From f8a2b2376559512ba3bd185eff04e20a37c5c488 Mon Sep 17 00:00:00 2001 From: Simon van Lierde Date: Fri, 17 Oct 2025 10:02:48 +0200 Subject: [PATCH 01/71] fix(cicd): update renovate.json to preserve semver ranges --- renovate.json | 22 +++++----------------- 1 file changed, 5 insertions(+), 17 deletions(-) diff --git a/renovate.json b/renovate.json index a024b67..0b3d5ad 100644 --- a/renovate.json +++ b/renovate.json @@ -4,34 +4,22 @@ "config:best-practices", ":approveMajorUpdates", ":maintainLockFilesWeekly", + ":preserveSemverRanges", "schedule:weekly" ], "packageRules": [ { "groupName": "backend", - "matchFileNames": [ - "backend/pyproject.toml", - "backend/.python-version", - "backend/Dockerfile*" - ] + "matchFileNames": ["backend/pyproject.toml", "backend/.python-version", "backend/Dockerfile*"] }, { "groupName": "frontend", - "matchFileNames": [ - "frontend/package.json", - "frontend/Dockerfile*" - ] + "matchFileNames": ["frontend/package.json", "frontend/Dockerfile*"] }, { "groupName": "infrastructure", - "matchFileNames": [ - "**/compose.*.yml", - "**/compose.yml" - ] + "matchFileNames": ["**/compose.*.yml", "**/compose.yml"] } ], - "labels": [ - "dependencies", - "renovate" - ] + "labels": ["dependencies", "renovate"] } From 30d992b12f13bfcbdbff8ec05c10ba9ad6f02fdc Mon Sep 17 00:00:00 2001 From: Simon van Lierde Date: Fri, 17 Oct 2025 14:11:14 +0200 Subject: [PATCH 02/71] fix(backend): Include disposable email check in backend registration endpoint --- .pre-commit-config.yaml | 2 +- backend/app/api/auth/crud/users.py | 6 +++++- backend/app/api/auth/exceptions.py | 10 ++++++++++ backend/app/api/auth/utils/email_validation.py | 13 +++++++------ 4 files changed, 23 insertions(+), 8 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index ed4ace6..767c39b 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -16,7 +16,7 @@ repos: - id: gitleaks - repo: https://github.com/executablebooks/mdformat - rev: 1.0.0 + rev: 0.7.22 hooks: - id: mdformat # Format Markdown files. additional_dependencies: diff --git a/backend/app/api/auth/crud/users.py b/backend/app/api/auth/crud/users.py index 5961c18..d2906e5 100644 --- a/backend/app/api/auth/crud/users.py +++ b/backend/app/api/auth/crud/users.py @@ -6,7 +6,7 @@ from sqlmodel import select from sqlmodel.ext.asyncio.session import AsyncSession -from app.api.auth.exceptions import UserNameAlreadyExistsError +from app.api.auth.exceptions import DisposableEmailError, UserNameAlreadyExistsError from app.api.auth.models import Organization, OrganizationRole, User from app.api.auth.schemas import ( OrganizationCreate, @@ -14,6 +14,7 @@ UserCreateWithOrganization, UserUpdate, ) +from app.api.auth.utils.email_validation import is_disposable_email from app.api.common.crud.utils import db_get_model_with_id_if_it_exists @@ -27,6 +28,9 @@ async def create_user_override( """ # TODO: Fix type errors in this method and implement custom UserNameAlreadyExists error in FastAPI-Users + if await is_disposable_email(user_create.email): + raise DisposableEmailError(email=user_create.email) + if user_create.username is not None: query = select(User).where(User.username == user_create.username) existing_username = await user_db.session.execute(query) diff --git a/backend/app/api/auth/exceptions.py b/backend/app/api/auth/exceptions.py index d03bdef..3ba0302 100644 --- a/backend/app/api/auth/exceptions.py +++ b/backend/app/api/auth/exceptions.py @@ -126,3 +126,13 @@ def __init__( ) -> None: model_name = model_type.get_api_model_name().name_capital super().__init__(message=(f"User {user_id} does not own {model_name} with ID {model_id}.")) + + +class DisposableEmailError(AuthCRUDError): + """Raised when a disposable email address is used.""" + + http_status_code = status.HTTP_400_BAD_REQUEST + + def __init__(self, email: str) -> None: + msg = f"The email address '{email}' is from a disposable email provider, which is not allowed." + super().__init__(msg) diff --git a/backend/app/api/auth/utils/email_validation.py b/backend/app/api/auth/utils/email_validation.py index b4e3ac1..36dfefa 100644 --- a/backend/app/api/auth/utils/email_validation.py +++ b/backend/app/api/auth/utils/email_validation.py @@ -1,10 +1,10 @@ -# backend/app/api/auth/utils/email_validation.py +"""Utilities for validating email addresses.""" + from datetime import UTC, datetime, timedelta from pathlib import Path import anyio import httpx -from fastapi import HTTPException DISPOSABLE_DOMAINS_URL = "https://raw.githubusercontent.com/disposable/disposable-email-domains/master/domains.txt" BASE_DIR: Path = (Path(__file__).parents[4]).resolve() @@ -20,7 +20,7 @@ async def get_disposable_domains() -> set[str]: cache_age = datetime.now(tz=UTC) - datetime.fromtimestamp(CACHE_FILE.stat().st_mtime, tz=UTC) if cache_age < CACHE_DURATION: async with await anyio.open_file(CACHE_FILE, "r") as f: - content = await f.read() # Read the entire file first + content = await f.read() return {line.strip().lower() for line in content.splitlines() if line.strip()} # Fetch fresh list @@ -38,13 +38,14 @@ async def get_disposable_domains() -> set[str]: await f.write("\n".join(sorted(domains))) return domains - except Exception as e: + except (httpx.RequestError, httpx.HTTPStatusError, OSError): # If fetch fails and cache exists, use stale cache if CACHE_FILE.exists(): async with await anyio.open_file(CACHE_FILE, "r") as f: - content = await f.read() # Read the entire file first + content = await f.read() return {line.strip().lower() for line in content.splitlines() if line.strip()} - raise HTTPException(status_code=503, detail="Email validation service unavailable") from e + # If no cache available, return empty set (allow registration) + return set() async def is_disposable_email(email: str) -> bool: From 6b7ca36313d897f6347ab208189f403ed409bd81 Mon Sep 17 00:00:00 2001 From: Simon van Lierde Date: Tue, 21 Oct 2025 12:49:38 +0200 Subject: [PATCH 03/71] fix(cicd): Fix versioning issues across the repo --- .pre-commit-config.yaml | 7 +- backend/.python-version | 2 +- backend/Dockerfile | 2 +- backend/Dockerfile.migrations | 2 +- backend/pyproject.toml | 2 +- backend/uv.lock | 751 +- frontend-app/src/assets/data/demo.json | 50791 ------------------- frontend-app/src/assets/data/products.json | 109 - 8 files changed, 384 insertions(+), 51282 deletions(-) delete mode 100644 frontend-app/src/assets/data/demo.json delete mode 100644 frontend-app/src/assets/data/products.json diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 767c39b..69be1fe 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -9,6 +9,8 @@ repos: rev: v0.8.0 hooks: - id: pre-commit-update # Autoupdate pre-commit hooks + # TODO: Re-add mdformat to pre-commit-update when mdformat plugins are compatible with mdformat 1.0.0 + args: [--exclude, mdformat] - repo: https://github.com/gitleaks/gitleaks rev: v8.28.0 @@ -24,7 +26,6 @@ repos: - mdformat-footnote - mdformat-frontmatter - mdformat-ruff # Support Python code blocks linted with Ruff. - - mdformat-tables # Support GitHub style tables. - repo: https://github.com/pre-commit/pre-commit-hooks rev: v6.0.0 @@ -63,7 +64,7 @@ repos: entry: pyright --project backend - repo: https://github.com/astral-sh/ruff-pre-commit - rev: v0.14.0 + rev: v0.14.1 hooks: - id: ruff-check # Lint code files: ^backend/(app|scripts|tests)/ @@ -73,7 +74,7 @@ repos: args: ["--config", "backend/pyproject.toml"] - repo: https://github.com/astral-sh/uv-pre-commit - rev: 0.9.3 + rev: 0.9.4 hooks: - id: uv-lock # Update the uv lockfile for the backend. files: ^backend/(uv\.lock|pyproject\.toml|uv\.toml)$ diff --git a/backend/.python-version b/backend/.python-version index 6324d40..24ee5b1 100644 --- a/backend/.python-version +++ b/backend/.python-version @@ -1 +1 @@ -3.14 +3.13 diff --git a/backend/Dockerfile b/backend/Dockerfile index 74b22a8..0d3fee1 100644 --- a/backend/Dockerfile +++ b/backend/Dockerfile @@ -34,7 +34,7 @@ RUN --mount=type=cache,target=/root/.cache/uv \ uv sync --locked --no-editable --no-default-groups --group=api # --- Final runtime stage --- -FROM python:3.14-slim@sha256:1e7c3510ceb3d6ebb499c86e1c418b95cb4e5e2f682f8e195069f470135f8d51 +FROM python:3.13-slim # Build arguments ARG WORKDIR=/opt/relab/backend diff --git a/backend/Dockerfile.migrations b/backend/Dockerfile.migrations index 5f8b17a..92cecd6 100644 --- a/backend/Dockerfile.migrations +++ b/backend/Dockerfile.migrations @@ -33,7 +33,7 @@ COPY scripts/ scripts/ COPY app/ app/ # --- Final runtime stage --- -FROM python:3.14-slim@sha256:1e7c3510ceb3d6ebb499c86e1c418b95cb4e5e2f682f8e195069f470135f8d51 +FROM python:3.13-slim # Build arguments ARG WORKDIR=/opt/relab/backend_migrations diff --git a/backend/pyproject.toml b/backend/pyproject.toml index c5198a9..4ed11cf 100644 --- a/backend/pyproject.toml +++ b/backend/pyproject.toml @@ -40,7 +40,7 @@ "markdown>=3.8.2", "pillow >=11.2.1", "psycopg[binary] >=3.2.9", - # TODO: Investigate pydantic v2.12 compatibility issues (might have to do with custom fastapi-users-db-sqlmodel fork) + # TODO: Upgrade to python 3.14 and pydantic 2.12 when SQLModel fixes compatibility issues (see https://github.com/fastapi/sqlmodel/issues/1606) "pydantic >=2.11,<2.12", "pydantic-extra-types >=2.10.5", "pydantic-settings >=2.10.1", diff --git a/backend/uv.lock b/backend/uv.lock index 5d16955..99661a9 100644 --- a/backend/uv.lock +++ b/backend/uv.lock @@ -8,11 +8,11 @@ resolution-markers = [ [[package]] name = "aiosmtplib" -version = "4.0.2" +version = "5.0.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/0f/e1/cc58e0be242f0b410707e001ed22c689435964fcaab42108887426e44fff/aiosmtplib-4.0.2.tar.gz", hash = "sha256:f0b4933e7270a8be2b588761e5b12b7334c11890ee91987c2fb057e72f566da6", size = 61052, upload-time = "2025-08-25T02:39:07.249Z" } +sdist = { url = "https://files.pythonhosted.org/packages/a2/15/c2dc93a58d716bce64b53918d3cf667d86c96a56a9f3a239a9f104643637/aiosmtplib-5.0.0.tar.gz", hash = "sha256:514ac11c31cb767c764077eb3c2eb2ae48df6f63f1e847aeb36119c4fc42b52d", size = 61057, upload-time = "2025-10-19T19:12:31.426Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/f1/2f/db9414bbeacee48ab0c7421a0319b361b7c15b5c3feebcd38684f5d5f849/aiosmtplib-4.0.2-py3-none-any.whl", hash = "sha256:72491f96e6de035c28d29870186782eccb2f651db9c5f8a32c9db689327f5742", size = 27048, upload-time = "2025-08-25T02:39:06.089Z" }, + { url = "https://files.pythonhosted.org/packages/99/42/b997c306dc54e6ac62a251787f6b5ec730797eea08e0336d8f0d7b899d5f/aiosmtplib-5.0.0-py3-none-any.whl", hash = "sha256:95eb0f81189780845363ab0627e7f130bca2d0060d46cd3eeb459f066eb7df32", size = 27048, upload-time = "2025-10-19T19:12:30.124Z" }, ] [[package]] @@ -200,30 +200,30 @@ wheels = [ [[package]] name = "boto3" -version = "1.40.49" +version = "1.40.55" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "botocore" }, { name = "jmespath" }, { name = "s3transfer" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/32/5b/165dbfc6de77774b0dac5582ac8a7aa92652d61215871ff4c88854864fb0/boto3-1.40.49.tar.gz", hash = "sha256:ea37d133548fbae543092ada61aeb08bced8f9aecd2e96e803dc8237459a80a0", size = 111572, upload-time = "2025-10-09T19:21:49.295Z" } +sdist = { url = "https://files.pythonhosted.org/packages/50/d8/a279c054e0c9731172f05b3d118f3ffc9d74806657f84fc0c93c42d1bb5d/boto3-1.40.55.tar.gz", hash = "sha256:27e35b4fa9edd414ce06c1a748bf57cacd8203271847d93fc1053e4a4ec6e1a9", size = 111590, upload-time = "2025-10-17T19:34:56.753Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/71/07/9b622ec8691911e3420c9872a50a9d333d4880d217e9eb25b327193099dc/boto3-1.40.49-py3-none-any.whl", hash = "sha256:64eb7af5f66998b34ad629786ff4a7f81d74c2d4ef9e42f69d99499dbee46d07", size = 139345, upload-time = "2025-10-09T19:21:46.886Z" }, + { url = "https://files.pythonhosted.org/packages/42/8c/559c6145d857ed953536a83f3a94915bbd5d3d2d406db1abf8bf40be7645/boto3-1.40.55-py3-none-any.whl", hash = "sha256:2e30f5a0d49e107b8a5c0c487891afd300bfa410e1d918bf187ae45ac3839332", size = 139322, upload-time = "2025-10-17T19:34:55.028Z" }, ] [[package]] name = "botocore" -version = "1.40.49" +version = "1.40.55" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "jmespath" }, { name = "python-dateutil" }, { name = "urllib3" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/01/6a/eb7503536552bbd3388b2607bc7a64e59d4f988336406b51a69d29f17ed2/botocore-1.40.49.tar.gz", hash = "sha256:fe8d4cbcc22de84c20190ae728c46b931bafeb40fce247010fb071c31b6532b5", size = 14415240, upload-time = "2025-10-09T19:21:37.133Z" } +sdist = { url = "https://files.pythonhosted.org/packages/a4/92/dce4842b2e215d213d34b064fcdd13c6a782c43344e77336bcde586e9229/botocore-1.40.55.tar.gz", hash = "sha256:79b6472e2de92b3519d44fc1eec8c5feced7f99a0d10fdea6dc93133426057c1", size = 14446917, upload-time = "2025-10-17T19:34:47.44Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/fc/7b/dce396a3f7078e0432d40a9778602cbf0785ca91e7bcb64e05f19dfb5662/botocore-1.40.49-py3-none-any.whl", hash = "sha256:bf1089d0e77e4fc2e195d81c519b194ab62a4d4dd3e7113ee4e2bf903b0b75ab", size = 14085172, upload-time = "2025-10-09T19:21:32.721Z" }, + { url = "https://files.pythonhosted.org/packages/21/30/f13bbc36e83b78777ff1abf50a084efcc3336b808e76560d8c5a0c9219e0/botocore-1.40.55-py3-none-any.whl", hash = "sha256:cdc38f7a4ddb30a2cd1cdd4fabde2a5a16e41b5a642292e1c30de5c4e46f5d44", size = 14116107, upload-time = "2025-10-17T19:34:44.398Z" }, ] [[package]] @@ -365,119 +365,119 @@ wheels = [ [[package]] name = "coverage" -version = "7.10.7" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/51/26/d22c300112504f5f9a9fd2297ce33c35f3d353e4aeb987c8419453b2a7c2/coverage-7.10.7.tar.gz", hash = "sha256:f4ab143ab113be368a3e9b795f9cd7906c5ef407d6173fe9675a902e1fffc239", size = 827704, upload-time = "2025-09-21T20:03:56.815Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/9a/94/b765c1abcb613d103b64fcf10395f54d69b0ef8be6a0dd9c524384892cc7/coverage-7.10.7-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:981a651f543f2854abd3b5fcb3263aac581b18209be49863ba575de6edf4c14d", size = 218320, upload-time = "2025-09-21T20:01:56.629Z" }, - { url = "https://files.pythonhosted.org/packages/72/4f/732fff31c119bb73b35236dd333030f32c4bfe909f445b423e6c7594f9a2/coverage-7.10.7-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:73ab1601f84dc804f7812dc297e93cd99381162da39c47040a827d4e8dafe63b", size = 218575, upload-time = "2025-09-21T20:01:58.203Z" }, - { url = "https://files.pythonhosted.org/packages/87/02/ae7e0af4b674be47566707777db1aa375474f02a1d64b9323e5813a6cdd5/coverage-7.10.7-cp313-cp313-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:a8b6f03672aa6734e700bbcd65ff050fd19cddfec4b031cc8cf1c6967de5a68e", size = 249568, upload-time = "2025-09-21T20:01:59.748Z" }, - { url = "https://files.pythonhosted.org/packages/a2/77/8c6d22bf61921a59bce5471c2f1f7ac30cd4ac50aadde72b8c48d5727902/coverage-7.10.7-cp313-cp313-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:10b6ba00ab1132a0ce4428ff68cf50a25efd6840a42cdf4239c9b99aad83be8b", size = 252174, upload-time = "2025-09-21T20:02:01.192Z" }, - { url = "https://files.pythonhosted.org/packages/b1/20/b6ea4f69bbb52dac0aebd62157ba6a9dddbfe664f5af8122dac296c3ee15/coverage-7.10.7-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:c79124f70465a150e89340de5963f936ee97097d2ef76c869708c4248c63ca49", size = 253447, upload-time = "2025-09-21T20:02:02.701Z" }, - { url = "https://files.pythonhosted.org/packages/f9/28/4831523ba483a7f90f7b259d2018fef02cb4d5b90bc7c1505d6e5a84883c/coverage-7.10.7-cp313-cp313-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:69212fbccdbd5b0e39eac4067e20a4a5256609e209547d86f740d68ad4f04911", size = 249779, upload-time = "2025-09-21T20:02:04.185Z" }, - { url = "https://files.pythonhosted.org/packages/a7/9f/4331142bc98c10ca6436d2d620c3e165f31e6c58d43479985afce6f3191c/coverage-7.10.7-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:7ea7c6c9d0d286d04ed3541747e6597cbe4971f22648b68248f7ddcd329207f0", size = 251604, upload-time = "2025-09-21T20:02:06.034Z" }, - { url = "https://files.pythonhosted.org/packages/ce/60/bda83b96602036b77ecf34e6393a3836365481b69f7ed7079ab85048202b/coverage-7.10.7-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:b9be91986841a75042b3e3243d0b3cb0b2434252b977baaf0cd56e960fe1e46f", size = 249497, upload-time = "2025-09-21T20:02:07.619Z" }, - { url = "https://files.pythonhosted.org/packages/5f/af/152633ff35b2af63977edd835d8e6430f0caef27d171edf2fc76c270ef31/coverage-7.10.7-cp313-cp313-musllinux_1_2_riscv64.whl", hash = "sha256:b281d5eca50189325cfe1f365fafade89b14b4a78d9b40b05ddd1fc7d2a10a9c", size = 249350, upload-time = "2025-09-21T20:02:10.34Z" }, - { url = "https://files.pythonhosted.org/packages/9d/71/d92105d122bd21cebba877228990e1646d862e34a98bb3374d3fece5a794/coverage-7.10.7-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:99e4aa63097ab1118e75a848a28e40d68b08a5e19ce587891ab7fd04475e780f", size = 251111, upload-time = "2025-09-21T20:02:12.122Z" }, - { url = "https://files.pythonhosted.org/packages/a2/9e/9fdb08f4bf476c912f0c3ca292e019aab6712c93c9344a1653986c3fd305/coverage-7.10.7-cp313-cp313-win32.whl", hash = "sha256:dc7c389dce432500273eaf48f410b37886be9208b2dd5710aaf7c57fd442c698", size = 220746, upload-time = "2025-09-21T20:02:13.919Z" }, - { url = "https://files.pythonhosted.org/packages/b1/b1/a75fd25df44eab52d1931e89980d1ada46824c7a3210be0d3c88a44aaa99/coverage-7.10.7-cp313-cp313-win_amd64.whl", hash = "sha256:cac0fdca17b036af3881a9d2729a850b76553f3f716ccb0360ad4dbc06b3b843", size = 221541, upload-time = "2025-09-21T20:02:15.57Z" }, - { url = "https://files.pythonhosted.org/packages/14/3a/d720d7c989562a6e9a14b2c9f5f2876bdb38e9367126d118495b89c99c37/coverage-7.10.7-cp313-cp313-win_arm64.whl", hash = "sha256:4b6f236edf6e2f9ae8fcd1332da4e791c1b6ba0dc16a2dc94590ceccb482e546", size = 220170, upload-time = "2025-09-21T20:02:17.395Z" }, - { url = "https://files.pythonhosted.org/packages/bb/22/e04514bf2a735d8b0add31d2b4ab636fc02370730787c576bb995390d2d5/coverage-7.10.7-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:a0ec07fd264d0745ee396b666d47cef20875f4ff2375d7c4f58235886cc1ef0c", size = 219029, upload-time = "2025-09-21T20:02:18.936Z" }, - { url = "https://files.pythonhosted.org/packages/11/0b/91128e099035ece15da3445d9015e4b4153a6059403452d324cbb0a575fa/coverage-7.10.7-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:dd5e856ebb7bfb7672b0086846db5afb4567a7b9714b8a0ebafd211ec7ce6a15", size = 219259, upload-time = "2025-09-21T20:02:20.44Z" }, - { url = "https://files.pythonhosted.org/packages/8b/51/66420081e72801536a091a0c8f8c1f88a5c4bf7b9b1bdc6222c7afe6dc9b/coverage-7.10.7-cp313-cp313t-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:f57b2a3c8353d3e04acf75b3fed57ba41f5c0646bbf1d10c7c282291c97936b4", size = 260592, upload-time = "2025-09-21T20:02:22.313Z" }, - { url = "https://files.pythonhosted.org/packages/5d/22/9b8d458c2881b22df3db5bb3e7369e63d527d986decb6c11a591ba2364f7/coverage-7.10.7-cp313-cp313t-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:1ef2319dd15a0b009667301a3f84452a4dc6fddfd06b0c5c53ea472d3989fbf0", size = 262768, upload-time = "2025-09-21T20:02:24.287Z" }, - { url = "https://files.pythonhosted.org/packages/f7/08/16bee2c433e60913c610ea200b276e8eeef084b0d200bdcff69920bd5828/coverage-7.10.7-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:83082a57783239717ceb0ad584de3c69cf581b2a95ed6bf81ea66034f00401c0", size = 264995, upload-time = "2025-09-21T20:02:26.133Z" }, - { url = "https://files.pythonhosted.org/packages/20/9d/e53eb9771d154859b084b90201e5221bca7674ba449a17c101a5031d4054/coverage-7.10.7-cp313-cp313t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:50aa94fb1fb9a397eaa19c0d5ec15a5edd03a47bf1a3a6111a16b36e190cff65", size = 259546, upload-time = "2025-09-21T20:02:27.716Z" }, - { url = "https://files.pythonhosted.org/packages/ad/b0/69bc7050f8d4e56a89fb550a1577d5d0d1db2278106f6f626464067b3817/coverage-7.10.7-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:2120043f147bebb41c85b97ac45dd173595ff14f2a584f2963891cbcc3091541", size = 262544, upload-time = "2025-09-21T20:02:29.216Z" }, - { url = "https://files.pythonhosted.org/packages/ef/4b/2514b060dbd1bc0aaf23b852c14bb5818f244c664cb16517feff6bb3a5ab/coverage-7.10.7-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:2fafd773231dd0378fdba66d339f84904a8e57a262f583530f4f156ab83863e6", size = 260308, upload-time = "2025-09-21T20:02:31.226Z" }, - { url = "https://files.pythonhosted.org/packages/54/78/7ba2175007c246d75e496f64c06e94122bdb914790a1285d627a918bd271/coverage-7.10.7-cp313-cp313t-musllinux_1_2_riscv64.whl", hash = "sha256:0b944ee8459f515f28b851728ad224fa2d068f1513ef6b7ff1efafeb2185f999", size = 258920, upload-time = "2025-09-21T20:02:32.823Z" }, - { url = "https://files.pythonhosted.org/packages/c0/b3/fac9f7abbc841409b9a410309d73bfa6cfb2e51c3fada738cb607ce174f8/coverage-7.10.7-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:4b583b97ab2e3efe1b3e75248a9b333bd3f8b0b1b8e5b45578e05e5850dfb2c2", size = 261434, upload-time = "2025-09-21T20:02:34.86Z" }, - { url = "https://files.pythonhosted.org/packages/ee/51/a03bec00d37faaa891b3ff7387192cef20f01604e5283a5fabc95346befa/coverage-7.10.7-cp313-cp313t-win32.whl", hash = "sha256:2a78cd46550081a7909b3329e2266204d584866e8d97b898cd7fb5ac8d888b1a", size = 221403, upload-time = "2025-09-21T20:02:37.034Z" }, - { url = "https://files.pythonhosted.org/packages/53/22/3cf25d614e64bf6d8e59c7c669b20d6d940bb337bdee5900b9ca41c820bb/coverage-7.10.7-cp313-cp313t-win_amd64.whl", hash = "sha256:33a5e6396ab684cb43dc7befa386258acb2d7fae7f67330ebb85ba4ea27938eb", size = 222469, upload-time = "2025-09-21T20:02:39.011Z" }, - { url = "https://files.pythonhosted.org/packages/49/a1/00164f6d30d8a01c3c9c48418a7a5be394de5349b421b9ee019f380df2a0/coverage-7.10.7-cp313-cp313t-win_arm64.whl", hash = "sha256:86b0e7308289ddde73d863b7683f596d8d21c7d8664ce1dee061d0bcf3fbb4bb", size = 220731, upload-time = "2025-09-21T20:02:40.939Z" }, - { url = "https://files.pythonhosted.org/packages/23/9c/5844ab4ca6a4dd97a1850e030a15ec7d292b5c5cb93082979225126e35dd/coverage-7.10.7-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:b06f260b16ead11643a5a9f955bd4b5fd76c1a4c6796aeade8520095b75de520", size = 218302, upload-time = "2025-09-21T20:02:42.527Z" }, - { url = "https://files.pythonhosted.org/packages/f0/89/673f6514b0961d1f0e20ddc242e9342f6da21eaba3489901b565c0689f34/coverage-7.10.7-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:212f8f2e0612778f09c55dd4872cb1f64a1f2b074393d139278ce902064d5b32", size = 218578, upload-time = "2025-09-21T20:02:44.468Z" }, - { url = "https://files.pythonhosted.org/packages/05/e8/261cae479e85232828fb17ad536765c88dd818c8470aca690b0ac6feeaa3/coverage-7.10.7-cp314-cp314-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:3445258bcded7d4aa630ab8296dea4d3f15a255588dd535f980c193ab6b95f3f", size = 249629, upload-time = "2025-09-21T20:02:46.503Z" }, - { url = "https://files.pythonhosted.org/packages/82/62/14ed6546d0207e6eda876434e3e8475a3e9adbe32110ce896c9e0c06bb9a/coverage-7.10.7-cp314-cp314-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:bb45474711ba385c46a0bfe696c695a929ae69ac636cda8f532be9e8c93d720a", size = 252162, upload-time = "2025-09-21T20:02:48.689Z" }, - { url = "https://files.pythonhosted.org/packages/ff/49/07f00db9ac6478e4358165a08fb41b469a1b053212e8a00cb02f0d27a05f/coverage-7.10.7-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:813922f35bd800dca9994c5971883cbc0d291128a5de6b167c7aa697fcf59360", size = 253517, upload-time = "2025-09-21T20:02:50.31Z" }, - { url = "https://files.pythonhosted.org/packages/a2/59/c5201c62dbf165dfbc91460f6dbbaa85a8b82cfa6131ac45d6c1bfb52deb/coverage-7.10.7-cp314-cp314-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:93c1b03552081b2a4423091d6fb3787265b8f86af404cff98d1b5342713bdd69", size = 249632, upload-time = "2025-09-21T20:02:51.971Z" }, - { url = "https://files.pythonhosted.org/packages/07/ae/5920097195291a51fb00b3a70b9bbd2edbfe3c84876a1762bd1ef1565ebc/coverage-7.10.7-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:cc87dd1b6eaf0b848eebb1c86469b9f72a1891cb42ac7adcfbce75eadb13dd14", size = 251520, upload-time = "2025-09-21T20:02:53.858Z" }, - { url = "https://files.pythonhosted.org/packages/b9/3c/a815dde77a2981f5743a60b63df31cb322c944843e57dbd579326625a413/coverage-7.10.7-cp314-cp314-musllinux_1_2_i686.whl", hash = "sha256:39508ffda4f343c35f3236fe8d1a6634a51f4581226a1262769d7f970e73bffe", size = 249455, upload-time = "2025-09-21T20:02:55.807Z" }, - { url = "https://files.pythonhosted.org/packages/aa/99/f5cdd8421ea656abefb6c0ce92556709db2265c41e8f9fc6c8ae0f7824c9/coverage-7.10.7-cp314-cp314-musllinux_1_2_riscv64.whl", hash = "sha256:925a1edf3d810537c5a3abe78ec5530160c5f9a26b1f4270b40e62cc79304a1e", size = 249287, upload-time = "2025-09-21T20:02:57.784Z" }, - { url = "https://files.pythonhosted.org/packages/c3/7a/e9a2da6a1fc5d007dd51fca083a663ab930a8c4d149c087732a5dbaa0029/coverage-7.10.7-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:2c8b9a0636f94c43cd3576811e05b89aa9bc2d0a85137affc544ae5cb0e4bfbd", size = 250946, upload-time = "2025-09-21T20:02:59.431Z" }, - { url = "https://files.pythonhosted.org/packages/ef/5b/0b5799aa30380a949005a353715095d6d1da81927d6dbed5def2200a4e25/coverage-7.10.7-cp314-cp314-win32.whl", hash = "sha256:b7b8288eb7cdd268b0304632da8cb0bb93fadcfec2fe5712f7b9cc8f4d487be2", size = 221009, upload-time = "2025-09-21T20:03:01.324Z" }, - { url = "https://files.pythonhosted.org/packages/da/b0/e802fbb6eb746de006490abc9bb554b708918b6774b722bb3a0e6aa1b7de/coverage-7.10.7-cp314-cp314-win_amd64.whl", hash = "sha256:1ca6db7c8807fb9e755d0379ccc39017ce0a84dcd26d14b5a03b78563776f681", size = 221804, upload-time = "2025-09-21T20:03:03.4Z" }, - { url = "https://files.pythonhosted.org/packages/9e/e8/71d0c8e374e31f39e3389bb0bd19e527d46f00ea8571ec7ec8fd261d8b44/coverage-7.10.7-cp314-cp314-win_arm64.whl", hash = "sha256:097c1591f5af4496226d5783d036bf6fd6cd0cbc132e071b33861de756efb880", size = 220384, upload-time = "2025-09-21T20:03:05.111Z" }, - { url = "https://files.pythonhosted.org/packages/62/09/9a5608d319fa3eba7a2019addeacb8c746fb50872b57a724c9f79f146969/coverage-7.10.7-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:a62c6ef0d50e6de320c270ff91d9dd0a05e7250cac2a800b7784bae474506e63", size = 219047, upload-time = "2025-09-21T20:03:06.795Z" }, - { url = "https://files.pythonhosted.org/packages/f5/6f/f58d46f33db9f2e3647b2d0764704548c184e6f5e014bef528b7f979ef84/coverage-7.10.7-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:9fa6e4dd51fe15d8738708a973470f67a855ca50002294852e9571cdbd9433f2", size = 219266, upload-time = "2025-09-21T20:03:08.495Z" }, - { url = "https://files.pythonhosted.org/packages/74/5c/183ffc817ba68e0b443b8c934c8795553eb0c14573813415bd59941ee165/coverage-7.10.7-cp314-cp314t-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:8fb190658865565c549b6b4706856d6a7b09302c797eb2cf8e7fe9dabb043f0d", size = 260767, upload-time = "2025-09-21T20:03:10.172Z" }, - { url = "https://files.pythonhosted.org/packages/0f/48/71a8abe9c1ad7e97548835e3cc1adbf361e743e9d60310c5f75c9e7bf847/coverage-7.10.7-cp314-cp314t-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:affef7c76a9ef259187ef31599a9260330e0335a3011732c4b9effa01e1cd6e0", size = 262931, upload-time = "2025-09-21T20:03:11.861Z" }, - { url = "https://files.pythonhosted.org/packages/84/fd/193a8fb132acfc0a901f72020e54be5e48021e1575bb327d8ee1097a28fd/coverage-7.10.7-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6e16e07d85ca0cf8bafe5f5d23a0b850064e8e945d5677492b06bbe6f09cc699", size = 265186, upload-time = "2025-09-21T20:03:13.539Z" }, - { url = "https://files.pythonhosted.org/packages/b1/8f/74ecc30607dd95ad50e3034221113ccb1c6d4e8085cc761134782995daae/coverage-7.10.7-cp314-cp314t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:03ffc58aacdf65d2a82bbeb1ffe4d01ead4017a21bfd0454983b88ca73af94b9", size = 259470, upload-time = "2025-09-21T20:03:15.584Z" }, - { url = "https://files.pythonhosted.org/packages/0f/55/79ff53a769f20d71b07023ea115c9167c0bb56f281320520cf64c5298a96/coverage-7.10.7-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:1b4fd784344d4e52647fd7857b2af5b3fbe6c239b0b5fa63e94eb67320770e0f", size = 262626, upload-time = "2025-09-21T20:03:17.673Z" }, - { url = "https://files.pythonhosted.org/packages/88/e2/dac66c140009b61ac3fc13af673a574b00c16efdf04f9b5c740703e953c0/coverage-7.10.7-cp314-cp314t-musllinux_1_2_i686.whl", hash = "sha256:0ebbaddb2c19b71912c6f2518e791aa8b9f054985a0769bdb3a53ebbc765c6a1", size = 260386, upload-time = "2025-09-21T20:03:19.36Z" }, - { url = "https://files.pythonhosted.org/packages/a2/f1/f48f645e3f33bb9ca8a496bc4a9671b52f2f353146233ebd7c1df6160440/coverage-7.10.7-cp314-cp314t-musllinux_1_2_riscv64.whl", hash = "sha256:a2d9a3b260cc1d1dbdb1c582e63ddcf5363426a1a68faa0f5da28d8ee3c722a0", size = 258852, upload-time = "2025-09-21T20:03:21.007Z" }, - { url = "https://files.pythonhosted.org/packages/bb/3b/8442618972c51a7affeead957995cfa8323c0c9bcf8fa5a027421f720ff4/coverage-7.10.7-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:a3cc8638b2480865eaa3926d192e64ce6c51e3d29c849e09d5b4ad95efae5399", size = 261534, upload-time = "2025-09-21T20:03:23.12Z" }, - { url = "https://files.pythonhosted.org/packages/b2/dc/101f3fa3a45146db0cb03f5b4376e24c0aac818309da23e2de0c75295a91/coverage-7.10.7-cp314-cp314t-win32.whl", hash = "sha256:67f8c5cbcd3deb7a60b3345dffc89a961a484ed0af1f6f73de91705cc6e31235", size = 221784, upload-time = "2025-09-21T20:03:24.769Z" }, - { url = "https://files.pythonhosted.org/packages/4c/a1/74c51803fc70a8a40d7346660379e144be772bab4ac7bb6e6b905152345c/coverage-7.10.7-cp314-cp314t-win_amd64.whl", hash = "sha256:e1ed71194ef6dea7ed2d5cb5f7243d4bcd334bfb63e59878519be558078f848d", size = 222905, upload-time = "2025-09-21T20:03:26.93Z" }, - { url = "https://files.pythonhosted.org/packages/12/65/f116a6d2127df30bcafbceef0302d8a64ba87488bf6f73a6d8eebf060873/coverage-7.10.7-cp314-cp314t-win_arm64.whl", hash = "sha256:7fe650342addd8524ca63d77b2362b02345e5f1a093266787d210c70a50b471a", size = 220922, upload-time = "2025-09-21T20:03:28.672Z" }, - { url = "https://files.pythonhosted.org/packages/ec/16/114df1c291c22cac3b0c127a73e0af5c12ed7bbb6558d310429a0ae24023/coverage-7.10.7-py3-none-any.whl", hash = "sha256:f7941f6f2fe6dd6807a1208737b8a0cbcf1cc6d7b07d24998ad2d63590868260", size = 209952, upload-time = "2025-09-21T20:03:53.918Z" }, +version = "7.11.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/1c/38/ee22495420457259d2f3390309505ea98f98a5eed40901cf62196abad006/coverage-7.11.0.tar.gz", hash = "sha256:167bd504ac1ca2af7ff3b81d245dfea0292c5032ebef9d66cc08a7d28c1b8050", size = 811905, upload-time = "2025-10-15T15:15:08.542Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/60/7f/85e4dfe65e400645464b25c036a26ac226cf3a69d4a50c3934c532491cdd/coverage-7.11.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:cc3f49e65ea6e0d5d9bd60368684fe52a704d46f9e7fc413918f18d046ec40e1", size = 216129, upload-time = "2025-10-15T15:13:25.371Z" }, + { url = "https://files.pythonhosted.org/packages/96/5d/dc5fa98fea3c175caf9d360649cb1aa3715e391ab00dc78c4c66fabd7356/coverage-7.11.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:f39ae2f63f37472c17b4990f794035c9890418b1b8cca75c01193f3c8d3e01be", size = 216380, upload-time = "2025-10-15T15:13:26.976Z" }, + { url = "https://files.pythonhosted.org/packages/b2/f5/3da9cc9596708273385189289c0e4d8197d37a386bdf17619013554b3447/coverage-7.11.0-cp313-cp313-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:7db53b5cdd2917b6eaadd0b1251cf4e7d96f4a8d24e174bdbdf2f65b5ea7994d", size = 247375, upload-time = "2025-10-15T15:13:28.923Z" }, + { url = "https://files.pythonhosted.org/packages/65/6c/f7f59c342359a235559d2bc76b0c73cfc4bac7d61bb0df210965cb1ecffd/coverage-7.11.0-cp313-cp313-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:10ad04ac3a122048688387828b4537bc9cf60c0bf4869c1e9989c46e45690b82", size = 249978, upload-time = "2025-10-15T15:13:30.525Z" }, + { url = "https://files.pythonhosted.org/packages/e7/8c/042dede2e23525e863bf1ccd2b92689692a148d8b5fd37c37899ba882645/coverage-7.11.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:4036cc9c7983a2b1f2556d574d2eb2154ac6ed55114761685657e38782b23f52", size = 251253, upload-time = "2025-10-15T15:13:32.174Z" }, + { url = "https://files.pythonhosted.org/packages/7b/a9/3c58df67bfa809a7bddd786356d9c5283e45d693edb5f3f55d0986dd905a/coverage-7.11.0-cp313-cp313-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:7ab934dd13b1c5e94b692b1e01bd87e4488cb746e3a50f798cb9464fd128374b", size = 247591, upload-time = "2025-10-15T15:13:34.147Z" }, + { url = "https://files.pythonhosted.org/packages/26/5b/c7f32efd862ee0477a18c41e4761305de6ddd2d49cdeda0c1116227570fd/coverage-7.11.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:59a6e5a265f7cfc05f76e3bb53eca2e0dfe90f05e07e849930fecd6abb8f40b4", size = 249411, upload-time = "2025-10-15T15:13:38.425Z" }, + { url = "https://files.pythonhosted.org/packages/76/b5/78cb4f1e86c1611431c990423ec0768122905b03837e1b4c6a6f388a858b/coverage-7.11.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:df01d6c4c81e15a7c88337b795bb7595a8596e92310266b5072c7e301168efbd", size = 247303, upload-time = "2025-10-15T15:13:40.464Z" }, + { url = "https://files.pythonhosted.org/packages/87/c9/23c753a8641a330f45f221286e707c427e46d0ffd1719b080cedc984ec40/coverage-7.11.0-cp313-cp313-musllinux_1_2_riscv64.whl", hash = "sha256:8c934bd088eed6174210942761e38ee81d28c46de0132ebb1801dbe36a390dcc", size = 247157, upload-time = "2025-10-15T15:13:42.087Z" }, + { url = "https://files.pythonhosted.org/packages/c5/42/6e0cc71dc8a464486e944a4fa0d85bdec031cc2969e98ed41532a98336b9/coverage-7.11.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:5a03eaf7ec24078ad64a07f02e30060aaf22b91dedf31a6b24d0d98d2bba7f48", size = 248921, upload-time = "2025-10-15T15:13:43.715Z" }, + { url = "https://files.pythonhosted.org/packages/e8/1c/743c2ef665e6858cccb0f84377dfe3a4c25add51e8c7ef19249be92465b6/coverage-7.11.0-cp313-cp313-win32.whl", hash = "sha256:695340f698a5f56f795b2836abe6fb576e7c53d48cd155ad2f80fd24bc63a040", size = 218526, upload-time = "2025-10-15T15:13:45.336Z" }, + { url = "https://files.pythonhosted.org/packages/ff/d5/226daadfd1bf8ddbccefbd3aa3547d7b960fb48e1bdac124e2dd13a2b71a/coverage-7.11.0-cp313-cp313-win_amd64.whl", hash = "sha256:2727d47fce3ee2bac648528e41455d1b0c46395a087a229deac75e9f88ba5a05", size = 219317, upload-time = "2025-10-15T15:13:47.401Z" }, + { url = "https://files.pythonhosted.org/packages/97/54/47db81dcbe571a48a298f206183ba8a7ba79200a37cd0d9f4788fcd2af4a/coverage-7.11.0-cp313-cp313-win_arm64.whl", hash = "sha256:0efa742f431529699712b92ecdf22de8ff198df41e43aeaaadf69973eb93f17a", size = 217948, upload-time = "2025-10-15T15:13:49.096Z" }, + { url = "https://files.pythonhosted.org/packages/e5/8b/cb68425420154e7e2a82fd779a8cc01549b6fa83c2ad3679cd6c088ebd07/coverage-7.11.0-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:587c38849b853b157706407e9ebdca8fd12f45869edb56defbef2daa5fb0812b", size = 216837, upload-time = "2025-10-15T15:13:51.09Z" }, + { url = "https://files.pythonhosted.org/packages/33/55/9d61b5765a025685e14659c8d07037247de6383c0385757544ffe4606475/coverage-7.11.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:b971bdefdd75096163dd4261c74be813c4508477e39ff7b92191dea19f24cd37", size = 217061, upload-time = "2025-10-15T15:13:52.747Z" }, + { url = "https://files.pythonhosted.org/packages/52/85/292459c9186d70dcec6538f06ea251bc968046922497377bf4a1dc9a71de/coverage-7.11.0-cp313-cp313t-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:269bfe913b7d5be12ab13a95f3a76da23cf147be7fa043933320ba5625f0a8de", size = 258398, upload-time = "2025-10-15T15:13:54.45Z" }, + { url = "https://files.pythonhosted.org/packages/1f/e2/46edd73fb8bf51446c41148d81944c54ed224854812b6ca549be25113ee0/coverage-7.11.0-cp313-cp313t-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:dadbcce51a10c07b7c72b0ce4a25e4b6dcb0c0372846afb8e5b6307a121eb99f", size = 260574, upload-time = "2025-10-15T15:13:56.145Z" }, + { url = "https://files.pythonhosted.org/packages/07/5e/1df469a19007ff82e2ca8fe509822820a31e251f80ee7344c34f6cd2ec43/coverage-7.11.0-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:9ed43fa22c6436f7957df036331f8fe4efa7af132054e1844918866cd228af6c", size = 262797, upload-time = "2025-10-15T15:13:58.635Z" }, + { url = "https://files.pythonhosted.org/packages/f9/50/de216b31a1434b94d9b34a964c09943c6be45069ec704bfc379d8d89a649/coverage-7.11.0-cp313-cp313t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:9516add7256b6713ec08359b7b05aeff8850c98d357784c7205b2e60aa2513fa", size = 257361, upload-time = "2025-10-15T15:14:00.409Z" }, + { url = "https://files.pythonhosted.org/packages/82/1e/3f9f8344a48111e152e0fd495b6fff13cc743e771a6050abf1627a7ba918/coverage-7.11.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:eb92e47c92fcbcdc692f428da67db33337fa213756f7adb6a011f7b5a7a20740", size = 260349, upload-time = "2025-10-15T15:14:02.188Z" }, + { url = "https://files.pythonhosted.org/packages/65/9b/3f52741f9e7d82124272f3070bbe316006a7de1bad1093f88d59bfc6c548/coverage-7.11.0-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:d06f4fc7acf3cabd6d74941d53329e06bab00a8fe10e4df2714f0b134bfc64ef", size = 258114, upload-time = "2025-10-15T15:14:03.907Z" }, + { url = "https://files.pythonhosted.org/packages/0b/8b/918f0e15f0365d50d3986bbd3338ca01178717ac5678301f3f547b6619e6/coverage-7.11.0-cp313-cp313t-musllinux_1_2_riscv64.whl", hash = "sha256:6fbcee1a8f056af07ecd344482f711f563a9eb1c2cad192e87df00338ec3cdb0", size = 256723, upload-time = "2025-10-15T15:14:06.324Z" }, + { url = "https://files.pythonhosted.org/packages/44/9e/7776829f82d3cf630878a7965a7d70cc6ca94f22c7d20ec4944f7148cb46/coverage-7.11.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:dbbf012be5f32533a490709ad597ad8a8ff80c582a95adc8d62af664e532f9ca", size = 259238, upload-time = "2025-10-15T15:14:08.002Z" }, + { url = "https://files.pythonhosted.org/packages/9a/b8/49cf253e1e7a3bedb85199b201862dd7ca4859f75b6cf25ffa7298aa0760/coverage-7.11.0-cp313-cp313t-win32.whl", hash = "sha256:cee6291bb4fed184f1c2b663606a115c743df98a537c969c3c64b49989da96c2", size = 219180, upload-time = "2025-10-15T15:14:09.786Z" }, + { url = "https://files.pythonhosted.org/packages/ac/e1/1a541703826be7ae2125a0fb7f821af5729d56bb71e946e7b933cc7a89a4/coverage-7.11.0-cp313-cp313t-win_amd64.whl", hash = "sha256:a386c1061bf98e7ea4758e4313c0ab5ecf57af341ef0f43a0bf26c2477b5c268", size = 220241, upload-time = "2025-10-15T15:14:11.471Z" }, + { url = "https://files.pythonhosted.org/packages/d5/d1/5ee0e0a08621140fd418ec4020f595b4d52d7eb429ae6a0c6542b4ba6f14/coverage-7.11.0-cp313-cp313t-win_arm64.whl", hash = "sha256:f9ea02ef40bb83823b2b04964459d281688fe173e20643870bb5d2edf68bc836", size = 218510, upload-time = "2025-10-15T15:14:13.46Z" }, + { url = "https://files.pythonhosted.org/packages/f4/06/e923830c1985ce808e40a3fa3eb46c13350b3224b7da59757d37b6ce12b8/coverage-7.11.0-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:c770885b28fb399aaf2a65bbd1c12bf6f307ffd112d6a76c5231a94276f0c497", size = 216110, upload-time = "2025-10-15T15:14:15.157Z" }, + { url = "https://files.pythonhosted.org/packages/42/82/cdeed03bfead45203fb651ed756dfb5266028f5f939e7f06efac4041dad5/coverage-7.11.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:a3d0e2087dba64c86a6b254f43e12d264b636a39e88c5cc0a01a7c71bcfdab7e", size = 216395, upload-time = "2025-10-15T15:14:16.863Z" }, + { url = "https://files.pythonhosted.org/packages/fc/ba/e1c80caffc3199aa699813f73ff097bc2df7b31642bdbc7493600a8f1de5/coverage-7.11.0-cp314-cp314-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:73feb83bb41c32811973b8565f3705caf01d928d972b72042b44e97c71fd70d1", size = 247433, upload-time = "2025-10-15T15:14:18.589Z" }, + { url = "https://files.pythonhosted.org/packages/80/c0/5b259b029694ce0a5bbc1548834c7ba3db41d3efd3474489d7efce4ceb18/coverage-7.11.0-cp314-cp314-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:c6f31f281012235ad08f9a560976cc2fc9c95c17604ff3ab20120fe480169bca", size = 249970, upload-time = "2025-10-15T15:14:20.307Z" }, + { url = "https://files.pythonhosted.org/packages/8c/86/171b2b5e1aac7e2fd9b43f7158b987dbeb95f06d1fbecad54ad8163ae3e8/coverage-7.11.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:e9570ad567f880ef675673992222746a124b9595506826b210fbe0ce3f0499cd", size = 251324, upload-time = "2025-10-15T15:14:22.419Z" }, + { url = "https://files.pythonhosted.org/packages/1a/7e/7e10414d343385b92024af3932a27a1caf75c6e27ee88ba211221ff1a145/coverage-7.11.0-cp314-cp314-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:8badf70446042553a773547a61fecaa734b55dc738cacf20c56ab04b77425e43", size = 247445, upload-time = "2025-10-15T15:14:24.205Z" }, + { url = "https://files.pythonhosted.org/packages/c4/3b/e4f966b21f5be8c4bf86ad75ae94efa0de4c99c7bbb8114476323102e345/coverage-7.11.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:a09c1211959903a479e389685b7feb8a17f59ec5a4ef9afde7650bd5eabc2777", size = 249324, upload-time = "2025-10-15T15:14:26.234Z" }, + { url = "https://files.pythonhosted.org/packages/00/a2/8479325576dfcd909244d0df215f077f47437ab852ab778cfa2f8bf4d954/coverage-7.11.0-cp314-cp314-musllinux_1_2_i686.whl", hash = "sha256:5ef83b107f50db3f9ae40f69e34b3bd9337456c5a7fe3461c7abf8b75dd666a2", size = 247261, upload-time = "2025-10-15T15:14:28.42Z" }, + { url = "https://files.pythonhosted.org/packages/7b/d8/3a9e2db19d94d65771d0f2e21a9ea587d11b831332a73622f901157cc24b/coverage-7.11.0-cp314-cp314-musllinux_1_2_riscv64.whl", hash = "sha256:f91f927a3215b8907e214af77200250bb6aae36eca3f760f89780d13e495388d", size = 247092, upload-time = "2025-10-15T15:14:30.784Z" }, + { url = "https://files.pythonhosted.org/packages/b3/b1/bbca3c472544f9e2ad2d5116b2379732957048be4b93a9c543fcd0207e5f/coverage-7.11.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:cdbcd376716d6b7fbfeedd687a6c4be019c5a5671b35f804ba76a4c0a778cba4", size = 248755, upload-time = "2025-10-15T15:14:32.585Z" }, + { url = "https://files.pythonhosted.org/packages/89/49/638d5a45a6a0f00af53d6b637c87007eb2297042186334e9923a61aa8854/coverage-7.11.0-cp314-cp314-win32.whl", hash = "sha256:bab7ec4bb501743edc63609320aaec8cd9188b396354f482f4de4d40a9d10721", size = 218793, upload-time = "2025-10-15T15:14:34.972Z" }, + { url = "https://files.pythonhosted.org/packages/30/cc/b675a51f2d068adb3cdf3799212c662239b0ca27f4691d1fff81b92ea850/coverage-7.11.0-cp314-cp314-win_amd64.whl", hash = "sha256:3d4ba9a449e9364a936a27322b20d32d8b166553bfe63059bd21527e681e2fad", size = 219587, upload-time = "2025-10-15T15:14:37.047Z" }, + { url = "https://files.pythonhosted.org/packages/93/98/5ac886876026de04f00820e5094fe22166b98dcb8b426bf6827aaf67048c/coverage-7.11.0-cp314-cp314-win_arm64.whl", hash = "sha256:ce37f215223af94ef0f75ac68ea096f9f8e8c8ec7d6e8c346ee45c0d363f0479", size = 218168, upload-time = "2025-10-15T15:14:38.861Z" }, + { url = "https://files.pythonhosted.org/packages/14/d1/b4145d35b3e3ecf4d917e97fc8895bcf027d854879ba401d9ff0f533f997/coverage-7.11.0-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:f413ce6e07e0d0dc9c433228727b619871532674b45165abafe201f200cc215f", size = 216850, upload-time = "2025-10-15T15:14:40.651Z" }, + { url = "https://files.pythonhosted.org/packages/ca/d1/7f645fc2eccd318369a8a9948acc447bb7c1ade2911e31d3c5620544c22b/coverage-7.11.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:05791e528a18f7072bf5998ba772fe29db4da1234c45c2087866b5ba4dea710e", size = 217071, upload-time = "2025-10-15T15:14:42.755Z" }, + { url = "https://files.pythonhosted.org/packages/54/7d/64d124649db2737ceced1dfcbdcb79898d5868d311730f622f8ecae84250/coverage-7.11.0-cp314-cp314t-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:cacb29f420cfeb9283b803263c3b9a068924474ff19ca126ba9103e1278dfa44", size = 258570, upload-time = "2025-10-15T15:14:44.542Z" }, + { url = "https://files.pythonhosted.org/packages/6c/3f/6f5922f80dc6f2d8b2c6f974835c43f53eb4257a7797727e6ca5b7b2ec1f/coverage-7.11.0-cp314-cp314t-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:314c24e700d7027ae3ab0d95fbf8d53544fca1f20345fd30cd219b737c6e58d3", size = 260738, upload-time = "2025-10-15T15:14:46.436Z" }, + { url = "https://files.pythonhosted.org/packages/0e/5f/9e883523c4647c860b3812b417a2017e361eca5b635ee658387dc11b13c1/coverage-7.11.0-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:630d0bd7a293ad2fc8b4b94e5758c8b2536fdf36c05f1681270203e463cbfa9b", size = 262994, upload-time = "2025-10-15T15:14:48.3Z" }, + { url = "https://files.pythonhosted.org/packages/07/bb/43b5a8e94c09c8bf51743ffc65c4c841a4ca5d3ed191d0a6919c379a1b83/coverage-7.11.0-cp314-cp314t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:e89641f5175d65e2dbb44db15fe4ea48fade5d5bbb9868fdc2b4fce22f4a469d", size = 257282, upload-time = "2025-10-15T15:14:50.236Z" }, + { url = "https://files.pythonhosted.org/packages/aa/e5/0ead8af411411330b928733e1d201384b39251a5f043c1612970310e8283/coverage-7.11.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:c9f08ea03114a637dab06cedb2e914da9dc67fa52c6015c018ff43fdde25b9c2", size = 260430, upload-time = "2025-10-15T15:14:52.413Z" }, + { url = "https://files.pythonhosted.org/packages/ae/66/03dd8bb0ba5b971620dcaac145461950f6d8204953e535d2b20c6b65d729/coverage-7.11.0-cp314-cp314t-musllinux_1_2_i686.whl", hash = "sha256:ce9f3bde4e9b031eaf1eb61df95c1401427029ea1bfddb8621c1161dcb0fa02e", size = 258190, upload-time = "2025-10-15T15:14:54.268Z" }, + { url = "https://files.pythonhosted.org/packages/45/ae/28a9cce40bf3174426cb2f7e71ee172d98e7f6446dff936a7ccecee34b14/coverage-7.11.0-cp314-cp314t-musllinux_1_2_riscv64.whl", hash = "sha256:e4dc07e95495923d6fd4d6c27bf70769425b71c89053083843fd78f378558996", size = 256658, upload-time = "2025-10-15T15:14:56.436Z" }, + { url = "https://files.pythonhosted.org/packages/5c/7c/3a44234a8599513684bfc8684878fd7b126c2760f79712bb78c56f19efc4/coverage-7.11.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:424538266794db2861db4922b05d729ade0940ee69dcf0591ce8f69784db0e11", size = 259342, upload-time = "2025-10-15T15:14:58.538Z" }, + { url = "https://files.pythonhosted.org/packages/e1/e6/0108519cba871af0351725ebdb8660fd7a0fe2ba3850d56d32490c7d9b4b/coverage-7.11.0-cp314-cp314t-win32.whl", hash = "sha256:4c1eeb3fb8eb9e0190bebafd0462936f75717687117339f708f395fe455acc73", size = 219568, upload-time = "2025-10-15T15:15:00.382Z" }, + { url = "https://files.pythonhosted.org/packages/c9/76/44ba876e0942b4e62fdde23ccb029ddb16d19ba1bef081edd00857ba0b16/coverage-7.11.0-cp314-cp314t-win_amd64.whl", hash = "sha256:b56efee146c98dbf2cf5cffc61b9829d1e94442df4d7398b26892a53992d3547", size = 220687, upload-time = "2025-10-15T15:15:02.322Z" }, + { url = "https://files.pythonhosted.org/packages/b9/0c/0df55ecb20d0d0ed5c322e10a441775e1a3a5d78c60f0c4e1abfe6fcf949/coverage-7.11.0-cp314-cp314t-win_arm64.whl", hash = "sha256:b5c2705afa83f49bd91962a4094b6b082f94aef7626365ab3f8f4bd159c5acf3", size = 218711, upload-time = "2025-10-15T15:15:04.575Z" }, + { url = "https://files.pythonhosted.org/packages/5f/04/642c1d8a448ae5ea1369eac8495740a79eb4e581a9fb0cbdce56bbf56da1/coverage-7.11.0-py3-none-any.whl", hash = "sha256:4b7589765348d78fb4e5fb6ea35d07564e387da2fc5efff62e0222971f155f68", size = 207761, upload-time = "2025-10-15T15:15:06.439Z" }, ] [[package]] name = "cryptography" -version = "46.0.2" +version = "46.0.3" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "cffi", marker = "platform_python_implementation != 'PyPy'" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/4a/9b/e301418629f7bfdf72db9e80ad6ed9d1b83c487c471803eaa6464c511a01/cryptography-46.0.2.tar.gz", hash = "sha256:21b6fc8c71a3f9a604f028a329e5560009cc4a3a828bfea5fcba8eb7647d88fe", size = 749293, upload-time = "2025-10-01T00:29:11.856Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/e0/98/7a8df8c19a335c8028414738490fc3955c0cecbfdd37fcc1b9c3d04bd561/cryptography-46.0.2-cp311-abi3-macosx_10_9_universal2.whl", hash = "sha256:f3e32ab7dd1b1ef67b9232c4cf5e2ee4cd517d4316ea910acaaa9c5712a1c663", size = 7261255, upload-time = "2025-10-01T00:27:22.947Z" }, - { url = "https://files.pythonhosted.org/packages/c6/38/b2adb2aa1baa6706adc3eb746691edd6f90a656a9a65c3509e274d15a2b8/cryptography-46.0.2-cp311-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:1fd1a69086926b623ef8126b4c33d5399ce9e2f3fac07c9c734c2a4ec38b6d02", size = 4297596, upload-time = "2025-10-01T00:27:25.258Z" }, - { url = "https://files.pythonhosted.org/packages/e4/27/0f190ada240003119488ae66c897b5e97149292988f556aef4a6a2a57595/cryptography-46.0.2-cp311-abi3-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:bb7fb9cd44c2582aa5990cf61a4183e6f54eea3172e54963787ba47287edd135", size = 4450899, upload-time = "2025-10-01T00:27:27.458Z" }, - { url = "https://files.pythonhosted.org/packages/85/d5/e4744105ab02fdf6bb58ba9a816e23b7a633255987310b4187d6745533db/cryptography-46.0.2-cp311-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:9066cfd7f146f291869a9898b01df1c9b0e314bfa182cef432043f13fc462c92", size = 4300382, upload-time = "2025-10-01T00:27:29.091Z" }, - { url = "https://files.pythonhosted.org/packages/33/fb/bf9571065c18c04818cb07de90c43fc042c7977c68e5de6876049559c72f/cryptography-46.0.2-cp311-abi3-manylinux_2_28_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:97e83bf4f2f2c084d8dd792d13841d0a9b241643151686010866bbd076b19659", size = 4017347, upload-time = "2025-10-01T00:27:30.767Z" }, - { url = "https://files.pythonhosted.org/packages/35/72/fc51856b9b16155ca071080e1a3ad0c3a8e86616daf7eb018d9565b99baa/cryptography-46.0.2-cp311-abi3-manylinux_2_28_ppc64le.whl", hash = "sha256:4a766d2a5d8127364fd936572c6e6757682fc5dfcbdba1632d4554943199f2fa", size = 4983500, upload-time = "2025-10-01T00:27:32.741Z" }, - { url = "https://files.pythonhosted.org/packages/c1/53/0f51e926799025e31746d454ab2e36f8c3f0d41592bc65cb9840368d3275/cryptography-46.0.2-cp311-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:fab8f805e9675e61ed8538f192aad70500fa6afb33a8803932999b1049363a08", size = 4482591, upload-time = "2025-10-01T00:27:34.869Z" }, - { url = "https://files.pythonhosted.org/packages/86/96/4302af40b23ab8aa360862251fb8fc450b2a06ff24bc5e261c2007f27014/cryptography-46.0.2-cp311-abi3-manylinux_2_34_aarch64.whl", hash = "sha256:1e3b6428a3d56043bff0bb85b41c535734204e599c1c0977e1d0f261b02f3ad5", size = 4300019, upload-time = "2025-10-01T00:27:37.029Z" }, - { url = "https://files.pythonhosted.org/packages/9b/59/0be12c7fcc4c5e34fe2b665a75bc20958473047a30d095a7657c218fa9e8/cryptography-46.0.2-cp311-abi3-manylinux_2_34_ppc64le.whl", hash = "sha256:1a88634851d9b8de8bb53726f4300ab191d3b2f42595e2581a54b26aba71b7cc", size = 4950006, upload-time = "2025-10-01T00:27:40.272Z" }, - { url = "https://files.pythonhosted.org/packages/55/1d/42fda47b0111834b49e31590ae14fd020594d5e4dadd639bce89ad790fba/cryptography-46.0.2-cp311-abi3-manylinux_2_34_x86_64.whl", hash = "sha256:be939b99d4e091eec9a2bcf41aaf8f351f312cd19ff74b5c83480f08a8a43e0b", size = 4482088, upload-time = "2025-10-01T00:27:42.668Z" }, - { url = "https://files.pythonhosted.org/packages/17/50/60f583f69aa1602c2bdc7022dae86a0d2b837276182f8c1ec825feb9b874/cryptography-46.0.2-cp311-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:9f13b040649bc18e7eb37936009b24fd31ca095a5c647be8bb6aaf1761142bd1", size = 4425599, upload-time = "2025-10-01T00:27:44.616Z" }, - { url = "https://files.pythonhosted.org/packages/d1/57/d8d4134cd27e6e94cf44adb3f3489f935bde85f3a5508e1b5b43095b917d/cryptography-46.0.2-cp311-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:9bdc25e4e01b261a8fda4e98618f1c9515febcecebc9566ddf4a70c63967043b", size = 4697458, upload-time = "2025-10-01T00:27:46.209Z" }, - { url = "https://files.pythonhosted.org/packages/d1/2b/531e37408573e1da33adfb4c58875013ee8ac7d548d1548967d94a0ae5c4/cryptography-46.0.2-cp311-abi3-win32.whl", hash = "sha256:8b9bf67b11ef9e28f4d78ff88b04ed0929fcd0e4f70bb0f704cfc32a5c6311ee", size = 3056077, upload-time = "2025-10-01T00:27:48.424Z" }, - { url = "https://files.pythonhosted.org/packages/a8/cd/2f83cafd47ed2dc5a3a9c783ff5d764e9e70d3a160e0df9a9dcd639414ce/cryptography-46.0.2-cp311-abi3-win_amd64.whl", hash = "sha256:758cfc7f4c38c5c5274b55a57ef1910107436f4ae842478c4989abbd24bd5acb", size = 3512585, upload-time = "2025-10-01T00:27:50.521Z" }, - { url = "https://files.pythonhosted.org/packages/00/36/676f94e10bfaa5c5b86c469ff46d3e0663c5dc89542f7afbadac241a3ee4/cryptography-46.0.2-cp311-abi3-win_arm64.whl", hash = "sha256:218abd64a2e72f8472c2102febb596793347a3e65fafbb4ad50519969da44470", size = 2927474, upload-time = "2025-10-01T00:27:52.91Z" }, - { url = "https://files.pythonhosted.org/packages/6f/cc/47fc6223a341f26d103cb6da2216805e08a37d3b52bee7f3b2aee8066f95/cryptography-46.0.2-cp314-cp314t-macosx_10_9_universal2.whl", hash = "sha256:bda55e8dbe8533937956c996beaa20266a8eca3570402e52ae52ed60de1faca8", size = 7198626, upload-time = "2025-10-01T00:27:54.8Z" }, - { url = "https://files.pythonhosted.org/packages/93/22/d66a8591207c28bbe4ac7afa25c4656dc19dc0db29a219f9809205639ede/cryptography-46.0.2-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:e7155c0b004e936d381b15425273aee1cebc94f879c0ce82b0d7fecbf755d53a", size = 4287584, upload-time = "2025-10-01T00:27:57.018Z" }, - { url = "https://files.pythonhosted.org/packages/8c/3e/fac3ab6302b928e0398c269eddab5978e6c1c50b2b77bb5365ffa8633b37/cryptography-46.0.2-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:a61c154cc5488272a6c4b86e8d5beff4639cdb173d75325ce464d723cda0052b", size = 4433796, upload-time = "2025-10-01T00:27:58.631Z" }, - { url = "https://files.pythonhosted.org/packages/7d/d8/24392e5d3c58e2d83f98fe5a2322ae343360ec5b5b93fe18bc52e47298f5/cryptography-46.0.2-cp314-cp314t-manylinux_2_28_aarch64.whl", hash = "sha256:9ec3f2e2173f36a9679d3b06d3d01121ab9b57c979de1e6a244b98d51fea1b20", size = 4292126, upload-time = "2025-10-01T00:28:00.643Z" }, - { url = "https://files.pythonhosted.org/packages/ed/38/3d9f9359b84c16c49a5a336ee8be8d322072a09fac17e737f3bb11f1ce64/cryptography-46.0.2-cp314-cp314t-manylinux_2_28_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:2fafb6aa24e702bbf74de4cb23bfa2c3beb7ab7683a299062b69724c92e0fa73", size = 3993056, upload-time = "2025-10-01T00:28:02.8Z" }, - { url = "https://files.pythonhosted.org/packages/d6/a3/4c44fce0d49a4703cc94bfbe705adebf7ab36efe978053742957bc7ec324/cryptography-46.0.2-cp314-cp314t-manylinux_2_28_ppc64le.whl", hash = "sha256:0c7ffe8c9b1fcbb07a26d7c9fa5e857c2fe80d72d7b9e0353dcf1d2180ae60ee", size = 4967604, upload-time = "2025-10-01T00:28:04.783Z" }, - { url = "https://files.pythonhosted.org/packages/eb/c2/49d73218747c8cac16bb8318a5513fde3129e06a018af3bc4dc722aa4a98/cryptography-46.0.2-cp314-cp314t-manylinux_2_28_x86_64.whl", hash = "sha256:5840f05518caa86b09d23f8b9405a7b6d5400085aa14a72a98fdf5cf1568c0d2", size = 4465367, upload-time = "2025-10-01T00:28:06.864Z" }, - { url = "https://files.pythonhosted.org/packages/1b/64/9afa7d2ee742f55ca6285a54386ed2778556a4ed8871571cb1c1bfd8db9e/cryptography-46.0.2-cp314-cp314t-manylinux_2_34_aarch64.whl", hash = "sha256:27c53b4f6a682a1b645fbf1cd5058c72cf2f5aeba7d74314c36838c7cbc06e0f", size = 4291678, upload-time = "2025-10-01T00:28:08.982Z" }, - { url = "https://files.pythonhosted.org/packages/50/48/1696d5ea9623a7b72ace87608f6899ca3c331709ac7ebf80740abb8ac673/cryptography-46.0.2-cp314-cp314t-manylinux_2_34_ppc64le.whl", hash = "sha256:512c0250065e0a6b286b2db4bbcc2e67d810acd53eb81733e71314340366279e", size = 4931366, upload-time = "2025-10-01T00:28:10.74Z" }, - { url = "https://files.pythonhosted.org/packages/eb/3c/9dfc778401a334db3b24435ee0733dd005aefb74afe036e2d154547cb917/cryptography-46.0.2-cp314-cp314t-manylinux_2_34_x86_64.whl", hash = "sha256:07c0eb6657c0e9cca5891f4e35081dbf985c8131825e21d99b4f440a8f496f36", size = 4464738, upload-time = "2025-10-01T00:28:12.491Z" }, - { url = "https://files.pythonhosted.org/packages/dc/b1/abcde62072b8f3fd414e191a6238ce55a0050e9738090dc6cded24c12036/cryptography-46.0.2-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:48b983089378f50cba258f7f7aa28198c3f6e13e607eaf10472c26320332ca9a", size = 4419305, upload-time = "2025-10-01T00:28:14.145Z" }, - { url = "https://files.pythonhosted.org/packages/c7/1f/3d2228492f9391395ca34c677e8f2571fb5370fe13dc48c1014f8c509864/cryptography-46.0.2-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:e6f6775eaaa08c0eec73e301f7592f4367ccde5e4e4df8e58320f2ebf161ea2c", size = 4681201, upload-time = "2025-10-01T00:28:15.951Z" }, - { url = "https://files.pythonhosted.org/packages/de/77/b687745804a93a55054f391528fcfc76c3d6bfd082ce9fb62c12f0d29fc1/cryptography-46.0.2-cp314-cp314t-win32.whl", hash = "sha256:e8633996579961f9b5a3008683344c2558d38420029d3c0bc7ff77c17949a4e1", size = 3022492, upload-time = "2025-10-01T00:28:17.643Z" }, - { url = "https://files.pythonhosted.org/packages/60/a5/8d498ef2996e583de0bef1dcc5e70186376f00883ae27bf2133f490adf21/cryptography-46.0.2-cp314-cp314t-win_amd64.whl", hash = "sha256:48c01988ecbb32979bb98731f5c2b2f79042a6c58cc9a319c8c2f9987c7f68f9", size = 3496215, upload-time = "2025-10-01T00:28:19.272Z" }, - { url = "https://files.pythonhosted.org/packages/56/db/ee67aaef459a2706bc302b15889a1a8126ebe66877bab1487ae6ad00f33d/cryptography-46.0.2-cp314-cp314t-win_arm64.whl", hash = "sha256:8e2ad4d1a5899b7caa3a450e33ee2734be7cc0689010964703a7c4bcc8dd4fd0", size = 2919255, upload-time = "2025-10-01T00:28:21.115Z" }, - { url = "https://files.pythonhosted.org/packages/d5/bb/fa95abcf147a1b0bb94d95f53fbb09da77b24c776c5d87d36f3d94521d2c/cryptography-46.0.2-cp38-abi3-macosx_10_9_universal2.whl", hash = "sha256:a08e7401a94c002e79dc3bc5231b6558cd4b2280ee525c4673f650a37e2c7685", size = 7248090, upload-time = "2025-10-01T00:28:22.846Z" }, - { url = "https://files.pythonhosted.org/packages/b7/66/f42071ce0e3ffbfa80a88feadb209c779fda92a23fbc1e14f74ebf72ef6b/cryptography-46.0.2-cp38-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:d30bc11d35743bf4ddf76674a0a369ec8a21f87aaa09b0661b04c5f6c46e8d7b", size = 4293123, upload-time = "2025-10-01T00:28:25.072Z" }, - { url = "https://files.pythonhosted.org/packages/a8/5d/1fdbd2e5c1ba822828d250e5a966622ef00185e476d1cd2726b6dd135e53/cryptography-46.0.2-cp38-abi3-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:bca3f0ce67e5a2a2cf524e86f44697c4323a86e0fd7ba857de1c30d52c11ede1", size = 4439524, upload-time = "2025-10-01T00:28:26.808Z" }, - { url = "https://files.pythonhosted.org/packages/c8/c1/5e4989a7d102d4306053770d60f978c7b6b1ea2ff8c06e0265e305b23516/cryptography-46.0.2-cp38-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:ff798ad7a957a5021dcbab78dfff681f0cf15744d0e6af62bd6746984d9c9e9c", size = 4297264, upload-time = "2025-10-01T00:28:29.327Z" }, - { url = "https://files.pythonhosted.org/packages/28/78/b56f847d220cb1d6d6aef5a390e116ad603ce13a0945a3386a33abc80385/cryptography-46.0.2-cp38-abi3-manylinux_2_28_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:cb5e8daac840e8879407acbe689a174f5ebaf344a062f8918e526824eb5d97af", size = 4011872, upload-time = "2025-10-01T00:28:31.479Z" }, - { url = "https://files.pythonhosted.org/packages/e1/80/2971f214b066b888944f7b57761bf709ee3f2cf805619a18b18cab9b263c/cryptography-46.0.2-cp38-abi3-manylinux_2_28_ppc64le.whl", hash = "sha256:3f37aa12b2d91e157827d90ce78f6180f0c02319468a0aea86ab5a9566da644b", size = 4978458, upload-time = "2025-10-01T00:28:33.267Z" }, - { url = "https://files.pythonhosted.org/packages/a5/84/0cb0a2beaa4f1cbe63ebec4e97cd7e0e9f835d0ba5ee143ed2523a1e0016/cryptography-46.0.2-cp38-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:5e38f203160a48b93010b07493c15f2babb4e0f2319bbd001885adb3f3696d21", size = 4472195, upload-time = "2025-10-01T00:28:36.039Z" }, - { url = "https://files.pythonhosted.org/packages/30/8b/2b542ddbf78835c7cd67b6fa79e95560023481213a060b92352a61a10efe/cryptography-46.0.2-cp38-abi3-manylinux_2_34_aarch64.whl", hash = "sha256:d19f5f48883752b5ab34cff9e2f7e4a7f216296f33714e77d1beb03d108632b6", size = 4296791, upload-time = "2025-10-01T00:28:37.732Z" }, - { url = "https://files.pythonhosted.org/packages/78/12/9065b40201b4f4876e93b9b94d91feb18de9150d60bd842a16a21565007f/cryptography-46.0.2-cp38-abi3-manylinux_2_34_ppc64le.whl", hash = "sha256:04911b149eae142ccd8c9a68892a70c21613864afb47aba92d8c7ed9cc001023", size = 4939629, upload-time = "2025-10-01T00:28:39.654Z" }, - { url = "https://files.pythonhosted.org/packages/f6/9e/6507dc048c1b1530d372c483dfd34e7709fc542765015425f0442b08547f/cryptography-46.0.2-cp38-abi3-manylinux_2_34_x86_64.whl", hash = "sha256:8b16c1ede6a937c291d41176934268e4ccac2c6521c69d3f5961c5a1e11e039e", size = 4471988, upload-time = "2025-10-01T00:28:41.822Z" }, - { url = "https://files.pythonhosted.org/packages/b1/86/d025584a5f7d5c5ec8d3633dbcdce83a0cd579f1141ceada7817a4c26934/cryptography-46.0.2-cp38-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:747b6f4a4a23d5a215aadd1d0b12233b4119c4313df83ab4137631d43672cc90", size = 4422989, upload-time = "2025-10-01T00:28:43.608Z" }, - { url = "https://files.pythonhosted.org/packages/4b/39/536370418b38a15a61bbe413006b79dfc3d2b4b0eafceb5581983f973c15/cryptography-46.0.2-cp38-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:6b275e398ab3a7905e168c036aad54b5969d63d3d9099a0a66cc147a3cc983be", size = 4685578, upload-time = "2025-10-01T00:28:45.361Z" }, - { url = "https://files.pythonhosted.org/packages/15/52/ea7e2b1910f547baed566c866fbb86de2402e501a89ecb4871ea7f169a81/cryptography-46.0.2-cp38-abi3-win32.whl", hash = "sha256:0b507c8e033307e37af61cb9f7159b416173bdf5b41d11c4df2e499a1d8e007c", size = 3036711, upload-time = "2025-10-01T00:28:47.096Z" }, - { url = "https://files.pythonhosted.org/packages/71/9e/171f40f9c70a873e73c2efcdbe91e1d4b1777a03398fa1c4af3c56a2477a/cryptography-46.0.2-cp38-abi3-win_amd64.whl", hash = "sha256:f9b2dc7668418fb6f221e4bf701f716e05e8eadb4f1988a2487b11aedf8abe62", size = 3500007, upload-time = "2025-10-01T00:28:48.967Z" }, - { url = "https://files.pythonhosted.org/packages/3e/7c/15ad426257615f9be8caf7f97990cf3dcbb5b8dd7ed7e0db581a1c4759dd/cryptography-46.0.2-cp38-abi3-win_arm64.whl", hash = "sha256:91447f2b17e83c9e0c89f133119d83f94ce6e0fb55dd47da0a959316e6e9cfa1", size = 2918153, upload-time = "2025-10-01T00:28:51.003Z" }, +sdist = { url = "https://files.pythonhosted.org/packages/9f/33/c00162f49c0e2fe8064a62cb92b93e50c74a72bc370ab92f86112b33ff62/cryptography-46.0.3.tar.gz", hash = "sha256:a8b17438104fed022ce745b362294d9ce35b4c2e45c1d958ad4a4b019285f4a1", size = 749258, upload-time = "2025-10-15T23:18:31.74Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/1d/42/9c391dd801d6cf0d561b5890549d4b27bafcc53b39c31a817e69d87c625b/cryptography-46.0.3-cp311-abi3-macosx_10_9_universal2.whl", hash = "sha256:109d4ddfadf17e8e7779c39f9b18111a09efb969a301a31e987416a0191ed93a", size = 7225004, upload-time = "2025-10-15T23:16:52.239Z" }, + { url = "https://files.pythonhosted.org/packages/1c/67/38769ca6b65f07461eb200e85fc1639b438bdc667be02cf7f2cd6a64601c/cryptography-46.0.3-cp311-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:09859af8466b69bc3c27bdf4f5d84a665e0f7ab5088412e9e2ec49758eca5cbc", size = 4296667, upload-time = "2025-10-15T23:16:54.369Z" }, + { url = "https://files.pythonhosted.org/packages/5c/49/498c86566a1d80e978b42f0d702795f69887005548c041636df6ae1ca64c/cryptography-46.0.3-cp311-abi3-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:01ca9ff2885f3acc98c29f1860552e37f6d7c7d013d7334ff2a9de43a449315d", size = 4450807, upload-time = "2025-10-15T23:16:56.414Z" }, + { url = "https://files.pythonhosted.org/packages/4b/0a/863a3604112174c8624a2ac3c038662d9e59970c7f926acdcfaed8d61142/cryptography-46.0.3-cp311-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:6eae65d4c3d33da080cff9c4ab1f711b15c1d9760809dad6ea763f3812d254cb", size = 4299615, upload-time = "2025-10-15T23:16:58.442Z" }, + { url = "https://files.pythonhosted.org/packages/64/02/b73a533f6b64a69f3cd3872acb6ebc12aef924d8d103133bb3ea750dc703/cryptography-46.0.3-cp311-abi3-manylinux_2_28_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:e5bf0ed4490068a2e72ac03d786693adeb909981cc596425d09032d372bcc849", size = 4016800, upload-time = "2025-10-15T23:17:00.378Z" }, + { url = "https://files.pythonhosted.org/packages/25/d5/16e41afbfa450cde85a3b7ec599bebefaef16b5c6ba4ec49a3532336ed72/cryptography-46.0.3-cp311-abi3-manylinux_2_28_ppc64le.whl", hash = "sha256:5ecfccd2329e37e9b7112a888e76d9feca2347f12f37918facbb893d7bb88ee8", size = 4984707, upload-time = "2025-10-15T23:17:01.98Z" }, + { url = "https://files.pythonhosted.org/packages/c9/56/e7e69b427c3878352c2fb9b450bd0e19ed552753491d39d7d0a2f5226d41/cryptography-46.0.3-cp311-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:a2c0cd47381a3229c403062f764160d57d4d175e022c1df84e168c6251a22eec", size = 4482541, upload-time = "2025-10-15T23:17:04.078Z" }, + { url = "https://files.pythonhosted.org/packages/78/f6/50736d40d97e8483172f1bb6e698895b92a223dba513b0ca6f06b2365339/cryptography-46.0.3-cp311-abi3-manylinux_2_34_aarch64.whl", hash = "sha256:549e234ff32571b1f4076ac269fcce7a808d3bf98b76c8dd560e42dbc66d7d91", size = 4299464, upload-time = "2025-10-15T23:17:05.483Z" }, + { url = "https://files.pythonhosted.org/packages/00/de/d8e26b1a855f19d9994a19c702fa2e93b0456beccbcfe437eda00e0701f2/cryptography-46.0.3-cp311-abi3-manylinux_2_34_ppc64le.whl", hash = "sha256:c0a7bb1a68a5d3471880e264621346c48665b3bf1c3759d682fc0864c540bd9e", size = 4950838, upload-time = "2025-10-15T23:17:07.425Z" }, + { url = "https://files.pythonhosted.org/packages/8f/29/798fc4ec461a1c9e9f735f2fc58741b0daae30688f41b2497dcbc9ed1355/cryptography-46.0.3-cp311-abi3-manylinux_2_34_x86_64.whl", hash = "sha256:10b01676fc208c3e6feeb25a8b83d81767e8059e1fe86e1dc62d10a3018fa926", size = 4481596, upload-time = "2025-10-15T23:17:09.343Z" }, + { url = "https://files.pythonhosted.org/packages/15/8d/03cd48b20a573adfff7652b76271078e3045b9f49387920e7f1f631d125e/cryptography-46.0.3-cp311-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:0abf1ffd6e57c67e92af68330d05760b7b7efb243aab8377e583284dbab72c71", size = 4426782, upload-time = "2025-10-15T23:17:11.22Z" }, + { url = "https://files.pythonhosted.org/packages/fa/b1/ebacbfe53317d55cf33165bda24c86523497a6881f339f9aae5c2e13e57b/cryptography-46.0.3-cp311-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:a04bee9ab6a4da801eb9b51f1b708a1b5b5c9eb48c03f74198464c66f0d344ac", size = 4698381, upload-time = "2025-10-15T23:17:12.829Z" }, + { url = "https://files.pythonhosted.org/packages/96/92/8a6a9525893325fc057a01f654d7efc2c64b9de90413adcf605a85744ff4/cryptography-46.0.3-cp311-abi3-win32.whl", hash = "sha256:f260d0d41e9b4da1ed1e0f1ce571f97fe370b152ab18778e9e8f67d6af432018", size = 3055988, upload-time = "2025-10-15T23:17:14.65Z" }, + { url = "https://files.pythonhosted.org/packages/7e/bf/80fbf45253ea585a1e492a6a17efcb93467701fa79e71550a430c5e60df0/cryptography-46.0.3-cp311-abi3-win_amd64.whl", hash = "sha256:a9a3008438615669153eb86b26b61e09993921ebdd75385ddd748702c5adfddb", size = 3514451, upload-time = "2025-10-15T23:17:16.142Z" }, + { url = "https://files.pythonhosted.org/packages/2e/af/9b302da4c87b0beb9db4e756386a7c6c5b8003cd0e742277888d352ae91d/cryptography-46.0.3-cp311-abi3-win_arm64.whl", hash = "sha256:5d7f93296ee28f68447397bf5198428c9aeeab45705a55d53a6343455dcb2c3c", size = 2928007, upload-time = "2025-10-15T23:17:18.04Z" }, + { url = "https://files.pythonhosted.org/packages/f5/e2/a510aa736755bffa9d2f75029c229111a1d02f8ecd5de03078f4c18d91a3/cryptography-46.0.3-cp314-cp314t-macosx_10_9_universal2.whl", hash = "sha256:00a5e7e87938e5ff9ff5447ab086a5706a957137e6e433841e9d24f38a065217", size = 7158012, upload-time = "2025-10-15T23:17:19.982Z" }, + { url = "https://files.pythonhosted.org/packages/73/dc/9aa866fbdbb95b02e7f9d086f1fccfeebf8953509b87e3f28fff927ff8a0/cryptography-46.0.3-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:c8daeb2d2174beb4575b77482320303f3d39b8e81153da4f0fb08eb5fe86a6c5", size = 4288728, upload-time = "2025-10-15T23:17:21.527Z" }, + { url = "https://files.pythonhosted.org/packages/c5/fd/bc1daf8230eaa075184cbbf5f8cd00ba9db4fd32d63fb83da4671b72ed8a/cryptography-46.0.3-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:39b6755623145ad5eff1dab323f4eae2a32a77a7abef2c5089a04a3d04366715", size = 4435078, upload-time = "2025-10-15T23:17:23.042Z" }, + { url = "https://files.pythonhosted.org/packages/82/98/d3bd5407ce4c60017f8ff9e63ffee4200ab3e23fe05b765cab805a7db008/cryptography-46.0.3-cp314-cp314t-manylinux_2_28_aarch64.whl", hash = "sha256:db391fa7c66df6762ee3f00c95a89e6d428f4d60e7abc8328f4fe155b5ac6e54", size = 4293460, upload-time = "2025-10-15T23:17:24.885Z" }, + { url = "https://files.pythonhosted.org/packages/26/e9/e23e7900983c2b8af7a08098db406cf989d7f09caea7897e347598d4cd5b/cryptography-46.0.3-cp314-cp314t-manylinux_2_28_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:78a97cf6a8839a48c49271cdcbd5cf37ca2c1d6b7fdd86cc864f302b5e9bf459", size = 3995237, upload-time = "2025-10-15T23:17:26.449Z" }, + { url = "https://files.pythonhosted.org/packages/91/15/af68c509d4a138cfe299d0d7ddb14afba15233223ebd933b4bbdbc7155d3/cryptography-46.0.3-cp314-cp314t-manylinux_2_28_ppc64le.whl", hash = "sha256:dfb781ff7eaa91a6f7fd41776ec37c5853c795d3b358d4896fdbb5df168af422", size = 4967344, upload-time = "2025-10-15T23:17:28.06Z" }, + { url = "https://files.pythonhosted.org/packages/ca/e3/8643d077c53868b681af077edf6b3cb58288b5423610f21c62aadcbe99f4/cryptography-46.0.3-cp314-cp314t-manylinux_2_28_x86_64.whl", hash = "sha256:6f61efb26e76c45c4a227835ddeae96d83624fb0d29eb5df5b96e14ed1a0afb7", size = 4466564, upload-time = "2025-10-15T23:17:29.665Z" }, + { url = "https://files.pythonhosted.org/packages/0e/43/c1e8726fa59c236ff477ff2b5dc071e54b21e5a1e51aa2cee1676f1c986f/cryptography-46.0.3-cp314-cp314t-manylinux_2_34_aarch64.whl", hash = "sha256:23b1a8f26e43f47ceb6d6a43115f33a5a37d57df4ea0ca295b780ae8546e8044", size = 4292415, upload-time = "2025-10-15T23:17:31.686Z" }, + { url = "https://files.pythonhosted.org/packages/42/f9/2f8fefdb1aee8a8e3256a0568cffc4e6d517b256a2fe97a029b3f1b9fe7e/cryptography-46.0.3-cp314-cp314t-manylinux_2_34_ppc64le.whl", hash = "sha256:b419ae593c86b87014b9be7396b385491ad7f320bde96826d0dd174459e54665", size = 4931457, upload-time = "2025-10-15T23:17:33.478Z" }, + { url = "https://files.pythonhosted.org/packages/79/30/9b54127a9a778ccd6d27c3da7563e9f2d341826075ceab89ae3b41bf5be2/cryptography-46.0.3-cp314-cp314t-manylinux_2_34_x86_64.whl", hash = "sha256:50fc3343ac490c6b08c0cf0d704e881d0d660be923fd3076db3e932007e726e3", size = 4466074, upload-time = "2025-10-15T23:17:35.158Z" }, + { url = "https://files.pythonhosted.org/packages/ac/68/b4f4a10928e26c941b1b6a179143af9f4d27d88fe84a6a3c53592d2e76bf/cryptography-46.0.3-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:22d7e97932f511d6b0b04f2bfd818d73dcd5928db509460aaf48384778eb6d20", size = 4420569, upload-time = "2025-10-15T23:17:37.188Z" }, + { url = "https://files.pythonhosted.org/packages/a3/49/3746dab4c0d1979888f125226357d3262a6dd40e114ac29e3d2abdf1ec55/cryptography-46.0.3-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:d55f3dffadd674514ad19451161118fd010988540cee43d8bc20675e775925de", size = 4681941, upload-time = "2025-10-15T23:17:39.236Z" }, + { url = "https://files.pythonhosted.org/packages/fd/30/27654c1dbaf7e4a3531fa1fc77986d04aefa4d6d78259a62c9dc13d7ad36/cryptography-46.0.3-cp314-cp314t-win32.whl", hash = "sha256:8a6e050cb6164d3f830453754094c086ff2d0b2f3a897a1d9820f6139a1f0914", size = 3022339, upload-time = "2025-10-15T23:17:40.888Z" }, + { url = "https://files.pythonhosted.org/packages/f6/30/640f34ccd4d2a1bc88367b54b926b781b5a018d65f404d409aba76a84b1c/cryptography-46.0.3-cp314-cp314t-win_amd64.whl", hash = "sha256:760f83faa07f8b64e9c33fc963d790a2edb24efb479e3520c14a45741cd9b2db", size = 3494315, upload-time = "2025-10-15T23:17:42.769Z" }, + { url = "https://files.pythonhosted.org/packages/ba/8b/88cc7e3bd0a8e7b861f26981f7b820e1f46aa9d26cc482d0feba0ecb4919/cryptography-46.0.3-cp314-cp314t-win_arm64.whl", hash = "sha256:516ea134e703e9fe26bcd1277a4b59ad30586ea90c365a87781d7887a646fe21", size = 2919331, upload-time = "2025-10-15T23:17:44.468Z" }, + { url = "https://files.pythonhosted.org/packages/fd/23/45fe7f376a7df8daf6da3556603b36f53475a99ce4faacb6ba2cf3d82021/cryptography-46.0.3-cp38-abi3-macosx_10_9_universal2.whl", hash = "sha256:cb3d760a6117f621261d662bccc8ef5bc32ca673e037c83fbe565324f5c46936", size = 7218248, upload-time = "2025-10-15T23:17:46.294Z" }, + { url = "https://files.pythonhosted.org/packages/27/32/b68d27471372737054cbd34c84981f9edbc24fe67ca225d389799614e27f/cryptography-46.0.3-cp38-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:4b7387121ac7d15e550f5cb4a43aef2559ed759c35df7336c402bb8275ac9683", size = 4294089, upload-time = "2025-10-15T23:17:48.269Z" }, + { url = "https://files.pythonhosted.org/packages/26/42/fa8389d4478368743e24e61eea78846a0006caffaf72ea24a15159215a14/cryptography-46.0.3-cp38-abi3-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:15ab9b093e8f09daab0f2159bb7e47532596075139dd74365da52ecc9cb46c5d", size = 4440029, upload-time = "2025-10-15T23:17:49.837Z" }, + { url = "https://files.pythonhosted.org/packages/5f/eb/f483db0ec5ac040824f269e93dd2bd8a21ecd1027e77ad7bdf6914f2fd80/cryptography-46.0.3-cp38-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:46acf53b40ea38f9c6c229599a4a13f0d46a6c3fa9ef19fc1a124d62e338dfa0", size = 4297222, upload-time = "2025-10-15T23:17:51.357Z" }, + { url = "https://files.pythonhosted.org/packages/fd/cf/da9502c4e1912cb1da3807ea3618a6829bee8207456fbbeebc361ec38ba3/cryptography-46.0.3-cp38-abi3-manylinux_2_28_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:10ca84c4668d066a9878890047f03546f3ae0a6b8b39b697457b7757aaf18dbc", size = 4012280, upload-time = "2025-10-15T23:17:52.964Z" }, + { url = "https://files.pythonhosted.org/packages/6b/8f/9adb86b93330e0df8b3dcf03eae67c33ba89958fc2e03862ef1ac2b42465/cryptography-46.0.3-cp38-abi3-manylinux_2_28_ppc64le.whl", hash = "sha256:36e627112085bb3b81b19fed209c05ce2a52ee8b15d161b7c643a7d5a88491f3", size = 4978958, upload-time = "2025-10-15T23:17:54.965Z" }, + { url = "https://files.pythonhosted.org/packages/d1/a0/5fa77988289c34bdb9f913f5606ecc9ada1adb5ae870bd0d1054a7021cc4/cryptography-46.0.3-cp38-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:1000713389b75c449a6e979ffc7dcc8ac90b437048766cef052d4d30b8220971", size = 4473714, upload-time = "2025-10-15T23:17:56.754Z" }, + { url = "https://files.pythonhosted.org/packages/14/e5/fc82d72a58d41c393697aa18c9abe5ae1214ff6f2a5c18ac470f92777895/cryptography-46.0.3-cp38-abi3-manylinux_2_34_aarch64.whl", hash = "sha256:b02cf04496f6576afffef5ddd04a0cb7d49cf6be16a9059d793a30b035f6b6ac", size = 4296970, upload-time = "2025-10-15T23:17:58.588Z" }, + { url = "https://files.pythonhosted.org/packages/78/06/5663ed35438d0b09056973994f1aec467492b33bd31da36e468b01ec1097/cryptography-46.0.3-cp38-abi3-manylinux_2_34_ppc64le.whl", hash = "sha256:71e842ec9bc7abf543b47cf86b9a743baa95f4677d22baa4c7d5c69e49e9bc04", size = 4940236, upload-time = "2025-10-15T23:18:00.897Z" }, + { url = "https://files.pythonhosted.org/packages/fc/59/873633f3f2dcd8a053b8dd1d38f783043b5fce589c0f6988bf55ef57e43e/cryptography-46.0.3-cp38-abi3-manylinux_2_34_x86_64.whl", hash = "sha256:402b58fc32614f00980b66d6e56a5b4118e6cb362ae8f3fda141ba4689bd4506", size = 4472642, upload-time = "2025-10-15T23:18:02.749Z" }, + { url = "https://files.pythonhosted.org/packages/3d/39/8e71f3930e40f6877737d6f69248cf74d4e34b886a3967d32f919cc50d3b/cryptography-46.0.3-cp38-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:ef639cb3372f69ec44915fafcd6698b6cc78fbe0c2ea41be867f6ed612811963", size = 4423126, upload-time = "2025-10-15T23:18:04.85Z" }, + { url = "https://files.pythonhosted.org/packages/cd/c7/f65027c2810e14c3e7268353b1681932b87e5a48e65505d8cc17c99e36ae/cryptography-46.0.3-cp38-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:3b51b8ca4f1c6453d8829e1eb7299499ca7f313900dd4d89a24b8b87c0a780d4", size = 4686573, upload-time = "2025-10-15T23:18:06.908Z" }, + { url = "https://files.pythonhosted.org/packages/0a/6e/1c8331ddf91ca4730ab3086a0f1be19c65510a33b5a441cb334e7a2d2560/cryptography-46.0.3-cp38-abi3-win32.whl", hash = "sha256:6276eb85ef938dc035d59b87c8a7dc559a232f954962520137529d77b18ff1df", size = 3036695, upload-time = "2025-10-15T23:18:08.672Z" }, + { url = "https://files.pythonhosted.org/packages/90/45/b0d691df20633eff80955a0fc7695ff9051ffce8b69741444bd9ed7bd0db/cryptography-46.0.3-cp38-abi3-win_amd64.whl", hash = "sha256:416260257577718c05135c55958b674000baef9a1c7d9e8f306ec60d71db850f", size = 3501720, upload-time = "2025-10-15T23:18:10.632Z" }, + { url = "https://files.pythonhosted.org/packages/e8/cb/2da4cc83f5edb9c3257d09e1e7ab7b23f049c7962cae8d842bbef0a9cec9/cryptography-46.0.3-cp38-abi3-win_arm64.whl", hash = "sha256:d89c3468de4cdc4f08a57e214384d0471911a3830fcdaf7a8cc587e42a866372", size = 2918740, upload-time = "2025-10-15T23:18:12.277Z" }, ] [[package]] @@ -537,16 +537,16 @@ wheels = [ [[package]] name = "fastapi" -version = "0.118.2" +version = "0.119.1" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "pydantic" }, { name = "starlette" }, { name = "typing-extensions" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/2e/ad/31a59efecca3b584440cafac6f69634f4661295c858912c2b2905280a089/fastapi-0.118.2.tar.gz", hash = "sha256:d5388dbe76d97cb6ccd2c93b4dd981608062ebf6335280edfa9a11af82443e18", size = 311963, upload-time = "2025-10-08T14:52:17.796Z" } +sdist = { url = "https://files.pythonhosted.org/packages/a6/f4/152127681182e6413e7a89684c434e19e7414ed7ac0c632999c3c6980640/fastapi-0.119.1.tar.gz", hash = "sha256:a5e3426edce3fe221af4e1992c6d79011b247e3b03cc57999d697fe76cbf8ae0", size = 338616, upload-time = "2025-10-20T11:30:27.734Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/45/7c/97d033faf771c9fe960c7b51eb78ab266bfa64cbc917601978963f0c3c7b/fastapi-0.118.2-py3-none-any.whl", hash = "sha256:d1f842612e6a305f95abe784b7f8d3215477742e7c67a16fccd20bd79db68150", size = 97954, upload-time = "2025-10-08T14:52:16.166Z" }, + { url = "https://files.pythonhosted.org/packages/b1/26/e6d959b4ac959fdb3e9c4154656fc160794db6af8e64673d52759456bf07/fastapi-0.119.1-py3-none-any.whl", hash = "sha256:0b8c2a2cce853216e150e9bd4faaed88227f8eb37de21cb200771f491586a27f", size = 108123, upload-time = "2025-10-20T11:30:26.185Z" }, ] [package.optional-dependencies] @@ -561,16 +561,16 @@ standard = [ [[package]] name = "fastapi-cli" -version = "0.0.13" +version = "0.0.14" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "rich-toolkit" }, { name = "typer" }, { name = "uvicorn", extra = ["standard"] }, ] -sdist = { url = "https://files.pythonhosted.org/packages/32/4e/3f61850012473b097fc5297d681bd85788e186fadb8555b67baf4c7707f4/fastapi_cli-0.0.13.tar.gz", hash = "sha256:312addf3f57ba7139457cf0d345c03e2170cc5a034057488259c33cd7e494529", size = 17780, upload-time = "2025-09-20T16:37:31.089Z" } +sdist = { url = "https://files.pythonhosted.org/packages/cc/13/11e43d630be84e51ba5510a6da6a11eb93b44b72caa796137c5dddda937b/fastapi_cli-0.0.14.tar.gz", hash = "sha256:ddfb5de0a67f77a8b3271af1460489bd4d7f4add73d11fbfac613827b0275274", size = 17994, upload-time = "2025-10-20T16:33:21.054Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/08/36/7432750f3638324b055496d2c952000bea824259fca70df5577a6a3c172f/fastapi_cli-0.0.13-py3-none-any.whl", hash = "sha256:219b73ccfde7622559cef1d43197da928516acb4f21f2ec69128c4b90057baba", size = 11142, upload-time = "2025-09-20T16:37:29.695Z" }, + { url = "https://files.pythonhosted.org/packages/40/e8/bc8bbfd93dcc8e347ce98a3e654fb0d2e5f2739afb46b98f41a30c339269/fastapi_cli-0.0.14-py3-none-any.whl", hash = "sha256:e66b9ad499ee77a4e6007545cde6de1459b7f21df199d7f29aad2adaab168eca", size = 11151, upload-time = "2025-10-20T16:33:19.318Z" }, ] [package.optional-dependencies] @@ -711,7 +711,7 @@ wheels = [ [[package]] name = "google-api-python-client" -version = "2.184.0" +version = "2.185.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "google-api-core" }, @@ -720,9 +720,9 @@ dependencies = [ { name = "httplib2" }, { name = "uritemplate" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/7c/30/8b3a626ccf84ca43da62d77e2d40d70bedc6387951cc5104011cddce34e0/google_api_python_client-2.184.0.tar.gz", hash = "sha256:ef2a3330ad058cdfc8a558d199c051c3356f6ed012436c3ad3d08b67891b039f", size = 13694120, upload-time = "2025-10-01T21:13:48.961Z" } +sdist = { url = "https://files.pythonhosted.org/packages/8e/5a/6f9b49d67ea91376305fdb8bbf2877c746d756e45fd8fb7d2e32d6dad19b/google_api_python_client-2.185.0.tar.gz", hash = "sha256:aa1b338e4bb0f141c2df26743f6b46b11f38705aacd775b61971cbc51da089c3", size = 13885609, upload-time = "2025-10-17T15:00:35.623Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/f4/38/d25ae1565103a545cf18207a5dec09a6d39ad88e5b0399a2430e9edb0550/google_api_python_client-2.184.0-py3-none-any.whl", hash = "sha256:15a18d02f42de99416921c77be235d12ead474e474a1abc348b01a2b92633fa4", size = 14260480, upload-time = "2025-10-01T21:13:46.037Z" }, + { url = "https://files.pythonhosted.org/packages/fa/28/be3b17bd6a190c8c2ec9e4fb65d43e6ecd7b7a1bb19ccc1d9ab4f687a58c/google_api_python_client-2.185.0-py3-none-any.whl", hash = "sha256:00fe173a4b346d2397fbe0d37ac15368170dfbed91a0395a66ef2558e22b93fc", size = 14453595, upload-time = "2025-10-17T15:00:33.176Z" }, ] [[package]] @@ -754,14 +754,14 @@ wheels = [ [[package]] name = "googleapis-common-protos" -version = "1.70.0" +version = "1.71.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "protobuf" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/39/24/33db22342cf4a2ea27c9955e6713140fedd51e8b141b5ce5260897020f1a/googleapis_common_protos-1.70.0.tar.gz", hash = "sha256:0e1b44e0ea153e6594f9f394fef15193a68aaaea2d843f83e2742717ca753257", size = 145903, upload-time = "2025-04-14T10:17:02.924Z" } +sdist = { url = "https://files.pythonhosted.org/packages/30/43/b25abe02db2911397819003029bef768f68a974f2ece483e6084d1a5f754/googleapis_common_protos-1.71.0.tar.gz", hash = "sha256:1aec01e574e29da63c80ba9f7bbf1ccfaacf1da877f23609fe236ca7c72a2e2e", size = 146454, upload-time = "2025-10-20T14:58:08.732Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/86/f1/62a193f0227cf15a920390abe675f386dec35f7ae3ffe6da582d3ade42c7/googleapis_common_protos-1.70.0-py3-none-any.whl", hash = "sha256:b8bfcca8c25a2bb253e0e0b0adaf8c00773e5e6af6fd92397576680b807e0fd8", size = 294530, upload-time = "2025-04-14T10:17:01.271Z" }, + { url = "https://files.pythonhosted.org/packages/25/e8/eba9fece11d57a71e3e22ea672742c8f3cf23b35730c9e96db768b295216/googleapis_common_protos-1.71.0-py3-none-any.whl", hash = "sha256:59034a1d849dc4d18971997a72ac56246570afdd17f9369a0ff68218d50ab78c", size = 294576, upload-time = "2025-10-20T14:56:21.295Z" }, ] [[package]] @@ -894,11 +894,11 @@ wheels = [ [[package]] name = "iniconfig" -version = "2.1.0" +version = "2.3.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/f2/97/ebf4da567aa6827c909642694d71c9fcf53e5b504f2d96afea02718862f3/iniconfig-2.1.0.tar.gz", hash = "sha256:3abbd2e30b36733fee78f9c7f7308f2d0050e88f0087fd25c2645f63c773e1c7", size = 4793, upload-time = "2025-03-19T20:09:59.721Z" } +sdist = { url = "https://files.pythonhosted.org/packages/72/34/14ca021ce8e5dfedc35312d08ba8bf51fdd999c576889fc2c24cb97f4f10/iniconfig-2.3.0.tar.gz", hash = "sha256:c76315c77db068650d49c5b56314774a7804df16fee4402c1f19d6d15d8c4730", size = 20503, upload-time = "2025-10-18T21:55:43.219Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/2c/e1/e6716421ea10d38022b952c159d5161ca1193197fb744506875fbb87ea7b/iniconfig-2.1.0-py3-none-any.whl", hash = "sha256:9deba5723312380e77435581c6bf4935c94cbfab9b1ed33ef8d238ea168eb760", size = 6050, upload-time = "2025-03-19T20:10:01.071Z" }, + { url = "https://files.pythonhosted.org/packages/cb/b1/3846dd7f199d53cb17f49cba7e651e9ce294d8497c8c150530ed11865bb8/iniconfig-2.3.0-py3-none-any.whl", hash = "sha256:f631c04d2c48c52b84d0d0549c99ff3859c98df65b3101406327ecc7d53fbf12", size = 7484, upload-time = "2025-10-18T21:55:41.639Z" }, ] [[package]] @@ -1045,54 +1045,54 @@ wheels = [ [[package]] name = "numpy" -version = "2.3.3" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/d0/19/95b3d357407220ed24c139018d2518fab0a61a948e68286a25f1a4d049ff/numpy-2.3.3.tar.gz", hash = "sha256:ddc7c39727ba62b80dfdbedf400d1c10ddfa8eefbd7ec8dcb118be8b56d31029", size = 20576648, upload-time = "2025-09-09T16:54:12.543Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/7d/b9/984c2b1ee61a8b803bf63582b4ac4242cf76e2dbd663efeafcb620cc0ccb/numpy-2.3.3-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:f5415fb78995644253370985342cd03572ef8620b934da27d77377a2285955bf", size = 20949588, upload-time = "2025-09-09T15:56:59.087Z" }, - { url = "https://files.pythonhosted.org/packages/a6/e4/07970e3bed0b1384d22af1e9912527ecbeb47d3b26e9b6a3bced068b3bea/numpy-2.3.3-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:d00de139a3324e26ed5b95870ce63be7ec7352171bc69a4cf1f157a48e3eb6b7", size = 14177802, upload-time = "2025-09-09T15:57:01.73Z" }, - { url = "https://files.pythonhosted.org/packages/35/c7/477a83887f9de61f1203bad89cf208b7c19cc9fef0cebef65d5a1a0619f2/numpy-2.3.3-cp313-cp313-macosx_14_0_arm64.whl", hash = "sha256:9dc13c6a5829610cc07422bc74d3ac083bd8323f14e2827d992f9e52e22cd6a6", size = 5106537, upload-time = "2025-09-09T15:57:03.765Z" }, - { url = "https://files.pythonhosted.org/packages/52/47/93b953bd5866a6f6986344d045a207d3f1cfbad99db29f534ea9cee5108c/numpy-2.3.3-cp313-cp313-macosx_14_0_x86_64.whl", hash = "sha256:d79715d95f1894771eb4e60fb23f065663b2298f7d22945d66877aadf33d00c7", size = 6640743, upload-time = "2025-09-09T15:57:07.921Z" }, - { url = "https://files.pythonhosted.org/packages/23/83/377f84aaeb800b64c0ef4de58b08769e782edcefa4fea712910b6f0afd3c/numpy-2.3.3-cp313-cp313-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:952cfd0748514ea7c3afc729a0fc639e61655ce4c55ab9acfab14bda4f402b4c", size = 14278881, upload-time = "2025-09-09T15:57:11.349Z" }, - { url = "https://files.pythonhosted.org/packages/9a/a5/bf3db6e66c4b160d6ea10b534c381a1955dfab34cb1017ea93aa33c70ed3/numpy-2.3.3-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:5b83648633d46f77039c29078751f80da65aa64d5622a3cd62aaef9d835b6c93", size = 16636301, upload-time = "2025-09-09T15:57:14.245Z" }, - { url = "https://files.pythonhosted.org/packages/a2/59/1287924242eb4fa3f9b3a2c30400f2e17eb2707020d1c5e3086fe7330717/numpy-2.3.3-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:b001bae8cea1c7dfdb2ae2b017ed0a6f2102d7a70059df1e338e307a4c78a8ae", size = 16053645, upload-time = "2025-09-09T15:57:16.534Z" }, - { url = "https://files.pythonhosted.org/packages/e6/93/b3d47ed882027c35e94ac2320c37e452a549f582a5e801f2d34b56973c97/numpy-2.3.3-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:8e9aced64054739037d42fb84c54dd38b81ee238816c948c8f3ed134665dcd86", size = 18578179, upload-time = "2025-09-09T15:57:18.883Z" }, - { url = "https://files.pythonhosted.org/packages/20/d9/487a2bccbf7cc9d4bfc5f0f197761a5ef27ba870f1e3bbb9afc4bbe3fcc2/numpy-2.3.3-cp313-cp313-win32.whl", hash = "sha256:9591e1221db3f37751e6442850429b3aabf7026d3b05542d102944ca7f00c8a8", size = 6312250, upload-time = "2025-09-09T15:57:21.296Z" }, - { url = "https://files.pythonhosted.org/packages/1b/b5/263ebbbbcede85028f30047eab3d58028d7ebe389d6493fc95ae66c636ab/numpy-2.3.3-cp313-cp313-win_amd64.whl", hash = "sha256:f0dadeb302887f07431910f67a14d57209ed91130be0adea2f9793f1a4f817cf", size = 12783269, upload-time = "2025-09-09T15:57:23.034Z" }, - { url = "https://files.pythonhosted.org/packages/fa/75/67b8ca554bbeaaeb3fac2e8bce46967a5a06544c9108ec0cf5cece559b6c/numpy-2.3.3-cp313-cp313-win_arm64.whl", hash = "sha256:3c7cf302ac6e0b76a64c4aecf1a09e51abd9b01fc7feee80f6c43e3ab1b1dbc5", size = 10195314, upload-time = "2025-09-09T15:57:25.045Z" }, - { url = "https://files.pythonhosted.org/packages/11/d0/0d1ddec56b162042ddfafeeb293bac672de9b0cfd688383590090963720a/numpy-2.3.3-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:eda59e44957d272846bb407aad19f89dc6f58fecf3504bd144f4c5cf81a7eacc", size = 21048025, upload-time = "2025-09-09T15:57:27.257Z" }, - { url = "https://files.pythonhosted.org/packages/36/9e/1996ca6b6d00415b6acbdd3c42f7f03ea256e2c3f158f80bd7436a8a19f3/numpy-2.3.3-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:823d04112bc85ef5c4fda73ba24e6096c8f869931405a80aa8b0e604510a26bc", size = 14301053, upload-time = "2025-09-09T15:57:30.077Z" }, - { url = "https://files.pythonhosted.org/packages/05/24/43da09aa764c68694b76e84b3d3f0c44cb7c18cdc1ba80e48b0ac1d2cd39/numpy-2.3.3-cp313-cp313t-macosx_14_0_arm64.whl", hash = "sha256:40051003e03db4041aa325da2a0971ba41cf65714e65d296397cc0e32de6018b", size = 5229444, upload-time = "2025-09-09T15:57:32.733Z" }, - { url = "https://files.pythonhosted.org/packages/bc/14/50ffb0f22f7218ef8af28dd089f79f68289a7a05a208db9a2c5dcbe123c1/numpy-2.3.3-cp313-cp313t-macosx_14_0_x86_64.whl", hash = "sha256:6ee9086235dd6ab7ae75aba5662f582a81ced49f0f1c6de4260a78d8f2d91a19", size = 6738039, upload-time = "2025-09-09T15:57:34.328Z" }, - { url = "https://files.pythonhosted.org/packages/55/52/af46ac0795e09657d45a7f4db961917314377edecf66db0e39fa7ab5c3d3/numpy-2.3.3-cp313-cp313t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:94fcaa68757c3e2e668ddadeaa86ab05499a70725811e582b6a9858dd472fb30", size = 14352314, upload-time = "2025-09-09T15:57:36.255Z" }, - { url = "https://files.pythonhosted.org/packages/a7/b1/dc226b4c90eb9f07a3fff95c2f0db3268e2e54e5cce97c4ac91518aee71b/numpy-2.3.3-cp313-cp313t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:da1a74b90e7483d6ce5244053399a614b1d6b7bc30a60d2f570e5071f8959d3e", size = 16701722, upload-time = "2025-09-09T15:57:38.622Z" }, - { url = "https://files.pythonhosted.org/packages/9d/9d/9d8d358f2eb5eced14dba99f110d83b5cd9a4460895230f3b396ad19a323/numpy-2.3.3-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:2990adf06d1ecee3b3dcbb4977dfab6e9f09807598d647f04d385d29e7a3c3d3", size = 16132755, upload-time = "2025-09-09T15:57:41.16Z" }, - { url = "https://files.pythonhosted.org/packages/b6/27/b3922660c45513f9377b3fb42240bec63f203c71416093476ec9aa0719dc/numpy-2.3.3-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:ed635ff692483b8e3f0fcaa8e7eb8a75ee71aa6d975388224f70821421800cea", size = 18651560, upload-time = "2025-09-09T15:57:43.459Z" }, - { url = "https://files.pythonhosted.org/packages/5b/8e/3ab61a730bdbbc201bb245a71102aa609f0008b9ed15255500a99cd7f780/numpy-2.3.3-cp313-cp313t-win32.whl", hash = "sha256:a333b4ed33d8dc2b373cc955ca57babc00cd6f9009991d9edc5ddbc1bac36bcd", size = 6442776, upload-time = "2025-09-09T15:57:45.793Z" }, - { url = "https://files.pythonhosted.org/packages/1c/3a/e22b766b11f6030dc2decdeff5c2fb1610768055603f9f3be88b6d192fb2/numpy-2.3.3-cp313-cp313t-win_amd64.whl", hash = "sha256:4384a169c4d8f97195980815d6fcad04933a7e1ab3b530921c3fef7a1c63426d", size = 12927281, upload-time = "2025-09-09T15:57:47.492Z" }, - { url = "https://files.pythonhosted.org/packages/7b/42/c2e2bc48c5e9b2a83423f99733950fbefd86f165b468a3d85d52b30bf782/numpy-2.3.3-cp313-cp313t-win_arm64.whl", hash = "sha256:75370986cc0bc66f4ce5110ad35aae6d182cc4ce6433c40ad151f53690130bf1", size = 10265275, upload-time = "2025-09-09T15:57:49.647Z" }, - { url = "https://files.pythonhosted.org/packages/6b/01/342ad585ad82419b99bcf7cebe99e61da6bedb89e213c5fd71acc467faee/numpy-2.3.3-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:cd052f1fa6a78dee696b58a914b7229ecfa41f0a6d96dc663c1220a55e137593", size = 20951527, upload-time = "2025-09-09T15:57:52.006Z" }, - { url = "https://files.pythonhosted.org/packages/ef/d8/204e0d73fc1b7a9ee80ab1fe1983dd33a4d64a4e30a05364b0208e9a241a/numpy-2.3.3-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:414a97499480067d305fcac9716c29cf4d0d76db6ebf0bf3cbce666677f12652", size = 14186159, upload-time = "2025-09-09T15:57:54.407Z" }, - { url = "https://files.pythonhosted.org/packages/22/af/f11c916d08f3a18fb8ba81ab72b5b74a6e42ead4c2846d270eb19845bf74/numpy-2.3.3-cp314-cp314-macosx_14_0_arm64.whl", hash = "sha256:50a5fe69f135f88a2be9b6ca0481a68a136f6febe1916e4920e12f1a34e708a7", size = 5114624, upload-time = "2025-09-09T15:57:56.5Z" }, - { url = "https://files.pythonhosted.org/packages/fb/11/0ed919c8381ac9d2ffacd63fd1f0c34d27e99cab650f0eb6f110e6ae4858/numpy-2.3.3-cp314-cp314-macosx_14_0_x86_64.whl", hash = "sha256:b912f2ed2b67a129e6a601e9d93d4fa37bef67e54cac442a2f588a54afe5c67a", size = 6642627, upload-time = "2025-09-09T15:57:58.206Z" }, - { url = "https://files.pythonhosted.org/packages/ee/83/deb5f77cb0f7ba6cb52b91ed388b47f8f3c2e9930d4665c600408d9b90b9/numpy-2.3.3-cp314-cp314-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:9e318ee0596d76d4cb3d78535dc005fa60e5ea348cd131a51e99d0bdbe0b54fe", size = 14296926, upload-time = "2025-09-09T15:58:00.035Z" }, - { url = "https://files.pythonhosted.org/packages/77/cc/70e59dcb84f2b005d4f306310ff0a892518cc0c8000a33d0e6faf7ca8d80/numpy-2.3.3-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:ce020080e4a52426202bdb6f7691c65bb55e49f261f31a8f506c9f6bc7450421", size = 16638958, upload-time = "2025-09-09T15:58:02.738Z" }, - { url = "https://files.pythonhosted.org/packages/b6/5a/b2ab6c18b4257e099587d5b7f903317bd7115333ad8d4ec4874278eafa61/numpy-2.3.3-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:e6687dc183aa55dae4a705b35f9c0f8cb178bcaa2f029b241ac5356221d5c021", size = 16071920, upload-time = "2025-09-09T15:58:05.029Z" }, - { url = "https://files.pythonhosted.org/packages/b8/f1/8b3fdc44324a259298520dd82147ff648979bed085feeacc1250ef1656c0/numpy-2.3.3-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:d8f3b1080782469fdc1718c4ed1d22549b5fb12af0d57d35e992158a772a37cf", size = 18577076, upload-time = "2025-09-09T15:58:07.745Z" }, - { url = "https://files.pythonhosted.org/packages/f0/a1/b87a284fb15a42e9274e7fcea0dad259d12ddbf07c1595b26883151ca3b4/numpy-2.3.3-cp314-cp314-win32.whl", hash = "sha256:cb248499b0bc3be66ebd6578b83e5acacf1d6cb2a77f2248ce0e40fbec5a76d0", size = 6366952, upload-time = "2025-09-09T15:58:10.096Z" }, - { url = "https://files.pythonhosted.org/packages/70/5f/1816f4d08f3b8f66576d8433a66f8fa35a5acfb3bbd0bf6c31183b003f3d/numpy-2.3.3-cp314-cp314-win_amd64.whl", hash = "sha256:691808c2b26b0f002a032c73255d0bd89751425f379f7bcd22d140db593a96e8", size = 12919322, upload-time = "2025-09-09T15:58:12.138Z" }, - { url = "https://files.pythonhosted.org/packages/8c/de/072420342e46a8ea41c324a555fa90fcc11637583fb8df722936aed1736d/numpy-2.3.3-cp314-cp314-win_arm64.whl", hash = "sha256:9ad12e976ca7b10f1774b03615a2a4bab8addce37ecc77394d8e986927dc0dfe", size = 10478630, upload-time = "2025-09-09T15:58:14.64Z" }, - { url = "https://files.pythonhosted.org/packages/d5/df/ee2f1c0a9de7347f14da5dd3cd3c3b034d1b8607ccb6883d7dd5c035d631/numpy-2.3.3-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:9cc48e09feb11e1db00b320e9d30a4151f7369afb96bd0e48d942d09da3a0d00", size = 21047987, upload-time = "2025-09-09T15:58:16.889Z" }, - { url = "https://files.pythonhosted.org/packages/d6/92/9453bdc5a4e9e69cf4358463f25e8260e2ffc126d52e10038b9077815989/numpy-2.3.3-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:901bf6123879b7f251d3631967fd574690734236075082078e0571977c6a8e6a", size = 14301076, upload-time = "2025-09-09T15:58:20.343Z" }, - { url = "https://files.pythonhosted.org/packages/13/77/1447b9eb500f028bb44253105bd67534af60499588a5149a94f18f2ca917/numpy-2.3.3-cp314-cp314t-macosx_14_0_arm64.whl", hash = "sha256:7f025652034199c301049296b59fa7d52c7e625017cae4c75d8662e377bf487d", size = 5229491, upload-time = "2025-09-09T15:58:22.481Z" }, - { url = "https://files.pythonhosted.org/packages/3d/f9/d72221b6ca205f9736cb4b2ce3b002f6e45cd67cd6a6d1c8af11a2f0b649/numpy-2.3.3-cp314-cp314t-macosx_14_0_x86_64.whl", hash = "sha256:533ca5f6d325c80b6007d4d7fb1984c303553534191024ec6a524a4c92a5935a", size = 6737913, upload-time = "2025-09-09T15:58:24.569Z" }, - { url = "https://files.pythonhosted.org/packages/3c/5f/d12834711962ad9c46af72f79bb31e73e416ee49d17f4c797f72c96b6ca5/numpy-2.3.3-cp314-cp314t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:0edd58682a399824633b66885d699d7de982800053acf20be1eaa46d92009c54", size = 14352811, upload-time = "2025-09-09T15:58:26.416Z" }, - { url = "https://files.pythonhosted.org/packages/a1/0d/fdbec6629d97fd1bebed56cd742884e4eead593611bbe1abc3eb40d304b2/numpy-2.3.3-cp314-cp314t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:367ad5d8fbec5d9296d18478804a530f1191e24ab4d75ab408346ae88045d25e", size = 16702689, upload-time = "2025-09-09T15:58:28.831Z" }, - { url = "https://files.pythonhosted.org/packages/9b/09/0a35196dc5575adde1eb97ddfbc3e1687a814f905377621d18ca9bc2b7dd/numpy-2.3.3-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:8f6ac61a217437946a1fa48d24c47c91a0c4f725237871117dea264982128097", size = 16133855, upload-time = "2025-09-09T15:58:31.349Z" }, - { url = "https://files.pythonhosted.org/packages/7a/ca/c9de3ea397d576f1b6753eaa906d4cdef1bf97589a6d9825a349b4729cc2/numpy-2.3.3-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:179a42101b845a816d464b6fe9a845dfaf308fdfc7925387195570789bb2c970", size = 18652520, upload-time = "2025-09-09T15:58:33.762Z" }, - { url = "https://files.pythonhosted.org/packages/fd/c2/e5ed830e08cd0196351db55db82f65bc0ab05da6ef2b72a836dcf1936d2f/numpy-2.3.3-cp314-cp314t-win32.whl", hash = "sha256:1250c5d3d2562ec4174bce2e3a1523041595f9b651065e4a4473f5f48a6bc8a5", size = 6515371, upload-time = "2025-09-09T15:58:36.04Z" }, - { url = "https://files.pythonhosted.org/packages/47/c7/b0f6b5b67f6788a0725f744496badbb604d226bf233ba716683ebb47b570/numpy-2.3.3-cp314-cp314t-win_amd64.whl", hash = "sha256:b37a0b2e5935409daebe82c1e42274d30d9dd355852529eab91dab8dcca7419f", size = 13112576, upload-time = "2025-09-09T15:58:37.927Z" }, - { url = "https://files.pythonhosted.org/packages/06/b9/33bba5ff6fb679aa0b1f8a07e853f002a6b04b9394db3069a1270a7784ca/numpy-2.3.3-cp314-cp314t-win_arm64.whl", hash = "sha256:78c9f6560dc7e6b3990e32df7ea1a50bbd0e2a111e05209963f5ddcab7073b0b", size = 10545953, upload-time = "2025-09-09T15:58:40.576Z" }, +version = "2.3.4" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/b5/f4/098d2270d52b41f1bd7db9fc288aaa0400cb48c2a3e2af6fa365d9720947/numpy-2.3.4.tar.gz", hash = "sha256:a7d018bfedb375a8d979ac758b120ba846a7fe764911a64465fd87b8729f4a6a", size = 20582187, upload-time = "2025-10-15T16:18:11.77Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/57/7e/b72610cc91edf138bc588df5150957a4937221ca6058b825b4725c27be62/numpy-2.3.4-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:c090d4860032b857d94144d1a9976b8e36709e40386db289aaf6672de2a81966", size = 20950335, upload-time = "2025-10-15T16:16:10.304Z" }, + { url = "https://files.pythonhosted.org/packages/3e/46/bdd3370dcea2f95ef14af79dbf81e6927102ddf1cc54adc0024d61252fd9/numpy-2.3.4-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:a13fc473b6db0be619e45f11f9e81260f7302f8d180c49a22b6e6120022596b3", size = 14179878, upload-time = "2025-10-15T16:16:12.595Z" }, + { url = "https://files.pythonhosted.org/packages/ac/01/5a67cb785bda60f45415d09c2bc245433f1c68dd82eef9c9002c508b5a65/numpy-2.3.4-cp313-cp313-macosx_14_0_arm64.whl", hash = "sha256:3634093d0b428e6c32c3a69b78e554f0cd20ee420dcad5a9f3b2a63762ce4197", size = 5108673, upload-time = "2025-10-15T16:16:14.877Z" }, + { url = "https://files.pythonhosted.org/packages/c2/cd/8428e23a9fcebd33988f4cb61208fda832800ca03781f471f3727a820704/numpy-2.3.4-cp313-cp313-macosx_14_0_x86_64.whl", hash = "sha256:043885b4f7e6e232d7df4f51ffdef8c36320ee9d5f227b380ea636722c7ed12e", size = 6641438, upload-time = "2025-10-15T16:16:16.805Z" }, + { url = "https://files.pythonhosted.org/packages/3e/d1/913fe563820f3c6b079f992458f7331278dcd7ba8427e8e745af37ddb44f/numpy-2.3.4-cp313-cp313-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:4ee6a571d1e4f0ea6d5f22d6e5fbd6ed1dc2b18542848e1e7301bd190500c9d7", size = 14281290, upload-time = "2025-10-15T16:16:18.764Z" }, + { url = "https://files.pythonhosted.org/packages/9e/7e/7d306ff7cb143e6d975cfa7eb98a93e73495c4deabb7d1b5ecf09ea0fd69/numpy-2.3.4-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:fc8a63918b04b8571789688b2780ab2b4a33ab44bfe8ccea36d3eba51228c953", size = 16636543, upload-time = "2025-10-15T16:16:21.072Z" }, + { url = "https://files.pythonhosted.org/packages/47/6a/8cfc486237e56ccfb0db234945552a557ca266f022d281a2f577b98e955c/numpy-2.3.4-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:40cc556d5abbc54aabe2b1ae287042d7bdb80c08edede19f0c0afb36ae586f37", size = 16056117, upload-time = "2025-10-15T16:16:23.369Z" }, + { url = "https://files.pythonhosted.org/packages/b1/0e/42cb5e69ea901e06ce24bfcc4b5664a56f950a70efdcf221f30d9615f3f3/numpy-2.3.4-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:ecb63014bb7f4ce653f8be7f1df8cbc6093a5a2811211770f6606cc92b5a78fd", size = 18577788, upload-time = "2025-10-15T16:16:27.496Z" }, + { url = "https://files.pythonhosted.org/packages/86/92/41c3d5157d3177559ef0a35da50f0cda7fa071f4ba2306dd36818591a5bc/numpy-2.3.4-cp313-cp313-win32.whl", hash = "sha256:e8370eb6925bb8c1c4264fec52b0384b44f675f191df91cbe0140ec9f0955646", size = 6282620, upload-time = "2025-10-15T16:16:29.811Z" }, + { url = "https://files.pythonhosted.org/packages/09/97/fd421e8bc50766665ad35536c2bb4ef916533ba1fdd053a62d96cc7c8b95/numpy-2.3.4-cp313-cp313-win_amd64.whl", hash = "sha256:56209416e81a7893036eea03abcb91c130643eb14233b2515c90dcac963fe99d", size = 12784672, upload-time = "2025-10-15T16:16:31.589Z" }, + { url = "https://files.pythonhosted.org/packages/ad/df/5474fb2f74970ca8eb978093969b125a84cc3d30e47f82191f981f13a8a0/numpy-2.3.4-cp313-cp313-win_arm64.whl", hash = "sha256:a700a4031bc0fd6936e78a752eefb79092cecad2599ea9c8039c548bc097f9bc", size = 10196702, upload-time = "2025-10-15T16:16:33.902Z" }, + { url = "https://files.pythonhosted.org/packages/11/83/66ac031464ec1767ea3ed48ce40f615eb441072945e98693bec0bcd056cc/numpy-2.3.4-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:86966db35c4040fdca64f0816a1c1dd8dbd027d90fca5a57e00e1ca4cd41b879", size = 21049003, upload-time = "2025-10-15T16:16:36.101Z" }, + { url = "https://files.pythonhosted.org/packages/5f/99/5b14e0e686e61371659a1d5bebd04596b1d72227ce36eed121bb0aeab798/numpy-2.3.4-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:838f045478638b26c375ee96ea89464d38428c69170360b23a1a50fa4baa3562", size = 14302980, upload-time = "2025-10-15T16:16:39.124Z" }, + { url = "https://files.pythonhosted.org/packages/2c/44/e9486649cd087d9fc6920e3fc3ac2aba10838d10804b1e179fb7cbc4e634/numpy-2.3.4-cp313-cp313t-macosx_14_0_arm64.whl", hash = "sha256:d7315ed1dab0286adca467377c8381cd748f3dc92235f22a7dfc42745644a96a", size = 5231472, upload-time = "2025-10-15T16:16:41.168Z" }, + { url = "https://files.pythonhosted.org/packages/3e/51/902b24fa8887e5fe2063fd61b1895a476d0bbf46811ab0c7fdf4bd127345/numpy-2.3.4-cp313-cp313t-macosx_14_0_x86_64.whl", hash = "sha256:84f01a4d18b2cc4ade1814a08e5f3c907b079c847051d720fad15ce37aa930b6", size = 6739342, upload-time = "2025-10-15T16:16:43.777Z" }, + { url = "https://files.pythonhosted.org/packages/34/f1/4de9586d05b1962acdcdb1dc4af6646361a643f8c864cef7c852bf509740/numpy-2.3.4-cp313-cp313t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:817e719a868f0dacde4abdfc5c1910b301877970195db9ab6a5e2c4bd5b121f7", size = 14354338, upload-time = "2025-10-15T16:16:46.081Z" }, + { url = "https://files.pythonhosted.org/packages/1f/06/1c16103b425de7969d5a76bdf5ada0804b476fed05d5f9e17b777f1cbefd/numpy-2.3.4-cp313-cp313t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:85e071da78d92a214212cacea81c6da557cab307f2c34b5f85b628e94803f9c0", size = 16702392, upload-time = "2025-10-15T16:16:48.455Z" }, + { url = "https://files.pythonhosted.org/packages/34/b2/65f4dc1b89b5322093572b6e55161bb42e3e0487067af73627f795cc9d47/numpy-2.3.4-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:2ec646892819370cf3558f518797f16597b4e4669894a2ba712caccc9da53f1f", size = 16134998, upload-time = "2025-10-15T16:16:51.114Z" }, + { url = "https://files.pythonhosted.org/packages/d4/11/94ec578896cdb973aaf56425d6c7f2aff4186a5c00fac15ff2ec46998b46/numpy-2.3.4-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:035796aaaddfe2f9664b9a9372f089cfc88bd795a67bd1bfe15e6e770934cf64", size = 18651574, upload-time = "2025-10-15T16:16:53.429Z" }, + { url = "https://files.pythonhosted.org/packages/62/b7/7efa763ab33dbccf56dade36938a77345ce8e8192d6b39e470ca25ff3cd0/numpy-2.3.4-cp313-cp313t-win32.whl", hash = "sha256:fea80f4f4cf83b54c3a051f2f727870ee51e22f0248d3114b8e755d160b38cfb", size = 6413135, upload-time = "2025-10-15T16:16:55.992Z" }, + { url = "https://files.pythonhosted.org/packages/43/70/aba4c38e8400abcc2f345e13d972fb36c26409b3e644366db7649015f291/numpy-2.3.4-cp313-cp313t-win_amd64.whl", hash = "sha256:15eea9f306b98e0be91eb344a94c0e630689ef302e10c2ce5f7e11905c704f9c", size = 12928582, upload-time = "2025-10-15T16:16:57.943Z" }, + { url = "https://files.pythonhosted.org/packages/67/63/871fad5f0073fc00fbbdd7232962ea1ac40eeaae2bba66c76214f7954236/numpy-2.3.4-cp313-cp313t-win_arm64.whl", hash = "sha256:b6c231c9c2fadbae4011ca5e7e83e12dc4a5072f1a1d85a0a7b3ed754d145a40", size = 10266691, upload-time = "2025-10-15T16:17:00.048Z" }, + { url = "https://files.pythonhosted.org/packages/72/71/ae6170143c115732470ae3a2d01512870dd16e0953f8a6dc89525696069b/numpy-2.3.4-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:81c3e6d8c97295a7360d367f9f8553973651b76907988bb6066376bc2252f24e", size = 20955580, upload-time = "2025-10-15T16:17:02.509Z" }, + { url = "https://files.pythonhosted.org/packages/af/39/4be9222ffd6ca8a30eda033d5f753276a9c3426c397bb137d8e19dedd200/numpy-2.3.4-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:7c26b0b2bf58009ed1f38a641f3db4be8d960a417ca96d14e5b06df1506d41ff", size = 14188056, upload-time = "2025-10-15T16:17:04.873Z" }, + { url = "https://files.pythonhosted.org/packages/6c/3d/d85f6700d0a4aa4f9491030e1021c2b2b7421b2b38d01acd16734a2bfdc7/numpy-2.3.4-cp314-cp314-macosx_14_0_arm64.whl", hash = "sha256:62b2198c438058a20b6704351b35a1d7db881812d8512d67a69c9de1f18ca05f", size = 5116555, upload-time = "2025-10-15T16:17:07.499Z" }, + { url = "https://files.pythonhosted.org/packages/bf/04/82c1467d86f47eee8a19a464c92f90a9bb68ccf14a54c5224d7031241ffb/numpy-2.3.4-cp314-cp314-macosx_14_0_x86_64.whl", hash = "sha256:9d729d60f8d53a7361707f4b68a9663c968882dd4f09e0d58c044c8bf5faee7b", size = 6643581, upload-time = "2025-10-15T16:17:09.774Z" }, + { url = "https://files.pythonhosted.org/packages/0c/d3/c79841741b837e293f48bd7db89d0ac7a4f2503b382b78a790ef1dc778a5/numpy-2.3.4-cp314-cp314-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:bd0c630cf256b0a7fd9d0a11c9413b42fef5101219ce6ed5a09624f5a65392c7", size = 14299186, upload-time = "2025-10-15T16:17:11.937Z" }, + { url = "https://files.pythonhosted.org/packages/e8/7e/4a14a769741fbf237eec5a12a2cbc7a4c4e061852b6533bcb9e9a796c908/numpy-2.3.4-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:d5e081bc082825f8b139f9e9fe42942cb4054524598aaeb177ff476cc76d09d2", size = 16638601, upload-time = "2025-10-15T16:17:14.391Z" }, + { url = "https://files.pythonhosted.org/packages/93/87/1c1de269f002ff0a41173fe01dcc925f4ecff59264cd8f96cf3b60d12c9b/numpy-2.3.4-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:15fb27364ed84114438fff8aaf998c9e19adbeba08c0b75409f8c452a8692c52", size = 16074219, upload-time = "2025-10-15T16:17:17.058Z" }, + { url = "https://files.pythonhosted.org/packages/cd/28/18f72ee77408e40a76d691001ae599e712ca2a47ddd2c4f695b16c65f077/numpy-2.3.4-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:85d9fb2d8cd998c84d13a79a09cc0c1091648e848e4e6249b0ccd7f6b487fa26", size = 18576702, upload-time = "2025-10-15T16:17:19.379Z" }, + { url = "https://files.pythonhosted.org/packages/c3/76/95650169b465ececa8cf4b2e8f6df255d4bf662775e797ade2025cc51ae6/numpy-2.3.4-cp314-cp314-win32.whl", hash = "sha256:e73d63fd04e3a9d6bc187f5455d81abfad05660b212c8804bf3b407e984cd2bc", size = 6337136, upload-time = "2025-10-15T16:17:22.886Z" }, + { url = "https://files.pythonhosted.org/packages/dc/89/a231a5c43ede5d6f77ba4a91e915a87dea4aeea76560ba4d2bf185c683f0/numpy-2.3.4-cp314-cp314-win_amd64.whl", hash = "sha256:3da3491cee49cf16157e70f607c03a217ea6647b1cea4819c4f48e53d49139b9", size = 12920542, upload-time = "2025-10-15T16:17:24.783Z" }, + { url = "https://files.pythonhosted.org/packages/0d/0c/ae9434a888f717c5ed2ff2393b3f344f0ff6f1c793519fa0c540461dc530/numpy-2.3.4-cp314-cp314-win_arm64.whl", hash = "sha256:6d9cd732068e8288dbe2717177320723ccec4fb064123f0caf9bbd90ab5be868", size = 10480213, upload-time = "2025-10-15T16:17:26.935Z" }, + { url = "https://files.pythonhosted.org/packages/83/4b/c4a5f0841f92536f6b9592694a5b5f68c9ab37b775ff342649eadf9055d3/numpy-2.3.4-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:22758999b256b595cf0b1d102b133bb61866ba5ceecf15f759623b64c020c9ec", size = 21052280, upload-time = "2025-10-15T16:17:29.638Z" }, + { url = "https://files.pythonhosted.org/packages/3e/80/90308845fc93b984d2cc96d83e2324ce8ad1fd6efea81b324cba4b673854/numpy-2.3.4-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:9cb177bc55b010b19798dc5497d540dea67fd13a8d9e882b2dae71de0cf09eb3", size = 14302930, upload-time = "2025-10-15T16:17:32.384Z" }, + { url = "https://files.pythonhosted.org/packages/3d/4e/07439f22f2a3b247cec4d63a713faae55e1141a36e77fb212881f7cda3fb/numpy-2.3.4-cp314-cp314t-macosx_14_0_arm64.whl", hash = "sha256:0f2bcc76f1e05e5ab58893407c63d90b2029908fa41f9f1cc51eecce936c3365", size = 5231504, upload-time = "2025-10-15T16:17:34.515Z" }, + { url = "https://files.pythonhosted.org/packages/ab/de/1e11f2547e2fe3d00482b19721855348b94ada8359aef5d40dd57bfae9df/numpy-2.3.4-cp314-cp314t-macosx_14_0_x86_64.whl", hash = "sha256:8dc20bde86802df2ed8397a08d793da0ad7a5fd4ea3ac85d757bf5dd4ad7c252", size = 6739405, upload-time = "2025-10-15T16:17:36.128Z" }, + { url = "https://files.pythonhosted.org/packages/3b/40/8cd57393a26cebe2e923005db5134a946c62fa56a1087dc7c478f3e30837/numpy-2.3.4-cp314-cp314t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:5e199c087e2aa71c8f9ce1cb7a8e10677dc12457e7cc1be4798632da37c3e86e", size = 14354866, upload-time = "2025-10-15T16:17:38.884Z" }, + { url = "https://files.pythonhosted.org/packages/93/39/5b3510f023f96874ee6fea2e40dfa99313a00bf3ab779f3c92978f34aace/numpy-2.3.4-cp314-cp314t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:85597b2d25ddf655495e2363fe044b0ae999b75bc4d630dc0d886484b03a5eb0", size = 16703296, upload-time = "2025-10-15T16:17:41.564Z" }, + { url = "https://files.pythonhosted.org/packages/41/0d/19bb163617c8045209c1996c4e427bccbc4bbff1e2c711f39203c8ddbb4a/numpy-2.3.4-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:04a69abe45b49c5955923cf2c407843d1c85013b424ae8a560bba16c92fe44a0", size = 16136046, upload-time = "2025-10-15T16:17:43.901Z" }, + { url = "https://files.pythonhosted.org/packages/e2/c1/6dba12fdf68b02a21ac411c9df19afa66bed2540f467150ca64d246b463d/numpy-2.3.4-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:e1708fac43ef8b419c975926ce1eaf793b0c13b7356cfab6ab0dc34c0a02ac0f", size = 18652691, upload-time = "2025-10-15T16:17:46.247Z" }, + { url = "https://files.pythonhosted.org/packages/f8/73/f85056701dbbbb910c51d846c58d29fd46b30eecd2b6ba760fc8b8a1641b/numpy-2.3.4-cp314-cp314t-win32.whl", hash = "sha256:863e3b5f4d9915aaf1b8ec79ae560ad21f0b8d5e3adc31e73126491bb86dee1d", size = 6485782, upload-time = "2025-10-15T16:17:48.872Z" }, + { url = "https://files.pythonhosted.org/packages/17/90/28fa6f9865181cb817c2471ee65678afa8a7e2a1fb16141473d5fa6bacc3/numpy-2.3.4-cp314-cp314t-win_amd64.whl", hash = "sha256:962064de37b9aef801d33bc579690f8bfe6c5e70e29b61783f60bcba838a14d6", size = 13113301, upload-time = "2025-10-15T16:17:50.938Z" }, + { url = "https://files.pythonhosted.org/packages/54/23/08c002201a8e7e1f9afba93b97deceb813252d9cfd0d3351caed123dcf97/numpy-2.3.4-cp314-cp314t-win_arm64.whl", hash = "sha256:8b5a9a39c45d852b62693d9b3f3e0fe052541f804296ff401a72a1b60edafb29", size = 10547532, upload-time = "2025-10-15T16:17:53.48Z" }, ] [[package]] @@ -1172,57 +1172,60 @@ wheels = [ [[package]] name = "pillow" -version = "11.3.0" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/f3/0d/d0d6dea55cd152ce3d6767bb38a8fc10e33796ba4ba210cbab9354b6d238/pillow-11.3.0.tar.gz", hash = "sha256:3828ee7586cd0b2091b6209e5ad53e20d0649bbe87164a459d0676e035e8f523", size = 47113069, upload-time = "2025-07-01T09:16:30.666Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/1e/93/0952f2ed8db3a5a4c7a11f91965d6184ebc8cd7cbb7941a260d5f018cd2d/pillow-11.3.0-cp313-cp313-ios_13_0_arm64_iphoneos.whl", hash = "sha256:1c627742b539bba4309df89171356fcb3cc5a9178355b2727d1b74a6cf155fbd", size = 2128328, upload-time = "2025-07-01T09:14:35.276Z" }, - { url = "https://files.pythonhosted.org/packages/4b/e8/100c3d114b1a0bf4042f27e0f87d2f25e857e838034e98ca98fe7b8c0a9c/pillow-11.3.0-cp313-cp313-ios_13_0_arm64_iphonesimulator.whl", hash = "sha256:30b7c02f3899d10f13d7a48163c8969e4e653f8b43416d23d13d1bbfdc93b9f8", size = 2170652, upload-time = "2025-07-01T09:14:37.203Z" }, - { url = "https://files.pythonhosted.org/packages/aa/86/3f758a28a6e381758545f7cdb4942e1cb79abd271bea932998fc0db93cb6/pillow-11.3.0-cp313-cp313-ios_13_0_x86_64_iphonesimulator.whl", hash = "sha256:7859a4cc7c9295f5838015d8cc0a9c215b77e43d07a25e460f35cf516df8626f", size = 2227443, upload-time = "2025-07-01T09:14:39.344Z" }, - { url = "https://files.pythonhosted.org/packages/01/f4/91d5b3ffa718df2f53b0dc109877993e511f4fd055d7e9508682e8aba092/pillow-11.3.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:ec1ee50470b0d050984394423d96325b744d55c701a439d2bd66089bff963d3c", size = 5278474, upload-time = "2025-07-01T09:14:41.843Z" }, - { url = "https://files.pythonhosted.org/packages/f9/0e/37d7d3eca6c879fbd9dba21268427dffda1ab00d4eb05b32923d4fbe3b12/pillow-11.3.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:7db51d222548ccfd274e4572fdbf3e810a5e66b00608862f947b163e613b67dd", size = 4686038, upload-time = "2025-07-01T09:14:44.008Z" }, - { url = "https://files.pythonhosted.org/packages/ff/b0/3426e5c7f6565e752d81221af9d3676fdbb4f352317ceafd42899aaf5d8a/pillow-11.3.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:2d6fcc902a24ac74495df63faad1884282239265c6839a0a6416d33faedfae7e", size = 5864407, upload-time = "2025-07-03T13:10:15.628Z" }, - { url = "https://files.pythonhosted.org/packages/fc/c1/c6c423134229f2a221ee53f838d4be9d82bab86f7e2f8e75e47b6bf6cd77/pillow-11.3.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:f0f5d8f4a08090c6d6d578351a2b91acf519a54986c055af27e7a93feae6d3f1", size = 7639094, upload-time = "2025-07-03T13:10:21.857Z" }, - { url = "https://files.pythonhosted.org/packages/ba/c9/09e6746630fe6372c67c648ff9deae52a2bc20897d51fa293571977ceb5d/pillow-11.3.0-cp313-cp313-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:c37d8ba9411d6003bba9e518db0db0c58a680ab9fe5179f040b0463644bc9805", size = 5973503, upload-time = "2025-07-01T09:14:45.698Z" }, - { url = "https://files.pythonhosted.org/packages/d5/1c/a2a29649c0b1983d3ef57ee87a66487fdeb45132df66ab30dd37f7dbe162/pillow-11.3.0-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:13f87d581e71d9189ab21fe0efb5a23e9f28552d5be6979e84001d3b8505abe8", size = 6642574, upload-time = "2025-07-01T09:14:47.415Z" }, - { url = "https://files.pythonhosted.org/packages/36/de/d5cc31cc4b055b6c6fd990e3e7f0f8aaf36229a2698501bcb0cdf67c7146/pillow-11.3.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:023f6d2d11784a465f09fd09a34b150ea4672e85fb3d05931d89f373ab14abb2", size = 6084060, upload-time = "2025-07-01T09:14:49.636Z" }, - { url = "https://files.pythonhosted.org/packages/d5/ea/502d938cbaeec836ac28a9b730193716f0114c41325db428e6b280513f09/pillow-11.3.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:45dfc51ac5975b938e9809451c51734124e73b04d0f0ac621649821a63852e7b", size = 6721407, upload-time = "2025-07-01T09:14:51.962Z" }, - { url = "https://files.pythonhosted.org/packages/45/9c/9c5e2a73f125f6cbc59cc7087c8f2d649a7ae453f83bd0362ff7c9e2aee2/pillow-11.3.0-cp313-cp313-win32.whl", hash = "sha256:a4d336baed65d50d37b88ca5b60c0fa9d81e3a87d4a7930d3880d1624d5b31f3", size = 6273841, upload-time = "2025-07-01T09:14:54.142Z" }, - { url = "https://files.pythonhosted.org/packages/23/85/397c73524e0cd212067e0c969aa245b01d50183439550d24d9f55781b776/pillow-11.3.0-cp313-cp313-win_amd64.whl", hash = "sha256:0bce5c4fd0921f99d2e858dc4d4d64193407e1b99478bc5cacecba2311abde51", size = 6978450, upload-time = "2025-07-01T09:14:56.436Z" }, - { url = "https://files.pythonhosted.org/packages/17/d2/622f4547f69cd173955194b78e4d19ca4935a1b0f03a302d655c9f6aae65/pillow-11.3.0-cp313-cp313-win_arm64.whl", hash = "sha256:1904e1264881f682f02b7f8167935cce37bc97db457f8e7849dc3a6a52b99580", size = 2423055, upload-time = "2025-07-01T09:14:58.072Z" }, - { url = "https://files.pythonhosted.org/packages/dd/80/a8a2ac21dda2e82480852978416cfacd439a4b490a501a288ecf4fe2532d/pillow-11.3.0-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:4c834a3921375c48ee6b9624061076bc0a32a60b5532b322cc0ea64e639dd50e", size = 5281110, upload-time = "2025-07-01T09:14:59.79Z" }, - { url = "https://files.pythonhosted.org/packages/44/d6/b79754ca790f315918732e18f82a8146d33bcd7f4494380457ea89eb883d/pillow-11.3.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:5e05688ccef30ea69b9317a9ead994b93975104a677a36a8ed8106be9260aa6d", size = 4689547, upload-time = "2025-07-01T09:15:01.648Z" }, - { url = "https://files.pythonhosted.org/packages/49/20/716b8717d331150cb00f7fdd78169c01e8e0c219732a78b0e59b6bdb2fd6/pillow-11.3.0-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:1019b04af07fc0163e2810167918cb5add8d74674b6267616021ab558dc98ced", size = 5901554, upload-time = "2025-07-03T13:10:27.018Z" }, - { url = "https://files.pythonhosted.org/packages/74/cf/a9f3a2514a65bb071075063a96f0a5cf949c2f2fce683c15ccc83b1c1cab/pillow-11.3.0-cp313-cp313t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:f944255db153ebb2b19c51fe85dd99ef0ce494123f21b9db4877ffdfc5590c7c", size = 7669132, upload-time = "2025-07-03T13:10:33.01Z" }, - { url = "https://files.pythonhosted.org/packages/98/3c/da78805cbdbee9cb43efe8261dd7cc0b4b93f2ac79b676c03159e9db2187/pillow-11.3.0-cp313-cp313t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:1f85acb69adf2aaee8b7da124efebbdb959a104db34d3a2cb0f3793dbae422a8", size = 6005001, upload-time = "2025-07-01T09:15:03.365Z" }, - { url = "https://files.pythonhosted.org/packages/6c/fa/ce044b91faecf30e635321351bba32bab5a7e034c60187fe9698191aef4f/pillow-11.3.0-cp313-cp313t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:05f6ecbeff5005399bb48d198f098a9b4b6bdf27b8487c7f38ca16eeb070cd59", size = 6668814, upload-time = "2025-07-01T09:15:05.655Z" }, - { url = "https://files.pythonhosted.org/packages/7b/51/90f9291406d09bf93686434f9183aba27b831c10c87746ff49f127ee80cb/pillow-11.3.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:a7bc6e6fd0395bc052f16b1a8670859964dbd7003bd0af2ff08342eb6e442cfe", size = 6113124, upload-time = "2025-07-01T09:15:07.358Z" }, - { url = "https://files.pythonhosted.org/packages/cd/5a/6fec59b1dfb619234f7636d4157d11fb4e196caeee220232a8d2ec48488d/pillow-11.3.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:83e1b0161c9d148125083a35c1c5a89db5b7054834fd4387499e06552035236c", size = 6747186, upload-time = "2025-07-01T09:15:09.317Z" }, - { url = "https://files.pythonhosted.org/packages/49/6b/00187a044f98255225f172de653941e61da37104a9ea60e4f6887717e2b5/pillow-11.3.0-cp313-cp313t-win32.whl", hash = "sha256:2a3117c06b8fb646639dce83694f2f9eac405472713fcb1ae887469c0d4f6788", size = 6277546, upload-time = "2025-07-01T09:15:11.311Z" }, - { url = "https://files.pythonhosted.org/packages/e8/5c/6caaba7e261c0d75bab23be79f1d06b5ad2a2ae49f028ccec801b0e853d6/pillow-11.3.0-cp313-cp313t-win_amd64.whl", hash = "sha256:857844335c95bea93fb39e0fa2726b4d9d758850b34075a7e3ff4f4fa3aa3b31", size = 6985102, upload-time = "2025-07-01T09:15:13.164Z" }, - { url = "https://files.pythonhosted.org/packages/f3/7e/b623008460c09a0cb38263c93b828c666493caee2eb34ff67f778b87e58c/pillow-11.3.0-cp313-cp313t-win_arm64.whl", hash = "sha256:8797edc41f3e8536ae4b10897ee2f637235c94f27404cac7297f7b607dd0716e", size = 2424803, upload-time = "2025-07-01T09:15:15.695Z" }, - { url = "https://files.pythonhosted.org/packages/73/f4/04905af42837292ed86cb1b1dabe03dce1edc008ef14c473c5c7e1443c5d/pillow-11.3.0-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:d9da3df5f9ea2a89b81bb6087177fb1f4d1c7146d583a3fe5c672c0d94e55e12", size = 5278520, upload-time = "2025-07-01T09:15:17.429Z" }, - { url = "https://files.pythonhosted.org/packages/41/b0/33d79e377a336247df6348a54e6d2a2b85d644ca202555e3faa0cf811ecc/pillow-11.3.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:0b275ff9b04df7b640c59ec5a3cb113eefd3795a8df80bac69646ef699c6981a", size = 4686116, upload-time = "2025-07-01T09:15:19.423Z" }, - { url = "https://files.pythonhosted.org/packages/49/2d/ed8bc0ab219ae8768f529597d9509d184fe8a6c4741a6864fea334d25f3f/pillow-11.3.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:0743841cabd3dba6a83f38a92672cccbd69af56e3e91777b0ee7f4dba4385632", size = 5864597, upload-time = "2025-07-03T13:10:38.404Z" }, - { url = "https://files.pythonhosted.org/packages/b5/3d/b932bb4225c80b58dfadaca9d42d08d0b7064d2d1791b6a237f87f661834/pillow-11.3.0-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:2465a69cf967b8b49ee1b96d76718cd98c4e925414ead59fdf75cf0fd07df673", size = 7638246, upload-time = "2025-07-03T13:10:44.987Z" }, - { url = "https://files.pythonhosted.org/packages/09/b5/0487044b7c096f1b48f0d7ad416472c02e0e4bf6919541b111efd3cae690/pillow-11.3.0-cp314-cp314-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:41742638139424703b4d01665b807c6468e23e699e8e90cffefe291c5832b027", size = 5973336, upload-time = "2025-07-01T09:15:21.237Z" }, - { url = "https://files.pythonhosted.org/packages/a8/2d/524f9318f6cbfcc79fbc004801ea6b607ec3f843977652fdee4857a7568b/pillow-11.3.0-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:93efb0b4de7e340d99057415c749175e24c8864302369e05914682ba642e5d77", size = 6642699, upload-time = "2025-07-01T09:15:23.186Z" }, - { url = "https://files.pythonhosted.org/packages/6f/d2/a9a4f280c6aefedce1e8f615baaa5474e0701d86dd6f1dede66726462bbd/pillow-11.3.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:7966e38dcd0fa11ca390aed7c6f20454443581d758242023cf36fcb319b1a874", size = 6083789, upload-time = "2025-07-01T09:15:25.1Z" }, - { url = "https://files.pythonhosted.org/packages/fe/54/86b0cd9dbb683a9d5e960b66c7379e821a19be4ac5810e2e5a715c09a0c0/pillow-11.3.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:98a9afa7b9007c67ed84c57c9e0ad86a6000da96eaa638e4f8abe5b65ff83f0a", size = 6720386, upload-time = "2025-07-01T09:15:27.378Z" }, - { url = "https://files.pythonhosted.org/packages/e7/95/88efcaf384c3588e24259c4203b909cbe3e3c2d887af9e938c2022c9dd48/pillow-11.3.0-cp314-cp314-win32.whl", hash = "sha256:02a723e6bf909e7cea0dac1b0e0310be9d7650cd66222a5f1c571455c0a45214", size = 6370911, upload-time = "2025-07-01T09:15:29.294Z" }, - { url = "https://files.pythonhosted.org/packages/2e/cc/934e5820850ec5eb107e7b1a72dd278140731c669f396110ebc326f2a503/pillow-11.3.0-cp314-cp314-win_amd64.whl", hash = "sha256:a418486160228f64dd9e9efcd132679b7a02a5f22c982c78b6fc7dab3fefb635", size = 7117383, upload-time = "2025-07-01T09:15:31.128Z" }, - { url = "https://files.pythonhosted.org/packages/d6/e9/9c0a616a71da2a5d163aa37405e8aced9a906d574b4a214bede134e731bc/pillow-11.3.0-cp314-cp314-win_arm64.whl", hash = "sha256:155658efb5e044669c08896c0c44231c5e9abcaadbc5cd3648df2f7c0b96b9a6", size = 2511385, upload-time = "2025-07-01T09:15:33.328Z" }, - { url = "https://files.pythonhosted.org/packages/1a/33/c88376898aff369658b225262cd4f2659b13e8178e7534df9e6e1fa289f6/pillow-11.3.0-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:59a03cdf019efbfeeed910bf79c7c93255c3d54bc45898ac2a4140071b02b4ae", size = 5281129, upload-time = "2025-07-01T09:15:35.194Z" }, - { url = "https://files.pythonhosted.org/packages/1f/70/d376247fb36f1844b42910911c83a02d5544ebd2a8bad9efcc0f707ea774/pillow-11.3.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:f8a5827f84d973d8636e9dc5764af4f0cf2318d26744b3d902931701b0d46653", size = 4689580, upload-time = "2025-07-01T09:15:37.114Z" }, - { url = "https://files.pythonhosted.org/packages/eb/1c/537e930496149fbac69efd2fc4329035bbe2e5475b4165439e3be9cb183b/pillow-11.3.0-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:ee92f2fd10f4adc4b43d07ec5e779932b4eb3dbfbc34790ada5a6669bc095aa6", size = 5902860, upload-time = "2025-07-03T13:10:50.248Z" }, - { url = "https://files.pythonhosted.org/packages/bd/57/80f53264954dcefeebcf9dae6e3eb1daea1b488f0be8b8fef12f79a3eb10/pillow-11.3.0-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:c96d333dcf42d01f47b37e0979b6bd73ec91eae18614864622d9b87bbd5bbf36", size = 7670694, upload-time = "2025-07-03T13:10:56.432Z" }, - { url = "https://files.pythonhosted.org/packages/70/ff/4727d3b71a8578b4587d9c276e90efad2d6fe0335fd76742a6da08132e8c/pillow-11.3.0-cp314-cp314t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:4c96f993ab8c98460cd0c001447bff6194403e8b1d7e149ade5f00594918128b", size = 6005888, upload-time = "2025-07-01T09:15:39.436Z" }, - { url = "https://files.pythonhosted.org/packages/05/ae/716592277934f85d3be51d7256f3636672d7b1abfafdc42cf3f8cbd4b4c8/pillow-11.3.0-cp314-cp314t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:41342b64afeba938edb034d122b2dda5db2139b9a4af999729ba8818e0056477", size = 6670330, upload-time = "2025-07-01T09:15:41.269Z" }, - { url = "https://files.pythonhosted.org/packages/e7/bb/7fe6cddcc8827b01b1a9766f5fdeb7418680744f9082035bdbabecf1d57f/pillow-11.3.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:068d9c39a2d1b358eb9f245ce7ab1b5c3246c7c8c7d9ba58cfa5b43146c06e50", size = 6114089, upload-time = "2025-07-01T09:15:43.13Z" }, - { url = "https://files.pythonhosted.org/packages/8b/f5/06bfaa444c8e80f1a8e4bff98da9c83b37b5be3b1deaa43d27a0db37ef84/pillow-11.3.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:a1bc6ba083b145187f648b667e05a2534ecc4b9f2784c2cbe3089e44868f2b9b", size = 6748206, upload-time = "2025-07-01T09:15:44.937Z" }, - { url = "https://files.pythonhosted.org/packages/f0/77/bc6f92a3e8e6e46c0ca78abfffec0037845800ea38c73483760362804c41/pillow-11.3.0-cp314-cp314t-win32.whl", hash = "sha256:118ca10c0d60b06d006be10a501fd6bbdfef559251ed31b794668ed569c87e12", size = 6377370, upload-time = "2025-07-01T09:15:46.673Z" }, - { url = "https://files.pythonhosted.org/packages/4a/82/3a721f7d69dca802befb8af08b7c79ebcab461007ce1c18bd91a5d5896f9/pillow-11.3.0-cp314-cp314t-win_amd64.whl", hash = "sha256:8924748b688aa210d79883357d102cd64690e56b923a186f35a82cbc10f997db", size = 7121500, upload-time = "2025-07-01T09:15:48.512Z" }, - { url = "https://files.pythonhosted.org/packages/89/c7/5572fa4a3f45740eaab6ae86fcdf7195b55beac1371ac8c619d880cfe948/pillow-11.3.0-cp314-cp314t-win_arm64.whl", hash = "sha256:79ea0d14d3ebad43ec77ad5272e6ff9bba5b679ef73375ea760261207fa8e0aa", size = 2512835, upload-time = "2025-07-01T09:15:50.399Z" }, +version = "12.0.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/5a/b0/cace85a1b0c9775a9f8f5d5423c8261c858760e2466c79b2dd184638b056/pillow-12.0.0.tar.gz", hash = "sha256:87d4f8125c9988bfbed67af47dd7a953e2fc7b0cc1e7800ec6d2080d490bb353", size = 47008828, upload-time = "2025-10-15T18:24:14.008Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/62/f2/de993bb2d21b33a98d031ecf6a978e4b61da207bef02f7b43093774c480d/pillow-12.0.0-cp313-cp313-ios_13_0_arm64_iphoneos.whl", hash = "sha256:0869154a2d0546545cde61d1789a6524319fc1897d9ee31218eae7a60ccc5643", size = 4045493, upload-time = "2025-10-15T18:22:25.758Z" }, + { url = "https://files.pythonhosted.org/packages/0e/b6/bc8d0c4c9f6f111a783d045310945deb769b806d7574764234ffd50bc5ea/pillow-12.0.0-cp313-cp313-ios_13_0_arm64_iphonesimulator.whl", hash = "sha256:a7921c5a6d31b3d756ec980f2f47c0cfdbce0fc48c22a39347a895f41f4a6ea4", size = 4120461, upload-time = "2025-10-15T18:22:27.286Z" }, + { url = "https://files.pythonhosted.org/packages/5d/57/d60d343709366a353dc56adb4ee1e7d8a2cc34e3fbc22905f4167cfec119/pillow-12.0.0-cp313-cp313-ios_13_0_x86_64_iphonesimulator.whl", hash = "sha256:1ee80a59f6ce048ae13cda1abf7fbd2a34ab9ee7d401c46be3ca685d1999a399", size = 3576912, upload-time = "2025-10-15T18:22:28.751Z" }, + { url = "https://files.pythonhosted.org/packages/a4/a4/a0a31467e3f83b94d37568294b01d22b43ae3c5d85f2811769b9c66389dd/pillow-12.0.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:c50f36a62a22d350c96e49ad02d0da41dbd17ddc2e29750dbdba4323f85eb4a5", size = 5249132, upload-time = "2025-10-15T18:22:30.641Z" }, + { url = "https://files.pythonhosted.org/packages/83/06/48eab21dd561de2914242711434c0c0eb992ed08ff3f6107a5f44527f5e9/pillow-12.0.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:5193fde9a5f23c331ea26d0cf171fbf67e3f247585f50c08b3e205c7aeb4589b", size = 4650099, upload-time = "2025-10-15T18:22:32.73Z" }, + { url = "https://files.pythonhosted.org/packages/fc/bd/69ed99fd46a8dba7c1887156d3572fe4484e3f031405fcc5a92e31c04035/pillow-12.0.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:bde737cff1a975b70652b62d626f7785e0480918dece11e8fef3c0cf057351c3", size = 6230808, upload-time = "2025-10-15T18:22:34.337Z" }, + { url = "https://files.pythonhosted.org/packages/ea/94/8fad659bcdbf86ed70099cb60ae40be6acca434bbc8c4c0d4ef356d7e0de/pillow-12.0.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:a6597ff2b61d121172f5844b53f21467f7082f5fb385a9a29c01414463f93b07", size = 8037804, upload-time = "2025-10-15T18:22:36.402Z" }, + { url = "https://files.pythonhosted.org/packages/20/39/c685d05c06deecfd4e2d1950e9a908aa2ca8bc4e6c3b12d93b9cafbd7837/pillow-12.0.0-cp313-cp313-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:0b817e7035ea7f6b942c13aa03bb554fc44fea70838ea21f8eb31c638326584e", size = 6345553, upload-time = "2025-10-15T18:22:38.066Z" }, + { url = "https://files.pythonhosted.org/packages/38/57/755dbd06530a27a5ed74f8cb0a7a44a21722ebf318edbe67ddbd7fb28f88/pillow-12.0.0-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:f4f1231b7dec408e8670264ce63e9c71409d9583dd21d32c163e25213ee2a344", size = 7037729, upload-time = "2025-10-15T18:22:39.769Z" }, + { url = "https://files.pythonhosted.org/packages/ca/b6/7e94f4c41d238615674d06ed677c14883103dce1c52e4af16f000338cfd7/pillow-12.0.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:6e51b71417049ad6ab14c49608b4a24d8fb3fe605e5dfabfe523b58064dc3d27", size = 6459789, upload-time = "2025-10-15T18:22:41.437Z" }, + { url = "https://files.pythonhosted.org/packages/9c/14/4448bb0b5e0f22dd865290536d20ec8a23b64e2d04280b89139f09a36bb6/pillow-12.0.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:d120c38a42c234dc9a8c5de7ceaaf899cf33561956acb4941653f8bdc657aa79", size = 7130917, upload-time = "2025-10-15T18:22:43.152Z" }, + { url = "https://files.pythonhosted.org/packages/dd/ca/16c6926cc1c015845745d5c16c9358e24282f1e588237a4c36d2b30f182f/pillow-12.0.0-cp313-cp313-win32.whl", hash = "sha256:4cc6b3b2efff105c6a1656cfe59da4fdde2cda9af1c5e0b58529b24525d0a098", size = 6302391, upload-time = "2025-10-15T18:22:44.753Z" }, + { url = "https://files.pythonhosted.org/packages/6d/2a/dd43dcfd6dae9b6a49ee28a8eedb98c7d5ff2de94a5d834565164667b97b/pillow-12.0.0-cp313-cp313-win_amd64.whl", hash = "sha256:4cf7fed4b4580601c4345ceb5d4cbf5a980d030fd5ad07c4d2ec589f95f09905", size = 7007477, upload-time = "2025-10-15T18:22:46.838Z" }, + { url = "https://files.pythonhosted.org/packages/77/f0/72ea067f4b5ae5ead653053212af05ce3705807906ba3f3e8f58ddf617e6/pillow-12.0.0-cp313-cp313-win_arm64.whl", hash = "sha256:9f0b04c6b8584c2c193babcccc908b38ed29524b29dd464bc8801bf10d746a3a", size = 2435918, upload-time = "2025-10-15T18:22:48.399Z" }, + { url = "https://files.pythonhosted.org/packages/f5/5e/9046b423735c21f0487ea6cb5b10f89ea8f8dfbe32576fe052b5ba9d4e5b/pillow-12.0.0-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:7fa22993bac7b77b78cae22bad1e2a987ddf0d9015c63358032f84a53f23cdc3", size = 5251406, upload-time = "2025-10-15T18:22:49.905Z" }, + { url = "https://files.pythonhosted.org/packages/12/66/982ceebcdb13c97270ef7a56c3969635b4ee7cd45227fa707c94719229c5/pillow-12.0.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:f135c702ac42262573fe9714dfe99c944b4ba307af5eb507abef1667e2cbbced", size = 4653218, upload-time = "2025-10-15T18:22:51.587Z" }, + { url = "https://files.pythonhosted.org/packages/16/b3/81e625524688c31859450119bf12674619429cab3119eec0e30a7a1029cb/pillow-12.0.0-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:c85de1136429c524e55cfa4e033b4a7940ac5c8ee4d9401cc2d1bf48154bbc7b", size = 6266564, upload-time = "2025-10-15T18:22:53.215Z" }, + { url = "https://files.pythonhosted.org/packages/98/59/dfb38f2a41240d2408096e1a76c671d0a105a4a8471b1871c6902719450c/pillow-12.0.0-cp313-cp313t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:38df9b4bfd3db902c9c2bd369bcacaf9d935b2fff73709429d95cc41554f7b3d", size = 8069260, upload-time = "2025-10-15T18:22:54.933Z" }, + { url = "https://files.pythonhosted.org/packages/dc/3d/378dbea5cd1874b94c312425ca77b0f47776c78e0df2df751b820c8c1d6c/pillow-12.0.0-cp313-cp313t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:7d87ef5795da03d742bf49439f9ca4d027cde49c82c5371ba52464aee266699a", size = 6379248, upload-time = "2025-10-15T18:22:56.605Z" }, + { url = "https://files.pythonhosted.org/packages/84/b0/d525ef47d71590f1621510327acec75ae58c721dc071b17d8d652ca494d8/pillow-12.0.0-cp313-cp313t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:aff9e4d82d082ff9513bdd6acd4f5bd359f5b2c870907d2b0a9c5e10d40c88fe", size = 7066043, upload-time = "2025-10-15T18:22:58.53Z" }, + { url = "https://files.pythonhosted.org/packages/61/2c/aced60e9cf9d0cde341d54bf7932c9ffc33ddb4a1595798b3a5150c7ec4e/pillow-12.0.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:8d8ca2b210ada074d57fcee40c30446c9562e542fc46aedc19baf758a93532ee", size = 6490915, upload-time = "2025-10-15T18:23:00.582Z" }, + { url = "https://files.pythonhosted.org/packages/ef/26/69dcb9b91f4e59f8f34b2332a4a0a951b44f547c4ed39d3e4dcfcff48f89/pillow-12.0.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:99a7f72fb6249302aa62245680754862a44179b545ded638cf1fef59befb57ef", size = 7157998, upload-time = "2025-10-15T18:23:02.627Z" }, + { url = "https://files.pythonhosted.org/packages/61/2b/726235842220ca95fa441ddf55dd2382b52ab5b8d9c0596fe6b3f23dafe8/pillow-12.0.0-cp313-cp313t-win32.whl", hash = "sha256:4078242472387600b2ce8d93ade8899c12bf33fa89e55ec89fe126e9d6d5d9e9", size = 6306201, upload-time = "2025-10-15T18:23:04.709Z" }, + { url = "https://files.pythonhosted.org/packages/c0/3d/2afaf4e840b2df71344ababf2f8edd75a705ce500e5dc1e7227808312ae1/pillow-12.0.0-cp313-cp313t-win_amd64.whl", hash = "sha256:2c54c1a783d6d60595d3514f0efe9b37c8808746a66920315bfd34a938d7994b", size = 7013165, upload-time = "2025-10-15T18:23:06.46Z" }, + { url = "https://files.pythonhosted.org/packages/6f/75/3fa09aa5cf6ed04bee3fa575798ddf1ce0bace8edb47249c798077a81f7f/pillow-12.0.0-cp313-cp313t-win_arm64.whl", hash = "sha256:26d9f7d2b604cd23aba3e9faf795787456ac25634d82cd060556998e39c6fa47", size = 2437834, upload-time = "2025-10-15T18:23:08.194Z" }, + { url = "https://files.pythonhosted.org/packages/54/2a/9a8c6ba2c2c07b71bec92cf63e03370ca5e5f5c5b119b742bcc0cde3f9c5/pillow-12.0.0-cp314-cp314-ios_13_0_arm64_iphoneos.whl", hash = "sha256:beeae3f27f62308f1ddbcfb0690bf44b10732f2ef43758f169d5e9303165d3f9", size = 4045531, upload-time = "2025-10-15T18:23:10.121Z" }, + { url = "https://files.pythonhosted.org/packages/84/54/836fdbf1bfb3d66a59f0189ff0b9f5f666cee09c6188309300df04ad71fa/pillow-12.0.0-cp314-cp314-ios_13_0_arm64_iphonesimulator.whl", hash = "sha256:d4827615da15cd59784ce39d3388275ec093ae3ee8d7f0c089b76fa87af756c2", size = 4120554, upload-time = "2025-10-15T18:23:12.14Z" }, + { url = "https://files.pythonhosted.org/packages/0d/cd/16aec9f0da4793e98e6b54778a5fbce4f375c6646fe662e80600b8797379/pillow-12.0.0-cp314-cp314-ios_13_0_x86_64_iphonesimulator.whl", hash = "sha256:3e42edad50b6909089750e65c91aa09aaf1e0a71310d383f11321b27c224ed8a", size = 3576812, upload-time = "2025-10-15T18:23:13.962Z" }, + { url = "https://files.pythonhosted.org/packages/f6/b7/13957fda356dc46339298b351cae0d327704986337c3c69bb54628c88155/pillow-12.0.0-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:e5d8efac84c9afcb40914ab49ba063d94f5dbdf5066db4482c66a992f47a3a3b", size = 5252689, upload-time = "2025-10-15T18:23:15.562Z" }, + { url = "https://files.pythonhosted.org/packages/fc/f5/eae31a306341d8f331f43edb2e9122c7661b975433de5e447939ae61c5da/pillow-12.0.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:266cd5f2b63ff316d5a1bba46268e603c9caf5606d44f38c2873c380950576ad", size = 4650186, upload-time = "2025-10-15T18:23:17.379Z" }, + { url = "https://files.pythonhosted.org/packages/86/62/2a88339aa40c4c77e79108facbd307d6091e2c0eb5b8d3cf4977cfca2fe6/pillow-12.0.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:58eea5ebe51504057dd95c5b77d21700b77615ab0243d8152793dc00eb4faf01", size = 6230308, upload-time = "2025-10-15T18:23:18.971Z" }, + { url = "https://files.pythonhosted.org/packages/c7/33/5425a8992bcb32d1cb9fa3dd39a89e613d09a22f2c8083b7bf43c455f760/pillow-12.0.0-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:f13711b1a5ba512d647a0e4ba79280d3a9a045aaf7e0cc6fbe96b91d4cdf6b0c", size = 8039222, upload-time = "2025-10-15T18:23:20.909Z" }, + { url = "https://files.pythonhosted.org/packages/d8/61/3f5d3b35c5728f37953d3eec5b5f3e77111949523bd2dd7f31a851e50690/pillow-12.0.0-cp314-cp314-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6846bd2d116ff42cba6b646edf5bf61d37e5cbd256425fa089fee4ff5c07a99e", size = 6346657, upload-time = "2025-10-15T18:23:23.077Z" }, + { url = "https://files.pythonhosted.org/packages/3a/be/ee90a3d79271227e0f0a33c453531efd6ed14b2e708596ba5dd9be948da3/pillow-12.0.0-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c98fa880d695de164b4135a52fd2e9cd7b7c90a9d8ac5e9e443a24a95ef9248e", size = 7038482, upload-time = "2025-10-15T18:23:25.005Z" }, + { url = "https://files.pythonhosted.org/packages/44/34/a16b6a4d1ad727de390e9bd9f19f5f669e079e5826ec0f329010ddea492f/pillow-12.0.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:fa3ed2a29a9e9d2d488b4da81dcb54720ac3104a20bf0bd273f1e4648aff5af9", size = 6461416, upload-time = "2025-10-15T18:23:27.009Z" }, + { url = "https://files.pythonhosted.org/packages/b6/39/1aa5850d2ade7d7ba9f54e4e4c17077244ff7a2d9e25998c38a29749eb3f/pillow-12.0.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:d034140032870024e6b9892c692fe2968493790dd57208b2c37e3fb35f6df3ab", size = 7131584, upload-time = "2025-10-15T18:23:29.752Z" }, + { url = "https://files.pythonhosted.org/packages/bf/db/4fae862f8fad0167073a7733973bfa955f47e2cac3dc3e3e6257d10fab4a/pillow-12.0.0-cp314-cp314-win32.whl", hash = "sha256:1b1b133e6e16105f524a8dec491e0586d072948ce15c9b914e41cdadd209052b", size = 6400621, upload-time = "2025-10-15T18:23:32.06Z" }, + { url = "https://files.pythonhosted.org/packages/2b/24/b350c31543fb0107ab2599464d7e28e6f856027aadda995022e695313d94/pillow-12.0.0-cp314-cp314-win_amd64.whl", hash = "sha256:8dc232e39d409036af549c86f24aed8273a40ffa459981146829a324e0848b4b", size = 7142916, upload-time = "2025-10-15T18:23:34.71Z" }, + { url = "https://files.pythonhosted.org/packages/0f/9b/0ba5a6fd9351793996ef7487c4fdbde8d3f5f75dbedc093bb598648fddf0/pillow-12.0.0-cp314-cp314-win_arm64.whl", hash = "sha256:d52610d51e265a51518692045e372a4c363056130d922a7351429ac9f27e70b0", size = 2523836, upload-time = "2025-10-15T18:23:36.967Z" }, + { url = "https://files.pythonhosted.org/packages/f5/7a/ceee0840aebc579af529b523d530840338ecf63992395842e54edc805987/pillow-12.0.0-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:1979f4566bb96c1e50a62d9831e2ea2d1211761e5662afc545fa766f996632f6", size = 5255092, upload-time = "2025-10-15T18:23:38.573Z" }, + { url = "https://files.pythonhosted.org/packages/44/76/20776057b4bfd1aef4eeca992ebde0f53a4dce874f3ae693d0ec90a4f79b/pillow-12.0.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:b2e4b27a6e15b04832fe9bf292b94b5ca156016bbc1ea9c2c20098a0320d6cf6", size = 4653158, upload-time = "2025-10-15T18:23:40.238Z" }, + { url = "https://files.pythonhosted.org/packages/82/3f/d9ff92ace07be8836b4e7e87e6a4c7a8318d47c2f1463ffcf121fc57d9cb/pillow-12.0.0-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:fb3096c30df99fd01c7bf8e544f392103d0795b9f98ba71a8054bcbf56b255f1", size = 6267882, upload-time = "2025-10-15T18:23:42.434Z" }, + { url = "https://files.pythonhosted.org/packages/9f/7a/4f7ff87f00d3ad33ba21af78bfcd2f032107710baf8280e3722ceec28cda/pillow-12.0.0-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:7438839e9e053ef79f7112c881cef684013855016f928b168b81ed5835f3e75e", size = 8071001, upload-time = "2025-10-15T18:23:44.29Z" }, + { url = "https://files.pythonhosted.org/packages/75/87/fcea108944a52dad8cca0715ae6247e271eb80459364a98518f1e4f480c1/pillow-12.0.0-cp314-cp314t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:5d5c411a8eaa2299322b647cd932586b1427367fd3184ffbb8f7a219ea2041ca", size = 6380146, upload-time = "2025-10-15T18:23:46.065Z" }, + { url = "https://files.pythonhosted.org/packages/91/52/0d31b5e571ef5fd111d2978b84603fce26aba1b6092f28e941cb46570745/pillow-12.0.0-cp314-cp314t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:d7e091d464ac59d2c7ad8e7e08105eaf9dafbc3883fd7265ffccc2baad6ac925", size = 7067344, upload-time = "2025-10-15T18:23:47.898Z" }, + { url = "https://files.pythonhosted.org/packages/7b/f4/2dd3d721f875f928d48e83bb30a434dee75a2531bca839bb996bb0aa5a91/pillow-12.0.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:792a2c0be4dcc18af9d4a2dfd8a11a17d5e25274a1062b0ec1c2d79c76f3e7f8", size = 6491864, upload-time = "2025-10-15T18:23:49.607Z" }, + { url = "https://files.pythonhosted.org/packages/30/4b/667dfcf3d61fc309ba5a15b141845cece5915e39b99c1ceab0f34bf1d124/pillow-12.0.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:afbefa430092f71a9593a99ab6a4e7538bc9eabbf7bf94f91510d3503943edc4", size = 7158911, upload-time = "2025-10-15T18:23:51.351Z" }, + { url = "https://files.pythonhosted.org/packages/a2/2f/16cabcc6426c32218ace36bf0d55955e813f2958afddbf1d391849fee9d1/pillow-12.0.0-cp314-cp314t-win32.whl", hash = "sha256:3830c769decf88f1289680a59d4f4c46c72573446352e2befec9a8512104fa52", size = 6408045, upload-time = "2025-10-15T18:23:53.177Z" }, + { url = "https://files.pythonhosted.org/packages/35/73/e29aa0c9c666cf787628d3f0dcf379f4791fba79f4936d02f8b37165bdf8/pillow-12.0.0-cp314-cp314t-win_amd64.whl", hash = "sha256:905b0365b210c73afb0ebe9101a32572152dfd1c144c7e28968a331b9217b94a", size = 7148282, upload-time = "2025-10-15T18:23:55.316Z" }, + { url = "https://files.pythonhosted.org/packages/c1/70/6b41bdcddf541b437bbb9f47f94d2db5d9ddef6c37ccab8c9107743748a4/pillow-12.0.0-cp314-cp314t-win_arm64.whl", hash = "sha256:99353a06902c2e43b43e8ff74ee65a7d90307d82370604746738a1e0661ccca7", size = 2525630, upload-time = "2025-10-15T18:23:57.149Z" }, ] [[package]] @@ -1248,28 +1251,29 @@ wheels = [ [[package]] name = "protobuf" -version = "6.32.1" +version = "6.33.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/fa/a4/cc17347aa2897568beece2e674674359f911d6fe21b0b8d6268cd42727ac/protobuf-6.32.1.tar.gz", hash = "sha256:ee2469e4a021474ab9baafea6cd070e5bf27c7d29433504ddea1a4ee5850f68d", size = 440635, upload-time = "2025-09-11T21:38:42.935Z" } +sdist = { url = "https://files.pythonhosted.org/packages/19/ff/64a6c8f420818bb873713988ca5492cba3a7946be57e027ac63495157d97/protobuf-6.33.0.tar.gz", hash = "sha256:140303d5c8d2037730c548f8c7b93b20bb1dc301be280c378b82b8894589c954", size = 443463, upload-time = "2025-10-15T20:39:52.159Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/c0/98/645183ea03ab3995d29086b8bf4f7562ebd3d10c9a4b14ee3f20d47cfe50/protobuf-6.32.1-cp310-abi3-win32.whl", hash = "sha256:a8a32a84bc9f2aad712041b8b366190f71dde248926da517bde9e832e4412085", size = 424411, upload-time = "2025-09-11T21:38:27.427Z" }, - { url = "https://files.pythonhosted.org/packages/8c/f3/6f58f841f6ebafe076cebeae33fc336e900619d34b1c93e4b5c97a81fdfa/protobuf-6.32.1-cp310-abi3-win_amd64.whl", hash = "sha256:b00a7d8c25fa471f16bc8153d0e53d6c9e827f0953f3c09aaa4331c718cae5e1", size = 435738, upload-time = "2025-09-11T21:38:30.959Z" }, - { url = "https://files.pythonhosted.org/packages/10/56/a8a3f4e7190837139e68c7002ec749190a163af3e330f65d90309145a210/protobuf-6.32.1-cp39-abi3-macosx_10_9_universal2.whl", hash = "sha256:d8c7e6eb619ffdf105ee4ab76af5a68b60a9d0f66da3ea12d1640e6d8dab7281", size = 426454, upload-time = "2025-09-11T21:38:34.076Z" }, - { url = "https://files.pythonhosted.org/packages/3f/be/8dd0a927c559b37d7a6c8ab79034fd167dcc1f851595f2e641ad62be8643/protobuf-6.32.1-cp39-abi3-manylinux2014_aarch64.whl", hash = "sha256:2f5b80a49e1eb7b86d85fcd23fe92df154b9730a725c3b38c4e43b9d77018bf4", size = 322874, upload-time = "2025-09-11T21:38:35.509Z" }, - { url = "https://files.pythonhosted.org/packages/5c/f6/88d77011b605ef979aace37b7703e4eefad066f7e84d935e5a696515c2dd/protobuf-6.32.1-cp39-abi3-manylinux2014_x86_64.whl", hash = "sha256:b1864818300c297265c83a4982fd3169f97122c299f56a56e2445c3698d34710", size = 322013, upload-time = "2025-09-11T21:38:37.017Z" }, - { url = "https://files.pythonhosted.org/packages/97/b7/15cc7d93443d6c6a84626ae3258a91f4c6ac8c0edd5df35ea7658f71b79c/protobuf-6.32.1-py3-none-any.whl", hash = "sha256:2601b779fc7d32a866c6b4404f9d42a3f67c5b9f3f15b4db3cccabe06b95c346", size = 169289, upload-time = "2025-09-11T21:38:41.234Z" }, + { url = "https://files.pythonhosted.org/packages/7e/ee/52b3fa8feb6db4a833dfea4943e175ce645144532e8a90f72571ad85df4e/protobuf-6.33.0-cp310-abi3-win32.whl", hash = "sha256:d6101ded078042a8f17959eccd9236fb7a9ca20d3b0098bbcb91533a5680d035", size = 425593, upload-time = "2025-10-15T20:39:40.29Z" }, + { url = "https://files.pythonhosted.org/packages/7b/c6/7a465f1825872c55e0341ff4a80198743f73b69ce5d43ab18043699d1d81/protobuf-6.33.0-cp310-abi3-win_amd64.whl", hash = "sha256:9a031d10f703f03768f2743a1c403af050b6ae1f3480e9c140f39c45f81b13ee", size = 436882, upload-time = "2025-10-15T20:39:42.841Z" }, + { url = "https://files.pythonhosted.org/packages/e1/a9/b6eee662a6951b9c3640e8e452ab3e09f117d99fc10baa32d1581a0d4099/protobuf-6.33.0-cp39-abi3-macosx_10_9_universal2.whl", hash = "sha256:905b07a65f1a4b72412314082c7dbfae91a9e8b68a0cc1577515f8df58ecf455", size = 427521, upload-time = "2025-10-15T20:39:43.803Z" }, + { url = "https://files.pythonhosted.org/packages/10/35/16d31e0f92c6d2f0e77c2a3ba93185130ea13053dd16200a57434c882f2b/protobuf-6.33.0-cp39-abi3-manylinux2014_aarch64.whl", hash = "sha256:e0697ece353e6239b90ee43a9231318302ad8353c70e6e45499fa52396debf90", size = 324445, upload-time = "2025-10-15T20:39:44.932Z" }, + { url = "https://files.pythonhosted.org/packages/e6/eb/2a981a13e35cda8b75b5585aaffae2eb904f8f351bdd3870769692acbd8a/protobuf-6.33.0-cp39-abi3-manylinux2014_s390x.whl", hash = "sha256:e0a1715e4f27355afd9570f3ea369735afc853a6c3951a6afe1f80d8569ad298", size = 339159, upload-time = "2025-10-15T20:39:46.186Z" }, + { url = "https://files.pythonhosted.org/packages/21/51/0b1cbad62074439b867b4e04cc09b93f6699d78fd191bed2bbb44562e077/protobuf-6.33.0-cp39-abi3-manylinux2014_x86_64.whl", hash = "sha256:35be49fd3f4fefa4e6e2aacc35e8b837d6703c37a2168a55ac21e9b1bc7559ef", size = 323172, upload-time = "2025-10-15T20:39:47.465Z" }, + { url = "https://files.pythonhosted.org/packages/07/d1/0a28c21707807c6aacd5dc9c3704b2aa1effbf37adebd8caeaf68b17a636/protobuf-6.33.0-py3-none-any.whl", hash = "sha256:25c9e1963c6734448ea2d308cfa610e692b801304ba0908d7bfa564ac5132995", size = 170477, upload-time = "2025-10-15T20:39:51.311Z" }, ] [[package]] name = "psycopg" -version = "3.2.10" +version = "3.2.11" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "tzdata", marker = "sys_platform == 'win32'" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/a9/f1/0258a123c045afaf3c3b60c22ccff077bceeb24b8dc2c593270899353bd0/psycopg-3.2.10.tar.gz", hash = "sha256:0bce99269d16ed18401683a8569b2c5abd94f72f8364856d56c0389bcd50972a", size = 160380, upload-time = "2025-09-08T09:13:37.775Z" } +sdist = { url = "https://files.pythonhosted.org/packages/27/02/9fdfc018c026df2bcf9c11480c1014f9b90c6d801e5f929408cbfbf94cc0/psycopg-3.2.11.tar.gz", hash = "sha256:398bb484ed44361e041c8f804ed7af3d2fcefbffdace1d905b7446c319321706", size = 160644, upload-time = "2025-10-18T22:48:28.136Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/4a/90/422ffbbeeb9418c795dae2a768db860401446af0c6768bc061ce22325f58/psycopg-3.2.10-py3-none-any.whl", hash = "sha256:ab5caf09a9ec42e314a21f5216dbcceac528e0e05142e42eea83a3b28b320ac3", size = 206586, upload-time = "2025-09-08T09:07:50.121Z" }, + { url = "https://files.pythonhosted.org/packages/aa/1b/96ee90ed0007d64936d9bd1bb3108d0af3cf762b4f11dbd73359f0687c3d/psycopg-3.2.11-py3-none-any.whl", hash = "sha256:217231b2b6b72fba88281b94241b2f16043ee67f81def47c52a01b72ff0c086a", size = 206766, upload-time = "2025-10-18T22:43:32.114Z" }, ] [package.optional-dependencies] @@ -1279,27 +1283,27 @@ binary = [ [[package]] name = "psycopg-binary" -version = "3.2.10" -source = { registry = "https://pypi.org/simple" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/3a/80/db840f7ebf948ab05b4793ad34d4da6ad251829d6c02714445ae8b5f1403/psycopg_binary-3.2.10-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:55b14f2402be027fe1568bc6c4d75ac34628ff5442a70f74137dadf99f738e3b", size = 3982057, upload-time = "2025-09-08T09:10:28.725Z" }, - { url = "https://files.pythonhosted.org/packages/2d/53/39308328bb8388b1ec3501a16128c5ada405f217c6d91b3d921b9f3c5604/psycopg_binary-3.2.10-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:43d803fb4e108a67c78ba58f3e6855437ca25d56504cae7ebbfbd8fce9b59247", size = 4066830, upload-time = "2025-09-08T09:10:34.083Z" }, - { url = "https://files.pythonhosted.org/packages/e7/5a/18e6f41b40c71197479468cb18703b2999c6e4ab06f9c05df3bf416a55d7/psycopg_binary-3.2.10-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:470594d303928ab72a1ffd179c9c7bde9d00f76711d6b0c28f8a46ddf56d9807", size = 4610747, upload-time = "2025-09-08T09:10:39.697Z" }, - { url = "https://files.pythonhosted.org/packages/be/ab/9198fed279aca238c245553ec16504179d21aad049958a2865d0aa797db4/psycopg_binary-3.2.10-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:a1d4e4d309049e3cb61269652a3ca56cb598da30ecd7eb8cea561e0d18bc1a43", size = 4700301, upload-time = "2025-09-08T09:10:44.715Z" }, - { url = "https://files.pythonhosted.org/packages/fc/0d/59024313b5e6c5da3e2a016103494c609d73a95157a86317e0f600c8acb3/psycopg_binary-3.2.10-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:a92ff1c2cd79b3966d6a87e26ceb222ecd5581b5ae4b58961f126af806a861ed", size = 4392679, upload-time = "2025-09-08T09:10:49.106Z" }, - { url = "https://files.pythonhosted.org/packages/ff/47/21ef15d8a66e3a7a76a177f885173d27f0c5cbe39f5dd6eda9832d6b4e19/psycopg_binary-3.2.10-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:ac0365398947879c9827b319217096be727da16c94422e0eb3cf98c930643162", size = 3857881, upload-time = "2025-09-08T09:10:56.75Z" }, - { url = "https://files.pythonhosted.org/packages/af/35/c5e5402ccd40016f15d708bbf343b8cf107a58f8ae34d14dc178fdea4fd4/psycopg_binary-3.2.10-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:42ee399c2613b470a87084ed79b06d9d277f19b0457c10e03a4aef7059097abc", size = 3531135, upload-time = "2025-09-08T09:11:03.346Z" }, - { url = "https://files.pythonhosted.org/packages/e6/e2/9b82946859001fe5e546c8749991b8b3b283f40d51bdc897d7a8e13e0a5e/psycopg_binary-3.2.10-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:2028073fc12cd70ba003309d1439c0c4afab4a7eee7653b8c91213064fffe12b", size = 3581813, upload-time = "2025-09-08T09:11:08.76Z" }, - { url = "https://files.pythonhosted.org/packages/c5/91/c10cfccb75464adb4781486e0014ecd7c2ad6decf6cbe0afd8db65ac2bc9/psycopg_binary-3.2.10-cp313-cp313-win_amd64.whl", hash = "sha256:8390db6d2010ffcaf7f2b42339a2da620a7125d37029c1f9b72dfb04a8e7be6f", size = 2881466, upload-time = "2025-09-08T09:11:14.078Z" }, - { url = "https://files.pythonhosted.org/packages/fd/89/b0702ba0d007cc787dd7a205212c8c8cae229d1e7214c8e27bdd3b13d33e/psycopg_binary-3.2.10-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:b34c278a58aa79562afe7f45e0455b1f4cad5974fc3d5674cc5f1f9f57e97fc5", size = 3981253, upload-time = "2025-09-08T09:11:19.864Z" }, - { url = "https://files.pythonhosted.org/packages/dc/c9/e51ac72ac34d1d8ea7fd861008ad8de60e56997f5bd3fbae7536570f6f58/psycopg_binary-3.2.10-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:810f65b9ef1fe9dddb5c05937884ea9563aaf4e1a2c3d138205231ed5f439511", size = 4067542, upload-time = "2025-09-08T09:11:25.366Z" }, - { url = "https://files.pythonhosted.org/packages/d6/27/49625c79ae89959a070c1fb63ebb5c6eed426fa09e15086b6f5b626fcdc2/psycopg_binary-3.2.10-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:8923487c3898c65e1450847e15d734bb2e6adbd2e79d2d1dd5ad829a1306bdc0", size = 4615338, upload-time = "2025-09-08T09:11:31.079Z" }, - { url = "https://files.pythonhosted.org/packages/b9/0d/9fdb5482f50f56303770ea8a3b1c1f32105762da731c7e2a4f425e0b3887/psycopg_binary-3.2.10-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:7950ff79df7a453ac8a7d7a74694055b6c15905b0a2b6e3c99eb59c51a3f9bf7", size = 4703401, upload-time = "2025-09-08T09:11:38.718Z" }, - { url = "https://files.pythonhosted.org/packages/3c/f3/eb2f75ca2c090bf1d0c90d6da29ef340876fe4533bcfc072a9fd94dd52b4/psycopg_binary-3.2.10-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:0c2b95e83fda70ed2b0b4fadd8538572e4a4d987b721823981862d1ab56cc760", size = 4393458, upload-time = "2025-09-08T09:11:44.114Z" }, - { url = "https://files.pythonhosted.org/packages/20/2e/887abe0591b2f1c1af31164b9efb46c5763e4418f403503bc9fbddaa02ef/psycopg_binary-3.2.10-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:20384985fbc650c09a547a13c6d7f91bb42020d38ceafd2b68b7fc4a48a1f160", size = 3863733, upload-time = "2025-09-08T09:11:49.237Z" }, - { url = "https://files.pythonhosted.org/packages/6b/8c/9446e3a84187220a98657ef778518f9b44eba55b1f6c3e8300d229ec9930/psycopg_binary-3.2.10-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:1f6982609b8ff8fcd67299b67cd5787da1876f3bb28fedd547262cfa8ddedf94", size = 3535121, upload-time = "2025-09-08T09:11:53.887Z" }, - { url = "https://files.pythonhosted.org/packages/b4/e1/f0382c956bfaa951a0dbd4d5a354acf093ef7e5219996958143dfd2bf37d/psycopg_binary-3.2.10-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:bf30dcf6aaaa8d4779a20d2158bdf81cc8e84ce8eee595d748a7671c70c7b890", size = 3584235, upload-time = "2025-09-08T09:12:01.118Z" }, - { url = "https://files.pythonhosted.org/packages/5a/dd/464bd739bacb3b745a1c93bc15f20f0b1e27f0a64ec693367794b398673b/psycopg_binary-3.2.10-cp314-cp314-win_amd64.whl", hash = "sha256:d5c6a66a76022af41970bf19f51bc6bf87bd10165783dd1d40484bfd87d6b382", size = 2973554, upload-time = "2025-09-08T09:12:05.884Z" }, +version = "3.2.11" +source = { registry = "https://pypi.org/simple" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/f2/93/9cea78ed3b279909f0fd6c2badb24b2361b93c875d6a7c921e26f6254044/psycopg_binary-3.2.11-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:47f6cf8a1d02d25238bdb8741ac641ff0ec22b1c6ff6a2acd057d0da5c712842", size = 4017939, upload-time = "2025-10-18T22:45:45.114Z" }, + { url = "https://files.pythonhosted.org/packages/58/86/fc9925f500b2c140c0bb8c1f8fcd04f8c45c76d4852e87baf4c75182de8c/psycopg_binary-3.2.11-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:91268f04380964a5e767f8102d05f1e23312ddbe848de1a9514b08b3fc57d354", size = 4090150, upload-time = "2025-10-18T22:45:50.214Z" }, + { url = "https://files.pythonhosted.org/packages/4e/10/752b698da1ca9e6c5f15d8798cb637c3615315fd2da17eee4a90cf20ee08/psycopg_binary-3.2.11-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:199f88a05dd22133eab2deb30348ef7a70c23d706c8e63fdc904234163c63517", size = 4625597, upload-time = "2025-10-18T22:45:54.638Z" }, + { url = "https://files.pythonhosted.org/packages/0a/9f/b578545c3c23484f4e234282d97ab24632a1d3cbfec64209786872e7cc8f/psycopg_binary-3.2.11-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:7b3c5474dbad63bcccb8d14d4d4c7c19f1dc6f8e8c1914cbc771d261cf8eddca", size = 4720326, upload-time = "2025-10-18T22:45:59.266Z" }, + { url = "https://files.pythonhosted.org/packages/43/3b/ba548d3fe65a7d4c96e568c2188e4b665802e3cba41664945ed95d16eae9/psycopg_binary-3.2.11-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:581358e770a4536e546841b78fd0fe318added4a82443bf22d0bbe3109cf9582", size = 4411647, upload-time = "2025-10-18T22:46:04.009Z" }, + { url = "https://files.pythonhosted.org/packages/26/65/559ab485b198600e7ff70d70786ae5c89d63475ca01d43a7dda0d7c91386/psycopg_binary-3.2.11-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:54a30f00a51b9043048b3e7ee806ffd31fc5fbd02a20f0e69d21306ff33dc473", size = 3863037, upload-time = "2025-10-18T22:46:08.469Z" }, + { url = "https://files.pythonhosted.org/packages/8c/29/05d0b48c8bef147e8216a36a1263a309a6240dcc09a56f5b8174fa6216d2/psycopg_binary-3.2.11-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:2a438fad4cc081b018431fde0e791b6d50201526edf39522a85164f606c39ddb", size = 3536975, upload-time = "2025-10-18T22:46:12.982Z" }, + { url = "https://files.pythonhosted.org/packages/d4/75/304e133d3ab1a49602616192edb81f603ed574f79966449105f2e200999d/psycopg_binary-3.2.11-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:f5e7415b5d0f58edf2708842c66605092df67f3821161d861b09695fc326c4de", size = 3586213, upload-time = "2025-10-18T22:46:19.523Z" }, + { url = "https://files.pythonhosted.org/packages/c0/10/c47cce42fa3c37d439e1400eaa5eeb2ce53dc3abc84d52c8a8a9e544d945/psycopg_binary-3.2.11-cp313-cp313-win_amd64.whl", hash = "sha256:6b9632c42f76d5349e7dd50025cff02688eb760b258e891ad2c6428e7e4917d5", size = 2912997, upload-time = "2025-10-18T22:46:24.978Z" }, + { url = "https://files.pythonhosted.org/packages/85/13/728b4763ef76a688737acebfcb5ab8696b024adc49a69c86081392b0e5ba/psycopg_binary-3.2.11-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:260738ae222b41dbefd0d84cb2e150a112f90b41688630f57fdac487ab6d6f38", size = 4016962, upload-time = "2025-10-18T22:46:29.207Z" }, + { url = "https://files.pythonhosted.org/packages/9f/0f/6180149621a907c5b60a2fae87d6ee10cc13e8c9f58d8250c310634ced04/psycopg_binary-3.2.11-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:c594c199869099c59c85b9f4423370b6212491fb929e7fcda0da1768761a2c2c", size = 4090614, upload-time = "2025-10-18T22:46:33.073Z" }, + { url = "https://files.pythonhosted.org/packages/f8/97/cce19bdef510b698c9036d5573b941b539ffcaa7602450da559c8a62e0c3/psycopg_binary-3.2.11-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:5768a9e7d393b2edd3a28de5a6d5850d054a016ed711f7044a9072f19f5e50d5", size = 4629749, upload-time = "2025-10-18T22:46:37.415Z" }, + { url = "https://files.pythonhosted.org/packages/93/9d/9bff18989fb2bf05d18c1431dd8bec4a1d90141beb11fc45d3269947ddf3/psycopg_binary-3.2.11-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:27eb6367350b75fef882c40cd6f748bfd976db2f8651f7511956f11efc15154f", size = 4724035, upload-time = "2025-10-18T22:46:42.568Z" }, + { url = "https://files.pythonhosted.org/packages/08/e5/39b930323428596990367b7953197730213d3d9d07bcedcad1d026608178/psycopg_binary-3.2.11-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:fa2aa5094dc962967ca0978c035b3ef90329b802501ef12a088d3bac6a55598e", size = 4411419, upload-time = "2025-10-18T22:46:47.745Z" }, + { url = "https://files.pythonhosted.org/packages/9a/9c/97c25438d1e51ddc6a7f67990b4c59f94bc515114ada864804ccee27ef1b/psycopg_binary-3.2.11-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:7744b4ed1f3b76fe37de7e9ef98014482fe74b6d3dfe1026cc4cfb4b4404e74f", size = 3867844, upload-time = "2025-10-18T22:46:53.328Z" }, + { url = "https://files.pythonhosted.org/packages/91/51/8c1e291cf4aa9982666f71a886aa782d990aa16853a42de545a0a9a871ef/psycopg_binary-3.2.11-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:5f6f948ff1cd252003ff534d7b50a2b25453b4212b283a7514ff8751bdb68c37", size = 3541539, upload-time = "2025-10-18T22:46:58.993Z" }, + { url = "https://files.pythonhosted.org/packages/57/0a/e25edcdfa1111bfc5c95668b7469b5a957b40ce10cc81383688d65564826/psycopg_binary-3.2.11-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:3bd2c8fb1dec6f93383fbaa561591fa3d676e079f9cb9889af17c3020a19715f", size = 3588090, upload-time = "2025-10-18T22:47:04.105Z" }, + { url = "https://files.pythonhosted.org/packages/a3/aa/f8c2f4b4c13d5680a20e5bfcd61f9e154bce26e7a2c70cb0abeade088d61/psycopg_binary-3.2.11-cp314-cp314-win_amd64.whl", hash = "sha256:c45f61202e5691090a697e599997eaffa3ec298209743caa4fd346145acabafe", size = 3006049, upload-time = "2025-10-18T22:47:07.923Z" }, ] [[package]] @@ -1351,7 +1355,7 @@ wheels = [ [[package]] name = "pydantic" -version = "2.12.0" +version = "2.11.10" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "annotated-types" }, @@ -1359,9 +1363,9 @@ dependencies = [ { name = "typing-extensions" }, { name = "typing-inspection" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/c3/da/b8a7ee04378a53f6fefefc0c5e05570a3ebfdfa0523a878bcd3b475683ee/pydantic-2.12.0.tar.gz", hash = "sha256:c1a077e6270dbfb37bfd8b498b3981e2bb18f68103720e51fa6c306a5a9af563", size = 814760, upload-time = "2025-10-07T15:58:03.467Z" } +sdist = { url = "https://files.pythonhosted.org/packages/ae/54/ecab642b3bed45f7d5f59b38443dcb36ef50f85af192e6ece103dbfe9587/pydantic-2.11.10.tar.gz", hash = "sha256:dc280f0982fbda6c38fada4e476dc0a4f3aeaf9c6ad4c28df68a666ec3c61423", size = 788494, upload-time = "2025-10-04T10:40:41.338Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/f4/9d/d5c855424e2e5b6b626fbc6ec514d8e655a600377ce283008b115abb7445/pydantic-2.12.0-py3-none-any.whl", hash = "sha256:f6a1da352d42790537e95e83a8bdfb91c7efbae63ffd0b86fa823899e807116f", size = 459730, upload-time = "2025-10-07T15:58:01.576Z" }, + { url = "https://files.pythonhosted.org/packages/bd/1f/73c53fcbfb0b5a78f91176df41945ca466e71e9d9d836e5c522abda39ee7/pydantic-2.11.10-py3-none-any.whl", hash = "sha256:802a655709d49bd004c31e865ef37da30b540786a46bfce02333e0e24b5fe29a", size = 444823, upload-time = "2025-10-04T10:40:39.055Z" }, ] [package.optional-dependencies] @@ -1371,47 +1375,30 @@ email = [ [[package]] name = "pydantic-core" -version = "2.41.1" +version = "2.33.2" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "typing-extensions" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/7d/14/12b4a0d2b0b10d8e1d9a24ad94e7bbb43335eaf29c0c4e57860e8a30734a/pydantic_core-2.41.1.tar.gz", hash = "sha256:1ad375859a6d8c356b7704ec0f547a58e82ee80bb41baa811ad710e124bc8f2f", size = 454870, upload-time = "2025-10-07T10:50:45.974Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/27/8a/6d54198536a90a37807d31a156642aae7a8e1263ed9fe6fc6245defe9332/pydantic_core-2.41.1-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:70e790fce5f05204ef4403159857bfcd587779da78627b0babb3654f75361ebf", size = 2105825, upload-time = "2025-10-06T21:10:51.719Z" }, - { url = "https://files.pythonhosted.org/packages/4f/2e/4784fd7b22ac9c8439db25bf98ffed6853d01e7e560a346e8af821776ccc/pydantic_core-2.41.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:9cebf1ca35f10930612d60bd0f78adfacee824c30a880e3534ba02c207cceceb", size = 1910126, upload-time = "2025-10-06T21:10:53.145Z" }, - { url = "https://files.pythonhosted.org/packages/f3/92/31eb0748059ba5bd0aa708fb4bab9fcb211461ddcf9e90702a6542f22d0d/pydantic_core-2.41.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:170406a37a5bc82c22c3274616bf6f17cc7df9c4a0a0a50449e559cb755db669", size = 1961472, upload-time = "2025-10-06T21:10:55.754Z" }, - { url = "https://files.pythonhosted.org/packages/ab/91/946527792275b5c4c7dde4cfa3e81241bf6900e9fee74fb1ba43e0c0f1ab/pydantic_core-2.41.1-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:12d4257fc9187a0ccd41b8b327d6a4e57281ab75e11dda66a9148ef2e1fb712f", size = 2063230, upload-time = "2025-10-06T21:10:57.179Z" }, - { url = "https://files.pythonhosted.org/packages/31/5d/a35c5d7b414e5c0749f1d9f0d159ee2ef4bab313f499692896b918014ee3/pydantic_core-2.41.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a75a33b4db105dd1c8d57839e17ee12db8d5ad18209e792fa325dbb4baeb00f4", size = 2229469, upload-time = "2025-10-06T21:10:59.409Z" }, - { url = "https://files.pythonhosted.org/packages/21/4d/8713737c689afa57ecfefe38db78259d4484c97aa494979e6a9d19662584/pydantic_core-2.41.1-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:08a589f850803a74e0fcb16a72081cafb0d72a3cdda500106942b07e76b7bf62", size = 2347986, upload-time = "2025-10-06T21:11:00.847Z" }, - { url = "https://files.pythonhosted.org/packages/f6/ec/929f9a3a5ed5cda767081494bacd32f783e707a690ce6eeb5e0730ec4986/pydantic_core-2.41.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7a97939d6ea44763c456bd8a617ceada2c9b96bb5b8ab3dfa0d0827df7619014", size = 2072216, upload-time = "2025-10-06T21:11:02.43Z" }, - { url = "https://files.pythonhosted.org/packages/26/55/a33f459d4f9cc8786d9db42795dbecc84fa724b290d7d71ddc3d7155d46a/pydantic_core-2.41.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:d2ae423c65c556f09569524b80ffd11babff61f33055ef9773d7c9fabc11ed8d", size = 2193047, upload-time = "2025-10-06T21:11:03.787Z" }, - { url = "https://files.pythonhosted.org/packages/77/af/d5c6959f8b089f2185760a2779079e3c2c411bfc70ea6111f58367851629/pydantic_core-2.41.1-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:4dc703015fbf8764d6a8001c327a87f1823b7328d40b47ce6000c65918ad2b4f", size = 2140613, upload-time = "2025-10-06T21:11:05.607Z" }, - { url = "https://files.pythonhosted.org/packages/58/e5/2c19bd2a14bffe7fabcf00efbfbd3ac430aaec5271b504a938ff019ac7be/pydantic_core-2.41.1-cp313-cp313-musllinux_1_1_armv7l.whl", hash = "sha256:968e4ffdfd35698a5fe659e5e44c508b53664870a8e61c8f9d24d3d145d30257", size = 2327641, upload-time = "2025-10-06T21:11:07.143Z" }, - { url = "https://files.pythonhosted.org/packages/93/ef/e0870ccda798c54e6b100aff3c4d49df5458fd64217e860cb9c3b0a403f4/pydantic_core-2.41.1-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:fff2b76c8e172d34771cd4d4f0ade08072385310f214f823b5a6ad4006890d32", size = 2318229, upload-time = "2025-10-06T21:11:08.73Z" }, - { url = "https://files.pythonhosted.org/packages/b1/4b/c3b991d95f5deb24d0bd52e47bcf716098fa1afe0ce2d4bd3125b38566ba/pydantic_core-2.41.1-cp313-cp313-win32.whl", hash = "sha256:a38a5263185407ceb599f2f035faf4589d57e73c7146d64f10577f6449e8171d", size = 1997911, upload-time = "2025-10-06T21:11:10.329Z" }, - { url = "https://files.pythonhosted.org/packages/a7/ce/5c316fd62e01f8d6be1b7ee6b54273214e871772997dc2c95e204997a055/pydantic_core-2.41.1-cp313-cp313-win_amd64.whl", hash = "sha256:b42ae7fd6760782c975897e1fdc810f483b021b32245b0105d40f6e7a3803e4b", size = 2034301, upload-time = "2025-10-06T21:11:12.113Z" }, - { url = "https://files.pythonhosted.org/packages/29/41/902640cfd6a6523194123e2c3373c60f19006447f2fb06f76de4e8466c5b/pydantic_core-2.41.1-cp313-cp313-win_arm64.whl", hash = "sha256:ad4111acc63b7384e205c27a2f15e23ac0ee21a9d77ad6f2e9cb516ec90965fb", size = 1977238, upload-time = "2025-10-06T21:11:14.1Z" }, - { url = "https://files.pythonhosted.org/packages/04/04/28b040e88c1b89d851278478842f0bdf39c7a05da9e850333c6c8cbe7dfa/pydantic_core-2.41.1-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:440d0df7415b50084a4ba9d870480c16c5f67c0d1d4d5119e3f70925533a0edc", size = 1875626, upload-time = "2025-10-06T21:11:15.69Z" }, - { url = "https://files.pythonhosted.org/packages/d6/58/b41dd3087505220bb58bc81be8c3e8cbc037f5710cd3c838f44f90bdd704/pydantic_core-2.41.1-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:71eaa38d342099405dae6484216dcf1e8e4b0bebd9b44a4e08c9b43db6a2ab67", size = 2045708, upload-time = "2025-10-06T21:11:17.258Z" }, - { url = "https://files.pythonhosted.org/packages/d7/b8/760f23754e40bf6c65b94a69b22c394c24058a0ef7e2aa471d2e39219c1a/pydantic_core-2.41.1-cp313-cp313t-win_amd64.whl", hash = "sha256:555ecf7e50f1161d3f693bc49f23c82cf6cdeafc71fa37a06120772a09a38795", size = 1997171, upload-time = "2025-10-06T21:11:18.822Z" }, - { url = "https://files.pythonhosted.org/packages/41/12/cec246429ddfa2778d2d6301eca5362194dc8749ecb19e621f2f65b5090f/pydantic_core-2.41.1-cp314-cp314-macosx_10_12_x86_64.whl", hash = "sha256:05226894a26f6f27e1deb735d7308f74ef5fa3a6de3e0135bb66cdcaee88f64b", size = 2107836, upload-time = "2025-10-06T21:11:20.432Z" }, - { url = "https://files.pythonhosted.org/packages/20/39/baba47f8d8b87081302498e610aefc37142ce6a1cc98b2ab6b931a162562/pydantic_core-2.41.1-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:85ff7911c6c3e2fd8d3779c50925f6406d770ea58ea6dde9c230d35b52b16b4a", size = 1904449, upload-time = "2025-10-06T21:11:22.185Z" }, - { url = "https://files.pythonhosted.org/packages/50/32/9a3d87cae2c75a5178334b10358d631bd094b916a00a5993382222dbfd92/pydantic_core-2.41.1-cp314-cp314-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:47f1f642a205687d59b52dc1a9a607f45e588f5a2e9eeae05edd80c7a8c47674", size = 1961750, upload-time = "2025-10-06T21:11:24.348Z" }, - { url = "https://files.pythonhosted.org/packages/27/42/a96c9d793a04cf2a9773bff98003bb154087b94f5530a2ce6063ecfec583/pydantic_core-2.41.1-cp314-cp314-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:df11c24e138876ace5ec6043e5cae925e34cf38af1a1b3d63589e8f7b5f5cdc4", size = 2063305, upload-time = "2025-10-06T21:11:26.556Z" }, - { url = "https://files.pythonhosted.org/packages/3e/8d/028c4b7d157a005b1f52c086e2d4b0067886b213c86220c1153398dbdf8f/pydantic_core-2.41.1-cp314-cp314-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:7f0bf7f5c8f7bf345c527e8a0d72d6b26eda99c1227b0c34e7e59e181260de31", size = 2228959, upload-time = "2025-10-06T21:11:28.426Z" }, - { url = "https://files.pythonhosted.org/packages/08/f7/ee64cda8fcc9ca3f4716e6357144f9ee71166775df582a1b6b738bf6da57/pydantic_core-2.41.1-cp314-cp314-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:82b887a711d341c2c47352375d73b029418f55b20bd7815446d175a70effa706", size = 2345421, upload-time = "2025-10-06T21:11:30.226Z" }, - { url = "https://files.pythonhosted.org/packages/13/c0/e8ec05f0f5ee7a3656973ad9cd3bc73204af99f6512c1a4562f6fb4b3f7d/pydantic_core-2.41.1-cp314-cp314-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b5f1d5d6bbba484bdf220c72d8ecd0be460f4bd4c5e534a541bb2cd57589fb8b", size = 2065288, upload-time = "2025-10-06T21:11:32.019Z" }, - { url = "https://files.pythonhosted.org/packages/0a/25/d77a73ff24e2e4fcea64472f5e39b0402d836da9b08b5361a734d0153023/pydantic_core-2.41.1-cp314-cp314-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:2bf1917385ebe0f968dc5c6ab1375886d56992b93ddfe6bf52bff575d03662be", size = 2189759, upload-time = "2025-10-06T21:11:33.753Z" }, - { url = "https://files.pythonhosted.org/packages/66/45/4a4ebaaae12a740552278d06fe71418c0f2869537a369a89c0e6723b341d/pydantic_core-2.41.1-cp314-cp314-musllinux_1_1_aarch64.whl", hash = "sha256:4f94f3ab188f44b9a73f7295663f3ecb8f2e2dd03a69c8f2ead50d37785ecb04", size = 2140747, upload-time = "2025-10-06T21:11:35.781Z" }, - { url = "https://files.pythonhosted.org/packages/da/6d/b727ce1022f143194a36593243ff244ed5a1eb3c9122296bf7e716aa37ba/pydantic_core-2.41.1-cp314-cp314-musllinux_1_1_armv7l.whl", hash = "sha256:3925446673641d37c30bd84a9d597e49f72eacee8b43322c8999fa17d5ae5bc4", size = 2327416, upload-time = "2025-10-06T21:11:37.75Z" }, - { url = "https://files.pythonhosted.org/packages/6f/8c/02df9d8506c427787059f87c6c7253435c6895e12472a652d9616ee0fc95/pydantic_core-2.41.1-cp314-cp314-musllinux_1_1_x86_64.whl", hash = "sha256:49bd51cc27adb980c7b97357ae036ce9b3c4d0bb406e84fbe16fb2d368b602a8", size = 2318138, upload-time = "2025-10-06T21:11:39.463Z" }, - { url = "https://files.pythonhosted.org/packages/98/67/0cf429a7d6802536941f430e6e3243f6d4b68f41eeea4b242372f1901794/pydantic_core-2.41.1-cp314-cp314-win32.whl", hash = "sha256:a31ca0cd0e4d12ea0df0077df2d487fc3eb9d7f96bbb13c3c5b88dcc21d05159", size = 1998429, upload-time = "2025-10-06T21:11:41.989Z" }, - { url = "https://files.pythonhosted.org/packages/38/60/742fef93de5d085022d2302a6317a2b34dbfe15258e9396a535c8a100ae7/pydantic_core-2.41.1-cp314-cp314-win_amd64.whl", hash = "sha256:1b5c4374a152e10a22175d7790e644fbd8ff58418890e07e2073ff9d4414efae", size = 2028870, upload-time = "2025-10-06T21:11:43.66Z" }, - { url = "https://files.pythonhosted.org/packages/31/38/cdd8ccb8555ef7720bd7715899bd6cfbe3c29198332710e1b61b8f5dd8b8/pydantic_core-2.41.1-cp314-cp314-win_arm64.whl", hash = "sha256:4fee76d757639b493eb600fba668f1e17475af34c17dd61db7a47e824d464ca9", size = 1974275, upload-time = "2025-10-06T21:11:45.476Z" }, - { url = "https://files.pythonhosted.org/packages/e7/7e/8ac10ccb047dc0221aa2530ec3c7c05ab4656d4d4bd984ee85da7f3d5525/pydantic_core-2.41.1-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:f9b9c968cfe5cd576fdd7361f47f27adeb120517e637d1b189eea1c3ece573f4", size = 1875124, upload-time = "2025-10-06T21:11:47.591Z" }, - { url = "https://files.pythonhosted.org/packages/c3/e4/7d9791efeb9c7d97e7268f8d20e0da24d03438a7fa7163ab58f1073ba968/pydantic_core-2.41.1-cp314-cp314t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f1ebc7ab67b856384aba09ed74e3e977dded40e693de18a4f197c67d0d4e6d8e", size = 2043075, upload-time = "2025-10-06T21:11:49.542Z" }, - { url = "https://files.pythonhosted.org/packages/2d/c3/3f6e6b2342ac11ac8cd5cb56e24c7b14afa27c010e82a765ffa5f771884a/pydantic_core-2.41.1-cp314-cp314t-win_amd64.whl", hash = "sha256:8ae0dc57b62a762985bc7fbf636be3412394acc0ddb4ade07fe104230f1b9762", size = 1995341, upload-time = "2025-10-06T21:11:51.497Z" }, +sdist = { url = "https://files.pythonhosted.org/packages/ad/88/5f2260bdfae97aabf98f1778d43f69574390ad787afb646292a638c923d4/pydantic_core-2.33.2.tar.gz", hash = "sha256:7cb8bc3605c29176e1b105350d2e6474142d7c1bd1d9327c4a9bdb46bf827acc", size = 435195, upload-time = "2025-04-23T18:33:52.104Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/46/8c/99040727b41f56616573a28771b1bfa08a3d3fe74d3d513f01251f79f172/pydantic_core-2.33.2-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:1082dd3e2d7109ad8b7da48e1d4710c8d06c253cbc4a27c1cff4fbcaa97a9e3f", size = 2015688, upload-time = "2025-04-23T18:31:53.175Z" }, + { url = "https://files.pythonhosted.org/packages/3a/cc/5999d1eb705a6cefc31f0b4a90e9f7fc400539b1a1030529700cc1b51838/pydantic_core-2.33.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:f517ca031dfc037a9c07e748cefd8d96235088b83b4f4ba8939105d20fa1dcd6", size = 1844808, upload-time = "2025-04-23T18:31:54.79Z" }, + { url = "https://files.pythonhosted.org/packages/6f/5e/a0a7b8885c98889a18b6e376f344da1ef323d270b44edf8174d6bce4d622/pydantic_core-2.33.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0a9f2c9dd19656823cb8250b0724ee9c60a82f3cdf68a080979d13092a3b0fef", size = 1885580, upload-time = "2025-04-23T18:31:57.393Z" }, + { url = "https://files.pythonhosted.org/packages/3b/2a/953581f343c7d11a304581156618c3f592435523dd9d79865903272c256a/pydantic_core-2.33.2-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:2b0a451c263b01acebe51895bfb0e1cc842a5c666efe06cdf13846c7418caa9a", size = 1973859, upload-time = "2025-04-23T18:31:59.065Z" }, + { url = "https://files.pythonhosted.org/packages/e6/55/f1a813904771c03a3f97f676c62cca0c0a4138654107c1b61f19c644868b/pydantic_core-2.33.2-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1ea40a64d23faa25e62a70ad163571c0b342b8bf66d5fa612ac0dec4f069d916", size = 2120810, upload-time = "2025-04-23T18:32:00.78Z" }, + { url = "https://files.pythonhosted.org/packages/aa/c3/053389835a996e18853ba107a63caae0b9deb4a276c6b472931ea9ae6e48/pydantic_core-2.33.2-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:0fb2d542b4d66f9470e8065c5469ec676978d625a8b7a363f07d9a501a9cb36a", size = 2676498, upload-time = "2025-04-23T18:32:02.418Z" }, + { url = "https://files.pythonhosted.org/packages/eb/3c/f4abd740877a35abade05e437245b192f9d0ffb48bbbbd708df33d3cda37/pydantic_core-2.33.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9fdac5d6ffa1b5a83bca06ffe7583f5576555e6c8b3a91fbd25ea7780f825f7d", size = 2000611, upload-time = "2025-04-23T18:32:04.152Z" }, + { url = "https://files.pythonhosted.org/packages/59/a7/63ef2fed1837d1121a894d0ce88439fe3e3b3e48c7543b2a4479eb99c2bd/pydantic_core-2.33.2-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:04a1a413977ab517154eebb2d326da71638271477d6ad87a769102f7c2488c56", size = 2107924, upload-time = "2025-04-23T18:32:06.129Z" }, + { url = "https://files.pythonhosted.org/packages/04/8f/2551964ef045669801675f1cfc3b0d74147f4901c3ffa42be2ddb1f0efc4/pydantic_core-2.33.2-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:c8e7af2f4e0194c22b5b37205bfb293d166a7344a5b0d0eaccebc376546d77d5", size = 2063196, upload-time = "2025-04-23T18:32:08.178Z" }, + { url = "https://files.pythonhosted.org/packages/26/bd/d9602777e77fc6dbb0c7db9ad356e9a985825547dce5ad1d30ee04903918/pydantic_core-2.33.2-cp313-cp313-musllinux_1_1_armv7l.whl", hash = "sha256:5c92edd15cd58b3c2d34873597a1e20f13094f59cf88068adb18947df5455b4e", size = 2236389, upload-time = "2025-04-23T18:32:10.242Z" }, + { url = "https://files.pythonhosted.org/packages/42/db/0e950daa7e2230423ab342ae918a794964b053bec24ba8af013fc7c94846/pydantic_core-2.33.2-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:65132b7b4a1c0beded5e057324b7e16e10910c106d43675d9bd87d4f38dde162", size = 2239223, upload-time = "2025-04-23T18:32:12.382Z" }, + { url = "https://files.pythonhosted.org/packages/58/4d/4f937099c545a8a17eb52cb67fe0447fd9a373b348ccfa9a87f141eeb00f/pydantic_core-2.33.2-cp313-cp313-win32.whl", hash = "sha256:52fb90784e0a242bb96ec53f42196a17278855b0f31ac7c3cc6f5c1ec4811849", size = 1900473, upload-time = "2025-04-23T18:32:14.034Z" }, + { url = "https://files.pythonhosted.org/packages/a0/75/4a0a9bac998d78d889def5e4ef2b065acba8cae8c93696906c3a91f310ca/pydantic_core-2.33.2-cp313-cp313-win_amd64.whl", hash = "sha256:c083a3bdd5a93dfe480f1125926afcdbf2917ae714bdb80b36d34318b2bec5d9", size = 1955269, upload-time = "2025-04-23T18:32:15.783Z" }, + { url = "https://files.pythonhosted.org/packages/f9/86/1beda0576969592f1497b4ce8e7bc8cbdf614c352426271b1b10d5f0aa64/pydantic_core-2.33.2-cp313-cp313-win_arm64.whl", hash = "sha256:e80b087132752f6b3d714f041ccf74403799d3b23a72722ea2e6ba2e892555b9", size = 1893921, upload-time = "2025-04-23T18:32:18.473Z" }, + { url = "https://files.pythonhosted.org/packages/a4/7d/e09391c2eebeab681df2b74bfe6c43422fffede8dc74187b2b0bf6fd7571/pydantic_core-2.33.2-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:61c18fba8e5e9db3ab908620af374db0ac1baa69f0f32df4f61ae23f15e586ac", size = 1806162, upload-time = "2025-04-23T18:32:20.188Z" }, + { url = "https://files.pythonhosted.org/packages/f1/3d/847b6b1fed9f8ed3bb95a9ad04fbd0b212e832d4f0f50ff4d9ee5a9f15cf/pydantic_core-2.33.2-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:95237e53bb015f67b63c91af7518a62a8660376a6a0db19b89acc77a4d6199f5", size = 1981560, upload-time = "2025-04-23T18:32:22.354Z" }, + { url = "https://files.pythonhosted.org/packages/6f/9a/e73262f6c6656262b5fdd723ad90f518f579b7bc8622e43a942eec53c938/pydantic_core-2.33.2-cp313-cp313t-win_amd64.whl", hash = "sha256:c2fc0a768ef76c15ab9238afa6da7f69895bb5d1ee83aeea2e3509af4472d0b9", size = 1935777, upload-time = "2025-04-23T18:32:25.088Z" }, ] [[package]] @@ -1795,14 +1782,14 @@ wheels = [ [[package]] name = "requests-file" -version = "2.1.0" +version = "3.0.1" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "requests" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/72/97/bf44e6c6bd8ddbb99943baf7ba8b1a8485bcd2fe0e55e5708d7fee4ff1ae/requests_file-2.1.0.tar.gz", hash = "sha256:0f549a3f3b0699415ac04d167e9cb39bccfb730cb832b4d20be3d9867356e658", size = 6891, upload-time = "2024-05-21T16:28:00.24Z" } +sdist = { url = "https://files.pythonhosted.org/packages/3c/f8/5dc70102e4d337063452c82e1f0d95e39abfe67aa222ed8a5ddeb9df8de8/requests_file-3.0.1.tar.gz", hash = "sha256:f14243d7796c588f3521bd423c5dea2ee4cc730e54a3cac9574d78aca1272576", size = 6967, upload-time = "2025-10-20T18:56:42.279Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/d7/25/dd878a121fcfdf38f52850f11c512e13ec87c2ea72385933818e5b6c15ce/requests_file-2.1.0-py2.py3-none-any.whl", hash = "sha256:cf270de5a4c5874e84599fc5778303d496c10ae5e870bfa378818f35d21bda5c", size = 4244, upload-time = "2024-05-21T16:27:57.733Z" }, + { url = "https://files.pythonhosted.org/packages/e1/d5/de8f089119205a09da657ed4784c584ede8381a0ce6821212a6d4ca47054/requests_file-3.0.1-py2.py3-none-any.whl", hash = "sha256:d0f5eb94353986d998f80ac63c7f146a307728be051d4d1cd390dbdb59c10fa2", size = 4514, upload-time = "2025-10-20T18:56:41.184Z" }, ] [[package]] @@ -1834,38 +1821,40 @@ wheels = [ [[package]] name = "rignore" -version = "0.7.0" +version = "0.7.1" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/ae/46/e5ef3423a3746f91d3a3d9a68c499fde983be7dbab7d874efa8d3bb139ba/rignore-0.7.0.tar.gz", hash = "sha256:cfe6a2cbec855b440d7550d53e670246fce43ca5847e46557b6d4577c9cdb540", size = 12796, upload-time = "2025-10-02T13:26:22.194Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/5e/85/cd1441043c5ed13e671153af260c5f328042ebfb87aa28849367602206f2/rignore-0.7.0-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:190e469db68112c4027a7a126facfd80ce353374ff208c585ca7dacc75de0472", size = 880474, upload-time = "2025-10-02T13:25:08.111Z" }, - { url = "https://files.pythonhosted.org/packages/f4/07/d5b9593cb05593718508308543a8fbee75998a7489cf4f4b489d2632bd4a/rignore-0.7.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:0a43f6fabf46ed8e96fbf2861187362e513960c2a8200c35242981bd36ef8b96", size = 811882, upload-time = "2025-10-02T13:24:56.599Z" }, - { url = "https://files.pythonhosted.org/packages/aa/67/b82b2704660c280061d8bc90bc91092622309f78e20c9e3321f45f88cd4e/rignore-0.7.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b89a59e5291805eca3c3317a55fcd2a579e9ee1184511660078a398182463deb", size = 892043, upload-time = "2025-10-02T13:23:22.326Z" }, - { url = "https://files.pythonhosted.org/packages/8b/7e/e91a1899a06882cd8a7acc3025c51b9f830971b193bd6b72e34254ed7733/rignore-0.7.0-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:3a155f36be847c05c800e0218e9ac04946ba44bf077e1f11dc024ca9e1f7a727", size = 865404, upload-time = "2025-10-02T13:23:40.085Z" }, - { url = "https://files.pythonhosted.org/packages/91/2c/68487538a2d2d7e0e1ca1051d143af690211314e22cbed58a245e816ebaf/rignore-0.7.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:dba075135ac3cda5f3236b4f03f82bbcd97454a908631ad3da93aae1e7390b17", size = 1167661, upload-time = "2025-10-02T13:23:57.578Z" }, - { url = "https://files.pythonhosted.org/packages/b4/39/8498ac13fb710a1920526480f9476aaeaaaa20c522a027d07513929ba9d9/rignore-0.7.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8525b8c31f36dc9fbcb474ef58d654f6404b19b6110b7f5df332e58e657a4aa8", size = 936272, upload-time = "2025-10-02T13:24:13.414Z" }, - { url = "https://files.pythonhosted.org/packages/55/1a/38b92fde209931611dcff0db59bd5656a325ba58d368d4e50f1e711fdd16/rignore-0.7.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e0428b64d8b02ad83fc0a2505ded0e9064cac97df7aa1dffc9c7558b56429912", size = 950552, upload-time = "2025-10-02T13:24:43.263Z" }, - { url = "https://files.pythonhosted.org/packages/e3/01/f59f38ae1b879309b0151b1ed0dd82880e1d3759f91bfdaa570730672308/rignore-0.7.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:0ab1db960a64835ec3ed541951821bfc38f30dfbd6ebd990f7d039d0c54ff957", size = 974407, upload-time = "2025-10-02T13:24:30.618Z" }, - { url = "https://files.pythonhosted.org/packages/6e/67/de92fdc09dc1a622abb6d1b2678e940d24de2a07c60d193126eb52a7e8ea/rignore-0.7.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:3749711b1e50fb5b28b55784e159a3b8209ecc72d01cc1511c05bc3a23b4a063", size = 1072865, upload-time = "2025-10-02T13:25:20.451Z" }, - { url = "https://files.pythonhosted.org/packages/65/bb/75fbef03cf56b0918880cb3b922da83d6546309566be60f6c6b451f7221b/rignore-0.7.0-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:57240739c786f897f89e29c05e529291ee1b477df9f6b29b774403a23a169fe2", size = 1129007, upload-time = "2025-10-02T13:25:36.837Z" }, - { url = "https://files.pythonhosted.org/packages/ec/24/4d591d45a8994fb4afaefa22e356d69948726c9ccba0cfd76c82509aedc2/rignore-0.7.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:6b70581286acd5f96ce11efd209bfe9261108586e1a948cc558fc3f58ba5bf5f", size = 1106827, upload-time = "2025-10-02T13:25:52.964Z" }, - { url = "https://files.pythonhosted.org/packages/c2/b3/b614d54fa1f1c7621aeb20b2841cd980288ad9d7d61407fc4595d5c5f132/rignore-0.7.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:33fb6e4cba1b798f1328e889b4bf2341894d82e3be42bb3513b4e0fe38788538", size = 1115328, upload-time = "2025-10-02T13:26:10.947Z" }, - { url = "https://files.pythonhosted.org/packages/83/22/ea0b3e30e230b2d2222e1ee18e20316c8297088f4cc6a6ea2ee6cb34f595/rignore-0.7.0-cp313-cp313-win32.whl", hash = "sha256:119f0497fb4776cddc663ee8f35085ce00758bd423221ba1e8222a816e10cf5e", size = 636896, upload-time = "2025-10-02T13:26:40.3Z" }, - { url = "https://files.pythonhosted.org/packages/79/16/f55b3db13f6fff408fde348d2a726d3b4ba06ed55dce8ff119e374ce3005/rignore-0.7.0-cp313-cp313-win_amd64.whl", hash = "sha256:fb06e11dda689be138909f53639f0baa8d7c6be4d76ca9ec316382ccf3517469", size = 716519, upload-time = "2025-10-02T13:26:28.51Z" }, - { url = "https://files.pythonhosted.org/packages/69/db/8c20a7b59abb21d3d20d387656b6759cd5890fa68185064fe8899f942a4b/rignore-0.7.0-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1f2255821ab4bc34fa129a94535f5d0d88b164940b25d0a3b26ebd41d99f1a9f", size = 890684, upload-time = "2025-10-02T13:23:23.761Z" }, - { url = "https://files.pythonhosted.org/packages/45/a0/ae5ca63aed23f64dcd740f55ee6432037af5c09d25efaf79dc052a4a51ff/rignore-0.7.0-cp313-cp313t-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:b57efcbbc1510f8ce831a5e19fb1fe9dd329bb246c4e4f8a09bf1c06687b0331", size = 865174, upload-time = "2025-10-02T13:23:41.948Z" }, - { url = "https://files.pythonhosted.org/packages/ae/27/5aff661e792efbffda689f0d3fa91ea36f2e0d4bcca3b02f70ae95ea96da/rignore-0.7.0-cp313-cp313t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1ead4bc2baceeccdfeb82cb70ba8f70fdb6dc1e58976f805f9d0d19b9ee915f0", size = 1165293, upload-time = "2025-10-02T13:23:59.238Z" }, - { url = "https://files.pythonhosted.org/packages/cb/df/13de7ce5ba2a58c724ef202310408729941c262179389df5e90cb9a41381/rignore-0.7.0-cp313-cp313t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:4f0a8996437a22df0faf2844d65ec91d41176b9d4e7357abee42baa39dc996ae", size = 936093, upload-time = "2025-10-02T13:24:15.057Z" }, - { url = "https://files.pythonhosted.org/packages/c3/63/4ea42bc454db8499906c8d075a7a0053b7fd381b85f3bcc857e68a8b8b23/rignore-0.7.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:cb17ef4a413444fccbd57e1b4a3870f1320951b81f1b7007af9c70e1a5bc2897", size = 1071518, upload-time = "2025-10-02T13:25:22.076Z" }, - { url = "https://files.pythonhosted.org/packages/a3/a7/7400a4343d1b5a1345a98846c6fd7768ff13890d207fce79d690c7fd7798/rignore-0.7.0-cp313-cp313t-musllinux_1_2_armv7l.whl", hash = "sha256:b12b316adf6cf64f9d22bd690b2aa019a37335a1f632a0da7fb15a423cb64080", size = 1128403, upload-time = "2025-10-02T13:25:38.394Z" }, - { url = "https://files.pythonhosted.org/packages/45/8b/ce8ff27336a86bad47bbf011f8f7fb0b82b559ee4a0d6a4815ee3555ef56/rignore-0.7.0-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:dba8181d999387c17dd6cce5fd7f0009376ca8623d2d86842d034b18d83dc768", size = 1105552, upload-time = "2025-10-02T13:25:54.511Z" }, - { url = "https://files.pythonhosted.org/packages/8c/e2/7925b564d853c7057f150a7f2f384400422ed30f7b7baf2fde5849562381/rignore-0.7.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:04a3d4513cdd184f4f849ae8d6407a169cca543a2c4dd69bfc42e67cb0155504", size = 1114826, upload-time = "2025-10-02T13:26:12.56Z" }, - { url = "https://files.pythonhosted.org/packages/c4/34/c42ccdd81143d38d99e45b965e4040a1ef6c07a365ad205dd94b6d16c794/rignore-0.7.0-cp314-cp314-macosx_10_12_x86_64.whl", hash = "sha256:a296bc26b713aacd0f31702e7d89426ba6240abdbf01b2b18daeeaeaa782f475", size = 879718, upload-time = "2025-10-02T13:25:09.62Z" }, - { url = "https://files.pythonhosted.org/packages/e9/ba/f522adf949d2b581a0a1e488a79577631ed6661fdc12e80d4182ed655036/rignore-0.7.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:f7f71807ed0bc1542860a8fa1615a0d93f3d5a22dde1066e9f50d7270bc60686", size = 810391, upload-time = "2025-10-02T13:24:58.144Z" }, - { url = "https://files.pythonhosted.org/packages/f2/82/935bffa4ad7d9560541daaca7ba0e4ee9b0b9a6370ab9518cf9c991087bb/rignore-0.7.0-cp314-cp314-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c7e6ff54399ddb650f4e4dc74b325766e7607967a49b868326e9687fc3642620", size = 950261, upload-time = "2025-10-02T13:24:45.121Z" }, - { url = "https://files.pythonhosted.org/packages/1e/0e/22abda23cc6d20901262fcfea50c25ed66ca6e1a5dc610d338df4ca10407/rignore-0.7.0-cp314-cp314-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:09dfad3ca450b3967533c6b1a2c7c0228c63c518f619ff342df5f9c3ed978b66", size = 974258, upload-time = "2025-10-02T13:24:32.44Z" }, - { url = "https://files.pythonhosted.org/packages/ed/8d/0ba2c712723fdda62125087d00dcdad93102876d4e3fa5adbb99f0b859c3/rignore-0.7.0-cp314-cp314-win32.whl", hash = "sha256:2850718cfb1caece6b7ac19a524c7905a8d0c6627b0d0f4e81798e20b6c75078", size = 637403, upload-time = "2025-10-02T13:26:41.814Z" }, - { url = "https://files.pythonhosted.org/packages/1c/63/0d7df1237c6353d1a85d8a0bc1797ac766c68e8bc6fbca241db74124eb61/rignore-0.7.0-cp314-cp314-win_amd64.whl", hash = "sha256:2401637dc8ab074f5e642295f8225d2572db395ae504ffc272a8d21e9fe77b2c", size = 717404, upload-time = "2025-10-02T13:26:29.936Z" }, +sdist = { url = "https://files.pythonhosted.org/packages/01/1a/4e407524cf97ed42a9c77d3cc31b12dd5fb2ce542f174ff7cf78ea0ca293/rignore-0.7.1.tar.gz", hash = "sha256:67bb99d57d0bab0c473261561f98f118f7c9838a06de222338ed8f2b95ed84b4", size = 15437, upload-time = "2025-10-15T20:59:08.474Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/c2/f8/99145d7ee439db898709b9a7e913d42ed3a6ff679c50a163bae373f07276/rignore-0.7.1-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:cb6c993b22d7c88eeadc4fed2957be688b6c5f98d4a9b86d3a5057f4a17ea5bd", size = 881743, upload-time = "2025-10-15T20:58:09.804Z" }, + { url = "https://files.pythonhosted.org/packages/fa/db/aea84354518a24578c77d8fec2f42c065520b48ba5bded9d8eca9e46fefd/rignore-0.7.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:32da28b0e0434b88134f8d97f22afe6bd1e2a103278a726809e2d8da8426b33f", size = 814397, upload-time = "2025-10-15T20:58:00.071Z" }, + { url = "https://files.pythonhosted.org/packages/12/0b/116afdee4093f0ccd3c4e7b6840d3699ea2a34c1ae6d1dd4d7d9d0adc65b/rignore-0.7.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:401d52a0a1c5eae342b2c7b4091206e1ce70de54e85c8c8f0ea3309765a62d60", size = 893431, upload-time = "2025-10-15T20:56:45.476Z" }, + { url = "https://files.pythonhosted.org/packages/52/b5/66778c7cbb8e2c6f4ca6f2f59067aa01632b913741c4aa46b163dc4c8f8c/rignore-0.7.1-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:9ffcfbef75656243cfdcdd495b0ea0b71980b76af343b1bf3aed61a78db3f145", size = 867220, upload-time = "2025-10-15T20:56:58.931Z" }, + { url = "https://files.pythonhosted.org/packages/6e/da/bdd6de52941391f0056295c6904c45e1f8667df754b17fe880d0a663d941/rignore-0.7.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:0e89efa2ad36a9206ed30219eb1a8783a0722ae8b6d68390ae854e5f5ceab6ff", size = 1169076, upload-time = "2025-10-15T20:57:12.153Z" }, + { url = "https://files.pythonhosted.org/packages/0e/8d/d7d4bfbae28e340a6afe850809a020a31c2364fc0ee8105be4ec0841b20a/rignore-0.7.1-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2f6191d7f52894ee65a879f022329011e31cc41f98739ff184cd3f256a3f0711", size = 937738, upload-time = "2025-10-15T20:57:25.497Z" }, + { url = "https://files.pythonhosted.org/packages/d8/b1/1d3f88aaf3cc6f4e31d1d72eb261eff3418dabd2677c83653b7574e7947a/rignore-0.7.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:873a8e84b4342534b9e283f7c17dc39c295edcdc686dfa395ddca3628316931b", size = 951791, upload-time = "2025-10-15T20:57:49.574Z" }, + { url = "https://files.pythonhosted.org/packages/90/7f/033631f29af972bc4f69e241ab188d21fbc4665ad67879c77bc984009550/rignore-0.7.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:65443a6a5efd184d21538816282c78c4787a8a5f73c243ab87cbbb6f313a623d", size = 977580, upload-time = "2025-10-15T20:57:39.063Z" }, + { url = "https://files.pythonhosted.org/packages/c7/38/6f963926b769365a803ec17d448a4fc9c2dbad9c1a1bf73c28088021c2fc/rignore-0.7.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:d6cafca0b422c0d57ce617fed3831e6639dc151653b98396af919f8eb3ba9e2b", size = 1074486, upload-time = "2025-10-15T20:58:18.505Z" }, + { url = "https://files.pythonhosted.org/packages/74/d2/a1c1e2cd3e43f6433d3ecb8d947e1ed684c261fa2e7b2f6b8827c3bf18d1/rignore-0.7.1-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:1f731b018b5b5a93d7b4a0f4e43e5fcbd6cf25e97cec265392f9dd8d10916e5c", size = 1131024, upload-time = "2025-10-15T20:58:32.075Z" }, + { url = "https://files.pythonhosted.org/packages/93/22/b7dd8312aa98211df1f10a6cd2a3005e72cd4ac5c125fd064c7e58394205/rignore-0.7.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:b3be78b1ab9fa1c0eac822a69a7799a2261ce06e4d548374093c4c64d796d7d8", size = 1109625, upload-time = "2025-10-15T20:58:46.077Z" }, + { url = "https://files.pythonhosted.org/packages/f7/65/dd31859304bd71ad72f71e2bf5f18e6f0043cc75394ead8c0d752ab580ad/rignore-0.7.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:d8c3b77ae1a24b09a6d38e07d180f362e47b970c767d2e22417b03d95685cb9d", size = 1117466, upload-time = "2025-10-15T20:58:59.102Z" }, + { url = "https://files.pythonhosted.org/packages/5f/d7/e83241e1b0a6caef1e37586d5b2edb0227478d038675e4e6e1cd748c08ce/rignore-0.7.1-cp313-cp313-win32.whl", hash = "sha256:c01cc8c5d7099d35a7fd00e174948986d4f2cfb6b7fe2923b0b801b1a4741b37", size = 635266, upload-time = "2025-10-15T20:59:28.782Z" }, + { url = "https://files.pythonhosted.org/packages/95/e5/c2ce66a71cfc44010a238a61339cae7469adc17306025796884672784b4c/rignore-0.7.1-cp313-cp313-win_amd64.whl", hash = "sha256:5dd0de4a7d38a49b9d85f332d129b4ca4a29eef5667d4c7bf503e767cf9e2ec4", size = 718048, upload-time = "2025-10-15T20:59:19.312Z" }, + { url = "https://files.pythonhosted.org/packages/ba/fb/b92aa591e247f6258997163e8b1844c9b799371fbfdfd29533e203df06b9/rignore-0.7.1-cp313-cp313-win_arm64.whl", hash = "sha256:4a4c57b75ec758fb31ad1abab4c77810ea417e9d33bdf2f38cf9e6db556eebcb", size = 647790, upload-time = "2025-10-15T20:59:12.408Z" }, + { url = "https://files.pythonhosted.org/packages/b6/d3/b6c5764d3dcaf47de7f0e408dcb4a1a17d4ce3bb1b0aa9a346e221e3c5a1/rignore-0.7.1-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:abb7df83a41213069195436e9c1a433a6df85c089ce4be406d070a4db0ee3897", size = 892938, upload-time = "2025-10-15T20:56:46.559Z" }, + { url = "https://files.pythonhosted.org/packages/48/6a/4d8ae9af9936a061dacda0d8f638cd63571ff93e4eb28e0159db6c4dc009/rignore-0.7.1-cp313-cp313t-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:30d9c9a93a266d1f384465d626178f49d0da4d1a0cf739f15151cdf2eb500e53", size = 867312, upload-time = "2025-10-15T20:57:00.083Z" }, + { url = "https://files.pythonhosted.org/packages/9b/88/cb243662a0b523b4350db1c7c3adee87004af90e9b26100e84c7e13b93cc/rignore-0.7.1-cp313-cp313t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:7e83c68f557d793b4cc7aac943f3b23631469e1bc5b02e63626d0b008be01cd1", size = 1166871, upload-time = "2025-10-15T20:57:13.618Z" }, + { url = "https://files.pythonhosted.org/packages/f6/0a/da28a3f3e8ab1829180f3a7af5b601b04bab1d833e31a74fee78a2d3f5c3/rignore-0.7.1-cp313-cp313t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:682a6efe3f84af4b1100d4c68f0a345f490af74fd9d18346ebf67da9a3b96b08", size = 937964, upload-time = "2025-10-15T20:57:27.054Z" }, + { url = "https://files.pythonhosted.org/packages/c6/2e/f55d0759c6cf48d8fabc62d8924ce58dca81f5c370c0abdcc7cc8176210d/rignore-0.7.1-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:736b6aa3e3dfda2b1404b6f9a9d6f67e2a89f184179e9e5b629198df7c22f9c6", size = 1073720, upload-time = "2025-10-15T20:58:20.833Z" }, + { url = "https://files.pythonhosted.org/packages/c3/aa/8698caf5eb1824f8cae08cd3a296bc7f6f46e7bb539a4dd60c6a7a9f5ca2/rignore-0.7.1-cp313-cp313t-musllinux_1_2_armv7l.whl", hash = "sha256:eed55292d949e99f29cd4f1ae6ddc2562428a3e74f6f4f6b8658f1d5113ffbd5", size = 1130545, upload-time = "2025-10-15T20:58:33.709Z" }, + { url = "https://files.pythonhosted.org/packages/f5/88/89abacdc122f4a0d069d12ebbd87693253f08f19457b77f030c0c6cba316/rignore-0.7.1-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:93ce054754857e37f15fe6768fd28e5450a52c7bbdb00e215100b092281ed123", size = 1108570, upload-time = "2025-10-15T20:58:47.438Z" }, + { url = "https://files.pythonhosted.org/packages/c9/4b/a815624ff1f2420ff29be1ffa2ea5204a69d9a9738fe5a6638fcd1069347/rignore-0.7.1-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:447004c774083e4f9cddf0aefcb80b12264f23e28c37918fb709917c2aabd00d", size = 1116940, upload-time = "2025-10-15T20:59:00.581Z" }, + { url = "https://files.pythonhosted.org/packages/43/63/3464fe5855fc37689d7bdd7b4b7ea0d008a8a58738bc0d68b0b5fa6dcf28/rignore-0.7.1-cp314-cp314-macosx_10_12_x86_64.whl", hash = "sha256:322ac35f2431dd2e80518200e31af1985689dfa7658003ae40012bf3d3e9f0dd", size = 880536, upload-time = "2025-10-15T20:58:11.286Z" }, + { url = "https://files.pythonhosted.org/packages/63/c3/c37469643baeb04c58db2713dc268f582974c71f3936f7d989610b344fca/rignore-0.7.1-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:2d38e282e4b917fb6108198564b018f90de57bb6209aadf9ff39434d4709a650", size = 814741, upload-time = "2025-10-15T20:58:01.228Z" }, + { url = "https://files.pythonhosted.org/packages/76/6c/57fa917c7515db3b72a9c3a6377dc806282e6db390ace68cda29bd73774e/rignore-0.7.1-cp314-cp314-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:89ad7373ec1e7b519a6f07dbcfca38024ba45f5e44df79ee0da4e4c817648a50", size = 951257, upload-time = "2025-10-15T20:57:50.779Z" }, + { url = "https://files.pythonhosted.org/packages/b6/58/b64fb42d6a73937a93c5f060e2720decde4d2b4a7a27fc3b69e69c397358/rignore-0.7.1-cp314-cp314-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:ff94b215b4fe1d81e45b29dc259145fd8aaf40e7b1057f020890cd12db566e4e", size = 977468, upload-time = "2025-10-15T20:57:40.291Z" }, + { url = "https://files.pythonhosted.org/packages/22/54/5b9e60ad6ea7ef654d2607936be312ce78615e011b3461d4b1d161f031c0/rignore-0.7.1-cp314-cp314-win32.whl", hash = "sha256:f49ecef68b5cb99d1212ebe332cbb2851fb2c93672d3b1d372b0fbf475eeb172", size = 635618, upload-time = "2025-10-15T20:59:29.95Z" }, + { url = "https://files.pythonhosted.org/packages/62/50/67137617cbe3e53cbf34d21dad49e153f731797e07261f3b00572a49e69d/rignore-0.7.1-cp314-cp314-win_amd64.whl", hash = "sha256:3f55593d3bbcae3c108d546e8776e51ecb61d1d79bbb02016acf29d136813835", size = 717951, upload-time = "2025-10-15T20:59:20.519Z" }, + { url = "https://files.pythonhosted.org/packages/77/19/dd556e97354ad541b4f7f113e28503865777d6edd940c147f052dc7b8f04/rignore-0.7.1-cp314-cp314-win_arm64.whl", hash = "sha256:60745773b5278fa5f20232fbfb148d74ad9fb27ae8a5097d3cbd5d7cc922d7f7", size = 647796, upload-time = "2025-10-15T20:59:13.724Z" }, ] [[package]] @@ -1882,28 +1871,28 @@ wheels = [ [[package]] name = "ruff" -version = "0.14.0" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/41/b9/9bd84453ed6dd04688de9b3f3a4146a1698e8faae2ceeccce4e14c67ae17/ruff-0.14.0.tar.gz", hash = "sha256:62ec8969b7510f77945df916de15da55311fade8d6050995ff7f680afe582c57", size = 5452071, upload-time = "2025-10-07T18:21:55.763Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/3a/4e/79d463a5f80654e93fa653ebfb98e0becc3f0e7cf6219c9ddedf1e197072/ruff-0.14.0-py3-none-linux_armv6l.whl", hash = "sha256:58e15bffa7054299becf4bab8a1187062c6f8cafbe9f6e39e0d5aface455d6b3", size = 12494532, upload-time = "2025-10-07T18:21:00.373Z" }, - { url = "https://files.pythonhosted.org/packages/ee/40/e2392f445ed8e02aa6105d49db4bfff01957379064c30f4811c3bf38aece/ruff-0.14.0-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:838d1b065f4df676b7c9957992f2304e41ead7a50a568185efd404297d5701e8", size = 13160768, upload-time = "2025-10-07T18:21:04.73Z" }, - { url = "https://files.pythonhosted.org/packages/75/da/2a656ea7c6b9bd14c7209918268dd40e1e6cea65f4bb9880eaaa43b055cd/ruff-0.14.0-py3-none-macosx_11_0_arm64.whl", hash = "sha256:703799d059ba50f745605b04638fa7e9682cc3da084b2092feee63500ff3d9b8", size = 12363376, upload-time = "2025-10-07T18:21:07.833Z" }, - { url = "https://files.pythonhosted.org/packages/42/e2/1ffef5a1875add82416ff388fcb7ea8b22a53be67a638487937aea81af27/ruff-0.14.0-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3ba9a8925e90f861502f7d974cc60e18ca29c72bb0ee8bfeabb6ade35a3abde7", size = 12608055, upload-time = "2025-10-07T18:21:10.72Z" }, - { url = "https://files.pythonhosted.org/packages/4a/32/986725199d7cee510d9f1dfdf95bf1efc5fa9dd714d0d85c1fb1f6be3bc3/ruff-0.14.0-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:e41f785498bd200ffc276eb9e1570c019c1d907b07cfb081092c8ad51975bbe7", size = 12318544, upload-time = "2025-10-07T18:21:13.741Z" }, - { url = "https://files.pythonhosted.org/packages/9a/ed/4969cefd53315164c94eaf4da7cfba1f267dc275b0abdd593d11c90829a3/ruff-0.14.0-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:30a58c087aef4584c193aebf2700f0fbcfc1e77b89c7385e3139956fa90434e2", size = 14001280, upload-time = "2025-10-07T18:21:16.411Z" }, - { url = "https://files.pythonhosted.org/packages/ab/ad/96c1fc9f8854c37681c9613d825925c7f24ca1acfc62a4eb3896b50bacd2/ruff-0.14.0-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:f8d07350bc7af0a5ce8812b7d5c1a7293cf02476752f23fdfc500d24b79b783c", size = 15027286, upload-time = "2025-10-07T18:21:19.577Z" }, - { url = "https://files.pythonhosted.org/packages/b3/00/1426978f97df4fe331074baf69615f579dc4e7c37bb4c6f57c2aad80c87f/ruff-0.14.0-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:eec3bbbf3a7d5482b5c1f42d5fc972774d71d107d447919fca620b0be3e3b75e", size = 14451506, upload-time = "2025-10-07T18:21:22.779Z" }, - { url = "https://files.pythonhosted.org/packages/58/d5/9c1cea6e493c0cf0647674cca26b579ea9d2a213b74b5c195fbeb9678e15/ruff-0.14.0-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:16b68e183a0e28e5c176d51004aaa40559e8f90065a10a559176713fcf435206", size = 13437384, upload-time = "2025-10-07T18:21:25.758Z" }, - { url = "https://files.pythonhosted.org/packages/29/b4/4cd6a4331e999fc05d9d77729c95503f99eae3ba1160469f2b64866964e3/ruff-0.14.0-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:eb732d17db2e945cfcbbc52af0143eda1da36ca8ae25083dd4f66f1542fdf82e", size = 13447976, upload-time = "2025-10-07T18:21:28.83Z" }, - { url = "https://files.pythonhosted.org/packages/3b/c0/ac42f546d07e4f49f62332576cb845d45c67cf5610d1851254e341d563b6/ruff-0.14.0-py3-none-manylinux_2_31_riscv64.whl", hash = "sha256:c958f66ab884b7873e72df38dcabee03d556a8f2ee1b8538ee1c2bbd619883dd", size = 13682850, upload-time = "2025-10-07T18:21:31.842Z" }, - { url = "https://files.pythonhosted.org/packages/5f/c4/4b0c9bcadd45b4c29fe1af9c5d1dc0ca87b4021665dfbe1c4688d407aa20/ruff-0.14.0-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:7eb0499a2e01f6e0c285afc5bac43ab380cbfc17cd43a2e1dd10ec97d6f2c42d", size = 12449825, upload-time = "2025-10-07T18:21:35.074Z" }, - { url = "https://files.pythonhosted.org/packages/4b/a8/e2e76288e6c16540fa820d148d83e55f15e994d852485f221b9524514730/ruff-0.14.0-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:4c63b2d99fafa05efca0ab198fd48fa6030d57e4423df3f18e03aa62518c565f", size = 12272599, upload-time = "2025-10-07T18:21:38.08Z" }, - { url = "https://files.pythonhosted.org/packages/18/14/e2815d8eff847391af632b22422b8207704222ff575dec8d044f9ab779b2/ruff-0.14.0-py3-none-musllinux_1_2_i686.whl", hash = "sha256:668fce701b7a222f3f5327f86909db2bbe99c30877c8001ff934c5413812ac02", size = 13193828, upload-time = "2025-10-07T18:21:41.216Z" }, - { url = "https://files.pythonhosted.org/packages/44/c6/61ccc2987cf0aecc588ff8f3212dea64840770e60d78f5606cd7dc34de32/ruff-0.14.0-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:a86bf575e05cb68dcb34e4c7dfe1064d44d3f0c04bbc0491949092192b515296", size = 13628617, upload-time = "2025-10-07T18:21:44.04Z" }, - { url = "https://files.pythonhosted.org/packages/73/e6/03b882225a1b0627e75339b420883dc3c90707a8917d2284abef7a58d317/ruff-0.14.0-py3-none-win32.whl", hash = "sha256:7450a243d7125d1c032cb4b93d9625dea46c8c42b4f06c6b709baac168e10543", size = 12367872, upload-time = "2025-10-07T18:21:46.67Z" }, - { url = "https://files.pythonhosted.org/packages/41/77/56cf9cf01ea0bfcc662de72540812e5ba8e9563f33ef3d37ab2174892c47/ruff-0.14.0-py3-none-win_amd64.whl", hash = "sha256:ea95da28cd874c4d9c922b39381cbd69cb7e7b49c21b8152b014bd4f52acddc2", size = 13464628, upload-time = "2025-10-07T18:21:50.318Z" }, - { url = "https://files.pythonhosted.org/packages/c6/2a/65880dfd0e13f7f13a775998f34703674a4554906167dce02daf7865b954/ruff-0.14.0-py3-none-win_arm64.whl", hash = "sha256:f42c9495f5c13ff841b1da4cb3c2a42075409592825dada7c5885c2c844ac730", size = 12565142, upload-time = "2025-10-07T18:21:53.577Z" }, +version = "0.14.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/9e/58/6ca66896635352812de66f71cdf9ff86b3a4f79071ca5730088c0cd0fc8d/ruff-0.14.1.tar.gz", hash = "sha256:1dd86253060c4772867c61791588627320abcb6ed1577a90ef432ee319729b69", size = 5513429, upload-time = "2025-10-16T18:05:41.766Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/8d/39/9cc5ab181478d7a18adc1c1e051a84ee02bec94eb9bdfd35643d7c74ca31/ruff-0.14.1-py3-none-linux_armv6l.whl", hash = "sha256:083bfc1f30f4a391ae09c6f4f99d83074416b471775b59288956f5bc18e82f8b", size = 12445415, upload-time = "2025-10-16T18:04:48.227Z" }, + { url = "https://files.pythonhosted.org/packages/ef/2e/1226961855ccd697255988f5a2474890ac7c5863b080b15bd038df820818/ruff-0.14.1-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:f6fa757cd717f791009f7669fefb09121cc5f7d9bd0ef211371fad68c2b8b224", size = 12784267, upload-time = "2025-10-16T18:04:52.515Z" }, + { url = "https://files.pythonhosted.org/packages/c1/ea/fd9e95863124ed159cd0667ec98449ae461de94acda7101f1acb6066da00/ruff-0.14.1-py3-none-macosx_11_0_arm64.whl", hash = "sha256:d6191903d39ac156921398e9c86b7354d15e3c93772e7dbf26c9fcae59ceccd5", size = 11781872, upload-time = "2025-10-16T18:04:55.396Z" }, + { url = "https://files.pythonhosted.org/packages/1e/5a/e890f7338ff537dba4589a5e02c51baa63020acfb7c8cbbaea4831562c96/ruff-0.14.1-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ed04f0e04f7a4587244e5c9d7df50e6b5bf2705d75059f409a6421c593a35896", size = 12226558, upload-time = "2025-10-16T18:04:58.166Z" }, + { url = "https://files.pythonhosted.org/packages/a6/7a/8ab5c3377f5bf31e167b73651841217542bcc7aa1c19e83030835cc25204/ruff-0.14.1-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:5c9e6cf6cd4acae0febbce29497accd3632fe2025c0c583c8b87e8dbdeae5f61", size = 12187898, upload-time = "2025-10-16T18:05:01.455Z" }, + { url = "https://files.pythonhosted.org/packages/48/8d/ba7c33aa55406955fc124e62c8259791c3d42e3075a71710fdff9375134f/ruff-0.14.1-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a6fa2458527794ecdfbe45f654e42c61f2503a230545a91af839653a0a93dbc6", size = 12939168, upload-time = "2025-10-16T18:05:04.397Z" }, + { url = "https://files.pythonhosted.org/packages/b4/c2/70783f612b50f66d083380e68cbd1696739d88e9b4f6164230375532c637/ruff-0.14.1-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:39f1c392244e338b21d42ab29b8a6392a722c5090032eb49bb4d6defcdb34345", size = 14386942, upload-time = "2025-10-16T18:05:07.102Z" }, + { url = "https://files.pythonhosted.org/packages/48/44/cd7abb9c776b66d332119d67f96acf15830d120f5b884598a36d9d3f4d83/ruff-0.14.1-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:7382fa12a26cce1f95070ce450946bec357727aaa428983036362579eadcc5cf", size = 13990622, upload-time = "2025-10-16T18:05:09.882Z" }, + { url = "https://files.pythonhosted.org/packages/eb/56/4259b696db12ac152fe472764b4f78bbdd9b477afd9bc3a6d53c01300b37/ruff-0.14.1-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:dd0bf2be3ae8521e1093a487c4aa3b455882f139787770698530d28ed3fbb37c", size = 13431143, upload-time = "2025-10-16T18:05:13.46Z" }, + { url = "https://files.pythonhosted.org/packages/e0/35/266a80d0eb97bd224b3265b9437bd89dde0dcf4faf299db1212e81824e7e/ruff-0.14.1-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cabcaa9ccf8089fb4fdb78d17cc0e28241520f50f4c2e88cb6261ed083d85151", size = 13132844, upload-time = "2025-10-16T18:05:16.1Z" }, + { url = "https://files.pythonhosted.org/packages/65/6e/d31ce218acc11a8d91ef208e002a31acf315061a85132f94f3df7a252b18/ruff-0.14.1-py3-none-manylinux_2_31_riscv64.whl", hash = "sha256:747d583400f6125ec11a4c14d1c8474bf75d8b419ad22a111a537ec1a952d192", size = 13401241, upload-time = "2025-10-16T18:05:19.395Z" }, + { url = "https://files.pythonhosted.org/packages/9f/b5/dbc4221bf0b03774b3b2f0d47f39e848d30664157c15b965a14d890637d2/ruff-0.14.1-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:5a6e74c0efd78515a1d13acbfe6c90f0f5bd822aa56b4a6d43a9ffb2ae6e56cd", size = 12132476, upload-time = "2025-10-16T18:05:22.163Z" }, + { url = "https://files.pythonhosted.org/packages/98/4b/ac99194e790ccd092d6a8b5f341f34b6e597d698e3077c032c502d75ea84/ruff-0.14.1-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:0ea6a864d2fb41a4b6d5b456ed164302a0d96f4daac630aeba829abfb059d020", size = 12139749, upload-time = "2025-10-16T18:05:25.162Z" }, + { url = "https://files.pythonhosted.org/packages/47/26/7df917462c3bb5004e6fdfcc505a49e90bcd8a34c54a051953118c00b53a/ruff-0.14.1-py3-none-musllinux_1_2_i686.whl", hash = "sha256:0826b8764f94229604fa255918d1cc45e583e38c21c203248b0bfc9a0e930be5", size = 12544758, upload-time = "2025-10-16T18:05:28.018Z" }, + { url = "https://files.pythonhosted.org/packages/64/d0/81e7f0648e9764ad9b51dd4be5e5dac3fcfff9602428ccbae288a39c2c22/ruff-0.14.1-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:cbc52160465913a1a3f424c81c62ac8096b6a491468e7d872cb9444a860bc33d", size = 13221811, upload-time = "2025-10-16T18:05:30.707Z" }, + { url = "https://files.pythonhosted.org/packages/c3/07/3c45562c67933cc35f6d5df4ca77dabbcd88fddaca0d6b8371693d29fd56/ruff-0.14.1-py3-none-win32.whl", hash = "sha256:e037ea374aaaff4103240ae79168c0945ae3d5ae8db190603de3b4012bd1def6", size = 12319467, upload-time = "2025-10-16T18:05:33.261Z" }, + { url = "https://files.pythonhosted.org/packages/02/88/0ee4ca507d4aa05f67e292d2e5eb0b3e358fbcfe527554a2eda9ac422d6b/ruff-0.14.1-py3-none-win_amd64.whl", hash = "sha256:59d599cdff9c7f925a017f6f2c256c908b094e55967f93f2821b1439928746a1", size = 13401123, upload-time = "2025-10-16T18:05:35.984Z" }, + { url = "https://files.pythonhosted.org/packages/b8/81/4b6387be7014858d924b843530e1b2a8e531846807516e9bea2ee0936bf7/ruff-0.14.1-py3-none-win_arm64.whl", hash = "sha256:e3b443c4c9f16ae850906b8d0a707b2a4c16f8d2f0a7fe65c475c5886665ce44", size = 12436636, upload-time = "2025-10-16T18:05:38.995Z" }, ] [[package]] @@ -1920,15 +1909,15 @@ wheels = [ [[package]] name = "sentry-sdk" -version = "2.41.0" +version = "2.42.1" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "certifi" }, { name = "urllib3" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/68/47/aea50a61d85bc07a34e6e7145aad7bd96c5671a86a32618059bad0cbc73b/sentry_sdk-2.41.0.tar.gz", hash = "sha256:e7af3f4d7f8bac4c56fbaf95adb0d111f061cce58d5df91cfcd4e69782759b10", size = 343942, upload-time = "2025-10-09T14:12:21.132Z" } +sdist = { url = "https://files.pythonhosted.org/packages/31/04/ec8c1dd9250847303d98516e917978cb1c7083024770d86d657d2ccb5a70/sentry_sdk-2.42.1.tar.gz", hash = "sha256:8598cc6edcfe74cb8074ba6a7c15338cdee93d63d3eb9b9943b4b568354ad5b6", size = 354839, upload-time = "2025-10-20T12:38:40.45Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/71/58/175d0e4d93f62075a01f8aebe904b412c34a94a4517e5045d0a1d512aad0/sentry_sdk-2.41.0-py2.py3-none-any.whl", hash = "sha256:343cde6540574113d13d178d1b2093e011ac21dd55abd3a1ec7e540f0d18a5bd", size = 370606, upload-time = "2025-10-09T14:12:19.003Z" }, + { url = "https://files.pythonhosted.org/packages/0f/cb/c21b96ff379923310b4fb2c06e8d560d801e24aeb300faa72a04776868fc/sentry_sdk-2.42.1-py2.py3-none-any.whl", hash = "sha256:f8716b50c927d3beb41bc88439dc6bcd872237b596df5b14613e2ade104aee02", size = 380952, upload-time = "2025-10-20T12:38:38.88Z" }, ] [[package]] @@ -2051,7 +2040,7 @@ wheels = [ [[package]] name = "typer" -version = "0.19.2" +version = "0.20.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "click" }, @@ -2059,9 +2048,9 @@ dependencies = [ { name = "shellingham" }, { name = "typing-extensions" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/21/ca/950278884e2ca20547ff3eb109478c6baf6b8cf219318e6bc4f666fad8e8/typer-0.19.2.tar.gz", hash = "sha256:9ad824308ded0ad06cc716434705f691d4ee0bfd0fb081839d2e426860e7fdca", size = 104755, upload-time = "2025-09-23T09:47:48.256Z" } +sdist = { url = "https://files.pythonhosted.org/packages/8f/28/7c85c8032b91dbe79725b6f17d2fffc595dff06a35c7a30a37bef73a1ab4/typer-0.20.0.tar.gz", hash = "sha256:1aaf6494031793e4876fb0bacfa6a912b551cf43c1e63c800df8b1a866720c37", size = 106492, upload-time = "2025-10-20T17:03:49.445Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/00/22/35617eee79080a5d071d0f14ad698d325ee6b3bf824fc0467c03b30e7fa8/typer-0.19.2-py3-none-any.whl", hash = "sha256:755e7e19670ffad8283db353267cb81ef252f595aa6834a0d1ca9312d9326cb9", size = 46748, upload-time = "2025-09-23T09:47:46.777Z" }, + { url = "https://files.pythonhosted.org/packages/78/64/7713ffe4b5983314e9d436a90d5bd4f63b6054e2aca783a3cfc44cb95bbf/typer-0.20.0-py3-none-any.whl", hash = "sha256:5b463df6793ec1dca6213a3cf4c0f03bc6e322ac5e16e13ddd622a889489784a", size = 47028, upload-time = "2025-10-20T17:03:47.617Z" }, ] [[package]] @@ -2114,15 +2103,15 @@ wheels = [ [[package]] name = "uvicorn" -version = "0.37.0" +version = "0.38.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "click" }, { name = "h11" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/71/57/1616c8274c3442d802621abf5deb230771c7a0fec9414cb6763900eb3868/uvicorn-0.37.0.tar.gz", hash = "sha256:4115c8add6d3fd536c8ee77f0e14a7fd2ebba939fed9b02583a97f80648f9e13", size = 80367, upload-time = "2025-09-23T13:33:47.486Z" } +sdist = { url = "https://files.pythonhosted.org/packages/cb/ce/f06b84e2697fef4688ca63bdb2fdf113ca0a3be33f94488f2cadb690b0cf/uvicorn-0.38.0.tar.gz", hash = "sha256:fd97093bdd120a2609fc0d3afe931d4d4ad688b6e75f0f929fde1bc36fe0e91d", size = 80605, upload-time = "2025-10-18T13:46:44.63Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/85/cd/584a2ceb5532af99dd09e50919e3615ba99aa127e9850eafe5f31ddfdb9a/uvicorn-0.37.0-py3-none-any.whl", hash = "sha256:913b2b88672343739927ce381ff9e2ad62541f9f8289664fa1d1d3803fa2ce6c", size = 67976, upload-time = "2025-09-23T13:33:45.842Z" }, + { url = "https://files.pythonhosted.org/packages/ee/d9/d88e73ca598f4f6ff671fb5fde8a32925c2e08a637303a1d12883c7305fa/uvicorn-0.38.0-py3-none-any.whl", hash = "sha256:48c0afd214ceb59340075b4a052ea1ee91c16fbc2a9b1469cca0e54566977b02", size = 68109, upload-time = "2025-10-18T13:46:42.958Z" }, ] [package.optional-dependencies] @@ -2138,16 +2127,28 @@ standard = [ [[package]] name = "uvloop" -version = "0.21.0" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/af/c0/854216d09d33c543f12a44b393c402e89a920b1a0a7dc634c42de91b9cf6/uvloop-0.21.0.tar.gz", hash = "sha256:3bf12b0fda68447806a7ad847bfa591613177275d35b6724b1ee573faa3704e3", size = 2492741, upload-time = "2024-10-14T23:38:35.489Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/3f/8d/2cbef610ca21539f0f36e2b34da49302029e7c9f09acef0b1c3b5839412b/uvloop-0.21.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:bfd55dfcc2a512316e65f16e503e9e450cab148ef11df4e4e679b5e8253a5281", size = 1468123, upload-time = "2024-10-14T23:38:00.688Z" }, - { url = "https://files.pythonhosted.org/packages/93/0d/b0038d5a469f94ed8f2b2fce2434a18396d8fbfb5da85a0a9781ebbdec14/uvloop-0.21.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:787ae31ad8a2856fc4e7c095341cccc7209bd657d0e71ad0dc2ea83c4a6fa8af", size = 819325, upload-time = "2024-10-14T23:38:02.309Z" }, - { url = "https://files.pythonhosted.org/packages/50/94/0a687f39e78c4c1e02e3272c6b2ccdb4e0085fda3b8352fecd0410ccf915/uvloop-0.21.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5ee4d4ef48036ff6e5cfffb09dd192c7a5027153948d85b8da7ff705065bacc6", size = 4582806, upload-time = "2024-10-14T23:38:04.711Z" }, - { url = "https://files.pythonhosted.org/packages/d2/19/f5b78616566ea68edd42aacaf645adbf71fbd83fc52281fba555dc27e3f1/uvloop-0.21.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f3df876acd7ec037a3d005b3ab85a7e4110422e4d9c1571d4fc89b0fc41b6816", size = 4701068, upload-time = "2024-10-14T23:38:06.385Z" }, - { url = "https://files.pythonhosted.org/packages/47/57/66f061ee118f413cd22a656de622925097170b9380b30091b78ea0c6ea75/uvloop-0.21.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:bd53ecc9a0f3d87ab847503c2e1552b690362e005ab54e8a48ba97da3924c0dc", size = 4454428, upload-time = "2024-10-14T23:38:08.416Z" }, - { url = "https://files.pythonhosted.org/packages/63/9a/0962b05b308494e3202d3f794a6e85abe471fe3cafdbcf95c2e8c713aabd/uvloop-0.21.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:a5c39f217ab3c663dc699c04cbd50c13813e31d917642d459fdcec07555cc553", size = 4660018, upload-time = "2024-10-14T23:38:10.888Z" }, +version = "0.22.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/06/f0/18d39dbd1971d6d62c4629cc7fa67f74821b0dc1f5a77af43719de7936a7/uvloop-0.22.1.tar.gz", hash = "sha256:6c84bae345b9147082b17371e3dd5d42775bddce91f885499017f4607fdaf39f", size = 2443250, upload-time = "2025-10-16T22:17:19.342Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/89/8c/182a2a593195bfd39842ea68ebc084e20c850806117213f5a299dfc513d9/uvloop-0.22.1-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:561577354eb94200d75aca23fbde86ee11be36b00e52a4eaf8f50fb0c86b7705", size = 1358611, upload-time = "2025-10-16T22:16:36.833Z" }, + { url = "https://files.pythonhosted.org/packages/d2/14/e301ee96a6dc95224b6f1162cd3312f6d1217be3907b79173b06785f2fe7/uvloop-0.22.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:1cdf5192ab3e674ca26da2eada35b288d2fa49fdd0f357a19f0e7c4e7d5077c8", size = 751811, upload-time = "2025-10-16T22:16:38.275Z" }, + { url = "https://files.pythonhosted.org/packages/b7/02/654426ce265ac19e2980bfd9ea6590ca96a56f10c76e63801a2df01c0486/uvloop-0.22.1-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6e2ea3d6190a2968f4a14a23019d3b16870dd2190cd69c8180f7c632d21de68d", size = 4288562, upload-time = "2025-10-16T22:16:39.375Z" }, + { url = "https://files.pythonhosted.org/packages/15/c0/0be24758891ef825f2065cd5db8741aaddabe3e248ee6acc5e8a80f04005/uvloop-0.22.1-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:0530a5fbad9c9e4ee3f2b33b148c6a64d47bbad8000ea63704fa8260f4cf728e", size = 4366890, upload-time = "2025-10-16T22:16:40.547Z" }, + { url = "https://files.pythonhosted.org/packages/d2/53/8369e5219a5855869bcee5f4d317f6da0e2c669aecf0ef7d371e3d084449/uvloop-0.22.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:bc5ef13bbc10b5335792360623cc378d52d7e62c2de64660616478c32cd0598e", size = 4119472, upload-time = "2025-10-16T22:16:41.694Z" }, + { url = "https://files.pythonhosted.org/packages/f8/ba/d69adbe699b768f6b29a5eec7b47dd610bd17a69de51b251126a801369ea/uvloop-0.22.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:1f38ec5e3f18c8a10ded09742f7fb8de0108796eb673f30ce7762ce1b8550cad", size = 4239051, upload-time = "2025-10-16T22:16:43.224Z" }, + { url = "https://files.pythonhosted.org/packages/90/cd/b62bdeaa429758aee8de8b00ac0dd26593a9de93d302bff3d21439e9791d/uvloop-0.22.1-cp314-cp314-macosx_10_13_universal2.whl", hash = "sha256:3879b88423ec7e97cd4eba2a443aa26ed4e59b45e6b76aabf13fe2f27023a142", size = 1362067, upload-time = "2025-10-16T22:16:44.503Z" }, + { url = "https://files.pythonhosted.org/packages/0d/f8/a132124dfda0777e489ca86732e85e69afcd1ff7686647000050ba670689/uvloop-0.22.1-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:4baa86acedf1d62115c1dc6ad1e17134476688f08c6efd8a2ab076e815665c74", size = 752423, upload-time = "2025-10-16T22:16:45.968Z" }, + { url = "https://files.pythonhosted.org/packages/a3/94/94af78c156f88da4b3a733773ad5ba0b164393e357cc4bd0ab2e2677a7d6/uvloop-0.22.1-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:297c27d8003520596236bdb2335e6b3f649480bd09e00d1e3a99144b691d2a35", size = 4272437, upload-time = "2025-10-16T22:16:47.451Z" }, + { url = "https://files.pythonhosted.org/packages/b5/35/60249e9fd07b32c665192cec7af29e06c7cd96fa1d08b84f012a56a0b38e/uvloop-0.22.1-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c1955d5a1dd43198244d47664a5858082a3239766a839b2102a269aaff7a4e25", size = 4292101, upload-time = "2025-10-16T22:16:49.318Z" }, + { url = "https://files.pythonhosted.org/packages/02/62/67d382dfcb25d0a98ce73c11ed1a6fba5037a1a1d533dcbb7cab033a2636/uvloop-0.22.1-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:b31dc2fccbd42adc73bc4e7cdbae4fc5086cf378979e53ca5d0301838c5682c6", size = 4114158, upload-time = "2025-10-16T22:16:50.517Z" }, + { url = "https://files.pythonhosted.org/packages/f0/7a/f1171b4a882a5d13c8b7576f348acfe6074d72eaf52cccef752f748d4a9f/uvloop-0.22.1-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:93f617675b2d03af4e72a5333ef89450dfaa5321303ede6e67ba9c9d26878079", size = 4177360, upload-time = "2025-10-16T22:16:52.646Z" }, + { url = "https://files.pythonhosted.org/packages/79/7b/b01414f31546caf0919da80ad57cbfe24c56b151d12af68cee1b04922ca8/uvloop-0.22.1-cp314-cp314t-macosx_10_13_universal2.whl", hash = "sha256:37554f70528f60cad66945b885eb01f1bb514f132d92b6eeed1c90fd54ed6289", size = 1454790, upload-time = "2025-10-16T22:16:54.355Z" }, + { url = "https://files.pythonhosted.org/packages/d4/31/0bb232318dd838cad3fa8fb0c68c8b40e1145b32025581975e18b11fab40/uvloop-0.22.1-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:b76324e2dc033a0b2f435f33eb88ff9913c156ef78e153fb210e03c13da746b3", size = 796783, upload-time = "2025-10-16T22:16:55.906Z" }, + { url = "https://files.pythonhosted.org/packages/42/38/c9b09f3271a7a723a5de69f8e237ab8e7803183131bc57c890db0b6bb872/uvloop-0.22.1-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:badb4d8e58ee08dad957002027830d5c3b06aea446a6a3744483c2b3b745345c", size = 4647548, upload-time = "2025-10-16T22:16:57.008Z" }, + { url = "https://files.pythonhosted.org/packages/c1/37/945b4ca0ac27e3dc4952642d4c900edd030b3da6c9634875af6e13ae80e5/uvloop-0.22.1-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:b91328c72635f6f9e0282e4a57da7470c7350ab1c9f48546c0f2866205349d21", size = 4467065, upload-time = "2025-10-16T22:16:58.206Z" }, + { url = "https://files.pythonhosted.org/packages/97/cc/48d232f33d60e2e2e0b42f4e73455b146b76ebe216487e862700457fbf3c/uvloop-0.22.1-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:daf620c2995d193449393d6c62131b3fbd40a63bf7b307a1527856ace637fe88", size = 4328384, upload-time = "2025-10-16T22:16:59.36Z" }, + { url = "https://files.pythonhosted.org/packages/e4/16/c1fd27e9549f3c4baf1dc9c20c456cd2f822dbf8de9f463824b0c0357e06/uvloop-0.22.1-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:6cde23eeda1a25c75b2e07d39970f3374105d5eafbaab2a4482be82f272d5a5e", size = 4296730, upload-time = "2025-10-16T22:17:00.744Z" }, ] [[package]] diff --git a/frontend-app/src/assets/data/demo.json b/frontend-app/src/assets/data/demo.json deleted file mode 100644 index 3289842..0000000 --- a/frontend-app/src/assets/data/demo.json +++ /dev/null @@ -1,50791 +0,0 @@ -{ - "products": [ - { - "id": 1, - "name": "SmartToast Pro 2000", - "description": "Advanced 4-slice toaster with smart temperature control and multiple browning settings", - "brand": "SmartToast", - "model": "pr-2000-3111", - "product_type": { - "id": 1, - "name": "Kitchen Appliance" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 2.8, - "unit": "kg" - }, - { - "property_name": "Width", - "value": 35, - "unit": "cm" - }, - { - "property_name": "Height", - "value": 22, - "unit": "cm" - }, - { - "property_name": "Depth", - "value": 18, - "unit": "cm" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 7.5, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 6.0, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 1, - "name": "Stainless Steel", - "type": "Metal" - }, - "percentage": 45, - "mass": 1.26, - "unit": "kg" - }, - { - "material": { - "id": 2, - "name": "ABS Plastic", - "type": "Plastic" - }, - "percentage": 35, - "mass": 0.98, - "unit": "kg" - }, - { - "material": { - "id": 3, - "name": "Copper Wire", - "type": "Metal" - }, - "percentage": 15, - "mass": 0.42, - "unit": "kg" - }, - { - "material": { - "id": 4, - "name": "Mica", - "type": "Mineral" - }, - "percentage": 5, - "mass": 0.14, - "unit": "kg" - } - ], - "components": [ - { - "id": 101, - "name": "Heating Element", - "description": "Nichrome wire heating element" - }, - { - "id": 102, - "name": "Control Panel", - "description": "Digital display with touch controls" - }, - { - "id": 103, - "name": "Spring Mechanism", - "description": "Pop-up mechanism for toast ejection" - }, - { - "id": 104, - "name": "Crumb Tray", - "description": "Removable stainless steel crumb collection tray" - } - ], - "images": [ - { - "id": 1, - "url": "https://via.placeholder.com/400x300/0066cc/ffffff?text=SmartToast+Pro+2000", - "description": "Front view of toaster" - } - ], - "created_at": "2024-01-15T10:30:00Z", - "updated_at": "2024-06-15T14:22:00Z" - }, - { - "id": 2, - "name": "EcoBoil Electric Kettle", - "description": "Energy-efficient 1.7L electric kettle with temperature control and auto shut-off", - "product_type": { - "id": 1, - "name": "Kitchen Appliance" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 1.2, - "unit": "kg" - }, - { - "property_name": "Capacity", - "value": 1.7, - "unit": "L" - }, - { - "property_name": "Height", - "value": 24, - "unit": "cm" - }, - { - "property_name": "Base Diameter", - "value": 20, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 2200, - "unit": "W" - }, - { - "property_name": "Boiling Time", - "value": 3.5, - "unit": "min" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 8.2, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 7.5, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 9.1, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 5, - "name": "Borosilicate Glass", - "type": "Glass" - }, - "percentage": 60, - "mass": 0.72, - "unit": "kg" - }, - { - "material": { - "id": 6, - "name": "Polypropylene", - "type": "Plastic" - }, - "percentage": 25, - "mass": 0.3, - "unit": "kg" - }, - { - "material": { - "id": 7, - "name": "Stainless Steel", - "type": "Metal" - }, - "percentage": 10, - "mass": 0.12, - "unit": "kg" - }, - { - "material": { - "id": 8, - "name": "Silicone", - "type": "Elastomer" - }, - "percentage": 5, - "mass": 0.06, - "unit": "kg" - } - ], - "components": [ - { - "id": 201, - "name": "Heating Base", - "description": "Electric heating element with power cord" - }, - { - "id": 202, - "name": "Glass Body", - "description": "Borosilicate glass water container" - }, - { - "id": 203, - "name": "Temperature Sensor", - "description": "Auto shut-off temperature control" - }, - { - "id": 204, - "name": "Handle Assembly", - "description": "Ergonomic heat-resistant handle" - }, - { - "id": 205, - "name": "Lid Mechanism", - "description": "Spring-loaded lid with steam vent" - } - ], - "images": [ - { - "id": 2, - "url": "https://via.placeholder.com/400x300/009966/ffffff?text=EcoBoil+Electric+Kettle", - "description": "Side view of electric kettle" - } - ], - "created_at": "2024-02-20T09:15:00Z", - "updated_at": "2024-06-10T11:45:00Z" - }, - { - "id": 3, - "name": "ZenGear Iron 607C", - "description": "ZenGear Iron 607C is a high-performance iron designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 4, - "name": "Smart Home Device" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 3.62, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 32.9, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 29.5, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 1332, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 8.9, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 8.7, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 9.5, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 4, - "name": "Mica", - "type": "Mineral" - }, - "percentage": 56.3, - "mass": 0.83, - "unit": "kg" - }, - { - "material": { - "id": 6, - "name": "Polypropylene", - "type": "Plastic" - }, - "percentage": 43.7, - "mass": 1.48, - "unit": "kg" - } - ], - "components": [ - { - "id": 31, - "name": "Iron Component 1", - "description": "High-quality part for iron functionality" - }, - { - "id": 32, - "name": "Iron Component 2", - "description": "High-quality part for iron functionality" - }, - { - "id": 33, - "name": "Iron Component 3", - "description": "High-quality part for iron functionality" - } - ], - "images": [ - { - "id": 3, - "url": "https://via.placeholder.com/400x300/0da203/ffffff?text=ZenGear+Iron+607C", - "description": "Iron product image" - } - ], - "created_at": "2025-02-09T09:16:11.448062Z", - "updated_at": "2025-05-01T09:16:11.448062Z" - }, - { - "id": 4, - "name": "EcoTech Kettle 101P", - "description": "EcoTech Kettle 101P is a high-performance kettle designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 5, - "name": "Office Equipment" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 2.61, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 21.5, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 17.7, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 2176, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 6.8, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 8.8, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 6.4, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 4, - "name": "Mica", - "type": "Mineral" - }, - "percentage": 38.1, - "mass": 1.08, - "unit": "kg" - }, - { - "material": { - "id": 7, - "name": "Silicone", - "type": "Elastomer" - }, - "percentage": 39.7, - "mass": 1.18, - "unit": "kg" - }, - { - "material": { - "id": 6, - "name": "Polypropylene", - "type": "Plastic" - }, - "percentage": 22.2, - "mass": 0.23, - "unit": "kg" - } - ], - "components": [ - { - "id": 41, - "name": "Kettle Component 1", - "description": "High-quality part for kettle functionality" - }, - { - "id": 42, - "name": "Kettle Component 2", - "description": "High-quality part for kettle functionality" - } - ], - "images": [ - { - "id": 4, - "url": "https://via.placeholder.com/400x300/069a50/ffffff?text=EcoTech+Kettle+101P", - "description": "Kettle product image" - } - ], - "created_at": "2024-12-01T09:16:11.448126Z", - "updated_at": "2025-07-03T09:16:11.448126Z" - }, - { - "id": 5, - "name": "CleanWave Blender 604Z", - "description": "CleanWave Blender 604Z is a high-performance blender designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 5, - "name": "Office Equipment" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 3.68, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 27.0, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 25.8, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 1210, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 8.7, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 6.4, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 9.8, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 6, - "name": "Polypropylene", - "type": "Plastic" - }, - "percentage": 38.6, - "mass": 1.05, - "unit": "kg" - }, - { - "material": { - "id": 2, - "name": "ABS Plastic", - "type": "Plastic" - }, - "percentage": 29.9, - "mass": 0.81, - "unit": "kg" - }, - { - "material": { - "id": 3, - "name": "Copper Wire", - "type": "Metal" - }, - "percentage": 31.5, - "mass": 0.47, - "unit": "kg" - } - ], - "components": [ - { - "id": 51, - "name": "Blender Component 1", - "description": "High-quality part for blender functionality" - }, - { - "id": 52, - "name": "Blender Component 2", - "description": "High-quality part for blender functionality" - }, - { - "id": 53, - "name": "Blender Component 3", - "description": "High-quality part for blender functionality" - }, - { - "id": 54, - "name": "Blender Component 4", - "description": "High-quality part for blender functionality" - } - ], - "images": [ - { - "id": 5, - "url": "https://via.placeholder.com/400x300/072c44/ffffff?text=CleanWave+Blender+604Z", - "description": "Blender product image" - } - ], - "created_at": "2025-04-01T09:16:11.448191Z", - "updated_at": "2025-07-19T09:16:11.448191Z" - }, - { - "id": 6, - "name": "AquaPro Monitor 996S", - "description": "AquaPro Monitor 996S is a high-performance monitor designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 1, - "name": "Kitchen Appliance" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 3.61, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 26.1, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 16.5, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 1520, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 7.1, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 8.4, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 9.6, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 7, - "name": "Silicone", - "type": "Elastomer" - }, - "percentage": 8.9, - "mass": 0.11, - "unit": "kg" - }, - { - "material": { - "id": 6, - "name": "Polypropylene", - "type": "Plastic" - }, - "percentage": 42.3, - "mass": 1.68, - "unit": "kg" - }, - { - "material": { - "id": 4, - "name": "Mica", - "type": "Mineral" - }, - "percentage": 48.8, - "mass": 0.8, - "unit": "kg" - } - ], - "components": [ - { - "id": 61, - "name": "Monitor Component 1", - "description": "High-quality part for monitor functionality" - }, - { - "id": 62, - "name": "Monitor Component 2", - "description": "High-quality part for monitor functionality" - } - ], - "images": [ - { - "id": 6, - "url": "https://via.placeholder.com/400x300/0d7971/ffffff?text=AquaPro+Monitor+996S", - "description": "Monitor product image" - } - ], - "created_at": "2024-09-08T09:16:11.448244Z", - "updated_at": "2025-06-13T09:16:11.448244Z" - }, - { - "id": 7, - "name": "PureLife Iron 148J", - "description": "PureLife Iron 148J is a high-performance iron designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 1, - "name": "Kitchen Appliance" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 1.55, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 34.8, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 28.2, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 2134, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 7.9, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 5.3, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 8.1, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 2, - "name": "ABS Plastic", - "type": "Plastic" - }, - "percentage": 14.3, - "mass": 0.5, - "unit": "kg" - }, - { - "material": { - "id": 5, - "name": "Borosilicate Glass", - "type": "Glass" - }, - "percentage": 19.3, - "mass": 0.59, - "unit": "kg" - }, - { - "material": { - "id": 3, - "name": "Copper Wire", - "type": "Metal" - }, - "percentage": 42.9, - "mass": 1.31, - "unit": "kg" - }, - { - "material": { - "id": 6, - "name": "Polypropylene", - "type": "Plastic" - }, - "percentage": 23.5, - "mass": 0.53, - "unit": "kg" - } - ], - "components": [ - { - "id": 71, - "name": "Iron Component 1", - "description": "High-quality part for iron functionality" - }, - { - "id": 72, - "name": "Iron Component 2", - "description": "High-quality part for iron functionality" - }, - { - "id": 73, - "name": "Iron Component 3", - "description": "High-quality part for iron functionality" - } - ], - "images": [ - { - "id": 7, - "url": "https://via.placeholder.com/400x300/06f447/ffffff?text=PureLife+Iron+148J", - "description": "Iron product image" - } - ], - "created_at": "2024-06-17T09:16:11.448297Z", - "updated_at": "2025-05-30T09:16:11.448297Z" - }, - { - "id": 8, - "name": "SmartHome Toaster 171W", - "description": "SmartHome Toaster 171W is a high-performance toaster designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 5, - "name": "Office Equipment" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 1.24, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 34.6, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 28.1, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 831, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 7.5, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 6.8, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 8.3, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 2, - "name": "ABS Plastic", - "type": "Plastic" - }, - "percentage": 71.2, - "mass": 2.77, - "unit": "kg" - }, - { - "material": { - "id": 4, - "name": "Mica", - "type": "Mineral" - }, - "percentage": 28.7, - "mass": 0.83, - "unit": "kg" - } - ], - "components": [ - { - "id": 81, - "name": "Toaster Component 1", - "description": "High-quality part for toaster functionality" - }, - { - "id": 82, - "name": "Toaster Component 2", - "description": "High-quality part for toaster functionality" - } - ], - "images": [ - { - "id": 8, - "url": "https://via.placeholder.com/400x300/0c50a7/ffffff?text=SmartHome+Toaster+171W", - "description": "Toaster product image" - } - ], - "created_at": "2024-12-19T09:16:11.448351Z", - "updated_at": "2025-06-08T09:16:11.448351Z" - }, - { - "id": 9, - "name": "ZenGear Kettle 987Y", - "description": "ZenGear Kettle 987Y is a high-performance kettle designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 1, - "name": "Kitchen Appliance" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 1.28, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 30.1, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 26.0, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 808, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 8.6, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 5.1, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 7.0, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 3, - "name": "Copper Wire", - "type": "Metal" - }, - "percentage": 38.1, - "mass": 1.34, - "unit": "kg" - }, - { - "material": { - "id": 7, - "name": "Silicone", - "type": "Elastomer" - }, - "percentage": 23.9, - "mass": 0.96, - "unit": "kg" - }, - { - "material": { - "id": 1, - "name": "Stainless Steel", - "type": "Metal" - }, - "percentage": 38.1, - "mass": 0.74, - "unit": "kg" - } - ], - "components": [ - { - "id": 91, - "name": "Kettle Component 1", - "description": "High-quality part for kettle functionality" - }, - { - "id": 92, - "name": "Kettle Component 2", - "description": "High-quality part for kettle functionality" - }, - { - "id": 93, - "name": "Kettle Component 3", - "description": "High-quality part for kettle functionality" - }, - { - "id": 94, - "name": "Kettle Component 4", - "description": "High-quality part for kettle functionality" - }, - { - "id": 95, - "name": "Kettle Component 5", - "description": "High-quality part for kettle functionality" - } - ], - "images": [ - { - "id": 9, - "url": "https://via.placeholder.com/400x300/0c41dd/ffffff?text=ZenGear+Kettle+987Y", - "description": "Kettle product image" - } - ], - "created_at": "2024-12-07T09:16:11.448425Z", - "updated_at": "2025-05-27T09:16:11.448425Z" - }, - { - "id": 10, - "name": "EcoTech Rice Cooker 218T", - "description": "EcoTech Rice Cooker 218T is a high-performance rice cooker designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 3, - "name": "Personal Care Device" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 2.57, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 32.2, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 24.9, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 1245, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 6.9, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 7.6, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 6.5, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 5, - "name": "Borosilicate Glass", - "type": "Glass" - }, - "percentage": 55.6, - "mass": 2.02, - "unit": "kg" - }, - { - "material": { - "id": 2, - "name": "ABS Plastic", - "type": "Plastic" - }, - "percentage": 44.4, - "mass": 1.19, - "unit": "kg" - } - ], - "components": [ - { - "id": 101, - "name": "Rice Cooker Component 1", - "description": "High-quality part for rice cooker functionality" - }, - { - "id": 102, - "name": "Rice Cooker Component 2", - "description": "High-quality part for rice cooker functionality" - } - ], - "images": [ - { - "id": 10, - "url": "https://via.placeholder.com/400x300/0265e0/ffffff?text=EcoTech+Rice+Cooker+218T", - "description": "Rice Cooker product image" - } - ], - "created_at": "2024-09-23T09:16:11.448490Z", - "updated_at": "2025-06-30T09:16:11.448490Z" - }, - { - "id": 11, - "name": "EcoTech Coffee Maker 433D", - "description": "EcoTech Coffee Maker 433D is a high-performance coffee maker designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 2, - "name": "Home Electronics" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 1.83, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 30.5, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 18.8, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 1320, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 7.3, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 7.5, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 9.6, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 7, - "name": "Silicone", - "type": "Elastomer" - }, - "percentage": 37.3, - "mass": 0.44, - "unit": "kg" - }, - { - "material": { - "id": 5, - "name": "Borosilicate Glass", - "type": "Glass" - }, - "percentage": 44.9, - "mass": 1.13, - "unit": "kg" - }, - { - "material": { - "id": 4, - "name": "Mica", - "type": "Mineral" - }, - "percentage": 17.8, - "mass": 0.4, - "unit": "kg" - } - ], - "components": [ - { - "id": 111, - "name": "Coffee Maker Component 1", - "description": "High-quality part for coffee maker functionality" - }, - { - "id": 112, - "name": "Coffee Maker Component 2", - "description": "High-quality part for coffee maker functionality" - } - ], - "images": [ - { - "id": 11, - "url": "https://via.placeholder.com/400x300/0dbfa2/ffffff?text=EcoTech+Coffee+Maker+433D", - "description": "Coffee Maker product image" - } - ], - "created_at": "2025-03-12T09:16:11.448541Z", - "updated_at": "2025-04-27T09:16:11.448541Z" - }, - { - "id": 12, - "name": "CleanWave Toaster 161K", - "description": "CleanWave Toaster 161K is a high-performance toaster designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 4, - "name": "Smart Home Device" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 1.3, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 25.1, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 15.0, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 1429, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 8.6, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 8.1, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 9.0, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 1, - "name": "Stainless Steel", - "type": "Metal" - }, - "percentage": 22.8, - "mass": 0.56, - "unit": "kg" - }, - { - "material": { - "id": 3, - "name": "Copper Wire", - "type": "Metal" - }, - "percentage": 56.5, - "mass": 1.12, - "unit": "kg" - }, - { - "material": { - "id": 4, - "name": "Mica", - "type": "Mineral" - }, - "percentage": 20.7, - "mass": 0.41, - "unit": "kg" - } - ], - "components": [ - { - "id": 121, - "name": "Toaster Component 1", - "description": "High-quality part for toaster functionality" - }, - { - "id": 122, - "name": "Toaster Component 2", - "description": "High-quality part for toaster functionality" - }, - { - "id": 123, - "name": "Toaster Component 3", - "description": "High-quality part for toaster functionality" - } - ], - "images": [ - { - "id": 12, - "url": "https://via.placeholder.com/400x300/02c151/ffffff?text=CleanWave+Toaster+161K", - "description": "Toaster product image" - } - ], - "created_at": "2024-05-15T09:16:11.448588Z", - "updated_at": "2025-07-14T09:16:11.448588Z" - }, - { - "id": 13, - "name": "ChefMate Monitor 267O", - "description": "ChefMate Monitor 267O is a high-performance monitor designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 3, - "name": "Personal Care Device" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 2.71, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 20.9, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 23.3, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 893, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 6.0, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 7.3, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 9.8, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 7, - "name": "Silicone", - "type": "Elastomer" - }, - "percentage": 17.2, - "mass": 0.33, - "unit": "kg" - }, - { - "material": { - "id": 6, - "name": "Polypropylene", - "type": "Plastic" - }, - "percentage": 19.4, - "mass": 0.55, - "unit": "kg" - }, - { - "material": { - "id": 4, - "name": "Mica", - "type": "Mineral" - }, - "percentage": 22.4, - "mass": 0.31, - "unit": "kg" - }, - { - "material": { - "id": 3, - "name": "Copper Wire", - "type": "Metal" - }, - "percentage": 41.0, - "mass": 0.68, - "unit": "kg" - } - ], - "components": [ - { - "id": 131, - "name": "Monitor Component 1", - "description": "High-quality part for monitor functionality" - }, - { - "id": 132, - "name": "Monitor Component 2", - "description": "High-quality part for monitor functionality" - } - ], - "images": [ - { - "id": 13, - "url": "https://via.placeholder.com/400x300/03dc20/ffffff?text=ChefMate+Monitor+267O", - "description": "Monitor product image" - } - ], - "created_at": "2024-12-15T09:16:11.448644Z", - "updated_at": "2025-06-24T09:16:11.448644Z" - }, - { - "id": 14, - "name": "SmartHome Toaster 457E", - "description": "SmartHome Toaster 457E is a high-performance toaster designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 3, - "name": "Personal Care Device" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 1.25, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 28.1, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 25.2, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 2091, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 9.1, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 5.3, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 7.0, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 6, - "name": "Polypropylene", - "type": "Plastic" - }, - "percentage": 16.7, - "mass": 0.48, - "unit": "kg" - }, - { - "material": { - "id": 3, - "name": "Copper Wire", - "type": "Metal" - }, - "percentage": 83.3, - "mass": 0.99, - "unit": "kg" - } - ], - "components": [ - { - "id": 141, - "name": "Toaster Component 1", - "description": "High-quality part for toaster functionality" - }, - { - "id": 142, - "name": "Toaster Component 2", - "description": "High-quality part for toaster functionality" - }, - { - "id": 143, - "name": "Toaster Component 3", - "description": "High-quality part for toaster functionality" - } - ], - "images": [ - { - "id": 14, - "url": "https://via.placeholder.com/400x300/050341/ffffff?text=SmartHome+Toaster+457E", - "description": "Toaster product image" - } - ], - "created_at": "2024-06-19T09:16:11.448693Z", - "updated_at": "2025-07-03T09:16:11.448693Z" - }, - { - "id": 15, - "name": "SmartHome Humidifier 945H", - "description": "SmartHome Humidifier 945H is a high-performance humidifier designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 1, - "name": "Kitchen Appliance" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 2.73, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 24.3, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 26.4, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 895, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 8.2, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 8.9, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 9.8, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 1, - "name": "Stainless Steel", - "type": "Metal" - }, - "percentage": 32.3, - "mass": 0.9, - "unit": "kg" - }, - { - "material": { - "id": 2, - "name": "ABS Plastic", - "type": "Plastic" - }, - "percentage": 13.5, - "mass": 0.32, - "unit": "kg" - }, - { - "material": { - "id": 4, - "name": "Mica", - "type": "Mineral" - }, - "percentage": 15.8, - "mass": 0.43, - "unit": "kg" - }, - { - "material": { - "id": 5, - "name": "Borosilicate Glass", - "type": "Glass" - }, - "percentage": 38.3, - "mass": 1.29, - "unit": "kg" - } - ], - "components": [ - { - "id": 151, - "name": "Humidifier Component 1", - "description": "High-quality part for humidifier functionality" - }, - { - "id": 152, - "name": "Humidifier Component 2", - "description": "High-quality part for humidifier functionality" - }, - { - "id": 153, - "name": "Humidifier Component 3", - "description": "High-quality part for humidifier functionality" - } - ], - "images": [ - { - "id": 15, - "url": "https://via.placeholder.com/400x300/0a70db/ffffff?text=SmartHome+Humidifier+945H", - "description": "Humidifier product image" - } - ], - "created_at": "2024-08-15T09:16:11.448751Z", - "updated_at": "2025-07-06T09:16:11.448751Z" - }, - { - "id": 16, - "name": "CleanWave Monitor 211U", - "description": "CleanWave Monitor 211U is a high-performance monitor designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 3, - "name": "Personal Care Device" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 3.35, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 29.0, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 19.2, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 1361, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 9.2, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 8.6, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 7.2, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 6, - "name": "Polypropylene", - "type": "Plastic" - }, - "percentage": 20.2, - "mass": 0.45, - "unit": "kg" - }, - { - "material": { - "id": 7, - "name": "Silicone", - "type": "Elastomer" - }, - "percentage": 26.4, - "mass": 0.95, - "unit": "kg" - }, - { - "material": { - "id": 1, - "name": "Stainless Steel", - "type": "Metal" - }, - "percentage": 35.6, - "mass": 0.44, - "unit": "kg" - }, - { - "material": { - "id": 2, - "name": "ABS Plastic", - "type": "Plastic" - }, - "percentage": 17.8, - "mass": 0.25, - "unit": "kg" - } - ], - "components": [ - { - "id": 161, - "name": "Monitor Component 1", - "description": "High-quality part for monitor functionality" - }, - { - "id": 162, - "name": "Monitor Component 2", - "description": "High-quality part for monitor functionality" - }, - { - "id": 163, - "name": "Monitor Component 3", - "description": "High-quality part for monitor functionality" - }, - { - "id": 164, - "name": "Monitor Component 4", - "description": "High-quality part for monitor functionality" - } - ], - "images": [ - { - "id": 16, - "url": "https://via.placeholder.com/400x300/0294b4/ffffff?text=CleanWave+Monitor+211U", - "description": "Monitor product image" - } - ], - "created_at": "2024-06-16T09:16:11.448814Z", - "updated_at": "2025-05-02T09:16:11.448814Z" - }, - { - "id": 17, - "name": "PureLife Iron 216C", - "description": "PureLife Iron 216C is a high-performance iron designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 5, - "name": "Office Equipment" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 3.34, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 34.9, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 24.3, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 1146, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 7.9, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 6.5, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 8.3, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 4, - "name": "Mica", - "type": "Mineral" - }, - "percentage": 25.5, - "mass": 0.48, - "unit": "kg" - }, - { - "material": { - "id": 3, - "name": "Copper Wire", - "type": "Metal" - }, - "percentage": 15.3, - "mass": 0.31, - "unit": "kg" - }, - { - "material": { - "id": 5, - "name": "Borosilicate Glass", - "type": "Glass" - }, - "percentage": 36.3, - "mass": 0.67, - "unit": "kg" - }, - { - "material": { - "id": 6, - "name": "Polypropylene", - "type": "Plastic" - }, - "percentage": 22.9, - "mass": 0.6, - "unit": "kg" - } - ], - "components": [ - { - "id": 171, - "name": "Iron Component 1", - "description": "High-quality part for iron functionality" - }, - { - "id": 172, - "name": "Iron Component 2", - "description": "High-quality part for iron functionality" - } - ], - "images": [ - { - "id": 17, - "url": "https://via.placeholder.com/400x300/0e8e27/ffffff?text=PureLife+Iron+216C", - "description": "Iron product image" - } - ], - "created_at": "2024-11-27T09:16:11.448862Z", - "updated_at": "2025-06-09T09:16:11.448862Z" - }, - { - "id": 18, - "name": "CleanWave Coffee Maker 800U", - "description": "CleanWave Coffee Maker 800U is a high-performance coffee maker designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 2, - "name": "Home Electronics" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 3.19, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 26.7, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 21.6, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 2100, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 8.8, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 7.1, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 7.9, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 4, - "name": "Mica", - "type": "Mineral" - }, - "percentage": 29.1, - "mass": 0.61, - "unit": "kg" - }, - { - "material": { - "id": 5, - "name": "Borosilicate Glass", - "type": "Glass" - }, - "percentage": 22.3, - "mass": 0.6, - "unit": "kg" - }, - { - "material": { - "id": 2, - "name": "ABS Plastic", - "type": "Plastic" - }, - "percentage": 48.5, - "mass": 1.77, - "unit": "kg" - } - ], - "components": [ - { - "id": 181, - "name": "Coffee Maker Component 1", - "description": "High-quality part for coffee maker functionality" - }, - { - "id": 182, - "name": "Coffee Maker Component 2", - "description": "High-quality part for coffee maker functionality" - }, - { - "id": 183, - "name": "Coffee Maker Component 3", - "description": "High-quality part for coffee maker functionality" - } - ], - "images": [ - { - "id": 18, - "url": "https://via.placeholder.com/400x300/0a7c26/ffffff?text=CleanWave+Coffee+Maker+800U", - "description": "Coffee Maker product image" - } - ], - "created_at": "2024-09-11T09:16:11.448908Z", - "updated_at": "2025-07-13T09:16:11.448908Z" - }, - { - "id": 19, - "name": "ZenGear Rice Cooker 172F", - "description": "ZenGear Rice Cooker 172F is a high-performance rice cooker designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 3, - "name": "Personal Care Device" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 1.6, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 29.1, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 17.5, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 2192, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 6.8, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 7.2, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 9.1, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 6, - "name": "Polypropylene", - "type": "Plastic" - }, - "percentage": 54.3, - "mass": 1.82, - "unit": "kg" - }, - { - "material": { - "id": 1, - "name": "Stainless Steel", - "type": "Metal" - }, - "percentage": 45.7, - "mass": 1.31, - "unit": "kg" - } - ], - "components": [ - { - "id": 191, - "name": "Rice Cooker Component 1", - "description": "High-quality part for rice cooker functionality" - }, - { - "id": 192, - "name": "Rice Cooker Component 2", - "description": "High-quality part for rice cooker functionality" - }, - { - "id": 193, - "name": "Rice Cooker Component 3", - "description": "High-quality part for rice cooker functionality" - } - ], - "images": [ - { - "id": 19, - "url": "https://via.placeholder.com/400x300/036ad5/ffffff?text=ZenGear+Rice+Cooker+172F", - "description": "Rice Cooker product image" - } - ], - "created_at": "2024-11-24T09:16:11.448939Z", - "updated_at": "2025-07-08T09:16:11.448939Z" - }, - { - "id": 20, - "name": "ZenGear Iron 414Y", - "description": "ZenGear Iron 414Y is a high-performance iron designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 4, - "name": "Smart Home Device" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 2.81, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 26.5, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 21.0, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 1082, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 6.3, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 7.9, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 9.3, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 7, - "name": "Silicone", - "type": "Elastomer" - }, - "percentage": 16.4, - "mass": 0.29, - "unit": "kg" - }, - { - "material": { - "id": 6, - "name": "Polypropylene", - "type": "Plastic" - }, - "percentage": 36.9, - "mass": 1.34, - "unit": "kg" - }, - { - "material": { - "id": 1, - "name": "Stainless Steel", - "type": "Metal" - }, - "percentage": 46.7, - "mass": 1.26, - "unit": "kg" - } - ], - "components": [ - { - "id": 201, - "name": "Iron Component 1", - "description": "High-quality part for iron functionality" - }, - { - "id": 202, - "name": "Iron Component 2", - "description": "High-quality part for iron functionality" - } - ], - "images": [ - { - "id": 20, - "url": "https://via.placeholder.com/400x300/0cd673/ffffff?text=ZenGear+Iron+414Y", - "description": "Iron product image" - } - ], - "created_at": "2025-01-06T09:16:11.448987Z", - "updated_at": "2025-05-06T09:16:11.448987Z" - }, - { - "id": 21, - "name": "PureLife Rice Cooker 449F", - "description": "PureLife Rice Cooker 449F is a high-performance rice cooker designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 4, - "name": "Smart Home Device" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 1.95, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 32.8, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 29.7, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 2053, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 9.0, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 7.2, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 7.6, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 1, - "name": "Stainless Steel", - "type": "Metal" - }, - "percentage": 52.8, - "mass": 0.72, - "unit": "kg" - }, - { - "material": { - "id": 6, - "name": "Polypropylene", - "type": "Plastic" - }, - "percentage": 47.2, - "mass": 1.59, - "unit": "kg" - } - ], - "components": [ - { - "id": 211, - "name": "Rice Cooker Component 1", - "description": "High-quality part for rice cooker functionality" - }, - { - "id": 212, - "name": "Rice Cooker Component 2", - "description": "High-quality part for rice cooker functionality" - }, - { - "id": 213, - "name": "Rice Cooker Component 3", - "description": "High-quality part for rice cooker functionality" - } - ], - "images": [ - { - "id": 21, - "url": "https://via.placeholder.com/400x300/04576b/ffffff?text=PureLife+Rice+Cooker+449F", - "description": "Rice Cooker product image" - } - ], - "created_at": "2024-09-10T09:16:11.449032Z", - "updated_at": "2025-05-29T09:16:11.449032Z" - }, - { - "id": 22, - "name": "AquaPro Blender 361J", - "description": "AquaPro Blender 361J is a high-performance blender designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 2, - "name": "Home Electronics" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 1.89, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 22.7, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 23.9, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 1695, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 7.5, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 6.8, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 7.8, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 4, - "name": "Mica", - "type": "Mineral" - }, - "percentage": 35.8, - "mass": 1.16, - "unit": "kg" - }, - { - "material": { - "id": 6, - "name": "Polypropylene", - "type": "Plastic" - }, - "percentage": 38.7, - "mass": 1.25, - "unit": "kg" - }, - { - "material": { - "id": 1, - "name": "Stainless Steel", - "type": "Metal" - }, - "percentage": 25.5, - "mass": 0.82, - "unit": "kg" - } - ], - "components": [ - { - "id": 221, - "name": "Blender Component 1", - "description": "High-quality part for blender functionality" - }, - { - "id": 222, - "name": "Blender Component 2", - "description": "High-quality part for blender functionality" - }, - { - "id": 223, - "name": "Blender Component 3", - "description": "High-quality part for blender functionality" - }, - { - "id": 224, - "name": "Blender Component 4", - "description": "High-quality part for blender functionality" - } - ], - "images": [ - { - "id": 22, - "url": "https://via.placeholder.com/400x300/068aab/ffffff?text=AquaPro+Blender+361J", - "description": "Blender product image" - } - ], - "created_at": "2025-03-17T09:16:11.449086Z", - "updated_at": "2025-06-28T09:16:11.449086Z" - }, - { - "id": 23, - "name": "SmartHome Kettle 600E", - "description": "SmartHome Kettle 600E is a high-performance kettle designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 3, - "name": "Personal Care Device" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 2.15, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 24.5, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 23.7, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 887, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 9.4, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 6.0, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 6.3, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 4, - "name": "Mica", - "type": "Mineral" - }, - "percentage": 41.3, - "mass": 0.46, - "unit": "kg" - }, - { - "material": { - "id": 7, - "name": "Silicone", - "type": "Elastomer" - }, - "percentage": 58.7, - "mass": 2.24, - "unit": "kg" - } - ], - "components": [ - { - "id": 231, - "name": "Kettle Component 1", - "description": "High-quality part for kettle functionality" - }, - { - "id": 232, - "name": "Kettle Component 2", - "description": "High-quality part for kettle functionality" - }, - { - "id": 233, - "name": "Kettle Component 3", - "description": "High-quality part for kettle functionality" - }, - { - "id": 234, - "name": "Kettle Component 4", - "description": "High-quality part for kettle functionality" - } - ], - "images": [ - { - "id": 23, - "url": "https://via.placeholder.com/400x300/03810c/ffffff?text=SmartHome+Kettle+600E", - "description": "Kettle product image" - } - ], - "created_at": "2024-06-24T09:16:11.449263Z", - "updated_at": "2025-06-30T09:16:11.449263Z" - }, - { - "id": 24, - "name": "AquaPro Toaster 875K", - "description": "AquaPro Toaster 875K is a high-performance toaster designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 1, - "name": "Kitchen Appliance" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 2.02, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 34.1, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 15.9, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 2144, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 8.1, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 5.4, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 8.5, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 4, - "name": "Mica", - "type": "Mineral" - }, - "percentage": 16.6, - "mass": 0.61, - "unit": "kg" - }, - { - "material": { - "id": 3, - "name": "Copper Wire", - "type": "Metal" - }, - "percentage": 27.8, - "mass": 1.04, - "unit": "kg" - }, - { - "material": { - "id": 7, - "name": "Silicone", - "type": "Elastomer" - }, - "percentage": 29.4, - "mass": 0.95, - "unit": "kg" - }, - { - "material": { - "id": 6, - "name": "Polypropylene", - "type": "Plastic" - }, - "percentage": 26.2, - "mass": 0.88, - "unit": "kg" - } - ], - "components": [ - { - "id": 241, - "name": "Toaster Component 1", - "description": "High-quality part for toaster functionality" - }, - { - "id": 242, - "name": "Toaster Component 2", - "description": "High-quality part for toaster functionality" - }, - { - "id": 243, - "name": "Toaster Component 3", - "description": "High-quality part for toaster functionality" - } - ], - "images": [ - { - "id": 24, - "url": "https://via.placeholder.com/400x300/0639a7/ffffff?text=AquaPro+Toaster+875K", - "description": "Toaster product image" - } - ], - "created_at": "2025-02-11T09:16:11.449344Z", - "updated_at": "2025-05-02T09:16:11.449344Z" - }, - { - "id": 25, - "name": "EcoTech Toaster 888I", - "description": "EcoTech Toaster 888I is a high-performance toaster designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 3, - "name": "Personal Care Device" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 3.71, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 22.6, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 23.5, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 1052, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 7.5, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 7.6, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 7.2, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 2, - "name": "ABS Plastic", - "type": "Plastic" - }, - "percentage": 31.4, - "mass": 1.24, - "unit": "kg" - }, - { - "material": { - "id": 3, - "name": "Copper Wire", - "type": "Metal" - }, - "percentage": 54.3, - "mass": 2.13, - "unit": "kg" - }, - { - "material": { - "id": 5, - "name": "Borosilicate Glass", - "type": "Glass" - }, - "percentage": 14.3, - "mass": 0.38, - "unit": "kg" - } - ], - "components": [ - { - "id": 251, - "name": "Toaster Component 1", - "description": "High-quality part for toaster functionality" - }, - { - "id": 252, - "name": "Toaster Component 2", - "description": "High-quality part for toaster functionality" - }, - { - "id": 253, - "name": "Toaster Component 3", - "description": "High-quality part for toaster functionality" - }, - { - "id": 254, - "name": "Toaster Component 4", - "description": "High-quality part for toaster functionality" - }, - { - "id": 255, - "name": "Toaster Component 5", - "description": "High-quality part for toaster functionality" - } - ], - "images": [ - { - "id": 25, - "url": "https://via.placeholder.com/400x300/0f345d/ffffff?text=EcoTech+Toaster+888I", - "description": "Toaster product image" - } - ], - "created_at": "2024-11-15T09:16:11.449404Z", - "updated_at": "2025-05-16T09:16:11.449404Z" - }, - { - "id": 26, - "name": "NeoCook Humidifier 796I", - "description": "NeoCook Humidifier 796I is a high-performance humidifier designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 1, - "name": "Kitchen Appliance" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 1.58, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 22.6, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 20.7, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 824, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 6.5, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 8.9, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 10.0, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 1, - "name": "Stainless Steel", - "type": "Metal" - }, - "percentage": 70.3, - "mass": 2.54, - "unit": "kg" - }, - { - "material": { - "id": 3, - "name": "Copper Wire", - "type": "Metal" - }, - "percentage": 29.7, - "mass": 0.86, - "unit": "kg" - } - ], - "components": [ - { - "id": 261, - "name": "Humidifier Component 1", - "description": "High-quality part for humidifier functionality" - }, - { - "id": 262, - "name": "Humidifier Component 2", - "description": "High-quality part for humidifier functionality" - }, - { - "id": 263, - "name": "Humidifier Component 3", - "description": "High-quality part for humidifier functionality" - }, - { - "id": 264, - "name": "Humidifier Component 4", - "description": "High-quality part for humidifier functionality" - } - ], - "images": [ - { - "id": 26, - "url": "https://via.placeholder.com/400x300/0c9cb6/ffffff?text=NeoCook+Humidifier+796I", - "description": "Humidifier product image" - } - ], - "created_at": "2024-04-09T09:16:11.449463Z", - "updated_at": "2025-06-23T09:16:11.449463Z" - }, - { - "id": 27, - "name": "SmartHome Rice Cooker 876N", - "description": "SmartHome Rice Cooker 876N is a high-performance rice cooker designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 1, - "name": "Kitchen Appliance" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 3.31, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 22.3, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 27.4, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 2037, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 6.2, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 5.5, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 6.7, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 3, - "name": "Copper Wire", - "type": "Metal" - }, - "percentage": 48.9, - "mass": 1.66, - "unit": "kg" - }, - { - "material": { - "id": 6, - "name": "Polypropylene", - "type": "Plastic" - }, - "percentage": 51.1, - "mass": 0.52, - "unit": "kg" - } - ], - "components": [ - { - "id": 271, - "name": "Rice Cooker Component 1", - "description": "High-quality part for rice cooker functionality" - }, - { - "id": 272, - "name": "Rice Cooker Component 2", - "description": "High-quality part for rice cooker functionality" - } - ], - "images": [ - { - "id": 27, - "url": "https://via.placeholder.com/400x300/0d4b5a/ffffff?text=SmartHome+Rice+Cooker+876N", - "description": "Rice Cooker product image" - } - ], - "created_at": "2025-04-15T09:16:11.449525Z", - "updated_at": "2025-06-12T09:16:11.449525Z" - }, - { - "id": 28, - "name": "PureLife Fan 661Y", - "description": "PureLife Fan 661Y is a high-performance fan designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 4, - "name": "Smart Home Device" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 3.98, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 22.4, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 23.1, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 1543, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 6.1, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 6.1, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 6.2, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 5, - "name": "Borosilicate Glass", - "type": "Glass" - }, - "percentage": 42.2, - "mass": 1.25, - "unit": "kg" - }, - { - "material": { - "id": 2, - "name": "ABS Plastic", - "type": "Plastic" - }, - "percentage": 57.8, - "mass": 1.35, - "unit": "kg" - } - ], - "components": [ - { - "id": 281, - "name": "Fan Component 1", - "description": "High-quality part for fan functionality" - }, - { - "id": 282, - "name": "Fan Component 2", - "description": "High-quality part for fan functionality" - } - ], - "images": [ - { - "id": 28, - "url": "https://via.placeholder.com/400x300/06f71a/ffffff?text=PureLife+Fan+661Y", - "description": "Fan product image" - } - ], - "created_at": "2024-11-06T09:16:11.449580Z", - "updated_at": "2025-05-10T09:16:11.449580Z" - }, - { - "id": 29, - "name": "PureLife Kettle 359P", - "description": "PureLife Kettle 359P is a high-performance kettle designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 5, - "name": "Office Equipment" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 3.16, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 30.8, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 17.2, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 1849, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 6.5, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 6.1, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 7.2, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 2, - "name": "ABS Plastic", - "type": "Plastic" - }, - "percentage": 59.2, - "mass": 1.76, - "unit": "kg" - }, - { - "material": { - "id": 1, - "name": "Stainless Steel", - "type": "Metal" - }, - "percentage": 40.8, - "mass": 1.01, - "unit": "kg" - } - ], - "components": [ - { - "id": 291, - "name": "Kettle Component 1", - "description": "High-quality part for kettle functionality" - }, - { - "id": 292, - "name": "Kettle Component 2", - "description": "High-quality part for kettle functionality" - }, - { - "id": 293, - "name": "Kettle Component 3", - "description": "High-quality part for kettle functionality" - }, - { - "id": 294, - "name": "Kettle Component 4", - "description": "High-quality part for kettle functionality" - } - ], - "images": [ - { - "id": 29, - "url": "https://via.placeholder.com/400x300/023dff/ffffff?text=PureLife+Kettle+359P", - "description": "Kettle product image" - } - ], - "created_at": "2025-02-27T09:16:11.449635Z", - "updated_at": "2025-07-11T09:16:11.449635Z" - }, - { - "id": 30, - "name": "ChefMate Humidifier 229A", - "description": "ChefMate Humidifier 229A is a high-performance humidifier designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 5, - "name": "Office Equipment" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 2.29, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 29.7, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 22.9, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 1712, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 6.8, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 6.2, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 6.9, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 5, - "name": "Borosilicate Glass", - "type": "Glass" - }, - "percentage": 13.8, - "mass": 0.18, - "unit": "kg" - }, - { - "material": { - "id": 6, - "name": "Polypropylene", - "type": "Plastic" - }, - "percentage": 51.7, - "mass": 1.38, - "unit": "kg" - }, - { - "material": { - "id": 1, - "name": "Stainless Steel", - "type": "Metal" - }, - "percentage": 34.5, - "mass": 1.3, - "unit": "kg" - } - ], - "components": [ - { - "id": 301, - "name": "Humidifier Component 1", - "description": "High-quality part for humidifier functionality" - }, - { - "id": 302, - "name": "Humidifier Component 2", - "description": "High-quality part for humidifier functionality" - }, - { - "id": 303, - "name": "Humidifier Component 3", - "description": "High-quality part for humidifier functionality" - }, - { - "id": 304, - "name": "Humidifier Component 4", - "description": "High-quality part for humidifier functionality" - } - ], - "images": [ - { - "id": 30, - "url": "https://via.placeholder.com/400x300/03af0e/ffffff?text=ChefMate+Humidifier+229A", - "description": "Humidifier product image" - } - ], - "created_at": "2024-06-22T09:16:11.449692Z", - "updated_at": "2025-07-26T09:16:11.449692Z" - }, - { - "id": 31, - "name": "PureLife Air Purifier 405S", - "description": "PureLife Air Purifier 405S is a high-performance air purifier designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 5, - "name": "Office Equipment" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 1.85, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 32.5, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 22.3, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 1108, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 6.2, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 8.8, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 9.8, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 7, - "name": "Silicone", - "type": "Elastomer" - }, - "percentage": 22.6, - "mass": 0.24, - "unit": "kg" - }, - { - "material": { - "id": 5, - "name": "Borosilicate Glass", - "type": "Glass" - }, - "percentage": 24.8, - "mass": 0.69, - "unit": "kg" - }, - { - "material": { - "id": 6, - "name": "Polypropylene", - "type": "Plastic" - }, - "percentage": 43.8, - "mass": 1.15, - "unit": "kg" - }, - { - "material": { - "id": 2, - "name": "ABS Plastic", - "type": "Plastic" - }, - "percentage": 8.8, - "mass": 0.19, - "unit": "kg" - } - ], - "components": [ - { - "id": 311, - "name": "Air Purifier Component 1", - "description": "High-quality part for air purifier functionality" - }, - { - "id": 312, - "name": "Air Purifier Component 2", - "description": "High-quality part for air purifier functionality" - }, - { - "id": 313, - "name": "Air Purifier Component 3", - "description": "High-quality part for air purifier functionality" - } - ], - "images": [ - { - "id": 31, - "url": "https://via.placeholder.com/400x300/097300/ffffff?text=PureLife+Air+Purifier+405S", - "description": "Air Purifier product image" - } - ], - "created_at": "2024-06-15T09:16:11.449731Z", - "updated_at": "2025-06-11T09:16:11.449731Z" - }, - { - "id": 32, - "name": "PureLife Blender 476H", - "description": "PureLife Blender 476H is a high-performance blender designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 4, - "name": "Smart Home Device" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 1.49, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 33.2, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 22.9, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 1712, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 8.6, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 5.2, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 6.1, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 1, - "name": "Stainless Steel", - "type": "Metal" - }, - "percentage": 62.1, - "mass": 1.3, - "unit": "kg" - }, - { - "material": { - "id": 4, - "name": "Mica", - "type": "Mineral" - }, - "percentage": 37.9, - "mass": 0.74, - "unit": "kg" - } - ], - "components": [ - { - "id": 321, - "name": "Blender Component 1", - "description": "High-quality part for blender functionality" - }, - { - "id": 322, - "name": "Blender Component 2", - "description": "High-quality part for blender functionality" - } - ], - "images": [ - { - "id": 32, - "url": "https://via.placeholder.com/400x300/06c4a0/ffffff?text=PureLife+Blender+476H", - "description": "Blender product image" - } - ], - "created_at": "2025-01-20T09:16:11.449760Z", - "updated_at": "2025-05-28T09:16:11.449760Z" - }, - { - "id": 33, - "name": "ChefMate Iron 478S", - "description": "ChefMate Iron 478S is a high-performance iron designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 3, - "name": "Personal Care Device" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 1.29, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 33.6, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 28.2, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 1948, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 9.1, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 7.8, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 7.4, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 7, - "name": "Silicone", - "type": "Elastomer" - }, - "percentage": 18.1, - "mass": 0.54, - "unit": "kg" - }, - { - "material": { - "id": 6, - "name": "Polypropylene", - "type": "Plastic" - }, - "percentage": 55.2, - "mass": 2.06, - "unit": "kg" - }, - { - "material": { - "id": 3, - "name": "Copper Wire", - "type": "Metal" - }, - "percentage": 26.7, - "mass": 0.88, - "unit": "kg" - } - ], - "components": [ - { - "id": 331, - "name": "Iron Component 1", - "description": "High-quality part for iron functionality" - }, - { - "id": 332, - "name": "Iron Component 2", - "description": "High-quality part for iron functionality" - } - ], - "images": [ - { - "id": 33, - "url": "https://via.placeholder.com/400x300/0b8f9f/ffffff?text=ChefMate+Iron+478S", - "description": "Iron product image" - } - ], - "created_at": "2024-09-17T09:16:11.449791Z", - "updated_at": "2025-04-30T09:16:11.449791Z" - }, - { - "id": 34, - "name": "PureLife Coffee Maker 338V", - "description": "PureLife Coffee Maker 338V is a high-performance coffee maker designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 2, - "name": "Home Electronics" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 2.25, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 21.8, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 21.6, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 944, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 8.9, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 8.4, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 9.5, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 2, - "name": "ABS Plastic", - "type": "Plastic" - }, - "percentage": 41.9, - "mass": 1.08, - "unit": "kg" - }, - { - "material": { - "id": 5, - "name": "Borosilicate Glass", - "type": "Glass" - }, - "percentage": 58.1, - "mass": 2.0, - "unit": "kg" - } - ], - "components": [ - { - "id": 341, - "name": "Coffee Maker Component 1", - "description": "High-quality part for coffee maker functionality" - }, - { - "id": 342, - "name": "Coffee Maker Component 2", - "description": "High-quality part for coffee maker functionality" - }, - { - "id": 343, - "name": "Coffee Maker Component 3", - "description": "High-quality part for coffee maker functionality" - } - ], - "images": [ - { - "id": 34, - "url": "https://via.placeholder.com/400x300/048f56/ffffff?text=PureLife+Coffee+Maker+338V", - "description": "Coffee Maker product image" - } - ], - "created_at": "2025-02-10T09:16:11.449820Z", - "updated_at": "2025-07-30T09:16:11.449820Z" - }, - { - "id": 35, - "name": "AquaPro Humidifier 442U", - "description": "AquaPro Humidifier 442U is a high-performance humidifier designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 1, - "name": "Kitchen Appliance" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 2.36, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 23.7, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 17.4, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 933, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 7.1, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 7.8, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 8.7, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 7, - "name": "Silicone", - "type": "Elastomer" - }, - "percentage": 57.7, - "mass": 2.22, - "unit": "kg" - }, - { - "material": { - "id": 4, - "name": "Mica", - "type": "Mineral" - }, - "percentage": 42.3, - "mass": 1.24, - "unit": "kg" - } - ], - "components": [ - { - "id": 351, - "name": "Humidifier Component 1", - "description": "High-quality part for humidifier functionality" - }, - { - "id": 352, - "name": "Humidifier Component 2", - "description": "High-quality part for humidifier functionality" - }, - { - "id": 353, - "name": "Humidifier Component 3", - "description": "High-quality part for humidifier functionality" - }, - { - "id": 354, - "name": "Humidifier Component 4", - "description": "High-quality part for humidifier functionality" - }, - { - "id": 355, - "name": "Humidifier Component 5", - "description": "High-quality part for humidifier functionality" - } - ], - "images": [ - { - "id": 35, - "url": "https://via.placeholder.com/400x300/0e23c6/ffffff?text=AquaPro+Humidifier+442U", - "description": "Humidifier product image" - } - ], - "created_at": "2025-03-03T09:16:11.449869Z", - "updated_at": "2025-05-23T09:16:11.449869Z" - }, - { - "id": 36, - "name": "PureLife Iron 423Q", - "description": "PureLife Iron 423Q is a high-performance iron designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 5, - "name": "Office Equipment" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 3.49, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 28.7, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 25.5, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 978, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 9.0, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 7.3, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 8.4, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 2, - "name": "ABS Plastic", - "type": "Plastic" - }, - "percentage": 20.3, - "mass": 0.36, - "unit": "kg" - }, - { - "material": { - "id": 1, - "name": "Stainless Steel", - "type": "Metal" - }, - "percentage": 18.8, - "mass": 0.43, - "unit": "kg" - }, - { - "material": { - "id": 4, - "name": "Mica", - "type": "Mineral" - }, - "percentage": 33.3, - "mass": 0.66, - "unit": "kg" - }, - { - "material": { - "id": 5, - "name": "Borosilicate Glass", - "type": "Glass" - }, - "percentage": 27.5, - "mass": 0.82, - "unit": "kg" - } - ], - "components": [ - { - "id": 361, - "name": "Iron Component 1", - "description": "High-quality part for iron functionality" - }, - { - "id": 362, - "name": "Iron Component 2", - "description": "High-quality part for iron functionality" - }, - { - "id": 363, - "name": "Iron Component 3", - "description": "High-quality part for iron functionality" - }, - { - "id": 364, - "name": "Iron Component 4", - "description": "High-quality part for iron functionality" - }, - { - "id": 365, - "name": "Iron Component 5", - "description": "High-quality part for iron functionality" - } - ], - "images": [ - { - "id": 36, - "url": "https://via.placeholder.com/400x300/04726a/ffffff?text=PureLife+Iron+423Q", - "description": "Iron product image" - } - ], - "created_at": "2024-03-27T09:16:11.449941Z", - "updated_at": "2025-05-18T09:16:11.449941Z" - }, - { - "id": 37, - "name": "PureLife Rice Cooker 677F", - "description": "PureLife Rice Cooker 677F is a high-performance rice cooker designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 3, - "name": "Personal Care Device" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 2.91, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 25.3, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 18.2, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 1711, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 7.2, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 7.3, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 8.3, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 2, - "name": "ABS Plastic", - "type": "Plastic" - }, - "percentage": 29.4, - "mass": 0.86, - "unit": "kg" - }, - { - "material": { - "id": 1, - "name": "Stainless Steel", - "type": "Metal" - }, - "percentage": 70.6, - "mass": 1.53, - "unit": "kg" - } - ], - "components": [ - { - "id": 371, - "name": "Rice Cooker Component 1", - "description": "High-quality part for rice cooker functionality" - }, - { - "id": 372, - "name": "Rice Cooker Component 2", - "description": "High-quality part for rice cooker functionality" - }, - { - "id": 373, - "name": "Rice Cooker Component 3", - "description": "High-quality part for rice cooker functionality" - } - ], - "images": [ - { - "id": 37, - "url": "https://via.placeholder.com/400x300/030e25/ffffff?text=PureLife+Rice+Cooker+677F", - "description": "Rice Cooker product image" - } - ], - "created_at": "2024-06-05T09:16:11.449994Z", - "updated_at": "2025-05-25T09:16:11.449994Z" - }, - { - "id": 38, - "name": "EcoTech Monitor 581K", - "description": "EcoTech Monitor 581K is a high-performance monitor designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 2, - "name": "Home Electronics" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 2.46, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 26.3, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 16.5, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 1585, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 8.0, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 5.9, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 6.1, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 1, - "name": "Stainless Steel", - "type": "Metal" - }, - "percentage": 26.1, - "mass": 0.56, - "unit": "kg" - }, - { - "material": { - "id": 7, - "name": "Silicone", - "type": "Elastomer" - }, - "percentage": 32.7, - "mass": 1.05, - "unit": "kg" - }, - { - "material": { - "id": 2, - "name": "ABS Plastic", - "type": "Plastic" - }, - "percentage": 26.8, - "mass": 0.69, - "unit": "kg" - }, - { - "material": { - "id": 6, - "name": "Polypropylene", - "type": "Plastic" - }, - "percentage": 14.4, - "mass": 0.4, - "unit": "kg" - } - ], - "components": [ - { - "id": 381, - "name": "Monitor Component 1", - "description": "High-quality part for monitor functionality" - }, - { - "id": 382, - "name": "Monitor Component 2", - "description": "High-quality part for monitor functionality" - }, - { - "id": 383, - "name": "Monitor Component 3", - "description": "High-quality part for monitor functionality" - }, - { - "id": 384, - "name": "Monitor Component 4", - "description": "High-quality part for monitor functionality" - } - ], - "images": [ - { - "id": 38, - "url": "https://via.placeholder.com/400x300/0332f4/ffffff?text=EcoTech+Monitor+581K", - "description": "Monitor product image" - } - ], - "created_at": "2024-08-28T09:16:11.450054Z", - "updated_at": "2025-05-24T09:16:11.450054Z" - }, - { - "id": 39, - "name": "NeoCook Iron 319T", - "description": "NeoCook Iron 319T is a high-performance iron designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 2, - "name": "Home Electronics" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 2.4, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 31.4, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 20.6, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 1786, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 7.1, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 8.8, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 6.6, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 4, - "name": "Mica", - "type": "Mineral" - }, - "percentage": 78.1, - "mass": 2.58, - "unit": "kg" - }, - { - "material": { - "id": 6, - "name": "Polypropylene", - "type": "Plastic" - }, - "percentage": 21.9, - "mass": 0.66, - "unit": "kg" - } - ], - "components": [ - { - "id": 391, - "name": "Iron Component 1", - "description": "High-quality part for iron functionality" - }, - { - "id": 392, - "name": "Iron Component 2", - "description": "High-quality part for iron functionality" - } - ], - "images": [ - { - "id": 39, - "url": "https://via.placeholder.com/400x300/0774ba/ffffff?text=NeoCook+Iron+319T", - "description": "Iron product image" - } - ], - "created_at": "2025-02-19T09:16:11.450107Z", - "updated_at": "2025-07-03T09:16:11.450107Z" - }, - { - "id": 40, - "name": "EcoTech Air Purifier 835Q", - "description": "EcoTech Air Purifier 835Q is a high-performance air purifier designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 3, - "name": "Personal Care Device" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 3.49, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 33.5, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 22.3, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 1201, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 6.9, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 7.0, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 8.5, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 7, - "name": "Silicone", - "type": "Elastomer" - }, - "percentage": 43.1, - "mass": 1.2, - "unit": "kg" - }, - { - "material": { - "id": 4, - "name": "Mica", - "type": "Mineral" - }, - "percentage": 20.3, - "mass": 0.44, - "unit": "kg" - }, - { - "material": { - "id": 1, - "name": "Stainless Steel", - "type": "Metal" - }, - "percentage": 8.9, - "mass": 0.1, - "unit": "kg" - }, - { - "material": { - "id": 5, - "name": "Borosilicate Glass", - "type": "Glass" - }, - "percentage": 27.6, - "mass": 0.62, - "unit": "kg" - } - ], - "components": [ - { - "id": 401, - "name": "Air Purifier Component 1", - "description": "High-quality part for air purifier functionality" - }, - { - "id": 402, - "name": "Air Purifier Component 2", - "description": "High-quality part for air purifier functionality" - } - ], - "images": [ - { - "id": 40, - "url": "https://via.placeholder.com/400x300/07d9b6/ffffff?text=EcoTech+Air+Purifier+835Q", - "description": "Air Purifier product image" - } - ], - "created_at": "2024-03-27T09:16:11.450162Z", - "updated_at": "2025-07-18T09:16:11.450162Z" - }, - { - "id": 41, - "name": "CleanWave Iron 565H", - "description": "CleanWave Iron 565H is a high-performance iron designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 1, - "name": "Kitchen Appliance" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 1.73, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 28.4, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 15.5, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 1409, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 7.3, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 6.7, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 7.5, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 5, - "name": "Borosilicate Glass", - "type": "Glass" - }, - "percentage": 20.6, - "mass": 0.37, - "unit": "kg" - }, - { - "material": { - "id": 6, - "name": "Polypropylene", - "type": "Plastic" - }, - "percentage": 44.1, - "mass": 1.71, - "unit": "kg" - }, - { - "material": { - "id": 1, - "name": "Stainless Steel", - "type": "Metal" - }, - "percentage": 35.3, - "mass": 0.61, - "unit": "kg" - } - ], - "components": [ - { - "id": 411, - "name": "Iron Component 1", - "description": "High-quality part for iron functionality" - }, - { - "id": 412, - "name": "Iron Component 2", - "description": "High-quality part for iron functionality" - } - ], - "images": [ - { - "id": 41, - "url": "https://via.placeholder.com/400x300/0ddb85/ffffff?text=CleanWave+Iron+565H", - "description": "Iron product image" - } - ], - "created_at": "2024-11-20T09:16:11.450211Z", - "updated_at": "2025-06-07T09:16:11.450211Z" - }, - { - "id": 42, - "name": "PureLife Blender 974S", - "description": "PureLife Blender 974S is a high-performance blender designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 4, - "name": "Smart Home Device" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 2.79, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 29.2, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 21.5, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 1410, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 8.0, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 6.0, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 8.7, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 3, - "name": "Copper Wire", - "type": "Metal" - }, - "percentage": 54.1, - "mass": 0.63, - "unit": "kg" - }, - { - "material": { - "id": 1, - "name": "Stainless Steel", - "type": "Metal" - }, - "percentage": 45.9, - "mass": 0.83, - "unit": "kg" - } - ], - "components": [ - { - "id": 421, - "name": "Blender Component 1", - "description": "High-quality part for blender functionality" - }, - { - "id": 422, - "name": "Blender Component 2", - "description": "High-quality part for blender functionality" - }, - { - "id": 423, - "name": "Blender Component 3", - "description": "High-quality part for blender functionality" - }, - { - "id": 424, - "name": "Blender Component 4", - "description": "High-quality part for blender functionality" - }, - { - "id": 425, - "name": "Blender Component 5", - "description": "High-quality part for blender functionality" - } - ], - "images": [ - { - "id": 42, - "url": "https://via.placeholder.com/400x300/069e57/ffffff?text=PureLife+Blender+974S", - "description": "Blender product image" - } - ], - "created_at": "2024-10-27T09:16:11.450262Z", - "updated_at": "2025-05-19T09:16:11.450262Z" - }, - { - "id": 43, - "name": "PureLife Fan 944U", - "description": "PureLife Fan 944U is a high-performance fan designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 1, - "name": "Kitchen Appliance" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 2.3, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 33.4, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 15.5, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 1062, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 9.1, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 6.3, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 8.5, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 3, - "name": "Copper Wire", - "type": "Metal" - }, - "percentage": 33.7, - "mass": 1.01, - "unit": "kg" - }, - { - "material": { - "id": 6, - "name": "Polypropylene", - "type": "Plastic" - }, - "percentage": 14.7, - "mass": 0.24, - "unit": "kg" - }, - { - "material": { - "id": 2, - "name": "ABS Plastic", - "type": "Plastic" - }, - "percentage": 25.8, - "mass": 0.86, - "unit": "kg" - }, - { - "material": { - "id": 7, - "name": "Silicone", - "type": "Elastomer" - }, - "percentage": 25.8, - "mass": 0.87, - "unit": "kg" - } - ], - "components": [ - { - "id": 431, - "name": "Fan Component 1", - "description": "High-quality part for fan functionality" - }, - { - "id": 432, - "name": "Fan Component 2", - "description": "High-quality part for fan functionality" - }, - { - "id": 433, - "name": "Fan Component 3", - "description": "High-quality part for fan functionality" - }, - { - "id": 434, - "name": "Fan Component 4", - "description": "High-quality part for fan functionality" - }, - { - "id": 435, - "name": "Fan Component 5", - "description": "High-quality part for fan functionality" - } - ], - "images": [ - { - "id": 43, - "url": "https://via.placeholder.com/400x300/0b9486/ffffff?text=PureLife+Fan+944U", - "description": "Fan product image" - } - ], - "created_at": "2024-06-28T09:16:11.450318Z", - "updated_at": "2025-06-19T09:16:11.450318Z" - }, - { - "id": 44, - "name": "SmartHome Monitor 264C", - "description": "SmartHome Monitor 264C is a high-performance monitor designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 5, - "name": "Office Equipment" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 1.55, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 30.9, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 25.9, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 926, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 9.2, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 6.4, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 8.6, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 2, - "name": "ABS Plastic", - "type": "Plastic" - }, - "percentage": 31.0, - "mass": 0.89, - "unit": "kg" - }, - { - "material": { - "id": 1, - "name": "Stainless Steel", - "type": "Metal" - }, - "percentage": 50.0, - "mass": 0.62, - "unit": "kg" - }, - { - "material": { - "id": 6, - "name": "Polypropylene", - "type": "Plastic" - }, - "percentage": 19.0, - "mass": 0.32, - "unit": "kg" - } - ], - "components": [ - { - "id": 441, - "name": "Monitor Component 1", - "description": "High-quality part for monitor functionality" - }, - { - "id": 442, - "name": "Monitor Component 2", - "description": "High-quality part for monitor functionality" - }, - { - "id": 443, - "name": "Monitor Component 3", - "description": "High-quality part for monitor functionality" - }, - { - "id": 444, - "name": "Monitor Component 4", - "description": "High-quality part for monitor functionality" - }, - { - "id": 445, - "name": "Monitor Component 5", - "description": "High-quality part for monitor functionality" - } - ], - "images": [ - { - "id": 44, - "url": "https://via.placeholder.com/400x300/0e4812/ffffff?text=SmartHome+Monitor+264C", - "description": "Monitor product image" - } - ], - "created_at": "2024-10-04T09:16:11.450374Z", - "updated_at": "2025-06-21T09:16:11.450374Z" - }, - { - "id": 45, - "name": "AquaPro Toaster 959U", - "description": "AquaPro Toaster 959U is a high-performance toaster designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 2, - "name": "Home Electronics" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 3.2, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 24.1, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 28.4, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 1487, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 8.1, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 8.2, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 6.2, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 4, - "name": "Mica", - "type": "Mineral" - }, - "percentage": 47.3, - "mass": 0.66, - "unit": "kg" - }, - { - "material": { - "id": 5, - "name": "Borosilicate Glass", - "type": "Glass" - }, - "percentage": 52.7, - "mass": 0.62, - "unit": "kg" - } - ], - "components": [ - { - "id": 451, - "name": "Toaster Component 1", - "description": "High-quality part for toaster functionality" - }, - { - "id": 452, - "name": "Toaster Component 2", - "description": "High-quality part for toaster functionality" - } - ], - "images": [ - { - "id": 45, - "url": "https://via.placeholder.com/400x300/0b2990/ffffff?text=AquaPro+Toaster+959U", - "description": "Toaster product image" - } - ], - "created_at": "2024-06-07T09:16:11.450426Z", - "updated_at": "2025-06-16T09:16:11.450426Z" - }, - { - "id": 46, - "name": "NeoCook Monitor 646J", - "description": "NeoCook Monitor 646J is a high-performance monitor designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 3, - "name": "Personal Care Device" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 3.61, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 26.0, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 28.5, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 1709, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 8.9, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 7.8, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 7.4, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 3, - "name": "Copper Wire", - "type": "Metal" - }, - "percentage": 32.1, - "mass": 0.93, - "unit": "kg" - }, - { - "material": { - "id": 1, - "name": "Stainless Steel", - "type": "Metal" - }, - "percentage": 46.2, - "mass": 1.5, - "unit": "kg" - }, - { - "material": { - "id": 5, - "name": "Borosilicate Glass", - "type": "Glass" - }, - "percentage": 21.7, - "mass": 0.77, - "unit": "kg" - } - ], - "components": [ - { - "id": 461, - "name": "Monitor Component 1", - "description": "High-quality part for monitor functionality" - }, - { - "id": 462, - "name": "Monitor Component 2", - "description": "High-quality part for monitor functionality" - }, - { - "id": 463, - "name": "Monitor Component 3", - "description": "High-quality part for monitor functionality" - }, - { - "id": 464, - "name": "Monitor Component 4", - "description": "High-quality part for monitor functionality" - }, - { - "id": 465, - "name": "Monitor Component 5", - "description": "High-quality part for monitor functionality" - } - ], - "images": [ - { - "id": 46, - "url": "https://via.placeholder.com/400x300/08046c/ffffff?text=NeoCook+Monitor+646J", - "description": "Monitor product image" - } - ], - "created_at": "2024-04-17T09:16:11.450510Z", - "updated_at": "2025-05-11T09:16:11.450510Z" - }, - { - "id": 47, - "name": "ZenGear Fan 714T", - "description": "ZenGear Fan 714T is a high-performance fan designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 3, - "name": "Personal Care Device" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 3.74, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 32.7, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 20.9, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 969, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 6.1, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 7.4, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 7.1, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 4, - "name": "Mica", - "type": "Mineral" - }, - "percentage": 62.9, - "mass": 2.39, - "unit": "kg" - }, - { - "material": { - "id": 5, - "name": "Borosilicate Glass", - "type": "Glass" - }, - "percentage": 18.6, - "mass": 0.44, - "unit": "kg" - }, - { - "material": { - "id": 7, - "name": "Silicone", - "type": "Elastomer" - }, - "percentage": 18.6, - "mass": 0.3, - "unit": "kg" - } - ], - "components": [ - { - "id": 471, - "name": "Fan Component 1", - "description": "High-quality part for fan functionality" - }, - { - "id": 472, - "name": "Fan Component 2", - "description": "High-quality part for fan functionality" - }, - { - "id": 473, - "name": "Fan Component 3", - "description": "High-quality part for fan functionality" - }, - { - "id": 474, - "name": "Fan Component 4", - "description": "High-quality part for fan functionality" - }, - { - "id": 475, - "name": "Fan Component 5", - "description": "High-quality part for fan functionality" - } - ], - "images": [ - { - "id": 47, - "url": "https://via.placeholder.com/400x300/0c6ad3/ffffff?text=ZenGear+Fan+714T", - "description": "Fan product image" - } - ], - "created_at": "2024-09-30T09:16:11.450571Z", - "updated_at": "2025-07-07T09:16:11.450571Z" - }, - { - "id": 48, - "name": "SmartHome Monitor 576C", - "description": "SmartHome Monitor 576C is a high-performance monitor designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 2, - "name": "Home Electronics" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 1.72, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 32.6, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 20.3, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 1312, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 8.8, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 5.4, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 6.6, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 2, - "name": "ABS Plastic", - "type": "Plastic" - }, - "percentage": 39.5, - "mass": 0.8, - "unit": "kg" - }, - { - "material": { - "id": 1, - "name": "Stainless Steel", - "type": "Metal" - }, - "percentage": 60.5, - "mass": 2.19, - "unit": "kg" - } - ], - "components": [ - { - "id": 481, - "name": "Monitor Component 1", - "description": "High-quality part for monitor functionality" - }, - { - "id": 482, - "name": "Monitor Component 2", - "description": "High-quality part for monitor functionality" - } - ], - "images": [ - { - "id": 48, - "url": "https://via.placeholder.com/400x300/0afd76/ffffff?text=SmartHome+Monitor+576C", - "description": "Monitor product image" - } - ], - "created_at": "2024-07-24T09:16:11.450622Z", - "updated_at": "2025-04-26T09:16:11.450622Z" - }, - { - "id": 49, - "name": "EcoTech Coffee Maker 618O", - "description": "EcoTech Coffee Maker 618O is a high-performance coffee maker designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 3, - "name": "Personal Care Device" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 2.6, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 32.6, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 29.6, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 1340, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 8.7, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 5.6, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 6.5, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 2, - "name": "ABS Plastic", - "type": "Plastic" - }, - "percentage": 27.7, - "mass": 0.61, - "unit": "kg" - }, - { - "material": { - "id": 5, - "name": "Borosilicate Glass", - "type": "Glass" - }, - "percentage": 72.3, - "mass": 1.95, - "unit": "kg" - } - ], - "components": [ - { - "id": 491, - "name": "Coffee Maker Component 1", - "description": "High-quality part for coffee maker functionality" - }, - { - "id": 492, - "name": "Coffee Maker Component 2", - "description": "High-quality part for coffee maker functionality" - } - ], - "images": [ - { - "id": 49, - "url": "https://via.placeholder.com/400x300/0de4d0/ffffff?text=EcoTech+Coffee+Maker+618O", - "description": "Coffee Maker product image" - } - ], - "created_at": "2024-06-19T09:16:11.450670Z", - "updated_at": "2025-07-17T09:16:11.450670Z" - }, - { - "id": 50, - "name": "EcoTech Blender 695H", - "description": "EcoTech Blender 695H is a high-performance blender designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 1, - "name": "Kitchen Appliance" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 1.71, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 27.2, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 16.9, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 1391, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 7.2, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 5.1, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 10.0, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 1, - "name": "Stainless Steel", - "type": "Metal" - }, - "percentage": 25.0, - "mass": 0.97, - "unit": "kg" - }, - { - "material": { - "id": 4, - "name": "Mica", - "type": "Mineral" - }, - "percentage": 29.9, - "mass": 1.08, - "unit": "kg" - }, - { - "material": { - "id": 6, - "name": "Polypropylene", - "type": "Plastic" - }, - "percentage": 15.3, - "mass": 0.16, - "unit": "kg" - }, - { - "material": { - "id": 2, - "name": "ABS Plastic", - "type": "Plastic" - }, - "percentage": 29.9, - "mass": 0.98, - "unit": "kg" - } - ], - "components": [ - { - "id": 501, - "name": "Blender Component 1", - "description": "High-quality part for blender functionality" - }, - { - "id": 502, - "name": "Blender Component 2", - "description": "High-quality part for blender functionality" - }, - { - "id": 503, - "name": "Blender Component 3", - "description": "High-quality part for blender functionality" - }, - { - "id": 504, - "name": "Blender Component 4", - "description": "High-quality part for blender functionality" - }, - { - "id": 505, - "name": "Blender Component 5", - "description": "High-quality part for blender functionality" - } - ], - "images": [ - { - "id": 50, - "url": "https://via.placeholder.com/400x300/02b428/ffffff?text=EcoTech+Blender+695H", - "description": "Blender product image" - } - ], - "created_at": "2024-10-19T09:16:11.450731Z", - "updated_at": "2025-07-29T09:16:11.450731Z" - }, - { - "id": 51, - "name": "EcoTech Air Purifier 705E", - "description": "EcoTech Air Purifier 705E is a high-performance air purifier designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 1, - "name": "Kitchen Appliance" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 2.2, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 31.0, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 19.4, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 1461, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 6.9, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 7.2, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 7.6, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 5, - "name": "Borosilicate Glass", - "type": "Glass" - }, - "percentage": 34.3, - "mass": 1.04, - "unit": "kg" - }, - { - "material": { - "id": 6, - "name": "Polypropylene", - "type": "Plastic" - }, - "percentage": 55.9, - "mass": 2.08, - "unit": "kg" - }, - { - "material": { - "id": 7, - "name": "Silicone", - "type": "Elastomer" - }, - "percentage": 9.8, - "mass": 0.16, - "unit": "kg" - } - ], - "components": [ - { - "id": 511, - "name": "Air Purifier Component 1", - "description": "High-quality part for air purifier functionality" - }, - { - "id": 512, - "name": "Air Purifier Component 2", - "description": "High-quality part for air purifier functionality" - } - ], - "images": [ - { - "id": 51, - "url": "https://via.placeholder.com/400x300/035657/ffffff?text=EcoTech+Air+Purifier+705E", - "description": "Air Purifier product image" - } - ], - "created_at": "2024-12-27T09:16:11.450787Z", - "updated_at": "2025-04-27T09:16:11.450787Z" - }, - { - "id": 52, - "name": "AquaPro Iron 902H", - "description": "AquaPro Iron 902H is a high-performance iron designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 2, - "name": "Home Electronics" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 3.26, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 26.1, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 29.6, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 2060, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 8.0, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 8.6, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 6.2, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 6, - "name": "Polypropylene", - "type": "Plastic" - }, - "percentage": 23.3, - "mass": 0.46, - "unit": "kg" - }, - { - "material": { - "id": 7, - "name": "Silicone", - "type": "Elastomer" - }, - "percentage": 32.0, - "mass": 1.25, - "unit": "kg" - }, - { - "material": { - "id": 1, - "name": "Stainless Steel", - "type": "Metal" - }, - "percentage": 44.7, - "mass": 0.88, - "unit": "kg" - } - ], - "components": [ - { - "id": 521, - "name": "Iron Component 1", - "description": "High-quality part for iron functionality" - }, - { - "id": 522, - "name": "Iron Component 2", - "description": "High-quality part for iron functionality" - } - ], - "images": [ - { - "id": 52, - "url": "https://via.placeholder.com/400x300/0a3c5c/ffffff?text=AquaPro+Iron+902H", - "description": "Iron product image" - } - ], - "created_at": "2025-01-11T09:16:11.450851Z", - "updated_at": "2025-07-04T09:16:11.450851Z" - }, - { - "id": 53, - "name": "AquaPro Humidifier 598N", - "description": "AquaPro Humidifier 598N is a high-performance humidifier designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 4, - "name": "Smart Home Device" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 1.12, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 24.2, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 30.0, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 802, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 6.4, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 8.8, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 7.5, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 1, - "name": "Stainless Steel", - "type": "Metal" - }, - "percentage": 17.9, - "mass": 0.4, - "unit": "kg" - }, - { - "material": { - "id": 6, - "name": "Polypropylene", - "type": "Plastic" - }, - "percentage": 82.1, - "mass": 3.0, - "unit": "kg" - } - ], - "components": [ - { - "id": 531, - "name": "Humidifier Component 1", - "description": "High-quality part for humidifier functionality" - }, - { - "id": 532, - "name": "Humidifier Component 2", - "description": "High-quality part for humidifier functionality" - }, - { - "id": 533, - "name": "Humidifier Component 3", - "description": "High-quality part for humidifier functionality" - }, - { - "id": 534, - "name": "Humidifier Component 4", - "description": "High-quality part for humidifier functionality" - }, - { - "id": 535, - "name": "Humidifier Component 5", - "description": "High-quality part for humidifier functionality" - } - ], - "images": [ - { - "id": 53, - "url": "https://via.placeholder.com/400x300/04ebc3/ffffff?text=AquaPro+Humidifier+598N", - "description": "Humidifier product image" - } - ], - "created_at": "2024-04-02T09:16:11.450905Z", - "updated_at": "2025-05-15T09:16:11.450905Z" - }, - { - "id": 54, - "name": "ChefMate Blender 609N", - "description": "ChefMate Blender 609N is a high-performance blender designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 5, - "name": "Office Equipment" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 3.85, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 27.6, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 24.9, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 1173, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 6.3, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 7.7, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 9.5, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 7, - "name": "Silicone", - "type": "Elastomer" - }, - "percentage": 47.4, - "mass": 0.89, - "unit": "kg" - }, - { - "material": { - "id": 1, - "name": "Stainless Steel", - "type": "Metal" - }, - "percentage": 52.6, - "mass": 1.01, - "unit": "kg" - } - ], - "components": [ - { - "id": 541, - "name": "Blender Component 1", - "description": "High-quality part for blender functionality" - }, - { - "id": 542, - "name": "Blender Component 2", - "description": "High-quality part for blender functionality" - } - ], - "images": [ - { - "id": 54, - "url": "https://via.placeholder.com/400x300/0782a7/ffffff?text=ChefMate+Blender+609N", - "description": "Blender product image" - } - ], - "created_at": "2025-03-12T09:16:11.450954Z", - "updated_at": "2025-07-13T09:16:11.450954Z" - }, - { - "id": 55, - "name": "ChefMate Blender 554T", - "description": "ChefMate Blender 554T is a high-performance blender designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 2, - "name": "Home Electronics" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 1.43, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 31.0, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 26.6, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 1816, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 7.9, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 8.3, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 7.0, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 5, - "name": "Borosilicate Glass", - "type": "Glass" - }, - "percentage": 25.8, - "mass": 0.38, - "unit": "kg" - }, - { - "material": { - "id": 2, - "name": "ABS Plastic", - "type": "Plastic" - }, - "percentage": 42.7, - "mass": 1.49, - "unit": "kg" - }, - { - "material": { - "id": 4, - "name": "Mica", - "type": "Mineral" - }, - "percentage": 31.5, - "mass": 1.24, - "unit": "kg" - } - ], - "components": [ - { - "id": 551, - "name": "Blender Component 1", - "description": "High-quality part for blender functionality" - }, - { - "id": 552, - "name": "Blender Component 2", - "description": "High-quality part for blender functionality" - }, - { - "id": 553, - "name": "Blender Component 3", - "description": "High-quality part for blender functionality" - }, - { - "id": 554, - "name": "Blender Component 4", - "description": "High-quality part for blender functionality" - }, - { - "id": 555, - "name": "Blender Component 5", - "description": "High-quality part for blender functionality" - } - ], - "images": [ - { - "id": 55, - "url": "https://via.placeholder.com/400x300/086604/ffffff?text=ChefMate+Blender+554T", - "description": "Blender product image" - } - ], - "created_at": "2024-11-10T09:16:11.451002Z", - "updated_at": "2025-06-29T09:16:11.451002Z" - }, - { - "id": 56, - "name": "ZenGear Coffee Maker 136V", - "description": "ZenGear Coffee Maker 136V is a high-performance coffee maker designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 1, - "name": "Kitchen Appliance" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 2.0, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 21.7, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 22.0, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 2168, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 7.4, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 7.1, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 6.5, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 4, - "name": "Mica", - "type": "Mineral" - }, - "percentage": 33.0, - "mass": 1.23, - "unit": "kg" - }, - { - "material": { - "id": 5, - "name": "Borosilicate Glass", - "type": "Glass" - }, - "percentage": 12.2, - "mass": 0.42, - "unit": "kg" - }, - { - "material": { - "id": 7, - "name": "Silicone", - "type": "Elastomer" - }, - "percentage": 25.2, - "mass": 0.79, - "unit": "kg" - }, - { - "material": { - "id": 1, - "name": "Stainless Steel", - "type": "Metal" - }, - "percentage": 29.6, - "mass": 1.0, - "unit": "kg" - } - ], - "components": [ - { - "id": 561, - "name": "Coffee Maker Component 1", - "description": "High-quality part for coffee maker functionality" - }, - { - "id": 562, - "name": "Coffee Maker Component 2", - "description": "High-quality part for coffee maker functionality" - }, - { - "id": 563, - "name": "Coffee Maker Component 3", - "description": "High-quality part for coffee maker functionality" - } - ], - "images": [ - { - "id": 56, - "url": "https://via.placeholder.com/400x300/0e065e/ffffff?text=ZenGear+Coffee+Maker+136V", - "description": "Coffee Maker product image" - } - ], - "created_at": "2024-05-03T09:16:11.451059Z", - "updated_at": "2025-05-24T09:16:11.451059Z" - }, - { - "id": 57, - "name": "ZenGear Air Purifier 922A", - "description": "ZenGear Air Purifier 922A is a high-performance air purifier designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 3, - "name": "Personal Care Device" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 3.57, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 32.9, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 22.7, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 1760, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 6.1, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 6.4, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 9.6, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 3, - "name": "Copper Wire", - "type": "Metal" - }, - "percentage": 35.7, - "mass": 0.53, - "unit": "kg" - }, - { - "material": { - "id": 4, - "name": "Mica", - "type": "Mineral" - }, - "percentage": 31.7, - "mass": 0.9, - "unit": "kg" - }, - { - "material": { - "id": 2, - "name": "ABS Plastic", - "type": "Plastic" - }, - "percentage": 32.5, - "mass": 0.39, - "unit": "kg" - } - ], - "components": [ - { - "id": 571, - "name": "Air Purifier Component 1", - "description": "High-quality part for air purifier functionality" - }, - { - "id": 572, - "name": "Air Purifier Component 2", - "description": "High-quality part for air purifier functionality" - }, - { - "id": 573, - "name": "Air Purifier Component 3", - "description": "High-quality part for air purifier functionality" - } - ], - "images": [ - { - "id": 57, - "url": "https://via.placeholder.com/400x300/03e73b/ffffff?text=ZenGear+Air+Purifier+922A", - "description": "Air Purifier product image" - } - ], - "created_at": "2024-10-28T09:16:11.451110Z", - "updated_at": "2025-06-19T09:16:11.451110Z" - }, - { - "id": 58, - "name": "AquaPro Blender 481C", - "description": "AquaPro Blender 481C is a high-performance blender designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 4, - "name": "Smart Home Device" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 3.11, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 28.0, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 26.4, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 1054, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 8.3, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 6.9, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 6.3, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 6, - "name": "Polypropylene", - "type": "Plastic" - }, - "percentage": 55.8, - "mass": 0.83, - "unit": "kg" - }, - { - "material": { - "id": 2, - "name": "ABS Plastic", - "type": "Plastic" - }, - "percentage": 44.2, - "mass": 0.83, - "unit": "kg" - } - ], - "components": [ - { - "id": 581, - "name": "Blender Component 1", - "description": "High-quality part for blender functionality" - }, - { - "id": 582, - "name": "Blender Component 2", - "description": "High-quality part for blender functionality" - }, - { - "id": 583, - "name": "Blender Component 3", - "description": "High-quality part for blender functionality" - } - ], - "images": [ - { - "id": 58, - "url": "https://via.placeholder.com/400x300/0442d3/ffffff?text=AquaPro+Blender+481C", - "description": "Blender product image" - } - ], - "created_at": "2024-08-24T09:16:11.451244Z", - "updated_at": "2025-07-11T09:16:11.451244Z" - }, - { - "id": 59, - "name": "NeoCook Blender 846D", - "description": "NeoCook Blender 846D is a high-performance blender designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 4, - "name": "Smart Home Device" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 2.69, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 29.5, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 22.6, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 2176, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 8.6, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 5.5, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 6.6, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 3, - "name": "Copper Wire", - "type": "Metal" - }, - "percentage": 42.1, - "mass": 0.88, - "unit": "kg" - }, - { - "material": { - "id": 7, - "name": "Silicone", - "type": "Elastomer" - }, - "percentage": 57.9, - "mass": 1.87, - "unit": "kg" - } - ], - "components": [ - { - "id": 591, - "name": "Blender Component 1", - "description": "High-quality part for blender functionality" - }, - { - "id": 592, - "name": "Blender Component 2", - "description": "High-quality part for blender functionality" - }, - { - "id": 593, - "name": "Blender Component 3", - "description": "High-quality part for blender functionality" - }, - { - "id": 594, - "name": "Blender Component 4", - "description": "High-quality part for blender functionality" - } - ], - "images": [ - { - "id": 59, - "url": "https://via.placeholder.com/400x300/0d36a8/ffffff?text=NeoCook+Blender+846D", - "description": "Blender product image" - } - ], - "created_at": "2025-04-19T09:16:11.451291Z", - "updated_at": "2025-07-25T09:16:11.451291Z" - }, - { - "id": 60, - "name": "SmartHome Rice Cooker 607S", - "description": "SmartHome Rice Cooker 607S is a high-performance rice cooker designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 1, - "name": "Kitchen Appliance" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 2.68, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 20.9, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 28.1, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 1531, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 9.5, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 6.7, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 6.7, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 7, - "name": "Silicone", - "type": "Elastomer" - }, - "percentage": 42.2, - "mass": 0.92, - "unit": "kg" - }, - { - "material": { - "id": 1, - "name": "Stainless Steel", - "type": "Metal" - }, - "percentage": 57.8, - "mass": 1.41, - "unit": "kg" - } - ], - "components": [ - { - "id": 601, - "name": "Rice Cooker Component 1", - "description": "High-quality part for rice cooker functionality" - }, - { - "id": 602, - "name": "Rice Cooker Component 2", - "description": "High-quality part for rice cooker functionality" - }, - { - "id": 603, - "name": "Rice Cooker Component 3", - "description": "High-quality part for rice cooker functionality" - } - ], - "images": [ - { - "id": 60, - "url": "https://via.placeholder.com/400x300/05bcce/ffffff?text=SmartHome+Rice+Cooker+607S", - "description": "Rice Cooker product image" - } - ], - "created_at": "2024-05-04T09:16:11.451331Z", - "updated_at": "2025-06-02T09:16:11.451331Z" - }, - { - "id": 61, - "name": "AquaPro Fan 781X", - "description": "AquaPro Fan 781X is a high-performance fan designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 4, - "name": "Smart Home Device" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 1.95, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 32.1, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 18.4, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 1849, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 8.1, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 5.2, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 8.6, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 6, - "name": "Polypropylene", - "type": "Plastic" - }, - "percentage": 29.0, - "mass": 0.87, - "unit": "kg" - }, - { - "material": { - "id": 1, - "name": "Stainless Steel", - "type": "Metal" - }, - "percentage": 8.9, - "mass": 0.25, - "unit": "kg" - }, - { - "material": { - "id": 4, - "name": "Mica", - "type": "Mineral" - }, - "percentage": 21.8, - "mass": 0.69, - "unit": "kg" - }, - { - "material": { - "id": 2, - "name": "ABS Plastic", - "type": "Plastic" - }, - "percentage": 40.3, - "mass": 0.96, - "unit": "kg" - } - ], - "components": [ - { - "id": 611, - "name": "Fan Component 1", - "description": "High-quality part for fan functionality" - }, - { - "id": 612, - "name": "Fan Component 2", - "description": "High-quality part for fan functionality" - }, - { - "id": 613, - "name": "Fan Component 3", - "description": "High-quality part for fan functionality" - }, - { - "id": 614, - "name": "Fan Component 4", - "description": "High-quality part for fan functionality" - }, - { - "id": 615, - "name": "Fan Component 5", - "description": "High-quality part for fan functionality" - } - ], - "images": [ - { - "id": 61, - "url": "https://via.placeholder.com/400x300/04115f/ffffff?text=AquaPro+Fan+781X", - "description": "Fan product image" - } - ], - "created_at": "2024-10-25T09:16:11.451377Z", - "updated_at": "2025-06-24T09:16:11.451377Z" - }, - { - "id": 62, - "name": "NeoCook Humidifier 532S", - "description": "NeoCook Humidifier 532S is a high-performance humidifier designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 2, - "name": "Home Electronics" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 2.34, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 34.4, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 28.3, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 2171, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 7.9, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 5.0, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 9.2, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 4, - "name": "Mica", - "type": "Mineral" - }, - "percentage": 27.2, - "mass": 0.9, - "unit": "kg" - }, - { - "material": { - "id": 5, - "name": "Borosilicate Glass", - "type": "Glass" - }, - "percentage": 28.9, - "mass": 1.03, - "unit": "kg" - }, - { - "material": { - "id": 7, - "name": "Silicone", - "type": "Elastomer" - }, - "percentage": 10.5, - "mass": 0.39, - "unit": "kg" - }, - { - "material": { - "id": 1, - "name": "Stainless Steel", - "type": "Metal" - }, - "percentage": 33.3, - "mass": 0.82, - "unit": "kg" - } - ], - "components": [ - { - "id": 621, - "name": "Humidifier Component 1", - "description": "High-quality part for humidifier functionality" - }, - { - "id": 622, - "name": "Humidifier Component 2", - "description": "High-quality part for humidifier functionality" - } - ], - "images": [ - { - "id": 62, - "url": "https://via.placeholder.com/400x300/0d16cf/ffffff?text=NeoCook+Humidifier+532S", - "description": "Humidifier product image" - } - ], - "created_at": "2024-10-19T09:16:11.451428Z", - "updated_at": "2025-06-18T09:16:11.451428Z" - }, - { - "id": 63, - "name": "CleanWave Toaster 934J", - "description": "CleanWave Toaster 934J is a high-performance toaster designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 3, - "name": "Personal Care Device" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 3.09, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 20.9, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 24.6, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 2044, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 7.7, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 7.6, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 6.8, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 7, - "name": "Silicone", - "type": "Elastomer" - }, - "percentage": 30.9, - "mass": 1.05, - "unit": "kg" - }, - { - "material": { - "id": 4, - "name": "Mica", - "type": "Mineral" - }, - "percentage": 37.5, - "mass": 1.04, - "unit": "kg" - }, - { - "material": { - "id": 1, - "name": "Stainless Steel", - "type": "Metal" - }, - "percentage": 31.6, - "mass": 0.35, - "unit": "kg" - } - ], - "components": [ - { - "id": 631, - "name": "Toaster Component 1", - "description": "High-quality part for toaster functionality" - }, - { - "id": 632, - "name": "Toaster Component 2", - "description": "High-quality part for toaster functionality" - }, - { - "id": 633, - "name": "Toaster Component 3", - "description": "High-quality part for toaster functionality" - } - ], - "images": [ - { - "id": 63, - "url": "https://via.placeholder.com/400x300/0b850a/ffffff?text=CleanWave+Toaster+934J", - "description": "Toaster product image" - } - ], - "created_at": "2024-10-12T09:16:11.451483Z", - "updated_at": "2025-07-17T09:16:11.451483Z" - }, - { - "id": 64, - "name": "ChefMate Humidifier 817V", - "description": "ChefMate Humidifier 817V is a high-performance humidifier designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 2, - "name": "Home Electronics" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 2.85, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 32.0, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 28.9, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 931, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 9.3, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 5.5, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 6.5, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 7, - "name": "Silicone", - "type": "Elastomer" - }, - "percentage": 24.6, - "mass": 0.38, - "unit": "kg" - }, - { - "material": { - "id": 3, - "name": "Copper Wire", - "type": "Metal" - }, - "percentage": 16.6, - "mass": 0.39, - "unit": "kg" - }, - { - "material": { - "id": 5, - "name": "Borosilicate Glass", - "type": "Glass" - }, - "percentage": 32.6, - "mass": 0.83, - "unit": "kg" - }, - { - "material": { - "id": 1, - "name": "Stainless Steel", - "type": "Metal" - }, - "percentage": 26.3, - "mass": 0.62, - "unit": "kg" - } - ], - "components": [ - { - "id": 641, - "name": "Humidifier Component 1", - "description": "High-quality part for humidifier functionality" - }, - { - "id": 642, - "name": "Humidifier Component 2", - "description": "High-quality part for humidifier functionality" - }, - { - "id": 643, - "name": "Humidifier Component 3", - "description": "High-quality part for humidifier functionality" - }, - { - "id": 644, - "name": "Humidifier Component 4", - "description": "High-quality part for humidifier functionality" - }, - { - "id": 645, - "name": "Humidifier Component 5", - "description": "High-quality part for humidifier functionality" - } - ], - "images": [ - { - "id": 64, - "url": "https://via.placeholder.com/400x300/0c871e/ffffff?text=ChefMate+Humidifier+817V", - "description": "Humidifier product image" - } - ], - "created_at": "2024-06-14T09:16:11.451537Z", - "updated_at": "2025-05-23T09:16:11.451537Z" - }, - { - "id": 65, - "name": "EcoTech Monitor 888W", - "description": "EcoTech Monitor 888W is a high-performance monitor designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 1, - "name": "Kitchen Appliance" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 3.73, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 22.9, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 15.0, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 1091, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 9.2, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 8.6, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 6.7, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 4, - "name": "Mica", - "type": "Mineral" - }, - "percentage": 36.6, - "mass": 0.65, - "unit": "kg" - }, - { - "material": { - "id": 2, - "name": "ABS Plastic", - "type": "Plastic" - }, - "percentage": 42.3, - "mass": 1.41, - "unit": "kg" - }, - { - "material": { - "id": 5, - "name": "Borosilicate Glass", - "type": "Glass" - }, - "percentage": 21.1, - "mass": 0.56, - "unit": "kg" - } - ], - "components": [ - { - "id": 651, - "name": "Monitor Component 1", - "description": "High-quality part for monitor functionality" - }, - { - "id": 652, - "name": "Monitor Component 2", - "description": "High-quality part for monitor functionality" - }, - { - "id": 653, - "name": "Monitor Component 3", - "description": "High-quality part for monitor functionality" - }, - { - "id": 654, - "name": "Monitor Component 4", - "description": "High-quality part for monitor functionality" - } - ], - "images": [ - { - "id": 65, - "url": "https://via.placeholder.com/400x300/0a8e4d/ffffff?text=EcoTech+Monitor+888W", - "description": "Monitor product image" - } - ], - "created_at": "2024-07-15T09:16:11.451569Z", - "updated_at": "2025-05-29T09:16:11.451569Z" - }, - { - "id": 66, - "name": "NeoCook Kettle 219G", - "description": "NeoCook Kettle 219G is a high-performance kettle designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 1, - "name": "Kitchen Appliance" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 3.49, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 27.0, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 24.0, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 968, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 6.8, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 8.9, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 9.2, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 2, - "name": "ABS Plastic", - "type": "Plastic" - }, - "percentage": 14.4, - "mass": 0.18, - "unit": "kg" - }, - { - "material": { - "id": 5, - "name": "Borosilicate Glass", - "type": "Glass" - }, - "percentage": 43.9, - "mass": 1.05, - "unit": "kg" - }, - { - "material": { - "id": 4, - "name": "Mica", - "type": "Mineral" - }, - "percentage": 41.7, - "mass": 1.34, - "unit": "kg" - } - ], - "components": [ - { - "id": 661, - "name": "Kettle Component 1", - "description": "High-quality part for kettle functionality" - }, - { - "id": 662, - "name": "Kettle Component 2", - "description": "High-quality part for kettle functionality" - } - ], - "images": [ - { - "id": 66, - "url": "https://via.placeholder.com/400x300/038125/ffffff?text=NeoCook+Kettle+219G", - "description": "Kettle product image" - } - ], - "created_at": "2024-03-30T09:16:11.451600Z", - "updated_at": "2025-06-26T09:16:11.451600Z" - }, - { - "id": 67, - "name": "CleanWave Fan 871L", - "description": "CleanWave Fan 871L is a high-performance fan designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 1, - "name": "Kitchen Appliance" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 2.24, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 32.6, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 19.1, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 1259, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 8.0, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 8.4, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 7.6, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 3, - "name": "Copper Wire", - "type": "Metal" - }, - "percentage": 24.1, - "mass": 0.93, - "unit": "kg" - }, - { - "material": { - "id": 4, - "name": "Mica", - "type": "Mineral" - }, - "percentage": 54.4, - "mass": 1.11, - "unit": "kg" - }, - { - "material": { - "id": 7, - "name": "Silicone", - "type": "Elastomer" - }, - "percentage": 21.5, - "mass": 0.52, - "unit": "kg" - } - ], - "components": [ - { - "id": 671, - "name": "Fan Component 1", - "description": "High-quality part for fan functionality" - }, - { - "id": 672, - "name": "Fan Component 2", - "description": "High-quality part for fan functionality" - }, - { - "id": 673, - "name": "Fan Component 3", - "description": "High-quality part for fan functionality" - }, - { - "id": 674, - "name": "Fan Component 4", - "description": "High-quality part for fan functionality" - } - ], - "images": [ - { - "id": 67, - "url": "https://via.placeholder.com/400x300/06766b/ffffff?text=CleanWave+Fan+871L", - "description": "Fan product image" - } - ], - "created_at": "2024-11-30T09:16:11.451635Z", - "updated_at": "2025-04-26T09:16:11.451635Z" - }, - { - "id": 68, - "name": "EcoTech Fan 746H", - "description": "EcoTech Fan 746H is a high-performance fan designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 4, - "name": "Smart Home Device" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 3.64, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 32.2, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 17.7, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 1488, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 7.0, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 6.0, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 8.1, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 6, - "name": "Polypropylene", - "type": "Plastic" - }, - "percentage": 33.0, - "mass": 0.79, - "unit": "kg" - }, - { - "material": { - "id": 4, - "name": "Mica", - "type": "Mineral" - }, - "percentage": 46.8, - "mass": 0.57, - "unit": "kg" - }, - { - "material": { - "id": 2, - "name": "ABS Plastic", - "type": "Plastic" - }, - "percentage": 20.2, - "mass": 0.31, - "unit": "kg" - } - ], - "components": [ - { - "id": 681, - "name": "Fan Component 1", - "description": "High-quality part for fan functionality" - }, - { - "id": 682, - "name": "Fan Component 2", - "description": "High-quality part for fan functionality" - }, - { - "id": 683, - "name": "Fan Component 3", - "description": "High-quality part for fan functionality" - }, - { - "id": 684, - "name": "Fan Component 4", - "description": "High-quality part for fan functionality" - } - ], - "images": [ - { - "id": 68, - "url": "https://via.placeholder.com/400x300/0e6f50/ffffff?text=EcoTech+Fan+746H", - "description": "Fan product image" - } - ], - "created_at": "2025-04-05T09:16:11.451671Z", - "updated_at": "2025-05-15T09:16:11.451671Z" - }, - { - "id": 69, - "name": "NeoCook Toaster 779R", - "description": "NeoCook Toaster 779R is a high-performance toaster designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 1, - "name": "Kitchen Appliance" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 1.29, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 32.0, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 16.8, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 2135, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 9.1, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 5.1, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 7.0, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 1, - "name": "Stainless Steel", - "type": "Metal" - }, - "percentage": 22.7, - "mass": 0.54, - "unit": "kg" - }, - { - "material": { - "id": 2, - "name": "ABS Plastic", - "type": "Plastic" - }, - "percentage": 77.3, - "mass": 2.93, - "unit": "kg" - } - ], - "components": [ - { - "id": 691, - "name": "Toaster Component 1", - "description": "High-quality part for toaster functionality" - }, - { - "id": 692, - "name": "Toaster Component 2", - "description": "High-quality part for toaster functionality" - }, - { - "id": 693, - "name": "Toaster Component 3", - "description": "High-quality part for toaster functionality" - }, - { - "id": 694, - "name": "Toaster Component 4", - "description": "High-quality part for toaster functionality" - } - ], - "images": [ - { - "id": 69, - "url": "https://via.placeholder.com/400x300/05ac9b/ffffff?text=NeoCook+Toaster+779R", - "description": "Toaster product image" - } - ], - "created_at": "2025-01-25T09:16:11.451718Z", - "updated_at": "2025-06-05T09:16:11.451718Z" - }, - { - "id": 70, - "name": "NeoCook Toaster 749F", - "description": "NeoCook Toaster 749F is a high-performance toaster designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 4, - "name": "Smart Home Device" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 2.0, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 32.2, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 19.6, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 845, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 6.8, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 7.2, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 8.9, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 1, - "name": "Stainless Steel", - "type": "Metal" - }, - "percentage": 81.5, - "mass": 2.22, - "unit": "kg" - }, - { - "material": { - "id": 4, - "name": "Mica", - "type": "Mineral" - }, - "percentage": 18.5, - "mass": 0.32, - "unit": "kg" - } - ], - "components": [ - { - "id": 701, - "name": "Toaster Component 1", - "description": "High-quality part for toaster functionality" - }, - { - "id": 702, - "name": "Toaster Component 2", - "description": "High-quality part for toaster functionality" - }, - { - "id": 703, - "name": "Toaster Component 3", - "description": "High-quality part for toaster functionality" - }, - { - "id": 704, - "name": "Toaster Component 4", - "description": "High-quality part for toaster functionality" - } - ], - "images": [ - { - "id": 70, - "url": "https://via.placeholder.com/400x300/0d3980/ffffff?text=NeoCook+Toaster+749F", - "description": "Toaster product image" - } - ], - "created_at": "2024-07-29T09:16:11.451770Z", - "updated_at": "2025-06-21T09:16:11.451770Z" - }, - { - "id": 71, - "name": "ZenGear Blender 125N", - "description": "ZenGear Blender 125N is a high-performance blender designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 2, - "name": "Home Electronics" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 2.81, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 30.3, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 29.7, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 928, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 9.2, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 6.1, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 9.1, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 1, - "name": "Stainless Steel", - "type": "Metal" - }, - "percentage": 48.6, - "mass": 1.92, - "unit": "kg" - }, - { - "material": { - "id": 7, - "name": "Silicone", - "type": "Elastomer" - }, - "percentage": 51.4, - "mass": 1.5, - "unit": "kg" - } - ], - "components": [ - { - "id": 711, - "name": "Blender Component 1", - "description": "High-quality part for blender functionality" - }, - { - "id": 712, - "name": "Blender Component 2", - "description": "High-quality part for blender functionality" - } - ], - "images": [ - { - "id": 71, - "url": "https://via.placeholder.com/400x300/0b18a9/ffffff?text=ZenGear+Blender+125N", - "description": "Blender product image" - } - ], - "created_at": "2024-03-28T09:16:11.451819Z", - "updated_at": "2025-05-05T09:16:11.451819Z" - }, - { - "id": 72, - "name": "PureLife Toaster 874Q", - "description": "PureLife Toaster 874Q is a high-performance toaster designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 4, - "name": "Smart Home Device" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 2.13, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 22.3, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 25.4, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 1878, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 8.0, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 8.6, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 8.8, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 3, - "name": "Copper Wire", - "type": "Metal" - }, - "percentage": 35.0, - "mass": 0.85, - "unit": "kg" - }, - { - "material": { - "id": 1, - "name": "Stainless Steel", - "type": "Metal" - }, - "percentage": 31.5, - "mass": 0.61, - "unit": "kg" - }, - { - "material": { - "id": 4, - "name": "Mica", - "type": "Mineral" - }, - "percentage": 33.6, - "mass": 0.83, - "unit": "kg" - } - ], - "components": [ - { - "id": 721, - "name": "Toaster Component 1", - "description": "High-quality part for toaster functionality" - }, - { - "id": 722, - "name": "Toaster Component 2", - "description": "High-quality part for toaster functionality" - }, - { - "id": 723, - "name": "Toaster Component 3", - "description": "High-quality part for toaster functionality" - }, - { - "id": 724, - "name": "Toaster Component 4", - "description": "High-quality part for toaster functionality" - } - ], - "images": [ - { - "id": 72, - "url": "https://via.placeholder.com/400x300/0f0e0d/ffffff?text=PureLife+Toaster+874Q", - "description": "Toaster product image" - } - ], - "created_at": "2025-04-05T09:16:11.451880Z", - "updated_at": "2025-06-14T09:16:11.451880Z" - }, - { - "id": 73, - "name": "ChefMate Air Purifier 590Y", - "description": "ChefMate Air Purifier 590Y is a high-performance air purifier designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 1, - "name": "Kitchen Appliance" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 2.26, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 31.4, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 23.6, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 1519, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 7.1, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 5.5, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 9.3, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 2, - "name": "ABS Plastic", - "type": "Plastic" - }, - "percentage": 65.8, - "mass": 2.01, - "unit": "kg" - }, - { - "material": { - "id": 5, - "name": "Borosilicate Glass", - "type": "Glass" - }, - "percentage": 34.2, - "mass": 0.5, - "unit": "kg" - } - ], - "components": [ - { - "id": 731, - "name": "Air Purifier Component 1", - "description": "High-quality part for air purifier functionality" - }, - { - "id": 732, - "name": "Air Purifier Component 2", - "description": "High-quality part for air purifier functionality" - }, - { - "id": 733, - "name": "Air Purifier Component 3", - "description": "High-quality part for air purifier functionality" - } - ], - "images": [ - { - "id": 73, - "url": "https://via.placeholder.com/400x300/0cc406/ffffff?text=ChefMate+Air+Purifier+590Y", - "description": "Air Purifier product image" - } - ], - "created_at": "2024-03-30T09:16:11.451926Z", - "updated_at": "2025-06-15T09:16:11.451926Z" - }, - { - "id": 74, - "name": "AquaPro Iron 454C", - "description": "AquaPro Iron 454C is a high-performance iron designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 3, - "name": "Personal Care Device" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 1.07, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 27.0, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 22.2, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 1280, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 9.3, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 5.0, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 7.5, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 5, - "name": "Borosilicate Glass", - "type": "Glass" - }, - "percentage": 29.7, - "mass": 0.33, - "unit": "kg" - }, - { - "material": { - "id": 4, - "name": "Mica", - "type": "Mineral" - }, - "percentage": 48.6, - "mass": 1.85, - "unit": "kg" - }, - { - "material": { - "id": 7, - "name": "Silicone", - "type": "Elastomer" - }, - "percentage": 21.6, - "mass": 0.26, - "unit": "kg" - } - ], - "components": [ - { - "id": 741, - "name": "Iron Component 1", - "description": "High-quality part for iron functionality" - }, - { - "id": 742, - "name": "Iron Component 2", - "description": "High-quality part for iron functionality" - }, - { - "id": 743, - "name": "Iron Component 3", - "description": "High-quality part for iron functionality" - }, - { - "id": 744, - "name": "Iron Component 4", - "description": "High-quality part for iron functionality" - }, - { - "id": 745, - "name": "Iron Component 5", - "description": "High-quality part for iron functionality" - } - ], - "images": [ - { - "id": 74, - "url": "https://via.placeholder.com/400x300/07dbf9/ffffff?text=AquaPro+Iron+454C", - "description": "Iron product image" - } - ], - "created_at": "2025-03-22T09:16:11.451961Z", - "updated_at": "2025-04-27T09:16:11.451961Z" - }, - { - "id": 75, - "name": "PureLife Air Purifier 527P", - "description": "PureLife Air Purifier 527P is a high-performance air purifier designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 3, - "name": "Personal Care Device" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 1.37, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 31.4, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 19.3, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 2127, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 7.9, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 6.3, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 6.3, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 6, - "name": "Polypropylene", - "type": "Plastic" - }, - "percentage": 12.7, - "mass": 0.15, - "unit": "kg" - }, - { - "material": { - "id": 2, - "name": "ABS Plastic", - "type": "Plastic" - }, - "percentage": 37.3, - "mass": 0.69, - "unit": "kg" - }, - { - "material": { - "id": 4, - "name": "Mica", - "type": "Mineral" - }, - "percentage": 12.0, - "mass": 0.32, - "unit": "kg" - }, - { - "material": { - "id": 5, - "name": "Borosilicate Glass", - "type": "Glass" - }, - "percentage": 38.0, - "mass": 1.42, - "unit": "kg" - } - ], - "components": [ - { - "id": 751, - "name": "Air Purifier Component 1", - "description": "High-quality part for air purifier functionality" - }, - { - "id": 752, - "name": "Air Purifier Component 2", - "description": "High-quality part for air purifier functionality" - }, - { - "id": 753, - "name": "Air Purifier Component 3", - "description": "High-quality part for air purifier functionality" - }, - { - "id": 754, - "name": "Air Purifier Component 4", - "description": "High-quality part for air purifier functionality" - }, - { - "id": 755, - "name": "Air Purifier Component 5", - "description": "High-quality part for air purifier functionality" - } - ], - "images": [ - { - "id": 75, - "url": "https://via.placeholder.com/400x300/043674/ffffff?text=PureLife+Air+Purifier+527P", - "description": "Air Purifier product image" - } - ], - "created_at": "2024-05-02T09:16:11.451999Z", - "updated_at": "2025-07-24T09:16:11.451999Z" - }, - { - "id": 76, - "name": "ZenGear Monitor 938X", - "description": "ZenGear Monitor 938X is a high-performance monitor designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 3, - "name": "Personal Care Device" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 1.06, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 20.9, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 21.3, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 1145, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 6.9, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 5.4, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 6.6, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 5, - "name": "Borosilicate Glass", - "type": "Glass" - }, - "percentage": 19.8, - "mass": 0.41, - "unit": "kg" - }, - { - "material": { - "id": 4, - "name": "Mica", - "type": "Mineral" - }, - "percentage": 31.1, - "mass": 1.0, - "unit": "kg" - }, - { - "material": { - "id": 7, - "name": "Silicone", - "type": "Elastomer" - }, - "percentage": 49.1, - "mass": 0.85, - "unit": "kg" - } - ], - "components": [ - { - "id": 761, - "name": "Monitor Component 1", - "description": "High-quality part for monitor functionality" - }, - { - "id": 762, - "name": "Monitor Component 2", - "description": "High-quality part for monitor functionality" - }, - { - "id": 763, - "name": "Monitor Component 3", - "description": "High-quality part for monitor functionality" - } - ], - "images": [ - { - "id": 76, - "url": "https://via.placeholder.com/400x300/0ddb03/ffffff?text=ZenGear+Monitor+938X", - "description": "Monitor product image" - } - ], - "created_at": "2025-02-15T09:16:11.452045Z", - "updated_at": "2025-07-11T09:16:11.452045Z" - }, - { - "id": 77, - "name": "EcoTech Monitor 598B", - "description": "EcoTech Monitor 598B is a high-performance monitor designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 2, - "name": "Home Electronics" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 3.08, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 27.9, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 21.6, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 1944, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 7.5, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 7.8, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 6.5, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 3, - "name": "Copper Wire", - "type": "Metal" - }, - "percentage": 26.4, - "mass": 0.96, - "unit": "kg" - }, - { - "material": { - "id": 4, - "name": "Mica", - "type": "Mineral" - }, - "percentage": 31.9, - "mass": 0.94, - "unit": "kg" - }, - { - "material": { - "id": 7, - "name": "Silicone", - "type": "Elastomer" - }, - "percentage": 16.0, - "mass": 0.63, - "unit": "kg" - }, - { - "material": { - "id": 2, - "name": "ABS Plastic", - "type": "Plastic" - }, - "percentage": 25.8, - "mass": 0.53, - "unit": "kg" - } - ], - "components": [ - { - "id": 771, - "name": "Monitor Component 1", - "description": "High-quality part for monitor functionality" - }, - { - "id": 772, - "name": "Monitor Component 2", - "description": "High-quality part for monitor functionality" - }, - { - "id": 773, - "name": "Monitor Component 3", - "description": "High-quality part for monitor functionality" - }, - { - "id": 774, - "name": "Monitor Component 4", - "description": "High-quality part for monitor functionality" - }, - { - "id": 775, - "name": "Monitor Component 5", - "description": "High-quality part for monitor functionality" - } - ], - "images": [ - { - "id": 77, - "url": "https://via.placeholder.com/400x300/03abc0/ffffff?text=EcoTech+Monitor+598B", - "description": "Monitor product image" - } - ], - "created_at": "2025-01-12T09:16:11.452091Z", - "updated_at": "2025-06-13T09:16:11.452091Z" - }, - { - "id": 78, - "name": "NeoCook Toaster 499E", - "description": "NeoCook Toaster 499E is a high-performance toaster designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 2, - "name": "Home Electronics" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 2.27, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 32.9, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 27.6, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 1203, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 6.4, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 7.0, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 9.6, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 2, - "name": "ABS Plastic", - "type": "Plastic" - }, - "percentage": 43.8, - "mass": 1.63, - "unit": "kg" - }, - { - "material": { - "id": 1, - "name": "Stainless Steel", - "type": "Metal" - }, - "percentage": 56.2, - "mass": 1.25, - "unit": "kg" - } - ], - "components": [ - { - "id": 781, - "name": "Toaster Component 1", - "description": "High-quality part for toaster functionality" - }, - { - "id": 782, - "name": "Toaster Component 2", - "description": "High-quality part for toaster functionality" - } - ], - "images": [ - { - "id": 78, - "url": "https://via.placeholder.com/400x300/06fcae/ffffff?text=NeoCook+Toaster+499E", - "description": "Toaster product image" - } - ], - "created_at": "2025-01-13T09:16:11.452135Z", - "updated_at": "2025-07-23T09:16:11.452135Z" - }, - { - "id": 79, - "name": "PureLife Iron 780K", - "description": "PureLife Iron 780K is a high-performance iron designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 1, - "name": "Kitchen Appliance" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 3.13, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 27.8, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 22.3, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 1041, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 8.2, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 7.8, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 9.7, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 1, - "name": "Stainless Steel", - "type": "Metal" - }, - "percentage": 50.5, - "mass": 1.27, - "unit": "kg" - }, - { - "material": { - "id": 4, - "name": "Mica", - "type": "Mineral" - }, - "percentage": 49.5, - "mass": 1.24, - "unit": "kg" - } - ], - "components": [ - { - "id": 791, - "name": "Iron Component 1", - "description": "High-quality part for iron functionality" - }, - { - "id": 792, - "name": "Iron Component 2", - "description": "High-quality part for iron functionality" - } - ], - "images": [ - { - "id": 79, - "url": "https://via.placeholder.com/400x300/0cbe03/ffffff?text=PureLife+Iron+780K", - "description": "Iron product image" - } - ], - "created_at": "2025-01-08T09:16:11.452166Z", - "updated_at": "2025-07-07T09:16:11.452166Z" - }, - { - "id": 80, - "name": "EcoTech Humidifier 864C", - "description": "EcoTech Humidifier 864C is a high-performance humidifier designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 4, - "name": "Smart Home Device" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 2.08, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 32.4, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 15.5, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 2052, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 9.3, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 8.0, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 8.4, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 3, - "name": "Copper Wire", - "type": "Metal" - }, - "percentage": 68.5, - "mass": 2.73, - "unit": "kg" - }, - { - "material": { - "id": 4, - "name": "Mica", - "type": "Mineral" - }, - "percentage": 31.5, - "mass": 0.81, - "unit": "kg" - } - ], - "components": [ - { - "id": 801, - "name": "Humidifier Component 1", - "description": "High-quality part for humidifier functionality" - }, - { - "id": 802, - "name": "Humidifier Component 2", - "description": "High-quality part for humidifier functionality" - }, - { - "id": 803, - "name": "Humidifier Component 3", - "description": "High-quality part for humidifier functionality" - }, - { - "id": 804, - "name": "Humidifier Component 4", - "description": "High-quality part for humidifier functionality" - } - ], - "images": [ - { - "id": 80, - "url": "https://via.placeholder.com/400x300/0454a1/ffffff?text=EcoTech+Humidifier+864C", - "description": "Humidifier product image" - } - ], - "created_at": "2024-07-17T09:16:11.452198Z", - "updated_at": "2025-06-09T09:16:11.452198Z" - }, - { - "id": 81, - "name": "SmartHome Fan 980L", - "description": "SmartHome Fan 980L is a high-performance fan designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 5, - "name": "Office Equipment" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 1.8, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 28.0, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 27.9, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 1134, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 9.3, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 8.1, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 9.3, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 1, - "name": "Stainless Steel", - "type": "Metal" - }, - "percentage": 24.6, - "mass": 0.82, - "unit": "kg" - }, - { - "material": { - "id": 6, - "name": "Polypropylene", - "type": "Plastic" - }, - "percentage": 75.4, - "mass": 0.91, - "unit": "kg" - } - ], - "components": [ - { - "id": 811, - "name": "Fan Component 1", - "description": "High-quality part for fan functionality" - }, - { - "id": 812, - "name": "Fan Component 2", - "description": "High-quality part for fan functionality" - }, - { - "id": 813, - "name": "Fan Component 3", - "description": "High-quality part for fan functionality" - }, - { - "id": 814, - "name": "Fan Component 4", - "description": "High-quality part for fan functionality" - } - ], - "images": [ - { - "id": 81, - "url": "https://via.placeholder.com/400x300/063607/ffffff?text=SmartHome+Fan+980L", - "description": "Fan product image" - } - ], - "created_at": "2024-06-26T09:16:11.452227Z", - "updated_at": "2025-05-18T09:16:11.452227Z" - }, - { - "id": 82, - "name": "ZenGear Kettle 816G", - "description": "ZenGear Kettle 816G is a high-performance kettle designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 3, - "name": "Personal Care Device" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 1.12, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 22.8, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 25.1, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 977, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 6.0, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 6.5, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 8.1, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 6, - "name": "Polypropylene", - "type": "Plastic" - }, - "percentage": 23.4, - "mass": 0.69, - "unit": "kg" - }, - { - "material": { - "id": 2, - "name": "ABS Plastic", - "type": "Plastic" - }, - "percentage": 76.6, - "mass": 1.98, - "unit": "kg" - } - ], - "components": [ - { - "id": 821, - "name": "Kettle Component 1", - "description": "High-quality part for kettle functionality" - }, - { - "id": 822, - "name": "Kettle Component 2", - "description": "High-quality part for kettle functionality" - }, - { - "id": 823, - "name": "Kettle Component 3", - "description": "High-quality part for kettle functionality" - }, - { - "id": 824, - "name": "Kettle Component 4", - "description": "High-quality part for kettle functionality" - }, - { - "id": 825, - "name": "Kettle Component 5", - "description": "High-quality part for kettle functionality" - } - ], - "images": [ - { - "id": 82, - "url": "https://via.placeholder.com/400x300/03f661/ffffff?text=ZenGear+Kettle+816G", - "description": "Kettle product image" - } - ], - "created_at": "2025-04-03T09:16:11.452256Z", - "updated_at": "2025-05-22T09:16:11.452256Z" - }, - { - "id": 83, - "name": "CleanWave Kettle 743T", - "description": "CleanWave Kettle 743T is a high-performance kettle designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 3, - "name": "Personal Care Device" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 1.86, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 32.4, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 18.9, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 882, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 7.4, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 8.6, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 6.3, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 2, - "name": "ABS Plastic", - "type": "Plastic" - }, - "percentage": 20.2, - "mass": 0.49, - "unit": "kg" - }, - { - "material": { - "id": 4, - "name": "Mica", - "type": "Mineral" - }, - "percentage": 48.6, - "mass": 1.49, - "unit": "kg" - }, - { - "material": { - "id": 6, - "name": "Polypropylene", - "type": "Plastic" - }, - "percentage": 31.2, - "mass": 0.56, - "unit": "kg" - } - ], - "components": [ - { - "id": 831, - "name": "Kettle Component 1", - "description": "High-quality part for kettle functionality" - }, - { - "id": 832, - "name": "Kettle Component 2", - "description": "High-quality part for kettle functionality" - }, - { - "id": 833, - "name": "Kettle Component 3", - "description": "High-quality part for kettle functionality" - }, - { - "id": 834, - "name": "Kettle Component 4", - "description": "High-quality part for kettle functionality" - } - ], - "images": [ - { - "id": 83, - "url": "https://via.placeholder.com/400x300/060138/ffffff?text=CleanWave+Kettle+743T", - "description": "Kettle product image" - } - ], - "created_at": "2024-12-30T09:16:11.452541Z", - "updated_at": "2025-07-22T09:16:11.452541Z" - }, - { - "id": 84, - "name": "AquaPro Iron 426H", - "description": "AquaPro Iron 426H is a high-performance iron designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 3, - "name": "Personal Care Device" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 2.12, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 20.6, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 16.9, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 1477, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 7.9, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 8.3, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 9.4, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 1, - "name": "Stainless Steel", - "type": "Metal" - }, - "percentage": 18.2, - "mass": 0.71, - "unit": "kg" - }, - { - "material": { - "id": 7, - "name": "Silicone", - "type": "Elastomer" - }, - "percentage": 81.8, - "mass": 2.84, - "unit": "kg" - } - ], - "components": [ - { - "id": 841, - "name": "Iron Component 1", - "description": "High-quality part for iron functionality" - }, - { - "id": 842, - "name": "Iron Component 2", - "description": "High-quality part for iron functionality" - }, - { - "id": 843, - "name": "Iron Component 3", - "description": "High-quality part for iron functionality" - } - ], - "images": [ - { - "id": 84, - "url": "https://via.placeholder.com/400x300/020ecf/ffffff?text=AquaPro+Iron+426H", - "description": "Iron product image" - } - ], - "created_at": "2024-08-14T09:16:11.452584Z", - "updated_at": "2025-07-15T09:16:11.452584Z" - }, - { - "id": 85, - "name": "EcoTech Humidifier 407F", - "description": "EcoTech Humidifier 407F is a high-performance humidifier designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 1, - "name": "Kitchen Appliance" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 2.92, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 32.6, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 16.1, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 1692, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 7.6, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 5.5, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 9.6, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 1, - "name": "Stainless Steel", - "type": "Metal" - }, - "percentage": 48.6, - "mass": 0.52, - "unit": "kg" - }, - { - "material": { - "id": 2, - "name": "ABS Plastic", - "type": "Plastic" - }, - "percentage": 51.4, - "mass": 0.6, - "unit": "kg" - } - ], - "components": [ - { - "id": 851, - "name": "Humidifier Component 1", - "description": "High-quality part for humidifier functionality" - }, - { - "id": 852, - "name": "Humidifier Component 2", - "description": "High-quality part for humidifier functionality" - }, - { - "id": 853, - "name": "Humidifier Component 3", - "description": "High-quality part for humidifier functionality" - }, - { - "id": 854, - "name": "Humidifier Component 4", - "description": "High-quality part for humidifier functionality" - }, - { - "id": 855, - "name": "Humidifier Component 5", - "description": "High-quality part for humidifier functionality" - } - ], - "images": [ - { - "id": 85, - "url": "https://via.placeholder.com/400x300/05ddbf/ffffff?text=EcoTech+Humidifier+407F", - "description": "Humidifier product image" - } - ], - "created_at": "2025-02-25T09:16:11.452617Z", - "updated_at": "2025-06-10T09:16:11.452617Z" - }, - { - "id": 86, - "name": "ZenGear Toaster 287I", - "description": "ZenGear Toaster 287I is a high-performance toaster designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 5, - "name": "Office Equipment" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 2.77, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 28.1, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 20.5, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 1830, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 8.4, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 6.6, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 6.3, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 2, - "name": "ABS Plastic", - "type": "Plastic" - }, - "percentage": 60.6, - "mass": 2.2, - "unit": "kg" - }, - { - "material": { - "id": 3, - "name": "Copper Wire", - "type": "Metal" - }, - "percentage": 39.4, - "mass": 0.66, - "unit": "kg" - } - ], - "components": [ - { - "id": 861, - "name": "Toaster Component 1", - "description": "High-quality part for toaster functionality" - }, - { - "id": 862, - "name": "Toaster Component 2", - "description": "High-quality part for toaster functionality" - } - ], - "images": [ - { - "id": 86, - "url": "https://via.placeholder.com/400x300/04ea76/ffffff?text=ZenGear+Toaster+287I", - "description": "Toaster product image" - } - ], - "created_at": "2024-10-24T09:16:11.452644Z", - "updated_at": "2025-07-26T09:16:11.452644Z" - }, - { - "id": 87, - "name": "EcoTech Monitor 837D", - "description": "EcoTech Monitor 837D is a high-performance monitor designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 1, - "name": "Kitchen Appliance" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 1.08, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 30.3, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 19.1, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 1779, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 8.9, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 5.7, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 8.4, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 7, - "name": "Silicone", - "type": "Elastomer" - }, - "percentage": 58.3, - "mass": 1.99, - "unit": "kg" - }, - { - "material": { - "id": 3, - "name": "Copper Wire", - "type": "Metal" - }, - "percentage": 41.7, - "mass": 1.37, - "unit": "kg" - } - ], - "components": [ - { - "id": 871, - "name": "Monitor Component 1", - "description": "High-quality part for monitor functionality" - }, - { - "id": 872, - "name": "Monitor Component 2", - "description": "High-quality part for monitor functionality" - }, - { - "id": 873, - "name": "Monitor Component 3", - "description": "High-quality part for monitor functionality" - }, - { - "id": 874, - "name": "Monitor Component 4", - "description": "High-quality part for monitor functionality" - } - ], - "images": [ - { - "id": 87, - "url": "https://via.placeholder.com/400x300/0dc27f/ffffff?text=EcoTech+Monitor+837D", - "description": "Monitor product image" - } - ], - "created_at": "2024-05-28T09:16:11.452675Z", - "updated_at": "2025-06-24T09:16:11.452675Z" - }, - { - "id": 88, - "name": "PureLife Iron 727S", - "description": "PureLife Iron 727S is a high-performance iron designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 2, - "name": "Home Electronics" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 3.5, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 28.7, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 15.8, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 1529, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 7.6, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 8.8, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 6.6, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 2, - "name": "ABS Plastic", - "type": "Plastic" - }, - "percentage": 37.3, - "mass": 1.16, - "unit": "kg" - }, - { - "material": { - "id": 1, - "name": "Stainless Steel", - "type": "Metal" - }, - "percentage": 13.6, - "mass": 0.33, - "unit": "kg" - }, - { - "material": { - "id": 3, - "name": "Copper Wire", - "type": "Metal" - }, - "percentage": 18.2, - "mass": 0.73, - "unit": "kg" - }, - { - "material": { - "id": 4, - "name": "Mica", - "type": "Mineral" - }, - "percentage": 30.9, - "mass": 0.54, - "unit": "kg" - } - ], - "components": [ - { - "id": 881, - "name": "Iron Component 1", - "description": "High-quality part for iron functionality" - }, - { - "id": 882, - "name": "Iron Component 2", - "description": "High-quality part for iron functionality" - } - ], - "images": [ - { - "id": 88, - "url": "https://via.placeholder.com/400x300/0aaeaf/ffffff?text=PureLife+Iron+727S", - "description": "Iron product image" - } - ], - "created_at": "2025-03-04T09:16:11.452707Z", - "updated_at": "2025-06-22T09:16:11.452707Z" - }, - { - "id": 89, - "name": "PureLife Monitor 709R", - "description": "PureLife Monitor 709R is a high-performance monitor designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 5, - "name": "Office Equipment" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 3.18, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 32.6, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 18.9, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 1418, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 8.4, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 5.6, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 9.5, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 1, - "name": "Stainless Steel", - "type": "Metal" - }, - "percentage": 19.4, - "mass": 0.48, - "unit": "kg" - }, - { - "material": { - "id": 4, - "name": "Mica", - "type": "Mineral" - }, - "percentage": 40.3, - "mass": 0.81, - "unit": "kg" - }, - { - "material": { - "id": 5, - "name": "Borosilicate Glass", - "type": "Glass" - }, - "percentage": 40.3, - "mass": 0.55, - "unit": "kg" - } - ], - "components": [ - { - "id": 891, - "name": "Monitor Component 1", - "description": "High-quality part for monitor functionality" - }, - { - "id": 892, - "name": "Monitor Component 2", - "description": "High-quality part for monitor functionality" - }, - { - "id": 893, - "name": "Monitor Component 3", - "description": "High-quality part for monitor functionality" - }, - { - "id": 894, - "name": "Monitor Component 4", - "description": "High-quality part for monitor functionality" - }, - { - "id": 895, - "name": "Monitor Component 5", - "description": "High-quality part for monitor functionality" - } - ], - "images": [ - { - "id": 89, - "url": "https://via.placeholder.com/400x300/054ec8/ffffff?text=PureLife+Monitor+709R", - "description": "Monitor product image" - } - ], - "created_at": "2024-10-20T09:16:11.452738Z", - "updated_at": "2025-06-27T09:16:11.452738Z" - }, - { - "id": 90, - "name": "SmartHome Kettle 786V", - "description": "SmartHome Kettle 786V is a high-performance kettle designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 5, - "name": "Office Equipment" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 2.67, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 26.5, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 27.7, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 1169, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 7.4, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 6.3, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 10.0, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 2, - "name": "ABS Plastic", - "type": "Plastic" - }, - "percentage": 32.2, - "mass": 1.25, - "unit": "kg" - }, - { - "material": { - "id": 5, - "name": "Borosilicate Glass", - "type": "Glass" - }, - "percentage": 32.2, - "mass": 0.94, - "unit": "kg" - }, - { - "material": { - "id": 6, - "name": "Polypropylene", - "type": "Plastic" - }, - "percentage": 13.5, - "mass": 0.53, - "unit": "kg" - }, - { - "material": { - "id": 4, - "name": "Mica", - "type": "Mineral" - }, - "percentage": 22.2, - "mass": 0.83, - "unit": "kg" - } - ], - "components": [ - { - "id": 901, - "name": "Kettle Component 1", - "description": "High-quality part for kettle functionality" - }, - { - "id": 902, - "name": "Kettle Component 2", - "description": "High-quality part for kettle functionality" - }, - { - "id": 903, - "name": "Kettle Component 3", - "description": "High-quality part for kettle functionality" - }, - { - "id": 904, - "name": "Kettle Component 4", - "description": "High-quality part for kettle functionality" - }, - { - "id": 905, - "name": "Kettle Component 5", - "description": "High-quality part for kettle functionality" - } - ], - "images": [ - { - "id": 90, - "url": "https://via.placeholder.com/400x300/0a3e25/ffffff?text=SmartHome+Kettle+786V", - "description": "Kettle product image" - } - ], - "created_at": "2025-01-08T09:16:11.452771Z", - "updated_at": "2025-06-16T09:16:11.452771Z" - }, - { - "id": 91, - "name": "ChefMate Fan 942H", - "description": "ChefMate Fan 942H is a high-performance fan designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 2, - "name": "Home Electronics" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 1.46, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 22.1, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 28.0, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 1299, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 8.1, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 5.2, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 9.9, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 5, - "name": "Borosilicate Glass", - "type": "Glass" - }, - "percentage": 20.8, - "mass": 0.3, - "unit": "kg" - }, - { - "material": { - "id": 4, - "name": "Mica", - "type": "Mineral" - }, - "percentage": 79.2, - "mass": 2.1, - "unit": "kg" - } - ], - "components": [ - { - "id": 911, - "name": "Fan Component 1", - "description": "High-quality part for fan functionality" - }, - { - "id": 912, - "name": "Fan Component 2", - "description": "High-quality part for fan functionality" - }, - { - "id": 913, - "name": "Fan Component 3", - "description": "High-quality part for fan functionality" - } - ], - "images": [ - { - "id": 91, - "url": "https://via.placeholder.com/400x300/0c2c51/ffffff?text=ChefMate+Fan+942H", - "description": "Fan product image" - } - ], - "created_at": "2024-11-15T09:16:11.452799Z", - "updated_at": "2025-06-14T09:16:11.452799Z" - }, - { - "id": 92, - "name": "NeoCook Coffee Maker 473K", - "description": "NeoCook Coffee Maker 473K is a high-performance coffee maker designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 5, - "name": "Office Equipment" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 2.71, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 31.9, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 15.4, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 1991, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 6.7, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 5.6, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 9.0, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 1, - "name": "Stainless Steel", - "type": "Metal" - }, - "percentage": 24.7, - "mass": 0.91, - "unit": "kg" - }, - { - "material": { - "id": 4, - "name": "Mica", - "type": "Mineral" - }, - "percentage": 25.3, - "mass": 0.68, - "unit": "kg" - }, - { - "material": { - "id": 2, - "name": "ABS Plastic", - "type": "Plastic" - }, - "percentage": 28.2, - "mass": 0.92, - "unit": "kg" - }, - { - "material": { - "id": 7, - "name": "Silicone", - "type": "Elastomer" - }, - "percentage": 21.8, - "mass": 0.41, - "unit": "kg" - } - ], - "components": [ - { - "id": 921, - "name": "Coffee Maker Component 1", - "description": "High-quality part for coffee maker functionality" - }, - { - "id": 922, - "name": "Coffee Maker Component 2", - "description": "High-quality part for coffee maker functionality" - } - ], - "images": [ - { - "id": 92, - "url": "https://via.placeholder.com/400x300/028c87/ffffff?text=NeoCook+Coffee+Maker+473K", - "description": "Coffee Maker product image" - } - ], - "created_at": "2024-03-26T09:16:11.452845Z", - "updated_at": "2025-07-08T09:16:11.452845Z" - }, - { - "id": 93, - "name": "ChefMate Fan 200G", - "description": "ChefMate Fan 200G is a high-performance fan designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 1, - "name": "Kitchen Appliance" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 3.01, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 26.6, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 24.5, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 1998, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 6.3, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 5.9, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 9.7, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 5, - "name": "Borosilicate Glass", - "type": "Glass" - }, - "percentage": 40.5, - "mass": 0.47, - "unit": "kg" - }, - { - "material": { - "id": 7, - "name": "Silicone", - "type": "Elastomer" - }, - "percentage": 36.2, - "mass": 0.91, - "unit": "kg" - }, - { - "material": { - "id": 4, - "name": "Mica", - "type": "Mineral" - }, - "percentage": 23.3, - "mass": 0.51, - "unit": "kg" - } - ], - "components": [ - { - "id": 931, - "name": "Fan Component 1", - "description": "High-quality part for fan functionality" - }, - { - "id": 932, - "name": "Fan Component 2", - "description": "High-quality part for fan functionality" - } - ], - "images": [ - { - "id": 93, - "url": "https://via.placeholder.com/400x300/0b4781/ffffff?text=ChefMate+Fan+200G", - "description": "Fan product image" - } - ], - "created_at": "2025-02-11T09:16:11.452979Z", - "updated_at": "2025-06-17T09:16:11.452979Z" - }, - { - "id": 94, - "name": "CleanWave Coffee Maker 693H", - "description": "CleanWave Coffee Maker 693H is a high-performance coffee maker designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 5, - "name": "Office Equipment" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 3.39, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 31.4, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 17.2, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 1061, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 7.2, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 8.8, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 7.0, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 6, - "name": "Polypropylene", - "type": "Plastic" - }, - "percentage": 52.2, - "mass": 1.01, - "unit": "kg" - }, - { - "material": { - "id": 5, - "name": "Borosilicate Glass", - "type": "Glass" - }, - "percentage": 30.4, - "mass": 0.37, - "unit": "kg" - }, - { - "material": { - "id": 7, - "name": "Silicone", - "type": "Elastomer" - }, - "percentage": 17.4, - "mass": 0.64, - "unit": "kg" - } - ], - "components": [ - { - "id": 941, - "name": "Coffee Maker Component 1", - "description": "High-quality part for coffee maker functionality" - }, - { - "id": 942, - "name": "Coffee Maker Component 2", - "description": "High-quality part for coffee maker functionality" - } - ], - "images": [ - { - "id": 94, - "url": "https://via.placeholder.com/400x300/078609/ffffff?text=CleanWave+Coffee+Maker+693H", - "description": "Coffee Maker product image" - } - ], - "created_at": "2025-01-16T09:16:11.453014Z", - "updated_at": "2025-05-26T09:16:11.453014Z" - }, - { - "id": 95, - "name": "CleanWave Air Purifier 565A", - "description": "CleanWave Air Purifier 565A is a high-performance air purifier designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 3, - "name": "Personal Care Device" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 3.49, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 20.0, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 30.0, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 1724, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 9.5, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 7.7, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 6.3, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 2, - "name": "ABS Plastic", - "type": "Plastic" - }, - "percentage": 34.5, - "mass": 1.37, - "unit": "kg" - }, - { - "material": { - "id": 4, - "name": "Mica", - "type": "Mineral" - }, - "percentage": 36.6, - "mass": 0.51, - "unit": "kg" - }, - { - "material": { - "id": 3, - "name": "Copper Wire", - "type": "Metal" - }, - "percentage": 28.9, - "mass": 0.73, - "unit": "kg" - } - ], - "components": [ - { - "id": 951, - "name": "Air Purifier Component 1", - "description": "High-quality part for air purifier functionality" - }, - { - "id": 952, - "name": "Air Purifier Component 2", - "description": "High-quality part for air purifier functionality" - }, - { - "id": 953, - "name": "Air Purifier Component 3", - "description": "High-quality part for air purifier functionality" - }, - { - "id": 954, - "name": "Air Purifier Component 4", - "description": "High-quality part for air purifier functionality" - } - ], - "images": [ - { - "id": 95, - "url": "https://via.placeholder.com/400x300/0488b4/ffffff?text=CleanWave+Air+Purifier+565A", - "description": "Air Purifier product image" - } - ], - "created_at": "2024-07-09T09:16:11.453047Z", - "updated_at": "2025-07-17T09:16:11.453047Z" - }, - { - "id": 96, - "name": "ZenGear Monitor 993I", - "description": "ZenGear Monitor 993I is a high-performance monitor designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 3, - "name": "Personal Care Device" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 2.0, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 23.8, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 27.8, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 1664, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 7.4, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 8.9, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 9.9, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 5, - "name": "Borosilicate Glass", - "type": "Glass" - }, - "percentage": 20.9, - "mass": 0.71, - "unit": "kg" - }, - { - "material": { - "id": 7, - "name": "Silicone", - "type": "Elastomer" - }, - "percentage": 15.1, - "mass": 0.6, - "unit": "kg" - }, - { - "material": { - "id": 1, - "name": "Stainless Steel", - "type": "Metal" - }, - "percentage": 39.6, - "mass": 1.14, - "unit": "kg" - }, - { - "material": { - "id": 2, - "name": "ABS Plastic", - "type": "Plastic" - }, - "percentage": 24.5, - "mass": 0.48, - "unit": "kg" - } - ], - "components": [ - { - "id": 961, - "name": "Monitor Component 1", - "description": "High-quality part for monitor functionality" - }, - { - "id": 962, - "name": "Monitor Component 2", - "description": "High-quality part for monitor functionality" - }, - { - "id": 963, - "name": "Monitor Component 3", - "description": "High-quality part for monitor functionality" - } - ], - "images": [ - { - "id": 96, - "url": "https://via.placeholder.com/400x300/0ac1a9/ffffff?text=ZenGear+Monitor+993I", - "description": "Monitor product image" - } - ], - "created_at": "2024-08-31T09:16:11.453082Z", - "updated_at": "2025-07-07T09:16:11.453082Z" - }, - { - "id": 97, - "name": "SmartHome Humidifier 193Z", - "description": "SmartHome Humidifier 193Z is a high-performance humidifier designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 4, - "name": "Smart Home Device" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 1.31, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 21.6, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 20.3, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 1245, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 9.0, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 5.1, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 7.0, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 4, - "name": "Mica", - "type": "Mineral" - }, - "percentage": 40.4, - "mass": 0.88, - "unit": "kg" - }, - { - "material": { - "id": 7, - "name": "Silicone", - "type": "Elastomer" - }, - "percentage": 30.8, - "mass": 0.37, - "unit": "kg" - }, - { - "material": { - "id": 3, - "name": "Copper Wire", - "type": "Metal" - }, - "percentage": 13.0, - "mass": 0.46, - "unit": "kg" - }, - { - "material": { - "id": 5, - "name": "Borosilicate Glass", - "type": "Glass" - }, - "percentage": 15.8, - "mass": 0.48, - "unit": "kg" - } - ], - "components": [ - { - "id": 971, - "name": "Humidifier Component 1", - "description": "High-quality part for humidifier functionality" - }, - { - "id": 972, - "name": "Humidifier Component 2", - "description": "High-quality part for humidifier functionality" - } - ], - "images": [ - { - "id": 97, - "url": "https://via.placeholder.com/400x300/0a16c7/ffffff?text=SmartHome+Humidifier+193Z", - "description": "Humidifier product image" - } - ], - "created_at": "2025-02-10T09:16:11.453132Z", - "updated_at": "2025-06-12T09:16:11.453132Z" - }, - { - "id": 98, - "name": "AquaPro Coffee Maker 128R", - "description": "AquaPro Coffee Maker 128R is a high-performance coffee maker designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 5, - "name": "Office Equipment" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 3.08, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 33.0, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 29.1, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 2131, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 6.4, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 5.6, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 6.3, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 5, - "name": "Borosilicate Glass", - "type": "Glass" - }, - "percentage": 53.4, - "mass": 0.69, - "unit": "kg" - }, - { - "material": { - "id": 7, - "name": "Silicone", - "type": "Elastomer" - }, - "percentage": 27.6, - "mass": 1.08, - "unit": "kg" - }, - { - "material": { - "id": 3, - "name": "Copper Wire", - "type": "Metal" - }, - "percentage": 19.0, - "mass": 0.56, - "unit": "kg" - } - ], - "components": [ - { - "id": 981, - "name": "Coffee Maker Component 1", - "description": "High-quality part for coffee maker functionality" - }, - { - "id": 982, - "name": "Coffee Maker Component 2", - "description": "High-quality part for coffee maker functionality" - }, - { - "id": 983, - "name": "Coffee Maker Component 3", - "description": "High-quality part for coffee maker functionality" - } - ], - "images": [ - { - "id": 98, - "url": "https://via.placeholder.com/400x300/05e3b0/ffffff?text=AquaPro+Coffee+Maker+128R", - "description": "Coffee Maker product image" - } - ], - "created_at": "2024-10-13T09:16:11.453186Z", - "updated_at": "2025-05-27T09:16:11.453186Z" - }, - { - "id": 99, - "name": "ChefMate Kettle 864I", - "description": "ChefMate Kettle 864I is a high-performance kettle designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 5, - "name": "Office Equipment" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 3.52, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 27.6, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 28.1, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 1265, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 7.0, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 6.4, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 6.7, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 2, - "name": "ABS Plastic", - "type": "Plastic" - }, - "percentage": 20.0, - "mass": 0.67, - "unit": "kg" - }, - { - "material": { - "id": 7, - "name": "Silicone", - "type": "Elastomer" - }, - "percentage": 38.4, - "mass": 1.25, - "unit": "kg" - }, - { - "material": { - "id": 4, - "name": "Mica", - "type": "Mineral" - }, - "percentage": 41.6, - "mass": 1.24, - "unit": "kg" - } - ], - "components": [ - { - "id": 991, - "name": "Kettle Component 1", - "description": "High-quality part for kettle functionality" - }, - { - "id": 992, - "name": "Kettle Component 2", - "description": "High-quality part for kettle functionality" - }, - { - "id": 993, - "name": "Kettle Component 3", - "description": "High-quality part for kettle functionality" - }, - { - "id": 994, - "name": "Kettle Component 4", - "description": "High-quality part for kettle functionality" - } - ], - "images": [ - { - "id": 99, - "url": "https://via.placeholder.com/400x300/022bcc/ffffff?text=ChefMate+Kettle+864I", - "description": "Kettle product image" - } - ], - "created_at": "2024-11-09T09:16:11.453220Z", - "updated_at": "2025-06-20T09:16:11.453220Z" - }, - { - "id": 100, - "name": "CleanWave Humidifier 149T", - "description": "CleanWave Humidifier 149T is a high-performance humidifier designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 5, - "name": "Office Equipment" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 2.11, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 29.7, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 19.8, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 1658, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 7.9, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 7.6, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 6.9, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 1, - "name": "Stainless Steel", - "type": "Metal" - }, - "percentage": 13.7, - "mass": 0.48, - "unit": "kg" - }, - { - "material": { - "id": 5, - "name": "Borosilicate Glass", - "type": "Glass" - }, - "percentage": 35.9, - "mass": 1.05, - "unit": "kg" - }, - { - "material": { - "id": 3, - "name": "Copper Wire", - "type": "Metal" - }, - "percentage": 40.5, - "mass": 1.42, - "unit": "kg" - }, - { - "material": { - "id": 2, - "name": "ABS Plastic", - "type": "Plastic" - }, - "percentage": 9.9, - "mass": 0.24, - "unit": "kg" - } - ], - "components": [ - { - "id": 1001, - "name": "Humidifier Component 1", - "description": "High-quality part for humidifier functionality" - }, - { - "id": 1002, - "name": "Humidifier Component 2", - "description": "High-quality part for humidifier functionality" - }, - { - "id": 1003, - "name": "Humidifier Component 3", - "description": "High-quality part for humidifier functionality" - }, - { - "id": 1004, - "name": "Humidifier Component 4", - "description": "High-quality part for humidifier functionality" - }, - { - "id": 1005, - "name": "Humidifier Component 5", - "description": "High-quality part for humidifier functionality" - } - ], - "images": [ - { - "id": 100, - "url": "https://via.placeholder.com/400x300/0a7255/ffffff?text=CleanWave+Humidifier+149T", - "description": "Humidifier product image" - } - ], - "created_at": "2024-08-31T09:16:11.453256Z", - "updated_at": "2025-07-04T09:16:11.453256Z" - }, - { - "id": 101, - "name": "PureLife Blender 932O", - "description": "PureLife Blender 932O is a high-performance blender designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 4, - "name": "Smart Home Device" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 3.78, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 34.6, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 26.5, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 2114, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 6.9, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 6.0, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 8.6, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 1, - "name": "Stainless Steel", - "type": "Metal" - }, - "percentage": 22.0, - "mass": 0.28, - "unit": "kg" - }, - { - "material": { - "id": 6, - "name": "Polypropylene", - "type": "Plastic" - }, - "percentage": 78.0, - "mass": 1.21, - "unit": "kg" - } - ], - "components": [ - { - "id": 1011, - "name": "Blender Component 1", - "description": "High-quality part for blender functionality" - }, - { - "id": 1012, - "name": "Blender Component 2", - "description": "High-quality part for blender functionality" - }, - { - "id": 1013, - "name": "Blender Component 3", - "description": "High-quality part for blender functionality" - } - ], - "images": [ - { - "id": 101, - "url": "https://via.placeholder.com/400x300/0876c7/ffffff?text=PureLife+Blender+932O", - "description": "Blender product image" - } - ], - "created_at": "2024-06-09T09:16:11.453285Z", - "updated_at": "2025-06-21T09:16:11.453285Z" - }, - { - "id": 102, - "name": "EcoTech Coffee Maker 859H", - "description": "EcoTech Coffee Maker 859H is a high-performance coffee maker designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 2, - "name": "Home Electronics" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 1.0, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 25.1, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 25.3, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 1521, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 9.4, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 8.1, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 6.0, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 2, - "name": "ABS Plastic", - "type": "Plastic" - }, - "percentage": 28.7, - "mass": 1.07, - "unit": "kg" - }, - { - "material": { - "id": 4, - "name": "Mica", - "type": "Mineral" - }, - "percentage": 71.2, - "mass": 1.37, - "unit": "kg" - } - ], - "components": [ - { - "id": 1021, - "name": "Coffee Maker Component 1", - "description": "High-quality part for coffee maker functionality" - }, - { - "id": 1022, - "name": "Coffee Maker Component 2", - "description": "High-quality part for coffee maker functionality" - }, - { - "id": 1023, - "name": "Coffee Maker Component 3", - "description": "High-quality part for coffee maker functionality" - } - ], - "images": [ - { - "id": 102, - "url": "https://via.placeholder.com/400x300/0495ec/ffffff?text=EcoTech+Coffee+Maker+859H", - "description": "Coffee Maker product image" - } - ], - "created_at": "2024-12-03T09:16:11.453315Z", - "updated_at": "2025-06-14T09:16:11.453315Z" - }, - { - "id": 103, - "name": "NeoCook Coffee Maker 171A", - "description": "NeoCook Coffee Maker 171A is a high-performance coffee maker designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 3, - "name": "Personal Care Device" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 2.03, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 30.5, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 25.9, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 1065, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 8.6, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 5.2, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 6.5, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 3, - "name": "Copper Wire", - "type": "Metal" - }, - "percentage": 18.5, - "mass": 0.53, - "unit": "kg" - }, - { - "material": { - "id": 2, - "name": "ABS Plastic", - "type": "Plastic" - }, - "percentage": 23.6, - "mass": 0.45, - "unit": "kg" - }, - { - "material": { - "id": 4, - "name": "Mica", - "type": "Mineral" - }, - "percentage": 29.8, - "mass": 1.01, - "unit": "kg" - }, - { - "material": { - "id": 7, - "name": "Silicone", - "type": "Elastomer" - }, - "percentage": 28.1, - "mass": 0.42, - "unit": "kg" - } - ], - "components": [ - { - "id": 1031, - "name": "Coffee Maker Component 1", - "description": "High-quality part for coffee maker functionality" - }, - { - "id": 1032, - "name": "Coffee Maker Component 2", - "description": "High-quality part for coffee maker functionality" - }, - { - "id": 1033, - "name": "Coffee Maker Component 3", - "description": "High-quality part for coffee maker functionality" - }, - { - "id": 1034, - "name": "Coffee Maker Component 4", - "description": "High-quality part for coffee maker functionality" - }, - { - "id": 1035, - "name": "Coffee Maker Component 5", - "description": "High-quality part for coffee maker functionality" - } - ], - "images": [ - { - "id": 103, - "url": "https://via.placeholder.com/400x300/0c248e/ffffff?text=NeoCook+Coffee+Maker+171A", - "description": "Coffee Maker product image" - } - ], - "created_at": "2025-02-18T09:16:11.453348Z", - "updated_at": "2025-06-26T09:16:11.453348Z" - }, - { - "id": 104, - "name": "SmartHome Rice Cooker 419U", - "description": "SmartHome Rice Cooker 419U is a high-performance rice cooker designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 1, - "name": "Kitchen Appliance" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 3.33, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 34.3, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 21.0, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 1217, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 9.1, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 7.0, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 9.7, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 3, - "name": "Copper Wire", - "type": "Metal" - }, - "percentage": 11.9, - "mass": 0.13, - "unit": "kg" - }, - { - "material": { - "id": 5, - "name": "Borosilicate Glass", - "type": "Glass" - }, - "percentage": 24.6, - "mass": 0.59, - "unit": "kg" - }, - { - "material": { - "id": 6, - "name": "Polypropylene", - "type": "Plastic" - }, - "percentage": 41.0, - "mass": 1.55, - "unit": "kg" - }, - { - "material": { - "id": 4, - "name": "Mica", - "type": "Mineral" - }, - "percentage": 22.4, - "mass": 0.51, - "unit": "kg" - } - ], - "components": [ - { - "id": 1041, - "name": "Rice Cooker Component 1", - "description": "High-quality part for rice cooker functionality" - }, - { - "id": 1042, - "name": "Rice Cooker Component 2", - "description": "High-quality part for rice cooker functionality" - }, - { - "id": 1043, - "name": "Rice Cooker Component 3", - "description": "High-quality part for rice cooker functionality" - }, - { - "id": 1044, - "name": "Rice Cooker Component 4", - "description": "High-quality part for rice cooker functionality" - }, - { - "id": 1045, - "name": "Rice Cooker Component 5", - "description": "High-quality part for rice cooker functionality" - } - ], - "images": [ - { - "id": 104, - "url": "https://via.placeholder.com/400x300/0899aa/ffffff?text=SmartHome+Rice+Cooker+419U", - "description": "Rice Cooker product image" - } - ], - "created_at": "2024-12-14T09:16:11.453381Z", - "updated_at": "2025-05-01T09:16:11.453381Z" - }, - { - "id": 105, - "name": "AquaPro Air Purifier 306F", - "description": "AquaPro Air Purifier 306F is a high-performance air purifier designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 1, - "name": "Kitchen Appliance" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 2.05, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 26.6, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 28.3, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 1472, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 8.2, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 6.9, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 8.7, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 6, - "name": "Polypropylene", - "type": "Plastic" - }, - "percentage": 18.4, - "mass": 0.23, - "unit": "kg" - }, - { - "material": { - "id": 3, - "name": "Copper Wire", - "type": "Metal" - }, - "percentage": 16.1, - "mass": 0.62, - "unit": "kg" - }, - { - "material": { - "id": 2, - "name": "ABS Plastic", - "type": "Plastic" - }, - "percentage": 36.8, - "mass": 1.43, - "unit": "kg" - }, - { - "material": { - "id": 4, - "name": "Mica", - "type": "Mineral" - }, - "percentage": 28.7, - "mass": 0.72, - "unit": "kg" - } - ], - "components": [ - { - "id": 1051, - "name": "Air Purifier Component 1", - "description": "High-quality part for air purifier functionality" - }, - { - "id": 1052, - "name": "Air Purifier Component 2", - "description": "High-quality part for air purifier functionality" - }, - { - "id": 1053, - "name": "Air Purifier Component 3", - "description": "High-quality part for air purifier functionality" - } - ], - "images": [ - { - "id": 105, - "url": "https://via.placeholder.com/400x300/0eaa70/ffffff?text=AquaPro+Air+Purifier+306F", - "description": "Air Purifier product image" - } - ], - "created_at": "2024-10-30T09:16:11.453413Z", - "updated_at": "2025-07-09T09:16:11.453413Z" - }, - { - "id": 106, - "name": "PureLife Iron 428F", - "description": "PureLife Iron 428F is a high-performance iron designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 3, - "name": "Personal Care Device" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 3.03, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 29.5, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 29.9, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 1605, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 7.5, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 6.9, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 8.1, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 5, - "name": "Borosilicate Glass", - "type": "Glass" - }, - "percentage": 75.0, - "mass": 1.13, - "unit": "kg" - }, - { - "material": { - "id": 1, - "name": "Stainless Steel", - "type": "Metal" - }, - "percentage": 25.0, - "mass": 0.7, - "unit": "kg" - } - ], - "components": [ - { - "id": 1061, - "name": "Iron Component 1", - "description": "High-quality part for iron functionality" - }, - { - "id": 1062, - "name": "Iron Component 2", - "description": "High-quality part for iron functionality" - } - ], - "images": [ - { - "id": 106, - "url": "https://via.placeholder.com/400x300/070382/ffffff?text=PureLife+Iron+428F", - "description": "Iron product image" - } - ], - "created_at": "2025-04-13T09:16:11.453442Z", - "updated_at": "2025-06-16T09:16:11.453442Z" - }, - { - "id": 107, - "name": "SmartHome Rice Cooker 782J", - "description": "SmartHome Rice Cooker 782J is a high-performance rice cooker designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 1, - "name": "Kitchen Appliance" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 3.75, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 27.3, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 21.3, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 2091, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 7.8, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 5.8, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 7.8, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 3, - "name": "Copper Wire", - "type": "Metal" - }, - "percentage": 33.3, - "mass": 0.79, - "unit": "kg" - }, - { - "material": { - "id": 4, - "name": "Mica", - "type": "Mineral" - }, - "percentage": 46.7, - "mass": 0.5, - "unit": "kg" - }, - { - "material": { - "id": 1, - "name": "Stainless Steel", - "type": "Metal" - }, - "percentage": 20.0, - "mass": 0.38, - "unit": "kg" - } - ], - "components": [ - { - "id": 1071, - "name": "Rice Cooker Component 1", - "description": "High-quality part for rice cooker functionality" - }, - { - "id": 1072, - "name": "Rice Cooker Component 2", - "description": "High-quality part for rice cooker functionality" - }, - { - "id": 1073, - "name": "Rice Cooker Component 3", - "description": "High-quality part for rice cooker functionality" - }, - { - "id": 1074, - "name": "Rice Cooker Component 4", - "description": "High-quality part for rice cooker functionality" - } - ], - "images": [ - { - "id": 107, - "url": "https://via.placeholder.com/400x300/0676cc/ffffff?text=SmartHome+Rice+Cooker+782J", - "description": "Rice Cooker product image" - } - ], - "created_at": "2024-05-27T09:16:11.453488Z", - "updated_at": "2025-06-09T09:16:11.453488Z" - }, - { - "id": 108, - "name": "ZenGear Blender 351S", - "description": "ZenGear Blender 351S is a high-performance blender designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 2, - "name": "Home Electronics" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 2.12, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 26.8, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 22.7, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 1460, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 9.4, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 6.6, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 6.9, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 2, - "name": "ABS Plastic", - "type": "Plastic" - }, - "percentage": 35.0, - "mass": 1.22, - "unit": "kg" - }, - { - "material": { - "id": 4, - "name": "Mica", - "type": "Mineral" - }, - "percentage": 18.3, - "mass": 0.71, - "unit": "kg" - }, - { - "material": { - "id": 7, - "name": "Silicone", - "type": "Elastomer" - }, - "percentage": 11.7, - "mass": 0.42, - "unit": "kg" - }, - { - "material": { - "id": 3, - "name": "Copper Wire", - "type": "Metal" - }, - "percentage": 35.0, - "mass": 0.97, - "unit": "kg" - } - ], - "components": [ - { - "id": 1081, - "name": "Blender Component 1", - "description": "High-quality part for blender functionality" - }, - { - "id": 1082, - "name": "Blender Component 2", - "description": "High-quality part for blender functionality" - } - ], - "images": [ - { - "id": 108, - "url": "https://via.placeholder.com/400x300/0b229f/ffffff?text=ZenGear+Blender+351S", - "description": "Blender product image" - } - ], - "created_at": "2024-12-18T09:16:11.453527Z", - "updated_at": "2025-07-14T09:16:11.453527Z" - }, - { - "id": 109, - "name": "ZenGear Rice Cooker 350F", - "description": "ZenGear Rice Cooker 350F is a high-performance rice cooker designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 3, - "name": "Personal Care Device" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 1.94, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 22.8, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 18.2, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 950, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 6.5, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 6.9, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 9.1, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 7, - "name": "Silicone", - "type": "Elastomer" - }, - "percentage": 51.5, - "mass": 1.8, - "unit": "kg" - }, - { - "material": { - "id": 6, - "name": "Polypropylene", - "type": "Plastic" - }, - "percentage": 48.5, - "mass": 1.33, - "unit": "kg" - } - ], - "components": [ - { - "id": 1091, - "name": "Rice Cooker Component 1", - "description": "High-quality part for rice cooker functionality" - }, - { - "id": 1092, - "name": "Rice Cooker Component 2", - "description": "High-quality part for rice cooker functionality" - }, - { - "id": 1093, - "name": "Rice Cooker Component 3", - "description": "High-quality part for rice cooker functionality" - }, - { - "id": 1094, - "name": "Rice Cooker Component 4", - "description": "High-quality part for rice cooker functionality" - }, - { - "id": 1095, - "name": "Rice Cooker Component 5", - "description": "High-quality part for rice cooker functionality" - } - ], - "images": [ - { - "id": 109, - "url": "https://via.placeholder.com/400x300/0312f6/ffffff?text=ZenGear+Rice+Cooker+350F", - "description": "Rice Cooker product image" - } - ], - "created_at": "2024-09-26T09:16:11.453560Z", - "updated_at": "2025-05-02T09:16:11.453560Z" - }, - { - "id": 110, - "name": "NeoCook Blender 666A", - "description": "NeoCook Blender 666A is a high-performance blender designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 5, - "name": "Office Equipment" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 1.89, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 27.7, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 28.9, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 1205, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 9.2, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 8.8, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 8.7, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 6, - "name": "Polypropylene", - "type": "Plastic" - }, - "percentage": 34.1, - "mass": 0.46, - "unit": "kg" - }, - { - "material": { - "id": 3, - "name": "Copper Wire", - "type": "Metal" - }, - "percentage": 65.9, - "mass": 1.82, - "unit": "kg" - } - ], - "components": [ - { - "id": 1101, - "name": "Blender Component 1", - "description": "High-quality part for blender functionality" - }, - { - "id": 1102, - "name": "Blender Component 2", - "description": "High-quality part for blender functionality" - }, - { - "id": 1103, - "name": "Blender Component 3", - "description": "High-quality part for blender functionality" - }, - { - "id": 1104, - "name": "Blender Component 4", - "description": "High-quality part for blender functionality" - }, - { - "id": 1105, - "name": "Blender Component 5", - "description": "High-quality part for blender functionality" - } - ], - "images": [ - { - "id": 110, - "url": "https://via.placeholder.com/400x300/0204bc/ffffff?text=NeoCook+Blender+666A", - "description": "Blender product image" - } - ], - "created_at": "2024-11-25T09:16:11.453592Z", - "updated_at": "2025-05-28T09:16:11.453592Z" - }, - { - "id": 111, - "name": "PureLife Rice Cooker 176O", - "description": "PureLife Rice Cooker 176O is a high-performance rice cooker designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 5, - "name": "Office Equipment" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 1.05, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 34.5, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 23.9, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 1244, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 6.2, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 7.1, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 9.7, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 3, - "name": "Copper Wire", - "type": "Metal" - }, - "percentage": 19.6, - "mass": 0.6, - "unit": "kg" - }, - { - "material": { - "id": 4, - "name": "Mica", - "type": "Mineral" - }, - "percentage": 32.9, - "mass": 0.67, - "unit": "kg" - }, - { - "material": { - "id": 1, - "name": "Stainless Steel", - "type": "Metal" - }, - "percentage": 17.5, - "mass": 0.43, - "unit": "kg" - }, - { - "material": { - "id": 2, - "name": "ABS Plastic", - "type": "Plastic" - }, - "percentage": 30.1, - "mass": 0.72, - "unit": "kg" - } - ], - "components": [ - { - "id": 1111, - "name": "Rice Cooker Component 1", - "description": "High-quality part for rice cooker functionality" - }, - { - "id": 1112, - "name": "Rice Cooker Component 2", - "description": "High-quality part for rice cooker functionality" - }, - { - "id": 1113, - "name": "Rice Cooker Component 3", - "description": "High-quality part for rice cooker functionality" - }, - { - "id": 1114, - "name": "Rice Cooker Component 4", - "description": "High-quality part for rice cooker functionality" - }, - { - "id": 1115, - "name": "Rice Cooker Component 5", - "description": "High-quality part for rice cooker functionality" - } - ], - "images": [ - { - "id": 111, - "url": "https://via.placeholder.com/400x300/06f8ff/ffffff?text=PureLife+Rice+Cooker+176O", - "description": "Rice Cooker product image" - } - ], - "created_at": "2025-03-21T09:16:11.453631Z", - "updated_at": "2025-05-24T09:16:11.453631Z" - }, - { - "id": 112, - "name": "ZenGear Rice Cooker 747A", - "description": "ZenGear Rice Cooker 747A is a high-performance rice cooker designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 5, - "name": "Office Equipment" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 3.06, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 21.9, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 29.7, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 1575, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 9.0, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 5.2, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 8.6, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 2, - "name": "ABS Plastic", - "type": "Plastic" - }, - "percentage": 58.8, - "mass": 1.73, - "unit": "kg" - }, - { - "material": { - "id": 7, - "name": "Silicone", - "type": "Elastomer" - }, - "percentage": 41.2, - "mass": 1.47, - "unit": "kg" - } - ], - "components": [ - { - "id": 1121, - "name": "Rice Cooker Component 1", - "description": "High-quality part for rice cooker functionality" - }, - { - "id": 1122, - "name": "Rice Cooker Component 2", - "description": "High-quality part for rice cooker functionality" - }, - { - "id": 1123, - "name": "Rice Cooker Component 3", - "description": "High-quality part for rice cooker functionality" - }, - { - "id": 1124, - "name": "Rice Cooker Component 4", - "description": "High-quality part for rice cooker functionality" - }, - { - "id": 1125, - "name": "Rice Cooker Component 5", - "description": "High-quality part for rice cooker functionality" - } - ], - "images": [ - { - "id": 112, - "url": "https://via.placeholder.com/400x300/07f384/ffffff?text=ZenGear+Rice+Cooker+747A", - "description": "Rice Cooker product image" - } - ], - "created_at": "2024-07-16T09:16:11.453667Z", - "updated_at": "2025-06-09T09:16:11.453667Z" - }, - { - "id": 113, - "name": "AquaPro Toaster 535O", - "description": "AquaPro Toaster 535O is a high-performance toaster designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 5, - "name": "Office Equipment" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 2.78, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 28.7, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 27.3, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 1784, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 6.9, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 7.7, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 8.7, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 4, - "name": "Mica", - "type": "Mineral" - }, - "percentage": 27.1, - "mass": 0.48, - "unit": "kg" - }, - { - "material": { - "id": 5, - "name": "Borosilicate Glass", - "type": "Glass" - }, - "percentage": 30.7, - "mass": 0.99, - "unit": "kg" - }, - { - "material": { - "id": 2, - "name": "ABS Plastic", - "type": "Plastic" - }, - "percentage": 20.8, - "mass": 0.44, - "unit": "kg" - }, - { - "material": { - "id": 6, - "name": "Polypropylene", - "type": "Plastic" - }, - "percentage": 21.4, - "mass": 0.26, - "unit": "kg" - } - ], - "components": [ - { - "id": 1131, - "name": "Toaster Component 1", - "description": "High-quality part for toaster functionality" - }, - { - "id": 1132, - "name": "Toaster Component 2", - "description": "High-quality part for toaster functionality" - }, - { - "id": 1133, - "name": "Toaster Component 3", - "description": "High-quality part for toaster functionality" - } - ], - "images": [ - { - "id": 113, - "url": "https://via.placeholder.com/400x300/051dd1/ffffff?text=AquaPro+Toaster+535O", - "description": "Toaster product image" - } - ], - "created_at": "2024-07-28T09:16:11.453706Z", - "updated_at": "2025-06-04T09:16:11.453706Z" - }, - { - "id": 114, - "name": "NeoCook Iron 558J", - "description": "NeoCook Iron 558J is a high-performance iron designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 5, - "name": "Office Equipment" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 3.44, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 30.1, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 20.6, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 1313, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 6.1, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 7.1, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 8.5, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 5, - "name": "Borosilicate Glass", - "type": "Glass" - }, - "percentage": 8.9, - "mass": 0.21, - "unit": "kg" - }, - { - "material": { - "id": 1, - "name": "Stainless Steel", - "type": "Metal" - }, - "percentage": 41.1, - "mass": 1.2, - "unit": "kg" - }, - { - "material": { - "id": 3, - "name": "Copper Wire", - "type": "Metal" - }, - "percentage": 30.6, - "mass": 1.05, - "unit": "kg" - }, - { - "material": { - "id": 7, - "name": "Silicone", - "type": "Elastomer" - }, - "percentage": 19.4, - "mass": 0.25, - "unit": "kg" - } - ], - "components": [ - { - "id": 1141, - "name": "Iron Component 1", - "description": "High-quality part for iron functionality" - }, - { - "id": 1142, - "name": "Iron Component 2", - "description": "High-quality part for iron functionality" - } - ], - "images": [ - { - "id": 114, - "url": "https://via.placeholder.com/400x300/0d56eb/ffffff?text=NeoCook+Iron+558J", - "description": "Iron product image" - } - ], - "created_at": "2025-03-19T09:16:11.453766Z", - "updated_at": "2025-05-06T09:16:11.453766Z" - }, - { - "id": 115, - "name": "EcoTech Iron 827F", - "description": "EcoTech Iron 827F is a high-performance iron designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 3, - "name": "Personal Care Device" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 3.7, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 32.6, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 17.3, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 1995, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 9.1, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 6.5, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 9.5, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 5, - "name": "Borosilicate Glass", - "type": "Glass" - }, - "percentage": 48.3, - "mass": 1.46, - "unit": "kg" - }, - { - "material": { - "id": 4, - "name": "Mica", - "type": "Mineral" - }, - "percentage": 51.7, - "mass": 0.73, - "unit": "kg" - } - ], - "components": [ - { - "id": 1151, - "name": "Iron Component 1", - "description": "High-quality part for iron functionality" - }, - { - "id": 1152, - "name": "Iron Component 2", - "description": "High-quality part for iron functionality" - } - ], - "images": [ - { - "id": 115, - "url": "https://via.placeholder.com/400x300/0491fe/ffffff?text=EcoTech+Iron+827F", - "description": "Iron product image" - } - ], - "created_at": "2024-04-16T09:16:11.453823Z", - "updated_at": "2025-06-23T09:16:11.453823Z" - }, - { - "id": 116, - "name": "NeoCook Toaster 570V", - "description": "NeoCook Toaster 570V is a high-performance toaster designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 4, - "name": "Smart Home Device" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 3.04, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 26.9, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 21.4, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 1252, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 7.9, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 6.5, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 6.1, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 3, - "name": "Copper Wire", - "type": "Metal" - }, - "percentage": 19.9, - "mass": 0.64, - "unit": "kg" - }, - { - "material": { - "id": 2, - "name": "ABS Plastic", - "type": "Plastic" - }, - "percentage": 30.7, - "mass": 0.46, - "unit": "kg" - }, - { - "material": { - "id": 7, - "name": "Silicone", - "type": "Elastomer" - }, - "percentage": 21.6, - "mass": 0.49, - "unit": "kg" - }, - { - "material": { - "id": 5, - "name": "Borosilicate Glass", - "type": "Glass" - }, - "percentage": 27.8, - "mass": 0.97, - "unit": "kg" - } - ], - "components": [ - { - "id": 1161, - "name": "Toaster Component 1", - "description": "High-quality part for toaster functionality" - }, - { - "id": 1162, - "name": "Toaster Component 2", - "description": "High-quality part for toaster functionality" - }, - { - "id": 1163, - "name": "Toaster Component 3", - "description": "High-quality part for toaster functionality" - } - ], - "images": [ - { - "id": 116, - "url": "https://via.placeholder.com/400x300/0a3b61/ffffff?text=NeoCook+Toaster+570V", - "description": "Toaster product image" - } - ], - "created_at": "2024-04-24T09:16:11.453896Z", - "updated_at": "2025-04-30T09:16:11.453896Z" - }, - { - "id": 117, - "name": "EcoTech Fan 392G", - "description": "EcoTech Fan 392G is a high-performance fan designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 2, - "name": "Home Electronics" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 1.47, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 31.6, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 28.2, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 1361, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 6.8, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 7.7, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 6.2, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 6, - "name": "Polypropylene", - "type": "Plastic" - }, - "percentage": 12.2, - "mass": 0.35, - "unit": "kg" - }, - { - "material": { - "id": 7, - "name": "Silicone", - "type": "Elastomer" - }, - "percentage": 26.7, - "mass": 0.56, - "unit": "kg" - }, - { - "material": { - "id": 2, - "name": "ABS Plastic", - "type": "Plastic" - }, - "percentage": 20.0, - "mass": 0.61, - "unit": "kg" - }, - { - "material": { - "id": 4, - "name": "Mica", - "type": "Mineral" - }, - "percentage": 41.1, - "mass": 0.93, - "unit": "kg" - } - ], - "components": [ - { - "id": 1171, - "name": "Fan Component 1", - "description": "High-quality part for fan functionality" - }, - { - "id": 1172, - "name": "Fan Component 2", - "description": "High-quality part for fan functionality" - }, - { - "id": 1173, - "name": "Fan Component 3", - "description": "High-quality part for fan functionality" - }, - { - "id": 1174, - "name": "Fan Component 4", - "description": "High-quality part for fan functionality" - }, - { - "id": 1175, - "name": "Fan Component 5", - "description": "High-quality part for fan functionality" - } - ], - "images": [ - { - "id": 117, - "url": "https://via.placeholder.com/400x300/06785f/ffffff?text=EcoTech+Fan+392G", - "description": "Fan product image" - } - ], - "created_at": "2024-05-15T09:16:11.454124Z", - "updated_at": "2025-05-08T09:16:11.454124Z" - }, - { - "id": 118, - "name": "EcoTech Monitor 661X", - "description": "EcoTech Monitor 661X is a high-performance monitor designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 5, - "name": "Office Equipment" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 2.04, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 23.8, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 20.9, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 1126, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 6.1, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 7.8, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 9.5, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 5, - "name": "Borosilicate Glass", - "type": "Glass" - }, - "percentage": 47.7, - "mass": 0.54, - "unit": "kg" - }, - { - "material": { - "id": 6, - "name": "Polypropylene", - "type": "Plastic" - }, - "percentage": 52.3, - "mass": 0.95, - "unit": "kg" - } - ], - "components": [ - { - "id": 1181, - "name": "Monitor Component 1", - "description": "High-quality part for monitor functionality" - }, - { - "id": 1182, - "name": "Monitor Component 2", - "description": "High-quality part for monitor functionality" - }, - { - "id": 1183, - "name": "Monitor Component 3", - "description": "High-quality part for monitor functionality" - }, - { - "id": 1184, - "name": "Monitor Component 4", - "description": "High-quality part for monitor functionality" - } - ], - "images": [ - { - "id": 118, - "url": "https://via.placeholder.com/400x300/03d2a7/ffffff?text=EcoTech+Monitor+661X", - "description": "Monitor product image" - } - ], - "created_at": "2024-10-31T09:16:11.454397Z", - "updated_at": "2025-05-15T09:16:11.454397Z" - }, - { - "id": 119, - "name": "CleanWave Fan 528A", - "description": "CleanWave Fan 528A is a high-performance fan designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 3, - "name": "Personal Care Device" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 2.95, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 28.6, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 21.7, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 1294, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 6.7, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 7.4, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 6.7, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 2, - "name": "ABS Plastic", - "type": "Plastic" - }, - "percentage": 12.0, - "mass": 0.16, - "unit": "kg" - }, - { - "material": { - "id": 6, - "name": "Polypropylene", - "type": "Plastic" - }, - "percentage": 35.4, - "mass": 1.31, - "unit": "kg" - }, - { - "material": { - "id": 4, - "name": "Mica", - "type": "Mineral" - }, - "percentage": 16.5, - "mass": 0.25, - "unit": "kg" - }, - { - "material": { - "id": 3, - "name": "Copper Wire", - "type": "Metal" - }, - "percentage": 36.1, - "mass": 0.69, - "unit": "kg" - } - ], - "components": [ - { - "id": 1191, - "name": "Fan Component 1", - "description": "High-quality part for fan functionality" - }, - { - "id": 1192, - "name": "Fan Component 2", - "description": "High-quality part for fan functionality" - }, - { - "id": 1193, - "name": "Fan Component 3", - "description": "High-quality part for fan functionality" - }, - { - "id": 1194, - "name": "Fan Component 4", - "description": "High-quality part for fan functionality" - }, - { - "id": 1195, - "name": "Fan Component 5", - "description": "High-quality part for fan functionality" - } - ], - "images": [ - { - "id": 119, - "url": "https://via.placeholder.com/400x300/03e948/ffffff?text=CleanWave+Fan+528A", - "description": "Fan product image" - } - ], - "created_at": "2025-04-07T09:16:11.454813Z", - "updated_at": "2025-06-12T09:16:11.454813Z" - }, - { - "id": 120, - "name": "AquaPro Blender 433Z", - "description": "AquaPro Blender 433Z is a high-performance blender designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 1, - "name": "Kitchen Appliance" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 1.26, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 23.9, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 27.3, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 1899, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 7.9, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 8.1, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 7.4, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 6, - "name": "Polypropylene", - "type": "Plastic" - }, - "percentage": 31.4, - "mass": 0.84, - "unit": "kg" - }, - { - "material": { - "id": 7, - "name": "Silicone", - "type": "Elastomer" - }, - "percentage": 31.4, - "mass": 0.85, - "unit": "kg" - }, - { - "material": { - "id": 5, - "name": "Borosilicate Glass", - "type": "Glass" - }, - "percentage": 31.9, - "mass": 0.6, - "unit": "kg" - }, - { - "material": { - "id": 3, - "name": "Copper Wire", - "type": "Metal" - }, - "percentage": 5.3, - "mass": 0.15, - "unit": "kg" - } - ], - "components": [ - { - "id": 1201, - "name": "Blender Component 1", - "description": "High-quality part for blender functionality" - }, - { - "id": 1202, - "name": "Blender Component 2", - "description": "High-quality part for blender functionality" - } - ], - "images": [ - { - "id": 120, - "url": "https://via.placeholder.com/400x300/06af50/ffffff?text=AquaPro+Blender+433Z", - "description": "Blender product image" - } - ], - "created_at": "2024-10-14T09:16:11.454916Z", - "updated_at": "2025-07-21T09:16:11.454916Z" - }, - { - "id": 121, - "name": "CleanWave Kettle 614T", - "description": "CleanWave Kettle 614T is a high-performance kettle designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 3, - "name": "Personal Care Device" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 2.74, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 24.1, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 22.0, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 1292, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 6.1, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 6.0, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 9.4, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 7, - "name": "Silicone", - "type": "Elastomer" - }, - "percentage": 11.5, - "mass": 0.2, - "unit": "kg" - }, - { - "material": { - "id": 3, - "name": "Copper Wire", - "type": "Metal" - }, - "percentage": 48.1, - "mass": 0.75, - "unit": "kg" - }, - { - "material": { - "id": 4, - "name": "Mica", - "type": "Mineral" - }, - "percentage": 40.4, - "mass": 0.85, - "unit": "kg" - } - ], - "components": [ - { - "id": 1211, - "name": "Kettle Component 1", - "description": "High-quality part for kettle functionality" - }, - { - "id": 1212, - "name": "Kettle Component 2", - "description": "High-quality part for kettle functionality" - }, - { - "id": 1213, - "name": "Kettle Component 3", - "description": "High-quality part for kettle functionality" - }, - { - "id": 1214, - "name": "Kettle Component 4", - "description": "High-quality part for kettle functionality" - }, - { - "id": 1215, - "name": "Kettle Component 5", - "description": "High-quality part for kettle functionality" - } - ], - "images": [ - { - "id": 121, - "url": "https://via.placeholder.com/400x300/0afe96/ffffff?text=CleanWave+Kettle+614T", - "description": "Kettle product image" - } - ], - "created_at": "2025-01-09T09:16:11.454988Z", - "updated_at": "2025-07-21T09:16:11.454988Z" - }, - { - "id": 122, - "name": "NeoCook Coffee Maker 892J", - "description": "NeoCook Coffee Maker 892J is a high-performance coffee maker designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 4, - "name": "Smart Home Device" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 1.21, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 21.2, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 17.8, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 1383, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 6.5, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 6.2, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 9.7, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 7, - "name": "Silicone", - "type": "Elastomer" - }, - "percentage": 27.4, - "mass": 0.66, - "unit": "kg" - }, - { - "material": { - "id": 5, - "name": "Borosilicate Glass", - "type": "Glass" - }, - "percentage": 22.2, - "mass": 0.73, - "unit": "kg" - }, - { - "material": { - "id": 1, - "name": "Stainless Steel", - "type": "Metal" - }, - "percentage": 23.7, - "mass": 0.39, - "unit": "kg" - }, - { - "material": { - "id": 4, - "name": "Mica", - "type": "Mineral" - }, - "percentage": 26.7, - "mass": 0.3, - "unit": "kg" - } - ], - "components": [ - { - "id": 1221, - "name": "Coffee Maker Component 1", - "description": "High-quality part for coffee maker functionality" - }, - { - "id": 1222, - "name": "Coffee Maker Component 2", - "description": "High-quality part for coffee maker functionality" - } - ], - "images": [ - { - "id": 122, - "url": "https://via.placeholder.com/400x300/0bf37c/ffffff?text=NeoCook+Coffee+Maker+892J", - "description": "Coffee Maker product image" - } - ], - "created_at": "2025-03-25T09:16:11.455056Z", - "updated_at": "2025-07-12T09:16:11.455056Z" - }, - { - "id": 123, - "name": "CleanWave Fan 298P", - "description": "CleanWave Fan 298P is a high-performance fan designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 1, - "name": "Kitchen Appliance" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 3.61, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 28.1, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 28.7, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 1089, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 9.1, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 7.1, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 9.4, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 2, - "name": "ABS Plastic", - "type": "Plastic" - }, - "percentage": 40.5, - "mass": 0.47, - "unit": "kg" - }, - { - "material": { - "id": 3, - "name": "Copper Wire", - "type": "Metal" - }, - "percentage": 23.8, - "mass": 0.45, - "unit": "kg" - }, - { - "material": { - "id": 1, - "name": "Stainless Steel", - "type": "Metal" - }, - "percentage": 35.7, - "mass": 1.24, - "unit": "kg" - } - ], - "components": [ - { - "id": 1231, - "name": "Fan Component 1", - "description": "High-quality part for fan functionality" - }, - { - "id": 1232, - "name": "Fan Component 2", - "description": "High-quality part for fan functionality" - }, - { - "id": 1233, - "name": "Fan Component 3", - "description": "High-quality part for fan functionality" - } - ], - "images": [ - { - "id": 123, - "url": "https://via.placeholder.com/400x300/0979a8/ffffff?text=CleanWave+Fan+298P", - "description": "Fan product image" - } - ], - "created_at": "2025-02-02T09:16:11.455114Z", - "updated_at": "2025-06-17T09:16:11.455114Z" - }, - { - "id": 124, - "name": "NeoCook Kettle 965Z", - "description": "NeoCook Kettle 965Z is a high-performance kettle designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 2, - "name": "Home Electronics" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 2.64, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 21.5, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 26.2, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 1928, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 9.2, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 7.0, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 6.1, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 5, - "name": "Borosilicate Glass", - "type": "Glass" - }, - "percentage": 16.9, - "mass": 0.43, - "unit": "kg" - }, - { - "material": { - "id": 6, - "name": "Polypropylene", - "type": "Plastic" - }, - "percentage": 27.1, - "mass": 0.3, - "unit": "kg" - }, - { - "material": { - "id": 3, - "name": "Copper Wire", - "type": "Metal" - }, - "percentage": 45.8, - "mass": 1.0, - "unit": "kg" - }, - { - "material": { - "id": 7, - "name": "Silicone", - "type": "Elastomer" - }, - "percentage": 10.2, - "mass": 0.17, - "unit": "kg" - } - ], - "components": [ - { - "id": 1241, - "name": "Kettle Component 1", - "description": "High-quality part for kettle functionality" - }, - { - "id": 1242, - "name": "Kettle Component 2", - "description": "High-quality part for kettle functionality" - }, - { - "id": 1243, - "name": "Kettle Component 3", - "description": "High-quality part for kettle functionality" - }, - { - "id": 1244, - "name": "Kettle Component 4", - "description": "High-quality part for kettle functionality" - }, - { - "id": 1245, - "name": "Kettle Component 5", - "description": "High-quality part for kettle functionality" - } - ], - "images": [ - { - "id": 124, - "url": "https://via.placeholder.com/400x300/0e07cc/ffffff?text=NeoCook+Kettle+965Z", - "description": "Kettle product image" - } - ], - "created_at": "2024-06-02T09:16:11.455190Z", - "updated_at": "2025-05-19T09:16:11.455190Z" - }, - { - "id": 125, - "name": "PureLife Toaster 428F", - "description": "PureLife Toaster 428F is a high-performance toaster designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 4, - "name": "Smart Home Device" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 2.37, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 23.7, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 20.5, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 1647, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 8.3, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 6.7, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 9.5, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 2, - "name": "ABS Plastic", - "type": "Plastic" - }, - "percentage": 16.8, - "mass": 0.26, - "unit": "kg" - }, - { - "material": { - "id": 6, - "name": "Polypropylene", - "type": "Plastic" - }, - "percentage": 33.6, - "mass": 1.31, - "unit": "kg" - }, - { - "material": { - "id": 7, - "name": "Silicone", - "type": "Elastomer" - }, - "percentage": 22.7, - "mass": 0.26, - "unit": "kg" - }, - { - "material": { - "id": 4, - "name": "Mica", - "type": "Mineral" - }, - "percentage": 26.9, - "mass": 0.54, - "unit": "kg" - } - ], - "components": [ - { - "id": 1251, - "name": "Toaster Component 1", - "description": "High-quality part for toaster functionality" - }, - { - "id": 1252, - "name": "Toaster Component 2", - "description": "High-quality part for toaster functionality" - }, - { - "id": 1253, - "name": "Toaster Component 3", - "description": "High-quality part for toaster functionality" - }, - { - "id": 1254, - "name": "Toaster Component 4", - "description": "High-quality part for toaster functionality" - }, - { - "id": 1255, - "name": "Toaster Component 5", - "description": "High-quality part for toaster functionality" - } - ], - "images": [ - { - "id": 125, - "url": "https://via.placeholder.com/400x300/0c7508/ffffff?text=PureLife+Toaster+428F", - "description": "Toaster product image" - } - ], - "created_at": "2024-03-29T09:16:11.455388Z", - "updated_at": "2025-05-04T09:16:11.455388Z" - }, - { - "id": 126, - "name": "ZenGear Kettle 889Q", - "description": "ZenGear Kettle 889Q is a high-performance kettle designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 2, - "name": "Home Electronics" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 3.99, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 32.3, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 18.0, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 1558, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 7.7, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 7.7, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 9.7, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 4, - "name": "Mica", - "type": "Mineral" - }, - "percentage": 13.5, - "mass": 0.49, - "unit": "kg" - }, - { - "material": { - "id": 6, - "name": "Polypropylene", - "type": "Plastic" - }, - "percentage": 66.3, - "mass": 1.82, - "unit": "kg" - }, - { - "material": { - "id": 1, - "name": "Stainless Steel", - "type": "Metal" - }, - "percentage": 20.2, - "mass": 0.77, - "unit": "kg" - } - ], - "components": [ - { - "id": 1261, - "name": "Kettle Component 1", - "description": "High-quality part for kettle functionality" - }, - { - "id": 1262, - "name": "Kettle Component 2", - "description": "High-quality part for kettle functionality" - } - ], - "images": [ - { - "id": 126, - "url": "https://via.placeholder.com/400x300/034a52/ffffff?text=ZenGear+Kettle+889Q", - "description": "Kettle product image" - } - ], - "created_at": "2024-05-30T09:16:11.455471Z", - "updated_at": "2025-06-15T09:16:11.455471Z" - }, - { - "id": 127, - "name": "SmartHome Air Purifier 934O", - "description": "SmartHome Air Purifier 934O is a high-performance air purifier designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 5, - "name": "Office Equipment" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 1.06, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 31.3, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 18.6, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 2050, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 7.0, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 7.6, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 9.7, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 1, - "name": "Stainless Steel", - "type": "Metal" - }, - "percentage": 20.7, - "mass": 0.31, - "unit": "kg" - }, - { - "material": { - "id": 6, - "name": "Polypropylene", - "type": "Plastic" - }, - "percentage": 25.9, - "mass": 0.35, - "unit": "kg" - }, - { - "material": { - "id": 7, - "name": "Silicone", - "type": "Elastomer" - }, - "percentage": 22.8, - "mass": 0.75, - "unit": "kg" - }, - { - "material": { - "id": 3, - "name": "Copper Wire", - "type": "Metal" - }, - "percentage": 30.6, - "mass": 0.87, - "unit": "kg" - } - ], - "components": [ - { - "id": 1271, - "name": "Air Purifier Component 1", - "description": "High-quality part for air purifier functionality" - }, - { - "id": 1272, - "name": "Air Purifier Component 2", - "description": "High-quality part for air purifier functionality" - }, - { - "id": 1273, - "name": "Air Purifier Component 3", - "description": "High-quality part for air purifier functionality" - }, - { - "id": 1274, - "name": "Air Purifier Component 4", - "description": "High-quality part for air purifier functionality" - }, - { - "id": 1275, - "name": "Air Purifier Component 5", - "description": "High-quality part for air purifier functionality" - } - ], - "images": [ - { - "id": 127, - "url": "https://via.placeholder.com/400x300/0f29cd/ffffff?text=SmartHome+Air+Purifier+934O", - "description": "Air Purifier product image" - } - ], - "created_at": "2024-10-19T09:16:11.455605Z", - "updated_at": "2025-05-04T09:16:11.455605Z" - }, - { - "id": 128, - "name": "EcoTech Rice Cooker 420T", - "description": "EcoTech Rice Cooker 420T is a high-performance rice cooker designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 4, - "name": "Smart Home Device" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 1.16, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 28.8, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 25.5, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 1892, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 8.2, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 7.2, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 6.5, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 1, - "name": "Stainless Steel", - "type": "Metal" - }, - "percentage": 42.0, - "mass": 1.02, - "unit": "kg" - }, - { - "material": { - "id": 2, - "name": "ABS Plastic", - "type": "Plastic" - }, - "percentage": 10.1, - "mass": 0.12, - "unit": "kg" - }, - { - "material": { - "id": 7, - "name": "Silicone", - "type": "Elastomer" - }, - "percentage": 47.9, - "mass": 0.76, - "unit": "kg" - } - ], - "components": [ - { - "id": 1281, - "name": "Rice Cooker Component 1", - "description": "High-quality part for rice cooker functionality" - }, - { - "id": 1282, - "name": "Rice Cooker Component 2", - "description": "High-quality part for rice cooker functionality" - } - ], - "images": [ - { - "id": 128, - "url": "https://via.placeholder.com/400x300/056bba/ffffff?text=EcoTech+Rice+Cooker+420T", - "description": "Rice Cooker product image" - } - ], - "created_at": "2024-08-09T09:16:11.455824Z", - "updated_at": "2025-07-17T09:16:11.455824Z" - }, - { - "id": 129, - "name": "AquaPro Rice Cooker 402Y", - "description": "AquaPro Rice Cooker 402Y is a high-performance rice cooker designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 5, - "name": "Office Equipment" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 1.63, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 32.8, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 21.5, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 921, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 8.5, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 6.1, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 9.4, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 4, - "name": "Mica", - "type": "Mineral" - }, - "percentage": 55.9, - "mass": 1.08, - "unit": "kg" - }, - { - "material": { - "id": 5, - "name": "Borosilicate Glass", - "type": "Glass" - }, - "percentage": 44.1, - "mass": 0.86, - "unit": "kg" - } - ], - "components": [ - { - "id": 1291, - "name": "Rice Cooker Component 1", - "description": "High-quality part for rice cooker functionality" - }, - { - "id": 1292, - "name": "Rice Cooker Component 2", - "description": "High-quality part for rice cooker functionality" - }, - { - "id": 1293, - "name": "Rice Cooker Component 3", - "description": "High-quality part for rice cooker functionality" - } - ], - "images": [ - { - "id": 129, - "url": "https://via.placeholder.com/400x300/03a221/ffffff?text=AquaPro+Rice+Cooker+402Y", - "description": "Rice Cooker product image" - } - ], - "created_at": "2024-08-16T09:16:11.455917Z", - "updated_at": "2025-07-16T09:16:11.455917Z" - }, - { - "id": 130, - "name": "AquaPro Monitor 295C", - "description": "AquaPro Monitor 295C is a high-performance monitor designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 1, - "name": "Kitchen Appliance" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 1.96, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 34.5, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 18.5, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 1157, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 6.4, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 8.7, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 8.9, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 4, - "name": "Mica", - "type": "Mineral" - }, - "percentage": 36.9, - "mass": 1.11, - "unit": "kg" - }, - { - "material": { - "id": 2, - "name": "ABS Plastic", - "type": "Plastic" - }, - "percentage": 24.3, - "mass": 0.83, - "unit": "kg" - }, - { - "material": { - "id": 3, - "name": "Copper Wire", - "type": "Metal" - }, - "percentage": 38.8, - "mass": 0.43, - "unit": "kg" - } - ], - "components": [ - { - "id": 1301, - "name": "Monitor Component 1", - "description": "High-quality part for monitor functionality" - }, - { - "id": 1302, - "name": "Monitor Component 2", - "description": "High-quality part for monitor functionality" - }, - { - "id": 1303, - "name": "Monitor Component 3", - "description": "High-quality part for monitor functionality" - }, - { - "id": 1304, - "name": "Monitor Component 4", - "description": "High-quality part for monitor functionality" - } - ], - "images": [ - { - "id": 130, - "url": "https://via.placeholder.com/400x300/07b9a6/ffffff?text=AquaPro+Monitor+295C", - "description": "Monitor product image" - } - ], - "created_at": "2024-10-22T09:16:11.456018Z", - "updated_at": "2025-05-17T09:16:11.456018Z" - }, - { - "id": 131, - "name": "NeoCook Coffee Maker 459Q", - "description": "NeoCook Coffee Maker 459Q is a high-performance coffee maker designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 3, - "name": "Personal Care Device" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 3.99, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 28.9, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 19.7, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 1518, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 8.3, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 5.8, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 6.9, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 6, - "name": "Polypropylene", - "type": "Plastic" - }, - "percentage": 14.3, - "mass": 0.55, - "unit": "kg" - }, - { - "material": { - "id": 3, - "name": "Copper Wire", - "type": "Metal" - }, - "percentage": 28.6, - "mass": 1.04, - "unit": "kg" - }, - { - "material": { - "id": 1, - "name": "Stainless Steel", - "type": "Metal" - }, - "percentage": 57.1, - "mass": 1.69, - "unit": "kg" - } - ], - "components": [ - { - "id": 1311, - "name": "Coffee Maker Component 1", - "description": "High-quality part for coffee maker functionality" - }, - { - "id": 1312, - "name": "Coffee Maker Component 2", - "description": "High-quality part for coffee maker functionality" - } - ], - "images": [ - { - "id": 131, - "url": "https://via.placeholder.com/400x300/03bb89/ffffff?text=NeoCook+Coffee+Maker+459Q", - "description": "Coffee Maker product image" - } - ], - "created_at": "2024-11-28T09:16:11.456102Z", - "updated_at": "2025-05-09T09:16:11.456102Z" - }, - { - "id": 132, - "name": "NeoCook Monitor 111M", - "description": "NeoCook Monitor 111M is a high-performance monitor designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 3, - "name": "Personal Care Device" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 2.37, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 25.3, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 25.1, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 2091, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 7.9, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 6.5, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 9.4, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 6, - "name": "Polypropylene", - "type": "Plastic" - }, - "percentage": 42.4, - "mass": 0.74, - "unit": "kg" - }, - { - "material": { - "id": 5, - "name": "Borosilicate Glass", - "type": "Glass" - }, - "percentage": 32.0, - "mass": 0.96, - "unit": "kg" - }, - { - "material": { - "id": 7, - "name": "Silicone", - "type": "Elastomer" - }, - "percentage": 25.6, - "mass": 0.29, - "unit": "kg" - } - ], - "components": [ - { - "id": 1321, - "name": "Monitor Component 1", - "description": "High-quality part for monitor functionality" - }, - { - "id": 1322, - "name": "Monitor Component 2", - "description": "High-quality part for monitor functionality" - }, - { - "id": 1323, - "name": "Monitor Component 3", - "description": "High-quality part for monitor functionality" - }, - { - "id": 1324, - "name": "Monitor Component 4", - "description": "High-quality part for monitor functionality" - }, - { - "id": 1325, - "name": "Monitor Component 5", - "description": "High-quality part for monitor functionality" - } - ], - "images": [ - { - "id": 132, - "url": "https://via.placeholder.com/400x300/0d2198/ffffff?text=NeoCook+Monitor+111M", - "description": "Monitor product image" - } - ], - "created_at": "2024-04-26T09:16:11.456170Z", - "updated_at": "2025-07-22T09:16:11.456170Z" - }, - { - "id": 133, - "name": "AquaPro Iron 797U", - "description": "AquaPro Iron 797U is a high-performance iron designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 5, - "name": "Office Equipment" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 1.07, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 28.6, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 19.2, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 1019, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 7.8, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 7.2, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 8.6, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 1, - "name": "Stainless Steel", - "type": "Metal" - }, - "percentage": 13.1, - "mass": 0.15, - "unit": "kg" - }, - { - "material": { - "id": 2, - "name": "ABS Plastic", - "type": "Plastic" - }, - "percentage": 59.6, - "mass": 1.6, - "unit": "kg" - }, - { - "material": { - "id": 4, - "name": "Mica", - "type": "Mineral" - }, - "percentage": 12.1, - "mass": 0.3, - "unit": "kg" - }, - { - "material": { - "id": 3, - "name": "Copper Wire", - "type": "Metal" - }, - "percentage": 15.2, - "mass": 0.2, - "unit": "kg" - } - ], - "components": [ - { - "id": 1331, - "name": "Iron Component 1", - "description": "High-quality part for iron functionality" - }, - { - "id": 1332, - "name": "Iron Component 2", - "description": "High-quality part for iron functionality" - }, - { - "id": 1333, - "name": "Iron Component 3", - "description": "High-quality part for iron functionality" - } - ], - "images": [ - { - "id": 133, - "url": "https://via.placeholder.com/400x300/07d5df/ffffff?text=AquaPro+Iron+797U", - "description": "Iron product image" - } - ], - "created_at": "2024-08-01T09:16:11.456224Z", - "updated_at": "2025-04-29T09:16:11.456224Z" - }, - { - "id": 134, - "name": "ZenGear Monitor 834P", - "description": "ZenGear Monitor 834P is a high-performance monitor designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 1, - "name": "Kitchen Appliance" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 3.7, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 34.3, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 19.3, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 948, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 6.0, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 5.2, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 9.3, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 5, - "name": "Borosilicate Glass", - "type": "Glass" - }, - "percentage": 66.7, - "mass": 2.16, - "unit": "kg" - }, - { - "material": { - "id": 3, - "name": "Copper Wire", - "type": "Metal" - }, - "percentage": 33.3, - "mass": 1.18, - "unit": "kg" - } - ], - "components": [ - { - "id": 1341, - "name": "Monitor Component 1", - "description": "High-quality part for monitor functionality" - }, - { - "id": 1342, - "name": "Monitor Component 2", - "description": "High-quality part for monitor functionality" - }, - { - "id": 1343, - "name": "Monitor Component 3", - "description": "High-quality part for monitor functionality" - }, - { - "id": 1344, - "name": "Monitor Component 4", - "description": "High-quality part for monitor functionality" - } - ], - "images": [ - { - "id": 134, - "url": "https://via.placeholder.com/400x300/0703f2/ffffff?text=ZenGear+Monitor+834P", - "description": "Monitor product image" - } - ], - "created_at": "2024-12-19T09:16:11.456285Z", - "updated_at": "2025-04-25T09:16:11.456285Z" - }, - { - "id": 135, - "name": "PureLife Kettle 981Q", - "description": "PureLife Kettle 981Q is a high-performance kettle designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 2, - "name": "Home Electronics" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 2.52, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 23.9, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 17.8, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 1716, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 6.3, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 7.7, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 6.3, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 3, - "name": "Copper Wire", - "type": "Metal" - }, - "percentage": 53.8, - "mass": 1.18, - "unit": "kg" - }, - { - "material": { - "id": 2, - "name": "ABS Plastic", - "type": "Plastic" - }, - "percentage": 19.8, - "mass": 0.76, - "unit": "kg" - }, - { - "material": { - "id": 7, - "name": "Silicone", - "type": "Elastomer" - }, - "percentage": 26.4, - "mass": 0.82, - "unit": "kg" - } - ], - "components": [ - { - "id": 1351, - "name": "Kettle Component 1", - "description": "High-quality part for kettle functionality" - }, - { - "id": 1352, - "name": "Kettle Component 2", - "description": "High-quality part for kettle functionality" - }, - { - "id": 1353, - "name": "Kettle Component 3", - "description": "High-quality part for kettle functionality" - }, - { - "id": 1354, - "name": "Kettle Component 4", - "description": "High-quality part for kettle functionality" - } - ], - "images": [ - { - "id": 135, - "url": "https://via.placeholder.com/400x300/0e823d/ffffff?text=PureLife+Kettle+981Q", - "description": "Kettle product image" - } - ], - "created_at": "2025-03-08T09:16:11.456359Z", - "updated_at": "2025-07-10T09:16:11.456359Z" - }, - { - "id": 136, - "name": "SmartHome Humidifier 259V", - "description": "SmartHome Humidifier 259V is a high-performance humidifier designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 1, - "name": "Kitchen Appliance" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 3.94, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 20.6, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 20.7, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 2079, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 6.3, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 8.8, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 7.1, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 4, - "name": "Mica", - "type": "Mineral" - }, - "percentage": 9.4, - "mass": 0.24, - "unit": "kg" - }, - { - "material": { - "id": 5, - "name": "Borosilicate Glass", - "type": "Glass" - }, - "percentage": 48.1, - "mass": 1.84, - "unit": "kg" - }, - { - "material": { - "id": 1, - "name": "Stainless Steel", - "type": "Metal" - }, - "percentage": 42.5, - "mass": 1.08, - "unit": "kg" - } - ], - "components": [ - { - "id": 1361, - "name": "Humidifier Component 1", - "description": "High-quality part for humidifier functionality" - }, - { - "id": 1362, - "name": "Humidifier Component 2", - "description": "High-quality part for humidifier functionality" - }, - { - "id": 1363, - "name": "Humidifier Component 3", - "description": "High-quality part for humidifier functionality" - }, - { - "id": 1364, - "name": "Humidifier Component 4", - "description": "High-quality part for humidifier functionality" - }, - { - "id": 1365, - "name": "Humidifier Component 5", - "description": "High-quality part for humidifier functionality" - } - ], - "images": [ - { - "id": 136, - "url": "https://via.placeholder.com/400x300/0bf14d/ffffff?text=SmartHome+Humidifier+259V", - "description": "Humidifier product image" - } - ], - "created_at": "2025-02-24T09:16:11.456420Z", - "updated_at": "2025-07-31T09:16:11.456420Z" - }, - { - "id": 137, - "name": "ZenGear Coffee Maker 637O", - "description": "ZenGear Coffee Maker 637O is a high-performance coffee maker designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 1, - "name": "Kitchen Appliance" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 3.55, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 30.1, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 25.0, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 1587, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 9.2, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 5.5, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 6.4, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 6, - "name": "Polypropylene", - "type": "Plastic" - }, - "percentage": 21.1, - "mass": 0.44, - "unit": "kg" - }, - { - "material": { - "id": 3, - "name": "Copper Wire", - "type": "Metal" - }, - "percentage": 50.5, - "mass": 1.94, - "unit": "kg" - }, - { - "material": { - "id": 7, - "name": "Silicone", - "type": "Elastomer" - }, - "percentage": 28.4, - "mass": 0.52, - "unit": "kg" - } - ], - "components": [ - { - "id": 1371, - "name": "Coffee Maker Component 1", - "description": "High-quality part for coffee maker functionality" - }, - { - "id": 1372, - "name": "Coffee Maker Component 2", - "description": "High-quality part for coffee maker functionality" - }, - { - "id": 1373, - "name": "Coffee Maker Component 3", - "description": "High-quality part for coffee maker functionality" - }, - { - "id": 1374, - "name": "Coffee Maker Component 4", - "description": "High-quality part for coffee maker functionality" - }, - { - "id": 1375, - "name": "Coffee Maker Component 5", - "description": "High-quality part for coffee maker functionality" - } - ], - "images": [ - { - "id": 137, - "url": "https://via.placeholder.com/400x300/09b645/ffffff?text=ZenGear+Coffee+Maker+637O", - "description": "Coffee Maker product image" - } - ], - "created_at": "2025-01-22T09:16:11.456499Z", - "updated_at": "2025-05-07T09:16:11.456499Z" - }, - { - "id": 138, - "name": "CleanWave Kettle 783H", - "description": "CleanWave Kettle 783H is a high-performance kettle designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 3, - "name": "Personal Care Device" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 2.98, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 20.8, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 27.0, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 1534, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 6.3, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 8.8, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 9.1, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 1, - "name": "Stainless Steel", - "type": "Metal" - }, - "percentage": 37.3, - "mass": 1.38, - "unit": "kg" - }, - { - "material": { - "id": 7, - "name": "Silicone", - "type": "Elastomer" - }, - "percentage": 30.3, - "mass": 0.57, - "unit": "kg" - }, - { - "material": { - "id": 6, - "name": "Polypropylene", - "type": "Plastic" - }, - "percentage": 32.4, - "mass": 0.84, - "unit": "kg" - } - ], - "components": [ - { - "id": 1381, - "name": "Kettle Component 1", - "description": "High-quality part for kettle functionality" - }, - { - "id": 1382, - "name": "Kettle Component 2", - "description": "High-quality part for kettle functionality" - }, - { - "id": 1383, - "name": "Kettle Component 3", - "description": "High-quality part for kettle functionality" - } - ], - "images": [ - { - "id": 138, - "url": "https://via.placeholder.com/400x300/09b511/ffffff?text=CleanWave+Kettle+783H", - "description": "Kettle product image" - } - ], - "created_at": "2024-11-08T09:16:11.456556Z", - "updated_at": "2025-07-19T09:16:11.456556Z" - }, - { - "id": 139, - "name": "ZenGear Rice Cooker 406O", - "description": "ZenGear Rice Cooker 406O is a high-performance rice cooker designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 4, - "name": "Smart Home Device" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 2.24, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 32.8, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 24.8, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 1764, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 9.3, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 7.1, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 9.9, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 4, - "name": "Mica", - "type": "Mineral" - }, - "percentage": 36.0, - "mass": 1.2, - "unit": "kg" - }, - { - "material": { - "id": 2, - "name": "ABS Plastic", - "type": "Plastic" - }, - "percentage": 33.8, - "mass": 0.72, - "unit": "kg" - }, - { - "material": { - "id": 5, - "name": "Borosilicate Glass", - "type": "Glass" - }, - "percentage": 11.0, - "mass": 0.13, - "unit": "kg" - }, - { - "material": { - "id": 3, - "name": "Copper Wire", - "type": "Metal" - }, - "percentage": 19.1, - "mass": 0.23, - "unit": "kg" - } - ], - "components": [ - { - "id": 1391, - "name": "Rice Cooker Component 1", - "description": "High-quality part for rice cooker functionality" - }, - { - "id": 1392, - "name": "Rice Cooker Component 2", - "description": "High-quality part for rice cooker functionality" - }, - { - "id": 1393, - "name": "Rice Cooker Component 3", - "description": "High-quality part for rice cooker functionality" - }, - { - "id": 1394, - "name": "Rice Cooker Component 4", - "description": "High-quality part for rice cooker functionality" - }, - { - "id": 1395, - "name": "Rice Cooker Component 5", - "description": "High-quality part for rice cooker functionality" - } - ], - "images": [ - { - "id": 139, - "url": "https://via.placeholder.com/400x300/0c089d/ffffff?text=ZenGear+Rice+Cooker+406O", - "description": "Rice Cooker product image" - } - ], - "created_at": "2025-02-04T09:16:11.456803Z", - "updated_at": "2025-07-19T09:16:11.456803Z" - }, - { - "id": 140, - "name": "ChefMate Humidifier 939C", - "description": "ChefMate Humidifier 939C is a high-performance humidifier designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 5, - "name": "Office Equipment" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 3.5, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 28.2, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 25.5, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 2065, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 6.8, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 5.3, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 8.5, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 6, - "name": "Polypropylene", - "type": "Plastic" - }, - "percentage": 31.7, - "mass": 1.12, - "unit": "kg" - }, - { - "material": { - "id": 3, - "name": "Copper Wire", - "type": "Metal" - }, - "percentage": 68.3, - "mass": 2.11, - "unit": "kg" - } - ], - "components": [ - { - "id": 1401, - "name": "Humidifier Component 1", - "description": "High-quality part for humidifier functionality" - }, - { - "id": 1402, - "name": "Humidifier Component 2", - "description": "High-quality part for humidifier functionality" - }, - { - "id": 1403, - "name": "Humidifier Component 3", - "description": "High-quality part for humidifier functionality" - }, - { - "id": 1404, - "name": "Humidifier Component 4", - "description": "High-quality part for humidifier functionality" - }, - { - "id": 1405, - "name": "Humidifier Component 5", - "description": "High-quality part for humidifier functionality" - } - ], - "images": [ - { - "id": 140, - "url": "https://via.placeholder.com/400x300/0cfc83/ffffff?text=ChefMate+Humidifier+939C", - "description": "Humidifier product image" - } - ], - "created_at": "2024-09-24T09:16:11.456881Z", - "updated_at": "2025-06-08T09:16:11.456881Z" - }, - { - "id": 141, - "name": "NeoCook Humidifier 447M", - "description": "NeoCook Humidifier 447M is a high-performance humidifier designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 4, - "name": "Smart Home Device" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 3.72, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 29.6, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 16.6, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 2132, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 6.5, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 5.2, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 9.0, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 3, - "name": "Copper Wire", - "type": "Metal" - }, - "percentage": 67.1, - "mass": 2.21, - "unit": "kg" - }, - { - "material": { - "id": 4, - "name": "Mica", - "type": "Mineral" - }, - "percentage": 32.9, - "mass": 0.95, - "unit": "kg" - } - ], - "components": [ - { - "id": 1411, - "name": "Humidifier Component 1", - "description": "High-quality part for humidifier functionality" - }, - { - "id": 1412, - "name": "Humidifier Component 2", - "description": "High-quality part for humidifier functionality" - } - ], - "images": [ - { - "id": 141, - "url": "https://via.placeholder.com/400x300/0d3b4c/ffffff?text=NeoCook+Humidifier+447M", - "description": "Humidifier product image" - } - ], - "created_at": "2025-01-04T09:16:11.456942Z", - "updated_at": "2025-05-27T09:16:11.456942Z" - }, - { - "id": 142, - "name": "ZenGear Fan 908F", - "description": "ZenGear Fan 908F is a high-performance fan designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 1, - "name": "Kitchen Appliance" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 1.29, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 22.6, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 22.2, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 1815, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 8.0, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 8.1, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 8.4, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 6, - "name": "Polypropylene", - "type": "Plastic" - }, - "percentage": 27.9, - "mass": 0.8, - "unit": "kg" - }, - { - "material": { - "id": 7, - "name": "Silicone", - "type": "Elastomer" - }, - "percentage": 72.1, - "mass": 2.31, - "unit": "kg" - } - ], - "components": [ - { - "id": 1421, - "name": "Fan Component 1", - "description": "High-quality part for fan functionality" - }, - { - "id": 1422, - "name": "Fan Component 2", - "description": "High-quality part for fan functionality" - }, - { - "id": 1423, - "name": "Fan Component 3", - "description": "High-quality part for fan functionality" - }, - { - "id": 1424, - "name": "Fan Component 4", - "description": "High-quality part for fan functionality" - } - ], - "images": [ - { - "id": 142, - "url": "https://via.placeholder.com/400x300/073224/ffffff?text=ZenGear+Fan+908F", - "description": "Fan product image" - } - ], - "created_at": "2025-03-18T09:16:11.456997Z", - "updated_at": "2025-05-11T09:16:11.456997Z" - }, - { - "id": 143, - "name": "PureLife Coffee Maker 690C", - "description": "PureLife Coffee Maker 690C is a high-performance coffee maker designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 1, - "name": "Kitchen Appliance" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 3.03, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 22.6, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 20.8, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 922, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 6.8, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 7.2, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 8.3, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 3, - "name": "Copper Wire", - "type": "Metal" - }, - "percentage": 35.0, - "mass": 0.93, - "unit": "kg" - }, - { - "material": { - "id": 6, - "name": "Polypropylene", - "type": "Plastic" - }, - "percentage": 15.4, - "mass": 0.51, - "unit": "kg" - }, - { - "material": { - "id": 5, - "name": "Borosilicate Glass", - "type": "Glass" - }, - "percentage": 14.5, - "mass": 0.19, - "unit": "kg" - }, - { - "material": { - "id": 4, - "name": "Mica", - "type": "Mineral" - }, - "percentage": 35.0, - "mass": 0.41, - "unit": "kg" - } - ], - "components": [ - { - "id": 1431, - "name": "Coffee Maker Component 1", - "description": "High-quality part for coffee maker functionality" - }, - { - "id": 1432, - "name": "Coffee Maker Component 2", - "description": "High-quality part for coffee maker functionality" - }, - { - "id": 1433, - "name": "Coffee Maker Component 3", - "description": "High-quality part for coffee maker functionality" - } - ], - "images": [ - { - "id": 143, - "url": "https://via.placeholder.com/400x300/0807e3/ffffff?text=PureLife+Coffee+Maker+690C", - "description": "Coffee Maker product image" - } - ], - "created_at": "2024-11-08T09:16:11.457052Z", - "updated_at": "2025-04-26T09:16:11.457052Z" - }, - { - "id": 144, - "name": "EcoTech Blender 793S", - "description": "EcoTech Blender 793S is a high-performance blender designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 5, - "name": "Office Equipment" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 1.18, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 33.8, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 23.2, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 2141, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 6.9, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 7.3, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 7.4, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 4, - "name": "Mica", - "type": "Mineral" - }, - "percentage": 26.2, - "mass": 0.69, - "unit": "kg" - }, - { - "material": { - "id": 2, - "name": "ABS Plastic", - "type": "Plastic" - }, - "percentage": 56.9, - "mass": 1.54, - "unit": "kg" - }, - { - "material": { - "id": 1, - "name": "Stainless Steel", - "type": "Metal" - }, - "percentage": 16.9, - "mass": 0.52, - "unit": "kg" - } - ], - "components": [ - { - "id": 1441, - "name": "Blender Component 1", - "description": "High-quality part for blender functionality" - }, - { - "id": 1442, - "name": "Blender Component 2", - "description": "High-quality part for blender functionality" - }, - { - "id": 1443, - "name": "Blender Component 3", - "description": "High-quality part for blender functionality" - } - ], - "images": [ - { - "id": 144, - "url": "https://via.placeholder.com/400x300/0d15de/ffffff?text=EcoTech+Blender+793S", - "description": "Blender product image" - } - ], - "created_at": "2024-08-01T09:16:11.457118Z", - "updated_at": "2025-06-08T09:16:11.457118Z" - }, - { - "id": 145, - "name": "CleanWave Kettle 715F", - "description": "CleanWave Kettle 715F is a high-performance kettle designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 2, - "name": "Home Electronics" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 1.25, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 30.6, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 15.0, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 1738, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 8.0, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 6.9, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 6.5, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 1, - "name": "Stainless Steel", - "type": "Metal" - }, - "percentage": 30.7, - "mass": 0.76, - "unit": "kg" - }, - { - "material": { - "id": 4, - "name": "Mica", - "type": "Mineral" - }, - "percentage": 9.2, - "mass": 0.22, - "unit": "kg" - }, - { - "material": { - "id": 6, - "name": "Polypropylene", - "type": "Plastic" - }, - "percentage": 22.9, - "mass": 0.63, - "unit": "kg" - }, - { - "material": { - "id": 5, - "name": "Borosilicate Glass", - "type": "Glass" - }, - "percentage": 37.3, - "mass": 0.61, - "unit": "kg" - } - ], - "components": [ - { - "id": 1451, - "name": "Kettle Component 1", - "description": "High-quality part for kettle functionality" - }, - { - "id": 1452, - "name": "Kettle Component 2", - "description": "High-quality part for kettle functionality" - }, - { - "id": 1453, - "name": "Kettle Component 3", - "description": "High-quality part for kettle functionality" - }, - { - "id": 1454, - "name": "Kettle Component 4", - "description": "High-quality part for kettle functionality" - }, - { - "id": 1455, - "name": "Kettle Component 5", - "description": "High-quality part for kettle functionality" - } - ], - "images": [ - { - "id": 145, - "url": "https://via.placeholder.com/400x300/04e263/ffffff?text=CleanWave+Kettle+715F", - "description": "Kettle product image" - } - ], - "created_at": "2025-01-14T09:16:11.457163Z", - "updated_at": "2025-07-09T09:16:11.457163Z" - }, - { - "id": 146, - "name": "ChefMate Toaster 831R", - "description": "ChefMate Toaster 831R is a high-performance toaster designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 2, - "name": "Home Electronics" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 2.88, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 34.2, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 28.4, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 1013, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 9.1, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 6.0, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 9.4, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 3, - "name": "Copper Wire", - "type": "Metal" - }, - "percentage": 27.3, - "mass": 0.4, - "unit": "kg" - }, - { - "material": { - "id": 5, - "name": "Borosilicate Glass", - "type": "Glass" - }, - "percentage": 15.3, - "mass": 0.37, - "unit": "kg" - }, - { - "material": { - "id": 7, - "name": "Silicone", - "type": "Elastomer" - }, - "percentage": 30.7, - "mass": 0.76, - "unit": "kg" - }, - { - "material": { - "id": 4, - "name": "Mica", - "type": "Mineral" - }, - "percentage": 26.7, - "mass": 0.7, - "unit": "kg" - } - ], - "components": [ - { - "id": 1461, - "name": "Toaster Component 1", - "description": "High-quality part for toaster functionality" - }, - { - "id": 1462, - "name": "Toaster Component 2", - "description": "High-quality part for toaster functionality" - }, - { - "id": 1463, - "name": "Toaster Component 3", - "description": "High-quality part for toaster functionality" - } - ], - "images": [ - { - "id": 146, - "url": "https://via.placeholder.com/400x300/0b1b13/ffffff?text=ChefMate+Toaster+831R", - "description": "Toaster product image" - } - ], - "created_at": "2024-12-09T09:16:11.457254Z", - "updated_at": "2025-07-17T09:16:11.457254Z" - }, - { - "id": 147, - "name": "EcoTech Coffee Maker 849K", - "description": "EcoTech Coffee Maker 849K is a high-performance coffee maker designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 3, - "name": "Personal Care Device" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 1.29, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 32.1, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 27.0, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 1389, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 8.8, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 8.5, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 6.4, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 3, - "name": "Copper Wire", - "type": "Metal" - }, - "percentage": 82.2, - "mass": 1.48, - "unit": "kg" - }, - { - "material": { - "id": 6, - "name": "Polypropylene", - "type": "Plastic" - }, - "percentage": 17.8, - "mass": 0.69, - "unit": "kg" - } - ], - "components": [ - { - "id": 1471, - "name": "Coffee Maker Component 1", - "description": "High-quality part for coffee maker functionality" - }, - { - "id": 1472, - "name": "Coffee Maker Component 2", - "description": "High-quality part for coffee maker functionality" - } - ], - "images": [ - { - "id": 147, - "url": "https://via.placeholder.com/400x300/05f647/ffffff?text=EcoTech+Coffee+Maker+849K", - "description": "Coffee Maker product image" - } - ], - "created_at": "2024-12-01T09:16:11.457313Z", - "updated_at": "2025-05-03T09:16:11.457313Z" - }, - { - "id": 148, - "name": "SmartHome Fan 907H", - "description": "SmartHome Fan 907H is a high-performance fan designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 4, - "name": "Smart Home Device" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 2.28, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 24.3, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 16.0, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 1964, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 8.6, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 8.2, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 9.2, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 1, - "name": "Stainless Steel", - "type": "Metal" - }, - "percentage": 32.5, - "mass": 0.74, - "unit": "kg" - }, - { - "material": { - "id": 5, - "name": "Borosilicate Glass", - "type": "Glass" - }, - "percentage": 33.8, - "mass": 1.24, - "unit": "kg" - }, - { - "material": { - "id": 6, - "name": "Polypropylene", - "type": "Plastic" - }, - "percentage": 33.8, - "mass": 1.32, - "unit": "kg" - } - ], - "components": [ - { - "id": 1481, - "name": "Fan Component 1", - "description": "High-quality part for fan functionality" - }, - { - "id": 1482, - "name": "Fan Component 2", - "description": "High-quality part for fan functionality" - }, - { - "id": 1483, - "name": "Fan Component 3", - "description": "High-quality part for fan functionality" - }, - { - "id": 1484, - "name": "Fan Component 4", - "description": "High-quality part for fan functionality" - } - ], - "images": [ - { - "id": 148, - "url": "https://via.placeholder.com/400x300/0c3578/ffffff?text=SmartHome+Fan+907H", - "description": "Fan product image" - } - ], - "created_at": "2025-04-02T09:16:11.457377Z", - "updated_at": "2025-07-14T09:16:11.457377Z" - }, - { - "id": 149, - "name": "CleanWave Iron 405P", - "description": "CleanWave Iron 405P is a high-performance iron designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 5, - "name": "Office Equipment" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 2.5, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 26.5, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 22.1, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 811, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 7.6, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 6.7, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 7.6, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 4, - "name": "Mica", - "type": "Mineral" - }, - "percentage": 29.7, - "mass": 0.5, - "unit": "kg" - }, - { - "material": { - "id": 7, - "name": "Silicone", - "type": "Elastomer" - }, - "percentage": 70.3, - "mass": 2.04, - "unit": "kg" - } - ], - "components": [ - { - "id": 1491, - "name": "Iron Component 1", - "description": "High-quality part for iron functionality" - }, - { - "id": 1492, - "name": "Iron Component 2", - "description": "High-quality part for iron functionality" - }, - { - "id": 1493, - "name": "Iron Component 3", - "description": "High-quality part for iron functionality" - } - ], - "images": [ - { - "id": 149, - "url": "https://via.placeholder.com/400x300/060da7/ffffff?text=CleanWave+Iron+405P", - "description": "Iron product image" - } - ], - "created_at": "2025-04-13T09:16:11.457418Z", - "updated_at": "2025-06-25T09:16:11.457418Z" - }, - { - "id": 150, - "name": "PureLife Iron 151K", - "description": "PureLife Iron 151K is a high-performance iron designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 3, - "name": "Personal Care Device" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 2.12, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 31.0, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 18.4, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 1239, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 9.2, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 7.9, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 7.7, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 5, - "name": "Borosilicate Glass", - "type": "Glass" - }, - "percentage": 13.9, - "mass": 0.27, - "unit": "kg" - }, - { - "material": { - "id": 6, - "name": "Polypropylene", - "type": "Plastic" - }, - "percentage": 45.1, - "mass": 1.49, - "unit": "kg" - }, - { - "material": { - "id": 4, - "name": "Mica", - "type": "Mineral" - }, - "percentage": 11.5, - "mass": 0.29, - "unit": "kg" - }, - { - "material": { - "id": 2, - "name": "ABS Plastic", - "type": "Plastic" - }, - "percentage": 29.5, - "mass": 0.97, - "unit": "kg" - } - ], - "components": [ - { - "id": 1501, - "name": "Iron Component 1", - "description": "High-quality part for iron functionality" - }, - { - "id": 1502, - "name": "Iron Component 2", - "description": "High-quality part for iron functionality" - }, - { - "id": 1503, - "name": "Iron Component 3", - "description": "High-quality part for iron functionality" - }, - { - "id": 1504, - "name": "Iron Component 4", - "description": "High-quality part for iron functionality" - } - ], - "images": [ - { - "id": 150, - "url": "https://via.placeholder.com/400x300/054030/ffffff?text=PureLife+Iron+151K", - "description": "Iron product image" - } - ], - "created_at": "2025-03-09T09:16:11.457478Z", - "updated_at": "2025-05-10T09:16:11.457478Z" - }, - { - "id": 151, - "name": "ZenGear Fan 425K", - "description": "ZenGear Fan 425K is a high-performance fan designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 2, - "name": "Home Electronics" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 2.6, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 33.8, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 16.5, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 1316, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 8.9, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 7.6, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 8.7, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 7, - "name": "Silicone", - "type": "Elastomer" - }, - "percentage": 27.8, - "mass": 0.45, - "unit": "kg" - }, - { - "material": { - "id": 2, - "name": "ABS Plastic", - "type": "Plastic" - }, - "percentage": 72.2, - "mass": 0.79, - "unit": "kg" - } - ], - "components": [ - { - "id": 1511, - "name": "Fan Component 1", - "description": "High-quality part for fan functionality" - }, - { - "id": 1512, - "name": "Fan Component 2", - "description": "High-quality part for fan functionality" - }, - { - "id": 1513, - "name": "Fan Component 3", - "description": "High-quality part for fan functionality" - } - ], - "images": [ - { - "id": 151, - "url": "https://via.placeholder.com/400x300/05c99a/ffffff?text=ZenGear+Fan+425K", - "description": "Fan product image" - } - ], - "created_at": "2024-05-30T09:16:11.457516Z", - "updated_at": "2025-06-02T09:16:11.457516Z" - }, - { - "id": 152, - "name": "EcoTech Fan 802P", - "description": "EcoTech Fan 802P is a high-performance fan designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 4, - "name": "Smart Home Device" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 3.94, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 32.3, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 21.3, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 1916, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 6.2, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 7.4, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 9.2, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 6, - "name": "Polypropylene", - "type": "Plastic" - }, - "percentage": 44.8, - "mass": 1.3, - "unit": "kg" - }, - { - "material": { - "id": 1, - "name": "Stainless Steel", - "type": "Metal" - }, - "percentage": 55.2, - "mass": 1.07, - "unit": "kg" - } - ], - "components": [ - { - "id": 1521, - "name": "Fan Component 1", - "description": "High-quality part for fan functionality" - }, - { - "id": 1522, - "name": "Fan Component 2", - "description": "High-quality part for fan functionality" - }, - { - "id": 1523, - "name": "Fan Component 3", - "description": "High-quality part for fan functionality" - }, - { - "id": 1524, - "name": "Fan Component 4", - "description": "High-quality part for fan functionality" - } - ], - "images": [ - { - "id": 152, - "url": "https://via.placeholder.com/400x300/039628/ffffff?text=EcoTech+Fan+802P", - "description": "Fan product image" - } - ], - "created_at": "2024-07-26T09:16:11.457559Z", - "updated_at": "2025-05-26T09:16:11.457559Z" - }, - { - "id": 153, - "name": "NeoCook Iron 387O", - "description": "NeoCook Iron 387O is a high-performance iron designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 1, - "name": "Kitchen Appliance" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 2.91, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 33.1, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 28.9, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 900, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 8.7, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 7.0, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 6.4, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 4, - "name": "Mica", - "type": "Mineral" - }, - "percentage": 21.5, - "mass": 0.38, - "unit": "kg" - }, - { - "material": { - "id": 5, - "name": "Borosilicate Glass", - "type": "Glass" - }, - "percentage": 56.9, - "mass": 1.05, - "unit": "kg" - }, - { - "material": { - "id": 1, - "name": "Stainless Steel", - "type": "Metal" - }, - "percentage": 21.5, - "mass": 0.68, - "unit": "kg" - } - ], - "components": [ - { - "id": 1531, - "name": "Iron Component 1", - "description": "High-quality part for iron functionality" - }, - { - "id": 1532, - "name": "Iron Component 2", - "description": "High-quality part for iron functionality" - }, - { - "id": 1533, - "name": "Iron Component 3", - "description": "High-quality part for iron functionality" - } - ], - "images": [ - { - "id": 153, - "url": "https://via.placeholder.com/400x300/03d8f1/ffffff?text=NeoCook+Iron+387O", - "description": "Iron product image" - } - ], - "created_at": "2025-03-23T09:16:11.457614Z", - "updated_at": "2025-07-17T09:16:11.457614Z" - }, - { - "id": 154, - "name": "ChefMate Rice Cooker 645N", - "description": "ChefMate Rice Cooker 645N is a high-performance rice cooker designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 2, - "name": "Home Electronics" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 2.89, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 21.4, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 18.2, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 950, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 8.6, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 5.9, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 7.2, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 4, - "name": "Mica", - "type": "Mineral" - }, - "percentage": 21.1, - "mass": 0.82, - "unit": "kg" - }, - { - "material": { - "id": 3, - "name": "Copper Wire", - "type": "Metal" - }, - "percentage": 78.9, - "mass": 3.09, - "unit": "kg" - } - ], - "components": [ - { - "id": 1541, - "name": "Rice Cooker Component 1", - "description": "High-quality part for rice cooker functionality" - }, - { - "id": 1542, - "name": "Rice Cooker Component 2", - "description": "High-quality part for rice cooker functionality" - }, - { - "id": 1543, - "name": "Rice Cooker Component 3", - "description": "High-quality part for rice cooker functionality" - }, - { - "id": 1544, - "name": "Rice Cooker Component 4", - "description": "High-quality part for rice cooker functionality" - }, - { - "id": 1545, - "name": "Rice Cooker Component 5", - "description": "High-quality part for rice cooker functionality" - } - ], - "images": [ - { - "id": 154, - "url": "https://via.placeholder.com/400x300/05f50e/ffffff?text=ChefMate+Rice+Cooker+645N", - "description": "Rice Cooker product image" - } - ], - "created_at": "2024-03-24T09:16:11.457658Z", - "updated_at": "2025-05-24T09:16:11.457658Z" - }, - { - "id": 155, - "name": "SmartHome Coffee Maker 347W", - "description": "SmartHome Coffee Maker 347W is a high-performance coffee maker designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 4, - "name": "Smart Home Device" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 1.12, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 33.3, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 25.1, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 1116, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 8.0, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 7.1, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 8.0, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 1, - "name": "Stainless Steel", - "type": "Metal" - }, - "percentage": 44.3, - "mass": 1.0, - "unit": "kg" - }, - { - "material": { - "id": 5, - "name": "Borosilicate Glass", - "type": "Glass" - }, - "percentage": 55.7, - "mass": 0.85, - "unit": "kg" - } - ], - "components": [ - { - "id": 1551, - "name": "Coffee Maker Component 1", - "description": "High-quality part for coffee maker functionality" - }, - { - "id": 1552, - "name": "Coffee Maker Component 2", - "description": "High-quality part for coffee maker functionality" - }, - { - "id": 1553, - "name": "Coffee Maker Component 3", - "description": "High-quality part for coffee maker functionality" - }, - { - "id": 1554, - "name": "Coffee Maker Component 4", - "description": "High-quality part for coffee maker functionality" - }, - { - "id": 1555, - "name": "Coffee Maker Component 5", - "description": "High-quality part for coffee maker functionality" - } - ], - "images": [ - { - "id": 155, - "url": "https://via.placeholder.com/400x300/09b7f2/ffffff?text=SmartHome+Coffee+Maker+347W", - "description": "Coffee Maker product image" - } - ], - "created_at": "2024-06-06T09:16:11.457697Z", - "updated_at": "2025-05-31T09:16:11.457697Z" - }, - { - "id": 156, - "name": "SmartHome Humidifier 635C", - "description": "SmartHome Humidifier 635C is a high-performance humidifier designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 3, - "name": "Personal Care Device" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 2.99, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 25.8, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 20.8, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 1267, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 8.7, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 5.7, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 8.3, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 7, - "name": "Silicone", - "type": "Elastomer" - }, - "percentage": 26.7, - "mass": 0.39, - "unit": "kg" - }, - { - "material": { - "id": 6, - "name": "Polypropylene", - "type": "Plastic" - }, - "percentage": 13.3, - "mass": 0.32, - "unit": "kg" - }, - { - "material": { - "id": 3, - "name": "Copper Wire", - "type": "Metal" - }, - "percentage": 60.0, - "mass": 1.28, - "unit": "kg" - } - ], - "components": [ - { - "id": 1561, - "name": "Humidifier Component 1", - "description": "High-quality part for humidifier functionality" - }, - { - "id": 1562, - "name": "Humidifier Component 2", - "description": "High-quality part for humidifier functionality" - }, - { - "id": 1563, - "name": "Humidifier Component 3", - "description": "High-quality part for humidifier functionality" - }, - { - "id": 1564, - "name": "Humidifier Component 4", - "description": "High-quality part for humidifier functionality" - }, - { - "id": 1565, - "name": "Humidifier Component 5", - "description": "High-quality part for humidifier functionality" - } - ], - "images": [ - { - "id": 156, - "url": "https://via.placeholder.com/400x300/08a081/ffffff?text=SmartHome+Humidifier+635C", - "description": "Humidifier product image" - } - ], - "created_at": "2025-02-02T09:16:11.457947Z", - "updated_at": "2025-06-06T09:16:11.457947Z" - }, - { - "id": 157, - "name": "PureLife Iron 639P", - "description": "PureLife Iron 639P is a high-performance iron designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 4, - "name": "Smart Home Device" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 1.06, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 32.4, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 20.8, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 1800, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 6.2, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 8.8, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 7.3, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 3, - "name": "Copper Wire", - "type": "Metal" - }, - "percentage": 28.0, - "mass": 0.86, - "unit": "kg" - }, - { - "material": { - "id": 2, - "name": "ABS Plastic", - "type": "Plastic" - }, - "percentage": 72.0, - "mass": 1.99, - "unit": "kg" - } - ], - "components": [ - { - "id": 1571, - "name": "Iron Component 1", - "description": "High-quality part for iron functionality" - }, - { - "id": 1572, - "name": "Iron Component 2", - "description": "High-quality part for iron functionality" - }, - { - "id": 1573, - "name": "Iron Component 3", - "description": "High-quality part for iron functionality" - } - ], - "images": [ - { - "id": 157, - "url": "https://via.placeholder.com/400x300/08ca64/ffffff?text=PureLife+Iron+639P", - "description": "Iron product image" - } - ], - "created_at": "2025-03-31T09:16:11.458028Z", - "updated_at": "2025-06-02T09:16:11.458028Z" - }, - { - "id": 158, - "name": "PureLife Coffee Maker 399D", - "description": "PureLife Coffee Maker 399D is a high-performance coffee maker designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 5, - "name": "Office Equipment" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 1.85, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 25.8, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 24.7, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 1604, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 9.0, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 8.5, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 9.6, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 3, - "name": "Copper Wire", - "type": "Metal" - }, - "percentage": 31.2, - "mass": 1.14, - "unit": "kg" - }, - { - "material": { - "id": 4, - "name": "Mica", - "type": "Mineral" - }, - "percentage": 44.1, - "mass": 1.14, - "unit": "kg" - }, - { - "material": { - "id": 1, - "name": "Stainless Steel", - "type": "Metal" - }, - "percentage": 24.7, - "mass": 0.38, - "unit": "kg" - } - ], - "components": [ - { - "id": 1581, - "name": "Coffee Maker Component 1", - "description": "High-quality part for coffee maker functionality" - }, - { - "id": 1582, - "name": "Coffee Maker Component 2", - "description": "High-quality part for coffee maker functionality" - } - ], - "images": [ - { - "id": 158, - "url": "https://via.placeholder.com/400x300/0abfac/ffffff?text=PureLife+Coffee+Maker+399D", - "description": "Coffee Maker product image" - } - ], - "created_at": "2025-01-28T09:16:11.458092Z", - "updated_at": "2025-04-30T09:16:11.458092Z" - }, - { - "id": 159, - "name": "ZenGear Iron 956L", - "description": "ZenGear Iron 956L is a high-performance iron designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 4, - "name": "Smart Home Device" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 2.97, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 33.8, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 27.9, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 1118, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 9.0, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 8.4, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 8.2, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 6, - "name": "Polypropylene", - "type": "Plastic" - }, - "percentage": 30.1, - "mass": 0.43, - "unit": "kg" - }, - { - "material": { - "id": 3, - "name": "Copper Wire", - "type": "Metal" - }, - "percentage": 32.2, - "mass": 0.79, - "unit": "kg" - }, - { - "material": { - "id": 2, - "name": "ABS Plastic", - "type": "Plastic" - }, - "percentage": 17.5, - "mass": 0.38, - "unit": "kg" - }, - { - "material": { - "id": 1, - "name": "Stainless Steel", - "type": "Metal" - }, - "percentage": 20.2, - "mass": 0.58, - "unit": "kg" - } - ], - "components": [ - { - "id": 1591, - "name": "Iron Component 1", - "description": "High-quality part for iron functionality" - }, - { - "id": 1592, - "name": "Iron Component 2", - "description": "High-quality part for iron functionality" - }, - { - "id": 1593, - "name": "Iron Component 3", - "description": "High-quality part for iron functionality" - } - ], - "images": [ - { - "id": 159, - "url": "https://via.placeholder.com/400x300/097bdb/ffffff?text=ZenGear+Iron+956L", - "description": "Iron product image" - } - ], - "created_at": "2024-12-05T09:16:11.458161Z", - "updated_at": "2025-07-25T09:16:11.458161Z" - }, - { - "id": 160, - "name": "PureLife Air Purifier 644M", - "description": "PureLife Air Purifier 644M is a high-performance air purifier designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 5, - "name": "Office Equipment" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 1.08, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 26.6, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 15.6, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 1495, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 7.6, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 5.4, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 8.2, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 4, - "name": "Mica", - "type": "Mineral" - }, - "percentage": 39.7, - "mass": 0.93, - "unit": "kg" - }, - { - "material": { - "id": 1, - "name": "Stainless Steel", - "type": "Metal" - }, - "percentage": 11.1, - "mass": 0.38, - "unit": "kg" - }, - { - "material": { - "id": 6, - "name": "Polypropylene", - "type": "Plastic" - }, - "percentage": 20.6, - "mass": 0.6, - "unit": "kg" - }, - { - "material": { - "id": 3, - "name": "Copper Wire", - "type": "Metal" - }, - "percentage": 28.6, - "mass": 1.0, - "unit": "kg" - } - ], - "components": [ - { - "id": 1601, - "name": "Air Purifier Component 1", - "description": "High-quality part for air purifier functionality" - }, - { - "id": 1602, - "name": "Air Purifier Component 2", - "description": "High-quality part for air purifier functionality" - }, - { - "id": 1603, - "name": "Air Purifier Component 3", - "description": "High-quality part for air purifier functionality" - }, - { - "id": 1604, - "name": "Air Purifier Component 4", - "description": "High-quality part for air purifier functionality" - } - ], - "images": [ - { - "id": 160, - "url": "https://via.placeholder.com/400x300/073e17/ffffff?text=PureLife+Air+Purifier+644M", - "description": "Air Purifier product image" - } - ], - "created_at": "2024-08-24T09:16:11.458215Z", - "updated_at": "2025-06-09T09:16:11.458215Z" - }, - { - "id": 161, - "name": "ChefMate Coffee Maker 778K", - "description": "ChefMate Coffee Maker 778K is a high-performance coffee maker designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 1, - "name": "Kitchen Appliance" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 3.46, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 27.5, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 24.5, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 1729, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 7.6, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 6.7, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 6.7, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 3, - "name": "Copper Wire", - "type": "Metal" - }, - "percentage": 13.2, - "mass": 0.14, - "unit": "kg" - }, - { - "material": { - "id": 5, - "name": "Borosilicate Glass", - "type": "Glass" - }, - "percentage": 9.6, - "mass": 0.38, - "unit": "kg" - }, - { - "material": { - "id": 7, - "name": "Silicone", - "type": "Elastomer" - }, - "percentage": 38.2, - "mass": 1.48, - "unit": "kg" - }, - { - "material": { - "id": 1, - "name": "Stainless Steel", - "type": "Metal" - }, - "percentage": 39.0, - "mass": 1.35, - "unit": "kg" - } - ], - "components": [ - { - "id": 1611, - "name": "Coffee Maker Component 1", - "description": "High-quality part for coffee maker functionality" - }, - { - "id": 1612, - "name": "Coffee Maker Component 2", - "description": "High-quality part for coffee maker functionality" - }, - { - "id": 1613, - "name": "Coffee Maker Component 3", - "description": "High-quality part for coffee maker functionality" - }, - { - "id": 1614, - "name": "Coffee Maker Component 4", - "description": "High-quality part for coffee maker functionality" - }, - { - "id": 1615, - "name": "Coffee Maker Component 5", - "description": "High-quality part for coffee maker functionality" - } - ], - "images": [ - { - "id": 161, - "url": "https://via.placeholder.com/400x300/01bace/ffffff?text=ChefMate+Coffee+Maker+778K", - "description": "Coffee Maker product image" - } - ], - "created_at": "2025-04-18T09:16:11.458338Z", - "updated_at": "2025-05-01T09:16:11.458338Z" - }, - { - "id": 162, - "name": "ChefMate Fan 148C", - "description": "ChefMate Fan 148C is a high-performance fan designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 5, - "name": "Office Equipment" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 2.36, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 30.8, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 20.1, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 1754, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 8.1, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 5.4, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 8.3, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 2, - "name": "ABS Plastic", - "type": "Plastic" - }, - "percentage": 37.1, - "mass": 1.42, - "unit": "kg" - }, - { - "material": { - "id": 7, - "name": "Silicone", - "type": "Elastomer" - }, - "percentage": 40.9, - "mass": 1.48, - "unit": "kg" - }, - { - "material": { - "id": 5, - "name": "Borosilicate Glass", - "type": "Glass" - }, - "percentage": 22.0, - "mass": 0.22, - "unit": "kg" - } - ], - "components": [ - { - "id": 1621, - "name": "Fan Component 1", - "description": "High-quality part for fan functionality" - }, - { - "id": 1622, - "name": "Fan Component 2", - "description": "High-quality part for fan functionality" - }, - { - "id": 1623, - "name": "Fan Component 3", - "description": "High-quality part for fan functionality" - }, - { - "id": 1624, - "name": "Fan Component 4", - "description": "High-quality part for fan functionality" - } - ], - "images": [ - { - "id": 162, - "url": "https://via.placeholder.com/400x300/0d0929/ffffff?text=ChefMate+Fan+148C", - "description": "Fan product image" - } - ], - "created_at": "2024-05-26T09:16:11.458381Z", - "updated_at": "2025-05-22T09:16:11.458381Z" - }, - { - "id": 163, - "name": "SmartHome Fan 954Q", - "description": "SmartHome Fan 954Q is a high-performance fan designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 3, - "name": "Personal Care Device" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 1.35, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 25.7, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 26.1, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 1141, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 8.1, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 8.2, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 8.8, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 4, - "name": "Mica", - "type": "Mineral" - }, - "percentage": 78.5, - "mass": 1.88, - "unit": "kg" - }, - { - "material": { - "id": 6, - "name": "Polypropylene", - "type": "Plastic" - }, - "percentage": 21.5, - "mass": 0.5, - "unit": "kg" - } - ], - "components": [ - { - "id": 1631, - "name": "Fan Component 1", - "description": "High-quality part for fan functionality" - }, - { - "id": 1632, - "name": "Fan Component 2", - "description": "High-quality part for fan functionality" - }, - { - "id": 1633, - "name": "Fan Component 3", - "description": "High-quality part for fan functionality" - } - ], - "images": [ - { - "id": 163, - "url": "https://via.placeholder.com/400x300/072ef0/ffffff?text=SmartHome+Fan+954Q", - "description": "Fan product image" - } - ], - "created_at": "2024-08-17T09:16:11.458431Z", - "updated_at": "2025-06-02T09:16:11.458431Z" - }, - { - "id": 164, - "name": "PureLife Blender 806F", - "description": "PureLife Blender 806F is a high-performance blender designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 4, - "name": "Smart Home Device" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 1.15, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 21.3, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 26.2, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 993, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 6.3, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 8.9, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 9.2, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 2, - "name": "ABS Plastic", - "type": "Plastic" - }, - "percentage": 40.8, - "mass": 0.46, - "unit": "kg" - }, - { - "material": { - "id": 3, - "name": "Copper Wire", - "type": "Metal" - }, - "percentage": 45.6, - "mass": 1.31, - "unit": "kg" - }, - { - "material": { - "id": 5, - "name": "Borosilicate Glass", - "type": "Glass" - }, - "percentage": 13.6, - "mass": 0.52, - "unit": "kg" - } - ], - "components": [ - { - "id": 1641, - "name": "Blender Component 1", - "description": "High-quality part for blender functionality" - }, - { - "id": 1642, - "name": "Blender Component 2", - "description": "High-quality part for blender functionality" - }, - { - "id": 1643, - "name": "Blender Component 3", - "description": "High-quality part for blender functionality" - }, - { - "id": 1644, - "name": "Blender Component 4", - "description": "High-quality part for blender functionality" - }, - { - "id": 1645, - "name": "Blender Component 5", - "description": "High-quality part for blender functionality" - } - ], - "images": [ - { - "id": 164, - "url": "https://via.placeholder.com/400x300/03a7bb/ffffff?text=PureLife+Blender+806F", - "description": "Blender product image" - } - ], - "created_at": "2025-01-08T09:16:11.458628Z", - "updated_at": "2025-07-14T09:16:11.458628Z" - }, - { - "id": 165, - "name": "CleanWave Blender 124H", - "description": "CleanWave Blender 124H is a high-performance blender designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 1, - "name": "Kitchen Appliance" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 1.07, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 20.5, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 28.4, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 2192, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 7.5, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 5.4, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 6.1, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 1, - "name": "Stainless Steel", - "type": "Metal" - }, - "percentage": 39.6, - "mass": 0.67, - "unit": "kg" - }, - { - "material": { - "id": 4, - "name": "Mica", - "type": "Mineral" - }, - "percentage": 60.4, - "mass": 2.01, - "unit": "kg" - } - ], - "components": [ - { - "id": 1651, - "name": "Blender Component 1", - "description": "High-quality part for blender functionality" - }, - { - "id": 1652, - "name": "Blender Component 2", - "description": "High-quality part for blender functionality" - }, - { - "id": 1653, - "name": "Blender Component 3", - "description": "High-quality part for blender functionality" - }, - { - "id": 1654, - "name": "Blender Component 4", - "description": "High-quality part for blender functionality" - }, - { - "id": 1655, - "name": "Blender Component 5", - "description": "High-quality part for blender functionality" - } - ], - "images": [ - { - "id": 165, - "url": "https://via.placeholder.com/400x300/019b00/ffffff?text=CleanWave+Blender+124H", - "description": "Blender product image" - } - ], - "created_at": "2024-12-12T09:16:11.458679Z", - "updated_at": "2025-07-03T09:16:11.458679Z" - }, - { - "id": 166, - "name": "ChefMate Monitor 543X", - "description": "ChefMate Monitor 543X is a high-performance monitor designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 3, - "name": "Personal Care Device" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 2.8, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 27.6, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 24.8, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 1043, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 7.7, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 6.2, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 7.4, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 7, - "name": "Silicone", - "type": "Elastomer" - }, - "percentage": 27.9, - "mass": 0.58, - "unit": "kg" - }, - { - "material": { - "id": 1, - "name": "Stainless Steel", - "type": "Metal" - }, - "percentage": 17.3, - "mass": 0.37, - "unit": "kg" - }, - { - "material": { - "id": 5, - "name": "Borosilicate Glass", - "type": "Glass" - }, - "percentage": 14.4, - "mass": 0.42, - "unit": "kg" - }, - { - "material": { - "id": 6, - "name": "Polypropylene", - "type": "Plastic" - }, - "percentage": 40.4, - "mass": 1.46, - "unit": "kg" - } - ], - "components": [ - { - "id": 1661, - "name": "Monitor Component 1", - "description": "High-quality part for monitor functionality" - }, - { - "id": 1662, - "name": "Monitor Component 2", - "description": "High-quality part for monitor functionality" - } - ], - "images": [ - { - "id": 166, - "url": "https://via.placeholder.com/400x300/0d7224/ffffff?text=ChefMate+Monitor+543X", - "description": "Monitor product image" - } - ], - "created_at": "2025-01-27T09:16:11.458720Z", - "updated_at": "2025-06-05T09:16:11.458720Z" - }, - { - "id": 167, - "name": "ZenGear Iron 514I", - "description": "ZenGear Iron 514I is a high-performance iron designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 3, - "name": "Personal Care Device" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 2.01, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 28.3, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 26.1, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 1492, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 6.5, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 5.9, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 8.0, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 5, - "name": "Borosilicate Glass", - "type": "Glass" - }, - "percentage": 56.5, - "mass": 1.8, - "unit": "kg" - }, - { - "material": { - "id": 6, - "name": "Polypropylene", - "type": "Plastic" - }, - "percentage": 43.5, - "mass": 1.63, - "unit": "kg" - } - ], - "components": [ - { - "id": 1671, - "name": "Iron Component 1", - "description": "High-quality part for iron functionality" - }, - { - "id": 1672, - "name": "Iron Component 2", - "description": "High-quality part for iron functionality" - } - ], - "images": [ - { - "id": 167, - "url": "https://via.placeholder.com/400x300/0b2876/ffffff?text=ZenGear+Iron+514I", - "description": "Iron product image" - } - ], - "created_at": "2025-02-16T09:16:11.458757Z", - "updated_at": "2025-06-21T09:16:11.458757Z" - }, - { - "id": 168, - "name": "AquaPro Blender 568J", - "description": "AquaPro Blender 568J is a high-performance blender designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 4, - "name": "Smart Home Device" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 3.07, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 29.2, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 28.5, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 932, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 7.3, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 8.0, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 10.0, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 6, - "name": "Polypropylene", - "type": "Plastic" - }, - "percentage": 7.0, - "mass": 0.11, - "unit": "kg" - }, - { - "material": { - "id": 2, - "name": "ABS Plastic", - "type": "Plastic" - }, - "percentage": 42.3, - "mass": 0.65, - "unit": "kg" - }, - { - "material": { - "id": 7, - "name": "Silicone", - "type": "Elastomer" - }, - "percentage": 40.8, - "mass": 1.61, - "unit": "kg" - }, - { - "material": { - "id": 3, - "name": "Copper Wire", - "type": "Metal" - }, - "percentage": 9.9, - "mass": 0.16, - "unit": "kg" - } - ], - "components": [ - { - "id": 1681, - "name": "Blender Component 1", - "description": "High-quality part for blender functionality" - }, - { - "id": 1682, - "name": "Blender Component 2", - "description": "High-quality part for blender functionality" - }, - { - "id": 1683, - "name": "Blender Component 3", - "description": "High-quality part for blender functionality" - } - ], - "images": [ - { - "id": 168, - "url": "https://via.placeholder.com/400x300/0a0983/ffffff?text=AquaPro+Blender+568J", - "description": "Blender product image" - } - ], - "created_at": "2024-04-29T09:16:11.458791Z", - "updated_at": "2025-07-02T09:16:11.458791Z" - }, - { - "id": 169, - "name": "SmartHome Coffee Maker 447B", - "description": "SmartHome Coffee Maker 447B is a high-performance coffee maker designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 3, - "name": "Personal Care Device" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 2.03, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 31.9, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 15.7, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 1942, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 7.0, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 5.6, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 6.2, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 2, - "name": "ABS Plastic", - "type": "Plastic" - }, - "percentage": 38.8, - "mass": 0.77, - "unit": "kg" - }, - { - "material": { - "id": 6, - "name": "Polypropylene", - "type": "Plastic" - }, - "percentage": 9.5, - "mass": 0.13, - "unit": "kg" - }, - { - "material": { - "id": 4, - "name": "Mica", - "type": "Mineral" - }, - "percentage": 25.9, - "mass": 0.77, - "unit": "kg" - }, - { - "material": { - "id": 7, - "name": "Silicone", - "type": "Elastomer" - }, - "percentage": 25.9, - "mass": 0.85, - "unit": "kg" - } - ], - "components": [ - { - "id": 1691, - "name": "Coffee Maker Component 1", - "description": "High-quality part for coffee maker functionality" - }, - { - "id": 1692, - "name": "Coffee Maker Component 2", - "description": "High-quality part for coffee maker functionality" - } - ], - "images": [ - { - "id": 169, - "url": "https://via.placeholder.com/400x300/05bf0b/ffffff?text=SmartHome+Coffee+Maker+447B", - "description": "Coffee Maker product image" - } - ], - "created_at": "2024-03-19T09:16:11.458829Z", - "updated_at": "2025-07-14T09:16:11.458829Z" - }, - { - "id": 170, - "name": "ZenGear Humidifier 398I", - "description": "ZenGear Humidifier 398I is a high-performance humidifier designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 2, - "name": "Home Electronics" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 2.81, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 33.1, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 26.2, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 1109, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 8.7, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 6.4, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 8.8, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 1, - "name": "Stainless Steel", - "type": "Metal" - }, - "percentage": 27.3, - "mass": 1.0, - "unit": "kg" - }, - { - "material": { - "id": 3, - "name": "Copper Wire", - "type": "Metal" - }, - "percentage": 30.3, - "mass": 0.84, - "unit": "kg" - }, - { - "material": { - "id": 2, - "name": "ABS Plastic", - "type": "Plastic" - }, - "percentage": 42.4, - "mass": 1.65, - "unit": "kg" - } - ], - "components": [ - { - "id": 1701, - "name": "Humidifier Component 1", - "description": "High-quality part for humidifier functionality" - }, - { - "id": 1702, - "name": "Humidifier Component 2", - "description": "High-quality part for humidifier functionality" - }, - { - "id": 1703, - "name": "Humidifier Component 3", - "description": "High-quality part for humidifier functionality" - }, - { - "id": 1704, - "name": "Humidifier Component 4", - "description": "High-quality part for humidifier functionality" - } - ], - "images": [ - { - "id": 170, - "url": "https://via.placeholder.com/400x300/061b21/ffffff?text=ZenGear+Humidifier+398I", - "description": "Humidifier product image" - } - ], - "created_at": "2025-04-18T09:16:11.458866Z", - "updated_at": "2025-06-16T09:16:11.458866Z" - }, - { - "id": 171, - "name": "NeoCook Toaster 221Z", - "description": "NeoCook Toaster 221Z is a high-performance toaster designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 3, - "name": "Personal Care Device" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 2.89, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 26.8, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 27.6, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 1265, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 7.2, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 5.3, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 6.1, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 4, - "name": "Mica", - "type": "Mineral" - }, - "percentage": 46.4, - "mass": 0.8, - "unit": "kg" - }, - { - "material": { - "id": 3, - "name": "Copper Wire", - "type": "Metal" - }, - "percentage": 53.6, - "mass": 0.54, - "unit": "kg" - } - ], - "components": [ - { - "id": 1711, - "name": "Toaster Component 1", - "description": "High-quality part for toaster functionality" - }, - { - "id": 1712, - "name": "Toaster Component 2", - "description": "High-quality part for toaster functionality" - }, - { - "id": 1713, - "name": "Toaster Component 3", - "description": "High-quality part for toaster functionality" - }, - { - "id": 1714, - "name": "Toaster Component 4", - "description": "High-quality part for toaster functionality" - }, - { - "id": 1715, - "name": "Toaster Component 5", - "description": "High-quality part for toaster functionality" - } - ], - "images": [ - { - "id": 171, - "url": "https://via.placeholder.com/400x300/08cc4b/ffffff?text=NeoCook+Toaster+221Z", - "description": "Toaster product image" - } - ], - "created_at": "2024-11-01T09:16:11.458898Z", - "updated_at": "2025-07-30T09:16:11.458898Z" - }, - { - "id": 172, - "name": "SmartHome Coffee Maker 126B", - "description": "SmartHome Coffee Maker 126B is a high-performance coffee maker designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 5, - "name": "Office Equipment" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 2.85, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 22.1, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 27.6, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 1736, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 6.1, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 6.2, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 7.2, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 3, - "name": "Copper Wire", - "type": "Metal" - }, - "percentage": 29.5, - "mass": 1.11, - "unit": "kg" - }, - { - "material": { - "id": 7, - "name": "Silicone", - "type": "Elastomer" - }, - "percentage": 29.5, - "mass": 0.73, - "unit": "kg" - }, - { - "material": { - "id": 5, - "name": "Borosilicate Glass", - "type": "Glass" - }, - "percentage": 40.9, - "mass": 0.61, - "unit": "kg" - } - ], - "components": [ - { - "id": 1721, - "name": "Coffee Maker Component 1", - "description": "High-quality part for coffee maker functionality" - }, - { - "id": 1722, - "name": "Coffee Maker Component 2", - "description": "High-quality part for coffee maker functionality" - }, - { - "id": 1723, - "name": "Coffee Maker Component 3", - "description": "High-quality part for coffee maker functionality" - } - ], - "images": [ - { - "id": 172, - "url": "https://via.placeholder.com/400x300/074699/ffffff?text=SmartHome+Coffee+Maker+126B", - "description": "Coffee Maker product image" - } - ], - "created_at": "2024-12-15T09:16:11.458933Z", - "updated_at": "2025-05-08T09:16:11.458933Z" - }, - { - "id": 173, - "name": "ZenGear Fan 130W", - "description": "ZenGear Fan 130W is a high-performance fan designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 2, - "name": "Home Electronics" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 2.15, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 31.9, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 24.8, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 1338, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 7.2, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 8.5, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 7.8, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 2, - "name": "ABS Plastic", - "type": "Plastic" - }, - "percentage": 22.6, - "mass": 0.8, - "unit": "kg" - }, - { - "material": { - "id": 7, - "name": "Silicone", - "type": "Elastomer" - }, - "percentage": 28.0, - "mass": 0.48, - "unit": "kg" - }, - { - "material": { - "id": 6, - "name": "Polypropylene", - "type": "Plastic" - }, - "percentage": 49.5, - "mass": 1.18, - "unit": "kg" - } - ], - "components": [ - { - "id": 1731, - "name": "Fan Component 1", - "description": "High-quality part for fan functionality" - }, - { - "id": 1732, - "name": "Fan Component 2", - "description": "High-quality part for fan functionality" - } - ], - "images": [ - { - "id": 173, - "url": "https://via.placeholder.com/400x300/033a12/ffffff?text=ZenGear+Fan+130W", - "description": "Fan product image" - } - ], - "created_at": "2024-12-22T09:16:11.458986Z", - "updated_at": "2025-07-22T09:16:11.458986Z" - }, - { - "id": 174, - "name": "CleanWave Iron 282V", - "description": "CleanWave Iron 282V is a high-performance iron designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 2, - "name": "Home Electronics" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 3.31, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 23.4, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 22.1, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 871, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 9.0, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 7.8, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 8.6, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 5, - "name": "Borosilicate Glass", - "type": "Glass" - }, - "percentage": 49.0, - "mass": 1.28, - "unit": "kg" - }, - { - "material": { - "id": 6, - "name": "Polypropylene", - "type": "Plastic" - }, - "percentage": 51.0, - "mass": 1.11, - "unit": "kg" - } - ], - "components": [ - { - "id": 1741, - "name": "Iron Component 1", - "description": "High-quality part for iron functionality" - }, - { - "id": 1742, - "name": "Iron Component 2", - "description": "High-quality part for iron functionality" - } - ], - "images": [ - { - "id": 174, - "url": "https://via.placeholder.com/400x300/0659ce/ffffff?text=CleanWave+Iron+282V", - "description": "Iron product image" - } - ], - "created_at": "2024-04-23T09:16:11.459039Z", - "updated_at": "2025-06-21T09:16:11.459039Z" - }, - { - "id": 175, - "name": "ZenGear Kettle 134D", - "description": "ZenGear Kettle 134D is a high-performance kettle designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 2, - "name": "Home Electronics" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 1.38, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 27.6, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 16.0, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 1026, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 7.3, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 5.4, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 9.5, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 3, - "name": "Copper Wire", - "type": "Metal" - }, - "percentage": 22.6, - "mass": 0.4, - "unit": "kg" - }, - { - "material": { - "id": 1, - "name": "Stainless Steel", - "type": "Metal" - }, - "percentage": 39.1, - "mass": 0.98, - "unit": "kg" - }, - { - "material": { - "id": 2, - "name": "ABS Plastic", - "type": "Plastic" - }, - "percentage": 38.3, - "mass": 1.42, - "unit": "kg" - } - ], - "components": [ - { - "id": 1751, - "name": "Kettle Component 1", - "description": "High-quality part for kettle functionality" - }, - { - "id": 1752, - "name": "Kettle Component 2", - "description": "High-quality part for kettle functionality" - } - ], - "images": [ - { - "id": 175, - "url": "https://via.placeholder.com/400x300/0e1694/ffffff?text=ZenGear+Kettle+134D", - "description": "Kettle product image" - } - ], - "created_at": "2024-06-16T09:16:11.459086Z", - "updated_at": "2025-06-28T09:16:11.459086Z" - }, - { - "id": 176, - "name": "ChefMate Monitor 551S", - "description": "ChefMate Monitor 551S is a high-performance monitor designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 5, - "name": "Office Equipment" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 3.33, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 26.1, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 23.9, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 1685, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 9.3, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 8.3, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 8.6, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 6, - "name": "Polypropylene", - "type": "Plastic" - }, - "percentage": 49.0, - "mass": 0.53, - "unit": "kg" - }, - { - "material": { - "id": 4, - "name": "Mica", - "type": "Mineral" - }, - "percentage": 51.0, - "mass": 1.22, - "unit": "kg" - } - ], - "components": [ - { - "id": 1761, - "name": "Monitor Component 1", - "description": "High-quality part for monitor functionality" - }, - { - "id": 1762, - "name": "Monitor Component 2", - "description": "High-quality part for monitor functionality" - }, - { - "id": 1763, - "name": "Monitor Component 3", - "description": "High-quality part for monitor functionality" - }, - { - "id": 1764, - "name": "Monitor Component 4", - "description": "High-quality part for monitor functionality" - }, - { - "id": 1765, - "name": "Monitor Component 5", - "description": "High-quality part for monitor functionality" - } - ], - "images": [ - { - "id": 176, - "url": "https://via.placeholder.com/400x300/0e72cd/ffffff?text=ChefMate+Monitor+551S", - "description": "Monitor product image" - } - ], - "created_at": "2024-09-24T09:16:11.459141Z", - "updated_at": "2025-07-10T09:16:11.459141Z" - }, - { - "id": 177, - "name": "EcoTech Fan 100N", - "description": "EcoTech Fan 100N is a high-performance fan designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 2, - "name": "Home Electronics" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 3.36, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 26.9, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 16.8, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 2085, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 6.9, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 6.9, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 7.7, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 1, - "name": "Stainless Steel", - "type": "Metal" - }, - "percentage": 37.8, - "mass": 1.49, - "unit": "kg" - }, - { - "material": { - "id": 4, - "name": "Mica", - "type": "Mineral" - }, - "percentage": 18.9, - "mass": 0.21, - "unit": "kg" - }, - { - "material": { - "id": 5, - "name": "Borosilicate Glass", - "type": "Glass" - }, - "percentage": 43.2, - "mass": 0.58, - "unit": "kg" - } - ], - "components": [ - { - "id": 1771, - "name": "Fan Component 1", - "description": "High-quality part for fan functionality" - }, - { - "id": 1772, - "name": "Fan Component 2", - "description": "High-quality part for fan functionality" - }, - { - "id": 1773, - "name": "Fan Component 3", - "description": "High-quality part for fan functionality" - }, - { - "id": 1774, - "name": "Fan Component 4", - "description": "High-quality part for fan functionality" - } - ], - "images": [ - { - "id": 177, - "url": "https://via.placeholder.com/400x300/05ada2/ffffff?text=EcoTech+Fan+100N", - "description": "Fan product image" - } - ], - "created_at": "2024-10-23T09:16:11.459190Z", - "updated_at": "2025-05-09T09:16:11.459190Z" - }, - { - "id": 178, - "name": "ChefMate Humidifier 376F", - "description": "ChefMate Humidifier 376F is a high-performance humidifier designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 3, - "name": "Personal Care Device" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 2.03, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 26.8, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 18.7, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 1596, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 6.5, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 8.8, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 7.6, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 4, - "name": "Mica", - "type": "Mineral" - }, - "percentage": 41.4, - "mass": 0.54, - "unit": "kg" - }, - { - "material": { - "id": 2, - "name": "ABS Plastic", - "type": "Plastic" - }, - "percentage": 58.6, - "mass": 2.32, - "unit": "kg" - } - ], - "components": [ - { - "id": 1781, - "name": "Humidifier Component 1", - "description": "High-quality part for humidifier functionality" - }, - { - "id": 1782, - "name": "Humidifier Component 2", - "description": "High-quality part for humidifier functionality" - }, - { - "id": 1783, - "name": "Humidifier Component 3", - "description": "High-quality part for humidifier functionality" - } - ], - "images": [ - { - "id": 178, - "url": "https://via.placeholder.com/400x300/0c6482/ffffff?text=ChefMate+Humidifier+376F", - "description": "Humidifier product image" - } - ], - "created_at": "2025-04-04T09:16:11.459226Z", - "updated_at": "2025-07-25T09:16:11.459226Z" - }, - { - "id": 179, - "name": "ChefMate Monitor 876P", - "description": "ChefMate Monitor 876P is a high-performance monitor designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 2, - "name": "Home Electronics" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 1.56, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 30.1, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 16.1, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 1998, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 8.8, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 8.9, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 8.9, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 6, - "name": "Polypropylene", - "type": "Plastic" - }, - "percentage": 46.7, - "mass": 1.4, - "unit": "kg" - }, - { - "material": { - "id": 5, - "name": "Borosilicate Glass", - "type": "Glass" - }, - "percentage": 53.3, - "mass": 1.8, - "unit": "kg" - } - ], - "components": [ - { - "id": 1791, - "name": "Monitor Component 1", - "description": "High-quality part for monitor functionality" - }, - { - "id": 1792, - "name": "Monitor Component 2", - "description": "High-quality part for monitor functionality" - }, - { - "id": 1793, - "name": "Monitor Component 3", - "description": "High-quality part for monitor functionality" - }, - { - "id": 1794, - "name": "Monitor Component 4", - "description": "High-quality part for monitor functionality" - } - ], - "images": [ - { - "id": 179, - "url": "https://via.placeholder.com/400x300/069c1b/ffffff?text=ChefMate+Monitor+876P", - "description": "Monitor product image" - } - ], - "created_at": "2025-03-07T09:16:11.459264Z", - "updated_at": "2025-06-02T09:16:11.459264Z" - }, - { - "id": 180, - "name": "PureLife Blender 523P", - "description": "PureLife Blender 523P is a high-performance blender designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 3, - "name": "Personal Care Device" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 3.07, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 33.6, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 20.7, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 1200, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 8.0, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 6.2, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 6.5, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 2, - "name": "ABS Plastic", - "type": "Plastic" - }, - "percentage": 65.1, - "mass": 2.49, - "unit": "kg" - }, - { - "material": { - "id": 7, - "name": "Silicone", - "type": "Elastomer" - }, - "percentage": 34.9, - "mass": 1.13, - "unit": "kg" - } - ], - "components": [ - { - "id": 1801, - "name": "Blender Component 1", - "description": "High-quality part for blender functionality" - }, - { - "id": 1802, - "name": "Blender Component 2", - "description": "High-quality part for blender functionality" - }, - { - "id": 1803, - "name": "Blender Component 3", - "description": "High-quality part for blender functionality" - } - ], - "images": [ - { - "id": 180, - "url": "https://via.placeholder.com/400x300/07724e/ffffff?text=PureLife+Blender+523P", - "description": "Blender product image" - } - ], - "created_at": "2025-01-11T09:16:11.459308Z", - "updated_at": "2025-07-21T09:16:11.459308Z" - }, - { - "id": 181, - "name": "PureLife Rice Cooker 749I", - "description": "PureLife Rice Cooker 749I is a high-performance rice cooker designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 2, - "name": "Home Electronics" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 2.58, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 22.5, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 20.5, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 894, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 9.1, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 7.0, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 9.6, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 5, - "name": "Borosilicate Glass", - "type": "Glass" - }, - "percentage": 16.4, - "mass": 0.37, - "unit": "kg" - }, - { - "material": { - "id": 4, - "name": "Mica", - "type": "Mineral" - }, - "percentage": 22.4, - "mass": 0.3, - "unit": "kg" - }, - { - "material": { - "id": 2, - "name": "ABS Plastic", - "type": "Plastic" - }, - "percentage": 32.2, - "mass": 0.65, - "unit": "kg" - }, - { - "material": { - "id": 7, - "name": "Silicone", - "type": "Elastomer" - }, - "percentage": 28.9, - "mass": 1.12, - "unit": "kg" - } - ], - "components": [ - { - "id": 1811, - "name": "Rice Cooker Component 1", - "description": "High-quality part for rice cooker functionality" - }, - { - "id": 1812, - "name": "Rice Cooker Component 2", - "description": "High-quality part for rice cooker functionality" - }, - { - "id": 1813, - "name": "Rice Cooker Component 3", - "description": "High-quality part for rice cooker functionality" - }, - { - "id": 1814, - "name": "Rice Cooker Component 4", - "description": "High-quality part for rice cooker functionality" - } - ], - "images": [ - { - "id": 181, - "url": "https://via.placeholder.com/400x300/0bc755/ffffff?text=PureLife+Rice+Cooker+749I", - "description": "Rice Cooker product image" - } - ], - "created_at": "2025-01-29T09:16:11.459366Z", - "updated_at": "2025-04-25T09:16:11.459366Z" - }, - { - "id": 182, - "name": "NeoCook Blender 829D", - "description": "NeoCook Blender 829D is a high-performance blender designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 2, - "name": "Home Electronics" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 3.11, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 33.5, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 22.5, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 2108, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 8.8, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 6.4, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 7.9, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 7, - "name": "Silicone", - "type": "Elastomer" - }, - "percentage": 43.9, - "mass": 0.92, - "unit": "kg" - }, - { - "material": { - "id": 5, - "name": "Borosilicate Glass", - "type": "Glass" - }, - "percentage": 29.8, - "mass": 0.87, - "unit": "kg" - }, - { - "material": { - "id": 6, - "name": "Polypropylene", - "type": "Plastic" - }, - "percentage": 26.3, - "mass": 0.85, - "unit": "kg" - } - ], - "components": [ - { - "id": 1821, - "name": "Blender Component 1", - "description": "High-quality part for blender functionality" - }, - { - "id": 1822, - "name": "Blender Component 2", - "description": "High-quality part for blender functionality" - } - ], - "images": [ - { - "id": 182, - "url": "https://via.placeholder.com/400x300/07ebac/ffffff?text=NeoCook+Blender+829D", - "description": "Blender product image" - } - ], - "created_at": "2024-10-14T09:16:11.459428Z", - "updated_at": "2025-06-11T09:16:11.459428Z" - }, - { - "id": 183, - "name": "SmartHome Monitor 878G", - "description": "SmartHome Monitor 878G is a high-performance monitor designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 3, - "name": "Personal Care Device" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 1.42, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 34.1, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 20.5, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 1969, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 9.0, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 6.0, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 6.7, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 7, - "name": "Silicone", - "type": "Elastomer" - }, - "percentage": 31.1, - "mass": 0.89, - "unit": "kg" - }, - { - "material": { - "id": 1, - "name": "Stainless Steel", - "type": "Metal" - }, - "percentage": 10.9, - "mass": 0.36, - "unit": "kg" - }, - { - "material": { - "id": 5, - "name": "Borosilicate Glass", - "type": "Glass" - }, - "percentage": 20.2, - "mass": 0.65, - "unit": "kg" - }, - { - "material": { - "id": 6, - "name": "Polypropylene", - "type": "Plastic" - }, - "percentage": 37.8, - "mass": 0.45, - "unit": "kg" - } - ], - "components": [ - { - "id": 1831, - "name": "Monitor Component 1", - "description": "High-quality part for monitor functionality" - }, - { - "id": 1832, - "name": "Monitor Component 2", - "description": "High-quality part for monitor functionality" - }, - { - "id": 1833, - "name": "Monitor Component 3", - "description": "High-quality part for monitor functionality" - }, - { - "id": 1834, - "name": "Monitor Component 4", - "description": "High-quality part for monitor functionality" - } - ], - "images": [ - { - "id": 183, - "url": "https://via.placeholder.com/400x300/0eeb79/ffffff?text=SmartHome+Monitor+878G", - "description": "Monitor product image" - } - ], - "created_at": "2024-08-27T09:16:11.459490Z", - "updated_at": "2025-04-28T09:16:11.459490Z" - }, - { - "id": 184, - "name": "NeoCook Coffee Maker 492J", - "description": "NeoCook Coffee Maker 492J is a high-performance coffee maker designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 2, - "name": "Home Electronics" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 1.15, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 30.5, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 22.3, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 1698, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 6.8, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 5.1, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 9.7, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 6, - "name": "Polypropylene", - "type": "Plastic" - }, - "percentage": 32.9, - "mass": 1.08, - "unit": "kg" - }, - { - "material": { - "id": 1, - "name": "Stainless Steel", - "type": "Metal" - }, - "percentage": 31.1, - "mass": 1.21, - "unit": "kg" - }, - { - "material": { - "id": 2, - "name": "ABS Plastic", - "type": "Plastic" - }, - "percentage": 36.0, - "mass": 0.56, - "unit": "kg" - } - ], - "components": [ - { - "id": 1841, - "name": "Coffee Maker Component 1", - "description": "High-quality part for coffee maker functionality" - }, - { - "id": 1842, - "name": "Coffee Maker Component 2", - "description": "High-quality part for coffee maker functionality" - }, - { - "id": 1843, - "name": "Coffee Maker Component 3", - "description": "High-quality part for coffee maker functionality" - }, - { - "id": 1844, - "name": "Coffee Maker Component 4", - "description": "High-quality part for coffee maker functionality" - }, - { - "id": 1845, - "name": "Coffee Maker Component 5", - "description": "High-quality part for coffee maker functionality" - } - ], - "images": [ - { - "id": 184, - "url": "https://via.placeholder.com/400x300/0cea6a/ffffff?text=NeoCook+Coffee+Maker+492J", - "description": "Coffee Maker product image" - } - ], - "created_at": "2024-11-09T09:16:11.459534Z", - "updated_at": "2025-05-18T09:16:11.459534Z" - }, - { - "id": 185, - "name": "NeoCook Blender 191L", - "description": "NeoCook Blender 191L is a high-performance blender designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 5, - "name": "Office Equipment" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 2.07, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 21.7, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 29.4, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 1870, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 9.3, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 5.7, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 7.3, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 7, - "name": "Silicone", - "type": "Elastomer" - }, - "percentage": 33.5, - "mass": 0.52, - "unit": "kg" - }, - { - "material": { - "id": 5, - "name": "Borosilicate Glass", - "type": "Glass" - }, - "percentage": 7.2, - "mass": 0.27, - "unit": "kg" - }, - { - "material": { - "id": 4, - "name": "Mica", - "type": "Mineral" - }, - "percentage": 33.5, - "mass": 1.3, - "unit": "kg" - }, - { - "material": { - "id": 1, - "name": "Stainless Steel", - "type": "Metal" - }, - "percentage": 25.7, - "mass": 0.99, - "unit": "kg" - } - ], - "components": [ - { - "id": 1851, - "name": "Blender Component 1", - "description": "High-quality part for blender functionality" - }, - { - "id": 1852, - "name": "Blender Component 2", - "description": "High-quality part for blender functionality" - }, - { - "id": 1853, - "name": "Blender Component 3", - "description": "High-quality part for blender functionality" - }, - { - "id": 1854, - "name": "Blender Component 4", - "description": "High-quality part for blender functionality" - }, - { - "id": 1855, - "name": "Blender Component 5", - "description": "High-quality part for blender functionality" - } - ], - "images": [ - { - "id": 185, - "url": "https://via.placeholder.com/400x300/0bfcef/ffffff?text=NeoCook+Blender+191L", - "description": "Blender product image" - } - ], - "created_at": "2025-03-10T09:16:11.459585Z", - "updated_at": "2025-07-23T09:16:11.459585Z" - }, - { - "id": 186, - "name": "NeoCook Iron 604K", - "description": "NeoCook Iron 604K is a high-performance iron designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 1, - "name": "Kitchen Appliance" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 3.01, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 20.9, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 20.7, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 1356, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 7.2, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 5.8, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 6.3, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 1, - "name": "Stainless Steel", - "type": "Metal" - }, - "percentage": 25.5, - "mass": 0.99, - "unit": "kg" - }, - { - "material": { - "id": 3, - "name": "Copper Wire", - "type": "Metal" - }, - "percentage": 42.9, - "mass": 0.73, - "unit": "kg" - }, - { - "material": { - "id": 6, - "name": "Polypropylene", - "type": "Plastic" - }, - "percentage": 31.6, - "mass": 0.41, - "unit": "kg" - } - ], - "components": [ - { - "id": 1861, - "name": "Iron Component 1", - "description": "High-quality part for iron functionality" - }, - { - "id": 1862, - "name": "Iron Component 2", - "description": "High-quality part for iron functionality" - } - ], - "images": [ - { - "id": 186, - "url": "https://via.placeholder.com/400x300/0a08f5/ffffff?text=NeoCook+Iron+604K", - "description": "Iron product image" - } - ], - "created_at": "2024-12-10T09:16:11.459621Z", - "updated_at": "2025-05-07T09:16:11.459621Z" - }, - { - "id": 187, - "name": "ChefMate Iron 615G", - "description": "ChefMate Iron 615G is a high-performance iron designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 4, - "name": "Smart Home Device" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 1.51, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 28.1, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 20.6, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 1227, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 8.7, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 5.7, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 10.0, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 4, - "name": "Mica", - "type": "Mineral" - }, - "percentage": 9.4, - "mass": 0.36, - "unit": "kg" - }, - { - "material": { - "id": 7, - "name": "Silicone", - "type": "Elastomer" - }, - "percentage": 30.4, - "mass": 0.37, - "unit": "kg" - }, - { - "material": { - "id": 3, - "name": "Copper Wire", - "type": "Metal" - }, - "percentage": 26.3, - "mass": 0.32, - "unit": "kg" - }, - { - "material": { - "id": 6, - "name": "Polypropylene", - "type": "Plastic" - }, - "percentage": 33.9, - "mass": 1.02, - "unit": "kg" - } - ], - "components": [ - { - "id": 1871, - "name": "Iron Component 1", - "description": "High-quality part for iron functionality" - }, - { - "id": 1872, - "name": "Iron Component 2", - "description": "High-quality part for iron functionality" - } - ], - "images": [ - { - "id": 187, - "url": "https://via.placeholder.com/400x300/048ca6/ffffff?text=ChefMate+Iron+615G", - "description": "Iron product image" - } - ], - "created_at": "2024-03-26T09:16:11.459662Z", - "updated_at": "2025-06-06T09:16:11.459662Z" - }, - { - "id": 188, - "name": "NeoCook Rice Cooker 721C", - "description": "NeoCook Rice Cooker 721C is a high-performance rice cooker designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 2, - "name": "Home Electronics" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 1.62, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 23.0, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 22.4, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 1689, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 7.5, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 6.5, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 8.6, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 4, - "name": "Mica", - "type": "Mineral" - }, - "percentage": 43.0, - "mass": 0.98, - "unit": "kg" - }, - { - "material": { - "id": 5, - "name": "Borosilicate Glass", - "type": "Glass" - }, - "percentage": 40.2, - "mass": 1.34, - "unit": "kg" - }, - { - "material": { - "id": 6, - "name": "Polypropylene", - "type": "Plastic" - }, - "percentage": 16.8, - "mass": 0.37, - "unit": "kg" - } - ], - "components": [ - { - "id": 1881, - "name": "Rice Cooker Component 1", - "description": "High-quality part for rice cooker functionality" - }, - { - "id": 1882, - "name": "Rice Cooker Component 2", - "description": "High-quality part for rice cooker functionality" - }, - { - "id": 1883, - "name": "Rice Cooker Component 3", - "description": "High-quality part for rice cooker functionality" - }, - { - "id": 1884, - "name": "Rice Cooker Component 4", - "description": "High-quality part for rice cooker functionality" - }, - { - "id": 1885, - "name": "Rice Cooker Component 5", - "description": "High-quality part for rice cooker functionality" - } - ], - "images": [ - { - "id": 188, - "url": "https://via.placeholder.com/400x300/03116a/ffffff?text=NeoCook+Rice+Cooker+721C", - "description": "Rice Cooker product image" - } - ], - "created_at": "2024-04-17T09:16:11.459724Z", - "updated_at": "2025-05-24T09:16:11.459724Z" - }, - { - "id": 189, - "name": "ChefMate Monitor 877K", - "description": "ChefMate Monitor 877K is a high-performance monitor designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 3, - "name": "Personal Care Device" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 3.61, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 22.0, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 18.9, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 1175, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 8.5, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 6.7, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 6.6, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 3, - "name": "Copper Wire", - "type": "Metal" - }, - "percentage": 32.8, - "mass": 0.89, - "unit": "kg" - }, - { - "material": { - "id": 1, - "name": "Stainless Steel", - "type": "Metal" - }, - "percentage": 12.0, - "mass": 0.31, - "unit": "kg" - }, - { - "material": { - "id": 2, - "name": "ABS Plastic", - "type": "Plastic" - }, - "percentage": 30.4, - "mass": 1.16, - "unit": "kg" - }, - { - "material": { - "id": 7, - "name": "Silicone", - "type": "Elastomer" - }, - "percentage": 24.8, - "mass": 0.58, - "unit": "kg" - } - ], - "components": [ - { - "id": 1891, - "name": "Monitor Component 1", - "description": "High-quality part for monitor functionality" - }, - { - "id": 1892, - "name": "Monitor Component 2", - "description": "High-quality part for monitor functionality" - } - ], - "images": [ - { - "id": 189, - "url": "https://via.placeholder.com/400x300/05a4a4/ffffff?text=ChefMate+Monitor+877K", - "description": "Monitor product image" - } - ], - "created_at": "2024-06-19T09:16:11.459760Z", - "updated_at": "2025-05-24T09:16:11.459760Z" - }, - { - "id": 190, - "name": "AquaPro Humidifier 762F", - "description": "AquaPro Humidifier 762F is a high-performance humidifier designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 1, - "name": "Kitchen Appliance" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 1.49, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 31.3, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 24.2, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 1156, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 6.1, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 6.4, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 7.8, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 3, - "name": "Copper Wire", - "type": "Metal" - }, - "percentage": 40.0, - "mass": 0.55, - "unit": "kg" - }, - { - "material": { - "id": 4, - "name": "Mica", - "type": "Mineral" - }, - "percentage": 41.2, - "mass": 0.72, - "unit": "kg" - }, - { - "material": { - "id": 2, - "name": "ABS Plastic", - "type": "Plastic" - }, - "percentage": 18.8, - "mass": 0.32, - "unit": "kg" - } - ], - "components": [ - { - "id": 1901, - "name": "Humidifier Component 1", - "description": "High-quality part for humidifier functionality" - }, - { - "id": 1902, - "name": "Humidifier Component 2", - "description": "High-quality part for humidifier functionality" - }, - { - "id": 1903, - "name": "Humidifier Component 3", - "description": "High-quality part for humidifier functionality" - }, - { - "id": 1904, - "name": "Humidifier Component 4", - "description": "High-quality part for humidifier functionality" - } - ], - "images": [ - { - "id": 190, - "url": "https://via.placeholder.com/400x300/03f749/ffffff?text=AquaPro+Humidifier+762F", - "description": "Humidifier product image" - } - ], - "created_at": "2024-09-01T09:16:11.459793Z", - "updated_at": "2025-07-20T09:16:11.459793Z" - }, - { - "id": 191, - "name": "NeoCook Humidifier 113P", - "description": "NeoCook Humidifier 113P is a high-performance humidifier designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 3, - "name": "Personal Care Device" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 3.25, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 31.7, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 24.5, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 2075, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 6.5, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 7.9, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 6.9, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 4, - "name": "Mica", - "type": "Mineral" - }, - "percentage": 55.0, - "mass": 1.87, - "unit": "kg" - }, - { - "material": { - "id": 1, - "name": "Stainless Steel", - "type": "Metal" - }, - "percentage": 45.0, - "mass": 1.38, - "unit": "kg" - } - ], - "components": [ - { - "id": 1911, - "name": "Humidifier Component 1", - "description": "High-quality part for humidifier functionality" - }, - { - "id": 1912, - "name": "Humidifier Component 2", - "description": "High-quality part for humidifier functionality" - } - ], - "images": [ - { - "id": 191, - "url": "https://via.placeholder.com/400x300/0af212/ffffff?text=NeoCook+Humidifier+113P", - "description": "Humidifier product image" - } - ], - "created_at": "2024-06-25T09:16:11.459844Z", - "updated_at": "2025-05-10T09:16:11.459844Z" - }, - { - "id": 192, - "name": "PureLife Fan 544N", - "description": "PureLife Fan 544N is a high-performance fan designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 4, - "name": "Smart Home Device" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 3.33, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 22.0, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 20.1, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 1244, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 7.8, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 8.2, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 6.8, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 3, - "name": "Copper Wire", - "type": "Metal" - }, - "percentage": 24.2, - "mass": 0.35, - "unit": "kg" - }, - { - "material": { - "id": 1, - "name": "Stainless Steel", - "type": "Metal" - }, - "percentage": 42.4, - "mass": 1.67, - "unit": "kg" - }, - { - "material": { - "id": 2, - "name": "ABS Plastic", - "type": "Plastic" - }, - "percentage": 33.3, - "mass": 0.94, - "unit": "kg" - } - ], - "components": [ - { - "id": 1921, - "name": "Fan Component 1", - "description": "High-quality part for fan functionality" - }, - { - "id": 1922, - "name": "Fan Component 2", - "description": "High-quality part for fan functionality" - } - ], - "images": [ - { - "id": 192, - "url": "https://via.placeholder.com/400x300/0a688d/ffffff?text=PureLife+Fan+544N", - "description": "Fan product image" - } - ], - "created_at": "2024-06-04T09:16:11.459889Z", - "updated_at": "2025-06-21T09:16:11.459889Z" - }, - { - "id": 193, - "name": "CleanWave Monitor 173R", - "description": "CleanWave Monitor 173R is a high-performance monitor designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 1, - "name": "Kitchen Appliance" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 3.85, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 34.9, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 17.3, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 920, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 7.1, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 6.8, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 7.2, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 3, - "name": "Copper Wire", - "type": "Metal" - }, - "percentage": 42.0, - "mass": 1.53, - "unit": "kg" - }, - { - "material": { - "id": 6, - "name": "Polypropylene", - "type": "Plastic" - }, - "percentage": 29.4, - "mass": 0.39, - "unit": "kg" - }, - { - "material": { - "id": 7, - "name": "Silicone", - "type": "Elastomer" - }, - "percentage": 28.7, - "mass": 0.98, - "unit": "kg" - } - ], - "components": [ - { - "id": 1931, - "name": "Monitor Component 1", - "description": "High-quality part for monitor functionality" - }, - { - "id": 1932, - "name": "Monitor Component 2", - "description": "High-quality part for monitor functionality" - }, - { - "id": 1933, - "name": "Monitor Component 3", - "description": "High-quality part for monitor functionality" - } - ], - "images": [ - { - "id": 193, - "url": "https://via.placeholder.com/400x300/01c58a/ffffff?text=CleanWave+Monitor+173R", - "description": "Monitor product image" - } - ], - "created_at": "2025-02-06T09:16:11.459924Z", - "updated_at": "2025-07-06T09:16:11.459924Z" - }, - { - "id": 194, - "name": "ChefMate Monitor 848C", - "description": "ChefMate Monitor 848C is a high-performance monitor designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 3, - "name": "Personal Care Device" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 1.55, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 30.0, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 21.5, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 1298, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 8.2, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 5.0, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 8.0, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 7, - "name": "Silicone", - "type": "Elastomer" - }, - "percentage": 60.4, - "mass": 2.13, - "unit": "kg" - }, - { - "material": { - "id": 1, - "name": "Stainless Steel", - "type": "Metal" - }, - "percentage": 39.6, - "mass": 0.75, - "unit": "kg" - } - ], - "components": [ - { - "id": 1941, - "name": "Monitor Component 1", - "description": "High-quality part for monitor functionality" - }, - { - "id": 1942, - "name": "Monitor Component 2", - "description": "High-quality part for monitor functionality" - }, - { - "id": 1943, - "name": "Monitor Component 3", - "description": "High-quality part for monitor functionality" - } - ], - "images": [ - { - "id": 194, - "url": "https://via.placeholder.com/400x300/0d129a/ffffff?text=ChefMate+Monitor+848C", - "description": "Monitor product image" - } - ], - "created_at": "2024-08-11T09:16:11.459950Z", - "updated_at": "2025-07-26T09:16:11.459950Z" - }, - { - "id": 195, - "name": "NeoCook Monitor 299Z", - "description": "NeoCook Monitor 299Z is a high-performance monitor designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 5, - "name": "Office Equipment" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 3.35, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 32.0, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 20.5, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 1163, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 6.2, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 7.3, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 6.3, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 2, - "name": "ABS Plastic", - "type": "Plastic" - }, - "percentage": 45.0, - "mass": 1.69, - "unit": "kg" - }, - { - "material": { - "id": 5, - "name": "Borosilicate Glass", - "type": "Glass" - }, - "percentage": 55.0, - "mass": 2.01, - "unit": "kg" - } - ], - "components": [ - { - "id": 1951, - "name": "Monitor Component 1", - "description": "High-quality part for monitor functionality" - }, - { - "id": 1952, - "name": "Monitor Component 2", - "description": "High-quality part for monitor functionality" - } - ], - "images": [ - { - "id": 195, - "url": "https://via.placeholder.com/400x300/0475c3/ffffff?text=NeoCook+Monitor+299Z", - "description": "Monitor product image" - } - ], - "created_at": "2024-05-09T09:16:11.459985Z", - "updated_at": "2025-05-02T09:16:11.459985Z" - }, - { - "id": 196, - "name": "ZenGear Kettle 605E", - "description": "ZenGear Kettle 605E is a high-performance kettle designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 1, - "name": "Kitchen Appliance" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 2.13, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 30.3, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 26.2, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 882, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 8.2, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 8.6, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 8.7, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 7, - "name": "Silicone", - "type": "Elastomer" - }, - "percentage": 23.4, - "mass": 0.5, - "unit": "kg" - }, - { - "material": { - "id": 6, - "name": "Polypropylene", - "type": "Plastic" - }, - "percentage": 22.8, - "mass": 0.91, - "unit": "kg" - }, - { - "material": { - "id": 5, - "name": "Borosilicate Glass", - "type": "Glass" - }, - "percentage": 26.1, - "mass": 0.68, - "unit": "kg" - }, - { - "material": { - "id": 3, - "name": "Copper Wire", - "type": "Metal" - }, - "percentage": 27.7, - "mass": 0.46, - "unit": "kg" - } - ], - "components": [ - { - "id": 1961, - "name": "Kettle Component 1", - "description": "High-quality part for kettle functionality" - }, - { - "id": 1962, - "name": "Kettle Component 2", - "description": "High-quality part for kettle functionality" - }, - { - "id": 1963, - "name": "Kettle Component 3", - "description": "High-quality part for kettle functionality" - }, - { - "id": 1964, - "name": "Kettle Component 4", - "description": "High-quality part for kettle functionality" - }, - { - "id": 1965, - "name": "Kettle Component 5", - "description": "High-quality part for kettle functionality" - } - ], - "images": [ - { - "id": 196, - "url": "https://via.placeholder.com/400x300/051679/ffffff?text=ZenGear+Kettle+605E", - "description": "Kettle product image" - } - ], - "created_at": "2024-10-22T09:16:11.460074Z", - "updated_at": "2025-07-08T09:16:11.460074Z" - }, - { - "id": 197, - "name": "ChefMate Fan 829A", - "description": "ChefMate Fan 829A is a high-performance fan designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 5, - "name": "Office Equipment" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 2.24, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 27.6, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 16.5, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 1651, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 7.8, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 6.9, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 9.8, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 6, - "name": "Polypropylene", - "type": "Plastic" - }, - "percentage": 9.3, - "mass": 0.32, - "unit": "kg" - }, - { - "material": { - "id": 2, - "name": "ABS Plastic", - "type": "Plastic" - }, - "percentage": 10.9, - "mass": 0.15, - "unit": "kg" - }, - { - "material": { - "id": 7, - "name": "Silicone", - "type": "Elastomer" - }, - "percentage": 42.6, - "mass": 1.62, - "unit": "kg" - }, - { - "material": { - "id": 3, - "name": "Copper Wire", - "type": "Metal" - }, - "percentage": 37.2, - "mass": 1.48, - "unit": "kg" - } - ], - "components": [ - { - "id": 1971, - "name": "Fan Component 1", - "description": "High-quality part for fan functionality" - }, - { - "id": 1972, - "name": "Fan Component 2", - "description": "High-quality part for fan functionality" - }, - { - "id": 1973, - "name": "Fan Component 3", - "description": "High-quality part for fan functionality" - } - ], - "images": [ - { - "id": 197, - "url": "https://via.placeholder.com/400x300/038a09/ffffff?text=ChefMate+Fan+829A", - "description": "Fan product image" - } - ], - "created_at": "2024-07-18T09:16:11.460140Z", - "updated_at": "2025-04-30T09:16:11.460140Z" - }, - { - "id": 198, - "name": "CleanWave Blender 175J", - "description": "CleanWave Blender 175J is a high-performance blender designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 1, - "name": "Kitchen Appliance" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 1.03, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 22.0, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 22.4, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 829, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 9.0, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 8.1, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 9.6, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 6, - "name": "Polypropylene", - "type": "Plastic" - }, - "percentage": 15.2, - "mass": 0.16, - "unit": "kg" - }, - { - "material": { - "id": 1, - "name": "Stainless Steel", - "type": "Metal" - }, - "percentage": 42.8, - "mass": 1.11, - "unit": "kg" - }, - { - "material": { - "id": 7, - "name": "Silicone", - "type": "Elastomer" - }, - "percentage": 23.9, - "mass": 0.46, - "unit": "kg" - }, - { - "material": { - "id": 5, - "name": "Borosilicate Glass", - "type": "Glass" - }, - "percentage": 18.1, - "mass": 0.69, - "unit": "kg" - } - ], - "components": [ - { - "id": 1981, - "name": "Blender Component 1", - "description": "High-quality part for blender functionality" - }, - { - "id": 1982, - "name": "Blender Component 2", - "description": "High-quality part for blender functionality" - } - ], - "images": [ - { - "id": 198, - "url": "https://via.placeholder.com/400x300/028e3f/ffffff?text=CleanWave+Blender+175J", - "description": "Blender product image" - } - ], - "created_at": "2025-03-31T09:16:11.460191Z", - "updated_at": "2025-07-07T09:16:11.460191Z" - }, - { - "id": 199, - "name": "ChefMate Humidifier 238X", - "description": "ChefMate Humidifier 238X is a high-performance humidifier designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 2, - "name": "Home Electronics" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 2.96, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 24.6, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 29.3, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 1673, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 9.0, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 8.8, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 7.0, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 3, - "name": "Copper Wire", - "type": "Metal" - }, - "percentage": 64.9, - "mass": 1.12, - "unit": "kg" - }, - { - "material": { - "id": 2, - "name": "ABS Plastic", - "type": "Plastic" - }, - "percentage": 35.1, - "mass": 0.87, - "unit": "kg" - } - ], - "components": [ - { - "id": 1991, - "name": "Humidifier Component 1", - "description": "High-quality part for humidifier functionality" - }, - { - "id": 1992, - "name": "Humidifier Component 2", - "description": "High-quality part for humidifier functionality" - }, - { - "id": 1993, - "name": "Humidifier Component 3", - "description": "High-quality part for humidifier functionality" - } - ], - "images": [ - { - "id": 199, - "url": "https://via.placeholder.com/400x300/05d368/ffffff?text=ChefMate+Humidifier+238X", - "description": "Humidifier product image" - } - ], - "created_at": "2025-04-07T09:16:11.460242Z", - "updated_at": "2025-06-09T09:16:11.460242Z" - }, - { - "id": 200, - "name": "AquaPro Fan 496Z", - "description": "AquaPro Fan 496Z is a high-performance fan designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 2, - "name": "Home Electronics" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 2.11, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 23.9, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 29.5, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 2153, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 7.5, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 5.9, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 6.3, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 4, - "name": "Mica", - "type": "Mineral" - }, - "percentage": 30.5, - "mass": 0.65, - "unit": "kg" - }, - { - "material": { - "id": 6, - "name": "Polypropylene", - "type": "Plastic" - }, - "percentage": 25.7, - "mass": 0.68, - "unit": "kg" - }, - { - "material": { - "id": 2, - "name": "ABS Plastic", - "type": "Plastic" - }, - "percentage": 11.4, - "mass": 0.43, - "unit": "kg" - }, - { - "material": { - "id": 3, - "name": "Copper Wire", - "type": "Metal" - }, - "percentage": 32.4, - "mass": 0.67, - "unit": "kg" - } - ], - "components": [ - { - "id": 2001, - "name": "Fan Component 1", - "description": "High-quality part for fan functionality" - }, - { - "id": 2002, - "name": "Fan Component 2", - "description": "High-quality part for fan functionality" - } - ], - "images": [ - { - "id": 200, - "url": "https://via.placeholder.com/400x300/034f85/ffffff?text=AquaPro+Fan+496Z", - "description": "Fan product image" - } - ], - "created_at": "2025-03-22T09:16:11.460292Z", - "updated_at": "2025-06-20T09:16:11.460292Z" - }, - { - "id": 201, - "name": "NeoCook Blender 309E", - "description": "NeoCook Blender 309E is a high-performance blender designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 4, - "name": "Smart Home Device" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 2.15, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 29.2, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 17.5, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 2087, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 7.4, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 7.6, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 6.3, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 7, - "name": "Silicone", - "type": "Elastomer" - }, - "percentage": 38.2, - "mass": 0.96, - "unit": "kg" - }, - { - "material": { - "id": 3, - "name": "Copper Wire", - "type": "Metal" - }, - "percentage": 16.8, - "mass": 0.39, - "unit": "kg" - }, - { - "material": { - "id": 2, - "name": "ABS Plastic", - "type": "Plastic" - }, - "percentage": 45.0, - "mass": 1.6, - "unit": "kg" - } - ], - "components": [ - { - "id": 2011, - "name": "Blender Component 1", - "description": "High-quality part for blender functionality" - }, - { - "id": 2012, - "name": "Blender Component 2", - "description": "High-quality part for blender functionality" - } - ], - "images": [ - { - "id": 201, - "url": "https://via.placeholder.com/400x300/058ce4/ffffff?text=NeoCook+Blender+309E", - "description": "Blender product image" - } - ], - "created_at": "2024-09-09T09:16:11.460352Z", - "updated_at": "2025-06-24T09:16:11.460352Z" - }, - { - "id": 202, - "name": "NeoCook Kettle 631F", - "description": "NeoCook Kettle 631F is a high-performance kettle designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 1, - "name": "Kitchen Appliance" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 3.45, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 33.2, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 23.5, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 957, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 6.5, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 6.3, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 8.5, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 2, - "name": "ABS Plastic", - "type": "Plastic" - }, - "percentage": 37.0, - "mass": 0.39, - "unit": "kg" - }, - { - "material": { - "id": 5, - "name": "Borosilicate Glass", - "type": "Glass" - }, - "percentage": 63.0, - "mass": 1.16, - "unit": "kg" - } - ], - "components": [ - { - "id": 2021, - "name": "Kettle Component 1", - "description": "High-quality part for kettle functionality" - }, - { - "id": 2022, - "name": "Kettle Component 2", - "description": "High-quality part for kettle functionality" - }, - { - "id": 2023, - "name": "Kettle Component 3", - "description": "High-quality part for kettle functionality" - }, - { - "id": 2024, - "name": "Kettle Component 4", - "description": "High-quality part for kettle functionality" - }, - { - "id": 2025, - "name": "Kettle Component 5", - "description": "High-quality part for kettle functionality" - } - ], - "images": [ - { - "id": 202, - "url": "https://via.placeholder.com/400x300/04c645/ffffff?text=NeoCook+Kettle+631F", - "description": "Kettle product image" - } - ], - "created_at": "2024-11-19T09:16:11.460397Z", - "updated_at": "2025-07-27T09:16:11.460397Z" - }, - { - "id": 203, - "name": "SmartHome Kettle 398Z", - "description": "SmartHome Kettle 398Z is a high-performance kettle designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 5, - "name": "Office Equipment" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 2.36, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 26.2, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 26.7, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 1592, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 6.3, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 6.0, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 7.7, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 5, - "name": "Borosilicate Glass", - "type": "Glass" - }, - "percentage": 21.6, - "mass": 0.61, - "unit": "kg" - }, - { - "material": { - "id": 4, - "name": "Mica", - "type": "Mineral" - }, - "percentage": 20.1, - "mass": 0.59, - "unit": "kg" - }, - { - "material": { - "id": 1, - "name": "Stainless Steel", - "type": "Metal" - }, - "percentage": 25.4, - "mass": 0.28, - "unit": "kg" - }, - { - "material": { - "id": 6, - "name": "Polypropylene", - "type": "Plastic" - }, - "percentage": 32.8, - "mass": 0.76, - "unit": "kg" - } - ], - "components": [ - { - "id": 2031, - "name": "Kettle Component 1", - "description": "High-quality part for kettle functionality" - }, - { - "id": 2032, - "name": "Kettle Component 2", - "description": "High-quality part for kettle functionality" - }, - { - "id": 2033, - "name": "Kettle Component 3", - "description": "High-quality part for kettle functionality" - }, - { - "id": 2034, - "name": "Kettle Component 4", - "description": "High-quality part for kettle functionality" - }, - { - "id": 2035, - "name": "Kettle Component 5", - "description": "High-quality part for kettle functionality" - } - ], - "images": [ - { - "id": 203, - "url": "https://via.placeholder.com/400x300/04379f/ffffff?text=SmartHome+Kettle+398Z", - "description": "Kettle product image" - } - ], - "created_at": "2024-07-22T09:16:11.460453Z", - "updated_at": "2025-06-15T09:16:11.460453Z" - }, - { - "id": 204, - "name": "ChefMate Air Purifier 481K", - "description": "ChefMate Air Purifier 481K is a high-performance air purifier designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 1, - "name": "Kitchen Appliance" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 1.4, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 25.0, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 28.4, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 1486, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 8.3, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 8.7, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 6.4, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 4, - "name": "Mica", - "type": "Mineral" - }, - "percentage": 28.3, - "mass": 0.46, - "unit": "kg" - }, - { - "material": { - "id": 7, - "name": "Silicone", - "type": "Elastomer" - }, - "percentage": 40.0, - "mass": 1.25, - "unit": "kg" - }, - { - "material": { - "id": 1, - "name": "Stainless Steel", - "type": "Metal" - }, - "percentage": 12.4, - "mass": 0.14, - "unit": "kg" - }, - { - "material": { - "id": 5, - "name": "Borosilicate Glass", - "type": "Glass" - }, - "percentage": 19.3, - "mass": 0.75, - "unit": "kg" - } - ], - "components": [ - { - "id": 2041, - "name": "Air Purifier Component 1", - "description": "High-quality part for air purifier functionality" - }, - { - "id": 2042, - "name": "Air Purifier Component 2", - "description": "High-quality part for air purifier functionality" - }, - { - "id": 2043, - "name": "Air Purifier Component 3", - "description": "High-quality part for air purifier functionality" - }, - { - "id": 2044, - "name": "Air Purifier Component 4", - "description": "High-quality part for air purifier functionality" - }, - { - "id": 2045, - "name": "Air Purifier Component 5", - "description": "High-quality part for air purifier functionality" - } - ], - "images": [ - { - "id": 204, - "url": "https://via.placeholder.com/400x300/0707d1/ffffff?text=ChefMate+Air+Purifier+481K", - "description": "Air Purifier product image" - } - ], - "created_at": "2024-04-01T09:16:11.460520Z", - "updated_at": "2025-07-05T09:16:11.460520Z" - }, - { - "id": 205, - "name": "EcoTech Blender 294G", - "description": "EcoTech Blender 294G is a high-performance blender designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 2, - "name": "Home Electronics" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 2.52, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 29.9, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 16.5, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 1636, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 8.6, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 8.5, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 9.2, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 5, - "name": "Borosilicate Glass", - "type": "Glass" - }, - "percentage": 33.6, - "mass": 0.74, - "unit": "kg" - }, - { - "material": { - "id": 3, - "name": "Copper Wire", - "type": "Metal" - }, - "percentage": 30.0, - "mass": 0.37, - "unit": "kg" - }, - { - "material": { - "id": 6, - "name": "Polypropylene", - "type": "Plastic" - }, - "percentage": 36.4, - "mass": 0.88, - "unit": "kg" - } - ], - "components": [ - { - "id": 2051, - "name": "Blender Component 1", - "description": "High-quality part for blender functionality" - }, - { - "id": 2052, - "name": "Blender Component 2", - "description": "High-quality part for blender functionality" - }, - { - "id": 2053, - "name": "Blender Component 3", - "description": "High-quality part for blender functionality" - }, - { - "id": 2054, - "name": "Blender Component 4", - "description": "High-quality part for blender functionality" - }, - { - "id": 2055, - "name": "Blender Component 5", - "description": "High-quality part for blender functionality" - } - ], - "images": [ - { - "id": 205, - "url": "https://via.placeholder.com/400x300/093ae7/ffffff?text=EcoTech+Blender+294G", - "description": "Blender product image" - } - ], - "created_at": "2024-07-29T09:16:11.460570Z", - "updated_at": "2025-05-05T09:16:11.460570Z" - }, - { - "id": 206, - "name": "PureLife Kettle 641E", - "description": "PureLife Kettle 641E is a high-performance kettle designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 5, - "name": "Office Equipment" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 1.21, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 32.5, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 22.5, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 1325, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 6.3, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 6.5, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 9.5, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 6, - "name": "Polypropylene", - "type": "Plastic" - }, - "percentage": 71.2, - "mass": 1.36, - "unit": "kg" - }, - { - "material": { - "id": 4, - "name": "Mica", - "type": "Mineral" - }, - "percentage": 28.8, - "mass": 0.72, - "unit": "kg" - } - ], - "components": [ - { - "id": 2061, - "name": "Kettle Component 1", - "description": "High-quality part for kettle functionality" - }, - { - "id": 2062, - "name": "Kettle Component 2", - "description": "High-quality part for kettle functionality" - } - ], - "images": [ - { - "id": 206, - "url": "https://via.placeholder.com/400x300/071524/ffffff?text=PureLife+Kettle+641E", - "description": "Kettle product image" - } - ], - "created_at": "2024-09-16T09:16:11.460611Z", - "updated_at": "2025-05-13T09:16:11.460611Z" - }, - { - "id": 207, - "name": "ChefMate Fan 302I", - "description": "ChefMate Fan 302I is a high-performance fan designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 4, - "name": "Smart Home Device" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 2.07, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 28.4, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 20.1, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 1465, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 8.5, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 6.2, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 8.1, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 3, - "name": "Copper Wire", - "type": "Metal" - }, - "percentage": 40.0, - "mass": 0.47, - "unit": "kg" - }, - { - "material": { - "id": 7, - "name": "Silicone", - "type": "Elastomer" - }, - "percentage": 60.0, - "mass": 1.11, - "unit": "kg" - } - ], - "components": [ - { - "id": 2071, - "name": "Fan Component 1", - "description": "High-quality part for fan functionality" - }, - { - "id": 2072, - "name": "Fan Component 2", - "description": "High-quality part for fan functionality" - }, - { - "id": 2073, - "name": "Fan Component 3", - "description": "High-quality part for fan functionality" - }, - { - "id": 2074, - "name": "Fan Component 4", - "description": "High-quality part for fan functionality" - }, - { - "id": 2075, - "name": "Fan Component 5", - "description": "High-quality part for fan functionality" - } - ], - "images": [ - { - "id": 207, - "url": "https://via.placeholder.com/400x300/0c3abe/ffffff?text=ChefMate+Fan+302I", - "description": "Fan product image" - } - ], - "created_at": "2024-11-19T09:16:11.460661Z", - "updated_at": "2025-05-09T09:16:11.460661Z" - }, - { - "id": 208, - "name": "AquaPro Monitor 969U", - "description": "AquaPro Monitor 969U is a high-performance monitor designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 4, - "name": "Smart Home Device" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 1.81, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 32.1, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 15.0, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 1779, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 9.1, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 8.0, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 9.7, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 1, - "name": "Stainless Steel", - "type": "Metal" - }, - "percentage": 56.1, - "mass": 0.68, - "unit": "kg" - }, - { - "material": { - "id": 5, - "name": "Borosilicate Glass", - "type": "Glass" - }, - "percentage": 43.9, - "mass": 1.01, - "unit": "kg" - } - ], - "components": [ - { - "id": 2081, - "name": "Monitor Component 1", - "description": "High-quality part for monitor functionality" - }, - { - "id": 2082, - "name": "Monitor Component 2", - "description": "High-quality part for monitor functionality" - }, - { - "id": 2083, - "name": "Monitor Component 3", - "description": "High-quality part for monitor functionality" - }, - { - "id": 2084, - "name": "Monitor Component 4", - "description": "High-quality part for monitor functionality" - } - ], - "images": [ - { - "id": 208, - "url": "https://via.placeholder.com/400x300/0481cb/ffffff?text=AquaPro+Monitor+969U", - "description": "Monitor product image" - } - ], - "created_at": "2024-11-09T09:16:11.460690Z", - "updated_at": "2025-07-19T09:16:11.460690Z" - }, - { - "id": 209, - "name": "AquaPro Air Purifier 689J", - "description": "AquaPro Air Purifier 689J is a high-performance air purifier designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 4, - "name": "Smart Home Device" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 2.26, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 23.3, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 23.7, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 1256, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 7.3, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 6.0, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 8.0, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 2, - "name": "ABS Plastic", - "type": "Plastic" - }, - "percentage": 50.4, - "mass": 1.6, - "unit": "kg" - }, - { - "material": { - "id": 1, - "name": "Stainless Steel", - "type": "Metal" - }, - "percentage": 49.6, - "mass": 1.1, - "unit": "kg" - } - ], - "components": [ - { - "id": 2091, - "name": "Air Purifier Component 1", - "description": "High-quality part for air purifier functionality" - }, - { - "id": 2092, - "name": "Air Purifier Component 2", - "description": "High-quality part for air purifier functionality" - }, - { - "id": 2093, - "name": "Air Purifier Component 3", - "description": "High-quality part for air purifier functionality" - } - ], - "images": [ - { - "id": 209, - "url": "https://via.placeholder.com/400x300/0d732a/ffffff?text=AquaPro+Air+Purifier+689J", - "description": "Air Purifier product image" - } - ], - "created_at": "2024-06-10T09:16:11.460721Z", - "updated_at": "2025-06-13T09:16:11.460721Z" - }, - { - "id": 210, - "name": "NeoCook Iron 975Q", - "description": "NeoCook Iron 975Q is a high-performance iron designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 2, - "name": "Home Electronics" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 1.73, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 20.2, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 15.3, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 1365, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 8.3, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 6.9, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 9.2, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 4, - "name": "Mica", - "type": "Mineral" - }, - "percentage": 43.2, - "mass": 1.67, - "unit": "kg" - }, - { - "material": { - "id": 5, - "name": "Borosilicate Glass", - "type": "Glass" - }, - "percentage": 38.6, - "mass": 1.03, - "unit": "kg" - }, - { - "material": { - "id": 1, - "name": "Stainless Steel", - "type": "Metal" - }, - "percentage": 18.2, - "mass": 0.34, - "unit": "kg" - } - ], - "components": [ - { - "id": 2101, - "name": "Iron Component 1", - "description": "High-quality part for iron functionality" - }, - { - "id": 2102, - "name": "Iron Component 2", - "description": "High-quality part for iron functionality" - }, - { - "id": 2103, - "name": "Iron Component 3", - "description": "High-quality part for iron functionality" - }, - { - "id": 2104, - "name": "Iron Component 4", - "description": "High-quality part for iron functionality" - } - ], - "images": [ - { - "id": 210, - "url": "https://via.placeholder.com/400x300/0ecacf/ffffff?text=NeoCook+Iron+975Q", - "description": "Iron product image" - } - ], - "created_at": "2024-03-26T09:16:11.460775Z", - "updated_at": "2025-05-10T09:16:11.460775Z" - }, - { - "id": 211, - "name": "ChefMate Rice Cooker 688A", - "description": "ChefMate Rice Cooker 688A is a high-performance rice cooker designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 4, - "name": "Smart Home Device" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 3.6, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 29.1, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 16.3, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 1670, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 6.7, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 5.0, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 8.3, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 3, - "name": "Copper Wire", - "type": "Metal" - }, - "percentage": 45.0, - "mass": 0.95, - "unit": "kg" - }, - { - "material": { - "id": 5, - "name": "Borosilicate Glass", - "type": "Glass" - }, - "percentage": 55.0, - "mass": 1.27, - "unit": "kg" - } - ], - "components": [ - { - "id": 2111, - "name": "Rice Cooker Component 1", - "description": "High-quality part for rice cooker functionality" - }, - { - "id": 2112, - "name": "Rice Cooker Component 2", - "description": "High-quality part for rice cooker functionality" - }, - { - "id": 2113, - "name": "Rice Cooker Component 3", - "description": "High-quality part for rice cooker functionality" - }, - { - "id": 2114, - "name": "Rice Cooker Component 4", - "description": "High-quality part for rice cooker functionality" - }, - { - "id": 2115, - "name": "Rice Cooker Component 5", - "description": "High-quality part for rice cooker functionality" - } - ], - "images": [ - { - "id": 211, - "url": "https://via.placeholder.com/400x300/0905d7/ffffff?text=ChefMate+Rice+Cooker+688A", - "description": "Rice Cooker product image" - } - ], - "created_at": "2025-02-26T09:16:11.460815Z", - "updated_at": "2025-06-30T09:16:11.460815Z" - }, - { - "id": 212, - "name": "CleanWave Toaster 324U", - "description": "CleanWave Toaster 324U is a high-performance toaster designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 1, - "name": "Kitchen Appliance" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 3.32, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 28.6, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 25.7, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 1310, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 7.1, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 8.6, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 7.3, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 7, - "name": "Silicone", - "type": "Elastomer" - }, - "percentage": 21.8, - "mass": 0.81, - "unit": "kg" - }, - { - "material": { - "id": 2, - "name": "ABS Plastic", - "type": "Plastic" - }, - "percentage": 22.9, - "mass": 0.51, - "unit": "kg" - }, - { - "material": { - "id": 6, - "name": "Polypropylene", - "type": "Plastic" - }, - "percentage": 27.9, - "mass": 0.42, - "unit": "kg" - }, - { - "material": { - "id": 3, - "name": "Copper Wire", - "type": "Metal" - }, - "percentage": 27.4, - "mass": 0.8, - "unit": "kg" - } - ], - "components": [ - { - "id": 2121, - "name": "Toaster Component 1", - "description": "High-quality part for toaster functionality" - }, - { - "id": 2122, - "name": "Toaster Component 2", - "description": "High-quality part for toaster functionality" - } - ], - "images": [ - { - "id": 212, - "url": "https://via.placeholder.com/400x300/01b496/ffffff?text=CleanWave+Toaster+324U", - "description": "Toaster product image" - } - ], - "created_at": "2024-12-30T09:16:11.460855Z", - "updated_at": "2025-06-12T09:16:11.460855Z" - }, - { - "id": 213, - "name": "CleanWave Toaster 334M", - "description": "CleanWave Toaster 334M is a high-performance toaster designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 4, - "name": "Smart Home Device" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 1.89, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 32.9, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 17.0, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 929, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 8.5, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 8.4, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 6.5, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 4, - "name": "Mica", - "type": "Mineral" - }, - "percentage": 51.7, - "mass": 1.52, - "unit": "kg" - }, - { - "material": { - "id": 7, - "name": "Silicone", - "type": "Elastomer" - }, - "percentage": 14.7, - "mass": 0.56, - "unit": "kg" - }, - { - "material": { - "id": 3, - "name": "Copper Wire", - "type": "Metal" - }, - "percentage": 33.6, - "mass": 0.78, - "unit": "kg" - } - ], - "components": [ - { - "id": 2131, - "name": "Toaster Component 1", - "description": "High-quality part for toaster functionality" - }, - { - "id": 2132, - "name": "Toaster Component 2", - "description": "High-quality part for toaster functionality" - } - ], - "images": [ - { - "id": 213, - "url": "https://via.placeholder.com/400x300/0e9982/ffffff?text=CleanWave+Toaster+334M", - "description": "Toaster product image" - } - ], - "created_at": "2025-01-21T09:16:11.460888Z", - "updated_at": "2025-06-26T09:16:11.460888Z" - }, - { - "id": 214, - "name": "AquaPro Monitor 790C", - "description": "AquaPro Monitor 790C is a high-performance monitor designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 1, - "name": "Kitchen Appliance" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 2.25, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 27.1, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 29.2, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 818, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 6.6, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 5.6, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 8.9, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 7, - "name": "Silicone", - "type": "Elastomer" - }, - "percentage": 18.6, - "mass": 0.57, - "unit": "kg" - }, - { - "material": { - "id": 4, - "name": "Mica", - "type": "Mineral" - }, - "percentage": 43.4, - "mass": 1.49, - "unit": "kg" - }, - { - "material": { - "id": 1, - "name": "Stainless Steel", - "type": "Metal" - }, - "percentage": 38.1, - "mass": 0.53, - "unit": "kg" - } - ], - "components": [ - { - "id": 2141, - "name": "Monitor Component 1", - "description": "High-quality part for monitor functionality" - }, - { - "id": 2142, - "name": "Monitor Component 2", - "description": "High-quality part for monitor functionality" - }, - { - "id": 2143, - "name": "Monitor Component 3", - "description": "High-quality part for monitor functionality" - }, - { - "id": 2144, - "name": "Monitor Component 4", - "description": "High-quality part for monitor functionality" - }, - { - "id": 2145, - "name": "Monitor Component 5", - "description": "High-quality part for monitor functionality" - } - ], - "images": [ - { - "id": 214, - "url": "https://via.placeholder.com/400x300/0c2322/ffffff?text=AquaPro+Monitor+790C", - "description": "Monitor product image" - } - ], - "created_at": "2024-12-09T09:16:11.460938Z", - "updated_at": "2025-05-03T09:16:11.460938Z" - }, - { - "id": 215, - "name": "ChefMate Monitor 826P", - "description": "ChefMate Monitor 826P is a high-performance monitor designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 2, - "name": "Home Electronics" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 1.93, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 33.1, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 25.9, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 1241, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 8.4, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 7.2, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 7.2, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 7, - "name": "Silicone", - "type": "Elastomer" - }, - "percentage": 17.0, - "mass": 0.34, - "unit": "kg" - }, - { - "material": { - "id": 3, - "name": "Copper Wire", - "type": "Metal" - }, - "percentage": 34.1, - "mass": 0.95, - "unit": "kg" - }, - { - "material": { - "id": 6, - "name": "Polypropylene", - "type": "Plastic" - }, - "percentage": 31.1, - "mass": 0.62, - "unit": "kg" - }, - { - "material": { - "id": 1, - "name": "Stainless Steel", - "type": "Metal" - }, - "percentage": 17.8, - "mass": 0.35, - "unit": "kg" - } - ], - "components": [ - { - "id": 2151, - "name": "Monitor Component 1", - "description": "High-quality part for monitor functionality" - }, - { - "id": 2152, - "name": "Monitor Component 2", - "description": "High-quality part for monitor functionality" - }, - { - "id": 2153, - "name": "Monitor Component 3", - "description": "High-quality part for monitor functionality" - }, - { - "id": 2154, - "name": "Monitor Component 4", - "description": "High-quality part for monitor functionality" - } - ], - "images": [ - { - "id": 215, - "url": "https://via.placeholder.com/400x300/0b2990/ffffff?text=ChefMate+Monitor+826P", - "description": "Monitor product image" - } - ], - "created_at": "2024-04-29T09:16:11.460976Z", - "updated_at": "2025-05-13T09:16:11.460976Z" - }, - { - "id": 216, - "name": "AquaPro Blender 614W", - "description": "AquaPro Blender 614W is a high-performance blender designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 5, - "name": "Office Equipment" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 3.14, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 31.4, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 20.3, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 2046, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 7.8, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 6.9, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 9.2, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 1, - "name": "Stainless Steel", - "type": "Metal" - }, - "percentage": 56.8, - "mass": 1.11, - "unit": "kg" - }, - { - "material": { - "id": 3, - "name": "Copper Wire", - "type": "Metal" - }, - "percentage": 14.8, - "mass": 0.21, - "unit": "kg" - }, - { - "material": { - "id": 2, - "name": "ABS Plastic", - "type": "Plastic" - }, - "percentage": 28.4, - "mass": 0.31, - "unit": "kg" - } - ], - "components": [ - { - "id": 2161, - "name": "Blender Component 1", - "description": "High-quality part for blender functionality" - }, - { - "id": 2162, - "name": "Blender Component 2", - "description": "High-quality part for blender functionality" - }, - { - "id": 2163, - "name": "Blender Component 3", - "description": "High-quality part for blender functionality" - } - ], - "images": [ - { - "id": 216, - "url": "https://via.placeholder.com/400x300/027527/ffffff?text=AquaPro+Blender+614W", - "description": "Blender product image" - } - ], - "created_at": "2024-04-20T09:16:11.461014Z", - "updated_at": "2025-07-22T09:16:11.461014Z" - }, - { - "id": 217, - "name": "AquaPro Blender 132T", - "description": "AquaPro Blender 132T is a high-performance blender designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 3, - "name": "Personal Care Device" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 3.5, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 33.1, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 17.9, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 1108, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 9.5, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 6.5, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 8.0, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 1, - "name": "Stainless Steel", - "type": "Metal" - }, - "percentage": 11.6, - "mass": 0.41, - "unit": "kg" - }, - { - "material": { - "id": 5, - "name": "Borosilicate Glass", - "type": "Glass" - }, - "percentage": 69.8, - "mass": 1.32, - "unit": "kg" - }, - { - "material": { - "id": 7, - "name": "Silicone", - "type": "Elastomer" - }, - "percentage": 18.6, - "mass": 0.35, - "unit": "kg" - } - ], - "components": [ - { - "id": 2171, - "name": "Blender Component 1", - "description": "High-quality part for blender functionality" - }, - { - "id": 2172, - "name": "Blender Component 2", - "description": "High-quality part for blender functionality" - }, - { - "id": 2173, - "name": "Blender Component 3", - "description": "High-quality part for blender functionality" - }, - { - "id": 2174, - "name": "Blender Component 4", - "description": "High-quality part for blender functionality" - } - ], - "images": [ - { - "id": 217, - "url": "https://via.placeholder.com/400x300/078f15/ffffff?text=AquaPro+Blender+132T", - "description": "Blender product image" - } - ], - "created_at": "2024-05-03T09:16:11.461050Z", - "updated_at": "2025-06-26T09:16:11.461050Z" - }, - { - "id": 218, - "name": "CleanWave Humidifier 617O", - "description": "CleanWave Humidifier 617O is a high-performance humidifier designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 5, - "name": "Office Equipment" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 3.71, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 34.8, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 15.0, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 1314, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 6.9, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 8.2, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 6.7, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 4, - "name": "Mica", - "type": "Mineral" - }, - "percentage": 33.3, - "mass": 1.22, - "unit": "kg" - }, - { - "material": { - "id": 3, - "name": "Copper Wire", - "type": "Metal" - }, - "percentage": 66.7, - "mass": 1.88, - "unit": "kg" - } - ], - "components": [ - { - "id": 2181, - "name": "Humidifier Component 1", - "description": "High-quality part for humidifier functionality" - }, - { - "id": 2182, - "name": "Humidifier Component 2", - "description": "High-quality part for humidifier functionality" - } - ], - "images": [ - { - "id": 218, - "url": "https://via.placeholder.com/400x300/09da1c/ffffff?text=CleanWave+Humidifier+617O", - "description": "Humidifier product image" - } - ], - "created_at": "2024-08-26T09:16:11.461081Z", - "updated_at": "2025-07-07T09:16:11.461081Z" - }, - { - "id": 219, - "name": "EcoTech Kettle 628E", - "description": "EcoTech Kettle 628E is a high-performance kettle designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 5, - "name": "Office Equipment" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 1.47, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 27.9, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 27.4, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 2187, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 9.2, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 6.2, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 8.9, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 1, - "name": "Stainless Steel", - "type": "Metal" - }, - "percentage": 47.0, - "mass": 0.58, - "unit": "kg" - }, - { - "material": { - "id": 2, - "name": "ABS Plastic", - "type": "Plastic" - }, - "percentage": 53.0, - "mass": 1.45, - "unit": "kg" - } - ], - "components": [ - { - "id": 2191, - "name": "Kettle Component 1", - "description": "High-quality part for kettle functionality" - }, - { - "id": 2192, - "name": "Kettle Component 2", - "description": "High-quality part for kettle functionality" - } - ], - "images": [ - { - "id": 219, - "url": "https://via.placeholder.com/400x300/0dbff8/ffffff?text=EcoTech+Kettle+628E", - "description": "Kettle product image" - } - ], - "created_at": "2024-04-08T09:16:11.461116Z", - "updated_at": "2025-06-16T09:16:11.461116Z" - }, - { - "id": 220, - "name": "ZenGear Coffee Maker 413T", - "description": "ZenGear Coffee Maker 413T is a high-performance coffee maker designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 3, - "name": "Personal Care Device" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 3.28, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 24.3, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 25.7, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 1659, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 6.1, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 6.3, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 7.1, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 1, - "name": "Stainless Steel", - "type": "Metal" - }, - "percentage": 11.0, - "mass": 0.27, - "unit": "kg" - }, - { - "material": { - "id": 4, - "name": "Mica", - "type": "Mineral" - }, - "percentage": 47.3, - "mass": 0.58, - "unit": "kg" - }, - { - "material": { - "id": 5, - "name": "Borosilicate Glass", - "type": "Glass" - }, - "percentage": 41.8, - "mass": 1.18, - "unit": "kg" - } - ], - "components": [ - { - "id": 2201, - "name": "Coffee Maker Component 1", - "description": "High-quality part for coffee maker functionality" - }, - { - "id": 2202, - "name": "Coffee Maker Component 2", - "description": "High-quality part for coffee maker functionality" - }, - { - "id": 2203, - "name": "Coffee Maker Component 3", - "description": "High-quality part for coffee maker functionality" - }, - { - "id": 2204, - "name": "Coffee Maker Component 4", - "description": "High-quality part for coffee maker functionality" - } - ], - "images": [ - { - "id": 220, - "url": "https://via.placeholder.com/400x300/046a5b/ffffff?text=ZenGear+Coffee+Maker+413T", - "description": "Coffee Maker product image" - } - ], - "created_at": "2025-03-19T09:16:11.461152Z", - "updated_at": "2025-06-04T09:16:11.461152Z" - }, - { - "id": 221, - "name": "PureLife Fan 491R", - "description": "PureLife Fan 491R is a high-performance fan designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 5, - "name": "Office Equipment" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 3.17, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 30.4, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 28.5, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 984, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 7.3, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 7.0, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 7.5, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 5, - "name": "Borosilicate Glass", - "type": "Glass" - }, - "percentage": 41.3, - "mass": 0.72, - "unit": "kg" - }, - { - "material": { - "id": 4, - "name": "Mica", - "type": "Mineral" - }, - "percentage": 58.7, - "mass": 1.07, - "unit": "kg" - } - ], - "components": [ - { - "id": 2211, - "name": "Fan Component 1", - "description": "High-quality part for fan functionality" - }, - { - "id": 2212, - "name": "Fan Component 2", - "description": "High-quality part for fan functionality" - }, - { - "id": 2213, - "name": "Fan Component 3", - "description": "High-quality part for fan functionality" - } - ], - "images": [ - { - "id": 221, - "url": "https://via.placeholder.com/400x300/08557e/ffffff?text=PureLife+Fan+491R", - "description": "Fan product image" - } - ], - "created_at": "2024-05-05T09:16:11.461194Z", - "updated_at": "2025-04-29T09:16:11.461194Z" - }, - { - "id": 222, - "name": "SmartHome Fan 715N", - "description": "SmartHome Fan 715N is a high-performance fan designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 4, - "name": "Smart Home Device" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 3.49, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 26.0, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 17.5, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 2136, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 8.6, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 5.8, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 8.9, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 4, - "name": "Mica", - "type": "Mineral" - }, - "percentage": 25.0, - "mass": 0.48, - "unit": "kg" - }, - { - "material": { - "id": 7, - "name": "Silicone", - "type": "Elastomer" - }, - "percentage": 34.5, - "mass": 0.95, - "unit": "kg" - }, - { - "material": { - "id": 1, - "name": "Stainless Steel", - "type": "Metal" - }, - "percentage": 40.5, - "mass": 1.16, - "unit": "kg" - } - ], - "components": [ - { - "id": 2221, - "name": "Fan Component 1", - "description": "High-quality part for fan functionality" - }, - { - "id": 2222, - "name": "Fan Component 2", - "description": "High-quality part for fan functionality" - }, - { - "id": 2223, - "name": "Fan Component 3", - "description": "High-quality part for fan functionality" - }, - { - "id": 2224, - "name": "Fan Component 4", - "description": "High-quality part for fan functionality" - } - ], - "images": [ - { - "id": 222, - "url": "https://via.placeholder.com/400x300/05e641/ffffff?text=SmartHome+Fan+715N", - "description": "Fan product image" - } - ], - "created_at": "2025-02-19T09:16:11.461261Z", - "updated_at": "2025-07-06T09:16:11.461261Z" - }, - { - "id": 223, - "name": "NeoCook Toaster 809G", - "description": "NeoCook Toaster 809G is a high-performance toaster designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 1, - "name": "Kitchen Appliance" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 1.76, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 30.5, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 18.3, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 1541, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 6.7, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 7.1, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 7.0, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 5, - "name": "Borosilicate Glass", - "type": "Glass" - }, - "percentage": 46.5, - "mass": 1.35, - "unit": "kg" - }, - { - "material": { - "id": 2, - "name": "ABS Plastic", - "type": "Plastic" - }, - "percentage": 29.8, - "mass": 0.51, - "unit": "kg" - }, - { - "material": { - "id": 6, - "name": "Polypropylene", - "type": "Plastic" - }, - "percentage": 23.7, - "mass": 0.5, - "unit": "kg" - } - ], - "components": [ - { - "id": 2231, - "name": "Toaster Component 1", - "description": "High-quality part for toaster functionality" - }, - { - "id": 2232, - "name": "Toaster Component 2", - "description": "High-quality part for toaster functionality" - }, - { - "id": 2233, - "name": "Toaster Component 3", - "description": "High-quality part for toaster functionality" - } - ], - "images": [ - { - "id": 223, - "url": "https://via.placeholder.com/400x300/07ab6a/ffffff?text=NeoCook+Toaster+809G", - "description": "Toaster product image" - } - ], - "created_at": "2025-02-06T09:16:11.461307Z", - "updated_at": "2025-07-19T09:16:11.461307Z" - }, - { - "id": 224, - "name": "ChefMate Iron 970X", - "description": "ChefMate Iron 970X is a high-performance iron designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 1, - "name": "Kitchen Appliance" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 1.46, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 24.2, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 15.1, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 1848, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 7.1, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 8.9, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 6.3, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 1, - "name": "Stainless Steel", - "type": "Metal" - }, - "percentage": 30.8, - "mass": 0.4, - "unit": "kg" - }, - { - "material": { - "id": 6, - "name": "Polypropylene", - "type": "Plastic" - }, - "percentage": 36.4, - "mass": 0.77, - "unit": "kg" - }, - { - "material": { - "id": 2, - "name": "ABS Plastic", - "type": "Plastic" - }, - "percentage": 32.9, - "mass": 0.47, - "unit": "kg" - } - ], - "components": [ - { - "id": 2241, - "name": "Iron Component 1", - "description": "High-quality part for iron functionality" - }, - { - "id": 2242, - "name": "Iron Component 2", - "description": "High-quality part for iron functionality" - }, - { - "id": 2243, - "name": "Iron Component 3", - "description": "High-quality part for iron functionality" - }, - { - "id": 2244, - "name": "Iron Component 4", - "description": "High-quality part for iron functionality" - } - ], - "images": [ - { - "id": 224, - "url": "https://via.placeholder.com/400x300/0763bf/ffffff?text=ChefMate+Iron+970X", - "description": "Iron product image" - } - ], - "created_at": "2024-08-13T09:16:11.461369Z", - "updated_at": "2025-05-22T09:16:11.461369Z" - }, - { - "id": 225, - "name": "AquaPro Humidifier 893T", - "description": "AquaPro Humidifier 893T is a high-performance humidifier designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 2, - "name": "Home Electronics" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 3.48, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 30.7, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 28.5, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 1083, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 6.1, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 8.9, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 9.5, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 2, - "name": "ABS Plastic", - "type": "Plastic" - }, - "percentage": 50.7, - "mass": 1.27, - "unit": "kg" - }, - { - "material": { - "id": 3, - "name": "Copper Wire", - "type": "Metal" - }, - "percentage": 49.3, - "mass": 1.2, - "unit": "kg" - } - ], - "components": [ - { - "id": 2251, - "name": "Humidifier Component 1", - "description": "High-quality part for humidifier functionality" - }, - { - "id": 2252, - "name": "Humidifier Component 2", - "description": "High-quality part for humidifier functionality" - }, - { - "id": 2253, - "name": "Humidifier Component 3", - "description": "High-quality part for humidifier functionality" - }, - { - "id": 2254, - "name": "Humidifier Component 4", - "description": "High-quality part for humidifier functionality" - } - ], - "images": [ - { - "id": 225, - "url": "https://via.placeholder.com/400x300/03c5d6/ffffff?text=AquaPro+Humidifier+893T", - "description": "Humidifier product image" - } - ], - "created_at": "2024-10-24T09:16:11.461433Z", - "updated_at": "2025-05-15T09:16:11.461433Z" - }, - { - "id": 226, - "name": "ZenGear Fan 548F", - "description": "ZenGear Fan 548F is a high-performance fan designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 5, - "name": "Office Equipment" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 2.61, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 23.9, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 16.5, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 1765, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 7.4, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 6.8, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 7.1, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 6, - "name": "Polypropylene", - "type": "Plastic" - }, - "percentage": 63.1, - "mass": 1.46, - "unit": "kg" - }, - { - "material": { - "id": 5, - "name": "Borosilicate Glass", - "type": "Glass" - }, - "percentage": 36.9, - "mass": 0.95, - "unit": "kg" - } - ], - "components": [ - { - "id": 2261, - "name": "Fan Component 1", - "description": "High-quality part for fan functionality" - }, - { - "id": 2262, - "name": "Fan Component 2", - "description": "High-quality part for fan functionality" - } - ], - "images": [ - { - "id": 226, - "url": "https://via.placeholder.com/400x300/0b33a5/ffffff?text=ZenGear+Fan+548F", - "description": "Fan product image" - } - ], - "created_at": "2025-01-14T09:16:11.461481Z", - "updated_at": "2025-07-16T09:16:11.461481Z" - }, - { - "id": 227, - "name": "CleanWave Blender 976X", - "description": "CleanWave Blender 976X is a high-performance blender designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 5, - "name": "Office Equipment" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 2.65, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 32.0, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 24.2, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 1615, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 8.5, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 7.3, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 6.3, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 6, - "name": "Polypropylene", - "type": "Plastic" - }, - "percentage": 25.0, - "mass": 0.56, - "unit": "kg" - }, - { - "material": { - "id": 7, - "name": "Silicone", - "type": "Elastomer" - }, - "percentage": 55.6, - "mass": 1.81, - "unit": "kg" - }, - { - "material": { - "id": 2, - "name": "ABS Plastic", - "type": "Plastic" - }, - "percentage": 19.4, - "mass": 0.28, - "unit": "kg" - } - ], - "components": [ - { - "id": 2271, - "name": "Blender Component 1", - "description": "High-quality part for blender functionality" - }, - { - "id": 2272, - "name": "Blender Component 2", - "description": "High-quality part for blender functionality" - }, - { - "id": 2273, - "name": "Blender Component 3", - "description": "High-quality part for blender functionality" - }, - { - "id": 2274, - "name": "Blender Component 4", - "description": "High-quality part for blender functionality" - } - ], - "images": [ - { - "id": 227, - "url": "https://via.placeholder.com/400x300/038d5b/ffffff?text=CleanWave+Blender+976X", - "description": "Blender product image" - } - ], - "created_at": "2024-08-29T09:16:11.461538Z", - "updated_at": "2025-05-31T09:16:11.461538Z" - }, - { - "id": 228, - "name": "PureLife Toaster 790V", - "description": "PureLife Toaster 790V is a high-performance toaster designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 4, - "name": "Smart Home Device" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 3.87, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 30.6, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 27.2, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 1825, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 8.6, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 8.5, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 9.7, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 1, - "name": "Stainless Steel", - "type": "Metal" - }, - "percentage": 34.7, - "mass": 1.24, - "unit": "kg" - }, - { - "material": { - "id": 4, - "name": "Mica", - "type": "Mineral" - }, - "percentage": 19.4, - "mass": 0.33, - "unit": "kg" - }, - { - "material": { - "id": 3, - "name": "Copper Wire", - "type": "Metal" - }, - "percentage": 20.1, - "mass": 0.34, - "unit": "kg" - }, - { - "material": { - "id": 2, - "name": "ABS Plastic", - "type": "Plastic" - }, - "percentage": 25.7, - "mass": 0.56, - "unit": "kg" - } - ], - "components": [ - { - "id": 2281, - "name": "Toaster Component 1", - "description": "High-quality part for toaster functionality" - }, - { - "id": 2282, - "name": "Toaster Component 2", - "description": "High-quality part for toaster functionality" - }, - { - "id": 2283, - "name": "Toaster Component 3", - "description": "High-quality part for toaster functionality" - }, - { - "id": 2284, - "name": "Toaster Component 4", - "description": "High-quality part for toaster functionality" - } - ], - "images": [ - { - "id": 228, - "url": "https://via.placeholder.com/400x300/0a57db/ffffff?text=PureLife+Toaster+790V", - "description": "Toaster product image" - } - ], - "created_at": "2024-09-21T09:16:11.461585Z", - "updated_at": "2025-05-04T09:16:11.461585Z" - }, - { - "id": 229, - "name": "CleanWave Humidifier 848K", - "description": "CleanWave Humidifier 848K is a high-performance humidifier designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 2, - "name": "Home Electronics" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 3.17, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 34.3, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 20.0, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 1439, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 8.5, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 8.8, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 7.3, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 2, - "name": "ABS Plastic", - "type": "Plastic" - }, - "percentage": 27.4, - "mass": 0.49, - "unit": "kg" - }, - { - "material": { - "id": 3, - "name": "Copper Wire", - "type": "Metal" - }, - "percentage": 28.4, - "mass": 0.79, - "unit": "kg" - }, - { - "material": { - "id": 7, - "name": "Silicone", - "type": "Elastomer" - }, - "percentage": 16.3, - "mass": 0.5, - "unit": "kg" - }, - { - "material": { - "id": 1, - "name": "Stainless Steel", - "type": "Metal" - }, - "percentage": 27.9, - "mass": 0.74, - "unit": "kg" - } - ], - "components": [ - { - "id": 2291, - "name": "Humidifier Component 1", - "description": "High-quality part for humidifier functionality" - }, - { - "id": 2292, - "name": "Humidifier Component 2", - "description": "High-quality part for humidifier functionality" - } - ], - "images": [ - { - "id": 229, - "url": "https://via.placeholder.com/400x300/0cc646/ffffff?text=CleanWave+Humidifier+848K", - "description": "Humidifier product image" - } - ], - "created_at": "2024-09-29T09:16:11.461627Z", - "updated_at": "2025-04-27T09:16:11.461627Z" - }, - { - "id": 230, - "name": "ZenGear Humidifier 675S", - "description": "ZenGear Humidifier 675S is a high-performance humidifier designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 5, - "name": "Office Equipment" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 1.24, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 29.3, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 26.2, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 1324, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 9.1, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 6.2, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 9.7, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 6, - "name": "Polypropylene", - "type": "Plastic" - }, - "percentage": 65.1, - "mass": 2.23, - "unit": "kg" - }, - { - "material": { - "id": 5, - "name": "Borosilicate Glass", - "type": "Glass" - }, - "percentage": 34.9, - "mass": 0.62, - "unit": "kg" - } - ], - "components": [ - { - "id": 2301, - "name": "Humidifier Component 1", - "description": "High-quality part for humidifier functionality" - }, - { - "id": 2302, - "name": "Humidifier Component 2", - "description": "High-quality part for humidifier functionality" - }, - { - "id": 2303, - "name": "Humidifier Component 3", - "description": "High-quality part for humidifier functionality" - } - ], - "images": [ - { - "id": 230, - "url": "https://via.placeholder.com/400x300/03cc91/ffffff?text=ZenGear+Humidifier+675S", - "description": "Humidifier product image" - } - ], - "created_at": "2025-01-10T09:16:11.461666Z", - "updated_at": "2025-07-03T09:16:11.461666Z" - }, - { - "id": 231, - "name": "CleanWave Fan 815Z", - "description": "CleanWave Fan 815Z is a high-performance fan designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 3, - "name": "Personal Care Device" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 3.49, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 24.4, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 19.7, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 994, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 8.4, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 7.0, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 8.6, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 3, - "name": "Copper Wire", - "type": "Metal" - }, - "percentage": 51.2, - "mass": 1.62, - "unit": "kg" - }, - { - "material": { - "id": 2, - "name": "ABS Plastic", - "type": "Plastic" - }, - "percentage": 48.8, - "mass": 0.6, - "unit": "kg" - } - ], - "components": [ - { - "id": 2311, - "name": "Fan Component 1", - "description": "High-quality part for fan functionality" - }, - { - "id": 2312, - "name": "Fan Component 2", - "description": "High-quality part for fan functionality" - }, - { - "id": 2313, - "name": "Fan Component 3", - "description": "High-quality part for fan functionality" - } - ], - "images": [ - { - "id": 231, - "url": "https://via.placeholder.com/400x300/0ab275/ffffff?text=CleanWave+Fan+815Z", - "description": "Fan product image" - } - ], - "created_at": "2024-11-04T09:16:11.462805Z", - "updated_at": "2025-07-16T09:16:11.462805Z" - }, - { - "id": 232, - "name": "ZenGear Humidifier 843P", - "description": "ZenGear Humidifier 843P is a high-performance humidifier designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 5, - "name": "Office Equipment" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 2.24, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 23.8, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 25.0, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 1959, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 6.1, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 5.3, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 6.8, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 2, - "name": "ABS Plastic", - "type": "Plastic" - }, - "percentage": 45.5, - "mass": 1.45, - "unit": "kg" - }, - { - "material": { - "id": 4, - "name": "Mica", - "type": "Mineral" - }, - "percentage": 28.8, - "mass": 0.65, - "unit": "kg" - }, - { - "material": { - "id": 1, - "name": "Stainless Steel", - "type": "Metal" - }, - "percentage": 25.8, - "mass": 0.51, - "unit": "kg" - } - ], - "components": [ - { - "id": 2321, - "name": "Humidifier Component 1", - "description": "High-quality part for humidifier functionality" - }, - { - "id": 2322, - "name": "Humidifier Component 2", - "description": "High-quality part for humidifier functionality" - } - ], - "images": [ - { - "id": 232, - "url": "https://via.placeholder.com/400x300/01ccb7/ffffff?text=ZenGear+Humidifier+843P", - "description": "Humidifier product image" - } - ], - "created_at": "2024-08-26T09:16:11.462873Z", - "updated_at": "2025-07-07T09:16:11.462873Z" - }, - { - "id": 233, - "name": "PureLife Coffee Maker 108Z", - "description": "PureLife Coffee Maker 108Z is a high-performance coffee maker designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 3, - "name": "Personal Care Device" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 1.6, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 31.6, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 29.4, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 2114, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 6.0, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 7.7, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 7.4, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 4, - "name": "Mica", - "type": "Mineral" - }, - "percentage": 21.3, - "mass": 0.31, - "unit": "kg" - }, - { - "material": { - "id": 3, - "name": "Copper Wire", - "type": "Metal" - }, - "percentage": 34.9, - "mass": 0.45, - "unit": "kg" - }, - { - "material": { - "id": 6, - "name": "Polypropylene", - "type": "Plastic" - }, - "percentage": 33.1, - "mass": 0.67, - "unit": "kg" - }, - { - "material": { - "id": 2, - "name": "ABS Plastic", - "type": "Plastic" - }, - "percentage": 10.7, - "mass": 0.19, - "unit": "kg" - } - ], - "components": [ - { - "id": 2331, - "name": "Coffee Maker Component 1", - "description": "High-quality part for coffee maker functionality" - }, - { - "id": 2332, - "name": "Coffee Maker Component 2", - "description": "High-quality part for coffee maker functionality" - }, - { - "id": 2333, - "name": "Coffee Maker Component 3", - "description": "High-quality part for coffee maker functionality" - } - ], - "images": [ - { - "id": 233, - "url": "https://via.placeholder.com/400x300/09cc27/ffffff?text=PureLife+Coffee+Maker+108Z", - "description": "Coffee Maker product image" - } - ], - "created_at": "2024-08-10T09:16:11.462925Z", - "updated_at": "2025-06-01T09:16:11.462925Z" - }, - { - "id": 234, - "name": "CleanWave Toaster 110Y", - "description": "CleanWave Toaster 110Y is a high-performance toaster designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 1, - "name": "Kitchen Appliance" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 2.43, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 26.2, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 17.4, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 1805, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 7.6, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 7.5, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 7.6, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 4, - "name": "Mica", - "type": "Mineral" - }, - "percentage": 41.7, - "mass": 0.45, - "unit": "kg" - }, - { - "material": { - "id": 7, - "name": "Silicone", - "type": "Elastomer" - }, - "percentage": 58.3, - "mass": 1.83, - "unit": "kg" - } - ], - "components": [ - { - "id": 2341, - "name": "Toaster Component 1", - "description": "High-quality part for toaster functionality" - }, - { - "id": 2342, - "name": "Toaster Component 2", - "description": "High-quality part for toaster functionality" - }, - { - "id": 2343, - "name": "Toaster Component 3", - "description": "High-quality part for toaster functionality" - } - ], - "images": [ - { - "id": 234, - "url": "https://via.placeholder.com/400x300/0d484f/ffffff?text=CleanWave+Toaster+110Y", - "description": "Toaster product image" - } - ], - "created_at": "2025-03-05T09:16:11.462964Z", - "updated_at": "2025-06-17T09:16:11.462964Z" - }, - { - "id": 235, - "name": "ZenGear Coffee Maker 902S", - "description": "ZenGear Coffee Maker 902S is a high-performance coffee maker designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 3, - "name": "Personal Care Device" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 3.44, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 26.9, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 18.2, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 849, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 8.8, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 6.6, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 8.5, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 7, - "name": "Silicone", - "type": "Elastomer" - }, - "percentage": 45.2, - "mass": 1.62, - "unit": "kg" - }, - { - "material": { - "id": 5, - "name": "Borosilicate Glass", - "type": "Glass" - }, - "percentage": 54.8, - "mass": 0.8, - "unit": "kg" - } - ], - "components": [ - { - "id": 2351, - "name": "Coffee Maker Component 1", - "description": "High-quality part for coffee maker functionality" - }, - { - "id": 2352, - "name": "Coffee Maker Component 2", - "description": "High-quality part for coffee maker functionality" - } - ], - "images": [ - { - "id": 235, - "url": "https://via.placeholder.com/400x300/0a5032/ffffff?text=ZenGear+Coffee+Maker+902S", - "description": "Coffee Maker product image" - } - ], - "created_at": "2024-06-30T09:16:11.462994Z", - "updated_at": "2025-06-09T09:16:11.462994Z" - }, - { - "id": 236, - "name": "CleanWave Coffee Maker 399S", - "description": "CleanWave Coffee Maker 399S is a high-performance coffee maker designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 5, - "name": "Office Equipment" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 3.28, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 34.0, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 22.6, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 1225, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 8.3, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 5.6, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 9.4, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 7, - "name": "Silicone", - "type": "Elastomer" - }, - "percentage": 32.3, - "mass": 0.86, - "unit": "kg" - }, - { - "material": { - "id": 2, - "name": "ABS Plastic", - "type": "Plastic" - }, - "percentage": 25.9, - "mass": 0.36, - "unit": "kg" - }, - { - "material": { - "id": 1, - "name": "Stainless Steel", - "type": "Metal" - }, - "percentage": 10.1, - "mass": 0.29, - "unit": "kg" - }, - { - "material": { - "id": 4, - "name": "Mica", - "type": "Mineral" - }, - "percentage": 31.6, - "mass": 0.92, - "unit": "kg" - } - ], - "components": [ - { - "id": 2361, - "name": "Coffee Maker Component 1", - "description": "High-quality part for coffee maker functionality" - }, - { - "id": 2362, - "name": "Coffee Maker Component 2", - "description": "High-quality part for coffee maker functionality" - }, - { - "id": 2363, - "name": "Coffee Maker Component 3", - "description": "High-quality part for coffee maker functionality" - }, - { - "id": 2364, - "name": "Coffee Maker Component 4", - "description": "High-quality part for coffee maker functionality" - }, - { - "id": 2365, - "name": "Coffee Maker Component 5", - "description": "High-quality part for coffee maker functionality" - } - ], - "images": [ - { - "id": 236, - "url": "https://via.placeholder.com/400x300/07e9a0/ffffff?text=CleanWave+Coffee+Maker+399S", - "description": "Coffee Maker product image" - } - ], - "created_at": "2024-05-17T09:16:11.463033Z", - "updated_at": "2025-07-16T09:16:11.463033Z" - }, - { - "id": 237, - "name": "AquaPro Fan 303A", - "description": "AquaPro Fan 303A is a high-performance fan designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 2, - "name": "Home Electronics" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 2.93, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 35.0, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 28.5, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 1400, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 7.8, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 8.4, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 7.4, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 3, - "name": "Copper Wire", - "type": "Metal" - }, - "percentage": 31.8, - "mass": 0.51, - "unit": "kg" - }, - { - "material": { - "id": 2, - "name": "ABS Plastic", - "type": "Plastic" - }, - "percentage": 37.1, - "mass": 0.62, - "unit": "kg" - }, - { - "material": { - "id": 5, - "name": "Borosilicate Glass", - "type": "Glass" - }, - "percentage": 31.1, - "mass": 1.15, - "unit": "kg" - } - ], - "components": [ - { - "id": 2371, - "name": "Fan Component 1", - "description": "High-quality part for fan functionality" - }, - { - "id": 2372, - "name": "Fan Component 2", - "description": "High-quality part for fan functionality" - } - ], - "images": [ - { - "id": 237, - "url": "https://via.placeholder.com/400x300/0758b4/ffffff?text=AquaPro+Fan+303A", - "description": "Fan product image" - } - ], - "created_at": "2024-12-07T09:16:11.463081Z", - "updated_at": "2025-05-16T09:16:11.463081Z" - }, - { - "id": 238, - "name": "CleanWave Monitor 457V", - "description": "CleanWave Monitor 457V is a high-performance monitor designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 5, - "name": "Office Equipment" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 2.99, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 29.1, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 23.6, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 908, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 8.6, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 5.9, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 7.2, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 5, - "name": "Borosilicate Glass", - "type": "Glass" - }, - "percentage": 28.5, - "mass": 0.76, - "unit": "kg" - }, - { - "material": { - "id": 7, - "name": "Silicone", - "type": "Elastomer" - }, - "percentage": 15.2, - "mass": 0.42, - "unit": "kg" - }, - { - "material": { - "id": 1, - "name": "Stainless Steel", - "type": "Metal" - }, - "percentage": 24.1, - "mass": 0.96, - "unit": "kg" - }, - { - "material": { - "id": 4, - "name": "Mica", - "type": "Mineral" - }, - "percentage": 32.3, - "mass": 1.09, - "unit": "kg" - } - ], - "components": [ - { - "id": 2381, - "name": "Monitor Component 1", - "description": "High-quality part for monitor functionality" - }, - { - "id": 2382, - "name": "Monitor Component 2", - "description": "High-quality part for monitor functionality" - }, - { - "id": 2383, - "name": "Monitor Component 3", - "description": "High-quality part for monitor functionality" - }, - { - "id": 2384, - "name": "Monitor Component 4", - "description": "High-quality part for monitor functionality" - } - ], - "images": [ - { - "id": 238, - "url": "https://via.placeholder.com/400x300/0cf971/ffffff?text=CleanWave+Monitor+457V", - "description": "Monitor product image" - } - ], - "created_at": "2024-04-08T09:16:11.463125Z", - "updated_at": "2025-06-29T09:16:11.463125Z" - }, - { - "id": 239, - "name": "NeoCook Fan 246N", - "description": "NeoCook Fan 246N is a high-performance fan designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 2, - "name": "Home Electronics" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 3.05, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 24.2, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 27.1, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 1852, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 6.1, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 6.8, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 9.8, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 1, - "name": "Stainless Steel", - "type": "Metal" - }, - "percentage": 56.9, - "mass": 0.59, - "unit": "kg" - }, - { - "material": { - "id": 2, - "name": "ABS Plastic", - "type": "Plastic" - }, - "percentage": 43.1, - "mass": 0.76, - "unit": "kg" - } - ], - "components": [ - { - "id": 2391, - "name": "Fan Component 1", - "description": "High-quality part for fan functionality" - }, - { - "id": 2392, - "name": "Fan Component 2", - "description": "High-quality part for fan functionality" - }, - { - "id": 2393, - "name": "Fan Component 3", - "description": "High-quality part for fan functionality" - }, - { - "id": 2394, - "name": "Fan Component 4", - "description": "High-quality part for fan functionality" - } - ], - "images": [ - { - "id": 239, - "url": "https://via.placeholder.com/400x300/08ebf2/ffffff?text=NeoCook+Fan+246N", - "description": "Fan product image" - } - ], - "created_at": "2024-07-13T09:16:11.463381Z", - "updated_at": "2025-06-16T09:16:11.463381Z" - }, - { - "id": 240, - "name": "CleanWave Monitor 716X", - "description": "CleanWave Monitor 716X is a high-performance monitor designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 5, - "name": "Office Equipment" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 3.51, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 31.7, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 16.4, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 897, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 8.5, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 8.5, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 8.3, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 5, - "name": "Borosilicate Glass", - "type": "Glass" - }, - "percentage": 29.0, - "mass": 0.79, - "unit": "kg" - }, - { - "material": { - "id": 6, - "name": "Polypropylene", - "type": "Plastic" - }, - "percentage": 33.9, - "mass": 1.25, - "unit": "kg" - }, - { - "material": { - "id": 3, - "name": "Copper Wire", - "type": "Metal" - }, - "percentage": 37.1, - "mass": 0.95, - "unit": "kg" - } - ], - "components": [ - { - "id": 2401, - "name": "Monitor Component 1", - "description": "High-quality part for monitor functionality" - }, - { - "id": 2402, - "name": "Monitor Component 2", - "description": "High-quality part for monitor functionality" - }, - { - "id": 2403, - "name": "Monitor Component 3", - "description": "High-quality part for monitor functionality" - }, - { - "id": 2404, - "name": "Monitor Component 4", - "description": "High-quality part for monitor functionality" - }, - { - "id": 2405, - "name": "Monitor Component 5", - "description": "High-quality part for monitor functionality" - } - ], - "images": [ - { - "id": 240, - "url": "https://via.placeholder.com/400x300/0ba5c3/ffffff?text=CleanWave+Monitor+716X", - "description": "Monitor product image" - } - ], - "created_at": "2024-05-21T09:16:11.463459Z", - "updated_at": "2025-04-25T09:16:11.463459Z" - }, - { - "id": 241, - "name": "ZenGear Coffee Maker 829T", - "description": "ZenGear Coffee Maker 829T is a high-performance coffee maker designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 3, - "name": "Personal Care Device" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 1.9, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 23.1, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 23.6, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 1990, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 8.3, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 5.5, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 8.4, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 4, - "name": "Mica", - "type": "Mineral" - }, - "percentage": 27.0, - "mass": 0.73, - "unit": "kg" - }, - { - "material": { - "id": 3, - "name": "Copper Wire", - "type": "Metal" - }, - "percentage": 11.3, - "mass": 0.17, - "unit": "kg" - }, - { - "material": { - "id": 6, - "name": "Polypropylene", - "type": "Plastic" - }, - "percentage": 30.5, - "mass": 0.32, - "unit": "kg" - }, - { - "material": { - "id": 1, - "name": "Stainless Steel", - "type": "Metal" - }, - "percentage": 31.2, - "mass": 1.08, - "unit": "kg" - } - ], - "components": [ - { - "id": 2411, - "name": "Coffee Maker Component 1", - "description": "High-quality part for coffee maker functionality" - }, - { - "id": 2412, - "name": "Coffee Maker Component 2", - "description": "High-quality part for coffee maker functionality" - }, - { - "id": 2413, - "name": "Coffee Maker Component 3", - "description": "High-quality part for coffee maker functionality" - }, - { - "id": 2414, - "name": "Coffee Maker Component 4", - "description": "High-quality part for coffee maker functionality" - }, - { - "id": 2415, - "name": "Coffee Maker Component 5", - "description": "High-quality part for coffee maker functionality" - } - ], - "images": [ - { - "id": 241, - "url": "https://via.placeholder.com/400x300/02931e/ffffff?text=ZenGear+Coffee+Maker+829T", - "description": "Coffee Maker product image" - } - ], - "created_at": "2024-09-17T09:16:11.463501Z", - "updated_at": "2025-04-29T09:16:11.463501Z" - }, - { - "id": 242, - "name": "SmartHome Coffee Maker 492Z", - "description": "SmartHome Coffee Maker 492Z is a high-performance coffee maker designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 5, - "name": "Office Equipment" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 1.89, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 29.1, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 25.4, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 2025, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 6.3, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 5.8, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 8.3, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 4, - "name": "Mica", - "type": "Mineral" - }, - "percentage": 36.4, - "mass": 1.37, - "unit": "kg" - }, - { - "material": { - "id": 7, - "name": "Silicone", - "type": "Elastomer" - }, - "percentage": 10.9, - "mass": 0.35, - "unit": "kg" - }, - { - "material": { - "id": 2, - "name": "ABS Plastic", - "type": "Plastic" - }, - "percentage": 13.2, - "mass": 0.21, - "unit": "kg" - }, - { - "material": { - "id": 1, - "name": "Stainless Steel", - "type": "Metal" - }, - "percentage": 39.5, - "mass": 1.56, - "unit": "kg" - } - ], - "components": [ - { - "id": 2421, - "name": "Coffee Maker Component 1", - "description": "High-quality part for coffee maker functionality" - }, - { - "id": 2422, - "name": "Coffee Maker Component 2", - "description": "High-quality part for coffee maker functionality" - }, - { - "id": 2423, - "name": "Coffee Maker Component 3", - "description": "High-quality part for coffee maker functionality" - }, - { - "id": 2424, - "name": "Coffee Maker Component 4", - "description": "High-quality part for coffee maker functionality" - }, - { - "id": 2425, - "name": "Coffee Maker Component 5", - "description": "High-quality part for coffee maker functionality" - } - ], - "images": [ - { - "id": 242, - "url": "https://via.placeholder.com/400x300/0db02f/ffffff?text=SmartHome+Coffee+Maker+492Z", - "description": "Coffee Maker product image" - } - ], - "created_at": "2024-10-18T09:16:11.463557Z", - "updated_at": "2025-06-13T09:16:11.463557Z" - }, - { - "id": 243, - "name": "CleanWave Iron 762S", - "description": "CleanWave Iron 762S is a high-performance iron designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 5, - "name": "Office Equipment" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 3.72, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 21.4, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 22.0, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 912, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 9.2, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 8.3, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 7.5, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 5, - "name": "Borosilicate Glass", - "type": "Glass" - }, - "percentage": 60.0, - "mass": 1.3, - "unit": "kg" - }, - { - "material": { - "id": 7, - "name": "Silicone", - "type": "Elastomer" - }, - "percentage": 40.0, - "mass": 0.87, - "unit": "kg" - } - ], - "components": [ - { - "id": 2431, - "name": "Iron Component 1", - "description": "High-quality part for iron functionality" - }, - { - "id": 2432, - "name": "Iron Component 2", - "description": "High-quality part for iron functionality" - }, - { - "id": 2433, - "name": "Iron Component 3", - "description": "High-quality part for iron functionality" - }, - { - "id": 2434, - "name": "Iron Component 4", - "description": "High-quality part for iron functionality" - }, - { - "id": 2435, - "name": "Iron Component 5", - "description": "High-quality part for iron functionality" - } - ], - "images": [ - { - "id": 243, - "url": "https://via.placeholder.com/400x300/0c3636/ffffff?text=CleanWave+Iron+762S", - "description": "Iron product image" - } - ], - "created_at": "2025-04-09T09:16:11.463601Z", - "updated_at": "2025-06-21T09:16:11.463601Z" - }, - { - "id": 244, - "name": "ZenGear Blender 900X", - "description": "ZenGear Blender 900X is a high-performance blender designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 5, - "name": "Office Equipment" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 3.21, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 22.6, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 29.3, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 2149, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 9.3, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 7.5, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 7.7, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 7, - "name": "Silicone", - "type": "Elastomer" - }, - "percentage": 32.6, - "mass": 0.4, - "unit": "kg" - }, - { - "material": { - "id": 1, - "name": "Stainless Steel", - "type": "Metal" - }, - "percentage": 40.7, - "mass": 1.28, - "unit": "kg" - }, - { - "material": { - "id": 5, - "name": "Borosilicate Glass", - "type": "Glass" - }, - "percentage": 26.7, - "mass": 0.74, - "unit": "kg" - } - ], - "components": [ - { - "id": 2441, - "name": "Blender Component 1", - "description": "High-quality part for blender functionality" - }, - { - "id": 2442, - "name": "Blender Component 2", - "description": "High-quality part for blender functionality" - }, - { - "id": 2443, - "name": "Blender Component 3", - "description": "High-quality part for blender functionality" - }, - { - "id": 2444, - "name": "Blender Component 4", - "description": "High-quality part for blender functionality" - } - ], - "images": [ - { - "id": 244, - "url": "https://via.placeholder.com/400x300/0ac2f2/ffffff?text=ZenGear+Blender+900X", - "description": "Blender product image" - } - ], - "created_at": "2024-11-23T09:16:11.463632Z", - "updated_at": "2025-07-25T09:16:11.463632Z" - }, - { - "id": 245, - "name": "CleanWave Rice Cooker 166O", - "description": "CleanWave Rice Cooker 166O is a high-performance rice cooker designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 5, - "name": "Office Equipment" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 2.85, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 31.9, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 18.6, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 1670, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 6.4, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 7.3, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 6.8, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 4, - "name": "Mica", - "type": "Mineral" - }, - "percentage": 32.8, - "mass": 0.79, - "unit": "kg" - }, - { - "material": { - "id": 3, - "name": "Copper Wire", - "type": "Metal" - }, - "percentage": 67.2, - "mass": 0.8, - "unit": "kg" - } - ], - "components": [ - { - "id": 2451, - "name": "Rice Cooker Component 1", - "description": "High-quality part for rice cooker functionality" - }, - { - "id": 2452, - "name": "Rice Cooker Component 2", - "description": "High-quality part for rice cooker functionality" - }, - { - "id": 2453, - "name": "Rice Cooker Component 3", - "description": "High-quality part for rice cooker functionality" - }, - { - "id": 2454, - "name": "Rice Cooker Component 4", - "description": "High-quality part for rice cooker functionality" - }, - { - "id": 2455, - "name": "Rice Cooker Component 5", - "description": "High-quality part for rice cooker functionality" - } - ], - "images": [ - { - "id": 245, - "url": "https://via.placeholder.com/400x300/097866/ffffff?text=CleanWave+Rice+Cooker+166O", - "description": "Rice Cooker product image" - } - ], - "created_at": "2024-04-17T09:16:11.463662Z", - "updated_at": "2025-07-13T09:16:11.463662Z" - }, - { - "id": 246, - "name": "AquaPro Air Purifier 638V", - "description": "AquaPro Air Purifier 638V is a high-performance air purifier designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 1, - "name": "Kitchen Appliance" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 3.07, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 22.9, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 26.7, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 1080, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 8.0, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 6.5, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 8.1, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 6, - "name": "Polypropylene", - "type": "Plastic" - }, - "percentage": 14.3, - "mass": 0.24, - "unit": "kg" - }, - { - "material": { - "id": 7, - "name": "Silicone", - "type": "Elastomer" - }, - "percentage": 19.0, - "mass": 0.54, - "unit": "kg" - }, - { - "material": { - "id": 5, - "name": "Borosilicate Glass", - "type": "Glass" - }, - "percentage": 26.5, - "mass": 0.42, - "unit": "kg" - }, - { - "material": { - "id": 2, - "name": "ABS Plastic", - "type": "Plastic" - }, - "percentage": 40.1, - "mass": 0.63, - "unit": "kg" - } - ], - "components": [ - { - "id": 2461, - "name": "Air Purifier Component 1", - "description": "High-quality part for air purifier functionality" - }, - { - "id": 2462, - "name": "Air Purifier Component 2", - "description": "High-quality part for air purifier functionality" - }, - { - "id": 2463, - "name": "Air Purifier Component 3", - "description": "High-quality part for air purifier functionality" - }, - { - "id": 2464, - "name": "Air Purifier Component 4", - "description": "High-quality part for air purifier functionality" - }, - { - "id": 2465, - "name": "Air Purifier Component 5", - "description": "High-quality part for air purifier functionality" - } - ], - "images": [ - { - "id": 246, - "url": "https://via.placeholder.com/400x300/0a3080/ffffff?text=AquaPro+Air+Purifier+638V", - "description": "Air Purifier product image" - } - ], - "created_at": "2024-08-03T09:16:11.463706Z", - "updated_at": "2025-06-08T09:16:11.463706Z" - }, - { - "id": 247, - "name": "CleanWave Kettle 403Y", - "description": "CleanWave Kettle 403Y is a high-performance kettle designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 1, - "name": "Kitchen Appliance" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 2.67, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 25.0, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 18.7, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 1151, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 6.6, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 5.6, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 7.8, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 4, - "name": "Mica", - "type": "Mineral" - }, - "percentage": 23.3, - "mass": 0.68, - "unit": "kg" - }, - { - "material": { - "id": 1, - "name": "Stainless Steel", - "type": "Metal" - }, - "percentage": 17.4, - "mass": 0.52, - "unit": "kg" - }, - { - "material": { - "id": 2, - "name": "ABS Plastic", - "type": "Plastic" - }, - "percentage": 59.3, - "mass": 1.72, - "unit": "kg" - } - ], - "components": [ - { - "id": 2471, - "name": "Kettle Component 1", - "description": "High-quality part for kettle functionality" - }, - { - "id": 2472, - "name": "Kettle Component 2", - "description": "High-quality part for kettle functionality" - } - ], - "images": [ - { - "id": 247, - "url": "https://via.placeholder.com/400x300/0dbac5/ffffff?text=CleanWave+Kettle+403Y", - "description": "Kettle product image" - } - ], - "created_at": "2024-05-19T09:16:11.463762Z", - "updated_at": "2025-06-30T09:16:11.463762Z" - }, - { - "id": 248, - "name": "CleanWave Coffee Maker 397Y", - "description": "CleanWave Coffee Maker 397Y is a high-performance coffee maker designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 4, - "name": "Smart Home Device" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 1.16, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 24.3, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 18.8, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 1273, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 8.6, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 7.5, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 8.2, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 6, - "name": "Polypropylene", - "type": "Plastic" - }, - "percentage": 41.0, - "mass": 1.04, - "unit": "kg" - }, - { - "material": { - "id": 1, - "name": "Stainless Steel", - "type": "Metal" - }, - "percentage": 12.2, - "mass": 0.35, - "unit": "kg" - }, - { - "material": { - "id": 7, - "name": "Silicone", - "type": "Elastomer" - }, - "percentage": 39.6, - "mass": 1.18, - "unit": "kg" - }, - { - "material": { - "id": 3, - "name": "Copper Wire", - "type": "Metal" - }, - "percentage": 7.2, - "mass": 0.2, - "unit": "kg" - } - ], - "components": [ - { - "id": 2481, - "name": "Coffee Maker Component 1", - "description": "High-quality part for coffee maker functionality" - }, - { - "id": 2482, - "name": "Coffee Maker Component 2", - "description": "High-quality part for coffee maker functionality" - }, - { - "id": 2483, - "name": "Coffee Maker Component 3", - "description": "High-quality part for coffee maker functionality" - }, - { - "id": 2484, - "name": "Coffee Maker Component 4", - "description": "High-quality part for coffee maker functionality" - } - ], - "images": [ - { - "id": 248, - "url": "https://via.placeholder.com/400x300/0c9a01/ffffff?text=CleanWave+Coffee+Maker+397Y", - "description": "Coffee Maker product image" - } - ], - "created_at": "2024-06-20T09:16:11.463809Z", - "updated_at": "2025-05-25T09:16:11.463809Z" - }, - { - "id": 249, - "name": "CleanWave Monitor 619K", - "description": "CleanWave Monitor 619K is a high-performance monitor designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 5, - "name": "Office Equipment" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 2.55, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 26.0, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 21.5, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 1101, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 7.5, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 8.1, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 7.4, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 1, - "name": "Stainless Steel", - "type": "Metal" - }, - "percentage": 34.8, - "mass": 1.17, - "unit": "kg" - }, - { - "material": { - "id": 5, - "name": "Borosilicate Glass", - "type": "Glass" - }, - "percentage": 65.2, - "mass": 1.74, - "unit": "kg" - } - ], - "components": [ - { - "id": 2491, - "name": "Monitor Component 1", - "description": "High-quality part for monitor functionality" - }, - { - "id": 2492, - "name": "Monitor Component 2", - "description": "High-quality part for monitor functionality" - }, - { - "id": 2493, - "name": "Monitor Component 3", - "description": "High-quality part for monitor functionality" - }, - { - "id": 2494, - "name": "Monitor Component 4", - "description": "High-quality part for monitor functionality" - }, - { - "id": 2495, - "name": "Monitor Component 5", - "description": "High-quality part for monitor functionality" - } - ], - "images": [ - { - "id": 249, - "url": "https://via.placeholder.com/400x300/0a3344/ffffff?text=CleanWave+Monitor+619K", - "description": "Monitor product image" - } - ], - "created_at": "2025-01-28T09:16:11.463855Z", - "updated_at": "2025-07-14T09:16:11.463855Z" - }, - { - "id": 250, - "name": "AquaPro Air Purifier 504C", - "description": "AquaPro Air Purifier 504C is a high-performance air purifier designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 2, - "name": "Home Electronics" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 1.94, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 34.0, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 18.9, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 1246, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 8.2, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 5.5, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 7.4, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 2, - "name": "ABS Plastic", - "type": "Plastic" - }, - "percentage": 29.0, - "mass": 0.35, - "unit": "kg" - }, - { - "material": { - "id": 1, - "name": "Stainless Steel", - "type": "Metal" - }, - "percentage": 28.0, - "mass": 0.63, - "unit": "kg" - }, - { - "material": { - "id": 4, - "name": "Mica", - "type": "Mineral" - }, - "percentage": 43.0, - "mass": 1.0, - "unit": "kg" - } - ], - "components": [ - { - "id": 2501, - "name": "Air Purifier Component 1", - "description": "High-quality part for air purifier functionality" - }, - { - "id": 2502, - "name": "Air Purifier Component 2", - "description": "High-quality part for air purifier functionality" - }, - { - "id": 2503, - "name": "Air Purifier Component 3", - "description": "High-quality part for air purifier functionality" - } - ], - "images": [ - { - "id": 250, - "url": "https://via.placeholder.com/400x300/052d6b/ffffff?text=AquaPro+Air+Purifier+504C", - "description": "Air Purifier product image" - } - ], - "created_at": "2024-12-19T09:16:11.463920Z", - "updated_at": "2025-05-24T09:16:11.463920Z" - }, - { - "id": 251, - "name": "SmartHome Monitor 713U", - "description": "SmartHome Monitor 713U is a high-performance monitor designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 2, - "name": "Home Electronics" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 1.9, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 20.3, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 29.7, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 1438, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 7.9, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 7.4, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 6.1, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 7, - "name": "Silicone", - "type": "Elastomer" - }, - "percentage": 28.6, - "mass": 0.68, - "unit": "kg" - }, - { - "material": { - "id": 4, - "name": "Mica", - "type": "Mineral" - }, - "percentage": 27.1, - "mass": 0.67, - "unit": "kg" - }, - { - "material": { - "id": 6, - "name": "Polypropylene", - "type": "Plastic" - }, - "percentage": 44.4, - "mass": 1.5, - "unit": "kg" - } - ], - "components": [ - { - "id": 2511, - "name": "Monitor Component 1", - "description": "High-quality part for monitor functionality" - }, - { - "id": 2512, - "name": "Monitor Component 2", - "description": "High-quality part for monitor functionality" - } - ], - "images": [ - { - "id": 251, - "url": "https://via.placeholder.com/400x300/068125/ffffff?text=SmartHome+Monitor+713U", - "description": "Monitor product image" - } - ], - "created_at": "2025-02-22T09:16:11.463968Z", - "updated_at": "2025-07-11T09:16:11.463968Z" - }, - { - "id": 252, - "name": "SmartHome Humidifier 873Q", - "description": "SmartHome Humidifier 873Q is a high-performance humidifier designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 2, - "name": "Home Electronics" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 2.41, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 24.9, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 29.2, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 1562, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 7.1, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 5.9, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 6.1, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 2, - "name": "ABS Plastic", - "type": "Plastic" - }, - "percentage": 27.5, - "mass": 0.39, - "unit": "kg" - }, - { - "material": { - "id": 7, - "name": "Silicone", - "type": "Elastomer" - }, - "percentage": 19.8, - "mass": 0.72, - "unit": "kg" - }, - { - "material": { - "id": 6, - "name": "Polypropylene", - "type": "Plastic" - }, - "percentage": 52.7, - "mass": 1.26, - "unit": "kg" - } - ], - "components": [ - { - "id": 2521, - "name": "Humidifier Component 1", - "description": "High-quality part for humidifier functionality" - }, - { - "id": 2522, - "name": "Humidifier Component 2", - "description": "High-quality part for humidifier functionality" - } - ], - "images": [ - { - "id": 252, - "url": "https://via.placeholder.com/400x300/0a4e8a/ffffff?text=SmartHome+Humidifier+873Q", - "description": "Humidifier product image" - } - ], - "created_at": "2024-10-31T09:16:11.464031Z", - "updated_at": "2025-07-03T09:16:11.464031Z" - }, - { - "id": 253, - "name": "EcoTech Fan 327S", - "description": "EcoTech Fan 327S is a high-performance fan designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 2, - "name": "Home Electronics" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 1.66, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 31.6, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 15.2, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 1386, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 7.9, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 8.2, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 7.9, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 3, - "name": "Copper Wire", - "type": "Metal" - }, - "percentage": 15.0, - "mass": 0.4, - "unit": "kg" - }, - { - "material": { - "id": 7, - "name": "Silicone", - "type": "Elastomer" - }, - "percentage": 39.8, - "mass": 1.46, - "unit": "kg" - }, - { - "material": { - "id": 6, - "name": "Polypropylene", - "type": "Plastic" - }, - "percentage": 45.1, - "mass": 1.22, - "unit": "kg" - } - ], - "components": [ - { - "id": 2531, - "name": "Fan Component 1", - "description": "High-quality part for fan functionality" - }, - { - "id": 2532, - "name": "Fan Component 2", - "description": "High-quality part for fan functionality" - }, - { - "id": 2533, - "name": "Fan Component 3", - "description": "High-quality part for fan functionality" - }, - { - "id": 2534, - "name": "Fan Component 4", - "description": "High-quality part for fan functionality" - } - ], - "images": [ - { - "id": 253, - "url": "https://via.placeholder.com/400x300/0625c2/ffffff?text=EcoTech+Fan+327S", - "description": "Fan product image" - } - ], - "created_at": "2024-03-30T09:16:11.464084Z", - "updated_at": "2025-07-26T09:16:11.464084Z" - }, - { - "id": 254, - "name": "SmartHome Iron 836G", - "description": "SmartHome Iron 836G is a high-performance iron designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 2, - "name": "Home Electronics" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 1.72, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 26.1, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 23.1, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 1489, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 7.3, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 7.7, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 8.7, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 2, - "name": "ABS Plastic", - "type": "Plastic" - }, - "percentage": 23.3, - "mass": 0.7, - "unit": "kg" - }, - { - "material": { - "id": 1, - "name": "Stainless Steel", - "type": "Metal" - }, - "percentage": 76.7, - "mass": 1.06, - "unit": "kg" - } - ], - "components": [ - { - "id": 2541, - "name": "Iron Component 1", - "description": "High-quality part for iron functionality" - }, - { - "id": 2542, - "name": "Iron Component 2", - "description": "High-quality part for iron functionality" - }, - { - "id": 2543, - "name": "Iron Component 3", - "description": "High-quality part for iron functionality" - }, - { - "id": 2544, - "name": "Iron Component 4", - "description": "High-quality part for iron functionality" - } - ], - "images": [ - { - "id": 254, - "url": "https://via.placeholder.com/400x300/0f190b/ffffff?text=SmartHome+Iron+836G", - "description": "Iron product image" - } - ], - "created_at": "2025-03-27T09:16:11.464144Z", - "updated_at": "2025-05-15T09:16:11.464144Z" - }, - { - "id": 255, - "name": "EcoTech Rice Cooker 371T", - "description": "EcoTech Rice Cooker 371T is a high-performance rice cooker designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 5, - "name": "Office Equipment" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 3.77, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 34.3, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 16.9, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 912, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 6.5, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 6.0, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 8.5, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 7, - "name": "Silicone", - "type": "Elastomer" - }, - "percentage": 16.0, - "mass": 0.39, - "unit": "kg" - }, - { - "material": { - "id": 4, - "name": "Mica", - "type": "Mineral" - }, - "percentage": 28.3, - "mass": 0.47, - "unit": "kg" - }, - { - "material": { - "id": 6, - "name": "Polypropylene", - "type": "Plastic" - }, - "percentage": 55.7, - "mass": 1.23, - "unit": "kg" - } - ], - "components": [ - { - "id": 2551, - "name": "Rice Cooker Component 1", - "description": "High-quality part for rice cooker functionality" - }, - { - "id": 2552, - "name": "Rice Cooker Component 2", - "description": "High-quality part for rice cooker functionality" - }, - { - "id": 2553, - "name": "Rice Cooker Component 3", - "description": "High-quality part for rice cooker functionality" - } - ], - "images": [ - { - "id": 255, - "url": "https://via.placeholder.com/400x300/0dbca9/ffffff?text=EcoTech+Rice+Cooker+371T", - "description": "Rice Cooker product image" - } - ], - "created_at": "2025-01-01T09:16:11.464212Z", - "updated_at": "2025-05-09T09:16:11.464212Z" - }, - { - "id": 256, - "name": "SmartHome Rice Cooker 865X", - "description": "SmartHome Rice Cooker 865X is a high-performance rice cooker designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 2, - "name": "Home Electronics" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 2.02, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 28.1, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 18.6, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 913, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 9.1, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 5.5, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 9.0, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 5, - "name": "Borosilicate Glass", - "type": "Glass" - }, - "percentage": 35.7, - "mass": 0.49, - "unit": "kg" - }, - { - "material": { - "id": 3, - "name": "Copper Wire", - "type": "Metal" - }, - "percentage": 36.4, - "mass": 0.68, - "unit": "kg" - }, - { - "material": { - "id": 6, - "name": "Polypropylene", - "type": "Plastic" - }, - "percentage": 27.9, - "mass": 1.04, - "unit": "kg" - } - ], - "components": [ - { - "id": 2561, - "name": "Rice Cooker Component 1", - "description": "High-quality part for rice cooker functionality" - }, - { - "id": 2562, - "name": "Rice Cooker Component 2", - "description": "High-quality part for rice cooker functionality" - }, - { - "id": 2563, - "name": "Rice Cooker Component 3", - "description": "High-quality part for rice cooker functionality" - } - ], - "images": [ - { - "id": 256, - "url": "https://via.placeholder.com/400x300/036c99/ffffff?text=SmartHome+Rice+Cooker+865X", - "description": "Rice Cooker product image" - } - ], - "created_at": "2024-03-23T09:16:11.464310Z", - "updated_at": "2025-05-10T09:16:11.464310Z" - }, - { - "id": 257, - "name": "PureLife Kettle 821Z", - "description": "PureLife Kettle 821Z is a high-performance kettle designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 5, - "name": "Office Equipment" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 2.93, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 24.3, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 20.6, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 1831, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 6.2, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 9.0, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 7.1, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 3, - "name": "Copper Wire", - "type": "Metal" - }, - "percentage": 12.6, - "mass": 0.28, - "unit": "kg" - }, - { - "material": { - "id": 6, - "name": "Polypropylene", - "type": "Plastic" - }, - "percentage": 40.9, - "mass": 0.88, - "unit": "kg" - }, - { - "material": { - "id": 7, - "name": "Silicone", - "type": "Elastomer" - }, - "percentage": 46.5, - "mass": 1.83, - "unit": "kg" - } - ], - "components": [ - { - "id": 2571, - "name": "Kettle Component 1", - "description": "High-quality part for kettle functionality" - }, - { - "id": 2572, - "name": "Kettle Component 2", - "description": "High-quality part for kettle functionality" - }, - { - "id": 2573, - "name": "Kettle Component 3", - "description": "High-quality part for kettle functionality" - }, - { - "id": 2574, - "name": "Kettle Component 4", - "description": "High-quality part for kettle functionality" - } - ], - "images": [ - { - "id": 257, - "url": "https://via.placeholder.com/400x300/023c5a/ffffff?text=PureLife+Kettle+821Z", - "description": "Kettle product image" - } - ], - "created_at": "2024-08-18T09:16:11.464367Z", - "updated_at": "2025-06-14T09:16:11.464367Z" - }, - { - "id": 258, - "name": "EcoTech Rice Cooker 869X", - "description": "EcoTech Rice Cooker 869X is a high-performance rice cooker designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 4, - "name": "Smart Home Device" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 3.09, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 32.8, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 27.3, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 928, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 8.3, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 7.0, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 6.3, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 3, - "name": "Copper Wire", - "type": "Metal" - }, - "percentage": 35.4, - "mass": 1.14, - "unit": "kg" - }, - { - "material": { - "id": 4, - "name": "Mica", - "type": "Mineral" - }, - "percentage": 27.8, - "mass": 1.01, - "unit": "kg" - }, - { - "material": { - "id": 1, - "name": "Stainless Steel", - "type": "Metal" - }, - "percentage": 36.8, - "mass": 1.28, - "unit": "kg" - } - ], - "components": [ - { - "id": 2581, - "name": "Rice Cooker Component 1", - "description": "High-quality part for rice cooker functionality" - }, - { - "id": 2582, - "name": "Rice Cooker Component 2", - "description": "High-quality part for rice cooker functionality" - } - ], - "images": [ - { - "id": 258, - "url": "https://via.placeholder.com/400x300/0b7f3c/ffffff?text=EcoTech+Rice+Cooker+869X", - "description": "Rice Cooker product image" - } - ], - "created_at": "2024-09-22T09:16:11.464435Z", - "updated_at": "2025-06-30T09:16:11.464435Z" - }, - { - "id": 259, - "name": "ZenGear Humidifier 787T", - "description": "ZenGear Humidifier 787T is a high-performance humidifier designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 5, - "name": "Office Equipment" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 2.09, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 21.8, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 18.6, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 2044, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 8.9, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 8.9, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 6.2, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 5, - "name": "Borosilicate Glass", - "type": "Glass" - }, - "percentage": 31.7, - "mass": 0.59, - "unit": "kg" - }, - { - "material": { - "id": 2, - "name": "ABS Plastic", - "type": "Plastic" - }, - "percentage": 33.3, - "mass": 0.43, - "unit": "kg" - }, - { - "material": { - "id": 3, - "name": "Copper Wire", - "type": "Metal" - }, - "percentage": 20.8, - "mass": 0.77, - "unit": "kg" - }, - { - "material": { - "id": 1, - "name": "Stainless Steel", - "type": "Metal" - }, - "percentage": 14.2, - "mass": 0.54, - "unit": "kg" - } - ], - "components": [ - { - "id": 2591, - "name": "Humidifier Component 1", - "description": "High-quality part for humidifier functionality" - }, - { - "id": 2592, - "name": "Humidifier Component 2", - "description": "High-quality part for humidifier functionality" - } - ], - "images": [ - { - "id": 259, - "url": "https://via.placeholder.com/400x300/0f1fa5/ffffff?text=ZenGear+Humidifier+787T", - "description": "Humidifier product image" - } - ], - "created_at": "2024-08-25T09:16:11.464493Z", - "updated_at": "2025-05-03T09:16:11.464493Z" - }, - { - "id": 260, - "name": "EcoTech Kettle 165T", - "description": "EcoTech Kettle 165T is a high-performance kettle designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 3, - "name": "Personal Care Device" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 2.99, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 21.7, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 29.5, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 1532, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 8.4, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 7.4, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 7.0, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 4, - "name": "Mica", - "type": "Mineral" - }, - "percentage": 54.2, - "mass": 0.55, - "unit": "kg" - }, - { - "material": { - "id": 7, - "name": "Silicone", - "type": "Elastomer" - }, - "percentage": 45.8, - "mass": 0.82, - "unit": "kg" - } - ], - "components": [ - { - "id": 2601, - "name": "Kettle Component 1", - "description": "High-quality part for kettle functionality" - }, - { - "id": 2602, - "name": "Kettle Component 2", - "description": "High-quality part for kettle functionality" - }, - { - "id": 2603, - "name": "Kettle Component 3", - "description": "High-quality part for kettle functionality" - }, - { - "id": 2604, - "name": "Kettle Component 4", - "description": "High-quality part for kettle functionality" - }, - { - "id": 2605, - "name": "Kettle Component 5", - "description": "High-quality part for kettle functionality" - } - ], - "images": [ - { - "id": 260, - "url": "https://via.placeholder.com/400x300/080cf2/ffffff?text=EcoTech+Kettle+165T", - "description": "Kettle product image" - } - ], - "created_at": "2024-06-28T09:16:11.464549Z", - "updated_at": "2025-05-16T09:16:11.464549Z" - }, - { - "id": 261, - "name": "NeoCook Coffee Maker 295E", - "description": "NeoCook Coffee Maker 295E is a high-performance coffee maker designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 4, - "name": "Smart Home Device" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 3.1, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 33.2, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 15.7, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 1318, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 8.4, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 8.1, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 8.5, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 5, - "name": "Borosilicate Glass", - "type": "Glass" - }, - "percentage": 40.2, - "mass": 0.43, - "unit": "kg" - }, - { - "material": { - "id": 3, - "name": "Copper Wire", - "type": "Metal" - }, - "percentage": 59.8, - "mass": 1.97, - "unit": "kg" - } - ], - "components": [ - { - "id": 2611, - "name": "Coffee Maker Component 1", - "description": "High-quality part for coffee maker functionality" - }, - { - "id": 2612, - "name": "Coffee Maker Component 2", - "description": "High-quality part for coffee maker functionality" - }, - { - "id": 2613, - "name": "Coffee Maker Component 3", - "description": "High-quality part for coffee maker functionality" - } - ], - "images": [ - { - "id": 261, - "url": "https://via.placeholder.com/400x300/07d5e7/ffffff?text=NeoCook+Coffee+Maker+295E", - "description": "Coffee Maker product image" - } - ], - "created_at": "2024-11-26T09:16:11.464610Z", - "updated_at": "2025-05-06T09:16:11.464610Z" - }, - { - "id": 262, - "name": "AquaPro Blender 981U", - "description": "AquaPro Blender 981U is a high-performance blender designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 1, - "name": "Kitchen Appliance" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 1.93, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 25.2, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 15.0, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 1731, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 6.3, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 7.8, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 7.3, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 4, - "name": "Mica", - "type": "Mineral" - }, - "percentage": 30.7, - "mass": 1.23, - "unit": "kg" - }, - { - "material": { - "id": 6, - "name": "Polypropylene", - "type": "Plastic" - }, - "percentage": 59.4, - "mass": 1.63, - "unit": "kg" - }, - { - "material": { - "id": 5, - "name": "Borosilicate Glass", - "type": "Glass" - }, - "percentage": 9.9, - "mass": 0.12, - "unit": "kg" - } - ], - "components": [ - { - "id": 2621, - "name": "Blender Component 1", - "description": "High-quality part for blender functionality" - }, - { - "id": 2622, - "name": "Blender Component 2", - "description": "High-quality part for blender functionality" - }, - { - "id": 2623, - "name": "Blender Component 3", - "description": "High-quality part for blender functionality" - }, - { - "id": 2624, - "name": "Blender Component 4", - "description": "High-quality part for blender functionality" - }, - { - "id": 2625, - "name": "Blender Component 5", - "description": "High-quality part for blender functionality" - } - ], - "images": [ - { - "id": 262, - "url": "https://via.placeholder.com/400x300/091f8c/ffffff?text=AquaPro+Blender+981U", - "description": "Blender product image" - } - ], - "created_at": "2024-03-26T09:16:11.464678Z", - "updated_at": "2025-05-06T09:16:11.464678Z" - }, - { - "id": 263, - "name": "EcoTech Monitor 313N", - "description": "EcoTech Monitor 313N is a high-performance monitor designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 5, - "name": "Office Equipment" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 3.8, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 22.2, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 17.1, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 1380, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 6.4, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 6.4, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 7.1, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 2, - "name": "ABS Plastic", - "type": "Plastic" - }, - "percentage": 78.3, - "mass": 0.8, - "unit": "kg" - }, - { - "material": { - "id": 5, - "name": "Borosilicate Glass", - "type": "Glass" - }, - "percentage": 21.7, - "mass": 0.67, - "unit": "kg" - } - ], - "components": [ - { - "id": 2631, - "name": "Monitor Component 1", - "description": "High-quality part for monitor functionality" - }, - { - "id": 2632, - "name": "Monitor Component 2", - "description": "High-quality part for monitor functionality" - }, - { - "id": 2633, - "name": "Monitor Component 3", - "description": "High-quality part for monitor functionality" - } - ], - "images": [ - { - "id": 263, - "url": "https://via.placeholder.com/400x300/0cacdf/ffffff?text=EcoTech+Monitor+313N", - "description": "Monitor product image" - } - ], - "created_at": "2024-10-02T09:16:11.464733Z", - "updated_at": "2025-06-11T09:16:11.464733Z" - }, - { - "id": 264, - "name": "PureLife Monitor 694H", - "description": "PureLife Monitor 694H is a high-performance monitor designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 3, - "name": "Personal Care Device" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 1.12, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 32.3, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 24.0, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 1466, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 7.9, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 6.0, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 8.4, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 5, - "name": "Borosilicate Glass", - "type": "Glass" - }, - "percentage": 44.4, - "mass": 1.66, - "unit": "kg" - }, - { - "material": { - "id": 4, - "name": "Mica", - "type": "Mineral" - }, - "percentage": 55.6, - "mass": 2.1, - "unit": "kg" - } - ], - "components": [ - { - "id": 2641, - "name": "Monitor Component 1", - "description": "High-quality part for monitor functionality" - }, - { - "id": 2642, - "name": "Monitor Component 2", - "description": "High-quality part for monitor functionality" - } - ], - "images": [ - { - "id": 264, - "url": "https://via.placeholder.com/400x300/05f976/ffffff?text=PureLife+Monitor+694H", - "description": "Monitor product image" - } - ], - "created_at": "2024-10-22T09:16:11.464781Z", - "updated_at": "2025-07-09T09:16:11.464781Z" - }, - { - "id": 265, - "name": "PureLife Toaster 748C", - "description": "PureLife Toaster 748C is a high-performance toaster designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 3, - "name": "Personal Care Device" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 2.23, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 21.2, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 19.8, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 1253, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 8.8, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 8.5, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 9.8, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 6, - "name": "Polypropylene", - "type": "Plastic" - }, - "percentage": 19.8, - "mass": 0.3, - "unit": "kg" - }, - { - "material": { - "id": 4, - "name": "Mica", - "type": "Mineral" - }, - "percentage": 28.4, - "mass": 0.69, - "unit": "kg" - }, - { - "material": { - "id": 3, - "name": "Copper Wire", - "type": "Metal" - }, - "percentage": 21.6, - "mass": 0.56, - "unit": "kg" - }, - { - "material": { - "id": 1, - "name": "Stainless Steel", - "type": "Metal" - }, - "percentage": 30.2, - "mass": 0.49, - "unit": "kg" - } - ], - "components": [ - { - "id": 2651, - "name": "Toaster Component 1", - "description": "High-quality part for toaster functionality" - }, - { - "id": 2652, - "name": "Toaster Component 2", - "description": "High-quality part for toaster functionality" - }, - { - "id": 2653, - "name": "Toaster Component 3", - "description": "High-quality part for toaster functionality" - }, - { - "id": 2654, - "name": "Toaster Component 4", - "description": "High-quality part for toaster functionality" - }, - { - "id": 2655, - "name": "Toaster Component 5", - "description": "High-quality part for toaster functionality" - } - ], - "images": [ - { - "id": 265, - "url": "https://via.placeholder.com/400x300/0d721e/ffffff?text=PureLife+Toaster+748C", - "description": "Toaster product image" - } - ], - "created_at": "2024-03-27T09:16:11.464862Z", - "updated_at": "2025-05-08T09:16:11.464862Z" - }, - { - "id": 266, - "name": "PureLife Humidifier 160T", - "description": "PureLife Humidifier 160T is a high-performance humidifier designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 5, - "name": "Office Equipment" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 1.21, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 25.0, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 26.0, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 2032, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 6.7, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 8.0, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 6.8, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 7, - "name": "Silicone", - "type": "Elastomer" - }, - "percentage": 76.5, - "mass": 1.65, - "unit": "kg" - }, - { - "material": { - "id": 3, - "name": "Copper Wire", - "type": "Metal" - }, - "percentage": 23.5, - "mass": 0.41, - "unit": "kg" - } - ], - "components": [ - { - "id": 2661, - "name": "Humidifier Component 1", - "description": "High-quality part for humidifier functionality" - }, - { - "id": 2662, - "name": "Humidifier Component 2", - "description": "High-quality part for humidifier functionality" - } - ], - "images": [ - { - "id": 266, - "url": "https://via.placeholder.com/400x300/05145a/ffffff?text=PureLife+Humidifier+160T", - "description": "Humidifier product image" - } - ], - "created_at": "2024-03-19T09:16:11.464975Z", - "updated_at": "2025-07-30T09:16:11.464975Z" - }, - { - "id": 267, - "name": "ChefMate Air Purifier 951O", - "description": "ChefMate Air Purifier 951O is a high-performance air purifier designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 1, - "name": "Kitchen Appliance" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 3.94, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 26.4, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 22.4, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 1994, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 8.7, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 7.0, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 7.0, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 4, - "name": "Mica", - "type": "Mineral" - }, - "percentage": 11.0, - "mass": 0.34, - "unit": "kg" - }, - { - "material": { - "id": 5, - "name": "Borosilicate Glass", - "type": "Glass" - }, - "percentage": 39.0, - "mass": 0.53, - "unit": "kg" - }, - { - "material": { - "id": 1, - "name": "Stainless Steel", - "type": "Metal" - }, - "percentage": 32.2, - "mass": 1.24, - "unit": "kg" - }, - { - "material": { - "id": 2, - "name": "ABS Plastic", - "type": "Plastic" - }, - "percentage": 17.8, - "mass": 0.42, - "unit": "kg" - } - ], - "components": [ - { - "id": 2671, - "name": "Air Purifier Component 1", - "description": "High-quality part for air purifier functionality" - }, - { - "id": 2672, - "name": "Air Purifier Component 2", - "description": "High-quality part for air purifier functionality" - }, - { - "id": 2673, - "name": "Air Purifier Component 3", - "description": "High-quality part for air purifier functionality" - }, - { - "id": 2674, - "name": "Air Purifier Component 4", - "description": "High-quality part for air purifier functionality" - }, - { - "id": 2675, - "name": "Air Purifier Component 5", - "description": "High-quality part for air purifier functionality" - } - ], - "images": [ - { - "id": 267, - "url": "https://via.placeholder.com/400x300/095092/ffffff?text=ChefMate+Air+Purifier+951O", - "description": "Air Purifier product image" - } - ], - "created_at": "2024-09-04T09:16:11.465048Z", - "updated_at": "2025-04-30T09:16:11.465048Z" - }, - { - "id": 268, - "name": "AquaPro Air Purifier 116R", - "description": "AquaPro Air Purifier 116R is a high-performance air purifier designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 1, - "name": "Kitchen Appliance" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 3.43, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 23.0, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 29.6, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 1660, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 6.1, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 7.8, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 7.2, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 1, - "name": "Stainless Steel", - "type": "Metal" - }, - "percentage": 50.0, - "mass": 1.22, - "unit": "kg" - }, - { - "material": { - "id": 4, - "name": "Mica", - "type": "Mineral" - }, - "percentage": 50.0, - "mass": 1.5, - "unit": "kg" - } - ], - "components": [ - { - "id": 2681, - "name": "Air Purifier Component 1", - "description": "High-quality part for air purifier functionality" - }, - { - "id": 2682, - "name": "Air Purifier Component 2", - "description": "High-quality part for air purifier functionality" - } - ], - "images": [ - { - "id": 268, - "url": "https://via.placeholder.com/400x300/058df3/ffffff?text=AquaPro+Air+Purifier+116R", - "description": "Air Purifier product image" - } - ], - "created_at": "2024-12-31T09:16:11.465104Z", - "updated_at": "2025-06-17T09:16:11.465104Z" - }, - { - "id": 269, - "name": "ChefMate Toaster 145U", - "description": "ChefMate Toaster 145U is a high-performance toaster designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 3, - "name": "Personal Care Device" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 2.73, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 21.4, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 17.7, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 1634, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 7.0, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 7.1, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 8.5, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 2, - "name": "ABS Plastic", - "type": "Plastic" - }, - "percentage": 55.3, - "mass": 1.88, - "unit": "kg" - }, - { - "material": { - "id": 1, - "name": "Stainless Steel", - "type": "Metal" - }, - "percentage": 44.7, - "mass": 1.59, - "unit": "kg" - } - ], - "components": [ - { - "id": 2691, - "name": "Toaster Component 1", - "description": "High-quality part for toaster functionality" - }, - { - "id": 2692, - "name": "Toaster Component 2", - "description": "High-quality part for toaster functionality" - } - ], - "images": [ - { - "id": 269, - "url": "https://via.placeholder.com/400x300/08ac73/ffffff?text=ChefMate+Toaster+145U", - "description": "Toaster product image" - } - ], - "created_at": "2024-07-02T09:16:11.465165Z", - "updated_at": "2025-06-18T09:16:11.465165Z" - }, - { - "id": 270, - "name": "CleanWave Rice Cooker 594W", - "description": "CleanWave Rice Cooker 594W is a high-performance rice cooker designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 3, - "name": "Personal Care Device" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 3.0, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 26.6, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 26.4, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 890, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 8.2, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 5.4, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 6.6, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 7, - "name": "Silicone", - "type": "Elastomer" - }, - "percentage": 22.8, - "mass": 0.46, - "unit": "kg" - }, - { - "material": { - "id": 2, - "name": "ABS Plastic", - "type": "Plastic" - }, - "percentage": 39.1, - "mass": 0.87, - "unit": "kg" - }, - { - "material": { - "id": 1, - "name": "Stainless Steel", - "type": "Metal" - }, - "percentage": 38.0, - "mass": 0.79, - "unit": "kg" - } - ], - "components": [ - { - "id": 2701, - "name": "Rice Cooker Component 1", - "description": "High-quality part for rice cooker functionality" - }, - { - "id": 2702, - "name": "Rice Cooker Component 2", - "description": "High-quality part for rice cooker functionality" - }, - { - "id": 2703, - "name": "Rice Cooker Component 3", - "description": "High-quality part for rice cooker functionality" - } - ], - "images": [ - { - "id": 270, - "url": "https://via.placeholder.com/400x300/08ccc2/ffffff?text=CleanWave+Rice+Cooker+594W", - "description": "Rice Cooker product image" - } - ], - "created_at": "2024-09-30T09:16:11.465217Z", - "updated_at": "2025-07-18T09:16:11.465217Z" - }, - { - "id": 271, - "name": "NeoCook Coffee Maker 582N", - "description": "NeoCook Coffee Maker 582N is a high-performance coffee maker designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 1, - "name": "Kitchen Appliance" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 1.07, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 22.5, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 29.4, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 1082, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 7.0, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 8.6, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 9.0, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 6, - "name": "Polypropylene", - "type": "Plastic" - }, - "percentage": 17.9, - "mass": 0.34, - "unit": "kg" - }, - { - "material": { - "id": 4, - "name": "Mica", - "type": "Mineral" - }, - "percentage": 46.2, - "mass": 0.78, - "unit": "kg" - }, - { - "material": { - "id": 3, - "name": "Copper Wire", - "type": "Metal" - }, - "percentage": 35.9, - "mass": 0.78, - "unit": "kg" - } - ], - "components": [ - { - "id": 2711, - "name": "Coffee Maker Component 1", - "description": "High-quality part for coffee maker functionality" - }, - { - "id": 2712, - "name": "Coffee Maker Component 2", - "description": "High-quality part for coffee maker functionality" - } - ], - "images": [ - { - "id": 271, - "url": "https://via.placeholder.com/400x300/07ce5c/ffffff?text=NeoCook+Coffee+Maker+582N", - "description": "Coffee Maker product image" - } - ], - "created_at": "2024-11-03T09:16:11.465278Z", - "updated_at": "2025-06-03T09:16:11.465278Z" - }, - { - "id": 272, - "name": "EcoTech Blender 933K", - "description": "EcoTech Blender 933K is a high-performance blender designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 4, - "name": "Smart Home Device" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 3.01, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 34.3, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 24.4, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 1007, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 6.4, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 5.6, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 6.3, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 4, - "name": "Mica", - "type": "Mineral" - }, - "percentage": 53.4, - "mass": 0.6, - "unit": "kg" - }, - { - "material": { - "id": 7, - "name": "Silicone", - "type": "Elastomer" - }, - "percentage": 20.5, - "mass": 0.68, - "unit": "kg" - }, - { - "material": { - "id": 6, - "name": "Polypropylene", - "type": "Plastic" - }, - "percentage": 26.1, - "mass": 0.73, - "unit": "kg" - } - ], - "components": [ - { - "id": 2721, - "name": "Blender Component 1", - "description": "High-quality part for blender functionality" - }, - { - "id": 2722, - "name": "Blender Component 2", - "description": "High-quality part for blender functionality" - }, - { - "id": 2723, - "name": "Blender Component 3", - "description": "High-quality part for blender functionality" - }, - { - "id": 2724, - "name": "Blender Component 4", - "description": "High-quality part for blender functionality" - } - ], - "images": [ - { - "id": 272, - "url": "https://via.placeholder.com/400x300/0b3398/ffffff?text=EcoTech+Blender+933K", - "description": "Blender product image" - } - ], - "created_at": "2025-04-17T09:16:11.465341Z", - "updated_at": "2025-06-02T09:16:11.465341Z" - }, - { - "id": 273, - "name": "CleanWave Coffee Maker 371O", - "description": "CleanWave Coffee Maker 371O is a high-performance coffee maker designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 3, - "name": "Personal Care Device" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 2.21, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 26.5, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 27.4, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 1380, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 6.7, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 5.8, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 6.4, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 2, - "name": "ABS Plastic", - "type": "Plastic" - }, - "percentage": 43.4, - "mass": 0.47, - "unit": "kg" - }, - { - "material": { - "id": 4, - "name": "Mica", - "type": "Mineral" - }, - "percentage": 27.7, - "mass": 0.63, - "unit": "kg" - }, - { - "material": { - "id": 7, - "name": "Silicone", - "type": "Elastomer" - }, - "percentage": 28.9, - "mass": 0.64, - "unit": "kg" - } - ], - "components": [ - { - "id": 2731, - "name": "Coffee Maker Component 1", - "description": "High-quality part for coffee maker functionality" - }, - { - "id": 2732, - "name": "Coffee Maker Component 2", - "description": "High-quality part for coffee maker functionality" - }, - { - "id": 2733, - "name": "Coffee Maker Component 3", - "description": "High-quality part for coffee maker functionality" - }, - { - "id": 2734, - "name": "Coffee Maker Component 4", - "description": "High-quality part for coffee maker functionality" - }, - { - "id": 2735, - "name": "Coffee Maker Component 5", - "description": "High-quality part for coffee maker functionality" - } - ], - "images": [ - { - "id": 273, - "url": "https://via.placeholder.com/400x300/0aa952/ffffff?text=CleanWave+Coffee+Maker+371O", - "description": "Coffee Maker product image" - } - ], - "created_at": "2024-11-13T09:16:11.465394Z", - "updated_at": "2025-06-16T09:16:11.465394Z" - }, - { - "id": 274, - "name": "CleanWave Rice Cooker 295I", - "description": "CleanWave Rice Cooker 295I is a high-performance rice cooker designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 4, - "name": "Smart Home Device" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 1.48, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 25.3, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 16.9, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 1775, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 7.2, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 8.6, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 7.0, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 1, - "name": "Stainless Steel", - "type": "Metal" - }, - "percentage": 12.9, - "mass": 0.41, - "unit": "kg" - }, - { - "material": { - "id": 5, - "name": "Borosilicate Glass", - "type": "Glass" - }, - "percentage": 41.9, - "mass": 1.47, - "unit": "kg" - }, - { - "material": { - "id": 6, - "name": "Polypropylene", - "type": "Plastic" - }, - "percentage": 45.2, - "mass": 1.69, - "unit": "kg" - } - ], - "components": [ - { - "id": 2741, - "name": "Rice Cooker Component 1", - "description": "High-quality part for rice cooker functionality" - }, - { - "id": 2742, - "name": "Rice Cooker Component 2", - "description": "High-quality part for rice cooker functionality" - } - ], - "images": [ - { - "id": 274, - "url": "https://via.placeholder.com/400x300/0a3127/ffffff?text=CleanWave+Rice+Cooker+295I", - "description": "Rice Cooker product image" - } - ], - "created_at": "2025-02-11T09:16:11.465465Z", - "updated_at": "2025-06-06T09:16:11.465465Z" - }, - { - "id": 275, - "name": "CleanWave Air Purifier 656B", - "description": "CleanWave Air Purifier 656B is a high-performance air purifier designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 2, - "name": "Home Electronics" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 2.0, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 29.1, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 27.5, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 1657, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 6.6, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 7.2, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 6.6, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 5, - "name": "Borosilicate Glass", - "type": "Glass" - }, - "percentage": 55.7, - "mass": 1.49, - "unit": "kg" - }, - { - "material": { - "id": 2, - "name": "ABS Plastic", - "type": "Plastic" - }, - "percentage": 44.3, - "mass": 1.49, - "unit": "kg" - } - ], - "components": [ - { - "id": 2751, - "name": "Air Purifier Component 1", - "description": "High-quality part for air purifier functionality" - }, - { - "id": 2752, - "name": "Air Purifier Component 2", - "description": "High-quality part for air purifier functionality" - }, - { - "id": 2753, - "name": "Air Purifier Component 3", - "description": "High-quality part for air purifier functionality" - }, - { - "id": 2754, - "name": "Air Purifier Component 4", - "description": "High-quality part for air purifier functionality" - } - ], - "images": [ - { - "id": 275, - "url": "https://via.placeholder.com/400x300/04e70f/ffffff?text=CleanWave+Air+Purifier+656B", - "description": "Air Purifier product image" - } - ], - "created_at": "2024-05-07T09:16:11.465515Z", - "updated_at": "2025-06-24T09:16:11.465515Z" - }, - { - "id": 276, - "name": "EcoTech Coffee Maker 165P", - "description": "EcoTech Coffee Maker 165P is a high-performance coffee maker designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 3, - "name": "Personal Care Device" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 1.29, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 28.4, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 16.6, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 1181, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 7.8, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 6.7, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 7.5, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 5, - "name": "Borosilicate Glass", - "type": "Glass" - }, - "percentage": 28.2, - "mass": 1.0, - "unit": "kg" - }, - { - "material": { - "id": 3, - "name": "Copper Wire", - "type": "Metal" - }, - "percentage": 7.1, - "mass": 0.12, - "unit": "kg" - }, - { - "material": { - "id": 4, - "name": "Mica", - "type": "Mineral" - }, - "percentage": 32.7, - "mass": 0.9, - "unit": "kg" - }, - { - "material": { - "id": 7, - "name": "Silicone", - "type": "Elastomer" - }, - "percentage": 32.1, - "mass": 0.44, - "unit": "kg" - } - ], - "components": [ - { - "id": 2761, - "name": "Coffee Maker Component 1", - "description": "High-quality part for coffee maker functionality" - }, - { - "id": 2762, - "name": "Coffee Maker Component 2", - "description": "High-quality part for coffee maker functionality" - }, - { - "id": 2763, - "name": "Coffee Maker Component 3", - "description": "High-quality part for coffee maker functionality" - }, - { - "id": 2764, - "name": "Coffee Maker Component 4", - "description": "High-quality part for coffee maker functionality" - }, - { - "id": 2765, - "name": "Coffee Maker Component 5", - "description": "High-quality part for coffee maker functionality" - } - ], - "images": [ - { - "id": 276, - "url": "https://via.placeholder.com/400x300/0978e5/ffffff?text=EcoTech+Coffee+Maker+165P", - "description": "Coffee Maker product image" - } - ], - "created_at": "2024-08-27T09:16:11.465587Z", - "updated_at": "2025-04-26T09:16:11.465587Z" - }, - { - "id": 277, - "name": "CleanWave Fan 815K", - "description": "CleanWave Fan 815K is a high-performance fan designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 4, - "name": "Smart Home Device" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 3.69, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 24.2, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 18.4, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 1768, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 7.8, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 5.1, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 10.0, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 2, - "name": "ABS Plastic", - "type": "Plastic" - }, - "percentage": 13.6, - "mass": 0.49, - "unit": "kg" - }, - { - "material": { - "id": 6, - "name": "Polypropylene", - "type": "Plastic" - }, - "percentage": 30.0, - "mass": 0.69, - "unit": "kg" - }, - { - "material": { - "id": 4, - "name": "Mica", - "type": "Mineral" - }, - "percentage": 27.9, - "mass": 0.42, - "unit": "kg" - }, - { - "material": { - "id": 5, - "name": "Borosilicate Glass", - "type": "Glass" - }, - "percentage": 28.6, - "mass": 1.02, - "unit": "kg" - } - ], - "components": [ - { - "id": 2771, - "name": "Fan Component 1", - "description": "High-quality part for fan functionality" - }, - { - "id": 2772, - "name": "Fan Component 2", - "description": "High-quality part for fan functionality" - }, - { - "id": 2773, - "name": "Fan Component 3", - "description": "High-quality part for fan functionality" - } - ], - "images": [ - { - "id": 277, - "url": "https://via.placeholder.com/400x300/09935b/ffffff?text=CleanWave+Fan+815K", - "description": "Fan product image" - } - ], - "created_at": "2025-04-17T09:16:11.465651Z", - "updated_at": "2025-05-10T09:16:11.465651Z" - }, - { - "id": 278, - "name": "NeoCook Toaster 826V", - "description": "NeoCook Toaster 826V is a high-performance toaster designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 4, - "name": "Smart Home Device" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 1.36, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 31.3, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 15.6, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 986, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 7.8, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 8.6, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 7.9, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 2, - "name": "ABS Plastic", - "type": "Plastic" - }, - "percentage": 11.5, - "mass": 0.29, - "unit": "kg" - }, - { - "material": { - "id": 1, - "name": "Stainless Steel", - "type": "Metal" - }, - "percentage": 35.4, - "mass": 0.62, - "unit": "kg" - }, - { - "material": { - "id": 7, - "name": "Silicone", - "type": "Elastomer" - }, - "percentage": 42.3, - "mass": 1.13, - "unit": "kg" - }, - { - "material": { - "id": 4, - "name": "Mica", - "type": "Mineral" - }, - "percentage": 10.8, - "mass": 0.13, - "unit": "kg" - } - ], - "components": [ - { - "id": 2781, - "name": "Toaster Component 1", - "description": "High-quality part for toaster functionality" - }, - { - "id": 2782, - "name": "Toaster Component 2", - "description": "High-quality part for toaster functionality" - }, - { - "id": 2783, - "name": "Toaster Component 3", - "description": "High-quality part for toaster functionality" - } - ], - "images": [ - { - "id": 278, - "url": "https://via.placeholder.com/400x300/0b3fe6/ffffff?text=NeoCook+Toaster+826V", - "description": "Toaster product image" - } - ], - "created_at": "2024-08-19T09:16:11.465712Z", - "updated_at": "2025-06-23T09:16:11.465712Z" - }, - { - "id": 279, - "name": "PureLife Monitor 317U", - "description": "PureLife Monitor 317U is a high-performance monitor designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 1, - "name": "Kitchen Appliance" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 1.86, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 21.7, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 23.9, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 2167, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 8.6, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 7.2, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 9.2, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 5, - "name": "Borosilicate Glass", - "type": "Glass" - }, - "percentage": 27.3, - "mass": 0.6, - "unit": "kg" - }, - { - "material": { - "id": 4, - "name": "Mica", - "type": "Mineral" - }, - "percentage": 36.4, - "mass": 1.05, - "unit": "kg" - }, - { - "material": { - "id": 1, - "name": "Stainless Steel", - "type": "Metal" - }, - "percentage": 10.7, - "mass": 0.42, - "unit": "kg" - }, - { - "material": { - "id": 2, - "name": "ABS Plastic", - "type": "Plastic" - }, - "percentage": 25.6, - "mass": 0.77, - "unit": "kg" - } - ], - "components": [ - { - "id": 2791, - "name": "Monitor Component 1", - "description": "High-quality part for monitor functionality" - }, - { - "id": 2792, - "name": "Monitor Component 2", - "description": "High-quality part for monitor functionality" - } - ], - "images": [ - { - "id": 279, - "url": "https://via.placeholder.com/400x300/0f07a9/ffffff?text=PureLife+Monitor+317U", - "description": "Monitor product image" - } - ], - "created_at": "2025-04-23T09:16:11.465768Z", - "updated_at": "2025-06-12T09:16:11.465768Z" - }, - { - "id": 280, - "name": "SmartHome Rice Cooker 990X", - "description": "SmartHome Rice Cooker 990X is a high-performance rice cooker designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 5, - "name": "Office Equipment" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 1.81, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 31.1, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 23.8, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 1068, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 9.1, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 6.5, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 9.9, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 7, - "name": "Silicone", - "type": "Elastomer" - }, - "percentage": 44.7, - "mass": 1.58, - "unit": "kg" - }, - { - "material": { - "id": 5, - "name": "Borosilicate Glass", - "type": "Glass" - }, - "percentage": 55.3, - "mass": 0.61, - "unit": "kg" - } - ], - "components": [ - { - "id": 2801, - "name": "Rice Cooker Component 1", - "description": "High-quality part for rice cooker functionality" - }, - { - "id": 2802, - "name": "Rice Cooker Component 2", - "description": "High-quality part for rice cooker functionality" - }, - { - "id": 2803, - "name": "Rice Cooker Component 3", - "description": "High-quality part for rice cooker functionality" - }, - { - "id": 2804, - "name": "Rice Cooker Component 4", - "description": "High-quality part for rice cooker functionality" - }, - { - "id": 2805, - "name": "Rice Cooker Component 5", - "description": "High-quality part for rice cooker functionality" - } - ], - "images": [ - { - "id": 280, - "url": "https://via.placeholder.com/400x300/0316f5/ffffff?text=SmartHome+Rice+Cooker+990X", - "description": "Rice Cooker product image" - } - ], - "created_at": "2024-12-02T09:16:11.465843Z", - "updated_at": "2025-06-13T09:16:11.465843Z" - }, - { - "id": 281, - "name": "ChefMate Humidifier 455V", - "description": "ChefMate Humidifier 455V is a high-performance humidifier designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 5, - "name": "Office Equipment" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 3.51, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 34.3, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 15.8, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 1805, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 8.3, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 6.2, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 9.2, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 1, - "name": "Stainless Steel", - "type": "Metal" - }, - "percentage": 56.2, - "mass": 0.9, - "unit": "kg" - }, - { - "material": { - "id": 4, - "name": "Mica", - "type": "Mineral" - }, - "percentage": 31.2, - "mass": 0.38, - "unit": "kg" - }, - { - "material": { - "id": 5, - "name": "Borosilicate Glass", - "type": "Glass" - }, - "percentage": 12.5, - "mass": 0.34, - "unit": "kg" - } - ], - "components": [ - { - "id": 2811, - "name": "Humidifier Component 1", - "description": "High-quality part for humidifier functionality" - }, - { - "id": 2812, - "name": "Humidifier Component 2", - "description": "High-quality part for humidifier functionality" - }, - { - "id": 2813, - "name": "Humidifier Component 3", - "description": "High-quality part for humidifier functionality" - }, - { - "id": 2814, - "name": "Humidifier Component 4", - "description": "High-quality part for humidifier functionality" - }, - { - "id": 2815, - "name": "Humidifier Component 5", - "description": "High-quality part for humidifier functionality" - } - ], - "images": [ - { - "id": 281, - "url": "https://via.placeholder.com/400x300/034834/ffffff?text=ChefMate+Humidifier+455V", - "description": "Humidifier product image" - } - ], - "created_at": "2025-04-08T09:16:11.465899Z", - "updated_at": "2025-06-16T09:16:11.465899Z" - }, - { - "id": 282, - "name": "NeoCook Monitor 125C", - "description": "NeoCook Monitor 125C is a high-performance monitor designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 5, - "name": "Office Equipment" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 3.09, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 22.6, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 16.2, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 1787, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 6.6, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 7.1, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 6.4, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 1, - "name": "Stainless Steel", - "type": "Metal" - }, - "percentage": 50.4, - "mass": 1.55, - "unit": "kg" - }, - { - "material": { - "id": 7, - "name": "Silicone", - "type": "Elastomer" - }, - "percentage": 38.7, - "mass": 1.48, - "unit": "kg" - }, - { - "material": { - "id": 4, - "name": "Mica", - "type": "Mineral" - }, - "percentage": 10.9, - "mass": 0.41, - "unit": "kg" - } - ], - "components": [ - { - "id": 2821, - "name": "Monitor Component 1", - "description": "High-quality part for monitor functionality" - }, - { - "id": 2822, - "name": "Monitor Component 2", - "description": "High-quality part for monitor functionality" - } - ], - "images": [ - { - "id": 282, - "url": "https://via.placeholder.com/400x300/0c4961/ffffff?text=NeoCook+Monitor+125C", - "description": "Monitor product image" - } - ], - "created_at": "2024-12-20T09:16:11.466151Z", - "updated_at": "2025-05-23T09:16:11.466151Z" - }, - { - "id": 283, - "name": "EcoTech Iron 197P", - "description": "EcoTech Iron 197P is a high-performance iron designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 4, - "name": "Smart Home Device" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 3.44, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 28.8, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 23.6, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 2065, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 7.9, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 6.6, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 9.8, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 3, - "name": "Copper Wire", - "type": "Metal" - }, - "percentage": 36.4, - "mass": 0.49, - "unit": "kg" - }, - { - "material": { - "id": 6, - "name": "Polypropylene", - "type": "Plastic" - }, - "percentage": 41.7, - "mass": 0.46, - "unit": "kg" - }, - { - "material": { - "id": 5, - "name": "Borosilicate Glass", - "type": "Glass" - }, - "percentage": 22.0, - "mass": 0.39, - "unit": "kg" - } - ], - "components": [ - { - "id": 2831, - "name": "Iron Component 1", - "description": "High-quality part for iron functionality" - }, - { - "id": 2832, - "name": "Iron Component 2", - "description": "High-quality part for iron functionality" - }, - { - "id": 2833, - "name": "Iron Component 3", - "description": "High-quality part for iron functionality" - }, - { - "id": 2834, - "name": "Iron Component 4", - "description": "High-quality part for iron functionality" - }, - { - "id": 2835, - "name": "Iron Component 5", - "description": "High-quality part for iron functionality" - } - ], - "images": [ - { - "id": 283, - "url": "https://via.placeholder.com/400x300/01b85e/ffffff?text=EcoTech+Iron+197P", - "description": "Iron product image" - } - ], - "created_at": "2025-04-19T09:16:11.466258Z", - "updated_at": "2025-07-28T09:16:11.466258Z" - }, - { - "id": 284, - "name": "CleanWave Monitor 381B", - "description": "CleanWave Monitor 381B is a high-performance monitor designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 3, - "name": "Personal Care Device" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 1.32, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 22.6, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 16.6, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 1101, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 7.4, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 8.1, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 7.4, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 2, - "name": "ABS Plastic", - "type": "Plastic" - }, - "percentage": 41.2, - "mass": 1.49, - "unit": "kg" - }, - { - "material": { - "id": 5, - "name": "Borosilicate Glass", - "type": "Glass" - }, - "percentage": 17.6, - "mass": 0.34, - "unit": "kg" - }, - { - "material": { - "id": 7, - "name": "Silicone", - "type": "Elastomer" - }, - "percentage": 41.2, - "mass": 1.6, - "unit": "kg" - } - ], - "components": [ - { - "id": 2841, - "name": "Monitor Component 1", - "description": "High-quality part for monitor functionality" - }, - { - "id": 2842, - "name": "Monitor Component 2", - "description": "High-quality part for monitor functionality" - }, - { - "id": 2843, - "name": "Monitor Component 3", - "description": "High-quality part for monitor functionality" - }, - { - "id": 2844, - "name": "Monitor Component 4", - "description": "High-quality part for monitor functionality" - }, - { - "id": 2845, - "name": "Monitor Component 5", - "description": "High-quality part for monitor functionality" - } - ], - "images": [ - { - "id": 284, - "url": "https://via.placeholder.com/400x300/0dc916/ffffff?text=CleanWave+Monitor+381B", - "description": "Monitor product image" - } - ], - "created_at": "2025-02-22T09:16:11.466327Z", - "updated_at": "2025-07-06T09:16:11.466327Z" - }, - { - "id": 285, - "name": "EcoTech Monitor 150C", - "description": "EcoTech Monitor 150C is a high-performance monitor designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 1, - "name": "Kitchen Appliance" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 1.89, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 23.5, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 29.0, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 1475, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 8.1, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 7.2, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 7.1, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 4, - "name": "Mica", - "type": "Mineral" - }, - "percentage": 44.0, - "mass": 1.02, - "unit": "kg" - }, - { - "material": { - "id": 2, - "name": "ABS Plastic", - "type": "Plastic" - }, - "percentage": 21.6, - "mass": 0.81, - "unit": "kg" - }, - { - "material": { - "id": 5, - "name": "Borosilicate Glass", - "type": "Glass" - }, - "percentage": 34.4, - "mass": 1.14, - "unit": "kg" - } - ], - "components": [ - { - "id": 2851, - "name": "Monitor Component 1", - "description": "High-quality part for monitor functionality" - }, - { - "id": 2852, - "name": "Monitor Component 2", - "description": "High-quality part for monitor functionality" - }, - { - "id": 2853, - "name": "Monitor Component 3", - "description": "High-quality part for monitor functionality" - }, - { - "id": 2854, - "name": "Monitor Component 4", - "description": "High-quality part for monitor functionality" - } - ], - "images": [ - { - "id": 285, - "url": "https://via.placeholder.com/400x300/0bd853/ffffff?text=EcoTech+Monitor+150C", - "description": "Monitor product image" - } - ], - "created_at": "2024-07-26T09:16:11.466367Z", - "updated_at": "2025-07-05T09:16:11.466367Z" - }, - { - "id": 286, - "name": "AquaPro Monitor 255R", - "description": "AquaPro Monitor 255R is a high-performance monitor designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 3, - "name": "Personal Care Device" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 3.88, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 28.1, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 19.8, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 1632, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 6.6, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 7.8, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 9.4, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 4, - "name": "Mica", - "type": "Mineral" - }, - "percentage": 27.5, - "mass": 0.59, - "unit": "kg" - }, - { - "material": { - "id": 3, - "name": "Copper Wire", - "type": "Metal" - }, - "percentage": 27.5, - "mass": 1.1, - "unit": "kg" - }, - { - "material": { - "id": 6, - "name": "Polypropylene", - "type": "Plastic" - }, - "percentage": 44.9, - "mass": 1.29, - "unit": "kg" - } - ], - "components": [ - { - "id": 2861, - "name": "Monitor Component 1", - "description": "High-quality part for monitor functionality" - }, - { - "id": 2862, - "name": "Monitor Component 2", - "description": "High-quality part for monitor functionality" - }, - { - "id": 2863, - "name": "Monitor Component 3", - "description": "High-quality part for monitor functionality" - } - ], - "images": [ - { - "id": 286, - "url": "https://via.placeholder.com/400x300/0309c4/ffffff?text=AquaPro+Monitor+255R", - "description": "Monitor product image" - } - ], - "created_at": "2025-02-16T09:16:11.466413Z", - "updated_at": "2025-07-24T09:16:11.466413Z" - }, - { - "id": 287, - "name": "ChefMate Monitor 552Y", - "description": "ChefMate Monitor 552Y is a high-performance monitor designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 2, - "name": "Home Electronics" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 3.43, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 28.8, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 22.0, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 1820, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 6.1, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 6.2, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 9.0, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 5, - "name": "Borosilicate Glass", - "type": "Glass" - }, - "percentage": 19.5, - "mass": 0.22, - "unit": "kg" - }, - { - "material": { - "id": 3, - "name": "Copper Wire", - "type": "Metal" - }, - "percentage": 28.9, - "mass": 0.69, - "unit": "kg" - }, - { - "material": { - "id": 2, - "name": "ABS Plastic", - "type": "Plastic" - }, - "percentage": 18.0, - "mass": 0.2, - "unit": "kg" - }, - { - "material": { - "id": 6, - "name": "Polypropylene", - "type": "Plastic" - }, - "percentage": 33.6, - "mass": 1.33, - "unit": "kg" - } - ], - "components": [ - { - "id": 2871, - "name": "Monitor Component 1", - "description": "High-quality part for monitor functionality" - }, - { - "id": 2872, - "name": "Monitor Component 2", - "description": "High-quality part for monitor functionality" - }, - { - "id": 2873, - "name": "Monitor Component 3", - "description": "High-quality part for monitor functionality" - }, - { - "id": 2874, - "name": "Monitor Component 4", - "description": "High-quality part for monitor functionality" - }, - { - "id": 2875, - "name": "Monitor Component 5", - "description": "High-quality part for monitor functionality" - } - ], - "images": [ - { - "id": 287, - "url": "https://via.placeholder.com/400x300/0e39d7/ffffff?text=ChefMate+Monitor+552Y", - "description": "Monitor product image" - } - ], - "created_at": "2024-05-08T09:16:11.466604Z", - "updated_at": "2025-07-26T09:16:11.466604Z" - }, - { - "id": 288, - "name": "EcoTech Monitor 479I", - "description": "EcoTech Monitor 479I is a high-performance monitor designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 5, - "name": "Office Equipment" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 2.67, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 30.0, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 19.0, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 1754, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 9.4, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 5.7, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 8.8, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 2, - "name": "ABS Plastic", - "type": "Plastic" - }, - "percentage": 29.7, - "mass": 0.9, - "unit": "kg" - }, - { - "material": { - "id": 3, - "name": "Copper Wire", - "type": "Metal" - }, - "percentage": 32.2, - "mass": 1.28, - "unit": "kg" - }, - { - "material": { - "id": 6, - "name": "Polypropylene", - "type": "Plastic" - }, - "percentage": 18.6, - "mass": 0.62, - "unit": "kg" - }, - { - "material": { - "id": 5, - "name": "Borosilicate Glass", - "type": "Glass" - }, - "percentage": 19.5, - "mass": 0.32, - "unit": "kg" - } - ], - "components": [ - { - "id": 2881, - "name": "Monitor Component 1", - "description": "High-quality part for monitor functionality" - }, - { - "id": 2882, - "name": "Monitor Component 2", - "description": "High-quality part for monitor functionality" - }, - { - "id": 2883, - "name": "Monitor Component 3", - "description": "High-quality part for monitor functionality" - }, - { - "id": 2884, - "name": "Monitor Component 4", - "description": "High-quality part for monitor functionality" - }, - { - "id": 2885, - "name": "Monitor Component 5", - "description": "High-quality part for monitor functionality" - } - ], - "images": [ - { - "id": 288, - "url": "https://via.placeholder.com/400x300/05e5d9/ffffff?text=EcoTech+Monitor+479I", - "description": "Monitor product image" - } - ], - "created_at": "2025-01-24T09:16:11.466670Z", - "updated_at": "2025-07-20T09:16:11.466670Z" - }, - { - "id": 289, - "name": "AquaPro Blender 305E", - "description": "AquaPro Blender 305E is a high-performance blender designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 3, - "name": "Personal Care Device" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 2.0, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 31.6, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 21.5, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 1115, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 6.4, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 8.1, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 8.5, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 3, - "name": "Copper Wire", - "type": "Metal" - }, - "percentage": 24.8, - "mass": 0.96, - "unit": "kg" - }, - { - "material": { - "id": 1, - "name": "Stainless Steel", - "type": "Metal" - }, - "percentage": 55.0, - "mass": 1.2, - "unit": "kg" - }, - { - "material": { - "id": 6, - "name": "Polypropylene", - "type": "Plastic" - }, - "percentage": 20.2, - "mass": 0.76, - "unit": "kg" - } - ], - "components": [ - { - "id": 2891, - "name": "Blender Component 1", - "description": "High-quality part for blender functionality" - }, - { - "id": 2892, - "name": "Blender Component 2", - "description": "High-quality part for blender functionality" - }, - { - "id": 2893, - "name": "Blender Component 3", - "description": "High-quality part for blender functionality" - }, - { - "id": 2894, - "name": "Blender Component 4", - "description": "High-quality part for blender functionality" - }, - { - "id": 2895, - "name": "Blender Component 5", - "description": "High-quality part for blender functionality" - } - ], - "images": [ - { - "id": 289, - "url": "https://via.placeholder.com/400x300/01a1d2/ffffff?text=AquaPro+Blender+305E", - "description": "Blender product image" - } - ], - "created_at": "2024-12-27T09:16:11.466726Z", - "updated_at": "2025-06-27T09:16:11.466726Z" - }, - { - "id": 290, - "name": "AquaPro Monitor 506U", - "description": "AquaPro Monitor 506U is a high-performance monitor designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 1, - "name": "Kitchen Appliance" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 1.6, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 20.3, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 23.7, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 1646, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 6.9, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 5.6, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 6.8, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 4, - "name": "Mica", - "type": "Mineral" - }, - "percentage": 26.1, - "mass": 0.81, - "unit": "kg" - }, - { - "material": { - "id": 2, - "name": "ABS Plastic", - "type": "Plastic" - }, - "percentage": 29.3, - "mass": 0.9, - "unit": "kg" - }, - { - "material": { - "id": 3, - "name": "Copper Wire", - "type": "Metal" - }, - "percentage": 25.0, - "mass": 0.82, - "unit": "kg" - }, - { - "material": { - "id": 5, - "name": "Borosilicate Glass", - "type": "Glass" - }, - "percentage": 19.6, - "mass": 0.29, - "unit": "kg" - } - ], - "components": [ - { - "id": 2901, - "name": "Monitor Component 1", - "description": "High-quality part for monitor functionality" - }, - { - "id": 2902, - "name": "Monitor Component 2", - "description": "High-quality part for monitor functionality" - }, - { - "id": 2903, - "name": "Monitor Component 3", - "description": "High-quality part for monitor functionality" - } - ], - "images": [ - { - "id": 290, - "url": "https://via.placeholder.com/400x300/02fd13/ffffff?text=AquaPro+Monitor+506U", - "description": "Monitor product image" - } - ], - "created_at": "2025-02-11T09:16:11.466786Z", - "updated_at": "2025-04-26T09:16:11.466786Z" - }, - { - "id": 291, - "name": "PureLife Air Purifier 874X", - "description": "PureLife Air Purifier 874X is a high-performance air purifier designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 4, - "name": "Smart Home Device" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 1.68, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 20.8, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 19.3, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 1175, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 7.7, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 8.2, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 6.5, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 1, - "name": "Stainless Steel", - "type": "Metal" - }, - "percentage": 53.2, - "mass": 1.52, - "unit": "kg" - }, - { - "material": { - "id": 4, - "name": "Mica", - "type": "Mineral" - }, - "percentage": 46.8, - "mass": 0.77, - "unit": "kg" - } - ], - "components": [ - { - "id": 2911, - "name": "Air Purifier Component 1", - "description": "High-quality part for air purifier functionality" - }, - { - "id": 2912, - "name": "Air Purifier Component 2", - "description": "High-quality part for air purifier functionality" - } - ], - "images": [ - { - "id": 291, - "url": "https://via.placeholder.com/400x300/0dc724/ffffff?text=PureLife+Air+Purifier+874X", - "description": "Air Purifier product image" - } - ], - "created_at": "2024-05-23T09:16:11.466843Z", - "updated_at": "2025-06-19T09:16:11.466843Z" - }, - { - "id": 292, - "name": "SmartHome Blender 307I", - "description": "SmartHome Blender 307I is a high-performance blender designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 2, - "name": "Home Electronics" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 2.66, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 30.4, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 17.2, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 1648, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 9.2, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 5.6, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 7.0, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 5, - "name": "Borosilicate Glass", - "type": "Glass" - }, - "percentage": 17.8, - "mass": 0.37, - "unit": "kg" - }, - { - "material": { - "id": 6, - "name": "Polypropylene", - "type": "Plastic" - }, - "percentage": 37.8, - "mass": 1.09, - "unit": "kg" - }, - { - "material": { - "id": 3, - "name": "Copper Wire", - "type": "Metal" - }, - "percentage": 16.7, - "mass": 0.2, - "unit": "kg" - }, - { - "material": { - "id": 4, - "name": "Mica", - "type": "Mineral" - }, - "percentage": 27.8, - "mass": 1.09, - "unit": "kg" - } - ], - "components": [ - { - "id": 2921, - "name": "Blender Component 1", - "description": "High-quality part for blender functionality" - }, - { - "id": 2922, - "name": "Blender Component 2", - "description": "High-quality part for blender functionality" - } - ], - "images": [ - { - "id": 292, - "url": "https://via.placeholder.com/400x300/05fb28/ffffff?text=SmartHome+Blender+307I", - "description": "Blender product image" - } - ], - "created_at": "2025-02-28T09:16:11.466936Z", - "updated_at": "2025-06-02T09:16:11.466936Z" - }, - { - "id": 293, - "name": "PureLife Coffee Maker 936G", - "description": "PureLife Coffee Maker 936G is a high-performance coffee maker designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 5, - "name": "Office Equipment" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 3.33, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 23.2, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 28.3, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 1181, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 7.8, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 6.9, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 9.6, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 3, - "name": "Copper Wire", - "type": "Metal" - }, - "percentage": 51.7, - "mass": 1.13, - "unit": "kg" - }, - { - "material": { - "id": 5, - "name": "Borosilicate Glass", - "type": "Glass" - }, - "percentage": 48.3, - "mass": 0.78, - "unit": "kg" - } - ], - "components": [ - { - "id": 2931, - "name": "Coffee Maker Component 1", - "description": "High-quality part for coffee maker functionality" - }, - { - "id": 2932, - "name": "Coffee Maker Component 2", - "description": "High-quality part for coffee maker functionality" - } - ], - "images": [ - { - "id": 293, - "url": "https://via.placeholder.com/400x300/07d5d7/ffffff?text=PureLife+Coffee+Maker+936G", - "description": "Coffee Maker product image" - } - ], - "created_at": "2025-02-22T09:16:11.466985Z", - "updated_at": "2025-05-19T09:16:11.466985Z" - }, - { - "id": 294, - "name": "NeoCook Toaster 589A", - "description": "NeoCook Toaster 589A is a high-performance toaster designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 4, - "name": "Smart Home Device" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 3.64, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 24.9, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 27.6, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 1699, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 8.1, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 6.9, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 8.3, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 2, - "name": "ABS Plastic", - "type": "Plastic" - }, - "percentage": 39.1, - "mass": 0.73, - "unit": "kg" - }, - { - "material": { - "id": 1, - "name": "Stainless Steel", - "type": "Metal" - }, - "percentage": 26.3, - "mass": 0.69, - "unit": "kg" - }, - { - "material": { - "id": 6, - "name": "Polypropylene", - "type": "Plastic" - }, - "percentage": 34.6, - "mass": 1.04, - "unit": "kg" - } - ], - "components": [ - { - "id": 2941, - "name": "Toaster Component 1", - "description": "High-quality part for toaster functionality" - }, - { - "id": 2942, - "name": "Toaster Component 2", - "description": "High-quality part for toaster functionality" - }, - { - "id": 2943, - "name": "Toaster Component 3", - "description": "High-quality part for toaster functionality" - }, - { - "id": 2944, - "name": "Toaster Component 4", - "description": "High-quality part for toaster functionality" - }, - { - "id": 2945, - "name": "Toaster Component 5", - "description": "High-quality part for toaster functionality" - } - ], - "images": [ - { - "id": 294, - "url": "https://via.placeholder.com/400x300/047deb/ffffff?text=NeoCook+Toaster+589A", - "description": "Toaster product image" - } - ], - "created_at": "2024-10-07T09:16:11.467037Z", - "updated_at": "2025-07-23T09:16:11.467037Z" - }, - { - "id": 295, - "name": "ZenGear Kettle 454K", - "description": "ZenGear Kettle 454K is a high-performance kettle designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 2, - "name": "Home Electronics" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 2.01, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 21.2, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 28.3, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 2171, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 7.1, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 8.7, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 8.0, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 1, - "name": "Stainless Steel", - "type": "Metal" - }, - "percentage": 41.6, - "mass": 1.1, - "unit": "kg" - }, - { - "material": { - "id": 6, - "name": "Polypropylene", - "type": "Plastic" - }, - "percentage": 28.0, - "mass": 0.4, - "unit": "kg" - }, - { - "material": { - "id": 3, - "name": "Copper Wire", - "type": "Metal" - }, - "percentage": 30.4, - "mass": 0.73, - "unit": "kg" - } - ], - "components": [ - { - "id": 2951, - "name": "Kettle Component 1", - "description": "High-quality part for kettle functionality" - }, - { - "id": 2952, - "name": "Kettle Component 2", - "description": "High-quality part for kettle functionality" - }, - { - "id": 2953, - "name": "Kettle Component 3", - "description": "High-quality part for kettle functionality" - }, - { - "id": 2954, - "name": "Kettle Component 4", - "description": "High-quality part for kettle functionality" - } - ], - "images": [ - { - "id": 295, - "url": "https://via.placeholder.com/400x300/070ae7/ffffff?text=ZenGear+Kettle+454K", - "description": "Kettle product image" - } - ], - "created_at": "2024-12-22T09:16:11.467091Z", - "updated_at": "2025-05-29T09:16:11.467091Z" - }, - { - "id": 296, - "name": "SmartHome Rice Cooker 275T", - "description": "SmartHome Rice Cooker 275T is a high-performance rice cooker designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 5, - "name": "Office Equipment" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 1.3, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 32.1, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 23.9, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 1067, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 8.5, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 8.9, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 8.0, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 6, - "name": "Polypropylene", - "type": "Plastic" - }, - "percentage": 50.7, - "mass": 0.78, - "unit": "kg" - }, - { - "material": { - "id": 1, - "name": "Stainless Steel", - "type": "Metal" - }, - "percentage": 49.3, - "mass": 1.11, - "unit": "kg" - } - ], - "components": [ - { - "id": 2961, - "name": "Rice Cooker Component 1", - "description": "High-quality part for rice cooker functionality" - }, - { - "id": 2962, - "name": "Rice Cooker Component 2", - "description": "High-quality part for rice cooker functionality" - }, - { - "id": 2963, - "name": "Rice Cooker Component 3", - "description": "High-quality part for rice cooker functionality" - } - ], - "images": [ - { - "id": 296, - "url": "https://via.placeholder.com/400x300/09afef/ffffff?text=SmartHome+Rice+Cooker+275T", - "description": "Rice Cooker product image" - } - ], - "created_at": "2024-11-07T09:16:11.467155Z", - "updated_at": "2025-05-23T09:16:11.467155Z" - }, - { - "id": 297, - "name": "ChefMate Monitor 548Y", - "description": "ChefMate Monitor 548Y is a high-performance monitor designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 5, - "name": "Office Equipment" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 4.0, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 21.2, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 17.0, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 2052, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 7.0, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 7.1, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 7.1, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 7, - "name": "Silicone", - "type": "Elastomer" - }, - "percentage": 25.0, - "mass": 0.33, - "unit": "kg" - }, - { - "material": { - "id": 4, - "name": "Mica", - "type": "Mineral" - }, - "percentage": 75.0, - "mass": 2.75, - "unit": "kg" - } - ], - "components": [ - { - "id": 2971, - "name": "Monitor Component 1", - "description": "High-quality part for monitor functionality" - }, - { - "id": 2972, - "name": "Monitor Component 2", - "description": "High-quality part for monitor functionality" - }, - { - "id": 2973, - "name": "Monitor Component 3", - "description": "High-quality part for monitor functionality" - }, - { - "id": 2974, - "name": "Monitor Component 4", - "description": "High-quality part for monitor functionality" - }, - { - "id": 2975, - "name": "Monitor Component 5", - "description": "High-quality part for monitor functionality" - } - ], - "images": [ - { - "id": 297, - "url": "https://via.placeholder.com/400x300/02c755/ffffff?text=ChefMate+Monitor+548Y", - "description": "Monitor product image" - } - ], - "created_at": "2024-04-09T09:16:11.467200Z", - "updated_at": "2025-07-02T09:16:11.467200Z" - }, - { - "id": 298, - "name": "CleanWave Kettle 973Q", - "description": "CleanWave Kettle 973Q is a high-performance kettle designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 1, - "name": "Kitchen Appliance" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 1.73, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 27.5, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 22.6, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 915, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 8.7, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 8.0, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 7.1, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 6, - "name": "Polypropylene", - "type": "Plastic" - }, - "percentage": 71.4, - "mass": 0.94, - "unit": "kg" - }, - { - "material": { - "id": 5, - "name": "Borosilicate Glass", - "type": "Glass" - }, - "percentage": 28.6, - "mass": 1.03, - "unit": "kg" - } - ], - "components": [ - { - "id": 2981, - "name": "Kettle Component 1", - "description": "High-quality part for kettle functionality" - }, - { - "id": 2982, - "name": "Kettle Component 2", - "description": "High-quality part for kettle functionality" - }, - { - "id": 2983, - "name": "Kettle Component 3", - "description": "High-quality part for kettle functionality" - }, - { - "id": 2984, - "name": "Kettle Component 4", - "description": "High-quality part for kettle functionality" - } - ], - "images": [ - { - "id": 298, - "url": "https://via.placeholder.com/400x300/0d57f8/ffffff?text=CleanWave+Kettle+973Q", - "description": "Kettle product image" - } - ], - "created_at": "2024-12-02T09:16:11.467253Z", - "updated_at": "2025-05-08T09:16:11.467253Z" - }, - { - "id": 299, - "name": "NeoCook Rice Cooker 872D", - "description": "NeoCook Rice Cooker 872D is a high-performance rice cooker designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 5, - "name": "Office Equipment" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 1.07, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 31.3, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 25.7, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 1987, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 6.6, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 7.4, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 9.1, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 2, - "name": "ABS Plastic", - "type": "Plastic" - }, - "percentage": 57.7, - "mass": 1.71, - "unit": "kg" - }, - { - "material": { - "id": 3, - "name": "Copper Wire", - "type": "Metal" - }, - "percentage": 42.3, - "mass": 1.41, - "unit": "kg" - } - ], - "components": [ - { - "id": 2991, - "name": "Rice Cooker Component 1", - "description": "High-quality part for rice cooker functionality" - }, - { - "id": 2992, - "name": "Rice Cooker Component 2", - "description": "High-quality part for rice cooker functionality" - }, - { - "id": 2993, - "name": "Rice Cooker Component 3", - "description": "High-quality part for rice cooker functionality" - }, - { - "id": 2994, - "name": "Rice Cooker Component 4", - "description": "High-quality part for rice cooker functionality" - } - ], - "images": [ - { - "id": 299, - "url": "https://via.placeholder.com/400x300/0b9d23/ffffff?text=NeoCook+Rice+Cooker+872D", - "description": "Rice Cooker product image" - } - ], - "created_at": "2025-02-17T09:16:11.467285Z", - "updated_at": "2025-07-15T09:16:11.467285Z" - }, - { - "id": 300, - "name": "EcoTech Toaster 625V", - "description": "EcoTech Toaster 625V is a high-performance toaster designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 1, - "name": "Kitchen Appliance" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 2.88, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 21.9, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 17.6, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 940, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 9.3, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 5.7, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 8.5, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 1, - "name": "Stainless Steel", - "type": "Metal" - }, - "percentage": 83.9, - "mass": 2.22, - "unit": "kg" - }, - { - "material": { - "id": 6, - "name": "Polypropylene", - "type": "Plastic" - }, - "percentage": 16.1, - "mass": 0.3, - "unit": "kg" - } - ], - "components": [ - { - "id": 3001, - "name": "Toaster Component 1", - "description": "High-quality part for toaster functionality" - }, - { - "id": 3002, - "name": "Toaster Component 2", - "description": "High-quality part for toaster functionality" - } - ], - "images": [ - { - "id": 300, - "url": "https://via.placeholder.com/400x300/0b4f56/ffffff?text=EcoTech+Toaster+625V", - "description": "Toaster product image" - } - ], - "created_at": "2024-09-30T09:16:11.467366Z", - "updated_at": "2025-07-14T09:16:11.467366Z" - }, - { - "id": 301, - "name": "NeoCook Toaster 322Y", - "description": "NeoCook Toaster 322Y is a high-performance toaster designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 2, - "name": "Home Electronics" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 2.67, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 28.7, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 26.5, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 1158, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 6.4, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 5.1, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 7.8, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 4, - "name": "Mica", - "type": "Mineral" - }, - "percentage": 23.0, - "mass": 0.32, - "unit": "kg" - }, - { - "material": { - "id": 6, - "name": "Polypropylene", - "type": "Plastic" - }, - "percentage": 26.3, - "mass": 0.85, - "unit": "kg" - }, - { - "material": { - "id": 1, - "name": "Stainless Steel", - "type": "Metal" - }, - "percentage": 21.7, - "mass": 0.34, - "unit": "kg" - }, - { - "material": { - "id": 7, - "name": "Silicone", - "type": "Elastomer" - }, - "percentage": 28.9, - "mass": 0.35, - "unit": "kg" - } - ], - "components": [ - { - "id": 3011, - "name": "Toaster Component 1", - "description": "High-quality part for toaster functionality" - }, - { - "id": 3012, - "name": "Toaster Component 2", - "description": "High-quality part for toaster functionality" - }, - { - "id": 3013, - "name": "Toaster Component 3", - "description": "High-quality part for toaster functionality" - }, - { - "id": 3014, - "name": "Toaster Component 4", - "description": "High-quality part for toaster functionality" - }, - { - "id": 3015, - "name": "Toaster Component 5", - "description": "High-quality part for toaster functionality" - } - ], - "images": [ - { - "id": 301, - "url": "https://via.placeholder.com/400x300/0431a4/ffffff?text=NeoCook+Toaster+322Y", - "description": "Toaster product image" - } - ], - "created_at": "2024-12-13T09:16:11.467421Z", - "updated_at": "2025-06-18T09:16:11.467421Z" - }, - { - "id": 302, - "name": "ChefMate Coffee Maker 427Z", - "description": "ChefMate Coffee Maker 427Z is a high-performance coffee maker designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 2, - "name": "Home Electronics" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 2.89, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 33.0, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 21.7, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 1856, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 8.1, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 5.6, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 7.3, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 4, - "name": "Mica", - "type": "Mineral" - }, - "percentage": 44.1, - "mass": 1.46, - "unit": "kg" - }, - { - "material": { - "id": 5, - "name": "Borosilicate Glass", - "type": "Glass" - }, - "percentage": 41.9, - "mass": 1.2, - "unit": "kg" - }, - { - "material": { - "id": 6, - "name": "Polypropylene", - "type": "Plastic" - }, - "percentage": 14.0, - "mass": 0.43, - "unit": "kg" - } - ], - "components": [ - { - "id": 3021, - "name": "Coffee Maker Component 1", - "description": "High-quality part for coffee maker functionality" - }, - { - "id": 3022, - "name": "Coffee Maker Component 2", - "description": "High-quality part for coffee maker functionality" - } - ], - "images": [ - { - "id": 302, - "url": "https://via.placeholder.com/400x300/01c354/ffffff?text=ChefMate+Coffee+Maker+427Z", - "description": "Coffee Maker product image" - } - ], - "created_at": "2024-10-29T09:16:11.467455Z", - "updated_at": "2025-06-09T09:16:11.467455Z" - }, - { - "id": 303, - "name": "CleanWave Rice Cooker 554H", - "description": "CleanWave Rice Cooker 554H is a high-performance rice cooker designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 5, - "name": "Office Equipment" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 4.0, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 33.2, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 19.0, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 1741, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 8.8, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 9.0, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 8.8, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 5, - "name": "Borosilicate Glass", - "type": "Glass" - }, - "percentage": 66.7, - "mass": 0.79, - "unit": "kg" - }, - { - "material": { - "id": 2, - "name": "ABS Plastic", - "type": "Plastic" - }, - "percentage": 33.3, - "mass": 0.99, - "unit": "kg" - } - ], - "components": [ - { - "id": 3031, - "name": "Rice Cooker Component 1", - "description": "High-quality part for rice cooker functionality" - }, - { - "id": 3032, - "name": "Rice Cooker Component 2", - "description": "High-quality part for rice cooker functionality" - }, - { - "id": 3033, - "name": "Rice Cooker Component 3", - "description": "High-quality part for rice cooker functionality" - }, - { - "id": 3034, - "name": "Rice Cooker Component 4", - "description": "High-quality part for rice cooker functionality" - } - ], - "images": [ - { - "id": 303, - "url": "https://via.placeholder.com/400x300/0258f8/ffffff?text=CleanWave+Rice+Cooker+554H", - "description": "Rice Cooker product image" - } - ], - "created_at": "2025-04-17T09:16:11.467490Z", - "updated_at": "2025-06-12T09:16:11.467490Z" - }, - { - "id": 304, - "name": "PureLife Monitor 896D", - "description": "PureLife Monitor 896D is a high-performance monitor designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 2, - "name": "Home Electronics" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 2.66, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 33.8, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 25.7, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 1539, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 7.2, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 7.7, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 7.0, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 7, - "name": "Silicone", - "type": "Elastomer" - }, - "percentage": 65.6, - "mass": 2.59, - "unit": "kg" - }, - { - "material": { - "id": 2, - "name": "ABS Plastic", - "type": "Plastic" - }, - "percentage": 34.4, - "mass": 0.86, - "unit": "kg" - } - ], - "components": [ - { - "id": 3041, - "name": "Monitor Component 1", - "description": "High-quality part for monitor functionality" - }, - { - "id": 3042, - "name": "Monitor Component 2", - "description": "High-quality part for monitor functionality" - }, - { - "id": 3043, - "name": "Monitor Component 3", - "description": "High-quality part for monitor functionality" - }, - { - "id": 3044, - "name": "Monitor Component 4", - "description": "High-quality part for monitor functionality" - }, - { - "id": 3045, - "name": "Monitor Component 5", - "description": "High-quality part for monitor functionality" - } - ], - "images": [ - { - "id": 304, - "url": "https://via.placeholder.com/400x300/0d9540/ffffff?text=PureLife+Monitor+896D", - "description": "Monitor product image" - } - ], - "created_at": "2024-08-17T09:16:11.467526Z", - "updated_at": "2025-06-22T09:16:11.467526Z" - }, - { - "id": 305, - "name": "ChefMate Humidifier 361F", - "description": "ChefMate Humidifier 361F is a high-performance humidifier designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 5, - "name": "Office Equipment" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 3.48, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 25.3, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 20.5, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 1646, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 9.5, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 8.8, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 7.3, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 7, - "name": "Silicone", - "type": "Elastomer" - }, - "percentage": 15.8, - "mass": 0.41, - "unit": "kg" - }, - { - "material": { - "id": 5, - "name": "Borosilicate Glass", - "type": "Glass" - }, - "percentage": 52.6, - "mass": 0.87, - "unit": "kg" - }, - { - "material": { - "id": 4, - "name": "Mica", - "type": "Mineral" - }, - "percentage": 31.6, - "mass": 1.04, - "unit": "kg" - } - ], - "components": [ - { - "id": 3051, - "name": "Humidifier Component 1", - "description": "High-quality part for humidifier functionality" - }, - { - "id": 3052, - "name": "Humidifier Component 2", - "description": "High-quality part for humidifier functionality" - }, - { - "id": 3053, - "name": "Humidifier Component 3", - "description": "High-quality part for humidifier functionality" - }, - { - "id": 3054, - "name": "Humidifier Component 4", - "description": "High-quality part for humidifier functionality" - } - ], - "images": [ - { - "id": 305, - "url": "https://via.placeholder.com/400x300/0df883/ffffff?text=ChefMate+Humidifier+361F", - "description": "Humidifier product image" - } - ], - "created_at": "2024-09-09T09:16:11.467566Z", - "updated_at": "2025-05-13T09:16:11.467566Z" - }, - { - "id": 306, - "name": "ZenGear Air Purifier 689E", - "description": "ZenGear Air Purifier 689E is a high-performance air purifier designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 5, - "name": "Office Equipment" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 2.31, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 34.9, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 24.2, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 1283, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 8.9, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 6.2, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 7.0, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 3, - "name": "Copper Wire", - "type": "Metal" - }, - "percentage": 12.6, - "mass": 0.4, - "unit": "kg" - }, - { - "material": { - "id": 7, - "name": "Silicone", - "type": "Elastomer" - }, - "percentage": 52.9, - "mass": 0.91, - "unit": "kg" - }, - { - "material": { - "id": 1, - "name": "Stainless Steel", - "type": "Metal" - }, - "percentage": 34.5, - "mass": 1.09, - "unit": "kg" - } - ], - "components": [ - { - "id": 3061, - "name": "Air Purifier Component 1", - "description": "High-quality part for air purifier functionality" - }, - { - "id": 3062, - "name": "Air Purifier Component 2", - "description": "High-quality part for air purifier functionality" - } - ], - "images": [ - { - "id": 306, - "url": "https://via.placeholder.com/400x300/0ace8f/ffffff?text=ZenGear+Air+Purifier+689E", - "description": "Air Purifier product image" - } - ], - "created_at": "2024-10-12T09:16:11.467594Z", - "updated_at": "2025-06-04T09:16:11.467594Z" - }, - { - "id": 307, - "name": "ZenGear Kettle 641K", - "description": "ZenGear Kettle 641K is a high-performance kettle designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 2, - "name": "Home Electronics" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 3.94, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 28.7, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 21.0, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 1182, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 6.8, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 8.5, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 8.8, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 2, - "name": "ABS Plastic", - "type": "Plastic" - }, - "percentage": 40.4, - "mass": 0.4, - "unit": "kg" - }, - { - "material": { - "id": 5, - "name": "Borosilicate Glass", - "type": "Glass" - }, - "percentage": 59.6, - "mass": 1.25, - "unit": "kg" - } - ], - "components": [ - { - "id": 3071, - "name": "Kettle Component 1", - "description": "High-quality part for kettle functionality" - }, - { - "id": 3072, - "name": "Kettle Component 2", - "description": "High-quality part for kettle functionality" - }, - { - "id": 3073, - "name": "Kettle Component 3", - "description": "High-quality part for kettle functionality" - } - ], - "images": [ - { - "id": 307, - "url": "https://via.placeholder.com/400x300/0a6acf/ffffff?text=ZenGear+Kettle+641K", - "description": "Kettle product image" - } - ], - "created_at": "2025-01-07T09:16:11.467646Z", - "updated_at": "2025-05-29T09:16:11.467646Z" - }, - { - "id": 308, - "name": "SmartHome Fan 241E", - "description": "SmartHome Fan 241E is a high-performance fan designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 3, - "name": "Personal Care Device" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 2.27, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 28.8, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 26.7, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 2101, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 6.1, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 6.2, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 7.1, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 4, - "name": "Mica", - "type": "Mineral" - }, - "percentage": 82.1, - "mass": 1.56, - "unit": "kg" - }, - { - "material": { - "id": 3, - "name": "Copper Wire", - "type": "Metal" - }, - "percentage": 17.9, - "mass": 0.35, - "unit": "kg" - } - ], - "components": [ - { - "id": 3081, - "name": "Fan Component 1", - "description": "High-quality part for fan functionality" - }, - { - "id": 3082, - "name": "Fan Component 2", - "description": "High-quality part for fan functionality" - }, - { - "id": 3083, - "name": "Fan Component 3", - "description": "High-quality part for fan functionality" - }, - { - "id": 3084, - "name": "Fan Component 4", - "description": "High-quality part for fan functionality" - } - ], - "images": [ - { - "id": 308, - "url": "https://via.placeholder.com/400x300/044a03/ffffff?text=SmartHome+Fan+241E", - "description": "Fan product image" - } - ], - "created_at": "2025-04-22T09:16:11.467680Z", - "updated_at": "2025-05-15T09:16:11.467680Z" - }, - { - "id": 309, - "name": "EcoTech Humidifier 836F", - "description": "EcoTech Humidifier 836F is a high-performance humidifier designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 5, - "name": "Office Equipment" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 3.62, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 33.1, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 22.6, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 1662, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 6.8, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 7.4, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 9.0, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 7, - "name": "Silicone", - "type": "Elastomer" - }, - "percentage": 15.4, - "mass": 0.41, - "unit": "kg" - }, - { - "material": { - "id": 1, - "name": "Stainless Steel", - "type": "Metal" - }, - "percentage": 57.1, - "mass": 1.72, - "unit": "kg" - }, - { - "material": { - "id": 2, - "name": "ABS Plastic", - "type": "Plastic" - }, - "percentage": 27.5, - "mass": 0.62, - "unit": "kg" - } - ], - "components": [ - { - "id": 3091, - "name": "Humidifier Component 1", - "description": "High-quality part for humidifier functionality" - }, - { - "id": 3092, - "name": "Humidifier Component 2", - "description": "High-quality part for humidifier functionality" - }, - { - "id": 3093, - "name": "Humidifier Component 3", - "description": "High-quality part for humidifier functionality" - } - ], - "images": [ - { - "id": 309, - "url": "https://via.placeholder.com/400x300/035fdb/ffffff?text=EcoTech+Humidifier+836F", - "description": "Humidifier product image" - } - ], - "created_at": "2024-11-18T09:16:11.467739Z", - "updated_at": "2025-06-03T09:16:11.467739Z" - }, - { - "id": 310, - "name": "NeoCook Toaster 361H", - "description": "NeoCook Toaster 361H is a high-performance toaster designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 5, - "name": "Office Equipment" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 1.34, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 26.2, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 23.1, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 1621, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 9.0, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 6.6, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 9.2, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 6, - "name": "Polypropylene", - "type": "Plastic" - }, - "percentage": 34.9, - "mass": 1.31, - "unit": "kg" - }, - { - "material": { - "id": 4, - "name": "Mica", - "type": "Mineral" - }, - "percentage": 11.6, - "mass": 0.26, - "unit": "kg" - }, - { - "material": { - "id": 7, - "name": "Silicone", - "type": "Elastomer" - }, - "percentage": 23.3, - "mass": 0.3, - "unit": "kg" - }, - { - "material": { - "id": 3, - "name": "Copper Wire", - "type": "Metal" - }, - "percentage": 30.2, - "mass": 0.77, - "unit": "kg" - } - ], - "components": [ - { - "id": 3101, - "name": "Toaster Component 1", - "description": "High-quality part for toaster functionality" - }, - { - "id": 3102, - "name": "Toaster Component 2", - "description": "High-quality part for toaster functionality" - }, - { - "id": 3103, - "name": "Toaster Component 3", - "description": "High-quality part for toaster functionality" - }, - { - "id": 3104, - "name": "Toaster Component 4", - "description": "High-quality part for toaster functionality" - } - ], - "images": [ - { - "id": 310, - "url": "https://via.placeholder.com/400x300/097dcc/ffffff?text=NeoCook+Toaster+361H", - "description": "Toaster product image" - } - ], - "created_at": "2024-09-18T09:16:11.467794Z", - "updated_at": "2025-07-13T09:16:11.467794Z" - }, - { - "id": 311, - "name": "EcoTech Rice Cooker 509M", - "description": "EcoTech Rice Cooker 509M is a high-performance rice cooker designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 5, - "name": "Office Equipment" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 1.11, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 29.7, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 17.7, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 2053, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 9.1, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 7.0, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 7.6, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 2, - "name": "ABS Plastic", - "type": "Plastic" - }, - "percentage": 39.5, - "mass": 1.49, - "unit": "kg" - }, - { - "material": { - "id": 7, - "name": "Silicone", - "type": "Elastomer" - }, - "percentage": 60.5, - "mass": 2.08, - "unit": "kg" - } - ], - "components": [ - { - "id": 3111, - "name": "Rice Cooker Component 1", - "description": "High-quality part for rice cooker functionality" - }, - { - "id": 3112, - "name": "Rice Cooker Component 2", - "description": "High-quality part for rice cooker functionality" - } - ], - "images": [ - { - "id": 311, - "url": "https://via.placeholder.com/400x300/0dddfe/ffffff?text=EcoTech+Rice+Cooker+509M", - "description": "Rice Cooker product image" - } - ], - "created_at": "2025-03-01T09:16:11.467839Z", - "updated_at": "2025-07-27T09:16:11.467839Z" - }, - { - "id": 312, - "name": "ZenGear Rice Cooker 661J", - "description": "ZenGear Rice Cooker 661J is a high-performance rice cooker designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 4, - "name": "Smart Home Device" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 3.28, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 25.4, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 24.6, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 802, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 9.4, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 7.6, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 6.8, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 1, - "name": "Stainless Steel", - "type": "Metal" - }, - "percentage": 21.1, - "mass": 0.62, - "unit": "kg" - }, - { - "material": { - "id": 3, - "name": "Copper Wire", - "type": "Metal" - }, - "percentage": 25.2, - "mass": 0.45, - "unit": "kg" - }, - { - "material": { - "id": 2, - "name": "ABS Plastic", - "type": "Plastic" - }, - "percentage": 25.2, - "mass": 0.84, - "unit": "kg" - }, - { - "material": { - "id": 4, - "name": "Mica", - "type": "Mineral" - }, - "percentage": 28.5, - "mass": 0.57, - "unit": "kg" - } - ], - "components": [ - { - "id": 3121, - "name": "Rice Cooker Component 1", - "description": "High-quality part for rice cooker functionality" - }, - { - "id": 3122, - "name": "Rice Cooker Component 2", - "description": "High-quality part for rice cooker functionality" - } - ], - "images": [ - { - "id": 312, - "url": "https://via.placeholder.com/400x300/0acc10/ffffff?text=ZenGear+Rice+Cooker+661J", - "description": "Rice Cooker product image" - } - ], - "created_at": "2024-11-11T09:16:11.467887Z", - "updated_at": "2025-07-20T09:16:11.467887Z" - }, - { - "id": 313, - "name": "CleanWave Fan 262Y", - "description": "CleanWave Fan 262Y is a high-performance fan designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 2, - "name": "Home Electronics" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 3.25, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 26.8, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 26.0, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 802, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 8.4, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 7.7, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 7.0, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 2, - "name": "ABS Plastic", - "type": "Plastic" - }, - "percentage": 28.3, - "mass": 0.37, - "unit": "kg" - }, - { - "material": { - "id": 1, - "name": "Stainless Steel", - "type": "Metal" - }, - "percentage": 32.6, - "mass": 0.71, - "unit": "kg" - }, - { - "material": { - "id": 3, - "name": "Copper Wire", - "type": "Metal" - }, - "percentage": 39.1, - "mass": 1.25, - "unit": "kg" - } - ], - "components": [ - { - "id": 3131, - "name": "Fan Component 1", - "description": "High-quality part for fan functionality" - }, - { - "id": 3132, - "name": "Fan Component 2", - "description": "High-quality part for fan functionality" - }, - { - "id": 3133, - "name": "Fan Component 3", - "description": "High-quality part for fan functionality" - }, - { - "id": 3134, - "name": "Fan Component 4", - "description": "High-quality part for fan functionality" - } - ], - "images": [ - { - "id": 313, - "url": "https://via.placeholder.com/400x300/08e7cd/ffffff?text=CleanWave+Fan+262Y", - "description": "Fan product image" - } - ], - "created_at": "2024-06-04T09:16:11.467924Z", - "updated_at": "2025-05-01T09:16:11.467924Z" - }, - { - "id": 314, - "name": "ZenGear Monitor 319J", - "description": "ZenGear Monitor 319J is a high-performance monitor designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 3, - "name": "Personal Care Device" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 3.14, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 30.4, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 16.9, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 1444, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 6.6, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 8.9, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 6.7, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 7, - "name": "Silicone", - "type": "Elastomer" - }, - "percentage": 50.0, - "mass": 1.06, - "unit": "kg" - }, - { - "material": { - "id": 1, - "name": "Stainless Steel", - "type": "Metal" - }, - "percentage": 50.0, - "mass": 1.83, - "unit": "kg" - } - ], - "components": [ - { - "id": 3141, - "name": "Monitor Component 1", - "description": "High-quality part for monitor functionality" - }, - { - "id": 3142, - "name": "Monitor Component 2", - "description": "High-quality part for monitor functionality" - }, - { - "id": 3143, - "name": "Monitor Component 3", - "description": "High-quality part for monitor functionality" - }, - { - "id": 3144, - "name": "Monitor Component 4", - "description": "High-quality part for monitor functionality" - }, - { - "id": 3145, - "name": "Monitor Component 5", - "description": "High-quality part for monitor functionality" - } - ], - "images": [ - { - "id": 314, - "url": "https://via.placeholder.com/400x300/053af8/ffffff?text=ZenGear+Monitor+319J", - "description": "Monitor product image" - } - ], - "created_at": "2025-01-25T09:16:11.467976Z", - "updated_at": "2025-06-08T09:16:11.467976Z" - }, - { - "id": 315, - "name": "PureLife Toaster 140K", - "description": "PureLife Toaster 140K is a high-performance toaster designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 3, - "name": "Personal Care Device" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 3.57, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 20.3, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 22.1, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 816, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 6.1, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 7.2, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 6.7, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 6, - "name": "Polypropylene", - "type": "Plastic" - }, - "percentage": 30.3, - "mass": 1.2, - "unit": "kg" - }, - { - "material": { - "id": 2, - "name": "ABS Plastic", - "type": "Plastic" - }, - "percentage": 51.5, - "mass": 1.44, - "unit": "kg" - }, - { - "material": { - "id": 3, - "name": "Copper Wire", - "type": "Metal" - }, - "percentage": 18.2, - "mass": 0.46, - "unit": "kg" - } - ], - "components": [ - { - "id": 3151, - "name": "Toaster Component 1", - "description": "High-quality part for toaster functionality" - }, - { - "id": 3152, - "name": "Toaster Component 2", - "description": "High-quality part for toaster functionality" - }, - { - "id": 3153, - "name": "Toaster Component 3", - "description": "High-quality part for toaster functionality" - }, - { - "id": 3154, - "name": "Toaster Component 4", - "description": "High-quality part for toaster functionality" - } - ], - "images": [ - { - "id": 315, - "url": "https://via.placeholder.com/400x300/0dc4e0/ffffff?text=PureLife+Toaster+140K", - "description": "Toaster product image" - } - ], - "created_at": "2024-10-24T09:16:11.468019Z", - "updated_at": "2025-06-30T09:16:11.468019Z" - }, - { - "id": 316, - "name": "CleanWave Fan 867B", - "description": "CleanWave Fan 867B is a high-performance fan designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 4, - "name": "Smart Home Device" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 1.73, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 25.1, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 15.6, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 2099, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 8.6, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 8.7, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 8.0, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 7, - "name": "Silicone", - "type": "Elastomer" - }, - "percentage": 51.0, - "mass": 1.63, - "unit": "kg" - }, - { - "material": { - "id": 3, - "name": "Copper Wire", - "type": "Metal" - }, - "percentage": 49.0, - "mass": 1.23, - "unit": "kg" - } - ], - "components": [ - { - "id": 3161, - "name": "Fan Component 1", - "description": "High-quality part for fan functionality" - }, - { - "id": 3162, - "name": "Fan Component 2", - "description": "High-quality part for fan functionality" - }, - { - "id": 3163, - "name": "Fan Component 3", - "description": "High-quality part for fan functionality" - }, - { - "id": 3164, - "name": "Fan Component 4", - "description": "High-quality part for fan functionality" - } - ], - "images": [ - { - "id": 316, - "url": "https://via.placeholder.com/400x300/0b33d5/ffffff?text=CleanWave+Fan+867B", - "description": "Fan product image" - } - ], - "created_at": "2024-08-31T09:16:11.468074Z", - "updated_at": "2025-05-09T09:16:11.468074Z" - }, - { - "id": 317, - "name": "AquaPro Rice Cooker 996T", - "description": "AquaPro Rice Cooker 996T is a high-performance rice cooker designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 1, - "name": "Kitchen Appliance" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 3.36, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 22.7, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 15.0, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 1717, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 6.7, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 7.0, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 6.8, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 3, - "name": "Copper Wire", - "type": "Metal" - }, - "percentage": 20.5, - "mass": 0.22, - "unit": "kg" - }, - { - "material": { - "id": 2, - "name": "ABS Plastic", - "type": "Plastic" - }, - "percentage": 21.9, - "mass": 0.42, - "unit": "kg" - }, - { - "material": { - "id": 6, - "name": "Polypropylene", - "type": "Plastic" - }, - "percentage": 57.5, - "mass": 0.89, - "unit": "kg" - } - ], - "components": [ - { - "id": 3171, - "name": "Rice Cooker Component 1", - "description": "High-quality part for rice cooker functionality" - }, - { - "id": 3172, - "name": "Rice Cooker Component 2", - "description": "High-quality part for rice cooker functionality" - }, - { - "id": 3173, - "name": "Rice Cooker Component 3", - "description": "High-quality part for rice cooker functionality" - }, - { - "id": 3174, - "name": "Rice Cooker Component 4", - "description": "High-quality part for rice cooker functionality" - }, - { - "id": 3175, - "name": "Rice Cooker Component 5", - "description": "High-quality part for rice cooker functionality" - } - ], - "images": [ - { - "id": 317, - "url": "https://via.placeholder.com/400x300/0b37e0/ffffff?text=AquaPro+Rice+Cooker+996T", - "description": "Rice Cooker product image" - } - ], - "created_at": "2024-12-25T09:16:11.468115Z", - "updated_at": "2025-06-01T09:16:11.468115Z" - }, - { - "id": 318, - "name": "ZenGear Iron 445Y", - "description": "ZenGear Iron 445Y is a high-performance iron designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 4, - "name": "Smart Home Device" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 3.57, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 34.7, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 24.3, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 925, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 8.0, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 7.0, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 6.6, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 1, - "name": "Stainless Steel", - "type": "Metal" - }, - "percentage": 16.9, - "mass": 0.28, - "unit": "kg" - }, - { - "material": { - "id": 2, - "name": "ABS Plastic", - "type": "Plastic" - }, - "percentage": 25.4, - "mass": 0.57, - "unit": "kg" - }, - { - "material": { - "id": 4, - "name": "Mica", - "type": "Mineral" - }, - "percentage": 17.8, - "mass": 0.59, - "unit": "kg" - }, - { - "material": { - "id": 6, - "name": "Polypropylene", - "type": "Plastic" - }, - "percentage": 39.8, - "mass": 0.91, - "unit": "kg" - } - ], - "components": [ - { - "id": 3181, - "name": "Iron Component 1", - "description": "High-quality part for iron functionality" - }, - { - "id": 3182, - "name": "Iron Component 2", - "description": "High-quality part for iron functionality" - }, - { - "id": 3183, - "name": "Iron Component 3", - "description": "High-quality part for iron functionality" - } - ], - "images": [ - { - "id": 318, - "url": "https://via.placeholder.com/400x300/042de4/ffffff?text=ZenGear+Iron+445Y", - "description": "Iron product image" - } - ], - "created_at": "2025-01-15T09:16:11.468166Z", - "updated_at": "2025-06-28T09:16:11.468166Z" - }, - { - "id": 319, - "name": "EcoTech Humidifier 976X", - "description": "EcoTech Humidifier 976X is a high-performance humidifier designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 3, - "name": "Personal Care Device" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 2.15, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 26.1, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 24.2, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 1850, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 8.1, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 5.5, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 6.4, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 4, - "name": "Mica", - "type": "Mineral" - }, - "percentage": 17.6, - "mass": 0.7, - "unit": "kg" - }, - { - "material": { - "id": 6, - "name": "Polypropylene", - "type": "Plastic" - }, - "percentage": 45.6, - "mass": 1.31, - "unit": "kg" - }, - { - "material": { - "id": 2, - "name": "ABS Plastic", - "type": "Plastic" - }, - "percentage": 36.8, - "mass": 0.87, - "unit": "kg" - } - ], - "components": [ - { - "id": 3191, - "name": "Humidifier Component 1", - "description": "High-quality part for humidifier functionality" - }, - { - "id": 3192, - "name": "Humidifier Component 2", - "description": "High-quality part for humidifier functionality" - }, - { - "id": 3193, - "name": "Humidifier Component 3", - "description": "High-quality part for humidifier functionality" - }, - { - "id": 3194, - "name": "Humidifier Component 4", - "description": "High-quality part for humidifier functionality" - } - ], - "images": [ - { - "id": 319, - "url": "https://via.placeholder.com/400x300/078ec7/ffffff?text=EcoTech+Humidifier+976X", - "description": "Humidifier product image" - } - ], - "created_at": "2024-11-28T09:16:11.468216Z", - "updated_at": "2025-07-17T09:16:11.468216Z" - }, - { - "id": 320, - "name": "NeoCook Rice Cooker 354J", - "description": "NeoCook Rice Cooker 354J is a high-performance rice cooker designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 3, - "name": "Personal Care Device" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 2.97, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 26.6, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 15.6, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 1112, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 7.5, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 7.3, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 8.2, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 1, - "name": "Stainless Steel", - "type": "Metal" - }, - "percentage": 24.0, - "mass": 0.36, - "unit": "kg" - }, - { - "material": { - "id": 4, - "name": "Mica", - "type": "Mineral" - }, - "percentage": 27.0, - "mass": 0.37, - "unit": "kg" - }, - { - "material": { - "id": 2, - "name": "ABS Plastic", - "type": "Plastic" - }, - "percentage": 27.0, - "mass": 0.86, - "unit": "kg" - }, - { - "material": { - "id": 5, - "name": "Borosilicate Glass", - "type": "Glass" - }, - "percentage": 22.0, - "mass": 0.79, - "unit": "kg" - } - ], - "components": [ - { - "id": 3201, - "name": "Rice Cooker Component 1", - "description": "High-quality part for rice cooker functionality" - }, - { - "id": 3202, - "name": "Rice Cooker Component 2", - "description": "High-quality part for rice cooker functionality" - }, - { - "id": 3203, - "name": "Rice Cooker Component 3", - "description": "High-quality part for rice cooker functionality" - } - ], - "images": [ - { - "id": 320, - "url": "https://via.placeholder.com/400x300/0a8999/ffffff?text=NeoCook+Rice+Cooker+354J", - "description": "Rice Cooker product image" - } - ], - "created_at": "2024-04-16T09:16:11.468269Z", - "updated_at": "2025-07-30T09:16:11.468269Z" - }, - { - "id": 321, - "name": "ZenGear Blender 330X", - "description": "ZenGear Blender 330X is a high-performance blender designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 3, - "name": "Personal Care Device" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 2.27, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 28.6, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 15.7, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 1383, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 9.4, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 7.3, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 6.3, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 3, - "name": "Copper Wire", - "type": "Metal" - }, - "percentage": 36.8, - "mass": 1.08, - "unit": "kg" - }, - { - "material": { - "id": 7, - "name": "Silicone", - "type": "Elastomer" - }, - "percentage": 34.7, - "mass": 0.92, - "unit": "kg" - }, - { - "material": { - "id": 1, - "name": "Stainless Steel", - "type": "Metal" - }, - "percentage": 28.5, - "mass": 0.36, - "unit": "kg" - } - ], - "components": [ - { - "id": 3211, - "name": "Blender Component 1", - "description": "High-quality part for blender functionality" - }, - { - "id": 3212, - "name": "Blender Component 2", - "description": "High-quality part for blender functionality" - } - ], - "images": [ - { - "id": 321, - "url": "https://via.placeholder.com/400x300/0269b9/ffffff?text=ZenGear+Blender+330X", - "description": "Blender product image" - } - ], - "created_at": "2025-04-20T09:16:11.468306Z", - "updated_at": "2025-05-31T09:16:11.468306Z" - }, - { - "id": 322, - "name": "ZenGear Toaster 810D", - "description": "ZenGear Toaster 810D is a high-performance toaster designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 4, - "name": "Smart Home Device" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 2.33, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 29.3, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 24.8, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 809, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 6.5, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 7.9, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 8.8, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 1, - "name": "Stainless Steel", - "type": "Metal" - }, - "percentage": 19.9, - "mass": 0.33, - "unit": "kg" - }, - { - "material": { - "id": 2, - "name": "ABS Plastic", - "type": "Plastic" - }, - "percentage": 28.3, - "mass": 0.98, - "unit": "kg" - }, - { - "material": { - "id": 6, - "name": "Polypropylene", - "type": "Plastic" - }, - "percentage": 26.7, - "mass": 0.8, - "unit": "kg" - }, - { - "material": { - "id": 4, - "name": "Mica", - "type": "Mineral" - }, - "percentage": 25.1, - "mass": 0.43, - "unit": "kg" - } - ], - "components": [ - { - "id": 3221, - "name": "Toaster Component 1", - "description": "High-quality part for toaster functionality" - }, - { - "id": 3222, - "name": "Toaster Component 2", - "description": "High-quality part for toaster functionality" - }, - { - "id": 3223, - "name": "Toaster Component 3", - "description": "High-quality part for toaster functionality" - }, - { - "id": 3224, - "name": "Toaster Component 4", - "description": "High-quality part for toaster functionality" - }, - { - "id": 3225, - "name": "Toaster Component 5", - "description": "High-quality part for toaster functionality" - } - ], - "images": [ - { - "id": 322, - "url": "https://via.placeholder.com/400x300/0588a4/ffffff?text=ZenGear+Toaster+810D", - "description": "Toaster product image" - } - ], - "created_at": "2024-11-23T09:16:11.468350Z", - "updated_at": "2025-06-10T09:16:11.468350Z" - }, - { - "id": 323, - "name": "ChefMate Toaster 771L", - "description": "ChefMate Toaster 771L is a high-performance toaster designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 1, - "name": "Kitchen Appliance" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 2.31, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 29.6, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 19.9, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 1775, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 8.1, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 8.0, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 7.3, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 3, - "name": "Copper Wire", - "type": "Metal" - }, - "percentage": 21.8, - "mass": 0.66, - "unit": "kg" - }, - { - "material": { - "id": 4, - "name": "Mica", - "type": "Mineral" - }, - "percentage": 29.1, - "mass": 1.12, - "unit": "kg" - }, - { - "material": { - "id": 5, - "name": "Borosilicate Glass", - "type": "Glass" - }, - "percentage": 28.5, - "mass": 0.97, - "unit": "kg" - }, - { - "material": { - "id": 6, - "name": "Polypropylene", - "type": "Plastic" - }, - "percentage": 20.6, - "mass": 0.52, - "unit": "kg" - } - ], - "components": [ - { - "id": 3231, - "name": "Toaster Component 1", - "description": "High-quality part for toaster functionality" - }, - { - "id": 3232, - "name": "Toaster Component 2", - "description": "High-quality part for toaster functionality" - } - ], - "images": [ - { - "id": 323, - "url": "https://via.placeholder.com/400x300/0a5a35/ffffff?text=ChefMate+Toaster+771L", - "description": "Toaster product image" - } - ], - "created_at": "2024-04-26T09:16:11.468385Z", - "updated_at": "2025-04-26T09:16:11.468385Z" - }, - { - "id": 324, - "name": "EcoTech Iron 631B", - "description": "EcoTech Iron 631B is a high-performance iron designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 4, - "name": "Smart Home Device" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 2.48, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 27.7, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 28.9, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 1057, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 7.7, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 6.6, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 9.0, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 7, - "name": "Silicone", - "type": "Elastomer" - }, - "percentage": 65.1, - "mass": 2.38, - "unit": "kg" - }, - { - "material": { - "id": 1, - "name": "Stainless Steel", - "type": "Metal" - }, - "percentage": 34.9, - "mass": 0.46, - "unit": "kg" - } - ], - "components": [ - { - "id": 3241, - "name": "Iron Component 1", - "description": "High-quality part for iron functionality" - }, - { - "id": 3242, - "name": "Iron Component 2", - "description": "High-quality part for iron functionality" - } - ], - "images": [ - { - "id": 324, - "url": "https://via.placeholder.com/400x300/024df6/ffffff?text=EcoTech+Iron+631B", - "description": "Iron product image" - } - ], - "created_at": "2024-07-03T09:16:11.468418Z", - "updated_at": "2025-06-16T09:16:11.468418Z" - }, - { - "id": 325, - "name": "CleanWave Iron 517C", - "description": "CleanWave Iron 517C is a high-performance iron designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 5, - "name": "Office Equipment" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 2.51, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 20.9, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 22.3, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 1697, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 8.2, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 8.2, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 9.2, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 5, - "name": "Borosilicate Glass", - "type": "Glass" - }, - "percentage": 64.3, - "mass": 0.86, - "unit": "kg" - }, - { - "material": { - "id": 2, - "name": "ABS Plastic", - "type": "Plastic" - }, - "percentage": 35.7, - "mass": 1.13, - "unit": "kg" - } - ], - "components": [ - { - "id": 3251, - "name": "Iron Component 1", - "description": "High-quality part for iron functionality" - }, - { - "id": 3252, - "name": "Iron Component 2", - "description": "High-quality part for iron functionality" - }, - { - "id": 3253, - "name": "Iron Component 3", - "description": "High-quality part for iron functionality" - } - ], - "images": [ - { - "id": 325, - "url": "https://via.placeholder.com/400x300/06e906/ffffff?text=CleanWave+Iron+517C", - "description": "Iron product image" - } - ], - "created_at": "2025-01-12T09:16:11.468465Z", - "updated_at": "2025-06-30T09:16:11.468465Z" - }, - { - "id": 326, - "name": "ChefMate Kettle 300J", - "description": "ChefMate Kettle 300J is a high-performance kettle designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 4, - "name": "Smart Home Device" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 3.36, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 21.1, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 30.0, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 822, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 7.1, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 5.3, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 9.6, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 6, - "name": "Polypropylene", - "type": "Plastic" - }, - "percentage": 76.9, - "mass": 2.51, - "unit": "kg" - }, - { - "material": { - "id": 3, - "name": "Copper Wire", - "type": "Metal" - }, - "percentage": 23.1, - "mass": 0.88, - "unit": "kg" - } - ], - "components": [ - { - "id": 3261, - "name": "Kettle Component 1", - "description": "High-quality part for kettle functionality" - }, - { - "id": 3262, - "name": "Kettle Component 2", - "description": "High-quality part for kettle functionality" - }, - { - "id": 3263, - "name": "Kettle Component 3", - "description": "High-quality part for kettle functionality" - }, - { - "id": 3264, - "name": "Kettle Component 4", - "description": "High-quality part for kettle functionality" - }, - { - "id": 3265, - "name": "Kettle Component 5", - "description": "High-quality part for kettle functionality" - } - ], - "images": [ - { - "id": 326, - "url": "https://via.placeholder.com/400x300/029df8/ffffff?text=ChefMate+Kettle+300J", - "description": "Kettle product image" - } - ], - "created_at": "2024-11-26T09:16:11.468516Z", - "updated_at": "2025-05-03T09:16:11.468516Z" - }, - { - "id": 327, - "name": "PureLife Rice Cooker 128T", - "description": "PureLife Rice Cooker 128T is a high-performance rice cooker designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 5, - "name": "Office Equipment" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 1.03, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 31.6, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 25.7, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 1137, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 7.0, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 7.2, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 7.4, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 2, - "name": "ABS Plastic", - "type": "Plastic" - }, - "percentage": 35.4, - "mass": 1.24, - "unit": "kg" - }, - { - "material": { - "id": 1, - "name": "Stainless Steel", - "type": "Metal" - }, - "percentage": 64.6, - "mass": 2.37, - "unit": "kg" - } - ], - "components": [ - { - "id": 3271, - "name": "Rice Cooker Component 1", - "description": "High-quality part for rice cooker functionality" - }, - { - "id": 3272, - "name": "Rice Cooker Component 2", - "description": "High-quality part for rice cooker functionality" - }, - { - "id": 3273, - "name": "Rice Cooker Component 3", - "description": "High-quality part for rice cooker functionality" - }, - { - "id": 3274, - "name": "Rice Cooker Component 4", - "description": "High-quality part for rice cooker functionality" - } - ], - "images": [ - { - "id": 327, - "url": "https://via.placeholder.com/400x300/0410ea/ffffff?text=PureLife+Rice+Cooker+128T", - "description": "Rice Cooker product image" - } - ], - "created_at": "2024-07-29T09:16:11.468557Z", - "updated_at": "2025-05-23T09:16:11.468557Z" - }, - { - "id": 328, - "name": "AquaPro Humidifier 967Z", - "description": "AquaPro Humidifier 967Z is a high-performance humidifier designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 3, - "name": "Personal Care Device" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 2.87, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 24.8, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 16.7, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 2188, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 7.6, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 8.7, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 9.8, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 7, - "name": "Silicone", - "type": "Elastomer" - }, - "percentage": 38.6, - "mass": 1.3, - "unit": "kg" - }, - { - "material": { - "id": 2, - "name": "ABS Plastic", - "type": "Plastic" - }, - "percentage": 45.5, - "mass": 1.74, - "unit": "kg" - }, - { - "material": { - "id": 6, - "name": "Polypropylene", - "type": "Plastic" - }, - "percentage": 15.9, - "mass": 0.61, - "unit": "kg" - } - ], - "components": [ - { - "id": 3281, - "name": "Humidifier Component 1", - "description": "High-quality part for humidifier functionality" - }, - { - "id": 3282, - "name": "Humidifier Component 2", - "description": "High-quality part for humidifier functionality" - } - ], - "images": [ - { - "id": 328, - "url": "https://via.placeholder.com/400x300/098807/ffffff?text=AquaPro+Humidifier+967Z", - "description": "Humidifier product image" - } - ], - "created_at": "2025-02-27T09:16:11.469090Z", - "updated_at": "2025-07-07T09:16:11.469090Z" - }, - { - "id": 329, - "name": "EcoTech Monitor 924D", - "description": "EcoTech Monitor 924D is a high-performance monitor designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 3, - "name": "Personal Care Device" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 1.96, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 21.9, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 23.3, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 1508, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 6.9, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 8.3, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 8.8, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 4, - "name": "Mica", - "type": "Mineral" - }, - "percentage": 51.3, - "mass": 0.92, - "unit": "kg" - }, - { - "material": { - "id": 3, - "name": "Copper Wire", - "type": "Metal" - }, - "percentage": 15.4, - "mass": 0.44, - "unit": "kg" - }, - { - "material": { - "id": 5, - "name": "Borosilicate Glass", - "type": "Glass" - }, - "percentage": 33.3, - "mass": 0.57, - "unit": "kg" - } - ], - "components": [ - { - "id": 3291, - "name": "Monitor Component 1", - "description": "High-quality part for monitor functionality" - }, - { - "id": 3292, - "name": "Monitor Component 2", - "description": "High-quality part for monitor functionality" - }, - { - "id": 3293, - "name": "Monitor Component 3", - "description": "High-quality part for monitor functionality" - } - ], - "images": [ - { - "id": 329, - "url": "https://via.placeholder.com/400x300/0721a4/ffffff?text=EcoTech+Monitor+924D", - "description": "Monitor product image" - } - ], - "created_at": "2025-03-20T09:16:11.469187Z", - "updated_at": "2025-06-09T09:16:11.469187Z" - }, - { - "id": 330, - "name": "NeoCook Humidifier 208N", - "description": "NeoCook Humidifier 208N is a high-performance humidifier designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 1, - "name": "Kitchen Appliance" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 3.16, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 20.8, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 17.9, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 845, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 8.4, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 9.0, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 8.4, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 3, - "name": "Copper Wire", - "type": "Metal" - }, - "percentage": 28.3, - "mass": 0.67, - "unit": "kg" - }, - { - "material": { - "id": 5, - "name": "Borosilicate Glass", - "type": "Glass" - }, - "percentage": 33.3, - "mass": 0.56, - "unit": "kg" - }, - { - "material": { - "id": 6, - "name": "Polypropylene", - "type": "Plastic" - }, - "percentage": 38.3, - "mass": 1.45, - "unit": "kg" - } - ], - "components": [ - { - "id": 3301, - "name": "Humidifier Component 1", - "description": "High-quality part for humidifier functionality" - }, - { - "id": 3302, - "name": "Humidifier Component 2", - "description": "High-quality part for humidifier functionality" - } - ], - "images": [ - { - "id": 330, - "url": "https://via.placeholder.com/400x300/089931/ffffff?text=NeoCook+Humidifier+208N", - "description": "Humidifier product image" - } - ], - "created_at": "2025-01-03T09:16:11.469239Z", - "updated_at": "2025-05-30T09:16:11.469239Z" - }, - { - "id": 331, - "name": "PureLife Humidifier 211K", - "description": "PureLife Humidifier 211K is a high-performance humidifier designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 3, - "name": "Personal Care Device" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 1.03, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 30.6, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 15.7, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 1525, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 8.0, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 5.9, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 9.5, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 6, - "name": "Polypropylene", - "type": "Plastic" - }, - "percentage": 19.6, - "mass": 0.62, - "unit": "kg" - }, - { - "material": { - "id": 2, - "name": "ABS Plastic", - "type": "Plastic" - }, - "percentage": 62.5, - "mass": 0.91, - "unit": "kg" - }, - { - "material": { - "id": 1, - "name": "Stainless Steel", - "type": "Metal" - }, - "percentage": 17.9, - "mass": 0.24, - "unit": "kg" - } - ], - "components": [ - { - "id": 3311, - "name": "Humidifier Component 1", - "description": "High-quality part for humidifier functionality" - }, - { - "id": 3312, - "name": "Humidifier Component 2", - "description": "High-quality part for humidifier functionality" - }, - { - "id": 3313, - "name": "Humidifier Component 3", - "description": "High-quality part for humidifier functionality" - } - ], - "images": [ - { - "id": 331, - "url": "https://via.placeholder.com/400x300/07c140/ffffff?text=PureLife+Humidifier+211K", - "description": "Humidifier product image" - } - ], - "created_at": "2025-01-08T09:16:11.469310Z", - "updated_at": "2025-07-10T09:16:11.469310Z" - }, - { - "id": 332, - "name": "CleanWave Iron 692Y", - "description": "CleanWave Iron 692Y is a high-performance iron designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 1, - "name": "Kitchen Appliance" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 2.2, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 20.2, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 23.5, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 1968, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 8.6, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 8.6, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 8.3, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 7, - "name": "Silicone", - "type": "Elastomer" - }, - "percentage": 47.5, - "mass": 0.86, - "unit": "kg" - }, - { - "material": { - "id": 5, - "name": "Borosilicate Glass", - "type": "Glass" - }, - "percentage": 31.3, - "mass": 0.77, - "unit": "kg" - }, - { - "material": { - "id": 4, - "name": "Mica", - "type": "Mineral" - }, - "percentage": 21.2, - "mass": 0.58, - "unit": "kg" - } - ], - "components": [ - { - "id": 3321, - "name": "Iron Component 1", - "description": "High-quality part for iron functionality" - }, - { - "id": 3322, - "name": "Iron Component 2", - "description": "High-quality part for iron functionality" - }, - { - "id": 3323, - "name": "Iron Component 3", - "description": "High-quality part for iron functionality" - }, - { - "id": 3324, - "name": "Iron Component 4", - "description": "High-quality part for iron functionality" - }, - { - "id": 3325, - "name": "Iron Component 5", - "description": "High-quality part for iron functionality" - } - ], - "images": [ - { - "id": 332, - "url": "https://via.placeholder.com/400x300/02bae0/ffffff?text=CleanWave+Iron+692Y", - "description": "Iron product image" - } - ], - "created_at": "2024-11-27T09:16:11.469375Z", - "updated_at": "2025-06-11T09:16:11.469375Z" - }, - { - "id": 333, - "name": "AquaPro Rice Cooker 980I", - "description": "AquaPro Rice Cooker 980I is a high-performance rice cooker designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 2, - "name": "Home Electronics" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 1.7, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 32.5, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 29.8, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 1593, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 7.3, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 5.2, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 8.4, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 2, - "name": "ABS Plastic", - "type": "Plastic" - }, - "percentage": 30.7, - "mass": 0.45, - "unit": "kg" - }, - { - "material": { - "id": 7, - "name": "Silicone", - "type": "Elastomer" - }, - "percentage": 27.1, - "mass": 0.56, - "unit": "kg" - }, - { - "material": { - "id": 4, - "name": "Mica", - "type": "Mineral" - }, - "percentage": 24.5, - "mass": 0.9, - "unit": "kg" - }, - { - "material": { - "id": 1, - "name": "Stainless Steel", - "type": "Metal" - }, - "percentage": 17.7, - "mass": 0.62, - "unit": "kg" - } - ], - "components": [ - { - "id": 3331, - "name": "Rice Cooker Component 1", - "description": "High-quality part for rice cooker functionality" - }, - { - "id": 3332, - "name": "Rice Cooker Component 2", - "description": "High-quality part for rice cooker functionality" - } - ], - "images": [ - { - "id": 333, - "url": "https://via.placeholder.com/400x300/05a542/ffffff?text=AquaPro+Rice+Cooker+980I", - "description": "Rice Cooker product image" - } - ], - "created_at": "2024-11-06T09:16:11.469437Z", - "updated_at": "2025-06-18T09:16:11.469437Z" - }, - { - "id": 334, - "name": "SmartHome Toaster 935W", - "description": "SmartHome Toaster 935W is a high-performance toaster designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 2, - "name": "Home Electronics" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 1.16, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 31.4, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 21.1, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 1198, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 6.7, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 8.0, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 8.6, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 5, - "name": "Borosilicate Glass", - "type": "Glass" - }, - "percentage": 72.1, - "mass": 0.88, - "unit": "kg" - }, - { - "material": { - "id": 6, - "name": "Polypropylene", - "type": "Plastic" - }, - "percentage": 27.9, - "mass": 0.51, - "unit": "kg" - } - ], - "components": [ - { - "id": 3341, - "name": "Toaster Component 1", - "description": "High-quality part for toaster functionality" - }, - { - "id": 3342, - "name": "Toaster Component 2", - "description": "High-quality part for toaster functionality" - }, - { - "id": 3343, - "name": "Toaster Component 3", - "description": "High-quality part for toaster functionality" - }, - { - "id": 3344, - "name": "Toaster Component 4", - "description": "High-quality part for toaster functionality" - }, - { - "id": 3345, - "name": "Toaster Component 5", - "description": "High-quality part for toaster functionality" - } - ], - "images": [ - { - "id": 334, - "url": "https://via.placeholder.com/400x300/03c9b8/ffffff?text=SmartHome+Toaster+935W", - "description": "Toaster product image" - } - ], - "created_at": "2025-03-31T09:16:11.469489Z", - "updated_at": "2025-07-21T09:16:11.469489Z" - }, - { - "id": 335, - "name": "NeoCook Kettle 572F", - "description": "NeoCook Kettle 572F is a high-performance kettle designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 3, - "name": "Personal Care Device" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 1.88, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 30.4, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 20.6, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 1811, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 8.4, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 8.2, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 8.3, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 7, - "name": "Silicone", - "type": "Elastomer" - }, - "percentage": 53.6, - "mass": 0.72, - "unit": "kg" - }, - { - "material": { - "id": 3, - "name": "Copper Wire", - "type": "Metal" - }, - "percentage": 46.4, - "mass": 1.7, - "unit": "kg" - } - ], - "components": [ - { - "id": 3351, - "name": "Kettle Component 1", - "description": "High-quality part for kettle functionality" - }, - { - "id": 3352, - "name": "Kettle Component 2", - "description": "High-quality part for kettle functionality" - }, - { - "id": 3353, - "name": "Kettle Component 3", - "description": "High-quality part for kettle functionality" - } - ], - "images": [ - { - "id": 335, - "url": "https://via.placeholder.com/400x300/0afd50/ffffff?text=NeoCook+Kettle+572F", - "description": "Kettle product image" - } - ], - "created_at": "2024-10-28T09:16:11.469630Z", - "updated_at": "2025-07-11T09:16:11.469630Z" - }, - { - "id": 336, - "name": "ZenGear Humidifier 669I", - "description": "ZenGear Humidifier 669I is a high-performance humidifier designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 5, - "name": "Office Equipment" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 2.34, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 34.3, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 22.2, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 1315, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 6.5, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 6.8, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 6.8, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 2, - "name": "ABS Plastic", - "type": "Plastic" - }, - "percentage": 52.6, - "mass": 0.81, - "unit": "kg" - }, - { - "material": { - "id": 6, - "name": "Polypropylene", - "type": "Plastic" - }, - "percentage": 47.4, - "mass": 0.97, - "unit": "kg" - } - ], - "components": [ - { - "id": 3361, - "name": "Humidifier Component 1", - "description": "High-quality part for humidifier functionality" - }, - { - "id": 3362, - "name": "Humidifier Component 2", - "description": "High-quality part for humidifier functionality" - }, - { - "id": 3363, - "name": "Humidifier Component 3", - "description": "High-quality part for humidifier functionality" - } - ], - "images": [ - { - "id": 336, - "url": "https://via.placeholder.com/400x300/056c2d/ffffff?text=ZenGear+Humidifier+669I", - "description": "Humidifier product image" - } - ], - "created_at": "2024-03-30T09:16:11.469682Z", - "updated_at": "2025-06-13T09:16:11.469682Z" - }, - { - "id": 337, - "name": "SmartHome Toaster 335A", - "description": "SmartHome Toaster 335A is a high-performance toaster designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 5, - "name": "Office Equipment" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 3.61, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 21.6, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 22.2, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 995, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 8.2, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 6.2, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 7.7, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 6, - "name": "Polypropylene", - "type": "Plastic" - }, - "percentage": 60.0, - "mass": 1.05, - "unit": "kg" - }, - { - "material": { - "id": 3, - "name": "Copper Wire", - "type": "Metal" - }, - "percentage": 12.9, - "mass": 0.19, - "unit": "kg" - }, - { - "material": { - "id": 2, - "name": "ABS Plastic", - "type": "Plastic" - }, - "percentage": 27.1, - "mass": 0.78, - "unit": "kg" - } - ], - "components": [ - { - "id": 3371, - "name": "Toaster Component 1", - "description": "High-quality part for toaster functionality" - }, - { - "id": 3372, - "name": "Toaster Component 2", - "description": "High-quality part for toaster functionality" - }, - { - "id": 3373, - "name": "Toaster Component 3", - "description": "High-quality part for toaster functionality" - }, - { - "id": 3374, - "name": "Toaster Component 4", - "description": "High-quality part for toaster functionality" - } - ], - "images": [ - { - "id": 337, - "url": "https://via.placeholder.com/400x300/0a8fc6/ffffff?text=SmartHome+Toaster+335A", - "description": "Toaster product image" - } - ], - "created_at": "2024-09-03T09:16:11.469753Z", - "updated_at": "2025-07-02T09:16:11.469753Z" - }, - { - "id": 338, - "name": "NeoCook Iron 651R", - "description": "NeoCook Iron 651R is a high-performance iron designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 4, - "name": "Smart Home Device" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 2.93, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 27.4, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 17.2, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 1183, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 9.2, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 6.7, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 9.8, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 4, - "name": "Mica", - "type": "Mineral" - }, - "percentage": 50.6, - "mass": 0.75, - "unit": "kg" - }, - { - "material": { - "id": 6, - "name": "Polypropylene", - "type": "Plastic" - }, - "percentage": 19.8, - "mass": 0.21, - "unit": "kg" - }, - { - "material": { - "id": 7, - "name": "Silicone", - "type": "Elastomer" - }, - "percentage": 29.6, - "mass": 0.79, - "unit": "kg" - } - ], - "components": [ - { - "id": 3381, - "name": "Iron Component 1", - "description": "High-quality part for iron functionality" - }, - { - "id": 3382, - "name": "Iron Component 2", - "description": "High-quality part for iron functionality" - }, - { - "id": 3383, - "name": "Iron Component 3", - "description": "High-quality part for iron functionality" - } - ], - "images": [ - { - "id": 338, - "url": "https://via.placeholder.com/400x300/050ddd/ffffff?text=NeoCook+Iron+651R", - "description": "Iron product image" - } - ], - "created_at": "2025-04-12T09:16:11.469825Z", - "updated_at": "2025-05-11T09:16:11.469825Z" - }, - { - "id": 339, - "name": "ZenGear Humidifier 469E", - "description": "ZenGear Humidifier 469E is a high-performance humidifier designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 5, - "name": "Office Equipment" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 1.97, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 23.8, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 23.2, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 1106, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 6.6, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 5.8, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 9.8, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 1, - "name": "Stainless Steel", - "type": "Metal" - }, - "percentage": 40.9, - "mass": 0.79, - "unit": "kg" - }, - { - "material": { - "id": 5, - "name": "Borosilicate Glass", - "type": "Glass" - }, - "percentage": 59.1, - "mass": 2.05, - "unit": "kg" - } - ], - "components": [ - { - "id": 3391, - "name": "Humidifier Component 1", - "description": "High-quality part for humidifier functionality" - }, - { - "id": 3392, - "name": "Humidifier Component 2", - "description": "High-quality part for humidifier functionality" - }, - { - "id": 3393, - "name": "Humidifier Component 3", - "description": "High-quality part for humidifier functionality" - } - ], - "images": [ - { - "id": 339, - "url": "https://via.placeholder.com/400x300/079a20/ffffff?text=ZenGear+Humidifier+469E", - "description": "Humidifier product image" - } - ], - "created_at": "2024-04-27T09:16:11.469889Z", - "updated_at": "2025-06-16T09:16:11.469889Z" - }, - { - "id": 340, - "name": "ChefMate Blender 406Y", - "description": "ChefMate Blender 406Y is a high-performance blender designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 3, - "name": "Personal Care Device" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 1.22, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 34.6, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 20.3, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 2101, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 9.1, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 6.9, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 8.7, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 7, - "name": "Silicone", - "type": "Elastomer" - }, - "percentage": 21.3, - "mass": 0.84, - "unit": "kg" - }, - { - "material": { - "id": 3, - "name": "Copper Wire", - "type": "Metal" - }, - "percentage": 78.7, - "mass": 2.06, - "unit": "kg" - } - ], - "components": [ - { - "id": 3401, - "name": "Blender Component 1", - "description": "High-quality part for blender functionality" - }, - { - "id": 3402, - "name": "Blender Component 2", - "description": "High-quality part for blender functionality" - } - ], - "images": [ - { - "id": 340, - "url": "https://via.placeholder.com/400x300/08513b/ffffff?text=ChefMate+Blender+406Y", - "description": "Blender product image" - } - ], - "created_at": "2024-10-28T09:16:11.469934Z", - "updated_at": "2025-06-25T09:16:11.469934Z" - }, - { - "id": 341, - "name": "SmartHome Iron 936J", - "description": "SmartHome Iron 936J is a high-performance iron designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 5, - "name": "Office Equipment" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 2.04, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 34.9, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 20.3, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 895, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 8.4, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 6.9, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 10.0, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 7, - "name": "Silicone", - "type": "Elastomer" - }, - "percentage": 37.1, - "mass": 1.16, - "unit": "kg" - }, - { - "material": { - "id": 4, - "name": "Mica", - "type": "Mineral" - }, - "percentage": 14.3, - "mass": 0.33, - "unit": "kg" - }, - { - "material": { - "id": 6, - "name": "Polypropylene", - "type": "Plastic" - }, - "percentage": 37.1, - "mass": 0.99, - "unit": "kg" - }, - { - "material": { - "id": 2, - "name": "ABS Plastic", - "type": "Plastic" - }, - "percentage": 11.4, - "mass": 0.31, - "unit": "kg" - } - ], - "components": [ - { - "id": 3411, - "name": "Iron Component 1", - "description": "High-quality part for iron functionality" - }, - { - "id": 3412, - "name": "Iron Component 2", - "description": "High-quality part for iron functionality" - }, - { - "id": 3413, - "name": "Iron Component 3", - "description": "High-quality part for iron functionality" - }, - { - "id": 3414, - "name": "Iron Component 4", - "description": "High-quality part for iron functionality" - } - ], - "images": [ - { - "id": 341, - "url": "https://via.placeholder.com/400x300/07dffb/ffffff?text=SmartHome+Iron+936J", - "description": "Iron product image" - } - ], - "created_at": "2024-05-08T09:16:11.469997Z", - "updated_at": "2025-07-20T09:16:11.469997Z" - }, - { - "id": 342, - "name": "ChefMate Coffee Maker 531I", - "description": "ChefMate Coffee Maker 531I is a high-performance coffee maker designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 2, - "name": "Home Electronics" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 1.39, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 23.6, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 20.9, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 1245, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 8.2, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 6.2, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 8.1, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 2, - "name": "ABS Plastic", - "type": "Plastic" - }, - "percentage": 49.1, - "mass": 1.49, - "unit": "kg" - }, - { - "material": { - "id": 1, - "name": "Stainless Steel", - "type": "Metal" - }, - "percentage": 50.9, - "mass": 1.48, - "unit": "kg" - } - ], - "components": [ - { - "id": 3421, - "name": "Coffee Maker Component 1", - "description": "High-quality part for coffee maker functionality" - }, - { - "id": 3422, - "name": "Coffee Maker Component 2", - "description": "High-quality part for coffee maker functionality" - }, - { - "id": 3423, - "name": "Coffee Maker Component 3", - "description": "High-quality part for coffee maker functionality" - } - ], - "images": [ - { - "id": 342, - "url": "https://via.placeholder.com/400x300/04f9ff/ffffff?text=ChefMate+Coffee+Maker+531I", - "description": "Coffee Maker product image" - } - ], - "created_at": "2024-07-21T09:16:11.470050Z", - "updated_at": "2025-05-17T09:16:11.470050Z" - }, - { - "id": 343, - "name": "AquaPro Rice Cooker 663X", - "description": "AquaPro Rice Cooker 663X is a high-performance rice cooker designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 3, - "name": "Personal Care Device" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 3.33, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 20.4, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 21.5, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 941, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 6.8, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 5.7, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 7.3, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 5, - "name": "Borosilicate Glass", - "type": "Glass" - }, - "percentage": 28.1, - "mass": 0.48, - "unit": "kg" - }, - { - "material": { - "id": 7, - "name": "Silicone", - "type": "Elastomer" - }, - "percentage": 8.6, - "mass": 0.29, - "unit": "kg" - }, - { - "material": { - "id": 1, - "name": "Stainless Steel", - "type": "Metal" - }, - "percentage": 20.1, - "mass": 0.5, - "unit": "kg" - }, - { - "material": { - "id": 2, - "name": "ABS Plastic", - "type": "Plastic" - }, - "percentage": 43.2, - "mass": 1.44, - "unit": "kg" - } - ], - "components": [ - { - "id": 3431, - "name": "Rice Cooker Component 1", - "description": "High-quality part for rice cooker functionality" - }, - { - "id": 3432, - "name": "Rice Cooker Component 2", - "description": "High-quality part for rice cooker functionality" - }, - { - "id": 3433, - "name": "Rice Cooker Component 3", - "description": "High-quality part for rice cooker functionality" - }, - { - "id": 3434, - "name": "Rice Cooker Component 4", - "description": "High-quality part for rice cooker functionality" - }, - { - "id": 3435, - "name": "Rice Cooker Component 5", - "description": "High-quality part for rice cooker functionality" - } - ], - "images": [ - { - "id": 343, - "url": "https://via.placeholder.com/400x300/0d122c/ffffff?text=AquaPro+Rice+Cooker+663X", - "description": "Rice Cooker product image" - } - ], - "created_at": "2024-10-30T09:16:11.470170Z", - "updated_at": "2025-07-29T09:16:11.470170Z" - }, - { - "id": 344, - "name": "SmartHome Iron 640P", - "description": "SmartHome Iron 640P is a high-performance iron designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 5, - "name": "Office Equipment" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 1.27, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 28.6, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 26.7, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 1638, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 7.5, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 6.9, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 9.2, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 3, - "name": "Copper Wire", - "type": "Metal" - }, - "percentage": 30.1, - "mass": 0.83, - "unit": "kg" - }, - { - "material": { - "id": 4, - "name": "Mica", - "type": "Mineral" - }, - "percentage": 38.4, - "mass": 0.89, - "unit": "kg" - }, - { - "material": { - "id": 7, - "name": "Silicone", - "type": "Elastomer" - }, - "percentage": 31.5, - "mass": 0.65, - "unit": "kg" - } - ], - "components": [ - { - "id": 3441, - "name": "Iron Component 1", - "description": "High-quality part for iron functionality" - }, - { - "id": 3442, - "name": "Iron Component 2", - "description": "High-quality part for iron functionality" - } - ], - "images": [ - { - "id": 344, - "url": "https://via.placeholder.com/400x300/0a81f0/ffffff?text=SmartHome+Iron+640P", - "description": "Iron product image" - } - ], - "created_at": "2025-01-02T09:16:11.470225Z", - "updated_at": "2025-07-22T09:16:11.470225Z" - }, - { - "id": 345, - "name": "EcoTech Fan 472L", - "description": "EcoTech Fan 472L is a high-performance fan designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 5, - "name": "Office Equipment" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 2.23, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 29.5, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 29.4, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 1905, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 9.3, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 8.1, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 6.6, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 1, - "name": "Stainless Steel", - "type": "Metal" - }, - "percentage": 29.3, - "mass": 0.9, - "unit": "kg" - }, - { - "material": { - "id": 6, - "name": "Polypropylene", - "type": "Plastic" - }, - "percentage": 47.2, - "mass": 1.88, - "unit": "kg" - }, - { - "material": { - "id": 7, - "name": "Silicone", - "type": "Elastomer" - }, - "percentage": 23.6, - "mass": 0.48, - "unit": "kg" - } - ], - "components": [ - { - "id": 3451, - "name": "Fan Component 1", - "description": "High-quality part for fan functionality" - }, - { - "id": 3452, - "name": "Fan Component 2", - "description": "High-quality part for fan functionality" - }, - { - "id": 3453, - "name": "Fan Component 3", - "description": "High-quality part for fan functionality" - }, - { - "id": 3454, - "name": "Fan Component 4", - "description": "High-quality part for fan functionality" - }, - { - "id": 3455, - "name": "Fan Component 5", - "description": "High-quality part for fan functionality" - } - ], - "images": [ - { - "id": 345, - "url": "https://via.placeholder.com/400x300/05d410/ffffff?text=EcoTech+Fan+472L", - "description": "Fan product image" - } - ], - "created_at": "2025-03-19T09:16:11.470289Z", - "updated_at": "2025-07-27T09:16:11.470289Z" - }, - { - "id": 346, - "name": "CleanWave Coffee Maker 440K", - "description": "CleanWave Coffee Maker 440K is a high-performance coffee maker designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 2, - "name": "Home Electronics" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 3.77, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 20.0, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 24.8, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 2028, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 6.3, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 6.9, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 9.3, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 2, - "name": "ABS Plastic", - "type": "Plastic" - }, - "percentage": 34.0, - "mass": 1.19, - "unit": "kg" - }, - { - "material": { - "id": 6, - "name": "Polypropylene", - "type": "Plastic" - }, - "percentage": 9.6, - "mass": 0.12, - "unit": "kg" - }, - { - "material": { - "id": 1, - "name": "Stainless Steel", - "type": "Metal" - }, - "percentage": 19.9, - "mass": 0.79, - "unit": "kg" - }, - { - "material": { - "id": 7, - "name": "Silicone", - "type": "Elastomer" - }, - "percentage": 36.5, - "mass": 1.3, - "unit": "kg" - } - ], - "components": [ - { - "id": 3461, - "name": "Coffee Maker Component 1", - "description": "High-quality part for coffee maker functionality" - }, - { - "id": 3462, - "name": "Coffee Maker Component 2", - "description": "High-quality part for coffee maker functionality" - }, - { - "id": 3463, - "name": "Coffee Maker Component 3", - "description": "High-quality part for coffee maker functionality" - }, - { - "id": 3464, - "name": "Coffee Maker Component 4", - "description": "High-quality part for coffee maker functionality" - } - ], - "images": [ - { - "id": 346, - "url": "https://via.placeholder.com/400x300/08f70c/ffffff?text=CleanWave+Coffee+Maker+440K", - "description": "Coffee Maker product image" - } - ], - "created_at": "2024-08-03T09:16:11.470354Z", - "updated_at": "2025-07-03T09:16:11.470354Z" - }, - { - "id": 347, - "name": "SmartHome Blender 611E", - "description": "SmartHome Blender 611E is a high-performance blender designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 1, - "name": "Kitchen Appliance" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 1.73, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 20.0, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 26.1, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 1140, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 6.2, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 8.1, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 9.6, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 6, - "name": "Polypropylene", - "type": "Plastic" - }, - "percentage": 50.0, - "mass": 1.26, - "unit": "kg" - }, - { - "material": { - "id": 5, - "name": "Borosilicate Glass", - "type": "Glass" - }, - "percentage": 50.0, - "mass": 0.99, - "unit": "kg" - } - ], - "components": [ - { - "id": 3471, - "name": "Blender Component 1", - "description": "High-quality part for blender functionality" - }, - { - "id": 3472, - "name": "Blender Component 2", - "description": "High-quality part for blender functionality" - }, - { - "id": 3473, - "name": "Blender Component 3", - "description": "High-quality part for blender functionality" - }, - { - "id": 3474, - "name": "Blender Component 4", - "description": "High-quality part for blender functionality" - } - ], - "images": [ - { - "id": 347, - "url": "https://via.placeholder.com/400x300/02da67/ffffff?text=SmartHome+Blender+611E", - "description": "Blender product image" - } - ], - "created_at": "2025-02-28T09:16:11.470422Z", - "updated_at": "2025-04-26T09:16:11.470422Z" - }, - { - "id": 348, - "name": "SmartHome Monitor 422N", - "description": "SmartHome Monitor 422N is a high-performance monitor designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 3, - "name": "Personal Care Device" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 1.66, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 20.5, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 22.1, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 1839, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 6.3, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 8.4, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 8.1, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 2, - "name": "ABS Plastic", - "type": "Plastic" - }, - "percentage": 34.7, - "mass": 0.86, - "unit": "kg" - }, - { - "material": { - "id": 7, - "name": "Silicone", - "type": "Elastomer" - }, - "percentage": 14.7, - "mass": 0.39, - "unit": "kg" - }, - { - "material": { - "id": 3, - "name": "Copper Wire", - "type": "Metal" - }, - "percentage": 33.3, - "mass": 1.01, - "unit": "kg" - }, - { - "material": { - "id": 5, - "name": "Borosilicate Glass", - "type": "Glass" - }, - "percentage": 17.3, - "mass": 0.38, - "unit": "kg" - } - ], - "components": [ - { - "id": 3481, - "name": "Monitor Component 1", - "description": "High-quality part for monitor functionality" - }, - { - "id": 3482, - "name": "Monitor Component 2", - "description": "High-quality part for monitor functionality" - }, - { - "id": 3483, - "name": "Monitor Component 3", - "description": "High-quality part for monitor functionality" - }, - { - "id": 3484, - "name": "Monitor Component 4", - "description": "High-quality part for monitor functionality" - }, - { - "id": 3485, - "name": "Monitor Component 5", - "description": "High-quality part for monitor functionality" - } - ], - "images": [ - { - "id": 348, - "url": "https://via.placeholder.com/400x300/0ef575/ffffff?text=SmartHome+Monitor+422N", - "description": "Monitor product image" - } - ], - "created_at": "2025-04-14T09:16:11.470632Z", - "updated_at": "2025-05-28T09:16:11.470632Z" - }, - { - "id": 349, - "name": "AquaPro Coffee Maker 808N", - "description": "AquaPro Coffee Maker 808N is a high-performance coffee maker designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 2, - "name": "Home Electronics" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 3.43, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 27.2, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 16.8, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 1915, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 8.4, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 8.0, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 8.7, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 7, - "name": "Silicone", - "type": "Elastomer" - }, - "percentage": 37.3, - "mass": 1.32, - "unit": "kg" - }, - { - "material": { - "id": 3, - "name": "Copper Wire", - "type": "Metal" - }, - "percentage": 62.7, - "mass": 1.98, - "unit": "kg" - } - ], - "components": [ - { - "id": 3491, - "name": "Coffee Maker Component 1", - "description": "High-quality part for coffee maker functionality" - }, - { - "id": 3492, - "name": "Coffee Maker Component 2", - "description": "High-quality part for coffee maker functionality" - }, - { - "id": 3493, - "name": "Coffee Maker Component 3", - "description": "High-quality part for coffee maker functionality" - }, - { - "id": 3494, - "name": "Coffee Maker Component 4", - "description": "High-quality part for coffee maker functionality" - } - ], - "images": [ - { - "id": 349, - "url": "https://via.placeholder.com/400x300/0e9510/ffffff?text=AquaPro+Coffee+Maker+808N", - "description": "Coffee Maker product image" - } - ], - "created_at": "2024-07-22T09:16:11.470689Z", - "updated_at": "2025-06-18T09:16:11.470689Z" - }, - { - "id": 350, - "name": "PureLife Monitor 123W", - "description": "PureLife Monitor 123W is a high-performance monitor designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 5, - "name": "Office Equipment" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 3.78, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 34.9, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 19.9, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 1123, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 8.2, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 5.5, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 7.1, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 7, - "name": "Silicone", - "type": "Elastomer" - }, - "percentage": 23.2, - "mass": 0.38, - "unit": "kg" - }, - { - "material": { - "id": 5, - "name": "Borosilicate Glass", - "type": "Glass" - }, - "percentage": 34.8, - "mass": 1.28, - "unit": "kg" - }, - { - "material": { - "id": 4, - "name": "Mica", - "type": "Mineral" - }, - "percentage": 42.0, - "mass": 1.1, - "unit": "kg" - } - ], - "components": [ - { - "id": 3501, - "name": "Monitor Component 1", - "description": "High-quality part for monitor functionality" - }, - { - "id": 3502, - "name": "Monitor Component 2", - "description": "High-quality part for monitor functionality" - } - ], - "images": [ - { - "id": 350, - "url": "https://via.placeholder.com/400x300/0cb13a/ffffff?text=PureLife+Monitor+123W", - "description": "Monitor product image" - } - ], - "created_at": "2025-03-22T09:16:11.470746Z", - "updated_at": "2025-06-22T09:16:11.470746Z" - }, - { - "id": 351, - "name": "SmartHome Iron 238Z", - "description": "SmartHome Iron 238Z is a high-performance iron designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 4, - "name": "Smart Home Device" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 1.3, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 22.1, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 29.1, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 1109, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 6.5, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 6.7, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 9.0, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 6, - "name": "Polypropylene", - "type": "Plastic" - }, - "percentage": 32.2, - "mass": 0.57, - "unit": "kg" - }, - { - "material": { - "id": 7, - "name": "Silicone", - "type": "Elastomer" - }, - "percentage": 48.3, - "mass": 1.78, - "unit": "kg" - }, - { - "material": { - "id": 5, - "name": "Borosilicate Glass", - "type": "Glass" - }, - "percentage": 8.5, - "mass": 0.33, - "unit": "kg" - }, - { - "material": { - "id": 2, - "name": "ABS Plastic", - "type": "Plastic" - }, - "percentage": 11.0, - "mass": 0.29, - "unit": "kg" - } - ], - "components": [ - { - "id": 3511, - "name": "Iron Component 1", - "description": "High-quality part for iron functionality" - }, - { - "id": 3512, - "name": "Iron Component 2", - "description": "High-quality part for iron functionality" - }, - { - "id": 3513, - "name": "Iron Component 3", - "description": "High-quality part for iron functionality" - }, - { - "id": 3514, - "name": "Iron Component 4", - "description": "High-quality part for iron functionality" - } - ], - "images": [ - { - "id": 351, - "url": "https://via.placeholder.com/400x300/02560e/ffffff?text=SmartHome+Iron+238Z", - "description": "Iron product image" - } - ], - "created_at": "2024-11-15T09:16:11.470806Z", - "updated_at": "2025-06-15T09:16:11.470806Z" - }, - { - "id": 352, - "name": "ChefMate Fan 327O", - "description": "ChefMate Fan 327O is a high-performance fan designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 2, - "name": "Home Electronics" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 1.69, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 29.7, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 24.0, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 1372, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 8.3, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 8.1, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 6.6, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 5, - "name": "Borosilicate Glass", - "type": "Glass" - }, - "percentage": 17.0, - "mass": 0.61, - "unit": "kg" - }, - { - "material": { - "id": 4, - "name": "Mica", - "type": "Mineral" - }, - "percentage": 38.5, - "mass": 0.42, - "unit": "kg" - }, - { - "material": { - "id": 7, - "name": "Silicone", - "type": "Elastomer" - }, - "percentage": 44.4, - "mass": 0.59, - "unit": "kg" - } - ], - "components": [ - { - "id": 3521, - "name": "Fan Component 1", - "description": "High-quality part for fan functionality" - }, - { - "id": 3522, - "name": "Fan Component 2", - "description": "High-quality part for fan functionality" - }, - { - "id": 3523, - "name": "Fan Component 3", - "description": "High-quality part for fan functionality" - }, - { - "id": 3524, - "name": "Fan Component 4", - "description": "High-quality part for fan functionality" - }, - { - "id": 3525, - "name": "Fan Component 5", - "description": "High-quality part for fan functionality" - } - ], - "images": [ - { - "id": 352, - "url": "https://via.placeholder.com/400x300/05c0db/ffffff?text=ChefMate+Fan+327O", - "description": "Fan product image" - } - ], - "created_at": "2024-07-22T09:16:11.470863Z", - "updated_at": "2025-04-29T09:16:11.470863Z" - }, - { - "id": 353, - "name": "ChefMate Iron 598X", - "description": "ChefMate Iron 598X is a high-performance iron designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 5, - "name": "Office Equipment" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 1.19, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 26.2, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 28.6, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 1061, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 8.6, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 7.0, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 6.2, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 7, - "name": "Silicone", - "type": "Elastomer" - }, - "percentage": 25.3, - "mass": 0.83, - "unit": "kg" - }, - { - "material": { - "id": 2, - "name": "ABS Plastic", - "type": "Plastic" - }, - "percentage": 25.3, - "mass": 0.84, - "unit": "kg" - }, - { - "material": { - "id": 4, - "name": "Mica", - "type": "Mineral" - }, - "percentage": 22.3, - "mass": 0.73, - "unit": "kg" - }, - { - "material": { - "id": 5, - "name": "Borosilicate Glass", - "type": "Glass" - }, - "percentage": 27.1, - "mass": 1.01, - "unit": "kg" - } - ], - "components": [ - { - "id": 3531, - "name": "Iron Component 1", - "description": "High-quality part for iron functionality" - }, - { - "id": 3532, - "name": "Iron Component 2", - "description": "High-quality part for iron functionality" - }, - { - "id": 3533, - "name": "Iron Component 3", - "description": "High-quality part for iron functionality" - }, - { - "id": 3534, - "name": "Iron Component 4", - "description": "High-quality part for iron functionality" - }, - { - "id": 3535, - "name": "Iron Component 5", - "description": "High-quality part for iron functionality" - } - ], - "images": [ - { - "id": 353, - "url": "https://via.placeholder.com/400x300/0c2aa5/ffffff?text=ChefMate+Iron+598X", - "description": "Iron product image" - } - ], - "created_at": "2025-03-23T09:16:11.470937Z", - "updated_at": "2025-05-05T09:16:11.470937Z" - }, - { - "id": 354, - "name": "EcoTech Blender 942N", - "description": "EcoTech Blender 942N is a high-performance blender designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 5, - "name": "Office Equipment" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 3.47, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 26.4, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 29.5, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 1573, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 6.8, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 5.2, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 9.2, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 2, - "name": "ABS Plastic", - "type": "Plastic" - }, - "percentage": 19.3, - "mass": 0.51, - "unit": "kg" - }, - { - "material": { - "id": 6, - "name": "Polypropylene", - "type": "Plastic" - }, - "percentage": 51.1, - "mass": 2.0, - "unit": "kg" - }, - { - "material": { - "id": 3, - "name": "Copper Wire", - "type": "Metal" - }, - "percentage": 29.5, - "mass": 1.15, - "unit": "kg" - } - ], - "components": [ - { - "id": 3541, - "name": "Blender Component 1", - "description": "High-quality part for blender functionality" - }, - { - "id": 3542, - "name": "Blender Component 2", - "description": "High-quality part for blender functionality" - } - ], - "images": [ - { - "id": 354, - "url": "https://via.placeholder.com/400x300/08e40f/ffffff?text=EcoTech+Blender+942N", - "description": "Blender product image" - } - ], - "created_at": "2024-08-25T09:16:11.470986Z", - "updated_at": "2025-06-16T09:16:11.470986Z" - }, - { - "id": 355, - "name": "SmartHome Fan 524Y", - "description": "SmartHome Fan 524Y is a high-performance fan designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 2, - "name": "Home Electronics" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 2.76, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 26.5, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 24.6, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 1854, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 7.5, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 5.2, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 7.3, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 1, - "name": "Stainless Steel", - "type": "Metal" - }, - "percentage": 35.4, - "mass": 0.64, - "unit": "kg" - }, - { - "material": { - "id": 4, - "name": "Mica", - "type": "Mineral" - }, - "percentage": 34.8, - "mass": 1.11, - "unit": "kg" - }, - { - "material": { - "id": 2, - "name": "ABS Plastic", - "type": "Plastic" - }, - "percentage": 29.7, - "mass": 0.93, - "unit": "kg" - } - ], - "components": [ - { - "id": 3551, - "name": "Fan Component 1", - "description": "High-quality part for fan functionality" - }, - { - "id": 3552, - "name": "Fan Component 2", - "description": "High-quality part for fan functionality" - }, - { - "id": 3553, - "name": "Fan Component 3", - "description": "High-quality part for fan functionality" - } - ], - "images": [ - { - "id": 355, - "url": "https://via.placeholder.com/400x300/02a511/ffffff?text=SmartHome+Fan+524Y", - "description": "Fan product image" - } - ], - "created_at": "2025-02-24T09:16:11.471032Z", - "updated_at": "2025-06-02T09:16:11.471032Z" - }, - { - "id": 356, - "name": "CleanWave Humidifier 360F", - "description": "CleanWave Humidifier 360F is a high-performance humidifier designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 4, - "name": "Smart Home Device" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 3.08, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 22.3, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 20.0, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 1294, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 6.6, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 7.3, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 9.7, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 5, - "name": "Borosilicate Glass", - "type": "Glass" - }, - "percentage": 30.0, - "mass": 0.85, - "unit": "kg" - }, - { - "material": { - "id": 2, - "name": "ABS Plastic", - "type": "Plastic" - }, - "percentage": 41.4, - "mass": 0.54, - "unit": "kg" - }, - { - "material": { - "id": 4, - "name": "Mica", - "type": "Mineral" - }, - "percentage": 28.6, - "mass": 0.75, - "unit": "kg" - } - ], - "components": [ - { - "id": 3561, - "name": "Humidifier Component 1", - "description": "High-quality part for humidifier functionality" - }, - { - "id": 3562, - "name": "Humidifier Component 2", - "description": "High-quality part for humidifier functionality" - }, - { - "id": 3563, - "name": "Humidifier Component 3", - "description": "High-quality part for humidifier functionality" - }, - { - "id": 3564, - "name": "Humidifier Component 4", - "description": "High-quality part for humidifier functionality" - } - ], - "images": [ - { - "id": 356, - "url": "https://via.placeholder.com/400x300/03beb5/ffffff?text=CleanWave+Humidifier+360F", - "description": "Humidifier product image" - } - ], - "created_at": "2024-06-26T09:16:11.471106Z", - "updated_at": "2025-04-24T09:16:11.471106Z" - }, - { - "id": 357, - "name": "AquaPro Air Purifier 208Z", - "description": "AquaPro Air Purifier 208Z is a high-performance air purifier designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 4, - "name": "Smart Home Device" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 1.52, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 22.1, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 29.6, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 1745, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 8.6, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 5.0, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 8.5, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 6, - "name": "Polypropylene", - "type": "Plastic" - }, - "percentage": 24.8, - "mass": 0.27, - "unit": "kg" - }, - { - "material": { - "id": 4, - "name": "Mica", - "type": "Mineral" - }, - "percentage": 38.3, - "mass": 0.84, - "unit": "kg" - }, - { - "material": { - "id": 7, - "name": "Silicone", - "type": "Elastomer" - }, - "percentage": 36.9, - "mass": 0.9, - "unit": "kg" - } - ], - "components": [ - { - "id": 3571, - "name": "Air Purifier Component 1", - "description": "High-quality part for air purifier functionality" - }, - { - "id": 3572, - "name": "Air Purifier Component 2", - "description": "High-quality part for air purifier functionality" - }, - { - "id": 3573, - "name": "Air Purifier Component 3", - "description": "High-quality part for air purifier functionality" - }, - { - "id": 3574, - "name": "Air Purifier Component 4", - "description": "High-quality part for air purifier functionality" - }, - { - "id": 3575, - "name": "Air Purifier Component 5", - "description": "High-quality part for air purifier functionality" - } - ], - "images": [ - { - "id": 357, - "url": "https://via.placeholder.com/400x300/06862a/ffffff?text=AquaPro+Air+Purifier+208Z", - "description": "Air Purifier product image" - } - ], - "created_at": "2024-10-18T09:16:11.471158Z", - "updated_at": "2025-05-26T09:16:11.471158Z" - }, - { - "id": 358, - "name": "ZenGear Monitor 388P", - "description": "ZenGear Monitor 388P is a high-performance monitor designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 5, - "name": "Office Equipment" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 1.92, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 22.3, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 24.2, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 1352, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 6.4, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 5.7, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 7.5, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 5, - "name": "Borosilicate Glass", - "type": "Glass" - }, - "percentage": 43.2, - "mass": 0.49, - "unit": "kg" - }, - { - "material": { - "id": 6, - "name": "Polypropylene", - "type": "Plastic" - }, - "percentage": 56.8, - "mass": 1.15, - "unit": "kg" - } - ], - "components": [ - { - "id": 3581, - "name": "Monitor Component 1", - "description": "High-quality part for monitor functionality" - }, - { - "id": 3582, - "name": "Monitor Component 2", - "description": "High-quality part for monitor functionality" - }, - { - "id": 3583, - "name": "Monitor Component 3", - "description": "High-quality part for monitor functionality" - }, - { - "id": 3584, - "name": "Monitor Component 4", - "description": "High-quality part for monitor functionality" - }, - { - "id": 3585, - "name": "Monitor Component 5", - "description": "High-quality part for monitor functionality" - } - ], - "images": [ - { - "id": 358, - "url": "https://via.placeholder.com/400x300/0d6e75/ffffff?text=ZenGear+Monitor+388P", - "description": "Monitor product image" - } - ], - "created_at": "2024-09-01T09:16:11.471211Z", - "updated_at": "2025-04-24T09:16:11.471211Z" - }, - { - "id": 359, - "name": "NeoCook Monitor 255A", - "description": "NeoCook Monitor 255A is a high-performance monitor designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 2, - "name": "Home Electronics" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 2.84, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 22.8, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 27.9, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 1604, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 8.4, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 6.1, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 8.7, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 1, - "name": "Stainless Steel", - "type": "Metal" - }, - "percentage": 53.5, - "mass": 2.08, - "unit": "kg" - }, - { - "material": { - "id": 6, - "name": "Polypropylene", - "type": "Plastic" - }, - "percentage": 46.5, - "mass": 1.38, - "unit": "kg" - } - ], - "components": [ - { - "id": 3591, - "name": "Monitor Component 1", - "description": "High-quality part for monitor functionality" - }, - { - "id": 3592, - "name": "Monitor Component 2", - "description": "High-quality part for monitor functionality" - }, - { - "id": 3593, - "name": "Monitor Component 3", - "description": "High-quality part for monitor functionality" - } - ], - "images": [ - { - "id": 359, - "url": "https://via.placeholder.com/400x300/07c03d/ffffff?text=NeoCook+Monitor+255A", - "description": "Monitor product image" - } - ], - "created_at": "2024-12-14T09:16:11.471268Z", - "updated_at": "2025-07-09T09:16:11.471268Z" - }, - { - "id": 360, - "name": "CleanWave Humidifier 538D", - "description": "CleanWave Humidifier 538D is a high-performance humidifier designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 2, - "name": "Home Electronics" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 3.23, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 29.3, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 21.1, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 1871, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 8.8, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 5.7, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 7.8, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 2, - "name": "ABS Plastic", - "type": "Plastic" - }, - "percentage": 27.3, - "mass": 0.86, - "unit": "kg" - }, - { - "material": { - "id": 3, - "name": "Copper Wire", - "type": "Metal" - }, - "percentage": 6.7, - "mass": 0.17, - "unit": "kg" - }, - { - "material": { - "id": 7, - "name": "Silicone", - "type": "Elastomer" - }, - "percentage": 28.0, - "mass": 0.66, - "unit": "kg" - }, - { - "material": { - "id": 4, - "name": "Mica", - "type": "Mineral" - }, - "percentage": 38.0, - "mass": 1.19, - "unit": "kg" - } - ], - "components": [ - { - "id": 3601, - "name": "Humidifier Component 1", - "description": "High-quality part for humidifier functionality" - }, - { - "id": 3602, - "name": "Humidifier Component 2", - "description": "High-quality part for humidifier functionality" - } - ], - "images": [ - { - "id": 360, - "url": "https://via.placeholder.com/400x300/0e3101/ffffff?text=CleanWave+Humidifier+538D", - "description": "Humidifier product image" - } - ], - "created_at": "2024-11-25T09:16:11.471333Z", - "updated_at": "2025-04-29T09:16:11.471333Z" - }, - { - "id": 361, - "name": "PureLife Monitor 424K", - "description": "PureLife Monitor 424K is a high-performance monitor designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 4, - "name": "Smart Home Device" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 1.74, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 22.3, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 28.8, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 1874, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 6.9, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 5.1, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 7.6, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 5, - "name": "Borosilicate Glass", - "type": "Glass" - }, - "percentage": 52.7, - "mass": 1.52, - "unit": "kg" - }, - { - "material": { - "id": 3, - "name": "Copper Wire", - "type": "Metal" - }, - "percentage": 47.3, - "mass": 0.99, - "unit": "kg" - } - ], - "components": [ - { - "id": 3611, - "name": "Monitor Component 1", - "description": "High-quality part for monitor functionality" - }, - { - "id": 3612, - "name": "Monitor Component 2", - "description": "High-quality part for monitor functionality" - } - ], - "images": [ - { - "id": 361, - "url": "https://via.placeholder.com/400x300/09916e/ffffff?text=PureLife+Monitor+424K", - "description": "Monitor product image" - } - ], - "created_at": "2024-11-05T09:16:11.471377Z", - "updated_at": "2025-07-01T09:16:11.471377Z" - }, - { - "id": 362, - "name": "CleanWave Rice Cooker 678K", - "description": "CleanWave Rice Cooker 678K is a high-performance rice cooker designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 5, - "name": "Office Equipment" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 3.67, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 29.1, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 16.1, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 1960, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 7.1, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 7.2, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 7.8, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 6, - "name": "Polypropylene", - "type": "Plastic" - }, - "percentage": 54.3, - "mass": 1.96, - "unit": "kg" - }, - { - "material": { - "id": 4, - "name": "Mica", - "type": "Mineral" - }, - "percentage": 17.1, - "mass": 0.63, - "unit": "kg" - }, - { - "material": { - "id": 7, - "name": "Silicone", - "type": "Elastomer" - }, - "percentage": 28.6, - "mass": 1.07, - "unit": "kg" - } - ], - "components": [ - { - "id": 3621, - "name": "Rice Cooker Component 1", - "description": "High-quality part for rice cooker functionality" - }, - { - "id": 3622, - "name": "Rice Cooker Component 2", - "description": "High-quality part for rice cooker functionality" - }, - { - "id": 3623, - "name": "Rice Cooker Component 3", - "description": "High-quality part for rice cooker functionality" - }, - { - "id": 3624, - "name": "Rice Cooker Component 4", - "description": "High-quality part for rice cooker functionality" - }, - { - "id": 3625, - "name": "Rice Cooker Component 5", - "description": "High-quality part for rice cooker functionality" - } - ], - "images": [ - { - "id": 362, - "url": "https://via.placeholder.com/400x300/038519/ffffff?text=CleanWave+Rice+Cooker+678K", - "description": "Rice Cooker product image" - } - ], - "created_at": "2024-08-31T09:16:11.471443Z", - "updated_at": "2025-06-22T09:16:11.471443Z" - }, - { - "id": 363, - "name": "AquaPro Coffee Maker 546D", - "description": "AquaPro Coffee Maker 546D is a high-performance coffee maker designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 3, - "name": "Personal Care Device" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 3.91, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 21.0, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 25.2, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 1654, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 6.1, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 5.0, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 6.4, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 6, - "name": "Polypropylene", - "type": "Plastic" - }, - "percentage": 43.8, - "mass": 1.41, - "unit": "kg" - }, - { - "material": { - "id": 4, - "name": "Mica", - "type": "Mineral" - }, - "percentage": 9.1, - "mass": 0.35, - "unit": "kg" - }, - { - "material": { - "id": 7, - "name": "Silicone", - "type": "Elastomer" - }, - "percentage": 9.1, - "mass": 0.29, - "unit": "kg" - }, - { - "material": { - "id": 5, - "name": "Borosilicate Glass", - "type": "Glass" - }, - "percentage": 38.0, - "mass": 0.79, - "unit": "kg" - } - ], - "components": [ - { - "id": 3631, - "name": "Coffee Maker Component 1", - "description": "High-quality part for coffee maker functionality" - }, - { - "id": 3632, - "name": "Coffee Maker Component 2", - "description": "High-quality part for coffee maker functionality" - } - ], - "images": [ - { - "id": 363, - "url": "https://via.placeholder.com/400x300/066cc4/ffffff?text=AquaPro+Coffee+Maker+546D", - "description": "Coffee Maker product image" - } - ], - "created_at": "2024-05-23T09:16:11.471496Z", - "updated_at": "2025-06-15T09:16:11.471496Z" - }, - { - "id": 364, - "name": "AquaPro Blender 920U", - "description": "AquaPro Blender 920U is a high-performance blender designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 3, - "name": "Personal Care Device" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 1.71, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 34.6, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 16.4, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 2069, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 7.0, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 7.8, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 9.4, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 3, - "name": "Copper Wire", - "type": "Metal" - }, - "percentage": 26.5, - "mass": 0.86, - "unit": "kg" - }, - { - "material": { - "id": 1, - "name": "Stainless Steel", - "type": "Metal" - }, - "percentage": 27.2, - "mass": 0.95, - "unit": "kg" - }, - { - "material": { - "id": 7, - "name": "Silicone", - "type": "Elastomer" - }, - "percentage": 16.9, - "mass": 0.37, - "unit": "kg" - }, - { - "material": { - "id": 2, - "name": "ABS Plastic", - "type": "Plastic" - }, - "percentage": 29.4, - "mass": 0.57, - "unit": "kg" - } - ], - "components": [ - { - "id": 3641, - "name": "Blender Component 1", - "description": "High-quality part for blender functionality" - }, - { - "id": 3642, - "name": "Blender Component 2", - "description": "High-quality part for blender functionality" - } - ], - "images": [ - { - "id": 364, - "url": "https://via.placeholder.com/400x300/066b68/ffffff?text=AquaPro+Blender+920U", - "description": "Blender product image" - } - ], - "created_at": "2025-02-28T09:16:11.471553Z", - "updated_at": "2025-07-21T09:16:11.471553Z" - }, - { - "id": 365, - "name": "CleanWave Blender 815R", - "description": "CleanWave Blender 815R is a high-performance blender designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 1, - "name": "Kitchen Appliance" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 2.14, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 24.1, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 27.7, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 2136, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 8.0, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 7.8, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 7.8, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 4, - "name": "Mica", - "type": "Mineral" - }, - "percentage": 30.0, - "mass": 0.84, - "unit": "kg" - }, - { - "material": { - "id": 2, - "name": "ABS Plastic", - "type": "Plastic" - }, - "percentage": 27.8, - "mass": 0.31, - "unit": "kg" - }, - { - "material": { - "id": 3, - "name": "Copper Wire", - "type": "Metal" - }, - "percentage": 42.2, - "mass": 1.52, - "unit": "kg" - } - ], - "components": [ - { - "id": 3651, - "name": "Blender Component 1", - "description": "High-quality part for blender functionality" - }, - { - "id": 3652, - "name": "Blender Component 2", - "description": "High-quality part for blender functionality" - }, - { - "id": 3653, - "name": "Blender Component 3", - "description": "High-quality part for blender functionality" - }, - { - "id": 3654, - "name": "Blender Component 4", - "description": "High-quality part for blender functionality" - }, - { - "id": 3655, - "name": "Blender Component 5", - "description": "High-quality part for blender functionality" - } - ], - "images": [ - { - "id": 365, - "url": "https://via.placeholder.com/400x300/0c5cff/ffffff?text=CleanWave+Blender+815R", - "description": "Blender product image" - } - ], - "created_at": "2024-11-28T09:16:11.471615Z", - "updated_at": "2025-07-06T09:16:11.471615Z" - }, - { - "id": 366, - "name": "EcoTech Monitor 667L", - "description": "EcoTech Monitor 667L is a high-performance monitor designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 1, - "name": "Kitchen Appliance" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 2.99, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 24.7, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 24.1, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 2017, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 6.1, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 5.0, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 8.7, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 6, - "name": "Polypropylene", - "type": "Plastic" - }, - "percentage": 64.4, - "mass": 2.18, - "unit": "kg" - }, - { - "material": { - "id": 4, - "name": "Mica", - "type": "Mineral" - }, - "percentage": 35.6, - "mass": 0.46, - "unit": "kg" - } - ], - "components": [ - { - "id": 3661, - "name": "Monitor Component 1", - "description": "High-quality part for monitor functionality" - }, - { - "id": 3662, - "name": "Monitor Component 2", - "description": "High-quality part for monitor functionality" - }, - { - "id": 3663, - "name": "Monitor Component 3", - "description": "High-quality part for monitor functionality" - }, - { - "id": 3664, - "name": "Monitor Component 4", - "description": "High-quality part for monitor functionality" - }, - { - "id": 3665, - "name": "Monitor Component 5", - "description": "High-quality part for monitor functionality" - } - ], - "images": [ - { - "id": 366, - "url": "https://via.placeholder.com/400x300/06274f/ffffff?text=EcoTech+Monitor+667L", - "description": "Monitor product image" - } - ], - "created_at": "2024-08-03T09:16:11.471675Z", - "updated_at": "2025-05-25T09:16:11.471675Z" - }, - { - "id": 367, - "name": "ChefMate Monitor 439N", - "description": "ChefMate Monitor 439N is a high-performance monitor designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 2, - "name": "Home Electronics" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 3.54, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 25.0, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 22.6, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 1726, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 9.1, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 7.5, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 9.8, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 5, - "name": "Borosilicate Glass", - "type": "Glass" - }, - "percentage": 9.6, - "mass": 0.36, - "unit": "kg" - }, - { - "material": { - "id": 2, - "name": "ABS Plastic", - "type": "Plastic" - }, - "percentage": 17.3, - "mass": 0.46, - "unit": "kg" - }, - { - "material": { - "id": 1, - "name": "Stainless Steel", - "type": "Metal" - }, - "percentage": 53.8, - "mass": 1.05, - "unit": "kg" - }, - { - "material": { - "id": 4, - "name": "Mica", - "type": "Mineral" - }, - "percentage": 19.2, - "mass": 0.32, - "unit": "kg" - } - ], - "components": [ - { - "id": 3671, - "name": "Monitor Component 1", - "description": "High-quality part for monitor functionality" - }, - { - "id": 3672, - "name": "Monitor Component 2", - "description": "High-quality part for monitor functionality" - }, - { - "id": 3673, - "name": "Monitor Component 3", - "description": "High-quality part for monitor functionality" - }, - { - "id": 3674, - "name": "Monitor Component 4", - "description": "High-quality part for monitor functionality" - } - ], - "images": [ - { - "id": 367, - "url": "https://via.placeholder.com/400x300/099931/ffffff?text=ChefMate+Monitor+439N", - "description": "Monitor product image" - } - ], - "created_at": "2025-02-28T09:16:11.471733Z", - "updated_at": "2025-07-09T09:16:11.471733Z" - }, - { - "id": 368, - "name": "NeoCook Kettle 142Q", - "description": "NeoCook Kettle 142Q is a high-performance kettle designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 5, - "name": "Office Equipment" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 1.7, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 23.3, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 24.0, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 1096, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 7.9, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 5.7, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 8.6, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 2, - "name": "ABS Plastic", - "type": "Plastic" - }, - "percentage": 39.9, - "mass": 1.17, - "unit": "kg" - }, - { - "material": { - "id": 1, - "name": "Stainless Steel", - "type": "Metal" - }, - "percentage": 33.6, - "mass": 0.59, - "unit": "kg" - }, - { - "material": { - "id": 5, - "name": "Borosilicate Glass", - "type": "Glass" - }, - "percentage": 26.6, - "mass": 0.47, - "unit": "kg" - } - ], - "components": [ - { - "id": 3681, - "name": "Kettle Component 1", - "description": "High-quality part for kettle functionality" - }, - { - "id": 3682, - "name": "Kettle Component 2", - "description": "High-quality part for kettle functionality" - }, - { - "id": 3683, - "name": "Kettle Component 3", - "description": "High-quality part for kettle functionality" - }, - { - "id": 3684, - "name": "Kettle Component 4", - "description": "High-quality part for kettle functionality" - } - ], - "images": [ - { - "id": 368, - "url": "https://via.placeholder.com/400x300/0c4a10/ffffff?text=NeoCook+Kettle+142Q", - "description": "Kettle product image" - } - ], - "created_at": "2024-06-01T09:16:11.471797Z", - "updated_at": "2025-06-07T09:16:11.471797Z" - }, - { - "id": 369, - "name": "NeoCook Coffee Maker 650W", - "description": "NeoCook Coffee Maker 650W is a high-performance coffee maker designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 1, - "name": "Kitchen Appliance" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 3.74, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 33.4, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 16.5, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 2057, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 9.1, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 8.4, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 6.5, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 3, - "name": "Copper Wire", - "type": "Metal" - }, - "percentage": 20.6, - "mass": 0.28, - "unit": "kg" - }, - { - "material": { - "id": 7, - "name": "Silicone", - "type": "Elastomer" - }, - "percentage": 39.7, - "mass": 1.33, - "unit": "kg" - }, - { - "material": { - "id": 4, - "name": "Mica", - "type": "Mineral" - }, - "percentage": 39.7, - "mass": 0.69, - "unit": "kg" - } - ], - "components": [ - { - "id": 3691, - "name": "Coffee Maker Component 1", - "description": "High-quality part for coffee maker functionality" - }, - { - "id": 3692, - "name": "Coffee Maker Component 2", - "description": "High-quality part for coffee maker functionality" - } - ], - "images": [ - { - "id": 369, - "url": "https://via.placeholder.com/400x300/0f0d19/ffffff?text=NeoCook+Coffee+Maker+650W", - "description": "Coffee Maker product image" - } - ], - "created_at": "2024-07-02T09:16:11.471846Z", - "updated_at": "2025-05-22T09:16:11.471846Z" - }, - { - "id": 370, - "name": "SmartHome Air Purifier 272A", - "description": "SmartHome Air Purifier 272A is a high-performance air purifier designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 3, - "name": "Personal Care Device" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 3.79, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 34.3, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 17.4, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 1877, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 6.1, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 7.8, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 6.1, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 1, - "name": "Stainless Steel", - "type": "Metal" - }, - "percentage": 35.7, - "mass": 0.48, - "unit": "kg" - }, - { - "material": { - "id": 2, - "name": "ABS Plastic", - "type": "Plastic" - }, - "percentage": 39.7, - "mass": 1.05, - "unit": "kg" - }, - { - "material": { - "id": 7, - "name": "Silicone", - "type": "Elastomer" - }, - "percentage": 9.5, - "mass": 0.27, - "unit": "kg" - }, - { - "material": { - "id": 4, - "name": "Mica", - "type": "Mineral" - }, - "percentage": 15.1, - "mass": 0.55, - "unit": "kg" - } - ], - "components": [ - { - "id": 3701, - "name": "Air Purifier Component 1", - "description": "High-quality part for air purifier functionality" - }, - { - "id": 3702, - "name": "Air Purifier Component 2", - "description": "High-quality part for air purifier functionality" - }, - { - "id": 3703, - "name": "Air Purifier Component 3", - "description": "High-quality part for air purifier functionality" - }, - { - "id": 3704, - "name": "Air Purifier Component 4", - "description": "High-quality part for air purifier functionality" - } - ], - "images": [ - { - "id": 370, - "url": "https://via.placeholder.com/400x300/071d71/ffffff?text=SmartHome+Air+Purifier+272A", - "description": "Air Purifier product image" - } - ], - "created_at": "2024-10-06T09:16:11.471966Z", - "updated_at": "2025-05-21T09:16:11.471966Z" - }, - { - "id": 371, - "name": "ChefMate Fan 167R", - "description": "ChefMate Fan 167R is a high-performance fan designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 5, - "name": "Office Equipment" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 1.21, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 30.2, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 23.5, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 2157, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 8.1, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 8.4, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 8.3, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 3, - "name": "Copper Wire", - "type": "Metal" - }, - "percentage": 8.5, - "mass": 0.23, - "unit": "kg" - }, - { - "material": { - "id": 5, - "name": "Borosilicate Glass", - "type": "Glass" - }, - "percentage": 33.9, - "mass": 1.01, - "unit": "kg" - }, - { - "material": { - "id": 6, - "name": "Polypropylene", - "type": "Plastic" - }, - "percentage": 33.1, - "mass": 0.92, - "unit": "kg" - }, - { - "material": { - "id": 4, - "name": "Mica", - "type": "Mineral" - }, - "percentage": 24.6, - "mass": 0.87, - "unit": "kg" - } - ], - "components": [ - { - "id": 3711, - "name": "Fan Component 1", - "description": "High-quality part for fan functionality" - }, - { - "id": 3712, - "name": "Fan Component 2", - "description": "High-quality part for fan functionality" - }, - { - "id": 3713, - "name": "Fan Component 3", - "description": "High-quality part for fan functionality" - }, - { - "id": 3714, - "name": "Fan Component 4", - "description": "High-quality part for fan functionality" - }, - { - "id": 3715, - "name": "Fan Component 5", - "description": "High-quality part for fan functionality" - } - ], - "images": [ - { - "id": 371, - "url": "https://via.placeholder.com/400x300/0b339f/ffffff?text=ChefMate+Fan+167R", - "description": "Fan product image" - } - ], - "created_at": "2024-10-28T09:16:11.472033Z", - "updated_at": "2025-06-05T09:16:11.472033Z" - }, - { - "id": 372, - "name": "EcoTech Humidifier 695R", - "description": "EcoTech Humidifier 695R is a high-performance humidifier designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 1, - "name": "Kitchen Appliance" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 1.96, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 28.6, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 29.2, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 2083, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 9.1, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 8.8, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 7.3, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 6, - "name": "Polypropylene", - "type": "Plastic" - }, - "percentage": 23.1, - "mass": 0.74, - "unit": "kg" - }, - { - "material": { - "id": 3, - "name": "Copper Wire", - "type": "Metal" - }, - "percentage": 76.9, - "mass": 1.74, - "unit": "kg" - } - ], - "components": [ - { - "id": 3721, - "name": "Humidifier Component 1", - "description": "High-quality part for humidifier functionality" - }, - { - "id": 3722, - "name": "Humidifier Component 2", - "description": "High-quality part for humidifier functionality" - } - ], - "images": [ - { - "id": 372, - "url": "https://via.placeholder.com/400x300/01f9d2/ffffff?text=EcoTech+Humidifier+695R", - "description": "Humidifier product image" - } - ], - "created_at": "2025-02-15T09:16:11.472084Z", - "updated_at": "2025-06-02T09:16:11.472084Z" - }, - { - "id": 373, - "name": "ZenGear Kettle 958R", - "description": "ZenGear Kettle 958R is a high-performance kettle designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 5, - "name": "Office Equipment" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 1.67, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 21.2, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 19.7, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 2123, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 9.3, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 8.7, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 8.5, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 7, - "name": "Silicone", - "type": "Elastomer" - }, - "percentage": 10.4, - "mass": 0.25, - "unit": "kg" - }, - { - "material": { - "id": 3, - "name": "Copper Wire", - "type": "Metal" - }, - "percentage": 33.9, - "mass": 0.48, - "unit": "kg" - }, - { - "material": { - "id": 5, - "name": "Borosilicate Glass", - "type": "Glass" - }, - "percentage": 22.6, - "mass": 0.42, - "unit": "kg" - }, - { - "material": { - "id": 1, - "name": "Stainless Steel", - "type": "Metal" - }, - "percentage": 33.0, - "mass": 1.03, - "unit": "kg" - } - ], - "components": [ - { - "id": 3731, - "name": "Kettle Component 1", - "description": "High-quality part for kettle functionality" - }, - { - "id": 3732, - "name": "Kettle Component 2", - "description": "High-quality part for kettle functionality" - }, - { - "id": 3733, - "name": "Kettle Component 3", - "description": "High-quality part for kettle functionality" - }, - { - "id": 3734, - "name": "Kettle Component 4", - "description": "High-quality part for kettle functionality" - } - ], - "images": [ - { - "id": 373, - "url": "https://via.placeholder.com/400x300/0ab909/ffffff?text=ZenGear+Kettle+958R", - "description": "Kettle product image" - } - ], - "created_at": "2025-01-02T09:16:11.472136Z", - "updated_at": "2025-04-24T09:16:11.472136Z" - }, - { - "id": 374, - "name": "SmartHome Iron 659S", - "description": "SmartHome Iron 659S is a high-performance iron designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 4, - "name": "Smart Home Device" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 2.73, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 26.7, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 24.1, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 1523, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 6.9, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 7.1, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 8.7, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 2, - "name": "ABS Plastic", - "type": "Plastic" - }, - "percentage": 59.1, - "mass": 1.08, - "unit": "kg" - }, - { - "material": { - "id": 7, - "name": "Silicone", - "type": "Elastomer" - }, - "percentage": 40.9, - "mass": 0.42, - "unit": "kg" - } - ], - "components": [ - { - "id": 3741, - "name": "Iron Component 1", - "description": "High-quality part for iron functionality" - }, - { - "id": 3742, - "name": "Iron Component 2", - "description": "High-quality part for iron functionality" - }, - { - "id": 3743, - "name": "Iron Component 3", - "description": "High-quality part for iron functionality" - }, - { - "id": 3744, - "name": "Iron Component 4", - "description": "High-quality part for iron functionality" - }, - { - "id": 3745, - "name": "Iron Component 5", - "description": "High-quality part for iron functionality" - } - ], - "images": [ - { - "id": 374, - "url": "https://via.placeholder.com/400x300/0503bf/ffffff?text=SmartHome+Iron+659S", - "description": "Iron product image" - } - ], - "created_at": "2025-01-23T09:16:11.472197Z", - "updated_at": "2025-05-30T09:16:11.472197Z" - }, - { - "id": 375, - "name": "PureLife Iron 683G", - "description": "PureLife Iron 683G is a high-performance iron designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 5, - "name": "Office Equipment" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 2.72, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 33.8, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 26.3, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 2034, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 6.6, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 6.2, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 7.2, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 3, - "name": "Copper Wire", - "type": "Metal" - }, - "percentage": 36.5, - "mass": 1.3, - "unit": "kg" - }, - { - "material": { - "id": 2, - "name": "ABS Plastic", - "type": "Plastic" - }, - "percentage": 63.5, - "mass": 1.51, - "unit": "kg" - } - ], - "components": [ - { - "id": 3751, - "name": "Iron Component 1", - "description": "High-quality part for iron functionality" - }, - { - "id": 3752, - "name": "Iron Component 2", - "description": "High-quality part for iron functionality" - } - ], - "images": [ - { - "id": 375, - "url": "https://via.placeholder.com/400x300/063462/ffffff?text=PureLife+Iron+683G", - "description": "Iron product image" - } - ], - "created_at": "2024-11-09T09:16:11.472251Z", - "updated_at": "2025-05-24T09:16:11.472251Z" - }, - { - "id": 376, - "name": "SmartHome Air Purifier 358B", - "description": "SmartHome Air Purifier 358B is a high-performance air purifier designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 1, - "name": "Kitchen Appliance" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 3.99, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 30.6, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 29.8, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 1995, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 8.7, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 7.5, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 8.7, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 1, - "name": "Stainless Steel", - "type": "Metal" - }, - "percentage": 50.0, - "mass": 1.24, - "unit": "kg" - }, - { - "material": { - "id": 7, - "name": "Silicone", - "type": "Elastomer" - }, - "percentage": 50.0, - "mass": 1.76, - "unit": "kg" - } - ], - "components": [ - { - "id": 3761, - "name": "Air Purifier Component 1", - "description": "High-quality part for air purifier functionality" - }, - { - "id": 3762, - "name": "Air Purifier Component 2", - "description": "High-quality part for air purifier functionality" - }, - { - "id": 3763, - "name": "Air Purifier Component 3", - "description": "High-quality part for air purifier functionality" - } - ], - "images": [ - { - "id": 376, - "url": "https://via.placeholder.com/400x300/09c5e0/ffffff?text=SmartHome+Air+Purifier+358B", - "description": "Air Purifier product image" - } - ], - "created_at": "2024-09-01T09:16:11.472304Z", - "updated_at": "2025-06-26T09:16:11.472304Z" - }, - { - "id": 377, - "name": "ZenGear Kettle 126C", - "description": "ZenGear Kettle 126C is a high-performance kettle designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 5, - "name": "Office Equipment" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 2.87, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 21.6, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 29.7, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 1718, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 8.4, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 8.3, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 6.9, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 3, - "name": "Copper Wire", - "type": "Metal" - }, - "percentage": 57.1, - "mass": 1.46, - "unit": "kg" - }, - { - "material": { - "id": 6, - "name": "Polypropylene", - "type": "Plastic" - }, - "percentage": 24.8, - "mass": 0.5, - "unit": "kg" - }, - { - "material": { - "id": 7, - "name": "Silicone", - "type": "Elastomer" - }, - "percentage": 18.1, - "mass": 0.2, - "unit": "kg" - } - ], - "components": [ - { - "id": 3771, - "name": "Kettle Component 1", - "description": "High-quality part for kettle functionality" - }, - { - "id": 3772, - "name": "Kettle Component 2", - "description": "High-quality part for kettle functionality" - }, - { - "id": 3773, - "name": "Kettle Component 3", - "description": "High-quality part for kettle functionality" - } - ], - "images": [ - { - "id": 377, - "url": "https://via.placeholder.com/400x300/08d421/ffffff?text=ZenGear+Kettle+126C", - "description": "Kettle product image" - } - ], - "created_at": "2024-04-06T09:16:11.472370Z", - "updated_at": "2025-07-02T09:16:11.472370Z" - }, - { - "id": 378, - "name": "SmartHome Blender 357W", - "description": "SmartHome Blender 357W is a high-performance blender designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 2, - "name": "Home Electronics" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 1.91, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 30.2, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 19.5, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 1383, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 7.5, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 5.6, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 9.0, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 3, - "name": "Copper Wire", - "type": "Metal" - }, - "percentage": 16.0, - "mass": 0.64, - "unit": "kg" - }, - { - "material": { - "id": 2, - "name": "ABS Plastic", - "type": "Plastic" - }, - "percentage": 57.4, - "mass": 2.22, - "unit": "kg" - }, - { - "material": { - "id": 4, - "name": "Mica", - "type": "Mineral" - }, - "percentage": 26.6, - "mass": 0.87, - "unit": "kg" - } - ], - "components": [ - { - "id": 3781, - "name": "Blender Component 1", - "description": "High-quality part for blender functionality" - }, - { - "id": 3782, - "name": "Blender Component 2", - "description": "High-quality part for blender functionality" - }, - { - "id": 3783, - "name": "Blender Component 3", - "description": "High-quality part for blender functionality" - }, - { - "id": 3784, - "name": "Blender Component 4", - "description": "High-quality part for blender functionality" - } - ], - "images": [ - { - "id": 378, - "url": "https://via.placeholder.com/400x300/0c34c2/ffffff?text=SmartHome+Blender+357W", - "description": "Blender product image" - } - ], - "created_at": "2024-07-27T09:16:11.472426Z", - "updated_at": "2025-04-25T09:16:11.472426Z" - }, - { - "id": 379, - "name": "AquaPro Coffee Maker 348Z", - "description": "AquaPro Coffee Maker 348Z is a high-performance coffee maker designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 4, - "name": "Smart Home Device" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 1.79, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 27.3, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 19.7, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 1153, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 9.2, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 5.9, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 7.5, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 7, - "name": "Silicone", - "type": "Elastomer" - }, - "percentage": 33.8, - "mass": 0.73, - "unit": "kg" - }, - { - "material": { - "id": 3, - "name": "Copper Wire", - "type": "Metal" - }, - "percentage": 66.2, - "mass": 1.81, - "unit": "kg" - } - ], - "components": [ - { - "id": 3791, - "name": "Coffee Maker Component 1", - "description": "High-quality part for coffee maker functionality" - }, - { - "id": 3792, - "name": "Coffee Maker Component 2", - "description": "High-quality part for coffee maker functionality" - }, - { - "id": 3793, - "name": "Coffee Maker Component 3", - "description": "High-quality part for coffee maker functionality" - }, - { - "id": 3794, - "name": "Coffee Maker Component 4", - "description": "High-quality part for coffee maker functionality" - } - ], - "images": [ - { - "id": 379, - "url": "https://via.placeholder.com/400x300/051b95/ffffff?text=AquaPro+Coffee+Maker+348Z", - "description": "Coffee Maker product image" - } - ], - "created_at": "2024-12-15T09:16:11.472483Z", - "updated_at": "2025-05-07T09:16:11.472483Z" - }, - { - "id": 380, - "name": "NeoCook Humidifier 197O", - "description": "NeoCook Humidifier 197O is a high-performance humidifier designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 5, - "name": "Office Equipment" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 1.02, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 30.3, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 24.2, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 1534, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 9.2, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 5.0, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 6.4, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 1, - "name": "Stainless Steel", - "type": "Metal" - }, - "percentage": 32.7, - "mass": 0.48, - "unit": "kg" - }, - { - "material": { - "id": 5, - "name": "Borosilicate Glass", - "type": "Glass" - }, - "percentage": 36.0, - "mass": 0.89, - "unit": "kg" - }, - { - "material": { - "id": 2, - "name": "ABS Plastic", - "type": "Plastic" - }, - "percentage": 18.0, - "mass": 0.62, - "unit": "kg" - }, - { - "material": { - "id": 7, - "name": "Silicone", - "type": "Elastomer" - }, - "percentage": 13.3, - "mass": 0.2, - "unit": "kg" - } - ], - "components": [ - { - "id": 3801, - "name": "Humidifier Component 1", - "description": "High-quality part for humidifier functionality" - }, - { - "id": 3802, - "name": "Humidifier Component 2", - "description": "High-quality part for humidifier functionality" - }, - { - "id": 3803, - "name": "Humidifier Component 3", - "description": "High-quality part for humidifier functionality" - }, - { - "id": 3804, - "name": "Humidifier Component 4", - "description": "High-quality part for humidifier functionality" - } - ], - "images": [ - { - "id": 380, - "url": "https://via.placeholder.com/400x300/0e9df9/ffffff?text=NeoCook+Humidifier+197O", - "description": "Humidifier product image" - } - ], - "created_at": "2024-12-07T09:16:11.472543Z", - "updated_at": "2025-07-03T09:16:11.472543Z" - }, - { - "id": 381, - "name": "NeoCook Iron 597T", - "description": "NeoCook Iron 597T is a high-performance iron designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 3, - "name": "Personal Care Device" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 2.61, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 30.7, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 15.6, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 925, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 7.8, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 5.1, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 9.0, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 5, - "name": "Borosilicate Glass", - "type": "Glass" - }, - "percentage": 43.2, - "mass": 0.82, - "unit": "kg" - }, - { - "material": { - "id": 1, - "name": "Stainless Steel", - "type": "Metal" - }, - "percentage": 44.0, - "mass": 1.49, - "unit": "kg" - }, - { - "material": { - "id": 3, - "name": "Copper Wire", - "type": "Metal" - }, - "percentage": 12.8, - "mass": 0.42, - "unit": "kg" - } - ], - "components": [ - { - "id": 3811, - "name": "Iron Component 1", - "description": "High-quality part for iron functionality" - }, - { - "id": 3812, - "name": "Iron Component 2", - "description": "High-quality part for iron functionality" - }, - { - "id": 3813, - "name": "Iron Component 3", - "description": "High-quality part for iron functionality" - } - ], - "images": [ - { - "id": 381, - "url": "https://via.placeholder.com/400x300/0a5cca/ffffff?text=NeoCook+Iron+597T", - "description": "Iron product image" - } - ], - "created_at": "2024-07-15T09:16:11.472600Z", - "updated_at": "2025-06-25T09:16:11.472600Z" - }, - { - "id": 382, - "name": "AquaPro Toaster 280U", - "description": "AquaPro Toaster 280U is a high-performance toaster designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 2, - "name": "Home Electronics" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 3.9, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 23.3, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 16.6, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 1366, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 6.1, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 7.3, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 9.4, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 4, - "name": "Mica", - "type": "Mineral" - }, - "percentage": 34.1, - "mass": 1.22, - "unit": "kg" - }, - { - "material": { - "id": 3, - "name": "Copper Wire", - "type": "Metal" - }, - "percentage": 21.4, - "mass": 0.83, - "unit": "kg" - }, - { - "material": { - "id": 7, - "name": "Silicone", - "type": "Elastomer" - }, - "percentage": 44.4, - "mass": 1.35, - "unit": "kg" - } - ], - "components": [ - { - "id": 3821, - "name": "Toaster Component 1", - "description": "High-quality part for toaster functionality" - }, - { - "id": 3822, - "name": "Toaster Component 2", - "description": "High-quality part for toaster functionality" - }, - { - "id": 3823, - "name": "Toaster Component 3", - "description": "High-quality part for toaster functionality" - }, - { - "id": 3824, - "name": "Toaster Component 4", - "description": "High-quality part for toaster functionality" - } - ], - "images": [ - { - "id": 382, - "url": "https://via.placeholder.com/400x300/0db2e3/ffffff?text=AquaPro+Toaster+280U", - "description": "Toaster product image" - } - ], - "created_at": "2024-12-08T09:16:11.472654Z", - "updated_at": "2025-07-31T09:16:11.472654Z" - }, - { - "id": 383, - "name": "NeoCook Monitor 940X", - "description": "NeoCook Monitor 940X is a high-performance monitor designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 5, - "name": "Office Equipment" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 3.66, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 30.8, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 29.0, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 2049, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 8.9, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 8.5, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 8.0, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 5, - "name": "Borosilicate Glass", - "type": "Glass" - }, - "percentage": 22.3, - "mass": 0.75, - "unit": "kg" - }, - { - "material": { - "id": 7, - "name": "Silicone", - "type": "Elastomer" - }, - "percentage": 35.1, - "mass": 0.41, - "unit": "kg" - }, - { - "material": { - "id": 2, - "name": "ABS Plastic", - "type": "Plastic" - }, - "percentage": 42.6, - "mass": 1.2, - "unit": "kg" - } - ], - "components": [ - { - "id": 3831, - "name": "Monitor Component 1", - "description": "High-quality part for monitor functionality" - }, - { - "id": 3832, - "name": "Monitor Component 2", - "description": "High-quality part for monitor functionality" - }, - { - "id": 3833, - "name": "Monitor Component 3", - "description": "High-quality part for monitor functionality" - }, - { - "id": 3834, - "name": "Monitor Component 4", - "description": "High-quality part for monitor functionality" - } - ], - "images": [ - { - "id": 383, - "url": "https://via.placeholder.com/400x300/0c1ffc/ffffff?text=NeoCook+Monitor+940X", - "description": "Monitor product image" - } - ], - "created_at": "2024-08-02T09:16:11.472717Z", - "updated_at": "2025-04-28T09:16:11.472717Z" - }, - { - "id": 384, - "name": "NeoCook Coffee Maker 940C", - "description": "NeoCook Coffee Maker 940C is a high-performance coffee maker designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 3, - "name": "Personal Care Device" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 2.41, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 26.3, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 24.4, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 1729, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 9.0, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 7.9, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 8.0, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 6, - "name": "Polypropylene", - "type": "Plastic" - }, - "percentage": 40.0, - "mass": 1.34, - "unit": "kg" - }, - { - "material": { - "id": 1, - "name": "Stainless Steel", - "type": "Metal" - }, - "percentage": 39.0, - "mass": 1.17, - "unit": "kg" - }, - { - "material": { - "id": 5, - "name": "Borosilicate Glass", - "type": "Glass" - }, - "percentage": 21.0, - "mass": 0.79, - "unit": "kg" - } - ], - "components": [ - { - "id": 3841, - "name": "Coffee Maker Component 1", - "description": "High-quality part for coffee maker functionality" - }, - { - "id": 3842, - "name": "Coffee Maker Component 2", - "description": "High-quality part for coffee maker functionality" - }, - { - "id": 3843, - "name": "Coffee Maker Component 3", - "description": "High-quality part for coffee maker functionality" - }, - { - "id": 3844, - "name": "Coffee Maker Component 4", - "description": "High-quality part for coffee maker functionality" - }, - { - "id": 3845, - "name": "Coffee Maker Component 5", - "description": "High-quality part for coffee maker functionality" - } - ], - "images": [ - { - "id": 384, - "url": "https://via.placeholder.com/400x300/03ccf6/ffffff?text=NeoCook+Coffee+Maker+940C", - "description": "Coffee Maker product image" - } - ], - "created_at": "2025-04-05T09:16:11.472782Z", - "updated_at": "2025-07-25T09:16:11.472782Z" - }, - { - "id": 385, - "name": "NeoCook Blender 767P", - "description": "NeoCook Blender 767P is a high-performance blender designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 4, - "name": "Smart Home Device" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 2.58, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 28.0, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 29.2, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 1909, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 8.5, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 7.2, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 6.1, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 2, - "name": "ABS Plastic", - "type": "Plastic" - }, - "percentage": 51.5, - "mass": 2.01, - "unit": "kg" - }, - { - "material": { - "id": 1, - "name": "Stainless Steel", - "type": "Metal" - }, - "percentage": 20.4, - "mass": 0.28, - "unit": "kg" - }, - { - "material": { - "id": 7, - "name": "Silicone", - "type": "Elastomer" - }, - "percentage": 28.2, - "mass": 1.05, - "unit": "kg" - } - ], - "components": [ - { - "id": 3851, - "name": "Blender Component 1", - "description": "High-quality part for blender functionality" - }, - { - "id": 3852, - "name": "Blender Component 2", - "description": "High-quality part for blender functionality" - }, - { - "id": 3853, - "name": "Blender Component 3", - "description": "High-quality part for blender functionality" - }, - { - "id": 3854, - "name": "Blender Component 4", - "description": "High-quality part for blender functionality" - }, - { - "id": 3855, - "name": "Blender Component 5", - "description": "High-quality part for blender functionality" - } - ], - "images": [ - { - "id": 385, - "url": "https://via.placeholder.com/400x300/0ae109/ffffff?text=NeoCook+Blender+767P", - "description": "Blender product image" - } - ], - "created_at": "2025-01-18T09:16:11.472846Z", - "updated_at": "2025-06-17T09:16:11.472846Z" - }, - { - "id": 386, - "name": "PureLife Fan 397H", - "description": "PureLife Fan 397H is a high-performance fan designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 1, - "name": "Kitchen Appliance" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 2.35, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 24.6, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 17.9, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 1268, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 6.6, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 6.0, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 7.8, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 6, - "name": "Polypropylene", - "type": "Plastic" - }, - "percentage": 23.6, - "mass": 0.83, - "unit": "kg" - }, - { - "material": { - "id": 7, - "name": "Silicone", - "type": "Elastomer" - }, - "percentage": 27.8, - "mass": 0.41, - "unit": "kg" - }, - { - "material": { - "id": 5, - "name": "Borosilicate Glass", - "type": "Glass" - }, - "percentage": 48.6, - "mass": 0.53, - "unit": "kg" - } - ], - "components": [ - { - "id": 3861, - "name": "Fan Component 1", - "description": "High-quality part for fan functionality" - }, - { - "id": 3862, - "name": "Fan Component 2", - "description": "High-quality part for fan functionality" - }, - { - "id": 3863, - "name": "Fan Component 3", - "description": "High-quality part for fan functionality" - }, - { - "id": 3864, - "name": "Fan Component 4", - "description": "High-quality part for fan functionality" - } - ], - "images": [ - { - "id": 386, - "url": "https://via.placeholder.com/400x300/0d571e/ffffff?text=PureLife+Fan+397H", - "description": "Fan product image" - } - ], - "created_at": "2024-09-30T09:16:11.472900Z", - "updated_at": "2025-07-10T09:16:11.472900Z" - }, - { - "id": 387, - "name": "SmartHome Coffee Maker 502Q", - "description": "SmartHome Coffee Maker 502Q is a high-performance coffee maker designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 3, - "name": "Personal Care Device" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 1.27, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 22.1, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 19.4, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 1794, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 9.1, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 5.2, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 8.3, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 5, - "name": "Borosilicate Glass", - "type": "Glass" - }, - "percentage": 40.5, - "mass": 0.98, - "unit": "kg" - }, - { - "material": { - "id": 3, - "name": "Copper Wire", - "type": "Metal" - }, - "percentage": 9.5, - "mass": 0.22, - "unit": "kg" - }, - { - "material": { - "id": 6, - "name": "Polypropylene", - "type": "Plastic" - }, - "percentage": 34.5, - "mass": 0.63, - "unit": "kg" - }, - { - "material": { - "id": 2, - "name": "ABS Plastic", - "type": "Plastic" - }, - "percentage": 15.5, - "mass": 0.2, - "unit": "kg" - } - ], - "components": [ - { - "id": 3871, - "name": "Coffee Maker Component 1", - "description": "High-quality part for coffee maker functionality" - }, - { - "id": 3872, - "name": "Coffee Maker Component 2", - "description": "High-quality part for coffee maker functionality" - }, - { - "id": 3873, - "name": "Coffee Maker Component 3", - "description": "High-quality part for coffee maker functionality" - } - ], - "images": [ - { - "id": 387, - "url": "https://via.placeholder.com/400x300/061a97/ffffff?text=SmartHome+Coffee+Maker+502Q", - "description": "Coffee Maker product image" - } - ], - "created_at": "2025-03-28T09:16:11.472959Z", - "updated_at": "2025-07-11T09:16:11.472959Z" - }, - { - "id": 388, - "name": "SmartHome Humidifier 753A", - "description": "SmartHome Humidifier 753A is a high-performance humidifier designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 2, - "name": "Home Electronics" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 1.31, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 28.0, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 30.0, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 2195, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 6.0, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 6.8, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 9.0, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 1, - "name": "Stainless Steel", - "type": "Metal" - }, - "percentage": 27.8, - "mass": 0.59, - "unit": "kg" - }, - { - "material": { - "id": 7, - "name": "Silicone", - "type": "Elastomer" - }, - "percentage": 24.7, - "mass": 0.83, - "unit": "kg" - }, - { - "material": { - "id": 4, - "name": "Mica", - "type": "Mineral" - }, - "percentage": 20.4, - "mass": 0.42, - "unit": "kg" - }, - { - "material": { - "id": 2, - "name": "ABS Plastic", - "type": "Plastic" - }, - "percentage": 27.2, - "mass": 0.92, - "unit": "kg" - } - ], - "components": [ - { - "id": 3881, - "name": "Humidifier Component 1", - "description": "High-quality part for humidifier functionality" - }, - { - "id": 3882, - "name": "Humidifier Component 2", - "description": "High-quality part for humidifier functionality" - }, - { - "id": 3883, - "name": "Humidifier Component 3", - "description": "High-quality part for humidifier functionality" - }, - { - "id": 3884, - "name": "Humidifier Component 4", - "description": "High-quality part for humidifier functionality" - } - ], - "images": [ - { - "id": 388, - "url": "https://via.placeholder.com/400x300/0a9019/ffffff?text=SmartHome+Humidifier+753A", - "description": "Humidifier product image" - } - ], - "created_at": "2024-07-02T09:16:11.473018Z", - "updated_at": "2025-07-14T09:16:11.473018Z" - }, - { - "id": 389, - "name": "ChefMate Rice Cooker 395K", - "description": "ChefMate Rice Cooker 395K is a high-performance rice cooker designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 4, - "name": "Smart Home Device" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 3.35, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 25.7, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 20.2, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 1871, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 7.4, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 7.6, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 7.4, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 7, - "name": "Silicone", - "type": "Elastomer" - }, - "percentage": 52.8, - "mass": 0.53, - "unit": "kg" - }, - { - "material": { - "id": 4, - "name": "Mica", - "type": "Mineral" - }, - "percentage": 47.2, - "mass": 1.43, - "unit": "kg" - } - ], - "components": [ - { - "id": 3891, - "name": "Rice Cooker Component 1", - "description": "High-quality part for rice cooker functionality" - }, - { - "id": 3892, - "name": "Rice Cooker Component 2", - "description": "High-quality part for rice cooker functionality" - }, - { - "id": 3893, - "name": "Rice Cooker Component 3", - "description": "High-quality part for rice cooker functionality" - }, - { - "id": 3894, - "name": "Rice Cooker Component 4", - "description": "High-quality part for rice cooker functionality" - } - ], - "images": [ - { - "id": 389, - "url": "https://via.placeholder.com/400x300/0adc29/ffffff?text=ChefMate+Rice+Cooker+395K", - "description": "Rice Cooker product image" - } - ], - "created_at": "2025-04-17T09:16:11.473086Z", - "updated_at": "2025-06-27T09:16:11.473086Z" - }, - { - "id": 390, - "name": "EcoTech Iron 792K", - "description": "EcoTech Iron 792K is a high-performance iron designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 4, - "name": "Smart Home Device" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 1.73, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 20.3, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 28.3, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 1683, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 6.7, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 6.5, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 7.1, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 7, - "name": "Silicone", - "type": "Elastomer" - }, - "percentage": 77.6, - "mass": 1.25, - "unit": "kg" - }, - { - "material": { - "id": 6, - "name": "Polypropylene", - "type": "Plastic" - }, - "percentage": 22.4, - "mass": 0.29, - "unit": "kg" - } - ], - "components": [ - { - "id": 3901, - "name": "Iron Component 1", - "description": "High-quality part for iron functionality" - }, - { - "id": 3902, - "name": "Iron Component 2", - "description": "High-quality part for iron functionality" - }, - { - "id": 3903, - "name": "Iron Component 3", - "description": "High-quality part for iron functionality" - } - ], - "images": [ - { - "id": 390, - "url": "https://via.placeholder.com/400x300/02f7a7/ffffff?text=EcoTech+Iron+792K", - "description": "Iron product image" - } - ], - "created_at": "2024-06-14T09:16:11.473133Z", - "updated_at": "2025-05-16T09:16:11.473133Z" - }, - { - "id": 391, - "name": "CleanWave Kettle 221G", - "description": "CleanWave Kettle 221G is a high-performance kettle designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 4, - "name": "Smart Home Device" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 3.68, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 27.0, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 16.0, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 1875, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 7.6, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 9.0, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 9.6, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 6, - "name": "Polypropylene", - "type": "Plastic" - }, - "percentage": 48.8, - "mass": 0.92, - "unit": "kg" - }, - { - "material": { - "id": 2, - "name": "ABS Plastic", - "type": "Plastic" - }, - "percentage": 51.2, - "mass": 0.61, - "unit": "kg" - } - ], - "components": [ - { - "id": 3911, - "name": "Kettle Component 1", - "description": "High-quality part for kettle functionality" - }, - { - "id": 3912, - "name": "Kettle Component 2", - "description": "High-quality part for kettle functionality" - }, - { - "id": 3913, - "name": "Kettle Component 3", - "description": "High-quality part for kettle functionality" - } - ], - "images": [ - { - "id": 391, - "url": "https://via.placeholder.com/400x300/07f59d/ffffff?text=CleanWave+Kettle+221G", - "description": "Kettle product image" - } - ], - "created_at": "2024-05-31T09:16:11.473184Z", - "updated_at": "2025-07-12T09:16:11.473184Z" - }, - { - "id": 392, - "name": "SmartHome Air Purifier 987Y", - "description": "SmartHome Air Purifier 987Y is a high-performance air purifier designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 5, - "name": "Office Equipment" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 3.7, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 29.2, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 16.1, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 1843, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 6.1, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 7.0, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 7.6, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 5, - "name": "Borosilicate Glass", - "type": "Glass" - }, - "percentage": 48.6, - "mass": 1.82, - "unit": "kg" - }, - { - "material": { - "id": 3, - "name": "Copper Wire", - "type": "Metal" - }, - "percentage": 51.4, - "mass": 1.48, - "unit": "kg" - } - ], - "components": [ - { - "id": 3921, - "name": "Air Purifier Component 1", - "description": "High-quality part for air purifier functionality" - }, - { - "id": 3922, - "name": "Air Purifier Component 2", - "description": "High-quality part for air purifier functionality" - }, - { - "id": 3923, - "name": "Air Purifier Component 3", - "description": "High-quality part for air purifier functionality" - }, - { - "id": 3924, - "name": "Air Purifier Component 4", - "description": "High-quality part for air purifier functionality" - } - ], - "images": [ - { - "id": 392, - "url": "https://via.placeholder.com/400x300/0b5a99/ffffff?text=SmartHome+Air+Purifier+987Y", - "description": "Air Purifier product image" - } - ], - "created_at": "2024-12-17T09:16:11.473240Z", - "updated_at": "2025-05-15T09:16:11.473240Z" - }, - { - "id": 393, - "name": "EcoTech Blender 261Q", - "description": "EcoTech Blender 261Q is a high-performance blender designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 5, - "name": "Office Equipment" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 3.51, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 22.2, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 18.6, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 2061, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 8.1, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 5.0, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 6.5, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 5, - "name": "Borosilicate Glass", - "type": "Glass" - }, - "percentage": 30.2, - "mass": 1.19, - "unit": "kg" - }, - { - "material": { - "id": 2, - "name": "ABS Plastic", - "type": "Plastic" - }, - "percentage": 30.9, - "mass": 0.63, - "unit": "kg" - }, - { - "material": { - "id": 7, - "name": "Silicone", - "type": "Elastomer" - }, - "percentage": 21.6, - "mass": 0.58, - "unit": "kg" - }, - { - "material": { - "id": 6, - "name": "Polypropylene", - "type": "Plastic" - }, - "percentage": 17.3, - "mass": 0.68, - "unit": "kg" - } - ], - "components": [ - { - "id": 3931, - "name": "Blender Component 1", - "description": "High-quality part for blender functionality" - }, - { - "id": 3932, - "name": "Blender Component 2", - "description": "High-quality part for blender functionality" - }, - { - "id": 3933, - "name": "Blender Component 3", - "description": "High-quality part for blender functionality" - }, - { - "id": 3934, - "name": "Blender Component 4", - "description": "High-quality part for blender functionality" - } - ], - "images": [ - { - "id": 393, - "url": "https://via.placeholder.com/400x300/0a62ec/ffffff?text=EcoTech+Blender+261Q", - "description": "Blender product image" - } - ], - "created_at": "2025-03-27T09:16:11.473313Z", - "updated_at": "2025-07-30T09:16:11.473313Z" - }, - { - "id": 394, - "name": "ZenGear Monitor 970W", - "description": "ZenGear Monitor 970W is a high-performance monitor designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 1, - "name": "Kitchen Appliance" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 1.96, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 23.1, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 23.3, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 2050, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 7.7, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 6.8, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 8.9, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 3, - "name": "Copper Wire", - "type": "Metal" - }, - "percentage": 29.3, - "mass": 0.91, - "unit": "kg" - }, - { - "material": { - "id": 4, - "name": "Mica", - "type": "Mineral" - }, - "percentage": 35.9, - "mass": 0.87, - "unit": "kg" - }, - { - "material": { - "id": 1, - "name": "Stainless Steel", - "type": "Metal" - }, - "percentage": 34.7, - "mass": 1.02, - "unit": "kg" - } - ], - "components": [ - { - "id": 3941, - "name": "Monitor Component 1", - "description": "High-quality part for monitor functionality" - }, - { - "id": 3942, - "name": "Monitor Component 2", - "description": "High-quality part for monitor functionality" - }, - { - "id": 3943, - "name": "Monitor Component 3", - "description": "High-quality part for monitor functionality" - } - ], - "images": [ - { - "id": 394, - "url": "https://via.placeholder.com/400x300/0deb64/ffffff?text=ZenGear+Monitor+970W", - "description": "Monitor product image" - } - ], - "created_at": "2024-06-04T09:16:11.473363Z", - "updated_at": "2025-07-29T09:16:11.473363Z" - }, - { - "id": 395, - "name": "ZenGear Toaster 160N", - "description": "ZenGear Toaster 160N is a high-performance toaster designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 3, - "name": "Personal Care Device" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 1.8, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 34.8, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 19.7, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 2051, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 9.3, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 8.2, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 6.2, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 3, - "name": "Copper Wire", - "type": "Metal" - }, - "percentage": 15.7, - "mass": 0.59, - "unit": "kg" - }, - { - "material": { - "id": 7, - "name": "Silicone", - "type": "Elastomer" - }, - "percentage": 84.3, - "mass": 2.15, - "unit": "kg" - } - ], - "components": [ - { - "id": 3951, - "name": "Toaster Component 1", - "description": "High-quality part for toaster functionality" - }, - { - "id": 3952, - "name": "Toaster Component 2", - "description": "High-quality part for toaster functionality" - } - ], - "images": [ - { - "id": 395, - "url": "https://via.placeholder.com/400x300/03488f/ffffff?text=ZenGear+Toaster+160N", - "description": "Toaster product image" - } - ], - "created_at": "2025-03-29T09:16:11.473417Z", - "updated_at": "2025-07-12T09:16:11.473417Z" - }, - { - "id": 396, - "name": "CleanWave Kettle 771D", - "description": "CleanWave Kettle 771D is a high-performance kettle designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 2, - "name": "Home Electronics" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 2.15, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 27.4, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 22.0, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 1268, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 8.2, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 8.0, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 9.2, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 4, - "name": "Mica", - "type": "Mineral" - }, - "percentage": 15.1, - "mass": 0.34, - "unit": "kg" - }, - { - "material": { - "id": 1, - "name": "Stainless Steel", - "type": "Metal" - }, - "percentage": 17.8, - "mass": 0.49, - "unit": "kg" - }, - { - "material": { - "id": 5, - "name": "Borosilicate Glass", - "type": "Glass" - }, - "percentage": 38.8, - "mass": 1.02, - "unit": "kg" - }, - { - "material": { - "id": 2, - "name": "ABS Plastic", - "type": "Plastic" - }, - "percentage": 28.3, - "mass": 0.66, - "unit": "kg" - } - ], - "components": [ - { - "id": 3961, - "name": "Kettle Component 1", - "description": "High-quality part for kettle functionality" - }, - { - "id": 3962, - "name": "Kettle Component 2", - "description": "High-quality part for kettle functionality" - }, - { - "id": 3963, - "name": "Kettle Component 3", - "description": "High-quality part for kettle functionality" - }, - { - "id": 3964, - "name": "Kettle Component 4", - "description": "High-quality part for kettle functionality" - } - ], - "images": [ - { - "id": 396, - "url": "https://via.placeholder.com/400x300/093dad/ffffff?text=CleanWave+Kettle+771D", - "description": "Kettle product image" - } - ], - "created_at": "2024-07-13T09:16:11.473487Z", - "updated_at": "2025-06-26T09:16:11.473487Z" - }, - { - "id": 397, - "name": "ZenGear Fan 286A", - "description": "ZenGear Fan 286A is a high-performance fan designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 5, - "name": "Office Equipment" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 3.26, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 21.8, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 17.6, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 865, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 6.4, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 7.4, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 9.9, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 2, - "name": "ABS Plastic", - "type": "Plastic" - }, - "percentage": 49.1, - "mass": 0.73, - "unit": "kg" - }, - { - "material": { - "id": 7, - "name": "Silicone", - "type": "Elastomer" - }, - "percentage": 18.4, - "mass": 0.68, - "unit": "kg" - }, - { - "material": { - "id": 6, - "name": "Polypropylene", - "type": "Plastic" - }, - "percentage": 32.5, - "mass": 1.19, - "unit": "kg" - } - ], - "components": [ - { - "id": 3971, - "name": "Fan Component 1", - "description": "High-quality part for fan functionality" - }, - { - "id": 3972, - "name": "Fan Component 2", - "description": "High-quality part for fan functionality" - }, - { - "id": 3973, - "name": "Fan Component 3", - "description": "High-quality part for fan functionality" - }, - { - "id": 3974, - "name": "Fan Component 4", - "description": "High-quality part for fan functionality" - } - ], - "images": [ - { - "id": 397, - "url": "https://via.placeholder.com/400x300/0e9894/ffffff?text=ZenGear+Fan+286A", - "description": "Fan product image" - } - ], - "created_at": "2024-05-28T09:16:11.473541Z", - "updated_at": "2025-06-03T09:16:11.473541Z" - }, - { - "id": 398, - "name": "AquaPro Humidifier 521X", - "description": "AquaPro Humidifier 521X is a high-performance humidifier designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 3, - "name": "Personal Care Device" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 1.64, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 24.1, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 29.7, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 1186, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 7.7, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 7.2, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 10.0, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 7, - "name": "Silicone", - "type": "Elastomer" - }, - "percentage": 9.1, - "mass": 0.28, - "unit": "kg" - }, - { - "material": { - "id": 3, - "name": "Copper Wire", - "type": "Metal" - }, - "percentage": 43.6, - "mass": 0.8, - "unit": "kg" - }, - { - "material": { - "id": 1, - "name": "Stainless Steel", - "type": "Metal" - }, - "percentage": 20.0, - "mass": 0.51, - "unit": "kg" - }, - { - "material": { - "id": 2, - "name": "ABS Plastic", - "type": "Plastic" - }, - "percentage": 27.3, - "mass": 0.32, - "unit": "kg" - } - ], - "components": [ - { - "id": 3981, - "name": "Humidifier Component 1", - "description": "High-quality part for humidifier functionality" - }, - { - "id": 3982, - "name": "Humidifier Component 2", - "description": "High-quality part for humidifier functionality" - } - ], - "images": [ - { - "id": 398, - "url": "https://via.placeholder.com/400x300/0c8502/ffffff?text=AquaPro+Humidifier+521X", - "description": "Humidifier product image" - } - ], - "created_at": "2024-04-02T09:16:11.473597Z", - "updated_at": "2025-05-03T09:16:11.473597Z" - }, - { - "id": 399, - "name": "CleanWave Humidifier 631V", - "description": "CleanWave Humidifier 631V is a high-performance humidifier designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 3, - "name": "Personal Care Device" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 3.88, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 33.2, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 23.9, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 866, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 9.0, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 8.4, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 7.8, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 4, - "name": "Mica", - "type": "Mineral" - }, - "percentage": 33.8, - "mass": 1.04, - "unit": "kg" - }, - { - "material": { - "id": 7, - "name": "Silicone", - "type": "Elastomer" - }, - "percentage": 36.2, - "mass": 0.42, - "unit": "kg" - }, - { - "material": { - "id": 6, - "name": "Polypropylene", - "type": "Plastic" - }, - "percentage": 30.0, - "mass": 0.7, - "unit": "kg" - } - ], - "components": [ - { - "id": 3991, - "name": "Humidifier Component 1", - "description": "High-quality part for humidifier functionality" - }, - { - "id": 3992, - "name": "Humidifier Component 2", - "description": "High-quality part for humidifier functionality" - }, - { - "id": 3993, - "name": "Humidifier Component 3", - "description": "High-quality part for humidifier functionality" - }, - { - "id": 3994, - "name": "Humidifier Component 4", - "description": "High-quality part for humidifier functionality" - }, - { - "id": 3995, - "name": "Humidifier Component 5", - "description": "High-quality part for humidifier functionality" - } - ], - "images": [ - { - "id": 399, - "url": "https://via.placeholder.com/400x300/0b1fba/ffffff?text=CleanWave+Humidifier+631V", - "description": "Humidifier product image" - } - ], - "created_at": "2025-03-02T09:16:11.473655Z", - "updated_at": "2025-07-24T09:16:11.473655Z" - }, - { - "id": 400, - "name": "AquaPro Humidifier 657I", - "description": "AquaPro Humidifier 657I is a high-performance humidifier designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 4, - "name": "Smart Home Device" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 1.06, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 25.1, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 18.4, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 1684, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 9.1, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 8.7, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 9.6, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 4, - "name": "Mica", - "type": "Mineral" - }, - "percentage": 49.0, - "mass": 1.23, - "unit": "kg" - }, - { - "material": { - "id": 3, - "name": "Copper Wire", - "type": "Metal" - }, - "percentage": 16.0, - "mass": 0.5, - "unit": "kg" - }, - { - "material": { - "id": 7, - "name": "Silicone", - "type": "Elastomer" - }, - "percentage": 35.0, - "mass": 1.08, - "unit": "kg" - } - ], - "components": [ - { - "id": 4001, - "name": "Humidifier Component 1", - "description": "High-quality part for humidifier functionality" - }, - { - "id": 4002, - "name": "Humidifier Component 2", - "description": "High-quality part for humidifier functionality" - }, - { - "id": 4003, - "name": "Humidifier Component 3", - "description": "High-quality part for humidifier functionality" - } - ], - "images": [ - { - "id": 400, - "url": "https://via.placeholder.com/400x300/060be2/ffffff?text=AquaPro+Humidifier+657I", - "description": "Humidifier product image" - } - ], - "created_at": "2025-01-22T09:16:11.473711Z", - "updated_at": "2025-07-07T09:16:11.473711Z" - }, - { - "id": 401, - "name": "PureLife Monitor 309E", - "description": "PureLife Monitor 309E is a high-performance monitor designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 2, - "name": "Home Electronics" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 3.32, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 23.4, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 23.7, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 1857, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 7.1, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 8.4, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 7.4, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 6, - "name": "Polypropylene", - "type": "Plastic" - }, - "percentage": 60.3, - "mass": 1.55, - "unit": "kg" - }, - { - "material": { - "id": 5, - "name": "Borosilicate Glass", - "type": "Glass" - }, - "percentage": 39.7, - "mass": 0.97, - "unit": "kg" - } - ], - "components": [ - { - "id": 4011, - "name": "Monitor Component 1", - "description": "High-quality part for monitor functionality" - }, - { - "id": 4012, - "name": "Monitor Component 2", - "description": "High-quality part for monitor functionality" - }, - { - "id": 4013, - "name": "Monitor Component 3", - "description": "High-quality part for monitor functionality" - } - ], - "images": [ - { - "id": 401, - "url": "https://via.placeholder.com/400x300/068e9e/ffffff?text=PureLife+Monitor+309E", - "description": "Monitor product image" - } - ], - "created_at": "2024-06-10T09:16:11.473764Z", - "updated_at": "2025-05-09T09:16:11.473764Z" - }, - { - "id": 402, - "name": "ZenGear Blender 708U", - "description": "ZenGear Blender 708U is a high-performance blender designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 4, - "name": "Smart Home Device" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 3.9, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 22.7, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 26.4, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 1547, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 6.3, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 6.2, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 6.2, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 1, - "name": "Stainless Steel", - "type": "Metal" - }, - "percentage": 54.0, - "mass": 1.9, - "unit": "kg" - }, - { - "material": { - "id": 7, - "name": "Silicone", - "type": "Elastomer" - }, - "percentage": 46.0, - "mass": 0.51, - "unit": "kg" - } - ], - "components": [ - { - "id": 4021, - "name": "Blender Component 1", - "description": "High-quality part for blender functionality" - }, - { - "id": 4022, - "name": "Blender Component 2", - "description": "High-quality part for blender functionality" - }, - { - "id": 4023, - "name": "Blender Component 3", - "description": "High-quality part for blender functionality" - } - ], - "images": [ - { - "id": 402, - "url": "https://via.placeholder.com/400x300/0458c7/ffffff?text=ZenGear+Blender+708U", - "description": "Blender product image" - } - ], - "created_at": "2025-02-09T09:16:11.473826Z", - "updated_at": "2025-05-21T09:16:11.473826Z" - }, - { - "id": 403, - "name": "ZenGear Kettle 161D", - "description": "ZenGear Kettle 161D is a high-performance kettle designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 5, - "name": "Office Equipment" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 1.2, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 27.4, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 27.5, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 1171, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 6.7, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 5.5, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 7.3, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 5, - "name": "Borosilicate Glass", - "type": "Glass" - }, - "percentage": 38.6, - "mass": 0.52, - "unit": "kg" - }, - { - "material": { - "id": 4, - "name": "Mica", - "type": "Mineral" - }, - "percentage": 8.5, - "mass": 0.29, - "unit": "kg" - }, - { - "material": { - "id": 7, - "name": "Silicone", - "type": "Elastomer" - }, - "percentage": 18.3, - "mass": 0.21, - "unit": "kg" - }, - { - "material": { - "id": 3, - "name": "Copper Wire", - "type": "Metal" - }, - "percentage": 34.6, - "mass": 0.89, - "unit": "kg" - } - ], - "components": [ - { - "id": 4031, - "name": "Kettle Component 1", - "description": "High-quality part for kettle functionality" - }, - { - "id": 4032, - "name": "Kettle Component 2", - "description": "High-quality part for kettle functionality" - } - ], - "images": [ - { - "id": 403, - "url": "https://via.placeholder.com/400x300/0d02aa/ffffff?text=ZenGear+Kettle+161D", - "description": "Kettle product image" - } - ], - "created_at": "2024-12-18T09:16:11.473884Z", - "updated_at": "2025-07-12T09:16:11.473884Z" - }, - { - "id": 404, - "name": "PureLife Monitor 924P", - "description": "PureLife Monitor 924P is a high-performance monitor designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 5, - "name": "Office Equipment" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 3.18, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 32.5, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 17.3, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 1457, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 6.8, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 8.7, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 9.2, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 4, - "name": "Mica", - "type": "Mineral" - }, - "percentage": 28.6, - "mass": 0.44, - "unit": "kg" - }, - { - "material": { - "id": 1, - "name": "Stainless Steel", - "type": "Metal" - }, - "percentage": 28.6, - "mass": 0.57, - "unit": "kg" - }, - { - "material": { - "id": 2, - "name": "ABS Plastic", - "type": "Plastic" - }, - "percentage": 42.9, - "mass": 1.16, - "unit": "kg" - } - ], - "components": [ - { - "id": 4041, - "name": "Monitor Component 1", - "description": "High-quality part for monitor functionality" - }, - { - "id": 4042, - "name": "Monitor Component 2", - "description": "High-quality part for monitor functionality" - }, - { - "id": 4043, - "name": "Monitor Component 3", - "description": "High-quality part for monitor functionality" - }, - { - "id": 4044, - "name": "Monitor Component 4", - "description": "High-quality part for monitor functionality" - }, - { - "id": 4045, - "name": "Monitor Component 5", - "description": "High-quality part for monitor functionality" - } - ], - "images": [ - { - "id": 404, - "url": "https://via.placeholder.com/400x300/080e63/ffffff?text=PureLife+Monitor+924P", - "description": "Monitor product image" - } - ], - "created_at": "2025-01-31T09:16:11.474008Z", - "updated_at": "2025-05-03T09:16:11.474008Z" - }, - { - "id": 405, - "name": "CleanWave Blender 195Y", - "description": "CleanWave Blender 195Y is a high-performance blender designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 2, - "name": "Home Electronics" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 2.97, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 30.1, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 19.7, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 1167, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 6.6, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 7.4, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 7.2, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 2, - "name": "ABS Plastic", - "type": "Plastic" - }, - "percentage": 52.5, - "mass": 0.9, - "unit": "kg" - }, - { - "material": { - "id": 3, - "name": "Copper Wire", - "type": "Metal" - }, - "percentage": 47.5, - "mass": 1.16, - "unit": "kg" - } - ], - "components": [ - { - "id": 4051, - "name": "Blender Component 1", - "description": "High-quality part for blender functionality" - }, - { - "id": 4052, - "name": "Blender Component 2", - "description": "High-quality part for blender functionality" - }, - { - "id": 4053, - "name": "Blender Component 3", - "description": "High-quality part for blender functionality" - }, - { - "id": 4054, - "name": "Blender Component 4", - "description": "High-quality part for blender functionality" - } - ], - "images": [ - { - "id": 405, - "url": "https://via.placeholder.com/400x300/0edf63/ffffff?text=CleanWave+Blender+195Y", - "description": "Blender product image" - } - ], - "created_at": "2025-03-31T09:16:11.474063Z", - "updated_at": "2025-07-21T09:16:11.474063Z" - }, - { - "id": 406, - "name": "PureLife Coffee Maker 549B", - "description": "PureLife Coffee Maker 549B is a high-performance coffee maker designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 2, - "name": "Home Electronics" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 2.05, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 24.7, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 15.9, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 1923, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 7.6, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 7.4, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 7.8, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 6, - "name": "Polypropylene", - "type": "Plastic" - }, - "percentage": 42.3, - "mass": 1.24, - "unit": "kg" - }, - { - "material": { - "id": 4, - "name": "Mica", - "type": "Mineral" - }, - "percentage": 34.5, - "mass": 0.81, - "unit": "kg" - }, - { - "material": { - "id": 1, - "name": "Stainless Steel", - "type": "Metal" - }, - "percentage": 16.2, - "mass": 0.44, - "unit": "kg" - }, - { - "material": { - "id": 3, - "name": "Copper Wire", - "type": "Metal" - }, - "percentage": 7.0, - "mass": 0.22, - "unit": "kg" - } - ], - "components": [ - { - "id": 4061, - "name": "Coffee Maker Component 1", - "description": "High-quality part for coffee maker functionality" - }, - { - "id": 4062, - "name": "Coffee Maker Component 2", - "description": "High-quality part for coffee maker functionality" - } - ], - "images": [ - { - "id": 406, - "url": "https://via.placeholder.com/400x300/0d136f/ffffff?text=PureLife+Coffee+Maker+549B", - "description": "Coffee Maker product image" - } - ], - "created_at": "2024-05-21T09:16:11.474123Z", - "updated_at": "2025-07-10T09:16:11.474123Z" - }, - { - "id": 407, - "name": "SmartHome Toaster 629M", - "description": "SmartHome Toaster 629M is a high-performance toaster designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 5, - "name": "Office Equipment" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 1.64, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 32.1, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 21.9, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 834, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 8.8, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 9.0, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 9.9, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 5, - "name": "Borosilicate Glass", - "type": "Glass" - }, - "percentage": 38.8, - "mass": 1.37, - "unit": "kg" - }, - { - "material": { - "id": 3, - "name": "Copper Wire", - "type": "Metal" - }, - "percentage": 61.2, - "mass": 1.66, - "unit": "kg" - } - ], - "components": [ - { - "id": 4071, - "name": "Toaster Component 1", - "description": "High-quality part for toaster functionality" - }, - { - "id": 4072, - "name": "Toaster Component 2", - "description": "High-quality part for toaster functionality" - }, - { - "id": 4073, - "name": "Toaster Component 3", - "description": "High-quality part for toaster functionality" - }, - { - "id": 4074, - "name": "Toaster Component 4", - "description": "High-quality part for toaster functionality" - } - ], - "images": [ - { - "id": 407, - "url": "https://via.placeholder.com/400x300/0389a8/ffffff?text=SmartHome+Toaster+629M", - "description": "Toaster product image" - } - ], - "created_at": "2024-12-01T09:16:11.474179Z", - "updated_at": "2025-06-15T09:16:11.474179Z" - }, - { - "id": 408, - "name": "PureLife Monitor 231I", - "description": "PureLife Monitor 231I is a high-performance monitor designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 3, - "name": "Personal Care Device" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 2.89, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 23.7, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 23.1, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 1726, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 7.4, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 6.6, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 7.9, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 3, - "name": "Copper Wire", - "type": "Metal" - }, - "percentage": 53.1, - "mass": 2.0, - "unit": "kg" - }, - { - "material": { - "id": 6, - "name": "Polypropylene", - "type": "Plastic" - }, - "percentage": 46.9, - "mass": 1.08, - "unit": "kg" - } - ], - "components": [ - { - "id": 4081, - "name": "Monitor Component 1", - "description": "High-quality part for monitor functionality" - }, - { - "id": 4082, - "name": "Monitor Component 2", - "description": "High-quality part for monitor functionality" - }, - { - "id": 4083, - "name": "Monitor Component 3", - "description": "High-quality part for monitor functionality" - }, - { - "id": 4084, - "name": "Monitor Component 4", - "description": "High-quality part for monitor functionality" - } - ], - "images": [ - { - "id": 408, - "url": "https://via.placeholder.com/400x300/02248f/ffffff?text=PureLife+Monitor+231I", - "description": "Monitor product image" - } - ], - "created_at": "2024-03-28T09:16:11.474233Z", - "updated_at": "2025-06-17T09:16:11.474233Z" - }, - { - "id": 409, - "name": "ZenGear Fan 109Y", - "description": "ZenGear Fan 109Y is a high-performance fan designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 5, - "name": "Office Equipment" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 3.37, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 22.8, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 18.9, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 1380, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 8.3, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 6.6, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 8.4, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 6, - "name": "Polypropylene", - "type": "Plastic" - }, - "percentage": 32.9, - "mass": 0.7, - "unit": "kg" - }, - { - "material": { - "id": 3, - "name": "Copper Wire", - "type": "Metal" - }, - "percentage": 67.1, - "mass": 2.06, - "unit": "kg" - } - ], - "components": [ - { - "id": 4091, - "name": "Fan Component 1", - "description": "High-quality part for fan functionality" - }, - { - "id": 4092, - "name": "Fan Component 2", - "description": "High-quality part for fan functionality" - }, - { - "id": 4093, - "name": "Fan Component 3", - "description": "High-quality part for fan functionality" - }, - { - "id": 4094, - "name": "Fan Component 4", - "description": "High-quality part for fan functionality" - }, - { - "id": 4095, - "name": "Fan Component 5", - "description": "High-quality part for fan functionality" - } - ], - "images": [ - { - "id": 409, - "url": "https://via.placeholder.com/400x300/04d8bc/ffffff?text=ZenGear+Fan+109Y", - "description": "Fan product image" - } - ], - "created_at": "2025-04-12T09:16:11.474273Z", - "updated_at": "2025-07-02T09:16:11.474273Z" - }, - { - "id": 410, - "name": "EcoTech Toaster 705C", - "description": "EcoTech Toaster 705C is a high-performance toaster designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 5, - "name": "Office Equipment" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 3.81, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 20.5, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 25.3, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 1207, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 7.7, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 6.1, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 9.6, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 4, - "name": "Mica", - "type": "Mineral" - }, - "percentage": 24.3, - "mass": 0.29, - "unit": "kg" - }, - { - "material": { - "id": 1, - "name": "Stainless Steel", - "type": "Metal" - }, - "percentage": 20.1, - "mass": 0.67, - "unit": "kg" - }, - { - "material": { - "id": 2, - "name": "ABS Plastic", - "type": "Plastic" - }, - "percentage": 18.8, - "mass": 0.64, - "unit": "kg" - }, - { - "material": { - "id": 5, - "name": "Borosilicate Glass", - "type": "Glass" - }, - "percentage": 36.8, - "mass": 1.2, - "unit": "kg" - } - ], - "components": [ - { - "id": 4101, - "name": "Toaster Component 1", - "description": "High-quality part for toaster functionality" - }, - { - "id": 4102, - "name": "Toaster Component 2", - "description": "High-quality part for toaster functionality" - }, - { - "id": 4103, - "name": "Toaster Component 3", - "description": "High-quality part for toaster functionality" - }, - { - "id": 4104, - "name": "Toaster Component 4", - "description": "High-quality part for toaster functionality" - }, - { - "id": 4105, - "name": "Toaster Component 5", - "description": "High-quality part for toaster functionality" - } - ], - "images": [ - { - "id": 410, - "url": "https://via.placeholder.com/400x300/04bf1f/ffffff?text=EcoTech+Toaster+705C", - "description": "Toaster product image" - } - ], - "created_at": "2024-07-28T09:16:11.474331Z", - "updated_at": "2025-05-27T09:16:11.474331Z" - }, - { - "id": 411, - "name": "AquaPro Kettle 901D", - "description": "AquaPro Kettle 901D is a high-performance kettle designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 5, - "name": "Office Equipment" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 1.97, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 31.5, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 24.3, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 1922, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 6.4, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 6.3, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 8.4, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 3, - "name": "Copper Wire", - "type": "Metal" - }, - "percentage": 11.2, - "mass": 0.24, - "unit": "kg" - }, - { - "material": { - "id": 1, - "name": "Stainless Steel", - "type": "Metal" - }, - "percentage": 14.7, - "mass": 0.49, - "unit": "kg" - }, - { - "material": { - "id": 4, - "name": "Mica", - "type": "Mineral" - }, - "percentage": 32.8, - "mass": 0.5, - "unit": "kg" - }, - { - "material": { - "id": 2, - "name": "ABS Plastic", - "type": "Plastic" - }, - "percentage": 41.4, - "mass": 1.2, - "unit": "kg" - } - ], - "components": [ - { - "id": 4111, - "name": "Kettle Component 1", - "description": "High-quality part for kettle functionality" - }, - { - "id": 4112, - "name": "Kettle Component 2", - "description": "High-quality part for kettle functionality" - }, - { - "id": 4113, - "name": "Kettle Component 3", - "description": "High-quality part for kettle functionality" - }, - { - "id": 4114, - "name": "Kettle Component 4", - "description": "High-quality part for kettle functionality" - }, - { - "id": 4115, - "name": "Kettle Component 5", - "description": "High-quality part for kettle functionality" - } - ], - "images": [ - { - "id": 411, - "url": "https://via.placeholder.com/400x300/0b8b33/ffffff?text=AquaPro+Kettle+901D", - "description": "Kettle product image" - } - ], - "created_at": "2024-03-26T09:16:11.474388Z", - "updated_at": "2025-07-09T09:16:11.474388Z" - }, - { - "id": 412, - "name": "SmartHome Toaster 310E", - "description": "SmartHome Toaster 310E is a high-performance toaster designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 3, - "name": "Personal Care Device" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 3.78, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 29.0, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 17.3, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 855, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 7.8, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 7.5, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 7.2, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 3, - "name": "Copper Wire", - "type": "Metal" - }, - "percentage": 51.7, - "mass": 1.13, - "unit": "kg" - }, - { - "material": { - "id": 5, - "name": "Borosilicate Glass", - "type": "Glass" - }, - "percentage": 48.3, - "mass": 1.22, - "unit": "kg" - } - ], - "components": [ - { - "id": 4121, - "name": "Toaster Component 1", - "description": "High-quality part for toaster functionality" - }, - { - "id": 4122, - "name": "Toaster Component 2", - "description": "High-quality part for toaster functionality" - }, - { - "id": 4123, - "name": "Toaster Component 3", - "description": "High-quality part for toaster functionality" - }, - { - "id": 4124, - "name": "Toaster Component 4", - "description": "High-quality part for toaster functionality" - } - ], - "images": [ - { - "id": 412, - "url": "https://via.placeholder.com/400x300/0d4db9/ffffff?text=SmartHome+Toaster+310E", - "description": "Toaster product image" - } - ], - "created_at": "2024-10-30T09:16:11.474434Z", - "updated_at": "2025-07-21T09:16:11.474434Z" - }, - { - "id": 413, - "name": "EcoTech Iron 639I", - "description": "EcoTech Iron 639I is a high-performance iron designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 1, - "name": "Kitchen Appliance" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 3.61, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 26.4, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 15.4, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 1597, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 7.3, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 8.2, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 7.9, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 1, - "name": "Stainless Steel", - "type": "Metal" - }, - "percentage": 30.4, - "mass": 1.11, - "unit": "kg" - }, - { - "material": { - "id": 3, - "name": "Copper Wire", - "type": "Metal" - }, - "percentage": 25.5, - "mass": 0.83, - "unit": "kg" - }, - { - "material": { - "id": 6, - "name": "Polypropylene", - "type": "Plastic" - }, - "percentage": 44.1, - "mass": 1.37, - "unit": "kg" - } - ], - "components": [ - { - "id": 4131, - "name": "Iron Component 1", - "description": "High-quality part for iron functionality" - }, - { - "id": 4132, - "name": "Iron Component 2", - "description": "High-quality part for iron functionality" - }, - { - "id": 4133, - "name": "Iron Component 3", - "description": "High-quality part for iron functionality" - }, - { - "id": 4134, - "name": "Iron Component 4", - "description": "High-quality part for iron functionality" - }, - { - "id": 4135, - "name": "Iron Component 5", - "description": "High-quality part for iron functionality" - } - ], - "images": [ - { - "id": 413, - "url": "https://via.placeholder.com/400x300/06bb74/ffffff?text=EcoTech+Iron+639I", - "description": "Iron product image" - } - ], - "created_at": "2024-09-06T09:16:11.474511Z", - "updated_at": "2025-05-03T09:16:11.474511Z" - }, - { - "id": 414, - "name": "ZenGear Iron 435D", - "description": "ZenGear Iron 435D is a high-performance iron designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 5, - "name": "Office Equipment" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 2.88, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 33.5, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 22.4, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 1253, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 6.6, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 6.4, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 9.0, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 7, - "name": "Silicone", - "type": "Elastomer" - }, - "percentage": 30.6, - "mass": 0.93, - "unit": "kg" - }, - { - "material": { - "id": 2, - "name": "ABS Plastic", - "type": "Plastic" - }, - "percentage": 20.9, - "mass": 0.6, - "unit": "kg" - }, - { - "material": { - "id": 1, - "name": "Stainless Steel", - "type": "Metal" - }, - "percentage": 21.9, - "mass": 0.8, - "unit": "kg" - }, - { - "material": { - "id": 5, - "name": "Borosilicate Glass", - "type": "Glass" - }, - "percentage": 26.5, - "mass": 0.82, - "unit": "kg" - } - ], - "components": [ - { - "id": 4141, - "name": "Iron Component 1", - "description": "High-quality part for iron functionality" - }, - { - "id": 4142, - "name": "Iron Component 2", - "description": "High-quality part for iron functionality" - } - ], - "images": [ - { - "id": 414, - "url": "https://via.placeholder.com/400x300/02cc71/ffffff?text=ZenGear+Iron+435D", - "description": "Iron product image" - } - ], - "created_at": "2024-11-02T09:16:11.474567Z", - "updated_at": "2025-07-27T09:16:11.474567Z" - }, - { - "id": 415, - "name": "EcoTech Coffee Maker 881G", - "description": "EcoTech Coffee Maker 881G is a high-performance coffee maker designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 1, - "name": "Kitchen Appliance" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 3.38, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 22.2, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 29.7, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 2149, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 8.8, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 6.1, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 9.6, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 2, - "name": "ABS Plastic", - "type": "Plastic" - }, - "percentage": 40.8, - "mass": 0.66, - "unit": "kg" - }, - { - "material": { - "id": 6, - "name": "Polypropylene", - "type": "Plastic" - }, - "percentage": 59.2, - "mass": 1.91, - "unit": "kg" - } - ], - "components": [ - { - "id": 4151, - "name": "Coffee Maker Component 1", - "description": "High-quality part for coffee maker functionality" - }, - { - "id": 4152, - "name": "Coffee Maker Component 2", - "description": "High-quality part for coffee maker functionality" - }, - { - "id": 4153, - "name": "Coffee Maker Component 3", - "description": "High-quality part for coffee maker functionality" - } - ], - "images": [ - { - "id": 415, - "url": "https://via.placeholder.com/400x300/0c44f4/ffffff?text=EcoTech+Coffee+Maker+881G", - "description": "Coffee Maker product image" - } - ], - "created_at": "2024-12-18T09:16:11.474605Z", - "updated_at": "2025-06-12T09:16:11.474605Z" - }, - { - "id": 416, - "name": "PureLife Blender 214I", - "description": "PureLife Blender 214I is a high-performance blender designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 5, - "name": "Office Equipment" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 2.86, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 32.2, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 18.1, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 1465, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 7.3, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 8.3, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 9.3, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 3, - "name": "Copper Wire", - "type": "Metal" - }, - "percentage": 31.1, - "mass": 1.21, - "unit": "kg" - }, - { - "material": { - "id": 5, - "name": "Borosilicate Glass", - "type": "Glass" - }, - "percentage": 23.2, - "mass": 0.66, - "unit": "kg" - }, - { - "material": { - "id": 4, - "name": "Mica", - "type": "Mineral" - }, - "percentage": 37.1, - "mass": 0.39, - "unit": "kg" - }, - { - "material": { - "id": 2, - "name": "ABS Plastic", - "type": "Plastic" - }, - "percentage": 8.6, - "mass": 0.14, - "unit": "kg" - } - ], - "components": [ - { - "id": 4161, - "name": "Blender Component 1", - "description": "High-quality part for blender functionality" - }, - { - "id": 4162, - "name": "Blender Component 2", - "description": "High-quality part for blender functionality" - }, - { - "id": 4163, - "name": "Blender Component 3", - "description": "High-quality part for blender functionality" - }, - { - "id": 4164, - "name": "Blender Component 4", - "description": "High-quality part for blender functionality" - }, - { - "id": 4165, - "name": "Blender Component 5", - "description": "High-quality part for blender functionality" - } - ], - "images": [ - { - "id": 416, - "url": "https://via.placeholder.com/400x300/064489/ffffff?text=PureLife+Blender+214I", - "description": "Blender product image" - } - ], - "created_at": "2024-09-22T09:16:11.474677Z", - "updated_at": "2025-05-30T09:16:11.474677Z" - }, - { - "id": 417, - "name": "ChefMate Monitor 611R", - "description": "ChefMate Monitor 611R is a high-performance monitor designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 3, - "name": "Personal Care Device" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 2.56, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 25.0, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 23.3, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 1280, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 6.8, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 8.0, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 6.5, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 3, - "name": "Copper Wire", - "type": "Metal" - }, - "percentage": 29.5, - "mass": 0.92, - "unit": "kg" - }, - { - "material": { - "id": 6, - "name": "Polypropylene", - "type": "Plastic" - }, - "percentage": 70.5, - "mass": 0.78, - "unit": "kg" - } - ], - "components": [ - { - "id": 4171, - "name": "Monitor Component 1", - "description": "High-quality part for monitor functionality" - }, - { - "id": 4172, - "name": "Monitor Component 2", - "description": "High-quality part for monitor functionality" - } - ], - "images": [ - { - "id": 417, - "url": "https://via.placeholder.com/400x300/0e1aee/ffffff?text=ChefMate+Monitor+611R", - "description": "Monitor product image" - } - ], - "created_at": "2024-06-25T09:16:11.474722Z", - "updated_at": "2025-05-08T09:16:11.474722Z" - }, - { - "id": 418, - "name": "ChefMate Air Purifier 787V", - "description": "ChefMate Air Purifier 787V is a high-performance air purifier designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 3, - "name": "Personal Care Device" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 2.05, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 31.4, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 18.2, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 2059, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 7.7, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 5.4, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 8.5, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 3, - "name": "Copper Wire", - "type": "Metal" - }, - "percentage": 13.7, - "mass": 0.43, - "unit": "kg" - }, - { - "material": { - "id": 4, - "name": "Mica", - "type": "Mineral" - }, - "percentage": 53.7, - "mass": 1.11, - "unit": "kg" - }, - { - "material": { - "id": 2, - "name": "ABS Plastic", - "type": "Plastic" - }, - "percentage": 32.6, - "mass": 0.83, - "unit": "kg" - } - ], - "components": [ - { - "id": 4181, - "name": "Air Purifier Component 1", - "description": "High-quality part for air purifier functionality" - }, - { - "id": 4182, - "name": "Air Purifier Component 2", - "description": "High-quality part for air purifier functionality" - }, - { - "id": 4183, - "name": "Air Purifier Component 3", - "description": "High-quality part for air purifier functionality" - } - ], - "images": [ - { - "id": 418, - "url": "https://via.placeholder.com/400x300/0aaca8/ffffff?text=ChefMate+Air+Purifier+787V", - "description": "Air Purifier product image" - } - ], - "created_at": "2024-09-02T09:16:11.474769Z", - "updated_at": "2025-07-06T09:16:11.474769Z" - }, - { - "id": 419, - "name": "EcoTech Kettle 870P", - "description": "EcoTech Kettle 870P is a high-performance kettle designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 4, - "name": "Smart Home Device" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 2.69, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 30.6, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 25.1, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 2120, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 8.0, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 6.7, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 7.0, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 5, - "name": "Borosilicate Glass", - "type": "Glass" - }, - "percentage": 25.4, - "mass": 0.56, - "unit": "kg" - }, - { - "material": { - "id": 6, - "name": "Polypropylene", - "type": "Plastic" - }, - "percentage": 74.6, - "mass": 2.85, - "unit": "kg" - } - ], - "components": [ - { - "id": 4191, - "name": "Kettle Component 1", - "description": "High-quality part for kettle functionality" - }, - { - "id": 4192, - "name": "Kettle Component 2", - "description": "High-quality part for kettle functionality" - }, - { - "id": 4193, - "name": "Kettle Component 3", - "description": "High-quality part for kettle functionality" - }, - { - "id": 4194, - "name": "Kettle Component 4", - "description": "High-quality part for kettle functionality" - }, - { - "id": 4195, - "name": "Kettle Component 5", - "description": "High-quality part for kettle functionality" - } - ], - "images": [ - { - "id": 419, - "url": "https://via.placeholder.com/400x300/08a405/ffffff?text=EcoTech+Kettle+870P", - "description": "Kettle product image" - } - ], - "created_at": "2024-07-24T09:16:11.474814Z", - "updated_at": "2025-07-27T09:16:11.474814Z" - }, - { - "id": 420, - "name": "EcoTech Rice Cooker 467K", - "description": "EcoTech Rice Cooker 467K is a high-performance rice cooker designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 3, - "name": "Personal Care Device" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 3.78, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 30.2, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 21.3, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 1972, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 6.8, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 5.3, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 7.1, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 6, - "name": "Polypropylene", - "type": "Plastic" - }, - "percentage": 71.1, - "mass": 2.49, - "unit": "kg" - }, - { - "material": { - "id": 4, - "name": "Mica", - "type": "Mineral" - }, - "percentage": 28.9, - "mass": 0.45, - "unit": "kg" - } - ], - "components": [ - { - "id": 4201, - "name": "Rice Cooker Component 1", - "description": "High-quality part for rice cooker functionality" - }, - { - "id": 4202, - "name": "Rice Cooker Component 2", - "description": "High-quality part for rice cooker functionality" - }, - { - "id": 4203, - "name": "Rice Cooker Component 3", - "description": "High-quality part for rice cooker functionality" - } - ], - "images": [ - { - "id": 420, - "url": "https://via.placeholder.com/400x300/0cc027/ffffff?text=EcoTech+Rice+Cooker+467K", - "description": "Rice Cooker product image" - } - ], - "created_at": "2025-01-10T09:16:11.474879Z", - "updated_at": "2025-06-23T09:16:11.474879Z" - }, - { - "id": 421, - "name": "PureLife Rice Cooker 120N", - "description": "PureLife Rice Cooker 120N is a high-performance rice cooker designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 2, - "name": "Home Electronics" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 3.86, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 34.6, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 19.6, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 1374, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 7.3, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 7.2, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 7.4, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 7, - "name": "Silicone", - "type": "Elastomer" - }, - "percentage": 54.1, - "mass": 1.58, - "unit": "kg" - }, - { - "material": { - "id": 3, - "name": "Copper Wire", - "type": "Metal" - }, - "percentage": 45.9, - "mass": 0.78, - "unit": "kg" - } - ], - "components": [ - { - "id": 4211, - "name": "Rice Cooker Component 1", - "description": "High-quality part for rice cooker functionality" - }, - { - "id": 4212, - "name": "Rice Cooker Component 2", - "description": "High-quality part for rice cooker functionality" - }, - { - "id": 4213, - "name": "Rice Cooker Component 3", - "description": "High-quality part for rice cooker functionality" - } - ], - "images": [ - { - "id": 421, - "url": "https://via.placeholder.com/400x300/0670be/ffffff?text=PureLife+Rice+Cooker+120N", - "description": "Rice Cooker product image" - } - ], - "created_at": "2024-12-15T09:16:11.474921Z", - "updated_at": "2025-06-02T09:16:11.474921Z" - }, - { - "id": 422, - "name": "PureLife Humidifier 155E", - "description": "PureLife Humidifier 155E is a high-performance humidifier designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 3, - "name": "Personal Care Device" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 1.55, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 25.5, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 26.1, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 1766, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 7.5, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 6.5, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 7.7, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 3, - "name": "Copper Wire", - "type": "Metal" - }, - "percentage": 34.4, - "mass": 1.32, - "unit": "kg" - }, - { - "material": { - "id": 4, - "name": "Mica", - "type": "Mineral" - }, - "percentage": 36.8, - "mass": 0.71, - "unit": "kg" - }, - { - "material": { - "id": 6, - "name": "Polypropylene", - "type": "Plastic" - }, - "percentage": 28.8, - "mass": 0.75, - "unit": "kg" - } - ], - "components": [ - { - "id": 4221, - "name": "Humidifier Component 1", - "description": "High-quality part for humidifier functionality" - }, - { - "id": 4222, - "name": "Humidifier Component 2", - "description": "High-quality part for humidifier functionality" - }, - { - "id": 4223, - "name": "Humidifier Component 3", - "description": "High-quality part for humidifier functionality" - }, - { - "id": 4224, - "name": "Humidifier Component 4", - "description": "High-quality part for humidifier functionality" - }, - { - "id": 4225, - "name": "Humidifier Component 5", - "description": "High-quality part for humidifier functionality" - } - ], - "images": [ - { - "id": 422, - "url": "https://via.placeholder.com/400x300/06a751/ffffff?text=PureLife+Humidifier+155E", - "description": "Humidifier product image" - } - ], - "created_at": "2024-07-31T09:16:11.474964Z", - "updated_at": "2025-07-09T09:16:11.474964Z" - }, - { - "id": 423, - "name": "EcoTech Kettle 934T", - "description": "EcoTech Kettle 934T is a high-performance kettle designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 3, - "name": "Personal Care Device" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 1.63, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 34.6, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 25.8, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 2062, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 6.2, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 8.4, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 10.0, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 7, - "name": "Silicone", - "type": "Elastomer" - }, - "percentage": 19.0, - "mass": 0.48, - "unit": "kg" - }, - { - "material": { - "id": 3, - "name": "Copper Wire", - "type": "Metal" - }, - "percentage": 20.4, - "mass": 0.66, - "unit": "kg" - }, - { - "material": { - "id": 5, - "name": "Borosilicate Glass", - "type": "Glass" - }, - "percentage": 16.8, - "mass": 0.48, - "unit": "kg" - }, - { - "material": { - "id": 2, - "name": "ABS Plastic", - "type": "Plastic" - }, - "percentage": 43.8, - "mass": 0.67, - "unit": "kg" - } - ], - "components": [ - { - "id": 4231, - "name": "Kettle Component 1", - "description": "High-quality part for kettle functionality" - }, - { - "id": 4232, - "name": "Kettle Component 2", - "description": "High-quality part for kettle functionality" - }, - { - "id": 4233, - "name": "Kettle Component 3", - "description": "High-quality part for kettle functionality" - }, - { - "id": 4234, - "name": "Kettle Component 4", - "description": "High-quality part for kettle functionality" - } - ], - "images": [ - { - "id": 423, - "url": "https://via.placeholder.com/400x300/091036/ffffff?text=EcoTech+Kettle+934T", - "description": "Kettle product image" - } - ], - "created_at": "2024-06-03T09:16:11.475197Z", - "updated_at": "2025-07-31T09:16:11.475197Z" - }, - { - "id": 424, - "name": "ChefMate Toaster 365Y", - "description": "ChefMate Toaster 365Y is a high-performance toaster designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 5, - "name": "Office Equipment" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 2.96, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 28.9, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 19.8, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 1283, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 6.4, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 8.3, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 7.6, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 7, - "name": "Silicone", - "type": "Elastomer" - }, - "percentage": 49.5, - "mass": 1.8, - "unit": "kg" - }, - { - "material": { - "id": 3, - "name": "Copper Wire", - "type": "Metal" - }, - "percentage": 50.5, - "mass": 1.1, - "unit": "kg" - } - ], - "components": [ - { - "id": 4241, - "name": "Toaster Component 1", - "description": "High-quality part for toaster functionality" - }, - { - "id": 4242, - "name": "Toaster Component 2", - "description": "High-quality part for toaster functionality" - }, - { - "id": 4243, - "name": "Toaster Component 3", - "description": "High-quality part for toaster functionality" - }, - { - "id": 4244, - "name": "Toaster Component 4", - "description": "High-quality part for toaster functionality" - } - ], - "images": [ - { - "id": 424, - "url": "https://via.placeholder.com/400x300/0545fb/ffffff?text=ChefMate+Toaster+365Y", - "description": "Toaster product image" - } - ], - "created_at": "2024-04-28T09:16:11.475317Z", - "updated_at": "2025-07-23T09:16:11.475317Z" - }, - { - "id": 425, - "name": "EcoTech Iron 187U", - "description": "EcoTech Iron 187U is a high-performance iron designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 4, - "name": "Smart Home Device" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 3.35, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 34.0, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 15.9, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 1755, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 7.8, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 6.8, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 8.4, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 7, - "name": "Silicone", - "type": "Elastomer" - }, - "percentage": 16.2, - "mass": 0.25, - "unit": "kg" - }, - { - "material": { - "id": 5, - "name": "Borosilicate Glass", - "type": "Glass" - }, - "percentage": 31.3, - "mass": 0.77, - "unit": "kg" - }, - { - "material": { - "id": 6, - "name": "Polypropylene", - "type": "Plastic" - }, - "percentage": 19.0, - "mass": 0.38, - "unit": "kg" - }, - { - "material": { - "id": 1, - "name": "Stainless Steel", - "type": "Metal" - }, - "percentage": 33.5, - "mass": 0.93, - "unit": "kg" - } - ], - "components": [ - { - "id": 4251, - "name": "Iron Component 1", - "description": "High-quality part for iron functionality" - }, - { - "id": 4252, - "name": "Iron Component 2", - "description": "High-quality part for iron functionality" - }, - { - "id": 4253, - "name": "Iron Component 3", - "description": "High-quality part for iron functionality" - } - ], - "images": [ - { - "id": 425, - "url": "https://via.placeholder.com/400x300/0bb191/ffffff?text=EcoTech+Iron+187U", - "description": "Iron product image" - } - ], - "created_at": "2024-09-11T09:16:11.475399Z", - "updated_at": "2025-07-29T09:16:11.475399Z" - }, - { - "id": 426, - "name": "ZenGear Air Purifier 987P", - "description": "ZenGear Air Purifier 987P is a high-performance air purifier designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 3, - "name": "Personal Care Device" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 2.16, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 31.5, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 29.6, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 944, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 6.6, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 8.2, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 7.3, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 3, - "name": "Copper Wire", - "type": "Metal" - }, - "percentage": 28.7, - "mass": 0.91, - "unit": "kg" - }, - { - "material": { - "id": 4, - "name": "Mica", - "type": "Mineral" - }, - "percentage": 17.6, - "mass": 0.54, - "unit": "kg" - }, - { - "material": { - "id": 5, - "name": "Borosilicate Glass", - "type": "Glass" - }, - "percentage": 15.4, - "mass": 0.26, - "unit": "kg" - }, - { - "material": { - "id": 7, - "name": "Silicone", - "type": "Elastomer" - }, - "percentage": 38.2, - "mass": 0.45, - "unit": "kg" - } - ], - "components": [ - { - "id": 4261, - "name": "Air Purifier Component 1", - "description": "High-quality part for air purifier functionality" - }, - { - "id": 4262, - "name": "Air Purifier Component 2", - "description": "High-quality part for air purifier functionality" - }, - { - "id": 4263, - "name": "Air Purifier Component 3", - "description": "High-quality part for air purifier functionality" - }, - { - "id": 4264, - "name": "Air Purifier Component 4", - "description": "High-quality part for air purifier functionality" - }, - { - "id": 4265, - "name": "Air Purifier Component 5", - "description": "High-quality part for air purifier functionality" - } - ], - "images": [ - { - "id": 426, - "url": "https://via.placeholder.com/400x300/02cd55/ffffff?text=ZenGear+Air+Purifier+987P", - "description": "Air Purifier product image" - } - ], - "created_at": "2025-02-27T09:16:11.475469Z", - "updated_at": "2025-07-12T09:16:11.475469Z" - }, - { - "id": 427, - "name": "EcoTech Rice Cooker 648O", - "description": "EcoTech Rice Cooker 648O is a high-performance rice cooker designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 5, - "name": "Office Equipment" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 3.16, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 26.3, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 15.9, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 1747, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 7.5, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 6.8, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 6.8, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 2, - "name": "ABS Plastic", - "type": "Plastic" - }, - "percentage": 51.7, - "mass": 1.88, - "unit": "kg" - }, - { - "material": { - "id": 7, - "name": "Silicone", - "type": "Elastomer" - }, - "percentage": 48.3, - "mass": 1.68, - "unit": "kg" - } - ], - "components": [ - { - "id": 4271, - "name": "Rice Cooker Component 1", - "description": "High-quality part for rice cooker functionality" - }, - { - "id": 4272, - "name": "Rice Cooker Component 2", - "description": "High-quality part for rice cooker functionality" - }, - { - "id": 4273, - "name": "Rice Cooker Component 3", - "description": "High-quality part for rice cooker functionality" - }, - { - "id": 4274, - "name": "Rice Cooker Component 4", - "description": "High-quality part for rice cooker functionality" - }, - { - "id": 4275, - "name": "Rice Cooker Component 5", - "description": "High-quality part for rice cooker functionality" - } - ], - "images": [ - { - "id": 427, - "url": "https://via.placeholder.com/400x300/0f147d/ffffff?text=EcoTech+Rice+Cooker+648O", - "description": "Rice Cooker product image" - } - ], - "created_at": "2024-11-27T09:16:11.475521Z", - "updated_at": "2025-04-30T09:16:11.475521Z" - }, - { - "id": 428, - "name": "CleanWave Air Purifier 135N", - "description": "CleanWave Air Purifier 135N is a high-performance air purifier designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 4, - "name": "Smart Home Device" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 3.68, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 31.8, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 23.1, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 1657, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 6.5, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 5.4, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 6.7, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 4, - "name": "Mica", - "type": "Mineral" - }, - "percentage": 19.8, - "mass": 0.69, - "unit": "kg" - }, - { - "material": { - "id": 2, - "name": "ABS Plastic", - "type": "Plastic" - }, - "percentage": 50.9, - "mass": 1.34, - "unit": "kg" - }, - { - "material": { - "id": 1, - "name": "Stainless Steel", - "type": "Metal" - }, - "percentage": 29.3, - "mass": 0.59, - "unit": "kg" - } - ], - "components": [ - { - "id": 4281, - "name": "Air Purifier Component 1", - "description": "High-quality part for air purifier functionality" - }, - { - "id": 4282, - "name": "Air Purifier Component 2", - "description": "High-quality part for air purifier functionality" - }, - { - "id": 4283, - "name": "Air Purifier Component 3", - "description": "High-quality part for air purifier functionality" - }, - { - "id": 4284, - "name": "Air Purifier Component 4", - "description": "High-quality part for air purifier functionality" - }, - { - "id": 4285, - "name": "Air Purifier Component 5", - "description": "High-quality part for air purifier functionality" - } - ], - "images": [ - { - "id": 428, - "url": "https://via.placeholder.com/400x300/01b0fc/ffffff?text=CleanWave+Air+Purifier+135N", - "description": "Air Purifier product image" - } - ], - "created_at": "2024-12-13T09:16:11.475569Z", - "updated_at": "2025-05-03T09:16:11.475569Z" - }, - { - "id": 429, - "name": "ChefMate Fan 457U", - "description": "ChefMate Fan 457U is a high-performance fan designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 3, - "name": "Personal Care Device" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 3.16, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 22.3, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 15.1, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 1623, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 8.4, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 8.4, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 6.2, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 1, - "name": "Stainless Steel", - "type": "Metal" - }, - "percentage": 14.7, - "mass": 0.29, - "unit": "kg" - }, - { - "material": { - "id": 2, - "name": "ABS Plastic", - "type": "Plastic" - }, - "percentage": 29.3, - "mass": 0.61, - "unit": "kg" - }, - { - "material": { - "id": 4, - "name": "Mica", - "type": "Mineral" - }, - "percentage": 20.0, - "mass": 0.71, - "unit": "kg" - }, - { - "material": { - "id": 7, - "name": "Silicone", - "type": "Elastomer" - }, - "percentage": 36.0, - "mass": 0.42, - "unit": "kg" - } - ], - "components": [ - { - "id": 4291, - "name": "Fan Component 1", - "description": "High-quality part for fan functionality" - }, - { - "id": 4292, - "name": "Fan Component 2", - "description": "High-quality part for fan functionality" - }, - { - "id": 4293, - "name": "Fan Component 3", - "description": "High-quality part for fan functionality" - }, - { - "id": 4294, - "name": "Fan Component 4", - "description": "High-quality part for fan functionality" - }, - { - "id": 4295, - "name": "Fan Component 5", - "description": "High-quality part for fan functionality" - } - ], - "images": [ - { - "id": 429, - "url": "https://via.placeholder.com/400x300/08100e/ffffff?text=ChefMate+Fan+457U", - "description": "Fan product image" - } - ], - "created_at": "2025-02-25T09:16:11.475633Z", - "updated_at": "2025-06-23T09:16:11.475633Z" - }, - { - "id": 430, - "name": "NeoCook Iron 289A", - "description": "NeoCook Iron 289A is a high-performance iron designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 4, - "name": "Smart Home Device" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 1.6, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 22.2, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 23.6, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 2072, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 6.5, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 6.1, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 8.5, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 5, - "name": "Borosilicate Glass", - "type": "Glass" - }, - "percentage": 9.6, - "mass": 0.32, - "unit": "kg" - }, - { - "material": { - "id": 1, - "name": "Stainless Steel", - "type": "Metal" - }, - "percentage": 21.2, - "mass": 0.76, - "unit": "kg" - }, - { - "material": { - "id": 4, - "name": "Mica", - "type": "Mineral" - }, - "percentage": 49.0, - "mass": 0.86, - "unit": "kg" - }, - { - "material": { - "id": 3, - "name": "Copper Wire", - "type": "Metal" - }, - "percentage": 20.2, - "mass": 0.28, - "unit": "kg" - } - ], - "components": [ - { - "id": 4301, - "name": "Iron Component 1", - "description": "High-quality part for iron functionality" - }, - { - "id": 4302, - "name": "Iron Component 2", - "description": "High-quality part for iron functionality" - }, - { - "id": 4303, - "name": "Iron Component 3", - "description": "High-quality part for iron functionality" - } - ], - "images": [ - { - "id": 430, - "url": "https://via.placeholder.com/400x300/0be98b/ffffff?text=NeoCook+Iron+289A", - "description": "Iron product image" - } - ], - "created_at": "2024-11-30T09:16:11.475715Z", - "updated_at": "2025-06-24T09:16:11.475715Z" - }, - { - "id": 431, - "name": "PureLife Kettle 460L", - "description": "PureLife Kettle 460L is a high-performance kettle designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 1, - "name": "Kitchen Appliance" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 2.64, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 21.8, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 29.9, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 1434, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 7.5, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 8.1, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 8.3, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 5, - "name": "Borosilicate Glass", - "type": "Glass" - }, - "percentage": 13.4, - "mass": 0.15, - "unit": "kg" - }, - { - "material": { - "id": 1, - "name": "Stainless Steel", - "type": "Metal" - }, - "percentage": 33.9, - "mass": 1.3, - "unit": "kg" - }, - { - "material": { - "id": 6, - "name": "Polypropylene", - "type": "Plastic" - }, - "percentage": 40.2, - "mass": 1.37, - "unit": "kg" - }, - { - "material": { - "id": 4, - "name": "Mica", - "type": "Mineral" - }, - "percentage": 12.6, - "mass": 0.3, - "unit": "kg" - } - ], - "components": [ - { - "id": 4311, - "name": "Kettle Component 1", - "description": "High-quality part for kettle functionality" - }, - { - "id": 4312, - "name": "Kettle Component 2", - "description": "High-quality part for kettle functionality" - } - ], - "images": [ - { - "id": 431, - "url": "https://via.placeholder.com/400x300/084271/ffffff?text=PureLife+Kettle+460L", - "description": "Kettle product image" - } - ], - "created_at": "2024-09-19T09:16:11.475778Z", - "updated_at": "2025-05-17T09:16:11.475778Z" - }, - { - "id": 432, - "name": "AquaPro Toaster 281P", - "description": "AquaPro Toaster 281P is a high-performance toaster designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 2, - "name": "Home Electronics" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 2.73, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 33.6, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 21.2, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 870, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 6.3, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 8.0, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 7.4, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 4, - "name": "Mica", - "type": "Mineral" - }, - "percentage": 34.2, - "mass": 0.55, - "unit": "kg" - }, - { - "material": { - "id": 5, - "name": "Borosilicate Glass", - "type": "Glass" - }, - "percentage": 28.9, - "mass": 0.66, - "unit": "kg" - }, - { - "material": { - "id": 2, - "name": "ABS Plastic", - "type": "Plastic" - }, - "percentage": 36.8, - "mass": 0.6, - "unit": "kg" - } - ], - "components": [ - { - "id": 4321, - "name": "Toaster Component 1", - "description": "High-quality part for toaster functionality" - }, - { - "id": 4322, - "name": "Toaster Component 2", - "description": "High-quality part for toaster functionality" - }, - { - "id": 4323, - "name": "Toaster Component 3", - "description": "High-quality part for toaster functionality" - }, - { - "id": 4324, - "name": "Toaster Component 4", - "description": "High-quality part for toaster functionality" - }, - { - "id": 4325, - "name": "Toaster Component 5", - "description": "High-quality part for toaster functionality" - } - ], - "images": [ - { - "id": 432, - "url": "https://via.placeholder.com/400x300/077efd/ffffff?text=AquaPro+Toaster+281P", - "description": "Toaster product image" - } - ], - "created_at": "2024-07-12T09:16:11.475843Z", - "updated_at": "2025-05-11T09:16:11.475843Z" - }, - { - "id": 433, - "name": "SmartHome Monitor 901X", - "description": "SmartHome Monitor 901X is a high-performance monitor designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 1, - "name": "Kitchen Appliance" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 3.0, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 20.5, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 22.2, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 1353, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 8.0, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 7.6, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 8.2, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 3, - "name": "Copper Wire", - "type": "Metal" - }, - "percentage": 18.8, - "mass": 0.4, - "unit": "kg" - }, - { - "material": { - "id": 7, - "name": "Silicone", - "type": "Elastomer" - }, - "percentage": 18.8, - "mass": 0.68, - "unit": "kg" - }, - { - "material": { - "id": 2, - "name": "ABS Plastic", - "type": "Plastic" - }, - "percentage": 50.5, - "mass": 1.12, - "unit": "kg" - }, - { - "material": { - "id": 1, - "name": "Stainless Steel", - "type": "Metal" - }, - "percentage": 11.9, - "mass": 0.21, - "unit": "kg" - } - ], - "components": [ - { - "id": 4331, - "name": "Monitor Component 1", - "description": "High-quality part for monitor functionality" - }, - { - "id": 4332, - "name": "Monitor Component 2", - "description": "High-quality part for monitor functionality" - }, - { - "id": 4333, - "name": "Monitor Component 3", - "description": "High-quality part for monitor functionality" - } - ], - "images": [ - { - "id": 433, - "url": "https://via.placeholder.com/400x300/087626/ffffff?text=SmartHome+Monitor+901X", - "description": "Monitor product image" - } - ], - "created_at": "2025-03-06T09:16:11.475897Z", - "updated_at": "2025-07-30T09:16:11.475897Z" - }, - { - "id": 434, - "name": "CleanWave Humidifier 779Q", - "description": "CleanWave Humidifier 779Q is a high-performance humidifier designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 2, - "name": "Home Electronics" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 3.85, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 22.3, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 24.9, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 1038, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 8.3, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 8.7, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 6.1, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 1, - "name": "Stainless Steel", - "type": "Metal" - }, - "percentage": 22.6, - "mass": 0.3, - "unit": "kg" - }, - { - "material": { - "id": 5, - "name": "Borosilicate Glass", - "type": "Glass" - }, - "percentage": 28.4, - "mass": 0.35, - "unit": "kg" - }, - { - "material": { - "id": 2, - "name": "ABS Plastic", - "type": "Plastic" - }, - "percentage": 24.5, - "mass": 0.77, - "unit": "kg" - }, - { - "material": { - "id": 6, - "name": "Polypropylene", - "type": "Plastic" - }, - "percentage": 24.5, - "mass": 0.25, - "unit": "kg" - } - ], - "components": [ - { - "id": 4341, - "name": "Humidifier Component 1", - "description": "High-quality part for humidifier functionality" - }, - { - "id": 4342, - "name": "Humidifier Component 2", - "description": "High-quality part for humidifier functionality" - }, - { - "id": 4343, - "name": "Humidifier Component 3", - "description": "High-quality part for humidifier functionality" - }, - { - "id": 4344, - "name": "Humidifier Component 4", - "description": "High-quality part for humidifier functionality" - }, - { - "id": 4345, - "name": "Humidifier Component 5", - "description": "High-quality part for humidifier functionality" - } - ], - "images": [ - { - "id": 434, - "url": "https://via.placeholder.com/400x300/036e7d/ffffff?text=CleanWave+Humidifier+779Q", - "description": "Humidifier product image" - } - ], - "created_at": "2024-06-24T09:16:11.475966Z", - "updated_at": "2025-05-21T09:16:11.475966Z" - }, - { - "id": 435, - "name": "SmartHome Fan 532N", - "description": "SmartHome Fan 532N is a high-performance fan designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 4, - "name": "Smart Home Device" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 1.69, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 26.4, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 23.4, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 1683, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 7.0, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 6.3, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 8.7, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 7, - "name": "Silicone", - "type": "Elastomer" - }, - "percentage": 47.6, - "mass": 0.67, - "unit": "kg" - }, - { - "material": { - "id": 6, - "name": "Polypropylene", - "type": "Plastic" - }, - "percentage": 22.2, - "mass": 0.48, - "unit": "kg" - }, - { - "material": { - "id": 4, - "name": "Mica", - "type": "Mineral" - }, - "percentage": 30.2, - "mass": 0.45, - "unit": "kg" - } - ], - "components": [ - { - "id": 4351, - "name": "Fan Component 1", - "description": "High-quality part for fan functionality" - }, - { - "id": 4352, - "name": "Fan Component 2", - "description": "High-quality part for fan functionality" - }, - { - "id": 4353, - "name": "Fan Component 3", - "description": "High-quality part for fan functionality" - }, - { - "id": 4354, - "name": "Fan Component 4", - "description": "High-quality part for fan functionality" - } - ], - "images": [ - { - "id": 435, - "url": "https://via.placeholder.com/400x300/09cd55/ffffff?text=SmartHome+Fan+532N", - "description": "Fan product image" - } - ], - "created_at": "2025-04-23T09:16:11.476018Z", - "updated_at": "2025-05-18T09:16:11.476018Z" - }, - { - "id": 436, - "name": "CleanWave Toaster 710M", - "description": "CleanWave Toaster 710M is a high-performance toaster designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 4, - "name": "Smart Home Device" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 2.54, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 32.9, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 23.0, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 1330, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 9.2, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 8.0, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 8.2, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 2, - "name": "ABS Plastic", - "type": "Plastic" - }, - "percentage": 16.2, - "mass": 0.53, - "unit": "kg" - }, - { - "material": { - "id": 6, - "name": "Polypropylene", - "type": "Plastic" - }, - "percentage": 41.9, - "mass": 0.51, - "unit": "kg" - }, - { - "material": { - "id": 3, - "name": "Copper Wire", - "type": "Metal" - }, - "percentage": 41.9, - "mass": 1.39, - "unit": "kg" - } - ], - "components": [ - { - "id": 4361, - "name": "Toaster Component 1", - "description": "High-quality part for toaster functionality" - }, - { - "id": 4362, - "name": "Toaster Component 2", - "description": "High-quality part for toaster functionality" - }, - { - "id": 4363, - "name": "Toaster Component 3", - "description": "High-quality part for toaster functionality" - } - ], - "images": [ - { - "id": 436, - "url": "https://via.placeholder.com/400x300/02d68b/ffffff?text=CleanWave+Toaster+710M", - "description": "Toaster product image" - } - ], - "created_at": "2024-11-16T09:16:11.476074Z", - "updated_at": "2025-05-08T09:16:11.476074Z" - }, - { - "id": 437, - "name": "PureLife Iron 355C", - "description": "PureLife Iron 355C is a high-performance iron designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 4, - "name": "Smart Home Device" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 1.1, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 25.6, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 15.8, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 2087, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 8.6, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 6.5, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 7.6, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 7, - "name": "Silicone", - "type": "Elastomer" - }, - "percentage": 34.0, - "mass": 1.28, - "unit": "kg" - }, - { - "material": { - "id": 1, - "name": "Stainless Steel", - "type": "Metal" - }, - "percentage": 26.7, - "mass": 0.73, - "unit": "kg" - }, - { - "material": { - "id": 5, - "name": "Borosilicate Glass", - "type": "Glass" - }, - "percentage": 39.3, - "mass": 1.42, - "unit": "kg" - } - ], - "components": [ - { - "id": 4371, - "name": "Iron Component 1", - "description": "High-quality part for iron functionality" - }, - { - "id": 4372, - "name": "Iron Component 2", - "description": "High-quality part for iron functionality" - } - ], - "images": [ - { - "id": 437, - "url": "https://via.placeholder.com/400x300/08620d/ffffff?text=PureLife+Iron+355C", - "description": "Iron product image" - } - ], - "created_at": "2025-04-11T09:16:11.476135Z", - "updated_at": "2025-05-19T09:16:11.476135Z" - }, - { - "id": 438, - "name": "EcoTech Toaster 539U", - "description": "EcoTech Toaster 539U is a high-performance toaster designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 5, - "name": "Office Equipment" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 2.5, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 28.3, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 21.2, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 1358, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 8.4, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 5.5, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 9.0, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 2, - "name": "ABS Plastic", - "type": "Plastic" - }, - "percentage": 52.8, - "mass": 1.03, - "unit": "kg" - }, - { - "material": { - "id": 4, - "name": "Mica", - "type": "Mineral" - }, - "percentage": 47.2, - "mass": 1.8, - "unit": "kg" - } - ], - "components": [ - { - "id": 4381, - "name": "Toaster Component 1", - "description": "High-quality part for toaster functionality" - }, - { - "id": 4382, - "name": "Toaster Component 2", - "description": "High-quality part for toaster functionality" - }, - { - "id": 4383, - "name": "Toaster Component 3", - "description": "High-quality part for toaster functionality" - }, - { - "id": 4384, - "name": "Toaster Component 4", - "description": "High-quality part for toaster functionality" - }, - { - "id": 4385, - "name": "Toaster Component 5", - "description": "High-quality part for toaster functionality" - } - ], - "images": [ - { - "id": 438, - "url": "https://via.placeholder.com/400x300/0c9b2b/ffffff?text=EcoTech+Toaster+539U", - "description": "Toaster product image" - } - ], - "created_at": "2024-04-23T09:16:11.476261Z", - "updated_at": "2025-05-24T09:16:11.476261Z" - }, - { - "id": 439, - "name": "SmartHome Rice Cooker 285G", - "description": "SmartHome Rice Cooker 285G is a high-performance rice cooker designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 3, - "name": "Personal Care Device" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 3.53, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 21.8, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 16.5, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 2181, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 7.8, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 7.2, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 6.1, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 7, - "name": "Silicone", - "type": "Elastomer" - }, - "percentage": 17.7, - "mass": 0.46, - "unit": "kg" - }, - { - "material": { - "id": 5, - "name": "Borosilicate Glass", - "type": "Glass" - }, - "percentage": 32.9, - "mass": 0.98, - "unit": "kg" - }, - { - "material": { - "id": 1, - "name": "Stainless Steel", - "type": "Metal" - }, - "percentage": 32.3, - "mass": 0.36, - "unit": "kg" - }, - { - "material": { - "id": 3, - "name": "Copper Wire", - "type": "Metal" - }, - "percentage": 17.1, - "mass": 0.28, - "unit": "kg" - } - ], - "components": [ - { - "id": 4391, - "name": "Rice Cooker Component 1", - "description": "High-quality part for rice cooker functionality" - }, - { - "id": 4392, - "name": "Rice Cooker Component 2", - "description": "High-quality part for rice cooker functionality" - }, - { - "id": 4393, - "name": "Rice Cooker Component 3", - "description": "High-quality part for rice cooker functionality" - }, - { - "id": 4394, - "name": "Rice Cooker Component 4", - "description": "High-quality part for rice cooker functionality" - } - ], - "images": [ - { - "id": 439, - "url": "https://via.placeholder.com/400x300/07ebf1/ffffff?text=SmartHome+Rice+Cooker+285G", - "description": "Rice Cooker product image" - } - ], - "created_at": "2024-06-21T09:16:11.476341Z", - "updated_at": "2025-06-05T09:16:11.476341Z" - }, - { - "id": 440, - "name": "ZenGear Air Purifier 922X", - "description": "ZenGear Air Purifier 922X is a high-performance air purifier designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 2, - "name": "Home Electronics" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 3.93, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 34.3, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 24.9, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 2132, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 7.6, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 7.7, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 7.6, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 6, - "name": "Polypropylene", - "type": "Plastic" - }, - "percentage": 9.6, - "mass": 0.31, - "unit": "kg" - }, - { - "material": { - "id": 1, - "name": "Stainless Steel", - "type": "Metal" - }, - "percentage": 31.8, - "mass": 0.79, - "unit": "kg" - }, - { - "material": { - "id": 5, - "name": "Borosilicate Glass", - "type": "Glass" - }, - "percentage": 31.8, - "mass": 0.92, - "unit": "kg" - }, - { - "material": { - "id": 4, - "name": "Mica", - "type": "Mineral" - }, - "percentage": 26.8, - "mass": 0.42, - "unit": "kg" - } - ], - "components": [ - { - "id": 4401, - "name": "Air Purifier Component 1", - "description": "High-quality part for air purifier functionality" - }, - { - "id": 4402, - "name": "Air Purifier Component 2", - "description": "High-quality part for air purifier functionality" - } - ], - "images": [ - { - "id": 440, - "url": "https://via.placeholder.com/400x300/03ed09/ffffff?text=ZenGear+Air+Purifier+922X", - "description": "Air Purifier product image" - } - ], - "created_at": "2025-03-28T09:16:11.476411Z", - "updated_at": "2025-06-19T09:16:11.476411Z" - }, - { - "id": 441, - "name": "PureLife Fan 359O", - "description": "PureLife Fan 359O is a high-performance fan designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 2, - "name": "Home Electronics" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 1.43, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 29.4, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 21.0, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 1357, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 7.8, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 6.8, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 9.5, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 2, - "name": "ABS Plastic", - "type": "Plastic" - }, - "percentage": 43.4, - "mass": 1.18, - "unit": "kg" - }, - { - "material": { - "id": 3, - "name": "Copper Wire", - "type": "Metal" - }, - "percentage": 46.7, - "mass": 1.85, - "unit": "kg" - }, - { - "material": { - "id": 7, - "name": "Silicone", - "type": "Elastomer" - }, - "percentage": 9.8, - "mass": 0.22, - "unit": "kg" - } - ], - "components": [ - { - "id": 4411, - "name": "Fan Component 1", - "description": "High-quality part for fan functionality" - }, - { - "id": 4412, - "name": "Fan Component 2", - "description": "High-quality part for fan functionality" - }, - { - "id": 4413, - "name": "Fan Component 3", - "description": "High-quality part for fan functionality" - } - ], - "images": [ - { - "id": 441, - "url": "https://via.placeholder.com/400x300/0bf962/ffffff?text=PureLife+Fan+359O", - "description": "Fan product image" - } - ], - "created_at": "2025-02-01T09:16:11.476468Z", - "updated_at": "2025-06-18T09:16:11.476468Z" - }, - { - "id": 442, - "name": "AquaPro Air Purifier 832G", - "description": "AquaPro Air Purifier 832G is a high-performance air purifier designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 3, - "name": "Personal Care Device" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 3.07, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 26.9, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 24.4, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 1964, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 7.1, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 8.6, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 8.8, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 2, - "name": "ABS Plastic", - "type": "Plastic" - }, - "percentage": 33.8, - "mass": 0.39, - "unit": "kg" - }, - { - "material": { - "id": 5, - "name": "Borosilicate Glass", - "type": "Glass" - }, - "percentage": 66.2, - "mass": 0.86, - "unit": "kg" - } - ], - "components": [ - { - "id": 4421, - "name": "Air Purifier Component 1", - "description": "High-quality part for air purifier functionality" - }, - { - "id": 4422, - "name": "Air Purifier Component 2", - "description": "High-quality part for air purifier functionality" - }, - { - "id": 4423, - "name": "Air Purifier Component 3", - "description": "High-quality part for air purifier functionality" - }, - { - "id": 4424, - "name": "Air Purifier Component 4", - "description": "High-quality part for air purifier functionality" - } - ], - "images": [ - { - "id": 442, - "url": "https://via.placeholder.com/400x300/08f9a1/ffffff?text=AquaPro+Air+Purifier+832G", - "description": "Air Purifier product image" - } - ], - "created_at": "2024-11-17T09:16:11.476511Z", - "updated_at": "2025-05-19T09:16:11.476511Z" - }, - { - "id": 443, - "name": "CleanWave Blender 185N", - "description": "CleanWave Blender 185N is a high-performance blender designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 5, - "name": "Office Equipment" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 1.99, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 27.6, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 24.9, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 1667, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 9.2, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 5.3, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 7.7, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 6, - "name": "Polypropylene", - "type": "Plastic" - }, - "percentage": 54.5, - "mass": 1.31, - "unit": "kg" - }, - { - "material": { - "id": 7, - "name": "Silicone", - "type": "Elastomer" - }, - "percentage": 45.5, - "mass": 1.4, - "unit": "kg" - } - ], - "components": [ - { - "id": 4431, - "name": "Blender Component 1", - "description": "High-quality part for blender functionality" - }, - { - "id": 4432, - "name": "Blender Component 2", - "description": "High-quality part for blender functionality" - }, - { - "id": 4433, - "name": "Blender Component 3", - "description": "High-quality part for blender functionality" - }, - { - "id": 4434, - "name": "Blender Component 4", - "description": "High-quality part for blender functionality" - }, - { - "id": 4435, - "name": "Blender Component 5", - "description": "High-quality part for blender functionality" - } - ], - "images": [ - { - "id": 443, - "url": "https://via.placeholder.com/400x300/073b00/ffffff?text=CleanWave+Blender+185N", - "description": "Blender product image" - } - ], - "created_at": "2024-10-18T09:16:11.476570Z", - "updated_at": "2025-05-28T09:16:11.476570Z" - }, - { - "id": 444, - "name": "PureLife Coffee Maker 966X", - "description": "PureLife Coffee Maker 966X is a high-performance coffee maker designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 3, - "name": "Personal Care Device" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 1.75, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 29.6, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 27.5, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 1017, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 7.2, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 8.0, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 7.0, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 5, - "name": "Borosilicate Glass", - "type": "Glass" - }, - "percentage": 33.3, - "mass": 1.15, - "unit": "kg" - }, - { - "material": { - "id": 1, - "name": "Stainless Steel", - "type": "Metal" - }, - "percentage": 25.3, - "mass": 0.76, - "unit": "kg" - }, - { - "material": { - "id": 3, - "name": "Copper Wire", - "type": "Metal" - }, - "percentage": 31.3, - "mass": 1.02, - "unit": "kg" - }, - { - "material": { - "id": 6, - "name": "Polypropylene", - "type": "Plastic" - }, - "percentage": 10.0, - "mass": 0.25, - "unit": "kg" - } - ], - "components": [ - { - "id": 4441, - "name": "Coffee Maker Component 1", - "description": "High-quality part for coffee maker functionality" - }, - { - "id": 4442, - "name": "Coffee Maker Component 2", - "description": "High-quality part for coffee maker functionality" - }, - { - "id": 4443, - "name": "Coffee Maker Component 3", - "description": "High-quality part for coffee maker functionality" - }, - { - "id": 4444, - "name": "Coffee Maker Component 4", - "description": "High-quality part for coffee maker functionality" - }, - { - "id": 4445, - "name": "Coffee Maker Component 5", - "description": "High-quality part for coffee maker functionality" - } - ], - "images": [ - { - "id": 444, - "url": "https://via.placeholder.com/400x300/06a2c2/ffffff?text=PureLife+Coffee+Maker+966X", - "description": "Coffee Maker product image" - } - ], - "created_at": "2024-04-16T09:16:11.476634Z", - "updated_at": "2025-07-16T09:16:11.476634Z" - }, - { - "id": 445, - "name": "AquaPro Kettle 745H", - "description": "AquaPro Kettle 745H is a high-performance kettle designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 1, - "name": "Kitchen Appliance" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 2.43, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 33.6, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 27.1, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 1142, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 6.0, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 7.8, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 6.4, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 4, - "name": "Mica", - "type": "Mineral" - }, - "percentage": 13.2, - "mass": 0.5, - "unit": "kg" - }, - { - "material": { - "id": 7, - "name": "Silicone", - "type": "Elastomer" - }, - "percentage": 46.2, - "mass": 1.67, - "unit": "kg" - }, - { - "material": { - "id": 6, - "name": "Polypropylene", - "type": "Plastic" - }, - "percentage": 11.0, - "mass": 0.19, - "unit": "kg" - }, - { - "material": { - "id": 3, - "name": "Copper Wire", - "type": "Metal" - }, - "percentage": 29.7, - "mass": 1.1, - "unit": "kg" - } - ], - "components": [ - { - "id": 4451, - "name": "Kettle Component 1", - "description": "High-quality part for kettle functionality" - }, - { - "id": 4452, - "name": "Kettle Component 2", - "description": "High-quality part for kettle functionality" - } - ], - "images": [ - { - "id": 445, - "url": "https://via.placeholder.com/400x300/0ee055/ffffff?text=AquaPro+Kettle+745H", - "description": "Kettle product image" - } - ], - "created_at": "2024-06-15T09:16:11.476691Z", - "updated_at": "2025-07-29T09:16:11.476691Z" - }, - { - "id": 446, - "name": "ZenGear Fan 678V", - "description": "ZenGear Fan 678V is a high-performance fan designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 2, - "name": "Home Electronics" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 1.25, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 32.6, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 18.9, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 1730, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 8.1, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 7.8, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 8.0, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 5, - "name": "Borosilicate Glass", - "type": "Glass" - }, - "percentage": 37.0, - "mass": 1.28, - "unit": "kg" - }, - { - "material": { - "id": 4, - "name": "Mica", - "type": "Mineral" - }, - "percentage": 21.7, - "mass": 0.42, - "unit": "kg" - }, - { - "material": { - "id": 3, - "name": "Copper Wire", - "type": "Metal" - }, - "percentage": 41.3, - "mass": 1.49, - "unit": "kg" - } - ], - "components": [ - { - "id": 4461, - "name": "Fan Component 1", - "description": "High-quality part for fan functionality" - }, - { - "id": 4462, - "name": "Fan Component 2", - "description": "High-quality part for fan functionality" - }, - { - "id": 4463, - "name": "Fan Component 3", - "description": "High-quality part for fan functionality" - }, - { - "id": 4464, - "name": "Fan Component 4", - "description": "High-quality part for fan functionality" - }, - { - "id": 4465, - "name": "Fan Component 5", - "description": "High-quality part for fan functionality" - } - ], - "images": [ - { - "id": 446, - "url": "https://via.placeholder.com/400x300/05d429/ffffff?text=ZenGear+Fan+678V", - "description": "Fan product image" - } - ], - "created_at": "2024-11-08T09:16:11.476753Z", - "updated_at": "2025-05-10T09:16:11.476753Z" - }, - { - "id": 447, - "name": "EcoTech Toaster 720C", - "description": "EcoTech Toaster 720C is a high-performance toaster designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 1, - "name": "Kitchen Appliance" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 1.97, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 31.3, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 26.5, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 1057, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 7.8, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 7.7, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 9.1, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 3, - "name": "Copper Wire", - "type": "Metal" - }, - "percentage": 30.9, - "mass": 0.52, - "unit": "kg" - }, - { - "material": { - "id": 5, - "name": "Borosilicate Glass", - "type": "Glass" - }, - "percentage": 27.2, - "mass": 0.4, - "unit": "kg" - }, - { - "material": { - "id": 4, - "name": "Mica", - "type": "Mineral" - }, - "percentage": 23.6, - "mass": 0.38, - "unit": "kg" - }, - { - "material": { - "id": 7, - "name": "Silicone", - "type": "Elastomer" - }, - "percentage": 18.3, - "mass": 0.26, - "unit": "kg" - } - ], - "components": [ - { - "id": 4471, - "name": "Toaster Component 1", - "description": "High-quality part for toaster functionality" - }, - { - "id": 4472, - "name": "Toaster Component 2", - "description": "High-quality part for toaster functionality" - }, - { - "id": 4473, - "name": "Toaster Component 3", - "description": "High-quality part for toaster functionality" - } - ], - "images": [ - { - "id": 447, - "url": "https://via.placeholder.com/400x300/0a3899/ffffff?text=EcoTech+Toaster+720C", - "description": "Toaster product image" - } - ], - "created_at": "2025-03-05T09:16:11.476805Z", - "updated_at": "2025-06-21T09:16:11.476805Z" - }, - { - "id": 448, - "name": "NeoCook Toaster 243Y", - "description": "NeoCook Toaster 243Y is a high-performance toaster designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 4, - "name": "Smart Home Device" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 2.62, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 26.6, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 15.3, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 824, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 8.9, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 8.0, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 7.1, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 4, - "name": "Mica", - "type": "Mineral" - }, - "percentage": 39.2, - "mass": 0.71, - "unit": "kg" - }, - { - "material": { - "id": 1, - "name": "Stainless Steel", - "type": "Metal" - }, - "percentage": 20.0, - "mass": 0.59, - "unit": "kg" - }, - { - "material": { - "id": 3, - "name": "Copper Wire", - "type": "Metal" - }, - "percentage": 40.8, - "mass": 1.27, - "unit": "kg" - } - ], - "components": [ - { - "id": 4481, - "name": "Toaster Component 1", - "description": "High-quality part for toaster functionality" - }, - { - "id": 4482, - "name": "Toaster Component 2", - "description": "High-quality part for toaster functionality" - } - ], - "images": [ - { - "id": 448, - "url": "https://via.placeholder.com/400x300/0c37ce/ffffff?text=NeoCook+Toaster+243Y", - "description": "Toaster product image" - } - ], - "created_at": "2025-01-01T09:16:11.476854Z", - "updated_at": "2025-07-07T09:16:11.476854Z" - }, - { - "id": 449, - "name": "PureLife Blender 497A", - "description": "PureLife Blender 497A is a high-performance blender designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 5, - "name": "Office Equipment" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 2.51, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 31.4, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 28.6, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 2199, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 7.8, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 8.4, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 6.0, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 1, - "name": "Stainless Steel", - "type": "Metal" - }, - "percentage": 69.0, - "mass": 2.25, - "unit": "kg" - }, - { - "material": { - "id": 2, - "name": "ABS Plastic", - "type": "Plastic" - }, - "percentage": 31.0, - "mass": 0.45, - "unit": "kg" - } - ], - "components": [ - { - "id": 4491, - "name": "Blender Component 1", - "description": "High-quality part for blender functionality" - }, - { - "id": 4492, - "name": "Blender Component 2", - "description": "High-quality part for blender functionality" - }, - { - "id": 4493, - "name": "Blender Component 3", - "description": "High-quality part for blender functionality" - } - ], - "images": [ - { - "id": 449, - "url": "https://via.placeholder.com/400x300/0b6726/ffffff?text=PureLife+Blender+497A", - "description": "Blender product image" - } - ], - "created_at": "2025-04-17T09:16:11.476910Z", - "updated_at": "2025-06-14T09:16:11.476910Z" - }, - { - "id": 450, - "name": "EcoTech Kettle 421L", - "description": "EcoTech Kettle 421L is a high-performance kettle designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 3, - "name": "Personal Care Device" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 3.9, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 26.1, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 25.4, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 2084, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 8.8, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 8.3, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 9.2, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 7, - "name": "Silicone", - "type": "Elastomer" - }, - "percentage": 17.2, - "mass": 0.49, - "unit": "kg" - }, - { - "material": { - "id": 3, - "name": "Copper Wire", - "type": "Metal" - }, - "percentage": 21.7, - "mass": 0.65, - "unit": "kg" - }, - { - "material": { - "id": 5, - "name": "Borosilicate Glass", - "type": "Glass" - }, - "percentage": 36.9, - "mass": 1.45, - "unit": "kg" - }, - { - "material": { - "id": 6, - "name": "Polypropylene", - "type": "Plastic" - }, - "percentage": 24.2, - "mass": 0.84, - "unit": "kg" - } - ], - "components": [ - { - "id": 4501, - "name": "Kettle Component 1", - "description": "High-quality part for kettle functionality" - }, - { - "id": 4502, - "name": "Kettle Component 2", - "description": "High-quality part for kettle functionality" - } - ], - "images": [ - { - "id": 450, - "url": "https://via.placeholder.com/400x300/0b449b/ffffff?text=EcoTech+Kettle+421L", - "description": "Kettle product image" - } - ], - "created_at": "2024-04-19T09:16:11.476957Z", - "updated_at": "2025-07-03T09:16:11.476957Z" - }, - { - "id": 451, - "name": "CleanWave Blender 300G", - "description": "CleanWave Blender 300G is a high-performance blender designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 5, - "name": "Office Equipment" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 1.51, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 28.4, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 18.3, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 1628, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 9.0, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 6.3, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 8.2, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 1, - "name": "Stainless Steel", - "type": "Metal" - }, - "percentage": 31.0, - "mass": 0.6, - "unit": "kg" - }, - { - "material": { - "id": 5, - "name": "Borosilicate Glass", - "type": "Glass" - }, - "percentage": 69.0, - "mass": 2.65, - "unit": "kg" - } - ], - "components": [ - { - "id": 4511, - "name": "Blender Component 1", - "description": "High-quality part for blender functionality" - }, - { - "id": 4512, - "name": "Blender Component 2", - "description": "High-quality part for blender functionality" - }, - { - "id": 4513, - "name": "Blender Component 3", - "description": "High-quality part for blender functionality" - }, - { - "id": 4514, - "name": "Blender Component 4", - "description": "High-quality part for blender functionality" - } - ], - "images": [ - { - "id": 451, - "url": "https://via.placeholder.com/400x300/01dd26/ffffff?text=CleanWave+Blender+300G", - "description": "Blender product image" - } - ], - "created_at": "2024-08-22T09:16:11.477006Z", - "updated_at": "2025-06-23T09:16:11.477006Z" - }, - { - "id": 452, - "name": "EcoTech Coffee Maker 155V", - "description": "EcoTech Coffee Maker 155V is a high-performance coffee maker designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 3, - "name": "Personal Care Device" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 2.3, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 28.0, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 20.4, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 1841, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 7.0, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 5.7, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 8.6, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 5, - "name": "Borosilicate Glass", - "type": "Glass" - }, - "percentage": 11.7, - "mass": 0.4, - "unit": "kg" - }, - { - "material": { - "id": 6, - "name": "Polypropylene", - "type": "Plastic" - }, - "percentage": 31.1, - "mass": 0.5, - "unit": "kg" - }, - { - "material": { - "id": 4, - "name": "Mica", - "type": "Mineral" - }, - "percentage": 57.3, - "mass": 2.26, - "unit": "kg" - } - ], - "components": [ - { - "id": 4521, - "name": "Coffee Maker Component 1", - "description": "High-quality part for coffee maker functionality" - }, - { - "id": 4522, - "name": "Coffee Maker Component 2", - "description": "High-quality part for coffee maker functionality" - }, - { - "id": 4523, - "name": "Coffee Maker Component 3", - "description": "High-quality part for coffee maker functionality" - }, - { - "id": 4524, - "name": "Coffee Maker Component 4", - "description": "High-quality part for coffee maker functionality" - } - ], - "images": [ - { - "id": 452, - "url": "https://via.placeholder.com/400x300/061a83/ffffff?text=EcoTech+Coffee+Maker+155V", - "description": "Coffee Maker product image" - } - ], - "created_at": "2024-08-10T09:16:11.477058Z", - "updated_at": "2025-05-19T09:16:11.477058Z" - }, - { - "id": 453, - "name": "NeoCook Rice Cooker 568E", - "description": "NeoCook Rice Cooker 568E is a high-performance rice cooker designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 3, - "name": "Personal Care Device" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 3.54, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 26.0, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 28.0, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 1288, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 9.0, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 6.1, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 8.7, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 3, - "name": "Copper Wire", - "type": "Metal" - }, - "percentage": 27.1, - "mass": 0.71, - "unit": "kg" - }, - { - "material": { - "id": 1, - "name": "Stainless Steel", - "type": "Metal" - }, - "percentage": 25.2, - "mass": 0.95, - "unit": "kg" - }, - { - "material": { - "id": 4, - "name": "Mica", - "type": "Mineral" - }, - "percentage": 27.5, - "mass": 0.86, - "unit": "kg" - }, - { - "material": { - "id": 2, - "name": "ABS Plastic", - "type": "Plastic" - }, - "percentage": 20.2, - "mass": 0.73, - "unit": "kg" - } - ], - "components": [ - { - "id": 4531, - "name": "Rice Cooker Component 1", - "description": "High-quality part for rice cooker functionality" - }, - { - "id": 4532, - "name": "Rice Cooker Component 2", - "description": "High-quality part for rice cooker functionality" - }, - { - "id": 4533, - "name": "Rice Cooker Component 3", - "description": "High-quality part for rice cooker functionality" - }, - { - "id": 4534, - "name": "Rice Cooker Component 4", - "description": "High-quality part for rice cooker functionality" - }, - { - "id": 4535, - "name": "Rice Cooker Component 5", - "description": "High-quality part for rice cooker functionality" - } - ], - "images": [ - { - "id": 453, - "url": "https://via.placeholder.com/400x300/0f2752/ffffff?text=NeoCook+Rice+Cooker+568E", - "description": "Rice Cooker product image" - } - ], - "created_at": "2024-04-12T09:16:11.477115Z", - "updated_at": "2025-04-30T09:16:11.477115Z" - }, - { - "id": 454, - "name": "ZenGear Humidifier 186G", - "description": "ZenGear Humidifier 186G is a high-performance humidifier designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 2, - "name": "Home Electronics" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 2.42, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 34.1, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 20.7, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 1727, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 6.3, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 8.2, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 8.4, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 7, - "name": "Silicone", - "type": "Elastomer" - }, - "percentage": 69.5, - "mass": 1.7, - "unit": "kg" - }, - { - "material": { - "id": 3, - "name": "Copper Wire", - "type": "Metal" - }, - "percentage": 30.5, - "mass": 0.77, - "unit": "kg" - } - ], - "components": [ - { - "id": 4541, - "name": "Humidifier Component 1", - "description": "High-quality part for humidifier functionality" - }, - { - "id": 4542, - "name": "Humidifier Component 2", - "description": "High-quality part for humidifier functionality" - }, - { - "id": 4543, - "name": "Humidifier Component 3", - "description": "High-quality part for humidifier functionality" - }, - { - "id": 4544, - "name": "Humidifier Component 4", - "description": "High-quality part for humidifier functionality" - } - ], - "images": [ - { - "id": 454, - "url": "https://via.placeholder.com/400x300/07f064/ffffff?text=ZenGear+Humidifier+186G", - "description": "Humidifier product image" - } - ], - "created_at": "2025-04-05T09:16:11.477159Z", - "updated_at": "2025-05-20T09:16:11.477159Z" - }, - { - "id": 455, - "name": "EcoTech Iron 315T", - "description": "EcoTech Iron 315T is a high-performance iron designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 2, - "name": "Home Electronics" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 2.94, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 32.7, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 27.0, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 1804, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 7.3, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 8.2, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 9.8, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 4, - "name": "Mica", - "type": "Mineral" - }, - "percentage": 26.0, - "mass": 0.32, - "unit": "kg" - }, - { - "material": { - "id": 5, - "name": "Borosilicate Glass", - "type": "Glass" - }, - "percentage": 34.7, - "mass": 0.9, - "unit": "kg" - }, - { - "material": { - "id": 1, - "name": "Stainless Steel", - "type": "Metal" - }, - "percentage": 39.3, - "mass": 1.02, - "unit": "kg" - } - ], - "components": [ - { - "id": 4551, - "name": "Iron Component 1", - "description": "High-quality part for iron functionality" - }, - { - "id": 4552, - "name": "Iron Component 2", - "description": "High-quality part for iron functionality" - }, - { - "id": 4553, - "name": "Iron Component 3", - "description": "High-quality part for iron functionality" - } - ], - "images": [ - { - "id": 455, - "url": "https://via.placeholder.com/400x300/0e01e7/ffffff?text=EcoTech+Iron+315T", - "description": "Iron product image" - } - ], - "created_at": "2025-02-10T09:16:11.477219Z", - "updated_at": "2025-06-16T09:16:11.477219Z" - }, - { - "id": 456, - "name": "PureLife Rice Cooker 170F", - "description": "PureLife Rice Cooker 170F is a high-performance rice cooker designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 5, - "name": "Office Equipment" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 1.05, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 26.2, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 22.4, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 2053, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 7.9, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 7.4, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 7.5, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 3, - "name": "Copper Wire", - "type": "Metal" - }, - "percentage": 33.8, - "mass": 0.57, - "unit": "kg" - }, - { - "material": { - "id": 2, - "name": "ABS Plastic", - "type": "Plastic" - }, - "percentage": 16.2, - "mass": 0.19, - "unit": "kg" - }, - { - "material": { - "id": 4, - "name": "Mica", - "type": "Mineral" - }, - "percentage": 50.0, - "mass": 1.01, - "unit": "kg" - } - ], - "components": [ - { - "id": 4561, - "name": "Rice Cooker Component 1", - "description": "High-quality part for rice cooker functionality" - }, - { - "id": 4562, - "name": "Rice Cooker Component 2", - "description": "High-quality part for rice cooker functionality" - }, - { - "id": 4563, - "name": "Rice Cooker Component 3", - "description": "High-quality part for rice cooker functionality" - }, - { - "id": 4564, - "name": "Rice Cooker Component 4", - "description": "High-quality part for rice cooker functionality" - }, - { - "id": 4565, - "name": "Rice Cooker Component 5", - "description": "High-quality part for rice cooker functionality" - } - ], - "images": [ - { - "id": 456, - "url": "https://via.placeholder.com/400x300/0f326d/ffffff?text=PureLife+Rice+Cooker+170F", - "description": "Rice Cooker product image" - } - ], - "created_at": "2025-03-09T09:16:11.477266Z", - "updated_at": "2025-05-13T09:16:11.477266Z" - }, - { - "id": 457, - "name": "ZenGear Blender 780C", - "description": "ZenGear Blender 780C is a high-performance blender designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 5, - "name": "Office Equipment" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 3.14, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 25.8, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 20.5, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 1230, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 6.8, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 6.8, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 6.0, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 6, - "name": "Polypropylene", - "type": "Plastic" - }, - "percentage": 71.2, - "mass": 1.89, - "unit": "kg" - }, - { - "material": { - "id": 7, - "name": "Silicone", - "type": "Elastomer" - }, - "percentage": 28.8, - "mass": 0.33, - "unit": "kg" - } - ], - "components": [ - { - "id": 4571, - "name": "Blender Component 1", - "description": "High-quality part for blender functionality" - }, - { - "id": 4572, - "name": "Blender Component 2", - "description": "High-quality part for blender functionality" - }, - { - "id": 4573, - "name": "Blender Component 3", - "description": "High-quality part for blender functionality" - } - ], - "images": [ - { - "id": 457, - "url": "https://via.placeholder.com/400x300/070d39/ffffff?text=ZenGear+Blender+780C", - "description": "Blender product image" - } - ], - "created_at": "2024-09-13T09:16:11.477320Z", - "updated_at": "2025-04-29T09:16:11.477320Z" - }, - { - "id": 458, - "name": "EcoTech Kettle 891Z", - "description": "EcoTech Kettle 891Z is a high-performance kettle designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 1, - "name": "Kitchen Appliance" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 1.46, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 34.2, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 18.3, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 1452, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 7.2, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 5.3, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 8.3, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 1, - "name": "Stainless Steel", - "type": "Metal" - }, - "percentage": 10.8, - "mass": 0.23, - "unit": "kg" - }, - { - "material": { - "id": 5, - "name": "Borosilicate Glass", - "type": "Glass" - }, - "percentage": 14.4, - "mass": 0.19, - "unit": "kg" - }, - { - "material": { - "id": 3, - "name": "Copper Wire", - "type": "Metal" - }, - "percentage": 32.4, - "mass": 0.37, - "unit": "kg" - }, - { - "material": { - "id": 6, - "name": "Polypropylene", - "type": "Plastic" - }, - "percentage": 42.3, - "mass": 0.99, - "unit": "kg" - } - ], - "components": [ - { - "id": 4581, - "name": "Kettle Component 1", - "description": "High-quality part for kettle functionality" - }, - { - "id": 4582, - "name": "Kettle Component 2", - "description": "High-quality part for kettle functionality" - } - ], - "images": [ - { - "id": 458, - "url": "https://via.placeholder.com/400x300/029982/ffffff?text=EcoTech+Kettle+891Z", - "description": "Kettle product image" - } - ], - "created_at": "2025-03-13T09:16:11.477371Z", - "updated_at": "2025-07-20T09:16:11.477371Z" - }, - { - "id": 459, - "name": "CleanWave Coffee Maker 655L", - "description": "CleanWave Coffee Maker 655L is a high-performance coffee maker designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 4, - "name": "Smart Home Device" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 2.85, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 20.6, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 20.5, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 1232, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 6.6, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 7.2, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 8.9, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 7, - "name": "Silicone", - "type": "Elastomer" - }, - "percentage": 26.4, - "mass": 0.74, - "unit": "kg" - }, - { - "material": { - "id": 5, - "name": "Borosilicate Glass", - "type": "Glass" - }, - "percentage": 50.9, - "mass": 1.5, - "unit": "kg" - }, - { - "material": { - "id": 3, - "name": "Copper Wire", - "type": "Metal" - }, - "percentage": 22.6, - "mass": 0.44, - "unit": "kg" - } - ], - "components": [ - { - "id": 4591, - "name": "Coffee Maker Component 1", - "description": "High-quality part for coffee maker functionality" - }, - { - "id": 4592, - "name": "Coffee Maker Component 2", - "description": "High-quality part for coffee maker functionality" - } - ], - "images": [ - { - "id": 459, - "url": "https://via.placeholder.com/400x300/05470f/ffffff?text=CleanWave+Coffee+Maker+655L", - "description": "Coffee Maker product image" - } - ], - "created_at": "2025-03-18T09:16:11.477427Z", - "updated_at": "2025-05-30T09:16:11.477427Z" - }, - { - "id": 460, - "name": "NeoCook Iron 823D", - "description": "NeoCook Iron 823D is a high-performance iron designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 5, - "name": "Office Equipment" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 1.98, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 26.3, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 28.4, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 1364, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 7.4, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 8.4, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 9.0, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 2, - "name": "ABS Plastic", - "type": "Plastic" - }, - "percentage": 40.8, - "mass": 0.76, - "unit": "kg" - }, - { - "material": { - "id": 3, - "name": "Copper Wire", - "type": "Metal" - }, - "percentage": 41.5, - "mass": 1.54, - "unit": "kg" - }, - { - "material": { - "id": 7, - "name": "Silicone", - "type": "Elastomer" - }, - "percentage": 7.7, - "mass": 0.19, - "unit": "kg" - }, - { - "material": { - "id": 1, - "name": "Stainless Steel", - "type": "Metal" - }, - "percentage": 9.9, - "mass": 0.3, - "unit": "kg" - } - ], - "components": [ - { - "id": 4601, - "name": "Iron Component 1", - "description": "High-quality part for iron functionality" - }, - { - "id": 4602, - "name": "Iron Component 2", - "description": "High-quality part for iron functionality" - }, - { - "id": 4603, - "name": "Iron Component 3", - "description": "High-quality part for iron functionality" - }, - { - "id": 4604, - "name": "Iron Component 4", - "description": "High-quality part for iron functionality" - } - ], - "images": [ - { - "id": 460, - "url": "https://via.placeholder.com/400x300/0b962a/ffffff?text=NeoCook+Iron+823D", - "description": "Iron product image" - } - ], - "created_at": "2024-09-19T09:16:11.477485Z", - "updated_at": "2025-07-04T09:16:11.477485Z" - }, - { - "id": 461, - "name": "SmartHome Air Purifier 791E", - "description": "SmartHome Air Purifier 791E is a high-performance air purifier designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 2, - "name": "Home Electronics" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 3.4, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 23.7, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 17.8, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 1403, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 6.8, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 8.5, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 8.8, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 6, - "name": "Polypropylene", - "type": "Plastic" - }, - "percentage": 23.3, - "mass": 0.88, - "unit": "kg" - }, - { - "material": { - "id": 1, - "name": "Stainless Steel", - "type": "Metal" - }, - "percentage": 76.7, - "mass": 1.54, - "unit": "kg" - } - ], - "components": [ - { - "id": 4611, - "name": "Air Purifier Component 1", - "description": "High-quality part for air purifier functionality" - }, - { - "id": 4612, - "name": "Air Purifier Component 2", - "description": "High-quality part for air purifier functionality" - }, - { - "id": 4613, - "name": "Air Purifier Component 3", - "description": "High-quality part for air purifier functionality" - } - ], - "images": [ - { - "id": 461, - "url": "https://via.placeholder.com/400x300/03ea2a/ffffff?text=SmartHome+Air+Purifier+791E", - "description": "Air Purifier product image" - } - ], - "created_at": "2025-01-14T09:16:11.477537Z", - "updated_at": "2025-07-26T09:16:11.477537Z" - }, - { - "id": 462, - "name": "AquaPro Fan 807U", - "description": "AquaPro Fan 807U is a high-performance fan designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 1, - "name": "Kitchen Appliance" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 3.57, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 29.5, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 23.1, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 1872, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 7.3, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 6.6, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 8.0, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 5, - "name": "Borosilicate Glass", - "type": "Glass" - }, - "percentage": 28.1, - "mass": 1.11, - "unit": "kg" - }, - { - "material": { - "id": 3, - "name": "Copper Wire", - "type": "Metal" - }, - "percentage": 25.0, - "mass": 0.75, - "unit": "kg" - }, - { - "material": { - "id": 1, - "name": "Stainless Steel", - "type": "Metal" - }, - "percentage": 31.2, - "mass": 1.24, - "unit": "kg" - }, - { - "material": { - "id": 6, - "name": "Polypropylene", - "type": "Plastic" - }, - "percentage": 15.6, - "mass": 0.45, - "unit": "kg" - } - ], - "components": [ - { - "id": 4621, - "name": "Fan Component 1", - "description": "High-quality part for fan functionality" - }, - { - "id": 4622, - "name": "Fan Component 2", - "description": "High-quality part for fan functionality" - }, - { - "id": 4623, - "name": "Fan Component 3", - "description": "High-quality part for fan functionality" - }, - { - "id": 4624, - "name": "Fan Component 4", - "description": "High-quality part for fan functionality" - }, - { - "id": 4625, - "name": "Fan Component 5", - "description": "High-quality part for fan functionality" - } - ], - "images": [ - { - "id": 462, - "url": "https://via.placeholder.com/400x300/063653/ffffff?text=AquaPro+Fan+807U", - "description": "Fan product image" - } - ], - "created_at": "2024-12-13T09:16:11.477595Z", - "updated_at": "2025-04-27T09:16:11.477595Z" - }, - { - "id": 463, - "name": "ChefMate Air Purifier 355V", - "description": "ChefMate Air Purifier 355V is a high-performance air purifier designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 1, - "name": "Kitchen Appliance" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 3.02, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 22.6, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 18.3, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 915, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 9.2, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 6.3, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 7.2, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 6, - "name": "Polypropylene", - "type": "Plastic" - }, - "percentage": 41.2, - "mass": 1.03, - "unit": "kg" - }, - { - "material": { - "id": 4, - "name": "Mica", - "type": "Mineral" - }, - "percentage": 33.8, - "mass": 0.7, - "unit": "kg" - }, - { - "material": { - "id": 7, - "name": "Silicone", - "type": "Elastomer" - }, - "percentage": 25.0, - "mass": 0.65, - "unit": "kg" - } - ], - "components": [ - { - "id": 4631, - "name": "Air Purifier Component 1", - "description": "High-quality part for air purifier functionality" - }, - { - "id": 4632, - "name": "Air Purifier Component 2", - "description": "High-quality part for air purifier functionality" - }, - { - "id": 4633, - "name": "Air Purifier Component 3", - "description": "High-quality part for air purifier functionality" - }, - { - "id": 4634, - "name": "Air Purifier Component 4", - "description": "High-quality part for air purifier functionality" - } - ], - "images": [ - { - "id": 463, - "url": "https://via.placeholder.com/400x300/05b042/ffffff?text=ChefMate+Air+Purifier+355V", - "description": "Air Purifier product image" - } - ], - "created_at": "2025-02-27T09:16:11.477641Z", - "updated_at": "2025-05-30T09:16:11.477641Z" - }, - { - "id": 464, - "name": "ChefMate Iron 529H", - "description": "ChefMate Iron 529H is a high-performance iron designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 1, - "name": "Kitchen Appliance" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 2.67, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 29.2, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 27.1, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 1102, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 6.8, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 7.4, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 7.2, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 6, - "name": "Polypropylene", - "type": "Plastic" - }, - "percentage": 53.1, - "mass": 1.48, - "unit": "kg" - }, - { - "material": { - "id": 3, - "name": "Copper Wire", - "type": "Metal" - }, - "percentage": 46.9, - "mass": 1.68, - "unit": "kg" - } - ], - "components": [ - { - "id": 4641, - "name": "Iron Component 1", - "description": "High-quality part for iron functionality" - }, - { - "id": 4642, - "name": "Iron Component 2", - "description": "High-quality part for iron functionality" - }, - { - "id": 4643, - "name": "Iron Component 3", - "description": "High-quality part for iron functionality" - } - ], - "images": [ - { - "id": 464, - "url": "https://via.placeholder.com/400x300/02967a/ffffff?text=ChefMate+Iron+529H", - "description": "Iron product image" - } - ], - "created_at": "2024-07-21T09:16:11.477693Z", - "updated_at": "2025-07-07T09:16:11.477693Z" - }, - { - "id": 465, - "name": "CleanWave Rice Cooker 115N", - "description": "CleanWave Rice Cooker 115N is a high-performance rice cooker designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 4, - "name": "Smart Home Device" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 3.64, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 26.8, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 26.7, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 1949, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 7.3, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 5.6, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 8.9, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 5, - "name": "Borosilicate Glass", - "type": "Glass" - }, - "percentage": 75.0, - "mass": 2.68, - "unit": "kg" - }, - { - "material": { - "id": 2, - "name": "ABS Plastic", - "type": "Plastic" - }, - "percentage": 25.0, - "mass": 0.91, - "unit": "kg" - } - ], - "components": [ - { - "id": 4651, - "name": "Rice Cooker Component 1", - "description": "High-quality part for rice cooker functionality" - }, - { - "id": 4652, - "name": "Rice Cooker Component 2", - "description": "High-quality part for rice cooker functionality" - }, - { - "id": 4653, - "name": "Rice Cooker Component 3", - "description": "High-quality part for rice cooker functionality" - }, - { - "id": 4654, - "name": "Rice Cooker Component 4", - "description": "High-quality part for rice cooker functionality" - }, - { - "id": 4655, - "name": "Rice Cooker Component 5", - "description": "High-quality part for rice cooker functionality" - } - ], - "images": [ - { - "id": 465, - "url": "https://via.placeholder.com/400x300/0d635d/ffffff?text=CleanWave+Rice+Cooker+115N", - "description": "Rice Cooker product image" - } - ], - "created_at": "2024-05-12T09:16:11.477737Z", - "updated_at": "2025-07-09T09:16:11.477737Z" - }, - { - "id": 466, - "name": "PureLife Coffee Maker 908L", - "description": "PureLife Coffee Maker 908L is a high-performance coffee maker designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 3, - "name": "Personal Care Device" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 2.18, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 25.5, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 20.0, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 1209, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 6.2, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 8.0, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 9.4, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 1, - "name": "Stainless Steel", - "type": "Metal" - }, - "percentage": 33.8, - "mass": 0.82, - "unit": "kg" - }, - { - "material": { - "id": 7, - "name": "Silicone", - "type": "Elastomer" - }, - "percentage": 66.2, - "mass": 1.98, - "unit": "kg" - } - ], - "components": [ - { - "id": 4661, - "name": "Coffee Maker Component 1", - "description": "High-quality part for coffee maker functionality" - }, - { - "id": 4662, - "name": "Coffee Maker Component 2", - "description": "High-quality part for coffee maker functionality" - }, - { - "id": 4663, - "name": "Coffee Maker Component 3", - "description": "High-quality part for coffee maker functionality" - }, - { - "id": 4664, - "name": "Coffee Maker Component 4", - "description": "High-quality part for coffee maker functionality" - }, - { - "id": 4665, - "name": "Coffee Maker Component 5", - "description": "High-quality part for coffee maker functionality" - } - ], - "images": [ - { - "id": 466, - "url": "https://via.placeholder.com/400x300/051590/ffffff?text=PureLife+Coffee+Maker+908L", - "description": "Coffee Maker product image" - } - ], - "created_at": "2024-03-21T09:16:11.477795Z", - "updated_at": "2025-07-02T09:16:11.477795Z" - }, - { - "id": 467, - "name": "CleanWave Humidifier 336J", - "description": "CleanWave Humidifier 336J is a high-performance humidifier designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 2, - "name": "Home Electronics" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 1.65, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 34.7, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 28.6, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 833, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 7.6, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 5.9, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 8.6, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 3, - "name": "Copper Wire", - "type": "Metal" - }, - "percentage": 25.5, - "mass": 0.79, - "unit": "kg" - }, - { - "material": { - "id": 6, - "name": "Polypropylene", - "type": "Plastic" - }, - "percentage": 38.2, - "mass": 0.93, - "unit": "kg" - }, - { - "material": { - "id": 2, - "name": "ABS Plastic", - "type": "Plastic" - }, - "percentage": 36.4, - "mass": 0.81, - "unit": "kg" - } - ], - "components": [ - { - "id": 4671, - "name": "Humidifier Component 1", - "description": "High-quality part for humidifier functionality" - }, - { - "id": 4672, - "name": "Humidifier Component 2", - "description": "High-quality part for humidifier functionality" - }, - { - "id": 4673, - "name": "Humidifier Component 3", - "description": "High-quality part for humidifier functionality" - } - ], - "images": [ - { - "id": 467, - "url": "https://via.placeholder.com/400x300/02e324/ffffff?text=CleanWave+Humidifier+336J", - "description": "Humidifier product image" - } - ], - "created_at": "2024-10-29T09:16:11.477849Z", - "updated_at": "2025-07-14T09:16:11.477849Z" - }, - { - "id": 468, - "name": "ZenGear Kettle 160L", - "description": "ZenGear Kettle 160L is a high-performance kettle designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 3, - "name": "Personal Care Device" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 3.26, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 26.2, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 21.4, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 1922, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 9.5, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 8.3, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 6.1, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 1, - "name": "Stainless Steel", - "type": "Metal" - }, - "percentage": 20.4, - "mass": 0.56, - "unit": "kg" - }, - { - "material": { - "id": 2, - "name": "ABS Plastic", - "type": "Plastic" - }, - "percentage": 20.9, - "mass": 0.61, - "unit": "kg" - }, - { - "material": { - "id": 3, - "name": "Copper Wire", - "type": "Metal" - }, - "percentage": 30.6, - "mass": 0.95, - "unit": "kg" - }, - { - "material": { - "id": 4, - "name": "Mica", - "type": "Mineral" - }, - "percentage": 28.1, - "mass": 0.99, - "unit": "kg" - } - ], - "components": [ - { - "id": 4681, - "name": "Kettle Component 1", - "description": "High-quality part for kettle functionality" - }, - { - "id": 4682, - "name": "Kettle Component 2", - "description": "High-quality part for kettle functionality" - }, - { - "id": 4683, - "name": "Kettle Component 3", - "description": "High-quality part for kettle functionality" - }, - { - "id": 4684, - "name": "Kettle Component 4", - "description": "High-quality part for kettle functionality" - } - ], - "images": [ - { - "id": 468, - "url": "https://via.placeholder.com/400x300/0be076/ffffff?text=ZenGear+Kettle+160L", - "description": "Kettle product image" - } - ], - "created_at": "2024-09-09T09:16:11.477905Z", - "updated_at": "2025-05-21T09:16:11.477905Z" - }, - { - "id": 469, - "name": "CleanWave Iron 879A", - "description": "CleanWave Iron 879A is a high-performance iron designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 4, - "name": "Smart Home Device" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 2.39, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 31.0, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 22.0, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 1804, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 6.2, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 7.0, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 9.5, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 7, - "name": "Silicone", - "type": "Elastomer" - }, - "percentage": 16.0, - "mass": 0.27, - "unit": "kg" - }, - { - "material": { - "id": 2, - "name": "ABS Plastic", - "type": "Plastic" - }, - "percentage": 31.2, - "mass": 0.86, - "unit": "kg" - }, - { - "material": { - "id": 5, - "name": "Borosilicate Glass", - "type": "Glass" - }, - "percentage": 12.5, - "mass": 0.29, - "unit": "kg" - }, - { - "material": { - "id": 6, - "name": "Polypropylene", - "type": "Plastic" - }, - "percentage": 40.3, - "mass": 0.64, - "unit": "kg" - } - ], - "components": [ - { - "id": 4691, - "name": "Iron Component 1", - "description": "High-quality part for iron functionality" - }, - { - "id": 4692, - "name": "Iron Component 2", - "description": "High-quality part for iron functionality" - } - ], - "images": [ - { - "id": 469, - "url": "https://via.placeholder.com/400x300/0695b3/ffffff?text=CleanWave+Iron+879A", - "description": "Iron product image" - } - ], - "created_at": "2025-02-03T09:16:11.477957Z", - "updated_at": "2025-07-07T09:16:11.477957Z" - }, - { - "id": 470, - "name": "EcoTech Toaster 210H", - "description": "EcoTech Toaster 210H is a high-performance toaster designed for modern households, featuring advanced controls and energy-efficient components.", - "product_type": { - "id": 4, - "name": "Smart Home Device" - }, - "physical_properties": [ - { - "property_name": "Weight", - "value": 2.84, - "unit": "kg" - }, - { - "property_name": "Height", - "value": 32.5, - "unit": "cm" - }, - { - "property_name": "Width", - "value": 18.5, - "unit": "cm" - }, - { - "property_name": "Power", - "value": 1042, - "unit": "W" - } - ], - "circularity_properties": [ - { - "property_name": "Recyclability Score", - "value": 6.7, - "unit": "/10" - }, - { - "property_name": "Repairability Score", - "value": 9.0, - "unit": "/10" - }, - { - "property_name": "Energy Efficiency", - "value": 7.8, - "unit": "/10" - } - ], - "bill_of_materials": [ - { - "material": { - "id": 7, - "name": "Silicone", - "type": "Elastomer" - }, - "percentage": 34.7, - "mass": 1.34, - "unit": "kg" - }, - { - "material": { - "id": 6, - "name": "Polypropylene", - "type": "Plastic" - }, - "percentage": 27.1, - "mass": 0.89, - "unit": "kg" - }, - { - "material": { - "id": 4, - "name": "Mica", - "type": "Mineral" - }, - "percentage": 24.7, - "mass": 0.4, - "unit": "kg" - }, - { - "material": { - "id": 2, - "name": "ABS Plastic", - "type": "Plastic" - }, - "percentage": 13.5, - "mass": 0.41, - "unit": "kg" - } - ], - "components": [ - { - "id": 4701, - "name": "Toaster Component 1", - "description": "High-quality part for toaster functionality" - }, - { - "id": 4702, - "name": "Toaster Component 2", - "description": "High-quality part for toaster functionality" - }, - { - "id": 4703, - "name": "Toaster Component 3", - "description": "High-quality part for toaster functionality" - } - ], - "images": [ - { - "id": 470, - "url": "https://via.placeholder.com/400x300/01f0e0/ffffff?text=EcoTech+Toaster+210H", - "description": "Toaster product image" - } - ], - "created_at": "2025-04-08T09:16:11.478016Z", - "updated_at": "2025-04-28T09:16:11.478016Z" - }, - ] -} diff --git a/frontend-app/src/assets/data/products.json b/frontend-app/src/assets/data/products.json deleted file mode 100644 index 9fcc26d..0000000 --- a/frontend-app/src/assets/data/products.json +++ /dev/null @@ -1,109 +0,0 @@ -{ - "1": - { - "created_at": "2025-06-30T11:02:56.661198Z", - "updated_at": "2025-06-30T11:02:56.661198Z", - "name": "iPhone 12", - "description": "Apple smartphone.", - "brand": "Apple", - "model": "A2403", - "id": 1, - "physical_properties": { - "created_at": "2025-06-30T11:02:56Z", - "updated_at": "2025-06-30T11:02:56Z", - "weight_kg": 0.164, - "height_cm": 14.7, - "width_cm": 7.15, - "depth_cm": 0.74, - "id": 1, - "volume_cm3": 77.777 - }, - "product_type": { - "id": 1, - "name": "32250000-0", - "description": "Mobile telephones" - }, - "images": [{ - "id": 1, - "image_url": "https://reebelo.com/_next/image?url=https%3A%2F%2Fcdn.reebelo.com%2Fpim%2Fproducts%2FP-IPHONE12MINI%2FBLA-image-0.jpg&w=256&q=75", - "description": "iPhone 12 Image" - }], - "videos": [], - "files": [], - "bill_of_materials": [], - "components": [] - }, - "2": - { - "created_at": "2025-06-30T11:02:56.693608Z", - "updated_at": "2025-06-30T11:02:56.693608Z", - "name": "Dell XPS 13", - "description": "Dell laptop.", - "brand": "Dell", - "model": "XPS9380", - "dismantling_notes": null, - "dismantling_time_start": "2025-06-30T11:02:56Z", - "dismantling_time_end": null, - "id": 2, - "physical_properties": { - "created_at": "2025-06-30T11:02:56Z", - "updated_at": "2025-06-30T11:02:56Z", - "weight_kg": 0.164, - "height_cm": 14.7, - "width_cm": 7.15, - "depth_cm": 0.74, - "id": 1, - "volume_cm3": 77.777 - }, - "product_type": { - "id": 1, - "name": "32250000-0", - "description": "Mobile telephones" - }, - "images": [], - "videos": [], - "files": [], - "bill_of_materials": [], - "components": [ - { - "id": 3, - "name": "Screen Assembly", - "description": "LED 4k Touch screen assembly" - } - ] - }, - "3": - { - "created_at": "2025-06-30T11:02:56.693608Z", - "updated_at": "2025-06-30T11:02:56.693608Z", - "name": "Screen Assembly", - "description": "LED 4k Touch screen assembly", - "brand": "Dell", - "model": "bb-asd4-123234", - "dismantling_notes": null, - "dismantling_time_start": "2025-06-30T11:02:56Z", - "dismantling_time_end": null, - "id": 3, - "product_type_id": 2, - "physical_properties": { - "created_at": "2025-06-30T11:02:56Z", - "updated_at": "2025-06-30T11:02:56Z", - "weight_kg": 0.164, - "height_cm": 14.7, - "width_cm": 7.15, - "depth_cm": 0.74, - "id": 1, - "volume_cm3": 77.777 - }, - "product_type": { - "id": 1, - "name": "32250000-0", - "description": "Mobile telephones" - }, - "images": [], - "videos": [], - "files": [], - "bill_of_materials": [], - "components": [] - } -} From 793b2a5e76037d4ac492976e596efb298ac02b51 Mon Sep 17 00:00:00 2001 From: Simon van Lierde Date: Tue, 21 Oct 2025 13:47:37 +0200 Subject: [PATCH 04/71] fix(backend): Don't seed dummy data by default --- backend/scripts/seed/migrations_entrypoint.sh | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/backend/scripts/seed/migrations_entrypoint.sh b/backend/scripts/seed/migrations_entrypoint.sh index e48e483..9cc678c 100755 --- a/backend/scripts/seed/migrations_entrypoint.sh +++ b/backend/scripts/seed/migrations_entrypoint.sh @@ -23,6 +23,7 @@ fi if [ "$SEED_PRODUCT_TYPES" = "true" ]; then echo "Seeding product types..." .venv/bin/python -m scripts.seed.taxonomies.cpv --seed-product-types + fi # Check if all tables are empty @@ -31,7 +32,7 @@ echo "Checking if all tables in the database are empty using scripts/db_is_empty # Run the script and temporarily disable exit-on-error to capture the exit code DB_EMPTY=$(.venv/bin/python -m scripts.db_is_empty) -if [ "$DB_EMPTY" = "TRUE" ]; then +if [ "$DB_EMPTY" = "TRUE" ] && [ "$SEED_DUMMY_DATA" = "true" ]; then echo "All tables are empty, proceeding to seed dummy data..." .venv/bin/python -m scripts.seed.dummy_data else From eaf6b42a85ed93fb9ed3e9545dc8fd8afe1b0f97 Mon Sep 17 00:00:00 2001 From: Simon van Lierde Date: Tue, 21 Oct 2025 13:49:14 +0200 Subject: [PATCH 05/71] fix(backend): improve seeding scripts --- backend/scripts/seed/migrations_entrypoint.sh | 35 +++++++++++-------- 1 file changed, 20 insertions(+), 15 deletions(-) diff --git a/backend/scripts/seed/migrations_entrypoint.sh b/backend/scripts/seed/migrations_entrypoint.sh index 9cc678c..e4fd77b 100755 --- a/backend/scripts/seed/migrations_entrypoint.sh +++ b/backend/scripts/seed/migrations_entrypoint.sh @@ -3,8 +3,17 @@ # Exit immediately if a command exits with a non-zero status set -e +# Helper to lowercase a value (POSIX) +lc() { echo "$1" | tr '[:upper:]' '[:lower:]'; } + +# Defaults (so missing env vars behave as "false") +SEED_TAXONOMIES="${SEED_TAXONOMIES:-false}" +SEED_PRODUCT_TYPES="${SEED_PRODUCT_TYPES:-false}" +SEED_DUMMY_DATA="${SEED_DUMMY_DATA:-false}" +DEBUG="${DEBUG:-false}" + # Run Alembic migrations -if [ "$DEBUG" = "True" ]; then +if [ "$(lc "$DEBUG")" = "true" ]; then echo "Current migration status:" .venv/bin/alembic current fi @@ -12,31 +21,26 @@ fi echo "Upgrading database to the latest revision..." .venv/bin/alembic upgrade head -# Check if we should seed taxonomies -if [ "$SEED_TAXONOMIES" = "true" ]; then +# Seed taxonomies — run cpv once and pass the product-types flag if requested +if [ "$(lc "$SEED_TAXONOMIES")" = "true" ]; then echo "Seeding taxonomies..." - .venv/bin/python -m scripts.seed.taxonomies.cpv + if [ "$(lc "$SEED_PRODUCT_TYPES")" = "true" ]; then + .venv/bin/python -m scripts.seed.taxonomies.cpv --seed-product-types + else + .venv/bin/python -m scripts.seed.taxonomies.cpv + fi .venv/bin/python -m scripts.seed.taxonomies.harmonized_system fi -# Check if we should seed product types -if [ "$SEED_PRODUCT_TYPES" = "true" ]; then - echo "Seeding product types..." - .venv/bin/python -m scripts.seed.taxonomies.cpv --seed-product-types - -fi - # Check if all tables are empty echo "Checking if all tables in the database are empty using scripts/db_is_empty.py..." - -# Run the script and temporarily disable exit-on-error to capture the exit code DB_EMPTY=$(.venv/bin/python -m scripts.db_is_empty) -if [ "$DB_EMPTY" = "TRUE" ] && [ "$SEED_DUMMY_DATA" = "true" ]; then +if [ "$(lc "$DB_EMPTY")" = "true" ] && [ "$(lc "$SEED_DUMMY_DATA")" = "true" ]; then echo "All tables are empty, proceeding to seed dummy data..." .venv/bin/python -m scripts.seed.dummy_data else - echo "Database already has data, skipping seeding." + echo "Database already has data or dummy data seeding disabled, skipping." fi # Create a superuser if the required environment variables are set @@ -45,3 +49,4 @@ echo "Creating a superuser..." # Start the server or other desired commands exec "$@" +# ...existing code... \ No newline at end of file From 6a59854f5dd2d0a5fd7a188f647a99811bce12be Mon Sep 17 00:00:00 2001 From: Simon van Lierde Date: Tue, 28 Oct 2025 11:01:52 +0000 Subject: [PATCH 06/71] fix(docker): Fix postgres-backup-local config --- compose.prod.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/compose.prod.yml b/compose.prod.yml index 6e20e2c..656a48f 100644 --- a/compose.prod.yml +++ b/compose.prod.yml @@ -46,7 +46,8 @@ services: environment: SCHEDULE: 0 2 * * * # Daily at 2am POSTGRES_HOST: database - POSTGRES_EXTRA_OPTS: "-Z1 --schema: public --blobs" # Compress backups, only back up public schema, include blobs + BACKUP_ON_STARTUP: true + POSTGRES_EXTRA_OPTS: "--compress=zstd:3 --schema=public" # Compress backups, only back up public schema BACKUP_KEEP_DAYS: 7 BACKUP_KEEP_WEEKS: 4 BACKUP_KEEP_MONTHS: 6 From 8774ecfd26a2468d121ce2028f2d89e7fe499ffd Mon Sep 17 00:00:00 2001 From: Simon van Lierde Date: Tue, 28 Oct 2025 12:12:05 +0100 Subject: [PATCH 07/71] feat(backend): add manual pg backup script and rclone backup sync script --- .env.example | 10 +- backend/scripts/backup/README.md | 136 +++++++++++++++++++ backend/scripts/backup/backup_pg_database.sh | 63 +++++++++ backend/scripts/backup/rclone_backup.sh | 42 ++++++ backend/scripts/backup/rsync_backup.sh | 8 +- 5 files changed, 252 insertions(+), 7 deletions(-) create mode 100644 backend/scripts/backup/README.md create mode 100755 backend/scripts/backup/backup_pg_database.sh create mode 100755 backend/scripts/backup/rclone_backup.sh diff --git a/.env.example b/.env.example index b371bd6..00aa2f7 100644 --- a/.env.example +++ b/.env.example @@ -9,6 +9,10 @@ TUNNEL_TOKEN=your_token # Host directory where database and user upload backups are stored BACKUP_DIR=./backups -# Remote backup config (for use of backend/scripts/backup/backup_rclone.sh script) -BACKUP_REMOTE_HOST=user@host -BACKUP_REMOTE_PATH=/path/to/remote/backup +# Remote rsync backup config (for use of backend/scripts/backup/rsync_backup.sh script) +BACKUP_RSYNC_REMOTE_HOST=user@host +BACKUP_RSYNC_REMOTE_PATH=/path/to/remote/backup + +# Remote rclone backup config (for use of backend/scripts/backup/rclone_backup.sh script) +BACKUP_RCLONE_REMOTE=myremote:/path/to/remote/backup +BACKUP_RCLONE_MULTI_THREAD_STREAMS=16 \ No newline at end of file diff --git a/backend/scripts/backup/README.md b/backend/scripts/backup/README.md new file mode 100644 index 0000000..e180501 --- /dev/null +++ b/backend/scripts/backup/README.md @@ -0,0 +1,136 @@ +# ReLab Data Backups + +Scripts for backing up ReLab data locally and syncing to remote storage. + +## Overview + +Two types of data are backed up: + +- **PostgreSQL database**: Compressed SQL dumps +- **User uploads**: Compressed tarballs of product images and files + +Backups are created locally first, then optionally synced to remote storage. + +--- + +## Local Backups + +### Configuration + +In the root [`.env`](../../../.env) file, set where backups are stored: + +```env +BACKUP_DIR=/path/to/local/backups +``` + +Ensure the directory exists and is writable by the Docker user. + +The backup scripts create subdirectories: + +- `$BACKUP_DIR/postgres_db`: PostgreSQL backups +- `$BACKUP_DIR/user_upload_backups`: User upload backups + +### Usage + +**Manual backup:** + +Run the backup scripts directly: + +```bash +./backup_user_uploads.sh +``` + +```bash +./backup_postgres_database.sh +``` + +> 💡 **Note:** By default these scripts back up services running on the host, not processes inside Docker containers. To back up Dockerized services, configure the scripts to back up the docker volume (for user uploads) or connect to the database container (for database backups). + +**Automated backup:** + +From the repo root, start the stack with the `backups` profile: + +```bash +docker compose -f compose.yml -f compose.prod.yml --profile backups up -d +``` + +This runs: + +- `backend_user_upload_backups`: Scheduled user upload backups, backed up to `$BACKUP_DIR/user_upload_backups` directory +- `database_backups`: Scheduled PostgreSQL backups, backed up to `$BACKUP_DIR/postgres_db` directory + +Backup schedules and retention policies are configured in [`compose.prod.yml`](../../../compose.prod.yml). + +--- + +## Remote Backups + +Optionally, you can sync local backups to remote storage using **rsync** (SSH/local network) or **rclone** (cloud/SFTP). Both scripts include safety checks to prevent data loss if the local directory is unexpectedly empty. + +### Option 1: rsync (SSH/Local Network) + +Ideal for fast local networks or SSH-accessible servers + +#### Prerequisites + +- SSH key-based authentication configured for the remote host +- `rsync` installed on both local and remote machines + +#### Configuration + +Add to root [`.env`](../../../.env) file: + +```env +BACKUP_RSYNC_REMOTE_HOST=user@hostname +BACKUP_RSYNC_REMOTE_PATH=/path/to/remote/backup +``` + +#### Usage + +**Manual sync:** + +```bash +./backend/scripts/backup/rsync_backup.sh +``` + +**Automated sync (cron):** + +```cron +# Daily at 3:30 AM +30 3 * * * /path/to/relab/backend/scripts/backup/rsync_backup.sh >> /var/log/relab/rsync_backup.log 2>&1 +``` + +--- + +### Option 2: rclone (Cloud/SFTP) + +Ideal for cloud storage (S3, SharePoint, Google Drive, etc.) + +#### Prerequisites + +- `rclone` installed +- Rclone remote configured with `rclone config` (SFTP, S3, SharePoint, etc.) + +#### Configuration + +Add to root [`.env`](../../../.env) file: + +```env +BACKUP_RCLONE_REMOTE=myremote:/backup/relab +BACKUP_RCLONE_MULTI_THREAD_STREAMS=16 # Optional: adjust for network speed +``` + +#### Usage + +**Manual sync:** + +```bash +./backend/scripts/backup/rclone_backup.sh +``` + +**Automated sync (cron):** + +```cron +# Daily at 3:30 AM +30 3 * * * /path/to/relab/backend/scripts/backup/rclone_backup.sh >> /var/log/relab/rclone_backup.log 2>&1 +``` diff --git a/backend/scripts/backup/backup_pg_database.sh b/backend/scripts/backup/backup_pg_database.sh new file mode 100755 index 0000000..c67e6f4 --- /dev/null +++ b/backend/scripts/backup/backup_pg_database.sh @@ -0,0 +1,63 @@ +#!/bin/sh +### Simple script to backup the postgres database manually +set -e + +# Load backend and root .env files +SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)" +PG_ENV_FILE="$SCRIPT_DIR/../../.env" +ROOT_ENV_FILE="$SCRIPT_DIR/../../../.env" + +if [ -f "$PG_ENV_FILE" ]; then + . "$PG_ENV_FILE" + echo "[$(date)] Loaded backend env file: $PG_ENV_FILE" +else + echo "[$(date)] ERROR: Backend env file not found at $PG_ENV_FILE. Aborting." + exit 1 +fi + +if [ -f "$ROOT_ENV_FILE" ]; then + . "$ROOT_ENV_FILE" + echo "[$(date)] Loaded root env file: $ROOT_ENV_FILE" +else + echo "[$(date)] INFO: Root env file not found at $ROOT_ENV_FILE. Skipping." +fi + +# Configuration +BACKUP_DIR_PG="${BACKUP_DIR:-$SCRIPT_DIR/../../backups}/postgres_db/manual" +DATABASE_HOST="${DATABASE_HOST:-localhost}" +DATABASE_PORT="${DATABASE_PORT:-5432}" +POSTGRES_USER="${POSTGRES_USER:-postgres}" +POSTGRES_PASSWORD="${POSTGRES_PASSWORD:?POSTGRES_PASSWORD not set}" +POSTGRES_DB="${POSTGRES_DB:?POSTGRES_DB not set}" + +COMPRESSION="${POSTGRES_COMPRESSION:-zstd:3}" +SCHEMA="${POSTGRES_SCHEMA:-public}" +FILENAME="${POSTGRES_DB}-$(date +%Y%m%d-%H%M%S).sql.zst" + +# Wait for PostgreSQL +echo "[$(date)] Waiting for PostgreSQL..." +for i in $(seq 1 10); do + if PGPASSWORD="$POSTGRES_PASSWORD" pg_isready -h "$DATABASE_HOST" -p "$DATABASE_PORT" -U "$POSTGRES_USER" -q; then + echo "[$(date)] PostgreSQL ready" + break + fi + [ "$i" -eq 10 ] && { echo "[$(date)] ERROR: PostgreSQL timeout"; exit 1; } + sleep 2 +done + +echo "Successfully connected to PostgreSQL." + +# Perform backup +mkdir -p "$BACKUP_DIR_PG" +echo "[$(date)] Backing up '$POSTGRES_DB' to $BACKUP_DIR_PG/$FILENAME" + +PGPASSWORD="$POSTGRES_PASSWORD" pg_dump \ + -h "$DATABASE_HOST" \ + -p "$DATABASE_PORT" \ + -U "$POSTGRES_USER" \ + --compress="$COMPRESSION" \ + --schema="$SCHEMA" \ + "$POSTGRES_DB" \ + > "$BACKUP_DIR_PG/$FILENAME" + +echo "[$(date)] Backup completed. Size: $(du -h "$BACKUP_DIR_PG/$FILENAME" | cut -f1)" diff --git a/backend/scripts/backup/rclone_backup.sh b/backend/scripts/backup/rclone_backup.sh new file mode 100755 index 0000000..da25000 --- /dev/null +++ b/backend/scripts/backup/rclone_backup.sh @@ -0,0 +1,42 @@ +#!/bin/sh +### Rclone script to mirror a local backup directory to a remote server. +set -e + +# Load root .env file +SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)" +ENV_FILE="$SCRIPT_DIR/../../../.env" + +if [ -f "$ENV_FILE" ]; then + . "$ENV_FILE" + echo "[$(date)] Loaded env file: $ENV_FILE" +else + echo "[$(date)] ERROR: Env file not found at $ENV_FILE. Aborting." + exit 1 +fi + +# Configuration +BACKUP_DIR="${BACKUP_DIR:-$REPO_ROOT/backend/backups}" +BACKUP_RCLONE_REMOTE="${BACKUP_RCLONE_REMOTE?BACKUP_RCLONE_REMOTE not set}" # e.g., "myremote:/backup/relab" +BACKUP_RCLONE_MULTI_THREAD_STREAMS="${BACKUP_RCLONE_MULTI_THREAD_STREAMS:-16}" + +# Safety Check: If the local dir has 0 files AND the remote has more than 0 files, abort. +LOCAL_FILE_COUNT=$(find "$BACKUP_DIR" -type f | wc -l) +REMOTE_FILE_COUNT=$(rclone lsf "$BACKUP_RCLONE_REMOTE" --files-only 2>/dev/null | wc -l) + +if [ "$LOCAL_FILE_COUNT" -eq 0 ] && [ "$REMOTE_FILE_COUNT" -gt 0 ]; then + echo "[$(date)] ERROR: Local backup directory is empty, but remote is not. Aborting sync to prevent data loss." + exit 1 +fi + +echo "[$(date)] Safety check passed. Syncing backups to $BACKUP_RCLONE_REMOTE..." +rclone sync "$BACKUP_DIR" "$BACKUP_RCLONE_REMOTE" \ + --multi-thread-streams="$BACKUP_RCLONE_MULTI_THREAD_STREAMS" \ + --copy-links \ + --checksum \ + --transfers="$BACKUP_RCLONE_MULTI_THREAD_STREAMS" \ + --retries 3 \ + --low-level-retries 10 \ + --stats=30s \ + --stats-one-line + +echo "[$(date)] Sync complete." \ No newline at end of file diff --git a/backend/scripts/backup/rsync_backup.sh b/backend/scripts/backup/rsync_backup.sh index 05e3537..2315fb4 100755 --- a/backend/scripts/backup/rsync_backup.sh +++ b/backend/scripts/backup/rsync_backup.sh @@ -16,17 +16,17 @@ fi # Configuration BACKUP_DIR="${BACKUP_DIR:-$REPO_ROOT/backend/backups}" -BACKUP_REMOTE_HOST="${BACKUP_REMOTE_HOST?BACKUP_REMOTE_HOST not set}" -BACKUP_REMOTE_DIR="${BACKUP_REMOTE_DIR?BACKUP_REMOTE_DIR not set}" +BACKUP_RSYNC_REMOTE_HOST="${BACKUP_RSYNC_REMOTE_HOST?BACKUP_RSYNC_REMOTE_HOST not set}" +BACKUP_RSYNC_REMOTE_DIR="${BACKUP_RSYNC_REMOTE_DIR?BACKUP_RSYNC_REMOTE_DIR not set}" # Safety Check: If the local dir has 0 files AND the remote has more than 0 files, abort. if [ "$(find "$BACKUP_DIR" -type f | wc -l)" -eq 0 ] && \ - [ "$(ssh "$BACKUP_REMOTE_HOST" "find '$BACKUP_REMOTE_DIR' -type f 2>/dev/null | wc -l")" -gt 0 ]; then + [ "$(ssh "$BACKUP_RSYNC_REMOTE_HOST" "find '$BACKUP_RSYNC_REMOTE_DIR' -type f 2>/dev/null | wc -l")" -gt 0 ]; then echo "[$(date)] ERROR: Local backup directory is empty, but remote is not. Aborting sync to prevent data loss." exit 1 fi -BACKUP_REMOTE="$BACKUP_REMOTE_HOST:$BACKUP_REMOTE_DIR" +BACKUP_REMOTE="$BACKUP_RSYNC_REMOTE_HOST:$BACKUP_RSYNC_REMOTE_DIR" echo "[$(date)] Safety check passed. Mirroring backups to $BACKUP_REMOTE..." rsync -avz --delete "$BACKUP_DIR"/ "$BACKUP_REMOTE" From c68890fc0850c3ea9d34e6791cc5ff5379172251 Mon Sep 17 00:00:00 2001 From: Simon van Lierde Date: Tue, 28 Oct 2025 11:54:13 +0000 Subject: [PATCH 08/71] feat(backend): Print backup stats after rclone --- backend/scripts/backup/rclone_backup.sh | 5 +++-- compose.prod.yml | 1 - 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/backend/scripts/backup/rclone_backup.sh b/backend/scripts/backup/rclone_backup.sh index da25000..4a5e123 100755 --- a/backend/scripts/backup/rclone_backup.sh +++ b/backend/scripts/backup/rclone_backup.sh @@ -21,7 +21,7 @@ BACKUP_RCLONE_MULTI_THREAD_STREAMS="${BACKUP_RCLONE_MULTI_THREAD_STREAMS:-16}" # Safety Check: If the local dir has 0 files AND the remote has more than 0 files, abort. LOCAL_FILE_COUNT=$(find "$BACKUP_DIR" -type f | wc -l) -REMOTE_FILE_COUNT=$(rclone lsf "$BACKUP_RCLONE_REMOTE" --files-only 2>/dev/null | wc -l) +REMOTE_FILE_COUNT=$(rclone lsf "$BACKUP_RCLONE_REMOTE" --files-only --max-depth=3 2>/dev/null | wc -l) if [ "$LOCAL_FILE_COUNT" -eq 0 ] && [ "$REMOTE_FILE_COUNT" -gt 0 ]; then echo "[$(date)] ERROR: Local backup directory is empty, but remote is not. Aborting sync to prevent data loss." @@ -39,4 +39,5 @@ rclone sync "$BACKUP_DIR" "$BACKUP_RCLONE_REMOTE" \ --stats=30s \ --stats-one-line -echo "[$(date)] Sync complete." \ No newline at end of file +echo "[$(date)] Sync complete. Remote backup stats after sync:" +rclone size "$BACKUP_RCLONE_REMOTE" --max-depth=3 2>/dev/null | sed 's/^/ /' \ No newline at end of file diff --git a/compose.prod.yml b/compose.prod.yml index 656a48f..dc1c5a3 100644 --- a/compose.prod.yml +++ b/compose.prod.yml @@ -46,7 +46,6 @@ services: environment: SCHEDULE: 0 2 * * * # Daily at 2am POSTGRES_HOST: database - BACKUP_ON_STARTUP: true POSTGRES_EXTRA_OPTS: "--compress=zstd:3 --schema=public" # Compress backups, only back up public schema BACKUP_KEEP_DAYS: 7 BACKUP_KEEP_WEEKS: 4 From f2e1eaf1344fff0a094698e3ae386c37c0404ce1 Mon Sep 17 00:00:00 2001 From: Simon van Lierde Date: Tue, 28 Oct 2025 13:03:46 +0000 Subject: [PATCH 09/71] fix(backend): Use rclone symlink files for symlinked backups --- backend/scripts/backup/rclone_backup.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/backend/scripts/backup/rclone_backup.sh b/backend/scripts/backup/rclone_backup.sh index 4a5e123..1188c1a 100755 --- a/backend/scripts/backup/rclone_backup.sh +++ b/backend/scripts/backup/rclone_backup.sh @@ -31,13 +31,13 @@ fi echo "[$(date)] Safety check passed. Syncing backups to $BACKUP_RCLONE_REMOTE..." rclone sync "$BACKUP_DIR" "$BACKUP_RCLONE_REMOTE" \ --multi-thread-streams="$BACKUP_RCLONE_MULTI_THREAD_STREAMS" \ - --copy-links \ + --links \ --checksum \ --transfers="$BACKUP_RCLONE_MULTI_THREAD_STREAMS" \ --retries 3 \ --low-level-retries 10 \ --stats=30s \ - --stats-one-line + --stats-one-line-date echo "[$(date)] Sync complete. Remote backup stats after sync:" rclone size "$BACKUP_RCLONE_REMOTE" --max-depth=3 2>/dev/null | sed 's/^/ /' \ No newline at end of file From 87558679a913a56d13adddf0749261f285b1175b Mon Sep 17 00:00:00 2001 From: Simon van Lierde Date: Wed, 29 Oct 2025 09:39:38 +0000 Subject: [PATCH 10/71] fix(backend): Move username validation from model to schema --- backend/app/api/auth/models.py | 9 +++------ backend/app/api/auth/schemas.py | 19 ++++++++++++++----- 2 files changed, 17 insertions(+), 11 deletions(-) diff --git a/backend/app/api/auth/models.py b/backend/app/api/auth/models.py index 46acc52..5b507f0 100644 --- a/backend/app/api/auth/models.py +++ b/backend/app/api/auth/models.py @@ -3,10 +3,10 @@ import uuid from enum import Enum from functools import cached_property -from typing import TYPE_CHECKING, Annotated, Optional +from typing import TYPE_CHECKING, Optional from fastapi_users_db_sqlmodel import SQLModelBaseOAuthAccount, SQLModelBaseUserDB -from pydantic import UUID4, BaseModel, ConfigDict, StringConstraints +from pydantic import UUID4, BaseModel, ConfigDict from sqlalchemy import Enum as SAEnum from sqlalchemy import ForeignKey from sqlmodel import Column, Field, Relationship @@ -31,10 +31,7 @@ class OrganizationRole(str, Enum): class UserBase(BaseModel): """Base schema for user data.""" - username: Annotated[ - str | None, - StringConstraints(strip_whitespace=True, pattern=r"^[\w]+$"), # Allows only letters, numbers, and underscores - ] = Field(index=True, unique=True, default=None) + username: str | None = Field(index=True, unique=True, default=None, min_length=2, max_length=50) model_config = ConfigDict(use_enum_values=True) # pyright: ignore [reportIncompatibleVariableOverride] # This is not a type override, see https://github.com/fastapi/sqlmodel/discussions/855 diff --git a/backend/app/api/auth/schemas.py b/backend/app/api/auth/schemas.py index 9f69481..6abd33f 100644 --- a/backend/app/api/auth/schemas.py +++ b/backend/app/api/auth/schemas.py @@ -51,14 +51,21 @@ class OrganizationUpdate(BaseUpdateSchema): ### Users ### + +# Validation constraints for username field +ValidatedUsername = Annotated[ + str | None, StringConstraints(strip_whitespace=True, pattern=r"^\w+$", min_length=2, max_length=50) +] + + class UserCreateBase(UserBase, schemas.BaseUserCreate): """Base schema for user creation.""" - # Override for validation - username: Annotated[str | None, StringConstraints(strip_whitespace=True)] = None + # Override for username field validation + username: ValidatedUsername = None # Override for OpenAPI schema configuration - password: str = Field(json_schema_extra={"format": "password"}) + password: str = Field(json_schema_extra={"format": "password"}, min_length=8) class UserCreate(UserCreateBase): @@ -145,11 +152,13 @@ class UserReadWithRelationships(UserReadWithOrganization): class UserUpdate(UserBase, schemas.BaseUserUpdate): """Update schema for users.""" - username: Annotated[str | None, StringConstraints(strip_whitespace=True)] = None + # Override for username field validation + username: ValidatedUsername = None + organization_id: UUID4 | None = None # Override password field to include password format in JSON schema - password: str | None = Field(default=None, json_schema_extra={"format": "password"}) + password: str | None = Field(default=None, json_schema_extra={"format": "password"}, min_length=8) model_config: ConfigDict = ConfigDict( # pyright: ignore [reportIncompatibleVariableOverride] # This is not a type override, see https://github.com/fastapi/sqlmodel/discussions/855 { From 4e7a0acce779db3aaeb43ec8c3f3050540ce051c Mon Sep 17 00:00:00 2001 From: Simon van Lierde Date: Wed, 29 Oct 2025 10:03:06 +0000 Subject: [PATCH 11/71] refactor(frontend-app): Deduplicate product name validation --- frontend-app/src/app/products/[id]/index.tsx | 70 +++++---- .../components/product/ProductComponents.tsx | 59 ++++--- .../src/services/api/validation/product.ts | 146 +++++++++++++++--- 3 files changed, 198 insertions(+), 77 deletions(-) diff --git a/frontend-app/src/app/products/[id]/index.tsx b/frontend-app/src/app/products/[id]/index.tsx index f240cac..725f55b 100644 --- a/frontend-app/src/app/products/[id]/index.tsx +++ b/frontend-app/src/app/products/[id]/index.tsx @@ -22,7 +22,7 @@ import { useDialog } from '@/components/common/DialogProvider'; import { getProduct, newProduct } from '@/services/api/fetching'; import { deleteProduct, saveProduct } from '@/services/api/saving'; -import { getProductNameHelperText, isProductValid, isValidProductName } from '@/services/api/validation/product'; +import { getProductNameHelperText, validateProduct, validateProductName } from '@/services/api/validation/product'; import { Product } from '@/types/Product'; /** @@ -256,15 +256,15 @@ export default function ProductPage(): JSX.Element { - + ); } @@ -279,27 +279,37 @@ function EditNameButton({ const dialog = useDialog(); const onPress = () => { - if (!product) { - return; - } - dialog.input({ - title: 'Edit name', - placeholder: 'Product Name', - helperText: getProductNameHelperText(), - defaultValue: product.name || '', - buttons: [ - { text: 'Cancel', onPress: () => undefined }, - { - text: 'OK', - disabled: (value) => !isValidProductName(value), - onPress: (newName) => { - const name = typeof newName === 'string' ? newName.trim() : ''; - onProductNameChange?.(name); - }, + if (!product) { + return; + } + dialog.input({ + title: 'Edit name', + placeholder: 'Product Name', + helperText: getProductNameHelperText(), + defaultValue: product.name || '', + buttons: [ + { text: 'Cancel', onPress: () => undefined }, + { + text: 'OK', + disabled: (value) => { + const result = validateProductName(value); + return !result.isValid; }, - ], - }); - }; + onPress: (newName) => { + const name = typeof newName === 'string' ? newName.trim() : ''; + const result = validateProductName(name); + + if (!result.isValid) { + alert(result.error); + return; + } + + onProductNameChange?.(name); + }, + }, + ], + }); +}; return ; } diff --git a/frontend-app/src/components/product/ProductComponents.tsx b/frontend-app/src/components/product/ProductComponents.tsx index 6261606..2acd837 100644 --- a/frontend-app/src/components/product/ProductComponents.tsx +++ b/frontend-app/src/components/product/ProductComponents.tsx @@ -2,13 +2,13 @@ import { useEffect, useState } from 'react'; import { View } from 'react-native'; import { Button } from 'react-native-paper'; -import { useRouter } from 'expo-router'; import { InfoTooltip, Text } from '@/components/base'; import { useDialog } from '@/components/common/DialogProvider'; import ProductCard from '@/components/common/ProductCard'; import { productComponents } from '@/services/api/fetching'; -import { isValidProductName } from '@/services/api/validation/product'; +import { getProductNameHelperText, validateProductName } from '@/services/api/validation/product'; import { Product } from '@/types/Product'; +import { useRouter } from 'expo-router'; interface Props { product: Product; @@ -30,29 +30,40 @@ export default function ProductComponents({ product, editMode }: Props) { // Callbacks const newComponent = () => { - dialog.input({ - title: 'Create New Component', - placeholder: 'Component Name', - helperText: 'Enter a descriptive name between 2 and 100 characters', - buttons: [ - { text: 'Cancel' }, - { - text: 'OK', - disabled: (value) => !isValidProductName(value), - onPress: (componentName) => { - const name = typeof componentName === 'string' ? componentName.trim() : ''; - const params = { - id: 'new', - name, - isComponent: 'true', - parent: product.id, - }; - router.push({ pathname: '/products/[id]', params: params }); - }, + dialog.input({ + title: 'Create New Component', + placeholder: 'Component Name', + helperText: getProductNameHelperText(), + buttons: [ + { text: 'Cancel' }, + { + text: 'OK', + disabled: (value) => { + const result = validateProductName(value); + return !result.isValid; + }, + onPress: (componentName) => { + const name = typeof componentName === 'string' ? componentName.trim() : ''; + const result = validateProductName(name); + + if (!result.isValid) { + // This shouldn't happen due to disabled check, but handle defensively + alert(result.error); + return; + } + + const params = { + id: 'new', + name, + isComponent: 'true', + parent: product.id, + }; + router.push({ pathname: '/products/[id]', params: params }); }, - ], - }); - }; + }, + ], + }); +}; // Render return ( diff --git a/frontend-app/src/services/api/validation/product.ts b/frontend-app/src/services/api/validation/product.ts index 37c9658..39e2ba8 100644 --- a/frontend-app/src/services/api/validation/product.ts +++ b/frontend-app/src/services/api/validation/product.ts @@ -7,9 +7,33 @@ import { Product } from '@/types/Product'; export const PRODUCT_NAME_MIN_LENGTH = 2; export const PRODUCT_NAME_MAX_LENGTH = 100; -export function isValidProductName(value: string | undefined): boolean { +export type ValidationResult = { + isValid: boolean; + error?: string; +}; + +export function validateProductName(value: string | undefined): ValidationResult { const name = typeof value === 'string' ? value.trim() : ''; - return name.length >= PRODUCT_NAME_MIN_LENGTH && name.length <= PRODUCT_NAME_MAX_LENGTH; + + if (!name) { + return { isValid: false, error: 'Product name is required' }; + } + + if (name.length < PRODUCT_NAME_MIN_LENGTH) { + return { + isValid: false, + error: `Product name must be at least ${PRODUCT_NAME_MIN_LENGTH} characters` + }; + } + + if (name.length > PRODUCT_NAME_MAX_LENGTH) { + return { + isValid: false, + error: `Product name must be at most ${PRODUCT_NAME_MAX_LENGTH} characters` + }; + } + + return { isValid: true }; } export function getProductNameHelperText(): string { @@ -31,27 +55,103 @@ export function isValidUrl(value: string | undefined): boolean { } } -export function isProductValid(product: Product): boolean { +export function isValidUrl(value: string | undefined): boolean { + if (!value || typeof value !== 'string') return false; + + const trimmed = value.trim(); + if (trimmed.length === 0) return false; + + try { + const url = new URL(trimmed); + // Check if protocol is http or https + return url.protocol === 'http:' || url.protocol === 'https:'; + } catch { + return false; + } +} + +export function validateProductDimension( + value: number | undefined, + dimensionName: string +): ValidationResult { + if (value == null || Number.isNaN(value)) { + return { isValid: true }; // Optional field + } + + if (typeof value !== 'number' || value <= 0) { + return { + isValid: false, + error: `${dimensionName} must be a positive number` + }; + } + + return { isValid: true }; +} + +export function validateProductWeight(value: number | undefined): ValidationResult { + if (value == null || Number.isNaN(value)) { + return { isValid: false, error: 'Weight is required' }; + } + + if (typeof value !== 'number' || value <= 0) { + return { isValid: false, error: 'Weight must be a positive number' }; + } + + return { isValid: true }; +} + +export function validateProductVideos(videos: { title: string; url: string }[]): ValidationResult { + for (const video of videos) { + if (video.title.trim().length === 0) { + return { isValid: false, error: 'Video title cannot be empty' }; + } + if (!isValidUrl(video.url)) { + return { isValid: false, error: `Invalid URL for video titled "${video.title}"` }; + } + } + return { isValid: true }; +} + +export function validateProduct(product: Product): ValidationResult { const { weight, width, height, depth } = product.physicalProperties; - // Allow undefined dimensions, but if provided, they must be positive numbers - const isValidDimension = (val: number | undefined) => { - return val == null || Number.isNaN(val) || (typeof val === 'number' && val > 0); - }; - - // Validate that all videos have non-empty titles and valid URLs - const areVideosValid = product.videos.every(video => { - return video.title.trim().length > 0 && isValidUrl(video.url); - }); - - return ( - isValidProductName(product.name) && - typeof weight === 'number' && - !Number.isNaN(weight) && - weight > 0 && - isValidDimension(width) && - isValidDimension(height) && - isValidDimension(depth) && - areVideosValid - ); + // Validate product name + const nameResult = validateProductName(product.name); + if (!nameResult.isValid) { + return nameResult; + } + + // Validate weight + const weightResult = validateProductWeight(weight); + if (!weightResult.isValid) { + return weightResult; + } + + // Validate dimensions + const widthResult = validateProductDimension(width, 'Width'); + if (!widthResult.isValid) { + return widthResult; + } + + const heightResult = validateProductDimension(height, 'Height'); + if (!heightResult.isValid) { + return heightResult; + } + + const depthResult = validateProductDimension(depth, 'Depth'); + if (!depthResult.isValid) { + return depthResult; + } + + // Validate product videos + const videosResult = validateProductVideos(product.videos); + if (!videosResult.isValid) { + return videosResult; + } + + return { isValid: true }; +} + +export function isProductValid(product: Product): boolean { + return validateProduct(product).isValid; } From 93a938ed6f4d2abf1f70fc4f93f467a339c83b76 Mon Sep 17 00:00:00 2001 From: Simon van Lierde Date: Wed, 29 Oct 2025 10:03:24 +0000 Subject: [PATCH 12/71] chore(deps): update pre-commit yaml --- .pre-commit-config.yaml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 69be1fe..cfb56f1 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -57,14 +57,14 @@ repos: files: ^ (?!(backend/frontend-app|frontend-web)/data/) ### Backend hooks - repo: https://github.com/RobertCraigie/pyright-python # Lint backend code with Pyright. - rev: v1.1.406 + rev: v1.1.407 hooks: - id: pyright files: ^backend/(app|scripts|tests)/ entry: pyright --project backend - repo: https://github.com/astral-sh/ruff-pre-commit - rev: v0.14.1 + rev: v0.14.2 hooks: - id: ruff-check # Lint code files: ^backend/(app|scripts|tests)/ @@ -74,7 +74,7 @@ repos: args: ["--config", "backend/pyproject.toml"] - repo: https://github.com/astral-sh/uv-pre-commit - rev: 0.9.4 + rev: 0.9.5 hooks: - id: uv-lock # Update the uv lockfile for the backend. files: ^backend/(uv\.lock|pyproject\.toml|uv\.toml)$ From 5875e1ee8007e8ca83373d916b4d0fa87aaa1ce0 Mon Sep 17 00:00:00 2001 From: Simon van Lierde Date: Wed, 29 Oct 2025 10:03:50 +0000 Subject: [PATCH 13/71] feat(frontend-app): update registration validation and error handling --- frontend-app/src/app/(auth)/new-account.tsx | 419 ++++++++++-------- .../src/services/api/authentication.ts | 31 +- .../src/services/api/validation/user.ts | 125 ++++++ 3 files changed, 376 insertions(+), 199 deletions(-) create mode 100644 frontend-app/src/services/api/validation/user.ts diff --git a/frontend-app/src/app/(auth)/new-account.tsx b/frontend-app/src/app/(auth)/new-account.tsx index e5f0ce5..ed178bf 100644 --- a/frontend-app/src/app/(auth)/new-account.tsx +++ b/frontend-app/src/app/(auth)/new-account.tsx @@ -1,168 +1,227 @@ import { Link, useRouter } from 'expo-router'; import { useState } from 'react'; -import { View } from 'react-native'; +import { StyleSheet, View } from 'react-native'; import { Button, HelperText, IconButton, Text, TextInput } from 'react-native-paper'; -import validator from 'validator'; import { login, register } from '@/services/api/authentication'; +import { + validateEmail, + validatePassword, + validateUsername +} from '@/services/api/validation/user'; + +const styles = StyleSheet.create({ + container: { + flex: 1, + padding: 20, + }, + welcomeText: { + marginTop: 80, + fontSize: 40, + marginLeft: 5, + }, + brandText: { + fontSize: 80, + fontWeight: 'bold', + }, + questionText: { + fontSize: 31, + marginTop: 80, + marginLeft: 5, + marginBottom: 40, + }, + inputContainer: { + flexDirection: 'column', + marginBottom: 10, + }, + inputRow: { + flexDirection: 'row', + alignItems: 'center', + }, + textInput: { + flex: 1, + marginRight: 10, + }, + helperText: { + marginTop: -8, + }, + backButton: { + flexDirection: 'row', + alignItems: 'center', + marginTop: 8, + }, + backButtonIcon: { + margin: 0, + }, + backButtonText: { + fontSize: 13, + color: '#999', + marginLeft: 4, + }, + bottomContainer: { + position: 'absolute', + bottom: 20, + left: 20, + right: 20, + alignItems: 'center', + gap: 8, + }, + privacyText: { + fontSize: 12, + opacity: 0.7, + textAlign: 'center', + }, + privacyLink: { + fontSize: 12, + textDecorationLine: 'underline', + }, + registerButton: { + minWidth: 140, + }, +}); + +const PrivacyPolicy = () => ( + + By creating an account, you agree to our{' '} + + Privacy Policy + + +); export default function NewAccount() { - // Hooks const router = useRouter(); - // States const [section, setSection] = useState<'username' | 'email' | 'password'>('username'); - const [username, setUsername] = useState(''); const [email, setEmail] = useState(''); const [password, setPassword] = useState(''); + const [usernameError, setUsernameError] = useState(''); const [emailError, setEmailError] = useState(''); + const [passwordError, setPasswordError] = useState(''); + const [isRegistering, setIsRegistering] = useState(false); - // Functions - const validateEmail = async (emailInput: string) => { - setEmail(emailInput); - setEmailError(''); + const handleUsernameChange = (input: string) => { + const trimmed = input.trim(); + setUsername(trimmed); + + const result = validateUsername(trimmed); + setUsernameError(result.error || ''); + }; + + const handleEmailChange = (input: string) => { + setEmail(input); + + const result = validateEmail(input); + setEmailError(result.error || ''); + }; - if (!emailInput) { + const handlePasswordChange = (input: string) => { + setPassword(input); + + const result = validatePassword(input, username, email); + setPasswordError(result.error || ''); + }; + + const createAccount = async () => { + // Final validation + const usernameResult = validateUsername(username); + if (!usernameResult.isValid) { + alert(usernameResult.error); return; } - // Check if email format is valid - if (!validator.isEmail(emailInput)) { - setEmailError('Please enter a valid email address'); + const emailResult = validateEmail(email); + if (!emailResult.isValid) { + alert(emailResult.error); return; } - // Check for disposable email via backend - try { - const response = await fetch( - `${process.env.EXPO_PUBLIC_API_URL}/auth/validate-email?email=${encodeURIComponent(emailInput)}`, - ); - const data = await response.json(); - - if (!data.isValid) { - setEmailError(data.reason || 'Please use a permanent email address'); - return; - } - } catch (error) { - console.error('Error validating email:', error); - // Continue even if the check fails - don't block the user + const passwordResult = validatePassword(password, username, email); + if (!passwordResult.isValid) { + alert(passwordResult.error); + return; } - }; - const createAccount = async () => { - const success = await register(username, email, password); - if (!success) { - alert('Account creation failed. Please try again.'); + setIsRegistering(true); + + const result = await register(username, email, password); + + if (!result.success) { + setIsRegistering(false); + alert(result.error || 'Account creation failed. Please try again.'); return; } + const loginSuccess = await login(email, password); + setIsRegistering(false); + if (!loginSuccess) { - alert('Login failed. Please try logging in manually.'); + alert('Account created! Please log in manually.'); router.replace('/login'); return; } + router.navigate('/products'); }; - // Render if (section === 'username') { return ( - - - {'Welcome to'} - - - {'ReLab.'} - - - {'Who are you?'} - + + Welcome to + ReLab. + Who are you? - - - setSection('email')} - /> + + + + setSection('email')} + /> + + {usernameError && ( + + {usernameError} + + )} + + + + + - ); } + if (section === 'email') { return ( - - - {'Hi'} - - - {username + '.'} - - - {'How do we reach you?'} - + + Hi + {username}. + How do we reach you? - - + + setSection('password')} /> - {emailError ? ( - + {emailError && ( + {emailError} - ) : null} + )} - + setSection('username')} - style={{ margin: 0 }} + style={styles.backButtonIcon} /> - setSection('username')} style={{ fontSize: 13, color: '#999', marginLeft: 4 }}> + setSection('username')} style={styles.backButtonText}> Edit username - + + + + ); } if (section === 'password') { return ( - - - {'Finally,'} - - - {username + '.'} - - - {'How will you log in?'} - + + Finally, + {username}. + How will you log in? - - - + + + + + + {passwordError && ( + + {passwordError} + + )} - + setSection('email')} - style={{ margin: 0 }} + style={styles.backButtonIcon} /> - setSection('email')} style={{ fontSize: 13, color: '#999', marginLeft: 4 }}> + setSection('email')} style={styles.backButtonText}> Edit email address - - - By creating an account, you agree to our{' '} - - Privacy Policy - - - - ); } -} +} \ No newline at end of file diff --git a/frontend-app/src/services/api/authentication.ts b/frontend-app/src/services/api/authentication.ts index e7973ff..a36399b 100644 --- a/frontend-app/src/services/api/authentication.ts +++ b/frontend-app/src/services/api/authentication.ts @@ -1,12 +1,12 @@ -import AsyncStorage from '@react-native-async-storage/async-storage'; import { User } from '@/types/User'; +import AsyncStorage from '@react-native-async-storage/async-storage'; -const baseUrl = `${process.env.EXPO_PUBLIC_API_URL}`; +const apiURL = `${process.env.EXPO_PUBLIC_API_URL}`; let token: string | undefined; let user: User | undefined; export async function login(username: string, password: string): Promise { - const url = new URL(baseUrl + '/auth/bearer/login'); + const url = new URL(apiURL + '/auth/bearer/login'); const headers = { 'Content-Type': 'application/x-www-form-urlencoded', Accept: 'application/json' }; const body = new URLSearchParams({ username, password }).toString(); @@ -74,7 +74,7 @@ export async function getUser(): Promise { return user; } - const url = new URL(baseUrl + '/users/me'); + const url = new URL(apiURL + '/users/me'); const authToken = await getToken(); if (!authToken) { return undefined; @@ -112,8 +112,8 @@ export async function getUser(): Promise { } } -export async function register(username: string, email: string, password: string): Promise { - const url = new URL(baseUrl + '/auth/register'); +export async function register(username: string, email: string, password: string): Promise<{ success: boolean; error?: string }> { + const url = new URL(apiURL + '/auth/register'); const headers = { 'Content-Type': 'application/json', Accept: 'application/json' }; const body = { @@ -122,12 +122,25 @@ export async function register(username: string, email: string, password: string password: password, }; - const response = await fetch(url, { method: 'POST', headers: headers, body: JSON.stringify(body) }); - return response.ok; + try { + const response = await fetch(url, { method: 'POST', headers: headers, body: JSON.stringify(body) }); + + if (response.ok) { + return { success: true }; + } + + const errorData = await response.json(); + const errorMessage = errorData.detail?.reason || errorData.detail || 'Registration failed. Please try again.'; + + return { success: false, error: errorMessage }; + } catch (error) { + console.error('Registration error:', error); + return { success: false, error: 'Network error. Please check your connection and try again.' }; + } } export async function verify(email: string): Promise { - const url = new URL(baseUrl + '/auth/request-verify-token'); + const url = new URL(apiURL + '/auth/request-verify-token'); const headers = { 'Content-Type': 'application/json', Accept: 'application/json' }; const body = { diff --git a/frontend-app/src/services/api/validation/user.ts b/frontend-app/src/services/api/validation/user.ts new file mode 100644 index 0000000..c81b3b8 --- /dev/null +++ b/frontend-app/src/services/api/validation/user.ts @@ -0,0 +1,125 @@ +/** + * User validation utilities + */ + +// Constants +export const USERNAME_MIN_LENGTH = 2; +export const USERNAME_MAX_LENGTH = 50; +export const USERNAME_PATTERN = /^\w+$/; // Only letters, numbers, and underscores + +export const PASSWORD_MIN_LENGTH = 8; +export const PASSWORD_MAX_LENGTH = 128; + +// Types +export type ValidationResult = { + isValid: boolean; + error?: string; +}; + +// Methods +export function validateUsername(value: string | undefined): ValidationResult { + const username = typeof value === 'string' ? value.trim() : ''; + + if (!username) { + return { isValid: false, error: 'Username is required' }; + } + + if (username.length < USERNAME_MIN_LENGTH) { + return { + isValid: false, + error: `Username must be at least ${USERNAME_MIN_LENGTH} characters` + }; + } + + if (username.length > USERNAME_MAX_LENGTH) { + return { + isValid: false, + error: `Username must be at most ${USERNAME_MAX_LENGTH} characters` + }; + } + + if (!USERNAME_PATTERN.test(username)) { + return { + isValid: false, + error: 'Username can only contain letters, numbers, and underscores' + }; + } + + return { isValid: true }; +} + +export function getUsernameHelperText(): string { + return `Username must be ${USERNAME_MIN_LENGTH}-${USERNAME_MAX_LENGTH} characters and contain only letters, numbers, and underscores`; +} + +export function validateEmail(value: string | undefined): ValidationResult { + const email = typeof value === 'string' ? value.trim() : ''; + + if (!email) { + return { isValid: false, error: 'Email is required' }; + } + + // Basic email format validation + const emailPattern = /^[^\s@]+@[^\s@]+\.[^\s@]+$/; + if (!emailPattern.test(email)) { + return { isValid: false, error: 'Please enter a valid email address' }; + } + + return { isValid: true }; +} + +export function getEmailHelperText(): string { + return 'Enter a valid email address'; +} + +export function validatePassword( + value: string | undefined, + username?: string, + email?: string +): ValidationResult { + const password = typeof value === 'string' ? value : ''; + + if (!password) { + return { isValid: false, error: 'Password is required' }; + } + + if (password.length < PASSWORD_MIN_LENGTH) { + return { + isValid: false, + error: `Password must be at least ${PASSWORD_MIN_LENGTH} characters` + }; + } + + if (password.length > PASSWORD_MAX_LENGTH) { + return { + isValid: false, + error: `Password must be at most ${PASSWORD_MAX_LENGTH} characters` + }; + } + + // Check if password contains username + if (username && password.toLowerCase().includes(username.toLowerCase())) { + return { + isValid: false, + error: 'Password cannot contain your username' + }; + } + + // Check if password contains email or email username part + if (email) { + const emailUsername = email.split('@')[0]; + if (password.toLowerCase().includes(email.toLowerCase()) || + password.toLowerCase().includes(emailUsername.toLowerCase())) { + return { + isValid: false, + error: 'Password cannot contain your email address' + }; + } + } + + return { isValid: true }; +} + +export function getPasswordHelperText(): string { + return `Password must be ${PASSWORD_MIN_LENGTH}-${PASSWORD_MAX_LENGTH} characters and cannot contain your username or email`; +} From acdd1f0b8cbf81ccd86c29a3dc515f12346fc375 Mon Sep 17 00:00:00 2001 From: Simon van Lierde Date: Wed, 29 Oct 2025 11:27:29 +0100 Subject: [PATCH 14/71] fix(cicd): Format frontend instead of just linting --- .pre-commit-config.yaml | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index cfb56f1..ea48998 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -55,7 +55,8 @@ repos: hooks: - id: check-json5 files: ^ (?!(backend/frontend-app|frontend-web)/data/) - ### Backend hooks + + ### Backend hooks - repo: https://github.com/RobertCraigie/pyright-python # Lint backend code with Pyright. rev: v1.1.407 hooks: @@ -90,22 +91,22 @@ repos: pass_filenames: false stages: [pre-commit] - ### Frontend hooks + ### Frontend hooks - repo: local hooks: - - id: frontend-web-lint - name: lint frontend-web code - entry: bash -c 'cd frontend-web && npm run lint' + - id: frontend-web-format + name: format frontend-web code + entry: bash -c 'cd frontend-web && npm run format' language: system - # Match frontend JavaScript and TypeScript files for linting. + # Match frontend JavaScript and TypeScript files for formatting. files: ^frontend-web\/.*\.(jsx?|tsx?|c(js|ts)|m(js|ts)|d\\.(ts|cts|mts)|jsonc?)$ pass_filenames: false - - id: frontend-app-lint - name: lint frontend-app code - entry: bash -c 'cd frontend-app && npm run lint' + - id: frontend-app-format + name: format frontend-app code + entry: bash -c 'cd frontend-app && npm run format' language: system - # Match frontend JavaScript and TypeScript files for linting. + # Match frontend JavaScript and TypeScript files for formatting. files: ^frontend-app\/.*\.(jsx?|tsx?|c(js|ts)|m(js|ts)|d\\.(ts|cts|mts)|jsonc?)$ pass_filenames: false From 4b5e80bb1d352b479d90923b5a71019bdc2f9299 Mon Sep 17 00:00:00 2001 From: Simon van Lierde Date: Wed, 29 Oct 2025 11:46:33 +0100 Subject: [PATCH 15/71] chore: linting --- .env.example | 2 +- .../app/api/auth/utils/programmatic_emails.py | 1 - backend/scripts/backup/README.md | 6 +- backend/scripts/backup/rclone_backup.sh | 4 +- backend/scripts/seed/migrations_entrypoint.sh | 1 - frontend-app/src/app/(auth)/new-account.tsx | 38 ++++------ frontend-app/src/app/products/[id]/index.tsx | 76 +++++++++---------- .../components/product/ProductComponents.tsx | 64 ++++++++-------- .../src/services/api/authentication.ts | 14 ++-- .../src/services/api/validation/product.ts | 26 +------ .../src/services/api/validation/user.ts | 26 +++---- 11 files changed, 115 insertions(+), 143 deletions(-) diff --git a/.env.example b/.env.example index 00aa2f7..57e0a49 100644 --- a/.env.example +++ b/.env.example @@ -15,4 +15,4 @@ BACKUP_RSYNC_REMOTE_PATH=/path/to/remote/backup # Remote rclone backup config (for use of backend/scripts/backup/rclone_backup.sh script) BACKUP_RCLONE_REMOTE=myremote:/path/to/remote/backup -BACKUP_RCLONE_MULTI_THREAD_STREAMS=16 \ No newline at end of file +BACKUP_RCLONE_MULTI_THREAD_STREAMS=16 diff --git a/backend/app/api/auth/utils/programmatic_emails.py b/backend/app/api/auth/utils/programmatic_emails.py index dc1cefa..e9bef95 100644 --- a/backend/app/api/auth/utils/programmatic_emails.py +++ b/backend/app/api/auth/utils/programmatic_emails.py @@ -68,7 +68,6 @@ async def send_email( port=auth_settings.email_port, ) await smtp.connect() - # logger.info("Sending email to %s", auth_settings.__dict__) await smtp.login(auth_settings.email_username, auth_settings.email_password) await smtp.send_message(msg) await smtp.quit() diff --git a/backend/scripts/backup/README.md b/backend/scripts/backup/README.md index e180501..abeb00f 100644 --- a/backend/scripts/backup/README.md +++ b/backend/scripts/backup/README.md @@ -11,7 +11,7 @@ Two types of data are backed up: Backups are created locally first, then optionally synced to remote storage. ---- +______________________________________________________________________ ## Local Backups @@ -61,7 +61,7 @@ This runs: Backup schedules and retention policies are configured in [`compose.prod.yml`](../../../compose.prod.yml). ---- +______________________________________________________________________ ## Remote Backups @@ -100,7 +100,7 @@ BACKUP_RSYNC_REMOTE_PATH=/path/to/remote/backup 30 3 * * * /path/to/relab/backend/scripts/backup/rsync_backup.sh >> /var/log/relab/rsync_backup.log 2>&1 ``` ---- +______________________________________________________________________ ### Option 2: rclone (Cloud/SFTP) diff --git a/backend/scripts/backup/rclone_backup.sh b/backend/scripts/backup/rclone_backup.sh index 1188c1a..16d9db3 100755 --- a/backend/scripts/backup/rclone_backup.sh +++ b/backend/scripts/backup/rclone_backup.sh @@ -37,7 +37,7 @@ rclone sync "$BACKUP_DIR" "$BACKUP_RCLONE_REMOTE" \ --retries 3 \ --low-level-retries 10 \ --stats=30s \ - --stats-one-line-date + --stats-one-line-date echo "[$(date)] Sync complete. Remote backup stats after sync:" -rclone size "$BACKUP_RCLONE_REMOTE" --max-depth=3 2>/dev/null | sed 's/^/ /' \ No newline at end of file +rclone size "$BACKUP_RCLONE_REMOTE" --max-depth=3 2>/dev/null | sed 's/^/ /' diff --git a/backend/scripts/seed/migrations_entrypoint.sh b/backend/scripts/seed/migrations_entrypoint.sh index e4fd77b..4124d6e 100755 --- a/backend/scripts/seed/migrations_entrypoint.sh +++ b/backend/scripts/seed/migrations_entrypoint.sh @@ -49,4 +49,3 @@ echo "Creating a superuser..." # Start the server or other desired commands exec "$@" -# ...existing code... \ No newline at end of file diff --git a/frontend-app/src/app/(auth)/new-account.tsx b/frontend-app/src/app/(auth)/new-account.tsx index ed178bf..6dce0bb 100644 --- a/frontend-app/src/app/(auth)/new-account.tsx +++ b/frontend-app/src/app/(auth)/new-account.tsx @@ -4,11 +4,7 @@ import { StyleSheet, View } from 'react-native'; import { Button, HelperText, IconButton, Text, TextInput } from 'react-native-paper'; import { login, register } from '@/services/api/authentication'; -import { - validateEmail, - validatePassword, - validateUsername -} from '@/services/api/validation/user'; +import { validateEmail, validatePassword, validateUsername } from '@/services/api/validation/user'; const styles = StyleSheet.create({ container: { @@ -104,21 +100,21 @@ export default function NewAccount() { const handleUsernameChange = (input: string) => { const trimmed = input.trim(); setUsername(trimmed); - + const result = validateUsername(trimmed); setUsernameError(result.error || ''); }; const handleEmailChange = (input: string) => { setEmail(input); - + const result = validateEmail(input); setEmailError(result.error || ''); }; const handlePasswordChange = (input: string) => { setPassword(input); - + const result = validatePassword(input, username, email); setPasswordError(result.error || ''); }; @@ -146,22 +142,22 @@ export default function NewAccount() { setIsRegistering(true); const result = await register(username, email, password); - + if (!result.success) { setIsRegistering(false); alert(result.error || 'Account creation failed. Please try again.'); return; } - + const loginSuccess = await login(email, password); setIsRegistering(false); - + if (!loginSuccess) { alert('Account created! Please log in manually.'); router.replace('/login'); return; } - + router.navigate('/products'); }; @@ -200,14 +196,12 @@ export default function NewAccount() { - + ); } - + if (section === 'email') { return ( @@ -257,9 +251,7 @@ export default function NewAccount() { - + ); @@ -284,7 +276,7 @@ export default function NewAccount() { placeholder="Password" error={!!passwordError} /> - + ); } -} \ No newline at end of file +} diff --git a/frontend-app/src/app/products/[id]/index.tsx b/frontend-app/src/app/products/[id]/index.tsx index 725f55b..3b57952 100644 --- a/frontend-app/src/app/products/[id]/index.tsx +++ b/frontend-app/src/app/products/[id]/index.tsx @@ -256,15 +256,15 @@ export default function ProductPage(): JSX.Element { - + ); } @@ -279,37 +279,37 @@ function EditNameButton({ const dialog = useDialog(); const onPress = () => { - if (!product) { - return; - } - dialog.input({ - title: 'Edit name', - placeholder: 'Product Name', - helperText: getProductNameHelperText(), - defaultValue: product.name || '', - buttons: [ - { text: 'Cancel', onPress: () => undefined }, - { - text: 'OK', - disabled: (value) => { - const result = validateProductName(value); - return !result.isValid; - }, - onPress: (newName) => { - const name = typeof newName === 'string' ? newName.trim() : ''; - const result = validateProductName(name); - - if (!result.isValid) { - alert(result.error); - return; - } + if (!product) { + return; + } + dialog.input({ + title: 'Edit name', + placeholder: 'Product Name', + helperText: getProductNameHelperText(), + defaultValue: product.name || '', + buttons: [ + { text: 'Cancel', onPress: () => undefined }, + { + text: 'OK', + disabled: (value) => { + const result = validateProductName(value); + return !result.isValid; + }, + onPress: (newName) => { + const name = typeof newName === 'string' ? newName.trim() : ''; + const result = validateProductName(name); + + if (!result.isValid) { + alert(result.error); + return; + } - onProductNameChange?.(name); + onProductNameChange?.(name); + }, }, - }, - ], - }); -}; + ], + }); + }; return ; } diff --git a/frontend-app/src/components/product/ProductComponents.tsx b/frontend-app/src/components/product/ProductComponents.tsx index 2acd837..daf9286 100644 --- a/frontend-app/src/components/product/ProductComponents.tsx +++ b/frontend-app/src/components/product/ProductComponents.tsx @@ -2,13 +2,13 @@ import { useEffect, useState } from 'react'; import { View } from 'react-native'; import { Button } from 'react-native-paper'; +import { useRouter } from 'expo-router'; import { InfoTooltip, Text } from '@/components/base'; import { useDialog } from '@/components/common/DialogProvider'; import ProductCard from '@/components/common/ProductCard'; import { productComponents } from '@/services/api/fetching'; import { getProductNameHelperText, validateProductName } from '@/services/api/validation/product'; import { Product } from '@/types/Product'; -import { useRouter } from 'expo-router'; interface Props { product: Product; @@ -30,40 +30,40 @@ export default function ProductComponents({ product, editMode }: Props) { // Callbacks const newComponent = () => { - dialog.input({ - title: 'Create New Component', - placeholder: 'Component Name', - helperText: getProductNameHelperText(), - buttons: [ - { text: 'Cancel' }, - { - text: 'OK', - disabled: (value) => { - const result = validateProductName(value); - return !result.isValid; - }, - onPress: (componentName) => { - const name = typeof componentName === 'string' ? componentName.trim() : ''; - const result = validateProductName(name); + dialog.input({ + title: 'Create New Component', + placeholder: 'Component Name', + helperText: getProductNameHelperText(), + buttons: [ + { text: 'Cancel' }, + { + text: 'OK', + disabled: (value) => { + const result = validateProductName(value); + return !result.isValid; + }, + onPress: (componentName) => { + const name = typeof componentName === 'string' ? componentName.trim() : ''; + const result = validateProductName(name); - if (!result.isValid) { - // This shouldn't happen due to disabled check, but handle defensively - alert(result.error); - return; - } + if (!result.isValid) { + // This shouldn't happen due to disabled check, but handle defensively + alert(result.error); + return; + } - const params = { - id: 'new', - name, - isComponent: 'true', - parent: product.id, - }; - router.push({ pathname: '/products/[id]', params: params }); + const params = { + id: 'new', + name, + isComponent: 'true', + parent: product.id, + }; + router.push({ pathname: '/products/[id]', params: params }); + }, }, - }, - ], - }); -}; + ], + }); + }; // Render return ( diff --git a/frontend-app/src/services/api/authentication.ts b/frontend-app/src/services/api/authentication.ts index a36399b..f720cc3 100644 --- a/frontend-app/src/services/api/authentication.ts +++ b/frontend-app/src/services/api/authentication.ts @@ -1,5 +1,5 @@ -import { User } from '@/types/User'; import AsyncStorage from '@react-native-async-storage/async-storage'; +import { User } from '@/types/User'; const apiURL = `${process.env.EXPO_PUBLIC_API_URL}`; let token: string | undefined; @@ -112,7 +112,11 @@ export async function getUser(): Promise { } } -export async function register(username: string, email: string, password: string): Promise<{ success: boolean; error?: string }> { +export async function register( + username: string, + email: string, + password: string, +): Promise<{ success: boolean; error?: string }> { const url = new URL(apiURL + '/auth/register'); const headers = { 'Content-Type': 'application/json', Accept: 'application/json' }; @@ -124,14 +128,14 @@ export async function register(username: string, email: string, password: string try { const response = await fetch(url, { method: 'POST', headers: headers, body: JSON.stringify(body) }); - + if (response.ok) { return { success: true }; } - + const errorData = await response.json(); const errorMessage = errorData.detail?.reason || errorData.detail || 'Registration failed. Please try again.'; - + return { success: false, error: errorMessage }; } catch (error) { console.error('Registration error:', error); diff --git a/frontend-app/src/services/api/validation/product.ts b/frontend-app/src/services/api/validation/product.ts index 39e2ba8..fd7e7c5 100644 --- a/frontend-app/src/services/api/validation/product.ts +++ b/frontend-app/src/services/api/validation/product.ts @@ -22,14 +22,14 @@ export function validateProductName(value: string | undefined): ValidationResult if (name.length < PRODUCT_NAME_MIN_LENGTH) { return { isValid: false, - error: `Product name must be at least ${PRODUCT_NAME_MIN_LENGTH} characters` + error: `Product name must be at least ${PRODUCT_NAME_MIN_LENGTH} characters`, }; } if (name.length > PRODUCT_NAME_MAX_LENGTH) { return { isValid: false, - error: `Product name must be at most ${PRODUCT_NAME_MAX_LENGTH} characters` + error: `Product name must be at most ${PRODUCT_NAME_MAX_LENGTH} characters`, }; } @@ -55,25 +55,7 @@ export function isValidUrl(value: string | undefined): boolean { } } -export function isValidUrl(value: string | undefined): boolean { - if (!value || typeof value !== 'string') return false; - - const trimmed = value.trim(); - if (trimmed.length === 0) return false; - - try { - const url = new URL(trimmed); - // Check if protocol is http or https - return url.protocol === 'http:' || url.protocol === 'https:'; - } catch { - return false; - } -} - -export function validateProductDimension( - value: number | undefined, - dimensionName: string -): ValidationResult { +export function validateProductDimension(value: number | undefined, dimensionName: string): ValidationResult { if (value == null || Number.isNaN(value)) { return { isValid: true }; // Optional field } @@ -81,7 +63,7 @@ export function validateProductDimension( if (typeof value !== 'number' || value <= 0) { return { isValid: false, - error: `${dimensionName} must be a positive number` + error: `${dimensionName} must be a positive number`, }; } diff --git a/frontend-app/src/services/api/validation/user.ts b/frontend-app/src/services/api/validation/user.ts index c81b3b8..7ed6057 100644 --- a/frontend-app/src/services/api/validation/user.ts +++ b/frontend-app/src/services/api/validation/user.ts @@ -27,21 +27,21 @@ export function validateUsername(value: string | undefined): ValidationResult { if (username.length < USERNAME_MIN_LENGTH) { return { isValid: false, - error: `Username must be at least ${USERNAME_MIN_LENGTH} characters` + error: `Username must be at least ${USERNAME_MIN_LENGTH} characters`, }; } if (username.length > USERNAME_MAX_LENGTH) { return { isValid: false, - error: `Username must be at most ${USERNAME_MAX_LENGTH} characters` + error: `Username must be at most ${USERNAME_MAX_LENGTH} characters`, }; } if (!USERNAME_PATTERN.test(username)) { return { isValid: false, - error: 'Username can only contain letters, numbers, and underscores' + error: 'Username can only contain letters, numbers, and underscores', }; } @@ -72,11 +72,7 @@ export function getEmailHelperText(): string { return 'Enter a valid email address'; } -export function validatePassword( - value: string | undefined, - username?: string, - email?: string -): ValidationResult { +export function validatePassword(value: string | undefined, username?: string, email?: string): ValidationResult { const password = typeof value === 'string' ? value : ''; if (!password) { @@ -86,14 +82,14 @@ export function validatePassword( if (password.length < PASSWORD_MIN_LENGTH) { return { isValid: false, - error: `Password must be at least ${PASSWORD_MIN_LENGTH} characters` + error: `Password must be at least ${PASSWORD_MIN_LENGTH} characters`, }; } if (password.length > PASSWORD_MAX_LENGTH) { return { isValid: false, - error: `Password must be at most ${PASSWORD_MAX_LENGTH} characters` + error: `Password must be at most ${PASSWORD_MAX_LENGTH} characters`, }; } @@ -101,18 +97,20 @@ export function validatePassword( if (username && password.toLowerCase().includes(username.toLowerCase())) { return { isValid: false, - error: 'Password cannot contain your username' + error: 'Password cannot contain your username', }; } // Check if password contains email or email username part if (email) { const emailUsername = email.split('@')[0]; - if (password.toLowerCase().includes(email.toLowerCase()) || - password.toLowerCase().includes(emailUsername.toLowerCase())) { + if ( + password.toLowerCase().includes(email.toLowerCase()) || + password.toLowerCase().includes(emailUsername.toLowerCase()) + ) { return { isValid: false, - error: 'Password cannot contain your email address' + error: 'Password cannot contain your email address', }; } } From cd06b0279a0762a205f06bb31a65924f486c77ef Mon Sep 17 00:00:00 2001 From: Simon van Lierde Date: Wed, 29 Oct 2025 12:14:12 +0000 Subject: [PATCH 16/71] fix(backend): remove logging info --- backend/app/api/auth/services/user_manager.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/backend/app/api/auth/services/user_manager.py b/backend/app/api/auth/services/user_manager.py index daad8b7..0eedec0 100644 --- a/backend/app/api/auth/services/user_manager.py +++ b/backend/app/api/auth/services/user_manager.py @@ -139,7 +139,7 @@ async def on_after_verify(self, user: User, request: Request | None = None) -> N await send_post_verification_email(user.email, user.username) async def on_after_forgot_password(self, user: User, token: str, request: Request | None = None) -> None: # noqa: ARG002 # Request argument is expected in the method signature - logger.info("User %s has forgot their password. Reset token: %s", user.email, token) + logger.info("User %s has forgot their password. Sending reset token", user.email) await send_reset_password_email(user.email, user.username, token) From 8b6f233a99bb7115f1d5fa1ca8fb10350c5a284e Mon Sep 17 00:00:00 2001 From: Simon van Lierde Date: Wed, 29 Oct 2025 13:28:53 +0100 Subject: [PATCH 17/71] docs(backend): Clarify config setup (local .env file vs. env vars in docker) --- backend/app/api/auth/config.py | 2 +- backend/app/api/plugins/rpi_cam/config.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/backend/app/api/auth/config.py b/backend/app/api/auth/config.py index e412c4f..657e290 100644 --- a/backend/app/api/auth/config.py +++ b/backend/app/api/auth/config.py @@ -29,7 +29,7 @@ class AuthSettings(BaseSettings): email_from: str = "" email_reply_to: str = "" - # Initialize the settings configuration from the .env file + # Initialize the settings configuration from the .env file (or direct environment variables in Docker) model_config = SettingsConfigDict(env_file=BASE_DIR / ".env", extra="ignore") # Set default values for email settings if not provided diff --git a/backend/app/api/plugins/rpi_cam/config.py b/backend/app/api/plugins/rpi_cam/config.py index 4d40723..5088326 100644 --- a/backend/app/api/plugins/rpi_cam/config.py +++ b/backend/app/api/plugins/rpi_cam/config.py @@ -14,7 +14,7 @@ class RPiCamSettings(BaseSettings): # Authentication settings rpi_cam_plugin_secret: str = "" - # Initialize the settings configuration from the .env file + # Initialize the settings configuration from the .env file (or direct environment variables in Docker) model_config = SettingsConfigDict(env_file=BASE_DIR / ".env", extra="ignore") api_key_header_name: str = "X-API-Key" From 2fe6e3699edd1fee312dd6504df73e629f0322e7 Mon Sep 17 00:00:00 2001 From: Simon van Lierde Date: Wed, 29 Oct 2025 13:49:04 +0000 Subject: [PATCH 18/71] feature(frontend-app): Add tooltip to product save button showing validation status --- frontend-app/src/app/products/[id]/index.tsx | 35 ++++++++++++------- .../src/services/api/validation/product.ts | 15 ++++---- 2 files changed, 32 insertions(+), 18 deletions(-) diff --git a/frontend-app/src/app/products/[id]/index.tsx b/frontend-app/src/app/products/[id]/index.tsx index 3b57952..201b7c1 100644 --- a/frontend-app/src/app/products/[id]/index.tsx +++ b/frontend-app/src/app/products/[id]/index.tsx @@ -1,10 +1,10 @@ import { MaterialCommunityIcons } from '@expo/vector-icons'; import { HeaderBackButton } from '@react-navigation/elements'; import { useLocalSearchParams, useNavigation, useRouter } from 'expo-router'; -import { JSX, useCallback, useEffect, useState } from 'react'; +import { JSX, useCallback, useEffect, useMemo, useState } from 'react'; import { ActivityIndicator, NativeScrollEvent, NativeSyntheticEvent, View } from 'react-native'; import { KeyboardAwareScrollView } from 'react-native-keyboard-controller'; -import { AnimatedFAB, Button, useTheme } from 'react-native-paper'; +import { AnimatedFAB, Button, Tooltip, useTheme } from 'react-native-paper'; import ProductAmountInParent from '@/components/product/ProductAmountInParent'; import ProductComponents from '@/components/product/ProductComponents'; @@ -50,9 +50,13 @@ export default function ProductPage(): JSX.Element { const [editMode, setEditMode] = useState(id === 'new' || false); const [savingState, setSavingState] = useState<'saving' | 'success' | undefined>(undefined); const [fabExtended, setFabExtended] = useState(true); + const [tooltipVisible, setTooltipVisible] = useState(false); const isProductComponent = typeof product.parentID === 'number' && !isNaN(product.parentID); + // Validate product on every change + const validationResult = useMemo(() => validateProduct(product), [product]); + // Callbacks const onProductNameChange = useCallback( (newName: string) => { @@ -256,15 +260,22 @@ export default function ProductPage(): JSX.Element { - + + setTooltipVisible(true)} + style={{ position: 'absolute', right: 0, bottom: 0, overflow: 'hidden', margin: 19 }} + disabled={!validationResult.isValid} + extended={fabExtended} + label={editMode ? 'Save Product' : 'Edit Product'} + visible={product.ownedBy === 'me'} + /> + ); } @@ -312,4 +323,4 @@ function EditNameButton({ }; return ; -} +} \ No newline at end of file diff --git a/frontend-app/src/services/api/validation/product.ts b/frontend-app/src/services/api/validation/product.ts index fd7e7c5..8639dda 100644 --- a/frontend-app/src/services/api/validation/product.ts +++ b/frontend-app/src/services/api/validation/product.ts @@ -95,7 +95,10 @@ export function validateProductVideos(videos: { title: string; url: string }[]): } export function validateProduct(product: Product): ValidationResult { - const { weight, width, height, depth } = product.physicalProperties; + // Handle undefined or incomplete product + if (!product || typeof product !== 'object') { + return { isValid: false, error: 'Invalid product data' }; + } // Validate product name const nameResult = validateProductName(product.name); @@ -103,6 +106,10 @@ export function validateProduct(product: Product): ValidationResult { return nameResult; } + // Safely access physicalProperties with fallback + const physicalProperties = product.physicalProperties || {}; + const { weight, width, height, depth } = physicalProperties; + // Validate weight const weightResult = validateProductWeight(weight); if (!weightResult.isValid) { @@ -132,8 +139,4 @@ export function validateProduct(product: Product): ValidationResult { } return { isValid: true }; -} - -export function isProductValid(product: Product): boolean { - return validateProduct(product).isValid; -} +} \ No newline at end of file From ac2ab05646b7e3ef591b5b4810552110526e7c05 Mon Sep 17 00:00:00 2001 From: Simon van Lierde Date: Mon, 3 Nov 2025 11:25:32 +0000 Subject: [PATCH 19/71] feature(backend): add order_by, created_at and updated_at filters for product get endpoint --- backend/app/api/data_collection/filters.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/backend/app/api/data_collection/filters.py b/backend/app/api/data_collection/filters.py index c01d801..4d40d20 100644 --- a/backend/app/api/data_collection/filters.py +++ b/backend/app/api/data_collection/filters.py @@ -58,6 +58,11 @@ class ProductFilter(Filter): dismantling_time_start__lte: datetime | None = None dismantling_time_end__gte: datetime | None = None dismantling_time_end__lte: datetime | None = None + created_at__gte: datetime | None = None + created_at__lte: datetime | None = None + updated_at__gte: datetime | None = None + updated_at__lte: datetime | None = None + order_by: list[str] | None = None search: str | None = None From d0f5247b4ea46287defc7a662fd4c176c0e52a2d Mon Sep 17 00:00:00 2001 From: Simon van Lierde Date: Tue, 4 Nov 2025 16:05:05 +0100 Subject: [PATCH 20/71] feature(backend): Move to mjml email templates and fastapi-email to simplify email setup --- CONTRIBUTING.md | 27 ++ backend/app/api/auth/config.py | 3 +- backend/app/api/auth/utils/email_config.py | 31 +++ .../app/api/auth/utils/programmatic_emails.py | 252 ++++++++---------- backend/app/api/newsletter/routers.py | 16 +- backend/app/api/newsletter/utils/emails.py | 121 ++++----- .../emails/src/components/footer.mjml | 15 ++ .../emails/src/components/header.mjml | 5 + .../emails/src/components/styles.mjml | 9 + .../app/templates/emails/src/newsletter.mjml | 35 +++ .../emails/src/newsletter_subscription.mjml | 28 ++ .../emails/src/newsletter_unsubscribe.mjml | 30 +++ .../templates/emails/src/password_reset.mjml | 25 ++ .../emails/src/post_verification.mjml | 19 ++ .../templates/emails/src/registration.mjml | 50 ++++ .../templates/emails/src/verification.mjml | 25 ++ backend/app/templates/login.html | 4 +- backend/pyproject.toml | 2 + backend/scripts/compile_email_templates.py | 67 +++++ backend/tests/conftest.py | 61 ++++- backend/tests/constants/__init__.py | 1 - backend/tests/constants/background_data.py | 1 - backend/tests/factories/background_data.py | 6 - backend/tests/factories/emails.py | 26 ++ backend/tests/tests/emails/__init__.py | 1 + .../tests/emails/test_programmatic_emails.py | 227 ++++++++++++++++ 26 files changed, 864 insertions(+), 223 deletions(-) create mode 100644 backend/app/api/auth/utils/email_config.py create mode 100644 backend/app/templates/emails/src/components/footer.mjml create mode 100644 backend/app/templates/emails/src/components/header.mjml create mode 100644 backend/app/templates/emails/src/components/styles.mjml create mode 100644 backend/app/templates/emails/src/newsletter.mjml create mode 100644 backend/app/templates/emails/src/newsletter_subscription.mjml create mode 100644 backend/app/templates/emails/src/newsletter_unsubscribe.mjml create mode 100644 backend/app/templates/emails/src/password_reset.mjml create mode 100644 backend/app/templates/emails/src/post_verification.mjml create mode 100644 backend/app/templates/emails/src/registration.mjml create mode 100644 backend/app/templates/emails/src/verification.mjml create mode 100755 backend/scripts/compile_email_templates.py delete mode 100644 backend/tests/constants/__init__.py delete mode 100644 backend/tests/constants/background_data.py delete mode 100644 backend/tests/factories/background_data.py create mode 100644 backend/tests/factories/emails.py create mode 100644 backend/tests/tests/emails/__init__.py create mode 100644 backend/tests/tests/emails/test_programmatic_emails.py diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index e3148c9..b7c8b97 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -20,6 +20,7 @@ Thank you for your interest in contributing to the Reverse Engineering Lab proje - [Backend Code Style](#backend-code-style) - [Backend Testing](#backend-testing) - [Database Migrations](#database-migrations) + - [Email templates](#email-templates) - [Frontend Development](#frontend-development) - [Frontend Code Style](#frontend-code-style) - [Frontend Testing](#frontend-testing) @@ -339,6 +340,32 @@ When making changes to the database schema: uv run alembic upgrade head ``` +#### Email templates + +This project uses [MJML](https://mjml.io/) to write email templates and [Jinja2](https://jinja.palletsprojects.com/en/latest/) for variable substitution at runtime. + +- **Location** + - Source MJML templates: `backend/app/templates/emails/src/` + - Reusable components: `backend/app/templates/emails/src/components/` + - Compiled HTML output: `backend/app/templates/emails/build/` (This directory is **auto-generated**—do not edit files here.) + +- **Editing Guidelines** + - Use **MJML** for structure and the `{{include:component_name}}` directive to reuse components. + - Use **Jinja2-style variables** in templates, e.g., `{{ username }}`, `{{ verification_link }}`. + - Keep components small and shared styles in `src/components/styles.mjml`. + - **Do not modify** files in `build/`. + +- **Compiling Templates** + Run the compilation script from the repository root: + + ```bash + cd backend + python scripts/compile_email_templates.py + ``` + +- **Interactive Preview** + For visual development, use MJML online tools or the [MJML VS Code extension](https://marketplace.visualstudio.com/items?itemName=mjmlio.vscode-mjml). + ### Frontend Development Set up your environment as described in the [Getting Started](#getting-started) section. diff --git a/backend/app/api/auth/config.py b/backend/app/api/auth/config.py index 657e290..d3ccfb1 100644 --- a/backend/app/api/auth/config.py +++ b/backend/app/api/auth/config.py @@ -2,6 +2,7 @@ from pathlib import Path +from pydantic import SecretStr from pydantic_settings import BaseSettings, SettingsConfigDict # Set the project base directory and .env file @@ -25,7 +26,7 @@ class AuthSettings(BaseSettings): email_host: str = "" email_port: int = 587 # Default SMTP port for TLS email_username: str = "" - email_password: str = "" + email_password: SecretStr = SecretStr("") email_from: str = "" email_reply_to: str = "" diff --git a/backend/app/api/auth/utils/email_config.py b/backend/app/api/auth/utils/email_config.py new file mode 100644 index 0000000..d2d2284 --- /dev/null +++ b/backend/app/api/auth/utils/email_config.py @@ -0,0 +1,31 @@ +"""Email configuration for fastapi-mail. + +This module provides the FastMail instance and configuration for sending emails +throughout the application. +""" + +from pathlib import Path + +from fastapi_mail import ConnectionConfig, FastMail + +from app.api.auth.config import settings as auth_settings + +# Path to pre-compiled HTML email templates +TEMPLATE_FOLDER = Path(__file__).parent.parent.parent.parent / "templates" / "emails" / "build" + +# Configure email connection +email_conf = ConnectionConfig( + MAIL_USERNAME=auth_settings.email_username, + MAIL_PASSWORD=auth_settings.email_password, + MAIL_FROM=auth_settings.email_from, + MAIL_PORT=auth_settings.email_port, + MAIL_SERVER=auth_settings.email_host, + MAIL_STARTTLS=True, + MAIL_SSL_TLS=False, + USE_CREDENTIALS=True, + VALIDATE_CERTS=True, + TEMPLATE_FOLDER=TEMPLATE_FOLDER, +) + +# Create FastMail instance +fm = FastMail(email_conf) diff --git a/backend/app/api/auth/utils/programmatic_emails.py b/backend/app/api/auth/utils/programmatic_emails.py index e9bef95..97bee35 100644 --- a/backend/app/api/auth/utils/programmatic_emails.py +++ b/backend/app/api/auth/utils/programmatic_emails.py @@ -1,168 +1,140 @@ -"""Utilities for sending authentication-related emails.""" +"""Utilities for sending authentication-related emails using fastapi-mail.""" import logging -from email.mime.multipart import MIMEMultipart -from email.mime.text import MIMEText -from enum import Enum +from typing import Any from urllib.parse import urljoin -import markdown -from aiosmtplib import SMTP, SMTPException +from fastapi import BackgroundTasks +from fastapi_mail import MessageSchema, MessageType +from pydantic import AnyUrl, EmailStr -from app.api.auth.config import settings as auth_settings +from app.api.auth.utils.email_config import fm from app.core.config import settings as core_settings logger: logging.Logger = logging.getLogger(__name__) -### Common email functions ### -# TODO: Move to using MJML or similar templating system for email content. - - -class TextContentType(str, Enum): - """Type for specifying the content type of the email body.""" - - PLAIN = "plain" - HTML = "html" - MARKDOWN = "markdown" - - def body_to_mimetext(self, body: str) -> MIMEText: - """Convert an email body to MIMEText format.""" - match self: - case TextContentType.PLAIN: - return MIMEText(body, "plain") - case TextContentType.HTML: - return MIMEText(body, "html") - case TextContentType.MARKDOWN: - # Convert Markdown to HTML - html = markdown.markdown(body) - return MIMEText(html, "html") +### Helper functions ### +def generate_token_link(token: str, route: str, base_url: str | AnyUrl | None = None) -> str: + """Generate a link with the specified token and route.""" + if base_url is None: + # Default to frontend app URL from core settings + base_url = str(core_settings.frontend_app_url) + return urljoin(str(base_url), f"{route}?token={token}") -async def send_email( - to_email: str, +async def send_email_with_template( + to_email: EmailStr, subject: str, - body: str, - content_type: TextContentType = TextContentType.PLAIN, - headers: dict | None = None, + template_name: str, + template_body: dict[str, Any], + background_tasks: BackgroundTasks | None = None, +) -> None: + """Send an HTML email using a template. + + Args: + to_email: Recipient email address + subject: Email subject line + template_name: Name of the template file (e.g., "registration.html") + template_body: Dictionary of variables to pass to the template + background_tasks: Optional BackgroundTasks instance for async sending + """ + message = MessageSchema( + subject=subject, + recipients=[to_email], + template_body=template_body, + subtype=MessageType.html, + ) + + if background_tasks: + background_tasks.add_task(fm.send_message, message, template_name=template_name) + logger.info("Email queued for background sending to %s using template %s", to_email, template_name) + else: + await fm.send_message(message, template_name=template_name) + logger.info("Email sent to %s using template %s", to_email, template_name) + + +### Authentication email functions ### +async def send_registration_email( + to_email: EmailStr, + username: str | None, + token: str, + background_tasks: BackgroundTasks | None = None, ) -> None: - """Send an email with the specified subject and body.""" - msg = MIMEMultipart() - msg["From"] = auth_settings.email_from - msg["Reply-To"] = auth_settings.email_reply_to - msg["To"] = to_email - msg["Subject"] = subject - - # Add additional headers if provided - if headers: - for key, value in headers.items(): - msg[key] = value - - # Attach the body in the specified content type - msg.attach(content_type.body_to_mimetext(body)) - - try: - # TODO: Investigate use of managed outlook address for sending emails - smtp = SMTP( - hostname=auth_settings.email_host, - port=auth_settings.email_port, - ) - await smtp.connect() - await smtp.login(auth_settings.email_username, auth_settings.email_password) - await smtp.send_message(msg) - await smtp.quit() - logger.info("Email sent to %s", to_email) - except SMTPException as e: - error_message = f"Error sending email: {e}" - raise SMTPException(error_message) from e - - -def generate_token_link(token: str, route: str) -> str: - """Generate a link with the specified token and route.""" - # TODO: Check that the base url works in remote deployment - return urljoin(str(core_settings.frontend_app_url), f"{route}?token={token}") - - -### Email content ### -async def send_registration_email(to_email: str, username: str | None, token: str) -> None: """Send a registration email with verification token.""" - # TODO: Store frontend paths required by the backend in a shared .env or other config file in the root directory - # Alternatively, we can send the right path as a parameter from the frontend to the backend verification_link = generate_token_link(token, "/verify") subject = "Welcome to Reverse Engineering Lab - Verify Your Email" - body = f""" -Hello {username if username else to_email}, - -Thank you for registering! Please verify your email by clicking the link below: -{verification_link} - -This link will expire in 1 hour. - -If you did not register for this service, please ignore this email. - -Best regards, - -The Reverse Engineering Lab Team - """ - - await send_email(subject=subject, body=body, to_email=to_email) - - -async def send_reset_password_email(to_email: str, username: str | None, token: str) -> None: + await send_email_with_template( + to_email=to_email, + subject=subject, + template_name="registration.html", + template_body={ + "username": username if username else to_email, + "verification_link": verification_link, + }, + background_tasks=background_tasks, + ) + + +async def send_reset_password_email( + to_email: EmailStr, + username: str | None, + token: str, + background_tasks: BackgroundTasks | None = None, +) -> None: """Send a reset password email with the token.""" - request_password_link = generate_token_link(token, "/reset-password") + reset_link = generate_token_link(token, "/reset-password") subject = "Password Reset" - body = f""" -Hello {username if username else to_email}, - -Please reset your password by clicking the link below: -{request_password_link} - -This link will expire in 1 hour. - -If you did not request a password reset, please ignore this email. - -Best regards, - -The Reverse Engineering Lab Team - """ - await send_email(to_email, subject, body) - - -async def send_verification_email(to_email: str, username: str | None, token: str) -> None: + await send_email_with_template( + to_email=to_email, + subject=subject, + template_name="password_reset.html", + template_body={ + "username": username if username else to_email, + "reset_link": reset_link, + }, + background_tasks=background_tasks, + ) + + +async def send_verification_email( + to_email: EmailStr, + username: str | None, + token: str, + background_tasks: BackgroundTasks | None = None, +) -> None: """Send a verification email with the token.""" verification_link = generate_token_link(token, "/verify") subject = "Email Verification" - body = f""" -Hello {username if username else to_email}, - -Please verify your email by clicking the link below: - -{verification_link} -This link will expire in 1 hour. - -If you did not request verification, please ignore this email. - -Best regards, - -The Reverse Engineering Lab Team - """ - await send_email(to_email, subject, body) - - -async def send_post_verification_email(to_email: str, username: str | None) -> None: + await send_email_with_template( + to_email=to_email, + subject=subject, + template_name="verification.html", + template_body={ + "username": username if username else to_email, + "verification_link": verification_link, + }, + background_tasks=background_tasks, + ) + + +async def send_post_verification_email( + to_email: EmailStr, + username: str | None, + background_tasks: BackgroundTasks | None = None, +) -> None: """Send a post-verification email.""" subject = "Email Verified" - body = f""" -Hello {username if username else to_email}, - -Your email has been verified! -Best regards, - -The Reverse Engineering Lab Team - """ - await send_email(to_email, subject, body) + await send_email_with_template( + to_email=to_email, + subject=subject, + template_name="post_verification.html", + template_body={ + "username": username if username else to_email, + }, + background_tasks=background_tasks, + ) diff --git a/backend/app/api/newsletter/routers.py b/backend/app/api/newsletter/routers.py index 4483832..83f7b00 100644 --- a/backend/app/api/newsletter/routers.py +++ b/backend/app/api/newsletter/routers.py @@ -3,7 +3,7 @@ from collections.abc import Sequence from typing import Annotated -from fastapi import APIRouter, HTTPException, Security +from fastapi import APIRouter, BackgroundTasks, HTTPException, Security from fastapi.params import Body from pydantic import EmailStr from sqlmodel import select @@ -23,7 +23,9 @@ @backend_router.post("/subscribe", status_code=201, response_model=NewsletterSubscriberRead) -async def subscribe_to_newsletter(email: Annotated[EmailStr, Body()], db: AsyncSessionDep) -> NewsletterSubscriber: +async def subscribe_to_newsletter( + email: Annotated[EmailStr, Body()], db: AsyncSessionDep, background_tasks: BackgroundTasks +) -> NewsletterSubscriber: """Subscribe to the newsletter to receive updates about the app launch.""" # Check if the email already exists existing_subscriber = ( @@ -36,7 +38,7 @@ async def subscribe_to_newsletter(email: Annotated[EmailStr, Body()], db: AsyncS # If not confirmed, generate new token and send email token = create_jwt_token(email, JWTType.NEWSLETTER_CONFIRMATION) - await send_newsletter_subscription_email(email, token) + await send_newsletter_subscription_email(email, token, background_tasks=background_tasks) raise HTTPException( status_code=400, detail="Already subscribed, but not confirmed. A new confirmation email has been sent.", @@ -50,7 +52,7 @@ async def subscribe_to_newsletter(email: Annotated[EmailStr, Body()], db: AsyncS # Send confirmation email token = create_jwt_token(email, JWTType.NEWSLETTER_CONFIRMATION) - await send_newsletter_subscription_email(email, token) + await send_newsletter_subscription_email(email, token, background_tasks=background_tasks) return new_subscriber @@ -83,7 +85,9 @@ async def confirm_newsletter_subscription(token: Annotated[str, Body()], db: Asy @backend_router.post("/request-unsubscribe", status_code=200) -async def request_unsubscribe(email: Annotated[EmailStr, Body()], db: AsyncSessionDep) -> dict: +async def request_unsubscribe( + email: Annotated[EmailStr, Body()], db: AsyncSessionDep, background_tasks: BackgroundTasks +) -> dict: """Request to unsubscribe by sending an email with unsubscribe link.""" # Check if the email is subscribed existing_subscriber = ( @@ -98,7 +102,7 @@ async def request_unsubscribe(email: Annotated[EmailStr, Body()], db: AsyncSessi token = create_jwt_token(email, JWTType.NEWSLETTER_UNSUBSCRIBE) # Send unsubscription email with the link - await send_newsletter_unsubscription_request_email(email, token) + await send_newsletter_unsubscription_request_email(email, token, background_tasks=background_tasks) return {"message": "If you are subscribed, we've sent an unsubscribe link to your email."} diff --git a/backend/app/api/newsletter/utils/emails.py b/backend/app/api/newsletter/utils/emails.py index 32b4459..cc4d85c 100644 --- a/backend/app/api/newsletter/utils/emails.py +++ b/backend/app/api/newsletter/utils/emails.py @@ -1,71 +1,72 @@ """Email sending utilities for the newsletter service.""" -from app.api.auth.utils.programmatic_emails import TextContentType, generate_token_link, send_email +from fastapi import BackgroundTasks +from pydantic import EmailStr + +from app.api.auth.utils.programmatic_emails import generate_token_link, send_email_with_template from app.api.newsletter.utils.tokens import JWTType, create_jwt_token +from app.core.config import settings as core_settings -async def send_newsletter_subscription_email(to_email: str, token: str) -> None: +async def send_newsletter_subscription_email( + to_email: EmailStr, + token: str, + background_tasks: BackgroundTasks | None = None, +) -> None: """Send a newsletter subscription email.""" subject = "Reverse Engineering Lab: Confirm Your Newsletter Subscription" - # TODO: Dynamically generate the confirmation link based on the frontend URL tree - # Alternatively, send the frontend-side link to the backend as a parameter - confirmation_link = generate_token_link(token, "newsletter/confirm") - - body = f""" -Hello, - -Thank you for subscribing to the Reverse Engineering Lab newsletter! - -Please confirm your subscription by clicking [here]({confirmation_link}). - -This link will expire in 24 hours. - -We'll keep you updated with our progress and let you know when the full application is launched. - -Best regards, - -The Reverse Engineering Lab Team - """ - await send_email(to_email, subject, body, content_type=TextContentType.MARKDOWN) - - -async def send_newsletter(to_email: str, subject: str, content: str) -> None: - """Send newsletter with proper unsubscribe headers.""" + confirmation_link = generate_token_link(token, "newsletter/confirm", base_url=core_settings.frontend_web_url) + + await send_email_with_template( + to_email=to_email, + subject=subject, + template_name="newsletter_subscription.html", + template_body={ + "confirmation_link": confirmation_link, + }, + background_tasks=background_tasks, + ) + + +async def send_newsletter( + to_email: EmailStr, + subject: str, + content: str, + background_tasks: BackgroundTasks | None = None, +) -> None: + """Send newsletter with proper unsubscribe link.""" # Create unsubscribe token and link token = create_jwt_token(to_email, JWTType.NEWSLETTER_UNSUBSCRIBE) - unsubscribe_link = generate_token_link(token, "newsletter/unsubscribe") - - # Add footer with unsubscribe link - body = f""" - {content} - ---- -You're receiving this email because you subscribed to the Reverse Engineering Lab newsletter. -To unsubscribe, click [here]({unsubscribe_link}) - """ - - # Add List-Unsubscribe header for email clients that support it - headers = {"List-Unsubscribe": f"<{unsubscribe_link}>", "List-Unsubscribe-Post": "List-Unsubscribe=One-Click"} - - await send_email(to_email, subject, body, content_type=TextContentType.MARKDOWN, headers=headers) - - -async def send_newsletter_unsubscription_request_email(to_email: str, token: str) -> None: + unsubscribe_link = generate_token_link(token, "newsletter/unsubscribe", base_url=core_settings.frontend_web_url) + + await send_email_with_template( + to_email=to_email, + subject=subject, + template_name="newsletter.html", + template_body={ + "subject": subject, + "content": content, + "unsubscribe_link": unsubscribe_link, + }, + background_tasks=background_tasks, + ) + + +async def send_newsletter_unsubscription_request_email( + to_email: EmailStr, + token: str, + background_tasks: BackgroundTasks | None = None, +) -> None: """Send an email with unsubscribe link.""" subject = "Reverse Engineering Lab: Unsubscribe Request" - unsubscribe_link = generate_token_link(token, "newsletter/unsubscribe") - - body = f""" -Hello, - -We received a request to unsubscribe this email address from the Reverse Engineering Lab newsletter. - -If you made this request, please click [here]({unsubscribe_link}) to unsubscribe. - -If you did not request to unsubscribe, you can safely ignore this email. - -Best regards, - -The Reverse Engineering Lab Team - """ - await send_email(to_email, subject, body, content_type=TextContentType.MARKDOWN) + unsubscribe_link = generate_token_link(token, "newsletter/unsubscribe", base_url=core_settings.frontend_web_url) + + await send_email_with_template( + to_email=to_email, + subject=subject, + template_name="newsletter_unsubscribe.html", + template_body={ + "unsubscribe_link": unsubscribe_link, + }, + background_tasks=background_tasks, + ) diff --git a/backend/app/templates/emails/src/components/footer.mjml b/backend/app/templates/emails/src/components/footer.mjml new file mode 100644 index 0000000..19da9ed --- /dev/null +++ b/backend/app/templates/emails/src/components/footer.mjml @@ -0,0 +1,15 @@ + + + + + Best regards,
+ The Reverse Engineering Lab Team +
+
+
+ + + + This email was sent from Reverse Engineering Lab + + diff --git a/backend/app/templates/emails/src/components/header.mjml b/backend/app/templates/emails/src/components/header.mjml new file mode 100644 index 0000000..caafe50 --- /dev/null +++ b/backend/app/templates/emails/src/components/header.mjml @@ -0,0 +1,5 @@ + + + Reverse Engineering Lab + + diff --git a/backend/app/templates/emails/src/components/styles.mjml b/backend/app/templates/emails/src/components/styles.mjml new file mode 100644 index 0000000..a564039 --- /dev/null +++ b/backend/app/templates/emails/src/components/styles.mjml @@ -0,0 +1,9 @@ + + + + + + + .header { font-size: 24px; font-weight: bold; color: #007bff; } .footer { font-size: 12px; color: #666666; } .success + { font-size: 18px; color: #28a745; font-weight: bold; } + diff --git a/backend/app/templates/emails/src/newsletter.mjml b/backend/app/templates/emails/src/newsletter.mjml new file mode 100644 index 0000000..274d6d4 --- /dev/null +++ b/backend/app/templates/emails/src/newsletter.mjml @@ -0,0 +1,35 @@ + + + {{subject}} + {{include:styles}} + + + {{include:header}} + + + + {{content}} + + + + + + + + Best regards,
+ The Reverse Engineering Lab Team +
+
+
+ + + + + + You're receiving this email because you subscribed to the Reverse Engineering Lab newsletter.
+ Unsubscribe +
+
+
+
+
diff --git a/backend/app/templates/emails/src/newsletter_subscription.mjml b/backend/app/templates/emails/src/newsletter_subscription.mjml new file mode 100644 index 0000000..89b0294 --- /dev/null +++ b/backend/app/templates/emails/src/newsletter_subscription.mjml @@ -0,0 +1,28 @@ + + + Reverse Engineering Lab: Confirm Your Newsletter Subscription + {{include:styles}} + + + {{include:header}} + + + + Hello, + Thank you for subscribing to the Reverse Engineering Lab newsletter! + Please confirm your subscription by clicking the button below: + Confirm Subscription + + Or copy and paste this link in your browser:
+ {{confirmation_link}} +
+ This link will expire in 24 hours. + + We'll keep you updated with our progress and let you know when the full application is launched. + +
+
+ + {{include:footer}} +
+
diff --git a/backend/app/templates/emails/src/newsletter_unsubscribe.mjml b/backend/app/templates/emails/src/newsletter_unsubscribe.mjml new file mode 100644 index 0000000..05f2d4b --- /dev/null +++ b/backend/app/templates/emails/src/newsletter_unsubscribe.mjml @@ -0,0 +1,30 @@ + + + Reverse Engineering Lab: Unsubscribe Request + {{include:styles}} + + + + + + {{include:header}} + + + + Hello, + + We received a request to unsubscribe this email address from the Reverse Engineering Lab newsletter. + + If you made this request, please click the button below to unsubscribe: + Unsubscribe + + Or copy and paste this link in your browser:
+ {{unsubscribe_link}} +
+ If you did not request to unsubscribe, you can safely ignore this email. +
+
+ + {{include:footer}} +
+
diff --git a/backend/app/templates/emails/src/password_reset.mjml b/backend/app/templates/emails/src/password_reset.mjml new file mode 100644 index 0000000..0ec11a7 --- /dev/null +++ b/backend/app/templates/emails/src/password_reset.mjml @@ -0,0 +1,25 @@ + + + Password Reset + {{include:styles}} + + + {{include:header}} + + + + Hello {{username}}, + Please reset your password by clicking the button below: + Reset Password + + Or copy and paste this link in your browser:
+ {{reset_link}} +
+ This link will expire in 1 hour. + If you did not request a password reset, please ignore this email. +
+
+ + {{include:footer}} +
+
diff --git a/backend/app/templates/emails/src/post_verification.mjml b/backend/app/templates/emails/src/post_verification.mjml new file mode 100644 index 0000000..8961c8b --- /dev/null +++ b/backend/app/templates/emails/src/post_verification.mjml @@ -0,0 +1,19 @@ + + + Email Verified + {{include:styles}} + + + {{include:header}} + + + + Hello {{username}}, + Your email has been verified! + Thank you for verifying your email address. You can now enjoy full access to all features. + + + + {{include:footer}} + + diff --git a/backend/app/templates/emails/src/registration.mjml b/backend/app/templates/emails/src/registration.mjml new file mode 100644 index 0000000..437203c --- /dev/null +++ b/backend/app/templates/emails/src/registration.mjml @@ -0,0 +1,50 @@ + + + Welcome to Reverse Engineering Lab - Verify Your Email + + + + + + + .header { font-size: 24px; font-weight: bold; color: #007bff; } .footer { font-size: 12px; color: #666666; } + + + + + + Reverse Engineering Lab + + + + + + Hello {{ username }}, + Thank you for registering! Please verify your email by clicking the button below: + Verify Email Address + + Or copy and paste this link in your browser:
+ {{ verification_link }} +
+ This link will expire in 1 hour. + If you did not register for this service, please ignore this email. +
+
+ + + + + + Best regards,
+ The Reverse Engineering Lab Team +
+
+
+ + + + This email was sent from Reverse Engineering Lab + + +
+
diff --git a/backend/app/templates/emails/src/verification.mjml b/backend/app/templates/emails/src/verification.mjml new file mode 100644 index 0000000..cc324a5 --- /dev/null +++ b/backend/app/templates/emails/src/verification.mjml @@ -0,0 +1,25 @@ + + + Email Verification + {{include:styles}} + + + {{include:header}} + + + + Hello {{username}}, + Please verify your email by clicking the button below: + Verify Email Address + + Or copy and paste this link in your browser:
+ {{verification_link}} +
+ This link will expire in 1 hour. + If you did not request verification, please ignore this email. +
+
+ + {{include:footer}} +
+
diff --git a/backend/app/templates/login.html b/backend/app/templates/login.html index 3adfb68..1fb1f6d 100644 --- a/backend/app/templates/login.html +++ b/backend/app/templates/login.html @@ -35,7 +35,7 @@

Login

const errorDiv = document.getElementById('error') const nextInput = document.getElementById('next') const nextValue = nextInput ? nextInput.value : null - + try { const response = await fetch('/auth/cookie/login', { method: 'POST', @@ -49,7 +49,7 @@

Login

}), credentials: 'include' }) - + if (response.ok) { window.location.href = nextValue || '{{ url_for("index") }}' } else { diff --git a/backend/pyproject.toml b/backend/pyproject.toml index 4ed11cf..cd7df75 100644 --- a/backend/pyproject.toml +++ b/backend/pyproject.toml @@ -28,6 +28,7 @@ "cachetools>=5.5.2", "email-validator>=2.2.0", "fastapi-filter>=2.0.1", + "fastapi-mail==1.5.2", "fastapi-pagination>=0.13.2", # NOTE: This is a heavy dependency (~40MB) due to its use of boto3, even though we don't use any cloud storage # We should consider using a more lightweight alternative if it becomes available. @@ -38,6 +39,7 @@ "fastapi-users[oauth,sqlalchemy]>=14.0.1", "fastapi[standard] >=0.115.14", "markdown>=3.8.2", + "mjml>=0.11.1", "pillow >=11.2.1", "psycopg[binary] >=3.2.9", # TODO: Upgrade to python 3.14 and pydantic 2.12 when SQLModel fixes compatibility issues (see https://github.com/fastapi/sqlmodel/issues/1606) diff --git a/backend/scripts/compile_email_templates.py b/backend/scripts/compile_email_templates.py new file mode 100755 index 0000000..713e720 --- /dev/null +++ b/backend/scripts/compile_email_templates.py @@ -0,0 +1,67 @@ +#!/usr/bin/env python3 +"""Compile MJML email templates to HTML. + +This script reads MJML templates from app/templates/emails/src/, +expands any {{include:component}} directives from src/components/, +compiles them to HTML, and saves the output to app/templates/emails/build/. +""" + +import logging +from pathlib import Path + +from mjml.mjml2html import mjml_to_html + +logging.basicConfig(level=logging.INFO) +logger = logging.getLogger(__name__) + +# Paths +SCRIPT_DIR = Path(__file__).parent +BACKEND_DIR = SCRIPT_DIR.parent +SRC_DIR = BACKEND_DIR / "app" / "templates" / "emails" / "src" +BUILD_DIR = BACKEND_DIR / "app" / "templates" / "emails" / "build" + + +def compile_mjml_templates() -> None: + """Compile all MJML templates in src/ to HTML in build/.""" + if not SRC_DIR.exists(): + logger.error("Source directory not found: %s", SRC_DIR) + return + + # Create build directory if it doesn't exist + BUILD_DIR.mkdir(parents=True, exist_ok=True) + + # Find all MJML files + mjml_files = list(SRC_DIR.glob("*.mjml")) + + if not mjml_files: + logger.warning("No MJML files found in %s", SRC_DIR) + return + + logger.info("Found %d MJML template(s) to compile", len(mjml_files)) + + # Compile each template + for mjml_file in mjml_files: + try: + logger.info("Compiling %s...", mjml_file.name) + + # Read MJML content + mjml_content = mjml_file.read_text() + + # Compile to HTML + html_dotmap = mjml_to_html(mjml_content) + html_content = html_dotmap.html + + # Write HTML to build directory + html_file = BUILD_DIR / mjml_file.with_suffix(".html").name + html_file.write_text(html_content) + + logger.info(" ✓ Compiled to %s", html_file.name) + + except Exception: + logger.exception(" ✗ Failed to compile %s", mjml_file.name) + + logger.info("Compilation complete!") + + +if __name__ == "__main__": + compile_mjml_templates() diff --git a/backend/tests/conftest.py b/backend/tests/conftest.py index 0a4732a..5deafde 100644 --- a/backend/tests/conftest.py +++ b/backend/tests/conftest.py @@ -6,12 +6,10 @@ import logging from collections.abc import AsyncGenerator, Generator from pathlib import Path +from unittest.mock import AsyncMock import pytest -from alembic import command from alembic.config import Config -from app.core.config import settings -from app.main import app from fastapi.testclient import TestClient from sqlalchemy import Engine, create_engine, text from sqlalchemy.exc import ProgrammingError @@ -19,6 +17,12 @@ from sqlalchemy.ext.asyncio.engine import AsyncEngine from sqlmodel.ext.asyncio.session import AsyncSession +from alembic import command +from app.core.config import settings +from app.main import app + +from .factories.emails import EmailContextFactory, EmailDataFactory + # Set up logger logger: logging.Logger = logging.getLogger(__name__) @@ -55,7 +59,7 @@ def get_alembic_config() -> Config: return alembic_cfg -@pytest.fixture(scope="session", autouse=True) +@pytest.fixture(scope="session") def setup_test_database() -> Generator: """Create test database, run migrations, and cleanup after tests.""" create_test_database() # Create empty database @@ -72,7 +76,7 @@ def setup_test_database() -> Generator: ### Async test session generators -@pytest.fixture(scope="function") +@pytest.fixture async def get_async_session() -> AsyncGenerator[AsyncSession]: """Create a new database session for each test and roll it back after the test.""" async with async_engine.begin() as connection, async_session_local(bind=connection) as session: @@ -81,7 +85,7 @@ async def get_async_session() -> AsyncGenerator[AsyncSession]: await transaction.rollback() -@pytest.fixture(scope="function") +@pytest.fixture async def client(db: AsyncSession) -> AsyncGenerator[TestClient]: """Provide a TestClient that uses the test database session.""" @@ -94,3 +98,48 @@ async def override_get_db() -> AsyncGenerator[AsyncSession]: yield c app.dependency_overrides.clear() + + +### Email fixtures +@pytest.fixture +def email_context() -> dict: + """Return a realistic email template context dict using FactoryBoy/Faker.""" + return EmailContextFactory() + + +@pytest.fixture +def email_data() -> dict: + """Return realistic test data for email functions using FactoryBoy/Faker.""" + return EmailDataFactory() + + +@pytest.fixture +def mock_smtp() -> AsyncMock: + """Return a configured mock SMTP client for testing email sending.""" + mock = AsyncMock() + mock.connect = AsyncMock() + mock.login = AsyncMock() + mock.send_message = AsyncMock() + mock.quit = AsyncMock() + return mock + + +@pytest.fixture +def mock_email_sender(monkeypatch: pytest.MonkeyPatch) -> AsyncMock: + """Mock the fastapi-mail send_message function for all email tests. + + This fixture automatically patches fm.send_message so tests don't need + to manually patch it with context managers. + + Returns: + AsyncMock: The mocked send_message function + + Usage: + @pytest.mark.asyncio + async def test_send_email(mock_email_sender): + await send_registration_email("test@example.com", "user", "token") + mock_email_sender.assert_called_once() + """ + mock_send = AsyncMock() + monkeypatch.setattr("app.api.auth.utils.programmatic_emails.fm.send_message", mock_send) + return mock_send diff --git a/backend/tests/constants/__init__.py b/backend/tests/constants/__init__.py deleted file mode 100644 index 2564ef9..0000000 --- a/backend/tests/constants/__init__.py +++ /dev/null @@ -1 +0,0 @@ -"""Constants used in testing.""" diff --git a/backend/tests/constants/background_data.py b/backend/tests/constants/background_data.py deleted file mode 100644 index 196044a..0000000 --- a/backend/tests/constants/background_data.py +++ /dev/null @@ -1 +0,0 @@ -"""Constants for background data tests.""" diff --git a/backend/tests/factories/background_data.py b/backend/tests/factories/background_data.py deleted file mode 100644 index 4ef9990..0000000 --- a/backend/tests/factories/background_data.py +++ /dev/null @@ -1,6 +0,0 @@ -import factory -from app.api.background_data.models import Taxonomy - - -class TaxonomyFactory(factory.alchemy.SQLAlchemyModelFactory): - pass diff --git a/backend/tests/factories/emails.py b/backend/tests/factories/emails.py new file mode 100644 index 0000000..1974be0 --- /dev/null +++ b/backend/tests/factories/emails.py @@ -0,0 +1,26 @@ +"""Factories for email template context dicts for tests.""" + +from factory.base import DictFactory +from factory.faker import Faker + + +class EmailContextFactory(DictFactory): + """Produce realistic email template context dicts for tests.""" + + username = Faker("user_name") + verification_link = Faker("url") + reset_link = Faker("url") + confirmation_link = Faker("url") + unsubscribe_link = Faker("url") + subject = Faker("sentence", nb_words=5) + newsletter_content = Faker("text", max_nb_chars=200) + + +class EmailDataFactory(DictFactory): + """Produce test data for email sending functions.""" + + email = Faker("email") + username = Faker("user_name") + token = Faker("uuid4") + subject = Faker("sentence", nb_words=5) + body = Faker("text", max_nb_chars=200) diff --git a/backend/tests/tests/emails/__init__.py b/backend/tests/tests/emails/__init__.py new file mode 100644 index 0000000..d04ba40 --- /dev/null +++ b/backend/tests/tests/emails/__init__.py @@ -0,0 +1 @@ +"""Tests related to email functionality.""" diff --git a/backend/tests/tests/emails/test_programmatic_emails.py b/backend/tests/tests/emails/test_programmatic_emails.py new file mode 100644 index 0000000..390a857 --- /dev/null +++ b/backend/tests/tests/emails/test_programmatic_emails.py @@ -0,0 +1,227 @@ +"""Tests for programmatic email sending functionality.""" + +from typing import Any +from unittest.mock import AsyncMock, MagicMock +from urllib.parse import parse_qs, urlparse + +import pytest +from faker import Faker +from fastapi import BackgroundTasks + +from app.api.auth.utils.programmatic_emails import ( + generate_token_link, + send_post_verification_email, + send_registration_email, + send_reset_password_email, + send_verification_email, +) +from app.core.config import settings as core_settings + +fake = Faker() + + +### Token Link Generation Tests ### +def test_generate_token_link_default_base_url() -> None: + """Test token link generation with default base URL from core settings.""" + token = fake.uuid4() + route = "/verify" + + link = generate_token_link(token, route) + + parsed = urlparse(link) + query_params = parse_qs(parsed.query) + + assert link.startswith(str(core_settings.frontend_app_url)) + assert parsed.path == route + assert query_params["token"] == [token] + + +def test_generate_token_link_custom_base_url() -> None: + """Test token link generation with custom base URL.""" + token = fake.uuid4() + route = "/reset-password" + custom_base_url = fake.url() + + link = generate_token_link(token, route, base_url=custom_base_url) + + parsed = urlparse(link) + query_params = parse_qs(parsed.query) + + assert link.startswith(custom_base_url) + assert parsed.path == route + assert query_params["token"] == [token] + + +def test_generate_token_link_with_trailing_slash() -> None: + """Test that token links are generated correctly regardless of trailing slashes.""" + token = fake.uuid4() + route = "/verify" + base_url_with_slash = f"{fake.url()}//" + + link = generate_token_link(token, route, base_url=base_url_with_slash) + + # Should not have double slashes + assert "//" not in link.replace("https://", "") # noqa: PLR2004 # Magic value for double slash + # Should still have the correct route + assert urlparse(link).path == route + + +### Registration Email Tests ### +@pytest.mark.asyncio +async def test_send_registration_email(email_data: dict, mock_email_sender: AsyncMock) -> None: + """Test registration email is sent.""" + await send_registration_email(email_data["email"], email_data["username"], email_data["token"]) + mock_email_sender.assert_called_once() + + +@pytest.mark.asyncio +async def test_send_registration_email_no_username(email_data: dict, mock_email_sender: AsyncMock) -> None: + """Test registration email works without username.""" + await send_registration_email(email_data["email"], None, email_data["token"]) + mock_email_sender.assert_called_once() + + +@pytest.mark.asyncio +async def test_send_registration_email_with_background_tasks(email_data: dict, mock_email_sender: AsyncMock) -> None: + """Test registration email queues task instead of sending immediately.""" + background_tasks = MagicMock(spec=BackgroundTasks) + + await send_registration_email( + email_data["email"], email_data["username"], email_data["token"], background_tasks=background_tasks + ) + + # When background_tasks is provided, it should queue, not send + background_tasks.add_task.assert_called_once() + mock_email_sender.assert_not_called() + + +### Password Reset Email Tests ### +@pytest.mark.asyncio +async def test_send_reset_password_email(email_data: dict, mock_email_sender: AsyncMock) -> None: + """Test password reset email is sent.""" + await send_reset_password_email(email_data["email"], email_data["username"], email_data["token"]) + mock_email_sender.assert_called_once() + + +@pytest.mark.asyncio +async def test_send_reset_password_email_with_background_tasks(email_data: dict, mock_email_sender: AsyncMock) -> None: + """Test password reset email queues task when background_tasks provided.""" + background_tasks = MagicMock(spec=BackgroundTasks) + + await send_reset_password_email( + email_data["email"], email_data["username"], email_data["token"], background_tasks=background_tasks + ) + + background_tasks.add_task.assert_called_once() + mock_email_sender.assert_not_called() + + +### Verification Email Tests ### +@pytest.mark.asyncio +async def test_send_verification_email(email_data: dict, mock_email_sender: AsyncMock) -> None: + """Test verification email is sent.""" + await send_verification_email(email_data["email"], email_data["username"], email_data["token"]) + mock_email_sender.assert_called_once() + + +@pytest.mark.asyncio +async def test_send_verification_email_with_background_tasks(email_data: dict, mock_email_sender: AsyncMock) -> None: + """Test verification email queues task when background_tasks provided.""" + background_tasks = MagicMock(spec=BackgroundTasks) + + await send_verification_email( + email_data["email"], email_data["username"], email_data["token"], background_tasks=background_tasks + ) + + background_tasks.add_task.assert_called_once() + mock_email_sender.assert_not_called() + + +### Post-Verification Email Tests ### +@pytest.mark.asyncio +async def test_send_post_verification_email(email_data: dict, mock_email_sender: AsyncMock) -> None: + """Test post-verification email is sent.""" + await send_post_verification_email(email_data["email"], email_data["username"]) + mock_email_sender.assert_called_once() + + +@pytest.mark.asyncio +async def test_send_post_verification_email_no_username(email_data: dict, mock_email_sender: AsyncMock) -> None: + """Test post-verification email works without username.""" + await send_post_verification_email(email_data["email"], None) + mock_email_sender.assert_called_once() + + +@pytest.mark.asyncio +async def test_send_post_verification_email_with_background_tasks( + email_data: dict, mock_email_sender: AsyncMock +) -> None: + """Test post-verification email queues task when background_tasks provided.""" + background_tasks = MagicMock(spec=BackgroundTasks) + + await send_post_verification_email(email_data["email"], email_data["username"], background_tasks=background_tasks) + + background_tasks.add_task.assert_called_once() + mock_email_sender.assert_not_called() + + +### Parametrized Integration Tests ### +@pytest.mark.asyncio +@pytest.mark.parametrize( + ("email_func", "needs_token"), + [ + (send_registration_email, True), + (send_reset_password_email, True), + (send_verification_email, True), + (send_post_verification_email, False), + ], +) +async def test_all_email_functions_send_emails( + email_data: dict, + mock_email_sender: AsyncMock, + email_func: Any, + *, + needs_token: bool, +) -> None: + """Test that all email functions successfully send emails.""" + # Call function with appropriate arguments + if needs_token: + await email_func(email_data["email"], email_data["username"], email_data["token"]) + else: + await email_func(email_data["email"], email_data["username"]) + + # Verify email was sent + mock_email_sender.assert_called_once() + + +@pytest.mark.asyncio +@pytest.mark.parametrize( + ("email_func", "needs_token"), + [ + (send_registration_email, True), + (send_reset_password_email, True), + (send_verification_email, True), + (send_post_verification_email, False), + ], +) +async def test_all_email_functions_support_background_tasks( + email_data: dict, + mock_email_sender: AsyncMock, + email_func: Any, + *, + needs_token: bool, +) -> None: + """Test that all email functions support background tasks.""" + background_tasks = MagicMock(spec=BackgroundTasks) + + # Call function with background tasks + if needs_token: + await email_func( + email_data["email"], email_data["username"], email_data["token"], background_tasks=background_tasks + ) + else: + await email_func(email_data["email"], email_data["username"], background_tasks=background_tasks) + + # Verify task was queued, not sent immediately + background_tasks.add_task.assert_called_once() + mock_email_sender.assert_not_called() From ebfa5ae824f9a4ebd29f74cbb94ccf00f142d815 Mon Sep 17 00:00:00 2001 From: Simon van Lierde Date: Thu, 6 Nov 2025 16:07:29 +0100 Subject: [PATCH 21/71] feature(backend): Move to fastapi-mail and redis for disposable mail cache. We can use the Redis cache for faster session management as well. --- .pre-commit-config.yaml | 100 +++++----- backend/.env.example | 6 + backend/app/api/admin/auth.py | 2 +- backend/app/api/auth/config.py | 12 +- backend/app/api/auth/crud/users.py | 8 +- backend/app/api/auth/routers/auth.py | 15 +- backend/app/api/auth/routers/oauth.py | 4 +- backend/app/api/auth/services/user_manager.py | 12 +- .../app/api/auth/utils/email_validation.py | 175 +++++++++++++----- backend/app/api/newsletter/utils/tokens.py | 6 +- backend/app/core/config.py | 6 + backend/app/core/redis.py | 129 +++++++++++++ backend/app/main.py | 59 +++++- backend/pyproject.toml | 4 +- backend/uv.lock | 106 ++++++++++- compose.override.yml | 4 + compose.prod.yml | 4 + compose.yml | 14 +- 18 files changed, 530 insertions(+), 136 deletions(-) create mode 100644 backend/app/core/redis.py diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index ea48998..42a0b64 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -5,85 +5,85 @@ repos: ### Global hooks - - repo: https://gitlab.com/vojko.pribudic.foss/pre-commit-update - rev: v0.8.0 +- repo: https://gitlab.com/vojko.pribudic.foss/pre-commit-update + rev: v0.9.0 hooks: - - id: pre-commit-update # Autoupdate pre-commit hooks + - id: pre-commit-update # Autoupdate pre-commit hooks # TODO: Re-add mdformat to pre-commit-update when mdformat plugins are compatible with mdformat 1.0.0 args: [--exclude, mdformat] - - repo: https://github.com/gitleaks/gitleaks - rev: v8.28.0 +- repo: https://github.com/gitleaks/gitleaks + rev: v8.29.0 hooks: - - id: gitleaks + - id: gitleaks - - repo: https://github.com/executablebooks/mdformat +- repo: https://github.com/executablebooks/mdformat rev: 0.7.22 hooks: - - id: mdformat # Format Markdown files. + - id: mdformat # Format Markdown files. additional_dependencies: - - mdformat-gfm # Support GitHub Flavored Markdown. - - mdformat-footnote - - mdformat-frontmatter - - mdformat-ruff # Support Python code blocks linted with Ruff. + - mdformat-gfm # Support GitHub Flavored Markdown. + - mdformat-footnote + - mdformat-frontmatter + - mdformat-ruff # Support Python code blocks linted with Ruff. - - repo: https://github.com/pre-commit/pre-commit-hooks +- repo: https://github.com/pre-commit/pre-commit-hooks rev: v6.0.0 hooks: - - id: check-added-large-files - - id: check-case-conflict # Check for files with names that differ only in case. - - id: check-executables-have-shebangs - - id: check-shebang-scripts-are-executable - - id: check-toml - - id: check-yaml + - id: check-added-large-files + - id: check-case-conflict # Check for files with names that differ only in case. + - id: check-executables-have-shebangs + - id: check-shebang-scripts-are-executable + - id: check-toml + - id: check-yaml exclude: ^docs/mkdocs.yml$ # Exclude mkdocs.yml because it uses an obscure tag to allow for mermaid formatting - - id: detect-private-key - - id: end-of-file-fixer # Ensure files end with a newline. - - id: mixed-line-ending - - id: no-commit-to-branch # Prevent commits to main and master branches. - - id: trailing-whitespace + - id: detect-private-key + - id: end-of-file-fixer # Ensure files end with a newline. + - id: mixed-line-ending + - id: no-commit-to-branch # Prevent commits to main and master branches. + - id: trailing-whitespace args: ["--markdown-linebreak-ext", "md"] # Preserve Markdown hard line breaks. - - repo: https://github.com/commitizen-tools/commitizen +- repo: https://github.com/commitizen-tools/commitizen rev: v4.9.1 hooks: - - id: commitizen + - id: commitizen stages: [commit-msg] - - repo: https://github.com/simonvanlierde/check-json5 +- repo: https://github.com/simonvanlierde/check-json5 rev: v1.1.0 hooks: - - id: check-json5 + - id: check-json5 files: ^ (?!(backend/frontend-app|frontend-web)/data/) - ### Backend hooks - - repo: https://github.com/RobertCraigie/pyright-python # Lint backend code with Pyright. + ### Backend hooks +- repo: https://github.com/RobertCraigie/pyright-python # Lint backend code with Pyright. rev: v1.1.407 hooks: - - id: pyright + - id: pyright files: ^backend/(app|scripts|tests)/ entry: pyright --project backend - - repo: https://github.com/astral-sh/ruff-pre-commit - rev: v0.14.2 +- repo: https://github.com/astral-sh/ruff-pre-commit + rev: v0.14.3 hooks: - - id: ruff-check # Lint code + - id: ruff-check # Lint code files: ^backend/(app|scripts|tests)/ args: ["--fix", "--config", "backend/pyproject.toml", "--ignore", "FIX002"] # Allow TODO comments in commits. - - id: ruff-format # Format code + - id: ruff-format # Format code files: ^backend/(app|scripts|tests)/ args: ["--config", "backend/pyproject.toml"] - - repo: https://github.com/astral-sh/uv-pre-commit - rev: 0.9.5 +- repo: https://github.com/astral-sh/uv-pre-commit + rev: 0.9.7 hooks: - - id: uv-lock # Update the uv lockfile for the backend. + - id: uv-lock # Update the uv lockfile for the backend. files: ^backend/(uv\.lock|pyproject\.toml|uv\.toml)$ entry: uv lock --project backend - - repo: local +- repo: local hooks: # Check if Alembic migrations are up-to-date. Uses uv to ensure the right environment when executed through VS Code Git extension. - - id: backend-alembic-autogen-check + - id: backend-alembic-autogen-check name: check alembic migrations entry: bash -c 'cd backend && uv run alembic-autogen-check' language: system @@ -91,22 +91,22 @@ repos: pass_filenames: false stages: [pre-commit] - ### Frontend hooks - - repo: local + ### Frontend hooks +- repo: local hooks: - - id: frontend-web-format + - id: frontend-web-format name: format frontend-web code entry: bash -c 'cd frontend-web && npm run format' - language: - system + language: system # Match frontend JavaScript and TypeScript files for formatting. - files: ^frontend-web\/.*\.(jsx?|tsx?|c(js|ts)|m(js|ts)|d\\.(ts|cts|mts)|jsonc?)$ + files: + ^frontend-web\/.*\.(jsx?|tsx?|c(js|ts)|m(js|ts)|d\\.(ts|cts|mts)|jsonc?)$ pass_filenames: false - - id: frontend-app-format + - id: frontend-app-format name: format frontend-app code entry: bash -c 'cd frontend-app && npm run format' - language: - system + language: system # Match frontend JavaScript and TypeScript files for formatting. - files: ^frontend-app\/.*\.(jsx?|tsx?|c(js|ts)|m(js|ts)|d\\.(ts|cts|mts)|jsonc?)$ + files: + ^frontend-app\/.*\.(jsx?|tsx?|c(js|ts)|m(js|ts)|d\\.(ts|cts|mts)|jsonc?)$ pass_filenames: false diff --git a/backend/.env.example b/backend/.env.example index ab1001c..fac58ca 100644 --- a/backend/.env.example +++ b/backend/.env.example @@ -28,6 +28,12 @@ EMAIL_PASSWORD='your-email-password' # 🔀 Password for EMAIL_FROM='Your Name ' # 🔀 Email address from which the emails are sent. Can be different from the SMTP server username. EMAIL_REPLY_TO='your.replyto.alias.@example.com' # 🔀 Email address to which replies are sent. Can be different from the SMTP server username. +# Redis settings for caching (disposable email domains, sessions, etc.) +REDIS_HOST='localhost' # 🔀 Redis server host (use 'cache' in Docker) +REDIS_PORT='6379' # 🔀 Redis server port +REDIS_DB='0' # 🔀 Redis database number (0-15) +REDIS_PASSWORD='password' # 🔀 Redis password (leave empty if no password) + # Superuser details SUPERUSER_EMAIL='your-email@example.com' # 🔀 SUPERUSER_PASSWORD='example_password' # 🔀 diff --git a/backend/app/api/admin/auth.py b/backend/app/api/admin/auth.py index 9371707..f3916af 100644 --- a/backend/app/api/admin/auth.py +++ b/backend/app/api/admin/auth.py @@ -64,7 +64,7 @@ async def authenticate(self, request: Request) -> RedirectResponse | Response | def get_authentication_backend() -> AdminAuth: """Get the authentication backend for the SQLAdmin interface.""" - return AdminAuth(secret_key=auth_settings.fastapi_users_secret) + return AdminAuth(secret_key=auth_settings.fastapi_users_secret.get_secret_value()) async def logout_override(request: Request) -> RedirectResponse: # noqa: ARG001 # Signature expected by the SQLAdmin implementation diff --git a/backend/app/api/auth/config.py b/backend/app/api/auth/config.py index d3ccfb1..5a519b4 100644 --- a/backend/app/api/auth/config.py +++ b/backend/app/api/auth/config.py @@ -13,14 +13,14 @@ class AuthSettings(BaseSettings): """Settings class to store settings related to auth components.""" # Authentication settings - fastapi_users_secret: str = "" - newsletter_secret: str = "" + fastapi_users_secret: SecretStr = SecretStr("") + newsletter_secret: SecretStr = SecretStr("") # OAuth settings - google_oauth_client_id: str = "" - google_oauth_client_secret: str = "" - github_oauth_client_id: str = "" - github_oauth_client_secret: str = "" + google_oauth_client_id: SecretStr = SecretStr("") + google_oauth_client_secret: SecretStr = SecretStr("") + github_oauth_client_id: SecretStr = SecretStr("") + github_oauth_client_secret: SecretStr = SecretStr("") # Settings used to configure the email server for sending emails from the app. email_host: str = "" diff --git a/backend/app/api/auth/crud/users.py b/backend/app/api/auth/crud/users.py index d2906e5..2942899 100644 --- a/backend/app/api/auth/crud/users.py +++ b/backend/app/api/auth/crud/users.py @@ -14,13 +14,15 @@ UserCreateWithOrganization, UserUpdate, ) -from app.api.auth.utils.email_validation import is_disposable_email +from app.api.auth.utils.email_validation import EmailChecker from app.api.common.crud.utils import db_get_model_with_id_if_it_exists ## Create User ## async def create_user_override( - user_db: BaseUserDatabase[User, UUID4], user_create: UserCreate | UserCreateWithOrganization + user_db: BaseUserDatabase[User, UUID4], + user_create: UserCreate | UserCreateWithOrganization, + email_checker: EmailChecker | None = None, ) -> UserCreate: """Override of base user creation with additional username uniqueness check. @@ -28,7 +30,7 @@ async def create_user_override( """ # TODO: Fix type errors in this method and implement custom UserNameAlreadyExists error in FastAPI-Users - if await is_disposable_email(user_create.email): + if email_checker and await email_checker.is_disposable(user_create.email): raise DisposableEmailError(email=user_create.email) if user_create.username is not None: diff --git a/backend/app/api/auth/routers/auth.py b/backend/app/api/auth/routers/auth.py index 22a105a..d63266a 100644 --- a/backend/app/api/auth/routers/auth.py +++ b/backend/app/api/auth/routers/auth.py @@ -1,11 +1,13 @@ """Authentication, registration, and login routes.""" -from fastapi import APIRouter +from typing import Annotated + +from fastapi import APIRouter, Depends from pydantic import EmailStr from app.api.auth.schemas import UserCreate, UserCreateWithOrganization, UserRead from app.api.auth.services.user_manager import bearer_auth_backend, cookie_auth_backend, fastapi_user_manager -from app.api.auth.utils.email_validation import is_disposable_email +from app.api.auth.utils.email_validation import EmailChecker, get_email_checker_dependency from app.api.common.routers.openapi import mark_router_routes_public router = APIRouter(prefix="/auth", tags=["auth"]) @@ -38,8 +40,13 @@ @router.get("/validate-email") -async def validate_email(email: EmailStr) -> dict: +async def validate_email( + email: EmailStr, + email_checker: Annotated[EmailChecker | None, Depends(get_email_checker_dependency)], +) -> dict: """Validate email address for registration.""" - is_disposable = await is_disposable_email(email) + is_disposable = False + if email_checker: + is_disposable = await email_checker.is_disposable(email) return {"isValid": not is_disposable, "reason": "Please use a permanent email address" if is_disposable else None} diff --git a/backend/app/api/auth/routers/oauth.py b/backend/app/api/auth/routers/oauth.py index eba947c..51e5478 100644 --- a/backend/app/api/auth/routers/oauth.py +++ b/backend/app/api/auth/routers/oauth.py @@ -32,7 +32,7 @@ fastapi_user_manager.get_oauth_router( oauth_client, auth_backend, - settings.fastapi_users_secret, + settings.fastapi_users_secret.get_secret_value(), associate_by_email=True, is_verified_by_default=True, ), @@ -44,7 +44,7 @@ fastapi_user_manager.get_oauth_associate_router( oauth_client, UserRead, - settings.fastapi_users_secret, + settings.fastapi_users_secret.get_secret_value(), ), prefix=f"/{provider_name}/associate", ) diff --git a/backend/app/api/auth/services/user_manager.py b/backend/app/api/auth/services/user_manager.py index 0eedec0..c8a312c 100644 --- a/backend/app/api/auth/services/user_manager.py +++ b/backend/app/api/auth/services/user_manager.py @@ -35,7 +35,7 @@ logger = logging.getLogger(__name__) # Declare constants -SECRET: str = auth_settings.fastapi_users_secret +SECRET: SecretStr = auth_settings.fastapi_users_secret ACCESS_TOKEN_TTL = auth_settings.access_token_ttl_seconds RESET_TOKEN_TTL = auth_settings.reset_password_token_ttl_seconds VERIFICATION_TOKEN_TTL = auth_settings.verification_token_ttl_seconds @@ -45,10 +45,10 @@ class UserManager(UUIDIDMixin, BaseUserManager[User, UUID4]): """User manager class for FastAPI-Users.""" # Set up token secrets and lifetimes - reset_password_token_secret: SecretType = SECRET + reset_password_token_secret: SecretType = SECRET.get_secret_value() reset_password_token_lifetime_seconds = RESET_TOKEN_TTL - verification_token_secret: SecretType = SECRET + verification_token_secret: SecretType = SECRET.get_secret_value() verification_token_lifetime_seconds = VERIFICATION_TOKEN_TTL async def create( @@ -59,7 +59,9 @@ async def create( ) -> User: """Override of base user creation with additional username uniqueness check and organization creation.""" try: - user_create = await create_user_override(self.user_db, user_create) + # Get email checker from app state if request is available + email_checker = request.app.state.email_checker if request else None + user_create = await create_user_override(self.user_db, user_create, email_checker) # HACK: This is a temporary solution to allow error propagation for username and organization creation errors. # The built-in UserManager register route can only catch UserAlreadyExists and InvalidPasswordException errors. # TODO: Implement custom exceptions in custom register router, this will also simplify user creation crud. @@ -172,7 +174,7 @@ async def get_user_manager(user_db: SQLModelUserDatabaseAsync = Depends(get_user def get_jwt_strategy() -> JWTStrategy: """Get a JWT strategy to be used in authentication backends.""" - return JWTStrategy(secret=SECRET, lifetime_seconds=ACCESS_TOKEN_TTL) + return JWTStrategy(secret=SECRET.get_secret_value(), lifetime_seconds=ACCESS_TOKEN_TTL) # Authentication backends diff --git a/backend/app/api/auth/utils/email_validation.py b/backend/app/api/auth/utils/email_validation.py index 36dfefa..ac2c6de 100644 --- a/backend/app/api/auth/utils/email_validation.py +++ b/backend/app/api/auth/utils/email_validation.py @@ -1,55 +1,130 @@ """Utilities for validating email addresses.""" -from datetime import UTC, datetime, timedelta -from pathlib import Path +import asyncio +import contextlib +import logging -import anyio -import httpx +from fastapi import Request +from fastapi_mail.email_utils import DefaultChecker +from redis.asyncio import Redis +from redis.exceptions import RedisError +logger = logging.getLogger(__name__) + +# Custom source for disposable domains DISPOSABLE_DOMAINS_URL = "https://raw.githubusercontent.com/disposable/disposable-email-domains/master/domains.txt" -BASE_DIR: Path = (Path(__file__).parents[4]).resolve() - -CACHE_FILE = BASE_DIR / "data" / "cache" / "disposable_domains_cache.txt" -CACHE_DURATION = timedelta(days=1) - - -async def get_disposable_domains() -> set[str]: - """Get disposable email domains, using cache if fresh.""" - # Check if cache exists and is fresh - if CACHE_FILE.exists(): - cache_age = datetime.now(tz=UTC) - datetime.fromtimestamp(CACHE_FILE.stat().st_mtime, tz=UTC) - if cache_age < CACHE_DURATION: - async with await anyio.open_file(CACHE_FILE, "r") as f: - content = await f.read() - return {line.strip().lower() for line in content.splitlines() if line.strip()} - - # Fetch fresh list - try: - async with httpx.AsyncClient() as client: - response = await client.get(DISPOSABLE_DOMAINS_URL, timeout=10.0) - response.raise_for_status() - domains = {line.strip().lower() for line in response.text.splitlines() if line.strip()} - - # Ensure cache directory exists - CACHE_FILE.parent.mkdir(parents=True, exist_ok=True) - - # Update cache - async with await anyio.open_file(CACHE_FILE, "w") as f: - await f.write("\n".join(sorted(domains))) - - return domains - except (httpx.RequestError, httpx.HTTPStatusError, OSError): - # If fetch fails and cache exists, use stale cache - if CACHE_FILE.exists(): - async with await anyio.open_file(CACHE_FILE, "r") as f: - content = await f.read() - return {line.strip().lower() for line in content.splitlines() if line.strip()} - # If no cache available, return empty set (allow registration) - return set() - - -async def is_disposable_email(email: str) -> bool: - """Check if email domain is disposable.""" - domain = email.split("@")[-1].lower() - disposable_domains = await get_disposable_domains() - return domain in disposable_domains + + +class EmailChecker: + """Email checker that manages disposable domain validation.""" + + def __init__(self, redis_client: Redis) -> None: + """Initialize email checker with Redis client. + + Args: + redis_client: Redis client instance to use for caching + """ + self.redis_client = redis_client + self.checker: DefaultChecker | None = None + self._refresh_task: asyncio.Task | None = None + + async def initialize(self) -> None: + """Initialize the disposable email checker. + + Should be called during application startup. + """ + try: + self.checker = DefaultChecker(db_provider="redis", source=DISPOSABLE_DOMAINS_URL) + await self.checker.init_redis() + logger.info("Disposable email checker initialized successfully") + + # Fetch initial domains + await self._refresh_domains() + + # Start periodic refresh task + self._refresh_task = asyncio.create_task(self._periodic_refresh()) + + except (RuntimeError, ValueError, ConnectionError, OSError, RedisError) as e: + logger.warning("Failed to initialize disposable email checker: %s", e) + self.checker = None + + async def _refresh_domains(self) -> None: + """Refresh the list of disposable email domains from the source.""" + if self.checker is None: + logger.warning("Email checker not initialized, cannot refresh domains") + return + try: + await self.checker.fetch_temp_email_domains() + logger.info("Disposable email domains refreshed successfully") + except (RuntimeError, ValueError, ConnectionError, OSError, RedisError): + logger.exception("Failed to refresh disposable email domains:") + + async def _periodic_refresh(self) -> None: + """Periodically refresh disposable domains every 24 hours.""" + while True: + try: + await asyncio.sleep(60 * 60 * 24) # 24 hours + await self._refresh_domains() + except asyncio.CancelledError: + logger.info("Periodic domain refresh task cancelled") + break + except (RuntimeError, ValueError, ConnectionError, OSError, RedisError): + logger.exception("Error in periodic domain refresh:") + + async def close(self) -> None: + """Close the email checker and cleanup resources. + + Should be called during application shutdown. + """ + # Cancel periodic refresh task + if self._refresh_task is not None: + self._refresh_task.cancel() + with contextlib.suppress(asyncio.CancelledError): + await self._refresh_task + + # Close checker connections if initialized + if self.checker is not None: + try: + await self.checker.close_connections() + logger.info("Email checker closed successfully") + except (RuntimeError, ValueError, ConnectionError, OSError, RedisError) as e: + logger.warning("Error closing email checker: %s", e) + finally: + self.checker = None + + async def is_disposable(self, email: str) -> bool: + """Check if email domain is disposable. + + Args: + email: Email address to check + + Returns: + bool: True if email is from a disposable domain, False otherwise + """ + if self.checker is None: + logger.warning("Email checker not initialized, allowing registration") + return False + try: + return await self.checker.is_disposable(email) + except (RuntimeError, ValueError, ConnectionError, OSError, RedisError): + logger.exception("Failed to check if email is disposable: %s. Allowing registration.", email) + # If check fails, allow registration (fail open) + return False + + +def get_email_checker_dependency(request: Request) -> EmailChecker | None: + """FastAPI dependency to get EmailChecker from app state. + + Args: + request: FastAPI request object + + Returns: + EmailChecker instance or None if not initialized + + Usage: + @app.get("/example") + async def example(email_checker: EmailChecker | None = Depends(get_email_checker_dependency)): + if email_checker: + await email_checker.is_disposable("test@example.com") + """ + return request.app.state.email_checker diff --git a/backend/app/api/newsletter/utils/tokens.py b/backend/app/api/newsletter/utils/tokens.py index 04ba19c..f94bdf5 100644 --- a/backend/app/api/newsletter/utils/tokens.py +++ b/backend/app/api/newsletter/utils/tokens.py @@ -4,10 +4,12 @@ from enum import Enum import jwt +from pydantic import SecretStr from app.api.auth.config import settings ALGORITHM = "HS256" # Algorithm used for JWT encoding/decoding +SECRET: SecretStr = settings.newsletter_secret class JWTType(str, Enum): @@ -33,13 +35,13 @@ def create_jwt_token(email: str, token_type: JWTType) -> str: """Create a JWT token for newsletter confirmation.""" expiration = datetime.now(UTC) + timedelta(seconds=token_type.expiration_seconds) payload = {"sub": email, "exp": expiration, "type": token_type.value} - return jwt.encode(payload, settings.newsletter_secret, algorithm=ALGORITHM) + return jwt.encode(payload, SECRET.get_secret_value(), algorithm=ALGORITHM) def verify_jwt_token(token: str, expected_token_type: JWTType) -> str | None: """Verify the JWT token and return the email if valid.""" try: - payload = jwt.decode(token, settings.newsletter_secret, algorithms=[ALGORITHM]) + payload = jwt.decode(token, SECRET.get_secret_value(), algorithms=[ALGORITHM]) if payload["type"] != expected_token_type.value: return None return payload["sub"] # Returns the email address from the token diff --git a/backend/app/core/config.py b/backend/app/core/config.py index 7bf2740..9aa8888 100644 --- a/backend/app/core/config.py +++ b/backend/app/core/config.py @@ -21,6 +21,12 @@ class CoreSettings(BaseSettings): postgres_db: str = "relab_db" postgres_test_db: str = "relab_test_db" + # Redis settings for caching + redis_host: str = "localhost" + redis_port: int = 6379 + redis_db: int = 0 + redis_password: str = "" + # Debug settings debug: bool = False diff --git a/backend/app/core/redis.py b/backend/app/core/redis.py new file mode 100644 index 0000000..282bf72 --- /dev/null +++ b/backend/app/core/redis.py @@ -0,0 +1,129 @@ +"""Redis connection management.""" + +import logging +from typing import Any + +from fastapi import Request +from redis.asyncio import Redis +from redis.exceptions import RedisError + +from app.core.config import settings + +logger = logging.getLogger(__name__) + + +async def init_redis() -> Redis: + """Initialize Redis client instance with connection pooling. + + Returns: + Redis: Async Redis client with connection pooling + + This should be called once during application startup. + """ + redis_client = Redis( + host=settings.redis_host, + port=settings.redis_port, + db=settings.redis_db, + password=settings.redis_password if settings.redis_password else None, + decode_responses=True, + socket_connect_timeout=5, + socket_timeout=5, + ) + + # Verify connection on startup + try: + await redis_client.pubsub().ping() + logger.info("Redis client initialized and connected: %s:%s", settings.redis_host, settings.redis_port) + except (TimeoutError, RedisError, OSError): + logger.exception("Failed to connect to Redis during initialization.") + raise + + return redis_client + + +async def close_redis(redis_client: Redis) -> None: + """Close Redis connection and connection pool. + + Args: + redis_client: Redis client to close + + This properly closes all connections in the pool. + """ + if redis_client: + await redis_client.aclose() + logger.info("Redis connection pool closed") + + +async def ping_redis(redis_client: Redis) -> bool: + """Check if Redis is available (health check). + + Args: + redis_client: Redis client to ping + + Returns: + bool: True if Redis is responding, False otherwise + + This is useful for health check endpoints. + """ + try: + await redis_client.pubsub().ping() + except (TimeoutError, RedisError, OSError) as e: + logger.warning("Redis ping failed: %s", e) + return False + else: + return True + + +async def get_redis_value(redis_client: Redis, key: str) -> str | None: + """Get value from Redis. + + Args: + redis_client: Redis client + key: Redis key + + Returns: + Value as string, or None if not found + """ + try: + return await redis_client.get(key) + except (TimeoutError, RedisError, OSError): + logger.exception("Failed to get Redis value for key %s.", key) + return None + + +async def set_redis_value(redis_client: Redis, key: str, value: Any, ex: int | None = None) -> bool: + """Set value in Redis. + + Args: + redis_client: Redis client + key: Redis key + value: Value to stores + ex: Expiration time in seconds (optional) + + Returns: + bool: True if successful, False otherwise + """ + try: + await redis_client.set(key, value, ex=ex) + except (TimeoutError, RedisError, OSError): + logger.exception("Failed to set Redis value for key %s.", key) + return False + else: + return True + + +def get_redis_dependency(request: Request) -> Redis: + """FastAPI dependency to get Redis client from app state. + + Args: + request: FastAPI request object + + Returns: + Redis: Redis client instance + + Usage: + @app.get("/example") + async def example(redis: Redis = Depends(get_redis_dependency)): + await redis.get("key") + """ + return request.app.state.redis diff --git a/backend/app/main.py b/backend/app/main.py index 8623cfe..2104b08 100644 --- a/backend/app/main.py +++ b/backend/app/main.py @@ -4,27 +4,84 @@ mounts static and upload directories, and initializes the admin interface. """ +import logging +from collections.abc import AsyncGenerator +from contextlib import asynccontextmanager + from fastapi import FastAPI from fastapi.middleware.cors import CORSMiddleware from fastapi.staticfiles import StaticFiles from fastapi_pagination import add_pagination from app.api.admin.main import init_admin +from app.api.auth.utils.email_validation import EmailChecker from app.api.common.routers.exceptions import register_exception_handlers from app.api.common.routers.main import router from app.api.common.routers.openapi import init_openapi_docs from app.core.config import settings from app.core.database import async_engine +from app.core.redis import close_redis, init_redis from app.core.utils.custom_logging import setup_logging # Initialize logging setup_logging() +logger = logging.getLogger(__name__) + + +@asynccontextmanager +async def lifespan(app: FastAPI) -> AsyncGenerator: + """Manage application lifespan: startup and shutdown events.""" + # Startup + logger.info("Starting up application...") + + # Initialize Redis connection and store in app.state + # The init_redis() function will verify the connection on startup + try: + app.state.redis = await init_redis() + except (ConnectionError, OSError) as e: + logger.warning("Failed to initialize Redis: %s", e) + app.state.redis = None + + # Initialize disposable email checker and store in app.state + app.state.email_checker = None + if app.state.redis is not None: + try: + email_checker = EmailChecker(app.state.redis) + await email_checker.initialize() + app.state.email_checker = email_checker + except (RuntimeError, ValueError, ConnectionError) as e: + logger.warning("Failed to initialize email checker: %s", e) + + logger.info("Application startup complete") + + yield + + # Shutdown + logger.info("Shutting down application...") + + # Close email checker (this will cancel background tasks) + if app.state.email_checker is not None: + try: + await app.state.email_checker.close() + except (RuntimeError, OSError) as e: + logger.warning("Error closing email checker: %s", e) + + # Close Redis connection + if app.state.redis is not None: + try: + await close_redis(app.state.redis) + except (ConnectionError, OSError) as e: + logger.warning("Error closing Redis: %s", e) + + logger.info("Application shutdown complete") + -# Initialize FastAPI application +# Initialize FastAPI application with lifespan app = FastAPI( openapi_url=None, docs_url=None, redoc_url=None, + lifespan=lifespan, ) # Add CORS middleware diff --git a/backend/pyproject.toml b/backend/pyproject.toml index cd7df75..fd4f4c1 100644 --- a/backend/pyproject.toml +++ b/backend/pyproject.toml @@ -21,8 +21,7 @@ readme = "README.md" ## Dependencies and version constraints - dependencies = [ # Core dependencies. - "aiosmtplib>=4.0.1", + dependencies = [ "asyncache>=0.3.1", "asyncpg>=0.30.0", "cachetools>=5.5.2", @@ -48,6 +47,7 @@ "pydantic-settings >=2.10.1", "python-dotenv >=1.1.1", "python-slugify>=8.0.4", + "redis>=5.2.1", "relab-rpi-cam-models>=0.1.1", "sqlalchemy >=2.0.41", "sqlmodel >=0.0.24", diff --git a/backend/uv.lock b/backend/uv.lock index 99661a9..44bede3 100644 --- a/backend/uv.lock +++ b/backend/uv.lock @@ -8,11 +8,11 @@ resolution-markers = [ [[package]] name = "aiosmtplib" -version = "5.0.0" +version = "3.0.2" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/a2/15/c2dc93a58d716bce64b53918d3cf667d86c96a56a9f3a239a9f104643637/aiosmtplib-5.0.0.tar.gz", hash = "sha256:514ac11c31cb767c764077eb3c2eb2ae48df6f63f1e847aeb36119c4fc42b52d", size = 61057, upload-time = "2025-10-19T19:12:31.426Z" } +sdist = { url = "https://files.pythonhosted.org/packages/91/2a/812517f8350cd317aad2ba1ce25dfc213c6f1f2e62e1cbf662b4bdc51d34/aiosmtplib-3.0.2.tar.gz", hash = "sha256:08fd840f9dbc23258025dca229e8a8f04d2ccf3ecb1319585615bfc7933f7f47", size = 59941, upload-time = "2024-07-31T05:13:10.065Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/99/42/b997c306dc54e6ac62a251787f6b5ec730797eea08e0336d8f0d7b899d5f/aiosmtplib-5.0.0-py3-none-any.whl", hash = "sha256:95eb0f81189780845363ab0627e7f130bca2d0060d46cd3eeb459f066eb7df32", size = 27048, upload-time = "2025-10-19T19:12:30.124Z" }, + { url = "https://files.pythonhosted.org/packages/87/35/441faea7a11159795881a6ec869454f40269e4e3806dced935a35d83a412/aiosmtplib-3.0.2-py3-none-any.whl", hash = "sha256:8783059603a34834c7c90ca51103c3aa129d5922003b5ce98dbaa6d4440f10fc", size = 27111, upload-time = "2024-07-31T05:13:08.515Z" }, ] [[package]] @@ -198,6 +198,28 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/a9/cf/45fb5261ece3e6b9817d3d82b2f343a505fd58674a92577923bc500bd1aa/bcrypt-4.3.0-cp39-abi3-win_amd64.whl", hash = "sha256:e53e074b120f2877a35cc6c736b8eb161377caae8925c17688bd46ba56daaa5b", size = 152799, upload-time = "2025-02-28T01:23:53.139Z" }, ] +[[package]] +name = "beautifulsoup4" +version = "4.14.2" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "soupsieve" }, + { name = "typing-extensions" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/77/e9/df2358efd7659577435e2177bfa69cba6c33216681af51a707193dec162a/beautifulsoup4-4.14.2.tar.gz", hash = "sha256:2a98ab9f944a11acee9cc848508ec28d9228abfd522ef0fad6a02a72e0ded69e", size = 625822, upload-time = "2025-09-29T10:05:42.613Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/94/fe/3aed5d0be4d404d12d36ab97e2f1791424d9ca39c2f754a6285d59a3b01d/beautifulsoup4-4.14.2-py3-none-any.whl", hash = "sha256:5ef6fa3a8cbece8488d66985560f97ed091e22bbc4e9c2338508a9d5de6d4515", size = 106392, upload-time = "2025-09-29T10:05:43.771Z" }, +] + +[[package]] +name = "blinker" +version = "1.9.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/21/28/9b3f50ce0e048515135495f198351908d99540d69bfdc8c1d15b73dc55ce/blinker-1.9.0.tar.gz", hash = "sha256:b4ce2265a7abece45e7cc896e98dbebe6cead56bcf805a3d23136d145f5445bf", size = 22460, upload-time = "2024-11-08T17:25:47.436Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/10/cb/f2ad4230dc2eb1a74edf38f1a38b9b52277f75bef262d8908e60d957e13c/blinker-1.9.0-py3-none-any.whl", hash = "sha256:ba0efaa9080b619ff2f3459d1d500c57bddea4a6b424b60a91141db6fd2f08bc", size = 8458, upload-time = "2024-11-08T17:25:46.184Z" }, +] + [[package]] name = "boto3" version = "1.40.55" @@ -489,6 +511,21 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/ba/5a/18ad964b0086c6e62e2e7500f7edc89e3faa45033c71c1893d34eed2b2de/dnspython-2.8.0-py3-none-any.whl", hash = "sha256:01d9bbc4a2d76bf0db7c1f729812ded6d912bd318d3b1cf81d30c0f845dbf3af", size = 331094, upload-time = "2025-09-07T18:57:58.071Z" }, ] +[[package]] +name = "docopt" +version = "0.6.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/a2/55/8f8cab2afd404cf578136ef2cc5dfb50baa1761b68c9da1fb1e4eed343c9/docopt-0.6.2.tar.gz", hash = "sha256:49b3a825280bd66b3aa83585ef59c4a8c82f2c8a522dbe754a8bc8d08c85c491", size = 25901, upload-time = "2014-06-16T11:18:57.406Z" } + +[[package]] +name = "dotmap" +version = "1.3.30" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/bc/68/c186606e4f2bf731abd18044ea201e70c3c244bf468f41368820d197fca5/dotmap-1.3.30.tar.gz", hash = "sha256:5821a7933f075fb47563417c0e92e0b7c031158b4c9a6a7e56163479b658b368", size = 12391, upload-time = "2022-04-06T16:26:49.211Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/4d/f9/976d6813c160d6c89196d81e9466dca1503d20e609d8751f3536daf37ec6/dotmap-1.3.30-py3-none-any.whl", hash = "sha256:bd9fa15286ea2ad899a4d1dc2445ed85a1ae884a42effb87c89a6ecce71243c6", size = 11464, upload-time = "2022-04-06T16:26:47.103Z" }, +] + [[package]] name = "email-validator" version = "2.2.0" @@ -610,6 +647,24 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/5e/88/afc022ad64d12f730141fc50758ecf9d60de5fed11335dc16e3127617f05/fastapi_filter-2.0.1-py3-none-any.whl", hash = "sha256:711d48707ec62f7c9e12a7713fc0f6a99858a9e3741b4d108102d5599e77197d", size = 11586, upload-time = "2024-12-07T17:30:05.375Z" }, ] +[[package]] +name = "fastapi-mail" +version = "1.5.2" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "aiosmtplib" }, + { name = "blinker" }, + { name = "email-validator" }, + { name = "jinja2" }, + { name = "pydantic" }, + { name = "pydantic-settings" }, + { name = "starlette" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/65/0c/05837963c44ce15e4c81e95bb8bb8a2910fddd60a2f41ac5c015c068c53e/fastapi_mail-1.5.2.tar.gz", hash = "sha256:c83b96f1a030db754e83c64d8687b62b3d4f847d25b5adb00f30d5765ff9825a", size = 13312, upload-time = "2025-10-16T11:13:40.484Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/af/da/30e1a709d85a3132220538714af09b9befad9e81703021dde698c884187a/fastapi_mail-1.5.2-py3-none-any.whl", hash = "sha256:158ecf49075430cb6a5483f557a8f45b987e31f2105a77b3239933b0bacb03e5", size = 15153, upload-time = "2025-10-16T11:13:39.529Z" }, +] + [[package]] name = "fastapi-pagination" version = "0.14.3" @@ -778,6 +833,8 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/ee/43/3cecdc0349359e1a527cbf2e3e28e5f8f06d3343aaf82ca13437a9aa290f/greenlet-3.2.4-cp313-cp313-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:23768528f2911bcd7e475210822ffb5254ed10d71f4028387e5a99b4c6699671", size = 610497, upload-time = "2025-08-07T13:18:31.636Z" }, { url = "https://files.pythonhosted.org/packages/b8/19/06b6cf5d604e2c382a6f31cafafd6f33d5dea706f4db7bdab184bad2b21d/greenlet-3.2.4-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:00fadb3fedccc447f517ee0d3fd8fe49eae949e1cd0f6a611818f4f6fb7dc83b", size = 1121662, upload-time = "2025-08-07T13:42:41.117Z" }, { url = "https://files.pythonhosted.org/packages/a2/15/0d5e4e1a66fab130d98168fe984c509249c833c1a3c16806b90f253ce7b9/greenlet-3.2.4-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:d25c5091190f2dc0eaa3f950252122edbbadbb682aa7b1ef2f8af0f8c0afefae", size = 1149210, upload-time = "2025-08-07T13:18:24.072Z" }, + { url = "https://files.pythonhosted.org/packages/1c/53/f9c440463b3057485b8594d7a638bed53ba531165ef0ca0e6c364b5cc807/greenlet-3.2.4-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:6e343822feb58ac4d0a1211bd9399de2b3a04963ddeec21530fc426cc121f19b", size = 1564759, upload-time = "2025-11-04T12:42:19.395Z" }, + { url = "https://files.pythonhosted.org/packages/47/e4/3bb4240abdd0a8d23f4f88adec746a3099f0d86bfedb623f063b2e3b4df0/greenlet-3.2.4-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:ca7f6f1f2649b89ce02f6f229d7c19f680a6238af656f61e0115b24857917929", size = 1634288, upload-time = "2025-11-04T12:42:21.174Z" }, { url = "https://files.pythonhosted.org/packages/0b/55/2321e43595e6801e105fcfdee02b34c0f996eb71e6ddffca6b10b7e1d771/greenlet-3.2.4-cp313-cp313-win_amd64.whl", hash = "sha256:554b03b6e73aaabec3745364d6239e9e012d64c68ccd0b8430c64ccc14939a8b", size = 299685, upload-time = "2025-08-07T13:24:38.824Z" }, { url = "https://files.pythonhosted.org/packages/22/5c/85273fd7cc388285632b0498dbbab97596e04b154933dfe0f3e68156c68c/greenlet-3.2.4-cp314-cp314-macosx_11_0_universal2.whl", hash = "sha256:49a30d5fda2507ae77be16479bdb62a660fa51b1eb4928b524975b3bde77b3c0", size = 273586, upload-time = "2025-08-07T13:16:08.004Z" }, { url = "https://files.pythonhosted.org/packages/d1/75/10aeeaa3da9332c2e761e4c50d4c3556c21113ee3f0afa2cf5769946f7a3/greenlet-3.2.4-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:299fd615cd8fc86267b47597123e3f43ad79c9d8a22bebdce535e53550763e2f", size = 686346, upload-time = "2025-08-07T13:42:59.944Z" }, @@ -785,6 +842,8 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/dc/8b/29aae55436521f1d6f8ff4e12fb676f3400de7fcf27fccd1d4d17fd8fecd/greenlet-3.2.4-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:b4a1870c51720687af7fa3e7cda6d08d801dae660f75a76f3845b642b4da6ee1", size = 694659, upload-time = "2025-08-07T13:53:17.759Z" }, { url = "https://files.pythonhosted.org/packages/92/2e/ea25914b1ebfde93b6fc4ff46d6864564fba59024e928bdc7de475affc25/greenlet-3.2.4-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:061dc4cf2c34852b052a8620d40f36324554bc192be474b9e9770e8c042fd735", size = 695355, upload-time = "2025-08-07T13:18:34.517Z" }, { url = "https://files.pythonhosted.org/packages/72/60/fc56c62046ec17f6b0d3060564562c64c862948c9d4bc8aa807cf5bd74f4/greenlet-3.2.4-cp314-cp314-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:44358b9bf66c8576a9f57a590d5f5d6e72fa4228b763d0e43fee6d3b06d3a337", size = 657512, upload-time = "2025-08-07T13:18:33.969Z" }, + { url = "https://files.pythonhosted.org/packages/23/6e/74407aed965a4ab6ddd93a7ded3180b730d281c77b765788419484cdfeef/greenlet-3.2.4-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:2917bdf657f5859fbf3386b12d68ede4cf1f04c90c3a6bc1f013dd68a22e2269", size = 1612508, upload-time = "2025-11-04T12:42:23.427Z" }, + { url = "https://files.pythonhosted.org/packages/0d/da/343cd760ab2f92bac1845ca07ee3faea9fe52bee65f7bcb19f16ad7de08b/greenlet-3.2.4-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:015d48959d4add5d6c9f6c5210ee3803a830dce46356e3bc326d6776bde54681", size = 1680760, upload-time = "2025-11-04T12:42:25.341Z" }, { url = "https://files.pythonhosted.org/packages/e3/a5/6ddab2b4c112be95601c13428db1d8b6608a8b6039816f2ba09c346c08fc/greenlet-3.2.4-cp314-cp314-win_amd64.whl", hash = "sha256:e37ab26028f12dbb0ff65f29a8d3d44a765c61e729647bf2ddfbbed621726f01", size = 303425, upload-time = "2025-08-07T13:32:27.59Z" }, ] @@ -1034,6 +1093,21 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/b3/38/89ba8ad64ae25be8de66a6d463314cf1eb366222074cfda9ee839c56a4b4/mdurl-0.1.2-py3-none-any.whl", hash = "sha256:84008a41e51615a49fc9966191ff91509e3c40b939176e643fd50a5c2196b8f8", size = 9979, upload-time = "2022-08-14T12:40:09.779Z" }, ] +[[package]] +name = "mjml" +version = "0.11.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "beautifulsoup4" }, + { name = "docopt" }, + { name = "dotmap" }, + { name = "jinja2" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/2a/68/4e0e1b0bc64f0d3afac2fb8a4fb35f2a4e9a0521ae1c777c0e29e21b27fa/mjml-0.11.1.tar.gz", hash = "sha256:f703c8b3458ca0100df6cf56a3633f193b352a80b1a1836a452b92361e74ca73", size = 66589, upload-time = "2025-05-13T10:24:05.693Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/85/a6/7ed27888adbf8cbdd734e298691004918ec0ef5f40e6bc1329ed97da2273/mjml-0.11.1-py3-none-any.whl", hash = "sha256:fef9f7a95929cbe5ddce9351ee8702e05153d68abc77dcf8e84da2c22a330b2a", size = 63191, upload-time = "2025-05-13T10:24:03.953Z" }, +] + [[package]] name = "nodeenv" version = "1.9.1" @@ -1637,23 +1711,33 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/f1/12/de94a39c2ef588c7e6455cfbe7343d3b2dc9d6b6b2f40c4c6565744c873d/pyyaml-6.0.3-cp314-cp314t-win_arm64.whl", hash = "sha256:ebc55a14a21cb14062aa4162f906cd962b28e2e9ea38f9b4391244cd8de4ae0b", size = 149341, upload-time = "2025-09-25T21:32:56.828Z" }, ] +[[package]] +name = "redis" +version = "7.0.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/57/8f/f125feec0b958e8d22c8f0b492b30b1991d9499a4315dfde466cf4289edc/redis-7.0.1.tar.gz", hash = "sha256:c949df947dca995dc68fdf5a7863950bf6df24f8d6022394585acc98e81624f1", size = 4755322, upload-time = "2025-10-27T14:34:00.33Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/e9/97/9f22a33c475cda519f20aba6babb340fb2f2254a02fb947816960d1e669a/redis-7.0.1-py3-none-any.whl", hash = "sha256:4977af3c7d67f8f0eb8b6fec0dafc9605db9343142f634041fb0235f67c0588a", size = 339938, upload-time = "2025-10-27T14:33:58.553Z" }, +] + [[package]] name = "relab-backend" version = "0.1.0" source = { virtual = "." } dependencies = [ - { name = "aiosmtplib" }, { name = "asyncache" }, { name = "asyncpg" }, { name = "cachetools" }, { name = "email-validator" }, { name = "fastapi", extra = ["standard"] }, { name = "fastapi-filter" }, + { name = "fastapi-mail" }, { name = "fastapi-pagination" }, { name = "fastapi-storages" }, { name = "fastapi-users", extra = ["oauth", "sqlalchemy"] }, { name = "fastapi-users-db-sqlmodel" }, { name = "markdown" }, + { name = "mjml" }, { name = "pillow" }, { name = "psycopg", extra = ["binary"] }, { name = "pydantic" }, @@ -1661,6 +1745,7 @@ dependencies = [ { name = "pydantic-settings" }, { name = "python-dotenv" }, { name = "python-slugify" }, + { name = "redis" }, { name = "relab-rpi-cam-models" }, { name = "sqlalchemy" }, { name = "sqlmodel" }, @@ -1698,18 +1783,19 @@ tests = [ [package.metadata] requires-dist = [ - { name = "aiosmtplib", specifier = ">=4.0.1" }, { name = "asyncache", specifier = ">=0.3.1" }, { name = "asyncpg", specifier = ">=0.30.0" }, { name = "cachetools", specifier = ">=5.5.2" }, { name = "email-validator", specifier = ">=2.2.0" }, { name = "fastapi", extras = ["standard"], specifier = ">=0.115.14" }, { name = "fastapi-filter", specifier = ">=2.0.1" }, + { name = "fastapi-mail", specifier = "==1.5.2" }, { name = "fastapi-pagination", specifier = ">=0.13.2" }, { name = "fastapi-storages", specifier = ">=0.3.0" }, { name = "fastapi-users", extras = ["oauth", "sqlalchemy"], specifier = ">=14.0.1" }, { name = "fastapi-users-db-sqlmodel", git = "https://github.com/simonvanlierde/fastapi-users-db-sqlmodel?rev=7e9c4830e53ee20c38e3de80066cb19d7c3efc43" }, { name = "markdown", specifier = ">=3.8.2" }, + { name = "mjml", specifier = ">=0.11.1" }, { name = "pillow", specifier = ">=11.2.1" }, { name = "psycopg", extras = ["binary"], specifier = ">=3.2.9" }, { name = "pydantic", specifier = ">=2.11,<2.12" }, @@ -1717,6 +1803,7 @@ requires-dist = [ { name = "pydantic-settings", specifier = ">=2.10.1" }, { name = "python-dotenv", specifier = ">=1.1.1" }, { name = "python-slugify", specifier = ">=8.0.4" }, + { name = "redis", specifier = ">=5.2.1" }, { name = "relab-rpi-cam-models", specifier = ">=0.1.1" }, { name = "sqlalchemy", specifier = ">=2.0.41" }, { name = "sqlmodel", specifier = ">=0.0.24" }, @@ -1947,6 +2034,15 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/e9/44/75a9c9421471a6c4805dbf2356f7c181a29c1879239abab1ea2cc8f38b40/sniffio-1.3.1-py3-none-any.whl", hash = "sha256:2f6da418d1f1e0fddd844478f41680e794e6051915791a034ff65e5f100525a2", size = 10235, upload-time = "2024-02-25T23:20:01.196Z" }, ] +[[package]] +name = "soupsieve" +version = "2.8" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/6d/e6/21ccce3262dd4889aa3332e5a119a3491a95e8f60939870a3a035aabac0d/soupsieve-2.8.tar.gz", hash = "sha256:e2dd4a40a628cb5f28f6d4b0db8800b8f581b65bb380b97de22ba5ca8d72572f", size = 103472, upload-time = "2025-08-27T15:39:51.78Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/14/a0/bb38d3b76b8cae341dad93a2dd83ab7462e6dbcdd84d43f54ee60a8dc167/soupsieve-2.8-py3-none-any.whl", hash = "sha256:0cc76456a30e20f5d7f2e14a98a4ae2ee4e5abdc7c5ea0aafe795f344bc7984c", size = 36679, upload-time = "2025-08-27T15:39:50.179Z" }, +] + [[package]] name = "sqladmin" version = "0.21.0" diff --git a/compose.override.yml b/compose.override.yml index e6acd8b..d1b6eaf 100644 --- a/compose.override.yml +++ b/compose.override.yml @@ -15,6 +15,10 @@ services: - /opt/relab/backend/.venv # Prevent overwriting local virtual environment - /opt/relab/backend/logs # Prevent overwriting local logs + cache: + ports: + - "6379:6379" + database: ports: - "5433:5432" diff --git a/compose.prod.yml b/compose.prod.yml index dc1c5a3..82908a0 100644 --- a/compose.prod.yml +++ b/compose.prod.yml @@ -31,6 +31,10 @@ services: - user_uploads:/data/uploads:ro - ${BACKUP_DIR:-./backend/backups}/user_uploads:/backups + cache: + volumes: # Persist cache data in production + - cache_data:/data + cloudflared: # Cloudflared tunnel to cml-relab.org image: cloudflare/cloudflared:latest@sha256:89ee50efb1e9cb2ae30281a8a404fed95eb8f02f0a972617526f8c5b417acae2 command: tunnel --no-autoupdate run diff --git a/compose.yml b/compose.yml index 1d194ae..792db55 100644 --- a/compose.yml +++ b/compose.yml @@ -21,6 +21,8 @@ services: depends_on: database: condition: service_healthy + cache: + condition: service_healthy env_file: ./backend/.env environment: DATABASE_HOST: database @@ -35,15 +37,17 @@ services: image: postgres:18@sha256:41bfa2e5b168fff0847a5286694a86cff102bdc4d59719869f6b117bb30b3a24 env_file: ./backend/.env healthcheck: - test: # Check if the database is ready to accept connections - ["CMD-SHELL", "pg_isready -h localhost -U $${POSTGRES_USER} -d $${POSTGRES_DB}"] - interval: 5s - timeout: 5s - retries: 5 + test: ["CMD-SHELL", "pg_isready -h localhost -U $${POSTGRES_USER} -d $${POSTGRES_DB}"] restart: unless-stopped volumes: - database_data:/var/lib/postgresql + cache: + image: redis:8 + healthcheck: + test: ["CMD-SHELL", "redis-cli ping"] + restart: unless-stopped + docs: image: squidfunk/mkdocs-material:9@sha256:980e11fed03b8e7851e579be9f34b1210f516c9f0b4da1a1457f21a460bd6628 restart: unless-stopped From 31bd113ba11d3112f306e5099a2f3d0c638d8e02 Mon Sep 17 00:00:00 2001 From: Simon van Lierde Date: Thu, 6 Nov 2025 18:49:19 +0100 Subject: [PATCH 22/71] feature(backend): add order_by query param to get_products route --- backend/app/api/common/crud/base.py | 2 ++ backend/app/api/data_collection/routers.py | 3 --- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/backend/app/api/common/crud/base.py b/backend/app/api/common/crud/base.py index 2864aaa..f183630 100644 --- a/backend/app/api/common/crud/base.py +++ b/backend/app/api/common/crud/base.py @@ -95,6 +95,8 @@ def get_models_query( statement = add_filter_joins(statement, model, model_filter) # Apply the filter statement = model_filter.filter(statement) + # Apply sorting - fastapi-filter stores it but doesn't apply it automatically + statement = model_filter.sort(statement) relationships_to_exclude = [] statement, relationships_to_exclude = add_relationship_options( diff --git a/backend/app/api/data_collection/routers.py b/backend/app/api/data_collection/routers.py index c70f2dd..cd4ebbb 100644 --- a/backend/app/api/data_collection/routers.py +++ b/backend/app/api/data_collection/routers.py @@ -228,9 +228,6 @@ async def get_products( else: statement: SelectOfScalar[Product] = select(Product).where(Product.parent_id == None) - if product_filter: - statement = product_filter.filter(statement) - return await get_paginated_models( session, Product, From 662c32e24a40400c4551f394794383013f279dd5 Mon Sep 17 00:00:00 2001 From: Simon van Lierde Date: Thu, 6 Nov 2025 18:50:26 +0100 Subject: [PATCH 23/71] fix(backend): graceful handling of failed redis connection on app startup --- backend/app/core/redis.py | 43 +++++++++++++++++++++------------------ backend/app/main.py | 8 ++------ 2 files changed, 25 insertions(+), 26 deletions(-) diff --git a/backend/app/core/redis.py b/backend/app/core/redis.py index 282bf72..af91b16 100644 --- a/backend/app/core/redis.py +++ b/backend/app/core/redis.py @@ -12,33 +12,34 @@ logger = logging.getLogger(__name__) -async def init_redis() -> Redis: +async def init_redis() -> Redis | None: """Initialize Redis client instance with connection pooling. Returns: - Redis: Async Redis client with connection pooling + Redis: Async Redis client with connection pooling, or None if connection fails This should be called once during application startup. + Gracefully handles connection failures and returns None if Redis is unavailable. """ - redis_client = Redis( - host=settings.redis_host, - port=settings.redis_port, - db=settings.redis_db, - password=settings.redis_password if settings.redis_password else None, - decode_responses=True, - socket_connect_timeout=5, - socket_timeout=5, - ) - - # Verify connection on startup try: + redis_client = Redis( + host=settings.redis_host, + port=settings.redis_port, + db=settings.redis_db, + password=settings.redis_password if settings.redis_password else None, + decode_responses=True, + socket_connect_timeout=5, + socket_timeout=5, + ) + + # Verify connection on startup await redis_client.pubsub().ping() logger.info("Redis client initialized and connected: %s:%s", settings.redis_host, settings.redis_port) - except (TimeoutError, RedisError, OSError): - logger.exception("Failed to connect to Redis during initialization.") - raise + return redis_client - return redis_client + except (TimeoutError, RedisError, OSError, ConnectionError) as e: + logger.warning("Failed to connect to Redis during initialization: %s. Application will continue without Redis.", e) + return None async def close_redis(redis_client: Redis) -> None: @@ -112,18 +113,20 @@ async def set_redis_value(redis_client: Redis, key: str, value: Any, ex: int | N return True -def get_redis_dependency(request: Request) -> Redis: +def get_redis_dependency(request: Request) -> Redis | None: """FastAPI dependency to get Redis client from app state. Args: request: FastAPI request object Returns: - Redis: Redis client instance + Redis client instance, or None if Redis is not available Usage: @app.get("/example") - async def example(redis: Redis = Depends(get_redis_dependency)): + async def example(redis: Redis | None = Depends(get_redis_dependency)): + if redis is None: + raise HTTPException(status_code=503, detail="Redis is not available") await redis.get("key") """ return request.app.state.redis diff --git a/backend/app/main.py b/backend/app/main.py index 2104b08..7d0757f 100644 --- a/backend/app/main.py +++ b/backend/app/main.py @@ -35,12 +35,8 @@ async def lifespan(app: FastAPI) -> AsyncGenerator: logger.info("Starting up application...") # Initialize Redis connection and store in app.state - # The init_redis() function will verify the connection on startup - try: - app.state.redis = await init_redis() - except (ConnectionError, OSError) as e: - logger.warning("Failed to initialize Redis: %s", e) - app.state.redis = None + # The init_redis() function will verify the connection on startup and return None if it fails + app.state.redis = await init_redis() # Initialize disposable email checker and store in app.state app.state.email_checker = None From 9db5f411d3d28ac42748622dede9423a2181e092 Mon Sep 17 00:00:00 2001 From: Simon van Lierde Date: Fri, 7 Nov 2025 12:41:36 +0100 Subject: [PATCH 24/71] fix(backend): Include built email templates in git --- backend/.dockerignore | 3 + backend/.gitignore | 3 + .../templates/emails/build/newsletter.html | 259 ++++++++++++++ .../emails/build/newsletter_subscription.html | 170 +++++++++ .../emails/build/newsletter_unsubscribe.html | 165 +++++++++ .../emails/build/password_reset.html | 165 +++++++++ .../emails/build/post_verification.html | 141 ++++++++ .../templates/emails/build/registration.html | 324 ++++++++++++++++++ .../templates/emails/build/verification.html | 165 +++++++++ 9 files changed, 1395 insertions(+) create mode 100644 backend/app/templates/emails/build/newsletter.html create mode 100644 backend/app/templates/emails/build/newsletter_subscription.html create mode 100644 backend/app/templates/emails/build/newsletter_unsubscribe.html create mode 100644 backend/app/templates/emails/build/password_reset.html create mode 100644 backend/app/templates/emails/build/post_verification.html create mode 100644 backend/app/templates/emails/build/registration.html create mode 100644 backend/app/templates/emails/build/verification.html diff --git a/backend/.dockerignore b/backend/.dockerignore index 4c510a3..2c42c71 100644 --- a/backend/.dockerignore +++ b/backend/.dockerignore @@ -96,3 +96,6 @@ MANIFEST # Local logs ./logs + +# Include built email templates +!app/templates/emails/build/ \ No newline at end of file diff --git a/backend/.gitignore b/backend/.gitignore index 38f0b26..966df64 100644 --- a/backend/.gitignore +++ b/backend/.gitignore @@ -80,3 +80,6 @@ backups/* # VS Code settings !.vscode/settings.json !.vscode/extensions.json + +# Include built email templates +!app/templates/emails/build/ \ No newline at end of file diff --git a/backend/app/templates/emails/build/newsletter.html b/backend/app/templates/emails/build/newsletter.html new file mode 100644 index 0000000..5a11a13 --- /dev/null +++ b/backend/app/templates/emails/build/newsletter.html @@ -0,0 +1,259 @@ + + + + {{ subject }} + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + + + +
+ +
+ + + + + + +
+
{{ content }}
+
+
+ +
+
+ +
+ + + + + + +
+ +
+ + + + + + + + + +
+

+ + +
+
+ +
+
+ +
+ + + + + + +
+ +
+ + + + + + + + + +
+

+ + +
+
+ +
+
+ +
+ + diff --git a/backend/app/templates/emails/build/newsletter_subscription.html b/backend/app/templates/emails/build/newsletter_subscription.html new file mode 100644 index 0000000..74db9ce --- /dev/null +++ b/backend/app/templates/emails/build/newsletter_subscription.html @@ -0,0 +1,170 @@ + + + + Reverse Engineering Lab: Confirm Your Newsletter Subscription + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + + + +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +
+
Hello,
+
+
Thank you for subscribing to the Reverse Engineering Lab newsletter!
+
+
Please confirm your subscription by clicking the button below:
+
+ + + + +
+ Confirm Subscription +
+
+
+ Or copy and paste this link in your browser:
+ {{ confirmation_link }} +
+
+
This link will expire in 24 hours.
+
+
We'll keep you updated with our progress and let you know when the full application is launched.
+
+
+ +
+
+ +
+ + diff --git a/backend/app/templates/emails/build/newsletter_unsubscribe.html b/backend/app/templates/emails/build/newsletter_unsubscribe.html new file mode 100644 index 0000000..2bba8b1 --- /dev/null +++ b/backend/app/templates/emails/build/newsletter_unsubscribe.html @@ -0,0 +1,165 @@ + + + + Reverse Engineering Lab: Unsubscribe Request + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + + + +
+ +
+ + + + + + + + + + + + + + + + + + + + + +
+
Hello,
+
+
We received a request to unsubscribe this email address from the Reverse Engineering Lab newsletter.
+
+
If you made this request, please click the button below to unsubscribe:
+
+ + + + +
+ Unsubscribe +
+
+
+ Or copy and paste this link in your browser:
+ {{ unsubscribe_link }} +
+
+
If you did not request to unsubscribe, you can safely ignore this email.
+
+
+ +
+
+ +
+ + diff --git a/backend/app/templates/emails/build/password_reset.html b/backend/app/templates/emails/build/password_reset.html new file mode 100644 index 0000000..0974956 --- /dev/null +++ b/backend/app/templates/emails/build/password_reset.html @@ -0,0 +1,165 @@ + + + + Password Reset + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + + + +
+ +
+ + + + + + + + + + + + + + + + + + + + + +
+
Hello {{ username }},
+
+
Please reset your password by clicking the button below:
+
+ + + + +
+ Reset Password +
+
+
+ Or copy and paste this link in your browser:
+ {{ reset_link }} +
+
+
This link will expire in 1 hour.
+
+
If you did not request a password reset, please ignore this email.
+
+
+ +
+
+ +
+ + diff --git a/backend/app/templates/emails/build/post_verification.html b/backend/app/templates/emails/build/post_verification.html new file mode 100644 index 0000000..39f7850 --- /dev/null +++ b/backend/app/templates/emails/build/post_verification.html @@ -0,0 +1,141 @@ + + + + Email Verified + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + + + +
+ +
+ + + + + + + + + + + + +
+
Hello {{ username }},
+
+
Your email has been verified!
+
+
Thank you for verifying your email address. You can now enjoy full access to all features.
+
+
+ +
+
+ +
+ + diff --git a/backend/app/templates/emails/build/registration.html b/backend/app/templates/emails/build/registration.html new file mode 100644 index 0000000..a37667d --- /dev/null +++ b/backend/app/templates/emails/build/registration.html @@ -0,0 +1,324 @@ + + + + Welcome to Reverse Engineering Lab - Verify Your Email + + + + + + + + + + + + + + + + +
+ +
+ + + + + + +
+ +
+ + + + + + +
+
Reverse Engineering Lab
+
+
+ +
+
+ +
+ + + + + + +
+ +
+ + + + + + + + + + + + + + + + + + + + + +
+
Hello {{ username }},
+
+
Thank you for registering! Please verify your email by clicking the button below:
+
+ + + + +
+ Verify Email Address +
+
+
+ Or copy and paste this link in your browser:
+ {{ verification_link }} +
+
+
This link will expire in 1 hour.
+
+
If you did not register for this service, please ignore this email.
+
+
+ +
+
+ +
+ + + + + + +
+ +
+ + + + + + + + + +
+

+ + +
+
+ +
+
+ +
+ + + + + + +
+ +
+ + + + + + +
+
+ +
+
+ +
+ + diff --git a/backend/app/templates/emails/build/verification.html b/backend/app/templates/emails/build/verification.html new file mode 100644 index 0000000..d71be70 --- /dev/null +++ b/backend/app/templates/emails/build/verification.html @@ -0,0 +1,165 @@ + + + + Email Verification + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + + + +
+ +
+ + + + + + + + + + + + + + + + + + + + + +
+
Hello {{ username }},
+
+
Please verify your email by clicking the button below:
+
+ + + + +
+ Verify Email Address +
+
+
+ Or copy and paste this link in your browser:
+ {{ verification_link }} +
+
+
This link will expire in 1 hour.
+
+
If you did not request verification, please ignore this email.
+
+
+ +
+
+ +
+ + From 5c4d92c306a5b0393de72711b9d63fcc9921fcde Mon Sep 17 00:00:00 2001 From: Simon van Lierde Date: Fri, 7 Nov 2025 13:56:38 +0100 Subject: [PATCH 25/71] fix(backend): Fix cache dependency in docker compose file (backend, not backend-migrations, depends on cache) --- compose.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/compose.yml b/compose.yml index 792db55..1994d98 100644 --- a/compose.yml +++ b/compose.yml @@ -6,6 +6,8 @@ services: depends_on: database: condition: service_healthy + cache: + condition: service_healthy env_file: ./backend/.env environment: DATABASE_HOST: database # Point to the database service @@ -21,8 +23,6 @@ services: depends_on: database: condition: service_healthy - cache: - condition: service_healthy env_file: ./backend/.env environment: DATABASE_HOST: database From 775728b3e702483854633dd729ce540fc95554fd Mon Sep 17 00:00:00 2001 From: Simon van Lierde Date: Fri, 7 Nov 2025 16:48:51 +0000 Subject: [PATCH 26/71] chore: update pre-commit revs --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 42a0b64..6b9ca26 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -65,7 +65,7 @@ repos: entry: pyright --project backend - repo: https://github.com/astral-sh/ruff-pre-commit - rev: v0.14.3 + rev: v0.14.4 hooks: - id: ruff-check # Lint code files: ^backend/(app|scripts|tests)/ From 36434c3c987d55c0623cfac7016b47283473a796 Mon Sep 17 00:00:00 2001 From: Simon van Lierde Date: Fri, 7 Nov 2025 16:49:43 +0000 Subject: [PATCH 27/71] feature(backend): Use SecretStr for secret env vars in the core config --- backend/app/core/config.py | 10 +++++----- backend/app/core/redis.py | 2 +- backend/scripts/create_superuser.py | 5 +++-- 3 files changed, 9 insertions(+), 8 deletions(-) diff --git a/backend/app/core/config.py b/backend/app/core/config.py index 9aa8888..04313c1 100644 --- a/backend/app/core/config.py +++ b/backend/app/core/config.py @@ -3,7 +3,7 @@ from functools import cached_property from pathlib import Path -from pydantic import EmailStr, HttpUrl, PostgresDsn, computed_field +from pydantic import EmailStr, HttpUrl, PostgresDsn, SecretStr, computed_field from pydantic_settings import BaseSettings, SettingsConfigDict # Set the project base directory and .env file @@ -17,7 +17,7 @@ class CoreSettings(BaseSettings): database_host: str = "localhost" database_port: int = 5432 postgres_user: str = "postgres" - postgres_password: str = "" + postgres_password: SecretStr = SecretStr("") postgres_db: str = "relab_db" postgres_test_db: str = "relab_test_db" @@ -25,14 +25,14 @@ class CoreSettings(BaseSettings): redis_host: str = "localhost" redis_port: int = 6379 redis_db: int = 0 - redis_password: str = "" + redis_password: SecretStr = SecretStr("") # Debug settings debug: bool = False # Superuser settings superuser_email: EmailStr = "your-email@example.com" - superuser_password: str = "" + superuser_password: SecretStr = SecretStr("") # Network settings frontend_web_url: HttpUrl = HttpUrl("http://127.0.0.1:8000") @@ -55,7 +55,7 @@ class CoreSettings(BaseSettings): def _build_database_url(self, driver: str, database: str) -> str: """Build and validate PostgreSQL database URL.""" url = ( - f"postgresql+{driver}://{self.postgres_user}:{self.postgres_password}" + f"postgresql+{driver}://{self.postgres_user}:{self.postgres_password.get_secret_value()}" f"@{self.database_host}:{self.database_port}/{database}" ) PostgresDsn(url) # Validate URL format diff --git a/backend/app/core/redis.py b/backend/app/core/redis.py index af91b16..31e5302 100644 --- a/backend/app/core/redis.py +++ b/backend/app/core/redis.py @@ -26,7 +26,7 @@ async def init_redis() -> Redis | None: host=settings.redis_host, port=settings.redis_port, db=settings.redis_db, - password=settings.redis_password if settings.redis_password else None, + password=settings.redis_password.get_secret_value() if settings.redis_password else None, decode_responses=True, socket_connect_timeout=5, socket_timeout=5, diff --git a/backend/scripts/create_superuser.py b/backend/scripts/create_superuser.py index 1b044fe..c70b78a 100755 --- a/backend/scripts/create_superuser.py +++ b/backend/scripts/create_superuser.py @@ -6,11 +6,12 @@ import logging import anyio +from fastapi_users.exceptions import InvalidPasswordException, UserAlreadyExists + from app.api.auth.schemas import UserCreate from app.api.auth.utils.programmatic_user_crud import create_user from app.core.config import settings from app.core.database import get_async_session -from fastapi_users.exceptions import InvalidPasswordException, UserAlreadyExists # Set up logging logger: logging.Logger = logging.getLogger(__name__) @@ -35,7 +36,7 @@ async def create_superuser() -> None: async_session=async_session, user_create=UserCreate( email=superuser_email, - password=superuser_password, + password=superuser_password.get_secret_value(), organization_id=None, is_superuser=True, is_verified=True, From fd86e95055e38f37ab491cee775010f165f38b1d Mon Sep 17 00:00:00 2001 From: Simon van Lierde Date: Fri, 7 Nov 2025 16:52:39 +0000 Subject: [PATCH 28/71] fix(docker): Improve healthcheck timing and override REDIS_HOST var in backend services --- compose.yml | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/compose.yml b/compose.yml index 1994d98..8937ad6 100644 --- a/compose.yml +++ b/compose.yml @@ -11,6 +11,7 @@ services: env_file: ./backend/.env environment: DATABASE_HOST: database # Point to the database service + REDIS_HOST: cache # Point to the cache service restart: unless-stopped volumes: - user_uploads:/opt/relab/backend/data/uploads @@ -26,6 +27,7 @@ services: env_file: ./backend/.env environment: DATABASE_HOST: database + REDIS_HOST: cache profiles: - migrations restart: on-failure:3 @@ -38,14 +40,20 @@ services: env_file: ./backend/.env healthcheck: test: ["CMD-SHELL", "pg_isready -h localhost -U $${POSTGRES_USER} -d $${POSTGRES_DB}"] + start_period: 5s + start_interval: 5s restart: unless-stopped volumes: - database_data:/var/lib/postgresql cache: image: redis:8 + command: ["sh", "-c", "redis-server --appendonly yes --save 60 1 --requirepass $${REDIS_PASSWORD}"] + env_file: ./backend/.env healthcheck: test: ["CMD-SHELL", "redis-cli ping"] + start_period: 5s + start_interval: 5s restart: unless-stopped docs: From f2662a43c5a13cf068a2bd58b227f4b5b380290f Mon Sep 17 00:00:00 2001 From: Simon van Lierde Date: Fri, 7 Nov 2025 16:53:02 +0000 Subject: [PATCH 29/71] fix(backend): default example redis password should be empty --- backend/.env.example | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/backend/.env.example b/backend/.env.example index fac58ca..1cf0df5 100644 --- a/backend/.env.example +++ b/backend/.env.example @@ -29,10 +29,10 @@ EMAIL_FROM='Your Name ' # 🔀 Email address EMAIL_REPLY_TO='your.replyto.alias.@example.com' # 🔀 Email address to which replies are sent. Can be different from the SMTP server username. # Redis settings for caching (disposable email domains, sessions, etc.) -REDIS_HOST='localhost' # 🔀 Redis server host (use 'cache' in Docker) -REDIS_PORT='6379' # 🔀 Redis server port -REDIS_DB='0' # 🔀 Redis database number (0-15) -REDIS_PASSWORD='password' # 🔀 Redis password (leave empty if no password) +REDIS_HOST='localhost' # Redis server host (use 'cache' in Docker) +REDIS_PORT='6379' # Redis server port +REDIS_DB='0' # Redis database number (0-15) +REDIS_PASSWORD='' # 🔀 Redis password (leave empty if no password) # Superuser details SUPERUSER_EMAIL='your-email@example.com' # 🔀 From d98d002144aad5ee5441937175d431989f1f84ec Mon Sep 17 00:00:00 2001 From: Simon van Lierde Date: Fri, 7 Nov 2025 16:53:55 +0000 Subject: [PATCH 30/71] feature(backend): Use custom fork of fastapi-mail and pass redis client directly to email checker instead of creating double Redis connection --- .../app/api/auth/utils/email_validation.py | 6 +- backend/pyproject.toml | 4 +- backend/uv.lock | 1950 +++++++++-------- 3 files changed, 1027 insertions(+), 933 deletions(-) diff --git a/backend/app/api/auth/utils/email_validation.py b/backend/app/api/auth/utils/email_validation.py index ac2c6de..79e908b 100644 --- a/backend/app/api/auth/utils/email_validation.py +++ b/backend/app/api/auth/utils/email_validation.py @@ -34,7 +34,11 @@ async def initialize(self) -> None: Should be called during application startup. """ try: - self.checker = DefaultChecker(db_provider="redis", source=DISPOSABLE_DOMAINS_URL) + self.checker = DefaultChecker( + source=DISPOSABLE_DOMAINS_URL, + db_provider="redis", + redis_client=self.redis_client, + ) await self.checker.init_redis() logger.info("Disposable email checker initialized successfully") diff --git a/backend/pyproject.toml b/backend/pyproject.toml index fd4f4c1..cd97213 100644 --- a/backend/pyproject.toml +++ b/backend/pyproject.toml @@ -27,7 +27,7 @@ "cachetools>=5.5.2", "email-validator>=2.2.0", "fastapi-filter>=2.0.1", - "fastapi-mail==1.5.2", + "fastapi-mail", "fastapi-pagination>=0.13.2", # NOTE: This is a heavy dependency (~40MB) due to its use of boto3, even though we don't use any cloud storage # We should consider using a more lightweight alternative if it becomes available. @@ -249,5 +249,7 @@ default-groups = ["api", "dev", "migrations", "tests"] [tool.uv.sources] + # HACK: Fetch FastAPI-Mail from custom fork on GitHub to allow passing existing Redis client and fix compatibility issues with Pydantic > 2.12 and SQLModel (see https://github.com/fastapi/sqlmodel/issues/1623) + fastapi-mail = { git = "https://github.com/simonvanlierde/fastapi-mail", rev = "f32147ec1a450ed22262913c5ac7ec3b67dd0117" } # Fetch FastAPI-Users-DB-SQLModel from custom fork on GitHub for Pydantic V2 support fastapi-users-db-sqlmodel = { git = "https://github.com/simonvanlierde/fastapi-users-db-sqlmodel", rev = "7e9c4830e53ee20c38e3de80066cb19d7c3efc43" } diff --git a/backend/uv.lock b/backend/uv.lock index 44bede3..cfb072d 100644 --- a/backend/uv.lock +++ b/backend/uv.lock @@ -1,5 +1,5 @@ version = 1 -revision = 3 +revision = 1 requires-python = ">=3.13" resolution-markers = [ "python_full_version >= '3.14'", @@ -8,25 +8,25 @@ resolution-markers = [ [[package]] name = "aiosmtplib" -version = "3.0.2" +version = "4.0.2" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/91/2a/812517f8350cd317aad2ba1ce25dfc213c6f1f2e62e1cbf662b4bdc51d34/aiosmtplib-3.0.2.tar.gz", hash = "sha256:08fd840f9dbc23258025dca229e8a8f04d2ccf3ecb1319585615bfc7933f7f47", size = 59941, upload-time = "2024-07-31T05:13:10.065Z" } +sdist = { url = "https://files.pythonhosted.org/packages/0f/e1/cc58e0be242f0b410707e001ed22c689435964fcaab42108887426e44fff/aiosmtplib-4.0.2.tar.gz", hash = "sha256:f0b4933e7270a8be2b588761e5b12b7334c11890ee91987c2fb057e72f566da6", size = 61052 } wheels = [ - { url = "https://files.pythonhosted.org/packages/87/35/441faea7a11159795881a6ec869454f40269e4e3806dced935a35d83a412/aiosmtplib-3.0.2-py3-none-any.whl", hash = "sha256:8783059603a34834c7c90ca51103c3aa129d5922003b5ce98dbaa6d4440f10fc", size = 27111, upload-time = "2024-07-31T05:13:08.515Z" }, + { url = "https://files.pythonhosted.org/packages/f1/2f/db9414bbeacee48ab0c7421a0319b361b7c15b5c3feebcd38684f5d5f849/aiosmtplib-4.0.2-py3-none-any.whl", hash = "sha256:72491f96e6de035c28d29870186782eccb2f651db9c5f8a32c9db689327f5742", size = 27048 }, ] [[package]] name = "alembic" -version = "1.17.0" +version = "1.17.1" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "mako" }, { name = "sqlalchemy" }, { name = "typing-extensions" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/6b/45/6f4555f2039f364c3ce31399529dcf48dd60726ff3715ad67f547d87dfd2/alembic-1.17.0.tar.gz", hash = "sha256:4652a0b3e19616b57d652b82bfa5e38bf5dbea0813eed971612671cb9e90c0fe", size = 1975526, upload-time = "2025-10-11T18:40:13.585Z" } +sdist = { url = "https://files.pythonhosted.org/packages/6e/b6/2a81d7724c0c124edc5ec7a167e85858b6fd31b9611c6fb8ecf617b7e2d3/alembic-1.17.1.tar.gz", hash = "sha256:8a289f6778262df31571d29cca4c7fbacd2f0f582ea0816f4c399b6da7528486", size = 1981285 } wheels = [ - { url = "https://files.pythonhosted.org/packages/44/1f/38e29b06bfed7818ebba1f84904afdc8153ef7b6c7e0d8f3bc6643f5989c/alembic-1.17.0-py3-none-any.whl", hash = "sha256:80523bc437d41b35c5db7e525ad9d908f79de65c27d6a5a5eab6df348a352d99", size = 247449, upload-time = "2025-10-11T18:40:16.288Z" }, + { url = "https://files.pythonhosted.org/packages/a5/32/7df1d81ec2e50fb661944a35183d87e62d3f6c6d9f8aff64a4f245226d55/alembic-1.17.1-py3-none-any.whl", hash = "sha256:cbc2386e60f89608bb63f30d2d6cc66c7aaed1fe105bd862828600e5ad167023", size = 247848 }, ] [[package]] @@ -37,9 +37,9 @@ dependencies = [ { name = "alembic" }, { name = "click" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/d2/bb/6e5eb52a6695690f91b7f67027f7a498ecb0e307f4f2e7d0ae0f854059f5/alembic-autogen-check-1.1.1.tar.gz", hash = "sha256:cdda293a71b2413e854b07641c6f8291dffca0c5c6d0531b7b457629a30ca9cf", size = 2660, upload-time = "2019-05-10T21:45:02.015Z" } +sdist = { url = "https://files.pythonhosted.org/packages/d2/bb/6e5eb52a6695690f91b7f67027f7a498ecb0e307f4f2e7d0ae0f854059f5/alembic-autogen-check-1.1.1.tar.gz", hash = "sha256:cdda293a71b2413e854b07641c6f8291dffca0c5c6d0531b7b457629a30ca9cf", size = 2660 } wheels = [ - { url = "https://files.pythonhosted.org/packages/24/10/57410287f55b37aff354aa078d66f4a759b753ecb7d5aa1225174e1fd6ee/alembic_autogen_check-1.1.1-py3-none-any.whl", hash = "sha256:331c90b99cc2d1c40e69205dfd5e44b5d9c8f111e4b96244f79b303398740659", size = 3968, upload-time = "2019-05-10T21:45:01.039Z" }, + { url = "https://files.pythonhosted.org/packages/24/10/57410287f55b37aff354aa078d66f4a759b753ecb7d5aa1225174e1fd6ee/alembic_autogen_check-1.1.1-py3-none-any.whl", hash = "sha256:331c90b99cc2d1c40e69205dfd5e44b5d9c8f111e4b96244f79b303398740659", size = 3968 }, ] [[package]] @@ -50,18 +50,27 @@ dependencies = [ { name = "alembic" }, { name = "sqlalchemy" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/58/04/e465cb5c051fb056b7fadda7667b3e1fb4d32d7f19533e3bbff071c73788/alembic_postgresql_enum-1.8.0.tar.gz", hash = "sha256:132cd5fdc4a2a0b6498f3d89ea1c7b2a5ddc3281ddd84edae7259ec4c0a215a0", size = 15858, upload-time = "2025-07-20T12:25:50.626Z" } +sdist = { url = "https://files.pythonhosted.org/packages/58/04/e465cb5c051fb056b7fadda7667b3e1fb4d32d7f19533e3bbff071c73788/alembic_postgresql_enum-1.8.0.tar.gz", hash = "sha256:132cd5fdc4a2a0b6498f3d89ea1c7b2a5ddc3281ddd84edae7259ec4c0a215a0", size = 15858 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/77/80/4e6e841f9a0403b520b8f28650c2cdf5905e25bd4ff403b43daec580fed3/alembic_postgresql_enum-1.8.0-py3-none-any.whl", hash = "sha256:0e62833f8d1aca2c58fa09cae1d4a52472fb32d2dde32b68c84515fffcf401d5", size = 23697 }, +] + +[[package]] +name = "annotated-doc" +version = "0.0.3" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/d7/a6/dc46877b911e40c00d395771ea710d5e77b6de7bacd5fdcd78d70cc5a48f/annotated_doc-0.0.3.tar.gz", hash = "sha256:e18370014c70187422c33e945053ff4c286f453a984eba84d0dbfa0c935adeda", size = 5535 } wheels = [ - { url = "https://files.pythonhosted.org/packages/77/80/4e6e841f9a0403b520b8f28650c2cdf5905e25bd4ff403b43daec580fed3/alembic_postgresql_enum-1.8.0-py3-none-any.whl", hash = "sha256:0e62833f8d1aca2c58fa09cae1d4a52472fb32d2dde32b68c84515fffcf401d5", size = 23697, upload-time = "2025-07-20T12:25:49.048Z" }, + { url = "https://files.pythonhosted.org/packages/02/b7/cf592cb5de5cb3bade3357f8d2cf42bf103bbe39f459824b4939fd212911/annotated_doc-0.0.3-py3-none-any.whl", hash = "sha256:348ec6664a76f1fd3be81f43dffbee4c7e8ce931ba71ec67cc7f4ade7fbbb580", size = 5488 }, ] [[package]] name = "annotated-types" version = "0.7.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/ee/67/531ea369ba64dcff5ec9c3402f9f51bf748cec26dde048a2f973a4eea7f5/annotated_types-0.7.0.tar.gz", hash = "sha256:aff07c09a53a08bc8cfccb9c85b05f1aa9a2a6f23728d790723543408344ce89", size = 16081, upload-time = "2024-05-20T21:33:25.928Z" } +sdist = { url = "https://files.pythonhosted.org/packages/ee/67/531ea369ba64dcff5ec9c3402f9f51bf748cec26dde048a2f973a4eea7f5/annotated_types-0.7.0.tar.gz", hash = "sha256:aff07c09a53a08bc8cfccb9c85b05f1aa9a2a6f23728d790723543408344ce89", size = 16081 } wheels = [ - { url = "https://files.pythonhosted.org/packages/78/b6/6307fbef88d9b5ee7421e68d78a9f162e0da4900bc5f5793f6d3d0e34fb8/annotated_types-0.7.0-py3-none-any.whl", hash = "sha256:1f02e8b43a8fbbc3f3e0d4f0f4bfc8131bcb4eebe8849b8e5c773f3a1c582a53", size = 13643, upload-time = "2024-05-20T21:33:24.1Z" }, + { url = "https://files.pythonhosted.org/packages/78/b6/6307fbef88d9b5ee7421e68d78a9f162e0da4900bc5f5793f6d3d0e34fb8/annotated_types-0.7.0-py3-none-any.whl", hash = "sha256:1f02e8b43a8fbbc3f3e0d4f0f4bfc8131bcb4eebe8849b8e5c773f3a1c582a53", size = 13643 }, ] [[package]] @@ -72,9 +81,9 @@ dependencies = [ { name = "idna" }, { name = "sniffio" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/c6/78/7d432127c41b50bccba979505f272c16cbcadcc33645d5fa3a738110ae75/anyio-4.11.0.tar.gz", hash = "sha256:82a8d0b81e318cc5ce71a5f1f8b5c4e63619620b63141ef8c995fa0db95a57c4", size = 219094, upload-time = "2025-09-23T09:19:12.58Z" } +sdist = { url = "https://files.pythonhosted.org/packages/c6/78/7d432127c41b50bccba979505f272c16cbcadcc33645d5fa3a738110ae75/anyio-4.11.0.tar.gz", hash = "sha256:82a8d0b81e318cc5ce71a5f1f8b5c4e63619620b63141ef8c995fa0db95a57c4", size = 219094 } wheels = [ - { url = "https://files.pythonhosted.org/packages/15/b3/9b1a8074496371342ec1e796a96f99c82c945a339cd81a8e73de28b4cf9e/anyio-4.11.0-py3-none-any.whl", hash = "sha256:0287e96f4d26d4149305414d4e3bc32f0dcd0862365a4bddea19d7a1ec38c4fc", size = 109097, upload-time = "2025-09-23T09:19:10.601Z" }, + { url = "https://files.pythonhosted.org/packages/15/b3/9b1a8074496371342ec1e796a96f99c82c945a339cd81a8e73de28b4cf9e/anyio-4.11.0-py3-none-any.whl", hash = "sha256:0287e96f4d26d4149305414d4e3bc32f0dcd0862365a4bddea19d7a1ec38c4fc", size = 109097 }, ] [[package]] @@ -84,9 +93,9 @@ source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "argon2-cffi-bindings" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/31/fa/57ec2c6d16ecd2ba0cf15f3c7d1c3c2e7b5fcb83555ff56d7ab10888ec8f/argon2_cffi-23.1.0.tar.gz", hash = "sha256:879c3e79a2729ce768ebb7d36d4609e3a78a4ca2ec3a9f12286ca057e3d0db08", size = 42798, upload-time = "2023-08-15T14:13:12.711Z" } +sdist = { url = "https://files.pythonhosted.org/packages/31/fa/57ec2c6d16ecd2ba0cf15f3c7d1c3c2e7b5fcb83555ff56d7ab10888ec8f/argon2_cffi-23.1.0.tar.gz", hash = "sha256:879c3e79a2729ce768ebb7d36d4609e3a78a4ca2ec3a9f12286ca057e3d0db08", size = 42798 } wheels = [ - { url = "https://files.pythonhosted.org/packages/a4/6a/e8a041599e78b6b3752da48000b14c8d1e8a04ded09c88c714ba047f34f5/argon2_cffi-23.1.0-py3-none-any.whl", hash = "sha256:c670642b78ba29641818ab2e68bd4e6a78ba53b7eff7b4c3815ae16abf91c7ea", size = 15124, upload-time = "2023-08-15T14:13:10.752Z" }, + { url = "https://files.pythonhosted.org/packages/a4/6a/e8a041599e78b6b3752da48000b14c8d1e8a04ded09c88c714ba047f34f5/argon2_cffi-23.1.0-py3-none-any.whl", hash = "sha256:c670642b78ba29641818ab2e68bd4e6a78ba53b7eff7b4c3815ae16abf91c7ea", size = 15124 }, ] [[package]] @@ -96,28 +105,28 @@ source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "cffi" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/5c/2d/db8af0df73c1cf454f71b2bbe5e356b8c1f8041c979f505b3d3186e520a9/argon2_cffi_bindings-25.1.0.tar.gz", hash = "sha256:b957f3e6ea4d55d820e40ff76f450952807013d361a65d7f28acc0acbf29229d", size = 1783441, upload-time = "2025-07-30T10:02:05.147Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/60/97/3c0a35f46e52108d4707c44b95cfe2afcafc50800b5450c197454569b776/argon2_cffi_bindings-25.1.0-cp314-cp314t-macosx_10_13_universal2.whl", hash = "sha256:3d3f05610594151994ca9ccb3c771115bdb4daef161976a266f0dd8aa9996b8f", size = 54393, upload-time = "2025-07-30T10:01:40.97Z" }, - { url = "https://files.pythonhosted.org/packages/9d/f4/98bbd6ee89febd4f212696f13c03ca302b8552e7dbf9c8efa11ea4a388c3/argon2_cffi_bindings-25.1.0-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:8b8efee945193e667a396cbc7b4fb7d357297d6234d30a489905d96caabde56b", size = 29328, upload-time = "2025-07-30T10:01:41.916Z" }, - { url = "https://files.pythonhosted.org/packages/43/24/90a01c0ef12ac91a6be05969f29944643bc1e5e461155ae6559befa8f00b/argon2_cffi_bindings-25.1.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:3c6702abc36bf3ccba3f802b799505def420a1b7039862014a65db3205967f5a", size = 31269, upload-time = "2025-07-30T10:01:42.716Z" }, - { url = "https://files.pythonhosted.org/packages/d4/d3/942aa10782b2697eee7af5e12eeff5ebb325ccfb86dd8abda54174e377e4/argon2_cffi_bindings-25.1.0-cp314-cp314t-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:a1c70058c6ab1e352304ac7e3b52554daadacd8d453c1752e547c76e9c99ac44", size = 86558, upload-time = "2025-07-30T10:01:43.943Z" }, - { url = "https://files.pythonhosted.org/packages/0d/82/b484f702fec5536e71836fc2dbc8c5267b3f6e78d2d539b4eaa6f0db8bf8/argon2_cffi_bindings-25.1.0-cp314-cp314t-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:e2fd3bfbff3c5d74fef31a722f729bf93500910db650c925c2d6ef879a7e51cb", size = 92364, upload-time = "2025-07-30T10:01:44.887Z" }, - { url = "https://files.pythonhosted.org/packages/c9/c1/a606ff83b3f1735f3759ad0f2cd9e038a0ad11a3de3b6c673aa41c24bb7b/argon2_cffi_bindings-25.1.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:c4f9665de60b1b0e99bcd6be4f17d90339698ce954cfd8d9cf4f91c995165a92", size = 85637, upload-time = "2025-07-30T10:01:46.225Z" }, - { url = "https://files.pythonhosted.org/packages/44/b4/678503f12aceb0262f84fa201f6027ed77d71c5019ae03b399b97caa2f19/argon2_cffi_bindings-25.1.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:ba92837e4a9aa6a508c8d2d7883ed5a8f6c308c89a4790e1e447a220deb79a85", size = 91934, upload-time = "2025-07-30T10:01:47.203Z" }, - { url = "https://files.pythonhosted.org/packages/f0/c7/f36bd08ef9bd9f0a9cff9428406651f5937ce27b6c5b07b92d41f91ae541/argon2_cffi_bindings-25.1.0-cp314-cp314t-win32.whl", hash = "sha256:84a461d4d84ae1295871329b346a97f68eade8c53b6ed9a7ca2d7467f3c8ff6f", size = 28158, upload-time = "2025-07-30T10:01:48.341Z" }, - { url = "https://files.pythonhosted.org/packages/b3/80/0106a7448abb24a2c467bf7d527fe5413b7fdfa4ad6d6a96a43a62ef3988/argon2_cffi_bindings-25.1.0-cp314-cp314t-win_amd64.whl", hash = "sha256:b55aec3565b65f56455eebc9b9f34130440404f27fe21c3b375bf1ea4d8fbae6", size = 32597, upload-time = "2025-07-30T10:01:49.112Z" }, - { url = "https://files.pythonhosted.org/packages/05/b8/d663c9caea07e9180b2cb662772865230715cbd573ba3b5e81793d580316/argon2_cffi_bindings-25.1.0-cp314-cp314t-win_arm64.whl", hash = "sha256:87c33a52407e4c41f3b70a9c2d3f6056d88b10dad7695be708c5021673f55623", size = 28231, upload-time = "2025-07-30T10:01:49.92Z" }, - { url = "https://files.pythonhosted.org/packages/1d/57/96b8b9f93166147826da5f90376e784a10582dd39a393c99bb62cfcf52f0/argon2_cffi_bindings-25.1.0-cp39-abi3-macosx_10_9_universal2.whl", hash = "sha256:aecba1723ae35330a008418a91ea6cfcedf6d31e5fbaa056a166462ff066d500", size = 54121, upload-time = "2025-07-30T10:01:50.815Z" }, - { url = "https://files.pythonhosted.org/packages/0a/08/a9bebdb2e0e602dde230bdde8021b29f71f7841bd54801bcfd514acb5dcf/argon2_cffi_bindings-25.1.0-cp39-abi3-macosx_10_9_x86_64.whl", hash = "sha256:2630b6240b495dfab90aebe159ff784d08ea999aa4b0d17efa734055a07d2f44", size = 29177, upload-time = "2025-07-30T10:01:51.681Z" }, - { url = "https://files.pythonhosted.org/packages/b6/02/d297943bcacf05e4f2a94ab6f462831dc20158614e5d067c35d4e63b9acb/argon2_cffi_bindings-25.1.0-cp39-abi3-macosx_11_0_arm64.whl", hash = "sha256:7aef0c91e2c0fbca6fc68e7555aa60ef7008a739cbe045541e438373bc54d2b0", size = 31090, upload-time = "2025-07-30T10:01:53.184Z" }, - { url = "https://files.pythonhosted.org/packages/c1/93/44365f3d75053e53893ec6d733e4a5e3147502663554b4d864587c7828a7/argon2_cffi_bindings-25.1.0-cp39-abi3-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:1e021e87faa76ae0d413b619fe2b65ab9a037f24c60a1e6cc43457ae20de6dc6", size = 81246, upload-time = "2025-07-30T10:01:54.145Z" }, - { url = "https://files.pythonhosted.org/packages/09/52/94108adfdd6e2ddf58be64f959a0b9c7d4ef2fa71086c38356d22dc501ea/argon2_cffi_bindings-25.1.0-cp39-abi3-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:d3e924cfc503018a714f94a49a149fdc0b644eaead5d1f089330399134fa028a", size = 87126, upload-time = "2025-07-30T10:01:55.074Z" }, - { url = "https://files.pythonhosted.org/packages/72/70/7a2993a12b0ffa2a9271259b79cc616e2389ed1a4d93842fac5a1f923ffd/argon2_cffi_bindings-25.1.0-cp39-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:c87b72589133f0346a1cb8d5ecca4b933e3c9b64656c9d175270a000e73b288d", size = 80343, upload-time = "2025-07-30T10:01:56.007Z" }, - { url = "https://files.pythonhosted.org/packages/78/9a/4e5157d893ffc712b74dbd868c7f62365618266982b64accab26bab01edc/argon2_cffi_bindings-25.1.0-cp39-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:1db89609c06afa1a214a69a462ea741cf735b29a57530478c06eb81dd403de99", size = 86777, upload-time = "2025-07-30T10:01:56.943Z" }, - { url = "https://files.pythonhosted.org/packages/74/cd/15777dfde1c29d96de7f18edf4cc94c385646852e7c7b0320aa91ccca583/argon2_cffi_bindings-25.1.0-cp39-abi3-win32.whl", hash = "sha256:473bcb5f82924b1becbb637b63303ec8d10e84c8d241119419897a26116515d2", size = 27180, upload-time = "2025-07-30T10:01:57.759Z" }, - { url = "https://files.pythonhosted.org/packages/e2/c6/a759ece8f1829d1f162261226fbfd2c6832b3ff7657384045286d2afa384/argon2_cffi_bindings-25.1.0-cp39-abi3-win_amd64.whl", hash = "sha256:a98cd7d17e9f7ce244c0803cad3c23a7d379c301ba618a5fa76a67d116618b98", size = 31715, upload-time = "2025-07-30T10:01:58.56Z" }, - { url = "https://files.pythonhosted.org/packages/42/b9/f8d6fa329ab25128b7e98fd83a3cb34d9db5b059a9847eddb840a0af45dd/argon2_cffi_bindings-25.1.0-cp39-abi3-win_arm64.whl", hash = "sha256:b0fdbcf513833809c882823f98dc2f931cf659d9a1429616ac3adebb49f5db94", size = 27149, upload-time = "2025-07-30T10:01:59.329Z" }, +sdist = { url = "https://files.pythonhosted.org/packages/5c/2d/db8af0df73c1cf454f71b2bbe5e356b8c1f8041c979f505b3d3186e520a9/argon2_cffi_bindings-25.1.0.tar.gz", hash = "sha256:b957f3e6ea4d55d820e40ff76f450952807013d361a65d7f28acc0acbf29229d", size = 1783441 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/60/97/3c0a35f46e52108d4707c44b95cfe2afcafc50800b5450c197454569b776/argon2_cffi_bindings-25.1.0-cp314-cp314t-macosx_10_13_universal2.whl", hash = "sha256:3d3f05610594151994ca9ccb3c771115bdb4daef161976a266f0dd8aa9996b8f", size = 54393 }, + { url = "https://files.pythonhosted.org/packages/9d/f4/98bbd6ee89febd4f212696f13c03ca302b8552e7dbf9c8efa11ea4a388c3/argon2_cffi_bindings-25.1.0-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:8b8efee945193e667a396cbc7b4fb7d357297d6234d30a489905d96caabde56b", size = 29328 }, + { url = "https://files.pythonhosted.org/packages/43/24/90a01c0ef12ac91a6be05969f29944643bc1e5e461155ae6559befa8f00b/argon2_cffi_bindings-25.1.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:3c6702abc36bf3ccba3f802b799505def420a1b7039862014a65db3205967f5a", size = 31269 }, + { url = "https://files.pythonhosted.org/packages/d4/d3/942aa10782b2697eee7af5e12eeff5ebb325ccfb86dd8abda54174e377e4/argon2_cffi_bindings-25.1.0-cp314-cp314t-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:a1c70058c6ab1e352304ac7e3b52554daadacd8d453c1752e547c76e9c99ac44", size = 86558 }, + { url = "https://files.pythonhosted.org/packages/0d/82/b484f702fec5536e71836fc2dbc8c5267b3f6e78d2d539b4eaa6f0db8bf8/argon2_cffi_bindings-25.1.0-cp314-cp314t-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:e2fd3bfbff3c5d74fef31a722f729bf93500910db650c925c2d6ef879a7e51cb", size = 92364 }, + { url = "https://files.pythonhosted.org/packages/c9/c1/a606ff83b3f1735f3759ad0f2cd9e038a0ad11a3de3b6c673aa41c24bb7b/argon2_cffi_bindings-25.1.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:c4f9665de60b1b0e99bcd6be4f17d90339698ce954cfd8d9cf4f91c995165a92", size = 85637 }, + { url = "https://files.pythonhosted.org/packages/44/b4/678503f12aceb0262f84fa201f6027ed77d71c5019ae03b399b97caa2f19/argon2_cffi_bindings-25.1.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:ba92837e4a9aa6a508c8d2d7883ed5a8f6c308c89a4790e1e447a220deb79a85", size = 91934 }, + { url = "https://files.pythonhosted.org/packages/f0/c7/f36bd08ef9bd9f0a9cff9428406651f5937ce27b6c5b07b92d41f91ae541/argon2_cffi_bindings-25.1.0-cp314-cp314t-win32.whl", hash = "sha256:84a461d4d84ae1295871329b346a97f68eade8c53b6ed9a7ca2d7467f3c8ff6f", size = 28158 }, + { url = "https://files.pythonhosted.org/packages/b3/80/0106a7448abb24a2c467bf7d527fe5413b7fdfa4ad6d6a96a43a62ef3988/argon2_cffi_bindings-25.1.0-cp314-cp314t-win_amd64.whl", hash = "sha256:b55aec3565b65f56455eebc9b9f34130440404f27fe21c3b375bf1ea4d8fbae6", size = 32597 }, + { url = "https://files.pythonhosted.org/packages/05/b8/d663c9caea07e9180b2cb662772865230715cbd573ba3b5e81793d580316/argon2_cffi_bindings-25.1.0-cp314-cp314t-win_arm64.whl", hash = "sha256:87c33a52407e4c41f3b70a9c2d3f6056d88b10dad7695be708c5021673f55623", size = 28231 }, + { url = "https://files.pythonhosted.org/packages/1d/57/96b8b9f93166147826da5f90376e784a10582dd39a393c99bb62cfcf52f0/argon2_cffi_bindings-25.1.0-cp39-abi3-macosx_10_9_universal2.whl", hash = "sha256:aecba1723ae35330a008418a91ea6cfcedf6d31e5fbaa056a166462ff066d500", size = 54121 }, + { url = "https://files.pythonhosted.org/packages/0a/08/a9bebdb2e0e602dde230bdde8021b29f71f7841bd54801bcfd514acb5dcf/argon2_cffi_bindings-25.1.0-cp39-abi3-macosx_10_9_x86_64.whl", hash = "sha256:2630b6240b495dfab90aebe159ff784d08ea999aa4b0d17efa734055a07d2f44", size = 29177 }, + { url = "https://files.pythonhosted.org/packages/b6/02/d297943bcacf05e4f2a94ab6f462831dc20158614e5d067c35d4e63b9acb/argon2_cffi_bindings-25.1.0-cp39-abi3-macosx_11_0_arm64.whl", hash = "sha256:7aef0c91e2c0fbca6fc68e7555aa60ef7008a739cbe045541e438373bc54d2b0", size = 31090 }, + { url = "https://files.pythonhosted.org/packages/c1/93/44365f3d75053e53893ec6d733e4a5e3147502663554b4d864587c7828a7/argon2_cffi_bindings-25.1.0-cp39-abi3-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:1e021e87faa76ae0d413b619fe2b65ab9a037f24c60a1e6cc43457ae20de6dc6", size = 81246 }, + { url = "https://files.pythonhosted.org/packages/09/52/94108adfdd6e2ddf58be64f959a0b9c7d4ef2fa71086c38356d22dc501ea/argon2_cffi_bindings-25.1.0-cp39-abi3-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:d3e924cfc503018a714f94a49a149fdc0b644eaead5d1f089330399134fa028a", size = 87126 }, + { url = "https://files.pythonhosted.org/packages/72/70/7a2993a12b0ffa2a9271259b79cc616e2389ed1a4d93842fac5a1f923ffd/argon2_cffi_bindings-25.1.0-cp39-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:c87b72589133f0346a1cb8d5ecca4b933e3c9b64656c9d175270a000e73b288d", size = 80343 }, + { url = "https://files.pythonhosted.org/packages/78/9a/4e5157d893ffc712b74dbd868c7f62365618266982b64accab26bab01edc/argon2_cffi_bindings-25.1.0-cp39-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:1db89609c06afa1a214a69a462ea741cf735b29a57530478c06eb81dd403de99", size = 86777 }, + { url = "https://files.pythonhosted.org/packages/74/cd/15777dfde1c29d96de7f18edf4cc94c385646852e7c7b0320aa91ccca583/argon2_cffi_bindings-25.1.0-cp39-abi3-win32.whl", hash = "sha256:473bcb5f82924b1becbb637b63303ec8d10e84c8d241119419897a26116515d2", size = 27180 }, + { url = "https://files.pythonhosted.org/packages/e2/c6/a759ece8f1829d1f162261226fbfd2c6832b3ff7657384045286d2afa384/argon2_cffi_bindings-25.1.0-cp39-abi3-win_amd64.whl", hash = "sha256:a98cd7d17e9f7ce244c0803cad3c23a7d379c301ba618a5fa76a67d116618b98", size = 31715 }, + { url = "https://files.pythonhosted.org/packages/42/b9/f8d6fa329ab25128b7e98fd83a3cb34d9db5b059a9847eddb840a0af45dd/argon2_cffi_bindings-25.1.0-cp39-abi3-win_arm64.whl", hash = "sha256:b0fdbcf513833809c882823f98dc2f931cf659d9a1429616ac3adebb49f5db94", size = 27149 }, ] [[package]] @@ -127,75 +136,75 @@ source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "cachetools" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/49/cf/17f8a6b6b97f77b5981fbce1266913e718daaa3467b46f60a785cbaadc29/asyncache-0.3.1.tar.gz", hash = "sha256:9a1e60a75668e794657489bdea6540ee7e3259c483517b934670db7600bf5035", size = 3797, upload-time = "2022-11-15T10:06:47.476Z" } +sdist = { url = "https://files.pythonhosted.org/packages/49/cf/17f8a6b6b97f77b5981fbce1266913e718daaa3467b46f60a785cbaadc29/asyncache-0.3.1.tar.gz", hash = "sha256:9a1e60a75668e794657489bdea6540ee7e3259c483517b934670db7600bf5035", size = 3797 } wheels = [ - { url = "https://files.pythonhosted.org/packages/2f/94/51927deb4f40872361ec4f5534f68f7a9ce81c4ef20bf5cd765307f4c15d/asyncache-0.3.1-py3-none-any.whl", hash = "sha256:ef20a1024d265090dd1e0785c961cf98b9c32cc7d9478973dcf25ac1b80011f5", size = 3722, upload-time = "2022-11-15T10:06:45.546Z" }, + { url = "https://files.pythonhosted.org/packages/2f/94/51927deb4f40872361ec4f5534f68f7a9ce81c4ef20bf5cd765307f4c15d/asyncache-0.3.1-py3-none-any.whl", hash = "sha256:ef20a1024d265090dd1e0785c961cf98b9c32cc7d9478973dcf25ac1b80011f5", size = 3722 }, ] [[package]] name = "asyncpg" version = "0.30.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/2f/4c/7c991e080e106d854809030d8584e15b2e996e26f16aee6d757e387bc17d/asyncpg-0.30.0.tar.gz", hash = "sha256:c551e9928ab6707602f44811817f82ba3c446e018bfe1d3abecc8ba5f3eac851", size = 957746, upload-time = "2024-10-20T00:30:41.127Z" } +sdist = { url = "https://files.pythonhosted.org/packages/2f/4c/7c991e080e106d854809030d8584e15b2e996e26f16aee6d757e387bc17d/asyncpg-0.30.0.tar.gz", hash = "sha256:c551e9928ab6707602f44811817f82ba3c446e018bfe1d3abecc8ba5f3eac851", size = 957746 } wheels = [ - { url = "https://files.pythonhosted.org/packages/3a/22/e20602e1218dc07692acf70d5b902be820168d6282e69ef0d3cb920dc36f/asyncpg-0.30.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:05b185ebb8083c8568ea8a40e896d5f7af4b8554b64d7719c0eaa1eb5a5c3a70", size = 670373, upload-time = "2024-10-20T00:29:55.165Z" }, - { url = "https://files.pythonhosted.org/packages/3d/b3/0cf269a9d647852a95c06eb00b815d0b95a4eb4b55aa2d6ba680971733b9/asyncpg-0.30.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:c47806b1a8cbb0a0db896f4cd34d89942effe353a5035c62734ab13b9f938da3", size = 634745, upload-time = "2024-10-20T00:29:57.14Z" }, - { url = "https://files.pythonhosted.org/packages/8e/6d/a4f31bf358ce8491d2a31bfe0d7bcf25269e80481e49de4d8616c4295a34/asyncpg-0.30.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9b6fde867a74e8c76c71e2f64f80c64c0f3163e687f1763cfaf21633ec24ec33", size = 3512103, upload-time = "2024-10-20T00:29:58.499Z" }, - { url = "https://files.pythonhosted.org/packages/96/19/139227a6e67f407b9c386cb594d9628c6c78c9024f26df87c912fabd4368/asyncpg-0.30.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:46973045b567972128a27d40001124fbc821c87a6cade040cfcd4fa8a30bcdc4", size = 3592471, upload-time = "2024-10-20T00:30:00.354Z" }, - { url = "https://files.pythonhosted.org/packages/67/e4/ab3ca38f628f53f0fd28d3ff20edff1c975dd1cb22482e0061916b4b9a74/asyncpg-0.30.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:9110df111cabc2ed81aad2f35394a00cadf4f2e0635603db6ebbd0fc896f46a4", size = 3496253, upload-time = "2024-10-20T00:30:02.794Z" }, - { url = "https://files.pythonhosted.org/packages/ef/5f/0bf65511d4eeac3a1f41c54034a492515a707c6edbc642174ae79034d3ba/asyncpg-0.30.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:04ff0785ae7eed6cc138e73fc67b8e51d54ee7a3ce9b63666ce55a0bf095f7ba", size = 3662720, upload-time = "2024-10-20T00:30:04.501Z" }, - { url = "https://files.pythonhosted.org/packages/e7/31/1513d5a6412b98052c3ed9158d783b1e09d0910f51fbe0e05f56cc370bc4/asyncpg-0.30.0-cp313-cp313-win32.whl", hash = "sha256:ae374585f51c2b444510cdf3595b97ece4f233fde739aa14b50e0d64e8a7a590", size = 560404, upload-time = "2024-10-20T00:30:06.537Z" }, - { url = "https://files.pythonhosted.org/packages/c8/a4/cec76b3389c4c5ff66301cd100fe88c318563ec8a520e0b2e792b5b84972/asyncpg-0.30.0-cp313-cp313-win_amd64.whl", hash = "sha256:f59b430b8e27557c3fb9869222559f7417ced18688375825f8f12302c34e915e", size = 621623, upload-time = "2024-10-20T00:30:09.024Z" }, + { url = "https://files.pythonhosted.org/packages/3a/22/e20602e1218dc07692acf70d5b902be820168d6282e69ef0d3cb920dc36f/asyncpg-0.30.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:05b185ebb8083c8568ea8a40e896d5f7af4b8554b64d7719c0eaa1eb5a5c3a70", size = 670373 }, + { url = "https://files.pythonhosted.org/packages/3d/b3/0cf269a9d647852a95c06eb00b815d0b95a4eb4b55aa2d6ba680971733b9/asyncpg-0.30.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:c47806b1a8cbb0a0db896f4cd34d89942effe353a5035c62734ab13b9f938da3", size = 634745 }, + { url = "https://files.pythonhosted.org/packages/8e/6d/a4f31bf358ce8491d2a31bfe0d7bcf25269e80481e49de4d8616c4295a34/asyncpg-0.30.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9b6fde867a74e8c76c71e2f64f80c64c0f3163e687f1763cfaf21633ec24ec33", size = 3512103 }, + { url = "https://files.pythonhosted.org/packages/96/19/139227a6e67f407b9c386cb594d9628c6c78c9024f26df87c912fabd4368/asyncpg-0.30.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:46973045b567972128a27d40001124fbc821c87a6cade040cfcd4fa8a30bcdc4", size = 3592471 }, + { url = "https://files.pythonhosted.org/packages/67/e4/ab3ca38f628f53f0fd28d3ff20edff1c975dd1cb22482e0061916b4b9a74/asyncpg-0.30.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:9110df111cabc2ed81aad2f35394a00cadf4f2e0635603db6ebbd0fc896f46a4", size = 3496253 }, + { url = "https://files.pythonhosted.org/packages/ef/5f/0bf65511d4eeac3a1f41c54034a492515a707c6edbc642174ae79034d3ba/asyncpg-0.30.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:04ff0785ae7eed6cc138e73fc67b8e51d54ee7a3ce9b63666ce55a0bf095f7ba", size = 3662720 }, + { url = "https://files.pythonhosted.org/packages/e7/31/1513d5a6412b98052c3ed9158d783b1e09d0910f51fbe0e05f56cc370bc4/asyncpg-0.30.0-cp313-cp313-win32.whl", hash = "sha256:ae374585f51c2b444510cdf3595b97ece4f233fde739aa14b50e0d64e8a7a590", size = 560404 }, + { url = "https://files.pythonhosted.org/packages/c8/a4/cec76b3389c4c5ff66301cd100fe88c318563ec8a520e0b2e792b5b84972/asyncpg-0.30.0-cp313-cp313-win_amd64.whl", hash = "sha256:f59b430b8e27557c3fb9869222559f7417ced18688375825f8f12302c34e915e", size = 621623 }, ] [[package]] name = "bcrypt" version = "4.3.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/bb/5d/6d7433e0f3cd46ce0b43cd65e1db465ea024dbb8216fb2404e919c2ad77b/bcrypt-4.3.0.tar.gz", hash = "sha256:3a3fd2204178b6d2adcf09cb4f6426ffef54762577a7c9b54c159008cb288c18", size = 25697, upload-time = "2025-02-28T01:24:09.174Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/bf/2c/3d44e853d1fe969d229bd58d39ae6902b3d924af0e2b5a60d17d4b809ded/bcrypt-4.3.0-cp313-cp313t-macosx_10_12_universal2.whl", hash = "sha256:f01e060f14b6b57bbb72fc5b4a83ac21c443c9a2ee708e04a10e9192f90a6281", size = 483719, upload-time = "2025-02-28T01:22:34.539Z" }, - { url = "https://files.pythonhosted.org/packages/a1/e2/58ff6e2a22eca2e2cff5370ae56dba29d70b1ea6fc08ee9115c3ae367795/bcrypt-4.3.0-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c5eeac541cefd0bb887a371ef73c62c3cd78535e4887b310626036a7c0a817bb", size = 272001, upload-time = "2025-02-28T01:22:38.078Z" }, - { url = "https://files.pythonhosted.org/packages/37/1f/c55ed8dbe994b1d088309e366749633c9eb90d139af3c0a50c102ba68a1a/bcrypt-4.3.0-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:59e1aa0e2cd871b08ca146ed08445038f42ff75968c7ae50d2fdd7860ade2180", size = 277451, upload-time = "2025-02-28T01:22:40.787Z" }, - { url = "https://files.pythonhosted.org/packages/d7/1c/794feb2ecf22fe73dcfb697ea7057f632061faceb7dcf0f155f3443b4d79/bcrypt-4.3.0-cp313-cp313t-manylinux_2_28_aarch64.whl", hash = "sha256:0042b2e342e9ae3d2ed22727c1262f76cc4f345683b5c1715f0250cf4277294f", size = 272792, upload-time = "2025-02-28T01:22:43.144Z" }, - { url = "https://files.pythonhosted.org/packages/13/b7/0b289506a3f3598c2ae2bdfa0ea66969812ed200264e3f61df77753eee6d/bcrypt-4.3.0-cp313-cp313t-manylinux_2_28_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:74a8d21a09f5e025a9a23e7c0fd2c7fe8e7503e4d356c0a2c1486ba010619f09", size = 289752, upload-time = "2025-02-28T01:22:45.56Z" }, - { url = "https://files.pythonhosted.org/packages/dc/24/d0fb023788afe9e83cc118895a9f6c57e1044e7e1672f045e46733421fe6/bcrypt-4.3.0-cp313-cp313t-manylinux_2_28_x86_64.whl", hash = "sha256:0142b2cb84a009f8452c8c5a33ace5e3dfec4159e7735f5afe9a4d50a8ea722d", size = 277762, upload-time = "2025-02-28T01:22:47.023Z" }, - { url = "https://files.pythonhosted.org/packages/e4/38/cde58089492e55ac4ef6c49fea7027600c84fd23f7520c62118c03b4625e/bcrypt-4.3.0-cp313-cp313t-manylinux_2_34_aarch64.whl", hash = "sha256:12fa6ce40cde3f0b899729dbd7d5e8811cb892d31b6f7d0334a1f37748b789fd", size = 272384, upload-time = "2025-02-28T01:22:49.221Z" }, - { url = "https://files.pythonhosted.org/packages/de/6a/d5026520843490cfc8135d03012a413e4532a400e471e6188b01b2de853f/bcrypt-4.3.0-cp313-cp313t-manylinux_2_34_x86_64.whl", hash = "sha256:5bd3cca1f2aa5dbcf39e2aa13dd094ea181f48959e1071265de49cc2b82525af", size = 277329, upload-time = "2025-02-28T01:22:51.603Z" }, - { url = "https://files.pythonhosted.org/packages/b3/a3/4fc5255e60486466c389e28c12579d2829b28a527360e9430b4041df4cf9/bcrypt-4.3.0-cp313-cp313t-musllinux_1_1_aarch64.whl", hash = "sha256:335a420cfd63fc5bc27308e929bee231c15c85cc4c496610ffb17923abf7f231", size = 305241, upload-time = "2025-02-28T01:22:53.283Z" }, - { url = "https://files.pythonhosted.org/packages/c7/15/2b37bc07d6ce27cc94e5b10fd5058900eb8fb11642300e932c8c82e25c4a/bcrypt-4.3.0-cp313-cp313t-musllinux_1_1_x86_64.whl", hash = "sha256:0e30e5e67aed0187a1764911af023043b4542e70a7461ad20e837e94d23e1d6c", size = 309617, upload-time = "2025-02-28T01:22:55.461Z" }, - { url = "https://files.pythonhosted.org/packages/5f/1f/99f65edb09e6c935232ba0430c8c13bb98cb3194b6d636e61d93fe60ac59/bcrypt-4.3.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:3b8d62290ebefd49ee0b3ce7500f5dbdcf13b81402c05f6dafab9a1e1b27212f", size = 335751, upload-time = "2025-02-28T01:22:57.81Z" }, - { url = "https://files.pythonhosted.org/packages/00/1b/b324030c706711c99769988fcb694b3cb23f247ad39a7823a78e361bdbb8/bcrypt-4.3.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:2ef6630e0ec01376f59a006dc72918b1bf436c3b571b80fa1968d775fa02fe7d", size = 355965, upload-time = "2025-02-28T01:22:59.181Z" }, - { url = "https://files.pythonhosted.org/packages/aa/dd/20372a0579dd915dfc3b1cd4943b3bca431866fcb1dfdfd7518c3caddea6/bcrypt-4.3.0-cp313-cp313t-win32.whl", hash = "sha256:7a4be4cbf241afee43f1c3969b9103a41b40bcb3a3f467ab19f891d9bc4642e4", size = 155316, upload-time = "2025-02-28T01:23:00.763Z" }, - { url = "https://files.pythonhosted.org/packages/6d/52/45d969fcff6b5577c2bf17098dc36269b4c02197d551371c023130c0f890/bcrypt-4.3.0-cp313-cp313t-win_amd64.whl", hash = "sha256:5c1949bf259a388863ced887c7861da1df681cb2388645766c89fdfd9004c669", size = 147752, upload-time = "2025-02-28T01:23:02.908Z" }, - { url = "https://files.pythonhosted.org/packages/11/22/5ada0b9af72b60cbc4c9a399fdde4af0feaa609d27eb0adc61607997a3fa/bcrypt-4.3.0-cp38-abi3-macosx_10_12_universal2.whl", hash = "sha256:f81b0ed2639568bf14749112298f9e4e2b28853dab50a8b357e31798686a036d", size = 498019, upload-time = "2025-02-28T01:23:05.838Z" }, - { url = "https://files.pythonhosted.org/packages/b8/8c/252a1edc598dc1ce57905be173328eda073083826955ee3c97c7ff5ba584/bcrypt-4.3.0-cp38-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:864f8f19adbe13b7de11ba15d85d4a428c7e2f344bac110f667676a0ff84924b", size = 279174, upload-time = "2025-02-28T01:23:07.274Z" }, - { url = "https://files.pythonhosted.org/packages/29/5b/4547d5c49b85f0337c13929f2ccbe08b7283069eea3550a457914fc078aa/bcrypt-4.3.0-cp38-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3e36506d001e93bffe59754397572f21bb5dc7c83f54454c990c74a468cd589e", size = 283870, upload-time = "2025-02-28T01:23:09.151Z" }, - { url = "https://files.pythonhosted.org/packages/be/21/7dbaf3fa1745cb63f776bb046e481fbababd7d344c5324eab47f5ca92dd2/bcrypt-4.3.0-cp38-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:842d08d75d9fe9fb94b18b071090220697f9f184d4547179b60734846461ed59", size = 279601, upload-time = "2025-02-28T01:23:11.461Z" }, - { url = "https://files.pythonhosted.org/packages/6d/64/e042fc8262e971347d9230d9abbe70d68b0a549acd8611c83cebd3eaec67/bcrypt-4.3.0-cp38-abi3-manylinux_2_28_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:7c03296b85cb87db865d91da79bf63d5609284fc0cab9472fdd8367bbd830753", size = 297660, upload-time = "2025-02-28T01:23:12.989Z" }, - { url = "https://files.pythonhosted.org/packages/50/b8/6294eb84a3fef3b67c69b4470fcdd5326676806bf2519cda79331ab3c3a9/bcrypt-4.3.0-cp38-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:62f26585e8b219cdc909b6a0069efc5e4267e25d4a3770a364ac58024f62a761", size = 284083, upload-time = "2025-02-28T01:23:14.5Z" }, - { url = "https://files.pythonhosted.org/packages/62/e6/baff635a4f2c42e8788fe1b1633911c38551ecca9a749d1052d296329da6/bcrypt-4.3.0-cp38-abi3-manylinux_2_34_aarch64.whl", hash = "sha256:beeefe437218a65322fbd0069eb437e7c98137e08f22c4660ac2dc795c31f8bb", size = 279237, upload-time = "2025-02-28T01:23:16.686Z" }, - { url = "https://files.pythonhosted.org/packages/39/48/46f623f1b0c7dc2e5de0b8af5e6f5ac4cc26408ac33f3d424e5ad8da4a90/bcrypt-4.3.0-cp38-abi3-manylinux_2_34_x86_64.whl", hash = "sha256:97eea7408db3a5bcce4a55d13245ab3fa566e23b4c67cd227062bb49e26c585d", size = 283737, upload-time = "2025-02-28T01:23:18.897Z" }, - { url = "https://files.pythonhosted.org/packages/49/8b/70671c3ce9c0fca4a6cc3cc6ccbaa7e948875a2e62cbd146e04a4011899c/bcrypt-4.3.0-cp38-abi3-musllinux_1_1_aarch64.whl", hash = "sha256:191354ebfe305e84f344c5964c7cd5f924a3bfc5d405c75ad07f232b6dffb49f", size = 312741, upload-time = "2025-02-28T01:23:21.041Z" }, - { url = "https://files.pythonhosted.org/packages/27/fb/910d3a1caa2d249b6040a5caf9f9866c52114d51523ac2fb47578a27faee/bcrypt-4.3.0-cp38-abi3-musllinux_1_1_x86_64.whl", hash = "sha256:41261d64150858eeb5ff43c753c4b216991e0ae16614a308a15d909503617732", size = 316472, upload-time = "2025-02-28T01:23:23.183Z" }, - { url = "https://files.pythonhosted.org/packages/dc/cf/7cf3a05b66ce466cfb575dbbda39718d45a609daa78500f57fa9f36fa3c0/bcrypt-4.3.0-cp38-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:33752b1ba962ee793fa2b6321404bf20011fe45b9afd2a842139de3011898fef", size = 343606, upload-time = "2025-02-28T01:23:25.361Z" }, - { url = "https://files.pythonhosted.org/packages/e3/b8/e970ecc6d7e355c0d892b7f733480f4aa8509f99b33e71550242cf0b7e63/bcrypt-4.3.0-cp38-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:50e6e80a4bfd23a25f5c05b90167c19030cf9f87930f7cb2eacb99f45d1c3304", size = 362867, upload-time = "2025-02-28T01:23:26.875Z" }, - { url = "https://files.pythonhosted.org/packages/a9/97/8d3118efd8354c555a3422d544163f40d9f236be5b96c714086463f11699/bcrypt-4.3.0-cp38-abi3-win32.whl", hash = "sha256:67a561c4d9fb9465ec866177e7aebcad08fe23aaf6fbd692a6fab69088abfc51", size = 160589, upload-time = "2025-02-28T01:23:28.381Z" }, - { url = "https://files.pythonhosted.org/packages/29/07/416f0b99f7f3997c69815365babbc2e8754181a4b1899d921b3c7d5b6f12/bcrypt-4.3.0-cp38-abi3-win_amd64.whl", hash = "sha256:584027857bc2843772114717a7490a37f68da563b3620f78a849bcb54dc11e62", size = 152794, upload-time = "2025-02-28T01:23:30.187Z" }, - { url = "https://files.pythonhosted.org/packages/6e/c1/3fa0e9e4e0bfd3fd77eb8b52ec198fd6e1fd7e9402052e43f23483f956dd/bcrypt-4.3.0-cp39-abi3-macosx_10_12_universal2.whl", hash = "sha256:0d3efb1157edebfd9128e4e46e2ac1a64e0c1fe46fb023158a407c7892b0f8c3", size = 498969, upload-time = "2025-02-28T01:23:31.945Z" }, - { url = "https://files.pythonhosted.org/packages/ce/d4/755ce19b6743394787fbd7dff6bf271b27ee9b5912a97242e3caf125885b/bcrypt-4.3.0-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:08bacc884fd302b611226c01014eca277d48f0a05187666bca23aac0dad6fe24", size = 279158, upload-time = "2025-02-28T01:23:34.161Z" }, - { url = "https://files.pythonhosted.org/packages/9b/5d/805ef1a749c965c46b28285dfb5cd272a7ed9fa971f970435a5133250182/bcrypt-4.3.0-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f6746e6fec103fcd509b96bacdfdaa2fbde9a553245dbada284435173a6f1aef", size = 284285, upload-time = "2025-02-28T01:23:35.765Z" }, - { url = "https://files.pythonhosted.org/packages/ab/2b/698580547a4a4988e415721b71eb45e80c879f0fb04a62da131f45987b96/bcrypt-4.3.0-cp39-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:afe327968aaf13fc143a56a3360cb27d4ad0345e34da12c7290f1b00b8fe9a8b", size = 279583, upload-time = "2025-02-28T01:23:38.021Z" }, - { url = "https://files.pythonhosted.org/packages/f2/87/62e1e426418204db520f955ffd06f1efd389feca893dad7095bf35612eec/bcrypt-4.3.0-cp39-abi3-manylinux_2_28_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:d9af79d322e735b1fc33404b5765108ae0ff232d4b54666d46730f8ac1a43676", size = 297896, upload-time = "2025-02-28T01:23:39.575Z" }, - { url = "https://files.pythonhosted.org/packages/cb/c6/8fedca4c2ada1b6e889c52d2943b2f968d3427e5d65f595620ec4c06fa2f/bcrypt-4.3.0-cp39-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:f1e3ffa1365e8702dc48c8b360fef8d7afeca482809c5e45e653af82ccd088c1", size = 284492, upload-time = "2025-02-28T01:23:40.901Z" }, - { url = "https://files.pythonhosted.org/packages/4d/4d/c43332dcaaddb7710a8ff5269fcccba97ed3c85987ddaa808db084267b9a/bcrypt-4.3.0-cp39-abi3-manylinux_2_34_aarch64.whl", hash = "sha256:3004df1b323d10021fda07a813fd33e0fd57bef0e9a480bb143877f6cba996fe", size = 279213, upload-time = "2025-02-28T01:23:42.653Z" }, - { url = "https://files.pythonhosted.org/packages/dc/7f/1e36379e169a7df3a14a1c160a49b7b918600a6008de43ff20d479e6f4b5/bcrypt-4.3.0-cp39-abi3-manylinux_2_34_x86_64.whl", hash = "sha256:531457e5c839d8caea9b589a1bcfe3756b0547d7814e9ce3d437f17da75c32b0", size = 284162, upload-time = "2025-02-28T01:23:43.964Z" }, - { url = "https://files.pythonhosted.org/packages/1c/0a/644b2731194b0d7646f3210dc4d80c7fee3ecb3a1f791a6e0ae6bb8684e3/bcrypt-4.3.0-cp39-abi3-musllinux_1_1_aarch64.whl", hash = "sha256:17a854d9a7a476a89dcef6c8bd119ad23e0f82557afbd2c442777a16408e614f", size = 312856, upload-time = "2025-02-28T01:23:46.011Z" }, - { url = "https://files.pythonhosted.org/packages/dc/62/2a871837c0bb6ab0c9a88bf54de0fc021a6a08832d4ea313ed92a669d437/bcrypt-4.3.0-cp39-abi3-musllinux_1_1_x86_64.whl", hash = "sha256:6fb1fd3ab08c0cbc6826a2e0447610c6f09e983a281b919ed721ad32236b8b23", size = 316726, upload-time = "2025-02-28T01:23:47.575Z" }, - { url = "https://files.pythonhosted.org/packages/0c/a1/9898ea3faac0b156d457fd73a3cb9c2855c6fd063e44b8522925cdd8ce46/bcrypt-4.3.0-cp39-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:e965a9c1e9a393b8005031ff52583cedc15b7884fce7deb8b0346388837d6cfe", size = 343664, upload-time = "2025-02-28T01:23:49.059Z" }, - { url = "https://files.pythonhosted.org/packages/40/f2/71b4ed65ce38982ecdda0ff20c3ad1b15e71949c78b2c053df53629ce940/bcrypt-4.3.0-cp39-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:79e70b8342a33b52b55d93b3a59223a844962bef479f6a0ea318ebbcadf71505", size = 363128, upload-time = "2025-02-28T01:23:50.399Z" }, - { url = "https://files.pythonhosted.org/packages/11/99/12f6a58eca6dea4be992d6c681b7ec9410a1d9f5cf368c61437e31daa879/bcrypt-4.3.0-cp39-abi3-win32.whl", hash = "sha256:b4d4e57f0a63fd0b358eb765063ff661328f69a04494427265950c71b992a39a", size = 160598, upload-time = "2025-02-28T01:23:51.775Z" }, - { url = "https://files.pythonhosted.org/packages/a9/cf/45fb5261ece3e6b9817d3d82b2f343a505fd58674a92577923bc500bd1aa/bcrypt-4.3.0-cp39-abi3-win_amd64.whl", hash = "sha256:e53e074b120f2877a35cc6c736b8eb161377caae8925c17688bd46ba56daaa5b", size = 152799, upload-time = "2025-02-28T01:23:53.139Z" }, +sdist = { url = "https://files.pythonhosted.org/packages/bb/5d/6d7433e0f3cd46ce0b43cd65e1db465ea024dbb8216fb2404e919c2ad77b/bcrypt-4.3.0.tar.gz", hash = "sha256:3a3fd2204178b6d2adcf09cb4f6426ffef54762577a7c9b54c159008cb288c18", size = 25697 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/bf/2c/3d44e853d1fe969d229bd58d39ae6902b3d924af0e2b5a60d17d4b809ded/bcrypt-4.3.0-cp313-cp313t-macosx_10_12_universal2.whl", hash = "sha256:f01e060f14b6b57bbb72fc5b4a83ac21c443c9a2ee708e04a10e9192f90a6281", size = 483719 }, + { url = "https://files.pythonhosted.org/packages/a1/e2/58ff6e2a22eca2e2cff5370ae56dba29d70b1ea6fc08ee9115c3ae367795/bcrypt-4.3.0-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c5eeac541cefd0bb887a371ef73c62c3cd78535e4887b310626036a7c0a817bb", size = 272001 }, + { url = "https://files.pythonhosted.org/packages/37/1f/c55ed8dbe994b1d088309e366749633c9eb90d139af3c0a50c102ba68a1a/bcrypt-4.3.0-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:59e1aa0e2cd871b08ca146ed08445038f42ff75968c7ae50d2fdd7860ade2180", size = 277451 }, + { url = "https://files.pythonhosted.org/packages/d7/1c/794feb2ecf22fe73dcfb697ea7057f632061faceb7dcf0f155f3443b4d79/bcrypt-4.3.0-cp313-cp313t-manylinux_2_28_aarch64.whl", hash = "sha256:0042b2e342e9ae3d2ed22727c1262f76cc4f345683b5c1715f0250cf4277294f", size = 272792 }, + { url = "https://files.pythonhosted.org/packages/13/b7/0b289506a3f3598c2ae2bdfa0ea66969812ed200264e3f61df77753eee6d/bcrypt-4.3.0-cp313-cp313t-manylinux_2_28_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:74a8d21a09f5e025a9a23e7c0fd2c7fe8e7503e4d356c0a2c1486ba010619f09", size = 289752 }, + { url = "https://files.pythonhosted.org/packages/dc/24/d0fb023788afe9e83cc118895a9f6c57e1044e7e1672f045e46733421fe6/bcrypt-4.3.0-cp313-cp313t-manylinux_2_28_x86_64.whl", hash = "sha256:0142b2cb84a009f8452c8c5a33ace5e3dfec4159e7735f5afe9a4d50a8ea722d", size = 277762 }, + { url = "https://files.pythonhosted.org/packages/e4/38/cde58089492e55ac4ef6c49fea7027600c84fd23f7520c62118c03b4625e/bcrypt-4.3.0-cp313-cp313t-manylinux_2_34_aarch64.whl", hash = "sha256:12fa6ce40cde3f0b899729dbd7d5e8811cb892d31b6f7d0334a1f37748b789fd", size = 272384 }, + { url = "https://files.pythonhosted.org/packages/de/6a/d5026520843490cfc8135d03012a413e4532a400e471e6188b01b2de853f/bcrypt-4.3.0-cp313-cp313t-manylinux_2_34_x86_64.whl", hash = "sha256:5bd3cca1f2aa5dbcf39e2aa13dd094ea181f48959e1071265de49cc2b82525af", size = 277329 }, + { url = "https://files.pythonhosted.org/packages/b3/a3/4fc5255e60486466c389e28c12579d2829b28a527360e9430b4041df4cf9/bcrypt-4.3.0-cp313-cp313t-musllinux_1_1_aarch64.whl", hash = "sha256:335a420cfd63fc5bc27308e929bee231c15c85cc4c496610ffb17923abf7f231", size = 305241 }, + { url = "https://files.pythonhosted.org/packages/c7/15/2b37bc07d6ce27cc94e5b10fd5058900eb8fb11642300e932c8c82e25c4a/bcrypt-4.3.0-cp313-cp313t-musllinux_1_1_x86_64.whl", hash = "sha256:0e30e5e67aed0187a1764911af023043b4542e70a7461ad20e837e94d23e1d6c", size = 309617 }, + { url = "https://files.pythonhosted.org/packages/5f/1f/99f65edb09e6c935232ba0430c8c13bb98cb3194b6d636e61d93fe60ac59/bcrypt-4.3.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:3b8d62290ebefd49ee0b3ce7500f5dbdcf13b81402c05f6dafab9a1e1b27212f", size = 335751 }, + { url = "https://files.pythonhosted.org/packages/00/1b/b324030c706711c99769988fcb694b3cb23f247ad39a7823a78e361bdbb8/bcrypt-4.3.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:2ef6630e0ec01376f59a006dc72918b1bf436c3b571b80fa1968d775fa02fe7d", size = 355965 }, + { url = "https://files.pythonhosted.org/packages/aa/dd/20372a0579dd915dfc3b1cd4943b3bca431866fcb1dfdfd7518c3caddea6/bcrypt-4.3.0-cp313-cp313t-win32.whl", hash = "sha256:7a4be4cbf241afee43f1c3969b9103a41b40bcb3a3f467ab19f891d9bc4642e4", size = 155316 }, + { url = "https://files.pythonhosted.org/packages/6d/52/45d969fcff6b5577c2bf17098dc36269b4c02197d551371c023130c0f890/bcrypt-4.3.0-cp313-cp313t-win_amd64.whl", hash = "sha256:5c1949bf259a388863ced887c7861da1df681cb2388645766c89fdfd9004c669", size = 147752 }, + { url = "https://files.pythonhosted.org/packages/11/22/5ada0b9af72b60cbc4c9a399fdde4af0feaa609d27eb0adc61607997a3fa/bcrypt-4.3.0-cp38-abi3-macosx_10_12_universal2.whl", hash = "sha256:f81b0ed2639568bf14749112298f9e4e2b28853dab50a8b357e31798686a036d", size = 498019 }, + { url = "https://files.pythonhosted.org/packages/b8/8c/252a1edc598dc1ce57905be173328eda073083826955ee3c97c7ff5ba584/bcrypt-4.3.0-cp38-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:864f8f19adbe13b7de11ba15d85d4a428c7e2f344bac110f667676a0ff84924b", size = 279174 }, + { url = "https://files.pythonhosted.org/packages/29/5b/4547d5c49b85f0337c13929f2ccbe08b7283069eea3550a457914fc078aa/bcrypt-4.3.0-cp38-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3e36506d001e93bffe59754397572f21bb5dc7c83f54454c990c74a468cd589e", size = 283870 }, + { url = "https://files.pythonhosted.org/packages/be/21/7dbaf3fa1745cb63f776bb046e481fbababd7d344c5324eab47f5ca92dd2/bcrypt-4.3.0-cp38-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:842d08d75d9fe9fb94b18b071090220697f9f184d4547179b60734846461ed59", size = 279601 }, + { url = "https://files.pythonhosted.org/packages/6d/64/e042fc8262e971347d9230d9abbe70d68b0a549acd8611c83cebd3eaec67/bcrypt-4.3.0-cp38-abi3-manylinux_2_28_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:7c03296b85cb87db865d91da79bf63d5609284fc0cab9472fdd8367bbd830753", size = 297660 }, + { url = "https://files.pythonhosted.org/packages/50/b8/6294eb84a3fef3b67c69b4470fcdd5326676806bf2519cda79331ab3c3a9/bcrypt-4.3.0-cp38-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:62f26585e8b219cdc909b6a0069efc5e4267e25d4a3770a364ac58024f62a761", size = 284083 }, + { url = "https://files.pythonhosted.org/packages/62/e6/baff635a4f2c42e8788fe1b1633911c38551ecca9a749d1052d296329da6/bcrypt-4.3.0-cp38-abi3-manylinux_2_34_aarch64.whl", hash = "sha256:beeefe437218a65322fbd0069eb437e7c98137e08f22c4660ac2dc795c31f8bb", size = 279237 }, + { url = "https://files.pythonhosted.org/packages/39/48/46f623f1b0c7dc2e5de0b8af5e6f5ac4cc26408ac33f3d424e5ad8da4a90/bcrypt-4.3.0-cp38-abi3-manylinux_2_34_x86_64.whl", hash = "sha256:97eea7408db3a5bcce4a55d13245ab3fa566e23b4c67cd227062bb49e26c585d", size = 283737 }, + { url = "https://files.pythonhosted.org/packages/49/8b/70671c3ce9c0fca4a6cc3cc6ccbaa7e948875a2e62cbd146e04a4011899c/bcrypt-4.3.0-cp38-abi3-musllinux_1_1_aarch64.whl", hash = "sha256:191354ebfe305e84f344c5964c7cd5f924a3bfc5d405c75ad07f232b6dffb49f", size = 312741 }, + { url = "https://files.pythonhosted.org/packages/27/fb/910d3a1caa2d249b6040a5caf9f9866c52114d51523ac2fb47578a27faee/bcrypt-4.3.0-cp38-abi3-musllinux_1_1_x86_64.whl", hash = "sha256:41261d64150858eeb5ff43c753c4b216991e0ae16614a308a15d909503617732", size = 316472 }, + { url = "https://files.pythonhosted.org/packages/dc/cf/7cf3a05b66ce466cfb575dbbda39718d45a609daa78500f57fa9f36fa3c0/bcrypt-4.3.0-cp38-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:33752b1ba962ee793fa2b6321404bf20011fe45b9afd2a842139de3011898fef", size = 343606 }, + { url = "https://files.pythonhosted.org/packages/e3/b8/e970ecc6d7e355c0d892b7f733480f4aa8509f99b33e71550242cf0b7e63/bcrypt-4.3.0-cp38-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:50e6e80a4bfd23a25f5c05b90167c19030cf9f87930f7cb2eacb99f45d1c3304", size = 362867 }, + { url = "https://files.pythonhosted.org/packages/a9/97/8d3118efd8354c555a3422d544163f40d9f236be5b96c714086463f11699/bcrypt-4.3.0-cp38-abi3-win32.whl", hash = "sha256:67a561c4d9fb9465ec866177e7aebcad08fe23aaf6fbd692a6fab69088abfc51", size = 160589 }, + { url = "https://files.pythonhosted.org/packages/29/07/416f0b99f7f3997c69815365babbc2e8754181a4b1899d921b3c7d5b6f12/bcrypt-4.3.0-cp38-abi3-win_amd64.whl", hash = "sha256:584027857bc2843772114717a7490a37f68da563b3620f78a849bcb54dc11e62", size = 152794 }, + { url = "https://files.pythonhosted.org/packages/6e/c1/3fa0e9e4e0bfd3fd77eb8b52ec198fd6e1fd7e9402052e43f23483f956dd/bcrypt-4.3.0-cp39-abi3-macosx_10_12_universal2.whl", hash = "sha256:0d3efb1157edebfd9128e4e46e2ac1a64e0c1fe46fb023158a407c7892b0f8c3", size = 498969 }, + { url = "https://files.pythonhosted.org/packages/ce/d4/755ce19b6743394787fbd7dff6bf271b27ee9b5912a97242e3caf125885b/bcrypt-4.3.0-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:08bacc884fd302b611226c01014eca277d48f0a05187666bca23aac0dad6fe24", size = 279158 }, + { url = "https://files.pythonhosted.org/packages/9b/5d/805ef1a749c965c46b28285dfb5cd272a7ed9fa971f970435a5133250182/bcrypt-4.3.0-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f6746e6fec103fcd509b96bacdfdaa2fbde9a553245dbada284435173a6f1aef", size = 284285 }, + { url = "https://files.pythonhosted.org/packages/ab/2b/698580547a4a4988e415721b71eb45e80c879f0fb04a62da131f45987b96/bcrypt-4.3.0-cp39-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:afe327968aaf13fc143a56a3360cb27d4ad0345e34da12c7290f1b00b8fe9a8b", size = 279583 }, + { url = "https://files.pythonhosted.org/packages/f2/87/62e1e426418204db520f955ffd06f1efd389feca893dad7095bf35612eec/bcrypt-4.3.0-cp39-abi3-manylinux_2_28_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:d9af79d322e735b1fc33404b5765108ae0ff232d4b54666d46730f8ac1a43676", size = 297896 }, + { url = "https://files.pythonhosted.org/packages/cb/c6/8fedca4c2ada1b6e889c52d2943b2f968d3427e5d65f595620ec4c06fa2f/bcrypt-4.3.0-cp39-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:f1e3ffa1365e8702dc48c8b360fef8d7afeca482809c5e45e653af82ccd088c1", size = 284492 }, + { url = "https://files.pythonhosted.org/packages/4d/4d/c43332dcaaddb7710a8ff5269fcccba97ed3c85987ddaa808db084267b9a/bcrypt-4.3.0-cp39-abi3-manylinux_2_34_aarch64.whl", hash = "sha256:3004df1b323d10021fda07a813fd33e0fd57bef0e9a480bb143877f6cba996fe", size = 279213 }, + { url = "https://files.pythonhosted.org/packages/dc/7f/1e36379e169a7df3a14a1c160a49b7b918600a6008de43ff20d479e6f4b5/bcrypt-4.3.0-cp39-abi3-manylinux_2_34_x86_64.whl", hash = "sha256:531457e5c839d8caea9b589a1bcfe3756b0547d7814e9ce3d437f17da75c32b0", size = 284162 }, + { url = "https://files.pythonhosted.org/packages/1c/0a/644b2731194b0d7646f3210dc4d80c7fee3ecb3a1f791a6e0ae6bb8684e3/bcrypt-4.3.0-cp39-abi3-musllinux_1_1_aarch64.whl", hash = "sha256:17a854d9a7a476a89dcef6c8bd119ad23e0f82557afbd2c442777a16408e614f", size = 312856 }, + { url = "https://files.pythonhosted.org/packages/dc/62/2a871837c0bb6ab0c9a88bf54de0fc021a6a08832d4ea313ed92a669d437/bcrypt-4.3.0-cp39-abi3-musllinux_1_1_x86_64.whl", hash = "sha256:6fb1fd3ab08c0cbc6826a2e0447610c6f09e983a281b919ed721ad32236b8b23", size = 316726 }, + { url = "https://files.pythonhosted.org/packages/0c/a1/9898ea3faac0b156d457fd73a3cb9c2855c6fd063e44b8522925cdd8ce46/bcrypt-4.3.0-cp39-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:e965a9c1e9a393b8005031ff52583cedc15b7884fce7deb8b0346388837d6cfe", size = 343664 }, + { url = "https://files.pythonhosted.org/packages/40/f2/71b4ed65ce38982ecdda0ff20c3ad1b15e71949c78b2c053df53629ce940/bcrypt-4.3.0-cp39-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:79e70b8342a33b52b55d93b3a59223a844962bef479f6a0ea318ebbcadf71505", size = 363128 }, + { url = "https://files.pythonhosted.org/packages/11/99/12f6a58eca6dea4be992d6c681b7ec9410a1d9f5cf368c61437e31daa879/bcrypt-4.3.0-cp39-abi3-win32.whl", hash = "sha256:b4d4e57f0a63fd0b358eb765063ff661328f69a04494427265950c71b992a39a", size = 160598 }, + { url = "https://files.pythonhosted.org/packages/a9/cf/45fb5261ece3e6b9817d3d82b2f343a505fd58674a92577923bc500bd1aa/bcrypt-4.3.0-cp39-abi3-win_amd64.whl", hash = "sha256:e53e074b120f2877a35cc6c736b8eb161377caae8925c17688bd46ba56daaa5b", size = 152799 }, ] [[package]] @@ -206,64 +215,64 @@ dependencies = [ { name = "soupsieve" }, { name = "typing-extensions" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/77/e9/df2358efd7659577435e2177bfa69cba6c33216681af51a707193dec162a/beautifulsoup4-4.14.2.tar.gz", hash = "sha256:2a98ab9f944a11acee9cc848508ec28d9228abfd522ef0fad6a02a72e0ded69e", size = 625822, upload-time = "2025-09-29T10:05:42.613Z" } +sdist = { url = "https://files.pythonhosted.org/packages/77/e9/df2358efd7659577435e2177bfa69cba6c33216681af51a707193dec162a/beautifulsoup4-4.14.2.tar.gz", hash = "sha256:2a98ab9f944a11acee9cc848508ec28d9228abfd522ef0fad6a02a72e0ded69e", size = 625822 } wheels = [ - { url = "https://files.pythonhosted.org/packages/94/fe/3aed5d0be4d404d12d36ab97e2f1791424d9ca39c2f754a6285d59a3b01d/beautifulsoup4-4.14.2-py3-none-any.whl", hash = "sha256:5ef6fa3a8cbece8488d66985560f97ed091e22bbc4e9c2338508a9d5de6d4515", size = 106392, upload-time = "2025-09-29T10:05:43.771Z" }, + { url = "https://files.pythonhosted.org/packages/94/fe/3aed5d0be4d404d12d36ab97e2f1791424d9ca39c2f754a6285d59a3b01d/beautifulsoup4-4.14.2-py3-none-any.whl", hash = "sha256:5ef6fa3a8cbece8488d66985560f97ed091e22bbc4e9c2338508a9d5de6d4515", size = 106392 }, ] [[package]] name = "blinker" version = "1.9.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/21/28/9b3f50ce0e048515135495f198351908d99540d69bfdc8c1d15b73dc55ce/blinker-1.9.0.tar.gz", hash = "sha256:b4ce2265a7abece45e7cc896e98dbebe6cead56bcf805a3d23136d145f5445bf", size = 22460, upload-time = "2024-11-08T17:25:47.436Z" } +sdist = { url = "https://files.pythonhosted.org/packages/21/28/9b3f50ce0e048515135495f198351908d99540d69bfdc8c1d15b73dc55ce/blinker-1.9.0.tar.gz", hash = "sha256:b4ce2265a7abece45e7cc896e98dbebe6cead56bcf805a3d23136d145f5445bf", size = 22460 } wheels = [ - { url = "https://files.pythonhosted.org/packages/10/cb/f2ad4230dc2eb1a74edf38f1a38b9b52277f75bef262d8908e60d957e13c/blinker-1.9.0-py3-none-any.whl", hash = "sha256:ba0efaa9080b619ff2f3459d1d500c57bddea4a6b424b60a91141db6fd2f08bc", size = 8458, upload-time = "2024-11-08T17:25:46.184Z" }, + { url = "https://files.pythonhosted.org/packages/10/cb/f2ad4230dc2eb1a74edf38f1a38b9b52277f75bef262d8908e60d957e13c/blinker-1.9.0-py3-none-any.whl", hash = "sha256:ba0efaa9080b619ff2f3459d1d500c57bddea4a6b424b60a91141db6fd2f08bc", size = 8458 }, ] [[package]] name = "boto3" -version = "1.40.55" +version = "1.40.68" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "botocore" }, { name = "jmespath" }, { name = "s3transfer" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/50/d8/a279c054e0c9731172f05b3d118f3ffc9d74806657f84fc0c93c42d1bb5d/boto3-1.40.55.tar.gz", hash = "sha256:27e35b4fa9edd414ce06c1a748bf57cacd8203271847d93fc1053e4a4ec6e1a9", size = 111590, upload-time = "2025-10-17T19:34:56.753Z" } +sdist = { url = "https://files.pythonhosted.org/packages/df/3e/6c8ab966798f4e07651009ad08efc3ed4ffccf2662318790574695c740f7/boto3-1.40.68.tar.gz", hash = "sha256:c7994989e5bbba071b7c742adfba35773cf03e87f5d3f9f2b0a18c1664417b61", size = 111629 } wheels = [ - { url = "https://files.pythonhosted.org/packages/42/8c/559c6145d857ed953536a83f3a94915bbd5d3d2d406db1abf8bf40be7645/boto3-1.40.55-py3-none-any.whl", hash = "sha256:2e30f5a0d49e107b8a5c0c487891afd300bfa410e1d918bf187ae45ac3839332", size = 139322, upload-time = "2025-10-17T19:34:55.028Z" }, + { url = "https://files.pythonhosted.org/packages/07/e6/b9df94d3a51ad658ef1974da6c0d7401b6aed7be50a2ee57bf1de1ef9517/boto3-1.40.68-py3-none-any.whl", hash = "sha256:4f08115e3a4d1e1056003e433d393e78c20da6af7753409992bb33fb69f04186", size = 139361 }, ] [[package]] name = "botocore" -version = "1.40.55" +version = "1.40.68" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "jmespath" }, { name = "python-dateutil" }, { name = "urllib3" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/a4/92/dce4842b2e215d213d34b064fcdd13c6a782c43344e77336bcde586e9229/botocore-1.40.55.tar.gz", hash = "sha256:79b6472e2de92b3519d44fc1eec8c5feced7f99a0d10fdea6dc93133426057c1", size = 14446917, upload-time = "2025-10-17T19:34:47.44Z" } +sdist = { url = "https://files.pythonhosted.org/packages/eb/df/b0300da4cc1fe3e37c8d7a44d835518004454c7d21b579fce9ef2cd691ce/botocore-1.40.68.tar.gz", hash = "sha256:28f41b463d9f012a711ee8b61d4e26cd14ee3b450b816d5dee849aa79155e856", size = 14435596 } wheels = [ - { url = "https://files.pythonhosted.org/packages/21/30/f13bbc36e83b78777ff1abf50a084efcc3336b808e76560d8c5a0c9219e0/botocore-1.40.55-py3-none-any.whl", hash = "sha256:cdc38f7a4ddb30a2cd1cdd4fabde2a5a16e41b5a642292e1c30de5c4e46f5d44", size = 14116107, upload-time = "2025-10-17T19:34:44.398Z" }, + { url = "https://files.pythonhosted.org/packages/7a/72/ac8123169ce48cb2eb593cd4c6a22e66d72bf8dc30fe75191a7669dd036d/botocore-1.40.68-py3-none-any.whl", hash = "sha256:9d514f9c9054e1af055f2cbe9e0d6771d407a600206d45a01b54d5f09538fecb", size = 14097634 }, ] [[package]] name = "cachetools" version = "5.5.2" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/6c/81/3747dad6b14fa2cf53fcf10548cf5aea6913e96fab41a3c198676f8948a5/cachetools-5.5.2.tar.gz", hash = "sha256:1a661caa9175d26759571b2e19580f9d6393969e5dfca11fdb1f947a23e640d4", size = 28380, upload-time = "2025-02-20T21:01:19.524Z" } +sdist = { url = "https://files.pythonhosted.org/packages/6c/81/3747dad6b14fa2cf53fcf10548cf5aea6913e96fab41a3c198676f8948a5/cachetools-5.5.2.tar.gz", hash = "sha256:1a661caa9175d26759571b2e19580f9d6393969e5dfca11fdb1f947a23e640d4", size = 28380 } wheels = [ - { url = "https://files.pythonhosted.org/packages/72/76/20fa66124dbe6be5cafeb312ece67de6b61dd91a0247d1ea13db4ebb33c2/cachetools-5.5.2-py3-none-any.whl", hash = "sha256:d26a22bcc62eb95c3beabd9f1ee5e820d3d2704fe2967cbe350e20c8ffcd3f0a", size = 10080, upload-time = "2025-02-20T21:01:16.647Z" }, + { url = "https://files.pythonhosted.org/packages/72/76/20fa66124dbe6be5cafeb312ece67de6b61dd91a0247d1ea13db4ebb33c2/cachetools-5.5.2-py3-none-any.whl", hash = "sha256:d26a22bcc62eb95c3beabd9f1ee5e820d3d2704fe2967cbe350e20c8ffcd3f0a", size = 10080 }, ] [[package]] name = "certifi" version = "2025.10.5" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/4c/5b/b6ce21586237c77ce67d01dc5507039d444b630dd76611bbca2d8e5dcd91/certifi-2025.10.5.tar.gz", hash = "sha256:47c09d31ccf2acf0be3f701ea53595ee7e0b8fa08801c6624be771df09ae7b43", size = 164519, upload-time = "2025-10-05T04:12:15.808Z" } +sdist = { url = "https://files.pythonhosted.org/packages/4c/5b/b6ce21586237c77ce67d01dc5507039d444b630dd76611bbca2d8e5dcd91/certifi-2025.10.5.tar.gz", hash = "sha256:47c09d31ccf2acf0be3f701ea53595ee7e0b8fa08801c6624be771df09ae7b43", size = 164519 } wheels = [ - { url = "https://files.pythonhosted.org/packages/e4/37/af0d2ef3967ac0d6113837b44a4f0bfe1328c2b9763bd5b1744520e5cfed/certifi-2025.10.5-py3-none-any.whl", hash = "sha256:0f212c2744a9bb6de0c56639a6f68afe01ecd92d91f14ae897c4fe7bbeeef0de", size = 163286, upload-time = "2025-10-05T04:12:14.03Z" }, + { url = "https://files.pythonhosted.org/packages/e4/37/af0d2ef3967ac0d6113837b44a4f0bfe1328c2b9763bd5b1744520e5cfed/certifi-2025.10.5-py3-none-any.whl", hash = "sha256:0f212c2744a9bb6de0c56639a6f68afe01ecd92d91f14ae897c4fe7bbeeef0de", size = 163286 }, ] [[package]] @@ -273,83 +282,83 @@ source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "pycparser", marker = "implementation_name != 'PyPy'" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/eb/56/b1ba7935a17738ae8453301356628e8147c79dbb825bcbc73dc7401f9846/cffi-2.0.0.tar.gz", hash = "sha256:44d1b5909021139fe36001ae048dbdde8214afa20200eda0f64c068cac5d5529", size = 523588, upload-time = "2025-09-08T23:24:04.541Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/4b/8d/a0a47a0c9e413a658623d014e91e74a50cdd2c423f7ccfd44086ef767f90/cffi-2.0.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:00bdf7acc5f795150faa6957054fbbca2439db2f775ce831222b66f192f03beb", size = 185230, upload-time = "2025-09-08T23:23:00.879Z" }, - { url = "https://files.pythonhosted.org/packages/4a/d2/a6c0296814556c68ee32009d9c2ad4f85f2707cdecfd7727951ec228005d/cffi-2.0.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:45d5e886156860dc35862657e1494b9bae8dfa63bf56796f2fb56e1679fc0bca", size = 181043, upload-time = "2025-09-08T23:23:02.231Z" }, - { url = "https://files.pythonhosted.org/packages/b0/1e/d22cc63332bd59b06481ceaac49d6c507598642e2230f201649058a7e704/cffi-2.0.0-cp313-cp313-manylinux1_i686.manylinux2014_i686.manylinux_2_17_i686.manylinux_2_5_i686.whl", hash = "sha256:07b271772c100085dd28b74fa0cd81c8fb1a3ba18b21e03d7c27f3436a10606b", size = 212446, upload-time = "2025-09-08T23:23:03.472Z" }, - { url = "https://files.pythonhosted.org/packages/a9/f5/a2c23eb03b61a0b8747f211eb716446c826ad66818ddc7810cc2cc19b3f2/cffi-2.0.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:d48a880098c96020b02d5a1f7d9251308510ce8858940e6fa99ece33f610838b", size = 220101, upload-time = "2025-09-08T23:23:04.792Z" }, - { url = "https://files.pythonhosted.org/packages/f2/7f/e6647792fc5850d634695bc0e6ab4111ae88e89981d35ac269956605feba/cffi-2.0.0-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:f93fd8e5c8c0a4aa1f424d6173f14a892044054871c771f8566e4008eaa359d2", size = 207948, upload-time = "2025-09-08T23:23:06.127Z" }, - { url = "https://files.pythonhosted.org/packages/cb/1e/a5a1bd6f1fb30f22573f76533de12a00bf274abcdc55c8edab639078abb6/cffi-2.0.0-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:dd4f05f54a52fb558f1ba9f528228066954fee3ebe629fc1660d874d040ae5a3", size = 206422, upload-time = "2025-09-08T23:23:07.753Z" }, - { url = "https://files.pythonhosted.org/packages/98/df/0a1755e750013a2081e863e7cd37e0cdd02664372c754e5560099eb7aa44/cffi-2.0.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:c8d3b5532fc71b7a77c09192b4a5a200ea992702734a2e9279a37f2478236f26", size = 219499, upload-time = "2025-09-08T23:23:09.648Z" }, - { url = "https://files.pythonhosted.org/packages/50/e1/a969e687fcf9ea58e6e2a928ad5e2dd88cc12f6f0ab477e9971f2309b57c/cffi-2.0.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:d9b29c1f0ae438d5ee9acb31cadee00a58c46cc9c0b2f9038c6b0b3470877a8c", size = 222928, upload-time = "2025-09-08T23:23:10.928Z" }, - { url = "https://files.pythonhosted.org/packages/36/54/0362578dd2c9e557a28ac77698ed67323ed5b9775ca9d3fe73fe191bb5d8/cffi-2.0.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:6d50360be4546678fc1b79ffe7a66265e28667840010348dd69a314145807a1b", size = 221302, upload-time = "2025-09-08T23:23:12.42Z" }, - { url = "https://files.pythonhosted.org/packages/eb/6d/bf9bda840d5f1dfdbf0feca87fbdb64a918a69bca42cfa0ba7b137c48cb8/cffi-2.0.0-cp313-cp313-win32.whl", hash = "sha256:74a03b9698e198d47562765773b4a8309919089150a0bb17d829ad7b44b60d27", size = 172909, upload-time = "2025-09-08T23:23:14.32Z" }, - { url = "https://files.pythonhosted.org/packages/37/18/6519e1ee6f5a1e579e04b9ddb6f1676c17368a7aba48299c3759bbc3c8b3/cffi-2.0.0-cp313-cp313-win_amd64.whl", hash = "sha256:19f705ada2530c1167abacb171925dd886168931e0a7b78f5bffcae5c6b5be75", size = 183402, upload-time = "2025-09-08T23:23:15.535Z" }, - { url = "https://files.pythonhosted.org/packages/cb/0e/02ceeec9a7d6ee63bb596121c2c8e9b3a9e150936f4fbef6ca1943e6137c/cffi-2.0.0-cp313-cp313-win_arm64.whl", hash = "sha256:256f80b80ca3853f90c21b23ee78cd008713787b1b1e93eae9f3d6a7134abd91", size = 177780, upload-time = "2025-09-08T23:23:16.761Z" }, - { url = "https://files.pythonhosted.org/packages/92/c4/3ce07396253a83250ee98564f8d7e9789fab8e58858f35d07a9a2c78de9f/cffi-2.0.0-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:fc33c5141b55ed366cfaad382df24fe7dcbc686de5be719b207bb248e3053dc5", size = 185320, upload-time = "2025-09-08T23:23:18.087Z" }, - { url = "https://files.pythonhosted.org/packages/59/dd/27e9fa567a23931c838c6b02d0764611c62290062a6d4e8ff7863daf9730/cffi-2.0.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:c654de545946e0db659b3400168c9ad31b5d29593291482c43e3564effbcee13", size = 181487, upload-time = "2025-09-08T23:23:19.622Z" }, - { url = "https://files.pythonhosted.org/packages/d6/43/0e822876f87ea8a4ef95442c3d766a06a51fc5298823f884ef87aaad168c/cffi-2.0.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:24b6f81f1983e6df8db3adc38562c83f7d4a0c36162885ec7f7b77c7dcbec97b", size = 220049, upload-time = "2025-09-08T23:23:20.853Z" }, - { url = "https://files.pythonhosted.org/packages/b4/89/76799151d9c2d2d1ead63c2429da9ea9d7aac304603de0c6e8764e6e8e70/cffi-2.0.0-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:12873ca6cb9b0f0d3a0da705d6086fe911591737a59f28b7936bdfed27c0d47c", size = 207793, upload-time = "2025-09-08T23:23:22.08Z" }, - { url = "https://files.pythonhosted.org/packages/bb/dd/3465b14bb9e24ee24cb88c9e3730f6de63111fffe513492bf8c808a3547e/cffi-2.0.0-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:d9b97165e8aed9272a6bb17c01e3cc5871a594a446ebedc996e2397a1c1ea8ef", size = 206300, upload-time = "2025-09-08T23:23:23.314Z" }, - { url = "https://files.pythonhosted.org/packages/47/d9/d83e293854571c877a92da46fdec39158f8d7e68da75bf73581225d28e90/cffi-2.0.0-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:afb8db5439b81cf9c9d0c80404b60c3cc9c3add93e114dcae767f1477cb53775", size = 219244, upload-time = "2025-09-08T23:23:24.541Z" }, - { url = "https://files.pythonhosted.org/packages/2b/0f/1f177e3683aead2bb00f7679a16451d302c436b5cbf2505f0ea8146ef59e/cffi-2.0.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:737fe7d37e1a1bffe70bd5754ea763a62a066dc5913ca57e957824b72a85e205", size = 222828, upload-time = "2025-09-08T23:23:26.143Z" }, - { url = "https://files.pythonhosted.org/packages/c6/0f/cafacebd4b040e3119dcb32fed8bdef8dfe94da653155f9d0b9dc660166e/cffi-2.0.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:38100abb9d1b1435bc4cc340bb4489635dc2f0da7456590877030c9b3d40b0c1", size = 220926, upload-time = "2025-09-08T23:23:27.873Z" }, - { url = "https://files.pythonhosted.org/packages/3e/aa/df335faa45b395396fcbc03de2dfcab242cd61a9900e914fe682a59170b1/cffi-2.0.0-cp314-cp314-win32.whl", hash = "sha256:087067fa8953339c723661eda6b54bc98c5625757ea62e95eb4898ad5e776e9f", size = 175328, upload-time = "2025-09-08T23:23:44.61Z" }, - { url = "https://files.pythonhosted.org/packages/bb/92/882c2d30831744296ce713f0feb4c1cd30f346ef747b530b5318715cc367/cffi-2.0.0-cp314-cp314-win_amd64.whl", hash = "sha256:203a48d1fb583fc7d78a4c6655692963b860a417c0528492a6bc21f1aaefab25", size = 185650, upload-time = "2025-09-08T23:23:45.848Z" }, - { url = "https://files.pythonhosted.org/packages/9f/2c/98ece204b9d35a7366b5b2c6539c350313ca13932143e79dc133ba757104/cffi-2.0.0-cp314-cp314-win_arm64.whl", hash = "sha256:dbd5c7a25a7cb98f5ca55d258b103a2054f859a46ae11aaf23134f9cc0d356ad", size = 180687, upload-time = "2025-09-08T23:23:47.105Z" }, - { url = "https://files.pythonhosted.org/packages/3e/61/c768e4d548bfa607abcda77423448df8c471f25dbe64fb2ef6d555eae006/cffi-2.0.0-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:9a67fc9e8eb39039280526379fb3a70023d77caec1852002b4da7e8b270c4dd9", size = 188773, upload-time = "2025-09-08T23:23:29.347Z" }, - { url = "https://files.pythonhosted.org/packages/2c/ea/5f76bce7cf6fcd0ab1a1058b5af899bfbef198bea4d5686da88471ea0336/cffi-2.0.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:7a66c7204d8869299919db4d5069a82f1561581af12b11b3c9f48c584eb8743d", size = 185013, upload-time = "2025-09-08T23:23:30.63Z" }, - { url = "https://files.pythonhosted.org/packages/be/b4/c56878d0d1755cf9caa54ba71e5d049479c52f9e4afc230f06822162ab2f/cffi-2.0.0-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:7cc09976e8b56f8cebd752f7113ad07752461f48a58cbba644139015ac24954c", size = 221593, upload-time = "2025-09-08T23:23:31.91Z" }, - { url = "https://files.pythonhosted.org/packages/e0/0d/eb704606dfe8033e7128df5e90fee946bbcb64a04fcdaa97321309004000/cffi-2.0.0-cp314-cp314t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:92b68146a71df78564e4ef48af17551a5ddd142e5190cdf2c5624d0c3ff5b2e8", size = 209354, upload-time = "2025-09-08T23:23:33.214Z" }, - { url = "https://files.pythonhosted.org/packages/d8/19/3c435d727b368ca475fb8742ab97c9cb13a0de600ce86f62eab7fa3eea60/cffi-2.0.0-cp314-cp314t-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:b1e74d11748e7e98e2f426ab176d4ed720a64412b6a15054378afdb71e0f37dc", size = 208480, upload-time = "2025-09-08T23:23:34.495Z" }, - { url = "https://files.pythonhosted.org/packages/d0/44/681604464ed9541673e486521497406fadcc15b5217c3e326b061696899a/cffi-2.0.0-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:28a3a209b96630bca57cce802da70c266eb08c6e97e5afd61a75611ee6c64592", size = 221584, upload-time = "2025-09-08T23:23:36.096Z" }, - { url = "https://files.pythonhosted.org/packages/25/8e/342a504ff018a2825d395d44d63a767dd8ebc927ebda557fecdaca3ac33a/cffi-2.0.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:7553fb2090d71822f02c629afe6042c299edf91ba1bf94951165613553984512", size = 224443, upload-time = "2025-09-08T23:23:37.328Z" }, - { url = "https://files.pythonhosted.org/packages/e1/5e/b666bacbbc60fbf415ba9988324a132c9a7a0448a9a8f125074671c0f2c3/cffi-2.0.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:6c6c373cfc5c83a975506110d17457138c8c63016b563cc9ed6e056a82f13ce4", size = 223437, upload-time = "2025-09-08T23:23:38.945Z" }, - { url = "https://files.pythonhosted.org/packages/a0/1d/ec1a60bd1a10daa292d3cd6bb0b359a81607154fb8165f3ec95fe003b85c/cffi-2.0.0-cp314-cp314t-win32.whl", hash = "sha256:1fc9ea04857caf665289b7a75923f2c6ed559b8298a1b8c49e59f7dd95c8481e", size = 180487, upload-time = "2025-09-08T23:23:40.423Z" }, - { url = "https://files.pythonhosted.org/packages/bf/41/4c1168c74fac325c0c8156f04b6749c8b6a8f405bbf91413ba088359f60d/cffi-2.0.0-cp314-cp314t-win_amd64.whl", hash = "sha256:d68b6cef7827e8641e8ef16f4494edda8b36104d79773a334beaa1e3521430f6", size = 191726, upload-time = "2025-09-08T23:23:41.742Z" }, - { url = "https://files.pythonhosted.org/packages/ae/3a/dbeec9d1ee0844c679f6bb5d6ad4e9f198b1224f4e7a32825f47f6192b0c/cffi-2.0.0-cp314-cp314t-win_arm64.whl", hash = "sha256:0a1527a803f0a659de1af2e1fd700213caba79377e27e4693648c2923da066f9", size = 184195, upload-time = "2025-09-08T23:23:43.004Z" }, +sdist = { url = "https://files.pythonhosted.org/packages/eb/56/b1ba7935a17738ae8453301356628e8147c79dbb825bcbc73dc7401f9846/cffi-2.0.0.tar.gz", hash = "sha256:44d1b5909021139fe36001ae048dbdde8214afa20200eda0f64c068cac5d5529", size = 523588 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/4b/8d/a0a47a0c9e413a658623d014e91e74a50cdd2c423f7ccfd44086ef767f90/cffi-2.0.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:00bdf7acc5f795150faa6957054fbbca2439db2f775ce831222b66f192f03beb", size = 185230 }, + { url = "https://files.pythonhosted.org/packages/4a/d2/a6c0296814556c68ee32009d9c2ad4f85f2707cdecfd7727951ec228005d/cffi-2.0.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:45d5e886156860dc35862657e1494b9bae8dfa63bf56796f2fb56e1679fc0bca", size = 181043 }, + { url = "https://files.pythonhosted.org/packages/b0/1e/d22cc63332bd59b06481ceaac49d6c507598642e2230f201649058a7e704/cffi-2.0.0-cp313-cp313-manylinux1_i686.manylinux2014_i686.manylinux_2_17_i686.manylinux_2_5_i686.whl", hash = "sha256:07b271772c100085dd28b74fa0cd81c8fb1a3ba18b21e03d7c27f3436a10606b", size = 212446 }, + { url = "https://files.pythonhosted.org/packages/a9/f5/a2c23eb03b61a0b8747f211eb716446c826ad66818ddc7810cc2cc19b3f2/cffi-2.0.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:d48a880098c96020b02d5a1f7d9251308510ce8858940e6fa99ece33f610838b", size = 220101 }, + { url = "https://files.pythonhosted.org/packages/f2/7f/e6647792fc5850d634695bc0e6ab4111ae88e89981d35ac269956605feba/cffi-2.0.0-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:f93fd8e5c8c0a4aa1f424d6173f14a892044054871c771f8566e4008eaa359d2", size = 207948 }, + { url = "https://files.pythonhosted.org/packages/cb/1e/a5a1bd6f1fb30f22573f76533de12a00bf274abcdc55c8edab639078abb6/cffi-2.0.0-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:dd4f05f54a52fb558f1ba9f528228066954fee3ebe629fc1660d874d040ae5a3", size = 206422 }, + { url = "https://files.pythonhosted.org/packages/98/df/0a1755e750013a2081e863e7cd37e0cdd02664372c754e5560099eb7aa44/cffi-2.0.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:c8d3b5532fc71b7a77c09192b4a5a200ea992702734a2e9279a37f2478236f26", size = 219499 }, + { url = "https://files.pythonhosted.org/packages/50/e1/a969e687fcf9ea58e6e2a928ad5e2dd88cc12f6f0ab477e9971f2309b57c/cffi-2.0.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:d9b29c1f0ae438d5ee9acb31cadee00a58c46cc9c0b2f9038c6b0b3470877a8c", size = 222928 }, + { url = "https://files.pythonhosted.org/packages/36/54/0362578dd2c9e557a28ac77698ed67323ed5b9775ca9d3fe73fe191bb5d8/cffi-2.0.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:6d50360be4546678fc1b79ffe7a66265e28667840010348dd69a314145807a1b", size = 221302 }, + { url = "https://files.pythonhosted.org/packages/eb/6d/bf9bda840d5f1dfdbf0feca87fbdb64a918a69bca42cfa0ba7b137c48cb8/cffi-2.0.0-cp313-cp313-win32.whl", hash = "sha256:74a03b9698e198d47562765773b4a8309919089150a0bb17d829ad7b44b60d27", size = 172909 }, + { url = "https://files.pythonhosted.org/packages/37/18/6519e1ee6f5a1e579e04b9ddb6f1676c17368a7aba48299c3759bbc3c8b3/cffi-2.0.0-cp313-cp313-win_amd64.whl", hash = "sha256:19f705ada2530c1167abacb171925dd886168931e0a7b78f5bffcae5c6b5be75", size = 183402 }, + { url = "https://files.pythonhosted.org/packages/cb/0e/02ceeec9a7d6ee63bb596121c2c8e9b3a9e150936f4fbef6ca1943e6137c/cffi-2.0.0-cp313-cp313-win_arm64.whl", hash = "sha256:256f80b80ca3853f90c21b23ee78cd008713787b1b1e93eae9f3d6a7134abd91", size = 177780 }, + { url = "https://files.pythonhosted.org/packages/92/c4/3ce07396253a83250ee98564f8d7e9789fab8e58858f35d07a9a2c78de9f/cffi-2.0.0-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:fc33c5141b55ed366cfaad382df24fe7dcbc686de5be719b207bb248e3053dc5", size = 185320 }, + { url = "https://files.pythonhosted.org/packages/59/dd/27e9fa567a23931c838c6b02d0764611c62290062a6d4e8ff7863daf9730/cffi-2.0.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:c654de545946e0db659b3400168c9ad31b5d29593291482c43e3564effbcee13", size = 181487 }, + { url = "https://files.pythonhosted.org/packages/d6/43/0e822876f87ea8a4ef95442c3d766a06a51fc5298823f884ef87aaad168c/cffi-2.0.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:24b6f81f1983e6df8db3adc38562c83f7d4a0c36162885ec7f7b77c7dcbec97b", size = 220049 }, + { url = "https://files.pythonhosted.org/packages/b4/89/76799151d9c2d2d1ead63c2429da9ea9d7aac304603de0c6e8764e6e8e70/cffi-2.0.0-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:12873ca6cb9b0f0d3a0da705d6086fe911591737a59f28b7936bdfed27c0d47c", size = 207793 }, + { url = "https://files.pythonhosted.org/packages/bb/dd/3465b14bb9e24ee24cb88c9e3730f6de63111fffe513492bf8c808a3547e/cffi-2.0.0-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:d9b97165e8aed9272a6bb17c01e3cc5871a594a446ebedc996e2397a1c1ea8ef", size = 206300 }, + { url = "https://files.pythonhosted.org/packages/47/d9/d83e293854571c877a92da46fdec39158f8d7e68da75bf73581225d28e90/cffi-2.0.0-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:afb8db5439b81cf9c9d0c80404b60c3cc9c3add93e114dcae767f1477cb53775", size = 219244 }, + { url = "https://files.pythonhosted.org/packages/2b/0f/1f177e3683aead2bb00f7679a16451d302c436b5cbf2505f0ea8146ef59e/cffi-2.0.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:737fe7d37e1a1bffe70bd5754ea763a62a066dc5913ca57e957824b72a85e205", size = 222828 }, + { url = "https://files.pythonhosted.org/packages/c6/0f/cafacebd4b040e3119dcb32fed8bdef8dfe94da653155f9d0b9dc660166e/cffi-2.0.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:38100abb9d1b1435bc4cc340bb4489635dc2f0da7456590877030c9b3d40b0c1", size = 220926 }, + { url = "https://files.pythonhosted.org/packages/3e/aa/df335faa45b395396fcbc03de2dfcab242cd61a9900e914fe682a59170b1/cffi-2.0.0-cp314-cp314-win32.whl", hash = "sha256:087067fa8953339c723661eda6b54bc98c5625757ea62e95eb4898ad5e776e9f", size = 175328 }, + { url = "https://files.pythonhosted.org/packages/bb/92/882c2d30831744296ce713f0feb4c1cd30f346ef747b530b5318715cc367/cffi-2.0.0-cp314-cp314-win_amd64.whl", hash = "sha256:203a48d1fb583fc7d78a4c6655692963b860a417c0528492a6bc21f1aaefab25", size = 185650 }, + { url = "https://files.pythonhosted.org/packages/9f/2c/98ece204b9d35a7366b5b2c6539c350313ca13932143e79dc133ba757104/cffi-2.0.0-cp314-cp314-win_arm64.whl", hash = "sha256:dbd5c7a25a7cb98f5ca55d258b103a2054f859a46ae11aaf23134f9cc0d356ad", size = 180687 }, + { url = "https://files.pythonhosted.org/packages/3e/61/c768e4d548bfa607abcda77423448df8c471f25dbe64fb2ef6d555eae006/cffi-2.0.0-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:9a67fc9e8eb39039280526379fb3a70023d77caec1852002b4da7e8b270c4dd9", size = 188773 }, + { url = "https://files.pythonhosted.org/packages/2c/ea/5f76bce7cf6fcd0ab1a1058b5af899bfbef198bea4d5686da88471ea0336/cffi-2.0.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:7a66c7204d8869299919db4d5069a82f1561581af12b11b3c9f48c584eb8743d", size = 185013 }, + { url = "https://files.pythonhosted.org/packages/be/b4/c56878d0d1755cf9caa54ba71e5d049479c52f9e4afc230f06822162ab2f/cffi-2.0.0-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:7cc09976e8b56f8cebd752f7113ad07752461f48a58cbba644139015ac24954c", size = 221593 }, + { url = "https://files.pythonhosted.org/packages/e0/0d/eb704606dfe8033e7128df5e90fee946bbcb64a04fcdaa97321309004000/cffi-2.0.0-cp314-cp314t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:92b68146a71df78564e4ef48af17551a5ddd142e5190cdf2c5624d0c3ff5b2e8", size = 209354 }, + { url = "https://files.pythonhosted.org/packages/d8/19/3c435d727b368ca475fb8742ab97c9cb13a0de600ce86f62eab7fa3eea60/cffi-2.0.0-cp314-cp314t-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:b1e74d11748e7e98e2f426ab176d4ed720a64412b6a15054378afdb71e0f37dc", size = 208480 }, + { url = "https://files.pythonhosted.org/packages/d0/44/681604464ed9541673e486521497406fadcc15b5217c3e326b061696899a/cffi-2.0.0-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:28a3a209b96630bca57cce802da70c266eb08c6e97e5afd61a75611ee6c64592", size = 221584 }, + { url = "https://files.pythonhosted.org/packages/25/8e/342a504ff018a2825d395d44d63a767dd8ebc927ebda557fecdaca3ac33a/cffi-2.0.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:7553fb2090d71822f02c629afe6042c299edf91ba1bf94951165613553984512", size = 224443 }, + { url = "https://files.pythonhosted.org/packages/e1/5e/b666bacbbc60fbf415ba9988324a132c9a7a0448a9a8f125074671c0f2c3/cffi-2.0.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:6c6c373cfc5c83a975506110d17457138c8c63016b563cc9ed6e056a82f13ce4", size = 223437 }, + { url = "https://files.pythonhosted.org/packages/a0/1d/ec1a60bd1a10daa292d3cd6bb0b359a81607154fb8165f3ec95fe003b85c/cffi-2.0.0-cp314-cp314t-win32.whl", hash = "sha256:1fc9ea04857caf665289b7a75923f2c6ed559b8298a1b8c49e59f7dd95c8481e", size = 180487 }, + { url = "https://files.pythonhosted.org/packages/bf/41/4c1168c74fac325c0c8156f04b6749c8b6a8f405bbf91413ba088359f60d/cffi-2.0.0-cp314-cp314t-win_amd64.whl", hash = "sha256:d68b6cef7827e8641e8ef16f4494edda8b36104d79773a334beaa1e3521430f6", size = 191726 }, + { url = "https://files.pythonhosted.org/packages/ae/3a/dbeec9d1ee0844c679f6bb5d6ad4e9f198b1224f4e7a32825f47f6192b0c/cffi-2.0.0-cp314-cp314t-win_arm64.whl", hash = "sha256:0a1527a803f0a659de1af2e1fd700213caba79377e27e4693648c2923da066f9", size = 184195 }, ] [[package]] name = "charset-normalizer" version = "3.4.4" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/13/69/33ddede1939fdd074bce5434295f38fae7136463422fe4fd3e0e89b98062/charset_normalizer-3.4.4.tar.gz", hash = "sha256:94537985111c35f28720e43603b8e7b43a6ecfb2ce1d3058bbe955b73404e21a", size = 129418, upload-time = "2025-10-14T04:42:32.879Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/97/45/4b3a1239bbacd321068ea6e7ac28875b03ab8bc0aa0966452db17cd36714/charset_normalizer-3.4.4-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:e1f185f86a6f3403aa2420e815904c67b2f9ebc443f045edd0de921108345794", size = 208091, upload-time = "2025-10-14T04:41:13.346Z" }, - { url = "https://files.pythonhosted.org/packages/7d/62/73a6d7450829655a35bb88a88fca7d736f9882a27eacdca2c6d505b57e2e/charset_normalizer-3.4.4-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6b39f987ae8ccdf0d2642338faf2abb1862340facc796048b604ef14919e55ed", size = 147936, upload-time = "2025-10-14T04:41:14.461Z" }, - { url = "https://files.pythonhosted.org/packages/89/c5/adb8c8b3d6625bef6d88b251bbb0d95f8205831b987631ab0c8bb5d937c2/charset_normalizer-3.4.4-cp313-cp313-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:3162d5d8ce1bb98dd51af660f2121c55d0fa541b46dff7bb9b9f86ea1d87de72", size = 144180, upload-time = "2025-10-14T04:41:15.588Z" }, - { url = "https://files.pythonhosted.org/packages/91/ed/9706e4070682d1cc219050b6048bfd293ccf67b3d4f5a4f39207453d4b99/charset_normalizer-3.4.4-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:81d5eb2a312700f4ecaa977a8235b634ce853200e828fbadf3a9c50bab278328", size = 161346, upload-time = "2025-10-14T04:41:16.738Z" }, - { url = "https://files.pythonhosted.org/packages/d5/0d/031f0d95e4972901a2f6f09ef055751805ff541511dc1252ba3ca1f80cf5/charset_normalizer-3.4.4-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:5bd2293095d766545ec1a8f612559f6b40abc0eb18bb2f5d1171872d34036ede", size = 158874, upload-time = "2025-10-14T04:41:17.923Z" }, - { url = "https://files.pythonhosted.org/packages/f5/83/6ab5883f57c9c801ce5e5677242328aa45592be8a00644310a008d04f922/charset_normalizer-3.4.4-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:a8a8b89589086a25749f471e6a900d3f662d1d3b6e2e59dcecf787b1cc3a1894", size = 153076, upload-time = "2025-10-14T04:41:19.106Z" }, - { url = "https://files.pythonhosted.org/packages/75/1e/5ff781ddf5260e387d6419959ee89ef13878229732732ee73cdae01800f2/charset_normalizer-3.4.4-cp313-cp313-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:bc7637e2f80d8530ee4a78e878bce464f70087ce73cf7c1caf142416923b98f1", size = 150601, upload-time = "2025-10-14T04:41:20.245Z" }, - { url = "https://files.pythonhosted.org/packages/d7/57/71be810965493d3510a6ca79b90c19e48696fb1ff964da319334b12677f0/charset_normalizer-3.4.4-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:f8bf04158c6b607d747e93949aa60618b61312fe647a6369f88ce2ff16043490", size = 150376, upload-time = "2025-10-14T04:41:21.398Z" }, - { url = "https://files.pythonhosted.org/packages/e5/d5/c3d057a78c181d007014feb7e9f2e65905a6c4ef182c0ddf0de2924edd65/charset_normalizer-3.4.4-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:554af85e960429cf30784dd47447d5125aaa3b99a6f0683589dbd27e2f45da44", size = 144825, upload-time = "2025-10-14T04:41:22.583Z" }, - { url = "https://files.pythonhosted.org/packages/e6/8c/d0406294828d4976f275ffbe66f00266c4b3136b7506941d87c00cab5272/charset_normalizer-3.4.4-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:74018750915ee7ad843a774364e13a3db91682f26142baddf775342c3f5b1133", size = 162583, upload-time = "2025-10-14T04:41:23.754Z" }, - { url = "https://files.pythonhosted.org/packages/d7/24/e2aa1f18c8f15c4c0e932d9287b8609dd30ad56dbe41d926bd846e22fb8d/charset_normalizer-3.4.4-cp313-cp313-musllinux_1_2_riscv64.whl", hash = "sha256:c0463276121fdee9c49b98908b3a89c39be45d86d1dbaa22957e38f6321d4ce3", size = 150366, upload-time = "2025-10-14T04:41:25.27Z" }, - { url = "https://files.pythonhosted.org/packages/e4/5b/1e6160c7739aad1e2df054300cc618b06bf784a7a164b0f238360721ab86/charset_normalizer-3.4.4-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:362d61fd13843997c1c446760ef36f240cf81d3ebf74ac62652aebaf7838561e", size = 160300, upload-time = "2025-10-14T04:41:26.725Z" }, - { url = "https://files.pythonhosted.org/packages/7a/10/f882167cd207fbdd743e55534d5d9620e095089d176d55cb22d5322f2afd/charset_normalizer-3.4.4-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:9a26f18905b8dd5d685d6d07b0cdf98a79f3c7a918906af7cc143ea2e164c8bc", size = 154465, upload-time = "2025-10-14T04:41:28.322Z" }, - { url = "https://files.pythonhosted.org/packages/89/66/c7a9e1b7429be72123441bfdbaf2bc13faab3f90b933f664db506dea5915/charset_normalizer-3.4.4-cp313-cp313-win32.whl", hash = "sha256:9b35f4c90079ff2e2edc5b26c0c77925e5d2d255c42c74fdb70fb49b172726ac", size = 99404, upload-time = "2025-10-14T04:41:29.95Z" }, - { url = "https://files.pythonhosted.org/packages/c4/26/b9924fa27db384bdcd97ab83b4f0a8058d96ad9626ead570674d5e737d90/charset_normalizer-3.4.4-cp313-cp313-win_amd64.whl", hash = "sha256:b435cba5f4f750aa6c0a0d92c541fb79f69a387c91e61f1795227e4ed9cece14", size = 107092, upload-time = "2025-10-14T04:41:31.188Z" }, - { url = "https://files.pythonhosted.org/packages/af/8f/3ed4bfa0c0c72a7ca17f0380cd9e4dd842b09f664e780c13cff1dcf2ef1b/charset_normalizer-3.4.4-cp313-cp313-win_arm64.whl", hash = "sha256:542d2cee80be6f80247095cc36c418f7bddd14f4a6de45af91dfad36d817bba2", size = 100408, upload-time = "2025-10-14T04:41:32.624Z" }, - { url = "https://files.pythonhosted.org/packages/2a/35/7051599bd493e62411d6ede36fd5af83a38f37c4767b92884df7301db25d/charset_normalizer-3.4.4-cp314-cp314-macosx_10_13_universal2.whl", hash = "sha256:da3326d9e65ef63a817ecbcc0df6e94463713b754fe293eaa03da99befb9a5bd", size = 207746, upload-time = "2025-10-14T04:41:33.773Z" }, - { url = "https://files.pythonhosted.org/packages/10/9a/97c8d48ef10d6cd4fcead2415523221624bf58bcf68a802721a6bc807c8f/charset_normalizer-3.4.4-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:8af65f14dc14a79b924524b1e7fffe304517b2bff5a58bf64f30b98bbc5079eb", size = 147889, upload-time = "2025-10-14T04:41:34.897Z" }, - { url = "https://files.pythonhosted.org/packages/10/bf/979224a919a1b606c82bd2c5fa49b5c6d5727aa47b4312bb27b1734f53cd/charset_normalizer-3.4.4-cp314-cp314-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:74664978bb272435107de04e36db5a9735e78232b85b77d45cfb38f758efd33e", size = 143641, upload-time = "2025-10-14T04:41:36.116Z" }, - { url = "https://files.pythonhosted.org/packages/ba/33/0ad65587441fc730dc7bd90e9716b30b4702dc7b617e6ba4997dc8651495/charset_normalizer-3.4.4-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:752944c7ffbfdd10c074dc58ec2d5a8a4cd9493b314d367c14d24c17684ddd14", size = 160779, upload-time = "2025-10-14T04:41:37.229Z" }, - { url = "https://files.pythonhosted.org/packages/67/ed/331d6b249259ee71ddea93f6f2f0a56cfebd46938bde6fcc6f7b9a3d0e09/charset_normalizer-3.4.4-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:d1f13550535ad8cff21b8d757a3257963e951d96e20ec82ab44bc64aeb62a191", size = 159035, upload-time = "2025-10-14T04:41:38.368Z" }, - { url = "https://files.pythonhosted.org/packages/67/ff/f6b948ca32e4f2a4576aa129d8bed61f2e0543bf9f5f2b7fc3758ed005c9/charset_normalizer-3.4.4-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:ecaae4149d99b1c9e7b88bb03e3221956f68fd6d50be2ef061b2381b61d20838", size = 152542, upload-time = "2025-10-14T04:41:39.862Z" }, - { url = "https://files.pythonhosted.org/packages/16/85/276033dcbcc369eb176594de22728541a925b2632f9716428c851b149e83/charset_normalizer-3.4.4-cp314-cp314-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:cb6254dc36b47a990e59e1068afacdcd02958bdcce30bb50cc1700a8b9d624a6", size = 149524, upload-time = "2025-10-14T04:41:41.319Z" }, - { url = "https://files.pythonhosted.org/packages/9e/f2/6a2a1f722b6aba37050e626530a46a68f74e63683947a8acff92569f979a/charset_normalizer-3.4.4-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:c8ae8a0f02f57a6e61203a31428fa1d677cbe50c93622b4149d5c0f319c1d19e", size = 150395, upload-time = "2025-10-14T04:41:42.539Z" }, - { url = "https://files.pythonhosted.org/packages/60/bb/2186cb2f2bbaea6338cad15ce23a67f9b0672929744381e28b0592676824/charset_normalizer-3.4.4-cp314-cp314-musllinux_1_2_armv7l.whl", hash = "sha256:47cc91b2f4dd2833fddaedd2893006b0106129d4b94fdb6af1f4ce5a9965577c", size = 143680, upload-time = "2025-10-14T04:41:43.661Z" }, - { url = "https://files.pythonhosted.org/packages/7d/a5/bf6f13b772fbb2a90360eb620d52ed8f796f3c5caee8398c3b2eb7b1c60d/charset_normalizer-3.4.4-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:82004af6c302b5d3ab2cfc4cc5f29db16123b1a8417f2e25f9066f91d4411090", size = 162045, upload-time = "2025-10-14T04:41:44.821Z" }, - { url = "https://files.pythonhosted.org/packages/df/c5/d1be898bf0dc3ef9030c3825e5d3b83f2c528d207d246cbabe245966808d/charset_normalizer-3.4.4-cp314-cp314-musllinux_1_2_riscv64.whl", hash = "sha256:2b7d8f6c26245217bd2ad053761201e9f9680f8ce52f0fcd8d0755aeae5b2152", size = 149687, upload-time = "2025-10-14T04:41:46.442Z" }, - { url = "https://files.pythonhosted.org/packages/a5/42/90c1f7b9341eef50c8a1cb3f098ac43b0508413f33affd762855f67a410e/charset_normalizer-3.4.4-cp314-cp314-musllinux_1_2_s390x.whl", hash = "sha256:799a7a5e4fb2d5898c60b640fd4981d6a25f1c11790935a44ce38c54e985f828", size = 160014, upload-time = "2025-10-14T04:41:47.631Z" }, - { url = "https://files.pythonhosted.org/packages/76/be/4d3ee471e8145d12795ab655ece37baed0929462a86e72372fd25859047c/charset_normalizer-3.4.4-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:99ae2cffebb06e6c22bdc25801d7b30f503cc87dbd283479e7b606f70aff57ec", size = 154044, upload-time = "2025-10-14T04:41:48.81Z" }, - { url = "https://files.pythonhosted.org/packages/b0/6f/8f7af07237c34a1defe7defc565a9bc1807762f672c0fde711a4b22bf9c0/charset_normalizer-3.4.4-cp314-cp314-win32.whl", hash = "sha256:f9d332f8c2a2fcbffe1378594431458ddbef721c1769d78e2cbc06280d8155f9", size = 99940, upload-time = "2025-10-14T04:41:49.946Z" }, - { url = "https://files.pythonhosted.org/packages/4b/51/8ade005e5ca5b0d80fb4aff72a3775b325bdc3d27408c8113811a7cbe640/charset_normalizer-3.4.4-cp314-cp314-win_amd64.whl", hash = "sha256:8a6562c3700cce886c5be75ade4a5db4214fda19fede41d9792d100288d8f94c", size = 107104, upload-time = "2025-10-14T04:41:51.051Z" }, - { url = "https://files.pythonhosted.org/packages/da/5f/6b8f83a55bb8278772c5ae54a577f3099025f9ade59d0136ac24a0df4bde/charset_normalizer-3.4.4-cp314-cp314-win_arm64.whl", hash = "sha256:de00632ca48df9daf77a2c65a484531649261ec9f25489917f09e455cb09ddb2", size = 100743, upload-time = "2025-10-14T04:41:52.122Z" }, - { url = "https://files.pythonhosted.org/packages/0a/4c/925909008ed5a988ccbb72dcc897407e5d6d3bd72410d69e051fc0c14647/charset_normalizer-3.4.4-py3-none-any.whl", hash = "sha256:7a32c560861a02ff789ad905a2fe94e3f840803362c84fecf1851cb4cf3dc37f", size = 53402, upload-time = "2025-10-14T04:42:31.76Z" }, +sdist = { url = "https://files.pythonhosted.org/packages/13/69/33ddede1939fdd074bce5434295f38fae7136463422fe4fd3e0e89b98062/charset_normalizer-3.4.4.tar.gz", hash = "sha256:94537985111c35f28720e43603b8e7b43a6ecfb2ce1d3058bbe955b73404e21a", size = 129418 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/97/45/4b3a1239bbacd321068ea6e7ac28875b03ab8bc0aa0966452db17cd36714/charset_normalizer-3.4.4-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:e1f185f86a6f3403aa2420e815904c67b2f9ebc443f045edd0de921108345794", size = 208091 }, + { url = "https://files.pythonhosted.org/packages/7d/62/73a6d7450829655a35bb88a88fca7d736f9882a27eacdca2c6d505b57e2e/charset_normalizer-3.4.4-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6b39f987ae8ccdf0d2642338faf2abb1862340facc796048b604ef14919e55ed", size = 147936 }, + { url = "https://files.pythonhosted.org/packages/89/c5/adb8c8b3d6625bef6d88b251bbb0d95f8205831b987631ab0c8bb5d937c2/charset_normalizer-3.4.4-cp313-cp313-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:3162d5d8ce1bb98dd51af660f2121c55d0fa541b46dff7bb9b9f86ea1d87de72", size = 144180 }, + { url = "https://files.pythonhosted.org/packages/91/ed/9706e4070682d1cc219050b6048bfd293ccf67b3d4f5a4f39207453d4b99/charset_normalizer-3.4.4-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:81d5eb2a312700f4ecaa977a8235b634ce853200e828fbadf3a9c50bab278328", size = 161346 }, + { url = "https://files.pythonhosted.org/packages/d5/0d/031f0d95e4972901a2f6f09ef055751805ff541511dc1252ba3ca1f80cf5/charset_normalizer-3.4.4-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:5bd2293095d766545ec1a8f612559f6b40abc0eb18bb2f5d1171872d34036ede", size = 158874 }, + { url = "https://files.pythonhosted.org/packages/f5/83/6ab5883f57c9c801ce5e5677242328aa45592be8a00644310a008d04f922/charset_normalizer-3.4.4-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:a8a8b89589086a25749f471e6a900d3f662d1d3b6e2e59dcecf787b1cc3a1894", size = 153076 }, + { url = "https://files.pythonhosted.org/packages/75/1e/5ff781ddf5260e387d6419959ee89ef13878229732732ee73cdae01800f2/charset_normalizer-3.4.4-cp313-cp313-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:bc7637e2f80d8530ee4a78e878bce464f70087ce73cf7c1caf142416923b98f1", size = 150601 }, + { url = "https://files.pythonhosted.org/packages/d7/57/71be810965493d3510a6ca79b90c19e48696fb1ff964da319334b12677f0/charset_normalizer-3.4.4-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:f8bf04158c6b607d747e93949aa60618b61312fe647a6369f88ce2ff16043490", size = 150376 }, + { url = "https://files.pythonhosted.org/packages/e5/d5/c3d057a78c181d007014feb7e9f2e65905a6c4ef182c0ddf0de2924edd65/charset_normalizer-3.4.4-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:554af85e960429cf30784dd47447d5125aaa3b99a6f0683589dbd27e2f45da44", size = 144825 }, + { url = "https://files.pythonhosted.org/packages/e6/8c/d0406294828d4976f275ffbe66f00266c4b3136b7506941d87c00cab5272/charset_normalizer-3.4.4-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:74018750915ee7ad843a774364e13a3db91682f26142baddf775342c3f5b1133", size = 162583 }, + { url = "https://files.pythonhosted.org/packages/d7/24/e2aa1f18c8f15c4c0e932d9287b8609dd30ad56dbe41d926bd846e22fb8d/charset_normalizer-3.4.4-cp313-cp313-musllinux_1_2_riscv64.whl", hash = "sha256:c0463276121fdee9c49b98908b3a89c39be45d86d1dbaa22957e38f6321d4ce3", size = 150366 }, + { url = "https://files.pythonhosted.org/packages/e4/5b/1e6160c7739aad1e2df054300cc618b06bf784a7a164b0f238360721ab86/charset_normalizer-3.4.4-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:362d61fd13843997c1c446760ef36f240cf81d3ebf74ac62652aebaf7838561e", size = 160300 }, + { url = "https://files.pythonhosted.org/packages/7a/10/f882167cd207fbdd743e55534d5d9620e095089d176d55cb22d5322f2afd/charset_normalizer-3.4.4-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:9a26f18905b8dd5d685d6d07b0cdf98a79f3c7a918906af7cc143ea2e164c8bc", size = 154465 }, + { url = "https://files.pythonhosted.org/packages/89/66/c7a9e1b7429be72123441bfdbaf2bc13faab3f90b933f664db506dea5915/charset_normalizer-3.4.4-cp313-cp313-win32.whl", hash = "sha256:9b35f4c90079ff2e2edc5b26c0c77925e5d2d255c42c74fdb70fb49b172726ac", size = 99404 }, + { url = "https://files.pythonhosted.org/packages/c4/26/b9924fa27db384bdcd97ab83b4f0a8058d96ad9626ead570674d5e737d90/charset_normalizer-3.4.4-cp313-cp313-win_amd64.whl", hash = "sha256:b435cba5f4f750aa6c0a0d92c541fb79f69a387c91e61f1795227e4ed9cece14", size = 107092 }, + { url = "https://files.pythonhosted.org/packages/af/8f/3ed4bfa0c0c72a7ca17f0380cd9e4dd842b09f664e780c13cff1dcf2ef1b/charset_normalizer-3.4.4-cp313-cp313-win_arm64.whl", hash = "sha256:542d2cee80be6f80247095cc36c418f7bddd14f4a6de45af91dfad36d817bba2", size = 100408 }, + { url = "https://files.pythonhosted.org/packages/2a/35/7051599bd493e62411d6ede36fd5af83a38f37c4767b92884df7301db25d/charset_normalizer-3.4.4-cp314-cp314-macosx_10_13_universal2.whl", hash = "sha256:da3326d9e65ef63a817ecbcc0df6e94463713b754fe293eaa03da99befb9a5bd", size = 207746 }, + { url = "https://files.pythonhosted.org/packages/10/9a/97c8d48ef10d6cd4fcead2415523221624bf58bcf68a802721a6bc807c8f/charset_normalizer-3.4.4-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:8af65f14dc14a79b924524b1e7fffe304517b2bff5a58bf64f30b98bbc5079eb", size = 147889 }, + { url = "https://files.pythonhosted.org/packages/10/bf/979224a919a1b606c82bd2c5fa49b5c6d5727aa47b4312bb27b1734f53cd/charset_normalizer-3.4.4-cp314-cp314-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:74664978bb272435107de04e36db5a9735e78232b85b77d45cfb38f758efd33e", size = 143641 }, + { url = "https://files.pythonhosted.org/packages/ba/33/0ad65587441fc730dc7bd90e9716b30b4702dc7b617e6ba4997dc8651495/charset_normalizer-3.4.4-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:752944c7ffbfdd10c074dc58ec2d5a8a4cd9493b314d367c14d24c17684ddd14", size = 160779 }, + { url = "https://files.pythonhosted.org/packages/67/ed/331d6b249259ee71ddea93f6f2f0a56cfebd46938bde6fcc6f7b9a3d0e09/charset_normalizer-3.4.4-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:d1f13550535ad8cff21b8d757a3257963e951d96e20ec82ab44bc64aeb62a191", size = 159035 }, + { url = "https://files.pythonhosted.org/packages/67/ff/f6b948ca32e4f2a4576aa129d8bed61f2e0543bf9f5f2b7fc3758ed005c9/charset_normalizer-3.4.4-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:ecaae4149d99b1c9e7b88bb03e3221956f68fd6d50be2ef061b2381b61d20838", size = 152542 }, + { url = "https://files.pythonhosted.org/packages/16/85/276033dcbcc369eb176594de22728541a925b2632f9716428c851b149e83/charset_normalizer-3.4.4-cp314-cp314-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:cb6254dc36b47a990e59e1068afacdcd02958bdcce30bb50cc1700a8b9d624a6", size = 149524 }, + { url = "https://files.pythonhosted.org/packages/9e/f2/6a2a1f722b6aba37050e626530a46a68f74e63683947a8acff92569f979a/charset_normalizer-3.4.4-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:c8ae8a0f02f57a6e61203a31428fa1d677cbe50c93622b4149d5c0f319c1d19e", size = 150395 }, + { url = "https://files.pythonhosted.org/packages/60/bb/2186cb2f2bbaea6338cad15ce23a67f9b0672929744381e28b0592676824/charset_normalizer-3.4.4-cp314-cp314-musllinux_1_2_armv7l.whl", hash = "sha256:47cc91b2f4dd2833fddaedd2893006b0106129d4b94fdb6af1f4ce5a9965577c", size = 143680 }, + { url = "https://files.pythonhosted.org/packages/7d/a5/bf6f13b772fbb2a90360eb620d52ed8f796f3c5caee8398c3b2eb7b1c60d/charset_normalizer-3.4.4-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:82004af6c302b5d3ab2cfc4cc5f29db16123b1a8417f2e25f9066f91d4411090", size = 162045 }, + { url = "https://files.pythonhosted.org/packages/df/c5/d1be898bf0dc3ef9030c3825e5d3b83f2c528d207d246cbabe245966808d/charset_normalizer-3.4.4-cp314-cp314-musllinux_1_2_riscv64.whl", hash = "sha256:2b7d8f6c26245217bd2ad053761201e9f9680f8ce52f0fcd8d0755aeae5b2152", size = 149687 }, + { url = "https://files.pythonhosted.org/packages/a5/42/90c1f7b9341eef50c8a1cb3f098ac43b0508413f33affd762855f67a410e/charset_normalizer-3.4.4-cp314-cp314-musllinux_1_2_s390x.whl", hash = "sha256:799a7a5e4fb2d5898c60b640fd4981d6a25f1c11790935a44ce38c54e985f828", size = 160014 }, + { url = "https://files.pythonhosted.org/packages/76/be/4d3ee471e8145d12795ab655ece37baed0929462a86e72372fd25859047c/charset_normalizer-3.4.4-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:99ae2cffebb06e6c22bdc25801d7b30f503cc87dbd283479e7b606f70aff57ec", size = 154044 }, + { url = "https://files.pythonhosted.org/packages/b0/6f/8f7af07237c34a1defe7defc565a9bc1807762f672c0fde711a4b22bf9c0/charset_normalizer-3.4.4-cp314-cp314-win32.whl", hash = "sha256:f9d332f8c2a2fcbffe1378594431458ddbef721c1769d78e2cbc06280d8155f9", size = 99940 }, + { url = "https://files.pythonhosted.org/packages/4b/51/8ade005e5ca5b0d80fb4aff72a3775b325bdc3d27408c8113811a7cbe640/charset_normalizer-3.4.4-cp314-cp314-win_amd64.whl", hash = "sha256:8a6562c3700cce886c5be75ade4a5db4214fda19fede41d9792d100288d8f94c", size = 107104 }, + { url = "https://files.pythonhosted.org/packages/da/5f/6b8f83a55bb8278772c5ae54a577f3099025f9ade59d0136ac24a0df4bde/charset_normalizer-3.4.4-cp314-cp314-win_arm64.whl", hash = "sha256:de00632ca48df9daf77a2c65a484531649261ec9f25489917f09e455cb09ddb2", size = 100743 }, + { url = "https://files.pythonhosted.org/packages/0a/4c/925909008ed5a988ccbb72dcc897407e5d6d3bd72410d69e051fc0c14647/charset_normalizer-3.4.4-py3-none-any.whl", hash = "sha256:7a32c560861a02ff789ad905a2fe94e3f840803362c84fecf1851cb4cf3dc37f", size = 53402 }, ] [[package]] @@ -359,18 +368,18 @@ source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "colorama", marker = "sys_platform == 'win32'" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/46/61/de6cd827efad202d7057d93e0fed9294b96952e188f7384832791c7b2254/click-8.3.0.tar.gz", hash = "sha256:e7b8232224eba16f4ebe410c25ced9f7875cb5f3263ffc93cc3e8da705e229c4", size = 276943, upload-time = "2025-09-18T17:32:23.696Z" } +sdist = { url = "https://files.pythonhosted.org/packages/46/61/de6cd827efad202d7057d93e0fed9294b96952e188f7384832791c7b2254/click-8.3.0.tar.gz", hash = "sha256:e7b8232224eba16f4ebe410c25ced9f7875cb5f3263ffc93cc3e8da705e229c4", size = 276943 } wheels = [ - { url = "https://files.pythonhosted.org/packages/db/d3/9dcc0f5797f070ec8edf30fbadfb200e71d9db6b84d211e3b2085a7589a0/click-8.3.0-py3-none-any.whl", hash = "sha256:9b9f285302c6e3064f4330c05f05b81945b2a39544279343e6e7c5f27a9baddc", size = 107295, upload-time = "2025-09-18T17:32:22.42Z" }, + { url = "https://files.pythonhosted.org/packages/db/d3/9dcc0f5797f070ec8edf30fbadfb200e71d9db6b84d211e3b2085a7589a0/click-8.3.0-py3-none-any.whl", hash = "sha256:9b9f285302c6e3064f4330c05f05b81945b2a39544279343e6e7c5f27a9baddc", size = 107295 }, ] [[package]] name = "colorama" version = "0.4.6" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/d8/53/6f443c9a4a8358a93a6792e2acffb9d9d5cb0a5cfd8802644b7b1c9a02e4/colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44", size = 27697, upload-time = "2022-10-25T02:36:22.414Z" } +sdist = { url = "https://files.pythonhosted.org/packages/d8/53/6f443c9a4a8358a93a6792e2acffb9d9d5cb0a5cfd8802644b7b1c9a02e4/colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44", size = 27697 } wheels = [ - { url = "https://files.pythonhosted.org/packages/d1/d6/3965ed04c63042e047cb6a3e6ed1a63a35087b6a609aa3a15ed8ac56c221/colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6", size = 25335, upload-time = "2022-10-25T02:36:20.889Z" }, + { url = "https://files.pythonhosted.org/packages/d1/d6/3965ed04c63042e047cb6a3e6ed1a63a35087b6a609aa3a15ed8ac56c221/colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6", size = 25335 }, ] [[package]] @@ -380,70 +389,70 @@ source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "humanfriendly" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/cc/c7/eed8f27100517e8c0e6b923d5f0845d0cb99763da6fdee00478f91db7325/coloredlogs-15.0.1.tar.gz", hash = "sha256:7c991aa71a4577af2f82600d8f8f3a89f936baeaf9b50a9c197da014e5bf16b0", size = 278520, upload-time = "2021-06-11T10:22:45.202Z" } +sdist = { url = "https://files.pythonhosted.org/packages/cc/c7/eed8f27100517e8c0e6b923d5f0845d0cb99763da6fdee00478f91db7325/coloredlogs-15.0.1.tar.gz", hash = "sha256:7c991aa71a4577af2f82600d8f8f3a89f936baeaf9b50a9c197da014e5bf16b0", size = 278520 } wheels = [ - { url = "https://files.pythonhosted.org/packages/a7/06/3d6badcf13db419e25b07041d9c7b4a2c331d3f4e7134445ec5df57714cd/coloredlogs-15.0.1-py2.py3-none-any.whl", hash = "sha256:612ee75c546f53e92e70049c9dbfcc18c935a2b9a53b66085ce9ef6a6e5c0934", size = 46018, upload-time = "2021-06-11T10:22:42.561Z" }, + { url = "https://files.pythonhosted.org/packages/a7/06/3d6badcf13db419e25b07041d9c7b4a2c331d3f4e7134445ec5df57714cd/coloredlogs-15.0.1-py2.py3-none-any.whl", hash = "sha256:612ee75c546f53e92e70049c9dbfcc18c935a2b9a53b66085ce9ef6a6e5c0934", size = 46018 }, ] [[package]] name = "coverage" -version = "7.11.0" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/1c/38/ee22495420457259d2f3390309505ea98f98a5eed40901cf62196abad006/coverage-7.11.0.tar.gz", hash = "sha256:167bd504ac1ca2af7ff3b81d245dfea0292c5032ebef9d66cc08a7d28c1b8050", size = 811905, upload-time = "2025-10-15T15:15:08.542Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/60/7f/85e4dfe65e400645464b25c036a26ac226cf3a69d4a50c3934c532491cdd/coverage-7.11.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:cc3f49e65ea6e0d5d9bd60368684fe52a704d46f9e7fc413918f18d046ec40e1", size = 216129, upload-time = "2025-10-15T15:13:25.371Z" }, - { url = "https://files.pythonhosted.org/packages/96/5d/dc5fa98fea3c175caf9d360649cb1aa3715e391ab00dc78c4c66fabd7356/coverage-7.11.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:f39ae2f63f37472c17b4990f794035c9890418b1b8cca75c01193f3c8d3e01be", size = 216380, upload-time = "2025-10-15T15:13:26.976Z" }, - { url = "https://files.pythonhosted.org/packages/b2/f5/3da9cc9596708273385189289c0e4d8197d37a386bdf17619013554b3447/coverage-7.11.0-cp313-cp313-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:7db53b5cdd2917b6eaadd0b1251cf4e7d96f4a8d24e174bdbdf2f65b5ea7994d", size = 247375, upload-time = "2025-10-15T15:13:28.923Z" }, - { url = "https://files.pythonhosted.org/packages/65/6c/f7f59c342359a235559d2bc76b0c73cfc4bac7d61bb0df210965cb1ecffd/coverage-7.11.0-cp313-cp313-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:10ad04ac3a122048688387828b4537bc9cf60c0bf4869c1e9989c46e45690b82", size = 249978, upload-time = "2025-10-15T15:13:30.525Z" }, - { url = "https://files.pythonhosted.org/packages/e7/8c/042dede2e23525e863bf1ccd2b92689692a148d8b5fd37c37899ba882645/coverage-7.11.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:4036cc9c7983a2b1f2556d574d2eb2154ac6ed55114761685657e38782b23f52", size = 251253, upload-time = "2025-10-15T15:13:32.174Z" }, - { url = "https://files.pythonhosted.org/packages/7b/a9/3c58df67bfa809a7bddd786356d9c5283e45d693edb5f3f55d0986dd905a/coverage-7.11.0-cp313-cp313-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:7ab934dd13b1c5e94b692b1e01bd87e4488cb746e3a50f798cb9464fd128374b", size = 247591, upload-time = "2025-10-15T15:13:34.147Z" }, - { url = "https://files.pythonhosted.org/packages/26/5b/c7f32efd862ee0477a18c41e4761305de6ddd2d49cdeda0c1116227570fd/coverage-7.11.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:59a6e5a265f7cfc05f76e3bb53eca2e0dfe90f05e07e849930fecd6abb8f40b4", size = 249411, upload-time = "2025-10-15T15:13:38.425Z" }, - { url = "https://files.pythonhosted.org/packages/76/b5/78cb4f1e86c1611431c990423ec0768122905b03837e1b4c6a6f388a858b/coverage-7.11.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:df01d6c4c81e15a7c88337b795bb7595a8596e92310266b5072c7e301168efbd", size = 247303, upload-time = "2025-10-15T15:13:40.464Z" }, - { url = "https://files.pythonhosted.org/packages/87/c9/23c753a8641a330f45f221286e707c427e46d0ffd1719b080cedc984ec40/coverage-7.11.0-cp313-cp313-musllinux_1_2_riscv64.whl", hash = "sha256:8c934bd088eed6174210942761e38ee81d28c46de0132ebb1801dbe36a390dcc", size = 247157, upload-time = "2025-10-15T15:13:42.087Z" }, - { url = "https://files.pythonhosted.org/packages/c5/42/6e0cc71dc8a464486e944a4fa0d85bdec031cc2969e98ed41532a98336b9/coverage-7.11.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:5a03eaf7ec24078ad64a07f02e30060aaf22b91dedf31a6b24d0d98d2bba7f48", size = 248921, upload-time = "2025-10-15T15:13:43.715Z" }, - { url = "https://files.pythonhosted.org/packages/e8/1c/743c2ef665e6858cccb0f84377dfe3a4c25add51e8c7ef19249be92465b6/coverage-7.11.0-cp313-cp313-win32.whl", hash = "sha256:695340f698a5f56f795b2836abe6fb576e7c53d48cd155ad2f80fd24bc63a040", size = 218526, upload-time = "2025-10-15T15:13:45.336Z" }, - { url = "https://files.pythonhosted.org/packages/ff/d5/226daadfd1bf8ddbccefbd3aa3547d7b960fb48e1bdac124e2dd13a2b71a/coverage-7.11.0-cp313-cp313-win_amd64.whl", hash = "sha256:2727d47fce3ee2bac648528e41455d1b0c46395a087a229deac75e9f88ba5a05", size = 219317, upload-time = "2025-10-15T15:13:47.401Z" }, - { url = "https://files.pythonhosted.org/packages/97/54/47db81dcbe571a48a298f206183ba8a7ba79200a37cd0d9f4788fcd2af4a/coverage-7.11.0-cp313-cp313-win_arm64.whl", hash = "sha256:0efa742f431529699712b92ecdf22de8ff198df41e43aeaaadf69973eb93f17a", size = 217948, upload-time = "2025-10-15T15:13:49.096Z" }, - { url = "https://files.pythonhosted.org/packages/e5/8b/cb68425420154e7e2a82fd779a8cc01549b6fa83c2ad3679cd6c088ebd07/coverage-7.11.0-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:587c38849b853b157706407e9ebdca8fd12f45869edb56defbef2daa5fb0812b", size = 216837, upload-time = "2025-10-15T15:13:51.09Z" }, - { url = "https://files.pythonhosted.org/packages/33/55/9d61b5765a025685e14659c8d07037247de6383c0385757544ffe4606475/coverage-7.11.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:b971bdefdd75096163dd4261c74be813c4508477e39ff7b92191dea19f24cd37", size = 217061, upload-time = "2025-10-15T15:13:52.747Z" }, - { url = "https://files.pythonhosted.org/packages/52/85/292459c9186d70dcec6538f06ea251bc968046922497377bf4a1dc9a71de/coverage-7.11.0-cp313-cp313t-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:269bfe913b7d5be12ab13a95f3a76da23cf147be7fa043933320ba5625f0a8de", size = 258398, upload-time = "2025-10-15T15:13:54.45Z" }, - { url = "https://files.pythonhosted.org/packages/1f/e2/46edd73fb8bf51446c41148d81944c54ed224854812b6ca549be25113ee0/coverage-7.11.0-cp313-cp313t-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:dadbcce51a10c07b7c72b0ce4a25e4b6dcb0c0372846afb8e5b6307a121eb99f", size = 260574, upload-time = "2025-10-15T15:13:56.145Z" }, - { url = "https://files.pythonhosted.org/packages/07/5e/1df469a19007ff82e2ca8fe509822820a31e251f80ee7344c34f6cd2ec43/coverage-7.11.0-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:9ed43fa22c6436f7957df036331f8fe4efa7af132054e1844918866cd228af6c", size = 262797, upload-time = "2025-10-15T15:13:58.635Z" }, - { url = "https://files.pythonhosted.org/packages/f9/50/de216b31a1434b94d9b34a964c09943c6be45069ec704bfc379d8d89a649/coverage-7.11.0-cp313-cp313t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:9516add7256b6713ec08359b7b05aeff8850c98d357784c7205b2e60aa2513fa", size = 257361, upload-time = "2025-10-15T15:14:00.409Z" }, - { url = "https://files.pythonhosted.org/packages/82/1e/3f9f8344a48111e152e0fd495b6fff13cc743e771a6050abf1627a7ba918/coverage-7.11.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:eb92e47c92fcbcdc692f428da67db33337fa213756f7adb6a011f7b5a7a20740", size = 260349, upload-time = "2025-10-15T15:14:02.188Z" }, - { url = "https://files.pythonhosted.org/packages/65/9b/3f52741f9e7d82124272f3070bbe316006a7de1bad1093f88d59bfc6c548/coverage-7.11.0-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:d06f4fc7acf3cabd6d74941d53329e06bab00a8fe10e4df2714f0b134bfc64ef", size = 258114, upload-time = "2025-10-15T15:14:03.907Z" }, - { url = "https://files.pythonhosted.org/packages/0b/8b/918f0e15f0365d50d3986bbd3338ca01178717ac5678301f3f547b6619e6/coverage-7.11.0-cp313-cp313t-musllinux_1_2_riscv64.whl", hash = "sha256:6fbcee1a8f056af07ecd344482f711f563a9eb1c2cad192e87df00338ec3cdb0", size = 256723, upload-time = "2025-10-15T15:14:06.324Z" }, - { url = "https://files.pythonhosted.org/packages/44/9e/7776829f82d3cf630878a7965a7d70cc6ca94f22c7d20ec4944f7148cb46/coverage-7.11.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:dbbf012be5f32533a490709ad597ad8a8ff80c582a95adc8d62af664e532f9ca", size = 259238, upload-time = "2025-10-15T15:14:08.002Z" }, - { url = "https://files.pythonhosted.org/packages/9a/b8/49cf253e1e7a3bedb85199b201862dd7ca4859f75b6cf25ffa7298aa0760/coverage-7.11.0-cp313-cp313t-win32.whl", hash = "sha256:cee6291bb4fed184f1c2b663606a115c743df98a537c969c3c64b49989da96c2", size = 219180, upload-time = "2025-10-15T15:14:09.786Z" }, - { url = "https://files.pythonhosted.org/packages/ac/e1/1a541703826be7ae2125a0fb7f821af5729d56bb71e946e7b933cc7a89a4/coverage-7.11.0-cp313-cp313t-win_amd64.whl", hash = "sha256:a386c1061bf98e7ea4758e4313c0ab5ecf57af341ef0f43a0bf26c2477b5c268", size = 220241, upload-time = "2025-10-15T15:14:11.471Z" }, - { url = "https://files.pythonhosted.org/packages/d5/d1/5ee0e0a08621140fd418ec4020f595b4d52d7eb429ae6a0c6542b4ba6f14/coverage-7.11.0-cp313-cp313t-win_arm64.whl", hash = "sha256:f9ea02ef40bb83823b2b04964459d281688fe173e20643870bb5d2edf68bc836", size = 218510, upload-time = "2025-10-15T15:14:13.46Z" }, - { url = "https://files.pythonhosted.org/packages/f4/06/e923830c1985ce808e40a3fa3eb46c13350b3224b7da59757d37b6ce12b8/coverage-7.11.0-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:c770885b28fb399aaf2a65bbd1c12bf6f307ffd112d6a76c5231a94276f0c497", size = 216110, upload-time = "2025-10-15T15:14:15.157Z" }, - { url = "https://files.pythonhosted.org/packages/42/82/cdeed03bfead45203fb651ed756dfb5266028f5f939e7f06efac4041dad5/coverage-7.11.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:a3d0e2087dba64c86a6b254f43e12d264b636a39e88c5cc0a01a7c71bcfdab7e", size = 216395, upload-time = "2025-10-15T15:14:16.863Z" }, - { url = "https://files.pythonhosted.org/packages/fc/ba/e1c80caffc3199aa699813f73ff097bc2df7b31642bdbc7493600a8f1de5/coverage-7.11.0-cp314-cp314-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:73feb83bb41c32811973b8565f3705caf01d928d972b72042b44e97c71fd70d1", size = 247433, upload-time = "2025-10-15T15:14:18.589Z" }, - { url = "https://files.pythonhosted.org/packages/80/c0/5b259b029694ce0a5bbc1548834c7ba3db41d3efd3474489d7efce4ceb18/coverage-7.11.0-cp314-cp314-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:c6f31f281012235ad08f9a560976cc2fc9c95c17604ff3ab20120fe480169bca", size = 249970, upload-time = "2025-10-15T15:14:20.307Z" }, - { url = "https://files.pythonhosted.org/packages/8c/86/171b2b5e1aac7e2fd9b43f7158b987dbeb95f06d1fbecad54ad8163ae3e8/coverage-7.11.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:e9570ad567f880ef675673992222746a124b9595506826b210fbe0ce3f0499cd", size = 251324, upload-time = "2025-10-15T15:14:22.419Z" }, - { url = "https://files.pythonhosted.org/packages/1a/7e/7e10414d343385b92024af3932a27a1caf75c6e27ee88ba211221ff1a145/coverage-7.11.0-cp314-cp314-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:8badf70446042553a773547a61fecaa734b55dc738cacf20c56ab04b77425e43", size = 247445, upload-time = "2025-10-15T15:14:24.205Z" }, - { url = "https://files.pythonhosted.org/packages/c4/3b/e4f966b21f5be8c4bf86ad75ae94efa0de4c99c7bbb8114476323102e345/coverage-7.11.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:a09c1211959903a479e389685b7feb8a17f59ec5a4ef9afde7650bd5eabc2777", size = 249324, upload-time = "2025-10-15T15:14:26.234Z" }, - { url = "https://files.pythonhosted.org/packages/00/a2/8479325576dfcd909244d0df215f077f47437ab852ab778cfa2f8bf4d954/coverage-7.11.0-cp314-cp314-musllinux_1_2_i686.whl", hash = "sha256:5ef83b107f50db3f9ae40f69e34b3bd9337456c5a7fe3461c7abf8b75dd666a2", size = 247261, upload-time = "2025-10-15T15:14:28.42Z" }, - { url = "https://files.pythonhosted.org/packages/7b/d8/3a9e2db19d94d65771d0f2e21a9ea587d11b831332a73622f901157cc24b/coverage-7.11.0-cp314-cp314-musllinux_1_2_riscv64.whl", hash = "sha256:f91f927a3215b8907e214af77200250bb6aae36eca3f760f89780d13e495388d", size = 247092, upload-time = "2025-10-15T15:14:30.784Z" }, - { url = "https://files.pythonhosted.org/packages/b3/b1/bbca3c472544f9e2ad2d5116b2379732957048be4b93a9c543fcd0207e5f/coverage-7.11.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:cdbcd376716d6b7fbfeedd687a6c4be019c5a5671b35f804ba76a4c0a778cba4", size = 248755, upload-time = "2025-10-15T15:14:32.585Z" }, - { url = "https://files.pythonhosted.org/packages/89/49/638d5a45a6a0f00af53d6b637c87007eb2297042186334e9923a61aa8854/coverage-7.11.0-cp314-cp314-win32.whl", hash = "sha256:bab7ec4bb501743edc63609320aaec8cd9188b396354f482f4de4d40a9d10721", size = 218793, upload-time = "2025-10-15T15:14:34.972Z" }, - { url = "https://files.pythonhosted.org/packages/30/cc/b675a51f2d068adb3cdf3799212c662239b0ca27f4691d1fff81b92ea850/coverage-7.11.0-cp314-cp314-win_amd64.whl", hash = "sha256:3d4ba9a449e9364a936a27322b20d32d8b166553bfe63059bd21527e681e2fad", size = 219587, upload-time = "2025-10-15T15:14:37.047Z" }, - { url = "https://files.pythonhosted.org/packages/93/98/5ac886876026de04f00820e5094fe22166b98dcb8b426bf6827aaf67048c/coverage-7.11.0-cp314-cp314-win_arm64.whl", hash = "sha256:ce37f215223af94ef0f75ac68ea096f9f8e8c8ec7d6e8c346ee45c0d363f0479", size = 218168, upload-time = "2025-10-15T15:14:38.861Z" }, - { url = "https://files.pythonhosted.org/packages/14/d1/b4145d35b3e3ecf4d917e97fc8895bcf027d854879ba401d9ff0f533f997/coverage-7.11.0-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:f413ce6e07e0d0dc9c433228727b619871532674b45165abafe201f200cc215f", size = 216850, upload-time = "2025-10-15T15:14:40.651Z" }, - { url = "https://files.pythonhosted.org/packages/ca/d1/7f645fc2eccd318369a8a9948acc447bb7c1ade2911e31d3c5620544c22b/coverage-7.11.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:05791e528a18f7072bf5998ba772fe29db4da1234c45c2087866b5ba4dea710e", size = 217071, upload-time = "2025-10-15T15:14:42.755Z" }, - { url = "https://files.pythonhosted.org/packages/54/7d/64d124649db2737ceced1dfcbdcb79898d5868d311730f622f8ecae84250/coverage-7.11.0-cp314-cp314t-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:cacb29f420cfeb9283b803263c3b9a068924474ff19ca126ba9103e1278dfa44", size = 258570, upload-time = "2025-10-15T15:14:44.542Z" }, - { url = "https://files.pythonhosted.org/packages/6c/3f/6f5922f80dc6f2d8b2c6f974835c43f53eb4257a7797727e6ca5b7b2ec1f/coverage-7.11.0-cp314-cp314t-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:314c24e700d7027ae3ab0d95fbf8d53544fca1f20345fd30cd219b737c6e58d3", size = 260738, upload-time = "2025-10-15T15:14:46.436Z" }, - { url = "https://files.pythonhosted.org/packages/0e/5f/9e883523c4647c860b3812b417a2017e361eca5b635ee658387dc11b13c1/coverage-7.11.0-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:630d0bd7a293ad2fc8b4b94e5758c8b2536fdf36c05f1681270203e463cbfa9b", size = 262994, upload-time = "2025-10-15T15:14:48.3Z" }, - { url = "https://files.pythonhosted.org/packages/07/bb/43b5a8e94c09c8bf51743ffc65c4c841a4ca5d3ed191d0a6919c379a1b83/coverage-7.11.0-cp314-cp314t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:e89641f5175d65e2dbb44db15fe4ea48fade5d5bbb9868fdc2b4fce22f4a469d", size = 257282, upload-time = "2025-10-15T15:14:50.236Z" }, - { url = "https://files.pythonhosted.org/packages/aa/e5/0ead8af411411330b928733e1d201384b39251a5f043c1612970310e8283/coverage-7.11.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:c9f08ea03114a637dab06cedb2e914da9dc67fa52c6015c018ff43fdde25b9c2", size = 260430, upload-time = "2025-10-15T15:14:52.413Z" }, - { url = "https://files.pythonhosted.org/packages/ae/66/03dd8bb0ba5b971620dcaac145461950f6d8204953e535d2b20c6b65d729/coverage-7.11.0-cp314-cp314t-musllinux_1_2_i686.whl", hash = "sha256:ce9f3bde4e9b031eaf1eb61df95c1401427029ea1bfddb8621c1161dcb0fa02e", size = 258190, upload-time = "2025-10-15T15:14:54.268Z" }, - { url = "https://files.pythonhosted.org/packages/45/ae/28a9cce40bf3174426cb2f7e71ee172d98e7f6446dff936a7ccecee34b14/coverage-7.11.0-cp314-cp314t-musllinux_1_2_riscv64.whl", hash = "sha256:e4dc07e95495923d6fd4d6c27bf70769425b71c89053083843fd78f378558996", size = 256658, upload-time = "2025-10-15T15:14:56.436Z" }, - { url = "https://files.pythonhosted.org/packages/5c/7c/3a44234a8599513684bfc8684878fd7b126c2760f79712bb78c56f19efc4/coverage-7.11.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:424538266794db2861db4922b05d729ade0940ee69dcf0591ce8f69784db0e11", size = 259342, upload-time = "2025-10-15T15:14:58.538Z" }, - { url = "https://files.pythonhosted.org/packages/e1/e6/0108519cba871af0351725ebdb8660fd7a0fe2ba3850d56d32490c7d9b4b/coverage-7.11.0-cp314-cp314t-win32.whl", hash = "sha256:4c1eeb3fb8eb9e0190bebafd0462936f75717687117339f708f395fe455acc73", size = 219568, upload-time = "2025-10-15T15:15:00.382Z" }, - { url = "https://files.pythonhosted.org/packages/c9/76/44ba876e0942b4e62fdde23ccb029ddb16d19ba1bef081edd00857ba0b16/coverage-7.11.0-cp314-cp314t-win_amd64.whl", hash = "sha256:b56efee146c98dbf2cf5cffc61b9829d1e94442df4d7398b26892a53992d3547", size = 220687, upload-time = "2025-10-15T15:15:02.322Z" }, - { url = "https://files.pythonhosted.org/packages/b9/0c/0df55ecb20d0d0ed5c322e10a441775e1a3a5d78c60f0c4e1abfe6fcf949/coverage-7.11.0-cp314-cp314t-win_arm64.whl", hash = "sha256:b5c2705afa83f49bd91962a4094b6b082f94aef7626365ab3f8f4bd159c5acf3", size = 218711, upload-time = "2025-10-15T15:15:04.575Z" }, - { url = "https://files.pythonhosted.org/packages/5f/04/642c1d8a448ae5ea1369eac8495740a79eb4e581a9fb0cbdce56bbf56da1/coverage-7.11.0-py3-none-any.whl", hash = "sha256:4b7589765348d78fb4e5fb6ea35d07564e387da2fc5efff62e0222971f155f68", size = 207761, upload-time = "2025-10-15T15:15:06.439Z" }, +version = "7.11.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/89/12/3e2d2ec71796e0913178478e693a06af6a3bc9f7f9cb899bf85a426d8370/coverage-7.11.1.tar.gz", hash = "sha256:b4b3a072559578129a9e863082a2972a2abd8975bc0e2ec57da96afcd6580a8a", size = 814037 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/f4/01/0c50c318f5e8f1a482da05d788d0ff06137803ed8fface4a1ba51e04b3ad/coverage-7.11.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:da9930594ca99d66eb6f613d7beba850db2f8dfa86810ee35ae24e4d5f2bb97d", size = 216920 }, + { url = "https://files.pythonhosted.org/packages/20/11/9f038e6c2baea968c377ab355b0d1d0a46b5f38985691bf51164e1b78c1f/coverage-7.11.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:cc47a280dc014220b0fc6e5f55082a3f51854faf08fd9635b8a4f341c46c77d3", size = 217301 }, + { url = "https://files.pythonhosted.org/packages/68/cd/9dcf93d81d0cddaa0bba90c3b4580e6f1ddf833918b816930d250cc553a4/coverage-7.11.1-cp313-cp313-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:74003324321bbf130939146886eddf92e48e616b5910215e79dea6edeb8ee7c8", size = 248277 }, + { url = "https://files.pythonhosted.org/packages/11/f5/b2c7c494046c9c783d3cac4c812fc24d6104dd36a7a598e7dd6fea3e7927/coverage-7.11.1-cp313-cp313-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:211f7996265daab60a8249af4ca6641b3080769cbedcffc42cc4841118f3a305", size = 250871 }, + { url = "https://files.pythonhosted.org/packages/a5/5a/b359649566954498aa17d7c98093182576d9e435ceb4ea917b3b48d56f86/coverage-7.11.1-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:70619d194d8fea0cb028cb6bb9c85b519c7509c1d1feef1eea635183bc8ecd27", size = 252115 }, + { url = "https://files.pythonhosted.org/packages/f3/17/3cef1ede3739622950f0737605353b797ec564e70c9d254521b10f4b03ba/coverage-7.11.1-cp313-cp313-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:e0208bb59d441cfa3321569040f8e455f9261256e0df776c5462a1e5a9b31e13", size = 248442 }, + { url = "https://files.pythonhosted.org/packages/5f/63/d5854c47ae42d9d18855329db6bc528f5b7f4f874257edb00cf8b483f9f8/coverage-7.11.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:545714d8765bda1c51f8b1c96e0b497886a054471c68211e76ef49dd1468587d", size = 250253 }, + { url = "https://files.pythonhosted.org/packages/48/e8/c7706f8a5358a59c18b489e7e19e83d6161b7c8bc60771f95920570c94a8/coverage-7.11.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:d0a2b02c1e20158dd405054bcca87f91fd5b7605626aee87150819ea616edd67", size = 248217 }, + { url = "https://files.pythonhosted.org/packages/5b/c9/a2136dfb168eb09e2f6d9d6b6c986243fdc0b3866a9376adb263d3c3378b/coverage-7.11.1-cp313-cp313-musllinux_1_2_riscv64.whl", hash = "sha256:e0f4aa986a4308a458e0fb572faa3eb3db2ea7ce294604064b25ab32b435a468", size = 248040 }, + { url = "https://files.pythonhosted.org/packages/18/9a/a63991c0608ddc6adf65e6f43124951aaf36bd79f41937b028120b8268ea/coverage-7.11.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:d51cc6687e8bbfd1e041f52baed0f979cd592242cf50bf18399a7e03afc82d88", size = 249801 }, + { url = "https://files.pythonhosted.org/packages/84/19/947acf7c0c6e90e4ec3abf474133ed36d94407d07e36eafdfd3acb59fee9/coverage-7.11.1-cp313-cp313-win32.whl", hash = "sha256:1b3067db3afe6deeca2b2c9f0ec23820d5f1bd152827acfadf24de145dfc5f66", size = 219430 }, + { url = "https://files.pythonhosted.org/packages/35/54/36fef7afb3884450c7b6d494fcabe2fab7c669d547c800ca30f41c1dc212/coverage-7.11.1-cp313-cp313-win_amd64.whl", hash = "sha256:39a4c44b0cd40e3c9d89b2b7303ebd6ab9ae8a63f9e9a8c4d65a181a0b33aebe", size = 220239 }, + { url = "https://files.pythonhosted.org/packages/d3/dc/7d38bb99e8e69200b7dd5de15507226bd90eac102dfc7cc891b9934cdc76/coverage-7.11.1-cp313-cp313-win_arm64.whl", hash = "sha256:a2e3560bf82fa8169a577e054cbbc29888699526063fee26ea59ea2627fd6e73", size = 218868 }, + { url = "https://files.pythonhosted.org/packages/36/c6/d1ff54fbd6bcad42dbcfd13b417e636ef84aae194353b1ef3361700f2525/coverage-7.11.1-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:47a4f362a10285897ab3aa7a4b37d28213a4f2626823923613d6d7a3584dd79a", size = 217615 }, + { url = "https://files.pythonhosted.org/packages/73/f9/6ed59e7cf1488d6f975e5b14ef836f5e537913523e92175135f8518a83ce/coverage-7.11.1-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:0df35fa7419ef571db9dacd50b0517bc54dbfe37eb94043b5fc3540bff276acd", size = 217960 }, + { url = "https://files.pythonhosted.org/packages/c4/74/2dab1dc2ebe16f074f80ae483b0f45faf278d102be703ac01b32cd85b6c3/coverage-7.11.1-cp313-cp313t-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:e1a2c621d341c9d56f7917e56fbb56be4f73fe0d0e8dae28352fb095060fd467", size = 259262 }, + { url = "https://files.pythonhosted.org/packages/15/49/eccfe039663e29a50a54b0c2c8d076acd174d7ac50d018ef8a5b1c37c8dc/coverage-7.11.1-cp313-cp313t-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:6c354b111be9b2234d9573d75dd30ca4e414b7659c730e477e89be4f620b3fb5", size = 261326 }, + { url = "https://files.pythonhosted.org/packages/f0/bb/2b829aa23fd5ee8318e33cc02a606eb09900921291497963adc3f06af8bb/coverage-7.11.1-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:4589bd44698728f600233fb2881014c9b8ec86637ef454c00939e779661dbe7e", size = 263758 }, + { url = "https://files.pythonhosted.org/packages/ac/03/d44c3d70e5da275caf2cad2071da6b425412fbcb1d1d5a81f1f89b45e3f1/coverage-7.11.1-cp313-cp313t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:c6956fc8754f2309131230272a7213a483a32ecbe29e2b9316d808a28f2f8ea1", size = 258444 }, + { url = "https://files.pythonhosted.org/packages/a9/c1/cf61d9f46ae088774c65dd3387a15dfbc72de90c1f6e105025e9eda19b42/coverage-7.11.1-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:63926a97ed89dc6a087369b92dcb8b9a94cead46c08b33a7f1f4818cd8b6a3c3", size = 261335 }, + { url = "https://files.pythonhosted.org/packages/95/9a/b3299bb14f11f2364d78a2b9704491b15395e757af6116694731ce4e5834/coverage-7.11.1-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:f5311ba00c53a7fb2b293fdc1f478b7286fe2a845a7ba9cda053f6e98178f0b4", size = 258951 }, + { url = "https://files.pythonhosted.org/packages/3f/a3/73cb2763e59f14ba6d8d6444b1f640a9be2242bfb59b7e50581c695db7ff/coverage-7.11.1-cp313-cp313t-musllinux_1_2_riscv64.whl", hash = "sha256:31bf5ffad84c974f9e72ac53493350f36b6fa396109159ec704210698f12860b", size = 257840 }, + { url = "https://files.pythonhosted.org/packages/85/db/482e72589a952027e238ffa3a15f192c552e0685fd0c5220ad05b5f17d56/coverage-7.11.1-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:227ee59fbc4a8c57a7383a1d7af6ca94a78ae3beee4045f38684548a8479a65b", size = 260040 }, + { url = "https://files.pythonhosted.org/packages/18/a1/b931d3ee099c2dca8e9ea56c07ae84c0f91562f7bbbcccab8c91b3474ef1/coverage-7.11.1-cp313-cp313t-win32.whl", hash = "sha256:a447d97b3ce680bb1da2e6bd822ebb71be6a1fb77ce2c2ad2fe4bd8aacec3058", size = 220102 }, + { url = "https://files.pythonhosted.org/packages/9a/53/b553b7bfa6207def4918f0cb72884c844fa4c3f1566e58fbb4f34e54cdc5/coverage-7.11.1-cp313-cp313t-win_amd64.whl", hash = "sha256:d6d11180437c67bde2248563a42b8e5bbf85c8df78fae13bf818ad17bfb15f02", size = 221166 }, + { url = "https://files.pythonhosted.org/packages/6b/45/1c1d58b3ed585598764bd2fe41fcf60ccafe15973ad621c322ba52e22d32/coverage-7.11.1-cp313-cp313t-win_arm64.whl", hash = "sha256:1e19a4c43d612760c6f7190411fb157e2d8a6dde00c91b941d43203bd3b17f6f", size = 219439 }, + { url = "https://files.pythonhosted.org/packages/d9/c2/ac2c3417eaa4de1361036ebbc7da664242b274b2e00c4b4a1cfc7b29920b/coverage-7.11.1-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:0305463c45c5f21f0396cd5028de92b1f1387e2e0756a85dd3147daa49f7a674", size = 216967 }, + { url = "https://files.pythonhosted.org/packages/5e/a3/afef455d03c468ee303f9df9a6f407e8bea64cd576fca914ff888faf52ca/coverage-7.11.1-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:fa4d468d5efa1eb6e3062be8bd5f45cbf28257a37b71b969a8c1da2652dfec77", size = 217298 }, + { url = "https://files.pythonhosted.org/packages/9d/59/6e2fb3fb58637001132dc32228b4fb5b332d75d12f1353cb00fe084ee0ba/coverage-7.11.1-cp314-cp314-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:d2b2f5fc8fe383cbf2d5c77d6c4b2632ede553bc0afd0cdc910fa5390046c290", size = 248337 }, + { url = "https://files.pythonhosted.org/packages/1d/5e/ce442bab963e3388658da8bde6ddbd0a15beda230afafaa25e3c487dc391/coverage-7.11.1-cp314-cp314-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:bde6488c1ad509f4fb1a4f9960fd003d5a94adef61e226246f9699befbab3276", size = 250853 }, + { url = "https://files.pythonhosted.org/packages/d1/2f/43f94557924ca9b64e09f1c3876da4eec44a05a41e27b8a639d899716c0e/coverage-7.11.1-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:a69e0d6fa0b920fe6706a898c52955ec5bcfa7e45868215159f45fd87ea6da7c", size = 252190 }, + { url = "https://files.pythonhosted.org/packages/8c/fa/a04e769b92bc5628d4bd909dcc3c8219efe5e49f462e29adc43e198ecfde/coverage-7.11.1-cp314-cp314-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:976e51e4a549b80e4639eda3a53e95013a14ff6ad69bb58ed604d34deb0e774c", size = 248335 }, + { url = "https://files.pythonhosted.org/packages/99/d0/b98ab5d2abe425c71117a7c690ead697a0b32b83256bf0f566c726b7f77b/coverage-7.11.1-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:d61fcc4d384c82971a3d9cf00d0872881f9ded19404c714d6079b7a4547e2955", size = 250209 }, + { url = "https://files.pythonhosted.org/packages/9c/3f/b9c4fbd2e6d1b64098f99fb68df7f7c1b3e0a0968d24025adb24f359cdec/coverage-7.11.1-cp314-cp314-musllinux_1_2_i686.whl", hash = "sha256:284c5df762b533fae3ebd764e3b81c20c1c9648d93ef34469759cb4e3dfe13d0", size = 248163 }, + { url = "https://files.pythonhosted.org/packages/08/fc/3e4d54fb6368b0628019eefd897fc271badbd025410fd5421a65fb58758f/coverage-7.11.1-cp314-cp314-musllinux_1_2_riscv64.whl", hash = "sha256:bab32cb1d4ad2ac6dcc4e17eee5fa136c2a1d14ae914e4bce6c8b78273aece3c", size = 247983 }, + { url = "https://files.pythonhosted.org/packages/b9/4a/a5700764a12e932b35afdddb2f59adbca289c1689455d06437f609f3ef35/coverage-7.11.1-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:36f2fed9ce392ca450fb4e283900d0b41f05c8c5db674d200f471498be3ce747", size = 249646 }, + { url = "https://files.pythonhosted.org/packages/0e/2c/45ed33d9e80a1cc9b44b4bd535d44c154d3204671c65abd90ec1e99522a2/coverage-7.11.1-cp314-cp314-win32.whl", hash = "sha256:853136cecb92a5ba1cc8f61ec6ffa62ca3c88b4b386a6c835f8b833924f9a8c5", size = 219700 }, + { url = "https://files.pythonhosted.org/packages/90/d7/5845597360f6434af1290118ebe114642865f45ce47e7e822d9c07b371be/coverage-7.11.1-cp314-cp314-win_amd64.whl", hash = "sha256:77443d39143e20927259a61da0c95d55ffc31cf43086b8f0f11a92da5260d592", size = 220516 }, + { url = "https://files.pythonhosted.org/packages/ae/d0/d311a06f9cf7a48a98ffcfd0c57db0dcab6da46e75c439286a50dc648161/coverage-7.11.1-cp314-cp314-win_arm64.whl", hash = "sha256:829acb88fa47591a64bf5197e96a931ce9d4b3634c7f81a224ba3319623cdf6c", size = 219091 }, + { url = "https://files.pythonhosted.org/packages/a7/3d/c6a84da4fa9b840933045b19dd19d17b892f3f2dd1612903260291416dba/coverage-7.11.1-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:2ad1fe321d9522ea14399de83e75a11fb6a8887930c3679feb383301c28070d9", size = 217700 }, + { url = "https://files.pythonhosted.org/packages/94/10/a4fc5022017dd7ac682dc423849c241dfbdad31734b8f96060d84e70b587/coverage-7.11.1-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:f69c332f0c3d1357c74decc9b1843fcd428cf9221bf196a20ad22aa1db3e1b6c", size = 217968 }, + { url = "https://files.pythonhosted.org/packages/59/2d/a554cd98924d296de5816413280ac3b09e42a05fb248d66f8d474d321938/coverage-7.11.1-cp314-cp314t-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:576baeea4eebde684bf6c91c01e97171c8015765c8b2cfd4022a42b899897811", size = 259334 }, + { url = "https://files.pythonhosted.org/packages/05/98/d484cb659ec33958ca96b6f03438f56edc23b239d1ad0417b7a97fc1848a/coverage-7.11.1-cp314-cp314t-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:28ad84c694fa86084cfd3c1eab4149844b8cb95bd8e5cbfc4a647f3ee2cce2b3", size = 261445 }, + { url = "https://files.pythonhosted.org/packages/f3/fa/920cba122cc28f4557c0507f8bd7c6e527ebcc537d0309186f66464a8fd9/coverage-7.11.1-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:b1043ff958f09fc3f552c014d599f3c6b7088ba97d7bc1bd1cce8603cd75b520", size = 263858 }, + { url = "https://files.pythonhosted.org/packages/2a/a0/036397bdbee0f3bd46c2e26fdfbb1a61b2140bf9059240c37b61149047fa/coverage-7.11.1-cp314-cp314t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:c6681add5060c2742dafcf29826dff1ff8eef889a3b03390daeed84361c428bd", size = 258381 }, + { url = "https://files.pythonhosted.org/packages/b6/61/2533926eb8990f182eb287f4873216c8ca530cc47241144aabf46fe80abe/coverage-7.11.1-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:773419b225ec9a75caa1e941dd0c83a91b92c2b525269e44e6ee3e4c630607db", size = 261321 }, + { url = "https://files.pythonhosted.org/packages/32/6e/618f7e203a998e4f6b8a0fa395744a416ad2adbcdc3735bc19466456718a/coverage-7.11.1-cp314-cp314t-musllinux_1_2_i686.whl", hash = "sha256:a9cb272a0e0157dbb9b2fd0b201b759bd378a1a6138a16536c025c2ce4f7643b", size = 258933 }, + { url = "https://files.pythonhosted.org/packages/22/40/6b1c27f772cb08a14a338647ead1254a57ee9dabbb4cacbc15df7f278741/coverage-7.11.1-cp314-cp314t-musllinux_1_2_riscv64.whl", hash = "sha256:e09adb2a7811dc75998eef68f47599cf699e2b62eed09c9fefaeb290b3920f34", size = 257756 }, + { url = "https://files.pythonhosted.org/packages/73/07/f9cd12f71307a785ea15b009c8d8cc2543e4a867bd04b8673843970b6b43/coverage-7.11.1-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:1335fa8c2a2fea49924d97e1e3500cfe8d7c849f5369f26bb7559ad4259ccfab", size = 260086 }, + { url = "https://files.pythonhosted.org/packages/34/02/31c5394f6f5d72a466966bcfdb61ce5a19862d452816d6ffcbb44add16ee/coverage-7.11.1-cp314-cp314t-win32.whl", hash = "sha256:4782d71d2a4fa7cef95e853b7097c8bbead4dbd0e6f9c7152a6b11a194b794db", size = 220483 }, + { url = "https://files.pythonhosted.org/packages/7f/96/81e1ef5fbfd5090113a96e823dbe055e4c58d96ca73b1fb0ad9d26f9ec36/coverage-7.11.1-cp314-cp314t-win_amd64.whl", hash = "sha256:939f45e66eceb63c75e8eb8fc58bb7077c00f1a41b0e15c6ef02334a933cfe93", size = 221592 }, + { url = "https://files.pythonhosted.org/packages/38/7a/a5d050de44951ac453a2046a0f3fb5471a4a557f0c914d00db27d543d94c/coverage-7.11.1-cp314-cp314t-win_arm64.whl", hash = "sha256:01c575bdbef35e3f023b50a146e9a75c53816e4f2569109458155cd2315f87d9", size = 219627 }, + { url = "https://files.pythonhosted.org/packages/76/32/bd9f48c28e23b2f08946f8e83983617b00619f5538dbd7e1045fa7e88c00/coverage-7.11.1-py3-none-any.whl", hash = "sha256:0fa848acb5f1da24765cee840e1afe9232ac98a8f9431c6112c15b34e880b9e8", size = 208689 }, ] [[package]] @@ -453,99 +462,99 @@ source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "cffi", marker = "platform_python_implementation != 'PyPy'" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/9f/33/c00162f49c0e2fe8064a62cb92b93e50c74a72bc370ab92f86112b33ff62/cryptography-46.0.3.tar.gz", hash = "sha256:a8b17438104fed022ce745b362294d9ce35b4c2e45c1d958ad4a4b019285f4a1", size = 749258, upload-time = "2025-10-15T23:18:31.74Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/1d/42/9c391dd801d6cf0d561b5890549d4b27bafcc53b39c31a817e69d87c625b/cryptography-46.0.3-cp311-abi3-macosx_10_9_universal2.whl", hash = "sha256:109d4ddfadf17e8e7779c39f9b18111a09efb969a301a31e987416a0191ed93a", size = 7225004, upload-time = "2025-10-15T23:16:52.239Z" }, - { url = "https://files.pythonhosted.org/packages/1c/67/38769ca6b65f07461eb200e85fc1639b438bdc667be02cf7f2cd6a64601c/cryptography-46.0.3-cp311-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:09859af8466b69bc3c27bdf4f5d84a665e0f7ab5088412e9e2ec49758eca5cbc", size = 4296667, upload-time = "2025-10-15T23:16:54.369Z" }, - { url = "https://files.pythonhosted.org/packages/5c/49/498c86566a1d80e978b42f0d702795f69887005548c041636df6ae1ca64c/cryptography-46.0.3-cp311-abi3-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:01ca9ff2885f3acc98c29f1860552e37f6d7c7d013d7334ff2a9de43a449315d", size = 4450807, upload-time = "2025-10-15T23:16:56.414Z" }, - { url = "https://files.pythonhosted.org/packages/4b/0a/863a3604112174c8624a2ac3c038662d9e59970c7f926acdcfaed8d61142/cryptography-46.0.3-cp311-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:6eae65d4c3d33da080cff9c4ab1f711b15c1d9760809dad6ea763f3812d254cb", size = 4299615, upload-time = "2025-10-15T23:16:58.442Z" }, - { url = "https://files.pythonhosted.org/packages/64/02/b73a533f6b64a69f3cd3872acb6ebc12aef924d8d103133bb3ea750dc703/cryptography-46.0.3-cp311-abi3-manylinux_2_28_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:e5bf0ed4490068a2e72ac03d786693adeb909981cc596425d09032d372bcc849", size = 4016800, upload-time = "2025-10-15T23:17:00.378Z" }, - { url = "https://files.pythonhosted.org/packages/25/d5/16e41afbfa450cde85a3b7ec599bebefaef16b5c6ba4ec49a3532336ed72/cryptography-46.0.3-cp311-abi3-manylinux_2_28_ppc64le.whl", hash = "sha256:5ecfccd2329e37e9b7112a888e76d9feca2347f12f37918facbb893d7bb88ee8", size = 4984707, upload-time = "2025-10-15T23:17:01.98Z" }, - { url = "https://files.pythonhosted.org/packages/c9/56/e7e69b427c3878352c2fb9b450bd0e19ed552753491d39d7d0a2f5226d41/cryptography-46.0.3-cp311-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:a2c0cd47381a3229c403062f764160d57d4d175e022c1df84e168c6251a22eec", size = 4482541, upload-time = "2025-10-15T23:17:04.078Z" }, - { url = "https://files.pythonhosted.org/packages/78/f6/50736d40d97e8483172f1bb6e698895b92a223dba513b0ca6f06b2365339/cryptography-46.0.3-cp311-abi3-manylinux_2_34_aarch64.whl", hash = "sha256:549e234ff32571b1f4076ac269fcce7a808d3bf98b76c8dd560e42dbc66d7d91", size = 4299464, upload-time = "2025-10-15T23:17:05.483Z" }, - { url = "https://files.pythonhosted.org/packages/00/de/d8e26b1a855f19d9994a19c702fa2e93b0456beccbcfe437eda00e0701f2/cryptography-46.0.3-cp311-abi3-manylinux_2_34_ppc64le.whl", hash = "sha256:c0a7bb1a68a5d3471880e264621346c48665b3bf1c3759d682fc0864c540bd9e", size = 4950838, upload-time = "2025-10-15T23:17:07.425Z" }, - { url = "https://files.pythonhosted.org/packages/8f/29/798fc4ec461a1c9e9f735f2fc58741b0daae30688f41b2497dcbc9ed1355/cryptography-46.0.3-cp311-abi3-manylinux_2_34_x86_64.whl", hash = "sha256:10b01676fc208c3e6feeb25a8b83d81767e8059e1fe86e1dc62d10a3018fa926", size = 4481596, upload-time = "2025-10-15T23:17:09.343Z" }, - { url = "https://files.pythonhosted.org/packages/15/8d/03cd48b20a573adfff7652b76271078e3045b9f49387920e7f1f631d125e/cryptography-46.0.3-cp311-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:0abf1ffd6e57c67e92af68330d05760b7b7efb243aab8377e583284dbab72c71", size = 4426782, upload-time = "2025-10-15T23:17:11.22Z" }, - { url = "https://files.pythonhosted.org/packages/fa/b1/ebacbfe53317d55cf33165bda24c86523497a6881f339f9aae5c2e13e57b/cryptography-46.0.3-cp311-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:a04bee9ab6a4da801eb9b51f1b708a1b5b5c9eb48c03f74198464c66f0d344ac", size = 4698381, upload-time = "2025-10-15T23:17:12.829Z" }, - { url = "https://files.pythonhosted.org/packages/96/92/8a6a9525893325fc057a01f654d7efc2c64b9de90413adcf605a85744ff4/cryptography-46.0.3-cp311-abi3-win32.whl", hash = "sha256:f260d0d41e9b4da1ed1e0f1ce571f97fe370b152ab18778e9e8f67d6af432018", size = 3055988, upload-time = "2025-10-15T23:17:14.65Z" }, - { url = "https://files.pythonhosted.org/packages/7e/bf/80fbf45253ea585a1e492a6a17efcb93467701fa79e71550a430c5e60df0/cryptography-46.0.3-cp311-abi3-win_amd64.whl", hash = "sha256:a9a3008438615669153eb86b26b61e09993921ebdd75385ddd748702c5adfddb", size = 3514451, upload-time = "2025-10-15T23:17:16.142Z" }, - { url = "https://files.pythonhosted.org/packages/2e/af/9b302da4c87b0beb9db4e756386a7c6c5b8003cd0e742277888d352ae91d/cryptography-46.0.3-cp311-abi3-win_arm64.whl", hash = "sha256:5d7f93296ee28f68447397bf5198428c9aeeab45705a55d53a6343455dcb2c3c", size = 2928007, upload-time = "2025-10-15T23:17:18.04Z" }, - { url = "https://files.pythonhosted.org/packages/f5/e2/a510aa736755bffa9d2f75029c229111a1d02f8ecd5de03078f4c18d91a3/cryptography-46.0.3-cp314-cp314t-macosx_10_9_universal2.whl", hash = "sha256:00a5e7e87938e5ff9ff5447ab086a5706a957137e6e433841e9d24f38a065217", size = 7158012, upload-time = "2025-10-15T23:17:19.982Z" }, - { url = "https://files.pythonhosted.org/packages/73/dc/9aa866fbdbb95b02e7f9d086f1fccfeebf8953509b87e3f28fff927ff8a0/cryptography-46.0.3-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:c8daeb2d2174beb4575b77482320303f3d39b8e81153da4f0fb08eb5fe86a6c5", size = 4288728, upload-time = "2025-10-15T23:17:21.527Z" }, - { url = "https://files.pythonhosted.org/packages/c5/fd/bc1daf8230eaa075184cbbf5f8cd00ba9db4fd32d63fb83da4671b72ed8a/cryptography-46.0.3-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:39b6755623145ad5eff1dab323f4eae2a32a77a7abef2c5089a04a3d04366715", size = 4435078, upload-time = "2025-10-15T23:17:23.042Z" }, - { url = "https://files.pythonhosted.org/packages/82/98/d3bd5407ce4c60017f8ff9e63ffee4200ab3e23fe05b765cab805a7db008/cryptography-46.0.3-cp314-cp314t-manylinux_2_28_aarch64.whl", hash = "sha256:db391fa7c66df6762ee3f00c95a89e6d428f4d60e7abc8328f4fe155b5ac6e54", size = 4293460, upload-time = "2025-10-15T23:17:24.885Z" }, - { url = "https://files.pythonhosted.org/packages/26/e9/e23e7900983c2b8af7a08098db406cf989d7f09caea7897e347598d4cd5b/cryptography-46.0.3-cp314-cp314t-manylinux_2_28_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:78a97cf6a8839a48c49271cdcbd5cf37ca2c1d6b7fdd86cc864f302b5e9bf459", size = 3995237, upload-time = "2025-10-15T23:17:26.449Z" }, - { url = "https://files.pythonhosted.org/packages/91/15/af68c509d4a138cfe299d0d7ddb14afba15233223ebd933b4bbdbc7155d3/cryptography-46.0.3-cp314-cp314t-manylinux_2_28_ppc64le.whl", hash = "sha256:dfb781ff7eaa91a6f7fd41776ec37c5853c795d3b358d4896fdbb5df168af422", size = 4967344, upload-time = "2025-10-15T23:17:28.06Z" }, - { url = "https://files.pythonhosted.org/packages/ca/e3/8643d077c53868b681af077edf6b3cb58288b5423610f21c62aadcbe99f4/cryptography-46.0.3-cp314-cp314t-manylinux_2_28_x86_64.whl", hash = "sha256:6f61efb26e76c45c4a227835ddeae96d83624fb0d29eb5df5b96e14ed1a0afb7", size = 4466564, upload-time = "2025-10-15T23:17:29.665Z" }, - { url = "https://files.pythonhosted.org/packages/0e/43/c1e8726fa59c236ff477ff2b5dc071e54b21e5a1e51aa2cee1676f1c986f/cryptography-46.0.3-cp314-cp314t-manylinux_2_34_aarch64.whl", hash = "sha256:23b1a8f26e43f47ceb6d6a43115f33a5a37d57df4ea0ca295b780ae8546e8044", size = 4292415, upload-time = "2025-10-15T23:17:31.686Z" }, - { url = "https://files.pythonhosted.org/packages/42/f9/2f8fefdb1aee8a8e3256a0568cffc4e6d517b256a2fe97a029b3f1b9fe7e/cryptography-46.0.3-cp314-cp314t-manylinux_2_34_ppc64le.whl", hash = "sha256:b419ae593c86b87014b9be7396b385491ad7f320bde96826d0dd174459e54665", size = 4931457, upload-time = "2025-10-15T23:17:33.478Z" }, - { url = "https://files.pythonhosted.org/packages/79/30/9b54127a9a778ccd6d27c3da7563e9f2d341826075ceab89ae3b41bf5be2/cryptography-46.0.3-cp314-cp314t-manylinux_2_34_x86_64.whl", hash = "sha256:50fc3343ac490c6b08c0cf0d704e881d0d660be923fd3076db3e932007e726e3", size = 4466074, upload-time = "2025-10-15T23:17:35.158Z" }, - { url = "https://files.pythonhosted.org/packages/ac/68/b4f4a10928e26c941b1b6a179143af9f4d27d88fe84a6a3c53592d2e76bf/cryptography-46.0.3-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:22d7e97932f511d6b0b04f2bfd818d73dcd5928db509460aaf48384778eb6d20", size = 4420569, upload-time = "2025-10-15T23:17:37.188Z" }, - { url = "https://files.pythonhosted.org/packages/a3/49/3746dab4c0d1979888f125226357d3262a6dd40e114ac29e3d2abdf1ec55/cryptography-46.0.3-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:d55f3dffadd674514ad19451161118fd010988540cee43d8bc20675e775925de", size = 4681941, upload-time = "2025-10-15T23:17:39.236Z" }, - { url = "https://files.pythonhosted.org/packages/fd/30/27654c1dbaf7e4a3531fa1fc77986d04aefa4d6d78259a62c9dc13d7ad36/cryptography-46.0.3-cp314-cp314t-win32.whl", hash = "sha256:8a6e050cb6164d3f830453754094c086ff2d0b2f3a897a1d9820f6139a1f0914", size = 3022339, upload-time = "2025-10-15T23:17:40.888Z" }, - { url = "https://files.pythonhosted.org/packages/f6/30/640f34ccd4d2a1bc88367b54b926b781b5a018d65f404d409aba76a84b1c/cryptography-46.0.3-cp314-cp314t-win_amd64.whl", hash = "sha256:760f83faa07f8b64e9c33fc963d790a2edb24efb479e3520c14a45741cd9b2db", size = 3494315, upload-time = "2025-10-15T23:17:42.769Z" }, - { url = "https://files.pythonhosted.org/packages/ba/8b/88cc7e3bd0a8e7b861f26981f7b820e1f46aa9d26cc482d0feba0ecb4919/cryptography-46.0.3-cp314-cp314t-win_arm64.whl", hash = "sha256:516ea134e703e9fe26bcd1277a4b59ad30586ea90c365a87781d7887a646fe21", size = 2919331, upload-time = "2025-10-15T23:17:44.468Z" }, - { url = "https://files.pythonhosted.org/packages/fd/23/45fe7f376a7df8daf6da3556603b36f53475a99ce4faacb6ba2cf3d82021/cryptography-46.0.3-cp38-abi3-macosx_10_9_universal2.whl", hash = "sha256:cb3d760a6117f621261d662bccc8ef5bc32ca673e037c83fbe565324f5c46936", size = 7218248, upload-time = "2025-10-15T23:17:46.294Z" }, - { url = "https://files.pythonhosted.org/packages/27/32/b68d27471372737054cbd34c84981f9edbc24fe67ca225d389799614e27f/cryptography-46.0.3-cp38-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:4b7387121ac7d15e550f5cb4a43aef2559ed759c35df7336c402bb8275ac9683", size = 4294089, upload-time = "2025-10-15T23:17:48.269Z" }, - { url = "https://files.pythonhosted.org/packages/26/42/fa8389d4478368743e24e61eea78846a0006caffaf72ea24a15159215a14/cryptography-46.0.3-cp38-abi3-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:15ab9b093e8f09daab0f2159bb7e47532596075139dd74365da52ecc9cb46c5d", size = 4440029, upload-time = "2025-10-15T23:17:49.837Z" }, - { url = "https://files.pythonhosted.org/packages/5f/eb/f483db0ec5ac040824f269e93dd2bd8a21ecd1027e77ad7bdf6914f2fd80/cryptography-46.0.3-cp38-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:46acf53b40ea38f9c6c229599a4a13f0d46a6c3fa9ef19fc1a124d62e338dfa0", size = 4297222, upload-time = "2025-10-15T23:17:51.357Z" }, - { url = "https://files.pythonhosted.org/packages/fd/cf/da9502c4e1912cb1da3807ea3618a6829bee8207456fbbeebc361ec38ba3/cryptography-46.0.3-cp38-abi3-manylinux_2_28_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:10ca84c4668d066a9878890047f03546f3ae0a6b8b39b697457b7757aaf18dbc", size = 4012280, upload-time = "2025-10-15T23:17:52.964Z" }, - { url = "https://files.pythonhosted.org/packages/6b/8f/9adb86b93330e0df8b3dcf03eae67c33ba89958fc2e03862ef1ac2b42465/cryptography-46.0.3-cp38-abi3-manylinux_2_28_ppc64le.whl", hash = "sha256:36e627112085bb3b81b19fed209c05ce2a52ee8b15d161b7c643a7d5a88491f3", size = 4978958, upload-time = "2025-10-15T23:17:54.965Z" }, - { url = "https://files.pythonhosted.org/packages/d1/a0/5fa77988289c34bdb9f913f5606ecc9ada1adb5ae870bd0d1054a7021cc4/cryptography-46.0.3-cp38-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:1000713389b75c449a6e979ffc7dcc8ac90b437048766cef052d4d30b8220971", size = 4473714, upload-time = "2025-10-15T23:17:56.754Z" }, - { url = "https://files.pythonhosted.org/packages/14/e5/fc82d72a58d41c393697aa18c9abe5ae1214ff6f2a5c18ac470f92777895/cryptography-46.0.3-cp38-abi3-manylinux_2_34_aarch64.whl", hash = "sha256:b02cf04496f6576afffef5ddd04a0cb7d49cf6be16a9059d793a30b035f6b6ac", size = 4296970, upload-time = "2025-10-15T23:17:58.588Z" }, - { url = "https://files.pythonhosted.org/packages/78/06/5663ed35438d0b09056973994f1aec467492b33bd31da36e468b01ec1097/cryptography-46.0.3-cp38-abi3-manylinux_2_34_ppc64le.whl", hash = "sha256:71e842ec9bc7abf543b47cf86b9a743baa95f4677d22baa4c7d5c69e49e9bc04", size = 4940236, upload-time = "2025-10-15T23:18:00.897Z" }, - { url = "https://files.pythonhosted.org/packages/fc/59/873633f3f2dcd8a053b8dd1d38f783043b5fce589c0f6988bf55ef57e43e/cryptography-46.0.3-cp38-abi3-manylinux_2_34_x86_64.whl", hash = "sha256:402b58fc32614f00980b66d6e56a5b4118e6cb362ae8f3fda141ba4689bd4506", size = 4472642, upload-time = "2025-10-15T23:18:02.749Z" }, - { url = "https://files.pythonhosted.org/packages/3d/39/8e71f3930e40f6877737d6f69248cf74d4e34b886a3967d32f919cc50d3b/cryptography-46.0.3-cp38-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:ef639cb3372f69ec44915fafcd6698b6cc78fbe0c2ea41be867f6ed612811963", size = 4423126, upload-time = "2025-10-15T23:18:04.85Z" }, - { url = "https://files.pythonhosted.org/packages/cd/c7/f65027c2810e14c3e7268353b1681932b87e5a48e65505d8cc17c99e36ae/cryptography-46.0.3-cp38-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:3b51b8ca4f1c6453d8829e1eb7299499ca7f313900dd4d89a24b8b87c0a780d4", size = 4686573, upload-time = "2025-10-15T23:18:06.908Z" }, - { url = "https://files.pythonhosted.org/packages/0a/6e/1c8331ddf91ca4730ab3086a0f1be19c65510a33b5a441cb334e7a2d2560/cryptography-46.0.3-cp38-abi3-win32.whl", hash = "sha256:6276eb85ef938dc035d59b87c8a7dc559a232f954962520137529d77b18ff1df", size = 3036695, upload-time = "2025-10-15T23:18:08.672Z" }, - { url = "https://files.pythonhosted.org/packages/90/45/b0d691df20633eff80955a0fc7695ff9051ffce8b69741444bd9ed7bd0db/cryptography-46.0.3-cp38-abi3-win_amd64.whl", hash = "sha256:416260257577718c05135c55958b674000baef9a1c7d9e8f306ec60d71db850f", size = 3501720, upload-time = "2025-10-15T23:18:10.632Z" }, - { url = "https://files.pythonhosted.org/packages/e8/cb/2da4cc83f5edb9c3257d09e1e7ab7b23f049c7962cae8d842bbef0a9cec9/cryptography-46.0.3-cp38-abi3-win_arm64.whl", hash = "sha256:d89c3468de4cdc4f08a57e214384d0471911a3830fcdaf7a8cc587e42a866372", size = 2918740, upload-time = "2025-10-15T23:18:12.277Z" }, +sdist = { url = "https://files.pythonhosted.org/packages/9f/33/c00162f49c0e2fe8064a62cb92b93e50c74a72bc370ab92f86112b33ff62/cryptography-46.0.3.tar.gz", hash = "sha256:a8b17438104fed022ce745b362294d9ce35b4c2e45c1d958ad4a4b019285f4a1", size = 749258 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/1d/42/9c391dd801d6cf0d561b5890549d4b27bafcc53b39c31a817e69d87c625b/cryptography-46.0.3-cp311-abi3-macosx_10_9_universal2.whl", hash = "sha256:109d4ddfadf17e8e7779c39f9b18111a09efb969a301a31e987416a0191ed93a", size = 7225004 }, + { url = "https://files.pythonhosted.org/packages/1c/67/38769ca6b65f07461eb200e85fc1639b438bdc667be02cf7f2cd6a64601c/cryptography-46.0.3-cp311-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:09859af8466b69bc3c27bdf4f5d84a665e0f7ab5088412e9e2ec49758eca5cbc", size = 4296667 }, + { url = "https://files.pythonhosted.org/packages/5c/49/498c86566a1d80e978b42f0d702795f69887005548c041636df6ae1ca64c/cryptography-46.0.3-cp311-abi3-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:01ca9ff2885f3acc98c29f1860552e37f6d7c7d013d7334ff2a9de43a449315d", size = 4450807 }, + { url = "https://files.pythonhosted.org/packages/4b/0a/863a3604112174c8624a2ac3c038662d9e59970c7f926acdcfaed8d61142/cryptography-46.0.3-cp311-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:6eae65d4c3d33da080cff9c4ab1f711b15c1d9760809dad6ea763f3812d254cb", size = 4299615 }, + { url = "https://files.pythonhosted.org/packages/64/02/b73a533f6b64a69f3cd3872acb6ebc12aef924d8d103133bb3ea750dc703/cryptography-46.0.3-cp311-abi3-manylinux_2_28_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:e5bf0ed4490068a2e72ac03d786693adeb909981cc596425d09032d372bcc849", size = 4016800 }, + { url = "https://files.pythonhosted.org/packages/25/d5/16e41afbfa450cde85a3b7ec599bebefaef16b5c6ba4ec49a3532336ed72/cryptography-46.0.3-cp311-abi3-manylinux_2_28_ppc64le.whl", hash = "sha256:5ecfccd2329e37e9b7112a888e76d9feca2347f12f37918facbb893d7bb88ee8", size = 4984707 }, + { url = "https://files.pythonhosted.org/packages/c9/56/e7e69b427c3878352c2fb9b450bd0e19ed552753491d39d7d0a2f5226d41/cryptography-46.0.3-cp311-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:a2c0cd47381a3229c403062f764160d57d4d175e022c1df84e168c6251a22eec", size = 4482541 }, + { url = "https://files.pythonhosted.org/packages/78/f6/50736d40d97e8483172f1bb6e698895b92a223dba513b0ca6f06b2365339/cryptography-46.0.3-cp311-abi3-manylinux_2_34_aarch64.whl", hash = "sha256:549e234ff32571b1f4076ac269fcce7a808d3bf98b76c8dd560e42dbc66d7d91", size = 4299464 }, + { url = "https://files.pythonhosted.org/packages/00/de/d8e26b1a855f19d9994a19c702fa2e93b0456beccbcfe437eda00e0701f2/cryptography-46.0.3-cp311-abi3-manylinux_2_34_ppc64le.whl", hash = "sha256:c0a7bb1a68a5d3471880e264621346c48665b3bf1c3759d682fc0864c540bd9e", size = 4950838 }, + { url = "https://files.pythonhosted.org/packages/8f/29/798fc4ec461a1c9e9f735f2fc58741b0daae30688f41b2497dcbc9ed1355/cryptography-46.0.3-cp311-abi3-manylinux_2_34_x86_64.whl", hash = "sha256:10b01676fc208c3e6feeb25a8b83d81767e8059e1fe86e1dc62d10a3018fa926", size = 4481596 }, + { url = "https://files.pythonhosted.org/packages/15/8d/03cd48b20a573adfff7652b76271078e3045b9f49387920e7f1f631d125e/cryptography-46.0.3-cp311-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:0abf1ffd6e57c67e92af68330d05760b7b7efb243aab8377e583284dbab72c71", size = 4426782 }, + { url = "https://files.pythonhosted.org/packages/fa/b1/ebacbfe53317d55cf33165bda24c86523497a6881f339f9aae5c2e13e57b/cryptography-46.0.3-cp311-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:a04bee9ab6a4da801eb9b51f1b708a1b5b5c9eb48c03f74198464c66f0d344ac", size = 4698381 }, + { url = "https://files.pythonhosted.org/packages/96/92/8a6a9525893325fc057a01f654d7efc2c64b9de90413adcf605a85744ff4/cryptography-46.0.3-cp311-abi3-win32.whl", hash = "sha256:f260d0d41e9b4da1ed1e0f1ce571f97fe370b152ab18778e9e8f67d6af432018", size = 3055988 }, + { url = "https://files.pythonhosted.org/packages/7e/bf/80fbf45253ea585a1e492a6a17efcb93467701fa79e71550a430c5e60df0/cryptography-46.0.3-cp311-abi3-win_amd64.whl", hash = "sha256:a9a3008438615669153eb86b26b61e09993921ebdd75385ddd748702c5adfddb", size = 3514451 }, + { url = "https://files.pythonhosted.org/packages/2e/af/9b302da4c87b0beb9db4e756386a7c6c5b8003cd0e742277888d352ae91d/cryptography-46.0.3-cp311-abi3-win_arm64.whl", hash = "sha256:5d7f93296ee28f68447397bf5198428c9aeeab45705a55d53a6343455dcb2c3c", size = 2928007 }, + { url = "https://files.pythonhosted.org/packages/f5/e2/a510aa736755bffa9d2f75029c229111a1d02f8ecd5de03078f4c18d91a3/cryptography-46.0.3-cp314-cp314t-macosx_10_9_universal2.whl", hash = "sha256:00a5e7e87938e5ff9ff5447ab086a5706a957137e6e433841e9d24f38a065217", size = 7158012 }, + { url = "https://files.pythonhosted.org/packages/73/dc/9aa866fbdbb95b02e7f9d086f1fccfeebf8953509b87e3f28fff927ff8a0/cryptography-46.0.3-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:c8daeb2d2174beb4575b77482320303f3d39b8e81153da4f0fb08eb5fe86a6c5", size = 4288728 }, + { url = "https://files.pythonhosted.org/packages/c5/fd/bc1daf8230eaa075184cbbf5f8cd00ba9db4fd32d63fb83da4671b72ed8a/cryptography-46.0.3-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:39b6755623145ad5eff1dab323f4eae2a32a77a7abef2c5089a04a3d04366715", size = 4435078 }, + { url = "https://files.pythonhosted.org/packages/82/98/d3bd5407ce4c60017f8ff9e63ffee4200ab3e23fe05b765cab805a7db008/cryptography-46.0.3-cp314-cp314t-manylinux_2_28_aarch64.whl", hash = "sha256:db391fa7c66df6762ee3f00c95a89e6d428f4d60e7abc8328f4fe155b5ac6e54", size = 4293460 }, + { url = "https://files.pythonhosted.org/packages/26/e9/e23e7900983c2b8af7a08098db406cf989d7f09caea7897e347598d4cd5b/cryptography-46.0.3-cp314-cp314t-manylinux_2_28_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:78a97cf6a8839a48c49271cdcbd5cf37ca2c1d6b7fdd86cc864f302b5e9bf459", size = 3995237 }, + { url = "https://files.pythonhosted.org/packages/91/15/af68c509d4a138cfe299d0d7ddb14afba15233223ebd933b4bbdbc7155d3/cryptography-46.0.3-cp314-cp314t-manylinux_2_28_ppc64le.whl", hash = "sha256:dfb781ff7eaa91a6f7fd41776ec37c5853c795d3b358d4896fdbb5df168af422", size = 4967344 }, + { url = "https://files.pythonhosted.org/packages/ca/e3/8643d077c53868b681af077edf6b3cb58288b5423610f21c62aadcbe99f4/cryptography-46.0.3-cp314-cp314t-manylinux_2_28_x86_64.whl", hash = "sha256:6f61efb26e76c45c4a227835ddeae96d83624fb0d29eb5df5b96e14ed1a0afb7", size = 4466564 }, + { url = "https://files.pythonhosted.org/packages/0e/43/c1e8726fa59c236ff477ff2b5dc071e54b21e5a1e51aa2cee1676f1c986f/cryptography-46.0.3-cp314-cp314t-manylinux_2_34_aarch64.whl", hash = "sha256:23b1a8f26e43f47ceb6d6a43115f33a5a37d57df4ea0ca295b780ae8546e8044", size = 4292415 }, + { url = "https://files.pythonhosted.org/packages/42/f9/2f8fefdb1aee8a8e3256a0568cffc4e6d517b256a2fe97a029b3f1b9fe7e/cryptography-46.0.3-cp314-cp314t-manylinux_2_34_ppc64le.whl", hash = "sha256:b419ae593c86b87014b9be7396b385491ad7f320bde96826d0dd174459e54665", size = 4931457 }, + { url = "https://files.pythonhosted.org/packages/79/30/9b54127a9a778ccd6d27c3da7563e9f2d341826075ceab89ae3b41bf5be2/cryptography-46.0.3-cp314-cp314t-manylinux_2_34_x86_64.whl", hash = "sha256:50fc3343ac490c6b08c0cf0d704e881d0d660be923fd3076db3e932007e726e3", size = 4466074 }, + { url = "https://files.pythonhosted.org/packages/ac/68/b4f4a10928e26c941b1b6a179143af9f4d27d88fe84a6a3c53592d2e76bf/cryptography-46.0.3-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:22d7e97932f511d6b0b04f2bfd818d73dcd5928db509460aaf48384778eb6d20", size = 4420569 }, + { url = "https://files.pythonhosted.org/packages/a3/49/3746dab4c0d1979888f125226357d3262a6dd40e114ac29e3d2abdf1ec55/cryptography-46.0.3-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:d55f3dffadd674514ad19451161118fd010988540cee43d8bc20675e775925de", size = 4681941 }, + { url = "https://files.pythonhosted.org/packages/fd/30/27654c1dbaf7e4a3531fa1fc77986d04aefa4d6d78259a62c9dc13d7ad36/cryptography-46.0.3-cp314-cp314t-win32.whl", hash = "sha256:8a6e050cb6164d3f830453754094c086ff2d0b2f3a897a1d9820f6139a1f0914", size = 3022339 }, + { url = "https://files.pythonhosted.org/packages/f6/30/640f34ccd4d2a1bc88367b54b926b781b5a018d65f404d409aba76a84b1c/cryptography-46.0.3-cp314-cp314t-win_amd64.whl", hash = "sha256:760f83faa07f8b64e9c33fc963d790a2edb24efb479e3520c14a45741cd9b2db", size = 3494315 }, + { url = "https://files.pythonhosted.org/packages/ba/8b/88cc7e3bd0a8e7b861f26981f7b820e1f46aa9d26cc482d0feba0ecb4919/cryptography-46.0.3-cp314-cp314t-win_arm64.whl", hash = "sha256:516ea134e703e9fe26bcd1277a4b59ad30586ea90c365a87781d7887a646fe21", size = 2919331 }, + { url = "https://files.pythonhosted.org/packages/fd/23/45fe7f376a7df8daf6da3556603b36f53475a99ce4faacb6ba2cf3d82021/cryptography-46.0.3-cp38-abi3-macosx_10_9_universal2.whl", hash = "sha256:cb3d760a6117f621261d662bccc8ef5bc32ca673e037c83fbe565324f5c46936", size = 7218248 }, + { url = "https://files.pythonhosted.org/packages/27/32/b68d27471372737054cbd34c84981f9edbc24fe67ca225d389799614e27f/cryptography-46.0.3-cp38-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:4b7387121ac7d15e550f5cb4a43aef2559ed759c35df7336c402bb8275ac9683", size = 4294089 }, + { url = "https://files.pythonhosted.org/packages/26/42/fa8389d4478368743e24e61eea78846a0006caffaf72ea24a15159215a14/cryptography-46.0.3-cp38-abi3-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:15ab9b093e8f09daab0f2159bb7e47532596075139dd74365da52ecc9cb46c5d", size = 4440029 }, + { url = "https://files.pythonhosted.org/packages/5f/eb/f483db0ec5ac040824f269e93dd2bd8a21ecd1027e77ad7bdf6914f2fd80/cryptography-46.0.3-cp38-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:46acf53b40ea38f9c6c229599a4a13f0d46a6c3fa9ef19fc1a124d62e338dfa0", size = 4297222 }, + { url = "https://files.pythonhosted.org/packages/fd/cf/da9502c4e1912cb1da3807ea3618a6829bee8207456fbbeebc361ec38ba3/cryptography-46.0.3-cp38-abi3-manylinux_2_28_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:10ca84c4668d066a9878890047f03546f3ae0a6b8b39b697457b7757aaf18dbc", size = 4012280 }, + { url = "https://files.pythonhosted.org/packages/6b/8f/9adb86b93330e0df8b3dcf03eae67c33ba89958fc2e03862ef1ac2b42465/cryptography-46.0.3-cp38-abi3-manylinux_2_28_ppc64le.whl", hash = "sha256:36e627112085bb3b81b19fed209c05ce2a52ee8b15d161b7c643a7d5a88491f3", size = 4978958 }, + { url = "https://files.pythonhosted.org/packages/d1/a0/5fa77988289c34bdb9f913f5606ecc9ada1adb5ae870bd0d1054a7021cc4/cryptography-46.0.3-cp38-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:1000713389b75c449a6e979ffc7dcc8ac90b437048766cef052d4d30b8220971", size = 4473714 }, + { url = "https://files.pythonhosted.org/packages/14/e5/fc82d72a58d41c393697aa18c9abe5ae1214ff6f2a5c18ac470f92777895/cryptography-46.0.3-cp38-abi3-manylinux_2_34_aarch64.whl", hash = "sha256:b02cf04496f6576afffef5ddd04a0cb7d49cf6be16a9059d793a30b035f6b6ac", size = 4296970 }, + { url = "https://files.pythonhosted.org/packages/78/06/5663ed35438d0b09056973994f1aec467492b33bd31da36e468b01ec1097/cryptography-46.0.3-cp38-abi3-manylinux_2_34_ppc64le.whl", hash = "sha256:71e842ec9bc7abf543b47cf86b9a743baa95f4677d22baa4c7d5c69e49e9bc04", size = 4940236 }, + { url = "https://files.pythonhosted.org/packages/fc/59/873633f3f2dcd8a053b8dd1d38f783043b5fce589c0f6988bf55ef57e43e/cryptography-46.0.3-cp38-abi3-manylinux_2_34_x86_64.whl", hash = "sha256:402b58fc32614f00980b66d6e56a5b4118e6cb362ae8f3fda141ba4689bd4506", size = 4472642 }, + { url = "https://files.pythonhosted.org/packages/3d/39/8e71f3930e40f6877737d6f69248cf74d4e34b886a3967d32f919cc50d3b/cryptography-46.0.3-cp38-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:ef639cb3372f69ec44915fafcd6698b6cc78fbe0c2ea41be867f6ed612811963", size = 4423126 }, + { url = "https://files.pythonhosted.org/packages/cd/c7/f65027c2810e14c3e7268353b1681932b87e5a48e65505d8cc17c99e36ae/cryptography-46.0.3-cp38-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:3b51b8ca4f1c6453d8829e1eb7299499ca7f313900dd4d89a24b8b87c0a780d4", size = 4686573 }, + { url = "https://files.pythonhosted.org/packages/0a/6e/1c8331ddf91ca4730ab3086a0f1be19c65510a33b5a441cb334e7a2d2560/cryptography-46.0.3-cp38-abi3-win32.whl", hash = "sha256:6276eb85ef938dc035d59b87c8a7dc559a232f954962520137529d77b18ff1df", size = 3036695 }, + { url = "https://files.pythonhosted.org/packages/90/45/b0d691df20633eff80955a0fc7695ff9051ffce8b69741444bd9ed7bd0db/cryptography-46.0.3-cp38-abi3-win_amd64.whl", hash = "sha256:416260257577718c05135c55958b674000baef9a1c7d9e8f306ec60d71db850f", size = 3501720 }, + { url = "https://files.pythonhosted.org/packages/e8/cb/2da4cc83f5edb9c3257d09e1e7ab7b23f049c7962cae8d842bbef0a9cec9/cryptography-46.0.3-cp38-abi3-win_arm64.whl", hash = "sha256:d89c3468de4cdc4f08a57e214384d0471911a3830fcdaf7a8cc587e42a866372", size = 2918740 }, ] [[package]] name = "dnspython" version = "2.8.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/8c/8b/57666417c0f90f08bcafa776861060426765fdb422eb10212086fb811d26/dnspython-2.8.0.tar.gz", hash = "sha256:181d3c6996452cb1189c4046c61599b84a5a86e099562ffde77d26984ff26d0f", size = 368251, upload-time = "2025-09-07T18:58:00.022Z" } +sdist = { url = "https://files.pythonhosted.org/packages/8c/8b/57666417c0f90f08bcafa776861060426765fdb422eb10212086fb811d26/dnspython-2.8.0.tar.gz", hash = "sha256:181d3c6996452cb1189c4046c61599b84a5a86e099562ffde77d26984ff26d0f", size = 368251 } wheels = [ - { url = "https://files.pythonhosted.org/packages/ba/5a/18ad964b0086c6e62e2e7500f7edc89e3faa45033c71c1893d34eed2b2de/dnspython-2.8.0-py3-none-any.whl", hash = "sha256:01d9bbc4a2d76bf0db7c1f729812ded6d912bd318d3b1cf81d30c0f845dbf3af", size = 331094, upload-time = "2025-09-07T18:57:58.071Z" }, + { url = "https://files.pythonhosted.org/packages/ba/5a/18ad964b0086c6e62e2e7500f7edc89e3faa45033c71c1893d34eed2b2de/dnspython-2.8.0-py3-none-any.whl", hash = "sha256:01d9bbc4a2d76bf0db7c1f729812ded6d912bd318d3b1cf81d30c0f845dbf3af", size = 331094 }, ] [[package]] name = "docopt" version = "0.6.2" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/a2/55/8f8cab2afd404cf578136ef2cc5dfb50baa1761b68c9da1fb1e4eed343c9/docopt-0.6.2.tar.gz", hash = "sha256:49b3a825280bd66b3aa83585ef59c4a8c82f2c8a522dbe754a8bc8d08c85c491", size = 25901, upload-time = "2014-06-16T11:18:57.406Z" } +sdist = { url = "https://files.pythonhosted.org/packages/a2/55/8f8cab2afd404cf578136ef2cc5dfb50baa1761b68c9da1fb1e4eed343c9/docopt-0.6.2.tar.gz", hash = "sha256:49b3a825280bd66b3aa83585ef59c4a8c82f2c8a522dbe754a8bc8d08c85c491", size = 25901 } [[package]] name = "dotmap" version = "1.3.30" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/bc/68/c186606e4f2bf731abd18044ea201e70c3c244bf468f41368820d197fca5/dotmap-1.3.30.tar.gz", hash = "sha256:5821a7933f075fb47563417c0e92e0b7c031158b4c9a6a7e56163479b658b368", size = 12391, upload-time = "2022-04-06T16:26:49.211Z" } +sdist = { url = "https://files.pythonhosted.org/packages/bc/68/c186606e4f2bf731abd18044ea201e70c3c244bf468f41368820d197fca5/dotmap-1.3.30.tar.gz", hash = "sha256:5821a7933f075fb47563417c0e92e0b7c031158b4c9a6a7e56163479b658b368", size = 12391 } wheels = [ - { url = "https://files.pythonhosted.org/packages/4d/f9/976d6813c160d6c89196d81e9466dca1503d20e609d8751f3536daf37ec6/dotmap-1.3.30-py3-none-any.whl", hash = "sha256:bd9fa15286ea2ad899a4d1dc2445ed85a1ae884a42effb87c89a6ecce71243c6", size = 11464, upload-time = "2022-04-06T16:26:47.103Z" }, + { url = "https://files.pythonhosted.org/packages/4d/f9/976d6813c160d6c89196d81e9466dca1503d20e609d8751f3536daf37ec6/dotmap-1.3.30-py3-none-any.whl", hash = "sha256:bd9fa15286ea2ad899a4d1dc2445ed85a1ae884a42effb87c89a6ecce71243c6", size = 11464 }, ] [[package]] name = "email-validator" -version = "2.2.0" +version = "2.3.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "dnspython" }, { name = "idna" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/48/ce/13508a1ec3f8bb981ae4ca79ea40384becc868bfae97fd1c942bb3a001b1/email_validator-2.2.0.tar.gz", hash = "sha256:cb690f344c617a714f22e66ae771445a1ceb46821152df8e165c5f9a364582b7", size = 48967, upload-time = "2024-06-20T11:30:30.034Z" } +sdist = { url = "https://files.pythonhosted.org/packages/f5/22/900cb125c76b7aaa450ce02fd727f452243f2e91a61af068b40adba60ea9/email_validator-2.3.0.tar.gz", hash = "sha256:9fc05c37f2f6cf439ff414f8fc46d917929974a82244c20eb10231ba60c54426", size = 51238 } wheels = [ - { url = "https://files.pythonhosted.org/packages/d7/ee/bf0adb559ad3c786f12bcbc9296b3f5675f529199bef03e2df281fa1fadb/email_validator-2.2.0-py3-none-any.whl", hash = "sha256:561977c2d73ce3611850a06fa56b414621e0c8faa9d66f2611407d87465da631", size = 33521, upload-time = "2024-06-20T11:30:28.248Z" }, + { url = "https://files.pythonhosted.org/packages/de/15/545e2b6cf2e3be84bc1ed85613edd75b8aea69807a71c26f4ca6a9258e82/email_validator-2.3.0-py3-none-any.whl", hash = "sha256:80f13f623413e6b197ae73bb10bf4eb0908faf509ad8362c5edeb0be7fd450b4", size = 35604 }, ] [[package]] name = "et-xmlfile" version = "2.0.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/d3/38/af70d7ab1ae9d4da450eeec1fa3918940a5fafb9055e934af8d6eb0c2313/et_xmlfile-2.0.0.tar.gz", hash = "sha256:dab3f4764309081ce75662649be815c4c9081e88f0837825f90fd28317d4da54", size = 17234, upload-time = "2024-10-25T17:25:40.039Z" } +sdist = { url = "https://files.pythonhosted.org/packages/d3/38/af70d7ab1ae9d4da450eeec1fa3918940a5fafb9055e934af8d6eb0c2313/et_xmlfile-2.0.0.tar.gz", hash = "sha256:dab3f4764309081ce75662649be815c4c9081e88f0837825f90fd28317d4da54", size = 17234 } wheels = [ - { url = "https://files.pythonhosted.org/packages/c1/8b/5fe2cc11fee489817272089c4203e679c63b570a5aaeb18d852ae3cbba6a/et_xmlfile-2.0.0-py3-none-any.whl", hash = "sha256:7a91720bc756843502c3b7504c77b8fe44217c85c537d85037f0f536151b2caa", size = 18059, upload-time = "2024-10-25T17:25:39.051Z" }, + { url = "https://files.pythonhosted.org/packages/c1/8b/5fe2cc11fee489817272089c4203e679c63b570a5aaeb18d852ae3cbba6a/et_xmlfile-2.0.0-py3-none-any.whl", hash = "sha256:7a91720bc756843502c3b7504c77b8fe44217c85c537d85037f0f536151b2caa", size = 18059 }, ] [[package]] @@ -555,35 +564,36 @@ source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "faker" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/ba/98/75cacae9945f67cfe323829fc2ac451f64517a8a330b572a06a323997065/factory_boy-3.3.3.tar.gz", hash = "sha256:866862d226128dfac7f2b4160287e899daf54f2612778327dd03d0e2cb1e3d03", size = 164146, upload-time = "2025-02-03T09:49:04.433Z" } +sdist = { url = "https://files.pythonhosted.org/packages/ba/98/75cacae9945f67cfe323829fc2ac451f64517a8a330b572a06a323997065/factory_boy-3.3.3.tar.gz", hash = "sha256:866862d226128dfac7f2b4160287e899daf54f2612778327dd03d0e2cb1e3d03", size = 164146 } wheels = [ - { url = "https://files.pythonhosted.org/packages/27/8d/2bc5f5546ff2ccb3f7de06742853483ab75bf74f36a92254702f8baecc79/factory_boy-3.3.3-py2.py3-none-any.whl", hash = "sha256:1c39e3289f7e667c4285433f305f8d506efc2fe9c73aaea4151ebd5cdea394fc", size = 37036, upload-time = "2025-02-03T09:49:01.659Z" }, + { url = "https://files.pythonhosted.org/packages/27/8d/2bc5f5546ff2ccb3f7de06742853483ab75bf74f36a92254702f8baecc79/factory_boy-3.3.3-py2.py3-none-any.whl", hash = "sha256:1c39e3289f7e667c4285433f305f8d506efc2fe9c73aaea4151ebd5cdea394fc", size = 37036 }, ] [[package]] name = "faker" -version = "37.11.0" +version = "37.12.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "tzdata" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/c9/4b/ca43f6bbcef63deb8ac01201af306388670a172587169aab3b192f7490f0/faker-37.11.0.tar.gz", hash = "sha256:22969803849ba0618be8eee2dd01d0d9e2cd3b75e6ff1a291fa9abcdb34da5e6", size = 1935301, upload-time = "2025-10-07T14:49:01.481Z" } +sdist = { url = "https://files.pythonhosted.org/packages/3d/84/e95acaa848b855e15c83331d0401ee5f84b2f60889255c2e055cb4fb6bdf/faker-37.12.0.tar.gz", hash = "sha256:7505e59a7e02fa9010f06c3e1e92f8250d4cfbb30632296140c2d6dbef09b0fa", size = 1935741 } wheels = [ - { url = "https://files.pythonhosted.org/packages/a3/46/8f4097b55e43af39e8e71e1f7aec59ff7398bca54d975c30889bc844719d/faker-37.11.0-py3-none-any.whl", hash = "sha256:1508d2da94dfd1e0087b36f386126d84f8583b3de19ac18e392a2831a6676c57", size = 1975525, upload-time = "2025-10-07T14:48:58.29Z" }, + { url = "https://files.pythonhosted.org/packages/8e/98/2c050dec90e295a524c9b65c4cb9e7c302386a296b2938710448cbd267d5/faker-37.12.0-py3-none-any.whl", hash = "sha256:afe7ccc038da92f2fbae30d8e16d19d91e92e242f8401ce9caf44de892bab4c4", size = 1975461 }, ] [[package]] name = "fastapi" -version = "0.119.1" +version = "0.121.0" source = { registry = "https://pypi.org/simple" } dependencies = [ + { name = "annotated-doc" }, { name = "pydantic" }, { name = "starlette" }, { name = "typing-extensions" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/a6/f4/152127681182e6413e7a89684c434e19e7414ed7ac0c632999c3c6980640/fastapi-0.119.1.tar.gz", hash = "sha256:a5e3426edce3fe221af4e1992c6d79011b247e3b03cc57999d697fe76cbf8ae0", size = 338616, upload-time = "2025-10-20T11:30:27.734Z" } +sdist = { url = "https://files.pythonhosted.org/packages/8c/e3/77a2df0946703973b9905fd0cde6172c15e0781984320123b4f5079e7113/fastapi-0.121.0.tar.gz", hash = "sha256:06663356a0b1ee93e875bbf05a31fb22314f5bed455afaaad2b2dad7f26e98fa", size = 342412 } wheels = [ - { url = "https://files.pythonhosted.org/packages/b1/26/e6d959b4ac959fdb3e9c4154656fc160794db6af8e64673d52759456bf07/fastapi-0.119.1-py3-none-any.whl", hash = "sha256:0b8c2a2cce853216e150e9bd4faaed88227f8eb37de21cb200771f491586a27f", size = 108123, upload-time = "2025-10-20T11:30:26.185Z" }, + { url = "https://files.pythonhosted.org/packages/dd/2c/42277afc1ba1a18f8358561eee40785d27becab8f80a1f945c0a3051c6eb/fastapi-0.121.0-py3-none-any.whl", hash = "sha256:8bdf1b15a55f4e4b0d6201033da9109ea15632cb76cf156e7b8b4019f2172106", size = 109183 }, ] [package.optional-dependencies] @@ -605,9 +615,9 @@ dependencies = [ { name = "typer" }, { name = "uvicorn", extra = ["standard"] }, ] -sdist = { url = "https://files.pythonhosted.org/packages/cc/13/11e43d630be84e51ba5510a6da6a11eb93b44b72caa796137c5dddda937b/fastapi_cli-0.0.14.tar.gz", hash = "sha256:ddfb5de0a67f77a8b3271af1460489bd4d7f4add73d11fbfac613827b0275274", size = 17994, upload-time = "2025-10-20T16:33:21.054Z" } +sdist = { url = "https://files.pythonhosted.org/packages/cc/13/11e43d630be84e51ba5510a6da6a11eb93b44b72caa796137c5dddda937b/fastapi_cli-0.0.14.tar.gz", hash = "sha256:ddfb5de0a67f77a8b3271af1460489bd4d7f4add73d11fbfac613827b0275274", size = 17994 } wheels = [ - { url = "https://files.pythonhosted.org/packages/40/e8/bc8bbfd93dcc8e347ce98a3e654fb0d2e5f2739afb46b98f41a30c339269/fastapi_cli-0.0.14-py3-none-any.whl", hash = "sha256:e66b9ad499ee77a4e6007545cde6de1459b7f21df199d7f29aad2adaab168eca", size = 11151, upload-time = "2025-10-20T16:33:19.318Z" }, + { url = "https://files.pythonhosted.org/packages/40/e8/bc8bbfd93dcc8e347ce98a3e654fb0d2e5f2739afb46b98f41a30c339269/fastapi_cli-0.0.14-py3-none-any.whl", hash = "sha256:e66b9ad499ee77a4e6007545cde6de1459b7f21df199d7f29aad2adaab168eca", size = 11151 }, ] [package.optional-dependencies] @@ -629,9 +639,9 @@ dependencies = [ { name = "typer" }, { name = "uvicorn", extra = ["standard"] }, ] -sdist = { url = "https://files.pythonhosted.org/packages/f9/48/0f14d8555b750dc8c04382804e4214f1d7f55298127f3a0237ba566e69dd/fastapi_cloud_cli-0.3.1.tar.gz", hash = "sha256:8c7226c36e92e92d0c89827e8f56dbf164ab2de4444bd33aa26b6c3f7675db69", size = 24080, upload-time = "2025-10-09T11:32:58.174Z" } +sdist = { url = "https://files.pythonhosted.org/packages/f9/48/0f14d8555b750dc8c04382804e4214f1d7f55298127f3a0237ba566e69dd/fastapi_cloud_cli-0.3.1.tar.gz", hash = "sha256:8c7226c36e92e92d0c89827e8f56dbf164ab2de4444bd33aa26b6c3f7675db69", size = 24080 } wheels = [ - { url = "https://files.pythonhosted.org/packages/68/79/7f5a5e5513e6a737e5fb089d9c59c74d4d24dc24d581d3aa519b326bedda/fastapi_cloud_cli-0.3.1-py3-none-any.whl", hash = "sha256:7d1a98a77791a9d0757886b2ffbf11bcc6b3be93210dd15064be10b216bf7e00", size = 19711, upload-time = "2025-10-09T11:32:57.118Z" }, + { url = "https://files.pythonhosted.org/packages/68/79/7f5a5e5513e6a737e5fb089d9c59c74d4d24dc24d581d3aa519b326bedda/fastapi_cloud_cli-0.3.1-py3-none-any.whl", hash = "sha256:7d1a98a77791a9d0757886b2ffbf11bcc6b3be93210dd15064be10b216bf7e00", size = 19711 }, ] [[package]] @@ -642,41 +652,40 @@ dependencies = [ { name = "fastapi" }, { name = "pydantic" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/43/ed/c36cfcd849519fd2d23051ad81a91fc5e8cfa7109496fc8a10ad565a5fe9/fastapi_filter-2.0.1.tar.gz", hash = "sha256:cffda370097af7e404f1eb188aca58b199084bfaf7cec881e40b404adf12566e", size = 9857, upload-time = "2024-12-07T17:30:06.343Z" } +sdist = { url = "https://files.pythonhosted.org/packages/43/ed/c36cfcd849519fd2d23051ad81a91fc5e8cfa7109496fc8a10ad565a5fe9/fastapi_filter-2.0.1.tar.gz", hash = "sha256:cffda370097af7e404f1eb188aca58b199084bfaf7cec881e40b404adf12566e", size = 9857 } wheels = [ - { url = "https://files.pythonhosted.org/packages/5e/88/afc022ad64d12f730141fc50758ecf9d60de5fed11335dc16e3127617f05/fastapi_filter-2.0.1-py3-none-any.whl", hash = "sha256:711d48707ec62f7c9e12a7713fc0f6a99858a9e3741b4d108102d5599e77197d", size = 11586, upload-time = "2024-12-07T17:30:05.375Z" }, + { url = "https://files.pythonhosted.org/packages/5e/88/afc022ad64d12f730141fc50758ecf9d60de5fed11335dc16e3127617f05/fastapi_filter-2.0.1-py3-none-any.whl", hash = "sha256:711d48707ec62f7c9e12a7713fc0f6a99858a9e3741b4d108102d5599e77197d", size = 11586 }, ] [[package]] name = "fastapi-mail" -version = "1.5.2" -source = { registry = "https://pypi.org/simple" } +version = "1.2.6" +source = { git = "https://github.com/simonvanlierde/fastapi-mail?rev=f32147ec1a450ed22262913c5ac7ec3b67dd0117#f32147ec1a450ed22262913c5ac7ec3b67dd0117" } dependencies = [ { name = "aiosmtplib" }, { name = "blinker" }, + { name = "cryptography" }, { name = "email-validator" }, { name = "jinja2" }, { name = "pydantic" }, { name = "pydantic-settings" }, + { name = "regex" }, { name = "starlette" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/65/0c/05837963c44ce15e4c81e95bb8bb8a2910fddd60a2f41ac5c015c068c53e/fastapi_mail-1.5.2.tar.gz", hash = "sha256:c83b96f1a030db754e83c64d8687b62b3d4f847d25b5adb00f30d5765ff9825a", size = 13312, upload-time = "2025-10-16T11:13:40.484Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/af/da/30e1a709d85a3132220538714af09b9befad9e81703021dde698c884187a/fastapi_mail-1.5.2-py3-none-any.whl", hash = "sha256:158ecf49075430cb6a5483f557a8f45b987e31f2105a77b3239933b0bacb03e5", size = 15153, upload-time = "2025-10-16T11:13:39.529Z" }, + { name = "typing-extensions" }, ] [[package]] name = "fastapi-pagination" -version = "0.14.3" +version = "0.15.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "fastapi" }, { name = "pydantic" }, { name = "typing-extensions" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/99/df/b8a227a621713ed0133a737dee91066beb09e8769ff875225319da4a3a26/fastapi_pagination-0.14.3.tar.gz", hash = "sha256:be8e81e21235c0758cbdd2f0e597c65bcb82a85062e2b99a9474418d23006791", size = 568147, upload-time = "2025-10-08T10:58:01.833Z" } +sdist = { url = "https://files.pythonhosted.org/packages/bc/db/8a3d097c491ad873574bd7295834ef89e16263ae9104855bbb5ee6d46e47/fastapi_pagination-0.15.0.tar.gz", hash = "sha256:11fe39cbe181ed3c18919b90faf6bfcbe40cb596aa9c52a98bbce85111a29a4f", size = 557472 } wheels = [ - { url = "https://files.pythonhosted.org/packages/a2/6a/0b6804e1c20013855379fe58e02206e9cc7f7131653d8daad1af6be67851/fastapi_pagination-0.14.3-py3-none-any.whl", hash = "sha256:e87350b64010fd3b2df840218b1f65a21eec6078238cd3a1794c2468a03ea45f", size = 52559, upload-time = "2025-10-08T10:58:00.428Z" }, + { url = "https://files.pythonhosted.org/packages/68/91/b835e07234170ba85473227aa107bcf1dc616ff6cb643c0bd9b8225a55f1/fastapi_pagination-0.15.0-py3-none-any.whl", hash = "sha256:ffef937e78903fcb6f356b8407ec1fb0620a06675087fa7d0c4e537a60aa0447", size = 52292 }, ] [[package]] @@ -686,14 +695,14 @@ source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "boto3" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/68/8a/e56d4ade659994c2989091b96642f10554ec3914a40de56a556ffdbbcd26/fastapi_storages-0.3.0.tar.gz", hash = "sha256:f784335fff9cd163b783e842da04c6d9ed1b306fce8995fda109b170d6d453df", size = 6706, upload-time = "2024-02-15T15:14:26.431Z" } +sdist = { url = "https://files.pythonhosted.org/packages/68/8a/e56d4ade659994c2989091b96642f10554ec3914a40de56a556ffdbbcd26/fastapi_storages-0.3.0.tar.gz", hash = "sha256:f784335fff9cd163b783e842da04c6d9ed1b306fce8995fda109b170d6d453df", size = 6706 } wheels = [ - { url = "https://files.pythonhosted.org/packages/a7/b5/3fb94b4f329fb2f83ffa54e6941b769deaaaa77f63a9fe70905219dd7339/fastapi_storages-0.3.0-py3-none-any.whl", hash = "sha256:91adb41a80fdef2a84c0f8244c27ade7ff8bd5db9b7fa95c496c06c03e192477", size = 9725, upload-time = "2024-02-15T15:14:27.567Z" }, + { url = "https://files.pythonhosted.org/packages/a7/b5/3fb94b4f329fb2f83ffa54e6941b769deaaaa77f63a9fe70905219dd7339/fastapi_storages-0.3.0-py3-none-any.whl", hash = "sha256:91adb41a80fdef2a84c0f8244c27ade7ff8bd5db9b7fa95c496c06c03e192477", size = 9725 }, ] [[package]] name = "fastapi-users" -version = "14.0.1" +version = "15.0.1" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "email-validator" }, @@ -703,9 +712,9 @@ dependencies = [ { name = "pyjwt", extra = ["crypto"] }, { name = "python-multipart" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/e4/26/7fe4e6a4f60d9cde2b95f58ba45ff03219b62bd03bea75d914b723ecfa2a/fastapi_users-14.0.1.tar.gz", hash = "sha256:8c032b3a75c6fb2b1f5eab8ffce5321176e9916efe1fe93e7c15ee55f0b02236", size = 120315, upload-time = "2025-01-04T13:20:05.95Z" } +sdist = { url = "https://files.pythonhosted.org/packages/fa/ea/6c0ba809f29d22ad53ab25bbae4408f00b0a3375b71bd21c39dcc3a16044/fastapi_users-15.0.1.tar.gz", hash = "sha256:c822755c1288740a919636d3463797e54df91b53c1c6f4917693d499867d21a7", size = 120916 } wheels = [ - { url = "https://files.pythonhosted.org/packages/2c/52/2821d3e95a92567d38f98a33d1ef89302aa3448866bf45ff19a48a5f28f8/fastapi_users-14.0.1-py3-none-any.whl", hash = "sha256:074df59676dccf79412d2880bdcb661ab1fabc2ecec1f043b4e6a23be97ed9e1", size = 38717, upload-time = "2025-01-04T13:20:04.441Z" }, + { url = "https://files.pythonhosted.org/packages/59/7f/1bff91a48e755e659d0505f597a8e010ec92059f2219a838fd15887a89b2/fastapi_users-15.0.1-py3-none-any.whl", hash = "sha256:6f637eb2fc80be6bba396b77dded30fe4c22fa943349d2e0a1647894f8b21c16", size = 38624 }, ] [package.optional-dependencies] @@ -724,9 +733,9 @@ dependencies = [ { name = "fastapi-users" }, { name = "sqlalchemy", extra = ["asyncio"] }, ] -sdist = { url = "https://files.pythonhosted.org/packages/87/12/bc9e6146ae31564741cefc87ee6e37fa5b566933f0afe8aa030779d60e60/fastapi_users_db_sqlalchemy-7.0.0.tar.gz", hash = "sha256:6823eeedf8a92f819276a2b2210ef1dcfd71fe8b6e37f7b4da8d1c60e3dfd595", size = 10877, upload-time = "2025-01-04T13:09:05.086Z" } +sdist = { url = "https://files.pythonhosted.org/packages/87/12/bc9e6146ae31564741cefc87ee6e37fa5b566933f0afe8aa030779d60e60/fastapi_users_db_sqlalchemy-7.0.0.tar.gz", hash = "sha256:6823eeedf8a92f819276a2b2210ef1dcfd71fe8b6e37f7b4da8d1c60e3dfd595", size = 10877 } wheels = [ - { url = "https://files.pythonhosted.org/packages/a6/08/9968963c1fb8c34627b7f1fbcdfe9438540f87dc7c9bfb59bb4fd19a4ecf/fastapi_users_db_sqlalchemy-7.0.0-py3-none-any.whl", hash = "sha256:5fceac018e7cfa69efc70834dd3035b3de7988eb4274154a0dbe8b14f5aa001e", size = 6891, upload-time = "2025-01-04T13:09:02.869Z" }, + { url = "https://files.pythonhosted.org/packages/a6/08/9968963c1fb8c34627b7f1fbcdfe9438540f87dc7c9bfb59bb4fd19a4ecf/fastapi_users_db_sqlalchemy-7.0.0-py3-none-any.whl", hash = "sha256:5fceac018e7cfa69efc70834dd3035b3de7988eb4274154a0dbe8b14f5aa001e", size = 6891 }, ] [[package]] @@ -743,14 +752,14 @@ dependencies = [ name = "filelock" version = "3.20.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/58/46/0028a82567109b5ef6e4d2a1f04a583fb513e6cf9527fcdd09afd817deeb/filelock-3.20.0.tar.gz", hash = "sha256:711e943b4ec6be42e1d4e6690b48dc175c822967466bb31c0c293f34334c13f4", size = 18922, upload-time = "2025-10-08T18:03:50.056Z" } +sdist = { url = "https://files.pythonhosted.org/packages/58/46/0028a82567109b5ef6e4d2a1f04a583fb513e6cf9527fcdd09afd817deeb/filelock-3.20.0.tar.gz", hash = "sha256:711e943b4ec6be42e1d4e6690b48dc175c822967466bb31c0c293f34334c13f4", size = 18922 } wheels = [ - { url = "https://files.pythonhosted.org/packages/76/91/7216b27286936c16f5b4d0c530087e4a54eead683e6b0b73dd0c64844af6/filelock-3.20.0-py3-none-any.whl", hash = "sha256:339b4732ffda5cd79b13f4e2711a31b0365ce445d95d243bb996273d072546a2", size = 16054, upload-time = "2025-10-08T18:03:48.35Z" }, + { url = "https://files.pythonhosted.org/packages/76/91/7216b27286936c16f5b4d0c530087e4a54eead683e6b0b73dd0c64844af6/filelock-3.20.0-py3-none-any.whl", hash = "sha256:339b4732ffda5cd79b13f4e2711a31b0365ce445d95d243bb996273d072546a2", size = 16054 }, ] [[package]] name = "google-api-core" -version = "2.26.0" +version = "2.28.1" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "google-auth" }, @@ -759,14 +768,14 @@ dependencies = [ { name = "protobuf" }, { name = "requests" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/32/ea/e7b6ac3c7b557b728c2d0181010548cbbdd338e9002513420c5a354fa8df/google_api_core-2.26.0.tar.gz", hash = "sha256:e6e6d78bd6cf757f4aee41dcc85b07f485fbb069d5daa3afb126defba1e91a62", size = 166369, upload-time = "2025-10-08T21:37:38.39Z" } +sdist = { url = "https://files.pythonhosted.org/packages/61/da/83d7043169ac2c8c7469f0e375610d78ae2160134bf1b80634c482fa079c/google_api_core-2.28.1.tar.gz", hash = "sha256:2b405df02d68e68ce0fbc138559e6036559e685159d148ae5861013dc201baf8", size = 176759 } wheels = [ - { url = "https://files.pythonhosted.org/packages/77/ad/f73cf9fe9bd95918502b270e3ddb8764e4c900b3bbd7782b90c56fac14bb/google_api_core-2.26.0-py3-none-any.whl", hash = "sha256:2b204bd0da2c81f918e3582c48458e24c11771f987f6258e6e227212af78f3ed", size = 162505, upload-time = "2025-10-08T21:37:36.651Z" }, + { url = "https://files.pythonhosted.org/packages/ed/d4/90197b416cb61cefd316964fd9e7bd8324bcbafabf40eef14a9f20b81974/google_api_core-2.28.1-py3-none-any.whl", hash = "sha256:4021b0f8ceb77a6fb4de6fde4502cecab45062e66ff4f2895169e0b35bc9466c", size = 173706 }, ] [[package]] name = "google-api-python-client" -version = "2.185.0" +version = "2.187.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "google-api-core" }, @@ -775,85 +784,85 @@ dependencies = [ { name = "httplib2" }, { name = "uritemplate" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/8e/5a/6f9b49d67ea91376305fdb8bbf2877c746d756e45fd8fb7d2e32d6dad19b/google_api_python_client-2.185.0.tar.gz", hash = "sha256:aa1b338e4bb0f141c2df26743f6b46b11f38705aacd775b61971cbc51da089c3", size = 13885609, upload-time = "2025-10-17T15:00:35.623Z" } +sdist = { url = "https://files.pythonhosted.org/packages/75/83/60cdacf139d768dd7f0fcbe8d95b418299810068093fdf8228c6af89bb70/google_api_python_client-2.187.0.tar.gz", hash = "sha256:e98e8e8f49e1b5048c2f8276473d6485febc76c9c47892a8b4d1afa2c9ec8278", size = 14068154 } wheels = [ - { url = "https://files.pythonhosted.org/packages/fa/28/be3b17bd6a190c8c2ec9e4fb65d43e6ecd7b7a1bb19ccc1d9ab4f687a58c/google_api_python_client-2.185.0-py3-none-any.whl", hash = "sha256:00fe173a4b346d2397fbe0d37ac15368170dfbed91a0395a66ef2558e22b93fc", size = 14453595, upload-time = "2025-10-17T15:00:33.176Z" }, + { url = "https://files.pythonhosted.org/packages/96/58/c1e716be1b055b504d80db2c8413f6c6a890a6ae218a65f178b63bc30356/google_api_python_client-2.187.0-py3-none-any.whl", hash = "sha256:d8d0f6d85d7d1d10bdab32e642312ed572bdc98919f72f831b44b9a9cebba32f", size = 14641434 }, ] [[package]] name = "google-auth" -version = "2.41.1" +version = "2.43.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "cachetools" }, { name = "pyasn1-modules" }, { name = "rsa" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/a8/af/5129ce5b2f9688d2fa49b463e544972a7c82b0fdb50980dafee92e121d9f/google_auth-2.41.1.tar.gz", hash = "sha256:b76b7b1f9e61f0cb7e88870d14f6a94aeef248959ef6992670efee37709cbfd2", size = 292284, upload-time = "2025-09-30T22:51:26.363Z" } +sdist = { url = "https://files.pythonhosted.org/packages/ff/ef/66d14cf0e01b08d2d51ffc3c20410c4e134a1548fc246a6081eae585a4fe/google_auth-2.43.0.tar.gz", hash = "sha256:88228eee5fc21b62a1b5fe773ca15e67778cb07dc8363adcb4a8827b52d81483", size = 296359 } wheels = [ - { url = "https://files.pythonhosted.org/packages/be/a4/7319a2a8add4cc352be9e3efeff5e2aacee917c85ca2fa1647e29089983c/google_auth-2.41.1-py2.py3-none-any.whl", hash = "sha256:754843be95575b9a19c604a848a41be03f7f2afd8c019f716dc1f51ee41c639d", size = 221302, upload-time = "2025-09-30T22:51:24.212Z" }, + { url = "https://files.pythonhosted.org/packages/6f/d1/385110a9ae86d91cc14c5282c61fe9f4dc41c0b9f7d423c6ad77038c4448/google_auth-2.43.0-py2.py3-none-any.whl", hash = "sha256:af628ba6fa493f75c7e9dbe9373d148ca9f4399b5ea29976519e0a3848eddd16", size = 223114 }, ] [[package]] name = "google-auth-httplib2" -version = "0.2.0" +version = "0.2.1" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "google-auth" }, { name = "httplib2" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/56/be/217a598a818567b28e859ff087f347475c807a5649296fb5a817c58dacef/google-auth-httplib2-0.2.0.tar.gz", hash = "sha256:38aa7badf48f974f1eb9861794e9c0cb2a0511a4ec0679b1f886d108f5640e05", size = 10842, upload-time = "2023-12-12T17:40:30.722Z" } +sdist = { url = "https://files.pythonhosted.org/packages/e0/83/7ef576d1c7ccea214e7b001e69c006bc75e058a3a1f2ab810167204b698b/google_auth_httplib2-0.2.1.tar.gz", hash = "sha256:5ef03be3927423c87fb69607b42df23a444e434ddb2555b73b3679793187b7de", size = 11086 } wheels = [ - { url = "https://files.pythonhosted.org/packages/be/8a/fe34d2f3f9470a27b01c9e76226965863f153d5fbe276f83608562e49c04/google_auth_httplib2-0.2.0-py2.py3-none-any.whl", hash = "sha256:b65a0a2123300dd71281a7bf6e64d65a0759287df52729bdd1ae2e47dc311a3d", size = 9253, upload-time = "2023-12-12T17:40:13.055Z" }, + { url = "https://files.pythonhosted.org/packages/44/a7/ca23dd006255f70e2bc469d3f9f0c82ea455335bfd682ad4d677adc435de/google_auth_httplib2-0.2.1-py3-none-any.whl", hash = "sha256:1be94c611db91c01f9703e7f62b0a59bbd5587a95571c7b6fade510d648bc08b", size = 9525 }, ] [[package]] name = "googleapis-common-protos" -version = "1.71.0" +version = "1.72.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "protobuf" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/30/43/b25abe02db2911397819003029bef768f68a974f2ece483e6084d1a5f754/googleapis_common_protos-1.71.0.tar.gz", hash = "sha256:1aec01e574e29da63c80ba9f7bbf1ccfaacf1da877f23609fe236ca7c72a2e2e", size = 146454, upload-time = "2025-10-20T14:58:08.732Z" } +sdist = { url = "https://files.pythonhosted.org/packages/e5/7b/adfd75544c415c487b33061fe7ae526165241c1ea133f9a9125a56b39fd8/googleapis_common_protos-1.72.0.tar.gz", hash = "sha256:e55a601c1b32b52d7a3e65f43563e2aa61bcd737998ee672ac9b951cd49319f5", size = 147433 } wheels = [ - { url = "https://files.pythonhosted.org/packages/25/e8/eba9fece11d57a71e3e22ea672742c8f3cf23b35730c9e96db768b295216/googleapis_common_protos-1.71.0-py3-none-any.whl", hash = "sha256:59034a1d849dc4d18971997a72ac56246570afdd17f9369a0ff68218d50ab78c", size = 294576, upload-time = "2025-10-20T14:56:21.295Z" }, + { url = "https://files.pythonhosted.org/packages/c4/ab/09169d5a4612a5f92490806649ac8d41e3ec9129c636754575b3553f4ea4/googleapis_common_protos-1.72.0-py3-none-any.whl", hash = "sha256:4299c5a82d5ae1a9702ada957347726b167f9f8d1fc352477702a1e851ff4038", size = 297515 }, ] [[package]] name = "greenlet" version = "3.2.4" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/03/b8/704d753a5a45507a7aab61f18db9509302ed3d0a27ac7e0359ec2905b1a6/greenlet-3.2.4.tar.gz", hash = "sha256:0dca0d95ff849f9a364385f36ab49f50065d76964944638be9691e1832e9f86d", size = 188260, upload-time = "2025-08-07T13:24:33.51Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/49/e8/58c7f85958bda41dafea50497cbd59738c5c43dbbea5ee83d651234398f4/greenlet-3.2.4-cp313-cp313-macosx_11_0_universal2.whl", hash = "sha256:1a921e542453fe531144e91e1feedf12e07351b1cf6c9e8a3325ea600a715a31", size = 272814, upload-time = "2025-08-07T13:15:50.011Z" }, - { url = "https://files.pythonhosted.org/packages/62/dd/b9f59862e9e257a16e4e610480cfffd29e3fae018a68c2332090b53aac3d/greenlet-3.2.4-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:cd3c8e693bff0fff6ba55f140bf390fa92c994083f838fece0f63be121334945", size = 641073, upload-time = "2025-08-07T13:42:57.23Z" }, - { url = "https://files.pythonhosted.org/packages/f7/0b/bc13f787394920b23073ca3b6c4a7a21396301ed75a655bcb47196b50e6e/greenlet-3.2.4-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:710638eb93b1fa52823aa91bf75326f9ecdfd5e0466f00789246a5280f4ba0fc", size = 655191, upload-time = "2025-08-07T13:45:29.752Z" }, - { url = "https://files.pythonhosted.org/packages/f2/d6/6adde57d1345a8d0f14d31e4ab9c23cfe8e2cd39c3baf7674b4b0338d266/greenlet-3.2.4-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:c5111ccdc9c88f423426df3fd1811bfc40ed66264d35aa373420a34377efc98a", size = 649516, upload-time = "2025-08-07T13:53:16.314Z" }, - { url = "https://files.pythonhosted.org/packages/7f/3b/3a3328a788d4a473889a2d403199932be55b1b0060f4ddd96ee7cdfcad10/greenlet-3.2.4-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:d76383238584e9711e20ebe14db6c88ddcedc1829a9ad31a584389463b5aa504", size = 652169, upload-time = "2025-08-07T13:18:32.861Z" }, - { url = "https://files.pythonhosted.org/packages/ee/43/3cecdc0349359e1a527cbf2e3e28e5f8f06d3343aaf82ca13437a9aa290f/greenlet-3.2.4-cp313-cp313-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:23768528f2911bcd7e475210822ffb5254ed10d71f4028387e5a99b4c6699671", size = 610497, upload-time = "2025-08-07T13:18:31.636Z" }, - { url = "https://files.pythonhosted.org/packages/b8/19/06b6cf5d604e2c382a6f31cafafd6f33d5dea706f4db7bdab184bad2b21d/greenlet-3.2.4-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:00fadb3fedccc447f517ee0d3fd8fe49eae949e1cd0f6a611818f4f6fb7dc83b", size = 1121662, upload-time = "2025-08-07T13:42:41.117Z" }, - { url = "https://files.pythonhosted.org/packages/a2/15/0d5e4e1a66fab130d98168fe984c509249c833c1a3c16806b90f253ce7b9/greenlet-3.2.4-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:d25c5091190f2dc0eaa3f950252122edbbadbb682aa7b1ef2f8af0f8c0afefae", size = 1149210, upload-time = "2025-08-07T13:18:24.072Z" }, - { url = "https://files.pythonhosted.org/packages/1c/53/f9c440463b3057485b8594d7a638bed53ba531165ef0ca0e6c364b5cc807/greenlet-3.2.4-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:6e343822feb58ac4d0a1211bd9399de2b3a04963ddeec21530fc426cc121f19b", size = 1564759, upload-time = "2025-11-04T12:42:19.395Z" }, - { url = "https://files.pythonhosted.org/packages/47/e4/3bb4240abdd0a8d23f4f88adec746a3099f0d86bfedb623f063b2e3b4df0/greenlet-3.2.4-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:ca7f6f1f2649b89ce02f6f229d7c19f680a6238af656f61e0115b24857917929", size = 1634288, upload-time = "2025-11-04T12:42:21.174Z" }, - { url = "https://files.pythonhosted.org/packages/0b/55/2321e43595e6801e105fcfdee02b34c0f996eb71e6ddffca6b10b7e1d771/greenlet-3.2.4-cp313-cp313-win_amd64.whl", hash = "sha256:554b03b6e73aaabec3745364d6239e9e012d64c68ccd0b8430c64ccc14939a8b", size = 299685, upload-time = "2025-08-07T13:24:38.824Z" }, - { url = "https://files.pythonhosted.org/packages/22/5c/85273fd7cc388285632b0498dbbab97596e04b154933dfe0f3e68156c68c/greenlet-3.2.4-cp314-cp314-macosx_11_0_universal2.whl", hash = "sha256:49a30d5fda2507ae77be16479bdb62a660fa51b1eb4928b524975b3bde77b3c0", size = 273586, upload-time = "2025-08-07T13:16:08.004Z" }, - { url = "https://files.pythonhosted.org/packages/d1/75/10aeeaa3da9332c2e761e4c50d4c3556c21113ee3f0afa2cf5769946f7a3/greenlet-3.2.4-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:299fd615cd8fc86267b47597123e3f43ad79c9d8a22bebdce535e53550763e2f", size = 686346, upload-time = "2025-08-07T13:42:59.944Z" }, - { url = "https://files.pythonhosted.org/packages/c0/aa/687d6b12ffb505a4447567d1f3abea23bd20e73a5bed63871178e0831b7a/greenlet-3.2.4-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:c17b6b34111ea72fc5a4e4beec9711d2226285f0386ea83477cbb97c30a3f3a5", size = 699218, upload-time = "2025-08-07T13:45:30.969Z" }, - { url = "https://files.pythonhosted.org/packages/dc/8b/29aae55436521f1d6f8ff4e12fb676f3400de7fcf27fccd1d4d17fd8fecd/greenlet-3.2.4-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:b4a1870c51720687af7fa3e7cda6d08d801dae660f75a76f3845b642b4da6ee1", size = 694659, upload-time = "2025-08-07T13:53:17.759Z" }, - { url = "https://files.pythonhosted.org/packages/92/2e/ea25914b1ebfde93b6fc4ff46d6864564fba59024e928bdc7de475affc25/greenlet-3.2.4-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:061dc4cf2c34852b052a8620d40f36324554bc192be474b9e9770e8c042fd735", size = 695355, upload-time = "2025-08-07T13:18:34.517Z" }, - { url = "https://files.pythonhosted.org/packages/72/60/fc56c62046ec17f6b0d3060564562c64c862948c9d4bc8aa807cf5bd74f4/greenlet-3.2.4-cp314-cp314-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:44358b9bf66c8576a9f57a590d5f5d6e72fa4228b763d0e43fee6d3b06d3a337", size = 657512, upload-time = "2025-08-07T13:18:33.969Z" }, - { url = "https://files.pythonhosted.org/packages/23/6e/74407aed965a4ab6ddd93a7ded3180b730d281c77b765788419484cdfeef/greenlet-3.2.4-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:2917bdf657f5859fbf3386b12d68ede4cf1f04c90c3a6bc1f013dd68a22e2269", size = 1612508, upload-time = "2025-11-04T12:42:23.427Z" }, - { url = "https://files.pythonhosted.org/packages/0d/da/343cd760ab2f92bac1845ca07ee3faea9fe52bee65f7bcb19f16ad7de08b/greenlet-3.2.4-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:015d48959d4add5d6c9f6c5210ee3803a830dce46356e3bc326d6776bde54681", size = 1680760, upload-time = "2025-11-04T12:42:25.341Z" }, - { url = "https://files.pythonhosted.org/packages/e3/a5/6ddab2b4c112be95601c13428db1d8b6608a8b6039816f2ba09c346c08fc/greenlet-3.2.4-cp314-cp314-win_amd64.whl", hash = "sha256:e37ab26028f12dbb0ff65f29a8d3d44a765c61e729647bf2ddfbbed621726f01", size = 303425, upload-time = "2025-08-07T13:32:27.59Z" }, +sdist = { url = "https://files.pythonhosted.org/packages/03/b8/704d753a5a45507a7aab61f18db9509302ed3d0a27ac7e0359ec2905b1a6/greenlet-3.2.4.tar.gz", hash = "sha256:0dca0d95ff849f9a364385f36ab49f50065d76964944638be9691e1832e9f86d", size = 188260 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/49/e8/58c7f85958bda41dafea50497cbd59738c5c43dbbea5ee83d651234398f4/greenlet-3.2.4-cp313-cp313-macosx_11_0_universal2.whl", hash = "sha256:1a921e542453fe531144e91e1feedf12e07351b1cf6c9e8a3325ea600a715a31", size = 272814 }, + { url = "https://files.pythonhosted.org/packages/62/dd/b9f59862e9e257a16e4e610480cfffd29e3fae018a68c2332090b53aac3d/greenlet-3.2.4-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:cd3c8e693bff0fff6ba55f140bf390fa92c994083f838fece0f63be121334945", size = 641073 }, + { url = "https://files.pythonhosted.org/packages/f7/0b/bc13f787394920b23073ca3b6c4a7a21396301ed75a655bcb47196b50e6e/greenlet-3.2.4-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:710638eb93b1fa52823aa91bf75326f9ecdfd5e0466f00789246a5280f4ba0fc", size = 655191 }, + { url = "https://files.pythonhosted.org/packages/f2/d6/6adde57d1345a8d0f14d31e4ab9c23cfe8e2cd39c3baf7674b4b0338d266/greenlet-3.2.4-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:c5111ccdc9c88f423426df3fd1811bfc40ed66264d35aa373420a34377efc98a", size = 649516 }, + { url = "https://files.pythonhosted.org/packages/7f/3b/3a3328a788d4a473889a2d403199932be55b1b0060f4ddd96ee7cdfcad10/greenlet-3.2.4-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:d76383238584e9711e20ebe14db6c88ddcedc1829a9ad31a584389463b5aa504", size = 652169 }, + { url = "https://files.pythonhosted.org/packages/ee/43/3cecdc0349359e1a527cbf2e3e28e5f8f06d3343aaf82ca13437a9aa290f/greenlet-3.2.4-cp313-cp313-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:23768528f2911bcd7e475210822ffb5254ed10d71f4028387e5a99b4c6699671", size = 610497 }, + { url = "https://files.pythonhosted.org/packages/b8/19/06b6cf5d604e2c382a6f31cafafd6f33d5dea706f4db7bdab184bad2b21d/greenlet-3.2.4-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:00fadb3fedccc447f517ee0d3fd8fe49eae949e1cd0f6a611818f4f6fb7dc83b", size = 1121662 }, + { url = "https://files.pythonhosted.org/packages/a2/15/0d5e4e1a66fab130d98168fe984c509249c833c1a3c16806b90f253ce7b9/greenlet-3.2.4-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:d25c5091190f2dc0eaa3f950252122edbbadbb682aa7b1ef2f8af0f8c0afefae", size = 1149210 }, + { url = "https://files.pythonhosted.org/packages/1c/53/f9c440463b3057485b8594d7a638bed53ba531165ef0ca0e6c364b5cc807/greenlet-3.2.4-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:6e343822feb58ac4d0a1211bd9399de2b3a04963ddeec21530fc426cc121f19b", size = 1564759 }, + { url = "https://files.pythonhosted.org/packages/47/e4/3bb4240abdd0a8d23f4f88adec746a3099f0d86bfedb623f063b2e3b4df0/greenlet-3.2.4-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:ca7f6f1f2649b89ce02f6f229d7c19f680a6238af656f61e0115b24857917929", size = 1634288 }, + { url = "https://files.pythonhosted.org/packages/0b/55/2321e43595e6801e105fcfdee02b34c0f996eb71e6ddffca6b10b7e1d771/greenlet-3.2.4-cp313-cp313-win_amd64.whl", hash = "sha256:554b03b6e73aaabec3745364d6239e9e012d64c68ccd0b8430c64ccc14939a8b", size = 299685 }, + { url = "https://files.pythonhosted.org/packages/22/5c/85273fd7cc388285632b0498dbbab97596e04b154933dfe0f3e68156c68c/greenlet-3.2.4-cp314-cp314-macosx_11_0_universal2.whl", hash = "sha256:49a30d5fda2507ae77be16479bdb62a660fa51b1eb4928b524975b3bde77b3c0", size = 273586 }, + { url = "https://files.pythonhosted.org/packages/d1/75/10aeeaa3da9332c2e761e4c50d4c3556c21113ee3f0afa2cf5769946f7a3/greenlet-3.2.4-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:299fd615cd8fc86267b47597123e3f43ad79c9d8a22bebdce535e53550763e2f", size = 686346 }, + { url = "https://files.pythonhosted.org/packages/c0/aa/687d6b12ffb505a4447567d1f3abea23bd20e73a5bed63871178e0831b7a/greenlet-3.2.4-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:c17b6b34111ea72fc5a4e4beec9711d2226285f0386ea83477cbb97c30a3f3a5", size = 699218 }, + { url = "https://files.pythonhosted.org/packages/dc/8b/29aae55436521f1d6f8ff4e12fb676f3400de7fcf27fccd1d4d17fd8fecd/greenlet-3.2.4-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:b4a1870c51720687af7fa3e7cda6d08d801dae660f75a76f3845b642b4da6ee1", size = 694659 }, + { url = "https://files.pythonhosted.org/packages/92/2e/ea25914b1ebfde93b6fc4ff46d6864564fba59024e928bdc7de475affc25/greenlet-3.2.4-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:061dc4cf2c34852b052a8620d40f36324554bc192be474b9e9770e8c042fd735", size = 695355 }, + { url = "https://files.pythonhosted.org/packages/72/60/fc56c62046ec17f6b0d3060564562c64c862948c9d4bc8aa807cf5bd74f4/greenlet-3.2.4-cp314-cp314-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:44358b9bf66c8576a9f57a590d5f5d6e72fa4228b763d0e43fee6d3b06d3a337", size = 657512 }, + { url = "https://files.pythonhosted.org/packages/23/6e/74407aed965a4ab6ddd93a7ded3180b730d281c77b765788419484cdfeef/greenlet-3.2.4-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:2917bdf657f5859fbf3386b12d68ede4cf1f04c90c3a6bc1f013dd68a22e2269", size = 1612508 }, + { url = "https://files.pythonhosted.org/packages/0d/da/343cd760ab2f92bac1845ca07ee3faea9fe52bee65f7bcb19f16ad7de08b/greenlet-3.2.4-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:015d48959d4add5d6c9f6c5210ee3803a830dce46356e3bc326d6776bde54681", size = 1680760 }, + { url = "https://files.pythonhosted.org/packages/e3/a5/6ddab2b4c112be95601c13428db1d8b6608a8b6039816f2ba09c346c08fc/greenlet-3.2.4-cp314-cp314-win_amd64.whl", hash = "sha256:e37ab26028f12dbb0ff65f29a8d3d44a765c61e729647bf2ddfbbed621726f01", size = 303425 }, ] [[package]] name = "h11" version = "0.16.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/01/ee/02a2c011bdab74c6fb3c75474d40b3052059d95df7e73351460c8588d963/h11-0.16.0.tar.gz", hash = "sha256:4e35b956cf45792e4caa5885e69fba00bdbc6ffafbfa020300e549b208ee5ff1", size = 101250, upload-time = "2025-04-24T03:35:25.427Z" } +sdist = { url = "https://files.pythonhosted.org/packages/01/ee/02a2c011bdab74c6fb3c75474d40b3052059d95df7e73351460c8588d963/h11-0.16.0.tar.gz", hash = "sha256:4e35b956cf45792e4caa5885e69fba00bdbc6ffafbfa020300e549b208ee5ff1", size = 101250 } wheels = [ - { url = "https://files.pythonhosted.org/packages/04/4b/29cac41a4d98d144bf5f6d33995617b185d14b22401f75ca86f384e87ff1/h11-0.16.0-py3-none-any.whl", hash = "sha256:63cf8bbe7522de3bf65932fda1d9c2772064ffb3dae62d55932da54b31cb6c86", size = 37515, upload-time = "2025-04-24T03:35:24.344Z" }, + { url = "https://files.pythonhosted.org/packages/04/4b/29cac41a4d98d144bf5f6d33995617b185d14b22401f75ca86f384e87ff1/h11-0.16.0-py3-none-any.whl", hash = "sha256:63cf8bbe7522de3bf65932fda1d9c2772064ffb3dae62d55932da54b31cb6c86", size = 37515 }, ] [[package]] @@ -864,9 +873,9 @@ dependencies = [ { name = "certifi" }, { name = "h11" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/06/94/82699a10bca87a5556c9c59b5963f2d039dbd239f25bc2a63907a05a14cb/httpcore-1.0.9.tar.gz", hash = "sha256:6e34463af53fd2ab5d807f399a9b45ea31c3dfa2276f15a2c3f00afff6e176e8", size = 85484, upload-time = "2025-04-24T22:06:22.219Z" } +sdist = { url = "https://files.pythonhosted.org/packages/06/94/82699a10bca87a5556c9c59b5963f2d039dbd239f25bc2a63907a05a14cb/httpcore-1.0.9.tar.gz", hash = "sha256:6e34463af53fd2ab5d807f399a9b45ea31c3dfa2276f15a2c3f00afff6e176e8", size = 85484 } wheels = [ - { url = "https://files.pythonhosted.org/packages/7e/f5/f66802a942d491edb555dd61e3a9961140fd64c90bce1eafd741609d334d/httpcore-1.0.9-py3-none-any.whl", hash = "sha256:2d400746a40668fc9dec9810239072b40b4484b640a8c38fd654a024c7a1bf55", size = 78784, upload-time = "2025-04-24T22:06:20.566Z" }, + { url = "https://files.pythonhosted.org/packages/7e/f5/f66802a942d491edb555dd61e3a9961140fd64c90bce1eafd741609d334d/httpcore-1.0.9-py3-none-any.whl", hash = "sha256:2d400746a40668fc9dec9810239072b40b4484b640a8c38fd654a024c7a1bf55", size = 78784 }, ] [[package]] @@ -876,31 +885,31 @@ source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "pyparsing" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/52/77/6653db69c1f7ecfe5e3f9726fdadc981794656fcd7d98c4209fecfea9993/httplib2-0.31.0.tar.gz", hash = "sha256:ac7ab497c50975147d4f7b1ade44becc7df2f8954d42b38b3d69c515f531135c", size = 250759, upload-time = "2025-09-11T12:16:03.403Z" } +sdist = { url = "https://files.pythonhosted.org/packages/52/77/6653db69c1f7ecfe5e3f9726fdadc981794656fcd7d98c4209fecfea9993/httplib2-0.31.0.tar.gz", hash = "sha256:ac7ab497c50975147d4f7b1ade44becc7df2f8954d42b38b3d69c515f531135c", size = 250759 } wheels = [ - { url = "https://files.pythonhosted.org/packages/8c/a2/0d269db0f6163be503775dc8b6a6fa15820cc9fdc866f6ba608d86b721f2/httplib2-0.31.0-py3-none-any.whl", hash = "sha256:b9cd78abea9b4e43a7714c6e0f8b6b8561a6fc1e95d5dbd367f5bf0ef35f5d24", size = 91148, upload-time = "2025-09-11T12:16:01.803Z" }, + { url = "https://files.pythonhosted.org/packages/8c/a2/0d269db0f6163be503775dc8b6a6fa15820cc9fdc866f6ba608d86b721f2/httplib2-0.31.0-py3-none-any.whl", hash = "sha256:b9cd78abea9b4e43a7714c6e0f8b6b8561a6fc1e95d5dbd367f5bf0ef35f5d24", size = 91148 }, ] [[package]] name = "httptools" version = "0.7.1" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/b5/46/120a669232c7bdedb9d52d4aeae7e6c7dfe151e99dc70802e2fc7a5e1993/httptools-0.7.1.tar.gz", hash = "sha256:abd72556974f8e7c74a259655924a717a2365b236c882c3f6f8a45fe94703ac9", size = 258961, upload-time = "2025-10-10T03:55:08.559Z" } +sdist = { url = "https://files.pythonhosted.org/packages/b5/46/120a669232c7bdedb9d52d4aeae7e6c7dfe151e99dc70802e2fc7a5e1993/httptools-0.7.1.tar.gz", hash = "sha256:abd72556974f8e7c74a259655924a717a2365b236c882c3f6f8a45fe94703ac9", size = 258961 } wheels = [ - { url = "https://files.pythonhosted.org/packages/09/8f/c77b1fcbfd262d422f12da02feb0d218fa228d52485b77b953832105bb90/httptools-0.7.1-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:6babce6cfa2a99545c60bfef8bee0cc0545413cb0018f617c8059a30ad985de3", size = 202889, upload-time = "2025-10-10T03:54:47.089Z" }, - { url = "https://files.pythonhosted.org/packages/0a/1a/22887f53602feaa066354867bc49a68fc295c2293433177ee90870a7d517/httptools-0.7.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:601b7628de7504077dd3dcb3791c6b8694bbd967148a6d1f01806509254fb1ca", size = 108180, upload-time = "2025-10-10T03:54:48.052Z" }, - { url = "https://files.pythonhosted.org/packages/32/6a/6aaa91937f0010d288d3d124ca2946d48d60c3a5ee7ca62afe870e3ea011/httptools-0.7.1-cp313-cp313-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:04c6c0e6c5fb0739c5b8a9eb046d298650a0ff38cf42537fc372b28dc7e4472c", size = 478596, upload-time = "2025-10-10T03:54:48.919Z" }, - { url = "https://files.pythonhosted.org/packages/6d/70/023d7ce117993107be88d2cbca566a7c1323ccbaf0af7eabf2064fe356f6/httptools-0.7.1-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:69d4f9705c405ae3ee83d6a12283dc9feba8cc6aaec671b412917e644ab4fa66", size = 473268, upload-time = "2025-10-10T03:54:49.993Z" }, - { url = "https://files.pythonhosted.org/packages/32/4d/9dd616c38da088e3f436e9a616e1d0cc66544b8cdac405cc4e81c8679fc7/httptools-0.7.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:44c8f4347d4b31269c8a9205d8a5ee2df5322b09bbbd30f8f862185bb6b05346", size = 455517, upload-time = "2025-10-10T03:54:51.066Z" }, - { url = "https://files.pythonhosted.org/packages/1d/3a/a6c595c310b7df958e739aae88724e24f9246a514d909547778d776799be/httptools-0.7.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:465275d76db4d554918aba40bf1cbebe324670f3dfc979eaffaa5d108e2ed650", size = 458337, upload-time = "2025-10-10T03:54:52.196Z" }, - { url = "https://files.pythonhosted.org/packages/fd/82/88e8d6d2c51edc1cc391b6e044c6c435b6aebe97b1abc33db1b0b24cd582/httptools-0.7.1-cp313-cp313-win_amd64.whl", hash = "sha256:322d00c2068d125bd570f7bf78b2d367dad02b919d8581d7476d8b75b294e3e6", size = 85743, upload-time = "2025-10-10T03:54:53.448Z" }, - { url = "https://files.pythonhosted.org/packages/34/50/9d095fcbb6de2d523e027a2f304d4551855c2f46e0b82befd718b8b20056/httptools-0.7.1-cp314-cp314-macosx_10_13_universal2.whl", hash = "sha256:c08fe65728b8d70b6923ce31e3956f859d5e1e8548e6f22ec520a962c6757270", size = 203619, upload-time = "2025-10-10T03:54:54.321Z" }, - { url = "https://files.pythonhosted.org/packages/07/f0/89720dc5139ae54b03f861b5e2c55a37dba9a5da7d51e1e824a1f343627f/httptools-0.7.1-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:7aea2e3c3953521c3c51106ee11487a910d45586e351202474d45472db7d72d3", size = 108714, upload-time = "2025-10-10T03:54:55.163Z" }, - { url = "https://files.pythonhosted.org/packages/b3/cb/eea88506f191fb552c11787c23f9a405f4c7b0c5799bf73f2249cd4f5228/httptools-0.7.1-cp314-cp314-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:0e68b8582f4ea9166be62926077a3334064d422cf08ab87d8b74664f8e9058e1", size = 472909, upload-time = "2025-10-10T03:54:56.056Z" }, - { url = "https://files.pythonhosted.org/packages/e0/4a/a548bdfae6369c0d078bab5769f7b66f17f1bfaa6fa28f81d6be6959066b/httptools-0.7.1-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:df091cf961a3be783d6aebae963cc9b71e00d57fa6f149025075217bc6a55a7b", size = 470831, upload-time = "2025-10-10T03:54:57.219Z" }, - { url = "https://files.pythonhosted.org/packages/4d/31/14df99e1c43bd132eec921c2e7e11cda7852f65619bc0fc5bdc2d0cb126c/httptools-0.7.1-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:f084813239e1eb403ddacd06a30de3d3e09a9b76e7894dcda2b22f8a726e9c60", size = 452631, upload-time = "2025-10-10T03:54:58.219Z" }, - { url = "https://files.pythonhosted.org/packages/22/d2/b7e131f7be8d854d48cb6d048113c30f9a46dca0c9a8b08fcb3fcd588cdc/httptools-0.7.1-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:7347714368fb2b335e9063bc2b96f2f87a9ceffcd9758ac295f8bbcd3ffbc0ca", size = 452910, upload-time = "2025-10-10T03:54:59.366Z" }, - { url = "https://files.pythonhosted.org/packages/53/cf/878f3b91e4e6e011eff6d1fa9ca39f7eb17d19c9d7971b04873734112f30/httptools-0.7.1-cp314-cp314-win_amd64.whl", hash = "sha256:cfabda2a5bb85aa2a904ce06d974a3f30fb36cc63d7feaddec05d2050acede96", size = 88205, upload-time = "2025-10-10T03:55:00.389Z" }, + { url = "https://files.pythonhosted.org/packages/09/8f/c77b1fcbfd262d422f12da02feb0d218fa228d52485b77b953832105bb90/httptools-0.7.1-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:6babce6cfa2a99545c60bfef8bee0cc0545413cb0018f617c8059a30ad985de3", size = 202889 }, + { url = "https://files.pythonhosted.org/packages/0a/1a/22887f53602feaa066354867bc49a68fc295c2293433177ee90870a7d517/httptools-0.7.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:601b7628de7504077dd3dcb3791c6b8694bbd967148a6d1f01806509254fb1ca", size = 108180 }, + { url = "https://files.pythonhosted.org/packages/32/6a/6aaa91937f0010d288d3d124ca2946d48d60c3a5ee7ca62afe870e3ea011/httptools-0.7.1-cp313-cp313-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:04c6c0e6c5fb0739c5b8a9eb046d298650a0ff38cf42537fc372b28dc7e4472c", size = 478596 }, + { url = "https://files.pythonhosted.org/packages/6d/70/023d7ce117993107be88d2cbca566a7c1323ccbaf0af7eabf2064fe356f6/httptools-0.7.1-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:69d4f9705c405ae3ee83d6a12283dc9feba8cc6aaec671b412917e644ab4fa66", size = 473268 }, + { url = "https://files.pythonhosted.org/packages/32/4d/9dd616c38da088e3f436e9a616e1d0cc66544b8cdac405cc4e81c8679fc7/httptools-0.7.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:44c8f4347d4b31269c8a9205d8a5ee2df5322b09bbbd30f8f862185bb6b05346", size = 455517 }, + { url = "https://files.pythonhosted.org/packages/1d/3a/a6c595c310b7df958e739aae88724e24f9246a514d909547778d776799be/httptools-0.7.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:465275d76db4d554918aba40bf1cbebe324670f3dfc979eaffaa5d108e2ed650", size = 458337 }, + { url = "https://files.pythonhosted.org/packages/fd/82/88e8d6d2c51edc1cc391b6e044c6c435b6aebe97b1abc33db1b0b24cd582/httptools-0.7.1-cp313-cp313-win_amd64.whl", hash = "sha256:322d00c2068d125bd570f7bf78b2d367dad02b919d8581d7476d8b75b294e3e6", size = 85743 }, + { url = "https://files.pythonhosted.org/packages/34/50/9d095fcbb6de2d523e027a2f304d4551855c2f46e0b82befd718b8b20056/httptools-0.7.1-cp314-cp314-macosx_10_13_universal2.whl", hash = "sha256:c08fe65728b8d70b6923ce31e3956f859d5e1e8548e6f22ec520a962c6757270", size = 203619 }, + { url = "https://files.pythonhosted.org/packages/07/f0/89720dc5139ae54b03f861b5e2c55a37dba9a5da7d51e1e824a1f343627f/httptools-0.7.1-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:7aea2e3c3953521c3c51106ee11487a910d45586e351202474d45472db7d72d3", size = 108714 }, + { url = "https://files.pythonhosted.org/packages/b3/cb/eea88506f191fb552c11787c23f9a405f4c7b0c5799bf73f2249cd4f5228/httptools-0.7.1-cp314-cp314-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:0e68b8582f4ea9166be62926077a3334064d422cf08ab87d8b74664f8e9058e1", size = 472909 }, + { url = "https://files.pythonhosted.org/packages/e0/4a/a548bdfae6369c0d078bab5769f7b66f17f1bfaa6fa28f81d6be6959066b/httptools-0.7.1-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:df091cf961a3be783d6aebae963cc9b71e00d57fa6f149025075217bc6a55a7b", size = 470831 }, + { url = "https://files.pythonhosted.org/packages/4d/31/14df99e1c43bd132eec921c2e7e11cda7852f65619bc0fc5bdc2d0cb126c/httptools-0.7.1-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:f084813239e1eb403ddacd06a30de3d3e09a9b76e7894dcda2b22f8a726e9c60", size = 452631 }, + { url = "https://files.pythonhosted.org/packages/22/d2/b7e131f7be8d854d48cb6d048113c30f9a46dca0c9a8b08fcb3fcd588cdc/httptools-0.7.1-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:7347714368fb2b335e9063bc2b96f2f87a9ceffcd9758ac295f8bbcd3ffbc0ca", size = 452910 }, + { url = "https://files.pythonhosted.org/packages/53/cf/878f3b91e4e6e011eff6d1fa9ca39f7eb17d19c9d7971b04873734112f30/httptools-0.7.1-cp314-cp314-win_amd64.whl", hash = "sha256:cfabda2a5bb85aa2a904ce06d974a3f30fb36cc63d7feaddec05d2050acede96", size = 88205 }, ] [[package]] @@ -913,9 +922,9 @@ dependencies = [ { name = "httpcore" }, { name = "idna" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/b1/df/48c586a5fe32a0f01324ee087459e112ebb7224f646c0b5023f5e79e9956/httpx-0.28.1.tar.gz", hash = "sha256:75e98c5f16b0f35b567856f597f06ff2270a374470a5c2392242528e3e3e42fc", size = 141406, upload-time = "2024-12-06T15:37:23.222Z" } +sdist = { url = "https://files.pythonhosted.org/packages/b1/df/48c586a5fe32a0f01324ee087459e112ebb7224f646c0b5023f5e79e9956/httpx-0.28.1.tar.gz", hash = "sha256:75e98c5f16b0f35b567856f597f06ff2270a374470a5c2392242528e3e3e42fc", size = 141406 } wheels = [ - { url = "https://files.pythonhosted.org/packages/2a/39/e50c7c3a983047577ee07d2a9e53faf5a69493943ec3f6a384bdc792deb2/httpx-0.28.1-py3-none-any.whl", hash = "sha256:d909fcccc110f8c7faf814ca82a9a4d816bc5a6dbfea25d6591d6985b8ba59ad", size = 73517, upload-time = "2024-12-06T15:37:21.509Z" }, + { url = "https://files.pythonhosted.org/packages/2a/39/e50c7c3a983047577ee07d2a9e53faf5a69493943ec3f6a384bdc792deb2/httpx-0.28.1-py3-none-any.whl", hash = "sha256:d909fcccc110f8c7faf814ca82a9a4d816bc5a6dbfea25d6591d6985b8ba59ad", size = 73517 }, ] [[package]] @@ -925,9 +934,9 @@ source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "httpx" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/2f/07/db4ad128da3926be22eec586aa87dafd8840c9eb03fe88505fbed016b5c6/httpx_oauth-0.16.1.tar.gz", hash = "sha256:7402f061f860abc092ea4f5c90acfc576a40bbb79633c1d2920f1ca282c296ee", size = 44148, upload-time = "2024-12-20T07:23:02.589Z" } +sdist = { url = "https://files.pythonhosted.org/packages/2f/07/db4ad128da3926be22eec586aa87dafd8840c9eb03fe88505fbed016b5c6/httpx_oauth-0.16.1.tar.gz", hash = "sha256:7402f061f860abc092ea4f5c90acfc576a40bbb79633c1d2920f1ca282c296ee", size = 44148 } wheels = [ - { url = "https://files.pythonhosted.org/packages/45/4b/2b81e876abf77b4af3372aff731f4f6722840ebc7dcfd85778eaba271733/httpx_oauth-0.16.1-py3-none-any.whl", hash = "sha256:2fcad82f80f28d0473a0fc4b4eda223dc952050af7e3a8c8781342d850f09fb5", size = 38056, upload-time = "2024-12-20T07:23:00.394Z" }, + { url = "https://files.pythonhosted.org/packages/45/4b/2b81e876abf77b4af3372aff731f4f6722840ebc7dcfd85778eaba271733/httpx_oauth-0.16.1-py3-none-any.whl", hash = "sha256:2fcad82f80f28d0473a0fc4b4eda223dc952050af7e3a8c8781342d850f09fb5", size = 38056 }, ] [[package]] @@ -937,36 +946,36 @@ source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "pyreadline3", marker = "sys_platform == 'win32'" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/cc/3f/2c29224acb2e2df4d2046e4c73ee2662023c58ff5b113c4c1adac0886c43/humanfriendly-10.0.tar.gz", hash = "sha256:6b0b831ce8f15f7300721aa49829fc4e83921a9a301cc7f606be6686a2288ddc", size = 360702, upload-time = "2021-09-17T21:40:43.31Z" } +sdist = { url = "https://files.pythonhosted.org/packages/cc/3f/2c29224acb2e2df4d2046e4c73ee2662023c58ff5b113c4c1adac0886c43/humanfriendly-10.0.tar.gz", hash = "sha256:6b0b831ce8f15f7300721aa49829fc4e83921a9a301cc7f606be6686a2288ddc", size = 360702 } wheels = [ - { url = "https://files.pythonhosted.org/packages/f0/0f/310fb31e39e2d734ccaa2c0fb981ee41f7bd5056ce9bc29b2248bd569169/humanfriendly-10.0-py2.py3-none-any.whl", hash = "sha256:1697e1a8a8f550fd43c2865cd84542fc175a61dcb779b6fee18cf6b6ccba1477", size = 86794, upload-time = "2021-09-17T21:40:39.897Z" }, + { url = "https://files.pythonhosted.org/packages/f0/0f/310fb31e39e2d734ccaa2c0fb981ee41f7bd5056ce9bc29b2248bd569169/humanfriendly-10.0-py2.py3-none-any.whl", hash = "sha256:1697e1a8a8f550fd43c2865cd84542fc175a61dcb779b6fee18cf6b6ccba1477", size = 86794 }, ] [[package]] name = "idna" version = "3.11" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/6f/6d/0703ccc57f3a7233505399edb88de3cbd678da106337b9fcde432b65ed60/idna-3.11.tar.gz", hash = "sha256:795dafcc9c04ed0c1fb032c2aa73654d8e8c5023a7df64a53f39190ada629902", size = 194582, upload-time = "2025-10-12T14:55:20.501Z" } +sdist = { url = "https://files.pythonhosted.org/packages/6f/6d/0703ccc57f3a7233505399edb88de3cbd678da106337b9fcde432b65ed60/idna-3.11.tar.gz", hash = "sha256:795dafcc9c04ed0c1fb032c2aa73654d8e8c5023a7df64a53f39190ada629902", size = 194582 } wheels = [ - { url = "https://files.pythonhosted.org/packages/0e/61/66938bbb5fc52dbdf84594873d5b51fb1f7c7794e9c0f5bd885f30bc507b/idna-3.11-py3-none-any.whl", hash = "sha256:771a87f49d9defaf64091e6e6fe9c18d4833f140bd19464795bc32d966ca37ea", size = 71008, upload-time = "2025-10-12T14:55:18.883Z" }, + { url = "https://files.pythonhosted.org/packages/0e/61/66938bbb5fc52dbdf84594873d5b51fb1f7c7794e9c0f5bd885f30bc507b/idna-3.11-py3-none-any.whl", hash = "sha256:771a87f49d9defaf64091e6e6fe9c18d4833f140bd19464795bc32d966ca37ea", size = 71008 }, ] [[package]] name = "iniconfig" version = "2.3.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/72/34/14ca021ce8e5dfedc35312d08ba8bf51fdd999c576889fc2c24cb97f4f10/iniconfig-2.3.0.tar.gz", hash = "sha256:c76315c77db068650d49c5b56314774a7804df16fee4402c1f19d6d15d8c4730", size = 20503, upload-time = "2025-10-18T21:55:43.219Z" } +sdist = { url = "https://files.pythonhosted.org/packages/72/34/14ca021ce8e5dfedc35312d08ba8bf51fdd999c576889fc2c24cb97f4f10/iniconfig-2.3.0.tar.gz", hash = "sha256:c76315c77db068650d49c5b56314774a7804df16fee4402c1f19d6d15d8c4730", size = 20503 } wheels = [ - { url = "https://files.pythonhosted.org/packages/cb/b1/3846dd7f199d53cb17f49cba7e651e9ce294d8497c8c150530ed11865bb8/iniconfig-2.3.0-py3-none-any.whl", hash = "sha256:f631c04d2c48c52b84d0d0549c99ff3859c98df65b3101406327ecc7d53fbf12", size = 7484, upload-time = "2025-10-18T21:55:41.639Z" }, + { url = "https://files.pythonhosted.org/packages/cb/b1/3846dd7f199d53cb17f49cba7e651e9ce294d8497c8c150530ed11865bb8/iniconfig-2.3.0-py3-none-any.whl", hash = "sha256:f631c04d2c48c52b84d0d0549c99ff3859c98df65b3101406327ecc7d53fbf12", size = 7484 }, ] [[package]] name = "itsdangerous" version = "2.2.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/9c/cb/8ac0172223afbccb63986cc25049b154ecfb5e85932587206f42317be31d/itsdangerous-2.2.0.tar.gz", hash = "sha256:e0050c0b7da1eea53ffaf149c0cfbb5c6e2e2b69c4bef22c81fa6eb73e5f6173", size = 54410, upload-time = "2024-04-16T21:28:15.614Z" } +sdist = { url = "https://files.pythonhosted.org/packages/9c/cb/8ac0172223afbccb63986cc25049b154ecfb5e85932587206f42317be31d/itsdangerous-2.2.0.tar.gz", hash = "sha256:e0050c0b7da1eea53ffaf149c0cfbb5c6e2e2b69c4bef22c81fa6eb73e5f6173", size = 54410 } wheels = [ - { url = "https://files.pythonhosted.org/packages/04/96/92447566d16df59b2a776c0fb82dbc4d9e07cd95062562af01e408583fc4/itsdangerous-2.2.0-py3-none-any.whl", hash = "sha256:c6242fc49e35958c8b15141343aa660db5fc54d4f13a1db01a3f5891b98700ef", size = 16234, upload-time = "2024-04-16T21:28:14.499Z" }, + { url = "https://files.pythonhosted.org/packages/04/96/92447566d16df59b2a776c0fb82dbc4d9e07cd95062562af01e408583fc4/itsdangerous-2.2.0-py3-none-any.whl", hash = "sha256:c6242fc49e35958c8b15141343aa660db5fc54d4f13a1db01a3f5891b98700ef", size = 16234 }, ] [[package]] @@ -976,27 +985,27 @@ source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "markupsafe" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/df/bf/f7da0350254c0ed7c72f3e33cef02e048281fec7ecec5f032d4aac52226b/jinja2-3.1.6.tar.gz", hash = "sha256:0137fb05990d35f1275a587e9aee6d56da821fc83491a0fb838183be43f66d6d", size = 245115, upload-time = "2025-03-05T20:05:02.478Z" } +sdist = { url = "https://files.pythonhosted.org/packages/df/bf/f7da0350254c0ed7c72f3e33cef02e048281fec7ecec5f032d4aac52226b/jinja2-3.1.6.tar.gz", hash = "sha256:0137fb05990d35f1275a587e9aee6d56da821fc83491a0fb838183be43f66d6d", size = 245115 } wheels = [ - { url = "https://files.pythonhosted.org/packages/62/a1/3d680cbfd5f4b8f15abc1d571870c5fc3e594bb582bc3b64ea099db13e56/jinja2-3.1.6-py3-none-any.whl", hash = "sha256:85ece4451f492d0c13c5dd7c13a64681a86afae63a5f347908daf103ce6d2f67", size = 134899, upload-time = "2025-03-05T20:05:00.369Z" }, + { url = "https://files.pythonhosted.org/packages/62/a1/3d680cbfd5f4b8f15abc1d571870c5fc3e594bb582bc3b64ea099db13e56/jinja2-3.1.6-py3-none-any.whl", hash = "sha256:85ece4451f492d0c13c5dd7c13a64681a86afae63a5f347908daf103ce6d2f67", size = 134899 }, ] [[package]] name = "jmespath" version = "1.0.1" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/00/2a/e867e8531cf3e36b41201936b7fa7ba7b5702dbef42922193f05c8976cd6/jmespath-1.0.1.tar.gz", hash = "sha256:90261b206d6defd58fdd5e85f478bf633a2901798906be2ad389150c5c60edbe", size = 25843, upload-time = "2022-06-17T18:00:12.224Z" } +sdist = { url = "https://files.pythonhosted.org/packages/00/2a/e867e8531cf3e36b41201936b7fa7ba7b5702dbef42922193f05c8976cd6/jmespath-1.0.1.tar.gz", hash = "sha256:90261b206d6defd58fdd5e85f478bf633a2901798906be2ad389150c5c60edbe", size = 25843 } wheels = [ - { url = "https://files.pythonhosted.org/packages/31/b4/b9b800c45527aadd64d5b442f9b932b00648617eb5d63d2c7a6587b7cafc/jmespath-1.0.1-py3-none-any.whl", hash = "sha256:02e2e4cc71b5bcab88332eebf907519190dd9e6e82107fa7f83b1003a6252980", size = 20256, upload-time = "2022-06-17T18:00:10.251Z" }, + { url = "https://files.pythonhosted.org/packages/31/b4/b9b800c45527aadd64d5b442f9b932b00648617eb5d63d2c7a6587b7cafc/jmespath-1.0.1-py3-none-any.whl", hash = "sha256:02e2e4cc71b5bcab88332eebf907519190dd9e6e82107fa7f83b1003a6252980", size = 20256 }, ] [[package]] name = "makefun" version = "1.16.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/7b/cf/6780ab8bc3b84a1cce3e4400aed3d64b6db7d5e227a2f75b6ded5674701a/makefun-1.16.0.tar.gz", hash = "sha256:e14601831570bff1f6d7e68828bcd30d2f5856f24bad5de0ccb22921ceebc947", size = 73565, upload-time = "2025-05-09T15:00:42.313Z" } +sdist = { url = "https://files.pythonhosted.org/packages/7b/cf/6780ab8bc3b84a1cce3e4400aed3d64b6db7d5e227a2f75b6ded5674701a/makefun-1.16.0.tar.gz", hash = "sha256:e14601831570bff1f6d7e68828bcd30d2f5856f24bad5de0ccb22921ceebc947", size = 73565 } wheels = [ - { url = "https://files.pythonhosted.org/packages/b7/c0/4bc973defd1270b89ccaae04cef0d5fa3ea85b59b108ad2c08aeea9afb76/makefun-1.16.0-py2.py3-none-any.whl", hash = "sha256:43baa4c3e7ae2b17de9ceac20b669e9a67ceeadff31581007cca20a07bbe42c4", size = 22923, upload-time = "2025-05-09T15:00:41.042Z" }, + { url = "https://files.pythonhosted.org/packages/b7/c0/4bc973defd1270b89ccaae04cef0d5fa3ea85b59b108ad2c08aeea9afb76/makefun-1.16.0-py2.py3-none-any.whl", hash = "sha256:43baa4c3e7ae2b17de9ceac20b669e9a67ceeadff31581007cca20a07bbe42c4", size = 22923 }, ] [[package]] @@ -1006,18 +1015,18 @@ source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "markupsafe" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/9e/38/bd5b78a920a64d708fe6bc8e0a2c075e1389d53bef8413725c63ba041535/mako-1.3.10.tar.gz", hash = "sha256:99579a6f39583fa7e5630a28c3c1f440e4e97a414b80372649c0ce338da2ea28", size = 392474, upload-time = "2025-04-10T12:44:31.16Z" } +sdist = { url = "https://files.pythonhosted.org/packages/9e/38/bd5b78a920a64d708fe6bc8e0a2c075e1389d53bef8413725c63ba041535/mako-1.3.10.tar.gz", hash = "sha256:99579a6f39583fa7e5630a28c3c1f440e4e97a414b80372649c0ce338da2ea28", size = 392474 } wheels = [ - { url = "https://files.pythonhosted.org/packages/87/fb/99f81ac72ae23375f22b7afdb7642aba97c00a713c217124420147681a2f/mako-1.3.10-py3-none-any.whl", hash = "sha256:baef24a52fc4fc514a0887ac600f9f1cff3d82c61d4d700a1fa84d597b88db59", size = 78509, upload-time = "2025-04-10T12:50:53.297Z" }, + { url = "https://files.pythonhosted.org/packages/87/fb/99f81ac72ae23375f22b7afdb7642aba97c00a713c217124420147681a2f/mako-1.3.10-py3-none-any.whl", hash = "sha256:baef24a52fc4fc514a0887ac600f9f1cff3d82c61d4d700a1fa84d597b88db59", size = 78509 }, ] [[package]] name = "markdown" -version = "3.9" +version = "3.10" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/8d/37/02347f6d6d8279247a5837082ebc26fc0d5aaeaf75aa013fcbb433c777ab/markdown-3.9.tar.gz", hash = "sha256:d2900fe1782bd33bdbbd56859defef70c2e78fc46668f8eb9df3128138f2cb6a", size = 364585, upload-time = "2025-09-04T20:25:22.885Z" } +sdist = { url = "https://files.pythonhosted.org/packages/7d/ab/7dd27d9d863b3376fcf23a5a13cb5d024aed1db46f963f1b5735ae43b3be/markdown-3.10.tar.gz", hash = "sha256:37062d4f2aa4b2b6b32aefb80faa300f82cc790cb949a35b8caede34f2b68c0e", size = 364931 } wheels = [ - { url = "https://files.pythonhosted.org/packages/70/ae/44c4a6a4cbb496d93c6257954260fe3a6e91b7bed2240e5dad2a717f5111/markdown-3.9-py3-none-any.whl", hash = "sha256:9f4d91ed810864ea88a6f32c07ba8bee1346c0cc1f6b1f9f6c822f2a9667d280", size = 107441, upload-time = "2025-09-04T20:25:21.784Z" }, + { url = "https://files.pythonhosted.org/packages/70/81/54e3ce63502cd085a0c556652a4e1b919c45a446bd1e5300e10c44c8c521/markdown-3.10-py3-none-any.whl", hash = "sha256:b5b99d6951e2e4948d939255596523444c0e677c669700b1d17aa4a8a464cb7c", size = 107678 }, ] [[package]] @@ -1027,70 +1036,70 @@ source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "mdurl" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/5b/f5/4ec618ed16cc4f8fb3b701563655a69816155e79e24a17b651541804721d/markdown_it_py-4.0.0.tar.gz", hash = "sha256:cb0a2b4aa34f932c007117b194e945bd74e0ec24133ceb5bac59009cda1cb9f3", size = 73070, upload-time = "2025-08-11T12:57:52.854Z" } +sdist = { url = "https://files.pythonhosted.org/packages/5b/f5/4ec618ed16cc4f8fb3b701563655a69816155e79e24a17b651541804721d/markdown_it_py-4.0.0.tar.gz", hash = "sha256:cb0a2b4aa34f932c007117b194e945bd74e0ec24133ceb5bac59009cda1cb9f3", size = 73070 } wheels = [ - { url = "https://files.pythonhosted.org/packages/94/54/e7d793b573f298e1c9013b8c4dade17d481164aa517d1d7148619c2cedbf/markdown_it_py-4.0.0-py3-none-any.whl", hash = "sha256:87327c59b172c5011896038353a81343b6754500a08cd7a4973bb48c6d578147", size = 87321, upload-time = "2025-08-11T12:57:51.923Z" }, + { url = "https://files.pythonhosted.org/packages/94/54/e7d793b573f298e1c9013b8c4dade17d481164aa517d1d7148619c2cedbf/markdown_it_py-4.0.0-py3-none-any.whl", hash = "sha256:87327c59b172c5011896038353a81343b6754500a08cd7a4973bb48c6d578147", size = 87321 }, ] [[package]] name = "markupsafe" version = "3.0.3" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/7e/99/7690b6d4034fffd95959cbe0c02de8deb3098cc577c67bb6a24fe5d7caa7/markupsafe-3.0.3.tar.gz", hash = "sha256:722695808f4b6457b320fdc131280796bdceb04ab50fe1795cd540799ebe1698", size = 80313, upload-time = "2025-09-27T18:37:40.426Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/38/2f/907b9c7bbba283e68f20259574b13d005c121a0fa4c175f9bed27c4597ff/markupsafe-3.0.3-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:e1cf1972137e83c5d4c136c43ced9ac51d0e124706ee1c8aa8532c1287fa8795", size = 11622, upload-time = "2025-09-27T18:36:41.777Z" }, - { url = "https://files.pythonhosted.org/packages/9c/d9/5f7756922cdd676869eca1c4e3c0cd0df60ed30199ffd775e319089cb3ed/markupsafe-3.0.3-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:116bb52f642a37c115f517494ea5feb03889e04df47eeff5b130b1808ce7c219", size = 12029, upload-time = "2025-09-27T18:36:43.257Z" }, - { url = "https://files.pythonhosted.org/packages/00/07/575a68c754943058c78f30db02ee03a64b3c638586fba6a6dd56830b30a3/markupsafe-3.0.3-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:133a43e73a802c5562be9bbcd03d090aa5a1fe899db609c29e8c8d815c5f6de6", size = 24374, upload-time = "2025-09-27T18:36:44.508Z" }, - { url = "https://files.pythonhosted.org/packages/a9/21/9b05698b46f218fc0e118e1f8168395c65c8a2c750ae2bab54fc4bd4e0e8/markupsafe-3.0.3-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:ccfcd093f13f0f0b7fdd0f198b90053bf7b2f02a3927a30e63f3ccc9df56b676", size = 22980, upload-time = "2025-09-27T18:36:45.385Z" }, - { url = "https://files.pythonhosted.org/packages/7f/71/544260864f893f18b6827315b988c146b559391e6e7e8f7252839b1b846a/markupsafe-3.0.3-cp313-cp313-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:509fa21c6deb7a7a273d629cf5ec029bc209d1a51178615ddf718f5918992ab9", size = 21990, upload-time = "2025-09-27T18:36:46.916Z" }, - { url = "https://files.pythonhosted.org/packages/c2/28/b50fc2f74d1ad761af2f5dcce7492648b983d00a65b8c0e0cb457c82ebbe/markupsafe-3.0.3-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:a4afe79fb3de0b7097d81da19090f4df4f8d3a2b3adaa8764138aac2e44f3af1", size = 23784, upload-time = "2025-09-27T18:36:47.884Z" }, - { url = "https://files.pythonhosted.org/packages/ed/76/104b2aa106a208da8b17a2fb72e033a5a9d7073c68f7e508b94916ed47a9/markupsafe-3.0.3-cp313-cp313-musllinux_1_2_riscv64.whl", hash = "sha256:795e7751525cae078558e679d646ae45574b47ed6e7771863fcc079a6171a0fc", size = 21588, upload-time = "2025-09-27T18:36:48.82Z" }, - { url = "https://files.pythonhosted.org/packages/b5/99/16a5eb2d140087ebd97180d95249b00a03aa87e29cc224056274f2e45fd6/markupsafe-3.0.3-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:8485f406a96febb5140bfeca44a73e3ce5116b2501ac54fe953e488fb1d03b12", size = 23041, upload-time = "2025-09-27T18:36:49.797Z" }, - { url = "https://files.pythonhosted.org/packages/19/bc/e7140ed90c5d61d77cea142eed9f9c303f4c4806f60a1044c13e3f1471d0/markupsafe-3.0.3-cp313-cp313-win32.whl", hash = "sha256:bdd37121970bfd8be76c5fb069c7751683bdf373db1ed6c010162b2a130248ed", size = 14543, upload-time = "2025-09-27T18:36:51.584Z" }, - { url = "https://files.pythonhosted.org/packages/05/73/c4abe620b841b6b791f2edc248f556900667a5a1cf023a6646967ae98335/markupsafe-3.0.3-cp313-cp313-win_amd64.whl", hash = "sha256:9a1abfdc021a164803f4d485104931fb8f8c1efd55bc6b748d2f5774e78b62c5", size = 15113, upload-time = "2025-09-27T18:36:52.537Z" }, - { url = "https://files.pythonhosted.org/packages/f0/3a/fa34a0f7cfef23cf9500d68cb7c32dd64ffd58a12b09225fb03dd37d5b80/markupsafe-3.0.3-cp313-cp313-win_arm64.whl", hash = "sha256:7e68f88e5b8799aa49c85cd116c932a1ac15caaa3f5db09087854d218359e485", size = 13911, upload-time = "2025-09-27T18:36:53.513Z" }, - { url = "https://files.pythonhosted.org/packages/e4/d7/e05cd7efe43a88a17a37b3ae96e79a19e846f3f456fe79c57ca61356ef01/markupsafe-3.0.3-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:218551f6df4868a8d527e3062d0fb968682fe92054e89978594c28e642c43a73", size = 11658, upload-time = "2025-09-27T18:36:54.819Z" }, - { url = "https://files.pythonhosted.org/packages/99/9e/e412117548182ce2148bdeacdda3bb494260c0b0184360fe0d56389b523b/markupsafe-3.0.3-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:3524b778fe5cfb3452a09d31e7b5adefeea8c5be1d43c4f810ba09f2ceb29d37", size = 12066, upload-time = "2025-09-27T18:36:55.714Z" }, - { url = "https://files.pythonhosted.org/packages/bc/e6/fa0ffcda717ef64a5108eaa7b4f5ed28d56122c9a6d70ab8b72f9f715c80/markupsafe-3.0.3-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:4e885a3d1efa2eadc93c894a21770e4bc67899e3543680313b09f139e149ab19", size = 25639, upload-time = "2025-09-27T18:36:56.908Z" }, - { url = "https://files.pythonhosted.org/packages/96/ec/2102e881fe9d25fc16cb4b25d5f5cde50970967ffa5dddafdb771237062d/markupsafe-3.0.3-cp313-cp313t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:8709b08f4a89aa7586de0aadc8da56180242ee0ada3999749b183aa23df95025", size = 23569, upload-time = "2025-09-27T18:36:57.913Z" }, - { url = "https://files.pythonhosted.org/packages/4b/30/6f2fce1f1f205fc9323255b216ca8a235b15860c34b6798f810f05828e32/markupsafe-3.0.3-cp313-cp313t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:b8512a91625c9b3da6f127803b166b629725e68af71f8184ae7e7d54686a56d6", size = 23284, upload-time = "2025-09-27T18:36:58.833Z" }, - { url = "https://files.pythonhosted.org/packages/58/47/4a0ccea4ab9f5dcb6f79c0236d954acb382202721e704223a8aafa38b5c8/markupsafe-3.0.3-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:9b79b7a16f7fedff2495d684f2b59b0457c3b493778c9eed31111be64d58279f", size = 24801, upload-time = "2025-09-27T18:36:59.739Z" }, - { url = "https://files.pythonhosted.org/packages/6a/70/3780e9b72180b6fecb83a4814d84c3bf4b4ae4bf0b19c27196104149734c/markupsafe-3.0.3-cp313-cp313t-musllinux_1_2_riscv64.whl", hash = "sha256:12c63dfb4a98206f045aa9563db46507995f7ef6d83b2f68eda65c307c6829eb", size = 22769, upload-time = "2025-09-27T18:37:00.719Z" }, - { url = "https://files.pythonhosted.org/packages/98/c5/c03c7f4125180fc215220c035beac6b9cb684bc7a067c84fc69414d315f5/markupsafe-3.0.3-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:8f71bc33915be5186016f675cd83a1e08523649b0e33efdb898db577ef5bb009", size = 23642, upload-time = "2025-09-27T18:37:01.673Z" }, - { url = "https://files.pythonhosted.org/packages/80/d6/2d1b89f6ca4bff1036499b1e29a1d02d282259f3681540e16563f27ebc23/markupsafe-3.0.3-cp313-cp313t-win32.whl", hash = "sha256:69c0b73548bc525c8cb9a251cddf1931d1db4d2258e9599c28c07ef3580ef354", size = 14612, upload-time = "2025-09-27T18:37:02.639Z" }, - { url = "https://files.pythonhosted.org/packages/2b/98/e48a4bfba0a0ffcf9925fe2d69240bfaa19c6f7507b8cd09c70684a53c1e/markupsafe-3.0.3-cp313-cp313t-win_amd64.whl", hash = "sha256:1b4b79e8ebf6b55351f0d91fe80f893b4743f104bff22e90697db1590e47a218", size = 15200, upload-time = "2025-09-27T18:37:03.582Z" }, - { url = "https://files.pythonhosted.org/packages/0e/72/e3cc540f351f316e9ed0f092757459afbc595824ca724cbc5a5d4263713f/markupsafe-3.0.3-cp313-cp313t-win_arm64.whl", hash = "sha256:ad2cf8aa28b8c020ab2fc8287b0f823d0a7d8630784c31e9ee5edea20f406287", size = 13973, upload-time = "2025-09-27T18:37:04.929Z" }, - { url = "https://files.pythonhosted.org/packages/33/8a/8e42d4838cd89b7dde187011e97fe6c3af66d8c044997d2183fbd6d31352/markupsafe-3.0.3-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:eaa9599de571d72e2daf60164784109f19978b327a3910d3e9de8c97b5b70cfe", size = 11619, upload-time = "2025-09-27T18:37:06.342Z" }, - { url = "https://files.pythonhosted.org/packages/b5/64/7660f8a4a8e53c924d0fa05dc3a55c9cee10bbd82b11c5afb27d44b096ce/markupsafe-3.0.3-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:c47a551199eb8eb2121d4f0f15ae0f923d31350ab9280078d1e5f12b249e0026", size = 12029, upload-time = "2025-09-27T18:37:07.213Z" }, - { url = "https://files.pythonhosted.org/packages/da/ef/e648bfd021127bef5fa12e1720ffed0c6cbb8310c8d9bea7266337ff06de/markupsafe-3.0.3-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:f34c41761022dd093b4b6896d4810782ffbabe30f2d443ff5f083e0cbbb8c737", size = 24408, upload-time = "2025-09-27T18:37:09.572Z" }, - { url = "https://files.pythonhosted.org/packages/41/3c/a36c2450754618e62008bf7435ccb0f88053e07592e6028a34776213d877/markupsafe-3.0.3-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:457a69a9577064c05a97c41f4e65148652db078a3a509039e64d3467b9e7ef97", size = 23005, upload-time = "2025-09-27T18:37:10.58Z" }, - { url = "https://files.pythonhosted.org/packages/bc/20/b7fdf89a8456b099837cd1dc21974632a02a999ec9bf7ca3e490aacd98e7/markupsafe-3.0.3-cp314-cp314-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:e8afc3f2ccfa24215f8cb28dcf43f0113ac3c37c2f0f0806d8c70e4228c5cf4d", size = 22048, upload-time = "2025-09-27T18:37:11.547Z" }, - { url = "https://files.pythonhosted.org/packages/9a/a7/591f592afdc734f47db08a75793a55d7fbcc6902a723ae4cfbab61010cc5/markupsafe-3.0.3-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:ec15a59cf5af7be74194f7ab02d0f59a62bdcf1a537677ce67a2537c9b87fcda", size = 23821, upload-time = "2025-09-27T18:37:12.48Z" }, - { url = "https://files.pythonhosted.org/packages/7d/33/45b24e4f44195b26521bc6f1a82197118f74df348556594bd2262bda1038/markupsafe-3.0.3-cp314-cp314-musllinux_1_2_riscv64.whl", hash = "sha256:0eb9ff8191e8498cca014656ae6b8d61f39da5f95b488805da4bb029cccbfbaf", size = 21606, upload-time = "2025-09-27T18:37:13.485Z" }, - { url = "https://files.pythonhosted.org/packages/ff/0e/53dfaca23a69fbfbbf17a4b64072090e70717344c52eaaaa9c5ddff1e5f0/markupsafe-3.0.3-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:2713baf880df847f2bece4230d4d094280f4e67b1e813eec43b4c0e144a34ffe", size = 23043, upload-time = "2025-09-27T18:37:14.408Z" }, - { url = "https://files.pythonhosted.org/packages/46/11/f333a06fc16236d5238bfe74daccbca41459dcd8d1fa952e8fbd5dccfb70/markupsafe-3.0.3-cp314-cp314-win32.whl", hash = "sha256:729586769a26dbceff69f7a7dbbf59ab6572b99d94576a5592625d5b411576b9", size = 14747, upload-time = "2025-09-27T18:37:15.36Z" }, - { url = "https://files.pythonhosted.org/packages/28/52/182836104b33b444e400b14f797212f720cbc9ed6ba34c800639d154e821/markupsafe-3.0.3-cp314-cp314-win_amd64.whl", hash = "sha256:bdc919ead48f234740ad807933cdf545180bfbe9342c2bb451556db2ed958581", size = 15341, upload-time = "2025-09-27T18:37:16.496Z" }, - { url = "https://files.pythonhosted.org/packages/6f/18/acf23e91bd94fd7b3031558b1f013adfa21a8e407a3fdb32745538730382/markupsafe-3.0.3-cp314-cp314-win_arm64.whl", hash = "sha256:5a7d5dc5140555cf21a6fefbdbf8723f06fcd2f63ef108f2854de715e4422cb4", size = 14073, upload-time = "2025-09-27T18:37:17.476Z" }, - { url = "https://files.pythonhosted.org/packages/3c/f0/57689aa4076e1b43b15fdfa646b04653969d50cf30c32a102762be2485da/markupsafe-3.0.3-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:1353ef0c1b138e1907ae78e2f6c63ff67501122006b0f9abad68fda5f4ffc6ab", size = 11661, upload-time = "2025-09-27T18:37:18.453Z" }, - { url = "https://files.pythonhosted.org/packages/89/c3/2e67a7ca217c6912985ec766c6393b636fb0c2344443ff9d91404dc4c79f/markupsafe-3.0.3-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:1085e7fbddd3be5f89cc898938f42c0b3c711fdcb37d75221de2666af647c175", size = 12069, upload-time = "2025-09-27T18:37:19.332Z" }, - { url = "https://files.pythonhosted.org/packages/f0/00/be561dce4e6ca66b15276e184ce4b8aec61fe83662cce2f7d72bd3249d28/markupsafe-3.0.3-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:1b52b4fb9df4eb9ae465f8d0c228a00624de2334f216f178a995ccdcf82c4634", size = 25670, upload-time = "2025-09-27T18:37:20.245Z" }, - { url = "https://files.pythonhosted.org/packages/50/09/c419f6f5a92e5fadde27efd190eca90f05e1261b10dbd8cbcb39cd8ea1dc/markupsafe-3.0.3-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:fed51ac40f757d41b7c48425901843666a6677e3e8eb0abcff09e4ba6e664f50", size = 23598, upload-time = "2025-09-27T18:37:21.177Z" }, - { url = "https://files.pythonhosted.org/packages/22/44/a0681611106e0b2921b3033fc19bc53323e0b50bc70cffdd19f7d679bb66/markupsafe-3.0.3-cp314-cp314t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:f190daf01f13c72eac4efd5c430a8de82489d9cff23c364c3ea822545032993e", size = 23261, upload-time = "2025-09-27T18:37:22.167Z" }, - { url = "https://files.pythonhosted.org/packages/5f/57/1b0b3f100259dc9fffe780cfb60d4be71375510e435efec3d116b6436d43/markupsafe-3.0.3-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:e56b7d45a839a697b5eb268c82a71bd8c7f6c94d6fd50c3d577fa39a9f1409f5", size = 24835, upload-time = "2025-09-27T18:37:23.296Z" }, - { url = "https://files.pythonhosted.org/packages/26/6a/4bf6d0c97c4920f1597cc14dd720705eca0bf7c787aebc6bb4d1bead5388/markupsafe-3.0.3-cp314-cp314t-musllinux_1_2_riscv64.whl", hash = "sha256:f3e98bb3798ead92273dc0e5fd0f31ade220f59a266ffd8a4f6065e0a3ce0523", size = 22733, upload-time = "2025-09-27T18:37:24.237Z" }, - { url = "https://files.pythonhosted.org/packages/14/c7/ca723101509b518797fedc2fdf79ba57f886b4aca8a7d31857ba3ee8281f/markupsafe-3.0.3-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:5678211cb9333a6468fb8d8be0305520aa073f50d17f089b5b4b477ea6e67fdc", size = 23672, upload-time = "2025-09-27T18:37:25.271Z" }, - { url = "https://files.pythonhosted.org/packages/fb/df/5bd7a48c256faecd1d36edc13133e51397e41b73bb77e1a69deab746ebac/markupsafe-3.0.3-cp314-cp314t-win32.whl", hash = "sha256:915c04ba3851909ce68ccc2b8e2cd691618c4dc4c4232fb7982bca3f41fd8c3d", size = 14819, upload-time = "2025-09-27T18:37:26.285Z" }, - { url = "https://files.pythonhosted.org/packages/1a/8a/0402ba61a2f16038b48b39bccca271134be00c5c9f0f623208399333c448/markupsafe-3.0.3-cp314-cp314t-win_amd64.whl", hash = "sha256:4faffd047e07c38848ce017e8725090413cd80cbc23d86e55c587bf979e579c9", size = 15426, upload-time = "2025-09-27T18:37:27.316Z" }, - { url = "https://files.pythonhosted.org/packages/70/bc/6f1c2f612465f5fa89b95bead1f44dcb607670fd42891d8fdcd5d039f4f4/markupsafe-3.0.3-cp314-cp314t-win_arm64.whl", hash = "sha256:32001d6a8fc98c8cb5c947787c5d08b0a50663d139f1305bac5885d98d9b40fa", size = 14146, upload-time = "2025-09-27T18:37:28.327Z" }, +sdist = { url = "https://files.pythonhosted.org/packages/7e/99/7690b6d4034fffd95959cbe0c02de8deb3098cc577c67bb6a24fe5d7caa7/markupsafe-3.0.3.tar.gz", hash = "sha256:722695808f4b6457b320fdc131280796bdceb04ab50fe1795cd540799ebe1698", size = 80313 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/38/2f/907b9c7bbba283e68f20259574b13d005c121a0fa4c175f9bed27c4597ff/markupsafe-3.0.3-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:e1cf1972137e83c5d4c136c43ced9ac51d0e124706ee1c8aa8532c1287fa8795", size = 11622 }, + { url = "https://files.pythonhosted.org/packages/9c/d9/5f7756922cdd676869eca1c4e3c0cd0df60ed30199ffd775e319089cb3ed/markupsafe-3.0.3-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:116bb52f642a37c115f517494ea5feb03889e04df47eeff5b130b1808ce7c219", size = 12029 }, + { url = "https://files.pythonhosted.org/packages/00/07/575a68c754943058c78f30db02ee03a64b3c638586fba6a6dd56830b30a3/markupsafe-3.0.3-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:133a43e73a802c5562be9bbcd03d090aa5a1fe899db609c29e8c8d815c5f6de6", size = 24374 }, + { url = "https://files.pythonhosted.org/packages/a9/21/9b05698b46f218fc0e118e1f8168395c65c8a2c750ae2bab54fc4bd4e0e8/markupsafe-3.0.3-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:ccfcd093f13f0f0b7fdd0f198b90053bf7b2f02a3927a30e63f3ccc9df56b676", size = 22980 }, + { url = "https://files.pythonhosted.org/packages/7f/71/544260864f893f18b6827315b988c146b559391e6e7e8f7252839b1b846a/markupsafe-3.0.3-cp313-cp313-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:509fa21c6deb7a7a273d629cf5ec029bc209d1a51178615ddf718f5918992ab9", size = 21990 }, + { url = "https://files.pythonhosted.org/packages/c2/28/b50fc2f74d1ad761af2f5dcce7492648b983d00a65b8c0e0cb457c82ebbe/markupsafe-3.0.3-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:a4afe79fb3de0b7097d81da19090f4df4f8d3a2b3adaa8764138aac2e44f3af1", size = 23784 }, + { url = "https://files.pythonhosted.org/packages/ed/76/104b2aa106a208da8b17a2fb72e033a5a9d7073c68f7e508b94916ed47a9/markupsafe-3.0.3-cp313-cp313-musllinux_1_2_riscv64.whl", hash = "sha256:795e7751525cae078558e679d646ae45574b47ed6e7771863fcc079a6171a0fc", size = 21588 }, + { url = "https://files.pythonhosted.org/packages/b5/99/16a5eb2d140087ebd97180d95249b00a03aa87e29cc224056274f2e45fd6/markupsafe-3.0.3-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:8485f406a96febb5140bfeca44a73e3ce5116b2501ac54fe953e488fb1d03b12", size = 23041 }, + { url = "https://files.pythonhosted.org/packages/19/bc/e7140ed90c5d61d77cea142eed9f9c303f4c4806f60a1044c13e3f1471d0/markupsafe-3.0.3-cp313-cp313-win32.whl", hash = "sha256:bdd37121970bfd8be76c5fb069c7751683bdf373db1ed6c010162b2a130248ed", size = 14543 }, + { url = "https://files.pythonhosted.org/packages/05/73/c4abe620b841b6b791f2edc248f556900667a5a1cf023a6646967ae98335/markupsafe-3.0.3-cp313-cp313-win_amd64.whl", hash = "sha256:9a1abfdc021a164803f4d485104931fb8f8c1efd55bc6b748d2f5774e78b62c5", size = 15113 }, + { url = "https://files.pythonhosted.org/packages/f0/3a/fa34a0f7cfef23cf9500d68cb7c32dd64ffd58a12b09225fb03dd37d5b80/markupsafe-3.0.3-cp313-cp313-win_arm64.whl", hash = "sha256:7e68f88e5b8799aa49c85cd116c932a1ac15caaa3f5db09087854d218359e485", size = 13911 }, + { url = "https://files.pythonhosted.org/packages/e4/d7/e05cd7efe43a88a17a37b3ae96e79a19e846f3f456fe79c57ca61356ef01/markupsafe-3.0.3-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:218551f6df4868a8d527e3062d0fb968682fe92054e89978594c28e642c43a73", size = 11658 }, + { url = "https://files.pythonhosted.org/packages/99/9e/e412117548182ce2148bdeacdda3bb494260c0b0184360fe0d56389b523b/markupsafe-3.0.3-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:3524b778fe5cfb3452a09d31e7b5adefeea8c5be1d43c4f810ba09f2ceb29d37", size = 12066 }, + { url = "https://files.pythonhosted.org/packages/bc/e6/fa0ffcda717ef64a5108eaa7b4f5ed28d56122c9a6d70ab8b72f9f715c80/markupsafe-3.0.3-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:4e885a3d1efa2eadc93c894a21770e4bc67899e3543680313b09f139e149ab19", size = 25639 }, + { url = "https://files.pythonhosted.org/packages/96/ec/2102e881fe9d25fc16cb4b25d5f5cde50970967ffa5dddafdb771237062d/markupsafe-3.0.3-cp313-cp313t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:8709b08f4a89aa7586de0aadc8da56180242ee0ada3999749b183aa23df95025", size = 23569 }, + { url = "https://files.pythonhosted.org/packages/4b/30/6f2fce1f1f205fc9323255b216ca8a235b15860c34b6798f810f05828e32/markupsafe-3.0.3-cp313-cp313t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:b8512a91625c9b3da6f127803b166b629725e68af71f8184ae7e7d54686a56d6", size = 23284 }, + { url = "https://files.pythonhosted.org/packages/58/47/4a0ccea4ab9f5dcb6f79c0236d954acb382202721e704223a8aafa38b5c8/markupsafe-3.0.3-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:9b79b7a16f7fedff2495d684f2b59b0457c3b493778c9eed31111be64d58279f", size = 24801 }, + { url = "https://files.pythonhosted.org/packages/6a/70/3780e9b72180b6fecb83a4814d84c3bf4b4ae4bf0b19c27196104149734c/markupsafe-3.0.3-cp313-cp313t-musllinux_1_2_riscv64.whl", hash = "sha256:12c63dfb4a98206f045aa9563db46507995f7ef6d83b2f68eda65c307c6829eb", size = 22769 }, + { url = "https://files.pythonhosted.org/packages/98/c5/c03c7f4125180fc215220c035beac6b9cb684bc7a067c84fc69414d315f5/markupsafe-3.0.3-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:8f71bc33915be5186016f675cd83a1e08523649b0e33efdb898db577ef5bb009", size = 23642 }, + { url = "https://files.pythonhosted.org/packages/80/d6/2d1b89f6ca4bff1036499b1e29a1d02d282259f3681540e16563f27ebc23/markupsafe-3.0.3-cp313-cp313t-win32.whl", hash = "sha256:69c0b73548bc525c8cb9a251cddf1931d1db4d2258e9599c28c07ef3580ef354", size = 14612 }, + { url = "https://files.pythonhosted.org/packages/2b/98/e48a4bfba0a0ffcf9925fe2d69240bfaa19c6f7507b8cd09c70684a53c1e/markupsafe-3.0.3-cp313-cp313t-win_amd64.whl", hash = "sha256:1b4b79e8ebf6b55351f0d91fe80f893b4743f104bff22e90697db1590e47a218", size = 15200 }, + { url = "https://files.pythonhosted.org/packages/0e/72/e3cc540f351f316e9ed0f092757459afbc595824ca724cbc5a5d4263713f/markupsafe-3.0.3-cp313-cp313t-win_arm64.whl", hash = "sha256:ad2cf8aa28b8c020ab2fc8287b0f823d0a7d8630784c31e9ee5edea20f406287", size = 13973 }, + { url = "https://files.pythonhosted.org/packages/33/8a/8e42d4838cd89b7dde187011e97fe6c3af66d8c044997d2183fbd6d31352/markupsafe-3.0.3-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:eaa9599de571d72e2daf60164784109f19978b327a3910d3e9de8c97b5b70cfe", size = 11619 }, + { url = "https://files.pythonhosted.org/packages/b5/64/7660f8a4a8e53c924d0fa05dc3a55c9cee10bbd82b11c5afb27d44b096ce/markupsafe-3.0.3-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:c47a551199eb8eb2121d4f0f15ae0f923d31350ab9280078d1e5f12b249e0026", size = 12029 }, + { url = "https://files.pythonhosted.org/packages/da/ef/e648bfd021127bef5fa12e1720ffed0c6cbb8310c8d9bea7266337ff06de/markupsafe-3.0.3-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:f34c41761022dd093b4b6896d4810782ffbabe30f2d443ff5f083e0cbbb8c737", size = 24408 }, + { url = "https://files.pythonhosted.org/packages/41/3c/a36c2450754618e62008bf7435ccb0f88053e07592e6028a34776213d877/markupsafe-3.0.3-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:457a69a9577064c05a97c41f4e65148652db078a3a509039e64d3467b9e7ef97", size = 23005 }, + { url = "https://files.pythonhosted.org/packages/bc/20/b7fdf89a8456b099837cd1dc21974632a02a999ec9bf7ca3e490aacd98e7/markupsafe-3.0.3-cp314-cp314-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:e8afc3f2ccfa24215f8cb28dcf43f0113ac3c37c2f0f0806d8c70e4228c5cf4d", size = 22048 }, + { url = "https://files.pythonhosted.org/packages/9a/a7/591f592afdc734f47db08a75793a55d7fbcc6902a723ae4cfbab61010cc5/markupsafe-3.0.3-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:ec15a59cf5af7be74194f7ab02d0f59a62bdcf1a537677ce67a2537c9b87fcda", size = 23821 }, + { url = "https://files.pythonhosted.org/packages/7d/33/45b24e4f44195b26521bc6f1a82197118f74df348556594bd2262bda1038/markupsafe-3.0.3-cp314-cp314-musllinux_1_2_riscv64.whl", hash = "sha256:0eb9ff8191e8498cca014656ae6b8d61f39da5f95b488805da4bb029cccbfbaf", size = 21606 }, + { url = "https://files.pythonhosted.org/packages/ff/0e/53dfaca23a69fbfbbf17a4b64072090e70717344c52eaaaa9c5ddff1e5f0/markupsafe-3.0.3-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:2713baf880df847f2bece4230d4d094280f4e67b1e813eec43b4c0e144a34ffe", size = 23043 }, + { url = "https://files.pythonhosted.org/packages/46/11/f333a06fc16236d5238bfe74daccbca41459dcd8d1fa952e8fbd5dccfb70/markupsafe-3.0.3-cp314-cp314-win32.whl", hash = "sha256:729586769a26dbceff69f7a7dbbf59ab6572b99d94576a5592625d5b411576b9", size = 14747 }, + { url = "https://files.pythonhosted.org/packages/28/52/182836104b33b444e400b14f797212f720cbc9ed6ba34c800639d154e821/markupsafe-3.0.3-cp314-cp314-win_amd64.whl", hash = "sha256:bdc919ead48f234740ad807933cdf545180bfbe9342c2bb451556db2ed958581", size = 15341 }, + { url = "https://files.pythonhosted.org/packages/6f/18/acf23e91bd94fd7b3031558b1f013adfa21a8e407a3fdb32745538730382/markupsafe-3.0.3-cp314-cp314-win_arm64.whl", hash = "sha256:5a7d5dc5140555cf21a6fefbdbf8723f06fcd2f63ef108f2854de715e4422cb4", size = 14073 }, + { url = "https://files.pythonhosted.org/packages/3c/f0/57689aa4076e1b43b15fdfa646b04653969d50cf30c32a102762be2485da/markupsafe-3.0.3-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:1353ef0c1b138e1907ae78e2f6c63ff67501122006b0f9abad68fda5f4ffc6ab", size = 11661 }, + { url = "https://files.pythonhosted.org/packages/89/c3/2e67a7ca217c6912985ec766c6393b636fb0c2344443ff9d91404dc4c79f/markupsafe-3.0.3-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:1085e7fbddd3be5f89cc898938f42c0b3c711fdcb37d75221de2666af647c175", size = 12069 }, + { url = "https://files.pythonhosted.org/packages/f0/00/be561dce4e6ca66b15276e184ce4b8aec61fe83662cce2f7d72bd3249d28/markupsafe-3.0.3-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:1b52b4fb9df4eb9ae465f8d0c228a00624de2334f216f178a995ccdcf82c4634", size = 25670 }, + { url = "https://files.pythonhosted.org/packages/50/09/c419f6f5a92e5fadde27efd190eca90f05e1261b10dbd8cbcb39cd8ea1dc/markupsafe-3.0.3-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:fed51ac40f757d41b7c48425901843666a6677e3e8eb0abcff09e4ba6e664f50", size = 23598 }, + { url = "https://files.pythonhosted.org/packages/22/44/a0681611106e0b2921b3033fc19bc53323e0b50bc70cffdd19f7d679bb66/markupsafe-3.0.3-cp314-cp314t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:f190daf01f13c72eac4efd5c430a8de82489d9cff23c364c3ea822545032993e", size = 23261 }, + { url = "https://files.pythonhosted.org/packages/5f/57/1b0b3f100259dc9fffe780cfb60d4be71375510e435efec3d116b6436d43/markupsafe-3.0.3-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:e56b7d45a839a697b5eb268c82a71bd8c7f6c94d6fd50c3d577fa39a9f1409f5", size = 24835 }, + { url = "https://files.pythonhosted.org/packages/26/6a/4bf6d0c97c4920f1597cc14dd720705eca0bf7c787aebc6bb4d1bead5388/markupsafe-3.0.3-cp314-cp314t-musllinux_1_2_riscv64.whl", hash = "sha256:f3e98bb3798ead92273dc0e5fd0f31ade220f59a266ffd8a4f6065e0a3ce0523", size = 22733 }, + { url = "https://files.pythonhosted.org/packages/14/c7/ca723101509b518797fedc2fdf79ba57f886b4aca8a7d31857ba3ee8281f/markupsafe-3.0.3-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:5678211cb9333a6468fb8d8be0305520aa073f50d17f089b5b4b477ea6e67fdc", size = 23672 }, + { url = "https://files.pythonhosted.org/packages/fb/df/5bd7a48c256faecd1d36edc13133e51397e41b73bb77e1a69deab746ebac/markupsafe-3.0.3-cp314-cp314t-win32.whl", hash = "sha256:915c04ba3851909ce68ccc2b8e2cd691618c4dc4c4232fb7982bca3f41fd8c3d", size = 14819 }, + { url = "https://files.pythonhosted.org/packages/1a/8a/0402ba61a2f16038b48b39bccca271134be00c5c9f0f623208399333c448/markupsafe-3.0.3-cp314-cp314t-win_amd64.whl", hash = "sha256:4faffd047e07c38848ce017e8725090413cd80cbc23d86e55c587bf979e579c9", size = 15426 }, + { url = "https://files.pythonhosted.org/packages/70/bc/6f1c2f612465f5fa89b95bead1f44dcb607670fd42891d8fdcd5d039f4f4/markupsafe-3.0.3-cp314-cp314t-win_arm64.whl", hash = "sha256:32001d6a8fc98c8cb5c947787c5d08b0a50663d139f1305bac5885d98d9b40fa", size = 14146 }, ] [[package]] name = "mdurl" version = "0.1.2" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/d6/54/cfe61301667036ec958cb99bd3efefba235e65cdeb9c84d24a8293ba1d90/mdurl-0.1.2.tar.gz", hash = "sha256:bb413d29f5eea38f31dd4754dd7377d4465116fb207585f97bf925588687c1ba", size = 8729, upload-time = "2022-08-14T12:40:10.846Z" } +sdist = { url = "https://files.pythonhosted.org/packages/d6/54/cfe61301667036ec958cb99bd3efefba235e65cdeb9c84d24a8293ba1d90/mdurl-0.1.2.tar.gz", hash = "sha256:bb413d29f5eea38f31dd4754dd7377d4465116fb207585f97bf925588687c1ba", size = 8729 } wheels = [ - { url = "https://files.pythonhosted.org/packages/b3/38/89ba8ad64ae25be8de66a6d463314cf1eb366222074cfda9ee839c56a4b4/mdurl-0.1.2-py3-none-any.whl", hash = "sha256:84008a41e51615a49fc9966191ff91509e3c40b939176e643fd50a5c2196b8f8", size = 9979, upload-time = "2022-08-14T12:40:09.779Z" }, + { url = "https://files.pythonhosted.org/packages/b3/38/89ba8ad64ae25be8de66a6d463314cf1eb366222074cfda9ee839c56a4b4/mdurl-0.1.2-py3-none-any.whl", hash = "sha256:84008a41e51615a49fc9966191ff91509e3c40b939176e643fd50a5c2196b8f8", size = 9979 }, ] [[package]] @@ -1103,70 +1112,70 @@ dependencies = [ { name = "dotmap" }, { name = "jinja2" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/2a/68/4e0e1b0bc64f0d3afac2fb8a4fb35f2a4e9a0521ae1c777c0e29e21b27fa/mjml-0.11.1.tar.gz", hash = "sha256:f703c8b3458ca0100df6cf56a3633f193b352a80b1a1836a452b92361e74ca73", size = 66589, upload-time = "2025-05-13T10:24:05.693Z" } +sdist = { url = "https://files.pythonhosted.org/packages/2a/68/4e0e1b0bc64f0d3afac2fb8a4fb35f2a4e9a0521ae1c777c0e29e21b27fa/mjml-0.11.1.tar.gz", hash = "sha256:f703c8b3458ca0100df6cf56a3633f193b352a80b1a1836a452b92361e74ca73", size = 66589 } wheels = [ - { url = "https://files.pythonhosted.org/packages/85/a6/7ed27888adbf8cbdd734e298691004918ec0ef5f40e6bc1329ed97da2273/mjml-0.11.1-py3-none-any.whl", hash = "sha256:fef9f7a95929cbe5ddce9351ee8702e05153d68abc77dcf8e84da2c22a330b2a", size = 63191, upload-time = "2025-05-13T10:24:03.953Z" }, + { url = "https://files.pythonhosted.org/packages/85/a6/7ed27888adbf8cbdd734e298691004918ec0ef5f40e6bc1329ed97da2273/mjml-0.11.1-py3-none-any.whl", hash = "sha256:fef9f7a95929cbe5ddce9351ee8702e05153d68abc77dcf8e84da2c22a330b2a", size = 63191 }, ] [[package]] name = "nodeenv" version = "1.9.1" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/43/16/fc88b08840de0e0a72a2f9d8c6bae36be573e475a6326ae854bcc549fc45/nodeenv-1.9.1.tar.gz", hash = "sha256:6ec12890a2dab7946721edbfbcd91f3319c6ccc9aec47be7c7e6b7011ee6645f", size = 47437, upload-time = "2024-06-04T18:44:11.171Z" } +sdist = { url = "https://files.pythonhosted.org/packages/43/16/fc88b08840de0e0a72a2f9d8c6bae36be573e475a6326ae854bcc549fc45/nodeenv-1.9.1.tar.gz", hash = "sha256:6ec12890a2dab7946721edbfbcd91f3319c6ccc9aec47be7c7e6b7011ee6645f", size = 47437 } wheels = [ - { url = "https://files.pythonhosted.org/packages/d2/1d/1b658dbd2b9fa9c4c9f32accbfc0205d532c8c6194dc0f2a4c0428e7128a/nodeenv-1.9.1-py2.py3-none-any.whl", hash = "sha256:ba11c9782d29c27c70ffbdda2d7415098754709be8a7056d79a737cd901155c9", size = 22314, upload-time = "2024-06-04T18:44:08.352Z" }, + { url = "https://files.pythonhosted.org/packages/d2/1d/1b658dbd2b9fa9c4c9f32accbfc0205d532c8c6194dc0f2a4c0428e7128a/nodeenv-1.9.1-py2.py3-none-any.whl", hash = "sha256:ba11c9782d29c27c70ffbdda2d7415098754709be8a7056d79a737cd901155c9", size = 22314 }, ] [[package]] name = "numpy" version = "2.3.4" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/b5/f4/098d2270d52b41f1bd7db9fc288aaa0400cb48c2a3e2af6fa365d9720947/numpy-2.3.4.tar.gz", hash = "sha256:a7d018bfedb375a8d979ac758b120ba846a7fe764911a64465fd87b8729f4a6a", size = 20582187, upload-time = "2025-10-15T16:18:11.77Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/57/7e/b72610cc91edf138bc588df5150957a4937221ca6058b825b4725c27be62/numpy-2.3.4-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:c090d4860032b857d94144d1a9976b8e36709e40386db289aaf6672de2a81966", size = 20950335, upload-time = "2025-10-15T16:16:10.304Z" }, - { url = "https://files.pythonhosted.org/packages/3e/46/bdd3370dcea2f95ef14af79dbf81e6927102ddf1cc54adc0024d61252fd9/numpy-2.3.4-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:a13fc473b6db0be619e45f11f9e81260f7302f8d180c49a22b6e6120022596b3", size = 14179878, upload-time = "2025-10-15T16:16:12.595Z" }, - { url = "https://files.pythonhosted.org/packages/ac/01/5a67cb785bda60f45415d09c2bc245433f1c68dd82eef9c9002c508b5a65/numpy-2.3.4-cp313-cp313-macosx_14_0_arm64.whl", hash = "sha256:3634093d0b428e6c32c3a69b78e554f0cd20ee420dcad5a9f3b2a63762ce4197", size = 5108673, upload-time = "2025-10-15T16:16:14.877Z" }, - { url = "https://files.pythonhosted.org/packages/c2/cd/8428e23a9fcebd33988f4cb61208fda832800ca03781f471f3727a820704/numpy-2.3.4-cp313-cp313-macosx_14_0_x86_64.whl", hash = "sha256:043885b4f7e6e232d7df4f51ffdef8c36320ee9d5f227b380ea636722c7ed12e", size = 6641438, upload-time = "2025-10-15T16:16:16.805Z" }, - { url = "https://files.pythonhosted.org/packages/3e/d1/913fe563820f3c6b079f992458f7331278dcd7ba8427e8e745af37ddb44f/numpy-2.3.4-cp313-cp313-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:4ee6a571d1e4f0ea6d5f22d6e5fbd6ed1dc2b18542848e1e7301bd190500c9d7", size = 14281290, upload-time = "2025-10-15T16:16:18.764Z" }, - { url = "https://files.pythonhosted.org/packages/9e/7e/7d306ff7cb143e6d975cfa7eb98a93e73495c4deabb7d1b5ecf09ea0fd69/numpy-2.3.4-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:fc8a63918b04b8571789688b2780ab2b4a33ab44bfe8ccea36d3eba51228c953", size = 16636543, upload-time = "2025-10-15T16:16:21.072Z" }, - { url = "https://files.pythonhosted.org/packages/47/6a/8cfc486237e56ccfb0db234945552a557ca266f022d281a2f577b98e955c/numpy-2.3.4-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:40cc556d5abbc54aabe2b1ae287042d7bdb80c08edede19f0c0afb36ae586f37", size = 16056117, upload-time = "2025-10-15T16:16:23.369Z" }, - { url = "https://files.pythonhosted.org/packages/b1/0e/42cb5e69ea901e06ce24bfcc4b5664a56f950a70efdcf221f30d9615f3f3/numpy-2.3.4-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:ecb63014bb7f4ce653f8be7f1df8cbc6093a5a2811211770f6606cc92b5a78fd", size = 18577788, upload-time = "2025-10-15T16:16:27.496Z" }, - { url = "https://files.pythonhosted.org/packages/86/92/41c3d5157d3177559ef0a35da50f0cda7fa071f4ba2306dd36818591a5bc/numpy-2.3.4-cp313-cp313-win32.whl", hash = "sha256:e8370eb6925bb8c1c4264fec52b0384b44f675f191df91cbe0140ec9f0955646", size = 6282620, upload-time = "2025-10-15T16:16:29.811Z" }, - { url = "https://files.pythonhosted.org/packages/09/97/fd421e8bc50766665ad35536c2bb4ef916533ba1fdd053a62d96cc7c8b95/numpy-2.3.4-cp313-cp313-win_amd64.whl", hash = "sha256:56209416e81a7893036eea03abcb91c130643eb14233b2515c90dcac963fe99d", size = 12784672, upload-time = "2025-10-15T16:16:31.589Z" }, - { url = "https://files.pythonhosted.org/packages/ad/df/5474fb2f74970ca8eb978093969b125a84cc3d30e47f82191f981f13a8a0/numpy-2.3.4-cp313-cp313-win_arm64.whl", hash = "sha256:a700a4031bc0fd6936e78a752eefb79092cecad2599ea9c8039c548bc097f9bc", size = 10196702, upload-time = "2025-10-15T16:16:33.902Z" }, - { url = "https://files.pythonhosted.org/packages/11/83/66ac031464ec1767ea3ed48ce40f615eb441072945e98693bec0bcd056cc/numpy-2.3.4-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:86966db35c4040fdca64f0816a1c1dd8dbd027d90fca5a57e00e1ca4cd41b879", size = 21049003, upload-time = "2025-10-15T16:16:36.101Z" }, - { url = "https://files.pythonhosted.org/packages/5f/99/5b14e0e686e61371659a1d5bebd04596b1d72227ce36eed121bb0aeab798/numpy-2.3.4-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:838f045478638b26c375ee96ea89464d38428c69170360b23a1a50fa4baa3562", size = 14302980, upload-time = "2025-10-15T16:16:39.124Z" }, - { url = "https://files.pythonhosted.org/packages/2c/44/e9486649cd087d9fc6920e3fc3ac2aba10838d10804b1e179fb7cbc4e634/numpy-2.3.4-cp313-cp313t-macosx_14_0_arm64.whl", hash = "sha256:d7315ed1dab0286adca467377c8381cd748f3dc92235f22a7dfc42745644a96a", size = 5231472, upload-time = "2025-10-15T16:16:41.168Z" }, - { url = "https://files.pythonhosted.org/packages/3e/51/902b24fa8887e5fe2063fd61b1895a476d0bbf46811ab0c7fdf4bd127345/numpy-2.3.4-cp313-cp313t-macosx_14_0_x86_64.whl", hash = "sha256:84f01a4d18b2cc4ade1814a08e5f3c907b079c847051d720fad15ce37aa930b6", size = 6739342, upload-time = "2025-10-15T16:16:43.777Z" }, - { url = "https://files.pythonhosted.org/packages/34/f1/4de9586d05b1962acdcdb1dc4af6646361a643f8c864cef7c852bf509740/numpy-2.3.4-cp313-cp313t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:817e719a868f0dacde4abdfc5c1910b301877970195db9ab6a5e2c4bd5b121f7", size = 14354338, upload-time = "2025-10-15T16:16:46.081Z" }, - { url = "https://files.pythonhosted.org/packages/1f/06/1c16103b425de7969d5a76bdf5ada0804b476fed05d5f9e17b777f1cbefd/numpy-2.3.4-cp313-cp313t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:85e071da78d92a214212cacea81c6da557cab307f2c34b5f85b628e94803f9c0", size = 16702392, upload-time = "2025-10-15T16:16:48.455Z" }, - { url = "https://files.pythonhosted.org/packages/34/b2/65f4dc1b89b5322093572b6e55161bb42e3e0487067af73627f795cc9d47/numpy-2.3.4-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:2ec646892819370cf3558f518797f16597b4e4669894a2ba712caccc9da53f1f", size = 16134998, upload-time = "2025-10-15T16:16:51.114Z" }, - { url = "https://files.pythonhosted.org/packages/d4/11/94ec578896cdb973aaf56425d6c7f2aff4186a5c00fac15ff2ec46998b46/numpy-2.3.4-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:035796aaaddfe2f9664b9a9372f089cfc88bd795a67bd1bfe15e6e770934cf64", size = 18651574, upload-time = "2025-10-15T16:16:53.429Z" }, - { url = "https://files.pythonhosted.org/packages/62/b7/7efa763ab33dbccf56dade36938a77345ce8e8192d6b39e470ca25ff3cd0/numpy-2.3.4-cp313-cp313t-win32.whl", hash = "sha256:fea80f4f4cf83b54c3a051f2f727870ee51e22f0248d3114b8e755d160b38cfb", size = 6413135, upload-time = "2025-10-15T16:16:55.992Z" }, - { url = "https://files.pythonhosted.org/packages/43/70/aba4c38e8400abcc2f345e13d972fb36c26409b3e644366db7649015f291/numpy-2.3.4-cp313-cp313t-win_amd64.whl", hash = "sha256:15eea9f306b98e0be91eb344a94c0e630689ef302e10c2ce5f7e11905c704f9c", size = 12928582, upload-time = "2025-10-15T16:16:57.943Z" }, - { url = "https://files.pythonhosted.org/packages/67/63/871fad5f0073fc00fbbdd7232962ea1ac40eeaae2bba66c76214f7954236/numpy-2.3.4-cp313-cp313t-win_arm64.whl", hash = "sha256:b6c231c9c2fadbae4011ca5e7e83e12dc4a5072f1a1d85a0a7b3ed754d145a40", size = 10266691, upload-time = "2025-10-15T16:17:00.048Z" }, - { url = "https://files.pythonhosted.org/packages/72/71/ae6170143c115732470ae3a2d01512870dd16e0953f8a6dc89525696069b/numpy-2.3.4-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:81c3e6d8c97295a7360d367f9f8553973651b76907988bb6066376bc2252f24e", size = 20955580, upload-time = "2025-10-15T16:17:02.509Z" }, - { url = "https://files.pythonhosted.org/packages/af/39/4be9222ffd6ca8a30eda033d5f753276a9c3426c397bb137d8e19dedd200/numpy-2.3.4-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:7c26b0b2bf58009ed1f38a641f3db4be8d960a417ca96d14e5b06df1506d41ff", size = 14188056, upload-time = "2025-10-15T16:17:04.873Z" }, - { url = "https://files.pythonhosted.org/packages/6c/3d/d85f6700d0a4aa4f9491030e1021c2b2b7421b2b38d01acd16734a2bfdc7/numpy-2.3.4-cp314-cp314-macosx_14_0_arm64.whl", hash = "sha256:62b2198c438058a20b6704351b35a1d7db881812d8512d67a69c9de1f18ca05f", size = 5116555, upload-time = "2025-10-15T16:17:07.499Z" }, - { url = "https://files.pythonhosted.org/packages/bf/04/82c1467d86f47eee8a19a464c92f90a9bb68ccf14a54c5224d7031241ffb/numpy-2.3.4-cp314-cp314-macosx_14_0_x86_64.whl", hash = "sha256:9d729d60f8d53a7361707f4b68a9663c968882dd4f09e0d58c044c8bf5faee7b", size = 6643581, upload-time = "2025-10-15T16:17:09.774Z" }, - { url = "https://files.pythonhosted.org/packages/0c/d3/c79841741b837e293f48bd7db89d0ac7a4f2503b382b78a790ef1dc778a5/numpy-2.3.4-cp314-cp314-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:bd0c630cf256b0a7fd9d0a11c9413b42fef5101219ce6ed5a09624f5a65392c7", size = 14299186, upload-time = "2025-10-15T16:17:11.937Z" }, - { url = "https://files.pythonhosted.org/packages/e8/7e/4a14a769741fbf237eec5a12a2cbc7a4c4e061852b6533bcb9e9a796c908/numpy-2.3.4-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:d5e081bc082825f8b139f9e9fe42942cb4054524598aaeb177ff476cc76d09d2", size = 16638601, upload-time = "2025-10-15T16:17:14.391Z" }, - { url = "https://files.pythonhosted.org/packages/93/87/1c1de269f002ff0a41173fe01dcc925f4ecff59264cd8f96cf3b60d12c9b/numpy-2.3.4-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:15fb27364ed84114438fff8aaf998c9e19adbeba08c0b75409f8c452a8692c52", size = 16074219, upload-time = "2025-10-15T16:17:17.058Z" }, - { url = "https://files.pythonhosted.org/packages/cd/28/18f72ee77408e40a76d691001ae599e712ca2a47ddd2c4f695b16c65f077/numpy-2.3.4-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:85d9fb2d8cd998c84d13a79a09cc0c1091648e848e4e6249b0ccd7f6b487fa26", size = 18576702, upload-time = "2025-10-15T16:17:19.379Z" }, - { url = "https://files.pythonhosted.org/packages/c3/76/95650169b465ececa8cf4b2e8f6df255d4bf662775e797ade2025cc51ae6/numpy-2.3.4-cp314-cp314-win32.whl", hash = "sha256:e73d63fd04e3a9d6bc187f5455d81abfad05660b212c8804bf3b407e984cd2bc", size = 6337136, upload-time = "2025-10-15T16:17:22.886Z" }, - { url = "https://files.pythonhosted.org/packages/dc/89/a231a5c43ede5d6f77ba4a91e915a87dea4aeea76560ba4d2bf185c683f0/numpy-2.3.4-cp314-cp314-win_amd64.whl", hash = "sha256:3da3491cee49cf16157e70f607c03a217ea6647b1cea4819c4f48e53d49139b9", size = 12920542, upload-time = "2025-10-15T16:17:24.783Z" }, - { url = "https://files.pythonhosted.org/packages/0d/0c/ae9434a888f717c5ed2ff2393b3f344f0ff6f1c793519fa0c540461dc530/numpy-2.3.4-cp314-cp314-win_arm64.whl", hash = "sha256:6d9cd732068e8288dbe2717177320723ccec4fb064123f0caf9bbd90ab5be868", size = 10480213, upload-time = "2025-10-15T16:17:26.935Z" }, - { url = "https://files.pythonhosted.org/packages/83/4b/c4a5f0841f92536f6b9592694a5b5f68c9ab37b775ff342649eadf9055d3/numpy-2.3.4-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:22758999b256b595cf0b1d102b133bb61866ba5ceecf15f759623b64c020c9ec", size = 21052280, upload-time = "2025-10-15T16:17:29.638Z" }, - { url = "https://files.pythonhosted.org/packages/3e/80/90308845fc93b984d2cc96d83e2324ce8ad1fd6efea81b324cba4b673854/numpy-2.3.4-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:9cb177bc55b010b19798dc5497d540dea67fd13a8d9e882b2dae71de0cf09eb3", size = 14302930, upload-time = "2025-10-15T16:17:32.384Z" }, - { url = "https://files.pythonhosted.org/packages/3d/4e/07439f22f2a3b247cec4d63a713faae55e1141a36e77fb212881f7cda3fb/numpy-2.3.4-cp314-cp314t-macosx_14_0_arm64.whl", hash = "sha256:0f2bcc76f1e05e5ab58893407c63d90b2029908fa41f9f1cc51eecce936c3365", size = 5231504, upload-time = "2025-10-15T16:17:34.515Z" }, - { url = "https://files.pythonhosted.org/packages/ab/de/1e11f2547e2fe3d00482b19721855348b94ada8359aef5d40dd57bfae9df/numpy-2.3.4-cp314-cp314t-macosx_14_0_x86_64.whl", hash = "sha256:8dc20bde86802df2ed8397a08d793da0ad7a5fd4ea3ac85d757bf5dd4ad7c252", size = 6739405, upload-time = "2025-10-15T16:17:36.128Z" }, - { url = "https://files.pythonhosted.org/packages/3b/40/8cd57393a26cebe2e923005db5134a946c62fa56a1087dc7c478f3e30837/numpy-2.3.4-cp314-cp314t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:5e199c087e2aa71c8f9ce1cb7a8e10677dc12457e7cc1be4798632da37c3e86e", size = 14354866, upload-time = "2025-10-15T16:17:38.884Z" }, - { url = "https://files.pythonhosted.org/packages/93/39/5b3510f023f96874ee6fea2e40dfa99313a00bf3ab779f3c92978f34aace/numpy-2.3.4-cp314-cp314t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:85597b2d25ddf655495e2363fe044b0ae999b75bc4d630dc0d886484b03a5eb0", size = 16703296, upload-time = "2025-10-15T16:17:41.564Z" }, - { url = "https://files.pythonhosted.org/packages/41/0d/19bb163617c8045209c1996c4e427bccbc4bbff1e2c711f39203c8ddbb4a/numpy-2.3.4-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:04a69abe45b49c5955923cf2c407843d1c85013b424ae8a560bba16c92fe44a0", size = 16136046, upload-time = "2025-10-15T16:17:43.901Z" }, - { url = "https://files.pythonhosted.org/packages/e2/c1/6dba12fdf68b02a21ac411c9df19afa66bed2540f467150ca64d246b463d/numpy-2.3.4-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:e1708fac43ef8b419c975926ce1eaf793b0c13b7356cfab6ab0dc34c0a02ac0f", size = 18652691, upload-time = "2025-10-15T16:17:46.247Z" }, - { url = "https://files.pythonhosted.org/packages/f8/73/f85056701dbbbb910c51d846c58d29fd46b30eecd2b6ba760fc8b8a1641b/numpy-2.3.4-cp314-cp314t-win32.whl", hash = "sha256:863e3b5f4d9915aaf1b8ec79ae560ad21f0b8d5e3adc31e73126491bb86dee1d", size = 6485782, upload-time = "2025-10-15T16:17:48.872Z" }, - { url = "https://files.pythonhosted.org/packages/17/90/28fa6f9865181cb817c2471ee65678afa8a7e2a1fb16141473d5fa6bacc3/numpy-2.3.4-cp314-cp314t-win_amd64.whl", hash = "sha256:962064de37b9aef801d33bc579690f8bfe6c5e70e29b61783f60bcba838a14d6", size = 13113301, upload-time = "2025-10-15T16:17:50.938Z" }, - { url = "https://files.pythonhosted.org/packages/54/23/08c002201a8e7e1f9afba93b97deceb813252d9cfd0d3351caed123dcf97/numpy-2.3.4-cp314-cp314t-win_arm64.whl", hash = "sha256:8b5a9a39c45d852b62693d9b3f3e0fe052541f804296ff401a72a1b60edafb29", size = 10547532, upload-time = "2025-10-15T16:17:53.48Z" }, +sdist = { url = "https://files.pythonhosted.org/packages/b5/f4/098d2270d52b41f1bd7db9fc288aaa0400cb48c2a3e2af6fa365d9720947/numpy-2.3.4.tar.gz", hash = "sha256:a7d018bfedb375a8d979ac758b120ba846a7fe764911a64465fd87b8729f4a6a", size = 20582187 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/57/7e/b72610cc91edf138bc588df5150957a4937221ca6058b825b4725c27be62/numpy-2.3.4-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:c090d4860032b857d94144d1a9976b8e36709e40386db289aaf6672de2a81966", size = 20950335 }, + { url = "https://files.pythonhosted.org/packages/3e/46/bdd3370dcea2f95ef14af79dbf81e6927102ddf1cc54adc0024d61252fd9/numpy-2.3.4-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:a13fc473b6db0be619e45f11f9e81260f7302f8d180c49a22b6e6120022596b3", size = 14179878 }, + { url = "https://files.pythonhosted.org/packages/ac/01/5a67cb785bda60f45415d09c2bc245433f1c68dd82eef9c9002c508b5a65/numpy-2.3.4-cp313-cp313-macosx_14_0_arm64.whl", hash = "sha256:3634093d0b428e6c32c3a69b78e554f0cd20ee420dcad5a9f3b2a63762ce4197", size = 5108673 }, + { url = "https://files.pythonhosted.org/packages/c2/cd/8428e23a9fcebd33988f4cb61208fda832800ca03781f471f3727a820704/numpy-2.3.4-cp313-cp313-macosx_14_0_x86_64.whl", hash = "sha256:043885b4f7e6e232d7df4f51ffdef8c36320ee9d5f227b380ea636722c7ed12e", size = 6641438 }, + { url = "https://files.pythonhosted.org/packages/3e/d1/913fe563820f3c6b079f992458f7331278dcd7ba8427e8e745af37ddb44f/numpy-2.3.4-cp313-cp313-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:4ee6a571d1e4f0ea6d5f22d6e5fbd6ed1dc2b18542848e1e7301bd190500c9d7", size = 14281290 }, + { url = "https://files.pythonhosted.org/packages/9e/7e/7d306ff7cb143e6d975cfa7eb98a93e73495c4deabb7d1b5ecf09ea0fd69/numpy-2.3.4-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:fc8a63918b04b8571789688b2780ab2b4a33ab44bfe8ccea36d3eba51228c953", size = 16636543 }, + { url = "https://files.pythonhosted.org/packages/47/6a/8cfc486237e56ccfb0db234945552a557ca266f022d281a2f577b98e955c/numpy-2.3.4-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:40cc556d5abbc54aabe2b1ae287042d7bdb80c08edede19f0c0afb36ae586f37", size = 16056117 }, + { url = "https://files.pythonhosted.org/packages/b1/0e/42cb5e69ea901e06ce24bfcc4b5664a56f950a70efdcf221f30d9615f3f3/numpy-2.3.4-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:ecb63014bb7f4ce653f8be7f1df8cbc6093a5a2811211770f6606cc92b5a78fd", size = 18577788 }, + { url = "https://files.pythonhosted.org/packages/86/92/41c3d5157d3177559ef0a35da50f0cda7fa071f4ba2306dd36818591a5bc/numpy-2.3.4-cp313-cp313-win32.whl", hash = "sha256:e8370eb6925bb8c1c4264fec52b0384b44f675f191df91cbe0140ec9f0955646", size = 6282620 }, + { url = "https://files.pythonhosted.org/packages/09/97/fd421e8bc50766665ad35536c2bb4ef916533ba1fdd053a62d96cc7c8b95/numpy-2.3.4-cp313-cp313-win_amd64.whl", hash = "sha256:56209416e81a7893036eea03abcb91c130643eb14233b2515c90dcac963fe99d", size = 12784672 }, + { url = "https://files.pythonhosted.org/packages/ad/df/5474fb2f74970ca8eb978093969b125a84cc3d30e47f82191f981f13a8a0/numpy-2.3.4-cp313-cp313-win_arm64.whl", hash = "sha256:a700a4031bc0fd6936e78a752eefb79092cecad2599ea9c8039c548bc097f9bc", size = 10196702 }, + { url = "https://files.pythonhosted.org/packages/11/83/66ac031464ec1767ea3ed48ce40f615eb441072945e98693bec0bcd056cc/numpy-2.3.4-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:86966db35c4040fdca64f0816a1c1dd8dbd027d90fca5a57e00e1ca4cd41b879", size = 21049003 }, + { url = "https://files.pythonhosted.org/packages/5f/99/5b14e0e686e61371659a1d5bebd04596b1d72227ce36eed121bb0aeab798/numpy-2.3.4-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:838f045478638b26c375ee96ea89464d38428c69170360b23a1a50fa4baa3562", size = 14302980 }, + { url = "https://files.pythonhosted.org/packages/2c/44/e9486649cd087d9fc6920e3fc3ac2aba10838d10804b1e179fb7cbc4e634/numpy-2.3.4-cp313-cp313t-macosx_14_0_arm64.whl", hash = "sha256:d7315ed1dab0286adca467377c8381cd748f3dc92235f22a7dfc42745644a96a", size = 5231472 }, + { url = "https://files.pythonhosted.org/packages/3e/51/902b24fa8887e5fe2063fd61b1895a476d0bbf46811ab0c7fdf4bd127345/numpy-2.3.4-cp313-cp313t-macosx_14_0_x86_64.whl", hash = "sha256:84f01a4d18b2cc4ade1814a08e5f3c907b079c847051d720fad15ce37aa930b6", size = 6739342 }, + { url = "https://files.pythonhosted.org/packages/34/f1/4de9586d05b1962acdcdb1dc4af6646361a643f8c864cef7c852bf509740/numpy-2.3.4-cp313-cp313t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:817e719a868f0dacde4abdfc5c1910b301877970195db9ab6a5e2c4bd5b121f7", size = 14354338 }, + { url = "https://files.pythonhosted.org/packages/1f/06/1c16103b425de7969d5a76bdf5ada0804b476fed05d5f9e17b777f1cbefd/numpy-2.3.4-cp313-cp313t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:85e071da78d92a214212cacea81c6da557cab307f2c34b5f85b628e94803f9c0", size = 16702392 }, + { url = "https://files.pythonhosted.org/packages/34/b2/65f4dc1b89b5322093572b6e55161bb42e3e0487067af73627f795cc9d47/numpy-2.3.4-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:2ec646892819370cf3558f518797f16597b4e4669894a2ba712caccc9da53f1f", size = 16134998 }, + { url = "https://files.pythonhosted.org/packages/d4/11/94ec578896cdb973aaf56425d6c7f2aff4186a5c00fac15ff2ec46998b46/numpy-2.3.4-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:035796aaaddfe2f9664b9a9372f089cfc88bd795a67bd1bfe15e6e770934cf64", size = 18651574 }, + { url = "https://files.pythonhosted.org/packages/62/b7/7efa763ab33dbccf56dade36938a77345ce8e8192d6b39e470ca25ff3cd0/numpy-2.3.4-cp313-cp313t-win32.whl", hash = "sha256:fea80f4f4cf83b54c3a051f2f727870ee51e22f0248d3114b8e755d160b38cfb", size = 6413135 }, + { url = "https://files.pythonhosted.org/packages/43/70/aba4c38e8400abcc2f345e13d972fb36c26409b3e644366db7649015f291/numpy-2.3.4-cp313-cp313t-win_amd64.whl", hash = "sha256:15eea9f306b98e0be91eb344a94c0e630689ef302e10c2ce5f7e11905c704f9c", size = 12928582 }, + { url = "https://files.pythonhosted.org/packages/67/63/871fad5f0073fc00fbbdd7232962ea1ac40eeaae2bba66c76214f7954236/numpy-2.3.4-cp313-cp313t-win_arm64.whl", hash = "sha256:b6c231c9c2fadbae4011ca5e7e83e12dc4a5072f1a1d85a0a7b3ed754d145a40", size = 10266691 }, + { url = "https://files.pythonhosted.org/packages/72/71/ae6170143c115732470ae3a2d01512870dd16e0953f8a6dc89525696069b/numpy-2.3.4-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:81c3e6d8c97295a7360d367f9f8553973651b76907988bb6066376bc2252f24e", size = 20955580 }, + { url = "https://files.pythonhosted.org/packages/af/39/4be9222ffd6ca8a30eda033d5f753276a9c3426c397bb137d8e19dedd200/numpy-2.3.4-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:7c26b0b2bf58009ed1f38a641f3db4be8d960a417ca96d14e5b06df1506d41ff", size = 14188056 }, + { url = "https://files.pythonhosted.org/packages/6c/3d/d85f6700d0a4aa4f9491030e1021c2b2b7421b2b38d01acd16734a2bfdc7/numpy-2.3.4-cp314-cp314-macosx_14_0_arm64.whl", hash = "sha256:62b2198c438058a20b6704351b35a1d7db881812d8512d67a69c9de1f18ca05f", size = 5116555 }, + { url = "https://files.pythonhosted.org/packages/bf/04/82c1467d86f47eee8a19a464c92f90a9bb68ccf14a54c5224d7031241ffb/numpy-2.3.4-cp314-cp314-macosx_14_0_x86_64.whl", hash = "sha256:9d729d60f8d53a7361707f4b68a9663c968882dd4f09e0d58c044c8bf5faee7b", size = 6643581 }, + { url = "https://files.pythonhosted.org/packages/0c/d3/c79841741b837e293f48bd7db89d0ac7a4f2503b382b78a790ef1dc778a5/numpy-2.3.4-cp314-cp314-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:bd0c630cf256b0a7fd9d0a11c9413b42fef5101219ce6ed5a09624f5a65392c7", size = 14299186 }, + { url = "https://files.pythonhosted.org/packages/e8/7e/4a14a769741fbf237eec5a12a2cbc7a4c4e061852b6533bcb9e9a796c908/numpy-2.3.4-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:d5e081bc082825f8b139f9e9fe42942cb4054524598aaeb177ff476cc76d09d2", size = 16638601 }, + { url = "https://files.pythonhosted.org/packages/93/87/1c1de269f002ff0a41173fe01dcc925f4ecff59264cd8f96cf3b60d12c9b/numpy-2.3.4-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:15fb27364ed84114438fff8aaf998c9e19adbeba08c0b75409f8c452a8692c52", size = 16074219 }, + { url = "https://files.pythonhosted.org/packages/cd/28/18f72ee77408e40a76d691001ae599e712ca2a47ddd2c4f695b16c65f077/numpy-2.3.4-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:85d9fb2d8cd998c84d13a79a09cc0c1091648e848e4e6249b0ccd7f6b487fa26", size = 18576702 }, + { url = "https://files.pythonhosted.org/packages/c3/76/95650169b465ececa8cf4b2e8f6df255d4bf662775e797ade2025cc51ae6/numpy-2.3.4-cp314-cp314-win32.whl", hash = "sha256:e73d63fd04e3a9d6bc187f5455d81abfad05660b212c8804bf3b407e984cd2bc", size = 6337136 }, + { url = "https://files.pythonhosted.org/packages/dc/89/a231a5c43ede5d6f77ba4a91e915a87dea4aeea76560ba4d2bf185c683f0/numpy-2.3.4-cp314-cp314-win_amd64.whl", hash = "sha256:3da3491cee49cf16157e70f607c03a217ea6647b1cea4819c4f48e53d49139b9", size = 12920542 }, + { url = "https://files.pythonhosted.org/packages/0d/0c/ae9434a888f717c5ed2ff2393b3f344f0ff6f1c793519fa0c540461dc530/numpy-2.3.4-cp314-cp314-win_arm64.whl", hash = "sha256:6d9cd732068e8288dbe2717177320723ccec4fb064123f0caf9bbd90ab5be868", size = 10480213 }, + { url = "https://files.pythonhosted.org/packages/83/4b/c4a5f0841f92536f6b9592694a5b5f68c9ab37b775ff342649eadf9055d3/numpy-2.3.4-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:22758999b256b595cf0b1d102b133bb61866ba5ceecf15f759623b64c020c9ec", size = 21052280 }, + { url = "https://files.pythonhosted.org/packages/3e/80/90308845fc93b984d2cc96d83e2324ce8ad1fd6efea81b324cba4b673854/numpy-2.3.4-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:9cb177bc55b010b19798dc5497d540dea67fd13a8d9e882b2dae71de0cf09eb3", size = 14302930 }, + { url = "https://files.pythonhosted.org/packages/3d/4e/07439f22f2a3b247cec4d63a713faae55e1141a36e77fb212881f7cda3fb/numpy-2.3.4-cp314-cp314t-macosx_14_0_arm64.whl", hash = "sha256:0f2bcc76f1e05e5ab58893407c63d90b2029908fa41f9f1cc51eecce936c3365", size = 5231504 }, + { url = "https://files.pythonhosted.org/packages/ab/de/1e11f2547e2fe3d00482b19721855348b94ada8359aef5d40dd57bfae9df/numpy-2.3.4-cp314-cp314t-macosx_14_0_x86_64.whl", hash = "sha256:8dc20bde86802df2ed8397a08d793da0ad7a5fd4ea3ac85d757bf5dd4ad7c252", size = 6739405 }, + { url = "https://files.pythonhosted.org/packages/3b/40/8cd57393a26cebe2e923005db5134a946c62fa56a1087dc7c478f3e30837/numpy-2.3.4-cp314-cp314t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:5e199c087e2aa71c8f9ce1cb7a8e10677dc12457e7cc1be4798632da37c3e86e", size = 14354866 }, + { url = "https://files.pythonhosted.org/packages/93/39/5b3510f023f96874ee6fea2e40dfa99313a00bf3ab779f3c92978f34aace/numpy-2.3.4-cp314-cp314t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:85597b2d25ddf655495e2363fe044b0ae999b75bc4d630dc0d886484b03a5eb0", size = 16703296 }, + { url = "https://files.pythonhosted.org/packages/41/0d/19bb163617c8045209c1996c4e427bccbc4bbff1e2c711f39203c8ddbb4a/numpy-2.3.4-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:04a69abe45b49c5955923cf2c407843d1c85013b424ae8a560bba16c92fe44a0", size = 16136046 }, + { url = "https://files.pythonhosted.org/packages/e2/c1/6dba12fdf68b02a21ac411c9df19afa66bed2540f467150ca64d246b463d/numpy-2.3.4-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:e1708fac43ef8b419c975926ce1eaf793b0c13b7356cfab6ab0dc34c0a02ac0f", size = 18652691 }, + { url = "https://files.pythonhosted.org/packages/f8/73/f85056701dbbbb910c51d846c58d29fd46b30eecd2b6ba760fc8b8a1641b/numpy-2.3.4-cp314-cp314t-win32.whl", hash = "sha256:863e3b5f4d9915aaf1b8ec79ae560ad21f0b8d5e3adc31e73126491bb86dee1d", size = 6485782 }, + { url = "https://files.pythonhosted.org/packages/17/90/28fa6f9865181cb817c2471ee65678afa8a7e2a1fb16141473d5fa6bacc3/numpy-2.3.4-cp314-cp314t-win_amd64.whl", hash = "sha256:962064de37b9aef801d33bc579690f8bfe6c5e70e29b61783f60bcba838a14d6", size = 13113301 }, + { url = "https://files.pythonhosted.org/packages/54/23/08c002201a8e7e1f9afba93b97deceb813252d9cfd0d3351caed123dcf97/numpy-2.3.4-cp314-cp314t-win_arm64.whl", hash = "sha256:8b5a9a39c45d852b62693d9b3f3e0fe052541f804296ff401a72a1b60edafb29", size = 10547532 }, ] [[package]] @@ -1176,18 +1185,18 @@ source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "et-xmlfile" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/3d/f9/88d94a75de065ea32619465d2f77b29a0469500e99012523b91cc4141cd1/openpyxl-3.1.5.tar.gz", hash = "sha256:cf0e3cf56142039133628b5acffe8ef0c12bc902d2aadd3e0fe5878dc08d1050", size = 186464, upload-time = "2024-06-28T14:03:44.161Z" } +sdist = { url = "https://files.pythonhosted.org/packages/3d/f9/88d94a75de065ea32619465d2f77b29a0469500e99012523b91cc4141cd1/openpyxl-3.1.5.tar.gz", hash = "sha256:cf0e3cf56142039133628b5acffe8ef0c12bc902d2aadd3e0fe5878dc08d1050", size = 186464 } wheels = [ - { url = "https://files.pythonhosted.org/packages/c0/da/977ded879c29cbd04de313843e76868e6e13408a94ed6b987245dc7c8506/openpyxl-3.1.5-py2.py3-none-any.whl", hash = "sha256:5282c12b107bffeef825f4617dc029afaf41d0ea60823bbb665ef3079dc79de2", size = 250910, upload-time = "2024-06-28T14:03:41.161Z" }, + { url = "https://files.pythonhosted.org/packages/c0/da/977ded879c29cbd04de313843e76868e6e13408a94ed6b987245dc7c8506/openpyxl-3.1.5-py2.py3-none-any.whl", hash = "sha256:5282c12b107bffeef825f4617dc029afaf41d0ea60823bbb665ef3079dc79de2", size = 250910 }, ] [[package]] name = "packaging" version = "25.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/a1/d4/1fc4078c65507b51b96ca8f8c3ba19e6a61c8253c72794544580a7b6c24d/packaging-25.0.tar.gz", hash = "sha256:d443872c98d677bf60f6a1f2f8c1cb748e8fe762d2bf9d3148b5599295b0fc4f", size = 165727, upload-time = "2025-04-19T11:48:59.673Z" } +sdist = { url = "https://files.pythonhosted.org/packages/a1/d4/1fc4078c65507b51b96ca8f8c3ba19e6a61c8253c72794544580a7b6c24d/packaging-25.0.tar.gz", hash = "sha256:d443872c98d677bf60f6a1f2f8c1cb748e8fe762d2bf9d3148b5599295b0fc4f", size = 165727 } wheels = [ - { url = "https://files.pythonhosted.org/packages/20/12/38679034af332785aac8774540895e234f4d07f7545804097de4b666afd8/packaging-25.0-py3-none-any.whl", hash = "sha256:29572ef2b1f17581046b3a2227d5c611fb25ec70ca1ba8554b24b0e69331a484", size = 66469, upload-time = "2025-04-19T11:48:57.875Z" }, + { url = "https://files.pythonhosted.org/packages/20/12/38679034af332785aac8774540895e234f4d07f7545804097de4b666afd8/packaging-25.0-py3-none-any.whl", hash = "sha256:29572ef2b1f17581046b3a2227d5c611fb25ec70ca1ba8554b24b0e69331a484", size = 66469 }, ] [[package]] @@ -1200,34 +1209,34 @@ dependencies = [ { name = "pytz" }, { name = "tzdata" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/33/01/d40b85317f86cf08d853a4f495195c73815fdf205eef3993821720274518/pandas-2.3.3.tar.gz", hash = "sha256:e05e1af93b977f7eafa636d043f9f94c7ee3ac81af99c13508215942e64c993b", size = 4495223, upload-time = "2025-09-29T23:34:51.853Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/cd/4b/18b035ee18f97c1040d94debd8f2e737000ad70ccc8f5513f4eefad75f4b/pandas-2.3.3-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:56851a737e3470de7fa88e6131f41281ed440d29a9268dcbf0002da5ac366713", size = 11544671, upload-time = "2025-09-29T23:21:05.024Z" }, - { url = "https://files.pythonhosted.org/packages/31/94/72fac03573102779920099bcac1c3b05975c2cb5f01eac609faf34bed1ca/pandas-2.3.3-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:bdcd9d1167f4885211e401b3036c0c8d9e274eee67ea8d0758a256d60704cfe8", size = 10680807, upload-time = "2025-09-29T23:21:15.979Z" }, - { url = "https://files.pythonhosted.org/packages/16/87/9472cf4a487d848476865321de18cc8c920b8cab98453ab79dbbc98db63a/pandas-2.3.3-cp313-cp313-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:e32e7cc9af0f1cc15548288a51a3b681cc2a219faa838e995f7dc53dbab1062d", size = 11709872, upload-time = "2025-09-29T23:21:27.165Z" }, - { url = "https://files.pythonhosted.org/packages/15/07/284f757f63f8a8d69ed4472bfd85122bd086e637bf4ed09de572d575a693/pandas-2.3.3-cp313-cp313-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:318d77e0e42a628c04dc56bcef4b40de67918f7041c2b061af1da41dcff670ac", size = 12306371, upload-time = "2025-09-29T23:21:40.532Z" }, - { url = "https://files.pythonhosted.org/packages/33/81/a3afc88fca4aa925804a27d2676d22dcd2031c2ebe08aabd0ae55b9ff282/pandas-2.3.3-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:4e0a175408804d566144e170d0476b15d78458795bb18f1304fb94160cabf40c", size = 12765333, upload-time = "2025-09-29T23:21:55.77Z" }, - { url = "https://files.pythonhosted.org/packages/8d/0f/b4d4ae743a83742f1153464cf1a8ecfafc3ac59722a0b5c8602310cb7158/pandas-2.3.3-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:93c2d9ab0fc11822b5eece72ec9587e172f63cff87c00b062f6e37448ced4493", size = 13418120, upload-time = "2025-09-29T23:22:10.109Z" }, - { url = "https://files.pythonhosted.org/packages/4f/c7/e54682c96a895d0c808453269e0b5928a07a127a15704fedb643e9b0a4c8/pandas-2.3.3-cp313-cp313-win_amd64.whl", hash = "sha256:f8bfc0e12dc78f777f323f55c58649591b2cd0c43534e8355c51d3fede5f4dee", size = 10993991, upload-time = "2025-09-29T23:25:04.889Z" }, - { url = "https://files.pythonhosted.org/packages/f9/ca/3f8d4f49740799189e1395812f3bf23b5e8fc7c190827d55a610da72ce55/pandas-2.3.3-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:75ea25f9529fdec2d2e93a42c523962261e567d250b0013b16210e1d40d7c2e5", size = 12048227, upload-time = "2025-09-29T23:22:24.343Z" }, - { url = "https://files.pythonhosted.org/packages/0e/5a/f43efec3e8c0cc92c4663ccad372dbdff72b60bdb56b2749f04aa1d07d7e/pandas-2.3.3-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:74ecdf1d301e812db96a465a525952f4dde225fdb6d8e5a521d47e1f42041e21", size = 11411056, upload-time = "2025-09-29T23:22:37.762Z" }, - { url = "https://files.pythonhosted.org/packages/46/b1/85331edfc591208c9d1a63a06baa67b21d332e63b7a591a5ba42a10bb507/pandas-2.3.3-cp313-cp313t-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6435cb949cb34ec11cc9860246ccb2fdc9ecd742c12d3304989017d53f039a78", size = 11645189, upload-time = "2025-09-29T23:22:51.688Z" }, - { url = "https://files.pythonhosted.org/packages/44/23/78d645adc35d94d1ac4f2a3c4112ab6f5b8999f4898b8cdf01252f8df4a9/pandas-2.3.3-cp313-cp313t-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:900f47d8f20860de523a1ac881c4c36d65efcb2eb850e6948140fa781736e110", size = 12121912, upload-time = "2025-09-29T23:23:05.042Z" }, - { url = "https://files.pythonhosted.org/packages/53/da/d10013df5e6aaef6b425aa0c32e1fc1f3e431e4bcabd420517dceadce354/pandas-2.3.3-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:a45c765238e2ed7d7c608fc5bc4a6f88b642f2f01e70c0c23d2224dd21829d86", size = 12712160, upload-time = "2025-09-29T23:23:28.57Z" }, - { url = "https://files.pythonhosted.org/packages/bd/17/e756653095a083d8a37cbd816cb87148debcfcd920129b25f99dd8d04271/pandas-2.3.3-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:c4fc4c21971a1a9f4bdb4c73978c7f7256caa3e62b323f70d6cb80db583350bc", size = 13199233, upload-time = "2025-09-29T23:24:24.876Z" }, - { url = "https://files.pythonhosted.org/packages/04/fd/74903979833db8390b73b3a8a7d30d146d710bd32703724dd9083950386f/pandas-2.3.3-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:ee15f284898e7b246df8087fc82b87b01686f98ee67d85a17b7ab44143a3a9a0", size = 11540635, upload-time = "2025-09-29T23:25:52.486Z" }, - { url = "https://files.pythonhosted.org/packages/21/00/266d6b357ad5e6d3ad55093a7e8efc7dd245f5a842b584db9f30b0f0a287/pandas-2.3.3-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:1611aedd912e1ff81ff41c745822980c49ce4a7907537be8692c8dbc31924593", size = 10759079, upload-time = "2025-09-29T23:26:33.204Z" }, - { url = "https://files.pythonhosted.org/packages/ca/05/d01ef80a7a3a12b2f8bbf16daba1e17c98a2f039cbc8e2f77a2c5a63d382/pandas-2.3.3-cp314-cp314-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6d2cefc361461662ac48810cb14365a365ce864afe85ef1f447ff5a1e99ea81c", size = 11814049, upload-time = "2025-09-29T23:27:15.384Z" }, - { url = "https://files.pythonhosted.org/packages/15/b2/0e62f78c0c5ba7e3d2c5945a82456f4fac76c480940f805e0b97fcbc2f65/pandas-2.3.3-cp314-cp314-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:ee67acbbf05014ea6c763beb097e03cd629961c8a632075eeb34247120abcb4b", size = 12332638, upload-time = "2025-09-29T23:27:51.625Z" }, - { url = "https://files.pythonhosted.org/packages/c5/33/dd70400631b62b9b29c3c93d2feee1d0964dc2bae2e5ad7a6c73a7f25325/pandas-2.3.3-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:c46467899aaa4da076d5abc11084634e2d197e9460643dd455ac3db5856b24d6", size = 12886834, upload-time = "2025-09-29T23:28:21.289Z" }, - { url = "https://files.pythonhosted.org/packages/d3/18/b5d48f55821228d0d2692b34fd5034bb185e854bdb592e9c640f6290e012/pandas-2.3.3-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:6253c72c6a1d990a410bc7de641d34053364ef8bcd3126f7e7450125887dffe3", size = 13409925, upload-time = "2025-09-29T23:28:58.261Z" }, - { url = "https://files.pythonhosted.org/packages/a6/3d/124ac75fcd0ecc09b8fdccb0246ef65e35b012030defb0e0eba2cbbbe948/pandas-2.3.3-cp314-cp314-win_amd64.whl", hash = "sha256:1b07204a219b3b7350abaae088f451860223a52cfb8a6c53358e7948735158e5", size = 11109071, upload-time = "2025-09-29T23:32:27.484Z" }, - { url = "https://files.pythonhosted.org/packages/89/9c/0e21c895c38a157e0faa1fb64587a9226d6dd46452cac4532d80c3c4a244/pandas-2.3.3-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:2462b1a365b6109d275250baaae7b760fd25c726aaca0054649286bcfbb3e8ec", size = 12048504, upload-time = "2025-09-29T23:29:31.47Z" }, - { url = "https://files.pythonhosted.org/packages/d7/82/b69a1c95df796858777b68fbe6a81d37443a33319761d7c652ce77797475/pandas-2.3.3-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:0242fe9a49aa8b4d78a4fa03acb397a58833ef6199e9aa40a95f027bb3a1b6e7", size = 11410702, upload-time = "2025-09-29T23:29:54.591Z" }, - { url = "https://files.pythonhosted.org/packages/f9/88/702bde3ba0a94b8c73a0181e05144b10f13f29ebfc2150c3a79062a8195d/pandas-2.3.3-cp314-cp314t-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:a21d830e78df0a515db2b3d2f5570610f5e6bd2e27749770e8bb7b524b89b450", size = 11634535, upload-time = "2025-09-29T23:30:21.003Z" }, - { url = "https://files.pythonhosted.org/packages/a4/1e/1bac1a839d12e6a82ec6cb40cda2edde64a2013a66963293696bbf31fbbb/pandas-2.3.3-cp314-cp314t-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:2e3ebdb170b5ef78f19bfb71b0dc5dc58775032361fa188e814959b74d726dd5", size = 12121582, upload-time = "2025-09-29T23:30:43.391Z" }, - { url = "https://files.pythonhosted.org/packages/44/91/483de934193e12a3b1d6ae7c8645d083ff88dec75f46e827562f1e4b4da6/pandas-2.3.3-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:d051c0e065b94b7a3cea50eb1ec32e912cd96dba41647eb24104b6c6c14c5788", size = 12699963, upload-time = "2025-09-29T23:31:10.009Z" }, - { url = "https://files.pythonhosted.org/packages/70/44/5191d2e4026f86a2a109053e194d3ba7a31a2d10a9c2348368c63ed4e85a/pandas-2.3.3-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:3869faf4bd07b3b66a9f462417d0ca3a9df29a9f6abd5d0d0dbab15dac7abe87", size = 13202175, upload-time = "2025-09-29T23:31:59.173Z" }, +sdist = { url = "https://files.pythonhosted.org/packages/33/01/d40b85317f86cf08d853a4f495195c73815fdf205eef3993821720274518/pandas-2.3.3.tar.gz", hash = "sha256:e05e1af93b977f7eafa636d043f9f94c7ee3ac81af99c13508215942e64c993b", size = 4495223 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/cd/4b/18b035ee18f97c1040d94debd8f2e737000ad70ccc8f5513f4eefad75f4b/pandas-2.3.3-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:56851a737e3470de7fa88e6131f41281ed440d29a9268dcbf0002da5ac366713", size = 11544671 }, + { url = "https://files.pythonhosted.org/packages/31/94/72fac03573102779920099bcac1c3b05975c2cb5f01eac609faf34bed1ca/pandas-2.3.3-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:bdcd9d1167f4885211e401b3036c0c8d9e274eee67ea8d0758a256d60704cfe8", size = 10680807 }, + { url = "https://files.pythonhosted.org/packages/16/87/9472cf4a487d848476865321de18cc8c920b8cab98453ab79dbbc98db63a/pandas-2.3.3-cp313-cp313-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:e32e7cc9af0f1cc15548288a51a3b681cc2a219faa838e995f7dc53dbab1062d", size = 11709872 }, + { url = "https://files.pythonhosted.org/packages/15/07/284f757f63f8a8d69ed4472bfd85122bd086e637bf4ed09de572d575a693/pandas-2.3.3-cp313-cp313-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:318d77e0e42a628c04dc56bcef4b40de67918f7041c2b061af1da41dcff670ac", size = 12306371 }, + { url = "https://files.pythonhosted.org/packages/33/81/a3afc88fca4aa925804a27d2676d22dcd2031c2ebe08aabd0ae55b9ff282/pandas-2.3.3-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:4e0a175408804d566144e170d0476b15d78458795bb18f1304fb94160cabf40c", size = 12765333 }, + { url = "https://files.pythonhosted.org/packages/8d/0f/b4d4ae743a83742f1153464cf1a8ecfafc3ac59722a0b5c8602310cb7158/pandas-2.3.3-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:93c2d9ab0fc11822b5eece72ec9587e172f63cff87c00b062f6e37448ced4493", size = 13418120 }, + { url = "https://files.pythonhosted.org/packages/4f/c7/e54682c96a895d0c808453269e0b5928a07a127a15704fedb643e9b0a4c8/pandas-2.3.3-cp313-cp313-win_amd64.whl", hash = "sha256:f8bfc0e12dc78f777f323f55c58649591b2cd0c43534e8355c51d3fede5f4dee", size = 10993991 }, + { url = "https://files.pythonhosted.org/packages/f9/ca/3f8d4f49740799189e1395812f3bf23b5e8fc7c190827d55a610da72ce55/pandas-2.3.3-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:75ea25f9529fdec2d2e93a42c523962261e567d250b0013b16210e1d40d7c2e5", size = 12048227 }, + { url = "https://files.pythonhosted.org/packages/0e/5a/f43efec3e8c0cc92c4663ccad372dbdff72b60bdb56b2749f04aa1d07d7e/pandas-2.3.3-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:74ecdf1d301e812db96a465a525952f4dde225fdb6d8e5a521d47e1f42041e21", size = 11411056 }, + { url = "https://files.pythonhosted.org/packages/46/b1/85331edfc591208c9d1a63a06baa67b21d332e63b7a591a5ba42a10bb507/pandas-2.3.3-cp313-cp313t-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6435cb949cb34ec11cc9860246ccb2fdc9ecd742c12d3304989017d53f039a78", size = 11645189 }, + { url = "https://files.pythonhosted.org/packages/44/23/78d645adc35d94d1ac4f2a3c4112ab6f5b8999f4898b8cdf01252f8df4a9/pandas-2.3.3-cp313-cp313t-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:900f47d8f20860de523a1ac881c4c36d65efcb2eb850e6948140fa781736e110", size = 12121912 }, + { url = "https://files.pythonhosted.org/packages/53/da/d10013df5e6aaef6b425aa0c32e1fc1f3e431e4bcabd420517dceadce354/pandas-2.3.3-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:a45c765238e2ed7d7c608fc5bc4a6f88b642f2f01e70c0c23d2224dd21829d86", size = 12712160 }, + { url = "https://files.pythonhosted.org/packages/bd/17/e756653095a083d8a37cbd816cb87148debcfcd920129b25f99dd8d04271/pandas-2.3.3-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:c4fc4c21971a1a9f4bdb4c73978c7f7256caa3e62b323f70d6cb80db583350bc", size = 13199233 }, + { url = "https://files.pythonhosted.org/packages/04/fd/74903979833db8390b73b3a8a7d30d146d710bd32703724dd9083950386f/pandas-2.3.3-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:ee15f284898e7b246df8087fc82b87b01686f98ee67d85a17b7ab44143a3a9a0", size = 11540635 }, + { url = "https://files.pythonhosted.org/packages/21/00/266d6b357ad5e6d3ad55093a7e8efc7dd245f5a842b584db9f30b0f0a287/pandas-2.3.3-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:1611aedd912e1ff81ff41c745822980c49ce4a7907537be8692c8dbc31924593", size = 10759079 }, + { url = "https://files.pythonhosted.org/packages/ca/05/d01ef80a7a3a12b2f8bbf16daba1e17c98a2f039cbc8e2f77a2c5a63d382/pandas-2.3.3-cp314-cp314-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6d2cefc361461662ac48810cb14365a365ce864afe85ef1f447ff5a1e99ea81c", size = 11814049 }, + { url = "https://files.pythonhosted.org/packages/15/b2/0e62f78c0c5ba7e3d2c5945a82456f4fac76c480940f805e0b97fcbc2f65/pandas-2.3.3-cp314-cp314-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:ee67acbbf05014ea6c763beb097e03cd629961c8a632075eeb34247120abcb4b", size = 12332638 }, + { url = "https://files.pythonhosted.org/packages/c5/33/dd70400631b62b9b29c3c93d2feee1d0964dc2bae2e5ad7a6c73a7f25325/pandas-2.3.3-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:c46467899aaa4da076d5abc11084634e2d197e9460643dd455ac3db5856b24d6", size = 12886834 }, + { url = "https://files.pythonhosted.org/packages/d3/18/b5d48f55821228d0d2692b34fd5034bb185e854bdb592e9c640f6290e012/pandas-2.3.3-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:6253c72c6a1d990a410bc7de641d34053364ef8bcd3126f7e7450125887dffe3", size = 13409925 }, + { url = "https://files.pythonhosted.org/packages/a6/3d/124ac75fcd0ecc09b8fdccb0246ef65e35b012030defb0e0eba2cbbbe948/pandas-2.3.3-cp314-cp314-win_amd64.whl", hash = "sha256:1b07204a219b3b7350abaae088f451860223a52cfb8a6c53358e7948735158e5", size = 11109071 }, + { url = "https://files.pythonhosted.org/packages/89/9c/0e21c895c38a157e0faa1fb64587a9226d6dd46452cac4532d80c3c4a244/pandas-2.3.3-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:2462b1a365b6109d275250baaae7b760fd25c726aaca0054649286bcfbb3e8ec", size = 12048504 }, + { url = "https://files.pythonhosted.org/packages/d7/82/b69a1c95df796858777b68fbe6a81d37443a33319761d7c652ce77797475/pandas-2.3.3-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:0242fe9a49aa8b4d78a4fa03acb397a58833ef6199e9aa40a95f027bb3a1b6e7", size = 11410702 }, + { url = "https://files.pythonhosted.org/packages/f9/88/702bde3ba0a94b8c73a0181e05144b10f13f29ebfc2150c3a79062a8195d/pandas-2.3.3-cp314-cp314t-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:a21d830e78df0a515db2b3d2f5570610f5e6bd2e27749770e8bb7b524b89b450", size = 11634535 }, + { url = "https://files.pythonhosted.org/packages/a4/1e/1bac1a839d12e6a82ec6cb40cda2edde64a2013a66963293696bbf31fbbb/pandas-2.3.3-cp314-cp314t-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:2e3ebdb170b5ef78f19bfb71b0dc5dc58775032361fa188e814959b74d726dd5", size = 12121582 }, + { url = "https://files.pythonhosted.org/packages/44/91/483de934193e12a3b1d6ae7c8645d083ff88dec75f46e827562f1e4b4da6/pandas-2.3.3-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:d051c0e065b94b7a3cea50eb1ec32e912cd96dba41647eb24104b6c6c14c5788", size = 12699963 }, + { url = "https://files.pythonhosted.org/packages/70/44/5191d2e4026f86a2a109053e194d3ba7a31a2d10a9c2348368c63ed4e85a/pandas-2.3.3-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:3869faf4bd07b3b66a9f462417d0ca3a9df29a9f6abd5d0d0dbab15dac7abe87", size = 13202175 }, ] [[package]] @@ -1239,76 +1248,76 @@ dependencies = [ { name = "sqlalchemy" }, { name = "typer" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/c3/fe/84f4d06ac3e6038384847dc1d5c8b956f61b780f69509d177107b550c7b9/paracelsus-0.12.0.tar.gz", hash = "sha256:f1d8f584ebc445db99a2906f97ff55f36ae663c104320dd4a6b5b78b4fa24dce", size = 83664, upload-time = "2025-10-07T12:45:41.112Z" } +sdist = { url = "https://files.pythonhosted.org/packages/c3/fe/84f4d06ac3e6038384847dc1d5c8b956f61b780f69509d177107b550c7b9/paracelsus-0.12.0.tar.gz", hash = "sha256:f1d8f584ebc445db99a2906f97ff55f36ae663c104320dd4a6b5b78b4fa24dce", size = 83664 } wheels = [ - { url = "https://files.pythonhosted.org/packages/b3/60/9062e4072c16750b6b01bac9c55b329b249ee7c970d61c128049be197d7a/paracelsus-0.12.0-py3-none-any.whl", hash = "sha256:01f5a508174d06a86d53374215a0c85962498361ac3f0bd3450023760d3b3836", size = 81236, upload-time = "2025-10-07T12:45:39.929Z" }, + { url = "https://files.pythonhosted.org/packages/b3/60/9062e4072c16750b6b01bac9c55b329b249ee7c970d61c128049be197d7a/paracelsus-0.12.0-py3-none-any.whl", hash = "sha256:01f5a508174d06a86d53374215a0c85962498361ac3f0bd3450023760d3b3836", size = 81236 }, ] [[package]] name = "pillow" version = "12.0.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/5a/b0/cace85a1b0c9775a9f8f5d5423c8261c858760e2466c79b2dd184638b056/pillow-12.0.0.tar.gz", hash = "sha256:87d4f8125c9988bfbed67af47dd7a953e2fc7b0cc1e7800ec6d2080d490bb353", size = 47008828, upload-time = "2025-10-15T18:24:14.008Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/62/f2/de993bb2d21b33a98d031ecf6a978e4b61da207bef02f7b43093774c480d/pillow-12.0.0-cp313-cp313-ios_13_0_arm64_iphoneos.whl", hash = "sha256:0869154a2d0546545cde61d1789a6524319fc1897d9ee31218eae7a60ccc5643", size = 4045493, upload-time = "2025-10-15T18:22:25.758Z" }, - { url = "https://files.pythonhosted.org/packages/0e/b6/bc8d0c4c9f6f111a783d045310945deb769b806d7574764234ffd50bc5ea/pillow-12.0.0-cp313-cp313-ios_13_0_arm64_iphonesimulator.whl", hash = "sha256:a7921c5a6d31b3d756ec980f2f47c0cfdbce0fc48c22a39347a895f41f4a6ea4", size = 4120461, upload-time = "2025-10-15T18:22:27.286Z" }, - { url = "https://files.pythonhosted.org/packages/5d/57/d60d343709366a353dc56adb4ee1e7d8a2cc34e3fbc22905f4167cfec119/pillow-12.0.0-cp313-cp313-ios_13_0_x86_64_iphonesimulator.whl", hash = "sha256:1ee80a59f6ce048ae13cda1abf7fbd2a34ab9ee7d401c46be3ca685d1999a399", size = 3576912, upload-time = "2025-10-15T18:22:28.751Z" }, - { url = "https://files.pythonhosted.org/packages/a4/a4/a0a31467e3f83b94d37568294b01d22b43ae3c5d85f2811769b9c66389dd/pillow-12.0.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:c50f36a62a22d350c96e49ad02d0da41dbd17ddc2e29750dbdba4323f85eb4a5", size = 5249132, upload-time = "2025-10-15T18:22:30.641Z" }, - { url = "https://files.pythonhosted.org/packages/83/06/48eab21dd561de2914242711434c0c0eb992ed08ff3f6107a5f44527f5e9/pillow-12.0.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:5193fde9a5f23c331ea26d0cf171fbf67e3f247585f50c08b3e205c7aeb4589b", size = 4650099, upload-time = "2025-10-15T18:22:32.73Z" }, - { url = "https://files.pythonhosted.org/packages/fc/bd/69ed99fd46a8dba7c1887156d3572fe4484e3f031405fcc5a92e31c04035/pillow-12.0.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:bde737cff1a975b70652b62d626f7785e0480918dece11e8fef3c0cf057351c3", size = 6230808, upload-time = "2025-10-15T18:22:34.337Z" }, - { url = "https://files.pythonhosted.org/packages/ea/94/8fad659bcdbf86ed70099cb60ae40be6acca434bbc8c4c0d4ef356d7e0de/pillow-12.0.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:a6597ff2b61d121172f5844b53f21467f7082f5fb385a9a29c01414463f93b07", size = 8037804, upload-time = "2025-10-15T18:22:36.402Z" }, - { url = "https://files.pythonhosted.org/packages/20/39/c685d05c06deecfd4e2d1950e9a908aa2ca8bc4e6c3b12d93b9cafbd7837/pillow-12.0.0-cp313-cp313-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:0b817e7035ea7f6b942c13aa03bb554fc44fea70838ea21f8eb31c638326584e", size = 6345553, upload-time = "2025-10-15T18:22:38.066Z" }, - { url = "https://files.pythonhosted.org/packages/38/57/755dbd06530a27a5ed74f8cb0a7a44a21722ebf318edbe67ddbd7fb28f88/pillow-12.0.0-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:f4f1231b7dec408e8670264ce63e9c71409d9583dd21d32c163e25213ee2a344", size = 7037729, upload-time = "2025-10-15T18:22:39.769Z" }, - { url = "https://files.pythonhosted.org/packages/ca/b6/7e94f4c41d238615674d06ed677c14883103dce1c52e4af16f000338cfd7/pillow-12.0.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:6e51b71417049ad6ab14c49608b4a24d8fb3fe605e5dfabfe523b58064dc3d27", size = 6459789, upload-time = "2025-10-15T18:22:41.437Z" }, - { url = "https://files.pythonhosted.org/packages/9c/14/4448bb0b5e0f22dd865290536d20ec8a23b64e2d04280b89139f09a36bb6/pillow-12.0.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:d120c38a42c234dc9a8c5de7ceaaf899cf33561956acb4941653f8bdc657aa79", size = 7130917, upload-time = "2025-10-15T18:22:43.152Z" }, - { url = "https://files.pythonhosted.org/packages/dd/ca/16c6926cc1c015845745d5c16c9358e24282f1e588237a4c36d2b30f182f/pillow-12.0.0-cp313-cp313-win32.whl", hash = "sha256:4cc6b3b2efff105c6a1656cfe59da4fdde2cda9af1c5e0b58529b24525d0a098", size = 6302391, upload-time = "2025-10-15T18:22:44.753Z" }, - { url = "https://files.pythonhosted.org/packages/6d/2a/dd43dcfd6dae9b6a49ee28a8eedb98c7d5ff2de94a5d834565164667b97b/pillow-12.0.0-cp313-cp313-win_amd64.whl", hash = "sha256:4cf7fed4b4580601c4345ceb5d4cbf5a980d030fd5ad07c4d2ec589f95f09905", size = 7007477, upload-time = "2025-10-15T18:22:46.838Z" }, - { url = "https://files.pythonhosted.org/packages/77/f0/72ea067f4b5ae5ead653053212af05ce3705807906ba3f3e8f58ddf617e6/pillow-12.0.0-cp313-cp313-win_arm64.whl", hash = "sha256:9f0b04c6b8584c2c193babcccc908b38ed29524b29dd464bc8801bf10d746a3a", size = 2435918, upload-time = "2025-10-15T18:22:48.399Z" }, - { url = "https://files.pythonhosted.org/packages/f5/5e/9046b423735c21f0487ea6cb5b10f89ea8f8dfbe32576fe052b5ba9d4e5b/pillow-12.0.0-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:7fa22993bac7b77b78cae22bad1e2a987ddf0d9015c63358032f84a53f23cdc3", size = 5251406, upload-time = "2025-10-15T18:22:49.905Z" }, - { url = "https://files.pythonhosted.org/packages/12/66/982ceebcdb13c97270ef7a56c3969635b4ee7cd45227fa707c94719229c5/pillow-12.0.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:f135c702ac42262573fe9714dfe99c944b4ba307af5eb507abef1667e2cbbced", size = 4653218, upload-time = "2025-10-15T18:22:51.587Z" }, - { url = "https://files.pythonhosted.org/packages/16/b3/81e625524688c31859450119bf12674619429cab3119eec0e30a7a1029cb/pillow-12.0.0-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:c85de1136429c524e55cfa4e033b4a7940ac5c8ee4d9401cc2d1bf48154bbc7b", size = 6266564, upload-time = "2025-10-15T18:22:53.215Z" }, - { url = "https://files.pythonhosted.org/packages/98/59/dfb38f2a41240d2408096e1a76c671d0a105a4a8471b1871c6902719450c/pillow-12.0.0-cp313-cp313t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:38df9b4bfd3db902c9c2bd369bcacaf9d935b2fff73709429d95cc41554f7b3d", size = 8069260, upload-time = "2025-10-15T18:22:54.933Z" }, - { url = "https://files.pythonhosted.org/packages/dc/3d/378dbea5cd1874b94c312425ca77b0f47776c78e0df2df751b820c8c1d6c/pillow-12.0.0-cp313-cp313t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:7d87ef5795da03d742bf49439f9ca4d027cde49c82c5371ba52464aee266699a", size = 6379248, upload-time = "2025-10-15T18:22:56.605Z" }, - { url = "https://files.pythonhosted.org/packages/84/b0/d525ef47d71590f1621510327acec75ae58c721dc071b17d8d652ca494d8/pillow-12.0.0-cp313-cp313t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:aff9e4d82d082ff9513bdd6acd4f5bd359f5b2c870907d2b0a9c5e10d40c88fe", size = 7066043, upload-time = "2025-10-15T18:22:58.53Z" }, - { url = "https://files.pythonhosted.org/packages/61/2c/aced60e9cf9d0cde341d54bf7932c9ffc33ddb4a1595798b3a5150c7ec4e/pillow-12.0.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:8d8ca2b210ada074d57fcee40c30446c9562e542fc46aedc19baf758a93532ee", size = 6490915, upload-time = "2025-10-15T18:23:00.582Z" }, - { url = "https://files.pythonhosted.org/packages/ef/26/69dcb9b91f4e59f8f34b2332a4a0a951b44f547c4ed39d3e4dcfcff48f89/pillow-12.0.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:99a7f72fb6249302aa62245680754862a44179b545ded638cf1fef59befb57ef", size = 7157998, upload-time = "2025-10-15T18:23:02.627Z" }, - { url = "https://files.pythonhosted.org/packages/61/2b/726235842220ca95fa441ddf55dd2382b52ab5b8d9c0596fe6b3f23dafe8/pillow-12.0.0-cp313-cp313t-win32.whl", hash = "sha256:4078242472387600b2ce8d93ade8899c12bf33fa89e55ec89fe126e9d6d5d9e9", size = 6306201, upload-time = "2025-10-15T18:23:04.709Z" }, - { url = "https://files.pythonhosted.org/packages/c0/3d/2afaf4e840b2df71344ababf2f8edd75a705ce500e5dc1e7227808312ae1/pillow-12.0.0-cp313-cp313t-win_amd64.whl", hash = "sha256:2c54c1a783d6d60595d3514f0efe9b37c8808746a66920315bfd34a938d7994b", size = 7013165, upload-time = "2025-10-15T18:23:06.46Z" }, - { url = "https://files.pythonhosted.org/packages/6f/75/3fa09aa5cf6ed04bee3fa575798ddf1ce0bace8edb47249c798077a81f7f/pillow-12.0.0-cp313-cp313t-win_arm64.whl", hash = "sha256:26d9f7d2b604cd23aba3e9faf795787456ac25634d82cd060556998e39c6fa47", size = 2437834, upload-time = "2025-10-15T18:23:08.194Z" }, - { url = "https://files.pythonhosted.org/packages/54/2a/9a8c6ba2c2c07b71bec92cf63e03370ca5e5f5c5b119b742bcc0cde3f9c5/pillow-12.0.0-cp314-cp314-ios_13_0_arm64_iphoneos.whl", hash = "sha256:beeae3f27f62308f1ddbcfb0690bf44b10732f2ef43758f169d5e9303165d3f9", size = 4045531, upload-time = "2025-10-15T18:23:10.121Z" }, - { url = "https://files.pythonhosted.org/packages/84/54/836fdbf1bfb3d66a59f0189ff0b9f5f666cee09c6188309300df04ad71fa/pillow-12.0.0-cp314-cp314-ios_13_0_arm64_iphonesimulator.whl", hash = "sha256:d4827615da15cd59784ce39d3388275ec093ae3ee8d7f0c089b76fa87af756c2", size = 4120554, upload-time = "2025-10-15T18:23:12.14Z" }, - { url = "https://files.pythonhosted.org/packages/0d/cd/16aec9f0da4793e98e6b54778a5fbce4f375c6646fe662e80600b8797379/pillow-12.0.0-cp314-cp314-ios_13_0_x86_64_iphonesimulator.whl", hash = "sha256:3e42edad50b6909089750e65c91aa09aaf1e0a71310d383f11321b27c224ed8a", size = 3576812, upload-time = "2025-10-15T18:23:13.962Z" }, - { url = "https://files.pythonhosted.org/packages/f6/b7/13957fda356dc46339298b351cae0d327704986337c3c69bb54628c88155/pillow-12.0.0-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:e5d8efac84c9afcb40914ab49ba063d94f5dbdf5066db4482c66a992f47a3a3b", size = 5252689, upload-time = "2025-10-15T18:23:15.562Z" }, - { url = "https://files.pythonhosted.org/packages/fc/f5/eae31a306341d8f331f43edb2e9122c7661b975433de5e447939ae61c5da/pillow-12.0.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:266cd5f2b63ff316d5a1bba46268e603c9caf5606d44f38c2873c380950576ad", size = 4650186, upload-time = "2025-10-15T18:23:17.379Z" }, - { url = "https://files.pythonhosted.org/packages/86/62/2a88339aa40c4c77e79108facbd307d6091e2c0eb5b8d3cf4977cfca2fe6/pillow-12.0.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:58eea5ebe51504057dd95c5b77d21700b77615ab0243d8152793dc00eb4faf01", size = 6230308, upload-time = "2025-10-15T18:23:18.971Z" }, - { url = "https://files.pythonhosted.org/packages/c7/33/5425a8992bcb32d1cb9fa3dd39a89e613d09a22f2c8083b7bf43c455f760/pillow-12.0.0-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:f13711b1a5ba512d647a0e4ba79280d3a9a045aaf7e0cc6fbe96b91d4cdf6b0c", size = 8039222, upload-time = "2025-10-15T18:23:20.909Z" }, - { url = "https://files.pythonhosted.org/packages/d8/61/3f5d3b35c5728f37953d3eec5b5f3e77111949523bd2dd7f31a851e50690/pillow-12.0.0-cp314-cp314-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6846bd2d116ff42cba6b646edf5bf61d37e5cbd256425fa089fee4ff5c07a99e", size = 6346657, upload-time = "2025-10-15T18:23:23.077Z" }, - { url = "https://files.pythonhosted.org/packages/3a/be/ee90a3d79271227e0f0a33c453531efd6ed14b2e708596ba5dd9be948da3/pillow-12.0.0-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c98fa880d695de164b4135a52fd2e9cd7b7c90a9d8ac5e9e443a24a95ef9248e", size = 7038482, upload-time = "2025-10-15T18:23:25.005Z" }, - { url = "https://files.pythonhosted.org/packages/44/34/a16b6a4d1ad727de390e9bd9f19f5f669e079e5826ec0f329010ddea492f/pillow-12.0.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:fa3ed2a29a9e9d2d488b4da81dcb54720ac3104a20bf0bd273f1e4648aff5af9", size = 6461416, upload-time = "2025-10-15T18:23:27.009Z" }, - { url = "https://files.pythonhosted.org/packages/b6/39/1aa5850d2ade7d7ba9f54e4e4c17077244ff7a2d9e25998c38a29749eb3f/pillow-12.0.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:d034140032870024e6b9892c692fe2968493790dd57208b2c37e3fb35f6df3ab", size = 7131584, upload-time = "2025-10-15T18:23:29.752Z" }, - { url = "https://files.pythonhosted.org/packages/bf/db/4fae862f8fad0167073a7733973bfa955f47e2cac3dc3e3e6257d10fab4a/pillow-12.0.0-cp314-cp314-win32.whl", hash = "sha256:1b1b133e6e16105f524a8dec491e0586d072948ce15c9b914e41cdadd209052b", size = 6400621, upload-time = "2025-10-15T18:23:32.06Z" }, - { url = "https://files.pythonhosted.org/packages/2b/24/b350c31543fb0107ab2599464d7e28e6f856027aadda995022e695313d94/pillow-12.0.0-cp314-cp314-win_amd64.whl", hash = "sha256:8dc232e39d409036af549c86f24aed8273a40ffa459981146829a324e0848b4b", size = 7142916, upload-time = "2025-10-15T18:23:34.71Z" }, - { url = "https://files.pythonhosted.org/packages/0f/9b/0ba5a6fd9351793996ef7487c4fdbde8d3f5f75dbedc093bb598648fddf0/pillow-12.0.0-cp314-cp314-win_arm64.whl", hash = "sha256:d52610d51e265a51518692045e372a4c363056130d922a7351429ac9f27e70b0", size = 2523836, upload-time = "2025-10-15T18:23:36.967Z" }, - { url = "https://files.pythonhosted.org/packages/f5/7a/ceee0840aebc579af529b523d530840338ecf63992395842e54edc805987/pillow-12.0.0-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:1979f4566bb96c1e50a62d9831e2ea2d1211761e5662afc545fa766f996632f6", size = 5255092, upload-time = "2025-10-15T18:23:38.573Z" }, - { url = "https://files.pythonhosted.org/packages/44/76/20776057b4bfd1aef4eeca992ebde0f53a4dce874f3ae693d0ec90a4f79b/pillow-12.0.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:b2e4b27a6e15b04832fe9bf292b94b5ca156016bbc1ea9c2c20098a0320d6cf6", size = 4653158, upload-time = "2025-10-15T18:23:40.238Z" }, - { url = "https://files.pythonhosted.org/packages/82/3f/d9ff92ace07be8836b4e7e87e6a4c7a8318d47c2f1463ffcf121fc57d9cb/pillow-12.0.0-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:fb3096c30df99fd01c7bf8e544f392103d0795b9f98ba71a8054bcbf56b255f1", size = 6267882, upload-time = "2025-10-15T18:23:42.434Z" }, - { url = "https://files.pythonhosted.org/packages/9f/7a/4f7ff87f00d3ad33ba21af78bfcd2f032107710baf8280e3722ceec28cda/pillow-12.0.0-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:7438839e9e053ef79f7112c881cef684013855016f928b168b81ed5835f3e75e", size = 8071001, upload-time = "2025-10-15T18:23:44.29Z" }, - { url = "https://files.pythonhosted.org/packages/75/87/fcea108944a52dad8cca0715ae6247e271eb80459364a98518f1e4f480c1/pillow-12.0.0-cp314-cp314t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:5d5c411a8eaa2299322b647cd932586b1427367fd3184ffbb8f7a219ea2041ca", size = 6380146, upload-time = "2025-10-15T18:23:46.065Z" }, - { url = "https://files.pythonhosted.org/packages/91/52/0d31b5e571ef5fd111d2978b84603fce26aba1b6092f28e941cb46570745/pillow-12.0.0-cp314-cp314t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:d7e091d464ac59d2c7ad8e7e08105eaf9dafbc3883fd7265ffccc2baad6ac925", size = 7067344, upload-time = "2025-10-15T18:23:47.898Z" }, - { url = "https://files.pythonhosted.org/packages/7b/f4/2dd3d721f875f928d48e83bb30a434dee75a2531bca839bb996bb0aa5a91/pillow-12.0.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:792a2c0be4dcc18af9d4a2dfd8a11a17d5e25274a1062b0ec1c2d79c76f3e7f8", size = 6491864, upload-time = "2025-10-15T18:23:49.607Z" }, - { url = "https://files.pythonhosted.org/packages/30/4b/667dfcf3d61fc309ba5a15b141845cece5915e39b99c1ceab0f34bf1d124/pillow-12.0.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:afbefa430092f71a9593a99ab6a4e7538bc9eabbf7bf94f91510d3503943edc4", size = 7158911, upload-time = "2025-10-15T18:23:51.351Z" }, - { url = "https://files.pythonhosted.org/packages/a2/2f/16cabcc6426c32218ace36bf0d55955e813f2958afddbf1d391849fee9d1/pillow-12.0.0-cp314-cp314t-win32.whl", hash = "sha256:3830c769decf88f1289680a59d4f4c46c72573446352e2befec9a8512104fa52", size = 6408045, upload-time = "2025-10-15T18:23:53.177Z" }, - { url = "https://files.pythonhosted.org/packages/35/73/e29aa0c9c666cf787628d3f0dcf379f4791fba79f4936d02f8b37165bdf8/pillow-12.0.0-cp314-cp314t-win_amd64.whl", hash = "sha256:905b0365b210c73afb0ebe9101a32572152dfd1c144c7e28968a331b9217b94a", size = 7148282, upload-time = "2025-10-15T18:23:55.316Z" }, - { url = "https://files.pythonhosted.org/packages/c1/70/6b41bdcddf541b437bbb9f47f94d2db5d9ddef6c37ccab8c9107743748a4/pillow-12.0.0-cp314-cp314t-win_arm64.whl", hash = "sha256:99353a06902c2e43b43e8ff74ee65a7d90307d82370604746738a1e0661ccca7", size = 2525630, upload-time = "2025-10-15T18:23:57.149Z" }, +sdist = { url = "https://files.pythonhosted.org/packages/5a/b0/cace85a1b0c9775a9f8f5d5423c8261c858760e2466c79b2dd184638b056/pillow-12.0.0.tar.gz", hash = "sha256:87d4f8125c9988bfbed67af47dd7a953e2fc7b0cc1e7800ec6d2080d490bb353", size = 47008828 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/62/f2/de993bb2d21b33a98d031ecf6a978e4b61da207bef02f7b43093774c480d/pillow-12.0.0-cp313-cp313-ios_13_0_arm64_iphoneos.whl", hash = "sha256:0869154a2d0546545cde61d1789a6524319fc1897d9ee31218eae7a60ccc5643", size = 4045493 }, + { url = "https://files.pythonhosted.org/packages/0e/b6/bc8d0c4c9f6f111a783d045310945deb769b806d7574764234ffd50bc5ea/pillow-12.0.0-cp313-cp313-ios_13_0_arm64_iphonesimulator.whl", hash = "sha256:a7921c5a6d31b3d756ec980f2f47c0cfdbce0fc48c22a39347a895f41f4a6ea4", size = 4120461 }, + { url = "https://files.pythonhosted.org/packages/5d/57/d60d343709366a353dc56adb4ee1e7d8a2cc34e3fbc22905f4167cfec119/pillow-12.0.0-cp313-cp313-ios_13_0_x86_64_iphonesimulator.whl", hash = "sha256:1ee80a59f6ce048ae13cda1abf7fbd2a34ab9ee7d401c46be3ca685d1999a399", size = 3576912 }, + { url = "https://files.pythonhosted.org/packages/a4/a4/a0a31467e3f83b94d37568294b01d22b43ae3c5d85f2811769b9c66389dd/pillow-12.0.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:c50f36a62a22d350c96e49ad02d0da41dbd17ddc2e29750dbdba4323f85eb4a5", size = 5249132 }, + { url = "https://files.pythonhosted.org/packages/83/06/48eab21dd561de2914242711434c0c0eb992ed08ff3f6107a5f44527f5e9/pillow-12.0.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:5193fde9a5f23c331ea26d0cf171fbf67e3f247585f50c08b3e205c7aeb4589b", size = 4650099 }, + { url = "https://files.pythonhosted.org/packages/fc/bd/69ed99fd46a8dba7c1887156d3572fe4484e3f031405fcc5a92e31c04035/pillow-12.0.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:bde737cff1a975b70652b62d626f7785e0480918dece11e8fef3c0cf057351c3", size = 6230808 }, + { url = "https://files.pythonhosted.org/packages/ea/94/8fad659bcdbf86ed70099cb60ae40be6acca434bbc8c4c0d4ef356d7e0de/pillow-12.0.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:a6597ff2b61d121172f5844b53f21467f7082f5fb385a9a29c01414463f93b07", size = 8037804 }, + { url = "https://files.pythonhosted.org/packages/20/39/c685d05c06deecfd4e2d1950e9a908aa2ca8bc4e6c3b12d93b9cafbd7837/pillow-12.0.0-cp313-cp313-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:0b817e7035ea7f6b942c13aa03bb554fc44fea70838ea21f8eb31c638326584e", size = 6345553 }, + { url = "https://files.pythonhosted.org/packages/38/57/755dbd06530a27a5ed74f8cb0a7a44a21722ebf318edbe67ddbd7fb28f88/pillow-12.0.0-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:f4f1231b7dec408e8670264ce63e9c71409d9583dd21d32c163e25213ee2a344", size = 7037729 }, + { url = "https://files.pythonhosted.org/packages/ca/b6/7e94f4c41d238615674d06ed677c14883103dce1c52e4af16f000338cfd7/pillow-12.0.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:6e51b71417049ad6ab14c49608b4a24d8fb3fe605e5dfabfe523b58064dc3d27", size = 6459789 }, + { url = "https://files.pythonhosted.org/packages/9c/14/4448bb0b5e0f22dd865290536d20ec8a23b64e2d04280b89139f09a36bb6/pillow-12.0.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:d120c38a42c234dc9a8c5de7ceaaf899cf33561956acb4941653f8bdc657aa79", size = 7130917 }, + { url = "https://files.pythonhosted.org/packages/dd/ca/16c6926cc1c015845745d5c16c9358e24282f1e588237a4c36d2b30f182f/pillow-12.0.0-cp313-cp313-win32.whl", hash = "sha256:4cc6b3b2efff105c6a1656cfe59da4fdde2cda9af1c5e0b58529b24525d0a098", size = 6302391 }, + { url = "https://files.pythonhosted.org/packages/6d/2a/dd43dcfd6dae9b6a49ee28a8eedb98c7d5ff2de94a5d834565164667b97b/pillow-12.0.0-cp313-cp313-win_amd64.whl", hash = "sha256:4cf7fed4b4580601c4345ceb5d4cbf5a980d030fd5ad07c4d2ec589f95f09905", size = 7007477 }, + { url = "https://files.pythonhosted.org/packages/77/f0/72ea067f4b5ae5ead653053212af05ce3705807906ba3f3e8f58ddf617e6/pillow-12.0.0-cp313-cp313-win_arm64.whl", hash = "sha256:9f0b04c6b8584c2c193babcccc908b38ed29524b29dd464bc8801bf10d746a3a", size = 2435918 }, + { url = "https://files.pythonhosted.org/packages/f5/5e/9046b423735c21f0487ea6cb5b10f89ea8f8dfbe32576fe052b5ba9d4e5b/pillow-12.0.0-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:7fa22993bac7b77b78cae22bad1e2a987ddf0d9015c63358032f84a53f23cdc3", size = 5251406 }, + { url = "https://files.pythonhosted.org/packages/12/66/982ceebcdb13c97270ef7a56c3969635b4ee7cd45227fa707c94719229c5/pillow-12.0.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:f135c702ac42262573fe9714dfe99c944b4ba307af5eb507abef1667e2cbbced", size = 4653218 }, + { url = "https://files.pythonhosted.org/packages/16/b3/81e625524688c31859450119bf12674619429cab3119eec0e30a7a1029cb/pillow-12.0.0-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:c85de1136429c524e55cfa4e033b4a7940ac5c8ee4d9401cc2d1bf48154bbc7b", size = 6266564 }, + { url = "https://files.pythonhosted.org/packages/98/59/dfb38f2a41240d2408096e1a76c671d0a105a4a8471b1871c6902719450c/pillow-12.0.0-cp313-cp313t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:38df9b4bfd3db902c9c2bd369bcacaf9d935b2fff73709429d95cc41554f7b3d", size = 8069260 }, + { url = "https://files.pythonhosted.org/packages/dc/3d/378dbea5cd1874b94c312425ca77b0f47776c78e0df2df751b820c8c1d6c/pillow-12.0.0-cp313-cp313t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:7d87ef5795da03d742bf49439f9ca4d027cde49c82c5371ba52464aee266699a", size = 6379248 }, + { url = "https://files.pythonhosted.org/packages/84/b0/d525ef47d71590f1621510327acec75ae58c721dc071b17d8d652ca494d8/pillow-12.0.0-cp313-cp313t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:aff9e4d82d082ff9513bdd6acd4f5bd359f5b2c870907d2b0a9c5e10d40c88fe", size = 7066043 }, + { url = "https://files.pythonhosted.org/packages/61/2c/aced60e9cf9d0cde341d54bf7932c9ffc33ddb4a1595798b3a5150c7ec4e/pillow-12.0.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:8d8ca2b210ada074d57fcee40c30446c9562e542fc46aedc19baf758a93532ee", size = 6490915 }, + { url = "https://files.pythonhosted.org/packages/ef/26/69dcb9b91f4e59f8f34b2332a4a0a951b44f547c4ed39d3e4dcfcff48f89/pillow-12.0.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:99a7f72fb6249302aa62245680754862a44179b545ded638cf1fef59befb57ef", size = 7157998 }, + { url = "https://files.pythonhosted.org/packages/61/2b/726235842220ca95fa441ddf55dd2382b52ab5b8d9c0596fe6b3f23dafe8/pillow-12.0.0-cp313-cp313t-win32.whl", hash = "sha256:4078242472387600b2ce8d93ade8899c12bf33fa89e55ec89fe126e9d6d5d9e9", size = 6306201 }, + { url = "https://files.pythonhosted.org/packages/c0/3d/2afaf4e840b2df71344ababf2f8edd75a705ce500e5dc1e7227808312ae1/pillow-12.0.0-cp313-cp313t-win_amd64.whl", hash = "sha256:2c54c1a783d6d60595d3514f0efe9b37c8808746a66920315bfd34a938d7994b", size = 7013165 }, + { url = "https://files.pythonhosted.org/packages/6f/75/3fa09aa5cf6ed04bee3fa575798ddf1ce0bace8edb47249c798077a81f7f/pillow-12.0.0-cp313-cp313t-win_arm64.whl", hash = "sha256:26d9f7d2b604cd23aba3e9faf795787456ac25634d82cd060556998e39c6fa47", size = 2437834 }, + { url = "https://files.pythonhosted.org/packages/54/2a/9a8c6ba2c2c07b71bec92cf63e03370ca5e5f5c5b119b742bcc0cde3f9c5/pillow-12.0.0-cp314-cp314-ios_13_0_arm64_iphoneos.whl", hash = "sha256:beeae3f27f62308f1ddbcfb0690bf44b10732f2ef43758f169d5e9303165d3f9", size = 4045531 }, + { url = "https://files.pythonhosted.org/packages/84/54/836fdbf1bfb3d66a59f0189ff0b9f5f666cee09c6188309300df04ad71fa/pillow-12.0.0-cp314-cp314-ios_13_0_arm64_iphonesimulator.whl", hash = "sha256:d4827615da15cd59784ce39d3388275ec093ae3ee8d7f0c089b76fa87af756c2", size = 4120554 }, + { url = "https://files.pythonhosted.org/packages/0d/cd/16aec9f0da4793e98e6b54778a5fbce4f375c6646fe662e80600b8797379/pillow-12.0.0-cp314-cp314-ios_13_0_x86_64_iphonesimulator.whl", hash = "sha256:3e42edad50b6909089750e65c91aa09aaf1e0a71310d383f11321b27c224ed8a", size = 3576812 }, + { url = "https://files.pythonhosted.org/packages/f6/b7/13957fda356dc46339298b351cae0d327704986337c3c69bb54628c88155/pillow-12.0.0-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:e5d8efac84c9afcb40914ab49ba063d94f5dbdf5066db4482c66a992f47a3a3b", size = 5252689 }, + { url = "https://files.pythonhosted.org/packages/fc/f5/eae31a306341d8f331f43edb2e9122c7661b975433de5e447939ae61c5da/pillow-12.0.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:266cd5f2b63ff316d5a1bba46268e603c9caf5606d44f38c2873c380950576ad", size = 4650186 }, + { url = "https://files.pythonhosted.org/packages/86/62/2a88339aa40c4c77e79108facbd307d6091e2c0eb5b8d3cf4977cfca2fe6/pillow-12.0.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:58eea5ebe51504057dd95c5b77d21700b77615ab0243d8152793dc00eb4faf01", size = 6230308 }, + { url = "https://files.pythonhosted.org/packages/c7/33/5425a8992bcb32d1cb9fa3dd39a89e613d09a22f2c8083b7bf43c455f760/pillow-12.0.0-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:f13711b1a5ba512d647a0e4ba79280d3a9a045aaf7e0cc6fbe96b91d4cdf6b0c", size = 8039222 }, + { url = "https://files.pythonhosted.org/packages/d8/61/3f5d3b35c5728f37953d3eec5b5f3e77111949523bd2dd7f31a851e50690/pillow-12.0.0-cp314-cp314-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6846bd2d116ff42cba6b646edf5bf61d37e5cbd256425fa089fee4ff5c07a99e", size = 6346657 }, + { url = "https://files.pythonhosted.org/packages/3a/be/ee90a3d79271227e0f0a33c453531efd6ed14b2e708596ba5dd9be948da3/pillow-12.0.0-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c98fa880d695de164b4135a52fd2e9cd7b7c90a9d8ac5e9e443a24a95ef9248e", size = 7038482 }, + { url = "https://files.pythonhosted.org/packages/44/34/a16b6a4d1ad727de390e9bd9f19f5f669e079e5826ec0f329010ddea492f/pillow-12.0.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:fa3ed2a29a9e9d2d488b4da81dcb54720ac3104a20bf0bd273f1e4648aff5af9", size = 6461416 }, + { url = "https://files.pythonhosted.org/packages/b6/39/1aa5850d2ade7d7ba9f54e4e4c17077244ff7a2d9e25998c38a29749eb3f/pillow-12.0.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:d034140032870024e6b9892c692fe2968493790dd57208b2c37e3fb35f6df3ab", size = 7131584 }, + { url = "https://files.pythonhosted.org/packages/bf/db/4fae862f8fad0167073a7733973bfa955f47e2cac3dc3e3e6257d10fab4a/pillow-12.0.0-cp314-cp314-win32.whl", hash = "sha256:1b1b133e6e16105f524a8dec491e0586d072948ce15c9b914e41cdadd209052b", size = 6400621 }, + { url = "https://files.pythonhosted.org/packages/2b/24/b350c31543fb0107ab2599464d7e28e6f856027aadda995022e695313d94/pillow-12.0.0-cp314-cp314-win_amd64.whl", hash = "sha256:8dc232e39d409036af549c86f24aed8273a40ffa459981146829a324e0848b4b", size = 7142916 }, + { url = "https://files.pythonhosted.org/packages/0f/9b/0ba5a6fd9351793996ef7487c4fdbde8d3f5f75dbedc093bb598648fddf0/pillow-12.0.0-cp314-cp314-win_arm64.whl", hash = "sha256:d52610d51e265a51518692045e372a4c363056130d922a7351429ac9f27e70b0", size = 2523836 }, + { url = "https://files.pythonhosted.org/packages/f5/7a/ceee0840aebc579af529b523d530840338ecf63992395842e54edc805987/pillow-12.0.0-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:1979f4566bb96c1e50a62d9831e2ea2d1211761e5662afc545fa766f996632f6", size = 5255092 }, + { url = "https://files.pythonhosted.org/packages/44/76/20776057b4bfd1aef4eeca992ebde0f53a4dce874f3ae693d0ec90a4f79b/pillow-12.0.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:b2e4b27a6e15b04832fe9bf292b94b5ca156016bbc1ea9c2c20098a0320d6cf6", size = 4653158 }, + { url = "https://files.pythonhosted.org/packages/82/3f/d9ff92ace07be8836b4e7e87e6a4c7a8318d47c2f1463ffcf121fc57d9cb/pillow-12.0.0-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:fb3096c30df99fd01c7bf8e544f392103d0795b9f98ba71a8054bcbf56b255f1", size = 6267882 }, + { url = "https://files.pythonhosted.org/packages/9f/7a/4f7ff87f00d3ad33ba21af78bfcd2f032107710baf8280e3722ceec28cda/pillow-12.0.0-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:7438839e9e053ef79f7112c881cef684013855016f928b168b81ed5835f3e75e", size = 8071001 }, + { url = "https://files.pythonhosted.org/packages/75/87/fcea108944a52dad8cca0715ae6247e271eb80459364a98518f1e4f480c1/pillow-12.0.0-cp314-cp314t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:5d5c411a8eaa2299322b647cd932586b1427367fd3184ffbb8f7a219ea2041ca", size = 6380146 }, + { url = "https://files.pythonhosted.org/packages/91/52/0d31b5e571ef5fd111d2978b84603fce26aba1b6092f28e941cb46570745/pillow-12.0.0-cp314-cp314t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:d7e091d464ac59d2c7ad8e7e08105eaf9dafbc3883fd7265ffccc2baad6ac925", size = 7067344 }, + { url = "https://files.pythonhosted.org/packages/7b/f4/2dd3d721f875f928d48e83bb30a434dee75a2531bca839bb996bb0aa5a91/pillow-12.0.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:792a2c0be4dcc18af9d4a2dfd8a11a17d5e25274a1062b0ec1c2d79c76f3e7f8", size = 6491864 }, + { url = "https://files.pythonhosted.org/packages/30/4b/667dfcf3d61fc309ba5a15b141845cece5915e39b99c1ceab0f34bf1d124/pillow-12.0.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:afbefa430092f71a9593a99ab6a4e7538bc9eabbf7bf94f91510d3503943edc4", size = 7158911 }, + { url = "https://files.pythonhosted.org/packages/a2/2f/16cabcc6426c32218ace36bf0d55955e813f2958afddbf1d391849fee9d1/pillow-12.0.0-cp314-cp314t-win32.whl", hash = "sha256:3830c769decf88f1289680a59d4f4c46c72573446352e2befec9a8512104fa52", size = 6408045 }, + { url = "https://files.pythonhosted.org/packages/35/73/e29aa0c9c666cf787628d3f0dcf379f4791fba79f4936d02f8b37165bdf8/pillow-12.0.0-cp314-cp314t-win_amd64.whl", hash = "sha256:905b0365b210c73afb0ebe9101a32572152dfd1c144c7e28968a331b9217b94a", size = 7148282 }, + { url = "https://files.pythonhosted.org/packages/c1/70/6b41bdcddf541b437bbb9f47f94d2db5d9ddef6c37ccab8c9107743748a4/pillow-12.0.0-cp314-cp314t-win_arm64.whl", hash = "sha256:99353a06902c2e43b43e8ff74ee65a7d90307d82370604746738a1e0661ccca7", size = 2525630 }, ] [[package]] name = "pluggy" version = "1.6.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/f9/e2/3e91f31a7d2b083fe6ef3fa267035b518369d9511ffab804f839851d2779/pluggy-1.6.0.tar.gz", hash = "sha256:7dcc130b76258d33b90f61b658791dede3486c3e6bfb003ee5c9bfb396dd22f3", size = 69412, upload-time = "2025-05-15T12:30:07.975Z" } +sdist = { url = "https://files.pythonhosted.org/packages/f9/e2/3e91f31a7d2b083fe6ef3fa267035b518369d9511ffab804f839851d2779/pluggy-1.6.0.tar.gz", hash = "sha256:7dcc130b76258d33b90f61b658791dede3486c3e6bfb003ee5c9bfb396dd22f3", size = 69412 } wheels = [ - { url = "https://files.pythonhosted.org/packages/54/20/4d324d65cc6d9205fabedc306948156824eb9f0ee1633355a8f7ec5c66bf/pluggy-1.6.0-py3-none-any.whl", hash = "sha256:e920276dd6813095e9377c0bc5566d94c932c33b27a3e3945d8389c374dd4746", size = 20538, upload-time = "2025-05-15T12:30:06.134Z" }, + { url = "https://files.pythonhosted.org/packages/54/20/4d324d65cc6d9205fabedc306948156824eb9f0ee1633355a8f7ec5c66bf/pluggy-1.6.0-py3-none-any.whl", hash = "sha256:e920276dd6813095e9377c0bc5566d94c932c33b27a3e3945d8389c374dd4746", size = 20538 }, ] [[package]] @@ -1318,36 +1327,36 @@ source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "protobuf" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/f4/ac/87285f15f7cce6d4a008f33f1757fb5a13611ea8914eb58c3d0d26243468/proto_plus-1.26.1.tar.gz", hash = "sha256:21a515a4c4c0088a773899e23c7bbade3d18f9c66c73edd4c7ee3816bc96a012", size = 56142, upload-time = "2025-03-10T15:54:38.843Z" } +sdist = { url = "https://files.pythonhosted.org/packages/f4/ac/87285f15f7cce6d4a008f33f1757fb5a13611ea8914eb58c3d0d26243468/proto_plus-1.26.1.tar.gz", hash = "sha256:21a515a4c4c0088a773899e23c7bbade3d18f9c66c73edd4c7ee3816bc96a012", size = 56142 } wheels = [ - { url = "https://files.pythonhosted.org/packages/4e/6d/280c4c2ce28b1593a19ad5239c8b826871fc6ec275c21afc8e1820108039/proto_plus-1.26.1-py3-none-any.whl", hash = "sha256:13285478c2dcf2abb829db158e1047e2f1e8d63a077d94263c2b88b043c75a66", size = 50163, upload-time = "2025-03-10T15:54:37.335Z" }, + { url = "https://files.pythonhosted.org/packages/4e/6d/280c4c2ce28b1593a19ad5239c8b826871fc6ec275c21afc8e1820108039/proto_plus-1.26.1-py3-none-any.whl", hash = "sha256:13285478c2dcf2abb829db158e1047e2f1e8d63a077d94263c2b88b043c75a66", size = 50163 }, ] [[package]] name = "protobuf" version = "6.33.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/19/ff/64a6c8f420818bb873713988ca5492cba3a7946be57e027ac63495157d97/protobuf-6.33.0.tar.gz", hash = "sha256:140303d5c8d2037730c548f8c7b93b20bb1dc301be280c378b82b8894589c954", size = 443463, upload-time = "2025-10-15T20:39:52.159Z" } +sdist = { url = "https://files.pythonhosted.org/packages/19/ff/64a6c8f420818bb873713988ca5492cba3a7946be57e027ac63495157d97/protobuf-6.33.0.tar.gz", hash = "sha256:140303d5c8d2037730c548f8c7b93b20bb1dc301be280c378b82b8894589c954", size = 443463 } wheels = [ - { url = "https://files.pythonhosted.org/packages/7e/ee/52b3fa8feb6db4a833dfea4943e175ce645144532e8a90f72571ad85df4e/protobuf-6.33.0-cp310-abi3-win32.whl", hash = "sha256:d6101ded078042a8f17959eccd9236fb7a9ca20d3b0098bbcb91533a5680d035", size = 425593, upload-time = "2025-10-15T20:39:40.29Z" }, - { url = "https://files.pythonhosted.org/packages/7b/c6/7a465f1825872c55e0341ff4a80198743f73b69ce5d43ab18043699d1d81/protobuf-6.33.0-cp310-abi3-win_amd64.whl", hash = "sha256:9a031d10f703f03768f2743a1c403af050b6ae1f3480e9c140f39c45f81b13ee", size = 436882, upload-time = "2025-10-15T20:39:42.841Z" }, - { url = "https://files.pythonhosted.org/packages/e1/a9/b6eee662a6951b9c3640e8e452ab3e09f117d99fc10baa32d1581a0d4099/protobuf-6.33.0-cp39-abi3-macosx_10_9_universal2.whl", hash = "sha256:905b07a65f1a4b72412314082c7dbfae91a9e8b68a0cc1577515f8df58ecf455", size = 427521, upload-time = "2025-10-15T20:39:43.803Z" }, - { url = "https://files.pythonhosted.org/packages/10/35/16d31e0f92c6d2f0e77c2a3ba93185130ea13053dd16200a57434c882f2b/protobuf-6.33.0-cp39-abi3-manylinux2014_aarch64.whl", hash = "sha256:e0697ece353e6239b90ee43a9231318302ad8353c70e6e45499fa52396debf90", size = 324445, upload-time = "2025-10-15T20:39:44.932Z" }, - { url = "https://files.pythonhosted.org/packages/e6/eb/2a981a13e35cda8b75b5585aaffae2eb904f8f351bdd3870769692acbd8a/protobuf-6.33.0-cp39-abi3-manylinux2014_s390x.whl", hash = "sha256:e0a1715e4f27355afd9570f3ea369735afc853a6c3951a6afe1f80d8569ad298", size = 339159, upload-time = "2025-10-15T20:39:46.186Z" }, - { url = "https://files.pythonhosted.org/packages/21/51/0b1cbad62074439b867b4e04cc09b93f6699d78fd191bed2bbb44562e077/protobuf-6.33.0-cp39-abi3-manylinux2014_x86_64.whl", hash = "sha256:35be49fd3f4fefa4e6e2aacc35e8b837d6703c37a2168a55ac21e9b1bc7559ef", size = 323172, upload-time = "2025-10-15T20:39:47.465Z" }, - { url = "https://files.pythonhosted.org/packages/07/d1/0a28c21707807c6aacd5dc9c3704b2aa1effbf37adebd8caeaf68b17a636/protobuf-6.33.0-py3-none-any.whl", hash = "sha256:25c9e1963c6734448ea2d308cfa610e692b801304ba0908d7bfa564ac5132995", size = 170477, upload-time = "2025-10-15T20:39:51.311Z" }, + { url = "https://files.pythonhosted.org/packages/7e/ee/52b3fa8feb6db4a833dfea4943e175ce645144532e8a90f72571ad85df4e/protobuf-6.33.0-cp310-abi3-win32.whl", hash = "sha256:d6101ded078042a8f17959eccd9236fb7a9ca20d3b0098bbcb91533a5680d035", size = 425593 }, + { url = "https://files.pythonhosted.org/packages/7b/c6/7a465f1825872c55e0341ff4a80198743f73b69ce5d43ab18043699d1d81/protobuf-6.33.0-cp310-abi3-win_amd64.whl", hash = "sha256:9a031d10f703f03768f2743a1c403af050b6ae1f3480e9c140f39c45f81b13ee", size = 436882 }, + { url = "https://files.pythonhosted.org/packages/e1/a9/b6eee662a6951b9c3640e8e452ab3e09f117d99fc10baa32d1581a0d4099/protobuf-6.33.0-cp39-abi3-macosx_10_9_universal2.whl", hash = "sha256:905b07a65f1a4b72412314082c7dbfae91a9e8b68a0cc1577515f8df58ecf455", size = 427521 }, + { url = "https://files.pythonhosted.org/packages/10/35/16d31e0f92c6d2f0e77c2a3ba93185130ea13053dd16200a57434c882f2b/protobuf-6.33.0-cp39-abi3-manylinux2014_aarch64.whl", hash = "sha256:e0697ece353e6239b90ee43a9231318302ad8353c70e6e45499fa52396debf90", size = 324445 }, + { url = "https://files.pythonhosted.org/packages/e6/eb/2a981a13e35cda8b75b5585aaffae2eb904f8f351bdd3870769692acbd8a/protobuf-6.33.0-cp39-abi3-manylinux2014_s390x.whl", hash = "sha256:e0a1715e4f27355afd9570f3ea369735afc853a6c3951a6afe1f80d8569ad298", size = 339159 }, + { url = "https://files.pythonhosted.org/packages/21/51/0b1cbad62074439b867b4e04cc09b93f6699d78fd191bed2bbb44562e077/protobuf-6.33.0-cp39-abi3-manylinux2014_x86_64.whl", hash = "sha256:35be49fd3f4fefa4e6e2aacc35e8b837d6703c37a2168a55ac21e9b1bc7559ef", size = 323172 }, + { url = "https://files.pythonhosted.org/packages/07/d1/0a28c21707807c6aacd5dc9c3704b2aa1effbf37adebd8caeaf68b17a636/protobuf-6.33.0-py3-none-any.whl", hash = "sha256:25c9e1963c6734448ea2d308cfa610e692b801304ba0908d7bfa564ac5132995", size = 170477 }, ] [[package]] name = "psycopg" -version = "3.2.11" +version = "3.2.12" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "tzdata", marker = "sys_platform == 'win32'" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/27/02/9fdfc018c026df2bcf9c11480c1014f9b90c6d801e5f929408cbfbf94cc0/psycopg-3.2.11.tar.gz", hash = "sha256:398bb484ed44361e041c8f804ed7af3d2fcefbffdace1d905b7446c319321706", size = 160644, upload-time = "2025-10-18T22:48:28.136Z" } +sdist = { url = "https://files.pythonhosted.org/packages/a8/77/c72d10262b872617e509a0c60445afcc4ce2cd5cd6bc1c97700246d69c85/psycopg-3.2.12.tar.gz", hash = "sha256:85c08d6f6e2a897b16280e0ff6406bef29b1327c045db06d21f364d7cd5da90b", size = 160642 } wheels = [ - { url = "https://files.pythonhosted.org/packages/aa/1b/96ee90ed0007d64936d9bd1bb3108d0af3cf762b4f11dbd73359f0687c3d/psycopg-3.2.11-py3-none-any.whl", hash = "sha256:217231b2b6b72fba88281b94241b2f16043ee67f81def47c52a01b72ff0c086a", size = 206766, upload-time = "2025-10-18T22:43:32.114Z" }, + { url = "https://files.pythonhosted.org/packages/c8/28/8c4f90e415411dc9c78d6ba10b549baa324659907c13f64bfe3779d4066c/psycopg-3.2.12-py3-none-any.whl", hash = "sha256:8a1611a2d4c16ae37eada46438be9029a35bb959bb50b3d0e1e93c0f3d54c9ee", size = 206765 }, ] [package.optional-dependencies] @@ -1357,36 +1366,36 @@ binary = [ [[package]] name = "psycopg-binary" -version = "3.2.11" -source = { registry = "https://pypi.org/simple" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/f2/93/9cea78ed3b279909f0fd6c2badb24b2361b93c875d6a7c921e26f6254044/psycopg_binary-3.2.11-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:47f6cf8a1d02d25238bdb8741ac641ff0ec22b1c6ff6a2acd057d0da5c712842", size = 4017939, upload-time = "2025-10-18T22:45:45.114Z" }, - { url = "https://files.pythonhosted.org/packages/58/86/fc9925f500b2c140c0bb8c1f8fcd04f8c45c76d4852e87baf4c75182de8c/psycopg_binary-3.2.11-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:91268f04380964a5e767f8102d05f1e23312ddbe848de1a9514b08b3fc57d354", size = 4090150, upload-time = "2025-10-18T22:45:50.214Z" }, - { url = "https://files.pythonhosted.org/packages/4e/10/752b698da1ca9e6c5f15d8798cb637c3615315fd2da17eee4a90cf20ee08/psycopg_binary-3.2.11-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:199f88a05dd22133eab2deb30348ef7a70c23d706c8e63fdc904234163c63517", size = 4625597, upload-time = "2025-10-18T22:45:54.638Z" }, - { url = "https://files.pythonhosted.org/packages/0a/9f/b578545c3c23484f4e234282d97ab24632a1d3cbfec64209786872e7cc8f/psycopg_binary-3.2.11-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:7b3c5474dbad63bcccb8d14d4d4c7c19f1dc6f8e8c1914cbc771d261cf8eddca", size = 4720326, upload-time = "2025-10-18T22:45:59.266Z" }, - { url = "https://files.pythonhosted.org/packages/43/3b/ba548d3fe65a7d4c96e568c2188e4b665802e3cba41664945ed95d16eae9/psycopg_binary-3.2.11-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:581358e770a4536e546841b78fd0fe318added4a82443bf22d0bbe3109cf9582", size = 4411647, upload-time = "2025-10-18T22:46:04.009Z" }, - { url = "https://files.pythonhosted.org/packages/26/65/559ab485b198600e7ff70d70786ae5c89d63475ca01d43a7dda0d7c91386/psycopg_binary-3.2.11-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:54a30f00a51b9043048b3e7ee806ffd31fc5fbd02a20f0e69d21306ff33dc473", size = 3863037, upload-time = "2025-10-18T22:46:08.469Z" }, - { url = "https://files.pythonhosted.org/packages/8c/29/05d0b48c8bef147e8216a36a1263a309a6240dcc09a56f5b8174fa6216d2/psycopg_binary-3.2.11-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:2a438fad4cc081b018431fde0e791b6d50201526edf39522a85164f606c39ddb", size = 3536975, upload-time = "2025-10-18T22:46:12.982Z" }, - { url = "https://files.pythonhosted.org/packages/d4/75/304e133d3ab1a49602616192edb81f603ed574f79966449105f2e200999d/psycopg_binary-3.2.11-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:f5e7415b5d0f58edf2708842c66605092df67f3821161d861b09695fc326c4de", size = 3586213, upload-time = "2025-10-18T22:46:19.523Z" }, - { url = "https://files.pythonhosted.org/packages/c0/10/c47cce42fa3c37d439e1400eaa5eeb2ce53dc3abc84d52c8a8a9e544d945/psycopg_binary-3.2.11-cp313-cp313-win_amd64.whl", hash = "sha256:6b9632c42f76d5349e7dd50025cff02688eb760b258e891ad2c6428e7e4917d5", size = 2912997, upload-time = "2025-10-18T22:46:24.978Z" }, - { url = "https://files.pythonhosted.org/packages/85/13/728b4763ef76a688737acebfcb5ab8696b024adc49a69c86081392b0e5ba/psycopg_binary-3.2.11-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:260738ae222b41dbefd0d84cb2e150a112f90b41688630f57fdac487ab6d6f38", size = 4016962, upload-time = "2025-10-18T22:46:29.207Z" }, - { url = "https://files.pythonhosted.org/packages/9f/0f/6180149621a907c5b60a2fae87d6ee10cc13e8c9f58d8250c310634ced04/psycopg_binary-3.2.11-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:c594c199869099c59c85b9f4423370b6212491fb929e7fcda0da1768761a2c2c", size = 4090614, upload-time = "2025-10-18T22:46:33.073Z" }, - { url = "https://files.pythonhosted.org/packages/f8/97/cce19bdef510b698c9036d5573b941b539ffcaa7602450da559c8a62e0c3/psycopg_binary-3.2.11-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:5768a9e7d393b2edd3a28de5a6d5850d054a016ed711f7044a9072f19f5e50d5", size = 4629749, upload-time = "2025-10-18T22:46:37.415Z" }, - { url = "https://files.pythonhosted.org/packages/93/9d/9bff18989fb2bf05d18c1431dd8bec4a1d90141beb11fc45d3269947ddf3/psycopg_binary-3.2.11-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:27eb6367350b75fef882c40cd6f748bfd976db2f8651f7511956f11efc15154f", size = 4724035, upload-time = "2025-10-18T22:46:42.568Z" }, - { url = "https://files.pythonhosted.org/packages/08/e5/39b930323428596990367b7953197730213d3d9d07bcedcad1d026608178/psycopg_binary-3.2.11-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:fa2aa5094dc962967ca0978c035b3ef90329b802501ef12a088d3bac6a55598e", size = 4411419, upload-time = "2025-10-18T22:46:47.745Z" }, - { url = "https://files.pythonhosted.org/packages/9a/9c/97c25438d1e51ddc6a7f67990b4c59f94bc515114ada864804ccee27ef1b/psycopg_binary-3.2.11-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:7744b4ed1f3b76fe37de7e9ef98014482fe74b6d3dfe1026cc4cfb4b4404e74f", size = 3867844, upload-time = "2025-10-18T22:46:53.328Z" }, - { url = "https://files.pythonhosted.org/packages/91/51/8c1e291cf4aa9982666f71a886aa782d990aa16853a42de545a0a9a871ef/psycopg_binary-3.2.11-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:5f6f948ff1cd252003ff534d7b50a2b25453b4212b283a7514ff8751bdb68c37", size = 3541539, upload-time = "2025-10-18T22:46:58.993Z" }, - { url = "https://files.pythonhosted.org/packages/57/0a/e25edcdfa1111bfc5c95668b7469b5a957b40ce10cc81383688d65564826/psycopg_binary-3.2.11-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:3bd2c8fb1dec6f93383fbaa561591fa3d676e079f9cb9889af17c3020a19715f", size = 3588090, upload-time = "2025-10-18T22:47:04.105Z" }, - { url = "https://files.pythonhosted.org/packages/a3/aa/f8c2f4b4c13d5680a20e5bfcd61f9e154bce26e7a2c70cb0abeade088d61/psycopg_binary-3.2.11-cp314-cp314-win_amd64.whl", hash = "sha256:c45f61202e5691090a697e599997eaffa3ec298209743caa4fd346145acabafe", size = 3006049, upload-time = "2025-10-18T22:47:07.923Z" }, +version = "3.2.12" +source = { registry = "https://pypi.org/simple" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/b2/0b/9d480aba4a4864832c29e6fc94ddd34d9927c276448eb3b56ffe24ed064c/psycopg_binary-3.2.12-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:442f20153415f374ae5753ca618637611a41a3c58c56d16ce55f845d76a3cf7b", size = 4017829 }, + { url = "https://files.pythonhosted.org/packages/a4/f3/0d294b30349bde24a46741a1f27a10e8ab81e9f4118d27c2fe592acfb42a/psycopg_binary-3.2.12-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:79de3cc5adbf51677009a8fda35ac9e9e3686d5595ab4b0c43ec7099ece6aeb5", size = 4089835 }, + { url = "https://files.pythonhosted.org/packages/82/d4/ff82e318e5a55d6951b278d3af7b4c7c1b19344e3a3722b6613f156a38ea/psycopg_binary-3.2.12-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:095ccda59042a1239ac2fefe693a336cb5cecf8944a8d9e98b07f07e94e2b78d", size = 4625474 }, + { url = "https://files.pythonhosted.org/packages/b1/e8/2c9df6475a5ab6d614d516f4497c568d84f7d6c21d0e11444468c9786c9f/psycopg_binary-3.2.12-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:efab679a2c7d1bf7d0ec0e1ecb47fe764945eff75bb4321f2e699b30a12db9b3", size = 4720350 }, + { url = "https://files.pythonhosted.org/packages/74/f5/7aec81b0c41985dc006e2d5822486ad4b7c2a1a97a5a05e37dc2adaf1512/psycopg_binary-3.2.12-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:d369e79ad9647fc8217cbb51bbbf11f9a1ffca450be31d005340157ffe8e91b3", size = 4411621 }, + { url = "https://files.pythonhosted.org/packages/fc/15/d3cb41b8fa9d5f14320ab250545fbb66f9ddb481e448e618902672a806c0/psycopg_binary-3.2.12-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:eedc410f82007038030650aa58f620f9fe0009b9d6b04c3dc71cbd3bae5b2675", size = 3863081 }, + { url = "https://files.pythonhosted.org/packages/69/8a/72837664e63e3cd3aa145cedcf29e5c21257579739aba78ab7eb668f7d9c/psycopg_binary-3.2.12-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:f3bae4be7f6781bf6c9576eedcd5e1bb74468126fa6de991e47cdb1a8ea3a42a", size = 3537428 }, + { url = "https://files.pythonhosted.org/packages/cc/7e/1b78ae38e7d69e6d7fb1e2dcce101493f5fa429480bac3a68b876c9b1635/psycopg_binary-3.2.12-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:8ffe75fe6be902dadd439adf4228c98138a992088e073ede6dd34e7235f4e03e", size = 3585981 }, + { url = "https://files.pythonhosted.org/packages/a3/f8/245b4868b2dac46c3fb6383b425754ae55df1910c826d305ed414da03777/psycopg_binary-3.2.12-cp313-cp313-win_amd64.whl", hash = "sha256:2598d0e4f2f258da13df0560187b3f1dfc9b8688c46b9d90176360ae5212c3fc", size = 2912929 }, + { url = "https://files.pythonhosted.org/packages/5c/5b/76fbb40b981b73b285a00dccafc38cf67b7a9b3f7d4f2025dda7b896e7ef/psycopg_binary-3.2.12-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:dc68094e00a5a7e8c20de1d3a0d5e404a27f522e18f8eb62bbbc9f865c3c81ef", size = 4016868 }, + { url = "https://files.pythonhosted.org/packages/0e/08/8841ae3e2d1a3228e79eaaf5b7f991d15f0a231bb5031a114305b19724b1/psycopg_binary-3.2.12-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:2d55009eeddbef54c711093c986daaf361d2c4210aaa1ee905075a3b97a62441", size = 4090508 }, + { url = "https://files.pythonhosted.org/packages/05/de/a41f62230cf4095ae4547eceada218cf28c17e7f94376913c1c8dde9546f/psycopg_binary-3.2.12-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:66a031f22e4418016990446d3e38143826f03ad811b9f78f58e2afbc1d343f7a", size = 4629788 }, + { url = "https://files.pythonhosted.org/packages/45/19/529d92134eae44475f781a86d58cdf3edd0953e17c69762abf387a9f2636/psycopg_binary-3.2.12-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:58ed30d33c25d7dc8d2f06285e88493147c2a660cc94713e4b563a99efb80a1f", size = 4724124 }, + { url = "https://files.pythonhosted.org/packages/5c/f5/97344e87065f7c9713ce213a2cff7732936ec3af6622e4b2a88715a953f2/psycopg_binary-3.2.12-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:e0b5ccd03ca4749b8f66f38608ccbcb415cbd130d02de5eda80d042b83bee90e", size = 4411340 }, + { url = "https://files.pythonhosted.org/packages/b1/c2/34bce068f6bfb4c2e7bb1187bb64a3f3be254702b158c4ad05eacc0055cf/psycopg_binary-3.2.12-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:909de94de7dd4d6086098a5755562207114c9638ec42c52d84c8a440c45fe084", size = 3867815 }, + { url = "https://files.pythonhosted.org/packages/d1/a1/c647e01ab162e6bfa52380e23e486215e9d28ffd31e9cf3cb1e9ca59008b/psycopg_binary-3.2.12-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:7130effd0517881f3a852eff98729d51034128f0737f64f0d1c7ea8343d77bd7", size = 3541756 }, + { url = "https://files.pythonhosted.org/packages/6b/d0/795bdaa8c946a7b7126bf7ca8d4371eaaa613093e3ec341a0e50f52cbee2/psycopg_binary-3.2.12-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:89b3c5201ca616d69ca0c3c0003ca18f7170a679c445c7e386ebfb4f29aa738e", size = 3587950 }, + { url = "https://files.pythonhosted.org/packages/53/cf/10c3e95827a3ca8af332dfc471befec86e15a14dc83cee893c49a4910dad/psycopg_binary-3.2.12-cp314-cp314-win_amd64.whl", hash = "sha256:48a8e29f3e38fcf8d393b8fe460d83e39c107ad7e5e61cd3858a7569e0554a39", size = 3005787 }, ] [[package]] name = "pwdlib" version = "0.2.1" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/82/a0/9daed437a6226f632a25d98d65d60ba02bdafa920c90dcb6454c611ead6c/pwdlib-0.2.1.tar.gz", hash = "sha256:9a1d8a8fa09a2f7ebf208265e55d7d008103cbdc82b9e4902ffdd1ade91add5e", size = 11699, upload-time = "2024-08-19T06:48:59.58Z" } +sdist = { url = "https://files.pythonhosted.org/packages/82/a0/9daed437a6226f632a25d98d65d60ba02bdafa920c90dcb6454c611ead6c/pwdlib-0.2.1.tar.gz", hash = "sha256:9a1d8a8fa09a2f7ebf208265e55d7d008103cbdc82b9e4902ffdd1ade91add5e", size = 11699 } wheels = [ - { url = "https://files.pythonhosted.org/packages/01/f3/0dae5078a486f0fdf4d4a1121e103bc42694a9da9bea7b0f2c63f29cfbd3/pwdlib-0.2.1-py3-none-any.whl", hash = "sha256:1823dc6f22eae472b540e889ecf57fd424051d6a4023ec0bcf7f0de2d9d7ef8c", size = 8082, upload-time = "2024-08-19T06:49:00.997Z" }, + { url = "https://files.pythonhosted.org/packages/01/f3/0dae5078a486f0fdf4d4a1121e103bc42694a9da9bea7b0f2c63f29cfbd3/pwdlib-0.2.1-py3-none-any.whl", hash = "sha256:1823dc6f22eae472b540e889ecf57fd424051d6a4023ec0bcf7f0de2d9d7ef8c", size = 8082 }, ] [package.optional-dependencies] @@ -1401,9 +1410,9 @@ bcrypt = [ name = "pyasn1" version = "0.6.1" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/ba/e9/01f1a64245b89f039897cb0130016d79f77d52669aae6ee7b159a6c4c018/pyasn1-0.6.1.tar.gz", hash = "sha256:6f580d2bdd84365380830acf45550f2511469f673cb4a5ae3857a3170128b034", size = 145322, upload-time = "2024-09-10T22:41:42.55Z" } +sdist = { url = "https://files.pythonhosted.org/packages/ba/e9/01f1a64245b89f039897cb0130016d79f77d52669aae6ee7b159a6c4c018/pyasn1-0.6.1.tar.gz", hash = "sha256:6f580d2bdd84365380830acf45550f2511469f673cb4a5ae3857a3170128b034", size = 145322 } wheels = [ - { url = "https://files.pythonhosted.org/packages/c8/f1/d6a797abb14f6283c0ddff96bbdd46937f64122b8c925cab503dd37f8214/pyasn1-0.6.1-py3-none-any.whl", hash = "sha256:0d632f46f2ba09143da3a8afe9e33fb6f92fa2320ab7e886e2d0f7672af84629", size = 83135, upload-time = "2024-09-11T16:00:36.122Z" }, + { url = "https://files.pythonhosted.org/packages/c8/f1/d6a797abb14f6283c0ddff96bbdd46937f64122b8c925cab503dd37f8214/pyasn1-0.6.1-py3-none-any.whl", hash = "sha256:0d632f46f2ba09143da3a8afe9e33fb6f92fa2320ab7e886e2d0f7672af84629", size = 83135 }, ] [[package]] @@ -1413,18 +1422,18 @@ source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "pyasn1" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/e9/e6/78ebbb10a8c8e4b61a59249394a4a594c1a7af95593dc933a349c8d00964/pyasn1_modules-0.4.2.tar.gz", hash = "sha256:677091de870a80aae844b1ca6134f54652fa2c8c5a52aa396440ac3106e941e6", size = 307892, upload-time = "2025-03-28T02:41:22.17Z" } +sdist = { url = "https://files.pythonhosted.org/packages/e9/e6/78ebbb10a8c8e4b61a59249394a4a594c1a7af95593dc933a349c8d00964/pyasn1_modules-0.4.2.tar.gz", hash = "sha256:677091de870a80aae844b1ca6134f54652fa2c8c5a52aa396440ac3106e941e6", size = 307892 } wheels = [ - { url = "https://files.pythonhosted.org/packages/47/8d/d529b5d697919ba8c11ad626e835d4039be708a35b0d22de83a269a6682c/pyasn1_modules-0.4.2-py3-none-any.whl", hash = "sha256:29253a9207ce32b64c3ac6600edc75368f98473906e8fd1043bd6b5b1de2c14a", size = 181259, upload-time = "2025-03-28T02:41:19.028Z" }, + { url = "https://files.pythonhosted.org/packages/47/8d/d529b5d697919ba8c11ad626e835d4039be708a35b0d22de83a269a6682c/pyasn1_modules-0.4.2-py3-none-any.whl", hash = "sha256:29253a9207ce32b64c3ac6600edc75368f98473906e8fd1043bd6b5b1de2c14a", size = 181259 }, ] [[package]] name = "pycparser" version = "2.23" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/fe/cf/d2d3b9f5699fb1e4615c8e32ff220203e43b248e1dfcc6736ad9057731ca/pycparser-2.23.tar.gz", hash = "sha256:78816d4f24add8f10a06d6f05b4d424ad9e96cfebf68a4ddc99c65c0720d00c2", size = 173734, upload-time = "2025-09-09T13:23:47.91Z" } +sdist = { url = "https://files.pythonhosted.org/packages/fe/cf/d2d3b9f5699fb1e4615c8e32ff220203e43b248e1dfcc6736ad9057731ca/pycparser-2.23.tar.gz", hash = "sha256:78816d4f24add8f10a06d6f05b4d424ad9e96cfebf68a4ddc99c65c0720d00c2", size = 173734 } wheels = [ - { url = "https://files.pythonhosted.org/packages/a0/e3/59cd50310fc9b59512193629e1984c1f95e5c8ae6e5d8c69532ccc65a7fe/pycparser-2.23-py3-none-any.whl", hash = "sha256:e5c6e8d3fbad53479cab09ac03729e0a9faf2bee3db8208a550daf5af81a5934", size = 118140, upload-time = "2025-09-09T13:23:46.651Z" }, + { url = "https://files.pythonhosted.org/packages/a0/e3/59cd50310fc9b59512193629e1984c1f95e5c8ae6e5d8c69532ccc65a7fe/pycparser-2.23-py3-none-any.whl", hash = "sha256:e5c6e8d3fbad53479cab09ac03729e0a9faf2bee3db8208a550daf5af81a5934", size = 118140 }, ] [[package]] @@ -1437,9 +1446,9 @@ dependencies = [ { name = "typing-extensions" }, { name = "typing-inspection" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/ae/54/ecab642b3bed45f7d5f59b38443dcb36ef50f85af192e6ece103dbfe9587/pydantic-2.11.10.tar.gz", hash = "sha256:dc280f0982fbda6c38fada4e476dc0a4f3aeaf9c6ad4c28df68a666ec3c61423", size = 788494, upload-time = "2025-10-04T10:40:41.338Z" } +sdist = { url = "https://files.pythonhosted.org/packages/ae/54/ecab642b3bed45f7d5f59b38443dcb36ef50f85af192e6ece103dbfe9587/pydantic-2.11.10.tar.gz", hash = "sha256:dc280f0982fbda6c38fada4e476dc0a4f3aeaf9c6ad4c28df68a666ec3c61423", size = 788494 } wheels = [ - { url = "https://files.pythonhosted.org/packages/bd/1f/73c53fcbfb0b5a78f91176df41945ca466e71e9d9d836e5c522abda39ee7/pydantic-2.11.10-py3-none-any.whl", hash = "sha256:802a655709d49bd004c31e865ef37da30b540786a46bfce02333e0e24b5fe29a", size = 444823, upload-time = "2025-10-04T10:40:39.055Z" }, + { url = "https://files.pythonhosted.org/packages/bd/1f/73c53fcbfb0b5a78f91176df41945ca466e71e9d9d836e5c522abda39ee7/pydantic-2.11.10-py3-none-any.whl", hash = "sha256:802a655709d49bd004c31e865ef37da30b540786a46bfce02333e0e24b5fe29a", size = 444823 }, ] [package.optional-dependencies] @@ -1454,25 +1463,25 @@ source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "typing-extensions" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/ad/88/5f2260bdfae97aabf98f1778d43f69574390ad787afb646292a638c923d4/pydantic_core-2.33.2.tar.gz", hash = "sha256:7cb8bc3605c29176e1b105350d2e6474142d7c1bd1d9327c4a9bdb46bf827acc", size = 435195, upload-time = "2025-04-23T18:33:52.104Z" } +sdist = { url = "https://files.pythonhosted.org/packages/ad/88/5f2260bdfae97aabf98f1778d43f69574390ad787afb646292a638c923d4/pydantic_core-2.33.2.tar.gz", hash = "sha256:7cb8bc3605c29176e1b105350d2e6474142d7c1bd1d9327c4a9bdb46bf827acc", size = 435195 } wheels = [ - { url = "https://files.pythonhosted.org/packages/46/8c/99040727b41f56616573a28771b1bfa08a3d3fe74d3d513f01251f79f172/pydantic_core-2.33.2-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:1082dd3e2d7109ad8b7da48e1d4710c8d06c253cbc4a27c1cff4fbcaa97a9e3f", size = 2015688, upload-time = "2025-04-23T18:31:53.175Z" }, - { url = "https://files.pythonhosted.org/packages/3a/cc/5999d1eb705a6cefc31f0b4a90e9f7fc400539b1a1030529700cc1b51838/pydantic_core-2.33.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:f517ca031dfc037a9c07e748cefd8d96235088b83b4f4ba8939105d20fa1dcd6", size = 1844808, upload-time = "2025-04-23T18:31:54.79Z" }, - { url = "https://files.pythonhosted.org/packages/6f/5e/a0a7b8885c98889a18b6e376f344da1ef323d270b44edf8174d6bce4d622/pydantic_core-2.33.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0a9f2c9dd19656823cb8250b0724ee9c60a82f3cdf68a080979d13092a3b0fef", size = 1885580, upload-time = "2025-04-23T18:31:57.393Z" }, - { url = "https://files.pythonhosted.org/packages/3b/2a/953581f343c7d11a304581156618c3f592435523dd9d79865903272c256a/pydantic_core-2.33.2-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:2b0a451c263b01acebe51895bfb0e1cc842a5c666efe06cdf13846c7418caa9a", size = 1973859, upload-time = "2025-04-23T18:31:59.065Z" }, - { url = "https://files.pythonhosted.org/packages/e6/55/f1a813904771c03a3f97f676c62cca0c0a4138654107c1b61f19c644868b/pydantic_core-2.33.2-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1ea40a64d23faa25e62a70ad163571c0b342b8bf66d5fa612ac0dec4f069d916", size = 2120810, upload-time = "2025-04-23T18:32:00.78Z" }, - { url = "https://files.pythonhosted.org/packages/aa/c3/053389835a996e18853ba107a63caae0b9deb4a276c6b472931ea9ae6e48/pydantic_core-2.33.2-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:0fb2d542b4d66f9470e8065c5469ec676978d625a8b7a363f07d9a501a9cb36a", size = 2676498, upload-time = "2025-04-23T18:32:02.418Z" }, - { url = "https://files.pythonhosted.org/packages/eb/3c/f4abd740877a35abade05e437245b192f9d0ffb48bbbbd708df33d3cda37/pydantic_core-2.33.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9fdac5d6ffa1b5a83bca06ffe7583f5576555e6c8b3a91fbd25ea7780f825f7d", size = 2000611, upload-time = "2025-04-23T18:32:04.152Z" }, - { url = "https://files.pythonhosted.org/packages/59/a7/63ef2fed1837d1121a894d0ce88439fe3e3b3e48c7543b2a4479eb99c2bd/pydantic_core-2.33.2-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:04a1a413977ab517154eebb2d326da71638271477d6ad87a769102f7c2488c56", size = 2107924, upload-time = "2025-04-23T18:32:06.129Z" }, - { url = "https://files.pythonhosted.org/packages/04/8f/2551964ef045669801675f1cfc3b0d74147f4901c3ffa42be2ddb1f0efc4/pydantic_core-2.33.2-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:c8e7af2f4e0194c22b5b37205bfb293d166a7344a5b0d0eaccebc376546d77d5", size = 2063196, upload-time = "2025-04-23T18:32:08.178Z" }, - { url = "https://files.pythonhosted.org/packages/26/bd/d9602777e77fc6dbb0c7db9ad356e9a985825547dce5ad1d30ee04903918/pydantic_core-2.33.2-cp313-cp313-musllinux_1_1_armv7l.whl", hash = "sha256:5c92edd15cd58b3c2d34873597a1e20f13094f59cf88068adb18947df5455b4e", size = 2236389, upload-time = "2025-04-23T18:32:10.242Z" }, - { url = "https://files.pythonhosted.org/packages/42/db/0e950daa7e2230423ab342ae918a794964b053bec24ba8af013fc7c94846/pydantic_core-2.33.2-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:65132b7b4a1c0beded5e057324b7e16e10910c106d43675d9bd87d4f38dde162", size = 2239223, upload-time = "2025-04-23T18:32:12.382Z" }, - { url = "https://files.pythonhosted.org/packages/58/4d/4f937099c545a8a17eb52cb67fe0447fd9a373b348ccfa9a87f141eeb00f/pydantic_core-2.33.2-cp313-cp313-win32.whl", hash = "sha256:52fb90784e0a242bb96ec53f42196a17278855b0f31ac7c3cc6f5c1ec4811849", size = 1900473, upload-time = "2025-04-23T18:32:14.034Z" }, - { url = "https://files.pythonhosted.org/packages/a0/75/4a0a9bac998d78d889def5e4ef2b065acba8cae8c93696906c3a91f310ca/pydantic_core-2.33.2-cp313-cp313-win_amd64.whl", hash = "sha256:c083a3bdd5a93dfe480f1125926afcdbf2917ae714bdb80b36d34318b2bec5d9", size = 1955269, upload-time = "2025-04-23T18:32:15.783Z" }, - { url = "https://files.pythonhosted.org/packages/f9/86/1beda0576969592f1497b4ce8e7bc8cbdf614c352426271b1b10d5f0aa64/pydantic_core-2.33.2-cp313-cp313-win_arm64.whl", hash = "sha256:e80b087132752f6b3d714f041ccf74403799d3b23a72722ea2e6ba2e892555b9", size = 1893921, upload-time = "2025-04-23T18:32:18.473Z" }, - { url = "https://files.pythonhosted.org/packages/a4/7d/e09391c2eebeab681df2b74bfe6c43422fffede8dc74187b2b0bf6fd7571/pydantic_core-2.33.2-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:61c18fba8e5e9db3ab908620af374db0ac1baa69f0f32df4f61ae23f15e586ac", size = 1806162, upload-time = "2025-04-23T18:32:20.188Z" }, - { url = "https://files.pythonhosted.org/packages/f1/3d/847b6b1fed9f8ed3bb95a9ad04fbd0b212e832d4f0f50ff4d9ee5a9f15cf/pydantic_core-2.33.2-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:95237e53bb015f67b63c91af7518a62a8660376a6a0db19b89acc77a4d6199f5", size = 1981560, upload-time = "2025-04-23T18:32:22.354Z" }, - { url = "https://files.pythonhosted.org/packages/6f/9a/e73262f6c6656262b5fdd723ad90f518f579b7bc8622e43a942eec53c938/pydantic_core-2.33.2-cp313-cp313t-win_amd64.whl", hash = "sha256:c2fc0a768ef76c15ab9238afa6da7f69895bb5d1ee83aeea2e3509af4472d0b9", size = 1935777, upload-time = "2025-04-23T18:32:25.088Z" }, + { url = "https://files.pythonhosted.org/packages/46/8c/99040727b41f56616573a28771b1bfa08a3d3fe74d3d513f01251f79f172/pydantic_core-2.33.2-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:1082dd3e2d7109ad8b7da48e1d4710c8d06c253cbc4a27c1cff4fbcaa97a9e3f", size = 2015688 }, + { url = "https://files.pythonhosted.org/packages/3a/cc/5999d1eb705a6cefc31f0b4a90e9f7fc400539b1a1030529700cc1b51838/pydantic_core-2.33.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:f517ca031dfc037a9c07e748cefd8d96235088b83b4f4ba8939105d20fa1dcd6", size = 1844808 }, + { url = "https://files.pythonhosted.org/packages/6f/5e/a0a7b8885c98889a18b6e376f344da1ef323d270b44edf8174d6bce4d622/pydantic_core-2.33.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0a9f2c9dd19656823cb8250b0724ee9c60a82f3cdf68a080979d13092a3b0fef", size = 1885580 }, + { url = "https://files.pythonhosted.org/packages/3b/2a/953581f343c7d11a304581156618c3f592435523dd9d79865903272c256a/pydantic_core-2.33.2-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:2b0a451c263b01acebe51895bfb0e1cc842a5c666efe06cdf13846c7418caa9a", size = 1973859 }, + { url = "https://files.pythonhosted.org/packages/e6/55/f1a813904771c03a3f97f676c62cca0c0a4138654107c1b61f19c644868b/pydantic_core-2.33.2-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1ea40a64d23faa25e62a70ad163571c0b342b8bf66d5fa612ac0dec4f069d916", size = 2120810 }, + { url = "https://files.pythonhosted.org/packages/aa/c3/053389835a996e18853ba107a63caae0b9deb4a276c6b472931ea9ae6e48/pydantic_core-2.33.2-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:0fb2d542b4d66f9470e8065c5469ec676978d625a8b7a363f07d9a501a9cb36a", size = 2676498 }, + { url = "https://files.pythonhosted.org/packages/eb/3c/f4abd740877a35abade05e437245b192f9d0ffb48bbbbd708df33d3cda37/pydantic_core-2.33.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9fdac5d6ffa1b5a83bca06ffe7583f5576555e6c8b3a91fbd25ea7780f825f7d", size = 2000611 }, + { url = "https://files.pythonhosted.org/packages/59/a7/63ef2fed1837d1121a894d0ce88439fe3e3b3e48c7543b2a4479eb99c2bd/pydantic_core-2.33.2-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:04a1a413977ab517154eebb2d326da71638271477d6ad87a769102f7c2488c56", size = 2107924 }, + { url = "https://files.pythonhosted.org/packages/04/8f/2551964ef045669801675f1cfc3b0d74147f4901c3ffa42be2ddb1f0efc4/pydantic_core-2.33.2-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:c8e7af2f4e0194c22b5b37205bfb293d166a7344a5b0d0eaccebc376546d77d5", size = 2063196 }, + { url = "https://files.pythonhosted.org/packages/26/bd/d9602777e77fc6dbb0c7db9ad356e9a985825547dce5ad1d30ee04903918/pydantic_core-2.33.2-cp313-cp313-musllinux_1_1_armv7l.whl", hash = "sha256:5c92edd15cd58b3c2d34873597a1e20f13094f59cf88068adb18947df5455b4e", size = 2236389 }, + { url = "https://files.pythonhosted.org/packages/42/db/0e950daa7e2230423ab342ae918a794964b053bec24ba8af013fc7c94846/pydantic_core-2.33.2-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:65132b7b4a1c0beded5e057324b7e16e10910c106d43675d9bd87d4f38dde162", size = 2239223 }, + { url = "https://files.pythonhosted.org/packages/58/4d/4f937099c545a8a17eb52cb67fe0447fd9a373b348ccfa9a87f141eeb00f/pydantic_core-2.33.2-cp313-cp313-win32.whl", hash = "sha256:52fb90784e0a242bb96ec53f42196a17278855b0f31ac7c3cc6f5c1ec4811849", size = 1900473 }, + { url = "https://files.pythonhosted.org/packages/a0/75/4a0a9bac998d78d889def5e4ef2b065acba8cae8c93696906c3a91f310ca/pydantic_core-2.33.2-cp313-cp313-win_amd64.whl", hash = "sha256:c083a3bdd5a93dfe480f1125926afcdbf2917ae714bdb80b36d34318b2bec5d9", size = 1955269 }, + { url = "https://files.pythonhosted.org/packages/f9/86/1beda0576969592f1497b4ce8e7bc8cbdf614c352426271b1b10d5f0aa64/pydantic_core-2.33.2-cp313-cp313-win_arm64.whl", hash = "sha256:e80b087132752f6b3d714f041ccf74403799d3b23a72722ea2e6ba2e892555b9", size = 1893921 }, + { url = "https://files.pythonhosted.org/packages/a4/7d/e09391c2eebeab681df2b74bfe6c43422fffede8dc74187b2b0bf6fd7571/pydantic_core-2.33.2-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:61c18fba8e5e9db3ab908620af374db0ac1baa69f0f32df4f61ae23f15e586ac", size = 1806162 }, + { url = "https://files.pythonhosted.org/packages/f1/3d/847b6b1fed9f8ed3bb95a9ad04fbd0b212e832d4f0f50ff4d9ee5a9f15cf/pydantic_core-2.33.2-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:95237e53bb015f67b63c91af7518a62a8660376a6a0db19b89acc77a4d6199f5", size = 1981560 }, + { url = "https://files.pythonhosted.org/packages/6f/9a/e73262f6c6656262b5fdd723ad90f518f579b7bc8622e43a942eec53c938/pydantic_core-2.33.2-cp313-cp313t-win_amd64.whl", hash = "sha256:c2fc0a768ef76c15ab9238afa6da7f69895bb5d1ee83aeea2e3509af4472d0b9", size = 1935777 }, ] [[package]] @@ -1483,9 +1492,9 @@ dependencies = [ { name = "pydantic" }, { name = "typing-extensions" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/3a/10/fb64987804cde41bcc39d9cd757cd5f2bb5d97b389d81aa70238b14b8a7e/pydantic_extra_types-2.10.6.tar.gz", hash = "sha256:c63d70bf684366e6bbe1f4ee3957952ebe6973d41e7802aea0b770d06b116aeb", size = 141858, upload-time = "2025-10-08T13:47:49.483Z" } +sdist = { url = "https://files.pythonhosted.org/packages/3a/10/fb64987804cde41bcc39d9cd757cd5f2bb5d97b389d81aa70238b14b8a7e/pydantic_extra_types-2.10.6.tar.gz", hash = "sha256:c63d70bf684366e6bbe1f4ee3957952ebe6973d41e7802aea0b770d06b116aeb", size = 141858 } wheels = [ - { url = "https://files.pythonhosted.org/packages/93/04/5c918669096da8d1c9ec7bb716bd72e755526103a61bc5e76a3e4fb23b53/pydantic_extra_types-2.10.6-py3-none-any.whl", hash = "sha256:6106c448316d30abf721b5b9fecc65e983ef2614399a24142d689c7546cc246a", size = 40949, upload-time = "2025-10-08T13:47:48.268Z" }, + { url = "https://files.pythonhosted.org/packages/93/04/5c918669096da8d1c9ec7bb716bd72e755526103a61bc5e76a3e4fb23b53/pydantic_extra_types-2.10.6-py3-none-any.whl", hash = "sha256:6106c448316d30abf721b5b9fecc65e983ef2614399a24142d689c7546cc246a", size = 40949 }, ] [[package]] @@ -1497,9 +1506,9 @@ dependencies = [ { name = "python-dotenv" }, { name = "typing-inspection" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/20/c5/dbbc27b814c71676593d1c3f718e6cd7d4f00652cefa24b75f7aa3efb25e/pydantic_settings-2.11.0.tar.gz", hash = "sha256:d0e87a1c7d33593beb7194adb8470fc426e95ba02af83a0f23474a04c9a08180", size = 188394, upload-time = "2025-09-24T14:19:11.764Z" } +sdist = { url = "https://files.pythonhosted.org/packages/20/c5/dbbc27b814c71676593d1c3f718e6cd7d4f00652cefa24b75f7aa3efb25e/pydantic_settings-2.11.0.tar.gz", hash = "sha256:d0e87a1c7d33593beb7194adb8470fc426e95ba02af83a0f23474a04c9a08180", size = 188394 } wheels = [ - { url = "https://files.pythonhosted.org/packages/83/d6/887a1ff844e64aa823fb4905978d882a633cfe295c32eacad582b78a7d8b/pydantic_settings-2.11.0-py3-none-any.whl", hash = "sha256:fe2cea3413b9530d10f3a5875adffb17ada5c1e1bab0b2885546d7310415207c", size = 48608, upload-time = "2025-09-24T14:19:10.015Z" }, + { url = "https://files.pythonhosted.org/packages/83/d6/887a1ff844e64aa823fb4905978d882a633cfe295c32eacad582b78a7d8b/pydantic_settings-2.11.0-py3-none-any.whl", hash = "sha256:fe2cea3413b9530d10f3a5875adffb17ada5c1e1bab0b2885546d7310415207c", size = 48608 }, ] [[package]] @@ -1509,27 +1518,27 @@ source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "pyparsing" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/66/dd/e0e6a4fb84c22050f6a9701ad9fd6a67ef82faa7ba97b97eb6fdc6b49b34/pydot-3.0.4.tar.gz", hash = "sha256:3ce88b2558f3808b0376f22bfa6c263909e1c3981e2a7b629b65b451eee4a25d", size = 168167, upload-time = "2025-01-05T16:18:45.763Z" } +sdist = { url = "https://files.pythonhosted.org/packages/66/dd/e0e6a4fb84c22050f6a9701ad9fd6a67ef82faa7ba97b97eb6fdc6b49b34/pydot-3.0.4.tar.gz", hash = "sha256:3ce88b2558f3808b0376f22bfa6c263909e1c3981e2a7b629b65b451eee4a25d", size = 168167 } wheels = [ - { url = "https://files.pythonhosted.org/packages/b0/5f/1ebfd430df05c4f9e438dd3313c4456eab937d976f6ab8ce81a98f9fb381/pydot-3.0.4-py3-none-any.whl", hash = "sha256:bfa9c3fc0c44ba1d132adce131802d7df00429d1a79cc0346b0a5cd374dbe9c6", size = 35776, upload-time = "2025-01-05T16:18:42.836Z" }, + { url = "https://files.pythonhosted.org/packages/b0/5f/1ebfd430df05c4f9e438dd3313c4456eab937d976f6ab8ce81a98f9fb381/pydot-3.0.4-py3-none-any.whl", hash = "sha256:bfa9c3fc0c44ba1d132adce131802d7df00429d1a79cc0346b0a5cd374dbe9c6", size = 35776 }, ] [[package]] name = "pygments" version = "2.19.2" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/b0/77/a5b8c569bf593b0140bde72ea885a803b82086995367bf2037de0159d924/pygments-2.19.2.tar.gz", hash = "sha256:636cb2477cec7f8952536970bc533bc43743542f70392ae026374600add5b887", size = 4968631, upload-time = "2025-06-21T13:39:12.283Z" } +sdist = { url = "https://files.pythonhosted.org/packages/b0/77/a5b8c569bf593b0140bde72ea885a803b82086995367bf2037de0159d924/pygments-2.19.2.tar.gz", hash = "sha256:636cb2477cec7f8952536970bc533bc43743542f70392ae026374600add5b887", size = 4968631 } wheels = [ - { url = "https://files.pythonhosted.org/packages/c7/21/705964c7812476f378728bdf590ca4b771ec72385c533964653c68e86bdc/pygments-2.19.2-py3-none-any.whl", hash = "sha256:86540386c03d588bb81d44bc3928634ff26449851e99741617ecb9037ee5ec0b", size = 1225217, upload-time = "2025-06-21T13:39:07.939Z" }, + { url = "https://files.pythonhosted.org/packages/c7/21/705964c7812476f378728bdf590ca4b771ec72385c533964653c68e86bdc/pygments-2.19.2-py3-none-any.whl", hash = "sha256:86540386c03d588bb81d44bc3928634ff26449851e99741617ecb9037ee5ec0b", size = 1225217 }, ] [[package]] name = "pyjwt" version = "2.10.1" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/e7/46/bd74733ff231675599650d3e47f361794b22ef3e3770998dda30d3b63726/pyjwt-2.10.1.tar.gz", hash = "sha256:3cc5772eb20009233caf06e9d8a0577824723b44e6648ee0a2aedb6cf9381953", size = 87785, upload-time = "2024-11-28T03:43:29.933Z" } +sdist = { url = "https://files.pythonhosted.org/packages/e7/46/bd74733ff231675599650d3e47f361794b22ef3e3770998dda30d3b63726/pyjwt-2.10.1.tar.gz", hash = "sha256:3cc5772eb20009233caf06e9d8a0577824723b44e6648ee0a2aedb6cf9381953", size = 87785 } wheels = [ - { url = "https://files.pythonhosted.org/packages/61/ad/689f02752eeec26aed679477e80e632ef1b682313be70793d798c1d5fc8f/PyJWT-2.10.1-py3-none-any.whl", hash = "sha256:dcdd193e30abefd5debf142f9adfcdd2b58004e644f25406ffaebd50bd98dacb", size = 22997, upload-time = "2024-11-28T03:43:27.893Z" }, + { url = "https://files.pythonhosted.org/packages/61/ad/689f02752eeec26aed679477e80e632ef1b682313be70793d798c1d5fc8f/PyJWT-2.10.1-py3-none-any.whl", hash = "sha256:dcdd193e30abefd5debf142f9adfcdd2b58004e644f25406ffaebd50bd98dacb", size = 22997 }, ] [package.optional-dependencies] @@ -1541,31 +1550,31 @@ crypto = [ name = "pyparsing" version = "3.2.5" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/f2/a5/181488fc2b9d093e3972d2a472855aae8a03f000592dbfce716a512b3359/pyparsing-3.2.5.tar.gz", hash = "sha256:2df8d5b7b2802ef88e8d016a2eb9c7aeaa923529cd251ed0fe4608275d4105b6", size = 1099274, upload-time = "2025-09-21T04:11:06.277Z" } +sdist = { url = "https://files.pythonhosted.org/packages/f2/a5/181488fc2b9d093e3972d2a472855aae8a03f000592dbfce716a512b3359/pyparsing-3.2.5.tar.gz", hash = "sha256:2df8d5b7b2802ef88e8d016a2eb9c7aeaa923529cd251ed0fe4608275d4105b6", size = 1099274 } wheels = [ - { url = "https://files.pythonhosted.org/packages/10/5e/1aa9a93198c6b64513c9d7752de7422c06402de6600a8767da1524f9570b/pyparsing-3.2.5-py3-none-any.whl", hash = "sha256:e38a4f02064cf41fe6593d328d0512495ad1f3d8a91c4f73fc401b3079a59a5e", size = 113890, upload-time = "2025-09-21T04:11:04.117Z" }, + { url = "https://files.pythonhosted.org/packages/10/5e/1aa9a93198c6b64513c9d7752de7422c06402de6600a8767da1524f9570b/pyparsing-3.2.5-py3-none-any.whl", hash = "sha256:e38a4f02064cf41fe6593d328d0512495ad1f3d8a91c4f73fc401b3079a59a5e", size = 113890 }, ] [[package]] name = "pyreadline3" version = "3.5.4" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/0f/49/4cea918a08f02817aabae639e3d0ac046fef9f9180518a3ad394e22da148/pyreadline3-3.5.4.tar.gz", hash = "sha256:8d57d53039a1c75adba8e50dd3d992b28143480816187ea5efbd5c78e6c885b7", size = 99839, upload-time = "2024-09-19T02:40:10.062Z" } +sdist = { url = "https://files.pythonhosted.org/packages/0f/49/4cea918a08f02817aabae639e3d0ac046fef9f9180518a3ad394e22da148/pyreadline3-3.5.4.tar.gz", hash = "sha256:8d57d53039a1c75adba8e50dd3d992b28143480816187ea5efbd5c78e6c885b7", size = 99839 } wheels = [ - { url = "https://files.pythonhosted.org/packages/5a/dc/491b7661614ab97483abf2056be1deee4dc2490ecbf7bff9ab5cdbac86e1/pyreadline3-3.5.4-py3-none-any.whl", hash = "sha256:eaf8e6cc3c49bcccf145fc6067ba8643d1df34d604a1ec0eccbf7a18e6d3fae6", size = 83178, upload-time = "2024-09-19T02:40:08.598Z" }, + { url = "https://files.pythonhosted.org/packages/5a/dc/491b7661614ab97483abf2056be1deee4dc2490ecbf7bff9ab5cdbac86e1/pyreadline3-3.5.4-py3-none-any.whl", hash = "sha256:eaf8e6cc3c49bcccf145fc6067ba8643d1df34d604a1ec0eccbf7a18e6d3fae6", size = 83178 }, ] [[package]] name = "pyright" -version = "1.1.406" +version = "1.1.407" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "nodeenv" }, { name = "typing-extensions" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/f7/16/6b4fbdd1fef59a0292cbb99f790b44983e390321eccbc5921b4d161da5d1/pyright-1.1.406.tar.gz", hash = "sha256:c4872bc58c9643dac09e8a2e74d472c62036910b3bd37a32813989ef7576ea2c", size = 4113151, upload-time = "2025-10-02T01:04:45.488Z" } +sdist = { url = "https://files.pythonhosted.org/packages/a6/1b/0aa08ee42948b61745ac5b5b5ccaec4669e8884b53d31c8ec20b2fcd6b6f/pyright-1.1.407.tar.gz", hash = "sha256:099674dba5c10489832d4a4b2d302636152a9a42d317986c38474c76fe562262", size = 4122872 } wheels = [ - { url = "https://files.pythonhosted.org/packages/f6/a2/e309afbb459f50507103793aaef85ca4348b66814c86bc73908bdeb66d12/pyright-1.1.406-py3-none-any.whl", hash = "sha256:1d81fb43c2407bf566e97e57abb01c811973fdb21b2df8df59f870f688bdca71", size = 5980982, upload-time = "2025-10-02T01:04:43.137Z" }, + { url = "https://files.pythonhosted.org/packages/dc/93/b69052907d032b00c40cb656d21438ec00b3a471733de137a3f65a49a0a0/pyright-1.1.407-py3-none-any.whl", hash = "sha256:6dd419f54fcc13f03b52285796d65e639786373f433e243f8b94cf93a7444d21", size = 5997008 }, ] [[package]] @@ -1579,9 +1588,9 @@ dependencies = [ { name = "pluggy" }, { name = "pygments" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/a3/5c/00a0e072241553e1a7496d638deababa67c5058571567b92a7eaa258397c/pytest-8.4.2.tar.gz", hash = "sha256:86c0d0b93306b961d58d62a4db4879f27fe25513d4b969df351abdddb3c30e01", size = 1519618, upload-time = "2025-09-04T14:34:22.711Z" } +sdist = { url = "https://files.pythonhosted.org/packages/a3/5c/00a0e072241553e1a7496d638deababa67c5058571567b92a7eaa258397c/pytest-8.4.2.tar.gz", hash = "sha256:86c0d0b93306b961d58d62a4db4879f27fe25513d4b969df351abdddb3c30e01", size = 1519618 } wheels = [ - { url = "https://files.pythonhosted.org/packages/a8/a4/20da314d277121d6534b3a980b29035dcd51e6744bd79075a6ce8fa4eb8d/pytest-8.4.2-py3-none-any.whl", hash = "sha256:872f880de3fc3a5bdc88a11b39c9710c3497a547cfa9320bc3c5e62fbf272e79", size = 365750, upload-time = "2025-09-04T14:34:20.226Z" }, + { url = "https://files.pythonhosted.org/packages/a8/a4/20da314d277121d6534b3a980b29035dcd51e6744bd79075a6ce8fa4eb8d/pytest-8.4.2-py3-none-any.whl", hash = "sha256:872f880de3fc3a5bdc88a11b39c9710c3497a547cfa9320bc3c5e62fbf272e79", size = 365750 }, ] [[package]] @@ -1593,9 +1602,9 @@ dependencies = [ { name = "pytest" }, { name = "sqlalchemy" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/f9/37/ad095d92242fe5c6b4b793191240375c01f6508960f31179de7f0e22cb96/pytest_alembic-0.12.1.tar.gz", hash = "sha256:4e2b477d93464d0cfe80487fdf63922bfd22f29153ca980c1bccf1dbf833cf12", size = 30635, upload-time = "2025-05-27T14:15:29.85Z" } +sdist = { url = "https://files.pythonhosted.org/packages/f9/37/ad095d92242fe5c6b4b793191240375c01f6508960f31179de7f0e22cb96/pytest_alembic-0.12.1.tar.gz", hash = "sha256:4e2b477d93464d0cfe80487fdf63922bfd22f29153ca980c1bccf1dbf833cf12", size = 30635 } wheels = [ - { url = "https://files.pythonhosted.org/packages/8b/f4/ded73992f972360adf84781b7e58729a3778e4358d482e1fe375c83948b4/pytest_alembic-0.12.1-py3-none-any.whl", hash = "sha256:d0d6be79f1c597278fbeda08c5558e7b8770af099521b0aa164e0df4aed945da", size = 36571, upload-time = "2025-05-27T14:15:28.817Z" }, + { url = "https://files.pythonhosted.org/packages/8b/f4/ded73992f972360adf84781b7e58729a3778e4358d482e1fe375c83948b4/pytest_alembic-0.12.1-py3-none-any.whl", hash = "sha256:d0d6be79f1c597278fbeda08c5558e7b8770af099521b0aa164e0df4aed945da", size = 36571 }, ] [[package]] @@ -1605,9 +1614,9 @@ source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "pytest" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/42/86/9e3c5f48f7b7b638b216e4b9e645f54d199d7abbbab7a64a13b4e12ba10f/pytest_asyncio-1.2.0.tar.gz", hash = "sha256:c609a64a2a8768462d0c99811ddb8bd2583c33fd33cf7f21af1c142e824ffb57", size = 50119, upload-time = "2025-09-12T07:33:53.816Z" } +sdist = { url = "https://files.pythonhosted.org/packages/42/86/9e3c5f48f7b7b638b216e4b9e645f54d199d7abbbab7a64a13b4e12ba10f/pytest_asyncio-1.2.0.tar.gz", hash = "sha256:c609a64a2a8768462d0c99811ddb8bd2583c33fd33cf7f21af1c142e824ffb57", size = 50119 } wheels = [ - { url = "https://files.pythonhosted.org/packages/04/93/2fa34714b7a4ae72f2f8dad66ba17dd9a2c793220719e736dda28b7aec27/pytest_asyncio-1.2.0-py3-none-any.whl", hash = "sha256:8e17ae5e46d8e7efe51ab6494dd2010f4ca8dae51652aa3c8d55acf50bfb2e99", size = 15095, upload-time = "2025-09-12T07:33:52.639Z" }, + { url = "https://files.pythonhosted.org/packages/04/93/2fa34714b7a4ae72f2f8dad66ba17dd9a2c793220719e736dda28b7aec27/pytest_asyncio-1.2.0-py3-none-any.whl", hash = "sha256:8e17ae5e46d8e7efe51ab6494dd2010f4ca8dae51652aa3c8d55acf50bfb2e99", size = 15095 }, ] [[package]] @@ -1619,9 +1628,9 @@ dependencies = [ { name = "pluggy" }, { name = "pytest" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/5e/f7/c933acc76f5208b3b00089573cf6a2bc26dc80a8aece8f52bb7d6b1855ca/pytest_cov-7.0.0.tar.gz", hash = "sha256:33c97eda2e049a0c5298e91f519302a1334c26ac65c1a483d6206fd458361af1", size = 54328, upload-time = "2025-09-09T10:57:02.113Z" } +sdist = { url = "https://files.pythonhosted.org/packages/5e/f7/c933acc76f5208b3b00089573cf6a2bc26dc80a8aece8f52bb7d6b1855ca/pytest_cov-7.0.0.tar.gz", hash = "sha256:33c97eda2e049a0c5298e91f519302a1334c26ac65c1a483d6206fd458361af1", size = 54328 } wheels = [ - { url = "https://files.pythonhosted.org/packages/ee/49/1377b49de7d0c1ce41292161ea0f721913fa8722c19fb9c1e3aa0367eecb/pytest_cov-7.0.0-py3-none-any.whl", hash = "sha256:3b8e9558b16cc1479da72058bdecf8073661c7f57f7d3c5f22a1c23507f2d861", size = 22424, upload-time = "2025-09-09T10:57:00.695Z" }, + { url = "https://files.pythonhosted.org/packages/ee/49/1377b49de7d0c1ce41292161ea0f721913fa8722c19fb9c1e3aa0367eecb/pytest_cov-7.0.0-py3-none-any.whl", hash = "sha256:3b8e9558b16cc1479da72058bdecf8073661c7f57f7d3c5f22a1c23507f2d861", size = 22424 }, ] [[package]] @@ -1631,27 +1640,27 @@ source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "six" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/66/c0/0c8b6ad9f17a802ee498c46e004a0eb49bc148f2fd230864601a86dcf6db/python-dateutil-2.9.0.post0.tar.gz", hash = "sha256:37dd54208da7e1cd875388217d5e00ebd4179249f90fb72437e91a35459a0ad3", size = 342432, upload-time = "2024-03-01T18:36:20.211Z" } +sdist = { url = "https://files.pythonhosted.org/packages/66/c0/0c8b6ad9f17a802ee498c46e004a0eb49bc148f2fd230864601a86dcf6db/python-dateutil-2.9.0.post0.tar.gz", hash = "sha256:37dd54208da7e1cd875388217d5e00ebd4179249f90fb72437e91a35459a0ad3", size = 342432 } wheels = [ - { url = "https://files.pythonhosted.org/packages/ec/57/56b9bcc3c9c6a792fcbaf139543cee77261f3651ca9da0c93f5c1221264b/python_dateutil-2.9.0.post0-py2.py3-none-any.whl", hash = "sha256:a8b2bc7bffae282281c8140a97d3aa9c14da0b136dfe83f850eea9a5f7470427", size = 229892, upload-time = "2024-03-01T18:36:18.57Z" }, + { url = "https://files.pythonhosted.org/packages/ec/57/56b9bcc3c9c6a792fcbaf139543cee77261f3651ca9da0c93f5c1221264b/python_dateutil-2.9.0.post0-py2.py3-none-any.whl", hash = "sha256:a8b2bc7bffae282281c8140a97d3aa9c14da0b136dfe83f850eea9a5f7470427", size = 229892 }, ] [[package]] name = "python-dotenv" -version = "1.1.1" +version = "1.2.1" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/f6/b0/4bc07ccd3572a2f9df7e6782f52b0c6c90dcbb803ac4a167702d7d0dfe1e/python_dotenv-1.1.1.tar.gz", hash = "sha256:a8a6399716257f45be6a007360200409fce5cda2661e3dec71d23dc15f6189ab", size = 41978, upload-time = "2025-06-24T04:21:07.341Z" } +sdist = { url = "https://files.pythonhosted.org/packages/f0/26/19cadc79a718c5edbec86fd4919a6b6d3f681039a2f6d66d14be94e75fb9/python_dotenv-1.2.1.tar.gz", hash = "sha256:42667e897e16ab0d66954af0e60a9caa94f0fd4ecf3aaf6d2d260eec1aa36ad6", size = 44221 } wheels = [ - { url = "https://files.pythonhosted.org/packages/5f/ed/539768cf28c661b5b068d66d96a2f155c4971a5d55684a514c1a0e0dec2f/python_dotenv-1.1.1-py3-none-any.whl", hash = "sha256:31f23644fe2602f88ff55e1f5c79ba497e01224ee7737937930c448e4d0e24dc", size = 20556, upload-time = "2025-06-24T04:21:06.073Z" }, + { url = "https://files.pythonhosted.org/packages/14/1b/a298b06749107c305e1fe0f814c6c74aea7b2f1e10989cb30f544a1b3253/python_dotenv-1.2.1-py3-none-any.whl", hash = "sha256:b81ee9561e9ca4004139c6cbba3a238c32b03e4894671e181b671e8cb8425d61", size = 21230 }, ] [[package]] name = "python-multipart" version = "0.0.20" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/f3/87/f44d7c9f274c7ee665a29b885ec97089ec5dc034c7f3fafa03da9e39a09e/python_multipart-0.0.20.tar.gz", hash = "sha256:8dd0cab45b8e23064ae09147625994d090fa46f5b0d1e13af944c331a7fa9d13", size = 37158, upload-time = "2024-12-16T19:45:46.972Z" } +sdist = { url = "https://files.pythonhosted.org/packages/f3/87/f44d7c9f274c7ee665a29b885ec97089ec5dc034c7f3fafa03da9e39a09e/python_multipart-0.0.20.tar.gz", hash = "sha256:8dd0cab45b8e23064ae09147625994d090fa46f5b0d1e13af944c331a7fa9d13", size = 37158 } wheels = [ - { url = "https://files.pythonhosted.org/packages/45/58/38b5afbc1a800eeea951b9285d3912613f2603bdf897a4ab0f4bd7f405fc/python_multipart-0.0.20-py3-none-any.whl", hash = "sha256:8a62d3a8335e06589fe01f2a3e178cdcc632f3fbe0d492ad9ee0ec35aab1f104", size = 24546, upload-time = "2024-12-16T19:45:44.423Z" }, + { url = "https://files.pythonhosted.org/packages/45/58/38b5afbc1a800eeea951b9285d3912613f2603bdf897a4ab0f4bd7f405fc/python_multipart-0.0.20-py3-none-any.whl", hash = "sha256:8a62d3a8335e06589fe01f2a3e178cdcc632f3fbe0d492ad9ee0ec35aab1f104", size = 24546 }, ] [[package]] @@ -1661,63 +1670,127 @@ source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "text-unidecode" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/87/c7/5e1547c44e31da50a460df93af11a535ace568ef89d7a811069ead340c4a/python-slugify-8.0.4.tar.gz", hash = "sha256:59202371d1d05b54a9e7720c5e038f928f45daaffe41dd10822f3907b937c856", size = 10921, upload-time = "2024-02-08T18:32:45.488Z" } +sdist = { url = "https://files.pythonhosted.org/packages/87/c7/5e1547c44e31da50a460df93af11a535ace568ef89d7a811069ead340c4a/python-slugify-8.0.4.tar.gz", hash = "sha256:59202371d1d05b54a9e7720c5e038f928f45daaffe41dd10822f3907b937c856", size = 10921 } wheels = [ - { url = "https://files.pythonhosted.org/packages/a4/62/02da182e544a51a5c3ccf4b03ab79df279f9c60c5e82d5e8bec7ca26ac11/python_slugify-8.0.4-py2.py3-none-any.whl", hash = "sha256:276540b79961052b66b7d116620b36518847f52d5fd9e3a70164fc8c50faa6b8", size = 10051, upload-time = "2024-02-08T18:32:43.911Z" }, + { url = "https://files.pythonhosted.org/packages/a4/62/02da182e544a51a5c3ccf4b03ab79df279f9c60c5e82d5e8bec7ca26ac11/python_slugify-8.0.4-py2.py3-none-any.whl", hash = "sha256:276540b79961052b66b7d116620b36518847f52d5fd9e3a70164fc8c50faa6b8", size = 10051 }, ] [[package]] name = "pytz" version = "2025.2" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/f8/bf/abbd3cdfb8fbc7fb3d4d38d320f2441b1e7cbe29be4f23797b4a2b5d8aac/pytz-2025.2.tar.gz", hash = "sha256:360b9e3dbb49a209c21ad61809c7fb453643e048b38924c765813546746e81c3", size = 320884, upload-time = "2025-03-25T02:25:00.538Z" } +sdist = { url = "https://files.pythonhosted.org/packages/f8/bf/abbd3cdfb8fbc7fb3d4d38d320f2441b1e7cbe29be4f23797b4a2b5d8aac/pytz-2025.2.tar.gz", hash = "sha256:360b9e3dbb49a209c21ad61809c7fb453643e048b38924c765813546746e81c3", size = 320884 } wheels = [ - { url = "https://files.pythonhosted.org/packages/81/c4/34e93fe5f5429d7570ec1fa436f1986fb1f00c3e0f43a589fe2bbcd22c3f/pytz-2025.2-py2.py3-none-any.whl", hash = "sha256:5ddf76296dd8c44c26eb8f4b6f35488f3ccbf6fbbd7adee0b7262d43f0ec2f00", size = 509225, upload-time = "2025-03-25T02:24:58.468Z" }, + { url = "https://files.pythonhosted.org/packages/81/c4/34e93fe5f5429d7570ec1fa436f1986fb1f00c3e0f43a589fe2bbcd22c3f/pytz-2025.2-py2.py3-none-any.whl", hash = "sha256:5ddf76296dd8c44c26eb8f4b6f35488f3ccbf6fbbd7adee0b7262d43f0ec2f00", size = 509225 }, ] [[package]] name = "pyyaml" version = "6.0.3" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/05/8e/961c0007c59b8dd7729d542c61a4d537767a59645b82a0b521206e1e25c2/pyyaml-6.0.3.tar.gz", hash = "sha256:d76623373421df22fb4cf8817020cbb7ef15c725b9d5e45f17e189bfc384190f", size = 130960, upload-time = "2025-09-25T21:33:16.546Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/d1/11/0fd08f8192109f7169db964b5707a2f1e8b745d4e239b784a5a1dd80d1db/pyyaml-6.0.3-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:8da9669d359f02c0b91ccc01cac4a67f16afec0dac22c2ad09f46bee0697eba8", size = 181669, upload-time = "2025-09-25T21:32:23.673Z" }, - { url = "https://files.pythonhosted.org/packages/b1/16/95309993f1d3748cd644e02e38b75d50cbc0d9561d21f390a76242ce073f/pyyaml-6.0.3-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:2283a07e2c21a2aa78d9c4442724ec1eb15f5e42a723b99cb3d822d48f5f7ad1", size = 173252, upload-time = "2025-09-25T21:32:25.149Z" }, - { url = "https://files.pythonhosted.org/packages/50/31/b20f376d3f810b9b2371e72ef5adb33879b25edb7a6d072cb7ca0c486398/pyyaml-6.0.3-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ee2922902c45ae8ccada2c5b501ab86c36525b883eff4255313a253a3160861c", size = 767081, upload-time = "2025-09-25T21:32:26.575Z" }, - { url = "https://files.pythonhosted.org/packages/49/1e/a55ca81e949270d5d4432fbbd19dfea5321eda7c41a849d443dc92fd1ff7/pyyaml-6.0.3-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:a33284e20b78bd4a18c8c2282d549d10bc8408a2a7ff57653c0cf0b9be0afce5", size = 841159, upload-time = "2025-09-25T21:32:27.727Z" }, - { url = "https://files.pythonhosted.org/packages/74/27/e5b8f34d02d9995b80abcef563ea1f8b56d20134d8f4e5e81733b1feceb2/pyyaml-6.0.3-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:0f29edc409a6392443abf94b9cf89ce99889a1dd5376d94316ae5145dfedd5d6", size = 801626, upload-time = "2025-09-25T21:32:28.878Z" }, - { url = "https://files.pythonhosted.org/packages/f9/11/ba845c23988798f40e52ba45f34849aa8a1f2d4af4b798588010792ebad6/pyyaml-6.0.3-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:f7057c9a337546edc7973c0d3ba84ddcdf0daa14533c2065749c9075001090e6", size = 753613, upload-time = "2025-09-25T21:32:30.178Z" }, - { url = "https://files.pythonhosted.org/packages/3d/e0/7966e1a7bfc0a45bf0a7fb6b98ea03fc9b8d84fa7f2229e9659680b69ee3/pyyaml-6.0.3-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:eda16858a3cab07b80edaf74336ece1f986ba330fdb8ee0d6c0d68fe82bc96be", size = 794115, upload-time = "2025-09-25T21:32:31.353Z" }, - { url = "https://files.pythonhosted.org/packages/de/94/980b50a6531b3019e45ddeada0626d45fa85cbe22300844a7983285bed3b/pyyaml-6.0.3-cp313-cp313-win32.whl", hash = "sha256:d0eae10f8159e8fdad514efdc92d74fd8d682c933a6dd088030f3834bc8e6b26", size = 137427, upload-time = "2025-09-25T21:32:32.58Z" }, - { url = "https://files.pythonhosted.org/packages/97/c9/39d5b874e8b28845e4ec2202b5da735d0199dbe5b8fb85f91398814a9a46/pyyaml-6.0.3-cp313-cp313-win_amd64.whl", hash = "sha256:79005a0d97d5ddabfeeea4cf676af11e647e41d81c9a7722a193022accdb6b7c", size = 154090, upload-time = "2025-09-25T21:32:33.659Z" }, - { url = "https://files.pythonhosted.org/packages/73/e8/2bdf3ca2090f68bb3d75b44da7bbc71843b19c9f2b9cb9b0f4ab7a5a4329/pyyaml-6.0.3-cp313-cp313-win_arm64.whl", hash = "sha256:5498cd1645aa724a7c71c8f378eb29ebe23da2fc0d7a08071d89469bf1d2defb", size = 140246, upload-time = "2025-09-25T21:32:34.663Z" }, - { url = "https://files.pythonhosted.org/packages/9d/8c/f4bd7f6465179953d3ac9bc44ac1a8a3e6122cf8ada906b4f96c60172d43/pyyaml-6.0.3-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:8d1fab6bb153a416f9aeb4b8763bc0f22a5586065f86f7664fc23339fc1c1fac", size = 181814, upload-time = "2025-09-25T21:32:35.712Z" }, - { url = "https://files.pythonhosted.org/packages/bd/9c/4d95bb87eb2063d20db7b60faa3840c1b18025517ae857371c4dd55a6b3a/pyyaml-6.0.3-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:34d5fcd24b8445fadc33f9cf348c1047101756fd760b4dacb5c3e99755703310", size = 173809, upload-time = "2025-09-25T21:32:36.789Z" }, - { url = "https://files.pythonhosted.org/packages/92/b5/47e807c2623074914e29dabd16cbbdd4bf5e9b2db9f8090fa64411fc5382/pyyaml-6.0.3-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:501a031947e3a9025ed4405a168e6ef5ae3126c59f90ce0cd6f2bfc477be31b7", size = 766454, upload-time = "2025-09-25T21:32:37.966Z" }, - { url = "https://files.pythonhosted.org/packages/02/9e/e5e9b168be58564121efb3de6859c452fccde0ab093d8438905899a3a483/pyyaml-6.0.3-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:b3bc83488de33889877a0f2543ade9f70c67d66d9ebb4ac959502e12de895788", size = 836355, upload-time = "2025-09-25T21:32:39.178Z" }, - { url = "https://files.pythonhosted.org/packages/88/f9/16491d7ed2a919954993e48aa941b200f38040928474c9e85ea9e64222c3/pyyaml-6.0.3-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c458b6d084f9b935061bc36216e8a69a7e293a2f1e68bf956dcd9e6cbcd143f5", size = 794175, upload-time = "2025-09-25T21:32:40.865Z" }, - { url = "https://files.pythonhosted.org/packages/dd/3f/5989debef34dc6397317802b527dbbafb2b4760878a53d4166579111411e/pyyaml-6.0.3-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:7c6610def4f163542a622a73fb39f534f8c101d690126992300bf3207eab9764", size = 755228, upload-time = "2025-09-25T21:32:42.084Z" }, - { url = "https://files.pythonhosted.org/packages/d7/ce/af88a49043cd2e265be63d083fc75b27b6ed062f5f9fd6cdc223ad62f03e/pyyaml-6.0.3-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:5190d403f121660ce8d1d2c1bb2ef1bd05b5f68533fc5c2ea899bd15f4399b35", size = 789194, upload-time = "2025-09-25T21:32:43.362Z" }, - { url = "https://files.pythonhosted.org/packages/23/20/bb6982b26a40bb43951265ba29d4c246ef0ff59c9fdcdf0ed04e0687de4d/pyyaml-6.0.3-cp314-cp314-win_amd64.whl", hash = "sha256:4a2e8cebe2ff6ab7d1050ecd59c25d4c8bd7e6f400f5f82b96557ac0abafd0ac", size = 156429, upload-time = "2025-09-25T21:32:57.844Z" }, - { url = "https://files.pythonhosted.org/packages/f4/f4/a4541072bb9422c8a883ab55255f918fa378ecf083f5b85e87fc2b4eda1b/pyyaml-6.0.3-cp314-cp314-win_arm64.whl", hash = "sha256:93dda82c9c22deb0a405ea4dc5f2d0cda384168e466364dec6255b293923b2f3", size = 143912, upload-time = "2025-09-25T21:32:59.247Z" }, - { url = "https://files.pythonhosted.org/packages/7c/f9/07dd09ae774e4616edf6cda684ee78f97777bdd15847253637a6f052a62f/pyyaml-6.0.3-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:02893d100e99e03eda1c8fd5c441d8c60103fd175728e23e431db1b589cf5ab3", size = 189108, upload-time = "2025-09-25T21:32:44.377Z" }, - { url = "https://files.pythonhosted.org/packages/4e/78/8d08c9fb7ce09ad8c38ad533c1191cf27f7ae1effe5bb9400a46d9437fcf/pyyaml-6.0.3-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:c1ff362665ae507275af2853520967820d9124984e0f7466736aea23d8611fba", size = 183641, upload-time = "2025-09-25T21:32:45.407Z" }, - { url = "https://files.pythonhosted.org/packages/7b/5b/3babb19104a46945cf816d047db2788bcaf8c94527a805610b0289a01c6b/pyyaml-6.0.3-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6adc77889b628398debc7b65c073bcb99c4a0237b248cacaf3fe8a557563ef6c", size = 831901, upload-time = "2025-09-25T21:32:48.83Z" }, - { url = "https://files.pythonhosted.org/packages/8b/cc/dff0684d8dc44da4d22a13f35f073d558c268780ce3c6ba1b87055bb0b87/pyyaml-6.0.3-cp314-cp314t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:a80cb027f6b349846a3bf6d73b5e95e782175e52f22108cfa17876aaeff93702", size = 861132, upload-time = "2025-09-25T21:32:50.149Z" }, - { url = "https://files.pythonhosted.org/packages/b1/5e/f77dc6b9036943e285ba76b49e118d9ea929885becb0a29ba8a7c75e29fe/pyyaml-6.0.3-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:00c4bdeba853cc34e7dd471f16b4114f4162dc03e6b7afcc2128711f0eca823c", size = 839261, upload-time = "2025-09-25T21:32:51.808Z" }, - { url = "https://files.pythonhosted.org/packages/ce/88/a9db1376aa2a228197c58b37302f284b5617f56a5d959fd1763fb1675ce6/pyyaml-6.0.3-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:66e1674c3ef6f541c35191caae2d429b967b99e02040f5ba928632d9a7f0f065", size = 805272, upload-time = "2025-09-25T21:32:52.941Z" }, - { url = "https://files.pythonhosted.org/packages/da/92/1446574745d74df0c92e6aa4a7b0b3130706a4142b2d1a5869f2eaa423c6/pyyaml-6.0.3-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:16249ee61e95f858e83976573de0f5b2893b3677ba71c9dd36b9cf8be9ac6d65", size = 829923, upload-time = "2025-09-25T21:32:54.537Z" }, - { url = "https://files.pythonhosted.org/packages/f0/7a/1c7270340330e575b92f397352af856a8c06f230aa3e76f86b39d01b416a/pyyaml-6.0.3-cp314-cp314t-win_amd64.whl", hash = "sha256:4ad1906908f2f5ae4e5a8ddfce73c320c2a1429ec52eafd27138b7f1cbe341c9", size = 174062, upload-time = "2025-09-25T21:32:55.767Z" }, - { url = "https://files.pythonhosted.org/packages/f1/12/de94a39c2ef588c7e6455cfbe7343d3b2dc9d6b6b2f40c4c6565744c873d/pyyaml-6.0.3-cp314-cp314t-win_arm64.whl", hash = "sha256:ebc55a14a21cb14062aa4162f906cd962b28e2e9ea38f9b4391244cd8de4ae0b", size = 149341, upload-time = "2025-09-25T21:32:56.828Z" }, +sdist = { url = "https://files.pythonhosted.org/packages/05/8e/961c0007c59b8dd7729d542c61a4d537767a59645b82a0b521206e1e25c2/pyyaml-6.0.3.tar.gz", hash = "sha256:d76623373421df22fb4cf8817020cbb7ef15c725b9d5e45f17e189bfc384190f", size = 130960 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/d1/11/0fd08f8192109f7169db964b5707a2f1e8b745d4e239b784a5a1dd80d1db/pyyaml-6.0.3-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:8da9669d359f02c0b91ccc01cac4a67f16afec0dac22c2ad09f46bee0697eba8", size = 181669 }, + { url = "https://files.pythonhosted.org/packages/b1/16/95309993f1d3748cd644e02e38b75d50cbc0d9561d21f390a76242ce073f/pyyaml-6.0.3-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:2283a07e2c21a2aa78d9c4442724ec1eb15f5e42a723b99cb3d822d48f5f7ad1", size = 173252 }, + { url = "https://files.pythonhosted.org/packages/50/31/b20f376d3f810b9b2371e72ef5adb33879b25edb7a6d072cb7ca0c486398/pyyaml-6.0.3-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ee2922902c45ae8ccada2c5b501ab86c36525b883eff4255313a253a3160861c", size = 767081 }, + { url = "https://files.pythonhosted.org/packages/49/1e/a55ca81e949270d5d4432fbbd19dfea5321eda7c41a849d443dc92fd1ff7/pyyaml-6.0.3-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:a33284e20b78bd4a18c8c2282d549d10bc8408a2a7ff57653c0cf0b9be0afce5", size = 841159 }, + { url = "https://files.pythonhosted.org/packages/74/27/e5b8f34d02d9995b80abcef563ea1f8b56d20134d8f4e5e81733b1feceb2/pyyaml-6.0.3-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:0f29edc409a6392443abf94b9cf89ce99889a1dd5376d94316ae5145dfedd5d6", size = 801626 }, + { url = "https://files.pythonhosted.org/packages/f9/11/ba845c23988798f40e52ba45f34849aa8a1f2d4af4b798588010792ebad6/pyyaml-6.0.3-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:f7057c9a337546edc7973c0d3ba84ddcdf0daa14533c2065749c9075001090e6", size = 753613 }, + { url = "https://files.pythonhosted.org/packages/3d/e0/7966e1a7bfc0a45bf0a7fb6b98ea03fc9b8d84fa7f2229e9659680b69ee3/pyyaml-6.0.3-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:eda16858a3cab07b80edaf74336ece1f986ba330fdb8ee0d6c0d68fe82bc96be", size = 794115 }, + { url = "https://files.pythonhosted.org/packages/de/94/980b50a6531b3019e45ddeada0626d45fa85cbe22300844a7983285bed3b/pyyaml-6.0.3-cp313-cp313-win32.whl", hash = "sha256:d0eae10f8159e8fdad514efdc92d74fd8d682c933a6dd088030f3834bc8e6b26", size = 137427 }, + { url = "https://files.pythonhosted.org/packages/97/c9/39d5b874e8b28845e4ec2202b5da735d0199dbe5b8fb85f91398814a9a46/pyyaml-6.0.3-cp313-cp313-win_amd64.whl", hash = "sha256:79005a0d97d5ddabfeeea4cf676af11e647e41d81c9a7722a193022accdb6b7c", size = 154090 }, + { url = "https://files.pythonhosted.org/packages/73/e8/2bdf3ca2090f68bb3d75b44da7bbc71843b19c9f2b9cb9b0f4ab7a5a4329/pyyaml-6.0.3-cp313-cp313-win_arm64.whl", hash = "sha256:5498cd1645aa724a7c71c8f378eb29ebe23da2fc0d7a08071d89469bf1d2defb", size = 140246 }, + { url = "https://files.pythonhosted.org/packages/9d/8c/f4bd7f6465179953d3ac9bc44ac1a8a3e6122cf8ada906b4f96c60172d43/pyyaml-6.0.3-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:8d1fab6bb153a416f9aeb4b8763bc0f22a5586065f86f7664fc23339fc1c1fac", size = 181814 }, + { url = "https://files.pythonhosted.org/packages/bd/9c/4d95bb87eb2063d20db7b60faa3840c1b18025517ae857371c4dd55a6b3a/pyyaml-6.0.3-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:34d5fcd24b8445fadc33f9cf348c1047101756fd760b4dacb5c3e99755703310", size = 173809 }, + { url = "https://files.pythonhosted.org/packages/92/b5/47e807c2623074914e29dabd16cbbdd4bf5e9b2db9f8090fa64411fc5382/pyyaml-6.0.3-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:501a031947e3a9025ed4405a168e6ef5ae3126c59f90ce0cd6f2bfc477be31b7", size = 766454 }, + { url = "https://files.pythonhosted.org/packages/02/9e/e5e9b168be58564121efb3de6859c452fccde0ab093d8438905899a3a483/pyyaml-6.0.3-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:b3bc83488de33889877a0f2543ade9f70c67d66d9ebb4ac959502e12de895788", size = 836355 }, + { url = "https://files.pythonhosted.org/packages/88/f9/16491d7ed2a919954993e48aa941b200f38040928474c9e85ea9e64222c3/pyyaml-6.0.3-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c458b6d084f9b935061bc36216e8a69a7e293a2f1e68bf956dcd9e6cbcd143f5", size = 794175 }, + { url = "https://files.pythonhosted.org/packages/dd/3f/5989debef34dc6397317802b527dbbafb2b4760878a53d4166579111411e/pyyaml-6.0.3-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:7c6610def4f163542a622a73fb39f534f8c101d690126992300bf3207eab9764", size = 755228 }, + { url = "https://files.pythonhosted.org/packages/d7/ce/af88a49043cd2e265be63d083fc75b27b6ed062f5f9fd6cdc223ad62f03e/pyyaml-6.0.3-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:5190d403f121660ce8d1d2c1bb2ef1bd05b5f68533fc5c2ea899bd15f4399b35", size = 789194 }, + { url = "https://files.pythonhosted.org/packages/23/20/bb6982b26a40bb43951265ba29d4c246ef0ff59c9fdcdf0ed04e0687de4d/pyyaml-6.0.3-cp314-cp314-win_amd64.whl", hash = "sha256:4a2e8cebe2ff6ab7d1050ecd59c25d4c8bd7e6f400f5f82b96557ac0abafd0ac", size = 156429 }, + { url = "https://files.pythonhosted.org/packages/f4/f4/a4541072bb9422c8a883ab55255f918fa378ecf083f5b85e87fc2b4eda1b/pyyaml-6.0.3-cp314-cp314-win_arm64.whl", hash = "sha256:93dda82c9c22deb0a405ea4dc5f2d0cda384168e466364dec6255b293923b2f3", size = 143912 }, + { url = "https://files.pythonhosted.org/packages/7c/f9/07dd09ae774e4616edf6cda684ee78f97777bdd15847253637a6f052a62f/pyyaml-6.0.3-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:02893d100e99e03eda1c8fd5c441d8c60103fd175728e23e431db1b589cf5ab3", size = 189108 }, + { url = "https://files.pythonhosted.org/packages/4e/78/8d08c9fb7ce09ad8c38ad533c1191cf27f7ae1effe5bb9400a46d9437fcf/pyyaml-6.0.3-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:c1ff362665ae507275af2853520967820d9124984e0f7466736aea23d8611fba", size = 183641 }, + { url = "https://files.pythonhosted.org/packages/7b/5b/3babb19104a46945cf816d047db2788bcaf8c94527a805610b0289a01c6b/pyyaml-6.0.3-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6adc77889b628398debc7b65c073bcb99c4a0237b248cacaf3fe8a557563ef6c", size = 831901 }, + { url = "https://files.pythonhosted.org/packages/8b/cc/dff0684d8dc44da4d22a13f35f073d558c268780ce3c6ba1b87055bb0b87/pyyaml-6.0.3-cp314-cp314t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:a80cb027f6b349846a3bf6d73b5e95e782175e52f22108cfa17876aaeff93702", size = 861132 }, + { url = "https://files.pythonhosted.org/packages/b1/5e/f77dc6b9036943e285ba76b49e118d9ea929885becb0a29ba8a7c75e29fe/pyyaml-6.0.3-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:00c4bdeba853cc34e7dd471f16b4114f4162dc03e6b7afcc2128711f0eca823c", size = 839261 }, + { url = "https://files.pythonhosted.org/packages/ce/88/a9db1376aa2a228197c58b37302f284b5617f56a5d959fd1763fb1675ce6/pyyaml-6.0.3-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:66e1674c3ef6f541c35191caae2d429b967b99e02040f5ba928632d9a7f0f065", size = 805272 }, + { url = "https://files.pythonhosted.org/packages/da/92/1446574745d74df0c92e6aa4a7b0b3130706a4142b2d1a5869f2eaa423c6/pyyaml-6.0.3-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:16249ee61e95f858e83976573de0f5b2893b3677ba71c9dd36b9cf8be9ac6d65", size = 829923 }, + { url = "https://files.pythonhosted.org/packages/f0/7a/1c7270340330e575b92f397352af856a8c06f230aa3e76f86b39d01b416a/pyyaml-6.0.3-cp314-cp314t-win_amd64.whl", hash = "sha256:4ad1906908f2f5ae4e5a8ddfce73c320c2a1429ec52eafd27138b7f1cbe341c9", size = 174062 }, + { url = "https://files.pythonhosted.org/packages/f1/12/de94a39c2ef588c7e6455cfbe7343d3b2dc9d6b6b2f40c4c6565744c873d/pyyaml-6.0.3-cp314-cp314t-win_arm64.whl", hash = "sha256:ebc55a14a21cb14062aa4162f906cd962b28e2e9ea38f9b4391244cd8de4ae0b", size = 149341 }, ] [[package]] name = "redis" version = "7.0.1" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/57/8f/f125feec0b958e8d22c8f0b492b30b1991d9499a4315dfde466cf4289edc/redis-7.0.1.tar.gz", hash = "sha256:c949df947dca995dc68fdf5a7863950bf6df24f8d6022394585acc98e81624f1", size = 4755322, upload-time = "2025-10-27T14:34:00.33Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/e9/97/9f22a33c475cda519f20aba6babb340fb2f2254a02fb947816960d1e669a/redis-7.0.1-py3-none-any.whl", hash = "sha256:4977af3c7d67f8f0eb8b6fec0dafc9605db9343142f634041fb0235f67c0588a", size = 339938, upload-time = "2025-10-27T14:33:58.553Z" }, +sdist = { url = "https://files.pythonhosted.org/packages/57/8f/f125feec0b958e8d22c8f0b492b30b1991d9499a4315dfde466cf4289edc/redis-7.0.1.tar.gz", hash = "sha256:c949df947dca995dc68fdf5a7863950bf6df24f8d6022394585acc98e81624f1", size = 4755322 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/e9/97/9f22a33c475cda519f20aba6babb340fb2f2254a02fb947816960d1e669a/redis-7.0.1-py3-none-any.whl", hash = "sha256:4977af3c7d67f8f0eb8b6fec0dafc9605db9343142f634041fb0235f67c0588a", size = 339938 }, +] + +[[package]] +name = "regex" +version = "2025.11.3" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/cc/a9/546676f25e573a4cf00fe8e119b78a37b6a8fe2dc95cda877b30889c9c45/regex-2025.11.3.tar.gz", hash = "sha256:1fedc720f9bb2494ce31a58a1631f9c82df6a09b49c19517ea5cc280b4541e01", size = 414669 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/e1/a7/dda24ebd49da46a197436ad96378f17df30ceb40e52e859fc42cac45b850/regex-2025.11.3-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:c1e448051717a334891f2b9a620fe36776ebf3dd8ec46a0b877c8ae69575feb4", size = 489081 }, + { url = "https://files.pythonhosted.org/packages/19/22/af2dc751aacf88089836aa088a1a11c4f21a04707eb1b0478e8e8fb32847/regex-2025.11.3-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:9b5aca4d5dfd7fbfbfbdaf44850fcc7709a01146a797536a8f84952e940cca76", size = 291123 }, + { url = "https://files.pythonhosted.org/packages/a3/88/1a3ea5672f4b0a84802ee9891b86743438e7c04eb0b8f8c4e16a42375327/regex-2025.11.3-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:04d2765516395cf7dda331a244a3282c0f5ae96075f728629287dfa6f76ba70a", size = 288814 }, + { url = "https://files.pythonhosted.org/packages/fb/8c/f5987895bf42b8ddeea1b315c9fedcfe07cadee28b9c98cf50d00adcb14d/regex-2025.11.3-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:5d9903ca42bfeec4cebedba8022a7c97ad2aab22e09573ce9976ba01b65e4361", size = 798592 }, + { url = "https://files.pythonhosted.org/packages/99/2a/6591ebeede78203fa77ee46a1c36649e02df9eaa77a033d1ccdf2fcd5d4e/regex-2025.11.3-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:639431bdc89d6429f6721625e8129413980ccd62e9d3f496be618a41d205f160", size = 864122 }, + { url = "https://files.pythonhosted.org/packages/94/d6/be32a87cf28cf8ed064ff281cfbd49aefd90242a83e4b08b5a86b38e8eb4/regex-2025.11.3-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:f117efad42068f9715677c8523ed2be1518116d1c49b1dd17987716695181efe", size = 912272 }, + { url = "https://files.pythonhosted.org/packages/62/11/9bcef2d1445665b180ac7f230406ad80671f0fc2a6ffb93493b5dd8cd64c/regex-2025.11.3-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:4aecb6f461316adf9f1f0f6a4a1a3d79e045f9b71ec76055a791affa3b285850", size = 803497 }, + { url = "https://files.pythonhosted.org/packages/e5/a7/da0dc273d57f560399aa16d8a68ae7f9b57679476fc7ace46501d455fe84/regex-2025.11.3-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:3b3a5f320136873cc5561098dfab677eea139521cb9a9e8db98b7e64aef44cbc", size = 787892 }, + { url = "https://files.pythonhosted.org/packages/da/4b/732a0c5a9736a0b8d6d720d4945a2f1e6f38f87f48f3173559f53e8d5d82/regex-2025.11.3-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:75fa6f0056e7efb1f42a1c34e58be24072cb9e61a601340cc1196ae92326a4f9", size = 858462 }, + { url = "https://files.pythonhosted.org/packages/0c/f5/a2a03df27dc4c2d0c769220f5110ba8c4084b0bfa9ab0f9b4fcfa3d2b0fc/regex-2025.11.3-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:dbe6095001465294f13f1adcd3311e50dd84e5a71525f20a10bd16689c61ce0b", size = 850528 }, + { url = "https://files.pythonhosted.org/packages/d6/09/e1cd5bee3841c7f6eb37d95ca91cdee7100b8f88b81e41c2ef426910891a/regex-2025.11.3-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:454d9b4ae7881afbc25015b8627c16d88a597479b9dea82b8c6e7e2e07240dc7", size = 789866 }, + { url = "https://files.pythonhosted.org/packages/eb/51/702f5ea74e2a9c13d855a6a85b7f80c30f9e72a95493260193c07f3f8d74/regex-2025.11.3-cp313-cp313-win32.whl", hash = "sha256:28ba4d69171fc6e9896337d4fc63a43660002b7da53fc15ac992abcf3410917c", size = 266189 }, + { url = "https://files.pythonhosted.org/packages/8b/00/6e29bb314e271a743170e53649db0fdb8e8ff0b64b4f425f5602f4eb9014/regex-2025.11.3-cp313-cp313-win_amd64.whl", hash = "sha256:bac4200befe50c670c405dc33af26dad5a3b6b255dd6c000d92fe4629f9ed6a5", size = 277054 }, + { url = "https://files.pythonhosted.org/packages/25/f1/b156ff9f2ec9ac441710764dda95e4edaf5f36aca48246d1eea3f1fd96ec/regex-2025.11.3-cp313-cp313-win_arm64.whl", hash = "sha256:2292cd5a90dab247f9abe892ac584cb24f0f54680c73fcb4a7493c66c2bf2467", size = 270325 }, + { url = "https://files.pythonhosted.org/packages/20/28/fd0c63357caefe5680b8ea052131acbd7f456893b69cc2a90cc3e0dc90d4/regex-2025.11.3-cp313-cp313t-macosx_10_13_universal2.whl", hash = "sha256:1eb1ebf6822b756c723e09f5186473d93236c06c579d2cc0671a722d2ab14281", size = 491984 }, + { url = "https://files.pythonhosted.org/packages/df/ec/7014c15626ab46b902b3bcc4b28a7bae46d8f281fc7ea9c95e22fcaaa917/regex-2025.11.3-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:1e00ec2970aab10dc5db34af535f21fcf32b4a31d99e34963419636e2f85ae39", size = 292673 }, + { url = "https://files.pythonhosted.org/packages/23/ab/3b952ff7239f20d05f1f99e9e20188513905f218c81d52fb5e78d2bf7634/regex-2025.11.3-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:a4cb042b615245d5ff9b3794f56be4138b5adc35a4166014d31d1814744148c7", size = 291029 }, + { url = "https://files.pythonhosted.org/packages/21/7e/3dc2749fc684f455f162dcafb8a187b559e2614f3826877d3844a131f37b/regex-2025.11.3-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:44f264d4bf02f3176467d90b294d59bf1db9fe53c141ff772f27a8b456b2a9ed", size = 807437 }, + { url = "https://files.pythonhosted.org/packages/1b/0b/d529a85ab349c6a25d1ca783235b6e3eedf187247eab536797021f7126c6/regex-2025.11.3-cp313-cp313t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:7be0277469bf3bd7a34a9c57c1b6a724532a0d235cd0dc4e7f4316f982c28b19", size = 873368 }, + { url = "https://files.pythonhosted.org/packages/7d/18/2d868155f8c9e3e9d8f9e10c64e9a9f496bb8f7e037a88a8bed26b435af6/regex-2025.11.3-cp313-cp313t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:0d31e08426ff4b5b650f68839f5af51a92a5b51abd8554a60c2fbc7c71f25d0b", size = 914921 }, + { url = "https://files.pythonhosted.org/packages/2d/71/9d72ff0f354fa783fe2ba913c8734c3b433b86406117a8db4ea2bf1c7a2f/regex-2025.11.3-cp313-cp313t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:e43586ce5bd28f9f285a6e729466841368c4a0353f6fd08d4ce4630843d3648a", size = 812708 }, + { url = "https://files.pythonhosted.org/packages/e7/19/ce4bf7f5575c97f82b6e804ffb5c4e940c62609ab2a0d9538d47a7fdf7d4/regex-2025.11.3-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:0f9397d561a4c16829d4e6ff75202c1c08b68a3bdbfe29dbfcdb31c9830907c6", size = 795472 }, + { url = "https://files.pythonhosted.org/packages/03/86/fd1063a176ffb7b2315f9a1b08d17b18118b28d9df163132615b835a26ee/regex-2025.11.3-cp313-cp313t-musllinux_1_2_ppc64le.whl", hash = "sha256:dd16e78eb18ffdb25ee33a0682d17912e8cc8a770e885aeee95020046128f1ce", size = 868341 }, + { url = "https://files.pythonhosted.org/packages/12/43/103fb2e9811205e7386366501bc866a164a0430c79dd59eac886a2822950/regex-2025.11.3-cp313-cp313t-musllinux_1_2_s390x.whl", hash = "sha256:ffcca5b9efe948ba0661e9df0fa50d2bc4b097c70b9810212d6b62f05d83b2dd", size = 854666 }, + { url = "https://files.pythonhosted.org/packages/7d/22/e392e53f3869b75804762c7c848bd2dd2abf2b70fb0e526f58724638bd35/regex-2025.11.3-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:c56b4d162ca2b43318ac671c65bd4d563e841a694ac70e1a976ac38fcf4ca1d2", size = 799473 }, + { url = "https://files.pythonhosted.org/packages/4f/f9/8bd6b656592f925b6845fcbb4d57603a3ac2fb2373344ffa1ed70aa6820a/regex-2025.11.3-cp313-cp313t-win32.whl", hash = "sha256:9ddc42e68114e161e51e272f667d640f97e84a2b9ef14b7477c53aac20c2d59a", size = 268792 }, + { url = "https://files.pythonhosted.org/packages/e5/87/0e7d603467775ff65cd2aeabf1b5b50cc1c3708556a8b849a2fa4dd1542b/regex-2025.11.3-cp313-cp313t-win_amd64.whl", hash = "sha256:7a7c7fdf755032ffdd72c77e3d8096bdcb0eb92e89e17571a196f03d88b11b3c", size = 280214 }, + { url = "https://files.pythonhosted.org/packages/8d/d0/2afc6f8e94e2b64bfb738a7c2b6387ac1699f09f032d363ed9447fd2bb57/regex-2025.11.3-cp313-cp313t-win_arm64.whl", hash = "sha256:df9eb838c44f570283712e7cff14c16329a9f0fb19ca492d21d4b7528ee6821e", size = 271469 }, + { url = "https://files.pythonhosted.org/packages/31/e9/f6e13de7e0983837f7b6d238ad9458800a874bf37c264f7923e63409944c/regex-2025.11.3-cp314-cp314-macosx_10_13_universal2.whl", hash = "sha256:9697a52e57576c83139d7c6f213d64485d3df5bf84807c35fa409e6c970801c6", size = 489089 }, + { url = "https://files.pythonhosted.org/packages/a3/5c/261f4a262f1fa65141c1b74b255988bd2fa020cc599e53b080667d591cfc/regex-2025.11.3-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:e18bc3f73bd41243c9b38a6d9f2366cd0e0137a9aebe2d8ff76c5b67d4c0a3f4", size = 291059 }, + { url = "https://files.pythonhosted.org/packages/8e/57/f14eeb7f072b0e9a5a090d1712741fd8f214ec193dba773cf5410108bb7d/regex-2025.11.3-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:61a08bcb0ec14ff4e0ed2044aad948d0659604f824cbd50b55e30b0ec6f09c73", size = 288900 }, + { url = "https://files.pythonhosted.org/packages/3c/6b/1d650c45e99a9b327586739d926a1cd4e94666b1bd4af90428b36af66dc7/regex-2025.11.3-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:c9c30003b9347c24bcc210958c5d167b9e4f9be786cb380a7d32f14f9b84674f", size = 799010 }, + { url = "https://files.pythonhosted.org/packages/99/ee/d66dcbc6b628ce4e3f7f0cbbb84603aa2fc0ffc878babc857726b8aab2e9/regex-2025.11.3-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:4e1e592789704459900728d88d41a46fe3969b82ab62945560a31732ffc19a6d", size = 864893 }, + { url = "https://files.pythonhosted.org/packages/bf/2d/f238229f1caba7ac87a6c4153d79947fb0261415827ae0f77c304260c7d3/regex-2025.11.3-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:6538241f45eb5a25aa575dbba1069ad786f68a4f2773a29a2bd3dd1f9de787be", size = 911522 }, + { url = "https://files.pythonhosted.org/packages/bd/3d/22a4eaba214a917c80e04f6025d26143690f0419511e0116508e24b11c9b/regex-2025.11.3-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:bce22519c989bb72a7e6b36a199384c53db7722fe669ba891da75907fe3587db", size = 803272 }, + { url = "https://files.pythonhosted.org/packages/84/b1/03188f634a409353a84b5ef49754b97dbcc0c0f6fd6c8ede505a8960a0a4/regex-2025.11.3-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:66d559b21d3640203ab9075797a55165d79017520685fb407b9234d72ab63c62", size = 787958 }, + { url = "https://files.pythonhosted.org/packages/99/6a/27d072f7fbf6fadd59c64d210305e1ff865cc3b78b526fd147db768c553b/regex-2025.11.3-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:669dcfb2e38f9e8c69507bace46f4889e3abbfd9b0c29719202883c0a603598f", size = 859289 }, + { url = "https://files.pythonhosted.org/packages/9a/70/1b3878f648e0b6abe023172dacb02157e685564853cc363d9961bcccde4e/regex-2025.11.3-cp314-cp314-musllinux_1_2_s390x.whl", hash = "sha256:32f74f35ff0f25a5021373ac61442edcb150731fbaa28286bbc8bb1582c89d02", size = 850026 }, + { url = "https://files.pythonhosted.org/packages/dd/d5/68e25559b526b8baab8e66839304ede68ff6727237a47727d240006bd0ff/regex-2025.11.3-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:e6c7a21dffba883234baefe91bc3388e629779582038f75d2a5be918e250f0ed", size = 789499 }, + { url = "https://files.pythonhosted.org/packages/fc/df/43971264857140a350910d4e33df725e8c94dd9dee8d2e4729fa0d63d49e/regex-2025.11.3-cp314-cp314-win32.whl", hash = "sha256:795ea137b1d809eb6836b43748b12634291c0ed55ad50a7d72d21edf1cd565c4", size = 271604 }, + { url = "https://files.pythonhosted.org/packages/01/6f/9711b57dc6894a55faf80a4c1b5aa4f8649805cb9c7aef46f7d27e2b9206/regex-2025.11.3-cp314-cp314-win_amd64.whl", hash = "sha256:9f95fbaa0ee1610ec0fc6b26668e9917a582ba80c52cc6d9ada15e30aa9ab9ad", size = 280320 }, + { url = "https://files.pythonhosted.org/packages/f1/7e/f6eaa207d4377481f5e1775cdeb5a443b5a59b392d0065f3417d31d80f87/regex-2025.11.3-cp314-cp314-win_arm64.whl", hash = "sha256:dfec44d532be4c07088c3de2876130ff0fbeeacaa89a137decbbb5f665855a0f", size = 273372 }, + { url = "https://files.pythonhosted.org/packages/c3/06/49b198550ee0f5e4184271cee87ba4dfd9692c91ec55289e6282f0f86ccf/regex-2025.11.3-cp314-cp314t-macosx_10_13_universal2.whl", hash = "sha256:ba0d8a5d7f04f73ee7d01d974d47c5834f8a1b0224390e4fe7c12a3a92a78ecc", size = 491985 }, + { url = "https://files.pythonhosted.org/packages/ce/bf/abdafade008f0b1c9da10d934034cb670432d6cf6cbe38bbb53a1cfd6cf8/regex-2025.11.3-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:442d86cf1cfe4faabf97db7d901ef58347efd004934da045c745e7b5bd57ac49", size = 292669 }, + { url = "https://files.pythonhosted.org/packages/f9/ef/0c357bb8edbd2ad8e273fcb9e1761bc37b8acbc6e1be050bebd6475f19c1/regex-2025.11.3-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:fd0a5e563c756de210bb964789b5abe4f114dacae9104a47e1a649b910361536", size = 291030 }, + { url = "https://files.pythonhosted.org/packages/79/06/edbb67257596649b8fb088d6aeacbcb248ac195714b18a65e018bf4c0b50/regex-2025.11.3-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:bf3490bcbb985a1ae97b2ce9ad1c0f06a852d5b19dde9b07bdf25bf224248c95", size = 807674 }, + { url = "https://files.pythonhosted.org/packages/f4/d9/ad4deccfce0ea336296bd087f1a191543bb99ee1c53093dcd4c64d951d00/regex-2025.11.3-cp314-cp314t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:3809988f0a8b8c9dcc0f92478d6501fac7200b9ec56aecf0ec21f4a2ec4b6009", size = 873451 }, + { url = "https://files.pythonhosted.org/packages/13/75/a55a4724c56ef13e3e04acaab29df26582f6978c000ac9cd6810ad1f341f/regex-2025.11.3-cp314-cp314t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:f4ff94e58e84aedb9c9fce66d4ef9f27a190285b451420f297c9a09f2b9abee9", size = 914980 }, + { url = "https://files.pythonhosted.org/packages/67/1e/a1657ee15bd9116f70d4a530c736983eed997b361e20ecd8f5ca3759d5c5/regex-2025.11.3-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:7eb542fd347ce61e1321b0a6b945d5701528dca0cd9759c2e3bb8bd57e47964d", size = 812852 }, + { url = "https://files.pythonhosted.org/packages/b8/6f/f7516dde5506a588a561d296b2d0044839de06035bb486b326065b4c101e/regex-2025.11.3-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:d6c2d5919075a1f2e413c00b056ea0c2f065b3f5fe83c3d07d325ab92dce51d6", size = 795566 }, + { url = "https://files.pythonhosted.org/packages/d9/dd/3d10b9e170cc16fb34cb2cef91513cf3df65f440b3366030631b2984a264/regex-2025.11.3-cp314-cp314t-musllinux_1_2_ppc64le.whl", hash = "sha256:3f8bf11a4827cc7ce5a53d4ef6cddd5ad25595d3c1435ef08f76825851343154", size = 868463 }, + { url = "https://files.pythonhosted.org/packages/f5/8e/935e6beff1695aa9085ff83195daccd72acc82c81793df480f34569330de/regex-2025.11.3-cp314-cp314t-musllinux_1_2_s390x.whl", hash = "sha256:22c12d837298651e5550ac1d964e4ff57c3f56965fc1812c90c9fb2028eaf267", size = 854694 }, + { url = "https://files.pythonhosted.org/packages/92/12/10650181a040978b2f5720a6a74d44f841371a3d984c2083fc1752e4acf6/regex-2025.11.3-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:62ba394a3dda9ad41c7c780f60f6e4a70988741415ae96f6d1bf6c239cf01379", size = 799691 }, + { url = "https://files.pythonhosted.org/packages/67/90/8f37138181c9a7690e7e4cb388debbd389342db3c7381d636d2875940752/regex-2025.11.3-cp314-cp314t-win32.whl", hash = "sha256:4bf146dca15cdd53224a1bf46d628bd7590e4a07fbb69e720d561aea43a32b38", size = 274583 }, + { url = "https://files.pythonhosted.org/packages/8f/cd/867f5ec442d56beb56f5f854f40abcfc75e11d10b11fdb1869dd39c63aaf/regex-2025.11.3-cp314-cp314t-win_amd64.whl", hash = "sha256:adad1a1bcf1c9e76346e091d22d23ac54ef28e1365117d99521631078dfec9de", size = 284286 }, + { url = "https://files.pythonhosted.org/packages/20/31/32c0c4610cbc070362bf1d2e4ea86d1ea29014d400a6d6c2486fcfd57766/regex-2025.11.3-cp314-cp314t-win_arm64.whl", hash = "sha256:c54f768482cef41e219720013cd05933b6f971d9562544d691c68699bf2b6801", size = 274741 }, ] [[package]] @@ -1789,7 +1862,7 @@ requires-dist = [ { name = "email-validator", specifier = ">=2.2.0" }, { name = "fastapi", extras = ["standard"], specifier = ">=0.115.14" }, { name = "fastapi-filter", specifier = ">=2.0.1" }, - { name = "fastapi-mail", specifier = "==1.5.2" }, + { name = "fastapi-mail", git = "https://github.com/simonvanlierde/fastapi-mail?rev=f32147ec1a450ed22262913c5ac7ec3b67dd0117" }, { name = "fastapi-pagination", specifier = ">=0.13.2" }, { name = "fastapi-storages", specifier = ">=0.3.0" }, { name = "fastapi-users", extras = ["oauth", "sqlalchemy"], specifier = ">=14.0.1" }, @@ -1847,9 +1920,9 @@ dependencies = [ { name = "pillow" }, { name = "pydantic" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/58/55/1bd336b19e2483bea7d1f8c2967d25a297ddacb686ee72c13b2023ae97d0/relab_rpi_cam_models-0.1.1.tar.gz", hash = "sha256:6ac60f787b33c7951edd956c78c939764af48e63eaa9809eaa3590a604cf1dde", size = 3943, upload-time = "2025-08-19T23:38:05.058Z" } +sdist = { url = "https://files.pythonhosted.org/packages/58/55/1bd336b19e2483bea7d1f8c2967d25a297ddacb686ee72c13b2023ae97d0/relab_rpi_cam_models-0.1.1.tar.gz", hash = "sha256:6ac60f787b33c7951edd956c78c939764af48e63eaa9809eaa3590a604cf1dde", size = 3943 } wheels = [ - { url = "https://files.pythonhosted.org/packages/8f/85/1ec6ec0c444dcccdc343b2978d5bcde8043b0b696c6d853c51e115d7dc53/relab_rpi_cam_models-0.1.1-py3-none-any.whl", hash = "sha256:bba3182febdbbc8f48897e1dc42ac2b779a48de8ef6be867b6131eed2b019f6b", size = 5552, upload-time = "2025-08-19T23:38:03.866Z" }, + { url = "https://files.pythonhosted.org/packages/8f/85/1ec6ec0c444dcccdc343b2978d5bcde8043b0b696c6d853c51e115d7dc53/relab_rpi_cam_models-0.1.1-py3-none-any.whl", hash = "sha256:bba3182febdbbc8f48897e1dc42ac2b779a48de8ef6be867b6131eed2b019f6b", size = 5552 }, ] [[package]] @@ -1862,9 +1935,9 @@ dependencies = [ { name = "idna" }, { name = "urllib3" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/c9/74/b3ff8e6c8446842c3f5c837e9c3dfcfe2018ea6ecef224c710c85ef728f4/requests-2.32.5.tar.gz", hash = "sha256:dbba0bac56e100853db0ea71b82b4dfd5fe2bf6d3754a8893c3af500cec7d7cf", size = 134517, upload-time = "2025-08-18T20:46:02.573Z" } +sdist = { url = "https://files.pythonhosted.org/packages/c9/74/b3ff8e6c8446842c3f5c837e9c3dfcfe2018ea6ecef224c710c85ef728f4/requests-2.32.5.tar.gz", hash = "sha256:dbba0bac56e100853db0ea71b82b4dfd5fe2bf6d3754a8893c3af500cec7d7cf", size = 134517 } wheels = [ - { url = "https://files.pythonhosted.org/packages/1e/db/4254e3eabe8020b458f1a747140d32277ec7a271daf1d235b70dc0b4e6e3/requests-2.32.5-py3-none-any.whl", hash = "sha256:2462f94637a34fd532264295e186976db0f5d453d1cdd31473c85a6a161affb6", size = 64738, upload-time = "2025-08-18T20:46:00.542Z" }, + { url = "https://files.pythonhosted.org/packages/1e/db/4254e3eabe8020b458f1a747140d32277ec7a271daf1d235b70dc0b4e6e3/requests-2.32.5-py3-none-any.whl", hash = "sha256:2462f94637a34fd532264295e186976db0f5d453d1cdd31473c85a6a161affb6", size = 64738 }, ] [[package]] @@ -1874,9 +1947,9 @@ source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "requests" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/3c/f8/5dc70102e4d337063452c82e1f0d95e39abfe67aa222ed8a5ddeb9df8de8/requests_file-3.0.1.tar.gz", hash = "sha256:f14243d7796c588f3521bd423c5dea2ee4cc730e54a3cac9574d78aca1272576", size = 6967, upload-time = "2025-10-20T18:56:42.279Z" } +sdist = { url = "https://files.pythonhosted.org/packages/3c/f8/5dc70102e4d337063452c82e1f0d95e39abfe67aa222ed8a5ddeb9df8de8/requests_file-3.0.1.tar.gz", hash = "sha256:f14243d7796c588f3521bd423c5dea2ee4cc730e54a3cac9574d78aca1272576", size = 6967 } wheels = [ - { url = "https://files.pythonhosted.org/packages/e1/d5/de8f089119205a09da657ed4784c584ede8381a0ce6821212a6d4ca47054/requests_file-3.0.1-py2.py3-none-any.whl", hash = "sha256:d0f5eb94353986d998f80ac63c7f146a307728be051d4d1cd390dbdb59c10fa2", size = 4514, upload-time = "2025-10-20T18:56:41.184Z" }, + { url = "https://files.pythonhosted.org/packages/e1/d5/de8f089119205a09da657ed4784c584ede8381a0ce6821212a6d4ca47054/requests_file-3.0.1-py2.py3-none-any.whl", hash = "sha256:d0f5eb94353986d998f80ac63c7f146a307728be051d4d1cd390dbdb59c10fa2", size = 4514 }, ] [[package]] @@ -1887,9 +1960,9 @@ dependencies = [ { name = "markdown-it-py" }, { name = "pygments" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/fb/d2/8920e102050a0de7bfabeb4c4614a49248cf8d5d7a8d01885fbb24dc767a/rich-14.2.0.tar.gz", hash = "sha256:73ff50c7c0c1c77c8243079283f4edb376f0f6442433aecb8ce7e6d0b92d1fe4", size = 219990, upload-time = "2025-10-09T14:16:53.064Z" } +sdist = { url = "https://files.pythonhosted.org/packages/fb/d2/8920e102050a0de7bfabeb4c4614a49248cf8d5d7a8d01885fbb24dc767a/rich-14.2.0.tar.gz", hash = "sha256:73ff50c7c0c1c77c8243079283f4edb376f0f6442433aecb8ce7e6d0b92d1fe4", size = 219990 } wheels = [ - { url = "https://files.pythonhosted.org/packages/25/7a/b0178788f8dc6cafce37a212c99565fa1fe7872c70c6c9c1e1a372d9d88f/rich-14.2.0-py3-none-any.whl", hash = "sha256:76bc51fe2e57d2b1be1f96c524b890b816e334ab4c1e45888799bfaab0021edd", size = 243393, upload-time = "2025-10-09T14:16:51.245Z" }, + { url = "https://files.pythonhosted.org/packages/25/7a/b0178788f8dc6cafce37a212c99565fa1fe7872c70c6c9c1e1a372d9d88f/rich-14.2.0-py3-none-any.whl", hash = "sha256:76bc51fe2e57d2b1be1f96c524b890b816e334ab4c1e45888799bfaab0021edd", size = 243393 }, ] [[package]] @@ -1901,47 +1974,62 @@ dependencies = [ { name = "rich" }, { name = "typing-extensions" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/67/33/1a18839aaa8feef7983590c05c22c9c09d245ada6017d118325bbfcc7651/rich_toolkit-0.15.1.tar.gz", hash = "sha256:6f9630eb29f3843d19d48c3bd5706a086d36d62016687f9d0efa027ddc2dd08a", size = 115322, upload-time = "2025-09-04T09:28:11.789Z" } +sdist = { url = "https://files.pythonhosted.org/packages/67/33/1a18839aaa8feef7983590c05c22c9c09d245ada6017d118325bbfcc7651/rich_toolkit-0.15.1.tar.gz", hash = "sha256:6f9630eb29f3843d19d48c3bd5706a086d36d62016687f9d0efa027ddc2dd08a", size = 115322 } wheels = [ - { url = "https://files.pythonhosted.org/packages/c8/49/42821d55ead7b5a87c8d121edf323cb393d8579f63e933002ade900b784f/rich_toolkit-0.15.1-py3-none-any.whl", hash = "sha256:36a0b1d9a135d26776e4b78f1d5c2655da6e0ef432380b5c6b523c8d8ab97478", size = 29412, upload-time = "2025-09-04T09:28:10.587Z" }, + { url = "https://files.pythonhosted.org/packages/c8/49/42821d55ead7b5a87c8d121edf323cb393d8579f63e933002ade900b784f/rich_toolkit-0.15.1-py3-none-any.whl", hash = "sha256:36a0b1d9a135d26776e4b78f1d5c2655da6e0ef432380b5c6b523c8d8ab97478", size = 29412 }, ] [[package]] name = "rignore" -version = "0.7.1" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/01/1a/4e407524cf97ed42a9c77d3cc31b12dd5fb2ce542f174ff7cf78ea0ca293/rignore-0.7.1.tar.gz", hash = "sha256:67bb99d57d0bab0c473261561f98f118f7c9838a06de222338ed8f2b95ed84b4", size = 15437, upload-time = "2025-10-15T20:59:08.474Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/c2/f8/99145d7ee439db898709b9a7e913d42ed3a6ff679c50a163bae373f07276/rignore-0.7.1-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:cb6c993b22d7c88eeadc4fed2957be688b6c5f98d4a9b86d3a5057f4a17ea5bd", size = 881743, upload-time = "2025-10-15T20:58:09.804Z" }, - { url = "https://files.pythonhosted.org/packages/fa/db/aea84354518a24578c77d8fec2f42c065520b48ba5bded9d8eca9e46fefd/rignore-0.7.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:32da28b0e0434b88134f8d97f22afe6bd1e2a103278a726809e2d8da8426b33f", size = 814397, upload-time = "2025-10-15T20:58:00.071Z" }, - { url = "https://files.pythonhosted.org/packages/12/0b/116afdee4093f0ccd3c4e7b6840d3699ea2a34c1ae6d1dd4d7d9d0adc65b/rignore-0.7.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:401d52a0a1c5eae342b2c7b4091206e1ce70de54e85c8c8f0ea3309765a62d60", size = 893431, upload-time = "2025-10-15T20:56:45.476Z" }, - { url = "https://files.pythonhosted.org/packages/52/b5/66778c7cbb8e2c6f4ca6f2f59067aa01632b913741c4aa46b163dc4c8f8c/rignore-0.7.1-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:9ffcfbef75656243cfdcdd495b0ea0b71980b76af343b1bf3aed61a78db3f145", size = 867220, upload-time = "2025-10-15T20:56:58.931Z" }, - { url = "https://files.pythonhosted.org/packages/6e/da/bdd6de52941391f0056295c6904c45e1f8667df754b17fe880d0a663d941/rignore-0.7.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:0e89efa2ad36a9206ed30219eb1a8783a0722ae8b6d68390ae854e5f5ceab6ff", size = 1169076, upload-time = "2025-10-15T20:57:12.153Z" }, - { url = "https://files.pythonhosted.org/packages/0e/8d/d7d4bfbae28e340a6afe850809a020a31c2364fc0ee8105be4ec0841b20a/rignore-0.7.1-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2f6191d7f52894ee65a879f022329011e31cc41f98739ff184cd3f256a3f0711", size = 937738, upload-time = "2025-10-15T20:57:25.497Z" }, - { url = "https://files.pythonhosted.org/packages/d8/b1/1d3f88aaf3cc6f4e31d1d72eb261eff3418dabd2677c83653b7574e7947a/rignore-0.7.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:873a8e84b4342534b9e283f7c17dc39c295edcdc686dfa395ddca3628316931b", size = 951791, upload-time = "2025-10-15T20:57:49.574Z" }, - { url = "https://files.pythonhosted.org/packages/90/7f/033631f29af972bc4f69e241ab188d21fbc4665ad67879c77bc984009550/rignore-0.7.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:65443a6a5efd184d21538816282c78c4787a8a5f73c243ab87cbbb6f313a623d", size = 977580, upload-time = "2025-10-15T20:57:39.063Z" }, - { url = "https://files.pythonhosted.org/packages/c7/38/6f963926b769365a803ec17d448a4fc9c2dbad9c1a1bf73c28088021c2fc/rignore-0.7.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:d6cafca0b422c0d57ce617fed3831e6639dc151653b98396af919f8eb3ba9e2b", size = 1074486, upload-time = "2025-10-15T20:58:18.505Z" }, - { url = "https://files.pythonhosted.org/packages/74/d2/a1c1e2cd3e43f6433d3ecb8d947e1ed684c261fa2e7b2f6b8827c3bf18d1/rignore-0.7.1-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:1f731b018b5b5a93d7b4a0f4e43e5fcbd6cf25e97cec265392f9dd8d10916e5c", size = 1131024, upload-time = "2025-10-15T20:58:32.075Z" }, - { url = "https://files.pythonhosted.org/packages/93/22/b7dd8312aa98211df1f10a6cd2a3005e72cd4ac5c125fd064c7e58394205/rignore-0.7.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:b3be78b1ab9fa1c0eac822a69a7799a2261ce06e4d548374093c4c64d796d7d8", size = 1109625, upload-time = "2025-10-15T20:58:46.077Z" }, - { url = "https://files.pythonhosted.org/packages/f7/65/dd31859304bd71ad72f71e2bf5f18e6f0043cc75394ead8c0d752ab580ad/rignore-0.7.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:d8c3b77ae1a24b09a6d38e07d180f362e47b970c767d2e22417b03d95685cb9d", size = 1117466, upload-time = "2025-10-15T20:58:59.102Z" }, - { url = "https://files.pythonhosted.org/packages/5f/d7/e83241e1b0a6caef1e37586d5b2edb0227478d038675e4e6e1cd748c08ce/rignore-0.7.1-cp313-cp313-win32.whl", hash = "sha256:c01cc8c5d7099d35a7fd00e174948986d4f2cfb6b7fe2923b0b801b1a4741b37", size = 635266, upload-time = "2025-10-15T20:59:28.782Z" }, - { url = "https://files.pythonhosted.org/packages/95/e5/c2ce66a71cfc44010a238a61339cae7469adc17306025796884672784b4c/rignore-0.7.1-cp313-cp313-win_amd64.whl", hash = "sha256:5dd0de4a7d38a49b9d85f332d129b4ca4a29eef5667d4c7bf503e767cf9e2ec4", size = 718048, upload-time = "2025-10-15T20:59:19.312Z" }, - { url = "https://files.pythonhosted.org/packages/ba/fb/b92aa591e247f6258997163e8b1844c9b799371fbfdfd29533e203df06b9/rignore-0.7.1-cp313-cp313-win_arm64.whl", hash = "sha256:4a4c57b75ec758fb31ad1abab4c77810ea417e9d33bdf2f38cf9e6db556eebcb", size = 647790, upload-time = "2025-10-15T20:59:12.408Z" }, - { url = "https://files.pythonhosted.org/packages/b6/d3/b6c5764d3dcaf47de7f0e408dcb4a1a17d4ce3bb1b0aa9a346e221e3c5a1/rignore-0.7.1-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:abb7df83a41213069195436e9c1a433a6df85c089ce4be406d070a4db0ee3897", size = 892938, upload-time = "2025-10-15T20:56:46.559Z" }, - { url = "https://files.pythonhosted.org/packages/48/6a/4d8ae9af9936a061dacda0d8f638cd63571ff93e4eb28e0159db6c4dc009/rignore-0.7.1-cp313-cp313t-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:30d9c9a93a266d1f384465d626178f49d0da4d1a0cf739f15151cdf2eb500e53", size = 867312, upload-time = "2025-10-15T20:57:00.083Z" }, - { url = "https://files.pythonhosted.org/packages/9b/88/cb243662a0b523b4350db1c7c3adee87004af90e9b26100e84c7e13b93cc/rignore-0.7.1-cp313-cp313t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:7e83c68f557d793b4cc7aac943f3b23631469e1bc5b02e63626d0b008be01cd1", size = 1166871, upload-time = "2025-10-15T20:57:13.618Z" }, - { url = "https://files.pythonhosted.org/packages/f6/0a/da28a3f3e8ab1829180f3a7af5b601b04bab1d833e31a74fee78a2d3f5c3/rignore-0.7.1-cp313-cp313t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:682a6efe3f84af4b1100d4c68f0a345f490af74fd9d18346ebf67da9a3b96b08", size = 937964, upload-time = "2025-10-15T20:57:27.054Z" }, - { url = "https://files.pythonhosted.org/packages/c6/2e/f55d0759c6cf48d8fabc62d8924ce58dca81f5c370c0abdcc7cc8176210d/rignore-0.7.1-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:736b6aa3e3dfda2b1404b6f9a9d6f67e2a89f184179e9e5b629198df7c22f9c6", size = 1073720, upload-time = "2025-10-15T20:58:20.833Z" }, - { url = "https://files.pythonhosted.org/packages/c3/aa/8698caf5eb1824f8cae08cd3a296bc7f6f46e7bb539a4dd60c6a7a9f5ca2/rignore-0.7.1-cp313-cp313t-musllinux_1_2_armv7l.whl", hash = "sha256:eed55292d949e99f29cd4f1ae6ddc2562428a3e74f6f4f6b8658f1d5113ffbd5", size = 1130545, upload-time = "2025-10-15T20:58:33.709Z" }, - { url = "https://files.pythonhosted.org/packages/f5/88/89abacdc122f4a0d069d12ebbd87693253f08f19457b77f030c0c6cba316/rignore-0.7.1-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:93ce054754857e37f15fe6768fd28e5450a52c7bbdb00e215100b092281ed123", size = 1108570, upload-time = "2025-10-15T20:58:47.438Z" }, - { url = "https://files.pythonhosted.org/packages/c9/4b/a815624ff1f2420ff29be1ffa2ea5204a69d9a9738fe5a6638fcd1069347/rignore-0.7.1-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:447004c774083e4f9cddf0aefcb80b12264f23e28c37918fb709917c2aabd00d", size = 1116940, upload-time = "2025-10-15T20:59:00.581Z" }, - { url = "https://files.pythonhosted.org/packages/43/63/3464fe5855fc37689d7bdd7b4b7ea0d008a8a58738bc0d68b0b5fa6dcf28/rignore-0.7.1-cp314-cp314-macosx_10_12_x86_64.whl", hash = "sha256:322ac35f2431dd2e80518200e31af1985689dfa7658003ae40012bf3d3e9f0dd", size = 880536, upload-time = "2025-10-15T20:58:11.286Z" }, - { url = "https://files.pythonhosted.org/packages/63/c3/c37469643baeb04c58db2713dc268f582974c71f3936f7d989610b344fca/rignore-0.7.1-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:2d38e282e4b917fb6108198564b018f90de57bb6209aadf9ff39434d4709a650", size = 814741, upload-time = "2025-10-15T20:58:01.228Z" }, - { url = "https://files.pythonhosted.org/packages/76/6c/57fa917c7515db3b72a9c3a6377dc806282e6db390ace68cda29bd73774e/rignore-0.7.1-cp314-cp314-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:89ad7373ec1e7b519a6f07dbcfca38024ba45f5e44df79ee0da4e4c817648a50", size = 951257, upload-time = "2025-10-15T20:57:50.779Z" }, - { url = "https://files.pythonhosted.org/packages/b6/58/b64fb42d6a73937a93c5f060e2720decde4d2b4a7a27fc3b69e69c397358/rignore-0.7.1-cp314-cp314-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:ff94b215b4fe1d81e45b29dc259145fd8aaf40e7b1057f020890cd12db566e4e", size = 977468, upload-time = "2025-10-15T20:57:40.291Z" }, - { url = "https://files.pythonhosted.org/packages/22/54/5b9e60ad6ea7ef654d2607936be312ce78615e011b3461d4b1d161f031c0/rignore-0.7.1-cp314-cp314-win32.whl", hash = "sha256:f49ecef68b5cb99d1212ebe332cbb2851fb2c93672d3b1d372b0fbf475eeb172", size = 635618, upload-time = "2025-10-15T20:59:29.95Z" }, - { url = "https://files.pythonhosted.org/packages/62/50/67137617cbe3e53cbf34d21dad49e153f731797e07261f3b00572a49e69d/rignore-0.7.1-cp314-cp314-win_amd64.whl", hash = "sha256:3f55593d3bbcae3c108d546e8776e51ecb61d1d79bbb02016acf29d136813835", size = 717951, upload-time = "2025-10-15T20:59:20.519Z" }, - { url = "https://files.pythonhosted.org/packages/77/19/dd556e97354ad541b4f7f113e28503865777d6edd940c147f052dc7b8f04/rignore-0.7.1-cp314-cp314-win_arm64.whl", hash = "sha256:60745773b5278fa5f20232fbfb148d74ad9fb27ae8a5097d3cbd5d7cc922d7f7", size = 647796, upload-time = "2025-10-15T20:59:13.724Z" }, +version = "0.7.6" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/e5/f5/8bed2310abe4ae04b67a38374a4d311dd85220f5d8da56f47ae9361be0b0/rignore-0.7.6.tar.gz", hash = "sha256:00d3546cd793c30cb17921ce674d2c8f3a4b00501cb0e3dd0e82217dbeba2671", size = 57140 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/b7/8a/a4078f6e14932ac7edb171149c481de29969d96ddee3ece5dc4c26f9e0c3/rignore-0.7.6-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:2bdab1d31ec9b4fb1331980ee49ea051c0d7f7bb6baa28b3125ef03cdc48fdaf", size = 883057 }, + { url = "https://files.pythonhosted.org/packages/f9/8f/f8daacd177db4bf7c2223bab41e630c52711f8af9ed279be2058d2fe4982/rignore-0.7.6-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:90f0a00ce0c866c275bf888271f1dc0d2140f29b82fcf33cdbda1e1a6af01010", size = 820150 }, + { url = "https://files.pythonhosted.org/packages/36/31/b65b837e39c3f7064c426754714ac633b66b8c2290978af9d7f513e14aa9/rignore-0.7.6-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c1ad295537041dc2ed4b540fb1a3906bd9ede6ccdad3fe79770cd89e04e3c73c", size = 897406 }, + { url = "https://files.pythonhosted.org/packages/ca/58/1970ce006c427e202ac7c081435719a076c478f07b3a23f469227788dc23/rignore-0.7.6-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:f782dbd3a65a5ac85adfff69e5c6b101285ef3f845c3a3cae56a54bebf9fe116", size = 874050 }, + { url = "https://files.pythonhosted.org/packages/d4/00/eb45db9f90137329072a732273be0d383cb7d7f50ddc8e0bceea34c1dfdf/rignore-0.7.6-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:65cece3b36e5b0826d946494734c0e6aaf5a0337e18ff55b071438efe13d559e", size = 1167835 }, + { url = "https://files.pythonhosted.org/packages/f3/f1/6f1d72ddca41a64eed569680587a1236633587cc9f78136477ae69e2c88a/rignore-0.7.6-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d7e4bb66c13cd7602dc8931822c02dfbbd5252015c750ac5d6152b186f0a8be0", size = 941945 }, + { url = "https://files.pythonhosted.org/packages/48/6f/2f178af1c1a276a065f563ec1e11e7a9e23d4996fd0465516afce4b5c636/rignore-0.7.6-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:297e500c15766e196f68aaaa70e8b6db85fa23fdc075b880d8231fdfba738cd7", size = 959067 }, + { url = "https://files.pythonhosted.org/packages/5b/db/423a81c4c1e173877c7f9b5767dcaf1ab50484a94f60a0b2ed78be3fa765/rignore-0.7.6-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:a07084211a8d35e1a5b1d32b9661a5ed20669970b369df0cf77da3adea3405de", size = 984438 }, + { url = "https://files.pythonhosted.org/packages/31/eb/c4f92cc3f2825d501d3c46a244a671eb737fc1bcf7b05a3ecd34abb3e0d7/rignore-0.7.6-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:181eb2a975a22256a1441a9d2f15eb1292839ea3f05606620bd9e1938302cf79", size = 1078365 }, + { url = "https://files.pythonhosted.org/packages/26/09/99442f02794bd7441bfc8ed1c7319e890449b816a7493b2db0e30af39095/rignore-0.7.6-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:7bbcdc52b5bf9f054b34ce4af5269df5d863d9c2456243338bc193c28022bd7b", size = 1139066 }, + { url = "https://files.pythonhosted.org/packages/2c/88/bcfc21e520bba975410e9419450f4b90a2ac8236b9a80fd8130e87d098af/rignore-0.7.6-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:f2e027a6da21a7c8c0d87553c24ca5cc4364def18d146057862c23a96546238e", size = 1118036 }, + { url = "https://files.pythonhosted.org/packages/e2/25/d37215e4562cda5c13312636393aea0bafe38d54d4e0517520a4cc0753ec/rignore-0.7.6-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:ee4a18b82cbbc648e4aac1510066682fe62beb5dc88e2c67c53a83954e541360", size = 1127550 }, + { url = "https://files.pythonhosted.org/packages/dc/76/a264ab38bfa1620ec12a8ff1c07778da89e16d8c0f3450b0333020d3d6dc/rignore-0.7.6-cp313-cp313-win32.whl", hash = "sha256:a7d7148b6e5e95035d4390396895adc384d37ff4e06781a36fe573bba7c283e5", size = 646097 }, + { url = "https://files.pythonhosted.org/packages/62/44/3c31b8983c29ea8832b6082ddb1d07b90379c2d993bd20fce4487b71b4f4/rignore-0.7.6-cp313-cp313-win_amd64.whl", hash = "sha256:b037c4b15a64dced08fc12310ee844ec2284c4c5c1ca77bc37d0a04f7bff386e", size = 726170 }, + { url = "https://files.pythonhosted.org/packages/aa/41/e26a075cab83debe41a42661262f606166157df84e0e02e2d904d134c0d8/rignore-0.7.6-cp313-cp313-win_arm64.whl", hash = "sha256:e47443de9b12fe569889bdbe020abe0e0b667516ee2ab435443f6d0869bd2804", size = 656184 }, + { url = "https://files.pythonhosted.org/packages/9a/b9/1f5bd82b87e5550cd843ceb3768b4a8ef274eb63f29333cf2f29644b3d75/rignore-0.7.6-cp314-cp314-macosx_10_12_x86_64.whl", hash = "sha256:8e41be9fa8f2f47239ded8920cc283699a052ac4c371f77f5ac017ebeed75732", size = 882632 }, + { url = "https://files.pythonhosted.org/packages/e9/6b/07714a3efe4a8048864e8a5b7db311ba51b921e15268b17defaebf56d3db/rignore-0.7.6-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:6dc1e171e52cefa6c20e60c05394a71165663b48bca6c7666dee4f778f2a7d90", size = 820760 }, + { url = "https://files.pythonhosted.org/packages/ac/0f/348c829ea2d8d596e856371b14b9092f8a5dfbb62674ec9b3f67e4939a9d/rignore-0.7.6-cp314-cp314-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0ce2268837c3600f82ab8db58f5834009dc638ee17103582960da668963bebc5", size = 899044 }, + { url = "https://files.pythonhosted.org/packages/f0/30/2e1841a19b4dd23878d73edd5d82e998a83d5ed9570a89675f140ca8b2ad/rignore-0.7.6-cp314-cp314-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:690a3e1b54bfe77e89c4bacb13f046e642f8baadafc61d68f5a726f324a76ab6", size = 874144 }, + { url = "https://files.pythonhosted.org/packages/c2/bf/0ce9beb2e5f64c30e3580bef09f5829236889f01511a125f98b83169b993/rignore-0.7.6-cp314-cp314-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:09d12ac7a0b6210c07bcd145007117ebd8abe99c8eeb383e9e4673910c2754b2", size = 1168062 }, + { url = "https://files.pythonhosted.org/packages/b9/8b/571c178414eb4014969865317da8a02ce4cf5241a41676ef91a59aab24de/rignore-0.7.6-cp314-cp314-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2a2b2b74a8c60203b08452479b90e5ce3dbe96a916214bc9eb2e5af0b6a9beb0", size = 942542 }, + { url = "https://files.pythonhosted.org/packages/19/62/7a3cf601d5a45137a7e2b89d10c05b5b86499190c4b7ca5c3c47d79ee519/rignore-0.7.6-cp314-cp314-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8fc5a531ef02131e44359419a366bfac57f773ea58f5278c2cdd915f7d10ea94", size = 958739 }, + { url = "https://files.pythonhosted.org/packages/5f/1f/4261f6a0d7caf2058a5cde2f5045f565ab91aa7badc972b57d19ce58b14e/rignore-0.7.6-cp314-cp314-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:b7a1f77d9c4cd7e76229e252614d963442686bfe12c787a49f4fe481df49e7a9", size = 984138 }, + { url = "https://files.pythonhosted.org/packages/2b/bf/628dfe19c75e8ce1f45f7c248f5148b17dfa89a817f8e3552ab74c3ae812/rignore-0.7.6-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:ead81f728682ba72b5b1c3d5846b011d3e0174da978de87c61645f2ed36659a7", size = 1079299 }, + { url = "https://files.pythonhosted.org/packages/af/a5/be29c50f5c0c25c637ed32db8758fdf5b901a99e08b608971cda8afb293b/rignore-0.7.6-cp314-cp314-musllinux_1_2_armv7l.whl", hash = "sha256:12ffd50f520c22ffdabed8cd8bfb567d9ac165b2b854d3e679f4bcaef11a9441", size = 1139618 }, + { url = "https://files.pythonhosted.org/packages/2a/40/3c46cd7ce4fa05c20b525fd60f599165e820af66e66f2c371cd50644558f/rignore-0.7.6-cp314-cp314-musllinux_1_2_i686.whl", hash = "sha256:e5a16890fbe3c894f8ca34b0fcacc2c200398d4d46ae654e03bc9b3dbf2a0a72", size = 1117626 }, + { url = "https://files.pythonhosted.org/packages/8c/b9/aea926f263b8a29a23c75c2e0d8447965eb1879d3feb53cfcf84db67ed58/rignore-0.7.6-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:3abab3bf99e8a77488ef6c7c9a799fac22224c28fe9f25cc21aa7cc2b72bfc0b", size = 1128144 }, + { url = "https://files.pythonhosted.org/packages/a4/f6/0d6242f8d0df7f2ecbe91679fefc1f75e7cd2072cb4f497abaab3f0f8523/rignore-0.7.6-cp314-cp314-win32.whl", hash = "sha256:eeef421c1782953c4375aa32f06ecae470c1285c6381eee2a30d2e02a5633001", size = 646385 }, + { url = "https://files.pythonhosted.org/packages/d5/38/c0dcd7b10064f084343d6af26fe9414e46e9619c5f3224b5272e8e5d9956/rignore-0.7.6-cp314-cp314-win_amd64.whl", hash = "sha256:6aeed503b3b3d5af939b21d72a82521701a4bd3b89cd761da1e7dc78621af304", size = 725738 }, + { url = "https://files.pythonhosted.org/packages/d9/7a/290f868296c1ece914d565757ab363b04730a728b544beb567ceb3b2d96f/rignore-0.7.6-cp314-cp314-win_arm64.whl", hash = "sha256:104f215b60b3c984c386c3e747d6ab4376d5656478694e22c7bd2f788ddd8304", size = 656008 }, + { url = "https://files.pythonhosted.org/packages/ca/d2/3c74e3cd81fe8ea08a8dcd2d755c09ac2e8ad8fe409508904557b58383d3/rignore-0.7.6-cp314-cp314t-macosx_10_12_x86_64.whl", hash = "sha256:bb24a5b947656dd94cb9e41c4bc8b23cec0c435b58be0d74a874f63c259549e8", size = 882835 }, + { url = "https://files.pythonhosted.org/packages/77/61/a772a34b6b63154877433ac2d048364815b24c2dd308f76b212c408101a2/rignore-0.7.6-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:5b1e33c9501cefe24b70a1eafd9821acfd0ebf0b35c3a379430a14df089993e3", size = 820301 }, + { url = "https://files.pythonhosted.org/packages/71/30/054880b09c0b1b61d17eeb15279d8bf729c0ba52b36c3ada52fb827cbb3c/rignore-0.7.6-cp314-cp314t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bec3994665a44454df86deb762061e05cd4b61e3772f5b07d1882a8a0d2748d5", size = 897611 }, + { url = "https://files.pythonhosted.org/packages/1e/40/b2d1c169f833d69931bf232600eaa3c7998ba4f9a402e43a822dad2ea9f2/rignore-0.7.6-cp314-cp314t-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:26cba2edfe3cff1dfa72bddf65d316ddebf182f011f2f61538705d6dbaf54986", size = 873875 }, + { url = "https://files.pythonhosted.org/packages/55/59/ca5ae93d83a1a60e44b21d87deb48b177a8db1b85e82fc8a9abb24a8986d/rignore-0.7.6-cp314-cp314t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ffa86694fec604c613696cb91e43892aa22e1fec5f9870e48f111c603e5ec4e9", size = 1167245 }, + { url = "https://files.pythonhosted.org/packages/a5/52/cf3dce392ba2af806cba265aad6bcd9c48bb2a6cb5eee448d3319f6e505b/rignore-0.7.6-cp314-cp314t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:48efe2ed95aa8104145004afb15cdfa02bea5cdde8b0344afeb0434f0d989aa2", size = 941750 }, + { url = "https://files.pythonhosted.org/packages/ec/be/3f344c6218d779395e785091d05396dfd8b625f6aafbe502746fcd880af2/rignore-0.7.6-cp314-cp314t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8dcae43eb44b7f2457fef7cc87f103f9a0013017a6f4e62182c565e924948f21", size = 958896 }, + { url = "https://files.pythonhosted.org/packages/c9/34/d3fa71938aed7d00dcad87f0f9bcb02ad66c85d6ffc83ba31078ce53646a/rignore-0.7.6-cp314-cp314t-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:2cd649a7091c0dad2f11ef65630d30c698d505cbe8660dd395268e7c099cc99f", size = 983992 }, + { url = "https://files.pythonhosted.org/packages/24/a4/52a697158e9920705bdbd0748d59fa63e0f3233fb92e9df9a71afbead6ca/rignore-0.7.6-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:42de84b0289d478d30ceb7ae59023f7b0527786a9a5b490830e080f0e4ea5aeb", size = 1078181 }, + { url = "https://files.pythonhosted.org/packages/ac/65/aa76dbcdabf3787a6f0fd61b5cc8ed1e88580590556d6c0207960d2384bb/rignore-0.7.6-cp314-cp314t-musllinux_1_2_armv7l.whl", hash = "sha256:875a617e57b53b4acbc5a91de418233849711c02e29cc1f4f9febb2f928af013", size = 1139232 }, + { url = "https://files.pythonhosted.org/packages/08/44/31b31a49b3233c6842acc1c0731aa1e7fb322a7170612acf30327f700b44/rignore-0.7.6-cp314-cp314t-musllinux_1_2_i686.whl", hash = "sha256:8703998902771e96e49968105207719f22926e4431b108450f3f430b4e268b7c", size = 1117349 }, + { url = "https://files.pythonhosted.org/packages/e9/ae/1b199a2302c19c658cf74e5ee1427605234e8c91787cfba0015f2ace145b/rignore-0.7.6-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:602ef33f3e1b04c1e9a10a3c03f8bc3cef2d2383dcc250d309be42b49923cabc", size = 1127702 }, + { url = "https://files.pythonhosted.org/packages/fc/d3/18210222b37e87e36357f7b300b7d98c6dd62b133771e71ae27acba83a4f/rignore-0.7.6-cp314-cp314t-win32.whl", hash = "sha256:c1d8f117f7da0a4a96a8daef3da75bc090e3792d30b8b12cfadc240c631353f9", size = 647033 }, + { url = "https://files.pythonhosted.org/packages/3e/87/033eebfbee3ec7d92b3bb1717d8f68c88e6fc7de54537040f3b3a405726f/rignore-0.7.6-cp314-cp314t-win_amd64.whl", hash = "sha256:ca36e59408bec81de75d307c568c2d0d410fb880b1769be43611472c61e85c96", size = 725647 }, + { url = "https://files.pythonhosted.org/packages/79/62/b88e5879512c55b8ee979c666ee6902adc4ed05007226de266410ae27965/rignore-0.7.6-cp314-cp314t-win_arm64.whl", hash = "sha256:b83adabeb3e8cf662cabe1931b83e165b88c526fa6af6b3aa90429686e474896", size = 656035 }, ] [[package]] @@ -1951,35 +2039,35 @@ source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "pyasn1" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/da/8a/22b7beea3ee0d44b1916c0c1cb0ee3af23b700b6da9f04991899d0c555d4/rsa-4.9.1.tar.gz", hash = "sha256:e7bdbfdb5497da4c07dfd35530e1a902659db6ff241e39d9953cad06ebd0ae75", size = 29034, upload-time = "2025-04-16T09:51:18.218Z" } +sdist = { url = "https://files.pythonhosted.org/packages/da/8a/22b7beea3ee0d44b1916c0c1cb0ee3af23b700b6da9f04991899d0c555d4/rsa-4.9.1.tar.gz", hash = "sha256:e7bdbfdb5497da4c07dfd35530e1a902659db6ff241e39d9953cad06ebd0ae75", size = 29034 } wheels = [ - { url = "https://files.pythonhosted.org/packages/64/8d/0133e4eb4beed9e425d9a98ed6e081a55d195481b7632472be1af08d2f6b/rsa-4.9.1-py3-none-any.whl", hash = "sha256:68635866661c6836b8d39430f97a996acbd61bfa49406748ea243539fe239762", size = 34696, upload-time = "2025-04-16T09:51:17.142Z" }, + { url = "https://files.pythonhosted.org/packages/64/8d/0133e4eb4beed9e425d9a98ed6e081a55d195481b7632472be1af08d2f6b/rsa-4.9.1-py3-none-any.whl", hash = "sha256:68635866661c6836b8d39430f97a996acbd61bfa49406748ea243539fe239762", size = 34696 }, ] [[package]] name = "ruff" -version = "0.14.1" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/9e/58/6ca66896635352812de66f71cdf9ff86b3a4f79071ca5730088c0cd0fc8d/ruff-0.14.1.tar.gz", hash = "sha256:1dd86253060c4772867c61791588627320abcb6ed1577a90ef432ee319729b69", size = 5513429, upload-time = "2025-10-16T18:05:41.766Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/8d/39/9cc5ab181478d7a18adc1c1e051a84ee02bec94eb9bdfd35643d7c74ca31/ruff-0.14.1-py3-none-linux_armv6l.whl", hash = "sha256:083bfc1f30f4a391ae09c6f4f99d83074416b471775b59288956f5bc18e82f8b", size = 12445415, upload-time = "2025-10-16T18:04:48.227Z" }, - { url = "https://files.pythonhosted.org/packages/ef/2e/1226961855ccd697255988f5a2474890ac7c5863b080b15bd038df820818/ruff-0.14.1-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:f6fa757cd717f791009f7669fefb09121cc5f7d9bd0ef211371fad68c2b8b224", size = 12784267, upload-time = "2025-10-16T18:04:52.515Z" }, - { url = "https://files.pythonhosted.org/packages/c1/ea/fd9e95863124ed159cd0667ec98449ae461de94acda7101f1acb6066da00/ruff-0.14.1-py3-none-macosx_11_0_arm64.whl", hash = "sha256:d6191903d39ac156921398e9c86b7354d15e3c93772e7dbf26c9fcae59ceccd5", size = 11781872, upload-time = "2025-10-16T18:04:55.396Z" }, - { url = "https://files.pythonhosted.org/packages/1e/5a/e890f7338ff537dba4589a5e02c51baa63020acfb7c8cbbaea4831562c96/ruff-0.14.1-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ed04f0e04f7a4587244e5c9d7df50e6b5bf2705d75059f409a6421c593a35896", size = 12226558, upload-time = "2025-10-16T18:04:58.166Z" }, - { url = "https://files.pythonhosted.org/packages/a6/7a/8ab5c3377f5bf31e167b73651841217542bcc7aa1c19e83030835cc25204/ruff-0.14.1-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:5c9e6cf6cd4acae0febbce29497accd3632fe2025c0c583c8b87e8dbdeae5f61", size = 12187898, upload-time = "2025-10-16T18:05:01.455Z" }, - { url = "https://files.pythonhosted.org/packages/48/8d/ba7c33aa55406955fc124e62c8259791c3d42e3075a71710fdff9375134f/ruff-0.14.1-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a6fa2458527794ecdfbe45f654e42c61f2503a230545a91af839653a0a93dbc6", size = 12939168, upload-time = "2025-10-16T18:05:04.397Z" }, - { url = "https://files.pythonhosted.org/packages/b4/c2/70783f612b50f66d083380e68cbd1696739d88e9b4f6164230375532c637/ruff-0.14.1-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:39f1c392244e338b21d42ab29b8a6392a722c5090032eb49bb4d6defcdb34345", size = 14386942, upload-time = "2025-10-16T18:05:07.102Z" }, - { url = "https://files.pythonhosted.org/packages/48/44/cd7abb9c776b66d332119d67f96acf15830d120f5b884598a36d9d3f4d83/ruff-0.14.1-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:7382fa12a26cce1f95070ce450946bec357727aaa428983036362579eadcc5cf", size = 13990622, upload-time = "2025-10-16T18:05:09.882Z" }, - { url = "https://files.pythonhosted.org/packages/eb/56/4259b696db12ac152fe472764b4f78bbdd9b477afd9bc3a6d53c01300b37/ruff-0.14.1-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:dd0bf2be3ae8521e1093a487c4aa3b455882f139787770698530d28ed3fbb37c", size = 13431143, upload-time = "2025-10-16T18:05:13.46Z" }, - { url = "https://files.pythonhosted.org/packages/e0/35/266a80d0eb97bd224b3265b9437bd89dde0dcf4faf299db1212e81824e7e/ruff-0.14.1-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cabcaa9ccf8089fb4fdb78d17cc0e28241520f50f4c2e88cb6261ed083d85151", size = 13132844, upload-time = "2025-10-16T18:05:16.1Z" }, - { url = "https://files.pythonhosted.org/packages/65/6e/d31ce218acc11a8d91ef208e002a31acf315061a85132f94f3df7a252b18/ruff-0.14.1-py3-none-manylinux_2_31_riscv64.whl", hash = "sha256:747d583400f6125ec11a4c14d1c8474bf75d8b419ad22a111a537ec1a952d192", size = 13401241, upload-time = "2025-10-16T18:05:19.395Z" }, - { url = "https://files.pythonhosted.org/packages/9f/b5/dbc4221bf0b03774b3b2f0d47f39e848d30664157c15b965a14d890637d2/ruff-0.14.1-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:5a6e74c0efd78515a1d13acbfe6c90f0f5bd822aa56b4a6d43a9ffb2ae6e56cd", size = 12132476, upload-time = "2025-10-16T18:05:22.163Z" }, - { url = "https://files.pythonhosted.org/packages/98/4b/ac99194e790ccd092d6a8b5f341f34b6e597d698e3077c032c502d75ea84/ruff-0.14.1-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:0ea6a864d2fb41a4b6d5b456ed164302a0d96f4daac630aeba829abfb059d020", size = 12139749, upload-time = "2025-10-16T18:05:25.162Z" }, - { url = "https://files.pythonhosted.org/packages/47/26/7df917462c3bb5004e6fdfcc505a49e90bcd8a34c54a051953118c00b53a/ruff-0.14.1-py3-none-musllinux_1_2_i686.whl", hash = "sha256:0826b8764f94229604fa255918d1cc45e583e38c21c203248b0bfc9a0e930be5", size = 12544758, upload-time = "2025-10-16T18:05:28.018Z" }, - { url = "https://files.pythonhosted.org/packages/64/d0/81e7f0648e9764ad9b51dd4be5e5dac3fcfff9602428ccbae288a39c2c22/ruff-0.14.1-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:cbc52160465913a1a3f424c81c62ac8096b6a491468e7d872cb9444a860bc33d", size = 13221811, upload-time = "2025-10-16T18:05:30.707Z" }, - { url = "https://files.pythonhosted.org/packages/c3/07/3c45562c67933cc35f6d5df4ca77dabbcd88fddaca0d6b8371693d29fd56/ruff-0.14.1-py3-none-win32.whl", hash = "sha256:e037ea374aaaff4103240ae79168c0945ae3d5ae8db190603de3b4012bd1def6", size = 12319467, upload-time = "2025-10-16T18:05:33.261Z" }, - { url = "https://files.pythonhosted.org/packages/02/88/0ee4ca507d4aa05f67e292d2e5eb0b3e358fbcfe527554a2eda9ac422d6b/ruff-0.14.1-py3-none-win_amd64.whl", hash = "sha256:59d599cdff9c7f925a017f6f2c256c908b094e55967f93f2821b1439928746a1", size = 13401123, upload-time = "2025-10-16T18:05:35.984Z" }, - { url = "https://files.pythonhosted.org/packages/b8/81/4b6387be7014858d924b843530e1b2a8e531846807516e9bea2ee0936bf7/ruff-0.14.1-py3-none-win_arm64.whl", hash = "sha256:e3b443c4c9f16ae850906b8d0a707b2a4c16f8d2f0a7fe65c475c5886665ce44", size = 12436636, upload-time = "2025-10-16T18:05:38.995Z" }, +version = "0.14.4" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/df/55/cccfca45157a2031dcbb5a462a67f7cf27f8b37d4b3b1cd7438f0f5c1df6/ruff-0.14.4.tar.gz", hash = "sha256:f459a49fe1085a749f15414ca76f61595f1a2cc8778ed7c279b6ca2e1fd19df3", size = 5587844 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/17/b9/67240254166ae1eaa38dec32265e9153ac53645a6c6670ed36ad00722af8/ruff-0.14.4-py3-none-linux_armv6l.whl", hash = "sha256:e6604613ffbcf2297cd5dcba0e0ac9bd0c11dc026442dfbb614504e87c349518", size = 12606781 }, + { url = "https://files.pythonhosted.org/packages/46/c8/09b3ab245d8652eafe5256ab59718641429f68681ee713ff06c5c549f156/ruff-0.14.4-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:d99c0b52b6f0598acede45ee78288e5e9b4409d1ce7f661f0fa36d4cbeadf9a4", size = 12946765 }, + { url = "https://files.pythonhosted.org/packages/14/bb/1564b000219144bf5eed2359edc94c3590dd49d510751dad26202c18a17d/ruff-0.14.4-py3-none-macosx_11_0_arm64.whl", hash = "sha256:9358d490ec030f1b51d048a7fd6ead418ed0826daf6149e95e30aa67c168af33", size = 11928120 }, + { url = "https://files.pythonhosted.org/packages/a3/92/d5f1770e9988cc0742fefaa351e840d9aef04ec24ae1be36f333f96d5704/ruff-0.14.4-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:81b40d27924f1f02dfa827b9c0712a13c0e4b108421665322218fc38caf615c2", size = 12370877 }, + { url = "https://files.pythonhosted.org/packages/e2/29/e9282efa55f1973d109faf839a63235575519c8ad278cc87a182a366810e/ruff-0.14.4-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:f5e649052a294fe00818650712083cddc6cc02744afaf37202c65df9ea52efa5", size = 12408538 }, + { url = "https://files.pythonhosted.org/packages/8e/01/930ed6ecfce130144b32d77d8d69f5c610e6d23e6857927150adf5d7379a/ruff-0.14.4-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:aa082a8f878deeba955531f975881828fd6afd90dfa757c2b0808aadb437136e", size = 13141942 }, + { url = "https://files.pythonhosted.org/packages/6a/46/a9c89b42b231a9f487233f17a89cbef9d5acd538d9488687a02ad288fa6b/ruff-0.14.4-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:1043c6811c2419e39011890f14d0a30470f19d47d197c4858b2787dfa698f6c8", size = 14544306 }, + { url = "https://files.pythonhosted.org/packages/78/96/9c6cf86491f2a6d52758b830b89b78c2ae61e8ca66b86bf5a20af73d20e6/ruff-0.14.4-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a9f3a936ac27fb7c2a93e4f4b943a662775879ac579a433291a6f69428722649", size = 14210427 }, + { url = "https://files.pythonhosted.org/packages/71/f4/0666fe7769a54f63e66404e8ff698de1dcde733e12e2fd1c9c6efb689cb5/ruff-0.14.4-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:95643ffd209ce78bc113266b88fba3d39e0461f0cbc8b55fb92505030fb4a850", size = 13658488 }, + { url = "https://files.pythonhosted.org/packages/ee/79/6ad4dda2cfd55e41ac9ed6d73ef9ab9475b1eef69f3a85957210c74ba12c/ruff-0.14.4-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:456daa2fa1021bc86ca857f43fe29d5d8b3f0e55e9f90c58c317c1dcc2afc7b5", size = 13354908 }, + { url = "https://files.pythonhosted.org/packages/b5/60/f0b6990f740bb15c1588601d19d21bcc1bd5de4330a07222041678a8e04f/ruff-0.14.4-py3-none-manylinux_2_31_riscv64.whl", hash = "sha256:f911bba769e4a9f51af6e70037bb72b70b45a16db5ce73e1f72aefe6f6d62132", size = 13587803 }, + { url = "https://files.pythonhosted.org/packages/c9/da/eaaada586f80068728338e0ef7f29ab3e4a08a692f92eb901a4f06bbff24/ruff-0.14.4-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:76158a7369b3979fa878612c623a7e5430c18b2fd1c73b214945c2d06337db67", size = 12279654 }, + { url = "https://files.pythonhosted.org/packages/66/d4/b1d0e82cf9bf8aed10a6d45be47b3f402730aa2c438164424783ac88c0ed/ruff-0.14.4-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:f3b8f3b442d2b14c246e7aeca2e75915159e06a3540e2f4bed9f50d062d24469", size = 12357520 }, + { url = "https://files.pythonhosted.org/packages/04/f4/53e2b42cc82804617e5c7950b7079d79996c27e99c4652131c6a1100657f/ruff-0.14.4-py3-none-musllinux_1_2_i686.whl", hash = "sha256:c62da9a06779deecf4d17ed04939ae8b31b517643b26370c3be1d26f3ef7dbde", size = 12719431 }, + { url = "https://files.pythonhosted.org/packages/a2/94/80e3d74ed9a72d64e94a7b7706b1c1ebaa315ef2076fd33581f6a1cd2f95/ruff-0.14.4-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:5a443a83a1506c684e98acb8cb55abaf3ef725078be40237463dae4463366349", size = 13464394 }, + { url = "https://files.pythonhosted.org/packages/54/1a/a49f071f04c42345c793d22f6cf5e0920095e286119ee53a64a3a3004825/ruff-0.14.4-py3-none-win32.whl", hash = "sha256:643b69cb63cd996f1fc7229da726d07ac307eae442dd8974dbc7cf22c1e18fff", size = 12493429 }, + { url = "https://files.pythonhosted.org/packages/bc/22/e58c43e641145a2b670328fb98bc384e20679b5774258b1e540207580266/ruff-0.14.4-py3-none-win_amd64.whl", hash = "sha256:26673da283b96fe35fa0c939bf8411abec47111644aa9f7cfbd3c573fb125d2c", size = 13635380 }, + { url = "https://files.pythonhosted.org/packages/30/bd/4168a751ddbbf43e86544b4de8b5c3b7be8d7167a2a5cb977d274e04f0a1/ruff-0.14.4-py3-none-win_arm64.whl", hash = "sha256:dd09c292479596b0e6fec8cd95c65c3a6dc68e9ad17b8f2382130f87ff6a75bb", size = 12663065 }, ] [[package]] @@ -1989,58 +2077,58 @@ source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "botocore" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/62/74/8d69dcb7a9efe8baa2046891735e5dfe433ad558ae23d9e3c14c633d1d58/s3transfer-0.14.0.tar.gz", hash = "sha256:eff12264e7c8b4985074ccce27a3b38a485bb7f7422cc8046fee9be4983e4125", size = 151547, upload-time = "2025-09-09T19:23:31.089Z" } +sdist = { url = "https://files.pythonhosted.org/packages/62/74/8d69dcb7a9efe8baa2046891735e5dfe433ad558ae23d9e3c14c633d1d58/s3transfer-0.14.0.tar.gz", hash = "sha256:eff12264e7c8b4985074ccce27a3b38a485bb7f7422cc8046fee9be4983e4125", size = 151547 } wheels = [ - { url = "https://files.pythonhosted.org/packages/48/f0/ae7ca09223a81a1d890b2557186ea015f6e0502e9b8cb8e1813f1d8cfa4e/s3transfer-0.14.0-py3-none-any.whl", hash = "sha256:ea3b790c7077558ed1f02a3072fb3cb992bbbd253392f4b6e9e8976941c7d456", size = 85712, upload-time = "2025-09-09T19:23:30.041Z" }, + { url = "https://files.pythonhosted.org/packages/48/f0/ae7ca09223a81a1d890b2557186ea015f6e0502e9b8cb8e1813f1d8cfa4e/s3transfer-0.14.0-py3-none-any.whl", hash = "sha256:ea3b790c7077558ed1f02a3072fb3cb992bbbd253392f4b6e9e8976941c7d456", size = 85712 }, ] [[package]] name = "sentry-sdk" -version = "2.42.1" +version = "2.43.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "certifi" }, { name = "urllib3" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/31/04/ec8c1dd9250847303d98516e917978cb1c7083024770d86d657d2ccb5a70/sentry_sdk-2.42.1.tar.gz", hash = "sha256:8598cc6edcfe74cb8074ba6a7c15338cdee93d63d3eb9b9943b4b568354ad5b6", size = 354839, upload-time = "2025-10-20T12:38:40.45Z" } +sdist = { url = "https://files.pythonhosted.org/packages/b3/18/09875b4323b03ca9025bae7e6539797b27e4fc032998a466b4b9c3d24653/sentry_sdk-2.43.0.tar.gz", hash = "sha256:52ed6e251c5d2c084224d73efee56b007ef5c2d408a4a071270e82131d336e20", size = 368953 } wheels = [ - { url = "https://files.pythonhosted.org/packages/0f/cb/c21b96ff379923310b4fb2c06e8d560d801e24aeb300faa72a04776868fc/sentry_sdk-2.42.1-py2.py3-none-any.whl", hash = "sha256:f8716b50c927d3beb41bc88439dc6bcd872237b596df5b14613e2ade104aee02", size = 380952, upload-time = "2025-10-20T12:38:38.88Z" }, + { url = "https://files.pythonhosted.org/packages/69/31/8228fa962f7fd8814d634e4ebece8780e2cdcfbdf0cd2e14d4a6861a7cd5/sentry_sdk-2.43.0-py2.py3-none-any.whl", hash = "sha256:4aacafcf1756ef066d359ae35030881917160ba7f6fc3ae11e0e58b09edc2d5d", size = 400997 }, ] [[package]] name = "shellingham" version = "1.5.4" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/58/15/8b3609fd3830ef7b27b655beb4b4e9c62313a4e8da8c676e142cc210d58e/shellingham-1.5.4.tar.gz", hash = "sha256:8dbca0739d487e5bd35ab3ca4b36e11c4078f3a234bfce294b0a0291363404de", size = 10310, upload-time = "2023-10-24T04:13:40.426Z" } +sdist = { url = "https://files.pythonhosted.org/packages/58/15/8b3609fd3830ef7b27b655beb4b4e9c62313a4e8da8c676e142cc210d58e/shellingham-1.5.4.tar.gz", hash = "sha256:8dbca0739d487e5bd35ab3ca4b36e11c4078f3a234bfce294b0a0291363404de", size = 10310 } wheels = [ - { url = "https://files.pythonhosted.org/packages/e0/f9/0595336914c5619e5f28a1fb793285925a8cd4b432c9da0a987836c7f822/shellingham-1.5.4-py2.py3-none-any.whl", hash = "sha256:7ecfff8f2fd72616f7481040475a65b2bf8af90a56c89140852d1120324e8686", size = 9755, upload-time = "2023-10-24T04:13:38.866Z" }, + { url = "https://files.pythonhosted.org/packages/e0/f9/0595336914c5619e5f28a1fb793285925a8cd4b432c9da0a987836c7f822/shellingham-1.5.4-py2.py3-none-any.whl", hash = "sha256:7ecfff8f2fd72616f7481040475a65b2bf8af90a56c89140852d1120324e8686", size = 9755 }, ] [[package]] name = "six" version = "1.17.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/94/e7/b2c673351809dca68a0e064b6af791aa332cf192da575fd474ed7d6f16a2/six-1.17.0.tar.gz", hash = "sha256:ff70335d468e7eb6ec65b95b99d3a2836546063f63acc5171de367e834932a81", size = 34031, upload-time = "2024-12-04T17:35:28.174Z" } +sdist = { url = "https://files.pythonhosted.org/packages/94/e7/b2c673351809dca68a0e064b6af791aa332cf192da575fd474ed7d6f16a2/six-1.17.0.tar.gz", hash = "sha256:ff70335d468e7eb6ec65b95b99d3a2836546063f63acc5171de367e834932a81", size = 34031 } wheels = [ - { url = "https://files.pythonhosted.org/packages/b7/ce/149a00dd41f10bc29e5921b496af8b574d8413afcd5e30dfa0ed46c2cc5e/six-1.17.0-py2.py3-none-any.whl", hash = "sha256:4721f391ed90541fddacab5acf947aa0d3dc7d27b2e1e8eda2be8970586c3274", size = 11050, upload-time = "2024-12-04T17:35:26.475Z" }, + { url = "https://files.pythonhosted.org/packages/b7/ce/149a00dd41f10bc29e5921b496af8b574d8413afcd5e30dfa0ed46c2cc5e/six-1.17.0-py2.py3-none-any.whl", hash = "sha256:4721f391ed90541fddacab5acf947aa0d3dc7d27b2e1e8eda2be8970586c3274", size = 11050 }, ] [[package]] name = "sniffio" version = "1.3.1" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/a2/87/a6771e1546d97e7e041b6ae58d80074f81b7d5121207425c964ddf5cfdbd/sniffio-1.3.1.tar.gz", hash = "sha256:f4324edc670a0f49750a81b895f35c3adb843cca46f0530f79fc1babb23789dc", size = 20372, upload-time = "2024-02-25T23:20:04.057Z" } +sdist = { url = "https://files.pythonhosted.org/packages/a2/87/a6771e1546d97e7e041b6ae58d80074f81b7d5121207425c964ddf5cfdbd/sniffio-1.3.1.tar.gz", hash = "sha256:f4324edc670a0f49750a81b895f35c3adb843cca46f0530f79fc1babb23789dc", size = 20372 } wheels = [ - { url = "https://files.pythonhosted.org/packages/e9/44/75a9c9421471a6c4805dbf2356f7c181a29c1879239abab1ea2cc8f38b40/sniffio-1.3.1-py3-none-any.whl", hash = "sha256:2f6da418d1f1e0fddd844478f41680e794e6051915791a034ff65e5f100525a2", size = 10235, upload-time = "2024-02-25T23:20:01.196Z" }, + { url = "https://files.pythonhosted.org/packages/e9/44/75a9c9421471a6c4805dbf2356f7c181a29c1879239abab1ea2cc8f38b40/sniffio-1.3.1-py3-none-any.whl", hash = "sha256:2f6da418d1f1e0fddd844478f41680e794e6051915791a034ff65e5f100525a2", size = 10235 }, ] [[package]] name = "soupsieve" version = "2.8" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/6d/e6/21ccce3262dd4889aa3332e5a119a3491a95e8f60939870a3a035aabac0d/soupsieve-2.8.tar.gz", hash = "sha256:e2dd4a40a628cb5f28f6d4b0db8800b8f581b65bb380b97de22ba5ca8d72572f", size = 103472, upload-time = "2025-08-27T15:39:51.78Z" } +sdist = { url = "https://files.pythonhosted.org/packages/6d/e6/21ccce3262dd4889aa3332e5a119a3491a95e8f60939870a3a035aabac0d/soupsieve-2.8.tar.gz", hash = "sha256:e2dd4a40a628cb5f28f6d4b0db8800b8f581b65bb380b97de22ba5ca8d72572f", size = 103472 } wheels = [ - { url = "https://files.pythonhosted.org/packages/14/a0/bb38d3b76b8cae341dad93a2dd83ab7462e6dbcdd84d43f54ee60a8dc167/soupsieve-2.8-py3-none-any.whl", hash = "sha256:0cc76456a30e20f5d7f2e14a98a4ae2ee4e5abdc7c5ea0aafe795f344bc7984c", size = 36679, upload-time = "2025-08-27T15:39:50.179Z" }, + { url = "https://files.pythonhosted.org/packages/14/a0/bb38d3b76b8cae341dad93a2dd83ab7462e6dbcdd84d43f54ee60a8dc167/soupsieve-2.8-py3-none-any.whl", hash = "sha256:0cc76456a30e20f5d7f2e14a98a4ae2ee4e5abdc7c5ea0aafe795f344bc7984c", size = 36679 }, ] [[package]] @@ -2054,9 +2142,9 @@ dependencies = [ { name = "starlette" }, { name = "wtforms" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/5b/0c/614041e1b544e0de1f43b58f0105b3e2795b80369d5b0ff7412882d42fff/sqladmin-0.21.0.tar.gz", hash = "sha256:cb455b79eb79ef7d904680dd83817bf7750675147400b5b7cc401d04bda7ef2c", size = 1428312, upload-time = "2025-07-02T09:41:21.207Z" } +sdist = { url = "https://files.pythonhosted.org/packages/5b/0c/614041e1b544e0de1f43b58f0105b3e2795b80369d5b0ff7412882d42fff/sqladmin-0.21.0.tar.gz", hash = "sha256:cb455b79eb79ef7d904680dd83817bf7750675147400b5b7cc401d04bda7ef2c", size = 1428312 } wheels = [ - { url = "https://files.pythonhosted.org/packages/ed/8d/81b2a48cc6f5479cb1148292518e3006ec8f5fbe3b0829ef165984e9d7b9/sqladmin-0.21.0-py3-none-any.whl", hash = "sha256:2b1802c49bdd3128c6452625705693cf32d5d33e7db30e63f409bd20a9c05b53", size = 1443585, upload-time = "2025-07-02T09:41:19.205Z" }, + { url = "https://files.pythonhosted.org/packages/ed/8d/81b2a48cc6f5479cb1148292518e3006ec8f5fbe3b0829ef165984e9d7b9/sqladmin-0.21.0-py3-none-any.whl", hash = "sha256:2b1802c49bdd3128c6452625705693cf32d5d33e7db30e63f409bd20a9c05b53", size = 1443585 }, ] [[package]] @@ -2067,17 +2155,17 @@ dependencies = [ { name = "greenlet", marker = "platform_machine == 'AMD64' or platform_machine == 'WIN32' or platform_machine == 'aarch64' or platform_machine == 'amd64' or platform_machine == 'ppc64le' or platform_machine == 'win32' or platform_machine == 'x86_64'" }, { name = "typing-extensions" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/f0/f2/840d7b9496825333f532d2e3976b8eadbf52034178aac53630d09fe6e1ef/sqlalchemy-2.0.44.tar.gz", hash = "sha256:0ae7454e1ab1d780aee69fd2aae7d6b8670a581d8847f2d1e0f7ddfbf47e5a22", size = 9819830, upload-time = "2025-10-10T14:39:12.935Z" } +sdist = { url = "https://files.pythonhosted.org/packages/f0/f2/840d7b9496825333f532d2e3976b8eadbf52034178aac53630d09fe6e1ef/sqlalchemy-2.0.44.tar.gz", hash = "sha256:0ae7454e1ab1d780aee69fd2aae7d6b8670a581d8847f2d1e0f7ddfbf47e5a22", size = 9819830 } wheels = [ - { url = "https://files.pythonhosted.org/packages/45/d3/c67077a2249fdb455246e6853166360054c331db4613cda3e31ab1cadbef/sqlalchemy-2.0.44-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:ff486e183d151e51b1d694c7aa1695747599bb00b9f5f604092b54b74c64a8e1", size = 2135479, upload-time = "2025-10-10T16:03:37.671Z" }, - { url = "https://files.pythonhosted.org/packages/2b/91/eabd0688330d6fd114f5f12c4f89b0d02929f525e6bf7ff80aa17ca802af/sqlalchemy-2.0.44-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:0b1af8392eb27b372ddb783b317dea0f650241cea5bd29199b22235299ca2e45", size = 2123212, upload-time = "2025-10-10T16:03:41.755Z" }, - { url = "https://files.pythonhosted.org/packages/b0/bb/43e246cfe0e81c018076a16036d9b548c4cc649de241fa27d8d9ca6f85ab/sqlalchemy-2.0.44-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2b61188657e3a2b9ac4e8f04d6cf8e51046e28175f79464c67f2fd35bceb0976", size = 3255353, upload-time = "2025-10-10T15:35:31.221Z" }, - { url = "https://files.pythonhosted.org/packages/b9/96/c6105ed9a880abe346b64d3b6ddef269ddfcab04f7f3d90a0bf3c5a88e82/sqlalchemy-2.0.44-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b87e7b91a5d5973dda5f00cd61ef72ad75a1db73a386b62877d4875a8840959c", size = 3260222, upload-time = "2025-10-10T15:43:50.124Z" }, - { url = "https://files.pythonhosted.org/packages/44/16/1857e35a47155b5ad927272fee81ae49d398959cb749edca6eaa399b582f/sqlalchemy-2.0.44-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:15f3326f7f0b2bfe406ee562e17f43f36e16167af99c4c0df61db668de20002d", size = 3189614, upload-time = "2025-10-10T15:35:32.578Z" }, - { url = "https://files.pythonhosted.org/packages/88/ee/4afb39a8ee4fc786e2d716c20ab87b5b1fb33d4ac4129a1aaa574ae8a585/sqlalchemy-2.0.44-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:1e77faf6ff919aa8cd63f1c4e561cac1d9a454a191bb864d5dd5e545935e5a40", size = 3226248, upload-time = "2025-10-10T15:43:51.862Z" }, - { url = "https://files.pythonhosted.org/packages/32/d5/0e66097fc64fa266f29a7963296b40a80d6a997b7ac13806183700676f86/sqlalchemy-2.0.44-cp313-cp313-win32.whl", hash = "sha256:ee51625c2d51f8baadf2829fae817ad0b66b140573939dd69284d2ba3553ae73", size = 2101275, upload-time = "2025-10-10T15:03:26.096Z" }, - { url = "https://files.pythonhosted.org/packages/03/51/665617fe4f8c6450f42a6d8d69243f9420f5677395572c2fe9d21b493b7b/sqlalchemy-2.0.44-cp313-cp313-win_amd64.whl", hash = "sha256:c1c80faaee1a6c3428cecf40d16a2365bcf56c424c92c2b6f0f9ad204b899e9e", size = 2127901, upload-time = "2025-10-10T15:03:27.548Z" }, - { url = "https://files.pythonhosted.org/packages/9c/5e/6a29fa884d9fb7ddadf6b69490a9d45fded3b38541713010dad16b77d015/sqlalchemy-2.0.44-py3-none-any.whl", hash = "sha256:19de7ca1246fbef9f9d1bff8f1ab25641569df226364a0e40457dc5457c54b05", size = 1928718, upload-time = "2025-10-10T15:29:45.32Z" }, + { url = "https://files.pythonhosted.org/packages/45/d3/c67077a2249fdb455246e6853166360054c331db4613cda3e31ab1cadbef/sqlalchemy-2.0.44-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:ff486e183d151e51b1d694c7aa1695747599bb00b9f5f604092b54b74c64a8e1", size = 2135479 }, + { url = "https://files.pythonhosted.org/packages/2b/91/eabd0688330d6fd114f5f12c4f89b0d02929f525e6bf7ff80aa17ca802af/sqlalchemy-2.0.44-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:0b1af8392eb27b372ddb783b317dea0f650241cea5bd29199b22235299ca2e45", size = 2123212 }, + { url = "https://files.pythonhosted.org/packages/b0/bb/43e246cfe0e81c018076a16036d9b548c4cc649de241fa27d8d9ca6f85ab/sqlalchemy-2.0.44-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2b61188657e3a2b9ac4e8f04d6cf8e51046e28175f79464c67f2fd35bceb0976", size = 3255353 }, + { url = "https://files.pythonhosted.org/packages/b9/96/c6105ed9a880abe346b64d3b6ddef269ddfcab04f7f3d90a0bf3c5a88e82/sqlalchemy-2.0.44-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b87e7b91a5d5973dda5f00cd61ef72ad75a1db73a386b62877d4875a8840959c", size = 3260222 }, + { url = "https://files.pythonhosted.org/packages/44/16/1857e35a47155b5ad927272fee81ae49d398959cb749edca6eaa399b582f/sqlalchemy-2.0.44-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:15f3326f7f0b2bfe406ee562e17f43f36e16167af99c4c0df61db668de20002d", size = 3189614 }, + { url = "https://files.pythonhosted.org/packages/88/ee/4afb39a8ee4fc786e2d716c20ab87b5b1fb33d4ac4129a1aaa574ae8a585/sqlalchemy-2.0.44-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:1e77faf6ff919aa8cd63f1c4e561cac1d9a454a191bb864d5dd5e545935e5a40", size = 3226248 }, + { url = "https://files.pythonhosted.org/packages/32/d5/0e66097fc64fa266f29a7963296b40a80d6a997b7ac13806183700676f86/sqlalchemy-2.0.44-cp313-cp313-win32.whl", hash = "sha256:ee51625c2d51f8baadf2829fae817ad0b66b140573939dd69284d2ba3553ae73", size = 2101275 }, + { url = "https://files.pythonhosted.org/packages/03/51/665617fe4f8c6450f42a6d8d69243f9420f5677395572c2fe9d21b493b7b/sqlalchemy-2.0.44-cp313-cp313-win_amd64.whl", hash = "sha256:c1c80faaee1a6c3428cecf40d16a2365bcf56c424c92c2b6f0f9ad204b899e9e", size = 2127901 }, + { url = "https://files.pythonhosted.org/packages/9c/5e/6a29fa884d9fb7ddadf6b69490a9d45fded3b38541713010dad16b77d015/sqlalchemy-2.0.44-py3-none-any.whl", hash = "sha256:19de7ca1246fbef9f9d1bff8f1ab25641569df226364a0e40457dc5457c54b05", size = 1928718 }, ] [package.optional-dependencies] @@ -2093,30 +2181,30 @@ dependencies = [ { name = "pydantic" }, { name = "sqlalchemy" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/90/5a/693d90866233e837d182da76082a6d4c2303f54d3aaaa5c78e1238c5d863/sqlmodel-0.0.27.tar.gz", hash = "sha256:ad1227f2014a03905aef32e21428640848ac09ff793047744a73dfdd077ff620", size = 118053, upload-time = "2025-10-08T16:39:11.938Z" } +sdist = { url = "https://files.pythonhosted.org/packages/90/5a/693d90866233e837d182da76082a6d4c2303f54d3aaaa5c78e1238c5d863/sqlmodel-0.0.27.tar.gz", hash = "sha256:ad1227f2014a03905aef32e21428640848ac09ff793047744a73dfdd077ff620", size = 118053 } wheels = [ - { url = "https://files.pythonhosted.org/packages/8c/92/c35e036151fe53822893979f8a13e6f235ae8191f4164a79ae60a95d66aa/sqlmodel-0.0.27-py3-none-any.whl", hash = "sha256:667fe10aa8ff5438134668228dc7d7a08306f4c5c4c7e6ad3ad68defa0e7aa49", size = 29131, upload-time = "2025-10-08T16:39:10.917Z" }, + { url = "https://files.pythonhosted.org/packages/8c/92/c35e036151fe53822893979f8a13e6f235ae8191f4164a79ae60a95d66aa/sqlmodel-0.0.27-py3-none-any.whl", hash = "sha256:667fe10aa8ff5438134668228dc7d7a08306f4c5c4c7e6ad3ad68defa0e7aa49", size = 29131 }, ] [[package]] name = "starlette" -version = "0.48.0" +version = "0.49.3" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "anyio" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/a7/a5/d6f429d43394057b67a6b5bbe6eae2f77a6bf7459d961fdb224bf206eee6/starlette-0.48.0.tar.gz", hash = "sha256:7e8cee469a8ab2352911528110ce9088fdc6a37d9876926e73da7ce4aa4c7a46", size = 2652949, upload-time = "2025-09-13T08:41:05.699Z" } +sdist = { url = "https://files.pythonhosted.org/packages/de/1a/608df0b10b53b0beb96a37854ee05864d182ddd4b1156a22f1ad3860425a/starlette-0.49.3.tar.gz", hash = "sha256:1c14546f299b5901a1ea0e34410575bc33bbd741377a10484a54445588d00284", size = 2655031 } wheels = [ - { url = "https://files.pythonhosted.org/packages/be/72/2db2f49247d0a18b4f1bb9a5a39a0162869acf235f3a96418363947b3d46/starlette-0.48.0-py3-none-any.whl", hash = "sha256:0764ca97b097582558ecb498132ed0c7d942f233f365b86ba37770e026510659", size = 73736, upload-time = "2025-09-13T08:41:03.869Z" }, + { url = "https://files.pythonhosted.org/packages/a3/e0/021c772d6a662f43b63044ab481dc6ac7592447605b5b35a957785363122/starlette-0.49.3-py3-none-any.whl", hash = "sha256:b579b99715fdc2980cf88c8ec96d3bf1ce16f5a8051a7c2b84ef9b1cdecaea2f", size = 74340 }, ] [[package]] name = "text-unidecode" version = "1.3" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/ab/e2/e9a00f0ccb71718418230718b3d900e71a5d16e701a3dae079a21e9cd8f8/text-unidecode-1.3.tar.gz", hash = "sha256:bad6603bb14d279193107714b288be206cac565dfa49aa5b105294dd5c4aab93", size = 76885, upload-time = "2019-08-30T21:36:45.405Z" } +sdist = { url = "https://files.pythonhosted.org/packages/ab/e2/e9a00f0ccb71718418230718b3d900e71a5d16e701a3dae079a21e9cd8f8/text-unidecode-1.3.tar.gz", hash = "sha256:bad6603bb14d279193107714b288be206cac565dfa49aa5b105294dd5c4aab93", size = 76885 } wheels = [ - { url = "https://files.pythonhosted.org/packages/a6/a5/c0b6468d3824fe3fde30dbb5e1f687b291608f9473681bbf7dabbf5a87d7/text_unidecode-1.3-py2.py3-none-any.whl", hash = "sha256:1311f10e8b895935241623731c2ba64f4c455287888b18189350b67134a822e8", size = 78154, upload-time = "2019-08-30T21:37:03.543Z" }, + { url = "https://files.pythonhosted.org/packages/a6/a5/c0b6468d3824fe3fde30dbb5e1f687b291608f9473681bbf7dabbf5a87d7/text_unidecode-1.3-py2.py3-none-any.whl", hash = "sha256:1311f10e8b895935241623731c2ba64f4c455287888b18189350b67134a822e8", size = 78154 }, ] [[package]] @@ -2129,9 +2217,9 @@ dependencies = [ { name = "requests" }, { name = "requests-file" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/97/78/182641ea38e3cfd56e9c7b3c0d48a53d432eea755003aa544af96403d4ac/tldextract-5.3.0.tar.gz", hash = "sha256:b3d2b70a1594a0ecfa6967d57251527d58e00bb5a91a74387baa0d87a0678609", size = 128502, upload-time = "2025-04-22T06:19:37.491Z" } +sdist = { url = "https://files.pythonhosted.org/packages/97/78/182641ea38e3cfd56e9c7b3c0d48a53d432eea755003aa544af96403d4ac/tldextract-5.3.0.tar.gz", hash = "sha256:b3d2b70a1594a0ecfa6967d57251527d58e00bb5a91a74387baa0d87a0678609", size = 128502 } wheels = [ - { url = "https://files.pythonhosted.org/packages/67/7c/ea488ef48f2f544566947ced88541bc45fae9e0e422b2edbf165ee07da99/tldextract-5.3.0-py3-none-any.whl", hash = "sha256:f70f31d10b55c83993f55e91ecb7c5d84532a8972f22ec578ecfbe5ea2292db2", size = 107384, upload-time = "2025-04-22T06:19:36.304Z" }, + { url = "https://files.pythonhosted.org/packages/67/7c/ea488ef48f2f544566947ced88541bc45fae9e0e422b2edbf165ee07da99/tldextract-5.3.0-py3-none-any.whl", hash = "sha256:f70f31d10b55c83993f55e91ecb7c5d84532a8972f22ec578ecfbe5ea2292db2", size = 107384 }, ] [[package]] @@ -2144,18 +2232,18 @@ dependencies = [ { name = "shellingham" }, { name = "typing-extensions" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/8f/28/7c85c8032b91dbe79725b6f17d2fffc595dff06a35c7a30a37bef73a1ab4/typer-0.20.0.tar.gz", hash = "sha256:1aaf6494031793e4876fb0bacfa6a912b551cf43c1e63c800df8b1a866720c37", size = 106492, upload-time = "2025-10-20T17:03:49.445Z" } +sdist = { url = "https://files.pythonhosted.org/packages/8f/28/7c85c8032b91dbe79725b6f17d2fffc595dff06a35c7a30a37bef73a1ab4/typer-0.20.0.tar.gz", hash = "sha256:1aaf6494031793e4876fb0bacfa6a912b551cf43c1e63c800df8b1a866720c37", size = 106492 } wheels = [ - { url = "https://files.pythonhosted.org/packages/78/64/7713ffe4b5983314e9d436a90d5bd4f63b6054e2aca783a3cfc44cb95bbf/typer-0.20.0-py3-none-any.whl", hash = "sha256:5b463df6793ec1dca6213a3cf4c0f03bc6e322ac5e16e13ddd622a889489784a", size = 47028, upload-time = "2025-10-20T17:03:47.617Z" }, + { url = "https://files.pythonhosted.org/packages/78/64/7713ffe4b5983314e9d436a90d5bd4f63b6054e2aca783a3cfc44cb95bbf/typer-0.20.0-py3-none-any.whl", hash = "sha256:5b463df6793ec1dca6213a3cf4c0f03bc6e322ac5e16e13ddd622a889489784a", size = 47028 }, ] [[package]] name = "typing-extensions" version = "4.15.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/72/94/1a15dd82efb362ac84269196e94cf00f187f7ed21c242792a923cdb1c61f/typing_extensions-4.15.0.tar.gz", hash = "sha256:0cea48d173cc12fa28ecabc3b837ea3cf6f38c6d1136f85cbaaf598984861466", size = 109391, upload-time = "2025-08-25T13:49:26.313Z" } +sdist = { url = "https://files.pythonhosted.org/packages/72/94/1a15dd82efb362ac84269196e94cf00f187f7ed21c242792a923cdb1c61f/typing_extensions-4.15.0.tar.gz", hash = "sha256:0cea48d173cc12fa28ecabc3b837ea3cf6f38c6d1136f85cbaaf598984861466", size = 109391 } wheels = [ - { url = "https://files.pythonhosted.org/packages/18/67/36e9267722cc04a6b9f15c7f3441c2363321a3ea07da7ae0c0707beb2a9c/typing_extensions-4.15.0-py3-none-any.whl", hash = "sha256:f0fa19c6845758ab08074a0cfa8b7aecb71c999ca73d62883bc25cc018c4e548", size = 44614, upload-time = "2025-08-25T13:49:24.86Z" }, + { url = "https://files.pythonhosted.org/packages/18/67/36e9267722cc04a6b9f15c7f3441c2363321a3ea07da7ae0c0707beb2a9c/typing_extensions-4.15.0-py3-none-any.whl", hash = "sha256:f0fa19c6845758ab08074a0cfa8b7aecb71c999ca73d62883bc25cc018c4e548", size = 44614 }, ] [[package]] @@ -2165,36 +2253,36 @@ source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "typing-extensions" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/55/e3/70399cb7dd41c10ac53367ae42139cf4b1ca5f36bb3dc6c9d33acdb43655/typing_inspection-0.4.2.tar.gz", hash = "sha256:ba561c48a67c5958007083d386c3295464928b01faa735ab8547c5692e87f464", size = 75949, upload-time = "2025-10-01T02:14:41.687Z" } +sdist = { url = "https://files.pythonhosted.org/packages/55/e3/70399cb7dd41c10ac53367ae42139cf4b1ca5f36bb3dc6c9d33acdb43655/typing_inspection-0.4.2.tar.gz", hash = "sha256:ba561c48a67c5958007083d386c3295464928b01faa735ab8547c5692e87f464", size = 75949 } wheels = [ - { url = "https://files.pythonhosted.org/packages/dc/9b/47798a6c91d8bdb567fe2698fe81e0c6b7cb7ef4d13da4114b41d239f65d/typing_inspection-0.4.2-py3-none-any.whl", hash = "sha256:4ed1cacbdc298c220f1bd249ed5287caa16f34d44ef4e9c3d0cbad5b521545e7", size = 14611, upload-time = "2025-10-01T02:14:40.154Z" }, + { url = "https://files.pythonhosted.org/packages/dc/9b/47798a6c91d8bdb567fe2698fe81e0c6b7cb7ef4d13da4114b41d239f65d/typing_inspection-0.4.2-py3-none-any.whl", hash = "sha256:4ed1cacbdc298c220f1bd249ed5287caa16f34d44ef4e9c3d0cbad5b521545e7", size = 14611 }, ] [[package]] name = "tzdata" version = "2025.2" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/95/32/1a225d6164441be760d75c2c42e2780dc0873fe382da3e98a2e1e48361e5/tzdata-2025.2.tar.gz", hash = "sha256:b60a638fcc0daffadf82fe0f57e53d06bdec2f36c4df66280ae79bce6bd6f2b9", size = 196380, upload-time = "2025-03-23T13:54:43.652Z" } +sdist = { url = "https://files.pythonhosted.org/packages/95/32/1a225d6164441be760d75c2c42e2780dc0873fe382da3e98a2e1e48361e5/tzdata-2025.2.tar.gz", hash = "sha256:b60a638fcc0daffadf82fe0f57e53d06bdec2f36c4df66280ae79bce6bd6f2b9", size = 196380 } wheels = [ - { url = "https://files.pythonhosted.org/packages/5c/23/c7abc0ca0a1526a0774eca151daeb8de62ec457e77262b66b359c3c7679e/tzdata-2025.2-py2.py3-none-any.whl", hash = "sha256:1a403fada01ff9221ca8044d701868fa132215d84beb92242d9acd2147f667a8", size = 347839, upload-time = "2025-03-23T13:54:41.845Z" }, + { url = "https://files.pythonhosted.org/packages/5c/23/c7abc0ca0a1526a0774eca151daeb8de62ec457e77262b66b359c3c7679e/tzdata-2025.2-py2.py3-none-any.whl", hash = "sha256:1a403fada01ff9221ca8044d701868fa132215d84beb92242d9acd2147f667a8", size = 347839 }, ] [[package]] name = "uritemplate" version = "4.2.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/98/60/f174043244c5306c9988380d2cb10009f91563fc4b31293d27e17201af56/uritemplate-4.2.0.tar.gz", hash = "sha256:480c2ed180878955863323eea31b0ede668795de182617fef9c6ca09e6ec9d0e", size = 33267, upload-time = "2025-06-02T15:12:06.318Z" } +sdist = { url = "https://files.pythonhosted.org/packages/98/60/f174043244c5306c9988380d2cb10009f91563fc4b31293d27e17201af56/uritemplate-4.2.0.tar.gz", hash = "sha256:480c2ed180878955863323eea31b0ede668795de182617fef9c6ca09e6ec9d0e", size = 33267 } wheels = [ - { url = "https://files.pythonhosted.org/packages/a9/99/3ae339466c9183ea5b8ae87b34c0b897eda475d2aec2307cae60e5cd4f29/uritemplate-4.2.0-py3-none-any.whl", hash = "sha256:962201ba1c4edcab02e60f9a0d3821e82dfc5d2d6662a21abd533879bdb8a686", size = 11488, upload-time = "2025-06-02T15:12:03.405Z" }, + { url = "https://files.pythonhosted.org/packages/a9/99/3ae339466c9183ea5b8ae87b34c0b897eda475d2aec2307cae60e5cd4f29/uritemplate-4.2.0-py3-none-any.whl", hash = "sha256:962201ba1c4edcab02e60f9a0d3821e82dfc5d2d6662a21abd533879bdb8a686", size = 11488 }, ] [[package]] name = "urllib3" version = "2.5.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/15/22/9ee70a2574a4f4599c47dd506532914ce044817c7752a79b6a51286319bc/urllib3-2.5.0.tar.gz", hash = "sha256:3fc47733c7e419d4bc3f6b3dc2b4f890bb743906a30d56ba4a5bfa4bbff92760", size = 393185, upload-time = "2025-06-18T14:07:41.644Z" } +sdist = { url = "https://files.pythonhosted.org/packages/15/22/9ee70a2574a4f4599c47dd506532914ce044817c7752a79b6a51286319bc/urllib3-2.5.0.tar.gz", hash = "sha256:3fc47733c7e419d4bc3f6b3dc2b4f890bb743906a30d56ba4a5bfa4bbff92760", size = 393185 } wheels = [ - { url = "https://files.pythonhosted.org/packages/a7/c2/fe1e52489ae3122415c51f387e221dd0773709bad6c6cdaa599e8a2c5185/urllib3-2.5.0-py3-none-any.whl", hash = "sha256:e6b01673c0fa6a13e374b50871808eb3bf7046c4b125b216f6bf1cc604cff0dc", size = 129795, upload-time = "2025-06-18T14:07:40.39Z" }, + { url = "https://files.pythonhosted.org/packages/a7/c2/fe1e52489ae3122415c51f387e221dd0773709bad6c6cdaa599e8a2c5185/urllib3-2.5.0-py3-none-any.whl", hash = "sha256:e6b01673c0fa6a13e374b50871808eb3bf7046c4b125b216f6bf1cc604cff0dc", size = 129795 }, ] [[package]] @@ -2205,9 +2293,9 @@ dependencies = [ { name = "click" }, { name = "h11" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/cb/ce/f06b84e2697fef4688ca63bdb2fdf113ca0a3be33f94488f2cadb690b0cf/uvicorn-0.38.0.tar.gz", hash = "sha256:fd97093bdd120a2609fc0d3afe931d4d4ad688b6e75f0f929fde1bc36fe0e91d", size = 80605, upload-time = "2025-10-18T13:46:44.63Z" } +sdist = { url = "https://files.pythonhosted.org/packages/cb/ce/f06b84e2697fef4688ca63bdb2fdf113ca0a3be33f94488f2cadb690b0cf/uvicorn-0.38.0.tar.gz", hash = "sha256:fd97093bdd120a2609fc0d3afe931d4d4ad688b6e75f0f929fde1bc36fe0e91d", size = 80605 } wheels = [ - { url = "https://files.pythonhosted.org/packages/ee/d9/d88e73ca598f4f6ff671fb5fde8a32925c2e08a637303a1d12883c7305fa/uvicorn-0.38.0-py3-none-any.whl", hash = "sha256:48c0afd214ceb59340075b4a052ea1ee91c16fbc2a9b1469cca0e54566977b02", size = 68109, upload-time = "2025-10-18T13:46:42.958Z" }, + { url = "https://files.pythonhosted.org/packages/ee/d9/d88e73ca598f4f6ff671fb5fde8a32925c2e08a637303a1d12883c7305fa/uvicorn-0.38.0-py3-none-any.whl", hash = "sha256:48c0afd214ceb59340075b4a052ea1ee91c16fbc2a9b1469cca0e54566977b02", size = 68109 }, ] [package.optional-dependencies] @@ -2225,26 +2313,26 @@ standard = [ name = "uvloop" version = "0.22.1" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/06/f0/18d39dbd1971d6d62c4629cc7fa67f74821b0dc1f5a77af43719de7936a7/uvloop-0.22.1.tar.gz", hash = "sha256:6c84bae345b9147082b17371e3dd5d42775bddce91f885499017f4607fdaf39f", size = 2443250, upload-time = "2025-10-16T22:17:19.342Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/89/8c/182a2a593195bfd39842ea68ebc084e20c850806117213f5a299dfc513d9/uvloop-0.22.1-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:561577354eb94200d75aca23fbde86ee11be36b00e52a4eaf8f50fb0c86b7705", size = 1358611, upload-time = "2025-10-16T22:16:36.833Z" }, - { url = "https://files.pythonhosted.org/packages/d2/14/e301ee96a6dc95224b6f1162cd3312f6d1217be3907b79173b06785f2fe7/uvloop-0.22.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:1cdf5192ab3e674ca26da2eada35b288d2fa49fdd0f357a19f0e7c4e7d5077c8", size = 751811, upload-time = "2025-10-16T22:16:38.275Z" }, - { url = "https://files.pythonhosted.org/packages/b7/02/654426ce265ac19e2980bfd9ea6590ca96a56f10c76e63801a2df01c0486/uvloop-0.22.1-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6e2ea3d6190a2968f4a14a23019d3b16870dd2190cd69c8180f7c632d21de68d", size = 4288562, upload-time = "2025-10-16T22:16:39.375Z" }, - { url = "https://files.pythonhosted.org/packages/15/c0/0be24758891ef825f2065cd5db8741aaddabe3e248ee6acc5e8a80f04005/uvloop-0.22.1-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:0530a5fbad9c9e4ee3f2b33b148c6a64d47bbad8000ea63704fa8260f4cf728e", size = 4366890, upload-time = "2025-10-16T22:16:40.547Z" }, - { url = "https://files.pythonhosted.org/packages/d2/53/8369e5219a5855869bcee5f4d317f6da0e2c669aecf0ef7d371e3d084449/uvloop-0.22.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:bc5ef13bbc10b5335792360623cc378d52d7e62c2de64660616478c32cd0598e", size = 4119472, upload-time = "2025-10-16T22:16:41.694Z" }, - { url = "https://files.pythonhosted.org/packages/f8/ba/d69adbe699b768f6b29a5eec7b47dd610bd17a69de51b251126a801369ea/uvloop-0.22.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:1f38ec5e3f18c8a10ded09742f7fb8de0108796eb673f30ce7762ce1b8550cad", size = 4239051, upload-time = "2025-10-16T22:16:43.224Z" }, - { url = "https://files.pythonhosted.org/packages/90/cd/b62bdeaa429758aee8de8b00ac0dd26593a9de93d302bff3d21439e9791d/uvloop-0.22.1-cp314-cp314-macosx_10_13_universal2.whl", hash = "sha256:3879b88423ec7e97cd4eba2a443aa26ed4e59b45e6b76aabf13fe2f27023a142", size = 1362067, upload-time = "2025-10-16T22:16:44.503Z" }, - { url = "https://files.pythonhosted.org/packages/0d/f8/a132124dfda0777e489ca86732e85e69afcd1ff7686647000050ba670689/uvloop-0.22.1-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:4baa86acedf1d62115c1dc6ad1e17134476688f08c6efd8a2ab076e815665c74", size = 752423, upload-time = "2025-10-16T22:16:45.968Z" }, - { url = "https://files.pythonhosted.org/packages/a3/94/94af78c156f88da4b3a733773ad5ba0b164393e357cc4bd0ab2e2677a7d6/uvloop-0.22.1-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:297c27d8003520596236bdb2335e6b3f649480bd09e00d1e3a99144b691d2a35", size = 4272437, upload-time = "2025-10-16T22:16:47.451Z" }, - { url = "https://files.pythonhosted.org/packages/b5/35/60249e9fd07b32c665192cec7af29e06c7cd96fa1d08b84f012a56a0b38e/uvloop-0.22.1-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c1955d5a1dd43198244d47664a5858082a3239766a839b2102a269aaff7a4e25", size = 4292101, upload-time = "2025-10-16T22:16:49.318Z" }, - { url = "https://files.pythonhosted.org/packages/02/62/67d382dfcb25d0a98ce73c11ed1a6fba5037a1a1d533dcbb7cab033a2636/uvloop-0.22.1-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:b31dc2fccbd42adc73bc4e7cdbae4fc5086cf378979e53ca5d0301838c5682c6", size = 4114158, upload-time = "2025-10-16T22:16:50.517Z" }, - { url = "https://files.pythonhosted.org/packages/f0/7a/f1171b4a882a5d13c8b7576f348acfe6074d72eaf52cccef752f748d4a9f/uvloop-0.22.1-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:93f617675b2d03af4e72a5333ef89450dfaa5321303ede6e67ba9c9d26878079", size = 4177360, upload-time = "2025-10-16T22:16:52.646Z" }, - { url = "https://files.pythonhosted.org/packages/79/7b/b01414f31546caf0919da80ad57cbfe24c56b151d12af68cee1b04922ca8/uvloop-0.22.1-cp314-cp314t-macosx_10_13_universal2.whl", hash = "sha256:37554f70528f60cad66945b885eb01f1bb514f132d92b6eeed1c90fd54ed6289", size = 1454790, upload-time = "2025-10-16T22:16:54.355Z" }, - { url = "https://files.pythonhosted.org/packages/d4/31/0bb232318dd838cad3fa8fb0c68c8b40e1145b32025581975e18b11fab40/uvloop-0.22.1-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:b76324e2dc033a0b2f435f33eb88ff9913c156ef78e153fb210e03c13da746b3", size = 796783, upload-time = "2025-10-16T22:16:55.906Z" }, - { url = "https://files.pythonhosted.org/packages/42/38/c9b09f3271a7a723a5de69f8e237ab8e7803183131bc57c890db0b6bb872/uvloop-0.22.1-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:badb4d8e58ee08dad957002027830d5c3b06aea446a6a3744483c2b3b745345c", size = 4647548, upload-time = "2025-10-16T22:16:57.008Z" }, - { url = "https://files.pythonhosted.org/packages/c1/37/945b4ca0ac27e3dc4952642d4c900edd030b3da6c9634875af6e13ae80e5/uvloop-0.22.1-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:b91328c72635f6f9e0282e4a57da7470c7350ab1c9f48546c0f2866205349d21", size = 4467065, upload-time = "2025-10-16T22:16:58.206Z" }, - { url = "https://files.pythonhosted.org/packages/97/cc/48d232f33d60e2e2e0b42f4e73455b146b76ebe216487e862700457fbf3c/uvloop-0.22.1-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:daf620c2995d193449393d6c62131b3fbd40a63bf7b307a1527856ace637fe88", size = 4328384, upload-time = "2025-10-16T22:16:59.36Z" }, - { url = "https://files.pythonhosted.org/packages/e4/16/c1fd27e9549f3c4baf1dc9c20c456cd2f822dbf8de9f463824b0c0357e06/uvloop-0.22.1-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:6cde23eeda1a25c75b2e07d39970f3374105d5eafbaab2a4482be82f272d5a5e", size = 4296730, upload-time = "2025-10-16T22:17:00.744Z" }, +sdist = { url = "https://files.pythonhosted.org/packages/06/f0/18d39dbd1971d6d62c4629cc7fa67f74821b0dc1f5a77af43719de7936a7/uvloop-0.22.1.tar.gz", hash = "sha256:6c84bae345b9147082b17371e3dd5d42775bddce91f885499017f4607fdaf39f", size = 2443250 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/89/8c/182a2a593195bfd39842ea68ebc084e20c850806117213f5a299dfc513d9/uvloop-0.22.1-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:561577354eb94200d75aca23fbde86ee11be36b00e52a4eaf8f50fb0c86b7705", size = 1358611 }, + { url = "https://files.pythonhosted.org/packages/d2/14/e301ee96a6dc95224b6f1162cd3312f6d1217be3907b79173b06785f2fe7/uvloop-0.22.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:1cdf5192ab3e674ca26da2eada35b288d2fa49fdd0f357a19f0e7c4e7d5077c8", size = 751811 }, + { url = "https://files.pythonhosted.org/packages/b7/02/654426ce265ac19e2980bfd9ea6590ca96a56f10c76e63801a2df01c0486/uvloop-0.22.1-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6e2ea3d6190a2968f4a14a23019d3b16870dd2190cd69c8180f7c632d21de68d", size = 4288562 }, + { url = "https://files.pythonhosted.org/packages/15/c0/0be24758891ef825f2065cd5db8741aaddabe3e248ee6acc5e8a80f04005/uvloop-0.22.1-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:0530a5fbad9c9e4ee3f2b33b148c6a64d47bbad8000ea63704fa8260f4cf728e", size = 4366890 }, + { url = "https://files.pythonhosted.org/packages/d2/53/8369e5219a5855869bcee5f4d317f6da0e2c669aecf0ef7d371e3d084449/uvloop-0.22.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:bc5ef13bbc10b5335792360623cc378d52d7e62c2de64660616478c32cd0598e", size = 4119472 }, + { url = "https://files.pythonhosted.org/packages/f8/ba/d69adbe699b768f6b29a5eec7b47dd610bd17a69de51b251126a801369ea/uvloop-0.22.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:1f38ec5e3f18c8a10ded09742f7fb8de0108796eb673f30ce7762ce1b8550cad", size = 4239051 }, + { url = "https://files.pythonhosted.org/packages/90/cd/b62bdeaa429758aee8de8b00ac0dd26593a9de93d302bff3d21439e9791d/uvloop-0.22.1-cp314-cp314-macosx_10_13_universal2.whl", hash = "sha256:3879b88423ec7e97cd4eba2a443aa26ed4e59b45e6b76aabf13fe2f27023a142", size = 1362067 }, + { url = "https://files.pythonhosted.org/packages/0d/f8/a132124dfda0777e489ca86732e85e69afcd1ff7686647000050ba670689/uvloop-0.22.1-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:4baa86acedf1d62115c1dc6ad1e17134476688f08c6efd8a2ab076e815665c74", size = 752423 }, + { url = "https://files.pythonhosted.org/packages/a3/94/94af78c156f88da4b3a733773ad5ba0b164393e357cc4bd0ab2e2677a7d6/uvloop-0.22.1-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:297c27d8003520596236bdb2335e6b3f649480bd09e00d1e3a99144b691d2a35", size = 4272437 }, + { url = "https://files.pythonhosted.org/packages/b5/35/60249e9fd07b32c665192cec7af29e06c7cd96fa1d08b84f012a56a0b38e/uvloop-0.22.1-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c1955d5a1dd43198244d47664a5858082a3239766a839b2102a269aaff7a4e25", size = 4292101 }, + { url = "https://files.pythonhosted.org/packages/02/62/67d382dfcb25d0a98ce73c11ed1a6fba5037a1a1d533dcbb7cab033a2636/uvloop-0.22.1-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:b31dc2fccbd42adc73bc4e7cdbae4fc5086cf378979e53ca5d0301838c5682c6", size = 4114158 }, + { url = "https://files.pythonhosted.org/packages/f0/7a/f1171b4a882a5d13c8b7576f348acfe6074d72eaf52cccef752f748d4a9f/uvloop-0.22.1-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:93f617675b2d03af4e72a5333ef89450dfaa5321303ede6e67ba9c9d26878079", size = 4177360 }, + { url = "https://files.pythonhosted.org/packages/79/7b/b01414f31546caf0919da80ad57cbfe24c56b151d12af68cee1b04922ca8/uvloop-0.22.1-cp314-cp314t-macosx_10_13_universal2.whl", hash = "sha256:37554f70528f60cad66945b885eb01f1bb514f132d92b6eeed1c90fd54ed6289", size = 1454790 }, + { url = "https://files.pythonhosted.org/packages/d4/31/0bb232318dd838cad3fa8fb0c68c8b40e1145b32025581975e18b11fab40/uvloop-0.22.1-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:b76324e2dc033a0b2f435f33eb88ff9913c156ef78e153fb210e03c13da746b3", size = 796783 }, + { url = "https://files.pythonhosted.org/packages/42/38/c9b09f3271a7a723a5de69f8e237ab8e7803183131bc57c890db0b6bb872/uvloop-0.22.1-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:badb4d8e58ee08dad957002027830d5c3b06aea446a6a3744483c2b3b745345c", size = 4647548 }, + { url = "https://files.pythonhosted.org/packages/c1/37/945b4ca0ac27e3dc4952642d4c900edd030b3da6c9634875af6e13ae80e5/uvloop-0.22.1-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:b91328c72635f6f9e0282e4a57da7470c7350ab1c9f48546c0f2866205349d21", size = 4467065 }, + { url = "https://files.pythonhosted.org/packages/97/cc/48d232f33d60e2e2e0b42f4e73455b146b76ebe216487e862700457fbf3c/uvloop-0.22.1-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:daf620c2995d193449393d6c62131b3fbd40a63bf7b307a1527856ace637fe88", size = 4328384 }, + { url = "https://files.pythonhosted.org/packages/e4/16/c1fd27e9549f3c4baf1dc9c20c456cd2f822dbf8de9f463824b0c0357e06/uvloop-0.22.1-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:6cde23eeda1a25c75b2e07d39970f3374105d5eafbaab2a4482be82f272d5a5e", size = 4296730 }, ] [[package]] @@ -2254,74 +2342,74 @@ source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "anyio" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/c2/c9/8869df9b2a2d6c59d79220a4db37679e74f807c559ffe5265e08b227a210/watchfiles-1.1.1.tar.gz", hash = "sha256:a173cb5c16c4f40ab19cecf48a534c409f7ea983ab8fed0741304a1c0a31b3f2", size = 94440, upload-time = "2025-10-14T15:06:21.08Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/bb/f4/f750b29225fe77139f7ae5de89d4949f5a99f934c65a1f1c0b248f26f747/watchfiles-1.1.1-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:130e4876309e8686a5e37dba7d5e9bc77e6ed908266996ca26572437a5271e18", size = 404321, upload-time = "2025-10-14T15:05:02.063Z" }, - { url = "https://files.pythonhosted.org/packages/2b/f9/f07a295cde762644aa4c4bb0f88921d2d141af45e735b965fb2e87858328/watchfiles-1.1.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:5f3bde70f157f84ece3765b42b4a52c6ac1a50334903c6eaf765362f6ccca88a", size = 391783, upload-time = "2025-10-14T15:05:03.052Z" }, - { url = "https://files.pythonhosted.org/packages/bc/11/fc2502457e0bea39a5c958d86d2cb69e407a4d00b85735ca724bfa6e0d1a/watchfiles-1.1.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:14e0b1fe858430fc0251737ef3824c54027bedb8c37c38114488b8e131cf8219", size = 449279, upload-time = "2025-10-14T15:05:04.004Z" }, - { url = "https://files.pythonhosted.org/packages/e3/1f/d66bc15ea0b728df3ed96a539c777acfcad0eb78555ad9efcaa1274688f0/watchfiles-1.1.1-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:f27db948078f3823a6bb3b465180db8ebecf26dd5dae6f6180bd87383b6b4428", size = 459405, upload-time = "2025-10-14T15:05:04.942Z" }, - { url = "https://files.pythonhosted.org/packages/be/90/9f4a65c0aec3ccf032703e6db02d89a157462fbb2cf20dd415128251cac0/watchfiles-1.1.1-cp313-cp313-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:059098c3a429f62fc98e8ec62b982230ef2c8df68c79e826e37b895bc359a9c0", size = 488976, upload-time = "2025-10-14T15:05:05.905Z" }, - { url = "https://files.pythonhosted.org/packages/37/57/ee347af605d867f712be7029bb94c8c071732a4b44792e3176fa3c612d39/watchfiles-1.1.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:bfb5862016acc9b869bb57284e6cb35fdf8e22fe59f7548858e2f971d045f150", size = 595506, upload-time = "2025-10-14T15:05:06.906Z" }, - { url = "https://files.pythonhosted.org/packages/a8/78/cc5ab0b86c122047f75e8fc471c67a04dee395daf847d3e59381996c8707/watchfiles-1.1.1-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:319b27255aacd9923b8a276bb14d21a5f7ff82564c744235fc5eae58d95422ae", size = 474936, upload-time = "2025-10-14T15:05:07.906Z" }, - { url = "https://files.pythonhosted.org/packages/62/da/def65b170a3815af7bd40a3e7010bf6ab53089ef1b75d05dd5385b87cf08/watchfiles-1.1.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c755367e51db90e75b19454b680903631d41f9e3607fbd941d296a020c2d752d", size = 456147, upload-time = "2025-10-14T15:05:09.138Z" }, - { url = "https://files.pythonhosted.org/packages/57/99/da6573ba71166e82d288d4df0839128004c67d2778d3b566c138695f5c0b/watchfiles-1.1.1-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:c22c776292a23bfc7237a98f791b9ad3144b02116ff10d820829ce62dff46d0b", size = 630007, upload-time = "2025-10-14T15:05:10.117Z" }, - { url = "https://files.pythonhosted.org/packages/a8/51/7439c4dd39511368849eb1e53279cd3454b4a4dbace80bab88feeb83c6b5/watchfiles-1.1.1-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:3a476189be23c3686bc2f4321dd501cb329c0a0469e77b7b534ee10129ae6374", size = 622280, upload-time = "2025-10-14T15:05:11.146Z" }, - { url = "https://files.pythonhosted.org/packages/95/9c/8ed97d4bba5db6fdcdb2b298d3898f2dd5c20f6b73aee04eabe56c59677e/watchfiles-1.1.1-cp313-cp313-win32.whl", hash = "sha256:bf0a91bfb5574a2f7fc223cf95eeea79abfefa404bf1ea5e339c0c1560ae99a0", size = 272056, upload-time = "2025-10-14T15:05:12.156Z" }, - { url = "https://files.pythonhosted.org/packages/1f/f3/c14e28429f744a260d8ceae18bf58c1d5fa56b50d006a7a9f80e1882cb0d/watchfiles-1.1.1-cp313-cp313-win_amd64.whl", hash = "sha256:52e06553899e11e8074503c8e716d574adeeb7e68913115c4b3653c53f9bae42", size = 288162, upload-time = "2025-10-14T15:05:13.208Z" }, - { url = "https://files.pythonhosted.org/packages/dc/61/fe0e56c40d5cd29523e398d31153218718c5786b5e636d9ae8ae79453d27/watchfiles-1.1.1-cp313-cp313-win_arm64.whl", hash = "sha256:ac3cc5759570cd02662b15fbcd9d917f7ecd47efe0d6b40474eafd246f91ea18", size = 277909, upload-time = "2025-10-14T15:05:14.49Z" }, - { url = "https://files.pythonhosted.org/packages/79/42/e0a7d749626f1e28c7108a99fb9bf524b501bbbeb9b261ceecde644d5a07/watchfiles-1.1.1-cp313-cp313t-macosx_10_12_x86_64.whl", hash = "sha256:563b116874a9a7ce6f96f87cd0b94f7faf92d08d0021e837796f0a14318ef8da", size = 403389, upload-time = "2025-10-14T15:05:15.777Z" }, - { url = "https://files.pythonhosted.org/packages/15/49/08732f90ce0fbbc13913f9f215c689cfc9ced345fb1bcd8829a50007cc8d/watchfiles-1.1.1-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:3ad9fe1dae4ab4212d8c91e80b832425e24f421703b5a42ef2e4a1e215aff051", size = 389964, upload-time = "2025-10-14T15:05:16.85Z" }, - { url = "https://files.pythonhosted.org/packages/27/0d/7c315d4bd5f2538910491a0393c56bf70d333d51bc5b34bee8e68e8cea19/watchfiles-1.1.1-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ce70f96a46b894b36eba678f153f052967a0d06d5b5a19b336ab0dbbd029f73e", size = 448114, upload-time = "2025-10-14T15:05:17.876Z" }, - { url = "https://files.pythonhosted.org/packages/c3/24/9e096de47a4d11bc4df41e9d1e61776393eac4cb6eb11b3e23315b78b2cc/watchfiles-1.1.1-cp313-cp313t-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:cb467c999c2eff23a6417e58d75e5828716f42ed8289fe6b77a7e5a91036ca70", size = 460264, upload-time = "2025-10-14T15:05:18.962Z" }, - { url = "https://files.pythonhosted.org/packages/cc/0f/e8dea6375f1d3ba5fcb0b3583e2b493e77379834c74fd5a22d66d85d6540/watchfiles-1.1.1-cp313-cp313t-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:836398932192dae4146c8f6f737d74baeac8b70ce14831a239bdb1ca882fc261", size = 487877, upload-time = "2025-10-14T15:05:20.094Z" }, - { url = "https://files.pythonhosted.org/packages/ac/5b/df24cfc6424a12deb41503b64d42fbea6b8cb357ec62ca84a5a3476f654a/watchfiles-1.1.1-cp313-cp313t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:743185e7372b7bc7c389e1badcc606931a827112fbbd37f14c537320fca08620", size = 595176, upload-time = "2025-10-14T15:05:21.134Z" }, - { url = "https://files.pythonhosted.org/packages/8f/b5/853b6757f7347de4e9b37e8cc3289283fb983cba1ab4d2d7144694871d9c/watchfiles-1.1.1-cp313-cp313t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:afaeff7696e0ad9f02cbb8f56365ff4686ab205fcf9c4c5b6fdfaaa16549dd04", size = 473577, upload-time = "2025-10-14T15:05:22.306Z" }, - { url = "https://files.pythonhosted.org/packages/e1/f7/0a4467be0a56e80447c8529c9fce5b38eab4f513cb3d9bf82e7392a5696b/watchfiles-1.1.1-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3f7eb7da0eb23aa2ba036d4f616d46906013a68caf61b7fdbe42fc8b25132e77", size = 455425, upload-time = "2025-10-14T15:05:23.348Z" }, - { url = "https://files.pythonhosted.org/packages/8e/e0/82583485ea00137ddf69bc84a2db88bd92ab4a6e3c405e5fb878ead8d0e7/watchfiles-1.1.1-cp313-cp313t-musllinux_1_1_aarch64.whl", hash = "sha256:831a62658609f0e5c64178211c942ace999517f5770fe9436be4c2faeba0c0ef", size = 628826, upload-time = "2025-10-14T15:05:24.398Z" }, - { url = "https://files.pythonhosted.org/packages/28/9a/a785356fccf9fae84c0cc90570f11702ae9571036fb25932f1242c82191c/watchfiles-1.1.1-cp313-cp313t-musllinux_1_1_x86_64.whl", hash = "sha256:f9a2ae5c91cecc9edd47e041a930490c31c3afb1f5e6d71de3dc671bfaca02bf", size = 622208, upload-time = "2025-10-14T15:05:25.45Z" }, - { url = "https://files.pythonhosted.org/packages/c3/f4/0872229324ef69b2c3edec35e84bd57a1289e7d3fe74588048ed8947a323/watchfiles-1.1.1-cp314-cp314-macosx_10_12_x86_64.whl", hash = "sha256:d1715143123baeeaeadec0528bb7441103979a1d5f6fd0e1f915383fea7ea6d5", size = 404315, upload-time = "2025-10-14T15:05:26.501Z" }, - { url = "https://files.pythonhosted.org/packages/7b/22/16d5331eaed1cb107b873f6ae1b69e9ced582fcf0c59a50cd84f403b1c32/watchfiles-1.1.1-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:39574d6370c4579d7f5d0ad940ce5b20db0e4117444e39b6d8f99db5676c52fd", size = 390869, upload-time = "2025-10-14T15:05:27.649Z" }, - { url = "https://files.pythonhosted.org/packages/b2/7e/5643bfff5acb6539b18483128fdc0ef2cccc94a5b8fbda130c823e8ed636/watchfiles-1.1.1-cp314-cp314-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7365b92c2e69ee952902e8f70f3ba6360d0d596d9299d55d7d386df84b6941fb", size = 449919, upload-time = "2025-10-14T15:05:28.701Z" }, - { url = "https://files.pythonhosted.org/packages/51/2e/c410993ba5025a9f9357c376f48976ef0e1b1aefb73b97a5ae01a5972755/watchfiles-1.1.1-cp314-cp314-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:bfff9740c69c0e4ed32416f013f3c45e2ae42ccedd1167ef2d805c000b6c71a5", size = 460845, upload-time = "2025-10-14T15:05:30.064Z" }, - { url = "https://files.pythonhosted.org/packages/8e/a4/2df3b404469122e8680f0fcd06079317e48db58a2da2950fb45020947734/watchfiles-1.1.1-cp314-cp314-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b27cf2eb1dda37b2089e3907d8ea92922b673c0c427886d4edc6b94d8dfe5db3", size = 489027, upload-time = "2025-10-14T15:05:31.064Z" }, - { url = "https://files.pythonhosted.org/packages/ea/84/4587ba5b1f267167ee715b7f66e6382cca6938e0a4b870adad93e44747e6/watchfiles-1.1.1-cp314-cp314-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:526e86aced14a65a5b0ec50827c745597c782ff46b571dbfe46192ab9e0b3c33", size = 595615, upload-time = "2025-10-14T15:05:32.074Z" }, - { url = "https://files.pythonhosted.org/packages/6a/0f/c6988c91d06e93cd0bb3d4a808bcf32375ca1904609835c3031799e3ecae/watchfiles-1.1.1-cp314-cp314-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:04e78dd0b6352db95507fd8cb46f39d185cf8c74e4cf1e4fbad1d3df96faf510", size = 474836, upload-time = "2025-10-14T15:05:33.209Z" }, - { url = "https://files.pythonhosted.org/packages/b4/36/ded8aebea91919485b7bbabbd14f5f359326cb5ec218cd67074d1e426d74/watchfiles-1.1.1-cp314-cp314-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5c85794a4cfa094714fb9c08d4a218375b2b95b8ed1666e8677c349906246c05", size = 455099, upload-time = "2025-10-14T15:05:34.189Z" }, - { url = "https://files.pythonhosted.org/packages/98/e0/8c9bdba88af756a2fce230dd365fab2baf927ba42cd47521ee7498fd5211/watchfiles-1.1.1-cp314-cp314-musllinux_1_1_aarch64.whl", hash = "sha256:74d5012b7630714b66be7b7b7a78855ef7ad58e8650c73afc4c076a1f480a8d6", size = 630626, upload-time = "2025-10-14T15:05:35.216Z" }, - { url = "https://files.pythonhosted.org/packages/2a/84/a95db05354bf2d19e438520d92a8ca475e578c647f78f53197f5a2f17aaf/watchfiles-1.1.1-cp314-cp314-musllinux_1_1_x86_64.whl", hash = "sha256:8fbe85cb3201c7d380d3d0b90e63d520f15d6afe217165d7f98c9c649654db81", size = 622519, upload-time = "2025-10-14T15:05:36.259Z" }, - { url = "https://files.pythonhosted.org/packages/1d/ce/d8acdc8de545de995c339be67711e474c77d643555a9bb74a9334252bd55/watchfiles-1.1.1-cp314-cp314-win32.whl", hash = "sha256:3fa0b59c92278b5a7800d3ee7733da9d096d4aabcfabb9a928918bd276ef9b9b", size = 272078, upload-time = "2025-10-14T15:05:37.63Z" }, - { url = "https://files.pythonhosted.org/packages/c4/c9/a74487f72d0451524be827e8edec251da0cc1fcf111646a511ae752e1a3d/watchfiles-1.1.1-cp314-cp314-win_amd64.whl", hash = "sha256:c2047d0b6cea13b3316bdbafbfa0c4228ae593d995030fda39089d36e64fc03a", size = 287664, upload-time = "2025-10-14T15:05:38.95Z" }, - { url = "https://files.pythonhosted.org/packages/df/b8/8ac000702cdd496cdce998c6f4ee0ca1f15977bba51bdf07d872ebdfc34c/watchfiles-1.1.1-cp314-cp314-win_arm64.whl", hash = "sha256:842178b126593addc05acf6fce960d28bc5fae7afbaa2c6c1b3a7b9460e5be02", size = 277154, upload-time = "2025-10-14T15:05:39.954Z" }, - { url = "https://files.pythonhosted.org/packages/47/a8/e3af2184707c29f0f14b1963c0aace6529f9d1b8582d5b99f31bbf42f59e/watchfiles-1.1.1-cp314-cp314t-macosx_10_12_x86_64.whl", hash = "sha256:88863fbbc1a7312972f1c511f202eb30866370ebb8493aef2812b9ff28156a21", size = 403820, upload-time = "2025-10-14T15:05:40.932Z" }, - { url = "https://files.pythonhosted.org/packages/c0/ec/e47e307c2f4bd75f9f9e8afbe3876679b18e1bcec449beca132a1c5ffb2d/watchfiles-1.1.1-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:55c7475190662e202c08c6c0f4d9e345a29367438cf8e8037f3155e10a88d5a5", size = 390510, upload-time = "2025-10-14T15:05:41.945Z" }, - { url = "https://files.pythonhosted.org/packages/d5/a0/ad235642118090f66e7b2f18fd5c42082418404a79205cdfca50b6309c13/watchfiles-1.1.1-cp314-cp314t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3f53fa183d53a1d7a8852277c92b967ae99c2d4dcee2bfacff8868e6e30b15f7", size = 448408, upload-time = "2025-10-14T15:05:43.385Z" }, - { url = "https://files.pythonhosted.org/packages/df/85/97fa10fd5ff3332ae17e7e40e20784e419e28521549780869f1413742e9d/watchfiles-1.1.1-cp314-cp314t-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:6aae418a8b323732fa89721d86f39ec8f092fc2af67f4217a2b07fd3e93c6101", size = 458968, upload-time = "2025-10-14T15:05:44.404Z" }, - { url = "https://files.pythonhosted.org/packages/47/c2/9059c2e8966ea5ce678166617a7f75ecba6164375f3b288e50a40dc6d489/watchfiles-1.1.1-cp314-cp314t-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f096076119da54a6080e8920cbdaac3dbee667eb91dcc5e5b78840b87415bd44", size = 488096, upload-time = "2025-10-14T15:05:45.398Z" }, - { url = "https://files.pythonhosted.org/packages/94/44/d90a9ec8ac309bc26db808a13e7bfc0e4e78b6fc051078a554e132e80160/watchfiles-1.1.1-cp314-cp314t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:00485f441d183717038ed2e887a7c868154f216877653121068107b227a2f64c", size = 596040, upload-time = "2025-10-14T15:05:46.502Z" }, - { url = "https://files.pythonhosted.org/packages/95/68/4e3479b20ca305cfc561db3ed207a8a1c745ee32bf24f2026a129d0ddb6e/watchfiles-1.1.1-cp314-cp314t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a55f3e9e493158d7bfdb60a1165035f1cf7d320914e7b7ea83fe22c6023b58fc", size = 473847, upload-time = "2025-10-14T15:05:47.484Z" }, - { url = "https://files.pythonhosted.org/packages/4f/55/2af26693fd15165c4ff7857e38330e1b61ab8c37d15dc79118cdba115b7a/watchfiles-1.1.1-cp314-cp314t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8c91ed27800188c2ae96d16e3149f199d62f86c7af5f5f4d2c61a3ed8cd3666c", size = 455072, upload-time = "2025-10-14T15:05:48.928Z" }, - { url = "https://files.pythonhosted.org/packages/66/1d/d0d200b10c9311ec25d2273f8aad8c3ef7cc7ea11808022501811208a750/watchfiles-1.1.1-cp314-cp314t-musllinux_1_1_aarch64.whl", hash = "sha256:311ff15a0bae3714ffb603e6ba6dbfba4065ab60865d15a6ec544133bdb21099", size = 629104, upload-time = "2025-10-14T15:05:49.908Z" }, - { url = "https://files.pythonhosted.org/packages/e3/bd/fa9bb053192491b3867ba07d2343d9f2252e00811567d30ae8d0f78136fe/watchfiles-1.1.1-cp314-cp314t-musllinux_1_1_x86_64.whl", hash = "sha256:a916a2932da8f8ab582f242c065f5c81bed3462849ca79ee357dd9551b0e9b01", size = 622112, upload-time = "2025-10-14T15:05:50.941Z" }, +sdist = { url = "https://files.pythonhosted.org/packages/c2/c9/8869df9b2a2d6c59d79220a4db37679e74f807c559ffe5265e08b227a210/watchfiles-1.1.1.tar.gz", hash = "sha256:a173cb5c16c4f40ab19cecf48a534c409f7ea983ab8fed0741304a1c0a31b3f2", size = 94440 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/bb/f4/f750b29225fe77139f7ae5de89d4949f5a99f934c65a1f1c0b248f26f747/watchfiles-1.1.1-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:130e4876309e8686a5e37dba7d5e9bc77e6ed908266996ca26572437a5271e18", size = 404321 }, + { url = "https://files.pythonhosted.org/packages/2b/f9/f07a295cde762644aa4c4bb0f88921d2d141af45e735b965fb2e87858328/watchfiles-1.1.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:5f3bde70f157f84ece3765b42b4a52c6ac1a50334903c6eaf765362f6ccca88a", size = 391783 }, + { url = "https://files.pythonhosted.org/packages/bc/11/fc2502457e0bea39a5c958d86d2cb69e407a4d00b85735ca724bfa6e0d1a/watchfiles-1.1.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:14e0b1fe858430fc0251737ef3824c54027bedb8c37c38114488b8e131cf8219", size = 449279 }, + { url = "https://files.pythonhosted.org/packages/e3/1f/d66bc15ea0b728df3ed96a539c777acfcad0eb78555ad9efcaa1274688f0/watchfiles-1.1.1-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:f27db948078f3823a6bb3b465180db8ebecf26dd5dae6f6180bd87383b6b4428", size = 459405 }, + { url = "https://files.pythonhosted.org/packages/be/90/9f4a65c0aec3ccf032703e6db02d89a157462fbb2cf20dd415128251cac0/watchfiles-1.1.1-cp313-cp313-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:059098c3a429f62fc98e8ec62b982230ef2c8df68c79e826e37b895bc359a9c0", size = 488976 }, + { url = "https://files.pythonhosted.org/packages/37/57/ee347af605d867f712be7029bb94c8c071732a4b44792e3176fa3c612d39/watchfiles-1.1.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:bfb5862016acc9b869bb57284e6cb35fdf8e22fe59f7548858e2f971d045f150", size = 595506 }, + { url = "https://files.pythonhosted.org/packages/a8/78/cc5ab0b86c122047f75e8fc471c67a04dee395daf847d3e59381996c8707/watchfiles-1.1.1-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:319b27255aacd9923b8a276bb14d21a5f7ff82564c744235fc5eae58d95422ae", size = 474936 }, + { url = "https://files.pythonhosted.org/packages/62/da/def65b170a3815af7bd40a3e7010bf6ab53089ef1b75d05dd5385b87cf08/watchfiles-1.1.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c755367e51db90e75b19454b680903631d41f9e3607fbd941d296a020c2d752d", size = 456147 }, + { url = "https://files.pythonhosted.org/packages/57/99/da6573ba71166e82d288d4df0839128004c67d2778d3b566c138695f5c0b/watchfiles-1.1.1-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:c22c776292a23bfc7237a98f791b9ad3144b02116ff10d820829ce62dff46d0b", size = 630007 }, + { url = "https://files.pythonhosted.org/packages/a8/51/7439c4dd39511368849eb1e53279cd3454b4a4dbace80bab88feeb83c6b5/watchfiles-1.1.1-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:3a476189be23c3686bc2f4321dd501cb329c0a0469e77b7b534ee10129ae6374", size = 622280 }, + { url = "https://files.pythonhosted.org/packages/95/9c/8ed97d4bba5db6fdcdb2b298d3898f2dd5c20f6b73aee04eabe56c59677e/watchfiles-1.1.1-cp313-cp313-win32.whl", hash = "sha256:bf0a91bfb5574a2f7fc223cf95eeea79abfefa404bf1ea5e339c0c1560ae99a0", size = 272056 }, + { url = "https://files.pythonhosted.org/packages/1f/f3/c14e28429f744a260d8ceae18bf58c1d5fa56b50d006a7a9f80e1882cb0d/watchfiles-1.1.1-cp313-cp313-win_amd64.whl", hash = "sha256:52e06553899e11e8074503c8e716d574adeeb7e68913115c4b3653c53f9bae42", size = 288162 }, + { url = "https://files.pythonhosted.org/packages/dc/61/fe0e56c40d5cd29523e398d31153218718c5786b5e636d9ae8ae79453d27/watchfiles-1.1.1-cp313-cp313-win_arm64.whl", hash = "sha256:ac3cc5759570cd02662b15fbcd9d917f7ecd47efe0d6b40474eafd246f91ea18", size = 277909 }, + { url = "https://files.pythonhosted.org/packages/79/42/e0a7d749626f1e28c7108a99fb9bf524b501bbbeb9b261ceecde644d5a07/watchfiles-1.1.1-cp313-cp313t-macosx_10_12_x86_64.whl", hash = "sha256:563b116874a9a7ce6f96f87cd0b94f7faf92d08d0021e837796f0a14318ef8da", size = 403389 }, + { url = "https://files.pythonhosted.org/packages/15/49/08732f90ce0fbbc13913f9f215c689cfc9ced345fb1bcd8829a50007cc8d/watchfiles-1.1.1-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:3ad9fe1dae4ab4212d8c91e80b832425e24f421703b5a42ef2e4a1e215aff051", size = 389964 }, + { url = "https://files.pythonhosted.org/packages/27/0d/7c315d4bd5f2538910491a0393c56bf70d333d51bc5b34bee8e68e8cea19/watchfiles-1.1.1-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ce70f96a46b894b36eba678f153f052967a0d06d5b5a19b336ab0dbbd029f73e", size = 448114 }, + { url = "https://files.pythonhosted.org/packages/c3/24/9e096de47a4d11bc4df41e9d1e61776393eac4cb6eb11b3e23315b78b2cc/watchfiles-1.1.1-cp313-cp313t-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:cb467c999c2eff23a6417e58d75e5828716f42ed8289fe6b77a7e5a91036ca70", size = 460264 }, + { url = "https://files.pythonhosted.org/packages/cc/0f/e8dea6375f1d3ba5fcb0b3583e2b493e77379834c74fd5a22d66d85d6540/watchfiles-1.1.1-cp313-cp313t-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:836398932192dae4146c8f6f737d74baeac8b70ce14831a239bdb1ca882fc261", size = 487877 }, + { url = "https://files.pythonhosted.org/packages/ac/5b/df24cfc6424a12deb41503b64d42fbea6b8cb357ec62ca84a5a3476f654a/watchfiles-1.1.1-cp313-cp313t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:743185e7372b7bc7c389e1badcc606931a827112fbbd37f14c537320fca08620", size = 595176 }, + { url = "https://files.pythonhosted.org/packages/8f/b5/853b6757f7347de4e9b37e8cc3289283fb983cba1ab4d2d7144694871d9c/watchfiles-1.1.1-cp313-cp313t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:afaeff7696e0ad9f02cbb8f56365ff4686ab205fcf9c4c5b6fdfaaa16549dd04", size = 473577 }, + { url = "https://files.pythonhosted.org/packages/e1/f7/0a4467be0a56e80447c8529c9fce5b38eab4f513cb3d9bf82e7392a5696b/watchfiles-1.1.1-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3f7eb7da0eb23aa2ba036d4f616d46906013a68caf61b7fdbe42fc8b25132e77", size = 455425 }, + { url = "https://files.pythonhosted.org/packages/8e/e0/82583485ea00137ddf69bc84a2db88bd92ab4a6e3c405e5fb878ead8d0e7/watchfiles-1.1.1-cp313-cp313t-musllinux_1_1_aarch64.whl", hash = "sha256:831a62658609f0e5c64178211c942ace999517f5770fe9436be4c2faeba0c0ef", size = 628826 }, + { url = "https://files.pythonhosted.org/packages/28/9a/a785356fccf9fae84c0cc90570f11702ae9571036fb25932f1242c82191c/watchfiles-1.1.1-cp313-cp313t-musllinux_1_1_x86_64.whl", hash = "sha256:f9a2ae5c91cecc9edd47e041a930490c31c3afb1f5e6d71de3dc671bfaca02bf", size = 622208 }, + { url = "https://files.pythonhosted.org/packages/c3/f4/0872229324ef69b2c3edec35e84bd57a1289e7d3fe74588048ed8947a323/watchfiles-1.1.1-cp314-cp314-macosx_10_12_x86_64.whl", hash = "sha256:d1715143123baeeaeadec0528bb7441103979a1d5f6fd0e1f915383fea7ea6d5", size = 404315 }, + { url = "https://files.pythonhosted.org/packages/7b/22/16d5331eaed1cb107b873f6ae1b69e9ced582fcf0c59a50cd84f403b1c32/watchfiles-1.1.1-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:39574d6370c4579d7f5d0ad940ce5b20db0e4117444e39b6d8f99db5676c52fd", size = 390869 }, + { url = "https://files.pythonhosted.org/packages/b2/7e/5643bfff5acb6539b18483128fdc0ef2cccc94a5b8fbda130c823e8ed636/watchfiles-1.1.1-cp314-cp314-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7365b92c2e69ee952902e8f70f3ba6360d0d596d9299d55d7d386df84b6941fb", size = 449919 }, + { url = "https://files.pythonhosted.org/packages/51/2e/c410993ba5025a9f9357c376f48976ef0e1b1aefb73b97a5ae01a5972755/watchfiles-1.1.1-cp314-cp314-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:bfff9740c69c0e4ed32416f013f3c45e2ae42ccedd1167ef2d805c000b6c71a5", size = 460845 }, + { url = "https://files.pythonhosted.org/packages/8e/a4/2df3b404469122e8680f0fcd06079317e48db58a2da2950fb45020947734/watchfiles-1.1.1-cp314-cp314-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b27cf2eb1dda37b2089e3907d8ea92922b673c0c427886d4edc6b94d8dfe5db3", size = 489027 }, + { url = "https://files.pythonhosted.org/packages/ea/84/4587ba5b1f267167ee715b7f66e6382cca6938e0a4b870adad93e44747e6/watchfiles-1.1.1-cp314-cp314-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:526e86aced14a65a5b0ec50827c745597c782ff46b571dbfe46192ab9e0b3c33", size = 595615 }, + { url = "https://files.pythonhosted.org/packages/6a/0f/c6988c91d06e93cd0bb3d4a808bcf32375ca1904609835c3031799e3ecae/watchfiles-1.1.1-cp314-cp314-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:04e78dd0b6352db95507fd8cb46f39d185cf8c74e4cf1e4fbad1d3df96faf510", size = 474836 }, + { url = "https://files.pythonhosted.org/packages/b4/36/ded8aebea91919485b7bbabbd14f5f359326cb5ec218cd67074d1e426d74/watchfiles-1.1.1-cp314-cp314-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5c85794a4cfa094714fb9c08d4a218375b2b95b8ed1666e8677c349906246c05", size = 455099 }, + { url = "https://files.pythonhosted.org/packages/98/e0/8c9bdba88af756a2fce230dd365fab2baf927ba42cd47521ee7498fd5211/watchfiles-1.1.1-cp314-cp314-musllinux_1_1_aarch64.whl", hash = "sha256:74d5012b7630714b66be7b7b7a78855ef7ad58e8650c73afc4c076a1f480a8d6", size = 630626 }, + { url = "https://files.pythonhosted.org/packages/2a/84/a95db05354bf2d19e438520d92a8ca475e578c647f78f53197f5a2f17aaf/watchfiles-1.1.1-cp314-cp314-musllinux_1_1_x86_64.whl", hash = "sha256:8fbe85cb3201c7d380d3d0b90e63d520f15d6afe217165d7f98c9c649654db81", size = 622519 }, + { url = "https://files.pythonhosted.org/packages/1d/ce/d8acdc8de545de995c339be67711e474c77d643555a9bb74a9334252bd55/watchfiles-1.1.1-cp314-cp314-win32.whl", hash = "sha256:3fa0b59c92278b5a7800d3ee7733da9d096d4aabcfabb9a928918bd276ef9b9b", size = 272078 }, + { url = "https://files.pythonhosted.org/packages/c4/c9/a74487f72d0451524be827e8edec251da0cc1fcf111646a511ae752e1a3d/watchfiles-1.1.1-cp314-cp314-win_amd64.whl", hash = "sha256:c2047d0b6cea13b3316bdbafbfa0c4228ae593d995030fda39089d36e64fc03a", size = 287664 }, + { url = "https://files.pythonhosted.org/packages/df/b8/8ac000702cdd496cdce998c6f4ee0ca1f15977bba51bdf07d872ebdfc34c/watchfiles-1.1.1-cp314-cp314-win_arm64.whl", hash = "sha256:842178b126593addc05acf6fce960d28bc5fae7afbaa2c6c1b3a7b9460e5be02", size = 277154 }, + { url = "https://files.pythonhosted.org/packages/47/a8/e3af2184707c29f0f14b1963c0aace6529f9d1b8582d5b99f31bbf42f59e/watchfiles-1.1.1-cp314-cp314t-macosx_10_12_x86_64.whl", hash = "sha256:88863fbbc1a7312972f1c511f202eb30866370ebb8493aef2812b9ff28156a21", size = 403820 }, + { url = "https://files.pythonhosted.org/packages/c0/ec/e47e307c2f4bd75f9f9e8afbe3876679b18e1bcec449beca132a1c5ffb2d/watchfiles-1.1.1-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:55c7475190662e202c08c6c0f4d9e345a29367438cf8e8037f3155e10a88d5a5", size = 390510 }, + { url = "https://files.pythonhosted.org/packages/d5/a0/ad235642118090f66e7b2f18fd5c42082418404a79205cdfca50b6309c13/watchfiles-1.1.1-cp314-cp314t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3f53fa183d53a1d7a8852277c92b967ae99c2d4dcee2bfacff8868e6e30b15f7", size = 448408 }, + { url = "https://files.pythonhosted.org/packages/df/85/97fa10fd5ff3332ae17e7e40e20784e419e28521549780869f1413742e9d/watchfiles-1.1.1-cp314-cp314t-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:6aae418a8b323732fa89721d86f39ec8f092fc2af67f4217a2b07fd3e93c6101", size = 458968 }, + { url = "https://files.pythonhosted.org/packages/47/c2/9059c2e8966ea5ce678166617a7f75ecba6164375f3b288e50a40dc6d489/watchfiles-1.1.1-cp314-cp314t-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f096076119da54a6080e8920cbdaac3dbee667eb91dcc5e5b78840b87415bd44", size = 488096 }, + { url = "https://files.pythonhosted.org/packages/94/44/d90a9ec8ac309bc26db808a13e7bfc0e4e78b6fc051078a554e132e80160/watchfiles-1.1.1-cp314-cp314t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:00485f441d183717038ed2e887a7c868154f216877653121068107b227a2f64c", size = 596040 }, + { url = "https://files.pythonhosted.org/packages/95/68/4e3479b20ca305cfc561db3ed207a8a1c745ee32bf24f2026a129d0ddb6e/watchfiles-1.1.1-cp314-cp314t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a55f3e9e493158d7bfdb60a1165035f1cf7d320914e7b7ea83fe22c6023b58fc", size = 473847 }, + { url = "https://files.pythonhosted.org/packages/4f/55/2af26693fd15165c4ff7857e38330e1b61ab8c37d15dc79118cdba115b7a/watchfiles-1.1.1-cp314-cp314t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8c91ed27800188c2ae96d16e3149f199d62f86c7af5f5f4d2c61a3ed8cd3666c", size = 455072 }, + { url = "https://files.pythonhosted.org/packages/66/1d/d0d200b10c9311ec25d2273f8aad8c3ef7cc7ea11808022501811208a750/watchfiles-1.1.1-cp314-cp314t-musllinux_1_1_aarch64.whl", hash = "sha256:311ff15a0bae3714ffb603e6ba6dbfba4065ab60865d15a6ec544133bdb21099", size = 629104 }, + { url = "https://files.pythonhosted.org/packages/e3/bd/fa9bb053192491b3867ba07d2343d9f2252e00811567d30ae8d0f78136fe/watchfiles-1.1.1-cp314-cp314t-musllinux_1_1_x86_64.whl", hash = "sha256:a916a2932da8f8ab582f242c065f5c81bed3462849ca79ee357dd9551b0e9b01", size = 622112 }, ] [[package]] name = "websockets" version = "15.0.1" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/21/e6/26d09fab466b7ca9c7737474c52be4f76a40301b08362eb2dbc19dcc16c1/websockets-15.0.1.tar.gz", hash = "sha256:82544de02076bafba038ce055ee6412d68da13ab47f0c60cab827346de828dee", size = 177016, upload-time = "2025-03-05T20:03:41.606Z" } +sdist = { url = "https://files.pythonhosted.org/packages/21/e6/26d09fab466b7ca9c7737474c52be4f76a40301b08362eb2dbc19dcc16c1/websockets-15.0.1.tar.gz", hash = "sha256:82544de02076bafba038ce055ee6412d68da13ab47f0c60cab827346de828dee", size = 177016 } wheels = [ - { url = "https://files.pythonhosted.org/packages/cb/9f/51f0cf64471a9d2b4d0fc6c534f323b664e7095640c34562f5182e5a7195/websockets-15.0.1-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:ee443ef070bb3b6ed74514f5efaa37a252af57c90eb33b956d35c8e9c10a1931", size = 175440, upload-time = "2025-03-05T20:02:36.695Z" }, - { url = "https://files.pythonhosted.org/packages/8a/05/aa116ec9943c718905997412c5989f7ed671bc0188ee2ba89520e8765d7b/websockets-15.0.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:5a939de6b7b4e18ca683218320fc67ea886038265fd1ed30173f5ce3f8e85675", size = 173098, upload-time = "2025-03-05T20:02:37.985Z" }, - { url = "https://files.pythonhosted.org/packages/ff/0b/33cef55ff24f2d92924923c99926dcce78e7bd922d649467f0eda8368923/websockets-15.0.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:746ee8dba912cd6fc889a8147168991d50ed70447bf18bcda7039f7d2e3d9151", size = 173329, upload-time = "2025-03-05T20:02:39.298Z" }, - { url = "https://files.pythonhosted.org/packages/31/1d/063b25dcc01faa8fada1469bdf769de3768b7044eac9d41f734fd7b6ad6d/websockets-15.0.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:595b6c3969023ecf9041b2936ac3827e4623bfa3ccf007575f04c5a6aa318c22", size = 183111, upload-time = "2025-03-05T20:02:40.595Z" }, - { url = "https://files.pythonhosted.org/packages/93/53/9a87ee494a51bf63e4ec9241c1ccc4f7c2f45fff85d5bde2ff74fcb68b9e/websockets-15.0.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3c714d2fc58b5ca3e285461a4cc0c9a66bd0e24c5da9911e30158286c9b5be7f", size = 182054, upload-time = "2025-03-05T20:02:41.926Z" }, - { url = "https://files.pythonhosted.org/packages/ff/b2/83a6ddf56cdcbad4e3d841fcc55d6ba7d19aeb89c50f24dd7e859ec0805f/websockets-15.0.1-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0f3c1e2ab208db911594ae5b4f79addeb3501604a165019dd221c0bdcabe4db8", size = 182496, upload-time = "2025-03-05T20:02:43.304Z" }, - { url = "https://files.pythonhosted.org/packages/98/41/e7038944ed0abf34c45aa4635ba28136f06052e08fc2168520bb8b25149f/websockets-15.0.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:229cf1d3ca6c1804400b0a9790dc66528e08a6a1feec0d5040e8b9eb14422375", size = 182829, upload-time = "2025-03-05T20:02:48.812Z" }, - { url = "https://files.pythonhosted.org/packages/e0/17/de15b6158680c7623c6ef0db361da965ab25d813ae54fcfeae2e5b9ef910/websockets-15.0.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:756c56e867a90fb00177d530dca4b097dd753cde348448a1012ed6c5131f8b7d", size = 182217, upload-time = "2025-03-05T20:02:50.14Z" }, - { url = "https://files.pythonhosted.org/packages/33/2b/1f168cb6041853eef0362fb9554c3824367c5560cbdaad89ac40f8c2edfc/websockets-15.0.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:558d023b3df0bffe50a04e710bc87742de35060580a293c2a984299ed83bc4e4", size = 182195, upload-time = "2025-03-05T20:02:51.561Z" }, - { url = "https://files.pythonhosted.org/packages/86/eb/20b6cdf273913d0ad05a6a14aed4b9a85591c18a987a3d47f20fa13dcc47/websockets-15.0.1-cp313-cp313-win32.whl", hash = "sha256:ba9e56e8ceeeedb2e080147ba85ffcd5cd0711b89576b83784d8605a7df455fa", size = 176393, upload-time = "2025-03-05T20:02:53.814Z" }, - { url = "https://files.pythonhosted.org/packages/1b/6c/c65773d6cab416a64d191d6ee8a8b1c68a09970ea6909d16965d26bfed1e/websockets-15.0.1-cp313-cp313-win_amd64.whl", hash = "sha256:e09473f095a819042ecb2ab9465aee615bd9c2028e4ef7d933600a8401c79561", size = 176837, upload-time = "2025-03-05T20:02:55.237Z" }, - { url = "https://files.pythonhosted.org/packages/fa/a8/5b41e0da817d64113292ab1f8247140aac61cbf6cfd085d6a0fa77f4984f/websockets-15.0.1-py3-none-any.whl", hash = "sha256:f7a866fbc1e97b5c617ee4116daaa09b722101d4a3c170c787450ba409f9736f", size = 169743, upload-time = "2025-03-05T20:03:39.41Z" }, + { url = "https://files.pythonhosted.org/packages/cb/9f/51f0cf64471a9d2b4d0fc6c534f323b664e7095640c34562f5182e5a7195/websockets-15.0.1-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:ee443ef070bb3b6ed74514f5efaa37a252af57c90eb33b956d35c8e9c10a1931", size = 175440 }, + { url = "https://files.pythonhosted.org/packages/8a/05/aa116ec9943c718905997412c5989f7ed671bc0188ee2ba89520e8765d7b/websockets-15.0.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:5a939de6b7b4e18ca683218320fc67ea886038265fd1ed30173f5ce3f8e85675", size = 173098 }, + { url = "https://files.pythonhosted.org/packages/ff/0b/33cef55ff24f2d92924923c99926dcce78e7bd922d649467f0eda8368923/websockets-15.0.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:746ee8dba912cd6fc889a8147168991d50ed70447bf18bcda7039f7d2e3d9151", size = 173329 }, + { url = "https://files.pythonhosted.org/packages/31/1d/063b25dcc01faa8fada1469bdf769de3768b7044eac9d41f734fd7b6ad6d/websockets-15.0.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:595b6c3969023ecf9041b2936ac3827e4623bfa3ccf007575f04c5a6aa318c22", size = 183111 }, + { url = "https://files.pythonhosted.org/packages/93/53/9a87ee494a51bf63e4ec9241c1ccc4f7c2f45fff85d5bde2ff74fcb68b9e/websockets-15.0.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3c714d2fc58b5ca3e285461a4cc0c9a66bd0e24c5da9911e30158286c9b5be7f", size = 182054 }, + { url = "https://files.pythonhosted.org/packages/ff/b2/83a6ddf56cdcbad4e3d841fcc55d6ba7d19aeb89c50f24dd7e859ec0805f/websockets-15.0.1-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0f3c1e2ab208db911594ae5b4f79addeb3501604a165019dd221c0bdcabe4db8", size = 182496 }, + { url = "https://files.pythonhosted.org/packages/98/41/e7038944ed0abf34c45aa4635ba28136f06052e08fc2168520bb8b25149f/websockets-15.0.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:229cf1d3ca6c1804400b0a9790dc66528e08a6a1feec0d5040e8b9eb14422375", size = 182829 }, + { url = "https://files.pythonhosted.org/packages/e0/17/de15b6158680c7623c6ef0db361da965ab25d813ae54fcfeae2e5b9ef910/websockets-15.0.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:756c56e867a90fb00177d530dca4b097dd753cde348448a1012ed6c5131f8b7d", size = 182217 }, + { url = "https://files.pythonhosted.org/packages/33/2b/1f168cb6041853eef0362fb9554c3824367c5560cbdaad89ac40f8c2edfc/websockets-15.0.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:558d023b3df0bffe50a04e710bc87742de35060580a293c2a984299ed83bc4e4", size = 182195 }, + { url = "https://files.pythonhosted.org/packages/86/eb/20b6cdf273913d0ad05a6a14aed4b9a85591c18a987a3d47f20fa13dcc47/websockets-15.0.1-cp313-cp313-win32.whl", hash = "sha256:ba9e56e8ceeeedb2e080147ba85ffcd5cd0711b89576b83784d8605a7df455fa", size = 176393 }, + { url = "https://files.pythonhosted.org/packages/1b/6c/c65773d6cab416a64d191d6ee8a8b1c68a09970ea6909d16965d26bfed1e/websockets-15.0.1-cp313-cp313-win_amd64.whl", hash = "sha256:e09473f095a819042ecb2ab9465aee615bd9c2028e4ef7d933600a8401c79561", size = 176837 }, + { url = "https://files.pythonhosted.org/packages/fa/a8/5b41e0da817d64113292ab1f8247140aac61cbf6cfd085d6a0fa77f4984f/websockets-15.0.1-py3-none-any.whl", hash = "sha256:f7a866fbc1e97b5c617ee4116daaa09b722101d4a3c170c787450ba409f9736f", size = 169743 }, ] [[package]] @@ -2331,7 +2419,7 @@ source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "markupsafe" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/6a/c7/96d10183c3470f1836846f7b9527d6cb0b6c2226ebca40f36fa29f23de60/wtforms-3.1.2.tar.gz", hash = "sha256:f8d76180d7239c94c6322f7990ae1216dae3659b7aa1cee94b6318bdffb474b9", size = 134705, upload-time = "2024-01-06T07:52:41.075Z" } +sdist = { url = "https://files.pythonhosted.org/packages/6a/c7/96d10183c3470f1836846f7b9527d6cb0b6c2226ebca40f36fa29f23de60/wtforms-3.1.2.tar.gz", hash = "sha256:f8d76180d7239c94c6322f7990ae1216dae3659b7aa1cee94b6318bdffb474b9", size = 134705 } wheels = [ - { url = "https://files.pythonhosted.org/packages/18/19/c3232f35e24dccfad372e9f341c4f3a1166ae7c66e4e1351a9467c921cc1/wtforms-3.1.2-py3-none-any.whl", hash = "sha256:bf831c042829c8cdbad74c27575098d541d039b1faa74c771545ecac916f2c07", size = 145961, upload-time = "2024-01-06T07:52:43.023Z" }, + { url = "https://files.pythonhosted.org/packages/18/19/c3232f35e24dccfad372e9f341c4f3a1166ae7c66e4e1351a9467c921cc1/wtforms-3.1.2-py3-none-any.whl", hash = "sha256:bf831c042829c8cdbad74c27575098d541d039b1faa74c771545ecac916f2c07", size = 145961 }, ] From 623961dfd2744cd7c131ef56f69cc09063a0a7e9 Mon Sep 17 00:00:00 2001 From: Simon van Lierde Date: Fri, 7 Nov 2025 16:55:18 +0000 Subject: [PATCH 31/71] fix(backend): Use try except else pattern --- backend/app/core/redis.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/backend/app/core/redis.py b/backend/app/core/redis.py index 31e5302..ea99feb 100644 --- a/backend/app/core/redis.py +++ b/backend/app/core/redis.py @@ -35,11 +35,14 @@ async def init_redis() -> Redis | None: # Verify connection on startup await redis_client.pubsub().ping() logger.info("Redis client initialized and connected: %s:%s", settings.redis_host, settings.redis_port) - return redis_client except (TimeoutError, RedisError, OSError, ConnectionError) as e: - logger.warning("Failed to connect to Redis during initialization: %s. Application will continue without Redis.", e) + logger.warning( + "Failed to connect to Redis during initialization: %s. Application will continue without Redis.", e + ) return None + else: + return redis_client async def close_redis(redis_client: Redis) -> None: From dc94217c46422a5d36f23ac90ccc114e0aec9c89 Mon Sep 17 00:00:00 2001 From: Simon van Lierde Date: Fri, 7 Nov 2025 18:53:20 +0100 Subject: [PATCH 32/71] fix(docker): Persist cache data in prod --- compose.prod.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/compose.prod.yml b/compose.prod.yml index 82908a0..e73373c 100644 --- a/compose.prod.yml +++ b/compose.prod.yml @@ -63,3 +63,6 @@ services: docs: # Disable live reload for production command: ["serve", "--dev-addr=0.0.0.0:8000", "--no-livereload"] + +volumes: + cache_data: From 009798234165e116c8c81b5104bf6150b6ef3d18 Mon Sep 17 00:00:00 2001 From: Simon van Lierde Date: Fri, 7 Nov 2025 23:02:34 +0100 Subject: [PATCH 33/71] fix(backend): Move Annotated validation from database models to Create and Udpate schemas --- .../app/api/common/models/custom_fields.py | 9 --------- .../app/api/common/schemas/custom_fields.py | 13 +++++++++++++ backend/app/api/file_storage/models/models.py | 14 +++++++++----- backend/app/api/file_storage/schemas.py | 10 ++++++++-- backend/app/api/newsletter/models.py | 8 ++++---- backend/app/api/newsletter/schemas.py | 6 +++++- backend/app/api/plugins/rpi_cam/models.py | 19 ++++++++++++------- backend/app/api/plugins/rpi_cam/schemas.py | 6 ++++-- 8 files changed, 55 insertions(+), 30 deletions(-) delete mode 100644 backend/app/api/common/models/custom_fields.py create mode 100644 backend/app/api/common/schemas/custom_fields.py diff --git a/backend/app/api/common/models/custom_fields.py b/backend/app/api/common/models/custom_fields.py deleted file mode 100644 index 343940e..0000000 --- a/backend/app/api/common/models/custom_fields.py +++ /dev/null @@ -1,9 +0,0 @@ -"""Custom Pydantic fields for database models.""" - -from typing import Annotated - -from pydantic import AnyUrl, HttpUrl, PlainSerializer - -# HTTP URL that is stored as string in the database. -HttpUrlInDB = Annotated[HttpUrl, PlainSerializer(lambda x: str(x), return_type=str)] -AnyUrlInDB = Annotated[AnyUrl, PlainSerializer(lambda x: str(x), return_type=str)] diff --git a/backend/app/api/common/schemas/custom_fields.py b/backend/app/api/common/schemas/custom_fields.py new file mode 100644 index 0000000..c50df7a --- /dev/null +++ b/backend/app/api/common/schemas/custom_fields.py @@ -0,0 +1,13 @@ +"""Shared fields for DTO schemas.""" + +from typing import Annotated + +from pydantic import AnyUrl, HttpUrl, PlainSerializer, StringConstraints + +# HTTP URL that is stored as string in the database. +type HttpUrlToDB = Annotated[ + HttpUrl, PlainSerializer(lambda x: str(x), return_type=str), StringConstraints(max_length=250) +] +type AnyUrlToDB = Annotated[ + AnyUrl, PlainSerializer(lambda x: str(x), return_type=str), StringConstraints(max_length=250) +] diff --git a/backend/app/api/file_storage/models/models.py b/backend/app/api/file_storage/models/models.py index ae78b78..d69fa48 100644 --- a/backend/app/api/file_storage/models/models.py +++ b/backend/app/api/file_storage/models/models.py @@ -10,11 +10,10 @@ from markupsafe import Markup from pydantic import UUID4, ConfigDict from sqlalchemy.dialects.postgresql import JSONB -from sqlmodel import AutoString, Column, Field, Relationship +from sqlmodel import Column, Field, Relationship from sqlmodel import Enum as SAEnum from app.api.common.models.base import APIModelName, CustomBase, SingleParentMixin, TimeStampMixinBare -from app.api.common.models.custom_fields import AnyUrlInDB from app.api.data_collection.models import Product from app.api.file_storage.exceptions import FastAPIStorageFileNotFoundError from app.api.file_storage.models.custom_types import FileType, ImageType @@ -49,7 +48,9 @@ class FileBase(CustomBase): class File(FileBase, TimeStampMixinBare, SingleParentMixin[FileParentType], table=True): """Database model for generic files stored in the local file system, using FastAPI-Storages.""" - id: UUID4 = Field(default_factory=uuid.uuid4, primary_key=True) + # HACK: Redefine id to allow None in the backend which is required by the > 2.12 pydantic/sqlmodel combo + id: UUID4 | None = Field(default_factory=uuid.uuid4, primary_key=True, nullable=False) + filename: str = Field(description="Original file name of the file. Automatically generated.") # TODO: Add custom file paths based on parent object (Product, year, etc.) @@ -111,7 +112,10 @@ class ImageBase(CustomBase): class Image(ImageBase, TimeStampMixinBare, SingleParentMixin, table=True): """Database model for images stored in the local file system, using FastAPI-Storages.""" - id: UUID4 = Field(default_factory=uuid.uuid4, primary_key=True) + # HACK: Redefine id to allow None in the backend which is required by the > 2.12 pydantic/sqlmodel combo + # TODO: To avoid this hack, for all database models, create a InDB child class that has non-optional id field + id: UUID4 | None = Field(default_factory=uuid.uuid4, primary_key=True, nullable=False) + filename: str = Field(description="Original file name of the image. Automatically generated.", nullable=False) file: ImageType = Field( sa_column=Column(ImageType, nullable=False), @@ -153,7 +157,7 @@ def image_preview(self, size: int = 100) -> str: class VideoBase(CustomBase): """Base model for videos stored online.""" - url: AnyUrlInDB = Field(description="URL linking to the video", sa_type=AutoString, nullable=False) + url: str = Field(description="URL linking to the video", nullable=False) title: str | None = Field(default=None, max_length=100, description="Title of the video") description: str | None = Field(default=None, max_length=500, description="Description of the video") video_metadata: dict[str, Any] | None = Field( diff --git a/backend/app/api/file_storage/schemas.py b/backend/app/api/file_storage/schemas.py index ab4bf4b..ed737a0 100644 --- a/backend/app/api/file_storage/schemas.py +++ b/backend/app/api/file_storage/schemas.py @@ -3,10 +3,11 @@ from typing import Annotated, Any from fastapi import UploadFile -from pydantic import AfterValidator, Field, HttpUrl, Json, PositiveInt +from pydantic import AfterValidator, Field, Json, PositiveInt from app.api.common.models.custom_types import IDT from app.api.common.schemas.base import BaseCreateSchema, BaseReadSchemaWithTimeStamp, BaseUpdateSchema +from app.api.common.schemas.custom_fields import AnyUrlToDB from app.api.file_storage.models.models import FileBase, FileParentType, ImageBase, ImageParentType, VideoBase ### Constants ### @@ -171,10 +172,15 @@ class ImageUpdate(BaseUpdateSchema, ImageBase): class VideoCreateWithinProduct(BaseCreateSchema, VideoBase): """Schema for creating a video.""" + # Override url field to add validation + url: AnyUrlToDB + class VideoCreate(BaseCreateSchema, VideoBase): """Schema for creating a video.""" + # Override url field to add validation + url: AnyUrlToDB product_id: PositiveInt @@ -191,7 +197,7 @@ class VideoRead(BaseReadSchemaWithTimeStamp, VideoBase): class VideoUpdate(BaseUpdateSchema): """Schema for updating a video.""" - url: HttpUrl | None = Field(default=None, max_length=250, description="HTTP(S) URL linking to the video") + url: AnyUrlToDB | None = Field(default=None, description="URL linking to the video") title: str | None = Field(default=None, max_length=100, description="Title of the video") description: str | None = Field(default=None, max_length=500, description="Description of the video") video_metadata: dict[str, Any] | None = Field(default=None, description="Video metadata as a JSON dict") diff --git a/backend/app/api/newsletter/models.py b/backend/app/api/newsletter/models.py index 1bbdc23..5c16113 100644 --- a/backend/app/api/newsletter/models.py +++ b/backend/app/api/newsletter/models.py @@ -1,9 +1,8 @@ """Database models related to newsletter subscribers.""" import uuid -from typing import Annotated -from pydantic import UUID4, EmailStr, StringConstraints +from pydantic import UUID4, EmailStr from sqlmodel import Field from app.api.common.models.base import CustomBase, TimeStampMixinBare @@ -12,11 +11,12 @@ class NewsletterSubscriberBase(CustomBase): """Base schema for newsletter subscribers.""" - email: Annotated[EmailStr, StringConstraints(strip_whitespace=True)] = Field(index=True, unique=True) + email: EmailStr = Field(index=True, unique=True) class NewsletterSubscriber(NewsletterSubscriberBase, TimeStampMixinBare, table=True): """Database model for newsletter subscribers.""" - id: UUID4 = Field(default_factory=uuid.uuid4, primary_key=True, nullable=False) + # HACK: Redefine id to allow None in the backend which is required by the > 2.12 pydantic/sqlmodel combo + id: UUID4 | None = Field(default_factory=uuid.uuid4, primary_key=True, nullable=False) is_confirmed: bool = Field(default=False) diff --git a/backend/app/api/newsletter/schemas.py b/backend/app/api/newsletter/schemas.py index cacc5bd..0e237a0 100644 --- a/backend/app/api/newsletter/schemas.py +++ b/backend/app/api/newsletter/schemas.py @@ -1,6 +1,8 @@ """DTO schemas for newsletter subscribers.""" -from pydantic import Field +from typing import Annotated + +from pydantic import EmailStr, Field, StringConstraints from app.api.common.schemas.base import BaseCreateSchema, BaseReadSchemaWithTimeStamp from app.api.newsletter.models import NewsletterSubscriberBase @@ -9,6 +11,8 @@ class NewsletterSubscriberCreate(BaseCreateSchema, NewsletterSubscriberBase): """Create schema for newsletter subscribers.""" + email: Annotated[EmailStr, StringConstraints(strip_whitespace=True)] = Field() + class NewsletterSubscriberRead(BaseReadSchemaWithTimeStamp, NewsletterSubscriberBase): """Read schema for newsletter subscribers.""" diff --git a/backend/app/api/plugins/rpi_cam/models.py b/backend/app/api/plugins/rpi_cam/models.py index 974fab6..fae5de8 100644 --- a/backend/app/api/plugins/rpi_cam/models.py +++ b/backend/app/api/plugins/rpi_cam/models.py @@ -14,7 +14,6 @@ from sqlmodel import AutoString, Field, Relationship from app.api.common.models.base import CustomBase, TimeStampMixinBare -from app.api.common.models.custom_fields import HttpUrlInDB from app.api.plugins.rpi_cam.config import settings from app.api.plugins.rpi_cam.utils.encryption import decrypt_dict, decrypt_str, encrypt_dict @@ -68,23 +67,29 @@ class CameraBase(CustomBase): # NOTE: Local addresses only work when they are on the local network of this API # TODO: Add support for server communication to local network cameras for users via websocket or similar - # NOTE: Database models will have url as string type. This is likely because of how sa_type=Autostring works - # This means HttpUrl methods are not available in database model instances. - # TODO: Only validate the URL format in Pydantic schemas and store as plain string in the database model. - url: HttpUrlInDB = Field(description="HTTP(S) URL where the camera API is hosted", sa_type=AutoString) + # NOTE: URL validation is done in the Pydantic schemas (CameraCreate/CameraUpdate). + # The database stores it as a plain string. + url: str = Field(description="HTTP(S) URL where the camera API is hosted", sa_type=AutoString) class Camera(CameraBase, TimeStampMixinBare, table=True): """Database model for Camera.""" - id: UUID4 = Field(default_factory=uuid.uuid4, primary_key=True) + # HACK: Redefine id to allow None in the backend which is required by the > 2.12 pydantic/sqlmodel combo + id: UUID4 | None = Field(default_factory=uuid.uuid4, primary_key=True, nullable=False) + encrypted_api_key: str = Field(nullable=False) # TODO: Consider merging encrypted_auth_headers and encrypted_api_key into a single encrypted_credentials field encrypted_auth_headers: str | None = Field(default=None) # Many-to-one relationship with User owner_id: UUID4 = Field(foreign_key="user.id") - owner: "User" = Relationship() # One-way relationship to maintain plugin isolation + owner: "User" = Relationship( # One-way relationship to maintain plugin isolation + sa_relationship_kwargs={ + "primaryjoin": "Camera.owner_id == User.id", + "foreign_keys": "[Camera.owner_id]", + } + ) @computed_field @cached_property diff --git a/backend/app/api/plugins/rpi_cam/schemas.py b/backend/app/api/plugins/rpi_cam/schemas.py index 18de973..1240978 100644 --- a/backend/app/api/plugins/rpi_cam/schemas.py +++ b/backend/app/api/plugins/rpi_cam/schemas.py @@ -9,7 +9,6 @@ AfterValidator, BaseModel, Field, - HttpUrl, PlainSerializer, SecretStr, ) @@ -20,6 +19,7 @@ BaseReadSchemaWithTimeStamp, BaseUpdateSchema, ) +from app.api.common.schemas.custom_fields import HttpUrlToDB from app.api.plugins.rpi_cam.config import settings from app.api.plugins.rpi_cam.models import Camera, CameraBase, CameraStatus from app.api.plugins.rpi_cam.utils.encryption import decrypt_str @@ -107,6 +107,8 @@ def validate_auth_headers_size(headers: list[HeaderCreate] | None) -> list[Heade class CameraCreate(BaseCreateSchema, CameraBase): """Schema for creating a camera.""" + # Override url field to add validation + url: HttpUrlToDB = Field(description="HTTP(S) URL where the camera API is hosted") auth_headers: OptionalAuthHeaderCreateList @@ -156,7 +158,7 @@ class CameraUpdate(BaseUpdateSchema): name: str | None = Field(default=None, min_length=2, max_length=100) description: str | None = Field(default=None, max_length=500) - url: HttpUrl | None = Field(default=None, description="HTTP(S) URL where the camera API is hosted") + url: HttpUrlToDB | None = Field(default=None, description="HTTP(S) URL where the camera API is hosted") auth_headers: OptionalAuthHeaderCreateList # TODO: Make it only possible to change ownership to existing users within the same organization From 5194bd3f272fa2993373dc6da13ad3431f8e8aec Mon Sep 17 00:00:00 2001 From: Simon van Lierde Date: Sat, 8 Nov 2025 11:01:51 +0100 Subject: [PATCH 34/71] feature(backend): Fix Pydantic 2.12 issues and move to python 3.14 --- backend/.python-version | 2 +- backend/Dockerfile | 4 +- backend/Dockerfile.dev | 2 +- backend/Dockerfile.migrations | 4 +- backend/app/api/auth/models.py | 70 +- backend/app/api/common/models/base.py | 2 +- backend/app/api/data_collection/models.py | 8 +- backend/pyproject.toml | 9 +- backend/uv.lock | 1981 +++++++++++---------- codemeta.json | 2 +- 10 files changed, 1082 insertions(+), 1002 deletions(-) diff --git a/backend/.python-version b/backend/.python-version index 24ee5b1..6324d40 100644 --- a/backend/.python-version +++ b/backend/.python-version @@ -1 +1 @@ -3.13 +3.14 diff --git a/backend/Dockerfile b/backend/Dockerfile index 0d3fee1..17b19a7 100644 --- a/backend/Dockerfile +++ b/backend/Dockerfile @@ -1,5 +1,5 @@ # --- Builder stage --- -FROM ghcr.io/astral-sh/uv:0.9-python3.13-trixie-slim@sha256:87db60325200a4fa5e9259fe43ff14c90c429adee952a8efe3f21b278409d09a AS builder +FROM ghcr.io/astral-sh/uv:0.9-python3.14-trixie-slim AS builder # Install git for custom dependencies (fastapi-users-db-sqlmodel) RUN --mount=type=cache,target=/var/cache/apt,sharing=locked \ @@ -34,7 +34,7 @@ RUN --mount=type=cache,target=/root/.cache/uv \ uv sync --locked --no-editable --no-default-groups --group=api # --- Final runtime stage --- -FROM python:3.13-slim +FROM python:3.14-slim # Build arguments ARG WORKDIR=/opt/relab/backend diff --git a/backend/Dockerfile.dev b/backend/Dockerfile.dev index dafcde7..36cea79 100644 --- a/backend/Dockerfile.dev +++ b/backend/Dockerfile.dev @@ -1,6 +1,6 @@ # Development Dockerfile for FastAPI Backend # Note: This requires mounting the source code as a volume in docker-compose.override.yml -FROM ghcr.io/astral-sh/uv:0.9-python3.13-trixie-slim@sha256:87db60325200a4fa5e9259fe43ff14c90c429adee952a8efe3f21b278409d09a +FROM ghcr.io/astral-sh/uv:0.9-python3.14-trixie-slim # Build arguments ARG WORKDIR=/opt/relab/backend diff --git a/backend/Dockerfile.migrations b/backend/Dockerfile.migrations index 92cecd6..73a3932 100644 --- a/backend/Dockerfile.migrations +++ b/backend/Dockerfile.migrations @@ -1,5 +1,5 @@ # --- Builder stage --- -FROM ghcr.io/astral-sh/uv:0.9-python3.13-trixie-slim@sha256:87db60325200a4fa5e9259fe43ff14c90c429adee952a8efe3f21b278409d09a AS builder +FROM ghcr.io/astral-sh/uv:0.9-python3.14-trixie-slim AS builder WORKDIR /opt/relab/backend_migrations @@ -33,7 +33,7 @@ COPY scripts/ scripts/ COPY app/ app/ # --- Final runtime stage --- -FROM python:3.13-slim +FROM python:3.14-slim # Build arguments ARG WORKDIR=/opt/relab/backend_migrations diff --git a/backend/app/api/auth/models.py b/backend/app/api/auth/models.py index 5b507f0..206f81a 100644 --- a/backend/app/api/auth/models.py +++ b/backend/app/api/auth/models.py @@ -36,26 +36,58 @@ class UserBase(BaseModel): model_config = ConfigDict(use_enum_values=True) # pyright: ignore [reportIncompatibleVariableOverride] # This is not a type override, see https://github.com/fastapi/sqlmodel/discussions/855 -class User(UserBase, CustomBaseBare, TimeStampMixinBare, SQLModelBaseUserDB, table=True): +class User(SQLModelBaseUserDB, CustomBaseBare, UserBase, TimeStampMixinBare, table=True): """Database model for platform users.""" + # HACK: Redefine id to allow None in the backend which is required by the > 2.12 pydantic/sqlmodel combo (see https://github.com/fastapi/sqlmodel/issues/1623) + id: UUID4 | None = Field(default_factory=uuid.uuid4, primary_key=True, nullable=False) + # One-to-many relationship with OAuthAccount oauth_accounts: list["OAuthAccount"] = Relationship( back_populates="user", - sa_relationship_kwargs={"lazy": "joined"}, # Required because of FastAPI-Users OAuth implementation + sa_relationship_kwargs={ + "lazy": "joined", # Required because of FastAPI-Users OAuth implementation + "primaryjoin": "User.id == OAuthAccount.user_id", # HACK: Explicitly define join condition because of + "foreign_keys": "[OAuthAccount.user_id]", # pydantic / sqlmodel issues (see https://github.com/fastapi/sqlmodel/issues/1623) + }, # TODO: Check if this is fixed in future versions of pydantic/sqlmodel and we can use automatic + # relationship detection again + ) + products: list["Product"] = Relationship( + back_populates="owner", + sa_relationship_kwargs={ + "primaryjoin": "User.id == Product.owner_id", # HACK: Explicitly define join condition because of + "foreign_keys": "[Product.owner_id]", # pydantic / sqlmodel issues + }, ) - products: list["Product"] = Relationship(back_populates="owner") # Many-to-one relationship with Organization organization_id: UUID4 | None = Field( default=None, - sa_column=Column(ForeignKey("organization.id", use_alter=True, name="fk_user_organization"), nullable=True), + sa_column=Column( + ForeignKey("organization.id", use_alter=True, name="fk_user_organization"), + nullable=True, + ), ) organization: Optional["Organization"] = Relationship( - back_populates="members", sa_relationship_kwargs={"lazy": "selectin", "foreign_keys": "[User.organization_id]"} + back_populates="members", + sa_relationship_kwargs={ + "lazy": "selectin", + "primaryjoin": "User.organization_id == Organization.id", # HACK: Explicitly define join condition because of + "foreign_keys": "[User.organization_id]", # pydantic / sqlmodel issues + }, ) organization_role: OrganizationRole | None = Field(default=None, sa_column=Column(SAEnum(OrganizationRole))) + # One-to-one relationship with owned Organization + owned_organization: Optional["Organization"] = Relationship( + back_populates="owner", + sa_relationship_kwargs={ + "uselist": False, + "primaryjoin": "User.id == Organization.owner_id", # HACK: Explicitly define join condition because of + "foreign_keys": "[Organization.owner_id]", # pydantic / sqlmodel issues + }, + ) + @cached_property def is_organization_owner(self) -> bool: return self.organization_role == OrganizationRole.OWNER @@ -68,8 +100,20 @@ def __str__(self) -> str: class OAuthAccount(SQLModelBaseOAuthAccount, CustomBaseBare, TimeStampMixinBare, table=True): """Database model for OAuth accounts. Note that the main implementation is in the base class.""" + # HACK: Redefine id to allow None in the backend which is required by the > 2.12 pydantic/sqlmodel combo + id: UUID4 | None = Field(default_factory=uuid.uuid4, primary_key=True, nullable=False) + + # HACK: Redefine user_id to ensure ForeignKey is preserved despite mixin interference + user_id: UUID4 = Field(foreign_key="user.id", nullable=False) + # Many-to-one relationship with User - user: User = Relationship(back_populates="oauth_accounts") + user: User = Relationship( + back_populates="oauth_accounts", + sa_relationship_kwargs={ # HACK: Explicitly define join condition because of pydantic / sqlmodel issues + "primaryjoin": "OAuthAccount.user_id == User.id", # (see https://github.com/fastapi/sqlmodel/issues/1623) + "foreign_keys": "[OAuthAccount.user_id]", + }, + ) ### Organization Model ### @@ -84,15 +128,21 @@ class OrganizationBase(CustomBase): class Organization(OrganizationBase, TimeStampMixinBare, table=True): """Database model for organizations.""" - id: UUID4 = Field(default_factory=uuid.uuid4, primary_key=True, nullable=False) + # HACK: Redefine id to allow None in the backend which is required by the > 2.12 pydantic/sqlmodel combo + id: UUID4 | None = Field(default_factory=uuid.uuid4, primary_key=True, nullable=False) # One-to-one relationship with owner User + # Use sa_column with explicit ForeignKey to preserve constraint through mixin inheritance owner_id: UUID4 = Field( - sa_column=Column(ForeignKey("user.id", use_alter=True, name="fk_organization_owner"), nullable=False), + sa_column=Column(ForeignKey("user.id", use_alter=True, name="fk_organization_owner"), nullable=False) ) owner: User = Relationship( - back_populates="organization", - sa_relationship_kwargs={"primaryjoin": "Organization.owner_id == User.id", "foreign_keys": "[User.id]"}, + back_populates="owned_organization", + sa_relationship_kwargs={ + "uselist": False, + "primaryjoin": "Organization.owner_id == User.id", # HACK: Explicitly define join condition because of + "foreign_keys": "[Organization.owner_id]", # pydantic / sqlmodel issues + }, ) # One-to-many relationship with member Users diff --git a/backend/app/api/common/models/base.py b/backend/app/api/common/models/base.py index 1a43b9c..54e3b41 100644 --- a/backend/app/api/common/models/base.py +++ b/backend/app/api/common/models/base.py @@ -4,7 +4,7 @@ from datetime import datetime from enum import Enum from functools import cached_property -from typing import Any, ClassVar, Generic, Self, TypeVar +from typing import Any, ClassVar, Self, TypeVar from pydantic import BaseModel, ConfigDict, computed_field, model_validator from sqlalchemy import TIMESTAMP, func diff --git a/backend/app/api/data_collection/models.py b/backend/app/api/data_collection/models.py index 9afe6fa..4cb5388 100644 --- a/backend/app/api/data_collection/models.py +++ b/backend/app/api/data_collection/models.py @@ -126,7 +126,13 @@ class Product(ProductBase, TimeStampMixinBare, table=True): # One-to-many relationships owner_id: UUID4 = Field(foreign_key="user.id") owner: "User" = Relationship( - back_populates="products", sa_relationship_kwargs={"uselist": False, "lazy": "selectin"} + back_populates="products", + sa_relationship_kwargs={ + "uselist": False, + "lazy": "selectin", + "primaryjoin": "Product.owner_id == User.id", # HACK: Explicitly define join condition because of + "foreign_keys": "[Product.owner_id]", # pydantic / sqlmodel issues (see https://github.com/fastapi/sqlmodel/issues/1623) + }, ) product_type_id: int | None = Field(default=None, foreign_key="producttype.id") diff --git a/backend/pyproject.toml b/backend/pyproject.toml index cd97213..860929e 100644 --- a/backend/pyproject.toml +++ b/backend/pyproject.toml @@ -41,8 +41,7 @@ "mjml>=0.11.1", "pillow >=11.2.1", "psycopg[binary] >=3.2.9", - # TODO: Upgrade to python 3.14 and pydantic 2.12 when SQLModel fixes compatibility issues (see https://github.com/fastapi/sqlmodel/issues/1606) - "pydantic >=2.11,<2.12", + "pydantic >=2.12", "pydantic-extra-types >=2.10.5", "pydantic-settings >=2.10.1", "python-dotenv >=1.1.1", @@ -50,7 +49,7 @@ "redis>=5.2.1", "relab-rpi-cam-models>=0.1.1", "sqlalchemy >=2.0.41", - "sqlmodel >=0.0.24", + "sqlmodel >=0.0.27", "tldextract>=5.3.0", ] requires-python = ">= 3.13" @@ -249,7 +248,7 @@ default-groups = ["api", "dev", "migrations", "tests"] [tool.uv.sources] - # HACK: Fetch FastAPI-Mail from custom fork on GitHub to allow passing existing Redis client and fix compatibility issues with Pydantic > 2.12 and SQLModel (see https://github.com/fastapi/sqlmodel/issues/1623) - fastapi-mail = { git = "https://github.com/simonvanlierde/fastapi-mail", rev = "f32147ec1a450ed22262913c5ac7ec3b67dd0117" } + # HACK: Fetch FastAPI-Mail from custom fork on GitHub to allow passing existing Redis client + fastapi-mail = { git = "https://github.com/simonvanlierde/fastapi-mail", rev = "6c6f04a7afaf3cdced82764009a2f1f2a3c3ee6c" } # Fetch FastAPI-Users-DB-SQLModel from custom fork on GitHub for Pydantic V2 support fastapi-users-db-sqlmodel = { git = "https://github.com/simonvanlierde/fastapi-users-db-sqlmodel", rev = "7e9c4830e53ee20c38e3de80066cb19d7c3efc43" } diff --git a/backend/uv.lock b/backend/uv.lock index cfb072d..c60bc1c 100644 --- a/backend/uv.lock +++ b/backend/uv.lock @@ -1,5 +1,5 @@ version = 1 -revision = 1 +revision = 3 requires-python = ">=3.13" resolution-markers = [ "python_full_version >= '3.14'", @@ -10,9 +10,9 @@ resolution-markers = [ name = "aiosmtplib" version = "4.0.2" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/0f/e1/cc58e0be242f0b410707e001ed22c689435964fcaab42108887426e44fff/aiosmtplib-4.0.2.tar.gz", hash = "sha256:f0b4933e7270a8be2b588761e5b12b7334c11890ee91987c2fb057e72f566da6", size = 61052 } +sdist = { url = "https://files.pythonhosted.org/packages/0f/e1/cc58e0be242f0b410707e001ed22c689435964fcaab42108887426e44fff/aiosmtplib-4.0.2.tar.gz", hash = "sha256:f0b4933e7270a8be2b588761e5b12b7334c11890ee91987c2fb057e72f566da6", size = 61052, upload-time = "2025-08-25T02:39:07.249Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/f1/2f/db9414bbeacee48ab0c7421a0319b361b7c15b5c3feebcd38684f5d5f849/aiosmtplib-4.0.2-py3-none-any.whl", hash = "sha256:72491f96e6de035c28d29870186782eccb2f651db9c5f8a32c9db689327f5742", size = 27048 }, + { url = "https://files.pythonhosted.org/packages/f1/2f/db9414bbeacee48ab0c7421a0319b361b7c15b5c3feebcd38684f5d5f849/aiosmtplib-4.0.2-py3-none-any.whl", hash = "sha256:72491f96e6de035c28d29870186782eccb2f651db9c5f8a32c9db689327f5742", size = 27048, upload-time = "2025-08-25T02:39:06.089Z" }, ] [[package]] @@ -24,9 +24,9 @@ dependencies = [ { name = "sqlalchemy" }, { name = "typing-extensions" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/6e/b6/2a81d7724c0c124edc5ec7a167e85858b6fd31b9611c6fb8ecf617b7e2d3/alembic-1.17.1.tar.gz", hash = "sha256:8a289f6778262df31571d29cca4c7fbacd2f0f582ea0816f4c399b6da7528486", size = 1981285 } +sdist = { url = "https://files.pythonhosted.org/packages/6e/b6/2a81d7724c0c124edc5ec7a167e85858b6fd31b9611c6fb8ecf617b7e2d3/alembic-1.17.1.tar.gz", hash = "sha256:8a289f6778262df31571d29cca4c7fbacd2f0f582ea0816f4c399b6da7528486", size = 1981285, upload-time = "2025-10-29T00:23:16.667Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/a5/32/7df1d81ec2e50fb661944a35183d87e62d3f6c6d9f8aff64a4f245226d55/alembic-1.17.1-py3-none-any.whl", hash = "sha256:cbc2386e60f89608bb63f30d2d6cc66c7aaed1fe105bd862828600e5ad167023", size = 247848 }, + { url = "https://files.pythonhosted.org/packages/a5/32/7df1d81ec2e50fb661944a35183d87e62d3f6c6d9f8aff64a4f245226d55/alembic-1.17.1-py3-none-any.whl", hash = "sha256:cbc2386e60f89608bb63f30d2d6cc66c7aaed1fe105bd862828600e5ad167023", size = 247848, upload-time = "2025-10-29T00:23:18.79Z" }, ] [[package]] @@ -37,9 +37,9 @@ dependencies = [ { name = "alembic" }, { name = "click" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/d2/bb/6e5eb52a6695690f91b7f67027f7a498ecb0e307f4f2e7d0ae0f854059f5/alembic-autogen-check-1.1.1.tar.gz", hash = "sha256:cdda293a71b2413e854b07641c6f8291dffca0c5c6d0531b7b457629a30ca9cf", size = 2660 } +sdist = { url = "https://files.pythonhosted.org/packages/d2/bb/6e5eb52a6695690f91b7f67027f7a498ecb0e307f4f2e7d0ae0f854059f5/alembic-autogen-check-1.1.1.tar.gz", hash = "sha256:cdda293a71b2413e854b07641c6f8291dffca0c5c6d0531b7b457629a30ca9cf", size = 2660, upload-time = "2019-05-10T21:45:02.015Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/24/10/57410287f55b37aff354aa078d66f4a759b753ecb7d5aa1225174e1fd6ee/alembic_autogen_check-1.1.1-py3-none-any.whl", hash = "sha256:331c90b99cc2d1c40e69205dfd5e44b5d9c8f111e4b96244f79b303398740659", size = 3968 }, + { url = "https://files.pythonhosted.org/packages/24/10/57410287f55b37aff354aa078d66f4a759b753ecb7d5aa1225174e1fd6ee/alembic_autogen_check-1.1.1-py3-none-any.whl", hash = "sha256:331c90b99cc2d1c40e69205dfd5e44b5d9c8f111e4b96244f79b303398740659", size = 3968, upload-time = "2019-05-10T21:45:01.039Z" }, ] [[package]] @@ -50,27 +50,27 @@ dependencies = [ { name = "alembic" }, { name = "sqlalchemy" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/58/04/e465cb5c051fb056b7fadda7667b3e1fb4d32d7f19533e3bbff071c73788/alembic_postgresql_enum-1.8.0.tar.gz", hash = "sha256:132cd5fdc4a2a0b6498f3d89ea1c7b2a5ddc3281ddd84edae7259ec4c0a215a0", size = 15858 } +sdist = { url = "https://files.pythonhosted.org/packages/58/04/e465cb5c051fb056b7fadda7667b3e1fb4d32d7f19533e3bbff071c73788/alembic_postgresql_enum-1.8.0.tar.gz", hash = "sha256:132cd5fdc4a2a0b6498f3d89ea1c7b2a5ddc3281ddd84edae7259ec4c0a215a0", size = 15858, upload-time = "2025-07-20T12:25:50.626Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/77/80/4e6e841f9a0403b520b8f28650c2cdf5905e25bd4ff403b43daec580fed3/alembic_postgresql_enum-1.8.0-py3-none-any.whl", hash = "sha256:0e62833f8d1aca2c58fa09cae1d4a52472fb32d2dde32b68c84515fffcf401d5", size = 23697 }, + { url = "https://files.pythonhosted.org/packages/77/80/4e6e841f9a0403b520b8f28650c2cdf5905e25bd4ff403b43daec580fed3/alembic_postgresql_enum-1.8.0-py3-none-any.whl", hash = "sha256:0e62833f8d1aca2c58fa09cae1d4a52472fb32d2dde32b68c84515fffcf401d5", size = 23697, upload-time = "2025-07-20T12:25:49.048Z" }, ] [[package]] name = "annotated-doc" version = "0.0.3" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/d7/a6/dc46877b911e40c00d395771ea710d5e77b6de7bacd5fdcd78d70cc5a48f/annotated_doc-0.0.3.tar.gz", hash = "sha256:e18370014c70187422c33e945053ff4c286f453a984eba84d0dbfa0c935adeda", size = 5535 } +sdist = { url = "https://files.pythonhosted.org/packages/d7/a6/dc46877b911e40c00d395771ea710d5e77b6de7bacd5fdcd78d70cc5a48f/annotated_doc-0.0.3.tar.gz", hash = "sha256:e18370014c70187422c33e945053ff4c286f453a984eba84d0dbfa0c935adeda", size = 5535, upload-time = "2025-10-24T14:57:10.718Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/02/b7/cf592cb5de5cb3bade3357f8d2cf42bf103bbe39f459824b4939fd212911/annotated_doc-0.0.3-py3-none-any.whl", hash = "sha256:348ec6664a76f1fd3be81f43dffbee4c7e8ce931ba71ec67cc7f4ade7fbbb580", size = 5488 }, + { url = "https://files.pythonhosted.org/packages/02/b7/cf592cb5de5cb3bade3357f8d2cf42bf103bbe39f459824b4939fd212911/annotated_doc-0.0.3-py3-none-any.whl", hash = "sha256:348ec6664a76f1fd3be81f43dffbee4c7e8ce931ba71ec67cc7f4ade7fbbb580", size = 5488, upload-time = "2025-10-24T14:57:09.462Z" }, ] [[package]] name = "annotated-types" version = "0.7.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/ee/67/531ea369ba64dcff5ec9c3402f9f51bf748cec26dde048a2f973a4eea7f5/annotated_types-0.7.0.tar.gz", hash = "sha256:aff07c09a53a08bc8cfccb9c85b05f1aa9a2a6f23728d790723543408344ce89", size = 16081 } +sdist = { url = "https://files.pythonhosted.org/packages/ee/67/531ea369ba64dcff5ec9c3402f9f51bf748cec26dde048a2f973a4eea7f5/annotated_types-0.7.0.tar.gz", hash = "sha256:aff07c09a53a08bc8cfccb9c85b05f1aa9a2a6f23728d790723543408344ce89", size = 16081, upload-time = "2024-05-20T21:33:25.928Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/78/b6/6307fbef88d9b5ee7421e68d78a9f162e0da4900bc5f5793f6d3d0e34fb8/annotated_types-0.7.0-py3-none-any.whl", hash = "sha256:1f02e8b43a8fbbc3f3e0d4f0f4bfc8131bcb4eebe8849b8e5c773f3a1c582a53", size = 13643 }, + { url = "https://files.pythonhosted.org/packages/78/b6/6307fbef88d9b5ee7421e68d78a9f162e0da4900bc5f5793f6d3d0e34fb8/annotated_types-0.7.0-py3-none-any.whl", hash = "sha256:1f02e8b43a8fbbc3f3e0d4f0f4bfc8131bcb4eebe8849b8e5c773f3a1c582a53", size = 13643, upload-time = "2024-05-20T21:33:24.1Z" }, ] [[package]] @@ -81,9 +81,9 @@ dependencies = [ { name = "idna" }, { name = "sniffio" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/c6/78/7d432127c41b50bccba979505f272c16cbcadcc33645d5fa3a738110ae75/anyio-4.11.0.tar.gz", hash = "sha256:82a8d0b81e318cc5ce71a5f1f8b5c4e63619620b63141ef8c995fa0db95a57c4", size = 219094 } +sdist = { url = "https://files.pythonhosted.org/packages/c6/78/7d432127c41b50bccba979505f272c16cbcadcc33645d5fa3a738110ae75/anyio-4.11.0.tar.gz", hash = "sha256:82a8d0b81e318cc5ce71a5f1f8b5c4e63619620b63141ef8c995fa0db95a57c4", size = 219094, upload-time = "2025-09-23T09:19:12.58Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/15/b3/9b1a8074496371342ec1e796a96f99c82c945a339cd81a8e73de28b4cf9e/anyio-4.11.0-py3-none-any.whl", hash = "sha256:0287e96f4d26d4149305414d4e3bc32f0dcd0862365a4bddea19d7a1ec38c4fc", size = 109097 }, + { url = "https://files.pythonhosted.org/packages/15/b3/9b1a8074496371342ec1e796a96f99c82c945a339cd81a8e73de28b4cf9e/anyio-4.11.0-py3-none-any.whl", hash = "sha256:0287e96f4d26d4149305414d4e3bc32f0dcd0862365a4bddea19d7a1ec38c4fc", size = 109097, upload-time = "2025-09-23T09:19:10.601Z" }, ] [[package]] @@ -93,9 +93,9 @@ source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "argon2-cffi-bindings" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/31/fa/57ec2c6d16ecd2ba0cf15f3c7d1c3c2e7b5fcb83555ff56d7ab10888ec8f/argon2_cffi-23.1.0.tar.gz", hash = "sha256:879c3e79a2729ce768ebb7d36d4609e3a78a4ca2ec3a9f12286ca057e3d0db08", size = 42798 } +sdist = { url = "https://files.pythonhosted.org/packages/31/fa/57ec2c6d16ecd2ba0cf15f3c7d1c3c2e7b5fcb83555ff56d7ab10888ec8f/argon2_cffi-23.1.0.tar.gz", hash = "sha256:879c3e79a2729ce768ebb7d36d4609e3a78a4ca2ec3a9f12286ca057e3d0db08", size = 42798, upload-time = "2023-08-15T14:13:12.711Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/a4/6a/e8a041599e78b6b3752da48000b14c8d1e8a04ded09c88c714ba047f34f5/argon2_cffi-23.1.0-py3-none-any.whl", hash = "sha256:c670642b78ba29641818ab2e68bd4e6a78ba53b7eff7b4c3815ae16abf91c7ea", size = 15124 }, + { url = "https://files.pythonhosted.org/packages/a4/6a/e8a041599e78b6b3752da48000b14c8d1e8a04ded09c88c714ba047f34f5/argon2_cffi-23.1.0-py3-none-any.whl", hash = "sha256:c670642b78ba29641818ab2e68bd4e6a78ba53b7eff7b4c3815ae16abf91c7ea", size = 15124, upload-time = "2023-08-15T14:13:10.752Z" }, ] [[package]] @@ -105,28 +105,28 @@ source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "cffi" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/5c/2d/db8af0df73c1cf454f71b2bbe5e356b8c1f8041c979f505b3d3186e520a9/argon2_cffi_bindings-25.1.0.tar.gz", hash = "sha256:b957f3e6ea4d55d820e40ff76f450952807013d361a65d7f28acc0acbf29229d", size = 1783441 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/60/97/3c0a35f46e52108d4707c44b95cfe2afcafc50800b5450c197454569b776/argon2_cffi_bindings-25.1.0-cp314-cp314t-macosx_10_13_universal2.whl", hash = "sha256:3d3f05610594151994ca9ccb3c771115bdb4daef161976a266f0dd8aa9996b8f", size = 54393 }, - { url = "https://files.pythonhosted.org/packages/9d/f4/98bbd6ee89febd4f212696f13c03ca302b8552e7dbf9c8efa11ea4a388c3/argon2_cffi_bindings-25.1.0-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:8b8efee945193e667a396cbc7b4fb7d357297d6234d30a489905d96caabde56b", size = 29328 }, - { url = "https://files.pythonhosted.org/packages/43/24/90a01c0ef12ac91a6be05969f29944643bc1e5e461155ae6559befa8f00b/argon2_cffi_bindings-25.1.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:3c6702abc36bf3ccba3f802b799505def420a1b7039862014a65db3205967f5a", size = 31269 }, - { url = "https://files.pythonhosted.org/packages/d4/d3/942aa10782b2697eee7af5e12eeff5ebb325ccfb86dd8abda54174e377e4/argon2_cffi_bindings-25.1.0-cp314-cp314t-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:a1c70058c6ab1e352304ac7e3b52554daadacd8d453c1752e547c76e9c99ac44", size = 86558 }, - { url = "https://files.pythonhosted.org/packages/0d/82/b484f702fec5536e71836fc2dbc8c5267b3f6e78d2d539b4eaa6f0db8bf8/argon2_cffi_bindings-25.1.0-cp314-cp314t-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:e2fd3bfbff3c5d74fef31a722f729bf93500910db650c925c2d6ef879a7e51cb", size = 92364 }, - { url = "https://files.pythonhosted.org/packages/c9/c1/a606ff83b3f1735f3759ad0f2cd9e038a0ad11a3de3b6c673aa41c24bb7b/argon2_cffi_bindings-25.1.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:c4f9665de60b1b0e99bcd6be4f17d90339698ce954cfd8d9cf4f91c995165a92", size = 85637 }, - { url = "https://files.pythonhosted.org/packages/44/b4/678503f12aceb0262f84fa201f6027ed77d71c5019ae03b399b97caa2f19/argon2_cffi_bindings-25.1.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:ba92837e4a9aa6a508c8d2d7883ed5a8f6c308c89a4790e1e447a220deb79a85", size = 91934 }, - { url = "https://files.pythonhosted.org/packages/f0/c7/f36bd08ef9bd9f0a9cff9428406651f5937ce27b6c5b07b92d41f91ae541/argon2_cffi_bindings-25.1.0-cp314-cp314t-win32.whl", hash = "sha256:84a461d4d84ae1295871329b346a97f68eade8c53b6ed9a7ca2d7467f3c8ff6f", size = 28158 }, - { url = "https://files.pythonhosted.org/packages/b3/80/0106a7448abb24a2c467bf7d527fe5413b7fdfa4ad6d6a96a43a62ef3988/argon2_cffi_bindings-25.1.0-cp314-cp314t-win_amd64.whl", hash = "sha256:b55aec3565b65f56455eebc9b9f34130440404f27fe21c3b375bf1ea4d8fbae6", size = 32597 }, - { url = "https://files.pythonhosted.org/packages/05/b8/d663c9caea07e9180b2cb662772865230715cbd573ba3b5e81793d580316/argon2_cffi_bindings-25.1.0-cp314-cp314t-win_arm64.whl", hash = "sha256:87c33a52407e4c41f3b70a9c2d3f6056d88b10dad7695be708c5021673f55623", size = 28231 }, - { url = "https://files.pythonhosted.org/packages/1d/57/96b8b9f93166147826da5f90376e784a10582dd39a393c99bb62cfcf52f0/argon2_cffi_bindings-25.1.0-cp39-abi3-macosx_10_9_universal2.whl", hash = "sha256:aecba1723ae35330a008418a91ea6cfcedf6d31e5fbaa056a166462ff066d500", size = 54121 }, - { url = "https://files.pythonhosted.org/packages/0a/08/a9bebdb2e0e602dde230bdde8021b29f71f7841bd54801bcfd514acb5dcf/argon2_cffi_bindings-25.1.0-cp39-abi3-macosx_10_9_x86_64.whl", hash = "sha256:2630b6240b495dfab90aebe159ff784d08ea999aa4b0d17efa734055a07d2f44", size = 29177 }, - { url = "https://files.pythonhosted.org/packages/b6/02/d297943bcacf05e4f2a94ab6f462831dc20158614e5d067c35d4e63b9acb/argon2_cffi_bindings-25.1.0-cp39-abi3-macosx_11_0_arm64.whl", hash = "sha256:7aef0c91e2c0fbca6fc68e7555aa60ef7008a739cbe045541e438373bc54d2b0", size = 31090 }, - { url = "https://files.pythonhosted.org/packages/c1/93/44365f3d75053e53893ec6d733e4a5e3147502663554b4d864587c7828a7/argon2_cffi_bindings-25.1.0-cp39-abi3-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:1e021e87faa76ae0d413b619fe2b65ab9a037f24c60a1e6cc43457ae20de6dc6", size = 81246 }, - { url = "https://files.pythonhosted.org/packages/09/52/94108adfdd6e2ddf58be64f959a0b9c7d4ef2fa71086c38356d22dc501ea/argon2_cffi_bindings-25.1.0-cp39-abi3-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:d3e924cfc503018a714f94a49a149fdc0b644eaead5d1f089330399134fa028a", size = 87126 }, - { url = "https://files.pythonhosted.org/packages/72/70/7a2993a12b0ffa2a9271259b79cc616e2389ed1a4d93842fac5a1f923ffd/argon2_cffi_bindings-25.1.0-cp39-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:c87b72589133f0346a1cb8d5ecca4b933e3c9b64656c9d175270a000e73b288d", size = 80343 }, - { url = "https://files.pythonhosted.org/packages/78/9a/4e5157d893ffc712b74dbd868c7f62365618266982b64accab26bab01edc/argon2_cffi_bindings-25.1.0-cp39-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:1db89609c06afa1a214a69a462ea741cf735b29a57530478c06eb81dd403de99", size = 86777 }, - { url = "https://files.pythonhosted.org/packages/74/cd/15777dfde1c29d96de7f18edf4cc94c385646852e7c7b0320aa91ccca583/argon2_cffi_bindings-25.1.0-cp39-abi3-win32.whl", hash = "sha256:473bcb5f82924b1becbb637b63303ec8d10e84c8d241119419897a26116515d2", size = 27180 }, - { url = "https://files.pythonhosted.org/packages/e2/c6/a759ece8f1829d1f162261226fbfd2c6832b3ff7657384045286d2afa384/argon2_cffi_bindings-25.1.0-cp39-abi3-win_amd64.whl", hash = "sha256:a98cd7d17e9f7ce244c0803cad3c23a7d379c301ba618a5fa76a67d116618b98", size = 31715 }, - { url = "https://files.pythonhosted.org/packages/42/b9/f8d6fa329ab25128b7e98fd83a3cb34d9db5b059a9847eddb840a0af45dd/argon2_cffi_bindings-25.1.0-cp39-abi3-win_arm64.whl", hash = "sha256:b0fdbcf513833809c882823f98dc2f931cf659d9a1429616ac3adebb49f5db94", size = 27149 }, +sdist = { url = "https://files.pythonhosted.org/packages/5c/2d/db8af0df73c1cf454f71b2bbe5e356b8c1f8041c979f505b3d3186e520a9/argon2_cffi_bindings-25.1.0.tar.gz", hash = "sha256:b957f3e6ea4d55d820e40ff76f450952807013d361a65d7f28acc0acbf29229d", size = 1783441, upload-time = "2025-07-30T10:02:05.147Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/60/97/3c0a35f46e52108d4707c44b95cfe2afcafc50800b5450c197454569b776/argon2_cffi_bindings-25.1.0-cp314-cp314t-macosx_10_13_universal2.whl", hash = "sha256:3d3f05610594151994ca9ccb3c771115bdb4daef161976a266f0dd8aa9996b8f", size = 54393, upload-time = "2025-07-30T10:01:40.97Z" }, + { url = "https://files.pythonhosted.org/packages/9d/f4/98bbd6ee89febd4f212696f13c03ca302b8552e7dbf9c8efa11ea4a388c3/argon2_cffi_bindings-25.1.0-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:8b8efee945193e667a396cbc7b4fb7d357297d6234d30a489905d96caabde56b", size = 29328, upload-time = "2025-07-30T10:01:41.916Z" }, + { url = "https://files.pythonhosted.org/packages/43/24/90a01c0ef12ac91a6be05969f29944643bc1e5e461155ae6559befa8f00b/argon2_cffi_bindings-25.1.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:3c6702abc36bf3ccba3f802b799505def420a1b7039862014a65db3205967f5a", size = 31269, upload-time = "2025-07-30T10:01:42.716Z" }, + { url = "https://files.pythonhosted.org/packages/d4/d3/942aa10782b2697eee7af5e12eeff5ebb325ccfb86dd8abda54174e377e4/argon2_cffi_bindings-25.1.0-cp314-cp314t-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:a1c70058c6ab1e352304ac7e3b52554daadacd8d453c1752e547c76e9c99ac44", size = 86558, upload-time = "2025-07-30T10:01:43.943Z" }, + { url = "https://files.pythonhosted.org/packages/0d/82/b484f702fec5536e71836fc2dbc8c5267b3f6e78d2d539b4eaa6f0db8bf8/argon2_cffi_bindings-25.1.0-cp314-cp314t-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:e2fd3bfbff3c5d74fef31a722f729bf93500910db650c925c2d6ef879a7e51cb", size = 92364, upload-time = "2025-07-30T10:01:44.887Z" }, + { url = "https://files.pythonhosted.org/packages/c9/c1/a606ff83b3f1735f3759ad0f2cd9e038a0ad11a3de3b6c673aa41c24bb7b/argon2_cffi_bindings-25.1.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:c4f9665de60b1b0e99bcd6be4f17d90339698ce954cfd8d9cf4f91c995165a92", size = 85637, upload-time = "2025-07-30T10:01:46.225Z" }, + { url = "https://files.pythonhosted.org/packages/44/b4/678503f12aceb0262f84fa201f6027ed77d71c5019ae03b399b97caa2f19/argon2_cffi_bindings-25.1.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:ba92837e4a9aa6a508c8d2d7883ed5a8f6c308c89a4790e1e447a220deb79a85", size = 91934, upload-time = "2025-07-30T10:01:47.203Z" }, + { url = "https://files.pythonhosted.org/packages/f0/c7/f36bd08ef9bd9f0a9cff9428406651f5937ce27b6c5b07b92d41f91ae541/argon2_cffi_bindings-25.1.0-cp314-cp314t-win32.whl", hash = "sha256:84a461d4d84ae1295871329b346a97f68eade8c53b6ed9a7ca2d7467f3c8ff6f", size = 28158, upload-time = "2025-07-30T10:01:48.341Z" }, + { url = "https://files.pythonhosted.org/packages/b3/80/0106a7448abb24a2c467bf7d527fe5413b7fdfa4ad6d6a96a43a62ef3988/argon2_cffi_bindings-25.1.0-cp314-cp314t-win_amd64.whl", hash = "sha256:b55aec3565b65f56455eebc9b9f34130440404f27fe21c3b375bf1ea4d8fbae6", size = 32597, upload-time = "2025-07-30T10:01:49.112Z" }, + { url = "https://files.pythonhosted.org/packages/05/b8/d663c9caea07e9180b2cb662772865230715cbd573ba3b5e81793d580316/argon2_cffi_bindings-25.1.0-cp314-cp314t-win_arm64.whl", hash = "sha256:87c33a52407e4c41f3b70a9c2d3f6056d88b10dad7695be708c5021673f55623", size = 28231, upload-time = "2025-07-30T10:01:49.92Z" }, + { url = "https://files.pythonhosted.org/packages/1d/57/96b8b9f93166147826da5f90376e784a10582dd39a393c99bb62cfcf52f0/argon2_cffi_bindings-25.1.0-cp39-abi3-macosx_10_9_universal2.whl", hash = "sha256:aecba1723ae35330a008418a91ea6cfcedf6d31e5fbaa056a166462ff066d500", size = 54121, upload-time = "2025-07-30T10:01:50.815Z" }, + { url = "https://files.pythonhosted.org/packages/0a/08/a9bebdb2e0e602dde230bdde8021b29f71f7841bd54801bcfd514acb5dcf/argon2_cffi_bindings-25.1.0-cp39-abi3-macosx_10_9_x86_64.whl", hash = "sha256:2630b6240b495dfab90aebe159ff784d08ea999aa4b0d17efa734055a07d2f44", size = 29177, upload-time = "2025-07-30T10:01:51.681Z" }, + { url = "https://files.pythonhosted.org/packages/b6/02/d297943bcacf05e4f2a94ab6f462831dc20158614e5d067c35d4e63b9acb/argon2_cffi_bindings-25.1.0-cp39-abi3-macosx_11_0_arm64.whl", hash = "sha256:7aef0c91e2c0fbca6fc68e7555aa60ef7008a739cbe045541e438373bc54d2b0", size = 31090, upload-time = "2025-07-30T10:01:53.184Z" }, + { url = "https://files.pythonhosted.org/packages/c1/93/44365f3d75053e53893ec6d733e4a5e3147502663554b4d864587c7828a7/argon2_cffi_bindings-25.1.0-cp39-abi3-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:1e021e87faa76ae0d413b619fe2b65ab9a037f24c60a1e6cc43457ae20de6dc6", size = 81246, upload-time = "2025-07-30T10:01:54.145Z" }, + { url = "https://files.pythonhosted.org/packages/09/52/94108adfdd6e2ddf58be64f959a0b9c7d4ef2fa71086c38356d22dc501ea/argon2_cffi_bindings-25.1.0-cp39-abi3-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:d3e924cfc503018a714f94a49a149fdc0b644eaead5d1f089330399134fa028a", size = 87126, upload-time = "2025-07-30T10:01:55.074Z" }, + { url = "https://files.pythonhosted.org/packages/72/70/7a2993a12b0ffa2a9271259b79cc616e2389ed1a4d93842fac5a1f923ffd/argon2_cffi_bindings-25.1.0-cp39-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:c87b72589133f0346a1cb8d5ecca4b933e3c9b64656c9d175270a000e73b288d", size = 80343, upload-time = "2025-07-30T10:01:56.007Z" }, + { url = "https://files.pythonhosted.org/packages/78/9a/4e5157d893ffc712b74dbd868c7f62365618266982b64accab26bab01edc/argon2_cffi_bindings-25.1.0-cp39-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:1db89609c06afa1a214a69a462ea741cf735b29a57530478c06eb81dd403de99", size = 86777, upload-time = "2025-07-30T10:01:56.943Z" }, + { url = "https://files.pythonhosted.org/packages/74/cd/15777dfde1c29d96de7f18edf4cc94c385646852e7c7b0320aa91ccca583/argon2_cffi_bindings-25.1.0-cp39-abi3-win32.whl", hash = "sha256:473bcb5f82924b1becbb637b63303ec8d10e84c8d241119419897a26116515d2", size = 27180, upload-time = "2025-07-30T10:01:57.759Z" }, + { url = "https://files.pythonhosted.org/packages/e2/c6/a759ece8f1829d1f162261226fbfd2c6832b3ff7657384045286d2afa384/argon2_cffi_bindings-25.1.0-cp39-abi3-win_amd64.whl", hash = "sha256:a98cd7d17e9f7ce244c0803cad3c23a7d379c301ba618a5fa76a67d116618b98", size = 31715, upload-time = "2025-07-30T10:01:58.56Z" }, + { url = "https://files.pythonhosted.org/packages/42/b9/f8d6fa329ab25128b7e98fd83a3cb34d9db5b059a9847eddb840a0af45dd/argon2_cffi_bindings-25.1.0-cp39-abi3-win_arm64.whl", hash = "sha256:b0fdbcf513833809c882823f98dc2f931cf659d9a1429616ac3adebb49f5db94", size = 27149, upload-time = "2025-07-30T10:01:59.329Z" }, ] [[package]] @@ -136,75 +136,75 @@ source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "cachetools" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/49/cf/17f8a6b6b97f77b5981fbce1266913e718daaa3467b46f60a785cbaadc29/asyncache-0.3.1.tar.gz", hash = "sha256:9a1e60a75668e794657489bdea6540ee7e3259c483517b934670db7600bf5035", size = 3797 } +sdist = { url = "https://files.pythonhosted.org/packages/49/cf/17f8a6b6b97f77b5981fbce1266913e718daaa3467b46f60a785cbaadc29/asyncache-0.3.1.tar.gz", hash = "sha256:9a1e60a75668e794657489bdea6540ee7e3259c483517b934670db7600bf5035", size = 3797, upload-time = "2022-11-15T10:06:47.476Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/2f/94/51927deb4f40872361ec4f5534f68f7a9ce81c4ef20bf5cd765307f4c15d/asyncache-0.3.1-py3-none-any.whl", hash = "sha256:ef20a1024d265090dd1e0785c961cf98b9c32cc7d9478973dcf25ac1b80011f5", size = 3722 }, + { url = "https://files.pythonhosted.org/packages/2f/94/51927deb4f40872361ec4f5534f68f7a9ce81c4ef20bf5cd765307f4c15d/asyncache-0.3.1-py3-none-any.whl", hash = "sha256:ef20a1024d265090dd1e0785c961cf98b9c32cc7d9478973dcf25ac1b80011f5", size = 3722, upload-time = "2022-11-15T10:06:45.546Z" }, ] [[package]] name = "asyncpg" version = "0.30.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/2f/4c/7c991e080e106d854809030d8584e15b2e996e26f16aee6d757e387bc17d/asyncpg-0.30.0.tar.gz", hash = "sha256:c551e9928ab6707602f44811817f82ba3c446e018bfe1d3abecc8ba5f3eac851", size = 957746 } +sdist = { url = "https://files.pythonhosted.org/packages/2f/4c/7c991e080e106d854809030d8584e15b2e996e26f16aee6d757e387bc17d/asyncpg-0.30.0.tar.gz", hash = "sha256:c551e9928ab6707602f44811817f82ba3c446e018bfe1d3abecc8ba5f3eac851", size = 957746, upload-time = "2024-10-20T00:30:41.127Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/3a/22/e20602e1218dc07692acf70d5b902be820168d6282e69ef0d3cb920dc36f/asyncpg-0.30.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:05b185ebb8083c8568ea8a40e896d5f7af4b8554b64d7719c0eaa1eb5a5c3a70", size = 670373 }, - { url = "https://files.pythonhosted.org/packages/3d/b3/0cf269a9d647852a95c06eb00b815d0b95a4eb4b55aa2d6ba680971733b9/asyncpg-0.30.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:c47806b1a8cbb0a0db896f4cd34d89942effe353a5035c62734ab13b9f938da3", size = 634745 }, - { url = "https://files.pythonhosted.org/packages/8e/6d/a4f31bf358ce8491d2a31bfe0d7bcf25269e80481e49de4d8616c4295a34/asyncpg-0.30.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9b6fde867a74e8c76c71e2f64f80c64c0f3163e687f1763cfaf21633ec24ec33", size = 3512103 }, - { url = "https://files.pythonhosted.org/packages/96/19/139227a6e67f407b9c386cb594d9628c6c78c9024f26df87c912fabd4368/asyncpg-0.30.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:46973045b567972128a27d40001124fbc821c87a6cade040cfcd4fa8a30bcdc4", size = 3592471 }, - { url = "https://files.pythonhosted.org/packages/67/e4/ab3ca38f628f53f0fd28d3ff20edff1c975dd1cb22482e0061916b4b9a74/asyncpg-0.30.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:9110df111cabc2ed81aad2f35394a00cadf4f2e0635603db6ebbd0fc896f46a4", size = 3496253 }, - { url = "https://files.pythonhosted.org/packages/ef/5f/0bf65511d4eeac3a1f41c54034a492515a707c6edbc642174ae79034d3ba/asyncpg-0.30.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:04ff0785ae7eed6cc138e73fc67b8e51d54ee7a3ce9b63666ce55a0bf095f7ba", size = 3662720 }, - { url = "https://files.pythonhosted.org/packages/e7/31/1513d5a6412b98052c3ed9158d783b1e09d0910f51fbe0e05f56cc370bc4/asyncpg-0.30.0-cp313-cp313-win32.whl", hash = "sha256:ae374585f51c2b444510cdf3595b97ece4f233fde739aa14b50e0d64e8a7a590", size = 560404 }, - { url = "https://files.pythonhosted.org/packages/c8/a4/cec76b3389c4c5ff66301cd100fe88c318563ec8a520e0b2e792b5b84972/asyncpg-0.30.0-cp313-cp313-win_amd64.whl", hash = "sha256:f59b430b8e27557c3fb9869222559f7417ced18688375825f8f12302c34e915e", size = 621623 }, + { url = "https://files.pythonhosted.org/packages/3a/22/e20602e1218dc07692acf70d5b902be820168d6282e69ef0d3cb920dc36f/asyncpg-0.30.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:05b185ebb8083c8568ea8a40e896d5f7af4b8554b64d7719c0eaa1eb5a5c3a70", size = 670373, upload-time = "2024-10-20T00:29:55.165Z" }, + { url = "https://files.pythonhosted.org/packages/3d/b3/0cf269a9d647852a95c06eb00b815d0b95a4eb4b55aa2d6ba680971733b9/asyncpg-0.30.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:c47806b1a8cbb0a0db896f4cd34d89942effe353a5035c62734ab13b9f938da3", size = 634745, upload-time = "2024-10-20T00:29:57.14Z" }, + { url = "https://files.pythonhosted.org/packages/8e/6d/a4f31bf358ce8491d2a31bfe0d7bcf25269e80481e49de4d8616c4295a34/asyncpg-0.30.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9b6fde867a74e8c76c71e2f64f80c64c0f3163e687f1763cfaf21633ec24ec33", size = 3512103, upload-time = "2024-10-20T00:29:58.499Z" }, + { url = "https://files.pythonhosted.org/packages/96/19/139227a6e67f407b9c386cb594d9628c6c78c9024f26df87c912fabd4368/asyncpg-0.30.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:46973045b567972128a27d40001124fbc821c87a6cade040cfcd4fa8a30bcdc4", size = 3592471, upload-time = "2024-10-20T00:30:00.354Z" }, + { url = "https://files.pythonhosted.org/packages/67/e4/ab3ca38f628f53f0fd28d3ff20edff1c975dd1cb22482e0061916b4b9a74/asyncpg-0.30.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:9110df111cabc2ed81aad2f35394a00cadf4f2e0635603db6ebbd0fc896f46a4", size = 3496253, upload-time = "2024-10-20T00:30:02.794Z" }, + { url = "https://files.pythonhosted.org/packages/ef/5f/0bf65511d4eeac3a1f41c54034a492515a707c6edbc642174ae79034d3ba/asyncpg-0.30.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:04ff0785ae7eed6cc138e73fc67b8e51d54ee7a3ce9b63666ce55a0bf095f7ba", size = 3662720, upload-time = "2024-10-20T00:30:04.501Z" }, + { url = "https://files.pythonhosted.org/packages/e7/31/1513d5a6412b98052c3ed9158d783b1e09d0910f51fbe0e05f56cc370bc4/asyncpg-0.30.0-cp313-cp313-win32.whl", hash = "sha256:ae374585f51c2b444510cdf3595b97ece4f233fde739aa14b50e0d64e8a7a590", size = 560404, upload-time = "2024-10-20T00:30:06.537Z" }, + { url = "https://files.pythonhosted.org/packages/c8/a4/cec76b3389c4c5ff66301cd100fe88c318563ec8a520e0b2e792b5b84972/asyncpg-0.30.0-cp313-cp313-win_amd64.whl", hash = "sha256:f59b430b8e27557c3fb9869222559f7417ced18688375825f8f12302c34e915e", size = 621623, upload-time = "2024-10-20T00:30:09.024Z" }, ] [[package]] name = "bcrypt" version = "4.3.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/bb/5d/6d7433e0f3cd46ce0b43cd65e1db465ea024dbb8216fb2404e919c2ad77b/bcrypt-4.3.0.tar.gz", hash = "sha256:3a3fd2204178b6d2adcf09cb4f6426ffef54762577a7c9b54c159008cb288c18", size = 25697 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/bf/2c/3d44e853d1fe969d229bd58d39ae6902b3d924af0e2b5a60d17d4b809ded/bcrypt-4.3.0-cp313-cp313t-macosx_10_12_universal2.whl", hash = "sha256:f01e060f14b6b57bbb72fc5b4a83ac21c443c9a2ee708e04a10e9192f90a6281", size = 483719 }, - { url = "https://files.pythonhosted.org/packages/a1/e2/58ff6e2a22eca2e2cff5370ae56dba29d70b1ea6fc08ee9115c3ae367795/bcrypt-4.3.0-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c5eeac541cefd0bb887a371ef73c62c3cd78535e4887b310626036a7c0a817bb", size = 272001 }, - { url = "https://files.pythonhosted.org/packages/37/1f/c55ed8dbe994b1d088309e366749633c9eb90d139af3c0a50c102ba68a1a/bcrypt-4.3.0-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:59e1aa0e2cd871b08ca146ed08445038f42ff75968c7ae50d2fdd7860ade2180", size = 277451 }, - { url = "https://files.pythonhosted.org/packages/d7/1c/794feb2ecf22fe73dcfb697ea7057f632061faceb7dcf0f155f3443b4d79/bcrypt-4.3.0-cp313-cp313t-manylinux_2_28_aarch64.whl", hash = "sha256:0042b2e342e9ae3d2ed22727c1262f76cc4f345683b5c1715f0250cf4277294f", size = 272792 }, - { url = "https://files.pythonhosted.org/packages/13/b7/0b289506a3f3598c2ae2bdfa0ea66969812ed200264e3f61df77753eee6d/bcrypt-4.3.0-cp313-cp313t-manylinux_2_28_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:74a8d21a09f5e025a9a23e7c0fd2c7fe8e7503e4d356c0a2c1486ba010619f09", size = 289752 }, - { url = "https://files.pythonhosted.org/packages/dc/24/d0fb023788afe9e83cc118895a9f6c57e1044e7e1672f045e46733421fe6/bcrypt-4.3.0-cp313-cp313t-manylinux_2_28_x86_64.whl", hash = "sha256:0142b2cb84a009f8452c8c5a33ace5e3dfec4159e7735f5afe9a4d50a8ea722d", size = 277762 }, - { url = "https://files.pythonhosted.org/packages/e4/38/cde58089492e55ac4ef6c49fea7027600c84fd23f7520c62118c03b4625e/bcrypt-4.3.0-cp313-cp313t-manylinux_2_34_aarch64.whl", hash = "sha256:12fa6ce40cde3f0b899729dbd7d5e8811cb892d31b6f7d0334a1f37748b789fd", size = 272384 }, - { url = "https://files.pythonhosted.org/packages/de/6a/d5026520843490cfc8135d03012a413e4532a400e471e6188b01b2de853f/bcrypt-4.3.0-cp313-cp313t-manylinux_2_34_x86_64.whl", hash = "sha256:5bd3cca1f2aa5dbcf39e2aa13dd094ea181f48959e1071265de49cc2b82525af", size = 277329 }, - { url = "https://files.pythonhosted.org/packages/b3/a3/4fc5255e60486466c389e28c12579d2829b28a527360e9430b4041df4cf9/bcrypt-4.3.0-cp313-cp313t-musllinux_1_1_aarch64.whl", hash = "sha256:335a420cfd63fc5bc27308e929bee231c15c85cc4c496610ffb17923abf7f231", size = 305241 }, - { url = "https://files.pythonhosted.org/packages/c7/15/2b37bc07d6ce27cc94e5b10fd5058900eb8fb11642300e932c8c82e25c4a/bcrypt-4.3.0-cp313-cp313t-musllinux_1_1_x86_64.whl", hash = "sha256:0e30e5e67aed0187a1764911af023043b4542e70a7461ad20e837e94d23e1d6c", size = 309617 }, - { url = "https://files.pythonhosted.org/packages/5f/1f/99f65edb09e6c935232ba0430c8c13bb98cb3194b6d636e61d93fe60ac59/bcrypt-4.3.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:3b8d62290ebefd49ee0b3ce7500f5dbdcf13b81402c05f6dafab9a1e1b27212f", size = 335751 }, - { url = "https://files.pythonhosted.org/packages/00/1b/b324030c706711c99769988fcb694b3cb23f247ad39a7823a78e361bdbb8/bcrypt-4.3.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:2ef6630e0ec01376f59a006dc72918b1bf436c3b571b80fa1968d775fa02fe7d", size = 355965 }, - { url = "https://files.pythonhosted.org/packages/aa/dd/20372a0579dd915dfc3b1cd4943b3bca431866fcb1dfdfd7518c3caddea6/bcrypt-4.3.0-cp313-cp313t-win32.whl", hash = "sha256:7a4be4cbf241afee43f1c3969b9103a41b40bcb3a3f467ab19f891d9bc4642e4", size = 155316 }, - { url = "https://files.pythonhosted.org/packages/6d/52/45d969fcff6b5577c2bf17098dc36269b4c02197d551371c023130c0f890/bcrypt-4.3.0-cp313-cp313t-win_amd64.whl", hash = "sha256:5c1949bf259a388863ced887c7861da1df681cb2388645766c89fdfd9004c669", size = 147752 }, - { url = "https://files.pythonhosted.org/packages/11/22/5ada0b9af72b60cbc4c9a399fdde4af0feaa609d27eb0adc61607997a3fa/bcrypt-4.3.0-cp38-abi3-macosx_10_12_universal2.whl", hash = "sha256:f81b0ed2639568bf14749112298f9e4e2b28853dab50a8b357e31798686a036d", size = 498019 }, - { url = "https://files.pythonhosted.org/packages/b8/8c/252a1edc598dc1ce57905be173328eda073083826955ee3c97c7ff5ba584/bcrypt-4.3.0-cp38-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:864f8f19adbe13b7de11ba15d85d4a428c7e2f344bac110f667676a0ff84924b", size = 279174 }, - { url = "https://files.pythonhosted.org/packages/29/5b/4547d5c49b85f0337c13929f2ccbe08b7283069eea3550a457914fc078aa/bcrypt-4.3.0-cp38-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3e36506d001e93bffe59754397572f21bb5dc7c83f54454c990c74a468cd589e", size = 283870 }, - { url = "https://files.pythonhosted.org/packages/be/21/7dbaf3fa1745cb63f776bb046e481fbababd7d344c5324eab47f5ca92dd2/bcrypt-4.3.0-cp38-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:842d08d75d9fe9fb94b18b071090220697f9f184d4547179b60734846461ed59", size = 279601 }, - { url = "https://files.pythonhosted.org/packages/6d/64/e042fc8262e971347d9230d9abbe70d68b0a549acd8611c83cebd3eaec67/bcrypt-4.3.0-cp38-abi3-manylinux_2_28_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:7c03296b85cb87db865d91da79bf63d5609284fc0cab9472fdd8367bbd830753", size = 297660 }, - { url = "https://files.pythonhosted.org/packages/50/b8/6294eb84a3fef3b67c69b4470fcdd5326676806bf2519cda79331ab3c3a9/bcrypt-4.3.0-cp38-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:62f26585e8b219cdc909b6a0069efc5e4267e25d4a3770a364ac58024f62a761", size = 284083 }, - { url = "https://files.pythonhosted.org/packages/62/e6/baff635a4f2c42e8788fe1b1633911c38551ecca9a749d1052d296329da6/bcrypt-4.3.0-cp38-abi3-manylinux_2_34_aarch64.whl", hash = "sha256:beeefe437218a65322fbd0069eb437e7c98137e08f22c4660ac2dc795c31f8bb", size = 279237 }, - { url = "https://files.pythonhosted.org/packages/39/48/46f623f1b0c7dc2e5de0b8af5e6f5ac4cc26408ac33f3d424e5ad8da4a90/bcrypt-4.3.0-cp38-abi3-manylinux_2_34_x86_64.whl", hash = "sha256:97eea7408db3a5bcce4a55d13245ab3fa566e23b4c67cd227062bb49e26c585d", size = 283737 }, - { url = "https://files.pythonhosted.org/packages/49/8b/70671c3ce9c0fca4a6cc3cc6ccbaa7e948875a2e62cbd146e04a4011899c/bcrypt-4.3.0-cp38-abi3-musllinux_1_1_aarch64.whl", hash = "sha256:191354ebfe305e84f344c5964c7cd5f924a3bfc5d405c75ad07f232b6dffb49f", size = 312741 }, - { url = "https://files.pythonhosted.org/packages/27/fb/910d3a1caa2d249b6040a5caf9f9866c52114d51523ac2fb47578a27faee/bcrypt-4.3.0-cp38-abi3-musllinux_1_1_x86_64.whl", hash = "sha256:41261d64150858eeb5ff43c753c4b216991e0ae16614a308a15d909503617732", size = 316472 }, - { url = "https://files.pythonhosted.org/packages/dc/cf/7cf3a05b66ce466cfb575dbbda39718d45a609daa78500f57fa9f36fa3c0/bcrypt-4.3.0-cp38-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:33752b1ba962ee793fa2b6321404bf20011fe45b9afd2a842139de3011898fef", size = 343606 }, - { url = "https://files.pythonhosted.org/packages/e3/b8/e970ecc6d7e355c0d892b7f733480f4aa8509f99b33e71550242cf0b7e63/bcrypt-4.3.0-cp38-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:50e6e80a4bfd23a25f5c05b90167c19030cf9f87930f7cb2eacb99f45d1c3304", size = 362867 }, - { url = "https://files.pythonhosted.org/packages/a9/97/8d3118efd8354c555a3422d544163f40d9f236be5b96c714086463f11699/bcrypt-4.3.0-cp38-abi3-win32.whl", hash = "sha256:67a561c4d9fb9465ec866177e7aebcad08fe23aaf6fbd692a6fab69088abfc51", size = 160589 }, - { url = "https://files.pythonhosted.org/packages/29/07/416f0b99f7f3997c69815365babbc2e8754181a4b1899d921b3c7d5b6f12/bcrypt-4.3.0-cp38-abi3-win_amd64.whl", hash = "sha256:584027857bc2843772114717a7490a37f68da563b3620f78a849bcb54dc11e62", size = 152794 }, - { url = "https://files.pythonhosted.org/packages/6e/c1/3fa0e9e4e0bfd3fd77eb8b52ec198fd6e1fd7e9402052e43f23483f956dd/bcrypt-4.3.0-cp39-abi3-macosx_10_12_universal2.whl", hash = "sha256:0d3efb1157edebfd9128e4e46e2ac1a64e0c1fe46fb023158a407c7892b0f8c3", size = 498969 }, - { url = "https://files.pythonhosted.org/packages/ce/d4/755ce19b6743394787fbd7dff6bf271b27ee9b5912a97242e3caf125885b/bcrypt-4.3.0-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:08bacc884fd302b611226c01014eca277d48f0a05187666bca23aac0dad6fe24", size = 279158 }, - { url = "https://files.pythonhosted.org/packages/9b/5d/805ef1a749c965c46b28285dfb5cd272a7ed9fa971f970435a5133250182/bcrypt-4.3.0-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f6746e6fec103fcd509b96bacdfdaa2fbde9a553245dbada284435173a6f1aef", size = 284285 }, - { url = "https://files.pythonhosted.org/packages/ab/2b/698580547a4a4988e415721b71eb45e80c879f0fb04a62da131f45987b96/bcrypt-4.3.0-cp39-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:afe327968aaf13fc143a56a3360cb27d4ad0345e34da12c7290f1b00b8fe9a8b", size = 279583 }, - { url = "https://files.pythonhosted.org/packages/f2/87/62e1e426418204db520f955ffd06f1efd389feca893dad7095bf35612eec/bcrypt-4.3.0-cp39-abi3-manylinux_2_28_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:d9af79d322e735b1fc33404b5765108ae0ff232d4b54666d46730f8ac1a43676", size = 297896 }, - { url = "https://files.pythonhosted.org/packages/cb/c6/8fedca4c2ada1b6e889c52d2943b2f968d3427e5d65f595620ec4c06fa2f/bcrypt-4.3.0-cp39-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:f1e3ffa1365e8702dc48c8b360fef8d7afeca482809c5e45e653af82ccd088c1", size = 284492 }, - { url = "https://files.pythonhosted.org/packages/4d/4d/c43332dcaaddb7710a8ff5269fcccba97ed3c85987ddaa808db084267b9a/bcrypt-4.3.0-cp39-abi3-manylinux_2_34_aarch64.whl", hash = "sha256:3004df1b323d10021fda07a813fd33e0fd57bef0e9a480bb143877f6cba996fe", size = 279213 }, - { url = "https://files.pythonhosted.org/packages/dc/7f/1e36379e169a7df3a14a1c160a49b7b918600a6008de43ff20d479e6f4b5/bcrypt-4.3.0-cp39-abi3-manylinux_2_34_x86_64.whl", hash = "sha256:531457e5c839d8caea9b589a1bcfe3756b0547d7814e9ce3d437f17da75c32b0", size = 284162 }, - { url = "https://files.pythonhosted.org/packages/1c/0a/644b2731194b0d7646f3210dc4d80c7fee3ecb3a1f791a6e0ae6bb8684e3/bcrypt-4.3.0-cp39-abi3-musllinux_1_1_aarch64.whl", hash = "sha256:17a854d9a7a476a89dcef6c8bd119ad23e0f82557afbd2c442777a16408e614f", size = 312856 }, - { url = "https://files.pythonhosted.org/packages/dc/62/2a871837c0bb6ab0c9a88bf54de0fc021a6a08832d4ea313ed92a669d437/bcrypt-4.3.0-cp39-abi3-musllinux_1_1_x86_64.whl", hash = "sha256:6fb1fd3ab08c0cbc6826a2e0447610c6f09e983a281b919ed721ad32236b8b23", size = 316726 }, - { url = "https://files.pythonhosted.org/packages/0c/a1/9898ea3faac0b156d457fd73a3cb9c2855c6fd063e44b8522925cdd8ce46/bcrypt-4.3.0-cp39-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:e965a9c1e9a393b8005031ff52583cedc15b7884fce7deb8b0346388837d6cfe", size = 343664 }, - { url = "https://files.pythonhosted.org/packages/40/f2/71b4ed65ce38982ecdda0ff20c3ad1b15e71949c78b2c053df53629ce940/bcrypt-4.3.0-cp39-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:79e70b8342a33b52b55d93b3a59223a844962bef479f6a0ea318ebbcadf71505", size = 363128 }, - { url = "https://files.pythonhosted.org/packages/11/99/12f6a58eca6dea4be992d6c681b7ec9410a1d9f5cf368c61437e31daa879/bcrypt-4.3.0-cp39-abi3-win32.whl", hash = "sha256:b4d4e57f0a63fd0b358eb765063ff661328f69a04494427265950c71b992a39a", size = 160598 }, - { url = "https://files.pythonhosted.org/packages/a9/cf/45fb5261ece3e6b9817d3d82b2f343a505fd58674a92577923bc500bd1aa/bcrypt-4.3.0-cp39-abi3-win_amd64.whl", hash = "sha256:e53e074b120f2877a35cc6c736b8eb161377caae8925c17688bd46ba56daaa5b", size = 152799 }, +sdist = { url = "https://files.pythonhosted.org/packages/bb/5d/6d7433e0f3cd46ce0b43cd65e1db465ea024dbb8216fb2404e919c2ad77b/bcrypt-4.3.0.tar.gz", hash = "sha256:3a3fd2204178b6d2adcf09cb4f6426ffef54762577a7c9b54c159008cb288c18", size = 25697, upload-time = "2025-02-28T01:24:09.174Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/bf/2c/3d44e853d1fe969d229bd58d39ae6902b3d924af0e2b5a60d17d4b809ded/bcrypt-4.3.0-cp313-cp313t-macosx_10_12_universal2.whl", hash = "sha256:f01e060f14b6b57bbb72fc5b4a83ac21c443c9a2ee708e04a10e9192f90a6281", size = 483719, upload-time = "2025-02-28T01:22:34.539Z" }, + { url = "https://files.pythonhosted.org/packages/a1/e2/58ff6e2a22eca2e2cff5370ae56dba29d70b1ea6fc08ee9115c3ae367795/bcrypt-4.3.0-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c5eeac541cefd0bb887a371ef73c62c3cd78535e4887b310626036a7c0a817bb", size = 272001, upload-time = "2025-02-28T01:22:38.078Z" }, + { url = "https://files.pythonhosted.org/packages/37/1f/c55ed8dbe994b1d088309e366749633c9eb90d139af3c0a50c102ba68a1a/bcrypt-4.3.0-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:59e1aa0e2cd871b08ca146ed08445038f42ff75968c7ae50d2fdd7860ade2180", size = 277451, upload-time = "2025-02-28T01:22:40.787Z" }, + { url = "https://files.pythonhosted.org/packages/d7/1c/794feb2ecf22fe73dcfb697ea7057f632061faceb7dcf0f155f3443b4d79/bcrypt-4.3.0-cp313-cp313t-manylinux_2_28_aarch64.whl", hash = "sha256:0042b2e342e9ae3d2ed22727c1262f76cc4f345683b5c1715f0250cf4277294f", size = 272792, upload-time = "2025-02-28T01:22:43.144Z" }, + { url = "https://files.pythonhosted.org/packages/13/b7/0b289506a3f3598c2ae2bdfa0ea66969812ed200264e3f61df77753eee6d/bcrypt-4.3.0-cp313-cp313t-manylinux_2_28_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:74a8d21a09f5e025a9a23e7c0fd2c7fe8e7503e4d356c0a2c1486ba010619f09", size = 289752, upload-time = "2025-02-28T01:22:45.56Z" }, + { url = "https://files.pythonhosted.org/packages/dc/24/d0fb023788afe9e83cc118895a9f6c57e1044e7e1672f045e46733421fe6/bcrypt-4.3.0-cp313-cp313t-manylinux_2_28_x86_64.whl", hash = "sha256:0142b2cb84a009f8452c8c5a33ace5e3dfec4159e7735f5afe9a4d50a8ea722d", size = 277762, upload-time = "2025-02-28T01:22:47.023Z" }, + { url = "https://files.pythonhosted.org/packages/e4/38/cde58089492e55ac4ef6c49fea7027600c84fd23f7520c62118c03b4625e/bcrypt-4.3.0-cp313-cp313t-manylinux_2_34_aarch64.whl", hash = "sha256:12fa6ce40cde3f0b899729dbd7d5e8811cb892d31b6f7d0334a1f37748b789fd", size = 272384, upload-time = "2025-02-28T01:22:49.221Z" }, + { url = "https://files.pythonhosted.org/packages/de/6a/d5026520843490cfc8135d03012a413e4532a400e471e6188b01b2de853f/bcrypt-4.3.0-cp313-cp313t-manylinux_2_34_x86_64.whl", hash = "sha256:5bd3cca1f2aa5dbcf39e2aa13dd094ea181f48959e1071265de49cc2b82525af", size = 277329, upload-time = "2025-02-28T01:22:51.603Z" }, + { url = "https://files.pythonhosted.org/packages/b3/a3/4fc5255e60486466c389e28c12579d2829b28a527360e9430b4041df4cf9/bcrypt-4.3.0-cp313-cp313t-musllinux_1_1_aarch64.whl", hash = "sha256:335a420cfd63fc5bc27308e929bee231c15c85cc4c496610ffb17923abf7f231", size = 305241, upload-time = "2025-02-28T01:22:53.283Z" }, + { url = "https://files.pythonhosted.org/packages/c7/15/2b37bc07d6ce27cc94e5b10fd5058900eb8fb11642300e932c8c82e25c4a/bcrypt-4.3.0-cp313-cp313t-musllinux_1_1_x86_64.whl", hash = "sha256:0e30e5e67aed0187a1764911af023043b4542e70a7461ad20e837e94d23e1d6c", size = 309617, upload-time = "2025-02-28T01:22:55.461Z" }, + { url = "https://files.pythonhosted.org/packages/5f/1f/99f65edb09e6c935232ba0430c8c13bb98cb3194b6d636e61d93fe60ac59/bcrypt-4.3.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:3b8d62290ebefd49ee0b3ce7500f5dbdcf13b81402c05f6dafab9a1e1b27212f", size = 335751, upload-time = "2025-02-28T01:22:57.81Z" }, + { url = "https://files.pythonhosted.org/packages/00/1b/b324030c706711c99769988fcb694b3cb23f247ad39a7823a78e361bdbb8/bcrypt-4.3.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:2ef6630e0ec01376f59a006dc72918b1bf436c3b571b80fa1968d775fa02fe7d", size = 355965, upload-time = "2025-02-28T01:22:59.181Z" }, + { url = "https://files.pythonhosted.org/packages/aa/dd/20372a0579dd915dfc3b1cd4943b3bca431866fcb1dfdfd7518c3caddea6/bcrypt-4.3.0-cp313-cp313t-win32.whl", hash = "sha256:7a4be4cbf241afee43f1c3969b9103a41b40bcb3a3f467ab19f891d9bc4642e4", size = 155316, upload-time = "2025-02-28T01:23:00.763Z" }, + { url = "https://files.pythonhosted.org/packages/6d/52/45d969fcff6b5577c2bf17098dc36269b4c02197d551371c023130c0f890/bcrypt-4.3.0-cp313-cp313t-win_amd64.whl", hash = "sha256:5c1949bf259a388863ced887c7861da1df681cb2388645766c89fdfd9004c669", size = 147752, upload-time = "2025-02-28T01:23:02.908Z" }, + { url = "https://files.pythonhosted.org/packages/11/22/5ada0b9af72b60cbc4c9a399fdde4af0feaa609d27eb0adc61607997a3fa/bcrypt-4.3.0-cp38-abi3-macosx_10_12_universal2.whl", hash = "sha256:f81b0ed2639568bf14749112298f9e4e2b28853dab50a8b357e31798686a036d", size = 498019, upload-time = "2025-02-28T01:23:05.838Z" }, + { url = "https://files.pythonhosted.org/packages/b8/8c/252a1edc598dc1ce57905be173328eda073083826955ee3c97c7ff5ba584/bcrypt-4.3.0-cp38-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:864f8f19adbe13b7de11ba15d85d4a428c7e2f344bac110f667676a0ff84924b", size = 279174, upload-time = "2025-02-28T01:23:07.274Z" }, + { url = "https://files.pythonhosted.org/packages/29/5b/4547d5c49b85f0337c13929f2ccbe08b7283069eea3550a457914fc078aa/bcrypt-4.3.0-cp38-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3e36506d001e93bffe59754397572f21bb5dc7c83f54454c990c74a468cd589e", size = 283870, upload-time = "2025-02-28T01:23:09.151Z" }, + { url = "https://files.pythonhosted.org/packages/be/21/7dbaf3fa1745cb63f776bb046e481fbababd7d344c5324eab47f5ca92dd2/bcrypt-4.3.0-cp38-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:842d08d75d9fe9fb94b18b071090220697f9f184d4547179b60734846461ed59", size = 279601, upload-time = "2025-02-28T01:23:11.461Z" }, + { url = "https://files.pythonhosted.org/packages/6d/64/e042fc8262e971347d9230d9abbe70d68b0a549acd8611c83cebd3eaec67/bcrypt-4.3.0-cp38-abi3-manylinux_2_28_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:7c03296b85cb87db865d91da79bf63d5609284fc0cab9472fdd8367bbd830753", size = 297660, upload-time = "2025-02-28T01:23:12.989Z" }, + { url = "https://files.pythonhosted.org/packages/50/b8/6294eb84a3fef3b67c69b4470fcdd5326676806bf2519cda79331ab3c3a9/bcrypt-4.3.0-cp38-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:62f26585e8b219cdc909b6a0069efc5e4267e25d4a3770a364ac58024f62a761", size = 284083, upload-time = "2025-02-28T01:23:14.5Z" }, + { url = "https://files.pythonhosted.org/packages/62/e6/baff635a4f2c42e8788fe1b1633911c38551ecca9a749d1052d296329da6/bcrypt-4.3.0-cp38-abi3-manylinux_2_34_aarch64.whl", hash = "sha256:beeefe437218a65322fbd0069eb437e7c98137e08f22c4660ac2dc795c31f8bb", size = 279237, upload-time = "2025-02-28T01:23:16.686Z" }, + { url = "https://files.pythonhosted.org/packages/39/48/46f623f1b0c7dc2e5de0b8af5e6f5ac4cc26408ac33f3d424e5ad8da4a90/bcrypt-4.3.0-cp38-abi3-manylinux_2_34_x86_64.whl", hash = "sha256:97eea7408db3a5bcce4a55d13245ab3fa566e23b4c67cd227062bb49e26c585d", size = 283737, upload-time = "2025-02-28T01:23:18.897Z" }, + { url = "https://files.pythonhosted.org/packages/49/8b/70671c3ce9c0fca4a6cc3cc6ccbaa7e948875a2e62cbd146e04a4011899c/bcrypt-4.3.0-cp38-abi3-musllinux_1_1_aarch64.whl", hash = "sha256:191354ebfe305e84f344c5964c7cd5f924a3bfc5d405c75ad07f232b6dffb49f", size = 312741, upload-time = "2025-02-28T01:23:21.041Z" }, + { url = "https://files.pythonhosted.org/packages/27/fb/910d3a1caa2d249b6040a5caf9f9866c52114d51523ac2fb47578a27faee/bcrypt-4.3.0-cp38-abi3-musllinux_1_1_x86_64.whl", hash = "sha256:41261d64150858eeb5ff43c753c4b216991e0ae16614a308a15d909503617732", size = 316472, upload-time = "2025-02-28T01:23:23.183Z" }, + { url = "https://files.pythonhosted.org/packages/dc/cf/7cf3a05b66ce466cfb575dbbda39718d45a609daa78500f57fa9f36fa3c0/bcrypt-4.3.0-cp38-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:33752b1ba962ee793fa2b6321404bf20011fe45b9afd2a842139de3011898fef", size = 343606, upload-time = "2025-02-28T01:23:25.361Z" }, + { url = "https://files.pythonhosted.org/packages/e3/b8/e970ecc6d7e355c0d892b7f733480f4aa8509f99b33e71550242cf0b7e63/bcrypt-4.3.0-cp38-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:50e6e80a4bfd23a25f5c05b90167c19030cf9f87930f7cb2eacb99f45d1c3304", size = 362867, upload-time = "2025-02-28T01:23:26.875Z" }, + { url = "https://files.pythonhosted.org/packages/a9/97/8d3118efd8354c555a3422d544163f40d9f236be5b96c714086463f11699/bcrypt-4.3.0-cp38-abi3-win32.whl", hash = "sha256:67a561c4d9fb9465ec866177e7aebcad08fe23aaf6fbd692a6fab69088abfc51", size = 160589, upload-time = "2025-02-28T01:23:28.381Z" }, + { url = "https://files.pythonhosted.org/packages/29/07/416f0b99f7f3997c69815365babbc2e8754181a4b1899d921b3c7d5b6f12/bcrypt-4.3.0-cp38-abi3-win_amd64.whl", hash = "sha256:584027857bc2843772114717a7490a37f68da563b3620f78a849bcb54dc11e62", size = 152794, upload-time = "2025-02-28T01:23:30.187Z" }, + { url = "https://files.pythonhosted.org/packages/6e/c1/3fa0e9e4e0bfd3fd77eb8b52ec198fd6e1fd7e9402052e43f23483f956dd/bcrypt-4.3.0-cp39-abi3-macosx_10_12_universal2.whl", hash = "sha256:0d3efb1157edebfd9128e4e46e2ac1a64e0c1fe46fb023158a407c7892b0f8c3", size = 498969, upload-time = "2025-02-28T01:23:31.945Z" }, + { url = "https://files.pythonhosted.org/packages/ce/d4/755ce19b6743394787fbd7dff6bf271b27ee9b5912a97242e3caf125885b/bcrypt-4.3.0-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:08bacc884fd302b611226c01014eca277d48f0a05187666bca23aac0dad6fe24", size = 279158, upload-time = "2025-02-28T01:23:34.161Z" }, + { url = "https://files.pythonhosted.org/packages/9b/5d/805ef1a749c965c46b28285dfb5cd272a7ed9fa971f970435a5133250182/bcrypt-4.3.0-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f6746e6fec103fcd509b96bacdfdaa2fbde9a553245dbada284435173a6f1aef", size = 284285, upload-time = "2025-02-28T01:23:35.765Z" }, + { url = "https://files.pythonhosted.org/packages/ab/2b/698580547a4a4988e415721b71eb45e80c879f0fb04a62da131f45987b96/bcrypt-4.3.0-cp39-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:afe327968aaf13fc143a56a3360cb27d4ad0345e34da12c7290f1b00b8fe9a8b", size = 279583, upload-time = "2025-02-28T01:23:38.021Z" }, + { url = "https://files.pythonhosted.org/packages/f2/87/62e1e426418204db520f955ffd06f1efd389feca893dad7095bf35612eec/bcrypt-4.3.0-cp39-abi3-manylinux_2_28_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:d9af79d322e735b1fc33404b5765108ae0ff232d4b54666d46730f8ac1a43676", size = 297896, upload-time = "2025-02-28T01:23:39.575Z" }, + { url = "https://files.pythonhosted.org/packages/cb/c6/8fedca4c2ada1b6e889c52d2943b2f968d3427e5d65f595620ec4c06fa2f/bcrypt-4.3.0-cp39-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:f1e3ffa1365e8702dc48c8b360fef8d7afeca482809c5e45e653af82ccd088c1", size = 284492, upload-time = "2025-02-28T01:23:40.901Z" }, + { url = "https://files.pythonhosted.org/packages/4d/4d/c43332dcaaddb7710a8ff5269fcccba97ed3c85987ddaa808db084267b9a/bcrypt-4.3.0-cp39-abi3-manylinux_2_34_aarch64.whl", hash = "sha256:3004df1b323d10021fda07a813fd33e0fd57bef0e9a480bb143877f6cba996fe", size = 279213, upload-time = "2025-02-28T01:23:42.653Z" }, + { url = "https://files.pythonhosted.org/packages/dc/7f/1e36379e169a7df3a14a1c160a49b7b918600a6008de43ff20d479e6f4b5/bcrypt-4.3.0-cp39-abi3-manylinux_2_34_x86_64.whl", hash = "sha256:531457e5c839d8caea9b589a1bcfe3756b0547d7814e9ce3d437f17da75c32b0", size = 284162, upload-time = "2025-02-28T01:23:43.964Z" }, + { url = "https://files.pythonhosted.org/packages/1c/0a/644b2731194b0d7646f3210dc4d80c7fee3ecb3a1f791a6e0ae6bb8684e3/bcrypt-4.3.0-cp39-abi3-musllinux_1_1_aarch64.whl", hash = "sha256:17a854d9a7a476a89dcef6c8bd119ad23e0f82557afbd2c442777a16408e614f", size = 312856, upload-time = "2025-02-28T01:23:46.011Z" }, + { url = "https://files.pythonhosted.org/packages/dc/62/2a871837c0bb6ab0c9a88bf54de0fc021a6a08832d4ea313ed92a669d437/bcrypt-4.3.0-cp39-abi3-musllinux_1_1_x86_64.whl", hash = "sha256:6fb1fd3ab08c0cbc6826a2e0447610c6f09e983a281b919ed721ad32236b8b23", size = 316726, upload-time = "2025-02-28T01:23:47.575Z" }, + { url = "https://files.pythonhosted.org/packages/0c/a1/9898ea3faac0b156d457fd73a3cb9c2855c6fd063e44b8522925cdd8ce46/bcrypt-4.3.0-cp39-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:e965a9c1e9a393b8005031ff52583cedc15b7884fce7deb8b0346388837d6cfe", size = 343664, upload-time = "2025-02-28T01:23:49.059Z" }, + { url = "https://files.pythonhosted.org/packages/40/f2/71b4ed65ce38982ecdda0ff20c3ad1b15e71949c78b2c053df53629ce940/bcrypt-4.3.0-cp39-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:79e70b8342a33b52b55d93b3a59223a844962bef479f6a0ea318ebbcadf71505", size = 363128, upload-time = "2025-02-28T01:23:50.399Z" }, + { url = "https://files.pythonhosted.org/packages/11/99/12f6a58eca6dea4be992d6c681b7ec9410a1d9f5cf368c61437e31daa879/bcrypt-4.3.0-cp39-abi3-win32.whl", hash = "sha256:b4d4e57f0a63fd0b358eb765063ff661328f69a04494427265950c71b992a39a", size = 160598, upload-time = "2025-02-28T01:23:51.775Z" }, + { url = "https://files.pythonhosted.org/packages/a9/cf/45fb5261ece3e6b9817d3d82b2f343a505fd58674a92577923bc500bd1aa/bcrypt-4.3.0-cp39-abi3-win_amd64.whl", hash = "sha256:e53e074b120f2877a35cc6c736b8eb161377caae8925c17688bd46ba56daaa5b", size = 152799, upload-time = "2025-02-28T01:23:53.139Z" }, ] [[package]] @@ -215,64 +215,64 @@ dependencies = [ { name = "soupsieve" }, { name = "typing-extensions" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/77/e9/df2358efd7659577435e2177bfa69cba6c33216681af51a707193dec162a/beautifulsoup4-4.14.2.tar.gz", hash = "sha256:2a98ab9f944a11acee9cc848508ec28d9228abfd522ef0fad6a02a72e0ded69e", size = 625822 } +sdist = { url = "https://files.pythonhosted.org/packages/77/e9/df2358efd7659577435e2177bfa69cba6c33216681af51a707193dec162a/beautifulsoup4-4.14.2.tar.gz", hash = "sha256:2a98ab9f944a11acee9cc848508ec28d9228abfd522ef0fad6a02a72e0ded69e", size = 625822, upload-time = "2025-09-29T10:05:42.613Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/94/fe/3aed5d0be4d404d12d36ab97e2f1791424d9ca39c2f754a6285d59a3b01d/beautifulsoup4-4.14.2-py3-none-any.whl", hash = "sha256:5ef6fa3a8cbece8488d66985560f97ed091e22bbc4e9c2338508a9d5de6d4515", size = 106392 }, + { url = "https://files.pythonhosted.org/packages/94/fe/3aed5d0be4d404d12d36ab97e2f1791424d9ca39c2f754a6285d59a3b01d/beautifulsoup4-4.14.2-py3-none-any.whl", hash = "sha256:5ef6fa3a8cbece8488d66985560f97ed091e22bbc4e9c2338508a9d5de6d4515", size = 106392, upload-time = "2025-09-29T10:05:43.771Z" }, ] [[package]] name = "blinker" version = "1.9.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/21/28/9b3f50ce0e048515135495f198351908d99540d69bfdc8c1d15b73dc55ce/blinker-1.9.0.tar.gz", hash = "sha256:b4ce2265a7abece45e7cc896e98dbebe6cead56bcf805a3d23136d145f5445bf", size = 22460 } +sdist = { url = "https://files.pythonhosted.org/packages/21/28/9b3f50ce0e048515135495f198351908d99540d69bfdc8c1d15b73dc55ce/blinker-1.9.0.tar.gz", hash = "sha256:b4ce2265a7abece45e7cc896e98dbebe6cead56bcf805a3d23136d145f5445bf", size = 22460, upload-time = "2024-11-08T17:25:47.436Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/10/cb/f2ad4230dc2eb1a74edf38f1a38b9b52277f75bef262d8908e60d957e13c/blinker-1.9.0-py3-none-any.whl", hash = "sha256:ba0efaa9080b619ff2f3459d1d500c57bddea4a6b424b60a91141db6fd2f08bc", size = 8458 }, + { url = "https://files.pythonhosted.org/packages/10/cb/f2ad4230dc2eb1a74edf38f1a38b9b52277f75bef262d8908e60d957e13c/blinker-1.9.0-py3-none-any.whl", hash = "sha256:ba0efaa9080b619ff2f3459d1d500c57bddea4a6b424b60a91141db6fd2f08bc", size = 8458, upload-time = "2024-11-08T17:25:46.184Z" }, ] [[package]] name = "boto3" -version = "1.40.68" +version = "1.40.69" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "botocore" }, { name = "jmespath" }, { name = "s3transfer" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/df/3e/6c8ab966798f4e07651009ad08efc3ed4ffccf2662318790574695c740f7/boto3-1.40.68.tar.gz", hash = "sha256:c7994989e5bbba071b7c742adfba35773cf03e87f5d3f9f2b0a18c1664417b61", size = 111629 } +sdist = { url = "https://files.pythonhosted.org/packages/56/36/65d292d14261aedbb9a22e5bf194d84c119c889135b42448db646d06d76b/boto3-1.40.69.tar.gz", hash = "sha256:5273f6bac347331a87db809dff97d8736c50c3be19f2bb36ad08c5131c408976", size = 111628, upload-time = "2025-11-07T20:26:26.949Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/07/e6/b9df94d3a51ad658ef1974da6c0d7401b6aed7be50a2ee57bf1de1ef9517/boto3-1.40.68-py3-none-any.whl", hash = "sha256:4f08115e3a4d1e1056003e433d393e78c20da6af7753409992bb33fb69f04186", size = 139361 }, + { url = "https://files.pythonhosted.org/packages/4d/2f/65009a8d274cd9c7211807c1a07cce17203ffe76368e3ebc4ca03a7b79de/boto3-1.40.69-py3-none-any.whl", hash = "sha256:c3f710a1990c4be1c0db43b938743d4e404c7f1f06d5f1fa0c8e9b1cea4290b2", size = 139361, upload-time = "2025-11-07T20:26:24.522Z" }, ] [[package]] name = "botocore" -version = "1.40.68" +version = "1.40.69" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "jmespath" }, { name = "python-dateutil" }, { name = "urllib3" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/eb/df/b0300da4cc1fe3e37c8d7a44d835518004454c7d21b579fce9ef2cd691ce/botocore-1.40.68.tar.gz", hash = "sha256:28f41b463d9f012a711ee8b61d4e26cd14ee3b450b816d5dee849aa79155e856", size = 14435596 } +sdist = { url = "https://files.pythonhosted.org/packages/e2/73/42499b183ca5cef25c35338ad2636368b0ae2193654642756492e96ee906/botocore-1.40.69.tar.gz", hash = "sha256:df310ddc4d2de5543ba3df4e4b5f9907a2951896d63a9fbae115c26ca0976951", size = 14440352, upload-time = "2025-11-07T20:26:14.276Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/7a/72/ac8123169ce48cb2eb593cd4c6a22e66d72bf8dc30fe75191a7669dd036d/botocore-1.40.68-py3-none-any.whl", hash = "sha256:9d514f9c9054e1af055f2cbe9e0d6771d407a600206d45a01b54d5f09538fecb", size = 14097634 }, + { url = "https://files.pythonhosted.org/packages/61/d6/bf2b91d4a92af6ee70e0689913414463a48cf51c0fc855c98b94bde8e7f3/botocore-1.40.69-py3-none-any.whl", hash = "sha256:5d810efeb9e18f91f32690642fa81ae60e482eefeea0d35ec72da2e3d924c1a5", size = 14103454, upload-time = "2025-11-07T20:26:09.486Z" }, ] [[package]] name = "cachetools" version = "5.5.2" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/6c/81/3747dad6b14fa2cf53fcf10548cf5aea6913e96fab41a3c198676f8948a5/cachetools-5.5.2.tar.gz", hash = "sha256:1a661caa9175d26759571b2e19580f9d6393969e5dfca11fdb1f947a23e640d4", size = 28380 } +sdist = { url = "https://files.pythonhosted.org/packages/6c/81/3747dad6b14fa2cf53fcf10548cf5aea6913e96fab41a3c198676f8948a5/cachetools-5.5.2.tar.gz", hash = "sha256:1a661caa9175d26759571b2e19580f9d6393969e5dfca11fdb1f947a23e640d4", size = 28380, upload-time = "2025-02-20T21:01:19.524Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/72/76/20fa66124dbe6be5cafeb312ece67de6b61dd91a0247d1ea13db4ebb33c2/cachetools-5.5.2-py3-none-any.whl", hash = "sha256:d26a22bcc62eb95c3beabd9f1ee5e820d3d2704fe2967cbe350e20c8ffcd3f0a", size = 10080 }, + { url = "https://files.pythonhosted.org/packages/72/76/20fa66124dbe6be5cafeb312ece67de6b61dd91a0247d1ea13db4ebb33c2/cachetools-5.5.2-py3-none-any.whl", hash = "sha256:d26a22bcc62eb95c3beabd9f1ee5e820d3d2704fe2967cbe350e20c8ffcd3f0a", size = 10080, upload-time = "2025-02-20T21:01:16.647Z" }, ] [[package]] name = "certifi" version = "2025.10.5" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/4c/5b/b6ce21586237c77ce67d01dc5507039d444b630dd76611bbca2d8e5dcd91/certifi-2025.10.5.tar.gz", hash = "sha256:47c09d31ccf2acf0be3f701ea53595ee7e0b8fa08801c6624be771df09ae7b43", size = 164519 } +sdist = { url = "https://files.pythonhosted.org/packages/4c/5b/b6ce21586237c77ce67d01dc5507039d444b630dd76611bbca2d8e5dcd91/certifi-2025.10.5.tar.gz", hash = "sha256:47c09d31ccf2acf0be3f701ea53595ee7e0b8fa08801c6624be771df09ae7b43", size = 164519, upload-time = "2025-10-05T04:12:15.808Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/e4/37/af0d2ef3967ac0d6113837b44a4f0bfe1328c2b9763bd5b1744520e5cfed/certifi-2025.10.5-py3-none-any.whl", hash = "sha256:0f212c2744a9bb6de0c56639a6f68afe01ecd92d91f14ae897c4fe7bbeeef0de", size = 163286 }, + { url = "https://files.pythonhosted.org/packages/e4/37/af0d2ef3967ac0d6113837b44a4f0bfe1328c2b9763bd5b1744520e5cfed/certifi-2025.10.5-py3-none-any.whl", hash = "sha256:0f212c2744a9bb6de0c56639a6f68afe01ecd92d91f14ae897c4fe7bbeeef0de", size = 163286, upload-time = "2025-10-05T04:12:14.03Z" }, ] [[package]] @@ -282,83 +282,83 @@ source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "pycparser", marker = "implementation_name != 'PyPy'" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/eb/56/b1ba7935a17738ae8453301356628e8147c79dbb825bcbc73dc7401f9846/cffi-2.0.0.tar.gz", hash = "sha256:44d1b5909021139fe36001ae048dbdde8214afa20200eda0f64c068cac5d5529", size = 523588 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/4b/8d/a0a47a0c9e413a658623d014e91e74a50cdd2c423f7ccfd44086ef767f90/cffi-2.0.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:00bdf7acc5f795150faa6957054fbbca2439db2f775ce831222b66f192f03beb", size = 185230 }, - { url = "https://files.pythonhosted.org/packages/4a/d2/a6c0296814556c68ee32009d9c2ad4f85f2707cdecfd7727951ec228005d/cffi-2.0.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:45d5e886156860dc35862657e1494b9bae8dfa63bf56796f2fb56e1679fc0bca", size = 181043 }, - { url = "https://files.pythonhosted.org/packages/b0/1e/d22cc63332bd59b06481ceaac49d6c507598642e2230f201649058a7e704/cffi-2.0.0-cp313-cp313-manylinux1_i686.manylinux2014_i686.manylinux_2_17_i686.manylinux_2_5_i686.whl", hash = "sha256:07b271772c100085dd28b74fa0cd81c8fb1a3ba18b21e03d7c27f3436a10606b", size = 212446 }, - { url = "https://files.pythonhosted.org/packages/a9/f5/a2c23eb03b61a0b8747f211eb716446c826ad66818ddc7810cc2cc19b3f2/cffi-2.0.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:d48a880098c96020b02d5a1f7d9251308510ce8858940e6fa99ece33f610838b", size = 220101 }, - { url = "https://files.pythonhosted.org/packages/f2/7f/e6647792fc5850d634695bc0e6ab4111ae88e89981d35ac269956605feba/cffi-2.0.0-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:f93fd8e5c8c0a4aa1f424d6173f14a892044054871c771f8566e4008eaa359d2", size = 207948 }, - { url = "https://files.pythonhosted.org/packages/cb/1e/a5a1bd6f1fb30f22573f76533de12a00bf274abcdc55c8edab639078abb6/cffi-2.0.0-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:dd4f05f54a52fb558f1ba9f528228066954fee3ebe629fc1660d874d040ae5a3", size = 206422 }, - { url = "https://files.pythonhosted.org/packages/98/df/0a1755e750013a2081e863e7cd37e0cdd02664372c754e5560099eb7aa44/cffi-2.0.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:c8d3b5532fc71b7a77c09192b4a5a200ea992702734a2e9279a37f2478236f26", size = 219499 }, - { url = "https://files.pythonhosted.org/packages/50/e1/a969e687fcf9ea58e6e2a928ad5e2dd88cc12f6f0ab477e9971f2309b57c/cffi-2.0.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:d9b29c1f0ae438d5ee9acb31cadee00a58c46cc9c0b2f9038c6b0b3470877a8c", size = 222928 }, - { url = "https://files.pythonhosted.org/packages/36/54/0362578dd2c9e557a28ac77698ed67323ed5b9775ca9d3fe73fe191bb5d8/cffi-2.0.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:6d50360be4546678fc1b79ffe7a66265e28667840010348dd69a314145807a1b", size = 221302 }, - { url = "https://files.pythonhosted.org/packages/eb/6d/bf9bda840d5f1dfdbf0feca87fbdb64a918a69bca42cfa0ba7b137c48cb8/cffi-2.0.0-cp313-cp313-win32.whl", hash = "sha256:74a03b9698e198d47562765773b4a8309919089150a0bb17d829ad7b44b60d27", size = 172909 }, - { url = "https://files.pythonhosted.org/packages/37/18/6519e1ee6f5a1e579e04b9ddb6f1676c17368a7aba48299c3759bbc3c8b3/cffi-2.0.0-cp313-cp313-win_amd64.whl", hash = "sha256:19f705ada2530c1167abacb171925dd886168931e0a7b78f5bffcae5c6b5be75", size = 183402 }, - { url = "https://files.pythonhosted.org/packages/cb/0e/02ceeec9a7d6ee63bb596121c2c8e9b3a9e150936f4fbef6ca1943e6137c/cffi-2.0.0-cp313-cp313-win_arm64.whl", hash = "sha256:256f80b80ca3853f90c21b23ee78cd008713787b1b1e93eae9f3d6a7134abd91", size = 177780 }, - { url = "https://files.pythonhosted.org/packages/92/c4/3ce07396253a83250ee98564f8d7e9789fab8e58858f35d07a9a2c78de9f/cffi-2.0.0-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:fc33c5141b55ed366cfaad382df24fe7dcbc686de5be719b207bb248e3053dc5", size = 185320 }, - { url = "https://files.pythonhosted.org/packages/59/dd/27e9fa567a23931c838c6b02d0764611c62290062a6d4e8ff7863daf9730/cffi-2.0.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:c654de545946e0db659b3400168c9ad31b5d29593291482c43e3564effbcee13", size = 181487 }, - { url = "https://files.pythonhosted.org/packages/d6/43/0e822876f87ea8a4ef95442c3d766a06a51fc5298823f884ef87aaad168c/cffi-2.0.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:24b6f81f1983e6df8db3adc38562c83f7d4a0c36162885ec7f7b77c7dcbec97b", size = 220049 }, - { url = "https://files.pythonhosted.org/packages/b4/89/76799151d9c2d2d1ead63c2429da9ea9d7aac304603de0c6e8764e6e8e70/cffi-2.0.0-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:12873ca6cb9b0f0d3a0da705d6086fe911591737a59f28b7936bdfed27c0d47c", size = 207793 }, - { url = "https://files.pythonhosted.org/packages/bb/dd/3465b14bb9e24ee24cb88c9e3730f6de63111fffe513492bf8c808a3547e/cffi-2.0.0-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:d9b97165e8aed9272a6bb17c01e3cc5871a594a446ebedc996e2397a1c1ea8ef", size = 206300 }, - { url = "https://files.pythonhosted.org/packages/47/d9/d83e293854571c877a92da46fdec39158f8d7e68da75bf73581225d28e90/cffi-2.0.0-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:afb8db5439b81cf9c9d0c80404b60c3cc9c3add93e114dcae767f1477cb53775", size = 219244 }, - { url = "https://files.pythonhosted.org/packages/2b/0f/1f177e3683aead2bb00f7679a16451d302c436b5cbf2505f0ea8146ef59e/cffi-2.0.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:737fe7d37e1a1bffe70bd5754ea763a62a066dc5913ca57e957824b72a85e205", size = 222828 }, - { url = "https://files.pythonhosted.org/packages/c6/0f/cafacebd4b040e3119dcb32fed8bdef8dfe94da653155f9d0b9dc660166e/cffi-2.0.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:38100abb9d1b1435bc4cc340bb4489635dc2f0da7456590877030c9b3d40b0c1", size = 220926 }, - { url = "https://files.pythonhosted.org/packages/3e/aa/df335faa45b395396fcbc03de2dfcab242cd61a9900e914fe682a59170b1/cffi-2.0.0-cp314-cp314-win32.whl", hash = "sha256:087067fa8953339c723661eda6b54bc98c5625757ea62e95eb4898ad5e776e9f", size = 175328 }, - { url = "https://files.pythonhosted.org/packages/bb/92/882c2d30831744296ce713f0feb4c1cd30f346ef747b530b5318715cc367/cffi-2.0.0-cp314-cp314-win_amd64.whl", hash = "sha256:203a48d1fb583fc7d78a4c6655692963b860a417c0528492a6bc21f1aaefab25", size = 185650 }, - { url = "https://files.pythonhosted.org/packages/9f/2c/98ece204b9d35a7366b5b2c6539c350313ca13932143e79dc133ba757104/cffi-2.0.0-cp314-cp314-win_arm64.whl", hash = "sha256:dbd5c7a25a7cb98f5ca55d258b103a2054f859a46ae11aaf23134f9cc0d356ad", size = 180687 }, - { url = "https://files.pythonhosted.org/packages/3e/61/c768e4d548bfa607abcda77423448df8c471f25dbe64fb2ef6d555eae006/cffi-2.0.0-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:9a67fc9e8eb39039280526379fb3a70023d77caec1852002b4da7e8b270c4dd9", size = 188773 }, - { url = "https://files.pythonhosted.org/packages/2c/ea/5f76bce7cf6fcd0ab1a1058b5af899bfbef198bea4d5686da88471ea0336/cffi-2.0.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:7a66c7204d8869299919db4d5069a82f1561581af12b11b3c9f48c584eb8743d", size = 185013 }, - { url = "https://files.pythonhosted.org/packages/be/b4/c56878d0d1755cf9caa54ba71e5d049479c52f9e4afc230f06822162ab2f/cffi-2.0.0-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:7cc09976e8b56f8cebd752f7113ad07752461f48a58cbba644139015ac24954c", size = 221593 }, - { url = "https://files.pythonhosted.org/packages/e0/0d/eb704606dfe8033e7128df5e90fee946bbcb64a04fcdaa97321309004000/cffi-2.0.0-cp314-cp314t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:92b68146a71df78564e4ef48af17551a5ddd142e5190cdf2c5624d0c3ff5b2e8", size = 209354 }, - { url = "https://files.pythonhosted.org/packages/d8/19/3c435d727b368ca475fb8742ab97c9cb13a0de600ce86f62eab7fa3eea60/cffi-2.0.0-cp314-cp314t-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:b1e74d11748e7e98e2f426ab176d4ed720a64412b6a15054378afdb71e0f37dc", size = 208480 }, - { url = "https://files.pythonhosted.org/packages/d0/44/681604464ed9541673e486521497406fadcc15b5217c3e326b061696899a/cffi-2.0.0-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:28a3a209b96630bca57cce802da70c266eb08c6e97e5afd61a75611ee6c64592", size = 221584 }, - { url = "https://files.pythonhosted.org/packages/25/8e/342a504ff018a2825d395d44d63a767dd8ebc927ebda557fecdaca3ac33a/cffi-2.0.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:7553fb2090d71822f02c629afe6042c299edf91ba1bf94951165613553984512", size = 224443 }, - { url = "https://files.pythonhosted.org/packages/e1/5e/b666bacbbc60fbf415ba9988324a132c9a7a0448a9a8f125074671c0f2c3/cffi-2.0.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:6c6c373cfc5c83a975506110d17457138c8c63016b563cc9ed6e056a82f13ce4", size = 223437 }, - { url = "https://files.pythonhosted.org/packages/a0/1d/ec1a60bd1a10daa292d3cd6bb0b359a81607154fb8165f3ec95fe003b85c/cffi-2.0.0-cp314-cp314t-win32.whl", hash = "sha256:1fc9ea04857caf665289b7a75923f2c6ed559b8298a1b8c49e59f7dd95c8481e", size = 180487 }, - { url = "https://files.pythonhosted.org/packages/bf/41/4c1168c74fac325c0c8156f04b6749c8b6a8f405bbf91413ba088359f60d/cffi-2.0.0-cp314-cp314t-win_amd64.whl", hash = "sha256:d68b6cef7827e8641e8ef16f4494edda8b36104d79773a334beaa1e3521430f6", size = 191726 }, - { url = "https://files.pythonhosted.org/packages/ae/3a/dbeec9d1ee0844c679f6bb5d6ad4e9f198b1224f4e7a32825f47f6192b0c/cffi-2.0.0-cp314-cp314t-win_arm64.whl", hash = "sha256:0a1527a803f0a659de1af2e1fd700213caba79377e27e4693648c2923da066f9", size = 184195 }, +sdist = { url = "https://files.pythonhosted.org/packages/eb/56/b1ba7935a17738ae8453301356628e8147c79dbb825bcbc73dc7401f9846/cffi-2.0.0.tar.gz", hash = "sha256:44d1b5909021139fe36001ae048dbdde8214afa20200eda0f64c068cac5d5529", size = 523588, upload-time = "2025-09-08T23:24:04.541Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/4b/8d/a0a47a0c9e413a658623d014e91e74a50cdd2c423f7ccfd44086ef767f90/cffi-2.0.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:00bdf7acc5f795150faa6957054fbbca2439db2f775ce831222b66f192f03beb", size = 185230, upload-time = "2025-09-08T23:23:00.879Z" }, + { url = "https://files.pythonhosted.org/packages/4a/d2/a6c0296814556c68ee32009d9c2ad4f85f2707cdecfd7727951ec228005d/cffi-2.0.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:45d5e886156860dc35862657e1494b9bae8dfa63bf56796f2fb56e1679fc0bca", size = 181043, upload-time = "2025-09-08T23:23:02.231Z" }, + { url = "https://files.pythonhosted.org/packages/b0/1e/d22cc63332bd59b06481ceaac49d6c507598642e2230f201649058a7e704/cffi-2.0.0-cp313-cp313-manylinux1_i686.manylinux2014_i686.manylinux_2_17_i686.manylinux_2_5_i686.whl", hash = "sha256:07b271772c100085dd28b74fa0cd81c8fb1a3ba18b21e03d7c27f3436a10606b", size = 212446, upload-time = "2025-09-08T23:23:03.472Z" }, + { url = "https://files.pythonhosted.org/packages/a9/f5/a2c23eb03b61a0b8747f211eb716446c826ad66818ddc7810cc2cc19b3f2/cffi-2.0.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:d48a880098c96020b02d5a1f7d9251308510ce8858940e6fa99ece33f610838b", size = 220101, upload-time = "2025-09-08T23:23:04.792Z" }, + { url = "https://files.pythonhosted.org/packages/f2/7f/e6647792fc5850d634695bc0e6ab4111ae88e89981d35ac269956605feba/cffi-2.0.0-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:f93fd8e5c8c0a4aa1f424d6173f14a892044054871c771f8566e4008eaa359d2", size = 207948, upload-time = "2025-09-08T23:23:06.127Z" }, + { url = "https://files.pythonhosted.org/packages/cb/1e/a5a1bd6f1fb30f22573f76533de12a00bf274abcdc55c8edab639078abb6/cffi-2.0.0-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:dd4f05f54a52fb558f1ba9f528228066954fee3ebe629fc1660d874d040ae5a3", size = 206422, upload-time = "2025-09-08T23:23:07.753Z" }, + { url = "https://files.pythonhosted.org/packages/98/df/0a1755e750013a2081e863e7cd37e0cdd02664372c754e5560099eb7aa44/cffi-2.0.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:c8d3b5532fc71b7a77c09192b4a5a200ea992702734a2e9279a37f2478236f26", size = 219499, upload-time = "2025-09-08T23:23:09.648Z" }, + { url = "https://files.pythonhosted.org/packages/50/e1/a969e687fcf9ea58e6e2a928ad5e2dd88cc12f6f0ab477e9971f2309b57c/cffi-2.0.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:d9b29c1f0ae438d5ee9acb31cadee00a58c46cc9c0b2f9038c6b0b3470877a8c", size = 222928, upload-time = "2025-09-08T23:23:10.928Z" }, + { url = "https://files.pythonhosted.org/packages/36/54/0362578dd2c9e557a28ac77698ed67323ed5b9775ca9d3fe73fe191bb5d8/cffi-2.0.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:6d50360be4546678fc1b79ffe7a66265e28667840010348dd69a314145807a1b", size = 221302, upload-time = "2025-09-08T23:23:12.42Z" }, + { url = "https://files.pythonhosted.org/packages/eb/6d/bf9bda840d5f1dfdbf0feca87fbdb64a918a69bca42cfa0ba7b137c48cb8/cffi-2.0.0-cp313-cp313-win32.whl", hash = "sha256:74a03b9698e198d47562765773b4a8309919089150a0bb17d829ad7b44b60d27", size = 172909, upload-time = "2025-09-08T23:23:14.32Z" }, + { url = "https://files.pythonhosted.org/packages/37/18/6519e1ee6f5a1e579e04b9ddb6f1676c17368a7aba48299c3759bbc3c8b3/cffi-2.0.0-cp313-cp313-win_amd64.whl", hash = "sha256:19f705ada2530c1167abacb171925dd886168931e0a7b78f5bffcae5c6b5be75", size = 183402, upload-time = "2025-09-08T23:23:15.535Z" }, + { url = "https://files.pythonhosted.org/packages/cb/0e/02ceeec9a7d6ee63bb596121c2c8e9b3a9e150936f4fbef6ca1943e6137c/cffi-2.0.0-cp313-cp313-win_arm64.whl", hash = "sha256:256f80b80ca3853f90c21b23ee78cd008713787b1b1e93eae9f3d6a7134abd91", size = 177780, upload-time = "2025-09-08T23:23:16.761Z" }, + { url = "https://files.pythonhosted.org/packages/92/c4/3ce07396253a83250ee98564f8d7e9789fab8e58858f35d07a9a2c78de9f/cffi-2.0.0-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:fc33c5141b55ed366cfaad382df24fe7dcbc686de5be719b207bb248e3053dc5", size = 185320, upload-time = "2025-09-08T23:23:18.087Z" }, + { url = "https://files.pythonhosted.org/packages/59/dd/27e9fa567a23931c838c6b02d0764611c62290062a6d4e8ff7863daf9730/cffi-2.0.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:c654de545946e0db659b3400168c9ad31b5d29593291482c43e3564effbcee13", size = 181487, upload-time = "2025-09-08T23:23:19.622Z" }, + { url = "https://files.pythonhosted.org/packages/d6/43/0e822876f87ea8a4ef95442c3d766a06a51fc5298823f884ef87aaad168c/cffi-2.0.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:24b6f81f1983e6df8db3adc38562c83f7d4a0c36162885ec7f7b77c7dcbec97b", size = 220049, upload-time = "2025-09-08T23:23:20.853Z" }, + { url = "https://files.pythonhosted.org/packages/b4/89/76799151d9c2d2d1ead63c2429da9ea9d7aac304603de0c6e8764e6e8e70/cffi-2.0.0-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:12873ca6cb9b0f0d3a0da705d6086fe911591737a59f28b7936bdfed27c0d47c", size = 207793, upload-time = "2025-09-08T23:23:22.08Z" }, + { url = "https://files.pythonhosted.org/packages/bb/dd/3465b14bb9e24ee24cb88c9e3730f6de63111fffe513492bf8c808a3547e/cffi-2.0.0-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:d9b97165e8aed9272a6bb17c01e3cc5871a594a446ebedc996e2397a1c1ea8ef", size = 206300, upload-time = "2025-09-08T23:23:23.314Z" }, + { url = "https://files.pythonhosted.org/packages/47/d9/d83e293854571c877a92da46fdec39158f8d7e68da75bf73581225d28e90/cffi-2.0.0-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:afb8db5439b81cf9c9d0c80404b60c3cc9c3add93e114dcae767f1477cb53775", size = 219244, upload-time = "2025-09-08T23:23:24.541Z" }, + { url = "https://files.pythonhosted.org/packages/2b/0f/1f177e3683aead2bb00f7679a16451d302c436b5cbf2505f0ea8146ef59e/cffi-2.0.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:737fe7d37e1a1bffe70bd5754ea763a62a066dc5913ca57e957824b72a85e205", size = 222828, upload-time = "2025-09-08T23:23:26.143Z" }, + { url = "https://files.pythonhosted.org/packages/c6/0f/cafacebd4b040e3119dcb32fed8bdef8dfe94da653155f9d0b9dc660166e/cffi-2.0.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:38100abb9d1b1435bc4cc340bb4489635dc2f0da7456590877030c9b3d40b0c1", size = 220926, upload-time = "2025-09-08T23:23:27.873Z" }, + { url = "https://files.pythonhosted.org/packages/3e/aa/df335faa45b395396fcbc03de2dfcab242cd61a9900e914fe682a59170b1/cffi-2.0.0-cp314-cp314-win32.whl", hash = "sha256:087067fa8953339c723661eda6b54bc98c5625757ea62e95eb4898ad5e776e9f", size = 175328, upload-time = "2025-09-08T23:23:44.61Z" }, + { url = "https://files.pythonhosted.org/packages/bb/92/882c2d30831744296ce713f0feb4c1cd30f346ef747b530b5318715cc367/cffi-2.0.0-cp314-cp314-win_amd64.whl", hash = "sha256:203a48d1fb583fc7d78a4c6655692963b860a417c0528492a6bc21f1aaefab25", size = 185650, upload-time = "2025-09-08T23:23:45.848Z" }, + { url = "https://files.pythonhosted.org/packages/9f/2c/98ece204b9d35a7366b5b2c6539c350313ca13932143e79dc133ba757104/cffi-2.0.0-cp314-cp314-win_arm64.whl", hash = "sha256:dbd5c7a25a7cb98f5ca55d258b103a2054f859a46ae11aaf23134f9cc0d356ad", size = 180687, upload-time = "2025-09-08T23:23:47.105Z" }, + { url = "https://files.pythonhosted.org/packages/3e/61/c768e4d548bfa607abcda77423448df8c471f25dbe64fb2ef6d555eae006/cffi-2.0.0-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:9a67fc9e8eb39039280526379fb3a70023d77caec1852002b4da7e8b270c4dd9", size = 188773, upload-time = "2025-09-08T23:23:29.347Z" }, + { url = "https://files.pythonhosted.org/packages/2c/ea/5f76bce7cf6fcd0ab1a1058b5af899bfbef198bea4d5686da88471ea0336/cffi-2.0.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:7a66c7204d8869299919db4d5069a82f1561581af12b11b3c9f48c584eb8743d", size = 185013, upload-time = "2025-09-08T23:23:30.63Z" }, + { url = "https://files.pythonhosted.org/packages/be/b4/c56878d0d1755cf9caa54ba71e5d049479c52f9e4afc230f06822162ab2f/cffi-2.0.0-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:7cc09976e8b56f8cebd752f7113ad07752461f48a58cbba644139015ac24954c", size = 221593, upload-time = "2025-09-08T23:23:31.91Z" }, + { url = "https://files.pythonhosted.org/packages/e0/0d/eb704606dfe8033e7128df5e90fee946bbcb64a04fcdaa97321309004000/cffi-2.0.0-cp314-cp314t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:92b68146a71df78564e4ef48af17551a5ddd142e5190cdf2c5624d0c3ff5b2e8", size = 209354, upload-time = "2025-09-08T23:23:33.214Z" }, + { url = "https://files.pythonhosted.org/packages/d8/19/3c435d727b368ca475fb8742ab97c9cb13a0de600ce86f62eab7fa3eea60/cffi-2.0.0-cp314-cp314t-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:b1e74d11748e7e98e2f426ab176d4ed720a64412b6a15054378afdb71e0f37dc", size = 208480, upload-time = "2025-09-08T23:23:34.495Z" }, + { url = "https://files.pythonhosted.org/packages/d0/44/681604464ed9541673e486521497406fadcc15b5217c3e326b061696899a/cffi-2.0.0-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:28a3a209b96630bca57cce802da70c266eb08c6e97e5afd61a75611ee6c64592", size = 221584, upload-time = "2025-09-08T23:23:36.096Z" }, + { url = "https://files.pythonhosted.org/packages/25/8e/342a504ff018a2825d395d44d63a767dd8ebc927ebda557fecdaca3ac33a/cffi-2.0.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:7553fb2090d71822f02c629afe6042c299edf91ba1bf94951165613553984512", size = 224443, upload-time = "2025-09-08T23:23:37.328Z" }, + { url = "https://files.pythonhosted.org/packages/e1/5e/b666bacbbc60fbf415ba9988324a132c9a7a0448a9a8f125074671c0f2c3/cffi-2.0.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:6c6c373cfc5c83a975506110d17457138c8c63016b563cc9ed6e056a82f13ce4", size = 223437, upload-time = "2025-09-08T23:23:38.945Z" }, + { url = "https://files.pythonhosted.org/packages/a0/1d/ec1a60bd1a10daa292d3cd6bb0b359a81607154fb8165f3ec95fe003b85c/cffi-2.0.0-cp314-cp314t-win32.whl", hash = "sha256:1fc9ea04857caf665289b7a75923f2c6ed559b8298a1b8c49e59f7dd95c8481e", size = 180487, upload-time = "2025-09-08T23:23:40.423Z" }, + { url = "https://files.pythonhosted.org/packages/bf/41/4c1168c74fac325c0c8156f04b6749c8b6a8f405bbf91413ba088359f60d/cffi-2.0.0-cp314-cp314t-win_amd64.whl", hash = "sha256:d68b6cef7827e8641e8ef16f4494edda8b36104d79773a334beaa1e3521430f6", size = 191726, upload-time = "2025-09-08T23:23:41.742Z" }, + { url = "https://files.pythonhosted.org/packages/ae/3a/dbeec9d1ee0844c679f6bb5d6ad4e9f198b1224f4e7a32825f47f6192b0c/cffi-2.0.0-cp314-cp314t-win_arm64.whl", hash = "sha256:0a1527a803f0a659de1af2e1fd700213caba79377e27e4693648c2923da066f9", size = 184195, upload-time = "2025-09-08T23:23:43.004Z" }, ] [[package]] name = "charset-normalizer" version = "3.4.4" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/13/69/33ddede1939fdd074bce5434295f38fae7136463422fe4fd3e0e89b98062/charset_normalizer-3.4.4.tar.gz", hash = "sha256:94537985111c35f28720e43603b8e7b43a6ecfb2ce1d3058bbe955b73404e21a", size = 129418 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/97/45/4b3a1239bbacd321068ea6e7ac28875b03ab8bc0aa0966452db17cd36714/charset_normalizer-3.4.4-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:e1f185f86a6f3403aa2420e815904c67b2f9ebc443f045edd0de921108345794", size = 208091 }, - { url = "https://files.pythonhosted.org/packages/7d/62/73a6d7450829655a35bb88a88fca7d736f9882a27eacdca2c6d505b57e2e/charset_normalizer-3.4.4-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6b39f987ae8ccdf0d2642338faf2abb1862340facc796048b604ef14919e55ed", size = 147936 }, - { url = "https://files.pythonhosted.org/packages/89/c5/adb8c8b3d6625bef6d88b251bbb0d95f8205831b987631ab0c8bb5d937c2/charset_normalizer-3.4.4-cp313-cp313-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:3162d5d8ce1bb98dd51af660f2121c55d0fa541b46dff7bb9b9f86ea1d87de72", size = 144180 }, - { url = "https://files.pythonhosted.org/packages/91/ed/9706e4070682d1cc219050b6048bfd293ccf67b3d4f5a4f39207453d4b99/charset_normalizer-3.4.4-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:81d5eb2a312700f4ecaa977a8235b634ce853200e828fbadf3a9c50bab278328", size = 161346 }, - { url = "https://files.pythonhosted.org/packages/d5/0d/031f0d95e4972901a2f6f09ef055751805ff541511dc1252ba3ca1f80cf5/charset_normalizer-3.4.4-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:5bd2293095d766545ec1a8f612559f6b40abc0eb18bb2f5d1171872d34036ede", size = 158874 }, - { url = "https://files.pythonhosted.org/packages/f5/83/6ab5883f57c9c801ce5e5677242328aa45592be8a00644310a008d04f922/charset_normalizer-3.4.4-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:a8a8b89589086a25749f471e6a900d3f662d1d3b6e2e59dcecf787b1cc3a1894", size = 153076 }, - { url = "https://files.pythonhosted.org/packages/75/1e/5ff781ddf5260e387d6419959ee89ef13878229732732ee73cdae01800f2/charset_normalizer-3.4.4-cp313-cp313-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:bc7637e2f80d8530ee4a78e878bce464f70087ce73cf7c1caf142416923b98f1", size = 150601 }, - { url = "https://files.pythonhosted.org/packages/d7/57/71be810965493d3510a6ca79b90c19e48696fb1ff964da319334b12677f0/charset_normalizer-3.4.4-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:f8bf04158c6b607d747e93949aa60618b61312fe647a6369f88ce2ff16043490", size = 150376 }, - { url = "https://files.pythonhosted.org/packages/e5/d5/c3d057a78c181d007014feb7e9f2e65905a6c4ef182c0ddf0de2924edd65/charset_normalizer-3.4.4-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:554af85e960429cf30784dd47447d5125aaa3b99a6f0683589dbd27e2f45da44", size = 144825 }, - { url = "https://files.pythonhosted.org/packages/e6/8c/d0406294828d4976f275ffbe66f00266c4b3136b7506941d87c00cab5272/charset_normalizer-3.4.4-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:74018750915ee7ad843a774364e13a3db91682f26142baddf775342c3f5b1133", size = 162583 }, - { url = "https://files.pythonhosted.org/packages/d7/24/e2aa1f18c8f15c4c0e932d9287b8609dd30ad56dbe41d926bd846e22fb8d/charset_normalizer-3.4.4-cp313-cp313-musllinux_1_2_riscv64.whl", hash = "sha256:c0463276121fdee9c49b98908b3a89c39be45d86d1dbaa22957e38f6321d4ce3", size = 150366 }, - { url = "https://files.pythonhosted.org/packages/e4/5b/1e6160c7739aad1e2df054300cc618b06bf784a7a164b0f238360721ab86/charset_normalizer-3.4.4-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:362d61fd13843997c1c446760ef36f240cf81d3ebf74ac62652aebaf7838561e", size = 160300 }, - { url = "https://files.pythonhosted.org/packages/7a/10/f882167cd207fbdd743e55534d5d9620e095089d176d55cb22d5322f2afd/charset_normalizer-3.4.4-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:9a26f18905b8dd5d685d6d07b0cdf98a79f3c7a918906af7cc143ea2e164c8bc", size = 154465 }, - { url = "https://files.pythonhosted.org/packages/89/66/c7a9e1b7429be72123441bfdbaf2bc13faab3f90b933f664db506dea5915/charset_normalizer-3.4.4-cp313-cp313-win32.whl", hash = "sha256:9b35f4c90079ff2e2edc5b26c0c77925e5d2d255c42c74fdb70fb49b172726ac", size = 99404 }, - { url = "https://files.pythonhosted.org/packages/c4/26/b9924fa27db384bdcd97ab83b4f0a8058d96ad9626ead570674d5e737d90/charset_normalizer-3.4.4-cp313-cp313-win_amd64.whl", hash = "sha256:b435cba5f4f750aa6c0a0d92c541fb79f69a387c91e61f1795227e4ed9cece14", size = 107092 }, - { url = "https://files.pythonhosted.org/packages/af/8f/3ed4bfa0c0c72a7ca17f0380cd9e4dd842b09f664e780c13cff1dcf2ef1b/charset_normalizer-3.4.4-cp313-cp313-win_arm64.whl", hash = "sha256:542d2cee80be6f80247095cc36c418f7bddd14f4a6de45af91dfad36d817bba2", size = 100408 }, - { url = "https://files.pythonhosted.org/packages/2a/35/7051599bd493e62411d6ede36fd5af83a38f37c4767b92884df7301db25d/charset_normalizer-3.4.4-cp314-cp314-macosx_10_13_universal2.whl", hash = "sha256:da3326d9e65ef63a817ecbcc0df6e94463713b754fe293eaa03da99befb9a5bd", size = 207746 }, - { url = "https://files.pythonhosted.org/packages/10/9a/97c8d48ef10d6cd4fcead2415523221624bf58bcf68a802721a6bc807c8f/charset_normalizer-3.4.4-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:8af65f14dc14a79b924524b1e7fffe304517b2bff5a58bf64f30b98bbc5079eb", size = 147889 }, - { url = "https://files.pythonhosted.org/packages/10/bf/979224a919a1b606c82bd2c5fa49b5c6d5727aa47b4312bb27b1734f53cd/charset_normalizer-3.4.4-cp314-cp314-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:74664978bb272435107de04e36db5a9735e78232b85b77d45cfb38f758efd33e", size = 143641 }, - { url = "https://files.pythonhosted.org/packages/ba/33/0ad65587441fc730dc7bd90e9716b30b4702dc7b617e6ba4997dc8651495/charset_normalizer-3.4.4-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:752944c7ffbfdd10c074dc58ec2d5a8a4cd9493b314d367c14d24c17684ddd14", size = 160779 }, - { url = "https://files.pythonhosted.org/packages/67/ed/331d6b249259ee71ddea93f6f2f0a56cfebd46938bde6fcc6f7b9a3d0e09/charset_normalizer-3.4.4-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:d1f13550535ad8cff21b8d757a3257963e951d96e20ec82ab44bc64aeb62a191", size = 159035 }, - { url = "https://files.pythonhosted.org/packages/67/ff/f6b948ca32e4f2a4576aa129d8bed61f2e0543bf9f5f2b7fc3758ed005c9/charset_normalizer-3.4.4-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:ecaae4149d99b1c9e7b88bb03e3221956f68fd6d50be2ef061b2381b61d20838", size = 152542 }, - { url = "https://files.pythonhosted.org/packages/16/85/276033dcbcc369eb176594de22728541a925b2632f9716428c851b149e83/charset_normalizer-3.4.4-cp314-cp314-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:cb6254dc36b47a990e59e1068afacdcd02958bdcce30bb50cc1700a8b9d624a6", size = 149524 }, - { url = "https://files.pythonhosted.org/packages/9e/f2/6a2a1f722b6aba37050e626530a46a68f74e63683947a8acff92569f979a/charset_normalizer-3.4.4-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:c8ae8a0f02f57a6e61203a31428fa1d677cbe50c93622b4149d5c0f319c1d19e", size = 150395 }, - { url = "https://files.pythonhosted.org/packages/60/bb/2186cb2f2bbaea6338cad15ce23a67f9b0672929744381e28b0592676824/charset_normalizer-3.4.4-cp314-cp314-musllinux_1_2_armv7l.whl", hash = "sha256:47cc91b2f4dd2833fddaedd2893006b0106129d4b94fdb6af1f4ce5a9965577c", size = 143680 }, - { url = "https://files.pythonhosted.org/packages/7d/a5/bf6f13b772fbb2a90360eb620d52ed8f796f3c5caee8398c3b2eb7b1c60d/charset_normalizer-3.4.4-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:82004af6c302b5d3ab2cfc4cc5f29db16123b1a8417f2e25f9066f91d4411090", size = 162045 }, - { url = "https://files.pythonhosted.org/packages/df/c5/d1be898bf0dc3ef9030c3825e5d3b83f2c528d207d246cbabe245966808d/charset_normalizer-3.4.4-cp314-cp314-musllinux_1_2_riscv64.whl", hash = "sha256:2b7d8f6c26245217bd2ad053761201e9f9680f8ce52f0fcd8d0755aeae5b2152", size = 149687 }, - { url = "https://files.pythonhosted.org/packages/a5/42/90c1f7b9341eef50c8a1cb3f098ac43b0508413f33affd762855f67a410e/charset_normalizer-3.4.4-cp314-cp314-musllinux_1_2_s390x.whl", hash = "sha256:799a7a5e4fb2d5898c60b640fd4981d6a25f1c11790935a44ce38c54e985f828", size = 160014 }, - { url = "https://files.pythonhosted.org/packages/76/be/4d3ee471e8145d12795ab655ece37baed0929462a86e72372fd25859047c/charset_normalizer-3.4.4-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:99ae2cffebb06e6c22bdc25801d7b30f503cc87dbd283479e7b606f70aff57ec", size = 154044 }, - { url = "https://files.pythonhosted.org/packages/b0/6f/8f7af07237c34a1defe7defc565a9bc1807762f672c0fde711a4b22bf9c0/charset_normalizer-3.4.4-cp314-cp314-win32.whl", hash = "sha256:f9d332f8c2a2fcbffe1378594431458ddbef721c1769d78e2cbc06280d8155f9", size = 99940 }, - { url = "https://files.pythonhosted.org/packages/4b/51/8ade005e5ca5b0d80fb4aff72a3775b325bdc3d27408c8113811a7cbe640/charset_normalizer-3.4.4-cp314-cp314-win_amd64.whl", hash = "sha256:8a6562c3700cce886c5be75ade4a5db4214fda19fede41d9792d100288d8f94c", size = 107104 }, - { url = "https://files.pythonhosted.org/packages/da/5f/6b8f83a55bb8278772c5ae54a577f3099025f9ade59d0136ac24a0df4bde/charset_normalizer-3.4.4-cp314-cp314-win_arm64.whl", hash = "sha256:de00632ca48df9daf77a2c65a484531649261ec9f25489917f09e455cb09ddb2", size = 100743 }, - { url = "https://files.pythonhosted.org/packages/0a/4c/925909008ed5a988ccbb72dcc897407e5d6d3bd72410d69e051fc0c14647/charset_normalizer-3.4.4-py3-none-any.whl", hash = "sha256:7a32c560861a02ff789ad905a2fe94e3f840803362c84fecf1851cb4cf3dc37f", size = 53402 }, +sdist = { url = "https://files.pythonhosted.org/packages/13/69/33ddede1939fdd074bce5434295f38fae7136463422fe4fd3e0e89b98062/charset_normalizer-3.4.4.tar.gz", hash = "sha256:94537985111c35f28720e43603b8e7b43a6ecfb2ce1d3058bbe955b73404e21a", size = 129418, upload-time = "2025-10-14T04:42:32.879Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/97/45/4b3a1239bbacd321068ea6e7ac28875b03ab8bc0aa0966452db17cd36714/charset_normalizer-3.4.4-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:e1f185f86a6f3403aa2420e815904c67b2f9ebc443f045edd0de921108345794", size = 208091, upload-time = "2025-10-14T04:41:13.346Z" }, + { url = "https://files.pythonhosted.org/packages/7d/62/73a6d7450829655a35bb88a88fca7d736f9882a27eacdca2c6d505b57e2e/charset_normalizer-3.4.4-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6b39f987ae8ccdf0d2642338faf2abb1862340facc796048b604ef14919e55ed", size = 147936, upload-time = "2025-10-14T04:41:14.461Z" }, + { url = "https://files.pythonhosted.org/packages/89/c5/adb8c8b3d6625bef6d88b251bbb0d95f8205831b987631ab0c8bb5d937c2/charset_normalizer-3.4.4-cp313-cp313-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:3162d5d8ce1bb98dd51af660f2121c55d0fa541b46dff7bb9b9f86ea1d87de72", size = 144180, upload-time = "2025-10-14T04:41:15.588Z" }, + { url = "https://files.pythonhosted.org/packages/91/ed/9706e4070682d1cc219050b6048bfd293ccf67b3d4f5a4f39207453d4b99/charset_normalizer-3.4.4-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:81d5eb2a312700f4ecaa977a8235b634ce853200e828fbadf3a9c50bab278328", size = 161346, upload-time = "2025-10-14T04:41:16.738Z" }, + { url = "https://files.pythonhosted.org/packages/d5/0d/031f0d95e4972901a2f6f09ef055751805ff541511dc1252ba3ca1f80cf5/charset_normalizer-3.4.4-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:5bd2293095d766545ec1a8f612559f6b40abc0eb18bb2f5d1171872d34036ede", size = 158874, upload-time = "2025-10-14T04:41:17.923Z" }, + { url = "https://files.pythonhosted.org/packages/f5/83/6ab5883f57c9c801ce5e5677242328aa45592be8a00644310a008d04f922/charset_normalizer-3.4.4-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:a8a8b89589086a25749f471e6a900d3f662d1d3b6e2e59dcecf787b1cc3a1894", size = 153076, upload-time = "2025-10-14T04:41:19.106Z" }, + { url = "https://files.pythonhosted.org/packages/75/1e/5ff781ddf5260e387d6419959ee89ef13878229732732ee73cdae01800f2/charset_normalizer-3.4.4-cp313-cp313-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:bc7637e2f80d8530ee4a78e878bce464f70087ce73cf7c1caf142416923b98f1", size = 150601, upload-time = "2025-10-14T04:41:20.245Z" }, + { url = "https://files.pythonhosted.org/packages/d7/57/71be810965493d3510a6ca79b90c19e48696fb1ff964da319334b12677f0/charset_normalizer-3.4.4-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:f8bf04158c6b607d747e93949aa60618b61312fe647a6369f88ce2ff16043490", size = 150376, upload-time = "2025-10-14T04:41:21.398Z" }, + { url = "https://files.pythonhosted.org/packages/e5/d5/c3d057a78c181d007014feb7e9f2e65905a6c4ef182c0ddf0de2924edd65/charset_normalizer-3.4.4-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:554af85e960429cf30784dd47447d5125aaa3b99a6f0683589dbd27e2f45da44", size = 144825, upload-time = "2025-10-14T04:41:22.583Z" }, + { url = "https://files.pythonhosted.org/packages/e6/8c/d0406294828d4976f275ffbe66f00266c4b3136b7506941d87c00cab5272/charset_normalizer-3.4.4-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:74018750915ee7ad843a774364e13a3db91682f26142baddf775342c3f5b1133", size = 162583, upload-time = "2025-10-14T04:41:23.754Z" }, + { url = "https://files.pythonhosted.org/packages/d7/24/e2aa1f18c8f15c4c0e932d9287b8609dd30ad56dbe41d926bd846e22fb8d/charset_normalizer-3.4.4-cp313-cp313-musllinux_1_2_riscv64.whl", hash = "sha256:c0463276121fdee9c49b98908b3a89c39be45d86d1dbaa22957e38f6321d4ce3", size = 150366, upload-time = "2025-10-14T04:41:25.27Z" }, + { url = "https://files.pythonhosted.org/packages/e4/5b/1e6160c7739aad1e2df054300cc618b06bf784a7a164b0f238360721ab86/charset_normalizer-3.4.4-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:362d61fd13843997c1c446760ef36f240cf81d3ebf74ac62652aebaf7838561e", size = 160300, upload-time = "2025-10-14T04:41:26.725Z" }, + { url = "https://files.pythonhosted.org/packages/7a/10/f882167cd207fbdd743e55534d5d9620e095089d176d55cb22d5322f2afd/charset_normalizer-3.4.4-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:9a26f18905b8dd5d685d6d07b0cdf98a79f3c7a918906af7cc143ea2e164c8bc", size = 154465, upload-time = "2025-10-14T04:41:28.322Z" }, + { url = "https://files.pythonhosted.org/packages/89/66/c7a9e1b7429be72123441bfdbaf2bc13faab3f90b933f664db506dea5915/charset_normalizer-3.4.4-cp313-cp313-win32.whl", hash = "sha256:9b35f4c90079ff2e2edc5b26c0c77925e5d2d255c42c74fdb70fb49b172726ac", size = 99404, upload-time = "2025-10-14T04:41:29.95Z" }, + { url = "https://files.pythonhosted.org/packages/c4/26/b9924fa27db384bdcd97ab83b4f0a8058d96ad9626ead570674d5e737d90/charset_normalizer-3.4.4-cp313-cp313-win_amd64.whl", hash = "sha256:b435cba5f4f750aa6c0a0d92c541fb79f69a387c91e61f1795227e4ed9cece14", size = 107092, upload-time = "2025-10-14T04:41:31.188Z" }, + { url = "https://files.pythonhosted.org/packages/af/8f/3ed4bfa0c0c72a7ca17f0380cd9e4dd842b09f664e780c13cff1dcf2ef1b/charset_normalizer-3.4.4-cp313-cp313-win_arm64.whl", hash = "sha256:542d2cee80be6f80247095cc36c418f7bddd14f4a6de45af91dfad36d817bba2", size = 100408, upload-time = "2025-10-14T04:41:32.624Z" }, + { url = "https://files.pythonhosted.org/packages/2a/35/7051599bd493e62411d6ede36fd5af83a38f37c4767b92884df7301db25d/charset_normalizer-3.4.4-cp314-cp314-macosx_10_13_universal2.whl", hash = "sha256:da3326d9e65ef63a817ecbcc0df6e94463713b754fe293eaa03da99befb9a5bd", size = 207746, upload-time = "2025-10-14T04:41:33.773Z" }, + { url = "https://files.pythonhosted.org/packages/10/9a/97c8d48ef10d6cd4fcead2415523221624bf58bcf68a802721a6bc807c8f/charset_normalizer-3.4.4-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:8af65f14dc14a79b924524b1e7fffe304517b2bff5a58bf64f30b98bbc5079eb", size = 147889, upload-time = "2025-10-14T04:41:34.897Z" }, + { url = "https://files.pythonhosted.org/packages/10/bf/979224a919a1b606c82bd2c5fa49b5c6d5727aa47b4312bb27b1734f53cd/charset_normalizer-3.4.4-cp314-cp314-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:74664978bb272435107de04e36db5a9735e78232b85b77d45cfb38f758efd33e", size = 143641, upload-time = "2025-10-14T04:41:36.116Z" }, + { url = "https://files.pythonhosted.org/packages/ba/33/0ad65587441fc730dc7bd90e9716b30b4702dc7b617e6ba4997dc8651495/charset_normalizer-3.4.4-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:752944c7ffbfdd10c074dc58ec2d5a8a4cd9493b314d367c14d24c17684ddd14", size = 160779, upload-time = "2025-10-14T04:41:37.229Z" }, + { url = "https://files.pythonhosted.org/packages/67/ed/331d6b249259ee71ddea93f6f2f0a56cfebd46938bde6fcc6f7b9a3d0e09/charset_normalizer-3.4.4-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:d1f13550535ad8cff21b8d757a3257963e951d96e20ec82ab44bc64aeb62a191", size = 159035, upload-time = "2025-10-14T04:41:38.368Z" }, + { url = "https://files.pythonhosted.org/packages/67/ff/f6b948ca32e4f2a4576aa129d8bed61f2e0543bf9f5f2b7fc3758ed005c9/charset_normalizer-3.4.4-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:ecaae4149d99b1c9e7b88bb03e3221956f68fd6d50be2ef061b2381b61d20838", size = 152542, upload-time = "2025-10-14T04:41:39.862Z" }, + { url = "https://files.pythonhosted.org/packages/16/85/276033dcbcc369eb176594de22728541a925b2632f9716428c851b149e83/charset_normalizer-3.4.4-cp314-cp314-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:cb6254dc36b47a990e59e1068afacdcd02958bdcce30bb50cc1700a8b9d624a6", size = 149524, upload-time = "2025-10-14T04:41:41.319Z" }, + { url = "https://files.pythonhosted.org/packages/9e/f2/6a2a1f722b6aba37050e626530a46a68f74e63683947a8acff92569f979a/charset_normalizer-3.4.4-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:c8ae8a0f02f57a6e61203a31428fa1d677cbe50c93622b4149d5c0f319c1d19e", size = 150395, upload-time = "2025-10-14T04:41:42.539Z" }, + { url = "https://files.pythonhosted.org/packages/60/bb/2186cb2f2bbaea6338cad15ce23a67f9b0672929744381e28b0592676824/charset_normalizer-3.4.4-cp314-cp314-musllinux_1_2_armv7l.whl", hash = "sha256:47cc91b2f4dd2833fddaedd2893006b0106129d4b94fdb6af1f4ce5a9965577c", size = 143680, upload-time = "2025-10-14T04:41:43.661Z" }, + { url = "https://files.pythonhosted.org/packages/7d/a5/bf6f13b772fbb2a90360eb620d52ed8f796f3c5caee8398c3b2eb7b1c60d/charset_normalizer-3.4.4-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:82004af6c302b5d3ab2cfc4cc5f29db16123b1a8417f2e25f9066f91d4411090", size = 162045, upload-time = "2025-10-14T04:41:44.821Z" }, + { url = "https://files.pythonhosted.org/packages/df/c5/d1be898bf0dc3ef9030c3825e5d3b83f2c528d207d246cbabe245966808d/charset_normalizer-3.4.4-cp314-cp314-musllinux_1_2_riscv64.whl", hash = "sha256:2b7d8f6c26245217bd2ad053761201e9f9680f8ce52f0fcd8d0755aeae5b2152", size = 149687, upload-time = "2025-10-14T04:41:46.442Z" }, + { url = "https://files.pythonhosted.org/packages/a5/42/90c1f7b9341eef50c8a1cb3f098ac43b0508413f33affd762855f67a410e/charset_normalizer-3.4.4-cp314-cp314-musllinux_1_2_s390x.whl", hash = "sha256:799a7a5e4fb2d5898c60b640fd4981d6a25f1c11790935a44ce38c54e985f828", size = 160014, upload-time = "2025-10-14T04:41:47.631Z" }, + { url = "https://files.pythonhosted.org/packages/76/be/4d3ee471e8145d12795ab655ece37baed0929462a86e72372fd25859047c/charset_normalizer-3.4.4-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:99ae2cffebb06e6c22bdc25801d7b30f503cc87dbd283479e7b606f70aff57ec", size = 154044, upload-time = "2025-10-14T04:41:48.81Z" }, + { url = "https://files.pythonhosted.org/packages/b0/6f/8f7af07237c34a1defe7defc565a9bc1807762f672c0fde711a4b22bf9c0/charset_normalizer-3.4.4-cp314-cp314-win32.whl", hash = "sha256:f9d332f8c2a2fcbffe1378594431458ddbef721c1769d78e2cbc06280d8155f9", size = 99940, upload-time = "2025-10-14T04:41:49.946Z" }, + { url = "https://files.pythonhosted.org/packages/4b/51/8ade005e5ca5b0d80fb4aff72a3775b325bdc3d27408c8113811a7cbe640/charset_normalizer-3.4.4-cp314-cp314-win_amd64.whl", hash = "sha256:8a6562c3700cce886c5be75ade4a5db4214fda19fede41d9792d100288d8f94c", size = 107104, upload-time = "2025-10-14T04:41:51.051Z" }, + { url = "https://files.pythonhosted.org/packages/da/5f/6b8f83a55bb8278772c5ae54a577f3099025f9ade59d0136ac24a0df4bde/charset_normalizer-3.4.4-cp314-cp314-win_arm64.whl", hash = "sha256:de00632ca48df9daf77a2c65a484531649261ec9f25489917f09e455cb09ddb2", size = 100743, upload-time = "2025-10-14T04:41:52.122Z" }, + { url = "https://files.pythonhosted.org/packages/0a/4c/925909008ed5a988ccbb72dcc897407e5d6d3bd72410d69e051fc0c14647/charset_normalizer-3.4.4-py3-none-any.whl", hash = "sha256:7a32c560861a02ff789ad905a2fe94e3f840803362c84fecf1851cb4cf3dc37f", size = 53402, upload-time = "2025-10-14T04:42:31.76Z" }, ] [[package]] @@ -368,18 +368,18 @@ source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "colorama", marker = "sys_platform == 'win32'" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/46/61/de6cd827efad202d7057d93e0fed9294b96952e188f7384832791c7b2254/click-8.3.0.tar.gz", hash = "sha256:e7b8232224eba16f4ebe410c25ced9f7875cb5f3263ffc93cc3e8da705e229c4", size = 276943 } +sdist = { url = "https://files.pythonhosted.org/packages/46/61/de6cd827efad202d7057d93e0fed9294b96952e188f7384832791c7b2254/click-8.3.0.tar.gz", hash = "sha256:e7b8232224eba16f4ebe410c25ced9f7875cb5f3263ffc93cc3e8da705e229c4", size = 276943, upload-time = "2025-09-18T17:32:23.696Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/db/d3/9dcc0f5797f070ec8edf30fbadfb200e71d9db6b84d211e3b2085a7589a0/click-8.3.0-py3-none-any.whl", hash = "sha256:9b9f285302c6e3064f4330c05f05b81945b2a39544279343e6e7c5f27a9baddc", size = 107295 }, + { url = "https://files.pythonhosted.org/packages/db/d3/9dcc0f5797f070ec8edf30fbadfb200e71d9db6b84d211e3b2085a7589a0/click-8.3.0-py3-none-any.whl", hash = "sha256:9b9f285302c6e3064f4330c05f05b81945b2a39544279343e6e7c5f27a9baddc", size = 107295, upload-time = "2025-09-18T17:32:22.42Z" }, ] [[package]] name = "colorama" version = "0.4.6" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/d8/53/6f443c9a4a8358a93a6792e2acffb9d9d5cb0a5cfd8802644b7b1c9a02e4/colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44", size = 27697 } +sdist = { url = "https://files.pythonhosted.org/packages/d8/53/6f443c9a4a8358a93a6792e2acffb9d9d5cb0a5cfd8802644b7b1c9a02e4/colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44", size = 27697, upload-time = "2022-10-25T02:36:22.414Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/d1/d6/3965ed04c63042e047cb6a3e6ed1a63a35087b6a609aa3a15ed8ac56c221/colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6", size = 25335 }, + { url = "https://files.pythonhosted.org/packages/d1/d6/3965ed04c63042e047cb6a3e6ed1a63a35087b6a609aa3a15ed8ac56c221/colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6", size = 25335, upload-time = "2022-10-25T02:36:20.889Z" }, ] [[package]] @@ -389,70 +389,70 @@ source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "humanfriendly" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/cc/c7/eed8f27100517e8c0e6b923d5f0845d0cb99763da6fdee00478f91db7325/coloredlogs-15.0.1.tar.gz", hash = "sha256:7c991aa71a4577af2f82600d8f8f3a89f936baeaf9b50a9c197da014e5bf16b0", size = 278520 } +sdist = { url = "https://files.pythonhosted.org/packages/cc/c7/eed8f27100517e8c0e6b923d5f0845d0cb99763da6fdee00478f91db7325/coloredlogs-15.0.1.tar.gz", hash = "sha256:7c991aa71a4577af2f82600d8f8f3a89f936baeaf9b50a9c197da014e5bf16b0", size = 278520, upload-time = "2021-06-11T10:22:45.202Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/a7/06/3d6badcf13db419e25b07041d9c7b4a2c331d3f4e7134445ec5df57714cd/coloredlogs-15.0.1-py2.py3-none-any.whl", hash = "sha256:612ee75c546f53e92e70049c9dbfcc18c935a2b9a53b66085ce9ef6a6e5c0934", size = 46018 }, + { url = "https://files.pythonhosted.org/packages/a7/06/3d6badcf13db419e25b07041d9c7b4a2c331d3f4e7134445ec5df57714cd/coloredlogs-15.0.1-py2.py3-none-any.whl", hash = "sha256:612ee75c546f53e92e70049c9dbfcc18c935a2b9a53b66085ce9ef6a6e5c0934", size = 46018, upload-time = "2021-06-11T10:22:42.561Z" }, ] [[package]] name = "coverage" version = "7.11.1" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/89/12/3e2d2ec71796e0913178478e693a06af6a3bc9f7f9cb899bf85a426d8370/coverage-7.11.1.tar.gz", hash = "sha256:b4b3a072559578129a9e863082a2972a2abd8975bc0e2ec57da96afcd6580a8a", size = 814037 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/f4/01/0c50c318f5e8f1a482da05d788d0ff06137803ed8fface4a1ba51e04b3ad/coverage-7.11.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:da9930594ca99d66eb6f613d7beba850db2f8dfa86810ee35ae24e4d5f2bb97d", size = 216920 }, - { url = "https://files.pythonhosted.org/packages/20/11/9f038e6c2baea968c377ab355b0d1d0a46b5f38985691bf51164e1b78c1f/coverage-7.11.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:cc47a280dc014220b0fc6e5f55082a3f51854faf08fd9635b8a4f341c46c77d3", size = 217301 }, - { url = "https://files.pythonhosted.org/packages/68/cd/9dcf93d81d0cddaa0bba90c3b4580e6f1ddf833918b816930d250cc553a4/coverage-7.11.1-cp313-cp313-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:74003324321bbf130939146886eddf92e48e616b5910215e79dea6edeb8ee7c8", size = 248277 }, - { url = "https://files.pythonhosted.org/packages/11/f5/b2c7c494046c9c783d3cac4c812fc24d6104dd36a7a598e7dd6fea3e7927/coverage-7.11.1-cp313-cp313-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:211f7996265daab60a8249af4ca6641b3080769cbedcffc42cc4841118f3a305", size = 250871 }, - { url = "https://files.pythonhosted.org/packages/a5/5a/b359649566954498aa17d7c98093182576d9e435ceb4ea917b3b48d56f86/coverage-7.11.1-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:70619d194d8fea0cb028cb6bb9c85b519c7509c1d1feef1eea635183bc8ecd27", size = 252115 }, - { url = "https://files.pythonhosted.org/packages/f3/17/3cef1ede3739622950f0737605353b797ec564e70c9d254521b10f4b03ba/coverage-7.11.1-cp313-cp313-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:e0208bb59d441cfa3321569040f8e455f9261256e0df776c5462a1e5a9b31e13", size = 248442 }, - { url = "https://files.pythonhosted.org/packages/5f/63/d5854c47ae42d9d18855329db6bc528f5b7f4f874257edb00cf8b483f9f8/coverage-7.11.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:545714d8765bda1c51f8b1c96e0b497886a054471c68211e76ef49dd1468587d", size = 250253 }, - { url = "https://files.pythonhosted.org/packages/48/e8/c7706f8a5358a59c18b489e7e19e83d6161b7c8bc60771f95920570c94a8/coverage-7.11.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:d0a2b02c1e20158dd405054bcca87f91fd5b7605626aee87150819ea616edd67", size = 248217 }, - { url = "https://files.pythonhosted.org/packages/5b/c9/a2136dfb168eb09e2f6d9d6b6c986243fdc0b3866a9376adb263d3c3378b/coverage-7.11.1-cp313-cp313-musllinux_1_2_riscv64.whl", hash = "sha256:e0f4aa986a4308a458e0fb572faa3eb3db2ea7ce294604064b25ab32b435a468", size = 248040 }, - { url = "https://files.pythonhosted.org/packages/18/9a/a63991c0608ddc6adf65e6f43124951aaf36bd79f41937b028120b8268ea/coverage-7.11.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:d51cc6687e8bbfd1e041f52baed0f979cd592242cf50bf18399a7e03afc82d88", size = 249801 }, - { url = "https://files.pythonhosted.org/packages/84/19/947acf7c0c6e90e4ec3abf474133ed36d94407d07e36eafdfd3acb59fee9/coverage-7.11.1-cp313-cp313-win32.whl", hash = "sha256:1b3067db3afe6deeca2b2c9f0ec23820d5f1bd152827acfadf24de145dfc5f66", size = 219430 }, - { url = "https://files.pythonhosted.org/packages/35/54/36fef7afb3884450c7b6d494fcabe2fab7c669d547c800ca30f41c1dc212/coverage-7.11.1-cp313-cp313-win_amd64.whl", hash = "sha256:39a4c44b0cd40e3c9d89b2b7303ebd6ab9ae8a63f9e9a8c4d65a181a0b33aebe", size = 220239 }, - { url = "https://files.pythonhosted.org/packages/d3/dc/7d38bb99e8e69200b7dd5de15507226bd90eac102dfc7cc891b9934cdc76/coverage-7.11.1-cp313-cp313-win_arm64.whl", hash = "sha256:a2e3560bf82fa8169a577e054cbbc29888699526063fee26ea59ea2627fd6e73", size = 218868 }, - { url = "https://files.pythonhosted.org/packages/36/c6/d1ff54fbd6bcad42dbcfd13b417e636ef84aae194353b1ef3361700f2525/coverage-7.11.1-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:47a4f362a10285897ab3aa7a4b37d28213a4f2626823923613d6d7a3584dd79a", size = 217615 }, - { url = "https://files.pythonhosted.org/packages/73/f9/6ed59e7cf1488d6f975e5b14ef836f5e537913523e92175135f8518a83ce/coverage-7.11.1-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:0df35fa7419ef571db9dacd50b0517bc54dbfe37eb94043b5fc3540bff276acd", size = 217960 }, - { url = "https://files.pythonhosted.org/packages/c4/74/2dab1dc2ebe16f074f80ae483b0f45faf278d102be703ac01b32cd85b6c3/coverage-7.11.1-cp313-cp313t-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:e1a2c621d341c9d56f7917e56fbb56be4f73fe0d0e8dae28352fb095060fd467", size = 259262 }, - { url = "https://files.pythonhosted.org/packages/15/49/eccfe039663e29a50a54b0c2c8d076acd174d7ac50d018ef8a5b1c37c8dc/coverage-7.11.1-cp313-cp313t-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:6c354b111be9b2234d9573d75dd30ca4e414b7659c730e477e89be4f620b3fb5", size = 261326 }, - { url = "https://files.pythonhosted.org/packages/f0/bb/2b829aa23fd5ee8318e33cc02a606eb09900921291497963adc3f06af8bb/coverage-7.11.1-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:4589bd44698728f600233fb2881014c9b8ec86637ef454c00939e779661dbe7e", size = 263758 }, - { url = "https://files.pythonhosted.org/packages/ac/03/d44c3d70e5da275caf2cad2071da6b425412fbcb1d1d5a81f1f89b45e3f1/coverage-7.11.1-cp313-cp313t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:c6956fc8754f2309131230272a7213a483a32ecbe29e2b9316d808a28f2f8ea1", size = 258444 }, - { url = "https://files.pythonhosted.org/packages/a9/c1/cf61d9f46ae088774c65dd3387a15dfbc72de90c1f6e105025e9eda19b42/coverage-7.11.1-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:63926a97ed89dc6a087369b92dcb8b9a94cead46c08b33a7f1f4818cd8b6a3c3", size = 261335 }, - { url = "https://files.pythonhosted.org/packages/95/9a/b3299bb14f11f2364d78a2b9704491b15395e757af6116694731ce4e5834/coverage-7.11.1-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:f5311ba00c53a7fb2b293fdc1f478b7286fe2a845a7ba9cda053f6e98178f0b4", size = 258951 }, - { url = "https://files.pythonhosted.org/packages/3f/a3/73cb2763e59f14ba6d8d6444b1f640a9be2242bfb59b7e50581c695db7ff/coverage-7.11.1-cp313-cp313t-musllinux_1_2_riscv64.whl", hash = "sha256:31bf5ffad84c974f9e72ac53493350f36b6fa396109159ec704210698f12860b", size = 257840 }, - { url = "https://files.pythonhosted.org/packages/85/db/482e72589a952027e238ffa3a15f192c552e0685fd0c5220ad05b5f17d56/coverage-7.11.1-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:227ee59fbc4a8c57a7383a1d7af6ca94a78ae3beee4045f38684548a8479a65b", size = 260040 }, - { url = "https://files.pythonhosted.org/packages/18/a1/b931d3ee099c2dca8e9ea56c07ae84c0f91562f7bbbcccab8c91b3474ef1/coverage-7.11.1-cp313-cp313t-win32.whl", hash = "sha256:a447d97b3ce680bb1da2e6bd822ebb71be6a1fb77ce2c2ad2fe4bd8aacec3058", size = 220102 }, - { url = "https://files.pythonhosted.org/packages/9a/53/b553b7bfa6207def4918f0cb72884c844fa4c3f1566e58fbb4f34e54cdc5/coverage-7.11.1-cp313-cp313t-win_amd64.whl", hash = "sha256:d6d11180437c67bde2248563a42b8e5bbf85c8df78fae13bf818ad17bfb15f02", size = 221166 }, - { url = "https://files.pythonhosted.org/packages/6b/45/1c1d58b3ed585598764bd2fe41fcf60ccafe15973ad621c322ba52e22d32/coverage-7.11.1-cp313-cp313t-win_arm64.whl", hash = "sha256:1e19a4c43d612760c6f7190411fb157e2d8a6dde00c91b941d43203bd3b17f6f", size = 219439 }, - { url = "https://files.pythonhosted.org/packages/d9/c2/ac2c3417eaa4de1361036ebbc7da664242b274b2e00c4b4a1cfc7b29920b/coverage-7.11.1-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:0305463c45c5f21f0396cd5028de92b1f1387e2e0756a85dd3147daa49f7a674", size = 216967 }, - { url = "https://files.pythonhosted.org/packages/5e/a3/afef455d03c468ee303f9df9a6f407e8bea64cd576fca914ff888faf52ca/coverage-7.11.1-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:fa4d468d5efa1eb6e3062be8bd5f45cbf28257a37b71b969a8c1da2652dfec77", size = 217298 }, - { url = "https://files.pythonhosted.org/packages/9d/59/6e2fb3fb58637001132dc32228b4fb5b332d75d12f1353cb00fe084ee0ba/coverage-7.11.1-cp314-cp314-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:d2b2f5fc8fe383cbf2d5c77d6c4b2632ede553bc0afd0cdc910fa5390046c290", size = 248337 }, - { url = "https://files.pythonhosted.org/packages/1d/5e/ce442bab963e3388658da8bde6ddbd0a15beda230afafaa25e3c487dc391/coverage-7.11.1-cp314-cp314-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:bde6488c1ad509f4fb1a4f9960fd003d5a94adef61e226246f9699befbab3276", size = 250853 }, - { url = "https://files.pythonhosted.org/packages/d1/2f/43f94557924ca9b64e09f1c3876da4eec44a05a41e27b8a639d899716c0e/coverage-7.11.1-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:a69e0d6fa0b920fe6706a898c52955ec5bcfa7e45868215159f45fd87ea6da7c", size = 252190 }, - { url = "https://files.pythonhosted.org/packages/8c/fa/a04e769b92bc5628d4bd909dcc3c8219efe5e49f462e29adc43e198ecfde/coverage-7.11.1-cp314-cp314-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:976e51e4a549b80e4639eda3a53e95013a14ff6ad69bb58ed604d34deb0e774c", size = 248335 }, - { url = "https://files.pythonhosted.org/packages/99/d0/b98ab5d2abe425c71117a7c690ead697a0b32b83256bf0f566c726b7f77b/coverage-7.11.1-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:d61fcc4d384c82971a3d9cf00d0872881f9ded19404c714d6079b7a4547e2955", size = 250209 }, - { url = "https://files.pythonhosted.org/packages/9c/3f/b9c4fbd2e6d1b64098f99fb68df7f7c1b3e0a0968d24025adb24f359cdec/coverage-7.11.1-cp314-cp314-musllinux_1_2_i686.whl", hash = "sha256:284c5df762b533fae3ebd764e3b81c20c1c9648d93ef34469759cb4e3dfe13d0", size = 248163 }, - { url = "https://files.pythonhosted.org/packages/08/fc/3e4d54fb6368b0628019eefd897fc271badbd025410fd5421a65fb58758f/coverage-7.11.1-cp314-cp314-musllinux_1_2_riscv64.whl", hash = "sha256:bab32cb1d4ad2ac6dcc4e17eee5fa136c2a1d14ae914e4bce6c8b78273aece3c", size = 247983 }, - { url = "https://files.pythonhosted.org/packages/b9/4a/a5700764a12e932b35afdddb2f59adbca289c1689455d06437f609f3ef35/coverage-7.11.1-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:36f2fed9ce392ca450fb4e283900d0b41f05c8c5db674d200f471498be3ce747", size = 249646 }, - { url = "https://files.pythonhosted.org/packages/0e/2c/45ed33d9e80a1cc9b44b4bd535d44c154d3204671c65abd90ec1e99522a2/coverage-7.11.1-cp314-cp314-win32.whl", hash = "sha256:853136cecb92a5ba1cc8f61ec6ffa62ca3c88b4b386a6c835f8b833924f9a8c5", size = 219700 }, - { url = "https://files.pythonhosted.org/packages/90/d7/5845597360f6434af1290118ebe114642865f45ce47e7e822d9c07b371be/coverage-7.11.1-cp314-cp314-win_amd64.whl", hash = "sha256:77443d39143e20927259a61da0c95d55ffc31cf43086b8f0f11a92da5260d592", size = 220516 }, - { url = "https://files.pythonhosted.org/packages/ae/d0/d311a06f9cf7a48a98ffcfd0c57db0dcab6da46e75c439286a50dc648161/coverage-7.11.1-cp314-cp314-win_arm64.whl", hash = "sha256:829acb88fa47591a64bf5197e96a931ce9d4b3634c7f81a224ba3319623cdf6c", size = 219091 }, - { url = "https://files.pythonhosted.org/packages/a7/3d/c6a84da4fa9b840933045b19dd19d17b892f3f2dd1612903260291416dba/coverage-7.11.1-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:2ad1fe321d9522ea14399de83e75a11fb6a8887930c3679feb383301c28070d9", size = 217700 }, - { url = "https://files.pythonhosted.org/packages/94/10/a4fc5022017dd7ac682dc423849c241dfbdad31734b8f96060d84e70b587/coverage-7.11.1-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:f69c332f0c3d1357c74decc9b1843fcd428cf9221bf196a20ad22aa1db3e1b6c", size = 217968 }, - { url = "https://files.pythonhosted.org/packages/59/2d/a554cd98924d296de5816413280ac3b09e42a05fb248d66f8d474d321938/coverage-7.11.1-cp314-cp314t-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:576baeea4eebde684bf6c91c01e97171c8015765c8b2cfd4022a42b899897811", size = 259334 }, - { url = "https://files.pythonhosted.org/packages/05/98/d484cb659ec33958ca96b6f03438f56edc23b239d1ad0417b7a97fc1848a/coverage-7.11.1-cp314-cp314t-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:28ad84c694fa86084cfd3c1eab4149844b8cb95bd8e5cbfc4a647f3ee2cce2b3", size = 261445 }, - { url = "https://files.pythonhosted.org/packages/f3/fa/920cba122cc28f4557c0507f8bd7c6e527ebcc537d0309186f66464a8fd9/coverage-7.11.1-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:b1043ff958f09fc3f552c014d599f3c6b7088ba97d7bc1bd1cce8603cd75b520", size = 263858 }, - { url = "https://files.pythonhosted.org/packages/2a/a0/036397bdbee0f3bd46c2e26fdfbb1a61b2140bf9059240c37b61149047fa/coverage-7.11.1-cp314-cp314t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:c6681add5060c2742dafcf29826dff1ff8eef889a3b03390daeed84361c428bd", size = 258381 }, - { url = "https://files.pythonhosted.org/packages/b6/61/2533926eb8990f182eb287f4873216c8ca530cc47241144aabf46fe80abe/coverage-7.11.1-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:773419b225ec9a75caa1e941dd0c83a91b92c2b525269e44e6ee3e4c630607db", size = 261321 }, - { url = "https://files.pythonhosted.org/packages/32/6e/618f7e203a998e4f6b8a0fa395744a416ad2adbcdc3735bc19466456718a/coverage-7.11.1-cp314-cp314t-musllinux_1_2_i686.whl", hash = "sha256:a9cb272a0e0157dbb9b2fd0b201b759bd378a1a6138a16536c025c2ce4f7643b", size = 258933 }, - { url = "https://files.pythonhosted.org/packages/22/40/6b1c27f772cb08a14a338647ead1254a57ee9dabbb4cacbc15df7f278741/coverage-7.11.1-cp314-cp314t-musllinux_1_2_riscv64.whl", hash = "sha256:e09adb2a7811dc75998eef68f47599cf699e2b62eed09c9fefaeb290b3920f34", size = 257756 }, - { url = "https://files.pythonhosted.org/packages/73/07/f9cd12f71307a785ea15b009c8d8cc2543e4a867bd04b8673843970b6b43/coverage-7.11.1-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:1335fa8c2a2fea49924d97e1e3500cfe8d7c849f5369f26bb7559ad4259ccfab", size = 260086 }, - { url = "https://files.pythonhosted.org/packages/34/02/31c5394f6f5d72a466966bcfdb61ce5a19862d452816d6ffcbb44add16ee/coverage-7.11.1-cp314-cp314t-win32.whl", hash = "sha256:4782d71d2a4fa7cef95e853b7097c8bbead4dbd0e6f9c7152a6b11a194b794db", size = 220483 }, - { url = "https://files.pythonhosted.org/packages/7f/96/81e1ef5fbfd5090113a96e823dbe055e4c58d96ca73b1fb0ad9d26f9ec36/coverage-7.11.1-cp314-cp314t-win_amd64.whl", hash = "sha256:939f45e66eceb63c75e8eb8fc58bb7077c00f1a41b0e15c6ef02334a933cfe93", size = 221592 }, - { url = "https://files.pythonhosted.org/packages/38/7a/a5d050de44951ac453a2046a0f3fb5471a4a557f0c914d00db27d543d94c/coverage-7.11.1-cp314-cp314t-win_arm64.whl", hash = "sha256:01c575bdbef35e3f023b50a146e9a75c53816e4f2569109458155cd2315f87d9", size = 219627 }, - { url = "https://files.pythonhosted.org/packages/76/32/bd9f48c28e23b2f08946f8e83983617b00619f5538dbd7e1045fa7e88c00/coverage-7.11.1-py3-none-any.whl", hash = "sha256:0fa848acb5f1da24765cee840e1afe9232ac98a8f9431c6112c15b34e880b9e8", size = 208689 }, +sdist = { url = "https://files.pythonhosted.org/packages/89/12/3e2d2ec71796e0913178478e693a06af6a3bc9f7f9cb899bf85a426d8370/coverage-7.11.1.tar.gz", hash = "sha256:b4b3a072559578129a9e863082a2972a2abd8975bc0e2ec57da96afcd6580a8a", size = 814037, upload-time = "2025-11-07T10:52:41.067Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/f4/01/0c50c318f5e8f1a482da05d788d0ff06137803ed8fface4a1ba51e04b3ad/coverage-7.11.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:da9930594ca99d66eb6f613d7beba850db2f8dfa86810ee35ae24e4d5f2bb97d", size = 216920, upload-time = "2025-11-07T10:50:55.992Z" }, + { url = "https://files.pythonhosted.org/packages/20/11/9f038e6c2baea968c377ab355b0d1d0a46b5f38985691bf51164e1b78c1f/coverage-7.11.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:cc47a280dc014220b0fc6e5f55082a3f51854faf08fd9635b8a4f341c46c77d3", size = 217301, upload-time = "2025-11-07T10:50:57.609Z" }, + { url = "https://files.pythonhosted.org/packages/68/cd/9dcf93d81d0cddaa0bba90c3b4580e6f1ddf833918b816930d250cc553a4/coverage-7.11.1-cp313-cp313-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:74003324321bbf130939146886eddf92e48e616b5910215e79dea6edeb8ee7c8", size = 248277, upload-time = "2025-11-07T10:50:59.442Z" }, + { url = "https://files.pythonhosted.org/packages/11/f5/b2c7c494046c9c783d3cac4c812fc24d6104dd36a7a598e7dd6fea3e7927/coverage-7.11.1-cp313-cp313-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:211f7996265daab60a8249af4ca6641b3080769cbedcffc42cc4841118f3a305", size = 250871, upload-time = "2025-11-07T10:51:01.094Z" }, + { url = "https://files.pythonhosted.org/packages/a5/5a/b359649566954498aa17d7c98093182576d9e435ceb4ea917b3b48d56f86/coverage-7.11.1-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:70619d194d8fea0cb028cb6bb9c85b519c7509c1d1feef1eea635183bc8ecd27", size = 252115, upload-time = "2025-11-07T10:51:03.087Z" }, + { url = "https://files.pythonhosted.org/packages/f3/17/3cef1ede3739622950f0737605353b797ec564e70c9d254521b10f4b03ba/coverage-7.11.1-cp313-cp313-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:e0208bb59d441cfa3321569040f8e455f9261256e0df776c5462a1e5a9b31e13", size = 248442, upload-time = "2025-11-07T10:51:04.888Z" }, + { url = "https://files.pythonhosted.org/packages/5f/63/d5854c47ae42d9d18855329db6bc528f5b7f4f874257edb00cf8b483f9f8/coverage-7.11.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:545714d8765bda1c51f8b1c96e0b497886a054471c68211e76ef49dd1468587d", size = 250253, upload-time = "2025-11-07T10:51:06.515Z" }, + { url = "https://files.pythonhosted.org/packages/48/e8/c7706f8a5358a59c18b489e7e19e83d6161b7c8bc60771f95920570c94a8/coverage-7.11.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:d0a2b02c1e20158dd405054bcca87f91fd5b7605626aee87150819ea616edd67", size = 248217, upload-time = "2025-11-07T10:51:08.405Z" }, + { url = "https://files.pythonhosted.org/packages/5b/c9/a2136dfb168eb09e2f6d9d6b6c986243fdc0b3866a9376adb263d3c3378b/coverage-7.11.1-cp313-cp313-musllinux_1_2_riscv64.whl", hash = "sha256:e0f4aa986a4308a458e0fb572faa3eb3db2ea7ce294604064b25ab32b435a468", size = 248040, upload-time = "2025-11-07T10:51:10.626Z" }, + { url = "https://files.pythonhosted.org/packages/18/9a/a63991c0608ddc6adf65e6f43124951aaf36bd79f41937b028120b8268ea/coverage-7.11.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:d51cc6687e8bbfd1e041f52baed0f979cd592242cf50bf18399a7e03afc82d88", size = 249801, upload-time = "2025-11-07T10:51:12.63Z" }, + { url = "https://files.pythonhosted.org/packages/84/19/947acf7c0c6e90e4ec3abf474133ed36d94407d07e36eafdfd3acb59fee9/coverage-7.11.1-cp313-cp313-win32.whl", hash = "sha256:1b3067db3afe6deeca2b2c9f0ec23820d5f1bd152827acfadf24de145dfc5f66", size = 219430, upload-time = "2025-11-07T10:51:14.329Z" }, + { url = "https://files.pythonhosted.org/packages/35/54/36fef7afb3884450c7b6d494fcabe2fab7c669d547c800ca30f41c1dc212/coverage-7.11.1-cp313-cp313-win_amd64.whl", hash = "sha256:39a4c44b0cd40e3c9d89b2b7303ebd6ab9ae8a63f9e9a8c4d65a181a0b33aebe", size = 220239, upload-time = "2025-11-07T10:51:16.418Z" }, + { url = "https://files.pythonhosted.org/packages/d3/dc/7d38bb99e8e69200b7dd5de15507226bd90eac102dfc7cc891b9934cdc76/coverage-7.11.1-cp313-cp313-win_arm64.whl", hash = "sha256:a2e3560bf82fa8169a577e054cbbc29888699526063fee26ea59ea2627fd6e73", size = 218868, upload-time = "2025-11-07T10:51:18.186Z" }, + { url = "https://files.pythonhosted.org/packages/36/c6/d1ff54fbd6bcad42dbcfd13b417e636ef84aae194353b1ef3361700f2525/coverage-7.11.1-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:47a4f362a10285897ab3aa7a4b37d28213a4f2626823923613d6d7a3584dd79a", size = 217615, upload-time = "2025-11-07T10:51:21.065Z" }, + { url = "https://files.pythonhosted.org/packages/73/f9/6ed59e7cf1488d6f975e5b14ef836f5e537913523e92175135f8518a83ce/coverage-7.11.1-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:0df35fa7419ef571db9dacd50b0517bc54dbfe37eb94043b5fc3540bff276acd", size = 217960, upload-time = "2025-11-07T10:51:22.797Z" }, + { url = "https://files.pythonhosted.org/packages/c4/74/2dab1dc2ebe16f074f80ae483b0f45faf278d102be703ac01b32cd85b6c3/coverage-7.11.1-cp313-cp313t-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:e1a2c621d341c9d56f7917e56fbb56be4f73fe0d0e8dae28352fb095060fd467", size = 259262, upload-time = "2025-11-07T10:51:24.467Z" }, + { url = "https://files.pythonhosted.org/packages/15/49/eccfe039663e29a50a54b0c2c8d076acd174d7ac50d018ef8a5b1c37c8dc/coverage-7.11.1-cp313-cp313t-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:6c354b111be9b2234d9573d75dd30ca4e414b7659c730e477e89be4f620b3fb5", size = 261326, upload-time = "2025-11-07T10:51:26.232Z" }, + { url = "https://files.pythonhosted.org/packages/f0/bb/2b829aa23fd5ee8318e33cc02a606eb09900921291497963adc3f06af8bb/coverage-7.11.1-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:4589bd44698728f600233fb2881014c9b8ec86637ef454c00939e779661dbe7e", size = 263758, upload-time = "2025-11-07T10:51:27.912Z" }, + { url = "https://files.pythonhosted.org/packages/ac/03/d44c3d70e5da275caf2cad2071da6b425412fbcb1d1d5a81f1f89b45e3f1/coverage-7.11.1-cp313-cp313t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:c6956fc8754f2309131230272a7213a483a32ecbe29e2b9316d808a28f2f8ea1", size = 258444, upload-time = "2025-11-07T10:51:30.107Z" }, + { url = "https://files.pythonhosted.org/packages/a9/c1/cf61d9f46ae088774c65dd3387a15dfbc72de90c1f6e105025e9eda19b42/coverage-7.11.1-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:63926a97ed89dc6a087369b92dcb8b9a94cead46c08b33a7f1f4818cd8b6a3c3", size = 261335, upload-time = "2025-11-07T10:51:31.814Z" }, + { url = "https://files.pythonhosted.org/packages/95/9a/b3299bb14f11f2364d78a2b9704491b15395e757af6116694731ce4e5834/coverage-7.11.1-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:f5311ba00c53a7fb2b293fdc1f478b7286fe2a845a7ba9cda053f6e98178f0b4", size = 258951, upload-time = "2025-11-07T10:51:33.925Z" }, + { url = "https://files.pythonhosted.org/packages/3f/a3/73cb2763e59f14ba6d8d6444b1f640a9be2242bfb59b7e50581c695db7ff/coverage-7.11.1-cp313-cp313t-musllinux_1_2_riscv64.whl", hash = "sha256:31bf5ffad84c974f9e72ac53493350f36b6fa396109159ec704210698f12860b", size = 257840, upload-time = "2025-11-07T10:51:36.092Z" }, + { url = "https://files.pythonhosted.org/packages/85/db/482e72589a952027e238ffa3a15f192c552e0685fd0c5220ad05b5f17d56/coverage-7.11.1-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:227ee59fbc4a8c57a7383a1d7af6ca94a78ae3beee4045f38684548a8479a65b", size = 260040, upload-time = "2025-11-07T10:51:38.277Z" }, + { url = "https://files.pythonhosted.org/packages/18/a1/b931d3ee099c2dca8e9ea56c07ae84c0f91562f7bbbcccab8c91b3474ef1/coverage-7.11.1-cp313-cp313t-win32.whl", hash = "sha256:a447d97b3ce680bb1da2e6bd822ebb71be6a1fb77ce2c2ad2fe4bd8aacec3058", size = 220102, upload-time = "2025-11-07T10:51:40.017Z" }, + { url = "https://files.pythonhosted.org/packages/9a/53/b553b7bfa6207def4918f0cb72884c844fa4c3f1566e58fbb4f34e54cdc5/coverage-7.11.1-cp313-cp313t-win_amd64.whl", hash = "sha256:d6d11180437c67bde2248563a42b8e5bbf85c8df78fae13bf818ad17bfb15f02", size = 221166, upload-time = "2025-11-07T10:51:41.921Z" }, + { url = "https://files.pythonhosted.org/packages/6b/45/1c1d58b3ed585598764bd2fe41fcf60ccafe15973ad621c322ba52e22d32/coverage-7.11.1-cp313-cp313t-win_arm64.whl", hash = "sha256:1e19a4c43d612760c6f7190411fb157e2d8a6dde00c91b941d43203bd3b17f6f", size = 219439, upload-time = "2025-11-07T10:51:43.753Z" }, + { url = "https://files.pythonhosted.org/packages/d9/c2/ac2c3417eaa4de1361036ebbc7da664242b274b2e00c4b4a1cfc7b29920b/coverage-7.11.1-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:0305463c45c5f21f0396cd5028de92b1f1387e2e0756a85dd3147daa49f7a674", size = 216967, upload-time = "2025-11-07T10:51:45.55Z" }, + { url = "https://files.pythonhosted.org/packages/5e/a3/afef455d03c468ee303f9df9a6f407e8bea64cd576fca914ff888faf52ca/coverage-7.11.1-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:fa4d468d5efa1eb6e3062be8bd5f45cbf28257a37b71b969a8c1da2652dfec77", size = 217298, upload-time = "2025-11-07T10:51:47.31Z" }, + { url = "https://files.pythonhosted.org/packages/9d/59/6e2fb3fb58637001132dc32228b4fb5b332d75d12f1353cb00fe084ee0ba/coverage-7.11.1-cp314-cp314-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:d2b2f5fc8fe383cbf2d5c77d6c4b2632ede553bc0afd0cdc910fa5390046c290", size = 248337, upload-time = "2025-11-07T10:51:49.48Z" }, + { url = "https://files.pythonhosted.org/packages/1d/5e/ce442bab963e3388658da8bde6ddbd0a15beda230afafaa25e3c487dc391/coverage-7.11.1-cp314-cp314-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:bde6488c1ad509f4fb1a4f9960fd003d5a94adef61e226246f9699befbab3276", size = 250853, upload-time = "2025-11-07T10:51:51.215Z" }, + { url = "https://files.pythonhosted.org/packages/d1/2f/43f94557924ca9b64e09f1c3876da4eec44a05a41e27b8a639d899716c0e/coverage-7.11.1-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:a69e0d6fa0b920fe6706a898c52955ec5bcfa7e45868215159f45fd87ea6da7c", size = 252190, upload-time = "2025-11-07T10:51:53.262Z" }, + { url = "https://files.pythonhosted.org/packages/8c/fa/a04e769b92bc5628d4bd909dcc3c8219efe5e49f462e29adc43e198ecfde/coverage-7.11.1-cp314-cp314-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:976e51e4a549b80e4639eda3a53e95013a14ff6ad69bb58ed604d34deb0e774c", size = 248335, upload-time = "2025-11-07T10:51:55.388Z" }, + { url = "https://files.pythonhosted.org/packages/99/d0/b98ab5d2abe425c71117a7c690ead697a0b32b83256bf0f566c726b7f77b/coverage-7.11.1-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:d61fcc4d384c82971a3d9cf00d0872881f9ded19404c714d6079b7a4547e2955", size = 250209, upload-time = "2025-11-07T10:51:57.263Z" }, + { url = "https://files.pythonhosted.org/packages/9c/3f/b9c4fbd2e6d1b64098f99fb68df7f7c1b3e0a0968d24025adb24f359cdec/coverage-7.11.1-cp314-cp314-musllinux_1_2_i686.whl", hash = "sha256:284c5df762b533fae3ebd764e3b81c20c1c9648d93ef34469759cb4e3dfe13d0", size = 248163, upload-time = "2025-11-07T10:51:59.014Z" }, + { url = "https://files.pythonhosted.org/packages/08/fc/3e4d54fb6368b0628019eefd897fc271badbd025410fd5421a65fb58758f/coverage-7.11.1-cp314-cp314-musllinux_1_2_riscv64.whl", hash = "sha256:bab32cb1d4ad2ac6dcc4e17eee5fa136c2a1d14ae914e4bce6c8b78273aece3c", size = 247983, upload-time = "2025-11-07T10:52:01.027Z" }, + { url = "https://files.pythonhosted.org/packages/b9/4a/a5700764a12e932b35afdddb2f59adbca289c1689455d06437f609f3ef35/coverage-7.11.1-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:36f2fed9ce392ca450fb4e283900d0b41f05c8c5db674d200f471498be3ce747", size = 249646, upload-time = "2025-11-07T10:52:02.856Z" }, + { url = "https://files.pythonhosted.org/packages/0e/2c/45ed33d9e80a1cc9b44b4bd535d44c154d3204671c65abd90ec1e99522a2/coverage-7.11.1-cp314-cp314-win32.whl", hash = "sha256:853136cecb92a5ba1cc8f61ec6ffa62ca3c88b4b386a6c835f8b833924f9a8c5", size = 219700, upload-time = "2025-11-07T10:52:05.05Z" }, + { url = "https://files.pythonhosted.org/packages/90/d7/5845597360f6434af1290118ebe114642865f45ce47e7e822d9c07b371be/coverage-7.11.1-cp314-cp314-win_amd64.whl", hash = "sha256:77443d39143e20927259a61da0c95d55ffc31cf43086b8f0f11a92da5260d592", size = 220516, upload-time = "2025-11-07T10:52:07.259Z" }, + { url = "https://files.pythonhosted.org/packages/ae/d0/d311a06f9cf7a48a98ffcfd0c57db0dcab6da46e75c439286a50dc648161/coverage-7.11.1-cp314-cp314-win_arm64.whl", hash = "sha256:829acb88fa47591a64bf5197e96a931ce9d4b3634c7f81a224ba3319623cdf6c", size = 219091, upload-time = "2025-11-07T10:52:09.216Z" }, + { url = "https://files.pythonhosted.org/packages/a7/3d/c6a84da4fa9b840933045b19dd19d17b892f3f2dd1612903260291416dba/coverage-7.11.1-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:2ad1fe321d9522ea14399de83e75a11fb6a8887930c3679feb383301c28070d9", size = 217700, upload-time = "2025-11-07T10:52:11.348Z" }, + { url = "https://files.pythonhosted.org/packages/94/10/a4fc5022017dd7ac682dc423849c241dfbdad31734b8f96060d84e70b587/coverage-7.11.1-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:f69c332f0c3d1357c74decc9b1843fcd428cf9221bf196a20ad22aa1db3e1b6c", size = 217968, upload-time = "2025-11-07T10:52:13.203Z" }, + { url = "https://files.pythonhosted.org/packages/59/2d/a554cd98924d296de5816413280ac3b09e42a05fb248d66f8d474d321938/coverage-7.11.1-cp314-cp314t-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:576baeea4eebde684bf6c91c01e97171c8015765c8b2cfd4022a42b899897811", size = 259334, upload-time = "2025-11-07T10:52:15.079Z" }, + { url = "https://files.pythonhosted.org/packages/05/98/d484cb659ec33958ca96b6f03438f56edc23b239d1ad0417b7a97fc1848a/coverage-7.11.1-cp314-cp314t-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:28ad84c694fa86084cfd3c1eab4149844b8cb95bd8e5cbfc4a647f3ee2cce2b3", size = 261445, upload-time = "2025-11-07T10:52:17.134Z" }, + { url = "https://files.pythonhosted.org/packages/f3/fa/920cba122cc28f4557c0507f8bd7c6e527ebcc537d0309186f66464a8fd9/coverage-7.11.1-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:b1043ff958f09fc3f552c014d599f3c6b7088ba97d7bc1bd1cce8603cd75b520", size = 263858, upload-time = "2025-11-07T10:52:19.836Z" }, + { url = "https://files.pythonhosted.org/packages/2a/a0/036397bdbee0f3bd46c2e26fdfbb1a61b2140bf9059240c37b61149047fa/coverage-7.11.1-cp314-cp314t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:c6681add5060c2742dafcf29826dff1ff8eef889a3b03390daeed84361c428bd", size = 258381, upload-time = "2025-11-07T10:52:21.687Z" }, + { url = "https://files.pythonhosted.org/packages/b6/61/2533926eb8990f182eb287f4873216c8ca530cc47241144aabf46fe80abe/coverage-7.11.1-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:773419b225ec9a75caa1e941dd0c83a91b92c2b525269e44e6ee3e4c630607db", size = 261321, upload-time = "2025-11-07T10:52:23.612Z" }, + { url = "https://files.pythonhosted.org/packages/32/6e/618f7e203a998e4f6b8a0fa395744a416ad2adbcdc3735bc19466456718a/coverage-7.11.1-cp314-cp314t-musllinux_1_2_i686.whl", hash = "sha256:a9cb272a0e0157dbb9b2fd0b201b759bd378a1a6138a16536c025c2ce4f7643b", size = 258933, upload-time = "2025-11-07T10:52:25.514Z" }, + { url = "https://files.pythonhosted.org/packages/22/40/6b1c27f772cb08a14a338647ead1254a57ee9dabbb4cacbc15df7f278741/coverage-7.11.1-cp314-cp314t-musllinux_1_2_riscv64.whl", hash = "sha256:e09adb2a7811dc75998eef68f47599cf699e2b62eed09c9fefaeb290b3920f34", size = 257756, upload-time = "2025-11-07T10:52:27.845Z" }, + { url = "https://files.pythonhosted.org/packages/73/07/f9cd12f71307a785ea15b009c8d8cc2543e4a867bd04b8673843970b6b43/coverage-7.11.1-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:1335fa8c2a2fea49924d97e1e3500cfe8d7c849f5369f26bb7559ad4259ccfab", size = 260086, upload-time = "2025-11-07T10:52:29.776Z" }, + { url = "https://files.pythonhosted.org/packages/34/02/31c5394f6f5d72a466966bcfdb61ce5a19862d452816d6ffcbb44add16ee/coverage-7.11.1-cp314-cp314t-win32.whl", hash = "sha256:4782d71d2a4fa7cef95e853b7097c8bbead4dbd0e6f9c7152a6b11a194b794db", size = 220483, upload-time = "2025-11-07T10:52:31.752Z" }, + { url = "https://files.pythonhosted.org/packages/7f/96/81e1ef5fbfd5090113a96e823dbe055e4c58d96ca73b1fb0ad9d26f9ec36/coverage-7.11.1-cp314-cp314t-win_amd64.whl", hash = "sha256:939f45e66eceb63c75e8eb8fc58bb7077c00f1a41b0e15c6ef02334a933cfe93", size = 221592, upload-time = "2025-11-07T10:52:33.724Z" }, + { url = "https://files.pythonhosted.org/packages/38/7a/a5d050de44951ac453a2046a0f3fb5471a4a557f0c914d00db27d543d94c/coverage-7.11.1-cp314-cp314t-win_arm64.whl", hash = "sha256:01c575bdbef35e3f023b50a146e9a75c53816e4f2569109458155cd2315f87d9", size = 219627, upload-time = "2025-11-07T10:52:36.285Z" }, + { url = "https://files.pythonhosted.org/packages/76/32/bd9f48c28e23b2f08946f8e83983617b00619f5538dbd7e1045fa7e88c00/coverage-7.11.1-py3-none-any.whl", hash = "sha256:0fa848acb5f1da24765cee840e1afe9232ac98a8f9431c6112c15b34e880b9e8", size = 208689, upload-time = "2025-11-07T10:52:38.646Z" }, ] [[package]] @@ -462,77 +462,77 @@ source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "cffi", marker = "platform_python_implementation != 'PyPy'" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/9f/33/c00162f49c0e2fe8064a62cb92b93e50c74a72bc370ab92f86112b33ff62/cryptography-46.0.3.tar.gz", hash = "sha256:a8b17438104fed022ce745b362294d9ce35b4c2e45c1d958ad4a4b019285f4a1", size = 749258 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/1d/42/9c391dd801d6cf0d561b5890549d4b27bafcc53b39c31a817e69d87c625b/cryptography-46.0.3-cp311-abi3-macosx_10_9_universal2.whl", hash = "sha256:109d4ddfadf17e8e7779c39f9b18111a09efb969a301a31e987416a0191ed93a", size = 7225004 }, - { url = "https://files.pythonhosted.org/packages/1c/67/38769ca6b65f07461eb200e85fc1639b438bdc667be02cf7f2cd6a64601c/cryptography-46.0.3-cp311-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:09859af8466b69bc3c27bdf4f5d84a665e0f7ab5088412e9e2ec49758eca5cbc", size = 4296667 }, - { url = "https://files.pythonhosted.org/packages/5c/49/498c86566a1d80e978b42f0d702795f69887005548c041636df6ae1ca64c/cryptography-46.0.3-cp311-abi3-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:01ca9ff2885f3acc98c29f1860552e37f6d7c7d013d7334ff2a9de43a449315d", size = 4450807 }, - { url = "https://files.pythonhosted.org/packages/4b/0a/863a3604112174c8624a2ac3c038662d9e59970c7f926acdcfaed8d61142/cryptography-46.0.3-cp311-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:6eae65d4c3d33da080cff9c4ab1f711b15c1d9760809dad6ea763f3812d254cb", size = 4299615 }, - { url = "https://files.pythonhosted.org/packages/64/02/b73a533f6b64a69f3cd3872acb6ebc12aef924d8d103133bb3ea750dc703/cryptography-46.0.3-cp311-abi3-manylinux_2_28_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:e5bf0ed4490068a2e72ac03d786693adeb909981cc596425d09032d372bcc849", size = 4016800 }, - { url = "https://files.pythonhosted.org/packages/25/d5/16e41afbfa450cde85a3b7ec599bebefaef16b5c6ba4ec49a3532336ed72/cryptography-46.0.3-cp311-abi3-manylinux_2_28_ppc64le.whl", hash = "sha256:5ecfccd2329e37e9b7112a888e76d9feca2347f12f37918facbb893d7bb88ee8", size = 4984707 }, - { url = "https://files.pythonhosted.org/packages/c9/56/e7e69b427c3878352c2fb9b450bd0e19ed552753491d39d7d0a2f5226d41/cryptography-46.0.3-cp311-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:a2c0cd47381a3229c403062f764160d57d4d175e022c1df84e168c6251a22eec", size = 4482541 }, - { url = "https://files.pythonhosted.org/packages/78/f6/50736d40d97e8483172f1bb6e698895b92a223dba513b0ca6f06b2365339/cryptography-46.0.3-cp311-abi3-manylinux_2_34_aarch64.whl", hash = "sha256:549e234ff32571b1f4076ac269fcce7a808d3bf98b76c8dd560e42dbc66d7d91", size = 4299464 }, - { url = "https://files.pythonhosted.org/packages/00/de/d8e26b1a855f19d9994a19c702fa2e93b0456beccbcfe437eda00e0701f2/cryptography-46.0.3-cp311-abi3-manylinux_2_34_ppc64le.whl", hash = "sha256:c0a7bb1a68a5d3471880e264621346c48665b3bf1c3759d682fc0864c540bd9e", size = 4950838 }, - { url = "https://files.pythonhosted.org/packages/8f/29/798fc4ec461a1c9e9f735f2fc58741b0daae30688f41b2497dcbc9ed1355/cryptography-46.0.3-cp311-abi3-manylinux_2_34_x86_64.whl", hash = "sha256:10b01676fc208c3e6feeb25a8b83d81767e8059e1fe86e1dc62d10a3018fa926", size = 4481596 }, - { url = "https://files.pythonhosted.org/packages/15/8d/03cd48b20a573adfff7652b76271078e3045b9f49387920e7f1f631d125e/cryptography-46.0.3-cp311-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:0abf1ffd6e57c67e92af68330d05760b7b7efb243aab8377e583284dbab72c71", size = 4426782 }, - { url = "https://files.pythonhosted.org/packages/fa/b1/ebacbfe53317d55cf33165bda24c86523497a6881f339f9aae5c2e13e57b/cryptography-46.0.3-cp311-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:a04bee9ab6a4da801eb9b51f1b708a1b5b5c9eb48c03f74198464c66f0d344ac", size = 4698381 }, - { url = "https://files.pythonhosted.org/packages/96/92/8a6a9525893325fc057a01f654d7efc2c64b9de90413adcf605a85744ff4/cryptography-46.0.3-cp311-abi3-win32.whl", hash = "sha256:f260d0d41e9b4da1ed1e0f1ce571f97fe370b152ab18778e9e8f67d6af432018", size = 3055988 }, - { url = "https://files.pythonhosted.org/packages/7e/bf/80fbf45253ea585a1e492a6a17efcb93467701fa79e71550a430c5e60df0/cryptography-46.0.3-cp311-abi3-win_amd64.whl", hash = "sha256:a9a3008438615669153eb86b26b61e09993921ebdd75385ddd748702c5adfddb", size = 3514451 }, - { url = "https://files.pythonhosted.org/packages/2e/af/9b302da4c87b0beb9db4e756386a7c6c5b8003cd0e742277888d352ae91d/cryptography-46.0.3-cp311-abi3-win_arm64.whl", hash = "sha256:5d7f93296ee28f68447397bf5198428c9aeeab45705a55d53a6343455dcb2c3c", size = 2928007 }, - { url = "https://files.pythonhosted.org/packages/f5/e2/a510aa736755bffa9d2f75029c229111a1d02f8ecd5de03078f4c18d91a3/cryptography-46.0.3-cp314-cp314t-macosx_10_9_universal2.whl", hash = "sha256:00a5e7e87938e5ff9ff5447ab086a5706a957137e6e433841e9d24f38a065217", size = 7158012 }, - { url = "https://files.pythonhosted.org/packages/73/dc/9aa866fbdbb95b02e7f9d086f1fccfeebf8953509b87e3f28fff927ff8a0/cryptography-46.0.3-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:c8daeb2d2174beb4575b77482320303f3d39b8e81153da4f0fb08eb5fe86a6c5", size = 4288728 }, - { url = "https://files.pythonhosted.org/packages/c5/fd/bc1daf8230eaa075184cbbf5f8cd00ba9db4fd32d63fb83da4671b72ed8a/cryptography-46.0.3-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:39b6755623145ad5eff1dab323f4eae2a32a77a7abef2c5089a04a3d04366715", size = 4435078 }, - { url = "https://files.pythonhosted.org/packages/82/98/d3bd5407ce4c60017f8ff9e63ffee4200ab3e23fe05b765cab805a7db008/cryptography-46.0.3-cp314-cp314t-manylinux_2_28_aarch64.whl", hash = "sha256:db391fa7c66df6762ee3f00c95a89e6d428f4d60e7abc8328f4fe155b5ac6e54", size = 4293460 }, - { url = "https://files.pythonhosted.org/packages/26/e9/e23e7900983c2b8af7a08098db406cf989d7f09caea7897e347598d4cd5b/cryptography-46.0.3-cp314-cp314t-manylinux_2_28_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:78a97cf6a8839a48c49271cdcbd5cf37ca2c1d6b7fdd86cc864f302b5e9bf459", size = 3995237 }, - { url = "https://files.pythonhosted.org/packages/91/15/af68c509d4a138cfe299d0d7ddb14afba15233223ebd933b4bbdbc7155d3/cryptography-46.0.3-cp314-cp314t-manylinux_2_28_ppc64le.whl", hash = "sha256:dfb781ff7eaa91a6f7fd41776ec37c5853c795d3b358d4896fdbb5df168af422", size = 4967344 }, - { url = "https://files.pythonhosted.org/packages/ca/e3/8643d077c53868b681af077edf6b3cb58288b5423610f21c62aadcbe99f4/cryptography-46.0.3-cp314-cp314t-manylinux_2_28_x86_64.whl", hash = "sha256:6f61efb26e76c45c4a227835ddeae96d83624fb0d29eb5df5b96e14ed1a0afb7", size = 4466564 }, - { url = "https://files.pythonhosted.org/packages/0e/43/c1e8726fa59c236ff477ff2b5dc071e54b21e5a1e51aa2cee1676f1c986f/cryptography-46.0.3-cp314-cp314t-manylinux_2_34_aarch64.whl", hash = "sha256:23b1a8f26e43f47ceb6d6a43115f33a5a37d57df4ea0ca295b780ae8546e8044", size = 4292415 }, - { url = "https://files.pythonhosted.org/packages/42/f9/2f8fefdb1aee8a8e3256a0568cffc4e6d517b256a2fe97a029b3f1b9fe7e/cryptography-46.0.3-cp314-cp314t-manylinux_2_34_ppc64le.whl", hash = "sha256:b419ae593c86b87014b9be7396b385491ad7f320bde96826d0dd174459e54665", size = 4931457 }, - { url = "https://files.pythonhosted.org/packages/79/30/9b54127a9a778ccd6d27c3da7563e9f2d341826075ceab89ae3b41bf5be2/cryptography-46.0.3-cp314-cp314t-manylinux_2_34_x86_64.whl", hash = "sha256:50fc3343ac490c6b08c0cf0d704e881d0d660be923fd3076db3e932007e726e3", size = 4466074 }, - { url = "https://files.pythonhosted.org/packages/ac/68/b4f4a10928e26c941b1b6a179143af9f4d27d88fe84a6a3c53592d2e76bf/cryptography-46.0.3-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:22d7e97932f511d6b0b04f2bfd818d73dcd5928db509460aaf48384778eb6d20", size = 4420569 }, - { url = "https://files.pythonhosted.org/packages/a3/49/3746dab4c0d1979888f125226357d3262a6dd40e114ac29e3d2abdf1ec55/cryptography-46.0.3-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:d55f3dffadd674514ad19451161118fd010988540cee43d8bc20675e775925de", size = 4681941 }, - { url = "https://files.pythonhosted.org/packages/fd/30/27654c1dbaf7e4a3531fa1fc77986d04aefa4d6d78259a62c9dc13d7ad36/cryptography-46.0.3-cp314-cp314t-win32.whl", hash = "sha256:8a6e050cb6164d3f830453754094c086ff2d0b2f3a897a1d9820f6139a1f0914", size = 3022339 }, - { url = "https://files.pythonhosted.org/packages/f6/30/640f34ccd4d2a1bc88367b54b926b781b5a018d65f404d409aba76a84b1c/cryptography-46.0.3-cp314-cp314t-win_amd64.whl", hash = "sha256:760f83faa07f8b64e9c33fc963d790a2edb24efb479e3520c14a45741cd9b2db", size = 3494315 }, - { url = "https://files.pythonhosted.org/packages/ba/8b/88cc7e3bd0a8e7b861f26981f7b820e1f46aa9d26cc482d0feba0ecb4919/cryptography-46.0.3-cp314-cp314t-win_arm64.whl", hash = "sha256:516ea134e703e9fe26bcd1277a4b59ad30586ea90c365a87781d7887a646fe21", size = 2919331 }, - { url = "https://files.pythonhosted.org/packages/fd/23/45fe7f376a7df8daf6da3556603b36f53475a99ce4faacb6ba2cf3d82021/cryptography-46.0.3-cp38-abi3-macosx_10_9_universal2.whl", hash = "sha256:cb3d760a6117f621261d662bccc8ef5bc32ca673e037c83fbe565324f5c46936", size = 7218248 }, - { url = "https://files.pythonhosted.org/packages/27/32/b68d27471372737054cbd34c84981f9edbc24fe67ca225d389799614e27f/cryptography-46.0.3-cp38-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:4b7387121ac7d15e550f5cb4a43aef2559ed759c35df7336c402bb8275ac9683", size = 4294089 }, - { url = "https://files.pythonhosted.org/packages/26/42/fa8389d4478368743e24e61eea78846a0006caffaf72ea24a15159215a14/cryptography-46.0.3-cp38-abi3-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:15ab9b093e8f09daab0f2159bb7e47532596075139dd74365da52ecc9cb46c5d", size = 4440029 }, - { url = "https://files.pythonhosted.org/packages/5f/eb/f483db0ec5ac040824f269e93dd2bd8a21ecd1027e77ad7bdf6914f2fd80/cryptography-46.0.3-cp38-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:46acf53b40ea38f9c6c229599a4a13f0d46a6c3fa9ef19fc1a124d62e338dfa0", size = 4297222 }, - { url = "https://files.pythonhosted.org/packages/fd/cf/da9502c4e1912cb1da3807ea3618a6829bee8207456fbbeebc361ec38ba3/cryptography-46.0.3-cp38-abi3-manylinux_2_28_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:10ca84c4668d066a9878890047f03546f3ae0a6b8b39b697457b7757aaf18dbc", size = 4012280 }, - { url = "https://files.pythonhosted.org/packages/6b/8f/9adb86b93330e0df8b3dcf03eae67c33ba89958fc2e03862ef1ac2b42465/cryptography-46.0.3-cp38-abi3-manylinux_2_28_ppc64le.whl", hash = "sha256:36e627112085bb3b81b19fed209c05ce2a52ee8b15d161b7c643a7d5a88491f3", size = 4978958 }, - { url = "https://files.pythonhosted.org/packages/d1/a0/5fa77988289c34bdb9f913f5606ecc9ada1adb5ae870bd0d1054a7021cc4/cryptography-46.0.3-cp38-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:1000713389b75c449a6e979ffc7dcc8ac90b437048766cef052d4d30b8220971", size = 4473714 }, - { url = "https://files.pythonhosted.org/packages/14/e5/fc82d72a58d41c393697aa18c9abe5ae1214ff6f2a5c18ac470f92777895/cryptography-46.0.3-cp38-abi3-manylinux_2_34_aarch64.whl", hash = "sha256:b02cf04496f6576afffef5ddd04a0cb7d49cf6be16a9059d793a30b035f6b6ac", size = 4296970 }, - { url = "https://files.pythonhosted.org/packages/78/06/5663ed35438d0b09056973994f1aec467492b33bd31da36e468b01ec1097/cryptography-46.0.3-cp38-abi3-manylinux_2_34_ppc64le.whl", hash = "sha256:71e842ec9bc7abf543b47cf86b9a743baa95f4677d22baa4c7d5c69e49e9bc04", size = 4940236 }, - { url = "https://files.pythonhosted.org/packages/fc/59/873633f3f2dcd8a053b8dd1d38f783043b5fce589c0f6988bf55ef57e43e/cryptography-46.0.3-cp38-abi3-manylinux_2_34_x86_64.whl", hash = "sha256:402b58fc32614f00980b66d6e56a5b4118e6cb362ae8f3fda141ba4689bd4506", size = 4472642 }, - { url = "https://files.pythonhosted.org/packages/3d/39/8e71f3930e40f6877737d6f69248cf74d4e34b886a3967d32f919cc50d3b/cryptography-46.0.3-cp38-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:ef639cb3372f69ec44915fafcd6698b6cc78fbe0c2ea41be867f6ed612811963", size = 4423126 }, - { url = "https://files.pythonhosted.org/packages/cd/c7/f65027c2810e14c3e7268353b1681932b87e5a48e65505d8cc17c99e36ae/cryptography-46.0.3-cp38-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:3b51b8ca4f1c6453d8829e1eb7299499ca7f313900dd4d89a24b8b87c0a780d4", size = 4686573 }, - { url = "https://files.pythonhosted.org/packages/0a/6e/1c8331ddf91ca4730ab3086a0f1be19c65510a33b5a441cb334e7a2d2560/cryptography-46.0.3-cp38-abi3-win32.whl", hash = "sha256:6276eb85ef938dc035d59b87c8a7dc559a232f954962520137529d77b18ff1df", size = 3036695 }, - { url = "https://files.pythonhosted.org/packages/90/45/b0d691df20633eff80955a0fc7695ff9051ffce8b69741444bd9ed7bd0db/cryptography-46.0.3-cp38-abi3-win_amd64.whl", hash = "sha256:416260257577718c05135c55958b674000baef9a1c7d9e8f306ec60d71db850f", size = 3501720 }, - { url = "https://files.pythonhosted.org/packages/e8/cb/2da4cc83f5edb9c3257d09e1e7ab7b23f049c7962cae8d842bbef0a9cec9/cryptography-46.0.3-cp38-abi3-win_arm64.whl", hash = "sha256:d89c3468de4cdc4f08a57e214384d0471911a3830fcdaf7a8cc587e42a866372", size = 2918740 }, +sdist = { url = "https://files.pythonhosted.org/packages/9f/33/c00162f49c0e2fe8064a62cb92b93e50c74a72bc370ab92f86112b33ff62/cryptography-46.0.3.tar.gz", hash = "sha256:a8b17438104fed022ce745b362294d9ce35b4c2e45c1d958ad4a4b019285f4a1", size = 749258, upload-time = "2025-10-15T23:18:31.74Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/1d/42/9c391dd801d6cf0d561b5890549d4b27bafcc53b39c31a817e69d87c625b/cryptography-46.0.3-cp311-abi3-macosx_10_9_universal2.whl", hash = "sha256:109d4ddfadf17e8e7779c39f9b18111a09efb969a301a31e987416a0191ed93a", size = 7225004, upload-time = "2025-10-15T23:16:52.239Z" }, + { url = "https://files.pythonhosted.org/packages/1c/67/38769ca6b65f07461eb200e85fc1639b438bdc667be02cf7f2cd6a64601c/cryptography-46.0.3-cp311-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:09859af8466b69bc3c27bdf4f5d84a665e0f7ab5088412e9e2ec49758eca5cbc", size = 4296667, upload-time = "2025-10-15T23:16:54.369Z" }, + { url = "https://files.pythonhosted.org/packages/5c/49/498c86566a1d80e978b42f0d702795f69887005548c041636df6ae1ca64c/cryptography-46.0.3-cp311-abi3-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:01ca9ff2885f3acc98c29f1860552e37f6d7c7d013d7334ff2a9de43a449315d", size = 4450807, upload-time = "2025-10-15T23:16:56.414Z" }, + { url = "https://files.pythonhosted.org/packages/4b/0a/863a3604112174c8624a2ac3c038662d9e59970c7f926acdcfaed8d61142/cryptography-46.0.3-cp311-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:6eae65d4c3d33da080cff9c4ab1f711b15c1d9760809dad6ea763f3812d254cb", size = 4299615, upload-time = "2025-10-15T23:16:58.442Z" }, + { url = "https://files.pythonhosted.org/packages/64/02/b73a533f6b64a69f3cd3872acb6ebc12aef924d8d103133bb3ea750dc703/cryptography-46.0.3-cp311-abi3-manylinux_2_28_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:e5bf0ed4490068a2e72ac03d786693adeb909981cc596425d09032d372bcc849", size = 4016800, upload-time = "2025-10-15T23:17:00.378Z" }, + { url = "https://files.pythonhosted.org/packages/25/d5/16e41afbfa450cde85a3b7ec599bebefaef16b5c6ba4ec49a3532336ed72/cryptography-46.0.3-cp311-abi3-manylinux_2_28_ppc64le.whl", hash = "sha256:5ecfccd2329e37e9b7112a888e76d9feca2347f12f37918facbb893d7bb88ee8", size = 4984707, upload-time = "2025-10-15T23:17:01.98Z" }, + { url = "https://files.pythonhosted.org/packages/c9/56/e7e69b427c3878352c2fb9b450bd0e19ed552753491d39d7d0a2f5226d41/cryptography-46.0.3-cp311-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:a2c0cd47381a3229c403062f764160d57d4d175e022c1df84e168c6251a22eec", size = 4482541, upload-time = "2025-10-15T23:17:04.078Z" }, + { url = "https://files.pythonhosted.org/packages/78/f6/50736d40d97e8483172f1bb6e698895b92a223dba513b0ca6f06b2365339/cryptography-46.0.3-cp311-abi3-manylinux_2_34_aarch64.whl", hash = "sha256:549e234ff32571b1f4076ac269fcce7a808d3bf98b76c8dd560e42dbc66d7d91", size = 4299464, upload-time = "2025-10-15T23:17:05.483Z" }, + { url = "https://files.pythonhosted.org/packages/00/de/d8e26b1a855f19d9994a19c702fa2e93b0456beccbcfe437eda00e0701f2/cryptography-46.0.3-cp311-abi3-manylinux_2_34_ppc64le.whl", hash = "sha256:c0a7bb1a68a5d3471880e264621346c48665b3bf1c3759d682fc0864c540bd9e", size = 4950838, upload-time = "2025-10-15T23:17:07.425Z" }, + { url = "https://files.pythonhosted.org/packages/8f/29/798fc4ec461a1c9e9f735f2fc58741b0daae30688f41b2497dcbc9ed1355/cryptography-46.0.3-cp311-abi3-manylinux_2_34_x86_64.whl", hash = "sha256:10b01676fc208c3e6feeb25a8b83d81767e8059e1fe86e1dc62d10a3018fa926", size = 4481596, upload-time = "2025-10-15T23:17:09.343Z" }, + { url = "https://files.pythonhosted.org/packages/15/8d/03cd48b20a573adfff7652b76271078e3045b9f49387920e7f1f631d125e/cryptography-46.0.3-cp311-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:0abf1ffd6e57c67e92af68330d05760b7b7efb243aab8377e583284dbab72c71", size = 4426782, upload-time = "2025-10-15T23:17:11.22Z" }, + { url = "https://files.pythonhosted.org/packages/fa/b1/ebacbfe53317d55cf33165bda24c86523497a6881f339f9aae5c2e13e57b/cryptography-46.0.3-cp311-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:a04bee9ab6a4da801eb9b51f1b708a1b5b5c9eb48c03f74198464c66f0d344ac", size = 4698381, upload-time = "2025-10-15T23:17:12.829Z" }, + { url = "https://files.pythonhosted.org/packages/96/92/8a6a9525893325fc057a01f654d7efc2c64b9de90413adcf605a85744ff4/cryptography-46.0.3-cp311-abi3-win32.whl", hash = "sha256:f260d0d41e9b4da1ed1e0f1ce571f97fe370b152ab18778e9e8f67d6af432018", size = 3055988, upload-time = "2025-10-15T23:17:14.65Z" }, + { url = "https://files.pythonhosted.org/packages/7e/bf/80fbf45253ea585a1e492a6a17efcb93467701fa79e71550a430c5e60df0/cryptography-46.0.3-cp311-abi3-win_amd64.whl", hash = "sha256:a9a3008438615669153eb86b26b61e09993921ebdd75385ddd748702c5adfddb", size = 3514451, upload-time = "2025-10-15T23:17:16.142Z" }, + { url = "https://files.pythonhosted.org/packages/2e/af/9b302da4c87b0beb9db4e756386a7c6c5b8003cd0e742277888d352ae91d/cryptography-46.0.3-cp311-abi3-win_arm64.whl", hash = "sha256:5d7f93296ee28f68447397bf5198428c9aeeab45705a55d53a6343455dcb2c3c", size = 2928007, upload-time = "2025-10-15T23:17:18.04Z" }, + { url = "https://files.pythonhosted.org/packages/f5/e2/a510aa736755bffa9d2f75029c229111a1d02f8ecd5de03078f4c18d91a3/cryptography-46.0.3-cp314-cp314t-macosx_10_9_universal2.whl", hash = "sha256:00a5e7e87938e5ff9ff5447ab086a5706a957137e6e433841e9d24f38a065217", size = 7158012, upload-time = "2025-10-15T23:17:19.982Z" }, + { url = "https://files.pythonhosted.org/packages/73/dc/9aa866fbdbb95b02e7f9d086f1fccfeebf8953509b87e3f28fff927ff8a0/cryptography-46.0.3-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:c8daeb2d2174beb4575b77482320303f3d39b8e81153da4f0fb08eb5fe86a6c5", size = 4288728, upload-time = "2025-10-15T23:17:21.527Z" }, + { url = "https://files.pythonhosted.org/packages/c5/fd/bc1daf8230eaa075184cbbf5f8cd00ba9db4fd32d63fb83da4671b72ed8a/cryptography-46.0.3-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:39b6755623145ad5eff1dab323f4eae2a32a77a7abef2c5089a04a3d04366715", size = 4435078, upload-time = "2025-10-15T23:17:23.042Z" }, + { url = "https://files.pythonhosted.org/packages/82/98/d3bd5407ce4c60017f8ff9e63ffee4200ab3e23fe05b765cab805a7db008/cryptography-46.0.3-cp314-cp314t-manylinux_2_28_aarch64.whl", hash = "sha256:db391fa7c66df6762ee3f00c95a89e6d428f4d60e7abc8328f4fe155b5ac6e54", size = 4293460, upload-time = "2025-10-15T23:17:24.885Z" }, + { url = "https://files.pythonhosted.org/packages/26/e9/e23e7900983c2b8af7a08098db406cf989d7f09caea7897e347598d4cd5b/cryptography-46.0.3-cp314-cp314t-manylinux_2_28_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:78a97cf6a8839a48c49271cdcbd5cf37ca2c1d6b7fdd86cc864f302b5e9bf459", size = 3995237, upload-time = "2025-10-15T23:17:26.449Z" }, + { url = "https://files.pythonhosted.org/packages/91/15/af68c509d4a138cfe299d0d7ddb14afba15233223ebd933b4bbdbc7155d3/cryptography-46.0.3-cp314-cp314t-manylinux_2_28_ppc64le.whl", hash = "sha256:dfb781ff7eaa91a6f7fd41776ec37c5853c795d3b358d4896fdbb5df168af422", size = 4967344, upload-time = "2025-10-15T23:17:28.06Z" }, + { url = "https://files.pythonhosted.org/packages/ca/e3/8643d077c53868b681af077edf6b3cb58288b5423610f21c62aadcbe99f4/cryptography-46.0.3-cp314-cp314t-manylinux_2_28_x86_64.whl", hash = "sha256:6f61efb26e76c45c4a227835ddeae96d83624fb0d29eb5df5b96e14ed1a0afb7", size = 4466564, upload-time = "2025-10-15T23:17:29.665Z" }, + { url = "https://files.pythonhosted.org/packages/0e/43/c1e8726fa59c236ff477ff2b5dc071e54b21e5a1e51aa2cee1676f1c986f/cryptography-46.0.3-cp314-cp314t-manylinux_2_34_aarch64.whl", hash = "sha256:23b1a8f26e43f47ceb6d6a43115f33a5a37d57df4ea0ca295b780ae8546e8044", size = 4292415, upload-time = "2025-10-15T23:17:31.686Z" }, + { url = "https://files.pythonhosted.org/packages/42/f9/2f8fefdb1aee8a8e3256a0568cffc4e6d517b256a2fe97a029b3f1b9fe7e/cryptography-46.0.3-cp314-cp314t-manylinux_2_34_ppc64le.whl", hash = "sha256:b419ae593c86b87014b9be7396b385491ad7f320bde96826d0dd174459e54665", size = 4931457, upload-time = "2025-10-15T23:17:33.478Z" }, + { url = "https://files.pythonhosted.org/packages/79/30/9b54127a9a778ccd6d27c3da7563e9f2d341826075ceab89ae3b41bf5be2/cryptography-46.0.3-cp314-cp314t-manylinux_2_34_x86_64.whl", hash = "sha256:50fc3343ac490c6b08c0cf0d704e881d0d660be923fd3076db3e932007e726e3", size = 4466074, upload-time = "2025-10-15T23:17:35.158Z" }, + { url = "https://files.pythonhosted.org/packages/ac/68/b4f4a10928e26c941b1b6a179143af9f4d27d88fe84a6a3c53592d2e76bf/cryptography-46.0.3-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:22d7e97932f511d6b0b04f2bfd818d73dcd5928db509460aaf48384778eb6d20", size = 4420569, upload-time = "2025-10-15T23:17:37.188Z" }, + { url = "https://files.pythonhosted.org/packages/a3/49/3746dab4c0d1979888f125226357d3262a6dd40e114ac29e3d2abdf1ec55/cryptography-46.0.3-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:d55f3dffadd674514ad19451161118fd010988540cee43d8bc20675e775925de", size = 4681941, upload-time = "2025-10-15T23:17:39.236Z" }, + { url = "https://files.pythonhosted.org/packages/fd/30/27654c1dbaf7e4a3531fa1fc77986d04aefa4d6d78259a62c9dc13d7ad36/cryptography-46.0.3-cp314-cp314t-win32.whl", hash = "sha256:8a6e050cb6164d3f830453754094c086ff2d0b2f3a897a1d9820f6139a1f0914", size = 3022339, upload-time = "2025-10-15T23:17:40.888Z" }, + { url = "https://files.pythonhosted.org/packages/f6/30/640f34ccd4d2a1bc88367b54b926b781b5a018d65f404d409aba76a84b1c/cryptography-46.0.3-cp314-cp314t-win_amd64.whl", hash = "sha256:760f83faa07f8b64e9c33fc963d790a2edb24efb479e3520c14a45741cd9b2db", size = 3494315, upload-time = "2025-10-15T23:17:42.769Z" }, + { url = "https://files.pythonhosted.org/packages/ba/8b/88cc7e3bd0a8e7b861f26981f7b820e1f46aa9d26cc482d0feba0ecb4919/cryptography-46.0.3-cp314-cp314t-win_arm64.whl", hash = "sha256:516ea134e703e9fe26bcd1277a4b59ad30586ea90c365a87781d7887a646fe21", size = 2919331, upload-time = "2025-10-15T23:17:44.468Z" }, + { url = "https://files.pythonhosted.org/packages/fd/23/45fe7f376a7df8daf6da3556603b36f53475a99ce4faacb6ba2cf3d82021/cryptography-46.0.3-cp38-abi3-macosx_10_9_universal2.whl", hash = "sha256:cb3d760a6117f621261d662bccc8ef5bc32ca673e037c83fbe565324f5c46936", size = 7218248, upload-time = "2025-10-15T23:17:46.294Z" }, + { url = "https://files.pythonhosted.org/packages/27/32/b68d27471372737054cbd34c84981f9edbc24fe67ca225d389799614e27f/cryptography-46.0.3-cp38-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:4b7387121ac7d15e550f5cb4a43aef2559ed759c35df7336c402bb8275ac9683", size = 4294089, upload-time = "2025-10-15T23:17:48.269Z" }, + { url = "https://files.pythonhosted.org/packages/26/42/fa8389d4478368743e24e61eea78846a0006caffaf72ea24a15159215a14/cryptography-46.0.3-cp38-abi3-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:15ab9b093e8f09daab0f2159bb7e47532596075139dd74365da52ecc9cb46c5d", size = 4440029, upload-time = "2025-10-15T23:17:49.837Z" }, + { url = "https://files.pythonhosted.org/packages/5f/eb/f483db0ec5ac040824f269e93dd2bd8a21ecd1027e77ad7bdf6914f2fd80/cryptography-46.0.3-cp38-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:46acf53b40ea38f9c6c229599a4a13f0d46a6c3fa9ef19fc1a124d62e338dfa0", size = 4297222, upload-time = "2025-10-15T23:17:51.357Z" }, + { url = "https://files.pythonhosted.org/packages/fd/cf/da9502c4e1912cb1da3807ea3618a6829bee8207456fbbeebc361ec38ba3/cryptography-46.0.3-cp38-abi3-manylinux_2_28_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:10ca84c4668d066a9878890047f03546f3ae0a6b8b39b697457b7757aaf18dbc", size = 4012280, upload-time = "2025-10-15T23:17:52.964Z" }, + { url = "https://files.pythonhosted.org/packages/6b/8f/9adb86b93330e0df8b3dcf03eae67c33ba89958fc2e03862ef1ac2b42465/cryptography-46.0.3-cp38-abi3-manylinux_2_28_ppc64le.whl", hash = "sha256:36e627112085bb3b81b19fed209c05ce2a52ee8b15d161b7c643a7d5a88491f3", size = 4978958, upload-time = "2025-10-15T23:17:54.965Z" }, + { url = "https://files.pythonhosted.org/packages/d1/a0/5fa77988289c34bdb9f913f5606ecc9ada1adb5ae870bd0d1054a7021cc4/cryptography-46.0.3-cp38-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:1000713389b75c449a6e979ffc7dcc8ac90b437048766cef052d4d30b8220971", size = 4473714, upload-time = "2025-10-15T23:17:56.754Z" }, + { url = "https://files.pythonhosted.org/packages/14/e5/fc82d72a58d41c393697aa18c9abe5ae1214ff6f2a5c18ac470f92777895/cryptography-46.0.3-cp38-abi3-manylinux_2_34_aarch64.whl", hash = "sha256:b02cf04496f6576afffef5ddd04a0cb7d49cf6be16a9059d793a30b035f6b6ac", size = 4296970, upload-time = "2025-10-15T23:17:58.588Z" }, + { url = "https://files.pythonhosted.org/packages/78/06/5663ed35438d0b09056973994f1aec467492b33bd31da36e468b01ec1097/cryptography-46.0.3-cp38-abi3-manylinux_2_34_ppc64le.whl", hash = "sha256:71e842ec9bc7abf543b47cf86b9a743baa95f4677d22baa4c7d5c69e49e9bc04", size = 4940236, upload-time = "2025-10-15T23:18:00.897Z" }, + { url = "https://files.pythonhosted.org/packages/fc/59/873633f3f2dcd8a053b8dd1d38f783043b5fce589c0f6988bf55ef57e43e/cryptography-46.0.3-cp38-abi3-manylinux_2_34_x86_64.whl", hash = "sha256:402b58fc32614f00980b66d6e56a5b4118e6cb362ae8f3fda141ba4689bd4506", size = 4472642, upload-time = "2025-10-15T23:18:02.749Z" }, + { url = "https://files.pythonhosted.org/packages/3d/39/8e71f3930e40f6877737d6f69248cf74d4e34b886a3967d32f919cc50d3b/cryptography-46.0.3-cp38-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:ef639cb3372f69ec44915fafcd6698b6cc78fbe0c2ea41be867f6ed612811963", size = 4423126, upload-time = "2025-10-15T23:18:04.85Z" }, + { url = "https://files.pythonhosted.org/packages/cd/c7/f65027c2810e14c3e7268353b1681932b87e5a48e65505d8cc17c99e36ae/cryptography-46.0.3-cp38-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:3b51b8ca4f1c6453d8829e1eb7299499ca7f313900dd4d89a24b8b87c0a780d4", size = 4686573, upload-time = "2025-10-15T23:18:06.908Z" }, + { url = "https://files.pythonhosted.org/packages/0a/6e/1c8331ddf91ca4730ab3086a0f1be19c65510a33b5a441cb334e7a2d2560/cryptography-46.0.3-cp38-abi3-win32.whl", hash = "sha256:6276eb85ef938dc035d59b87c8a7dc559a232f954962520137529d77b18ff1df", size = 3036695, upload-time = "2025-10-15T23:18:08.672Z" }, + { url = "https://files.pythonhosted.org/packages/90/45/b0d691df20633eff80955a0fc7695ff9051ffce8b69741444bd9ed7bd0db/cryptography-46.0.3-cp38-abi3-win_amd64.whl", hash = "sha256:416260257577718c05135c55958b674000baef9a1c7d9e8f306ec60d71db850f", size = 3501720, upload-time = "2025-10-15T23:18:10.632Z" }, + { url = "https://files.pythonhosted.org/packages/e8/cb/2da4cc83f5edb9c3257d09e1e7ab7b23f049c7962cae8d842bbef0a9cec9/cryptography-46.0.3-cp38-abi3-win_arm64.whl", hash = "sha256:d89c3468de4cdc4f08a57e214384d0471911a3830fcdaf7a8cc587e42a866372", size = 2918740, upload-time = "2025-10-15T23:18:12.277Z" }, ] [[package]] name = "dnspython" version = "2.8.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/8c/8b/57666417c0f90f08bcafa776861060426765fdb422eb10212086fb811d26/dnspython-2.8.0.tar.gz", hash = "sha256:181d3c6996452cb1189c4046c61599b84a5a86e099562ffde77d26984ff26d0f", size = 368251 } +sdist = { url = "https://files.pythonhosted.org/packages/8c/8b/57666417c0f90f08bcafa776861060426765fdb422eb10212086fb811d26/dnspython-2.8.0.tar.gz", hash = "sha256:181d3c6996452cb1189c4046c61599b84a5a86e099562ffde77d26984ff26d0f", size = 368251, upload-time = "2025-09-07T18:58:00.022Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/ba/5a/18ad964b0086c6e62e2e7500f7edc89e3faa45033c71c1893d34eed2b2de/dnspython-2.8.0-py3-none-any.whl", hash = "sha256:01d9bbc4a2d76bf0db7c1f729812ded6d912bd318d3b1cf81d30c0f845dbf3af", size = 331094 }, + { url = "https://files.pythonhosted.org/packages/ba/5a/18ad964b0086c6e62e2e7500f7edc89e3faa45033c71c1893d34eed2b2de/dnspython-2.8.0-py3-none-any.whl", hash = "sha256:01d9bbc4a2d76bf0db7c1f729812ded6d912bd318d3b1cf81d30c0f845dbf3af", size = 331094, upload-time = "2025-09-07T18:57:58.071Z" }, ] [[package]] name = "docopt" version = "0.6.2" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/a2/55/8f8cab2afd404cf578136ef2cc5dfb50baa1761b68c9da1fb1e4eed343c9/docopt-0.6.2.tar.gz", hash = "sha256:49b3a825280bd66b3aa83585ef59c4a8c82f2c8a522dbe754a8bc8d08c85c491", size = 25901 } +sdist = { url = "https://files.pythonhosted.org/packages/a2/55/8f8cab2afd404cf578136ef2cc5dfb50baa1761b68c9da1fb1e4eed343c9/docopt-0.6.2.tar.gz", hash = "sha256:49b3a825280bd66b3aa83585ef59c4a8c82f2c8a522dbe754a8bc8d08c85c491", size = 25901, upload-time = "2014-06-16T11:18:57.406Z" } [[package]] name = "dotmap" version = "1.3.30" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/bc/68/c186606e4f2bf731abd18044ea201e70c3c244bf468f41368820d197fca5/dotmap-1.3.30.tar.gz", hash = "sha256:5821a7933f075fb47563417c0e92e0b7c031158b4c9a6a7e56163479b658b368", size = 12391 } +sdist = { url = "https://files.pythonhosted.org/packages/bc/68/c186606e4f2bf731abd18044ea201e70c3c244bf468f41368820d197fca5/dotmap-1.3.30.tar.gz", hash = "sha256:5821a7933f075fb47563417c0e92e0b7c031158b4c9a6a7e56163479b658b368", size = 12391, upload-time = "2022-04-06T16:26:49.211Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/4d/f9/976d6813c160d6c89196d81e9466dca1503d20e609d8751f3536daf37ec6/dotmap-1.3.30-py3-none-any.whl", hash = "sha256:bd9fa15286ea2ad899a4d1dc2445ed85a1ae884a42effb87c89a6ecce71243c6", size = 11464 }, + { url = "https://files.pythonhosted.org/packages/4d/f9/976d6813c160d6c89196d81e9466dca1503d20e609d8751f3536daf37ec6/dotmap-1.3.30-py3-none-any.whl", hash = "sha256:bd9fa15286ea2ad899a4d1dc2445ed85a1ae884a42effb87c89a6ecce71243c6", size = 11464, upload-time = "2022-04-06T16:26:47.103Z" }, ] [[package]] @@ -543,18 +543,18 @@ dependencies = [ { name = "dnspython" }, { name = "idna" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/f5/22/900cb125c76b7aaa450ce02fd727f452243f2e91a61af068b40adba60ea9/email_validator-2.3.0.tar.gz", hash = "sha256:9fc05c37f2f6cf439ff414f8fc46d917929974a82244c20eb10231ba60c54426", size = 51238 } +sdist = { url = "https://files.pythonhosted.org/packages/f5/22/900cb125c76b7aaa450ce02fd727f452243f2e91a61af068b40adba60ea9/email_validator-2.3.0.tar.gz", hash = "sha256:9fc05c37f2f6cf439ff414f8fc46d917929974a82244c20eb10231ba60c54426", size = 51238, upload-time = "2025-08-26T13:09:06.831Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/de/15/545e2b6cf2e3be84bc1ed85613edd75b8aea69807a71c26f4ca6a9258e82/email_validator-2.3.0-py3-none-any.whl", hash = "sha256:80f13f623413e6b197ae73bb10bf4eb0908faf509ad8362c5edeb0be7fd450b4", size = 35604 }, + { url = "https://files.pythonhosted.org/packages/de/15/545e2b6cf2e3be84bc1ed85613edd75b8aea69807a71c26f4ca6a9258e82/email_validator-2.3.0-py3-none-any.whl", hash = "sha256:80f13f623413e6b197ae73bb10bf4eb0908faf509ad8362c5edeb0be7fd450b4", size = 35604, upload-time = "2025-08-26T13:09:05.858Z" }, ] [[package]] name = "et-xmlfile" version = "2.0.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/d3/38/af70d7ab1ae9d4da450eeec1fa3918940a5fafb9055e934af8d6eb0c2313/et_xmlfile-2.0.0.tar.gz", hash = "sha256:dab3f4764309081ce75662649be815c4c9081e88f0837825f90fd28317d4da54", size = 17234 } +sdist = { url = "https://files.pythonhosted.org/packages/d3/38/af70d7ab1ae9d4da450eeec1fa3918940a5fafb9055e934af8d6eb0c2313/et_xmlfile-2.0.0.tar.gz", hash = "sha256:dab3f4764309081ce75662649be815c4c9081e88f0837825f90fd28317d4da54", size = 17234, upload-time = "2024-10-25T17:25:40.039Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/c1/8b/5fe2cc11fee489817272089c4203e679c63b570a5aaeb18d852ae3cbba6a/et_xmlfile-2.0.0-py3-none-any.whl", hash = "sha256:7a91720bc756843502c3b7504c77b8fe44217c85c537d85037f0f536151b2caa", size = 18059 }, + { url = "https://files.pythonhosted.org/packages/c1/8b/5fe2cc11fee489817272089c4203e679c63b570a5aaeb18d852ae3cbba6a/et_xmlfile-2.0.0-py3-none-any.whl", hash = "sha256:7a91720bc756843502c3b7504c77b8fe44217c85c537d85037f0f536151b2caa", size = 18059, upload-time = "2024-10-25T17:25:39.051Z" }, ] [[package]] @@ -564,9 +564,9 @@ source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "faker" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/ba/98/75cacae9945f67cfe323829fc2ac451f64517a8a330b572a06a323997065/factory_boy-3.3.3.tar.gz", hash = "sha256:866862d226128dfac7f2b4160287e899daf54f2612778327dd03d0e2cb1e3d03", size = 164146 } +sdist = { url = "https://files.pythonhosted.org/packages/ba/98/75cacae9945f67cfe323829fc2ac451f64517a8a330b572a06a323997065/factory_boy-3.3.3.tar.gz", hash = "sha256:866862d226128dfac7f2b4160287e899daf54f2612778327dd03d0e2cb1e3d03", size = 164146, upload-time = "2025-02-03T09:49:04.433Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/27/8d/2bc5f5546ff2ccb3f7de06742853483ab75bf74f36a92254702f8baecc79/factory_boy-3.3.3-py2.py3-none-any.whl", hash = "sha256:1c39e3289f7e667c4285433f305f8d506efc2fe9c73aaea4151ebd5cdea394fc", size = 37036 }, + { url = "https://files.pythonhosted.org/packages/27/8d/2bc5f5546ff2ccb3f7de06742853483ab75bf74f36a92254702f8baecc79/factory_boy-3.3.3-py2.py3-none-any.whl", hash = "sha256:1c39e3289f7e667c4285433f305f8d506efc2fe9c73aaea4151ebd5cdea394fc", size = 37036, upload-time = "2025-02-03T09:49:01.659Z" }, ] [[package]] @@ -576,9 +576,9 @@ source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "tzdata" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/3d/84/e95acaa848b855e15c83331d0401ee5f84b2f60889255c2e055cb4fb6bdf/faker-37.12.0.tar.gz", hash = "sha256:7505e59a7e02fa9010f06c3e1e92f8250d4cfbb30632296140c2d6dbef09b0fa", size = 1935741 } +sdist = { url = "https://files.pythonhosted.org/packages/3d/84/e95acaa848b855e15c83331d0401ee5f84b2f60889255c2e055cb4fb6bdf/faker-37.12.0.tar.gz", hash = "sha256:7505e59a7e02fa9010f06c3e1e92f8250d4cfbb30632296140c2d6dbef09b0fa", size = 1935741, upload-time = "2025-10-24T15:19:58.764Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/8e/98/2c050dec90e295a524c9b65c4cb9e7c302386a296b2938710448cbd267d5/faker-37.12.0-py3-none-any.whl", hash = "sha256:afe7ccc038da92f2fbae30d8e16d19d91e92e242f8401ce9caf44de892bab4c4", size = 1975461 }, + { url = "https://files.pythonhosted.org/packages/8e/98/2c050dec90e295a524c9b65c4cb9e7c302386a296b2938710448cbd267d5/faker-37.12.0-py3-none-any.whl", hash = "sha256:afe7ccc038da92f2fbae30d8e16d19d91e92e242f8401ce9caf44de892bab4c4", size = 1975461, upload-time = "2025-10-24T15:19:55.739Z" }, ] [[package]] @@ -591,9 +591,9 @@ dependencies = [ { name = "starlette" }, { name = "typing-extensions" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/8c/e3/77a2df0946703973b9905fd0cde6172c15e0781984320123b4f5079e7113/fastapi-0.121.0.tar.gz", hash = "sha256:06663356a0b1ee93e875bbf05a31fb22314f5bed455afaaad2b2dad7f26e98fa", size = 342412 } +sdist = { url = "https://files.pythonhosted.org/packages/8c/e3/77a2df0946703973b9905fd0cde6172c15e0781984320123b4f5079e7113/fastapi-0.121.0.tar.gz", hash = "sha256:06663356a0b1ee93e875bbf05a31fb22314f5bed455afaaad2b2dad7f26e98fa", size = 342412, upload-time = "2025-11-03T10:25:54.818Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/dd/2c/42277afc1ba1a18f8358561eee40785d27becab8f80a1f945c0a3051c6eb/fastapi-0.121.0-py3-none-any.whl", hash = "sha256:8bdf1b15a55f4e4b0d6201033da9109ea15632cb76cf156e7b8b4019f2172106", size = 109183 }, + { url = "https://files.pythonhosted.org/packages/dd/2c/42277afc1ba1a18f8358561eee40785d27becab8f80a1f945c0a3051c6eb/fastapi-0.121.0-py3-none-any.whl", hash = "sha256:8bdf1b15a55f4e4b0d6201033da9109ea15632cb76cf156e7b8b4019f2172106", size = 109183, upload-time = "2025-11-03T10:25:53.27Z" }, ] [package.optional-dependencies] @@ -615,9 +615,9 @@ dependencies = [ { name = "typer" }, { name = "uvicorn", extra = ["standard"] }, ] -sdist = { url = "https://files.pythonhosted.org/packages/cc/13/11e43d630be84e51ba5510a6da6a11eb93b44b72caa796137c5dddda937b/fastapi_cli-0.0.14.tar.gz", hash = "sha256:ddfb5de0a67f77a8b3271af1460489bd4d7f4add73d11fbfac613827b0275274", size = 17994 } +sdist = { url = "https://files.pythonhosted.org/packages/cc/13/11e43d630be84e51ba5510a6da6a11eb93b44b72caa796137c5dddda937b/fastapi_cli-0.0.14.tar.gz", hash = "sha256:ddfb5de0a67f77a8b3271af1460489bd4d7f4add73d11fbfac613827b0275274", size = 17994, upload-time = "2025-10-20T16:33:21.054Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/40/e8/bc8bbfd93dcc8e347ce98a3e654fb0d2e5f2739afb46b98f41a30c339269/fastapi_cli-0.0.14-py3-none-any.whl", hash = "sha256:e66b9ad499ee77a4e6007545cde6de1459b7f21df199d7f29aad2adaab168eca", size = 11151 }, + { url = "https://files.pythonhosted.org/packages/40/e8/bc8bbfd93dcc8e347ce98a3e654fb0d2e5f2739afb46b98f41a30c339269/fastapi_cli-0.0.14-py3-none-any.whl", hash = "sha256:e66b9ad499ee77a4e6007545cde6de1459b7f21df199d7f29aad2adaab168eca", size = 11151, upload-time = "2025-10-20T16:33:19.318Z" }, ] [package.optional-dependencies] @@ -639,9 +639,9 @@ dependencies = [ { name = "typer" }, { name = "uvicorn", extra = ["standard"] }, ] -sdist = { url = "https://files.pythonhosted.org/packages/f9/48/0f14d8555b750dc8c04382804e4214f1d7f55298127f3a0237ba566e69dd/fastapi_cloud_cli-0.3.1.tar.gz", hash = "sha256:8c7226c36e92e92d0c89827e8f56dbf164ab2de4444bd33aa26b6c3f7675db69", size = 24080 } +sdist = { url = "https://files.pythonhosted.org/packages/f9/48/0f14d8555b750dc8c04382804e4214f1d7f55298127f3a0237ba566e69dd/fastapi_cloud_cli-0.3.1.tar.gz", hash = "sha256:8c7226c36e92e92d0c89827e8f56dbf164ab2de4444bd33aa26b6c3f7675db69", size = 24080, upload-time = "2025-10-09T11:32:58.174Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/68/79/7f5a5e5513e6a737e5fb089d9c59c74d4d24dc24d581d3aa519b326bedda/fastapi_cloud_cli-0.3.1-py3-none-any.whl", hash = "sha256:7d1a98a77791a9d0757886b2ffbf11bcc6b3be93210dd15064be10b216bf7e00", size = 19711 }, + { url = "https://files.pythonhosted.org/packages/68/79/7f5a5e5513e6a737e5fb089d9c59c74d4d24dc24d581d3aa519b326bedda/fastapi_cloud_cli-0.3.1-py3-none-any.whl", hash = "sha256:7d1a98a77791a9d0757886b2ffbf11bcc6b3be93210dd15064be10b216bf7e00", size = 19711, upload-time = "2025-10-09T11:32:57.118Z" }, ] [[package]] @@ -652,15 +652,15 @@ dependencies = [ { name = "fastapi" }, { name = "pydantic" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/43/ed/c36cfcd849519fd2d23051ad81a91fc5e8cfa7109496fc8a10ad565a5fe9/fastapi_filter-2.0.1.tar.gz", hash = "sha256:cffda370097af7e404f1eb188aca58b199084bfaf7cec881e40b404adf12566e", size = 9857 } +sdist = { url = "https://files.pythonhosted.org/packages/43/ed/c36cfcd849519fd2d23051ad81a91fc5e8cfa7109496fc8a10ad565a5fe9/fastapi_filter-2.0.1.tar.gz", hash = "sha256:cffda370097af7e404f1eb188aca58b199084bfaf7cec881e40b404adf12566e", size = 9857, upload-time = "2024-12-07T17:30:06.343Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/5e/88/afc022ad64d12f730141fc50758ecf9d60de5fed11335dc16e3127617f05/fastapi_filter-2.0.1-py3-none-any.whl", hash = "sha256:711d48707ec62f7c9e12a7713fc0f6a99858a9e3741b4d108102d5599e77197d", size = 11586 }, + { url = "https://files.pythonhosted.org/packages/5e/88/afc022ad64d12f730141fc50758ecf9d60de5fed11335dc16e3127617f05/fastapi_filter-2.0.1-py3-none-any.whl", hash = "sha256:711d48707ec62f7c9e12a7713fc0f6a99858a9e3741b4d108102d5599e77197d", size = 11586, upload-time = "2024-12-07T17:30:05.375Z" }, ] [[package]] name = "fastapi-mail" version = "1.2.6" -source = { git = "https://github.com/simonvanlierde/fastapi-mail?rev=f32147ec1a450ed22262913c5ac7ec3b67dd0117#f32147ec1a450ed22262913c5ac7ec3b67dd0117" } +source = { git = "https://github.com/simonvanlierde/fastapi-mail?rev=6c6f04a7afaf3cdced82764009a2f1f2a3c3ee6c#6c6f04a7afaf3cdced82764009a2f1f2a3c3ee6c" } dependencies = [ { name = "aiosmtplib" }, { name = "blinker" }, @@ -683,9 +683,9 @@ dependencies = [ { name = "pydantic" }, { name = "typing-extensions" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/bc/db/8a3d097c491ad873574bd7295834ef89e16263ae9104855bbb5ee6d46e47/fastapi_pagination-0.15.0.tar.gz", hash = "sha256:11fe39cbe181ed3c18919b90faf6bfcbe40cb596aa9c52a98bbce85111a29a4f", size = 557472 } +sdist = { url = "https://files.pythonhosted.org/packages/bc/db/8a3d097c491ad873574bd7295834ef89e16263ae9104855bbb5ee6d46e47/fastapi_pagination-0.15.0.tar.gz", hash = "sha256:11fe39cbe181ed3c18919b90faf6bfcbe40cb596aa9c52a98bbce85111a29a4f", size = 557472, upload-time = "2025-10-28T19:06:17.732Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/68/91/b835e07234170ba85473227aa107bcf1dc616ff6cb643c0bd9b8225a55f1/fastapi_pagination-0.15.0-py3-none-any.whl", hash = "sha256:ffef937e78903fcb6f356b8407ec1fb0620a06675087fa7d0c4e537a60aa0447", size = 52292 }, + { url = "https://files.pythonhosted.org/packages/68/91/b835e07234170ba85473227aa107bcf1dc616ff6cb643c0bd9b8225a55f1/fastapi_pagination-0.15.0-py3-none-any.whl", hash = "sha256:ffef937e78903fcb6f356b8407ec1fb0620a06675087fa7d0c4e537a60aa0447", size = 52292, upload-time = "2025-10-28T19:06:16.371Z" }, ] [[package]] @@ -695,9 +695,9 @@ source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "boto3" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/68/8a/e56d4ade659994c2989091b96642f10554ec3914a40de56a556ffdbbcd26/fastapi_storages-0.3.0.tar.gz", hash = "sha256:f784335fff9cd163b783e842da04c6d9ed1b306fce8995fda109b170d6d453df", size = 6706 } +sdist = { url = "https://files.pythonhosted.org/packages/68/8a/e56d4ade659994c2989091b96642f10554ec3914a40de56a556ffdbbcd26/fastapi_storages-0.3.0.tar.gz", hash = "sha256:f784335fff9cd163b783e842da04c6d9ed1b306fce8995fda109b170d6d453df", size = 6706, upload-time = "2024-02-15T15:14:26.431Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/a7/b5/3fb94b4f329fb2f83ffa54e6941b769deaaaa77f63a9fe70905219dd7339/fastapi_storages-0.3.0-py3-none-any.whl", hash = "sha256:91adb41a80fdef2a84c0f8244c27ade7ff8bd5db9b7fa95c496c06c03e192477", size = 9725 }, + { url = "https://files.pythonhosted.org/packages/a7/b5/3fb94b4f329fb2f83ffa54e6941b769deaaaa77f63a9fe70905219dd7339/fastapi_storages-0.3.0-py3-none-any.whl", hash = "sha256:91adb41a80fdef2a84c0f8244c27ade7ff8bd5db9b7fa95c496c06c03e192477", size = 9725, upload-time = "2024-02-15T15:14:27.567Z" }, ] [[package]] @@ -712,9 +712,9 @@ dependencies = [ { name = "pyjwt", extra = ["crypto"] }, { name = "python-multipart" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/fa/ea/6c0ba809f29d22ad53ab25bbae4408f00b0a3375b71bd21c39dcc3a16044/fastapi_users-15.0.1.tar.gz", hash = "sha256:c822755c1288740a919636d3463797e54df91b53c1c6f4917693d499867d21a7", size = 120916 } +sdist = { url = "https://files.pythonhosted.org/packages/fa/ea/6c0ba809f29d22ad53ab25bbae4408f00b0a3375b71bd21c39dcc3a16044/fastapi_users-15.0.1.tar.gz", hash = "sha256:c822755c1288740a919636d3463797e54df91b53c1c6f4917693d499867d21a7", size = 120916, upload-time = "2025-10-25T06:52:45.735Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/59/7f/1bff91a48e755e659d0505f597a8e010ec92059f2219a838fd15887a89b2/fastapi_users-15.0.1-py3-none-any.whl", hash = "sha256:6f637eb2fc80be6bba396b77dded30fe4c22fa943349d2e0a1647894f8b21c16", size = 38624 }, + { url = "https://files.pythonhosted.org/packages/59/7f/1bff91a48e755e659d0505f597a8e010ec92059f2219a838fd15887a89b2/fastapi_users-15.0.1-py3-none-any.whl", hash = "sha256:6f637eb2fc80be6bba396b77dded30fe4c22fa943349d2e0a1647894f8b21c16", size = 38624, upload-time = "2025-10-25T06:52:44.119Z" }, ] [package.optional-dependencies] @@ -733,9 +733,9 @@ dependencies = [ { name = "fastapi-users" }, { name = "sqlalchemy", extra = ["asyncio"] }, ] -sdist = { url = "https://files.pythonhosted.org/packages/87/12/bc9e6146ae31564741cefc87ee6e37fa5b566933f0afe8aa030779d60e60/fastapi_users_db_sqlalchemy-7.0.0.tar.gz", hash = "sha256:6823eeedf8a92f819276a2b2210ef1dcfd71fe8b6e37f7b4da8d1c60e3dfd595", size = 10877 } +sdist = { url = "https://files.pythonhosted.org/packages/87/12/bc9e6146ae31564741cefc87ee6e37fa5b566933f0afe8aa030779d60e60/fastapi_users_db_sqlalchemy-7.0.0.tar.gz", hash = "sha256:6823eeedf8a92f819276a2b2210ef1dcfd71fe8b6e37f7b4da8d1c60e3dfd595", size = 10877, upload-time = "2025-01-04T13:09:05.086Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/a6/08/9968963c1fb8c34627b7f1fbcdfe9438540f87dc7c9bfb59bb4fd19a4ecf/fastapi_users_db_sqlalchemy-7.0.0-py3-none-any.whl", hash = "sha256:5fceac018e7cfa69efc70834dd3035b3de7988eb4274154a0dbe8b14f5aa001e", size = 6891 }, + { url = "https://files.pythonhosted.org/packages/a6/08/9968963c1fb8c34627b7f1fbcdfe9438540f87dc7c9bfb59bb4fd19a4ecf/fastapi_users_db_sqlalchemy-7.0.0-py3-none-any.whl", hash = "sha256:5fceac018e7cfa69efc70834dd3035b3de7988eb4274154a0dbe8b14f5aa001e", size = 6891, upload-time = "2025-01-04T13:09:02.869Z" }, ] [[package]] @@ -752,9 +752,9 @@ dependencies = [ name = "filelock" version = "3.20.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/58/46/0028a82567109b5ef6e4d2a1f04a583fb513e6cf9527fcdd09afd817deeb/filelock-3.20.0.tar.gz", hash = "sha256:711e943b4ec6be42e1d4e6690b48dc175c822967466bb31c0c293f34334c13f4", size = 18922 } +sdist = { url = "https://files.pythonhosted.org/packages/58/46/0028a82567109b5ef6e4d2a1f04a583fb513e6cf9527fcdd09afd817deeb/filelock-3.20.0.tar.gz", hash = "sha256:711e943b4ec6be42e1d4e6690b48dc175c822967466bb31c0c293f34334c13f4", size = 18922, upload-time = "2025-10-08T18:03:50.056Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/76/91/7216b27286936c16f5b4d0c530087e4a54eead683e6b0b73dd0c64844af6/filelock-3.20.0-py3-none-any.whl", hash = "sha256:339b4732ffda5cd79b13f4e2711a31b0365ce445d95d243bb996273d072546a2", size = 16054 }, + { url = "https://files.pythonhosted.org/packages/76/91/7216b27286936c16f5b4d0c530087e4a54eead683e6b0b73dd0c64844af6/filelock-3.20.0-py3-none-any.whl", hash = "sha256:339b4732ffda5cd79b13f4e2711a31b0365ce445d95d243bb996273d072546a2", size = 16054, upload-time = "2025-10-08T18:03:48.35Z" }, ] [[package]] @@ -768,9 +768,9 @@ dependencies = [ { name = "protobuf" }, { name = "requests" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/61/da/83d7043169ac2c8c7469f0e375610d78ae2160134bf1b80634c482fa079c/google_api_core-2.28.1.tar.gz", hash = "sha256:2b405df02d68e68ce0fbc138559e6036559e685159d148ae5861013dc201baf8", size = 176759 } +sdist = { url = "https://files.pythonhosted.org/packages/61/da/83d7043169ac2c8c7469f0e375610d78ae2160134bf1b80634c482fa079c/google_api_core-2.28.1.tar.gz", hash = "sha256:2b405df02d68e68ce0fbc138559e6036559e685159d148ae5861013dc201baf8", size = 176759, upload-time = "2025-10-28T21:34:51.529Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/ed/d4/90197b416cb61cefd316964fd9e7bd8324bcbafabf40eef14a9f20b81974/google_api_core-2.28.1-py3-none-any.whl", hash = "sha256:4021b0f8ceb77a6fb4de6fde4502cecab45062e66ff4f2895169e0b35bc9466c", size = 173706 }, + { url = "https://files.pythonhosted.org/packages/ed/d4/90197b416cb61cefd316964fd9e7bd8324bcbafabf40eef14a9f20b81974/google_api_core-2.28.1-py3-none-any.whl", hash = "sha256:4021b0f8ceb77a6fb4de6fde4502cecab45062e66ff4f2895169e0b35bc9466c", size = 173706, upload-time = "2025-10-28T21:34:50.151Z" }, ] [[package]] @@ -784,9 +784,9 @@ dependencies = [ { name = "httplib2" }, { name = "uritemplate" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/75/83/60cdacf139d768dd7f0fcbe8d95b418299810068093fdf8228c6af89bb70/google_api_python_client-2.187.0.tar.gz", hash = "sha256:e98e8e8f49e1b5048c2f8276473d6485febc76c9c47892a8b4d1afa2c9ec8278", size = 14068154 } +sdist = { url = "https://files.pythonhosted.org/packages/75/83/60cdacf139d768dd7f0fcbe8d95b418299810068093fdf8228c6af89bb70/google_api_python_client-2.187.0.tar.gz", hash = "sha256:e98e8e8f49e1b5048c2f8276473d6485febc76c9c47892a8b4d1afa2c9ec8278", size = 14068154, upload-time = "2025-11-06T01:48:53.274Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/96/58/c1e716be1b055b504d80db2c8413f6c6a890a6ae218a65f178b63bc30356/google_api_python_client-2.187.0-py3-none-any.whl", hash = "sha256:d8d0f6d85d7d1d10bdab32e642312ed572bdc98919f72f831b44b9a9cebba32f", size = 14641434 }, + { url = "https://files.pythonhosted.org/packages/96/58/c1e716be1b055b504d80db2c8413f6c6a890a6ae218a65f178b63bc30356/google_api_python_client-2.187.0-py3-none-any.whl", hash = "sha256:d8d0f6d85d7d1d10bdab32e642312ed572bdc98919f72f831b44b9a9cebba32f", size = 14641434, upload-time = "2025-11-06T01:48:50.763Z" }, ] [[package]] @@ -798,9 +798,9 @@ dependencies = [ { name = "pyasn1-modules" }, { name = "rsa" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/ff/ef/66d14cf0e01b08d2d51ffc3c20410c4e134a1548fc246a6081eae585a4fe/google_auth-2.43.0.tar.gz", hash = "sha256:88228eee5fc21b62a1b5fe773ca15e67778cb07dc8363adcb4a8827b52d81483", size = 296359 } +sdist = { url = "https://files.pythonhosted.org/packages/ff/ef/66d14cf0e01b08d2d51ffc3c20410c4e134a1548fc246a6081eae585a4fe/google_auth-2.43.0.tar.gz", hash = "sha256:88228eee5fc21b62a1b5fe773ca15e67778cb07dc8363adcb4a8827b52d81483", size = 296359, upload-time = "2025-11-06T00:13:36.587Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/6f/d1/385110a9ae86d91cc14c5282c61fe9f4dc41c0b9f7d423c6ad77038c4448/google_auth-2.43.0-py2.py3-none-any.whl", hash = "sha256:af628ba6fa493f75c7e9dbe9373d148ca9f4399b5ea29976519e0a3848eddd16", size = 223114 }, + { url = "https://files.pythonhosted.org/packages/6f/d1/385110a9ae86d91cc14c5282c61fe9f4dc41c0b9f7d423c6ad77038c4448/google_auth-2.43.0-py2.py3-none-any.whl", hash = "sha256:af628ba6fa493f75c7e9dbe9373d148ca9f4399b5ea29976519e0a3848eddd16", size = 223114, upload-time = "2025-11-06T00:13:35.209Z" }, ] [[package]] @@ -811,9 +811,9 @@ dependencies = [ { name = "google-auth" }, { name = "httplib2" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/e0/83/7ef576d1c7ccea214e7b001e69c006bc75e058a3a1f2ab810167204b698b/google_auth_httplib2-0.2.1.tar.gz", hash = "sha256:5ef03be3927423c87fb69607b42df23a444e434ddb2555b73b3679793187b7de", size = 11086 } +sdist = { url = "https://files.pythonhosted.org/packages/e0/83/7ef576d1c7ccea214e7b001e69c006bc75e058a3a1f2ab810167204b698b/google_auth_httplib2-0.2.1.tar.gz", hash = "sha256:5ef03be3927423c87fb69607b42df23a444e434ddb2555b73b3679793187b7de", size = 11086, upload-time = "2025-10-30T21:13:16.569Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/44/a7/ca23dd006255f70e2bc469d3f9f0c82ea455335bfd682ad4d677adc435de/google_auth_httplib2-0.2.1-py3-none-any.whl", hash = "sha256:1be94c611db91c01f9703e7f62b0a59bbd5587a95571c7b6fade510d648bc08b", size = 9525 }, + { url = "https://files.pythonhosted.org/packages/44/a7/ca23dd006255f70e2bc469d3f9f0c82ea455335bfd682ad4d677adc435de/google_auth_httplib2-0.2.1-py3-none-any.whl", hash = "sha256:1be94c611db91c01f9703e7f62b0a59bbd5587a95571c7b6fade510d648bc08b", size = 9525, upload-time = "2025-10-30T21:13:15.758Z" }, ] [[package]] @@ -823,46 +823,46 @@ source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "protobuf" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/e5/7b/adfd75544c415c487b33061fe7ae526165241c1ea133f9a9125a56b39fd8/googleapis_common_protos-1.72.0.tar.gz", hash = "sha256:e55a601c1b32b52d7a3e65f43563e2aa61bcd737998ee672ac9b951cd49319f5", size = 147433 } +sdist = { url = "https://files.pythonhosted.org/packages/e5/7b/adfd75544c415c487b33061fe7ae526165241c1ea133f9a9125a56b39fd8/googleapis_common_protos-1.72.0.tar.gz", hash = "sha256:e55a601c1b32b52d7a3e65f43563e2aa61bcd737998ee672ac9b951cd49319f5", size = 147433, upload-time = "2025-11-06T18:29:24.087Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/c4/ab/09169d5a4612a5f92490806649ac8d41e3ec9129c636754575b3553f4ea4/googleapis_common_protos-1.72.0-py3-none-any.whl", hash = "sha256:4299c5a82d5ae1a9702ada957347726b167f9f8d1fc352477702a1e851ff4038", size = 297515 }, + { url = "https://files.pythonhosted.org/packages/c4/ab/09169d5a4612a5f92490806649ac8d41e3ec9129c636754575b3553f4ea4/googleapis_common_protos-1.72.0-py3-none-any.whl", hash = "sha256:4299c5a82d5ae1a9702ada957347726b167f9f8d1fc352477702a1e851ff4038", size = 297515, upload-time = "2025-11-06T18:29:13.14Z" }, ] [[package]] name = "greenlet" version = "3.2.4" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/03/b8/704d753a5a45507a7aab61f18db9509302ed3d0a27ac7e0359ec2905b1a6/greenlet-3.2.4.tar.gz", hash = "sha256:0dca0d95ff849f9a364385f36ab49f50065d76964944638be9691e1832e9f86d", size = 188260 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/49/e8/58c7f85958bda41dafea50497cbd59738c5c43dbbea5ee83d651234398f4/greenlet-3.2.4-cp313-cp313-macosx_11_0_universal2.whl", hash = "sha256:1a921e542453fe531144e91e1feedf12e07351b1cf6c9e8a3325ea600a715a31", size = 272814 }, - { url = "https://files.pythonhosted.org/packages/62/dd/b9f59862e9e257a16e4e610480cfffd29e3fae018a68c2332090b53aac3d/greenlet-3.2.4-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:cd3c8e693bff0fff6ba55f140bf390fa92c994083f838fece0f63be121334945", size = 641073 }, - { url = "https://files.pythonhosted.org/packages/f7/0b/bc13f787394920b23073ca3b6c4a7a21396301ed75a655bcb47196b50e6e/greenlet-3.2.4-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:710638eb93b1fa52823aa91bf75326f9ecdfd5e0466f00789246a5280f4ba0fc", size = 655191 }, - { url = "https://files.pythonhosted.org/packages/f2/d6/6adde57d1345a8d0f14d31e4ab9c23cfe8e2cd39c3baf7674b4b0338d266/greenlet-3.2.4-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:c5111ccdc9c88f423426df3fd1811bfc40ed66264d35aa373420a34377efc98a", size = 649516 }, - { url = "https://files.pythonhosted.org/packages/7f/3b/3a3328a788d4a473889a2d403199932be55b1b0060f4ddd96ee7cdfcad10/greenlet-3.2.4-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:d76383238584e9711e20ebe14db6c88ddcedc1829a9ad31a584389463b5aa504", size = 652169 }, - { url = "https://files.pythonhosted.org/packages/ee/43/3cecdc0349359e1a527cbf2e3e28e5f8f06d3343aaf82ca13437a9aa290f/greenlet-3.2.4-cp313-cp313-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:23768528f2911bcd7e475210822ffb5254ed10d71f4028387e5a99b4c6699671", size = 610497 }, - { url = "https://files.pythonhosted.org/packages/b8/19/06b6cf5d604e2c382a6f31cafafd6f33d5dea706f4db7bdab184bad2b21d/greenlet-3.2.4-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:00fadb3fedccc447f517ee0d3fd8fe49eae949e1cd0f6a611818f4f6fb7dc83b", size = 1121662 }, - { url = "https://files.pythonhosted.org/packages/a2/15/0d5e4e1a66fab130d98168fe984c509249c833c1a3c16806b90f253ce7b9/greenlet-3.2.4-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:d25c5091190f2dc0eaa3f950252122edbbadbb682aa7b1ef2f8af0f8c0afefae", size = 1149210 }, - { url = "https://files.pythonhosted.org/packages/1c/53/f9c440463b3057485b8594d7a638bed53ba531165ef0ca0e6c364b5cc807/greenlet-3.2.4-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:6e343822feb58ac4d0a1211bd9399de2b3a04963ddeec21530fc426cc121f19b", size = 1564759 }, - { url = "https://files.pythonhosted.org/packages/47/e4/3bb4240abdd0a8d23f4f88adec746a3099f0d86bfedb623f063b2e3b4df0/greenlet-3.2.4-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:ca7f6f1f2649b89ce02f6f229d7c19f680a6238af656f61e0115b24857917929", size = 1634288 }, - { url = "https://files.pythonhosted.org/packages/0b/55/2321e43595e6801e105fcfdee02b34c0f996eb71e6ddffca6b10b7e1d771/greenlet-3.2.4-cp313-cp313-win_amd64.whl", hash = "sha256:554b03b6e73aaabec3745364d6239e9e012d64c68ccd0b8430c64ccc14939a8b", size = 299685 }, - { url = "https://files.pythonhosted.org/packages/22/5c/85273fd7cc388285632b0498dbbab97596e04b154933dfe0f3e68156c68c/greenlet-3.2.4-cp314-cp314-macosx_11_0_universal2.whl", hash = "sha256:49a30d5fda2507ae77be16479bdb62a660fa51b1eb4928b524975b3bde77b3c0", size = 273586 }, - { url = "https://files.pythonhosted.org/packages/d1/75/10aeeaa3da9332c2e761e4c50d4c3556c21113ee3f0afa2cf5769946f7a3/greenlet-3.2.4-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:299fd615cd8fc86267b47597123e3f43ad79c9d8a22bebdce535e53550763e2f", size = 686346 }, - { url = "https://files.pythonhosted.org/packages/c0/aa/687d6b12ffb505a4447567d1f3abea23bd20e73a5bed63871178e0831b7a/greenlet-3.2.4-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:c17b6b34111ea72fc5a4e4beec9711d2226285f0386ea83477cbb97c30a3f3a5", size = 699218 }, - { url = "https://files.pythonhosted.org/packages/dc/8b/29aae55436521f1d6f8ff4e12fb676f3400de7fcf27fccd1d4d17fd8fecd/greenlet-3.2.4-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:b4a1870c51720687af7fa3e7cda6d08d801dae660f75a76f3845b642b4da6ee1", size = 694659 }, - { url = "https://files.pythonhosted.org/packages/92/2e/ea25914b1ebfde93b6fc4ff46d6864564fba59024e928bdc7de475affc25/greenlet-3.2.4-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:061dc4cf2c34852b052a8620d40f36324554bc192be474b9e9770e8c042fd735", size = 695355 }, - { url = "https://files.pythonhosted.org/packages/72/60/fc56c62046ec17f6b0d3060564562c64c862948c9d4bc8aa807cf5bd74f4/greenlet-3.2.4-cp314-cp314-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:44358b9bf66c8576a9f57a590d5f5d6e72fa4228b763d0e43fee6d3b06d3a337", size = 657512 }, - { url = "https://files.pythonhosted.org/packages/23/6e/74407aed965a4ab6ddd93a7ded3180b730d281c77b765788419484cdfeef/greenlet-3.2.4-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:2917bdf657f5859fbf3386b12d68ede4cf1f04c90c3a6bc1f013dd68a22e2269", size = 1612508 }, - { url = "https://files.pythonhosted.org/packages/0d/da/343cd760ab2f92bac1845ca07ee3faea9fe52bee65f7bcb19f16ad7de08b/greenlet-3.2.4-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:015d48959d4add5d6c9f6c5210ee3803a830dce46356e3bc326d6776bde54681", size = 1680760 }, - { url = "https://files.pythonhosted.org/packages/e3/a5/6ddab2b4c112be95601c13428db1d8b6608a8b6039816f2ba09c346c08fc/greenlet-3.2.4-cp314-cp314-win_amd64.whl", hash = "sha256:e37ab26028f12dbb0ff65f29a8d3d44a765c61e729647bf2ddfbbed621726f01", size = 303425 }, +sdist = { url = "https://files.pythonhosted.org/packages/03/b8/704d753a5a45507a7aab61f18db9509302ed3d0a27ac7e0359ec2905b1a6/greenlet-3.2.4.tar.gz", hash = "sha256:0dca0d95ff849f9a364385f36ab49f50065d76964944638be9691e1832e9f86d", size = 188260, upload-time = "2025-08-07T13:24:33.51Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/49/e8/58c7f85958bda41dafea50497cbd59738c5c43dbbea5ee83d651234398f4/greenlet-3.2.4-cp313-cp313-macosx_11_0_universal2.whl", hash = "sha256:1a921e542453fe531144e91e1feedf12e07351b1cf6c9e8a3325ea600a715a31", size = 272814, upload-time = "2025-08-07T13:15:50.011Z" }, + { url = "https://files.pythonhosted.org/packages/62/dd/b9f59862e9e257a16e4e610480cfffd29e3fae018a68c2332090b53aac3d/greenlet-3.2.4-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:cd3c8e693bff0fff6ba55f140bf390fa92c994083f838fece0f63be121334945", size = 641073, upload-time = "2025-08-07T13:42:57.23Z" }, + { url = "https://files.pythonhosted.org/packages/f7/0b/bc13f787394920b23073ca3b6c4a7a21396301ed75a655bcb47196b50e6e/greenlet-3.2.4-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:710638eb93b1fa52823aa91bf75326f9ecdfd5e0466f00789246a5280f4ba0fc", size = 655191, upload-time = "2025-08-07T13:45:29.752Z" }, + { url = "https://files.pythonhosted.org/packages/f2/d6/6adde57d1345a8d0f14d31e4ab9c23cfe8e2cd39c3baf7674b4b0338d266/greenlet-3.2.4-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:c5111ccdc9c88f423426df3fd1811bfc40ed66264d35aa373420a34377efc98a", size = 649516, upload-time = "2025-08-07T13:53:16.314Z" }, + { url = "https://files.pythonhosted.org/packages/7f/3b/3a3328a788d4a473889a2d403199932be55b1b0060f4ddd96ee7cdfcad10/greenlet-3.2.4-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:d76383238584e9711e20ebe14db6c88ddcedc1829a9ad31a584389463b5aa504", size = 652169, upload-time = "2025-08-07T13:18:32.861Z" }, + { url = "https://files.pythonhosted.org/packages/ee/43/3cecdc0349359e1a527cbf2e3e28e5f8f06d3343aaf82ca13437a9aa290f/greenlet-3.2.4-cp313-cp313-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:23768528f2911bcd7e475210822ffb5254ed10d71f4028387e5a99b4c6699671", size = 610497, upload-time = "2025-08-07T13:18:31.636Z" }, + { url = "https://files.pythonhosted.org/packages/b8/19/06b6cf5d604e2c382a6f31cafafd6f33d5dea706f4db7bdab184bad2b21d/greenlet-3.2.4-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:00fadb3fedccc447f517ee0d3fd8fe49eae949e1cd0f6a611818f4f6fb7dc83b", size = 1121662, upload-time = "2025-08-07T13:42:41.117Z" }, + { url = "https://files.pythonhosted.org/packages/a2/15/0d5e4e1a66fab130d98168fe984c509249c833c1a3c16806b90f253ce7b9/greenlet-3.2.4-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:d25c5091190f2dc0eaa3f950252122edbbadbb682aa7b1ef2f8af0f8c0afefae", size = 1149210, upload-time = "2025-08-07T13:18:24.072Z" }, + { url = "https://files.pythonhosted.org/packages/1c/53/f9c440463b3057485b8594d7a638bed53ba531165ef0ca0e6c364b5cc807/greenlet-3.2.4-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:6e343822feb58ac4d0a1211bd9399de2b3a04963ddeec21530fc426cc121f19b", size = 1564759, upload-time = "2025-11-04T12:42:19.395Z" }, + { url = "https://files.pythonhosted.org/packages/47/e4/3bb4240abdd0a8d23f4f88adec746a3099f0d86bfedb623f063b2e3b4df0/greenlet-3.2.4-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:ca7f6f1f2649b89ce02f6f229d7c19f680a6238af656f61e0115b24857917929", size = 1634288, upload-time = "2025-11-04T12:42:21.174Z" }, + { url = "https://files.pythonhosted.org/packages/0b/55/2321e43595e6801e105fcfdee02b34c0f996eb71e6ddffca6b10b7e1d771/greenlet-3.2.4-cp313-cp313-win_amd64.whl", hash = "sha256:554b03b6e73aaabec3745364d6239e9e012d64c68ccd0b8430c64ccc14939a8b", size = 299685, upload-time = "2025-08-07T13:24:38.824Z" }, + { url = "https://files.pythonhosted.org/packages/22/5c/85273fd7cc388285632b0498dbbab97596e04b154933dfe0f3e68156c68c/greenlet-3.2.4-cp314-cp314-macosx_11_0_universal2.whl", hash = "sha256:49a30d5fda2507ae77be16479bdb62a660fa51b1eb4928b524975b3bde77b3c0", size = 273586, upload-time = "2025-08-07T13:16:08.004Z" }, + { url = "https://files.pythonhosted.org/packages/d1/75/10aeeaa3da9332c2e761e4c50d4c3556c21113ee3f0afa2cf5769946f7a3/greenlet-3.2.4-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:299fd615cd8fc86267b47597123e3f43ad79c9d8a22bebdce535e53550763e2f", size = 686346, upload-time = "2025-08-07T13:42:59.944Z" }, + { url = "https://files.pythonhosted.org/packages/c0/aa/687d6b12ffb505a4447567d1f3abea23bd20e73a5bed63871178e0831b7a/greenlet-3.2.4-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:c17b6b34111ea72fc5a4e4beec9711d2226285f0386ea83477cbb97c30a3f3a5", size = 699218, upload-time = "2025-08-07T13:45:30.969Z" }, + { url = "https://files.pythonhosted.org/packages/dc/8b/29aae55436521f1d6f8ff4e12fb676f3400de7fcf27fccd1d4d17fd8fecd/greenlet-3.2.4-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:b4a1870c51720687af7fa3e7cda6d08d801dae660f75a76f3845b642b4da6ee1", size = 694659, upload-time = "2025-08-07T13:53:17.759Z" }, + { url = "https://files.pythonhosted.org/packages/92/2e/ea25914b1ebfde93b6fc4ff46d6864564fba59024e928bdc7de475affc25/greenlet-3.2.4-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:061dc4cf2c34852b052a8620d40f36324554bc192be474b9e9770e8c042fd735", size = 695355, upload-time = "2025-08-07T13:18:34.517Z" }, + { url = "https://files.pythonhosted.org/packages/72/60/fc56c62046ec17f6b0d3060564562c64c862948c9d4bc8aa807cf5bd74f4/greenlet-3.2.4-cp314-cp314-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:44358b9bf66c8576a9f57a590d5f5d6e72fa4228b763d0e43fee6d3b06d3a337", size = 657512, upload-time = "2025-08-07T13:18:33.969Z" }, + { url = "https://files.pythonhosted.org/packages/23/6e/74407aed965a4ab6ddd93a7ded3180b730d281c77b765788419484cdfeef/greenlet-3.2.4-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:2917bdf657f5859fbf3386b12d68ede4cf1f04c90c3a6bc1f013dd68a22e2269", size = 1612508, upload-time = "2025-11-04T12:42:23.427Z" }, + { url = "https://files.pythonhosted.org/packages/0d/da/343cd760ab2f92bac1845ca07ee3faea9fe52bee65f7bcb19f16ad7de08b/greenlet-3.2.4-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:015d48959d4add5d6c9f6c5210ee3803a830dce46356e3bc326d6776bde54681", size = 1680760, upload-time = "2025-11-04T12:42:25.341Z" }, + { url = "https://files.pythonhosted.org/packages/e3/a5/6ddab2b4c112be95601c13428db1d8b6608a8b6039816f2ba09c346c08fc/greenlet-3.2.4-cp314-cp314-win_amd64.whl", hash = "sha256:e37ab26028f12dbb0ff65f29a8d3d44a765c61e729647bf2ddfbbed621726f01", size = 303425, upload-time = "2025-08-07T13:32:27.59Z" }, ] [[package]] name = "h11" version = "0.16.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/01/ee/02a2c011bdab74c6fb3c75474d40b3052059d95df7e73351460c8588d963/h11-0.16.0.tar.gz", hash = "sha256:4e35b956cf45792e4caa5885e69fba00bdbc6ffafbfa020300e549b208ee5ff1", size = 101250 } +sdist = { url = "https://files.pythonhosted.org/packages/01/ee/02a2c011bdab74c6fb3c75474d40b3052059d95df7e73351460c8588d963/h11-0.16.0.tar.gz", hash = "sha256:4e35b956cf45792e4caa5885e69fba00bdbc6ffafbfa020300e549b208ee5ff1", size = 101250, upload-time = "2025-04-24T03:35:25.427Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/04/4b/29cac41a4d98d144bf5f6d33995617b185d14b22401f75ca86f384e87ff1/h11-0.16.0-py3-none-any.whl", hash = "sha256:63cf8bbe7522de3bf65932fda1d9c2772064ffb3dae62d55932da54b31cb6c86", size = 37515 }, + { url = "https://files.pythonhosted.org/packages/04/4b/29cac41a4d98d144bf5f6d33995617b185d14b22401f75ca86f384e87ff1/h11-0.16.0-py3-none-any.whl", hash = "sha256:63cf8bbe7522de3bf65932fda1d9c2772064ffb3dae62d55932da54b31cb6c86", size = 37515, upload-time = "2025-04-24T03:35:24.344Z" }, ] [[package]] @@ -873,9 +873,9 @@ dependencies = [ { name = "certifi" }, { name = "h11" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/06/94/82699a10bca87a5556c9c59b5963f2d039dbd239f25bc2a63907a05a14cb/httpcore-1.0.9.tar.gz", hash = "sha256:6e34463af53fd2ab5d807f399a9b45ea31c3dfa2276f15a2c3f00afff6e176e8", size = 85484 } +sdist = { url = "https://files.pythonhosted.org/packages/06/94/82699a10bca87a5556c9c59b5963f2d039dbd239f25bc2a63907a05a14cb/httpcore-1.0.9.tar.gz", hash = "sha256:6e34463af53fd2ab5d807f399a9b45ea31c3dfa2276f15a2c3f00afff6e176e8", size = 85484, upload-time = "2025-04-24T22:06:22.219Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/7e/f5/f66802a942d491edb555dd61e3a9961140fd64c90bce1eafd741609d334d/httpcore-1.0.9-py3-none-any.whl", hash = "sha256:2d400746a40668fc9dec9810239072b40b4484b640a8c38fd654a024c7a1bf55", size = 78784 }, + { url = "https://files.pythonhosted.org/packages/7e/f5/f66802a942d491edb555dd61e3a9961140fd64c90bce1eafd741609d334d/httpcore-1.0.9-py3-none-any.whl", hash = "sha256:2d400746a40668fc9dec9810239072b40b4484b640a8c38fd654a024c7a1bf55", size = 78784, upload-time = "2025-04-24T22:06:20.566Z" }, ] [[package]] @@ -885,31 +885,31 @@ source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "pyparsing" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/52/77/6653db69c1f7ecfe5e3f9726fdadc981794656fcd7d98c4209fecfea9993/httplib2-0.31.0.tar.gz", hash = "sha256:ac7ab497c50975147d4f7b1ade44becc7df2f8954d42b38b3d69c515f531135c", size = 250759 } +sdist = { url = "https://files.pythonhosted.org/packages/52/77/6653db69c1f7ecfe5e3f9726fdadc981794656fcd7d98c4209fecfea9993/httplib2-0.31.0.tar.gz", hash = "sha256:ac7ab497c50975147d4f7b1ade44becc7df2f8954d42b38b3d69c515f531135c", size = 250759, upload-time = "2025-09-11T12:16:03.403Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/8c/a2/0d269db0f6163be503775dc8b6a6fa15820cc9fdc866f6ba608d86b721f2/httplib2-0.31.0-py3-none-any.whl", hash = "sha256:b9cd78abea9b4e43a7714c6e0f8b6b8561a6fc1e95d5dbd367f5bf0ef35f5d24", size = 91148 }, + { url = "https://files.pythonhosted.org/packages/8c/a2/0d269db0f6163be503775dc8b6a6fa15820cc9fdc866f6ba608d86b721f2/httplib2-0.31.0-py3-none-any.whl", hash = "sha256:b9cd78abea9b4e43a7714c6e0f8b6b8561a6fc1e95d5dbd367f5bf0ef35f5d24", size = 91148, upload-time = "2025-09-11T12:16:01.803Z" }, ] [[package]] name = "httptools" version = "0.7.1" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/b5/46/120a669232c7bdedb9d52d4aeae7e6c7dfe151e99dc70802e2fc7a5e1993/httptools-0.7.1.tar.gz", hash = "sha256:abd72556974f8e7c74a259655924a717a2365b236c882c3f6f8a45fe94703ac9", size = 258961 } +sdist = { url = "https://files.pythonhosted.org/packages/b5/46/120a669232c7bdedb9d52d4aeae7e6c7dfe151e99dc70802e2fc7a5e1993/httptools-0.7.1.tar.gz", hash = "sha256:abd72556974f8e7c74a259655924a717a2365b236c882c3f6f8a45fe94703ac9", size = 258961, upload-time = "2025-10-10T03:55:08.559Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/09/8f/c77b1fcbfd262d422f12da02feb0d218fa228d52485b77b953832105bb90/httptools-0.7.1-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:6babce6cfa2a99545c60bfef8bee0cc0545413cb0018f617c8059a30ad985de3", size = 202889 }, - { url = "https://files.pythonhosted.org/packages/0a/1a/22887f53602feaa066354867bc49a68fc295c2293433177ee90870a7d517/httptools-0.7.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:601b7628de7504077dd3dcb3791c6b8694bbd967148a6d1f01806509254fb1ca", size = 108180 }, - { url = "https://files.pythonhosted.org/packages/32/6a/6aaa91937f0010d288d3d124ca2946d48d60c3a5ee7ca62afe870e3ea011/httptools-0.7.1-cp313-cp313-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:04c6c0e6c5fb0739c5b8a9eb046d298650a0ff38cf42537fc372b28dc7e4472c", size = 478596 }, - { url = "https://files.pythonhosted.org/packages/6d/70/023d7ce117993107be88d2cbca566a7c1323ccbaf0af7eabf2064fe356f6/httptools-0.7.1-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:69d4f9705c405ae3ee83d6a12283dc9feba8cc6aaec671b412917e644ab4fa66", size = 473268 }, - { url = "https://files.pythonhosted.org/packages/32/4d/9dd616c38da088e3f436e9a616e1d0cc66544b8cdac405cc4e81c8679fc7/httptools-0.7.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:44c8f4347d4b31269c8a9205d8a5ee2df5322b09bbbd30f8f862185bb6b05346", size = 455517 }, - { url = "https://files.pythonhosted.org/packages/1d/3a/a6c595c310b7df958e739aae88724e24f9246a514d909547778d776799be/httptools-0.7.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:465275d76db4d554918aba40bf1cbebe324670f3dfc979eaffaa5d108e2ed650", size = 458337 }, - { url = "https://files.pythonhosted.org/packages/fd/82/88e8d6d2c51edc1cc391b6e044c6c435b6aebe97b1abc33db1b0b24cd582/httptools-0.7.1-cp313-cp313-win_amd64.whl", hash = "sha256:322d00c2068d125bd570f7bf78b2d367dad02b919d8581d7476d8b75b294e3e6", size = 85743 }, - { url = "https://files.pythonhosted.org/packages/34/50/9d095fcbb6de2d523e027a2f304d4551855c2f46e0b82befd718b8b20056/httptools-0.7.1-cp314-cp314-macosx_10_13_universal2.whl", hash = "sha256:c08fe65728b8d70b6923ce31e3956f859d5e1e8548e6f22ec520a962c6757270", size = 203619 }, - { url = "https://files.pythonhosted.org/packages/07/f0/89720dc5139ae54b03f861b5e2c55a37dba9a5da7d51e1e824a1f343627f/httptools-0.7.1-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:7aea2e3c3953521c3c51106ee11487a910d45586e351202474d45472db7d72d3", size = 108714 }, - { url = "https://files.pythonhosted.org/packages/b3/cb/eea88506f191fb552c11787c23f9a405f4c7b0c5799bf73f2249cd4f5228/httptools-0.7.1-cp314-cp314-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:0e68b8582f4ea9166be62926077a3334064d422cf08ab87d8b74664f8e9058e1", size = 472909 }, - { url = "https://files.pythonhosted.org/packages/e0/4a/a548bdfae6369c0d078bab5769f7b66f17f1bfaa6fa28f81d6be6959066b/httptools-0.7.1-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:df091cf961a3be783d6aebae963cc9b71e00d57fa6f149025075217bc6a55a7b", size = 470831 }, - { url = "https://files.pythonhosted.org/packages/4d/31/14df99e1c43bd132eec921c2e7e11cda7852f65619bc0fc5bdc2d0cb126c/httptools-0.7.1-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:f084813239e1eb403ddacd06a30de3d3e09a9b76e7894dcda2b22f8a726e9c60", size = 452631 }, - { url = "https://files.pythonhosted.org/packages/22/d2/b7e131f7be8d854d48cb6d048113c30f9a46dca0c9a8b08fcb3fcd588cdc/httptools-0.7.1-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:7347714368fb2b335e9063bc2b96f2f87a9ceffcd9758ac295f8bbcd3ffbc0ca", size = 452910 }, - { url = "https://files.pythonhosted.org/packages/53/cf/878f3b91e4e6e011eff6d1fa9ca39f7eb17d19c9d7971b04873734112f30/httptools-0.7.1-cp314-cp314-win_amd64.whl", hash = "sha256:cfabda2a5bb85aa2a904ce06d974a3f30fb36cc63d7feaddec05d2050acede96", size = 88205 }, + { url = "https://files.pythonhosted.org/packages/09/8f/c77b1fcbfd262d422f12da02feb0d218fa228d52485b77b953832105bb90/httptools-0.7.1-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:6babce6cfa2a99545c60bfef8bee0cc0545413cb0018f617c8059a30ad985de3", size = 202889, upload-time = "2025-10-10T03:54:47.089Z" }, + { url = "https://files.pythonhosted.org/packages/0a/1a/22887f53602feaa066354867bc49a68fc295c2293433177ee90870a7d517/httptools-0.7.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:601b7628de7504077dd3dcb3791c6b8694bbd967148a6d1f01806509254fb1ca", size = 108180, upload-time = "2025-10-10T03:54:48.052Z" }, + { url = "https://files.pythonhosted.org/packages/32/6a/6aaa91937f0010d288d3d124ca2946d48d60c3a5ee7ca62afe870e3ea011/httptools-0.7.1-cp313-cp313-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:04c6c0e6c5fb0739c5b8a9eb046d298650a0ff38cf42537fc372b28dc7e4472c", size = 478596, upload-time = "2025-10-10T03:54:48.919Z" }, + { url = "https://files.pythonhosted.org/packages/6d/70/023d7ce117993107be88d2cbca566a7c1323ccbaf0af7eabf2064fe356f6/httptools-0.7.1-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:69d4f9705c405ae3ee83d6a12283dc9feba8cc6aaec671b412917e644ab4fa66", size = 473268, upload-time = "2025-10-10T03:54:49.993Z" }, + { url = "https://files.pythonhosted.org/packages/32/4d/9dd616c38da088e3f436e9a616e1d0cc66544b8cdac405cc4e81c8679fc7/httptools-0.7.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:44c8f4347d4b31269c8a9205d8a5ee2df5322b09bbbd30f8f862185bb6b05346", size = 455517, upload-time = "2025-10-10T03:54:51.066Z" }, + { url = "https://files.pythonhosted.org/packages/1d/3a/a6c595c310b7df958e739aae88724e24f9246a514d909547778d776799be/httptools-0.7.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:465275d76db4d554918aba40bf1cbebe324670f3dfc979eaffaa5d108e2ed650", size = 458337, upload-time = "2025-10-10T03:54:52.196Z" }, + { url = "https://files.pythonhosted.org/packages/fd/82/88e8d6d2c51edc1cc391b6e044c6c435b6aebe97b1abc33db1b0b24cd582/httptools-0.7.1-cp313-cp313-win_amd64.whl", hash = "sha256:322d00c2068d125bd570f7bf78b2d367dad02b919d8581d7476d8b75b294e3e6", size = 85743, upload-time = "2025-10-10T03:54:53.448Z" }, + { url = "https://files.pythonhosted.org/packages/34/50/9d095fcbb6de2d523e027a2f304d4551855c2f46e0b82befd718b8b20056/httptools-0.7.1-cp314-cp314-macosx_10_13_universal2.whl", hash = "sha256:c08fe65728b8d70b6923ce31e3956f859d5e1e8548e6f22ec520a962c6757270", size = 203619, upload-time = "2025-10-10T03:54:54.321Z" }, + { url = "https://files.pythonhosted.org/packages/07/f0/89720dc5139ae54b03f861b5e2c55a37dba9a5da7d51e1e824a1f343627f/httptools-0.7.1-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:7aea2e3c3953521c3c51106ee11487a910d45586e351202474d45472db7d72d3", size = 108714, upload-time = "2025-10-10T03:54:55.163Z" }, + { url = "https://files.pythonhosted.org/packages/b3/cb/eea88506f191fb552c11787c23f9a405f4c7b0c5799bf73f2249cd4f5228/httptools-0.7.1-cp314-cp314-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:0e68b8582f4ea9166be62926077a3334064d422cf08ab87d8b74664f8e9058e1", size = 472909, upload-time = "2025-10-10T03:54:56.056Z" }, + { url = "https://files.pythonhosted.org/packages/e0/4a/a548bdfae6369c0d078bab5769f7b66f17f1bfaa6fa28f81d6be6959066b/httptools-0.7.1-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:df091cf961a3be783d6aebae963cc9b71e00d57fa6f149025075217bc6a55a7b", size = 470831, upload-time = "2025-10-10T03:54:57.219Z" }, + { url = "https://files.pythonhosted.org/packages/4d/31/14df99e1c43bd132eec921c2e7e11cda7852f65619bc0fc5bdc2d0cb126c/httptools-0.7.1-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:f084813239e1eb403ddacd06a30de3d3e09a9b76e7894dcda2b22f8a726e9c60", size = 452631, upload-time = "2025-10-10T03:54:58.219Z" }, + { url = "https://files.pythonhosted.org/packages/22/d2/b7e131f7be8d854d48cb6d048113c30f9a46dca0c9a8b08fcb3fcd588cdc/httptools-0.7.1-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:7347714368fb2b335e9063bc2b96f2f87a9ceffcd9758ac295f8bbcd3ffbc0ca", size = 452910, upload-time = "2025-10-10T03:54:59.366Z" }, + { url = "https://files.pythonhosted.org/packages/53/cf/878f3b91e4e6e011eff6d1fa9ca39f7eb17d19c9d7971b04873734112f30/httptools-0.7.1-cp314-cp314-win_amd64.whl", hash = "sha256:cfabda2a5bb85aa2a904ce06d974a3f30fb36cc63d7feaddec05d2050acede96", size = 88205, upload-time = "2025-10-10T03:55:00.389Z" }, ] [[package]] @@ -922,9 +922,9 @@ dependencies = [ { name = "httpcore" }, { name = "idna" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/b1/df/48c586a5fe32a0f01324ee087459e112ebb7224f646c0b5023f5e79e9956/httpx-0.28.1.tar.gz", hash = "sha256:75e98c5f16b0f35b567856f597f06ff2270a374470a5c2392242528e3e3e42fc", size = 141406 } +sdist = { url = "https://files.pythonhosted.org/packages/b1/df/48c586a5fe32a0f01324ee087459e112ebb7224f646c0b5023f5e79e9956/httpx-0.28.1.tar.gz", hash = "sha256:75e98c5f16b0f35b567856f597f06ff2270a374470a5c2392242528e3e3e42fc", size = 141406, upload-time = "2024-12-06T15:37:23.222Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/2a/39/e50c7c3a983047577ee07d2a9e53faf5a69493943ec3f6a384bdc792deb2/httpx-0.28.1-py3-none-any.whl", hash = "sha256:d909fcccc110f8c7faf814ca82a9a4d816bc5a6dbfea25d6591d6985b8ba59ad", size = 73517 }, + { url = "https://files.pythonhosted.org/packages/2a/39/e50c7c3a983047577ee07d2a9e53faf5a69493943ec3f6a384bdc792deb2/httpx-0.28.1-py3-none-any.whl", hash = "sha256:d909fcccc110f8c7faf814ca82a9a4d816bc5a6dbfea25d6591d6985b8ba59ad", size = 73517, upload-time = "2024-12-06T15:37:21.509Z" }, ] [[package]] @@ -934,9 +934,9 @@ source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "httpx" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/2f/07/db4ad128da3926be22eec586aa87dafd8840c9eb03fe88505fbed016b5c6/httpx_oauth-0.16.1.tar.gz", hash = "sha256:7402f061f860abc092ea4f5c90acfc576a40bbb79633c1d2920f1ca282c296ee", size = 44148 } +sdist = { url = "https://files.pythonhosted.org/packages/2f/07/db4ad128da3926be22eec586aa87dafd8840c9eb03fe88505fbed016b5c6/httpx_oauth-0.16.1.tar.gz", hash = "sha256:7402f061f860abc092ea4f5c90acfc576a40bbb79633c1d2920f1ca282c296ee", size = 44148, upload-time = "2024-12-20T07:23:02.589Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/45/4b/2b81e876abf77b4af3372aff731f4f6722840ebc7dcfd85778eaba271733/httpx_oauth-0.16.1-py3-none-any.whl", hash = "sha256:2fcad82f80f28d0473a0fc4b4eda223dc952050af7e3a8c8781342d850f09fb5", size = 38056 }, + { url = "https://files.pythonhosted.org/packages/45/4b/2b81e876abf77b4af3372aff731f4f6722840ebc7dcfd85778eaba271733/httpx_oauth-0.16.1-py3-none-any.whl", hash = "sha256:2fcad82f80f28d0473a0fc4b4eda223dc952050af7e3a8c8781342d850f09fb5", size = 38056, upload-time = "2024-12-20T07:23:00.394Z" }, ] [[package]] @@ -946,36 +946,36 @@ source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "pyreadline3", marker = "sys_platform == 'win32'" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/cc/3f/2c29224acb2e2df4d2046e4c73ee2662023c58ff5b113c4c1adac0886c43/humanfriendly-10.0.tar.gz", hash = "sha256:6b0b831ce8f15f7300721aa49829fc4e83921a9a301cc7f606be6686a2288ddc", size = 360702 } +sdist = { url = "https://files.pythonhosted.org/packages/cc/3f/2c29224acb2e2df4d2046e4c73ee2662023c58ff5b113c4c1adac0886c43/humanfriendly-10.0.tar.gz", hash = "sha256:6b0b831ce8f15f7300721aa49829fc4e83921a9a301cc7f606be6686a2288ddc", size = 360702, upload-time = "2021-09-17T21:40:43.31Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/f0/0f/310fb31e39e2d734ccaa2c0fb981ee41f7bd5056ce9bc29b2248bd569169/humanfriendly-10.0-py2.py3-none-any.whl", hash = "sha256:1697e1a8a8f550fd43c2865cd84542fc175a61dcb779b6fee18cf6b6ccba1477", size = 86794 }, + { url = "https://files.pythonhosted.org/packages/f0/0f/310fb31e39e2d734ccaa2c0fb981ee41f7bd5056ce9bc29b2248bd569169/humanfriendly-10.0-py2.py3-none-any.whl", hash = "sha256:1697e1a8a8f550fd43c2865cd84542fc175a61dcb779b6fee18cf6b6ccba1477", size = 86794, upload-time = "2021-09-17T21:40:39.897Z" }, ] [[package]] name = "idna" version = "3.11" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/6f/6d/0703ccc57f3a7233505399edb88de3cbd678da106337b9fcde432b65ed60/idna-3.11.tar.gz", hash = "sha256:795dafcc9c04ed0c1fb032c2aa73654d8e8c5023a7df64a53f39190ada629902", size = 194582 } +sdist = { url = "https://files.pythonhosted.org/packages/6f/6d/0703ccc57f3a7233505399edb88de3cbd678da106337b9fcde432b65ed60/idna-3.11.tar.gz", hash = "sha256:795dafcc9c04ed0c1fb032c2aa73654d8e8c5023a7df64a53f39190ada629902", size = 194582, upload-time = "2025-10-12T14:55:20.501Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/0e/61/66938bbb5fc52dbdf84594873d5b51fb1f7c7794e9c0f5bd885f30bc507b/idna-3.11-py3-none-any.whl", hash = "sha256:771a87f49d9defaf64091e6e6fe9c18d4833f140bd19464795bc32d966ca37ea", size = 71008 }, + { url = "https://files.pythonhosted.org/packages/0e/61/66938bbb5fc52dbdf84594873d5b51fb1f7c7794e9c0f5bd885f30bc507b/idna-3.11-py3-none-any.whl", hash = "sha256:771a87f49d9defaf64091e6e6fe9c18d4833f140bd19464795bc32d966ca37ea", size = 71008, upload-time = "2025-10-12T14:55:18.883Z" }, ] [[package]] name = "iniconfig" version = "2.3.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/72/34/14ca021ce8e5dfedc35312d08ba8bf51fdd999c576889fc2c24cb97f4f10/iniconfig-2.3.0.tar.gz", hash = "sha256:c76315c77db068650d49c5b56314774a7804df16fee4402c1f19d6d15d8c4730", size = 20503 } +sdist = { url = "https://files.pythonhosted.org/packages/72/34/14ca021ce8e5dfedc35312d08ba8bf51fdd999c576889fc2c24cb97f4f10/iniconfig-2.3.0.tar.gz", hash = "sha256:c76315c77db068650d49c5b56314774a7804df16fee4402c1f19d6d15d8c4730", size = 20503, upload-time = "2025-10-18T21:55:43.219Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/cb/b1/3846dd7f199d53cb17f49cba7e651e9ce294d8497c8c150530ed11865bb8/iniconfig-2.3.0-py3-none-any.whl", hash = "sha256:f631c04d2c48c52b84d0d0549c99ff3859c98df65b3101406327ecc7d53fbf12", size = 7484 }, + { url = "https://files.pythonhosted.org/packages/cb/b1/3846dd7f199d53cb17f49cba7e651e9ce294d8497c8c150530ed11865bb8/iniconfig-2.3.0-py3-none-any.whl", hash = "sha256:f631c04d2c48c52b84d0d0549c99ff3859c98df65b3101406327ecc7d53fbf12", size = 7484, upload-time = "2025-10-18T21:55:41.639Z" }, ] [[package]] name = "itsdangerous" version = "2.2.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/9c/cb/8ac0172223afbccb63986cc25049b154ecfb5e85932587206f42317be31d/itsdangerous-2.2.0.tar.gz", hash = "sha256:e0050c0b7da1eea53ffaf149c0cfbb5c6e2e2b69c4bef22c81fa6eb73e5f6173", size = 54410 } +sdist = { url = "https://files.pythonhosted.org/packages/9c/cb/8ac0172223afbccb63986cc25049b154ecfb5e85932587206f42317be31d/itsdangerous-2.2.0.tar.gz", hash = "sha256:e0050c0b7da1eea53ffaf149c0cfbb5c6e2e2b69c4bef22c81fa6eb73e5f6173", size = 54410, upload-time = "2024-04-16T21:28:15.614Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/04/96/92447566d16df59b2a776c0fb82dbc4d9e07cd95062562af01e408583fc4/itsdangerous-2.2.0-py3-none-any.whl", hash = "sha256:c6242fc49e35958c8b15141343aa660db5fc54d4f13a1db01a3f5891b98700ef", size = 16234 }, + { url = "https://files.pythonhosted.org/packages/04/96/92447566d16df59b2a776c0fb82dbc4d9e07cd95062562af01e408583fc4/itsdangerous-2.2.0-py3-none-any.whl", hash = "sha256:c6242fc49e35958c8b15141343aa660db5fc54d4f13a1db01a3f5891b98700ef", size = 16234, upload-time = "2024-04-16T21:28:14.499Z" }, ] [[package]] @@ -985,27 +985,27 @@ source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "markupsafe" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/df/bf/f7da0350254c0ed7c72f3e33cef02e048281fec7ecec5f032d4aac52226b/jinja2-3.1.6.tar.gz", hash = "sha256:0137fb05990d35f1275a587e9aee6d56da821fc83491a0fb838183be43f66d6d", size = 245115 } +sdist = { url = "https://files.pythonhosted.org/packages/df/bf/f7da0350254c0ed7c72f3e33cef02e048281fec7ecec5f032d4aac52226b/jinja2-3.1.6.tar.gz", hash = "sha256:0137fb05990d35f1275a587e9aee6d56da821fc83491a0fb838183be43f66d6d", size = 245115, upload-time = "2025-03-05T20:05:02.478Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/62/a1/3d680cbfd5f4b8f15abc1d571870c5fc3e594bb582bc3b64ea099db13e56/jinja2-3.1.6-py3-none-any.whl", hash = "sha256:85ece4451f492d0c13c5dd7c13a64681a86afae63a5f347908daf103ce6d2f67", size = 134899 }, + { url = "https://files.pythonhosted.org/packages/62/a1/3d680cbfd5f4b8f15abc1d571870c5fc3e594bb582bc3b64ea099db13e56/jinja2-3.1.6-py3-none-any.whl", hash = "sha256:85ece4451f492d0c13c5dd7c13a64681a86afae63a5f347908daf103ce6d2f67", size = 134899, upload-time = "2025-03-05T20:05:00.369Z" }, ] [[package]] name = "jmespath" version = "1.0.1" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/00/2a/e867e8531cf3e36b41201936b7fa7ba7b5702dbef42922193f05c8976cd6/jmespath-1.0.1.tar.gz", hash = "sha256:90261b206d6defd58fdd5e85f478bf633a2901798906be2ad389150c5c60edbe", size = 25843 } +sdist = { url = "https://files.pythonhosted.org/packages/00/2a/e867e8531cf3e36b41201936b7fa7ba7b5702dbef42922193f05c8976cd6/jmespath-1.0.1.tar.gz", hash = "sha256:90261b206d6defd58fdd5e85f478bf633a2901798906be2ad389150c5c60edbe", size = 25843, upload-time = "2022-06-17T18:00:12.224Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/31/b4/b9b800c45527aadd64d5b442f9b932b00648617eb5d63d2c7a6587b7cafc/jmespath-1.0.1-py3-none-any.whl", hash = "sha256:02e2e4cc71b5bcab88332eebf907519190dd9e6e82107fa7f83b1003a6252980", size = 20256 }, + { url = "https://files.pythonhosted.org/packages/31/b4/b9b800c45527aadd64d5b442f9b932b00648617eb5d63d2c7a6587b7cafc/jmespath-1.0.1-py3-none-any.whl", hash = "sha256:02e2e4cc71b5bcab88332eebf907519190dd9e6e82107fa7f83b1003a6252980", size = 20256, upload-time = "2022-06-17T18:00:10.251Z" }, ] [[package]] name = "makefun" version = "1.16.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/7b/cf/6780ab8bc3b84a1cce3e4400aed3d64b6db7d5e227a2f75b6ded5674701a/makefun-1.16.0.tar.gz", hash = "sha256:e14601831570bff1f6d7e68828bcd30d2f5856f24bad5de0ccb22921ceebc947", size = 73565 } +sdist = { url = "https://files.pythonhosted.org/packages/7b/cf/6780ab8bc3b84a1cce3e4400aed3d64b6db7d5e227a2f75b6ded5674701a/makefun-1.16.0.tar.gz", hash = "sha256:e14601831570bff1f6d7e68828bcd30d2f5856f24bad5de0ccb22921ceebc947", size = 73565, upload-time = "2025-05-09T15:00:42.313Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/b7/c0/4bc973defd1270b89ccaae04cef0d5fa3ea85b59b108ad2c08aeea9afb76/makefun-1.16.0-py2.py3-none-any.whl", hash = "sha256:43baa4c3e7ae2b17de9ceac20b669e9a67ceeadff31581007cca20a07bbe42c4", size = 22923 }, + { url = "https://files.pythonhosted.org/packages/b7/c0/4bc973defd1270b89ccaae04cef0d5fa3ea85b59b108ad2c08aeea9afb76/makefun-1.16.0-py2.py3-none-any.whl", hash = "sha256:43baa4c3e7ae2b17de9ceac20b669e9a67ceeadff31581007cca20a07bbe42c4", size = 22923, upload-time = "2025-05-09T15:00:41.042Z" }, ] [[package]] @@ -1015,18 +1015,18 @@ source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "markupsafe" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/9e/38/bd5b78a920a64d708fe6bc8e0a2c075e1389d53bef8413725c63ba041535/mako-1.3.10.tar.gz", hash = "sha256:99579a6f39583fa7e5630a28c3c1f440e4e97a414b80372649c0ce338da2ea28", size = 392474 } +sdist = { url = "https://files.pythonhosted.org/packages/9e/38/bd5b78a920a64d708fe6bc8e0a2c075e1389d53bef8413725c63ba041535/mako-1.3.10.tar.gz", hash = "sha256:99579a6f39583fa7e5630a28c3c1f440e4e97a414b80372649c0ce338da2ea28", size = 392474, upload-time = "2025-04-10T12:44:31.16Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/87/fb/99f81ac72ae23375f22b7afdb7642aba97c00a713c217124420147681a2f/mako-1.3.10-py3-none-any.whl", hash = "sha256:baef24a52fc4fc514a0887ac600f9f1cff3d82c61d4d700a1fa84d597b88db59", size = 78509 }, + { url = "https://files.pythonhosted.org/packages/87/fb/99f81ac72ae23375f22b7afdb7642aba97c00a713c217124420147681a2f/mako-1.3.10-py3-none-any.whl", hash = "sha256:baef24a52fc4fc514a0887ac600f9f1cff3d82c61d4d700a1fa84d597b88db59", size = 78509, upload-time = "2025-04-10T12:50:53.297Z" }, ] [[package]] name = "markdown" version = "3.10" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/7d/ab/7dd27d9d863b3376fcf23a5a13cb5d024aed1db46f963f1b5735ae43b3be/markdown-3.10.tar.gz", hash = "sha256:37062d4f2aa4b2b6b32aefb80faa300f82cc790cb949a35b8caede34f2b68c0e", size = 364931 } +sdist = { url = "https://files.pythonhosted.org/packages/7d/ab/7dd27d9d863b3376fcf23a5a13cb5d024aed1db46f963f1b5735ae43b3be/markdown-3.10.tar.gz", hash = "sha256:37062d4f2aa4b2b6b32aefb80faa300f82cc790cb949a35b8caede34f2b68c0e", size = 364931, upload-time = "2025-11-03T19:51:15.007Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/70/81/54e3ce63502cd085a0c556652a4e1b919c45a446bd1e5300e10c44c8c521/markdown-3.10-py3-none-any.whl", hash = "sha256:b5b99d6951e2e4948d939255596523444c0e677c669700b1d17aa4a8a464cb7c", size = 107678 }, + { url = "https://files.pythonhosted.org/packages/70/81/54e3ce63502cd085a0c556652a4e1b919c45a446bd1e5300e10c44c8c521/markdown-3.10-py3-none-any.whl", hash = "sha256:b5b99d6951e2e4948d939255596523444c0e677c669700b1d17aa4a8a464cb7c", size = 107678, upload-time = "2025-11-03T19:51:13.887Z" }, ] [[package]] @@ -1036,70 +1036,70 @@ source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "mdurl" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/5b/f5/4ec618ed16cc4f8fb3b701563655a69816155e79e24a17b651541804721d/markdown_it_py-4.0.0.tar.gz", hash = "sha256:cb0a2b4aa34f932c007117b194e945bd74e0ec24133ceb5bac59009cda1cb9f3", size = 73070 } +sdist = { url = "https://files.pythonhosted.org/packages/5b/f5/4ec618ed16cc4f8fb3b701563655a69816155e79e24a17b651541804721d/markdown_it_py-4.0.0.tar.gz", hash = "sha256:cb0a2b4aa34f932c007117b194e945bd74e0ec24133ceb5bac59009cda1cb9f3", size = 73070, upload-time = "2025-08-11T12:57:52.854Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/94/54/e7d793b573f298e1c9013b8c4dade17d481164aa517d1d7148619c2cedbf/markdown_it_py-4.0.0-py3-none-any.whl", hash = "sha256:87327c59b172c5011896038353a81343b6754500a08cd7a4973bb48c6d578147", size = 87321 }, + { url = "https://files.pythonhosted.org/packages/94/54/e7d793b573f298e1c9013b8c4dade17d481164aa517d1d7148619c2cedbf/markdown_it_py-4.0.0-py3-none-any.whl", hash = "sha256:87327c59b172c5011896038353a81343b6754500a08cd7a4973bb48c6d578147", size = 87321, upload-time = "2025-08-11T12:57:51.923Z" }, ] [[package]] name = "markupsafe" version = "3.0.3" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/7e/99/7690b6d4034fffd95959cbe0c02de8deb3098cc577c67bb6a24fe5d7caa7/markupsafe-3.0.3.tar.gz", hash = "sha256:722695808f4b6457b320fdc131280796bdceb04ab50fe1795cd540799ebe1698", size = 80313 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/38/2f/907b9c7bbba283e68f20259574b13d005c121a0fa4c175f9bed27c4597ff/markupsafe-3.0.3-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:e1cf1972137e83c5d4c136c43ced9ac51d0e124706ee1c8aa8532c1287fa8795", size = 11622 }, - { url = "https://files.pythonhosted.org/packages/9c/d9/5f7756922cdd676869eca1c4e3c0cd0df60ed30199ffd775e319089cb3ed/markupsafe-3.0.3-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:116bb52f642a37c115f517494ea5feb03889e04df47eeff5b130b1808ce7c219", size = 12029 }, - { url = "https://files.pythonhosted.org/packages/00/07/575a68c754943058c78f30db02ee03a64b3c638586fba6a6dd56830b30a3/markupsafe-3.0.3-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:133a43e73a802c5562be9bbcd03d090aa5a1fe899db609c29e8c8d815c5f6de6", size = 24374 }, - { url = "https://files.pythonhosted.org/packages/a9/21/9b05698b46f218fc0e118e1f8168395c65c8a2c750ae2bab54fc4bd4e0e8/markupsafe-3.0.3-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:ccfcd093f13f0f0b7fdd0f198b90053bf7b2f02a3927a30e63f3ccc9df56b676", size = 22980 }, - { url = "https://files.pythonhosted.org/packages/7f/71/544260864f893f18b6827315b988c146b559391e6e7e8f7252839b1b846a/markupsafe-3.0.3-cp313-cp313-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:509fa21c6deb7a7a273d629cf5ec029bc209d1a51178615ddf718f5918992ab9", size = 21990 }, - { url = "https://files.pythonhosted.org/packages/c2/28/b50fc2f74d1ad761af2f5dcce7492648b983d00a65b8c0e0cb457c82ebbe/markupsafe-3.0.3-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:a4afe79fb3de0b7097d81da19090f4df4f8d3a2b3adaa8764138aac2e44f3af1", size = 23784 }, - { url = "https://files.pythonhosted.org/packages/ed/76/104b2aa106a208da8b17a2fb72e033a5a9d7073c68f7e508b94916ed47a9/markupsafe-3.0.3-cp313-cp313-musllinux_1_2_riscv64.whl", hash = "sha256:795e7751525cae078558e679d646ae45574b47ed6e7771863fcc079a6171a0fc", size = 21588 }, - { url = "https://files.pythonhosted.org/packages/b5/99/16a5eb2d140087ebd97180d95249b00a03aa87e29cc224056274f2e45fd6/markupsafe-3.0.3-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:8485f406a96febb5140bfeca44a73e3ce5116b2501ac54fe953e488fb1d03b12", size = 23041 }, - { url = "https://files.pythonhosted.org/packages/19/bc/e7140ed90c5d61d77cea142eed9f9c303f4c4806f60a1044c13e3f1471d0/markupsafe-3.0.3-cp313-cp313-win32.whl", hash = "sha256:bdd37121970bfd8be76c5fb069c7751683bdf373db1ed6c010162b2a130248ed", size = 14543 }, - { url = "https://files.pythonhosted.org/packages/05/73/c4abe620b841b6b791f2edc248f556900667a5a1cf023a6646967ae98335/markupsafe-3.0.3-cp313-cp313-win_amd64.whl", hash = "sha256:9a1abfdc021a164803f4d485104931fb8f8c1efd55bc6b748d2f5774e78b62c5", size = 15113 }, - { url = "https://files.pythonhosted.org/packages/f0/3a/fa34a0f7cfef23cf9500d68cb7c32dd64ffd58a12b09225fb03dd37d5b80/markupsafe-3.0.3-cp313-cp313-win_arm64.whl", hash = "sha256:7e68f88e5b8799aa49c85cd116c932a1ac15caaa3f5db09087854d218359e485", size = 13911 }, - { url = "https://files.pythonhosted.org/packages/e4/d7/e05cd7efe43a88a17a37b3ae96e79a19e846f3f456fe79c57ca61356ef01/markupsafe-3.0.3-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:218551f6df4868a8d527e3062d0fb968682fe92054e89978594c28e642c43a73", size = 11658 }, - { url = "https://files.pythonhosted.org/packages/99/9e/e412117548182ce2148bdeacdda3bb494260c0b0184360fe0d56389b523b/markupsafe-3.0.3-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:3524b778fe5cfb3452a09d31e7b5adefeea8c5be1d43c4f810ba09f2ceb29d37", size = 12066 }, - { url = "https://files.pythonhosted.org/packages/bc/e6/fa0ffcda717ef64a5108eaa7b4f5ed28d56122c9a6d70ab8b72f9f715c80/markupsafe-3.0.3-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:4e885a3d1efa2eadc93c894a21770e4bc67899e3543680313b09f139e149ab19", size = 25639 }, - { url = "https://files.pythonhosted.org/packages/96/ec/2102e881fe9d25fc16cb4b25d5f5cde50970967ffa5dddafdb771237062d/markupsafe-3.0.3-cp313-cp313t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:8709b08f4a89aa7586de0aadc8da56180242ee0ada3999749b183aa23df95025", size = 23569 }, - { url = "https://files.pythonhosted.org/packages/4b/30/6f2fce1f1f205fc9323255b216ca8a235b15860c34b6798f810f05828e32/markupsafe-3.0.3-cp313-cp313t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:b8512a91625c9b3da6f127803b166b629725e68af71f8184ae7e7d54686a56d6", size = 23284 }, - { url = "https://files.pythonhosted.org/packages/58/47/4a0ccea4ab9f5dcb6f79c0236d954acb382202721e704223a8aafa38b5c8/markupsafe-3.0.3-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:9b79b7a16f7fedff2495d684f2b59b0457c3b493778c9eed31111be64d58279f", size = 24801 }, - { url = "https://files.pythonhosted.org/packages/6a/70/3780e9b72180b6fecb83a4814d84c3bf4b4ae4bf0b19c27196104149734c/markupsafe-3.0.3-cp313-cp313t-musllinux_1_2_riscv64.whl", hash = "sha256:12c63dfb4a98206f045aa9563db46507995f7ef6d83b2f68eda65c307c6829eb", size = 22769 }, - { url = "https://files.pythonhosted.org/packages/98/c5/c03c7f4125180fc215220c035beac6b9cb684bc7a067c84fc69414d315f5/markupsafe-3.0.3-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:8f71bc33915be5186016f675cd83a1e08523649b0e33efdb898db577ef5bb009", size = 23642 }, - { url = "https://files.pythonhosted.org/packages/80/d6/2d1b89f6ca4bff1036499b1e29a1d02d282259f3681540e16563f27ebc23/markupsafe-3.0.3-cp313-cp313t-win32.whl", hash = "sha256:69c0b73548bc525c8cb9a251cddf1931d1db4d2258e9599c28c07ef3580ef354", size = 14612 }, - { url = "https://files.pythonhosted.org/packages/2b/98/e48a4bfba0a0ffcf9925fe2d69240bfaa19c6f7507b8cd09c70684a53c1e/markupsafe-3.0.3-cp313-cp313t-win_amd64.whl", hash = "sha256:1b4b79e8ebf6b55351f0d91fe80f893b4743f104bff22e90697db1590e47a218", size = 15200 }, - { url = "https://files.pythonhosted.org/packages/0e/72/e3cc540f351f316e9ed0f092757459afbc595824ca724cbc5a5d4263713f/markupsafe-3.0.3-cp313-cp313t-win_arm64.whl", hash = "sha256:ad2cf8aa28b8c020ab2fc8287b0f823d0a7d8630784c31e9ee5edea20f406287", size = 13973 }, - { url = "https://files.pythonhosted.org/packages/33/8a/8e42d4838cd89b7dde187011e97fe6c3af66d8c044997d2183fbd6d31352/markupsafe-3.0.3-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:eaa9599de571d72e2daf60164784109f19978b327a3910d3e9de8c97b5b70cfe", size = 11619 }, - { url = "https://files.pythonhosted.org/packages/b5/64/7660f8a4a8e53c924d0fa05dc3a55c9cee10bbd82b11c5afb27d44b096ce/markupsafe-3.0.3-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:c47a551199eb8eb2121d4f0f15ae0f923d31350ab9280078d1e5f12b249e0026", size = 12029 }, - { url = "https://files.pythonhosted.org/packages/da/ef/e648bfd021127bef5fa12e1720ffed0c6cbb8310c8d9bea7266337ff06de/markupsafe-3.0.3-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:f34c41761022dd093b4b6896d4810782ffbabe30f2d443ff5f083e0cbbb8c737", size = 24408 }, - { url = "https://files.pythonhosted.org/packages/41/3c/a36c2450754618e62008bf7435ccb0f88053e07592e6028a34776213d877/markupsafe-3.0.3-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:457a69a9577064c05a97c41f4e65148652db078a3a509039e64d3467b9e7ef97", size = 23005 }, - { url = "https://files.pythonhosted.org/packages/bc/20/b7fdf89a8456b099837cd1dc21974632a02a999ec9bf7ca3e490aacd98e7/markupsafe-3.0.3-cp314-cp314-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:e8afc3f2ccfa24215f8cb28dcf43f0113ac3c37c2f0f0806d8c70e4228c5cf4d", size = 22048 }, - { url = "https://files.pythonhosted.org/packages/9a/a7/591f592afdc734f47db08a75793a55d7fbcc6902a723ae4cfbab61010cc5/markupsafe-3.0.3-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:ec15a59cf5af7be74194f7ab02d0f59a62bdcf1a537677ce67a2537c9b87fcda", size = 23821 }, - { url = "https://files.pythonhosted.org/packages/7d/33/45b24e4f44195b26521bc6f1a82197118f74df348556594bd2262bda1038/markupsafe-3.0.3-cp314-cp314-musllinux_1_2_riscv64.whl", hash = "sha256:0eb9ff8191e8498cca014656ae6b8d61f39da5f95b488805da4bb029cccbfbaf", size = 21606 }, - { url = "https://files.pythonhosted.org/packages/ff/0e/53dfaca23a69fbfbbf17a4b64072090e70717344c52eaaaa9c5ddff1e5f0/markupsafe-3.0.3-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:2713baf880df847f2bece4230d4d094280f4e67b1e813eec43b4c0e144a34ffe", size = 23043 }, - { url = "https://files.pythonhosted.org/packages/46/11/f333a06fc16236d5238bfe74daccbca41459dcd8d1fa952e8fbd5dccfb70/markupsafe-3.0.3-cp314-cp314-win32.whl", hash = "sha256:729586769a26dbceff69f7a7dbbf59ab6572b99d94576a5592625d5b411576b9", size = 14747 }, - { url = "https://files.pythonhosted.org/packages/28/52/182836104b33b444e400b14f797212f720cbc9ed6ba34c800639d154e821/markupsafe-3.0.3-cp314-cp314-win_amd64.whl", hash = "sha256:bdc919ead48f234740ad807933cdf545180bfbe9342c2bb451556db2ed958581", size = 15341 }, - { url = "https://files.pythonhosted.org/packages/6f/18/acf23e91bd94fd7b3031558b1f013adfa21a8e407a3fdb32745538730382/markupsafe-3.0.3-cp314-cp314-win_arm64.whl", hash = "sha256:5a7d5dc5140555cf21a6fefbdbf8723f06fcd2f63ef108f2854de715e4422cb4", size = 14073 }, - { url = "https://files.pythonhosted.org/packages/3c/f0/57689aa4076e1b43b15fdfa646b04653969d50cf30c32a102762be2485da/markupsafe-3.0.3-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:1353ef0c1b138e1907ae78e2f6c63ff67501122006b0f9abad68fda5f4ffc6ab", size = 11661 }, - { url = "https://files.pythonhosted.org/packages/89/c3/2e67a7ca217c6912985ec766c6393b636fb0c2344443ff9d91404dc4c79f/markupsafe-3.0.3-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:1085e7fbddd3be5f89cc898938f42c0b3c711fdcb37d75221de2666af647c175", size = 12069 }, - { url = "https://files.pythonhosted.org/packages/f0/00/be561dce4e6ca66b15276e184ce4b8aec61fe83662cce2f7d72bd3249d28/markupsafe-3.0.3-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:1b52b4fb9df4eb9ae465f8d0c228a00624de2334f216f178a995ccdcf82c4634", size = 25670 }, - { url = "https://files.pythonhosted.org/packages/50/09/c419f6f5a92e5fadde27efd190eca90f05e1261b10dbd8cbcb39cd8ea1dc/markupsafe-3.0.3-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:fed51ac40f757d41b7c48425901843666a6677e3e8eb0abcff09e4ba6e664f50", size = 23598 }, - { url = "https://files.pythonhosted.org/packages/22/44/a0681611106e0b2921b3033fc19bc53323e0b50bc70cffdd19f7d679bb66/markupsafe-3.0.3-cp314-cp314t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:f190daf01f13c72eac4efd5c430a8de82489d9cff23c364c3ea822545032993e", size = 23261 }, - { url = "https://files.pythonhosted.org/packages/5f/57/1b0b3f100259dc9fffe780cfb60d4be71375510e435efec3d116b6436d43/markupsafe-3.0.3-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:e56b7d45a839a697b5eb268c82a71bd8c7f6c94d6fd50c3d577fa39a9f1409f5", size = 24835 }, - { url = "https://files.pythonhosted.org/packages/26/6a/4bf6d0c97c4920f1597cc14dd720705eca0bf7c787aebc6bb4d1bead5388/markupsafe-3.0.3-cp314-cp314t-musllinux_1_2_riscv64.whl", hash = "sha256:f3e98bb3798ead92273dc0e5fd0f31ade220f59a266ffd8a4f6065e0a3ce0523", size = 22733 }, - { url = "https://files.pythonhosted.org/packages/14/c7/ca723101509b518797fedc2fdf79ba57f886b4aca8a7d31857ba3ee8281f/markupsafe-3.0.3-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:5678211cb9333a6468fb8d8be0305520aa073f50d17f089b5b4b477ea6e67fdc", size = 23672 }, - { url = "https://files.pythonhosted.org/packages/fb/df/5bd7a48c256faecd1d36edc13133e51397e41b73bb77e1a69deab746ebac/markupsafe-3.0.3-cp314-cp314t-win32.whl", hash = "sha256:915c04ba3851909ce68ccc2b8e2cd691618c4dc4c4232fb7982bca3f41fd8c3d", size = 14819 }, - { url = "https://files.pythonhosted.org/packages/1a/8a/0402ba61a2f16038b48b39bccca271134be00c5c9f0f623208399333c448/markupsafe-3.0.3-cp314-cp314t-win_amd64.whl", hash = "sha256:4faffd047e07c38848ce017e8725090413cd80cbc23d86e55c587bf979e579c9", size = 15426 }, - { url = "https://files.pythonhosted.org/packages/70/bc/6f1c2f612465f5fa89b95bead1f44dcb607670fd42891d8fdcd5d039f4f4/markupsafe-3.0.3-cp314-cp314t-win_arm64.whl", hash = "sha256:32001d6a8fc98c8cb5c947787c5d08b0a50663d139f1305bac5885d98d9b40fa", size = 14146 }, +sdist = { url = "https://files.pythonhosted.org/packages/7e/99/7690b6d4034fffd95959cbe0c02de8deb3098cc577c67bb6a24fe5d7caa7/markupsafe-3.0.3.tar.gz", hash = "sha256:722695808f4b6457b320fdc131280796bdceb04ab50fe1795cd540799ebe1698", size = 80313, upload-time = "2025-09-27T18:37:40.426Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/38/2f/907b9c7bbba283e68f20259574b13d005c121a0fa4c175f9bed27c4597ff/markupsafe-3.0.3-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:e1cf1972137e83c5d4c136c43ced9ac51d0e124706ee1c8aa8532c1287fa8795", size = 11622, upload-time = "2025-09-27T18:36:41.777Z" }, + { url = "https://files.pythonhosted.org/packages/9c/d9/5f7756922cdd676869eca1c4e3c0cd0df60ed30199ffd775e319089cb3ed/markupsafe-3.0.3-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:116bb52f642a37c115f517494ea5feb03889e04df47eeff5b130b1808ce7c219", size = 12029, upload-time = "2025-09-27T18:36:43.257Z" }, + { url = "https://files.pythonhosted.org/packages/00/07/575a68c754943058c78f30db02ee03a64b3c638586fba6a6dd56830b30a3/markupsafe-3.0.3-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:133a43e73a802c5562be9bbcd03d090aa5a1fe899db609c29e8c8d815c5f6de6", size = 24374, upload-time = "2025-09-27T18:36:44.508Z" }, + { url = "https://files.pythonhosted.org/packages/a9/21/9b05698b46f218fc0e118e1f8168395c65c8a2c750ae2bab54fc4bd4e0e8/markupsafe-3.0.3-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:ccfcd093f13f0f0b7fdd0f198b90053bf7b2f02a3927a30e63f3ccc9df56b676", size = 22980, upload-time = "2025-09-27T18:36:45.385Z" }, + { url = "https://files.pythonhosted.org/packages/7f/71/544260864f893f18b6827315b988c146b559391e6e7e8f7252839b1b846a/markupsafe-3.0.3-cp313-cp313-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:509fa21c6deb7a7a273d629cf5ec029bc209d1a51178615ddf718f5918992ab9", size = 21990, upload-time = "2025-09-27T18:36:46.916Z" }, + { url = "https://files.pythonhosted.org/packages/c2/28/b50fc2f74d1ad761af2f5dcce7492648b983d00a65b8c0e0cb457c82ebbe/markupsafe-3.0.3-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:a4afe79fb3de0b7097d81da19090f4df4f8d3a2b3adaa8764138aac2e44f3af1", size = 23784, upload-time = "2025-09-27T18:36:47.884Z" }, + { url = "https://files.pythonhosted.org/packages/ed/76/104b2aa106a208da8b17a2fb72e033a5a9d7073c68f7e508b94916ed47a9/markupsafe-3.0.3-cp313-cp313-musllinux_1_2_riscv64.whl", hash = "sha256:795e7751525cae078558e679d646ae45574b47ed6e7771863fcc079a6171a0fc", size = 21588, upload-time = "2025-09-27T18:36:48.82Z" }, + { url = "https://files.pythonhosted.org/packages/b5/99/16a5eb2d140087ebd97180d95249b00a03aa87e29cc224056274f2e45fd6/markupsafe-3.0.3-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:8485f406a96febb5140bfeca44a73e3ce5116b2501ac54fe953e488fb1d03b12", size = 23041, upload-time = "2025-09-27T18:36:49.797Z" }, + { url = "https://files.pythonhosted.org/packages/19/bc/e7140ed90c5d61d77cea142eed9f9c303f4c4806f60a1044c13e3f1471d0/markupsafe-3.0.3-cp313-cp313-win32.whl", hash = "sha256:bdd37121970bfd8be76c5fb069c7751683bdf373db1ed6c010162b2a130248ed", size = 14543, upload-time = "2025-09-27T18:36:51.584Z" }, + { url = "https://files.pythonhosted.org/packages/05/73/c4abe620b841b6b791f2edc248f556900667a5a1cf023a6646967ae98335/markupsafe-3.0.3-cp313-cp313-win_amd64.whl", hash = "sha256:9a1abfdc021a164803f4d485104931fb8f8c1efd55bc6b748d2f5774e78b62c5", size = 15113, upload-time = "2025-09-27T18:36:52.537Z" }, + { url = "https://files.pythonhosted.org/packages/f0/3a/fa34a0f7cfef23cf9500d68cb7c32dd64ffd58a12b09225fb03dd37d5b80/markupsafe-3.0.3-cp313-cp313-win_arm64.whl", hash = "sha256:7e68f88e5b8799aa49c85cd116c932a1ac15caaa3f5db09087854d218359e485", size = 13911, upload-time = "2025-09-27T18:36:53.513Z" }, + { url = "https://files.pythonhosted.org/packages/e4/d7/e05cd7efe43a88a17a37b3ae96e79a19e846f3f456fe79c57ca61356ef01/markupsafe-3.0.3-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:218551f6df4868a8d527e3062d0fb968682fe92054e89978594c28e642c43a73", size = 11658, upload-time = "2025-09-27T18:36:54.819Z" }, + { url = "https://files.pythonhosted.org/packages/99/9e/e412117548182ce2148bdeacdda3bb494260c0b0184360fe0d56389b523b/markupsafe-3.0.3-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:3524b778fe5cfb3452a09d31e7b5adefeea8c5be1d43c4f810ba09f2ceb29d37", size = 12066, upload-time = "2025-09-27T18:36:55.714Z" }, + { url = "https://files.pythonhosted.org/packages/bc/e6/fa0ffcda717ef64a5108eaa7b4f5ed28d56122c9a6d70ab8b72f9f715c80/markupsafe-3.0.3-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:4e885a3d1efa2eadc93c894a21770e4bc67899e3543680313b09f139e149ab19", size = 25639, upload-time = "2025-09-27T18:36:56.908Z" }, + { url = "https://files.pythonhosted.org/packages/96/ec/2102e881fe9d25fc16cb4b25d5f5cde50970967ffa5dddafdb771237062d/markupsafe-3.0.3-cp313-cp313t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:8709b08f4a89aa7586de0aadc8da56180242ee0ada3999749b183aa23df95025", size = 23569, upload-time = "2025-09-27T18:36:57.913Z" }, + { url = "https://files.pythonhosted.org/packages/4b/30/6f2fce1f1f205fc9323255b216ca8a235b15860c34b6798f810f05828e32/markupsafe-3.0.3-cp313-cp313t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:b8512a91625c9b3da6f127803b166b629725e68af71f8184ae7e7d54686a56d6", size = 23284, upload-time = "2025-09-27T18:36:58.833Z" }, + { url = "https://files.pythonhosted.org/packages/58/47/4a0ccea4ab9f5dcb6f79c0236d954acb382202721e704223a8aafa38b5c8/markupsafe-3.0.3-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:9b79b7a16f7fedff2495d684f2b59b0457c3b493778c9eed31111be64d58279f", size = 24801, upload-time = "2025-09-27T18:36:59.739Z" }, + { url = "https://files.pythonhosted.org/packages/6a/70/3780e9b72180b6fecb83a4814d84c3bf4b4ae4bf0b19c27196104149734c/markupsafe-3.0.3-cp313-cp313t-musllinux_1_2_riscv64.whl", hash = "sha256:12c63dfb4a98206f045aa9563db46507995f7ef6d83b2f68eda65c307c6829eb", size = 22769, upload-time = "2025-09-27T18:37:00.719Z" }, + { url = "https://files.pythonhosted.org/packages/98/c5/c03c7f4125180fc215220c035beac6b9cb684bc7a067c84fc69414d315f5/markupsafe-3.0.3-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:8f71bc33915be5186016f675cd83a1e08523649b0e33efdb898db577ef5bb009", size = 23642, upload-time = "2025-09-27T18:37:01.673Z" }, + { url = "https://files.pythonhosted.org/packages/80/d6/2d1b89f6ca4bff1036499b1e29a1d02d282259f3681540e16563f27ebc23/markupsafe-3.0.3-cp313-cp313t-win32.whl", hash = "sha256:69c0b73548bc525c8cb9a251cddf1931d1db4d2258e9599c28c07ef3580ef354", size = 14612, upload-time = "2025-09-27T18:37:02.639Z" }, + { url = "https://files.pythonhosted.org/packages/2b/98/e48a4bfba0a0ffcf9925fe2d69240bfaa19c6f7507b8cd09c70684a53c1e/markupsafe-3.0.3-cp313-cp313t-win_amd64.whl", hash = "sha256:1b4b79e8ebf6b55351f0d91fe80f893b4743f104bff22e90697db1590e47a218", size = 15200, upload-time = "2025-09-27T18:37:03.582Z" }, + { url = "https://files.pythonhosted.org/packages/0e/72/e3cc540f351f316e9ed0f092757459afbc595824ca724cbc5a5d4263713f/markupsafe-3.0.3-cp313-cp313t-win_arm64.whl", hash = "sha256:ad2cf8aa28b8c020ab2fc8287b0f823d0a7d8630784c31e9ee5edea20f406287", size = 13973, upload-time = "2025-09-27T18:37:04.929Z" }, + { url = "https://files.pythonhosted.org/packages/33/8a/8e42d4838cd89b7dde187011e97fe6c3af66d8c044997d2183fbd6d31352/markupsafe-3.0.3-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:eaa9599de571d72e2daf60164784109f19978b327a3910d3e9de8c97b5b70cfe", size = 11619, upload-time = "2025-09-27T18:37:06.342Z" }, + { url = "https://files.pythonhosted.org/packages/b5/64/7660f8a4a8e53c924d0fa05dc3a55c9cee10bbd82b11c5afb27d44b096ce/markupsafe-3.0.3-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:c47a551199eb8eb2121d4f0f15ae0f923d31350ab9280078d1e5f12b249e0026", size = 12029, upload-time = "2025-09-27T18:37:07.213Z" }, + { url = "https://files.pythonhosted.org/packages/da/ef/e648bfd021127bef5fa12e1720ffed0c6cbb8310c8d9bea7266337ff06de/markupsafe-3.0.3-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:f34c41761022dd093b4b6896d4810782ffbabe30f2d443ff5f083e0cbbb8c737", size = 24408, upload-time = "2025-09-27T18:37:09.572Z" }, + { url = "https://files.pythonhosted.org/packages/41/3c/a36c2450754618e62008bf7435ccb0f88053e07592e6028a34776213d877/markupsafe-3.0.3-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:457a69a9577064c05a97c41f4e65148652db078a3a509039e64d3467b9e7ef97", size = 23005, upload-time = "2025-09-27T18:37:10.58Z" }, + { url = "https://files.pythonhosted.org/packages/bc/20/b7fdf89a8456b099837cd1dc21974632a02a999ec9bf7ca3e490aacd98e7/markupsafe-3.0.3-cp314-cp314-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:e8afc3f2ccfa24215f8cb28dcf43f0113ac3c37c2f0f0806d8c70e4228c5cf4d", size = 22048, upload-time = "2025-09-27T18:37:11.547Z" }, + { url = "https://files.pythonhosted.org/packages/9a/a7/591f592afdc734f47db08a75793a55d7fbcc6902a723ae4cfbab61010cc5/markupsafe-3.0.3-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:ec15a59cf5af7be74194f7ab02d0f59a62bdcf1a537677ce67a2537c9b87fcda", size = 23821, upload-time = "2025-09-27T18:37:12.48Z" }, + { url = "https://files.pythonhosted.org/packages/7d/33/45b24e4f44195b26521bc6f1a82197118f74df348556594bd2262bda1038/markupsafe-3.0.3-cp314-cp314-musllinux_1_2_riscv64.whl", hash = "sha256:0eb9ff8191e8498cca014656ae6b8d61f39da5f95b488805da4bb029cccbfbaf", size = 21606, upload-time = "2025-09-27T18:37:13.485Z" }, + { url = "https://files.pythonhosted.org/packages/ff/0e/53dfaca23a69fbfbbf17a4b64072090e70717344c52eaaaa9c5ddff1e5f0/markupsafe-3.0.3-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:2713baf880df847f2bece4230d4d094280f4e67b1e813eec43b4c0e144a34ffe", size = 23043, upload-time = "2025-09-27T18:37:14.408Z" }, + { url = "https://files.pythonhosted.org/packages/46/11/f333a06fc16236d5238bfe74daccbca41459dcd8d1fa952e8fbd5dccfb70/markupsafe-3.0.3-cp314-cp314-win32.whl", hash = "sha256:729586769a26dbceff69f7a7dbbf59ab6572b99d94576a5592625d5b411576b9", size = 14747, upload-time = "2025-09-27T18:37:15.36Z" }, + { url = "https://files.pythonhosted.org/packages/28/52/182836104b33b444e400b14f797212f720cbc9ed6ba34c800639d154e821/markupsafe-3.0.3-cp314-cp314-win_amd64.whl", hash = "sha256:bdc919ead48f234740ad807933cdf545180bfbe9342c2bb451556db2ed958581", size = 15341, upload-time = "2025-09-27T18:37:16.496Z" }, + { url = "https://files.pythonhosted.org/packages/6f/18/acf23e91bd94fd7b3031558b1f013adfa21a8e407a3fdb32745538730382/markupsafe-3.0.3-cp314-cp314-win_arm64.whl", hash = "sha256:5a7d5dc5140555cf21a6fefbdbf8723f06fcd2f63ef108f2854de715e4422cb4", size = 14073, upload-time = "2025-09-27T18:37:17.476Z" }, + { url = "https://files.pythonhosted.org/packages/3c/f0/57689aa4076e1b43b15fdfa646b04653969d50cf30c32a102762be2485da/markupsafe-3.0.3-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:1353ef0c1b138e1907ae78e2f6c63ff67501122006b0f9abad68fda5f4ffc6ab", size = 11661, upload-time = "2025-09-27T18:37:18.453Z" }, + { url = "https://files.pythonhosted.org/packages/89/c3/2e67a7ca217c6912985ec766c6393b636fb0c2344443ff9d91404dc4c79f/markupsafe-3.0.3-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:1085e7fbddd3be5f89cc898938f42c0b3c711fdcb37d75221de2666af647c175", size = 12069, upload-time = "2025-09-27T18:37:19.332Z" }, + { url = "https://files.pythonhosted.org/packages/f0/00/be561dce4e6ca66b15276e184ce4b8aec61fe83662cce2f7d72bd3249d28/markupsafe-3.0.3-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:1b52b4fb9df4eb9ae465f8d0c228a00624de2334f216f178a995ccdcf82c4634", size = 25670, upload-time = "2025-09-27T18:37:20.245Z" }, + { url = "https://files.pythonhosted.org/packages/50/09/c419f6f5a92e5fadde27efd190eca90f05e1261b10dbd8cbcb39cd8ea1dc/markupsafe-3.0.3-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:fed51ac40f757d41b7c48425901843666a6677e3e8eb0abcff09e4ba6e664f50", size = 23598, upload-time = "2025-09-27T18:37:21.177Z" }, + { url = "https://files.pythonhosted.org/packages/22/44/a0681611106e0b2921b3033fc19bc53323e0b50bc70cffdd19f7d679bb66/markupsafe-3.0.3-cp314-cp314t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:f190daf01f13c72eac4efd5c430a8de82489d9cff23c364c3ea822545032993e", size = 23261, upload-time = "2025-09-27T18:37:22.167Z" }, + { url = "https://files.pythonhosted.org/packages/5f/57/1b0b3f100259dc9fffe780cfb60d4be71375510e435efec3d116b6436d43/markupsafe-3.0.3-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:e56b7d45a839a697b5eb268c82a71bd8c7f6c94d6fd50c3d577fa39a9f1409f5", size = 24835, upload-time = "2025-09-27T18:37:23.296Z" }, + { url = "https://files.pythonhosted.org/packages/26/6a/4bf6d0c97c4920f1597cc14dd720705eca0bf7c787aebc6bb4d1bead5388/markupsafe-3.0.3-cp314-cp314t-musllinux_1_2_riscv64.whl", hash = "sha256:f3e98bb3798ead92273dc0e5fd0f31ade220f59a266ffd8a4f6065e0a3ce0523", size = 22733, upload-time = "2025-09-27T18:37:24.237Z" }, + { url = "https://files.pythonhosted.org/packages/14/c7/ca723101509b518797fedc2fdf79ba57f886b4aca8a7d31857ba3ee8281f/markupsafe-3.0.3-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:5678211cb9333a6468fb8d8be0305520aa073f50d17f089b5b4b477ea6e67fdc", size = 23672, upload-time = "2025-09-27T18:37:25.271Z" }, + { url = "https://files.pythonhosted.org/packages/fb/df/5bd7a48c256faecd1d36edc13133e51397e41b73bb77e1a69deab746ebac/markupsafe-3.0.3-cp314-cp314t-win32.whl", hash = "sha256:915c04ba3851909ce68ccc2b8e2cd691618c4dc4c4232fb7982bca3f41fd8c3d", size = 14819, upload-time = "2025-09-27T18:37:26.285Z" }, + { url = "https://files.pythonhosted.org/packages/1a/8a/0402ba61a2f16038b48b39bccca271134be00c5c9f0f623208399333c448/markupsafe-3.0.3-cp314-cp314t-win_amd64.whl", hash = "sha256:4faffd047e07c38848ce017e8725090413cd80cbc23d86e55c587bf979e579c9", size = 15426, upload-time = "2025-09-27T18:37:27.316Z" }, + { url = "https://files.pythonhosted.org/packages/70/bc/6f1c2f612465f5fa89b95bead1f44dcb607670fd42891d8fdcd5d039f4f4/markupsafe-3.0.3-cp314-cp314t-win_arm64.whl", hash = "sha256:32001d6a8fc98c8cb5c947787c5d08b0a50663d139f1305bac5885d98d9b40fa", size = 14146, upload-time = "2025-09-27T18:37:28.327Z" }, ] [[package]] name = "mdurl" version = "0.1.2" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/d6/54/cfe61301667036ec958cb99bd3efefba235e65cdeb9c84d24a8293ba1d90/mdurl-0.1.2.tar.gz", hash = "sha256:bb413d29f5eea38f31dd4754dd7377d4465116fb207585f97bf925588687c1ba", size = 8729 } +sdist = { url = "https://files.pythonhosted.org/packages/d6/54/cfe61301667036ec958cb99bd3efefba235e65cdeb9c84d24a8293ba1d90/mdurl-0.1.2.tar.gz", hash = "sha256:bb413d29f5eea38f31dd4754dd7377d4465116fb207585f97bf925588687c1ba", size = 8729, upload-time = "2022-08-14T12:40:10.846Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/b3/38/89ba8ad64ae25be8de66a6d463314cf1eb366222074cfda9ee839c56a4b4/mdurl-0.1.2-py3-none-any.whl", hash = "sha256:84008a41e51615a49fc9966191ff91509e3c40b939176e643fd50a5c2196b8f8", size = 9979 }, + { url = "https://files.pythonhosted.org/packages/b3/38/89ba8ad64ae25be8de66a6d463314cf1eb366222074cfda9ee839c56a4b4/mdurl-0.1.2-py3-none-any.whl", hash = "sha256:84008a41e51615a49fc9966191ff91509e3c40b939176e643fd50a5c2196b8f8", size = 9979, upload-time = "2022-08-14T12:40:09.779Z" }, ] [[package]] @@ -1112,70 +1112,70 @@ dependencies = [ { name = "dotmap" }, { name = "jinja2" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/2a/68/4e0e1b0bc64f0d3afac2fb8a4fb35f2a4e9a0521ae1c777c0e29e21b27fa/mjml-0.11.1.tar.gz", hash = "sha256:f703c8b3458ca0100df6cf56a3633f193b352a80b1a1836a452b92361e74ca73", size = 66589 } +sdist = { url = "https://files.pythonhosted.org/packages/2a/68/4e0e1b0bc64f0d3afac2fb8a4fb35f2a4e9a0521ae1c777c0e29e21b27fa/mjml-0.11.1.tar.gz", hash = "sha256:f703c8b3458ca0100df6cf56a3633f193b352a80b1a1836a452b92361e74ca73", size = 66589, upload-time = "2025-05-13T10:24:05.693Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/85/a6/7ed27888adbf8cbdd734e298691004918ec0ef5f40e6bc1329ed97da2273/mjml-0.11.1-py3-none-any.whl", hash = "sha256:fef9f7a95929cbe5ddce9351ee8702e05153d68abc77dcf8e84da2c22a330b2a", size = 63191 }, + { url = "https://files.pythonhosted.org/packages/85/a6/7ed27888adbf8cbdd734e298691004918ec0ef5f40e6bc1329ed97da2273/mjml-0.11.1-py3-none-any.whl", hash = "sha256:fef9f7a95929cbe5ddce9351ee8702e05153d68abc77dcf8e84da2c22a330b2a", size = 63191, upload-time = "2025-05-13T10:24:03.953Z" }, ] [[package]] name = "nodeenv" version = "1.9.1" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/43/16/fc88b08840de0e0a72a2f9d8c6bae36be573e475a6326ae854bcc549fc45/nodeenv-1.9.1.tar.gz", hash = "sha256:6ec12890a2dab7946721edbfbcd91f3319c6ccc9aec47be7c7e6b7011ee6645f", size = 47437 } +sdist = { url = "https://files.pythonhosted.org/packages/43/16/fc88b08840de0e0a72a2f9d8c6bae36be573e475a6326ae854bcc549fc45/nodeenv-1.9.1.tar.gz", hash = "sha256:6ec12890a2dab7946721edbfbcd91f3319c6ccc9aec47be7c7e6b7011ee6645f", size = 47437, upload-time = "2024-06-04T18:44:11.171Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/d2/1d/1b658dbd2b9fa9c4c9f32accbfc0205d532c8c6194dc0f2a4c0428e7128a/nodeenv-1.9.1-py2.py3-none-any.whl", hash = "sha256:ba11c9782d29c27c70ffbdda2d7415098754709be8a7056d79a737cd901155c9", size = 22314 }, + { url = "https://files.pythonhosted.org/packages/d2/1d/1b658dbd2b9fa9c4c9f32accbfc0205d532c8c6194dc0f2a4c0428e7128a/nodeenv-1.9.1-py2.py3-none-any.whl", hash = "sha256:ba11c9782d29c27c70ffbdda2d7415098754709be8a7056d79a737cd901155c9", size = 22314, upload-time = "2024-06-04T18:44:08.352Z" }, ] [[package]] name = "numpy" version = "2.3.4" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/b5/f4/098d2270d52b41f1bd7db9fc288aaa0400cb48c2a3e2af6fa365d9720947/numpy-2.3.4.tar.gz", hash = "sha256:a7d018bfedb375a8d979ac758b120ba846a7fe764911a64465fd87b8729f4a6a", size = 20582187 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/57/7e/b72610cc91edf138bc588df5150957a4937221ca6058b825b4725c27be62/numpy-2.3.4-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:c090d4860032b857d94144d1a9976b8e36709e40386db289aaf6672de2a81966", size = 20950335 }, - { url = "https://files.pythonhosted.org/packages/3e/46/bdd3370dcea2f95ef14af79dbf81e6927102ddf1cc54adc0024d61252fd9/numpy-2.3.4-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:a13fc473b6db0be619e45f11f9e81260f7302f8d180c49a22b6e6120022596b3", size = 14179878 }, - { url = "https://files.pythonhosted.org/packages/ac/01/5a67cb785bda60f45415d09c2bc245433f1c68dd82eef9c9002c508b5a65/numpy-2.3.4-cp313-cp313-macosx_14_0_arm64.whl", hash = "sha256:3634093d0b428e6c32c3a69b78e554f0cd20ee420dcad5a9f3b2a63762ce4197", size = 5108673 }, - { url = "https://files.pythonhosted.org/packages/c2/cd/8428e23a9fcebd33988f4cb61208fda832800ca03781f471f3727a820704/numpy-2.3.4-cp313-cp313-macosx_14_0_x86_64.whl", hash = "sha256:043885b4f7e6e232d7df4f51ffdef8c36320ee9d5f227b380ea636722c7ed12e", size = 6641438 }, - { url = "https://files.pythonhosted.org/packages/3e/d1/913fe563820f3c6b079f992458f7331278dcd7ba8427e8e745af37ddb44f/numpy-2.3.4-cp313-cp313-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:4ee6a571d1e4f0ea6d5f22d6e5fbd6ed1dc2b18542848e1e7301bd190500c9d7", size = 14281290 }, - { url = "https://files.pythonhosted.org/packages/9e/7e/7d306ff7cb143e6d975cfa7eb98a93e73495c4deabb7d1b5ecf09ea0fd69/numpy-2.3.4-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:fc8a63918b04b8571789688b2780ab2b4a33ab44bfe8ccea36d3eba51228c953", size = 16636543 }, - { url = "https://files.pythonhosted.org/packages/47/6a/8cfc486237e56ccfb0db234945552a557ca266f022d281a2f577b98e955c/numpy-2.3.4-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:40cc556d5abbc54aabe2b1ae287042d7bdb80c08edede19f0c0afb36ae586f37", size = 16056117 }, - { url = "https://files.pythonhosted.org/packages/b1/0e/42cb5e69ea901e06ce24bfcc4b5664a56f950a70efdcf221f30d9615f3f3/numpy-2.3.4-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:ecb63014bb7f4ce653f8be7f1df8cbc6093a5a2811211770f6606cc92b5a78fd", size = 18577788 }, - { url = "https://files.pythonhosted.org/packages/86/92/41c3d5157d3177559ef0a35da50f0cda7fa071f4ba2306dd36818591a5bc/numpy-2.3.4-cp313-cp313-win32.whl", hash = "sha256:e8370eb6925bb8c1c4264fec52b0384b44f675f191df91cbe0140ec9f0955646", size = 6282620 }, - { url = "https://files.pythonhosted.org/packages/09/97/fd421e8bc50766665ad35536c2bb4ef916533ba1fdd053a62d96cc7c8b95/numpy-2.3.4-cp313-cp313-win_amd64.whl", hash = "sha256:56209416e81a7893036eea03abcb91c130643eb14233b2515c90dcac963fe99d", size = 12784672 }, - { url = "https://files.pythonhosted.org/packages/ad/df/5474fb2f74970ca8eb978093969b125a84cc3d30e47f82191f981f13a8a0/numpy-2.3.4-cp313-cp313-win_arm64.whl", hash = "sha256:a700a4031bc0fd6936e78a752eefb79092cecad2599ea9c8039c548bc097f9bc", size = 10196702 }, - { url = "https://files.pythonhosted.org/packages/11/83/66ac031464ec1767ea3ed48ce40f615eb441072945e98693bec0bcd056cc/numpy-2.3.4-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:86966db35c4040fdca64f0816a1c1dd8dbd027d90fca5a57e00e1ca4cd41b879", size = 21049003 }, - { url = "https://files.pythonhosted.org/packages/5f/99/5b14e0e686e61371659a1d5bebd04596b1d72227ce36eed121bb0aeab798/numpy-2.3.4-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:838f045478638b26c375ee96ea89464d38428c69170360b23a1a50fa4baa3562", size = 14302980 }, - { url = "https://files.pythonhosted.org/packages/2c/44/e9486649cd087d9fc6920e3fc3ac2aba10838d10804b1e179fb7cbc4e634/numpy-2.3.4-cp313-cp313t-macosx_14_0_arm64.whl", hash = "sha256:d7315ed1dab0286adca467377c8381cd748f3dc92235f22a7dfc42745644a96a", size = 5231472 }, - { url = "https://files.pythonhosted.org/packages/3e/51/902b24fa8887e5fe2063fd61b1895a476d0bbf46811ab0c7fdf4bd127345/numpy-2.3.4-cp313-cp313t-macosx_14_0_x86_64.whl", hash = "sha256:84f01a4d18b2cc4ade1814a08e5f3c907b079c847051d720fad15ce37aa930b6", size = 6739342 }, - { url = "https://files.pythonhosted.org/packages/34/f1/4de9586d05b1962acdcdb1dc4af6646361a643f8c864cef7c852bf509740/numpy-2.3.4-cp313-cp313t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:817e719a868f0dacde4abdfc5c1910b301877970195db9ab6a5e2c4bd5b121f7", size = 14354338 }, - { url = "https://files.pythonhosted.org/packages/1f/06/1c16103b425de7969d5a76bdf5ada0804b476fed05d5f9e17b777f1cbefd/numpy-2.3.4-cp313-cp313t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:85e071da78d92a214212cacea81c6da557cab307f2c34b5f85b628e94803f9c0", size = 16702392 }, - { url = "https://files.pythonhosted.org/packages/34/b2/65f4dc1b89b5322093572b6e55161bb42e3e0487067af73627f795cc9d47/numpy-2.3.4-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:2ec646892819370cf3558f518797f16597b4e4669894a2ba712caccc9da53f1f", size = 16134998 }, - { url = "https://files.pythonhosted.org/packages/d4/11/94ec578896cdb973aaf56425d6c7f2aff4186a5c00fac15ff2ec46998b46/numpy-2.3.4-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:035796aaaddfe2f9664b9a9372f089cfc88bd795a67bd1bfe15e6e770934cf64", size = 18651574 }, - { url = "https://files.pythonhosted.org/packages/62/b7/7efa763ab33dbccf56dade36938a77345ce8e8192d6b39e470ca25ff3cd0/numpy-2.3.4-cp313-cp313t-win32.whl", hash = "sha256:fea80f4f4cf83b54c3a051f2f727870ee51e22f0248d3114b8e755d160b38cfb", size = 6413135 }, - { url = "https://files.pythonhosted.org/packages/43/70/aba4c38e8400abcc2f345e13d972fb36c26409b3e644366db7649015f291/numpy-2.3.4-cp313-cp313t-win_amd64.whl", hash = "sha256:15eea9f306b98e0be91eb344a94c0e630689ef302e10c2ce5f7e11905c704f9c", size = 12928582 }, - { url = "https://files.pythonhosted.org/packages/67/63/871fad5f0073fc00fbbdd7232962ea1ac40eeaae2bba66c76214f7954236/numpy-2.3.4-cp313-cp313t-win_arm64.whl", hash = "sha256:b6c231c9c2fadbae4011ca5e7e83e12dc4a5072f1a1d85a0a7b3ed754d145a40", size = 10266691 }, - { url = "https://files.pythonhosted.org/packages/72/71/ae6170143c115732470ae3a2d01512870dd16e0953f8a6dc89525696069b/numpy-2.3.4-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:81c3e6d8c97295a7360d367f9f8553973651b76907988bb6066376bc2252f24e", size = 20955580 }, - { url = "https://files.pythonhosted.org/packages/af/39/4be9222ffd6ca8a30eda033d5f753276a9c3426c397bb137d8e19dedd200/numpy-2.3.4-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:7c26b0b2bf58009ed1f38a641f3db4be8d960a417ca96d14e5b06df1506d41ff", size = 14188056 }, - { url = "https://files.pythonhosted.org/packages/6c/3d/d85f6700d0a4aa4f9491030e1021c2b2b7421b2b38d01acd16734a2bfdc7/numpy-2.3.4-cp314-cp314-macosx_14_0_arm64.whl", hash = "sha256:62b2198c438058a20b6704351b35a1d7db881812d8512d67a69c9de1f18ca05f", size = 5116555 }, - { url = "https://files.pythonhosted.org/packages/bf/04/82c1467d86f47eee8a19a464c92f90a9bb68ccf14a54c5224d7031241ffb/numpy-2.3.4-cp314-cp314-macosx_14_0_x86_64.whl", hash = "sha256:9d729d60f8d53a7361707f4b68a9663c968882dd4f09e0d58c044c8bf5faee7b", size = 6643581 }, - { url = "https://files.pythonhosted.org/packages/0c/d3/c79841741b837e293f48bd7db89d0ac7a4f2503b382b78a790ef1dc778a5/numpy-2.3.4-cp314-cp314-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:bd0c630cf256b0a7fd9d0a11c9413b42fef5101219ce6ed5a09624f5a65392c7", size = 14299186 }, - { url = "https://files.pythonhosted.org/packages/e8/7e/4a14a769741fbf237eec5a12a2cbc7a4c4e061852b6533bcb9e9a796c908/numpy-2.3.4-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:d5e081bc082825f8b139f9e9fe42942cb4054524598aaeb177ff476cc76d09d2", size = 16638601 }, - { url = "https://files.pythonhosted.org/packages/93/87/1c1de269f002ff0a41173fe01dcc925f4ecff59264cd8f96cf3b60d12c9b/numpy-2.3.4-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:15fb27364ed84114438fff8aaf998c9e19adbeba08c0b75409f8c452a8692c52", size = 16074219 }, - { url = "https://files.pythonhosted.org/packages/cd/28/18f72ee77408e40a76d691001ae599e712ca2a47ddd2c4f695b16c65f077/numpy-2.3.4-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:85d9fb2d8cd998c84d13a79a09cc0c1091648e848e4e6249b0ccd7f6b487fa26", size = 18576702 }, - { url = "https://files.pythonhosted.org/packages/c3/76/95650169b465ececa8cf4b2e8f6df255d4bf662775e797ade2025cc51ae6/numpy-2.3.4-cp314-cp314-win32.whl", hash = "sha256:e73d63fd04e3a9d6bc187f5455d81abfad05660b212c8804bf3b407e984cd2bc", size = 6337136 }, - { url = "https://files.pythonhosted.org/packages/dc/89/a231a5c43ede5d6f77ba4a91e915a87dea4aeea76560ba4d2bf185c683f0/numpy-2.3.4-cp314-cp314-win_amd64.whl", hash = "sha256:3da3491cee49cf16157e70f607c03a217ea6647b1cea4819c4f48e53d49139b9", size = 12920542 }, - { url = "https://files.pythonhosted.org/packages/0d/0c/ae9434a888f717c5ed2ff2393b3f344f0ff6f1c793519fa0c540461dc530/numpy-2.3.4-cp314-cp314-win_arm64.whl", hash = "sha256:6d9cd732068e8288dbe2717177320723ccec4fb064123f0caf9bbd90ab5be868", size = 10480213 }, - { url = "https://files.pythonhosted.org/packages/83/4b/c4a5f0841f92536f6b9592694a5b5f68c9ab37b775ff342649eadf9055d3/numpy-2.3.4-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:22758999b256b595cf0b1d102b133bb61866ba5ceecf15f759623b64c020c9ec", size = 21052280 }, - { url = "https://files.pythonhosted.org/packages/3e/80/90308845fc93b984d2cc96d83e2324ce8ad1fd6efea81b324cba4b673854/numpy-2.3.4-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:9cb177bc55b010b19798dc5497d540dea67fd13a8d9e882b2dae71de0cf09eb3", size = 14302930 }, - { url = "https://files.pythonhosted.org/packages/3d/4e/07439f22f2a3b247cec4d63a713faae55e1141a36e77fb212881f7cda3fb/numpy-2.3.4-cp314-cp314t-macosx_14_0_arm64.whl", hash = "sha256:0f2bcc76f1e05e5ab58893407c63d90b2029908fa41f9f1cc51eecce936c3365", size = 5231504 }, - { url = "https://files.pythonhosted.org/packages/ab/de/1e11f2547e2fe3d00482b19721855348b94ada8359aef5d40dd57bfae9df/numpy-2.3.4-cp314-cp314t-macosx_14_0_x86_64.whl", hash = "sha256:8dc20bde86802df2ed8397a08d793da0ad7a5fd4ea3ac85d757bf5dd4ad7c252", size = 6739405 }, - { url = "https://files.pythonhosted.org/packages/3b/40/8cd57393a26cebe2e923005db5134a946c62fa56a1087dc7c478f3e30837/numpy-2.3.4-cp314-cp314t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:5e199c087e2aa71c8f9ce1cb7a8e10677dc12457e7cc1be4798632da37c3e86e", size = 14354866 }, - { url = "https://files.pythonhosted.org/packages/93/39/5b3510f023f96874ee6fea2e40dfa99313a00bf3ab779f3c92978f34aace/numpy-2.3.4-cp314-cp314t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:85597b2d25ddf655495e2363fe044b0ae999b75bc4d630dc0d886484b03a5eb0", size = 16703296 }, - { url = "https://files.pythonhosted.org/packages/41/0d/19bb163617c8045209c1996c4e427bccbc4bbff1e2c711f39203c8ddbb4a/numpy-2.3.4-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:04a69abe45b49c5955923cf2c407843d1c85013b424ae8a560bba16c92fe44a0", size = 16136046 }, - { url = "https://files.pythonhosted.org/packages/e2/c1/6dba12fdf68b02a21ac411c9df19afa66bed2540f467150ca64d246b463d/numpy-2.3.4-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:e1708fac43ef8b419c975926ce1eaf793b0c13b7356cfab6ab0dc34c0a02ac0f", size = 18652691 }, - { url = "https://files.pythonhosted.org/packages/f8/73/f85056701dbbbb910c51d846c58d29fd46b30eecd2b6ba760fc8b8a1641b/numpy-2.3.4-cp314-cp314t-win32.whl", hash = "sha256:863e3b5f4d9915aaf1b8ec79ae560ad21f0b8d5e3adc31e73126491bb86dee1d", size = 6485782 }, - { url = "https://files.pythonhosted.org/packages/17/90/28fa6f9865181cb817c2471ee65678afa8a7e2a1fb16141473d5fa6bacc3/numpy-2.3.4-cp314-cp314t-win_amd64.whl", hash = "sha256:962064de37b9aef801d33bc579690f8bfe6c5e70e29b61783f60bcba838a14d6", size = 13113301 }, - { url = "https://files.pythonhosted.org/packages/54/23/08c002201a8e7e1f9afba93b97deceb813252d9cfd0d3351caed123dcf97/numpy-2.3.4-cp314-cp314t-win_arm64.whl", hash = "sha256:8b5a9a39c45d852b62693d9b3f3e0fe052541f804296ff401a72a1b60edafb29", size = 10547532 }, +sdist = { url = "https://files.pythonhosted.org/packages/b5/f4/098d2270d52b41f1bd7db9fc288aaa0400cb48c2a3e2af6fa365d9720947/numpy-2.3.4.tar.gz", hash = "sha256:a7d018bfedb375a8d979ac758b120ba846a7fe764911a64465fd87b8729f4a6a", size = 20582187, upload-time = "2025-10-15T16:18:11.77Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/57/7e/b72610cc91edf138bc588df5150957a4937221ca6058b825b4725c27be62/numpy-2.3.4-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:c090d4860032b857d94144d1a9976b8e36709e40386db289aaf6672de2a81966", size = 20950335, upload-time = "2025-10-15T16:16:10.304Z" }, + { url = "https://files.pythonhosted.org/packages/3e/46/bdd3370dcea2f95ef14af79dbf81e6927102ddf1cc54adc0024d61252fd9/numpy-2.3.4-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:a13fc473b6db0be619e45f11f9e81260f7302f8d180c49a22b6e6120022596b3", size = 14179878, upload-time = "2025-10-15T16:16:12.595Z" }, + { url = "https://files.pythonhosted.org/packages/ac/01/5a67cb785bda60f45415d09c2bc245433f1c68dd82eef9c9002c508b5a65/numpy-2.3.4-cp313-cp313-macosx_14_0_arm64.whl", hash = "sha256:3634093d0b428e6c32c3a69b78e554f0cd20ee420dcad5a9f3b2a63762ce4197", size = 5108673, upload-time = "2025-10-15T16:16:14.877Z" }, + { url = "https://files.pythonhosted.org/packages/c2/cd/8428e23a9fcebd33988f4cb61208fda832800ca03781f471f3727a820704/numpy-2.3.4-cp313-cp313-macosx_14_0_x86_64.whl", hash = "sha256:043885b4f7e6e232d7df4f51ffdef8c36320ee9d5f227b380ea636722c7ed12e", size = 6641438, upload-time = "2025-10-15T16:16:16.805Z" }, + { url = "https://files.pythonhosted.org/packages/3e/d1/913fe563820f3c6b079f992458f7331278dcd7ba8427e8e745af37ddb44f/numpy-2.3.4-cp313-cp313-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:4ee6a571d1e4f0ea6d5f22d6e5fbd6ed1dc2b18542848e1e7301bd190500c9d7", size = 14281290, upload-time = "2025-10-15T16:16:18.764Z" }, + { url = "https://files.pythonhosted.org/packages/9e/7e/7d306ff7cb143e6d975cfa7eb98a93e73495c4deabb7d1b5ecf09ea0fd69/numpy-2.3.4-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:fc8a63918b04b8571789688b2780ab2b4a33ab44bfe8ccea36d3eba51228c953", size = 16636543, upload-time = "2025-10-15T16:16:21.072Z" }, + { url = "https://files.pythonhosted.org/packages/47/6a/8cfc486237e56ccfb0db234945552a557ca266f022d281a2f577b98e955c/numpy-2.3.4-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:40cc556d5abbc54aabe2b1ae287042d7bdb80c08edede19f0c0afb36ae586f37", size = 16056117, upload-time = "2025-10-15T16:16:23.369Z" }, + { url = "https://files.pythonhosted.org/packages/b1/0e/42cb5e69ea901e06ce24bfcc4b5664a56f950a70efdcf221f30d9615f3f3/numpy-2.3.4-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:ecb63014bb7f4ce653f8be7f1df8cbc6093a5a2811211770f6606cc92b5a78fd", size = 18577788, upload-time = "2025-10-15T16:16:27.496Z" }, + { url = "https://files.pythonhosted.org/packages/86/92/41c3d5157d3177559ef0a35da50f0cda7fa071f4ba2306dd36818591a5bc/numpy-2.3.4-cp313-cp313-win32.whl", hash = "sha256:e8370eb6925bb8c1c4264fec52b0384b44f675f191df91cbe0140ec9f0955646", size = 6282620, upload-time = "2025-10-15T16:16:29.811Z" }, + { url = "https://files.pythonhosted.org/packages/09/97/fd421e8bc50766665ad35536c2bb4ef916533ba1fdd053a62d96cc7c8b95/numpy-2.3.4-cp313-cp313-win_amd64.whl", hash = "sha256:56209416e81a7893036eea03abcb91c130643eb14233b2515c90dcac963fe99d", size = 12784672, upload-time = "2025-10-15T16:16:31.589Z" }, + { url = "https://files.pythonhosted.org/packages/ad/df/5474fb2f74970ca8eb978093969b125a84cc3d30e47f82191f981f13a8a0/numpy-2.3.4-cp313-cp313-win_arm64.whl", hash = "sha256:a700a4031bc0fd6936e78a752eefb79092cecad2599ea9c8039c548bc097f9bc", size = 10196702, upload-time = "2025-10-15T16:16:33.902Z" }, + { url = "https://files.pythonhosted.org/packages/11/83/66ac031464ec1767ea3ed48ce40f615eb441072945e98693bec0bcd056cc/numpy-2.3.4-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:86966db35c4040fdca64f0816a1c1dd8dbd027d90fca5a57e00e1ca4cd41b879", size = 21049003, upload-time = "2025-10-15T16:16:36.101Z" }, + { url = "https://files.pythonhosted.org/packages/5f/99/5b14e0e686e61371659a1d5bebd04596b1d72227ce36eed121bb0aeab798/numpy-2.3.4-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:838f045478638b26c375ee96ea89464d38428c69170360b23a1a50fa4baa3562", size = 14302980, upload-time = "2025-10-15T16:16:39.124Z" }, + { url = "https://files.pythonhosted.org/packages/2c/44/e9486649cd087d9fc6920e3fc3ac2aba10838d10804b1e179fb7cbc4e634/numpy-2.3.4-cp313-cp313t-macosx_14_0_arm64.whl", hash = "sha256:d7315ed1dab0286adca467377c8381cd748f3dc92235f22a7dfc42745644a96a", size = 5231472, upload-time = "2025-10-15T16:16:41.168Z" }, + { url = "https://files.pythonhosted.org/packages/3e/51/902b24fa8887e5fe2063fd61b1895a476d0bbf46811ab0c7fdf4bd127345/numpy-2.3.4-cp313-cp313t-macosx_14_0_x86_64.whl", hash = "sha256:84f01a4d18b2cc4ade1814a08e5f3c907b079c847051d720fad15ce37aa930b6", size = 6739342, upload-time = "2025-10-15T16:16:43.777Z" }, + { url = "https://files.pythonhosted.org/packages/34/f1/4de9586d05b1962acdcdb1dc4af6646361a643f8c864cef7c852bf509740/numpy-2.3.4-cp313-cp313t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:817e719a868f0dacde4abdfc5c1910b301877970195db9ab6a5e2c4bd5b121f7", size = 14354338, upload-time = "2025-10-15T16:16:46.081Z" }, + { url = "https://files.pythonhosted.org/packages/1f/06/1c16103b425de7969d5a76bdf5ada0804b476fed05d5f9e17b777f1cbefd/numpy-2.3.4-cp313-cp313t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:85e071da78d92a214212cacea81c6da557cab307f2c34b5f85b628e94803f9c0", size = 16702392, upload-time = "2025-10-15T16:16:48.455Z" }, + { url = "https://files.pythonhosted.org/packages/34/b2/65f4dc1b89b5322093572b6e55161bb42e3e0487067af73627f795cc9d47/numpy-2.3.4-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:2ec646892819370cf3558f518797f16597b4e4669894a2ba712caccc9da53f1f", size = 16134998, upload-time = "2025-10-15T16:16:51.114Z" }, + { url = "https://files.pythonhosted.org/packages/d4/11/94ec578896cdb973aaf56425d6c7f2aff4186a5c00fac15ff2ec46998b46/numpy-2.3.4-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:035796aaaddfe2f9664b9a9372f089cfc88bd795a67bd1bfe15e6e770934cf64", size = 18651574, upload-time = "2025-10-15T16:16:53.429Z" }, + { url = "https://files.pythonhosted.org/packages/62/b7/7efa763ab33dbccf56dade36938a77345ce8e8192d6b39e470ca25ff3cd0/numpy-2.3.4-cp313-cp313t-win32.whl", hash = "sha256:fea80f4f4cf83b54c3a051f2f727870ee51e22f0248d3114b8e755d160b38cfb", size = 6413135, upload-time = "2025-10-15T16:16:55.992Z" }, + { url = "https://files.pythonhosted.org/packages/43/70/aba4c38e8400abcc2f345e13d972fb36c26409b3e644366db7649015f291/numpy-2.3.4-cp313-cp313t-win_amd64.whl", hash = "sha256:15eea9f306b98e0be91eb344a94c0e630689ef302e10c2ce5f7e11905c704f9c", size = 12928582, upload-time = "2025-10-15T16:16:57.943Z" }, + { url = "https://files.pythonhosted.org/packages/67/63/871fad5f0073fc00fbbdd7232962ea1ac40eeaae2bba66c76214f7954236/numpy-2.3.4-cp313-cp313t-win_arm64.whl", hash = "sha256:b6c231c9c2fadbae4011ca5e7e83e12dc4a5072f1a1d85a0a7b3ed754d145a40", size = 10266691, upload-time = "2025-10-15T16:17:00.048Z" }, + { url = "https://files.pythonhosted.org/packages/72/71/ae6170143c115732470ae3a2d01512870dd16e0953f8a6dc89525696069b/numpy-2.3.4-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:81c3e6d8c97295a7360d367f9f8553973651b76907988bb6066376bc2252f24e", size = 20955580, upload-time = "2025-10-15T16:17:02.509Z" }, + { url = "https://files.pythonhosted.org/packages/af/39/4be9222ffd6ca8a30eda033d5f753276a9c3426c397bb137d8e19dedd200/numpy-2.3.4-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:7c26b0b2bf58009ed1f38a641f3db4be8d960a417ca96d14e5b06df1506d41ff", size = 14188056, upload-time = "2025-10-15T16:17:04.873Z" }, + { url = "https://files.pythonhosted.org/packages/6c/3d/d85f6700d0a4aa4f9491030e1021c2b2b7421b2b38d01acd16734a2bfdc7/numpy-2.3.4-cp314-cp314-macosx_14_0_arm64.whl", hash = "sha256:62b2198c438058a20b6704351b35a1d7db881812d8512d67a69c9de1f18ca05f", size = 5116555, upload-time = "2025-10-15T16:17:07.499Z" }, + { url = "https://files.pythonhosted.org/packages/bf/04/82c1467d86f47eee8a19a464c92f90a9bb68ccf14a54c5224d7031241ffb/numpy-2.3.4-cp314-cp314-macosx_14_0_x86_64.whl", hash = "sha256:9d729d60f8d53a7361707f4b68a9663c968882dd4f09e0d58c044c8bf5faee7b", size = 6643581, upload-time = "2025-10-15T16:17:09.774Z" }, + { url = "https://files.pythonhosted.org/packages/0c/d3/c79841741b837e293f48bd7db89d0ac7a4f2503b382b78a790ef1dc778a5/numpy-2.3.4-cp314-cp314-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:bd0c630cf256b0a7fd9d0a11c9413b42fef5101219ce6ed5a09624f5a65392c7", size = 14299186, upload-time = "2025-10-15T16:17:11.937Z" }, + { url = "https://files.pythonhosted.org/packages/e8/7e/4a14a769741fbf237eec5a12a2cbc7a4c4e061852b6533bcb9e9a796c908/numpy-2.3.4-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:d5e081bc082825f8b139f9e9fe42942cb4054524598aaeb177ff476cc76d09d2", size = 16638601, upload-time = "2025-10-15T16:17:14.391Z" }, + { url = "https://files.pythonhosted.org/packages/93/87/1c1de269f002ff0a41173fe01dcc925f4ecff59264cd8f96cf3b60d12c9b/numpy-2.3.4-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:15fb27364ed84114438fff8aaf998c9e19adbeba08c0b75409f8c452a8692c52", size = 16074219, upload-time = "2025-10-15T16:17:17.058Z" }, + { url = "https://files.pythonhosted.org/packages/cd/28/18f72ee77408e40a76d691001ae599e712ca2a47ddd2c4f695b16c65f077/numpy-2.3.4-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:85d9fb2d8cd998c84d13a79a09cc0c1091648e848e4e6249b0ccd7f6b487fa26", size = 18576702, upload-time = "2025-10-15T16:17:19.379Z" }, + { url = "https://files.pythonhosted.org/packages/c3/76/95650169b465ececa8cf4b2e8f6df255d4bf662775e797ade2025cc51ae6/numpy-2.3.4-cp314-cp314-win32.whl", hash = "sha256:e73d63fd04e3a9d6bc187f5455d81abfad05660b212c8804bf3b407e984cd2bc", size = 6337136, upload-time = "2025-10-15T16:17:22.886Z" }, + { url = "https://files.pythonhosted.org/packages/dc/89/a231a5c43ede5d6f77ba4a91e915a87dea4aeea76560ba4d2bf185c683f0/numpy-2.3.4-cp314-cp314-win_amd64.whl", hash = "sha256:3da3491cee49cf16157e70f607c03a217ea6647b1cea4819c4f48e53d49139b9", size = 12920542, upload-time = "2025-10-15T16:17:24.783Z" }, + { url = "https://files.pythonhosted.org/packages/0d/0c/ae9434a888f717c5ed2ff2393b3f344f0ff6f1c793519fa0c540461dc530/numpy-2.3.4-cp314-cp314-win_arm64.whl", hash = "sha256:6d9cd732068e8288dbe2717177320723ccec4fb064123f0caf9bbd90ab5be868", size = 10480213, upload-time = "2025-10-15T16:17:26.935Z" }, + { url = "https://files.pythonhosted.org/packages/83/4b/c4a5f0841f92536f6b9592694a5b5f68c9ab37b775ff342649eadf9055d3/numpy-2.3.4-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:22758999b256b595cf0b1d102b133bb61866ba5ceecf15f759623b64c020c9ec", size = 21052280, upload-time = "2025-10-15T16:17:29.638Z" }, + { url = "https://files.pythonhosted.org/packages/3e/80/90308845fc93b984d2cc96d83e2324ce8ad1fd6efea81b324cba4b673854/numpy-2.3.4-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:9cb177bc55b010b19798dc5497d540dea67fd13a8d9e882b2dae71de0cf09eb3", size = 14302930, upload-time = "2025-10-15T16:17:32.384Z" }, + { url = "https://files.pythonhosted.org/packages/3d/4e/07439f22f2a3b247cec4d63a713faae55e1141a36e77fb212881f7cda3fb/numpy-2.3.4-cp314-cp314t-macosx_14_0_arm64.whl", hash = "sha256:0f2bcc76f1e05e5ab58893407c63d90b2029908fa41f9f1cc51eecce936c3365", size = 5231504, upload-time = "2025-10-15T16:17:34.515Z" }, + { url = "https://files.pythonhosted.org/packages/ab/de/1e11f2547e2fe3d00482b19721855348b94ada8359aef5d40dd57bfae9df/numpy-2.3.4-cp314-cp314t-macosx_14_0_x86_64.whl", hash = "sha256:8dc20bde86802df2ed8397a08d793da0ad7a5fd4ea3ac85d757bf5dd4ad7c252", size = 6739405, upload-time = "2025-10-15T16:17:36.128Z" }, + { url = "https://files.pythonhosted.org/packages/3b/40/8cd57393a26cebe2e923005db5134a946c62fa56a1087dc7c478f3e30837/numpy-2.3.4-cp314-cp314t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:5e199c087e2aa71c8f9ce1cb7a8e10677dc12457e7cc1be4798632da37c3e86e", size = 14354866, upload-time = "2025-10-15T16:17:38.884Z" }, + { url = "https://files.pythonhosted.org/packages/93/39/5b3510f023f96874ee6fea2e40dfa99313a00bf3ab779f3c92978f34aace/numpy-2.3.4-cp314-cp314t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:85597b2d25ddf655495e2363fe044b0ae999b75bc4d630dc0d886484b03a5eb0", size = 16703296, upload-time = "2025-10-15T16:17:41.564Z" }, + { url = "https://files.pythonhosted.org/packages/41/0d/19bb163617c8045209c1996c4e427bccbc4bbff1e2c711f39203c8ddbb4a/numpy-2.3.4-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:04a69abe45b49c5955923cf2c407843d1c85013b424ae8a560bba16c92fe44a0", size = 16136046, upload-time = "2025-10-15T16:17:43.901Z" }, + { url = "https://files.pythonhosted.org/packages/e2/c1/6dba12fdf68b02a21ac411c9df19afa66bed2540f467150ca64d246b463d/numpy-2.3.4-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:e1708fac43ef8b419c975926ce1eaf793b0c13b7356cfab6ab0dc34c0a02ac0f", size = 18652691, upload-time = "2025-10-15T16:17:46.247Z" }, + { url = "https://files.pythonhosted.org/packages/f8/73/f85056701dbbbb910c51d846c58d29fd46b30eecd2b6ba760fc8b8a1641b/numpy-2.3.4-cp314-cp314t-win32.whl", hash = "sha256:863e3b5f4d9915aaf1b8ec79ae560ad21f0b8d5e3adc31e73126491bb86dee1d", size = 6485782, upload-time = "2025-10-15T16:17:48.872Z" }, + { url = "https://files.pythonhosted.org/packages/17/90/28fa6f9865181cb817c2471ee65678afa8a7e2a1fb16141473d5fa6bacc3/numpy-2.3.4-cp314-cp314t-win_amd64.whl", hash = "sha256:962064de37b9aef801d33bc579690f8bfe6c5e70e29b61783f60bcba838a14d6", size = 13113301, upload-time = "2025-10-15T16:17:50.938Z" }, + { url = "https://files.pythonhosted.org/packages/54/23/08c002201a8e7e1f9afba93b97deceb813252d9cfd0d3351caed123dcf97/numpy-2.3.4-cp314-cp314t-win_arm64.whl", hash = "sha256:8b5a9a39c45d852b62693d9b3f3e0fe052541f804296ff401a72a1b60edafb29", size = 10547532, upload-time = "2025-10-15T16:17:53.48Z" }, ] [[package]] @@ -1185,18 +1185,18 @@ source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "et-xmlfile" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/3d/f9/88d94a75de065ea32619465d2f77b29a0469500e99012523b91cc4141cd1/openpyxl-3.1.5.tar.gz", hash = "sha256:cf0e3cf56142039133628b5acffe8ef0c12bc902d2aadd3e0fe5878dc08d1050", size = 186464 } +sdist = { url = "https://files.pythonhosted.org/packages/3d/f9/88d94a75de065ea32619465d2f77b29a0469500e99012523b91cc4141cd1/openpyxl-3.1.5.tar.gz", hash = "sha256:cf0e3cf56142039133628b5acffe8ef0c12bc902d2aadd3e0fe5878dc08d1050", size = 186464, upload-time = "2024-06-28T14:03:44.161Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/c0/da/977ded879c29cbd04de313843e76868e6e13408a94ed6b987245dc7c8506/openpyxl-3.1.5-py2.py3-none-any.whl", hash = "sha256:5282c12b107bffeef825f4617dc029afaf41d0ea60823bbb665ef3079dc79de2", size = 250910 }, + { url = "https://files.pythonhosted.org/packages/c0/da/977ded879c29cbd04de313843e76868e6e13408a94ed6b987245dc7c8506/openpyxl-3.1.5-py2.py3-none-any.whl", hash = "sha256:5282c12b107bffeef825f4617dc029afaf41d0ea60823bbb665ef3079dc79de2", size = 250910, upload-time = "2024-06-28T14:03:41.161Z" }, ] [[package]] name = "packaging" version = "25.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/a1/d4/1fc4078c65507b51b96ca8f8c3ba19e6a61c8253c72794544580a7b6c24d/packaging-25.0.tar.gz", hash = "sha256:d443872c98d677bf60f6a1f2f8c1cb748e8fe762d2bf9d3148b5599295b0fc4f", size = 165727 } +sdist = { url = "https://files.pythonhosted.org/packages/a1/d4/1fc4078c65507b51b96ca8f8c3ba19e6a61c8253c72794544580a7b6c24d/packaging-25.0.tar.gz", hash = "sha256:d443872c98d677bf60f6a1f2f8c1cb748e8fe762d2bf9d3148b5599295b0fc4f", size = 165727, upload-time = "2025-04-19T11:48:59.673Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/20/12/38679034af332785aac8774540895e234f4d07f7545804097de4b666afd8/packaging-25.0-py3-none-any.whl", hash = "sha256:29572ef2b1f17581046b3a2227d5c611fb25ec70ca1ba8554b24b0e69331a484", size = 66469 }, + { url = "https://files.pythonhosted.org/packages/20/12/38679034af332785aac8774540895e234f4d07f7545804097de4b666afd8/packaging-25.0-py3-none-any.whl", hash = "sha256:29572ef2b1f17581046b3a2227d5c611fb25ec70ca1ba8554b24b0e69331a484", size = 66469, upload-time = "2025-04-19T11:48:57.875Z" }, ] [[package]] @@ -1209,34 +1209,34 @@ dependencies = [ { name = "pytz" }, { name = "tzdata" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/33/01/d40b85317f86cf08d853a4f495195c73815fdf205eef3993821720274518/pandas-2.3.3.tar.gz", hash = "sha256:e05e1af93b977f7eafa636d043f9f94c7ee3ac81af99c13508215942e64c993b", size = 4495223 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/cd/4b/18b035ee18f97c1040d94debd8f2e737000ad70ccc8f5513f4eefad75f4b/pandas-2.3.3-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:56851a737e3470de7fa88e6131f41281ed440d29a9268dcbf0002da5ac366713", size = 11544671 }, - { url = "https://files.pythonhosted.org/packages/31/94/72fac03573102779920099bcac1c3b05975c2cb5f01eac609faf34bed1ca/pandas-2.3.3-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:bdcd9d1167f4885211e401b3036c0c8d9e274eee67ea8d0758a256d60704cfe8", size = 10680807 }, - { url = "https://files.pythonhosted.org/packages/16/87/9472cf4a487d848476865321de18cc8c920b8cab98453ab79dbbc98db63a/pandas-2.3.3-cp313-cp313-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:e32e7cc9af0f1cc15548288a51a3b681cc2a219faa838e995f7dc53dbab1062d", size = 11709872 }, - { url = "https://files.pythonhosted.org/packages/15/07/284f757f63f8a8d69ed4472bfd85122bd086e637bf4ed09de572d575a693/pandas-2.3.3-cp313-cp313-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:318d77e0e42a628c04dc56bcef4b40de67918f7041c2b061af1da41dcff670ac", size = 12306371 }, - { url = "https://files.pythonhosted.org/packages/33/81/a3afc88fca4aa925804a27d2676d22dcd2031c2ebe08aabd0ae55b9ff282/pandas-2.3.3-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:4e0a175408804d566144e170d0476b15d78458795bb18f1304fb94160cabf40c", size = 12765333 }, - { url = "https://files.pythonhosted.org/packages/8d/0f/b4d4ae743a83742f1153464cf1a8ecfafc3ac59722a0b5c8602310cb7158/pandas-2.3.3-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:93c2d9ab0fc11822b5eece72ec9587e172f63cff87c00b062f6e37448ced4493", size = 13418120 }, - { url = "https://files.pythonhosted.org/packages/4f/c7/e54682c96a895d0c808453269e0b5928a07a127a15704fedb643e9b0a4c8/pandas-2.3.3-cp313-cp313-win_amd64.whl", hash = "sha256:f8bfc0e12dc78f777f323f55c58649591b2cd0c43534e8355c51d3fede5f4dee", size = 10993991 }, - { url = "https://files.pythonhosted.org/packages/f9/ca/3f8d4f49740799189e1395812f3bf23b5e8fc7c190827d55a610da72ce55/pandas-2.3.3-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:75ea25f9529fdec2d2e93a42c523962261e567d250b0013b16210e1d40d7c2e5", size = 12048227 }, - { url = "https://files.pythonhosted.org/packages/0e/5a/f43efec3e8c0cc92c4663ccad372dbdff72b60bdb56b2749f04aa1d07d7e/pandas-2.3.3-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:74ecdf1d301e812db96a465a525952f4dde225fdb6d8e5a521d47e1f42041e21", size = 11411056 }, - { url = "https://files.pythonhosted.org/packages/46/b1/85331edfc591208c9d1a63a06baa67b21d332e63b7a591a5ba42a10bb507/pandas-2.3.3-cp313-cp313t-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6435cb949cb34ec11cc9860246ccb2fdc9ecd742c12d3304989017d53f039a78", size = 11645189 }, - { url = "https://files.pythonhosted.org/packages/44/23/78d645adc35d94d1ac4f2a3c4112ab6f5b8999f4898b8cdf01252f8df4a9/pandas-2.3.3-cp313-cp313t-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:900f47d8f20860de523a1ac881c4c36d65efcb2eb850e6948140fa781736e110", size = 12121912 }, - { url = "https://files.pythonhosted.org/packages/53/da/d10013df5e6aaef6b425aa0c32e1fc1f3e431e4bcabd420517dceadce354/pandas-2.3.3-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:a45c765238e2ed7d7c608fc5bc4a6f88b642f2f01e70c0c23d2224dd21829d86", size = 12712160 }, - { url = "https://files.pythonhosted.org/packages/bd/17/e756653095a083d8a37cbd816cb87148debcfcd920129b25f99dd8d04271/pandas-2.3.3-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:c4fc4c21971a1a9f4bdb4c73978c7f7256caa3e62b323f70d6cb80db583350bc", size = 13199233 }, - { url = "https://files.pythonhosted.org/packages/04/fd/74903979833db8390b73b3a8a7d30d146d710bd32703724dd9083950386f/pandas-2.3.3-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:ee15f284898e7b246df8087fc82b87b01686f98ee67d85a17b7ab44143a3a9a0", size = 11540635 }, - { url = "https://files.pythonhosted.org/packages/21/00/266d6b357ad5e6d3ad55093a7e8efc7dd245f5a842b584db9f30b0f0a287/pandas-2.3.3-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:1611aedd912e1ff81ff41c745822980c49ce4a7907537be8692c8dbc31924593", size = 10759079 }, - { url = "https://files.pythonhosted.org/packages/ca/05/d01ef80a7a3a12b2f8bbf16daba1e17c98a2f039cbc8e2f77a2c5a63d382/pandas-2.3.3-cp314-cp314-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6d2cefc361461662ac48810cb14365a365ce864afe85ef1f447ff5a1e99ea81c", size = 11814049 }, - { url = "https://files.pythonhosted.org/packages/15/b2/0e62f78c0c5ba7e3d2c5945a82456f4fac76c480940f805e0b97fcbc2f65/pandas-2.3.3-cp314-cp314-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:ee67acbbf05014ea6c763beb097e03cd629961c8a632075eeb34247120abcb4b", size = 12332638 }, - { url = "https://files.pythonhosted.org/packages/c5/33/dd70400631b62b9b29c3c93d2feee1d0964dc2bae2e5ad7a6c73a7f25325/pandas-2.3.3-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:c46467899aaa4da076d5abc11084634e2d197e9460643dd455ac3db5856b24d6", size = 12886834 }, - { url = "https://files.pythonhosted.org/packages/d3/18/b5d48f55821228d0d2692b34fd5034bb185e854bdb592e9c640f6290e012/pandas-2.3.3-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:6253c72c6a1d990a410bc7de641d34053364ef8bcd3126f7e7450125887dffe3", size = 13409925 }, - { url = "https://files.pythonhosted.org/packages/a6/3d/124ac75fcd0ecc09b8fdccb0246ef65e35b012030defb0e0eba2cbbbe948/pandas-2.3.3-cp314-cp314-win_amd64.whl", hash = "sha256:1b07204a219b3b7350abaae088f451860223a52cfb8a6c53358e7948735158e5", size = 11109071 }, - { url = "https://files.pythonhosted.org/packages/89/9c/0e21c895c38a157e0faa1fb64587a9226d6dd46452cac4532d80c3c4a244/pandas-2.3.3-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:2462b1a365b6109d275250baaae7b760fd25c726aaca0054649286bcfbb3e8ec", size = 12048504 }, - { url = "https://files.pythonhosted.org/packages/d7/82/b69a1c95df796858777b68fbe6a81d37443a33319761d7c652ce77797475/pandas-2.3.3-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:0242fe9a49aa8b4d78a4fa03acb397a58833ef6199e9aa40a95f027bb3a1b6e7", size = 11410702 }, - { url = "https://files.pythonhosted.org/packages/f9/88/702bde3ba0a94b8c73a0181e05144b10f13f29ebfc2150c3a79062a8195d/pandas-2.3.3-cp314-cp314t-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:a21d830e78df0a515db2b3d2f5570610f5e6bd2e27749770e8bb7b524b89b450", size = 11634535 }, - { url = "https://files.pythonhosted.org/packages/a4/1e/1bac1a839d12e6a82ec6cb40cda2edde64a2013a66963293696bbf31fbbb/pandas-2.3.3-cp314-cp314t-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:2e3ebdb170b5ef78f19bfb71b0dc5dc58775032361fa188e814959b74d726dd5", size = 12121582 }, - { url = "https://files.pythonhosted.org/packages/44/91/483de934193e12a3b1d6ae7c8645d083ff88dec75f46e827562f1e4b4da6/pandas-2.3.3-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:d051c0e065b94b7a3cea50eb1ec32e912cd96dba41647eb24104b6c6c14c5788", size = 12699963 }, - { url = "https://files.pythonhosted.org/packages/70/44/5191d2e4026f86a2a109053e194d3ba7a31a2d10a9c2348368c63ed4e85a/pandas-2.3.3-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:3869faf4bd07b3b66a9f462417d0ca3a9df29a9f6abd5d0d0dbab15dac7abe87", size = 13202175 }, +sdist = { url = "https://files.pythonhosted.org/packages/33/01/d40b85317f86cf08d853a4f495195c73815fdf205eef3993821720274518/pandas-2.3.3.tar.gz", hash = "sha256:e05e1af93b977f7eafa636d043f9f94c7ee3ac81af99c13508215942e64c993b", size = 4495223, upload-time = "2025-09-29T23:34:51.853Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/cd/4b/18b035ee18f97c1040d94debd8f2e737000ad70ccc8f5513f4eefad75f4b/pandas-2.3.3-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:56851a737e3470de7fa88e6131f41281ed440d29a9268dcbf0002da5ac366713", size = 11544671, upload-time = "2025-09-29T23:21:05.024Z" }, + { url = "https://files.pythonhosted.org/packages/31/94/72fac03573102779920099bcac1c3b05975c2cb5f01eac609faf34bed1ca/pandas-2.3.3-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:bdcd9d1167f4885211e401b3036c0c8d9e274eee67ea8d0758a256d60704cfe8", size = 10680807, upload-time = "2025-09-29T23:21:15.979Z" }, + { url = "https://files.pythonhosted.org/packages/16/87/9472cf4a487d848476865321de18cc8c920b8cab98453ab79dbbc98db63a/pandas-2.3.3-cp313-cp313-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:e32e7cc9af0f1cc15548288a51a3b681cc2a219faa838e995f7dc53dbab1062d", size = 11709872, upload-time = "2025-09-29T23:21:27.165Z" }, + { url = "https://files.pythonhosted.org/packages/15/07/284f757f63f8a8d69ed4472bfd85122bd086e637bf4ed09de572d575a693/pandas-2.3.3-cp313-cp313-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:318d77e0e42a628c04dc56bcef4b40de67918f7041c2b061af1da41dcff670ac", size = 12306371, upload-time = "2025-09-29T23:21:40.532Z" }, + { url = "https://files.pythonhosted.org/packages/33/81/a3afc88fca4aa925804a27d2676d22dcd2031c2ebe08aabd0ae55b9ff282/pandas-2.3.3-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:4e0a175408804d566144e170d0476b15d78458795bb18f1304fb94160cabf40c", size = 12765333, upload-time = "2025-09-29T23:21:55.77Z" }, + { url = "https://files.pythonhosted.org/packages/8d/0f/b4d4ae743a83742f1153464cf1a8ecfafc3ac59722a0b5c8602310cb7158/pandas-2.3.3-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:93c2d9ab0fc11822b5eece72ec9587e172f63cff87c00b062f6e37448ced4493", size = 13418120, upload-time = "2025-09-29T23:22:10.109Z" }, + { url = "https://files.pythonhosted.org/packages/4f/c7/e54682c96a895d0c808453269e0b5928a07a127a15704fedb643e9b0a4c8/pandas-2.3.3-cp313-cp313-win_amd64.whl", hash = "sha256:f8bfc0e12dc78f777f323f55c58649591b2cd0c43534e8355c51d3fede5f4dee", size = 10993991, upload-time = "2025-09-29T23:25:04.889Z" }, + { url = "https://files.pythonhosted.org/packages/f9/ca/3f8d4f49740799189e1395812f3bf23b5e8fc7c190827d55a610da72ce55/pandas-2.3.3-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:75ea25f9529fdec2d2e93a42c523962261e567d250b0013b16210e1d40d7c2e5", size = 12048227, upload-time = "2025-09-29T23:22:24.343Z" }, + { url = "https://files.pythonhosted.org/packages/0e/5a/f43efec3e8c0cc92c4663ccad372dbdff72b60bdb56b2749f04aa1d07d7e/pandas-2.3.3-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:74ecdf1d301e812db96a465a525952f4dde225fdb6d8e5a521d47e1f42041e21", size = 11411056, upload-time = "2025-09-29T23:22:37.762Z" }, + { url = "https://files.pythonhosted.org/packages/46/b1/85331edfc591208c9d1a63a06baa67b21d332e63b7a591a5ba42a10bb507/pandas-2.3.3-cp313-cp313t-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6435cb949cb34ec11cc9860246ccb2fdc9ecd742c12d3304989017d53f039a78", size = 11645189, upload-time = "2025-09-29T23:22:51.688Z" }, + { url = "https://files.pythonhosted.org/packages/44/23/78d645adc35d94d1ac4f2a3c4112ab6f5b8999f4898b8cdf01252f8df4a9/pandas-2.3.3-cp313-cp313t-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:900f47d8f20860de523a1ac881c4c36d65efcb2eb850e6948140fa781736e110", size = 12121912, upload-time = "2025-09-29T23:23:05.042Z" }, + { url = "https://files.pythonhosted.org/packages/53/da/d10013df5e6aaef6b425aa0c32e1fc1f3e431e4bcabd420517dceadce354/pandas-2.3.3-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:a45c765238e2ed7d7c608fc5bc4a6f88b642f2f01e70c0c23d2224dd21829d86", size = 12712160, upload-time = "2025-09-29T23:23:28.57Z" }, + { url = "https://files.pythonhosted.org/packages/bd/17/e756653095a083d8a37cbd816cb87148debcfcd920129b25f99dd8d04271/pandas-2.3.3-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:c4fc4c21971a1a9f4bdb4c73978c7f7256caa3e62b323f70d6cb80db583350bc", size = 13199233, upload-time = "2025-09-29T23:24:24.876Z" }, + { url = "https://files.pythonhosted.org/packages/04/fd/74903979833db8390b73b3a8a7d30d146d710bd32703724dd9083950386f/pandas-2.3.3-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:ee15f284898e7b246df8087fc82b87b01686f98ee67d85a17b7ab44143a3a9a0", size = 11540635, upload-time = "2025-09-29T23:25:52.486Z" }, + { url = "https://files.pythonhosted.org/packages/21/00/266d6b357ad5e6d3ad55093a7e8efc7dd245f5a842b584db9f30b0f0a287/pandas-2.3.3-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:1611aedd912e1ff81ff41c745822980c49ce4a7907537be8692c8dbc31924593", size = 10759079, upload-time = "2025-09-29T23:26:33.204Z" }, + { url = "https://files.pythonhosted.org/packages/ca/05/d01ef80a7a3a12b2f8bbf16daba1e17c98a2f039cbc8e2f77a2c5a63d382/pandas-2.3.3-cp314-cp314-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6d2cefc361461662ac48810cb14365a365ce864afe85ef1f447ff5a1e99ea81c", size = 11814049, upload-time = "2025-09-29T23:27:15.384Z" }, + { url = "https://files.pythonhosted.org/packages/15/b2/0e62f78c0c5ba7e3d2c5945a82456f4fac76c480940f805e0b97fcbc2f65/pandas-2.3.3-cp314-cp314-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:ee67acbbf05014ea6c763beb097e03cd629961c8a632075eeb34247120abcb4b", size = 12332638, upload-time = "2025-09-29T23:27:51.625Z" }, + { url = "https://files.pythonhosted.org/packages/c5/33/dd70400631b62b9b29c3c93d2feee1d0964dc2bae2e5ad7a6c73a7f25325/pandas-2.3.3-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:c46467899aaa4da076d5abc11084634e2d197e9460643dd455ac3db5856b24d6", size = 12886834, upload-time = "2025-09-29T23:28:21.289Z" }, + { url = "https://files.pythonhosted.org/packages/d3/18/b5d48f55821228d0d2692b34fd5034bb185e854bdb592e9c640f6290e012/pandas-2.3.3-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:6253c72c6a1d990a410bc7de641d34053364ef8bcd3126f7e7450125887dffe3", size = 13409925, upload-time = "2025-09-29T23:28:58.261Z" }, + { url = "https://files.pythonhosted.org/packages/a6/3d/124ac75fcd0ecc09b8fdccb0246ef65e35b012030defb0e0eba2cbbbe948/pandas-2.3.3-cp314-cp314-win_amd64.whl", hash = "sha256:1b07204a219b3b7350abaae088f451860223a52cfb8a6c53358e7948735158e5", size = 11109071, upload-time = "2025-09-29T23:32:27.484Z" }, + { url = "https://files.pythonhosted.org/packages/89/9c/0e21c895c38a157e0faa1fb64587a9226d6dd46452cac4532d80c3c4a244/pandas-2.3.3-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:2462b1a365b6109d275250baaae7b760fd25c726aaca0054649286bcfbb3e8ec", size = 12048504, upload-time = "2025-09-29T23:29:31.47Z" }, + { url = "https://files.pythonhosted.org/packages/d7/82/b69a1c95df796858777b68fbe6a81d37443a33319761d7c652ce77797475/pandas-2.3.3-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:0242fe9a49aa8b4d78a4fa03acb397a58833ef6199e9aa40a95f027bb3a1b6e7", size = 11410702, upload-time = "2025-09-29T23:29:54.591Z" }, + { url = "https://files.pythonhosted.org/packages/f9/88/702bde3ba0a94b8c73a0181e05144b10f13f29ebfc2150c3a79062a8195d/pandas-2.3.3-cp314-cp314t-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:a21d830e78df0a515db2b3d2f5570610f5e6bd2e27749770e8bb7b524b89b450", size = 11634535, upload-time = "2025-09-29T23:30:21.003Z" }, + { url = "https://files.pythonhosted.org/packages/a4/1e/1bac1a839d12e6a82ec6cb40cda2edde64a2013a66963293696bbf31fbbb/pandas-2.3.3-cp314-cp314t-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:2e3ebdb170b5ef78f19bfb71b0dc5dc58775032361fa188e814959b74d726dd5", size = 12121582, upload-time = "2025-09-29T23:30:43.391Z" }, + { url = "https://files.pythonhosted.org/packages/44/91/483de934193e12a3b1d6ae7c8645d083ff88dec75f46e827562f1e4b4da6/pandas-2.3.3-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:d051c0e065b94b7a3cea50eb1ec32e912cd96dba41647eb24104b6c6c14c5788", size = 12699963, upload-time = "2025-09-29T23:31:10.009Z" }, + { url = "https://files.pythonhosted.org/packages/70/44/5191d2e4026f86a2a109053e194d3ba7a31a2d10a9c2348368c63ed4e85a/pandas-2.3.3-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:3869faf4bd07b3b66a9f462417d0ca3a9df29a9f6abd5d0d0dbab15dac7abe87", size = 13202175, upload-time = "2025-09-29T23:31:59.173Z" }, ] [[package]] @@ -1248,76 +1248,76 @@ dependencies = [ { name = "sqlalchemy" }, { name = "typer" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/c3/fe/84f4d06ac3e6038384847dc1d5c8b956f61b780f69509d177107b550c7b9/paracelsus-0.12.0.tar.gz", hash = "sha256:f1d8f584ebc445db99a2906f97ff55f36ae663c104320dd4a6b5b78b4fa24dce", size = 83664 } +sdist = { url = "https://files.pythonhosted.org/packages/c3/fe/84f4d06ac3e6038384847dc1d5c8b956f61b780f69509d177107b550c7b9/paracelsus-0.12.0.tar.gz", hash = "sha256:f1d8f584ebc445db99a2906f97ff55f36ae663c104320dd4a6b5b78b4fa24dce", size = 83664, upload-time = "2025-10-07T12:45:41.112Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/b3/60/9062e4072c16750b6b01bac9c55b329b249ee7c970d61c128049be197d7a/paracelsus-0.12.0-py3-none-any.whl", hash = "sha256:01f5a508174d06a86d53374215a0c85962498361ac3f0bd3450023760d3b3836", size = 81236 }, + { url = "https://files.pythonhosted.org/packages/b3/60/9062e4072c16750b6b01bac9c55b329b249ee7c970d61c128049be197d7a/paracelsus-0.12.0-py3-none-any.whl", hash = "sha256:01f5a508174d06a86d53374215a0c85962498361ac3f0bd3450023760d3b3836", size = 81236, upload-time = "2025-10-07T12:45:39.929Z" }, ] [[package]] name = "pillow" version = "12.0.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/5a/b0/cace85a1b0c9775a9f8f5d5423c8261c858760e2466c79b2dd184638b056/pillow-12.0.0.tar.gz", hash = "sha256:87d4f8125c9988bfbed67af47dd7a953e2fc7b0cc1e7800ec6d2080d490bb353", size = 47008828 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/62/f2/de993bb2d21b33a98d031ecf6a978e4b61da207bef02f7b43093774c480d/pillow-12.0.0-cp313-cp313-ios_13_0_arm64_iphoneos.whl", hash = "sha256:0869154a2d0546545cde61d1789a6524319fc1897d9ee31218eae7a60ccc5643", size = 4045493 }, - { url = "https://files.pythonhosted.org/packages/0e/b6/bc8d0c4c9f6f111a783d045310945deb769b806d7574764234ffd50bc5ea/pillow-12.0.0-cp313-cp313-ios_13_0_arm64_iphonesimulator.whl", hash = "sha256:a7921c5a6d31b3d756ec980f2f47c0cfdbce0fc48c22a39347a895f41f4a6ea4", size = 4120461 }, - { url = "https://files.pythonhosted.org/packages/5d/57/d60d343709366a353dc56adb4ee1e7d8a2cc34e3fbc22905f4167cfec119/pillow-12.0.0-cp313-cp313-ios_13_0_x86_64_iphonesimulator.whl", hash = "sha256:1ee80a59f6ce048ae13cda1abf7fbd2a34ab9ee7d401c46be3ca685d1999a399", size = 3576912 }, - { url = "https://files.pythonhosted.org/packages/a4/a4/a0a31467e3f83b94d37568294b01d22b43ae3c5d85f2811769b9c66389dd/pillow-12.0.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:c50f36a62a22d350c96e49ad02d0da41dbd17ddc2e29750dbdba4323f85eb4a5", size = 5249132 }, - { url = "https://files.pythonhosted.org/packages/83/06/48eab21dd561de2914242711434c0c0eb992ed08ff3f6107a5f44527f5e9/pillow-12.0.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:5193fde9a5f23c331ea26d0cf171fbf67e3f247585f50c08b3e205c7aeb4589b", size = 4650099 }, - { url = "https://files.pythonhosted.org/packages/fc/bd/69ed99fd46a8dba7c1887156d3572fe4484e3f031405fcc5a92e31c04035/pillow-12.0.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:bde737cff1a975b70652b62d626f7785e0480918dece11e8fef3c0cf057351c3", size = 6230808 }, - { url = "https://files.pythonhosted.org/packages/ea/94/8fad659bcdbf86ed70099cb60ae40be6acca434bbc8c4c0d4ef356d7e0de/pillow-12.0.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:a6597ff2b61d121172f5844b53f21467f7082f5fb385a9a29c01414463f93b07", size = 8037804 }, - { url = "https://files.pythonhosted.org/packages/20/39/c685d05c06deecfd4e2d1950e9a908aa2ca8bc4e6c3b12d93b9cafbd7837/pillow-12.0.0-cp313-cp313-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:0b817e7035ea7f6b942c13aa03bb554fc44fea70838ea21f8eb31c638326584e", size = 6345553 }, - { url = "https://files.pythonhosted.org/packages/38/57/755dbd06530a27a5ed74f8cb0a7a44a21722ebf318edbe67ddbd7fb28f88/pillow-12.0.0-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:f4f1231b7dec408e8670264ce63e9c71409d9583dd21d32c163e25213ee2a344", size = 7037729 }, - { url = "https://files.pythonhosted.org/packages/ca/b6/7e94f4c41d238615674d06ed677c14883103dce1c52e4af16f000338cfd7/pillow-12.0.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:6e51b71417049ad6ab14c49608b4a24d8fb3fe605e5dfabfe523b58064dc3d27", size = 6459789 }, - { url = "https://files.pythonhosted.org/packages/9c/14/4448bb0b5e0f22dd865290536d20ec8a23b64e2d04280b89139f09a36bb6/pillow-12.0.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:d120c38a42c234dc9a8c5de7ceaaf899cf33561956acb4941653f8bdc657aa79", size = 7130917 }, - { url = "https://files.pythonhosted.org/packages/dd/ca/16c6926cc1c015845745d5c16c9358e24282f1e588237a4c36d2b30f182f/pillow-12.0.0-cp313-cp313-win32.whl", hash = "sha256:4cc6b3b2efff105c6a1656cfe59da4fdde2cda9af1c5e0b58529b24525d0a098", size = 6302391 }, - { url = "https://files.pythonhosted.org/packages/6d/2a/dd43dcfd6dae9b6a49ee28a8eedb98c7d5ff2de94a5d834565164667b97b/pillow-12.0.0-cp313-cp313-win_amd64.whl", hash = "sha256:4cf7fed4b4580601c4345ceb5d4cbf5a980d030fd5ad07c4d2ec589f95f09905", size = 7007477 }, - { url = "https://files.pythonhosted.org/packages/77/f0/72ea067f4b5ae5ead653053212af05ce3705807906ba3f3e8f58ddf617e6/pillow-12.0.0-cp313-cp313-win_arm64.whl", hash = "sha256:9f0b04c6b8584c2c193babcccc908b38ed29524b29dd464bc8801bf10d746a3a", size = 2435918 }, - { url = "https://files.pythonhosted.org/packages/f5/5e/9046b423735c21f0487ea6cb5b10f89ea8f8dfbe32576fe052b5ba9d4e5b/pillow-12.0.0-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:7fa22993bac7b77b78cae22bad1e2a987ddf0d9015c63358032f84a53f23cdc3", size = 5251406 }, - { url = "https://files.pythonhosted.org/packages/12/66/982ceebcdb13c97270ef7a56c3969635b4ee7cd45227fa707c94719229c5/pillow-12.0.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:f135c702ac42262573fe9714dfe99c944b4ba307af5eb507abef1667e2cbbced", size = 4653218 }, - { url = "https://files.pythonhosted.org/packages/16/b3/81e625524688c31859450119bf12674619429cab3119eec0e30a7a1029cb/pillow-12.0.0-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:c85de1136429c524e55cfa4e033b4a7940ac5c8ee4d9401cc2d1bf48154bbc7b", size = 6266564 }, - { url = "https://files.pythonhosted.org/packages/98/59/dfb38f2a41240d2408096e1a76c671d0a105a4a8471b1871c6902719450c/pillow-12.0.0-cp313-cp313t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:38df9b4bfd3db902c9c2bd369bcacaf9d935b2fff73709429d95cc41554f7b3d", size = 8069260 }, - { url = "https://files.pythonhosted.org/packages/dc/3d/378dbea5cd1874b94c312425ca77b0f47776c78e0df2df751b820c8c1d6c/pillow-12.0.0-cp313-cp313t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:7d87ef5795da03d742bf49439f9ca4d027cde49c82c5371ba52464aee266699a", size = 6379248 }, - { url = "https://files.pythonhosted.org/packages/84/b0/d525ef47d71590f1621510327acec75ae58c721dc071b17d8d652ca494d8/pillow-12.0.0-cp313-cp313t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:aff9e4d82d082ff9513bdd6acd4f5bd359f5b2c870907d2b0a9c5e10d40c88fe", size = 7066043 }, - { url = "https://files.pythonhosted.org/packages/61/2c/aced60e9cf9d0cde341d54bf7932c9ffc33ddb4a1595798b3a5150c7ec4e/pillow-12.0.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:8d8ca2b210ada074d57fcee40c30446c9562e542fc46aedc19baf758a93532ee", size = 6490915 }, - { url = "https://files.pythonhosted.org/packages/ef/26/69dcb9b91f4e59f8f34b2332a4a0a951b44f547c4ed39d3e4dcfcff48f89/pillow-12.0.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:99a7f72fb6249302aa62245680754862a44179b545ded638cf1fef59befb57ef", size = 7157998 }, - { url = "https://files.pythonhosted.org/packages/61/2b/726235842220ca95fa441ddf55dd2382b52ab5b8d9c0596fe6b3f23dafe8/pillow-12.0.0-cp313-cp313t-win32.whl", hash = "sha256:4078242472387600b2ce8d93ade8899c12bf33fa89e55ec89fe126e9d6d5d9e9", size = 6306201 }, - { url = "https://files.pythonhosted.org/packages/c0/3d/2afaf4e840b2df71344ababf2f8edd75a705ce500e5dc1e7227808312ae1/pillow-12.0.0-cp313-cp313t-win_amd64.whl", hash = "sha256:2c54c1a783d6d60595d3514f0efe9b37c8808746a66920315bfd34a938d7994b", size = 7013165 }, - { url = "https://files.pythonhosted.org/packages/6f/75/3fa09aa5cf6ed04bee3fa575798ddf1ce0bace8edb47249c798077a81f7f/pillow-12.0.0-cp313-cp313t-win_arm64.whl", hash = "sha256:26d9f7d2b604cd23aba3e9faf795787456ac25634d82cd060556998e39c6fa47", size = 2437834 }, - { url = "https://files.pythonhosted.org/packages/54/2a/9a8c6ba2c2c07b71bec92cf63e03370ca5e5f5c5b119b742bcc0cde3f9c5/pillow-12.0.0-cp314-cp314-ios_13_0_arm64_iphoneos.whl", hash = "sha256:beeae3f27f62308f1ddbcfb0690bf44b10732f2ef43758f169d5e9303165d3f9", size = 4045531 }, - { url = "https://files.pythonhosted.org/packages/84/54/836fdbf1bfb3d66a59f0189ff0b9f5f666cee09c6188309300df04ad71fa/pillow-12.0.0-cp314-cp314-ios_13_0_arm64_iphonesimulator.whl", hash = "sha256:d4827615da15cd59784ce39d3388275ec093ae3ee8d7f0c089b76fa87af756c2", size = 4120554 }, - { url = "https://files.pythonhosted.org/packages/0d/cd/16aec9f0da4793e98e6b54778a5fbce4f375c6646fe662e80600b8797379/pillow-12.0.0-cp314-cp314-ios_13_0_x86_64_iphonesimulator.whl", hash = "sha256:3e42edad50b6909089750e65c91aa09aaf1e0a71310d383f11321b27c224ed8a", size = 3576812 }, - { url = "https://files.pythonhosted.org/packages/f6/b7/13957fda356dc46339298b351cae0d327704986337c3c69bb54628c88155/pillow-12.0.0-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:e5d8efac84c9afcb40914ab49ba063d94f5dbdf5066db4482c66a992f47a3a3b", size = 5252689 }, - { url = "https://files.pythonhosted.org/packages/fc/f5/eae31a306341d8f331f43edb2e9122c7661b975433de5e447939ae61c5da/pillow-12.0.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:266cd5f2b63ff316d5a1bba46268e603c9caf5606d44f38c2873c380950576ad", size = 4650186 }, - { url = "https://files.pythonhosted.org/packages/86/62/2a88339aa40c4c77e79108facbd307d6091e2c0eb5b8d3cf4977cfca2fe6/pillow-12.0.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:58eea5ebe51504057dd95c5b77d21700b77615ab0243d8152793dc00eb4faf01", size = 6230308 }, - { url = "https://files.pythonhosted.org/packages/c7/33/5425a8992bcb32d1cb9fa3dd39a89e613d09a22f2c8083b7bf43c455f760/pillow-12.0.0-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:f13711b1a5ba512d647a0e4ba79280d3a9a045aaf7e0cc6fbe96b91d4cdf6b0c", size = 8039222 }, - { url = "https://files.pythonhosted.org/packages/d8/61/3f5d3b35c5728f37953d3eec5b5f3e77111949523bd2dd7f31a851e50690/pillow-12.0.0-cp314-cp314-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6846bd2d116ff42cba6b646edf5bf61d37e5cbd256425fa089fee4ff5c07a99e", size = 6346657 }, - { url = "https://files.pythonhosted.org/packages/3a/be/ee90a3d79271227e0f0a33c453531efd6ed14b2e708596ba5dd9be948da3/pillow-12.0.0-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c98fa880d695de164b4135a52fd2e9cd7b7c90a9d8ac5e9e443a24a95ef9248e", size = 7038482 }, - { url = "https://files.pythonhosted.org/packages/44/34/a16b6a4d1ad727de390e9bd9f19f5f669e079e5826ec0f329010ddea492f/pillow-12.0.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:fa3ed2a29a9e9d2d488b4da81dcb54720ac3104a20bf0bd273f1e4648aff5af9", size = 6461416 }, - { url = "https://files.pythonhosted.org/packages/b6/39/1aa5850d2ade7d7ba9f54e4e4c17077244ff7a2d9e25998c38a29749eb3f/pillow-12.0.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:d034140032870024e6b9892c692fe2968493790dd57208b2c37e3fb35f6df3ab", size = 7131584 }, - { url = "https://files.pythonhosted.org/packages/bf/db/4fae862f8fad0167073a7733973bfa955f47e2cac3dc3e3e6257d10fab4a/pillow-12.0.0-cp314-cp314-win32.whl", hash = "sha256:1b1b133e6e16105f524a8dec491e0586d072948ce15c9b914e41cdadd209052b", size = 6400621 }, - { url = "https://files.pythonhosted.org/packages/2b/24/b350c31543fb0107ab2599464d7e28e6f856027aadda995022e695313d94/pillow-12.0.0-cp314-cp314-win_amd64.whl", hash = "sha256:8dc232e39d409036af549c86f24aed8273a40ffa459981146829a324e0848b4b", size = 7142916 }, - { url = "https://files.pythonhosted.org/packages/0f/9b/0ba5a6fd9351793996ef7487c4fdbde8d3f5f75dbedc093bb598648fddf0/pillow-12.0.0-cp314-cp314-win_arm64.whl", hash = "sha256:d52610d51e265a51518692045e372a4c363056130d922a7351429ac9f27e70b0", size = 2523836 }, - { url = "https://files.pythonhosted.org/packages/f5/7a/ceee0840aebc579af529b523d530840338ecf63992395842e54edc805987/pillow-12.0.0-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:1979f4566bb96c1e50a62d9831e2ea2d1211761e5662afc545fa766f996632f6", size = 5255092 }, - { url = "https://files.pythonhosted.org/packages/44/76/20776057b4bfd1aef4eeca992ebde0f53a4dce874f3ae693d0ec90a4f79b/pillow-12.0.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:b2e4b27a6e15b04832fe9bf292b94b5ca156016bbc1ea9c2c20098a0320d6cf6", size = 4653158 }, - { url = "https://files.pythonhosted.org/packages/82/3f/d9ff92ace07be8836b4e7e87e6a4c7a8318d47c2f1463ffcf121fc57d9cb/pillow-12.0.0-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:fb3096c30df99fd01c7bf8e544f392103d0795b9f98ba71a8054bcbf56b255f1", size = 6267882 }, - { url = "https://files.pythonhosted.org/packages/9f/7a/4f7ff87f00d3ad33ba21af78bfcd2f032107710baf8280e3722ceec28cda/pillow-12.0.0-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:7438839e9e053ef79f7112c881cef684013855016f928b168b81ed5835f3e75e", size = 8071001 }, - { url = "https://files.pythonhosted.org/packages/75/87/fcea108944a52dad8cca0715ae6247e271eb80459364a98518f1e4f480c1/pillow-12.0.0-cp314-cp314t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:5d5c411a8eaa2299322b647cd932586b1427367fd3184ffbb8f7a219ea2041ca", size = 6380146 }, - { url = "https://files.pythonhosted.org/packages/91/52/0d31b5e571ef5fd111d2978b84603fce26aba1b6092f28e941cb46570745/pillow-12.0.0-cp314-cp314t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:d7e091d464ac59d2c7ad8e7e08105eaf9dafbc3883fd7265ffccc2baad6ac925", size = 7067344 }, - { url = "https://files.pythonhosted.org/packages/7b/f4/2dd3d721f875f928d48e83bb30a434dee75a2531bca839bb996bb0aa5a91/pillow-12.0.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:792a2c0be4dcc18af9d4a2dfd8a11a17d5e25274a1062b0ec1c2d79c76f3e7f8", size = 6491864 }, - { url = "https://files.pythonhosted.org/packages/30/4b/667dfcf3d61fc309ba5a15b141845cece5915e39b99c1ceab0f34bf1d124/pillow-12.0.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:afbefa430092f71a9593a99ab6a4e7538bc9eabbf7bf94f91510d3503943edc4", size = 7158911 }, - { url = "https://files.pythonhosted.org/packages/a2/2f/16cabcc6426c32218ace36bf0d55955e813f2958afddbf1d391849fee9d1/pillow-12.0.0-cp314-cp314t-win32.whl", hash = "sha256:3830c769decf88f1289680a59d4f4c46c72573446352e2befec9a8512104fa52", size = 6408045 }, - { url = "https://files.pythonhosted.org/packages/35/73/e29aa0c9c666cf787628d3f0dcf379f4791fba79f4936d02f8b37165bdf8/pillow-12.0.0-cp314-cp314t-win_amd64.whl", hash = "sha256:905b0365b210c73afb0ebe9101a32572152dfd1c144c7e28968a331b9217b94a", size = 7148282 }, - { url = "https://files.pythonhosted.org/packages/c1/70/6b41bdcddf541b437bbb9f47f94d2db5d9ddef6c37ccab8c9107743748a4/pillow-12.0.0-cp314-cp314t-win_arm64.whl", hash = "sha256:99353a06902c2e43b43e8ff74ee65a7d90307d82370604746738a1e0661ccca7", size = 2525630 }, +sdist = { url = "https://files.pythonhosted.org/packages/5a/b0/cace85a1b0c9775a9f8f5d5423c8261c858760e2466c79b2dd184638b056/pillow-12.0.0.tar.gz", hash = "sha256:87d4f8125c9988bfbed67af47dd7a953e2fc7b0cc1e7800ec6d2080d490bb353", size = 47008828, upload-time = "2025-10-15T18:24:14.008Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/62/f2/de993bb2d21b33a98d031ecf6a978e4b61da207bef02f7b43093774c480d/pillow-12.0.0-cp313-cp313-ios_13_0_arm64_iphoneos.whl", hash = "sha256:0869154a2d0546545cde61d1789a6524319fc1897d9ee31218eae7a60ccc5643", size = 4045493, upload-time = "2025-10-15T18:22:25.758Z" }, + { url = "https://files.pythonhosted.org/packages/0e/b6/bc8d0c4c9f6f111a783d045310945deb769b806d7574764234ffd50bc5ea/pillow-12.0.0-cp313-cp313-ios_13_0_arm64_iphonesimulator.whl", hash = "sha256:a7921c5a6d31b3d756ec980f2f47c0cfdbce0fc48c22a39347a895f41f4a6ea4", size = 4120461, upload-time = "2025-10-15T18:22:27.286Z" }, + { url = "https://files.pythonhosted.org/packages/5d/57/d60d343709366a353dc56adb4ee1e7d8a2cc34e3fbc22905f4167cfec119/pillow-12.0.0-cp313-cp313-ios_13_0_x86_64_iphonesimulator.whl", hash = "sha256:1ee80a59f6ce048ae13cda1abf7fbd2a34ab9ee7d401c46be3ca685d1999a399", size = 3576912, upload-time = "2025-10-15T18:22:28.751Z" }, + { url = "https://files.pythonhosted.org/packages/a4/a4/a0a31467e3f83b94d37568294b01d22b43ae3c5d85f2811769b9c66389dd/pillow-12.0.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:c50f36a62a22d350c96e49ad02d0da41dbd17ddc2e29750dbdba4323f85eb4a5", size = 5249132, upload-time = "2025-10-15T18:22:30.641Z" }, + { url = "https://files.pythonhosted.org/packages/83/06/48eab21dd561de2914242711434c0c0eb992ed08ff3f6107a5f44527f5e9/pillow-12.0.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:5193fde9a5f23c331ea26d0cf171fbf67e3f247585f50c08b3e205c7aeb4589b", size = 4650099, upload-time = "2025-10-15T18:22:32.73Z" }, + { url = "https://files.pythonhosted.org/packages/fc/bd/69ed99fd46a8dba7c1887156d3572fe4484e3f031405fcc5a92e31c04035/pillow-12.0.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:bde737cff1a975b70652b62d626f7785e0480918dece11e8fef3c0cf057351c3", size = 6230808, upload-time = "2025-10-15T18:22:34.337Z" }, + { url = "https://files.pythonhosted.org/packages/ea/94/8fad659bcdbf86ed70099cb60ae40be6acca434bbc8c4c0d4ef356d7e0de/pillow-12.0.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:a6597ff2b61d121172f5844b53f21467f7082f5fb385a9a29c01414463f93b07", size = 8037804, upload-time = "2025-10-15T18:22:36.402Z" }, + { url = "https://files.pythonhosted.org/packages/20/39/c685d05c06deecfd4e2d1950e9a908aa2ca8bc4e6c3b12d93b9cafbd7837/pillow-12.0.0-cp313-cp313-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:0b817e7035ea7f6b942c13aa03bb554fc44fea70838ea21f8eb31c638326584e", size = 6345553, upload-time = "2025-10-15T18:22:38.066Z" }, + { url = "https://files.pythonhosted.org/packages/38/57/755dbd06530a27a5ed74f8cb0a7a44a21722ebf318edbe67ddbd7fb28f88/pillow-12.0.0-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:f4f1231b7dec408e8670264ce63e9c71409d9583dd21d32c163e25213ee2a344", size = 7037729, upload-time = "2025-10-15T18:22:39.769Z" }, + { url = "https://files.pythonhosted.org/packages/ca/b6/7e94f4c41d238615674d06ed677c14883103dce1c52e4af16f000338cfd7/pillow-12.0.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:6e51b71417049ad6ab14c49608b4a24d8fb3fe605e5dfabfe523b58064dc3d27", size = 6459789, upload-time = "2025-10-15T18:22:41.437Z" }, + { url = "https://files.pythonhosted.org/packages/9c/14/4448bb0b5e0f22dd865290536d20ec8a23b64e2d04280b89139f09a36bb6/pillow-12.0.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:d120c38a42c234dc9a8c5de7ceaaf899cf33561956acb4941653f8bdc657aa79", size = 7130917, upload-time = "2025-10-15T18:22:43.152Z" }, + { url = "https://files.pythonhosted.org/packages/dd/ca/16c6926cc1c015845745d5c16c9358e24282f1e588237a4c36d2b30f182f/pillow-12.0.0-cp313-cp313-win32.whl", hash = "sha256:4cc6b3b2efff105c6a1656cfe59da4fdde2cda9af1c5e0b58529b24525d0a098", size = 6302391, upload-time = "2025-10-15T18:22:44.753Z" }, + { url = "https://files.pythonhosted.org/packages/6d/2a/dd43dcfd6dae9b6a49ee28a8eedb98c7d5ff2de94a5d834565164667b97b/pillow-12.0.0-cp313-cp313-win_amd64.whl", hash = "sha256:4cf7fed4b4580601c4345ceb5d4cbf5a980d030fd5ad07c4d2ec589f95f09905", size = 7007477, upload-time = "2025-10-15T18:22:46.838Z" }, + { url = "https://files.pythonhosted.org/packages/77/f0/72ea067f4b5ae5ead653053212af05ce3705807906ba3f3e8f58ddf617e6/pillow-12.0.0-cp313-cp313-win_arm64.whl", hash = "sha256:9f0b04c6b8584c2c193babcccc908b38ed29524b29dd464bc8801bf10d746a3a", size = 2435918, upload-time = "2025-10-15T18:22:48.399Z" }, + { url = "https://files.pythonhosted.org/packages/f5/5e/9046b423735c21f0487ea6cb5b10f89ea8f8dfbe32576fe052b5ba9d4e5b/pillow-12.0.0-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:7fa22993bac7b77b78cae22bad1e2a987ddf0d9015c63358032f84a53f23cdc3", size = 5251406, upload-time = "2025-10-15T18:22:49.905Z" }, + { url = "https://files.pythonhosted.org/packages/12/66/982ceebcdb13c97270ef7a56c3969635b4ee7cd45227fa707c94719229c5/pillow-12.0.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:f135c702ac42262573fe9714dfe99c944b4ba307af5eb507abef1667e2cbbced", size = 4653218, upload-time = "2025-10-15T18:22:51.587Z" }, + { url = "https://files.pythonhosted.org/packages/16/b3/81e625524688c31859450119bf12674619429cab3119eec0e30a7a1029cb/pillow-12.0.0-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:c85de1136429c524e55cfa4e033b4a7940ac5c8ee4d9401cc2d1bf48154bbc7b", size = 6266564, upload-time = "2025-10-15T18:22:53.215Z" }, + { url = "https://files.pythonhosted.org/packages/98/59/dfb38f2a41240d2408096e1a76c671d0a105a4a8471b1871c6902719450c/pillow-12.0.0-cp313-cp313t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:38df9b4bfd3db902c9c2bd369bcacaf9d935b2fff73709429d95cc41554f7b3d", size = 8069260, upload-time = "2025-10-15T18:22:54.933Z" }, + { url = "https://files.pythonhosted.org/packages/dc/3d/378dbea5cd1874b94c312425ca77b0f47776c78e0df2df751b820c8c1d6c/pillow-12.0.0-cp313-cp313t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:7d87ef5795da03d742bf49439f9ca4d027cde49c82c5371ba52464aee266699a", size = 6379248, upload-time = "2025-10-15T18:22:56.605Z" }, + { url = "https://files.pythonhosted.org/packages/84/b0/d525ef47d71590f1621510327acec75ae58c721dc071b17d8d652ca494d8/pillow-12.0.0-cp313-cp313t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:aff9e4d82d082ff9513bdd6acd4f5bd359f5b2c870907d2b0a9c5e10d40c88fe", size = 7066043, upload-time = "2025-10-15T18:22:58.53Z" }, + { url = "https://files.pythonhosted.org/packages/61/2c/aced60e9cf9d0cde341d54bf7932c9ffc33ddb4a1595798b3a5150c7ec4e/pillow-12.0.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:8d8ca2b210ada074d57fcee40c30446c9562e542fc46aedc19baf758a93532ee", size = 6490915, upload-time = "2025-10-15T18:23:00.582Z" }, + { url = "https://files.pythonhosted.org/packages/ef/26/69dcb9b91f4e59f8f34b2332a4a0a951b44f547c4ed39d3e4dcfcff48f89/pillow-12.0.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:99a7f72fb6249302aa62245680754862a44179b545ded638cf1fef59befb57ef", size = 7157998, upload-time = "2025-10-15T18:23:02.627Z" }, + { url = "https://files.pythonhosted.org/packages/61/2b/726235842220ca95fa441ddf55dd2382b52ab5b8d9c0596fe6b3f23dafe8/pillow-12.0.0-cp313-cp313t-win32.whl", hash = "sha256:4078242472387600b2ce8d93ade8899c12bf33fa89e55ec89fe126e9d6d5d9e9", size = 6306201, upload-time = "2025-10-15T18:23:04.709Z" }, + { url = "https://files.pythonhosted.org/packages/c0/3d/2afaf4e840b2df71344ababf2f8edd75a705ce500e5dc1e7227808312ae1/pillow-12.0.0-cp313-cp313t-win_amd64.whl", hash = "sha256:2c54c1a783d6d60595d3514f0efe9b37c8808746a66920315bfd34a938d7994b", size = 7013165, upload-time = "2025-10-15T18:23:06.46Z" }, + { url = "https://files.pythonhosted.org/packages/6f/75/3fa09aa5cf6ed04bee3fa575798ddf1ce0bace8edb47249c798077a81f7f/pillow-12.0.0-cp313-cp313t-win_arm64.whl", hash = "sha256:26d9f7d2b604cd23aba3e9faf795787456ac25634d82cd060556998e39c6fa47", size = 2437834, upload-time = "2025-10-15T18:23:08.194Z" }, + { url = "https://files.pythonhosted.org/packages/54/2a/9a8c6ba2c2c07b71bec92cf63e03370ca5e5f5c5b119b742bcc0cde3f9c5/pillow-12.0.0-cp314-cp314-ios_13_0_arm64_iphoneos.whl", hash = "sha256:beeae3f27f62308f1ddbcfb0690bf44b10732f2ef43758f169d5e9303165d3f9", size = 4045531, upload-time = "2025-10-15T18:23:10.121Z" }, + { url = "https://files.pythonhosted.org/packages/84/54/836fdbf1bfb3d66a59f0189ff0b9f5f666cee09c6188309300df04ad71fa/pillow-12.0.0-cp314-cp314-ios_13_0_arm64_iphonesimulator.whl", hash = "sha256:d4827615da15cd59784ce39d3388275ec093ae3ee8d7f0c089b76fa87af756c2", size = 4120554, upload-time = "2025-10-15T18:23:12.14Z" }, + { url = "https://files.pythonhosted.org/packages/0d/cd/16aec9f0da4793e98e6b54778a5fbce4f375c6646fe662e80600b8797379/pillow-12.0.0-cp314-cp314-ios_13_0_x86_64_iphonesimulator.whl", hash = "sha256:3e42edad50b6909089750e65c91aa09aaf1e0a71310d383f11321b27c224ed8a", size = 3576812, upload-time = "2025-10-15T18:23:13.962Z" }, + { url = "https://files.pythonhosted.org/packages/f6/b7/13957fda356dc46339298b351cae0d327704986337c3c69bb54628c88155/pillow-12.0.0-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:e5d8efac84c9afcb40914ab49ba063d94f5dbdf5066db4482c66a992f47a3a3b", size = 5252689, upload-time = "2025-10-15T18:23:15.562Z" }, + { url = "https://files.pythonhosted.org/packages/fc/f5/eae31a306341d8f331f43edb2e9122c7661b975433de5e447939ae61c5da/pillow-12.0.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:266cd5f2b63ff316d5a1bba46268e603c9caf5606d44f38c2873c380950576ad", size = 4650186, upload-time = "2025-10-15T18:23:17.379Z" }, + { url = "https://files.pythonhosted.org/packages/86/62/2a88339aa40c4c77e79108facbd307d6091e2c0eb5b8d3cf4977cfca2fe6/pillow-12.0.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:58eea5ebe51504057dd95c5b77d21700b77615ab0243d8152793dc00eb4faf01", size = 6230308, upload-time = "2025-10-15T18:23:18.971Z" }, + { url = "https://files.pythonhosted.org/packages/c7/33/5425a8992bcb32d1cb9fa3dd39a89e613d09a22f2c8083b7bf43c455f760/pillow-12.0.0-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:f13711b1a5ba512d647a0e4ba79280d3a9a045aaf7e0cc6fbe96b91d4cdf6b0c", size = 8039222, upload-time = "2025-10-15T18:23:20.909Z" }, + { url = "https://files.pythonhosted.org/packages/d8/61/3f5d3b35c5728f37953d3eec5b5f3e77111949523bd2dd7f31a851e50690/pillow-12.0.0-cp314-cp314-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6846bd2d116ff42cba6b646edf5bf61d37e5cbd256425fa089fee4ff5c07a99e", size = 6346657, upload-time = "2025-10-15T18:23:23.077Z" }, + { url = "https://files.pythonhosted.org/packages/3a/be/ee90a3d79271227e0f0a33c453531efd6ed14b2e708596ba5dd9be948da3/pillow-12.0.0-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c98fa880d695de164b4135a52fd2e9cd7b7c90a9d8ac5e9e443a24a95ef9248e", size = 7038482, upload-time = "2025-10-15T18:23:25.005Z" }, + { url = "https://files.pythonhosted.org/packages/44/34/a16b6a4d1ad727de390e9bd9f19f5f669e079e5826ec0f329010ddea492f/pillow-12.0.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:fa3ed2a29a9e9d2d488b4da81dcb54720ac3104a20bf0bd273f1e4648aff5af9", size = 6461416, upload-time = "2025-10-15T18:23:27.009Z" }, + { url = "https://files.pythonhosted.org/packages/b6/39/1aa5850d2ade7d7ba9f54e4e4c17077244ff7a2d9e25998c38a29749eb3f/pillow-12.0.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:d034140032870024e6b9892c692fe2968493790dd57208b2c37e3fb35f6df3ab", size = 7131584, upload-time = "2025-10-15T18:23:29.752Z" }, + { url = "https://files.pythonhosted.org/packages/bf/db/4fae862f8fad0167073a7733973bfa955f47e2cac3dc3e3e6257d10fab4a/pillow-12.0.0-cp314-cp314-win32.whl", hash = "sha256:1b1b133e6e16105f524a8dec491e0586d072948ce15c9b914e41cdadd209052b", size = 6400621, upload-time = "2025-10-15T18:23:32.06Z" }, + { url = "https://files.pythonhosted.org/packages/2b/24/b350c31543fb0107ab2599464d7e28e6f856027aadda995022e695313d94/pillow-12.0.0-cp314-cp314-win_amd64.whl", hash = "sha256:8dc232e39d409036af549c86f24aed8273a40ffa459981146829a324e0848b4b", size = 7142916, upload-time = "2025-10-15T18:23:34.71Z" }, + { url = "https://files.pythonhosted.org/packages/0f/9b/0ba5a6fd9351793996ef7487c4fdbde8d3f5f75dbedc093bb598648fddf0/pillow-12.0.0-cp314-cp314-win_arm64.whl", hash = "sha256:d52610d51e265a51518692045e372a4c363056130d922a7351429ac9f27e70b0", size = 2523836, upload-time = "2025-10-15T18:23:36.967Z" }, + { url = "https://files.pythonhosted.org/packages/f5/7a/ceee0840aebc579af529b523d530840338ecf63992395842e54edc805987/pillow-12.0.0-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:1979f4566bb96c1e50a62d9831e2ea2d1211761e5662afc545fa766f996632f6", size = 5255092, upload-time = "2025-10-15T18:23:38.573Z" }, + { url = "https://files.pythonhosted.org/packages/44/76/20776057b4bfd1aef4eeca992ebde0f53a4dce874f3ae693d0ec90a4f79b/pillow-12.0.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:b2e4b27a6e15b04832fe9bf292b94b5ca156016bbc1ea9c2c20098a0320d6cf6", size = 4653158, upload-time = "2025-10-15T18:23:40.238Z" }, + { url = "https://files.pythonhosted.org/packages/82/3f/d9ff92ace07be8836b4e7e87e6a4c7a8318d47c2f1463ffcf121fc57d9cb/pillow-12.0.0-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:fb3096c30df99fd01c7bf8e544f392103d0795b9f98ba71a8054bcbf56b255f1", size = 6267882, upload-time = "2025-10-15T18:23:42.434Z" }, + { url = "https://files.pythonhosted.org/packages/9f/7a/4f7ff87f00d3ad33ba21af78bfcd2f032107710baf8280e3722ceec28cda/pillow-12.0.0-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:7438839e9e053ef79f7112c881cef684013855016f928b168b81ed5835f3e75e", size = 8071001, upload-time = "2025-10-15T18:23:44.29Z" }, + { url = "https://files.pythonhosted.org/packages/75/87/fcea108944a52dad8cca0715ae6247e271eb80459364a98518f1e4f480c1/pillow-12.0.0-cp314-cp314t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:5d5c411a8eaa2299322b647cd932586b1427367fd3184ffbb8f7a219ea2041ca", size = 6380146, upload-time = "2025-10-15T18:23:46.065Z" }, + { url = "https://files.pythonhosted.org/packages/91/52/0d31b5e571ef5fd111d2978b84603fce26aba1b6092f28e941cb46570745/pillow-12.0.0-cp314-cp314t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:d7e091d464ac59d2c7ad8e7e08105eaf9dafbc3883fd7265ffccc2baad6ac925", size = 7067344, upload-time = "2025-10-15T18:23:47.898Z" }, + { url = "https://files.pythonhosted.org/packages/7b/f4/2dd3d721f875f928d48e83bb30a434dee75a2531bca839bb996bb0aa5a91/pillow-12.0.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:792a2c0be4dcc18af9d4a2dfd8a11a17d5e25274a1062b0ec1c2d79c76f3e7f8", size = 6491864, upload-time = "2025-10-15T18:23:49.607Z" }, + { url = "https://files.pythonhosted.org/packages/30/4b/667dfcf3d61fc309ba5a15b141845cece5915e39b99c1ceab0f34bf1d124/pillow-12.0.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:afbefa430092f71a9593a99ab6a4e7538bc9eabbf7bf94f91510d3503943edc4", size = 7158911, upload-time = "2025-10-15T18:23:51.351Z" }, + { url = "https://files.pythonhosted.org/packages/a2/2f/16cabcc6426c32218ace36bf0d55955e813f2958afddbf1d391849fee9d1/pillow-12.0.0-cp314-cp314t-win32.whl", hash = "sha256:3830c769decf88f1289680a59d4f4c46c72573446352e2befec9a8512104fa52", size = 6408045, upload-time = "2025-10-15T18:23:53.177Z" }, + { url = "https://files.pythonhosted.org/packages/35/73/e29aa0c9c666cf787628d3f0dcf379f4791fba79f4936d02f8b37165bdf8/pillow-12.0.0-cp314-cp314t-win_amd64.whl", hash = "sha256:905b0365b210c73afb0ebe9101a32572152dfd1c144c7e28968a331b9217b94a", size = 7148282, upload-time = "2025-10-15T18:23:55.316Z" }, + { url = "https://files.pythonhosted.org/packages/c1/70/6b41bdcddf541b437bbb9f47f94d2db5d9ddef6c37ccab8c9107743748a4/pillow-12.0.0-cp314-cp314t-win_arm64.whl", hash = "sha256:99353a06902c2e43b43e8ff74ee65a7d90307d82370604746738a1e0661ccca7", size = 2525630, upload-time = "2025-10-15T18:23:57.149Z" }, ] [[package]] name = "pluggy" version = "1.6.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/f9/e2/3e91f31a7d2b083fe6ef3fa267035b518369d9511ffab804f839851d2779/pluggy-1.6.0.tar.gz", hash = "sha256:7dcc130b76258d33b90f61b658791dede3486c3e6bfb003ee5c9bfb396dd22f3", size = 69412 } +sdist = { url = "https://files.pythonhosted.org/packages/f9/e2/3e91f31a7d2b083fe6ef3fa267035b518369d9511ffab804f839851d2779/pluggy-1.6.0.tar.gz", hash = "sha256:7dcc130b76258d33b90f61b658791dede3486c3e6bfb003ee5c9bfb396dd22f3", size = 69412, upload-time = "2025-05-15T12:30:07.975Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/54/20/4d324d65cc6d9205fabedc306948156824eb9f0ee1633355a8f7ec5c66bf/pluggy-1.6.0-py3-none-any.whl", hash = "sha256:e920276dd6813095e9377c0bc5566d94c932c33b27a3e3945d8389c374dd4746", size = 20538 }, + { url = "https://files.pythonhosted.org/packages/54/20/4d324d65cc6d9205fabedc306948156824eb9f0ee1633355a8f7ec5c66bf/pluggy-1.6.0-py3-none-any.whl", hash = "sha256:e920276dd6813095e9377c0bc5566d94c932c33b27a3e3945d8389c374dd4746", size = 20538, upload-time = "2025-05-15T12:30:06.134Z" }, ] [[package]] @@ -1327,24 +1327,24 @@ source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "protobuf" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/f4/ac/87285f15f7cce6d4a008f33f1757fb5a13611ea8914eb58c3d0d26243468/proto_plus-1.26.1.tar.gz", hash = "sha256:21a515a4c4c0088a773899e23c7bbade3d18f9c66c73edd4c7ee3816bc96a012", size = 56142 } +sdist = { url = "https://files.pythonhosted.org/packages/f4/ac/87285f15f7cce6d4a008f33f1757fb5a13611ea8914eb58c3d0d26243468/proto_plus-1.26.1.tar.gz", hash = "sha256:21a515a4c4c0088a773899e23c7bbade3d18f9c66c73edd4c7ee3816bc96a012", size = 56142, upload-time = "2025-03-10T15:54:38.843Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/4e/6d/280c4c2ce28b1593a19ad5239c8b826871fc6ec275c21afc8e1820108039/proto_plus-1.26.1-py3-none-any.whl", hash = "sha256:13285478c2dcf2abb829db158e1047e2f1e8d63a077d94263c2b88b043c75a66", size = 50163 }, + { url = "https://files.pythonhosted.org/packages/4e/6d/280c4c2ce28b1593a19ad5239c8b826871fc6ec275c21afc8e1820108039/proto_plus-1.26.1-py3-none-any.whl", hash = "sha256:13285478c2dcf2abb829db158e1047e2f1e8d63a077d94263c2b88b043c75a66", size = 50163, upload-time = "2025-03-10T15:54:37.335Z" }, ] [[package]] name = "protobuf" version = "6.33.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/19/ff/64a6c8f420818bb873713988ca5492cba3a7946be57e027ac63495157d97/protobuf-6.33.0.tar.gz", hash = "sha256:140303d5c8d2037730c548f8c7b93b20bb1dc301be280c378b82b8894589c954", size = 443463 } +sdist = { url = "https://files.pythonhosted.org/packages/19/ff/64a6c8f420818bb873713988ca5492cba3a7946be57e027ac63495157d97/protobuf-6.33.0.tar.gz", hash = "sha256:140303d5c8d2037730c548f8c7b93b20bb1dc301be280c378b82b8894589c954", size = 443463, upload-time = "2025-10-15T20:39:52.159Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/7e/ee/52b3fa8feb6db4a833dfea4943e175ce645144532e8a90f72571ad85df4e/protobuf-6.33.0-cp310-abi3-win32.whl", hash = "sha256:d6101ded078042a8f17959eccd9236fb7a9ca20d3b0098bbcb91533a5680d035", size = 425593 }, - { url = "https://files.pythonhosted.org/packages/7b/c6/7a465f1825872c55e0341ff4a80198743f73b69ce5d43ab18043699d1d81/protobuf-6.33.0-cp310-abi3-win_amd64.whl", hash = "sha256:9a031d10f703f03768f2743a1c403af050b6ae1f3480e9c140f39c45f81b13ee", size = 436882 }, - { url = "https://files.pythonhosted.org/packages/e1/a9/b6eee662a6951b9c3640e8e452ab3e09f117d99fc10baa32d1581a0d4099/protobuf-6.33.0-cp39-abi3-macosx_10_9_universal2.whl", hash = "sha256:905b07a65f1a4b72412314082c7dbfae91a9e8b68a0cc1577515f8df58ecf455", size = 427521 }, - { url = "https://files.pythonhosted.org/packages/10/35/16d31e0f92c6d2f0e77c2a3ba93185130ea13053dd16200a57434c882f2b/protobuf-6.33.0-cp39-abi3-manylinux2014_aarch64.whl", hash = "sha256:e0697ece353e6239b90ee43a9231318302ad8353c70e6e45499fa52396debf90", size = 324445 }, - { url = "https://files.pythonhosted.org/packages/e6/eb/2a981a13e35cda8b75b5585aaffae2eb904f8f351bdd3870769692acbd8a/protobuf-6.33.0-cp39-abi3-manylinux2014_s390x.whl", hash = "sha256:e0a1715e4f27355afd9570f3ea369735afc853a6c3951a6afe1f80d8569ad298", size = 339159 }, - { url = "https://files.pythonhosted.org/packages/21/51/0b1cbad62074439b867b4e04cc09b93f6699d78fd191bed2bbb44562e077/protobuf-6.33.0-cp39-abi3-manylinux2014_x86_64.whl", hash = "sha256:35be49fd3f4fefa4e6e2aacc35e8b837d6703c37a2168a55ac21e9b1bc7559ef", size = 323172 }, - { url = "https://files.pythonhosted.org/packages/07/d1/0a28c21707807c6aacd5dc9c3704b2aa1effbf37adebd8caeaf68b17a636/protobuf-6.33.0-py3-none-any.whl", hash = "sha256:25c9e1963c6734448ea2d308cfa610e692b801304ba0908d7bfa564ac5132995", size = 170477 }, + { url = "https://files.pythonhosted.org/packages/7e/ee/52b3fa8feb6db4a833dfea4943e175ce645144532e8a90f72571ad85df4e/protobuf-6.33.0-cp310-abi3-win32.whl", hash = "sha256:d6101ded078042a8f17959eccd9236fb7a9ca20d3b0098bbcb91533a5680d035", size = 425593, upload-time = "2025-10-15T20:39:40.29Z" }, + { url = "https://files.pythonhosted.org/packages/7b/c6/7a465f1825872c55e0341ff4a80198743f73b69ce5d43ab18043699d1d81/protobuf-6.33.0-cp310-abi3-win_amd64.whl", hash = "sha256:9a031d10f703f03768f2743a1c403af050b6ae1f3480e9c140f39c45f81b13ee", size = 436882, upload-time = "2025-10-15T20:39:42.841Z" }, + { url = "https://files.pythonhosted.org/packages/e1/a9/b6eee662a6951b9c3640e8e452ab3e09f117d99fc10baa32d1581a0d4099/protobuf-6.33.0-cp39-abi3-macosx_10_9_universal2.whl", hash = "sha256:905b07a65f1a4b72412314082c7dbfae91a9e8b68a0cc1577515f8df58ecf455", size = 427521, upload-time = "2025-10-15T20:39:43.803Z" }, + { url = "https://files.pythonhosted.org/packages/10/35/16d31e0f92c6d2f0e77c2a3ba93185130ea13053dd16200a57434c882f2b/protobuf-6.33.0-cp39-abi3-manylinux2014_aarch64.whl", hash = "sha256:e0697ece353e6239b90ee43a9231318302ad8353c70e6e45499fa52396debf90", size = 324445, upload-time = "2025-10-15T20:39:44.932Z" }, + { url = "https://files.pythonhosted.org/packages/e6/eb/2a981a13e35cda8b75b5585aaffae2eb904f8f351bdd3870769692acbd8a/protobuf-6.33.0-cp39-abi3-manylinux2014_s390x.whl", hash = "sha256:e0a1715e4f27355afd9570f3ea369735afc853a6c3951a6afe1f80d8569ad298", size = 339159, upload-time = "2025-10-15T20:39:46.186Z" }, + { url = "https://files.pythonhosted.org/packages/21/51/0b1cbad62074439b867b4e04cc09b93f6699d78fd191bed2bbb44562e077/protobuf-6.33.0-cp39-abi3-manylinux2014_x86_64.whl", hash = "sha256:35be49fd3f4fefa4e6e2aacc35e8b837d6703c37a2168a55ac21e9b1bc7559ef", size = 323172, upload-time = "2025-10-15T20:39:47.465Z" }, + { url = "https://files.pythonhosted.org/packages/07/d1/0a28c21707807c6aacd5dc9c3704b2aa1effbf37adebd8caeaf68b17a636/protobuf-6.33.0-py3-none-any.whl", hash = "sha256:25c9e1963c6734448ea2d308cfa610e692b801304ba0908d7bfa564ac5132995", size = 170477, upload-time = "2025-10-15T20:39:51.311Z" }, ] [[package]] @@ -1354,9 +1354,9 @@ source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "tzdata", marker = "sys_platform == 'win32'" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/a8/77/c72d10262b872617e509a0c60445afcc4ce2cd5cd6bc1c97700246d69c85/psycopg-3.2.12.tar.gz", hash = "sha256:85c08d6f6e2a897b16280e0ff6406bef29b1327c045db06d21f364d7cd5da90b", size = 160642 } +sdist = { url = "https://files.pythonhosted.org/packages/a8/77/c72d10262b872617e509a0c60445afcc4ce2cd5cd6bc1c97700246d69c85/psycopg-3.2.12.tar.gz", hash = "sha256:85c08d6f6e2a897b16280e0ff6406bef29b1327c045db06d21f364d7cd5da90b", size = 160642, upload-time = "2025-10-26T00:46:03.045Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/c8/28/8c4f90e415411dc9c78d6ba10b549baa324659907c13f64bfe3779d4066c/psycopg-3.2.12-py3-none-any.whl", hash = "sha256:8a1611a2d4c16ae37eada46438be9029a35bb959bb50b3d0e1e93c0f3d54c9ee", size = 206765 }, + { url = "https://files.pythonhosted.org/packages/c8/28/8c4f90e415411dc9c78d6ba10b549baa324659907c13f64bfe3779d4066c/psycopg-3.2.12-py3-none-any.whl", hash = "sha256:8a1611a2d4c16ae37eada46438be9029a35bb959bb50b3d0e1e93c0f3d54c9ee", size = 206765, upload-time = "2025-10-26T00:10:42.173Z" }, ] [package.optional-dependencies] @@ -1369,33 +1369,33 @@ name = "psycopg-binary" version = "3.2.12" source = { registry = "https://pypi.org/simple" } wheels = [ - { url = "https://files.pythonhosted.org/packages/b2/0b/9d480aba4a4864832c29e6fc94ddd34d9927c276448eb3b56ffe24ed064c/psycopg_binary-3.2.12-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:442f20153415f374ae5753ca618637611a41a3c58c56d16ce55f845d76a3cf7b", size = 4017829 }, - { url = "https://files.pythonhosted.org/packages/a4/f3/0d294b30349bde24a46741a1f27a10e8ab81e9f4118d27c2fe592acfb42a/psycopg_binary-3.2.12-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:79de3cc5adbf51677009a8fda35ac9e9e3686d5595ab4b0c43ec7099ece6aeb5", size = 4089835 }, - { url = "https://files.pythonhosted.org/packages/82/d4/ff82e318e5a55d6951b278d3af7b4c7c1b19344e3a3722b6613f156a38ea/psycopg_binary-3.2.12-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:095ccda59042a1239ac2fefe693a336cb5cecf8944a8d9e98b07f07e94e2b78d", size = 4625474 }, - { url = "https://files.pythonhosted.org/packages/b1/e8/2c9df6475a5ab6d614d516f4497c568d84f7d6c21d0e11444468c9786c9f/psycopg_binary-3.2.12-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:efab679a2c7d1bf7d0ec0e1ecb47fe764945eff75bb4321f2e699b30a12db9b3", size = 4720350 }, - { url = "https://files.pythonhosted.org/packages/74/f5/7aec81b0c41985dc006e2d5822486ad4b7c2a1a97a5a05e37dc2adaf1512/psycopg_binary-3.2.12-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:d369e79ad9647fc8217cbb51bbbf11f9a1ffca450be31d005340157ffe8e91b3", size = 4411621 }, - { url = "https://files.pythonhosted.org/packages/fc/15/d3cb41b8fa9d5f14320ab250545fbb66f9ddb481e448e618902672a806c0/psycopg_binary-3.2.12-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:eedc410f82007038030650aa58f620f9fe0009b9d6b04c3dc71cbd3bae5b2675", size = 3863081 }, - { url = "https://files.pythonhosted.org/packages/69/8a/72837664e63e3cd3aa145cedcf29e5c21257579739aba78ab7eb668f7d9c/psycopg_binary-3.2.12-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:f3bae4be7f6781bf6c9576eedcd5e1bb74468126fa6de991e47cdb1a8ea3a42a", size = 3537428 }, - { url = "https://files.pythonhosted.org/packages/cc/7e/1b78ae38e7d69e6d7fb1e2dcce101493f5fa429480bac3a68b876c9b1635/psycopg_binary-3.2.12-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:8ffe75fe6be902dadd439adf4228c98138a992088e073ede6dd34e7235f4e03e", size = 3585981 }, - { url = "https://files.pythonhosted.org/packages/a3/f8/245b4868b2dac46c3fb6383b425754ae55df1910c826d305ed414da03777/psycopg_binary-3.2.12-cp313-cp313-win_amd64.whl", hash = "sha256:2598d0e4f2f258da13df0560187b3f1dfc9b8688c46b9d90176360ae5212c3fc", size = 2912929 }, - { url = "https://files.pythonhosted.org/packages/5c/5b/76fbb40b981b73b285a00dccafc38cf67b7a9b3f7d4f2025dda7b896e7ef/psycopg_binary-3.2.12-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:dc68094e00a5a7e8c20de1d3a0d5e404a27f522e18f8eb62bbbc9f865c3c81ef", size = 4016868 }, - { url = "https://files.pythonhosted.org/packages/0e/08/8841ae3e2d1a3228e79eaaf5b7f991d15f0a231bb5031a114305b19724b1/psycopg_binary-3.2.12-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:2d55009eeddbef54c711093c986daaf361d2c4210aaa1ee905075a3b97a62441", size = 4090508 }, - { url = "https://files.pythonhosted.org/packages/05/de/a41f62230cf4095ae4547eceada218cf28c17e7f94376913c1c8dde9546f/psycopg_binary-3.2.12-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:66a031f22e4418016990446d3e38143826f03ad811b9f78f58e2afbc1d343f7a", size = 4629788 }, - { url = "https://files.pythonhosted.org/packages/45/19/529d92134eae44475f781a86d58cdf3edd0953e17c69762abf387a9f2636/psycopg_binary-3.2.12-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:58ed30d33c25d7dc8d2f06285e88493147c2a660cc94713e4b563a99efb80a1f", size = 4724124 }, - { url = "https://files.pythonhosted.org/packages/5c/f5/97344e87065f7c9713ce213a2cff7732936ec3af6622e4b2a88715a953f2/psycopg_binary-3.2.12-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:e0b5ccd03ca4749b8f66f38608ccbcb415cbd130d02de5eda80d042b83bee90e", size = 4411340 }, - { url = "https://files.pythonhosted.org/packages/b1/c2/34bce068f6bfb4c2e7bb1187bb64a3f3be254702b158c4ad05eacc0055cf/psycopg_binary-3.2.12-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:909de94de7dd4d6086098a5755562207114c9638ec42c52d84c8a440c45fe084", size = 3867815 }, - { url = "https://files.pythonhosted.org/packages/d1/a1/c647e01ab162e6bfa52380e23e486215e9d28ffd31e9cf3cb1e9ca59008b/psycopg_binary-3.2.12-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:7130effd0517881f3a852eff98729d51034128f0737f64f0d1c7ea8343d77bd7", size = 3541756 }, - { url = "https://files.pythonhosted.org/packages/6b/d0/795bdaa8c946a7b7126bf7ca8d4371eaaa613093e3ec341a0e50f52cbee2/psycopg_binary-3.2.12-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:89b3c5201ca616d69ca0c3c0003ca18f7170a679c445c7e386ebfb4f29aa738e", size = 3587950 }, - { url = "https://files.pythonhosted.org/packages/53/cf/10c3e95827a3ca8af332dfc471befec86e15a14dc83cee893c49a4910dad/psycopg_binary-3.2.12-cp314-cp314-win_amd64.whl", hash = "sha256:48a8e29f3e38fcf8d393b8fe460d83e39c107ad7e5e61cd3858a7569e0554a39", size = 3005787 }, + { url = "https://files.pythonhosted.org/packages/b2/0b/9d480aba4a4864832c29e6fc94ddd34d9927c276448eb3b56ffe24ed064c/psycopg_binary-3.2.12-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:442f20153415f374ae5753ca618637611a41a3c58c56d16ce55f845d76a3cf7b", size = 4017829, upload-time = "2025-10-26T00:26:27.031Z" }, + { url = "https://files.pythonhosted.org/packages/a4/f3/0d294b30349bde24a46741a1f27a10e8ab81e9f4118d27c2fe592acfb42a/psycopg_binary-3.2.12-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:79de3cc5adbf51677009a8fda35ac9e9e3686d5595ab4b0c43ec7099ece6aeb5", size = 4089835, upload-time = "2025-10-26T00:27:01.392Z" }, + { url = "https://files.pythonhosted.org/packages/82/d4/ff82e318e5a55d6951b278d3af7b4c7c1b19344e3a3722b6613f156a38ea/psycopg_binary-3.2.12-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:095ccda59042a1239ac2fefe693a336cb5cecf8944a8d9e98b07f07e94e2b78d", size = 4625474, upload-time = "2025-10-26T00:27:40.34Z" }, + { url = "https://files.pythonhosted.org/packages/b1/e8/2c9df6475a5ab6d614d516f4497c568d84f7d6c21d0e11444468c9786c9f/psycopg_binary-3.2.12-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:efab679a2c7d1bf7d0ec0e1ecb47fe764945eff75bb4321f2e699b30a12db9b3", size = 4720350, upload-time = "2025-10-26T00:28:20.104Z" }, + { url = "https://files.pythonhosted.org/packages/74/f5/7aec81b0c41985dc006e2d5822486ad4b7c2a1a97a5a05e37dc2adaf1512/psycopg_binary-3.2.12-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:d369e79ad9647fc8217cbb51bbbf11f9a1ffca450be31d005340157ffe8e91b3", size = 4411621, upload-time = "2025-10-26T00:28:59.104Z" }, + { url = "https://files.pythonhosted.org/packages/fc/15/d3cb41b8fa9d5f14320ab250545fbb66f9ddb481e448e618902672a806c0/psycopg_binary-3.2.12-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:eedc410f82007038030650aa58f620f9fe0009b9d6b04c3dc71cbd3bae5b2675", size = 3863081, upload-time = "2025-10-26T00:29:31.235Z" }, + { url = "https://files.pythonhosted.org/packages/69/8a/72837664e63e3cd3aa145cedcf29e5c21257579739aba78ab7eb668f7d9c/psycopg_binary-3.2.12-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:f3bae4be7f6781bf6c9576eedcd5e1bb74468126fa6de991e47cdb1a8ea3a42a", size = 3537428, upload-time = "2025-10-26T00:30:01.465Z" }, + { url = "https://files.pythonhosted.org/packages/cc/7e/1b78ae38e7d69e6d7fb1e2dcce101493f5fa429480bac3a68b876c9b1635/psycopg_binary-3.2.12-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:8ffe75fe6be902dadd439adf4228c98138a992088e073ede6dd34e7235f4e03e", size = 3585981, upload-time = "2025-10-26T00:30:31.635Z" }, + { url = "https://files.pythonhosted.org/packages/a3/f8/245b4868b2dac46c3fb6383b425754ae55df1910c826d305ed414da03777/psycopg_binary-3.2.12-cp313-cp313-win_amd64.whl", hash = "sha256:2598d0e4f2f258da13df0560187b3f1dfc9b8688c46b9d90176360ae5212c3fc", size = 2912929, upload-time = "2025-10-26T00:30:56.413Z" }, + { url = "https://files.pythonhosted.org/packages/5c/5b/76fbb40b981b73b285a00dccafc38cf67b7a9b3f7d4f2025dda7b896e7ef/psycopg_binary-3.2.12-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:dc68094e00a5a7e8c20de1d3a0d5e404a27f522e18f8eb62bbbc9f865c3c81ef", size = 4016868, upload-time = "2025-10-26T00:31:29.974Z" }, + { url = "https://files.pythonhosted.org/packages/0e/08/8841ae3e2d1a3228e79eaaf5b7f991d15f0a231bb5031a114305b19724b1/psycopg_binary-3.2.12-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:2d55009eeddbef54c711093c986daaf361d2c4210aaa1ee905075a3b97a62441", size = 4090508, upload-time = "2025-10-26T00:32:04.192Z" }, + { url = "https://files.pythonhosted.org/packages/05/de/a41f62230cf4095ae4547eceada218cf28c17e7f94376913c1c8dde9546f/psycopg_binary-3.2.12-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:66a031f22e4418016990446d3e38143826f03ad811b9f78f58e2afbc1d343f7a", size = 4629788, upload-time = "2025-10-26T00:32:43.28Z" }, + { url = "https://files.pythonhosted.org/packages/45/19/529d92134eae44475f781a86d58cdf3edd0953e17c69762abf387a9f2636/psycopg_binary-3.2.12-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:58ed30d33c25d7dc8d2f06285e88493147c2a660cc94713e4b563a99efb80a1f", size = 4724124, upload-time = "2025-10-26T00:33:22.594Z" }, + { url = "https://files.pythonhosted.org/packages/5c/f5/97344e87065f7c9713ce213a2cff7732936ec3af6622e4b2a88715a953f2/psycopg_binary-3.2.12-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:e0b5ccd03ca4749b8f66f38608ccbcb415cbd130d02de5eda80d042b83bee90e", size = 4411340, upload-time = "2025-10-26T00:34:00.759Z" }, + { url = "https://files.pythonhosted.org/packages/b1/c2/34bce068f6bfb4c2e7bb1187bb64a3f3be254702b158c4ad05eacc0055cf/psycopg_binary-3.2.12-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:909de94de7dd4d6086098a5755562207114c9638ec42c52d84c8a440c45fe084", size = 3867815, upload-time = "2025-10-26T00:34:33.181Z" }, + { url = "https://files.pythonhosted.org/packages/d1/a1/c647e01ab162e6bfa52380e23e486215e9d28ffd31e9cf3cb1e9ca59008b/psycopg_binary-3.2.12-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:7130effd0517881f3a852eff98729d51034128f0737f64f0d1c7ea8343d77bd7", size = 3541756, upload-time = "2025-10-26T00:35:08.622Z" }, + { url = "https://files.pythonhosted.org/packages/6b/d0/795bdaa8c946a7b7126bf7ca8d4371eaaa613093e3ec341a0e50f52cbee2/psycopg_binary-3.2.12-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:89b3c5201ca616d69ca0c3c0003ca18f7170a679c445c7e386ebfb4f29aa738e", size = 3587950, upload-time = "2025-10-26T00:35:41.183Z" }, + { url = "https://files.pythonhosted.org/packages/53/cf/10c3e95827a3ca8af332dfc471befec86e15a14dc83cee893c49a4910dad/psycopg_binary-3.2.12-cp314-cp314-win_amd64.whl", hash = "sha256:48a8e29f3e38fcf8d393b8fe460d83e39c107ad7e5e61cd3858a7569e0554a39", size = 3005787, upload-time = "2025-10-26T00:36:06.783Z" }, ] [[package]] name = "pwdlib" version = "0.2.1" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/82/a0/9daed437a6226f632a25d98d65d60ba02bdafa920c90dcb6454c611ead6c/pwdlib-0.2.1.tar.gz", hash = "sha256:9a1d8a8fa09a2f7ebf208265e55d7d008103cbdc82b9e4902ffdd1ade91add5e", size = 11699 } +sdist = { url = "https://files.pythonhosted.org/packages/82/a0/9daed437a6226f632a25d98d65d60ba02bdafa920c90dcb6454c611ead6c/pwdlib-0.2.1.tar.gz", hash = "sha256:9a1d8a8fa09a2f7ebf208265e55d7d008103cbdc82b9e4902ffdd1ade91add5e", size = 11699, upload-time = "2024-08-19T06:48:59.58Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/01/f3/0dae5078a486f0fdf4d4a1121e103bc42694a9da9bea7b0f2c63f29cfbd3/pwdlib-0.2.1-py3-none-any.whl", hash = "sha256:1823dc6f22eae472b540e889ecf57fd424051d6a4023ec0bcf7f0de2d9d7ef8c", size = 8082 }, + { url = "https://files.pythonhosted.org/packages/01/f3/0dae5078a486f0fdf4d4a1121e103bc42694a9da9bea7b0f2c63f29cfbd3/pwdlib-0.2.1-py3-none-any.whl", hash = "sha256:1823dc6f22eae472b540e889ecf57fd424051d6a4023ec0bcf7f0de2d9d7ef8c", size = 8082, upload-time = "2024-08-19T06:49:00.997Z" }, ] [package.optional-dependencies] @@ -1410,9 +1410,9 @@ bcrypt = [ name = "pyasn1" version = "0.6.1" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/ba/e9/01f1a64245b89f039897cb0130016d79f77d52669aae6ee7b159a6c4c018/pyasn1-0.6.1.tar.gz", hash = "sha256:6f580d2bdd84365380830acf45550f2511469f673cb4a5ae3857a3170128b034", size = 145322 } +sdist = { url = "https://files.pythonhosted.org/packages/ba/e9/01f1a64245b89f039897cb0130016d79f77d52669aae6ee7b159a6c4c018/pyasn1-0.6.1.tar.gz", hash = "sha256:6f580d2bdd84365380830acf45550f2511469f673cb4a5ae3857a3170128b034", size = 145322, upload-time = "2024-09-10T22:41:42.55Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/c8/f1/d6a797abb14f6283c0ddff96bbdd46937f64122b8c925cab503dd37f8214/pyasn1-0.6.1-py3-none-any.whl", hash = "sha256:0d632f46f2ba09143da3a8afe9e33fb6f92fa2320ab7e886e2d0f7672af84629", size = 83135 }, + { url = "https://files.pythonhosted.org/packages/c8/f1/d6a797abb14f6283c0ddff96bbdd46937f64122b8c925cab503dd37f8214/pyasn1-0.6.1-py3-none-any.whl", hash = "sha256:0d632f46f2ba09143da3a8afe9e33fb6f92fa2320ab7e886e2d0f7672af84629", size = 83135, upload-time = "2024-09-11T16:00:36.122Z" }, ] [[package]] @@ -1422,23 +1422,23 @@ source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "pyasn1" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/e9/e6/78ebbb10a8c8e4b61a59249394a4a594c1a7af95593dc933a349c8d00964/pyasn1_modules-0.4.2.tar.gz", hash = "sha256:677091de870a80aae844b1ca6134f54652fa2c8c5a52aa396440ac3106e941e6", size = 307892 } +sdist = { url = "https://files.pythonhosted.org/packages/e9/e6/78ebbb10a8c8e4b61a59249394a4a594c1a7af95593dc933a349c8d00964/pyasn1_modules-0.4.2.tar.gz", hash = "sha256:677091de870a80aae844b1ca6134f54652fa2c8c5a52aa396440ac3106e941e6", size = 307892, upload-time = "2025-03-28T02:41:22.17Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/47/8d/d529b5d697919ba8c11ad626e835d4039be708a35b0d22de83a269a6682c/pyasn1_modules-0.4.2-py3-none-any.whl", hash = "sha256:29253a9207ce32b64c3ac6600edc75368f98473906e8fd1043bd6b5b1de2c14a", size = 181259 }, + { url = "https://files.pythonhosted.org/packages/47/8d/d529b5d697919ba8c11ad626e835d4039be708a35b0d22de83a269a6682c/pyasn1_modules-0.4.2-py3-none-any.whl", hash = "sha256:29253a9207ce32b64c3ac6600edc75368f98473906e8fd1043bd6b5b1de2c14a", size = 181259, upload-time = "2025-03-28T02:41:19.028Z" }, ] [[package]] name = "pycparser" version = "2.23" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/fe/cf/d2d3b9f5699fb1e4615c8e32ff220203e43b248e1dfcc6736ad9057731ca/pycparser-2.23.tar.gz", hash = "sha256:78816d4f24add8f10a06d6f05b4d424ad9e96cfebf68a4ddc99c65c0720d00c2", size = 173734 } +sdist = { url = "https://files.pythonhosted.org/packages/fe/cf/d2d3b9f5699fb1e4615c8e32ff220203e43b248e1dfcc6736ad9057731ca/pycparser-2.23.tar.gz", hash = "sha256:78816d4f24add8f10a06d6f05b4d424ad9e96cfebf68a4ddc99c65c0720d00c2", size = 173734, upload-time = "2025-09-09T13:23:47.91Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/a0/e3/59cd50310fc9b59512193629e1984c1f95e5c8ae6e5d8c69532ccc65a7fe/pycparser-2.23-py3-none-any.whl", hash = "sha256:e5c6e8d3fbad53479cab09ac03729e0a9faf2bee3db8208a550daf5af81a5934", size = 118140 }, + { url = "https://files.pythonhosted.org/packages/a0/e3/59cd50310fc9b59512193629e1984c1f95e5c8ae6e5d8c69532ccc65a7fe/pycparser-2.23-py3-none-any.whl", hash = "sha256:e5c6e8d3fbad53479cab09ac03729e0a9faf2bee3db8208a550daf5af81a5934", size = 118140, upload-time = "2025-09-09T13:23:46.651Z" }, ] [[package]] name = "pydantic" -version = "2.11.10" +version = "2.12.4" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "annotated-types" }, @@ -1446,9 +1446,9 @@ dependencies = [ { name = "typing-extensions" }, { name = "typing-inspection" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/ae/54/ecab642b3bed45f7d5f59b38443dcb36ef50f85af192e6ece103dbfe9587/pydantic-2.11.10.tar.gz", hash = "sha256:dc280f0982fbda6c38fada4e476dc0a4f3aeaf9c6ad4c28df68a666ec3c61423", size = 788494 } +sdist = { url = "https://files.pythonhosted.org/packages/96/ad/a17bc283d7d81837c061c49e3eaa27a45991759a1b7eae1031921c6bd924/pydantic-2.12.4.tar.gz", hash = "sha256:0f8cb9555000a4b5b617f66bfd2566264c4984b27589d3b845685983e8ea85ac", size = 821038, upload-time = "2025-11-05T10:50:08.59Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/bd/1f/73c53fcbfb0b5a78f91176df41945ca466e71e9d9d836e5c522abda39ee7/pydantic-2.11.10-py3-none-any.whl", hash = "sha256:802a655709d49bd004c31e865ef37da30b540786a46bfce02333e0e24b5fe29a", size = 444823 }, + { url = "https://files.pythonhosted.org/packages/82/2f/e68750da9b04856e2a7ec56fc6f034a5a79775e9b9a81882252789873798/pydantic-2.12.4-py3-none-any.whl", hash = "sha256:92d3d202a745d46f9be6df459ac5a064fdaa3c1c4cd8adcfa332ccf3c05f871e", size = 463400, upload-time = "2025-11-05T10:50:06.732Z" }, ] [package.optional-dependencies] @@ -1458,30 +1458,55 @@ email = [ [[package]] name = "pydantic-core" -version = "2.33.2" +version = "2.41.5" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "typing-extensions" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/ad/88/5f2260bdfae97aabf98f1778d43f69574390ad787afb646292a638c923d4/pydantic_core-2.33.2.tar.gz", hash = "sha256:7cb8bc3605c29176e1b105350d2e6474142d7c1bd1d9327c4a9bdb46bf827acc", size = 435195 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/46/8c/99040727b41f56616573a28771b1bfa08a3d3fe74d3d513f01251f79f172/pydantic_core-2.33.2-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:1082dd3e2d7109ad8b7da48e1d4710c8d06c253cbc4a27c1cff4fbcaa97a9e3f", size = 2015688 }, - { url = "https://files.pythonhosted.org/packages/3a/cc/5999d1eb705a6cefc31f0b4a90e9f7fc400539b1a1030529700cc1b51838/pydantic_core-2.33.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:f517ca031dfc037a9c07e748cefd8d96235088b83b4f4ba8939105d20fa1dcd6", size = 1844808 }, - { url = "https://files.pythonhosted.org/packages/6f/5e/a0a7b8885c98889a18b6e376f344da1ef323d270b44edf8174d6bce4d622/pydantic_core-2.33.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0a9f2c9dd19656823cb8250b0724ee9c60a82f3cdf68a080979d13092a3b0fef", size = 1885580 }, - { url = "https://files.pythonhosted.org/packages/3b/2a/953581f343c7d11a304581156618c3f592435523dd9d79865903272c256a/pydantic_core-2.33.2-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:2b0a451c263b01acebe51895bfb0e1cc842a5c666efe06cdf13846c7418caa9a", size = 1973859 }, - { url = "https://files.pythonhosted.org/packages/e6/55/f1a813904771c03a3f97f676c62cca0c0a4138654107c1b61f19c644868b/pydantic_core-2.33.2-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1ea40a64d23faa25e62a70ad163571c0b342b8bf66d5fa612ac0dec4f069d916", size = 2120810 }, - { url = "https://files.pythonhosted.org/packages/aa/c3/053389835a996e18853ba107a63caae0b9deb4a276c6b472931ea9ae6e48/pydantic_core-2.33.2-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:0fb2d542b4d66f9470e8065c5469ec676978d625a8b7a363f07d9a501a9cb36a", size = 2676498 }, - { url = "https://files.pythonhosted.org/packages/eb/3c/f4abd740877a35abade05e437245b192f9d0ffb48bbbbd708df33d3cda37/pydantic_core-2.33.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9fdac5d6ffa1b5a83bca06ffe7583f5576555e6c8b3a91fbd25ea7780f825f7d", size = 2000611 }, - { url = "https://files.pythonhosted.org/packages/59/a7/63ef2fed1837d1121a894d0ce88439fe3e3b3e48c7543b2a4479eb99c2bd/pydantic_core-2.33.2-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:04a1a413977ab517154eebb2d326da71638271477d6ad87a769102f7c2488c56", size = 2107924 }, - { url = "https://files.pythonhosted.org/packages/04/8f/2551964ef045669801675f1cfc3b0d74147f4901c3ffa42be2ddb1f0efc4/pydantic_core-2.33.2-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:c8e7af2f4e0194c22b5b37205bfb293d166a7344a5b0d0eaccebc376546d77d5", size = 2063196 }, - { url = "https://files.pythonhosted.org/packages/26/bd/d9602777e77fc6dbb0c7db9ad356e9a985825547dce5ad1d30ee04903918/pydantic_core-2.33.2-cp313-cp313-musllinux_1_1_armv7l.whl", hash = "sha256:5c92edd15cd58b3c2d34873597a1e20f13094f59cf88068adb18947df5455b4e", size = 2236389 }, - { url = "https://files.pythonhosted.org/packages/42/db/0e950daa7e2230423ab342ae918a794964b053bec24ba8af013fc7c94846/pydantic_core-2.33.2-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:65132b7b4a1c0beded5e057324b7e16e10910c106d43675d9bd87d4f38dde162", size = 2239223 }, - { url = "https://files.pythonhosted.org/packages/58/4d/4f937099c545a8a17eb52cb67fe0447fd9a373b348ccfa9a87f141eeb00f/pydantic_core-2.33.2-cp313-cp313-win32.whl", hash = "sha256:52fb90784e0a242bb96ec53f42196a17278855b0f31ac7c3cc6f5c1ec4811849", size = 1900473 }, - { url = "https://files.pythonhosted.org/packages/a0/75/4a0a9bac998d78d889def5e4ef2b065acba8cae8c93696906c3a91f310ca/pydantic_core-2.33.2-cp313-cp313-win_amd64.whl", hash = "sha256:c083a3bdd5a93dfe480f1125926afcdbf2917ae714bdb80b36d34318b2bec5d9", size = 1955269 }, - { url = "https://files.pythonhosted.org/packages/f9/86/1beda0576969592f1497b4ce8e7bc8cbdf614c352426271b1b10d5f0aa64/pydantic_core-2.33.2-cp313-cp313-win_arm64.whl", hash = "sha256:e80b087132752f6b3d714f041ccf74403799d3b23a72722ea2e6ba2e892555b9", size = 1893921 }, - { url = "https://files.pythonhosted.org/packages/a4/7d/e09391c2eebeab681df2b74bfe6c43422fffede8dc74187b2b0bf6fd7571/pydantic_core-2.33.2-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:61c18fba8e5e9db3ab908620af374db0ac1baa69f0f32df4f61ae23f15e586ac", size = 1806162 }, - { url = "https://files.pythonhosted.org/packages/f1/3d/847b6b1fed9f8ed3bb95a9ad04fbd0b212e832d4f0f50ff4d9ee5a9f15cf/pydantic_core-2.33.2-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:95237e53bb015f67b63c91af7518a62a8660376a6a0db19b89acc77a4d6199f5", size = 1981560 }, - { url = "https://files.pythonhosted.org/packages/6f/9a/e73262f6c6656262b5fdd723ad90f518f579b7bc8622e43a942eec53c938/pydantic_core-2.33.2-cp313-cp313t-win_amd64.whl", hash = "sha256:c2fc0a768ef76c15ab9238afa6da7f69895bb5d1ee83aeea2e3509af4472d0b9", size = 1935777 }, +sdist = { url = "https://files.pythonhosted.org/packages/71/70/23b021c950c2addd24ec408e9ab05d59b035b39d97cdc1130e1bce647bb6/pydantic_core-2.41.5.tar.gz", hash = "sha256:08daa51ea16ad373ffd5e7606252cc32f07bc72b28284b6bc9c6df804816476e", size = 460952, upload-time = "2025-11-04T13:43:49.098Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/87/06/8806241ff1f70d9939f9af039c6c35f2360cf16e93c2ca76f184e76b1564/pydantic_core-2.41.5-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:941103c9be18ac8daf7b7adca8228f8ed6bb7a1849020f643b3a14d15b1924d9", size = 2120403, upload-time = "2025-11-04T13:40:25.248Z" }, + { url = "https://files.pythonhosted.org/packages/94/02/abfa0e0bda67faa65fef1c84971c7e45928e108fe24333c81f3bfe35d5f5/pydantic_core-2.41.5-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:112e305c3314f40c93998e567879e887a3160bb8689ef3d2c04b6cc62c33ac34", size = 1896206, upload-time = "2025-11-04T13:40:27.099Z" }, + { url = "https://files.pythonhosted.org/packages/15/df/a4c740c0943e93e6500f9eb23f4ca7ec9bf71b19e608ae5b579678c8d02f/pydantic_core-2.41.5-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0cbaad15cb0c90aa221d43c00e77bb33c93e8d36e0bf74760cd00e732d10a6a0", size = 1919307, upload-time = "2025-11-04T13:40:29.806Z" }, + { url = "https://files.pythonhosted.org/packages/9a/e3/6324802931ae1d123528988e0e86587c2072ac2e5394b4bc2bc34b61ff6e/pydantic_core-2.41.5-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:03ca43e12fab6023fc79d28ca6b39b05f794ad08ec2feccc59a339b02f2b3d33", size = 2063258, upload-time = "2025-11-04T13:40:33.544Z" }, + { url = "https://files.pythonhosted.org/packages/c9/d4/2230d7151d4957dd79c3044ea26346c148c98fbf0ee6ebd41056f2d62ab5/pydantic_core-2.41.5-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:dc799088c08fa04e43144b164feb0c13f9a0bc40503f8df3e9fde58a3c0c101e", size = 2214917, upload-time = "2025-11-04T13:40:35.479Z" }, + { url = "https://files.pythonhosted.org/packages/e6/9f/eaac5df17a3672fef0081b6c1bb0b82b33ee89aa5cec0d7b05f52fd4a1fa/pydantic_core-2.41.5-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:97aeba56665b4c3235a0e52b2c2f5ae9cd071b8a8310ad27bddb3f7fb30e9aa2", size = 2332186, upload-time = "2025-11-04T13:40:37.436Z" }, + { url = "https://files.pythonhosted.org/packages/cf/4e/35a80cae583a37cf15604b44240e45c05e04e86f9cfd766623149297e971/pydantic_core-2.41.5-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:406bf18d345822d6c21366031003612b9c77b3e29ffdb0f612367352aab7d586", size = 2073164, upload-time = "2025-11-04T13:40:40.289Z" }, + { url = "https://files.pythonhosted.org/packages/bf/e3/f6e262673c6140dd3305d144d032f7bd5f7497d3871c1428521f19f9efa2/pydantic_core-2.41.5-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:b93590ae81f7010dbe380cdeab6f515902ebcbefe0b9327cc4804d74e93ae69d", size = 2179146, upload-time = "2025-11-04T13:40:42.809Z" }, + { url = "https://files.pythonhosted.org/packages/75/c7/20bd7fc05f0c6ea2056a4565c6f36f8968c0924f19b7d97bbfea55780e73/pydantic_core-2.41.5-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:01a3d0ab748ee531f4ea6c3e48ad9dac84ddba4b0d82291f87248f2f9de8d740", size = 2137788, upload-time = "2025-11-04T13:40:44.752Z" }, + { url = "https://files.pythonhosted.org/packages/3a/8d/34318ef985c45196e004bc46c6eab2eda437e744c124ef0dbe1ff2c9d06b/pydantic_core-2.41.5-cp313-cp313-musllinux_1_1_armv7l.whl", hash = "sha256:6561e94ba9dacc9c61bce40e2d6bdc3bfaa0259d3ff36ace3b1e6901936d2e3e", size = 2340133, upload-time = "2025-11-04T13:40:46.66Z" }, + { url = "https://files.pythonhosted.org/packages/9c/59/013626bf8c78a5a5d9350d12e7697d3d4de951a75565496abd40ccd46bee/pydantic_core-2.41.5-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:915c3d10f81bec3a74fbd4faebe8391013ba61e5a1a8d48c4455b923bdda7858", size = 2324852, upload-time = "2025-11-04T13:40:48.575Z" }, + { url = "https://files.pythonhosted.org/packages/1a/d9/c248c103856f807ef70c18a4f986693a46a8ffe1602e5d361485da502d20/pydantic_core-2.41.5-cp313-cp313-win32.whl", hash = "sha256:650ae77860b45cfa6e2cdafc42618ceafab3a2d9a3811fcfbd3bbf8ac3c40d36", size = 1994679, upload-time = "2025-11-04T13:40:50.619Z" }, + { url = "https://files.pythonhosted.org/packages/9e/8b/341991b158ddab181cff136acd2552c9f35bd30380422a639c0671e99a91/pydantic_core-2.41.5-cp313-cp313-win_amd64.whl", hash = "sha256:79ec52ec461e99e13791ec6508c722742ad745571f234ea6255bed38c6480f11", size = 2019766, upload-time = "2025-11-04T13:40:52.631Z" }, + { url = "https://files.pythonhosted.org/packages/73/7d/f2f9db34af103bea3e09735bb40b021788a5e834c81eedb541991badf8f5/pydantic_core-2.41.5-cp313-cp313-win_arm64.whl", hash = "sha256:3f84d5c1b4ab906093bdc1ff10484838aca54ef08de4afa9de0f5f14d69639cd", size = 1981005, upload-time = "2025-11-04T13:40:54.734Z" }, + { url = "https://files.pythonhosted.org/packages/ea/28/46b7c5c9635ae96ea0fbb779e271a38129df2550f763937659ee6c5dbc65/pydantic_core-2.41.5-cp314-cp314-macosx_10_12_x86_64.whl", hash = "sha256:3f37a19d7ebcdd20b96485056ba9e8b304e27d9904d233d7b1015db320e51f0a", size = 2119622, upload-time = "2025-11-04T13:40:56.68Z" }, + { url = "https://files.pythonhosted.org/packages/74/1a/145646e5687e8d9a1e8d09acb278c8535ebe9e972e1f162ed338a622f193/pydantic_core-2.41.5-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:1d1d9764366c73f996edd17abb6d9d7649a7eb690006ab6adbda117717099b14", size = 1891725, upload-time = "2025-11-04T13:40:58.807Z" }, + { url = "https://files.pythonhosted.org/packages/23/04/e89c29e267b8060b40dca97bfc64a19b2a3cf99018167ea1677d96368273/pydantic_core-2.41.5-cp314-cp314-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:25e1c2af0fce638d5f1988b686f3b3ea8cd7de5f244ca147c777769e798a9cd1", size = 1915040, upload-time = "2025-11-04T13:41:00.853Z" }, + { url = "https://files.pythonhosted.org/packages/84/a3/15a82ac7bd97992a82257f777b3583d3e84bdb06ba6858f745daa2ec8a85/pydantic_core-2.41.5-cp314-cp314-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:506d766a8727beef16b7adaeb8ee6217c64fc813646b424d0804d67c16eddb66", size = 2063691, upload-time = "2025-11-04T13:41:03.504Z" }, + { url = "https://files.pythonhosted.org/packages/74/9b/0046701313c6ef08c0c1cf0e028c67c770a4e1275ca73131563c5f2a310a/pydantic_core-2.41.5-cp314-cp314-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:4819fa52133c9aa3c387b3328f25c1facc356491e6135b459f1de698ff64d869", size = 2213897, upload-time = "2025-11-04T13:41:05.804Z" }, + { url = "https://files.pythonhosted.org/packages/8a/cd/6bac76ecd1b27e75a95ca3a9a559c643b3afcd2dd62086d4b7a32a18b169/pydantic_core-2.41.5-cp314-cp314-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2b761d210c9ea91feda40d25b4efe82a1707da2ef62901466a42492c028553a2", size = 2333302, upload-time = "2025-11-04T13:41:07.809Z" }, + { url = "https://files.pythonhosted.org/packages/4c/d2/ef2074dc020dd6e109611a8be4449b98cd25e1b9b8a303c2f0fca2f2bcf7/pydantic_core-2.41.5-cp314-cp314-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:22f0fb8c1c583a3b6f24df2470833b40207e907b90c928cc8d3594b76f874375", size = 2064877, upload-time = "2025-11-04T13:41:09.827Z" }, + { url = "https://files.pythonhosted.org/packages/18/66/e9db17a9a763d72f03de903883c057b2592c09509ccfe468187f2a2eef29/pydantic_core-2.41.5-cp314-cp314-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:2782c870e99878c634505236d81e5443092fba820f0373997ff75f90f68cd553", size = 2180680, upload-time = "2025-11-04T13:41:12.379Z" }, + { url = "https://files.pythonhosted.org/packages/d3/9e/3ce66cebb929f3ced22be85d4c2399b8e85b622db77dad36b73c5387f8f8/pydantic_core-2.41.5-cp314-cp314-musllinux_1_1_aarch64.whl", hash = "sha256:0177272f88ab8312479336e1d777f6b124537d47f2123f89cb37e0accea97f90", size = 2138960, upload-time = "2025-11-04T13:41:14.627Z" }, + { url = "https://files.pythonhosted.org/packages/a6/62/205a998f4327d2079326b01abee48e502ea739d174f0a89295c481a2272e/pydantic_core-2.41.5-cp314-cp314-musllinux_1_1_armv7l.whl", hash = "sha256:63510af5e38f8955b8ee5687740d6ebf7c2a0886d15a6d65c32814613681bc07", size = 2339102, upload-time = "2025-11-04T13:41:16.868Z" }, + { url = "https://files.pythonhosted.org/packages/3c/0d/f05e79471e889d74d3d88f5bd20d0ed189ad94c2423d81ff8d0000aab4ff/pydantic_core-2.41.5-cp314-cp314-musllinux_1_1_x86_64.whl", hash = "sha256:e56ba91f47764cc14f1daacd723e3e82d1a89d783f0f5afe9c364b8bb491ccdb", size = 2326039, upload-time = "2025-11-04T13:41:18.934Z" }, + { url = "https://files.pythonhosted.org/packages/ec/e1/e08a6208bb100da7e0c4b288eed624a703f4d129bde2da475721a80cab32/pydantic_core-2.41.5-cp314-cp314-win32.whl", hash = "sha256:aec5cf2fd867b4ff45b9959f8b20ea3993fc93e63c7363fe6851424c8a7e7c23", size = 1995126, upload-time = "2025-11-04T13:41:21.418Z" }, + { url = "https://files.pythonhosted.org/packages/48/5d/56ba7b24e9557f99c9237e29f5c09913c81eeb2f3217e40e922353668092/pydantic_core-2.41.5-cp314-cp314-win_amd64.whl", hash = "sha256:8e7c86f27c585ef37c35e56a96363ab8de4e549a95512445b85c96d3e2f7c1bf", size = 2015489, upload-time = "2025-11-04T13:41:24.076Z" }, + { url = "https://files.pythonhosted.org/packages/4e/bb/f7a190991ec9e3e0ba22e4993d8755bbc4a32925c0b5b42775c03e8148f9/pydantic_core-2.41.5-cp314-cp314-win_arm64.whl", hash = "sha256:e672ba74fbc2dc8eea59fb6d4aed6845e6905fc2a8afe93175d94a83ba2a01a0", size = 1977288, upload-time = "2025-11-04T13:41:26.33Z" }, + { url = "https://files.pythonhosted.org/packages/92/ed/77542d0c51538e32e15afe7899d79efce4b81eee631d99850edc2f5e9349/pydantic_core-2.41.5-cp314-cp314t-macosx_10_12_x86_64.whl", hash = "sha256:8566def80554c3faa0e65ac30ab0932b9e3a5cd7f8323764303d468e5c37595a", size = 2120255, upload-time = "2025-11-04T13:41:28.569Z" }, + { url = "https://files.pythonhosted.org/packages/bb/3d/6913dde84d5be21e284439676168b28d8bbba5600d838b9dca99de0fad71/pydantic_core-2.41.5-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:b80aa5095cd3109962a298ce14110ae16b8c1aece8b72f9dafe81cf597ad80b3", size = 1863760, upload-time = "2025-11-04T13:41:31.055Z" }, + { url = "https://files.pythonhosted.org/packages/5a/f0/e5e6b99d4191da102f2b0eb9687aaa7f5bea5d9964071a84effc3e40f997/pydantic_core-2.41.5-cp314-cp314t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3006c3dd9ba34b0c094c544c6006cc79e87d8612999f1a5d43b769b89181f23c", size = 1878092, upload-time = "2025-11-04T13:41:33.21Z" }, + { url = "https://files.pythonhosted.org/packages/71/48/36fb760642d568925953bcc8116455513d6e34c4beaa37544118c36aba6d/pydantic_core-2.41.5-cp314-cp314t-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:72f6c8b11857a856bcfa48c86f5368439f74453563f951e473514579d44aa612", size = 2053385, upload-time = "2025-11-04T13:41:35.508Z" }, + { url = "https://files.pythonhosted.org/packages/20/25/92dc684dd8eb75a234bc1c764b4210cf2646479d54b47bf46061657292a8/pydantic_core-2.41.5-cp314-cp314t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5cb1b2f9742240e4bb26b652a5aeb840aa4b417c7748b6f8387927bc6e45e40d", size = 2218832, upload-time = "2025-11-04T13:41:37.732Z" }, + { url = "https://files.pythonhosted.org/packages/e2/09/f53e0b05023d3e30357d82eb35835d0f6340ca344720a4599cd663dca599/pydantic_core-2.41.5-cp314-cp314t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:bd3d54f38609ff308209bd43acea66061494157703364ae40c951f83ba99a1a9", size = 2327585, upload-time = "2025-11-04T13:41:40Z" }, + { url = "https://files.pythonhosted.org/packages/aa/4e/2ae1aa85d6af35a39b236b1b1641de73f5a6ac4d5a7509f77b814885760c/pydantic_core-2.41.5-cp314-cp314t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2ff4321e56e879ee8d2a879501c8e469414d948f4aba74a2d4593184eb326660", size = 2041078, upload-time = "2025-11-04T13:41:42.323Z" }, + { url = "https://files.pythonhosted.org/packages/cd/13/2e215f17f0ef326fc72afe94776edb77525142c693767fc347ed6288728d/pydantic_core-2.41.5-cp314-cp314t-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:d0d2568a8c11bf8225044aa94409e21da0cb09dcdafe9ecd10250b2baad531a9", size = 2173914, upload-time = "2025-11-04T13:41:45.221Z" }, + { url = "https://files.pythonhosted.org/packages/02/7a/f999a6dcbcd0e5660bc348a3991c8915ce6599f4f2c6ac22f01d7a10816c/pydantic_core-2.41.5-cp314-cp314t-musllinux_1_1_aarch64.whl", hash = "sha256:a39455728aabd58ceabb03c90e12f71fd30fa69615760a075b9fec596456ccc3", size = 2129560, upload-time = "2025-11-04T13:41:47.474Z" }, + { url = "https://files.pythonhosted.org/packages/3a/b1/6c990ac65e3b4c079a4fb9f5b05f5b013afa0f4ed6780a3dd236d2cbdc64/pydantic_core-2.41.5-cp314-cp314t-musllinux_1_1_armv7l.whl", hash = "sha256:239edca560d05757817c13dc17c50766136d21f7cd0fac50295499ae24f90fdf", size = 2329244, upload-time = "2025-11-04T13:41:49.992Z" }, + { url = "https://files.pythonhosted.org/packages/d9/02/3c562f3a51afd4d88fff8dffb1771b30cfdfd79befd9883ee094f5b6c0d8/pydantic_core-2.41.5-cp314-cp314t-musllinux_1_1_x86_64.whl", hash = "sha256:2a5e06546e19f24c6a96a129142a75cee553cc018ffee48a460059b1185f4470", size = 2331955, upload-time = "2025-11-04T13:41:54.079Z" }, + { url = "https://files.pythonhosted.org/packages/5c/96/5fb7d8c3c17bc8c62fdb031c47d77a1af698f1d7a406b0f79aaa1338f9ad/pydantic_core-2.41.5-cp314-cp314t-win32.whl", hash = "sha256:b4ececa40ac28afa90871c2cc2b9ffd2ff0bf749380fbdf57d165fd23da353aa", size = 1988906, upload-time = "2025-11-04T13:41:56.606Z" }, + { url = "https://files.pythonhosted.org/packages/22/ed/182129d83032702912c2e2d8bbe33c036f342cc735737064668585dac28f/pydantic_core-2.41.5-cp314-cp314t-win_amd64.whl", hash = "sha256:80aa89cad80b32a912a65332f64a4450ed00966111b6615ca6816153d3585a8c", size = 1981607, upload-time = "2025-11-04T13:41:58.889Z" }, + { url = "https://files.pythonhosted.org/packages/9f/ed/068e41660b832bb0b1aa5b58011dea2a3fe0ba7861ff38c4d4904c1c1a99/pydantic_core-2.41.5-cp314-cp314t-win_arm64.whl", hash = "sha256:35b44f37a3199f771c3eaa53051bc8a70cd7b54f333531c59e29fd4db5d15008", size = 1974769, upload-time = "2025-11-04T13:42:01.186Z" }, ] [[package]] @@ -1492,9 +1517,9 @@ dependencies = [ { name = "pydantic" }, { name = "typing-extensions" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/3a/10/fb64987804cde41bcc39d9cd757cd5f2bb5d97b389d81aa70238b14b8a7e/pydantic_extra_types-2.10.6.tar.gz", hash = "sha256:c63d70bf684366e6bbe1f4ee3957952ebe6973d41e7802aea0b770d06b116aeb", size = 141858 } +sdist = { url = "https://files.pythonhosted.org/packages/3a/10/fb64987804cde41bcc39d9cd757cd5f2bb5d97b389d81aa70238b14b8a7e/pydantic_extra_types-2.10.6.tar.gz", hash = "sha256:c63d70bf684366e6bbe1f4ee3957952ebe6973d41e7802aea0b770d06b116aeb", size = 141858, upload-time = "2025-10-08T13:47:49.483Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/93/04/5c918669096da8d1c9ec7bb716bd72e755526103a61bc5e76a3e4fb23b53/pydantic_extra_types-2.10.6-py3-none-any.whl", hash = "sha256:6106c448316d30abf721b5b9fecc65e983ef2614399a24142d689c7546cc246a", size = 40949 }, + { url = "https://files.pythonhosted.org/packages/93/04/5c918669096da8d1c9ec7bb716bd72e755526103a61bc5e76a3e4fb23b53/pydantic_extra_types-2.10.6-py3-none-any.whl", hash = "sha256:6106c448316d30abf721b5b9fecc65e983ef2614399a24142d689c7546cc246a", size = 40949, upload-time = "2025-10-08T13:47:48.268Z" }, ] [[package]] @@ -1506,9 +1531,9 @@ dependencies = [ { name = "python-dotenv" }, { name = "typing-inspection" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/20/c5/dbbc27b814c71676593d1c3f718e6cd7d4f00652cefa24b75f7aa3efb25e/pydantic_settings-2.11.0.tar.gz", hash = "sha256:d0e87a1c7d33593beb7194adb8470fc426e95ba02af83a0f23474a04c9a08180", size = 188394 } +sdist = { url = "https://files.pythonhosted.org/packages/20/c5/dbbc27b814c71676593d1c3f718e6cd7d4f00652cefa24b75f7aa3efb25e/pydantic_settings-2.11.0.tar.gz", hash = "sha256:d0e87a1c7d33593beb7194adb8470fc426e95ba02af83a0f23474a04c9a08180", size = 188394, upload-time = "2025-09-24T14:19:11.764Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/83/d6/887a1ff844e64aa823fb4905978d882a633cfe295c32eacad582b78a7d8b/pydantic_settings-2.11.0-py3-none-any.whl", hash = "sha256:fe2cea3413b9530d10f3a5875adffb17ada5c1e1bab0b2885546d7310415207c", size = 48608 }, + { url = "https://files.pythonhosted.org/packages/83/d6/887a1ff844e64aa823fb4905978d882a633cfe295c32eacad582b78a7d8b/pydantic_settings-2.11.0-py3-none-any.whl", hash = "sha256:fe2cea3413b9530d10f3a5875adffb17ada5c1e1bab0b2885546d7310415207c", size = 48608, upload-time = "2025-09-24T14:19:10.015Z" }, ] [[package]] @@ -1518,27 +1543,27 @@ source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "pyparsing" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/66/dd/e0e6a4fb84c22050f6a9701ad9fd6a67ef82faa7ba97b97eb6fdc6b49b34/pydot-3.0.4.tar.gz", hash = "sha256:3ce88b2558f3808b0376f22bfa6c263909e1c3981e2a7b629b65b451eee4a25d", size = 168167 } +sdist = { url = "https://files.pythonhosted.org/packages/66/dd/e0e6a4fb84c22050f6a9701ad9fd6a67ef82faa7ba97b97eb6fdc6b49b34/pydot-3.0.4.tar.gz", hash = "sha256:3ce88b2558f3808b0376f22bfa6c263909e1c3981e2a7b629b65b451eee4a25d", size = 168167, upload-time = "2025-01-05T16:18:45.763Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/b0/5f/1ebfd430df05c4f9e438dd3313c4456eab937d976f6ab8ce81a98f9fb381/pydot-3.0.4-py3-none-any.whl", hash = "sha256:bfa9c3fc0c44ba1d132adce131802d7df00429d1a79cc0346b0a5cd374dbe9c6", size = 35776 }, + { url = "https://files.pythonhosted.org/packages/b0/5f/1ebfd430df05c4f9e438dd3313c4456eab937d976f6ab8ce81a98f9fb381/pydot-3.0.4-py3-none-any.whl", hash = "sha256:bfa9c3fc0c44ba1d132adce131802d7df00429d1a79cc0346b0a5cd374dbe9c6", size = 35776, upload-time = "2025-01-05T16:18:42.836Z" }, ] [[package]] name = "pygments" version = "2.19.2" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/b0/77/a5b8c569bf593b0140bde72ea885a803b82086995367bf2037de0159d924/pygments-2.19.2.tar.gz", hash = "sha256:636cb2477cec7f8952536970bc533bc43743542f70392ae026374600add5b887", size = 4968631 } +sdist = { url = "https://files.pythonhosted.org/packages/b0/77/a5b8c569bf593b0140bde72ea885a803b82086995367bf2037de0159d924/pygments-2.19.2.tar.gz", hash = "sha256:636cb2477cec7f8952536970bc533bc43743542f70392ae026374600add5b887", size = 4968631, upload-time = "2025-06-21T13:39:12.283Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/c7/21/705964c7812476f378728bdf590ca4b771ec72385c533964653c68e86bdc/pygments-2.19.2-py3-none-any.whl", hash = "sha256:86540386c03d588bb81d44bc3928634ff26449851e99741617ecb9037ee5ec0b", size = 1225217 }, + { url = "https://files.pythonhosted.org/packages/c7/21/705964c7812476f378728bdf590ca4b771ec72385c533964653c68e86bdc/pygments-2.19.2-py3-none-any.whl", hash = "sha256:86540386c03d588bb81d44bc3928634ff26449851e99741617ecb9037ee5ec0b", size = 1225217, upload-time = "2025-06-21T13:39:07.939Z" }, ] [[package]] name = "pyjwt" version = "2.10.1" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/e7/46/bd74733ff231675599650d3e47f361794b22ef3e3770998dda30d3b63726/pyjwt-2.10.1.tar.gz", hash = "sha256:3cc5772eb20009233caf06e9d8a0577824723b44e6648ee0a2aedb6cf9381953", size = 87785 } +sdist = { url = "https://files.pythonhosted.org/packages/e7/46/bd74733ff231675599650d3e47f361794b22ef3e3770998dda30d3b63726/pyjwt-2.10.1.tar.gz", hash = "sha256:3cc5772eb20009233caf06e9d8a0577824723b44e6648ee0a2aedb6cf9381953", size = 87785, upload-time = "2024-11-28T03:43:29.933Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/61/ad/689f02752eeec26aed679477e80e632ef1b682313be70793d798c1d5fc8f/PyJWT-2.10.1-py3-none-any.whl", hash = "sha256:dcdd193e30abefd5debf142f9adfcdd2b58004e644f25406ffaebd50bd98dacb", size = 22997 }, + { url = "https://files.pythonhosted.org/packages/61/ad/689f02752eeec26aed679477e80e632ef1b682313be70793d798c1d5fc8f/PyJWT-2.10.1-py3-none-any.whl", hash = "sha256:dcdd193e30abefd5debf142f9adfcdd2b58004e644f25406ffaebd50bd98dacb", size = 22997, upload-time = "2024-11-28T03:43:27.893Z" }, ] [package.optional-dependencies] @@ -1550,18 +1575,18 @@ crypto = [ name = "pyparsing" version = "3.2.5" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/f2/a5/181488fc2b9d093e3972d2a472855aae8a03f000592dbfce716a512b3359/pyparsing-3.2.5.tar.gz", hash = "sha256:2df8d5b7b2802ef88e8d016a2eb9c7aeaa923529cd251ed0fe4608275d4105b6", size = 1099274 } +sdist = { url = "https://files.pythonhosted.org/packages/f2/a5/181488fc2b9d093e3972d2a472855aae8a03f000592dbfce716a512b3359/pyparsing-3.2.5.tar.gz", hash = "sha256:2df8d5b7b2802ef88e8d016a2eb9c7aeaa923529cd251ed0fe4608275d4105b6", size = 1099274, upload-time = "2025-09-21T04:11:06.277Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/10/5e/1aa9a93198c6b64513c9d7752de7422c06402de6600a8767da1524f9570b/pyparsing-3.2.5-py3-none-any.whl", hash = "sha256:e38a4f02064cf41fe6593d328d0512495ad1f3d8a91c4f73fc401b3079a59a5e", size = 113890 }, + { url = "https://files.pythonhosted.org/packages/10/5e/1aa9a93198c6b64513c9d7752de7422c06402de6600a8767da1524f9570b/pyparsing-3.2.5-py3-none-any.whl", hash = "sha256:e38a4f02064cf41fe6593d328d0512495ad1f3d8a91c4f73fc401b3079a59a5e", size = 113890, upload-time = "2025-09-21T04:11:04.117Z" }, ] [[package]] name = "pyreadline3" version = "3.5.4" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/0f/49/4cea918a08f02817aabae639e3d0ac046fef9f9180518a3ad394e22da148/pyreadline3-3.5.4.tar.gz", hash = "sha256:8d57d53039a1c75adba8e50dd3d992b28143480816187ea5efbd5c78e6c885b7", size = 99839 } +sdist = { url = "https://files.pythonhosted.org/packages/0f/49/4cea918a08f02817aabae639e3d0ac046fef9f9180518a3ad394e22da148/pyreadline3-3.5.4.tar.gz", hash = "sha256:8d57d53039a1c75adba8e50dd3d992b28143480816187ea5efbd5c78e6c885b7", size = 99839, upload-time = "2024-09-19T02:40:10.062Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/5a/dc/491b7661614ab97483abf2056be1deee4dc2490ecbf7bff9ab5cdbac86e1/pyreadline3-3.5.4-py3-none-any.whl", hash = "sha256:eaf8e6cc3c49bcccf145fc6067ba8643d1df34d604a1ec0eccbf7a18e6d3fae6", size = 83178 }, + { url = "https://files.pythonhosted.org/packages/5a/dc/491b7661614ab97483abf2056be1deee4dc2490ecbf7bff9ab5cdbac86e1/pyreadline3-3.5.4-py3-none-any.whl", hash = "sha256:eaf8e6cc3c49bcccf145fc6067ba8643d1df34d604a1ec0eccbf7a18e6d3fae6", size = 83178, upload-time = "2024-09-19T02:40:08.598Z" }, ] [[package]] @@ -1572,9 +1597,9 @@ dependencies = [ { name = "nodeenv" }, { name = "typing-extensions" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/a6/1b/0aa08ee42948b61745ac5b5b5ccaec4669e8884b53d31c8ec20b2fcd6b6f/pyright-1.1.407.tar.gz", hash = "sha256:099674dba5c10489832d4a4b2d302636152a9a42d317986c38474c76fe562262", size = 4122872 } +sdist = { url = "https://files.pythonhosted.org/packages/a6/1b/0aa08ee42948b61745ac5b5b5ccaec4669e8884b53d31c8ec20b2fcd6b6f/pyright-1.1.407.tar.gz", hash = "sha256:099674dba5c10489832d4a4b2d302636152a9a42d317986c38474c76fe562262", size = 4122872, upload-time = "2025-10-24T23:17:15.145Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/dc/93/b69052907d032b00c40cb656d21438ec00b3a471733de137a3f65a49a0a0/pyright-1.1.407-py3-none-any.whl", hash = "sha256:6dd419f54fcc13f03b52285796d65e639786373f433e243f8b94cf93a7444d21", size = 5997008 }, + { url = "https://files.pythonhosted.org/packages/dc/93/b69052907d032b00c40cb656d21438ec00b3a471733de137a3f65a49a0a0/pyright-1.1.407-py3-none-any.whl", hash = "sha256:6dd419f54fcc13f03b52285796d65e639786373f433e243f8b94cf93a7444d21", size = 5997008, upload-time = "2025-10-24T23:17:13.159Z" }, ] [[package]] @@ -1588,9 +1613,9 @@ dependencies = [ { name = "pluggy" }, { name = "pygments" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/a3/5c/00a0e072241553e1a7496d638deababa67c5058571567b92a7eaa258397c/pytest-8.4.2.tar.gz", hash = "sha256:86c0d0b93306b961d58d62a4db4879f27fe25513d4b969df351abdddb3c30e01", size = 1519618 } +sdist = { url = "https://files.pythonhosted.org/packages/a3/5c/00a0e072241553e1a7496d638deababa67c5058571567b92a7eaa258397c/pytest-8.4.2.tar.gz", hash = "sha256:86c0d0b93306b961d58d62a4db4879f27fe25513d4b969df351abdddb3c30e01", size = 1519618, upload-time = "2025-09-04T14:34:22.711Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/a8/a4/20da314d277121d6534b3a980b29035dcd51e6744bd79075a6ce8fa4eb8d/pytest-8.4.2-py3-none-any.whl", hash = "sha256:872f880de3fc3a5bdc88a11b39c9710c3497a547cfa9320bc3c5e62fbf272e79", size = 365750 }, + { url = "https://files.pythonhosted.org/packages/a8/a4/20da314d277121d6534b3a980b29035dcd51e6744bd79075a6ce8fa4eb8d/pytest-8.4.2-py3-none-any.whl", hash = "sha256:872f880de3fc3a5bdc88a11b39c9710c3497a547cfa9320bc3c5e62fbf272e79", size = 365750, upload-time = "2025-09-04T14:34:20.226Z" }, ] [[package]] @@ -1602,9 +1627,9 @@ dependencies = [ { name = "pytest" }, { name = "sqlalchemy" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/f9/37/ad095d92242fe5c6b4b793191240375c01f6508960f31179de7f0e22cb96/pytest_alembic-0.12.1.tar.gz", hash = "sha256:4e2b477d93464d0cfe80487fdf63922bfd22f29153ca980c1bccf1dbf833cf12", size = 30635 } +sdist = { url = "https://files.pythonhosted.org/packages/f9/37/ad095d92242fe5c6b4b793191240375c01f6508960f31179de7f0e22cb96/pytest_alembic-0.12.1.tar.gz", hash = "sha256:4e2b477d93464d0cfe80487fdf63922bfd22f29153ca980c1bccf1dbf833cf12", size = 30635, upload-time = "2025-05-27T14:15:29.85Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/8b/f4/ded73992f972360adf84781b7e58729a3778e4358d482e1fe375c83948b4/pytest_alembic-0.12.1-py3-none-any.whl", hash = "sha256:d0d6be79f1c597278fbeda08c5558e7b8770af099521b0aa164e0df4aed945da", size = 36571 }, + { url = "https://files.pythonhosted.org/packages/8b/f4/ded73992f972360adf84781b7e58729a3778e4358d482e1fe375c83948b4/pytest_alembic-0.12.1-py3-none-any.whl", hash = "sha256:d0d6be79f1c597278fbeda08c5558e7b8770af099521b0aa164e0df4aed945da", size = 36571, upload-time = "2025-05-27T14:15:28.817Z" }, ] [[package]] @@ -1614,9 +1639,9 @@ source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "pytest" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/42/86/9e3c5f48f7b7b638b216e4b9e645f54d199d7abbbab7a64a13b4e12ba10f/pytest_asyncio-1.2.0.tar.gz", hash = "sha256:c609a64a2a8768462d0c99811ddb8bd2583c33fd33cf7f21af1c142e824ffb57", size = 50119 } +sdist = { url = "https://files.pythonhosted.org/packages/42/86/9e3c5f48f7b7b638b216e4b9e645f54d199d7abbbab7a64a13b4e12ba10f/pytest_asyncio-1.2.0.tar.gz", hash = "sha256:c609a64a2a8768462d0c99811ddb8bd2583c33fd33cf7f21af1c142e824ffb57", size = 50119, upload-time = "2025-09-12T07:33:53.816Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/04/93/2fa34714b7a4ae72f2f8dad66ba17dd9a2c793220719e736dda28b7aec27/pytest_asyncio-1.2.0-py3-none-any.whl", hash = "sha256:8e17ae5e46d8e7efe51ab6494dd2010f4ca8dae51652aa3c8d55acf50bfb2e99", size = 15095 }, + { url = "https://files.pythonhosted.org/packages/04/93/2fa34714b7a4ae72f2f8dad66ba17dd9a2c793220719e736dda28b7aec27/pytest_asyncio-1.2.0-py3-none-any.whl", hash = "sha256:8e17ae5e46d8e7efe51ab6494dd2010f4ca8dae51652aa3c8d55acf50bfb2e99", size = 15095, upload-time = "2025-09-12T07:33:52.639Z" }, ] [[package]] @@ -1628,9 +1653,9 @@ dependencies = [ { name = "pluggy" }, { name = "pytest" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/5e/f7/c933acc76f5208b3b00089573cf6a2bc26dc80a8aece8f52bb7d6b1855ca/pytest_cov-7.0.0.tar.gz", hash = "sha256:33c97eda2e049a0c5298e91f519302a1334c26ac65c1a483d6206fd458361af1", size = 54328 } +sdist = { url = "https://files.pythonhosted.org/packages/5e/f7/c933acc76f5208b3b00089573cf6a2bc26dc80a8aece8f52bb7d6b1855ca/pytest_cov-7.0.0.tar.gz", hash = "sha256:33c97eda2e049a0c5298e91f519302a1334c26ac65c1a483d6206fd458361af1", size = 54328, upload-time = "2025-09-09T10:57:02.113Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/ee/49/1377b49de7d0c1ce41292161ea0f721913fa8722c19fb9c1e3aa0367eecb/pytest_cov-7.0.0-py3-none-any.whl", hash = "sha256:3b8e9558b16cc1479da72058bdecf8073661c7f57f7d3c5f22a1c23507f2d861", size = 22424 }, + { url = "https://files.pythonhosted.org/packages/ee/49/1377b49de7d0c1ce41292161ea0f721913fa8722c19fb9c1e3aa0367eecb/pytest_cov-7.0.0-py3-none-any.whl", hash = "sha256:3b8e9558b16cc1479da72058bdecf8073661c7f57f7d3c5f22a1c23507f2d861", size = 22424, upload-time = "2025-09-09T10:57:00.695Z" }, ] [[package]] @@ -1640,27 +1665,27 @@ source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "six" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/66/c0/0c8b6ad9f17a802ee498c46e004a0eb49bc148f2fd230864601a86dcf6db/python-dateutil-2.9.0.post0.tar.gz", hash = "sha256:37dd54208da7e1cd875388217d5e00ebd4179249f90fb72437e91a35459a0ad3", size = 342432 } +sdist = { url = "https://files.pythonhosted.org/packages/66/c0/0c8b6ad9f17a802ee498c46e004a0eb49bc148f2fd230864601a86dcf6db/python-dateutil-2.9.0.post0.tar.gz", hash = "sha256:37dd54208da7e1cd875388217d5e00ebd4179249f90fb72437e91a35459a0ad3", size = 342432, upload-time = "2024-03-01T18:36:20.211Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/ec/57/56b9bcc3c9c6a792fcbaf139543cee77261f3651ca9da0c93f5c1221264b/python_dateutil-2.9.0.post0-py2.py3-none-any.whl", hash = "sha256:a8b2bc7bffae282281c8140a97d3aa9c14da0b136dfe83f850eea9a5f7470427", size = 229892 }, + { url = "https://files.pythonhosted.org/packages/ec/57/56b9bcc3c9c6a792fcbaf139543cee77261f3651ca9da0c93f5c1221264b/python_dateutil-2.9.0.post0-py2.py3-none-any.whl", hash = "sha256:a8b2bc7bffae282281c8140a97d3aa9c14da0b136dfe83f850eea9a5f7470427", size = 229892, upload-time = "2024-03-01T18:36:18.57Z" }, ] [[package]] name = "python-dotenv" version = "1.2.1" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/f0/26/19cadc79a718c5edbec86fd4919a6b6d3f681039a2f6d66d14be94e75fb9/python_dotenv-1.2.1.tar.gz", hash = "sha256:42667e897e16ab0d66954af0e60a9caa94f0fd4ecf3aaf6d2d260eec1aa36ad6", size = 44221 } +sdist = { url = "https://files.pythonhosted.org/packages/f0/26/19cadc79a718c5edbec86fd4919a6b6d3f681039a2f6d66d14be94e75fb9/python_dotenv-1.2.1.tar.gz", hash = "sha256:42667e897e16ab0d66954af0e60a9caa94f0fd4ecf3aaf6d2d260eec1aa36ad6", size = 44221, upload-time = "2025-10-26T15:12:10.434Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/14/1b/a298b06749107c305e1fe0f814c6c74aea7b2f1e10989cb30f544a1b3253/python_dotenv-1.2.1-py3-none-any.whl", hash = "sha256:b81ee9561e9ca4004139c6cbba3a238c32b03e4894671e181b671e8cb8425d61", size = 21230 }, + { url = "https://files.pythonhosted.org/packages/14/1b/a298b06749107c305e1fe0f814c6c74aea7b2f1e10989cb30f544a1b3253/python_dotenv-1.2.1-py3-none-any.whl", hash = "sha256:b81ee9561e9ca4004139c6cbba3a238c32b03e4894671e181b671e8cb8425d61", size = 21230, upload-time = "2025-10-26T15:12:09.109Z" }, ] [[package]] name = "python-multipart" version = "0.0.20" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/f3/87/f44d7c9f274c7ee665a29b885ec97089ec5dc034c7f3fafa03da9e39a09e/python_multipart-0.0.20.tar.gz", hash = "sha256:8dd0cab45b8e23064ae09147625994d090fa46f5b0d1e13af944c331a7fa9d13", size = 37158 } +sdist = { url = "https://files.pythonhosted.org/packages/f3/87/f44d7c9f274c7ee665a29b885ec97089ec5dc034c7f3fafa03da9e39a09e/python_multipart-0.0.20.tar.gz", hash = "sha256:8dd0cab45b8e23064ae09147625994d090fa46f5b0d1e13af944c331a7fa9d13", size = 37158, upload-time = "2024-12-16T19:45:46.972Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/45/58/38b5afbc1a800eeea951b9285d3912613f2603bdf897a4ab0f4bd7f405fc/python_multipart-0.0.20-py3-none-any.whl", hash = "sha256:8a62d3a8335e06589fe01f2a3e178cdcc632f3fbe0d492ad9ee0ec35aab1f104", size = 24546 }, + { url = "https://files.pythonhosted.org/packages/45/58/38b5afbc1a800eeea951b9285d3912613f2603bdf897a4ab0f4bd7f405fc/python_multipart-0.0.20-py3-none-any.whl", hash = "sha256:8a62d3a8335e06589fe01f2a3e178cdcc632f3fbe0d492ad9ee0ec35aab1f104", size = 24546, upload-time = "2024-12-16T19:45:44.423Z" }, ] [[package]] @@ -1670,127 +1695,127 @@ source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "text-unidecode" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/87/c7/5e1547c44e31da50a460df93af11a535ace568ef89d7a811069ead340c4a/python-slugify-8.0.4.tar.gz", hash = "sha256:59202371d1d05b54a9e7720c5e038f928f45daaffe41dd10822f3907b937c856", size = 10921 } +sdist = { url = "https://files.pythonhosted.org/packages/87/c7/5e1547c44e31da50a460df93af11a535ace568ef89d7a811069ead340c4a/python-slugify-8.0.4.tar.gz", hash = "sha256:59202371d1d05b54a9e7720c5e038f928f45daaffe41dd10822f3907b937c856", size = 10921, upload-time = "2024-02-08T18:32:45.488Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/a4/62/02da182e544a51a5c3ccf4b03ab79df279f9c60c5e82d5e8bec7ca26ac11/python_slugify-8.0.4-py2.py3-none-any.whl", hash = "sha256:276540b79961052b66b7d116620b36518847f52d5fd9e3a70164fc8c50faa6b8", size = 10051 }, + { url = "https://files.pythonhosted.org/packages/a4/62/02da182e544a51a5c3ccf4b03ab79df279f9c60c5e82d5e8bec7ca26ac11/python_slugify-8.0.4-py2.py3-none-any.whl", hash = "sha256:276540b79961052b66b7d116620b36518847f52d5fd9e3a70164fc8c50faa6b8", size = 10051, upload-time = "2024-02-08T18:32:43.911Z" }, ] [[package]] name = "pytz" version = "2025.2" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/f8/bf/abbd3cdfb8fbc7fb3d4d38d320f2441b1e7cbe29be4f23797b4a2b5d8aac/pytz-2025.2.tar.gz", hash = "sha256:360b9e3dbb49a209c21ad61809c7fb453643e048b38924c765813546746e81c3", size = 320884 } +sdist = { url = "https://files.pythonhosted.org/packages/f8/bf/abbd3cdfb8fbc7fb3d4d38d320f2441b1e7cbe29be4f23797b4a2b5d8aac/pytz-2025.2.tar.gz", hash = "sha256:360b9e3dbb49a209c21ad61809c7fb453643e048b38924c765813546746e81c3", size = 320884, upload-time = "2025-03-25T02:25:00.538Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/81/c4/34e93fe5f5429d7570ec1fa436f1986fb1f00c3e0f43a589fe2bbcd22c3f/pytz-2025.2-py2.py3-none-any.whl", hash = "sha256:5ddf76296dd8c44c26eb8f4b6f35488f3ccbf6fbbd7adee0b7262d43f0ec2f00", size = 509225 }, + { url = "https://files.pythonhosted.org/packages/81/c4/34e93fe5f5429d7570ec1fa436f1986fb1f00c3e0f43a589fe2bbcd22c3f/pytz-2025.2-py2.py3-none-any.whl", hash = "sha256:5ddf76296dd8c44c26eb8f4b6f35488f3ccbf6fbbd7adee0b7262d43f0ec2f00", size = 509225, upload-time = "2025-03-25T02:24:58.468Z" }, ] [[package]] name = "pyyaml" version = "6.0.3" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/05/8e/961c0007c59b8dd7729d542c61a4d537767a59645b82a0b521206e1e25c2/pyyaml-6.0.3.tar.gz", hash = "sha256:d76623373421df22fb4cf8817020cbb7ef15c725b9d5e45f17e189bfc384190f", size = 130960 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/d1/11/0fd08f8192109f7169db964b5707a2f1e8b745d4e239b784a5a1dd80d1db/pyyaml-6.0.3-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:8da9669d359f02c0b91ccc01cac4a67f16afec0dac22c2ad09f46bee0697eba8", size = 181669 }, - { url = "https://files.pythonhosted.org/packages/b1/16/95309993f1d3748cd644e02e38b75d50cbc0d9561d21f390a76242ce073f/pyyaml-6.0.3-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:2283a07e2c21a2aa78d9c4442724ec1eb15f5e42a723b99cb3d822d48f5f7ad1", size = 173252 }, - { url = "https://files.pythonhosted.org/packages/50/31/b20f376d3f810b9b2371e72ef5adb33879b25edb7a6d072cb7ca0c486398/pyyaml-6.0.3-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ee2922902c45ae8ccada2c5b501ab86c36525b883eff4255313a253a3160861c", size = 767081 }, - { url = "https://files.pythonhosted.org/packages/49/1e/a55ca81e949270d5d4432fbbd19dfea5321eda7c41a849d443dc92fd1ff7/pyyaml-6.0.3-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:a33284e20b78bd4a18c8c2282d549d10bc8408a2a7ff57653c0cf0b9be0afce5", size = 841159 }, - { url = "https://files.pythonhosted.org/packages/74/27/e5b8f34d02d9995b80abcef563ea1f8b56d20134d8f4e5e81733b1feceb2/pyyaml-6.0.3-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:0f29edc409a6392443abf94b9cf89ce99889a1dd5376d94316ae5145dfedd5d6", size = 801626 }, - { url = "https://files.pythonhosted.org/packages/f9/11/ba845c23988798f40e52ba45f34849aa8a1f2d4af4b798588010792ebad6/pyyaml-6.0.3-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:f7057c9a337546edc7973c0d3ba84ddcdf0daa14533c2065749c9075001090e6", size = 753613 }, - { url = "https://files.pythonhosted.org/packages/3d/e0/7966e1a7bfc0a45bf0a7fb6b98ea03fc9b8d84fa7f2229e9659680b69ee3/pyyaml-6.0.3-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:eda16858a3cab07b80edaf74336ece1f986ba330fdb8ee0d6c0d68fe82bc96be", size = 794115 }, - { url = "https://files.pythonhosted.org/packages/de/94/980b50a6531b3019e45ddeada0626d45fa85cbe22300844a7983285bed3b/pyyaml-6.0.3-cp313-cp313-win32.whl", hash = "sha256:d0eae10f8159e8fdad514efdc92d74fd8d682c933a6dd088030f3834bc8e6b26", size = 137427 }, - { url = "https://files.pythonhosted.org/packages/97/c9/39d5b874e8b28845e4ec2202b5da735d0199dbe5b8fb85f91398814a9a46/pyyaml-6.0.3-cp313-cp313-win_amd64.whl", hash = "sha256:79005a0d97d5ddabfeeea4cf676af11e647e41d81c9a7722a193022accdb6b7c", size = 154090 }, - { url = "https://files.pythonhosted.org/packages/73/e8/2bdf3ca2090f68bb3d75b44da7bbc71843b19c9f2b9cb9b0f4ab7a5a4329/pyyaml-6.0.3-cp313-cp313-win_arm64.whl", hash = "sha256:5498cd1645aa724a7c71c8f378eb29ebe23da2fc0d7a08071d89469bf1d2defb", size = 140246 }, - { url = "https://files.pythonhosted.org/packages/9d/8c/f4bd7f6465179953d3ac9bc44ac1a8a3e6122cf8ada906b4f96c60172d43/pyyaml-6.0.3-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:8d1fab6bb153a416f9aeb4b8763bc0f22a5586065f86f7664fc23339fc1c1fac", size = 181814 }, - { url = "https://files.pythonhosted.org/packages/bd/9c/4d95bb87eb2063d20db7b60faa3840c1b18025517ae857371c4dd55a6b3a/pyyaml-6.0.3-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:34d5fcd24b8445fadc33f9cf348c1047101756fd760b4dacb5c3e99755703310", size = 173809 }, - { url = "https://files.pythonhosted.org/packages/92/b5/47e807c2623074914e29dabd16cbbdd4bf5e9b2db9f8090fa64411fc5382/pyyaml-6.0.3-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:501a031947e3a9025ed4405a168e6ef5ae3126c59f90ce0cd6f2bfc477be31b7", size = 766454 }, - { url = "https://files.pythonhosted.org/packages/02/9e/e5e9b168be58564121efb3de6859c452fccde0ab093d8438905899a3a483/pyyaml-6.0.3-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:b3bc83488de33889877a0f2543ade9f70c67d66d9ebb4ac959502e12de895788", size = 836355 }, - { url = "https://files.pythonhosted.org/packages/88/f9/16491d7ed2a919954993e48aa941b200f38040928474c9e85ea9e64222c3/pyyaml-6.0.3-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c458b6d084f9b935061bc36216e8a69a7e293a2f1e68bf956dcd9e6cbcd143f5", size = 794175 }, - { url = "https://files.pythonhosted.org/packages/dd/3f/5989debef34dc6397317802b527dbbafb2b4760878a53d4166579111411e/pyyaml-6.0.3-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:7c6610def4f163542a622a73fb39f534f8c101d690126992300bf3207eab9764", size = 755228 }, - { url = "https://files.pythonhosted.org/packages/d7/ce/af88a49043cd2e265be63d083fc75b27b6ed062f5f9fd6cdc223ad62f03e/pyyaml-6.0.3-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:5190d403f121660ce8d1d2c1bb2ef1bd05b5f68533fc5c2ea899bd15f4399b35", size = 789194 }, - { url = "https://files.pythonhosted.org/packages/23/20/bb6982b26a40bb43951265ba29d4c246ef0ff59c9fdcdf0ed04e0687de4d/pyyaml-6.0.3-cp314-cp314-win_amd64.whl", hash = "sha256:4a2e8cebe2ff6ab7d1050ecd59c25d4c8bd7e6f400f5f82b96557ac0abafd0ac", size = 156429 }, - { url = "https://files.pythonhosted.org/packages/f4/f4/a4541072bb9422c8a883ab55255f918fa378ecf083f5b85e87fc2b4eda1b/pyyaml-6.0.3-cp314-cp314-win_arm64.whl", hash = "sha256:93dda82c9c22deb0a405ea4dc5f2d0cda384168e466364dec6255b293923b2f3", size = 143912 }, - { url = "https://files.pythonhosted.org/packages/7c/f9/07dd09ae774e4616edf6cda684ee78f97777bdd15847253637a6f052a62f/pyyaml-6.0.3-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:02893d100e99e03eda1c8fd5c441d8c60103fd175728e23e431db1b589cf5ab3", size = 189108 }, - { url = "https://files.pythonhosted.org/packages/4e/78/8d08c9fb7ce09ad8c38ad533c1191cf27f7ae1effe5bb9400a46d9437fcf/pyyaml-6.0.3-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:c1ff362665ae507275af2853520967820d9124984e0f7466736aea23d8611fba", size = 183641 }, - { url = "https://files.pythonhosted.org/packages/7b/5b/3babb19104a46945cf816d047db2788bcaf8c94527a805610b0289a01c6b/pyyaml-6.0.3-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6adc77889b628398debc7b65c073bcb99c4a0237b248cacaf3fe8a557563ef6c", size = 831901 }, - { url = "https://files.pythonhosted.org/packages/8b/cc/dff0684d8dc44da4d22a13f35f073d558c268780ce3c6ba1b87055bb0b87/pyyaml-6.0.3-cp314-cp314t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:a80cb027f6b349846a3bf6d73b5e95e782175e52f22108cfa17876aaeff93702", size = 861132 }, - { url = "https://files.pythonhosted.org/packages/b1/5e/f77dc6b9036943e285ba76b49e118d9ea929885becb0a29ba8a7c75e29fe/pyyaml-6.0.3-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:00c4bdeba853cc34e7dd471f16b4114f4162dc03e6b7afcc2128711f0eca823c", size = 839261 }, - { url = "https://files.pythonhosted.org/packages/ce/88/a9db1376aa2a228197c58b37302f284b5617f56a5d959fd1763fb1675ce6/pyyaml-6.0.3-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:66e1674c3ef6f541c35191caae2d429b967b99e02040f5ba928632d9a7f0f065", size = 805272 }, - { url = "https://files.pythonhosted.org/packages/da/92/1446574745d74df0c92e6aa4a7b0b3130706a4142b2d1a5869f2eaa423c6/pyyaml-6.0.3-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:16249ee61e95f858e83976573de0f5b2893b3677ba71c9dd36b9cf8be9ac6d65", size = 829923 }, - { url = "https://files.pythonhosted.org/packages/f0/7a/1c7270340330e575b92f397352af856a8c06f230aa3e76f86b39d01b416a/pyyaml-6.0.3-cp314-cp314t-win_amd64.whl", hash = "sha256:4ad1906908f2f5ae4e5a8ddfce73c320c2a1429ec52eafd27138b7f1cbe341c9", size = 174062 }, - { url = "https://files.pythonhosted.org/packages/f1/12/de94a39c2ef588c7e6455cfbe7343d3b2dc9d6b6b2f40c4c6565744c873d/pyyaml-6.0.3-cp314-cp314t-win_arm64.whl", hash = "sha256:ebc55a14a21cb14062aa4162f906cd962b28e2e9ea38f9b4391244cd8de4ae0b", size = 149341 }, +sdist = { url = "https://files.pythonhosted.org/packages/05/8e/961c0007c59b8dd7729d542c61a4d537767a59645b82a0b521206e1e25c2/pyyaml-6.0.3.tar.gz", hash = "sha256:d76623373421df22fb4cf8817020cbb7ef15c725b9d5e45f17e189bfc384190f", size = 130960, upload-time = "2025-09-25T21:33:16.546Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/d1/11/0fd08f8192109f7169db964b5707a2f1e8b745d4e239b784a5a1dd80d1db/pyyaml-6.0.3-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:8da9669d359f02c0b91ccc01cac4a67f16afec0dac22c2ad09f46bee0697eba8", size = 181669, upload-time = "2025-09-25T21:32:23.673Z" }, + { url = "https://files.pythonhosted.org/packages/b1/16/95309993f1d3748cd644e02e38b75d50cbc0d9561d21f390a76242ce073f/pyyaml-6.0.3-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:2283a07e2c21a2aa78d9c4442724ec1eb15f5e42a723b99cb3d822d48f5f7ad1", size = 173252, upload-time = "2025-09-25T21:32:25.149Z" }, + { url = "https://files.pythonhosted.org/packages/50/31/b20f376d3f810b9b2371e72ef5adb33879b25edb7a6d072cb7ca0c486398/pyyaml-6.0.3-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ee2922902c45ae8ccada2c5b501ab86c36525b883eff4255313a253a3160861c", size = 767081, upload-time = "2025-09-25T21:32:26.575Z" }, + { url = "https://files.pythonhosted.org/packages/49/1e/a55ca81e949270d5d4432fbbd19dfea5321eda7c41a849d443dc92fd1ff7/pyyaml-6.0.3-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:a33284e20b78bd4a18c8c2282d549d10bc8408a2a7ff57653c0cf0b9be0afce5", size = 841159, upload-time = "2025-09-25T21:32:27.727Z" }, + { url = "https://files.pythonhosted.org/packages/74/27/e5b8f34d02d9995b80abcef563ea1f8b56d20134d8f4e5e81733b1feceb2/pyyaml-6.0.3-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:0f29edc409a6392443abf94b9cf89ce99889a1dd5376d94316ae5145dfedd5d6", size = 801626, upload-time = "2025-09-25T21:32:28.878Z" }, + { url = "https://files.pythonhosted.org/packages/f9/11/ba845c23988798f40e52ba45f34849aa8a1f2d4af4b798588010792ebad6/pyyaml-6.0.3-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:f7057c9a337546edc7973c0d3ba84ddcdf0daa14533c2065749c9075001090e6", size = 753613, upload-time = "2025-09-25T21:32:30.178Z" }, + { url = "https://files.pythonhosted.org/packages/3d/e0/7966e1a7bfc0a45bf0a7fb6b98ea03fc9b8d84fa7f2229e9659680b69ee3/pyyaml-6.0.3-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:eda16858a3cab07b80edaf74336ece1f986ba330fdb8ee0d6c0d68fe82bc96be", size = 794115, upload-time = "2025-09-25T21:32:31.353Z" }, + { url = "https://files.pythonhosted.org/packages/de/94/980b50a6531b3019e45ddeada0626d45fa85cbe22300844a7983285bed3b/pyyaml-6.0.3-cp313-cp313-win32.whl", hash = "sha256:d0eae10f8159e8fdad514efdc92d74fd8d682c933a6dd088030f3834bc8e6b26", size = 137427, upload-time = "2025-09-25T21:32:32.58Z" }, + { url = "https://files.pythonhosted.org/packages/97/c9/39d5b874e8b28845e4ec2202b5da735d0199dbe5b8fb85f91398814a9a46/pyyaml-6.0.3-cp313-cp313-win_amd64.whl", hash = "sha256:79005a0d97d5ddabfeeea4cf676af11e647e41d81c9a7722a193022accdb6b7c", size = 154090, upload-time = "2025-09-25T21:32:33.659Z" }, + { url = "https://files.pythonhosted.org/packages/73/e8/2bdf3ca2090f68bb3d75b44da7bbc71843b19c9f2b9cb9b0f4ab7a5a4329/pyyaml-6.0.3-cp313-cp313-win_arm64.whl", hash = "sha256:5498cd1645aa724a7c71c8f378eb29ebe23da2fc0d7a08071d89469bf1d2defb", size = 140246, upload-time = "2025-09-25T21:32:34.663Z" }, + { url = "https://files.pythonhosted.org/packages/9d/8c/f4bd7f6465179953d3ac9bc44ac1a8a3e6122cf8ada906b4f96c60172d43/pyyaml-6.0.3-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:8d1fab6bb153a416f9aeb4b8763bc0f22a5586065f86f7664fc23339fc1c1fac", size = 181814, upload-time = "2025-09-25T21:32:35.712Z" }, + { url = "https://files.pythonhosted.org/packages/bd/9c/4d95bb87eb2063d20db7b60faa3840c1b18025517ae857371c4dd55a6b3a/pyyaml-6.0.3-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:34d5fcd24b8445fadc33f9cf348c1047101756fd760b4dacb5c3e99755703310", size = 173809, upload-time = "2025-09-25T21:32:36.789Z" }, + { url = "https://files.pythonhosted.org/packages/92/b5/47e807c2623074914e29dabd16cbbdd4bf5e9b2db9f8090fa64411fc5382/pyyaml-6.0.3-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:501a031947e3a9025ed4405a168e6ef5ae3126c59f90ce0cd6f2bfc477be31b7", size = 766454, upload-time = "2025-09-25T21:32:37.966Z" }, + { url = "https://files.pythonhosted.org/packages/02/9e/e5e9b168be58564121efb3de6859c452fccde0ab093d8438905899a3a483/pyyaml-6.0.3-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:b3bc83488de33889877a0f2543ade9f70c67d66d9ebb4ac959502e12de895788", size = 836355, upload-time = "2025-09-25T21:32:39.178Z" }, + { url = "https://files.pythonhosted.org/packages/88/f9/16491d7ed2a919954993e48aa941b200f38040928474c9e85ea9e64222c3/pyyaml-6.0.3-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c458b6d084f9b935061bc36216e8a69a7e293a2f1e68bf956dcd9e6cbcd143f5", size = 794175, upload-time = "2025-09-25T21:32:40.865Z" }, + { url = "https://files.pythonhosted.org/packages/dd/3f/5989debef34dc6397317802b527dbbafb2b4760878a53d4166579111411e/pyyaml-6.0.3-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:7c6610def4f163542a622a73fb39f534f8c101d690126992300bf3207eab9764", size = 755228, upload-time = "2025-09-25T21:32:42.084Z" }, + { url = "https://files.pythonhosted.org/packages/d7/ce/af88a49043cd2e265be63d083fc75b27b6ed062f5f9fd6cdc223ad62f03e/pyyaml-6.0.3-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:5190d403f121660ce8d1d2c1bb2ef1bd05b5f68533fc5c2ea899bd15f4399b35", size = 789194, upload-time = "2025-09-25T21:32:43.362Z" }, + { url = "https://files.pythonhosted.org/packages/23/20/bb6982b26a40bb43951265ba29d4c246ef0ff59c9fdcdf0ed04e0687de4d/pyyaml-6.0.3-cp314-cp314-win_amd64.whl", hash = "sha256:4a2e8cebe2ff6ab7d1050ecd59c25d4c8bd7e6f400f5f82b96557ac0abafd0ac", size = 156429, upload-time = "2025-09-25T21:32:57.844Z" }, + { url = "https://files.pythonhosted.org/packages/f4/f4/a4541072bb9422c8a883ab55255f918fa378ecf083f5b85e87fc2b4eda1b/pyyaml-6.0.3-cp314-cp314-win_arm64.whl", hash = "sha256:93dda82c9c22deb0a405ea4dc5f2d0cda384168e466364dec6255b293923b2f3", size = 143912, upload-time = "2025-09-25T21:32:59.247Z" }, + { url = "https://files.pythonhosted.org/packages/7c/f9/07dd09ae774e4616edf6cda684ee78f97777bdd15847253637a6f052a62f/pyyaml-6.0.3-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:02893d100e99e03eda1c8fd5c441d8c60103fd175728e23e431db1b589cf5ab3", size = 189108, upload-time = "2025-09-25T21:32:44.377Z" }, + { url = "https://files.pythonhosted.org/packages/4e/78/8d08c9fb7ce09ad8c38ad533c1191cf27f7ae1effe5bb9400a46d9437fcf/pyyaml-6.0.3-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:c1ff362665ae507275af2853520967820d9124984e0f7466736aea23d8611fba", size = 183641, upload-time = "2025-09-25T21:32:45.407Z" }, + { url = "https://files.pythonhosted.org/packages/7b/5b/3babb19104a46945cf816d047db2788bcaf8c94527a805610b0289a01c6b/pyyaml-6.0.3-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6adc77889b628398debc7b65c073bcb99c4a0237b248cacaf3fe8a557563ef6c", size = 831901, upload-time = "2025-09-25T21:32:48.83Z" }, + { url = "https://files.pythonhosted.org/packages/8b/cc/dff0684d8dc44da4d22a13f35f073d558c268780ce3c6ba1b87055bb0b87/pyyaml-6.0.3-cp314-cp314t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:a80cb027f6b349846a3bf6d73b5e95e782175e52f22108cfa17876aaeff93702", size = 861132, upload-time = "2025-09-25T21:32:50.149Z" }, + { url = "https://files.pythonhosted.org/packages/b1/5e/f77dc6b9036943e285ba76b49e118d9ea929885becb0a29ba8a7c75e29fe/pyyaml-6.0.3-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:00c4bdeba853cc34e7dd471f16b4114f4162dc03e6b7afcc2128711f0eca823c", size = 839261, upload-time = "2025-09-25T21:32:51.808Z" }, + { url = "https://files.pythonhosted.org/packages/ce/88/a9db1376aa2a228197c58b37302f284b5617f56a5d959fd1763fb1675ce6/pyyaml-6.0.3-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:66e1674c3ef6f541c35191caae2d429b967b99e02040f5ba928632d9a7f0f065", size = 805272, upload-time = "2025-09-25T21:32:52.941Z" }, + { url = "https://files.pythonhosted.org/packages/da/92/1446574745d74df0c92e6aa4a7b0b3130706a4142b2d1a5869f2eaa423c6/pyyaml-6.0.3-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:16249ee61e95f858e83976573de0f5b2893b3677ba71c9dd36b9cf8be9ac6d65", size = 829923, upload-time = "2025-09-25T21:32:54.537Z" }, + { url = "https://files.pythonhosted.org/packages/f0/7a/1c7270340330e575b92f397352af856a8c06f230aa3e76f86b39d01b416a/pyyaml-6.0.3-cp314-cp314t-win_amd64.whl", hash = "sha256:4ad1906908f2f5ae4e5a8ddfce73c320c2a1429ec52eafd27138b7f1cbe341c9", size = 174062, upload-time = "2025-09-25T21:32:55.767Z" }, + { url = "https://files.pythonhosted.org/packages/f1/12/de94a39c2ef588c7e6455cfbe7343d3b2dc9d6b6b2f40c4c6565744c873d/pyyaml-6.0.3-cp314-cp314t-win_arm64.whl", hash = "sha256:ebc55a14a21cb14062aa4162f906cd962b28e2e9ea38f9b4391244cd8de4ae0b", size = 149341, upload-time = "2025-09-25T21:32:56.828Z" }, ] [[package]] name = "redis" version = "7.0.1" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/57/8f/f125feec0b958e8d22c8f0b492b30b1991d9499a4315dfde466cf4289edc/redis-7.0.1.tar.gz", hash = "sha256:c949df947dca995dc68fdf5a7863950bf6df24f8d6022394585acc98e81624f1", size = 4755322 } +sdist = { url = "https://files.pythonhosted.org/packages/57/8f/f125feec0b958e8d22c8f0b492b30b1991d9499a4315dfde466cf4289edc/redis-7.0.1.tar.gz", hash = "sha256:c949df947dca995dc68fdf5a7863950bf6df24f8d6022394585acc98e81624f1", size = 4755322, upload-time = "2025-10-27T14:34:00.33Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/e9/97/9f22a33c475cda519f20aba6babb340fb2f2254a02fb947816960d1e669a/redis-7.0.1-py3-none-any.whl", hash = "sha256:4977af3c7d67f8f0eb8b6fec0dafc9605db9343142f634041fb0235f67c0588a", size = 339938 }, + { url = "https://files.pythonhosted.org/packages/e9/97/9f22a33c475cda519f20aba6babb340fb2f2254a02fb947816960d1e669a/redis-7.0.1-py3-none-any.whl", hash = "sha256:4977af3c7d67f8f0eb8b6fec0dafc9605db9343142f634041fb0235f67c0588a", size = 339938, upload-time = "2025-10-27T14:33:58.553Z" }, ] [[package]] name = "regex" version = "2025.11.3" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/cc/a9/546676f25e573a4cf00fe8e119b78a37b6a8fe2dc95cda877b30889c9c45/regex-2025.11.3.tar.gz", hash = "sha256:1fedc720f9bb2494ce31a58a1631f9c82df6a09b49c19517ea5cc280b4541e01", size = 414669 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/e1/a7/dda24ebd49da46a197436ad96378f17df30ceb40e52e859fc42cac45b850/regex-2025.11.3-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:c1e448051717a334891f2b9a620fe36776ebf3dd8ec46a0b877c8ae69575feb4", size = 489081 }, - { url = "https://files.pythonhosted.org/packages/19/22/af2dc751aacf88089836aa088a1a11c4f21a04707eb1b0478e8e8fb32847/regex-2025.11.3-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:9b5aca4d5dfd7fbfbfbdaf44850fcc7709a01146a797536a8f84952e940cca76", size = 291123 }, - { url = "https://files.pythonhosted.org/packages/a3/88/1a3ea5672f4b0a84802ee9891b86743438e7c04eb0b8f8c4e16a42375327/regex-2025.11.3-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:04d2765516395cf7dda331a244a3282c0f5ae96075f728629287dfa6f76ba70a", size = 288814 }, - { url = "https://files.pythonhosted.org/packages/fb/8c/f5987895bf42b8ddeea1b315c9fedcfe07cadee28b9c98cf50d00adcb14d/regex-2025.11.3-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:5d9903ca42bfeec4cebedba8022a7c97ad2aab22e09573ce9976ba01b65e4361", size = 798592 }, - { url = "https://files.pythonhosted.org/packages/99/2a/6591ebeede78203fa77ee46a1c36649e02df9eaa77a033d1ccdf2fcd5d4e/regex-2025.11.3-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:639431bdc89d6429f6721625e8129413980ccd62e9d3f496be618a41d205f160", size = 864122 }, - { url = "https://files.pythonhosted.org/packages/94/d6/be32a87cf28cf8ed064ff281cfbd49aefd90242a83e4b08b5a86b38e8eb4/regex-2025.11.3-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:f117efad42068f9715677c8523ed2be1518116d1c49b1dd17987716695181efe", size = 912272 }, - { url = "https://files.pythonhosted.org/packages/62/11/9bcef2d1445665b180ac7f230406ad80671f0fc2a6ffb93493b5dd8cd64c/regex-2025.11.3-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:4aecb6f461316adf9f1f0f6a4a1a3d79e045f9b71ec76055a791affa3b285850", size = 803497 }, - { url = "https://files.pythonhosted.org/packages/e5/a7/da0dc273d57f560399aa16d8a68ae7f9b57679476fc7ace46501d455fe84/regex-2025.11.3-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:3b3a5f320136873cc5561098dfab677eea139521cb9a9e8db98b7e64aef44cbc", size = 787892 }, - { url = "https://files.pythonhosted.org/packages/da/4b/732a0c5a9736a0b8d6d720d4945a2f1e6f38f87f48f3173559f53e8d5d82/regex-2025.11.3-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:75fa6f0056e7efb1f42a1c34e58be24072cb9e61a601340cc1196ae92326a4f9", size = 858462 }, - { url = "https://files.pythonhosted.org/packages/0c/f5/a2a03df27dc4c2d0c769220f5110ba8c4084b0bfa9ab0f9b4fcfa3d2b0fc/regex-2025.11.3-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:dbe6095001465294f13f1adcd3311e50dd84e5a71525f20a10bd16689c61ce0b", size = 850528 }, - { url = "https://files.pythonhosted.org/packages/d6/09/e1cd5bee3841c7f6eb37d95ca91cdee7100b8f88b81e41c2ef426910891a/regex-2025.11.3-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:454d9b4ae7881afbc25015b8627c16d88a597479b9dea82b8c6e7e2e07240dc7", size = 789866 }, - { url = "https://files.pythonhosted.org/packages/eb/51/702f5ea74e2a9c13d855a6a85b7f80c30f9e72a95493260193c07f3f8d74/regex-2025.11.3-cp313-cp313-win32.whl", hash = "sha256:28ba4d69171fc6e9896337d4fc63a43660002b7da53fc15ac992abcf3410917c", size = 266189 }, - { url = "https://files.pythonhosted.org/packages/8b/00/6e29bb314e271a743170e53649db0fdb8e8ff0b64b4f425f5602f4eb9014/regex-2025.11.3-cp313-cp313-win_amd64.whl", hash = "sha256:bac4200befe50c670c405dc33af26dad5a3b6b255dd6c000d92fe4629f9ed6a5", size = 277054 }, - { url = "https://files.pythonhosted.org/packages/25/f1/b156ff9f2ec9ac441710764dda95e4edaf5f36aca48246d1eea3f1fd96ec/regex-2025.11.3-cp313-cp313-win_arm64.whl", hash = "sha256:2292cd5a90dab247f9abe892ac584cb24f0f54680c73fcb4a7493c66c2bf2467", size = 270325 }, - { url = "https://files.pythonhosted.org/packages/20/28/fd0c63357caefe5680b8ea052131acbd7f456893b69cc2a90cc3e0dc90d4/regex-2025.11.3-cp313-cp313t-macosx_10_13_universal2.whl", hash = "sha256:1eb1ebf6822b756c723e09f5186473d93236c06c579d2cc0671a722d2ab14281", size = 491984 }, - { url = "https://files.pythonhosted.org/packages/df/ec/7014c15626ab46b902b3bcc4b28a7bae46d8f281fc7ea9c95e22fcaaa917/regex-2025.11.3-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:1e00ec2970aab10dc5db34af535f21fcf32b4a31d99e34963419636e2f85ae39", size = 292673 }, - { url = "https://files.pythonhosted.org/packages/23/ab/3b952ff7239f20d05f1f99e9e20188513905f218c81d52fb5e78d2bf7634/regex-2025.11.3-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:a4cb042b615245d5ff9b3794f56be4138b5adc35a4166014d31d1814744148c7", size = 291029 }, - { url = "https://files.pythonhosted.org/packages/21/7e/3dc2749fc684f455f162dcafb8a187b559e2614f3826877d3844a131f37b/regex-2025.11.3-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:44f264d4bf02f3176467d90b294d59bf1db9fe53c141ff772f27a8b456b2a9ed", size = 807437 }, - { url = "https://files.pythonhosted.org/packages/1b/0b/d529a85ab349c6a25d1ca783235b6e3eedf187247eab536797021f7126c6/regex-2025.11.3-cp313-cp313t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:7be0277469bf3bd7a34a9c57c1b6a724532a0d235cd0dc4e7f4316f982c28b19", size = 873368 }, - { url = "https://files.pythonhosted.org/packages/7d/18/2d868155f8c9e3e9d8f9e10c64e9a9f496bb8f7e037a88a8bed26b435af6/regex-2025.11.3-cp313-cp313t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:0d31e08426ff4b5b650f68839f5af51a92a5b51abd8554a60c2fbc7c71f25d0b", size = 914921 }, - { url = "https://files.pythonhosted.org/packages/2d/71/9d72ff0f354fa783fe2ba913c8734c3b433b86406117a8db4ea2bf1c7a2f/regex-2025.11.3-cp313-cp313t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:e43586ce5bd28f9f285a6e729466841368c4a0353f6fd08d4ce4630843d3648a", size = 812708 }, - { url = "https://files.pythonhosted.org/packages/e7/19/ce4bf7f5575c97f82b6e804ffb5c4e940c62609ab2a0d9538d47a7fdf7d4/regex-2025.11.3-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:0f9397d561a4c16829d4e6ff75202c1c08b68a3bdbfe29dbfcdb31c9830907c6", size = 795472 }, - { url = "https://files.pythonhosted.org/packages/03/86/fd1063a176ffb7b2315f9a1b08d17b18118b28d9df163132615b835a26ee/regex-2025.11.3-cp313-cp313t-musllinux_1_2_ppc64le.whl", hash = "sha256:dd16e78eb18ffdb25ee33a0682d17912e8cc8a770e885aeee95020046128f1ce", size = 868341 }, - { url = "https://files.pythonhosted.org/packages/12/43/103fb2e9811205e7386366501bc866a164a0430c79dd59eac886a2822950/regex-2025.11.3-cp313-cp313t-musllinux_1_2_s390x.whl", hash = "sha256:ffcca5b9efe948ba0661e9df0fa50d2bc4b097c70b9810212d6b62f05d83b2dd", size = 854666 }, - { url = "https://files.pythonhosted.org/packages/7d/22/e392e53f3869b75804762c7c848bd2dd2abf2b70fb0e526f58724638bd35/regex-2025.11.3-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:c56b4d162ca2b43318ac671c65bd4d563e841a694ac70e1a976ac38fcf4ca1d2", size = 799473 }, - { url = "https://files.pythonhosted.org/packages/4f/f9/8bd6b656592f925b6845fcbb4d57603a3ac2fb2373344ffa1ed70aa6820a/regex-2025.11.3-cp313-cp313t-win32.whl", hash = "sha256:9ddc42e68114e161e51e272f667d640f97e84a2b9ef14b7477c53aac20c2d59a", size = 268792 }, - { url = "https://files.pythonhosted.org/packages/e5/87/0e7d603467775ff65cd2aeabf1b5b50cc1c3708556a8b849a2fa4dd1542b/regex-2025.11.3-cp313-cp313t-win_amd64.whl", hash = "sha256:7a7c7fdf755032ffdd72c77e3d8096bdcb0eb92e89e17571a196f03d88b11b3c", size = 280214 }, - { url = "https://files.pythonhosted.org/packages/8d/d0/2afc6f8e94e2b64bfb738a7c2b6387ac1699f09f032d363ed9447fd2bb57/regex-2025.11.3-cp313-cp313t-win_arm64.whl", hash = "sha256:df9eb838c44f570283712e7cff14c16329a9f0fb19ca492d21d4b7528ee6821e", size = 271469 }, - { url = "https://files.pythonhosted.org/packages/31/e9/f6e13de7e0983837f7b6d238ad9458800a874bf37c264f7923e63409944c/regex-2025.11.3-cp314-cp314-macosx_10_13_universal2.whl", hash = "sha256:9697a52e57576c83139d7c6f213d64485d3df5bf84807c35fa409e6c970801c6", size = 489089 }, - { url = "https://files.pythonhosted.org/packages/a3/5c/261f4a262f1fa65141c1b74b255988bd2fa020cc599e53b080667d591cfc/regex-2025.11.3-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:e18bc3f73bd41243c9b38a6d9f2366cd0e0137a9aebe2d8ff76c5b67d4c0a3f4", size = 291059 }, - { url = "https://files.pythonhosted.org/packages/8e/57/f14eeb7f072b0e9a5a090d1712741fd8f214ec193dba773cf5410108bb7d/regex-2025.11.3-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:61a08bcb0ec14ff4e0ed2044aad948d0659604f824cbd50b55e30b0ec6f09c73", size = 288900 }, - { url = "https://files.pythonhosted.org/packages/3c/6b/1d650c45e99a9b327586739d926a1cd4e94666b1bd4af90428b36af66dc7/regex-2025.11.3-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:c9c30003b9347c24bcc210958c5d167b9e4f9be786cb380a7d32f14f9b84674f", size = 799010 }, - { url = "https://files.pythonhosted.org/packages/99/ee/d66dcbc6b628ce4e3f7f0cbbb84603aa2fc0ffc878babc857726b8aab2e9/regex-2025.11.3-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:4e1e592789704459900728d88d41a46fe3969b82ab62945560a31732ffc19a6d", size = 864893 }, - { url = "https://files.pythonhosted.org/packages/bf/2d/f238229f1caba7ac87a6c4153d79947fb0261415827ae0f77c304260c7d3/regex-2025.11.3-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:6538241f45eb5a25aa575dbba1069ad786f68a4f2773a29a2bd3dd1f9de787be", size = 911522 }, - { url = "https://files.pythonhosted.org/packages/bd/3d/22a4eaba214a917c80e04f6025d26143690f0419511e0116508e24b11c9b/regex-2025.11.3-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:bce22519c989bb72a7e6b36a199384c53db7722fe669ba891da75907fe3587db", size = 803272 }, - { url = "https://files.pythonhosted.org/packages/84/b1/03188f634a409353a84b5ef49754b97dbcc0c0f6fd6c8ede505a8960a0a4/regex-2025.11.3-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:66d559b21d3640203ab9075797a55165d79017520685fb407b9234d72ab63c62", size = 787958 }, - { url = "https://files.pythonhosted.org/packages/99/6a/27d072f7fbf6fadd59c64d210305e1ff865cc3b78b526fd147db768c553b/regex-2025.11.3-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:669dcfb2e38f9e8c69507bace46f4889e3abbfd9b0c29719202883c0a603598f", size = 859289 }, - { url = "https://files.pythonhosted.org/packages/9a/70/1b3878f648e0b6abe023172dacb02157e685564853cc363d9961bcccde4e/regex-2025.11.3-cp314-cp314-musllinux_1_2_s390x.whl", hash = "sha256:32f74f35ff0f25a5021373ac61442edcb150731fbaa28286bbc8bb1582c89d02", size = 850026 }, - { url = "https://files.pythonhosted.org/packages/dd/d5/68e25559b526b8baab8e66839304ede68ff6727237a47727d240006bd0ff/regex-2025.11.3-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:e6c7a21dffba883234baefe91bc3388e629779582038f75d2a5be918e250f0ed", size = 789499 }, - { url = "https://files.pythonhosted.org/packages/fc/df/43971264857140a350910d4e33df725e8c94dd9dee8d2e4729fa0d63d49e/regex-2025.11.3-cp314-cp314-win32.whl", hash = "sha256:795ea137b1d809eb6836b43748b12634291c0ed55ad50a7d72d21edf1cd565c4", size = 271604 }, - { url = "https://files.pythonhosted.org/packages/01/6f/9711b57dc6894a55faf80a4c1b5aa4f8649805cb9c7aef46f7d27e2b9206/regex-2025.11.3-cp314-cp314-win_amd64.whl", hash = "sha256:9f95fbaa0ee1610ec0fc6b26668e9917a582ba80c52cc6d9ada15e30aa9ab9ad", size = 280320 }, - { url = "https://files.pythonhosted.org/packages/f1/7e/f6eaa207d4377481f5e1775cdeb5a443b5a59b392d0065f3417d31d80f87/regex-2025.11.3-cp314-cp314-win_arm64.whl", hash = "sha256:dfec44d532be4c07088c3de2876130ff0fbeeacaa89a137decbbb5f665855a0f", size = 273372 }, - { url = "https://files.pythonhosted.org/packages/c3/06/49b198550ee0f5e4184271cee87ba4dfd9692c91ec55289e6282f0f86ccf/regex-2025.11.3-cp314-cp314t-macosx_10_13_universal2.whl", hash = "sha256:ba0d8a5d7f04f73ee7d01d974d47c5834f8a1b0224390e4fe7c12a3a92a78ecc", size = 491985 }, - { url = "https://files.pythonhosted.org/packages/ce/bf/abdafade008f0b1c9da10d934034cb670432d6cf6cbe38bbb53a1cfd6cf8/regex-2025.11.3-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:442d86cf1cfe4faabf97db7d901ef58347efd004934da045c745e7b5bd57ac49", size = 292669 }, - { url = "https://files.pythonhosted.org/packages/f9/ef/0c357bb8edbd2ad8e273fcb9e1761bc37b8acbc6e1be050bebd6475f19c1/regex-2025.11.3-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:fd0a5e563c756de210bb964789b5abe4f114dacae9104a47e1a649b910361536", size = 291030 }, - { url = "https://files.pythonhosted.org/packages/79/06/edbb67257596649b8fb088d6aeacbcb248ac195714b18a65e018bf4c0b50/regex-2025.11.3-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:bf3490bcbb985a1ae97b2ce9ad1c0f06a852d5b19dde9b07bdf25bf224248c95", size = 807674 }, - { url = "https://files.pythonhosted.org/packages/f4/d9/ad4deccfce0ea336296bd087f1a191543bb99ee1c53093dcd4c64d951d00/regex-2025.11.3-cp314-cp314t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:3809988f0a8b8c9dcc0f92478d6501fac7200b9ec56aecf0ec21f4a2ec4b6009", size = 873451 }, - { url = "https://files.pythonhosted.org/packages/13/75/a55a4724c56ef13e3e04acaab29df26582f6978c000ac9cd6810ad1f341f/regex-2025.11.3-cp314-cp314t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:f4ff94e58e84aedb9c9fce66d4ef9f27a190285b451420f297c9a09f2b9abee9", size = 914980 }, - { url = "https://files.pythonhosted.org/packages/67/1e/a1657ee15bd9116f70d4a530c736983eed997b361e20ecd8f5ca3759d5c5/regex-2025.11.3-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:7eb542fd347ce61e1321b0a6b945d5701528dca0cd9759c2e3bb8bd57e47964d", size = 812852 }, - { url = "https://files.pythonhosted.org/packages/b8/6f/f7516dde5506a588a561d296b2d0044839de06035bb486b326065b4c101e/regex-2025.11.3-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:d6c2d5919075a1f2e413c00b056ea0c2f065b3f5fe83c3d07d325ab92dce51d6", size = 795566 }, - { url = "https://files.pythonhosted.org/packages/d9/dd/3d10b9e170cc16fb34cb2cef91513cf3df65f440b3366030631b2984a264/regex-2025.11.3-cp314-cp314t-musllinux_1_2_ppc64le.whl", hash = "sha256:3f8bf11a4827cc7ce5a53d4ef6cddd5ad25595d3c1435ef08f76825851343154", size = 868463 }, - { url = "https://files.pythonhosted.org/packages/f5/8e/935e6beff1695aa9085ff83195daccd72acc82c81793df480f34569330de/regex-2025.11.3-cp314-cp314t-musllinux_1_2_s390x.whl", hash = "sha256:22c12d837298651e5550ac1d964e4ff57c3f56965fc1812c90c9fb2028eaf267", size = 854694 }, - { url = "https://files.pythonhosted.org/packages/92/12/10650181a040978b2f5720a6a74d44f841371a3d984c2083fc1752e4acf6/regex-2025.11.3-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:62ba394a3dda9ad41c7c780f60f6e4a70988741415ae96f6d1bf6c239cf01379", size = 799691 }, - { url = "https://files.pythonhosted.org/packages/67/90/8f37138181c9a7690e7e4cb388debbd389342db3c7381d636d2875940752/regex-2025.11.3-cp314-cp314t-win32.whl", hash = "sha256:4bf146dca15cdd53224a1bf46d628bd7590e4a07fbb69e720d561aea43a32b38", size = 274583 }, - { url = "https://files.pythonhosted.org/packages/8f/cd/867f5ec442d56beb56f5f854f40abcfc75e11d10b11fdb1869dd39c63aaf/regex-2025.11.3-cp314-cp314t-win_amd64.whl", hash = "sha256:adad1a1bcf1c9e76346e091d22d23ac54ef28e1365117d99521631078dfec9de", size = 284286 }, - { url = "https://files.pythonhosted.org/packages/20/31/32c0c4610cbc070362bf1d2e4ea86d1ea29014d400a6d6c2486fcfd57766/regex-2025.11.3-cp314-cp314t-win_arm64.whl", hash = "sha256:c54f768482cef41e219720013cd05933b6f971d9562544d691c68699bf2b6801", size = 274741 }, +sdist = { url = "https://files.pythonhosted.org/packages/cc/a9/546676f25e573a4cf00fe8e119b78a37b6a8fe2dc95cda877b30889c9c45/regex-2025.11.3.tar.gz", hash = "sha256:1fedc720f9bb2494ce31a58a1631f9c82df6a09b49c19517ea5cc280b4541e01", size = 414669, upload-time = "2025-11-03T21:34:22.089Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/e1/a7/dda24ebd49da46a197436ad96378f17df30ceb40e52e859fc42cac45b850/regex-2025.11.3-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:c1e448051717a334891f2b9a620fe36776ebf3dd8ec46a0b877c8ae69575feb4", size = 489081, upload-time = "2025-11-03T21:31:55.9Z" }, + { url = "https://files.pythonhosted.org/packages/19/22/af2dc751aacf88089836aa088a1a11c4f21a04707eb1b0478e8e8fb32847/regex-2025.11.3-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:9b5aca4d5dfd7fbfbfbdaf44850fcc7709a01146a797536a8f84952e940cca76", size = 291123, upload-time = "2025-11-03T21:31:57.758Z" }, + { url = "https://files.pythonhosted.org/packages/a3/88/1a3ea5672f4b0a84802ee9891b86743438e7c04eb0b8f8c4e16a42375327/regex-2025.11.3-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:04d2765516395cf7dda331a244a3282c0f5ae96075f728629287dfa6f76ba70a", size = 288814, upload-time = "2025-11-03T21:32:01.12Z" }, + { url = "https://files.pythonhosted.org/packages/fb/8c/f5987895bf42b8ddeea1b315c9fedcfe07cadee28b9c98cf50d00adcb14d/regex-2025.11.3-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:5d9903ca42bfeec4cebedba8022a7c97ad2aab22e09573ce9976ba01b65e4361", size = 798592, upload-time = "2025-11-03T21:32:03.006Z" }, + { url = "https://files.pythonhosted.org/packages/99/2a/6591ebeede78203fa77ee46a1c36649e02df9eaa77a033d1ccdf2fcd5d4e/regex-2025.11.3-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:639431bdc89d6429f6721625e8129413980ccd62e9d3f496be618a41d205f160", size = 864122, upload-time = "2025-11-03T21:32:04.553Z" }, + { url = "https://files.pythonhosted.org/packages/94/d6/be32a87cf28cf8ed064ff281cfbd49aefd90242a83e4b08b5a86b38e8eb4/regex-2025.11.3-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:f117efad42068f9715677c8523ed2be1518116d1c49b1dd17987716695181efe", size = 912272, upload-time = "2025-11-03T21:32:06.148Z" }, + { url = "https://files.pythonhosted.org/packages/62/11/9bcef2d1445665b180ac7f230406ad80671f0fc2a6ffb93493b5dd8cd64c/regex-2025.11.3-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:4aecb6f461316adf9f1f0f6a4a1a3d79e045f9b71ec76055a791affa3b285850", size = 803497, upload-time = "2025-11-03T21:32:08.162Z" }, + { url = "https://files.pythonhosted.org/packages/e5/a7/da0dc273d57f560399aa16d8a68ae7f9b57679476fc7ace46501d455fe84/regex-2025.11.3-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:3b3a5f320136873cc5561098dfab677eea139521cb9a9e8db98b7e64aef44cbc", size = 787892, upload-time = "2025-11-03T21:32:09.769Z" }, + { url = "https://files.pythonhosted.org/packages/da/4b/732a0c5a9736a0b8d6d720d4945a2f1e6f38f87f48f3173559f53e8d5d82/regex-2025.11.3-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:75fa6f0056e7efb1f42a1c34e58be24072cb9e61a601340cc1196ae92326a4f9", size = 858462, upload-time = "2025-11-03T21:32:11.769Z" }, + { url = "https://files.pythonhosted.org/packages/0c/f5/a2a03df27dc4c2d0c769220f5110ba8c4084b0bfa9ab0f9b4fcfa3d2b0fc/regex-2025.11.3-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:dbe6095001465294f13f1adcd3311e50dd84e5a71525f20a10bd16689c61ce0b", size = 850528, upload-time = "2025-11-03T21:32:13.906Z" }, + { url = "https://files.pythonhosted.org/packages/d6/09/e1cd5bee3841c7f6eb37d95ca91cdee7100b8f88b81e41c2ef426910891a/regex-2025.11.3-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:454d9b4ae7881afbc25015b8627c16d88a597479b9dea82b8c6e7e2e07240dc7", size = 789866, upload-time = "2025-11-03T21:32:15.748Z" }, + { url = "https://files.pythonhosted.org/packages/eb/51/702f5ea74e2a9c13d855a6a85b7f80c30f9e72a95493260193c07f3f8d74/regex-2025.11.3-cp313-cp313-win32.whl", hash = "sha256:28ba4d69171fc6e9896337d4fc63a43660002b7da53fc15ac992abcf3410917c", size = 266189, upload-time = "2025-11-03T21:32:17.493Z" }, + { url = "https://files.pythonhosted.org/packages/8b/00/6e29bb314e271a743170e53649db0fdb8e8ff0b64b4f425f5602f4eb9014/regex-2025.11.3-cp313-cp313-win_amd64.whl", hash = "sha256:bac4200befe50c670c405dc33af26dad5a3b6b255dd6c000d92fe4629f9ed6a5", size = 277054, upload-time = "2025-11-03T21:32:19.042Z" }, + { url = "https://files.pythonhosted.org/packages/25/f1/b156ff9f2ec9ac441710764dda95e4edaf5f36aca48246d1eea3f1fd96ec/regex-2025.11.3-cp313-cp313-win_arm64.whl", hash = "sha256:2292cd5a90dab247f9abe892ac584cb24f0f54680c73fcb4a7493c66c2bf2467", size = 270325, upload-time = "2025-11-03T21:32:21.338Z" }, + { url = "https://files.pythonhosted.org/packages/20/28/fd0c63357caefe5680b8ea052131acbd7f456893b69cc2a90cc3e0dc90d4/regex-2025.11.3-cp313-cp313t-macosx_10_13_universal2.whl", hash = "sha256:1eb1ebf6822b756c723e09f5186473d93236c06c579d2cc0671a722d2ab14281", size = 491984, upload-time = "2025-11-03T21:32:23.466Z" }, + { url = "https://files.pythonhosted.org/packages/df/ec/7014c15626ab46b902b3bcc4b28a7bae46d8f281fc7ea9c95e22fcaaa917/regex-2025.11.3-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:1e00ec2970aab10dc5db34af535f21fcf32b4a31d99e34963419636e2f85ae39", size = 292673, upload-time = "2025-11-03T21:32:25.034Z" }, + { url = "https://files.pythonhosted.org/packages/23/ab/3b952ff7239f20d05f1f99e9e20188513905f218c81d52fb5e78d2bf7634/regex-2025.11.3-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:a4cb042b615245d5ff9b3794f56be4138b5adc35a4166014d31d1814744148c7", size = 291029, upload-time = "2025-11-03T21:32:26.528Z" }, + { url = "https://files.pythonhosted.org/packages/21/7e/3dc2749fc684f455f162dcafb8a187b559e2614f3826877d3844a131f37b/regex-2025.11.3-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:44f264d4bf02f3176467d90b294d59bf1db9fe53c141ff772f27a8b456b2a9ed", size = 807437, upload-time = "2025-11-03T21:32:28.363Z" }, + { url = "https://files.pythonhosted.org/packages/1b/0b/d529a85ab349c6a25d1ca783235b6e3eedf187247eab536797021f7126c6/regex-2025.11.3-cp313-cp313t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:7be0277469bf3bd7a34a9c57c1b6a724532a0d235cd0dc4e7f4316f982c28b19", size = 873368, upload-time = "2025-11-03T21:32:30.4Z" }, + { url = "https://files.pythonhosted.org/packages/7d/18/2d868155f8c9e3e9d8f9e10c64e9a9f496bb8f7e037a88a8bed26b435af6/regex-2025.11.3-cp313-cp313t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:0d31e08426ff4b5b650f68839f5af51a92a5b51abd8554a60c2fbc7c71f25d0b", size = 914921, upload-time = "2025-11-03T21:32:32.123Z" }, + { url = "https://files.pythonhosted.org/packages/2d/71/9d72ff0f354fa783fe2ba913c8734c3b433b86406117a8db4ea2bf1c7a2f/regex-2025.11.3-cp313-cp313t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:e43586ce5bd28f9f285a6e729466841368c4a0353f6fd08d4ce4630843d3648a", size = 812708, upload-time = "2025-11-03T21:32:34.305Z" }, + { url = "https://files.pythonhosted.org/packages/e7/19/ce4bf7f5575c97f82b6e804ffb5c4e940c62609ab2a0d9538d47a7fdf7d4/regex-2025.11.3-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:0f9397d561a4c16829d4e6ff75202c1c08b68a3bdbfe29dbfcdb31c9830907c6", size = 795472, upload-time = "2025-11-03T21:32:36.364Z" }, + { url = "https://files.pythonhosted.org/packages/03/86/fd1063a176ffb7b2315f9a1b08d17b18118b28d9df163132615b835a26ee/regex-2025.11.3-cp313-cp313t-musllinux_1_2_ppc64le.whl", hash = "sha256:dd16e78eb18ffdb25ee33a0682d17912e8cc8a770e885aeee95020046128f1ce", size = 868341, upload-time = "2025-11-03T21:32:38.042Z" }, + { url = "https://files.pythonhosted.org/packages/12/43/103fb2e9811205e7386366501bc866a164a0430c79dd59eac886a2822950/regex-2025.11.3-cp313-cp313t-musllinux_1_2_s390x.whl", hash = "sha256:ffcca5b9efe948ba0661e9df0fa50d2bc4b097c70b9810212d6b62f05d83b2dd", size = 854666, upload-time = "2025-11-03T21:32:40.079Z" }, + { url = "https://files.pythonhosted.org/packages/7d/22/e392e53f3869b75804762c7c848bd2dd2abf2b70fb0e526f58724638bd35/regex-2025.11.3-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:c56b4d162ca2b43318ac671c65bd4d563e841a694ac70e1a976ac38fcf4ca1d2", size = 799473, upload-time = "2025-11-03T21:32:42.148Z" }, + { url = "https://files.pythonhosted.org/packages/4f/f9/8bd6b656592f925b6845fcbb4d57603a3ac2fb2373344ffa1ed70aa6820a/regex-2025.11.3-cp313-cp313t-win32.whl", hash = "sha256:9ddc42e68114e161e51e272f667d640f97e84a2b9ef14b7477c53aac20c2d59a", size = 268792, upload-time = "2025-11-03T21:32:44.13Z" }, + { url = "https://files.pythonhosted.org/packages/e5/87/0e7d603467775ff65cd2aeabf1b5b50cc1c3708556a8b849a2fa4dd1542b/regex-2025.11.3-cp313-cp313t-win_amd64.whl", hash = "sha256:7a7c7fdf755032ffdd72c77e3d8096bdcb0eb92e89e17571a196f03d88b11b3c", size = 280214, upload-time = "2025-11-03T21:32:45.853Z" }, + { url = "https://files.pythonhosted.org/packages/8d/d0/2afc6f8e94e2b64bfb738a7c2b6387ac1699f09f032d363ed9447fd2bb57/regex-2025.11.3-cp313-cp313t-win_arm64.whl", hash = "sha256:df9eb838c44f570283712e7cff14c16329a9f0fb19ca492d21d4b7528ee6821e", size = 271469, upload-time = "2025-11-03T21:32:48.026Z" }, + { url = "https://files.pythonhosted.org/packages/31/e9/f6e13de7e0983837f7b6d238ad9458800a874bf37c264f7923e63409944c/regex-2025.11.3-cp314-cp314-macosx_10_13_universal2.whl", hash = "sha256:9697a52e57576c83139d7c6f213d64485d3df5bf84807c35fa409e6c970801c6", size = 489089, upload-time = "2025-11-03T21:32:50.027Z" }, + { url = "https://files.pythonhosted.org/packages/a3/5c/261f4a262f1fa65141c1b74b255988bd2fa020cc599e53b080667d591cfc/regex-2025.11.3-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:e18bc3f73bd41243c9b38a6d9f2366cd0e0137a9aebe2d8ff76c5b67d4c0a3f4", size = 291059, upload-time = "2025-11-03T21:32:51.682Z" }, + { url = "https://files.pythonhosted.org/packages/8e/57/f14eeb7f072b0e9a5a090d1712741fd8f214ec193dba773cf5410108bb7d/regex-2025.11.3-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:61a08bcb0ec14ff4e0ed2044aad948d0659604f824cbd50b55e30b0ec6f09c73", size = 288900, upload-time = "2025-11-03T21:32:53.569Z" }, + { url = "https://files.pythonhosted.org/packages/3c/6b/1d650c45e99a9b327586739d926a1cd4e94666b1bd4af90428b36af66dc7/regex-2025.11.3-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:c9c30003b9347c24bcc210958c5d167b9e4f9be786cb380a7d32f14f9b84674f", size = 799010, upload-time = "2025-11-03T21:32:55.222Z" }, + { url = "https://files.pythonhosted.org/packages/99/ee/d66dcbc6b628ce4e3f7f0cbbb84603aa2fc0ffc878babc857726b8aab2e9/regex-2025.11.3-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:4e1e592789704459900728d88d41a46fe3969b82ab62945560a31732ffc19a6d", size = 864893, upload-time = "2025-11-03T21:32:57.239Z" }, + { url = "https://files.pythonhosted.org/packages/bf/2d/f238229f1caba7ac87a6c4153d79947fb0261415827ae0f77c304260c7d3/regex-2025.11.3-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:6538241f45eb5a25aa575dbba1069ad786f68a4f2773a29a2bd3dd1f9de787be", size = 911522, upload-time = "2025-11-03T21:32:59.274Z" }, + { url = "https://files.pythonhosted.org/packages/bd/3d/22a4eaba214a917c80e04f6025d26143690f0419511e0116508e24b11c9b/regex-2025.11.3-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:bce22519c989bb72a7e6b36a199384c53db7722fe669ba891da75907fe3587db", size = 803272, upload-time = "2025-11-03T21:33:01.393Z" }, + { url = "https://files.pythonhosted.org/packages/84/b1/03188f634a409353a84b5ef49754b97dbcc0c0f6fd6c8ede505a8960a0a4/regex-2025.11.3-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:66d559b21d3640203ab9075797a55165d79017520685fb407b9234d72ab63c62", size = 787958, upload-time = "2025-11-03T21:33:03.379Z" }, + { url = "https://files.pythonhosted.org/packages/99/6a/27d072f7fbf6fadd59c64d210305e1ff865cc3b78b526fd147db768c553b/regex-2025.11.3-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:669dcfb2e38f9e8c69507bace46f4889e3abbfd9b0c29719202883c0a603598f", size = 859289, upload-time = "2025-11-03T21:33:05.374Z" }, + { url = "https://files.pythonhosted.org/packages/9a/70/1b3878f648e0b6abe023172dacb02157e685564853cc363d9961bcccde4e/regex-2025.11.3-cp314-cp314-musllinux_1_2_s390x.whl", hash = "sha256:32f74f35ff0f25a5021373ac61442edcb150731fbaa28286bbc8bb1582c89d02", size = 850026, upload-time = "2025-11-03T21:33:07.131Z" }, + { url = "https://files.pythonhosted.org/packages/dd/d5/68e25559b526b8baab8e66839304ede68ff6727237a47727d240006bd0ff/regex-2025.11.3-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:e6c7a21dffba883234baefe91bc3388e629779582038f75d2a5be918e250f0ed", size = 789499, upload-time = "2025-11-03T21:33:09.141Z" }, + { url = "https://files.pythonhosted.org/packages/fc/df/43971264857140a350910d4e33df725e8c94dd9dee8d2e4729fa0d63d49e/regex-2025.11.3-cp314-cp314-win32.whl", hash = "sha256:795ea137b1d809eb6836b43748b12634291c0ed55ad50a7d72d21edf1cd565c4", size = 271604, upload-time = "2025-11-03T21:33:10.9Z" }, + { url = "https://files.pythonhosted.org/packages/01/6f/9711b57dc6894a55faf80a4c1b5aa4f8649805cb9c7aef46f7d27e2b9206/regex-2025.11.3-cp314-cp314-win_amd64.whl", hash = "sha256:9f95fbaa0ee1610ec0fc6b26668e9917a582ba80c52cc6d9ada15e30aa9ab9ad", size = 280320, upload-time = "2025-11-03T21:33:12.572Z" }, + { url = "https://files.pythonhosted.org/packages/f1/7e/f6eaa207d4377481f5e1775cdeb5a443b5a59b392d0065f3417d31d80f87/regex-2025.11.3-cp314-cp314-win_arm64.whl", hash = "sha256:dfec44d532be4c07088c3de2876130ff0fbeeacaa89a137decbbb5f665855a0f", size = 273372, upload-time = "2025-11-03T21:33:14.219Z" }, + { url = "https://files.pythonhosted.org/packages/c3/06/49b198550ee0f5e4184271cee87ba4dfd9692c91ec55289e6282f0f86ccf/regex-2025.11.3-cp314-cp314t-macosx_10_13_universal2.whl", hash = "sha256:ba0d8a5d7f04f73ee7d01d974d47c5834f8a1b0224390e4fe7c12a3a92a78ecc", size = 491985, upload-time = "2025-11-03T21:33:16.555Z" }, + { url = "https://files.pythonhosted.org/packages/ce/bf/abdafade008f0b1c9da10d934034cb670432d6cf6cbe38bbb53a1cfd6cf8/regex-2025.11.3-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:442d86cf1cfe4faabf97db7d901ef58347efd004934da045c745e7b5bd57ac49", size = 292669, upload-time = "2025-11-03T21:33:18.32Z" }, + { url = "https://files.pythonhosted.org/packages/f9/ef/0c357bb8edbd2ad8e273fcb9e1761bc37b8acbc6e1be050bebd6475f19c1/regex-2025.11.3-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:fd0a5e563c756de210bb964789b5abe4f114dacae9104a47e1a649b910361536", size = 291030, upload-time = "2025-11-03T21:33:20.048Z" }, + { url = "https://files.pythonhosted.org/packages/79/06/edbb67257596649b8fb088d6aeacbcb248ac195714b18a65e018bf4c0b50/regex-2025.11.3-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:bf3490bcbb985a1ae97b2ce9ad1c0f06a852d5b19dde9b07bdf25bf224248c95", size = 807674, upload-time = "2025-11-03T21:33:21.797Z" }, + { url = "https://files.pythonhosted.org/packages/f4/d9/ad4deccfce0ea336296bd087f1a191543bb99ee1c53093dcd4c64d951d00/regex-2025.11.3-cp314-cp314t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:3809988f0a8b8c9dcc0f92478d6501fac7200b9ec56aecf0ec21f4a2ec4b6009", size = 873451, upload-time = "2025-11-03T21:33:23.741Z" }, + { url = "https://files.pythonhosted.org/packages/13/75/a55a4724c56ef13e3e04acaab29df26582f6978c000ac9cd6810ad1f341f/regex-2025.11.3-cp314-cp314t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:f4ff94e58e84aedb9c9fce66d4ef9f27a190285b451420f297c9a09f2b9abee9", size = 914980, upload-time = "2025-11-03T21:33:25.999Z" }, + { url = "https://files.pythonhosted.org/packages/67/1e/a1657ee15bd9116f70d4a530c736983eed997b361e20ecd8f5ca3759d5c5/regex-2025.11.3-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:7eb542fd347ce61e1321b0a6b945d5701528dca0cd9759c2e3bb8bd57e47964d", size = 812852, upload-time = "2025-11-03T21:33:27.852Z" }, + { url = "https://files.pythonhosted.org/packages/b8/6f/f7516dde5506a588a561d296b2d0044839de06035bb486b326065b4c101e/regex-2025.11.3-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:d6c2d5919075a1f2e413c00b056ea0c2f065b3f5fe83c3d07d325ab92dce51d6", size = 795566, upload-time = "2025-11-03T21:33:32.364Z" }, + { url = "https://files.pythonhosted.org/packages/d9/dd/3d10b9e170cc16fb34cb2cef91513cf3df65f440b3366030631b2984a264/regex-2025.11.3-cp314-cp314t-musllinux_1_2_ppc64le.whl", hash = "sha256:3f8bf11a4827cc7ce5a53d4ef6cddd5ad25595d3c1435ef08f76825851343154", size = 868463, upload-time = "2025-11-03T21:33:34.459Z" }, + { url = "https://files.pythonhosted.org/packages/f5/8e/935e6beff1695aa9085ff83195daccd72acc82c81793df480f34569330de/regex-2025.11.3-cp314-cp314t-musllinux_1_2_s390x.whl", hash = "sha256:22c12d837298651e5550ac1d964e4ff57c3f56965fc1812c90c9fb2028eaf267", size = 854694, upload-time = "2025-11-03T21:33:36.793Z" }, + { url = "https://files.pythonhosted.org/packages/92/12/10650181a040978b2f5720a6a74d44f841371a3d984c2083fc1752e4acf6/regex-2025.11.3-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:62ba394a3dda9ad41c7c780f60f6e4a70988741415ae96f6d1bf6c239cf01379", size = 799691, upload-time = "2025-11-03T21:33:39.079Z" }, + { url = "https://files.pythonhosted.org/packages/67/90/8f37138181c9a7690e7e4cb388debbd389342db3c7381d636d2875940752/regex-2025.11.3-cp314-cp314t-win32.whl", hash = "sha256:4bf146dca15cdd53224a1bf46d628bd7590e4a07fbb69e720d561aea43a32b38", size = 274583, upload-time = "2025-11-03T21:33:41.302Z" }, + { url = "https://files.pythonhosted.org/packages/8f/cd/867f5ec442d56beb56f5f854f40abcfc75e11d10b11fdb1869dd39c63aaf/regex-2025.11.3-cp314-cp314t-win_amd64.whl", hash = "sha256:adad1a1bcf1c9e76346e091d22d23ac54ef28e1365117d99521631078dfec9de", size = 284286, upload-time = "2025-11-03T21:33:43.324Z" }, + { url = "https://files.pythonhosted.org/packages/20/31/32c0c4610cbc070362bf1d2e4ea86d1ea29014d400a6d6c2486fcfd57766/regex-2025.11.3-cp314-cp314t-win_arm64.whl", hash = "sha256:c54f768482cef41e219720013cd05933b6f971d9562544d691c68699bf2b6801", size = 274741, upload-time = "2025-11-03T21:33:45.557Z" }, ] [[package]] @@ -1862,7 +1887,7 @@ requires-dist = [ { name = "email-validator", specifier = ">=2.2.0" }, { name = "fastapi", extras = ["standard"], specifier = ">=0.115.14" }, { name = "fastapi-filter", specifier = ">=2.0.1" }, - { name = "fastapi-mail", git = "https://github.com/simonvanlierde/fastapi-mail?rev=f32147ec1a450ed22262913c5ac7ec3b67dd0117" }, + { name = "fastapi-mail", git = "https://github.com/simonvanlierde/fastapi-mail?rev=6c6f04a7afaf3cdced82764009a2f1f2a3c3ee6c" }, { name = "fastapi-pagination", specifier = ">=0.13.2" }, { name = "fastapi-storages", specifier = ">=0.3.0" }, { name = "fastapi-users", extras = ["oauth", "sqlalchemy"], specifier = ">=14.0.1" }, @@ -1871,7 +1896,7 @@ requires-dist = [ { name = "mjml", specifier = ">=0.11.1" }, { name = "pillow", specifier = ">=11.2.1" }, { name = "psycopg", extras = ["binary"], specifier = ">=3.2.9" }, - { name = "pydantic", specifier = ">=2.11,<2.12" }, + { name = "pydantic", specifier = ">=2.12" }, { name = "pydantic-extra-types", specifier = ">=2.10.5" }, { name = "pydantic-settings", specifier = ">=2.10.1" }, { name = "python-dotenv", specifier = ">=1.1.1" }, @@ -1879,7 +1904,7 @@ requires-dist = [ { name = "redis", specifier = ">=5.2.1" }, { name = "relab-rpi-cam-models", specifier = ">=0.1.1" }, { name = "sqlalchemy", specifier = ">=2.0.41" }, - { name = "sqlmodel", specifier = ">=0.0.24" }, + { name = "sqlmodel", specifier = ">=0.0.27" }, { name = "tldextract", specifier = ">=5.3.0" }, ] @@ -1920,9 +1945,9 @@ dependencies = [ { name = "pillow" }, { name = "pydantic" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/58/55/1bd336b19e2483bea7d1f8c2967d25a297ddacb686ee72c13b2023ae97d0/relab_rpi_cam_models-0.1.1.tar.gz", hash = "sha256:6ac60f787b33c7951edd956c78c939764af48e63eaa9809eaa3590a604cf1dde", size = 3943 } +sdist = { url = "https://files.pythonhosted.org/packages/58/55/1bd336b19e2483bea7d1f8c2967d25a297ddacb686ee72c13b2023ae97d0/relab_rpi_cam_models-0.1.1.tar.gz", hash = "sha256:6ac60f787b33c7951edd956c78c939764af48e63eaa9809eaa3590a604cf1dde", size = 3943, upload-time = "2025-08-19T23:38:05.058Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/8f/85/1ec6ec0c444dcccdc343b2978d5bcde8043b0b696c6d853c51e115d7dc53/relab_rpi_cam_models-0.1.1-py3-none-any.whl", hash = "sha256:bba3182febdbbc8f48897e1dc42ac2b779a48de8ef6be867b6131eed2b019f6b", size = 5552 }, + { url = "https://files.pythonhosted.org/packages/8f/85/1ec6ec0c444dcccdc343b2978d5bcde8043b0b696c6d853c51e115d7dc53/relab_rpi_cam_models-0.1.1-py3-none-any.whl", hash = "sha256:bba3182febdbbc8f48897e1dc42ac2b779a48de8ef6be867b6131eed2b019f6b", size = 5552, upload-time = "2025-08-19T23:38:03.866Z" }, ] [[package]] @@ -1935,9 +1960,9 @@ dependencies = [ { name = "idna" }, { name = "urllib3" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/c9/74/b3ff8e6c8446842c3f5c837e9c3dfcfe2018ea6ecef224c710c85ef728f4/requests-2.32.5.tar.gz", hash = "sha256:dbba0bac56e100853db0ea71b82b4dfd5fe2bf6d3754a8893c3af500cec7d7cf", size = 134517 } +sdist = { url = "https://files.pythonhosted.org/packages/c9/74/b3ff8e6c8446842c3f5c837e9c3dfcfe2018ea6ecef224c710c85ef728f4/requests-2.32.5.tar.gz", hash = "sha256:dbba0bac56e100853db0ea71b82b4dfd5fe2bf6d3754a8893c3af500cec7d7cf", size = 134517, upload-time = "2025-08-18T20:46:02.573Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/1e/db/4254e3eabe8020b458f1a747140d32277ec7a271daf1d235b70dc0b4e6e3/requests-2.32.5-py3-none-any.whl", hash = "sha256:2462f94637a34fd532264295e186976db0f5d453d1cdd31473c85a6a161affb6", size = 64738 }, + { url = "https://files.pythonhosted.org/packages/1e/db/4254e3eabe8020b458f1a747140d32277ec7a271daf1d235b70dc0b4e6e3/requests-2.32.5-py3-none-any.whl", hash = "sha256:2462f94637a34fd532264295e186976db0f5d453d1cdd31473c85a6a161affb6", size = 64738, upload-time = "2025-08-18T20:46:00.542Z" }, ] [[package]] @@ -1947,9 +1972,9 @@ source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "requests" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/3c/f8/5dc70102e4d337063452c82e1f0d95e39abfe67aa222ed8a5ddeb9df8de8/requests_file-3.0.1.tar.gz", hash = "sha256:f14243d7796c588f3521bd423c5dea2ee4cc730e54a3cac9574d78aca1272576", size = 6967 } +sdist = { url = "https://files.pythonhosted.org/packages/3c/f8/5dc70102e4d337063452c82e1f0d95e39abfe67aa222ed8a5ddeb9df8de8/requests_file-3.0.1.tar.gz", hash = "sha256:f14243d7796c588f3521bd423c5dea2ee4cc730e54a3cac9574d78aca1272576", size = 6967, upload-time = "2025-10-20T18:56:42.279Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/e1/d5/de8f089119205a09da657ed4784c584ede8381a0ce6821212a6d4ca47054/requests_file-3.0.1-py2.py3-none-any.whl", hash = "sha256:d0f5eb94353986d998f80ac63c7f146a307728be051d4d1cd390dbdb59c10fa2", size = 4514 }, + { url = "https://files.pythonhosted.org/packages/e1/d5/de8f089119205a09da657ed4784c584ede8381a0ce6821212a6d4ca47054/requests_file-3.0.1-py2.py3-none-any.whl", hash = "sha256:d0f5eb94353986d998f80ac63c7f146a307728be051d4d1cd390dbdb59c10fa2", size = 4514, upload-time = "2025-10-20T18:56:41.184Z" }, ] [[package]] @@ -1960,9 +1985,9 @@ dependencies = [ { name = "markdown-it-py" }, { name = "pygments" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/fb/d2/8920e102050a0de7bfabeb4c4614a49248cf8d5d7a8d01885fbb24dc767a/rich-14.2.0.tar.gz", hash = "sha256:73ff50c7c0c1c77c8243079283f4edb376f0f6442433aecb8ce7e6d0b92d1fe4", size = 219990 } +sdist = { url = "https://files.pythonhosted.org/packages/fb/d2/8920e102050a0de7bfabeb4c4614a49248cf8d5d7a8d01885fbb24dc767a/rich-14.2.0.tar.gz", hash = "sha256:73ff50c7c0c1c77c8243079283f4edb376f0f6442433aecb8ce7e6d0b92d1fe4", size = 219990, upload-time = "2025-10-09T14:16:53.064Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/25/7a/b0178788f8dc6cafce37a212c99565fa1fe7872c70c6c9c1e1a372d9d88f/rich-14.2.0-py3-none-any.whl", hash = "sha256:76bc51fe2e57d2b1be1f96c524b890b816e334ab4c1e45888799bfaab0021edd", size = 243393 }, + { url = "https://files.pythonhosted.org/packages/25/7a/b0178788f8dc6cafce37a212c99565fa1fe7872c70c6c9c1e1a372d9d88f/rich-14.2.0-py3-none-any.whl", hash = "sha256:76bc51fe2e57d2b1be1f96c524b890b816e334ab4c1e45888799bfaab0021edd", size = 243393, upload-time = "2025-10-09T14:16:51.245Z" }, ] [[package]] @@ -1974,62 +1999,62 @@ dependencies = [ { name = "rich" }, { name = "typing-extensions" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/67/33/1a18839aaa8feef7983590c05c22c9c09d245ada6017d118325bbfcc7651/rich_toolkit-0.15.1.tar.gz", hash = "sha256:6f9630eb29f3843d19d48c3bd5706a086d36d62016687f9d0efa027ddc2dd08a", size = 115322 } +sdist = { url = "https://files.pythonhosted.org/packages/67/33/1a18839aaa8feef7983590c05c22c9c09d245ada6017d118325bbfcc7651/rich_toolkit-0.15.1.tar.gz", hash = "sha256:6f9630eb29f3843d19d48c3bd5706a086d36d62016687f9d0efa027ddc2dd08a", size = 115322, upload-time = "2025-09-04T09:28:11.789Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/c8/49/42821d55ead7b5a87c8d121edf323cb393d8579f63e933002ade900b784f/rich_toolkit-0.15.1-py3-none-any.whl", hash = "sha256:36a0b1d9a135d26776e4b78f1d5c2655da6e0ef432380b5c6b523c8d8ab97478", size = 29412 }, + { url = "https://files.pythonhosted.org/packages/c8/49/42821d55ead7b5a87c8d121edf323cb393d8579f63e933002ade900b784f/rich_toolkit-0.15.1-py3-none-any.whl", hash = "sha256:36a0b1d9a135d26776e4b78f1d5c2655da6e0ef432380b5c6b523c8d8ab97478", size = 29412, upload-time = "2025-09-04T09:28:10.587Z" }, ] [[package]] name = "rignore" version = "0.7.6" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/e5/f5/8bed2310abe4ae04b67a38374a4d311dd85220f5d8da56f47ae9361be0b0/rignore-0.7.6.tar.gz", hash = "sha256:00d3546cd793c30cb17921ce674d2c8f3a4b00501cb0e3dd0e82217dbeba2671", size = 57140 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/b7/8a/a4078f6e14932ac7edb171149c481de29969d96ddee3ece5dc4c26f9e0c3/rignore-0.7.6-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:2bdab1d31ec9b4fb1331980ee49ea051c0d7f7bb6baa28b3125ef03cdc48fdaf", size = 883057 }, - { url = "https://files.pythonhosted.org/packages/f9/8f/f8daacd177db4bf7c2223bab41e630c52711f8af9ed279be2058d2fe4982/rignore-0.7.6-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:90f0a00ce0c866c275bf888271f1dc0d2140f29b82fcf33cdbda1e1a6af01010", size = 820150 }, - { url = "https://files.pythonhosted.org/packages/36/31/b65b837e39c3f7064c426754714ac633b66b8c2290978af9d7f513e14aa9/rignore-0.7.6-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c1ad295537041dc2ed4b540fb1a3906bd9ede6ccdad3fe79770cd89e04e3c73c", size = 897406 }, - { url = "https://files.pythonhosted.org/packages/ca/58/1970ce006c427e202ac7c081435719a076c478f07b3a23f469227788dc23/rignore-0.7.6-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:f782dbd3a65a5ac85adfff69e5c6b101285ef3f845c3a3cae56a54bebf9fe116", size = 874050 }, - { url = "https://files.pythonhosted.org/packages/d4/00/eb45db9f90137329072a732273be0d383cb7d7f50ddc8e0bceea34c1dfdf/rignore-0.7.6-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:65cece3b36e5b0826d946494734c0e6aaf5a0337e18ff55b071438efe13d559e", size = 1167835 }, - { url = "https://files.pythonhosted.org/packages/f3/f1/6f1d72ddca41a64eed569680587a1236633587cc9f78136477ae69e2c88a/rignore-0.7.6-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d7e4bb66c13cd7602dc8931822c02dfbbd5252015c750ac5d6152b186f0a8be0", size = 941945 }, - { url = "https://files.pythonhosted.org/packages/48/6f/2f178af1c1a276a065f563ec1e11e7a9e23d4996fd0465516afce4b5c636/rignore-0.7.6-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:297e500c15766e196f68aaaa70e8b6db85fa23fdc075b880d8231fdfba738cd7", size = 959067 }, - { url = "https://files.pythonhosted.org/packages/5b/db/423a81c4c1e173877c7f9b5767dcaf1ab50484a94f60a0b2ed78be3fa765/rignore-0.7.6-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:a07084211a8d35e1a5b1d32b9661a5ed20669970b369df0cf77da3adea3405de", size = 984438 }, - { url = "https://files.pythonhosted.org/packages/31/eb/c4f92cc3f2825d501d3c46a244a671eb737fc1bcf7b05a3ecd34abb3e0d7/rignore-0.7.6-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:181eb2a975a22256a1441a9d2f15eb1292839ea3f05606620bd9e1938302cf79", size = 1078365 }, - { url = "https://files.pythonhosted.org/packages/26/09/99442f02794bd7441bfc8ed1c7319e890449b816a7493b2db0e30af39095/rignore-0.7.6-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:7bbcdc52b5bf9f054b34ce4af5269df5d863d9c2456243338bc193c28022bd7b", size = 1139066 }, - { url = "https://files.pythonhosted.org/packages/2c/88/bcfc21e520bba975410e9419450f4b90a2ac8236b9a80fd8130e87d098af/rignore-0.7.6-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:f2e027a6da21a7c8c0d87553c24ca5cc4364def18d146057862c23a96546238e", size = 1118036 }, - { url = "https://files.pythonhosted.org/packages/e2/25/d37215e4562cda5c13312636393aea0bafe38d54d4e0517520a4cc0753ec/rignore-0.7.6-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:ee4a18b82cbbc648e4aac1510066682fe62beb5dc88e2c67c53a83954e541360", size = 1127550 }, - { url = "https://files.pythonhosted.org/packages/dc/76/a264ab38bfa1620ec12a8ff1c07778da89e16d8c0f3450b0333020d3d6dc/rignore-0.7.6-cp313-cp313-win32.whl", hash = "sha256:a7d7148b6e5e95035d4390396895adc384d37ff4e06781a36fe573bba7c283e5", size = 646097 }, - { url = "https://files.pythonhosted.org/packages/62/44/3c31b8983c29ea8832b6082ddb1d07b90379c2d993bd20fce4487b71b4f4/rignore-0.7.6-cp313-cp313-win_amd64.whl", hash = "sha256:b037c4b15a64dced08fc12310ee844ec2284c4c5c1ca77bc37d0a04f7bff386e", size = 726170 }, - { url = "https://files.pythonhosted.org/packages/aa/41/e26a075cab83debe41a42661262f606166157df84e0e02e2d904d134c0d8/rignore-0.7.6-cp313-cp313-win_arm64.whl", hash = "sha256:e47443de9b12fe569889bdbe020abe0e0b667516ee2ab435443f6d0869bd2804", size = 656184 }, - { url = "https://files.pythonhosted.org/packages/9a/b9/1f5bd82b87e5550cd843ceb3768b4a8ef274eb63f29333cf2f29644b3d75/rignore-0.7.6-cp314-cp314-macosx_10_12_x86_64.whl", hash = "sha256:8e41be9fa8f2f47239ded8920cc283699a052ac4c371f77f5ac017ebeed75732", size = 882632 }, - { url = "https://files.pythonhosted.org/packages/e9/6b/07714a3efe4a8048864e8a5b7db311ba51b921e15268b17defaebf56d3db/rignore-0.7.6-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:6dc1e171e52cefa6c20e60c05394a71165663b48bca6c7666dee4f778f2a7d90", size = 820760 }, - { url = "https://files.pythonhosted.org/packages/ac/0f/348c829ea2d8d596e856371b14b9092f8a5dfbb62674ec9b3f67e4939a9d/rignore-0.7.6-cp314-cp314-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0ce2268837c3600f82ab8db58f5834009dc638ee17103582960da668963bebc5", size = 899044 }, - { url = "https://files.pythonhosted.org/packages/f0/30/2e1841a19b4dd23878d73edd5d82e998a83d5ed9570a89675f140ca8b2ad/rignore-0.7.6-cp314-cp314-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:690a3e1b54bfe77e89c4bacb13f046e642f8baadafc61d68f5a726f324a76ab6", size = 874144 }, - { url = "https://files.pythonhosted.org/packages/c2/bf/0ce9beb2e5f64c30e3580bef09f5829236889f01511a125f98b83169b993/rignore-0.7.6-cp314-cp314-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:09d12ac7a0b6210c07bcd145007117ebd8abe99c8eeb383e9e4673910c2754b2", size = 1168062 }, - { url = "https://files.pythonhosted.org/packages/b9/8b/571c178414eb4014969865317da8a02ce4cf5241a41676ef91a59aab24de/rignore-0.7.6-cp314-cp314-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2a2b2b74a8c60203b08452479b90e5ce3dbe96a916214bc9eb2e5af0b6a9beb0", size = 942542 }, - { url = "https://files.pythonhosted.org/packages/19/62/7a3cf601d5a45137a7e2b89d10c05b5b86499190c4b7ca5c3c47d79ee519/rignore-0.7.6-cp314-cp314-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8fc5a531ef02131e44359419a366bfac57f773ea58f5278c2cdd915f7d10ea94", size = 958739 }, - { url = "https://files.pythonhosted.org/packages/5f/1f/4261f6a0d7caf2058a5cde2f5045f565ab91aa7badc972b57d19ce58b14e/rignore-0.7.6-cp314-cp314-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:b7a1f77d9c4cd7e76229e252614d963442686bfe12c787a49f4fe481df49e7a9", size = 984138 }, - { url = "https://files.pythonhosted.org/packages/2b/bf/628dfe19c75e8ce1f45f7c248f5148b17dfa89a817f8e3552ab74c3ae812/rignore-0.7.6-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:ead81f728682ba72b5b1c3d5846b011d3e0174da978de87c61645f2ed36659a7", size = 1079299 }, - { url = "https://files.pythonhosted.org/packages/af/a5/be29c50f5c0c25c637ed32db8758fdf5b901a99e08b608971cda8afb293b/rignore-0.7.6-cp314-cp314-musllinux_1_2_armv7l.whl", hash = "sha256:12ffd50f520c22ffdabed8cd8bfb567d9ac165b2b854d3e679f4bcaef11a9441", size = 1139618 }, - { url = "https://files.pythonhosted.org/packages/2a/40/3c46cd7ce4fa05c20b525fd60f599165e820af66e66f2c371cd50644558f/rignore-0.7.6-cp314-cp314-musllinux_1_2_i686.whl", hash = "sha256:e5a16890fbe3c894f8ca34b0fcacc2c200398d4d46ae654e03bc9b3dbf2a0a72", size = 1117626 }, - { url = "https://files.pythonhosted.org/packages/8c/b9/aea926f263b8a29a23c75c2e0d8447965eb1879d3feb53cfcf84db67ed58/rignore-0.7.6-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:3abab3bf99e8a77488ef6c7c9a799fac22224c28fe9f25cc21aa7cc2b72bfc0b", size = 1128144 }, - { url = "https://files.pythonhosted.org/packages/a4/f6/0d6242f8d0df7f2ecbe91679fefc1f75e7cd2072cb4f497abaab3f0f8523/rignore-0.7.6-cp314-cp314-win32.whl", hash = "sha256:eeef421c1782953c4375aa32f06ecae470c1285c6381eee2a30d2e02a5633001", size = 646385 }, - { url = "https://files.pythonhosted.org/packages/d5/38/c0dcd7b10064f084343d6af26fe9414e46e9619c5f3224b5272e8e5d9956/rignore-0.7.6-cp314-cp314-win_amd64.whl", hash = "sha256:6aeed503b3b3d5af939b21d72a82521701a4bd3b89cd761da1e7dc78621af304", size = 725738 }, - { url = "https://files.pythonhosted.org/packages/d9/7a/290f868296c1ece914d565757ab363b04730a728b544beb567ceb3b2d96f/rignore-0.7.6-cp314-cp314-win_arm64.whl", hash = "sha256:104f215b60b3c984c386c3e747d6ab4376d5656478694e22c7bd2f788ddd8304", size = 656008 }, - { url = "https://files.pythonhosted.org/packages/ca/d2/3c74e3cd81fe8ea08a8dcd2d755c09ac2e8ad8fe409508904557b58383d3/rignore-0.7.6-cp314-cp314t-macosx_10_12_x86_64.whl", hash = "sha256:bb24a5b947656dd94cb9e41c4bc8b23cec0c435b58be0d74a874f63c259549e8", size = 882835 }, - { url = "https://files.pythonhosted.org/packages/77/61/a772a34b6b63154877433ac2d048364815b24c2dd308f76b212c408101a2/rignore-0.7.6-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:5b1e33c9501cefe24b70a1eafd9821acfd0ebf0b35c3a379430a14df089993e3", size = 820301 }, - { url = "https://files.pythonhosted.org/packages/71/30/054880b09c0b1b61d17eeb15279d8bf729c0ba52b36c3ada52fb827cbb3c/rignore-0.7.6-cp314-cp314t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bec3994665a44454df86deb762061e05cd4b61e3772f5b07d1882a8a0d2748d5", size = 897611 }, - { url = "https://files.pythonhosted.org/packages/1e/40/b2d1c169f833d69931bf232600eaa3c7998ba4f9a402e43a822dad2ea9f2/rignore-0.7.6-cp314-cp314t-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:26cba2edfe3cff1dfa72bddf65d316ddebf182f011f2f61538705d6dbaf54986", size = 873875 }, - { url = "https://files.pythonhosted.org/packages/55/59/ca5ae93d83a1a60e44b21d87deb48b177a8db1b85e82fc8a9abb24a8986d/rignore-0.7.6-cp314-cp314t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ffa86694fec604c613696cb91e43892aa22e1fec5f9870e48f111c603e5ec4e9", size = 1167245 }, - { url = "https://files.pythonhosted.org/packages/a5/52/cf3dce392ba2af806cba265aad6bcd9c48bb2a6cb5eee448d3319f6e505b/rignore-0.7.6-cp314-cp314t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:48efe2ed95aa8104145004afb15cdfa02bea5cdde8b0344afeb0434f0d989aa2", size = 941750 }, - { url = "https://files.pythonhosted.org/packages/ec/be/3f344c6218d779395e785091d05396dfd8b625f6aafbe502746fcd880af2/rignore-0.7.6-cp314-cp314t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8dcae43eb44b7f2457fef7cc87f103f9a0013017a6f4e62182c565e924948f21", size = 958896 }, - { url = "https://files.pythonhosted.org/packages/c9/34/d3fa71938aed7d00dcad87f0f9bcb02ad66c85d6ffc83ba31078ce53646a/rignore-0.7.6-cp314-cp314t-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:2cd649a7091c0dad2f11ef65630d30c698d505cbe8660dd395268e7c099cc99f", size = 983992 }, - { url = "https://files.pythonhosted.org/packages/24/a4/52a697158e9920705bdbd0748d59fa63e0f3233fb92e9df9a71afbead6ca/rignore-0.7.6-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:42de84b0289d478d30ceb7ae59023f7b0527786a9a5b490830e080f0e4ea5aeb", size = 1078181 }, - { url = "https://files.pythonhosted.org/packages/ac/65/aa76dbcdabf3787a6f0fd61b5cc8ed1e88580590556d6c0207960d2384bb/rignore-0.7.6-cp314-cp314t-musllinux_1_2_armv7l.whl", hash = "sha256:875a617e57b53b4acbc5a91de418233849711c02e29cc1f4f9febb2f928af013", size = 1139232 }, - { url = "https://files.pythonhosted.org/packages/08/44/31b31a49b3233c6842acc1c0731aa1e7fb322a7170612acf30327f700b44/rignore-0.7.6-cp314-cp314t-musllinux_1_2_i686.whl", hash = "sha256:8703998902771e96e49968105207719f22926e4431b108450f3f430b4e268b7c", size = 1117349 }, - { url = "https://files.pythonhosted.org/packages/e9/ae/1b199a2302c19c658cf74e5ee1427605234e8c91787cfba0015f2ace145b/rignore-0.7.6-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:602ef33f3e1b04c1e9a10a3c03f8bc3cef2d2383dcc250d309be42b49923cabc", size = 1127702 }, - { url = "https://files.pythonhosted.org/packages/fc/d3/18210222b37e87e36357f7b300b7d98c6dd62b133771e71ae27acba83a4f/rignore-0.7.6-cp314-cp314t-win32.whl", hash = "sha256:c1d8f117f7da0a4a96a8daef3da75bc090e3792d30b8b12cfadc240c631353f9", size = 647033 }, - { url = "https://files.pythonhosted.org/packages/3e/87/033eebfbee3ec7d92b3bb1717d8f68c88e6fc7de54537040f3b3a405726f/rignore-0.7.6-cp314-cp314t-win_amd64.whl", hash = "sha256:ca36e59408bec81de75d307c568c2d0d410fb880b1769be43611472c61e85c96", size = 725647 }, - { url = "https://files.pythonhosted.org/packages/79/62/b88e5879512c55b8ee979c666ee6902adc4ed05007226de266410ae27965/rignore-0.7.6-cp314-cp314t-win_arm64.whl", hash = "sha256:b83adabeb3e8cf662cabe1931b83e165b88c526fa6af6b3aa90429686e474896", size = 656035 }, +sdist = { url = "https://files.pythonhosted.org/packages/e5/f5/8bed2310abe4ae04b67a38374a4d311dd85220f5d8da56f47ae9361be0b0/rignore-0.7.6.tar.gz", hash = "sha256:00d3546cd793c30cb17921ce674d2c8f3a4b00501cb0e3dd0e82217dbeba2671", size = 57140, upload-time = "2025-11-05T21:41:21.968Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/b7/8a/a4078f6e14932ac7edb171149c481de29969d96ddee3ece5dc4c26f9e0c3/rignore-0.7.6-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:2bdab1d31ec9b4fb1331980ee49ea051c0d7f7bb6baa28b3125ef03cdc48fdaf", size = 883057, upload-time = "2025-11-05T20:42:42.741Z" }, + { url = "https://files.pythonhosted.org/packages/f9/8f/f8daacd177db4bf7c2223bab41e630c52711f8af9ed279be2058d2fe4982/rignore-0.7.6-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:90f0a00ce0c866c275bf888271f1dc0d2140f29b82fcf33cdbda1e1a6af01010", size = 820150, upload-time = "2025-11-05T20:42:26.545Z" }, + { url = "https://files.pythonhosted.org/packages/36/31/b65b837e39c3f7064c426754714ac633b66b8c2290978af9d7f513e14aa9/rignore-0.7.6-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c1ad295537041dc2ed4b540fb1a3906bd9ede6ccdad3fe79770cd89e04e3c73c", size = 897406, upload-time = "2025-11-05T20:40:53.854Z" }, + { url = "https://files.pythonhosted.org/packages/ca/58/1970ce006c427e202ac7c081435719a076c478f07b3a23f469227788dc23/rignore-0.7.6-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:f782dbd3a65a5ac85adfff69e5c6b101285ef3f845c3a3cae56a54bebf9fe116", size = 874050, upload-time = "2025-11-05T20:41:08.922Z" }, + { url = "https://files.pythonhosted.org/packages/d4/00/eb45db9f90137329072a732273be0d383cb7d7f50ddc8e0bceea34c1dfdf/rignore-0.7.6-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:65cece3b36e5b0826d946494734c0e6aaf5a0337e18ff55b071438efe13d559e", size = 1167835, upload-time = "2025-11-05T20:41:24.997Z" }, + { url = "https://files.pythonhosted.org/packages/f3/f1/6f1d72ddca41a64eed569680587a1236633587cc9f78136477ae69e2c88a/rignore-0.7.6-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d7e4bb66c13cd7602dc8931822c02dfbbd5252015c750ac5d6152b186f0a8be0", size = 941945, upload-time = "2025-11-05T20:41:40.628Z" }, + { url = "https://files.pythonhosted.org/packages/48/6f/2f178af1c1a276a065f563ec1e11e7a9e23d4996fd0465516afce4b5c636/rignore-0.7.6-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:297e500c15766e196f68aaaa70e8b6db85fa23fdc075b880d8231fdfba738cd7", size = 959067, upload-time = "2025-11-05T20:42:11.09Z" }, + { url = "https://files.pythonhosted.org/packages/5b/db/423a81c4c1e173877c7f9b5767dcaf1ab50484a94f60a0b2ed78be3fa765/rignore-0.7.6-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:a07084211a8d35e1a5b1d32b9661a5ed20669970b369df0cf77da3adea3405de", size = 984438, upload-time = "2025-11-05T20:41:55.443Z" }, + { url = "https://files.pythonhosted.org/packages/31/eb/c4f92cc3f2825d501d3c46a244a671eb737fc1bcf7b05a3ecd34abb3e0d7/rignore-0.7.6-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:181eb2a975a22256a1441a9d2f15eb1292839ea3f05606620bd9e1938302cf79", size = 1078365, upload-time = "2025-11-05T21:40:15.148Z" }, + { url = "https://files.pythonhosted.org/packages/26/09/99442f02794bd7441bfc8ed1c7319e890449b816a7493b2db0e30af39095/rignore-0.7.6-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:7bbcdc52b5bf9f054b34ce4af5269df5d863d9c2456243338bc193c28022bd7b", size = 1139066, upload-time = "2025-11-05T21:40:32.771Z" }, + { url = "https://files.pythonhosted.org/packages/2c/88/bcfc21e520bba975410e9419450f4b90a2ac8236b9a80fd8130e87d098af/rignore-0.7.6-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:f2e027a6da21a7c8c0d87553c24ca5cc4364def18d146057862c23a96546238e", size = 1118036, upload-time = "2025-11-05T21:40:49.646Z" }, + { url = "https://files.pythonhosted.org/packages/e2/25/d37215e4562cda5c13312636393aea0bafe38d54d4e0517520a4cc0753ec/rignore-0.7.6-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:ee4a18b82cbbc648e4aac1510066682fe62beb5dc88e2c67c53a83954e541360", size = 1127550, upload-time = "2025-11-05T21:41:07.648Z" }, + { url = "https://files.pythonhosted.org/packages/dc/76/a264ab38bfa1620ec12a8ff1c07778da89e16d8c0f3450b0333020d3d6dc/rignore-0.7.6-cp313-cp313-win32.whl", hash = "sha256:a7d7148b6e5e95035d4390396895adc384d37ff4e06781a36fe573bba7c283e5", size = 646097, upload-time = "2025-11-05T21:41:53.201Z" }, + { url = "https://files.pythonhosted.org/packages/62/44/3c31b8983c29ea8832b6082ddb1d07b90379c2d993bd20fce4487b71b4f4/rignore-0.7.6-cp313-cp313-win_amd64.whl", hash = "sha256:b037c4b15a64dced08fc12310ee844ec2284c4c5c1ca77bc37d0a04f7bff386e", size = 726170, upload-time = "2025-11-05T21:41:38.131Z" }, + { url = "https://files.pythonhosted.org/packages/aa/41/e26a075cab83debe41a42661262f606166157df84e0e02e2d904d134c0d8/rignore-0.7.6-cp313-cp313-win_arm64.whl", hash = "sha256:e47443de9b12fe569889bdbe020abe0e0b667516ee2ab435443f6d0869bd2804", size = 656184, upload-time = "2025-11-05T21:41:27.396Z" }, + { url = "https://files.pythonhosted.org/packages/9a/b9/1f5bd82b87e5550cd843ceb3768b4a8ef274eb63f29333cf2f29644b3d75/rignore-0.7.6-cp314-cp314-macosx_10_12_x86_64.whl", hash = "sha256:8e41be9fa8f2f47239ded8920cc283699a052ac4c371f77f5ac017ebeed75732", size = 882632, upload-time = "2025-11-05T20:42:44.063Z" }, + { url = "https://files.pythonhosted.org/packages/e9/6b/07714a3efe4a8048864e8a5b7db311ba51b921e15268b17defaebf56d3db/rignore-0.7.6-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:6dc1e171e52cefa6c20e60c05394a71165663b48bca6c7666dee4f778f2a7d90", size = 820760, upload-time = "2025-11-05T20:42:27.885Z" }, + { url = "https://files.pythonhosted.org/packages/ac/0f/348c829ea2d8d596e856371b14b9092f8a5dfbb62674ec9b3f67e4939a9d/rignore-0.7.6-cp314-cp314-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0ce2268837c3600f82ab8db58f5834009dc638ee17103582960da668963bebc5", size = 899044, upload-time = "2025-11-05T20:40:55.336Z" }, + { url = "https://files.pythonhosted.org/packages/f0/30/2e1841a19b4dd23878d73edd5d82e998a83d5ed9570a89675f140ca8b2ad/rignore-0.7.6-cp314-cp314-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:690a3e1b54bfe77e89c4bacb13f046e642f8baadafc61d68f5a726f324a76ab6", size = 874144, upload-time = "2025-11-05T20:41:10.195Z" }, + { url = "https://files.pythonhosted.org/packages/c2/bf/0ce9beb2e5f64c30e3580bef09f5829236889f01511a125f98b83169b993/rignore-0.7.6-cp314-cp314-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:09d12ac7a0b6210c07bcd145007117ebd8abe99c8eeb383e9e4673910c2754b2", size = 1168062, upload-time = "2025-11-05T20:41:26.511Z" }, + { url = "https://files.pythonhosted.org/packages/b9/8b/571c178414eb4014969865317da8a02ce4cf5241a41676ef91a59aab24de/rignore-0.7.6-cp314-cp314-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2a2b2b74a8c60203b08452479b90e5ce3dbe96a916214bc9eb2e5af0b6a9beb0", size = 942542, upload-time = "2025-11-05T20:41:41.838Z" }, + { url = "https://files.pythonhosted.org/packages/19/62/7a3cf601d5a45137a7e2b89d10c05b5b86499190c4b7ca5c3c47d79ee519/rignore-0.7.6-cp314-cp314-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8fc5a531ef02131e44359419a366bfac57f773ea58f5278c2cdd915f7d10ea94", size = 958739, upload-time = "2025-11-05T20:42:12.463Z" }, + { url = "https://files.pythonhosted.org/packages/5f/1f/4261f6a0d7caf2058a5cde2f5045f565ab91aa7badc972b57d19ce58b14e/rignore-0.7.6-cp314-cp314-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:b7a1f77d9c4cd7e76229e252614d963442686bfe12c787a49f4fe481df49e7a9", size = 984138, upload-time = "2025-11-05T20:41:56.775Z" }, + { url = "https://files.pythonhosted.org/packages/2b/bf/628dfe19c75e8ce1f45f7c248f5148b17dfa89a817f8e3552ab74c3ae812/rignore-0.7.6-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:ead81f728682ba72b5b1c3d5846b011d3e0174da978de87c61645f2ed36659a7", size = 1079299, upload-time = "2025-11-05T21:40:16.639Z" }, + { url = "https://files.pythonhosted.org/packages/af/a5/be29c50f5c0c25c637ed32db8758fdf5b901a99e08b608971cda8afb293b/rignore-0.7.6-cp314-cp314-musllinux_1_2_armv7l.whl", hash = "sha256:12ffd50f520c22ffdabed8cd8bfb567d9ac165b2b854d3e679f4bcaef11a9441", size = 1139618, upload-time = "2025-11-05T21:40:34.507Z" }, + { url = "https://files.pythonhosted.org/packages/2a/40/3c46cd7ce4fa05c20b525fd60f599165e820af66e66f2c371cd50644558f/rignore-0.7.6-cp314-cp314-musllinux_1_2_i686.whl", hash = "sha256:e5a16890fbe3c894f8ca34b0fcacc2c200398d4d46ae654e03bc9b3dbf2a0a72", size = 1117626, upload-time = "2025-11-05T21:40:51.494Z" }, + { url = "https://files.pythonhosted.org/packages/8c/b9/aea926f263b8a29a23c75c2e0d8447965eb1879d3feb53cfcf84db67ed58/rignore-0.7.6-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:3abab3bf99e8a77488ef6c7c9a799fac22224c28fe9f25cc21aa7cc2b72bfc0b", size = 1128144, upload-time = "2025-11-05T21:41:09.169Z" }, + { url = "https://files.pythonhosted.org/packages/a4/f6/0d6242f8d0df7f2ecbe91679fefc1f75e7cd2072cb4f497abaab3f0f8523/rignore-0.7.6-cp314-cp314-win32.whl", hash = "sha256:eeef421c1782953c4375aa32f06ecae470c1285c6381eee2a30d2e02a5633001", size = 646385, upload-time = "2025-11-05T21:41:55.105Z" }, + { url = "https://files.pythonhosted.org/packages/d5/38/c0dcd7b10064f084343d6af26fe9414e46e9619c5f3224b5272e8e5d9956/rignore-0.7.6-cp314-cp314-win_amd64.whl", hash = "sha256:6aeed503b3b3d5af939b21d72a82521701a4bd3b89cd761da1e7dc78621af304", size = 725738, upload-time = "2025-11-05T21:41:39.736Z" }, + { url = "https://files.pythonhosted.org/packages/d9/7a/290f868296c1ece914d565757ab363b04730a728b544beb567ceb3b2d96f/rignore-0.7.6-cp314-cp314-win_arm64.whl", hash = "sha256:104f215b60b3c984c386c3e747d6ab4376d5656478694e22c7bd2f788ddd8304", size = 656008, upload-time = "2025-11-05T21:41:29.028Z" }, + { url = "https://files.pythonhosted.org/packages/ca/d2/3c74e3cd81fe8ea08a8dcd2d755c09ac2e8ad8fe409508904557b58383d3/rignore-0.7.6-cp314-cp314t-macosx_10_12_x86_64.whl", hash = "sha256:bb24a5b947656dd94cb9e41c4bc8b23cec0c435b58be0d74a874f63c259549e8", size = 882835, upload-time = "2025-11-05T20:42:45.443Z" }, + { url = "https://files.pythonhosted.org/packages/77/61/a772a34b6b63154877433ac2d048364815b24c2dd308f76b212c408101a2/rignore-0.7.6-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:5b1e33c9501cefe24b70a1eafd9821acfd0ebf0b35c3a379430a14df089993e3", size = 820301, upload-time = "2025-11-05T20:42:29.226Z" }, + { url = "https://files.pythonhosted.org/packages/71/30/054880b09c0b1b61d17eeb15279d8bf729c0ba52b36c3ada52fb827cbb3c/rignore-0.7.6-cp314-cp314t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bec3994665a44454df86deb762061e05cd4b61e3772f5b07d1882a8a0d2748d5", size = 897611, upload-time = "2025-11-05T20:40:56.475Z" }, + { url = "https://files.pythonhosted.org/packages/1e/40/b2d1c169f833d69931bf232600eaa3c7998ba4f9a402e43a822dad2ea9f2/rignore-0.7.6-cp314-cp314t-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:26cba2edfe3cff1dfa72bddf65d316ddebf182f011f2f61538705d6dbaf54986", size = 873875, upload-time = "2025-11-05T20:41:11.561Z" }, + { url = "https://files.pythonhosted.org/packages/55/59/ca5ae93d83a1a60e44b21d87deb48b177a8db1b85e82fc8a9abb24a8986d/rignore-0.7.6-cp314-cp314t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ffa86694fec604c613696cb91e43892aa22e1fec5f9870e48f111c603e5ec4e9", size = 1167245, upload-time = "2025-11-05T20:41:28.29Z" }, + { url = "https://files.pythonhosted.org/packages/a5/52/cf3dce392ba2af806cba265aad6bcd9c48bb2a6cb5eee448d3319f6e505b/rignore-0.7.6-cp314-cp314t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:48efe2ed95aa8104145004afb15cdfa02bea5cdde8b0344afeb0434f0d989aa2", size = 941750, upload-time = "2025-11-05T20:41:43.111Z" }, + { url = "https://files.pythonhosted.org/packages/ec/be/3f344c6218d779395e785091d05396dfd8b625f6aafbe502746fcd880af2/rignore-0.7.6-cp314-cp314t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8dcae43eb44b7f2457fef7cc87f103f9a0013017a6f4e62182c565e924948f21", size = 958896, upload-time = "2025-11-05T20:42:13.784Z" }, + { url = "https://files.pythonhosted.org/packages/c9/34/d3fa71938aed7d00dcad87f0f9bcb02ad66c85d6ffc83ba31078ce53646a/rignore-0.7.6-cp314-cp314t-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:2cd649a7091c0dad2f11ef65630d30c698d505cbe8660dd395268e7c099cc99f", size = 983992, upload-time = "2025-11-05T20:41:58.022Z" }, + { url = "https://files.pythonhosted.org/packages/24/a4/52a697158e9920705bdbd0748d59fa63e0f3233fb92e9df9a71afbead6ca/rignore-0.7.6-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:42de84b0289d478d30ceb7ae59023f7b0527786a9a5b490830e080f0e4ea5aeb", size = 1078181, upload-time = "2025-11-05T21:40:18.151Z" }, + { url = "https://files.pythonhosted.org/packages/ac/65/aa76dbcdabf3787a6f0fd61b5cc8ed1e88580590556d6c0207960d2384bb/rignore-0.7.6-cp314-cp314t-musllinux_1_2_armv7l.whl", hash = "sha256:875a617e57b53b4acbc5a91de418233849711c02e29cc1f4f9febb2f928af013", size = 1139232, upload-time = "2025-11-05T21:40:35.966Z" }, + { url = "https://files.pythonhosted.org/packages/08/44/31b31a49b3233c6842acc1c0731aa1e7fb322a7170612acf30327f700b44/rignore-0.7.6-cp314-cp314t-musllinux_1_2_i686.whl", hash = "sha256:8703998902771e96e49968105207719f22926e4431b108450f3f430b4e268b7c", size = 1117349, upload-time = "2025-11-05T21:40:53.013Z" }, + { url = "https://files.pythonhosted.org/packages/e9/ae/1b199a2302c19c658cf74e5ee1427605234e8c91787cfba0015f2ace145b/rignore-0.7.6-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:602ef33f3e1b04c1e9a10a3c03f8bc3cef2d2383dcc250d309be42b49923cabc", size = 1127702, upload-time = "2025-11-05T21:41:10.881Z" }, + { url = "https://files.pythonhosted.org/packages/fc/d3/18210222b37e87e36357f7b300b7d98c6dd62b133771e71ae27acba83a4f/rignore-0.7.6-cp314-cp314t-win32.whl", hash = "sha256:c1d8f117f7da0a4a96a8daef3da75bc090e3792d30b8b12cfadc240c631353f9", size = 647033, upload-time = "2025-11-05T21:42:00.095Z" }, + { url = "https://files.pythonhosted.org/packages/3e/87/033eebfbee3ec7d92b3bb1717d8f68c88e6fc7de54537040f3b3a405726f/rignore-0.7.6-cp314-cp314t-win_amd64.whl", hash = "sha256:ca36e59408bec81de75d307c568c2d0d410fb880b1769be43611472c61e85c96", size = 725647, upload-time = "2025-11-05T21:41:44.449Z" }, + { url = "https://files.pythonhosted.org/packages/79/62/b88e5879512c55b8ee979c666ee6902adc4ed05007226de266410ae27965/rignore-0.7.6-cp314-cp314t-win_arm64.whl", hash = "sha256:b83adabeb3e8cf662cabe1931b83e165b88c526fa6af6b3aa90429686e474896", size = 656035, upload-time = "2025-11-05T21:41:31.13Z" }, ] [[package]] @@ -2039,35 +2064,35 @@ source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "pyasn1" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/da/8a/22b7beea3ee0d44b1916c0c1cb0ee3af23b700b6da9f04991899d0c555d4/rsa-4.9.1.tar.gz", hash = "sha256:e7bdbfdb5497da4c07dfd35530e1a902659db6ff241e39d9953cad06ebd0ae75", size = 29034 } +sdist = { url = "https://files.pythonhosted.org/packages/da/8a/22b7beea3ee0d44b1916c0c1cb0ee3af23b700b6da9f04991899d0c555d4/rsa-4.9.1.tar.gz", hash = "sha256:e7bdbfdb5497da4c07dfd35530e1a902659db6ff241e39d9953cad06ebd0ae75", size = 29034, upload-time = "2025-04-16T09:51:18.218Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/64/8d/0133e4eb4beed9e425d9a98ed6e081a55d195481b7632472be1af08d2f6b/rsa-4.9.1-py3-none-any.whl", hash = "sha256:68635866661c6836b8d39430f97a996acbd61bfa49406748ea243539fe239762", size = 34696 }, + { url = "https://files.pythonhosted.org/packages/64/8d/0133e4eb4beed9e425d9a98ed6e081a55d195481b7632472be1af08d2f6b/rsa-4.9.1-py3-none-any.whl", hash = "sha256:68635866661c6836b8d39430f97a996acbd61bfa49406748ea243539fe239762", size = 34696, upload-time = "2025-04-16T09:51:17.142Z" }, ] [[package]] name = "ruff" version = "0.14.4" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/df/55/cccfca45157a2031dcbb5a462a67f7cf27f8b37d4b3b1cd7438f0f5c1df6/ruff-0.14.4.tar.gz", hash = "sha256:f459a49fe1085a749f15414ca76f61595f1a2cc8778ed7c279b6ca2e1fd19df3", size = 5587844 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/17/b9/67240254166ae1eaa38dec32265e9153ac53645a6c6670ed36ad00722af8/ruff-0.14.4-py3-none-linux_armv6l.whl", hash = "sha256:e6604613ffbcf2297cd5dcba0e0ac9bd0c11dc026442dfbb614504e87c349518", size = 12606781 }, - { url = "https://files.pythonhosted.org/packages/46/c8/09b3ab245d8652eafe5256ab59718641429f68681ee713ff06c5c549f156/ruff-0.14.4-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:d99c0b52b6f0598acede45ee78288e5e9b4409d1ce7f661f0fa36d4cbeadf9a4", size = 12946765 }, - { url = "https://files.pythonhosted.org/packages/14/bb/1564b000219144bf5eed2359edc94c3590dd49d510751dad26202c18a17d/ruff-0.14.4-py3-none-macosx_11_0_arm64.whl", hash = "sha256:9358d490ec030f1b51d048a7fd6ead418ed0826daf6149e95e30aa67c168af33", size = 11928120 }, - { url = "https://files.pythonhosted.org/packages/a3/92/d5f1770e9988cc0742fefaa351e840d9aef04ec24ae1be36f333f96d5704/ruff-0.14.4-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:81b40d27924f1f02dfa827b9c0712a13c0e4b108421665322218fc38caf615c2", size = 12370877 }, - { url = "https://files.pythonhosted.org/packages/e2/29/e9282efa55f1973d109faf839a63235575519c8ad278cc87a182a366810e/ruff-0.14.4-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:f5e649052a294fe00818650712083cddc6cc02744afaf37202c65df9ea52efa5", size = 12408538 }, - { url = "https://files.pythonhosted.org/packages/8e/01/930ed6ecfce130144b32d77d8d69f5c610e6d23e6857927150adf5d7379a/ruff-0.14.4-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:aa082a8f878deeba955531f975881828fd6afd90dfa757c2b0808aadb437136e", size = 13141942 }, - { url = "https://files.pythonhosted.org/packages/6a/46/a9c89b42b231a9f487233f17a89cbef9d5acd538d9488687a02ad288fa6b/ruff-0.14.4-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:1043c6811c2419e39011890f14d0a30470f19d47d197c4858b2787dfa698f6c8", size = 14544306 }, - { url = "https://files.pythonhosted.org/packages/78/96/9c6cf86491f2a6d52758b830b89b78c2ae61e8ca66b86bf5a20af73d20e6/ruff-0.14.4-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a9f3a936ac27fb7c2a93e4f4b943a662775879ac579a433291a6f69428722649", size = 14210427 }, - { url = "https://files.pythonhosted.org/packages/71/f4/0666fe7769a54f63e66404e8ff698de1dcde733e12e2fd1c9c6efb689cb5/ruff-0.14.4-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:95643ffd209ce78bc113266b88fba3d39e0461f0cbc8b55fb92505030fb4a850", size = 13658488 }, - { url = "https://files.pythonhosted.org/packages/ee/79/6ad4dda2cfd55e41ac9ed6d73ef9ab9475b1eef69f3a85957210c74ba12c/ruff-0.14.4-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:456daa2fa1021bc86ca857f43fe29d5d8b3f0e55e9f90c58c317c1dcc2afc7b5", size = 13354908 }, - { url = "https://files.pythonhosted.org/packages/b5/60/f0b6990f740bb15c1588601d19d21bcc1bd5de4330a07222041678a8e04f/ruff-0.14.4-py3-none-manylinux_2_31_riscv64.whl", hash = "sha256:f911bba769e4a9f51af6e70037bb72b70b45a16db5ce73e1f72aefe6f6d62132", size = 13587803 }, - { url = "https://files.pythonhosted.org/packages/c9/da/eaaada586f80068728338e0ef7f29ab3e4a08a692f92eb901a4f06bbff24/ruff-0.14.4-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:76158a7369b3979fa878612c623a7e5430c18b2fd1c73b214945c2d06337db67", size = 12279654 }, - { url = "https://files.pythonhosted.org/packages/66/d4/b1d0e82cf9bf8aed10a6d45be47b3f402730aa2c438164424783ac88c0ed/ruff-0.14.4-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:f3b8f3b442d2b14c246e7aeca2e75915159e06a3540e2f4bed9f50d062d24469", size = 12357520 }, - { url = "https://files.pythonhosted.org/packages/04/f4/53e2b42cc82804617e5c7950b7079d79996c27e99c4652131c6a1100657f/ruff-0.14.4-py3-none-musllinux_1_2_i686.whl", hash = "sha256:c62da9a06779deecf4d17ed04939ae8b31b517643b26370c3be1d26f3ef7dbde", size = 12719431 }, - { url = "https://files.pythonhosted.org/packages/a2/94/80e3d74ed9a72d64e94a7b7706b1c1ebaa315ef2076fd33581f6a1cd2f95/ruff-0.14.4-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:5a443a83a1506c684e98acb8cb55abaf3ef725078be40237463dae4463366349", size = 13464394 }, - { url = "https://files.pythonhosted.org/packages/54/1a/a49f071f04c42345c793d22f6cf5e0920095e286119ee53a64a3a3004825/ruff-0.14.4-py3-none-win32.whl", hash = "sha256:643b69cb63cd996f1fc7229da726d07ac307eae442dd8974dbc7cf22c1e18fff", size = 12493429 }, - { url = "https://files.pythonhosted.org/packages/bc/22/e58c43e641145a2b670328fb98bc384e20679b5774258b1e540207580266/ruff-0.14.4-py3-none-win_amd64.whl", hash = "sha256:26673da283b96fe35fa0c939bf8411abec47111644aa9f7cfbd3c573fb125d2c", size = 13635380 }, - { url = "https://files.pythonhosted.org/packages/30/bd/4168a751ddbbf43e86544b4de8b5c3b7be8d7167a2a5cb977d274e04f0a1/ruff-0.14.4-py3-none-win_arm64.whl", hash = "sha256:dd09c292479596b0e6fec8cd95c65c3a6dc68e9ad17b8f2382130f87ff6a75bb", size = 12663065 }, +sdist = { url = "https://files.pythonhosted.org/packages/df/55/cccfca45157a2031dcbb5a462a67f7cf27f8b37d4b3b1cd7438f0f5c1df6/ruff-0.14.4.tar.gz", hash = "sha256:f459a49fe1085a749f15414ca76f61595f1a2cc8778ed7c279b6ca2e1fd19df3", size = 5587844, upload-time = "2025-11-06T22:07:45.033Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/17/b9/67240254166ae1eaa38dec32265e9153ac53645a6c6670ed36ad00722af8/ruff-0.14.4-py3-none-linux_armv6l.whl", hash = "sha256:e6604613ffbcf2297cd5dcba0e0ac9bd0c11dc026442dfbb614504e87c349518", size = 12606781, upload-time = "2025-11-06T22:07:01.841Z" }, + { url = "https://files.pythonhosted.org/packages/46/c8/09b3ab245d8652eafe5256ab59718641429f68681ee713ff06c5c549f156/ruff-0.14.4-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:d99c0b52b6f0598acede45ee78288e5e9b4409d1ce7f661f0fa36d4cbeadf9a4", size = 12946765, upload-time = "2025-11-06T22:07:05.858Z" }, + { url = "https://files.pythonhosted.org/packages/14/bb/1564b000219144bf5eed2359edc94c3590dd49d510751dad26202c18a17d/ruff-0.14.4-py3-none-macosx_11_0_arm64.whl", hash = "sha256:9358d490ec030f1b51d048a7fd6ead418ed0826daf6149e95e30aa67c168af33", size = 11928120, upload-time = "2025-11-06T22:07:08.023Z" }, + { url = "https://files.pythonhosted.org/packages/a3/92/d5f1770e9988cc0742fefaa351e840d9aef04ec24ae1be36f333f96d5704/ruff-0.14.4-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:81b40d27924f1f02dfa827b9c0712a13c0e4b108421665322218fc38caf615c2", size = 12370877, upload-time = "2025-11-06T22:07:10.015Z" }, + { url = "https://files.pythonhosted.org/packages/e2/29/e9282efa55f1973d109faf839a63235575519c8ad278cc87a182a366810e/ruff-0.14.4-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:f5e649052a294fe00818650712083cddc6cc02744afaf37202c65df9ea52efa5", size = 12408538, upload-time = "2025-11-06T22:07:13.085Z" }, + { url = "https://files.pythonhosted.org/packages/8e/01/930ed6ecfce130144b32d77d8d69f5c610e6d23e6857927150adf5d7379a/ruff-0.14.4-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:aa082a8f878deeba955531f975881828fd6afd90dfa757c2b0808aadb437136e", size = 13141942, upload-time = "2025-11-06T22:07:15.386Z" }, + { url = "https://files.pythonhosted.org/packages/6a/46/a9c89b42b231a9f487233f17a89cbef9d5acd538d9488687a02ad288fa6b/ruff-0.14.4-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:1043c6811c2419e39011890f14d0a30470f19d47d197c4858b2787dfa698f6c8", size = 14544306, upload-time = "2025-11-06T22:07:17.631Z" }, + { url = "https://files.pythonhosted.org/packages/78/96/9c6cf86491f2a6d52758b830b89b78c2ae61e8ca66b86bf5a20af73d20e6/ruff-0.14.4-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a9f3a936ac27fb7c2a93e4f4b943a662775879ac579a433291a6f69428722649", size = 14210427, upload-time = "2025-11-06T22:07:19.832Z" }, + { url = "https://files.pythonhosted.org/packages/71/f4/0666fe7769a54f63e66404e8ff698de1dcde733e12e2fd1c9c6efb689cb5/ruff-0.14.4-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:95643ffd209ce78bc113266b88fba3d39e0461f0cbc8b55fb92505030fb4a850", size = 13658488, upload-time = "2025-11-06T22:07:22.32Z" }, + { url = "https://files.pythonhosted.org/packages/ee/79/6ad4dda2cfd55e41ac9ed6d73ef9ab9475b1eef69f3a85957210c74ba12c/ruff-0.14.4-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:456daa2fa1021bc86ca857f43fe29d5d8b3f0e55e9f90c58c317c1dcc2afc7b5", size = 13354908, upload-time = "2025-11-06T22:07:24.347Z" }, + { url = "https://files.pythonhosted.org/packages/b5/60/f0b6990f740bb15c1588601d19d21bcc1bd5de4330a07222041678a8e04f/ruff-0.14.4-py3-none-manylinux_2_31_riscv64.whl", hash = "sha256:f911bba769e4a9f51af6e70037bb72b70b45a16db5ce73e1f72aefe6f6d62132", size = 13587803, upload-time = "2025-11-06T22:07:26.327Z" }, + { url = "https://files.pythonhosted.org/packages/c9/da/eaaada586f80068728338e0ef7f29ab3e4a08a692f92eb901a4f06bbff24/ruff-0.14.4-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:76158a7369b3979fa878612c623a7e5430c18b2fd1c73b214945c2d06337db67", size = 12279654, upload-time = "2025-11-06T22:07:28.46Z" }, + { url = "https://files.pythonhosted.org/packages/66/d4/b1d0e82cf9bf8aed10a6d45be47b3f402730aa2c438164424783ac88c0ed/ruff-0.14.4-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:f3b8f3b442d2b14c246e7aeca2e75915159e06a3540e2f4bed9f50d062d24469", size = 12357520, upload-time = "2025-11-06T22:07:31.468Z" }, + { url = "https://files.pythonhosted.org/packages/04/f4/53e2b42cc82804617e5c7950b7079d79996c27e99c4652131c6a1100657f/ruff-0.14.4-py3-none-musllinux_1_2_i686.whl", hash = "sha256:c62da9a06779deecf4d17ed04939ae8b31b517643b26370c3be1d26f3ef7dbde", size = 12719431, upload-time = "2025-11-06T22:07:33.831Z" }, + { url = "https://files.pythonhosted.org/packages/a2/94/80e3d74ed9a72d64e94a7b7706b1c1ebaa315ef2076fd33581f6a1cd2f95/ruff-0.14.4-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:5a443a83a1506c684e98acb8cb55abaf3ef725078be40237463dae4463366349", size = 13464394, upload-time = "2025-11-06T22:07:35.905Z" }, + { url = "https://files.pythonhosted.org/packages/54/1a/a49f071f04c42345c793d22f6cf5e0920095e286119ee53a64a3a3004825/ruff-0.14.4-py3-none-win32.whl", hash = "sha256:643b69cb63cd996f1fc7229da726d07ac307eae442dd8974dbc7cf22c1e18fff", size = 12493429, upload-time = "2025-11-06T22:07:38.43Z" }, + { url = "https://files.pythonhosted.org/packages/bc/22/e58c43e641145a2b670328fb98bc384e20679b5774258b1e540207580266/ruff-0.14.4-py3-none-win_amd64.whl", hash = "sha256:26673da283b96fe35fa0c939bf8411abec47111644aa9f7cfbd3c573fb125d2c", size = 13635380, upload-time = "2025-11-06T22:07:40.496Z" }, + { url = "https://files.pythonhosted.org/packages/30/bd/4168a751ddbbf43e86544b4de8b5c3b7be8d7167a2a5cb977d274e04f0a1/ruff-0.14.4-py3-none-win_arm64.whl", hash = "sha256:dd09c292479596b0e6fec8cd95c65c3a6dc68e9ad17b8f2382130f87ff6a75bb", size = 12663065, upload-time = "2025-11-06T22:07:42.603Z" }, ] [[package]] @@ -2077,9 +2102,9 @@ source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "botocore" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/62/74/8d69dcb7a9efe8baa2046891735e5dfe433ad558ae23d9e3c14c633d1d58/s3transfer-0.14.0.tar.gz", hash = "sha256:eff12264e7c8b4985074ccce27a3b38a485bb7f7422cc8046fee9be4983e4125", size = 151547 } +sdist = { url = "https://files.pythonhosted.org/packages/62/74/8d69dcb7a9efe8baa2046891735e5dfe433ad558ae23d9e3c14c633d1d58/s3transfer-0.14.0.tar.gz", hash = "sha256:eff12264e7c8b4985074ccce27a3b38a485bb7f7422cc8046fee9be4983e4125", size = 151547, upload-time = "2025-09-09T19:23:31.089Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/48/f0/ae7ca09223a81a1d890b2557186ea015f6e0502e9b8cb8e1813f1d8cfa4e/s3transfer-0.14.0-py3-none-any.whl", hash = "sha256:ea3b790c7077558ed1f02a3072fb3cb992bbbd253392f4b6e9e8976941c7d456", size = 85712 }, + { url = "https://files.pythonhosted.org/packages/48/f0/ae7ca09223a81a1d890b2557186ea015f6e0502e9b8cb8e1813f1d8cfa4e/s3transfer-0.14.0-py3-none-any.whl", hash = "sha256:ea3b790c7077558ed1f02a3072fb3cb992bbbd253392f4b6e9e8976941c7d456", size = 85712, upload-time = "2025-09-09T19:23:30.041Z" }, ] [[package]] @@ -2090,45 +2115,45 @@ dependencies = [ { name = "certifi" }, { name = "urllib3" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/b3/18/09875b4323b03ca9025bae7e6539797b27e4fc032998a466b4b9c3d24653/sentry_sdk-2.43.0.tar.gz", hash = "sha256:52ed6e251c5d2c084224d73efee56b007ef5c2d408a4a071270e82131d336e20", size = 368953 } +sdist = { url = "https://files.pythonhosted.org/packages/b3/18/09875b4323b03ca9025bae7e6539797b27e4fc032998a466b4b9c3d24653/sentry_sdk-2.43.0.tar.gz", hash = "sha256:52ed6e251c5d2c084224d73efee56b007ef5c2d408a4a071270e82131d336e20", size = 368953, upload-time = "2025-10-29T11:26:08.156Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/69/31/8228fa962f7fd8814d634e4ebece8780e2cdcfbdf0cd2e14d4a6861a7cd5/sentry_sdk-2.43.0-py2.py3-none-any.whl", hash = "sha256:4aacafcf1756ef066d359ae35030881917160ba7f6fc3ae11e0e58b09edc2d5d", size = 400997 }, + { url = "https://files.pythonhosted.org/packages/69/31/8228fa962f7fd8814d634e4ebece8780e2cdcfbdf0cd2e14d4a6861a7cd5/sentry_sdk-2.43.0-py2.py3-none-any.whl", hash = "sha256:4aacafcf1756ef066d359ae35030881917160ba7f6fc3ae11e0e58b09edc2d5d", size = 400997, upload-time = "2025-10-29T11:26:05.77Z" }, ] [[package]] name = "shellingham" version = "1.5.4" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/58/15/8b3609fd3830ef7b27b655beb4b4e9c62313a4e8da8c676e142cc210d58e/shellingham-1.5.4.tar.gz", hash = "sha256:8dbca0739d487e5bd35ab3ca4b36e11c4078f3a234bfce294b0a0291363404de", size = 10310 } +sdist = { url = "https://files.pythonhosted.org/packages/58/15/8b3609fd3830ef7b27b655beb4b4e9c62313a4e8da8c676e142cc210d58e/shellingham-1.5.4.tar.gz", hash = "sha256:8dbca0739d487e5bd35ab3ca4b36e11c4078f3a234bfce294b0a0291363404de", size = 10310, upload-time = "2023-10-24T04:13:40.426Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/e0/f9/0595336914c5619e5f28a1fb793285925a8cd4b432c9da0a987836c7f822/shellingham-1.5.4-py2.py3-none-any.whl", hash = "sha256:7ecfff8f2fd72616f7481040475a65b2bf8af90a56c89140852d1120324e8686", size = 9755 }, + { url = "https://files.pythonhosted.org/packages/e0/f9/0595336914c5619e5f28a1fb793285925a8cd4b432c9da0a987836c7f822/shellingham-1.5.4-py2.py3-none-any.whl", hash = "sha256:7ecfff8f2fd72616f7481040475a65b2bf8af90a56c89140852d1120324e8686", size = 9755, upload-time = "2023-10-24T04:13:38.866Z" }, ] [[package]] name = "six" version = "1.17.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/94/e7/b2c673351809dca68a0e064b6af791aa332cf192da575fd474ed7d6f16a2/six-1.17.0.tar.gz", hash = "sha256:ff70335d468e7eb6ec65b95b99d3a2836546063f63acc5171de367e834932a81", size = 34031 } +sdist = { url = "https://files.pythonhosted.org/packages/94/e7/b2c673351809dca68a0e064b6af791aa332cf192da575fd474ed7d6f16a2/six-1.17.0.tar.gz", hash = "sha256:ff70335d468e7eb6ec65b95b99d3a2836546063f63acc5171de367e834932a81", size = 34031, upload-time = "2024-12-04T17:35:28.174Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/b7/ce/149a00dd41f10bc29e5921b496af8b574d8413afcd5e30dfa0ed46c2cc5e/six-1.17.0-py2.py3-none-any.whl", hash = "sha256:4721f391ed90541fddacab5acf947aa0d3dc7d27b2e1e8eda2be8970586c3274", size = 11050 }, + { url = "https://files.pythonhosted.org/packages/b7/ce/149a00dd41f10bc29e5921b496af8b574d8413afcd5e30dfa0ed46c2cc5e/six-1.17.0-py2.py3-none-any.whl", hash = "sha256:4721f391ed90541fddacab5acf947aa0d3dc7d27b2e1e8eda2be8970586c3274", size = 11050, upload-time = "2024-12-04T17:35:26.475Z" }, ] [[package]] name = "sniffio" version = "1.3.1" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/a2/87/a6771e1546d97e7e041b6ae58d80074f81b7d5121207425c964ddf5cfdbd/sniffio-1.3.1.tar.gz", hash = "sha256:f4324edc670a0f49750a81b895f35c3adb843cca46f0530f79fc1babb23789dc", size = 20372 } +sdist = { url = "https://files.pythonhosted.org/packages/a2/87/a6771e1546d97e7e041b6ae58d80074f81b7d5121207425c964ddf5cfdbd/sniffio-1.3.1.tar.gz", hash = "sha256:f4324edc670a0f49750a81b895f35c3adb843cca46f0530f79fc1babb23789dc", size = 20372, upload-time = "2024-02-25T23:20:04.057Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/e9/44/75a9c9421471a6c4805dbf2356f7c181a29c1879239abab1ea2cc8f38b40/sniffio-1.3.1-py3-none-any.whl", hash = "sha256:2f6da418d1f1e0fddd844478f41680e794e6051915791a034ff65e5f100525a2", size = 10235 }, + { url = "https://files.pythonhosted.org/packages/e9/44/75a9c9421471a6c4805dbf2356f7c181a29c1879239abab1ea2cc8f38b40/sniffio-1.3.1-py3-none-any.whl", hash = "sha256:2f6da418d1f1e0fddd844478f41680e794e6051915791a034ff65e5f100525a2", size = 10235, upload-time = "2024-02-25T23:20:01.196Z" }, ] [[package]] name = "soupsieve" version = "2.8" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/6d/e6/21ccce3262dd4889aa3332e5a119a3491a95e8f60939870a3a035aabac0d/soupsieve-2.8.tar.gz", hash = "sha256:e2dd4a40a628cb5f28f6d4b0db8800b8f581b65bb380b97de22ba5ca8d72572f", size = 103472 } +sdist = { url = "https://files.pythonhosted.org/packages/6d/e6/21ccce3262dd4889aa3332e5a119a3491a95e8f60939870a3a035aabac0d/soupsieve-2.8.tar.gz", hash = "sha256:e2dd4a40a628cb5f28f6d4b0db8800b8f581b65bb380b97de22ba5ca8d72572f", size = 103472, upload-time = "2025-08-27T15:39:51.78Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/14/a0/bb38d3b76b8cae341dad93a2dd83ab7462e6dbcdd84d43f54ee60a8dc167/soupsieve-2.8-py3-none-any.whl", hash = "sha256:0cc76456a30e20f5d7f2e14a98a4ae2ee4e5abdc7c5ea0aafe795f344bc7984c", size = 36679 }, + { url = "https://files.pythonhosted.org/packages/14/a0/bb38d3b76b8cae341dad93a2dd83ab7462e6dbcdd84d43f54ee60a8dc167/soupsieve-2.8-py3-none-any.whl", hash = "sha256:0cc76456a30e20f5d7f2e14a98a4ae2ee4e5abdc7c5ea0aafe795f344bc7984c", size = 36679, upload-time = "2025-08-27T15:39:50.179Z" }, ] [[package]] @@ -2142,9 +2167,9 @@ dependencies = [ { name = "starlette" }, { name = "wtforms" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/5b/0c/614041e1b544e0de1f43b58f0105b3e2795b80369d5b0ff7412882d42fff/sqladmin-0.21.0.tar.gz", hash = "sha256:cb455b79eb79ef7d904680dd83817bf7750675147400b5b7cc401d04bda7ef2c", size = 1428312 } +sdist = { url = "https://files.pythonhosted.org/packages/5b/0c/614041e1b544e0de1f43b58f0105b3e2795b80369d5b0ff7412882d42fff/sqladmin-0.21.0.tar.gz", hash = "sha256:cb455b79eb79ef7d904680dd83817bf7750675147400b5b7cc401d04bda7ef2c", size = 1428312, upload-time = "2025-07-02T09:41:21.207Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/ed/8d/81b2a48cc6f5479cb1148292518e3006ec8f5fbe3b0829ef165984e9d7b9/sqladmin-0.21.0-py3-none-any.whl", hash = "sha256:2b1802c49bdd3128c6452625705693cf32d5d33e7db30e63f409bd20a9c05b53", size = 1443585 }, + { url = "https://files.pythonhosted.org/packages/ed/8d/81b2a48cc6f5479cb1148292518e3006ec8f5fbe3b0829ef165984e9d7b9/sqladmin-0.21.0-py3-none-any.whl", hash = "sha256:2b1802c49bdd3128c6452625705693cf32d5d33e7db30e63f409bd20a9c05b53", size = 1443585, upload-time = "2025-07-02T09:41:19.205Z" }, ] [[package]] @@ -2155,17 +2180,17 @@ dependencies = [ { name = "greenlet", marker = "platform_machine == 'AMD64' or platform_machine == 'WIN32' or platform_machine == 'aarch64' or platform_machine == 'amd64' or platform_machine == 'ppc64le' or platform_machine == 'win32' or platform_machine == 'x86_64'" }, { name = "typing-extensions" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/f0/f2/840d7b9496825333f532d2e3976b8eadbf52034178aac53630d09fe6e1ef/sqlalchemy-2.0.44.tar.gz", hash = "sha256:0ae7454e1ab1d780aee69fd2aae7d6b8670a581d8847f2d1e0f7ddfbf47e5a22", size = 9819830 } +sdist = { url = "https://files.pythonhosted.org/packages/f0/f2/840d7b9496825333f532d2e3976b8eadbf52034178aac53630d09fe6e1ef/sqlalchemy-2.0.44.tar.gz", hash = "sha256:0ae7454e1ab1d780aee69fd2aae7d6b8670a581d8847f2d1e0f7ddfbf47e5a22", size = 9819830, upload-time = "2025-10-10T14:39:12.935Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/45/d3/c67077a2249fdb455246e6853166360054c331db4613cda3e31ab1cadbef/sqlalchemy-2.0.44-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:ff486e183d151e51b1d694c7aa1695747599bb00b9f5f604092b54b74c64a8e1", size = 2135479 }, - { url = "https://files.pythonhosted.org/packages/2b/91/eabd0688330d6fd114f5f12c4f89b0d02929f525e6bf7ff80aa17ca802af/sqlalchemy-2.0.44-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:0b1af8392eb27b372ddb783b317dea0f650241cea5bd29199b22235299ca2e45", size = 2123212 }, - { url = "https://files.pythonhosted.org/packages/b0/bb/43e246cfe0e81c018076a16036d9b548c4cc649de241fa27d8d9ca6f85ab/sqlalchemy-2.0.44-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2b61188657e3a2b9ac4e8f04d6cf8e51046e28175f79464c67f2fd35bceb0976", size = 3255353 }, - { url = "https://files.pythonhosted.org/packages/b9/96/c6105ed9a880abe346b64d3b6ddef269ddfcab04f7f3d90a0bf3c5a88e82/sqlalchemy-2.0.44-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b87e7b91a5d5973dda5f00cd61ef72ad75a1db73a386b62877d4875a8840959c", size = 3260222 }, - { url = "https://files.pythonhosted.org/packages/44/16/1857e35a47155b5ad927272fee81ae49d398959cb749edca6eaa399b582f/sqlalchemy-2.0.44-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:15f3326f7f0b2bfe406ee562e17f43f36e16167af99c4c0df61db668de20002d", size = 3189614 }, - { url = "https://files.pythonhosted.org/packages/88/ee/4afb39a8ee4fc786e2d716c20ab87b5b1fb33d4ac4129a1aaa574ae8a585/sqlalchemy-2.0.44-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:1e77faf6ff919aa8cd63f1c4e561cac1d9a454a191bb864d5dd5e545935e5a40", size = 3226248 }, - { url = "https://files.pythonhosted.org/packages/32/d5/0e66097fc64fa266f29a7963296b40a80d6a997b7ac13806183700676f86/sqlalchemy-2.0.44-cp313-cp313-win32.whl", hash = "sha256:ee51625c2d51f8baadf2829fae817ad0b66b140573939dd69284d2ba3553ae73", size = 2101275 }, - { url = "https://files.pythonhosted.org/packages/03/51/665617fe4f8c6450f42a6d8d69243f9420f5677395572c2fe9d21b493b7b/sqlalchemy-2.0.44-cp313-cp313-win_amd64.whl", hash = "sha256:c1c80faaee1a6c3428cecf40d16a2365bcf56c424c92c2b6f0f9ad204b899e9e", size = 2127901 }, - { url = "https://files.pythonhosted.org/packages/9c/5e/6a29fa884d9fb7ddadf6b69490a9d45fded3b38541713010dad16b77d015/sqlalchemy-2.0.44-py3-none-any.whl", hash = "sha256:19de7ca1246fbef9f9d1bff8f1ab25641569df226364a0e40457dc5457c54b05", size = 1928718 }, + { url = "https://files.pythonhosted.org/packages/45/d3/c67077a2249fdb455246e6853166360054c331db4613cda3e31ab1cadbef/sqlalchemy-2.0.44-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:ff486e183d151e51b1d694c7aa1695747599bb00b9f5f604092b54b74c64a8e1", size = 2135479, upload-time = "2025-10-10T16:03:37.671Z" }, + { url = "https://files.pythonhosted.org/packages/2b/91/eabd0688330d6fd114f5f12c4f89b0d02929f525e6bf7ff80aa17ca802af/sqlalchemy-2.0.44-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:0b1af8392eb27b372ddb783b317dea0f650241cea5bd29199b22235299ca2e45", size = 2123212, upload-time = "2025-10-10T16:03:41.755Z" }, + { url = "https://files.pythonhosted.org/packages/b0/bb/43e246cfe0e81c018076a16036d9b548c4cc649de241fa27d8d9ca6f85ab/sqlalchemy-2.0.44-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2b61188657e3a2b9ac4e8f04d6cf8e51046e28175f79464c67f2fd35bceb0976", size = 3255353, upload-time = "2025-10-10T15:35:31.221Z" }, + { url = "https://files.pythonhosted.org/packages/b9/96/c6105ed9a880abe346b64d3b6ddef269ddfcab04f7f3d90a0bf3c5a88e82/sqlalchemy-2.0.44-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b87e7b91a5d5973dda5f00cd61ef72ad75a1db73a386b62877d4875a8840959c", size = 3260222, upload-time = "2025-10-10T15:43:50.124Z" }, + { url = "https://files.pythonhosted.org/packages/44/16/1857e35a47155b5ad927272fee81ae49d398959cb749edca6eaa399b582f/sqlalchemy-2.0.44-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:15f3326f7f0b2bfe406ee562e17f43f36e16167af99c4c0df61db668de20002d", size = 3189614, upload-time = "2025-10-10T15:35:32.578Z" }, + { url = "https://files.pythonhosted.org/packages/88/ee/4afb39a8ee4fc786e2d716c20ab87b5b1fb33d4ac4129a1aaa574ae8a585/sqlalchemy-2.0.44-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:1e77faf6ff919aa8cd63f1c4e561cac1d9a454a191bb864d5dd5e545935e5a40", size = 3226248, upload-time = "2025-10-10T15:43:51.862Z" }, + { url = "https://files.pythonhosted.org/packages/32/d5/0e66097fc64fa266f29a7963296b40a80d6a997b7ac13806183700676f86/sqlalchemy-2.0.44-cp313-cp313-win32.whl", hash = "sha256:ee51625c2d51f8baadf2829fae817ad0b66b140573939dd69284d2ba3553ae73", size = 2101275, upload-time = "2025-10-10T15:03:26.096Z" }, + { url = "https://files.pythonhosted.org/packages/03/51/665617fe4f8c6450f42a6d8d69243f9420f5677395572c2fe9d21b493b7b/sqlalchemy-2.0.44-cp313-cp313-win_amd64.whl", hash = "sha256:c1c80faaee1a6c3428cecf40d16a2365bcf56c424c92c2b6f0f9ad204b899e9e", size = 2127901, upload-time = "2025-10-10T15:03:27.548Z" }, + { url = "https://files.pythonhosted.org/packages/9c/5e/6a29fa884d9fb7ddadf6b69490a9d45fded3b38541713010dad16b77d015/sqlalchemy-2.0.44-py3-none-any.whl", hash = "sha256:19de7ca1246fbef9f9d1bff8f1ab25641569df226364a0e40457dc5457c54b05", size = 1928718, upload-time = "2025-10-10T15:29:45.32Z" }, ] [package.optional-dependencies] @@ -2181,9 +2206,9 @@ dependencies = [ { name = "pydantic" }, { name = "sqlalchemy" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/90/5a/693d90866233e837d182da76082a6d4c2303f54d3aaaa5c78e1238c5d863/sqlmodel-0.0.27.tar.gz", hash = "sha256:ad1227f2014a03905aef32e21428640848ac09ff793047744a73dfdd077ff620", size = 118053 } +sdist = { url = "https://files.pythonhosted.org/packages/90/5a/693d90866233e837d182da76082a6d4c2303f54d3aaaa5c78e1238c5d863/sqlmodel-0.0.27.tar.gz", hash = "sha256:ad1227f2014a03905aef32e21428640848ac09ff793047744a73dfdd077ff620", size = 118053, upload-time = "2025-10-08T16:39:11.938Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/8c/92/c35e036151fe53822893979f8a13e6f235ae8191f4164a79ae60a95d66aa/sqlmodel-0.0.27-py3-none-any.whl", hash = "sha256:667fe10aa8ff5438134668228dc7d7a08306f4c5c4c7e6ad3ad68defa0e7aa49", size = 29131 }, + { url = "https://files.pythonhosted.org/packages/8c/92/c35e036151fe53822893979f8a13e6f235ae8191f4164a79ae60a95d66aa/sqlmodel-0.0.27-py3-none-any.whl", hash = "sha256:667fe10aa8ff5438134668228dc7d7a08306f4c5c4c7e6ad3ad68defa0e7aa49", size = 29131, upload-time = "2025-10-08T16:39:10.917Z" }, ] [[package]] @@ -2193,18 +2218,18 @@ source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "anyio" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/de/1a/608df0b10b53b0beb96a37854ee05864d182ddd4b1156a22f1ad3860425a/starlette-0.49.3.tar.gz", hash = "sha256:1c14546f299b5901a1ea0e34410575bc33bbd741377a10484a54445588d00284", size = 2655031 } +sdist = { url = "https://files.pythonhosted.org/packages/de/1a/608df0b10b53b0beb96a37854ee05864d182ddd4b1156a22f1ad3860425a/starlette-0.49.3.tar.gz", hash = "sha256:1c14546f299b5901a1ea0e34410575bc33bbd741377a10484a54445588d00284", size = 2655031, upload-time = "2025-11-01T15:12:26.13Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/a3/e0/021c772d6a662f43b63044ab481dc6ac7592447605b5b35a957785363122/starlette-0.49.3-py3-none-any.whl", hash = "sha256:b579b99715fdc2980cf88c8ec96d3bf1ce16f5a8051a7c2b84ef9b1cdecaea2f", size = 74340 }, + { url = "https://files.pythonhosted.org/packages/a3/e0/021c772d6a662f43b63044ab481dc6ac7592447605b5b35a957785363122/starlette-0.49.3-py3-none-any.whl", hash = "sha256:b579b99715fdc2980cf88c8ec96d3bf1ce16f5a8051a7c2b84ef9b1cdecaea2f", size = 74340, upload-time = "2025-11-01T15:12:24.387Z" }, ] [[package]] name = "text-unidecode" version = "1.3" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/ab/e2/e9a00f0ccb71718418230718b3d900e71a5d16e701a3dae079a21e9cd8f8/text-unidecode-1.3.tar.gz", hash = "sha256:bad6603bb14d279193107714b288be206cac565dfa49aa5b105294dd5c4aab93", size = 76885 } +sdist = { url = "https://files.pythonhosted.org/packages/ab/e2/e9a00f0ccb71718418230718b3d900e71a5d16e701a3dae079a21e9cd8f8/text-unidecode-1.3.tar.gz", hash = "sha256:bad6603bb14d279193107714b288be206cac565dfa49aa5b105294dd5c4aab93", size = 76885, upload-time = "2019-08-30T21:36:45.405Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/a6/a5/c0b6468d3824fe3fde30dbb5e1f687b291608f9473681bbf7dabbf5a87d7/text_unidecode-1.3-py2.py3-none-any.whl", hash = "sha256:1311f10e8b895935241623731c2ba64f4c455287888b18189350b67134a822e8", size = 78154 }, + { url = "https://files.pythonhosted.org/packages/a6/a5/c0b6468d3824fe3fde30dbb5e1f687b291608f9473681bbf7dabbf5a87d7/text_unidecode-1.3-py2.py3-none-any.whl", hash = "sha256:1311f10e8b895935241623731c2ba64f4c455287888b18189350b67134a822e8", size = 78154, upload-time = "2019-08-30T21:37:03.543Z" }, ] [[package]] @@ -2217,9 +2242,9 @@ dependencies = [ { name = "requests" }, { name = "requests-file" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/97/78/182641ea38e3cfd56e9c7b3c0d48a53d432eea755003aa544af96403d4ac/tldextract-5.3.0.tar.gz", hash = "sha256:b3d2b70a1594a0ecfa6967d57251527d58e00bb5a91a74387baa0d87a0678609", size = 128502 } +sdist = { url = "https://files.pythonhosted.org/packages/97/78/182641ea38e3cfd56e9c7b3c0d48a53d432eea755003aa544af96403d4ac/tldextract-5.3.0.tar.gz", hash = "sha256:b3d2b70a1594a0ecfa6967d57251527d58e00bb5a91a74387baa0d87a0678609", size = 128502, upload-time = "2025-04-22T06:19:37.491Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/67/7c/ea488ef48f2f544566947ced88541bc45fae9e0e422b2edbf165ee07da99/tldextract-5.3.0-py3-none-any.whl", hash = "sha256:f70f31d10b55c83993f55e91ecb7c5d84532a8972f22ec578ecfbe5ea2292db2", size = 107384 }, + { url = "https://files.pythonhosted.org/packages/67/7c/ea488ef48f2f544566947ced88541bc45fae9e0e422b2edbf165ee07da99/tldextract-5.3.0-py3-none-any.whl", hash = "sha256:f70f31d10b55c83993f55e91ecb7c5d84532a8972f22ec578ecfbe5ea2292db2", size = 107384, upload-time = "2025-04-22T06:19:36.304Z" }, ] [[package]] @@ -2232,18 +2257,18 @@ dependencies = [ { name = "shellingham" }, { name = "typing-extensions" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/8f/28/7c85c8032b91dbe79725b6f17d2fffc595dff06a35c7a30a37bef73a1ab4/typer-0.20.0.tar.gz", hash = "sha256:1aaf6494031793e4876fb0bacfa6a912b551cf43c1e63c800df8b1a866720c37", size = 106492 } +sdist = { url = "https://files.pythonhosted.org/packages/8f/28/7c85c8032b91dbe79725b6f17d2fffc595dff06a35c7a30a37bef73a1ab4/typer-0.20.0.tar.gz", hash = "sha256:1aaf6494031793e4876fb0bacfa6a912b551cf43c1e63c800df8b1a866720c37", size = 106492, upload-time = "2025-10-20T17:03:49.445Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/78/64/7713ffe4b5983314e9d436a90d5bd4f63b6054e2aca783a3cfc44cb95bbf/typer-0.20.0-py3-none-any.whl", hash = "sha256:5b463df6793ec1dca6213a3cf4c0f03bc6e322ac5e16e13ddd622a889489784a", size = 47028 }, + { url = "https://files.pythonhosted.org/packages/78/64/7713ffe4b5983314e9d436a90d5bd4f63b6054e2aca783a3cfc44cb95bbf/typer-0.20.0-py3-none-any.whl", hash = "sha256:5b463df6793ec1dca6213a3cf4c0f03bc6e322ac5e16e13ddd622a889489784a", size = 47028, upload-time = "2025-10-20T17:03:47.617Z" }, ] [[package]] name = "typing-extensions" version = "4.15.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/72/94/1a15dd82efb362ac84269196e94cf00f187f7ed21c242792a923cdb1c61f/typing_extensions-4.15.0.tar.gz", hash = "sha256:0cea48d173cc12fa28ecabc3b837ea3cf6f38c6d1136f85cbaaf598984861466", size = 109391 } +sdist = { url = "https://files.pythonhosted.org/packages/72/94/1a15dd82efb362ac84269196e94cf00f187f7ed21c242792a923cdb1c61f/typing_extensions-4.15.0.tar.gz", hash = "sha256:0cea48d173cc12fa28ecabc3b837ea3cf6f38c6d1136f85cbaaf598984861466", size = 109391, upload-time = "2025-08-25T13:49:26.313Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/18/67/36e9267722cc04a6b9f15c7f3441c2363321a3ea07da7ae0c0707beb2a9c/typing_extensions-4.15.0-py3-none-any.whl", hash = "sha256:f0fa19c6845758ab08074a0cfa8b7aecb71c999ca73d62883bc25cc018c4e548", size = 44614 }, + { url = "https://files.pythonhosted.org/packages/18/67/36e9267722cc04a6b9f15c7f3441c2363321a3ea07da7ae0c0707beb2a9c/typing_extensions-4.15.0-py3-none-any.whl", hash = "sha256:f0fa19c6845758ab08074a0cfa8b7aecb71c999ca73d62883bc25cc018c4e548", size = 44614, upload-time = "2025-08-25T13:49:24.86Z" }, ] [[package]] @@ -2253,36 +2278,36 @@ source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "typing-extensions" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/55/e3/70399cb7dd41c10ac53367ae42139cf4b1ca5f36bb3dc6c9d33acdb43655/typing_inspection-0.4.2.tar.gz", hash = "sha256:ba561c48a67c5958007083d386c3295464928b01faa735ab8547c5692e87f464", size = 75949 } +sdist = { url = "https://files.pythonhosted.org/packages/55/e3/70399cb7dd41c10ac53367ae42139cf4b1ca5f36bb3dc6c9d33acdb43655/typing_inspection-0.4.2.tar.gz", hash = "sha256:ba561c48a67c5958007083d386c3295464928b01faa735ab8547c5692e87f464", size = 75949, upload-time = "2025-10-01T02:14:41.687Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/dc/9b/47798a6c91d8bdb567fe2698fe81e0c6b7cb7ef4d13da4114b41d239f65d/typing_inspection-0.4.2-py3-none-any.whl", hash = "sha256:4ed1cacbdc298c220f1bd249ed5287caa16f34d44ef4e9c3d0cbad5b521545e7", size = 14611 }, + { url = "https://files.pythonhosted.org/packages/dc/9b/47798a6c91d8bdb567fe2698fe81e0c6b7cb7ef4d13da4114b41d239f65d/typing_inspection-0.4.2-py3-none-any.whl", hash = "sha256:4ed1cacbdc298c220f1bd249ed5287caa16f34d44ef4e9c3d0cbad5b521545e7", size = 14611, upload-time = "2025-10-01T02:14:40.154Z" }, ] [[package]] name = "tzdata" version = "2025.2" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/95/32/1a225d6164441be760d75c2c42e2780dc0873fe382da3e98a2e1e48361e5/tzdata-2025.2.tar.gz", hash = "sha256:b60a638fcc0daffadf82fe0f57e53d06bdec2f36c4df66280ae79bce6bd6f2b9", size = 196380 } +sdist = { url = "https://files.pythonhosted.org/packages/95/32/1a225d6164441be760d75c2c42e2780dc0873fe382da3e98a2e1e48361e5/tzdata-2025.2.tar.gz", hash = "sha256:b60a638fcc0daffadf82fe0f57e53d06bdec2f36c4df66280ae79bce6bd6f2b9", size = 196380, upload-time = "2025-03-23T13:54:43.652Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/5c/23/c7abc0ca0a1526a0774eca151daeb8de62ec457e77262b66b359c3c7679e/tzdata-2025.2-py2.py3-none-any.whl", hash = "sha256:1a403fada01ff9221ca8044d701868fa132215d84beb92242d9acd2147f667a8", size = 347839 }, + { url = "https://files.pythonhosted.org/packages/5c/23/c7abc0ca0a1526a0774eca151daeb8de62ec457e77262b66b359c3c7679e/tzdata-2025.2-py2.py3-none-any.whl", hash = "sha256:1a403fada01ff9221ca8044d701868fa132215d84beb92242d9acd2147f667a8", size = 347839, upload-time = "2025-03-23T13:54:41.845Z" }, ] [[package]] name = "uritemplate" version = "4.2.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/98/60/f174043244c5306c9988380d2cb10009f91563fc4b31293d27e17201af56/uritemplate-4.2.0.tar.gz", hash = "sha256:480c2ed180878955863323eea31b0ede668795de182617fef9c6ca09e6ec9d0e", size = 33267 } +sdist = { url = "https://files.pythonhosted.org/packages/98/60/f174043244c5306c9988380d2cb10009f91563fc4b31293d27e17201af56/uritemplate-4.2.0.tar.gz", hash = "sha256:480c2ed180878955863323eea31b0ede668795de182617fef9c6ca09e6ec9d0e", size = 33267, upload-time = "2025-06-02T15:12:06.318Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/a9/99/3ae339466c9183ea5b8ae87b34c0b897eda475d2aec2307cae60e5cd4f29/uritemplate-4.2.0-py3-none-any.whl", hash = "sha256:962201ba1c4edcab02e60f9a0d3821e82dfc5d2d6662a21abd533879bdb8a686", size = 11488 }, + { url = "https://files.pythonhosted.org/packages/a9/99/3ae339466c9183ea5b8ae87b34c0b897eda475d2aec2307cae60e5cd4f29/uritemplate-4.2.0-py3-none-any.whl", hash = "sha256:962201ba1c4edcab02e60f9a0d3821e82dfc5d2d6662a21abd533879bdb8a686", size = 11488, upload-time = "2025-06-02T15:12:03.405Z" }, ] [[package]] name = "urllib3" version = "2.5.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/15/22/9ee70a2574a4f4599c47dd506532914ce044817c7752a79b6a51286319bc/urllib3-2.5.0.tar.gz", hash = "sha256:3fc47733c7e419d4bc3f6b3dc2b4f890bb743906a30d56ba4a5bfa4bbff92760", size = 393185 } +sdist = { url = "https://files.pythonhosted.org/packages/15/22/9ee70a2574a4f4599c47dd506532914ce044817c7752a79b6a51286319bc/urllib3-2.5.0.tar.gz", hash = "sha256:3fc47733c7e419d4bc3f6b3dc2b4f890bb743906a30d56ba4a5bfa4bbff92760", size = 393185, upload-time = "2025-06-18T14:07:41.644Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/a7/c2/fe1e52489ae3122415c51f387e221dd0773709bad6c6cdaa599e8a2c5185/urllib3-2.5.0-py3-none-any.whl", hash = "sha256:e6b01673c0fa6a13e374b50871808eb3bf7046c4b125b216f6bf1cc604cff0dc", size = 129795 }, + { url = "https://files.pythonhosted.org/packages/a7/c2/fe1e52489ae3122415c51f387e221dd0773709bad6c6cdaa599e8a2c5185/urllib3-2.5.0-py3-none-any.whl", hash = "sha256:e6b01673c0fa6a13e374b50871808eb3bf7046c4b125b216f6bf1cc604cff0dc", size = 129795, upload-time = "2025-06-18T14:07:40.39Z" }, ] [[package]] @@ -2293,9 +2318,9 @@ dependencies = [ { name = "click" }, { name = "h11" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/cb/ce/f06b84e2697fef4688ca63bdb2fdf113ca0a3be33f94488f2cadb690b0cf/uvicorn-0.38.0.tar.gz", hash = "sha256:fd97093bdd120a2609fc0d3afe931d4d4ad688b6e75f0f929fde1bc36fe0e91d", size = 80605 } +sdist = { url = "https://files.pythonhosted.org/packages/cb/ce/f06b84e2697fef4688ca63bdb2fdf113ca0a3be33f94488f2cadb690b0cf/uvicorn-0.38.0.tar.gz", hash = "sha256:fd97093bdd120a2609fc0d3afe931d4d4ad688b6e75f0f929fde1bc36fe0e91d", size = 80605, upload-time = "2025-10-18T13:46:44.63Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/ee/d9/d88e73ca598f4f6ff671fb5fde8a32925c2e08a637303a1d12883c7305fa/uvicorn-0.38.0-py3-none-any.whl", hash = "sha256:48c0afd214ceb59340075b4a052ea1ee91c16fbc2a9b1469cca0e54566977b02", size = 68109 }, + { url = "https://files.pythonhosted.org/packages/ee/d9/d88e73ca598f4f6ff671fb5fde8a32925c2e08a637303a1d12883c7305fa/uvicorn-0.38.0-py3-none-any.whl", hash = "sha256:48c0afd214ceb59340075b4a052ea1ee91c16fbc2a9b1469cca0e54566977b02", size = 68109, upload-time = "2025-10-18T13:46:42.958Z" }, ] [package.optional-dependencies] @@ -2313,26 +2338,26 @@ standard = [ name = "uvloop" version = "0.22.1" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/06/f0/18d39dbd1971d6d62c4629cc7fa67f74821b0dc1f5a77af43719de7936a7/uvloop-0.22.1.tar.gz", hash = "sha256:6c84bae345b9147082b17371e3dd5d42775bddce91f885499017f4607fdaf39f", size = 2443250 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/89/8c/182a2a593195bfd39842ea68ebc084e20c850806117213f5a299dfc513d9/uvloop-0.22.1-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:561577354eb94200d75aca23fbde86ee11be36b00e52a4eaf8f50fb0c86b7705", size = 1358611 }, - { url = "https://files.pythonhosted.org/packages/d2/14/e301ee96a6dc95224b6f1162cd3312f6d1217be3907b79173b06785f2fe7/uvloop-0.22.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:1cdf5192ab3e674ca26da2eada35b288d2fa49fdd0f357a19f0e7c4e7d5077c8", size = 751811 }, - { url = "https://files.pythonhosted.org/packages/b7/02/654426ce265ac19e2980bfd9ea6590ca96a56f10c76e63801a2df01c0486/uvloop-0.22.1-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6e2ea3d6190a2968f4a14a23019d3b16870dd2190cd69c8180f7c632d21de68d", size = 4288562 }, - { url = "https://files.pythonhosted.org/packages/15/c0/0be24758891ef825f2065cd5db8741aaddabe3e248ee6acc5e8a80f04005/uvloop-0.22.1-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:0530a5fbad9c9e4ee3f2b33b148c6a64d47bbad8000ea63704fa8260f4cf728e", size = 4366890 }, - { url = "https://files.pythonhosted.org/packages/d2/53/8369e5219a5855869bcee5f4d317f6da0e2c669aecf0ef7d371e3d084449/uvloop-0.22.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:bc5ef13bbc10b5335792360623cc378d52d7e62c2de64660616478c32cd0598e", size = 4119472 }, - { url = "https://files.pythonhosted.org/packages/f8/ba/d69adbe699b768f6b29a5eec7b47dd610bd17a69de51b251126a801369ea/uvloop-0.22.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:1f38ec5e3f18c8a10ded09742f7fb8de0108796eb673f30ce7762ce1b8550cad", size = 4239051 }, - { url = "https://files.pythonhosted.org/packages/90/cd/b62bdeaa429758aee8de8b00ac0dd26593a9de93d302bff3d21439e9791d/uvloop-0.22.1-cp314-cp314-macosx_10_13_universal2.whl", hash = "sha256:3879b88423ec7e97cd4eba2a443aa26ed4e59b45e6b76aabf13fe2f27023a142", size = 1362067 }, - { url = "https://files.pythonhosted.org/packages/0d/f8/a132124dfda0777e489ca86732e85e69afcd1ff7686647000050ba670689/uvloop-0.22.1-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:4baa86acedf1d62115c1dc6ad1e17134476688f08c6efd8a2ab076e815665c74", size = 752423 }, - { url = "https://files.pythonhosted.org/packages/a3/94/94af78c156f88da4b3a733773ad5ba0b164393e357cc4bd0ab2e2677a7d6/uvloop-0.22.1-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:297c27d8003520596236bdb2335e6b3f649480bd09e00d1e3a99144b691d2a35", size = 4272437 }, - { url = "https://files.pythonhosted.org/packages/b5/35/60249e9fd07b32c665192cec7af29e06c7cd96fa1d08b84f012a56a0b38e/uvloop-0.22.1-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c1955d5a1dd43198244d47664a5858082a3239766a839b2102a269aaff7a4e25", size = 4292101 }, - { url = "https://files.pythonhosted.org/packages/02/62/67d382dfcb25d0a98ce73c11ed1a6fba5037a1a1d533dcbb7cab033a2636/uvloop-0.22.1-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:b31dc2fccbd42adc73bc4e7cdbae4fc5086cf378979e53ca5d0301838c5682c6", size = 4114158 }, - { url = "https://files.pythonhosted.org/packages/f0/7a/f1171b4a882a5d13c8b7576f348acfe6074d72eaf52cccef752f748d4a9f/uvloop-0.22.1-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:93f617675b2d03af4e72a5333ef89450dfaa5321303ede6e67ba9c9d26878079", size = 4177360 }, - { url = "https://files.pythonhosted.org/packages/79/7b/b01414f31546caf0919da80ad57cbfe24c56b151d12af68cee1b04922ca8/uvloop-0.22.1-cp314-cp314t-macosx_10_13_universal2.whl", hash = "sha256:37554f70528f60cad66945b885eb01f1bb514f132d92b6eeed1c90fd54ed6289", size = 1454790 }, - { url = "https://files.pythonhosted.org/packages/d4/31/0bb232318dd838cad3fa8fb0c68c8b40e1145b32025581975e18b11fab40/uvloop-0.22.1-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:b76324e2dc033a0b2f435f33eb88ff9913c156ef78e153fb210e03c13da746b3", size = 796783 }, - { url = "https://files.pythonhosted.org/packages/42/38/c9b09f3271a7a723a5de69f8e237ab8e7803183131bc57c890db0b6bb872/uvloop-0.22.1-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:badb4d8e58ee08dad957002027830d5c3b06aea446a6a3744483c2b3b745345c", size = 4647548 }, - { url = "https://files.pythonhosted.org/packages/c1/37/945b4ca0ac27e3dc4952642d4c900edd030b3da6c9634875af6e13ae80e5/uvloop-0.22.1-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:b91328c72635f6f9e0282e4a57da7470c7350ab1c9f48546c0f2866205349d21", size = 4467065 }, - { url = "https://files.pythonhosted.org/packages/97/cc/48d232f33d60e2e2e0b42f4e73455b146b76ebe216487e862700457fbf3c/uvloop-0.22.1-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:daf620c2995d193449393d6c62131b3fbd40a63bf7b307a1527856ace637fe88", size = 4328384 }, - { url = "https://files.pythonhosted.org/packages/e4/16/c1fd27e9549f3c4baf1dc9c20c456cd2f822dbf8de9f463824b0c0357e06/uvloop-0.22.1-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:6cde23eeda1a25c75b2e07d39970f3374105d5eafbaab2a4482be82f272d5a5e", size = 4296730 }, +sdist = { url = "https://files.pythonhosted.org/packages/06/f0/18d39dbd1971d6d62c4629cc7fa67f74821b0dc1f5a77af43719de7936a7/uvloop-0.22.1.tar.gz", hash = "sha256:6c84bae345b9147082b17371e3dd5d42775bddce91f885499017f4607fdaf39f", size = 2443250, upload-time = "2025-10-16T22:17:19.342Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/89/8c/182a2a593195bfd39842ea68ebc084e20c850806117213f5a299dfc513d9/uvloop-0.22.1-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:561577354eb94200d75aca23fbde86ee11be36b00e52a4eaf8f50fb0c86b7705", size = 1358611, upload-time = "2025-10-16T22:16:36.833Z" }, + { url = "https://files.pythonhosted.org/packages/d2/14/e301ee96a6dc95224b6f1162cd3312f6d1217be3907b79173b06785f2fe7/uvloop-0.22.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:1cdf5192ab3e674ca26da2eada35b288d2fa49fdd0f357a19f0e7c4e7d5077c8", size = 751811, upload-time = "2025-10-16T22:16:38.275Z" }, + { url = "https://files.pythonhosted.org/packages/b7/02/654426ce265ac19e2980bfd9ea6590ca96a56f10c76e63801a2df01c0486/uvloop-0.22.1-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6e2ea3d6190a2968f4a14a23019d3b16870dd2190cd69c8180f7c632d21de68d", size = 4288562, upload-time = "2025-10-16T22:16:39.375Z" }, + { url = "https://files.pythonhosted.org/packages/15/c0/0be24758891ef825f2065cd5db8741aaddabe3e248ee6acc5e8a80f04005/uvloop-0.22.1-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:0530a5fbad9c9e4ee3f2b33b148c6a64d47bbad8000ea63704fa8260f4cf728e", size = 4366890, upload-time = "2025-10-16T22:16:40.547Z" }, + { url = "https://files.pythonhosted.org/packages/d2/53/8369e5219a5855869bcee5f4d317f6da0e2c669aecf0ef7d371e3d084449/uvloop-0.22.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:bc5ef13bbc10b5335792360623cc378d52d7e62c2de64660616478c32cd0598e", size = 4119472, upload-time = "2025-10-16T22:16:41.694Z" }, + { url = "https://files.pythonhosted.org/packages/f8/ba/d69adbe699b768f6b29a5eec7b47dd610bd17a69de51b251126a801369ea/uvloop-0.22.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:1f38ec5e3f18c8a10ded09742f7fb8de0108796eb673f30ce7762ce1b8550cad", size = 4239051, upload-time = "2025-10-16T22:16:43.224Z" }, + { url = "https://files.pythonhosted.org/packages/90/cd/b62bdeaa429758aee8de8b00ac0dd26593a9de93d302bff3d21439e9791d/uvloop-0.22.1-cp314-cp314-macosx_10_13_universal2.whl", hash = "sha256:3879b88423ec7e97cd4eba2a443aa26ed4e59b45e6b76aabf13fe2f27023a142", size = 1362067, upload-time = "2025-10-16T22:16:44.503Z" }, + { url = "https://files.pythonhosted.org/packages/0d/f8/a132124dfda0777e489ca86732e85e69afcd1ff7686647000050ba670689/uvloop-0.22.1-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:4baa86acedf1d62115c1dc6ad1e17134476688f08c6efd8a2ab076e815665c74", size = 752423, upload-time = "2025-10-16T22:16:45.968Z" }, + { url = "https://files.pythonhosted.org/packages/a3/94/94af78c156f88da4b3a733773ad5ba0b164393e357cc4bd0ab2e2677a7d6/uvloop-0.22.1-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:297c27d8003520596236bdb2335e6b3f649480bd09e00d1e3a99144b691d2a35", size = 4272437, upload-time = "2025-10-16T22:16:47.451Z" }, + { url = "https://files.pythonhosted.org/packages/b5/35/60249e9fd07b32c665192cec7af29e06c7cd96fa1d08b84f012a56a0b38e/uvloop-0.22.1-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c1955d5a1dd43198244d47664a5858082a3239766a839b2102a269aaff7a4e25", size = 4292101, upload-time = "2025-10-16T22:16:49.318Z" }, + { url = "https://files.pythonhosted.org/packages/02/62/67d382dfcb25d0a98ce73c11ed1a6fba5037a1a1d533dcbb7cab033a2636/uvloop-0.22.1-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:b31dc2fccbd42adc73bc4e7cdbae4fc5086cf378979e53ca5d0301838c5682c6", size = 4114158, upload-time = "2025-10-16T22:16:50.517Z" }, + { url = "https://files.pythonhosted.org/packages/f0/7a/f1171b4a882a5d13c8b7576f348acfe6074d72eaf52cccef752f748d4a9f/uvloop-0.22.1-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:93f617675b2d03af4e72a5333ef89450dfaa5321303ede6e67ba9c9d26878079", size = 4177360, upload-time = "2025-10-16T22:16:52.646Z" }, + { url = "https://files.pythonhosted.org/packages/79/7b/b01414f31546caf0919da80ad57cbfe24c56b151d12af68cee1b04922ca8/uvloop-0.22.1-cp314-cp314t-macosx_10_13_universal2.whl", hash = "sha256:37554f70528f60cad66945b885eb01f1bb514f132d92b6eeed1c90fd54ed6289", size = 1454790, upload-time = "2025-10-16T22:16:54.355Z" }, + { url = "https://files.pythonhosted.org/packages/d4/31/0bb232318dd838cad3fa8fb0c68c8b40e1145b32025581975e18b11fab40/uvloop-0.22.1-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:b76324e2dc033a0b2f435f33eb88ff9913c156ef78e153fb210e03c13da746b3", size = 796783, upload-time = "2025-10-16T22:16:55.906Z" }, + { url = "https://files.pythonhosted.org/packages/42/38/c9b09f3271a7a723a5de69f8e237ab8e7803183131bc57c890db0b6bb872/uvloop-0.22.1-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:badb4d8e58ee08dad957002027830d5c3b06aea446a6a3744483c2b3b745345c", size = 4647548, upload-time = "2025-10-16T22:16:57.008Z" }, + { url = "https://files.pythonhosted.org/packages/c1/37/945b4ca0ac27e3dc4952642d4c900edd030b3da6c9634875af6e13ae80e5/uvloop-0.22.1-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:b91328c72635f6f9e0282e4a57da7470c7350ab1c9f48546c0f2866205349d21", size = 4467065, upload-time = "2025-10-16T22:16:58.206Z" }, + { url = "https://files.pythonhosted.org/packages/97/cc/48d232f33d60e2e2e0b42f4e73455b146b76ebe216487e862700457fbf3c/uvloop-0.22.1-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:daf620c2995d193449393d6c62131b3fbd40a63bf7b307a1527856ace637fe88", size = 4328384, upload-time = "2025-10-16T22:16:59.36Z" }, + { url = "https://files.pythonhosted.org/packages/e4/16/c1fd27e9549f3c4baf1dc9c20c456cd2f822dbf8de9f463824b0c0357e06/uvloop-0.22.1-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:6cde23eeda1a25c75b2e07d39970f3374105d5eafbaab2a4482be82f272d5a5e", size = 4296730, upload-time = "2025-10-16T22:17:00.744Z" }, ] [[package]] @@ -2342,74 +2367,74 @@ source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "anyio" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/c2/c9/8869df9b2a2d6c59d79220a4db37679e74f807c559ffe5265e08b227a210/watchfiles-1.1.1.tar.gz", hash = "sha256:a173cb5c16c4f40ab19cecf48a534c409f7ea983ab8fed0741304a1c0a31b3f2", size = 94440 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/bb/f4/f750b29225fe77139f7ae5de89d4949f5a99f934c65a1f1c0b248f26f747/watchfiles-1.1.1-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:130e4876309e8686a5e37dba7d5e9bc77e6ed908266996ca26572437a5271e18", size = 404321 }, - { url = "https://files.pythonhosted.org/packages/2b/f9/f07a295cde762644aa4c4bb0f88921d2d141af45e735b965fb2e87858328/watchfiles-1.1.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:5f3bde70f157f84ece3765b42b4a52c6ac1a50334903c6eaf765362f6ccca88a", size = 391783 }, - { url = "https://files.pythonhosted.org/packages/bc/11/fc2502457e0bea39a5c958d86d2cb69e407a4d00b85735ca724bfa6e0d1a/watchfiles-1.1.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:14e0b1fe858430fc0251737ef3824c54027bedb8c37c38114488b8e131cf8219", size = 449279 }, - { url = "https://files.pythonhosted.org/packages/e3/1f/d66bc15ea0b728df3ed96a539c777acfcad0eb78555ad9efcaa1274688f0/watchfiles-1.1.1-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:f27db948078f3823a6bb3b465180db8ebecf26dd5dae6f6180bd87383b6b4428", size = 459405 }, - { url = "https://files.pythonhosted.org/packages/be/90/9f4a65c0aec3ccf032703e6db02d89a157462fbb2cf20dd415128251cac0/watchfiles-1.1.1-cp313-cp313-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:059098c3a429f62fc98e8ec62b982230ef2c8df68c79e826e37b895bc359a9c0", size = 488976 }, - { url = "https://files.pythonhosted.org/packages/37/57/ee347af605d867f712be7029bb94c8c071732a4b44792e3176fa3c612d39/watchfiles-1.1.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:bfb5862016acc9b869bb57284e6cb35fdf8e22fe59f7548858e2f971d045f150", size = 595506 }, - { url = "https://files.pythonhosted.org/packages/a8/78/cc5ab0b86c122047f75e8fc471c67a04dee395daf847d3e59381996c8707/watchfiles-1.1.1-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:319b27255aacd9923b8a276bb14d21a5f7ff82564c744235fc5eae58d95422ae", size = 474936 }, - { url = "https://files.pythonhosted.org/packages/62/da/def65b170a3815af7bd40a3e7010bf6ab53089ef1b75d05dd5385b87cf08/watchfiles-1.1.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c755367e51db90e75b19454b680903631d41f9e3607fbd941d296a020c2d752d", size = 456147 }, - { url = "https://files.pythonhosted.org/packages/57/99/da6573ba71166e82d288d4df0839128004c67d2778d3b566c138695f5c0b/watchfiles-1.1.1-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:c22c776292a23bfc7237a98f791b9ad3144b02116ff10d820829ce62dff46d0b", size = 630007 }, - { url = "https://files.pythonhosted.org/packages/a8/51/7439c4dd39511368849eb1e53279cd3454b4a4dbace80bab88feeb83c6b5/watchfiles-1.1.1-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:3a476189be23c3686bc2f4321dd501cb329c0a0469e77b7b534ee10129ae6374", size = 622280 }, - { url = "https://files.pythonhosted.org/packages/95/9c/8ed97d4bba5db6fdcdb2b298d3898f2dd5c20f6b73aee04eabe56c59677e/watchfiles-1.1.1-cp313-cp313-win32.whl", hash = "sha256:bf0a91bfb5574a2f7fc223cf95eeea79abfefa404bf1ea5e339c0c1560ae99a0", size = 272056 }, - { url = "https://files.pythonhosted.org/packages/1f/f3/c14e28429f744a260d8ceae18bf58c1d5fa56b50d006a7a9f80e1882cb0d/watchfiles-1.1.1-cp313-cp313-win_amd64.whl", hash = "sha256:52e06553899e11e8074503c8e716d574adeeb7e68913115c4b3653c53f9bae42", size = 288162 }, - { url = "https://files.pythonhosted.org/packages/dc/61/fe0e56c40d5cd29523e398d31153218718c5786b5e636d9ae8ae79453d27/watchfiles-1.1.1-cp313-cp313-win_arm64.whl", hash = "sha256:ac3cc5759570cd02662b15fbcd9d917f7ecd47efe0d6b40474eafd246f91ea18", size = 277909 }, - { url = "https://files.pythonhosted.org/packages/79/42/e0a7d749626f1e28c7108a99fb9bf524b501bbbeb9b261ceecde644d5a07/watchfiles-1.1.1-cp313-cp313t-macosx_10_12_x86_64.whl", hash = "sha256:563b116874a9a7ce6f96f87cd0b94f7faf92d08d0021e837796f0a14318ef8da", size = 403389 }, - { url = "https://files.pythonhosted.org/packages/15/49/08732f90ce0fbbc13913f9f215c689cfc9ced345fb1bcd8829a50007cc8d/watchfiles-1.1.1-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:3ad9fe1dae4ab4212d8c91e80b832425e24f421703b5a42ef2e4a1e215aff051", size = 389964 }, - { url = "https://files.pythonhosted.org/packages/27/0d/7c315d4bd5f2538910491a0393c56bf70d333d51bc5b34bee8e68e8cea19/watchfiles-1.1.1-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ce70f96a46b894b36eba678f153f052967a0d06d5b5a19b336ab0dbbd029f73e", size = 448114 }, - { url = "https://files.pythonhosted.org/packages/c3/24/9e096de47a4d11bc4df41e9d1e61776393eac4cb6eb11b3e23315b78b2cc/watchfiles-1.1.1-cp313-cp313t-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:cb467c999c2eff23a6417e58d75e5828716f42ed8289fe6b77a7e5a91036ca70", size = 460264 }, - { url = "https://files.pythonhosted.org/packages/cc/0f/e8dea6375f1d3ba5fcb0b3583e2b493e77379834c74fd5a22d66d85d6540/watchfiles-1.1.1-cp313-cp313t-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:836398932192dae4146c8f6f737d74baeac8b70ce14831a239bdb1ca882fc261", size = 487877 }, - { url = "https://files.pythonhosted.org/packages/ac/5b/df24cfc6424a12deb41503b64d42fbea6b8cb357ec62ca84a5a3476f654a/watchfiles-1.1.1-cp313-cp313t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:743185e7372b7bc7c389e1badcc606931a827112fbbd37f14c537320fca08620", size = 595176 }, - { url = "https://files.pythonhosted.org/packages/8f/b5/853b6757f7347de4e9b37e8cc3289283fb983cba1ab4d2d7144694871d9c/watchfiles-1.1.1-cp313-cp313t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:afaeff7696e0ad9f02cbb8f56365ff4686ab205fcf9c4c5b6fdfaaa16549dd04", size = 473577 }, - { url = "https://files.pythonhosted.org/packages/e1/f7/0a4467be0a56e80447c8529c9fce5b38eab4f513cb3d9bf82e7392a5696b/watchfiles-1.1.1-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3f7eb7da0eb23aa2ba036d4f616d46906013a68caf61b7fdbe42fc8b25132e77", size = 455425 }, - { url = "https://files.pythonhosted.org/packages/8e/e0/82583485ea00137ddf69bc84a2db88bd92ab4a6e3c405e5fb878ead8d0e7/watchfiles-1.1.1-cp313-cp313t-musllinux_1_1_aarch64.whl", hash = "sha256:831a62658609f0e5c64178211c942ace999517f5770fe9436be4c2faeba0c0ef", size = 628826 }, - { url = "https://files.pythonhosted.org/packages/28/9a/a785356fccf9fae84c0cc90570f11702ae9571036fb25932f1242c82191c/watchfiles-1.1.1-cp313-cp313t-musllinux_1_1_x86_64.whl", hash = "sha256:f9a2ae5c91cecc9edd47e041a930490c31c3afb1f5e6d71de3dc671bfaca02bf", size = 622208 }, - { url = "https://files.pythonhosted.org/packages/c3/f4/0872229324ef69b2c3edec35e84bd57a1289e7d3fe74588048ed8947a323/watchfiles-1.1.1-cp314-cp314-macosx_10_12_x86_64.whl", hash = "sha256:d1715143123baeeaeadec0528bb7441103979a1d5f6fd0e1f915383fea7ea6d5", size = 404315 }, - { url = "https://files.pythonhosted.org/packages/7b/22/16d5331eaed1cb107b873f6ae1b69e9ced582fcf0c59a50cd84f403b1c32/watchfiles-1.1.1-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:39574d6370c4579d7f5d0ad940ce5b20db0e4117444e39b6d8f99db5676c52fd", size = 390869 }, - { url = "https://files.pythonhosted.org/packages/b2/7e/5643bfff5acb6539b18483128fdc0ef2cccc94a5b8fbda130c823e8ed636/watchfiles-1.1.1-cp314-cp314-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7365b92c2e69ee952902e8f70f3ba6360d0d596d9299d55d7d386df84b6941fb", size = 449919 }, - { url = "https://files.pythonhosted.org/packages/51/2e/c410993ba5025a9f9357c376f48976ef0e1b1aefb73b97a5ae01a5972755/watchfiles-1.1.1-cp314-cp314-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:bfff9740c69c0e4ed32416f013f3c45e2ae42ccedd1167ef2d805c000b6c71a5", size = 460845 }, - { url = "https://files.pythonhosted.org/packages/8e/a4/2df3b404469122e8680f0fcd06079317e48db58a2da2950fb45020947734/watchfiles-1.1.1-cp314-cp314-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b27cf2eb1dda37b2089e3907d8ea92922b673c0c427886d4edc6b94d8dfe5db3", size = 489027 }, - { url = "https://files.pythonhosted.org/packages/ea/84/4587ba5b1f267167ee715b7f66e6382cca6938e0a4b870adad93e44747e6/watchfiles-1.1.1-cp314-cp314-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:526e86aced14a65a5b0ec50827c745597c782ff46b571dbfe46192ab9e0b3c33", size = 595615 }, - { url = "https://files.pythonhosted.org/packages/6a/0f/c6988c91d06e93cd0bb3d4a808bcf32375ca1904609835c3031799e3ecae/watchfiles-1.1.1-cp314-cp314-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:04e78dd0b6352db95507fd8cb46f39d185cf8c74e4cf1e4fbad1d3df96faf510", size = 474836 }, - { url = "https://files.pythonhosted.org/packages/b4/36/ded8aebea91919485b7bbabbd14f5f359326cb5ec218cd67074d1e426d74/watchfiles-1.1.1-cp314-cp314-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5c85794a4cfa094714fb9c08d4a218375b2b95b8ed1666e8677c349906246c05", size = 455099 }, - { url = "https://files.pythonhosted.org/packages/98/e0/8c9bdba88af756a2fce230dd365fab2baf927ba42cd47521ee7498fd5211/watchfiles-1.1.1-cp314-cp314-musllinux_1_1_aarch64.whl", hash = "sha256:74d5012b7630714b66be7b7b7a78855ef7ad58e8650c73afc4c076a1f480a8d6", size = 630626 }, - { url = "https://files.pythonhosted.org/packages/2a/84/a95db05354bf2d19e438520d92a8ca475e578c647f78f53197f5a2f17aaf/watchfiles-1.1.1-cp314-cp314-musllinux_1_1_x86_64.whl", hash = "sha256:8fbe85cb3201c7d380d3d0b90e63d520f15d6afe217165d7f98c9c649654db81", size = 622519 }, - { url = "https://files.pythonhosted.org/packages/1d/ce/d8acdc8de545de995c339be67711e474c77d643555a9bb74a9334252bd55/watchfiles-1.1.1-cp314-cp314-win32.whl", hash = "sha256:3fa0b59c92278b5a7800d3ee7733da9d096d4aabcfabb9a928918bd276ef9b9b", size = 272078 }, - { url = "https://files.pythonhosted.org/packages/c4/c9/a74487f72d0451524be827e8edec251da0cc1fcf111646a511ae752e1a3d/watchfiles-1.1.1-cp314-cp314-win_amd64.whl", hash = "sha256:c2047d0b6cea13b3316bdbafbfa0c4228ae593d995030fda39089d36e64fc03a", size = 287664 }, - { url = "https://files.pythonhosted.org/packages/df/b8/8ac000702cdd496cdce998c6f4ee0ca1f15977bba51bdf07d872ebdfc34c/watchfiles-1.1.1-cp314-cp314-win_arm64.whl", hash = "sha256:842178b126593addc05acf6fce960d28bc5fae7afbaa2c6c1b3a7b9460e5be02", size = 277154 }, - { url = "https://files.pythonhosted.org/packages/47/a8/e3af2184707c29f0f14b1963c0aace6529f9d1b8582d5b99f31bbf42f59e/watchfiles-1.1.1-cp314-cp314t-macosx_10_12_x86_64.whl", hash = "sha256:88863fbbc1a7312972f1c511f202eb30866370ebb8493aef2812b9ff28156a21", size = 403820 }, - { url = "https://files.pythonhosted.org/packages/c0/ec/e47e307c2f4bd75f9f9e8afbe3876679b18e1bcec449beca132a1c5ffb2d/watchfiles-1.1.1-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:55c7475190662e202c08c6c0f4d9e345a29367438cf8e8037f3155e10a88d5a5", size = 390510 }, - { url = "https://files.pythonhosted.org/packages/d5/a0/ad235642118090f66e7b2f18fd5c42082418404a79205cdfca50b6309c13/watchfiles-1.1.1-cp314-cp314t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3f53fa183d53a1d7a8852277c92b967ae99c2d4dcee2bfacff8868e6e30b15f7", size = 448408 }, - { url = "https://files.pythonhosted.org/packages/df/85/97fa10fd5ff3332ae17e7e40e20784e419e28521549780869f1413742e9d/watchfiles-1.1.1-cp314-cp314t-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:6aae418a8b323732fa89721d86f39ec8f092fc2af67f4217a2b07fd3e93c6101", size = 458968 }, - { url = "https://files.pythonhosted.org/packages/47/c2/9059c2e8966ea5ce678166617a7f75ecba6164375f3b288e50a40dc6d489/watchfiles-1.1.1-cp314-cp314t-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f096076119da54a6080e8920cbdaac3dbee667eb91dcc5e5b78840b87415bd44", size = 488096 }, - { url = "https://files.pythonhosted.org/packages/94/44/d90a9ec8ac309bc26db808a13e7bfc0e4e78b6fc051078a554e132e80160/watchfiles-1.1.1-cp314-cp314t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:00485f441d183717038ed2e887a7c868154f216877653121068107b227a2f64c", size = 596040 }, - { url = "https://files.pythonhosted.org/packages/95/68/4e3479b20ca305cfc561db3ed207a8a1c745ee32bf24f2026a129d0ddb6e/watchfiles-1.1.1-cp314-cp314t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a55f3e9e493158d7bfdb60a1165035f1cf7d320914e7b7ea83fe22c6023b58fc", size = 473847 }, - { url = "https://files.pythonhosted.org/packages/4f/55/2af26693fd15165c4ff7857e38330e1b61ab8c37d15dc79118cdba115b7a/watchfiles-1.1.1-cp314-cp314t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8c91ed27800188c2ae96d16e3149f199d62f86c7af5f5f4d2c61a3ed8cd3666c", size = 455072 }, - { url = "https://files.pythonhosted.org/packages/66/1d/d0d200b10c9311ec25d2273f8aad8c3ef7cc7ea11808022501811208a750/watchfiles-1.1.1-cp314-cp314t-musllinux_1_1_aarch64.whl", hash = "sha256:311ff15a0bae3714ffb603e6ba6dbfba4065ab60865d15a6ec544133bdb21099", size = 629104 }, - { url = "https://files.pythonhosted.org/packages/e3/bd/fa9bb053192491b3867ba07d2343d9f2252e00811567d30ae8d0f78136fe/watchfiles-1.1.1-cp314-cp314t-musllinux_1_1_x86_64.whl", hash = "sha256:a916a2932da8f8ab582f242c065f5c81bed3462849ca79ee357dd9551b0e9b01", size = 622112 }, +sdist = { url = "https://files.pythonhosted.org/packages/c2/c9/8869df9b2a2d6c59d79220a4db37679e74f807c559ffe5265e08b227a210/watchfiles-1.1.1.tar.gz", hash = "sha256:a173cb5c16c4f40ab19cecf48a534c409f7ea983ab8fed0741304a1c0a31b3f2", size = 94440, upload-time = "2025-10-14T15:06:21.08Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/bb/f4/f750b29225fe77139f7ae5de89d4949f5a99f934c65a1f1c0b248f26f747/watchfiles-1.1.1-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:130e4876309e8686a5e37dba7d5e9bc77e6ed908266996ca26572437a5271e18", size = 404321, upload-time = "2025-10-14T15:05:02.063Z" }, + { url = "https://files.pythonhosted.org/packages/2b/f9/f07a295cde762644aa4c4bb0f88921d2d141af45e735b965fb2e87858328/watchfiles-1.1.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:5f3bde70f157f84ece3765b42b4a52c6ac1a50334903c6eaf765362f6ccca88a", size = 391783, upload-time = "2025-10-14T15:05:03.052Z" }, + { url = "https://files.pythonhosted.org/packages/bc/11/fc2502457e0bea39a5c958d86d2cb69e407a4d00b85735ca724bfa6e0d1a/watchfiles-1.1.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:14e0b1fe858430fc0251737ef3824c54027bedb8c37c38114488b8e131cf8219", size = 449279, upload-time = "2025-10-14T15:05:04.004Z" }, + { url = "https://files.pythonhosted.org/packages/e3/1f/d66bc15ea0b728df3ed96a539c777acfcad0eb78555ad9efcaa1274688f0/watchfiles-1.1.1-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:f27db948078f3823a6bb3b465180db8ebecf26dd5dae6f6180bd87383b6b4428", size = 459405, upload-time = "2025-10-14T15:05:04.942Z" }, + { url = "https://files.pythonhosted.org/packages/be/90/9f4a65c0aec3ccf032703e6db02d89a157462fbb2cf20dd415128251cac0/watchfiles-1.1.1-cp313-cp313-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:059098c3a429f62fc98e8ec62b982230ef2c8df68c79e826e37b895bc359a9c0", size = 488976, upload-time = "2025-10-14T15:05:05.905Z" }, + { url = "https://files.pythonhosted.org/packages/37/57/ee347af605d867f712be7029bb94c8c071732a4b44792e3176fa3c612d39/watchfiles-1.1.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:bfb5862016acc9b869bb57284e6cb35fdf8e22fe59f7548858e2f971d045f150", size = 595506, upload-time = "2025-10-14T15:05:06.906Z" }, + { url = "https://files.pythonhosted.org/packages/a8/78/cc5ab0b86c122047f75e8fc471c67a04dee395daf847d3e59381996c8707/watchfiles-1.1.1-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:319b27255aacd9923b8a276bb14d21a5f7ff82564c744235fc5eae58d95422ae", size = 474936, upload-time = "2025-10-14T15:05:07.906Z" }, + { url = "https://files.pythonhosted.org/packages/62/da/def65b170a3815af7bd40a3e7010bf6ab53089ef1b75d05dd5385b87cf08/watchfiles-1.1.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c755367e51db90e75b19454b680903631d41f9e3607fbd941d296a020c2d752d", size = 456147, upload-time = "2025-10-14T15:05:09.138Z" }, + { url = "https://files.pythonhosted.org/packages/57/99/da6573ba71166e82d288d4df0839128004c67d2778d3b566c138695f5c0b/watchfiles-1.1.1-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:c22c776292a23bfc7237a98f791b9ad3144b02116ff10d820829ce62dff46d0b", size = 630007, upload-time = "2025-10-14T15:05:10.117Z" }, + { url = "https://files.pythonhosted.org/packages/a8/51/7439c4dd39511368849eb1e53279cd3454b4a4dbace80bab88feeb83c6b5/watchfiles-1.1.1-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:3a476189be23c3686bc2f4321dd501cb329c0a0469e77b7b534ee10129ae6374", size = 622280, upload-time = "2025-10-14T15:05:11.146Z" }, + { url = "https://files.pythonhosted.org/packages/95/9c/8ed97d4bba5db6fdcdb2b298d3898f2dd5c20f6b73aee04eabe56c59677e/watchfiles-1.1.1-cp313-cp313-win32.whl", hash = "sha256:bf0a91bfb5574a2f7fc223cf95eeea79abfefa404bf1ea5e339c0c1560ae99a0", size = 272056, upload-time = "2025-10-14T15:05:12.156Z" }, + { url = "https://files.pythonhosted.org/packages/1f/f3/c14e28429f744a260d8ceae18bf58c1d5fa56b50d006a7a9f80e1882cb0d/watchfiles-1.1.1-cp313-cp313-win_amd64.whl", hash = "sha256:52e06553899e11e8074503c8e716d574adeeb7e68913115c4b3653c53f9bae42", size = 288162, upload-time = "2025-10-14T15:05:13.208Z" }, + { url = "https://files.pythonhosted.org/packages/dc/61/fe0e56c40d5cd29523e398d31153218718c5786b5e636d9ae8ae79453d27/watchfiles-1.1.1-cp313-cp313-win_arm64.whl", hash = "sha256:ac3cc5759570cd02662b15fbcd9d917f7ecd47efe0d6b40474eafd246f91ea18", size = 277909, upload-time = "2025-10-14T15:05:14.49Z" }, + { url = "https://files.pythonhosted.org/packages/79/42/e0a7d749626f1e28c7108a99fb9bf524b501bbbeb9b261ceecde644d5a07/watchfiles-1.1.1-cp313-cp313t-macosx_10_12_x86_64.whl", hash = "sha256:563b116874a9a7ce6f96f87cd0b94f7faf92d08d0021e837796f0a14318ef8da", size = 403389, upload-time = "2025-10-14T15:05:15.777Z" }, + { url = "https://files.pythonhosted.org/packages/15/49/08732f90ce0fbbc13913f9f215c689cfc9ced345fb1bcd8829a50007cc8d/watchfiles-1.1.1-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:3ad9fe1dae4ab4212d8c91e80b832425e24f421703b5a42ef2e4a1e215aff051", size = 389964, upload-time = "2025-10-14T15:05:16.85Z" }, + { url = "https://files.pythonhosted.org/packages/27/0d/7c315d4bd5f2538910491a0393c56bf70d333d51bc5b34bee8e68e8cea19/watchfiles-1.1.1-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ce70f96a46b894b36eba678f153f052967a0d06d5b5a19b336ab0dbbd029f73e", size = 448114, upload-time = "2025-10-14T15:05:17.876Z" }, + { url = "https://files.pythonhosted.org/packages/c3/24/9e096de47a4d11bc4df41e9d1e61776393eac4cb6eb11b3e23315b78b2cc/watchfiles-1.1.1-cp313-cp313t-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:cb467c999c2eff23a6417e58d75e5828716f42ed8289fe6b77a7e5a91036ca70", size = 460264, upload-time = "2025-10-14T15:05:18.962Z" }, + { url = "https://files.pythonhosted.org/packages/cc/0f/e8dea6375f1d3ba5fcb0b3583e2b493e77379834c74fd5a22d66d85d6540/watchfiles-1.1.1-cp313-cp313t-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:836398932192dae4146c8f6f737d74baeac8b70ce14831a239bdb1ca882fc261", size = 487877, upload-time = "2025-10-14T15:05:20.094Z" }, + { url = "https://files.pythonhosted.org/packages/ac/5b/df24cfc6424a12deb41503b64d42fbea6b8cb357ec62ca84a5a3476f654a/watchfiles-1.1.1-cp313-cp313t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:743185e7372b7bc7c389e1badcc606931a827112fbbd37f14c537320fca08620", size = 595176, upload-time = "2025-10-14T15:05:21.134Z" }, + { url = "https://files.pythonhosted.org/packages/8f/b5/853b6757f7347de4e9b37e8cc3289283fb983cba1ab4d2d7144694871d9c/watchfiles-1.1.1-cp313-cp313t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:afaeff7696e0ad9f02cbb8f56365ff4686ab205fcf9c4c5b6fdfaaa16549dd04", size = 473577, upload-time = "2025-10-14T15:05:22.306Z" }, + { url = "https://files.pythonhosted.org/packages/e1/f7/0a4467be0a56e80447c8529c9fce5b38eab4f513cb3d9bf82e7392a5696b/watchfiles-1.1.1-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3f7eb7da0eb23aa2ba036d4f616d46906013a68caf61b7fdbe42fc8b25132e77", size = 455425, upload-time = "2025-10-14T15:05:23.348Z" }, + { url = "https://files.pythonhosted.org/packages/8e/e0/82583485ea00137ddf69bc84a2db88bd92ab4a6e3c405e5fb878ead8d0e7/watchfiles-1.1.1-cp313-cp313t-musllinux_1_1_aarch64.whl", hash = "sha256:831a62658609f0e5c64178211c942ace999517f5770fe9436be4c2faeba0c0ef", size = 628826, upload-time = "2025-10-14T15:05:24.398Z" }, + { url = "https://files.pythonhosted.org/packages/28/9a/a785356fccf9fae84c0cc90570f11702ae9571036fb25932f1242c82191c/watchfiles-1.1.1-cp313-cp313t-musllinux_1_1_x86_64.whl", hash = "sha256:f9a2ae5c91cecc9edd47e041a930490c31c3afb1f5e6d71de3dc671bfaca02bf", size = 622208, upload-time = "2025-10-14T15:05:25.45Z" }, + { url = "https://files.pythonhosted.org/packages/c3/f4/0872229324ef69b2c3edec35e84bd57a1289e7d3fe74588048ed8947a323/watchfiles-1.1.1-cp314-cp314-macosx_10_12_x86_64.whl", hash = "sha256:d1715143123baeeaeadec0528bb7441103979a1d5f6fd0e1f915383fea7ea6d5", size = 404315, upload-time = "2025-10-14T15:05:26.501Z" }, + { url = "https://files.pythonhosted.org/packages/7b/22/16d5331eaed1cb107b873f6ae1b69e9ced582fcf0c59a50cd84f403b1c32/watchfiles-1.1.1-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:39574d6370c4579d7f5d0ad940ce5b20db0e4117444e39b6d8f99db5676c52fd", size = 390869, upload-time = "2025-10-14T15:05:27.649Z" }, + { url = "https://files.pythonhosted.org/packages/b2/7e/5643bfff5acb6539b18483128fdc0ef2cccc94a5b8fbda130c823e8ed636/watchfiles-1.1.1-cp314-cp314-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7365b92c2e69ee952902e8f70f3ba6360d0d596d9299d55d7d386df84b6941fb", size = 449919, upload-time = "2025-10-14T15:05:28.701Z" }, + { url = "https://files.pythonhosted.org/packages/51/2e/c410993ba5025a9f9357c376f48976ef0e1b1aefb73b97a5ae01a5972755/watchfiles-1.1.1-cp314-cp314-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:bfff9740c69c0e4ed32416f013f3c45e2ae42ccedd1167ef2d805c000b6c71a5", size = 460845, upload-time = "2025-10-14T15:05:30.064Z" }, + { url = "https://files.pythonhosted.org/packages/8e/a4/2df3b404469122e8680f0fcd06079317e48db58a2da2950fb45020947734/watchfiles-1.1.1-cp314-cp314-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b27cf2eb1dda37b2089e3907d8ea92922b673c0c427886d4edc6b94d8dfe5db3", size = 489027, upload-time = "2025-10-14T15:05:31.064Z" }, + { url = "https://files.pythonhosted.org/packages/ea/84/4587ba5b1f267167ee715b7f66e6382cca6938e0a4b870adad93e44747e6/watchfiles-1.1.1-cp314-cp314-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:526e86aced14a65a5b0ec50827c745597c782ff46b571dbfe46192ab9e0b3c33", size = 595615, upload-time = "2025-10-14T15:05:32.074Z" }, + { url = "https://files.pythonhosted.org/packages/6a/0f/c6988c91d06e93cd0bb3d4a808bcf32375ca1904609835c3031799e3ecae/watchfiles-1.1.1-cp314-cp314-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:04e78dd0b6352db95507fd8cb46f39d185cf8c74e4cf1e4fbad1d3df96faf510", size = 474836, upload-time = "2025-10-14T15:05:33.209Z" }, + { url = "https://files.pythonhosted.org/packages/b4/36/ded8aebea91919485b7bbabbd14f5f359326cb5ec218cd67074d1e426d74/watchfiles-1.1.1-cp314-cp314-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5c85794a4cfa094714fb9c08d4a218375b2b95b8ed1666e8677c349906246c05", size = 455099, upload-time = "2025-10-14T15:05:34.189Z" }, + { url = "https://files.pythonhosted.org/packages/98/e0/8c9bdba88af756a2fce230dd365fab2baf927ba42cd47521ee7498fd5211/watchfiles-1.1.1-cp314-cp314-musllinux_1_1_aarch64.whl", hash = "sha256:74d5012b7630714b66be7b7b7a78855ef7ad58e8650c73afc4c076a1f480a8d6", size = 630626, upload-time = "2025-10-14T15:05:35.216Z" }, + { url = "https://files.pythonhosted.org/packages/2a/84/a95db05354bf2d19e438520d92a8ca475e578c647f78f53197f5a2f17aaf/watchfiles-1.1.1-cp314-cp314-musllinux_1_1_x86_64.whl", hash = "sha256:8fbe85cb3201c7d380d3d0b90e63d520f15d6afe217165d7f98c9c649654db81", size = 622519, upload-time = "2025-10-14T15:05:36.259Z" }, + { url = "https://files.pythonhosted.org/packages/1d/ce/d8acdc8de545de995c339be67711e474c77d643555a9bb74a9334252bd55/watchfiles-1.1.1-cp314-cp314-win32.whl", hash = "sha256:3fa0b59c92278b5a7800d3ee7733da9d096d4aabcfabb9a928918bd276ef9b9b", size = 272078, upload-time = "2025-10-14T15:05:37.63Z" }, + { url = "https://files.pythonhosted.org/packages/c4/c9/a74487f72d0451524be827e8edec251da0cc1fcf111646a511ae752e1a3d/watchfiles-1.1.1-cp314-cp314-win_amd64.whl", hash = "sha256:c2047d0b6cea13b3316bdbafbfa0c4228ae593d995030fda39089d36e64fc03a", size = 287664, upload-time = "2025-10-14T15:05:38.95Z" }, + { url = "https://files.pythonhosted.org/packages/df/b8/8ac000702cdd496cdce998c6f4ee0ca1f15977bba51bdf07d872ebdfc34c/watchfiles-1.1.1-cp314-cp314-win_arm64.whl", hash = "sha256:842178b126593addc05acf6fce960d28bc5fae7afbaa2c6c1b3a7b9460e5be02", size = 277154, upload-time = "2025-10-14T15:05:39.954Z" }, + { url = "https://files.pythonhosted.org/packages/47/a8/e3af2184707c29f0f14b1963c0aace6529f9d1b8582d5b99f31bbf42f59e/watchfiles-1.1.1-cp314-cp314t-macosx_10_12_x86_64.whl", hash = "sha256:88863fbbc1a7312972f1c511f202eb30866370ebb8493aef2812b9ff28156a21", size = 403820, upload-time = "2025-10-14T15:05:40.932Z" }, + { url = "https://files.pythonhosted.org/packages/c0/ec/e47e307c2f4bd75f9f9e8afbe3876679b18e1bcec449beca132a1c5ffb2d/watchfiles-1.1.1-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:55c7475190662e202c08c6c0f4d9e345a29367438cf8e8037f3155e10a88d5a5", size = 390510, upload-time = "2025-10-14T15:05:41.945Z" }, + { url = "https://files.pythonhosted.org/packages/d5/a0/ad235642118090f66e7b2f18fd5c42082418404a79205cdfca50b6309c13/watchfiles-1.1.1-cp314-cp314t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3f53fa183d53a1d7a8852277c92b967ae99c2d4dcee2bfacff8868e6e30b15f7", size = 448408, upload-time = "2025-10-14T15:05:43.385Z" }, + { url = "https://files.pythonhosted.org/packages/df/85/97fa10fd5ff3332ae17e7e40e20784e419e28521549780869f1413742e9d/watchfiles-1.1.1-cp314-cp314t-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:6aae418a8b323732fa89721d86f39ec8f092fc2af67f4217a2b07fd3e93c6101", size = 458968, upload-time = "2025-10-14T15:05:44.404Z" }, + { url = "https://files.pythonhosted.org/packages/47/c2/9059c2e8966ea5ce678166617a7f75ecba6164375f3b288e50a40dc6d489/watchfiles-1.1.1-cp314-cp314t-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f096076119da54a6080e8920cbdaac3dbee667eb91dcc5e5b78840b87415bd44", size = 488096, upload-time = "2025-10-14T15:05:45.398Z" }, + { url = "https://files.pythonhosted.org/packages/94/44/d90a9ec8ac309bc26db808a13e7bfc0e4e78b6fc051078a554e132e80160/watchfiles-1.1.1-cp314-cp314t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:00485f441d183717038ed2e887a7c868154f216877653121068107b227a2f64c", size = 596040, upload-time = "2025-10-14T15:05:46.502Z" }, + { url = "https://files.pythonhosted.org/packages/95/68/4e3479b20ca305cfc561db3ed207a8a1c745ee32bf24f2026a129d0ddb6e/watchfiles-1.1.1-cp314-cp314t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a55f3e9e493158d7bfdb60a1165035f1cf7d320914e7b7ea83fe22c6023b58fc", size = 473847, upload-time = "2025-10-14T15:05:47.484Z" }, + { url = "https://files.pythonhosted.org/packages/4f/55/2af26693fd15165c4ff7857e38330e1b61ab8c37d15dc79118cdba115b7a/watchfiles-1.1.1-cp314-cp314t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8c91ed27800188c2ae96d16e3149f199d62f86c7af5f5f4d2c61a3ed8cd3666c", size = 455072, upload-time = "2025-10-14T15:05:48.928Z" }, + { url = "https://files.pythonhosted.org/packages/66/1d/d0d200b10c9311ec25d2273f8aad8c3ef7cc7ea11808022501811208a750/watchfiles-1.1.1-cp314-cp314t-musllinux_1_1_aarch64.whl", hash = "sha256:311ff15a0bae3714ffb603e6ba6dbfba4065ab60865d15a6ec544133bdb21099", size = 629104, upload-time = "2025-10-14T15:05:49.908Z" }, + { url = "https://files.pythonhosted.org/packages/e3/bd/fa9bb053192491b3867ba07d2343d9f2252e00811567d30ae8d0f78136fe/watchfiles-1.1.1-cp314-cp314t-musllinux_1_1_x86_64.whl", hash = "sha256:a916a2932da8f8ab582f242c065f5c81bed3462849ca79ee357dd9551b0e9b01", size = 622112, upload-time = "2025-10-14T15:05:50.941Z" }, ] [[package]] name = "websockets" version = "15.0.1" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/21/e6/26d09fab466b7ca9c7737474c52be4f76a40301b08362eb2dbc19dcc16c1/websockets-15.0.1.tar.gz", hash = "sha256:82544de02076bafba038ce055ee6412d68da13ab47f0c60cab827346de828dee", size = 177016 } +sdist = { url = "https://files.pythonhosted.org/packages/21/e6/26d09fab466b7ca9c7737474c52be4f76a40301b08362eb2dbc19dcc16c1/websockets-15.0.1.tar.gz", hash = "sha256:82544de02076bafba038ce055ee6412d68da13ab47f0c60cab827346de828dee", size = 177016, upload-time = "2025-03-05T20:03:41.606Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/cb/9f/51f0cf64471a9d2b4d0fc6c534f323b664e7095640c34562f5182e5a7195/websockets-15.0.1-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:ee443ef070bb3b6ed74514f5efaa37a252af57c90eb33b956d35c8e9c10a1931", size = 175440 }, - { url = "https://files.pythonhosted.org/packages/8a/05/aa116ec9943c718905997412c5989f7ed671bc0188ee2ba89520e8765d7b/websockets-15.0.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:5a939de6b7b4e18ca683218320fc67ea886038265fd1ed30173f5ce3f8e85675", size = 173098 }, - { url = "https://files.pythonhosted.org/packages/ff/0b/33cef55ff24f2d92924923c99926dcce78e7bd922d649467f0eda8368923/websockets-15.0.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:746ee8dba912cd6fc889a8147168991d50ed70447bf18bcda7039f7d2e3d9151", size = 173329 }, - { url = "https://files.pythonhosted.org/packages/31/1d/063b25dcc01faa8fada1469bdf769de3768b7044eac9d41f734fd7b6ad6d/websockets-15.0.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:595b6c3969023ecf9041b2936ac3827e4623bfa3ccf007575f04c5a6aa318c22", size = 183111 }, - { url = "https://files.pythonhosted.org/packages/93/53/9a87ee494a51bf63e4ec9241c1ccc4f7c2f45fff85d5bde2ff74fcb68b9e/websockets-15.0.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3c714d2fc58b5ca3e285461a4cc0c9a66bd0e24c5da9911e30158286c9b5be7f", size = 182054 }, - { url = "https://files.pythonhosted.org/packages/ff/b2/83a6ddf56cdcbad4e3d841fcc55d6ba7d19aeb89c50f24dd7e859ec0805f/websockets-15.0.1-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0f3c1e2ab208db911594ae5b4f79addeb3501604a165019dd221c0bdcabe4db8", size = 182496 }, - { url = "https://files.pythonhosted.org/packages/98/41/e7038944ed0abf34c45aa4635ba28136f06052e08fc2168520bb8b25149f/websockets-15.0.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:229cf1d3ca6c1804400b0a9790dc66528e08a6a1feec0d5040e8b9eb14422375", size = 182829 }, - { url = "https://files.pythonhosted.org/packages/e0/17/de15b6158680c7623c6ef0db361da965ab25d813ae54fcfeae2e5b9ef910/websockets-15.0.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:756c56e867a90fb00177d530dca4b097dd753cde348448a1012ed6c5131f8b7d", size = 182217 }, - { url = "https://files.pythonhosted.org/packages/33/2b/1f168cb6041853eef0362fb9554c3824367c5560cbdaad89ac40f8c2edfc/websockets-15.0.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:558d023b3df0bffe50a04e710bc87742de35060580a293c2a984299ed83bc4e4", size = 182195 }, - { url = "https://files.pythonhosted.org/packages/86/eb/20b6cdf273913d0ad05a6a14aed4b9a85591c18a987a3d47f20fa13dcc47/websockets-15.0.1-cp313-cp313-win32.whl", hash = "sha256:ba9e56e8ceeeedb2e080147ba85ffcd5cd0711b89576b83784d8605a7df455fa", size = 176393 }, - { url = "https://files.pythonhosted.org/packages/1b/6c/c65773d6cab416a64d191d6ee8a8b1c68a09970ea6909d16965d26bfed1e/websockets-15.0.1-cp313-cp313-win_amd64.whl", hash = "sha256:e09473f095a819042ecb2ab9465aee615bd9c2028e4ef7d933600a8401c79561", size = 176837 }, - { url = "https://files.pythonhosted.org/packages/fa/a8/5b41e0da817d64113292ab1f8247140aac61cbf6cfd085d6a0fa77f4984f/websockets-15.0.1-py3-none-any.whl", hash = "sha256:f7a866fbc1e97b5c617ee4116daaa09b722101d4a3c170c787450ba409f9736f", size = 169743 }, + { url = "https://files.pythonhosted.org/packages/cb/9f/51f0cf64471a9d2b4d0fc6c534f323b664e7095640c34562f5182e5a7195/websockets-15.0.1-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:ee443ef070bb3b6ed74514f5efaa37a252af57c90eb33b956d35c8e9c10a1931", size = 175440, upload-time = "2025-03-05T20:02:36.695Z" }, + { url = "https://files.pythonhosted.org/packages/8a/05/aa116ec9943c718905997412c5989f7ed671bc0188ee2ba89520e8765d7b/websockets-15.0.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:5a939de6b7b4e18ca683218320fc67ea886038265fd1ed30173f5ce3f8e85675", size = 173098, upload-time = "2025-03-05T20:02:37.985Z" }, + { url = "https://files.pythonhosted.org/packages/ff/0b/33cef55ff24f2d92924923c99926dcce78e7bd922d649467f0eda8368923/websockets-15.0.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:746ee8dba912cd6fc889a8147168991d50ed70447bf18bcda7039f7d2e3d9151", size = 173329, upload-time = "2025-03-05T20:02:39.298Z" }, + { url = "https://files.pythonhosted.org/packages/31/1d/063b25dcc01faa8fada1469bdf769de3768b7044eac9d41f734fd7b6ad6d/websockets-15.0.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:595b6c3969023ecf9041b2936ac3827e4623bfa3ccf007575f04c5a6aa318c22", size = 183111, upload-time = "2025-03-05T20:02:40.595Z" }, + { url = "https://files.pythonhosted.org/packages/93/53/9a87ee494a51bf63e4ec9241c1ccc4f7c2f45fff85d5bde2ff74fcb68b9e/websockets-15.0.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3c714d2fc58b5ca3e285461a4cc0c9a66bd0e24c5da9911e30158286c9b5be7f", size = 182054, upload-time = "2025-03-05T20:02:41.926Z" }, + { url = "https://files.pythonhosted.org/packages/ff/b2/83a6ddf56cdcbad4e3d841fcc55d6ba7d19aeb89c50f24dd7e859ec0805f/websockets-15.0.1-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0f3c1e2ab208db911594ae5b4f79addeb3501604a165019dd221c0bdcabe4db8", size = 182496, upload-time = "2025-03-05T20:02:43.304Z" }, + { url = "https://files.pythonhosted.org/packages/98/41/e7038944ed0abf34c45aa4635ba28136f06052e08fc2168520bb8b25149f/websockets-15.0.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:229cf1d3ca6c1804400b0a9790dc66528e08a6a1feec0d5040e8b9eb14422375", size = 182829, upload-time = "2025-03-05T20:02:48.812Z" }, + { url = "https://files.pythonhosted.org/packages/e0/17/de15b6158680c7623c6ef0db361da965ab25d813ae54fcfeae2e5b9ef910/websockets-15.0.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:756c56e867a90fb00177d530dca4b097dd753cde348448a1012ed6c5131f8b7d", size = 182217, upload-time = "2025-03-05T20:02:50.14Z" }, + { url = "https://files.pythonhosted.org/packages/33/2b/1f168cb6041853eef0362fb9554c3824367c5560cbdaad89ac40f8c2edfc/websockets-15.0.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:558d023b3df0bffe50a04e710bc87742de35060580a293c2a984299ed83bc4e4", size = 182195, upload-time = "2025-03-05T20:02:51.561Z" }, + { url = "https://files.pythonhosted.org/packages/86/eb/20b6cdf273913d0ad05a6a14aed4b9a85591c18a987a3d47f20fa13dcc47/websockets-15.0.1-cp313-cp313-win32.whl", hash = "sha256:ba9e56e8ceeeedb2e080147ba85ffcd5cd0711b89576b83784d8605a7df455fa", size = 176393, upload-time = "2025-03-05T20:02:53.814Z" }, + { url = "https://files.pythonhosted.org/packages/1b/6c/c65773d6cab416a64d191d6ee8a8b1c68a09970ea6909d16965d26bfed1e/websockets-15.0.1-cp313-cp313-win_amd64.whl", hash = "sha256:e09473f095a819042ecb2ab9465aee615bd9c2028e4ef7d933600a8401c79561", size = 176837, upload-time = "2025-03-05T20:02:55.237Z" }, + { url = "https://files.pythonhosted.org/packages/fa/a8/5b41e0da817d64113292ab1f8247140aac61cbf6cfd085d6a0fa77f4984f/websockets-15.0.1-py3-none-any.whl", hash = "sha256:f7a866fbc1e97b5c617ee4116daaa09b722101d4a3c170c787450ba409f9736f", size = 169743, upload-time = "2025-03-05T20:03:39.41Z" }, ] [[package]] @@ -2419,7 +2444,7 @@ source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "markupsafe" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/6a/c7/96d10183c3470f1836846f7b9527d6cb0b6c2226ebca40f36fa29f23de60/wtforms-3.1.2.tar.gz", hash = "sha256:f8d76180d7239c94c6322f7990ae1216dae3659b7aa1cee94b6318bdffb474b9", size = 134705 } +sdist = { url = "https://files.pythonhosted.org/packages/6a/c7/96d10183c3470f1836846f7b9527d6cb0b6c2226ebca40f36fa29f23de60/wtforms-3.1.2.tar.gz", hash = "sha256:f8d76180d7239c94c6322f7990ae1216dae3659b7aa1cee94b6318bdffb474b9", size = 134705, upload-time = "2024-01-06T07:52:41.075Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/18/19/c3232f35e24dccfad372e9f341c4f3a1166ae7c66e4e1351a9467c921cc1/wtforms-3.1.2-py3-none-any.whl", hash = "sha256:bf831c042829c8cdbad74c27575098d541d039b1faa74c771545ecac916f2c07", size = 145961 }, + { url = "https://files.pythonhosted.org/packages/18/19/c3232f35e24dccfad372e9f341c4f3a1166ae7c66e4e1351a9467c921cc1/wtforms-3.1.2-py3-none-any.whl", hash = "sha256:bf831c042829c8cdbad74c27575098d541d039b1faa74c771545ecac916f2c07", size = 145961, upload-time = "2024-01-06T07:52:43.023Z" }, ] diff --git a/codemeta.json b/codemeta.json index 9d940b3..f3704e5 100644 --- a/codemeta.json +++ b/codemeta.json @@ -42,7 +42,7 @@ ], "license": "https://spdx.org/licenses/AGPL-3.0-or-later", "name": "Reverse Engineering Lab", - "programmingLanguage": ["Python 3.13", "JavaScript"], + "programmingLanguage": ["Python 3.14", "JavaScript"], "softwareRequirements": "Docker", "version": "0.1.0" } From 5bd435c30f063ede66c2c2c03fd6bc50dae5bd30 Mon Sep 17 00:00:00 2001 From: Simon van Lierde Date: Sat, 8 Nov 2025 11:02:31 +0100 Subject: [PATCH 35/71] fix(backend): Init disposable email checker without Redis if no Redis connection available --- .../app/api/auth/utils/email_validation.py | 21 ++++++++++++------- backend/app/main.py | 13 ++++++------ 2 files changed, 19 insertions(+), 15 deletions(-) diff --git a/backend/app/api/auth/utils/email_validation.py b/backend/app/api/auth/utils/email_validation.py index 79e908b..6d5275f 100644 --- a/backend/app/api/auth/utils/email_validation.py +++ b/backend/app/api/auth/utils/email_validation.py @@ -18,7 +18,7 @@ class EmailChecker: """Email checker that manages disposable domain validation.""" - def __init__(self, redis_client: Redis) -> None: + def __init__(self, redis_client: Redis | None) -> None: """Initialize email checker with Redis client. Args: @@ -34,13 +34,17 @@ async def initialize(self) -> None: Should be called during application startup. """ try: - self.checker = DefaultChecker( - source=DISPOSABLE_DOMAINS_URL, - db_provider="redis", - redis_client=self.redis_client, + if self.redis_client is None: + self.checker = DefaultChecker(source=DISPOSABLE_DOMAINS_URL) + logger.info("Disposable email checker initialized without Redis") + else: + self.checker = DefaultChecker( + source=DISPOSABLE_DOMAINS_URL, + db_provider="redis", + redis_client=self.redis_client, ) - await self.checker.init_redis() - logger.info("Disposable email checker initialized successfully") + await self.checker.init_redis() + logger.info("Disposable email checker initialized with Redis") # Fetch initial domains await self._refresh_domains() @@ -87,7 +91,8 @@ async def close(self) -> None: await self._refresh_task # Close checker connections if initialized - if self.checker is not None: + if self.checker is not None and self.redis_client is not None: + logger.info("Closing email checker Redis connections") try: await self.checker.close_connections() logger.info("Email checker closed successfully") diff --git a/backend/app/main.py b/backend/app/main.py index 7d0757f..4b8807b 100644 --- a/backend/app/main.py +++ b/backend/app/main.py @@ -40,13 +40,12 @@ async def lifespan(app: FastAPI) -> AsyncGenerator: # Initialize disposable email checker and store in app.state app.state.email_checker = None - if app.state.redis is not None: - try: - email_checker = EmailChecker(app.state.redis) - await email_checker.initialize() - app.state.email_checker = email_checker - except (RuntimeError, ValueError, ConnectionError) as e: - logger.warning("Failed to initialize email checker: %s", e) + try: + email_checker = EmailChecker(app.state.redis) + await email_checker.initialize() + app.state.email_checker = email_checker + except (RuntimeError, ValueError, ConnectionError) as e: + logger.warning("Failed to initialize email checker: %s", e) logger.info("Application startup complete") From a0e45336bf32b4f856b0e7c4e4558582db447b1a Mon Sep 17 00:00:00 2001 From: Simon van Lierde Date: Sat, 8 Nov 2025 11:04:20 +0100 Subject: [PATCH 36/71] fix(cicd): Lint pre-commit yaml and update mdformat pre-commit hook --- .pre-commit-config.yaml | 92 ++++++++++++++++++++--------------------- 1 file changed, 44 insertions(+), 48 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 6b9ca26..a6b2c07 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -5,85 +5,81 @@ repos: ### Global hooks -- repo: https://gitlab.com/vojko.pribudic.foss/pre-commit-update + - repo: https://gitlab.com/vojko.pribudic.foss/pre-commit-update rev: v0.9.0 hooks: - - id: pre-commit-update # Autoupdate pre-commit hooks - # TODO: Re-add mdformat to pre-commit-update when mdformat plugins are compatible with mdformat 1.0.0 - args: [--exclude, mdformat] + - id: pre-commit-update # Autoupdate pre-commit hooks -- repo: https://github.com/gitleaks/gitleaks + - repo: https://github.com/gitleaks/gitleaks rev: v8.29.0 hooks: - - id: gitleaks + - id: gitleaks -- repo: https://github.com/executablebooks/mdformat - rev: 0.7.22 + - repo: https://github.com/executablebooks/mdformat + rev: 1.0.0 hooks: - - id: mdformat # Format Markdown files. + - id: mdformat # Format Markdown files. additional_dependencies: - - mdformat-gfm # Support GitHub Flavored Markdown. - - mdformat-footnote - - mdformat-frontmatter - - mdformat-ruff # Support Python code blocks linted with Ruff. + - mdformat-gfm>=1.0.0 # Support GitHub Flavored Markdown. + - mdformat-ruff # Support Python code blocks linted with Ruff. -- repo: https://github.com/pre-commit/pre-commit-hooks + - repo: https://github.com/pre-commit/pre-commit-hooks rev: v6.0.0 hooks: - - id: check-added-large-files - - id: check-case-conflict # Check for files with names that differ only in case. - - id: check-executables-have-shebangs - - id: check-shebang-scripts-are-executable - - id: check-toml - - id: check-yaml + - id: check-added-large-files + - id: check-case-conflict # Check for files with names that differ only in case. + - id: check-executables-have-shebangs + - id: check-shebang-scripts-are-executable + - id: check-toml + - id: check-yaml exclude: ^docs/mkdocs.yml$ # Exclude mkdocs.yml because it uses an obscure tag to allow for mermaid formatting - - id: detect-private-key - - id: end-of-file-fixer # Ensure files end with a newline. - - id: mixed-line-ending - - id: no-commit-to-branch # Prevent commits to main and master branches. - - id: trailing-whitespace + - id: detect-private-key + - id: end-of-file-fixer # Ensure files end with a newline. + - id: mixed-line-ending + - id: no-commit-to-branch # Prevent commits to main and master branches. + - id: trailing-whitespace args: ["--markdown-linebreak-ext", "md"] # Preserve Markdown hard line breaks. -- repo: https://github.com/commitizen-tools/commitizen + - repo: https://github.com/commitizen-tools/commitizen rev: v4.9.1 hooks: - - id: commitizen + - id: commitizen stages: [commit-msg] -- repo: https://github.com/simonvanlierde/check-json5 + - repo: https://github.com/simonvanlierde/check-json5 rev: v1.1.0 hooks: - - id: check-json5 + - id: check-json5 files: ^ (?!(backend/frontend-app|frontend-web)/data/) ### Backend hooks -- repo: https://github.com/RobertCraigie/pyright-python # Lint backend code with Pyright. + - repo: https://github.com/RobertCraigie/pyright-python # Lint backend code with Pyright. rev: v1.1.407 hooks: - - id: pyright + - id: pyright files: ^backend/(app|scripts|tests)/ entry: pyright --project backend -- repo: https://github.com/astral-sh/ruff-pre-commit + - repo: https://github.com/astral-sh/ruff-pre-commit rev: v0.14.4 hooks: - - id: ruff-check # Lint code + - id: ruff-check # Lint code files: ^backend/(app|scripts|tests)/ args: ["--fix", "--config", "backend/pyproject.toml", "--ignore", "FIX002"] # Allow TODO comments in commits. - - id: ruff-format # Format code + - id: ruff-format # Format code files: ^backend/(app|scripts|tests)/ args: ["--config", "backend/pyproject.toml"] -- repo: https://github.com/astral-sh/uv-pre-commit - rev: 0.9.7 + - repo: https://github.com/astral-sh/uv-pre-commit + rev: 0.9.8 hooks: - - id: uv-lock # Update the uv lockfile for the backend. + - id: uv-lock # Update the uv lockfile for the backend. files: ^backend/(uv\.lock|pyproject\.toml|uv\.toml)$ entry: uv lock --project backend -- repo: local + - repo: local hooks: # Check if Alembic migrations are up-to-date. Uses uv to ensure the right environment when executed through VS Code Git extension. - - id: backend-alembic-autogen-check + - id: backend-alembic-autogen-check name: check alembic migrations entry: bash -c 'cd backend && uv run alembic-autogen-check' language: system @@ -92,21 +88,21 @@ repos: stages: [pre-commit] ### Frontend hooks -- repo: local + - repo: local hooks: - - id: frontend-web-format + - id: frontend-web-format name: format frontend-web code entry: bash -c 'cd frontend-web && npm run format' - language: system + language: + system # Match frontend JavaScript and TypeScript files for formatting. - files: - ^frontend-web\/.*\.(jsx?|tsx?|c(js|ts)|m(js|ts)|d\\.(ts|cts|mts)|jsonc?)$ + files: ^frontend-web\/.*\.(jsx?|tsx?|c(js|ts)|m(js|ts)|d\\.(ts|cts|mts)|jsonc?)$ pass_filenames: false - - id: frontend-app-format + - id: frontend-app-format name: format frontend-app code entry: bash -c 'cd frontend-app && npm run format' - language: system + language: + system # Match frontend JavaScript and TypeScript files for formatting. - files: - ^frontend-app\/.*\.(jsx?|tsx?|c(js|ts)|m(js|ts)|d\\.(ts|cts|mts)|jsonc?)$ + files: ^frontend-app\/.*\.(jsx?|tsx?|c(js|ts)|m(js|ts)|d\\.(ts|cts|mts)|jsonc?)$ pass_filenames: false From 9bbd55654e26d15db20cf44b74f43a1eb85a30cd Mon Sep 17 00:00:00 2001 From: Simon van Lierde Date: Sat, 8 Nov 2025 10:21:03 +0000 Subject: [PATCH 37/71] fix(backend): Move back to python 3.13 because Dockerized asyncpg doesn't support it yet --- backend/.python-version | 2 +- backend/Dockerfile | 5 +++-- backend/Dockerfile.dev | 2 +- backend/Dockerfile.migrations | 4 ++-- backend/pyproject.toml | 1 + codemeta.json | 2 +- 6 files changed, 9 insertions(+), 7 deletions(-) diff --git a/backend/.python-version b/backend/.python-version index 6324d40..24ee5b1 100644 --- a/backend/.python-version +++ b/backend/.python-version @@ -1 +1 @@ -3.14 +3.13 diff --git a/backend/Dockerfile b/backend/Dockerfile index 17b19a7..15ca725 100644 --- a/backend/Dockerfile +++ b/backend/Dockerfile @@ -1,5 +1,6 @@ # --- Builder stage --- -FROM ghcr.io/astral-sh/uv:0.9-python3.14-trixie-slim AS builder +# TODO: Move to Python 3.14 once asyncpg supports it (version 0.31.0+, see https://github.com/MagicStack/asyncpg/issues/1282) +FROM ghcr.io/astral-sh/uv:0.9-python3.13-trixie-slim AS builder # Install git for custom dependencies (fastapi-users-db-sqlmodel) RUN --mount=type=cache,target=/var/cache/apt,sharing=locked \ @@ -34,7 +35,7 @@ RUN --mount=type=cache,target=/root/.cache/uv \ uv sync --locked --no-editable --no-default-groups --group=api # --- Final runtime stage --- -FROM python:3.14-slim +FROM python:3.13-slim # Build arguments ARG WORKDIR=/opt/relab/backend diff --git a/backend/Dockerfile.dev b/backend/Dockerfile.dev index 36cea79..5609289 100644 --- a/backend/Dockerfile.dev +++ b/backend/Dockerfile.dev @@ -1,6 +1,6 @@ # Development Dockerfile for FastAPI Backend # Note: This requires mounting the source code as a volume in docker-compose.override.yml -FROM ghcr.io/astral-sh/uv:0.9-python3.14-trixie-slim +FROM ghcr.io/astral-sh/uv:0.9-python3.13-trixie-slim # Build arguments ARG WORKDIR=/opt/relab/backend diff --git a/backend/Dockerfile.migrations b/backend/Dockerfile.migrations index 73a3932..6c03c35 100644 --- a/backend/Dockerfile.migrations +++ b/backend/Dockerfile.migrations @@ -1,5 +1,5 @@ # --- Builder stage --- -FROM ghcr.io/astral-sh/uv:0.9-python3.14-trixie-slim AS builder +FROM ghcr.io/astral-sh/uv:0.9-python3.13-trixie-slim AS builder WORKDIR /opt/relab/backend_migrations @@ -33,7 +33,7 @@ COPY scripts/ scripts/ COPY app/ app/ # --- Final runtime stage --- -FROM python:3.14-slim +FROM python:3.13-slim # Build arguments ARG WORKDIR=/opt/relab/backend_migrations diff --git a/backend/pyproject.toml b/backend/pyproject.toml index 860929e..042eaca 100644 --- a/backend/pyproject.toml +++ b/backend/pyproject.toml @@ -23,6 +23,7 @@ ## Dependencies and version constraints dependencies = [ "asyncache>=0.3.1", + # TODO: Move to Python 3.14 once asyncpg supports it (version 0.31.0+, see https://github.com/MagicStack/asyncpg/issues/1282) "asyncpg>=0.30.0", "cachetools>=5.5.2", "email-validator>=2.2.0", diff --git a/codemeta.json b/codemeta.json index f3704e5..9d940b3 100644 --- a/codemeta.json +++ b/codemeta.json @@ -42,7 +42,7 @@ ], "license": "https://spdx.org/licenses/AGPL-3.0-or-later", "name": "Reverse Engineering Lab", - "programmingLanguage": ["Python 3.14", "JavaScript"], + "programmingLanguage": ["Python 3.13", "JavaScript"], "softwareRequirements": "Docker", "version": "0.1.0" } From 7ed08d93880d2a5061181077ef82f153caeff177 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 21 Oct 2025 09:50:23 +0000 Subject: [PATCH 38/71] chore(deps): update infrastructure --- compose.prod.yml | 2 +- compose.yml | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/compose.prod.yml b/compose.prod.yml index e73373c..866eb99 100644 --- a/compose.prod.yml +++ b/compose.prod.yml @@ -36,7 +36,7 @@ services: - cache_data:/data cloudflared: # Cloudflared tunnel to cml-relab.org - image: cloudflare/cloudflared:latest@sha256:89ee50efb1e9cb2ae30281a8a404fed95eb8f02f0a972617526f8c5b417acae2 + image: cloudflare/cloudflared:latest@sha256:396cd2e6f021275ad09969a1b4f1a7e62ca5349fde62781ce082bb2c18105c70 command: tunnel --no-autoupdate run env_file: .env # Should contain TUNNEL_TOKEN variable pull_policy: always diff --git a/compose.yml b/compose.yml index 8937ad6..1975b5f 100644 --- a/compose.yml +++ b/compose.yml @@ -36,7 +36,7 @@ services: - user_uploads:/opt/relab/backend/data/uploads database: - image: postgres:18@sha256:41bfa2e5b168fff0847a5286694a86cff102bdc4d59719869f6b117bb30b3a24 + image: postgres:18@sha256:78f1aed6e8c0185d3c6963c8343dd018c63e8ba5ebd78c159c7c772a05e75b30 env_file: ./backend/.env healthcheck: test: ["CMD-SHELL", "pg_isready -h localhost -U $${POSTGRES_USER} -d $${POSTGRES_DB}"] @@ -57,7 +57,7 @@ services: restart: unless-stopped docs: - image: squidfunk/mkdocs-material:9@sha256:980e11fed03b8e7851e579be9f34b1210f516c9f0b4da1a1457f21a460bd6628 + image: squidfunk/mkdocs-material:9@sha256:f5c556a6d30ce0c1c0df10e3c38c79bbcafdaea4b1c1be366809d0d4f6f9d57f restart: unless-stopped volumes: - ./docs:/docs From ec74a11cf6f49958ce8dfe654078c2bf10f5289c Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 21 Oct 2025 08:13:49 +0000 Subject: [PATCH 39/71] fix(deps): update expo monorepo --- frontend-app/package-lock.json | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/frontend-app/package-lock.json b/frontend-app/package-lock.json index bcce7aa..ccf4078 100644 --- a/frontend-app/package-lock.json +++ b/frontend-app/package-lock.json @@ -101,6 +101,7 @@ "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.28.5.tgz", "integrity": "sha512-e7jT4DxYvIDLk1ZHmU/m/mB19rex9sv0c2ftBtjSBv+kVM/902eh0fINUzD7UwLLNR+jU585GxUJ8/EBfAM5fw==", "license": "MIT", + "peer": true, "dependencies": { "@babel/code-frame": "^7.27.1", "@babel/generator": "^7.28.5", @@ -3847,6 +3848,7 @@ "resolved": "https://registry.npmjs.org/@react-navigation/native/-/native-7.1.18.tgz", "integrity": "sha512-DZgd6860dxcq3YX7UzIXeBr6m3UgXvo9acxp5jiJyIZXdR00Br9JwVkO7e0bUeTA2d3Z8dsmtAR84Y86NnH64Q==", "license": "MIT", + "peer": true, "dependencies": { "@react-navigation/core": "^7.12.4", "escape-string-regexp": "^4.0.0", @@ -4043,6 +4045,7 @@ "integrity": "sha512-Qec1E3mhALmaspIrhWt9jkQMNdw6bReVu64mjvhbhq2NFPftLPVr+l1SZgmw/66WwBNpDh7ao5AT6gF5v41PFA==", "devOptional": true, "license": "MIT", + "peer": true, "dependencies": { "csstype": "^3.0.2" } @@ -4121,6 +4124,7 @@ "integrity": "sha512-TGf22kon8KW+DeKaUmOibKWktRY8b2NSAZNdtWh798COm1NWx8+xJ6iFBtk3IvLdv6+LGLJLRlyhrhEDZWargQ==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "@typescript-eslint/scope-manager": "8.45.0", "@typescript-eslint/types": "8.45.0", @@ -4683,6 +4687,7 @@ "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.15.0.tgz", "integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==", "license": "MIT", + "peer": true, "bin": { "acorn": "bin/acorn" }, @@ -5374,6 +5379,7 @@ } ], "license": "MIT", + "peer": true, "dependencies": { "baseline-browser-mapping": "^2.8.9", "caniuse-lite": "^1.0.30001746", @@ -6630,6 +6636,7 @@ "integrity": "sha512-XyLmROnACWqSxiGYArdef1fItQd47weqB7iwtfr9JHwRrqIXZdcFMvvEcL9xHCmL0SNsOvF0c42lWyM1U5dgig==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "@eslint-community/eslint-utils": "^4.8.0", "@eslint-community/regexpp": "^4.12.1", @@ -6724,6 +6731,7 @@ "integrity": "sha512-82GZUjRS0p/jganf6q1rEO25VSoHH0hKPCTrgillPjdI/3bgBhAE1QzHrHTizjpRvy6pGAvKjDJtk2pF9NDq8w==", "dev": true, "license": "MIT", + "peer": true, "bin": { "eslint-config-prettier": "bin/cli.js" }, @@ -6843,6 +6851,7 @@ "integrity": "sha512-whOE1HFo/qJDyX4SnXzP4N6zOWn79WhnCUY/iDR0mPfQZO8wcYE4JClzI2oZrhBnnMUCBCHZhO6VQyoBU95mZA==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "@rtsao/scc": "^1.1.0", "array-includes": "^3.1.9", @@ -7156,6 +7165,7 @@ "resolved": "https://registry.npmjs.org/expo/-/expo-54.0.15.tgz", "integrity": "sha512-d4OLUz/9nC+Aw00zamHANh5TZB4/YVYvSmKJAvCfLNxOY2AJeTFAvk0mU5HwICeHQBp6zHtz13DDCiMbcyVQWQ==", "license": "MIT", + "peer": true, "dependencies": { "@babel/runtime": "^7.20.0", "@expo/cli": "54.0.12", @@ -7254,6 +7264,7 @@ "resolved": "https://registry.npmjs.org/expo-constants/-/expo-constants-18.0.9.tgz", "integrity": "sha512-sqoXHAOGDcr+M9NlXzj1tGoZyd3zxYDy215W6E0Z0n8fgBaqce9FAYQE2bu5X4G629AYig5go7U6sQz7Pjcm8A==", "license": "MIT", + "peer": true, "dependencies": { "@expo/config": "~12.0.9", "@expo/env": "~2.0.7" @@ -7278,6 +7289,7 @@ "resolved": "https://registry.npmjs.org/expo-font/-/expo-font-14.0.9.tgz", "integrity": "sha512-xCoQbR/36qqB6tew/LQ6GWICpaBmHLhg/Loix5Rku/0ZtNaXMJv08M9o1AcrdiGTn/Xf/BnLu6DgS45cWQEHZg==", "license": "MIT", + "peer": true, "dependencies": { "fontfaceobserver": "^2.1.0" }, @@ -7372,6 +7384,7 @@ "resolved": "https://registry.npmjs.org/expo-linking/-/expo-linking-8.0.8.tgz", "integrity": "sha512-MyeMcbFDKhXh4sDD1EHwd0uxFQNAc6VCrwBkNvvvufUsTYFq3glTA9Y8a+x78CPpjNqwNAamu74yIaIz7IEJyg==", "license": "MIT", + "peer": true, "dependencies": { "expo-constants": "~18.0.8", "invariant": "^2.2.4" @@ -11187,6 +11200,7 @@ "integrity": "sha512-I7AIg5boAr5R0FFtJ6rCfD+LFsWHp81dolrFD8S79U9tb8Az2nGrJncnMSnys+bpQJfRUzqs9hnA81OAA3hCuQ==", "dev": true, "license": "MIT", + "peer": true, "bin": { "prettier": "bin/prettier.cjs" }, @@ -11416,6 +11430,7 @@ "resolved": "https://registry.npmjs.org/react/-/react-19.1.0.tgz", "integrity": "sha512-FS+XFBNvn3GTAWq26joslQgWNoFu08F4kl0J4CgdNKADkdSGXQyTCnKteIAJy96Br6YbpEU1LSzV5dYtjMkMDg==", "license": "MIT", + "peer": true, "engines": { "node": ">=0.10.0" } @@ -11435,6 +11450,7 @@ "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-19.1.0.tgz", "integrity": "sha512-Xs1hdnE+DyKgeHJeJznQmYMIBG3TKIHJJT95Q58nHLSrElKlGQqDTR2HQ9fx5CN/Gk6Vh/kupBTDLU11/nDk/g==", "license": "MIT", + "peer": true, "dependencies": { "scheduler": "^0.26.0" }, @@ -11471,6 +11487,7 @@ "resolved": "https://registry.npmjs.org/react-native/-/react-native-0.81.4.tgz", "integrity": "sha512-bt5bz3A/+Cv46KcjV0VQa+fo7MKxs17RCcpzjftINlen4ZDUl0I6Ut+brQ2FToa5oD0IB0xvQHfmsg2EDqsZdQ==", "license": "MIT", + "peer": true, "dependencies": { "@jest/create-cache-key-function": "^29.7.0", "@react-native/assets-registry": "0.81.4", @@ -11528,6 +11545,7 @@ "resolved": "https://registry.npmjs.org/react-native-gesture-handler/-/react-native-gesture-handler-2.28.0.tgz", "integrity": "sha512-0msfJ1vRxXKVgTgvL+1ZOoYw3/0z1R+Ked0+udoJhyplC2jbVKIJ8Z1bzWdpQRCV3QcQ87Op0zJVE5DhKK2A0A==", "license": "MIT", + "peer": true, "dependencies": { "@egjs/hammerjs": "^2.0.17", "hoist-non-react-statics": "^3.3.0", @@ -11612,6 +11630,7 @@ "resolved": "https://registry.npmjs.org/react-native-reanimated/-/react-native-reanimated-4.1.3.tgz", "integrity": "sha512-GP8wsi1u3nqvC1fMab/m8gfFwFyldawElCcUSBJQgfrXeLmsPPUOpDw44lbLeCpcwUuLa05WTVePdTEwCLTUZg==", "license": "MIT", + "peer": true, "dependencies": { "react-native-is-edge-to-edge": "^1.2.1", "semver": "7.7.2" @@ -11640,6 +11659,7 @@ "resolved": "https://registry.npmjs.org/react-native-safe-area-context/-/react-native-safe-area-context-5.6.2.tgz", "integrity": "sha512-4XGqMNj5qjUTYywJqpdWZ9IG8jgkS3h06sfVjfw5yZQZfWnRFXczi0GnYyFyCc2EBps/qFmoCH8fez//WumdVg==", "license": "MIT", + "peer": true, "peerDependencies": { "react": "*", "react-native": "*" @@ -11650,6 +11670,7 @@ "resolved": "https://registry.npmjs.org/react-native-screens/-/react-native-screens-4.16.0.tgz", "integrity": "sha512-yIAyh7F/9uWkOzCi1/2FqvNvK6Wb9Y1+Kzn16SuGfN9YFJDTbwlzGRvePCNTOX0recpLQF3kc2FmvMUhyTCH1Q==", "license": "MIT", + "peer": true, "dependencies": { "react-freeze": "^1.0.0", "react-native-is-edge-to-edge": "^1.2.1", @@ -11680,6 +11701,7 @@ "resolved": "https://registry.npmjs.org/react-native-web/-/react-native-web-0.21.2.tgz", "integrity": "sha512-SO2t9/17zM4iEnFvlu2DA9jqNbzNhoUP+AItkoCOyFmDMOhUnBBznBDCYN92fGdfAkfQlWzPoez6+zLxFNsZEg==", "license": "MIT", + "peer": true, "dependencies": { "@babel/runtime": "^7.18.6", "@react-native/normalize-colors": "^0.74.1", @@ -11712,6 +11734,7 @@ "resolved": "https://registry.npmjs.org/react-native-webview/-/react-native-webview-13.15.0.tgz", "integrity": "sha512-Vzjgy8mmxa/JO6l5KZrsTC7YemSdq+qB01diA0FqjUTaWGAGwuykpJ73MDj3+mzBSlaDxAEugHzTtkUQkQEQeQ==", "license": "MIT", + "peer": true, "dependencies": { "escape-string-regexp": "^4.0.0", "invariant": "2.2.4" @@ -11726,6 +11749,7 @@ "resolved": "https://registry.npmjs.org/react-native-worklets/-/react-native-worklets-0.5.1.tgz", "integrity": "sha512-lJG6Uk9YuojjEX/tQrCbcbmpdLCSFxDK1rJlkDhgqkVi1KZzG7cdcBFQRqyNOOzR9Y0CXNuldmtWTGOyM0k0+w==", "license": "MIT", + "peer": true, "dependencies": { "@babel/plugin-transform-arrow-functions": "^7.0.0-0", "@babel/plugin-transform-class-properties": "^7.0.0-0", @@ -11813,6 +11837,7 @@ "resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.14.2.tgz", "integrity": "sha512-jCvmsr+1IUSMUyzOkRcvnVbX3ZYC6g9TDrDbFuFmRDq7PD4yaGbLKNQL6k2jnArV8hjYxh7hVhAZB6s9HDGpZA==", "license": "MIT", + "peer": true, "engines": { "node": ">=0.10.0" } @@ -13251,6 +13276,7 @@ "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", "dev": true, "license": "MIT", + "peer": true, "engines": { "node": ">=12" }, @@ -13457,6 +13483,7 @@ "integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==", "dev": true, "license": "Apache-2.0", + "peer": true, "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" @@ -14247,6 +14274,7 @@ "resolved": "https://registry.npmjs.org/zod/-/zod-3.25.76.tgz", "integrity": "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==", "license": "MIT", + "peer": true, "funding": { "url": "https://github.com/sponsors/colinhacks" } From dadebaac0942d0af6eea2f5b4139dea5459e0c0d Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 20 Oct 2025 02:31:30 +0000 Subject: [PATCH 40/71] chore(deps): update dependency @react-navigation/bottom-tabs to v7.4.9 --- frontend-app/package-lock.json | 1 + 1 file changed, 1 insertion(+) diff --git a/frontend-app/package-lock.json b/frontend-app/package-lock.json index ccf4078..7e7203f 100644 --- a/frontend-app/package-lock.json +++ b/frontend-app/package-lock.json @@ -1483,6 +1483,7 @@ "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.28.4.tgz", "integrity": "sha512-Q/N6JNWvIvPnLDvjlE1OUBLPQHH6l3CltCEsHIujp45zQUSSh8K+gHnaEX45yAT1nyngnINhvWtzN+Nb9D8RAQ==", "license": "MIT", + "peer": true, "engines": { "node": ">=6.9.0" } From 086f963d10a15c1585b0fd777fe01137107a176d Mon Sep 17 00:00:00 2001 From: Simon van Lierde Date: Sat, 8 Nov 2025 11:48:24 +0100 Subject: [PATCH 41/71] fix(backend): Use TypeAlias over simple type declaration for custom schema field types --- backend/app/api/common/schemas/custom_fields.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/backend/app/api/common/schemas/custom_fields.py b/backend/app/api/common/schemas/custom_fields.py index c50df7a..78019ec 100644 --- a/backend/app/api/common/schemas/custom_fields.py +++ b/backend/app/api/common/schemas/custom_fields.py @@ -1,13 +1,13 @@ """Shared fields for DTO schemas.""" -from typing import Annotated +from typing import Annotated, TypeAlias from pydantic import AnyUrl, HttpUrl, PlainSerializer, StringConstraints # HTTP URL that is stored as string in the database. -type HttpUrlToDB = Annotated[ +HttpUrlToDB: TypeAlias = Annotated[ HttpUrl, PlainSerializer(lambda x: str(x), return_type=str), StringConstraints(max_length=250) ] -type AnyUrlToDB = Annotated[ +AnyUrlToDB: TypeAlias = Annotated[ AnyUrl, PlainSerializer(lambda x: str(x), return_type=str), StringConstraints(max_length=250) ] From b4f3fb66960f1a1a3edc8b9ed9a6f0c4f499cd13 Mon Sep 17 00:00:00 2001 From: Simon van Lierde Date: Sat, 8 Nov 2025 11:48:57 +0100 Subject: [PATCH 42/71] fix(backend): Only apply sorting if explicit sorting was requested --- backend/app/api/common/crud/base.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/backend/app/api/common/crud/base.py b/backend/app/api/common/crud/base.py index f183630..9b3e768 100644 --- a/backend/app/api/common/crud/base.py +++ b/backend/app/api/common/crud/base.py @@ -95,8 +95,10 @@ def get_models_query( statement = add_filter_joins(statement, model, model_filter) # Apply the filter statement = model_filter.filter(statement) - # Apply sorting - fastapi-filter stores it but doesn't apply it automatically - statement = model_filter.sort(statement) + # Apply sorting if specified + # HACK: Inspect sort vars to see if any sorting is defined + if vars(model_filter.sort): + statement = model_filter.sort(statement) relationships_to_exclude = [] statement, relationships_to_exclude = add_relationship_options( From 3325db7da667697412eb72093972007d6d3274c3 Mon Sep 17 00:00:00 2001 From: Simon van Lierde Date: Sat, 8 Nov 2025 12:03:07 +0100 Subject: [PATCH 43/71] feature(backend): Mask user emails in logs for privacy --- .../app/api/auth/utils/programmatic_emails.py | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/backend/app/api/auth/utils/programmatic_emails.py b/backend/app/api/auth/utils/programmatic_emails.py index 97bee35..53f4028 100644 --- a/backend/app/api/auth/utils/programmatic_emails.py +++ b/backend/app/api/auth/utils/programmatic_emails.py @@ -22,7 +22,21 @@ def generate_token_link(token: str, route: str, base_url: str | AnyUrl | None = base_url = str(core_settings.frontend_app_url) return urljoin(str(base_url), f"{route}?token={token}") +def mask_email_for_log(email: EmailStr, mask: bool = True, max_len: int = 80) -> str: + """Mask emails for logging. + + Also remove non-printable characters and truncates long domains. + """ + string = "".join(ch for ch in str(email) if ch.isprintable()) + local, sep, domain = string.partition("@") + if sep and mask: + masked = (f"{local[0]}***@{domain}" if len(local) > 1 else f"*@{domain}") + else: + masked = string + return (f"{masked[:max_len-3]}..." if len(masked) > max_len else masked) + +### Generic email function ### async def send_email_with_template( to_email: EmailStr, subject: str, @@ -48,10 +62,10 @@ async def send_email_with_template( if background_tasks: background_tasks.add_task(fm.send_message, message, template_name=template_name) - logger.info("Email queued for background sending to %s using template %s", to_email, template_name) + logger.info("Email queued for background sending to %s using template %s", mask_email_for_log(to_email), template_name) else: await fm.send_message(message, template_name=template_name) - logger.info("Email sent to %s using template %s", to_email, template_name) + logger.info("Email sent to %s using template %s", mask_email_for_log(to_email), template_name) ### Authentication email functions ### From 1511004532af038e336f64bea2335a8e25855c65 Mon Sep 17 00:00:00 2001 From: Simon van Lierde <90462640+simonvanlierde@users.noreply.github.com> Date: Sat, 8 Nov 2025 12:06:30 +0100 Subject: [PATCH 44/71] Potential fix for code scanning alert no. 8: Log Injection Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com> --- backend/app/api/auth/utils/programmatic_emails.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/backend/app/api/auth/utils/programmatic_emails.py b/backend/app/api/auth/utils/programmatic_emails.py index 53f4028..b5217f8 100644 --- a/backend/app/api/auth/utils/programmatic_emails.py +++ b/backend/app/api/auth/utils/programmatic_emails.py @@ -25,9 +25,10 @@ def generate_token_link(token: str, route: str, base_url: str | AnyUrl | None = def mask_email_for_log(email: EmailStr, mask: bool = True, max_len: int = 80) -> str: """Mask emails for logging. - Also remove non-printable characters and truncates long domains. + Also remove non-printable characters and truncates long domains. Explicitly removes log-breaking control characters. """ - string = "".join(ch for ch in str(email) if ch.isprintable()) + # Remove non-printable and log-breaking control characters + string = "".join(ch for ch in str(email) if ch.isprintable()).replace('\n', '').replace('\r', '') local, sep, domain = string.partition("@") if sep and mask: masked = (f"{local[0]}***@{domain}" if len(local) > 1 else f"*@{domain}") From 7a43515ed9049722b96dc8a9de4e0e145cfb3ece Mon Sep 17 00:00:00 2001 From: Simon van Lierde Date: Sat, 8 Nov 2025 12:13:58 +0100 Subject: [PATCH 45/71] fix(backend): Simplify URL serializing to DB --- backend/app/api/common/schemas/custom_fields.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/backend/app/api/common/schemas/custom_fields.py b/backend/app/api/common/schemas/custom_fields.py index 78019ec..5614bd2 100644 --- a/backend/app/api/common/schemas/custom_fields.py +++ b/backend/app/api/common/schemas/custom_fields.py @@ -6,8 +6,8 @@ # HTTP URL that is stored as string in the database. HttpUrlToDB: TypeAlias = Annotated[ - HttpUrl, PlainSerializer(lambda x: str(x), return_type=str), StringConstraints(max_length=250) + HttpUrl, PlainSerializer(str, return_type=str), StringConstraints(max_length=250) ] AnyUrlToDB: TypeAlias = Annotated[ - AnyUrl, PlainSerializer(lambda x: str(x), return_type=str), StringConstraints(max_length=250) + AnyUrl, PlainSerializer(str, return_type=str), StringConstraints(max_length=250) ] From db2e6e51f21361f59850ec6dadd7bed0e97cc339 Mon Sep 17 00:00:00 2001 From: Simon van Lierde Date: Sat, 8 Nov 2025 12:27:20 +0100 Subject: [PATCH 46/71] fix(backend): Simplify dummy data checking logic --- backend/scripts/seed/migrations_entrypoint.sh | 21 ++++++++++++------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/backend/scripts/seed/migrations_entrypoint.sh b/backend/scripts/seed/migrations_entrypoint.sh index 4124d6e..aeb72b7 100755 --- a/backend/scripts/seed/migrations_entrypoint.sh +++ b/backend/scripts/seed/migrations_entrypoint.sh @@ -32,15 +32,20 @@ if [ "$(lc "$SEED_TAXONOMIES")" = "true" ]; then .venv/bin/python -m scripts.seed.taxonomies.harmonized_system fi -# Check if all tables are empty -echo "Checking if all tables in the database are empty using scripts/db_is_empty.py..." -DB_EMPTY=$(.venv/bin/python -m scripts.db_is_empty) - -if [ "$(lc "$DB_EMPTY")" = "true" ] && [ "$(lc "$SEED_DUMMY_DATA")" = "true" ]; then - echo "All tables are empty, proceeding to seed dummy data..." - .venv/bin/python -m scripts.seed.dummy_data +# Seed dummy data if enabled and if the database is empty +if [ "$(lc "$SEED_DUMMY_DATA")" = "true" ]; then + echo "Dummy data seeding is enabled." + echo "Checking if all tables in the database are empty using scripts/db_is_empty.py..." + DB_EMPTY=$(.venv/bin/python -m scripts.db_is_empty) + + if [ "$(lc "$DB_EMPTY")" = "true" ]; then + echo "All tables are empty, proceeding to seed dummy data..." + .venv/bin/python -m scripts.seed.dummy_data + else + echo "Database already has data seeding disabled, skipping." + fi else - echo "Database already has data or dummy data seeding disabled, skipping." + echo "Dummy data seeding is disabled." fi # Create a superuser if the required environment variables are set From fbb34dd9209f7475e4f72b2d1a03f3770481dd1b Mon Sep 17 00:00:00 2001 From: Simon van Lierde Date: Sat, 8 Nov 2025 12:30:08 +0100 Subject: [PATCH 47/71] fix(backend): Spellcheck --- backend/app/core/redis.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/backend/app/core/redis.py b/backend/app/core/redis.py index ea99feb..a8a0973 100644 --- a/backend/app/core/redis.py +++ b/backend/app/core/redis.py @@ -101,7 +101,7 @@ async def set_redis_value(redis_client: Redis, key: str, value: Any, ex: int | N Args: redis_client: Redis client key: Redis key - value: Value to stores + value: Value to store ex: Expiration time in seconds (optional) Returns: From fffbff3c20426db6880f00e7e35896ab545707a5 Mon Sep 17 00:00:00 2001 From: Simon van Lierde Date: Mon, 17 Nov 2025 13:38:00 +0100 Subject: [PATCH 48/71] feat(backend): Add circularity_properties model to products - Add CircularityPropertiesBase and CircularityProperties database models with fields for recyclability, repairability, and remanufacturability - Each property has observation (required), comment (optional), and reference (optional) fields - Add one-to-one relationship between Product and CircularityProperties - Create full CRUD operations for circularity properties - Add REST API endpoints (GET, POST, PATCH, DELETE) for managing circularity properties - Update product schemas to support circularity_properties in create/read/update operations - Update API documentation and examples to include circularity properties - Add alembic migration script for new circularity properties model --- ..._add_basic_circularity_properties_model.py | 54 +++++++++++ backend/app/api/data_collection/crud.py | 97 ++++++++++++++++++- backend/app/api/data_collection/models.py | 32 ++++++ backend/app/api/data_collection/routers.py | 73 +++++++++++++- backend/app/api/data_collection/schemas.py | 71 ++++++++++++++ 5 files changed, 318 insertions(+), 9 deletions(-) create mode 100644 backend/alembic/versions/b43d157d07f1_add_basic_circularity_properties_model.py diff --git a/backend/alembic/versions/b43d157d07f1_add_basic_circularity_properties_model.py b/backend/alembic/versions/b43d157d07f1_add_basic_circularity_properties_model.py new file mode 100644 index 0000000..0e5a745 --- /dev/null +++ b/backend/alembic/versions/b43d157d07f1_add_basic_circularity_properties_model.py @@ -0,0 +1,54 @@ +"""Add basic circularity_properties model + +Revision ID: b43d157d07f1 +Revises: 95cc94317b69 +Create Date: 2025-11-17 13:30:07.435637 + +""" + +from collections.abc import Sequence +from typing import Union + +import sqlalchemy as sa +import sqlmodel + +import app.api.common.models.custom_types +from alembic import op + +# revision identifiers, used by Alembic. +revision: str = "b43d157d07f1" +down_revision: str | None = "95cc94317b69" +branch_labels: str | Sequence[str] | None = None +depends_on: str | Sequence[str] | None = None + + +def upgrade() -> None: + # ### commands auto generated by Alembic - please adjust! ### + op.create_table( + "circularityproperties", + sa.Column("created_at", sa.TIMESTAMP(timezone=True), server_default=sa.text("now()"), nullable=True), + sa.Column("updated_at", sa.TIMESTAMP(timezone=True), server_default=sa.text("now()"), nullable=True), + sa.Column("recyclability_observation", sqlmodel.sql.sqltypes.AutoString(length=500), nullable=False), + sa.Column("recyclability_comment", sqlmodel.sql.sqltypes.AutoString(length=100), nullable=True), + sa.Column("recyclability_reference", sqlmodel.sql.sqltypes.AutoString(length=100), nullable=True), + sa.Column("repairability_observation", sqlmodel.sql.sqltypes.AutoString(length=500), nullable=False), + sa.Column("repairability_comment", sqlmodel.sql.sqltypes.AutoString(length=100), nullable=True), + sa.Column("repairability_reference", sqlmodel.sql.sqltypes.AutoString(length=100), nullable=True), + sa.Column("remanufacturability_observation", sqlmodel.sql.sqltypes.AutoString(length=500), nullable=False), + sa.Column("remanufacturability_comment", sqlmodel.sql.sqltypes.AutoString(length=100), nullable=True), + sa.Column("remanufacturability_reference", sqlmodel.sql.sqltypes.AutoString(length=100), nullable=True), + sa.Column("id", sa.Integer(), nullable=False), + sa.Column("product_id", sa.Integer(), nullable=False), + sa.ForeignKeyConstraint( + ["product_id"], + ["product.id"], + ), + sa.PrimaryKeyConstraint("id"), + ) + # ### end Alembic commands ### + + +def downgrade() -> None: + # ### commands auto generated by Alembic - please adjust! ### + op.drop_table("circularityproperties") + # ### end Alembic commands ### diff --git a/backend/app/api/data_collection/crud.py b/backend/app/api/data_collection/crud.py index 52d7570..cc9e20e 100644 --- a/backend/app/api/data_collection/crud.py +++ b/backend/app/api/data_collection/crud.py @@ -29,8 +29,10 @@ MaterialProductLinkUpdate, ) from app.api.data_collection.filters import ProductFilterWithRelationships -from app.api.data_collection.models import PhysicalProperties, Product +from app.api.data_collection.models import CircularityProperties, PhysicalProperties, Product from app.api.data_collection.schemas import ( + CircularityPropertiesCreate, + CircularityPropertiesUpdate, ComponentCreateWithComponents, PhysicalPropertiesCreate, PhysicalPropertiesUpdate, @@ -122,6 +124,72 @@ async def delete_physical_properties(db: AsyncSession, product: Product) -> None await db.commit() +### CircularityProperty CRUD operations ### +async def get_circularity_properties(db: AsyncSession, product_id: int) -> CircularityProperties: + """Get circularity properties for a product.""" + product: Product = await db_get_model_with_id_if_it_exists(db, Product, product_id) + + if not product.circularity_properties: + err_msg: str = f"Circularity properties for product with id {product_id} not found" + raise ValueError(err_msg) + + return product.circularity_properties + + +async def create_circularity_properties( + db: AsyncSession, + circularity_properties: CircularityPropertiesCreate, + product_id: int, +) -> CircularityProperties: + """Create circularity properties for a product.""" + # Validate that product exists and doesn't have circularity properties + product: Product = await db_get_model_with_id_if_it_exists(db, Product, product_id) + if product.circularity_properties: + err_msg: str = f"Product with id {product_id} already has circularity properties" + raise ValueError(err_msg) + + # Create circularity properties + db_circularity_property = CircularityProperties( + **circularity_properties.model_dump(), + product_id=product_id, + ) + db.add(db_circularity_property) + await db.commit() + await db.refresh(db_circularity_property) + + return db_circularity_property + + +async def update_circularity_properties( + db: AsyncSession, product_id: int, circularity_properties: CircularityPropertiesUpdate +) -> CircularityProperties: + """Update circularity properties for a product.""" + # Validate that product exists and has circularity properties + product: Product = await db_get_model_with_id_if_it_exists(db, Product, product_id) + if not (db_circularity_properties := product.circularity_properties): + err_msg: EmailStr = f"Circularity properties for product with id {product_id} not found" + raise ValueError(err_msg) + + circularity_properties_data: dict[str, Any] = circularity_properties.model_dump(exclude_unset=True) + db_circularity_properties.sqlmodel_update(circularity_properties_data) + + db.add(db_circularity_properties) + await db.commit() + await db.refresh(db_circularity_properties) + return db_circularity_properties + + +async def delete_circularity_properties(db: AsyncSession, product: Product) -> None: + """Delete circularity properties for a product.""" + # Validate that product exists and has circularity properties + if not (db_circularity_properties := product.circularity_properties): + err_msg: EmailStr = f"Circularity properties for product with id {product.id} not found" + raise ValueError(err_msg) + + await db.delete(db_circularity_properties) + await db.commit() + + ### Product CRUD operations ### ## Basic CRUD operations ### async def get_product_trees( @@ -178,6 +246,7 @@ async def create_component( "components", "owner_id", "physical_properties", + "circularity_properties", "videos", "bill_of_materials", } @@ -198,6 +267,13 @@ async def create_component( ) db.add(db_physical_property) + if component.circularity_properties: + db_circularity_property = CircularityProperties( + **component.circularity_properties.model_dump(), + product_id=db_component.id, # pyright: ignore[reportArgumentType] # component ID is guaranteed by database flush above + ) + db.add(db_circularity_property) + # Create videos if component.videos: for video in component.videos: @@ -257,6 +333,7 @@ async def create_product( exclude={ "components", "physical_properties", + "circularity_properties", "videos", "bill_of_materials", } @@ -274,6 +351,13 @@ async def create_product( ) db.add(db_physical_properties) + if product.circularity_properties: + db_circularity_properties = CircularityProperties( + **product.circularity_properties.model_dump(), + product_id=db_product.id, # pyright: ignore[reportArgumentType] # product ID is guaranteed by database flush above + ) + db.add(db_circularity_properties) + # Create videos if product.videos: for video in product.videos: @@ -327,12 +411,17 @@ async def update_product( if product.product_type_id: await db_get_model_with_id_if_it_exists(db, ProductType, product.product_type_id) - product_data: dict[str, Any] = product.model_dump(exclude_unset=True, exclude={"physical_properties"}) + product_data: dict[str, Any] = product.model_dump( + exclude_unset=True, exclude={"physical_properties", "circularity_properties"} + ) db_product.sqlmodel_update(product_data) # Update properties - if isinstance(product, ProductUpdateWithProperties) and product.physical_properties: - await update_physical_properties(db, product_id, product.physical_properties) + if isinstance(product, ProductUpdateWithProperties): + if product.physical_properties: + await update_physical_properties(db, product_id, product.physical_properties) + if product.circularity_properties: + await update_circularity_properties(db, product_id, product.circularity_properties) db.add(db_product) await db.commit() diff --git a/backend/app/api/data_collection/models.py b/backend/app/api/data_collection/models.py index 4cb5388..c96f59c 100644 --- a/backend/app/api/data_collection/models.py +++ b/backend/app/api/data_collection/models.py @@ -61,6 +61,35 @@ class PhysicalProperties(PhysicalPropertiesBase, TimeStampMixinBare, table=True) product: "Product" = Relationship(back_populates="physical_properties") +class CircularityPropertiesBase(CustomBase): + """Base model to store circularity properties of a product.""" + + # Recyclability + recyclability_observation: str = Field(min_length=2, max_length=500) + recyclability_comment: str | None = Field(default=None, max_length=100) + recyclability_reference: str | None = Field(default=None, max_length=100) + + # Repairability + repairability_observation: str = Field(min_length=2, max_length=500) + repairability_comment: str | None = Field(default=None, max_length=100) + repairability_reference: str | None = Field(default=None, max_length=100) + + # Remanufacturability + remanufacturability_observation: str = Field(min_length=2, max_length=500) + remanufacturability_comment: str | None = Field(default=None, max_length=100) + remanufacturability_reference: str | None = Field(default=None, max_length=100) + + +class CircularityProperties(CircularityPropertiesBase, TimeStampMixinBare, table=True): + """Model to store circularity properties of a product.""" + + id: int | None = Field(default=None, primary_key=True) + + # One-to-one relationships + product_id: int = Field(foreign_key="product.id") + product: "Product" = Relationship(back_populates="circularity_properties") + + ### Product Model ### class ProductBase(CustomBase): """Basic model to store product information.""" @@ -115,6 +144,9 @@ class Product(ProductBase, TimeStampMixinBare, table=True): physical_properties: PhysicalProperties | None = Relationship( back_populates="product", cascade_delete=True, sa_relationship_kwargs={"uselist": False, "lazy": "selectin"} ) + circularity_properties: CircularityProperties | None = Relationship( + back_populates="product", cascade_delete=True, sa_relationship_kwargs={"uselist": False, "lazy": "selectin"} + ) # Many-to-one relationships files: list["File"] | None = Relationship(back_populates="product", cascade_delete=True) diff --git a/backend/app/api/data_collection/routers.py b/backend/app/api/data_collection/routers.py index cd4ebbb..50cc836 100644 --- a/backend/app/api/data_collection/routers.py +++ b/backend/app/api/data_collection/routers.py @@ -45,10 +45,14 @@ get_user_owned_product_id, ) from app.api.data_collection.models import ( + CircularityProperties, PhysicalProperties, Product, ) from app.api.data_collection.schemas import ( + CircularityPropertiesCreate, + CircularityPropertiesRead, + CircularityPropertiesUpdate, ComponentCreateWithComponents, ComponentReadWithRecursiveComponents, PhysicalPropertiesCreate, @@ -116,13 +120,14 @@ async def get_user_products( description="Relationships to include", openapi_examples={ "none": {"value": {}}, - "properties": {"value": {"physical_properties"}}, + "properties": {"value": {"physical_properties", "circularity_properties"}}, "materials": {"value": {"bill_of_materials"}}, "components": {"value": {"components"}}, "media": {"value": {"images", "videos", "files"}}, "all": { "value": { "physical_properties", + "circularity_properties", "images", "videos", "files", @@ -187,13 +192,14 @@ async def get_products( description="Relationships to include", openapi_examples={ "none": {"value": []}, - "properties": {"value": ["physical_properties"]}, + "properties": {"value": ["physical_properties", "circularity_properties"]}, "materials": {"value": ["bill_of_materials"]}, "media": {"value": ["images", "videos", "files"]}, "components": {"value": ["components"]}, "all": { "value": [ "physical_properties", + "circularity_properties", "images", "videos", "files", @@ -215,6 +221,7 @@ async def get_products( Relationships that can be included: - physical_properties: Physical measurements and attributes + - circularity_properties: Circularity properties (recyclability, repairability, remanufacturability) - images: Product images - videos: Product videos - files: Related documents @@ -324,13 +331,14 @@ async def get_product( description="Relationships to include", openapi_examples={ "none": {"value": []}, - "properties": {"value": ["physical_properties"]}, + "properties": {"value": ["physical_properties", "circularity_properties"]}, "materials": {"value": ["bill_of_materials"]}, "media": {"value": ["images", "videos", "files"]}, "components": {"value": ["components"]}, "all": { "value": [ "physical_properties", + "circularity_properties", "images", "videos", "files", @@ -347,6 +355,7 @@ async def get_product( Relationships that can be included: - physical_properties: Physical measurements and attributes + - circularity_properties: Circularity properties (recyclability, repairability, remanufacturability) - images: Product images - videos: Product videos - files: Related documents @@ -564,13 +573,14 @@ async def get_product_components( description="Relationships to include", openapi_examples={ "none": {"value": []}, - "properties": {"value": ["physical_properties"]}, + "properties": {"value": ["physical_properties", "circularity_properties"]}, "materials": {"value": ["bill_of_materials"]}, "media": {"value": ["images", "videos", "files"]}, "components": {"value": ["components"]}, "all": { "value": [ "physical_properties", + "circularity_properties", "images", "videos", "files", @@ -612,13 +622,14 @@ async def get_product_component( description="Relationships to include", openapi_examples={ "none": {"value": []}, - "properties": {"value": ["physical_properties"]}, + "properties": {"value": ["physical_properties", "circularity_properties"]}, "materials": {"value": ["bill_of_materials"]}, "media": {"value": ["images", "videos", "files"]}, "components": {"value": ["components"]}, "all": { "value": [ "physical_properties", + "circularity_properties", "images", "videos", "files", @@ -773,6 +784,58 @@ async def delete_product_physical_properties( await crud.delete_physical_properties(session, product) +@product_router.get( + "/{product_id}/circularity_properties", + response_model=CircularityPropertiesRead, + summary="Get product circularity properties", +) +async def get_product_circularity_properties(product_id: PositiveInt, session: AsyncSessionDep) -> CircularityProperties: + """Get circularity properties for a product.""" + return await crud.get_circularity_properties(session, product_id) + + +@product_router.post( + "/{product_id}/circularity_properties", + response_model=CircularityPropertiesRead, + status_code=201, + summary="Create product circularity properties", +) +async def create_product_circularity_properties( + product: UserOwnedProductDep, + properties: CircularityPropertiesCreate, + session: AsyncSessionDep, +) -> CircularityProperties: + """Create circularity properties for a product.""" + return await crud.create_circularity_properties(session, properties, product.id) + + +@product_router.patch( + "/{product_id}/circularity_properties", + response_model=CircularityPropertiesRead, + summary="Update product circularity properties", +) +async def update_product_circularity_properties( + product: UserOwnedProductDep, + properties: CircularityPropertiesUpdate, + session: AsyncSessionDep, +) -> CircularityProperties: + """Update circularity properties for a product.""" + return await crud.update_circularity_properties(session, product.id, properties) + + +@product_router.delete( + "/{product_id}/circularity_properties", + status_code=204, + summary="Delete product circularity properties", +) +async def delete_product_circularity_properties( + product: UserOwnedProductDep, + session: AsyncSessionDep, +) -> None: + """Delete circularity properties for a product.""" + await crud.delete_circularity_properties(session, product) + + ## Product Video routers ## @product_router.get( "/{product_id}/videos", diff --git a/backend/app/api/data_collection/schemas.py b/backend/app/api/data_collection/schemas.py index 6306902..b21355d 100644 --- a/backend/app/api/data_collection/schemas.py +++ b/backend/app/api/data_collection/schemas.py @@ -27,6 +27,7 @@ ProductRead, ) from app.api.data_collection.models import ( + CircularityPropertiesBase, PhysicalPropertiesBase, ProductBase, ) @@ -93,6 +94,71 @@ class PhysicalPropertiesUpdate(BaseUpdateSchema, PhysicalPropertiesBase): model_config: ConfigDict = ConfigDict(json_schema_extra={"examples": [{"weight_kg": 15, "height_cm": 120}]}) +class CircularityPropertiesCreate(BaseCreateSchema, CircularityPropertiesBase): + """Schema for creating circularity properties.""" + + model_config: ConfigDict = ConfigDict( + json_schema_extra={ + "examples": [ + { + "recyclability_observation": "The product can be easily disassembled and materials separated", + "recyclability_comment": "High recyclability rating", + "recyclability_reference": "ISO 14021:2016", + "repairability_observation": "Components are modular and can be replaced individually", + "repairability_comment": "Good repairability score", + "repairability_reference": "EN 45554:2020", + "remanufacturability_observation": "Core components can be refurbished and reused", + "remanufacturability_comment": "Suitable for remanufacturing", + "remanufacturability_reference": "BS 8887-2:2009", + } + ] + } + ) + + +class CircularityPropertiesRead(BaseReadSchemaWithTimeStamp, CircularityPropertiesBase): + """Schema for reading circularity properties.""" + + model_config: ConfigDict = ConfigDict( + json_schema_extra={ + "examples": [ + { + "id": 1, + "recyclability_observation": "The product can be easily disassembled and materials separated", + "recyclability_comment": "High recyclability rating", + "recyclability_reference": "ISO 14021:2016", + "repairability_observation": "Components are modular and can be replaced individually", + "repairability_comment": "Good repairability score", + "repairability_reference": "EN 45554:2020", + "remanufacturability_observation": "Core components can be refurbished and reused", + "remanufacturability_comment": "Suitable for remanufacturing", + "remanufacturability_reference": "BS 8887-2:2009", + } + ] + } + ) + + +class CircularityPropertiesUpdate(BaseUpdateSchema, CircularityPropertiesBase): + """Schema for updating circularity properties.""" + + # Make all fields optional for updates + recyclability_observation: str | None = Field(default=None, min_length=2, max_length=500) + repairability_observation: str | None = Field(default=None, min_length=2, max_length=500) + remanufacturability_observation: str | None = Field(default=None, min_length=2, max_length=500) + + model_config: ConfigDict = ConfigDict( + json_schema_extra={ + "examples": [ + { + "recyclability_observation": "Updated observation on recyclability", + "recyclability_comment": "Updated comment", + } + ] + } + ) + + ### Product Schemas ### @@ -128,6 +194,9 @@ class ProductCreateWithRelationships(ProductCreateBase): physical_properties: PhysicalPropertiesCreate | None = Field( default=None, description="Physical properties of the product" ) + circularity_properties: CircularityPropertiesCreate | None = Field( + default=None, description="Circularity properties of the product" + ) videos: list[VideoCreateWithinProduct] = Field(default_factory=list, description="Disassembly videos") bill_of_materials: list[MaterialProductLinkCreateWithinProduct] = Field( @@ -222,6 +291,7 @@ class ProductReadWithProperties(ProductRead): """Schema for reading product information with all properties.""" physical_properties: PhysicalPropertiesRead | None = None + circularity_properties: CircularityPropertiesRead | None = None class ProductReadWithRelationships(ProductReadWithProperties): @@ -290,3 +360,4 @@ class ProductUpdateWithProperties(ProductUpdate): """Schema for a partial update of a product with properties.""" physical_properties: PhysicalPropertiesUpdate | None = None + circularity_properties: CircularityPropertiesUpdate | None = None From d9d2edb2a68086a6312af894e5588d626e142c04 Mon Sep 17 00:00:00 2001 From: Simon van Lierde Date: Mon, 17 Nov 2025 13:03:44 +0000 Subject: [PATCH 49/71] fix(backend): Don't initialize email checker for on synthetic user creation --- backend/app/api/auth/services/user_manager.py | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/backend/app/api/auth/services/user_manager.py b/backend/app/api/auth/services/user_manager.py index c8a312c..f0ab70d 100644 --- a/backend/app/api/auth/services/user_manager.py +++ b/backend/app/api/auth/services/user_manager.py @@ -58,9 +58,15 @@ async def create( request: Request | None = None, ) -> User: """Override of base user creation with additional username uniqueness check and organization creation.""" - try: + # HACK: Skipping of emails for synthetic users is implemented in an ugly way here + # Skip initialization of email checker if sending registration email is disabled + if request and hasattr(request.state, "send_registration_email") and not request.state.send_registration_email: + email_checker = None + else: # Get email checker from app state if request is available - email_checker = request.app.state.email_checker if request else None + email_checker = request.app.state.email_checker if (request and request.app and hasattr(request.app.state, "email_checker")) else None + + try: user_create = await create_user_override(self.user_db, user_create, email_checker) # HACK: This is a temporary solution to allow error propagation for username and organization creation errors. # The built-in UserManager register route can only catch UserAlreadyExists and InvalidPasswordException errors. From 3b495192ab72c4ff1af0228a553a77c25304c7ea Mon Sep 17 00:00:00 2001 From: Simon van Lierde Date: Mon, 17 Nov 2025 14:30:30 +0100 Subject: [PATCH 50/71] feature(backend): Allow superuser to remove any product --- backend/app/api/data_collection/dependencies.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/backend/app/api/data_collection/dependencies.py b/backend/app/api/data_collection/dependencies.py index 666577a..b8bb5b7 100644 --- a/backend/app/api/data_collection/dependencies.py +++ b/backend/app/api/data_collection/dependencies.py @@ -38,7 +38,7 @@ async def get_user_owned_product( current_user: CurrentActiveVerifiedUserDep, ) -> Product: """Verify that the current user owns the specified product.""" - if product.owner_id == current_user.id: + if product.owner_id == current_user.id or current_user.is_superuser: return product raise UserOwnershipError(model_type=Product, model_id=product.id, user_id=current_user.id) from None From e66f2864482c3ee527309cce2c9c960b554b6fd1 Mon Sep 17 00:00:00 2001 From: Simon van Lierde Date: Mon, 17 Nov 2025 15:00:07 +0100 Subject: [PATCH 51/71] feature(backend): Move from kg to g for physical_properties weight field --- ...fa19f62_move_from_weight_kg_to_weight_g.py | 55 +++++++++++++++++++ backend/app/api/data_collection/filters.py | 4 +- backend/app/api/data_collection/models.py | 2 +- backend/app/api/data_collection/routers.py | 26 ++++----- backend/app/api/data_collection/schemas.py | 12 ++-- backend/scripts/seed/dummy_data.py | 4 +- docs/docs/architecture/datamodel.md | 2 +- .../product/ProductPhysicalProperties.tsx | 2 +- frontend-app/src/services/api/fetching.ts | 4 +- frontend-app/src/services/api/saving.ts | 4 +- 10 files changed, 85 insertions(+), 30 deletions(-) create mode 100644 backend/alembic/versions/0faa2fa19f62_move_from_weight_kg_to_weight_g.py diff --git a/backend/alembic/versions/0faa2fa19f62_move_from_weight_kg_to_weight_g.py b/backend/alembic/versions/0faa2fa19f62_move_from_weight_kg_to_weight_g.py new file mode 100644 index 0000000..3641e9d --- /dev/null +++ b/backend/alembic/versions/0faa2fa19f62_move_from_weight_kg_to_weight_g.py @@ -0,0 +1,55 @@ +"""Move from weight_kg to weight_g + +Revision ID: 0faa2fa19f62 +Revises: b43d157d07f1 +Create Date: 2025-11-17 14:52:08.201228 + +""" + +from collections.abc import Sequence +from typing import Union + +import sqlalchemy as sa +import sqlmodel + +import app.api.common.models.custom_types +from alembic import op + +# revision identifiers, used by Alembic. +revision: str = "0faa2fa19f62" +down_revision: str | None = "b43d157d07f1" +branch_labels: str | Sequence[str] | None = None +depends_on: str | Sequence[str] | None = None + + +def upgrade() -> None: + # ### commands auto generated by Alembic - please adjust! ### + op.add_column("physicalproperties", sa.Column("weight_g", sa.Float(), nullable=True)) + + # Migrate data: convert kg to g (multiply by 1000) + op.execute(""" + UPDATE physicalproperties + SET weight_g = weight_kg * 1000 + WHERE weight_kg IS NOT NULL + """) + + op.drop_column("physicalproperties", "weight_kg") + # ### end Alembic commands ### + + +def downgrade() -> None: + # ### commands auto generated by Alembic - please adjust! ### + op.add_column( + "physicalproperties", + sa.Column("weight_kg", sa.DOUBLE_PRECISION(precision=53), autoincrement=False, nullable=True), + ) + + # Migrate data back: convert g to kg (divide by 1000) + op.execute(""" + UPDATE physicalproperties + SET weight_kg = weight_g / 1000 + WHERE weight_g IS NOT NULL + """) + + op.drop_column("physicalproperties", "weight_g") + # ### end Alembic commands ### diff --git a/backend/app/api/data_collection/filters.py b/backend/app/api/data_collection/filters.py index 4d40d20..47ed408 100644 --- a/backend/app/api/data_collection/filters.py +++ b/backend/app/api/data_collection/filters.py @@ -31,8 +31,8 @@ class Constants(Filter.Constants): class PhysicalPropertiesFilter(Filter): """FastAPI-filter class for Physical Properties filtering.""" - weight_kg__gte: float | None = None - weight_kg__lte: float | None = None + weight_g__gte: float | None = None + weight_g__lte: float | None = None height_cm__gte: float | None = None height_cm__lte: float | None = None width_cm__gte: float | None = None diff --git a/backend/app/api/data_collection/models.py b/backend/app/api/data_collection/models.py index c96f59c..1197b98 100644 --- a/backend/app/api/data_collection/models.py +++ b/backend/app/api/data_collection/models.py @@ -35,7 +35,7 @@ def validate_start_and_end_time(start_time: datetime, end_time: datetime | None) class PhysicalPropertiesBase(CustomBase): """Base model to store physical properties of a product.""" - weight_kg: float | None = Field(default=None, gt=0) + weight_g: float | None = Field(default=None, gt=0) height_cm: float | None = Field(default=None, gt=0) width_cm: float | None = Field(default=None, gt=0) depth_cm: float | None = Field(default=None, gt=0) diff --git a/backend/app/api/data_collection/routers.py b/backend/app/api/data_collection/routers.py index 50cc836..de465ed 100644 --- a/backend/app/api/data_collection/routers.py +++ b/backend/app/api/data_collection/routers.py @@ -389,7 +389,7 @@ async def create_product( "dismantling_time_end": "2025-09-22T16:30:45Z", "product_type_id": 1, "physical_properties": { - "weight_kg": 20, + "weight_g": 2000, "height_cm": 150, "width_cm": 70, "depth_cm": 50, @@ -398,8 +398,8 @@ async def create_product( {"url": "https://www.youtube.com/watch?v=123456789", "description": "Disassembly video"} ], "bill_of_materials": [ - {"quantity": 15, "unit": "kg", "material_id": 1}, - {"quantity": 5, "unit": "kg", "material_id": 2}, + {"quantity": 15, "unit": "g", "material_id": 1}, + {"quantity": 5, "unit": "g", "material_id": 2}, ], }, }, @@ -414,7 +414,7 @@ async def create_product( "dismantling_time_end": "2025-09-22T16:30:45Z", "product_type_id": 1, "physical_properties": { - "weight_kg": 20, + "weight_g": 20000, "height_cm": 150, "width_cm": 70, "depth_cm": 50, @@ -434,7 +434,7 @@ async def create_product( "amount_in_parent": 1, "product_type_id": 2, "physical_properties": { - "weight_kg": 5, + "weight_g": 5000, "height_cm": 50, "width_cm": 40, "depth_cm": 30, @@ -445,15 +445,15 @@ async def create_product( "description": "Seat cushion assembly", "amount_in_parent": 1, "physical_properties": { - "weight_kg": 2, + "weight_g": 2000, "height_cm": 10, "width_cm": 40, "depth_cm": 30, }, "product_type_id": 3, "bill_of_materials": [ - {"quantity": 1.5, "unit": "kg", "material_id": 1}, - {"quantity": 0.5, "unit": "kg", "material_id": 2}, + {"quantity": 1.5, "unit": "g", "material_id": 1}, + {"quantity": 0.5, "unit": "g", "material_id": 2}, ], } ], @@ -668,7 +668,7 @@ async def add_component_to_product( "name": "Seat Assembly", "description": "Chair seat component", "amount_in_parent": 1, - "bill_of_materials": [{"material_id": 1, "quantity": 0.5, "unit": "kg"}], + "bill_of_materials": [{"material_id": 1, "quantity": 0.5, "unit": "g"}], }, }, "nested": { @@ -683,7 +683,7 @@ async def add_component_to_product( "name": "Cushion", "description": "Foam cushion", "amount_in_parent": 1, - "bill_of_materials": [{"material_id": 2, "quantity": 0.3, "unit": "kg"}], + "bill_of_materials": [{"material_id": 2, "quantity": 0.3, "unit": "g"}], } ], }, @@ -1007,8 +1007,8 @@ async def add_materials_to_product( description="List of materials-product links to add to the product", examples=[ [ - {"material_id": 1, "quantity": 5, "unit": "kg"}, - {"material_id": 2, "quantity": 10, "unit": "kg"}, + {"material_id": 1, "quantity": 5, "unit": "g"}, + {"material_id": 2, "quantity": 10, "unit": "g"}, ] ], ), @@ -1035,7 +1035,7 @@ async def add_material_to_product( MaterialProductLinkCreateWithinProductAndMaterial, Body( description="Material-product link details", - examples=[[{"quantity": 5, "unit": "kg"}]], + examples=[[{"quantity": 5, "unit": "g"}]], ), ], session: AsyncSessionDep, diff --git a/backend/app/api/data_collection/schemas.py b/backend/app/api/data_collection/schemas.py index b21355d..32794af 100644 --- a/backend/app/api/data_collection/schemas.py +++ b/backend/app/api/data_collection/schemas.py @@ -76,7 +76,7 @@ class PhysicalPropertiesCreate(BaseCreateSchema, PhysicalPropertiesBase): """Schema for creating physical properties.""" model_config: ConfigDict = ConfigDict( - json_schema_extra={"examples": [{"weight_kg": 20, "height_cm": 150, "width_cm": 70, "depth_cm": 50}]} + json_schema_extra={"examples": [{"weight_g": 20000, "height_cm": 150, "width_cm": 70, "depth_cm": 50}]} ) @@ -84,14 +84,14 @@ class PhysicalPropertiesRead(BaseReadSchemaWithTimeStamp, PhysicalPropertiesBase """Schema for reading physical properties.""" model_config: ConfigDict = ConfigDict( - json_schema_extra={"examples": [{"id": 1, "weight_kg": 20, "height_cm": 150, "width_cm": 70, "depth_cm": 50}]} + json_schema_extra={"examples": [{"id": 1, "weight_g": 20000, "height_cm": 150, "width_cm": 70, "depth_cm": 50}]} ) class PhysicalPropertiesUpdate(BaseUpdateSchema, PhysicalPropertiesBase): """Schema for updating physical properties.""" - model_config: ConfigDict = ConfigDict(json_schema_extra={"examples": [{"weight_kg": 15, "height_cm": 120}]}) + model_config: ConfigDict = ConfigDict(json_schema_extra={"examples": [{"weight_g": 15000, "height_cm": 120}]}) class CircularityPropertiesCreate(BaseCreateSchema, CircularityPropertiesBase): @@ -219,7 +219,7 @@ class ProductCreateBaseProduct(ProductCreateWithRelationships): "dismantling_time_end": "2025-09-22T16:30:45Z", "product_type_id": 1, "physical_properties": { - "weight_kg": 20, + "weight_g": 20000, "height_cm": 150, "width_cm": 70, "depth_cm": 50, @@ -228,8 +228,8 @@ class ProductCreateBaseProduct(ProductCreateWithRelationships): {"url": "https://www.youtube.com/watch?v=123456789", "description": "Disassembly video"} ], "bill_of_materials": [ - {"quantity": 0.3, "unit": "kg", "material_id": 1}, - {"quantity": 0.1, "unit": "kg", "material_id": 2}, + {"quantity": 0.3, "unit": "g", "material_id": 1}, + {"quantity": 0.1, "unit": "g", "material_id": 2}, ], } ] diff --git a/backend/scripts/seed/dummy_data.py b/backend/scripts/seed/dummy_data.py index b084400..e9d4a6e 100755 --- a/backend/scripts/seed/dummy_data.py +++ b/backend/scripts/seed/dummy_data.py @@ -144,7 +144,7 @@ "model": "A2403", "product_type_name": "Smartphone", "physical_properties": { - "weight_kg": 0.164, + "weight_g": 164, "height_cm": 14.7, "width_cm": 7.15, "depth_cm": 0.74, @@ -161,7 +161,7 @@ "model": "XPS9380", "product_type_name": "Laptop", "physical_properties": { - "weight_kg": 1.23, + "weight_g": 1230, "height_cm": 1.16, "width_cm": 30.2, "depth_cm": 19.9, diff --git a/docs/docs/architecture/datamodel.md b/docs/docs/architecture/datamodel.md index 68ac873..315ec0a 100644 --- a/docs/docs/architecture/datamodel.md +++ b/docs/docs/architecture/datamodel.md @@ -207,7 +207,7 @@ erDiagram PHYSICALPROPERTIES { integer id PK - float weight_kg + float weight_g float height_cm float width_cm float depth_cm diff --git a/frontend-app/src/components/product/ProductPhysicalProperties.tsx b/frontend-app/src/components/product/ProductPhysicalProperties.tsx index 9b34019..cb855ce 100644 --- a/frontend-app/src/components/product/ProductPhysicalProperties.tsx +++ b/frontend-app/src/components/product/ProductPhysicalProperties.tsx @@ -13,7 +13,7 @@ interface Props { } const unitMap = { - weight: 'kg', + weight: 'g', height: 'cm', width: 'cm', depth: 'cm', diff --git a/frontend-app/src/services/api/fetching.ts b/frontend-app/src/services/api/fetching.ts index a46662b..9cb423b 100644 --- a/frontend-app/src/services/api/fetching.ts +++ b/frontend-app/src/services/api/fetching.ts @@ -15,7 +15,7 @@ type ProductData = { created_at: string; updated_at: string; product_type_id: number; - physical_properties: { weight_kg: number; height_cm: number; width_cm: number; depth_cm: number }; + physical_properties: { weight_g: number; height_cm: number; width_cm: number; depth_cm: number }; circularity_properties: { recyclability_comment: string | null; recyclability_observation: string; @@ -63,7 +63,7 @@ async function toProduct(data: ProductData): Promise { ownedBy: data.owner_id === meId ? 'me' : data.owner_id, amountInParent: data.amount_in_parent ?? undefined, physicalProperties: { - weight: data.physical_properties.weight_kg, + weight: data.physical_properties.weight_g, height: data.physical_properties.height_cm, width: data.physical_properties.width_cm, depth: data.physical_properties.depth_cm, diff --git a/frontend-app/src/services/api/saving.ts b/frontend-app/src/services/api/saving.ts index 8c9936e..46ac57c 100644 --- a/frontend-app/src/services/api/saving.ts +++ b/frontend-app/src/services/api/saving.ts @@ -18,7 +18,7 @@ function toNewProduct(product: Product): any { bill_of_materials: [ { quantity: 42, - unit: 'kg', + unit: 'g', material_id: 1, }, ], @@ -47,7 +47,7 @@ function toUpdateProduct(product: Product): any { function toUpdatePhysicalProperties(product: Product): any { return { - weight_kg: product.physicalProperties.weight || null, + weight_g: product.physicalProperties.weight || null, height_cm: product.physicalProperties.height || null, width_cm: product.physicalProperties.width || null, depth_cm: product.physicalProperties.depth || null, From 0cd5def5901bd8a940a4b22a263790166ceb8d51 Mon Sep 17 00:00:00 2001 From: Simon van Lierde Date: Mon, 17 Nov 2025 15:44:42 +0100 Subject: [PATCH 52/71] feature: paginate users/me/products --- backend/app/api/data_collection/routers.py | 17 ++++++++++++++--- frontend-app/src/services/api/fetching.ts | 3 +-- 2 files changed, 15 insertions(+), 5 deletions(-) diff --git a/backend/app/api/data_collection/routers.py b/backend/app/api/data_collection/routers.py index de465ed..8fdc0f9 100644 --- a/backend/app/api/data_collection/routers.py +++ b/backend/app/api/data_collection/routers.py @@ -106,7 +106,7 @@ async def redirect_to_current_user_products( @user_product_router.get( "", - response_model=list[ProductReadWithRelationshipsAndFlatComponents], + response_model=Page[ProductReadWithRelationshipsAndFlatComponents], summary="Get products collected by a user", ) async def get_user_products( @@ -139,18 +139,29 @@ async def get_user_products( }, ), ] = None, + *, + include_components_as_base_products: Annotated[ + bool | None, + Query(description="Whether to include components as base products in the response"), + ] = None, ) -> Sequence[Product]: """Get products collected by a specific user.""" # NOTE: If needed, we can open up this endpoint to any user by removing this ownership check if user_id != current_user.id and not current_user.is_superuser: raise HTTPException(status_code=403, detail="Not authorized to view this user's products") + + statement=(select(Product).where(Product.owner_id == user_id)) + + if not include_components_as_base_products: + statement: SelectOfScalar[Product] = statement.where(Product.parent_id == None) - return await get_models( + return await get_paginated_models( session, Product, include_relationships=include, model_filter=product_filter, - statement=(select(Product).where(Product.owner_id == user_id)), + statement=statement, + read_schema=ProductReadWithRelationshipsAndFlatComponents, ) diff --git a/frontend-app/src/services/api/fetching.ts b/frontend-app/src/services/api/fetching.ts index 9cb423b..ba932b0 100644 --- a/frontend-app/src/services/api/fetching.ts +++ b/frontend-app/src/services/api/fetching.ts @@ -203,8 +203,7 @@ export async function myProducts( const data = await response.json(); - // TODO: Update to data.items when adding pagination to /users/me/products endpoint - const product_data = data as ProductData[]; + const product_data = data.items as ProductData[]; return Promise.all(product_data.map((data) => toProduct(data))); } From 100039d7ffcb6abc71ec1b107385b79abe16f013 Mon Sep 17 00:00:00 2001 From: Simon van Lierde Date: Mon, 24 Nov 2025 10:20:34 +0000 Subject: [PATCH 53/71] fix(backend): make circularity properties optional --- backend/app/api/data_collection/models.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/backend/app/api/data_collection/models.py b/backend/app/api/data_collection/models.py index 1197b98..c981167 100644 --- a/backend/app/api/data_collection/models.py +++ b/backend/app/api/data_collection/models.py @@ -65,17 +65,17 @@ class CircularityPropertiesBase(CustomBase): """Base model to store circularity properties of a product.""" # Recyclability - recyclability_observation: str = Field(min_length=2, max_length=500) + recyclability_observation: str | None = Field(default=None, min_length=2, max_length=500) recyclability_comment: str | None = Field(default=None, max_length=100) recyclability_reference: str | None = Field(default=None, max_length=100) # Repairability - repairability_observation: str = Field(min_length=2, max_length=500) + repairability_observation: str | None = Field(default=None, min_length=2, max_length=500) repairability_comment: str | None = Field(default=None, max_length=100) repairability_reference: str | None = Field(default=None, max_length=100) # Remanufacturability - remanufacturability_observation: str = Field(min_length=2, max_length=500) + remanufacturability_observation: str | None = Field(default=None, min_length=2, max_length=500) remanufacturability_comment: str | None = Field(default=None, max_length=100) remanufacturability_reference: str | None = Field(default=None, max_length=100) From 71a680e38604a49dc83cae7d3d5f66245b5bacb1 Mon Sep 17 00:00:00 2001 From: Simon van Lierde Date: Tue, 25 Nov 2025 10:10:56 +0000 Subject: [PATCH 54/71] chore(backend): Update to python 3.14 --- backend/.python-version | 2 +- backend/Dockerfile | 5 +- backend/Dockerfile.dev | 2 +- backend/Dockerfile.migrations | 3 +- backend/uv.lock | 532 +++++++++++++++++++--------------- codemeta.json | 2 +- 6 files changed, 307 insertions(+), 239 deletions(-) diff --git a/backend/.python-version b/backend/.python-version index 24ee5b1..6324d40 100644 --- a/backend/.python-version +++ b/backend/.python-version @@ -1 +1 @@ -3.13 +3.14 diff --git a/backend/Dockerfile b/backend/Dockerfile index 15ca725..17b19a7 100644 --- a/backend/Dockerfile +++ b/backend/Dockerfile @@ -1,6 +1,5 @@ # --- Builder stage --- -# TODO: Move to Python 3.14 once asyncpg supports it (version 0.31.0+, see https://github.com/MagicStack/asyncpg/issues/1282) -FROM ghcr.io/astral-sh/uv:0.9-python3.13-trixie-slim AS builder +FROM ghcr.io/astral-sh/uv:0.9-python3.14-trixie-slim AS builder # Install git for custom dependencies (fastapi-users-db-sqlmodel) RUN --mount=type=cache,target=/var/cache/apt,sharing=locked \ @@ -35,7 +34,7 @@ RUN --mount=type=cache,target=/root/.cache/uv \ uv sync --locked --no-editable --no-default-groups --group=api # --- Final runtime stage --- -FROM python:3.13-slim +FROM python:3.14-slim # Build arguments ARG WORKDIR=/opt/relab/backend diff --git a/backend/Dockerfile.dev b/backend/Dockerfile.dev index 5609289..36cea79 100644 --- a/backend/Dockerfile.dev +++ b/backend/Dockerfile.dev @@ -1,6 +1,6 @@ # Development Dockerfile for FastAPI Backend # Note: This requires mounting the source code as a volume in docker-compose.override.yml -FROM ghcr.io/astral-sh/uv:0.9-python3.13-trixie-slim +FROM ghcr.io/astral-sh/uv:0.9-python3.14-trixie-slim # Build arguments ARG WORKDIR=/opt/relab/backend diff --git a/backend/Dockerfile.migrations b/backend/Dockerfile.migrations index 6c03c35..8d32ac9 100644 --- a/backend/Dockerfile.migrations +++ b/backend/Dockerfile.migrations @@ -1,6 +1,5 @@ # --- Builder stage --- -FROM ghcr.io/astral-sh/uv:0.9-python3.13-trixie-slim AS builder - +FROM ghcr.io/astral-sh/uv:0.9-python3.14-trixie-slim AS builder WORKDIR /opt/relab/backend_migrations # Install git for custom dependencies (fastapi-users-db-sqlmodel) diff --git a/backend/uv.lock b/backend/uv.lock index c60bc1c..2f9bde6 100644 --- a/backend/uv.lock +++ b/backend/uv.lock @@ -17,16 +17,16 @@ wheels = [ [[package]] name = "alembic" -version = "1.17.1" +version = "1.17.2" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "mako" }, { name = "sqlalchemy" }, { name = "typing-extensions" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/6e/b6/2a81d7724c0c124edc5ec7a167e85858b6fd31b9611c6fb8ecf617b7e2d3/alembic-1.17.1.tar.gz", hash = "sha256:8a289f6778262df31571d29cca4c7fbacd2f0f582ea0816f4c399b6da7528486", size = 1981285, upload-time = "2025-10-29T00:23:16.667Z" } +sdist = { url = "https://files.pythonhosted.org/packages/02/a6/74c8cadc2882977d80ad756a13857857dbcf9bd405bc80b662eb10651282/alembic-1.17.2.tar.gz", hash = "sha256:bbe9751705c5e0f14877f02d46c53d10885e377e3d90eda810a016f9baa19e8e", size = 1988064, upload-time = "2025-11-14T20:35:04.057Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/a5/32/7df1d81ec2e50fb661944a35183d87e62d3f6c6d9f8aff64a4f245226d55/alembic-1.17.1-py3-none-any.whl", hash = "sha256:cbc2386e60f89608bb63f30d2d6cc66c7aaed1fe105bd862828600e5ad167023", size = 247848, upload-time = "2025-10-29T00:23:18.79Z" }, + { url = "https://files.pythonhosted.org/packages/ba/88/6237e97e3385b57b5f1528647addea5cc03d4d65d5979ab24327d41fb00d/alembic-1.17.2-py3-none-any.whl", hash = "sha256:f483dd1fe93f6c5d49217055e4d15b905b425b6af906746abb35b69c1996c4e6", size = 248554, upload-time = "2025-11-14T20:35:05.699Z" }, ] [[package]] @@ -57,11 +57,11 @@ wheels = [ [[package]] name = "annotated-doc" -version = "0.0.3" +version = "0.0.4" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/d7/a6/dc46877b911e40c00d395771ea710d5e77b6de7bacd5fdcd78d70cc5a48f/annotated_doc-0.0.3.tar.gz", hash = "sha256:e18370014c70187422c33e945053ff4c286f453a984eba84d0dbfa0c935adeda", size = 5535, upload-time = "2025-10-24T14:57:10.718Z" } +sdist = { url = "https://files.pythonhosted.org/packages/57/ba/046ceea27344560984e26a590f90bc7f4a75b06701f653222458922b558c/annotated_doc-0.0.4.tar.gz", hash = "sha256:fbcda96e87e9c92ad167c2e53839e57503ecfda18804ea28102353485033faa4", size = 7288, upload-time = "2025-11-10T22:07:42.062Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/02/b7/cf592cb5de5cb3bade3357f8d2cf42bf103bbe39f459824b4939fd212911/annotated_doc-0.0.3-py3-none-any.whl", hash = "sha256:348ec6664a76f1fd3be81f43dffbee4c7e8ce931ba71ec67cc7f4ade7fbbb580", size = 5488, upload-time = "2025-10-24T14:57:09.462Z" }, + { url = "https://files.pythonhosted.org/packages/1e/d3/26bf1008eb3d2daa8ef4cacc7f3bfdc11818d111f7e2d0201bc6e3b49d45/annotated_doc-0.0.4-py3-none-any.whl", hash = "sha256:571ac1dc6991c450b25a9c2d84a3705e2ae7a53467b5d111c24fa8baabbed320", size = 5303, upload-time = "2025-11-10T22:07:40.673Z" }, ] [[package]] @@ -143,18 +143,34 @@ wheels = [ [[package]] name = "asyncpg" -version = "0.30.0" +version = "0.31.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/2f/4c/7c991e080e106d854809030d8584e15b2e996e26f16aee6d757e387bc17d/asyncpg-0.30.0.tar.gz", hash = "sha256:c551e9928ab6707602f44811817f82ba3c446e018bfe1d3abecc8ba5f3eac851", size = 957746, upload-time = "2024-10-20T00:30:41.127Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/3a/22/e20602e1218dc07692acf70d5b902be820168d6282e69ef0d3cb920dc36f/asyncpg-0.30.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:05b185ebb8083c8568ea8a40e896d5f7af4b8554b64d7719c0eaa1eb5a5c3a70", size = 670373, upload-time = "2024-10-20T00:29:55.165Z" }, - { url = "https://files.pythonhosted.org/packages/3d/b3/0cf269a9d647852a95c06eb00b815d0b95a4eb4b55aa2d6ba680971733b9/asyncpg-0.30.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:c47806b1a8cbb0a0db896f4cd34d89942effe353a5035c62734ab13b9f938da3", size = 634745, upload-time = "2024-10-20T00:29:57.14Z" }, - { url = "https://files.pythonhosted.org/packages/8e/6d/a4f31bf358ce8491d2a31bfe0d7bcf25269e80481e49de4d8616c4295a34/asyncpg-0.30.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9b6fde867a74e8c76c71e2f64f80c64c0f3163e687f1763cfaf21633ec24ec33", size = 3512103, upload-time = "2024-10-20T00:29:58.499Z" }, - { url = "https://files.pythonhosted.org/packages/96/19/139227a6e67f407b9c386cb594d9628c6c78c9024f26df87c912fabd4368/asyncpg-0.30.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:46973045b567972128a27d40001124fbc821c87a6cade040cfcd4fa8a30bcdc4", size = 3592471, upload-time = "2024-10-20T00:30:00.354Z" }, - { url = "https://files.pythonhosted.org/packages/67/e4/ab3ca38f628f53f0fd28d3ff20edff1c975dd1cb22482e0061916b4b9a74/asyncpg-0.30.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:9110df111cabc2ed81aad2f35394a00cadf4f2e0635603db6ebbd0fc896f46a4", size = 3496253, upload-time = "2024-10-20T00:30:02.794Z" }, - { url = "https://files.pythonhosted.org/packages/ef/5f/0bf65511d4eeac3a1f41c54034a492515a707c6edbc642174ae79034d3ba/asyncpg-0.30.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:04ff0785ae7eed6cc138e73fc67b8e51d54ee7a3ce9b63666ce55a0bf095f7ba", size = 3662720, upload-time = "2024-10-20T00:30:04.501Z" }, - { url = "https://files.pythonhosted.org/packages/e7/31/1513d5a6412b98052c3ed9158d783b1e09d0910f51fbe0e05f56cc370bc4/asyncpg-0.30.0-cp313-cp313-win32.whl", hash = "sha256:ae374585f51c2b444510cdf3595b97ece4f233fde739aa14b50e0d64e8a7a590", size = 560404, upload-time = "2024-10-20T00:30:06.537Z" }, - { url = "https://files.pythonhosted.org/packages/c8/a4/cec76b3389c4c5ff66301cd100fe88c318563ec8a520e0b2e792b5b84972/asyncpg-0.30.0-cp313-cp313-win_amd64.whl", hash = "sha256:f59b430b8e27557c3fb9869222559f7417ced18688375825f8f12302c34e915e", size = 621623, upload-time = "2024-10-20T00:30:09.024Z" }, +sdist = { url = "https://files.pythonhosted.org/packages/fe/cc/d18065ce2380d80b1bcce927c24a2642efd38918e33fd724bc4bca904877/asyncpg-0.31.0.tar.gz", hash = "sha256:c989386c83940bfbd787180f2b1519415e2d3d6277a70d9d0f0145ac73500735", size = 993667, upload-time = "2025-11-24T23:27:00.812Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/95/11/97b5c2af72a5d0b9bc3fa30cd4b9ce22284a9a943a150fdc768763caf035/asyncpg-0.31.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:c204fab1b91e08b0f47e90a75d1b3c62174dab21f670ad6c5d0f243a228f015b", size = 661111, upload-time = "2025-11-24T23:26:04.467Z" }, + { url = "https://files.pythonhosted.org/packages/1b/71/157d611c791a5e2d0423f09f027bd499935f0906e0c2a416ce712ba51ef3/asyncpg-0.31.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:54a64f91839ba59008eccf7aad2e93d6e3de688d796f35803235ea1c4898ae1e", size = 636928, upload-time = "2025-11-24T23:26:05.944Z" }, + { url = "https://files.pythonhosted.org/packages/2e/fc/9e3486fb2bbe69d4a867c0b76d68542650a7ff1574ca40e84c3111bb0c6e/asyncpg-0.31.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:c0e0822b1038dc7253b337b0f3f676cadc4ac31b126c5d42691c39691962e403", size = 3424067, upload-time = "2025-11-24T23:26:07.957Z" }, + { url = "https://files.pythonhosted.org/packages/12/c6/8c9d076f73f07f995013c791e018a1cd5f31823c2a3187fc8581706aa00f/asyncpg-0.31.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:bef056aa502ee34204c161c72ca1f3c274917596877f825968368b2c33f585f4", size = 3518156, upload-time = "2025-11-24T23:26:09.591Z" }, + { url = "https://files.pythonhosted.org/packages/ae/3b/60683a0baf50fbc546499cfb53132cb6835b92b529a05f6a81471ab60d0c/asyncpg-0.31.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:0bfbcc5b7ffcd9b75ab1558f00db2ae07db9c80637ad1b2469c43df79d7a5ae2", size = 3319636, upload-time = "2025-11-24T23:26:11.168Z" }, + { url = "https://files.pythonhosted.org/packages/50/dc/8487df0f69bd398a61e1792b3cba0e47477f214eff085ba0efa7eac9ce87/asyncpg-0.31.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:22bc525ebbdc24d1261ecbf6f504998244d4e3be1721784b5f64664d61fbe602", size = 3472079, upload-time = "2025-11-24T23:26:13.164Z" }, + { url = "https://files.pythonhosted.org/packages/13/a1/c5bbeeb8531c05c89135cb8b28575ac2fac618bcb60119ee9696c3faf71c/asyncpg-0.31.0-cp313-cp313-win32.whl", hash = "sha256:f890de5e1e4f7e14023619399a471ce4b71f5418cd67a51853b9910fdfa73696", size = 527606, upload-time = "2025-11-24T23:26:14.78Z" }, + { url = "https://files.pythonhosted.org/packages/91/66/b25ccb84a246b470eb943b0107c07edcae51804912b824054b3413995a10/asyncpg-0.31.0-cp313-cp313-win_amd64.whl", hash = "sha256:dc5f2fa9916f292e5c5c8b2ac2813763bcd7f58e130055b4ad8a0531314201ab", size = 596569, upload-time = "2025-11-24T23:26:16.189Z" }, + { url = "https://files.pythonhosted.org/packages/3c/36/e9450d62e84a13aea6580c83a47a437f26c7ca6fa0f0fd40b6670793ea30/asyncpg-0.31.0-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:f6b56b91bb0ffc328c4e3ed113136cddd9deefdf5f79ab448598b9772831df44", size = 660867, upload-time = "2025-11-24T23:26:17.631Z" }, + { url = "https://files.pythonhosted.org/packages/82/4b/1d0a2b33b3102d210439338e1beea616a6122267c0df459ff0265cd5807a/asyncpg-0.31.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:334dec28cf20d7f5bb9e45b39546ddf247f8042a690bff9b9573d00086e69cb5", size = 638349, upload-time = "2025-11-24T23:26:19.689Z" }, + { url = "https://files.pythonhosted.org/packages/41/aa/e7f7ac9a7974f08eff9183e392b2d62516f90412686532d27e196c0f0eeb/asyncpg-0.31.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:98cc158c53f46de7bb677fd20c417e264fc02b36d901cc2a43bd6cb0dc6dbfd2", size = 3410428, upload-time = "2025-11-24T23:26:21.275Z" }, + { url = "https://files.pythonhosted.org/packages/6f/de/bf1b60de3dede5c2731e6788617a512bc0ebd9693eac297ee74086f101d7/asyncpg-0.31.0-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:9322b563e2661a52e3cdbc93eed3be7748b289f792e0011cb2720d278b366ce2", size = 3471678, upload-time = "2025-11-24T23:26:23.627Z" }, + { url = "https://files.pythonhosted.org/packages/46/78/fc3ade003e22d8bd53aaf8f75f4be48f0b460fa73738f0391b9c856a9147/asyncpg-0.31.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:19857a358fc811d82227449b7ca40afb46e75b33eb8897240c3839dd8b744218", size = 3313505, upload-time = "2025-11-24T23:26:25.235Z" }, + { url = "https://files.pythonhosted.org/packages/bf/e9/73eb8a6789e927816f4705291be21f2225687bfa97321e40cd23055e903a/asyncpg-0.31.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:ba5f8886e850882ff2c2ace5732300e99193823e8107e2c53ef01c1ebfa1e85d", size = 3434744, upload-time = "2025-11-24T23:26:26.944Z" }, + { url = "https://files.pythonhosted.org/packages/08/4b/f10b880534413c65c5b5862f79b8e81553a8f364e5238832ad4c0af71b7f/asyncpg-0.31.0-cp314-cp314-win32.whl", hash = "sha256:cea3a0b2a14f95834cee29432e4ddc399b95700eb1d51bbc5bfee8f31fa07b2b", size = 532251, upload-time = "2025-11-24T23:26:28.404Z" }, + { url = "https://files.pythonhosted.org/packages/d3/2d/7aa40750b7a19efa5d66e67fc06008ca0f27ba1bd082e457ad82f59aba49/asyncpg-0.31.0-cp314-cp314-win_amd64.whl", hash = "sha256:04d19392716af6b029411a0264d92093b6e5e8285ae97a39957b9a9c14ea72be", size = 604901, upload-time = "2025-11-24T23:26:30.34Z" }, + { url = "https://files.pythonhosted.org/packages/ce/fe/b9dfe349b83b9dee28cc42360d2c86b2cdce4cb551a2c2d27e156bcac84d/asyncpg-0.31.0-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:bdb957706da132e982cc6856bb2f7b740603472b54c3ebc77fe60ea3e57e1bd2", size = 702280, upload-time = "2025-11-24T23:26:32Z" }, + { url = "https://files.pythonhosted.org/packages/6a/81/e6be6e37e560bd91e6c23ea8a6138a04fd057b08cf63d3c5055c98e81c1d/asyncpg-0.31.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:6d11b198111a72f47154fa03b85799f9be63701e068b43f84ac25da0bda9cb31", size = 682931, upload-time = "2025-11-24T23:26:33.572Z" }, + { url = "https://files.pythonhosted.org/packages/a6/45/6009040da85a1648dd5bc75b3b0a062081c483e75a1a29041ae63a0bf0dc/asyncpg-0.31.0-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:18c83b03bc0d1b23e6230f5bf8d4f217dc9bc08644ce0502a9d91dc9e634a9c7", size = 3581608, upload-time = "2025-11-24T23:26:35.638Z" }, + { url = "https://files.pythonhosted.org/packages/7e/06/2e3d4d7608b0b2b3adbee0d0bd6a2d29ca0fc4d8a78f8277df04e2d1fd7b/asyncpg-0.31.0-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:e009abc333464ff18b8f6fd146addffd9aaf63e79aa3bb40ab7a4c332d0c5e9e", size = 3498738, upload-time = "2025-11-24T23:26:37.275Z" }, + { url = "https://files.pythonhosted.org/packages/7d/aa/7d75ede780033141c51d83577ea23236ba7d3a23593929b32b49db8ed36e/asyncpg-0.31.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:3b1fbcb0e396a5ca435a8826a87e5c2c2cc0c8c68eb6fadf82168056b0e53a8c", size = 3401026, upload-time = "2025-11-24T23:26:39.423Z" }, + { url = "https://files.pythonhosted.org/packages/ba/7a/15e37d45e7f7c94facc1e9148c0e455e8f33c08f0b8a0b1deb2c5171771b/asyncpg-0.31.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:8df714dba348efcc162d2adf02d213e5fab1bd9f557e1305633e851a61814a7a", size = 3429426, upload-time = "2025-11-24T23:26:41.032Z" }, + { url = "https://files.pythonhosted.org/packages/13/d5/71437c5f6ae5f307828710efbe62163974e71237d5d46ebd2869ea052d10/asyncpg-0.31.0-cp314-cp314t-win32.whl", hash = "sha256:1b41f1afb1033f2b44f3234993b15096ddc9cd71b21a42dbd87fc6a57b43d65d", size = 614495, upload-time = "2025-11-24T23:26:42.659Z" }, + { url = "https://files.pythonhosted.org/packages/3c/d7/8fb3044eaef08a310acfe23dae9a8e2e07d305edc29a53497e52bc76eca7/asyncpg-0.31.0-cp314-cp314t-win_amd64.whl", hash = "sha256:bd4107bb7cdd0e9e65fae66a62afd3a249663b844fa34d479f6d5b3bef9c04c3", size = 706062, upload-time = "2025-11-24T23:26:44.086Z" }, ] [[package]] @@ -231,30 +247,30 @@ wheels = [ [[package]] name = "boto3" -version = "1.40.69" +version = "1.41.3" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "botocore" }, { name = "jmespath" }, { name = "s3transfer" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/56/36/65d292d14261aedbb9a22e5bf194d84c119c889135b42448db646d06d76b/boto3-1.40.69.tar.gz", hash = "sha256:5273f6bac347331a87db809dff97d8736c50c3be19f2bb36ad08c5131c408976", size = 111628, upload-time = "2025-11-07T20:26:26.949Z" } +sdist = { url = "https://files.pythonhosted.org/packages/90/30/1f1bfb34a97709b5d004d5c16ccac81a73ea6c5ce86ce75eaff0a75aee3f/boto3-1.41.3.tar.gz", hash = "sha256:8a89f3900a356879022c1600f72cbb3d8b85708f094d2d08a461bd193d0b07ca", size = 111614, upload-time = "2025-11-24T20:22:33.007Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/4d/2f/65009a8d274cd9c7211807c1a07cce17203ffe76368e3ebc4ca03a7b79de/boto3-1.40.69-py3-none-any.whl", hash = "sha256:c3f710a1990c4be1c0db43b938743d4e404c7f1f06d5f1fa0c8e9b1cea4290b2", size = 139361, upload-time = "2025-11-07T20:26:24.522Z" }, + { url = "https://files.pythonhosted.org/packages/37/d3/56e8c147e369fdc1b5526584f87151ca1742949bf5e6ab7500d926107624/boto3-1.41.3-py3-none-any.whl", hash = "sha256:10a3f5a72e071c362f5aa8443bd949edc31b7494c48a315ccdab14b1c387a1fd", size = 139345, upload-time = "2025-11-24T20:22:30.601Z" }, ] [[package]] name = "botocore" -version = "1.40.69" +version = "1.41.3" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "jmespath" }, { name = "python-dateutil" }, { name = "urllib3" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/e2/73/42499b183ca5cef25c35338ad2636368b0ae2193654642756492e96ee906/botocore-1.40.69.tar.gz", hash = "sha256:df310ddc4d2de5543ba3df4e4b5f9907a2951896d63a9fbae115c26ca0976951", size = 14440352, upload-time = "2025-11-07T20:26:14.276Z" } +sdist = { url = "https://files.pythonhosted.org/packages/8c/e9/d6207e08f35280cb8755b316f0e0a0cd2e8405d1b849e847c26fb4e3e3a6/botocore-1.41.3.tar.gz", hash = "sha256:1c6ad338f445c9bf02e231bfa302239d60520ec6dd88ded3206b34dca100103c", size = 14658770, upload-time = "2025-11-24T20:22:21.929Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/61/d6/bf2b91d4a92af6ee70e0689913414463a48cf51c0fc855c98b94bde8e7f3/botocore-1.40.69-py3-none-any.whl", hash = "sha256:5d810efeb9e18f91f32690642fa81ae60e482eefeea0d35ec72da2e3d924c1a5", size = 14103454, upload-time = "2025-11-07T20:26:09.486Z" }, + { url = "https://files.pythonhosted.org/packages/9f/18/a0597e4491d3a725768162c48a4dd1e1a57323fdb40fca04a34e9a68ef93/botocore-1.41.3-py3-none-any.whl", hash = "sha256:fe2379b30cc726e9e44bf47c3834fe208b85f7eaa57b934ab05f305ca9d05a8b", size = 14328009, upload-time = "2025-11-24T20:22:17.618Z" }, ] [[package]] @@ -268,11 +284,11 @@ wheels = [ [[package]] name = "certifi" -version = "2025.10.5" +version = "2025.11.12" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/4c/5b/b6ce21586237c77ce67d01dc5507039d444b630dd76611bbca2d8e5dcd91/certifi-2025.10.5.tar.gz", hash = "sha256:47c09d31ccf2acf0be3f701ea53595ee7e0b8fa08801c6624be771df09ae7b43", size = 164519, upload-time = "2025-10-05T04:12:15.808Z" } +sdist = { url = "https://files.pythonhosted.org/packages/a2/8c/58f469717fa48465e4a50c014a0400602d3c437d7c0c468e17ada824da3a/certifi-2025.11.12.tar.gz", hash = "sha256:d8ab5478f2ecd78af242878415affce761ca6bc54a22a27e026d7c25357c3316", size = 160538, upload-time = "2025-11-12T02:54:51.517Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/e4/37/af0d2ef3967ac0d6113837b44a4f0bfe1328c2b9763bd5b1744520e5cfed/certifi-2025.10.5-py3-none-any.whl", hash = "sha256:0f212c2744a9bb6de0c56639a6f68afe01ecd92d91f14ae897c4fe7bbeeef0de", size = 163286, upload-time = "2025-10-05T04:12:14.03Z" }, + { url = "https://files.pythonhosted.org/packages/70/7d/9bc192684cea499815ff478dfcdc13835ddf401365057044fb721ec6bddb/certifi-2025.11.12-py3-none-any.whl", hash = "sha256:97de8790030bbd5c2d96b7ec782fc2f7820ef8dba6db909ccf95449f2d062d4b", size = 159438, upload-time = "2025-11-12T02:54:49.735Z" }, ] [[package]] @@ -363,14 +379,14 @@ wheels = [ [[package]] name = "click" -version = "8.3.0" +version = "8.3.1" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "colorama", marker = "sys_platform == 'win32'" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/46/61/de6cd827efad202d7057d93e0fed9294b96952e188f7384832791c7b2254/click-8.3.0.tar.gz", hash = "sha256:e7b8232224eba16f4ebe410c25ced9f7875cb5f3263ffc93cc3e8da705e229c4", size = 276943, upload-time = "2025-09-18T17:32:23.696Z" } +sdist = { url = "https://files.pythonhosted.org/packages/3d/fa/656b739db8587d7b5dfa22e22ed02566950fbfbcdc20311993483657a5c0/click-8.3.1.tar.gz", hash = "sha256:12ff4785d337a1bb490bb7e9c2b1ee5da3112e94a8622f26a6c77f5d2fc6842a", size = 295065, upload-time = "2025-11-15T20:45:42.706Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/db/d3/9dcc0f5797f070ec8edf30fbadfb200e71d9db6b84d211e3b2085a7589a0/click-8.3.0-py3-none-any.whl", hash = "sha256:9b9f285302c6e3064f4330c05f05b81945b2a39544279343e6e7c5f27a9baddc", size = 107295, upload-time = "2025-09-18T17:32:22.42Z" }, + { url = "https://files.pythonhosted.org/packages/98/78/01c019cdb5d6498122777c1a43056ebb3ebfeef2076d9d026bfe15583b2b/click-8.3.1-py3-none-any.whl", hash = "sha256:981153a64e25f12d547d3426c367a4857371575ee7ad18df2a6183ab0545b2a6", size = 108274, upload-time = "2025-11-15T20:45:41.139Z" }, ] [[package]] @@ -396,63 +412,63 @@ wheels = [ [[package]] name = "coverage" -version = "7.11.1" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/89/12/3e2d2ec71796e0913178478e693a06af6a3bc9f7f9cb899bf85a426d8370/coverage-7.11.1.tar.gz", hash = "sha256:b4b3a072559578129a9e863082a2972a2abd8975bc0e2ec57da96afcd6580a8a", size = 814037, upload-time = "2025-11-07T10:52:41.067Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/f4/01/0c50c318f5e8f1a482da05d788d0ff06137803ed8fface4a1ba51e04b3ad/coverage-7.11.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:da9930594ca99d66eb6f613d7beba850db2f8dfa86810ee35ae24e4d5f2bb97d", size = 216920, upload-time = "2025-11-07T10:50:55.992Z" }, - { url = "https://files.pythonhosted.org/packages/20/11/9f038e6c2baea968c377ab355b0d1d0a46b5f38985691bf51164e1b78c1f/coverage-7.11.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:cc47a280dc014220b0fc6e5f55082a3f51854faf08fd9635b8a4f341c46c77d3", size = 217301, upload-time = "2025-11-07T10:50:57.609Z" }, - { url = "https://files.pythonhosted.org/packages/68/cd/9dcf93d81d0cddaa0bba90c3b4580e6f1ddf833918b816930d250cc553a4/coverage-7.11.1-cp313-cp313-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:74003324321bbf130939146886eddf92e48e616b5910215e79dea6edeb8ee7c8", size = 248277, upload-time = "2025-11-07T10:50:59.442Z" }, - { url = "https://files.pythonhosted.org/packages/11/f5/b2c7c494046c9c783d3cac4c812fc24d6104dd36a7a598e7dd6fea3e7927/coverage-7.11.1-cp313-cp313-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:211f7996265daab60a8249af4ca6641b3080769cbedcffc42cc4841118f3a305", size = 250871, upload-time = "2025-11-07T10:51:01.094Z" }, - { url = "https://files.pythonhosted.org/packages/a5/5a/b359649566954498aa17d7c98093182576d9e435ceb4ea917b3b48d56f86/coverage-7.11.1-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:70619d194d8fea0cb028cb6bb9c85b519c7509c1d1feef1eea635183bc8ecd27", size = 252115, upload-time = "2025-11-07T10:51:03.087Z" }, - { url = "https://files.pythonhosted.org/packages/f3/17/3cef1ede3739622950f0737605353b797ec564e70c9d254521b10f4b03ba/coverage-7.11.1-cp313-cp313-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:e0208bb59d441cfa3321569040f8e455f9261256e0df776c5462a1e5a9b31e13", size = 248442, upload-time = "2025-11-07T10:51:04.888Z" }, - { url = "https://files.pythonhosted.org/packages/5f/63/d5854c47ae42d9d18855329db6bc528f5b7f4f874257edb00cf8b483f9f8/coverage-7.11.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:545714d8765bda1c51f8b1c96e0b497886a054471c68211e76ef49dd1468587d", size = 250253, upload-time = "2025-11-07T10:51:06.515Z" }, - { url = "https://files.pythonhosted.org/packages/48/e8/c7706f8a5358a59c18b489e7e19e83d6161b7c8bc60771f95920570c94a8/coverage-7.11.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:d0a2b02c1e20158dd405054bcca87f91fd5b7605626aee87150819ea616edd67", size = 248217, upload-time = "2025-11-07T10:51:08.405Z" }, - { url = "https://files.pythonhosted.org/packages/5b/c9/a2136dfb168eb09e2f6d9d6b6c986243fdc0b3866a9376adb263d3c3378b/coverage-7.11.1-cp313-cp313-musllinux_1_2_riscv64.whl", hash = "sha256:e0f4aa986a4308a458e0fb572faa3eb3db2ea7ce294604064b25ab32b435a468", size = 248040, upload-time = "2025-11-07T10:51:10.626Z" }, - { url = "https://files.pythonhosted.org/packages/18/9a/a63991c0608ddc6adf65e6f43124951aaf36bd79f41937b028120b8268ea/coverage-7.11.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:d51cc6687e8bbfd1e041f52baed0f979cd592242cf50bf18399a7e03afc82d88", size = 249801, upload-time = "2025-11-07T10:51:12.63Z" }, - { url = "https://files.pythonhosted.org/packages/84/19/947acf7c0c6e90e4ec3abf474133ed36d94407d07e36eafdfd3acb59fee9/coverage-7.11.1-cp313-cp313-win32.whl", hash = "sha256:1b3067db3afe6deeca2b2c9f0ec23820d5f1bd152827acfadf24de145dfc5f66", size = 219430, upload-time = "2025-11-07T10:51:14.329Z" }, - { url = "https://files.pythonhosted.org/packages/35/54/36fef7afb3884450c7b6d494fcabe2fab7c669d547c800ca30f41c1dc212/coverage-7.11.1-cp313-cp313-win_amd64.whl", hash = "sha256:39a4c44b0cd40e3c9d89b2b7303ebd6ab9ae8a63f9e9a8c4d65a181a0b33aebe", size = 220239, upload-time = "2025-11-07T10:51:16.418Z" }, - { url = "https://files.pythonhosted.org/packages/d3/dc/7d38bb99e8e69200b7dd5de15507226bd90eac102dfc7cc891b9934cdc76/coverage-7.11.1-cp313-cp313-win_arm64.whl", hash = "sha256:a2e3560bf82fa8169a577e054cbbc29888699526063fee26ea59ea2627fd6e73", size = 218868, upload-time = "2025-11-07T10:51:18.186Z" }, - { url = "https://files.pythonhosted.org/packages/36/c6/d1ff54fbd6bcad42dbcfd13b417e636ef84aae194353b1ef3361700f2525/coverage-7.11.1-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:47a4f362a10285897ab3aa7a4b37d28213a4f2626823923613d6d7a3584dd79a", size = 217615, upload-time = "2025-11-07T10:51:21.065Z" }, - { url = "https://files.pythonhosted.org/packages/73/f9/6ed59e7cf1488d6f975e5b14ef836f5e537913523e92175135f8518a83ce/coverage-7.11.1-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:0df35fa7419ef571db9dacd50b0517bc54dbfe37eb94043b5fc3540bff276acd", size = 217960, upload-time = "2025-11-07T10:51:22.797Z" }, - { url = "https://files.pythonhosted.org/packages/c4/74/2dab1dc2ebe16f074f80ae483b0f45faf278d102be703ac01b32cd85b6c3/coverage-7.11.1-cp313-cp313t-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:e1a2c621d341c9d56f7917e56fbb56be4f73fe0d0e8dae28352fb095060fd467", size = 259262, upload-time = "2025-11-07T10:51:24.467Z" }, - { url = "https://files.pythonhosted.org/packages/15/49/eccfe039663e29a50a54b0c2c8d076acd174d7ac50d018ef8a5b1c37c8dc/coverage-7.11.1-cp313-cp313t-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:6c354b111be9b2234d9573d75dd30ca4e414b7659c730e477e89be4f620b3fb5", size = 261326, upload-time = "2025-11-07T10:51:26.232Z" }, - { url = "https://files.pythonhosted.org/packages/f0/bb/2b829aa23fd5ee8318e33cc02a606eb09900921291497963adc3f06af8bb/coverage-7.11.1-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:4589bd44698728f600233fb2881014c9b8ec86637ef454c00939e779661dbe7e", size = 263758, upload-time = "2025-11-07T10:51:27.912Z" }, - { url = "https://files.pythonhosted.org/packages/ac/03/d44c3d70e5da275caf2cad2071da6b425412fbcb1d1d5a81f1f89b45e3f1/coverage-7.11.1-cp313-cp313t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:c6956fc8754f2309131230272a7213a483a32ecbe29e2b9316d808a28f2f8ea1", size = 258444, upload-time = "2025-11-07T10:51:30.107Z" }, - { url = "https://files.pythonhosted.org/packages/a9/c1/cf61d9f46ae088774c65dd3387a15dfbc72de90c1f6e105025e9eda19b42/coverage-7.11.1-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:63926a97ed89dc6a087369b92dcb8b9a94cead46c08b33a7f1f4818cd8b6a3c3", size = 261335, upload-time = "2025-11-07T10:51:31.814Z" }, - { url = "https://files.pythonhosted.org/packages/95/9a/b3299bb14f11f2364d78a2b9704491b15395e757af6116694731ce4e5834/coverage-7.11.1-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:f5311ba00c53a7fb2b293fdc1f478b7286fe2a845a7ba9cda053f6e98178f0b4", size = 258951, upload-time = "2025-11-07T10:51:33.925Z" }, - { url = "https://files.pythonhosted.org/packages/3f/a3/73cb2763e59f14ba6d8d6444b1f640a9be2242bfb59b7e50581c695db7ff/coverage-7.11.1-cp313-cp313t-musllinux_1_2_riscv64.whl", hash = "sha256:31bf5ffad84c974f9e72ac53493350f36b6fa396109159ec704210698f12860b", size = 257840, upload-time = "2025-11-07T10:51:36.092Z" }, - { url = "https://files.pythonhosted.org/packages/85/db/482e72589a952027e238ffa3a15f192c552e0685fd0c5220ad05b5f17d56/coverage-7.11.1-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:227ee59fbc4a8c57a7383a1d7af6ca94a78ae3beee4045f38684548a8479a65b", size = 260040, upload-time = "2025-11-07T10:51:38.277Z" }, - { url = "https://files.pythonhosted.org/packages/18/a1/b931d3ee099c2dca8e9ea56c07ae84c0f91562f7bbbcccab8c91b3474ef1/coverage-7.11.1-cp313-cp313t-win32.whl", hash = "sha256:a447d97b3ce680bb1da2e6bd822ebb71be6a1fb77ce2c2ad2fe4bd8aacec3058", size = 220102, upload-time = "2025-11-07T10:51:40.017Z" }, - { url = "https://files.pythonhosted.org/packages/9a/53/b553b7bfa6207def4918f0cb72884c844fa4c3f1566e58fbb4f34e54cdc5/coverage-7.11.1-cp313-cp313t-win_amd64.whl", hash = "sha256:d6d11180437c67bde2248563a42b8e5bbf85c8df78fae13bf818ad17bfb15f02", size = 221166, upload-time = "2025-11-07T10:51:41.921Z" }, - { url = "https://files.pythonhosted.org/packages/6b/45/1c1d58b3ed585598764bd2fe41fcf60ccafe15973ad621c322ba52e22d32/coverage-7.11.1-cp313-cp313t-win_arm64.whl", hash = "sha256:1e19a4c43d612760c6f7190411fb157e2d8a6dde00c91b941d43203bd3b17f6f", size = 219439, upload-time = "2025-11-07T10:51:43.753Z" }, - { url = "https://files.pythonhosted.org/packages/d9/c2/ac2c3417eaa4de1361036ebbc7da664242b274b2e00c4b4a1cfc7b29920b/coverage-7.11.1-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:0305463c45c5f21f0396cd5028de92b1f1387e2e0756a85dd3147daa49f7a674", size = 216967, upload-time = "2025-11-07T10:51:45.55Z" }, - { url = "https://files.pythonhosted.org/packages/5e/a3/afef455d03c468ee303f9df9a6f407e8bea64cd576fca914ff888faf52ca/coverage-7.11.1-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:fa4d468d5efa1eb6e3062be8bd5f45cbf28257a37b71b969a8c1da2652dfec77", size = 217298, upload-time = "2025-11-07T10:51:47.31Z" }, - { url = "https://files.pythonhosted.org/packages/9d/59/6e2fb3fb58637001132dc32228b4fb5b332d75d12f1353cb00fe084ee0ba/coverage-7.11.1-cp314-cp314-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:d2b2f5fc8fe383cbf2d5c77d6c4b2632ede553bc0afd0cdc910fa5390046c290", size = 248337, upload-time = "2025-11-07T10:51:49.48Z" }, - { url = "https://files.pythonhosted.org/packages/1d/5e/ce442bab963e3388658da8bde6ddbd0a15beda230afafaa25e3c487dc391/coverage-7.11.1-cp314-cp314-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:bde6488c1ad509f4fb1a4f9960fd003d5a94adef61e226246f9699befbab3276", size = 250853, upload-time = "2025-11-07T10:51:51.215Z" }, - { url = "https://files.pythonhosted.org/packages/d1/2f/43f94557924ca9b64e09f1c3876da4eec44a05a41e27b8a639d899716c0e/coverage-7.11.1-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:a69e0d6fa0b920fe6706a898c52955ec5bcfa7e45868215159f45fd87ea6da7c", size = 252190, upload-time = "2025-11-07T10:51:53.262Z" }, - { url = "https://files.pythonhosted.org/packages/8c/fa/a04e769b92bc5628d4bd909dcc3c8219efe5e49f462e29adc43e198ecfde/coverage-7.11.1-cp314-cp314-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:976e51e4a549b80e4639eda3a53e95013a14ff6ad69bb58ed604d34deb0e774c", size = 248335, upload-time = "2025-11-07T10:51:55.388Z" }, - { url = "https://files.pythonhosted.org/packages/99/d0/b98ab5d2abe425c71117a7c690ead697a0b32b83256bf0f566c726b7f77b/coverage-7.11.1-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:d61fcc4d384c82971a3d9cf00d0872881f9ded19404c714d6079b7a4547e2955", size = 250209, upload-time = "2025-11-07T10:51:57.263Z" }, - { url = "https://files.pythonhosted.org/packages/9c/3f/b9c4fbd2e6d1b64098f99fb68df7f7c1b3e0a0968d24025adb24f359cdec/coverage-7.11.1-cp314-cp314-musllinux_1_2_i686.whl", hash = "sha256:284c5df762b533fae3ebd764e3b81c20c1c9648d93ef34469759cb4e3dfe13d0", size = 248163, upload-time = "2025-11-07T10:51:59.014Z" }, - { url = "https://files.pythonhosted.org/packages/08/fc/3e4d54fb6368b0628019eefd897fc271badbd025410fd5421a65fb58758f/coverage-7.11.1-cp314-cp314-musllinux_1_2_riscv64.whl", hash = "sha256:bab32cb1d4ad2ac6dcc4e17eee5fa136c2a1d14ae914e4bce6c8b78273aece3c", size = 247983, upload-time = "2025-11-07T10:52:01.027Z" }, - { url = "https://files.pythonhosted.org/packages/b9/4a/a5700764a12e932b35afdddb2f59adbca289c1689455d06437f609f3ef35/coverage-7.11.1-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:36f2fed9ce392ca450fb4e283900d0b41f05c8c5db674d200f471498be3ce747", size = 249646, upload-time = "2025-11-07T10:52:02.856Z" }, - { url = "https://files.pythonhosted.org/packages/0e/2c/45ed33d9e80a1cc9b44b4bd535d44c154d3204671c65abd90ec1e99522a2/coverage-7.11.1-cp314-cp314-win32.whl", hash = "sha256:853136cecb92a5ba1cc8f61ec6ffa62ca3c88b4b386a6c835f8b833924f9a8c5", size = 219700, upload-time = "2025-11-07T10:52:05.05Z" }, - { url = "https://files.pythonhosted.org/packages/90/d7/5845597360f6434af1290118ebe114642865f45ce47e7e822d9c07b371be/coverage-7.11.1-cp314-cp314-win_amd64.whl", hash = "sha256:77443d39143e20927259a61da0c95d55ffc31cf43086b8f0f11a92da5260d592", size = 220516, upload-time = "2025-11-07T10:52:07.259Z" }, - { url = "https://files.pythonhosted.org/packages/ae/d0/d311a06f9cf7a48a98ffcfd0c57db0dcab6da46e75c439286a50dc648161/coverage-7.11.1-cp314-cp314-win_arm64.whl", hash = "sha256:829acb88fa47591a64bf5197e96a931ce9d4b3634c7f81a224ba3319623cdf6c", size = 219091, upload-time = "2025-11-07T10:52:09.216Z" }, - { url = "https://files.pythonhosted.org/packages/a7/3d/c6a84da4fa9b840933045b19dd19d17b892f3f2dd1612903260291416dba/coverage-7.11.1-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:2ad1fe321d9522ea14399de83e75a11fb6a8887930c3679feb383301c28070d9", size = 217700, upload-time = "2025-11-07T10:52:11.348Z" }, - { url = "https://files.pythonhosted.org/packages/94/10/a4fc5022017dd7ac682dc423849c241dfbdad31734b8f96060d84e70b587/coverage-7.11.1-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:f69c332f0c3d1357c74decc9b1843fcd428cf9221bf196a20ad22aa1db3e1b6c", size = 217968, upload-time = "2025-11-07T10:52:13.203Z" }, - { url = "https://files.pythonhosted.org/packages/59/2d/a554cd98924d296de5816413280ac3b09e42a05fb248d66f8d474d321938/coverage-7.11.1-cp314-cp314t-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:576baeea4eebde684bf6c91c01e97171c8015765c8b2cfd4022a42b899897811", size = 259334, upload-time = "2025-11-07T10:52:15.079Z" }, - { url = "https://files.pythonhosted.org/packages/05/98/d484cb659ec33958ca96b6f03438f56edc23b239d1ad0417b7a97fc1848a/coverage-7.11.1-cp314-cp314t-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:28ad84c694fa86084cfd3c1eab4149844b8cb95bd8e5cbfc4a647f3ee2cce2b3", size = 261445, upload-time = "2025-11-07T10:52:17.134Z" }, - { url = "https://files.pythonhosted.org/packages/f3/fa/920cba122cc28f4557c0507f8bd7c6e527ebcc537d0309186f66464a8fd9/coverage-7.11.1-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:b1043ff958f09fc3f552c014d599f3c6b7088ba97d7bc1bd1cce8603cd75b520", size = 263858, upload-time = "2025-11-07T10:52:19.836Z" }, - { url = "https://files.pythonhosted.org/packages/2a/a0/036397bdbee0f3bd46c2e26fdfbb1a61b2140bf9059240c37b61149047fa/coverage-7.11.1-cp314-cp314t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:c6681add5060c2742dafcf29826dff1ff8eef889a3b03390daeed84361c428bd", size = 258381, upload-time = "2025-11-07T10:52:21.687Z" }, - { url = "https://files.pythonhosted.org/packages/b6/61/2533926eb8990f182eb287f4873216c8ca530cc47241144aabf46fe80abe/coverage-7.11.1-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:773419b225ec9a75caa1e941dd0c83a91b92c2b525269e44e6ee3e4c630607db", size = 261321, upload-time = "2025-11-07T10:52:23.612Z" }, - { url = "https://files.pythonhosted.org/packages/32/6e/618f7e203a998e4f6b8a0fa395744a416ad2adbcdc3735bc19466456718a/coverage-7.11.1-cp314-cp314t-musllinux_1_2_i686.whl", hash = "sha256:a9cb272a0e0157dbb9b2fd0b201b759bd378a1a6138a16536c025c2ce4f7643b", size = 258933, upload-time = "2025-11-07T10:52:25.514Z" }, - { url = "https://files.pythonhosted.org/packages/22/40/6b1c27f772cb08a14a338647ead1254a57ee9dabbb4cacbc15df7f278741/coverage-7.11.1-cp314-cp314t-musllinux_1_2_riscv64.whl", hash = "sha256:e09adb2a7811dc75998eef68f47599cf699e2b62eed09c9fefaeb290b3920f34", size = 257756, upload-time = "2025-11-07T10:52:27.845Z" }, - { url = "https://files.pythonhosted.org/packages/73/07/f9cd12f71307a785ea15b009c8d8cc2543e4a867bd04b8673843970b6b43/coverage-7.11.1-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:1335fa8c2a2fea49924d97e1e3500cfe8d7c849f5369f26bb7559ad4259ccfab", size = 260086, upload-time = "2025-11-07T10:52:29.776Z" }, - { url = "https://files.pythonhosted.org/packages/34/02/31c5394f6f5d72a466966bcfdb61ce5a19862d452816d6ffcbb44add16ee/coverage-7.11.1-cp314-cp314t-win32.whl", hash = "sha256:4782d71d2a4fa7cef95e853b7097c8bbead4dbd0e6f9c7152a6b11a194b794db", size = 220483, upload-time = "2025-11-07T10:52:31.752Z" }, - { url = "https://files.pythonhosted.org/packages/7f/96/81e1ef5fbfd5090113a96e823dbe055e4c58d96ca73b1fb0ad9d26f9ec36/coverage-7.11.1-cp314-cp314t-win_amd64.whl", hash = "sha256:939f45e66eceb63c75e8eb8fc58bb7077c00f1a41b0e15c6ef02334a933cfe93", size = 221592, upload-time = "2025-11-07T10:52:33.724Z" }, - { url = "https://files.pythonhosted.org/packages/38/7a/a5d050de44951ac453a2046a0f3fb5471a4a557f0c914d00db27d543d94c/coverage-7.11.1-cp314-cp314t-win_arm64.whl", hash = "sha256:01c575bdbef35e3f023b50a146e9a75c53816e4f2569109458155cd2315f87d9", size = 219627, upload-time = "2025-11-07T10:52:36.285Z" }, - { url = "https://files.pythonhosted.org/packages/76/32/bd9f48c28e23b2f08946f8e83983617b00619f5538dbd7e1045fa7e88c00/coverage-7.11.1-py3-none-any.whl", hash = "sha256:0fa848acb5f1da24765cee840e1afe9232ac98a8f9431c6112c15b34e880b9e8", size = 208689, upload-time = "2025-11-07T10:52:38.646Z" }, +version = "7.12.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/89/26/4a96807b193b011588099c3b5c89fbb05294e5b90e71018e065465f34eb6/coverage-7.12.0.tar.gz", hash = "sha256:fc11e0a4e372cb5f282f16ef90d4a585034050ccda536451901abfb19a57f40c", size = 819341, upload-time = "2025-11-18T13:34:20.766Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/b8/14/771700b4048774e48d2c54ed0c674273702713c9ee7acdfede40c2666747/coverage-7.12.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:47324fffca8d8eae7e185b5bb20c14645f23350f870c1649003618ea91a78941", size = 217725, upload-time = "2025-11-18T13:32:49.22Z" }, + { url = "https://files.pythonhosted.org/packages/17/a7/3aa4144d3bcb719bf67b22d2d51c2d577bf801498c13cb08f64173e80497/coverage-7.12.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:ccf3b2ede91decd2fb53ec73c1f949c3e034129d1e0b07798ff1d02ea0c8fa4a", size = 218098, upload-time = "2025-11-18T13:32:50.78Z" }, + { url = "https://files.pythonhosted.org/packages/fc/9c/b846bbc774ff81091a12a10203e70562c91ae71badda00c5ae5b613527b1/coverage-7.12.0-cp313-cp313-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:b365adc70a6936c6b0582dc38746b33b2454148c02349345412c6e743efb646d", size = 249093, upload-time = "2025-11-18T13:32:52.554Z" }, + { url = "https://files.pythonhosted.org/packages/76/b6/67d7c0e1f400b32c883e9342de4a8c2ae7c1a0b57c5de87622b7262e2309/coverage-7.12.0-cp313-cp313-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:bc13baf85cd8a4cfcf4a35c7bc9d795837ad809775f782f697bf630b7e200211", size = 251686, upload-time = "2025-11-18T13:32:54.862Z" }, + { url = "https://files.pythonhosted.org/packages/cc/75/b095bd4b39d49c3be4bffbb3135fea18a99a431c52dd7513637c0762fecb/coverage-7.12.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:099d11698385d572ceafb3288a5b80fe1fc58bf665b3f9d362389de488361d3d", size = 252930, upload-time = "2025-11-18T13:32:56.417Z" }, + { url = "https://files.pythonhosted.org/packages/6e/f3/466f63015c7c80550bead3093aacabf5380c1220a2a93c35d374cae8f762/coverage-7.12.0-cp313-cp313-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:473dc45d69694069adb7680c405fb1e81f60b2aff42c81e2f2c3feaf544d878c", size = 249296, upload-time = "2025-11-18T13:32:58.074Z" }, + { url = "https://files.pythonhosted.org/packages/27/86/eba2209bf2b7e28c68698fc13437519a295b2d228ba9e0ec91673e09fa92/coverage-7.12.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:583f9adbefd278e9de33c33d6846aa8f5d164fa49b47144180a0e037f0688bb9", size = 251068, upload-time = "2025-11-18T13:32:59.646Z" }, + { url = "https://files.pythonhosted.org/packages/ec/55/ca8ae7dbba962a3351f18940b359b94c6bafdd7757945fdc79ec9e452dc7/coverage-7.12.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:b2089cc445f2dc0af6f801f0d1355c025b76c24481935303cf1af28f636688f0", size = 249034, upload-time = "2025-11-18T13:33:01.481Z" }, + { url = "https://files.pythonhosted.org/packages/7a/d7/39136149325cad92d420b023b5fd900dabdd1c3a0d1d5f148ef4a8cedef5/coverage-7.12.0-cp313-cp313-musllinux_1_2_riscv64.whl", hash = "sha256:950411f1eb5d579999c5f66c62a40961f126fc71e5e14419f004471957b51508", size = 248853, upload-time = "2025-11-18T13:33:02.935Z" }, + { url = "https://files.pythonhosted.org/packages/fe/b6/76e1add8b87ef60e00643b0b7f8f7bb73d4bf5249a3be19ebefc5793dd25/coverage-7.12.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:b1aab7302a87bafebfe76b12af681b56ff446dc6f32ed178ff9c092ca776e6bc", size = 250619, upload-time = "2025-11-18T13:33:04.336Z" }, + { url = "https://files.pythonhosted.org/packages/95/87/924c6dc64f9203f7a3c1832a6a0eee5a8335dbe5f1bdadcc278d6f1b4d74/coverage-7.12.0-cp313-cp313-win32.whl", hash = "sha256:d7e0d0303c13b54db495eb636bc2465b2fb8475d4c8bcec8fe4b5ca454dfbae8", size = 220261, upload-time = "2025-11-18T13:33:06.493Z" }, + { url = "https://files.pythonhosted.org/packages/91/77/dd4aff9af16ff776bf355a24d87eeb48fc6acde54c907cc1ea89b14a8804/coverage-7.12.0-cp313-cp313-win_amd64.whl", hash = "sha256:ce61969812d6a98a981d147d9ac583a36ac7db7766f2e64a9d4d059c2fe29d07", size = 221072, upload-time = "2025-11-18T13:33:07.926Z" }, + { url = "https://files.pythonhosted.org/packages/70/49/5c9dc46205fef31b1b226a6e16513193715290584317fd4df91cdaf28b22/coverage-7.12.0-cp313-cp313-win_arm64.whl", hash = "sha256:bcec6f47e4cb8a4c2dc91ce507f6eefc6a1b10f58df32cdc61dff65455031dfc", size = 219702, upload-time = "2025-11-18T13:33:09.631Z" }, + { url = "https://files.pythonhosted.org/packages/9b/62/f87922641c7198667994dd472a91e1d9b829c95d6c29529ceb52132436ad/coverage-7.12.0-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:459443346509476170d553035e4a3eed7b860f4fe5242f02de1010501956ce87", size = 218420, upload-time = "2025-11-18T13:33:11.153Z" }, + { url = "https://files.pythonhosted.org/packages/85/dd/1cc13b2395ef15dbb27d7370a2509b4aee77890a464fb35d72d428f84871/coverage-7.12.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:04a79245ab2b7a61688958f7a855275997134bc84f4a03bc240cf64ff132abf6", size = 218773, upload-time = "2025-11-18T13:33:12.569Z" }, + { url = "https://files.pythonhosted.org/packages/74/40/35773cc4bb1e9d4658d4fb669eb4195b3151bef3bbd6f866aba5cd5dac82/coverage-7.12.0-cp313-cp313t-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:09a86acaaa8455f13d6a99221d9654df249b33937b4e212b4e5a822065f12aa7", size = 260078, upload-time = "2025-11-18T13:33:14.037Z" }, + { url = "https://files.pythonhosted.org/packages/ec/ee/231bb1a6ffc2905e396557585ebc6bdc559e7c66708376d245a1f1d330fc/coverage-7.12.0-cp313-cp313t-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:907e0df1b71ba77463687a74149c6122c3f6aac56c2510a5d906b2f368208560", size = 262144, upload-time = "2025-11-18T13:33:15.601Z" }, + { url = "https://files.pythonhosted.org/packages/28/be/32f4aa9f3bf0b56f3971001b56508352c7753915345d45fab4296a986f01/coverage-7.12.0-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:9b57e2d0ddd5f0582bae5437c04ee71c46cd908e7bc5d4d0391f9a41e812dd12", size = 264574, upload-time = "2025-11-18T13:33:17.354Z" }, + { url = "https://files.pythonhosted.org/packages/68/7c/00489fcbc2245d13ab12189b977e0cf06ff3351cb98bc6beba8bd68c5902/coverage-7.12.0-cp313-cp313t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:58c1c6aa677f3a1411fe6fb28ec3a942e4f665df036a3608816e0847fad23296", size = 259298, upload-time = "2025-11-18T13:33:18.958Z" }, + { url = "https://files.pythonhosted.org/packages/96/b4/f0760d65d56c3bea95b449e02570d4abd2549dc784bf39a2d4721a2d8ceb/coverage-7.12.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:4c589361263ab2953e3c4cd2a94db94c4ad4a8e572776ecfbad2389c626e4507", size = 262150, upload-time = "2025-11-18T13:33:20.644Z" }, + { url = "https://files.pythonhosted.org/packages/c5/71/9a9314df00f9326d78c1e5a910f520d599205907432d90d1c1b7a97aa4b1/coverage-7.12.0-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:91b810a163ccad2e43b1faa11d70d3cf4b6f3d83f9fd5f2df82a32d47b648e0d", size = 259763, upload-time = "2025-11-18T13:33:22.189Z" }, + { url = "https://files.pythonhosted.org/packages/10/34/01a0aceed13fbdf925876b9a15d50862eb8845454301fe3cdd1df08b2182/coverage-7.12.0-cp313-cp313t-musllinux_1_2_riscv64.whl", hash = "sha256:40c867af715f22592e0d0fb533a33a71ec9e0f73a6945f722a0c85c8c1cbe3a2", size = 258653, upload-time = "2025-11-18T13:33:24.239Z" }, + { url = "https://files.pythonhosted.org/packages/8d/04/81d8fd64928acf1574bbb0181f66901c6c1c6279c8ccf5f84259d2c68ae9/coverage-7.12.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:68b0d0a2d84f333de875666259dadf28cc67858bc8fd8b3f1eae84d3c2bec455", size = 260856, upload-time = "2025-11-18T13:33:26.365Z" }, + { url = "https://files.pythonhosted.org/packages/f2/76/fa2a37bfaeaf1f766a2d2360a25a5297d4fb567098112f6517475eee120b/coverage-7.12.0-cp313-cp313t-win32.whl", hash = "sha256:73f9e7fbd51a221818fd11b7090eaa835a353ddd59c236c57b2199486b116c6d", size = 220936, upload-time = "2025-11-18T13:33:28.165Z" }, + { url = "https://files.pythonhosted.org/packages/f9/52/60f64d932d555102611c366afb0eb434b34266b1d9266fc2fe18ab641c47/coverage-7.12.0-cp313-cp313t-win_amd64.whl", hash = "sha256:24cff9d1f5743f67db7ba46ff284018a6e9aeb649b67aa1e70c396aa1b7cb23c", size = 222001, upload-time = "2025-11-18T13:33:29.656Z" }, + { url = "https://files.pythonhosted.org/packages/77/df/c303164154a5a3aea7472bf323b7c857fed93b26618ed9fc5c2955566bb0/coverage-7.12.0-cp313-cp313t-win_arm64.whl", hash = "sha256:c87395744f5c77c866d0f5a43d97cc39e17c7f1cb0115e54a2fe67ca75c5d14d", size = 220273, upload-time = "2025-11-18T13:33:31.415Z" }, + { url = "https://files.pythonhosted.org/packages/bf/2e/fc12db0883478d6e12bbd62d481210f0c8daf036102aa11434a0c5755825/coverage-7.12.0-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:a1c59b7dc169809a88b21a936eccf71c3895a78f5592051b1af8f4d59c2b4f92", size = 217777, upload-time = "2025-11-18T13:33:32.86Z" }, + { url = "https://files.pythonhosted.org/packages/1f/c1/ce3e525d223350c6ec16b9be8a057623f54226ef7f4c2fee361ebb6a02b8/coverage-7.12.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:8787b0f982e020adb732b9f051f3e49dd5054cebbc3f3432061278512a2b1360", size = 218100, upload-time = "2025-11-18T13:33:34.532Z" }, + { url = "https://files.pythonhosted.org/packages/15/87/113757441504aee3808cb422990ed7c8bcc2d53a6779c66c5adef0942939/coverage-7.12.0-cp314-cp314-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:5ea5a9f7dc8877455b13dd1effd3202e0bca72f6f3ab09f9036b1bcf728f69ac", size = 249151, upload-time = "2025-11-18T13:33:36.135Z" }, + { url = "https://files.pythonhosted.org/packages/d9/1d/9529d9bd44049b6b05bb319c03a3a7e4b0a8a802d28fa348ad407e10706d/coverage-7.12.0-cp314-cp314-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:fdba9f15849534594f60b47c9a30bc70409b54947319a7c4fd0e8e3d8d2f355d", size = 251667, upload-time = "2025-11-18T13:33:37.996Z" }, + { url = "https://files.pythonhosted.org/packages/11/bb/567e751c41e9c03dc29d3ce74b8c89a1e3396313e34f255a2a2e8b9ebb56/coverage-7.12.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:a00594770eb715854fb1c57e0dea08cce6720cfbc531accdb9850d7c7770396c", size = 253003, upload-time = "2025-11-18T13:33:39.553Z" }, + { url = "https://files.pythonhosted.org/packages/e4/b3/c2cce2d8526a02fb9e9ca14a263ca6fc074449b33a6afa4892838c903528/coverage-7.12.0-cp314-cp314-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:5560c7e0d82b42eb1951e4f68f071f8017c824ebfd5a6ebe42c60ac16c6c2434", size = 249185, upload-time = "2025-11-18T13:33:42.086Z" }, + { url = "https://files.pythonhosted.org/packages/0e/a7/967f93bb66e82c9113c66a8d0b65ecf72fc865adfba5a145f50c7af7e58d/coverage-7.12.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:d6c2e26b481c9159c2773a37947a9718cfdc58893029cdfb177531793e375cfc", size = 251025, upload-time = "2025-11-18T13:33:43.634Z" }, + { url = "https://files.pythonhosted.org/packages/b9/b2/f2f6f56337bc1af465d5b2dc1ee7ee2141b8b9272f3bf6213fcbc309a836/coverage-7.12.0-cp314-cp314-musllinux_1_2_i686.whl", hash = "sha256:6e1a8c066dabcde56d5d9fed6a66bc19a2883a3fe051f0c397a41fc42aedd4cc", size = 248979, upload-time = "2025-11-18T13:33:46.04Z" }, + { url = "https://files.pythonhosted.org/packages/f4/7a/bf4209f45a4aec09d10a01a57313a46c0e0e8f4c55ff2965467d41a92036/coverage-7.12.0-cp314-cp314-musllinux_1_2_riscv64.whl", hash = "sha256:f7ba9da4726e446d8dd8aae5a6cd872511184a5d861de80a86ef970b5dacce3e", size = 248800, upload-time = "2025-11-18T13:33:47.546Z" }, + { url = "https://files.pythonhosted.org/packages/b8/b7/1e01b8696fb0521810f60c5bbebf699100d6754183e6cc0679bf2ed76531/coverage-7.12.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:e0f483ab4f749039894abaf80c2f9e7ed77bbf3c737517fb88c8e8e305896a17", size = 250460, upload-time = "2025-11-18T13:33:49.537Z" }, + { url = "https://files.pythonhosted.org/packages/71/ae/84324fb9cb46c024760e706353d9b771a81b398d117d8c1fe010391c186f/coverage-7.12.0-cp314-cp314-win32.whl", hash = "sha256:76336c19a9ef4a94b2f8dc79f8ac2da3f193f625bb5d6f51a328cd19bfc19933", size = 220533, upload-time = "2025-11-18T13:33:51.16Z" }, + { url = "https://files.pythonhosted.org/packages/e2/71/1033629deb8460a8f97f83e6ac4ca3b93952e2b6f826056684df8275e015/coverage-7.12.0-cp314-cp314-win_amd64.whl", hash = "sha256:7c1059b600aec6ef090721f8f633f60ed70afaffe8ecab85b59df748f24b31fe", size = 221348, upload-time = "2025-11-18T13:33:52.776Z" }, + { url = "https://files.pythonhosted.org/packages/0a/5f/ac8107a902f623b0c251abdb749be282dc2ab61854a8a4fcf49e276fce2f/coverage-7.12.0-cp314-cp314-win_arm64.whl", hash = "sha256:172cf3a34bfef42611963e2b661302a8931f44df31629e5b1050567d6b90287d", size = 219922, upload-time = "2025-11-18T13:33:54.316Z" }, + { url = "https://files.pythonhosted.org/packages/79/6e/f27af2d4da367f16077d21ef6fe796c874408219fa6dd3f3efe7751bd910/coverage-7.12.0-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:aa7d48520a32cb21c7a9b31f81799e8eaec7239db36c3b670be0fa2403828d1d", size = 218511, upload-time = "2025-11-18T13:33:56.343Z" }, + { url = "https://files.pythonhosted.org/packages/67/dd/65fd874aa460c30da78f9d259400d8e6a4ef457d61ab052fd248f0050558/coverage-7.12.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:90d58ac63bc85e0fb919f14d09d6caa63f35a5512a2205284b7816cafd21bb03", size = 218771, upload-time = "2025-11-18T13:33:57.966Z" }, + { url = "https://files.pythonhosted.org/packages/55/e0/7c6b71d327d8068cb79c05f8f45bf1b6145f7a0de23bbebe63578fe5240a/coverage-7.12.0-cp314-cp314t-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:ca8ecfa283764fdda3eae1bdb6afe58bf78c2c3ec2b2edcb05a671f0bba7b3f9", size = 260151, upload-time = "2025-11-18T13:33:59.597Z" }, + { url = "https://files.pythonhosted.org/packages/49/ce/4697457d58285b7200de6b46d606ea71066c6e674571a946a6ea908fb588/coverage-7.12.0-cp314-cp314t-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:874fe69a0785d96bd066059cd4368022cebbec1a8958f224f0016979183916e6", size = 262257, upload-time = "2025-11-18T13:34:01.166Z" }, + { url = "https://files.pythonhosted.org/packages/2f/33/acbc6e447aee4ceba88c15528dbe04a35fb4d67b59d393d2e0d6f1e242c1/coverage-7.12.0-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:5b3c889c0b8b283a24d721a9eabc8ccafcfc3aebf167e4cd0d0e23bf8ec4e339", size = 264671, upload-time = "2025-11-18T13:34:02.795Z" }, + { url = "https://files.pythonhosted.org/packages/87/ec/e2822a795c1ed44d569980097be839c5e734d4c0c1119ef8e0a073496a30/coverage-7.12.0-cp314-cp314t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:8bb5b894b3ec09dcd6d3743229dc7f2c42ef7787dc40596ae04c0edda487371e", size = 259231, upload-time = "2025-11-18T13:34:04.397Z" }, + { url = "https://files.pythonhosted.org/packages/72/c5/a7ec5395bb4a49c9b7ad97e63f0c92f6bf4a9e006b1393555a02dae75f16/coverage-7.12.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:79a44421cd5fba96aa57b5e3b5a4d3274c449d4c622e8f76882d76635501fd13", size = 262137, upload-time = "2025-11-18T13:34:06.068Z" }, + { url = "https://files.pythonhosted.org/packages/67/0c/02c08858b764129f4ecb8e316684272972e60777ae986f3865b10940bdd6/coverage-7.12.0-cp314-cp314t-musllinux_1_2_i686.whl", hash = "sha256:33baadc0efd5c7294f436a632566ccc1f72c867f82833eb59820ee37dc811c6f", size = 259745, upload-time = "2025-11-18T13:34:08.04Z" }, + { url = "https://files.pythonhosted.org/packages/5a/04/4fd32b7084505f3829a8fe45c1a74a7a728cb251aaadbe3bec04abcef06d/coverage-7.12.0-cp314-cp314t-musllinux_1_2_riscv64.whl", hash = "sha256:c406a71f544800ef7e9e0000af706b88465f3573ae8b8de37e5f96c59f689ad1", size = 258570, upload-time = "2025-11-18T13:34:09.676Z" }, + { url = "https://files.pythonhosted.org/packages/48/35/2365e37c90df4f5342c4fa202223744119fe31264ee2924f09f074ea9b6d/coverage-7.12.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:e71bba6a40883b00c6d571599b4627f50c360b3d0d02bfc658168936be74027b", size = 260899, upload-time = "2025-11-18T13:34:11.259Z" }, + { url = "https://files.pythonhosted.org/packages/05/56/26ab0464ca733fa325e8e71455c58c1c374ce30f7c04cebb88eabb037b18/coverage-7.12.0-cp314-cp314t-win32.whl", hash = "sha256:9157a5e233c40ce6613dead4c131a006adfda70e557b6856b97aceed01b0e27a", size = 221313, upload-time = "2025-11-18T13:34:12.863Z" }, + { url = "https://files.pythonhosted.org/packages/da/1c/017a3e1113ed34d998b27d2c6dba08a9e7cb97d362f0ec988fcd873dcf81/coverage-7.12.0-cp314-cp314t-win_amd64.whl", hash = "sha256:e84da3a0fd233aeec797b981c51af1cabac74f9bd67be42458365b30d11b5291", size = 222423, upload-time = "2025-11-18T13:34:15.14Z" }, + { url = "https://files.pythonhosted.org/packages/4c/36/bcc504fdd5169301b52568802bb1b9cdde2e27a01d39fbb3b4b508ab7c2c/coverage-7.12.0-cp314-cp314t-win_arm64.whl", hash = "sha256:01d24af36fedda51c2b1aca56e4330a3710f83b02a5ff3743a6b015ffa7c9384", size = 220459, upload-time = "2025-11-18T13:34:17.222Z" }, + { url = "https://files.pythonhosted.org/packages/ce/a3/43b749004e3c09452e39bb56347a008f0a0668aad37324a99b5c8ca91d9e/coverage-7.12.0-py3-none-any.whl", hash = "sha256:159d50c0b12e060b15ed3d39f87ed43d4f7f7ad40b8a534f4dd331adbb51104a", size = 209503, upload-time = "2025-11-18T13:34:18.892Z" }, ] [[package]] @@ -571,19 +587,19 @@ wheels = [ [[package]] name = "faker" -version = "37.12.0" +version = "38.2.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "tzdata" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/3d/84/e95acaa848b855e15c83331d0401ee5f84b2f60889255c2e055cb4fb6bdf/faker-37.12.0.tar.gz", hash = "sha256:7505e59a7e02fa9010f06c3e1e92f8250d4cfbb30632296140c2d6dbef09b0fa", size = 1935741, upload-time = "2025-10-24T15:19:58.764Z" } +sdist = { url = "https://files.pythonhosted.org/packages/64/27/022d4dbd4c20567b4c294f79a133cc2f05240ea61e0d515ead18c995c249/faker-38.2.0.tar.gz", hash = "sha256:20672803db9c7cb97f9b56c18c54b915b6f1d8991f63d1d673642dc43f5ce7ab", size = 1941469, upload-time = "2025-11-19T16:37:31.892Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/8e/98/2c050dec90e295a524c9b65c4cb9e7c302386a296b2938710448cbd267d5/faker-37.12.0-py3-none-any.whl", hash = "sha256:afe7ccc038da92f2fbae30d8e16d19d91e92e242f8401ce9caf44de892bab4c4", size = 1975461, upload-time = "2025-10-24T15:19:55.739Z" }, + { url = "https://files.pythonhosted.org/packages/17/93/00c94d45f55c336434a15f98d906387e87ce28f9918e4444829a8fda432d/faker-38.2.0-py3-none-any.whl", hash = "sha256:35fe4a0a79dee0dc4103a6083ee9224941e7d3594811a50e3969e547b0d2ee65", size = 1980505, upload-time = "2025-11-19T16:37:30.208Z" }, ] [[package]] name = "fastapi" -version = "0.121.0" +version = "0.122.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "annotated-doc" }, @@ -591,9 +607,9 @@ dependencies = [ { name = "starlette" }, { name = "typing-extensions" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/8c/e3/77a2df0946703973b9905fd0cde6172c15e0781984320123b4f5079e7113/fastapi-0.121.0.tar.gz", hash = "sha256:06663356a0b1ee93e875bbf05a31fb22314f5bed455afaaad2b2dad7f26e98fa", size = 342412, upload-time = "2025-11-03T10:25:54.818Z" } +sdist = { url = "https://files.pythonhosted.org/packages/b2/de/3ee97a4f6ffef1fb70bf20561e4f88531633bb5045dc6cebc0f8471f764d/fastapi-0.122.0.tar.gz", hash = "sha256:cd9b5352031f93773228af8b4c443eedc2ac2aa74b27780387b853c3726fb94b", size = 346436, upload-time = "2025-11-24T19:17:47.95Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/dd/2c/42277afc1ba1a18f8358561eee40785d27becab8f80a1f945c0a3051c6eb/fastapi-0.121.0-py3-none-any.whl", hash = "sha256:8bdf1b15a55f4e4b0d6201033da9109ea15632cb76cf156e7b8b4019f2172106", size = 109183, upload-time = "2025-11-03T10:25:53.27Z" }, + { url = "https://files.pythonhosted.org/packages/7a/93/aa8072af4ff37b795f6bbf43dcaf61115f40f49935c7dbb180c9afc3f421/fastapi-0.122.0-py3-none-any.whl", hash = "sha256:a456e8915dfc6c8914a50d9651133bd47ec96d331c5b44600baa635538a30d67", size = 110671, upload-time = "2025-11-24T19:17:45.96Z" }, ] [package.optional-dependencies] @@ -608,16 +624,16 @@ standard = [ [[package]] name = "fastapi-cli" -version = "0.0.14" +version = "0.0.16" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "rich-toolkit" }, { name = "typer" }, { name = "uvicorn", extra = ["standard"] }, ] -sdist = { url = "https://files.pythonhosted.org/packages/cc/13/11e43d630be84e51ba5510a6da6a11eb93b44b72caa796137c5dddda937b/fastapi_cli-0.0.14.tar.gz", hash = "sha256:ddfb5de0a67f77a8b3271af1460489bd4d7f4add73d11fbfac613827b0275274", size = 17994, upload-time = "2025-10-20T16:33:21.054Z" } +sdist = { url = "https://files.pythonhosted.org/packages/99/75/9407a6b452be4c988feacec9c9d2f58d8f315162a6c7258d5a649d933ebe/fastapi_cli-0.0.16.tar.gz", hash = "sha256:e8a2a1ecf7a4e062e3b2eec63ae34387d1e142d4849181d936b23c4bdfe29073", size = 19447, upload-time = "2025-11-10T19:01:07.856Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/40/e8/bc8bbfd93dcc8e347ce98a3e654fb0d2e5f2739afb46b98f41a30c339269/fastapi_cli-0.0.14-py3-none-any.whl", hash = "sha256:e66b9ad499ee77a4e6007545cde6de1459b7f21df199d7f29aad2adaab168eca", size = 11151, upload-time = "2025-10-20T16:33:19.318Z" }, + { url = "https://files.pythonhosted.org/packages/55/43/678528c19318394320ee43757648d5e0a8070cf391b31f69d931e5c840d2/fastapi_cli-0.0.16-py3-none-any.whl", hash = "sha256:addcb6d130b5b9c91adbbf3f2947fe115991495fdb442fe3e51b5fc6327df9f4", size = 12312, upload-time = "2025-11-10T19:01:06.728Z" }, ] [package.optional-dependencies] @@ -628,9 +644,10 @@ standard = [ [[package]] name = "fastapi-cloud-cli" -version = "0.3.1" +version = "0.5.1" source = { registry = "https://pypi.org/simple" } dependencies = [ + { name = "fastar" }, { name = "httpx" }, { name = "pydantic", extra = ["email"] }, { name = "rich-toolkit" }, @@ -639,9 +656,9 @@ dependencies = [ { name = "typer" }, { name = "uvicorn", extra = ["standard"] }, ] -sdist = { url = "https://files.pythonhosted.org/packages/f9/48/0f14d8555b750dc8c04382804e4214f1d7f55298127f3a0237ba566e69dd/fastapi_cloud_cli-0.3.1.tar.gz", hash = "sha256:8c7226c36e92e92d0c89827e8f56dbf164ab2de4444bd33aa26b6c3f7675db69", size = 24080, upload-time = "2025-10-09T11:32:58.174Z" } +sdist = { url = "https://files.pythonhosted.org/packages/cd/8d/cb1ae52121190eb75178b146652bfdce9296d2fd19aa30410ebb1fab3a63/fastapi_cloud_cli-0.5.1.tar.gz", hash = "sha256:5ed9591fda9ef5ed846c7fb937a06c491a00eef6d5bb656c84d82f47e500804b", size = 30746, upload-time = "2025-11-20T16:53:24.491Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/68/79/7f5a5e5513e6a737e5fb089d9c59c74d4d24dc24d581d3aa519b326bedda/fastapi_cloud_cli-0.3.1-py3-none-any.whl", hash = "sha256:7d1a98a77791a9d0757886b2ffbf11bcc6b3be93210dd15064be10b216bf7e00", size = 19711, upload-time = "2025-10-09T11:32:57.118Z" }, + { url = "https://files.pythonhosted.org/packages/42/d6/b83f0801fd2c3f648e3696cdd2a1967b176f43c0c9db35c0350a67e7c141/fastapi_cloud_cli-0.5.1-py3-none-any.whl", hash = "sha256:1a28415b059b27af180a55a835ac2c9e924a66be88412d5649d4f91993d1a698", size = 23216, upload-time = "2025-11-20T16:53:23.119Z" }, ] [[package]] @@ -748,6 +765,59 @@ dependencies = [ { name = "sqlmodel" }, ] +[[package]] +name = "fastar" +version = "0.7.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/d9/7e/0563141e374012f47eb0d219323378f4207d15d9939fa7aa0fa404d8613d/fastar-0.7.0.tar.gz", hash = "sha256:76739b48121cf8601ecc3ea9e87858362774b53cc1dd7e8332696b99c6ad2c27", size = 67917, upload-time = "2025-11-24T15:52:37.072Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/14/82/96043bd83b54f2074a7f47df7ad912b6de26b398a424580167a0d059b46e/fastar-0.7.0-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:d66c09da9ed60536326783becab08db4d4f478e12c0543e7ac750336e72b38e5", size = 705365, upload-time = "2025-11-24T15:51:14.945Z" }, + { url = "https://files.pythonhosted.org/packages/66/01/24f42e7693713c41b389aaa15c0f010ac84eeb9dd5e4e2e0336386b2cef6/fastar-0.7.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:4e443363617551be2e48f87a63f42ba1275c8f42094c6616168bd0512c9ed9b9", size = 627848, upload-time = "2025-11-24T15:51:00.295Z" }, + { url = "https://files.pythonhosted.org/packages/2e/5a/03d2589e2652506e73a8a85312852b5d3263ca348912fc39a396968009ff/fastar-0.7.0-cp313-cp313-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:5a6981f162ebf1148c08668e1ab0fa58f4a6b32a0a126545042a859d836e54ec", size = 867646, upload-time = "2025-11-24T15:50:30.874Z" }, + { url = "https://files.pythonhosted.org/packages/dd/81/ac6f2484f8919b642a45088d487089ac926f74d9b12f347e4ed2e3ebaf8e/fastar-0.7.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7605ce63582432f2bc6b5e59e569b818f5db74506d452be609537a5699cedc19", size = 763982, upload-time = "2025-11-24T15:49:31.069Z" }, + { url = "https://files.pythonhosted.org/packages/eb/77/0ab5991e97e882a90043f287ba08124b8b0a2af4e68e3e8e77cb6e9b09ab/fastar-0.7.0-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:9ae8c4dec44bac4a3e763d5993191962db1285525da61154b6bc158ebcd01ba4", size = 763680, upload-time = "2025-11-24T15:49:46.938Z" }, + { url = "https://files.pythonhosted.org/packages/b3/b4/0c269f4136278e0c652f7d6eca57e71104d02ba1fc3ebf7057a6c36e8339/fastar-0.7.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:abe4ff6fcc353618e395cceb760ae3a90d19686c2d67c9d6654ec0fa9d265395", size = 930118, upload-time = "2025-11-24T15:50:01.681Z" }, + { url = "https://files.pythonhosted.org/packages/70/11/f62a4b652534a5e4f3303b4124e9ca55864f77de9f74588643332f4e5caf/fastar-0.7.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7b54bbb9aa12b2c5550dfafedfe664088bc22a8acc4eebcc9dff7a1ca3048216", size = 820641, upload-time = "2025-11-24T15:50:15.622Z" }, + { url = "https://files.pythonhosted.org/packages/d6/c6/669c167472d31ea94caa5afa75227ef6f123e3be8474f56f9dad01c9b8d8/fastar-0.7.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f434f0a91235aec22a1d39714af3283ef768bb2de548e61ee4f3a74fb3504a2e", size = 820106, upload-time = "2025-11-24T15:50:45.978Z" }, + { url = "https://files.pythonhosted.org/packages/1d/7a/305c99ff3708fc3cb6bebbc2f6469d3c3c4f51119306691d0f57283da0d2/fastar-0.7.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:400e48ca94e5ed9a1f4d17dd8e74cbd9a978de4ba718f5610c73ba6172dcc59b", size = 985425, upload-time = "2025-11-24T15:51:31.58Z" }, + { url = "https://files.pythonhosted.org/packages/c7/c5/04ab4db328d0e3193cf9b1bbc3147f98cf09e1f99c24906789b929198fa8/fastar-0.7.0-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:94b11ba3d9d23fe612a4a612a62d7b2f18e2d7a1be2d5f94b938448a906436e9", size = 1038104, upload-time = "2025-11-24T15:51:49.085Z" }, + { url = "https://files.pythonhosted.org/packages/e6/72/e7c7d684efe1b92062096c29d0d5b38ca549beb5eb35336acf212a90ddc8/fastar-0.7.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:9610f6edb6fdb627491148e7071f725b4abffb8655554cad6a45637772f0795a", size = 1044294, upload-time = "2025-11-24T15:52:06.47Z" }, + { url = "https://files.pythonhosted.org/packages/e6/11/b2ad21f1b8ac20b6c4676e83f2dd3c5f70ff9a9926df60c3f4e36be8be08/fastar-0.7.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:db2373ebe1a699ce3ea34296ab85a22a572667aefd198ca6fa32fee5e69970fc", size = 993265, upload-time = "2025-11-24T15:52:24.049Z" }, + { url = "https://files.pythonhosted.org/packages/03/38/d44a7ea41c407d46c56f160fb870536e1dd9ba01c44b46d7091835ff1719/fastar-0.7.0-cp313-cp313-win32.whl", hash = "sha256:bcb4f04daa574108092abfba8c0f747e65910464671d5ab72e6f55d19f7e2a71", size = 455032, upload-time = "2025-11-24T15:53:03.244Z" }, + { url = "https://files.pythonhosted.org/packages/9d/65/d86c8d53b4f00bb7eed9c89eda2801d33930a8729dac72838807eb2d7314/fastar-0.7.0-cp313-cp313-win_amd64.whl", hash = "sha256:a577121830ba14acd70a8eccc7a0f815a78e9f01981bc9b71a005caa08f63afa", size = 489446, upload-time = "2025-11-24T15:52:50.877Z" }, + { url = "https://files.pythonhosted.org/packages/04/6d/12bc62cd7a425747efbba0755cbfd23015d592c3bf85753442ff1283bfc6/fastar-0.7.0-cp313-cp313-win_arm64.whl", hash = "sha256:b4e0ddd1fb513eac866eca22323dd28b2671aaa3facd10a854d3beef4933372b", size = 460203, upload-time = "2025-11-24T15:52:41.739Z" }, + { url = "https://files.pythonhosted.org/packages/3f/a5/a5eff2a7fe21026cce5fa3a175d88a23a34bca461cddeab87042c2c47e82/fastar-0.7.0-cp314-cp314-macosx_10_12_x86_64.whl", hash = "sha256:7cc47eeac659fed55f547b6c84fbd302726fab64de720c96d3ddcf0952535d0e", size = 705379, upload-time = "2025-11-24T15:51:16.497Z" }, + { url = "https://files.pythonhosted.org/packages/00/06/67228a6e1b32414afe79510ba1256b791541b8801d12660d6fbb203c88b7/fastar-0.7.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:f3139c8d48bdb2c2d79a42eb940efc20e67e1b9dd26798257b71f0d9f0083a5a", size = 627905, upload-time = "2025-11-24T15:51:01.523Z" }, + { url = "https://files.pythonhosted.org/packages/ea/11/753fd5b766d5b170d6d47ebb31aee87b95f5e5776e2661132aae68cae51a/fastar-0.7.0-cp314-cp314-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:f0e2c86b690116f50bd40c444fce6da000695e558a94e460d8b46eff6f23b26f", size = 868266, upload-time = "2025-11-24T15:50:32.119Z" }, + { url = "https://files.pythonhosted.org/packages/40/66/70a191f4d61df4bcda77e759bb840d3cdda796ff26628a454ca44ef58158/fastar-0.7.0-cp314-cp314-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1a698533c59125856e1c14978c589f933de312f066f2a15978f11030807ac535", size = 763815, upload-time = "2025-11-24T15:49:32.214Z" }, + { url = "https://files.pythonhosted.org/packages/d2/a0/72e7886ec7dd16e523522253ecf1862e422e43e3142de29052a562b6499d/fastar-0.7.0-cp314-cp314-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:240c546a20b6f8c1edfe0ab40ac6113cecea02380d6f59e6f9be3d1e079d0767", size = 763288, upload-time = "2025-11-24T15:49:48.082Z" }, + { url = "https://files.pythonhosted.org/packages/9c/b5/0d1cc3356bba8afad036e1808dc10ca76341cafd681a4479c98eb37d947f/fastar-0.7.0-cp314-cp314-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9f37e415192a27980377c0a0859275f178bfcd54c3b972f2f273bee1276a75f1", size = 929296, upload-time = "2025-11-24T15:50:02.957Z" }, + { url = "https://files.pythonhosted.org/packages/59/79/21aa7f864e2e3a1e7244475f864cd82d34b86aac73b1f54c8eb32778c34e/fastar-0.7.0-cp314-cp314-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c865328d56525fc71441f848dcf3d9d20855f3f619c4dca99ecdd932c7e0160c", size = 820264, upload-time = "2025-11-24T15:50:16.91Z" }, + { url = "https://files.pythonhosted.org/packages/de/91/c576af124855de6ffbb48511625ff51653029ba0fde8d3ef6913cf0f968c/fastar-0.7.0-cp314-cp314-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4a9e11313551a10032a6cd97c27434fde6a858794257d709040a7b351b586fe4", size = 819896, upload-time = "2025-11-24T15:50:47.264Z" }, + { url = "https://files.pythonhosted.org/packages/bf/f1/3b3ada104c1924f0a78bc66f89a1bca4957c26e7ad5befaaa2f4701af7bb/fastar-0.7.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:f0532d5ef74d0262f998150a7a2e5d8e51f411d400f655c5a83eb8775fc8d5ab", size = 985552, upload-time = "2025-11-24T15:51:32.859Z" }, + { url = "https://files.pythonhosted.org/packages/c1/1f/1f6424bc8bc2cdc932b16670433b4368b09bf32872b9975c1c1cba02891e/fastar-0.7.0-cp314-cp314-musllinux_1_2_armv7l.whl", hash = "sha256:008930f99c7602da1ec820b165724621df8d6ca327d8877bd46f3600c848aae0", size = 1038126, upload-time = "2025-11-24T15:51:50.93Z" }, + { url = "https://files.pythonhosted.org/packages/09/8e/f4c4db8de826ea9ff134c6bc9bf2aaf1fc977eac9153b3356f6d181a3149/fastar-0.7.0-cp314-cp314-musllinux_1_2_i686.whl", hash = "sha256:6965219b0dbb897557617400ef3a21601a08cfac0ba0e0dfcdbde19a13e0769d", size = 1044273, upload-time = "2025-11-24T15:52:08.061Z" }, + { url = "https://files.pythonhosted.org/packages/71/c6/b1af54e78ea288144bbb1e2e7b2ad56342285029bb2b68f84bf8c8713d70/fastar-0.7.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:bcf277df3c357db68b422944aa3717aff6178c797c4c64711437a81fc2271552", size = 993779, upload-time = "2025-11-24T15:52:25.818Z" }, + { url = "https://files.pythonhosted.org/packages/7f/25/f3043ebd1e19bb262a0ff7a2f2a07945e5e912ace308202e0f89b1d7f96c/fastar-0.7.0-cp314-cp314-win32.whl", hash = "sha256:12cff2cc933e4a74e56c591b1dda06cdae23c0718d07cdb696701e3596a23c5e", size = 455711, upload-time = "2025-11-24T15:53:05.198Z" }, + { url = "https://files.pythonhosted.org/packages/f9/13/b691a58b3cb1567c95b60032009549ccebcefabeceb6c3c4a6a3bddf9253/fastar-0.7.0-cp314-cp314-win_amd64.whl", hash = "sha256:99e7d8928b1d7092053e40d9132a246b4ed8156fa3cecad3def3ea5b2fd24027", size = 489799, upload-time = "2025-11-24T15:52:52.552Z" }, + { url = "https://files.pythonhosted.org/packages/14/0e/7c907f00cb71abc56b1dc3d4aaeaee85061feb955f014ac75af9933f7895/fastar-0.7.0-cp314-cp314-win_arm64.whl", hash = "sha256:cedf4212173f502fc61883a76142ccad9d9cbd2b61f0704d36b7bf6a17df311d", size = 460748, upload-time = "2025-11-24T15:52:43.105Z" }, + { url = "https://files.pythonhosted.org/packages/d5/97/a4cc30a5a962fe23e0b21937fb99ca5a267aa6dee1e3dd72df853a758cb0/fastar-0.7.0-cp314-cp314t-macosx_10_12_x86_64.whl", hash = "sha256:8484b7c55d77874d272c236869855021376722d9c51ff5747ad8b42896b6c4df", size = 704853, upload-time = "2025-11-24T15:51:17.708Z" }, + { url = "https://files.pythonhosted.org/packages/0e/4e/02312660f6027f5ad2bb75e16ea5f2a9f89439e0a502c754b4d8eff0beb1/fastar-0.7.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:514947a8d057e111a9ffd5943ce740d4186f9084562b44cc9875fa39b1a2e109", size = 626773, upload-time = "2025-11-24T15:51:02.835Z" }, + { url = "https://files.pythonhosted.org/packages/61/c7/e04147583ca17fbe6970dc20083b2a38e2ffc2e4e4f76d4e7640c0dbfa49/fastar-0.7.0-cp314-cp314t-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:1b71a5eb92f0c730798896e512a75f96b267bfd610b1148a8348dbcd565dea6c", size = 867940, upload-time = "2025-11-24T15:50:33.402Z" }, + { url = "https://files.pythonhosted.org/packages/0c/c1/8316762971c117b8043202d531320b3ebb740fc02bc5208e8a734e7d5b3c/fastar-0.7.0-cp314-cp314t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3fce1bfa66ceb0e96b6eee89f9efb3250929df22fdfdab8a08735c09b50cfe0c", size = 762971, upload-time = "2025-11-24T15:49:33.406Z" }, + { url = "https://files.pythonhosted.org/packages/62/07/d394742e2892818d52f391d40d24d60ef9a214865fef4a9e55339022d990/fastar-0.7.0-cp314-cp314t-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:9632c25c6a85f5eab589437bc6bfbb5461f93b799882e3c750b6f86448ad9ede", size = 762796, upload-time = "2025-11-24T15:49:49.187Z" }, + { url = "https://files.pythonhosted.org/packages/fd/7d/bb3ab1f10500c765833fc2c931d11e3fa2dae5e42e0451af759a89b5ef57/fastar-0.7.0-cp314-cp314t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c45e2422cca8fd3b5509edf8db44cceeb0d4eed3cc12d90d91d0e1ea08034258", size = 929810, upload-time = "2025-11-24T15:50:04.166Z" }, + { url = "https://files.pythonhosted.org/packages/0e/cb/5e42841f52a65b02796bae27a484c23375eabb07750c88face71d82e3717/fastar-0.7.0-cp314-cp314t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:99836a00322c39689f7d9772662a7b5ee62b3ec1a344ad693f9c162226775039", size = 819858, upload-time = "2025-11-24T15:50:18.395Z" }, + { url = "https://files.pythonhosted.org/packages/0e/7e/e268246b4f38421c84bb42048311fe269feacd8e1d5a6cac48b0f64f8044/fastar-0.7.0-cp314-cp314t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bcd2756c2ae9f1374619207b98d1143c9865910c9fecd094c8656b95c5a9a45b", size = 819585, upload-time = "2025-11-24T15:50:48.488Z" }, + { url = "https://files.pythonhosted.org/packages/50/1f/3d05285c98d3245944540aec77364618e0f508d0c4bbf311a7762b644c35/fastar-0.7.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:3ced9eddb9adcf8b27361c180f6bdfbc8cb2e36479aa00e4e7e78c17c7768efc", size = 984526, upload-time = "2025-11-24T15:51:34.988Z" }, + { url = "https://files.pythonhosted.org/packages/3b/e0/34c114c7016901cac190b18871212f7433871470d1ba1c92ed891ae7d85f/fastar-0.7.0-cp314-cp314t-musllinux_1_2_armv7l.whl", hash = "sha256:39ba9256790a13289f986c07c73bbc075647337008f1faea104e5e013a17ee70", size = 1037651, upload-time = "2025-11-24T15:51:52.286Z" }, + { url = "https://files.pythonhosted.org/packages/39/7e/371ddb9ed65733aa51370bf774234a142d315f841538c7af7fd959cc5c5e/fastar-0.7.0-cp314-cp314t-musllinux_1_2_i686.whl", hash = "sha256:f445e1acb722e228364c2d8012e6be1b46502062e3638cbe5b98c7c2d6bebb72", size = 1044369, upload-time = "2025-11-24T15:52:10.031Z" }, + { url = "https://files.pythonhosted.org/packages/92/0f/0d6a9fab23ba227f79f2e728aef274daf8fe8148c7cbd58022b752af7aeb/fastar-0.7.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:1e9b1e0cb44b0d43dae153d80e519b04aa0bc4c98240d4a2d85c7ede13b37aae", size = 993840, upload-time = "2025-11-24T15:52:27.41Z" }, + { url = "https://files.pythonhosted.org/packages/a1/e2/df1c197e4bfca4c23114ab1251c70b70a9a7a427a1ab73bef2dd9750056a/fastar-0.7.0-cp314-cp314t-win32.whl", hash = "sha256:44956db52c2d6afa5a26a9d2c8e926eb55902a9151ab0ce0bfa3023479db4800", size = 454334, upload-time = "2025-11-24T15:53:09.556Z" }, + { url = "https://files.pythonhosted.org/packages/ee/b0/e2b55bb0b521ac9abada459cd2bce8488b36525f913af536bf1dec90dc03/fastar-0.7.0-cp314-cp314t-win_amd64.whl", hash = "sha256:cfd514372850774e8651c4e98b2b81bba0ae00f2e1dfa666da89ea5e02d1e61a", size = 489047, upload-time = "2025-11-24T15:52:57.327Z" }, + { url = "https://files.pythonhosted.org/packages/f3/c1/ea150ccd09a6247a65e162596db393fb642ad92bf7d2af9f7e4ae58233da/fastar-0.7.0-cp314-cp314t-win_arm64.whl", hash = "sha256:96a366565662567ba1b7c1d2f72e02584575a33b220c361707e168270b68d4e4", size = 459525, upload-time = "2025-11-24T15:52:44.492Z" }, +] + [[package]] name = "filelock" version = "3.20.0" @@ -1128,54 +1198,54 @@ wheels = [ [[package]] name = "numpy" -version = "2.3.4" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/b5/f4/098d2270d52b41f1bd7db9fc288aaa0400cb48c2a3e2af6fa365d9720947/numpy-2.3.4.tar.gz", hash = "sha256:a7d018bfedb375a8d979ac758b120ba846a7fe764911a64465fd87b8729f4a6a", size = 20582187, upload-time = "2025-10-15T16:18:11.77Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/57/7e/b72610cc91edf138bc588df5150957a4937221ca6058b825b4725c27be62/numpy-2.3.4-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:c090d4860032b857d94144d1a9976b8e36709e40386db289aaf6672de2a81966", size = 20950335, upload-time = "2025-10-15T16:16:10.304Z" }, - { url = "https://files.pythonhosted.org/packages/3e/46/bdd3370dcea2f95ef14af79dbf81e6927102ddf1cc54adc0024d61252fd9/numpy-2.3.4-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:a13fc473b6db0be619e45f11f9e81260f7302f8d180c49a22b6e6120022596b3", size = 14179878, upload-time = "2025-10-15T16:16:12.595Z" }, - { url = "https://files.pythonhosted.org/packages/ac/01/5a67cb785bda60f45415d09c2bc245433f1c68dd82eef9c9002c508b5a65/numpy-2.3.4-cp313-cp313-macosx_14_0_arm64.whl", hash = "sha256:3634093d0b428e6c32c3a69b78e554f0cd20ee420dcad5a9f3b2a63762ce4197", size = 5108673, upload-time = "2025-10-15T16:16:14.877Z" }, - { url = "https://files.pythonhosted.org/packages/c2/cd/8428e23a9fcebd33988f4cb61208fda832800ca03781f471f3727a820704/numpy-2.3.4-cp313-cp313-macosx_14_0_x86_64.whl", hash = "sha256:043885b4f7e6e232d7df4f51ffdef8c36320ee9d5f227b380ea636722c7ed12e", size = 6641438, upload-time = "2025-10-15T16:16:16.805Z" }, - { url = "https://files.pythonhosted.org/packages/3e/d1/913fe563820f3c6b079f992458f7331278dcd7ba8427e8e745af37ddb44f/numpy-2.3.4-cp313-cp313-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:4ee6a571d1e4f0ea6d5f22d6e5fbd6ed1dc2b18542848e1e7301bd190500c9d7", size = 14281290, upload-time = "2025-10-15T16:16:18.764Z" }, - { url = "https://files.pythonhosted.org/packages/9e/7e/7d306ff7cb143e6d975cfa7eb98a93e73495c4deabb7d1b5ecf09ea0fd69/numpy-2.3.4-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:fc8a63918b04b8571789688b2780ab2b4a33ab44bfe8ccea36d3eba51228c953", size = 16636543, upload-time = "2025-10-15T16:16:21.072Z" }, - { url = "https://files.pythonhosted.org/packages/47/6a/8cfc486237e56ccfb0db234945552a557ca266f022d281a2f577b98e955c/numpy-2.3.4-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:40cc556d5abbc54aabe2b1ae287042d7bdb80c08edede19f0c0afb36ae586f37", size = 16056117, upload-time = "2025-10-15T16:16:23.369Z" }, - { url = "https://files.pythonhosted.org/packages/b1/0e/42cb5e69ea901e06ce24bfcc4b5664a56f950a70efdcf221f30d9615f3f3/numpy-2.3.4-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:ecb63014bb7f4ce653f8be7f1df8cbc6093a5a2811211770f6606cc92b5a78fd", size = 18577788, upload-time = "2025-10-15T16:16:27.496Z" }, - { url = "https://files.pythonhosted.org/packages/86/92/41c3d5157d3177559ef0a35da50f0cda7fa071f4ba2306dd36818591a5bc/numpy-2.3.4-cp313-cp313-win32.whl", hash = "sha256:e8370eb6925bb8c1c4264fec52b0384b44f675f191df91cbe0140ec9f0955646", size = 6282620, upload-time = "2025-10-15T16:16:29.811Z" }, - { url = "https://files.pythonhosted.org/packages/09/97/fd421e8bc50766665ad35536c2bb4ef916533ba1fdd053a62d96cc7c8b95/numpy-2.3.4-cp313-cp313-win_amd64.whl", hash = "sha256:56209416e81a7893036eea03abcb91c130643eb14233b2515c90dcac963fe99d", size = 12784672, upload-time = "2025-10-15T16:16:31.589Z" }, - { url = "https://files.pythonhosted.org/packages/ad/df/5474fb2f74970ca8eb978093969b125a84cc3d30e47f82191f981f13a8a0/numpy-2.3.4-cp313-cp313-win_arm64.whl", hash = "sha256:a700a4031bc0fd6936e78a752eefb79092cecad2599ea9c8039c548bc097f9bc", size = 10196702, upload-time = "2025-10-15T16:16:33.902Z" }, - { url = "https://files.pythonhosted.org/packages/11/83/66ac031464ec1767ea3ed48ce40f615eb441072945e98693bec0bcd056cc/numpy-2.3.4-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:86966db35c4040fdca64f0816a1c1dd8dbd027d90fca5a57e00e1ca4cd41b879", size = 21049003, upload-time = "2025-10-15T16:16:36.101Z" }, - { url = "https://files.pythonhosted.org/packages/5f/99/5b14e0e686e61371659a1d5bebd04596b1d72227ce36eed121bb0aeab798/numpy-2.3.4-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:838f045478638b26c375ee96ea89464d38428c69170360b23a1a50fa4baa3562", size = 14302980, upload-time = "2025-10-15T16:16:39.124Z" }, - { url = "https://files.pythonhosted.org/packages/2c/44/e9486649cd087d9fc6920e3fc3ac2aba10838d10804b1e179fb7cbc4e634/numpy-2.3.4-cp313-cp313t-macosx_14_0_arm64.whl", hash = "sha256:d7315ed1dab0286adca467377c8381cd748f3dc92235f22a7dfc42745644a96a", size = 5231472, upload-time = "2025-10-15T16:16:41.168Z" }, - { url = "https://files.pythonhosted.org/packages/3e/51/902b24fa8887e5fe2063fd61b1895a476d0bbf46811ab0c7fdf4bd127345/numpy-2.3.4-cp313-cp313t-macosx_14_0_x86_64.whl", hash = "sha256:84f01a4d18b2cc4ade1814a08e5f3c907b079c847051d720fad15ce37aa930b6", size = 6739342, upload-time = "2025-10-15T16:16:43.777Z" }, - { url = "https://files.pythonhosted.org/packages/34/f1/4de9586d05b1962acdcdb1dc4af6646361a643f8c864cef7c852bf509740/numpy-2.3.4-cp313-cp313t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:817e719a868f0dacde4abdfc5c1910b301877970195db9ab6a5e2c4bd5b121f7", size = 14354338, upload-time = "2025-10-15T16:16:46.081Z" }, - { url = "https://files.pythonhosted.org/packages/1f/06/1c16103b425de7969d5a76bdf5ada0804b476fed05d5f9e17b777f1cbefd/numpy-2.3.4-cp313-cp313t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:85e071da78d92a214212cacea81c6da557cab307f2c34b5f85b628e94803f9c0", size = 16702392, upload-time = "2025-10-15T16:16:48.455Z" }, - { url = "https://files.pythonhosted.org/packages/34/b2/65f4dc1b89b5322093572b6e55161bb42e3e0487067af73627f795cc9d47/numpy-2.3.4-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:2ec646892819370cf3558f518797f16597b4e4669894a2ba712caccc9da53f1f", size = 16134998, upload-time = "2025-10-15T16:16:51.114Z" }, - { url = "https://files.pythonhosted.org/packages/d4/11/94ec578896cdb973aaf56425d6c7f2aff4186a5c00fac15ff2ec46998b46/numpy-2.3.4-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:035796aaaddfe2f9664b9a9372f089cfc88bd795a67bd1bfe15e6e770934cf64", size = 18651574, upload-time = "2025-10-15T16:16:53.429Z" }, - { url = "https://files.pythonhosted.org/packages/62/b7/7efa763ab33dbccf56dade36938a77345ce8e8192d6b39e470ca25ff3cd0/numpy-2.3.4-cp313-cp313t-win32.whl", hash = "sha256:fea80f4f4cf83b54c3a051f2f727870ee51e22f0248d3114b8e755d160b38cfb", size = 6413135, upload-time = "2025-10-15T16:16:55.992Z" }, - { url = "https://files.pythonhosted.org/packages/43/70/aba4c38e8400abcc2f345e13d972fb36c26409b3e644366db7649015f291/numpy-2.3.4-cp313-cp313t-win_amd64.whl", hash = "sha256:15eea9f306b98e0be91eb344a94c0e630689ef302e10c2ce5f7e11905c704f9c", size = 12928582, upload-time = "2025-10-15T16:16:57.943Z" }, - { url = "https://files.pythonhosted.org/packages/67/63/871fad5f0073fc00fbbdd7232962ea1ac40eeaae2bba66c76214f7954236/numpy-2.3.4-cp313-cp313t-win_arm64.whl", hash = "sha256:b6c231c9c2fadbae4011ca5e7e83e12dc4a5072f1a1d85a0a7b3ed754d145a40", size = 10266691, upload-time = "2025-10-15T16:17:00.048Z" }, - { url = "https://files.pythonhosted.org/packages/72/71/ae6170143c115732470ae3a2d01512870dd16e0953f8a6dc89525696069b/numpy-2.3.4-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:81c3e6d8c97295a7360d367f9f8553973651b76907988bb6066376bc2252f24e", size = 20955580, upload-time = "2025-10-15T16:17:02.509Z" }, - { url = "https://files.pythonhosted.org/packages/af/39/4be9222ffd6ca8a30eda033d5f753276a9c3426c397bb137d8e19dedd200/numpy-2.3.4-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:7c26b0b2bf58009ed1f38a641f3db4be8d960a417ca96d14e5b06df1506d41ff", size = 14188056, upload-time = "2025-10-15T16:17:04.873Z" }, - { url = "https://files.pythonhosted.org/packages/6c/3d/d85f6700d0a4aa4f9491030e1021c2b2b7421b2b38d01acd16734a2bfdc7/numpy-2.3.4-cp314-cp314-macosx_14_0_arm64.whl", hash = "sha256:62b2198c438058a20b6704351b35a1d7db881812d8512d67a69c9de1f18ca05f", size = 5116555, upload-time = "2025-10-15T16:17:07.499Z" }, - { url = "https://files.pythonhosted.org/packages/bf/04/82c1467d86f47eee8a19a464c92f90a9bb68ccf14a54c5224d7031241ffb/numpy-2.3.4-cp314-cp314-macosx_14_0_x86_64.whl", hash = "sha256:9d729d60f8d53a7361707f4b68a9663c968882dd4f09e0d58c044c8bf5faee7b", size = 6643581, upload-time = "2025-10-15T16:17:09.774Z" }, - { url = "https://files.pythonhosted.org/packages/0c/d3/c79841741b837e293f48bd7db89d0ac7a4f2503b382b78a790ef1dc778a5/numpy-2.3.4-cp314-cp314-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:bd0c630cf256b0a7fd9d0a11c9413b42fef5101219ce6ed5a09624f5a65392c7", size = 14299186, upload-time = "2025-10-15T16:17:11.937Z" }, - { url = "https://files.pythonhosted.org/packages/e8/7e/4a14a769741fbf237eec5a12a2cbc7a4c4e061852b6533bcb9e9a796c908/numpy-2.3.4-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:d5e081bc082825f8b139f9e9fe42942cb4054524598aaeb177ff476cc76d09d2", size = 16638601, upload-time = "2025-10-15T16:17:14.391Z" }, - { url = "https://files.pythonhosted.org/packages/93/87/1c1de269f002ff0a41173fe01dcc925f4ecff59264cd8f96cf3b60d12c9b/numpy-2.3.4-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:15fb27364ed84114438fff8aaf998c9e19adbeba08c0b75409f8c452a8692c52", size = 16074219, upload-time = "2025-10-15T16:17:17.058Z" }, - { url = "https://files.pythonhosted.org/packages/cd/28/18f72ee77408e40a76d691001ae599e712ca2a47ddd2c4f695b16c65f077/numpy-2.3.4-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:85d9fb2d8cd998c84d13a79a09cc0c1091648e848e4e6249b0ccd7f6b487fa26", size = 18576702, upload-time = "2025-10-15T16:17:19.379Z" }, - { url = "https://files.pythonhosted.org/packages/c3/76/95650169b465ececa8cf4b2e8f6df255d4bf662775e797ade2025cc51ae6/numpy-2.3.4-cp314-cp314-win32.whl", hash = "sha256:e73d63fd04e3a9d6bc187f5455d81abfad05660b212c8804bf3b407e984cd2bc", size = 6337136, upload-time = "2025-10-15T16:17:22.886Z" }, - { url = "https://files.pythonhosted.org/packages/dc/89/a231a5c43ede5d6f77ba4a91e915a87dea4aeea76560ba4d2bf185c683f0/numpy-2.3.4-cp314-cp314-win_amd64.whl", hash = "sha256:3da3491cee49cf16157e70f607c03a217ea6647b1cea4819c4f48e53d49139b9", size = 12920542, upload-time = "2025-10-15T16:17:24.783Z" }, - { url = "https://files.pythonhosted.org/packages/0d/0c/ae9434a888f717c5ed2ff2393b3f344f0ff6f1c793519fa0c540461dc530/numpy-2.3.4-cp314-cp314-win_arm64.whl", hash = "sha256:6d9cd732068e8288dbe2717177320723ccec4fb064123f0caf9bbd90ab5be868", size = 10480213, upload-time = "2025-10-15T16:17:26.935Z" }, - { url = "https://files.pythonhosted.org/packages/83/4b/c4a5f0841f92536f6b9592694a5b5f68c9ab37b775ff342649eadf9055d3/numpy-2.3.4-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:22758999b256b595cf0b1d102b133bb61866ba5ceecf15f759623b64c020c9ec", size = 21052280, upload-time = "2025-10-15T16:17:29.638Z" }, - { url = "https://files.pythonhosted.org/packages/3e/80/90308845fc93b984d2cc96d83e2324ce8ad1fd6efea81b324cba4b673854/numpy-2.3.4-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:9cb177bc55b010b19798dc5497d540dea67fd13a8d9e882b2dae71de0cf09eb3", size = 14302930, upload-time = "2025-10-15T16:17:32.384Z" }, - { url = "https://files.pythonhosted.org/packages/3d/4e/07439f22f2a3b247cec4d63a713faae55e1141a36e77fb212881f7cda3fb/numpy-2.3.4-cp314-cp314t-macosx_14_0_arm64.whl", hash = "sha256:0f2bcc76f1e05e5ab58893407c63d90b2029908fa41f9f1cc51eecce936c3365", size = 5231504, upload-time = "2025-10-15T16:17:34.515Z" }, - { url = "https://files.pythonhosted.org/packages/ab/de/1e11f2547e2fe3d00482b19721855348b94ada8359aef5d40dd57bfae9df/numpy-2.3.4-cp314-cp314t-macosx_14_0_x86_64.whl", hash = "sha256:8dc20bde86802df2ed8397a08d793da0ad7a5fd4ea3ac85d757bf5dd4ad7c252", size = 6739405, upload-time = "2025-10-15T16:17:36.128Z" }, - { url = "https://files.pythonhosted.org/packages/3b/40/8cd57393a26cebe2e923005db5134a946c62fa56a1087dc7c478f3e30837/numpy-2.3.4-cp314-cp314t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:5e199c087e2aa71c8f9ce1cb7a8e10677dc12457e7cc1be4798632da37c3e86e", size = 14354866, upload-time = "2025-10-15T16:17:38.884Z" }, - { url = "https://files.pythonhosted.org/packages/93/39/5b3510f023f96874ee6fea2e40dfa99313a00bf3ab779f3c92978f34aace/numpy-2.3.4-cp314-cp314t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:85597b2d25ddf655495e2363fe044b0ae999b75bc4d630dc0d886484b03a5eb0", size = 16703296, upload-time = "2025-10-15T16:17:41.564Z" }, - { url = "https://files.pythonhosted.org/packages/41/0d/19bb163617c8045209c1996c4e427bccbc4bbff1e2c711f39203c8ddbb4a/numpy-2.3.4-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:04a69abe45b49c5955923cf2c407843d1c85013b424ae8a560bba16c92fe44a0", size = 16136046, upload-time = "2025-10-15T16:17:43.901Z" }, - { url = "https://files.pythonhosted.org/packages/e2/c1/6dba12fdf68b02a21ac411c9df19afa66bed2540f467150ca64d246b463d/numpy-2.3.4-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:e1708fac43ef8b419c975926ce1eaf793b0c13b7356cfab6ab0dc34c0a02ac0f", size = 18652691, upload-time = "2025-10-15T16:17:46.247Z" }, - { url = "https://files.pythonhosted.org/packages/f8/73/f85056701dbbbb910c51d846c58d29fd46b30eecd2b6ba760fc8b8a1641b/numpy-2.3.4-cp314-cp314t-win32.whl", hash = "sha256:863e3b5f4d9915aaf1b8ec79ae560ad21f0b8d5e3adc31e73126491bb86dee1d", size = 6485782, upload-time = "2025-10-15T16:17:48.872Z" }, - { url = "https://files.pythonhosted.org/packages/17/90/28fa6f9865181cb817c2471ee65678afa8a7e2a1fb16141473d5fa6bacc3/numpy-2.3.4-cp314-cp314t-win_amd64.whl", hash = "sha256:962064de37b9aef801d33bc579690f8bfe6c5e70e29b61783f60bcba838a14d6", size = 13113301, upload-time = "2025-10-15T16:17:50.938Z" }, - { url = "https://files.pythonhosted.org/packages/54/23/08c002201a8e7e1f9afba93b97deceb813252d9cfd0d3351caed123dcf97/numpy-2.3.4-cp314-cp314t-win_arm64.whl", hash = "sha256:8b5a9a39c45d852b62693d9b3f3e0fe052541f804296ff401a72a1b60edafb29", size = 10547532, upload-time = "2025-10-15T16:17:53.48Z" }, +version = "2.3.5" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/76/65/21b3bc86aac7b8f2862db1e808f1ea22b028e30a225a34a5ede9bf8678f2/numpy-2.3.5.tar.gz", hash = "sha256:784db1dcdab56bf0517743e746dfb0f885fc68d948aba86eeec2cba234bdf1c0", size = 20584950, upload-time = "2025-11-16T22:52:42.067Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/db/69/9cde09f36da4b5a505341180a3f2e6fadc352fd4d2b7096ce9778db83f1a/numpy-2.3.5-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:d0f23b44f57077c1ede8c5f26b30f706498b4862d3ff0a7298b8411dd2f043ff", size = 16728251, upload-time = "2025-11-16T22:50:19.013Z" }, + { url = "https://files.pythonhosted.org/packages/79/fb/f505c95ceddd7027347b067689db71ca80bd5ecc926f913f1a23e65cf09b/numpy-2.3.5-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:aa5bc7c5d59d831d9773d1170acac7893ce3a5e130540605770ade83280e7188", size = 12254652, upload-time = "2025-11-16T22:50:21.487Z" }, + { url = "https://files.pythonhosted.org/packages/78/da/8c7738060ca9c31b30e9301ee0cf6c5ffdbf889d9593285a1cead337f9a5/numpy-2.3.5-cp313-cp313-macosx_14_0_arm64.whl", hash = "sha256:ccc933afd4d20aad3c00bcef049cb40049f7f196e0397f1109dba6fed63267b0", size = 5083172, upload-time = "2025-11-16T22:50:24.562Z" }, + { url = "https://files.pythonhosted.org/packages/a4/b4/ee5bb2537fb9430fd2ef30a616c3672b991a4129bb1c7dcc42aa0abbe5d7/numpy-2.3.5-cp313-cp313-macosx_14_0_x86_64.whl", hash = "sha256:afaffc4393205524af9dfa400fa250143a6c3bc646c08c9f5e25a9f4b4d6a903", size = 6622990, upload-time = "2025-11-16T22:50:26.47Z" }, + { url = "https://files.pythonhosted.org/packages/95/03/dc0723a013c7d7c19de5ef29e932c3081df1c14ba582b8b86b5de9db7f0f/numpy-2.3.5-cp313-cp313-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:9c75442b2209b8470d6d5d8b1c25714270686f14c749028d2199c54e29f20b4d", size = 14248902, upload-time = "2025-11-16T22:50:28.861Z" }, + { url = "https://files.pythonhosted.org/packages/f5/10/ca162f45a102738958dcec8023062dad0cbc17d1ab99d68c4e4a6c45fb2b/numpy-2.3.5-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:11e06aa0af8c0f05104d56450d6093ee639e15f24ecf62d417329d06e522e017", size = 16597430, upload-time = "2025-11-16T22:50:31.56Z" }, + { url = "https://files.pythonhosted.org/packages/2a/51/c1e29be863588db58175175f057286900b4b3327a1351e706d5e0f8dd679/numpy-2.3.5-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:ed89927b86296067b4f81f108a2271d8926467a8868e554eaf370fc27fa3ccaf", size = 16024551, upload-time = "2025-11-16T22:50:34.242Z" }, + { url = "https://files.pythonhosted.org/packages/83/68/8236589d4dbb87253d28259d04d9b814ec0ecce7cb1c7fed29729f4c3a78/numpy-2.3.5-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:51c55fe3451421f3a6ef9a9c1439e82101c57a2c9eab9feb196a62b1a10b58ce", size = 18533275, upload-time = "2025-11-16T22:50:37.651Z" }, + { url = "https://files.pythonhosted.org/packages/40/56/2932d75b6f13465239e3b7b7e511be27f1b8161ca2510854f0b6e521c395/numpy-2.3.5-cp313-cp313-win32.whl", hash = "sha256:1978155dd49972084bd6ef388d66ab70f0c323ddee6f693d539376498720fb7e", size = 6277637, upload-time = "2025-11-16T22:50:40.11Z" }, + { url = "https://files.pythonhosted.org/packages/0c/88/e2eaa6cffb115b85ed7c7c87775cb8bcf0816816bc98ca8dbfa2ee33fe6e/numpy-2.3.5-cp313-cp313-win_amd64.whl", hash = "sha256:00dc4e846108a382c5869e77c6ed514394bdeb3403461d25a829711041217d5b", size = 12779090, upload-time = "2025-11-16T22:50:42.503Z" }, + { url = "https://files.pythonhosted.org/packages/8f/88/3f41e13a44ebd4034ee17baa384acac29ba6a4fcc2aca95f6f08ca0447d1/numpy-2.3.5-cp313-cp313-win_arm64.whl", hash = "sha256:0472f11f6ec23a74a906a00b48a4dcf3849209696dff7c189714511268d103ae", size = 10194710, upload-time = "2025-11-16T22:50:44.971Z" }, + { url = "https://files.pythonhosted.org/packages/13/cb/71744144e13389d577f867f745b7df2d8489463654a918eea2eeb166dfc9/numpy-2.3.5-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:414802f3b97f3c1eef41e530aaba3b3c1620649871d8cb38c6eaff034c2e16bd", size = 16827292, upload-time = "2025-11-16T22:50:47.715Z" }, + { url = "https://files.pythonhosted.org/packages/71/80/ba9dc6f2a4398e7f42b708a7fdc841bb638d353be255655498edbf9a15a8/numpy-2.3.5-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:5ee6609ac3604fa7780e30a03e5e241a7956f8e2fcfe547d51e3afa5247ac47f", size = 12378897, upload-time = "2025-11-16T22:50:51.327Z" }, + { url = "https://files.pythonhosted.org/packages/2e/6d/db2151b9f64264bcceccd51741aa39b50150de9b602d98ecfe7e0c4bff39/numpy-2.3.5-cp313-cp313t-macosx_14_0_arm64.whl", hash = "sha256:86d835afea1eaa143012a2d7a3f45a3adce2d7adc8b4961f0b362214d800846a", size = 5207391, upload-time = "2025-11-16T22:50:54.542Z" }, + { url = "https://files.pythonhosted.org/packages/80/ae/429bacace5ccad48a14c4ae5332f6aa8ab9f69524193511d60ccdfdc65fa/numpy-2.3.5-cp313-cp313t-macosx_14_0_x86_64.whl", hash = "sha256:30bc11310e8153ca664b14c5f1b73e94bd0503681fcf136a163de856f3a50139", size = 6721275, upload-time = "2025-11-16T22:50:56.794Z" }, + { url = "https://files.pythonhosted.org/packages/74/5b/1919abf32d8722646a38cd527bc3771eb229a32724ee6ba340ead9b92249/numpy-2.3.5-cp313-cp313t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:1062fde1dcf469571705945b0f221b73928f34a20c904ffb45db101907c3454e", size = 14306855, upload-time = "2025-11-16T22:50:59.208Z" }, + { url = "https://files.pythonhosted.org/packages/a5/87/6831980559434973bebc30cd9c1f21e541a0f2b0c280d43d3afd909b66d0/numpy-2.3.5-cp313-cp313t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:ce581db493ea1a96c0556360ede6607496e8bf9b3a8efa66e06477267bc831e9", size = 16657359, upload-time = "2025-11-16T22:51:01.991Z" }, + { url = "https://files.pythonhosted.org/packages/dd/91/c797f544491ee99fd00495f12ebb7802c440c1915811d72ac5b4479a3356/numpy-2.3.5-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:cc8920d2ec5fa99875b670bb86ddeb21e295cb07aa331810d9e486e0b969d946", size = 16093374, upload-time = "2025-11-16T22:51:05.291Z" }, + { url = "https://files.pythonhosted.org/packages/74/a6/54da03253afcbe7a72785ec4da9c69fb7a17710141ff9ac5fcb2e32dbe64/numpy-2.3.5-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:9ee2197ef8c4f0dfe405d835f3b6a14f5fee7782b5de51ba06fb65fc9b36e9f1", size = 18594587, upload-time = "2025-11-16T22:51:08.585Z" }, + { url = "https://files.pythonhosted.org/packages/80/e9/aff53abbdd41b0ecca94285f325aff42357c6b5abc482a3fcb4994290b18/numpy-2.3.5-cp313-cp313t-win32.whl", hash = "sha256:70b37199913c1bd300ff6e2693316c6f869c7ee16378faf10e4f5e3275b299c3", size = 6405940, upload-time = "2025-11-16T22:51:11.541Z" }, + { url = "https://files.pythonhosted.org/packages/d5/81/50613fec9d4de5480de18d4f8ef59ad7e344d497edbef3cfd80f24f98461/numpy-2.3.5-cp313-cp313t-win_amd64.whl", hash = "sha256:b501b5fa195cc9e24fe102f21ec0a44dffc231d2af79950b451e0d99cea02234", size = 12920341, upload-time = "2025-11-16T22:51:14.312Z" }, + { url = "https://files.pythonhosted.org/packages/bb/ab/08fd63b9a74303947f34f0bd7c5903b9c5532c2d287bead5bdf4c556c486/numpy-2.3.5-cp313-cp313t-win_arm64.whl", hash = "sha256:a80afd79f45f3c4a7d341f13acbe058d1ca8ac017c165d3fa0d3de6bc1a079d7", size = 10262507, upload-time = "2025-11-16T22:51:16.846Z" }, + { url = "https://files.pythonhosted.org/packages/ba/97/1a914559c19e32d6b2e233cf9a6a114e67c856d35b1d6babca571a3e880f/numpy-2.3.5-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:bf06bc2af43fa8d32d30fae16ad965663e966b1a3202ed407b84c989c3221e82", size = 16735706, upload-time = "2025-11-16T22:51:19.558Z" }, + { url = "https://files.pythonhosted.org/packages/57/d4/51233b1c1b13ecd796311216ae417796b88b0616cfd8a33ae4536330748a/numpy-2.3.5-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:052e8c42e0c49d2575621c158934920524f6c5da05a1d3b9bab5d8e259e045f0", size = 12264507, upload-time = "2025-11-16T22:51:22.492Z" }, + { url = "https://files.pythonhosted.org/packages/45/98/2fe46c5c2675b8306d0b4a3ec3494273e93e1226a490f766e84298576956/numpy-2.3.5-cp314-cp314-macosx_14_0_arm64.whl", hash = "sha256:1ed1ec893cff7040a02c8aa1c8611b94d395590d553f6b53629a4461dc7f7b63", size = 5093049, upload-time = "2025-11-16T22:51:25.171Z" }, + { url = "https://files.pythonhosted.org/packages/ce/0e/0698378989bb0ac5f1660c81c78ab1fe5476c1a521ca9ee9d0710ce54099/numpy-2.3.5-cp314-cp314-macosx_14_0_x86_64.whl", hash = "sha256:2dcd0808a421a482a080f89859a18beb0b3d1e905b81e617a188bd80422d62e9", size = 6626603, upload-time = "2025-11-16T22:51:27Z" }, + { url = "https://files.pythonhosted.org/packages/5e/a6/9ca0eecc489640615642a6cbc0ca9e10df70df38c4d43f5a928ff18d8827/numpy-2.3.5-cp314-cp314-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:727fd05b57df37dc0bcf1a27767a3d9a78cbbc92822445f32cc3436ba797337b", size = 14262696, upload-time = "2025-11-16T22:51:29.402Z" }, + { url = "https://files.pythonhosted.org/packages/c8/f6/07ec185b90ec9d7217a00eeeed7383b73d7e709dae2a9a021b051542a708/numpy-2.3.5-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:fffe29a1ef00883599d1dc2c51aa2e5d80afe49523c261a74933df395c15c520", size = 16597350, upload-time = "2025-11-16T22:51:32.167Z" }, + { url = "https://files.pythonhosted.org/packages/75/37/164071d1dde6a1a84c9b8e5b414fa127981bad47adf3a6b7e23917e52190/numpy-2.3.5-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:8f7f0e05112916223d3f438f293abf0727e1181b5983f413dfa2fefc4098245c", size = 16040190, upload-time = "2025-11-16T22:51:35.403Z" }, + { url = "https://files.pythonhosted.org/packages/08/3c/f18b82a406b04859eb026d204e4e1773eb41c5be58410f41ffa511d114ae/numpy-2.3.5-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:2e2eb32ddb9ccb817d620ac1d8dae7c3f641c1e5f55f531a33e8ab97960a75b8", size = 18536749, upload-time = "2025-11-16T22:51:39.698Z" }, + { url = "https://files.pythonhosted.org/packages/40/79/f82f572bf44cf0023a2fe8588768e23e1592585020d638999f15158609e1/numpy-2.3.5-cp314-cp314-win32.whl", hash = "sha256:66f85ce62c70b843bab1fb14a05d5737741e74e28c7b8b5a064de10142fad248", size = 6335432, upload-time = "2025-11-16T22:51:42.476Z" }, + { url = "https://files.pythonhosted.org/packages/a3/2e/235b4d96619931192c91660805e5e49242389742a7a82c27665021db690c/numpy-2.3.5-cp314-cp314-win_amd64.whl", hash = "sha256:e6a0bc88393d65807d751a614207b7129a310ca4fe76a74e5c7da5fa5671417e", size = 12919388, upload-time = "2025-11-16T22:51:45.275Z" }, + { url = "https://files.pythonhosted.org/packages/07/2b/29fd75ce45d22a39c61aad74f3d718e7ab67ccf839ca8b60866054eb15f8/numpy-2.3.5-cp314-cp314-win_arm64.whl", hash = "sha256:aeffcab3d4b43712bb7a60b65f6044d444e75e563ff6180af8f98dd4b905dfd2", size = 10476651, upload-time = "2025-11-16T22:51:47.749Z" }, + { url = "https://files.pythonhosted.org/packages/17/e1/f6a721234ebd4d87084cfa68d081bcba2f5cfe1974f7de4e0e8b9b2a2ba1/numpy-2.3.5-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:17531366a2e3a9e30762c000f2c43a9aaa05728712e25c11ce1dbe700c53ad41", size = 16834503, upload-time = "2025-11-16T22:51:50.443Z" }, + { url = "https://files.pythonhosted.org/packages/5c/1c/baf7ffdc3af9c356e1c135e57ab7cf8d247931b9554f55c467efe2c69eff/numpy-2.3.5-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:d21644de1b609825ede2f48be98dfde4656aefc713654eeee280e37cadc4e0ad", size = 12381612, upload-time = "2025-11-16T22:51:53.609Z" }, + { url = "https://files.pythonhosted.org/packages/74/91/f7f0295151407ddc9ba34e699013c32c3c91944f9b35fcf9281163dc1468/numpy-2.3.5-cp314-cp314t-macosx_14_0_arm64.whl", hash = "sha256:c804e3a5aba5460c73955c955bdbd5c08c354954e9270a2c1565f62e866bdc39", size = 5210042, upload-time = "2025-11-16T22:51:56.213Z" }, + { url = "https://files.pythonhosted.org/packages/2e/3b/78aebf345104ec50dd50a4d06ddeb46a9ff5261c33bcc58b1c4f12f85ec2/numpy-2.3.5-cp314-cp314t-macosx_14_0_x86_64.whl", hash = "sha256:cc0a57f895b96ec78969c34f682c602bf8da1a0270b09bc65673df2e7638ec20", size = 6724502, upload-time = "2025-11-16T22:51:58.584Z" }, + { url = "https://files.pythonhosted.org/packages/02/c6/7c34b528740512e57ef1b7c8337ab0b4f0bddf34c723b8996c675bc2bc91/numpy-2.3.5-cp314-cp314t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:900218e456384ea676e24ea6a0417f030a3b07306d29d7ad843957b40a9d8d52", size = 14308962, upload-time = "2025-11-16T22:52:01.698Z" }, + { url = "https://files.pythonhosted.org/packages/80/35/09d433c5262bc32d725bafc619e095b6a6651caf94027a03da624146f655/numpy-2.3.5-cp314-cp314t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:09a1bea522b25109bf8e6f3027bd810f7c1085c64a0c7ce050c1676ad0ba010b", size = 16655054, upload-time = "2025-11-16T22:52:04.267Z" }, + { url = "https://files.pythonhosted.org/packages/7a/ab/6a7b259703c09a88804fa2430b43d6457b692378f6b74b356155283566ac/numpy-2.3.5-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:04822c00b5fd0323c8166d66c701dc31b7fbd252c100acd708c48f763968d6a3", size = 16091613, upload-time = "2025-11-16T22:52:08.651Z" }, + { url = "https://files.pythonhosted.org/packages/c2/88/330da2071e8771e60d1038166ff9d73f29da37b01ec3eb43cb1427464e10/numpy-2.3.5-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:d6889ec4ec662a1a37eb4b4fb26b6100841804dac55bd9df579e326cdc146227", size = 18591147, upload-time = "2025-11-16T22:52:11.453Z" }, + { url = "https://files.pythonhosted.org/packages/51/41/851c4b4082402d9ea860c3626db5d5df47164a712cb23b54be028b184c1c/numpy-2.3.5-cp314-cp314t-win32.whl", hash = "sha256:93eebbcf1aafdf7e2ddd44c2923e2672e1010bddc014138b229e49725b4d6be5", size = 6479806, upload-time = "2025-11-16T22:52:14.641Z" }, + { url = "https://files.pythonhosted.org/packages/90/30/d48bde1dfd93332fa557cff1972fbc039e055a52021fbef4c2c4b1eefd17/numpy-2.3.5-cp314-cp314t-win_amd64.whl", hash = "sha256:c8a9958e88b65c3b27e22ca2a076311636850b612d6bbfb76e8d156aacde2aaf", size = 13105760, upload-time = "2025-11-16T22:52:17.975Z" }, + { url = "https://files.pythonhosted.org/packages/2d/fd/4b5eb0b3e888d86aee4d198c23acec7d214baaf17ea93c1adec94c9518b9/numpy-2.3.5-cp314-cp314t-win_arm64.whl", hash = "sha256:6203fdf9f3dc5bdaed7319ad8698e685c7a3be10819f41d32a0723e611733b42", size = 10545459, upload-time = "2025-11-16T22:52:20.55Z" }, ] [[package]] @@ -1241,16 +1311,16 @@ wheels = [ [[package]] name = "paracelsus" -version = "0.12.0" +version = "0.13.2" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "pydot" }, { name = "sqlalchemy" }, { name = "typer" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/c3/fe/84f4d06ac3e6038384847dc1d5c8b956f61b780f69509d177107b550c7b9/paracelsus-0.12.0.tar.gz", hash = "sha256:f1d8f584ebc445db99a2906f97ff55f36ae663c104320dd4a6b5b78b4fa24dce", size = 83664, upload-time = "2025-10-07T12:45:41.112Z" } +sdist = { url = "https://files.pythonhosted.org/packages/03/ca/adad895f85086a2942d4a47b02d0df02d99db3bd6adc904c796c487eb110/paracelsus-0.13.2.tar.gz", hash = "sha256:1865e68a6cd56e8c1a003266abfe2d4f7d8ec187c8649098d12c2ba8d4f8b48a", size = 86625, upload-time = "2025-11-22T01:36:30.514Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/b3/60/9062e4072c16750b6b01bac9c55b329b249ee7c970d61c128049be197d7a/paracelsus-0.12.0-py3-none-any.whl", hash = "sha256:01f5a508174d06a86d53374215a0c85962498361ac3f0bd3450023760d3b3836", size = 81236, upload-time = "2025-10-07T12:45:39.929Z" }, + { url = "https://files.pythonhosted.org/packages/8d/0e/7a7ba5b69bd6e75533e5ae046e359a74008366139d8fd36fcbfe3ac5923a/paracelsus-0.13.2-py3-none-any.whl", hash = "sha256:330782a682225f2ece59e29d7cc93ab902d177889d88eb2a97efa09a2fd9cc45", size = 15837, upload-time = "2025-11-22T01:36:29.12Z" }, ] [[package]] @@ -1334,29 +1404,29 @@ wheels = [ [[package]] name = "protobuf" -version = "6.33.0" +version = "6.33.1" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/19/ff/64a6c8f420818bb873713988ca5492cba3a7946be57e027ac63495157d97/protobuf-6.33.0.tar.gz", hash = "sha256:140303d5c8d2037730c548f8c7b93b20bb1dc301be280c378b82b8894589c954", size = 443463, upload-time = "2025-10-15T20:39:52.159Z" } +sdist = { url = "https://files.pythonhosted.org/packages/0a/03/a1440979a3f74f16cab3b75b0da1a1a7f922d56a8ddea96092391998edc0/protobuf-6.33.1.tar.gz", hash = "sha256:97f65757e8d09870de6fd973aeddb92f85435607235d20b2dfed93405d00c85b", size = 443432, upload-time = "2025-11-13T16:44:18.895Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/7e/ee/52b3fa8feb6db4a833dfea4943e175ce645144532e8a90f72571ad85df4e/protobuf-6.33.0-cp310-abi3-win32.whl", hash = "sha256:d6101ded078042a8f17959eccd9236fb7a9ca20d3b0098bbcb91533a5680d035", size = 425593, upload-time = "2025-10-15T20:39:40.29Z" }, - { url = "https://files.pythonhosted.org/packages/7b/c6/7a465f1825872c55e0341ff4a80198743f73b69ce5d43ab18043699d1d81/protobuf-6.33.0-cp310-abi3-win_amd64.whl", hash = "sha256:9a031d10f703f03768f2743a1c403af050b6ae1f3480e9c140f39c45f81b13ee", size = 436882, upload-time = "2025-10-15T20:39:42.841Z" }, - { url = "https://files.pythonhosted.org/packages/e1/a9/b6eee662a6951b9c3640e8e452ab3e09f117d99fc10baa32d1581a0d4099/protobuf-6.33.0-cp39-abi3-macosx_10_9_universal2.whl", hash = "sha256:905b07a65f1a4b72412314082c7dbfae91a9e8b68a0cc1577515f8df58ecf455", size = 427521, upload-time = "2025-10-15T20:39:43.803Z" }, - { url = "https://files.pythonhosted.org/packages/10/35/16d31e0f92c6d2f0e77c2a3ba93185130ea13053dd16200a57434c882f2b/protobuf-6.33.0-cp39-abi3-manylinux2014_aarch64.whl", hash = "sha256:e0697ece353e6239b90ee43a9231318302ad8353c70e6e45499fa52396debf90", size = 324445, upload-time = "2025-10-15T20:39:44.932Z" }, - { url = "https://files.pythonhosted.org/packages/e6/eb/2a981a13e35cda8b75b5585aaffae2eb904f8f351bdd3870769692acbd8a/protobuf-6.33.0-cp39-abi3-manylinux2014_s390x.whl", hash = "sha256:e0a1715e4f27355afd9570f3ea369735afc853a6c3951a6afe1f80d8569ad298", size = 339159, upload-time = "2025-10-15T20:39:46.186Z" }, - { url = "https://files.pythonhosted.org/packages/21/51/0b1cbad62074439b867b4e04cc09b93f6699d78fd191bed2bbb44562e077/protobuf-6.33.0-cp39-abi3-manylinux2014_x86_64.whl", hash = "sha256:35be49fd3f4fefa4e6e2aacc35e8b837d6703c37a2168a55ac21e9b1bc7559ef", size = 323172, upload-time = "2025-10-15T20:39:47.465Z" }, - { url = "https://files.pythonhosted.org/packages/07/d1/0a28c21707807c6aacd5dc9c3704b2aa1effbf37adebd8caeaf68b17a636/protobuf-6.33.0-py3-none-any.whl", hash = "sha256:25c9e1963c6734448ea2d308cfa610e692b801304ba0908d7bfa564ac5132995", size = 170477, upload-time = "2025-10-15T20:39:51.311Z" }, + { url = "https://files.pythonhosted.org/packages/06/f1/446a9bbd2c60772ca36556bac8bfde40eceb28d9cc7838755bc41e001d8f/protobuf-6.33.1-cp310-abi3-win32.whl", hash = "sha256:f8d3fdbc966aaab1d05046d0240dd94d40f2a8c62856d41eaa141ff64a79de6b", size = 425593, upload-time = "2025-11-13T16:44:06.275Z" }, + { url = "https://files.pythonhosted.org/packages/a6/79/8780a378c650e3df849b73de8b13cf5412f521ca2ff9b78a45c247029440/protobuf-6.33.1-cp310-abi3-win_amd64.whl", hash = "sha256:923aa6d27a92bf44394f6abf7ea0500f38769d4b07f4be41cb52bd8b1123b9ed", size = 436883, upload-time = "2025-11-13T16:44:09.222Z" }, + { url = "https://files.pythonhosted.org/packages/cd/93/26213ff72b103ae55bb0d73e7fb91ea570ef407c3ab4fd2f1f27cac16044/protobuf-6.33.1-cp39-abi3-macosx_10_9_universal2.whl", hash = "sha256:fe34575f2bdde76ac429ec7b570235bf0c788883e70aee90068e9981806f2490", size = 427522, upload-time = "2025-11-13T16:44:10.475Z" }, + { url = "https://files.pythonhosted.org/packages/c2/32/df4a35247923393aa6b887c3b3244a8c941c32a25681775f96e2b418f90e/protobuf-6.33.1-cp39-abi3-manylinux2014_aarch64.whl", hash = "sha256:f8adba2e44cde2d7618996b3fc02341f03f5bc3f2748be72dc7b063319276178", size = 324445, upload-time = "2025-11-13T16:44:11.869Z" }, + { url = "https://files.pythonhosted.org/packages/8e/d0/d796e419e2ec93d2f3fa44888861c3f88f722cde02b7c3488fcc6a166820/protobuf-6.33.1-cp39-abi3-manylinux2014_s390x.whl", hash = "sha256:0f4cf01222c0d959c2b399142deb526de420be8236f22c71356e2a544e153c53", size = 339161, upload-time = "2025-11-13T16:44:12.778Z" }, + { url = "https://files.pythonhosted.org/packages/1d/2a/3c5f05a4af06649547027d288747f68525755de692a26a7720dced3652c0/protobuf-6.33.1-cp39-abi3-manylinux2014_x86_64.whl", hash = "sha256:8fd7d5e0eb08cd5b87fd3df49bc193f5cfd778701f47e11d127d0afc6c39f1d1", size = 323171, upload-time = "2025-11-13T16:44:14.035Z" }, + { url = "https://files.pythonhosted.org/packages/08/b4/46310463b4f6ceef310f8348786f3cff181cea671578e3d9743ba61a459e/protobuf-6.33.1-py3-none-any.whl", hash = "sha256:d595a9fd694fdeb061a62fbe10eb039cc1e444df81ec9bb70c7fc59ebcb1eafa", size = 170477, upload-time = "2025-11-13T16:44:17.633Z" }, ] [[package]] name = "psycopg" -version = "3.2.12" +version = "3.2.13" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "tzdata", marker = "sys_platform == 'win32'" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/a8/77/c72d10262b872617e509a0c60445afcc4ce2cd5cd6bc1c97700246d69c85/psycopg-3.2.12.tar.gz", hash = "sha256:85c08d6f6e2a897b16280e0ff6406bef29b1327c045db06d21f364d7cd5da90b", size = 160642, upload-time = "2025-10-26T00:46:03.045Z" } +sdist = { url = "https://files.pythonhosted.org/packages/44/05/d4a05988f15fcf90e0088c735b1f2fc04a30b7fc65461d6ec278f5f2f17a/psycopg-3.2.13.tar.gz", hash = "sha256:309adaeda61d44556046ec9a83a93f42bbe5310120b1995f3af49ab6d9f13c1d", size = 160626, upload-time = "2025-11-21T22:34:32.328Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/c8/28/8c4f90e415411dc9c78d6ba10b549baa324659907c13f64bfe3779d4066c/psycopg-3.2.12-py3-none-any.whl", hash = "sha256:8a1611a2d4c16ae37eada46438be9029a35bb959bb50b3d0e1e93c0f3d54c9ee", size = 206765, upload-time = "2025-10-26T00:10:42.173Z" }, + { url = "https://files.pythonhosted.org/packages/a9/14/f2724bd1986158a348316e86fdd0837a838b14a711df3f00e47fba597447/psycopg-3.2.13-py3-none-any.whl", hash = "sha256:a481374514f2da627157f767a9336705ebefe93ea7a0522a6cbacba165da179a", size = 206797, upload-time = "2025-11-21T22:29:39.733Z" }, ] [package.optional-dependencies] @@ -1366,27 +1436,27 @@ binary = [ [[package]] name = "psycopg-binary" -version = "3.2.12" -source = { registry = "https://pypi.org/simple" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/b2/0b/9d480aba4a4864832c29e6fc94ddd34d9927c276448eb3b56ffe24ed064c/psycopg_binary-3.2.12-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:442f20153415f374ae5753ca618637611a41a3c58c56d16ce55f845d76a3cf7b", size = 4017829, upload-time = "2025-10-26T00:26:27.031Z" }, - { url = "https://files.pythonhosted.org/packages/a4/f3/0d294b30349bde24a46741a1f27a10e8ab81e9f4118d27c2fe592acfb42a/psycopg_binary-3.2.12-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:79de3cc5adbf51677009a8fda35ac9e9e3686d5595ab4b0c43ec7099ece6aeb5", size = 4089835, upload-time = "2025-10-26T00:27:01.392Z" }, - { url = "https://files.pythonhosted.org/packages/82/d4/ff82e318e5a55d6951b278d3af7b4c7c1b19344e3a3722b6613f156a38ea/psycopg_binary-3.2.12-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:095ccda59042a1239ac2fefe693a336cb5cecf8944a8d9e98b07f07e94e2b78d", size = 4625474, upload-time = "2025-10-26T00:27:40.34Z" }, - { url = "https://files.pythonhosted.org/packages/b1/e8/2c9df6475a5ab6d614d516f4497c568d84f7d6c21d0e11444468c9786c9f/psycopg_binary-3.2.12-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:efab679a2c7d1bf7d0ec0e1ecb47fe764945eff75bb4321f2e699b30a12db9b3", size = 4720350, upload-time = "2025-10-26T00:28:20.104Z" }, - { url = "https://files.pythonhosted.org/packages/74/f5/7aec81b0c41985dc006e2d5822486ad4b7c2a1a97a5a05e37dc2adaf1512/psycopg_binary-3.2.12-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:d369e79ad9647fc8217cbb51bbbf11f9a1ffca450be31d005340157ffe8e91b3", size = 4411621, upload-time = "2025-10-26T00:28:59.104Z" }, - { url = "https://files.pythonhosted.org/packages/fc/15/d3cb41b8fa9d5f14320ab250545fbb66f9ddb481e448e618902672a806c0/psycopg_binary-3.2.12-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:eedc410f82007038030650aa58f620f9fe0009b9d6b04c3dc71cbd3bae5b2675", size = 3863081, upload-time = "2025-10-26T00:29:31.235Z" }, - { url = "https://files.pythonhosted.org/packages/69/8a/72837664e63e3cd3aa145cedcf29e5c21257579739aba78ab7eb668f7d9c/psycopg_binary-3.2.12-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:f3bae4be7f6781bf6c9576eedcd5e1bb74468126fa6de991e47cdb1a8ea3a42a", size = 3537428, upload-time = "2025-10-26T00:30:01.465Z" }, - { url = "https://files.pythonhosted.org/packages/cc/7e/1b78ae38e7d69e6d7fb1e2dcce101493f5fa429480bac3a68b876c9b1635/psycopg_binary-3.2.12-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:8ffe75fe6be902dadd439adf4228c98138a992088e073ede6dd34e7235f4e03e", size = 3585981, upload-time = "2025-10-26T00:30:31.635Z" }, - { url = "https://files.pythonhosted.org/packages/a3/f8/245b4868b2dac46c3fb6383b425754ae55df1910c826d305ed414da03777/psycopg_binary-3.2.12-cp313-cp313-win_amd64.whl", hash = "sha256:2598d0e4f2f258da13df0560187b3f1dfc9b8688c46b9d90176360ae5212c3fc", size = 2912929, upload-time = "2025-10-26T00:30:56.413Z" }, - { url = "https://files.pythonhosted.org/packages/5c/5b/76fbb40b981b73b285a00dccafc38cf67b7a9b3f7d4f2025dda7b896e7ef/psycopg_binary-3.2.12-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:dc68094e00a5a7e8c20de1d3a0d5e404a27f522e18f8eb62bbbc9f865c3c81ef", size = 4016868, upload-time = "2025-10-26T00:31:29.974Z" }, - { url = "https://files.pythonhosted.org/packages/0e/08/8841ae3e2d1a3228e79eaaf5b7f991d15f0a231bb5031a114305b19724b1/psycopg_binary-3.2.12-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:2d55009eeddbef54c711093c986daaf361d2c4210aaa1ee905075a3b97a62441", size = 4090508, upload-time = "2025-10-26T00:32:04.192Z" }, - { url = "https://files.pythonhosted.org/packages/05/de/a41f62230cf4095ae4547eceada218cf28c17e7f94376913c1c8dde9546f/psycopg_binary-3.2.12-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:66a031f22e4418016990446d3e38143826f03ad811b9f78f58e2afbc1d343f7a", size = 4629788, upload-time = "2025-10-26T00:32:43.28Z" }, - { url = "https://files.pythonhosted.org/packages/45/19/529d92134eae44475f781a86d58cdf3edd0953e17c69762abf387a9f2636/psycopg_binary-3.2.12-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:58ed30d33c25d7dc8d2f06285e88493147c2a660cc94713e4b563a99efb80a1f", size = 4724124, upload-time = "2025-10-26T00:33:22.594Z" }, - { url = "https://files.pythonhosted.org/packages/5c/f5/97344e87065f7c9713ce213a2cff7732936ec3af6622e4b2a88715a953f2/psycopg_binary-3.2.12-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:e0b5ccd03ca4749b8f66f38608ccbcb415cbd130d02de5eda80d042b83bee90e", size = 4411340, upload-time = "2025-10-26T00:34:00.759Z" }, - { url = "https://files.pythonhosted.org/packages/b1/c2/34bce068f6bfb4c2e7bb1187bb64a3f3be254702b158c4ad05eacc0055cf/psycopg_binary-3.2.12-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:909de94de7dd4d6086098a5755562207114c9638ec42c52d84c8a440c45fe084", size = 3867815, upload-time = "2025-10-26T00:34:33.181Z" }, - { url = "https://files.pythonhosted.org/packages/d1/a1/c647e01ab162e6bfa52380e23e486215e9d28ffd31e9cf3cb1e9ca59008b/psycopg_binary-3.2.12-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:7130effd0517881f3a852eff98729d51034128f0737f64f0d1c7ea8343d77bd7", size = 3541756, upload-time = "2025-10-26T00:35:08.622Z" }, - { url = "https://files.pythonhosted.org/packages/6b/d0/795bdaa8c946a7b7126bf7ca8d4371eaaa613093e3ec341a0e50f52cbee2/psycopg_binary-3.2.12-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:89b3c5201ca616d69ca0c3c0003ca18f7170a679c445c7e386ebfb4f29aa738e", size = 3587950, upload-time = "2025-10-26T00:35:41.183Z" }, - { url = "https://files.pythonhosted.org/packages/53/cf/10c3e95827a3ca8af332dfc471befec86e15a14dc83cee893c49a4910dad/psycopg_binary-3.2.12-cp314-cp314-win_amd64.whl", hash = "sha256:48a8e29f3e38fcf8d393b8fe460d83e39c107ad7e5e61cd3858a7569e0554a39", size = 3005787, upload-time = "2025-10-26T00:36:06.783Z" }, +version = "3.2.13" +source = { registry = "https://pypi.org/simple" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/28/ec/ef37bb44dc02fcc6c0a3eeb93f4baaac13bcb228633fe38ad3fb5a3f6449/psycopg_binary-3.2.13-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:dbae6ab1966e2b61d97e47220556c330c4608bb4cfb3a124aa0595c39995c068", size = 3995628, upload-time = "2025-11-21T22:31:45.921Z" }, + { url = "https://files.pythonhosted.org/packages/6d/ad/4748f5f1a40248af16dba087dbec50bd335ee025cc1fb9bf64773378ceff/psycopg_binary-3.2.13-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:fae933e4564386199fc54845d85413eedb49760e0bcd2b621fde2dd1825b99b3", size = 4069024, upload-time = "2025-11-21T22:31:50.202Z" }, + { url = "https://files.pythonhosted.org/packages/cf/c2/f02ec6bbc30c7fcd3b39823d2d624b42fae480edeb6e50eb3276281d5635/psycopg_binary-3.2.13-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:13e2f8894d410678529ff9f1211f96c5a93ff142f992b302682b42d924428b61", size = 4615127, upload-time = "2025-11-21T22:31:56.517Z" }, + { url = "https://files.pythonhosted.org/packages/f0/0d/a54fc2cdd672c84175d6869cc823d6ec2a8909318d491f3c24e6077983f2/psycopg_binary-3.2.13-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:f26f7009375cf1e92180e5c517c52da1054f7e690dde90e0ed00fa8b5736bcd4", size = 4710267, upload-time = "2025-11-21T22:32:04.585Z" }, + { url = "https://files.pythonhosted.org/packages/9d/b7/067de1acaf3d312253351f3af4121f972584bd36cada6378d4b0cdcebd38/psycopg_binary-3.2.13-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:ea2fdbcc9142933a47c66970e0df8b363e3bd1ea4c5ce376f2f3d94a9aeec847", size = 4400795, upload-time = "2025-11-21T22:32:08.883Z" }, + { url = "https://files.pythonhosted.org/packages/64/b5/030e6b1ebfc4d3a8fca03adc5fc827982643bad0b01a1268538d17c08ed3/psycopg_binary-3.2.13-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:ac92d6bc1d4a41c7459953a9aa727b9966e937e94c9e072527317fd2a67d488b", size = 3851239, upload-time = "2025-11-21T22:32:12.333Z" }, + { url = "https://files.pythonhosted.org/packages/79/6f/0541845364a7de9eae6807060da6a04b22a8eb2e803606d285d9250fbe93/psycopg_binary-3.2.13-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:8b843c00478739e95c46d6d3472b13123b634685f107831a9bfc41503a06ecbd", size = 3525084, upload-time = "2025-11-21T22:32:15.946Z" }, + { url = "https://files.pythonhosted.org/packages/83/ae/6507890dc30a4bbd9d938d4ff3a4079d009a5ad8170af51c7f762438fdbf/psycopg_binary-3.2.13-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:2f63868cc96bc18486cebec24445affbdd7f7debf28fac466ea935a8b5a4753b", size = 3576787, upload-time = "2025-11-21T22:32:19.922Z" }, + { url = "https://files.pythonhosted.org/packages/9d/64/3d1c2f1fd09b60cdfbe68b9a810b357ba505eff6e4bdb1a2d9f6729da64c/psycopg_binary-3.2.13-cp313-cp313-win_amd64.whl", hash = "sha256:594dfbca3326e997ae738d3d339004e8416b1f7390f52ce8dc2d692393e8fa96", size = 2905584, upload-time = "2025-11-21T22:32:23.399Z" }, + { url = "https://files.pythonhosted.org/packages/d3/b4/7656b3d67bedff2b900c8c4671cb6eb5fb99c2fc36da33579cac89779c25/psycopg_binary-3.2.13-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:502a778c3e07c6b3aabfa56ee230e8c264d2debfab42d11535513a01bdfff0d6", size = 3997201, upload-time = "2025-11-21T22:32:28.185Z" }, + { url = "https://files.pythonhosted.org/packages/e0/2e/3b4afbd94d48df19c3931cedba464b109f89d81ac43178e6a3d654b4e8d5/psycopg_binary-3.2.13-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:7561a71d764d6f74d66e8b7d844b0f27fa33de508f65c17b1d56a94c73644776", size = 4071631, upload-time = "2025-11-21T22:32:32.594Z" }, + { url = "https://files.pythonhosted.org/packages/5e/8b/107d06d55992e2f13157eb705ba5a47d06c4cf1bed077dff0c567b10c187/psycopg_binary-3.2.13-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:9caf14745a1930b4e03fe4072cd7154eaf6e1241d20c42130ed784408a26b24b", size = 4620918, upload-time = "2025-11-21T22:32:37.357Z" }, + { url = "https://files.pythonhosted.org/packages/e1/47/a925620f261b115f31e813a5bfe640f316413b1864094a60162f4a6e4d67/psycopg_binary-3.2.13-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:4a6cafabdc0bfa37e11c6f365020fd5916b62d6296df581f4dceaa43a2ce680c", size = 4714494, upload-time = "2025-11-21T22:32:42.138Z" }, + { url = "https://files.pythonhosted.org/packages/46/33/bed384665356bb9ba17dd8e104884d87cc2343d16dffdfd9aaa9a159bd4d/psycopg_binary-3.2.13-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:c96cb5a27e68acac6d74b64fca38592a692de9c4b7827339190698d58027aa45", size = 4403046, upload-time = "2025-11-21T22:32:47.241Z" }, + { url = "https://files.pythonhosted.org/packages/41/88/749d8e8102fb5df502e2ecb053b79e78e3358af01af652b5dbeb96ab7905/psycopg_binary-3.2.13-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:596176ae3dfbf56fc61108870bfe17c7205d33ac28d524909feb5335201daa0a", size = 3859046, upload-time = "2025-11-21T22:32:51.481Z" }, + { url = "https://files.pythonhosted.org/packages/38/7c/f492e63b517d6dcd564e8c43bc15e11a4c712a848adf8938ce33bfd4c867/psycopg_binary-3.2.13-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:cc3a0408435dfbb77eeca5e8050df4b19a6e9b7e5e5583edf524c4a83d6293b2", size = 3531351, upload-time = "2025-11-21T22:32:55.571Z" }, + { url = "https://files.pythonhosted.org/packages/07/5a/d8743eb23944e5cf2a0bbfa92935c140b5beaacdb872be641065ed70ab2c/psycopg_binary-3.2.13-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:65df0d459ffba14082d8ca4bb2f6ffbb2f8d02968f7d34a747e1031934b76b23", size = 3581034, upload-time = "2025-11-21T22:33:01.648Z" }, + { url = "https://files.pythonhosted.org/packages/46/b2/411d4180252144f7eff024894d2d2ebb98c012c944a282fc20250870e461/psycopg_binary-3.2.13-cp314-cp314-win_amd64.whl", hash = "sha256:5c77f156c7316529ed371b5f95a51139e531328ee39c37493a2afcbc1f79d5de", size = 3000162, upload-time = "2025-11-21T22:33:07.378Z" }, ] [[package]] @@ -1524,16 +1594,16 @@ wheels = [ [[package]] name = "pydantic-settings" -version = "2.11.0" +version = "2.12.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "pydantic" }, { name = "python-dotenv" }, { name = "typing-inspection" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/20/c5/dbbc27b814c71676593d1c3f718e6cd7d4f00652cefa24b75f7aa3efb25e/pydantic_settings-2.11.0.tar.gz", hash = "sha256:d0e87a1c7d33593beb7194adb8470fc426e95ba02af83a0f23474a04c9a08180", size = 188394, upload-time = "2025-09-24T14:19:11.764Z" } +sdist = { url = "https://files.pythonhosted.org/packages/43/4b/ac7e0aae12027748076d72a8764ff1c9d82ca75a7a52622e67ed3f765c54/pydantic_settings-2.12.0.tar.gz", hash = "sha256:005538ef951e3c2a68e1c08b292b5f2e71490def8589d4221b95dab00dafcfd0", size = 194184, upload-time = "2025-11-10T14:25:47.013Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/83/d6/887a1ff844e64aa823fb4905978d882a633cfe295c32eacad582b78a7d8b/pydantic_settings-2.11.0-py3-none-any.whl", hash = "sha256:fe2cea3413b9530d10f3a5875adffb17ada5c1e1bab0b2885546d7310415207c", size = 48608, upload-time = "2025-09-24T14:19:10.015Z" }, + { url = "https://files.pythonhosted.org/packages/c1/60/5d4751ba3f4a40a6891f24eec885f51afd78d208498268c734e256fb13c4/pydantic_settings-2.12.0-py3-none-any.whl", hash = "sha256:fddb9fd99a5b18da837b29710391e945b1e30c135477f484084ee513adb93809", size = 51880, upload-time = "2025-11-10T14:25:45.546Z" }, ] [[package]] @@ -1604,7 +1674,7 @@ wheels = [ [[package]] name = "pytest" -version = "8.4.2" +version = "9.0.1" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "colorama", marker = "sys_platform == 'win32'" }, @@ -1613,9 +1683,9 @@ dependencies = [ { name = "pluggy" }, { name = "pygments" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/a3/5c/00a0e072241553e1a7496d638deababa67c5058571567b92a7eaa258397c/pytest-8.4.2.tar.gz", hash = "sha256:86c0d0b93306b961d58d62a4db4879f27fe25513d4b969df351abdddb3c30e01", size = 1519618, upload-time = "2025-09-04T14:34:22.711Z" } +sdist = { url = "https://files.pythonhosted.org/packages/07/56/f013048ac4bc4c1d9be45afd4ab209ea62822fb1598f40687e6bf45dcea4/pytest-9.0.1.tar.gz", hash = "sha256:3e9c069ea73583e255c3b21cf46b8d3c56f6e3a1a8f6da94ccb0fcf57b9d73c8", size = 1564125, upload-time = "2025-11-12T13:05:09.333Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/a8/a4/20da314d277121d6534b3a980b29035dcd51e6744bd79075a6ce8fa4eb8d/pytest-8.4.2-py3-none-any.whl", hash = "sha256:872f880de3fc3a5bdc88a11b39c9710c3497a547cfa9320bc3c5e62fbf272e79", size = 365750, upload-time = "2025-09-04T14:34:20.226Z" }, + { url = "https://files.pythonhosted.org/packages/0b/8b/6300fb80f858cda1c51ffa17075df5d846757081d11ab4aa35cef9e6258b/pytest-9.0.1-py3-none-any.whl", hash = "sha256:67be0030d194df2dfa7b556f2e56fb3c3315bd5c8822c6951162b92b32ce7dad", size = 373668, upload-time = "2025-11-12T13:05:07.379Z" }, ] [[package]] @@ -1634,14 +1704,14 @@ wheels = [ [[package]] name = "pytest-asyncio" -version = "1.2.0" +version = "1.3.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "pytest" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/42/86/9e3c5f48f7b7b638b216e4b9e645f54d199d7abbbab7a64a13b4e12ba10f/pytest_asyncio-1.2.0.tar.gz", hash = "sha256:c609a64a2a8768462d0c99811ddb8bd2583c33fd33cf7f21af1c142e824ffb57", size = 50119, upload-time = "2025-09-12T07:33:53.816Z" } +sdist = { url = "https://files.pythonhosted.org/packages/90/2c/8af215c0f776415f3590cac4f9086ccefd6fd463befeae41cd4d3f193e5a/pytest_asyncio-1.3.0.tar.gz", hash = "sha256:d7f52f36d231b80ee124cd216ffb19369aa168fc10095013c6b014a34d3ee9e5", size = 50087, upload-time = "2025-11-10T16:07:47.256Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/04/93/2fa34714b7a4ae72f2f8dad66ba17dd9a2c793220719e736dda28b7aec27/pytest_asyncio-1.2.0-py3-none-any.whl", hash = "sha256:8e17ae5e46d8e7efe51ab6494dd2010f4ca8dae51652aa3c8d55acf50bfb2e99", size = 15095, upload-time = "2025-09-12T07:33:52.639Z" }, + { url = "https://files.pythonhosted.org/packages/e5/35/f8b19922b6a25bc0880171a2f1a003eaeb93657475193ab516fd87cac9da/pytest_asyncio-1.3.0-py3-none-any.whl", hash = "sha256:611e26147c7f77640e6d0a92a38ed17c3e9848063698d5c93d5aa7aa11cebff5", size = 15075, upload-time = "2025-11-10T16:07:45.537Z" }, ] [[package]] @@ -1747,11 +1817,11 @@ wheels = [ [[package]] name = "redis" -version = "7.0.1" +version = "7.1.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/57/8f/f125feec0b958e8d22c8f0b492b30b1991d9499a4315dfde466cf4289edc/redis-7.0.1.tar.gz", hash = "sha256:c949df947dca995dc68fdf5a7863950bf6df24f8d6022394585acc98e81624f1", size = 4755322, upload-time = "2025-10-27T14:34:00.33Z" } +sdist = { url = "https://files.pythonhosted.org/packages/43/c8/983d5c6579a411d8a99bc5823cc5712768859b5ce2c8afe1a65b37832c81/redis-7.1.0.tar.gz", hash = "sha256:b1cc3cfa5a2cb9c2ab3ba700864fb0ad75617b41f01352ce5779dabf6d5f9c3c", size = 4796669, upload-time = "2025-11-19T15:54:39.961Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/e9/97/9f22a33c475cda519f20aba6babb340fb2f2254a02fb947816960d1e669a/redis-7.0.1-py3-none-any.whl", hash = "sha256:4977af3c7d67f8f0eb8b6fec0dafc9605db9343142f634041fb0235f67c0588a", size = 339938, upload-time = "2025-10-27T14:33:58.553Z" }, + { url = "https://files.pythonhosted.org/packages/89/f0/8956f8a86b20d7bb9d6ac0187cf4cd54d8065bc9a1a09eb8011d4d326596/redis-7.1.0-py3-none-any.whl", hash = "sha256:23c52b208f92b56103e17c5d06bdc1a6c2c0b3106583985a76a18f83b265de2b", size = 354159, upload-time = "2025-11-19T15:54:38.064Z" }, ] [[package]] @@ -1992,16 +2062,16 @@ wheels = [ [[package]] name = "rich-toolkit" -version = "0.15.1" +version = "0.16.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "click" }, { name = "rich" }, { name = "typing-extensions" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/67/33/1a18839aaa8feef7983590c05c22c9c09d245ada6017d118325bbfcc7651/rich_toolkit-0.15.1.tar.gz", hash = "sha256:6f9630eb29f3843d19d48c3bd5706a086d36d62016687f9d0efa027ddc2dd08a", size = 115322, upload-time = "2025-09-04T09:28:11.789Z" } +sdist = { url = "https://files.pythonhosted.org/packages/83/8e/ab512afd71d4e67bb611a57db92a0e967304c97ec61963e99103f5a88069/rich_toolkit-0.16.0.tar.gz", hash = "sha256:2f554b00b194776639f4d80f2706980756b659ceed9f345ebbd9de77d1bdd0f4", size = 183790, upload-time = "2025-11-19T15:26:11.431Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/c8/49/42821d55ead7b5a87c8d121edf323cb393d8579f63e933002ade900b784f/rich_toolkit-0.15.1-py3-none-any.whl", hash = "sha256:36a0b1d9a135d26776e4b78f1d5c2655da6e0ef432380b5c6b523c8d8ab97478", size = 29412, upload-time = "2025-09-04T09:28:10.587Z" }, + { url = "https://files.pythonhosted.org/packages/3a/04/f4bfb5d8a258d395d7fb6fbaa0e3fe7bafae17a2a3e2387e6dea9d6474df/rich_toolkit-0.16.0-py3-none-any.whl", hash = "sha256:3f4307f678c5c1e22c36d89ac05f1cd145ed7174f19c1ce5a4d3664ba77c0f9e", size = 29775, upload-time = "2025-11-19T15:26:10.336Z" }, ] [[package]] @@ -2071,53 +2141,53 @@ wheels = [ [[package]] name = "ruff" -version = "0.14.4" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/df/55/cccfca45157a2031dcbb5a462a67f7cf27f8b37d4b3b1cd7438f0f5c1df6/ruff-0.14.4.tar.gz", hash = "sha256:f459a49fe1085a749f15414ca76f61595f1a2cc8778ed7c279b6ca2e1fd19df3", size = 5587844, upload-time = "2025-11-06T22:07:45.033Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/17/b9/67240254166ae1eaa38dec32265e9153ac53645a6c6670ed36ad00722af8/ruff-0.14.4-py3-none-linux_armv6l.whl", hash = "sha256:e6604613ffbcf2297cd5dcba0e0ac9bd0c11dc026442dfbb614504e87c349518", size = 12606781, upload-time = "2025-11-06T22:07:01.841Z" }, - { url = "https://files.pythonhosted.org/packages/46/c8/09b3ab245d8652eafe5256ab59718641429f68681ee713ff06c5c549f156/ruff-0.14.4-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:d99c0b52b6f0598acede45ee78288e5e9b4409d1ce7f661f0fa36d4cbeadf9a4", size = 12946765, upload-time = "2025-11-06T22:07:05.858Z" }, - { url = "https://files.pythonhosted.org/packages/14/bb/1564b000219144bf5eed2359edc94c3590dd49d510751dad26202c18a17d/ruff-0.14.4-py3-none-macosx_11_0_arm64.whl", hash = "sha256:9358d490ec030f1b51d048a7fd6ead418ed0826daf6149e95e30aa67c168af33", size = 11928120, upload-time = "2025-11-06T22:07:08.023Z" }, - { url = "https://files.pythonhosted.org/packages/a3/92/d5f1770e9988cc0742fefaa351e840d9aef04ec24ae1be36f333f96d5704/ruff-0.14.4-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:81b40d27924f1f02dfa827b9c0712a13c0e4b108421665322218fc38caf615c2", size = 12370877, upload-time = "2025-11-06T22:07:10.015Z" }, - { url = "https://files.pythonhosted.org/packages/e2/29/e9282efa55f1973d109faf839a63235575519c8ad278cc87a182a366810e/ruff-0.14.4-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:f5e649052a294fe00818650712083cddc6cc02744afaf37202c65df9ea52efa5", size = 12408538, upload-time = "2025-11-06T22:07:13.085Z" }, - { url = "https://files.pythonhosted.org/packages/8e/01/930ed6ecfce130144b32d77d8d69f5c610e6d23e6857927150adf5d7379a/ruff-0.14.4-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:aa082a8f878deeba955531f975881828fd6afd90dfa757c2b0808aadb437136e", size = 13141942, upload-time = "2025-11-06T22:07:15.386Z" }, - { url = "https://files.pythonhosted.org/packages/6a/46/a9c89b42b231a9f487233f17a89cbef9d5acd538d9488687a02ad288fa6b/ruff-0.14.4-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:1043c6811c2419e39011890f14d0a30470f19d47d197c4858b2787dfa698f6c8", size = 14544306, upload-time = "2025-11-06T22:07:17.631Z" }, - { url = "https://files.pythonhosted.org/packages/78/96/9c6cf86491f2a6d52758b830b89b78c2ae61e8ca66b86bf5a20af73d20e6/ruff-0.14.4-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a9f3a936ac27fb7c2a93e4f4b943a662775879ac579a433291a6f69428722649", size = 14210427, upload-time = "2025-11-06T22:07:19.832Z" }, - { url = "https://files.pythonhosted.org/packages/71/f4/0666fe7769a54f63e66404e8ff698de1dcde733e12e2fd1c9c6efb689cb5/ruff-0.14.4-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:95643ffd209ce78bc113266b88fba3d39e0461f0cbc8b55fb92505030fb4a850", size = 13658488, upload-time = "2025-11-06T22:07:22.32Z" }, - { url = "https://files.pythonhosted.org/packages/ee/79/6ad4dda2cfd55e41ac9ed6d73ef9ab9475b1eef69f3a85957210c74ba12c/ruff-0.14.4-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:456daa2fa1021bc86ca857f43fe29d5d8b3f0e55e9f90c58c317c1dcc2afc7b5", size = 13354908, upload-time = "2025-11-06T22:07:24.347Z" }, - { url = "https://files.pythonhosted.org/packages/b5/60/f0b6990f740bb15c1588601d19d21bcc1bd5de4330a07222041678a8e04f/ruff-0.14.4-py3-none-manylinux_2_31_riscv64.whl", hash = "sha256:f911bba769e4a9f51af6e70037bb72b70b45a16db5ce73e1f72aefe6f6d62132", size = 13587803, upload-time = "2025-11-06T22:07:26.327Z" }, - { url = "https://files.pythonhosted.org/packages/c9/da/eaaada586f80068728338e0ef7f29ab3e4a08a692f92eb901a4f06bbff24/ruff-0.14.4-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:76158a7369b3979fa878612c623a7e5430c18b2fd1c73b214945c2d06337db67", size = 12279654, upload-time = "2025-11-06T22:07:28.46Z" }, - { url = "https://files.pythonhosted.org/packages/66/d4/b1d0e82cf9bf8aed10a6d45be47b3f402730aa2c438164424783ac88c0ed/ruff-0.14.4-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:f3b8f3b442d2b14c246e7aeca2e75915159e06a3540e2f4bed9f50d062d24469", size = 12357520, upload-time = "2025-11-06T22:07:31.468Z" }, - { url = "https://files.pythonhosted.org/packages/04/f4/53e2b42cc82804617e5c7950b7079d79996c27e99c4652131c6a1100657f/ruff-0.14.4-py3-none-musllinux_1_2_i686.whl", hash = "sha256:c62da9a06779deecf4d17ed04939ae8b31b517643b26370c3be1d26f3ef7dbde", size = 12719431, upload-time = "2025-11-06T22:07:33.831Z" }, - { url = "https://files.pythonhosted.org/packages/a2/94/80e3d74ed9a72d64e94a7b7706b1c1ebaa315ef2076fd33581f6a1cd2f95/ruff-0.14.4-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:5a443a83a1506c684e98acb8cb55abaf3ef725078be40237463dae4463366349", size = 13464394, upload-time = "2025-11-06T22:07:35.905Z" }, - { url = "https://files.pythonhosted.org/packages/54/1a/a49f071f04c42345c793d22f6cf5e0920095e286119ee53a64a3a3004825/ruff-0.14.4-py3-none-win32.whl", hash = "sha256:643b69cb63cd996f1fc7229da726d07ac307eae442dd8974dbc7cf22c1e18fff", size = 12493429, upload-time = "2025-11-06T22:07:38.43Z" }, - { url = "https://files.pythonhosted.org/packages/bc/22/e58c43e641145a2b670328fb98bc384e20679b5774258b1e540207580266/ruff-0.14.4-py3-none-win_amd64.whl", hash = "sha256:26673da283b96fe35fa0c939bf8411abec47111644aa9f7cfbd3c573fb125d2c", size = 13635380, upload-time = "2025-11-06T22:07:40.496Z" }, - { url = "https://files.pythonhosted.org/packages/30/bd/4168a751ddbbf43e86544b4de8b5c3b7be8d7167a2a5cb977d274e04f0a1/ruff-0.14.4-py3-none-win_arm64.whl", hash = "sha256:dd09c292479596b0e6fec8cd95c65c3a6dc68e9ad17b8f2382130f87ff6a75bb", size = 12663065, upload-time = "2025-11-06T22:07:42.603Z" }, +version = "0.14.6" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/52/f0/62b5a1a723fe183650109407fa56abb433b00aa1c0b9ba555f9c4efec2c6/ruff-0.14.6.tar.gz", hash = "sha256:6f0c742ca6a7783a736b867a263b9a7a80a45ce9bee391eeda296895f1b4e1cc", size = 5669501, upload-time = "2025-11-21T14:26:17.903Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/67/d2/7dd544116d107fffb24a0064d41a5d2ed1c9d6372d142f9ba108c8e39207/ruff-0.14.6-py3-none-linux_armv6l.whl", hash = "sha256:d724ac2f1c240dbd01a2ae98db5d1d9a5e1d9e96eba999d1c48e30062df578a3", size = 13326119, upload-time = "2025-11-21T14:25:24.2Z" }, + { url = "https://files.pythonhosted.org/packages/36/6a/ad66d0a3315d6327ed6b01f759d83df3c4d5f86c30462121024361137b6a/ruff-0.14.6-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:9f7539ea257aa4d07b7ce87aed580e485c40143f2473ff2f2b75aee003186004", size = 13526007, upload-time = "2025-11-21T14:25:26.906Z" }, + { url = "https://files.pythonhosted.org/packages/a3/9d/dae6db96df28e0a15dea8e986ee393af70fc97fd57669808728080529c37/ruff-0.14.6-py3-none-macosx_11_0_arm64.whl", hash = "sha256:7f6007e55b90a2a7e93083ba48a9f23c3158c433591c33ee2e99a49b889c6332", size = 12676572, upload-time = "2025-11-21T14:25:29.826Z" }, + { url = "https://files.pythonhosted.org/packages/76/a4/f319e87759949062cfee1b26245048e92e2acce900ad3a909285f9db1859/ruff-0.14.6-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0a8e7b9d73d8728b68f632aa8e824ef041d068d231d8dbc7808532d3629a6bef", size = 13140745, upload-time = "2025-11-21T14:25:32.788Z" }, + { url = "https://files.pythonhosted.org/packages/95/d3/248c1efc71a0a8ed4e8e10b4b2266845d7dfc7a0ab64354afe049eaa1310/ruff-0.14.6-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:d50d45d4553a3ebcbd33e7c5e0fe6ca4aafd9a9122492de357205c2c48f00775", size = 13076486, upload-time = "2025-11-21T14:25:35.601Z" }, + { url = "https://files.pythonhosted.org/packages/a5/19/b68d4563fe50eba4b8c92aa842149bb56dd24d198389c0ed12e7faff4f7d/ruff-0.14.6-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:118548dd121f8a21bfa8ab2c5b80e5b4aed67ead4b7567790962554f38e598ce", size = 13727563, upload-time = "2025-11-21T14:25:38.514Z" }, + { url = "https://files.pythonhosted.org/packages/47/ac/943169436832d4b0e867235abbdb57ce3a82367b47e0280fa7b4eabb7593/ruff-0.14.6-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:57256efafbfefcb8748df9d1d766062f62b20150691021f8ab79e2d919f7c11f", size = 15199755, upload-time = "2025-11-21T14:25:41.516Z" }, + { url = "https://files.pythonhosted.org/packages/c9/b9/288bb2399860a36d4bb0541cb66cce3c0f4156aaff009dc8499be0c24bf2/ruff-0.14.6-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ff18134841e5c68f8e5df1999a64429a02d5549036b394fafbe410f886e1989d", size = 14850608, upload-time = "2025-11-21T14:25:44.428Z" }, + { url = "https://files.pythonhosted.org/packages/ee/b1/a0d549dd4364e240f37e7d2907e97ee80587480d98c7799d2d8dc7a2f605/ruff-0.14.6-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:29c4b7ec1e66a105d5c27bd57fa93203637d66a26d10ca9809dc7fc18ec58440", size = 14118754, upload-time = "2025-11-21T14:25:47.214Z" }, + { url = "https://files.pythonhosted.org/packages/13/ac/9b9fe63716af8bdfddfacd0882bc1586f29985d3b988b3c62ddce2e202c3/ruff-0.14.6-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:167843a6f78680746d7e226f255d920aeed5e4ad9c03258094a2d49d3028b105", size = 13949214, upload-time = "2025-11-21T14:25:50.002Z" }, + { url = "https://files.pythonhosted.org/packages/12/27/4dad6c6a77fede9560b7df6802b1b697e97e49ceabe1f12baf3ea20862e9/ruff-0.14.6-py3-none-manylinux_2_31_riscv64.whl", hash = "sha256:16a33af621c9c523b1ae006b1b99b159bf5ac7e4b1f20b85b2572455018e0821", size = 14106112, upload-time = "2025-11-21T14:25:52.841Z" }, + { url = "https://files.pythonhosted.org/packages/6a/db/23e322d7177873eaedea59a7932ca5084ec5b7e20cb30f341ab594130a71/ruff-0.14.6-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:1432ab6e1ae2dc565a7eea707d3b03a0c234ef401482a6f1621bc1f427c2ff55", size = 13035010, upload-time = "2025-11-21T14:25:55.536Z" }, + { url = "https://files.pythonhosted.org/packages/a8/9c/20e21d4d69dbb35e6a1df7691e02f363423658a20a2afacf2a2c011800dc/ruff-0.14.6-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:4c55cfbbe7abb61eb914bfd20683d14cdfb38a6d56c6c66efa55ec6570ee4e71", size = 13054082, upload-time = "2025-11-21T14:25:58.625Z" }, + { url = "https://files.pythonhosted.org/packages/66/25/906ee6a0464c3125c8d673c589771a974965c2be1a1e28b5c3b96cb6ef88/ruff-0.14.6-py3-none-musllinux_1_2_i686.whl", hash = "sha256:efea3c0f21901a685fff4befda6d61a1bf4cb43de16da87e8226a281d614350b", size = 13303354, upload-time = "2025-11-21T14:26:01.816Z" }, + { url = "https://files.pythonhosted.org/packages/4c/58/60577569e198d56922b7ead07b465f559002b7b11d53f40937e95067ca1c/ruff-0.14.6-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:344d97172576d75dc6afc0e9243376dbe1668559c72de1864439c4fc95f78185", size = 14054487, upload-time = "2025-11-21T14:26:05.058Z" }, + { url = "https://files.pythonhosted.org/packages/67/0b/8e4e0639e4cc12547f41cb771b0b44ec8225b6b6a93393176d75fe6f7d40/ruff-0.14.6-py3-none-win32.whl", hash = "sha256:00169c0c8b85396516fdd9ce3446c7ca20c2a8f90a77aa945ba6b8f2bfe99e85", size = 13013361, upload-time = "2025-11-21T14:26:08.152Z" }, + { url = "https://files.pythonhosted.org/packages/fb/02/82240553b77fd1341f80ebb3eaae43ba011c7a91b4224a9f317d8e6591af/ruff-0.14.6-py3-none-win_amd64.whl", hash = "sha256:390e6480c5e3659f8a4c8d6a0373027820419ac14fa0d2713bd8e6c3e125b8b9", size = 14432087, upload-time = "2025-11-21T14:26:10.891Z" }, + { url = "https://files.pythonhosted.org/packages/a5/1f/93f9b0fad9470e4c829a5bb678da4012f0c710d09331b860ee555216f4ea/ruff-0.14.6-py3-none-win_arm64.whl", hash = "sha256:d43c81fbeae52cfa8728d8766bbf46ee4298c888072105815b392da70ca836b2", size = 13520930, upload-time = "2025-11-21T14:26:13.951Z" }, ] [[package]] name = "s3transfer" -version = "0.14.0" +version = "0.15.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "botocore" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/62/74/8d69dcb7a9efe8baa2046891735e5dfe433ad558ae23d9e3c14c633d1d58/s3transfer-0.14.0.tar.gz", hash = "sha256:eff12264e7c8b4985074ccce27a3b38a485bb7f7422cc8046fee9be4983e4125", size = 151547, upload-time = "2025-09-09T19:23:31.089Z" } +sdist = { url = "https://files.pythonhosted.org/packages/ca/bb/940d6af975948c1cc18f44545ffb219d3c35d78ec972b42ae229e8e37e08/s3transfer-0.15.0.tar.gz", hash = "sha256:d36fac8d0e3603eff9b5bfa4282c7ce6feb0301a633566153cbd0b93d11d8379", size = 152185, upload-time = "2025-11-20T20:28:56.327Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/48/f0/ae7ca09223a81a1d890b2557186ea015f6e0502e9b8cb8e1813f1d8cfa4e/s3transfer-0.14.0-py3-none-any.whl", hash = "sha256:ea3b790c7077558ed1f02a3072fb3cb992bbbd253392f4b6e9e8976941c7d456", size = 85712, upload-time = "2025-09-09T19:23:30.041Z" }, + { url = "https://files.pythonhosted.org/packages/5f/e1/5ef25f52973aa12a19cf4e1375d00932d7fb354ffd310487ba7d44225c1a/s3transfer-0.15.0-py3-none-any.whl", hash = "sha256:6f8bf5caa31a0865c4081186689db1b2534cef721d104eb26101de4b9d6a5852", size = 85984, upload-time = "2025-11-20T20:28:55.046Z" }, ] [[package]] name = "sentry-sdk" -version = "2.43.0" +version = "2.46.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "certifi" }, { name = "urllib3" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/b3/18/09875b4323b03ca9025bae7e6539797b27e4fc032998a466b4b9c3d24653/sentry_sdk-2.43.0.tar.gz", hash = "sha256:52ed6e251c5d2c084224d73efee56b007ef5c2d408a4a071270e82131d336e20", size = 368953, upload-time = "2025-10-29T11:26:08.156Z" } +sdist = { url = "https://files.pythonhosted.org/packages/7c/d7/c140a5837649e2bf2ec758494fde1d9a016c76777eab64e75ef38d685bbb/sentry_sdk-2.46.0.tar.gz", hash = "sha256:91821a23460725734b7741523021601593f35731808afc0bb2ba46c27b8acd91", size = 374761, upload-time = "2025-11-24T09:34:13.932Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/69/31/8228fa962f7fd8814d634e4ebece8780e2cdcfbdf0cd2e14d4a6861a7cd5/sentry_sdk-2.43.0-py2.py3-none-any.whl", hash = "sha256:4aacafcf1756ef066d359ae35030881917160ba7f6fc3ae11e0e58b09edc2d5d", size = 400997, upload-time = "2025-10-29T11:26:05.77Z" }, + { url = "https://files.pythonhosted.org/packages/4b/b6/ce7c502a366f4835b1f9c057753f6989a92d3c70cbadb168193f5fb7499b/sentry_sdk-2.46.0-py2.py3-none-any.whl", hash = "sha256:4eeeb60198074dff8d066ea153fa6f241fef1668c10900ea53a4200abc8da9b1", size = 406266, upload-time = "2025-11-24T09:34:12.114Z" }, ] [[package]] @@ -2158,7 +2228,7 @@ wheels = [ [[package]] name = "sqladmin" -version = "0.21.0" +version = "0.22.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "jinja2" }, @@ -2167,9 +2237,9 @@ dependencies = [ { name = "starlette" }, { name = "wtforms" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/5b/0c/614041e1b544e0de1f43b58f0105b3e2795b80369d5b0ff7412882d42fff/sqladmin-0.21.0.tar.gz", hash = "sha256:cb455b79eb79ef7d904680dd83817bf7750675147400b5b7cc401d04bda7ef2c", size = 1428312, upload-time = "2025-07-02T09:41:21.207Z" } +sdist = { url = "https://files.pythonhosted.org/packages/2c/ac/526bb3ff2dd94fbf8442bccb49ef40aa360045add19d4fbffcb43995e67a/sqladmin-0.22.0.tar.gz", hash = "sha256:4ea904d97e4d030edb68fb0681330b4d963f422442a64bee487fdc46119b3729", size = 1429937, upload-time = "2025-11-24T12:52:59.285Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/ed/8d/81b2a48cc6f5479cb1148292518e3006ec8f5fbe3b0829ef165984e9d7b9/sqladmin-0.21.0-py3-none-any.whl", hash = "sha256:2b1802c49bdd3128c6452625705693cf32d5d33e7db30e63f409bd20a9c05b53", size = 1443585, upload-time = "2025-07-02T09:41:19.205Z" }, + { url = "https://files.pythonhosted.org/packages/f2/b4/ab78c7d7b13bd3f90d6d8a106c5ad12bf7a738f89eb0241b24ad8efe5d1e/sqladmin-0.22.0-py3-none-any.whl", hash = "sha256:f2fb11165a70601a97f71956104b47da2c432db49b0d7966dc65e9e6343887d3", size = 1445514, upload-time = "2025-11-24T12:53:00.511Z" }, ] [[package]] @@ -2213,14 +2283,14 @@ wheels = [ [[package]] name = "starlette" -version = "0.49.3" +version = "0.50.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "anyio" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/de/1a/608df0b10b53b0beb96a37854ee05864d182ddd4b1156a22f1ad3860425a/starlette-0.49.3.tar.gz", hash = "sha256:1c14546f299b5901a1ea0e34410575bc33bbd741377a10484a54445588d00284", size = 2655031, upload-time = "2025-11-01T15:12:26.13Z" } +sdist = { url = "https://files.pythonhosted.org/packages/ba/b8/73a0e6a6e079a9d9cfa64113d771e421640b6f679a52eeb9b32f72d871a1/starlette-0.50.0.tar.gz", hash = "sha256:a2a17b22203254bcbc2e1f926d2d55f3f9497f769416b3190768befe598fa3ca", size = 2646985, upload-time = "2025-11-01T15:25:27.516Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/a3/e0/021c772d6a662f43b63044ab481dc6ac7592447605b5b35a957785363122/starlette-0.49.3-py3-none-any.whl", hash = "sha256:b579b99715fdc2980cf88c8ec96d3bf1ce16f5a8051a7c2b84ef9b1cdecaea2f", size = 74340, upload-time = "2025-11-01T15:12:24.387Z" }, + { url = "https://files.pythonhosted.org/packages/d9/52/1064f510b141bd54025f9b55105e26d1fa970b9be67ad766380a3c9b74b0/starlette-0.50.0-py3-none-any.whl", hash = "sha256:9e5391843ec9b6e472eed1365a78c8098cfceb7a74bfd4d6b1c0c0095efb3bca", size = 74033, upload-time = "2025-11-01T15:25:25.461Z" }, ] [[package]] diff --git a/codemeta.json b/codemeta.json index 9d940b3..caa27b5 100644 --- a/codemeta.json +++ b/codemeta.json @@ -42,7 +42,7 @@ ], "license": "https://spdx.org/licenses/AGPL-3.0-or-later", "name": "Reverse Engineering Lab", - "programmingLanguage": ["Python 3.13", "JavaScript"], + "programmingLanguage": ["Python 3", "JavaScript"], "softwareRequirements": "Docker", "version": "0.1.0" } From 04715fea042129618164d76808192df69c383b8c Mon Sep 17 00:00:00 2001 From: Simon van Lierde Date: Tue, 25 Nov 2025 10:23:09 +0000 Subject: [PATCH 55/71] chore: linting --- .github/ISSUE_TEMPLATE/bug_report.md | 6 +- .github/ISSUE_TEMPLATE/feature-request.md | 6 +- .github/ISSUE_TEMPLATE/internal-ticket.md | 6 +- .pre-commit-config.yaml | 93 ++++++------- CONTRIBUTING.md | 12 +- backend/.dockerignore | 2 +- backend/.gitignore | 2 +- backend/app/api/auth/services/user_manager.py | 6 +- .../app/api/auth/utils/email_validation.py | 2 +- .../app/api/auth/utils/programmatic_emails.py | 13 +- .../app/api/common/schemas/custom_fields.py | 8 +- backend/app/api/data_collection/routers.py | 10 +- backend/tests/conftest.py | 2 +- compose.prod.yml | 4 +- frontend-app/src/app/products/[id]/index.tsx | 8 +- .../src/services/api/validation/product.ts | 2 +- uv.lock | 126 ++++++++++-------- 17 files changed, 165 insertions(+), 143 deletions(-) diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md index 0d8647c..73bc3bd 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.md +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -1,9 +1,9 @@ --- -name: Bug report about: Create a report to help us improve -title: 'bug: ' -labels: bug assignees: '' +labels: bug +name: Bug report +title: 'bug: ' --- ## Bug description diff --git a/.github/ISSUE_TEMPLATE/feature-request.md b/.github/ISSUE_TEMPLATE/feature-request.md index eea6c5b..4d1d87f 100644 --- a/.github/ISSUE_TEMPLATE/feature-request.md +++ b/.github/ISSUE_TEMPLATE/feature-request.md @@ -1,9 +1,9 @@ --- -name: Feature request about: Suggest an idea for this project -title: 'feature request: ' -labels: feature request assignees: '' +labels: feature request +name: Feature request +title: 'feature request: ' --- ## Problem statement diff --git a/.github/ISSUE_TEMPLATE/internal-ticket.md b/.github/ISSUE_TEMPLATE/internal-ticket.md index e687334..bb764f7 100644 --- a/.github/ISSUE_TEMPLATE/internal-ticket.md +++ b/.github/ISSUE_TEMPLATE/internal-ticket.md @@ -1,9 +1,9 @@ --- -name: Internal ticket about: For internal development -title: '' -labels: '' assignees: '' +labels: '' +name: Internal ticket +title: '' --- ## Problem diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index a6b2c07..ce5a11e 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -5,81 +5,82 @@ repos: ### Global hooks - - repo: https://gitlab.com/vojko.pribudic.foss/pre-commit-update +- repo: https://gitlab.com/vojko.pribudic.foss/pre-commit-update rev: v0.9.0 hooks: - - id: pre-commit-update # Autoupdate pre-commit hooks + - id: pre-commit-update # Autoupdate pre-commit hooks - - repo: https://github.com/gitleaks/gitleaks - rev: v8.29.0 +- repo: https://github.com/gitleaks/gitleaks + rev: v8.29.1 hooks: - - id: gitleaks + - id: gitleaks - - repo: https://github.com/executablebooks/mdformat +- repo: https://github.com/executablebooks/mdformat rev: 1.0.0 hooks: - - id: mdformat # Format Markdown files. + - id: mdformat # Format Markdown files. additional_dependencies: - - mdformat-gfm>=1.0.0 # Support GitHub Flavored Markdown. - - mdformat-ruff # Support Python code blocks linted with Ruff. + - mdformat-gfm>=1.0.0 # Support GitHub Flavored Markdown. + - mdformat-front-matters + - mdformat-ruff # Support Python code blocks linted with Ruff. - - repo: https://github.com/pre-commit/pre-commit-hooks +- repo: https://github.com/pre-commit/pre-commit-hooks rev: v6.0.0 hooks: - - id: check-added-large-files - - id: check-case-conflict # Check for files with names that differ only in case. - - id: check-executables-have-shebangs - - id: check-shebang-scripts-are-executable - - id: check-toml - - id: check-yaml + - id: check-added-large-files + - id: check-case-conflict # Check for files with names that differ only in case. + - id: check-executables-have-shebangs + - id: check-shebang-scripts-are-executable + - id: check-toml + - id: check-yaml exclude: ^docs/mkdocs.yml$ # Exclude mkdocs.yml because it uses an obscure tag to allow for mermaid formatting - - id: detect-private-key - - id: end-of-file-fixer # Ensure files end with a newline. - - id: mixed-line-ending - - id: no-commit-to-branch # Prevent commits to main and master branches. - - id: trailing-whitespace + - id: detect-private-key + - id: end-of-file-fixer # Ensure files end with a newline. + - id: mixed-line-ending + - id: no-commit-to-branch # Prevent commits to main and master branches. + - id: trailing-whitespace args: ["--markdown-linebreak-ext", "md"] # Preserve Markdown hard line breaks. - - repo: https://github.com/commitizen-tools/commitizen - rev: v4.9.1 +- repo: https://github.com/commitizen-tools/commitizen + rev: v4.10.0 hooks: - - id: commitizen + - id: commitizen stages: [commit-msg] - - repo: https://github.com/simonvanlierde/check-json5 +- repo: https://github.com/simonvanlierde/check-json5 rev: v1.1.0 hooks: - - id: check-json5 + - id: check-json5 files: ^ (?!(backend/frontend-app|frontend-web)/data/) ### Backend hooks - - repo: https://github.com/RobertCraigie/pyright-python # Lint backend code with Pyright. +- repo: https://github.com/RobertCraigie/pyright-python # Lint backend code with Pyright. rev: v1.1.407 hooks: - - id: pyright + - id: pyright files: ^backend/(app|scripts|tests)/ entry: pyright --project backend - - repo: https://github.com/astral-sh/ruff-pre-commit - rev: v0.14.4 +- repo: https://github.com/astral-sh/ruff-pre-commit + rev: v0.14.6 hooks: - - id: ruff-check # Lint code + - id: ruff-check # Lint code files: ^backend/(app|scripts|tests)/ args: ["--fix", "--config", "backend/pyproject.toml", "--ignore", "FIX002"] # Allow TODO comments in commits. - - id: ruff-format # Format code + - id: ruff-format # Format code files: ^backend/(app|scripts|tests)/ args: ["--config", "backend/pyproject.toml"] - - repo: https://github.com/astral-sh/uv-pre-commit - rev: 0.9.8 +- repo: https://github.com/astral-sh/uv-pre-commit + rev: 0.9.11 hooks: - - id: uv-lock # Update the uv lockfile for the backend. + - id: uv-lock # Update the uv lockfile for the backend. files: ^backend/(uv\.lock|pyproject\.toml|uv\.toml)$ entry: uv lock --project backend - - repo: local +- repo: local hooks: # Check if Alembic migrations are up-to-date. Uses uv to ensure the right environment when executed through VS Code Git extension. - - id: backend-alembic-autogen-check + - id: backend-alembic-autogen-check name: check alembic migrations entry: bash -c 'cd backend && uv run alembic-autogen-check' language: system @@ -88,21 +89,21 @@ repos: stages: [pre-commit] ### Frontend hooks - - repo: local +- repo: local hooks: - - id: frontend-web-format + - id: frontend-web-format name: format frontend-web code entry: bash -c 'cd frontend-web && npm run format' - language: - system + language: system # Match frontend JavaScript and TypeScript files for formatting. - files: ^frontend-web\/.*\.(jsx?|tsx?|c(js|ts)|m(js|ts)|d\\.(ts|cts|mts)|jsonc?)$ + files: + ^frontend-web\/.*\.(jsx?|tsx?|c(js|ts)|m(js|ts)|d\\.(ts|cts|mts)|jsonc?)$ pass_filenames: false - - id: frontend-app-format + - id: frontend-app-format name: format frontend-app code entry: bash -c 'cd frontend-app && npm run format' - language: - system + language: system # Match frontend JavaScript and TypeScript files for formatting. - files: ^frontend-app\/.*\.(jsx?|tsx?|c(js|ts)|m(js|ts)|d\\.(ts|cts|mts)|jsonc?)$ + files: + ^frontend-app\/.*\.(jsx?|tsx?|c(js|ts)|m(js|ts)|d\\.(ts|cts|mts)|jsonc?)$ pass_filenames: false diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index b7c8b97..b151b2d 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -345,23 +345,25 @@ When making changes to the database schema: This project uses [MJML](https://mjml.io/) to write email templates and [Jinja2](https://jinja.palletsprojects.com/en/latest/) for variable substitution at runtime. - **Location** + - Source MJML templates: `backend/app/templates/emails/src/` - Reusable components: `backend/app/templates/emails/src/components/` - Compiled HTML output: `backend/app/templates/emails/build/` (This directory is **auto-generated**—do not edit files here.) - **Editing Guidelines** + - Use **MJML** for structure and the `{{include:component_name}}` directive to reuse components. - Use **Jinja2-style variables** in templates, e.g., `{{ username }}`, `{{ verification_link }}`. - Keep components small and shared styles in `src/components/styles.mjml`. - **Do not modify** files in `build/`. - **Compiling Templates** - Run the compilation script from the repository root: + Run the compilation script from the repository root: - ```bash - cd backend - python scripts/compile_email_templates.py - ``` + ```bash + cd backend + python scripts/compile_email_templates.py + ``` - **Interactive Preview** For visual development, use MJML online tools or the [MJML VS Code extension](https://marketplace.visualstudio.com/items?itemName=mjmlio.vscode-mjml). diff --git a/backend/.dockerignore b/backend/.dockerignore index 2c42c71..08aa94a 100644 --- a/backend/.dockerignore +++ b/backend/.dockerignore @@ -98,4 +98,4 @@ MANIFEST ./logs # Include built email templates -!app/templates/emails/build/ \ No newline at end of file +!app/templates/emails/build/ diff --git a/backend/.gitignore b/backend/.gitignore index 966df64..fb372f9 100644 --- a/backend/.gitignore +++ b/backend/.gitignore @@ -82,4 +82,4 @@ backups/* !.vscode/extensions.json # Include built email templates -!app/templates/emails/build/ \ No newline at end of file +!app/templates/emails/build/ diff --git a/backend/app/api/auth/services/user_manager.py b/backend/app/api/auth/services/user_manager.py index f0ab70d..40eab49 100644 --- a/backend/app/api/auth/services/user_manager.py +++ b/backend/app/api/auth/services/user_manager.py @@ -64,7 +64,11 @@ async def create( email_checker = None else: # Get email checker from app state if request is available - email_checker = request.app.state.email_checker if (request and request.app and hasattr(request.app.state, "email_checker")) else None + email_checker = ( + request.app.state.email_checker + if (request and request.app and hasattr(request.app.state, "email_checker")) + else None + ) try: user_create = await create_user_override(self.user_db, user_create, email_checker) diff --git a/backend/app/api/auth/utils/email_validation.py b/backend/app/api/auth/utils/email_validation.py index 6d5275f..5e98026 100644 --- a/backend/app/api/auth/utils/email_validation.py +++ b/backend/app/api/auth/utils/email_validation.py @@ -42,7 +42,7 @@ async def initialize(self) -> None: source=DISPOSABLE_DOMAINS_URL, db_provider="redis", redis_client=self.redis_client, - ) + ) await self.checker.init_redis() logger.info("Disposable email checker initialized with Redis") diff --git a/backend/app/api/auth/utils/programmatic_emails.py b/backend/app/api/auth/utils/programmatic_emails.py index b5217f8..6c02f37 100644 --- a/backend/app/api/auth/utils/programmatic_emails.py +++ b/backend/app/api/auth/utils/programmatic_emails.py @@ -22,19 +22,20 @@ def generate_token_link(token: str, route: str, base_url: str | AnyUrl | None = base_url = str(core_settings.frontend_app_url) return urljoin(str(base_url), f"{route}?token={token}") + def mask_email_for_log(email: EmailStr, mask: bool = True, max_len: int = 80) -> str: """Mask emails for logging. - + Also remove non-printable characters and truncates long domains. Explicitly removes log-breaking control characters. """ # Remove non-printable and log-breaking control characters - string = "".join(ch for ch in str(email) if ch.isprintable()).replace('\n', '').replace('\r', '') + string = "".join(ch for ch in str(email) if ch.isprintable()).replace("\n", "").replace("\r", "") local, sep, domain = string.partition("@") if sep and mask: - masked = (f"{local[0]}***@{domain}" if len(local) > 1 else f"*@{domain}") + masked = f"{local[0]}***@{domain}" if len(local) > 1 else f"*@{domain}" else: masked = string - return (f"{masked[:max_len-3]}..." if len(masked) > max_len else masked) + return f"{masked[: max_len - 3]}..." if len(masked) > max_len else masked ### Generic email function ### @@ -63,7 +64,9 @@ async def send_email_with_template( if background_tasks: background_tasks.add_task(fm.send_message, message, template_name=template_name) - logger.info("Email queued for background sending to %s using template %s", mask_email_for_log(to_email), template_name) + logger.info( + "Email queued for background sending to %s using template %s", mask_email_for_log(to_email), template_name + ) else: await fm.send_message(message, template_name=template_name) logger.info("Email sent to %s using template %s", mask_email_for_log(to_email), template_name) diff --git a/backend/app/api/common/schemas/custom_fields.py b/backend/app/api/common/schemas/custom_fields.py index 5614bd2..7fd682e 100644 --- a/backend/app/api/common/schemas/custom_fields.py +++ b/backend/app/api/common/schemas/custom_fields.py @@ -5,9 +5,5 @@ from pydantic import AnyUrl, HttpUrl, PlainSerializer, StringConstraints # HTTP URL that is stored as string in the database. -HttpUrlToDB: TypeAlias = Annotated[ - HttpUrl, PlainSerializer(str, return_type=str), StringConstraints(max_length=250) -] -AnyUrlToDB: TypeAlias = Annotated[ - AnyUrl, PlainSerializer(str, return_type=str), StringConstraints(max_length=250) -] +HttpUrlToDB: TypeAlias = Annotated[HttpUrl, PlainSerializer(str, return_type=str), StringConstraints(max_length=250)] +AnyUrlToDB: TypeAlias = Annotated[AnyUrl, PlainSerializer(str, return_type=str), StringConstraints(max_length=250)] diff --git a/backend/app/api/data_collection/routers.py b/backend/app/api/data_collection/routers.py index 8fdc0f9..58b5e52 100644 --- a/backend/app/api/data_collection/routers.py +++ b/backend/app/api/data_collection/routers.py @@ -149,9 +149,9 @@ async def get_user_products( # NOTE: If needed, we can open up this endpoint to any user by removing this ownership check if user_id != current_user.id and not current_user.is_superuser: raise HTTPException(status_code=403, detail="Not authorized to view this user's products") - - statement=(select(Product).where(Product.owner_id == user_id)) - + + statement = select(Product).where(Product.owner_id == user_id) + if not include_components_as_base_products: statement: SelectOfScalar[Product] = statement.where(Product.parent_id == None) @@ -800,7 +800,9 @@ async def delete_product_physical_properties( response_model=CircularityPropertiesRead, summary="Get product circularity properties", ) -async def get_product_circularity_properties(product_id: PositiveInt, session: AsyncSessionDep) -> CircularityProperties: +async def get_product_circularity_properties( + product_id: PositiveInt, session: AsyncSessionDep +) -> CircularityProperties: """Get circularity properties for a product.""" return await crud.get_circularity_properties(session, product_id) diff --git a/backend/tests/conftest.py b/backend/tests/conftest.py index 5deafde..843680c 100644 --- a/backend/tests/conftest.py +++ b/backend/tests/conftest.py @@ -9,7 +9,6 @@ from unittest.mock import AsyncMock import pytest -from alembic.config import Config from fastapi.testclient import TestClient from sqlalchemy import Engine, create_engine, text from sqlalchemy.exc import ProgrammingError @@ -18,6 +17,7 @@ from sqlmodel.ext.asyncio.session import AsyncSession from alembic import command +from alembic.config import Config from app.core.config import settings from app.main import app diff --git a/compose.prod.yml b/compose.prod.yml index 866eb99..12e7dd7 100644 --- a/compose.prod.yml +++ b/compose.prod.yml @@ -35,8 +35,8 @@ services: volumes: # Persist cache data in production - cache_data:/data - cloudflared: # Cloudflared tunnel to cml-relab.org - image: cloudflare/cloudflared:latest@sha256:396cd2e6f021275ad09969a1b4f1a7e62ca5349fde62781ce082bb2c18105c70 + cloudflared: # Cloudflared tunnel service + image: cloudflare/cloudflared:latest@sha256:89ee50efb1e9cb2ae30281a8a404fed95eb8f02f0a972617526f8c5b417acae2 command: tunnel --no-autoupdate run env_file: .env # Should contain TUNNEL_TOKEN variable pull_policy: always diff --git a/frontend-app/src/app/products/[id]/index.tsx b/frontend-app/src/app/products/[id]/index.tsx index 201b7c1..3c59cce 100644 --- a/frontend-app/src/app/products/[id]/index.tsx +++ b/frontend-app/src/app/products/[id]/index.tsx @@ -260,11 +260,7 @@ export default function ProductPage(): JSX.Element { - + Edit name; -} \ No newline at end of file +} diff --git a/frontend-app/src/services/api/validation/product.ts b/frontend-app/src/services/api/validation/product.ts index 8639dda..b55c6b0 100644 --- a/frontend-app/src/services/api/validation/product.ts +++ b/frontend-app/src/services/api/validation/product.ts @@ -139,4 +139,4 @@ export function validateProduct(product: Product): ValidationResult { } return { isValid: true }; -} \ No newline at end of file +} diff --git a/uv.lock b/uv.lock index a14c571..22883f8 100644 --- a/uv.lock +++ b/uv.lock @@ -4,20 +4,20 @@ requires-python = ">=3.13" [[package]] name = "argcomplete" -version = "3.6.2" +version = "3.6.3" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/16/0f/861e168fc813c56a78b35f3c30d91c6757d1fd185af1110f1aec784b35d0/argcomplete-3.6.2.tar.gz", hash = "sha256:d0519b1bc867f5f4f4713c41ad0aba73a4a5f007449716b16f385f2166dc6adf", size = 73403, upload-time = "2025-04-03T04:57:03.52Z" } +sdist = { url = "https://files.pythonhosted.org/packages/38/61/0b9ae6399dd4a58d8c1b1dc5a27d6f2808023d0b5dd3104bb99f45a33ff6/argcomplete-3.6.3.tar.gz", hash = "sha256:62e8ed4fd6a45864acc8235409461b72c9a28ee785a2011cc5eb78318786c89c", size = 73754, upload-time = "2025-10-20T03:33:34.741Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/31/da/e42d7a9d8dd33fa775f467e4028a47936da2f01e4b0e561f9ba0d74cb0ca/argcomplete-3.6.2-py3-none-any.whl", hash = "sha256:65b3133a29ad53fb42c48cf5114752c7ab66c1c38544fdf6460f450c09b42591", size = 43708, upload-time = "2025-04-03T04:57:01.591Z" }, + { url = "https://files.pythonhosted.org/packages/74/f5/9373290775639cb67a2fce7f629a1c240dce9f12fe927bc32b2736e16dfc/argcomplete-3.6.3-py3-none-any.whl", hash = "sha256:f5007b3a600ccac5d25bbce33089211dfd49eab4a7718da3f10e3082525a92ce", size = 43846, upload-time = "2025-10-20T03:33:33.021Z" }, ] [[package]] name = "cfgv" -version = "3.4.0" +version = "3.5.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/11/74/539e56497d9bd1d484fd863dd69cbbfa653cd2aa27abfe35653494d85e94/cfgv-3.4.0.tar.gz", hash = "sha256:e52591d4c5f5dead8e0f673fb16db7949d2cfb3f7da4582893288f0ded8fe560", size = 7114, upload-time = "2023-08-12T20:38:17.776Z" } +sdist = { url = "https://files.pythonhosted.org/packages/4e/b5/721b8799b04bf9afe054a3899c6cf4e880fcf8563cc71c15610242490a0c/cfgv-3.5.0.tar.gz", hash = "sha256:d5b1034354820651caa73ede66a6294d6e95c1b00acc5e9b098e917404669132", size = 7334, upload-time = "2025-11-19T20:55:51.612Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/c5/55/51844dd50c4fc7a33b653bfaba4c2456f06955289ca770a5dbd5fd267374/cfgv-3.4.0-py2.py3-none-any.whl", hash = "sha256:b7265b1f29fd3316bfcd2b330d63d024f2bfd8bcb8b0272f8e19a504856c48f9", size = 7249, upload-time = "2023-08-12T20:38:16.269Z" }, + { url = "https://files.pythonhosted.org/packages/db/3c/33bac158f8ab7f89b2e59426d5fe2e4f63f7ed25df84c036890172b412b5/cfgv-3.5.0-py2.py3-none-any.whl", hash = "sha256:a8dc6b26ad22ff227d2634a65cb388215ce6cc96bbcc5cfde7641ae87e8dacc0", size = 7445, upload-time = "2025-11-19T20:55:50.744Z" }, ] [[package]] @@ -72,7 +72,7 @@ wheels = [ [[package]] name = "commitizen" -version = "4.9.1" +version = "4.10.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "argcomplete" }, @@ -88,9 +88,9 @@ dependencies = [ { name = "termcolor" }, { name = "tomlkit" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/77/19/927ac5b0eabb9451e2d5bb45b30813915c9a1260713b5b68eeb31358ea23/commitizen-4.9.1.tar.gz", hash = "sha256:b076b24657718f7a35b1068f2083bd39b4065d250164a1398d1dac235c51753b", size = 56610, upload-time = "2025-09-10T14:19:33.746Z" } +sdist = { url = "https://files.pythonhosted.org/packages/ab/b3/cc29794fc2ecd7aa7353105773ca18ecd761c3ba5b38879bd106b3fc8840/commitizen-4.10.0.tar.gz", hash = "sha256:cc58067403b9eff21d0423b3d9a29bda05254bd51ad5bdd1fd0594bff31277e1", size = 56820, upload-time = "2025-11-10T14:08:49.365Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/cf/49/577035b841442fe031b017027c3d99278b46104d227f0353c69dbbe55148/commitizen-4.9.1-py3-none-any.whl", hash = "sha256:4241b2ecae97b8109af8e587c36bc3b805a09b9a311084d159098e12d6ead497", size = 80624, upload-time = "2025-09-10T14:19:32.102Z" }, + { url = "https://files.pythonhosted.org/packages/b3/5d/2bd8881737d6a5652ae3ebc37736893b9a7425f0eb16e605d1ff2957267e/commitizen-4.10.0-py3-none-any.whl", hash = "sha256:3fe56c168b30b30b84b8329cba6b132e77b4eb304a5460bbe2186aad0f78c966", size = 81269, upload-time = "2025-11-10T14:08:48.001Z" }, ] [[package]] @@ -104,14 +104,14 @@ wheels = [ [[package]] name = "deprecated" -version = "1.2.18" +version = "1.3.1" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "wrapt" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/98/97/06afe62762c9a8a86af0cfb7bfdab22a43ad17138b07af5b1a58442690a2/deprecated-1.2.18.tar.gz", hash = "sha256:422b6f6d859da6f2ef57857761bfb392480502a64c3028ca9bbe86085d72115d", size = 2928744, upload-time = "2025-01-27T10:46:25.7Z" } +sdist = { url = "https://files.pythonhosted.org/packages/49/85/12f0a49a7c4ffb70572b6c2ef13c90c88fd190debda93b23f026b25f9634/deprecated-1.3.1.tar.gz", hash = "sha256:b1b50e0ff0c1fddaa5708a2c6b0a6588bb09b892825ab2b214ac9ea9d92a5223", size = 2932523, upload-time = "2025-10-30T08:19:02.757Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/6e/c6/ac0b6c1e2d138f1002bcf799d330bd6d85084fece321e662a14223794041/Deprecated-1.2.18-py2.py3-none-any.whl", hash = "sha256:bd5011788200372a32418f888e326a09ff80d0214bd961147cfed01b5c018eec", size = 9998, upload-time = "2025-01-27T10:46:09.186Z" }, + { url = "https://files.pythonhosted.org/packages/84/d0/205d54408c08b13550c733c4b85429e7ead111c7f0014309637425520a9a/deprecated-1.3.1-py2.py3-none-any.whl", hash = "sha256:597bfef186b6f60181535a29fbe44865ce137a5079f295b479886c82729d5f3f", size = 11298, upload-time = "2025-10-30T08:19:00.758Z" }, ] [[package]] @@ -234,7 +234,7 @@ wheels = [ [[package]] name = "pre-commit" -version = "4.3.0" +version = "4.5.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "cfgv" }, @@ -243,9 +243,9 @@ dependencies = [ { name = "pyyaml" }, { name = "virtualenv" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/ff/29/7cf5bbc236333876e4b41f56e06857a87937ce4bf91e117a6991a2dbb02a/pre_commit-4.3.0.tar.gz", hash = "sha256:499fe450cc9d42e9d58e606262795ecb64dd05438943c62b66f6a8673da30b16", size = 193792, upload-time = "2025-08-09T18:56:14.651Z" } +sdist = { url = "https://files.pythonhosted.org/packages/f4/9b/6a4ffb4ed980519da959e1cf3122fc6cb41211daa58dbae1c73c0e519a37/pre_commit-4.5.0.tar.gz", hash = "sha256:dc5a065e932b19fc1d4c653c6939068fe54325af8e741e74e88db4d28a4dd66b", size = 198428, upload-time = "2025-11-22T21:02:42.304Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/5b/a5/987a405322d78a73b66e39e4a90e4ef156fd7141bf71df987e50717c321b/pre_commit-4.3.0-py2.py3-none-any.whl", hash = "sha256:2b0747ad7e6e967169136edffee14c16e148a778a54e4f967921aa1ebf2308d8", size = 220965, upload-time = "2025-08-09T18:56:13.192Z" }, + { url = "https://files.pythonhosted.org/packages/5d/c4/b2d28e9d2edf4f1713eb3c29307f1a63f3d67cf09bdda29715a36a68921a/pre_commit-4.5.0-py2.py3-none-any.whl", hash = "sha256:25e2ce09595174d9c97860a95609f9f852c0614ba602de3561e267547f2335e1", size = 226429, upload-time = "2025-11-22T21:02:40.836Z" }, ] [[package]] @@ -329,11 +329,11 @@ dev = [ [[package]] name = "termcolor" -version = "3.1.0" +version = "3.2.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/ca/6c/3d75c196ac07ac8749600b60b03f4f6094d54e132c4d94ebac6ee0e0add0/termcolor-3.1.0.tar.gz", hash = "sha256:6a6dd7fbee581909eeec6a756cff1d7f7c376063b14e4a298dc4980309e55970", size = 14324, upload-time = "2025-04-30T11:37:53.791Z" } +sdist = { url = "https://files.pythonhosted.org/packages/87/56/ab275c2b56a5e2342568838f0d5e3e66a32354adcc159b495e374cda43f5/termcolor-3.2.0.tar.gz", hash = "sha256:610e6456feec42c4bcd28934a8c87a06c3fa28b01561d46aa09a9881b8622c58", size = 14423, upload-time = "2025-10-25T19:11:42.586Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/4f/bd/de8d508070629b6d84a30d01d57e4a65c69aa7f5abe7560b8fad3b50ea59/termcolor-3.1.0-py3-none-any.whl", hash = "sha256:591dd26b5c2ce03b9e43f391264626557873ce1d379019786f99b0c2bee140aa", size = 7684, upload-time = "2025-04-30T11:37:52.382Z" }, + { url = "https://files.pythonhosted.org/packages/f9/d5/141f53d7c1eb2a80e6d3e9a390228c3222c27705cbe7f048d3623053f3ca/termcolor-3.2.0-py3-none-any.whl", hash = "sha256:a10343879eba4da819353c55cb8049b0933890c2ebf9ad5d3ecd2bb32ea96ea6", size = 7698, upload-time = "2025-10-25T19:11:41.536Z" }, ] [[package]] @@ -347,16 +347,16 @@ wheels = [ [[package]] name = "virtualenv" -version = "20.35.3" +version = "20.35.4" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "distlib" }, { name = "filelock" }, { name = "platformdirs" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/a4/d5/b0ccd381d55c8f45d46f77df6ae59fbc23d19e901e2d523395598e5f4c93/virtualenv-20.35.3.tar.gz", hash = "sha256:4f1a845d131133bdff10590489610c98c168ff99dc75d6c96853801f7f67af44", size = 6002907, upload-time = "2025-10-10T21:23:33.178Z" } +sdist = { url = "https://files.pythonhosted.org/packages/20/28/e6f1a6f655d620846bd9df527390ecc26b3805a0c5989048c210e22c5ca9/virtualenv-20.35.4.tar.gz", hash = "sha256:643d3914d73d3eeb0c552cbb12d7e82adf0e504dbf86a3182f8771a153a1971c", size = 6028799, upload-time = "2025-10-29T06:57:40.511Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/27/73/d9a94da0e9d470a543c1b9d3ccbceb0f59455983088e727b8a1824ed90fb/virtualenv-20.35.3-py3-none-any.whl", hash = "sha256:63d106565078d8c8d0b206d48080f938a8b25361e19432d2c9db40d2899c810a", size = 5981061, upload-time = "2025-10-10T21:23:30.433Z" }, + { url = "https://files.pythonhosted.org/packages/79/0c/c05523fa3181fdf0c9c52a6ba91a23fbf3246cc095f26f6516f9c60e6771/virtualenv-20.35.4-py3-none-any.whl", hash = "sha256:c21c9cede36c9753eeade68ba7d523529f228a403463376cf821eaae2b650f1b", size = 6005095, upload-time = "2025-10-29T06:57:37.598Z" }, ] [[package]] @@ -370,39 +370,57 @@ wheels = [ [[package]] name = "wrapt" -version = "1.17.3" +version = "2.0.1" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/95/8f/aeb76c5b46e273670962298c23e7ddde79916cb74db802131d49a85e4b7d/wrapt-1.17.3.tar.gz", hash = "sha256:f66eb08feaa410fe4eebd17f2a2c8e2e46d3476e9f8c783daa8e09e0faa666d0", size = 55547, upload-time = "2025-08-12T05:53:21.714Z" } +sdist = { url = "https://files.pythonhosted.org/packages/49/2a/6de8a50cb435b7f42c46126cf1a54b2aab81784e74c8595c8e025e8f36d3/wrapt-2.0.1.tar.gz", hash = "sha256:9c9c635e78497cacb81e84f8b11b23e0aacac7a136e73b8e5b2109a1d9fc468f", size = 82040, upload-time = "2025-11-07T00:45:33.312Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/fc/f6/759ece88472157acb55fc195e5b116e06730f1b651b5b314c66291729193/wrapt-1.17.3-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:a47681378a0439215912ef542c45a783484d4dd82bac412b71e59cf9c0e1cea0", size = 54003, upload-time = "2025-08-12T05:51:48.627Z" }, - { url = "https://files.pythonhosted.org/packages/4f/a9/49940b9dc6d47027dc850c116d79b4155f15c08547d04db0f07121499347/wrapt-1.17.3-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:54a30837587c6ee3cd1a4d1c2ec5d24e77984d44e2f34547e2323ddb4e22eb77", size = 39025, upload-time = "2025-08-12T05:51:37.156Z" }, - { url = "https://files.pythonhosted.org/packages/45/35/6a08de0f2c96dcdd7fe464d7420ddb9a7655a6561150e5fc4da9356aeaab/wrapt-1.17.3-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:16ecf15d6af39246fe33e507105d67e4b81d8f8d2c6598ff7e3ca1b8a37213f7", size = 39108, upload-time = "2025-08-12T05:51:58.425Z" }, - { url = "https://files.pythonhosted.org/packages/0c/37/6faf15cfa41bf1f3dba80cd3f5ccc6622dfccb660ab26ed79f0178c7497f/wrapt-1.17.3-cp313-cp313-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:6fd1ad24dc235e4ab88cda009e19bf347aabb975e44fd5c2fb22a3f6e4141277", size = 88072, upload-time = "2025-08-12T05:52:37.53Z" }, - { url = "https://files.pythonhosted.org/packages/78/f2/efe19ada4a38e4e15b6dff39c3e3f3f73f5decf901f66e6f72fe79623a06/wrapt-1.17.3-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:0ed61b7c2d49cee3c027372df5809a59d60cf1b6c2f81ee980a091f3afed6a2d", size = 88214, upload-time = "2025-08-12T05:52:15.886Z" }, - { url = "https://files.pythonhosted.org/packages/40/90/ca86701e9de1622b16e09689fc24b76f69b06bb0150990f6f4e8b0eeb576/wrapt-1.17.3-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:423ed5420ad5f5529db9ce89eac09c8a2f97da18eb1c870237e84c5a5c2d60aa", size = 87105, upload-time = "2025-08-12T05:52:17.914Z" }, - { url = "https://files.pythonhosted.org/packages/fd/e0/d10bd257c9a3e15cbf5523025252cc14d77468e8ed644aafb2d6f54cb95d/wrapt-1.17.3-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:e01375f275f010fcbf7f643b4279896d04e571889b8a5b3f848423d91bf07050", size = 87766, upload-time = "2025-08-12T05:52:39.243Z" }, - { url = "https://files.pythonhosted.org/packages/e8/cf/7d848740203c7b4b27eb55dbfede11aca974a51c3d894f6cc4b865f42f58/wrapt-1.17.3-cp313-cp313-win32.whl", hash = "sha256:53e5e39ff71b3fc484df8a522c933ea2b7cdd0d5d15ae82e5b23fde87d44cbd8", size = 36711, upload-time = "2025-08-12T05:53:10.074Z" }, - { url = "https://files.pythonhosted.org/packages/57/54/35a84d0a4d23ea675994104e667ceff49227ce473ba6a59ba2c84f250b74/wrapt-1.17.3-cp313-cp313-win_amd64.whl", hash = "sha256:1f0b2f40cf341ee8cc1a97d51ff50dddb9fcc73241b9143ec74b30fc4f44f6cb", size = 38885, upload-time = "2025-08-12T05:53:08.695Z" }, - { url = "https://files.pythonhosted.org/packages/01/77/66e54407c59d7b02a3c4e0af3783168fff8e5d61def52cda8728439d86bc/wrapt-1.17.3-cp313-cp313-win_arm64.whl", hash = "sha256:7425ac3c54430f5fc5e7b6f41d41e704db073309acfc09305816bc6a0b26bb16", size = 36896, upload-time = "2025-08-12T05:52:55.34Z" }, - { url = "https://files.pythonhosted.org/packages/02/a2/cd864b2a14f20d14f4c496fab97802001560f9f41554eef6df201cd7f76c/wrapt-1.17.3-cp314-cp314-macosx_10_13_universal2.whl", hash = "sha256:cf30f6e3c077c8e6a9a7809c94551203c8843e74ba0c960f4a98cd80d4665d39", size = 54132, upload-time = "2025-08-12T05:51:49.864Z" }, - { url = "https://files.pythonhosted.org/packages/d5/46/d011725b0c89e853dc44cceb738a307cde5d240d023d6d40a82d1b4e1182/wrapt-1.17.3-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:e228514a06843cae89621384cfe3a80418f3c04aadf8a3b14e46a7be704e4235", size = 39091, upload-time = "2025-08-12T05:51:38.935Z" }, - { url = "https://files.pythonhosted.org/packages/2e/9e/3ad852d77c35aae7ddebdbc3b6d35ec8013af7d7dddad0ad911f3d891dae/wrapt-1.17.3-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:5ea5eb3c0c071862997d6f3e02af1d055f381b1d25b286b9d6644b79db77657c", size = 39172, upload-time = "2025-08-12T05:51:59.365Z" }, - { url = "https://files.pythonhosted.org/packages/c3/f7/c983d2762bcce2326c317c26a6a1e7016f7eb039c27cdf5c4e30f4160f31/wrapt-1.17.3-cp314-cp314-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:281262213373b6d5e4bb4353bc36d1ba4084e6d6b5d242863721ef2bf2c2930b", size = 87163, upload-time = "2025-08-12T05:52:40.965Z" }, - { url = "https://files.pythonhosted.org/packages/e4/0f/f673f75d489c7f22d17fe0193e84b41540d962f75fce579cf6873167c29b/wrapt-1.17.3-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:dc4a8d2b25efb6681ecacad42fca8859f88092d8732b170de6a5dddd80a1c8fa", size = 87963, upload-time = "2025-08-12T05:52:20.326Z" }, - { url = "https://files.pythonhosted.org/packages/df/61/515ad6caca68995da2fac7a6af97faab8f78ebe3bf4f761e1b77efbc47b5/wrapt-1.17.3-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:373342dd05b1d07d752cecbec0c41817231f29f3a89aa8b8843f7b95992ed0c7", size = 86945, upload-time = "2025-08-12T05:52:21.581Z" }, - { url = "https://files.pythonhosted.org/packages/d3/bd/4e70162ce398462a467bc09e768bee112f1412e563620adc353de9055d33/wrapt-1.17.3-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:d40770d7c0fd5cbed9d84b2c3f2e156431a12c9a37dc6284060fb4bec0b7ffd4", size = 86857, upload-time = "2025-08-12T05:52:43.043Z" }, - { url = "https://files.pythonhosted.org/packages/2b/b8/da8560695e9284810b8d3df8a19396a6e40e7518059584a1a394a2b35e0a/wrapt-1.17.3-cp314-cp314-win32.whl", hash = "sha256:fbd3c8319de8e1dc79d346929cd71d523622da527cca14e0c1d257e31c2b8b10", size = 37178, upload-time = "2025-08-12T05:53:12.605Z" }, - { url = "https://files.pythonhosted.org/packages/db/c8/b71eeb192c440d67a5a0449aaee2310a1a1e8eca41676046f99ed2487e9f/wrapt-1.17.3-cp314-cp314-win_amd64.whl", hash = "sha256:e1a4120ae5705f673727d3253de3ed0e016f7cd78dc463db1b31e2463e1f3cf6", size = 39310, upload-time = "2025-08-12T05:53:11.106Z" }, - { url = "https://files.pythonhosted.org/packages/45/20/2cda20fd4865fa40f86f6c46ed37a2a8356a7a2fde0773269311f2af56c7/wrapt-1.17.3-cp314-cp314-win_arm64.whl", hash = "sha256:507553480670cab08a800b9463bdb881b2edeed77dc677b0a5915e6106e91a58", size = 37266, upload-time = "2025-08-12T05:52:56.531Z" }, - { url = "https://files.pythonhosted.org/packages/77/ed/dd5cf21aec36c80443c6f900449260b80e2a65cf963668eaef3b9accce36/wrapt-1.17.3-cp314-cp314t-macosx_10_13_universal2.whl", hash = "sha256:ed7c635ae45cfbc1a7371f708727bf74690daedc49b4dba310590ca0bd28aa8a", size = 56544, upload-time = "2025-08-12T05:51:51.109Z" }, - { url = "https://files.pythonhosted.org/packages/8d/96/450c651cc753877ad100c7949ab4d2e2ecc4d97157e00fa8f45df682456a/wrapt-1.17.3-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:249f88ed15503f6492a71f01442abddd73856a0032ae860de6d75ca62eed8067", size = 40283, upload-time = "2025-08-12T05:51:39.912Z" }, - { url = "https://files.pythonhosted.org/packages/d1/86/2fcad95994d9b572db57632acb6f900695a648c3e063f2cd344b3f5c5a37/wrapt-1.17.3-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:5a03a38adec8066d5a37bea22f2ba6bbf39fcdefbe2d91419ab864c3fb515454", size = 40366, upload-time = "2025-08-12T05:52:00.693Z" }, - { url = "https://files.pythonhosted.org/packages/64/0e/f4472f2fdde2d4617975144311f8800ef73677a159be7fe61fa50997d6c0/wrapt-1.17.3-cp314-cp314t-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:5d4478d72eb61c36e5b446e375bbc49ed002430d17cdec3cecb36993398e1a9e", size = 108571, upload-time = "2025-08-12T05:52:44.521Z" }, - { url = "https://files.pythonhosted.org/packages/cc/01/9b85a99996b0a97c8a17484684f206cbb6ba73c1ce6890ac668bcf3838fb/wrapt-1.17.3-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:223db574bb38637e8230eb14b185565023ab624474df94d2af18f1cdb625216f", size = 113094, upload-time = "2025-08-12T05:52:22.618Z" }, - { url = "https://files.pythonhosted.org/packages/25/02/78926c1efddcc7b3aa0bc3d6b33a822f7d898059f7cd9ace8c8318e559ef/wrapt-1.17.3-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:e405adefb53a435f01efa7ccdec012c016b5a1d3f35459990afc39b6be4d5056", size = 110659, upload-time = "2025-08-12T05:52:24.057Z" }, - { url = "https://files.pythonhosted.org/packages/dc/ee/c414501ad518ac3e6fe184753632fe5e5ecacdcf0effc23f31c1e4f7bfcf/wrapt-1.17.3-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:88547535b787a6c9ce4086917b6e1d291aa8ed914fdd3a838b3539dc95c12804", size = 106946, upload-time = "2025-08-12T05:52:45.976Z" }, - { url = "https://files.pythonhosted.org/packages/be/44/a1bd64b723d13bb151d6cc91b986146a1952385e0392a78567e12149c7b4/wrapt-1.17.3-cp314-cp314t-win32.whl", hash = "sha256:41b1d2bc74c2cac6f9074df52b2efbef2b30bdfe5f40cb78f8ca22963bc62977", size = 38717, upload-time = "2025-08-12T05:53:15.214Z" }, - { url = "https://files.pythonhosted.org/packages/79/d9/7cfd5a312760ac4dd8bf0184a6ee9e43c33e47f3dadc303032ce012b8fa3/wrapt-1.17.3-cp314-cp314t-win_amd64.whl", hash = "sha256:73d496de46cd2cdbdbcce4ae4bcdb4afb6a11234a1df9c085249d55166b95116", size = 41334, upload-time = "2025-08-12T05:53:14.178Z" }, - { url = "https://files.pythonhosted.org/packages/46/78/10ad9781128ed2f99dbc474f43283b13fea8ba58723e98844367531c18e9/wrapt-1.17.3-cp314-cp314t-win_arm64.whl", hash = "sha256:f38e60678850c42461d4202739f9bf1e3a737c7ad283638251e79cc49effb6b6", size = 38471, upload-time = "2025-08-12T05:52:57.784Z" }, - { url = "https://files.pythonhosted.org/packages/1f/f6/a933bd70f98e9cf3e08167fc5cd7aaaca49147e48411c0bd5ae701bb2194/wrapt-1.17.3-py3-none-any.whl", hash = "sha256:7171ae35d2c33d326ac19dd8facb1e82e5fd04ef8c6c0e394d7af55a55051c22", size = 23591, upload-time = "2025-08-12T05:53:20.674Z" }, + { url = "https://files.pythonhosted.org/packages/ad/fe/41af4c46b5e498c90fc87981ab2972fbd9f0bccda597adb99d3d3441b94b/wrapt-2.0.1-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:47b0f8bafe90f7736151f61482c583c86b0693d80f075a58701dd1549b0010a9", size = 78132, upload-time = "2025-11-07T00:44:04.628Z" }, + { url = "https://files.pythonhosted.org/packages/1c/92/d68895a984a5ebbbfb175512b0c0aad872354a4a2484fbd5552e9f275316/wrapt-2.0.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:cbeb0971e13b4bd81d34169ed57a6dda017328d1a22b62fda45e1d21dd06148f", size = 61211, upload-time = "2025-11-07T00:44:05.626Z" }, + { url = "https://files.pythonhosted.org/packages/e8/26/ba83dc5ae7cf5aa2b02364a3d9cf74374b86169906a1f3ade9a2d03cf21c/wrapt-2.0.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:eb7cffe572ad0a141a7886a1d2efa5bef0bf7fe021deeea76b3ab334d2c38218", size = 61689, upload-time = "2025-11-07T00:44:06.719Z" }, + { url = "https://files.pythonhosted.org/packages/cf/67/d7a7c276d874e5d26738c22444d466a3a64ed541f6ef35f740dbd865bab4/wrapt-2.0.1-cp313-cp313-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:c8d60527d1ecfc131426b10d93ab5d53e08a09c5fa0175f6b21b3252080c70a9", size = 121502, upload-time = "2025-11-07T00:44:09.557Z" }, + { url = "https://files.pythonhosted.org/packages/0f/6b/806dbf6dd9579556aab22fc92908a876636e250f063f71548a8660382184/wrapt-2.0.1-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:c654eafb01afac55246053d67a4b9a984a3567c3808bb7df2f8de1c1caba2e1c", size = 123110, upload-time = "2025-11-07T00:44:10.64Z" }, + { url = "https://files.pythonhosted.org/packages/e5/08/cdbb965fbe4c02c5233d185d070cabed2ecc1f1e47662854f95d77613f57/wrapt-2.0.1-cp313-cp313-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:98d873ed6c8b4ee2418f7afce666751854d6d03e3c0ec2a399bb039cd2ae89db", size = 117434, upload-time = "2025-11-07T00:44:08.138Z" }, + { url = "https://files.pythonhosted.org/packages/2d/d1/6aae2ce39db4cb5216302fa2e9577ad74424dfbe315bd6669725569e048c/wrapt-2.0.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:c9e850f5b7fc67af856ff054c71690d54fa940c3ef74209ad9f935b4f66a0233", size = 121533, upload-time = "2025-11-07T00:44:12.142Z" }, + { url = "https://files.pythonhosted.org/packages/79/35/565abf57559fbe0a9155c29879ff43ce8bd28d2ca61033a3a3dd67b70794/wrapt-2.0.1-cp313-cp313-musllinux_1_2_riscv64.whl", hash = "sha256:e505629359cb5f751e16e30cf3f91a1d3ddb4552480c205947da415d597f7ac2", size = 116324, upload-time = "2025-11-07T00:44:13.28Z" }, + { url = "https://files.pythonhosted.org/packages/e1/e0/53ff5e76587822ee33e560ad55876d858e384158272cd9947abdd4ad42ca/wrapt-2.0.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:2879af909312d0baf35f08edeea918ee3af7ab57c37fe47cb6a373c9f2749c7b", size = 120627, upload-time = "2025-11-07T00:44:14.431Z" }, + { url = "https://files.pythonhosted.org/packages/7c/7b/38df30fd629fbd7612c407643c63e80e1c60bcc982e30ceeae163a9800e7/wrapt-2.0.1-cp313-cp313-win32.whl", hash = "sha256:d67956c676be5a24102c7407a71f4126d30de2a569a1c7871c9f3cabc94225d7", size = 58252, upload-time = "2025-11-07T00:44:17.814Z" }, + { url = "https://files.pythonhosted.org/packages/85/64/d3954e836ea67c4d3ad5285e5c8fd9d362fd0a189a2db622df457b0f4f6a/wrapt-2.0.1-cp313-cp313-win_amd64.whl", hash = "sha256:9ca66b38dd642bf90c59b6738af8070747b610115a39af2498535f62b5cdc1c3", size = 60500, upload-time = "2025-11-07T00:44:15.561Z" }, + { url = "https://files.pythonhosted.org/packages/89/4e/3c8b99ac93527cfab7f116089db120fef16aac96e5f6cdb724ddf286086d/wrapt-2.0.1-cp313-cp313-win_arm64.whl", hash = "sha256:5a4939eae35db6b6cec8e7aa0e833dcca0acad8231672c26c2a9ab7a0f8ac9c8", size = 58993, upload-time = "2025-11-07T00:44:16.65Z" }, + { url = "https://files.pythonhosted.org/packages/f9/f4/eff2b7d711cae20d220780b9300faa05558660afb93f2ff5db61fe725b9a/wrapt-2.0.1-cp313-cp313t-macosx_10_13_universal2.whl", hash = "sha256:a52f93d95c8d38fed0669da2ebdb0b0376e895d84596a976c15a9eb45e3eccb3", size = 82028, upload-time = "2025-11-07T00:44:18.944Z" }, + { url = "https://files.pythonhosted.org/packages/0c/67/cb945563f66fd0f61a999339460d950f4735c69f18f0a87ca586319b1778/wrapt-2.0.1-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:4e54bbf554ee29fcceee24fa41c4d091398b911da6e7f5d7bffda963c9aed2e1", size = 62949, upload-time = "2025-11-07T00:44:20.074Z" }, + { url = "https://files.pythonhosted.org/packages/ec/ca/f63e177f0bbe1e5cf5e8d9b74a286537cd709724384ff20860f8f6065904/wrapt-2.0.1-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:908f8c6c71557f4deaa280f55d0728c3bca0960e8c3dd5ceeeafb3c19942719d", size = 63681, upload-time = "2025-11-07T00:44:21.345Z" }, + { url = "https://files.pythonhosted.org/packages/39/a1/1b88fcd21fd835dca48b556daef750952e917a2794fa20c025489e2e1f0f/wrapt-2.0.1-cp313-cp313t-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:e2f84e9af2060e3904a32cea9bb6db23ce3f91cfd90c6b426757cf7cc01c45c7", size = 152696, upload-time = "2025-11-07T00:44:24.318Z" }, + { url = "https://files.pythonhosted.org/packages/62/1c/d9185500c1960d9f5f77b9c0b890b7fc62282b53af7ad1b6bd779157f714/wrapt-2.0.1-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:e3612dc06b436968dfb9142c62e5dfa9eb5924f91120b3c8ff501ad878f90eb3", size = 158859, upload-time = "2025-11-07T00:44:25.494Z" }, + { url = "https://files.pythonhosted.org/packages/91/60/5d796ed0f481ec003220c7878a1d6894652efe089853a208ea0838c13086/wrapt-2.0.1-cp313-cp313t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:6d2d947d266d99a1477cd005b23cbd09465276e302515e122df56bb9511aca1b", size = 146068, upload-time = "2025-11-07T00:44:22.81Z" }, + { url = "https://files.pythonhosted.org/packages/04/f8/75282dd72f102ddbfba137e1e15ecba47b40acff32c08ae97edbf53f469e/wrapt-2.0.1-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:7d539241e87b650cbc4c3ac9f32c8d1ac8a54e510f6dca3f6ab60dcfd48c9b10", size = 155724, upload-time = "2025-11-07T00:44:26.634Z" }, + { url = "https://files.pythonhosted.org/packages/5a/27/fe39c51d1b344caebb4a6a9372157bdb8d25b194b3561b52c8ffc40ac7d1/wrapt-2.0.1-cp313-cp313t-musllinux_1_2_riscv64.whl", hash = "sha256:4811e15d88ee62dbf5c77f2c3ff3932b1e3ac92323ba3912f51fc4016ce81ecf", size = 144413, upload-time = "2025-11-07T00:44:27.939Z" }, + { url = "https://files.pythonhosted.org/packages/83/2b/9f6b643fe39d4505c7bf926d7c2595b7cb4b607c8c6b500e56c6b36ac238/wrapt-2.0.1-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:c1c91405fcf1d501fa5d55df21e58ea49e6b879ae829f1039faaf7e5e509b41e", size = 150325, upload-time = "2025-11-07T00:44:29.29Z" }, + { url = "https://files.pythonhosted.org/packages/bb/b6/20ffcf2558596a7f58a2e69c89597128781f0b88e124bf5a4cadc05b8139/wrapt-2.0.1-cp313-cp313t-win32.whl", hash = "sha256:e76e3f91f864e89db8b8d2a8311d57df93f01ad6bb1e9b9976d1f2e83e18315c", size = 59943, upload-time = "2025-11-07T00:44:33.211Z" }, + { url = "https://files.pythonhosted.org/packages/87/6a/0e56111cbb3320151eed5d3821ee1373be13e05b376ea0870711f18810c3/wrapt-2.0.1-cp313-cp313t-win_amd64.whl", hash = "sha256:83ce30937f0ba0d28818807b303a412440c4b63e39d3d8fc036a94764b728c92", size = 63240, upload-time = "2025-11-07T00:44:30.935Z" }, + { url = "https://files.pythonhosted.org/packages/1d/54/5ab4c53ea1f7f7e5c3e7c1095db92932cc32fd62359d285486d00c2884c3/wrapt-2.0.1-cp313-cp313t-win_arm64.whl", hash = "sha256:4b55cacc57e1dc2d0991dbe74c6419ffd415fb66474a02335cb10efd1aa3f84f", size = 60416, upload-time = "2025-11-07T00:44:32.002Z" }, + { url = "https://files.pythonhosted.org/packages/73/81/d08d83c102709258e7730d3cd25befd114c60e43ef3891d7e6877971c514/wrapt-2.0.1-cp314-cp314-macosx_10_13_universal2.whl", hash = "sha256:5e53b428f65ece6d9dad23cb87e64506392b720a0b45076c05354d27a13351a1", size = 78290, upload-time = "2025-11-07T00:44:34.691Z" }, + { url = "https://files.pythonhosted.org/packages/f6/14/393afba2abb65677f313aa680ff0981e829626fed39b6a7e3ec807487790/wrapt-2.0.1-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:ad3ee9d0f254851c71780966eb417ef8e72117155cff04821ab9b60549694a55", size = 61255, upload-time = "2025-11-07T00:44:35.762Z" }, + { url = "https://files.pythonhosted.org/packages/c4/10/a4a1f2fba205a9462e36e708ba37e5ac95f4987a0f1f8fd23f0bf1fc3b0f/wrapt-2.0.1-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:d7b822c61ed04ee6ad64bc90d13368ad6eb094db54883b5dde2182f67a7f22c0", size = 61797, upload-time = "2025-11-07T00:44:37.22Z" }, + { url = "https://files.pythonhosted.org/packages/12/db/99ba5c37cf1c4fad35349174f1e38bd8d992340afc1ff27f526729b98986/wrapt-2.0.1-cp314-cp314-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:7164a55f5e83a9a0b031d3ffab4d4e36bbec42e7025db560f225489fa929e509", size = 120470, upload-time = "2025-11-07T00:44:39.425Z" }, + { url = "https://files.pythonhosted.org/packages/30/3f/a1c8d2411eb826d695fc3395a431757331582907a0ec59afce8fe8712473/wrapt-2.0.1-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:e60690ba71a57424c8d9ff28f8d006b7ad7772c22a4af432188572cd7fa004a1", size = 122851, upload-time = "2025-11-07T00:44:40.582Z" }, + { url = "https://files.pythonhosted.org/packages/b3/8d/72c74a63f201768d6a04a8845c7976f86be6f5ff4d74996c272cefc8dafc/wrapt-2.0.1-cp314-cp314-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:3cd1a4bd9a7a619922a8557e1318232e7269b5fb69d4ba97b04d20450a6bf970", size = 117433, upload-time = "2025-11-07T00:44:38.313Z" }, + { url = "https://files.pythonhosted.org/packages/c7/5a/df37cf4042cb13b08256f8e27023e2f9b3d471d553376616591bb99bcb31/wrapt-2.0.1-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:b4c2e3d777e38e913b8ce3a6257af72fb608f86a1df471cb1d4339755d0a807c", size = 121280, upload-time = "2025-11-07T00:44:41.69Z" }, + { url = "https://files.pythonhosted.org/packages/54/34/40d6bc89349f9931e1186ceb3e5fbd61d307fef814f09fbbac98ada6a0c8/wrapt-2.0.1-cp314-cp314-musllinux_1_2_riscv64.whl", hash = "sha256:3d366aa598d69416b5afedf1faa539fac40c1d80a42f6b236c88c73a3c8f2d41", size = 116343, upload-time = "2025-11-07T00:44:43.013Z" }, + { url = "https://files.pythonhosted.org/packages/70/66/81c3461adece09d20781dee17c2366fdf0cb8754738b521d221ca056d596/wrapt-2.0.1-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:c235095d6d090aa903f1db61f892fffb779c1eaeb2a50e566b52001f7a0f66ed", size = 119650, upload-time = "2025-11-07T00:44:44.523Z" }, + { url = "https://files.pythonhosted.org/packages/46/3a/d0146db8be8761a9e388cc9cc1c312b36d583950ec91696f19bbbb44af5a/wrapt-2.0.1-cp314-cp314-win32.whl", hash = "sha256:bfb5539005259f8127ea9c885bdc231978c06b7a980e63a8a61c8c4c979719d0", size = 58701, upload-time = "2025-11-07T00:44:48.277Z" }, + { url = "https://files.pythonhosted.org/packages/1a/38/5359da9af7d64554be63e9046164bd4d8ff289a2dd365677d25ba3342c08/wrapt-2.0.1-cp314-cp314-win_amd64.whl", hash = "sha256:4ae879acc449caa9ed43fc36ba08392b9412ee67941748d31d94e3cedb36628c", size = 60947, upload-time = "2025-11-07T00:44:46.086Z" }, + { url = "https://files.pythonhosted.org/packages/aa/3f/96db0619276a833842bf36343685fa04f987dd6e3037f314531a1e00492b/wrapt-2.0.1-cp314-cp314-win_arm64.whl", hash = "sha256:8639b843c9efd84675f1e100ed9e99538ebea7297b62c4b45a7042edb84db03e", size = 59359, upload-time = "2025-11-07T00:44:47.164Z" }, + { url = "https://files.pythonhosted.org/packages/71/49/5f5d1e867bf2064bf3933bc6cf36ade23505f3902390e175e392173d36a2/wrapt-2.0.1-cp314-cp314t-macosx_10_13_universal2.whl", hash = "sha256:9219a1d946a9b32bb23ccae66bdb61e35c62773ce7ca6509ceea70f344656b7b", size = 82031, upload-time = "2025-11-07T00:44:49.4Z" }, + { url = "https://files.pythonhosted.org/packages/2b/89/0009a218d88db66ceb83921e5685e820e2c61b59bbbb1324ba65342668bc/wrapt-2.0.1-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:fa4184e74197af3adad3c889a1af95b53bb0466bced92ea99a0c014e48323eec", size = 62952, upload-time = "2025-11-07T00:44:50.74Z" }, + { url = "https://files.pythonhosted.org/packages/ae/18/9b968e920dd05d6e44bcc918a046d02afea0fb31b2f1c80ee4020f377cbe/wrapt-2.0.1-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:c5ef2f2b8a53b7caee2f797ef166a390fef73979b15778a4a153e4b5fedce8fa", size = 63688, upload-time = "2025-11-07T00:44:52.248Z" }, + { url = "https://files.pythonhosted.org/packages/a6/7d/78bdcb75826725885d9ea26c49a03071b10c4c92da93edda612910f150e4/wrapt-2.0.1-cp314-cp314t-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:e042d653a4745be832d5aa190ff80ee4f02c34b21f4b785745eceacd0907b815", size = 152706, upload-time = "2025-11-07T00:44:54.613Z" }, + { url = "https://files.pythonhosted.org/packages/dd/77/cac1d46f47d32084a703df0d2d29d47e7eb2a7d19fa5cbca0e529ef57659/wrapt-2.0.1-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:2afa23318136709c4b23d87d543b425c399887b4057936cd20386d5b1422b6fa", size = 158866, upload-time = "2025-11-07T00:44:55.79Z" }, + { url = "https://files.pythonhosted.org/packages/8a/11/b521406daa2421508903bf8d5e8b929216ec2af04839db31c0a2c525eee0/wrapt-2.0.1-cp314-cp314t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:6c72328f668cf4c503ffcf9434c2b71fdd624345ced7941bc6693e61bbe36bef", size = 146148, upload-time = "2025-11-07T00:44:53.388Z" }, + { url = "https://files.pythonhosted.org/packages/0c/c0/340b272bed297baa7c9ce0c98ef7017d9c035a17a6a71dce3184b8382da2/wrapt-2.0.1-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:3793ac154afb0e5b45d1233cb94d354ef7a983708cc3bb12563853b1d8d53747", size = 155737, upload-time = "2025-11-07T00:44:56.971Z" }, + { url = "https://files.pythonhosted.org/packages/f3/93/bfcb1fb2bdf186e9c2883a4d1ab45ab099c79cbf8f4e70ea453811fa3ea7/wrapt-2.0.1-cp314-cp314t-musllinux_1_2_riscv64.whl", hash = "sha256:fec0d993ecba3991645b4857837277469c8cc4c554a7e24d064d1ca291cfb81f", size = 144451, upload-time = "2025-11-07T00:44:58.515Z" }, + { url = "https://files.pythonhosted.org/packages/d2/6b/dca504fb18d971139d232652656180e3bd57120e1193d9a5899c3c0b7cdd/wrapt-2.0.1-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:949520bccc1fa227274da7d03bf238be15389cd94e32e4297b92337df9b7a349", size = 150353, upload-time = "2025-11-07T00:44:59.753Z" }, + { url = "https://files.pythonhosted.org/packages/1d/f6/a1de4bd3653afdf91d250ca5c721ee51195df2b61a4603d4b373aa804d1d/wrapt-2.0.1-cp314-cp314t-win32.whl", hash = "sha256:be9e84e91d6497ba62594158d3d31ec0486c60055c49179edc51ee43d095f79c", size = 60609, upload-time = "2025-11-07T00:45:03.315Z" }, + { url = "https://files.pythonhosted.org/packages/01/3a/07cd60a9d26fe73efead61c7830af975dfdba8537632d410462672e4432b/wrapt-2.0.1-cp314-cp314t-win_amd64.whl", hash = "sha256:61c4956171c7434634401db448371277d07032a81cc21c599c22953374781395", size = 64038, upload-time = "2025-11-07T00:45:00.948Z" }, + { url = "https://files.pythonhosted.org/packages/41/99/8a06b8e17dddbf321325ae4eb12465804120f699cd1b8a355718300c62da/wrapt-2.0.1-cp314-cp314t-win_arm64.whl", hash = "sha256:35cdbd478607036fee40273be8ed54a451f5f23121bd9d4be515158f9498f7ad", size = 60634, upload-time = "2025-11-07T00:45:02.087Z" }, + { url = "https://files.pythonhosted.org/packages/15/d1/b51471c11592ff9c012bd3e2f7334a6ff2f42a7aed2caffcf0bdddc9cb89/wrapt-2.0.1-py3-none-any.whl", hash = "sha256:4d2ce1bf1a48c5277d7969259232b57645aae5686dba1eaeade39442277afbca", size = 44046, upload-time = "2025-11-07T00:45:32.116Z" }, ] From 5e69941e15f38488ba21349e8551c887de26b7d3 Mon Sep 17 00:00:00 2001 From: Simon van Lierde Date: Thu, 27 Nov 2025 10:27:28 +0000 Subject: [PATCH 56/71] feat(backend): Allow patching videos --- backend/app/api/data_collection/routers.py | 23 ++++++++++++++++++-- backend/app/api/file_storage/crud.py | 5 +++-- backend/app/api/file_storage/schemas.py | 11 +++++++--- frontend-app/src/app/products/[id]/index.tsx | 2 +- 4 files changed, 33 insertions(+), 8 deletions(-) diff --git a/backend/app/api/data_collection/routers.py b/backend/app/api/data_collection/routers.py index 58b5e52..475a24b 100644 --- a/backend/app/api/data_collection/routers.py +++ b/backend/app/api/data_collection/routers.py @@ -65,11 +65,11 @@ ProductUpdate, ProductUpdateWithProperties, ) -from app.api.file_storage.crud import create_video, delete_video +from app.api.file_storage.crud import create_video, delete_video, update_video from app.api.file_storage.filters import VideoFilter from app.api.file_storage.models.models import Video from app.api.file_storage.router_factories import StorageRouteMethod, add_storage_routes -from app.api.file_storage.schemas import VideoCreateWithinProduct, VideoReadWithinProduct +from app.api.file_storage.schemas import VideoCreateWithinProduct, VideoReadWithinProduct, VideoUpdateWithinProduct if TYPE_CHECKING: from sqlmodel.sql._expression_select_cls import SelectOfScalar @@ -944,6 +944,25 @@ async def create_product_video( return await create_video(session, video, product_id=product.id) +@product_router.patch( + "/{product_id}/videos/{video_id}", + response_model=VideoReadWithinProduct, + summary="Update video by ID", +) +async def update_product_video( + product: UserOwnedProductDep, + video_id: PositiveInt, + video_update: VideoUpdateWithinProduct, + session: AsyncSessionDep, +) -> Video: + """Update a video associated with a specific product.""" + # Validate existence of product and video + await get_nested_model_by_id(session, Product, product.id, Video, video_id, "product_id") + + # Update video + return await update_video(session, video_id, video_update) + + @product_router.delete( "/{product_id}/videos/{video_id}", status_code=204, diff --git a/backend/app/api/file_storage/crud.py b/backend/app/api/file_storage/crud.py index d07bcdb..775cd82 100644 --- a/backend/app/api/file_storage/crud.py +++ b/backend/app/api/file_storage/crud.py @@ -4,7 +4,7 @@ import uuid from collections.abc import Callable, Sequence from pathlib import Path -from typing import Any, Generic, TypeVar +from typing import Any, TypeVar from anyio import to_thread from fastapi import UploadFile @@ -30,6 +30,7 @@ VideoCreate, VideoCreateWithinProduct, VideoUpdate, + VideoUpdateWithinProduct, ) logger = logging.getLogger(__name__) @@ -269,7 +270,7 @@ async def create_video( return db_video -async def update_video(db: AsyncSession, video_id: int, video: VideoUpdate) -> Video: +async def update_video(db: AsyncSession, video_id: int, video: VideoUpdate | VideoUpdateWithinProduct) -> Video: """Update an existing video in the database.""" db_video: Video = await db_get_model_with_id_if_it_exists(db, Video, video_id) diff --git a/backend/app/api/file_storage/schemas.py b/backend/app/api/file_storage/schemas.py index ed737a0..23b22be 100644 --- a/backend/app/api/file_storage/schemas.py +++ b/backend/app/api/file_storage/schemas.py @@ -185,7 +185,7 @@ class VideoCreate(BaseCreateSchema, VideoBase): class VideoReadWithinProduct(BaseReadSchemaWithTimeStamp, VideoBase): - """Schema for reading video information.""" + """Schema for reading video information within a product.""" class VideoRead(BaseReadSchemaWithTimeStamp, VideoBase): @@ -194,11 +194,16 @@ class VideoRead(BaseReadSchemaWithTimeStamp, VideoBase): product_id: PositiveInt -class VideoUpdate(BaseUpdateSchema): - """Schema for updating a video.""" +class VideoUpdateWithinProduct(BaseUpdateSchema): + """Schema for updating a video within a product.""" url: AnyUrlToDB | None = Field(default=None, description="URL linking to the video") title: str | None = Field(default=None, max_length=100, description="Title of the video") description: str | None = Field(default=None, max_length=500, description="Description of the video") video_metadata: dict[str, Any] | None = Field(default=None, description="Video metadata as a JSON dict") + + +class VideoUpdate(VideoUpdateWithinProduct): + """Schema for updating a video.""" + product_id: PositiveInt diff --git a/frontend-app/src/app/products/[id]/index.tsx b/frontend-app/src/app/products/[id]/index.tsx index 3c59cce..6f16f8d 100644 --- a/frontend-app/src/app/products/[id]/index.tsx +++ b/frontend-app/src/app/products/[id]/index.tsx @@ -7,6 +7,7 @@ import { KeyboardAwareScrollView } from 'react-native-keyboard-controller'; import { AnimatedFAB, Button, Tooltip, useTheme } from 'react-native-paper'; import ProductAmountInParent from '@/components/product/ProductAmountInParent'; +import ProductCircularityProperties from '@/components/product/ProductCircularityProperties'; import ProductComponents from '@/components/product/ProductComponents'; import ProductDelete from '@/components/product/ProductDelete'; import ProductDescription from '@/components/product/ProductDescription'; @@ -15,7 +16,6 @@ import ProductMetaData from '@/components/product/ProductMetaData'; import ProductPhysicalProperties from '@/components/product/ProductPhysicalProperties'; import ProductTags from '@/components/product/ProductTags'; import ProductType from '@/components/product/ProductType'; -import ProductCircularityProperties from '@/components/product/ProductCircularityProperties'; import ProductVideo from "@/components/product/ProductVideo"; import { useDialog } from '@/components/common/DialogProvider'; From 93a469ed3849e4deda85903c767d82972cdd703b Mon Sep 17 00:00:00 2001 From: Simon van Lierde Date: Thu, 27 Nov 2025 10:32:07 +0000 Subject: [PATCH 57/71] Merge pull request #80 from CMLPlatform/frontend-app-circularity-properties Frontend app circularity properties --- frontend-app/src/app/products/[id]/index.tsx | 1 + .../product/ProductCircularityProperties.tsx | 10 +++++----- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/frontend-app/src/app/products/[id]/index.tsx b/frontend-app/src/app/products/[id]/index.tsx index 6f16f8d..94fdf41 100644 --- a/frontend-app/src/app/products/[id]/index.tsx +++ b/frontend-app/src/app/products/[id]/index.tsx @@ -16,6 +16,7 @@ import ProductMetaData from '@/components/product/ProductMetaData'; import ProductPhysicalProperties from '@/components/product/ProductPhysicalProperties'; import ProductTags from '@/components/product/ProductTags'; import ProductType from '@/components/product/ProductType'; +import ProductCircularityProperties from '@/components/product/ProductCircularityProperties'; import ProductVideo from "@/components/product/ProductVideo"; import { useDialog } from '@/components/common/DialogProvider'; diff --git a/frontend-app/src/components/product/ProductCircularityProperties.tsx b/frontend-app/src/components/product/ProductCircularityProperties.tsx index acfe890..13dce1d 100644 --- a/frontend-app/src/components/product/ProductCircularityProperties.tsx +++ b/frontend-app/src/components/product/ProductCircularityProperties.tsx @@ -1,10 +1,10 @@ -import { MaterialCommunityIcons } from '@expo/vector-icons'; -import { Fragment, useState } from 'react'; -import { View, StyleSheet, Pressable, useColorScheme } from 'react-native'; -import { Chip, InfoTooltip, Text, TextInput } from '@/components/base'; -import { CircularityProperties, Product } from '@/types/Product'; import DarkTheme from '@/assets/themes/dark'; import LightTheme from '@/assets/themes/light'; +import { Chip, InfoTooltip, Text, TextInput } from '@/components/base'; +import { CircularityProperties, Product } from '@/types/Product'; +import { MaterialCommunityIcons } from '@expo/vector-icons'; +import { Fragment, useState } from 'react'; +import { Pressable, StyleSheet, useColorScheme, View } from 'react-native'; interface Props { product: Product; From 89c64ce7cbbb9685cfa73a8072a66d101fd8a056 Mon Sep 17 00:00:00 2001 From: Simon van Lierde Date: Thu, 27 Nov 2025 10:33:59 +0000 Subject: [PATCH 58/71] chore: linting --- .pre-commit-config.yaml | 4 +- backend/tests/conftest.py | 2 +- frontend-app/src/app/products/[id]/index.tsx | 3 +- .../product/ProductCircularityProperties.tsx | 255 +++++++++--------- .../src/components/product/ProductVideo.tsx | 252 ++++++++--------- frontend-app/src/services/api/saving.ts | 9 +- frontend-app/src/types/Product.ts | 3 +- 7 files changed, 267 insertions(+), 261 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index ce5a11e..898da1b 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -11,7 +11,7 @@ repos: - id: pre-commit-update # Autoupdate pre-commit hooks - repo: https://github.com/gitleaks/gitleaks - rev: v8.29.1 + rev: v8.30.0 hooks: - id: gitleaks @@ -72,7 +72,7 @@ repos: args: ["--config", "backend/pyproject.toml"] - repo: https://github.com/astral-sh/uv-pre-commit - rev: 0.9.11 + rev: 0.9.13 hooks: - id: uv-lock # Update the uv lockfile for the backend. files: ^backend/(uv\.lock|pyproject\.toml|uv\.toml)$ diff --git a/backend/tests/conftest.py b/backend/tests/conftest.py index 843680c..5deafde 100644 --- a/backend/tests/conftest.py +++ b/backend/tests/conftest.py @@ -9,6 +9,7 @@ from unittest.mock import AsyncMock import pytest +from alembic.config import Config from fastapi.testclient import TestClient from sqlalchemy import Engine, create_engine, text from sqlalchemy.exc import ProgrammingError @@ -17,7 +18,6 @@ from sqlmodel.ext.asyncio.session import AsyncSession from alembic import command -from alembic.config import Config from app.core.config import settings from app.main import app diff --git a/frontend-app/src/app/products/[id]/index.tsx b/frontend-app/src/app/products/[id]/index.tsx index 94fdf41..611235e 100644 --- a/frontend-app/src/app/products/[id]/index.tsx +++ b/frontend-app/src/app/products/[id]/index.tsx @@ -16,8 +16,7 @@ import ProductMetaData from '@/components/product/ProductMetaData'; import ProductPhysicalProperties from '@/components/product/ProductPhysicalProperties'; import ProductTags from '@/components/product/ProductTags'; import ProductType from '@/components/product/ProductType'; -import ProductCircularityProperties from '@/components/product/ProductCircularityProperties'; -import ProductVideo from "@/components/product/ProductVideo"; +import ProductVideo from '@/components/product/ProductVideo'; import { useDialog } from '@/components/common/DialogProvider'; diff --git a/frontend-app/src/components/product/ProductCircularityProperties.tsx b/frontend-app/src/components/product/ProductCircularityProperties.tsx index 13dce1d..3166d81 100644 --- a/frontend-app/src/components/product/ProductCircularityProperties.tsx +++ b/frontend-app/src/components/product/ProductCircularityProperties.tsx @@ -31,11 +31,7 @@ interface CircularityPropertySectionProps { onUpdateField: (field: 'comment' | 'observation' | 'reference', value: string) => void; } -export default function ProductCircularityProperties({ - product, - editMode, - onChangeCircularityProperties, -}: Props) { +export default function ProductCircularityProperties({ product, editMode, onChangeCircularityProperties }: Props) { const darkMode = useColorScheme() === 'dark'; const theme = darkMode ? DarkTheme : LightTheme; const [expandedProperty, setExpandedProperty] = useState(null); @@ -66,12 +62,17 @@ export default function ProductCircularityProperties({ (typeof reference === 'string' && reference.trim() !== '') || // Also consider it as "having data" if comment or reference are empty strings (not null) // This means the property was added but not yet filled in - (comment !== null || reference !== null) + comment !== null || + reference !== null ); }; // Helper function to update a specific field - const updateField = (type: CircularityPropertyType, field: 'comment' | 'observation' | 'reference', value: string) => { + const updateField = ( + type: CircularityPropertyType, + field: 'comment' | 'observation' | 'reference', + value: string, + ) => { if (!product.circularityProperties) return; const key = `${type}${field.charAt(0).toUpperCase()}${field.slice(1)}` as keyof CircularityProperties; @@ -121,8 +122,6 @@ export default function ProductCircularityProperties({ setExpandedProperty(null); }; - - const propertyTypes = ['recyclability', 'remanufacturability', 'repairability'] as CircularityPropertyType[]; const chipsToShow = editMode ? propertyTypes.filter((type) => !hasPropertyData(type)) : []; const expandedPropertiesToShow = propertyTypes.filter((type) => hasPropertyData(type)); @@ -157,134 +156,135 @@ export default function ProductCircularityProperties({ )} {/* Render expanded properties */} - {expandedPropertiesToShow.map((type) => ( - product.circularityProperties && ( - setExpandedProperty(expandedProperty === type ? null : type)} - onRemove={() => removeProperty(type)} - onUpdateField={(field, value) => updateField(type, field, value)} - /> - ) - ))} + {expandedPropertiesToShow.map( + (type) => + product.circularityProperties && ( + setExpandedProperty(expandedProperty === type ? null : type)} + onRemove={() => removeProperty(type)} + onUpdateField={(field, value) => updateField(type, field, value)} + /> + ), + )}
); } function CircularityPropertySection({ - type, - circularityProperties, - editMode, - isExpanded, - onToggleExpanded, - onRemove, - onUpdateField, - }: CircularityPropertySectionProps) { - const darkMode = useColorScheme() === 'dark'; - const theme = darkMode ? DarkTheme : LightTheme; - - const commentKey = `${type}Comment` as keyof CircularityProperties; - const observationKey = `${type}Observation` as keyof CircularityProperties; - const referenceKey = `${type}Reference` as keyof CircularityProperties; - - // Helper to check if a field has content - const hasContent = (value: string | null | undefined): boolean => { - return typeof value === 'string' && value.trim() !== ''; - }; + type, + circularityProperties, + editMode, + isExpanded, + onToggleExpanded, + onRemove, + onUpdateField, +}: CircularityPropertySectionProps) { + const darkMode = useColorScheme() === 'dark'; + const theme = darkMode ? DarkTheme : LightTheme; - const observation = circularityProperties[observationKey]; - const comment = circularityProperties[commentKey]; - const reference = circularityProperties[referenceKey]; + const commentKey = `${type}Comment` as keyof CircularityProperties; + const observationKey = `${type}Observation` as keyof CircularityProperties; + const referenceKey = `${type}Reference` as keyof CircularityProperties; - return ( - - - - - {propertyLabels[type]} - - [styles.iconButton, pressed && styles.iconButtonPressed]} - > - - - {editMode && ( - [styles.iconButton, pressed && styles.iconButtonPressed]} - > - - - )} - - + // Helper to check if a field has content + const hasContent = (value: string | null | undefined): boolean => { + return typeof value === 'string' && value.trim() !== ''; + }; - {isExpanded && ( - - {/* Observation field - always show in edit mode, only show if has content in view mode */} - {(editMode || hasContent(observation)) && ( - - Observation (Required) - onUpdateField('observation', text)} - multiline - numberOfLines={3} - editable={editMode} - style={[ - styles.input, - styles.multilineInput, - darkMode && styles.inputDark, - editMode && !observation && styles.inputError, - editMode && !observation && darkMode && styles.inputErrorDark, - ]} - errorOnEmpty={editMode && !observation} - /> - - )} + const observation = circularityProperties[observationKey]; + const comment = circularityProperties[commentKey]; + const reference = circularityProperties[referenceKey]; - {/* Comment field - always show in edit mode, only show if has content in view mode */} - {(editMode || hasContent(comment)) && ( - - Comment (Optional) - onUpdateField('comment', text)} - multiline - numberOfLines={2} - editable={editMode} - style={[styles.input, styles.multilineInput, darkMode && styles.inputDark]} - /> - - )} + return ( + + + + + {propertyLabels[type]} + + [styles.iconButton, pressed && styles.iconButtonPressed]} + > + + + {editMode && ( + [styles.iconButton, pressed && styles.iconButtonPressed]} + > + + + )} + + - {/* Reference field - always show in edit mode, only show if has content in view mode */} - {(editMode || hasContent(reference)) && ( - - Reference (Optional) - onUpdateField('reference', text)} - editable={editMode} - style={[styles.input, darkMode && styles.inputDark]} - placeholder="e.g., ISO 14021:2016" - /> - - )} - - )} - - - ); + {isExpanded && ( + + {/* Observation field - always show in edit mode, only show if has content in view mode */} + {(editMode || hasContent(observation)) && ( + + Observation (Required) + onUpdateField('observation', text)} + multiline + numberOfLines={3} + editable={editMode} + style={[ + styles.input, + styles.multilineInput, + darkMode && styles.inputDark, + editMode && !observation && styles.inputError, + editMode && !observation && darkMode && styles.inputErrorDark, + ]} + errorOnEmpty={editMode && !observation} + /> + + )} + + {/* Comment field - always show in edit mode, only show if has content in view mode */} + {(editMode || hasContent(comment)) && ( + + Comment (Optional) + onUpdateField('comment', text)} + multiline + numberOfLines={2} + editable={editMode} + style={[styles.input, styles.multilineInput, darkMode && styles.inputDark]} + /> + + )} + + {/* Reference field - always show in edit mode, only show if has content in view mode */} + {(editMode || hasContent(reference)) && ( + + Reference (Optional) + onUpdateField('reference', text)} + editable={editMode} + style={[styles.input, darkMode && styles.inputDark]} + placeholder="e.g., ISO 14021:2016" + /> + + )} + + )} + + + ); } const styles = StyleSheet.create({ @@ -372,4 +372,3 @@ const styles = StyleSheet.create({ textAlignVertical: 'top', }, }); - diff --git a/frontend-app/src/components/product/ProductVideo.tsx b/frontend-app/src/components/product/ProductVideo.tsx index 3c378a1..0405437 100644 --- a/frontend-app/src/components/product/ProductVideo.tsx +++ b/frontend-app/src/components/product/ProductVideo.tsx @@ -1,141 +1,153 @@ -import { useState } from 'react'; -import { View, Text, TouchableOpacity, Linking } from 'react-native'; -import { MaterialCommunityIcons } from '@expo/vector-icons'; import { InfoTooltip, TextInput } from '@/components/base'; import { useDialog } from '@/components/common/DialogProvider'; -import { Product } from '@/types/Product'; import { isValidUrl } from '@/services/api/validation/product'; +import { Product } from '@/types/Product'; +import { MaterialCommunityIcons } from '@expo/vector-icons'; +import { useState } from 'react'; +import { Linking, Text, TouchableOpacity, View } from 'react-native'; interface Video { - id?: number; - url: string; - title: string; - description: string; + id?: number; + url: string; + title: string; + description: string; } interface Props { - product: Product; - editMode: boolean; - onVideoChange?: (videos: Video[]) => void; + product: Product; + editMode: boolean; + onVideoChange?: (videos: Video[]) => void; } export default function ProductVideo({ product, editMode, onVideoChange }: Props) { - const [videos, setVideos] = useState(product.videos || []); - const dialog = useDialog(); + const [videos, setVideos] = useState(product.videos || []); + const dialog = useDialog(); - const handleVideoChange = (idx: number, field: 'url' | 'title' | 'description', value: string) => { - const updated = videos.map((v, i) => i === idx ? { ...v, [field]: value } : v); - setVideos(updated); - onVideoChange?.(updated); - }; + const handleVideoChange = (idx: number, field: 'url' | 'title' | 'description', value: string) => { + const updated = videos.map((v, i) => (i === idx ? { ...v, [field]: value } : v)); + setVideos(updated); + onVideoChange?.(updated); + }; - const handleRemove = (idx: number) => { - const updated = videos.filter((_, i) => i !== idx); - setVideos(updated); - onVideoChange?.(updated); - }; + const handleRemove = (idx: number) => { + const updated = videos.filter((_, i) => i !== idx); + setVideos(updated); + onVideoChange?.(updated); + }; - const handleAdd = () => { - dialog.input({ - title: 'Add Recording', - placeholder: 'Video URL', - helperText: 'Paste a video URL (YouTube)', - buttons: [ - { text: 'Cancel' }, - { - text: 'Add', - disabled: (value) => !value || !value.trim() || !isValidUrl(value), - onPress: (url) => { - if (!url || !isValidUrl(url)) return; - const updated = [...videos, { url: url.trim(), title: '', description: '' }]; - setVideos(updated); - onVideoChange?.(updated); - } - } - ] - }); - }; + const handleAdd = () => { + dialog.input({ + title: 'Add Recording', + placeholder: 'Video URL', + helperText: 'Paste a video URL (YouTube)', + buttons: [ + { text: 'Cancel' }, + { + text: 'Add', + disabled: (value) => !value || !value.trim() || !isValidUrl(value), + onPress: (url) => { + if (!url || !isValidUrl(url)) return; + const updated = [...videos, { url: url.trim(), title: '', description: '' }]; + setVideos(updated); + onVideoChange?.(updated); + }, + }, + ], + }); + }; - return ( - - + return ( + + + + Recordings + + {editMode && ( + + Add recording + + )} + + + {videos.length === 0 && ( + + This product has no associated recordings. + + )} + + {videos.map((video, idx) => ( + + + handleVideoChange(idx, 'title', val)} + editable={editMode} + errorOnEmpty + /> + {editMode ? ( + handleVideoChange(idx, 'url', val)} + errorOnEmpty + customValidation={isValidUrl} + editable={editMode} + /> + ) : ( + Linking.openURL(video.url)}> - Recordings + {video.url} - {editMode && ( - - Add recording - - )} - - - {videos.length === 0 && ( - This product has no associated recordings. + )} - - {videos.map((video, idx) => ( - - - handleVideoChange(idx, 'title', val)} - editable={editMode} - errorOnEmpty - /> - {editMode ? ( - handleVideoChange(idx, 'url', val)} - errorOnEmpty - customValidation={isValidUrl} - editable={editMode} - /> - ) : ( - Linking.openURL(video.url)}> - - {video.url} - - - )} - {(editMode || Boolean(video.description)) && handleVideoChange(idx, 'description', val)} - editable={editMode} - />} - - {editMode && ( - handleRemove(idx)} - style={{ - padding: 14, - justifyContent: 'center', - alignItems: 'center' - }} - > - - - )} - - ))} + {(editMode || Boolean(video.description)) && ( + handleVideoChange(idx, 'description', val)} + editable={editMode} + /> + )} + + {editMode && ( + handleRemove(idx)} + style={{ + padding: 14, + justifyContent: 'center', + alignItems: 'center', + }} + > + + + )} - ); + ))} + + ); } diff --git a/frontend-app/src/services/api/saving.ts b/frontend-app/src/services/api/saving.ts index 46ac57c..c422a4f 100644 --- a/frontend-app/src/services/api/saving.ts +++ b/frontend-app/src/services/api/saving.ts @@ -200,10 +200,7 @@ async function updateProductVideos(product: Product) { const videosToAdd = product.videos.filter((vid) => !vid.id); const videosToUpdate = product.videos.filter((vid) => { const orig = currentVideos.find((v) => v.id === vid.id); - return orig && (orig.url !== vid.url - || orig.description !== vid.description - || orig.title !== vid.title - ); + return orig && (orig.url !== vid.url || orig.description !== vid.description || orig.title !== vid.title); }); for (const vid of videosToDelete) { @@ -217,7 +214,7 @@ async function updateProductVideos(product: Product) { } } -async function addVideo(product: Product, video: { url: string; description: string, title: string, }) { +async function addVideo(product: Product, video: { url: string; description: string; title: string }) { const url = new URL(baseUrl + `/products/${product.id}/videos`); const token = await getToken(); const headers = { @@ -243,7 +240,7 @@ async function deleteVideo(product: Product, video: { id?: number }) { await fetch(url, { method: 'DELETE', headers }); } -async function updateVideo(product: Product, video: { id?: number; url: string; description: string, title: string, }) { +async function updateVideo(product: Product, video: { id?: number; url: string; description: string; title: string }) { if (!video.id) { return; } diff --git a/frontend-app/src/types/Product.ts b/frontend-app/src/types/Product.ts index df35132..a90e6c1 100644 --- a/frontend-app/src/types/Product.ts +++ b/frontend-app/src/types/Product.ts @@ -12,7 +12,7 @@ export type Product = { physicalProperties: PhysicalProperties; circularityProperties: CircularityProperties; images: { id?: number; url: string; description: string }[]; - videos: { id?: number; url: string; description: string; title: string; }[]; + videos: { id?: number; url: string; description: string; title: string }[]; ownedBy: 'me' | string; amountInParent?: number; }; @@ -35,4 +35,3 @@ export type CircularityProperties = { repairabilityObservation: string; repairabilityReference?: string | null; }; - From ba4017b4f20f0e84bb3de602ad4f559e75f0afb2 Mon Sep 17 00:00:00 2001 From: Simon van Lierde Date: Thu, 27 Nov 2025 12:03:56 +0100 Subject: [PATCH 59/71] chore(backend): Simplify circularity properties model --- ...7_simplify_circularity_properties_model.py | 50 +++++++++++++++++++ backend/app/api/data_collection/models.py | 6 +-- 2 files changed, 53 insertions(+), 3 deletions(-) create mode 100644 backend/alembic/versions/84d2f72dccc7_simplify_circularity_properties_model.py diff --git a/backend/alembic/versions/84d2f72dccc7_simplify_circularity_properties_model.py b/backend/alembic/versions/84d2f72dccc7_simplify_circularity_properties_model.py new file mode 100644 index 0000000..f62c861 --- /dev/null +++ b/backend/alembic/versions/84d2f72dccc7_simplify_circularity_properties_model.py @@ -0,0 +1,50 @@ +"""Simplify Circularity_properties model + +Revision ID: 84d2f72dccc7 +Revises: 0faa2fa19f62 +Create Date: 2025-11-27 12:01:32.413795 + +""" + +from collections.abc import Sequence +from typing import Union + +import sqlalchemy as sa +import sqlmodel + +import app.api.common.models.custom_types +from alembic import op + +# revision identifiers, used by Alembic. +revision: str = "84d2f72dccc7" +down_revision: str | None = "0faa2fa19f62" +branch_labels: str | Sequence[str] | None = None +depends_on: str | Sequence[str] | None = None + + +def upgrade() -> None: + # ### commands auto generated by Alembic - please adjust! ### + op.alter_column( + "circularityproperties", "recyclability_observation", existing_type=sa.VARCHAR(length=500), nullable=True + ) + op.alter_column( + "circularityproperties", "repairability_observation", existing_type=sa.VARCHAR(length=500), nullable=True + ) + op.alter_column( + "circularityproperties", "remanufacturability_observation", existing_type=sa.VARCHAR(length=500), nullable=True + ) + # ### end Alembic commands ### + + +def downgrade() -> None: + # ### commands auto generated by Alembic - please adjust! ### + op.alter_column( + "circularityproperties", "remanufacturability_observation", existing_type=sa.VARCHAR(length=500), nullable=False + ) + op.alter_column( + "circularityproperties", "repairability_observation", existing_type=sa.VARCHAR(length=500), nullable=False + ) + op.alter_column( + "circularityproperties", "recyclability_observation", existing_type=sa.VARCHAR(length=500), nullable=False + ) + # ### end Alembic commands ### diff --git a/backend/app/api/data_collection/models.py b/backend/app/api/data_collection/models.py index c981167..0e67d97 100644 --- a/backend/app/api/data_collection/models.py +++ b/backend/app/api/data_collection/models.py @@ -65,17 +65,17 @@ class CircularityPropertiesBase(CustomBase): """Base model to store circularity properties of a product.""" # Recyclability - recyclability_observation: str | None = Field(default=None, min_length=2, max_length=500) + recyclability_observation: str | None = Field(default=None, max_length=500) recyclability_comment: str | None = Field(default=None, max_length=100) recyclability_reference: str | None = Field(default=None, max_length=100) # Repairability - repairability_observation: str | None = Field(default=None, min_length=2, max_length=500) + repairability_observation: str | None = Field(default=None, max_length=500) repairability_comment: str | None = Field(default=None, max_length=100) repairability_reference: str | None = Field(default=None, max_length=100) # Remanufacturability - remanufacturability_observation: str | None = Field(default=None, min_length=2, max_length=500) + remanufacturability_observation: str | None = Field(default=None, max_length=500) remanufacturability_comment: str | None = Field(default=None, max_length=100) remanufacturability_reference: str | None = Field(default=None, max_length=100) From 0223b0ea3f6b701c071227bb43c68714b59cb7c2 Mon Sep 17 00:00:00 2001 From: Simon van Lierde Date: Thu, 27 Nov 2025 12:20:02 +0000 Subject: [PATCH 60/71] fix(docker): Update runtime stage python version to 3.14 in backend_migrations Docker image --- backend/Dockerfile.migrations | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/backend/Dockerfile.migrations b/backend/Dockerfile.migrations index 8d32ac9..47a017a 100644 --- a/backend/Dockerfile.migrations +++ b/backend/Dockerfile.migrations @@ -32,7 +32,7 @@ COPY scripts/ scripts/ COPY app/ app/ # --- Final runtime stage --- -FROM python:3.13-slim +FROM python:3.14-slim # Build arguments ARG WORKDIR=/opt/relab/backend_migrations From 671c0067d601335543c2513b2e74053799803684 Mon Sep 17 00:00:00 2001 From: Simon van Lierde Date: Thu, 27 Nov 2025 12:38:51 +0000 Subject: [PATCH 61/71] fix(frontend-app): omit circularityproperties if all fields are null --- frontend-app/src/services/api/saving.ts | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/frontend-app/src/services/api/saving.ts b/frontend-app/src/services/api/saving.ts index c422a4f..e9ec3d5 100644 --- a/frontend-app/src/services/api/saving.ts +++ b/frontend-app/src/services/api/saving.ts @@ -15,6 +15,7 @@ function toNewProduct(product: Product): any { brand: product.brand, model: product.model, description: product.description, + // TODO: Handle bill of materials properly bill_of_materials: [ { quantity: 42, @@ -55,7 +56,7 @@ function toUpdatePhysicalProperties(product: Product): any { } function toUpdateCircularityProperties(product: Product): any { - return { + const out = { recyclability_comment: product.circularityProperties.recyclabilityComment ?? null, recyclability_observation: product.circularityProperties.recyclabilityObservation, recyclability_reference: product.circularityProperties.recyclabilityReference ?? null, @@ -66,6 +67,10 @@ function toUpdateCircularityProperties(product: Product): any { repairability_observation: product.circularityProperties.repairabilityObservation, repairability_reference: product.circularityProperties.repairabilityReference ?? null, }; + + // If all values are null, return null so the caller can omit the object + const hasAny = Object.values(out).some((v) => v !== null); + return hasAny ? out : null; } export async function saveProduct(product: Product): Promise { From 6cf7e9f6cf4570fd4f06771e0a463346b3994eca Mon Sep 17 00:00:00 2001 From: Simon van Lierde Date: Thu, 27 Nov 2025 13:59:00 +0000 Subject: [PATCH 62/71] fix(backend): Add some logging on rpi-cam related network errors --- .../rpi_cam/routers/camera_interaction/utils.py | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/backend/app/api/plugins/rpi_cam/routers/camera_interaction/utils.py b/backend/app/api/plugins/rpi_cam/routers/camera_interaction/utils.py index 178851e..485cbd4 100644 --- a/backend/app/api/plugins/rpi_cam/routers/camera_interaction/utils.py +++ b/backend/app/api/plugins/rpi_cam/routers/camera_interaction/utils.py @@ -4,7 +4,8 @@ from urllib.parse import urljoin from fastapi import HTTPException -from httpx import AsyncClient, Headers, HTTPStatusError, QueryParams, Response +from httpx import AsyncClient, Headers, HTTPStatusError, QueryParams, Response, RequestError +import logging from pydantic import UUID4 from sqlmodel.ext.asyncio.session import AsyncSession @@ -68,5 +69,13 @@ async def fetch_from_camera_url( status_code=e.response.status_code, detail={"main API": error_msg, "Camera API": e.response.json().get("detail")}, ) from e + except RequestError as e: + # Network-level errors (DNS, connection refused, timeouts). + logger = logging.getLogger(__name__) + logger.warning("Network error contacting camera %s%s: %s", camera.url, endpoint, e) + raise HTTPException(status_code=503, detail={ + "main API": f"Network error contacting camera: {endpoint}", + "error": str(e), + }) from e else: return response From f68a9500abc25a86f7753c5bc46c06efd4ff0467 Mon Sep 17 00:00:00 2001 From: Simon van Lierde Date: Thu, 27 Nov 2025 15:09:14 +0100 Subject: [PATCH 63/71] fix(backend): Remove unused docker arg --- backend/Dockerfile | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/backend/Dockerfile b/backend/Dockerfile index 17b19a7..fb580fc 100644 --- a/backend/Dockerfile +++ b/backend/Dockerfile @@ -38,7 +38,6 @@ FROM python:3.14-slim # Build arguments ARG WORKDIR=/opt/relab/backend -ARG APP_PORT=8000 ARG APP_USER=appuser # Set up a non-root user @@ -54,11 +53,11 @@ ENV PYTHONPATH=$WORKDIR \ PYTHONUNBUFFERED=1 \ PATH="$WORKDIR/.venv/bin:$PATH" -# Expose the application port -EXPOSE 8000 - # Switch to non-root user USER $APP_USER +# Expose the application port +EXPOSE 8000 + # Run the FastAPI application CMD [".venv/bin/fastapi", "run", "app/main.py", "--host", "0.0.0.0", "--port", "8000"] From ef7deb59a4bf310ff2a3eb2d8a8cf955d4d96d55 Mon Sep 17 00:00:00 2001 From: Simon van Lierde Date: Mon, 1 Dec 2025 14:04:55 +0000 Subject: [PATCH 64/71] fix(backend): update ruff target python version --- backend/pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/backend/pyproject.toml b/backend/pyproject.toml index 042eaca..641d3f9 100644 --- a/backend/pyproject.toml +++ b/backend/pyproject.toml @@ -118,7 +118,7 @@ [tool.ruff] fix = true line-length = 120 - target-version = "py313" + target-version = "py314" # Exclude automatically generated files from linting extend-exclude = ["./alembic/versions"] From 1ef6d7a2b72a668ee3a5fa6fc667364b57ac75e2 Mon Sep 17 00:00:00 2001 From: Simon van Lierde Date: Mon, 1 Dec 2025 17:11:45 +0100 Subject: [PATCH 65/71] fix(backend): Update python target version for ruff to 3.14 --- backend/app/api/auth/schemas.py | 8 ++++---- backend/app/api/auth/utils/context_managers.py | 2 +- backend/app/api/background_data/schemas.py | 6 +++--- backend/app/api/common/models/associations.py | 4 ++-- backend/app/api/data_collection/schemas.py | 6 +++--- .../rpi_cam/routers/camera_interaction/utils.py | 15 +++++++++------ backend/pyproject.toml | 1 - 7 files changed, 22 insertions(+), 20 deletions(-) diff --git a/backend/app/api/auth/schemas.py b/backend/app/api/auth/schemas.py index 6abd33f..8db9611 100644 --- a/backend/app/api/auth/schemas.py +++ b/backend/app/api/auth/schemas.py @@ -31,13 +31,13 @@ class OrganizationRead(OrganizationBase): class OrganizationReadWithRelationshipsPublic(BaseReadSchemaWithTimeStamp, OrganizationBase): """Read schema for organizations, including relationships.""" - members: list["UserReadPublic"] = Field(default_factory=list, description="List of users in the organization.") + members: list[UserReadPublic] = Field(default_factory=list, description="List of users in the organization.") class OrganizationReadWithRelationships(BaseReadSchemaWithTimeStamp, OrganizationBase): """Read schema for organizations, including relationships.""" - members: list["UserRead"] = Field(default_factory=list, description="List of users in the organization.") + members: list[UserRead] = Field(default_factory=list, description="List of users in the organization.") class OrganizationUpdate(BaseUpdateSchema): @@ -92,7 +92,7 @@ class UserCreate(UserCreateBase): class UserCreateWithOrganization(UserCreateBase): """Create schema for users with organization to create and own.""" - organization: "OrganizationCreate" + organization: OrganizationCreate model_config: ConfigDict = ConfigDict( # pyright: ignore [reportIncompatibleVariableOverride] # This is not a type override, see https://github.com/fastapi/sqlmodel/discussions/855 { @@ -140,7 +140,7 @@ class UserRead(UserBase, schemas.BaseUser[uuid.UUID]): class UserReadWithOrganization(UserRead): """Read schema for users with organization.""" - organization: Optional["OrganizationRead"] = Field(default=None, description="Organization the user belongs to.") + organization: OrganizationRead | None = Field(default=None, description="Organization the user belongs to.") class UserReadWithRelationships(UserReadWithOrganization): diff --git a/backend/app/api/auth/utils/context_managers.py b/backend/app/api/auth/utils/context_managers.py index 9823ba6..af40334 100644 --- a/backend/app/api/auth/utils/context_managers.py +++ b/backend/app/api/auth/utils/context_managers.py @@ -19,7 +19,7 @@ @asynccontextmanager async def get_chained_async_user_manager_context( session: AsyncSession | None = None, -) -> AsyncGenerator["UserManager"]: +) -> AsyncGenerator[UserManager]: """Provides a user manager context using the user database and an async database session. If a session is provided, it will be used; otherwise, a new session for the default database will be created. diff --git a/backend/app/api/background_data/schemas.py b/backend/app/api/background_data/schemas.py index b82b280..682a6c2 100644 --- a/backend/app/api/background_data/schemas.py +++ b/backend/app/api/background_data/schemas.py @@ -33,7 +33,7 @@ class CategoryCreateWithinCategoryWithSubCategories(BaseCreateSchema, CategoryBa """Schema for creating a new category within a category, with optional subcategories.""" # Database model has a None default, but Pydantic model has empty set default for consistent API type handling - subcategories: set["CategoryCreateWithinCategoryWithSubCategories"] = Field( + subcategories: set[CategoryCreateWithinCategoryWithSubCategories] = Field( default_factory=set, description="List of subcategories", ) @@ -97,7 +97,7 @@ class CategoryReadWithRelationships(CategoryRead): """Schema for reading category information with all relationships.""" materials: list[MaterialRead] = Field(default_factory=list, description="List of materials linked to the category") - product_types: list["ProductTypeRead"] = Field( + product_types: list[ProductTypeRead] = Field( default_factory=list, description="List of product types linked to the category" ) @@ -111,7 +111,7 @@ class CategoryReadWithRelationshipsAndFlatSubCategories(CategoryReadWithRelation class CategoryReadAsSubCategoryWithRecursiveSubCategories(CategoryReadAsSubCategory): """Schema for reading category information with recursive subcategories.""" - subcategories: list["CategoryReadAsSubCategoryWithRecursiveSubCategories"] = Field( + subcategories: list[CategoryReadAsSubCategoryWithRecursiveSubCategories] = Field( default_factory=list, description="List of subcategories" ) diff --git a/backend/app/api/common/models/associations.py b/backend/app/api/common/models/associations.py index e0da3a4..e19285c 100644 --- a/backend/app/api/common/models/associations.py +++ b/backend/app/api/common/models/associations.py @@ -34,8 +34,8 @@ class MaterialProductLink(MaterialProductLinkBase, TimeStampMixinBare, table=Tru foreign_key="product.id", primary_key=True, description="ID of the product with the material" ) - material: "Material" = Relationship(back_populates="product_links", sa_relationship_kwargs={"lazy": "selectin"}) - product: "Product" = Relationship(back_populates="bill_of_materials", sa_relationship_kwargs={"lazy": "selectin"}) + material: Material = Relationship(back_populates="product_links", sa_relationship_kwargs={"lazy": "selectin"}) + product: Product = Relationship(back_populates="bill_of_materials", sa_relationship_kwargs={"lazy": "selectin"}) def __str__(self) -> str: return f"{self.quantity} {self.unit} of {self.material.name} in {self.product.name}" diff --git a/backend/app/api/data_collection/schemas.py b/backend/app/api/data_collection/schemas.py index 32794af..0471fa9 100644 --- a/backend/app/api/data_collection/schemas.py +++ b/backend/app/api/data_collection/schemas.py @@ -256,7 +256,7 @@ class ComponentCreateWithComponents(ComponentCreate): """ # Recursive components - components: list["ComponentCreateWithComponents"] = Field( + components: list[ComponentCreateWithComponents] = Field( default_factory=list, description="Set of component products" ) @@ -309,13 +309,13 @@ class ProductReadWithRelationships(ProductReadWithProperties): class ProductReadWithRelationshipsAndFlatComponents(ProductReadWithRelationships): """Schema for reading product information with one level of components.""" - components: list["ComponentRead"] = Field(default_factory=list, description="List of component products") + components: list[ComponentRead] = Field(default_factory=list, description="List of component products") class ComponentReadWithRecursiveComponents(ComponentRead): """Schema for reading product information with recursive components.""" - components: list["ComponentReadWithRecursiveComponents"] = Field( + components: list[ComponentReadWithRecursiveComponents] = Field( default_factory=list, description="List of component products" ) diff --git a/backend/app/api/plugins/rpi_cam/routers/camera_interaction/utils.py b/backend/app/api/plugins/rpi_cam/routers/camera_interaction/utils.py index 485cbd4..23f8f5a 100644 --- a/backend/app/api/plugins/rpi_cam/routers/camera_interaction/utils.py +++ b/backend/app/api/plugins/rpi_cam/routers/camera_interaction/utils.py @@ -1,11 +1,11 @@ """Utilities for the camera interaction endpoints.""" +import logging from enum import Enum from urllib.parse import urljoin from fastapi import HTTPException -from httpx import AsyncClient, Headers, HTTPStatusError, QueryParams, Response, RequestError -import logging +from httpx import AsyncClient, Headers, HTTPStatusError, QueryParams, RequestError, Response from pydantic import UUID4 from sqlmodel.ext.asyncio.session import AsyncSession @@ -73,9 +73,12 @@ async def fetch_from_camera_url( # Network-level errors (DNS, connection refused, timeouts). logger = logging.getLogger(__name__) logger.warning("Network error contacting camera %s%s: %s", camera.url, endpoint, e) - raise HTTPException(status_code=503, detail={ - "main API": f"Network error contacting camera: {endpoint}", - "error": str(e), - }) from e + raise HTTPException( + status_code=503, + detail={ + "main API": f"Network error contacting camera: {endpoint}", + "error": str(e), + }, + ) from e else: return response diff --git a/backend/pyproject.toml b/backend/pyproject.toml index 641d3f9..9c31527 100644 --- a/backend/pyproject.toml +++ b/backend/pyproject.toml @@ -137,7 +137,6 @@ "C4", # flake8-comprehensions (fixes iterable comprehensions) "C90", # mccabe "D", # pydocstyle - "DJ", # flake8-django "DTZ", # flake8-datetimez (checks for naive datetime uses without timezone) "E", # pycodestyle errors "EM", # flake8-errmsgs (checks for error messages) From cbdfbc376ba1e9a2a0d508f0a5f94c57f8f994fc Mon Sep 17 00:00:00 2001 From: Simon van Lierde Date: Mon, 1 Dec 2025 17:12:35 +0100 Subject: [PATCH 66/71] fix(backend): Move logging module --- backend/app/core/{utils/custom_logging.py => logging.py} | 0 backend/app/core/utils/__init__.py | 1 - backend/app/main.py | 2 +- 3 files changed, 1 insertion(+), 2 deletions(-) rename backend/app/core/{utils/custom_logging.py => logging.py} (100%) delete mode 100644 backend/app/core/utils/__init__.py diff --git a/backend/app/core/utils/custom_logging.py b/backend/app/core/logging.py similarity index 100% rename from backend/app/core/utils/custom_logging.py rename to backend/app/core/logging.py diff --git a/backend/app/core/utils/__init__.py b/backend/app/core/utils/__init__.py deleted file mode 100644 index 9b957b1..0000000 --- a/backend/app/core/utils/__init__.py +++ /dev/null @@ -1 +0,0 @@ -"""Cross-package utility functions.""" diff --git a/backend/app/main.py b/backend/app/main.py index 4b8807b..88c4e9e 100644 --- a/backend/app/main.py +++ b/backend/app/main.py @@ -20,8 +20,8 @@ from app.api.common.routers.openapi import init_openapi_docs from app.core.config import settings from app.core.database import async_engine +from app.core.logging import setup_logging from app.core.redis import close_redis, init_redis -from app.core.utils.custom_logging import setup_logging # Initialize logging setup_logging() From 324ce8e2c5d24eff4fb08feba071f7e79d4295f2 Mon Sep 17 00:00:00 2001 From: Simon van Lierde Date: Tue, 2 Dec 2025 11:01:12 +0100 Subject: [PATCH 67/71] fix(backend): Lint backend with ruff targeted to 3.14 and remove unused sqladmin interface --- CONTRIBUTING.md | 5 +- backend/.env.example | 2 +- backend/alembic/env.py | 3 +- backend/app/api/admin/__init__.py | 1 - backend/app/api/admin/auth.py | 76 ----- backend/app/api/admin/config.py | 13 - backend/app/api/admin/main.py | 65 ---- backend/app/api/admin/models.py | 306 ------------------ backend/app/api/auth/models.py | 10 +- backend/app/api/auth/routers/frontend.py | 2 - backend/app/api/background_data/models.py | 14 +- backend/app/api/data_collection/models.py | 22 +- backend/app/api/file_storage/models/models.py | 12 +- backend/app/api/plugins/rpi_cam/models.py | 2 +- backend/app/main.py | 12 +- backend/app/templates/index.html | 7 - backend/pyproject.toml | 3 +- backend/uv.lock | 30 -- docs/docs/architecture/system-design.md | 4 - frontend-app/src/app/products/[id]/camera.tsx | 255 +++++++++++---- frontend-app/src/services/api/saving.ts | 6 +- 21 files changed, 230 insertions(+), 620 deletions(-) delete mode 100644 backend/app/api/admin/__init__.py delete mode 100644 backend/app/api/admin/auth.py delete mode 100644 backend/app/api/admin/config.py delete mode 100644 backend/app/api/admin/main.py delete mode 100644 backend/app/api/admin/models.py diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index b151b2d..8e89656 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -173,10 +173,7 @@ It is still recommended to use VS Code as your IDE, as we have provided some rec The API is now available at . - You can log in with the superuser details specified in the `.env` file. This gives you access to: - - - Interactive API documentation at - - Admin panel for database management at + You can log in with the superuser details specified in the `.env` file. This gives you access to the interactive API documentation at #### Documentation Setup diff --git a/backend/.env.example b/backend/.env.example index 1cf0df5..bec577f 100644 --- a/backend/.env.example +++ b/backend/.env.example @@ -32,7 +32,7 @@ EMAIL_REPLY_TO='your.replyto.alias.@example.com' # 🔀 Email address REDIS_HOST='localhost' # Redis server host (use 'cache' in Docker) REDIS_PORT='6379' # Redis server port REDIS_DB='0' # Redis database number (0-15) -REDIS_PASSWORD='' # 🔀 Redis password (leave empty if no password) +REDIS_PASSWORD='' # 🔀 Redis password (leave empty if no password) # Superuser details SUPERUSER_EMAIL='your-email@example.com' # 🔀 diff --git a/backend/alembic/env.py b/backend/alembic/env.py index 397a112..ef4b0b2 100644 --- a/backend/alembic/env.py +++ b/backend/alembic/env.py @@ -4,10 +4,11 @@ from pathlib import Path import alembic_postgresql_enum # noqa: F401 (Make sure the PostgreSQL ENUM type is recognized) -from alembic import context from sqlalchemy import engine_from_config, pool from sqlmodel import SQLModel # Include the SQLModel metadata +from alembic import context + # Load settings from the FastAPI app config project_root = Path(__file__).resolve().parents[1] sys.path.append(str(project_root)) diff --git a/backend/app/api/admin/__init__.py b/backend/app/api/admin/__init__.py deleted file mode 100644 index 180309f..0000000 --- a/backend/app/api/admin/__init__.py +++ /dev/null @@ -1 +0,0 @@ -"""Admin panel package.""" diff --git a/backend/app/api/admin/auth.py b/backend/app/api/admin/auth.py deleted file mode 100644 index f3916af..0000000 --- a/backend/app/api/admin/auth.py +++ /dev/null @@ -1,76 +0,0 @@ -"""Authentication backend for the SQLAdmin interface, based on FastAPI-Users authentication backend.""" - -import json -from typing import Literal - -from fastapi import Response, status -from fastapi.responses import RedirectResponse -from sqladmin.authentication import AuthenticationBackend -from sqlalchemy.ext.asyncio import async_sessionmaker -from sqlmodel.ext.asyncio.session import AsyncSession -from starlette.requests import Request - -from app.api.admin.config import settings as admin_settings -from app.api.auth.config import settings as auth_settings -from app.api.auth.routers.frontend import router as frontend_auth_router -from app.api.auth.services.user_manager import cookie_transport, get_jwt_strategy -from app.api.auth.utils.context_managers import get_chained_async_user_manager_context -from app.core.database import async_engine - -async_session_generator = async_sessionmaker(bind=async_engine, class_=AsyncSession, expire_on_commit=False) - -# TODO: Redirect all backend login systems (admin panel, swagger docs, API landing page) to frontend login system -main_login_page_redirect_path = ( - f"{frontend_auth_router.url_path_for('login_page')}?next={admin_settings.admin_base_url}" -) - - -class AdminAuth(AuthenticationBackend): - """Authentication backend for the SQLAdmin interface, using FastAPI-Users.""" - - async def login(self, request: Request) -> bool: # noqa: ARG002 # Signature expected by the SQLAdmin implementation - """Placeholder logout function. - - Login is handled by the authenticate method, which redirects to the main API login page. - """ - return True - - async def logout(self, request: Request) -> bool: # noqa: ARG002 # Signature expected by the SQLAdmin implementation - """Placeholder logout function. - - Logout requires unsetting a cookie, which is not possible in the standard SQLAdmin logout function, - which is excepted to return a boolean. - Instead, the default logout route is overridden by the custom route below. - """ - return True - - async def authenticate(self, request: Request) -> RedirectResponse | Response | Literal[True]: - token = request.cookies.get(cookie_transport.cookie_name) - if not token: - return RedirectResponse(url=main_login_page_redirect_path) - async with get_chained_async_user_manager_context() as user_manager: - user = await get_jwt_strategy().read_token(token=token, user_manager=user_manager) - if user is None: - return RedirectResponse(url=main_login_page_redirect_path) - if not user.is_superuser: - return Response( - json.dumps({"detail": "You do not have permission to access this resource."}), - status_code=status.HTTP_403_FORBIDDEN, - media_type="application/json", - ) - - return True - - -def get_authentication_backend() -> AdminAuth: - """Get the authentication backend for the SQLAdmin interface.""" - return AdminAuth(secret_key=auth_settings.fastapi_users_secret.get_secret_value()) - - -async def logout_override(request: Request) -> RedirectResponse: # noqa: ARG001 # Signature expected by the SQLAdmin implementation - """Override of the default admin dashboard logout route to unset the authentication cookie.""" - response = RedirectResponse(url=frontend_auth_router.url_path_for("index"), status_code=302) - response.delete_cookie( - key=cookie_transport.cookie_name, domain=cookie_transport.cookie_domain, path=cookie_transport.cookie_path - ) - return response diff --git a/backend/app/api/admin/config.py b/backend/app/api/admin/config.py deleted file mode 100644 index 7ed8416..0000000 --- a/backend/app/api/admin/config.py +++ /dev/null @@ -1,13 +0,0 @@ -"""Configuration for the admin module.""" - -from pydantic_settings import BaseSettings - - -class AdminSettings(BaseSettings): - """Settings class to store settings related to admin components.""" - - admin_base_url: str = "/admin/dashboard" # The base url of the SQLadmin interface - - -# Create a settings instance that can be imported throughout the app -settings = AdminSettings() diff --git a/backend/app/api/admin/main.py b/backend/app/api/admin/main.py deleted file mode 100644 index df5aa67..0000000 --- a/backend/app/api/admin/main.py +++ /dev/null @@ -1,65 +0,0 @@ -"""SQLAdmin module for the FastAPI app.""" - -from fastapi import FastAPI -from sqladmin import Admin -from sqlalchemy import Engine -from sqlalchemy.ext.asyncio.engine import AsyncEngine -from starlette.applications import Starlette -from starlette.routing import Mount, Route - -from app.api.admin.auth import get_authentication_backend, logout_override -from app.api.admin.config import settings -from app.api.admin.models import ( - CategoryAdmin, - ImageAdmin, - MaterialAdmin, - MaterialProductLinkAdmin, - ProductAdmin, - ProductTypeAdmin, - TaxonomyAdmin, - UserAdmin, - VideoAdmin, -) - - -def init_admin(app: FastAPI, engine: Engine | AsyncEngine) -> Admin: - """Initialize the SQLAdmin interface for the FastAPI app. - - Args: - app (FastAPI): Main FastAPI application instance - engine (Engine | AsyncEngine): SQLAlchemy database engine, sync or async - """ - admin = Admin(app, engine, authentication_backend=get_authentication_backend(), base_url=settings.admin_base_url) - - # HACK: Override SQLAdmin logout route to allow cookie-based auth - for route in admin.app.routes: - # Find the mounted SQLAdmin app - if isinstance(route, Mount) and route.path == settings.admin_base_url and isinstance(route.app, Starlette): - for subroute in route.app.routes: - # Find the logout subroute and replace it with the custom override to allow cookie-based auth - if isinstance(subroute, Route) and subroute.name == "logout": - route.routes.remove(subroute) - route.app.add_route( - subroute.path, - logout_override, - methods=list(subroute.methods) if subroute.methods is not None else None, - name="logout", - ) - break - break - - # Add Background Data views to Admin interface - admin.add_view(CategoryAdmin) - admin.add_view(MaterialAdmin) - admin.add_view(ProductTypeAdmin) - admin.add_view(TaxonomyAdmin) - # Add Data Collection views to Admin interface - admin.add_view(MaterialProductLinkAdmin) - admin.add_view(ImageAdmin) - admin.add_view(ProductAdmin) - admin.add_view(VideoAdmin) - - # Add other admin views - admin.add_view(UserAdmin) - - return admin diff --git a/backend/app/api/admin/models.py b/backend/app/api/admin/models.py deleted file mode 100644 index f0efff6..0000000 --- a/backend/app/api/admin/models.py +++ /dev/null @@ -1,306 +0,0 @@ -"""Models for the admin module.""" - -import uuid -from collections.abc import Callable, Sequence -from pathlib import Path -from typing import Any, ClassVar - -from anyio import to_thread -from markupsafe import Markup -from sqladmin import ModelView -from sqladmin._types import MODEL_ATTR -from starlette.datastructures import UploadFile -from starlette.requests import Request -from wtforms import ValidationError -from wtforms.fields import FileField -from wtforms.form import Form -from wtforms.validators import InputRequired - -from app.api.auth.models import User -from app.api.background_data.models import Category, Material, ProductType, Taxonomy -from app.api.common.models.associations import MaterialProductLink -from app.api.data_collection.models import Product -from app.api.file_storage.models.models import Image, Video - -### Constants ### -ALLOWED_IMAGE_EXTENSIONS: set[str] = {".bmp", ".gif", ".jpeg", ".jpg", ".png", ".tiff", ".webp"} - - -### Form Validators ### -class FileSizeLimit: - """WTForms validator to limit the file size of a FileField.""" - - def __init__(self, max_size_mb: int, message: str | None = None) -> None: - self.max_size_mb = max_size_mb - self.message = message or f"File size must be under {self.max_size_mb} MB." - - def __call__(self, form: Form, field: FileField): # noqa: ARG002 # WTForms uses this signature - if isinstance(field.data, UploadFile) and field.data.size and field.data.size > self.max_size_mb * 1024 * 1024: - raise ValidationError(self.message) - - -class FileTypeValidator: - """WTForms validator to limit the file type of a FileField.""" - - def __init__(self, allowed_extensions: set[str], message: str | None = None): - self.allowed_extensions = allowed_extensions - self.message = message or f"Allowed file types: {', '.join(self.allowed_extensions)}." - - def __call__(self, form: Form, field: FileField): # noqa: ARG002 # WTForms uses this signature - if isinstance(field.data, UploadFile) and field.data.filename: - file_ext = Path(field.data.filename).suffix.lower() - if file_ext not in self.allowed_extensions: - raise ValidationError(self.message) - - -### Linking Models ### -class MaterialProductLinkAdmin(ModelView, model=MaterialProductLink): - """Admin view for Material-Product links.""" - - name = "Material-Product Link" - name_plural = "Material-Product Links" - icon = "fa-solid fa-link" - category = "Data Collection" - - column_list: ClassVar[Sequence[MODEL_ATTR]] = ["material", "product", "quantity", "unit"] - - column_formatters: ClassVar[dict[MODEL_ATTR, Callable]] = { - "material": lambda m, _: Markup('{}').format(m.material_id, m.material), - "product": lambda m, _: Markup('{}').format(m.product_id, m.product), - } - - column_searchable_list: ClassVar[Sequence[MODEL_ATTR]] = ["material.name", "product.name"] - - column_sortable_list: ClassVar[Sequence[MODEL_ATTR]] = ["quantity", "unit"] - - column_details_list: ClassVar[Sequence[MODEL_ATTR]] = [*column_list, "created_at", "updated_at"] - - -### Background Models ### -class CategoryAdmin(ModelView, model=Category): - """Admin view for Category model.""" - - name = "Category" - name_plural = "Categories" - icon = "fa-solid fa-list" - category = "Background Data" - column_list: ClassVar[Sequence[MODEL_ATTR]] = ["id", "name", "taxonomy_id"] - column_searchable_list: ClassVar[Sequence[MODEL_ATTR]] = ["name", "description"] - column_sortable_list: ClassVar[Sequence[MODEL_ATTR]] = ["id", "name", "taxonomy_id"] - - -class TaxonomyAdmin(ModelView, model=Taxonomy): - """Admin view for Taxonomy model.""" - - name = "Taxonomy" - name_plural = "Taxonomies" - icon = "fa-solid fa-sitemap" - category = "Background Data" - - column_list: ClassVar[Sequence[MODEL_ATTR]] = ["id", "name", "domain"] - column_searchable_list: ClassVar[Sequence[MODEL_ATTR]] = ["name", "domain"] - column_sortable_list: ClassVar[Sequence[MODEL_ATTR]] = ["id", "name"] - - -class MaterialAdmin(ModelView, model=Material): - """Admin view for Material model.""" - - name = "Material" - name_plural = "Materials" - icon = "fa-solid fa-cubes" - category = "Background Data" - - column_labels: ClassVar[dict[MODEL_ATTR, str]] = { - "density_kg_m3": "Density (kg/m³)", - "is_crm": "Is CRM", - } - - column_list: ClassVar[Sequence[MODEL_ATTR]] = [ - "id", - "name", - "description", - "is_crm", - ] - column_searchable_list: ClassVar[Sequence[MODEL_ATTR]] = ["name", "description"] - column_sortable_list: ClassVar[Sequence[MODEL_ATTR]] = ["id", "name", "is_crm"] - - -class ProductTypeAdmin(ModelView, model=ProductType): - """Admin view for ProductType model.""" - - name = "Product Type" - name_plural = "Product Types" - icon = "fa-solid fa-tag" - category = "Background Data" - - column_labels: ClassVar[dict[MODEL_ATTR, str]] = { - "lifespan_yr": "Lifespan (years)", - } - - column_list: ClassVar[Sequence[MODEL_ATTR]] = ["id", "name", "description"] - column_searchable_list: ClassVar[Sequence[MODEL_ATTR]] = ["name", "description"] - column_sortable_list: ClassVar[Sequence[MODEL_ATTR]] = ["id", "name"] - - -### Product Models ### -class ProductAdmin(ModelView, model=Product): - """Admin view for Product model.""" - - name = "Product" - name_plural = "Products" - icon = "fa-solid fa-box" - category = "Data Collection" - - column_list: ClassVar[Sequence[MODEL_ATTR]] = [ - "id", - "name", - "type", - "description", - ] - column_searchable_list: ClassVar[Sequence[MODEL_ATTR]] = ["name", "description"] - column_sortable_list: ClassVar[Sequence[MODEL_ATTR]] = [ - "id", - "name", - "product_type_id", - ] - - -### Data Collection Models ### -class VideoAdmin(ModelView, model=Video): - """Admin view for Video model.""" - - name = "Video" - name_plural = "Videos" - icon = "fa-solid fa-video" - category = "Data Collection" - - column_list: ClassVar[Sequence[MODEL_ATTR]] = ["id", "url", "description", "product", "created_at"] - - column_formatters: ClassVar[dict[MODEL_ATTR, Callable]] = { - "url": lambda m, _: Markup('{}').format(m.url, m.url), - "product": lambda m, _: Markup('{}').format(m.product_id, m.product) - if m.product - else "", - "created_at": lambda m, _: m.created_at.strftime("%Y-%m-%d %H:%M") if m.created_at else "", - } - - column_searchable_list: ClassVar[Sequence[MODEL_ATTR]] = ["description", "url"] - - column_sortable_list: ClassVar[Sequence[MODEL_ATTR]] = ["id", "created_at"] - - column_details_list: ClassVar[Sequence[MODEL_ATTR]] = [*column_list, "updated_at"] - - -### User Models ### -class UserAdmin(ModelView, model=User): - """Admin view for User model.""" - - name = "User" - name_plural = "Users" - icon = "fa-solid fa-user" - category = "Users" - - # User CRUD should be handled by the auth module - can_create = False - can_edit = False - can_delete = False - - column_list: ClassVar[Sequence[MODEL_ATTR]] = [ - "id", - "email", - "username", - "organization", - "is_active", - "is_superuser", - "is_verified", - ] - column_searchable_list: ClassVar[Sequence[MODEL_ATTR]] = ["email", "organization"] - column_sortable_list: ClassVar[Sequence[MODEL_ATTR]] = ["email", "organization"] - - column_details_list: ClassVar[Sequence[MODEL_ATTR]] = column_list - - -### File Storage Models ### -class ImageAdmin(ModelView, model=Image): - """Admin view for Image model.""" - - # TODO: Use Image schema logic instead of duplicating it here - # TODO: Add a method to download the original file (should take it from the filename but rename it to original_name) - - name = "Image" - name_plural = "Images" - icon = "fa-solid fa-camera" - category = "Data Collection" - - # Display settings - column_list: ClassVar[Sequence[MODEL_ATTR]] = [ - "id", - "description", - "filename", - "created_at", - "updated_at", - "image_preview", - ] - column_details_list: ClassVar[Sequence[MODEL_ATTR]] = column_list - column_formatters: ClassVar[dict[MODEL_ATTR, Callable]] = { - "created_at": lambda model, _: model.created_at.strftime("%Y-%m-%d %H:%M:%S") if model.created_at else "", - "updated_at": lambda model, _: model.updated_at.strftime("%Y-%m-%d %H:%M:%S") if model.updated_at else "", - "image_preview": lambda model, _: model.image_preview(100), - } - column_formatters_detail: ClassVar[dict[MODEL_ATTR, Callable]] = column_formatters - - column_searchable_list: ClassVar[Sequence[MODEL_ATTR]] = [ - "id", - "description", - "filename", - "created_at", - "updated_at", - ] - column_sortable_list: ClassVar[Sequence[MODEL_ATTR]] = column_searchable_list - - # Create and edit settings - form_columns: ClassVar[Sequence[MODEL_ATTR]] = [ - "description", - "file", - ] - - form_args: ClassVar[dict[str, Any]] = { - "file": { - "validators": [ - InputRequired(), - FileSizeLimit(max_size_mb=10), - FileTypeValidator(allowed_extensions=ALLOWED_IMAGE_EXTENSIONS), - ], - } - } - - def _delete_image_file(self, image_path: Path) -> None: - """Delete the image file from the filesystem if it exists.""" - if image_path.exists(): - image_path.unlink() - - def handle_model_change(self, data: dict[str, Any], model: Image, is_created: bool) -> None: # noqa: FBT001 # Wtforms uses this signature - def new_image_uploaded(data: dict[str, Any]) -> bool: - """Check if a new image is present in form data.""" - return isinstance(data.get("file"), UploadFile) and data["file"].size - - if new_image_uploaded(data): - model.filename = data["file"].filename # Set the filename to the original filename - data["file"].filename = f"{uuid.uuid4()}{Path(model.filename).suffix}" # Store the file to a unique path - - if not is_created and model.file: # If the model is being edited and it has an existing image - if new_image_uploaded(data): - self._delete_image_file(Path(model.file.path)) - else: - data.pop("file", None) # Keep existing image if no new one uploaded - - def handle_model_delete(self, model: Image) -> None: - if model.file: - self._delete_image_file(model.file.path) - - async def on_model_change(self, data: dict[str, Any], model: Image, is_created: bool, request: Request) -> None: # noqa: ARG002, FBT001 # Wtforms uses this signature - """SQLAdmin expects on_model_change to be asynchronous. This method handles the synchronous model change.""" - await to_thread.run_sync(self.handle_model_change, data, model, is_created) - - async def after_model_delete(self, model: Image, request: Request) -> None: # noqa: ARG002 # Wtforms uses this signature - await to_thread.run_sync(lambda: self._delete_image_file(Path(model.file.path)) if model.file.path else None) diff --git a/backend/app/api/auth/models.py b/backend/app/api/auth/models.py index 206f81a..afe73c1 100644 --- a/backend/app/api/auth/models.py +++ b/backend/app/api/auth/models.py @@ -43,7 +43,7 @@ class User(SQLModelBaseUserDB, CustomBaseBare, UserBase, TimeStampMixinBare, tab id: UUID4 | None = Field(default_factory=uuid.uuid4, primary_key=True, nullable=False) # One-to-many relationship with OAuthAccount - oauth_accounts: list["OAuthAccount"] = Relationship( + oauth_accounts: list[OAuthAccount] = Relationship( back_populates="user", sa_relationship_kwargs={ "lazy": "joined", # Required because of FastAPI-Users OAuth implementation @@ -52,7 +52,7 @@ class User(SQLModelBaseUserDB, CustomBaseBare, UserBase, TimeStampMixinBare, tab }, # TODO: Check if this is fixed in future versions of pydantic/sqlmodel and we can use automatic # relationship detection again ) - products: list["Product"] = Relationship( + products: list[Product] = Relationship( back_populates="owner", sa_relationship_kwargs={ "primaryjoin": "User.id == Product.owner_id", # HACK: Explicitly define join condition because of @@ -68,7 +68,7 @@ class User(SQLModelBaseUserDB, CustomBaseBare, UserBase, TimeStampMixinBare, tab nullable=True, ), ) - organization: Optional["Organization"] = Relationship( + organization: Organization | None = Relationship( back_populates="members", sa_relationship_kwargs={ "lazy": "selectin", @@ -79,7 +79,7 @@ class User(SQLModelBaseUserDB, CustomBaseBare, UserBase, TimeStampMixinBare, tab organization_role: OrganizationRole | None = Field(default=None, sa_column=Column(SAEnum(OrganizationRole))) # One-to-one relationship with owned Organization - owned_organization: Optional["Organization"] = Relationship( + owned_organization: Organization | None = Relationship( back_populates="owner", sa_relationship_kwargs={ "uselist": False, @@ -146,7 +146,7 @@ class Organization(OrganizationBase, TimeStampMixinBare, table=True): ) # One-to-many relationship with member Users - members: list["User"] = Relationship( + members: list[User] = Relationship( back_populates="organization", sa_relationship_kwargs={ "primaryjoin": "Organization.id == User.organization_id", diff --git a/backend/app/api/auth/routers/frontend.py b/backend/app/api/auth/routers/frontend.py index 8a83909..6b2aafd 100644 --- a/backend/app/api/auth/routers/frontend.py +++ b/backend/app/api/auth/routers/frontend.py @@ -6,7 +6,6 @@ from fastapi.responses import HTMLResponse, RedirectResponse from fastapi.templating import Jinja2Templates -from app.api.admin.config import settings as admin_settings from app.api.auth.dependencies import OptionalCurrentActiveUserDep from app.core.config import settings as core_settings @@ -30,7 +29,6 @@ async def index( "user": user, "show_full_docs": user.is_superuser if user else False, "frontend_web_url": core_settings.frontend_web_url, - "admin_path": admin_settings.admin_base_url, }, ) diff --git a/backend/app/api/background_data/models.py b/backend/app/api/background_data/models.py index d03a295..1600452 100644 --- a/backend/app/api/background_data/models.py +++ b/backend/app/api/background_data/models.py @@ -64,7 +64,7 @@ class Taxonomy(TaxonomyBase, TimeStampMixinBare, table=True): id: int | None = Field(default=None, primary_key=True) - categories: list["Category"] = Relationship(back_populates="taxonomy", cascade_delete=True) + categories: list[Category] = Relationship(back_populates="taxonomy", cascade_delete=True) model_config: ConfigDict = ConfigDict(use_enum_values=True, arbitrary_types_allowed=True) # pyright: ignore [reportIncompatibleVariableOverride] # This is not a type override, see https://github.com/fastapi/sqlmodel/discussions/855 @@ -89,11 +89,11 @@ class Category(CategoryBase, TimeStampMixinBare, table=True): # Self-referential relationship supercategory_id: int | None = Field(foreign_key="category.id", default=None, nullable=True) - supercategory: Optional["Category"] = Relationship( + supercategory: Category | None = Relationship( back_populates="subcategories", sa_relationship_kwargs={"remote_side": "Category.id", "lazy": "selectin", "join_depth": 1}, ) - subcategories: list["Category"] | None = Relationship( + subcategories: list[Category] | None = Relationship( back_populates="supercategory", sa_relationship_kwargs={"lazy": "selectin", "join_depth": 1}, cascade_delete=True, @@ -104,8 +104,8 @@ class Category(CategoryBase, TimeStampMixinBare, table=True): taxonomy: Taxonomy = Relationship(back_populates="categories") # Many-to-many relationships. This is ugly but SQLModel doesn't allow for polymorphic association. - materials: list["Material"] | None = Relationship(back_populates="categories", link_model=CategoryMaterialLink) - product_types: list["ProductType"] | None = Relationship( + materials: list[Material] | None = Relationship(back_populates="categories", link_model=CategoryMaterialLink) + product_types: list[ProductType] | None = Relationship( back_populates="categories", link_model=CategoryProductTypeLink ) @@ -138,7 +138,7 @@ class Material(MaterialBase, TimeStampMixinBare, table=True): # Many-to-many relationships categories: list[Category] | None = Relationship(back_populates="materials", link_model=CategoryMaterialLink) - product_links: list["MaterialProductLink"] | None = Relationship(back_populates="material") + product_links: list[MaterialProductLink] | None = Relationship(back_populates="material") # Magic methods def __str__(self) -> str: @@ -159,7 +159,7 @@ class ProductType(ProductTypeBase, TimeStampMixinBare, table=True): id: int | None = Field(default=None, primary_key=True) # One-to-many relationships - products: list["Product"] | None = Relationship(back_populates="product_type") + products: list[Product] | None = Relationship(back_populates="product_type") files: list[File] | None = Relationship(back_populates="product_type", cascade_delete=True) images: list[Image] | None = Relationship(back_populates="product_type", cascade_delete=True) diff --git a/backend/app/api/data_collection/models.py b/backend/app/api/data_collection/models.py index 0e67d97..4df8c42 100644 --- a/backend/app/api/data_collection/models.py +++ b/backend/app/api/data_collection/models.py @@ -58,7 +58,7 @@ class PhysicalProperties(PhysicalPropertiesBase, TimeStampMixinBare, table=True) # One-to-one relationships product_id: int = Field(foreign_key="product.id") - product: "Product" = Relationship(back_populates="physical_properties") + product: Product = Relationship(back_populates="physical_properties") class CircularityPropertiesBase(CustomBase): @@ -87,7 +87,7 @@ class CircularityProperties(CircularityPropertiesBase, TimeStampMixinBare, table # One-to-one relationships product_id: int = Field(foreign_key="product.id") - product: "Product" = Relationship(back_populates="circularity_properties") + product: Product = Relationship(back_populates="circularity_properties") ### Product Model ### @@ -124,7 +124,7 @@ class Product(ProductBase, TimeStampMixinBare, table=True): # Self-referential relationship for hierarchy parent_id: int | None = Field(default=None, foreign_key="product.id") - parent: Optional["Product"] = Relationship( + parent: Product | None = Relationship( back_populates="components", sa_relationship_kwargs={ "uselist": False, @@ -134,7 +134,7 @@ class Product(ProductBase, TimeStampMixinBare, table=True): }, ) amount_in_parent: int | None = Field(default=None, description="Quantity within parent product") - components: list["Product"] | None = Relationship( + components: list[Product] | None = Relationship( back_populates="parent", cascade_delete=True, sa_relationship_kwargs={"lazy": "selectin", "join_depth": 1}, # Eagerly load linked parent product @@ -149,15 +149,15 @@ class Product(ProductBase, TimeStampMixinBare, table=True): ) # Many-to-one relationships - files: list["File"] | None = Relationship(back_populates="product", cascade_delete=True) - images: list["Image"] | None = Relationship( + files: list[File] | None = Relationship(back_populates="product", cascade_delete=True) + images: list[Image] | None = Relationship( back_populates="product", cascade_delete=True, sa_relationship_kwargs={"lazy": "subquery"} ) - videos: list["Video"] | None = Relationship(back_populates="product", cascade_delete=True) + videos: list[Video] | None = Relationship(back_populates="product", cascade_delete=True) # One-to-many relationships owner_id: UUID4 = Field(foreign_key="user.id") - owner: "User" = Relationship( + owner: User = Relationship( back_populates="products", sa_relationship_kwargs={ "uselist": False, @@ -168,7 +168,7 @@ class Product(ProductBase, TimeStampMixinBare, table=True): ) product_type_id: int | None = Field(default=None, foreign_key="producttype.id") - product_type: "ProductType" = Relationship(back_populates="products", sa_relationship_kwargs={"uselist": False}) + product_type: ProductType = Relationship(back_populates="products", sa_relationship_kwargs={"uselist": False}) # Many-to-many relationships bill_of_materials: list[MaterialProductLink] | None = Relationship( @@ -194,7 +194,7 @@ def has_cycles(self) -> bool: """Check if the product hierarchy contains cycles.""" visited = set() - def visit(node: "Product") -> bool: + def visit(node: Product) -> bool: if node.id in visited: return True # Cycle detected visited.add(node.id) @@ -210,7 +210,7 @@ def visit(node: "Product") -> bool: def components_resolve_to_materials(self) -> bool: """Ensure all leaf components have a non-empty bill of materials.""" - def check(node: "Product") -> bool: + def check(node: Product) -> bool: if not node.components: # Leaf node if not node.bill_of_materials: diff --git a/backend/app/api/file_storage/models/models.py b/backend/app/api/file_storage/models/models.py index d69fa48..d159d99 100644 --- a/backend/app/api/file_storage/models/models.py +++ b/backend/app/api/file_storage/models/models.py @@ -65,13 +65,13 @@ class File(FileBase, TimeStampMixinBare, SingleParentMixin[FileParentType], tabl ) product_id: int | None = Field(default=None, foreign_key="product.id") - product: "Product" = Relationship(back_populates="files") + product: Product = Relationship(back_populates="files") material_id: int | None = Field(default=None, foreign_key="material.id") - material: "Material" = Relationship(back_populates="files") + material: Material = Relationship(back_populates="files") product_type_id: int | None = Field(default=None, foreign_key="producttype.id") - product_type: "ProductType" = Relationship(back_populates="files") + product_type: ProductType = Relationship(back_populates="files") # Model configuration model_config: ConfigDict = ConfigDict(arbitrary_types_allowed=True, use_enum_values=True) # pyright: ignore [reportIncompatibleVariableOverride] # This is not a type override, see https://github.com/fastapi/sqlmodel/discussions/855 @@ -129,13 +129,13 @@ class Image(ImageBase, TimeStampMixinBare, SingleParentMixin, table=True): ) product_id: int | None = Field(default=None, foreign_key="product.id") - product: "Product" = Relationship(back_populates="images") + product: Product = Relationship(back_populates="images") material_id: int | None = Field(default=None, foreign_key="material.id") - material: "Material" = Relationship(back_populates="images") + material: Material = Relationship(back_populates="images") product_type_id: int | None = Field(default=None, foreign_key="producttype.id") - product_type: "ProductType" = Relationship(back_populates="images") + product_type: ProductType = Relationship(back_populates="images") # Model configuration model_config: ConfigDict = ConfigDict(arbitrary_types_allowed=True) # pyright: ignore [reportIncompatibleVariableOverride] # This is not a type override, see https://github.com/fastapi/sqlmodel/discussions/855 diff --git a/backend/app/api/plugins/rpi_cam/models.py b/backend/app/api/plugins/rpi_cam/models.py index fae5de8..fc8dc46 100644 --- a/backend/app/api/plugins/rpi_cam/models.py +++ b/backend/app/api/plugins/rpi_cam/models.py @@ -84,7 +84,7 @@ class Camera(CameraBase, TimeStampMixinBare, table=True): # Many-to-one relationship with User owner_id: UUID4 = Field(foreign_key="user.id") - owner: "User" = Relationship( # One-way relationship to maintain plugin isolation + owner: User = Relationship( # One-way relationship to maintain plugin isolation sa_relationship_kwargs={ "primaryjoin": "Camera.owner_id == User.id", "foreign_keys": "[Camera.owner_id]", diff --git a/backend/app/main.py b/backend/app/main.py index 88c4e9e..c42a6b9 100644 --- a/backend/app/main.py +++ b/backend/app/main.py @@ -1,28 +1,29 @@ """Main application module for the Reverse Engineering Lab - Data collection API. This module initializes the FastAPI application, sets up the API routes, -mounts static and upload directories, and initializes the admin interface. +and mounts static and upload directories. """ import logging -from collections.abc import AsyncGenerator from contextlib import asynccontextmanager +from typing import TYPE_CHECKING from fastapi import FastAPI from fastapi.middleware.cors import CORSMiddleware from fastapi.staticfiles import StaticFiles from fastapi_pagination import add_pagination -from app.api.admin.main import init_admin from app.api.auth.utils.email_validation import EmailChecker from app.api.common.routers.exceptions import register_exception_handlers from app.api.common.routers.main import router from app.api.common.routers.openapi import init_openapi_docs from app.core.config import settings -from app.core.database import async_engine from app.core.logging import setup_logging from app.core.redis import close_redis, init_redis +if TYPE_CHECKING: + from collections.abc import AsyncGenerator + # Initialize logging setup_logging() logger = logging.getLogger(__name__) @@ -94,9 +95,6 @@ async def lifespan(app: FastAPI) -> AsyncGenerator: # Initialize OpenAPI documentation init_openapi_docs(app) -# Initialize admin interface -admin = init_admin(app, async_engine) - # Mount local file storage app.mount("/uploads", StaticFiles(directory=settings.uploads_path), name="uploads") app.mount("/static", StaticFiles(directory=settings.static_files_path), name="static") diff --git a/backend/app/templates/index.html b/backend/app/templates/index.html index 7ddf4a8..005923a 100644 --- a/backend/app/templates/index.html +++ b/backend/app/templates/index.html @@ -25,13 +25,6 @@

API Documentation

{% endif %} - {% if show_full_docs %} -
-

Administration

- Admin Dashboard -
- {% endif %} -

API Login

{% if user %} diff --git a/backend/pyproject.toml b/backend/pyproject.toml index 9c31527..24aa274 100644 --- a/backend/pyproject.toml +++ b/backend/pyproject.toml @@ -79,8 +79,7 @@ "google-auth>=2.40.3", "itsdangerous>=2.2.0", "markupsafe >=3.0.2", - "sqladmin >=0.20.1", - ] +] migrations = ["alembic >=1.16.2", "alembic-postgresql-enum >=1.7.0", "openpyxl>=3.1.5", "pandas>=2.3.3"] diff --git a/backend/uv.lock b/backend/uv.lock index 2f9bde6..03d51ab 100644 --- a/backend/uv.lock +++ b/backend/uv.lock @@ -1927,7 +1927,6 @@ api = [ { name = "google-auth" }, { name = "itsdangerous" }, { name = "markupsafe" }, - { name = "sqladmin" }, ] dev = [ { name = "alembic-autogen-check" }, @@ -1985,7 +1984,6 @@ api = [ { name = "google-auth", specifier = ">=2.40.3" }, { name = "itsdangerous", specifier = ">=2.2.0" }, { name = "markupsafe", specifier = ">=3.0.2" }, - { name = "sqladmin", specifier = ">=0.20.1" }, ] dev = [ { name = "alembic-autogen-check", specifier = ">=1.1.1" }, @@ -2226,22 +2224,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/14/a0/bb38d3b76b8cae341dad93a2dd83ab7462e6dbcdd84d43f54ee60a8dc167/soupsieve-2.8-py3-none-any.whl", hash = "sha256:0cc76456a30e20f5d7f2e14a98a4ae2ee4e5abdc7c5ea0aafe795f344bc7984c", size = 36679, upload-time = "2025-08-27T15:39:50.179Z" }, ] -[[package]] -name = "sqladmin" -version = "0.22.0" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "jinja2" }, - { name = "python-multipart" }, - { name = "sqlalchemy" }, - { name = "starlette" }, - { name = "wtforms" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/2c/ac/526bb3ff2dd94fbf8442bccb49ef40aa360045add19d4fbffcb43995e67a/sqladmin-0.22.0.tar.gz", hash = "sha256:4ea904d97e4d030edb68fb0681330b4d963f422442a64bee487fdc46119b3729", size = 1429937, upload-time = "2025-11-24T12:52:59.285Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/f2/b4/ab78c7d7b13bd3f90d6d8a106c5ad12bf7a738f89eb0241b24ad8efe5d1e/sqladmin-0.22.0-py3-none-any.whl", hash = "sha256:f2fb11165a70601a97f71956104b47da2c432db49b0d7966dc65e9e6343887d3", size = 1445514, upload-time = "2025-11-24T12:53:00.511Z" }, -] - [[package]] name = "sqlalchemy" version = "2.0.44" @@ -2506,15 +2488,3 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/1b/6c/c65773d6cab416a64d191d6ee8a8b1c68a09970ea6909d16965d26bfed1e/websockets-15.0.1-cp313-cp313-win_amd64.whl", hash = "sha256:e09473f095a819042ecb2ab9465aee615bd9c2028e4ef7d933600a8401c79561", size = 176837, upload-time = "2025-03-05T20:02:55.237Z" }, { url = "https://files.pythonhosted.org/packages/fa/a8/5b41e0da817d64113292ab1f8247140aac61cbf6cfd085d6a0fa77f4984f/websockets-15.0.1-py3-none-any.whl", hash = "sha256:f7a866fbc1e97b5c617ee4116daaa09b722101d4a3c170c787450ba409f9736f", size = 169743, upload-time = "2025-03-05T20:03:39.41Z" }, ] - -[[package]] -name = "wtforms" -version = "3.1.2" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "markupsafe" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/6a/c7/96d10183c3470f1836846f7b9527d6cb0b6c2226ebca40f36fa29f23de60/wtforms-3.1.2.tar.gz", hash = "sha256:f8d76180d7239c94c6322f7990ae1216dae3659b7aa1cee94b6318bdffb474b9", size = 134705, upload-time = "2024-01-06T07:52:41.075Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/18/19/c3232f35e24dccfad372e9f341c4f3a1166ae7c66e4e1351a9467c921cc1/wtforms-3.1.2-py3-none-any.whl", hash = "sha256:bf831c042829c8cdbad74c27575098d541d039b1faa74c771545ecac916f2c07", size = 145961, upload-time = "2024-01-06T07:52:43.023Z" }, -] diff --git a/docs/docs/architecture/system-design.md b/docs/docs/architecture/system-design.md index 0a2c523..c1cb781 100644 --- a/docs/docs/architecture/system-design.md +++ b/docs/docs/architecture/system-design.md @@ -7,11 +7,9 @@ The Reverse Engineering Lab platform is designed as a modular application for co ```mermaid graph TD User["User fa:fa-user"] -->|Interacts with| Frontend[Expo UI fa:fa-mobile] - SuperUser["Superuser fa:fa-user-shield"] -->|Interacts with| SQLAdmin[SQL Admin fa:fa-database] %% Core backend and DB Frontend -->|API Requests fa:fa-arrow-right| Backend[FastAPI Backend ] - SQLAdmin -->|Interfaces with fa:fa-link| Backend Backend -->|Queries fa:fa-database| PostgreSQL[(PostgreSQL )] %% Authentication @@ -36,7 +34,6 @@ graph TD style Frontend fill:#e0f7fa,stroke:#00acc1,stroke-width:2px style Backend fill:#e8f5e9,stroke:#4caf50,stroke-width:2px style PostgreSQL fill:#bbdefb,stroke:#1976d2,stroke-width:2px; - style SQLAdmin fill:#f3e5f5,stroke:#9c27b0,stroke-width:2px style RaspberryPi fill:#f8bbd0,stroke:#e91e63,stroke-width:2px; style YouTube fill:#ffe6e6,stroke:#ff0000,stroke-width:2px; style Alembic fill:#fce4ec,stroke:#f06292,stroke-width:2px @@ -53,7 +50,6 @@ graph TD ## Technology Stack - **Backend**: [FastAPI](https://fastapi.tiangolo.com/) -- **Admin interface**: [SQLAdmin](https://github.com/aminalaee/sqladmin) - **ORM layer**: [SQLModel](https://github.com/fastapi/sqlmodel) - **Migrations**: [Alembic](https://alembic.sqlalchemy.org/en/latest/) - **Database**: [PostgreSQL](https://www.postgresql.org/) diff --git a/frontend-app/src/app/products/[id]/camera.tsx b/frontend-app/src/app/products/[id]/camera.tsx index d0f5b9e..d049252 100644 --- a/frontend-app/src/app/products/[id]/camera.tsx +++ b/frontend-app/src/app/products/[id]/camera.tsx @@ -1,96 +1,213 @@ -// MAIN camera.tsx import AsyncStorage from '@react-native-async-storage/async-storage'; -import { CameraView } from 'expo-camera'; +import { CameraView, useCameraPermissions } from 'expo-camera'; +import * as ImagePicker from 'expo-image-picker'; import { useLocalSearchParams, useRouter } from 'expo-router'; -import { useRef, useState } from 'react'; -import { Pressable, View } from 'react-native'; +import React from 'react'; +import { Platform, StyleSheet, View } from 'react-native'; +import { Button, Text } from 'react-native-paper'; import { processImage } from '@/services/media/imageProcessing'; import { useDialog } from '@/components/common/DialogProvider'; -type searchParams = { - id: string; -}; +type searchParams = { id: string }; export default function ProductCamera() { // Hooks const router = useRouter(); const dialog = useDialog(); const { id } = useLocalSearchParams(); - const ref = useRef(null); - - // States - const [ready, setReady] = useState(false); - const [cameraReady, setCameraReady] = useState(false); - - // Callbacks - const takePicture = async () => { - // Take picture - const photo = await ref.current?.takePictureAsync(); - if (!photo) return; - - // Process the image - const processedUri = await processImage(photo, { - onError: (error) => { - dialog.alert({ - title: error.type === 'size' ? 'Image too large' : 'Processing failed', - message: error.message, + + // ImagePicker permissions (mobile + mobile web) + const [cameraStatus, requestCameraPermission] = ImagePicker.useCameraPermissions(); + const [libraryStatus, requestLibraryPermission] = ImagePicker.useMediaLibraryPermissions(); + + // expo-camera permission (desktop web webcam) + const [webCamPermission, requestWebCamPermission] = useCameraPermissions(); + const camRef = React.useRef(null); + + // Detect desktop web (mouse/trackpad pointer) + const isDesktopWeb = + Platform.OS === 'web' && typeof window !== 'undefined' && !window.matchMedia('(pointer: coarse)').matches; + + const handleImageResult = async (result: ImagePicker.ImagePickerResult) => { + console.log('ImagePicker result:', result); + if (!result.canceled && result.assets?.[0]) { + try { + const processedUri = await processImage(result.assets[0], { + onError: (error) => { + dialog.alert({ + title: error.type === 'size' ? 'Image too large' : 'Processing failed', + message: error.message, + }); + }, }); - }, - }); - if (!processedUri) { + if (processedUri) { + await handleCapturedUri(processedUri); + } else { + router.back(); + } + } catch (error) { + console.error('Failed to process image:', error); + router.back(); + } + } else { + console.log('Image picking canceled'); router.back(); - return; } + }; - // Save photo URI to AsyncStorage - await AsyncStorage.setItem('lastPhoto', processedUri); - - // Dismiss and return to product page + const handleCapturedUri = async (uri: string) => { + console.log('Captured URI:', uri); + await AsyncStorage.setItem('lastPhoto', uri); const params = { id: id, photoTaken: 'taken' }; router.dismissTo({ pathname: '/products/[id]', params: params }); }; - // Render - return ( - setReady(true)}> - {/*Only render when layouting is done to fix visual bug on Android*/} - {ready && setCameraReady(true)} />} + const ensureWebcamPermission = async () => { + if (!webCamPermission?.granted) { + const p = await requestWebCamPermission(); + if (!p.granted) { + await dialog.alert({ + title: 'Permission Required', + message: 'Camera permission is required to take photos', + }); + return false; + } + } + return true; + }; - {/*Only enable taking pictures when camera is actually ready*/} - {cameraReady && } - - ); -} + const takePhoto = async () => { + console.log('takePhoto pressed. isDesktopWeb:', isDesktopWeb); + + if (isDesktopWeb) { + // Desktop web: Capture from webcam + const ok = await ensureWebcamPermission(); + if (!ok) return; + try { + const photo = await camRef.current?.takePictureAsync(); + if (photo?.uri) { + // Process the webcam photo through the same validation + const processedUri = await processImage(photo, { + onError: (error) => { + dialog.alert({ + title: error.type === 'size' ? 'Image too large' : 'Processing failed', + message: error.message, + }); + }, + }); + + if (processedUri) { + await handleCapturedUri(processedUri); + } + } else { + console.warn('No photo URI returned from webcam'); + } + } catch (e) { + console.error('Webcam capture error:', e); + } + return; + } + + // Mobile / mobile web: Use ImagePicker camera + if (cameraStatus?.status !== 'granted') { + const permission = await requestCameraPermission(); + if (!permission.granted) { + await dialog.alert({ + title: 'Permission Required', + message: 'Camera permission is required to take photos', + }); + return; + } + } + + try { + const result = await ImagePicker.launchCameraAsync({ + allowsEditing: true, + mediaTypes: 'images', + }); + await handleImageResult(result); + } catch (error: any) { + console.error('Camera error:', error); + if (error.message?.includes('Unsupported file type')) { + await dialog.alert({ + title: 'Unsupported file', + message: 'Please select an image file.', + }); + } + } + }; + + const pickFromGallery = async () => { + console.log('pickFromGallery pressed'); + if (libraryStatus?.status !== 'granted') { + const permission = await requestLibraryPermission(); + if (!permission.granted) { + await dialog.alert({ + title: 'Permission Required', + message: 'Media library permission is required to choose photos', + }); + return; + } + } + try { + const result = await ImagePicker.launchImageLibraryAsync({ + allowsEditing: true, + mediaTypes: 'images', + }); + await handleImageResult(result); + } catch (error: any) { + console.error('Gallery picker error:', error); + if (error.message?.includes('Unsupported file type')) { + await dialog.alert({ + title: 'Unsupported file', + message: 'Please select an image file. PDFs and other documents are not supported.', + }); + } + } + }; -function CameraButton({ onPress }: { onPress: () => void }) { - // Render return ( - - {({ pressed }) => ( - - + + + Add Product Image + + + {isDesktopWeb && ( + + {webCamPermission?.granted ? ( + + ) : ( + + + Allow camera access to take a photo + + + + )} )} - + + + + + + + ); } + +const styles = StyleSheet.create({ + header: { alignItems: 'center', justifyContent: 'center', paddingVertical: 16 }, + permissionBox: { flex: 1, alignItems: 'center', justifyContent: 'center', padding: 20 }, + actions: { alignItems: 'center', justifyContent: 'center', padding: 16, gap: 8 }, + button: { marginVertical: 6, minWidth: 200 }, +}); diff --git a/frontend-app/src/services/api/saving.ts b/frontend-app/src/services/api/saving.ts index e9ec3d5..364bd56 100644 --- a/frontend-app/src/services/api/saving.ts +++ b/frontend-app/src/services/api/saving.ts @@ -175,13 +175,15 @@ async function addImage(product: Product, image: { url: string; description: str } else if (image.url.startsWith('file:')) { console.log(image.url); body.append('file', { uri: image.url, name: 'image.png', type: 'image/png' } as any); - } else if (image.url.startsWith('blob:')) { - // Fetch the blob from the blob URL + } else if (image.url.startsWith('blob:') || image.url.startsWith('http')) { + // Web blob or URL - fetch and convert to blob const response = await fetch(image.url); const blob = await response.blob(); body.append('file', blob, 'image.png'); } + console.log('[AddImage] Uploading image:', image.url); + await fetch(url, { method: 'POST', headers: headers, body: body }); } From c4eb2be1f9f3c3f40a7a64de257757feed5b07b2 Mon Sep 17 00:00:00 2001 From: Simon van Lierde Date: Mon, 8 Dec 2025 11:00:23 +0000 Subject: [PATCH 68/71] fix(backend): Remove min length constraints from CircularityProperties Patch update schema --- backend/app/api/data_collection/schemas.py | 6 +++--- .../api/plugins/rpi_cam/routers/camera_interaction/utils.py | 5 +++++ 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/backend/app/api/data_collection/schemas.py b/backend/app/api/data_collection/schemas.py index 0471fa9..03a9d6a 100644 --- a/backend/app/api/data_collection/schemas.py +++ b/backend/app/api/data_collection/schemas.py @@ -143,9 +143,9 @@ class CircularityPropertiesUpdate(BaseUpdateSchema, CircularityPropertiesBase): """Schema for updating circularity properties.""" # Make all fields optional for updates - recyclability_observation: str | None = Field(default=None, min_length=2, max_length=500) - repairability_observation: str | None = Field(default=None, min_length=2, max_length=500) - remanufacturability_observation: str | None = Field(default=None, min_length=2, max_length=500) + recyclability_observation: str | None = Field(default=None, max_length=500) + repairability_observation: str | None = Field(default=None, max_length=500) + remanufacturability_observation: str | None = Field(default=None, max_length=500) model_config: ConfigDict = ConfigDict( json_schema_extra={ diff --git a/backend/app/api/plugins/rpi_cam/routers/camera_interaction/utils.py b/backend/app/api/plugins/rpi_cam/routers/camera_interaction/utils.py index 23f8f5a..cd5de42 100644 --- a/backend/app/api/plugins/rpi_cam/routers/camera_interaction/utils.py +++ b/backend/app/api/plugins/rpi_cam/routers/camera_interaction/utils.py @@ -2,6 +2,7 @@ import logging from enum import Enum +from typing import TYPE_CHECKING from urllib.parse import urljoin from fastapi import HTTPException @@ -12,6 +13,10 @@ from app.api.common.utils import get_user_owned_object from app.api.plugins.rpi_cam.models import Camera, CameraConnectionStatus +if TYPE_CHECKING: + from pydantic import UUID4 + from sqlmodel.ext.asyncio.session import AsyncSession + class HttpMethod(str, Enum): """HTTP method type.""" From 88a6cbcc203b2078e9b27585103f41bf9f9be76c Mon Sep 17 00:00:00 2001 From: Simon van Lierde Date: Mon, 8 Dec 2025 12:12:37 +0100 Subject: [PATCH 69/71] fix(backend): Hotfix for SQLmodel issues --- backend/app/api/auth/models.py | 4 +- backend/app/api/background_data/models.py | 2 +- backend/app/api/common/crud/utils.py | 2 + backend/app/api/data_collection/models.py | 2 +- backend/uv.lock | 351 +++++++++++----------- 5 files changed, 180 insertions(+), 181 deletions(-) diff --git a/backend/app/api/auth/models.py b/backend/app/api/auth/models.py index afe73c1..c804717 100644 --- a/backend/app/api/auth/models.py +++ b/backend/app/api/auth/models.py @@ -68,7 +68,7 @@ class User(SQLModelBaseUserDB, CustomBaseBare, UserBase, TimeStampMixinBare, tab nullable=True, ), ) - organization: Organization | None = Relationship( + organization: Optional[Organization] = Relationship( # noqa: UP045 # Using 'Optional' over Organization | None to avoid issues with sqlmodel type detection back_populates="members", sa_relationship_kwargs={ "lazy": "selectin", @@ -79,7 +79,7 @@ class User(SQLModelBaseUserDB, CustomBaseBare, UserBase, TimeStampMixinBare, tab organization_role: OrganizationRole | None = Field(default=None, sa_column=Column(SAEnum(OrganizationRole))) # One-to-one relationship with owned Organization - owned_organization: Organization | None = Relationship( + owned_organization: Optional[Organization] = Relationship( # noqa: UP045 # Using 'Optional' over Organization | None to avoid issues with sqlmodel type detection back_populates="owner", sa_relationship_kwargs={ "uselist": False, diff --git a/backend/app/api/background_data/models.py b/backend/app/api/background_data/models.py index 1600452..2ee8f92 100644 --- a/backend/app/api/background_data/models.py +++ b/backend/app/api/background_data/models.py @@ -89,7 +89,7 @@ class Category(CategoryBase, TimeStampMixinBare, table=True): # Self-referential relationship supercategory_id: int | None = Field(foreign_key="category.id", default=None, nullable=True) - supercategory: Category | None = Relationship( + supercategory: Optional[Category] = Relationship( # noqa: UP045 # Using 'Optional' over Category | None to avoid issues with sqlmodel type detection back_populates="subcategories", sa_relationship_kwargs={"remote_side": "Category.id", "lazy": "selectin", "join_depth": 1}, ) diff --git a/backend/app/api/common/crud/utils.py b/backend/app/api/common/crud/utils.py index 8d051bd..c223a53 100644 --- a/backend/app/api/common/crud/utils.py +++ b/backend/app/api/common/crud/utils.py @@ -47,6 +47,8 @@ def add_relationship_options( """ # Get all relationships from the database model in one pass inspector: Mapper[Any] = inspect(model, raiseerr=True) + # HACK: Using SQLAlchemy internals to get relationship info. This sometimes causes runtime issues with circular model definitions. + # TODO: Fix this by finding a better way to get relationship info without using internals. all_db_rels = {rel.key: (getattr(model, rel.key), rel.uselist) for rel in inspector.relationships} # Determine which relationships are in scope (db ∩ schema) diff --git a/backend/app/api/data_collection/models.py b/backend/app/api/data_collection/models.py index 4df8c42..1261a22 100644 --- a/backend/app/api/data_collection/models.py +++ b/backend/app/api/data_collection/models.py @@ -124,7 +124,7 @@ class Product(ProductBase, TimeStampMixinBare, table=True): # Self-referential relationship for hierarchy parent_id: int | None = Field(default=None, foreign_key="product.id") - parent: Product | None = Relationship( + parent: Optional[Product] = Relationship( # noqa: UP045 # Using 'Optional' over Product | None to avoid issues with sqlmodel type detection back_populates="components", sa_relationship_kwargs={ "uselist": False, diff --git a/backend/uv.lock b/backend/uv.lock index 03d51ab..b05fc7c 100644 --- a/backend/uv.lock +++ b/backend/uv.lock @@ -75,15 +75,14 @@ wheels = [ [[package]] name = "anyio" -version = "4.11.0" +version = "4.12.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "idna" }, - { name = "sniffio" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/c6/78/7d432127c41b50bccba979505f272c16cbcadcc33645d5fa3a738110ae75/anyio-4.11.0.tar.gz", hash = "sha256:82a8d0b81e318cc5ce71a5f1f8b5c4e63619620b63141ef8c995fa0db95a57c4", size = 219094, upload-time = "2025-09-23T09:19:12.58Z" } +sdist = { url = "https://files.pythonhosted.org/packages/16/ce/8a777047513153587e5434fd752e89334ac33e379aa3497db860eeb60377/anyio-4.12.0.tar.gz", hash = "sha256:73c693b567b0c55130c104d0b43a9baf3aa6a31fc6110116509f27bf75e21ec0", size = 228266, upload-time = "2025-11-28T23:37:38.911Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/15/b3/9b1a8074496371342ec1e796a96f99c82c945a339cd81a8e73de28b4cf9e/anyio-4.11.0-py3-none-any.whl", hash = "sha256:0287e96f4d26d4149305414d4e3bc32f0dcd0862365a4bddea19d7a1ec38c4fc", size = 109097, upload-time = "2025-09-23T09:19:10.601Z" }, + { url = "https://files.pythonhosted.org/packages/7f/9c/36c5c37947ebfb8c7f22e0eb6e4d188ee2d53aa3880f3f2744fb894f0cb1/anyio-4.12.0-py3-none-any.whl", hash = "sha256:dad2376a628f98eeca4881fc56cd06affd18f659b17a747d3ff0307ced94b1bb", size = 113362, upload-time = "2025-11-28T23:36:57.897Z" }, ] [[package]] @@ -225,15 +224,15 @@ wheels = [ [[package]] name = "beautifulsoup4" -version = "4.14.2" +version = "4.14.3" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "soupsieve" }, { name = "typing-extensions" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/77/e9/df2358efd7659577435e2177bfa69cba6c33216681af51a707193dec162a/beautifulsoup4-4.14.2.tar.gz", hash = "sha256:2a98ab9f944a11acee9cc848508ec28d9228abfd522ef0fad6a02a72e0ded69e", size = 625822, upload-time = "2025-09-29T10:05:42.613Z" } +sdist = { url = "https://files.pythonhosted.org/packages/c3/b0/1c6a16426d389813b48d95e26898aff79abbde42ad353958ad95cc8c9b21/beautifulsoup4-4.14.3.tar.gz", hash = "sha256:6292b1c5186d356bba669ef9f7f051757099565ad9ada5dd630bd9de5fa7fb86", size = 627737, upload-time = "2025-11-30T15:08:26.084Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/94/fe/3aed5d0be4d404d12d36ab97e2f1791424d9ca39c2f754a6285d59a3b01d/beautifulsoup4-4.14.2-py3-none-any.whl", hash = "sha256:5ef6fa3a8cbece8488d66985560f97ed091e22bbc4e9c2338508a9d5de6d4515", size = 106392, upload-time = "2025-09-29T10:05:43.771Z" }, + { url = "https://files.pythonhosted.org/packages/1a/39/47f9197bdd44df24d67ac8893641e16f386c984a0619ef2ee4c51fbbc019/beautifulsoup4-4.14.3-py3-none-any.whl", hash = "sha256:0918bfe44902e6ad8d57732ba310582e98da931428d231a5ecb9e7c703a735bb", size = 107721, upload-time = "2025-11-30T15:08:24.087Z" }, ] [[package]] @@ -247,30 +246,30 @@ wheels = [ [[package]] name = "boto3" -version = "1.41.3" +version = "1.42.4" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "botocore" }, { name = "jmespath" }, { name = "s3transfer" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/90/30/1f1bfb34a97709b5d004d5c16ccac81a73ea6c5ce86ce75eaff0a75aee3f/boto3-1.41.3.tar.gz", hash = "sha256:8a89f3900a356879022c1600f72cbb3d8b85708f094d2d08a461bd193d0b07ca", size = 111614, upload-time = "2025-11-24T20:22:33.007Z" } +sdist = { url = "https://files.pythonhosted.org/packages/f3/31/246916eec4fc5ff7bebf7e75caf47ee4d72b37d4120b6943e3460956e618/boto3-1.42.4.tar.gz", hash = "sha256:65f0d98a3786ec729ba9b5f70448895b2d1d1f27949aa7af5cb4f39da341bbc4", size = 112826, upload-time = "2025-12-05T20:27:14.931Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/37/d3/56e8c147e369fdc1b5526584f87151ca1742949bf5e6ab7500d926107624/boto3-1.41.3-py3-none-any.whl", hash = "sha256:10a3f5a72e071c362f5aa8443bd949edc31b7494c48a315ccdab14b1c387a1fd", size = 139345, upload-time = "2025-11-24T20:22:30.601Z" }, + { url = "https://files.pythonhosted.org/packages/00/25/9ae819385aad79f524859f7179cecf8ac019b63ac8f150c51b250967f6db/boto3-1.42.4-py3-none-any.whl", hash = "sha256:0f4089e230d55f981d67376e48cefd41c3d58c7f694480f13288e6ff7b1fefbc", size = 140621, upload-time = "2025-12-05T20:27:12.803Z" }, ] [[package]] name = "botocore" -version = "1.41.3" +version = "1.42.4" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "jmespath" }, { name = "python-dateutil" }, { name = "urllib3" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/8c/e9/d6207e08f35280cb8755b316f0e0a0cd2e8405d1b849e847c26fb4e3e3a6/botocore-1.41.3.tar.gz", hash = "sha256:1c6ad338f445c9bf02e231bfa302239d60520ec6dd88ded3206b34dca100103c", size = 14658770, upload-time = "2025-11-24T20:22:21.929Z" } +sdist = { url = "https://files.pythonhosted.org/packages/5c/b7/dec048c124619b2702b5236c5fc9d8e5b0a87013529e9245dc49aaaf31ff/botocore-1.42.4.tar.gz", hash = "sha256:d4816023492b987a804f693c2d76fb751fdc8755d49933106d69e2489c4c0f98", size = 14848605, upload-time = "2025-12-05T20:27:02.919Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/9f/18/a0597e4491d3a725768162c48a4dd1e1a57323fdb40fca04a34e9a68ef93/botocore-1.41.3-py3-none-any.whl", hash = "sha256:fe2379b30cc726e9e44bf47c3834fe208b85f7eaa57b934ab05f305ca9d05a8b", size = 14328009, upload-time = "2025-11-24T20:22:17.618Z" }, + { url = "https://files.pythonhosted.org/packages/9b/a2/7b50f12a9c5a33cd85a5f23fdf78a0cbc445c0245c16051bb627f328be06/botocore-1.42.4-py3-none-any.whl", hash = "sha256:c3b091fd33809f187824b6434e518b889514ded5164cb379358367c18e8b0d7d", size = 14519938, upload-time = "2025-12-05T20:26:58.881Z" }, ] [[package]] @@ -599,7 +598,7 @@ wheels = [ [[package]] name = "fastapi" -version = "0.122.0" +version = "0.124.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "annotated-doc" }, @@ -607,9 +606,9 @@ dependencies = [ { name = "starlette" }, { name = "typing-extensions" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/b2/de/3ee97a4f6ffef1fb70bf20561e4f88531633bb5045dc6cebc0f8471f764d/fastapi-0.122.0.tar.gz", hash = "sha256:cd9b5352031f93773228af8b4c443eedc2ac2aa74b27780387b853c3726fb94b", size = 346436, upload-time = "2025-11-24T19:17:47.95Z" } +sdist = { url = "https://files.pythonhosted.org/packages/48/9c/11969bd3e3bc4aa3a711f83dd3720239d3565a934929c74fc32f6c9f3638/fastapi-0.124.0.tar.gz", hash = "sha256:260cd178ad75e6d259991f2fd9b0fee924b224850079df576a3ba604ce58f4e6", size = 357623, upload-time = "2025-12-06T13:11:35.692Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/7a/93/aa8072af4ff37b795f6bbf43dcaf61115f40f49935c7dbb180c9afc3f421/fastapi-0.122.0-py3-none-any.whl", hash = "sha256:a456e8915dfc6c8914a50d9651133bd47ec96d331c5b44600baa635538a30d67", size = 110671, upload-time = "2025-11-24T19:17:45.96Z" }, + { url = "https://files.pythonhosted.org/packages/4d/29/9e1e82e16e9a1763d3b55bfbe9b2fa39d7175a1fd97685c482fa402e111d/fastapi-0.124.0-py3-none-any.whl", hash = "sha256:91596bdc6dde303c318f06e8d2bc75eafb341fc793a0c9c92c0bc1db1ac52480", size = 112505, upload-time = "2025-12-06T13:11:34.392Z" }, ] [package.optional-dependencies] @@ -644,7 +643,7 @@ standard = [ [[package]] name = "fastapi-cloud-cli" -version = "0.5.1" +version = "0.6.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "fastar" }, @@ -656,9 +655,9 @@ dependencies = [ { name = "typer" }, { name = "uvicorn", extra = ["standard"] }, ] -sdist = { url = "https://files.pythonhosted.org/packages/cd/8d/cb1ae52121190eb75178b146652bfdce9296d2fd19aa30410ebb1fab3a63/fastapi_cloud_cli-0.5.1.tar.gz", hash = "sha256:5ed9591fda9ef5ed846c7fb937a06c491a00eef6d5bb656c84d82f47e500804b", size = 30746, upload-time = "2025-11-20T16:53:24.491Z" } +sdist = { url = "https://files.pythonhosted.org/packages/c2/dd/e5890bb4ee63f9d8988660b755490e346cf5769aaa7f5f3ced9afb9f090a/fastapi_cloud_cli-0.6.0.tar.gz", hash = "sha256:2c333fff2e4b93b9efbec7896ce3ffa3e77ce4cf3d8cb14e35b4f823dfddac02", size = 30579, upload-time = "2025-12-04T15:04:07.008Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/42/d6/b83f0801fd2c3f648e3696cdd2a1967b176f43c0c9db35c0350a67e7c141/fastapi_cloud_cli-0.5.1-py3-none-any.whl", hash = "sha256:1a28415b059b27af180a55a835ac2c9e924a66be88412d5649d4f91993d1a698", size = 23216, upload-time = "2025-11-20T16:53:23.119Z" }, + { url = "https://files.pythonhosted.org/packages/ac/2f/5ba9b5faa75067e30ff48e3c454263ebc2d2301d5509cfefe12cf9fc8156/fastapi_cloud_cli-0.6.0-py3-none-any.whl", hash = "sha256:b654890b5302c90d2f347b123a35186096328838a526316c470b6005cabd4983", size = 23215, upload-time = "2025-12-04T15:04:08.121Z" }, ] [[package]] @@ -693,16 +692,16 @@ dependencies = [ [[package]] name = "fastapi-pagination" -version = "0.15.0" +version = "0.15.2" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "fastapi" }, { name = "pydantic" }, { name = "typing-extensions" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/bc/db/8a3d097c491ad873574bd7295834ef89e16263ae9104855bbb5ee6d46e47/fastapi_pagination-0.15.0.tar.gz", hash = "sha256:11fe39cbe181ed3c18919b90faf6bfcbe40cb596aa9c52a98bbce85111a29a4f", size = 557472, upload-time = "2025-10-28T19:06:17.732Z" } +sdist = { url = "https://files.pythonhosted.org/packages/6a/8e/3f9b6980123a7003ca0fb0696f20a4308380f704603a600e6f0425f778c4/fastapi_pagination-0.15.2.tar.gz", hash = "sha256:e804014e853773a7c036b2e97379e79aab6715b8cb883d8ae251697d97b25223", size = 571283, upload-time = "2025-12-06T13:54:20.002Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/68/91/b835e07234170ba85473227aa107bcf1dc616ff6cb643c0bd9b8225a55f1/fastapi_pagination-0.15.0-py3-none-any.whl", hash = "sha256:ffef937e78903fcb6f356b8407ec1fb0620a06675087fa7d0c4e537a60aa0447", size = 52292, upload-time = "2025-10-28T19:06:16.371Z" }, + { url = "https://files.pythonhosted.org/packages/ea/db/9430508035b18d905e898deb91be21afbad9c8016b59e29d13879e8100c8/fastapi_pagination-0.15.2-py3-none-any.whl", hash = "sha256:f8763a2e1caafe9c2a10ac860d6403935c31a067ffd6e93e57811bfec9873d87", size = 56106, upload-time = "2025-12-06T13:54:18.643Z" }, ] [[package]] @@ -767,55 +766,55 @@ dependencies = [ [[package]] name = "fastar" -version = "0.7.0" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/d9/7e/0563141e374012f47eb0d219323378f4207d15d9939fa7aa0fa404d8613d/fastar-0.7.0.tar.gz", hash = "sha256:76739b48121cf8601ecc3ea9e87858362774b53cc1dd7e8332696b99c6ad2c27", size = 67917, upload-time = "2025-11-24T15:52:37.072Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/14/82/96043bd83b54f2074a7f47df7ad912b6de26b398a424580167a0d059b46e/fastar-0.7.0-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:d66c09da9ed60536326783becab08db4d4f478e12c0543e7ac750336e72b38e5", size = 705365, upload-time = "2025-11-24T15:51:14.945Z" }, - { url = "https://files.pythonhosted.org/packages/66/01/24f42e7693713c41b389aaa15c0f010ac84eeb9dd5e4e2e0336386b2cef6/fastar-0.7.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:4e443363617551be2e48f87a63f42ba1275c8f42094c6616168bd0512c9ed9b9", size = 627848, upload-time = "2025-11-24T15:51:00.295Z" }, - { url = "https://files.pythonhosted.org/packages/2e/5a/03d2589e2652506e73a8a85312852b5d3263ca348912fc39a396968009ff/fastar-0.7.0-cp313-cp313-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:5a6981f162ebf1148c08668e1ab0fa58f4a6b32a0a126545042a859d836e54ec", size = 867646, upload-time = "2025-11-24T15:50:30.874Z" }, - { url = "https://files.pythonhosted.org/packages/dd/81/ac6f2484f8919b642a45088d487089ac926f74d9b12f347e4ed2e3ebaf8e/fastar-0.7.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7605ce63582432f2bc6b5e59e569b818f5db74506d452be609537a5699cedc19", size = 763982, upload-time = "2025-11-24T15:49:31.069Z" }, - { url = "https://files.pythonhosted.org/packages/eb/77/0ab5991e97e882a90043f287ba08124b8b0a2af4e68e3e8e77cb6e9b09ab/fastar-0.7.0-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:9ae8c4dec44bac4a3e763d5993191962db1285525da61154b6bc158ebcd01ba4", size = 763680, upload-time = "2025-11-24T15:49:46.938Z" }, - { url = "https://files.pythonhosted.org/packages/b3/b4/0c269f4136278e0c652f7d6eca57e71104d02ba1fc3ebf7057a6c36e8339/fastar-0.7.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:abe4ff6fcc353618e395cceb760ae3a90d19686c2d67c9d6654ec0fa9d265395", size = 930118, upload-time = "2025-11-24T15:50:01.681Z" }, - { url = "https://files.pythonhosted.org/packages/70/11/f62a4b652534a5e4f3303b4124e9ca55864f77de9f74588643332f4e5caf/fastar-0.7.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7b54bbb9aa12b2c5550dfafedfe664088bc22a8acc4eebcc9dff7a1ca3048216", size = 820641, upload-time = "2025-11-24T15:50:15.622Z" }, - { url = "https://files.pythonhosted.org/packages/d6/c6/669c167472d31ea94caa5afa75227ef6f123e3be8474f56f9dad01c9b8d8/fastar-0.7.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f434f0a91235aec22a1d39714af3283ef768bb2de548e61ee4f3a74fb3504a2e", size = 820106, upload-time = "2025-11-24T15:50:45.978Z" }, - { url = "https://files.pythonhosted.org/packages/1d/7a/305c99ff3708fc3cb6bebbc2f6469d3c3c4f51119306691d0f57283da0d2/fastar-0.7.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:400e48ca94e5ed9a1f4d17dd8e74cbd9a978de4ba718f5610c73ba6172dcc59b", size = 985425, upload-time = "2025-11-24T15:51:31.58Z" }, - { url = "https://files.pythonhosted.org/packages/c7/c5/04ab4db328d0e3193cf9b1bbc3147f98cf09e1f99c24906789b929198fa8/fastar-0.7.0-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:94b11ba3d9d23fe612a4a612a62d7b2f18e2d7a1be2d5f94b938448a906436e9", size = 1038104, upload-time = "2025-11-24T15:51:49.085Z" }, - { url = "https://files.pythonhosted.org/packages/e6/72/e7c7d684efe1b92062096c29d0d5b38ca549beb5eb35336acf212a90ddc8/fastar-0.7.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:9610f6edb6fdb627491148e7071f725b4abffb8655554cad6a45637772f0795a", size = 1044294, upload-time = "2025-11-24T15:52:06.47Z" }, - { url = "https://files.pythonhosted.org/packages/e6/11/b2ad21f1b8ac20b6c4676e83f2dd3c5f70ff9a9926df60c3f4e36be8be08/fastar-0.7.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:db2373ebe1a699ce3ea34296ab85a22a572667aefd198ca6fa32fee5e69970fc", size = 993265, upload-time = "2025-11-24T15:52:24.049Z" }, - { url = "https://files.pythonhosted.org/packages/03/38/d44a7ea41c407d46c56f160fb870536e1dd9ba01c44b46d7091835ff1719/fastar-0.7.0-cp313-cp313-win32.whl", hash = "sha256:bcb4f04daa574108092abfba8c0f747e65910464671d5ab72e6f55d19f7e2a71", size = 455032, upload-time = "2025-11-24T15:53:03.244Z" }, - { url = "https://files.pythonhosted.org/packages/9d/65/d86c8d53b4f00bb7eed9c89eda2801d33930a8729dac72838807eb2d7314/fastar-0.7.0-cp313-cp313-win_amd64.whl", hash = "sha256:a577121830ba14acd70a8eccc7a0f815a78e9f01981bc9b71a005caa08f63afa", size = 489446, upload-time = "2025-11-24T15:52:50.877Z" }, - { url = "https://files.pythonhosted.org/packages/04/6d/12bc62cd7a425747efbba0755cbfd23015d592c3bf85753442ff1283bfc6/fastar-0.7.0-cp313-cp313-win_arm64.whl", hash = "sha256:b4e0ddd1fb513eac866eca22323dd28b2671aaa3facd10a854d3beef4933372b", size = 460203, upload-time = "2025-11-24T15:52:41.739Z" }, - { url = "https://files.pythonhosted.org/packages/3f/a5/a5eff2a7fe21026cce5fa3a175d88a23a34bca461cddeab87042c2c47e82/fastar-0.7.0-cp314-cp314-macosx_10_12_x86_64.whl", hash = "sha256:7cc47eeac659fed55f547b6c84fbd302726fab64de720c96d3ddcf0952535d0e", size = 705379, upload-time = "2025-11-24T15:51:16.497Z" }, - { url = "https://files.pythonhosted.org/packages/00/06/67228a6e1b32414afe79510ba1256b791541b8801d12660d6fbb203c88b7/fastar-0.7.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:f3139c8d48bdb2c2d79a42eb940efc20e67e1b9dd26798257b71f0d9f0083a5a", size = 627905, upload-time = "2025-11-24T15:51:01.523Z" }, - { url = "https://files.pythonhosted.org/packages/ea/11/753fd5b766d5b170d6d47ebb31aee87b95f5e5776e2661132aae68cae51a/fastar-0.7.0-cp314-cp314-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:f0e2c86b690116f50bd40c444fce6da000695e558a94e460d8b46eff6f23b26f", size = 868266, upload-time = "2025-11-24T15:50:32.119Z" }, - { url = "https://files.pythonhosted.org/packages/40/66/70a191f4d61df4bcda77e759bb840d3cdda796ff26628a454ca44ef58158/fastar-0.7.0-cp314-cp314-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1a698533c59125856e1c14978c589f933de312f066f2a15978f11030807ac535", size = 763815, upload-time = "2025-11-24T15:49:32.214Z" }, - { url = "https://files.pythonhosted.org/packages/d2/a0/72e7886ec7dd16e523522253ecf1862e422e43e3142de29052a562b6499d/fastar-0.7.0-cp314-cp314-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:240c546a20b6f8c1edfe0ab40ac6113cecea02380d6f59e6f9be3d1e079d0767", size = 763288, upload-time = "2025-11-24T15:49:48.082Z" }, - { url = "https://files.pythonhosted.org/packages/9c/b5/0d1cc3356bba8afad036e1808dc10ca76341cafd681a4479c98eb37d947f/fastar-0.7.0-cp314-cp314-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9f37e415192a27980377c0a0859275f178bfcd54c3b972f2f273bee1276a75f1", size = 929296, upload-time = "2025-11-24T15:50:02.957Z" }, - { url = "https://files.pythonhosted.org/packages/59/79/21aa7f864e2e3a1e7244475f864cd82d34b86aac73b1f54c8eb32778c34e/fastar-0.7.0-cp314-cp314-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c865328d56525fc71441f848dcf3d9d20855f3f619c4dca99ecdd932c7e0160c", size = 820264, upload-time = "2025-11-24T15:50:16.91Z" }, - { url = "https://files.pythonhosted.org/packages/de/91/c576af124855de6ffbb48511625ff51653029ba0fde8d3ef6913cf0f968c/fastar-0.7.0-cp314-cp314-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4a9e11313551a10032a6cd97c27434fde6a858794257d709040a7b351b586fe4", size = 819896, upload-time = "2025-11-24T15:50:47.264Z" }, - { url = "https://files.pythonhosted.org/packages/bf/f1/3b3ada104c1924f0a78bc66f89a1bca4957c26e7ad5befaaa2f4701af7bb/fastar-0.7.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:f0532d5ef74d0262f998150a7a2e5d8e51f411d400f655c5a83eb8775fc8d5ab", size = 985552, upload-time = "2025-11-24T15:51:32.859Z" }, - { url = "https://files.pythonhosted.org/packages/c1/1f/1f6424bc8bc2cdc932b16670433b4368b09bf32872b9975c1c1cba02891e/fastar-0.7.0-cp314-cp314-musllinux_1_2_armv7l.whl", hash = "sha256:008930f99c7602da1ec820b165724621df8d6ca327d8877bd46f3600c848aae0", size = 1038126, upload-time = "2025-11-24T15:51:50.93Z" }, - { url = "https://files.pythonhosted.org/packages/09/8e/f4c4db8de826ea9ff134c6bc9bf2aaf1fc977eac9153b3356f6d181a3149/fastar-0.7.0-cp314-cp314-musllinux_1_2_i686.whl", hash = "sha256:6965219b0dbb897557617400ef3a21601a08cfac0ba0e0dfcdbde19a13e0769d", size = 1044273, upload-time = "2025-11-24T15:52:08.061Z" }, - { url = "https://files.pythonhosted.org/packages/71/c6/b1af54e78ea288144bbb1e2e7b2ad56342285029bb2b68f84bf8c8713d70/fastar-0.7.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:bcf277df3c357db68b422944aa3717aff6178c797c4c64711437a81fc2271552", size = 993779, upload-time = "2025-11-24T15:52:25.818Z" }, - { url = "https://files.pythonhosted.org/packages/7f/25/f3043ebd1e19bb262a0ff7a2f2a07945e5e912ace308202e0f89b1d7f96c/fastar-0.7.0-cp314-cp314-win32.whl", hash = "sha256:12cff2cc933e4a74e56c591b1dda06cdae23c0718d07cdb696701e3596a23c5e", size = 455711, upload-time = "2025-11-24T15:53:05.198Z" }, - { url = "https://files.pythonhosted.org/packages/f9/13/b691a58b3cb1567c95b60032009549ccebcefabeceb6c3c4a6a3bddf9253/fastar-0.7.0-cp314-cp314-win_amd64.whl", hash = "sha256:99e7d8928b1d7092053e40d9132a246b4ed8156fa3cecad3def3ea5b2fd24027", size = 489799, upload-time = "2025-11-24T15:52:52.552Z" }, - { url = "https://files.pythonhosted.org/packages/14/0e/7c907f00cb71abc56b1dc3d4aaeaee85061feb955f014ac75af9933f7895/fastar-0.7.0-cp314-cp314-win_arm64.whl", hash = "sha256:cedf4212173f502fc61883a76142ccad9d9cbd2b61f0704d36b7bf6a17df311d", size = 460748, upload-time = "2025-11-24T15:52:43.105Z" }, - { url = "https://files.pythonhosted.org/packages/d5/97/a4cc30a5a962fe23e0b21937fb99ca5a267aa6dee1e3dd72df853a758cb0/fastar-0.7.0-cp314-cp314t-macosx_10_12_x86_64.whl", hash = "sha256:8484b7c55d77874d272c236869855021376722d9c51ff5747ad8b42896b6c4df", size = 704853, upload-time = "2025-11-24T15:51:17.708Z" }, - { url = "https://files.pythonhosted.org/packages/0e/4e/02312660f6027f5ad2bb75e16ea5f2a9f89439e0a502c754b4d8eff0beb1/fastar-0.7.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:514947a8d057e111a9ffd5943ce740d4186f9084562b44cc9875fa39b1a2e109", size = 626773, upload-time = "2025-11-24T15:51:02.835Z" }, - { url = "https://files.pythonhosted.org/packages/61/c7/e04147583ca17fbe6970dc20083b2a38e2ffc2e4e4f76d4e7640c0dbfa49/fastar-0.7.0-cp314-cp314t-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:1b71a5eb92f0c730798896e512a75f96b267bfd610b1148a8348dbcd565dea6c", size = 867940, upload-time = "2025-11-24T15:50:33.402Z" }, - { url = "https://files.pythonhosted.org/packages/0c/c1/8316762971c117b8043202d531320b3ebb740fc02bc5208e8a734e7d5b3c/fastar-0.7.0-cp314-cp314t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3fce1bfa66ceb0e96b6eee89f9efb3250929df22fdfdab8a08735c09b50cfe0c", size = 762971, upload-time = "2025-11-24T15:49:33.406Z" }, - { url = "https://files.pythonhosted.org/packages/62/07/d394742e2892818d52f391d40d24d60ef9a214865fef4a9e55339022d990/fastar-0.7.0-cp314-cp314t-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:9632c25c6a85f5eab589437bc6bfbb5461f93b799882e3c750b6f86448ad9ede", size = 762796, upload-time = "2025-11-24T15:49:49.187Z" }, - { url = "https://files.pythonhosted.org/packages/fd/7d/bb3ab1f10500c765833fc2c931d11e3fa2dae5e42e0451af759a89b5ef57/fastar-0.7.0-cp314-cp314t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c45e2422cca8fd3b5509edf8db44cceeb0d4eed3cc12d90d91d0e1ea08034258", size = 929810, upload-time = "2025-11-24T15:50:04.166Z" }, - { url = "https://files.pythonhosted.org/packages/0e/cb/5e42841f52a65b02796bae27a484c23375eabb07750c88face71d82e3717/fastar-0.7.0-cp314-cp314t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:99836a00322c39689f7d9772662a7b5ee62b3ec1a344ad693f9c162226775039", size = 819858, upload-time = "2025-11-24T15:50:18.395Z" }, - { url = "https://files.pythonhosted.org/packages/0e/7e/e268246b4f38421c84bb42048311fe269feacd8e1d5a6cac48b0f64f8044/fastar-0.7.0-cp314-cp314t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bcd2756c2ae9f1374619207b98d1143c9865910c9fecd094c8656b95c5a9a45b", size = 819585, upload-time = "2025-11-24T15:50:48.488Z" }, - { url = "https://files.pythonhosted.org/packages/50/1f/3d05285c98d3245944540aec77364618e0f508d0c4bbf311a7762b644c35/fastar-0.7.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:3ced9eddb9adcf8b27361c180f6bdfbc8cb2e36479aa00e4e7e78c17c7768efc", size = 984526, upload-time = "2025-11-24T15:51:34.988Z" }, - { url = "https://files.pythonhosted.org/packages/3b/e0/34c114c7016901cac190b18871212f7433871470d1ba1c92ed891ae7d85f/fastar-0.7.0-cp314-cp314t-musllinux_1_2_armv7l.whl", hash = "sha256:39ba9256790a13289f986c07c73bbc075647337008f1faea104e5e013a17ee70", size = 1037651, upload-time = "2025-11-24T15:51:52.286Z" }, - { url = "https://files.pythonhosted.org/packages/39/7e/371ddb9ed65733aa51370bf774234a142d315f841538c7af7fd959cc5c5e/fastar-0.7.0-cp314-cp314t-musllinux_1_2_i686.whl", hash = "sha256:f445e1acb722e228364c2d8012e6be1b46502062e3638cbe5b98c7c2d6bebb72", size = 1044369, upload-time = "2025-11-24T15:52:10.031Z" }, - { url = "https://files.pythonhosted.org/packages/92/0f/0d6a9fab23ba227f79f2e728aef274daf8fe8148c7cbd58022b752af7aeb/fastar-0.7.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:1e9b1e0cb44b0d43dae153d80e519b04aa0bc4c98240d4a2d85c7ede13b37aae", size = 993840, upload-time = "2025-11-24T15:52:27.41Z" }, - { url = "https://files.pythonhosted.org/packages/a1/e2/df1c197e4bfca4c23114ab1251c70b70a9a7a427a1ab73bef2dd9750056a/fastar-0.7.0-cp314-cp314t-win32.whl", hash = "sha256:44956db52c2d6afa5a26a9d2c8e926eb55902a9151ab0ce0bfa3023479db4800", size = 454334, upload-time = "2025-11-24T15:53:09.556Z" }, - { url = "https://files.pythonhosted.org/packages/ee/b0/e2b55bb0b521ac9abada459cd2bce8488b36525f913af536bf1dec90dc03/fastar-0.7.0-cp314-cp314t-win_amd64.whl", hash = "sha256:cfd514372850774e8651c4e98b2b81bba0ae00f2e1dfa666da89ea5e02d1e61a", size = 489047, upload-time = "2025-11-24T15:52:57.327Z" }, - { url = "https://files.pythonhosted.org/packages/f3/c1/ea150ccd09a6247a65e162596db393fb642ad92bf7d2af9f7e4ae58233da/fastar-0.7.0-cp314-cp314t-win_arm64.whl", hash = "sha256:96a366565662567ba1b7c1d2f72e02584575a33b220c361707e168270b68d4e4", size = 459525, upload-time = "2025-11-24T15:52:44.492Z" }, +version = "0.8.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/69/e7/f89d54fb04104114dd0552836dc2b47914f416cc0e200b409dd04a33de5e/fastar-0.8.0.tar.gz", hash = "sha256:f4d4d68dbf1c4c2808f0e730fac5843493fc849f70fe3ad3af60dfbaf68b9a12", size = 68524, upload-time = "2025-11-26T02:36:00.72Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/d1/a5/79ecba3646e22d03eef1a66fb7fc156567213e2e4ab9faab3bbd4489e483/fastar-0.8.0-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:a3253a06845462ca2196024c7a18f5c0ba4de1532ab1c4bad23a40b332a06a6a", size = 706112, upload-time = "2025-11-26T02:34:39.237Z" }, + { url = "https://files.pythonhosted.org/packages/0a/03/4f883bce878218a8676c2d7ca09b50c856a5470bb3b7f63baf9521ea6995/fastar-0.8.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:5cbeb3ebfa0980c68ff8b126295cc6b208ccd81b638aebc5a723d810a7a0e5d2", size = 628954, upload-time = "2025-11-26T02:34:23.705Z" }, + { url = "https://files.pythonhosted.org/packages/4f/f1/892e471f156b03d10ba48ace9384f5a896702a54506137462545f38e40b8/fastar-0.8.0-cp313-cp313-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:1c0d5956b917daac77d333d48b3f0f3ff927b8039d5b32d8125462782369f761", size = 868685, upload-time = "2025-11-26T02:33:53.077Z" }, + { url = "https://files.pythonhosted.org/packages/39/ba/e24915045852e30014ec6840446975c03f4234d1c9270394b51d3ad18394/fastar-0.8.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:27b404db2b786b65912927ce7f3790964a4bcbde42cdd13091b82a89cd655e1c", size = 765044, upload-time = "2025-11-26T02:32:48.187Z" }, + { url = "https://files.pythonhosted.org/packages/14/2c/1aa11ac21a99984864c2fca4994e094319ff3a2046e7a0343c39317bd5b9/fastar-0.8.0-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:0902fc89dcf1e7f07b8563032a4159fe2b835e4c16942c76fd63451d0e5f76a3", size = 764322, upload-time = "2025-11-26T02:33:03.859Z" }, + { url = "https://files.pythonhosted.org/packages/ba/f0/4b91902af39fe2d3bae7c85c6d789586b9fbcf618d7fdb3d37323915906d/fastar-0.8.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:069347e2f0f7a8b99bbac8cd1bc0e06c7b4a31dc964fc60d84b95eab3d869dc1", size = 931016, upload-time = "2025-11-26T02:33:19.902Z" }, + { url = "https://files.pythonhosted.org/packages/c9/97/8fc43a5a9c0a2dc195730f6f7a0f367d171282cd8be2511d0e87c6d2dad0/fastar-0.8.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7fd135306f6bfe9a835918280e0eb440b70ab303e0187d90ab51ca86e143f70d", size = 821308, upload-time = "2025-11-26T02:33:34.664Z" }, + { url = "https://files.pythonhosted.org/packages/0c/e9/058615b63a7fd27965e8c5966f393ed0c169f7ff5012e1674f21684de3ba/fastar-0.8.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:78d06d6897f43c27154b5f2d0eb930a43a81b7eec73f6f0b0114814d4a10ab38", size = 821171, upload-time = "2025-11-26T02:34:08.498Z" }, + { url = "https://files.pythonhosted.org/packages/ca/cf/69e16a17961570a755c37ffb5b5aa7610d2e77807625f537989da66f2a9d/fastar-0.8.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:a922f8439231fa0c32b15e8d70ff6d415619b9d40492029dabbc14a0c53b5f18", size = 986227, upload-time = "2025-11-26T02:34:55.06Z" }, + { url = "https://files.pythonhosted.org/packages/fb/83/2100192372e59b56f4ace37d7d9cabda511afd71b5febad1643d1c334271/fastar-0.8.0-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:a739abd51eb766384b4caff83050888e80cd75bbcfec61e6d1e64875f94e4a40", size = 1039395, upload-time = "2025-11-26T02:35:12.166Z" }, + { url = "https://files.pythonhosted.org/packages/75/15/cdd03aca972f55872efbb7cf7540c3fa7b97a75d626303a3ea46932163dc/fastar-0.8.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:5a65f419d808b23ac89d5cd1b13a2f340f15bc5d1d9af79f39fdb77bba48ff1b", size = 1044766, upload-time = "2025-11-26T02:35:29.62Z" }, + { url = "https://files.pythonhosted.org/packages/3d/29/945e69e4e2652329ace545999334ec31f1431fbae3abb0105587e11af2ae/fastar-0.8.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:7bb2ae6c0cce58f0db1c9f20495e7557cca2c1ee9c69bbd90eafd54f139171c5", size = 994740, upload-time = "2025-11-26T02:35:47.887Z" }, + { url = "https://files.pythonhosted.org/packages/4b/5d/dbfe28f8cd1eb484bba0c62e5259b2cf6fea229d6ef43e05c06b5a78c034/fastar-0.8.0-cp313-cp313-win32.whl", hash = "sha256:b28753e0d18a643272597cb16d39f1053842aa43131ad3e260c03a2417d38401", size = 455990, upload-time = "2025-11-26T02:36:28.502Z" }, + { url = "https://files.pythonhosted.org/packages/e1/01/e965740bd36e60ef4c5aa2cbe42b6c4eb1dc3551009238a97c2e5e96bd23/fastar-0.8.0-cp313-cp313-win_amd64.whl", hash = "sha256:620e5d737dce8321d49a5ebb7997f1fd0047cde3512082c27dc66d6ac8c1927a", size = 490227, upload-time = "2025-11-26T02:36:14.363Z" }, + { url = "https://files.pythonhosted.org/packages/dd/10/c99202719b83e5249f26902ae53a05aea67d840eeb242019322f20fc171c/fastar-0.8.0-cp313-cp313-win_arm64.whl", hash = "sha256:c4c4bd08df563120cd33e854fe0a93b81579e8571b11f9b7da9e84c37da2d6b6", size = 461078, upload-time = "2025-11-26T02:36:04.94Z" }, + { url = "https://files.pythonhosted.org/packages/96/4a/9573b87a0ef07580ed111e7230259aec31bb33ca3667963ebee77022ec61/fastar-0.8.0-cp314-cp314-macosx_10_12_x86_64.whl", hash = "sha256:50b36ce654ba44b0e13fae607ae17ee6e1597b69f71df1bee64bb8328d881dfc", size = 706041, upload-time = "2025-11-26T02:34:40.638Z" }, + { url = "https://files.pythonhosted.org/packages/4a/19/f95444a1d4f375333af49300aa75ee93afa3335c0e40fda528e460ed859c/fastar-0.8.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:63a892762683d7ab00df0227d5ea9677c62ff2cde9b875e666c0be569ed940f3", size = 628617, upload-time = "2025-11-26T02:34:24.893Z" }, + { url = "https://files.pythonhosted.org/packages/b3/c9/b51481b38b7e3f16ef2b9e233b1a3623386c939d745d6e41bbd389eaae30/fastar-0.8.0-cp314-cp314-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:4ae6a145c1bff592644bde13f2115e0239f4b7babaf506d14e7d208483cf01a5", size = 869299, upload-time = "2025-11-26T02:33:54.274Z" }, + { url = "https://files.pythonhosted.org/packages/bf/02/3ba1267ee5ba7314e29c431cf82eaa68586f2c40cdfa08be3632b7d07619/fastar-0.8.0-cp314-cp314-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6ae0ff7c0a1c7e1428404b81faee8aebef466bfd0be25bfe4dabf5d535c68741", size = 764667, upload-time = "2025-11-26T02:32:49.606Z" }, + { url = "https://files.pythonhosted.org/packages/1b/84/bf33530fd015b5d7c2cc69e0bce4a38d736754a6955487005aab1af6adcd/fastar-0.8.0-cp314-cp314-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:dbfd87dbd217b45c898b2dbcd0169aae534b2c1c5cbe3119510881f6a5ac8ef5", size = 763993, upload-time = "2025-11-26T02:33:05.782Z" }, + { url = "https://files.pythonhosted.org/packages/da/e0/9564d24e7cea6321a8d921c6d2a457044a476ef197aa4708e179d3d97f0d/fastar-0.8.0-cp314-cp314-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9a5abd99fcba83ef28c8fe6ae2927edc79053db43a0457a962ed85c9bf150d37", size = 930153, upload-time = "2025-11-26T02:33:21.53Z" }, + { url = "https://files.pythonhosted.org/packages/35/b1/6f57fcd8d6e192cfebf97e58eb27751640ad93784c857b79039e84387b51/fastar-0.8.0-cp314-cp314-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:91d4c685620c3a9d6b5ae091dbabab4f98b20049b7ecc7976e19cc9016c0d5d6", size = 821177, upload-time = "2025-11-26T02:33:35.839Z" }, + { url = "https://files.pythonhosted.org/packages/b3/78/9e004ea9f3aa7466f5ddb6f9518780e1d2f0ed3ca55f093632982598bace/fastar-0.8.0-cp314-cp314-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f77c2f2cad76e9dc7b6701297adb1eba87d0485944b416fc2ccf5516c01219a3", size = 820652, upload-time = "2025-11-26T02:34:09.776Z" }, + { url = "https://files.pythonhosted.org/packages/42/95/b604ed536544005c9f1aee7c4c74b00150db3d8d535cd8232dc20f947063/fastar-0.8.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:e7f07c4a3dada7757a8fc430a5b4a29e6ef696d2212747213f57086ffd970316", size = 985961, upload-time = "2025-11-26T02:34:56.401Z" }, + { url = "https://files.pythonhosted.org/packages/f2/7b/fa9d4d96a5d494bdb8699363bb9de8178c0c21a02e1d89cd6f913d127018/fastar-0.8.0-cp314-cp314-musllinux_1_2_armv7l.whl", hash = "sha256:90c0c3fe55105c0aed8a83135dbdeb31e683455dbd326a1c48fa44c378b85616", size = 1039316, upload-time = "2025-11-26T02:35:13.807Z" }, + { url = "https://files.pythonhosted.org/packages/4e/f9/8462789243bc3f33e8401378ec6d54de4e20cfa60c96a0e15e3e9d1389bb/fastar-0.8.0-cp314-cp314-musllinux_1_2_i686.whl", hash = "sha256:fb9ee51e5bffe0dab3d3126d3a4fac8d8f7235cedcb4b8e74936087ce1c157f3", size = 1045028, upload-time = "2025-11-26T02:35:31.079Z" }, + { url = "https://files.pythonhosted.org/packages/a5/71/9abb128777e616127194b509e98fcda3db797d76288c1a8c23dd22afc14f/fastar-0.8.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:e380b1e8d30317f52406c43b11e98d11e1d68723bbd031e18049ea3497b59a6d", size = 994677, upload-time = "2025-11-26T02:35:49.391Z" }, + { url = "https://files.pythonhosted.org/packages/de/c1/b81b3f194853d7ad232a67a1d768f5f51a016f165cfb56cb31b31bbc6177/fastar-0.8.0-cp314-cp314-win32.whl", hash = "sha256:1c4ffc06e9c4a8ca498c07e094670d8d8c0d25b17ca6465b9774da44ea997ab1", size = 456687, upload-time = "2025-11-26T02:36:30.205Z" }, + { url = "https://files.pythonhosted.org/packages/cb/87/9e0cd4768a98181d56f0cdbab2363404cc15deb93f4aad3b99cd2761bbaa/fastar-0.8.0-cp314-cp314-win_amd64.whl", hash = "sha256:5517a8ad4726267c57a3e0e2a44430b782e00b230bf51c55b5728e758bb3a692", size = 490578, upload-time = "2025-11-26T02:36:16.218Z" }, + { url = "https://files.pythonhosted.org/packages/aa/1e/580a76cf91847654f2ad6520e956e93218f778540975bc4190d363f709e2/fastar-0.8.0-cp314-cp314-win_arm64.whl", hash = "sha256:58030551046ff4a8616931e52a36c83545ff05996db5beb6e0cd2b7e748aa309", size = 461473, upload-time = "2025-11-26T02:36:06.373Z" }, + { url = "https://files.pythonhosted.org/packages/58/4c/bdb5c6efe934f68708529c8c9d4055ebef5c4be370621966438f658b29bd/fastar-0.8.0-cp314-cp314t-macosx_10_12_x86_64.whl", hash = "sha256:1e7d29b6bfecb29db126a08baf3c04a5ab667f6cea2b7067d3e623a67729c4a6", size = 705570, upload-time = "2025-11-26T02:34:42.01Z" }, + { url = "https://files.pythonhosted.org/packages/6d/78/f01ac7e71d5a37621bd13598a26e948a12b85ca8042f7ee1a0a8c9f59cda/fastar-0.8.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:05eb7b96940f9526b485f1d0b02393839f0f61cac4b1f60024984f8b326d2640", size = 627761, upload-time = "2025-11-26T02:34:26.152Z" }, + { url = "https://files.pythonhosted.org/packages/06/45/6df0ecda86ea9d2e95053c1a655d153dee55fc121b6e13ea6d1e246a50b6/fastar-0.8.0-cp314-cp314t-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:619352d8ac011794e2345c462189dc02ba634750d23cd9d86a9267dd71b1f278", size = 869414, upload-time = "2025-11-26T02:33:55.618Z" }, + { url = "https://files.pythonhosted.org/packages/b2/72/486421f5a8c0c377cc82e7a50c8a8ea899a6ec2aa72bde8f09fb667a2dc8/fastar-0.8.0-cp314-cp314t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:74ebfecef3fe6d7a90355fac1402fd30636988332a1d33f3e80019a10782bb24", size = 763863, upload-time = "2025-11-26T02:32:51.051Z" }, + { url = "https://files.pythonhosted.org/packages/d4/64/39f654dbb41a3867fb1f2c8081c014d8f1d32ea10585d84cacbef0b32995/fastar-0.8.0-cp314-cp314t-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:2975aca5a639e26a3ab0d23b4b0628d6dd6d521146c3c11486d782be621a35aa", size = 763065, upload-time = "2025-11-26T02:33:07.274Z" }, + { url = "https://files.pythonhosted.org/packages/4e/bd/c011a34fb3534c4c3301f7c87c4ffd7e47f6113c904c092ddc8a59a303ea/fastar-0.8.0-cp314-cp314t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:afc438eaed8ff0dcdd9308268be5cb38c1db7e94c3ccca7c498ca13a4a4535a3", size = 930530, upload-time = "2025-11-26T02:33:23.117Z" }, + { url = "https://files.pythonhosted.org/packages/55/9d/aa6e887a7033c571b1064429222bbe09adc9a3c1e04f3d1788ba5838ebd5/fastar-0.8.0-cp314-cp314t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:6ced0a5399cc0a84a858ef0a31ca2d0c24d3bbec4bcda506a9192d8119f3590a", size = 820572, upload-time = "2025-11-26T02:33:37.542Z" }, + { url = "https://files.pythonhosted.org/packages/ad/9c/7a3a2278a1052e1a5d98646de7c095a00cffd2492b3b84ce730e2f1cd93a/fastar-0.8.0-cp314-cp314t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ec9b23da8c4c039da3fe2e358973c66976a0c8508aa06d6626b4403cb5666c19", size = 820649, upload-time = "2025-11-26T02:34:11.108Z" }, + { url = "https://files.pythonhosted.org/packages/02/9e/d38edc1f4438cd047e56137c26d94783ffade42e1b3bde620ccf17b771ef/fastar-0.8.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:dfba078fcd53478032fd0ceed56960ec6b7ff0511cfc013a8a3a4307e3a7bac4", size = 985653, upload-time = "2025-11-26T02:34:57.884Z" }, + { url = "https://files.pythonhosted.org/packages/69/d9/2147d0c19757e165cd62d41cec3f7b38fad2ad68ab784978b5f81716c7ea/fastar-0.8.0-cp314-cp314t-musllinux_1_2_armv7l.whl", hash = "sha256:ade56c94c14be356d295fecb47a3fcd473dd43a8803ead2e2b5b9e58feb6dcfa", size = 1038140, upload-time = "2025-11-26T02:35:15.778Z" }, + { url = "https://files.pythonhosted.org/packages/7f/1d/ec4c717ffb8a308871e9602ec3197d957e238dc0227127ac573ec9bca952/fastar-0.8.0-cp314-cp314t-musllinux_1_2_i686.whl", hash = "sha256:e48d938f9366db5e59441728f70b7f6c1ccfab7eff84f96f9b7e689b07786c52", size = 1045195, upload-time = "2025-11-26T02:35:32.865Z" }, + { url = "https://files.pythonhosted.org/packages/6a/9f/637334dc8c8f3bb391388b064ae13f0ad9402bc5a6c3e77b8887d0c31921/fastar-0.8.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:79c441dc1482ff51a54fb3f57ae6f7bb3d2cff88fa2cc5d196c519f8aab64a56", size = 994686, upload-time = "2025-11-26T02:35:51.392Z" }, + { url = "https://files.pythonhosted.org/packages/c9/e2/dfa19a4b260b8ab3581b7484dcb80c09b25324f4daa6b6ae1c7640d1607a/fastar-0.8.0-cp314-cp314t-win32.whl", hash = "sha256:187f61dc739afe45ac8e47ed7fd1adc45d52eac110cf27d579155720507d6fbe", size = 455767, upload-time = "2025-11-26T02:36:34.758Z" }, + { url = "https://files.pythonhosted.org/packages/51/47/df65c72afc1297797b255f90c4778b5d6f1f0f80282a134d5ab610310ed9/fastar-0.8.0-cp314-cp314t-win_amd64.whl", hash = "sha256:40e9d763cf8bf85ce2fa256e010aa795c0fe3d3bd1326d5c3084e6ce7857127e", size = 489971, upload-time = "2025-11-26T02:36:22.081Z" }, + { url = "https://files.pythonhosted.org/packages/85/11/0aa8455af26f0ae89e42be67f3a874255ee5d7f0f026fc86e8d56f76b428/fastar-0.8.0-cp314-cp314t-win_arm64.whl", hash = "sha256:e59673307b6a08210987059a2bdea2614fe26e3335d0e5d1a3d95f49a05b1418", size = 460467, upload-time = "2025-11-26T02:36:07.978Z" }, ] [[package]] @@ -900,30 +899,33 @@ wheels = [ [[package]] name = "greenlet" -version = "3.2.4" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/03/b8/704d753a5a45507a7aab61f18db9509302ed3d0a27ac7e0359ec2905b1a6/greenlet-3.2.4.tar.gz", hash = "sha256:0dca0d95ff849f9a364385f36ab49f50065d76964944638be9691e1832e9f86d", size = 188260, upload-time = "2025-08-07T13:24:33.51Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/49/e8/58c7f85958bda41dafea50497cbd59738c5c43dbbea5ee83d651234398f4/greenlet-3.2.4-cp313-cp313-macosx_11_0_universal2.whl", hash = "sha256:1a921e542453fe531144e91e1feedf12e07351b1cf6c9e8a3325ea600a715a31", size = 272814, upload-time = "2025-08-07T13:15:50.011Z" }, - { url = "https://files.pythonhosted.org/packages/62/dd/b9f59862e9e257a16e4e610480cfffd29e3fae018a68c2332090b53aac3d/greenlet-3.2.4-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:cd3c8e693bff0fff6ba55f140bf390fa92c994083f838fece0f63be121334945", size = 641073, upload-time = "2025-08-07T13:42:57.23Z" }, - { url = "https://files.pythonhosted.org/packages/f7/0b/bc13f787394920b23073ca3b6c4a7a21396301ed75a655bcb47196b50e6e/greenlet-3.2.4-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:710638eb93b1fa52823aa91bf75326f9ecdfd5e0466f00789246a5280f4ba0fc", size = 655191, upload-time = "2025-08-07T13:45:29.752Z" }, - { url = "https://files.pythonhosted.org/packages/f2/d6/6adde57d1345a8d0f14d31e4ab9c23cfe8e2cd39c3baf7674b4b0338d266/greenlet-3.2.4-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:c5111ccdc9c88f423426df3fd1811bfc40ed66264d35aa373420a34377efc98a", size = 649516, upload-time = "2025-08-07T13:53:16.314Z" }, - { url = "https://files.pythonhosted.org/packages/7f/3b/3a3328a788d4a473889a2d403199932be55b1b0060f4ddd96ee7cdfcad10/greenlet-3.2.4-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:d76383238584e9711e20ebe14db6c88ddcedc1829a9ad31a584389463b5aa504", size = 652169, upload-time = "2025-08-07T13:18:32.861Z" }, - { url = "https://files.pythonhosted.org/packages/ee/43/3cecdc0349359e1a527cbf2e3e28e5f8f06d3343aaf82ca13437a9aa290f/greenlet-3.2.4-cp313-cp313-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:23768528f2911bcd7e475210822ffb5254ed10d71f4028387e5a99b4c6699671", size = 610497, upload-time = "2025-08-07T13:18:31.636Z" }, - { url = "https://files.pythonhosted.org/packages/b8/19/06b6cf5d604e2c382a6f31cafafd6f33d5dea706f4db7bdab184bad2b21d/greenlet-3.2.4-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:00fadb3fedccc447f517ee0d3fd8fe49eae949e1cd0f6a611818f4f6fb7dc83b", size = 1121662, upload-time = "2025-08-07T13:42:41.117Z" }, - { url = "https://files.pythonhosted.org/packages/a2/15/0d5e4e1a66fab130d98168fe984c509249c833c1a3c16806b90f253ce7b9/greenlet-3.2.4-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:d25c5091190f2dc0eaa3f950252122edbbadbb682aa7b1ef2f8af0f8c0afefae", size = 1149210, upload-time = "2025-08-07T13:18:24.072Z" }, - { url = "https://files.pythonhosted.org/packages/1c/53/f9c440463b3057485b8594d7a638bed53ba531165ef0ca0e6c364b5cc807/greenlet-3.2.4-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:6e343822feb58ac4d0a1211bd9399de2b3a04963ddeec21530fc426cc121f19b", size = 1564759, upload-time = "2025-11-04T12:42:19.395Z" }, - { url = "https://files.pythonhosted.org/packages/47/e4/3bb4240abdd0a8d23f4f88adec746a3099f0d86bfedb623f063b2e3b4df0/greenlet-3.2.4-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:ca7f6f1f2649b89ce02f6f229d7c19f680a6238af656f61e0115b24857917929", size = 1634288, upload-time = "2025-11-04T12:42:21.174Z" }, - { url = "https://files.pythonhosted.org/packages/0b/55/2321e43595e6801e105fcfdee02b34c0f996eb71e6ddffca6b10b7e1d771/greenlet-3.2.4-cp313-cp313-win_amd64.whl", hash = "sha256:554b03b6e73aaabec3745364d6239e9e012d64c68ccd0b8430c64ccc14939a8b", size = 299685, upload-time = "2025-08-07T13:24:38.824Z" }, - { url = "https://files.pythonhosted.org/packages/22/5c/85273fd7cc388285632b0498dbbab97596e04b154933dfe0f3e68156c68c/greenlet-3.2.4-cp314-cp314-macosx_11_0_universal2.whl", hash = "sha256:49a30d5fda2507ae77be16479bdb62a660fa51b1eb4928b524975b3bde77b3c0", size = 273586, upload-time = "2025-08-07T13:16:08.004Z" }, - { url = "https://files.pythonhosted.org/packages/d1/75/10aeeaa3da9332c2e761e4c50d4c3556c21113ee3f0afa2cf5769946f7a3/greenlet-3.2.4-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:299fd615cd8fc86267b47597123e3f43ad79c9d8a22bebdce535e53550763e2f", size = 686346, upload-time = "2025-08-07T13:42:59.944Z" }, - { url = "https://files.pythonhosted.org/packages/c0/aa/687d6b12ffb505a4447567d1f3abea23bd20e73a5bed63871178e0831b7a/greenlet-3.2.4-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:c17b6b34111ea72fc5a4e4beec9711d2226285f0386ea83477cbb97c30a3f3a5", size = 699218, upload-time = "2025-08-07T13:45:30.969Z" }, - { url = "https://files.pythonhosted.org/packages/dc/8b/29aae55436521f1d6f8ff4e12fb676f3400de7fcf27fccd1d4d17fd8fecd/greenlet-3.2.4-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:b4a1870c51720687af7fa3e7cda6d08d801dae660f75a76f3845b642b4da6ee1", size = 694659, upload-time = "2025-08-07T13:53:17.759Z" }, - { url = "https://files.pythonhosted.org/packages/92/2e/ea25914b1ebfde93b6fc4ff46d6864564fba59024e928bdc7de475affc25/greenlet-3.2.4-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:061dc4cf2c34852b052a8620d40f36324554bc192be474b9e9770e8c042fd735", size = 695355, upload-time = "2025-08-07T13:18:34.517Z" }, - { url = "https://files.pythonhosted.org/packages/72/60/fc56c62046ec17f6b0d3060564562c64c862948c9d4bc8aa807cf5bd74f4/greenlet-3.2.4-cp314-cp314-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:44358b9bf66c8576a9f57a590d5f5d6e72fa4228b763d0e43fee6d3b06d3a337", size = 657512, upload-time = "2025-08-07T13:18:33.969Z" }, - { url = "https://files.pythonhosted.org/packages/23/6e/74407aed965a4ab6ddd93a7ded3180b730d281c77b765788419484cdfeef/greenlet-3.2.4-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:2917bdf657f5859fbf3386b12d68ede4cf1f04c90c3a6bc1f013dd68a22e2269", size = 1612508, upload-time = "2025-11-04T12:42:23.427Z" }, - { url = "https://files.pythonhosted.org/packages/0d/da/343cd760ab2f92bac1845ca07ee3faea9fe52bee65f7bcb19f16ad7de08b/greenlet-3.2.4-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:015d48959d4add5d6c9f6c5210ee3803a830dce46356e3bc326d6776bde54681", size = 1680760, upload-time = "2025-11-04T12:42:25.341Z" }, - { url = "https://files.pythonhosted.org/packages/e3/a5/6ddab2b4c112be95601c13428db1d8b6608a8b6039816f2ba09c346c08fc/greenlet-3.2.4-cp314-cp314-win_amd64.whl", hash = "sha256:e37ab26028f12dbb0ff65f29a8d3d44a765c61e729647bf2ddfbbed621726f01", size = 303425, upload-time = "2025-08-07T13:32:27.59Z" }, +version = "3.3.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/c7/e5/40dbda2736893e3e53d25838e0f19a2b417dfc122b9989c91918db30b5d3/greenlet-3.3.0.tar.gz", hash = "sha256:a82bb225a4e9e4d653dd2fb7b8b2d36e4fb25bc0165422a11e48b88e9e6f78fb", size = 190651, upload-time = "2025-12-04T14:49:44.05Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/02/2f/28592176381b9ab2cafa12829ba7b472d177f3acc35d8fbcf3673d966fff/greenlet-3.3.0-cp313-cp313-macosx_11_0_universal2.whl", hash = "sha256:a1e41a81c7e2825822f4e068c48cb2196002362619e2d70b148f20a831c00739", size = 275140, upload-time = "2025-12-04T14:23:01.282Z" }, + { url = "https://files.pythonhosted.org/packages/2c/80/fbe937bf81e9fca98c981fe499e59a3f45df2a04da0baa5c2be0dca0d329/greenlet-3.3.0-cp313-cp313-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:9f515a47d02da4d30caaa85b69474cec77b7929b2e936ff7fb853d42f4bf8808", size = 599219, upload-time = "2025-12-04T14:50:08.309Z" }, + { url = "https://files.pythonhosted.org/packages/c2/ff/7c985128f0514271b8268476af89aee6866df5eec04ac17dcfbc676213df/greenlet-3.3.0-cp313-cp313-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:7d2d9fd66bfadf230b385fdc90426fcd6eb64db54b40c495b72ac0feb5766c54", size = 610211, upload-time = "2025-12-04T14:57:43.968Z" }, + { url = "https://files.pythonhosted.org/packages/79/07/c47a82d881319ec18a4510bb30463ed6891f2ad2c1901ed5ec23d3de351f/greenlet-3.3.0-cp313-cp313-manylinux_2_24_s390x.manylinux_2_28_s390x.whl", hash = "sha256:30a6e28487a790417d036088b3bcb3f3ac7d8babaa7d0139edbaddebf3af9492", size = 624311, upload-time = "2025-12-04T15:07:14.697Z" }, + { url = "https://files.pythonhosted.org/packages/fd/8e/424b8c6e78bd9837d14ff7df01a9829fc883ba2ab4ea787d4f848435f23f/greenlet-3.3.0-cp313-cp313-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:087ea5e004437321508a8d6f20efc4cfec5e3c30118e1417ea96ed1d93950527", size = 612833, upload-time = "2025-12-04T14:26:03.669Z" }, + { url = "https://files.pythonhosted.org/packages/b5/ba/56699ff9b7c76ca12f1cdc27a886d0f81f2189c3455ff9f65246780f713d/greenlet-3.3.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:ab97cf74045343f6c60a39913fa59710e4bd26a536ce7ab2397adf8b27e67c39", size = 1567256, upload-time = "2025-12-04T15:04:25.276Z" }, + { url = "https://files.pythonhosted.org/packages/1e/37/f31136132967982d698c71a281a8901daf1a8fbab935dce7c0cf15f942cc/greenlet-3.3.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:5375d2e23184629112ca1ea89a53389dddbffcf417dad40125713d88eb5f96e8", size = 1636483, upload-time = "2025-12-04T14:27:30.804Z" }, + { url = "https://files.pythonhosted.org/packages/7e/71/ba21c3fb8c5dce83b8c01f458a42e99ffdb1963aeec08fff5a18588d8fd7/greenlet-3.3.0-cp313-cp313-win_amd64.whl", hash = "sha256:9ee1942ea19550094033c35d25d20726e4f1c40d59545815e1128ac58d416d38", size = 301833, upload-time = "2025-12-04T14:32:23.929Z" }, + { url = "https://files.pythonhosted.org/packages/d7/7c/f0a6d0ede2c7bf092d00bc83ad5bafb7e6ec9b4aab2fbdfa6f134dc73327/greenlet-3.3.0-cp314-cp314-macosx_11_0_universal2.whl", hash = "sha256:60c2ef0f578afb3c8d92ea07ad327f9a062547137afe91f38408f08aacab667f", size = 275671, upload-time = "2025-12-04T14:23:05.267Z" }, + { url = "https://files.pythonhosted.org/packages/44/06/dac639ae1a50f5969d82d2e3dd9767d30d6dbdbab0e1a54010c8fe90263c/greenlet-3.3.0-cp314-cp314-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:0a5d554d0712ba1de0a6c94c640f7aeba3f85b3a6e1f2899c11c2c0428da9365", size = 646360, upload-time = "2025-12-04T14:50:10.026Z" }, + { url = "https://files.pythonhosted.org/packages/e0/94/0fb76fe6c5369fba9bf98529ada6f4c3a1adf19e406a47332245ef0eb357/greenlet-3.3.0-cp314-cp314-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:3a898b1e9c5f7307ebbde4102908e6cbfcb9ea16284a3abe15cab996bee8b9b3", size = 658160, upload-time = "2025-12-04T14:57:45.41Z" }, + { url = "https://files.pythonhosted.org/packages/93/79/d2c70cae6e823fac36c3bbc9077962105052b7ef81db2f01ec3b9bf17e2b/greenlet-3.3.0-cp314-cp314-manylinux_2_24_s390x.manylinux_2_28_s390x.whl", hash = "sha256:dcd2bdbd444ff340e8d6bdf54d2f206ccddbb3ccfdcd3c25bf4afaa7b8f0cf45", size = 671388, upload-time = "2025-12-04T15:07:15.789Z" }, + { url = "https://files.pythonhosted.org/packages/b8/14/bab308fc2c1b5228c3224ec2bf928ce2e4d21d8046c161e44a2012b5203e/greenlet-3.3.0-cp314-cp314-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:5773edda4dc00e173820722711d043799d3adb4f01731f40619e07ea2750b955", size = 660166, upload-time = "2025-12-04T14:26:05.099Z" }, + { url = "https://files.pythonhosted.org/packages/4b/d2/91465d39164eaa0085177f61983d80ffe746c5a1860f009811d498e7259c/greenlet-3.3.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:ac0549373982b36d5fd5d30beb8a7a33ee541ff98d2b502714a09f1169f31b55", size = 1615193, upload-time = "2025-12-04T15:04:27.041Z" }, + { url = "https://files.pythonhosted.org/packages/42/1b/83d110a37044b92423084d52d5d5a3b3a73cafb51b547e6d7366ff62eff1/greenlet-3.3.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:d198d2d977460358c3b3a4dc844f875d1adb33817f0613f663a656f463764ccc", size = 1683653, upload-time = "2025-12-04T14:27:32.366Z" }, + { url = "https://files.pythonhosted.org/packages/7c/9a/9030e6f9aa8fd7808e9c31ba4c38f87c4f8ec324ee67431d181fe396d705/greenlet-3.3.0-cp314-cp314-win_amd64.whl", hash = "sha256:73f51dd0e0bdb596fb0417e475fa3c5e32d4c83638296e560086b8d7da7c4170", size = 305387, upload-time = "2025-12-04T14:26:51.063Z" }, + { url = "https://files.pythonhosted.org/packages/a0/66/bd6317bc5932accf351fc19f177ffba53712a202f9df10587da8df257c7e/greenlet-3.3.0-cp314-cp314t-macosx_11_0_universal2.whl", hash = "sha256:d6ed6f85fae6cdfdb9ce04c9bf7a08d666cfcfb914e7d006f44f840b46741931", size = 282638, upload-time = "2025-12-04T14:25:20.941Z" }, + { url = "https://files.pythonhosted.org/packages/30/cf/cc81cb030b40e738d6e69502ccbd0dd1bced0588e958f9e757945de24404/greenlet-3.3.0-cp314-cp314t-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:d9125050fcf24554e69c4cacb086b87b3b55dc395a8b3ebe6487b045b2614388", size = 651145, upload-time = "2025-12-04T14:50:11.039Z" }, + { url = "https://files.pythonhosted.org/packages/9c/ea/1020037b5ecfe95ca7df8d8549959baceb8186031da83d5ecceff8b08cd2/greenlet-3.3.0-cp314-cp314t-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:87e63ccfa13c0a0f6234ed0add552af24cc67dd886731f2261e46e241608bee3", size = 654236, upload-time = "2025-12-04T14:57:47.007Z" }, + { url = "https://files.pythonhosted.org/packages/69/cc/1e4bae2e45ca2fa55299f4e85854606a78ecc37fead20d69322f96000504/greenlet-3.3.0-cp314-cp314t-manylinux_2_24_s390x.manylinux_2_28_s390x.whl", hash = "sha256:2662433acbca297c9153a4023fe2161c8dcfdcc91f10433171cf7e7d94ba2221", size = 662506, upload-time = "2025-12-04T15:07:16.906Z" }, + { url = "https://files.pythonhosted.org/packages/57/b9/f8025d71a6085c441a7eaff0fd928bbb275a6633773667023d19179fe815/greenlet-3.3.0-cp314-cp314t-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:3c6e9b9c1527a78520357de498b0e709fb9e2f49c3a513afd5a249007261911b", size = 653783, upload-time = "2025-12-04T14:26:06.225Z" }, + { url = "https://files.pythonhosted.org/packages/f6/c7/876a8c7a7485d5d6b5c6821201d542ef28be645aa024cfe1145b35c120c1/greenlet-3.3.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:286d093f95ec98fdd92fcb955003b8a3d054b4e2cab3e2707a5039e7b50520fd", size = 1614857, upload-time = "2025-12-04T15:04:28.484Z" }, + { url = "https://files.pythonhosted.org/packages/4f/dc/041be1dff9f23dac5f48a43323cd0789cb798342011c19a248d9c9335536/greenlet-3.3.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:6c10513330af5b8ae16f023e8ddbfb486ab355d04467c4679c5cfe4659975dd9", size = 1676034, upload-time = "2025-12-04T14:27:33.531Z" }, ] [[package]] @@ -1404,29 +1406,29 @@ wheels = [ [[package]] name = "protobuf" -version = "6.33.1" +version = "6.33.2" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/0a/03/a1440979a3f74f16cab3b75b0da1a1a7f922d56a8ddea96092391998edc0/protobuf-6.33.1.tar.gz", hash = "sha256:97f65757e8d09870de6fd973aeddb92f85435607235d20b2dfed93405d00c85b", size = 443432, upload-time = "2025-11-13T16:44:18.895Z" } +sdist = { url = "https://files.pythonhosted.org/packages/34/44/e49ecff446afeec9d1a66d6bbf9adc21e3c7cea7803a920ca3773379d4f6/protobuf-6.33.2.tar.gz", hash = "sha256:56dc370c91fbb8ac85bc13582c9e373569668a290aa2e66a590c2a0d35ddb9e4", size = 444296, upload-time = "2025-12-06T00:17:53.311Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/06/f1/446a9bbd2c60772ca36556bac8bfde40eceb28d9cc7838755bc41e001d8f/protobuf-6.33.1-cp310-abi3-win32.whl", hash = "sha256:f8d3fdbc966aaab1d05046d0240dd94d40f2a8c62856d41eaa141ff64a79de6b", size = 425593, upload-time = "2025-11-13T16:44:06.275Z" }, - { url = "https://files.pythonhosted.org/packages/a6/79/8780a378c650e3df849b73de8b13cf5412f521ca2ff9b78a45c247029440/protobuf-6.33.1-cp310-abi3-win_amd64.whl", hash = "sha256:923aa6d27a92bf44394f6abf7ea0500f38769d4b07f4be41cb52bd8b1123b9ed", size = 436883, upload-time = "2025-11-13T16:44:09.222Z" }, - { url = "https://files.pythonhosted.org/packages/cd/93/26213ff72b103ae55bb0d73e7fb91ea570ef407c3ab4fd2f1f27cac16044/protobuf-6.33.1-cp39-abi3-macosx_10_9_universal2.whl", hash = "sha256:fe34575f2bdde76ac429ec7b570235bf0c788883e70aee90068e9981806f2490", size = 427522, upload-time = "2025-11-13T16:44:10.475Z" }, - { url = "https://files.pythonhosted.org/packages/c2/32/df4a35247923393aa6b887c3b3244a8c941c32a25681775f96e2b418f90e/protobuf-6.33.1-cp39-abi3-manylinux2014_aarch64.whl", hash = "sha256:f8adba2e44cde2d7618996b3fc02341f03f5bc3f2748be72dc7b063319276178", size = 324445, upload-time = "2025-11-13T16:44:11.869Z" }, - { url = "https://files.pythonhosted.org/packages/8e/d0/d796e419e2ec93d2f3fa44888861c3f88f722cde02b7c3488fcc6a166820/protobuf-6.33.1-cp39-abi3-manylinux2014_s390x.whl", hash = "sha256:0f4cf01222c0d959c2b399142deb526de420be8236f22c71356e2a544e153c53", size = 339161, upload-time = "2025-11-13T16:44:12.778Z" }, - { url = "https://files.pythonhosted.org/packages/1d/2a/3c5f05a4af06649547027d288747f68525755de692a26a7720dced3652c0/protobuf-6.33.1-cp39-abi3-manylinux2014_x86_64.whl", hash = "sha256:8fd7d5e0eb08cd5b87fd3df49bc193f5cfd778701f47e11d127d0afc6c39f1d1", size = 323171, upload-time = "2025-11-13T16:44:14.035Z" }, - { url = "https://files.pythonhosted.org/packages/08/b4/46310463b4f6ceef310f8348786f3cff181cea671578e3d9743ba61a459e/protobuf-6.33.1-py3-none-any.whl", hash = "sha256:d595a9fd694fdeb061a62fbe10eb039cc1e444df81ec9bb70c7fc59ebcb1eafa", size = 170477, upload-time = "2025-11-13T16:44:17.633Z" }, + { url = "https://files.pythonhosted.org/packages/bc/91/1e3a34881a88697a7354ffd177e8746e97a722e5e8db101544b47e84afb1/protobuf-6.33.2-cp310-abi3-win32.whl", hash = "sha256:87eb388bd2d0f78febd8f4c8779c79247b26a5befad525008e49a6955787ff3d", size = 425603, upload-time = "2025-12-06T00:17:41.114Z" }, + { url = "https://files.pythonhosted.org/packages/64/20/4d50191997e917ae13ad0a235c8b42d8c1ab9c3e6fd455ca16d416944355/protobuf-6.33.2-cp310-abi3-win_amd64.whl", hash = "sha256:fc2a0e8b05b180e5fc0dd1559fe8ebdae21a27e81ac77728fb6c42b12c7419b4", size = 436930, upload-time = "2025-12-06T00:17:43.278Z" }, + { url = "https://files.pythonhosted.org/packages/b2/ca/7e485da88ba45c920fb3f50ae78de29ab925d9e54ef0de678306abfbb497/protobuf-6.33.2-cp39-abi3-macosx_10_9_universal2.whl", hash = "sha256:d9b19771ca75935b3a4422957bc518b0cecb978b31d1dd12037b088f6bcc0e43", size = 427621, upload-time = "2025-12-06T00:17:44.445Z" }, + { url = "https://files.pythonhosted.org/packages/7d/4f/f743761e41d3b2b2566748eb76bbff2b43e14d5fcab694f494a16458b05f/protobuf-6.33.2-cp39-abi3-manylinux2014_aarch64.whl", hash = "sha256:b5d3b5625192214066d99b2b605f5783483575656784de223f00a8d00754fc0e", size = 324460, upload-time = "2025-12-06T00:17:45.678Z" }, + { url = "https://files.pythonhosted.org/packages/b1/fa/26468d00a92824020f6f2090d827078c09c9c587e34cbfd2d0c7911221f8/protobuf-6.33.2-cp39-abi3-manylinux2014_s390x.whl", hash = "sha256:8cd7640aee0b7828b6d03ae518b5b4806fdfc1afe8de82f79c3454f8aef29872", size = 339168, upload-time = "2025-12-06T00:17:46.813Z" }, + { url = "https://files.pythonhosted.org/packages/56/13/333b8f421738f149d4fe5e49553bc2a2ab75235486259f689b4b91f96cec/protobuf-6.33.2-cp39-abi3-manylinux2014_x86_64.whl", hash = "sha256:1f8017c48c07ec5859106533b682260ba3d7c5567b1ca1f24297ce03384d1b4f", size = 323270, upload-time = "2025-12-06T00:17:48.253Z" }, + { url = "https://files.pythonhosted.org/packages/0e/15/4f02896cc3df04fc465010a4c6a0cd89810f54617a32a70ef531ed75d61c/protobuf-6.33.2-py3-none-any.whl", hash = "sha256:7636aad9bb01768870266de5dc009de2d1b936771b38a793f73cbbf279c91c5c", size = 170501, upload-time = "2025-12-06T00:17:52.211Z" }, ] [[package]] name = "psycopg" -version = "3.2.13" +version = "3.3.2" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "tzdata", marker = "sys_platform == 'win32'" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/44/05/d4a05988f15fcf90e0088c735b1f2fc04a30b7fc65461d6ec278f5f2f17a/psycopg-3.2.13.tar.gz", hash = "sha256:309adaeda61d44556046ec9a83a93f42bbe5310120b1995f3af49ab6d9f13c1d", size = 160626, upload-time = "2025-11-21T22:34:32.328Z" } +sdist = { url = "https://files.pythonhosted.org/packages/e0/1a/7d9ef4fdc13ef7f15b934c393edc97a35c281bb7d3c3329fbfcbe915a7c2/psycopg-3.3.2.tar.gz", hash = "sha256:707a67975ee214d200511177a6a80e56e654754c9afca06a7194ea6bbfde9ca7", size = 165630, upload-time = "2025-12-06T17:34:53.899Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/a9/14/f2724bd1986158a348316e86fdd0837a838b14a711df3f00e47fba597447/psycopg-3.2.13-py3-none-any.whl", hash = "sha256:a481374514f2da627157f767a9336705ebefe93ea7a0522a6cbacba165da179a", size = 206797, upload-time = "2025-11-21T22:29:39.733Z" }, + { url = "https://files.pythonhosted.org/packages/8c/51/2779ccdf9305981a06b21a6b27e8547c948d85c41c76ff434192784a4c93/psycopg-3.3.2-py3-none-any.whl", hash = "sha256:3e94bc5f4690247d734599af56e51bae8e0db8e4311ea413f801fef82b14a99b", size = 212774, upload-time = "2025-12-06T17:31:41.414Z" }, ] [package.optional-dependencies] @@ -1436,27 +1438,31 @@ binary = [ [[package]] name = "psycopg-binary" -version = "3.2.13" -source = { registry = "https://pypi.org/simple" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/28/ec/ef37bb44dc02fcc6c0a3eeb93f4baaac13bcb228633fe38ad3fb5a3f6449/psycopg_binary-3.2.13-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:dbae6ab1966e2b61d97e47220556c330c4608bb4cfb3a124aa0595c39995c068", size = 3995628, upload-time = "2025-11-21T22:31:45.921Z" }, - { url = "https://files.pythonhosted.org/packages/6d/ad/4748f5f1a40248af16dba087dbec50bd335ee025cc1fb9bf64773378ceff/psycopg_binary-3.2.13-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:fae933e4564386199fc54845d85413eedb49760e0bcd2b621fde2dd1825b99b3", size = 4069024, upload-time = "2025-11-21T22:31:50.202Z" }, - { url = "https://files.pythonhosted.org/packages/cf/c2/f02ec6bbc30c7fcd3b39823d2d624b42fae480edeb6e50eb3276281d5635/psycopg_binary-3.2.13-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:13e2f8894d410678529ff9f1211f96c5a93ff142f992b302682b42d924428b61", size = 4615127, upload-time = "2025-11-21T22:31:56.517Z" }, - { url = "https://files.pythonhosted.org/packages/f0/0d/a54fc2cdd672c84175d6869cc823d6ec2a8909318d491f3c24e6077983f2/psycopg_binary-3.2.13-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:f26f7009375cf1e92180e5c517c52da1054f7e690dde90e0ed00fa8b5736bcd4", size = 4710267, upload-time = "2025-11-21T22:32:04.585Z" }, - { url = "https://files.pythonhosted.org/packages/9d/b7/067de1acaf3d312253351f3af4121f972584bd36cada6378d4b0cdcebd38/psycopg_binary-3.2.13-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:ea2fdbcc9142933a47c66970e0df8b363e3bd1ea4c5ce376f2f3d94a9aeec847", size = 4400795, upload-time = "2025-11-21T22:32:08.883Z" }, - { url = "https://files.pythonhosted.org/packages/64/b5/030e6b1ebfc4d3a8fca03adc5fc827982643bad0b01a1268538d17c08ed3/psycopg_binary-3.2.13-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:ac92d6bc1d4a41c7459953a9aa727b9966e937e94c9e072527317fd2a67d488b", size = 3851239, upload-time = "2025-11-21T22:32:12.333Z" }, - { url = "https://files.pythonhosted.org/packages/79/6f/0541845364a7de9eae6807060da6a04b22a8eb2e803606d285d9250fbe93/psycopg_binary-3.2.13-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:8b843c00478739e95c46d6d3472b13123b634685f107831a9bfc41503a06ecbd", size = 3525084, upload-time = "2025-11-21T22:32:15.946Z" }, - { url = "https://files.pythonhosted.org/packages/83/ae/6507890dc30a4bbd9d938d4ff3a4079d009a5ad8170af51c7f762438fdbf/psycopg_binary-3.2.13-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:2f63868cc96bc18486cebec24445affbdd7f7debf28fac466ea935a8b5a4753b", size = 3576787, upload-time = "2025-11-21T22:32:19.922Z" }, - { url = "https://files.pythonhosted.org/packages/9d/64/3d1c2f1fd09b60cdfbe68b9a810b357ba505eff6e4bdb1a2d9f6729da64c/psycopg_binary-3.2.13-cp313-cp313-win_amd64.whl", hash = "sha256:594dfbca3326e997ae738d3d339004e8416b1f7390f52ce8dc2d692393e8fa96", size = 2905584, upload-time = "2025-11-21T22:32:23.399Z" }, - { url = "https://files.pythonhosted.org/packages/d3/b4/7656b3d67bedff2b900c8c4671cb6eb5fb99c2fc36da33579cac89779c25/psycopg_binary-3.2.13-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:502a778c3e07c6b3aabfa56ee230e8c264d2debfab42d11535513a01bdfff0d6", size = 3997201, upload-time = "2025-11-21T22:32:28.185Z" }, - { url = "https://files.pythonhosted.org/packages/e0/2e/3b4afbd94d48df19c3931cedba464b109f89d81ac43178e6a3d654b4e8d5/psycopg_binary-3.2.13-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:7561a71d764d6f74d66e8b7d844b0f27fa33de508f65c17b1d56a94c73644776", size = 4071631, upload-time = "2025-11-21T22:32:32.594Z" }, - { url = "https://files.pythonhosted.org/packages/5e/8b/107d06d55992e2f13157eb705ba5a47d06c4cf1bed077dff0c567b10c187/psycopg_binary-3.2.13-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:9caf14745a1930b4e03fe4072cd7154eaf6e1241d20c42130ed784408a26b24b", size = 4620918, upload-time = "2025-11-21T22:32:37.357Z" }, - { url = "https://files.pythonhosted.org/packages/e1/47/a925620f261b115f31e813a5bfe640f316413b1864094a60162f4a6e4d67/psycopg_binary-3.2.13-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:4a6cafabdc0bfa37e11c6f365020fd5916b62d6296df581f4dceaa43a2ce680c", size = 4714494, upload-time = "2025-11-21T22:32:42.138Z" }, - { url = "https://files.pythonhosted.org/packages/46/33/bed384665356bb9ba17dd8e104884d87cc2343d16dffdfd9aaa9a159bd4d/psycopg_binary-3.2.13-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:c96cb5a27e68acac6d74b64fca38592a692de9c4b7827339190698d58027aa45", size = 4403046, upload-time = "2025-11-21T22:32:47.241Z" }, - { url = "https://files.pythonhosted.org/packages/41/88/749d8e8102fb5df502e2ecb053b79e78e3358af01af652b5dbeb96ab7905/psycopg_binary-3.2.13-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:596176ae3dfbf56fc61108870bfe17c7205d33ac28d524909feb5335201daa0a", size = 3859046, upload-time = "2025-11-21T22:32:51.481Z" }, - { url = "https://files.pythonhosted.org/packages/38/7c/f492e63b517d6dcd564e8c43bc15e11a4c712a848adf8938ce33bfd4c867/psycopg_binary-3.2.13-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:cc3a0408435dfbb77eeca5e8050df4b19a6e9b7e5e5583edf524c4a83d6293b2", size = 3531351, upload-time = "2025-11-21T22:32:55.571Z" }, - { url = "https://files.pythonhosted.org/packages/07/5a/d8743eb23944e5cf2a0bbfa92935c140b5beaacdb872be641065ed70ab2c/psycopg_binary-3.2.13-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:65df0d459ffba14082d8ca4bb2f6ffbb2f8d02968f7d34a747e1031934b76b23", size = 3581034, upload-time = "2025-11-21T22:33:01.648Z" }, - { url = "https://files.pythonhosted.org/packages/46/b2/411d4180252144f7eff024894d2d2ebb98c012c944a282fc20250870e461/psycopg_binary-3.2.13-cp314-cp314-win_amd64.whl", hash = "sha256:5c77f156c7316529ed371b5f95a51139e531328ee39c37493a2afcbc1f79d5de", size = 3000162, upload-time = "2025-11-21T22:33:07.378Z" }, +version = "3.3.2" +source = { registry = "https://pypi.org/simple" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/14/73/7ca7cb22b9ac7393fb5de7d28ca97e8347c375c8498b3bff2c99c1f38038/psycopg_binary-3.3.2-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:fc5a189e89cbfff174588665bb18d28d2d0428366cc9dae5864afcaa2e57380b", size = 4579068, upload-time = "2025-12-06T17:33:39.303Z" }, + { url = "https://files.pythonhosted.org/packages/f5/42/0cf38ff6c62c792fc5b55398a853a77663210ebd51ed6f0c4a05b06f95a6/psycopg_binary-3.3.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:083c2e182be433f290dc2c516fd72b9b47054fcd305cce791e0a50d9e93e06f2", size = 4657520, upload-time = "2025-12-06T17:33:42.536Z" }, + { url = "https://files.pythonhosted.org/packages/3b/60/df846bc84cbf2231e01b0fff48b09841fe486fa177665e50f4995b1bfa44/psycopg_binary-3.3.2-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:ac230e3643d1c436a2dfb59ca84357dfc6862c9f372fc5dbd96bafecae581f9f", size = 5452086, upload-time = "2025-12-06T17:33:46.54Z" }, + { url = "https://files.pythonhosted.org/packages/ab/85/30c846a00db86b1b53fd5bfd4b4edfbd0c00de8f2c75dd105610bd7568fc/psycopg_binary-3.3.2-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:d8c899a540f6c7585cee53cddc929dd4d2db90fd828e37f5d4017b63acbc1a5d", size = 5131125, upload-time = "2025-12-06T17:33:50.413Z" }, + { url = "https://files.pythonhosted.org/packages/6d/15/9968732013373f36f8a2a3fb76104dffc8efd9db78709caa5ae1a87b1f80/psycopg_binary-3.3.2-cp313-cp313-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:50ff10ab8c0abdb5a5451b9315538865b50ba64c907742a1385fdf5f5772b73e", size = 6722914, upload-time = "2025-12-06T17:33:54.544Z" }, + { url = "https://files.pythonhosted.org/packages/b2/ba/29e361fe02143ac5ff5a1ca3e45697344cfbebe2eaf8c4e7eec164bff9a0/psycopg_binary-3.3.2-cp313-cp313-manylinux_2_38_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:23d2594af848c1fd3d874a9364bef50730124e72df7bb145a20cb45e728c50ed", size = 4966081, upload-time = "2025-12-06T17:33:58.477Z" }, + { url = "https://files.pythonhosted.org/packages/99/45/1be90c8f1a1a237046903e91202fb06708745c179f220b361d6333ed7641/psycopg_binary-3.3.2-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:ea4fe6b4ead3bbbe27244ea224fcd1f53cb119afc38b71a2f3ce570149a03e30", size = 4493332, upload-time = "2025-12-06T17:34:02.011Z" }, + { url = "https://files.pythonhosted.org/packages/2e/b5/bbdc07d5f0a5e90c617abd624368182aa131485e18038b2c6c85fc054aed/psycopg_binary-3.3.2-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:742ce48cde825b8e52fb1a658253d6d1ff66d152081cbc76aa45e2986534858d", size = 4170781, upload-time = "2025-12-06T17:34:05.298Z" }, + { url = "https://files.pythonhosted.org/packages/d1/2a/0d45e4f4da2bd78c3237ffa03475ef3751f69a81919c54a6e610eb1a7c96/psycopg_binary-3.3.2-cp313-cp313-musllinux_1_2_riscv64.whl", hash = "sha256:e22bf6b54df994aff37ab52695d635f1ef73155e781eee1f5fa75bc08b58c8da", size = 3910544, upload-time = "2025-12-06T17:34:08.251Z" }, + { url = "https://files.pythonhosted.org/packages/3a/62/a8e0f092f4dbef9a94b032fb71e214cf0a375010692fbe7493a766339e47/psycopg_binary-3.3.2-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:8db9034cde3bcdafc66980f0130813f5c5d19e74b3f2a19fb3cfbc25ad113121", size = 4220070, upload-time = "2025-12-06T17:34:11.392Z" }, + { url = "https://files.pythonhosted.org/packages/09/e6/5fc8d8aff8afa114bb4a94a0341b9309311e8bf3ab32d816032f8b984d4e/psycopg_binary-3.3.2-cp313-cp313-win_amd64.whl", hash = "sha256:df65174c7cf6b05ea273ce955927d3270b3a6e27b0b12762b009ce6082b8d3fc", size = 3540922, upload-time = "2025-12-06T17:34:14.88Z" }, + { url = "https://files.pythonhosted.org/packages/bd/75/ad18c0b97b852aba286d06befb398cc6d383e9dfd0a518369af275a5a526/psycopg_binary-3.3.2-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:9ca24062cd9b2270e4d77576042e9cc2b1d543f09da5aba1f1a3d016cea28390", size = 4596371, upload-time = "2025-12-06T17:34:18.007Z" }, + { url = "https://files.pythonhosted.org/packages/5a/79/91649d94c8d89f84af5da7c9d474bfba35b08eb8f492ca3422b08f0a6427/psycopg_binary-3.3.2-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:c749770da0947bc972e512f35366dd4950c0e34afad89e60b9787a37e97cb443", size = 4675139, upload-time = "2025-12-06T17:34:21.374Z" }, + { url = "https://files.pythonhosted.org/packages/56/ac/b26e004880f054549ec9396594e1ffe435810b0673e428e619ed722e4244/psycopg_binary-3.3.2-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:03b7cd73fb8c45d272a34ae7249713e32492891492681e3cf11dff9531cf37e9", size = 5456120, upload-time = "2025-12-06T17:34:25.102Z" }, + { url = "https://files.pythonhosted.org/packages/4b/8d/410681dccd6f2999fb115cc248521ec50dd2b0aba66ae8de7e81efdebbee/psycopg_binary-3.3.2-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:43b130e3b6edcb5ee856c7167ccb8561b473308c870ed83978ae478613764f1c", size = 5133484, upload-time = "2025-12-06T17:34:28.933Z" }, + { url = "https://files.pythonhosted.org/packages/66/30/ebbab99ea2cfa099d7b11b742ce13415d44f800555bfa4ad2911dc645b71/psycopg_binary-3.3.2-cp314-cp314-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:7c1feba5a8c617922321aef945865334e468337b8fc5c73074f5e63143013b5a", size = 6731818, upload-time = "2025-12-06T17:34:33.094Z" }, + { url = "https://files.pythonhosted.org/packages/70/02/d260646253b7ad805d60e0de47f9b811d6544078452579466a098598b6f4/psycopg_binary-3.3.2-cp314-cp314-manylinux_2_38_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:cabb2a554d9a0a6bf84037d86ca91782f087dfff2a61298d0b00c19c0bc43f6d", size = 4983859, upload-time = "2025-12-06T17:34:36.457Z" }, + { url = "https://files.pythonhosted.org/packages/72/8d/e778d7bad1a7910aa36281f092bd85c5702f508fd9bb0ea2020ffbb6585c/psycopg_binary-3.3.2-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:74bc306c4b4df35b09bc8cecf806b271e1c5d708f7900145e4e54a2e5dedfed0", size = 4516388, upload-time = "2025-12-06T17:34:40.129Z" }, + { url = "https://files.pythonhosted.org/packages/bd/f1/64e82098722e2ab3521797584caf515284be09c1e08a872551b6edbb0074/psycopg_binary-3.3.2-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:d79b0093f0fbf7a962d6a46ae292dc056c65d16a8ee9361f3cfbafd4c197ab14", size = 4192382, upload-time = "2025-12-06T17:34:43.279Z" }, + { url = "https://files.pythonhosted.org/packages/fa/d0/c20f4e668e89494972e551c31be2a0016e3f50d552d7ae9ac07086407599/psycopg_binary-3.3.2-cp314-cp314-musllinux_1_2_riscv64.whl", hash = "sha256:1586e220be05547c77afc326741dd41cc7fba38a81f9931f616ae98865439678", size = 3928660, upload-time = "2025-12-06T17:34:46.757Z" }, + { url = "https://files.pythonhosted.org/packages/0f/e1/99746c171de22539fd5eb1c9ca21dc805b54cfae502d7451d237d1dbc349/psycopg_binary-3.3.2-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:458696a5fa5dad5b6fb5d5862c22454434ce4fe1cf66ca6c0de5f904cbc1ae3e", size = 4239169, upload-time = "2025-12-06T17:34:49.751Z" }, + { url = "https://files.pythonhosted.org/packages/72/f7/212343c1c9cfac35fd943c527af85e9091d633176e2a407a0797856ff7b9/psycopg_binary-3.3.2-cp314-cp314-win_amd64.whl", hash = "sha256:04bb2de4ba69d6f8395b446ede795e8884c040ec71d01dd07ac2b2d18d4153d1", size = 3642122, upload-time = "2025-12-06T17:34:52.506Z" }, ] [[package]] @@ -1508,7 +1514,7 @@ wheels = [ [[package]] name = "pydantic" -version = "2.12.4" +version = "2.12.5" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "annotated-types" }, @@ -1516,9 +1522,9 @@ dependencies = [ { name = "typing-extensions" }, { name = "typing-inspection" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/96/ad/a17bc283d7d81837c061c49e3eaa27a45991759a1b7eae1031921c6bd924/pydantic-2.12.4.tar.gz", hash = "sha256:0f8cb9555000a4b5b617f66bfd2566264c4984b27589d3b845685983e8ea85ac", size = 821038, upload-time = "2025-11-05T10:50:08.59Z" } +sdist = { url = "https://files.pythonhosted.org/packages/69/44/36f1a6e523abc58ae5f928898e4aca2e0ea509b5aa6f6f392a5d882be928/pydantic-2.12.5.tar.gz", hash = "sha256:4d351024c75c0f085a9febbb665ce8c0c6ec5d30e903bdb6394b7ede26aebb49", size = 821591, upload-time = "2025-11-26T15:11:46.471Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/82/2f/e68750da9b04856e2a7ec56fc6f034a5a79775e9b9a81882252789873798/pydantic-2.12.4-py3-none-any.whl", hash = "sha256:92d3d202a745d46f9be6df459ac5a064fdaa3c1c4cd8adcfa332ccf3c05f871e", size = 463400, upload-time = "2025-11-05T10:50:06.732Z" }, + { url = "https://files.pythonhosted.org/packages/5a/87/b70ad306ebb6f9b585f114d0ac2137d792b48be34d732d60e597c2f8465a/pydantic-2.12.5-py3-none-any.whl", hash = "sha256:e561593fccf61e8a20fc46dfc2dfe075b8be7d0188df33f221ad1f0139180f9d", size = 463580, upload-time = "2025-11-26T15:11:44.605Z" }, ] [package.optional-dependencies] @@ -1674,7 +1680,7 @@ wheels = [ [[package]] name = "pytest" -version = "9.0.1" +version = "9.0.2" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "colorama", marker = "sys_platform == 'win32'" }, @@ -1683,9 +1689,9 @@ dependencies = [ { name = "pluggy" }, { name = "pygments" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/07/56/f013048ac4bc4c1d9be45afd4ab209ea62822fb1598f40687e6bf45dcea4/pytest-9.0.1.tar.gz", hash = "sha256:3e9c069ea73583e255c3b21cf46b8d3c56f6e3a1a8f6da94ccb0fcf57b9d73c8", size = 1564125, upload-time = "2025-11-12T13:05:09.333Z" } +sdist = { url = "https://files.pythonhosted.org/packages/d1/db/7ef3487e0fb0049ddb5ce41d3a49c235bf9ad299b6a25d5780a89f19230f/pytest-9.0.2.tar.gz", hash = "sha256:75186651a92bd89611d1d9fc20f0b4345fd827c41ccd5c299a868a05d70edf11", size = 1568901, upload-time = "2025-12-06T21:30:51.014Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/0b/8b/6300fb80f858cda1c51ffa17075df5d846757081d11ab4aa35cef9e6258b/pytest-9.0.1-py3-none-any.whl", hash = "sha256:67be0030d194df2dfa7b556f2e56fb3c3315bd5c8822c6951162b92b32ce7dad", size = 373668, upload-time = "2025-11-12T13:05:07.379Z" }, + { url = "https://files.pythonhosted.org/packages/3b/ab/b3226f0bd7cdcf710fbede2b3548584366da3b19b5021e74f5bde2a8fa3f/pytest-9.0.2-py3-none-any.whl", hash = "sha256:711ffd45bf766d5264d487b917733b453d917afd2b0ad65223959f59089f875b", size = 374801, upload-time = "2025-12-06T21:30:49.154Z" }, ] [[package]] @@ -2060,16 +2066,16 @@ wheels = [ [[package]] name = "rich-toolkit" -version = "0.16.0" +version = "0.17.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "click" }, { name = "rich" }, { name = "typing-extensions" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/83/8e/ab512afd71d4e67bb611a57db92a0e967304c97ec61963e99103f5a88069/rich_toolkit-0.16.0.tar.gz", hash = "sha256:2f554b00b194776639f4d80f2706980756b659ceed9f345ebbd9de77d1bdd0f4", size = 183790, upload-time = "2025-11-19T15:26:11.431Z" } +sdist = { url = "https://files.pythonhosted.org/packages/ad/d0/8f8de36e1abf8339b497ce700dd7251ca465ffca4a1976969b0eaeb596fb/rich_toolkit-0.17.0.tar.gz", hash = "sha256:17ca7a32e613001aa0945ddea27a246f6de01dfc4c12403254c057a8ee542977", size = 187955, upload-time = "2025-11-27T11:10:24.863Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/3a/04/f4bfb5d8a258d395d7fb6fbaa0e3fe7bafae17a2a3e2387e6dea9d6474df/rich_toolkit-0.16.0-py3-none-any.whl", hash = "sha256:3f4307f678c5c1e22c36d89ac05f1cd145ed7174f19c1ce5a4d3664ba77c0f9e", size = 29775, upload-time = "2025-11-19T15:26:10.336Z" }, + { url = "https://files.pythonhosted.org/packages/b2/42/ef2ed40699567661d03b0b511ac46cf6cee736de8f3666819c12d6d20696/rich_toolkit-0.17.0-py3-none-any.whl", hash = "sha256:06fb47a5c5259d6b480287cd38aff5f551b6e1a307f90ed592453dd360e4e71e", size = 31412, upload-time = "2025-11-27T11:10:23.847Z" }, ] [[package]] @@ -2139,53 +2145,53 @@ wheels = [ [[package]] name = "ruff" -version = "0.14.6" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/52/f0/62b5a1a723fe183650109407fa56abb433b00aa1c0b9ba555f9c4efec2c6/ruff-0.14.6.tar.gz", hash = "sha256:6f0c742ca6a7783a736b867a263b9a7a80a45ce9bee391eeda296895f1b4e1cc", size = 5669501, upload-time = "2025-11-21T14:26:17.903Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/67/d2/7dd544116d107fffb24a0064d41a5d2ed1c9d6372d142f9ba108c8e39207/ruff-0.14.6-py3-none-linux_armv6l.whl", hash = "sha256:d724ac2f1c240dbd01a2ae98db5d1d9a5e1d9e96eba999d1c48e30062df578a3", size = 13326119, upload-time = "2025-11-21T14:25:24.2Z" }, - { url = "https://files.pythonhosted.org/packages/36/6a/ad66d0a3315d6327ed6b01f759d83df3c4d5f86c30462121024361137b6a/ruff-0.14.6-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:9f7539ea257aa4d07b7ce87aed580e485c40143f2473ff2f2b75aee003186004", size = 13526007, upload-time = "2025-11-21T14:25:26.906Z" }, - { url = "https://files.pythonhosted.org/packages/a3/9d/dae6db96df28e0a15dea8e986ee393af70fc97fd57669808728080529c37/ruff-0.14.6-py3-none-macosx_11_0_arm64.whl", hash = "sha256:7f6007e55b90a2a7e93083ba48a9f23c3158c433591c33ee2e99a49b889c6332", size = 12676572, upload-time = "2025-11-21T14:25:29.826Z" }, - { url = "https://files.pythonhosted.org/packages/76/a4/f319e87759949062cfee1b26245048e92e2acce900ad3a909285f9db1859/ruff-0.14.6-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0a8e7b9d73d8728b68f632aa8e824ef041d068d231d8dbc7808532d3629a6bef", size = 13140745, upload-time = "2025-11-21T14:25:32.788Z" }, - { url = "https://files.pythonhosted.org/packages/95/d3/248c1efc71a0a8ed4e8e10b4b2266845d7dfc7a0ab64354afe049eaa1310/ruff-0.14.6-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:d50d45d4553a3ebcbd33e7c5e0fe6ca4aafd9a9122492de357205c2c48f00775", size = 13076486, upload-time = "2025-11-21T14:25:35.601Z" }, - { url = "https://files.pythonhosted.org/packages/a5/19/b68d4563fe50eba4b8c92aa842149bb56dd24d198389c0ed12e7faff4f7d/ruff-0.14.6-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:118548dd121f8a21bfa8ab2c5b80e5b4aed67ead4b7567790962554f38e598ce", size = 13727563, upload-time = "2025-11-21T14:25:38.514Z" }, - { url = "https://files.pythonhosted.org/packages/47/ac/943169436832d4b0e867235abbdb57ce3a82367b47e0280fa7b4eabb7593/ruff-0.14.6-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:57256efafbfefcb8748df9d1d766062f62b20150691021f8ab79e2d919f7c11f", size = 15199755, upload-time = "2025-11-21T14:25:41.516Z" }, - { url = "https://files.pythonhosted.org/packages/c9/b9/288bb2399860a36d4bb0541cb66cce3c0f4156aaff009dc8499be0c24bf2/ruff-0.14.6-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ff18134841e5c68f8e5df1999a64429a02d5549036b394fafbe410f886e1989d", size = 14850608, upload-time = "2025-11-21T14:25:44.428Z" }, - { url = "https://files.pythonhosted.org/packages/ee/b1/a0d549dd4364e240f37e7d2907e97ee80587480d98c7799d2d8dc7a2f605/ruff-0.14.6-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:29c4b7ec1e66a105d5c27bd57fa93203637d66a26d10ca9809dc7fc18ec58440", size = 14118754, upload-time = "2025-11-21T14:25:47.214Z" }, - { url = "https://files.pythonhosted.org/packages/13/ac/9b9fe63716af8bdfddfacd0882bc1586f29985d3b988b3c62ddce2e202c3/ruff-0.14.6-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:167843a6f78680746d7e226f255d920aeed5e4ad9c03258094a2d49d3028b105", size = 13949214, upload-time = "2025-11-21T14:25:50.002Z" }, - { url = "https://files.pythonhosted.org/packages/12/27/4dad6c6a77fede9560b7df6802b1b697e97e49ceabe1f12baf3ea20862e9/ruff-0.14.6-py3-none-manylinux_2_31_riscv64.whl", hash = "sha256:16a33af621c9c523b1ae006b1b99b159bf5ac7e4b1f20b85b2572455018e0821", size = 14106112, upload-time = "2025-11-21T14:25:52.841Z" }, - { url = "https://files.pythonhosted.org/packages/6a/db/23e322d7177873eaedea59a7932ca5084ec5b7e20cb30f341ab594130a71/ruff-0.14.6-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:1432ab6e1ae2dc565a7eea707d3b03a0c234ef401482a6f1621bc1f427c2ff55", size = 13035010, upload-time = "2025-11-21T14:25:55.536Z" }, - { url = "https://files.pythonhosted.org/packages/a8/9c/20e21d4d69dbb35e6a1df7691e02f363423658a20a2afacf2a2c011800dc/ruff-0.14.6-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:4c55cfbbe7abb61eb914bfd20683d14cdfb38a6d56c6c66efa55ec6570ee4e71", size = 13054082, upload-time = "2025-11-21T14:25:58.625Z" }, - { url = "https://files.pythonhosted.org/packages/66/25/906ee6a0464c3125c8d673c589771a974965c2be1a1e28b5c3b96cb6ef88/ruff-0.14.6-py3-none-musllinux_1_2_i686.whl", hash = "sha256:efea3c0f21901a685fff4befda6d61a1bf4cb43de16da87e8226a281d614350b", size = 13303354, upload-time = "2025-11-21T14:26:01.816Z" }, - { url = "https://files.pythonhosted.org/packages/4c/58/60577569e198d56922b7ead07b465f559002b7b11d53f40937e95067ca1c/ruff-0.14.6-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:344d97172576d75dc6afc0e9243376dbe1668559c72de1864439c4fc95f78185", size = 14054487, upload-time = "2025-11-21T14:26:05.058Z" }, - { url = "https://files.pythonhosted.org/packages/67/0b/8e4e0639e4cc12547f41cb771b0b44ec8225b6b6a93393176d75fe6f7d40/ruff-0.14.6-py3-none-win32.whl", hash = "sha256:00169c0c8b85396516fdd9ce3446c7ca20c2a8f90a77aa945ba6b8f2bfe99e85", size = 13013361, upload-time = "2025-11-21T14:26:08.152Z" }, - { url = "https://files.pythonhosted.org/packages/fb/02/82240553b77fd1341f80ebb3eaae43ba011c7a91b4224a9f317d8e6591af/ruff-0.14.6-py3-none-win_amd64.whl", hash = "sha256:390e6480c5e3659f8a4c8d6a0373027820419ac14fa0d2713bd8e6c3e125b8b9", size = 14432087, upload-time = "2025-11-21T14:26:10.891Z" }, - { url = "https://files.pythonhosted.org/packages/a5/1f/93f9b0fad9470e4c829a5bb678da4012f0c710d09331b860ee555216f4ea/ruff-0.14.6-py3-none-win_arm64.whl", hash = "sha256:d43c81fbeae52cfa8728d8766bbf46ee4298c888072105815b392da70ca836b2", size = 13520930, upload-time = "2025-11-21T14:26:13.951Z" }, +version = "0.14.8" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/ed/d9/f7a0c4b3a2bf2556cd5d99b05372c29980249ef71e8e32669ba77428c82c/ruff-0.14.8.tar.gz", hash = "sha256:774ed0dd87d6ce925e3b8496feb3a00ac564bea52b9feb551ecd17e0a23d1eed", size = 5765385, upload-time = "2025-12-04T15:06:17.669Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/48/b8/9537b52010134b1d2b72870cc3f92d5fb759394094741b09ceccae183fbe/ruff-0.14.8-py3-none-linux_armv6l.whl", hash = "sha256:ec071e9c82eca417f6111fd39f7043acb53cd3fde9b1f95bbed745962e345afb", size = 13441540, upload-time = "2025-12-04T15:06:14.896Z" }, + { url = "https://files.pythonhosted.org/packages/24/00/99031684efb025829713682012b6dd37279b1f695ed1b01725f85fd94b38/ruff-0.14.8-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:8cdb162a7159f4ca36ce980a18c43d8f036966e7f73f866ac8f493b75e0c27e9", size = 13669384, upload-time = "2025-12-04T15:06:51.809Z" }, + { url = "https://files.pythonhosted.org/packages/72/64/3eb5949169fc19c50c04f28ece2c189d3b6edd57e5b533649dae6ca484fe/ruff-0.14.8-py3-none-macosx_11_0_arm64.whl", hash = "sha256:2e2fcbefe91f9fad0916850edf0854530c15bd1926b6b779de47e9ab619ea38f", size = 12806917, upload-time = "2025-12-04T15:06:08.925Z" }, + { url = "https://files.pythonhosted.org/packages/c4/08/5250babb0b1b11910f470370ec0cbc67470231f7cdc033cee57d4976f941/ruff-0.14.8-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a9d70721066a296f45786ec31916dc287b44040f553da21564de0ab4d45a869b", size = 13256112, upload-time = "2025-12-04T15:06:23.498Z" }, + { url = "https://files.pythonhosted.org/packages/78/4c/6c588e97a8e8c2d4b522c31a579e1df2b4d003eddfbe23d1f262b1a431ff/ruff-0.14.8-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:2c87e09b3cd9d126fc67a9ecd3b5b1d3ded2b9c7fce3f16e315346b9d05cfb52", size = 13227559, upload-time = "2025-12-04T15:06:33.432Z" }, + { url = "https://files.pythonhosted.org/packages/23/ce/5f78cea13eda8eceac71b5f6fa6e9223df9b87bb2c1891c166d1f0dce9f1/ruff-0.14.8-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1d62cb310c4fbcb9ee4ac023fe17f984ae1e12b8a4a02e3d21489f9a2a5f730c", size = 13896379, upload-time = "2025-12-04T15:06:02.687Z" }, + { url = "https://files.pythonhosted.org/packages/cf/79/13de4517c4dadce9218a20035b21212a4c180e009507731f0d3b3f5df85a/ruff-0.14.8-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:1af35c2d62633d4da0521178e8a2641c636d2a7153da0bac1b30cfd4ccd91344", size = 15372786, upload-time = "2025-12-04T15:06:29.828Z" }, + { url = "https://files.pythonhosted.org/packages/00/06/33df72b3bb42be8a1c3815fd4fae83fa2945fc725a25d87ba3e42d1cc108/ruff-0.14.8-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:25add4575ffecc53d60eed3f24b1e934493631b48ebbc6ebaf9d8517924aca4b", size = 14990029, upload-time = "2025-12-04T15:06:36.812Z" }, + { url = "https://files.pythonhosted.org/packages/64/61/0f34927bd90925880394de0e081ce1afab66d7b3525336f5771dcf0cb46c/ruff-0.14.8-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:4c943d847b7f02f7db4201a0600ea7d244d8a404fbb639b439e987edcf2baf9a", size = 14407037, upload-time = "2025-12-04T15:06:39.979Z" }, + { url = "https://files.pythonhosted.org/packages/96/bc/058fe0aefc0fbf0d19614cb6d1a3e2c048f7dc77ca64957f33b12cfdc5ef/ruff-0.14.8-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cb6e8bf7b4f627548daa1b69283dac5a296bfe9ce856703b03130732e20ddfe2", size = 14102390, upload-time = "2025-12-04T15:06:46.372Z" }, + { url = "https://files.pythonhosted.org/packages/af/a4/e4f77b02b804546f4c17e8b37a524c27012dd6ff05855d2243b49a7d3cb9/ruff-0.14.8-py3-none-manylinux_2_31_riscv64.whl", hash = "sha256:7aaf2974f378e6b01d1e257c6948207aec6a9b5ba53fab23d0182efb887a0e4a", size = 14230793, upload-time = "2025-12-04T15:06:20.497Z" }, + { url = "https://files.pythonhosted.org/packages/3f/52/bb8c02373f79552e8d087cedaffad76b8892033d2876c2498a2582f09dcf/ruff-0.14.8-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:e5758ca513c43ad8a4ef13f0f081f80f08008f410790f3611a21a92421ab045b", size = 13160039, upload-time = "2025-12-04T15:06:49.06Z" }, + { url = "https://files.pythonhosted.org/packages/1f/ad/b69d6962e477842e25c0b11622548df746290cc6d76f9e0f4ed7456c2c31/ruff-0.14.8-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:f74f7ba163b6e85a8d81a590363bf71618847e5078d90827749bfda1d88c9cdf", size = 13205158, upload-time = "2025-12-04T15:06:54.574Z" }, + { url = "https://files.pythonhosted.org/packages/06/63/54f23da1315c0b3dfc1bc03fbc34e10378918a20c0b0f086418734e57e74/ruff-0.14.8-py3-none-musllinux_1_2_i686.whl", hash = "sha256:eed28f6fafcc9591994c42254f5a5c5ca40e69a30721d2ab18bb0bb3baac3ab6", size = 13469550, upload-time = "2025-12-04T15:05:59.209Z" }, + { url = "https://files.pythonhosted.org/packages/70/7d/a4d7b1961e4903bc37fffb7ddcfaa7beb250f67d97cfd1ee1d5cddb1ec90/ruff-0.14.8-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:21d48fa744c9d1cb8d71eb0a740c4dd02751a5de9db9a730a8ef75ca34cf138e", size = 14211332, upload-time = "2025-12-04T15:06:06.027Z" }, + { url = "https://files.pythonhosted.org/packages/5d/93/2a5063341fa17054e5c86582136e9895db773e3c2ffb770dde50a09f35f0/ruff-0.14.8-py3-none-win32.whl", hash = "sha256:15f04cb45c051159baebb0f0037f404f1dc2f15a927418f29730f411a79bc4e7", size = 13151890, upload-time = "2025-12-04T15:06:11.668Z" }, + { url = "https://files.pythonhosted.org/packages/02/1c/65c61a0859c0add13a3e1cbb6024b42de587456a43006ca2d4fd3d1618fe/ruff-0.14.8-py3-none-win_amd64.whl", hash = "sha256:9eeb0b24242b5bbff3011409a739929f497f3fb5fe3b5698aba5e77e8c833097", size = 14537826, upload-time = "2025-12-04T15:06:26.409Z" }, + { url = "https://files.pythonhosted.org/packages/6d/63/8b41cea3afd7f58eb64ac9251668ee0073789a3bc9ac6f816c8c6fef986d/ruff-0.14.8-py3-none-win_arm64.whl", hash = "sha256:965a582c93c63fe715fd3e3f8aa37c4b776777203d8e1d8aa3cc0c14424a4b99", size = 13634522, upload-time = "2025-12-04T15:06:43.212Z" }, ] [[package]] name = "s3transfer" -version = "0.15.0" +version = "0.16.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "botocore" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/ca/bb/940d6af975948c1cc18f44545ffb219d3c35d78ec972b42ae229e8e37e08/s3transfer-0.15.0.tar.gz", hash = "sha256:d36fac8d0e3603eff9b5bfa4282c7ce6feb0301a633566153cbd0b93d11d8379", size = 152185, upload-time = "2025-11-20T20:28:56.327Z" } +sdist = { url = "https://files.pythonhosted.org/packages/05/04/74127fc843314818edfa81b5540e26dd537353b123a4edc563109d8f17dd/s3transfer-0.16.0.tar.gz", hash = "sha256:8e990f13268025792229cd52fa10cb7163744bf56e719e0b9cb925ab79abf920", size = 153827, upload-time = "2025-12-01T02:30:59.114Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/5f/e1/5ef25f52973aa12a19cf4e1375d00932d7fb354ffd310487ba7d44225c1a/s3transfer-0.15.0-py3-none-any.whl", hash = "sha256:6f8bf5caa31a0865c4081186689db1b2534cef721d104eb26101de4b9d6a5852", size = 85984, upload-time = "2025-11-20T20:28:55.046Z" }, + { url = "https://files.pythonhosted.org/packages/fc/51/727abb13f44c1fcf6d145979e1535a35794db0f6e450a0cb46aa24732fe2/s3transfer-0.16.0-py3-none-any.whl", hash = "sha256:18e25d66fed509e3868dc1572b3f427ff947dd2c56f844a5bf09481ad3f3b2fe", size = 86830, upload-time = "2025-12-01T02:30:57.729Z" }, ] [[package]] name = "sentry-sdk" -version = "2.46.0" +version = "2.47.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "certifi" }, { name = "urllib3" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/7c/d7/c140a5837649e2bf2ec758494fde1d9a016c76777eab64e75ef38d685bbb/sentry_sdk-2.46.0.tar.gz", hash = "sha256:91821a23460725734b7741523021601593f35731808afc0bb2ba46c27b8acd91", size = 374761, upload-time = "2025-11-24T09:34:13.932Z" } +sdist = { url = "https://files.pythonhosted.org/packages/4a/2a/d225cbf87b6c8ecce5664db7bcecb82c317e448e3b24a2dcdaacb18ca9a7/sentry_sdk-2.47.0.tar.gz", hash = "sha256:8218891d5e41b4ea8d61d2aed62ed10c80e39d9f2959d6f939efbf056857e050", size = 381895, upload-time = "2025-12-03T14:06:36.846Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/4b/b6/ce7c502a366f4835b1f9c057753f6989a92d3c70cbadb168193f5fb7499b/sentry_sdk-2.46.0-py2.py3-none-any.whl", hash = "sha256:4eeeb60198074dff8d066ea153fa6f241fef1668c10900ea53a4200abc8da9b1", size = 406266, upload-time = "2025-11-24T09:34:12.114Z" }, + { url = "https://files.pythonhosted.org/packages/bd/ac/d6286ea0d49e7b58847faf67b00e56bb4ba3d525281e2ac306e1f1f353da/sentry_sdk-2.47.0-py2.py3-none-any.whl", hash = "sha256:d72f8c61025b7d1d9e52510d03a6247b280094a327dd900d987717a4fce93412", size = 411088, upload-time = "2025-12-03T14:06:35.374Z" }, ] [[package]] @@ -2206,15 +2212,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/b7/ce/149a00dd41f10bc29e5921b496af8b574d8413afcd5e30dfa0ed46c2cc5e/six-1.17.0-py2.py3-none-any.whl", hash = "sha256:4721f391ed90541fddacab5acf947aa0d3dc7d27b2e1e8eda2be8970586c3274", size = 11050, upload-time = "2024-12-04T17:35:26.475Z" }, ] -[[package]] -name = "sniffio" -version = "1.3.1" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/a2/87/a6771e1546d97e7e041b6ae58d80074f81b7d5121207425c964ddf5cfdbd/sniffio-1.3.1.tar.gz", hash = "sha256:f4324edc670a0f49750a81b895f35c3adb843cca46f0530f79fc1babb23789dc", size = 20372, upload-time = "2024-02-25T23:20:04.057Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/e9/44/75a9c9421471a6c4805dbf2356f7c181a29c1879239abab1ea2cc8f38b40/sniffio-1.3.1-py3-none-any.whl", hash = "sha256:2f6da418d1f1e0fddd844478f41680e794e6051915791a034ff65e5f100525a2", size = 10235, upload-time = "2024-02-25T23:20:01.196Z" }, -] - [[package]] name = "soupsieve" version = "2.8" @@ -2355,11 +2352,11 @@ wheels = [ [[package]] name = "urllib3" -version = "2.5.0" +version = "2.6.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/15/22/9ee70a2574a4f4599c47dd506532914ce044817c7752a79b6a51286319bc/urllib3-2.5.0.tar.gz", hash = "sha256:3fc47733c7e419d4bc3f6b3dc2b4f890bb743906a30d56ba4a5bfa4bbff92760", size = 393185, upload-time = "2025-06-18T14:07:41.644Z" } +sdist = { url = "https://files.pythonhosted.org/packages/1c/43/554c2569b62f49350597348fc3ac70f786e3c32e7f19d266e19817812dd3/urllib3-2.6.0.tar.gz", hash = "sha256:cb9bcef5a4b345d5da5d145dc3e30834f58e8018828cbc724d30b4cb7d4d49f1", size = 432585, upload-time = "2025-12-05T15:08:47.885Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/a7/c2/fe1e52489ae3122415c51f387e221dd0773709bad6c6cdaa599e8a2c5185/urllib3-2.5.0-py3-none-any.whl", hash = "sha256:e6b01673c0fa6a13e374b50871808eb3bf7046c4b125b216f6bf1cc604cff0dc", size = 129795, upload-time = "2025-06-18T14:07:40.39Z" }, + { url = "https://files.pythonhosted.org/packages/56/1a/9ffe814d317c5224166b23e7c47f606d6e473712a2fad0f704ea9b99f246/urllib3-2.6.0-py3-none-any.whl", hash = "sha256:c90f7a39f716c572c4e3e58509581ebd83f9b59cced005b7db7ad2d22b0db99f", size = 131083, upload-time = "2025-12-05T15:08:45.983Z" }, ] [[package]] From d74517dde9dc8f4085cad29faac14490b6867469 Mon Sep 17 00:00:00 2001 From: Simon van Lierde Date: Mon, 8 Dec 2025 11:58:36 +0000 Subject: [PATCH 70/71] fix(backend): Revert to old-school sqlalchemy typing to fix runtime ORM issues --- backend/app/api/auth/models.py | 4 ++-- backend/app/api/background_data/models.py | 2 +- backend/app/api/data_collection/models.py | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/backend/app/api/auth/models.py b/backend/app/api/auth/models.py index c804717..574c259 100644 --- a/backend/app/api/auth/models.py +++ b/backend/app/api/auth/models.py @@ -68,7 +68,7 @@ class User(SQLModelBaseUserDB, CustomBaseBare, UserBase, TimeStampMixinBare, tab nullable=True, ), ) - organization: Optional[Organization] = Relationship( # noqa: UP045 # Using 'Optional' over Organization | None to avoid issues with sqlmodel type detection + organization: Optional["Organization"] = Relationship( back_populates="members", sa_relationship_kwargs={ "lazy": "selectin", @@ -79,7 +79,7 @@ class User(SQLModelBaseUserDB, CustomBaseBare, UserBase, TimeStampMixinBare, tab organization_role: OrganizationRole | None = Field(default=None, sa_column=Column(SAEnum(OrganizationRole))) # One-to-one relationship with owned Organization - owned_organization: Optional[Organization] = Relationship( # noqa: UP045 # Using 'Optional' over Organization | None to avoid issues with sqlmodel type detection + owned_organization: Optional["Organization"] = Relationship( back_populates="owner", sa_relationship_kwargs={ "uselist": False, diff --git a/backend/app/api/background_data/models.py b/backend/app/api/background_data/models.py index 2ee8f92..1f8bba6 100644 --- a/backend/app/api/background_data/models.py +++ b/backend/app/api/background_data/models.py @@ -89,7 +89,7 @@ class Category(CategoryBase, TimeStampMixinBare, table=True): # Self-referential relationship supercategory_id: int | None = Field(foreign_key="category.id", default=None, nullable=True) - supercategory: Optional[Category] = Relationship( # noqa: UP045 # Using 'Optional' over Category | None to avoid issues with sqlmodel type detection + supercategory: Optional["Category"] = Relationship( back_populates="subcategories", sa_relationship_kwargs={"remote_side": "Category.id", "lazy": "selectin", "join_depth": 1}, ) diff --git a/backend/app/api/data_collection/models.py b/backend/app/api/data_collection/models.py index 1261a22..22b3585 100644 --- a/backend/app/api/data_collection/models.py +++ b/backend/app/api/data_collection/models.py @@ -124,7 +124,7 @@ class Product(ProductBase, TimeStampMixinBare, table=True): # Self-referential relationship for hierarchy parent_id: int | None = Field(default=None, foreign_key="product.id") - parent: Optional[Product] = Relationship( # noqa: UP045 # Using 'Optional' over Product | None to avoid issues with sqlmodel type detection + parent: Optional["Product"] = Relationship( back_populates="components", sa_relationship_kwargs={ "uselist": False, From c6665bd8d7205319bc393205b1c62e1550f48bca Mon Sep 17 00:00:00 2001 From: Simon van Lierde Date: Mon, 8 Dec 2025 16:33:34 +0000 Subject: [PATCH 71/71] feat(backend): Add timeout and use-cookies vars to rclone backup script --- .env.example | 2 ++ backend/scripts/backup/rclone_backup.sh | 8 ++++++-- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/.env.example b/.env.example index 57e0a49..277b256 100644 --- a/.env.example +++ b/.env.example @@ -16,3 +16,5 @@ BACKUP_RSYNC_REMOTE_PATH=/path/to/remote/backup # Remote rclone backup config (for use of backend/scripts/backup/rclone_backup.sh script) BACKUP_RCLONE_REMOTE=myremote:/path/to/remote/backup BACKUP_RCLONE_MULTI_THREAD_STREAMS=16 +BACKUP_RCLONE_TIMEOUT=5m +BACKUP_RCLONE_USE_COOKIES=false diff --git a/backend/scripts/backup/rclone_backup.sh b/backend/scripts/backup/rclone_backup.sh index 16d9db3..b72f2e8 100755 --- a/backend/scripts/backup/rclone_backup.sh +++ b/backend/scripts/backup/rclone_backup.sh @@ -16,8 +16,10 @@ fi # Configuration BACKUP_DIR="${BACKUP_DIR:-$REPO_ROOT/backend/backups}" -BACKUP_RCLONE_REMOTE="${BACKUP_RCLONE_REMOTE?BACKUP_RCLONE_REMOTE not set}" # e.g., "myremote:/backup/relab" +BACKUP_RCLONE_REMOTE="${BACKUP_RCLONE_REMOTE?BACKUP_RCLONE_REMOTE not set}" BACKUP_RCLONE_MULTI_THREAD_STREAMS="${BACKUP_RCLONE_MULTI_THREAD_STREAMS:-16}" +BACKUP_RCLONE_TIMEOUT="${BACKUP_RCLONE_TIMEOUT:-5m}" +BACKUP_RCLONE_USE_COOKIES="${BACKUP_RCLONE_USE_COOKIES:-false}" # Safety Check: If the local dir has 0 files AND the remote has more than 0 files, abort. LOCAL_FILE_COUNT=$(find "$BACKUP_DIR" -type f | wc -l) @@ -37,7 +39,9 @@ rclone sync "$BACKUP_DIR" "$BACKUP_RCLONE_REMOTE" \ --retries 3 \ --low-level-retries 10 \ --stats=30s \ - --stats-one-line-date + --stats-one-line-date \ + --timeout="$BACKUP_RCLONE_TIMEOUT" \ + --use-cookies="$BACKUP_RCLONE_USE_COOKIES" echo "[$(date)] Sync complete. Remote backup stats after sync:" rclone size "$BACKUP_RCLONE_REMOTE" --max-depth=3 2>/dev/null | sed 's/^/ /'