commit 68589a358e40a234358892a4f3cf974ad82467c7 Author: fn-registry agent Date: Thu Apr 30 16:03:25 2026 +0200 chore: sync from fn-registry agent diff --git a/.claude/CLAUDE.md b/.claude/CLAUDE.md new file mode 100644 index 0000000..36a65c7 --- /dev/null +++ b/.claude/CLAUDE.md @@ -0,0 +1,40 @@ +# JUPYTER HABILITADO EN ESTE ANALISIS + +## Reglas OBLIGATORIAS para Claude + +### 1. CODIGO INMUTABLE — NUNCA MODIFICAR CELDAS EXISTENTES +- **PROHIBIDO** usar NotebookEdit para reemplazar celdas existentes +- **SIEMPRE** anadir celdas NUEVAS al final del notebook +- Si hay un error en una celda, crear celda nueva con la correccion +- El historial de trabajo debe quedar intacto para trazabilidad + +### 2. PROGRAMACION FUNCIONAL OBLIGATORIA +- **Funciones puras**: sin efectos secundarios, mismo input -> mismo output +- **Inmutabilidad**: nunca mutar datos, crear copias transformadas +- **Composicion**: funciones pequenas que se combinan +- Preferir: `map`, `filter`, `reduce`, list comprehensions +- Evitar: loops con mutacion, `global`, modificar argumentos in-place + +### 3. SIEMPRE usar MCP jupyter para ejecutar codigo Python +- Las ejecuciones se ven en tiempo real en Jupyter Lab del usuario +- Compartimos variables y estado del kernel +- **NUNCA usar bash para ejecutar Python en este analisis** + +### 4. Verificar Jupyter activo ANTES de ejecutar +- Si no esta activo: pedir al usuario que ejecute `./run-jupyter-lab.sh` + +### 5. Gestion de notebooks +- Notebooks en la carpeta `notebooks/` o subcarpetas +- Si un notebook tiene >50 celdas, crear uno nuevo +- Nombrar descriptivamente: `01_exploracion.ipynb`, `02_limpieza.ipynb` + +### 6. Gestion de Python +- **SIEMPRE usar `uv`** para gestionar dependencias +- Anadir paquetes con `uv add nombre_paquete` + +### 7. Acceso al fn_registry +- `FN_REGISTRY_ROOT` apunta a la raiz del registry +- Para importar funciones Python: `sys.path.insert(0, os.path.join(os.environ["FN_REGISTRY_ROOT"], "python", "functions"))` +- Para consultar registry.db: `sqlite3` o `import sqlite3` con la ruta `$FN_REGISTRY_ROOT/registry.db` + + diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..9f24977 --- /dev/null +++ b/.gitignore @@ -0,0 +1,40 @@ +# Python venv (regenerable con uv sync) +.venv/ + +# Secrets +.env +.env.* + +# Data local (per-PC, no se sube) +data/ + +# Jupyter runtime (per-PC) +.jupyter/ +.jupyter-port +.jupyter_ystore.db +.mcp.json + +# IPython runtime — mantiene startup/ (registry helpers), ignora el resto +.ipython/profile_default/history.sqlite +.ipython/profile_default/log/ +.ipython/profile_default/db/ +.ipython/profile_default/security/ + +# Python bytecode +__pycache__/ +*.pyc +*.pyo + +# Jupyter checkpoints +.ipynb_checkpoints/ +**/.ipynb_checkpoints/ + +# Operations DB +operations.db +operations.db-shm +operations.db-wal +operations.db-journal + +# OS +.DS_Store +Thumbs.db diff --git a/.ipython/profile_default/startup/00_fn_registry.py b/.ipython/profile_default/startup/00_fn_registry.py new file mode 100644 index 0000000..3384300 --- /dev/null +++ b/.ipython/profile_default/startup/00_fn_registry.py @@ -0,0 +1,100 @@ +""" +fn_registry kernel startup +Autoconfigura acceso al registry en cada notebook. +Generado por write_jupyter_registry_kernel (fn_registry). +""" +import os +import sys +import sqlite3 +from pathlib import Path + +# ── FN_REGISTRY_ROOT ──────────────────────────────────────── +# Prioridad: env var > path hardcoded > descubrimiento automatico +def _discover_registry_root(): + if os.environ.get("FN_REGISTRY_ROOT"): + return Path(os.environ["FN_REGISTRY_ROOT"]).resolve() + hardcoded = Path("/home/egutierrez/fn_registry") + if (hardcoded / "registry.db").exists(): + return hardcoded + # Subir desde CWD hasta encontrar registry.db + p = Path.cwd() + for _ in range(10): + if (p / "registry.db").exists(): + return p + if p.parent == p: + break + p = p.parent + return hardcoded + +FN_REGISTRY_ROOT = _discover_registry_root() +os.environ["FN_REGISTRY_ROOT"] = str(FN_REGISTRY_ROOT) + +# ── sys.path: importar funciones Python del registry ──────── +_python_functions = FN_REGISTRY_ROOT / "python" / "functions" +for _domain in sorted(_python_functions.iterdir()) if _python_functions.exists() else []: + if _domain.is_dir() and not _domain.name.startswith("_"): + _path = str(_domain) + if _path not in sys.path: + sys.path.insert(0, _path) + +# Tambien el directorio padre para imports por dominio: from core import filter_list +_pf = str(_python_functions) +if _pf not in sys.path: + sys.path.insert(0, _pf) + +# ── fn_query: consultar registry.db desde el notebook ─────── +_REGISTRY_DB = FN_REGISTRY_ROOT / "registry.db" + +def fn_query(sql, params=()): + """Ejecuta una consulta SQL sobre registry.db y retorna las filas. + + Ejemplos: + fn_query("SELECT id, description FROM functions WHERE domain = ?", ("finance",)) + fn_query("SELECT id FROM functions_fts WHERE functions_fts MATCH ?", ("slice*",)) + """ + if not _REGISTRY_DB.exists(): + raise FileNotFoundError(f"registry.db no encontrado en {_REGISTRY_DB}") + con = sqlite3.connect(str(_REGISTRY_DB)) + con.row_factory = sqlite3.Row + try: + rows = con.execute(sql, params).fetchall() + return [dict(r) for r in rows] + finally: + con.close() + +def fn_search(term): + """Busca funciones y tipos en el registry por nombre o descripcion. + + Ejemplo: + fn_search("slice") + fn_search("finance") + """ + fts_term = f"name:{term}* OR description:{term}*" + functions = fn_query( + "SELECT id, kind, purity, lang, description FROM functions " + "WHERE id IN (SELECT id FROM functions_fts WHERE functions_fts MATCH ?) " + "ORDER BY name", (fts_term,) + ) + types = fn_query( + "SELECT id, algebraic, lang, description FROM types " + "WHERE id IN (SELECT id FROM types_fts WHERE types_fts MATCH ?) " + "ORDER BY name", (fts_term,) + ) + return {"functions": functions, "types": types} + +def fn_code(function_id): + """Retorna el codigo fuente de una funcion del registry. + + Ejemplo: + print(fn_code("filter_list_py_core")) + """ + rows = fn_query("SELECT code FROM functions WHERE id = ?", (function_id,)) + if not rows: + raise KeyError(f"Funcion no encontrada: {function_id}") + return rows[0]["code"] + +# ── Mensaje de bienvenida ─────────────────────────────────── +print(f"fn_registry conectado: {FN_REGISTRY_ROOT}") +print(f" registry.db: {'OK' if _REGISTRY_DB.exists() else 'NO ENCONTRADO'}") +print(f" Python functions: {_pf}") +print(f" Helpers: fn_query(), fn_search(), fn_code()") diff --git a/.python-version b/.python-version new file mode 100644 index 0000000..24ee5b1 --- /dev/null +++ b/.python-version @@ -0,0 +1 @@ +3.13 diff --git a/README.md b/README.md new file mode 100644 index 0000000..e69de29 diff --git a/analysis.md b/analysis.md new file mode 100644 index 0000000..eeed621 --- /dev/null +++ b/analysis.md @@ -0,0 +1,17 @@ +--- +name: venta_web +lang: py +domain: datascience +description: "Exploracion de tablas relacionadas con venta web" +tags: [] +uses_functions: [] +uses_types: [] +framework: "jupyterlab" +entry_point: "notebooks/main.ipynb" +dir_path: "projects/aurgi/analysis/venta_web" +repo_url: "" +--- + +## Notas + +Exploracion de tablas relacionadas con venta web diff --git a/main.py b/main.py new file mode 100644 index 0000000..1fa5c7a --- /dev/null +++ b/main.py @@ -0,0 +1,6 @@ +def main(): + print("Hello from venta-web!") + + +if __name__ == "__main__": + main() diff --git a/notebooks/01_exploracion_venta_web.ipynb b/notebooks/01_exploracion_venta_web.ipynb new file mode 100644 index 0000000..57bf1ca --- /dev/null +++ b/notebooks/01_exploracion_venta_web.ipynb @@ -0,0 +1,1404 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "e76ae307", + "metadata": {}, + "source": [ + "# Exploracion Venta Web — Aurgi\n", + "\n", + "Objetivo: contrastar las consultas y fuentes de datos entre:\n", + "\n", + "- **Documents** Metabase: `2`, `3`, `4`, `8` — https://reports.autingo.es/document/{id}\n", + "- **Dashboard** `734` — *BI Ventas Portfolio Producto* (centros digital / venta web)\n", + "\n", + "Queremos descubrir qué queries ejecutan, qué databases/tablas usan y qué solapamiento hay entre ambas vistas." + ] + }, + { + "cell_type": "markdown", + "id": "f0d6c35f", + "metadata": {}, + "source": [ + "## 1. Setup — cliente Metabase\n", + "\n", + "Usamos la funcion `MetabaseClient` del registry (`python/functions/metabase/client.py`).\n", + "La API key vive en `./.env` (gitignored) y tambien en `pass metabase/aurgi-api-key`." + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "id": "30c7e035", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Conectado a https://reports.autingo.es como api-key-user-e55e1da7-c8ea-4268-9faf-84343fd72150@api-key.invalid (id=301, admin=True)\n" + ] + } + ], + "source": [ + "import os, json, re\n", + "from pathlib import Path\n", + "import pandas as pd\n", + "from IPython.display import Markdown, display\n", + "\n", + "# Cargar .env local\n", + "env_path = Path('.env') if Path('.env').exists() else Path('../.env')\n", + "for line in env_path.read_text().splitlines():\n", + " if line and not line.startswith('#') and '=' in line:\n", + " k, v = line.split('=', 1)\n", + " os.environ.setdefault(k.strip(), v.strip())\n", + "\n", + "# Importar modulo metabase del registry (el kernel startup ya inyecta el sys.path)\n", + "from metabase import MetabaseClient, metabase_get_dashboard, metabase_get_document, metabase_get_card, metabase_list_databases\n", + "\n", + "URL = os.environ['METABASE_URL']\n", + "KEY = os.environ['METABASE_API_KEY']\n", + "client = MetabaseClient(URL, KEY)\n", + "\n", + "me = client.request('GET', '/api/user/current')\n", + "print(f\"Conectado a {URL} como {me.get('email')} (id={me.get('id')}, admin={me.get('is_superuser')})\")\n", + "pd.set_option('display.max_colwidth', 120)" + ] + }, + { + "cell_type": "markdown", + "id": "35825d9c", + "metadata": {}, + "source": [ + "## 2. Databases disponibles\n", + "\n", + "Para entender de donde vienen los datos necesitamos el catalogo de databases." + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "id": "ce7e91e6", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
idnameenginedbname
02ANJANA_DBpostgresproduction
138Call Center Analysispostgrescall-center-analysis
239CGDATApostgrescglass-data
33CuidamosTuCoche.netmysqlsanzauto_production_web
44DATACENTRIC_DB_STAGINGpostgresdatacentric_dev
56DCBigQuerybigquery-cloud-sdkNaN
637Plaza Pilotpostgresplaza_pilot_prod
75PRE STAGINGpostgresasync_datacentric_dev
840QA_DBpostgresqa_1
91Sample Databaseh2file:/plugins/sample-database.db;USER=GUEST;PASSWORD=guest
\n", + "
" + ], + "text/plain": [ + " id name engine \\\n", + "0 2 ANJANA_DB postgres \n", + "1 38 Call Center Analysis postgres \n", + "2 39 CGDATA postgres \n", + "3 3 CuidamosTuCoche.net mysql \n", + "4 4 DATACENTRIC_DB_STAGING postgres \n", + "5 6 DCBigQuery bigquery-cloud-sdk \n", + "6 37 Plaza Pilot postgres \n", + "7 5 PRE STAGING postgres \n", + "8 40 QA_DB postgres \n", + "9 1 Sample Database h2 \n", + "\n", + " dbname \n", + "0 production \n", + "1 call-center-analysis \n", + "2 cglass-data \n", + "3 sanzauto_production_web \n", + "4 datacentric_dev \n", + "5 NaN \n", + "6 plaza_pilot_prod \n", + "7 async_datacentric_dev \n", + "8 qa_1 \n", + "9 file:/plugins/sample-database.db;USER=GUEST;PASSWORD=guest " + ] + }, + "execution_count": 2, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "dbs = metabase_list_databases(client)\n", + "df_dbs = pd.DataFrame([\n", + " {'id': d['id'], 'name': d['name'], 'engine': d['engine'], 'dbname': (d.get('details') or {}).get('db') or (d.get('details') or {}).get('dbname')}\n", + " for d in dbs\n", + "])\n", + "df_dbs" + ] + }, + { + "cell_type": "markdown", + "id": "e42dc954", + "metadata": {}, + "source": [ + "## 3. Dashboard 734 — *BI Ventas Portfolio Producto*\n", + "\n", + "Extraemos metadata, tabs, parametros y todas las dashcards con su query." + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "id": "beefa761", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Dashboard 734: BI - VENTAS - PORTFOLIO PRODUCTO\n", + "Descripcion: -\n", + "Coleccion: 500 | Tabs: 11 | Dashcards: 94\n", + "Parameters: ['fecha', 'compa%C3%B1ia', 'centro', 'zona', 'comunidad_autonoma', 'provincia', 'jefe_regional', 'jefe_de_zona', 'rmo', 'tipo', 'categoria', 'subcategoria', 'producto', 'navid_producto', 'centro_1', 'centro_2', 'fecha_inicio', 'fecha_fin', 'temporada', 'marca', 'velocidad', 'ancho', 'carga', 'perfil', 'diametro', 'activo_%2F_no_activo']\n" + ] + } + ], + "source": [ + "dash = metabase_get_dashboard(client, 734)\n", + "print(f\"Dashboard {dash['id']}: {dash['name']}\")\n", + "print(f\"Descripcion: {dash.get('description') or '-'}\")\n", + "print(f\"Coleccion: {dash.get('collection_id')} | Tabs: {len(dash.get('tabs') or [])} | Dashcards: {len(dash.get('dashcards') or [])}\")\n", + "print(f\"Parameters: {[p.get('slug') or p.get('name') for p in (dash.get('parameters') or [])]}\")" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "id": "8b0feb87", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Total dashcards (incluye text/heading): 94 | con card real: 91\n" + ] + }, + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
dashcard_idtabcard_idnamedisplaytypedatabase_idhas_sql
03911Pelicula5686.0pelicula_categorias_semanaareaNone6.0False
13908Portafolio Producto5740.0Ventas TotalesscalarNone6.0False
23906Foto Centros - Compara SemanaNaNNaNNaNNoneNaNFalse
33907Foto Categorias - Compara SemanaNaNNaNNaNNoneNaNFalse
43914Portafolio Producto5673.0Evolucion de ventas por productobarNone6.0False
...........................
895885Foto Categorias - Compara Semana7519.0Objetivo por CategoríatableNone6.0False
9064195 Min View7708.0Margen € N-1scalarNone6.0False
9164205 Min View7709.0% MargenscalarNone6.0False
9264185 Min View7707.0Margen €scalarNone6.0False
9364215 Min View7710.0% Margen vs N-1scalarNone6.0False
\n", + "

94 rows × 8 columns

\n", + "
" + ], + "text/plain": [ + " dashcard_id tab card_id \\\n", + "0 3911 Pelicula 5686.0 \n", + "1 3908 Portafolio Producto 5740.0 \n", + "2 3906 Foto Centros - Compara Semana NaN \n", + "3 3907 Foto Categorias - Compara Semana NaN \n", + "4 3914 Portafolio Producto 5673.0 \n", + ".. ... ... ... \n", + "89 5885 Foto Categorias - Compara Semana 7519.0 \n", + "90 6419 5 Min View 7708.0 \n", + "91 6420 5 Min View 7709.0 \n", + "92 6418 5 Min View 7707.0 \n", + "93 6421 5 Min View 7710.0 \n", + "\n", + " name display type database_id has_sql \n", + "0 pelicula_categorias_semana area None 6.0 False \n", + "1 Ventas Totales scalar None 6.0 False \n", + "2 NaN NaN None NaN False \n", + "3 NaN NaN None NaN False \n", + "4 Evolucion de ventas por producto bar None 6.0 False \n", + ".. ... ... ... ... ... \n", + "89 Objetivo por Categoría table None 6.0 False \n", + "90 Margen € N-1 scalar None 6.0 False \n", + "91 % Margen scalar None 6.0 False \n", + "92 Margen € scalar None 6.0 False \n", + "93 % Margen vs N-1 scalar None 6.0 False \n", + "\n", + "[94 rows x 8 columns]" + ] + }, + "execution_count": 4, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# Resumen por tab\n", + "tabs = {t['id']: t['name'] for t in (dash.get('tabs') or [])}\n", + "\n", + "rows = []\n", + "for dc in dash.get('dashcards') or []:\n", + " card = dc.get('card') or {}\n", + " dq = card.get('dataset_query') or {}\n", + " rows.append({\n", + " 'dashcard_id': dc['id'],\n", + " 'tab': tabs.get(dc.get('dashboard_tab_id'), '-'),\n", + " 'card_id': card.get('id'),\n", + " 'name': card.get('name'),\n", + " 'display': card.get('display'),\n", + " 'type': dq.get('type'),\n", + " 'database_id': dq.get('database'),\n", + " 'has_sql': bool((dq.get('native') or {}).get('query')),\n", + " })\n", + "df_cards = pd.DataFrame(rows)\n", + "print(f\"Total dashcards (incluye text/heading): {len(df_cards)} | con card real: {df_cards['card_id'].notna().sum()}\")\n", + "df_cards" + ] + }, + { + "cell_type": "markdown", + "id": "9a295891", + "metadata": {}, + "source": [ + "### 3.1 Queries nativas (SQL) del dashboard\n", + "\n", + "Mostramos solo las cards que son SQL nativo (no MBQL), porque son las que revelan tablas directamente." + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "id": "13cace9f", + "metadata": {}, + "outputs": [], + "source": [ + "def card_query(dc):\n", + " card = dc.get('card') or {}\n", + " dq = card.get('dataset_query') or {}\n", + " if dq.get('type') == 'native':\n", + " return (dq.get('native') or {}).get('query')\n", + " return None\n", + "\n", + "for dc in dash.get('dashcards') or []:\n", + " q = card_query(dc)\n", + " if not q:\n", + " continue\n", + " card = dc['card']\n", + " print('='*80)\n", + " print(f\"card {card['id']} — {card['name']} [db={card['dataset_query'].get('database')}]\")\n", + " print('-'*80)\n", + " print(q.strip()[:2000])\n", + " if len(q) > 2000:\n", + " print(f'... ({len(q)-2000} chars mas)')\n", + " print()" + ] + }, + { + "cell_type": "markdown", + "id": "69f88d1d", + "metadata": {}, + "source": [ + "### 3.2 Tablas referenciadas\n", + "\n", + "Heuristica simple: regex sobre `FROM ...` y `JOIN ...` en las queries nativas." + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "id": "a544ae16", + "metadata": {}, + "outputs": [ + { + "ename": "KeyError", + "evalue": "'table'", + "output_type": "error", + "traceback": [ + "\u001b[31m---------------------------------------------------------------------------\u001b[39m", + "\u001b[31mKeyError\u001b[39m Traceback (most recent call last)", + "\u001b[36mCell\u001b[39m\u001b[36m \u001b[39m\u001b[32mIn[6]\u001b[39m\u001b[32m, line 21\u001b[39m\n\u001b[32m 17\u001b[39m \u001b[38;5;28;01mfor\u001b[39;00m t \u001b[38;5;28;01min\u001b[39;00m extract_tables(q):\n\u001b[32m 18\u001b[39m tbl_rows.append({\u001b[33m'card_id'\u001b[39m: card[\u001b[33m'id'\u001b[39m], \u001b[33m'card_name'\u001b[39m: card[\u001b[33m'name'\u001b[39m], \u001b[33m'db'\u001b[39m: card[\u001b[33m'dataset_query'\u001b[39m].get(\u001b[33m'database'\u001b[39m), \u001b[33m'table'\u001b[39m: t})\n\u001b[32m 19\u001b[39m \n\u001b[32m 20\u001b[39m df_tbls = pd.DataFrame(tbl_rows).drop_duplicates()\n\u001b[32m---> \u001b[39m\u001b[32m21\u001b[39m df_tbls.groupby(\u001b[33m'table'\u001b[39m).agg(cards=(\u001b[33m'card_id'\u001b[39m, \u001b[33m'nunique'\u001b[39m), sample_card=(\u001b[33m'card_name'\u001b[39m, \u001b[33m'first'\u001b[39m)).sort_values(\u001b[33m'cards'\u001b[39m, ascending=\u001b[38;5;28;01mFalse\u001b[39;00m)\n", + "\u001b[36mFile \u001b[39m\u001b[32m~/fn_registry/projects/aurgi/analysis/venta_web/.venv/lib/python3.13/site-packages/pandas/util/_decorators.py:336\u001b[39m, in \u001b[36mdeprecate_nonkeyword_arguments..decorate..wrapper\u001b[39m\u001b[34m(*args, **kwargs)\u001b[39m\n\u001b[32m 330\u001b[39m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;28mlen\u001b[39m(args) > num_allow_args:\n\u001b[32m 331\u001b[39m warnings.warn(\n\u001b[32m 332\u001b[39m msg.format(arguments=_format_argument_list(allow_args)),\n\u001b[32m 333\u001b[39m klass,\n\u001b[32m 334\u001b[39m stacklevel=find_stack_level(),\n\u001b[32m 335\u001b[39m )\n\u001b[32m--> \u001b[39m\u001b[32m336\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[43mfunc\u001b[49m\u001b[43m(\u001b[49m\u001b[43m*\u001b[49m\u001b[43margs\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43m*\u001b[49m\u001b[43m*\u001b[49m\u001b[43mkwargs\u001b[49m\u001b[43m)\u001b[49m\n", + "\u001b[36mFile \u001b[39m\u001b[32m~/fn_registry/projects/aurgi/analysis/venta_web/.venv/lib/python3.13/site-packages/pandas/core/frame.py:10821\u001b[39m, in \u001b[36mDataFrame.groupby\u001b[39m\u001b[34m(self, by, level, as_index, sort, group_keys, observed, dropna)\u001b[39m\n\u001b[32m 10817\u001b[39m \n\u001b[32m 10818\u001b[39m \u001b[38;5;28;01mif\u001b[39;00m level \u001b[38;5;28;01mis\u001b[39;00m \u001b[38;5;28;01mNone\u001b[39;00m \u001b[38;5;28;01mand\u001b[39;00m by \u001b[38;5;28;01mis\u001b[39;00m \u001b[38;5;28;01mNone\u001b[39;00m:\n\u001b[32m 10819\u001b[39m \u001b[38;5;28;01mraise\u001b[39;00m TypeError(\u001b[33m\"You have to supply one of 'by' and 'level'\"\u001b[39m)\n\u001b[32m 10820\u001b[39m \n\u001b[32m> \u001b[39m\u001b[32m10821\u001b[39m return DataFrameGroupBy(\n\u001b[32m 10822\u001b[39m obj=self,\n\u001b[32m 10823\u001b[39m keys=by,\n\u001b[32m 10824\u001b[39m level=level,\n", + "\u001b[36mFile \u001b[39m\u001b[32m~/fn_registry/projects/aurgi/analysis/venta_web/.venv/lib/python3.13/site-packages/pandas/core/groupby/groupby.py:1095\u001b[39m, in \u001b[36mGroupBy.__init__\u001b[39m\u001b[34m(self, obj, keys, level, grouper, exclusions, selection, as_index, sort, group_keys, observed, dropna)\u001b[39m\n\u001b[32m 1092\u001b[39m \u001b[38;5;28mself\u001b[39m.dropna = dropna\n\u001b[32m 1094\u001b[39m \u001b[38;5;28;01mif\u001b[39;00m grouper \u001b[38;5;129;01mis\u001b[39;00m \u001b[38;5;28;01mNone\u001b[39;00m:\n\u001b[32m-> \u001b[39m\u001b[32m1095\u001b[39m grouper, exclusions, obj = \u001b[43mget_grouper\u001b[49m\u001b[43m(\u001b[49m\n\u001b[32m 1096\u001b[39m \u001b[43m \u001b[49m\u001b[43mobj\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 1097\u001b[39m \u001b[43m \u001b[49m\u001b[43mkeys\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 1098\u001b[39m \u001b[43m \u001b[49m\u001b[43mlevel\u001b[49m\u001b[43m=\u001b[49m\u001b[43mlevel\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 1099\u001b[39m \u001b[43m \u001b[49m\u001b[43msort\u001b[49m\u001b[43m=\u001b[49m\u001b[43msort\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 1100\u001b[39m \u001b[43m \u001b[49m\u001b[43mobserved\u001b[49m\u001b[43m=\u001b[49m\u001b[43mobserved\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 1101\u001b[39m \u001b[43m \u001b[49m\u001b[43mdropna\u001b[49m\u001b[43m=\u001b[49m\u001b[38;5;28;43mself\u001b[39;49m\u001b[43m.\u001b[49m\u001b[43mdropna\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 1102\u001b[39m \u001b[43m \u001b[49m\u001b[43m)\u001b[49m\n\u001b[32m 1104\u001b[39m \u001b[38;5;28mself\u001b[39m.observed = observed\n\u001b[32m 1105\u001b[39m \u001b[38;5;28mself\u001b[39m.obj = obj\n", + "\u001b[36mFile \u001b[39m\u001b[32m~/fn_registry/projects/aurgi/analysis/venta_web/.venv/lib/python3.13/site-packages/pandas/core/groupby/grouper.py:901\u001b[39m, in \u001b[36mget_grouper\u001b[39m\u001b[34m(obj, key, level, sort, observed, validate, dropna)\u001b[39m\n\u001b[32m 899\u001b[39m in_axis, level, gpr = \u001b[38;5;28;01mFalse\u001b[39;00m, gpr, \u001b[38;5;28;01mNone\u001b[39;00m\n\u001b[32m 900\u001b[39m \u001b[38;5;28;01melse\u001b[39;00m:\n\u001b[32m--> \u001b[39m\u001b[32m901\u001b[39m \u001b[38;5;28;01mraise\u001b[39;00m \u001b[38;5;167;01mKeyError\u001b[39;00m(gpr)\n\u001b[32m 902\u001b[39m \u001b[38;5;28;01melif\u001b[39;00m \u001b[38;5;28misinstance\u001b[39m(gpr, Grouper) \u001b[38;5;129;01mand\u001b[39;00m gpr.key \u001b[38;5;129;01mis\u001b[39;00m \u001b[38;5;129;01mnot\u001b[39;00m \u001b[38;5;28;01mNone\u001b[39;00m:\n\u001b[32m 903\u001b[39m \u001b[38;5;66;03m# Add key to exclusions\u001b[39;00m\n\u001b[32m 904\u001b[39m exclusions.add(gpr.key)\n", + "\u001b[31mKeyError\u001b[39m: 'table'" + ] + } + ], + "source": [ + "TABLE_RE = re.compile(r'\\b(?:FROM|JOIN)\\s+([`\"\\[]?[\\w\\.`\"\\]]+)', re.IGNORECASE)\n", + "\n", + "def extract_tables(sql: str) -> set:\n", + " if not sql:\n", + " return set()\n", + " # quitar comentarios de linea y multilinea\n", + " sql2 = re.sub(r'--[^\\n]*', ' ', sql)\n", + " sql2 = re.sub(r'/\\*.*?\\*/', ' ', sql2, flags=re.S)\n", + " return {m.strip('`\"[]') for m in TABLE_RE.findall(sql2)}\n", + "\n", + "tbl_rows = []\n", + "for dc in dash.get('dashcards') or []:\n", + " q = card_query(dc)\n", + " if not q:\n", + " continue\n", + " card = dc['card']\n", + " for t in extract_tables(q):\n", + " tbl_rows.append({'card_id': card['id'], 'card_name': card['name'], 'db': card['dataset_query'].get('database'), 'table': t})\n", + "\n", + "df_tbls = pd.DataFrame(tbl_rows).drop_duplicates()\n", + "df_tbls.groupby('table').agg(cards=('card_id', 'nunique'), sample_card=('card_name', 'first')).sort_values('cards', ascending=False)" + ] + }, + { + "cell_type": "markdown", + "id": "9750c24f", + "metadata": {}, + "source": [ + "## 4. Documents 2, 3, 4, 8\n", + "\n", + "Los Metabase documents son notas tipo Notion (arbol ProseMirror). Pueden incluir `cardEmbed` que referencia cards existentes. Extraemos el texto plano y las cards embebidas." + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "id": "7b3d0052", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
doc_idnamecollection_idarchivedtext_charsembedded_card_ids
02SO↔NAV — Resumen ejecutivo600False833[7749, 7750, 7751]
13SO↔NAV — Análisis de categorías y márgenes600False1456[7762, 7763, 7764, 7765, 7766]
24SO↔NAV — Diagnóstico de trazabilidad600False1453[7755, 7756, 7757]
38WSWEB (Cubo) vs GA4/Supply Orders — ¿son lo mismo? (2025)600False3025[7845, 7846, 7847, 7848]
\n", + "
" + ], + "text/plain": [ + " doc_id name \\\n", + "0 2 SO↔NAV — Resumen ejecutivo \n", + "1 3 SO↔NAV — Análisis de categorías y márgenes \n", + "2 4 SO↔NAV — Diagnóstico de trazabilidad \n", + "3 8 WSWEB (Cubo) vs GA4/Supply Orders — ¿son lo mismo? (2025) \n", + "\n", + " collection_id archived text_chars embedded_card_ids \n", + "0 600 False 833 [7749, 7750, 7751] \n", + "1 600 False 1456 [7762, 7763, 7764, 7765, 7766] \n", + "2 600 False 1453 [7755, 7756, 7757] \n", + "3 600 False 3025 [7845, 7846, 7847, 7848] " + ] + }, + "execution_count": 7, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "DOC_IDS = [2, 3, 4, 8]\n", + "\n", + "def walk_prosemirror(node, out_text, out_embeds):\n", + " \"\"\"Recorre recursivamente el arbol ProseMirror.\n", + " Acumula texto plano y nodos cardEmbed con su card_id.\n", + " \"\"\"\n", + " if not isinstance(node, dict):\n", + " return\n", + " t = node.get('type')\n", + " if t == 'text':\n", + " out_text.append(node.get('text', ''))\n", + " elif t == 'cardEmbed':\n", + " attrs = node.get('attrs') or {}\n", + " out_embeds.append(attrs.get('id'))\n", + " # Tambien `smartLink` apunta a entidades Metabase\n", + " elif t == 'smartLink':\n", + " attrs = node.get('attrs') or {}\n", + " if attrs.get('model') in ('card', 'dataset'):\n", + " out_embeds.append(attrs.get('entityId') or attrs.get('id'))\n", + " for child in node.get('content') or []:\n", + " walk_prosemirror(child, out_text, out_embeds)\n", + "\n", + "documents = {}\n", + "for did in DOC_IDS:\n", + " try:\n", + " documents[did] = metabase_get_document(client, did)\n", + " except Exception as e:\n", + " print(f'doc {did}: ERROR {e}')\n", + "\n", + "doc_rows = []\n", + "for did, d in documents.items():\n", + " text, embeds = [], []\n", + " walk_prosemirror(d.get('document') or {}, text, embeds)\n", + " doc_rows.append({\n", + " 'doc_id': did,\n", + " 'name': d.get('name'),\n", + " 'collection_id': d.get('collection_id'),\n", + " 'archived': d.get('archived'),\n", + " 'text_chars': sum(len(t) for t in text),\n", + " 'embedded_card_ids': sorted({e for e in embeds if e}),\n", + " })\n", + "df_docs = pd.DataFrame(doc_rows)\n", + "df_docs" + ] + }, + { + "cell_type": "markdown", + "id": "1e8e42ab", + "metadata": {}, + "source": [ + "### 4.1 Preview del texto de cada document" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "id": "0db96337", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "================================================================================\n", + "doc 2 — SO↔NAV — Resumen ejecutivo\n", + "--------------------------------------------------------------------------------\n", + "Supply Orders ↔ Facturas Navision Análisis del cruce entre supply_orders (pedidos de suministro) y facturas de Navision . Periodo: enero 2025 en adelante. Datos actualizados automáticamente desde BigQuery. Cifras clave 558.571 supply orders totales 234.625 web (42%) + 300.643 centro (54%) + 23K sin origen 360.928 facturas NAV vinculadas (64.6% trazabilidad global) Revenue web: 27.4M€ | Margen web: 11.3M€ (41.3%) Evolución mensual Tendencia de volumen y trazabilidad Web vs Centro: Desglose por canal aurgi.com domina en revenue (17.8M€, 46.3% margen). Amazon segundo con 3.6M€ pero margen más bajo (34.3%). motortown.es tiene el mejor margen (52.3%) pero volumen pequeño. Revenue semanal por canal Evolución temporal para detectar tendencias y estacionalidad: Documento generado el 2026-04-14. Colección: Claude / Supply Orders ↔ Facturas NAV.\n", + "\n", + "================================================================================\n", + "doc 3 — SO↔NAV — Análisis de categorías y márgenes\n", + "--------------------------------------------------------------------------------\n", + "Categorías ecommerce y márgenes Análisis de supply orders web por familia ecommerce, subfamilia y canal. Solo web porque los supply orders de centro no tienen precios (sale_price/purchase_price son NULL). Revenue por familia ecommerce El 53% del revenue web (14.4M€) corresponde a productos sin categoría ecommerce — probablemente neumáticos y productos legacy sin clasificar. mundo-coche aporta 6M€ con 38.2% de margen. Volumen por familia ecommerce Número de supply orders y facturas NAV por familia. (sin cat) y mundo-coche lideran también en volumen: % Margen por familia ecommerce Ranking de familias por porcentaje de margen. Solo familias con más de 1.000€ de revenue. mundo-aurgi tiene margen de solo 2.9% (efecto rappel — el margen real incluye rappel de proveedores que no aparece en sale/purchase price). Drill-down: subfamilias Desglose dentro de cada familia para identificar qué productos específicos generan más valor: Matriz canal x familia Cruce de canal de venta con familia ecommerce. Permite identificar qué categorías rinden mejor en cada marketplace: Hallazgos clave (sin cat) domina en revenue pero es un hueco de datos — clasificar esos productos mejoraría la visibilid\n", + "... (283 chars mas)\n", + "\n", + "================================================================================\n", + "doc 4 — SO↔NAV — Diagnóstico de trazabilidad\n", + "--------------------------------------------------------------------------------\n", + "Diagnóstico: supply orders sin factura NAV De los 558K supply orders, ~140K (25%) no tienen factura Navision vinculada. Este documento analiza por qué y qué se puede hacer. Distribución por status 76.793 pending — pedidos aún en proceso, no esperan factura todavía 31.806 confirmed — deberían tener factura, posible gap 29.652 partial — parcialmente servidos, factura puede llegar 1.803 cancelled — cancelados, nunca tendrán factura 45 returned — devueltos Los pending son el grueso (55%): son pedidos en curso que aún no se han facturado. Es esperable. Los confirmed sin factura (31.8K) son el gap real a investigar. Supply orders sin factura por canal y status Tipo de envío y cobertura order_id El order_id se recupera con 3 fuentes en cascada: so.tpv_orders_order_id — directo (centro) precaweb.order_id — via tpv_precawebs_servicerequestjob (web cita/C&C) tpv_orders_invoice.order_id — via factura: logistic.invoice_number → inv.nav_id (web envío) Cobertura combinada: 99.8% . Solo el 0.2% no tiene order_id por ninguna vía. Métodos de pago La distribución de métodos de pago NAV confirma los canales de entrada: Acciones recomendadas Investigar los 31.8K confirmed sin factura — \n", + "... (291 chars mas)\n", + "\n", + "================================================================================\n", + "doc 8 — WSWEB (Cubo) vs GA4/Supply Orders — ¿son lo mismo? (2025)\n", + "--------------------------------------------------------------------------------\n", + "WSWEB en Cubo_Ventas vs GA4/Supply Orders: comparativa Cuando el dashboard 734 (BI Ventas Portfolio) filtra por compañía WSWEB , ¿está mostrando lo mismo que vemos en GA4 y en supply_orders? La respuesta corta: no exactamente . Aquí se explica por qué y cómo se mapean. Las 3 fuentes de datos de ventas web 1. Cubo_Ventas_Calculado — tabla: anjana_bi_datamart.Cubo_Ventas_Calculado Filtro digital: Dim_NombreDimGlobal2 = 'WSWEB' Revenue 2025: 5.879.313€ en 158.617 líneas 2. NAV directo — tablas: anjana_sales_invoice_header + anjana_sales_invoice_line Filtro: location_code IN ('18','19','405','421','422') (centros web) Revenue 2025: 15.878.883€ en 315.173 líneas 3. Supply Orders → NAV — tablas: supply_orders → logistic_orders → NAV Filtro: service_request_id IS NOT NULL Revenue 2025: 7.235.399€ en ~160K líneas ¿Por qué son diferentes? Cubo (5.88M€) es el MÁS restrictivo. El Cubo_Ventas_Calculado es un datamart preprocesado que aplica filtros de negocio: solo movimientos tipo 'Venta', excluye devoluciones, ajustes y ciertos tipos de ticket. Además, su campo Dim_NombreDimGlobal2 agrupa por 'compañía comercial' (quién gestiona la venta), no por c\n", + "... (1910 chars mas)\n", + "\n" + ] + } + ], + "source": [ + "for did, d in documents.items():\n", + " text, _ = [], []\n", + " walk_prosemirror(d.get('document') or {}, text, _)\n", + " plain = ' '.join(text).strip()\n", + " print('='*80)\n", + " print(f\"doc {did} — {d.get('name')}\")\n", + " print('-'*80)\n", + " print(plain[:1200] or '(sin texto plano, solo embeds)')\n", + " if len(plain) > 1200:\n", + " print(f'... ({len(plain)-1200} chars mas)')\n", + " print()" + ] + }, + { + "cell_type": "markdown", + "id": "ff843977", + "metadata": {}, + "source": [ + "### 4.2 Queries de las cards embebidas en los documents" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "id": "a24ef2bc", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
card_refdocsnamedisplaytypedatabase_idarchivedcollection_id
07749[2]SO↔NAV — Evolución mensual por origenlineNone6False600
17750[2]SO↔NAV — Desglose por canaltableNone6False600
27751[2]SO↔NAV — Revenue semanal web por canallineNone6False600
37764[3]SO↔NAV — Revenue por familia ecommercebarNone6False600
47765[3]SO↔NAV — Volumen por familia ecommercebarNone6False600
57766[3]SO↔NAV — % Margen por familia ecommercebarNone6False600
67762[3]SO↔NAV — Subfamilias ecommerce (web)tableNone6False600
77763[3]SO↔NAV — Margen canal x familia (web)tableNone6False600
87757[4]SO↔NAV — Sin factura NAV (diagnóstico)tableNone6False600
97756[4]SO↔NAV — Tipo de envíotableNone6False600
107755[4]SO↔NAV — Métodos de pago NAVbarNone6False600
117845[8]WSWEB vs GA4→NAV — Totales 2025tableNone6False600
127847[8]WSWEB — Centros web en Cubo vs psql_dcpublic 2025tableNone6False600
137846[8]WSWEB — Categorías en Cubo_Ventas 2025tableNone6False600
147848[8]WSWEB vs SO→NAV — Evolución mensual 2025lineNone6False600
\n", + "
" + ], + "text/plain": [ + " card_ref docs name display \\\n", + "0 7749 [2] SO↔NAV — Evolución mensual por origen line \n", + "1 7750 [2] SO↔NAV — Desglose por canal table \n", + "2 7751 [2] SO↔NAV — Revenue semanal web por canal line \n", + "3 7764 [3] SO↔NAV — Revenue por familia ecommerce bar \n", + "4 7765 [3] SO↔NAV — Volumen por familia ecommerce bar \n", + "5 7766 [3] SO↔NAV — % Margen por familia ecommerce bar \n", + "6 7762 [3] SO↔NAV — Subfamilias ecommerce (web) table \n", + "7 7763 [3] SO↔NAV — Margen canal x familia (web) table \n", + "8 7757 [4] SO↔NAV — Sin factura NAV (diagnóstico) table \n", + "9 7756 [4] SO↔NAV — Tipo de envío table \n", + "10 7755 [4] SO↔NAV — Métodos de pago NAV bar \n", + "11 7845 [8] WSWEB vs GA4→NAV — Totales 2025 table \n", + "12 7847 [8] WSWEB — Centros web en Cubo vs psql_dcpublic 2025 table \n", + "13 7846 [8] WSWEB — Categorías en Cubo_Ventas 2025 table \n", + "14 7848 [8] WSWEB vs SO→NAV — Evolución mensual 2025 line \n", + "\n", + " type database_id archived collection_id \n", + "0 None 6 False 600 \n", + "1 None 6 False 600 \n", + "2 None 6 False 600 \n", + "3 None 6 False 600 \n", + "4 None 6 False 600 \n", + "5 None 6 False 600 \n", + "6 None 6 False 600 \n", + "7 None 6 False 600 \n", + "8 None 6 False 600 \n", + "9 None 6 False 600 \n", + "10 None 6 False 600 \n", + "11 None 6 False 600 \n", + "12 None 6 False 600 \n", + "13 None 6 False 600 \n", + "14 None 6 False 600 " + ] + }, + "execution_count": 9, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# Recolectar todos los card_id embebidos\n", + "embed_map = {} # card_id -> [doc_id,...]\n", + "for did, d in documents.items():\n", + " text, embeds = [], []\n", + " walk_prosemirror(d.get('document') or {}, text, embeds)\n", + " for cid in embeds:\n", + " if cid is None:\n", + " continue\n", + " embed_map.setdefault(cid, []).append(did)\n", + "\n", + "# Normalizar a int cuando sea posible (cardEmbed usa int, smartLink a veces UUID)\n", + "cards_info = []\n", + "for cid, docs_using in embed_map.items():\n", + " if not isinstance(cid, int):\n", + " cards_info.append({'card_ref': cid, 'docs': docs_using, 'status': 'no-int-ref (posible smartLink UUID)'})\n", + " continue\n", + " try:\n", + " c = metabase_get_card(client, cid)\n", + " dq = c.get('dataset_query') or {}\n", + " cards_info.append({\n", + " 'card_ref': cid,\n", + " 'docs': docs_using,\n", + " 'name': c.get('name'),\n", + " 'display': c.get('display'),\n", + " 'type': dq.get('type'),\n", + " 'database_id': dq.get('database'),\n", + " 'archived': c.get('archived'),\n", + " 'collection_id': c.get('collection_id'),\n", + " })\n", + " except Exception as e:\n", + " cards_info.append({'card_ref': cid, 'docs': docs_using, 'status': f'error {e}'})\n", + "\n", + "df_doc_cards = pd.DataFrame(cards_info)\n", + "df_doc_cards" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "id": "e58916e5", + "metadata": {}, + "outputs": [], + "source": [ + "# Dump de queries de las cards embebidas (nativas primero)\n", + "for cid, docs_using in embed_map.items():\n", + " if not isinstance(cid, int):\n", + " continue\n", + " try:\n", + " c = metabase_get_card(client, cid)\n", + " except Exception:\n", + " continue\n", + " dq = c.get('dataset_query') or {}\n", + " if dq.get('type') != 'native':\n", + " continue\n", + " q = (dq.get('native') or {}).get('query', '')\n", + " print('='*80)\n", + " print(f\"card {cid} — {c['name']} [db={dq.get('database')}] (en docs {docs_using})\")\n", + " print('-'*80)\n", + " print(q.strip()[:2500])\n", + " if len(q) > 2500:\n", + " print(f'... ({len(q)-2500} chars mas)')\n", + " print()" + ] + }, + { + "cell_type": "markdown", + "id": "7a1fe9a3", + "metadata": {}, + "source": [ + "## 5. Comparacion Dashboard 734 vs Documents\n", + "\n", + "Overlap de cards y tablas entre ambas vistas." + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "id": "b4fe1167", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Cards unicas en dashboard 734: 85\n", + "Cards unicas en documents [2, 3, 4, 8]: 15\n", + "Overlap (mismas cards en ambos): 0 -> []\n", + "Solo en dashboard: 85\n", + "Solo en documents: 15 -> [7749, 7750, 7751, 7755, 7756, 7757, 7762, 7763, 7764, 7765, 7766, 7845, 7846, 7847, 7848]\n" + ] + } + ], + "source": [ + "dash_card_ids = set(df_cards['card_id'].dropna().astype(int).tolist())\n", + "doc_card_ids = {c for c in embed_map if isinstance(c, int)}\n", + "\n", + "overlap = dash_card_ids & doc_card_ids\n", + "only_dash = dash_card_ids - doc_card_ids\n", + "only_docs = doc_card_ids - dash_card_ids\n", + "\n", + "print(f\"Cards unicas en dashboard 734: {len(dash_card_ids)}\")\n", + "print(f\"Cards unicas en documents {DOC_IDS}: {len(doc_card_ids)}\")\n", + "print(f\"Overlap (mismas cards en ambos): {len(overlap)} -> {sorted(overlap)}\")\n", + "print(f\"Solo en dashboard: {len(only_dash)}\")\n", + "print(f\"Solo en documents: {len(only_docs)} -> {sorted(only_docs)}\")" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "c62d5192", + "metadata": {}, + "outputs": [], + "source": [ + "# Comparar tablas tocadas por ambas vistas\n", + "def tables_from_card(cid):\n", + " try:\n", + " c = metabase_get_card(client, cid)\n", + " except Exception:\n", + " return set()\n", + " dq = c.get('dataset_query') or {}\n", + " if dq.get('type') != 'native':\n", + " return set()\n", + " return extract_tables((dq.get('native') or {}).get('query', ''))\n", + "\n", + "dash_tables = set(df_tbls['table'])\n", + "doc_tables = set()\n", + "for cid in doc_card_ids:\n", + " doc_tables |= tables_from_card(cid)\n", + "\n", + "print('--- Tablas en dashboard 734 ---')\n", + "for t in sorted(dash_tables):\n", + " print(' ', t)\n", + "print('--- Tablas en documents ---')\n", + "for t in sorted(doc_tables):\n", + " print(' ', t)\n", + "print('--- Overlap ---')\n", + "for t in sorted(dash_tables & doc_tables):\n", + " print(' ', t)" + ] + }, + { + "cell_type": "markdown", + "id": "f8d70438", + "metadata": {}, + "source": [ + "## 6. Siguientes pasos\n", + "\n", + "1. Inspeccionar las queries SQL impresas en secciones 3.1 y 4.2 para entender joins y filtros.\n", + "2. Para cards MBQL (no nativas) en el dashboard, decodificar `dataset_query.query` para sacar `source-table` y `breakouts`.\n", + "3. Si hay tablas comunes, correr una query de control contra la DB para validar que ambos lados reportan cifras coherentes.\n", + "4. Identificar el concepto de **\"centros digital / venta web\"** buscando en `df_cards['name']` y en las clausulas WHERE de las queries." + ] + }, + { + "cell_type": "markdown", + "id": "d70deb35", + "metadata": {}, + "source": [ + "## 7. Resolver source-table de las cards MBQL\n", + "\n", + "Dashboard 734 y cards de documents son todas MBQL sobre DCBigQuery (db=6). Resolvemos los 'source-table' siguiendo 'source-query' o 'source-card' hasta encontrar tabla real, y luego mapeamos table_id -> (schema.name)." + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "id": "aaa4dcb2", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "DB 6 (DCBigQuery) tablas indexadas: 2830\n", + "table 184 -> None\n" + ] + } + ], + "source": [ + "# Cache metadata de DCBigQuery (db 6) para mapear table_id -> schema.name\n", + "db6 = client.request(\"GET\", \"/api/database/6?include=tables\")\n", + "table_by_id = {t[\"id\"]: f'{t.get(\"schema\",\"\")}.{t[\"name\"]}'.lstrip(\".\") for t in (db6.get(\"tables\") or [])}\n", + "print(f'DB 6 ({db6[\"name\"]}) tablas indexadas: {len(table_by_id)}')\n", + "print(f'table 184 -> {table_by_id.get(184)}')" + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "id": "3266674a", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "table 184 -> db_id=2 schema=public name=supply_orders\n", + "display_name: Supply Orders\n" + ] + } + ], + "source": [ + "# La tabla 184 no esta en db 6. Probar endpoint /api/table/184 directamente\n", + "t184 = client.request(\"GET\", \"/api/table/184\")\n", + "print(f'table 184 -> db_id={t184[\"db_id\"]} schema={t184.get(\"schema\")} name={t184[\"name\"]}')\n", + "print(f'display_name: {t184.get(\"display_name\")}')" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "4daaa759", + "metadata": {}, + "outputs": [], + "source": [ + "# Resolver cadena MBQL -> tabla fisica para cada card relevante.\n", + "# Estrategia: recorrer source-query/source-card hasta hallar source-table,\n", + "# luego /api/table/:id para obtener (db_id, schema, name).\n", + "\n", + "_table_cache = {}\n", + "_card_cache = {}\n", + "\n", + "def get_table(tid):\n", + " if tid not in _table_cache:\n", + " _table_cache[tid] = client.request(\"GET\", f\"/api/table/{tid}\")\n", + " return _table_cache[tid]\n", + "\n", + "def get_card(cid):\n", + " if cid not in _card_cache:\n", + " _card_cache[cid] = client.request(\"GET\", f\"/api/card/{cid}\")\n", + " return _card_cache[cid]\n", + "\n", + "def db_name(db_id):\n", + " for d in dbs:\n", + " if d[\"id\"] == db_id:\n", + " return d[\"name\"]\n", + " return f\"db:{db_id}\"\n", + "\n", + "def resolve_source(dataset_query, _depth=0):\n", + " \"\"\"Retorna (db_name, schema, table_name) siguiendo la cadena.\"\"\"\n", + " if _depth > 10: return (\"?\",\"?\",\"?\")\n", + " q = dataset_query.get(\"query\") or {}\n", + " # buscar hoja: source-table numerico\n", + " cur = q\n", + " while isinstance(cur, dict):\n", + " if \"source-table\" in cur and isinstance(cur[\"source-table\"], int):\n", + " t = get_table(cur[\"source-table\"])\n", + " return (db_name(t[\"db_id\"]), t.get(\"schema\",\"\"), t[\"name\"])\n", + " if \"source-table\" in cur and isinstance(cur[\"source-table\"], str) and cur[\"source-table\"].startswith(\"card__\"):\n", + " cid = int(cur[\"source-table\"].split(\"__\")[1])\n", + " return resolve_source(get_card(cid).get(\"dataset_query\") or {}, _depth+1)\n", + " if \"source-card-id\" in cur:\n", + " return resolve_source(get_card(cur[\"source-card-id\"]).get(\"dataset_query\") or {}, _depth+1)\n", + " cur = cur.get(\"source-query\") or {}\n", + " return (\"?\",\"?\",\"?\")\n", + "\n", + "# Candidatas unicas del dashboard\n", + "dash_cards = [dc.get(\"card\") for dc in dash.get(\"dashcards\") or [] if dc.get(\"card\") and dc[\"card\"].get(\"id\")]\n", + "dash_unique = {c[\"id\"]: c for c in dash_cards}.values()\n", + "\n", + "rows = []\n", + "for c in dash_unique:\n", + " dbn, sch, tn = resolve_source(c.get(\"dataset_query\") or {})\n", + " rows.append({\"card_id\": c[\"id\"], \"name\": c[\"name\"], \"source_db\": dbn, \"source_table\": f\"{sch}.{tn}\".lstrip(\".\")})\n", + "df_dash_sources = pd.DataFrame(rows)\n", + "print(f\"Total cards dashboard: {len(df_dash_sources)}\")\n", + "print()\n", + "print(\"=== TABLAS FISICAS DEL DASHBOARD 734 ===\")\n", + "print(df_dash_sources.groupby([\"source_db\",\"source_table\"]).size().sort_values(ascending=False).to_string())" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "e23ded90", + "metadata": {}, + "outputs": [], + "source": [ + "# Version rapida: resolver solo las FUENTES TOP del dashboard, no las 85 cards una a una\n", + "# Las 6 referencias top cubren ~70% del dashboard\n", + "TOP_REFS = [(\"table\", 184), (\"card\", 4324), (\"card\", 4421), (\"card\", 5305), (\"card\", 4290), (\"card\", 7518)]\n", + "\n", + "def db_name(db_id):\n", + " for d in dbs:\n", + " if d[\"id\"] == db_id:\n", + " return d[\"name\"]\n", + " return f\"db:{db_id}\"\n", + "\n", + "def walk_to_table(card_id, _depth=0, _seen=None):\n", + " if _seen is None: _seen = set()\n", + " if card_id in _seen or _depth > 8: return None\n", + " _seen.add(card_id)\n", + " c = client.request(\"GET\", f\"/api/card/{card_id}\")\n", + " dq = c.get(\"dataset_query\") or {}\n", + " q = dq.get(\"query\") or {}\n", + " cur = q\n", + " while isinstance(cur, dict):\n", + " st = cur.get(\"source-table\")\n", + " if isinstance(st, int):\n", + " t = client.request(\"GET\", f\"/api/table/{st}\")\n", + " return {\"card_chain\": [card_id], \"db\": db_name(t[\"db_id\"]), \"table\": f'{t.get(\"schema\",\"\")}.{t[\"name\"]}'.lstrip(\".\")}\n", + " if isinstance(st, str) and st.startswith(\"card__\"):\n", + " sub = walk_to_table(int(st.split(\"__\")[1]), _depth+1, _seen)\n", + " if sub: sub[\"card_chain\"] = [card_id] + sub[\"card_chain\"]\n", + " return sub\n", + " if \"source-card-id\" in cur:\n", + " sub = walk_to_table(cur[\"source-card-id\"], _depth+1, _seen)\n", + " if sub: sub[\"card_chain\"] = [card_id] + sub[\"card_chain\"]\n", + " return sub\n", + " cur = cur.get(\"source-query\")\n", + " return None\n", + "\n", + "results = []\n", + "for kind, ref in TOP_REFS:\n", + " if kind == \"table\":\n", + " t = client.request(\"GET\", f\"/api/table/{ref}\")\n", + " results.append({\"ref\": f\"table:{ref}\", \"db\": db_name(t[\"db_id\"]), \"table\": f'{t.get(\"schema\",\"\")}.{t[\"name\"]}'.lstrip(\".\"), \"chain\": []})\n", + " else:\n", + " info = walk_to_table(ref)\n", + " if info:\n", + " results.append({\"ref\": f\"card:{ref}\", \"db\": info[\"db\"], \"table\": info[\"table\"], \"chain\": info[\"card_chain\"]})\n", + " else:\n", + " results.append({\"ref\": f\"card:{ref}\", \"db\": \"?\", \"table\": \"?\", \"chain\": []})\n", + "\n", + "df_top = pd.DataFrame(results)\n", + "print(\"=== FUENTES TOP DEL DASHBOARD 734 ===\")\n", + "for _, r in df_top.iterrows():\n", + " chain_s = \" -> \".join(str(c) for c in r['chain']) if r['chain'] else \"-\"\n", + " print(f\" {r['ref']:12} db={r['db']:20} table={r['table']:50} chain: {chain_s}\")" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.13.5" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/notebooks/02_analisis_venta_web.ipynb b/notebooks/02_analisis_venta_web.ipynb new file mode 100644 index 0000000..a9a6450 --- /dev/null +++ b/notebooks/02_analisis_venta_web.ipynb @@ -0,0 +1,3284 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "1cc9e4a4", + "metadata": {}, + "source": [ + "# Análisis Venta Web — Aurgi\n", + "\n", + "Partiendo de los hallazgos del notebook 01, reproducimos y comparamos las 3 fuentes de venta web en 2025:\n", + "\n", + "| Fuente | Tabla(s) | Filtro | Revenue 2025 según doc 8 |\n", + "|---|---|---|---|\n", + "| **Cubo_Ventas_Calculado** | `anjana_bi_datamart.Cubo_Ventas_Calculado` | `Dim_NombreDimGlobal2 = 'WSWEB'` | 5.879.313 € |\n", + "| **NAV directo** | `anjana_sales_invoice_header` + `..._line` | `location_code IN ('18','19','405','421','422')` | 15.878.883 € |\n", + "| **Supply Orders → NAV** | `supply_orders` → `logistic_orders` → NAV | `service_request_id IS NOT NULL` | 7.235.399 € |\n", + "\n", + "Todas en **DCBigQuery (db=6)**.\n", + "\n", + "## Objetivos\n", + "\n", + "1. Reproducir los tres totales y confirmar las cifras del doc 8.\n", + "2. Desagregar cada fuente por mes, centro, canal y categoría.\n", + "3. Cuantificar la diferencia entre **Cubo** y **NAV directo** (la brecha de ~10M€).\n", + "4. Mapear qué parte del dashboard 734 se alimenta de cada fuente." + ] + }, + { + "cell_type": "markdown", + "id": "eff1289d", + "metadata": {}, + "source": [ + "## 1. Setup" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "id": "dac747f8", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Listo. BigQuery via Metabase.\n" + ] + } + ], + "source": [ + "import os, re\n", + "from pathlib import Path\n", + "import pandas as pd\n", + "\n", + "env_path = Path('.env') if Path('.env').exists() else Path('../.env')\n", + "for line in env_path.read_text().splitlines():\n", + " if line and not line.startswith('#') and '=' in line:\n", + " k, v = line.split('=', 1)\n", + " os.environ.setdefault(k.strip(), v.strip())\n", + "\n", + "from metabase import MetabaseClient, metabase_execute_query\n", + "\n", + "URL = os.environ['METABASE_URL']\n", + "KEY = os.environ['METABASE_API_KEY']\n", + "client = MetabaseClient(URL, KEY)\n", + "DB_BIGQUERY = 6\n", + "\n", + "def run_sql(sql: str, db_id: int = DB_BIGQUERY) -> pd.DataFrame:\n", + " \"\"\"Ejecuta SQL contra Metabase y retorna DataFrame.\"\"\"\n", + " res = metabase_execute_query(client, db_id, sql)\n", + " cols = [c['display_name'] or c['name'] for c in res['data']['cols']]\n", + " return pd.DataFrame(res['data']['rows'], columns=cols)\n", + "\n", + "pd.set_option('display.max_colwidth', 100)\n", + "pd.set_option('display.float_format', lambda x: f'{x:,.2f}')\n", + "print('Listo. BigQuery via Metabase.')" + ] + }, + { + "cell_type": "markdown", + "id": "9682af7a", + "metadata": {}, + "source": [ + "## 2. Descubrir el project/dataset de BigQuery\n", + "\n", + "Necesitamos el prefijo correcto para cualificar las tablas en SQL nativo contra BigQuery." + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "id": "740e351e", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Total tablas en DCBigQuery: 2830\n", + "--- schemas distintos ---\n", + "schema\n", + "analytics_353235710 1314\n", + "anjana_bi_amg 387\n", + "anjana_bi_datamart 213\n", + "google_ads_data 202\n", + "psql_dcpublic 142\n", + "anjana_bi_ntg 102\n", + "questions_metabase 67\n", + "arbentia_dev_dataset 64\n", + "anjana_bi_mmb 61\n", + "stg_anjana_bi 58\n", + "mssql2022_dbo 56\n", + "bi_anjana 52\n", + "citaprevia_aurphcp 25\n", + "almacen_movs 16\n", + "data_models 14\n", + "ralarsa 10\n", + "rag_datasets 9\n", + "test_sales 8\n", + "claude_bi 5\n", + "call_analytics 5\n", + "Name: count, dtype: int64\n", + "--- tablas clave referenciadas en doc 8 ---\n" + ] + }, + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
idschemaname
1543452mssql2022_dboanjana_sales_invoice_header
1553437mssql2022_dboanjana_sales_invoice_line
4242890anjana_bi_datamartCubo_Ventas_Calculado
13511534psql_dcpubliclogistic_orders
25311530psql_dcpublicsupply_orders
\n", + "
" + ], + "text/plain": [ + " id schema name\n", + "154 3452 mssql2022_dbo anjana_sales_invoice_header\n", + "155 3437 mssql2022_dbo anjana_sales_invoice_line\n", + "424 2890 anjana_bi_datamart Cubo_Ventas_Calculado\n", + "1351 1534 psql_dcpublic logistic_orders\n", + "2531 1530 psql_dcpublic supply_orders" + ] + }, + "execution_count": 2, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# Listar tablas de db=6 para confirmar naming\n", + "db6 = client.request('GET', '/api/database/6?include=tables')\n", + "tables = pd.DataFrame([\n", + " {'id': t['id'], 'schema': t.get('schema'), 'name': t['name']}\n", + " for t in db6.get('tables') or []\n", + "])\n", + "print(f\"Total tablas en DCBigQuery: {len(tables)}\")\n", + "print('--- schemas distintos ---')\n", + "print(tables['schema'].value_counts().head(20))\n", + "print('--- tablas clave referenciadas en doc 8 ---')\n", + "key_names = ['Cubo_Ventas_Calculado', 'anjana_sales_invoice_header', 'anjana_sales_invoice_line', 'supply_orders', 'logistic_orders']\n", + "tables[tables['name'].isin(key_names)]" + ] + }, + { + "cell_type": "markdown", + "id": "f0a1ba81", + "metadata": {}, + "source": [ + "## 3. Fuente 1 — Cubo_Ventas_Calculado (WSWEB)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "e595c0d4", + "metadata": {}, + "outputs": [], + "source": [ + "# Ajustar el nombre completo según lo descubierto en la celda anterior.\n", + "# En BigQuery Metabase suele cualificar como `project.dataset.tabla` automaticamente;\n", + "# si no lo hace, usar el schema como dataset.\n", + "CUBO = 'anjana_bi_datamart.Cubo_Ventas_Calculado'\n", + "\n", + "sql_cubo_total = f'''\n", + "SELECT\n", + " COUNT(*) AS lineas,\n", + " SUM(Importe_Neto) AS revenue_total\n", + "FROM {CUBO}\n", + "WHERE Dim_NombreDimGlobal2 = 'WSWEB'\n", + " AND EXTRACT(YEAR FROM Fecha_Registro) = 2025\n", + "'''\n", + "run_sql(sql_cubo_total)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "3d389e98", + "metadata": {}, + "outputs": [], + "source": [ + "# Evolucion mensual Cubo WSWEB 2025\n", + "sql_cubo_mes = f'''\n", + "SELECT\n", + " FORMAT_DATE('%Y-%m', Fecha_Registro) AS mes,\n", + " COUNT(*) AS lineas,\n", + " SUM(Importe_Neto) AS revenue\n", + "FROM {CUBO}\n", + "WHERE Dim_NombreDimGlobal2 = 'WSWEB'\n", + " AND EXTRACT(YEAR FROM Fecha_Registro) = 2025\n", + "GROUP BY mes\n", + "ORDER BY mes\n", + "'''\n", + "df_cubo_mes = run_sql(sql_cubo_mes)\n", + "df_cubo_mes" + ] + }, + { + "cell_type": "markdown", + "id": "ac71ce22", + "metadata": {}, + "source": [ + "## 4. Fuente 2 — NAV directo (centros web)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "4dbf152e", + "metadata": {}, + "outputs": [], + "source": [ + "NAV_HEADER = 'anjana_bi_datamart.anjana_sales_invoice_header'\n", + "NAV_LINE = 'anjana_bi_datamart.anjana_sales_invoice_line'\n", + "WEB_CENTERS = \"('18','19','405','421','422')\"\n", + "\n", + "sql_nav_total = f'''\n", + "SELECT\n", + " COUNT(*) AS lineas,\n", + " SUM(l.amount) AS revenue_total\n", + "FROM {NAV_LINE} l\n", + "JOIN {NAV_HEADER} h\n", + " ON l.document_no = h.no\n", + "WHERE h.location_code IN {WEB_CENTERS}\n", + " AND EXTRACT(YEAR FROM h.posting_date) = 2025\n", + "'''\n", + "run_sql(sql_nav_total)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "db4e883e", + "metadata": {}, + "outputs": [], + "source": [ + "# NAV por centro y mes\n", + "sql_nav_mes = f'''\n", + "SELECT\n", + " FORMAT_DATE('%Y-%m', h.posting_date) AS mes,\n", + " h.location_code,\n", + " COUNT(*) AS lineas,\n", + " SUM(l.amount) AS revenue\n", + "FROM {NAV_LINE} l\n", + "JOIN {NAV_HEADER} h\n", + " ON l.document_no = h.no\n", + "WHERE h.location_code IN {WEB_CENTERS}\n", + " AND EXTRACT(YEAR FROM h.posting_date) = 2025\n", + "GROUP BY mes, h.location_code\n", + "ORDER BY mes, h.location_code\n", + "'''\n", + "df_nav_mes = run_sql(sql_nav_mes)\n", + "df_nav_mes.head(20)" + ] + }, + { + "cell_type": "markdown", + "id": "9aa66747", + "metadata": {}, + "source": [ + "## 5. Fuente 3 — Supply Orders → NAV (web)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "9f78689a", + "metadata": {}, + "outputs": [], + "source": [ + "SO = 'anjana_bi_datamart.supply_orders'\n", + "LO = 'anjana_bi_datamart.logistic_orders'\n", + "\n", + "sql_so_total = f'''\n", + "SELECT\n", + " COUNT(*) AS supply_orders_web,\n", + " SUM(sale_price) AS revenue\n", + "FROM {SO}\n", + "WHERE service_request_id IS NOT NULL\n", + " AND EXTRACT(YEAR FROM created_at) = 2025\n", + "'''\n", + "run_sql(sql_so_total)" + ] + }, + { + "cell_type": "markdown", + "id": "830d4c2e", + "metadata": {}, + "source": [ + "## 6. Comparativa y brecha\n", + "\n", + "Consolidamos los tres totales y analizamos la diferencia." + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "id": "49ad9aad", + "metadata": {}, + "outputs": [ + { + "ename": "NameError", + "evalue": "name 'df_cubo_mes' is not defined", + "output_type": "error", + "traceback": [ + "\u001b[31m---------------------------------------------------------------------------\u001b[39m", + "\u001b[31mNameError\u001b[39m Traceback (most recent call last)", + "\u001b[36mCell\u001b[39m\u001b[36m \u001b[39m\u001b[32mIn[3]\u001b[39m\u001b[32m, line 2\u001b[39m\n\u001b[32m 1\u001b[39m \u001b[38;5;66;03m# Juntar los tres mensuales\u001b[39;00m\n\u001b[32m----> \u001b[39m\u001b[32m2\u001b[39m tot_cubo = df_cubo_mes.groupby(\u001b[33m'mes'\u001b[39m)[\u001b[33m'revenue'\u001b[39m].sum().rename(\u001b[33m'cubo'\u001b[39m)\n\u001b[32m 3\u001b[39m tot_nav = df_nav_mes.groupby(\u001b[33m'mes'\u001b[39m)[\u001b[33m'revenue'\u001b[39m].sum().rename(\u001b[33m'nav_directo'\u001b[39m)\n\u001b[32m 4\u001b[39m comparativa = pd.concat([tot_cubo, tot_nav], axis=\u001b[32m1\u001b[39m).reset_index()\n\u001b[32m 5\u001b[39m comparativa[\u001b[33m'brecha_nav_vs_cubo'\u001b[39m] = comparativa[\u001b[33m'nav_directo'\u001b[39m] - comparativa[\u001b[33m'cubo'\u001b[39m]\n", + "\u001b[31mNameError\u001b[39m: name 'df_cubo_mes' is not defined" + ] + } + ], + "source": [ + "# Juntar los tres mensuales\n", + "tot_cubo = df_cubo_mes.groupby('mes')['revenue'].sum().rename('cubo')\n", + "tot_nav = df_nav_mes.groupby('mes')['revenue'].sum().rename('nav_directo')\n", + "comparativa = pd.concat([tot_cubo, tot_nav], axis=1).reset_index()\n", + "comparativa['brecha_nav_vs_cubo'] = comparativa['nav_directo'] - comparativa['cubo']\n", + "comparativa['ratio_cubo_sobre_nav_pct'] = 100 * comparativa['cubo'] / comparativa['nav_directo']\n", + "comparativa" + ] + }, + { + "cell_type": "markdown", + "id": "d89d792d", + "metadata": {}, + "source": [ + "## 7. Qué filtra el Cubo respecto a NAV\n", + "\n", + "El Cubo aplica filtros de negocio extra: solo movimientos tipo 'Venta', excluye devoluciones, ajustes, ciertos tipos de ticket.\n", + "Exploramos el header NAV para ver qué categorías se pierden." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "6c026d51", + "metadata": {}, + "outputs": [], + "source": [ + "# Distribución por document_type en NAV centros web 2025\n", + "sql_doctype = f'''\n", + "SELECT\n", + " h.document_type,\n", + " COUNT(*) AS lineas,\n", + " SUM(l.amount) AS revenue\n", + "FROM {NAV_LINE} l\n", + "JOIN {NAV_HEADER} h\n", + " ON l.document_no = h.no\n", + "WHERE h.location_code IN {WEB_CENTERS}\n", + " AND EXTRACT(YEAR FROM h.posting_date) = 2025\n", + "GROUP BY h.document_type\n", + "ORDER BY revenue DESC\n", + "'''\n", + "run_sql(sql_doctype)" + ] + }, + { + "cell_type": "markdown", + "id": "273719d1", + "metadata": {}, + "source": [ + "## 8. Cruce dashboard 734 ← fuente\n", + "\n", + "Usando `df_dash_sources` del notebook 01 (celda 26), identificamos qué tabs del dashboard se alimentan del Cubo, de NAV directo o de supply_orders." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "e5613255", + "metadata": {}, + "outputs": [], + "source": [ + "# Si df_dash_sources vive en el mismo kernel (tras correr 01), lo reutilizamos.\n", + "# Si no, lo regeneramos aqui.\n", + "try:\n", + " df_dash_sources\n", + " print('Reutilizando df_dash_sources del notebook 01')\n", + "except NameError:\n", + " print('df_dash_sources no esta en el kernel. Ejecuta el notebook 01 o copia la celda 26 aqui.')\n", + "else:\n", + " print()\n", + " print('=== DISTRIBUCION DE LAS 85 CARDS DEL DASHBOARD ===')\n", + " print(df_dash_sources.groupby(['source_db','source_table']).size().sort_values(ascending=False).to_string())" + ] + }, + { + "cell_type": "markdown", + "id": "96450ff7", + "metadata": {}, + "source": [ + "## 9. Hallazgos y decisiones\n", + "\n", + "- (rellenar tras ejecutar)\n", + "- Cuál es la fuente canonica para \"venta web\" en reportes internos\n", + "- Cuándo usar cada una (p.ej. Cubo para analítica financiera, SO para operativa)\n", + "- Ajustes necesarios al dashboard 734 si mezcla fuentes" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "id": "6c5093a2", + "metadata": {}, + "outputs": [ + { + "ename": "HTTPStatusError", + "evalue": "Client error '400 Bad Request' for url 'https://reports.autingo.es/api/dataset'\nFor more information check: https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/400", + "output_type": "error", + "traceback": [ + "\u001b[31m---------------------------------------------------------------------------\u001b[39m", + "\u001b[31mHTTPStatusError\u001b[39m Traceback (most recent call last)", + "\u001b[36mCell\u001b[39m\u001b[36m \u001b[39m\u001b[32mIn[2]\u001b[39m\u001b[32m, line 17\u001b[39m\n\u001b[32m 13\u001b[39m FROM `{CUBO}`\n\u001b[32m 14\u001b[39m WHERE Dim_NombreDimGlobal2 = \u001b[33m'WSWEB'\u001b[39m\n\u001b[32m 15\u001b[39m AND EXTRACT(YEAR FROM Fecha_Registro) = \u001b[32m2025\u001b[39m\n\u001b[32m 16\u001b[39m '''\n\u001b[32m---> \u001b[39m\u001b[32m17\u001b[39m df_cubo_tot = run_sql(sql_cubo_total)\n\u001b[32m 18\u001b[39m print(\u001b[33m'=== FUENTE 1: Cubo_Ventas_Calculado (WSWEB) 2025 ==='\u001b[39m)\n\u001b[32m 19\u001b[39m print(df_cubo_tot.to_string(index=\u001b[38;5;28;01mFalse\u001b[39;00m))\n", + "\u001b[36mCell\u001b[39m\u001b[36m \u001b[39m\u001b[32mIn[1]\u001b[39m\u001b[32m, line 20\u001b[39m, in \u001b[36mrun_sql\u001b[39m\u001b[34m(sql, db_id)\u001b[39m\n\u001b[32m 18\u001b[39m \u001b[38;5;28;01mdef\u001b[39;00m run_sql(sql: str, db_id: int = DB_BIGQUERY) -> pd.DataFrame:\n\u001b[32m 19\u001b[39m \u001b[33m\"\"\"Ejecuta SQL contra Metabase y retorna DataFrame.\"\"\"\u001b[39m\n\u001b[32m---> \u001b[39m\u001b[32m20\u001b[39m res = metabase_execute_query(client, db_id, sql)\n\u001b[32m 21\u001b[39m cols = [c[\u001b[33m'display_name'\u001b[39m] \u001b[38;5;28;01mor\u001b[39;00m c[\u001b[33m'name'\u001b[39m] \u001b[38;5;28;01mfor\u001b[39;00m c \u001b[38;5;28;01min\u001b[39;00m res[\u001b[33m'data'\u001b[39m][\u001b[33m'cols'\u001b[39m]]\n\u001b[32m 22\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m pd.DataFrame(res[\u001b[33m'data'\u001b[39m][\u001b[33m'rows'\u001b[39m], columns=cols)\n", + "\u001b[36mFile \u001b[39m\u001b[32m~/fn_registry/python/functions/metabase/cards.py:227\u001b[39m, in \u001b[36mmetabase_execute_query\u001b[39m\u001b[34m(client, database_id, sql, max_results)\u001b[39m\n\u001b[32m 222\u001b[39m \u001b[38;5;28;01mif\u001b[39;00m max_results > \u001b[32m0\u001b[39m:\n\u001b[32m 223\u001b[39m body[\u001b[33m\"\u001b[39m\u001b[33mconstraints\u001b[39m\u001b[33m\"\u001b[39m] = {\n\u001b[32m 224\u001b[39m \u001b[33m\"\u001b[39m\u001b[33mmax-results\u001b[39m\u001b[33m\"\u001b[39m: max_results,\n\u001b[32m 225\u001b[39m \u001b[33m\"\u001b[39m\u001b[33mmax-results-bare-rows\u001b[39m\u001b[33m\"\u001b[39m: max_results,\n\u001b[32m 226\u001b[39m }\n\u001b[32m--> \u001b[39m\u001b[32m227\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[43mclient\u001b[49m\u001b[43m.\u001b[49m\u001b[43mrequest\u001b[49m\u001b[43m(\u001b[49m\u001b[33;43m\"\u001b[39;49m\u001b[33;43mPOST\u001b[39;49m\u001b[33;43m\"\u001b[39;49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[33;43m\"\u001b[39;49m\u001b[33;43m/api/dataset\u001b[39;49m\u001b[33;43m\"\u001b[39;49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mjson\u001b[49m\u001b[43m=\u001b[49m\u001b[43mbody\u001b[49m\u001b[43m)\u001b[49m\n", + "\u001b[36mFile \u001b[39m\u001b[32m~/fn_registry/python/functions/metabase/client.py:45\u001b[39m, in \u001b[36mMetabaseClient.request\u001b[39m\u001b[34m(self, method, path, **kwargs)\u001b[39m\n\u001b[32m 31\u001b[39m \u001b[38;5;250m\u001b[39m\u001b[33;03m\"\"\"Ejecuta una peticion HTTP contra la API de Metabase.\u001b[39;00m\n\u001b[32m 32\u001b[39m \n\u001b[32m 33\u001b[39m \u001b[33;03mArgs:\u001b[39;00m\n\u001b[32m (...)\u001b[39m\u001b[32m 42\u001b[39m \u001b[33;03m httpx.HTTPStatusError: Si el status code no es 2xx.\u001b[39;00m\n\u001b[32m 43\u001b[39m \u001b[33;03m\"\"\"\u001b[39;00m\n\u001b[32m 44\u001b[39m resp = \u001b[38;5;28mself\u001b[39m._http.request(method, path, **kwargs)\n\u001b[32m---> \u001b[39m\u001b[32m45\u001b[39m \u001b[43mresp\u001b[49m\u001b[43m.\u001b[49m\u001b[43mraise_for_status\u001b[49m\u001b[43m(\u001b[49m\u001b[43m)\u001b[49m\n\u001b[32m 46\u001b[39m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;129;01mnot\u001b[39;00m resp.content:\n\u001b[32m 47\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28;01mNone\u001b[39;00m\n", + "\u001b[36mFile \u001b[39m\u001b[32m~/fn_registry/projects/aurgi/analysis/venta_web/.venv/lib/python3.13/site-packages/httpx/_models.py:829\u001b[39m, in \u001b[36mResponse.raise_for_status\u001b[39m\u001b[34m(self)\u001b[39m\n\u001b[32m 827\u001b[39m error_type = error_types.get(status_class, \u001b[33m\"\u001b[39m\u001b[33mInvalid status code\u001b[39m\u001b[33m\"\u001b[39m)\n\u001b[32m 828\u001b[39m message = message.format(\u001b[38;5;28mself\u001b[39m, error_type=error_type)\n\u001b[32m--> \u001b[39m\u001b[32m829\u001b[39m \u001b[38;5;28;01mraise\u001b[39;00m HTTPStatusError(message, request=request, response=\u001b[38;5;28mself\u001b[39m)\n", + "\u001b[31mHTTPStatusError\u001b[39m: Client error '400 Bad Request' for url 'https://reports.autingo.es/api/dataset'\nFor more information check: https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/400" + ] + } + ], + "source": [ + "# --- Paths cualificados reales (corregidos tras celda 4) ---\n", + "CUBO = 'anjana_bi_datamart.Cubo_Ventas_Calculado'\n", + "NAV_HEADER = 'mssql2022_dbo.anjana_sales_invoice_header'\n", + "NAV_LINE = 'mssql2022_dbo.anjana_sales_invoice_line'\n", + "SO = 'psql_dcpublic.supply_orders'\n", + "LO = 'psql_dcpublic.logistic_orders'\n", + "\n", + "# FUENTE 1: Cubo_Ventas_Calculado (WSWEB) 2025\n", + "sql_cubo_total = f'''\n", + "SELECT\n", + " COUNT(*) AS lineas,\n", + " SUM(Importe_Neto) AS revenue_total\n", + "FROM `{CUBO}`\n", + "WHERE Dim_NombreDimGlobal2 = 'WSWEB'\n", + " AND EXTRACT(YEAR FROM Fecha_Registro) = 2025\n", + "'''\n", + "df_cubo_tot = run_sql(sql_cubo_total)\n", + "print('=== FUENTE 1: Cubo_Ventas_Calculado (WSWEB) 2025 ===')\n", + "print(df_cubo_tot.to_string(index=False))" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "id": "4af04f5b", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Tabla: Cubo_Ventas_Calculado db=6\n", + "Total columnas: 45\n", + "\n", + " fecha [DateTime]\n", + " Dim_Fecha [DateTime]\n", + " Dim_NombreCentro [Text]\n", + " Dim_IdComAutonoma [Integer]\n", + " Dim_NombreComAutonoma [Text]\n", + " Dim_IdZona [Integer]\n", + " Dim_NombreZona [Text]\n", + " Dim_AmbitoCentro [Text]\n", + " Dim_NombreTipoMov [Text]\n", + " Dim_NombreDimGlobal2 [Text]\n", + " Dim_NombreProveedor [Text]\n", + " Dim_NombreCampana [Text]\n", + " Dim_NombreTipoTicket [Text]\n", + " Dim_NombreMotivoAjuste [Text]\n", + " Dim_NombreProducto [Text]\n", + " Dim_CodProducto [Text]\n", + " Dim_IdCategoria [Text]\n", + " Dim_IdActivoExterno [Integer]\n", + " Dim_IdLiquidacion [Integer]\n", + " Dim_IdEstado [Integer]\n", + " Dim_IdTipo [Integer]\n", + " Dim_PeriodoCobertura [Integer]\n", + " Dim_Matricula [Text]\n", + " Dim_NombreCategoria [Text]\n", + " Dim_NombreTipo [Text]\n" + ] + } + ], + "source": [ + "# Listar columnas de Cubo_Ventas_Calculado para conocer nombres reales\n", + "cubo_tbl = client.request(\"GET\", \"/api/table/2890/query_metadata\")\n", + "print(f\"Tabla: {cubo_tbl['name']} db={cubo_tbl['db_id']}\")\n", + "print(f\"Total columnas: {len(cubo_tbl['fields'])}\")\n", + "print()\n", + "# Buscar campos relacionados con fecha, importe, dimension\n", + "for f in cubo_tbl['fields']:\n", + " n = f['name']\n", + " if any(k in n.lower() for k in ['fecha', 'date', 'importe', 'amount', 'dim_', 'nombre']):\n", + " print(f\" {n:45} [{f['base_type'].replace('type/','')}]\")" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "id": "38d51545", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + " idTipoMovimiento [Integer]\n", + " idMotivoAjuste [Integer]\n", + " idTipo [Integer]\n", + " idTipoDeTicket [Integer]\n", + " numeroLineas [Integer]\n", + " cantidad [Decimal]\n", + " costeUnitario [Decimal]\n", + " precioUnitario [Decimal]\n", + " compraReal [Decimal]\n", + " compraEsperada [Decimal]\n", + " Dim_IdComAutonoma [Integer]\n", + " Dim_IdZona [Integer]\n", + " Dim_IdActivoExterno [Integer]\n", + " Dim_IdLiquidacion [Integer]\n", + " Dim_IdEstado [Integer]\n", + " Dim_IdTipo [Integer]\n", + " Dim_PeriodoCobertura [Integer]\n", + " PrecioVenta [Decimal]\n", + " PrecioCompra [Decimal]\n" + ] + } + ], + "source": [ + "# Todas las columnas numericas (para encontrar importe/revenue)\n", + "for f in cubo_tbl['fields']:\n", + " if f['base_type'] in ('type/Float', 'type/Decimal', 'type/Integer', 'type/BigInteger'):\n", + " print(f\" {f['name']:45} [{f['base_type'].replace('type/','')}]\")" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "id": "78650d74", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "=== FUENTE 1 (v2): Cubo_Ventas_Calculado WSWEB 2025 ===\n", + " lineas revenue suma_precio_venta\n", + " 158617 5,879,313.22 5,879,313.22\n", + "\n", + "Doc 8 dice: 5.879.313€ en 158.617 lineas\n" + ] + } + ], + "source": [ + "# Query Cubo ajustada: campo fecha es 'fecha', revenue = cantidad * precioUnitario\n", + "sql_cubo_total_v2 = f'''\n", + "SELECT\n", + " COUNT(*) AS lineas,\n", + " SUM(cantidad * precioUnitario) AS revenue,\n", + " SUM(PrecioVenta) AS suma_precio_venta\n", + "FROM `{CUBO}`\n", + "WHERE Dim_NombreDimGlobal2 = 'WSWEB'\n", + " AND EXTRACT(YEAR FROM fecha) = 2025\n", + "'''\n", + "df_cubo_v2 = run_sql(sql_cubo_total_v2)\n", + "print('=== FUENTE 1 (v2): Cubo_Ventas_Calculado WSWEB 2025 ===')\n", + "print(df_cubo_v2.to_string(index=False))\n", + "print()\n", + "print(f\"Doc 8 dice: 5.879.313€ en 158.617 lineas\")" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "id": "94ba6ba6", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "--- anjana_sales_invoice_header (id 3452) — 180 cols ---\n", + " dates: ['document_date', 'hora_env__sol__autorizacion', 'time_sent', 'pmt__discount_date', 'shipment_date', 'fecha_operacion']\n", + " nums: ['tipo_de_registro_tpv', 'applies_to_doc__type', 'estado_pago_web', 'eu_3_party_trade', 'get_shipment_used', 'credito_disponible', 'venta_online', 'num__turno']\n", + " keys: ['no_', 'document_date', 'order_no__series', 'vat_registration_no_', 'applies_to_doc__no_', 'applies_to_bill_no_', 'prepayment_no__series', 'quote_no_', 'num__turno', 'pre_assigned_no__series', 'campaign_no_', 'pre_assigned_no_']\n", + "\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "--- anjana_sales_invoice_line (id 3437) — 126 cols ---\n", + " dates: ['fa_posting_date', 'shipment_date', 'posting_date', '_fivetran_synced']\n", + " nums: ['line_no_', 'ec__', 'vat__', 'permite_dto__promocion', 'cross_reference_type', 'job_contract_entry_no_', 'inv__discount_amount', 'unit_price']\n", + " keys: ['document_no_', 'line_no_', 'cross_reference_no_', 'job_contract_entry_no_', 'inv__discount_amount', 'unit_price', 'nonstock', 'line_amount', 'num__turno', 'shipment_no_', 'abono_num__linea_ticket', 'amount']\n", + "\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "--- supply_orders (id 1530) — 58 cols ---\n", + " dates: ['delivery_date', 'created_at', 'updated_at', 'reviewed_at', 'shipped_at', 'provider_delivery_at']\n", + " nums: ['id', 'service_request_id', 'product_id', 'quantity', 'supply_method', 'provider_id', 'status', 'marketplace_offer_id']\n", + " keys: ['service_request_id', 'provider_order_id', 'logistic_order_id', 'sale_price', 'purchase_price', 'tpv_orders_order_id', 'tpv_orders_orderitem_id', 'eci_sell_price', 'shipping_price', 'internal_provider_order', 'official_service', 'order_version']\n", + "\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "--- logistic_orders (id 1534) — 31 cols ---\n", + " dates: ['datetime', 'created_at', 'updated_at']\n", + " nums: ['id', 'service_request_id', 'center_id', 'provider_id', 'status', 'order_type', 'shipping_method', 'shipping_price']\n", + " keys: ['service_request_id', 'center_id', 'order_id', 'order_type', 'shipping_price', 'external_total_price', 'cd_order_id', 'center_request_id']\n", + "\n" + ] + } + ], + "source": [ + "# Inspect columns of the 4 remaining tables in BigQuery\n", + "TABLE_IDS = {\n", + " 'anjana_sales_invoice_header': 3452,\n", + " 'anjana_sales_invoice_line': 3437,\n", + " 'supply_orders': 1530,\n", + " 'logistic_orders': 1534,\n", + "}\n", + "tbl_meta = {}\n", + "for name, tid in TABLE_IDS.items():\n", + " m = client.request(\"GET\", f\"/api/table/{tid}/query_metadata\")\n", + " tbl_meta[name] = m\n", + " date_cols = [f['name'] for f in m['fields'] if f['base_type'] in ('type/Date','type/DateTime','type/DateTimeWithLocalTZ')]\n", + " num_cols = [f['name'] for f in m['fields'] if f['base_type'] in ('type/Float','type/Decimal','type/Integer','type/BigInteger')]\n", + " key_cols = [f['name'] for f in m['fields'] if any(k in f['name'].lower() for k in ['amount','price','location','center','no','document','order','request','service'])]\n", + " print(f\"--- {name} (id {tid}) — {len(m['fields'])} cols ---\")\n", + " print(f\" dates: {date_cols[:6]}\")\n", + " print(f\" nums: {num_cols[:8]}\")\n", + " print(f\" keys: {key_cols[:12]}\")\n", + " print()" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "id": "7af4af12", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Location cols header: ['location_code']\n", + "Date/Fecha cols header: ['document_date', 'pmt__discount_date', 'shipment_date', 'fecha_operacion', 'fecha_env__sol__autorizacion', 'posting_date', 'order_date', 'date_sent', 'due_date']\n" + ] + } + ], + "source": [ + "# location_code en header?\n", + "loc_cols = [f['name'] for f in tbl_meta['anjana_sales_invoice_header']['fields'] if 'location' in f['name'].lower()]\n", + "date_all = [f['name'] for f in tbl_meta['anjana_sales_invoice_header']['fields'] if 'date' in f['name'].lower() or 'fecha' in f['name'].lower()]\n", + "print('Location cols header:', loc_cols)\n", + "print('Date/Fecha cols header:', date_all)" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "id": "31e6e417", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "=== FUENTE 2: NAV directo (centros web) 2025 ===\n", + " lineas revenue suma_line_amount\n", + " 315831 13,324,819.67 15,872,265.87\n", + "Doc 8 dice: 15.878.883€ en 315.173 lineas\n" + ] + } + ], + "source": [ + "# FUENTE 2: NAV directo (centros web '18','19','405','421','422') 2025\n", + "sql_nav_total = f'''\n", + "SELECT\n", + " COUNT(*) AS lineas,\n", + " SUM(l.amount) AS revenue,\n", + " SUM(l.line_amount) AS suma_line_amount\n", + "FROM `{NAV_LINE}` l\n", + "JOIN `{NAV_HEADER}` h ON l.document_no_ = h.no_\n", + "WHERE h.location_code IN ('18','19','405','421','422')\n", + " AND EXTRACT(YEAR FROM h.posting_date) = 2025\n", + "'''\n", + "df_nav_v1 = run_sql(sql_nav_total)\n", + "print('=== FUENTE 2: NAV directo (centros web) 2025 ===')\n", + "print(df_nav_v1.to_string(index=False))\n", + "print(f\"Doc 8 dice: 15.878.883€ en 315.173 lineas\")" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "id": "86058b68", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "=== FUENTE 3: Supply Orders web (service_request_id NOT NULL) 2025 ===\n", + " supply_orders revenue_sale_x_qty suma_sale_price\n", + " 192251 22,669,646.01 11,302,142.62\n", + "Doc 8 dice: 7.235.399€ en ~160K lineas\n" + ] + } + ], + "source": [ + "# FUENTE 3: Supply Orders web (service_request_id IS NOT NULL) 2025\n", + "sql_so_total = f'''\n", + "SELECT\n", + " COUNT(*) AS supply_orders,\n", + " SUM(sale_price * quantity) AS revenue_sale_x_qty,\n", + " SUM(sale_price) AS suma_sale_price\n", + "FROM `{SO}`\n", + "WHERE service_request_id IS NOT NULL\n", + " AND EXTRACT(YEAR FROM created_at) = 2025\n", + "'''\n", + "df_so = run_sql(sql_so_total)\n", + "print('=== FUENTE 3: Supply Orders web (service_request_id NOT NULL) 2025 ===')\n", + "print(df_so.to_string(index=False))\n", + "print(f\"Doc 8 dice: 7.235.399€ en ~160K lineas\")" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "id": "0557b658", + "metadata": {}, + "outputs": [ + { + "ename": "NameError", + "evalue": "name 'db6' is not defined", + "output_type": "error", + "traceback": [ + "\u001b[31m---------------------------------------------------------------------------\u001b[39m", + "\u001b[31mNameError\u001b[39m Traceback (most recent call last)", + "\u001b[36mCell\u001b[39m\u001b[36m \u001b[39m\u001b[32mIn[10]\u001b[39m\u001b[32m, line 4\u001b[39m\n\u001b[32m 1\u001b[39m \u001b[38;5;66;03m# Buscar tablas candidatas para \"centros\" con flag digital\u001b[39;00m\n\u001b[32m 2\u001b[39m \u001b[38;5;66;03m# Probables: catalogos maestros en anjana_bi_datamart, mssql2022_dbo o anjana_bi_ntg\u001b[39;00m\n\u001b[32m 3\u001b[39m candidates = []\n\u001b[32m----> \u001b[39m\u001b[32m4\u001b[39m \u001b[38;5;28;01mfor\u001b[39;00m t \u001b[38;5;28;01min\u001b[39;00m db6[\u001b[33m'tables'\u001b[39m]:\n\u001b[32m 5\u001b[39m n = t[\u001b[33m'name'\u001b[39m].lower()\n\u001b[32m 6\u001b[39m \u001b[38;5;28;01mif\u001b[39;00m any(k \u001b[38;5;28;01min\u001b[39;00m n \u001b[38;5;28;01mfor\u001b[39;00m k \u001b[38;5;28;01min\u001b[39;00m [\u001b[33m'centro'\u001b[39m, \u001b[33m'center'\u001b[39m, \u001b[33m'compania'\u001b[39m, \u001b[33m'company'\u001b[39m, \u001b[33m'location'\u001b[39m, \u001b[33m'dim_centro'\u001b[39m, \u001b[33m'dim_nom'\u001b[39m]):\n\u001b[32m 7\u001b[39m candidates.append({\u001b[33m'id'\u001b[39m: t[\u001b[33m'id'\u001b[39m], \u001b[33m'schema'\u001b[39m: t.get(\u001b[33m'schema'\u001b[39m,\u001b[33m''\u001b[39m), \u001b[33m'name'\u001b[39m: t[\u001b[33m'name'\u001b[39m], \u001b[33m'rows'\u001b[39m: t.get(\u001b[33m'entity_type'\u001b[39m)})\n", + "\u001b[31mNameError\u001b[39m: name 'db6' is not defined" + ] + } + ], + "source": [ + "# Buscar tablas candidatas para \"centros\" con flag digital\n", + "# Probables: catalogos maestros en anjana_bi_datamart, mssql2022_dbo o anjana_bi_ntg\n", + "candidates = []\n", + "for t in db6['tables']:\n", + " n = t['name'].lower()\n", + " if any(k in n for k in ['centro', 'center', 'compania', 'company', 'location', 'dim_centro', 'dim_nom']):\n", + " candidates.append({'id': t['id'], 'schema': t.get('schema',''), 'name': t['name'], 'rows': t.get('entity_type')})\n", + "pd.DataFrame(candidates).head(30)" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "id": "89818b26", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Tablas candidatas centros: 163\n" + ] + }, + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
idschemaname
02332google_ads_dataads_CampaignLocationTargetStats_7692019626
12365google_ads_dataads_LocationBasedCampaignCriterion_7692019626
22450google_ads_dataads_LocationsDistanceStats_7692019626
32354google_ads_dataads_LocationsUserLocationsStats_7692019626
44141anjana_bi_datamartagg_venta_cat_centro_dia_mas_n1
54091anjana_bi_datamartagg_venta_cat_centro_semana_mas_n1
61914almacen_movsalmacen_centro
71924stg_anjana_bialmacen_centro
83424mssql2022_dboanjana_location
94263anjana_bi_amgapertura_agosto_centros
103681anjana_bi_amgapertura_centros
113940anjana_bi_amgapertura_centros_junio_v3
124493stg_anjana_biapertura_centros_mat
133941anjana_bi_amgapertura_junio_centros_patch_1
143674anjana_bi_datamartapertura_mayo_centros
153836anjana_bi_amgaperturas_junio_centros
163455mssql2022_dboautocentros_del_suroeste_itemstatusmodlog
173431mssql2022_dboautocentros_del_suroeste_purchdocsdeletelog
184472anjana_bi_ntgboxes_centros_mecanica_cristales
194475anjana_bi_ntgboxes_centros_mecanica_cristales_completo
204218anjana_bi_datamartCalendario_centros_productos
214216anjana_bi_datamartCalendario_productos_centros_ventas_n-1
224242anjana_bi_datamartCalen_product_center_n_materialized
233105anjana_bi_datamartCantidad_de_citas_contra_total_tiempo_citas_centros_cristales_prox_semana
241588psql_dcpubliccenters
253135anjana_bi_amgcenters_clean
262939test_salescentros
274102questions_metabasecentros
281679citaprevia_aurphcpcentros
291926stg_anjana_bicentros
\n", + "
" + ], + "text/plain": [ + " id schema \\\n", + "0 2332 google_ads_data \n", + "1 2365 google_ads_data \n", + "2 2450 google_ads_data \n", + "3 2354 google_ads_data \n", + "4 4141 anjana_bi_datamart \n", + "5 4091 anjana_bi_datamart \n", + "6 1914 almacen_movs \n", + "7 1924 stg_anjana_bi \n", + "8 3424 mssql2022_dbo \n", + "9 4263 anjana_bi_amg \n", + "10 3681 anjana_bi_amg \n", + "11 3940 anjana_bi_amg \n", + "12 4493 stg_anjana_bi \n", + "13 3941 anjana_bi_amg \n", + "14 3674 anjana_bi_datamart \n", + "15 3836 anjana_bi_amg \n", + "16 3455 mssql2022_dbo \n", + "17 3431 mssql2022_dbo \n", + "18 4472 anjana_bi_ntg \n", + "19 4475 anjana_bi_ntg \n", + "20 4218 anjana_bi_datamart \n", + "21 4216 anjana_bi_datamart \n", + "22 4242 anjana_bi_datamart \n", + "23 3105 anjana_bi_datamart \n", + "24 1588 psql_dcpublic \n", + "25 3135 anjana_bi_amg \n", + "26 2939 test_sales \n", + "27 4102 questions_metabase \n", + "28 1679 citaprevia_aurphcp \n", + "29 1926 stg_anjana_bi \n", + "\n", + " name \n", + "0 ads_CampaignLocationTargetStats_7692019626 \n", + "1 ads_LocationBasedCampaignCriterion_7692019626 \n", + "2 ads_LocationsDistanceStats_7692019626 \n", + "3 ads_LocationsUserLocationsStats_7692019626 \n", + "4 agg_venta_cat_centro_dia_mas_n1 \n", + "5 agg_venta_cat_centro_semana_mas_n1 \n", + "6 almacen_centro \n", + "7 almacen_centro \n", + "8 anjana_location \n", + "9 apertura_agosto_centros \n", + "10 apertura_centros \n", + "11 apertura_centros_junio_v3 \n", + "12 apertura_centros_mat \n", + "13 apertura_junio_centros_patch_1 \n", + "14 apertura_mayo_centros \n", + "15 aperturas_junio_centros \n", + "16 autocentros_del_suroeste_itemstatusmodlog \n", + "17 autocentros_del_suroeste_purchdocsdeletelog \n", + "18 boxes_centros_mecanica_cristales \n", + "19 boxes_centros_mecanica_cristales_completo \n", + "20 Calendario_centros_productos \n", + "21 Calendario_productos_centros_ventas_n-1 \n", + "22 Calen_product_center_n_materialized \n", + "23 Cantidad_de_citas_contra_total_tiempo_citas_centros_cristales_prox_semana \n", + "24 centers \n", + "25 centers_clean \n", + "26 centros \n", + "27 centros \n", + "28 centros \n", + "29 centros " + ] + }, + "execution_count": 11, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# Recargar metadata y globals tras restart del kernel\n", + "db6 = client.request('GET', '/api/database/6?include=tables')\n", + "TABLE_IDS = {\n", + " 'anjana_sales_invoice_header': 3452,\n", + " 'anjana_sales_invoice_line': 3437,\n", + " 'supply_orders': 1530,\n", + " 'logistic_orders': 1534,\n", + "}\n", + "tbl_meta = {}\n", + "for name, tid in TABLE_IDS.items():\n", + " tbl_meta[name] = client.request(\"GET\", f\"/api/table/{tid}/query_metadata\")\n", + "cubo_tbl = client.request(\"GET\", \"/api/table/2890/query_metadata\")\n", + "\n", + "CUBO = 'anjana_bi_datamart.Cubo_Ventas_Calculado'\n", + "NAV_HEADER = 'mssql2022_dbo.anjana_sales_invoice_header'\n", + "NAV_LINE = 'mssql2022_dbo.anjana_sales_invoice_line'\n", + "SO = 'psql_dcpublic.supply_orders'\n", + "LO = 'psql_dcpublic.logistic_orders'\n", + "\n", + "# Buscar tablas de centros\n", + "candidates = []\n", + "for t in db6['tables']:\n", + " n = t['name'].lower()\n", + " if any(k in n for k in ['centro', 'center', 'compania', 'company', 'location']):\n", + " candidates.append({'id': t['id'], 'schema': t.get('schema',''), 'name': t['name']})\n", + "print(f\"Tablas candidatas centros: {len(candidates)}\")\n", + "pd.DataFrame(candidates).head(30)" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "id": "f9f93165", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "=== mssql2022_dbo.anjana_location (id 3424) — 108 cols ===\n", + " code [Text]\n", + " cross_dock_bin_code [Text]\n", + " tipo_de_surtido [Integer]\n", + " shipment_bin_code [Text]\n", + " post_code [Text]\n", + " receipt_bin_code [Text]\n", + " outbound_production_bin_code [Text]\n", + " open_shop_floor_bin_code [Text]\n", + " name_2 [Text]\n", + " inbound_bom_bin_code [Text]\n", + " base_calendar_code [Text]\n", + " adjustment_bin_code [Text]\n", + " name [Text]\n", + " outbound_bom_bin_code [Text]\n", + " country_region_code [Text]\n", + " inbound_production_bin_code [Text]\n", + " put_away_template_code [Text]\n", + "\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "=== psql_dcpublic.centers (id 1588) — 101 cols ===\n", + " id [Integer]\n", + " name [Text]\n", + " nav_id [Text]\n", + " company_id [Integer]\n", + " center_type [Integer]\n", + " store_type [Integer]\n", + " postal_code [Text]\n", + " municipality_id [Integer]\n", + " normalized_name [Text]\n", + " external_id [Text]\n", + " allow_automatic_provider_orders [Boolean]\n", + " tax_type [Integer]\n", + " teccom_id [Text]\n", + " uuid [Text]\n", + " provider_config [JSON]\n", + " pin_pad_payment_type_id [Integer]\n", + " cash_payment_type_id [Integer]\n", + " zone_id [Integer]\n", + " visualtime_group_id [Integer]\n", + " stock_center_id [Integer]\n", + " is_digital [Boolean]\n", + "\n" + ] + } + ], + "source": [ + "# Inspeccionar las 2 candidatas mas probables: anjana_location (Navision) y centers (DC)\n", + "for tid, label in [(3424, 'mssql2022_dbo.anjana_location'), (1588, 'psql_dcpublic.centers')]:\n", + " m = client.request(\"GET\", f\"/api/table/{tid}/query_metadata\")\n", + " print(f\"=== {label} (id {tid}) — {len(m['fields'])} cols ===\")\n", + " for f in m['fields']:\n", + " n = f['name']\n", + " if any(k in n.lower() for k in ['code','name','company','compan','nav','id','type','digital','online','web','channel']):\n", + " print(f\" {n:40} [{f['base_type'].replace('type/','')}]\")\n", + " print()" + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "id": "815845c6", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Centros digitales: 5\n", + " id name nav_id company_id center_type\n", + "160 Aurgi Web 18 1 0\n", + "161 MT Web 19 2 0\n", + "167 Autingo 405 3 0\n", + "183 Aurgi Asociados Gruas 421 1 0\n", + "184 Aurgi Asociados 422 1 0\n", + "\n", + "nav_ids digital: ('18', '19', '405', '421', '422')\n" + ] + } + ], + "source": [ + "# Listar centros digitales\n", + "CENTERS = 'psql_dcpublic.centers'\n", + "sql_digital = f'''\n", + "SELECT id, name, nav_id, company_id, center_type\n", + "FROM `{CENTERS}`\n", + "WHERE is_digital = TRUE\n", + "ORDER BY nav_id\n", + "'''\n", + "df_digital = run_sql(sql_digital)\n", + "print(f'Centros digitales: {len(df_digital)}')\n", + "print(df_digital.to_string(index=False))\n", + "NAV_IDS_DIGITAL = tuple(df_digital['nav_id'].dropna().tolist())\n", + "print()\n", + "print('nav_ids digital:', NAV_IDS_DIGITAL)" + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "id": "494880ac", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
companiacentrotipo_movlineasrevenue
0WSWEBAurgi WebVenta1162663,777,996.81
1WSWEBAurgi Asociados GruasVenta274641,183,043.04
2WSWEBAutingoVenta11339725,910.50
3WSWEBAurgi AsociadosVenta5121,059.17
4WSWEBMT WebVenta354371,303.70
\n", + "
" + ], + "text/plain": [ + " compania centro tipo_mov lineas revenue\n", + "0 WSWEB Aurgi Web Venta 116266 3,777,996.81\n", + "1 WSWEB Aurgi Asociados Gruas Venta 27464 1,183,043.04\n", + "2 WSWEB Autingo Venta 11339 725,910.50\n", + "3 WSWEB Aurgi Asociados Venta 5 121,059.17\n", + "4 WSWEB MT Web Venta 3543 71,303.70" + ] + }, + "execution_count": 14, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# Valores en el Cubo para identificar centros digital. Mirar Dim_NombreCentro y tipos de mov.\n", + "sql_cubo_vals = f'''\n", + "SELECT\n", + " Dim_NombreDimGlobal2 AS compania,\n", + " Dim_NombreCentro AS centro,\n", + " Dim_NombreTipoMov AS tipo_mov,\n", + " COUNT(*) AS lineas,\n", + " SUM(cantidad * precioUnitario) AS revenue\n", + "FROM `{CUBO}`\n", + "WHERE EXTRACT(YEAR FROM fecha) = 2025\n", + " AND Dim_NombreDimGlobal2 = 'WSWEB'\n", + "GROUP BY compania, centro, tipo_mov\n", + "ORDER BY revenue DESC\n", + "LIMIT 50\n", + "'''\n", + "df_cubo_vals = run_sql(sql_cubo_vals)\n", + "df_cubo_vals" + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "id": "7c686f5e", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Document/type cols header: ['document_date', 'tipo_de_registro_tpv', 'applies_to_doc__type', 'tipo_operacion_intracomunitar', 'tipo_identificacion', 'tipo_factura', 'external_document_no_', 'n__documento_agrupado', 'bal__account_type', 'service_mgt__document', 'biztalk_document_sent', 'tipo_forma_pago', 'transaction_type', 'tipo_cliente_a_credito', 'tipo_fact__recrificativa_sii']\n" + ] + } + ], + "source": [ + "# NAV centros digitales 2025: desglose por document_type y location\n", + "# Tambien ver campos posibles de document_type en el header\n", + "header_fields = [f['name'] for f in tbl_meta['anjana_sales_invoice_header']['fields']]\n", + "doctype_cands = [n for n in header_fields if 'document' in n.lower() or 'type' in n.lower() or 'tipo' in n.lower()]\n", + "print('Document/type cols header:', doctype_cands[:20])" + ] + }, + { + "cell_type": "code", + "execution_count": 16, + "id": "3c0e4fc0", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + " 3423 anjana_sales_cr_memo_header\n", + " 3420 anjana_sales_cr_memo_line\n", + " 3422 anjana_sales_header\n", + " 3452 anjana_sales_invoice_header\n", + " 3437 anjana_sales_invoice_line\n", + " 3438 anjana_sales_shipment_header\n", + " 3447 anjana_sales_shipment_line\n", + " 3456 sales_price\n" + ] + } + ], + "source": [ + "# Buscar tablas complementarias: credit_memo / abono en mssql2022_dbo\n", + "nav_tables = [t for t in db6['tables'] if t.get('schema') == 'mssql2022_dbo' and \n", + " any(k in t['name'].lower() for k in ['invoice', 'credit', 'memo', 'abono', 'sales', 'return'])]\n", + "for t in nav_tables[:30]:\n", + " print(f\" {t['id']:5} {t['name']}\")" + ] + }, + { + "cell_type": "code", + "execution_count": 17, + "id": "a839b6f0", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "=== CUBO WSWEB Venta 2025 (por mes y centro) ===\n", + " mes centro tipos_ticket lineas revenue\n", + "2025-01 Aurgi Web 1 7194 225,546.19\n", + "2025-01 Autingo 1 817 37,279.39\n", + "2025-01 MT Web 1 841 17,140.52\n", + "2025-02 Aurgi Web 1 6639 199,168.29\n", + "2025-02 Autingo 1 651 32,029.22\n", + "2025-02 MT Web 1 282 4,990.85\n", + "2025-03 Aurgi Web 1 10983 291,552.93\n", + "2025-03 Autingo 1 1066 44,017.23\n", + "2025-03 MT Web 1 265 4,913.40\n", + "2025-04 Aurgi Asociados 1 1 165.12\n", + "2025-04 Aurgi Web 1 9272 269,613.69\n", + "2025-04 Autingo 1 762 36,524.61\n", + "2025-04 MT Web 1 187 4,311.97\n", + "2025-05 Aurgi Web 1 14096 416,243.31\n", + "2025-05 Autingo 1 1025 63,574.06\n", + "2025-05 MT Web 1 195 3,167.68\n", + "2025-06 Aurgi Web 1 14319 538,660.24\n", + "2025-06 Autingo 1 1340 106,750.38\n", + "2025-06 MT Web 1 208 4,092.61\n", + "2025-07 Aurgi Asociados 1 1 768.60\n", + "2025-07 Aurgi Web 1 14253 474,104.39\n", + "2025-07 Autingo 1 1647 120,074.72\n", + "2025-07 MT Web 1 192 3,933.84\n", + "2025-08 Aurgi Web 1 12914 406,695.78\n", + "2025-08 Autingo 1 1309 98,284.35\n", + "2025-08 MT Web 1 211 3,970.94\n", + "2025-09 Aurgi Asociados 1 1 125.45\n", + "2025-09 Aurgi Web 1 11336 362,341.53\n", + "2025-09 Autingo 1 936 66,635.28\n", + "2025-09 MT Web 1 181 3,756.54\n", + "2025-10 Aurgi Web 1 6787 242,111.20\n", + "2025-10 Autingo 1 914 62,344.22\n", + "2025-10 MT Web 1 235 5,063.87\n", + "2025-11 Aurgi Asociados Gruas 1 12 478.67\n", + "2025-11 Aurgi Web 1 6099 245,523.66\n", + "2025-11 Autingo 1 470 32,059.47\n", + "2025-11 MT Web 1 291 6,050.80\n", + "2025-12 Aurgi Asociados 1 2 120,000.00\n", + "2025-12 Aurgi Asociados Gruas 1 27452 1,182,564.37\n", + "2025-12 Aurgi Web 1 2374 106,435.60\n", + "2025-12 Autingo 1 402 26,337.57\n", + "2025-12 MT Web 1 455 9,910.68\n", + "\n", + "=== NAV directo centros digital 2025 (por mes y centro) ===\n", + " mes centro facturas lineas revenue_bruto revenue_neto\n", + "2025-01 18 13826 14107 545,817.10 451,092.37\n", + "2025-01 19 556 1119 41,481.82 34,281.91\n", + "2025-01 405 1703 1930 151,617.87 125,763.47\n", + "2025-02 18 12738 13008 481,985.12 398,336.60\n", + "2025-02 19 186 375 12,078.54 9,981.99\n", + "2025-02 405 1404 1597 118,325.88 97,789.87\n", + "2025-02 421 3 12 25,235.29 24,421.18\n", + "2025-03 18 21404 21695 706,556.94 584,016.70\n", + "2025-03 19 168 349 11,890.82 9,826.97\n", + "2025-03 405 2204 2461 155,032.74 128,125.80\n", + "2025-03 421 5 21 68,353.88 68,353.88\n", + "2025-04 18 17975 18252 652,055.79 538,890.56\n", + "2025-04 19 120 247 10,435.50 8,624.14\n", + "2025-04 405 1584 1778 134,098.20 110,824.51\n", + "2025-04 421 11 80 164,730.03 164,730.03\n", + "2025-04 422 2 2 399.60 330.24\n", + "2025-05 18 27494 27886 1,018,084.82 843,011.44\n", + "2025-05 19 130 260 7,666.28 6,335.59\n", + "2025-05 405 2105 2328 205,038.60 169,453.97\n", + "2025-05 421 12 51 86,491.73 86,491.73\n", + "2025-06 18 28022 28376 1,322,181.29 1,095,747.50\n", + "2025-06 19 136 276 9,904.60 8,185.45\n", + "2025-06 405 2764 2988 316,731.91 261,763.09\n", + "2025-06 421 10 48 116,732.66 116,732.66\n", + "2025-07 18 27610 28193 1,178,749.89 979,604.31\n", + "2025-07 19 126 255 9,520.20 7,867.80\n", + "2025-07 405 3372 3621 354,553.22 293,149.99\n", + "2025-07 421 16 60 135,986.92 135,986.92\n", + "2025-07 422 2 2 1,860.00 1,537.20\n", + "2025-08 18 25115 25495 986,518.81 815,692.95\n", + "2025-08 19 138 280 9,610.10 7,942.05\n", + "2025-08 405 2666 2829 271,704.71 224,551.24\n", + "2025-08 421 9 45 61,575.89 61,575.89\n", + "2025-09 18 22176 22456 881,738.19 729,572.09\n", + "2025-09 19 120 241 9,091.08 7,513.22\n", + "2025-09 405 1946 2109 205,127.52 169,527.47\n", + "2025-09 421 18 65 125,276.25 125,276.25\n", + "2025-09 422 2 2 303.60 250.90\n", + "2025-10 18 13110 13362 586,518.09 484,839.92\n", + "2025-10 19 156 313 12,255.24 10,128.06\n", + "2025-10 405 1924 2140 208,108.28 171,990.83\n", + "2025-10 421 14 60 112,173.57 112,173.57\n", + "2025-11 18 11832 12018 594,465.75 491,294.12\n", + "2025-11 19 190 386 14,643.46 12,101.80\n", + "2025-11 405 1028 1191 123,296.19 101,897.57\n", + "2025-11 421 49 109 131,830.71 131,629.65\n", + "2025-12 18 4376 4560 257,334.81 212,672.73\n", + "2025-12 19 302 606 23,984.90 19,821.76\n", + "2025-12 405 866 998 93,023.48 76,879.07\n", + "2025-12 421 55138 55187 2,974,888.00 2,476,230.66\n", + "2025-12 422 2 2 145,200.00 120,000.00\n" + ] + } + ], + "source": [ + "# --- Comparativa mensual 2025: Cubo vs NAV (centros digital 18/19/405/421/422) ---\n", + "# Incluye: revenue, nº facturas/tickets, nº lineas\n", + "\n", + "CENTROS_DIGITAL = \"('18','19','405','421','422')\"\n", + "CENTROS_DIGITAL_NOMBRES = \"('Aurgi Web','MT Web','Autingo','Aurgi Asociados Gruas','Aurgi Asociados')\"\n", + "\n", + "sql_cubo_mes = f'''\n", + "SELECT\n", + " FORMAT_DATE('%Y-%m', fecha) AS mes,\n", + " Dim_NombreCentro AS centro,\n", + " COUNT(DISTINCT Dim_NombreTipoTicket) AS tipos_ticket,\n", + " COUNT(*) AS lineas,\n", + " SUM(cantidad * precioUnitario) AS revenue\n", + "FROM `{CUBO}`\n", + "WHERE Dim_NombreDimGlobal2 = 'WSWEB'\n", + " AND Dim_NombreTipoMov = 'Venta'\n", + " AND EXTRACT(YEAR FROM fecha) = 2025\n", + "GROUP BY mes, centro\n", + "ORDER BY mes, centro\n", + "'''\n", + "df_cubo_mes = run_sql(sql_cubo_mes)\n", + "\n", + "sql_nav_mes = f'''\n", + "SELECT\n", + " FORMAT_DATE('%Y-%m', h.posting_date) AS mes,\n", + " h.location_code AS centro,\n", + " COUNT(DISTINCT h.no_) AS facturas,\n", + " COUNT(*) AS lineas,\n", + " SUM(l.line_amount) AS revenue_bruto,\n", + " SUM(l.amount) AS revenue_neto\n", + "FROM `{NAV_LINE}` l\n", + "JOIN `{NAV_HEADER}` h ON l.document_no_ = h.no_\n", + "WHERE h.location_code IN {CENTROS_DIGITAL}\n", + " AND EXTRACT(YEAR FROM h.posting_date) = 2025\n", + "GROUP BY mes, centro\n", + "ORDER BY mes, centro\n", + "'''\n", + "df_nav_mes = run_sql(sql_nav_mes)\n", + "\n", + "print('=== CUBO WSWEB Venta 2025 (por mes y centro) ===')\n", + "print(df_cubo_mes.to_string(index=False))\n", + "print()\n", + "print('=== NAV directo centros digital 2025 (por mes y centro) ===')\n", + "print(df_nav_mes.to_string(index=False))" + ] + }, + { + "cell_type": "code", + "execution_count": 18, + "id": "dab0247e", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "=== NAV tipos de registro (centros digital 2025) ===\n", + " tipo_de_registro_tpv tipo_factura transaction_type facturas revenue\n", + " 4 306634 14,670,280.59\n", + " 0 F1 231 1,201,985.28\n" + ] + } + ], + "source": [ + "# Que tipos de registros tiene NAV para centros digitales 2025\n", + "sql_nav_types = f'''\n", + "SELECT\n", + " h.tipo_de_registro_tpv,\n", + " h.tipo_factura,\n", + " h.transaction_type,\n", + " COUNT(DISTINCT h.no_) AS facturas,\n", + " SUM(l.line_amount) AS revenue\n", + "FROM `{NAV_LINE}` l\n", + "JOIN `{NAV_HEADER}` h ON l.document_no_ = h.no_\n", + "WHERE h.location_code IN {CENTROS_DIGITAL}\n", + " AND EXTRACT(YEAR FROM h.posting_date) = 2025\n", + "GROUP BY h.tipo_de_registro_tpv, h.tipo_factura, h.transaction_type\n", + "ORDER BY facturas DESC\n", + "'''\n", + "df_nav_types = run_sql(sql_nav_types)\n", + "print('=== NAV tipos de registro (centros digital 2025) ===')\n", + "print(df_nav_types.to_string(index=False))" + ] + }, + { + "cell_type": "code", + "execution_count": 19, + "id": "01872457", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "supply_orders — campos posibles canal:\n", + " marketplace_offer_id\n", + " tpv_orders_order_id\n", + " tpv_orders_orderitem_id\n", + " eci_mk_id\n", + " eci_sell_price\n", + " eci_status\n", + " source_timestamp\n", + " official_service\n", + " official_service_from_provider\n", + "\n", + "logistic_orders — campos posibles canal:\n", + " source_timestamp\n", + "\n", + "Tablas psql_dcpublic marketplace/tpv/orders:\n", + " 1565 channels\n", + " 1534 logistic_orders\n", + " 2704 ralarsa_orders\n", + " 1530 supply_orders\n", + " 2705 tpv_appointment_appointment\n", + " 1659 tpv_authorization_instanceaccesstoken\n", + " 1653 tpv_authorization_tpvclock\n", + " 1654 tpv_authorization_tpvuser\n", + " 1655 tpv_authorization_tpvuser_centers\n", + " 1657 tpv_authorization_tpvuser_groups\n", + " 1858 tpv_authorization_tpvuser_user_permissions\n", + " 3826 tpv_auto_billing_autobillingrequest\n", + " 3827 tpv_auto_billing_autobillingrequestlog\n", + " 1658 tpv_cashreg_cashmovement\n", + " 1656 tpv_centers_shift\n", + " 1888 tpv_commissions_commission\n", + " 1886 tpv_commissions_commissionconfiguration\n", + " 1884 tpv_commissions_productcommissionreduction\n", + " 1527 tpv_companies\n", + " 2560 tpv_customer_history_action\n" + ] + } + ], + "source": [ + "# Buscar campos de canal/marketplace en supply_orders y logistic_orders\n", + "so_fields = [f['name'] for f in tbl_meta['supply_orders']['fields']]\n", + "lo_fields = [f['name'] for f in tbl_meta['logistic_orders']['fields']]\n", + "print('supply_orders — campos posibles canal:')\n", + "for f in so_fields:\n", + " if any(k in f.lower() for k in ['channel','canal','market','source','platform','origin','referer','tpv','official','amazon','eci']):\n", + " print(f' {f}')\n", + "print()\n", + "print('logistic_orders — campos posibles canal:')\n", + "for f in lo_fields:\n", + " if any(k in f.lower() for k in ['channel','canal','market','source','platform','origin','referer','tpv']):\n", + " print(f' {f}')\n", + "print()\n", + "# Tablas complementarias: tpv_orders, marketplace\n", + "mkt_tables = [t for t in db6['tables'] if t.get('schema') == 'psql_dcpublic' and \n", + " any(k in t['name'].lower() for k in ['tpv','marketplace','channel','offer','order'])]\n", + "print(f'Tablas psql_dcpublic marketplace/tpv/orders:')\n", + "for t in mkt_tables[:20]:\n", + " print(f\" {t['id']:5} {t['name']}\")" + ] + }, + { + "cell_type": "code", + "execution_count": 20, + "id": "1c302199", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "=== channels fields ===\n", + " id [Integer]\n", + " company_id [Integer]\n", + " name [Text]\n", + " slug [Text]\n", + " domain [Text]\n", + " status [Integer]\n", + " nav_id [Integer]\n", + " channel_type [Integer]\n", + " external [Boolean]\n", + " starting_date [Date]\n", + " ending_date [Date]\n", + " created_at [DateTimeWithLocalTZ]\n", + " updated_at [DateTimeWithLocalTZ]\n", + " mirakl_code [Text]\n", + " tag_config [JSON]\n", + " datastream_metadata [Dictionary]\n", + " source_timestamp [Integer]\n", + " uuid [Text]\n", + " digital_center_id [Integer]\n", + "\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "=== channels data ===\n", + " id company_id name slug domain status nav_id channel_type external starting_date ending_date created_at updated_at mirakl_code tag_config datastream_metadata digital_center_id\n", + " 1 1 aurgi.com aurgi-com None None None None None None None 2020-05-07T23:57:45.785733+02:00 2023-10-03T17:45:54.377289+02:00 INIT {\"all_included_price_tag\":\"aurgi_all_included_price\",\"brand_tag\":\"aurgi\",\"economic_tag\":\"racing\",\"included_in_set_prices\":\"true\",\"mc2p_tag\":\"aurgi\",\"nav_name_tag\":\"Prestashop\",\"product_price_tag\":\"aurgi_price\",\"promo_price_tag\":\"aurgi\",\"sale_code_tag\":\"471\",\"sale_price_slug_tag\":\"aurgi-com\",\"set_other_prices_tags\":[\"aurgi_price_to_sort\",\"aurgi_all_included_price\"],\"set_simple_prices_tags\":[\"aurgi_price\"],\"slug_normal_tag\":\"aurgi\",\"slug_other_tag\":\"aurgi_tag\",\"stock_tag\":\"aurgi\"} {'uuid': '8cefc67c-1aa9-4447-a53c-91cb00000000', 'source_timestamp': 1696802998957} None\n", + " 2 2 motortown.es motortown-es None None None None None None None 2020-05-07T23:57:45.801079+02:00 2026-03-17T14:03:40.388276+01:00 {\"all_included_price_tag\":\"mt_all_included_price\",\"brand_tag\":\"motortown\",\"economic_tag\":\"economico\",\"included_in_set_prices\":\"true\",\"mc2p_tag\":\"mt\",\"nav_name_tag\":\"WebMT\",\"product_price_tag\":\"mt_price\",\"promo_price_tag\":\"motortown\",\"sale_code_tag\":\"472\",\"sale_price_slug_tag\":\"motortown-es\",\"set_other_prices_tags\":[\"motortown_price_to_sort\",\"mt_all_included_price\"],\"set_simple_prices_tags\":[\"mt_price\"],\"slug_normal_tag\":\"motortown\",\"slug_other_tag\":\"motortown_tag\",\"stock_tag\":\"motortown\",\"tpv_index\":\"TPV_MT_IDX\"} {'uuid': 'a947ab61-5cb5-416f-89ab-a8d700010010', 'source_timestamp': 1773752620397} None\n", + " 3 3 autingo.es autingo-es None None None None None None None 2020-05-07T23:57:45.818754+02:00 2024-11-06T11:34:08.699318+01:00 {\"bank_account_tag\":true,\"exclude_for_delete\":true,\"mc2p_tag\":\"autingo\",\"product_price_tag\":\"autingo_price\",\"sale_price_slug_tag\":\"autingo-es\",\"set_other_prices_tags\":[],\"set_simple_prices_tags\":[\"autingo_price\"],\"slug_normal_tag\":\"autingo\",\"stock_tag\":\"autingo\"} {'uuid': '5de8da99-c6da-497a-b088-5bd710100111', 'source_timestamp': 1730889248706} None\n", + " 4 1 Centros Aurgi centros-aurgi None None None None None None None 2020-12-15T15:39:36.135323+01:00 2025-03-25T15:54:20.349252+01:00 {\"all_included_price_tag\":\"aurgi_all_included_price\",\"brand_tag\":\"aurgi\",\"economic_tag\":\"racing\",\"included_in_set_prices\":\"true\",\"mc2p_tag\":\"aurgi\",\"nav_name_tag\":\"Producto Aurgi\",\"order_associate_tag\":\"true\",\"product_price_tag\":\"aurgi_price\",\"promo_price_tag\":\"aurgi\",\"sale_price_slug_tag\":\"aurgi-com\",\"set_other_prices_tags\":[\"aurgi_price_to_sort\",\"aurgi_all_included_price\"],\"set_simple_prices_tags\":[\"aurgi_price\"],\"slug_normal_tag\":\"aurgi\",\"slug_other_tag\":\"aurgi_tag\",\"stock_tag\":\"aurgi\"} {'uuid': 'b549922b-283c-4d12-82bb-632911110011', 'source_timestamp': 1742914460367} None\n", + " 5 2 Centros MT centros-mt None None None None None None None 2020-12-15T15:39:36.161249+01:00 2025-07-08T18:25:56.829215+02:00 {\"all_included_price_tag\":\"mt_all_included_price\",\"brand_tag\":\"motortown\",\"economic_tag\":\"economico\",\"included_in_set_prices\":\"true\",\"mc2p_tag\":\"mt\",\"nav_name_tag\":\"Producto MT\",\"product_price_tag\":\"mt_price\",\"promo_price_tag\":\"motortown\",\"sale_price_slug_tag\":\"motortown-es\",\"set_other_prices_tags\":[\"motortown_price_to_sort\",\"mt_all_included_price\"],\"set_simple_prices_tags\":[\"mt_price\"],\"slug_normal_tag\":\"motortown\",\"slug_other_tag\":\"motortown_tag\",\"stock_tag\":\"motortown\"} {'uuid': '71c2dcc4-f317-434d-8ca6-bd8311001100', 'source_timestamp': 1751991956843} None\n", + " 6 5 Eci Marketplace eci-marketplace None None None None None None None 2022-07-29T18:15:53.419166+02:00 2023-11-13T15:41:18.781688+01:00 NaN {\"product_price_tag\":\"eci_internal_price\",\"slug_normal_tag\":\"aurgi\",\"slug_other_tag\":\"aurgi_tag\"} {'uuid': '0a6cba7f-aea8-4e5e-ac82-3d3811100100', 'source_timestamp': 1699886478784} None\n", + " 7 5 NaN eci-internal-channel None None None None None None None 2022-11-21T11:40:03.968508+01:00 2023-11-13T15:40:28.875452+01:00 NaN {\"product_price_tag\":\"eci_internal_price\",\"slug_normal_tag\":\"aurgi\",\"slug_other_tag\":\"aurgi_tag\"} {'uuid': '1038881e-1a13-49ed-9aef-f23500110010', 'source_timestamp': 1699886428878} None\n", + " 8 6 Eci Marketplace eci-marketplace None None None None None None None 2022-11-21T13:15:24.79686+01:00 2023-11-13T15:41:25.976548+01:00 NaN {\"product_price_tag\":\"eci_internal_price\",\"slug_normal_tag\":\"aurgi\",\"slug_other_tag\":\"aurgi_tag\"} {'uuid': 'a72f9e13-0947-4c45-b1cc-170411111110', 'source_timestamp': 1699886485980} None\n", + " 10 1 Talleres Digitales talleres-digitales None None None None None None None 2023-11-06T12:16:20.072201+01:00 2024-04-22T12:34:27.691303+02:00 {\"all_included_price_tag\":\"digital_garage_all_included_price\",\"brand_tag\":\"aurgi\",\"economic_tag\":\"racing\",\"exclude_for_delete\":true,\"included_in_set_prices\":\"true\",\"mc2p_tag\":\"aurgi\",\"product_price_tag\":\"digital_garage_price\",\"promo_price_tag\":\"aurgi\",\"sale_price_slug_tag\":\"talleres-digitales\",\"set_other_prices_tags\":[],\"set_simple_prices_tags\":[\"digital_garage_price\"],\"slug_normal_tag\":\"aurgi\",\"slug_other_tag\":\"aurgi_tag\",\"stock_tag\":\"aurgi\",\"use_own_channel_automatic_order\":true} {'uuid': 'b4c39f76-a4df-4653-af17-6a4511111110', 'source_timestamp': 1713782067697} None\n", + " 11 1 Amazon amazon None None None None None None None 2023-11-20T15:37:28.276689+01:00 2024-03-12T16:36:34.826712+01:00 {\"exclude_for_delete\":true,\"payment_tag\":\"AMAZON\",\"product_price_tag\":\"amazon-price\",\"set_other_prices_tags\":[],\"set_simple_prices_tags\":[\"amazon-price\"],\"shopping_feed_tag\":66,\"skip_mk_offer_tag\":\"true\",\"slug_normal_tag\":\"aurgi\",\"slug_other_tag\":\"aurgi_tag\"} {'uuid': '4e0886a4-7296-45c3-8c76-016001001011', 'source_timestamp': 1710257794831} None\n", + " 12 2 canarias centros-canarias None None None None None None None 2023-11-23T15:17:28.028796+01:00 2023-11-23T15:17:39.873841+01:00 NaN {\"all_included_price_tag\":\"canarias_all_included_price\",\"brand_tag\":\"motortown\",\"economic_tag\":\"economico\",\"encargo_tax_tag\":1.07,\"included_in_set_prices\":\"true\",\"mc2p_tag\":\"mt\",\"nav_name_tag\":\"Producto MT Canarias\",\"product_price_tag\":\"canarias_price\",\"promo_price_tag\":\"motortown\",\"sale_code_tag\":\"478\",\"sale_price_slug_tag\":\"centros-canarias\",\"set_other_prices_tags\":[\"canarias_all_included_price\"],\"set_simple_prices_tags\":[\"canarias_price\"],\"slug_normal_tag\":\"motortown\",\"slug_other_tag\":\"motortown_tag\",\"stock_tag\":\"motortown\"} {'uuid': 'f099ca13-2277-416c-b5ca-a6c510010011', 'source_timestamp': 1700749059881} None\n", + " 13 1 Miravia miravia None None None None None None None 2023-11-30T18:04:57.917942+01:00 2024-03-12T16:37:29.88589+01:00 {\"exclude_for_delete\":true,\"payment_tag\":\"MIRAVIA\",\"product_price_tag\":\"miravia-price\",\"set_other_prices_tags\":[],\"set_simple_prices_tags\":[\"miravia-price\"],\"shopping_feed_tag\":46619,\"skip_mk_offer_tag\":\"true\",\"slug_normal_tag\":\"aurgi\",\"slug_other_tag\":\"aurgi_tag\"} {'uuid': '8a5ced8f-1e5c-49f8-a882-7be511101011', 'source_timestamp': 1710257849890} None\n", + " 14 1 Aliexpress aliexpress None None None None None None None 2024-07-29T16:31:25.337518+02:00 2024-07-29T17:18:24.465507+02:00 {\"exclude_for_delete\":true,\"payment_tag\":\"AE\",\"product_price_tag\":\"aliexpress-price\",\"set_other_prices_tags\":[],\"set_simple_prices_tags\":[\"aliexpress-price\"],\"shopping_feed_tag\":34210,\"skip_mk_offer_tag\":\"true\",\"slug_normal_tag\":\"aurgi\",\"slug_other_tag\":\"aurgi_tag\"} {'uuid': 'dbc99c04-6620-4528-92f4-4bdd00000010', 'source_timestamp': 1722266304470} None\n", + " 15 1 Tiktok Shop tiktok-shop None None None None None None None 2024-08-30T11:16:50.636998+02:00 2025-11-06T17:25:06.687578+01:00 {\"exclude_for_delete\":true,\"payment_tag\":\"TIKTOK\",\"product_price_tag\":\"tiktok_price\",\"set_other_prices_tags\":[],\"set_simple_prices_tags\":[\"tiktok_price\"],\"shopping_feed_tag\":51756,\"skip_mk_offer_tag\":\"true\",\"slug_normal_tag\":\"aurgi\",\"slug_other_tag\":\"aurgi_tag\"} {'uuid': '8836f949-5be3-426f-85c0-595111100011', 'source_timestamp': 1762446306694} None\n" + ] + } + ], + "source": [ + "# Ver tabla channels y buscar tpv_orders para entender canal\n", + "channels_meta = client.request(\"GET\", \"/api/table/1565/query_metadata\")\n", + "print('=== channels fields ===')\n", + "for f in channels_meta['fields']:\n", + " print(f\" {f['name']:40} [{f['base_type'].replace('type/','')}]\")\n", + "print()\n", + "\n", + "# Lista de todos los canales\n", + "df_ch = run_sql('SELECT * FROM `psql_dcpublic.channels` ORDER BY id')\n", + "print('=== channels data ===')\n", + "print(df_ch.to_string(index=False))" + ] + }, + { + "cell_type": "code", + "execution_count": 21, + "id": "886663ef", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "=== card 7750: SO↔NAV — Desglose por canal ===\n", + "type: None, database: 6\n" + ] + }, + { + "ename": "NameError", + "evalue": "name 'json' is not defined", + "output_type": "error", + "traceback": [ + "\u001b[31m---------------------------------------------------------------------------\u001b[39m", + "\u001b[31mNameError\u001b[39m Traceback (most recent call last)", + "\u001b[36mCell\u001b[39m\u001b[36m \u001b[39m\u001b[32mIn[21]\u001b[39m\u001b[32m, line 11\u001b[39m\n\u001b[32m 7\u001b[39m print(f'type: {dq.get(\u001b[33m\"type\"\u001b[39m)}, database: {dq.get(\u001b[33m\"database\"\u001b[39m)}')\n\u001b[32m 8\u001b[39m \u001b[38;5;28;01mif\u001b[39;00m dq.get(\u001b[33m'type'\u001b[39m) == \u001b[33m'native'\u001b[39m:\n\u001b[32m 9\u001b[39m print(dq[\u001b[33m'native'\u001b[39m][\u001b[33m'query'\u001b[39m][:\u001b[32m3000\u001b[39m])\n\u001b[32m 10\u001b[39m \u001b[38;5;28;01melse\u001b[39;00m:\n\u001b[32m---> \u001b[39m\u001b[32m11\u001b[39m print(json.dumps(dq.get(\u001b[33m'query'\u001b[39m), indent=\u001b[32m2\u001b[39m)[:\u001b[32m2000\u001b[39m])\n\u001b[32m 12\u001b[39m print()\n", + "\u001b[31mNameError\u001b[39m: name 'json' is not defined" + ] + } + ], + "source": [ + "# Leer la query de la card 7750 del doc 2 (Desglose por canal)\n", + "# y la 7751 (Revenue semanal web por canal)\n", + "for cid in [7750, 7751]:\n", + " c = client.request('GET', f'/api/card/{cid}')\n", + " dq = c.get('dataset_query') or {}\n", + " print(f'=== card {cid}: {c[\"name\"]} ===')\n", + " print(f'type: {dq.get(\"type\")}, database: {dq.get(\"database\")}')\n", + " if dq.get('type') == 'native':\n", + " print(dq['native']['query'][:3000])\n", + " else:\n", + " print(json.dumps(dq.get('query'), indent=2)[:2000])\n", + " print()" + ] + }, + { + "cell_type": "code", + "execution_count": 22, + "id": "15f185cb", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "=== card 7749: SO↔NAV — Evolución mensual por origen ===\n", + "type: None, database: 6\n", + "--- MBQL query ---\n", + "null\n", + "\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "=== card 7750: SO↔NAV — Desglose por canal ===\n", + "type: None, database: 6\n", + "--- MBQL query ---\n", + "null\n", + "\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "=== card 7751: SO↔NAV — Revenue semanal web por canal ===\n", + "type: None, database: 6\n", + "--- MBQL query ---\n", + "null\n", + "\n" + ] + } + ], + "source": [ + "import json as _json\n", + "# Leer la query de las cards del doc 2 (las 3)\n", + "for cid in [7749, 7750, 7751]:\n", + " c = client.request('GET', f'/api/card/{cid}')\n", + " dq = c.get('dataset_query') or {}\n", + " print(f'=== card {cid}: {c[\"name\"]} ===')\n", + " print(f'type: {dq.get(\"type\")}, database: {dq.get(\"database\")}')\n", + " native = dq.get('native') or {}\n", + " if native.get('query'):\n", + " print('--- NATIVE SQL ---')\n", + " print(native['query'][:3000])\n", + " else:\n", + " print('--- MBQL query ---')\n", + " print(_json.dumps(dq.get('query'), indent=2, default=str)[:2500])\n", + " print()" + ] + }, + { + "cell_type": "code", + "execution_count": 23, + "id": "103eb0ca", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "keys: ['cache_invalidated_at', 'description', 'archived', 'view_count', 'collection_position', 'source_card_id', 'table_id', 'can_run_adhoc_query', 'result_metadata', 'embedding_type', 'dependency_analysis_version', 'creator', 'initially_published_at', 'can_write', 'card_schema', 'database_id', 'enable_embedding', 'collection_id', 'query_type', 'name', 'last_query_start', 'is_remote_synced', 'dashboard_count', 'document_id', 'last_used_at', 'dashboard', 'type', 'average_query_time', 'creator_id', 'can_restore', 'moderation_reviews', 'updated_at', 'made_public_by_id', 'embedding_params', 'cache_ttl', 'dataset_query', 'id', 'legacy_query', 'parameter_mappings', 'can_manage_db', 'display', 'archived_directly', 'entity_id', 'collection_preview', 'last-edit-info', 'visualization_settings', 'collection', 'metabase_version', 'parameters', 'dashboard_id', 'created_at', 'parameter_usage_count', 'public_uuid', 'can_delete']\n", + "\n", + "dataset_query keys: ['lib/type', 'database', 'stages']\n", + "\n", + "{\n", + " \"lib/type\": \"mbql/query\",\n", + " \"database\": 6,\n", + " \"stages\": [\n", + " {\n", + " \"lib/type\": \"mbql.stage/native\",\n", + " \"native\": \"\\nWITH supply_full AS (\\n SELECT \\n so.id as supply_order_id,\\n so.service_request_id,\\n so.product_id,\\n so.quantity,\\n so.sale_price,\\n so.purchase_price,\\n so.status as so_status,\\n so.supply_method,\\n so.shipped,\\n so.created_at as so_created_at,\\n CASE \\n WHEN so.service_request_id IS NOT NULL THEN 'Web'\\n WHEN so.tpv_orders_order_id IS NOT NULL THEN 'Centro'\\n ELSE 'Sin origen'\\n END as origen,\\n ch.name as canal_nombre,\\n sr.shipping_method,\\n COALESCE(so.tpv_orders_order_id, pj.order_id, inv_lo.order_id) as order_id,\\n COALESCE(inv_direct.nav_id, inv_precaweb.nav_id, lo.invoice_number) as factura_nav,\\n p.description as producto,\\n COALESCE(SPLIT(ec.h_path, '#')[SAFE_OFFSET(0)], '(sin cat)') as familia_ecom,\\n COALESCE(SPLIT(ec.h_path, '#')[SAFE_OFFSET(1)], '') as subfamilia_ecom,\\n ec.name as ecom_cat_leaf,\\n sih.posting_date as fecha_factura,\\n sih.location_code as centro_nav,\\n sih.payment_method_code as metodo_pago\\n FROM `autingo-159109.psql_dcpublic.supply_orders` so\\n LEFT JOIN `autingo-159109.psql_dcpublic.service_requests` sr ON so.service_request_id = sr.id\\n LEFT JOIN `autingo-159109.psql_dcpublic.channels` ch ON sr.channel_id = ch.id\\n LEFT JOIN `autingo-159109.psql_dcpublic.tpv_precawebs_servicerequestjob` pj\\n ON CAST(so.service_request_id AS STRING) = pj.service_request_id\\n LEFT JOIN `autingo-159109.psql_dcpublic.tpv_orders_invoice` inv_direct\\n ON so.tpv_orders_order_id = inv_direct.order_id\\n LEFT JOIN `autingo-159109.psql_dcpublic.tpv_orders_invoice` inv_precaweb\\n ON pj.order_id = inv_precaweb.order_id AND so.tpv_orders_order_id IS NULL\\n LEFT JOIN `autingo-159109.psql_dcpublic.logistic_orders` lo ON so.logistic_order_id = lo.id\\n LEFT JOIN `autingo-159109.psql_dcpublic.tpv_orders_invoice` inv_lo\\n ON lo.invoice_number = inv_lo.nav_id AND so.tpv_orders_order_id IS NULL AND pj.order_id IS NULL\\n LEFT JOIN `autingo-159109.psql_dcpublic.products` p ON so.product_id = p.id\\n LEFT JOIN `autingo-159109.psql_dcpublic.ecommerce_categories` ec ON p.ecommerce_category_id = ec.id\\n LEFT JOIN `autingo-159109.mssql2022_dbo.anjana_sales_invoice_header` sih \\n ON COALESCE(inv_direct.nav_id, inv_precaweb.nav_id, lo.invoice_number) = sih.no_ \\n AND sih._fivetran_deleted = FALSE\\n WHERE so.created_at >= '2025-01-01'\\n)\\n\\nSELECT \\n COALESCE(canal_nombre, '(centro directo)') as canal,\\n origen,\\n COUNT(DISTINCT supply_order_id) as supply_orders,\\n COUNT(DISTINCT CASE WHEN factura_nav IS NOT NULL THEN supply_order_id END) as con_factura,\\n ROUND(COUNT(DISTINCT CASE WHEN factura_nav IS NOT NULL THEN supply_order_id END) * 100.0 \\n / NULLIF(COUNT(DISTINCT supply_order_id), 0), 1) as pct_trazable,\\n COUNT(DISTINCT order_id) as orders_tpv,\\n ROUND(SUM(sale_price * quantity), 0) as revenue_so,\\n ROUND(SUM(sale_price * quantity) - SUM(purchase_price * quantity), 0) as margen_so,\\n ROUND((SUM(sale_price * quantity) - SUM(purchase_price * quantity)) * 100.0 \\n / NULLIF(SUM(sale_price * quantity), 0), 1) as pct_margen\\nFROM supply_full\\nGROUP BY 1, 2\\nORDER BY supply_orders DESC\\n\"\n", + " }\n", + " ]\n", + "}\n" + ] + } + ], + "source": [ + "import json as _json\n", + "c = client.request('GET', '/api/card/7750')\n", + "# dump todos los keys\n", + "print('keys:', list(c.keys()))\n", + "print()\n", + "print('dataset_query keys:', list(c.get('dataset_query',{}).keys()))\n", + "print()\n", + "# Probar version v2 formato stages\n", + "print(_json.dumps(c.get('dataset_query'), indent=2, default=str)[:4000])" + ] + }, + { + "cell_type": "code", + "execution_count": 24, + "id": "416349bf", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "=== VENTA WEB 2025 POR CANAL (Supply Orders → NAV) ===\n", + " canal supply_orders con_factura facturas_distintas revenue_so revenue_trazable\n", + " aurgi.com 72843 71219 62651 17,606,179.00 17,016,564.00\n", + " Amazon 58134 58116 55152 3,243,771.00 3,241,920.00\n", + " Aliexpress 36994 36974 35398 1,181,809.00 1,181,423.00\n", + " autingo.es 11398 11358 10553 1,940,942.00 1,936,293.00\n", + " Miravia 10495 10487 10000 918,512.00 918,112.00\n", + "Eci Marketplace 1207 1207 1152 91,211.00 91,211.00\n", + " motortown.es 1150 1031 1355 1,137,556.00 1,034,280.00\n", + " Tiktok Shop 23 23 19 349.00 349.00\n", + " Centros Aurgi 7 7 7 426,266.00 426,266.00\n" + ] + } + ], + "source": [ + "# Revenue y conteo facturas por canal (Web solo) — 2025, usando la logica del doc 2\n", + "sql_canal = '''\n", + "WITH so_web AS (\n", + " SELECT\n", + " so.id,\n", + " so.service_request_id,\n", + " so.quantity,\n", + " so.sale_price,\n", + " so.created_at,\n", + " ch.name AS canal,\n", + " COALESCE(inv_direct.nav_id, inv_precaweb.nav_id, lo.invoice_number) AS factura_nav\n", + " FROM `autingo-159109.psql_dcpublic.supply_orders` so\n", + " LEFT JOIN `autingo-159109.psql_dcpublic.service_requests` sr ON so.service_request_id = sr.id\n", + " LEFT JOIN `autingo-159109.psql_dcpublic.channels` ch ON sr.channel_id = ch.id\n", + " LEFT JOIN `autingo-159109.psql_dcpublic.tpv_precawebs_servicerequestjob` pj\n", + " ON CAST(so.service_request_id AS STRING) = pj.service_request_id\n", + " LEFT JOIN `autingo-159109.psql_dcpublic.tpv_orders_invoice` inv_direct\n", + " ON so.tpv_orders_order_id = inv_direct.order_id\n", + " LEFT JOIN `autingo-159109.psql_dcpublic.tpv_orders_invoice` inv_precaweb\n", + " ON pj.order_id = inv_precaweb.order_id AND so.tpv_orders_order_id IS NULL\n", + " LEFT JOIN `autingo-159109.psql_dcpublic.logistic_orders` lo ON so.logistic_order_id = lo.id\n", + " WHERE so.service_request_id IS NOT NULL\n", + " AND EXTRACT(YEAR FROM so.created_at) = 2025\n", + ")\n", + "SELECT\n", + " COALESCE(canal, '(sin canal)') AS canal,\n", + " COUNT(DISTINCT id) AS supply_orders,\n", + " COUNT(DISTINCT CASE WHEN factura_nav IS NOT NULL THEN id END) AS con_factura,\n", + " COUNT(DISTINCT factura_nav) AS facturas_distintas,\n", + " ROUND(SUM(sale_price * quantity), 0) AS revenue_so,\n", + " ROUND(SUM(CASE WHEN factura_nav IS NOT NULL THEN sale_price * quantity END), 0) AS revenue_trazable\n", + "FROM so_web\n", + "GROUP BY canal\n", + "ORDER BY supply_orders DESC\n", + "'''\n", + "df_canal = run_sql(sql_canal)\n", + "print('=== VENTA WEB 2025 POR CANAL (Supply Orders → NAV) ===')\n", + "print(df_canal.to_string(index=False))" + ] + }, + { + "cell_type": "code", + "execution_count": 26, + "id": "b0e0660c", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "=== REVENUE POR MES Y CANAL (Supply Orders web 2025) ===\n", + "canal Aliexpress Amazon Centros Aurgi Eci Marketplace Miravia Tiktok Shop aurgi.com autingo.es motortown.es\n", + "mes \n", + "2025-01 68,343.00 166,947.00 0.00 20,871.00 76,124.00 0.00 2,245,281.00 115,703.00 60,239.00\n", + "2025-02 33,095.00 183,390.00 0.00 6,074.00 60,312.00 0.00 699,809.00 124,178.00 70,430.00\n", + "2025-03 50,465.00 276,958.00 0.00 6,054.00 80,987.00 0.00 929,023.00 111,122.00 101,507.00\n", + "2025-04 38,748.00 257,065.00 3,996.00 5,452.00 73,302.00 0.00 863,487.00 86,919.00 97,587.00\n", + "2025-05 98,737.00 429,018.00 23,148.00 4,016.00 92,269.00 0.00 819,083.00 220,599.00 65,286.00\n", + "2025-06 140,292.00 563,030.00 0.00 5,074.00 127,968.00 0.00 1,128,153.00 304,014.00 101,676.00\n", + "2025-07 197,834.00 420,412.00 27,900.00 5,153.00 99,631.00 0.00 2,410,787.00 285,622.00 146,945.00\n", + "2025-08 217,799.00 248,708.00 0.00 5,319.00 70,978.00 11.00 1,856,374.00 229,094.00 162,288.00\n", + "2025-09 120,499.00 285,104.00 759.00 4,600.00 98,794.00 157.00 1,097,121.00 144,585.00 91,482.00\n", + "2025-10 91,763.00 168,277.00 0.00 8,131.00 73,901.00 145.00 947,802.00 139,971.00 67,643.00\n", + "2025-11 101,533.00 170,078.00 0.00 7,662.00 49,572.00 36.00 940,761.00 75,873.00 74,999.00\n", + "2025-12 22,701.00 74,784.00 370,463.00 12,806.00 14,673.00 0.00 3,668,497.00 103,262.00 97,473.00\n", + "\n", + "=== FACTURAS DISTINTAS POR MES Y CANAL ===\n", + "canal Aliexpress Amazon Centros Aurgi Eci Marketplace Miravia Tiktok Shop aurgi.com autingo.es motortown.es\n", + "mes \n", + "2025-01 2,112.00 3,312.00 0.00 270.00 852.00 0.00 1,941.00 743.00 72.00\n", + "2025-02 1,415.00 3,517.00 0.00 93.00 794.00 0.00 2,059.00 614.00 73.00\n", + "2025-03 1,935.00 6,965.00 0.00 84.00 1,072.00 0.00 2,508.00 980.00 91.00\n", + "2025-04 1,249.00 6,000.00 1.00 60.00 994.00 0.00 2,569.00 691.00 94.00\n", + "2025-05 3,813.00 8,109.00 1.00 65.00 1,029.00 0.00 3,061.00 968.00 89.00\n", + "2025-06 3,672.00 8,359.00 0.00 68.00 1,331.00 0.00 4,564.00 1,296.00 186.00\n", + "2025-07 6,057.00 5,856.00 1.00 62.00 1,097.00 0.00 6,627.00 1,552.00 207.00\n", + "2025-08 6,219.00 4,781.00 0.00 70.00 801.00 1.00 5,338.00 1,237.00 207.00\n", + "2025-09 3,974.00 5,359.00 1.00 58.00 867.00 8.00 2,799.00 884.00 97.00\n", + "2025-10 2,769.00 2,301.00 0.00 77.00 616.00 7.00 2,629.00 864.00 67.00\n", + "2025-11 2,569.00 2,279.00 0.00 97.00 466.00 3.00 2,177.00 447.00 89.00\n", + "2025-12 635.00 872.00 3.00 150.00 157.00 0.00 29,681.00 379.00 83.00\n" + ] + } + ], + "source": [ + "# Evolucion mensual 2025 por CANAL para las 3 fuentes en paralelo (solo revenue y facturas)\n", + "sql_mensual_canal = '''\n", + "WITH so_web AS (\n", + " SELECT\n", + " so.id,\n", + " FORMAT_DATE('%Y-%m', so.created_at) AS mes,\n", + " ch.name AS canal,\n", + " so.sale_price * so.quantity AS revenue,\n", + " COALESCE(inv_direct.nav_id, inv_precaweb.nav_id, lo.invoice_number) AS factura_nav\n", + " FROM `autingo-159109.psql_dcpublic.supply_orders` so\n", + " LEFT JOIN `autingo-159109.psql_dcpublic.service_requests` sr ON so.service_request_id = sr.id\n", + " LEFT JOIN `autingo-159109.psql_dcpublic.channels` ch ON sr.channel_id = ch.id\n", + " LEFT JOIN `autingo-159109.psql_dcpublic.tpv_precawebs_servicerequestjob` pj\n", + " ON CAST(so.service_request_id AS STRING) = pj.service_request_id\n", + " LEFT JOIN `autingo-159109.psql_dcpublic.tpv_orders_invoice` inv_direct\n", + " ON so.tpv_orders_order_id = inv_direct.order_id\n", + " LEFT JOIN `autingo-159109.psql_dcpublic.tpv_orders_invoice` inv_precaweb\n", + " ON pj.order_id = inv_precaweb.order_id AND so.tpv_orders_order_id IS NULL\n", + " LEFT JOIN `autingo-159109.psql_dcpublic.logistic_orders` lo ON so.logistic_order_id = lo.id\n", + " WHERE so.service_request_id IS NOT NULL\n", + " AND EXTRACT(YEAR FROM so.created_at) = 2025\n", + ")\n", + "SELECT\n", + " mes,\n", + " COALESCE(canal, '(sin canal)') AS canal,\n", + " COUNT(DISTINCT id) AS supply_orders,\n", + " COUNT(DISTINCT factura_nav) AS facturas,\n", + " ROUND(SUM(revenue), 0) AS revenue\n", + "FROM so_web\n", + "GROUP BY mes, canal\n", + "ORDER BY mes, revenue DESC\n", + "'''\n", + "df_mensual_canal = run_sql(sql_mensual_canal)\n", + "\n", + "# Pivot por canal -> mes\n", + "pivot_rev = df_mensual_canal.pivot_table(index='mes', columns='canal', values='revenue', aggfunc='sum').fillna(0)\n", + "pivot_fact = df_mensual_canal.pivot_table(index='mes', columns='canal', values='facturas', aggfunc='sum').fillna(0)\n", + "\n", + "print('=== REVENUE POR MES Y CANAL (Supply Orders web 2025) ===')\n", + "print(pivot_rev.to_string())\n", + "print()\n", + "print('=== FACTURAS DISTINTAS POR MES Y CANAL ===')\n", + "print(pivot_fact.to_string())" + ] + }, + { + "cell_type": "markdown", + "id": "d0617844", + "metadata": {}, + "source": [ + "## 10. Por qué discrepan las fuentes — explicación y resumen\n", + "\n", + "### Totales 2025 reproducidos\n", + "\n", + "| Fuente | Revenue | Nº registros | Lógica aplicada |\n", + "|---|---|---|---|\n", + "| **Cubo_Ventas_Calculado** (WSWEB, Venta) | **5.879.313 €** | 158.617 líneas | `Dim_NombreDimGlobal2='WSWEB' AND Dim_NombreTipoMov='Venta'` |\n", + "| **NAV directo** (centros digitales) | **15.872.266 €** | 315.831 líneas / ~295K facturas | `location_code IN ('18','19','405','421','422')` |\n", + "| **Supply Orders → NAV** (web, por canal) | **26.499.895 €** | 192.251 SOs / 190K con factura | `service_request_id IS NOT NULL` con `sale_price*quantity` |\n", + "\n", + "### ¿Por qué 3 cifras tan distintas?\n", + "\n", + "Las tres miden **cosas distintas aunque suenen igual**:\n", + "\n", + "1. **Cubo (5.88M€) — \"compañía comercial WSWEB\"**\n", + " - Es un datamart pre-agregado que solo cuenta líneas cuya **dimensión comercial = WSWEB**\n", + " - Excluye implícitamente devoluciones, ajustes de stock, tickets intraempresa, abonos\n", + " - Solo tipo_mov = \"Venta\"\n", + " - Los centros físicos (18/19/405/421/422) aparecen aquí, pero solo por la fracción de su actividad que se imputa a la compañía WSWEB\n", + "\n", + "2. **NAV directo (15.87M€) — \"facturación bruta del almacén\"**\n", + " - Todo lo facturado en los almacenes con location_code digital: ventas a cliente final + tickets intraempresa + facturas de servicios + recargos + ajustes\n", + " - tipo_de_registro_tpv=4 (ticket TPV) domina con 306K facturas\n", + " - **2.7× el Cubo** porque incluye todo lo que sale del almacén, no solo la venta online limpia\n", + "\n", + "3. **Supply Orders (26.50M€) — \"pedidos web por canal\"**\n", + " - Todo pedido web (service_request_id ≠ NULL) independientemente del centro que lo facture\n", + " - **Incluye canales NO digital-center**: Amazon 3.24M€, Aliexpress 1.18M€, Miravia 918K€ → se facturan a centros/compañías distintas que no están en (18/19/405/421/422)\n", + " - Por eso es mayor que NAV directo\n", + "\n", + "### Diciembre tiene anomalías importantes\n", + "\n", + "- **aurgi.com diciembre**: 3.67M€ y 29.681 facturas (vs media ~2-3K facturas/mes) → 10× la media\n", + "- **Aurgi Asociados Gruas (421) diciembre en NAV**: 55.138 facturas por 2.97M€ en UN solo mes (todo el resto del año: ~150 facturas total)\n", + "- **Centros Aurgi (canal)**: 370K€ concentrado en diciembre\n", + "\n", + "Investigar: ¿cierre fiscal? ¿reemisión masiva? ¿cambio lógica canal?\n", + "\n", + "### Desglose canal digital 2025\n", + "\n", + "| Canal | Supply Orders | Revenue SO | % trazable a NAV |\n", + "|---|---|---|---|\n", + "| aurgi.com | 72.843 | 17.6M€ | 97.8% |\n", + "| Amazon | 58.134 | 3.24M€ | 99.97% |\n", + "| Aliexpress | 36.994 | 1.18M€ | 99.95% |\n", + "| autingo.es | 11.398 | 1.94M€ | 99.6% |\n", + "| Miravia | 10.495 | 918K€ | 99.9% |\n", + "| motortown.es | 1.150 | 1.14M€ | 89.7% |\n", + "| Eci Marketplace | 1.207 | 91K€ | 100% |\n", + "| Centros Aurgi | 7 | 426K€ | 100% |\n", + "| Tiktok Shop | 23 | 349€ | 100% |\n", + "\n", + "### Recomendación de uso\n", + "\n", + "- **Cubo_Ventas_Calculado (WSWEB, Venta)** → reporting financiero interno \"venta online\" en sentido estricto\n", + "- **NAV directo (location_code digital)** → auditoría contable, cierre fiscal\n", + "- **Supply Orders por canal** → operativa web, KPIs por marketplace, conciliación ventas-envíos" + ] + }, + { + "cell_type": "code", + "execution_count": 27, + "id": "7f2ef633", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "=== TOP 20 productos aurgi.com DICIEMBRE 2025 ===\n", + " producto supply_orders unidades revenue precio_medio\n", + " BALIZA V16 GEOLOC Mirovi RET 27706 41,293.00 2,803,090.00 52.09\n", + " REVISION PLUS TURISMO 61 61.00 10,020.00 164.26\n", + " CUB EP 235/60 R18 107V K125A V 6 20.00 9,845.00 453.52\n", + " REVISION TODO INCLUIDO TURISMO 45 45.00 9,221.00 204.91\n", + " CUB 205/55 R16 91V K135 VEN 10 28.00 9,103.00 288.60\n", + " CUB 205/55 R16 91V SECURADRIVE 22 54.00 9,080.00 149.98\n", + " CUB EN 205/50 R17 93W K135 VEN 9 23.00 7,577.00 280.47\n", + " CUB 205/55 R16 91V TUR6 8 22.00 7,154.00 294.15\n", + " CUB 225/45 R17 91Y K135 VEN 10 26.00 7,045.00 236.31\n", + " CUB 225/45 R17 94Y POWERGY 11 26.00 6,939.00 242.31\n", + "Baliza V16 IoT Alert Wise con geolocalización MIROVI Compatible DGT 3.0 y Conectividad telefónica tech 75 107.00 6,723.00 51.29\n", + " CUB 205/55 R16 91V RP062 20 44.00 6,235.00 132.68\n", + " CUB EN 235/55 R19 105W SCO AS 3 10.00 6,233.00 572.90\n", + " CAMBIO DE ACEITE MO Y FILTRO ACEITE TURISMO 84 84.00 5,921.00 70.49\n", + " REVISION TODO INCLUIDO 4X4/FU/MONOV 24 24.00 5,668.00 236.18\n", + " CUB EP 195/65 R15 91V 4E H750 6 18.00 5,206.00 258.40\n", + " CUB EP 195/55 R16 91V 4E CEAT 8 24.00 5,206.00 204.42\n", + " CUB EP 215/50 R18 92W PWRGY 2 8.00 5,139.00 642.39\n", + " CUB EP 225/50 R18 99Y K127 VEN 4 12.00 5,119.00 383.91\n", + " REVISION AHORRO TURISMO 41 41.00 4,977.00 121.38\n" + ] + } + ], + "source": [ + "# Hipotesis: pico aurgi.com diciembre 2025 = balizas V16 (ley obligatoria ene 2026)\n", + "# Ver top productos vendidos en aurgi.com en diciembre 2025\n", + "sql_dic_top = '''\n", + "SELECT\n", + " p.description AS producto,\n", + " COUNT(DISTINCT so.id) AS supply_orders,\n", + " SUM(so.quantity) AS unidades,\n", + " ROUND(SUM(so.sale_price * so.quantity), 0) AS revenue,\n", + " ROUND(AVG(so.sale_price), 2) AS precio_medio\n", + "FROM `autingo-159109.psql_dcpublic.supply_orders` so\n", + "LEFT JOIN `autingo-159109.psql_dcpublic.service_requests` sr ON so.service_request_id = sr.id\n", + "LEFT JOIN `autingo-159109.psql_dcpublic.channels` ch ON sr.channel_id = ch.id\n", + "LEFT JOIN `autingo-159109.psql_dcpublic.products` p ON so.product_id = p.id\n", + "WHERE so.service_request_id IS NOT NULL\n", + " AND ch.name = 'aurgi.com'\n", + " AND EXTRACT(YEAR FROM so.created_at) = 2025\n", + " AND EXTRACT(MONTH FROM so.created_at) = 12\n", + "GROUP BY p.description\n", + "ORDER BY revenue DESC\n", + "LIMIT 20\n", + "'''\n", + "df_dic_top = run_sql(sql_dic_top)\n", + "print('=== TOP 20 productos aurgi.com DICIEMBRE 2025 ===')\n", + "print(df_dic_top.to_string(index=False))" + ] + }, + { + "cell_type": "code", + "execution_count": 28, + "id": "f3e4daf7", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "=== Pico aurgi.com DIC 2025: balizas vs resto ===\n", + " categoria supply_orders unidades revenue\n", + " Balizas V16 27793 41,414.00 2,810,591.00\n", + "Resto productos 2865 4,191.00 705,417.00\n", + "\n", + "Balizas V16 = 79.9% del revenue aurgi.com diciembre 2025\n" + ] + } + ], + "source": [ + "# Desglose del pico diciembre: balizas vs resto\n", + "sql_dic_balizas = '''\n", + "SELECT\n", + " CASE \n", + " WHEN UPPER(p.description) LIKE '%BALIZA%' OR UPPER(p.description) LIKE '%V16%' THEN 'Balizas V16'\n", + " ELSE 'Resto productos'\n", + " END AS categoria,\n", + " COUNT(DISTINCT so.id) AS supply_orders,\n", + " SUM(so.quantity) AS unidades,\n", + " ROUND(SUM(so.sale_price * so.quantity), 0) AS revenue\n", + "FROM `autingo-159109.psql_dcpublic.supply_orders` so\n", + "LEFT JOIN `autingo-159109.psql_dcpublic.service_requests` sr ON so.service_request_id = sr.id\n", + "LEFT JOIN `autingo-159109.psql_dcpublic.channels` ch ON sr.channel_id = ch.id\n", + "LEFT JOIN `autingo-159109.psql_dcpublic.products` p ON so.product_id = p.id\n", + "WHERE so.service_request_id IS NOT NULL\n", + " AND ch.name = 'aurgi.com'\n", + " AND EXTRACT(YEAR FROM so.created_at) = 2025\n", + " AND EXTRACT(MONTH FROM so.created_at) = 12\n", + "GROUP BY categoria\n", + "ORDER BY revenue DESC\n", + "'''\n", + "df_bal = run_sql(sql_dic_balizas)\n", + "print('=== Pico aurgi.com DIC 2025: balizas vs resto ===')\n", + "print(df_bal.to_string(index=False))\n", + "total = df_bal['revenue'].sum()\n", + "pct_bal = df_bal.loc[df_bal['categoria']=='Balizas V16','revenue'].iloc[0] / total * 100\n", + "print(f'\\nBalizas V16 = {pct_bal:.1f}% del revenue aurgi.com diciembre 2025')" + ] + }, + { + "cell_type": "code", + "execution_count": 29, + "id": "e4d54fc1", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "=== 2025 venta web: por canal y destino de cumplimentacion ===\n", + " canal destino supply_orders facturas revenue locations_nav_distintos\n", + " Aliexpress 1) Centro digital (web puro) 36994 35398 1,181,809.00 4\n", + " Amazon 1) Centro digital (web puro) 58122 55149 3,242,247.00 4\n", + " Amazon 3) Sin centro asignado 12 5 1,524.00 1\n", + " Centros Aurgi 1) Centro digital (web puro) 7 7 426,266.00 3\n", + "Eci Marketplace 1) Centro digital (web puro) 1207 1152 91,211.00 4\n", + " Miravia 1) Centro digital (web puro) 10490 10000 918,172.00 4\n", + " Miravia 3) Sin centro asignado 5 0 340.00 0\n", + " Tiktok Shop 1) Centro digital (web puro) 23 19 349.00 3\n", + " aurgi.com 1) Centro digital (web puro) 37144 35349 5,024,463.00 58\n", + " aurgi.com 2) Centro fisico (C&C/envio tienda) 35671 30210 12,579,111.00 66\n", + " aurgi.com 3) Sin centro asignado 28 15 2,605.00 7\n", + " autingo.es 1) Centro digital (web puro) 11398 10553 1,940,942.00 4\n", + " motortown.es 2) Centro fisico (C&C/envio tienda) 1150 1355 1,137,556.00 48\n" + ] + } + ], + "source": [ + "# Trazabilidad completa: SO -> NAV para venta que va a CENTRO (C&C + envio tienda)\n", + "# Vamos a desglosar 2025 por \"destino final\"\n", + "\n", + "sql_destino = '''\n", + "WITH so_web AS (\n", + " SELECT\n", + " so.id,\n", + " so.service_request_id,\n", + " so.quantity,\n", + " so.sale_price,\n", + " so.created_at,\n", + " ch.name AS canal,\n", + " ce.name AS centro_fisico,\n", + " ce.nav_id AS nav_id_centro,\n", + " ce.is_digital,\n", + " sr.shipping_method AS shipping_method_sr,\n", + " lo.center_id AS logistic_center_id,\n", + " COALESCE(inv_direct.nav_id, inv_precaweb.nav_id, lo.invoice_number) AS factura_nav,\n", + " sih.location_code AS nav_location\n", + " FROM `autingo-159109.psql_dcpublic.supply_orders` so\n", + " LEFT JOIN `autingo-159109.psql_dcpublic.service_requests` sr ON so.service_request_id = sr.id\n", + " LEFT JOIN `autingo-159109.psql_dcpublic.channels` ch ON sr.channel_id = ch.id\n", + " LEFT JOIN `autingo-159109.psql_dcpublic.logistic_orders` lo ON so.logistic_order_id = lo.id\n", + " LEFT JOIN `autingo-159109.psql_dcpublic.centers` ce ON lo.center_id = ce.id\n", + " LEFT JOIN `autingo-159109.psql_dcpublic.tpv_precawebs_servicerequestjob` pj\n", + " ON CAST(so.service_request_id AS STRING) = pj.service_request_id\n", + " LEFT JOIN `autingo-159109.psql_dcpublic.tpv_orders_invoice` inv_direct\n", + " ON so.tpv_orders_order_id = inv_direct.order_id\n", + " LEFT JOIN `autingo-159109.psql_dcpublic.tpv_orders_invoice` inv_precaweb\n", + " ON pj.order_id = inv_precaweb.order_id AND so.tpv_orders_order_id IS NULL\n", + " LEFT JOIN `autingo-159109.mssql2022_dbo.anjana_sales_invoice_header` sih\n", + " ON COALESCE(inv_direct.nav_id, inv_precaweb.nav_id, lo.invoice_number) = sih.no_\n", + " AND sih._fivetran_deleted = FALSE\n", + " WHERE so.service_request_id IS NOT NULL\n", + " AND EXTRACT(YEAR FROM so.created_at) = 2025\n", + ")\n", + "SELECT\n", + " canal,\n", + " CASE\n", + " WHEN is_digital = TRUE THEN '1) Centro digital (web puro)'\n", + " WHEN is_digital = FALSE THEN '2) Centro fisico (C&C/envio tienda)'\n", + " WHEN centro_fisico IS NULL THEN '3) Sin centro asignado'\n", + " ELSE '4) Otro'\n", + " END AS destino,\n", + " COUNT(DISTINCT id) AS supply_orders,\n", + " COUNT(DISTINCT factura_nav) AS facturas,\n", + " ROUND(SUM(sale_price * quantity), 0) AS revenue,\n", + " COUNT(DISTINCT nav_location) AS locations_nav_distintos\n", + "FROM so_web\n", + "GROUP BY canal, destino\n", + "ORDER BY canal, destino\n", + "'''\n", + "df_dest = run_sql(sql_destino)\n", + "print('=== 2025 venta web: por canal y destino de cumplimentacion ===')\n", + "print(df_dest.to_string(index=False))" + ] + }, + { + "cell_type": "markdown", + "id": "0061c6c1", + "metadata": {}, + "source": [ + "## 11. Verificación balizas V16 — CONFIRMADO\n", + "\n", + "El pico aurgi.com diciembre (3.67M€, 29.681 facturas) es **80% balizas V16**:\n", + "\n", + "| Categoría | Supply Orders | Unidades | Revenue |\n", + "|---|---:|---:|---:|\n", + "| **Balizas V16** | 27.793 | 41.414 | **2.810.591 €** |\n", + "| Resto productos | 2.865 | 4.191 | 705.417 € |\n", + "\n", + "Todo por la **ley DGT de balizas V16 obligatoria desde 1 enero 2026** (sustituye triángulos de emergencia). Producto principal: **BALIZA V16 GEOLOC Mirovi RET** (52€ unidad, 41.293 unidades en un mes).\n", + "\n", + "## 12. La arquitectura real — dónde sacar cada dato\n", + "\n", + "### 12.1 Hallazgo clave: la venta web no va toda a centros digitales\n", + "\n", + "Cuando se desglosa por **destino de cumplimentación** (via `supply_orders.logistic_order_id → logistic_orders.center_id → centers`):\n", + "\n", + "| Canal | A centro digital (web puro) | A centro físico (C&C/envío tienda) | Sin centro |\n", + "|---|---:|---:|---:|\n", + "| aurgi.com | 5.02M€ (29%) | **12.58M€ (71%)** | 3K€ |\n", + "| motortown.es | 0 | 1.14M€ (100%) | 0 |\n", + "| Amazon | 3.24M€ (100%) | 0 | 2K€ |\n", + "| Aliexpress | 1.18M€ (100%) | 0 | 0 |\n", + "| autingo.es | 1.94M€ (100%) | 0 | 0 |\n", + "| Miravia | 918K€ (100%) | 0 | 0 |\n", + "\n", + "**Por eso NAV filtrado por location digital (5.02+3.24+1.18+1.94+0.92+…=13.5M€) queda lejos del total de supply_orders web (26.5M€)**: falta todo el C&C de aurgi.com que se factura en 66 locations físicas distintas.\n", + "\n", + "### 12.2 Tabla de verdad según pregunta\n", + "\n", + "| Pregunta de negocio | Fuente canónica | Filtro clave |\n", + "|---|---|---|\n", + "| ¿Cuánto vendí por canal online? | `psql_dcpublic.supply_orders` + join con `channels` | `service_request_id IS NOT NULL` |\n", + "| ¿Qué facturó fiscalmente cada almacén? | `mssql2022_dbo.anjana_sales_invoice_header/line` | `location_code` específico |\n", + "| ¿Cuál es el KPI comercial \"venta online\" estricto? | `anjana_bi_datamart.Cubo_Ventas_Calculado` | `Dim_NombreDimGlobal2='WSWEB' AND Dim_NombreTipoMov='Venta'` |\n", + "| ¿Un pedido web llegó a facturarse? | Cadena `supply_orders → tpv_orders_invoice → NAV` | factura_nav IS NOT NULL |\n", + "| ¿A qué tienda fue el C&C? | `logistic_orders.center_id → centers.nav_id` | `is_digital=FALSE` |\n", + "\n", + "### 12.3 Propuesta: vista canónica `v_venta_web_unificada`\n", + "\n", + "Una **view materializada en BigQuery** que consolide todo:\n", + "\n", + "```sql\n", + "CREATE OR REPLACE VIEW `autingo-159109.anjana_bi_datamart.v_venta_web_unificada` AS\n", + "SELECT\n", + " so.id AS supply_order_id,\n", + " so.created_at AS fecha_pedido,\n", + " ch.name AS canal,\n", + " ch.company_id AS company_id,\n", + " so.product_id,\n", + " p.description AS producto,\n", + " so.quantity,\n", + " so.sale_price,\n", + " so.sale_price * so.quantity AS revenue,\n", + " so.purchase_price,\n", + " (so.sale_price - so.purchase_price) * so.quantity AS margen,\n", + " ce.id AS centro_id,\n", + " ce.name AS centro_nombre,\n", + " ce.nav_id AS centro_nav_id,\n", + " ce.is_digital AS centro_es_digital,\n", + " CASE\n", + " WHEN ce.is_digital THEN 'entrega_web'\n", + " WHEN ce.is_digital = FALSE THEN 'click_and_collect'\n", + " ELSE 'sin_centro'\n", + " END AS modo_cumplimentacion,\n", + " sr.shipping_method AS shipping_method,\n", + " COALESCE(inv_direct.nav_id, inv_precaweb.nav_id, lo.invoice_number) AS factura_nav,\n", + " sih.posting_date AS fecha_factura_nav,\n", + " sih.location_code AS nav_location_code,\n", + " sih.amount_including_vat AS importe_factura_nav\n", + "FROM `autingo-159109.psql_dcpublic.supply_orders` so\n", + "LEFT JOIN `autingo-159109.psql_dcpublic.service_requests` sr ON so.service_request_id = sr.id\n", + "LEFT JOIN `autingo-159109.psql_dcpublic.channels` ch ON sr.channel_id = ch.id\n", + "LEFT JOIN `autingo-159109.psql_dcpublic.logistic_orders` lo ON so.logistic_order_id = lo.id\n", + "LEFT JOIN `autingo-159109.psql_dcpublic.centers` ce ON lo.center_id = ce.id\n", + "LEFT JOIN `autingo-159109.psql_dcpublic.products` p ON so.product_id = p.id\n", + "LEFT JOIN `autingo-159109.psql_dcpublic.tpv_precawebs_servicerequestjob` pj\n", + " ON CAST(so.service_request_id AS STRING) = pj.service_request_id\n", + "LEFT JOIN `autingo-159109.psql_dcpublic.tpv_orders_invoice` inv_direct\n", + " ON so.tpv_orders_order_id = inv_direct.order_id\n", + "LEFT JOIN `autingo-159109.psql_dcpublic.tpv_orders_invoice` inv_precaweb\n", + " ON pj.order_id = inv_precaweb.order_id AND so.tpv_orders_order_id IS NULL\n", + "LEFT JOIN `autingo-159109.mssql2022_dbo.anjana_sales_invoice_header` sih\n", + " ON COALESCE(inv_direct.nav_id, inv_precaweb.nav_id, lo.invoice_number) = sih.no_\n", + " AND sih._fivetran_deleted = FALSE\n", + "WHERE so.service_request_id IS NOT NULL\n", + "```\n", + "\n", + "Con esta vista, un analista puede responder en **una sola query**:\n", + "- Ventas por canal, mes, producto\n", + "- Qué % se factura realmente (trazabilidad)\n", + "- Qué % se cumple en centro físico vs digital\n", + "- Cuánto factura cada centro NAV por canal web\n", + "\n", + "### 12.4 Alternativa en Metabase (sin tocar BigQuery)\n", + "\n", + "Si no se puede crear la view en BQ, se puede crear como **Modelo** en Metabase (type='model'):\n", + "\n", + "1. Nueva card tipo model con la SQL de arriba\n", + "2. Guardar en colección \"Models / Venta Web\"\n", + "3. Cualquier card/dashboard nuevo puede usar `source-table: card__` y tiene todas las columnas disponibles en modo point-and-click\n", + "\n", + "### 12.5 Seguimiento cuando la venta va a centro\n", + "\n", + "La trazabilidad completa es:\n", + "\n", + "```\n", + "supply_orders.service_request_id\n", + " ↓\n", + "service_requests.channel_id (qué canal)\n", + " ↓\n", + "supply_orders.logistic_order_id\n", + " ↓\n", + "logistic_orders.center_id (qué centro cumple)\n", + " ↓\n", + "centers.nav_id (código NAV del centro)\n", + " ↓\n", + "anjana_sales_invoice_header.location_code (factura NAV final)\n", + "```\n", + "\n", + "Clave: **el centro que cumplimenta NO tiene por qué ser digital**. Para el 71% de aurgi.com (C&C), el flujo es: pedido web → tienda física → factura en NAV con location del centro físico.\n", + "\n", + "### 12.6 Recomendación operativa\n", + "\n", + "1. **Materializar la view** `v_venta_web_unificada` en BigQuery → fuente única para todos los reportes de venta web\n", + "2. **Crear un Model en Metabase** basado en esa view → democratizar acceso sin SQL\n", + "3. **Dashboard nuevo** con 3 tabs: \"Por canal\", \"Por destino (web/centro)\", \"Trazabilidad factura NAV\"\n", + "4. **Deprecar filtros engañosos** del dashboard 734 que usan solo location_code (pierden el 71% del C&C)" + ] + }, + { + "cell_type": "code", + "execution_count": 30, + "id": "878d8a19", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Tablas tpv_* en psql_dcpublic: 61\n", + "\n", + " 1653 tpv_authorization_tpvclock\n", + " 1654 tpv_authorization_tpvuser\n", + " 1655 tpv_authorization_tpvuser_centers\n", + " 1657 tpv_authorization_tpvuser_groups\n", + " 1858 tpv_authorization_tpvuser_user_permissions\n", + " 1656 tpv_centers_shift\n", + " 4637 tpv_insurance_insuranceclaim_orders\n", + " 1532 tpv_orders_advancepayment\n", + " 1593 tpv_orders_advancepayment_returns_documents\n", + " 1531 tpv_orders_cashoperation\n", + " 1575 tpv_orders_collective\n", + " 1581 tpv_orders_collective_companies\n", + " 1554 tpv_orders_comparative\n", + " 1561 tpv_orders_exchange\n", + " 1585 tpv_orders_exchange_new_items\n", + " 1544 tpv_orders_exchange_to_exchange\n", + " 1549 tpv_orders_gtrequest\n", + " 1528 tpv_orders_invoice\n", + " 1559 tpv_orders_itemreplace\n", + " 1572 tpv_orders_note\n", + " 1548 tpv_orders_order\n", + " 1555 tpv_orders_orderitem\n", + " 1579 tpv_orders_orderitem_promos\n", + " 1558 tpv_orders_payment\n", + " 1526 tpv_orders_paymentauthorization\n", + " 1564 tpv_orders_paymentreturnrelation\n", + " 1547 tpv_orders_quote\n", + " 1578 tpv_orders_return\n", + " 1541 tpv_orders_returnadvancepaymentdocument\n", + " 1536 tpv_orders_returnreason\n", + " 1571 tpv_orders_return_to_exchange\n", + " 1587 tpv_orders_transactiondeleteuser\n", + " 1567 tpv_otrs_otr_orders\n", + " 1543 tpv_payment_types\n", + " 1782 tpv_payment_types_centers\n", + " 1591 tpv_payment_types_companies\n", + " 1552 tpv_terminals\n" + ] + } + ], + "source": [ + "# Buscar todas las tablas tpv_* en psql_dcpublic\n", + "tpv_tables = [t for t in db6['tables'] if t.get('schema') == 'psql_dcpublic' and t['name'].startswith('tpv_')]\n", + "print(f'Tablas tpv_* en psql_dcpublic: {len(tpv_tables)}')\n", + "print()\n", + "# Filtrar las mas relevantes para venta/terminal\n", + "relevant = [t for t in tpv_tables if any(k in t['name'].lower() for k in \n", + " ['order', 'sale', 'ticket', 'terminal', 'device', 'pos', 'idx', 'clock', 'user', 'center', 'sessio', 'pay', 'checkout', 'invoice', 'receipt'])]\n", + "for t in relevant[:40]:\n", + " print(f\" {t['id']:5} {t['name']}\")" + ] + }, + { + "cell_type": "code", + "execution_count": 32, + "id": "c371fefb", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "=== tpv_terminals (id 1552) — 20 cols ===\n", + " id [Integer]\n", + " name [Text]\n", + " created_at [DateTimeWithLocalTZ]\n", + " updated_at [DateTimeWithLocalTZ]\n", + " center_id [Integer]\n", + " inventory_terminal [Boolean]\n", + " status_open [Boolean]\n", + " status_shift [Integer]\n", + " status_description [Text]\n", + " status_open_amount [Decimal]\n", + " terminal_type_id [Integer]\n", + " visibility [Integer]\n", + " current_shift_id [Integer]\n", + " pending_products [Boolean]\n", + " datastream_metadata [Dictionary]\n", + " source_timestamp [Integer]\n", + " uuid [Text]\n", + " second_screen_active [Boolean]\n", + " customer_interaction_lock [Boolean]\n", + " assistant_screen_online [Boolean]\n", + "\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "=== tpv_orders_order (id 1548) — 58 cols ===\n", + " id [Integer]\n", + " created_at [DateTimeWithLocalTZ]\n", + " updated_at [DateTimeWithLocalTZ]\n", + " customer_id [Integer]\n", + " total_cost [Decimal]\n", + " total_cost_currency [Text]\n", + " calculate_payload [JSON]\n", + " terminal_id [Integer]\n", + " vehicle_id [Integer]\n", + " shift [Integer]\n", + " has_exchange [Boolean]\n", + " parent_id [Integer]\n", + " is_precaweb [Boolean]\n", + " calculate_uuid [Text]\n", + " has_service_request [Boolean]\n", + " collective_id [Integer]\n", + " execution_time [Integer]\n", + " shift_model_id [Integer]\n", + " allow_all_returns [Boolean]\n", + " return_custom_times [JSON]\n", + " payment_methods_override [JSON]\n", + " referenced_user_id [Integer]\n", + " allow_return_with_open_otr [Boolean]\n", + " driver_id [Integer]\n", + " owner_id [Integer]\n", + " allow_returns_in_cash [Boolean]\n", + " gt_request_id [Integer]\n", + " requires_payment_authorization [Boolean]\n", + " can_be_returned_special_customer [Boolean]\n", + " tax_applied [Float]\n", + " datastream_metadata [Dictionary]\n", + " source_timestamp [Integer]\n", + " uuid [Text]\n", + " last_promo_line_number [Integer]\n", + " last_item_line_number [Integer]\n", + " last_update_in_nav [DateTimeWithLocalTZ]\n", + " voucher_code [Text]\n", + " kilometers [Integer]\n", + " autogenerated_from_otr_id [Integer]\n", + " reason [Text]\n", + " appointment_id [Integer]\n", + " stop_ralarsa_sync [Boolean]\n", + " skip_provider_requires_delivery_confirmation [Boolean]\n", + " insurance_claim_id [Integer]\n", + " need_insurance_validation [Boolean]\n", + " validate_sol_pieces_when_closing_otr [Boolean]\n", + " accident_type_description [Text]\n", + " operation_type [Text]\n", + " insurance_policy_id [Integer]\n", + " damage_type_description [Text]\n", + " recorder_car_renounce_id [Integer]\n", + " allowed_car_revision [Boolean]\n", + " date_car_renounce [DateTimeWithLocalTZ]\n", + " last_incident_id [Integer]\n", + " show_budget_vs_appraisal_comparison [Boolean]\n", + " can_link_appraissal [Boolean]\n", + " source [Text]\n", + " external_id [Text]\n", + "\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "=== tpv_orders_invoice (id 1528) — 24 cols ===\n", + " id [Integer]\n", + " nav_id [Text]\n", + " created_at [DateTimeWithLocalTZ]\n", + " updated_at [DateTimeWithLocalTZ]\n", + " order_id [Integer]\n", + " created_by_id [Integer]\n", + " terminal_id [Integer]\n", + " invoice_path [Text]\n", + " ticket_path [Text]\n", + " status [Integer]\n", + " clear_one_path [Text]\n", + " customer_copy [JSON]\n", + " vehicle_copy [JSON]\n", + " show_vehicle [Boolean]\n", + " profit [Decimal]\n", + " profit_currency [Text]\n", + " delivery_note [Text]\n", + " datastream_metadata [Dictionary]\n", + " source_timestamp [Integer]\n", + " uuid [Text]\n", + " adjusted_profit [Decimal]\n", + " adjusted_profit_currency [Text]\n", + " registered_in_sol [Boolean]\n", + " from_standard_billing_flow [Boolean]\n", + "\n" + ] + } + ], + "source": [ + "# Inspeccionar tpv_terminals, tpv_orders_order, tpv_orders_invoice\n", + "for tid, label in [(1552, 'tpv_terminals'), (1548, 'tpv_orders_order'), (1528, 'tpv_orders_invoice')]:\n", + " m = client.request(\"GET\", f\"/api/table/{tid}/query_metadata\")\n", + " print(f\"=== {label} (id {tid}) — {len(m['fields'])} cols ===\")\n", + " for f in m['fields']:\n", + " print(f\" {f['name']:40} [{f['base_type'].replace('type/','')}]\")\n", + " print()" + ] + }, + { + "cell_type": "code", + "execution_count": 33, + "id": "56384579", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Terminales totales: 2000\n", + "\n", + "--- Distribucion terminal_type_id ---\n", + "terminal_type_id\n", + "3 764\n", + "17 534\n", + "9 444\n", + "5 62\n", + "10 53\n", + "8 52\n", + "11 52\n", + "15 16\n", + "1 10\n", + "14 5\n", + "12 3\n", + "4 2\n", + "16 2\n", + "6 1\n", + "\n", + "--- Terminales en centros DIGITALES (32) ---\n", + " terminal_id terminal_name terminal_type_id center_id centro centro_nav_id centro_es_digital\n", + " 701 18CAJA01 3 160 Aurgi Web 18 True\n", + " 702 18CAJA02 3 160 Aurgi Web 18 True\n", + " 703 18CAJA03 3 160 Aurgi Web 18 True\n", + " 704 18CAJA04 3 160 Aurgi Web 18 True\n", + " 705 18OFICINA01 3 160 Aurgi Web 18 True\n", + " 706 18TALLER01 3 160 Aurgi Web 18 True\n", + " 707 CAJA_WEB 3 160 Aurgi Web 18 True\n", + " 708 FICHAJE 3 160 Aurgi Web 18 True\n", + " 1121 CCAL 3 160 Aurgi Web 18 True\n", + " 1070 19CAJA01 9 161 MT Web 19 True\n", + " 1071 19CAJA02 3 161 MT Web 19 True\n", + " 1072 19CAJA03 3 161 MT Web 19 True\n", + " 1073 19CAJA04 3 161 MT Web 19 True\n", + " 1074 19OFICINA01 3 161 MT Web 19 True\n", + " 1075 19TALLER01 3 161 MT Web 19 True\n", + " 1076 CAJA_WEB 6 161 MT Web 19 True\n", + " 1077 CCAL 3 161 MT Web 19 True\n", + " 1078 FICHAJE 3 161 MT Web 19 True\n", + " 3016 405CAJA01 3 167 Autingo 405 True\n", + " 3017 405CAJA02 3 167 Autingo 405 True\n", + " 3018 405CAJA03 3 167 Autingo 405 True\n", + " 3019 405CAJA04 3 167 Autingo 405 True\n", + " 3020 405OFICINA01 3 167 Autingo 405 True\n", + " 3021 405TALLER01 3 167 Autingo 405 True\n", + " 3022 CAJA_WEB 3 167 Autingo 405 True\n", + " 3023 CCAL 3 167 Autingo 405 True\n", + " 3024 FICHAJE 3 167 Autingo 405 True\n", + " 6033 CCAL 14 167 Autingo 405 True\n", + " 6039 CCAL 14 167 Autingo 405 True\n", + " 6040 CCAL 14 167 Autingo 405 True\n", + " 6041 CCAL 14 167 Autingo 405 True\n", + " 6334 CCAL 14 167 Autingo 405 True\n" + ] + } + ], + "source": [ + "# 1. Inventario de terminales con nombre, centro, tipo\n", + "sql_terms = '''\n", + "SELECT\n", + " t.id AS terminal_id,\n", + " t.name AS terminal_name,\n", + " t.terminal_type_id,\n", + " t.center_id,\n", + " c.name AS centro,\n", + " c.nav_id AS centro_nav_id,\n", + " c.is_digital AS centro_es_digital\n", + "FROM `autingo-159109.psql_dcpublic.tpv_terminals` t\n", + "LEFT JOIN `autingo-159109.psql_dcpublic.centers` c ON t.center_id = c.id\n", + "ORDER BY t.center_id, t.id\n", + "'''\n", + "df_terms = run_sql(sql_terms)\n", + "print(f'Terminales totales: {len(df_terms)}')\n", + "print()\n", + "# Distribucion por tipo\n", + "print('--- Distribucion terminal_type_id ---')\n", + "print(df_terms['terminal_type_id'].value_counts().to_string())\n", + "print()\n", + "# Terminales en centros digitales\n", + "dig = df_terms[df_terms['centro_es_digital'] == True]\n", + "print(f'--- Terminales en centros DIGITALES ({len(dig)}) ---')\n", + "print(dig.to_string(index=False))" + ] + }, + { + "cell_type": "code", + "execution_count": 34, + "id": "d5e4a942", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "=== Orders 2025 en centros DIGITALES por terminal y flag is_precaweb / has_service_request ===\n", + "terminal_name centro centro_es_digital is_precaweb has_service_request orders total_cost_sum\n", + " 422CAJA01 Aurgi Asociados True False False 5 834936\n", + " CAJA_WEB Aurgi Asociados True True False 3 1282\n", + " CAJA_WEB Aurgi Asociados Gruas True True False 27696 1442752\n", + " 18CAJA01 Aurgi Web True False False 2 143\n", + " CAJA_WEB Aurgi Web True True False 112805 4571118\n", + " CAJA_WEB Autingo True True False 11959 1239345\n", + " 19CAJA01 MT Web True False False 6 620\n", + " CAJA_WEB MT Web True True False 1161 86088\n" + ] + } + ], + "source": [ + "# Cross-check: para cada tpv_orders_order en 2025, agrupar por terminal_name + is_precaweb + has_service_request\n", + "sql_term_verify = '''\n", + "SELECT\n", + " t.name AS terminal_name,\n", + " c.name AS centro,\n", + " c.is_digital AS centro_es_digital,\n", + " o.is_precaweb,\n", + " o.has_service_request,\n", + " COUNT(DISTINCT o.id) AS orders,\n", + " ROUND(SUM(o.total_cost), 0) AS total_cost_sum\n", + "FROM `autingo-159109.psql_dcpublic.tpv_orders_order` o\n", + "LEFT JOIN `autingo-159109.psql_dcpublic.tpv_terminals` t ON o.terminal_id = t.id\n", + "LEFT JOIN `autingo-159109.psql_dcpublic.centers` c ON t.center_id = c.id\n", + "WHERE EXTRACT(YEAR FROM o.created_at) = 2025\n", + " AND c.is_digital = TRUE\n", + "GROUP BY terminal_name, centro, centro_es_digital, is_precaweb, has_service_request\n", + "ORDER BY centro, terminal_name, is_precaweb\n", + "'''\n", + "df_tv = run_sql(sql_term_verify)\n", + "print('=== Orders 2025 en centros DIGITALES por terminal y flag is_precaweb / has_service_request ===')\n", + "print(df_tv.to_string(index=False))" + ] + }, + { + "cell_type": "code", + "execution_count": 35, + "id": "ce97f39a", + "metadata": {}, + "outputs": [ + { + "ename": "HTTPStatusError", + "evalue": "Client error '400 Bad Request' for url 'https://reports.autingo.es/api/dataset'\nFor more information check: https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/400", + "output_type": "error", + "traceback": [ + "\u001b[31m---------------------------------------------------------------------------\u001b[39m", + "\u001b[31mHTTPStatusError\u001b[39m Traceback (most recent call last)", + "\u001b[36mCell\u001b[39m\u001b[36m \u001b[39m\u001b[32mIn[35]\u001b[39m\u001b[32m, line 20\u001b[39m\n\u001b[32m 16\u001b[39m AND (t.name LIKE \u001b[33m'%WEB%'\u001b[39m OR t.name LIKE \u001b[33m'%CCAL%'\u001b[39m OR t.name = \u001b[33m'CAJA_WEB'\u001b[39m)\n\u001b[32m 17\u001b[39m GROUP BY terminal_name\n\u001b[32m 18\u001b[39m ORDER BY orders DESC\n\u001b[32m 19\u001b[39m '''\n\u001b[32m---> \u001b[39m\u001b[32m20\u001b[39m df_fis = run_sql(sql_fisicos)\n\u001b[32m 21\u001b[39m print(\u001b[33m'=== Terminales WEB/CCAL en centros FISICOS 2025 ==='\u001b[39m)\n\u001b[32m 22\u001b[39m print(df_fis.to_string(index=\u001b[38;5;28;01mFalse\u001b[39;00m))\n\u001b[32m 23\u001b[39m print()\n", + "\u001b[36mCell\u001b[39m\u001b[36m \u001b[39m\u001b[32mIn[1]\u001b[39m\u001b[32m, line 20\u001b[39m, in \u001b[36mrun_sql\u001b[39m\u001b[34m(sql, db_id)\u001b[39m\n\u001b[32m 18\u001b[39m \u001b[38;5;28;01mdef\u001b[39;00m run_sql(sql: str, db_id: int = DB_BIGQUERY) -> pd.DataFrame:\n\u001b[32m 19\u001b[39m \u001b[33m\"\"\"Ejecuta SQL contra Metabase y retorna DataFrame.\"\"\"\u001b[39m\n\u001b[32m---> \u001b[39m\u001b[32m20\u001b[39m res = metabase_execute_query(client, db_id, sql)\n\u001b[32m 21\u001b[39m cols = [c[\u001b[33m'display_name'\u001b[39m] \u001b[38;5;28;01mor\u001b[39;00m c[\u001b[33m'name'\u001b[39m] \u001b[38;5;28;01mfor\u001b[39;00m c \u001b[38;5;28;01min\u001b[39;00m res[\u001b[33m'data'\u001b[39m][\u001b[33m'cols'\u001b[39m]]\n\u001b[32m 22\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m pd.DataFrame(res[\u001b[33m'data'\u001b[39m][\u001b[33m'rows'\u001b[39m], columns=cols)\n", + "\u001b[36mFile \u001b[39m\u001b[32m~/fn_registry/python/functions/metabase/cards.py:227\u001b[39m, in \u001b[36mmetabase_execute_query\u001b[39m\u001b[34m(client, database_id, sql, max_results)\u001b[39m\n\u001b[32m 222\u001b[39m \u001b[38;5;28;01mif\u001b[39;00m max_results > \u001b[32m0\u001b[39m:\n\u001b[32m 223\u001b[39m body[\u001b[33m\"\u001b[39m\u001b[33mconstraints\u001b[39m\u001b[33m\"\u001b[39m] = {\n\u001b[32m 224\u001b[39m \u001b[33m\"\u001b[39m\u001b[33mmax-results\u001b[39m\u001b[33m\"\u001b[39m: max_results,\n\u001b[32m 225\u001b[39m \u001b[33m\"\u001b[39m\u001b[33mmax-results-bare-rows\u001b[39m\u001b[33m\"\u001b[39m: max_results,\n\u001b[32m 226\u001b[39m }\n\u001b[32m--> \u001b[39m\u001b[32m227\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[43mclient\u001b[49m\u001b[43m.\u001b[49m\u001b[43mrequest\u001b[49m\u001b[43m(\u001b[49m\u001b[33;43m\"\u001b[39;49m\u001b[33;43mPOST\u001b[39;49m\u001b[33;43m\"\u001b[39;49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[33;43m\"\u001b[39;49m\u001b[33;43m/api/dataset\u001b[39;49m\u001b[33;43m\"\u001b[39;49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mjson\u001b[49m\u001b[43m=\u001b[49m\u001b[43mbody\u001b[49m\u001b[43m)\u001b[49m\n", + "\u001b[36mFile \u001b[39m\u001b[32m~/fn_registry/python/functions/metabase/client.py:45\u001b[39m, in \u001b[36mMetabaseClient.request\u001b[39m\u001b[34m(self, method, path, **kwargs)\u001b[39m\n\u001b[32m 31\u001b[39m \u001b[38;5;250m\u001b[39m\u001b[33;03m\"\"\"Ejecuta una peticion HTTP contra la API de Metabase.\u001b[39;00m\n\u001b[32m 32\u001b[39m \n\u001b[32m 33\u001b[39m \u001b[33;03mArgs:\u001b[39;00m\n\u001b[32m (...)\u001b[39m\u001b[32m 42\u001b[39m \u001b[33;03m httpx.HTTPStatusError: Si el status code no es 2xx.\u001b[39;00m\n\u001b[32m 43\u001b[39m \u001b[33;03m\"\"\"\u001b[39;00m\n\u001b[32m 44\u001b[39m resp = \u001b[38;5;28mself\u001b[39m._http.request(method, path, **kwargs)\n\u001b[32m---> \u001b[39m\u001b[32m45\u001b[39m \u001b[43mresp\u001b[49m\u001b[43m.\u001b[49m\u001b[43mraise_for_status\u001b[49m\u001b[43m(\u001b[49m\u001b[43m)\u001b[49m\n\u001b[32m 46\u001b[39m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;129;01mnot\u001b[39;00m resp.content:\n\u001b[32m 47\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28;01mNone\u001b[39;00m\n", + "\u001b[36mFile \u001b[39m\u001b[32m~/fn_registry/projects/aurgi/analysis/venta_web/.venv/lib/python3.13/site-packages/httpx/_models.py:829\u001b[39m, in \u001b[36mResponse.raise_for_status\u001b[39m\u001b[34m(self)\u001b[39m\n\u001b[32m 827\u001b[39m error_type = error_types.get(status_class, \u001b[33m\"\u001b[39m\u001b[33mInvalid status code\u001b[39m\u001b[33m\"\u001b[39m)\n\u001b[32m 828\u001b[39m message = message.format(\u001b[38;5;28mself\u001b[39m, error_type=error_type)\n\u001b[32m--> \u001b[39m\u001b[32m829\u001b[39m \u001b[38;5;28;01mraise\u001b[39;00m HTTPStatusError(message, request=request, response=\u001b[38;5;28mself\u001b[39m)\n", + "\u001b[31mHTTPStatusError\u001b[39m: Client error '400 Bad Request' for url 'https://reports.autingo.es/api/dataset'\nFor more information check: https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/400" + ] + } + ], + "source": [ + "# Y ahora los centros FISICOS (no digitales) — buscar terminales CCAL / CAJA_WEB ahi\n", + "# para ver venta web cumplida en tienda\n", + "sql_fisicos = '''\n", + "SELECT\n", + " t.name AS terminal_name,\n", + " COUNT(DISTINCT o.id) AS orders,\n", + " COUNT(DISTINCT o.id) FILTER (WHERE o.is_precaweb) AS orders_precaweb,\n", + " COUNT(DISTINCT o.id) FILTER (WHERE o.has_service_request) AS orders_con_service_req,\n", + " ROUND(SUM(o.total_cost), 0) AS total_cost,\n", + " ROUND(SUM(CASE WHEN o.is_precaweb THEN o.total_cost END), 0) AS total_cost_precaweb\n", + "FROM `autingo-159109.psql_dcpublic.tpv_orders_order` o\n", + "JOIN `autingo-159109.psql_dcpublic.tpv_terminals` t ON o.terminal_id = t.id\n", + "JOIN `autingo-159109.psql_dcpublic.centers` c ON t.center_id = c.id\n", + "WHERE EXTRACT(YEAR FROM o.created_at) = 2025\n", + " AND c.is_digital = FALSE\n", + " AND (t.name LIKE '%WEB%' OR t.name LIKE '%CCAL%' OR t.name = 'CAJA_WEB')\n", + "GROUP BY terminal_name\n", + "ORDER BY orders DESC\n", + "'''\n", + "df_fis = run_sql(sql_fisicos)\n", + "print('=== Terminales WEB/CCAL en centros FISICOS 2025 ===')\n", + "print(df_fis.to_string(index=False))\n", + "print()\n", + "\n", + "# Y ver conteo por nombre terminal (top) en centros fisicos con is_precaweb=TRUE\n", + "sql_fis2 = '''\n", + "SELECT\n", + " t.name AS terminal_name,\n", + " COUNT(DISTINCT o.id) AS orders_web_in_centro,\n", + " ROUND(SUM(o.total_cost), 0) AS revenue\n", + "FROM `autingo-159109.psql_dcpublic.tpv_orders_order` o\n", + "JOIN `autingo-159109.psql_dcpublic.tpv_terminals` t ON o.terminal_id = t.id\n", + "JOIN `autingo-159109.psql_dcpublic.centers` c ON t.center_id = c.id\n", + "WHERE EXTRACT(YEAR FROM o.created_at) = 2025\n", + " AND c.is_digital = FALSE\n", + " AND o.is_precaweb = TRUE\n", + "GROUP BY terminal_name\n", + "ORDER BY orders_web_in_centro DESC\n", + "LIMIT 20\n", + "'''\n", + "df_fis2 = run_sql(sql_fis2)\n", + "print('=== TOP terminales con is_precaweb=TRUE en centros FISICOS 2025 ===')\n", + "print(df_fis2.to_string(index=False))" + ] + }, + { + "cell_type": "code", + "execution_count": 36, + "id": "1adaf1b0", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "=== TOP terminales en centros FISICOS con is_precaweb>0 (2025) ===\n", + " terminal_id terminal_name terminal_type_id centro centro_nav_id orders orders_precaweb orders_con_sr revenue revenue_precaweb\n", + " 263 CAJA_WEB 3 Vaguada 89 3122 1126 0 418512 199638\n", + " 252 CAJA_WEB 3 San Sebastian 23 1982 961 0 283161 170123\n", + " 205 CAJA_WEB 3 Villalba 54 7036 866 0 753962 140903\n", + " 199 CAJA_WEB 3 Vallecas 40 6833 770 0 580134 124238\n", + " 185 CAJA_WEB 3 Leganes 21 7674 716 0 866044 114946\n", + " 55 CAJA_WEB 3 Malaga 26 2742 703 0 308018 112471\n", + " 90 CAJA_WEB 3 Majadahonda 85 1832 700 0 229677 126809\n", + " 134 CAJA_WEB 3 Emilio Muñoz 75 2375 671 0 288075 108933\n", + " 337 CAJA_WEB 3 Alcorcon 61 7462 652 0 846504 101293\n", + " 72 CAJA_WEB 3 Store 28 3793 608 0 453970 94475\n", + " 12 CAJA_WEB 3 Islazul 167 1995 589 0 249061 95465\n", + " 107 CAJA_WEB 3 Sant Cugat 156 2531 568 0 250190 97797\n", + " 84 CAJA_WEB 3 San Fernando 22 8029 561 0 725251 91731\n", + " 279 CAJA_WEB 3 Granada 38 2030 519 0 220857 83086\n", + " 357 CAJA_WEB 3 San Juan 63 5737 511 0 655167 82093\n", + " 219 CAJA_WEB 3 Cornella 55 5877 499 0 609250 80754\n", + " 350 CAJA_WEB 3 Las Rozas 25 6054 493 0 593887 95445\n", + " 96 CAJA_WEB 3 Avda. Toreros 76 1338 492 0 171564 87708\n", + " 171 CAJA_WEB 3 Almeria 46 3020 478 0 252919 74703\n", + " 324 CAJA_WEB 3 Barbera 29 3007 477 0 269678 76220\n", + " 65 CAJA_WEB 3 Mataro 36 3776 475 0 404397 73240\n", + " 148 CAJA_WEB 3 Mostoles 58 1606 447 0 207006 83856\n", + " 165 CAJA_WEB 3 Valdemoro 59 1876 436 0 245426 71580\n", + " 314 CAJA_WEB 3 Granollers 169 2117 396 0 195765 64192\n", + " 144 CAJA_WEB 3 Cornella 2 90 1343 386 0 178499 68037\n", + " 386 CAJA_WEB 3 La Red 27 2648 366 0 297999 58170\n", + " 192 CAJA_WEB 3 Gta. Cadiz 45 2309 363 0 270676 54017\n", + " 47 CAJA_WEB 3 Cordoba 43 5254 353 0 548276 58900\n", + " 399 CAJA_WEB 3 Rivas 53 938 340 0 109333 59602\n", + " 153 CAJA_WEB 3 Fuengirola 88 1453 314 0 141843 55727\n", + " 140 CAJA_WEB 3 Gava 95 1863 313 0 226120 48879\n", + " 299 CAJA_WEB 3 Velez Malaga 86 2480 310 0 273057 54281\n", + " 362 CAJA_WEB 3 Zaragoza 168 842 310 0 115717 55645\n", + " 224 CAJA_WEB 3 Sabadell 74 1794 305 0 217652 54001\n", + " 76 CAJA_WEB 3 Sant Boi 37 1011 291 0 139085 50410\n", + " 235 CAJA_WEB 3 Alcala Henares 56 2604 284 0 241717 55727\n", + " 128 CAJA_WEB 3 Pinto 24 967 267 0 126676 43069\n", + " 60 CAJA_WEB 3 Aluche 154 1587 265 0 151584 41967\n", + " 284 CAJA_WEB 3 Olias del Rey 78 846 251 0 97988 45618\n", + " 23 CAJA_WEB 3 Huelva 166 1230 249 0 124801 49376\n" + ] + } + ], + "source": [ + "# Sin asumir nombres: top terminales por orders is_precaweb=TRUE en CENTROS FISICOS 2025\n", + "# (syntax BigQuery: COUNTIF / SUM(IF(...)))\n", + "sql_fis = '''\n", + "SELECT\n", + " t.id AS terminal_id,\n", + " t.name AS terminal_name,\n", + " t.terminal_type_id,\n", + " c.name AS centro,\n", + " c.nav_id AS centro_nav_id,\n", + " COUNT(DISTINCT o.id) AS orders,\n", + " COUNTIF(o.is_precaweb) AS orders_precaweb,\n", + " COUNTIF(o.has_service_request) AS orders_con_sr,\n", + " ROUND(SUM(o.total_cost), 0) AS revenue,\n", + " ROUND(SUM(IF(o.is_precaweb, o.total_cost, 0)), 0) AS revenue_precaweb\n", + "FROM `autingo-159109.psql_dcpublic.tpv_orders_order` o\n", + "JOIN `autingo-159109.psql_dcpublic.tpv_terminals` t ON o.terminal_id = t.id\n", + "JOIN `autingo-159109.psql_dcpublic.centers` c ON t.center_id = c.id\n", + "WHERE EXTRACT(YEAR FROM o.created_at) = 2025\n", + " AND c.is_digital = FALSE\n", + "GROUP BY terminal_id, terminal_name, terminal_type_id, centro, centro_nav_id\n", + "HAVING COUNTIF(o.is_precaweb) > 0\n", + "ORDER BY orders_precaweb DESC\n", + "LIMIT 40\n", + "'''\n", + "df_fis = run_sql(sql_fis)\n", + "print('=== TOP terminales en centros FISICOS con is_precaweb>0 (2025) ===')\n", + "print(df_fis.to_string(index=False))" + ] + }, + { + "cell_type": "code", + "execution_count": 37, + "id": "f1f1595a", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "=== NOMBRES UNICOS DE TERMINAL + orders 2025 ===\n", + "terminal_name num_terminales orders_2025 precaweb service_req\n", + " CAJA_WEB 162 320493 177531 0\n", + " CCAL 213 241416 0 0\n", + " 55CAJA01 1 36579 0 0\n", + " 169CAJA02 1 28675 0 0\n", + " 58CAJA01 1 27506 0 0\n", + " 167CAJA02 1 27312 0 0\n", + " 75CAJA02 1 26657 0 0\n", + " 61CAJA02 1 25467 0 0\n", + " 36CAJA03 1 24685 0 0\n", + " 29CAJA02 1 24288 0 0\n", + " 21CAJA02 1 24210 0 0\n", + " 54CAJA02 1 23543 0 0\n", + " 43CAJA03 1 23437 0 0\n", + " 54CAJA03 1 22989 0 0\n", + " 57CAJA01 1 22854 0 0\n", + " 38CAJA03 1 22824 0 0\n", + " 45CAJA01 1 22640 0 0\n", + " 28CAJA03 1 22563 0 0\n", + " 28CAJA04 1 22251 0 0\n", + " 24CAJA02 1 20507 0 0\n", + " 46CAJA01 1 20398 0 0\n", + " 86CAJA01 1 20344 0 0\n", + " 62CAJA01 1 20103 0 0\n", + " 23CAJA01 1 20053 0 0\n", + " 76CAJA01 1 20021 0 0\n", + " 56CAJA02 1 19980 0 0\n", + " 164CAJA02 1 19838 0 0\n", + " 21CAJA03 1 19502 0 0\n", + " 156CAJA02 1 19203 0 0\n", + " 63CAJA04 1 19086 0 0\n", + " 27CAJA02 1 19036 0 0\n", + " 190CAJA01 1 19000 0 0\n", + " 26CAJA03 1 18998 0 0\n", + " 85CAJA01 1 18918 0 0\n", + " 74CAJA02 1 18783 0 0\n", + " 40CAJA02 1 18733 0 0\n", + " 26CAJA04 1 18683 0 0\n", + " 77CAJA02 1 18332 0 0\n", + " 95CAJA01 1 17910 0 0\n", + " 86CAJA02 1 17751 0 0\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\n", + "=== Distribucion de tpv_orders_order.source 2025 ===\n", + "source orders precaweb service_req revenue\n", + "(null) 2493702 177531 0 366408864\n" + ] + } + ], + "source": [ + "# Nombres unicos de terminales + tipos + el campo `source` de tpv_orders_order\n", + "# 1. Nombres distintos de terminales (top 30 por orders 2025)\n", + "sql_term_names = '''\n", + "SELECT\n", + " t.name AS terminal_name,\n", + " COUNT(DISTINCT t.id) AS num_terminales,\n", + " COUNT(DISTINCT o.id) AS orders_2025,\n", + " COUNTIF(o.is_precaweb) AS precaweb,\n", + " COUNTIF(o.has_service_request) AS service_req\n", + "FROM `autingo-159109.psql_dcpublic.tpv_terminals` t\n", + "LEFT JOIN `autingo-159109.psql_dcpublic.tpv_orders_order` o\n", + " ON o.terminal_id = t.id AND EXTRACT(YEAR FROM o.created_at) = 2025\n", + "GROUP BY terminal_name\n", + "ORDER BY orders_2025 DESC NULLS LAST\n", + "LIMIT 40\n", + "'''\n", + "df_tn = run_sql(sql_term_names)\n", + "print('=== NOMBRES UNICOS DE TERMINAL + orders 2025 ===')\n", + "print(df_tn.to_string(index=False))\n", + "\n", + "# 2. Campo `source` de tpv_orders_order\n", + "sql_source = '''\n", + "SELECT\n", + " COALESCE(o.source, '(null)') AS source,\n", + " COUNT(DISTINCT o.id) AS orders,\n", + " COUNTIF(o.is_precaweb) AS precaweb,\n", + " COUNTIF(o.has_service_request) AS service_req,\n", + " ROUND(SUM(o.total_cost), 0) AS revenue\n", + "FROM `autingo-159109.psql_dcpublic.tpv_orders_order` o\n", + "WHERE EXTRACT(YEAR FROM o.created_at) = 2025\n", + "GROUP BY source\n", + "ORDER BY orders DESC\n", + "'''\n", + "df_src = run_sql(sql_source)\n", + "print()\n", + "print('=== Distribucion de tpv_orders_order.source 2025 ===')\n", + "print(df_src.to_string(index=False))" + ] + }, + { + "cell_type": "code", + "execution_count": 38, + "id": "181dcded", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "=== TERMINAL CCAL (2025) — cruzando con supply_orders ===\n", + " centro ccal_orders supply_orders_asociados con_service_request total_cost_ccal\n", + " Goya GLASS 9110 7120 0 2366941\n", + " Store 6571 505 0 1139059\n", + " MT El Bercial CRISTALES 6143 4869 0 1648415\n", + " Vallecas CRISTALES 6019 4953 0 1550761\n", + " Leganes 5864 507 0 1093530\n", + " Vaguada 5644 940 0 995783\n", + " MT Sanchinarro 5166 1683 0 1427021\n", + " Malaga 4923 336 0 874492\n", + " Villalba 4732 658 0 856667\n", + " Alcobendas CRISTALES 4616 3751 0 1350488\n", + " Granada 4446 257 0 818977\n", + " Leganes CRISTALES 4102 3599 0 1140564\n", + " San Fernando CRISTALES 4007 3450 0 1167164\n", + " Villalba CRISTALES 3888 3478 0 1163717\n", + "Santa Engracia CRISTALES 3856 3306 0 1157439\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\n", + "=== Distribucion por terminal_type_id ===\n", + " terminal_type_id terminales orders_2025 precaweb ccal_count caja_web_count\n", + " 17 7274 0 0 0 0\n", + " 3 805 1797438 175236 5 77\n", + " 9 444 440148 1134 1 50\n", + " 15 274 13429 0 0 34\n", + " 5 65 140510 0 64 0\n", + " 8 53 0 0 0 0\n", + " 10 53 1834 0 52 0\n", + " 11 52 33533 0 52 0\n", + " 16 34 65649 0 34 0\n", + " 1 11 0 0 0 0\n", + " 14 5 0 0 5 0\n", + " 12 3 0 0 0 0\n", + " 4 2 0 0 0 0\n", + " 6 1 1161 1161 0 1\n", + " 20 1 0 0 0 0\n" + ] + } + ], + "source": [ + "# Cross-check CCAL: ver si sus orders generan supply_orders con service_request_id\n", + "# (indicando que es venta centralizada / call center)\n", + "sql_ccal = '''\n", + "WITH ccal_orders AS (\n", + " SELECT o.id AS order_id, o.terminal_id, o.total_cost, o.created_at, t.name AS term_name, c.name AS centro\n", + " FROM `autingo-159109.psql_dcpublic.tpv_orders_order` o\n", + " JOIN `autingo-159109.psql_dcpublic.tpv_terminals` t ON o.terminal_id = t.id\n", + " JOIN `autingo-159109.psql_dcpublic.centers` c ON t.center_id = c.id\n", + " WHERE t.name = 'CCAL'\n", + " AND EXTRACT(YEAR FROM o.created_at) = 2025\n", + ")\n", + "SELECT\n", + " co.centro,\n", + " COUNT(DISTINCT co.order_id) AS ccal_orders,\n", + " COUNT(DISTINCT so.id) AS supply_orders_asociados,\n", + " COUNTIF(so.service_request_id IS NOT NULL) AS con_service_request,\n", + " ROUND(SUM(co.total_cost), 0) AS total_cost_ccal\n", + "FROM ccal_orders co\n", + "LEFT JOIN `autingo-159109.psql_dcpublic.supply_orders` so ON so.tpv_orders_order_id = co.order_id\n", + "GROUP BY co.centro\n", + "ORDER BY ccal_orders DESC\n", + "LIMIT 15\n", + "'''\n", + "df_ccal = run_sql(sql_ccal)\n", + "print('=== TERMINAL CCAL (2025) — cruzando con supply_orders ===')\n", + "print(df_ccal.to_string(index=False))\n", + "\n", + "# Y ver terminal_types\n", + "sql_types = '''\n", + "SELECT\n", + " t.terminal_type_id,\n", + " COUNT(DISTINCT t.id) AS terminales,\n", + " COUNT(DISTINCT o.id) AS orders_2025,\n", + " COUNTIF(o.is_precaweb) AS precaweb,\n", + " COUNT(DISTINCT CASE WHEN t.name = 'CCAL' THEN t.id END) AS ccal_count,\n", + " COUNT(DISTINCT CASE WHEN t.name = 'CAJA_WEB' THEN t.id END) AS caja_web_count\n", + "FROM `autingo-159109.psql_dcpublic.tpv_terminals` t\n", + "LEFT JOIN `autingo-159109.psql_dcpublic.tpv_orders_order` o\n", + " ON o.terminal_id = t.id AND EXTRACT(YEAR FROM o.created_at) = 2025\n", + "GROUP BY t.terminal_type_id\n", + "ORDER BY terminales DESC\n", + "'''\n", + "df_types = run_sql(sql_types)\n", + "print()\n", + "print('=== Distribucion por terminal_type_id ===')\n", + "print(df_types.to_string(index=False))" + ] + }, + { + "cell_type": "markdown", + "id": "062f199b", + "metadata": {}, + "source": [ + "## 13. Unión venta ↔ terminal TPV — verificación\n", + "\n", + "### 13.1 Caminos que SÍ funcionan\n", + "\n", + "```\n", + "tpv_orders_order.terminal_id → tpv_terminals.id → tpv_terminals.center_id → centers\n", + "tpv_orders_invoice.terminal_id → tpv_terminals.id\n", + "supply_orders.tpv_orders_order_id → tpv_orders_order.id\n", + "```\n", + "\n", + "Tanto el `order` como la `invoice` TPV cargan el `terminal_id`. La union funciona limpia.\n", + "\n", + "### 13.2 Flags que indican origen (señales directas)\n", + "\n", + "Campos en **`tpv_orders_order`**:\n", + "\n", + "| Campo | Qué indica | Utilidad |\n", + "|---|---|---|\n", + "| `is_precaweb` (Boolean) | Orden creada por flujo web (pre-caja web) | **Sí**: flag directo venta online |\n", + "| `has_service_request` (Boolean) | Ligada a service_request web | Poco usado (siempre 0 en 2025) |\n", + "| `appointment_id` | Venía de cita previa | Útil para C&C/cita |\n", + "| `source` (Text) | **NULL en todos los 2.5M orders 2025** | ❌ No usar |\n", + "\n", + "### 13.3 Terminales reales (muestreo 2025)\n", + "\n", + "| Nombre terminal | Nº terminales | Orders 2025 | is_precaweb | Qué es |\n", + "|---|---:|---:|---:|---|\n", + "| `CAJA_WEB` | 162 | 320.493 | **177.531** | Terminal web — en TODOS los centros (no solo digitales) |\n", + "| `CCAL` | 213 | 241.416 | 0 | **Call center de cristales/lunas** — siempre ligado a centros CRISTALES (Goya GLASS, Vallecas CRISTALES, Alcobendas CRISTALES, etc.) |\n", + "| `{codcentro}CAJA01..04` | ~800 | millones | 0 | Cajas físicas del centro — venta presencial pura |\n", + "| `{codcentro}TALLER01` / `OFICINA01` | variable | variable | 0 | Terminales de taller/oficina |\n", + "| `FICHAJE` | variable | 0 | 0 | Terminal de fichar (no venta) |\n", + "\n", + "**Aviso importante**: `CCAL` NO es Click & Collect. Es el **call center de cristales** — operadores que toman pedidos telefónicos y los registran en una terminal dedicada. Tiene total_cost de 2.4M€/año solo en Goya GLASS. Es una línea de negocio aparte.\n", + "\n", + "### 13.4 Clasificación operativa del origen de venta\n", + "\n", + "Combinando terminal + flag:\n", + "\n", + "```sql\n", + "CASE\n", + " -- Venta web pura\n", + " WHEN o.is_precaweb = TRUE THEN 'web_online'\n", + " -- Call center cristales (detectar por terminal + centro)\n", + " WHEN t.name = 'CCAL' AND c.name LIKE '%CRISTAL%' THEN 'call_center_cristales'\n", + " WHEN t.name = 'CCAL' THEN 'call_center'\n", + " -- Venta presencial tienda\n", + " WHEN t.name LIKE '%CAJA0%' OR t.name LIKE '%TALLER%' OR t.name LIKE '%OFICINA%' THEN 'presencial_tienda'\n", + " -- CAJA_WEB con precaweb=FALSE: raro pero lo ves en centros digitales (5 orders en 2025)\n", + " WHEN t.name = 'CAJA_WEB' AND o.is_precaweb = FALSE THEN 'web_legacy_no_flag'\n", + " ELSE 'otro'\n", + "END AS origen_venta\n", + "```\n", + "\n", + "**Con este campo podemos**:\n", + "- Segmentar los ~2.5M orders/año por origen sin depender del nombre de terminal\n", + "- Cruzar cada origen con NAV invoice (vía `tpv_orders_invoice.nav_id` o `supply_orders.tpv_orders_order_id`)\n", + "- Añadir canal marketplace cuando origen = web_online (via `supply_orders → service_requests → channels`)\n", + "\n", + "### 13.5 Vista canónica v2 (incorporando TPV)\n", + "\n", + "La view `v_venta_web_unificada` propuesta en la sección 12.3 se enriquece con terminal + origen:\n", + "\n", + "```sql\n", + "-- Añadir JOINs a tpv_orders_order / terminals y campo origen_venta\n", + "LEFT JOIN `autingo-159109.psql_dcpublic.tpv_orders_order` tpv_o ON so.tpv_orders_order_id = tpv_o.id\n", + "LEFT JOIN `autingo-159109.psql_dcpublic.tpv_terminals` tpv_t ON tpv_o.terminal_id = tpv_t.id\n", + "```\n", + "\n", + "Esto permite:\n", + "- Saber en qué terminal se imputó (tienda + caja específica)\n", + "- Distinguir web / call center / presencial / C&C sin heurísticas frágiles\n", + "- Seguir la cadena hasta la factura NAV\n", + "\n", + "### 13.6 Limitaciones detectadas\n", + "\n", + "- El campo `source` está vacío → no confiar en él\n", + "- `has_service_request=FALSE` incluso para orders claramente web → flag no mantenido, usar `is_precaweb` en su lugar\n", + "- `CCAL` sin flag alguno → hay que identificarlo por nombre + contexto del centro\n", + "- Nombres de terminal no son estándar estricto (variantes `CAJA_WEB`, `CCAL`, `{cod}CAJA01`...) — conviene crear un catálogo `tpv_terminal_clasificacion` en `anjana_bi_datamart` para mantener la clasificación actualizada" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.13.5" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 0000000..fbc50bf --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,15 @@ +[project] +name = "venta-web" +version = "0.1.0" +description = "Add your description here" +readme = "README.md" +requires-python = ">=3.13" +dependencies = [ + "jupyter>=1.1.1", + "jupyter-collaboration>=4.3.0", + "jupyter-mcp-server>=0.4.0", + "jupyterlab>=4.5.6", + "matplotlib>=3.10.8", + "numpy>=2.4.4", + "pandas>=3.0.2", +] diff --git a/run-jupyter-lab.sh b/run-jupyter-lab.sh new file mode 100755 index 0000000..0739b68 --- /dev/null +++ b/run-jupyter-lab.sh @@ -0,0 +1,50 @@ +#!/bin/bash +# Jupyter Lab — modo colaborativo con autodeteccion de puerto +# Generado por write_jupyter_launcher (fn_registry) + +find_free_port() { + for port in 8888 8889 8890 8891 8892 8893 8894 8895 8896 8897 8898 8899; do + if ! ss -tln 2>/dev/null | grep -q ":${port} " && \ + ! lsof -i:"$port" >/dev/null 2>&1; then + echo $port + return + fi + done + echo 8888 +} + +PORT=${1:-$(find_free_port)} +cd "$(dirname "$0")" + +echo $PORT > .jupyter-port + +source .venv/bin/activate 2>/dev/null || true + +# IPython startup: cargar .ipython/ local (FN_REGISTRY_ROOT, helpers, sys.path) +if [ -d "$(pwd)/.ipython" ]; then + export IPYTHONDIR="$(pwd)/.ipython" +fi + +if ! python -c "import jupyter_collaboration" 2>/dev/null; then + echo "ERROR: jupyter-collaboration no esta instalado" + echo "Instala con: uv add jupyter-collaboration" + exit 1 +fi + +echo "════════════════════════════════════════════════" +echo " Jupyter Lab + Colaboracion en puerto $PORT" +echo "════════════════════════════════════════════════" +echo "" +echo " Abre: http://localhost:$PORT" +echo " Ctrl+C para detener" +echo "" + +jupyter lab \ + --port=$PORT \ + --no-browser \ + --ServerApp.token='' \ + --ServerApp.password='' \ + --ServerApp.disable_check_xsrf=True \ + --ServerApp.allow_origin='*' \ + --ServerApp.root_dir="$(pwd)" \ + --collaborative diff --git a/uv.lock b/uv.lock new file mode 100644 index 0000000..b37b113 --- /dev/null +++ b/uv.lock @@ -0,0 +1,2552 @@ +version = 1 +revision = 3 +requires-python = ">=3.13" +resolution-markers = [ + "python_full_version >= '3.14' and sys_platform == 'win32'", + "python_full_version >= '3.14' and sys_platform == 'emscripten'", + "python_full_version >= '3.14' and sys_platform != 'emscripten' and sys_platform != 'win32'", + "python_full_version < '3.14' and sys_platform == 'win32'", + "python_full_version < '3.14' and sys_platform == 'emscripten'", + "python_full_version < '3.14' and sys_platform != 'emscripten' and sys_platform != 'win32'", +] + +[[package]] +name = "annotated-doc" +version = "0.0.4" +source = { registry = "https://pypi.org/simple" } +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/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]] +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" } +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" }, +] + +[[package]] +name = "anyio" +version = "4.13.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "idna" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/19/14/2c5dd9f512b66549ae92767a9c7b330ae88e1932ca57876909410251fe13/anyio-4.13.0.tar.gz", hash = "sha256:334b70e641fd2221c1505b3890c69882fe4a2df910cba14d97019b90b24439dc", size = 231622, upload-time = "2026-03-24T12:59:09.671Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/da/42/e921fccf5015463e32a3cf6ee7f980a6ed0f395ceeaa45060b61d86486c2/anyio-4.13.0-py3-none-any.whl", hash = "sha256:08b310f9e24a9594186fd75b4f73f4a4152069e3853f1ed8bfbf58369f4ad708", size = 114353, upload-time = "2026-03-24T12:59:08.246Z" }, +] + +[[package]] +name = "appnope" +version = "0.1.4" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/35/5d/752690df9ef5b76e169e68d6a129fa6d08a7100ca7f754c89495db3c6019/appnope-0.1.4.tar.gz", hash = "sha256:1de3860566df9caf38f01f86f65e0e13e379af54f9e4bee1e66b48f2efffd1ee", size = 4170, upload-time = "2024-02-06T09:43:11.258Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/81/29/5ecc3a15d5a33e31b26c11426c45c501e439cb865d0bff96315d86443b78/appnope-0.1.4-py2.py3-none-any.whl", hash = "sha256:502575ee11cd7a28c0205f379b525beefebab9d161b7c964670864014ed7213c", size = 4321, upload-time = "2024-02-06T09:43:09.663Z" }, +] + +[[package]] +name = "argon2-cffi" +version = "25.1.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "argon2-cffi-bindings" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/0e/89/ce5af8a7d472a67cc819d5d998aa8c82c5d860608c4db9f46f1162d7dab9/argon2_cffi-25.1.0.tar.gz", hash = "sha256:694ae5cc8a42f4c4e2bf2ca0e64e51e23a040c6a517a85074683d3959e1346c1", size = 45706, upload-time = "2025-06-03T06:55:32.073Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/4f/d3/a8b22fa575b297cd6e3e3b0155c7e25db170edf1c74783d6a31a2490b8d9/argon2_cffi-25.1.0-py3-none-any.whl", hash = "sha256:fdc8b074db390fccb6eb4a3604ae7231f219aa669a2652e0f20e16ba513d5741", size = 14657, upload-time = "2025-06-03T06:55:30.804Z" }, +] + +[[package]] +name = "argon2-cffi-bindings" +version = "25.1.0" +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" }, +] + +[[package]] +name = "arrow" +version = "1.4.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "python-dateutil" }, + { name = "tzdata" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/b9/33/032cdc44182491aa708d06a68b62434140d8c50820a087fac7af37703357/arrow-1.4.0.tar.gz", hash = "sha256:ed0cc050e98001b8779e84d461b0098c4ac597e88704a655582b21d116e526d7", size = 152931, upload-time = "2025-10-18T17:46:46.761Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/ed/c9/d7977eaacb9df673210491da99e6a247e93df98c715fc43fd136ce1d3d33/arrow-1.4.0-py3-none-any.whl", hash = "sha256:749f0769958ebdc79c173ff0b0670d59051a535fa26e8eba02953dc19eb43205", size = 68797, upload-time = "2025-10-18T17:46:45.663Z" }, +] + +[[package]] +name = "asttokens" +version = "3.0.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/be/a5/8e3f9b6771b0b408517c82d97aed8f2036509bc247d46114925e32fe33f0/asttokens-3.0.1.tar.gz", hash = "sha256:71a4ee5de0bde6a31d64f6b13f2293ac190344478f081c3d1bccfcf5eacb0cb7", size = 62308, upload-time = "2025-11-15T16:43:48.578Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/d2/39/e7eaf1799466a4aef85b6a4fe7bd175ad2b1c6345066aa33f1f58d4b18d0/asttokens-3.0.1-py3-none-any.whl", hash = "sha256:15a3ebc0f43c2d0a50eeafea25e19046c68398e487b9f1f5b517f7c0f40f976a", size = 27047, upload-time = "2025-11-15T16:43:16.109Z" }, +] + +[[package]] +name = "async-lru" +version = "2.3.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/e8/1f/989ecfef8e64109a489fff357450cb73fa73a865a92bd8c272170a6922c2/async_lru-2.3.0.tar.gz", hash = "sha256:89bdb258a0140d7313cf8f4031d816a042202faa61d0ab310a0a538baa1c24b6", size = 16332, upload-time = "2026-03-19T01:04:32.413Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/e5/e2/c2e3abf398f80732e58b03be77bde9022550d221dd8781bf586bd4d97cc1/async_lru-2.3.0-py3-none-any.whl", hash = "sha256:eea27b01841909316f2cc739807acea1c623df2be8c5cfad7583286397bb8315", size = 8403, upload-time = "2026-03-19T01:04:30.883Z" }, +] + +[[package]] +name = "attrs" +version = "26.1.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/9a/8e/82a0fe20a541c03148528be8cac2408564a6c9a0cc7e9171802bc1d26985/attrs-26.1.0.tar.gz", hash = "sha256:d03ceb89cb322a8fd706d4fb91940737b6642aa36998fe130a9bc96c985eff32", size = 952055, upload-time = "2026-03-19T14:22:25.026Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/64/b4/17d4b0b2a2dc85a6df63d1157e028ed19f90d4cd97c36717afef2bc2f395/attrs-26.1.0-py3-none-any.whl", hash = "sha256:c647aa4a12dfbad9333ca4e71fe62ddc36f4e63b2d260a37a8b83d2f043ac309", size = 67548, upload-time = "2026-03-19T14:22:23.645Z" }, +] + +[[package]] +name = "babel" +version = "2.18.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/7d/b2/51899539b6ceeeb420d40ed3cd4b7a40519404f9baf3d4ac99dc413a834b/babel-2.18.0.tar.gz", hash = "sha256:b80b99a14bd085fcacfa15c9165f651fbb3406e66cc603abf11c5750937c992d", size = 9959554, upload-time = "2026-02-01T12:30:56.078Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/77/f5/21d2de20e8b8b0408f0681956ca2c69f1320a3848ac50e6e7f39c6159675/babel-2.18.0-py3-none-any.whl", hash = "sha256:e2b422b277c2b9a9630c1d7903c2a00d0830c409c59ac8cae9081c92f1aeba35", size = 10196845, upload-time = "2026-02-01T12:30:53.445Z" }, +] + +[[package]] +name = "beautifulsoup4" +version = "4.14.3" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "soupsieve" }, + { name = "typing-extensions" }, +] +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/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]] +name = "bleach" +version = "6.3.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "webencodings" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/07/18/3c8523962314be6bf4c8989c79ad9531c825210dd13a8669f6b84336e8bd/bleach-6.3.0.tar.gz", hash = "sha256:6f3b91b1c0a02bb9a78b5a454c92506aa0fdf197e1d5e114d2e00c6f64306d22", size = 203533, upload-time = "2025-10-27T17:57:39.211Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/cd/3a/577b549de0cc09d95f11087ee63c739bba856cd3952697eec4c4bb91350a/bleach-6.3.0-py3-none-any.whl", hash = "sha256:fe10ec77c93ddf3d13a73b035abaac7a9f5e436513864ccdad516693213c65d6", size = 164437, upload-time = "2025-10-27T17:57:37.538Z" }, +] + +[package.optional-dependencies] +css = [ + { name = "tinycss2" }, +] + +[[package]] +name = "certifi" +version = "2026.2.25" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/af/2d/7bf41579a8986e348fa033a31cdd0e4121114f6bce2457e8876010b092dd/certifi-2026.2.25.tar.gz", hash = "sha256:e887ab5cee78ea814d3472169153c2d12cd43b14bd03329a39a9c6e2e80bfba7", size = 155029, upload-time = "2026-02-25T02:54:17.342Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/9a/3c/c17fb3ca2d9c3acff52e30b309f538586f9f5b9c9cf454f3845fc9af4881/certifi-2026.2.25-py3-none-any.whl", hash = "sha256:027692e4402ad994f1c42e52a4997a9763c646b73e4096e4d5d6db8af1d6f0fa", size = 153684, upload-time = "2026-02-25T02:54:15.766Z" }, +] + +[[package]] +name = "cffi" +version = "2.0.0" +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" }, +] + +[[package]] +name = "charset-normalizer" +version = "3.4.7" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/e7/a1/67fe25fac3c7642725500a3f6cfe5821ad557c3abb11c9d20d12c7008d3e/charset_normalizer-3.4.7.tar.gz", hash = "sha256:ae89db9e5f98a11a4bf50407d4363e7b09b31e55bc117b4f7d80aab97ba009e5", size = 144271, upload-time = "2026-04-02T09:28:39.342Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/c1/3b/66777e39d3ae1ddc77ee606be4ec6d8cbd4c801f65e5a1b6f2b11b8346dd/charset_normalizer-3.4.7-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:f496c9c3cc02230093d8330875c4c3cdfc3b73612a5fd921c65d39cbcef08063", size = 309627, upload-time = "2026-04-02T09:26:45.198Z" }, + { url = "https://files.pythonhosted.org/packages/2e/4e/b7f84e617b4854ade48a1b7915c8ccfadeba444d2a18c291f696e37f0d3b/charset_normalizer-3.4.7-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:0ea948db76d31190bf08bd371623927ee1339d5f2a0b4b1b4a4439a65298703c", size = 207008, upload-time = "2026-04-02T09:26:46.824Z" }, + { url = "https://files.pythonhosted.org/packages/c4/bb/ec73c0257c9e11b268f018f068f5d00aa0ef8c8b09f7753ebd5f2880e248/charset_normalizer-3.4.7-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:a277ab8928b9f299723bc1a2dabb1265911b1a76341f90a510368ca44ad9ab66", size = 228303, upload-time = "2026-04-02T09:26:48.397Z" }, + { url = "https://files.pythonhosted.org/packages/85/fb/32d1f5033484494619f701e719429c69b766bfc4dbc61aa9e9c8c166528b/charset_normalizer-3.4.7-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:3bec022aec2c514d9cf199522a802bd007cd588ab17ab2525f20f9c34d067c18", size = 224282, upload-time = "2026-04-02T09:26:49.684Z" }, + { url = "https://files.pythonhosted.org/packages/fa/07/330e3a0dda4c404d6da83b327270906e9654a24f6c546dc886a0eb0ffb23/charset_normalizer-3.4.7-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:e044c39e41b92c845bc815e5ae4230804e8e7bc29e399b0437d64222d92809dd", size = 215595, upload-time = "2026-04-02T09:26:50.915Z" }, + { url = "https://files.pythonhosted.org/packages/e3/7c/fc890655786e423f02556e0216d4b8c6bcb6bdfa890160dc66bf52dee468/charset_normalizer-3.4.7-cp313-cp313-manylinux_2_31_armv7l.whl", hash = "sha256:f495a1652cf3fbab2eb0639776dad966c2fb874d79d87ca07f9d5f059b8bd215", size = 201986, upload-time = "2026-04-02T09:26:52.197Z" }, + { url = "https://files.pythonhosted.org/packages/d8/97/bfb18b3db2aed3b90cf54dc292ad79fdd5ad65c4eae454099475cbeadd0d/charset_normalizer-3.4.7-cp313-cp313-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:e712b419df8ba5e42b226c510472b37bd57b38e897d3eca5e8cfd410a29fa859", size = 211711, upload-time = "2026-04-02T09:26:53.49Z" }, + { url = "https://files.pythonhosted.org/packages/6f/a5/a581c13798546a7fd557c82614a5c65a13df2157e9ad6373166d2a3e645d/charset_normalizer-3.4.7-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:7804338df6fcc08105c7745f1502ba68d900f45fd770d5bdd5288ddccb8a42d8", size = 210036, upload-time = "2026-04-02T09:26:54.975Z" }, + { url = "https://files.pythonhosted.org/packages/8c/bf/b3ab5bcb478e4193d517644b0fb2bf5497fbceeaa7a1bc0f4d5b50953861/charset_normalizer-3.4.7-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:481551899c856c704d58119b5025793fa6730adda3571971af568f66d2424bb5", size = 202998, upload-time = "2026-04-02T09:26:56.303Z" }, + { url = "https://files.pythonhosted.org/packages/e7/4e/23efd79b65d314fa320ec6017b4b5834d5c12a58ba4610aa353af2e2f577/charset_normalizer-3.4.7-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:f59099f9b66f0d7145115e6f80dd8b1d847176df89b234a5a6b3f00437aa0832", size = 230056, upload-time = "2026-04-02T09:26:57.554Z" }, + { url = "https://files.pythonhosted.org/packages/b9/9f/1e1941bc3f0e01df116e68dc37a55c4d249df5e6fa77f008841aef68264f/charset_normalizer-3.4.7-cp313-cp313-musllinux_1_2_riscv64.whl", hash = "sha256:f59ad4c0e8f6bba240a9bb85504faa1ab438237199d4cce5f622761507b8f6a6", size = 211537, upload-time = "2026-04-02T09:26:58.843Z" }, + { url = "https://files.pythonhosted.org/packages/80/0f/088cbb3020d44428964a6c97fe1edfb1b9550396bf6d278330281e8b709c/charset_normalizer-3.4.7-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:3dedcc22d73ec993f42055eff4fcfed9318d1eeb9a6606c55892a26964964e48", size = 226176, upload-time = "2026-04-02T09:27:00.437Z" }, + { url = "https://files.pythonhosted.org/packages/6a/9f/130394f9bbe06f4f63e22641d32fc9b202b7e251c9aef4db044324dac493/charset_normalizer-3.4.7-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:64f02c6841d7d83f832cd97ccf8eb8a906d06eb95d5276069175c696b024b60a", size = 217723, upload-time = "2026-04-02T09:27:02.021Z" }, + { url = "https://files.pythonhosted.org/packages/73/55/c469897448a06e49f8fa03f6caae97074fde823f432a98f979cc42b90e69/charset_normalizer-3.4.7-cp313-cp313-win32.whl", hash = "sha256:4042d5c8f957e15221d423ba781e85d553722fc4113f523f2feb7b188cc34c5e", size = 148085, upload-time = "2026-04-02T09:27:03.192Z" }, + { url = "https://files.pythonhosted.org/packages/5d/78/1b74c5bbb3f99b77a1715c91b3e0b5bdb6fe302d95ace4f5b1bec37b0167/charset_normalizer-3.4.7-cp313-cp313-win_amd64.whl", hash = "sha256:3946fa46a0cf3e4c8cb1cc52f56bb536310d34f25f01ca9b6c16afa767dab110", size = 158819, upload-time = "2026-04-02T09:27:04.454Z" }, + { url = "https://files.pythonhosted.org/packages/68/86/46bd42279d323deb8687c4a5a811fd548cb7d1de10cf6535d099877a9a9f/charset_normalizer-3.4.7-cp313-cp313-win_arm64.whl", hash = "sha256:80d04837f55fc81da168b98de4f4b797ef007fc8a79ab71c6ec9bc4dd662b15b", size = 147915, upload-time = "2026-04-02T09:27:05.971Z" }, + { url = "https://files.pythonhosted.org/packages/97/c8/c67cb8c70e19ef1960b97b22ed2a1567711de46c4ddf19799923adc836c2/charset_normalizer-3.4.7-cp314-cp314-macosx_10_15_universal2.whl", hash = "sha256:c36c333c39be2dbca264d7803333c896ab8fa7d4d6f0ab7edb7dfd7aea6e98c0", size = 309234, upload-time = "2026-04-02T09:27:07.194Z" }, + { url = "https://files.pythonhosted.org/packages/99/85/c091fdee33f20de70d6c8b522743b6f831a2f1cd3ff86de4c6a827c48a76/charset_normalizer-3.4.7-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:1c2aed2e5e41f24ea8ef1590b8e848a79b56f3a5564a65ceec43c9d692dc7d8a", size = 208042, upload-time = "2026-04-02T09:27:08.749Z" }, + { url = "https://files.pythonhosted.org/packages/87/1c/ab2ce611b984d2fd5d86a5a8a19c1ae26acac6bad967da4967562c75114d/charset_normalizer-3.4.7-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:54523e136b8948060c0fa0bc7b1b50c32c186f2fceee897a495406bb6e311d2b", size = 228706, upload-time = "2026-04-02T09:27:09.951Z" }, + { url = "https://files.pythonhosted.org/packages/a8/29/2b1d2cb00bf085f59d29eb773ce58ec2d325430f8c216804a0a5cd83cbca/charset_normalizer-3.4.7-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:715479b9a2802ecac752a3b0efa2b0b60285cf962ee38414211abdfccc233b41", size = 224727, upload-time = "2026-04-02T09:27:11.175Z" }, + { url = "https://files.pythonhosted.org/packages/47/5c/032c2d5a07fe4d4855fea851209cca2b6f03ebeb6d4e3afdb3358386a684/charset_normalizer-3.4.7-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:bd6c2a1c7573c64738d716488d2cdd3c00e340e4835707d8fdb8dc1a66ef164e", size = 215882, upload-time = "2026-04-02T09:27:12.446Z" }, + { url = "https://files.pythonhosted.org/packages/2c/c2/356065d5a8b78ed04499cae5f339f091946a6a74f91e03476c33f0ab7100/charset_normalizer-3.4.7-cp314-cp314-manylinux_2_31_armv7l.whl", hash = "sha256:c45e9440fb78f8ddabcf714b68f936737a121355bf59f3907f4e17721b9d1aae", size = 200860, upload-time = "2026-04-02T09:27:13.721Z" }, + { url = "https://files.pythonhosted.org/packages/0c/cd/a32a84217ced5039f53b29f460962abb2d4420def55afabe45b1c3c7483d/charset_normalizer-3.4.7-cp314-cp314-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:3534e7dcbdcf757da6b85a0bbf5b6868786d5982dd959b065e65481644817a18", size = 211564, upload-time = "2026-04-02T09:27:15.272Z" }, + { url = "https://files.pythonhosted.org/packages/44/86/58e6f13ce26cc3b8f4a36b94a0f22ae2f00a72534520f4ae6857c4b81f89/charset_normalizer-3.4.7-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:e8ac484bf18ce6975760921bb6148041faa8fef0547200386ea0b52b5d27bf7b", size = 211276, upload-time = "2026-04-02T09:27:16.834Z" }, + { url = "https://files.pythonhosted.org/packages/8f/fe/d17c32dc72e17e155e06883efa84514ca375f8a528ba2546bee73fc4df81/charset_normalizer-3.4.7-cp314-cp314-musllinux_1_2_armv7l.whl", hash = "sha256:a5fe03b42827c13cdccd08e6c0247b6a6d4b5e3cdc53fd1749f5896adcdc2356", size = 201238, upload-time = "2026-04-02T09:27:18.229Z" }, + { url = "https://files.pythonhosted.org/packages/6a/29/f33daa50b06525a237451cdb6c69da366c381a3dadcd833fa5676bc468b3/charset_normalizer-3.4.7-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:2d6eb928e13016cea4f1f21d1e10c1cebd5a421bc57ddf5b1142ae3f86824fab", size = 230189, upload-time = "2026-04-02T09:27:19.445Z" }, + { url = "https://files.pythonhosted.org/packages/b6/6e/52c84015394a6a0bdcd435210a7e944c5f94ea1055f5cc5d56c5fe368e7b/charset_normalizer-3.4.7-cp314-cp314-musllinux_1_2_riscv64.whl", hash = "sha256:e74327fb75de8986940def6e8dee4f127cc9752bee7355bb323cc5b2659b6d46", size = 211352, upload-time = "2026-04-02T09:27:20.79Z" }, + { url = "https://files.pythonhosted.org/packages/8c/d7/4353be581b373033fb9198bf1da3cf8f09c1082561e8e922aa7b39bf9fe8/charset_normalizer-3.4.7-cp314-cp314-musllinux_1_2_s390x.whl", hash = "sha256:d6038d37043bced98a66e68d3aa2b6a35505dc01328cd65217cefe82f25def44", size = 227024, upload-time = "2026-04-02T09:27:22.063Z" }, + { url = "https://files.pythonhosted.org/packages/30/45/99d18aa925bd1740098ccd3060e238e21115fffbfdcb8f3ece837d0ace6c/charset_normalizer-3.4.7-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:7579e913a5339fb8fa133f6bbcfd8e6749696206cf05acdbdca71a1b436d8e72", size = 217869, upload-time = "2026-04-02T09:27:23.486Z" }, + { url = "https://files.pythonhosted.org/packages/5c/05/5ee478aa53f4bb7996482153d4bfe1b89e0f087f0ab6b294fcf92d595873/charset_normalizer-3.4.7-cp314-cp314-win32.whl", hash = "sha256:5b77459df20e08151cd6f8b9ef8ef1f961ef73d85c21a555c7eed5b79410ec10", size = 148541, upload-time = "2026-04-02T09:27:25.146Z" }, + { url = "https://files.pythonhosted.org/packages/48/77/72dcb0921b2ce86420b2d79d454c7022bf5be40202a2a07906b9f2a35c97/charset_normalizer-3.4.7-cp314-cp314-win_amd64.whl", hash = "sha256:92a0a01ead5e668468e952e4238cccd7c537364eb7d851ab144ab6627dbbe12f", size = 159634, upload-time = "2026-04-02T09:27:26.642Z" }, + { url = "https://files.pythonhosted.org/packages/c6/a3/c2369911cd72f02386e4e340770f6e158c7980267da16af8f668217abaa0/charset_normalizer-3.4.7-cp314-cp314-win_arm64.whl", hash = "sha256:67f6279d125ca0046a7fd386d01b311c6363844deac3e5b069b514ba3e63c246", size = 148384, upload-time = "2026-04-02T09:27:28.271Z" }, + { url = "https://files.pythonhosted.org/packages/94/09/7e8a7f73d24dba1f0035fbbf014d2c36828fc1bf9c88f84093e57d315935/charset_normalizer-3.4.7-cp314-cp314t-macosx_10_15_universal2.whl", hash = "sha256:effc3f449787117233702311a1b7d8f59cba9ced946ba727bdc329ec69028e24", size = 330133, upload-time = "2026-04-02T09:27:29.474Z" }, + { url = "https://files.pythonhosted.org/packages/8d/da/96975ddb11f8e977f706f45cddd8540fd8242f71ecdb5d18a80723dcf62c/charset_normalizer-3.4.7-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:fbccdc05410c9ee21bbf16a35f4c1d16123dcdeb8a1d38f33654fa21d0234f79", size = 216257, upload-time = "2026-04-02T09:27:30.793Z" }, + { url = "https://files.pythonhosted.org/packages/e5/e8/1d63bf8ef2d388e95c64b2098f45f84758f6d102a087552da1485912637b/charset_normalizer-3.4.7-cp314-cp314t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:733784b6d6def852c814bce5f318d25da2ee65dd4839a0718641c696e09a2960", size = 234851, upload-time = "2026-04-02T09:27:32.44Z" }, + { url = "https://files.pythonhosted.org/packages/9b/40/e5ff04233e70da2681fa43969ad6f66ca5611d7e669be0246c4c7aaf6dc8/charset_normalizer-3.4.7-cp314-cp314t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:a89c23ef8d2c6b27fd200a42aa4ac72786e7c60d40efdc76e6011260b6e949c4", size = 233393, upload-time = "2026-04-02T09:27:34.03Z" }, + { url = "https://files.pythonhosted.org/packages/be/c1/06c6c49d5a5450f76899992f1ee40b41d076aee9279b49cf9974d2f313d5/charset_normalizer-3.4.7-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:6c114670c45346afedc0d947faf3c7f701051d2518b943679c8ff88befe14f8e", size = 223251, upload-time = "2026-04-02T09:27:35.369Z" }, + { url = "https://files.pythonhosted.org/packages/2b/9f/f2ff16fb050946169e3e1f82134d107e5d4ae72647ec8a1b1446c148480f/charset_normalizer-3.4.7-cp314-cp314t-manylinux_2_31_armv7l.whl", hash = "sha256:a180c5e59792af262bf263b21a3c49353f25945d8d9f70628e73de370d55e1e1", size = 206609, upload-time = "2026-04-02T09:27:36.661Z" }, + { url = "https://files.pythonhosted.org/packages/69/d5/a527c0cd8d64d2eab7459784fb4169a0ac76e5a6fc5237337982fd61347e/charset_normalizer-3.4.7-cp314-cp314t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:3c9a494bc5ec77d43cea229c4f6db1e4d8fe7e1bbffa8b6f0f0032430ff8ab44", size = 220014, upload-time = "2026-04-02T09:27:38.019Z" }, + { url = "https://files.pythonhosted.org/packages/7e/80/8a7b8104a3e203074dc9aa2c613d4b726c0e136bad1cc734594b02867972/charset_normalizer-3.4.7-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:8d828b6667a32a728a1ad1d93957cdf37489c57b97ae6c4de2860fa749b8fc1e", size = 218979, upload-time = "2026-04-02T09:27:39.37Z" }, + { url = "https://files.pythonhosted.org/packages/02/9a/b759b503d507f375b2b5c153e4d2ee0a75aa215b7f2489cf314f4541f2c0/charset_normalizer-3.4.7-cp314-cp314t-musllinux_1_2_armv7l.whl", hash = "sha256:cf1493cd8607bec4d8a7b9b004e699fcf8f9103a9284cc94962cb73d20f9d4a3", size = 209238, upload-time = "2026-04-02T09:27:40.722Z" }, + { url = "https://files.pythonhosted.org/packages/c2/4e/0f3f5d47b86bdb79256e7290b26ac847a2832d9a4033f7eb2cd4bcf4bb5b/charset_normalizer-3.4.7-cp314-cp314t-musllinux_1_2_ppc64le.whl", hash = "sha256:0c96c3b819b5c3e9e165495db84d41914d6894d55181d2d108cc1a69bfc9cce0", size = 236110, upload-time = "2026-04-02T09:27:42.33Z" }, + { url = "https://files.pythonhosted.org/packages/96/23/bce28734eb3ed2c91dcf93abeb8a5cf393a7b2749725030bb630e554fdd8/charset_normalizer-3.4.7-cp314-cp314t-musllinux_1_2_riscv64.whl", hash = "sha256:752a45dc4a6934060b3b0dab47e04edc3326575f82be64bc4fc293914566503e", size = 219824, upload-time = "2026-04-02T09:27:43.924Z" }, + { url = "https://files.pythonhosted.org/packages/2c/6f/6e897c6984cc4d41af319b077f2f600fc8214eb2fe2d6bcb79141b882400/charset_normalizer-3.4.7-cp314-cp314t-musllinux_1_2_s390x.whl", hash = "sha256:8778f0c7a52e56f75d12dae53ae320fae900a8b9b4164b981b9c5ce059cd1fcb", size = 233103, upload-time = "2026-04-02T09:27:45.348Z" }, + { url = "https://files.pythonhosted.org/packages/76/22/ef7bd0fe480a0ae9b656189ec00744b60933f68b4f42a7bb06589f6f576a/charset_normalizer-3.4.7-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:ce3412fbe1e31eb81ea42f4169ed94861c56e643189e1e75f0041f3fe7020abe", size = 225194, upload-time = "2026-04-02T09:27:46.706Z" }, + { url = "https://files.pythonhosted.org/packages/c5/a7/0e0ab3e0b5bc1219bd80a6a0d4d72ca74d9250cb2382b7c699c147e06017/charset_normalizer-3.4.7-cp314-cp314t-win32.whl", hash = "sha256:c03a41a8784091e67a39648f70c5f97b5b6a37f216896d44d2cdcb82615339a0", size = 159827, upload-time = "2026-04-02T09:27:48.053Z" }, + { url = "https://files.pythonhosted.org/packages/7a/1d/29d32e0fb40864b1f878c7f5a0b343ae676c6e2b271a2d55cc3a152391da/charset_normalizer-3.4.7-cp314-cp314t-win_amd64.whl", hash = "sha256:03853ed82eeebbce3c2abfdbc98c96dc205f32a79627688ac9a27370ea61a49c", size = 174168, upload-time = "2026-04-02T09:27:49.795Z" }, + { url = "https://files.pythonhosted.org/packages/de/32/d92444ad05c7a6e41fb2036749777c163baf7a0301a040cb672d6b2b1ae9/charset_normalizer-3.4.7-cp314-cp314t-win_arm64.whl", hash = "sha256:c35abb8bfff0185efac5878da64c45dafd2b37fb0383add1be155a763c1f083d", size = 153018, upload-time = "2026-04-02T09:27:51.116Z" }, + { url = "https://files.pythonhosted.org/packages/db/8f/61959034484a4a7c527811f4721e75d02d653a35afb0b6054474d8185d4c/charset_normalizer-3.4.7-py3-none-any.whl", hash = "sha256:3dce51d0f5e7951f8bb4900c257dad282f49190fdbebecd4ba99bcc41fef404d", size = 61958, upload-time = "2026-04-02T09:28:37.794Z" }, +] + +[[package]] +name = "click" +version = "8.3.2" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "colorama", marker = "sys_platform == 'win32'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/57/75/31212c6bf2503fdf920d87fee5d7a86a2e3bcf444984126f13d8e4016804/click-8.3.2.tar.gz", hash = "sha256:14162b8b3b3550a7d479eafa77dfd3c38d9dc8951f6f69c78913a8f9a7540fd5", size = 302856, upload-time = "2026-04-03T19:14:45.118Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/e4/20/71885d8b97d4f3dde17b1fdb92dbd4908b00541c5a3379787137285f602e/click-8.3.2-py3-none-any.whl", hash = "sha256:1924d2c27c5653561cd2cae4548d1406039cb79b858b747cfea24924bbc1616d", size = 108379, upload-time = "2026-04-03T19:14:43.505Z" }, +] + +[[package]] +name = "colorama" +version = "0.4.6" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/d8/53/6f443c9a4a8358a93a6792e2acffb9d9d5cb0a5cfd8802644b7b1c9a02e4/colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44", size = 27697, upload-time = "2022-10-25T02:36:22.414Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/d1/d6/3965ed04c63042e047cb6a3e6ed1a63a35087b6a609aa3a15ed8ac56c221/colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6", size = 25335, upload-time = "2022-10-25T02:36:20.889Z" }, +] + +[[package]] +name = "comm" +version = "0.2.3" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/4c/13/7d740c5849255756bc17888787313b61fd38a0a8304fc4f073dfc46122aa/comm-0.2.3.tar.gz", hash = "sha256:2dc8048c10962d55d7ad693be1e7045d891b7ce8d999c97963a5e3e99c055971", size = 6319, upload-time = "2025-07-25T14:02:04.452Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/60/97/891a0971e1e4a8c5d2b20bbe0e524dc04548d2307fee33cdeba148fd4fc7/comm-0.2.3-py3-none-any.whl", hash = "sha256:c615d91d75f7f04f095b30d1c1711babd43bdc6419c1be9886a85f2f4e489417", size = 7294, upload-time = "2025-07-25T14:02:02.896Z" }, +] + +[[package]] +name = "contourpy" +version = "1.3.3" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "numpy" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/58/01/1253e6698a07380cd31a736d248a3f2a50a7c88779a1813da27503cadc2a/contourpy-1.3.3.tar.gz", hash = "sha256:083e12155b210502d0bca491432bb04d56dc3432f95a979b429f2848c3dbe880", size = 13466174, upload-time = "2025-07-26T12:03:12.549Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/68/35/0167aad910bbdb9599272bd96d01a9ec6852f36b9455cf2ca67bd4cc2d23/contourpy-1.3.3-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:177fb367556747a686509d6fef71d221a4b198a3905fe824430e5ea0fda54eb5", size = 293257, upload-time = "2025-07-26T12:01:39.367Z" }, + { url = "https://files.pythonhosted.org/packages/96/e4/7adcd9c8362745b2210728f209bfbcf7d91ba868a2c5f40d8b58f54c509b/contourpy-1.3.3-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:d002b6f00d73d69333dac9d0b8d5e84d9724ff9ef044fd63c5986e62b7c9e1b1", size = 274034, upload-time = "2025-07-26T12:01:40.645Z" }, + { url = "https://files.pythonhosted.org/packages/73/23/90e31ceeed1de63058a02cb04b12f2de4b40e3bef5e082a7c18d9c8ae281/contourpy-1.3.3-cp313-cp313-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:348ac1f5d4f1d66d3322420f01d42e43122f43616e0f194fc1c9f5d830c5b286", size = 334672, upload-time = "2025-07-26T12:01:41.942Z" }, + { url = "https://files.pythonhosted.org/packages/ed/93/b43d8acbe67392e659e1d984700e79eb67e2acb2bd7f62012b583a7f1b55/contourpy-1.3.3-cp313-cp313-manylinux_2_26_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:655456777ff65c2c548b7c454af9c6f33f16c8884f11083244b5819cc214f1b5", size = 381234, upload-time = "2025-07-26T12:01:43.499Z" }, + { url = "https://files.pythonhosted.org/packages/46/3b/bec82a3ea06f66711520f75a40c8fc0b113b2a75edb36aa633eb11c4f50f/contourpy-1.3.3-cp313-cp313-manylinux_2_26_s390x.manylinux_2_28_s390x.whl", hash = "sha256:644a6853d15b2512d67881586bd03f462c7ab755db95f16f14d7e238f2852c67", size = 385169, upload-time = "2025-07-26T12:01:45.219Z" }, + { url = "https://files.pythonhosted.org/packages/4b/32/e0f13a1c5b0f8572d0ec6ae2f6c677b7991fafd95da523159c19eff0696a/contourpy-1.3.3-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:4debd64f124ca62069f313a9cb86656ff087786016d76927ae2cf37846b006c9", size = 362859, upload-time = "2025-07-26T12:01:46.519Z" }, + { url = "https://files.pythonhosted.org/packages/33/71/e2a7945b7de4e58af42d708a219f3b2f4cff7386e6b6ab0a0fa0033c49a9/contourpy-1.3.3-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:a15459b0f4615b00bbd1e91f1b9e19b7e63aea7483d03d804186f278c0af2659", size = 1332062, upload-time = "2025-07-26T12:01:48.964Z" }, + { url = "https://files.pythonhosted.org/packages/12/fc/4e87ac754220ccc0e807284f88e943d6d43b43843614f0a8afa469801db0/contourpy-1.3.3-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:ca0fdcd73925568ca027e0b17ab07aad764be4706d0a925b89227e447d9737b7", size = 1403932, upload-time = "2025-07-26T12:01:51.979Z" }, + { url = "https://files.pythonhosted.org/packages/a6/2e/adc197a37443f934594112222ac1aa7dc9a98faf9c3842884df9a9d8751d/contourpy-1.3.3-cp313-cp313-win32.whl", hash = "sha256:b20c7c9a3bf701366556e1b1984ed2d0cedf999903c51311417cf5f591d8c78d", size = 185024, upload-time = "2025-07-26T12:01:53.245Z" }, + { url = "https://files.pythonhosted.org/packages/18/0b/0098c214843213759692cc638fce7de5c289200a830e5035d1791d7a2338/contourpy-1.3.3-cp313-cp313-win_amd64.whl", hash = "sha256:1cadd8b8969f060ba45ed7c1b714fe69185812ab43bd6b86a9123fe8f99c3263", size = 226578, upload-time = "2025-07-26T12:01:54.422Z" }, + { url = "https://files.pythonhosted.org/packages/8a/9a/2f6024a0c5995243cd63afdeb3651c984f0d2bc727fd98066d40e141ad73/contourpy-1.3.3-cp313-cp313-win_arm64.whl", hash = "sha256:fd914713266421b7536de2bfa8181aa8c699432b6763a0ea64195ebe28bff6a9", size = 193524, upload-time = "2025-07-26T12:01:55.73Z" }, + { url = "https://files.pythonhosted.org/packages/c0/b3/f8a1a86bd3298513f500e5b1f5fd92b69896449f6cab6a146a5d52715479/contourpy-1.3.3-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:88df9880d507169449d434c293467418b9f6cbe82edd19284aa0409e7fdb933d", size = 306730, upload-time = "2025-07-26T12:01:57.051Z" }, + { url = "https://files.pythonhosted.org/packages/3f/11/4780db94ae62fc0c2053909b65dc3246bd7cecfc4f8a20d957ad43aa4ad8/contourpy-1.3.3-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:d06bb1f751ba5d417047db62bca3c8fde202b8c11fb50742ab3ab962c81e8216", size = 287897, upload-time = "2025-07-26T12:01:58.663Z" }, + { url = "https://files.pythonhosted.org/packages/ae/15/e59f5f3ffdd6f3d4daa3e47114c53daabcb18574a26c21f03dc9e4e42ff0/contourpy-1.3.3-cp313-cp313t-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:e4e6b05a45525357e382909a4c1600444e2a45b4795163d3b22669285591c1ae", size = 326751, upload-time = "2025-07-26T12:02:00.343Z" }, + { url = "https://files.pythonhosted.org/packages/0f/81/03b45cfad088e4770b1dcf72ea78d3802d04200009fb364d18a493857210/contourpy-1.3.3-cp313-cp313t-manylinux_2_26_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:ab3074b48c4e2cf1a960e6bbeb7f04566bf36b1861d5c9d4d8ac04b82e38ba20", size = 375486, upload-time = "2025-07-26T12:02:02.128Z" }, + { url = "https://files.pythonhosted.org/packages/0c/ba/49923366492ffbdd4486e970d421b289a670ae8cf539c1ea9a09822b371a/contourpy-1.3.3-cp313-cp313t-manylinux_2_26_s390x.manylinux_2_28_s390x.whl", hash = "sha256:6c3d53c796f8647d6deb1abe867daeb66dcc8a97e8455efa729516b997b8ed99", size = 388106, upload-time = "2025-07-26T12:02:03.615Z" }, + { url = "https://files.pythonhosted.org/packages/9f/52/5b00ea89525f8f143651f9f03a0df371d3cbd2fccd21ca9b768c7a6500c2/contourpy-1.3.3-cp313-cp313t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:50ed930df7289ff2a8d7afeb9603f8289e5704755c7e5c3bbd929c90c817164b", size = 352548, upload-time = "2025-07-26T12:02:05.165Z" }, + { url = "https://files.pythonhosted.org/packages/32/1d/a209ec1a3a3452d490f6b14dd92e72280c99ae3d1e73da74f8277d4ee08f/contourpy-1.3.3-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:4feffb6537d64b84877da813a5c30f1422ea5739566abf0bd18065ac040e120a", size = 1322297, upload-time = "2025-07-26T12:02:07.379Z" }, + { url = "https://files.pythonhosted.org/packages/bc/9e/46f0e8ebdd884ca0e8877e46a3f4e633f6c9c8c4f3f6e72be3fe075994aa/contourpy-1.3.3-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:2b7e9480ffe2b0cd2e787e4df64270e3a0440d9db8dc823312e2c940c167df7e", size = 1391023, upload-time = "2025-07-26T12:02:10.171Z" }, + { url = "https://files.pythonhosted.org/packages/b9/70/f308384a3ae9cd2209e0849f33c913f658d3326900d0ff5d378d6a1422d2/contourpy-1.3.3-cp313-cp313t-win32.whl", hash = "sha256:283edd842a01e3dcd435b1c5116798d661378d83d36d337b8dde1d16a5fc9ba3", size = 196157, upload-time = "2025-07-26T12:02:11.488Z" }, + { url = "https://files.pythonhosted.org/packages/b2/dd/880f890a6663b84d9e34a6f88cded89d78f0091e0045a284427cb6b18521/contourpy-1.3.3-cp313-cp313t-win_amd64.whl", hash = "sha256:87acf5963fc2b34825e5b6b048f40e3635dd547f590b04d2ab317c2619ef7ae8", size = 240570, upload-time = "2025-07-26T12:02:12.754Z" }, + { url = "https://files.pythonhosted.org/packages/80/99/2adc7d8ffead633234817ef8e9a87115c8a11927a94478f6bb3d3f4d4f7d/contourpy-1.3.3-cp313-cp313t-win_arm64.whl", hash = "sha256:3c30273eb2a55024ff31ba7d052dde990d7d8e5450f4bbb6e913558b3d6c2301", size = 199713, upload-time = "2025-07-26T12:02:14.4Z" }, + { url = "https://files.pythonhosted.org/packages/72/8b/4546f3ab60f78c514ffb7d01a0bd743f90de36f0019d1be84d0a708a580a/contourpy-1.3.3-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:fde6c716d51c04b1c25d0b90364d0be954624a0ee9d60e23e850e8d48353d07a", size = 292189, upload-time = "2025-07-26T12:02:16.095Z" }, + { url = "https://files.pythonhosted.org/packages/fd/e1/3542a9cb596cadd76fcef413f19c79216e002623158befe6daa03dbfa88c/contourpy-1.3.3-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:cbedb772ed74ff5be440fa8eee9bd49f64f6e3fc09436d9c7d8f1c287b121d77", size = 273251, upload-time = "2025-07-26T12:02:17.524Z" }, + { url = "https://files.pythonhosted.org/packages/b1/71/f93e1e9471d189f79d0ce2497007731c1e6bf9ef6d1d61b911430c3db4e5/contourpy-1.3.3-cp314-cp314-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:22e9b1bd7a9b1d652cd77388465dc358dafcd2e217d35552424aa4f996f524f5", size = 335810, upload-time = "2025-07-26T12:02:18.9Z" }, + { url = "https://files.pythonhosted.org/packages/91/f9/e35f4c1c93f9275d4e38681a80506b5510e9327350c51f8d4a5a724d178c/contourpy-1.3.3-cp314-cp314-manylinux_2_26_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:a22738912262aa3e254e4f3cb079a95a67132fc5a063890e224393596902f5a4", size = 382871, upload-time = "2025-07-26T12:02:20.418Z" }, + { url = "https://files.pythonhosted.org/packages/b5/71/47b512f936f66a0a900d81c396a7e60d73419868fba959c61efed7a8ab46/contourpy-1.3.3-cp314-cp314-manylinux_2_26_s390x.manylinux_2_28_s390x.whl", hash = "sha256:afe5a512f31ee6bd7d0dda52ec9864c984ca3d66664444f2d72e0dc4eb832e36", size = 386264, upload-time = "2025-07-26T12:02:21.916Z" }, + { url = "https://files.pythonhosted.org/packages/04/5f/9ff93450ba96b09c7c2b3f81c94de31c89f92292f1380261bd7195bea4ea/contourpy-1.3.3-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:f64836de09927cba6f79dcd00fdd7d5329f3fccc633468507079c829ca4db4e3", size = 363819, upload-time = "2025-07-26T12:02:23.759Z" }, + { url = "https://files.pythonhosted.org/packages/3e/a6/0b185d4cc480ee494945cde102cb0149ae830b5fa17bf855b95f2e70ad13/contourpy-1.3.3-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:1fd43c3be4c8e5fd6e4f2baeae35ae18176cf2e5cced681cca908addf1cdd53b", size = 1333650, upload-time = "2025-07-26T12:02:26.181Z" }, + { url = "https://files.pythonhosted.org/packages/43/d7/afdc95580ca56f30fbcd3060250f66cedbde69b4547028863abd8aa3b47e/contourpy-1.3.3-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:6afc576f7b33cf00996e5c1102dc2a8f7cc89e39c0b55df93a0b78c1bd992b36", size = 1404833, upload-time = "2025-07-26T12:02:28.782Z" }, + { url = "https://files.pythonhosted.org/packages/e2/e2/366af18a6d386f41132a48f033cbd2102e9b0cf6345d35ff0826cd984566/contourpy-1.3.3-cp314-cp314-win32.whl", hash = "sha256:66c8a43a4f7b8df8b71ee1840e4211a3c8d93b214b213f590e18a1beca458f7d", size = 189692, upload-time = "2025-07-26T12:02:30.128Z" }, + { url = "https://files.pythonhosted.org/packages/7d/c2/57f54b03d0f22d4044b8afb9ca0e184f8b1afd57b4f735c2fa70883dc601/contourpy-1.3.3-cp314-cp314-win_amd64.whl", hash = "sha256:cf9022ef053f2694e31d630feaacb21ea24224be1c3ad0520b13d844274614fd", size = 232424, upload-time = "2025-07-26T12:02:31.395Z" }, + { url = "https://files.pythonhosted.org/packages/18/79/a9416650df9b525737ab521aa181ccc42d56016d2123ddcb7b58e926a42c/contourpy-1.3.3-cp314-cp314-win_arm64.whl", hash = "sha256:95b181891b4c71de4bb404c6621e7e2390745f887f2a026b2d99e92c17892339", size = 198300, upload-time = "2025-07-26T12:02:32.956Z" }, + { url = "https://files.pythonhosted.org/packages/1f/42/38c159a7d0f2b7b9c04c64ab317042bb6952b713ba875c1681529a2932fe/contourpy-1.3.3-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:33c82d0138c0a062380332c861387650c82e4cf1747aaa6938b9b6516762e772", size = 306769, upload-time = "2025-07-26T12:02:34.2Z" }, + { url = "https://files.pythonhosted.org/packages/c3/6c/26a8205f24bca10974e77460de68d3d7c63e282e23782f1239f226fcae6f/contourpy-1.3.3-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:ea37e7b45949df430fe649e5de8351c423430046a2af20b1c1961cae3afcda77", size = 287892, upload-time = "2025-07-26T12:02:35.807Z" }, + { url = "https://files.pythonhosted.org/packages/66/06/8a475c8ab718ebfd7925661747dbb3c3ee9c82ac834ccb3570be49d129f4/contourpy-1.3.3-cp314-cp314t-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:d304906ecc71672e9c89e87c4675dc5c2645e1f4269a5063b99b0bb29f232d13", size = 326748, upload-time = "2025-07-26T12:02:37.193Z" }, + { url = "https://files.pythonhosted.org/packages/b4/a3/c5ca9f010a44c223f098fccd8b158bb1cb287378a31ac141f04730dc49be/contourpy-1.3.3-cp314-cp314t-manylinux_2_26_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:ca658cd1a680a5c9ea96dc61cdbae1e85c8f25849843aa799dfd3cb370ad4fbe", size = 375554, upload-time = "2025-07-26T12:02:38.894Z" }, + { url = "https://files.pythonhosted.org/packages/80/5b/68bd33ae63fac658a4145088c1e894405e07584a316738710b636c6d0333/contourpy-1.3.3-cp314-cp314t-manylinux_2_26_s390x.manylinux_2_28_s390x.whl", hash = "sha256:ab2fd90904c503739a75b7c8c5c01160130ba67944a7b77bbf36ef8054576e7f", size = 388118, upload-time = "2025-07-26T12:02:40.642Z" }, + { url = "https://files.pythonhosted.org/packages/40/52/4c285a6435940ae25d7410a6c36bda5145839bc3f0beb20c707cda18b9d2/contourpy-1.3.3-cp314-cp314t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:b7301b89040075c30e5768810bc96a8e8d78085b47d8be6e4c3f5a0b4ed478a0", size = 352555, upload-time = "2025-07-26T12:02:42.25Z" }, + { url = "https://files.pythonhosted.org/packages/24/ee/3e81e1dd174f5c7fefe50e85d0892de05ca4e26ef1c9a59c2a57e43b865a/contourpy-1.3.3-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:2a2a8b627d5cc6b7c41a4beff6c5ad5eb848c88255fda4a8745f7e901b32d8e4", size = 1322295, upload-time = "2025-07-26T12:02:44.668Z" }, + { url = "https://files.pythonhosted.org/packages/3c/b2/6d913d4d04e14379de429057cd169e5e00f6c2af3bb13e1710bcbdb5da12/contourpy-1.3.3-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:fd6ec6be509c787f1caf6b247f0b1ca598bef13f4ddeaa126b7658215529ba0f", size = 1391027, upload-time = "2025-07-26T12:02:47.09Z" }, + { url = "https://files.pythonhosted.org/packages/93/8a/68a4ec5c55a2971213d29a9374913f7e9f18581945a7a31d1a39b5d2dfe5/contourpy-1.3.3-cp314-cp314t-win32.whl", hash = "sha256:e74a9a0f5e3fff48fb5a7f2fd2b9b70a3fe014a67522f79b7cca4c0c7e43c9ae", size = 202428, upload-time = "2025-07-26T12:02:48.691Z" }, + { url = "https://files.pythonhosted.org/packages/fa/96/fd9f641ffedc4fa3ace923af73b9d07e869496c9cc7a459103e6e978992f/contourpy-1.3.3-cp314-cp314t-win_amd64.whl", hash = "sha256:13b68d6a62db8eafaebb8039218921399baf6e47bf85006fd8529f2a08ef33fc", size = 250331, upload-time = "2025-07-26T12:02:50.137Z" }, + { url = "https://files.pythonhosted.org/packages/ae/8c/469afb6465b853afff216f9528ffda78a915ff880ed58813ba4faf4ba0b6/contourpy-1.3.3-cp314-cp314t-win_arm64.whl", hash = "sha256:b7448cb5a725bb1e35ce88771b86fba35ef418952474492cf7c764059933ff8b", size = 203831, upload-time = "2025-07-26T12:02:51.449Z" }, +] + +[[package]] +name = "cryptography" +version = "46.0.7" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "cffi", marker = "platform_python_implementation != 'PyPy'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/47/93/ac8f3d5ff04d54bc814e961a43ae5b0b146154c89c61b47bb07557679b18/cryptography-46.0.7.tar.gz", hash = "sha256:e4cfd68c5f3e0bfdad0d38e023239b96a2fe84146481852dffbcca442c245aa5", size = 750652, upload-time = "2026-04-08T01:57:54.692Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/0b/5d/4a8f770695d73be252331e60e526291e3df0c9b27556a90a6b47bccca4c2/cryptography-46.0.7-cp311-abi3-macosx_10_9_universal2.whl", hash = "sha256:ea42cbe97209df307fdc3b155f1b6fa2577c0defa8f1f7d3be7d31d189108ad4", size = 7179869, upload-time = "2026-04-08T01:56:17.157Z" }, + { url = "https://files.pythonhosted.org/packages/5f/45/6d80dc379b0bbc1f9d1e429f42e4cb9e1d319c7a8201beffd967c516ea01/cryptography-46.0.7-cp311-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:b36a4695e29fe69215d75960b22577197aca3f7a25b9cf9d165dcfe9d80bc325", size = 4275492, upload-time = "2026-04-08T01:56:19.36Z" }, + { url = "https://files.pythonhosted.org/packages/4a/9a/1765afe9f572e239c3469f2cb429f3ba7b31878c893b246b4b2994ffe2fe/cryptography-46.0.7-cp311-abi3-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:5ad9ef796328c5e3c4ceed237a183f5d41d21150f972455a9d926593a1dcb308", size = 4426670, upload-time = "2026-04-08T01:56:21.415Z" }, + { url = "https://files.pythonhosted.org/packages/8f/3e/af9246aaf23cd4ee060699adab1e47ced3f5f7e7a8ffdd339f817b446462/cryptography-46.0.7-cp311-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:73510b83623e080a2c35c62c15298096e2a5dc8d51c3b4e1740211839d0dea77", size = 4280275, upload-time = "2026-04-08T01:56:23.539Z" }, + { url = "https://files.pythonhosted.org/packages/0f/54/6bbbfc5efe86f9d71041827b793c24811a017c6ac0fd12883e4caa86b8ed/cryptography-46.0.7-cp311-abi3-manylinux_2_28_ppc64le.whl", hash = "sha256:cbd5fb06b62bd0721e1170273d3f4d5a277044c47ca27ee257025146c34cbdd1", size = 4928402, upload-time = "2026-04-08T01:56:25.624Z" }, + { url = "https://files.pythonhosted.org/packages/2d/cf/054b9d8220f81509939599c8bdbc0c408dbd2bdd41688616a20731371fe0/cryptography-46.0.7-cp311-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:420b1e4109cc95f0e5700eed79908cef9268265c773d3a66f7af1eef53d409ef", size = 4459985, upload-time = "2026-04-08T01:56:27.309Z" }, + { url = "https://files.pythonhosted.org/packages/f9/46/4e4e9c6040fb01c7467d47217d2f882daddeb8828f7df800cb806d8a2288/cryptography-46.0.7-cp311-abi3-manylinux_2_31_armv7l.whl", hash = "sha256:24402210aa54baae71d99441d15bb5a1919c195398a87b563df84468160a65de", size = 3990652, upload-time = "2026-04-08T01:56:29.095Z" }, + { url = "https://files.pythonhosted.org/packages/36/5f/313586c3be5a2fbe87e4c9a254207b860155a8e1f3cca99f9910008e7d08/cryptography-46.0.7-cp311-abi3-manylinux_2_34_aarch64.whl", hash = "sha256:8a469028a86f12eb7d2fe97162d0634026d92a21f3ae0ac87ed1c4a447886c83", size = 4279805, upload-time = "2026-04-08T01:56:30.928Z" }, + { url = "https://files.pythonhosted.org/packages/69/33/60dfc4595f334a2082749673386a4d05e4f0cf4df8248e63b2c3437585f2/cryptography-46.0.7-cp311-abi3-manylinux_2_34_ppc64le.whl", hash = "sha256:9694078c5d44c157ef3162e3bf3946510b857df5a3955458381d1c7cfc143ddb", size = 4892883, upload-time = "2026-04-08T01:56:32.614Z" }, + { url = "https://files.pythonhosted.org/packages/c7/0b/333ddab4270c4f5b972f980adef4faa66951a4aaf646ca067af597f15563/cryptography-46.0.7-cp311-abi3-manylinux_2_34_x86_64.whl", hash = "sha256:42a1e5f98abb6391717978baf9f90dc28a743b7d9be7f0751a6f56a75d14065b", size = 4459756, upload-time = "2026-04-08T01:56:34.306Z" }, + { url = "https://files.pythonhosted.org/packages/d2/14/633913398b43b75f1234834170947957c6b623d1701ffc7a9600da907e89/cryptography-46.0.7-cp311-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:91bbcb08347344f810cbe49065914fe048949648f6bd5c2519f34619142bbe85", size = 4410244, upload-time = "2026-04-08T01:56:35.977Z" }, + { url = "https://files.pythonhosted.org/packages/10/f2/19ceb3b3dc14009373432af0c13f46aa08e3ce334ec6eff13492e1812ccd/cryptography-46.0.7-cp311-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:5d1c02a14ceb9148cc7816249f64f623fbfee39e8c03b3650d842ad3f34d637e", size = 4674868, upload-time = "2026-04-08T01:56:38.034Z" }, + { url = "https://files.pythonhosted.org/packages/1a/bb/a5c213c19ee94b15dfccc48f363738633a493812687f5567addbcbba9f6f/cryptography-46.0.7-cp311-abi3-win32.whl", hash = "sha256:d23c8ca48e44ee015cd0a54aeccdf9f09004eba9fc96f38c911011d9ff1bd457", size = 3026504, upload-time = "2026-04-08T01:56:39.666Z" }, + { url = "https://files.pythonhosted.org/packages/2b/02/7788f9fefa1d060ca68717c3901ae7fffa21ee087a90b7f23c7a603c32ae/cryptography-46.0.7-cp311-abi3-win_amd64.whl", hash = "sha256:397655da831414d165029da9bc483bed2fe0e75dde6a1523ec2fe63f3c46046b", size = 3488363, upload-time = "2026-04-08T01:56:41.893Z" }, + { url = "https://files.pythonhosted.org/packages/7b/56/15619b210e689c5403bb0540e4cb7dbf11a6bf42e483b7644e471a2812b3/cryptography-46.0.7-cp314-cp314t-macosx_10_9_universal2.whl", hash = "sha256:d151173275e1728cf7839aaa80c34fe550c04ddb27b34f48c232193df8db5842", size = 7119671, upload-time = "2026-04-08T01:56:44Z" }, + { url = "https://files.pythonhosted.org/packages/74/66/e3ce040721b0b5599e175ba91ab08884c75928fbeb74597dd10ef13505d2/cryptography-46.0.7-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:db0f493b9181c7820c8134437eb8b0b4792085d37dbb24da050476ccb664e59c", size = 4268551, upload-time = "2026-04-08T01:56:46.071Z" }, + { url = "https://files.pythonhosted.org/packages/03/11/5e395f961d6868269835dee1bafec6a1ac176505a167f68b7d8818431068/cryptography-46.0.7-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:ebd6daf519b9f189f85c479427bbd6e9c9037862cf8fe89ee35503bd209ed902", size = 4408887, upload-time = "2026-04-08T01:56:47.718Z" }, + { url = "https://files.pythonhosted.org/packages/40/53/8ed1cf4c3b9c8e611e7122fb56f1c32d09e1fff0f1d77e78d9ff7c82653e/cryptography-46.0.7-cp314-cp314t-manylinux_2_28_aarch64.whl", hash = "sha256:b7b412817be92117ec5ed95f880defe9cf18a832e8cafacf0a22337dc1981b4d", size = 4271354, upload-time = "2026-04-08T01:56:49.312Z" }, + { url = "https://files.pythonhosted.org/packages/50/46/cf71e26025c2e767c5609162c866a78e8a2915bbcfa408b7ca495c6140c4/cryptography-46.0.7-cp314-cp314t-manylinux_2_28_ppc64le.whl", hash = "sha256:fbfd0e5f273877695cb93baf14b185f4878128b250cc9f8e617ea0c025dfb022", size = 4905845, upload-time = "2026-04-08T01:56:50.916Z" }, + { url = "https://files.pythonhosted.org/packages/c0/ea/01276740375bac6249d0a971ebdf6b4dc9ead0ee0a34ef3b5a88c1a9b0d4/cryptography-46.0.7-cp314-cp314t-manylinux_2_28_x86_64.whl", hash = "sha256:ffca7aa1d00cf7d6469b988c581598f2259e46215e0140af408966a24cf086ce", size = 4444641, upload-time = "2026-04-08T01:56:52.882Z" }, + { url = "https://files.pythonhosted.org/packages/3d/4c/7d258f169ae71230f25d9f3d06caabcff8c3baf0978e2b7d65e0acac3827/cryptography-46.0.7-cp314-cp314t-manylinux_2_31_armv7l.whl", hash = "sha256:60627cf07e0d9274338521205899337c5d18249db56865f943cbe753aa96f40f", size = 3967749, upload-time = "2026-04-08T01:56:54.597Z" }, + { url = "https://files.pythonhosted.org/packages/b5/2a/2ea0767cad19e71b3530e4cad9605d0b5e338b6a1e72c37c9c1ceb86c333/cryptography-46.0.7-cp314-cp314t-manylinux_2_34_aarch64.whl", hash = "sha256:80406c3065e2c55d7f49a9550fe0c49b3f12e5bfff5dedb727e319e1afb9bf99", size = 4270942, upload-time = "2026-04-08T01:56:56.416Z" }, + { url = "https://files.pythonhosted.org/packages/41/3d/fe14df95a83319af25717677e956567a105bb6ab25641acaa093db79975d/cryptography-46.0.7-cp314-cp314t-manylinux_2_34_ppc64le.whl", hash = "sha256:c5b1ccd1239f48b7151a65bc6dd54bcfcc15e028c8ac126d3fada09db0e07ef1", size = 4871079, upload-time = "2026-04-08T01:56:58.31Z" }, + { url = "https://files.pythonhosted.org/packages/9c/59/4a479e0f36f8f378d397f4eab4c850b4ffb79a2f0d58704b8fa0703ddc11/cryptography-46.0.7-cp314-cp314t-manylinux_2_34_x86_64.whl", hash = "sha256:d5f7520159cd9c2154eb61eb67548ca05c5774d39e9c2c4339fd793fe7d097b2", size = 4443999, upload-time = "2026-04-08T01:57:00.508Z" }, + { url = "https://files.pythonhosted.org/packages/28/17/b59a741645822ec6d04732b43c5d35e4ef58be7bfa84a81e5ae6f05a1d33/cryptography-46.0.7-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:fcd8eac50d9138c1d7fc53a653ba60a2bee81a505f9f8850b6b2888555a45d0e", size = 4399191, upload-time = "2026-04-08T01:57:02.654Z" }, + { url = "https://files.pythonhosted.org/packages/59/6a/bb2e166d6d0e0955f1e9ff70f10ec4b2824c9cfcdb4da772c7dd69cc7d80/cryptography-46.0.7-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:65814c60f8cc400c63131584e3e1fad01235edba2614b61fbfbfa954082db0ee", size = 4655782, upload-time = "2026-04-08T01:57:04.592Z" }, + { url = "https://files.pythonhosted.org/packages/95/b6/3da51d48415bcb63b00dc17c2eff3a651b7c4fed484308d0f19b30e8cb2c/cryptography-46.0.7-cp314-cp314t-win32.whl", hash = "sha256:fdd1736fed309b4300346f88f74cd120c27c56852c3838cab416e7a166f67298", size = 3002227, upload-time = "2026-04-08T01:57:06.91Z" }, + { url = "https://files.pythonhosted.org/packages/32/a8/9f0e4ed57ec9cebe506e58db11ae472972ecb0c659e4d52bbaee80ca340a/cryptography-46.0.7-cp314-cp314t-win_amd64.whl", hash = "sha256:e06acf3c99be55aa3b516397fe42f5855597f430add9c17fa46bf2e0fb34c9bb", size = 3475332, upload-time = "2026-04-08T01:57:08.807Z" }, + { url = "https://files.pythonhosted.org/packages/a7/7f/cd42fc3614386bc0c12f0cb3c4ae1fc2bbca5c9662dfed031514911d513d/cryptography-46.0.7-cp38-abi3-macosx_10_9_universal2.whl", hash = "sha256:462ad5cb1c148a22b2e3bcc5ad52504dff325d17daf5df8d88c17dda1f75f2a4", size = 7165618, upload-time = "2026-04-08T01:57:10.645Z" }, + { url = "https://files.pythonhosted.org/packages/a5/d0/36a49f0262d2319139d2829f773f1b97ef8aef7f97e6e5bd21455e5a8fb5/cryptography-46.0.7-cp38-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:84d4cced91f0f159a7ddacad249cc077e63195c36aac40b4150e7a57e84fffe7", size = 4270628, upload-time = "2026-04-08T01:57:12.885Z" }, + { url = "https://files.pythonhosted.org/packages/8a/6c/1a42450f464dda6ffbe578a911f773e54dd48c10f9895a23a7e88b3e7db5/cryptography-46.0.7-cp38-abi3-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:128c5edfe5e5938b86b03941e94fac9ee793a94452ad1365c9fc3f4f62216832", size = 4415405, upload-time = "2026-04-08T01:57:14.923Z" }, + { url = "https://files.pythonhosted.org/packages/9a/92/4ed714dbe93a066dc1f4b4581a464d2d7dbec9046f7c8b7016f5286329e2/cryptography-46.0.7-cp38-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:5e51be372b26ef4ba3de3c167cd3d1022934bc838ae9eaad7e644986d2a3d163", size = 4272715, upload-time = "2026-04-08T01:57:16.638Z" }, + { url = "https://files.pythonhosted.org/packages/b7/e6/a26b84096eddd51494bba19111f8fffe976f6a09f132706f8f1bf03f51f7/cryptography-46.0.7-cp38-abi3-manylinux_2_28_ppc64le.whl", hash = "sha256:cdf1a610ef82abb396451862739e3fc93b071c844399e15b90726ef7470eeaf2", size = 4918400, upload-time = "2026-04-08T01:57:19.021Z" }, + { url = "https://files.pythonhosted.org/packages/c7/08/ffd537b605568a148543ac3c2b239708ae0bd635064bab41359252ef88ed/cryptography-46.0.7-cp38-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:1d25aee46d0c6f1a501adcddb2d2fee4b979381346a78558ed13e50aa8a59067", size = 4450634, upload-time = "2026-04-08T01:57:21.185Z" }, + { url = "https://files.pythonhosted.org/packages/16/01/0cd51dd86ab5b9befe0d031e276510491976c3a80e9f6e31810cce46c4ad/cryptography-46.0.7-cp38-abi3-manylinux_2_31_armv7l.whl", hash = "sha256:cdfbe22376065ffcf8be74dc9a909f032df19bc58a699456a21712d6e5eabfd0", size = 3985233, upload-time = "2026-04-08T01:57:22.862Z" }, + { url = "https://files.pythonhosted.org/packages/92/49/819d6ed3a7d9349c2939f81b500a738cb733ab62fbecdbc1e38e83d45e12/cryptography-46.0.7-cp38-abi3-manylinux_2_34_aarch64.whl", hash = "sha256:abad9dac36cbf55de6eb49badd4016806b3165d396f64925bf2999bcb67837ba", size = 4271955, upload-time = "2026-04-08T01:57:24.814Z" }, + { url = "https://files.pythonhosted.org/packages/80/07/ad9b3c56ebb95ed2473d46df0847357e01583f4c52a85754d1a55e29e4d0/cryptography-46.0.7-cp38-abi3-manylinux_2_34_ppc64le.whl", hash = "sha256:935ce7e3cfdb53e3536119a542b839bb94ec1ad081013e9ab9b7cfd478b05006", size = 4879888, upload-time = "2026-04-08T01:57:26.88Z" }, + { url = "https://files.pythonhosted.org/packages/b8/c7/201d3d58f30c4c2bdbe9b03844c291feb77c20511cc3586daf7edc12a47b/cryptography-46.0.7-cp38-abi3-manylinux_2_34_x86_64.whl", hash = "sha256:35719dc79d4730d30f1c2b6474bd6acda36ae2dfae1e3c16f2051f215df33ce0", size = 4449961, upload-time = "2026-04-08T01:57:29.068Z" }, + { url = "https://files.pythonhosted.org/packages/a5/ef/649750cbf96f3033c3c976e112265c33906f8e462291a33d77f90356548c/cryptography-46.0.7-cp38-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:7bbc6ccf49d05ac8f7d7b5e2e2c33830d4fe2061def88210a126d130d7f71a85", size = 4401696, upload-time = "2026-04-08T01:57:31.029Z" }, + { url = "https://files.pythonhosted.org/packages/41/52/a8908dcb1a389a459a29008c29966c1d552588d4ae6d43f3a1a4512e0ebe/cryptography-46.0.7-cp38-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:a1529d614f44b863a7b480c6d000fe93b59acee9c82ffa027cfadc77521a9f5e", size = 4664256, upload-time = "2026-04-08T01:57:33.144Z" }, + { url = "https://files.pythonhosted.org/packages/4b/fa/f0ab06238e899cc3fb332623f337a7364f36f4bb3f2534c2bb95a35b132c/cryptography-46.0.7-cp38-abi3-win32.whl", hash = "sha256:f247c8c1a1fb45e12586afbb436ef21ff1e80670b2861a90353d9b025583d246", size = 3013001, upload-time = "2026-04-08T01:57:34.933Z" }, + { url = "https://files.pythonhosted.org/packages/d2/f1/00ce3bde3ca542d1acd8f8cfa38e446840945aa6363f9b74746394b14127/cryptography-46.0.7-cp38-abi3-win_amd64.whl", hash = "sha256:506c4ff91eff4f82bdac7633318a526b1d1309fc07ca76a3ad182cb5b686d6d3", size = 3472985, upload-time = "2026-04-08T01:57:36.714Z" }, +] + +[[package]] +name = "cycler" +version = "0.12.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/a9/95/a3dbbb5028f35eafb79008e7522a75244477d2838f38cbb722248dabc2a8/cycler-0.12.1.tar.gz", hash = "sha256:88bb128f02ba341da8ef447245a9e138fae777f6a23943da4540077d3601eb1c", size = 7615, upload-time = "2023-10-07T05:32:18.335Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/e7/05/c19819d5e3d95294a6f5947fb9b9629efb316b96de511b418c53d245aae6/cycler-0.12.1-py3-none-any.whl", hash = "sha256:85cef7cff222d8644161529808465972e51340599459b8ac3ccbac5a854e0d30", size = 8321, upload-time = "2023-10-07T05:32:16.783Z" }, +] + +[[package]] +name = "datalayer-pycrdt" +version = "0.12.17" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "anyio" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/6b/85/0b46dd3db445b9ac3fae859fa6ad21b4efa54ec7ac907756e7da25c236e9/datalayer_pycrdt-0.12.17.tar.gz", hash = "sha256:9eae67e39c89508746f6571852ed903e174ab72e691ead056f9a57a302b118c1", size = 74277, upload-time = "2025-05-18T16:11:11.834Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/f0/e8/70b326657902bf6c711718dcb772de5b228b169e09686bcc7e5009984241/datalayer_pycrdt-0.12.17-cp313-cp313-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl", hash = "sha256:ec9c7d85e8684e54544dc2189b2ae7fefbba74471632def959d46f749610831a", size = 1651291, upload-time = "2025-05-18T16:10:21.518Z" }, + { url = "https://files.pythonhosted.org/packages/01/5e/ace988fdeae105edaa8ebe386a4cc8d8115a152af39c85e8e1230aaa6257/datalayer_pycrdt-0.12.17-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d8b664d49724a07d633e3285ba08a84e0fd8f5e69f99b345b1a4a99c9bede34c", size = 898974, upload-time = "2025-05-18T16:10:23.039Z" }, + { url = "https://files.pythonhosted.org/packages/a7/bb/2b8de693c32e82d61962790e0a0a655556ba8a49d01ca8502bd13d63799a/datalayer_pycrdt-0.12.17-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:6d64833b4412569d08d1377430d8ccf10ceae617ef934dbf33eaa11a5732c498", size = 931622, upload-time = "2025-05-18T16:10:24.435Z" }, + { url = "https://files.pythonhosted.org/packages/1b/b5/6e9abdd06ea214e273b5c9fb520beb7d1baade9bb4cb49766baba410848e/datalayer_pycrdt-0.12.17-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ae361627668c6f3e0fdfc77969039881160341c9ed2e6e89cd714396769af3e8", size = 1120492, upload-time = "2025-05-18T16:10:25.795Z" }, + { url = "https://files.pythonhosted.org/packages/3b/5e/527c592bba2552c33008f5c259fcaa300b335390b5ba0e37b8a557e0af22/datalayer_pycrdt-0.12.17-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:355d47a0715376adc23e2b95a83b5b87d64331f03a5ba9d88dedf4325791df6c", size = 976431, upload-time = "2025-05-18T16:10:27.551Z" }, + { url = "https://files.pythonhosted.org/packages/7a/b0/f7458b39e17c0e51f5039f78d54f496db6dd13fae14a6b986c3fff52baa6/datalayer_pycrdt-0.12.17-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9c7645351893604edc7324fb8bba757871c0b5bc12b5d4bcbdea1d99a13fa094", size = 928779, upload-time = "2025-05-18T16:10:28.98Z" }, + { url = "https://files.pythonhosted.org/packages/e7/c0/b7b802d01530ebf58cdf4a9bcbae3a6cf363656fe7c9e9046e1390a69ad2/datalayer_pycrdt-0.12.17-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:13a77a1e13c1cf65b249487d62ddb5738840455cc78e65dabe665bc0feee08d8", size = 1001812, upload-time = "2025-05-18T16:10:30.896Z" }, + { url = "https://files.pythonhosted.org/packages/67/fa/32396a73f5434ad95a4df3b02f4d9df4854b9357640fb6a7e608fccf1e0b/datalayer_pycrdt-0.12.17-cp313-cp313-win32.whl", hash = "sha256:11565cae105c965d27b42b59bf2b3993e973a998bb7020ecfa6153f31e0231a3", size = 667055, upload-time = "2025-05-18T16:10:32.752Z" }, + { url = "https://files.pythonhosted.org/packages/9e/b1/8426abcd0bb44a7848435e012cd361884ea5cec878cb81252de2686b8360/datalayer_pycrdt-0.12.17-cp313-cp313-win_amd64.whl", hash = "sha256:10327f0715a5929f4aaa1655e8b503570e4783733f1c9986817df183eb0c0ecd", size = 723059, upload-time = "2025-05-18T16:10:34.081Z" }, +] + +[[package]] +name = "debugpy" +version = "1.8.20" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/e0/b7/cd8080344452e4874aae67c40d8940e2b4d47b01601a8fd9f44786c757c7/debugpy-1.8.20.tar.gz", hash = "sha256:55bc8701714969f1ab89a6d5f2f3d40c36f91b2cbe2f65d98bf8196f6a6a2c33", size = 1645207, upload-time = "2026-01-29T23:03:28.199Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/15/e2/fc500524cc6f104a9d049abc85a0a8b3f0d14c0a39b9c140511c61e5b40b/debugpy-1.8.20-cp313-cp313-macosx_15_0_universal2.whl", hash = "sha256:5dff4bb27027821fdfcc9e8f87309a28988231165147c31730128b1c983e282a", size = 2539560, upload-time = "2026-01-29T23:03:48.738Z" }, + { url = "https://files.pythonhosted.org/packages/90/83/fb33dcea789ed6018f8da20c5a9bc9d82adc65c0c990faed43f7c955da46/debugpy-1.8.20-cp313-cp313-manylinux_2_34_x86_64.whl", hash = "sha256:84562982dd7cf5ebebfdea667ca20a064e096099997b175fe204e86817f64eaf", size = 4293272, upload-time = "2026-01-29T23:03:50.169Z" }, + { url = "https://files.pythonhosted.org/packages/a6/25/b1e4a01bfb824d79a6af24b99ef291e24189080c93576dfd9b1a2815cd0f/debugpy-1.8.20-cp313-cp313-win32.whl", hash = "sha256:da11dea6447b2cadbf8ce2bec59ecea87cc18d2c574980f643f2d2dfe4862393", size = 5331208, upload-time = "2026-01-29T23:03:51.547Z" }, + { url = "https://files.pythonhosted.org/packages/13/f7/a0b368ce54ffff9e9028c098bd2d28cfc5b54f9f6c186929083d4c60ba58/debugpy-1.8.20-cp313-cp313-win_amd64.whl", hash = "sha256:eb506e45943cab2efb7c6eafdd65b842f3ae779f020c82221f55aca9de135ed7", size = 5372930, upload-time = "2026-01-29T23:03:53.585Z" }, + { url = "https://files.pythonhosted.org/packages/33/2e/f6cb9a8a13f5058f0a20fe09711a7b726232cd5a78c6a7c05b2ec726cff9/debugpy-1.8.20-cp314-cp314-macosx_15_0_universal2.whl", hash = "sha256:9c74df62fc064cd5e5eaca1353a3ef5a5d50da5eb8058fcef63106f7bebe6173", size = 2538066, upload-time = "2026-01-29T23:03:54.999Z" }, + { url = "https://files.pythonhosted.org/packages/c5/56/6ddca50b53624e1ca3ce1d1e49ff22db46c47ea5fb4c0cc5c9b90a616364/debugpy-1.8.20-cp314-cp314-manylinux_2_34_x86_64.whl", hash = "sha256:077a7447589ee9bc1ff0cdf443566d0ecf540ac8aa7333b775ebcb8ce9f4ecad", size = 4269425, upload-time = "2026-01-29T23:03:56.518Z" }, + { url = "https://files.pythonhosted.org/packages/c5/d9/d64199c14a0d4c476df46c82470a3ce45c8d183a6796cfb5e66533b3663c/debugpy-1.8.20-cp314-cp314-win32.whl", hash = "sha256:352036a99dd35053b37b7803f748efc456076f929c6a895556932eaf2d23b07f", size = 5331407, upload-time = "2026-01-29T23:03:58.481Z" }, + { url = "https://files.pythonhosted.org/packages/e0/d9/1f07395b54413432624d61524dfd98c1a7c7827d2abfdb8829ac92638205/debugpy-1.8.20-cp314-cp314-win_amd64.whl", hash = "sha256:a98eec61135465b062846112e5ecf2eebb855305acc1dfbae43b72903b8ab5be", size = 5372521, upload-time = "2026-01-29T23:03:59.864Z" }, + { url = "https://files.pythonhosted.org/packages/e0/c3/7f67dea8ccf8fdcb9c99033bbe3e90b9e7395415843accb81428c441be2d/debugpy-1.8.20-py2.py3-none-any.whl", hash = "sha256:5be9bed9ae3be00665a06acaa48f8329d2b9632f15fd09f6a9a8c8d9907e54d7", size = 5337658, upload-time = "2026-01-29T23:04:17.404Z" }, +] + +[[package]] +name = "decorator" +version = "5.2.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/43/fa/6d96a0978d19e17b68d634497769987b16c8f4cd0a7a05048bec693caa6b/decorator-5.2.1.tar.gz", hash = "sha256:65f266143752f734b0a7cc83c46f4618af75b8c5911b00ccb61d0ac9b6da0360", size = 56711, upload-time = "2025-02-24T04:41:34.073Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/4e/8c/f3147f5c4b73e7550fe5f9352eaa956ae838d5c51eb58e7a25b9f3e2643b/decorator-5.2.1-py3-none-any.whl", hash = "sha256:d316bb415a2d9e2d2b3abcc4084c6502fc09240e292cd76a76afc106a1c8e04a", size = 9190, upload-time = "2025-02-24T04:41:32.565Z" }, +] + +[[package]] +name = "defusedxml" +version = "0.7.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/0f/d5/c66da9b79e5bdb124974bfe172b4daf3c984ebd9c2a06e2b8a4dc7331c72/defusedxml-0.7.1.tar.gz", hash = "sha256:1bb3032db185915b62d7c6209c5a8792be6a32ab2fedacc84e01b52c51aa3e69", size = 75520, upload-time = "2021-03-08T10:59:26.269Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/07/6c/aa3f2f849e01cb6a001cd8554a88d4c77c5c1a31c95bdf1cf9301e6d9ef4/defusedxml-0.7.1-py2.py3-none-any.whl", hash = "sha256:a352e7e428770286cc899e2542b6cdaedb2b4953ff269a210103ec58f6198a61", size = 25604, upload-time = "2021-03-08T10:59:24.45Z" }, +] + +[[package]] +name = "executing" +version = "2.2.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/cc/28/c14e053b6762b1044f34a13aab6859bbf40456d37d23aa286ac24cfd9a5d/executing-2.2.1.tar.gz", hash = "sha256:3632cc370565f6648cc328b32435bd120a1e4ebb20c77e3fdde9a13cd1e533c4", size = 1129488, upload-time = "2025-09-01T09:48:10.866Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/c1/ea/53f2148663b321f21b5a606bd5f191517cf40b7072c0497d3c92c4a13b1e/executing-2.2.1-py2.py3-none-any.whl", hash = "sha256:760643d3452b4d777d295bb167ccc74c64a81df23fb5e08eff250c425a4b2017", size = 28317, upload-time = "2025-09-01T09:48:08.5Z" }, +] + +[[package]] +name = "fastjsonschema" +version = "2.21.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/20/b5/23b216d9d985a956623b6bd12d4086b60f0059b27799f23016af04a74ea1/fastjsonschema-2.21.2.tar.gz", hash = "sha256:b1eb43748041c880796cd077f1a07c3d94e93ae84bba5ed36800a33554ae05de", size = 374130, upload-time = "2025-08-14T18:49:36.666Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/cb/a8/20d0723294217e47de6d9e2e40fd4a9d2f7c4b6ef974babd482a59743694/fastjsonschema-2.21.2-py3-none-any.whl", hash = "sha256:1c797122d0a86c5cace2e54bf4e819c36223b552017172f32c5c024a6b77e463", size = 24024, upload-time = "2025-08-14T18:49:34.776Z" }, +] + +[[package]] +name = "fonttools" +version = "4.62.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/9a/08/7012b00a9a5874311b639c3920270c36ee0c445b69d9989a85e5c92ebcb0/fonttools-4.62.1.tar.gz", hash = "sha256:e54c75fd6041f1122476776880f7c3c3295ffa31962dc6ebe2543c00dca58b5d", size = 3580737, upload-time = "2026-03-13T13:54:25.52Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/3b/56/6f389de21c49555553d6a5aeed5ac9767631497ac836c4f076273d15bd72/fonttools-4.62.1-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:c22b1014017111c401469e3acc5433e6acf6ebcc6aa9efb538a533c800971c79", size = 2865155, upload-time = "2026-03-13T13:53:16.132Z" }, + { url = "https://files.pythonhosted.org/packages/03/c5/0e3966edd5ec668d41dfe418787726752bc07e2f5fd8c8f208615e61fa89/fonttools-4.62.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:68959f5fc58ed4599b44aad161c2837477d7f35f5f79402d97439974faebfebe", size = 2412802, upload-time = "2026-03-13T13:53:18.878Z" }, + { url = "https://files.pythonhosted.org/packages/52/94/e6ac4b44026de7786fe46e3bfa0c87e51d5d70a841054065d49cd62bb909/fonttools-4.62.1-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ef46db46c9447103b8f3ff91e8ba009d5fe181b1920a83757a5762551e32bb68", size = 5013926, upload-time = "2026-03-13T13:53:21.379Z" }, + { url = "https://files.pythonhosted.org/packages/e2/98/8b1e801939839d405f1f122e7d175cebe9aeb4e114f95bfc45e3152af9a7/fonttools-4.62.1-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:6706d1cb1d5e6251a97ad3c1b9347505c5615c112e66047abbef0f8545fa30d1", size = 4964575, upload-time = "2026-03-13T13:53:23.857Z" }, + { url = "https://files.pythonhosted.org/packages/46/76/7d051671e938b1881670528fec69cc4044315edd71a229c7fd712eaa5119/fonttools-4.62.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:2e7abd2b1e11736f58c1de27819e1955a53267c21732e78243fa2fa2e5c1e069", size = 4953693, upload-time = "2026-03-13T13:53:26.569Z" }, + { url = "https://files.pythonhosted.org/packages/1f/ae/b41f8628ec0be3c1b934fc12b84f4576a5c646119db4d3bdd76a217c90b5/fonttools-4.62.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:403d28ce06ebfc547fbcb0cb8b7f7cc2f7a2d3e1a67ba9a34b14632df9e080f9", size = 5094920, upload-time = "2026-03-13T13:53:29.329Z" }, + { url = "https://files.pythonhosted.org/packages/f2/f6/53a1e9469331a23dcc400970a27a4caa3d9f6edbf5baab0260285238b884/fonttools-4.62.1-cp313-cp313-win32.whl", hash = "sha256:93c316e0f5301b2adbe6a5f658634307c096fd5aae60a5b3412e4f3e1728ab24", size = 2279928, upload-time = "2026-03-13T13:53:32.352Z" }, + { url = "https://files.pythonhosted.org/packages/38/60/35186529de1db3c01f5ad625bde07c1f576305eab6d86bbda4c58445f721/fonttools-4.62.1-cp313-cp313-win_amd64.whl", hash = "sha256:7aa21ff53e28a9c2157acbc44e5b401149d3c9178107130e82d74ceb500e5056", size = 2330514, upload-time = "2026-03-13T13:53:34.991Z" }, + { url = "https://files.pythonhosted.org/packages/36/f0/2888cdac391807d68d90dcb16ef858ddc1b5309bfc6966195a459dd326e2/fonttools-4.62.1-cp314-cp314-macosx_10_15_universal2.whl", hash = "sha256:fa1d16210b6b10a826d71bed68dd9ec24a9e218d5a5e2797f37c573e7ec215ca", size = 2864442, upload-time = "2026-03-13T13:53:37.509Z" }, + { url = "https://files.pythonhosted.org/packages/4b/b2/e521803081f8dc35990816b82da6360fa668a21b44da4b53fc9e77efcd62/fonttools-4.62.1-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:aa69d10ed420d8121118e628ad47d86e4caa79ba37f968597b958f6cceab7eca", size = 2410901, upload-time = "2026-03-13T13:53:40.55Z" }, + { url = "https://files.pythonhosted.org/packages/00/a4/8c3511ff06e53110039358dbbdc1a65d72157a054638387aa2ada300a8b8/fonttools-4.62.1-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:bd13b7999d59c5eb1c2b442eb2d0c427cb517a0b7a1f5798fc5c9e003f5ff782", size = 4999608, upload-time = "2026-03-13T13:53:42.798Z" }, + { url = "https://files.pythonhosted.org/packages/28/63/cd0c3b26afe60995a5295f37c246a93d454023726c3261cfbb3559969bb9/fonttools-4.62.1-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:8d337fdd49a79b0d51c4da87bc38169d21c3abbf0c1aa9367eff5c6656fb6dae", size = 4912726, upload-time = "2026-03-13T13:53:45.405Z" }, + { url = "https://files.pythonhosted.org/packages/70/b9/ac677cb07c24c685cf34f64e140617d58789d67a3dd524164b63648c6114/fonttools-4.62.1-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:d241cdc4a67b5431c6d7f115fdf63335222414995e3a1df1a41e1182acd4bcc7", size = 4951422, upload-time = "2026-03-13T13:53:48.326Z" }, + { url = "https://files.pythonhosted.org/packages/e6/10/11c08419a14b85b7ca9a9faca321accccc8842dd9e0b1c8a72908de05945/fonttools-4.62.1-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:c05557a78f8fa514da0f869556eeda40887a8abc77c76ee3f74cf241778afd5a", size = 5060979, upload-time = "2026-03-13T13:53:51.366Z" }, + { url = "https://files.pythonhosted.org/packages/4e/3c/12eea4a4cf054e7ab058ed5ceada43b46809fce2bf319017c4d63ae55bb4/fonttools-4.62.1-cp314-cp314-win32.whl", hash = "sha256:49a445d2f544ce4a69338694cad575ba97b9a75fff02720da0882d1a73f12800", size = 2283733, upload-time = "2026-03-13T13:53:53.606Z" }, + { url = "https://files.pythonhosted.org/packages/6b/67/74b070029043186b5dd13462c958cb7c7f811be0d2e634309d9a1ffb1505/fonttools-4.62.1-cp314-cp314-win_amd64.whl", hash = "sha256:1eecc128c86c552fb963fe846ca4e011b1be053728f798185a1687502f6d398e", size = 2335663, upload-time = "2026-03-13T13:53:56.23Z" }, + { url = "https://files.pythonhosted.org/packages/42/c5/4d2ed3ca6e33617fc5624467da353337f06e7f637707478903c785bd8e20/fonttools-4.62.1-cp314-cp314t-macosx_10_15_universal2.whl", hash = "sha256:1596aeaddf7f78e21e68293c011316a25267b3effdaccaf4d59bc9159d681b82", size = 2947288, upload-time = "2026-03-13T13:53:59.397Z" }, + { url = "https://files.pythonhosted.org/packages/1f/e9/7ab11ddfda48ed0f89b13380e5595ba572619c27077be0b2c447a63ff351/fonttools-4.62.1-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:8f8fca95d3bb3208f59626a4b0ea6e526ee51f5a8ad5d91821c165903e8d9260", size = 2449023, upload-time = "2026-03-13T13:54:01.642Z" }, + { url = "https://files.pythonhosted.org/packages/b2/10/a800fa090b5e8819942e54e19b55fc7c21fe14a08757c3aa3ca8db358939/fonttools-4.62.1-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ee91628c08e76f77b533d65feb3fbe6d9dad699f95be51cf0d022db94089cdc4", size = 5137599, upload-time = "2026-03-13T13:54:04.495Z" }, + { url = "https://files.pythonhosted.org/packages/37/dc/8ccd45033fffd74deb6912fa1ca524643f584b94c87a16036855b498a1ed/fonttools-4.62.1-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:5f37df1cac61d906e7b836abe356bc2f34c99d4477467755c216b72aa3dc748b", size = 4920933, upload-time = "2026-03-13T13:54:07.557Z" }, + { url = "https://files.pythonhosted.org/packages/99/eb/e618adefb839598d25ac8136cd577925d6c513dc0d931d93b8af956210f0/fonttools-4.62.1-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:92bb00a947e666169c99b43753c4305fc95a890a60ef3aeb2a6963e07902cc87", size = 5016232, upload-time = "2026-03-13T13:54:10.611Z" }, + { url = "https://files.pythonhosted.org/packages/d9/5f/9b5c9bfaa8ec82def8d8168c4f13615990d6ce5996fe52bd49bfb5e05134/fonttools-4.62.1-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:bdfe592802ef939a0e33106ea4a318eeb17822c7ee168c290273cbd5fabd746c", size = 5042987, upload-time = "2026-03-13T13:54:13.569Z" }, + { url = "https://files.pythonhosted.org/packages/90/aa/dfbbe24c6a6afc5c203d90cc0343e24bcbb09e76d67c4d6eef8c2558d7ba/fonttools-4.62.1-cp314-cp314t-win32.whl", hash = "sha256:b820fcb92d4655513d8402d5b219f94481c4443d825b4372c75a2072aa4b357a", size = 2348021, upload-time = "2026-03-13T13:54:16.98Z" }, + { url = "https://files.pythonhosted.org/packages/13/6f/ae9c4e4dd417948407b680855c2c7790efb52add6009aaecff1e3bc50e8e/fonttools-4.62.1-cp314-cp314t-win_amd64.whl", hash = "sha256:59b372b4f0e113d3746b88985f1c796e7bf830dd54b28374cd85c2b8acd7583e", size = 2414147, upload-time = "2026-03-13T13:54:19.416Z" }, + { url = "https://files.pythonhosted.org/packages/fd/ba/56147c165442cc5ba7e82ecf301c9a68353cede498185869e6e02b4c264f/fonttools-4.62.1-py3-none-any.whl", hash = "sha256:7487782e2113861f4ddcc07c3436450659e3caa5e470b27dc2177cade2d8e7fd", size = 1152647, upload-time = "2026-03-13T13:54:22.735Z" }, +] + +[[package]] +name = "fqdn" +version = "1.5.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/30/3e/a80a8c077fd798951169626cde3e239adeba7dab75deb3555716415bd9b0/fqdn-1.5.1.tar.gz", hash = "sha256:105ed3677e767fb5ca086a0c1f4bb66ebc3c100be518f0e0d755d9eae164d89f", size = 6015, upload-time = "2021-03-11T07:16:29.08Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/cf/58/8acf1b3e91c58313ce5cb67df61001fc9dcd21be4fadb76c1a2d540e09ed/fqdn-1.5.1-py3-none-any.whl", hash = "sha256:3a179af3761e4df6eb2e026ff9e1a3033d3587bf980a0b1b2e1e5d08d7358014", size = 9121, upload-time = "2021-03-11T07:16:28.351Z" }, +] + +[[package]] +name = "h11" +version = "0.16.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/01/ee/02a2c011bdab74c6fb3c75474d40b3052059d95df7e73351460c8588d963/h11-0.16.0.tar.gz", hash = "sha256:4e35b956cf45792e4caa5885e69fba00bdbc6ffafbfa020300e549b208ee5ff1", size = 101250, upload-time = "2025-04-24T03:35:25.427Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/04/4b/29cac41a4d98d144bf5f6d33995617b185d14b22401f75ca86f384e87ff1/h11-0.16.0-py3-none-any.whl", hash = "sha256:63cf8bbe7522de3bf65932fda1d9c2772064ffb3dae62d55932da54b31cb6c86", size = 37515, upload-time = "2025-04-24T03:35:24.344Z" }, +] + +[[package]] +name = "httpcore" +version = "1.0.9" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "certifi" }, + { name = "h11" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/06/94/82699a10bca87a5556c9c59b5963f2d039dbd239f25bc2a63907a05a14cb/httpcore-1.0.9.tar.gz", hash = "sha256:6e34463af53fd2ab5d807f399a9b45ea31c3dfa2276f15a2c3f00afff6e176e8", size = 85484, upload-time = "2025-04-24T22:06:22.219Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/7e/f5/f66802a942d491edb555dd61e3a9961140fd64c90bce1eafd741609d334d/httpcore-1.0.9-py3-none-any.whl", hash = "sha256:2d400746a40668fc9dec9810239072b40b4484b640a8c38fd654a024c7a1bf55", size = 78784, upload-time = "2025-04-24T22:06:20.566Z" }, +] + +[[package]] +name = "httpx" +version = "0.28.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "anyio" }, + { name = "certifi" }, + { name = "httpcore" }, + { name = "idna" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/b1/df/48c586a5fe32a0f01324ee087459e112ebb7224f646c0b5023f5e79e9956/httpx-0.28.1.tar.gz", hash = "sha256:75e98c5f16b0f35b567856f597f06ff2270a374470a5c2392242528e3e3e42fc", size = 141406, upload-time = "2024-12-06T15:37:23.222Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/2a/39/e50c7c3a983047577ee07d2a9e53faf5a69493943ec3f6a384bdc792deb2/httpx-0.28.1-py3-none-any.whl", hash = "sha256:d909fcccc110f8c7faf814ca82a9a4d816bc5a6dbfea25d6591d6985b8ba59ad", size = 73517, upload-time = "2024-12-06T15:37:21.509Z" }, +] + +[[package]] +name = "httpx-sse" +version = "0.4.3" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/0f/4c/751061ffa58615a32c31b2d82e8482be8dd4a89154f003147acee90f2be9/httpx_sse-0.4.3.tar.gz", hash = "sha256:9b1ed0127459a66014aec3c56bebd93da3c1bc8bb6618c8082039a44889a755d", size = 15943, upload-time = "2025-10-10T21:48:22.271Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/d2/fd/6668e5aec43ab844de6fc74927e155a3b37bf40d7c3790e49fc0406b6578/httpx_sse-0.4.3-py3-none-any.whl", hash = "sha256:0ac1c9fe3c0afad2e0ebb25a934a59f4c7823b60792691f779fad2c5568830fc", size = 8960, upload-time = "2025-10-10T21:48:21.158Z" }, +] + +[[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" } +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" }, +] + +[[package]] +name = "ipykernel" +version = "7.2.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "appnope", marker = "sys_platform == 'darwin'" }, + { name = "comm" }, + { name = "debugpy" }, + { name = "ipython" }, + { name = "jupyter-client" }, + { name = "jupyter-core" }, + { name = "matplotlib-inline" }, + { name = "nest-asyncio" }, + { name = "packaging" }, + { name = "psutil" }, + { name = "pyzmq" }, + { name = "tornado" }, + { name = "traitlets" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/ca/8d/b68b728e2d06b9e0051019640a40a9eb7a88fcd82c2e1b5ce70bef5ff044/ipykernel-7.2.0.tar.gz", hash = "sha256:18ed160b6dee2cbb16e5f3575858bc19d8f1fe6046a9a680c708494ce31d909e", size = 176046, upload-time = "2026-02-06T16:43:27.403Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/82/b9/e73d5d9f405cba7706c539aa8b311b49d4c2f3d698d9c12f815231169c71/ipykernel-7.2.0-py3-none-any.whl", hash = "sha256:3bbd4420d2b3cc105cbdf3756bfc04500b1e52f090a90716851f3916c62e1661", size = 118788, upload-time = "2026-02-06T16:43:25.149Z" }, +] + +[[package]] +name = "ipython" +version = "9.12.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "colorama", marker = "sys_platform == 'win32'" }, + { name = "decorator" }, + { name = "ipython-pygments-lexers" }, + { name = "jedi" }, + { name = "matplotlib-inline" }, + { name = "pexpect", marker = "sys_platform != 'emscripten' and sys_platform != 'win32'" }, + { name = "prompt-toolkit" }, + { name = "pygments" }, + { name = "stack-data" }, + { name = "traitlets" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/3a/73/7114f80a8f9cabdb13c27732dce24af945b2923dcab80723602f7c8bc2d8/ipython-9.12.0.tar.gz", hash = "sha256:01daa83f504b693ba523b5a407246cabde4eb4513285a3c6acaff11a66735ee4", size = 4428879, upload-time = "2026-03-27T09:42:45.312Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/59/22/906c8108974c673ebef6356c506cebb6870d48cedea3c41e949e2dd556bb/ipython-9.12.0-py3-none-any.whl", hash = "sha256:0f2701e8ee86e117e37f50563205d36feaa259d2e08d4a6bc6b6d74b18ce128d", size = 625661, upload-time = "2026-03-27T09:42:42.831Z" }, +] + +[[package]] +name = "ipython-pygments-lexers" +version = "1.1.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "pygments" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/ef/4c/5dd1d8af08107f88c7f741ead7a40854b8ac24ddf9ae850afbcf698aa552/ipython_pygments_lexers-1.1.1.tar.gz", hash = "sha256:09c0138009e56b6854f9535736f4171d855c8c08a563a0dcd8022f78355c7e81", size = 8393, upload-time = "2025-01-17T11:24:34.505Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/d9/33/1f075bf72b0b747cb3288d011319aaf64083cf2efef8354174e3ed4540e2/ipython_pygments_lexers-1.1.1-py3-none-any.whl", hash = "sha256:a9462224a505ade19a605f71f8fa63c2048833ce50abc86768a0d81d876dc81c", size = 8074, upload-time = "2025-01-17T11:24:33.271Z" }, +] + +[[package]] +name = "ipywidgets" +version = "8.1.8" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "comm" }, + { name = "ipython" }, + { name = "jupyterlab-widgets" }, + { name = "traitlets" }, + { name = "widgetsnbextension" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/4c/ae/c5ce1edc1afe042eadb445e95b0671b03cee61895264357956e61c0d2ac0/ipywidgets-8.1.8.tar.gz", hash = "sha256:61f969306b95f85fba6b6986b7fe45d73124d1d9e3023a8068710d47a22ea668", size = 116739, upload-time = "2025-11-01T21:18:12.393Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/56/6d/0d9848617b9f753b87f214f1c682592f7ca42de085f564352f10f0843026/ipywidgets-8.1.8-py3-none-any.whl", hash = "sha256:ecaca67aed704a338f88f67b1181b58f821ab5dc89c1f0f5ef99db43c1c2921e", size = 139808, upload-time = "2025-11-01T21:18:10.956Z" }, +] + +[[package]] +name = "isoduration" +version = "20.11.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "arrow" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/7c/1a/3c8edc664e06e6bd06cce40c6b22da5f1429aa4224d0c590f3be21c91ead/isoduration-20.11.0.tar.gz", hash = "sha256:ac2f9015137935279eac671f94f89eb00584f940f5dc49462a0c4ee692ba1bd9", size = 11649, upload-time = "2020-11-01T11:00:00.312Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/7b/55/e5326141505c5d5e34c5e0935d2908a74e4561eca44108fbfb9c13d2911a/isoduration-20.11.0-py3-none-any.whl", hash = "sha256:b2904c2a4228c3d44f409c8ae8e2370eb21a26f7ac2ec5446df141dde3452042", size = 11321, upload-time = "2020-11-01T10:59:58.02Z" }, +] + +[[package]] +name = "jedi" +version = "0.19.2" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "parso" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/72/3a/79a912fbd4d8dd6fbb02bf69afd3bb72cf0c729bb3063c6f4498603db17a/jedi-0.19.2.tar.gz", hash = "sha256:4770dc3de41bde3966b02eb84fbcf557fb33cce26ad23da12c742fb50ecb11f0", size = 1231287, upload-time = "2024-11-11T01:41:42.873Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/c0/5a/9cac0c82afec3d09ccd97c8b6502d48f165f9124db81b4bcb90b4af974ee/jedi-0.19.2-py2.py3-none-any.whl", hash = "sha256:a8ef22bde8490f57fe5c7681a3c83cb58874daf72b4784de3cce5b6ef6edb5b9", size = 1572278, upload-time = "2024-11-11T01:41:40.175Z" }, +] + +[[package]] +name = "jinja2" +version = "3.1.6" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "markupsafe" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/df/bf/f7da0350254c0ed7c72f3e33cef02e048281fec7ecec5f032d4aac52226b/jinja2-3.1.6.tar.gz", hash = "sha256:0137fb05990d35f1275a587e9aee6d56da821fc83491a0fb838183be43f66d6d", size = 245115, upload-time = "2025-03-05T20:05:02.478Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/62/a1/3d680cbfd5f4b8f15abc1d571870c5fc3e594bb582bc3b64ea099db13e56/jinja2-3.1.6-py3-none-any.whl", hash = "sha256:85ece4451f492d0c13c5dd7c13a64681a86afae63a5f347908daf103ce6d2f67", size = 134899, upload-time = "2025-03-05T20:05:00.369Z" }, +] + +[[package]] +name = "json5" +version = "0.14.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/9c/4b/6f8906aaf67d501e259b0adab4d312945bb7211e8b8d4dcc77c92320edaa/json5-0.14.0.tar.gz", hash = "sha256:b3f492fad9f6cdbced8b7d40b28b9b1c9701c5f561bef0d33b81c2ff433fefcb", size = 52656, upload-time = "2026-03-27T22:50:48.108Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/b8/42/cf027b4ac873b076189d935b135397675dac80cb29acb13e1ab86ad6c631/json5-0.14.0-py3-none-any.whl", hash = "sha256:56cf861bab076b1178eb8c92e1311d273a9b9acea2ccc82c276abf839ebaef3a", size = 36271, upload-time = "2026-03-27T22:50:47.073Z" }, +] + +[[package]] +name = "jsonpointer" +version = "3.1.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/18/c7/af399a2e7a67fd18d63c40c5e62d3af4e67b836a2107468b6a5ea24c4304/jsonpointer-3.1.1.tar.gz", hash = "sha256:0b801c7db33a904024f6004d526dcc53bbb8a4a0f4e32bfd10beadf60adf1900", size = 9068, upload-time = "2026-03-23T22:32:32.458Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/9e/6a/a83720e953b1682d2d109d3c2dbb0bc9bf28cc1cbc205be4ef4be5da709d/jsonpointer-3.1.1-py3-none-any.whl", hash = "sha256:8ff8b95779d071ba472cf5bc913028df06031797532f08a7d5b602d8b2a488ca", size = 7659, upload-time = "2026-03-23T22:32:31.568Z" }, +] + +[[package]] +name = "jsonschema" +version = "4.26.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "attrs" }, + { name = "jsonschema-specifications" }, + { name = "referencing" }, + { name = "rpds-py" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/b3/fc/e067678238fa451312d4c62bf6e6cf5ec56375422aee02f9cb5f909b3047/jsonschema-4.26.0.tar.gz", hash = "sha256:0c26707e2efad8aa1bfc5b7ce170f3fccc2e4918ff85989ba9ffa9facb2be326", size = 366583, upload-time = "2026-01-07T13:41:07.246Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/69/90/f63fb5873511e014207a475e2bb4e8b2e570d655b00ac19a9a0ca0a385ee/jsonschema-4.26.0-py3-none-any.whl", hash = "sha256:d489f15263b8d200f8387e64b4c3a75f06629559fb73deb8fdfb525f2dab50ce", size = 90630, upload-time = "2026-01-07T13:41:05.306Z" }, +] + +[package.optional-dependencies] +format-nongpl = [ + { name = "fqdn" }, + { name = "idna" }, + { name = "isoduration" }, + { name = "jsonpointer" }, + { name = "rfc3339-validator" }, + { name = "rfc3986-validator" }, + { name = "rfc3987-syntax" }, + { name = "uri-template" }, + { name = "webcolors" }, +] + +[[package]] +name = "jsonschema-specifications" +version = "2025.9.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "referencing" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/19/74/a633ee74eb36c44aa6d1095e7cc5569bebf04342ee146178e2d36600708b/jsonschema_specifications-2025.9.1.tar.gz", hash = "sha256:b540987f239e745613c7a9176f3edb72b832a4ac465cf02712288397832b5e8d", size = 32855, upload-time = "2025-09-08T01:34:59.186Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/41/45/1a4ed80516f02155c51f51e8cedb3c1902296743db0bbc66608a0db2814f/jsonschema_specifications-2025.9.1-py3-none-any.whl", hash = "sha256:98802fee3a11ee76ecaca44429fda8a41bff98b00a0f2838151b113f210cc6fe", size = 18437, upload-time = "2025-09-08T01:34:57.871Z" }, +] + +[[package]] +name = "jupyter" +version = "1.1.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "ipykernel" }, + { name = "ipywidgets" }, + { name = "jupyter-console" }, + { name = "jupyterlab" }, + { name = "nbconvert" }, + { name = "notebook" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/58/f3/af28ea964ab8bc1e472dba2e82627d36d470c51f5cd38c37502eeffaa25e/jupyter-1.1.1.tar.gz", hash = "sha256:d55467bceabdea49d7e3624af7e33d59c37fff53ed3a350e1ac957bed731de7a", size = 5714959, upload-time = "2024-08-30T07:15:48.299Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/38/64/285f20a31679bf547b75602702f7800e74dbabae36ef324f716c02804753/jupyter-1.1.1-py2.py3-none-any.whl", hash = "sha256:7a59533c22af65439b24bbe60373a4e95af8f16ac65a6c00820ad378e3f7cc83", size = 2657, upload-time = "2024-08-30T07:15:47.045Z" }, +] + +[[package]] +name = "jupyter-client" +version = "8.8.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "jupyter-core" }, + { name = "python-dateutil" }, + { name = "pyzmq" }, + { name = "tornado" }, + { name = "traitlets" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/05/e4/ba649102a3bc3fbca54e7239fb924fd434c766f855693d86de0b1f2bec81/jupyter_client-8.8.0.tar.gz", hash = "sha256:d556811419a4f2d96c869af34e854e3f059b7cc2d6d01a9cd9c85c267691be3e", size = 348020, upload-time = "2026-01-08T13:55:47.938Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/2d/0b/ceb7694d864abc0a047649aec263878acb9f792e1fec3e676f22dc9015e3/jupyter_client-8.8.0-py3-none-any.whl", hash = "sha256:f93a5b99c5e23a507b773d3a1136bd6e16c67883ccdbd9a829b0bbdb98cd7d7a", size = 107371, upload-time = "2026-01-08T13:55:45.562Z" }, +] + +[[package]] +name = "jupyter-collaboration" +version = "4.3.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "jupyter-collaboration-ui" }, + { name = "jupyter-docprovider" }, + { name = "jupyter-server-ydoc" }, + { name = "jupyterlab" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/7b/b7/86b8f2aca6a554668c55c88401ba9ba6e355fdcc7d71cb3dd0bec85c330e/jupyter_collaboration-4.3.0.tar.gz", hash = "sha256:6ef03664fdda0fddf47d2904db29a659c8ef4d2f307080b89cdef72e7e7b24c9", size = 3734, upload-time = "2026-03-31T10:08:36.166Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/e4/1b/b518e55344a2bb787a8025d6cb51353b91d7af07e3756cc06b2ecb88098d/jupyter_collaboration-4.3.0-py3-none-any.whl", hash = "sha256:6dd3d7129e95a04e11f1fd22915f167023bebd4badc4cf1b71f73fb2690f5648", size = 4751, upload-time = "2026-03-31T10:08:34.383Z" }, +] + +[[package]] +name = "jupyter-collaboration-ui" +version = "2.3.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/0a/cf/bbf8f4b6f27a91c5addd3e8371bb97939a1f9bf0bf988d9961532f9c26a6/jupyter_collaboration_ui-2.3.0.tar.gz", hash = "sha256:835e818614eb39645f2f583a57b2246d8d1ecff4ffd2d481ab4a6f6b2c45b997", size = 77339, upload-time = "2026-03-31T10:08:13.898Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/36/63/a1f297c16092e44a7e143fe4f414317057b8e2acf33ce3c182cd2b08c291/jupyter_collaboration_ui-2.3.0-py3-none-any.whl", hash = "sha256:e8b9f026615e9ed448b1518bb74f044e15519ad5282976fa54c002f2572139c0", size = 46498, upload-time = "2026-03-31T10:08:12.167Z" }, +] + +[[package]] +name = "jupyter-console" +version = "6.6.3" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "ipykernel" }, + { name = "ipython" }, + { name = "jupyter-client" }, + { name = "jupyter-core" }, + { name = "prompt-toolkit" }, + { name = "pygments" }, + { name = "pyzmq" }, + { name = "traitlets" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/bd/2d/e2fd31e2fc41c14e2bcb6c976ab732597e907523f6b2420305f9fc7fdbdb/jupyter_console-6.6.3.tar.gz", hash = "sha256:566a4bf31c87adbfadf22cdf846e3069b59a71ed5da71d6ba4d8aaad14a53539", size = 34363, upload-time = "2023-03-06T14:13:31.02Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/ca/77/71d78d58f15c22db16328a476426f7ac4a60d3a5a7ba3b9627ee2f7903d4/jupyter_console-6.6.3-py3-none-any.whl", hash = "sha256:309d33409fcc92ffdad25f0bcdf9a4a9daa61b6f341177570fdac03de5352485", size = 24510, upload-time = "2023-03-06T14:13:28.229Z" }, +] + +[[package]] +name = "jupyter-core" +version = "5.9.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "platformdirs" }, + { name = "traitlets" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/02/49/9d1284d0dc65e2c757b74c6687b6d319b02f822ad039e5c512df9194d9dd/jupyter_core-5.9.1.tar.gz", hash = "sha256:4d09aaff303b9566c3ce657f580bd089ff5c91f5f89cf7d8846c3cdf465b5508", size = 89814, upload-time = "2025-10-16T19:19:18.444Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/e7/e7/80988e32bf6f73919a113473a604f5a8f09094de312b9d52b79c2df7612b/jupyter_core-5.9.1-py3-none-any.whl", hash = "sha256:ebf87fdc6073d142e114c72c9e29a9d7ca03fad818c5d300ce2adc1fb0743407", size = 29032, upload-time = "2025-10-16T19:19:16.783Z" }, +] + +[[package]] +name = "jupyter-docprovider" +version = "2.3.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/d8/d3/45571d4a7a4a2024750e582c17c1311052476dab4a2a02dbd68c7b5d0df0/jupyter_docprovider-2.3.0.tar.gz", hash = "sha256:c09808e15e93f2ea4ff194a18c7a8c8f83d81049fa91b09de24b09adeac9d572", size = 49964, upload-time = "2026-03-31T10:08:25.383Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/74/4a/af30f008f176d38c183a107b6556ba36f9e1a9970d5f730739bed4663c4a/jupyter_docprovider-2.3.0-py3-none-any.whl", hash = "sha256:44f9a8bfa47f069154e111b869f71c0e4297f201c56fa15ff308fe4b64c50f43", size = 35575, upload-time = "2026-03-31T10:08:23.534Z" }, +] + +[[package]] +name = "jupyter-events" +version = "0.12.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "jsonschema", extra = ["format-nongpl"] }, + { name = "packaging" }, + { name = "python-json-logger" }, + { name = "pyyaml" }, + { name = "referencing" }, + { name = "rfc3339-validator" }, + { name = "rfc3986-validator" }, + { name = "traitlets" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/9d/c3/306d090461e4cf3cd91eceaff84bede12a8e52cd821c2d20c9a4fd728385/jupyter_events-0.12.0.tar.gz", hash = "sha256:fc3fce98865f6784c9cd0a56a20644fc6098f21c8c33834a8d9fe383c17e554b", size = 62196, upload-time = "2025-02-03T17:23:41.485Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/e2/48/577993f1f99c552f18a0428731a755e06171f9902fa118c379eb7c04ea22/jupyter_events-0.12.0-py3-none-any.whl", hash = "sha256:6464b2fa5ad10451c3d35fabc75eab39556ae1e2853ad0c0cc31b656731a97fb", size = 19430, upload-time = "2025-02-03T17:23:38.643Z" }, +] + +[[package]] +name = "jupyter-kernel-client" +version = "0.9.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "jupyter-client" }, + { name = "jupyter-core" }, + { name = "jupyter-mimetypes" }, + { name = "requests" }, + { name = "traitlets" }, + { name = "typing-extensions" }, + { name = "websocket-client" }, +] +wheels = [ + { url = "https://files.pythonhosted.org/packages/7a/68/287315ba355aa93bda2e344de5febc45e6de1b47d8f4a5b69400b24cfdfd/jupyter_kernel_client-0.9.0-py3-none-any.whl", hash = "sha256:77acb8f2f738d97625d6bd01ee8cf21c4d59790b7ba464108712db3870416f20", size = 40097, upload-time = "2026-02-11T06:42:05.133Z" }, +] + +[[package]] +name = "jupyter-lsp" +version = "2.3.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "jupyter-server" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/36/ff/1e4a61f5170a9a1d978f3ac3872449de6c01fc71eaf89657824c878b1549/jupyter_lsp-2.3.1.tar.gz", hash = "sha256:fdf8a4aa7d85813976d6e29e95e6a2c8f752701f926f2715305249a3829805a6", size = 55677, upload-time = "2026-04-02T08:10:06.749Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/23/e8/9d61dcbd1dce8ef418f06befd4ac084b4720429c26b0b1222bc218685eff/jupyter_lsp-2.3.1-py3-none-any.whl", hash = "sha256:71b954d834e85ff3096400554f2eefaf7fe37053036f9a782b0f7c5e42dadb81", size = 77513, upload-time = "2026-04-02T08:10:01.753Z" }, +] + +[[package]] +name = "jupyter-mcp-server" +version = "0.4.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "jupyter-kernel-client" }, + { name = "jupyter-nbmodel-client" }, + { name = "mcp", extra = ["cli"] }, +] +wheels = [ + { url = "https://files.pythonhosted.org/packages/93/2f/0383d2b3b752a411abcb52dc3da7b7f064ecb8b902ed1c06dba5b57ac5c4/jupyter_mcp_server-0.4.0-py3-none-any.whl", hash = "sha256:54229b6201005f123479bdca1525a1d358af846027dd3067e4a37db128b87217", size = 7636, upload-time = "2025-06-13T07:51:11.072Z" }, +] + +[[package]] +name = "jupyter-mimetypes" +version = "0.2.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "pyarrow" }, + { name = "typing-extensions" }, +] +wheels = [ + { url = "https://files.pythonhosted.org/packages/72/45/cb4671e13fed39f721066ad1a00714d4b607982b8d3e97a25f836198d1df/jupyter_mimetypes-0.2.0-py3-none-any.whl", hash = "sha256:e6dcd989258e3fc944365b656d9173191517e0e393bd878e97ce500e5b388527", size = 16724, upload-time = "2025-08-10T18:18:27.309Z" }, +] + +[[package]] +name = "jupyter-nbmodel-client" +version = "0.11.2" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "datalayer-pycrdt" }, + { name = "jupyter-ydoc" }, + { name = "nbformat" }, + { name = "requests" }, + { name = "websockets" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/de/25/9dc9a4247fac5f4b5a13c1455f6a0e52538b26d877b5de93682a1aee3782/jupyter_nbmodel_client-0.11.2.tar.gz", hash = "sha256:fcf35823a5843ce7824f8411ab08d78fef1d07c306a5e195ce1777ba9ce0683e", size = 25761, upload-time = "2025-03-25T15:09:59.127Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/d3/60/e4de22326a765696746529c355a2cedc622bd18708c40b1ebcdc6839ddcb/jupyter_nbmodel_client-0.11.2-py3-none-any.whl", hash = "sha256:dfaec212064d16532b2bc93472aaec93c54b350efde342f581ba3bfad1e718d2", size = 26061, upload-time = "2025-03-25T15:09:57.266Z" }, +] + +[[package]] +name = "jupyter-server" +version = "2.17.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "anyio" }, + { name = "argon2-cffi" }, + { name = "jinja2" }, + { name = "jupyter-client" }, + { name = "jupyter-core" }, + { name = "jupyter-events" }, + { name = "jupyter-server-terminals" }, + { name = "nbconvert" }, + { name = "nbformat" }, + { name = "packaging" }, + { name = "prometheus-client" }, + { name = "pywinpty", marker = "os_name == 'nt'" }, + { name = "pyzmq" }, + { name = "send2trash" }, + { name = "terminado" }, + { name = "tornado" }, + { name = "traitlets" }, + { name = "websocket-client" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/5b/ac/e040ec363d7b6b1f11304cc9f209dac4517ece5d5e01821366b924a64a50/jupyter_server-2.17.0.tar.gz", hash = "sha256:c38ea898566964c888b4772ae1ed58eca84592e88251d2cfc4d171f81f7e99d5", size = 731949, upload-time = "2025-08-21T14:42:54.042Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/92/80/a24767e6ca280f5a49525d987bf3e4d7552bf67c8be07e8ccf20271f8568/jupyter_server-2.17.0-py3-none-any.whl", hash = "sha256:e8cb9c7db4251f51ed307e329b81b72ccf2056ff82d50524debde1ee1870e13f", size = 388221, upload-time = "2025-08-21T14:42:52.034Z" }, +] + +[[package]] +name = "jupyter-server-fileid" +version = "0.9.3" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "jupyter-events" }, + { name = "jupyter-server" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/0d/eb/7c2c09454bbf66b3727ba8c431d16159d642c0eb1aa179412a4f7af721cf/jupyter_server_fileid-0.9.3.tar.gz", hash = "sha256:521608bb87f606a8637fcbdce2f3d24a8b3cc89d2eef61751cb40e468d4e54be", size = 54959, upload-time = "2024-09-06T07:18:40.412Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/54/d6/5e5bca083664b1dd368e261107cbe2d350e3bdc62bdba8720fdbb9b9db39/jupyter_server_fileid-0.9.3-py3-none-any.whl", hash = "sha256:f73c01c19f90005d3fff93607b91b4955ba4e1dccdde9bfe8026646f94053791", size = 16922, upload-time = "2024-09-06T07:18:38.445Z" }, +] + +[[package]] +name = "jupyter-server-terminals" +version = "0.5.4" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "pywinpty", marker = "os_name == 'nt'" }, + { name = "terminado" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/f4/a7/bcd0a9b0cbba88986fe944aaaf91bfda603e5a50bda8ed15123f381a3b2f/jupyter_server_terminals-0.5.4.tar.gz", hash = "sha256:bbda128ed41d0be9020349f9f1f2a4ab9952a73ed5f5ac9f1419794761fb87f5", size = 31770, upload-time = "2026-01-14T16:53:20.213Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/d1/2d/6674563f71c6320841fc300911a55143925112a72a883e2ca71fba4c618d/jupyter_server_terminals-0.5.4-py3-none-any.whl", hash = "sha256:55be353fc74a80bc7f3b20e6be50a55a61cd525626f578dcb66a5708e2007d14", size = 13704, upload-time = "2026-01-14T16:53:18.738Z" }, +] + +[[package]] +name = "jupyter-server-ydoc" +version = "2.3.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "jsonschema" }, + { name = "jupyter-events" }, + { name = "jupyter-server" }, + { name = "jupyter-server-fileid" }, + { name = "jupyter-ydoc" }, + { name = "pycrdt" }, + { name = "pycrdt-websocket" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/f1/88/f81afcbd7cfca28c4d04086360a623319220f46a87f3206c1672f0411441/jupyter_server_ydoc-2.3.0.tar.gz", hash = "sha256:36f311491e9f289f461fcdf26afb9b72cdf0eac3ceed0c0cbc8ec43afc8efebc", size = 32103, upload-time = "2026-03-31T10:08:02.176Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/cd/73/18007b4fad0813a039b0c63c40b2f34f0f65f278c1d1670a323ff2d18638/jupyter_server_ydoc-2.3.0-py3-none-any.whl", hash = "sha256:888c4092592585f80d34f81e093aee4ce1b9d2e2601efb9e65eb5bdd23893a79", size = 33275, upload-time = "2026-03-31T10:08:00.239Z" }, +] + +[[package]] +name = "jupyter-ydoc" +version = "3.4.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "anyio" }, + { name = "pycrdt" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/22/f7/400e8ee54adb2396f7a70a85a8951bc696303a9bd413c5e35cc6c0c5c214/jupyter_ydoc-3.4.1.tar.gz", hash = "sha256:fb31f0e7033b8a5bf8920334e2b3dd9bdaba3052de3164de28e14525fd0bc4d8", size = 973504, upload-time = "2026-04-14T12:14:19.967Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/06/ff/15eca734d96277895573026dff14edd63d9d1709c02363f5902ea9767d71/jupyter_ydoc-3.4.1-py3-none-any.whl", hash = "sha256:848e5a9f37403846b7554b87d71495a38b6249579af64b1bde8de650b2e49d65", size = 14534, upload-time = "2026-04-14T12:14:18.439Z" }, +] + +[[package]] +name = "jupyterlab" +version = "4.5.6" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "async-lru" }, + { name = "httpx" }, + { name = "ipykernel" }, + { name = "jinja2" }, + { name = "jupyter-core" }, + { name = "jupyter-lsp" }, + { name = "jupyter-server" }, + { name = "jupyterlab-server" }, + { name = "notebook-shim" }, + { name = "packaging" }, + { name = "setuptools" }, + { name = "tornado" }, + { name = "traitlets" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/ac/d5/730628e03fff2e8a8e8ccdaedde1489ab1309f9a4fa2536248884e30b7c7/jupyterlab-4.5.6.tar.gz", hash = "sha256:642fe2cfe7f0f5922a8a558ba7a0d246c7bc133b708dfe43f7b3a826d163cf42", size = 23970670, upload-time = "2026-03-11T14:17:04.531Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/e1/1b/dad6fdcc658ed7af26fdf3841e7394072c9549a8b896c381ab49dd11e2d9/jupyterlab-4.5.6-py3-none-any.whl", hash = "sha256:d6b3dac883aa4d9993348e0f8e95b24624f75099aed64eab6a4351a9cdd1e580", size = 12447124, upload-time = "2026-03-11T14:17:00.229Z" }, +] + +[[package]] +name = "jupyterlab-pygments" +version = "0.3.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/90/51/9187be60d989df97f5f0aba133fa54e7300f17616e065d1ada7d7646b6d6/jupyterlab_pygments-0.3.0.tar.gz", hash = "sha256:721aca4d9029252b11cfa9d185e5b5af4d54772bb8072f9b7036f4170054d35d", size = 512900, upload-time = "2023-11-23T09:26:37.44Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/b1/dd/ead9d8ea85bf202d90cc513b533f9c363121c7792674f78e0d8a854b63b4/jupyterlab_pygments-0.3.0-py3-none-any.whl", hash = "sha256:841a89020971da1d8693f1a99997aefc5dc424bb1b251fd6322462a1b8842780", size = 15884, upload-time = "2023-11-23T09:26:34.325Z" }, +] + +[[package]] +name = "jupyterlab-server" +version = "2.28.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "babel" }, + { name = "jinja2" }, + { name = "json5" }, + { name = "jsonschema" }, + { name = "jupyter-server" }, + { name = "packaging" }, + { name = "requests" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/d6/2c/90153f189e421e93c4bb4f9e3f59802a1f01abd2ac5cf40b152d7f735232/jupyterlab_server-2.28.0.tar.gz", hash = "sha256:35baa81898b15f93573e2deca50d11ac0ae407ebb688299d3a5213265033712c", size = 76996, upload-time = "2025-10-22T13:59:18.37Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/e0/07/a000fe835f76b7e1143242ab1122e6362ef1c03f23f83a045c38859c2ae0/jupyterlab_server-2.28.0-py3-none-any.whl", hash = "sha256:e4355b148fdcf34d312bbbc80f22467d6d20460e8b8736bf235577dd18506968", size = 59830, upload-time = "2025-10-22T13:59:16.767Z" }, +] + +[[package]] +name = "jupyterlab-widgets" +version = "3.0.16" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/26/2d/ef58fed122b268c69c0aa099da20bc67657cdfb2e222688d5731bd5b971d/jupyterlab_widgets-3.0.16.tar.gz", hash = "sha256:423da05071d55cf27a9e602216d35a3a65a3e41cdf9c5d3b643b814ce38c19e0", size = 897423, upload-time = "2025-11-01T21:11:29.724Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/ab/b5/36c712098e6191d1b4e349304ef73a8d06aed77e56ceaac8c0a306c7bda1/jupyterlab_widgets-3.0.16-py3-none-any.whl", hash = "sha256:45fa36d9c6422cf2559198e4db481aa243c7a32d9926b500781c830c80f7ecf8", size = 914926, upload-time = "2025-11-01T21:11:28.008Z" }, +] + +[[package]] +name = "kiwisolver" +version = "1.5.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/d0/67/9c61eccb13f0bdca9307614e782fec49ffdde0f7a2314935d489fa93cd9c/kiwisolver-1.5.0.tar.gz", hash = "sha256:d4193f3d9dc3f6f79aaed0e5637f45d98850ebf01f7ca20e69457f3e8946b66a", size = 103482, upload-time = "2026-03-09T13:15:53.382Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/9d/69/024d6711d5ba575aa65d5538042e99964104e97fa153a9f10bc369182bc2/kiwisolver-1.5.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:fd40bb9cd0891c4c3cb1ddf83f8bbfa15731a248fdc8162669405451e2724b09", size = 123166, upload-time = "2026-03-09T13:13:48.032Z" }, + { url = "https://files.pythonhosted.org/packages/ce/48/adbb40df306f587054a348831220812b9b1d787aff714cfbc8556e38fccd/kiwisolver-1.5.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:c0e1403fd7c26d77c1f03e096dc58a5c726503fa0db0456678b8668f76f521e3", size = 66395, upload-time = "2026-03-09T13:13:49.365Z" }, + { url = "https://files.pythonhosted.org/packages/a8/3a/d0a972b34e1c63e2409413104216cd1caa02c5a37cb668d1687d466c1c45/kiwisolver-1.5.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:dda366d548e89a90d88a86c692377d18d8bd64b39c1fb2b92cb31370e2896bbd", size = 64065, upload-time = "2026-03-09T13:13:50.562Z" }, + { url = "https://files.pythonhosted.org/packages/2b/0a/7b98e1e119878a27ba8618ca1e18b14f992ff1eda40f47bccccf4de44121/kiwisolver-1.5.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:332b4f0145c30b5f5ad9374881133e5aa64320428a57c2c2b61e9d891a51c2f3", size = 1477903, upload-time = "2026-03-09T13:13:52.084Z" }, + { url = "https://files.pythonhosted.org/packages/18/d8/55638d89ffd27799d5cc3d8aa28e12f4ce7a64d67b285114dbedc8ea4136/kiwisolver-1.5.0-cp313-cp313-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:0c50b89ffd3e1a911c69a1dd3de7173c0cd10b130f56222e57898683841e4f96", size = 1278751, upload-time = "2026-03-09T13:13:54.673Z" }, + { url = "https://files.pythonhosted.org/packages/b8/97/b4c8d0d18421ecceba20ad8701358453b88e32414e6f6950b5a4bad54e65/kiwisolver-1.5.0-cp313-cp313-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:4db576bb8c3ef9365f8b40fe0f671644de6736ae2c27a2c62d7d8a1b4329f099", size = 1296793, upload-time = "2026-03-09T13:13:56.287Z" }, + { url = "https://files.pythonhosted.org/packages/c4/10/f862f94b6389d8957448ec9df59450b81bec4abb318805375c401a1e6892/kiwisolver-1.5.0-cp313-cp313-manylinux_2_24_s390x.manylinux_2_28_s390x.whl", hash = "sha256:0b85aad90cea8ac6797a53b5d5f2e967334fa4d1149f031c4537569972596cb8", size = 1346041, upload-time = "2026-03-09T13:13:58.269Z" }, + { url = "https://files.pythonhosted.org/packages/a3/6a/f1650af35821eaf09de398ec0bc2aefc8f211f0cda50204c9f1673741ba9/kiwisolver-1.5.0-cp313-cp313-manylinux_2_39_riscv64.whl", hash = "sha256:d36ca54cb4c6c4686f7cbb7b817f66f5911c12ddb519450bbe86707155028f87", size = 987292, upload-time = "2026-03-09T13:13:59.871Z" }, + { url = "https://files.pythonhosted.org/packages/de/19/d7fb82984b9238115fe629c915007be608ebd23dc8629703d917dbfaffd4/kiwisolver-1.5.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:38f4a703656f493b0ad185211ccfca7f0386120f022066b018eb5296d8613e23", size = 2227865, upload-time = "2026-03-09T13:14:01.401Z" }, + { url = "https://files.pythonhosted.org/packages/7f/b9/46b7f386589fd222dac9e9de9c956ce5bcefe2ee73b4e79891381dda8654/kiwisolver-1.5.0-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:3ac2360e93cb41be81121755c6462cff3beaa9967188c866e5fce5cf13170859", size = 2324369, upload-time = "2026-03-09T13:14:02.972Z" }, + { url = "https://files.pythonhosted.org/packages/92/8b/95e237cf3d9c642960153c769ddcbe278f182c8affb20cecc1cc983e7cc5/kiwisolver-1.5.0-cp313-cp313-musllinux_1_2_riscv64.whl", hash = "sha256:c95cab08d1965db3d84a121f1c7ce7479bdd4072c9b3dafd8fecce48a2e6b902", size = 1977989, upload-time = "2026-03-09T13:14:04.503Z" }, + { url = "https://files.pythonhosted.org/packages/1b/95/980c9df53501892784997820136c01f62bc1865e31b82b9560f980c0e649/kiwisolver-1.5.0-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:fc20894c3d21194d8041a28b65622d5b86db786da6e3cfe73f0c762951a61167", size = 2491645, upload-time = "2026-03-09T13:14:06.106Z" }, + { url = "https://files.pythonhosted.org/packages/cb/32/900647fd0840abebe1561792c6b31e6a7c0e278fc3973d30572a965ca14c/kiwisolver-1.5.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:7a32f72973f0f950c1920475d5c5ea3d971b81b6f0ec53b8d0a956cc965f22e0", size = 2295237, upload-time = "2026-03-09T13:14:08.891Z" }, + { url = "https://files.pythonhosted.org/packages/be/8a/be60e3bbcf513cc5a50f4a3e88e1dcecebb79c1ad607a7222877becaa101/kiwisolver-1.5.0-cp313-cp313-win_amd64.whl", hash = "sha256:0bf3acf1419fa93064a4c2189ac0b58e3be7872bf6ee6177b0d4c63dc4cea276", size = 73573, upload-time = "2026-03-09T13:14:12.327Z" }, + { url = "https://files.pythonhosted.org/packages/4d/d2/64be2e429eb4fca7f7e1c52a91b12663aeaf25de3895e5cca0f47ef2a8d0/kiwisolver-1.5.0-cp313-cp313-win_arm64.whl", hash = "sha256:fa8eb9ecdb7efb0b226acec134e0d709e87a909fa4971a54c0c4f6e88635484c", size = 64998, upload-time = "2026-03-09T13:14:13.469Z" }, + { url = "https://files.pythonhosted.org/packages/b0/69/ce68dd0c85755ae2de490bf015b62f2cea5f6b14ff00a463f9d0774449ff/kiwisolver-1.5.0-cp313-cp313t-macosx_10_13_universal2.whl", hash = "sha256:db485b3847d182b908b483b2ed133c66d88d49cacf98fd278fadafe11b4478d1", size = 125700, upload-time = "2026-03-09T13:14:14.636Z" }, + { url = "https://files.pythonhosted.org/packages/74/aa/937aac021cf9d4349990d47eb319309a51355ed1dbdc9c077cdc9224cb11/kiwisolver-1.5.0-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:be12f931839a3bdfe28b584db0e640a65a8bcbc24560ae3fdb025a449b3d754e", size = 67537, upload-time = "2026-03-09T13:14:15.808Z" }, + { url = "https://files.pythonhosted.org/packages/ee/20/3a87fbece2c40ad0f6f0aefa93542559159c5f99831d596050e8afae7a9f/kiwisolver-1.5.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:16b85d37c2cbb3253226d26e64663f755d88a03439a9c47df6246b35defbdfb7", size = 65514, upload-time = "2026-03-09T13:14:18.035Z" }, + { url = "https://files.pythonhosted.org/packages/f0/7f/f943879cda9007c45e1f7dba216d705c3a18d6b35830e488b6c6a4e7cdf0/kiwisolver-1.5.0-cp313-cp313t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:4432b835675f0ea7414aab3d37d119f7226d24869b7a829caeab49ebda407b0c", size = 1584848, upload-time = "2026-03-09T13:14:19.745Z" }, + { url = "https://files.pythonhosted.org/packages/37/f8/4d4f85cc1870c127c88d950913370dd76138482161cd07eabbc450deff01/kiwisolver-1.5.0-cp313-cp313t-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:1b0feb50971481a2cc44d94e88bdb02cdd497618252ae226b8eb1201b957e368", size = 1391542, upload-time = "2026-03-09T13:14:21.54Z" }, + { url = "https://files.pythonhosted.org/packages/04/0b/65dd2916c84d252b244bd405303220f729e7c17c9d7d33dca6feeff9ffc4/kiwisolver-1.5.0-cp313-cp313t-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:56fa888f10d0f367155e76ce849fa1166fc9730d13bd2d65a2aa13b6f5424489", size = 1404447, upload-time = "2026-03-09T13:14:23.205Z" }, + { url = "https://files.pythonhosted.org/packages/39/5c/2606a373247babce9b1d056c03a04b65f3cf5290a8eac5d7bdead0a17e21/kiwisolver-1.5.0-cp313-cp313t-manylinux_2_24_s390x.manylinux_2_28_s390x.whl", hash = "sha256:940dda65d5e764406b9fb92761cbf462e4e63f712ab60ed98f70552e496f3bf1", size = 1455918, upload-time = "2026-03-09T13:14:24.74Z" }, + { url = "https://files.pythonhosted.org/packages/d5/d1/c6078b5756670658e9192a2ef11e939c92918833d2745f85cd14a6004bdf/kiwisolver-1.5.0-cp313-cp313t-manylinux_2_39_riscv64.whl", hash = "sha256:89fc958c702ee9a745e4700378f5d23fddbc46ff89e8fdbf5395c24d5c1452a3", size = 1072856, upload-time = "2026-03-09T13:14:26.597Z" }, + { url = "https://files.pythonhosted.org/packages/cb/c8/7def6ddf16eb2b3741d8b172bdaa9af882b03c78e9b0772975408801fa63/kiwisolver-1.5.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:9027d773c4ff81487181a925945743413f6069634d0b122d0b37684ccf4f1e18", size = 2333580, upload-time = "2026-03-09T13:14:28.237Z" }, + { url = "https://files.pythonhosted.org/packages/9e/87/2ac1fce0eb1e616fcd3c35caa23e665e9b1948bb984f4764790924594128/kiwisolver-1.5.0-cp313-cp313t-musllinux_1_2_ppc64le.whl", hash = "sha256:5b233ea3e165e43e35dba1d2b8ecc21cf070b45b65ae17dd2747d2713d942021", size = 2423018, upload-time = "2026-03-09T13:14:30.018Z" }, + { url = "https://files.pythonhosted.org/packages/67/13/c6700ccc6cc218716bfcda4935e4b2997039869b4ad8a94f364c5a3b8e63/kiwisolver-1.5.0-cp313-cp313t-musllinux_1_2_riscv64.whl", hash = "sha256:ce9bf03dad3b46408c08649c6fbd6ca28a9fce0eb32fdfffa6775a13103b5310", size = 2062804, upload-time = "2026-03-09T13:14:32.888Z" }, + { url = "https://files.pythonhosted.org/packages/1b/bd/877056304626943ff0f1f44c08f584300c199b887cb3176cd7e34f1515f1/kiwisolver-1.5.0-cp313-cp313t-musllinux_1_2_s390x.whl", hash = "sha256:fc4d3f1fb9ca0ae9f97b095963bc6326f1dbfd3779d6679a1e016b9baaa153d3", size = 2597482, upload-time = "2026-03-09T13:14:34.971Z" }, + { url = "https://files.pythonhosted.org/packages/75/19/c60626c47bf0f8ac5dcf72c6c98e266d714f2fbbfd50cf6dab5ede3aaa50/kiwisolver-1.5.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:f443b4825c50a51ee68585522ab4a1d1257fac65896f282b4c6763337ac9f5d2", size = 2394328, upload-time = "2026-03-09T13:14:36.816Z" }, + { url = "https://files.pythonhosted.org/packages/47/84/6a6d5e5bb8273756c27b7d810d47f7ef2f1f9b9fd23c9ee9a3f8c75c9cef/kiwisolver-1.5.0-cp313-cp313t-win_arm64.whl", hash = "sha256:893ff3a711d1b515ba9da14ee090519bad4610ed1962fbe298a434e8c5f8db53", size = 68410, upload-time = "2026-03-09T13:14:38.695Z" }, + { url = "https://files.pythonhosted.org/packages/e4/d7/060f45052f2a01ad5762c8fdecd6d7a752b43400dc29ff75cd47225a40fd/kiwisolver-1.5.0-cp314-cp314-macosx_10_15_universal2.whl", hash = "sha256:8df31fe574b8b3993cc61764f40941111b25c2d9fea13d3ce24a49907cd2d615", size = 123231, upload-time = "2026-03-09T13:14:41.323Z" }, + { url = "https://files.pythonhosted.org/packages/c2/a7/78da680eadd06ff35edef6ef68a1ad273bad3e2a0936c9a885103230aece/kiwisolver-1.5.0-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:1d49a49ac4cbfb7c1375301cd1ec90169dfeae55ff84710d782260ce77a75a02", size = 66489, upload-time = "2026-03-09T13:14:42.534Z" }, + { url = "https://files.pythonhosted.org/packages/49/b2/97980f3ad4fae37dd7fe31626e2bf75fbf8bdf5d303950ec1fab39a12da8/kiwisolver-1.5.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:0cbe94b69b819209a62cb27bdfa5dc2a8977d8de2f89dfd97ba4f53ed3af754e", size = 64063, upload-time = "2026-03-09T13:14:44.759Z" }, + { url = "https://files.pythonhosted.org/packages/e7/f9/b06c934a6aa8bc91f566bd2a214fd04c30506c2d9e2b6b171953216a65b6/kiwisolver-1.5.0-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:80aa065ffd378ff784822a6d7c3212f2d5f5e9c3589614b5c228b311fd3063ac", size = 1475913, upload-time = "2026-03-09T13:14:46.247Z" }, + { url = "https://files.pythonhosted.org/packages/6b/f0/f768ae564a710135630672981231320bc403cf9152b5596ec5289de0f106/kiwisolver-1.5.0-cp314-cp314-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:4e7f886f47ab881692f278ae901039a234e4025a68e6dfab514263a0b1c4ae05", size = 1282782, upload-time = "2026-03-09T13:14:48.458Z" }, + { url = "https://files.pythonhosted.org/packages/e2/9f/1de7aad00697325f05238a5f2eafbd487fb637cc27a558b5367a5f37fb7f/kiwisolver-1.5.0-cp314-cp314-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:5060731cc3ed12ca3a8b57acd4aeca5bbc2f49216dd0bec1650a1acd89486bcd", size = 1300815, upload-time = "2026-03-09T13:14:50.721Z" }, + { url = "https://files.pythonhosted.org/packages/5a/c2/297f25141d2e468e0ce7f7a7b92e0cf8918143a0cbd3422c1ad627e85a06/kiwisolver-1.5.0-cp314-cp314-manylinux_2_24_s390x.manylinux_2_28_s390x.whl", hash = "sha256:7a4aa69609f40fce3cbc3f87b2061f042eee32f94b8f11db707b66a26461591a", size = 1347925, upload-time = "2026-03-09T13:14:52.304Z" }, + { url = "https://files.pythonhosted.org/packages/b9/d3/f4c73a02eb41520c47610207b21afa8cdd18fdbf64ffd94674ae21c4812d/kiwisolver-1.5.0-cp314-cp314-manylinux_2_39_riscv64.whl", hash = "sha256:d168fda2dbff7b9b5f38e693182d792a938c31db4dac3a80a4888de603c99554", size = 991322, upload-time = "2026-03-09T13:14:54.637Z" }, + { url = "https://files.pythonhosted.org/packages/7b/46/d3f2efef7732fcda98d22bf4ad5d3d71d545167a852ca710a494f4c15343/kiwisolver-1.5.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:413b820229730d358efd838ecbab79902fe97094565fdc80ddb6b0a18c18a581", size = 2232857, upload-time = "2026-03-09T13:14:56.471Z" }, + { url = "https://files.pythonhosted.org/packages/3f/ec/2d9756bf2b6d26ae4349b8d3662fb3993f16d80c1f971c179ce862b9dbae/kiwisolver-1.5.0-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:5124d1ea754509b09e53738ec185584cc609aae4a3b510aaf4ed6aa047ef9303", size = 2329376, upload-time = "2026-03-09T13:14:58.072Z" }, + { url = "https://files.pythonhosted.org/packages/8f/9f/876a0a0f2260f1bde92e002b3019a5fabc35e0939c7d945e0fa66185eb20/kiwisolver-1.5.0-cp314-cp314-musllinux_1_2_riscv64.whl", hash = "sha256:e4415a8db000bf49a6dd1c478bf70062eaacff0f462b92b0ba68791a905861f9", size = 1982549, upload-time = "2026-03-09T13:14:59.668Z" }, + { url = "https://files.pythonhosted.org/packages/6c/4f/ba3624dfac23a64d54ac4179832860cb537c1b0af06024936e82ca4154a0/kiwisolver-1.5.0-cp314-cp314-musllinux_1_2_s390x.whl", hash = "sha256:d618fd27420381a4f6044faa71f46d8bfd911bd077c555f7138ed88729bfbe79", size = 2494680, upload-time = "2026-03-09T13:15:01.364Z" }, + { url = "https://files.pythonhosted.org/packages/39/b7/97716b190ab98911b20d10bf92eca469121ec483b8ce0edd314f51bc85af/kiwisolver-1.5.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:5092eb5b1172947f57d6ea7d89b2f29650414e4293c47707eb499ec07a0ac796", size = 2297905, upload-time = "2026-03-09T13:15:03.925Z" }, + { url = "https://files.pythonhosted.org/packages/a3/36/4e551e8aa55c9188bca9abb5096805edbf7431072b76e2298e34fd3a3008/kiwisolver-1.5.0-cp314-cp314-win_amd64.whl", hash = "sha256:d76e2d8c75051d58177e762164d2e9ab92886534e3a12e795f103524f221dd8e", size = 75086, upload-time = "2026-03-09T13:15:07.775Z" }, + { url = "https://files.pythonhosted.org/packages/70/15/9b90f7df0e31a003c71649cf66ef61c3c1b862f48c81007fa2383c8bd8d7/kiwisolver-1.5.0-cp314-cp314-win_arm64.whl", hash = "sha256:fa6248cd194edff41d7ea9425ced8ca3a6f838bfb295f6f1d6e6bb694a8518df", size = 66577, upload-time = "2026-03-09T13:15:09.139Z" }, + { url = "https://files.pythonhosted.org/packages/17/01/7dc8c5443ff42b38e72731643ed7cf1ed9bf01691ae5cdca98501999ed83/kiwisolver-1.5.0-cp314-cp314t-macosx_10_15_universal2.whl", hash = "sha256:d1ffeb80b5676463d7a7d56acbe8e37a20ce725570e09549fe738e02ca6b7e1e", size = 125794, upload-time = "2026-03-09T13:15:10.525Z" }, + { url = "https://files.pythonhosted.org/packages/46/8a/b4ebe46ebaac6a303417fab10c2e165c557ddaff558f9699d302b256bc53/kiwisolver-1.5.0-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:bc4d8e252f532ab46a1de9349e2d27b91fce46736a9eedaa37beaca66f574ed4", size = 67646, upload-time = "2026-03-09T13:15:12.016Z" }, + { url = "https://files.pythonhosted.org/packages/60/35/10a844afc5f19d6f567359bf4789e26661755a2f36200d5d1ed8ad0126e5/kiwisolver-1.5.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:6783e069732715ad0c3ce96dbf21dbc2235ab0593f2baf6338101f70371f4028", size = 65511, upload-time = "2026-03-09T13:15:13.311Z" }, + { url = "https://files.pythonhosted.org/packages/f8/8a/685b297052dd041dcebce8e8787b58923b6e78acc6115a0dc9189011c44b/kiwisolver-1.5.0-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:e7c4c09a490dc4d4a7f8cbee56c606a320f9dc28cf92a7157a39d1ce7676a657", size = 1584858, upload-time = "2026-03-09T13:15:15.103Z" }, + { url = "https://files.pythonhosted.org/packages/9e/80/04865e3d4638ac5bddec28908916df4a3075b8c6cc101786a96803188b96/kiwisolver-1.5.0-cp314-cp314t-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:2a075bd7bd19c70cf67c8badfa36cf7c5d8de3c9ddb8420c51e10d9c50e94920", size = 1392539, upload-time = "2026-03-09T13:15:16.661Z" }, + { url = "https://files.pythonhosted.org/packages/ba/01/77a19cacc0893fa13fafa46d1bba06fb4dc2360b3292baf4b56d8e067b24/kiwisolver-1.5.0-cp314-cp314t-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:bdd3e53429ff02aa319ba59dfe4ceeec345bf46cf180ec2cf6fd5b942e7975e9", size = 1405310, upload-time = "2026-03-09T13:15:18.229Z" }, + { url = "https://files.pythonhosted.org/packages/53/39/bcaf5d0cca50e604cfa9b4e3ae1d64b50ca1ae5b754122396084599ef903/kiwisolver-1.5.0-cp314-cp314t-manylinux_2_24_s390x.manylinux_2_28_s390x.whl", hash = "sha256:3cdcb35dc9d807259c981a85531048ede628eabcffb3239adf3d17463518992d", size = 1456244, upload-time = "2026-03-09T13:15:20.444Z" }, + { url = "https://files.pythonhosted.org/packages/d0/7a/72c187abc6975f6978c3e39b7cf67aeb8b3c0a8f9790aa7fd412855e9e1f/kiwisolver-1.5.0-cp314-cp314t-manylinux_2_39_riscv64.whl", hash = "sha256:70d593af6a6ca332d1df73d519fddb5148edb15cd90d5f0155e3746a6d4fcc65", size = 1073154, upload-time = "2026-03-09T13:15:22.039Z" }, + { url = "https://files.pythonhosted.org/packages/c7/ca/cf5b25783ebbd59143b4371ed0c8428a278abe68d6d0104b01865b1bbd0f/kiwisolver-1.5.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:377815a8616074cabbf3f53354e1d040c35815a134e01d7614b7692e4bf8acfa", size = 2334377, upload-time = "2026-03-09T13:15:23.741Z" }, + { url = "https://files.pythonhosted.org/packages/4a/e5/b1f492adc516796e88751282276745340e2a72dcd0d36cf7173e0daf3210/kiwisolver-1.5.0-cp314-cp314t-musllinux_1_2_ppc64le.whl", hash = "sha256:0255a027391d52944eae1dbb5d4cc5903f57092f3674e8e544cdd2622826b3f0", size = 2425288, upload-time = "2026-03-09T13:15:25.789Z" }, + { url = "https://files.pythonhosted.org/packages/e6/e5/9b21fbe91a61b8f409d74a26498706e97a48008bfcd1864373d32a6ba31c/kiwisolver-1.5.0-cp314-cp314t-musllinux_1_2_riscv64.whl", hash = "sha256:012b1eb16e28718fa782b5e61dc6f2da1f0792ca73bd05d54de6cb9561665fc9", size = 2063158, upload-time = "2026-03-09T13:15:27.63Z" }, + { url = "https://files.pythonhosted.org/packages/b1/02/83f47986138310f95ea95531f851b2a62227c11cbc3e690ae1374fe49f0f/kiwisolver-1.5.0-cp314-cp314t-musllinux_1_2_s390x.whl", hash = "sha256:0e3aafb33aed7479377e5e9a82e9d4bf87063741fc99fc7ae48b0f16e32bdd6f", size = 2597260, upload-time = "2026-03-09T13:15:29.421Z" }, + { url = "https://files.pythonhosted.org/packages/07/18/43a5f24608d8c313dd189cf838c8e68d75b115567c6279de7796197cfb6a/kiwisolver-1.5.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:e7a116ae737f0000343218c4edf5bd45893bfeaff0993c0b215d7124c9f77646", size = 2394403, upload-time = "2026-03-09T13:15:31.517Z" }, + { url = "https://files.pythonhosted.org/packages/3b/b5/98222136d839b8afabcaa943b09bd05888c2d36355b7e448550211d1fca4/kiwisolver-1.5.0-cp314-cp314t-win_amd64.whl", hash = "sha256:1dd9b0b119a350976a6d781e7278ec7aca0b201e1a9e2d23d9804afecb6ca681", size = 79687, upload-time = "2026-03-09T13:15:33.204Z" }, + { url = "https://files.pythonhosted.org/packages/99/a2/ca7dc962848040befed12732dff6acae7fb3c4f6fc4272b3f6c9a30b8713/kiwisolver-1.5.0-cp314-cp314t-win_arm64.whl", hash = "sha256:58f812017cd2985c21fbffb4864d59174d4903dd66fa23815e74bbc7a0e2dd57", size = 70032, upload-time = "2026-03-09T13:15:34.411Z" }, +] + +[[package]] +name = "lark" +version = "1.3.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/da/34/28fff3ab31ccff1fd4f6c7c7b0ceb2b6968d8ea4950663eadcb5720591a0/lark-1.3.1.tar.gz", hash = "sha256:b426a7a6d6d53189d318f2b6236ab5d6429eaf09259f1ca33eb716eed10d2905", size = 382732, upload-time = "2025-10-27T18:25:56.653Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/82/3d/14ce75ef66813643812f3093ab17e46d3a206942ce7376d31ec2d36229e7/lark-1.3.1-py3-none-any.whl", hash = "sha256:c629b661023a014c37da873b4ff58a817398d12635d3bbb2c5a03be7fe5d1e12", size = 113151, upload-time = "2025-10-27T18:25:54.882Z" }, +] + +[[package]] +name = "markdown-it-py" +version = "4.0.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "mdurl" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/5b/f5/4ec618ed16cc4f8fb3b701563655a69816155e79e24a17b651541804721d/markdown_it_py-4.0.0.tar.gz", hash = "sha256:cb0a2b4aa34f932c007117b194e945bd74e0ec24133ceb5bac59009cda1cb9f3", size = 73070, upload-time = "2025-08-11T12:57:52.854Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/94/54/e7d793b573f298e1c9013b8c4dade17d481164aa517d1d7148619c2cedbf/markdown_it_py-4.0.0-py3-none-any.whl", hash = "sha256:87327c59b172c5011896038353a81343b6754500a08cd7a4973bb48c6d578147", size = 87321, upload-time = "2025-08-11T12:57:51.923Z" }, +] + +[[package]] +name = "markupsafe" +version = "3.0.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" }, +] + +[[package]] +name = "matplotlib" +version = "3.10.8" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "contourpy" }, + { name = "cycler" }, + { name = "fonttools" }, + { name = "kiwisolver" }, + { name = "numpy" }, + { name = "packaging" }, + { name = "pillow" }, + { name = "pyparsing" }, + { name = "python-dateutil" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/8a/76/d3c6e3a13fe484ebe7718d14e269c9569c4eb0020a968a327acb3b9a8fe6/matplotlib-3.10.8.tar.gz", hash = "sha256:2299372c19d56bcd35cf05a2738308758d32b9eaed2371898d8f5bd33f084aa3", size = 34806269, upload-time = "2025-12-10T22:56:51.155Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/3d/b9/15fd5541ef4f5b9a17eefd379356cf12175fe577424e7b1d80676516031a/matplotlib-3.10.8-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:3f2e409836d7f5ac2f1c013110a4d50b9f7edc26328c108915f9075d7d7a91b6", size = 8261076, upload-time = "2025-12-10T22:55:44.648Z" }, + { url = "https://files.pythonhosted.org/packages/8d/a0/2ba3473c1b66b9c74dc7107c67e9008cb1782edbe896d4c899d39ae9cf78/matplotlib-3.10.8-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:56271f3dac49a88d7fca5060f004d9d22b865f743a12a23b1e937a0be4818ee1", size = 8148794, upload-time = "2025-12-10T22:55:46.252Z" }, + { url = "https://files.pythonhosted.org/packages/75/97/a471f1c3eb1fd6f6c24a31a5858f443891d5127e63a7788678d14e249aea/matplotlib-3.10.8-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:a0a7f52498f72f13d4a25ea70f35f4cb60642b466cbb0a9be951b5bc3f45a486", size = 8718474, upload-time = "2025-12-10T22:55:47.864Z" }, + { url = "https://files.pythonhosted.org/packages/01/be/cd478f4b66f48256f42927d0acbcd63a26a893136456cd079c0cc24fbabf/matplotlib-3.10.8-cp313-cp313-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:646d95230efb9ca614a7a594d4fcacde0ac61d25e37dd51710b36477594963ce", size = 9549637, upload-time = "2025-12-10T22:55:50.048Z" }, + { url = "https://files.pythonhosted.org/packages/5d/7c/8dc289776eae5109e268c4fb92baf870678dc048a25d4ac903683b86d5bf/matplotlib-3.10.8-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:f89c151aab2e2e23cb3fe0acad1e8b82841fd265379c4cecd0f3fcb34c15e0f6", size = 9613678, upload-time = "2025-12-10T22:55:52.21Z" }, + { url = "https://files.pythonhosted.org/packages/64/40/37612487cc8a437d4dd261b32ca21fe2d79510fe74af74e1f42becb1bdb8/matplotlib-3.10.8-cp313-cp313-win_amd64.whl", hash = "sha256:e8ea3e2d4066083e264e75c829078f9e149fa119d27e19acd503de65e0b13149", size = 8142686, upload-time = "2025-12-10T22:55:54.253Z" }, + { url = "https://files.pythonhosted.org/packages/66/52/8d8a8730e968185514680c2a6625943f70269509c3dcfc0dcf7d75928cb8/matplotlib-3.10.8-cp313-cp313-win_arm64.whl", hash = "sha256:c108a1d6fa78a50646029cb6d49808ff0fc1330fda87fa6f6250c6b5369b6645", size = 8012917, upload-time = "2025-12-10T22:55:56.268Z" }, + { url = "https://files.pythonhosted.org/packages/b5/27/51fe26e1062f298af5ef66343d8ef460e090a27fea73036c76c35821df04/matplotlib-3.10.8-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:ad3d9833a64cf48cc4300f2b406c3d0f4f4724a91c0bd5640678a6ba7c102077", size = 8305679, upload-time = "2025-12-10T22:55:57.856Z" }, + { url = "https://files.pythonhosted.org/packages/2c/1e/4de865bc591ac8e3062e835f42dd7fe7a93168d519557837f0e37513f629/matplotlib-3.10.8-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:eb3823f11823deade26ce3b9f40dcb4a213da7a670013929f31d5f5ed1055b22", size = 8198336, upload-time = "2025-12-10T22:55:59.371Z" }, + { url = "https://files.pythonhosted.org/packages/c6/cb/2f7b6e75fb4dce87ef91f60cac4f6e34f4c145ab036a22318ec837971300/matplotlib-3.10.8-cp313-cp313t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:d9050fee89a89ed57b4fb2c1bfac9a3d0c57a0d55aed95949eedbc42070fea39", size = 8731653, upload-time = "2025-12-10T22:56:01.032Z" }, + { url = "https://files.pythonhosted.org/packages/46/b3/bd9c57d6ba670a37ab31fb87ec3e8691b947134b201f881665b28cc039ff/matplotlib-3.10.8-cp313-cp313t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:b44d07310e404ba95f8c25aa5536f154c0a8ec473303535949e52eb71d0a1565", size = 9561356, upload-time = "2025-12-10T22:56:02.95Z" }, + { url = "https://files.pythonhosted.org/packages/c0/3d/8b94a481456dfc9dfe6e39e93b5ab376e50998cddfd23f4ae3b431708f16/matplotlib-3.10.8-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:0a33deb84c15ede243aead39f77e990469fff93ad1521163305095b77b72ce4a", size = 9614000, upload-time = "2025-12-10T22:56:05.411Z" }, + { url = "https://files.pythonhosted.org/packages/bd/cd/bc06149fe5585ba800b189a6a654a75f1f127e8aab02fd2be10df7fa500c/matplotlib-3.10.8-cp313-cp313t-win_amd64.whl", hash = "sha256:3a48a78d2786784cc2413e57397981fb45c79e968d99656706018d6e62e57958", size = 8220043, upload-time = "2025-12-10T22:56:07.551Z" }, + { url = "https://files.pythonhosted.org/packages/e3/de/b22cf255abec916562cc04eef457c13e58a1990048de0c0c3604d082355e/matplotlib-3.10.8-cp313-cp313t-win_arm64.whl", hash = "sha256:15d30132718972c2c074cd14638c7f4592bd98719e2308bccea40e0538bc0cb5", size = 8062075, upload-time = "2025-12-10T22:56:09.178Z" }, + { url = "https://files.pythonhosted.org/packages/3c/43/9c0ff7a2f11615e516c3b058e1e6e8f9614ddeca53faca06da267c48345d/matplotlib-3.10.8-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:b53285e65d4fa4c86399979e956235deb900be5baa7fc1218ea67fbfaeaadd6f", size = 8262481, upload-time = "2025-12-10T22:56:10.885Z" }, + { url = "https://files.pythonhosted.org/packages/6f/ca/e8ae28649fcdf039fda5ef554b40a95f50592a3c47e6f7270c9561c12b07/matplotlib-3.10.8-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:32f8dce744be5569bebe789e46727946041199030db8aeb2954d26013a0eb26b", size = 8151473, upload-time = "2025-12-10T22:56:12.377Z" }, + { url = "https://files.pythonhosted.org/packages/f1/6f/009d129ae70b75e88cbe7e503a12a4c0670e08ed748a902c2568909e9eb5/matplotlib-3.10.8-cp314-cp314-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:4cf267add95b1c88300d96ca837833d4112756045364f5c734a2276038dae27d", size = 9553896, upload-time = "2025-12-10T22:56:14.432Z" }, + { url = "https://files.pythonhosted.org/packages/f5/26/4221a741eb97967bc1fd5e4c52b9aa5a91b2f4ec05b59f6def4d820f9df9/matplotlib-3.10.8-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:2cf5bd12cecf46908f286d7838b2abc6c91cda506c0445b8223a7c19a00df008", size = 9824193, upload-time = "2025-12-10T22:56:16.29Z" }, + { url = "https://files.pythonhosted.org/packages/1f/f3/3abf75f38605772cf48a9daf5821cd4f563472f38b4b828c6fba6fa6d06e/matplotlib-3.10.8-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:41703cc95688f2516b480f7f339d8851a6035f18e100ee6a32bc0b8536a12a9c", size = 9615444, upload-time = "2025-12-10T22:56:18.155Z" }, + { url = "https://files.pythonhosted.org/packages/93/a5/de89ac80f10b8dc615807ee1133cd99ac74082581196d4d9590bea10690d/matplotlib-3.10.8-cp314-cp314-win_amd64.whl", hash = "sha256:83d282364ea9f3e52363da262ce32a09dfe241e4080dcedda3c0db059d3c1f11", size = 8272719, upload-time = "2025-12-10T22:56:20.366Z" }, + { url = "https://files.pythonhosted.org/packages/69/ce/b006495c19ccc0a137b48083168a37bd056392dee02f87dba0472f2797fe/matplotlib-3.10.8-cp314-cp314-win_arm64.whl", hash = "sha256:2c1998e92cd5999e295a731bcb2911c75f597d937341f3030cc24ef2733d78a8", size = 8144205, upload-time = "2025-12-10T22:56:22.239Z" }, + { url = "https://files.pythonhosted.org/packages/68/d9/b31116a3a855bd313c6fcdb7226926d59b041f26061c6c5b1be66a08c826/matplotlib-3.10.8-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:b5a2b97dbdc7d4f353ebf343744f1d1f1cca8aa8bfddb4262fcf4306c3761d50", size = 8305785, upload-time = "2025-12-10T22:56:24.218Z" }, + { url = "https://files.pythonhosted.org/packages/1e/90/6effe8103f0272685767ba5f094f453784057072f49b393e3ea178fe70a5/matplotlib-3.10.8-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:3f5c3e4da343bba819f0234186b9004faba952cc420fbc522dc4e103c1985908", size = 8198361, upload-time = "2025-12-10T22:56:26.787Z" }, + { url = "https://files.pythonhosted.org/packages/d7/65/a73188711bea603615fc0baecca1061429ac16940e2385433cc778a9d8e7/matplotlib-3.10.8-cp314-cp314t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:5f62550b9a30afde8c1c3ae450e5eb547d579dd69b25c2fc7a1c67f934c1717a", size = 9561357, upload-time = "2025-12-10T22:56:28.953Z" }, + { url = "https://files.pythonhosted.org/packages/f4/3d/b5c5d5d5be8ce63292567f0e2c43dde9953d3ed86ac2de0a72e93c8f07a1/matplotlib-3.10.8-cp314-cp314t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:495672de149445ec1b772ff2c9ede9b769e3cb4f0d0aa7fa730d7f59e2d4e1c1", size = 9823610, upload-time = "2025-12-10T22:56:31.455Z" }, + { url = "https://files.pythonhosted.org/packages/4d/4b/e7beb6bbd49f6bae727a12b270a2654d13c397576d25bd6786e47033300f/matplotlib-3.10.8-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:595ba4d8fe983b88f0eec8c26a241e16d6376fe1979086232f481f8f3f67494c", size = 9614011, upload-time = "2025-12-10T22:56:33.85Z" }, + { url = "https://files.pythonhosted.org/packages/7c/e6/76f2813d31f032e65f6f797e3f2f6e4aab95b65015924b1c51370395c28a/matplotlib-3.10.8-cp314-cp314t-win_amd64.whl", hash = "sha256:25d380fe8b1dc32cf8f0b1b448470a77afb195438bafdf1d858bfb876f3edf7b", size = 8362801, upload-time = "2025-12-10T22:56:36.107Z" }, + { url = "https://files.pythonhosted.org/packages/5d/49/d651878698a0b67f23aa28e17f45a6d6dd3d3f933fa29087fa4ce5947b5a/matplotlib-3.10.8-cp314-cp314t-win_arm64.whl", hash = "sha256:113bb52413ea508ce954a02c10ffd0d565f9c3bc7f2eddc27dfe1731e71c7b5f", size = 8192560, upload-time = "2025-12-10T22:56:38.008Z" }, +] + +[[package]] +name = "matplotlib-inline" +version = "0.2.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "traitlets" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/c7/74/97e72a36efd4ae2bccb3463284300f8953f199b5ffbc04cbbb0ec78f74b1/matplotlib_inline-0.2.1.tar.gz", hash = "sha256:e1ee949c340d771fc39e241ea75683deb94762c8fa5f2927ec57c83c4dffa9fe", size = 8110, upload-time = "2025-10-23T09:00:22.126Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/af/33/ee4519fa02ed11a94aef9559552f3b17bb863f2ecfe1a35dc7f548cde231/matplotlib_inline-0.2.1-py3-none-any.whl", hash = "sha256:d56ce5156ba6085e00a9d54fead6ed29a9c47e215cd1bba2e976ef39f5710a76", size = 9516, upload-time = "2025-10-23T09:00:20.675Z" }, +] + +[[package]] +name = "mcp" +version = "1.27.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "anyio" }, + { name = "httpx" }, + { name = "httpx-sse" }, + { name = "jsonschema" }, + { name = "pydantic" }, + { name = "pydantic-settings" }, + { name = "pyjwt", extra = ["crypto"] }, + { name = "python-multipart" }, + { name = "pywin32", marker = "sys_platform == 'win32'" }, + { name = "sse-starlette" }, + { name = "starlette" }, + { name = "typing-extensions" }, + { name = "typing-inspection" }, + { name = "uvicorn", marker = "sys_platform != 'emscripten'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/8b/eb/c0cfc62075dc6e1ec1c64d352ae09ac051d9334311ed226f1f425312848a/mcp-1.27.0.tar.gz", hash = "sha256:d3dc35a7eec0d458c1da4976a48f982097ddaab87e278c5511d5a4a56e852b83", size = 607509, upload-time = "2026-04-02T14:48:08.88Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/9c/46/f6b4ad632c67ef35209a66127e4bddc95759649dd595f71f13fba11bdf9a/mcp-1.27.0-py3-none-any.whl", hash = "sha256:5ce1fa81614958e267b21fb2aa34e0aea8e2c6ede60d52aba45fd47246b4d741", size = 215967, upload-time = "2026-04-02T14:48:07.24Z" }, +] + +[package.optional-dependencies] +cli = [ + { name = "python-dotenv" }, + { name = "typer" }, +] + +[[package]] +name = "mdurl" +version = "0.1.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/d6/54/cfe61301667036ec958cb99bd3efefba235e65cdeb9c84d24a8293ba1d90/mdurl-0.1.2.tar.gz", hash = "sha256:bb413d29f5eea38f31dd4754dd7377d4465116fb207585f97bf925588687c1ba", size = 8729, upload-time = "2022-08-14T12:40:10.846Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/b3/38/89ba8ad64ae25be8de66a6d463314cf1eb366222074cfda9ee839c56a4b4/mdurl-0.1.2-py3-none-any.whl", hash = "sha256:84008a41e51615a49fc9966191ff91509e3c40b939176e643fd50a5c2196b8f8", size = 9979, upload-time = "2022-08-14T12:40:09.779Z" }, +] + +[[package]] +name = "mistune" +version = "3.2.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/9d/55/d01f0c4b45ade6536c51170b9043db8b2ec6ddf4a35c7ea3f5f559ac935b/mistune-3.2.0.tar.gz", hash = "sha256:708487c8a8cdd99c9d90eb3ed4c3ed961246ff78ac82f03418f5183ab70e398a", size = 95467, upload-time = "2025-12-23T11:36:34.994Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/9b/f7/4a5e785ec9fbd65146a27b6b70b6cdc161a66f2024e4b04ac06a67f5578b/mistune-3.2.0-py3-none-any.whl", hash = "sha256:febdc629a3c78616b94393c6580551e0e34cc289987ec6c35ed3f4be42d0eee1", size = 53598, upload-time = "2025-12-23T11:36:33.211Z" }, +] + +[[package]] +name = "nbclient" +version = "0.10.4" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "jupyter-client" }, + { name = "jupyter-core" }, + { name = "nbformat" }, + { name = "traitlets" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/56/91/1c1d5a4b9a9ebba2b4e32b8c852c2975c872aec1fe42ab5e516b2cecd193/nbclient-0.10.4.tar.gz", hash = "sha256:1e54091b16e6da39e297b0ece3e10f6f29f4ac4e8ee515d29f8a7099bd6553c9", size = 62554, upload-time = "2025-12-23T07:45:46.369Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/83/a0/5b0c2f11142ed1dddec842457d3f65eaf71a0080894eb6f018755b319c3a/nbclient-0.10.4-py3-none-any.whl", hash = "sha256:9162df5a7373d70d606527300a95a975a47c137776cd942e52d9c7e29ff83440", size = 25465, upload-time = "2025-12-23T07:45:44.51Z" }, +] + +[[package]] +name = "nbconvert" +version = "7.17.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "beautifulsoup4" }, + { name = "bleach", extra = ["css"] }, + { name = "defusedxml" }, + { name = "jinja2" }, + { name = "jupyter-core" }, + { name = "jupyterlab-pygments" }, + { name = "markupsafe" }, + { name = "mistune" }, + { name = "nbclient" }, + { name = "nbformat" }, + { name = "packaging" }, + { name = "pandocfilters" }, + { name = "pygments" }, + { name = "traitlets" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/01/b1/708e53fe2e429c103c6e6e159106bcf0357ac41aa4c28772bd8402339051/nbconvert-7.17.1.tar.gz", hash = "sha256:34d0d0a7e73ce3cbab6c5aae8f4f468797280b01fd8bd2ca746da8569eddd7d2", size = 865311, upload-time = "2026-04-08T00:44:14.914Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/67/f8/bb0a9d5f46819c821dc1f004aa2cc29b1d91453297dbf5ff20470f00f193/nbconvert-7.17.1-py3-none-any.whl", hash = "sha256:aa85c087b435e7bf1ffd03319f658e285f2b89eccab33bc1ba7025495ab3e7c8", size = 261927, upload-time = "2026-04-08T00:44:12.845Z" }, +] + +[[package]] +name = "nbformat" +version = "5.10.4" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "fastjsonschema" }, + { name = "jsonschema" }, + { name = "jupyter-core" }, + { name = "traitlets" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/6d/fd/91545e604bc3dad7dca9ed03284086039b294c6b3d75c0d2fa45f9e9caf3/nbformat-5.10.4.tar.gz", hash = "sha256:322168b14f937a5d11362988ecac2a4952d3d8e3a2cbeb2319584631226d5b3a", size = 142749, upload-time = "2024-04-04T11:20:37.371Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/a9/82/0340caa499416c78e5d8f5f05947ae4bc3cba53c9f038ab6e9ed964e22f1/nbformat-5.10.4-py3-none-any.whl", hash = "sha256:3b48d6c8fbca4b299bf3982ea7db1af21580e4fec269ad087b9e81588891200b", size = 78454, upload-time = "2024-04-04T11:20:34.895Z" }, +] + +[[package]] +name = "nest-asyncio" +version = "1.6.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/83/f8/51569ac65d696c8ecbee95938f89d4abf00f47d58d48f6fbabfe8f0baefe/nest_asyncio-1.6.0.tar.gz", hash = "sha256:6f172d5449aca15afd6c646851f4e31e02c598d553a667e38cafa997cfec55fe", size = 7418, upload-time = "2024-01-21T14:25:19.227Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/a0/c4/c2971a3ba4c6103a3d10c4b0f24f461ddc027f0f09763220cf35ca1401b3/nest_asyncio-1.6.0-py3-none-any.whl", hash = "sha256:87af6efd6b5e897c81050477ef65c62e2b2f35d51703cae01aff2905b1852e1c", size = 5195, upload-time = "2024-01-21T14:25:17.223Z" }, +] + +[[package]] +name = "notebook" +version = "7.5.5" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "jupyter-server" }, + { name = "jupyterlab" }, + { name = "jupyterlab-server" }, + { name = "notebook-shim" }, + { name = "tornado" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/1f/6d/41052c48d6f6349ca0a7c4d1f6a78464de135e6d18f5829ba2510e62184c/notebook-7.5.5.tar.gz", hash = "sha256:dc0bfab0f2372c8278c457423d3256c34154ac2cc76bf20e9925260c461013c3", size = 14169167, upload-time = "2026-03-11T16:32:51.922Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/f8/aa/cbd1deb9f07446241e88f8d5fecccd95b249bca0b4e5482214a4d1714c49/notebook-7.5.5-py3-none-any.whl", hash = "sha256:a7c14dbeefa6592e87f72290ca982e0c10f5bbf3786be2a600fda9da2764a2b8", size = 14578929, upload-time = "2026-03-11T16:32:48.021Z" }, +] + +[[package]] +name = "notebook-shim" +version = "0.2.4" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "jupyter-server" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/54/d2/92fa3243712b9a3e8bafaf60aac366da1cada3639ca767ff4b5b3654ec28/notebook_shim-0.2.4.tar.gz", hash = "sha256:b4b2cfa1b65d98307ca24361f5b30fe785b53c3fd07b7a47e89acb5e6ac638cb", size = 13167, upload-time = "2024-02-14T23:35:18.353Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/f9/33/bd5b9137445ea4b680023eb0469b2bb969d61303dedb2aac6560ff3d14a1/notebook_shim-0.2.4-py3-none-any.whl", hash = "sha256:411a5be4e9dc882a074ccbcae671eda64cceb068767e9a3419096986560e1cef", size = 13307, upload-time = "2024-02-14T23:35:16.286Z" }, +] + +[[package]] +name = "numpy" +version = "2.4.4" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/d7/9f/b8cef5bffa569759033adda9481211426f12f53299629b410340795c2514/numpy-2.4.4.tar.gz", hash = "sha256:2d390634c5182175533585cc89f3608a4682ccb173cc9bb940b2881c8d6f8fa0", size = 20731587, upload-time = "2026-03-29T13:22:01.298Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/14/1d/d0a583ce4fefcc3308806a749a536c201ed6b5ad6e1322e227ee4848979d/numpy-2.4.4-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:08f2e31ed5e6f04b118e49821397f12767934cfdd12a1ce86a058f91e004ee50", size = 16684933, upload-time = "2026-03-29T13:19:22.47Z" }, + { url = "https://files.pythonhosted.org/packages/c1/62/2b7a48fbb745d344742c0277f01286dead15f3f68e4f359fbfcf7b48f70f/numpy-2.4.4-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:e823b8b6edc81e747526f70f71a9c0a07ac4e7ad13020aa736bb7c9d67196115", size = 14694532, upload-time = "2026-03-29T13:19:25.581Z" }, + { url = "https://files.pythonhosted.org/packages/e5/87/499737bfba066b4a3bebff24a8f1c5b2dee410b209bc6668c9be692580f0/numpy-2.4.4-cp313-cp313-macosx_14_0_arm64.whl", hash = "sha256:4a19d9dba1a76618dd86b164d608566f393f8ec6ac7c44f0cc879011c45e65af", size = 5199661, upload-time = "2026-03-29T13:19:28.31Z" }, + { url = "https://files.pythonhosted.org/packages/cd/da/464d551604320d1491bc345efed99b4b7034143a85787aab78d5691d5a0e/numpy-2.4.4-cp313-cp313-macosx_14_0_x86_64.whl", hash = "sha256:d2a8490669bfe99a233298348acc2d824d496dee0e66e31b66a6022c2ad74a5c", size = 6547539, upload-time = "2026-03-29T13:19:30.97Z" }, + { url = "https://files.pythonhosted.org/packages/7d/90/8d23e3b0dafd024bf31bdec225b3bb5c2dbfa6912f8a53b8659f21216cbf/numpy-2.4.4-cp313-cp313-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:45dbed2ab436a9e826e302fcdcbe9133f9b0006e5af7168afb8963a6520da103", size = 15668806, upload-time = "2026-03-29T13:19:33.887Z" }, + { url = "https://files.pythonhosted.org/packages/d1/73/a9d864e42a01896bb5974475438f16086be9ba1f0d19d0bb7a07427c4a8b/numpy-2.4.4-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c901b15172510173f5cb310eae652908340f8dede90fff9e3bf6c0d8dfd92f83", size = 16632682, upload-time = "2026-03-29T13:19:37.336Z" }, + { url = "https://files.pythonhosted.org/packages/34/fb/14570d65c3bde4e202a031210475ae9cde9b7686a2e7dc97ee67d2833b35/numpy-2.4.4-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:99d838547ace2c4aace6c4f76e879ddfe02bb58a80c1549928477862b7a6d6ed", size = 17019810, upload-time = "2026-03-29T13:19:40.963Z" }, + { url = "https://files.pythonhosted.org/packages/8a/77/2ba9d87081fd41f6d640c83f26fb7351e536b7ce6dd9061b6af5904e8e46/numpy-2.4.4-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:0aec54fd785890ecca25a6003fd9a5aed47ad607bbac5cd64f836ad8666f4959", size = 18357394, upload-time = "2026-03-29T13:19:44.859Z" }, + { url = "https://files.pythonhosted.org/packages/a2/23/52666c9a41708b0853fa3b1a12c90da38c507a3074883823126d4e9d5b30/numpy-2.4.4-cp313-cp313-win32.whl", hash = "sha256:07077278157d02f65c43b1b26a3886bce886f95d20aabd11f87932750dfb14ed", size = 5959556, upload-time = "2026-03-29T13:19:47.661Z" }, + { url = "https://files.pythonhosted.org/packages/57/fb/48649b4971cde70d817cf97a2a2fdc0b4d8308569f1dd2f2611959d2e0cf/numpy-2.4.4-cp313-cp313-win_amd64.whl", hash = "sha256:5c70f1cc1c4efbe316a572e2d8b9b9cc44e89b95f79ca3331553fbb63716e2bf", size = 12317311, upload-time = "2026-03-29T13:19:50.67Z" }, + { url = "https://files.pythonhosted.org/packages/ba/d8/11490cddd564eb4de97b4579ef6bfe6a736cc07e94c1598590ae25415e01/numpy-2.4.4-cp313-cp313-win_arm64.whl", hash = "sha256:ef4059d6e5152fa1a39f888e344c73fdc926e1b2dd58c771d67b0acfbf2aa67d", size = 10222060, upload-time = "2026-03-29T13:19:54.229Z" }, + { url = "https://files.pythonhosted.org/packages/99/5d/dab4339177a905aad3e2221c915b35202f1ec30d750dd2e5e9d9a72b804b/numpy-2.4.4-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:4bbc7f303d125971f60ec0aaad5e12c62d0d2c925f0ab1273debd0e4ba37aba5", size = 14822302, upload-time = "2026-03-29T13:19:57.585Z" }, + { url = "https://files.pythonhosted.org/packages/eb/e4/0564a65e7d3d97562ed6f9b0fd0fb0a6f559ee444092f105938b50043876/numpy-2.4.4-cp313-cp313t-macosx_14_0_arm64.whl", hash = "sha256:4d6d57903571f86180eb98f8f0c839fa9ebbfb031356d87f1361be91e433f5b7", size = 5327407, upload-time = "2026-03-29T13:20:00.601Z" }, + { url = "https://files.pythonhosted.org/packages/29/8d/35a3a6ce5ad371afa58b4700f1c820f8f279948cca32524e0a695b0ded83/numpy-2.4.4-cp313-cp313t-macosx_14_0_x86_64.whl", hash = "sha256:4636de7fd195197b7535f231b5de9e4b36d2c440b6e566d2e4e4746e6af0ca93", size = 6647631, upload-time = "2026-03-29T13:20:02.855Z" }, + { url = "https://files.pythonhosted.org/packages/f4/da/477731acbd5a58a946c736edfdabb2ac5b34c3d08d1ba1a7b437fa0884df/numpy-2.4.4-cp313-cp313t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ad2e2ef14e0b04e544ea2fa0a36463f847f113d314aa02e5b402fdf910ef309e", size = 15727691, upload-time = "2026-03-29T13:20:06.004Z" }, + { url = "https://files.pythonhosted.org/packages/e6/db/338535d9b152beabeb511579598418ba0212ce77cf9718edd70262cc4370/numpy-2.4.4-cp313-cp313t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:5a285b3b96f951841799528cd1f4f01cd70e7e0204b4abebac9463eecfcf2a40", size = 16681241, upload-time = "2026-03-29T13:20:09.417Z" }, + { url = "https://files.pythonhosted.org/packages/e2/a9/ad248e8f58beb7a0219b413c9c7d8151c5d285f7f946c3e26695bdbbe2df/numpy-2.4.4-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:f8474c4241bc18b750be2abea9d7a9ec84f46ef861dbacf86a4f6e043401f79e", size = 17085767, upload-time = "2026-03-29T13:20:13.126Z" }, + { url = "https://files.pythonhosted.org/packages/b5/1a/3b88ccd3694681356f70da841630e4725a7264d6a885c8d442a697e1146b/numpy-2.4.4-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:4e874c976154687c1f71715b034739b45c7711bec81db01914770373d125e392", size = 18403169, upload-time = "2026-03-29T13:20:17.096Z" }, + { url = "https://files.pythonhosted.org/packages/c2/c9/fcfd5d0639222c6eac7f304829b04892ef51c96a75d479214d77e3ce6e33/numpy-2.4.4-cp313-cp313t-win32.whl", hash = "sha256:9c585a1790d5436a5374bac930dad6ed244c046ed91b2b2a3634eb2971d21008", size = 6083477, upload-time = "2026-03-29T13:20:20.195Z" }, + { url = "https://files.pythonhosted.org/packages/d5/e3/3938a61d1c538aaec8ed6fd6323f57b0c2d2d2219512434c5c878db76553/numpy-2.4.4-cp313-cp313t-win_amd64.whl", hash = "sha256:93e15038125dc1e5345d9b5b68aa7f996ec33b98118d18c6ca0d0b7d6198b7e8", size = 12457487, upload-time = "2026-03-29T13:20:22.946Z" }, + { url = "https://files.pythonhosted.org/packages/97/6a/7e345032cc60501721ef94e0e30b60f6b0bd601f9174ebd36389a2b86d40/numpy-2.4.4-cp313-cp313t-win_arm64.whl", hash = "sha256:0dfd3f9d3adbe2920b68b5cd3d51444e13a10792ec7154cd0a2f6e74d4ab3233", size = 10292002, upload-time = "2026-03-29T13:20:25.909Z" }, + { url = "https://files.pythonhosted.org/packages/6e/06/c54062f85f673dd5c04cbe2f14c3acb8c8b95e3384869bb8cc9bff8cb9df/numpy-2.4.4-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:f169b9a863d34f5d11b8698ead99febeaa17a13ca044961aa8e2662a6c7766a0", size = 16684353, upload-time = "2026-03-29T13:20:29.504Z" }, + { url = "https://files.pythonhosted.org/packages/4c/39/8a320264a84404c74cc7e79715de85d6130fa07a0898f67fb5cd5bd79908/numpy-2.4.4-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:2483e4584a1cb3092da4470b38866634bafb223cbcd551ee047633fd2584599a", size = 14704914, upload-time = "2026-03-29T13:20:33.547Z" }, + { url = "https://files.pythonhosted.org/packages/91/fb/287076b2614e1d1044235f50f03748f31fa287e3dbe6abeb35cdfa351eca/numpy-2.4.4-cp314-cp314-macosx_14_0_arm64.whl", hash = "sha256:2d19e6e2095506d1736b7d80595e0f252d76b89f5e715c35e06e937679ea7d7a", size = 5210005, upload-time = "2026-03-29T13:20:36.45Z" }, + { url = "https://files.pythonhosted.org/packages/63/eb/fcc338595309910de6ecabfcef2419a9ce24399680bfb149421fa2df1280/numpy-2.4.4-cp314-cp314-macosx_14_0_x86_64.whl", hash = "sha256:6a246d5914aa1c820c9443ddcee9c02bec3e203b0c080349533fae17727dfd1b", size = 6544974, upload-time = "2026-03-29T13:20:39.014Z" }, + { url = "https://files.pythonhosted.org/packages/44/5d/e7e9044032a716cdfaa3fba27a8e874bf1c5f1912a1ddd4ed071bf8a14a6/numpy-2.4.4-cp314-cp314-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:989824e9faf85f96ec9c7761cd8d29c531ad857bfa1daa930cba85baaecf1a9a", size = 15684591, upload-time = "2026-03-29T13:20:42.146Z" }, + { url = "https://files.pythonhosted.org/packages/98/7c/21252050676612625449b4807d6b695b9ce8a7c9e1c197ee6216c8a65c7c/numpy-2.4.4-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:27a8d92cd10f1382a67d7cf4db7ce18341b66438bdd9f691d7b0e48d104c2a9d", size = 16637700, upload-time = "2026-03-29T13:20:46.204Z" }, + { url = "https://files.pythonhosted.org/packages/b1/29/56d2bbef9465db24ef25393383d761a1af4f446a1df9b8cded4fe3a5a5d7/numpy-2.4.4-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:e44319a2953c738205bf3354537979eaa3998ed673395b964c1176083dd46252", size = 17035781, upload-time = "2026-03-29T13:20:50.242Z" }, + { url = "https://files.pythonhosted.org/packages/e3/2b/a35a6d7589d21f44cea7d0a98de5ddcbb3d421b2622a5c96b1edf18707c3/numpy-2.4.4-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:e892aff75639bbef0d2a2cfd55535510df26ff92f63c92cd84ef8d4ba5a5557f", size = 18362959, upload-time = "2026-03-29T13:20:54.019Z" }, + { url = "https://files.pythonhosted.org/packages/64/c9/d52ec581f2390e0f5f85cbfd80fb83d965fc15e9f0e1aec2195faa142cde/numpy-2.4.4-cp314-cp314-win32.whl", hash = "sha256:1378871da56ca8943c2ba674530924bb8ca40cd228358a3b5f302ad60cf875fc", size = 6008768, upload-time = "2026-03-29T13:20:56.912Z" }, + { url = "https://files.pythonhosted.org/packages/fa/22/4cc31a62a6c7b74a8730e31a4274c5dc80e005751e277a2ce38e675e4923/numpy-2.4.4-cp314-cp314-win_amd64.whl", hash = "sha256:715d1c092715954784bc79e1174fc2a90093dc4dc84ea15eb14dad8abdcdeb74", size = 12449181, upload-time = "2026-03-29T13:20:59.548Z" }, + { url = "https://files.pythonhosted.org/packages/70/2e/14cda6f4d8e396c612d1bf97f22958e92148801d7e4f110cabebdc0eef4b/numpy-2.4.4-cp314-cp314-win_arm64.whl", hash = "sha256:2c194dd721e54ecad9ad387c1d35e63dce5c4450c6dc7dd5611283dda239aabb", size = 10496035, upload-time = "2026-03-29T13:21:02.524Z" }, + { url = "https://files.pythonhosted.org/packages/b1/e8/8fed8c8d848d7ecea092dc3469643f9d10bc3a134a815a3b033da1d2039b/numpy-2.4.4-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:2aa0613a5177c264ff5921051a5719d20095ea586ca88cc802c5c218d1c67d3e", size = 14824958, upload-time = "2026-03-29T13:21:05.671Z" }, + { url = "https://files.pythonhosted.org/packages/05/1a/d8007a5138c179c2bf33ef44503e83d70434d2642877ee8fbb230e7c0548/numpy-2.4.4-cp314-cp314t-macosx_14_0_arm64.whl", hash = "sha256:42c16925aa5a02362f986765f9ebabf20de75cdefdca827d14315c568dcab113", size = 5330020, upload-time = "2026-03-29T13:21:08.635Z" }, + { url = "https://files.pythonhosted.org/packages/99/64/ffb99ac6ae93faf117bcbd5c7ba48a7f45364a33e8e458545d3633615dda/numpy-2.4.4-cp314-cp314t-macosx_14_0_x86_64.whl", hash = "sha256:874f200b2a981c647340f841730fc3a2b54c9d940566a3c4149099591e2c4c3d", size = 6650758, upload-time = "2026-03-29T13:21:10.949Z" }, + { url = "https://files.pythonhosted.org/packages/6e/6e/795cc078b78a384052e73b2f6281ff7a700e9bf53bcce2ee579d4f6dd879/numpy-2.4.4-cp314-cp314t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:c9b39d38a9bd2ae1becd7eac1303d031c5c110ad31f2b319c6e7d98b135c934d", size = 15729948, upload-time = "2026-03-29T13:21:14.047Z" }, + { url = "https://files.pythonhosted.org/packages/5f/86/2acbda8cc2af5f3d7bfc791192863b9e3e19674da7b5e533fded124d1299/numpy-2.4.4-cp314-cp314t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:b268594bccac7d7cf5844c7732e3f20c50921d94e36d7ec9b79e9857694b1b2f", size = 16679325, upload-time = "2026-03-29T13:21:17.561Z" }, + { url = "https://files.pythonhosted.org/packages/bc/59/cafd83018f4aa55e0ac6fa92aa066c0a1877b77a615ceff1711c260ffae8/numpy-2.4.4-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:ac6b31e35612a26483e20750126d30d0941f949426974cace8e6b5c58a3657b0", size = 17084883, upload-time = "2026-03-29T13:21:21.106Z" }, + { url = "https://files.pythonhosted.org/packages/f0/85/a42548db84e65ece46ab2caea3d3f78b416a47af387fcbb47ec28e660dc2/numpy-2.4.4-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:8e3ed142f2728df44263aaf5fb1f5b0b99f4070c553a0d7f033be65338329150", size = 18403474, upload-time = "2026-03-29T13:21:24.828Z" }, + { url = "https://files.pythonhosted.org/packages/ed/ad/483d9e262f4b831000062e5d8a45e342166ec8aaa1195264982bca267e62/numpy-2.4.4-cp314-cp314t-win32.whl", hash = "sha256:dddbbd259598d7240b18c9d87c56a9d2fb3b02fe266f49a7c101532e78c1d871", size = 6155500, upload-time = "2026-03-29T13:21:28.205Z" }, + { url = "https://files.pythonhosted.org/packages/c7/03/2fc4e14c7bd4ff2964b74ba90ecb8552540b6315f201df70f137faa5c589/numpy-2.4.4-cp314-cp314t-win_amd64.whl", hash = "sha256:a7164afb23be6e37ad90b2f10426149fd75aee07ca55653d2aa41e66c4ef697e", size = 12637755, upload-time = "2026-03-29T13:21:31.107Z" }, + { url = "https://files.pythonhosted.org/packages/58/78/548fb8e07b1a341746bfbecb32f2c268470f45fa028aacdbd10d9bc73aab/numpy-2.4.4-cp314-cp314t-win_arm64.whl", hash = "sha256:ba203255017337d39f89bdd58417f03c4426f12beed0440cfd933cb15f8669c7", size = 10566643, upload-time = "2026-03-29T13:21:34.339Z" }, +] + +[[package]] +name = "packaging" +version = "26.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/df/de/0d2b39fb4af88a0258f3bac87dfcbb48e73fbdea4a2ed0e2213f9a4c2f9a/packaging-26.1.tar.gz", hash = "sha256:f042152b681c4bfac5cae2742a55e103d27ab2ec0f3d88037136b6bfe7c9c5de", size = 215519, upload-time = "2026-04-14T21:12:49.362Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/7a/c2/920ef838e2f0028c8262f16101ec09ebd5969864e5a64c4c05fad0617c56/packaging-26.1-py3-none-any.whl", hash = "sha256:5d9c0669c6285e491e0ced2eee587eaf67b670d94a19e94e3984a481aba6802f", size = 95831, upload-time = "2026-04-14T21:12:47.56Z" }, +] + +[[package]] +name = "pandas" +version = "3.0.2" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "numpy" }, + { name = "python-dateutil" }, + { name = "tzdata", marker = "sys_platform == 'emscripten' or sys_platform == 'win32'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/da/99/b342345300f13440fe9fe385c3c481e2d9a595ee3bab4d3219247ac94e9a/pandas-3.0.2.tar.gz", hash = "sha256:f4753e73e34c8d83221ba58f232433fca2748be8b18dbca02d242ed153945043", size = 4645855, upload-time = "2026-03-31T06:48:30.816Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/bf/ca/3e639a1ea6fcd0617ca4e8ca45f62a74de33a56ae6cd552735470b22c8d3/pandas-3.0.2-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:b5918ba197c951dec132b0c5929a00c0bf05d5942f590d3c10a807f6e15a57d3", size = 10321105, upload-time = "2026-03-31T06:46:57.327Z" }, + { url = "https://files.pythonhosted.org/packages/0b/77/dbc82ff2fb0e63c6564356682bf201edff0ba16c98630d21a1fb312a8182/pandas-3.0.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:d606a041c89c0a474a4702d532ab7e73a14fe35c8d427b972a625c8e46373668", size = 9864088, upload-time = "2026-03-31T06:46:59.935Z" }, + { url = "https://files.pythonhosted.org/packages/5c/2b/341f1b04bbca2e17e13cd3f08c215b70ef2c60c5356ef1e8c6857449edc7/pandas-3.0.2-cp313-cp313-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:710246ba0616e86891b58ab95f2495143bb2bc83ab6b06747c74216f583a6ac9", size = 10369066, upload-time = "2026-03-31T06:47:02.792Z" }, + { url = "https://files.pythonhosted.org/packages/12/c5/cbb1ffefb20a93d3f0e1fdcda699fb84976210d411b008f97f48bf6ce27e/pandas-3.0.2-cp313-cp313-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:5d3cfe227c725b1f3dff4278b43d8c784656a42a9325b63af6b1492a8232209e", size = 10876780, upload-time = "2026-03-31T06:47:06.205Z" }, + { url = "https://files.pythonhosted.org/packages/98/fe/2249ae5e0a69bd0ddf17353d0a5d26611d70970111f5b3600cdc8be883e7/pandas-3.0.2-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:c3b723df9087a9a9a840e263ebd9f88b64a12075d1bf2ea401a5a42f254f084d", size = 11375181, upload-time = "2026-03-31T06:47:09.383Z" }, + { url = "https://files.pythonhosted.org/packages/de/64/77a38b09e70b6464883b8d7584ab543e748e42c1b5d337a2ee088e0df741/pandas-3.0.2-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:a3096110bf9eac0070b7208465f2740e2d8a670d5cb6530b5bb884eca495fd39", size = 11928899, upload-time = "2026-03-31T06:47:12.686Z" }, + { url = "https://files.pythonhosted.org/packages/5e/52/42855bf626868413f761addd574acc6195880ae247a5346477a4361c3acb/pandas-3.0.2-cp313-cp313-win_amd64.whl", hash = "sha256:07a10f5c36512eead51bc578eb3354ad17578b22c013d89a796ab5eee90cd991", size = 9746574, upload-time = "2026-03-31T06:47:15.64Z" }, + { url = "https://files.pythonhosted.org/packages/88/39/21304ae06a25e8bf9fc820d69b29b2c495b2ae580d1e143146c309941760/pandas-3.0.2-cp313-cp313-win_arm64.whl", hash = "sha256:5fdbfa05931071aba28b408e59226186b01eb5e92bea2ab78b65863ca3228d84", size = 9047156, upload-time = "2026-03-31T06:47:18.595Z" }, + { url = "https://files.pythonhosted.org/packages/72/20/7defa8b27d4f330a903bb68eea33be07d839c5ea6bdda54174efcec0e1d2/pandas-3.0.2-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:dbc20dea3b9e27d0e66d74c42b2d0c1bed9c2ffe92adea33633e3bedeb5ac235", size = 10756238, upload-time = "2026-03-31T06:47:22.012Z" }, + { url = "https://files.pythonhosted.org/packages/e9/95/49433c14862c636afc0e9b2db83ff16b3ad92959364e52b2955e44c8e94c/pandas-3.0.2-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:b75c347eff42497452116ce05ef461822d97ce5b9ff8df6edacb8076092c855d", size = 10408520, upload-time = "2026-03-31T06:47:25.197Z" }, + { url = "https://files.pythonhosted.org/packages/3b/f8/462ad2b5881d6b8ec8e5f7ed2ea1893faa02290d13870a1600fe72ad8efc/pandas-3.0.2-cp313-cp313t-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:d1478075142e83a5571782ad007fb201ed074bdeac7ebcc8890c71442e96adf7", size = 10324154, upload-time = "2026-03-31T06:47:28.097Z" }, + { url = "https://files.pythonhosted.org/packages/0a/65/d1e69b649cbcddda23ad6e4c40ef935340f6f652a006e5cbc3555ac8adb3/pandas-3.0.2-cp313-cp313t-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:5880314e69e763d4c8b27937090de570f1fb8d027059a7ada3f7f8e98bdcb677", size = 10714449, upload-time = "2026-03-31T06:47:30.85Z" }, + { url = "https://files.pythonhosted.org/packages/47/a4/85b59bc65b8190ea3689882db6cdf32a5003c0ccd5a586c30fdcc3ffc4fc/pandas-3.0.2-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:b5329e26898896f06035241a626d7c335daa479b9bbc82be7c2742d048e41172", size = 11338475, upload-time = "2026-03-31T06:47:34.026Z" }, + { url = "https://files.pythonhosted.org/packages/1e/c4/bc6966c6e38e5d9478b935272d124d80a589511ed1612a5d21d36f664c68/pandas-3.0.2-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:81526c4afd31971f8b62671442a4b2b51e0aa9acc3819c9f0f12a28b6fcf85f1", size = 11786568, upload-time = "2026-03-31T06:47:36.941Z" }, + { url = "https://files.pythonhosted.org/packages/e8/74/09298ca9740beed1d3504e073d67e128aa07e5ca5ca2824b0c674c0b8676/pandas-3.0.2-cp313-cp313t-win_amd64.whl", hash = "sha256:7cadd7e9a44ec13b621aec60f9150e744cfc7a3dd32924a7e2f45edff31823b0", size = 10488652, upload-time = "2026-03-31T06:47:40.612Z" }, + { url = "https://files.pythonhosted.org/packages/bb/40/c6ea527147c73b24fc15c891c3fcffe9c019793119c5742b8784a062c7db/pandas-3.0.2-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:db0dbfd2a6cdf3770aa60464d50333d8f3d9165b2f2671bcc299b72de5a6677b", size = 10326084, upload-time = "2026-03-31T06:47:43.834Z" }, + { url = "https://files.pythonhosted.org/packages/95/25/bdb9326c3b5455f8d4d3549fce7abcf967259de146fe2cf7a82368141948/pandas-3.0.2-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:0555c5882688a39317179ab4a0ed41d3ebc8812ab14c69364bbee8fb7a3f6288", size = 9914146, upload-time = "2026-03-31T06:47:46.67Z" }, + { url = "https://files.pythonhosted.org/packages/8d/77/3a227ff3337aa376c60d288e1d61c5d097131d0ac71f954d90a8f369e422/pandas-3.0.2-cp314-cp314-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:01f31a546acd5574ef77fe199bc90b55527c225c20ccda6601cf6b0fd5ed597c", size = 10444081, upload-time = "2026-03-31T06:47:49.681Z" }, + { url = "https://files.pythonhosted.org/packages/15/88/3cdd54fa279341afa10acf8d2b503556b1375245dccc9315659f795dd2e9/pandas-3.0.2-cp314-cp314-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:deeca1b5a931fdf0c2212c8a659ade6d3b1edc21f0914ce71ef24456ca7a6535", size = 10897535, upload-time = "2026-03-31T06:47:53.033Z" }, + { url = "https://files.pythonhosted.org/packages/06/9d/98cc7a7624f7932e40f434299260e2917b090a579d75937cb8a57b9d2de3/pandas-3.0.2-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:0f48afd9bb13300ffb5a3316973324c787054ba6665cda0da3fbd67f451995db", size = 11446992, upload-time = "2026-03-31T06:47:56.193Z" }, + { url = "https://files.pythonhosted.org/packages/9a/cd/19ff605cc3760e80602e6826ddef2824d8e7050ed80f2e11c4b079741dc3/pandas-3.0.2-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:6c4d8458b97a35717b62469a4ea0e85abd5ed8687277f5ccfc67f8a5126f8c53", size = 11968257, upload-time = "2026-03-31T06:47:59.137Z" }, + { url = "https://files.pythonhosted.org/packages/db/60/aba6a38de456e7341285102bede27514795c1eaa353bc0e7638b6b785356/pandas-3.0.2-cp314-cp314-win_amd64.whl", hash = "sha256:b35d14bb5d8285d9494fe93815a9e9307c0876e10f1e8e89ac5b88f728ec8dcf", size = 9865893, upload-time = "2026-03-31T06:48:02.038Z" }, + { url = "https://files.pythonhosted.org/packages/08/71/e5ec979dd2e8a093dacb8864598c0ff59a0cee0bbcdc0bfec16a51684d4f/pandas-3.0.2-cp314-cp314-win_arm64.whl", hash = "sha256:63d141b56ef686f7f0d714cfb8de4e320475b86bf4b620aa0b7da89af8cbdbbb", size = 9188644, upload-time = "2026-03-31T06:48:05.045Z" }, + { url = "https://files.pythonhosted.org/packages/f1/6c/7b45d85db19cae1eb524f2418ceaa9d85965dcf7b764ed151386b7c540f0/pandas-3.0.2-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:140f0cffb1fa2524e874dde5b477d9defe10780d8e9e220d259b2c0874c89d9d", size = 10776246, upload-time = "2026-03-31T06:48:07.789Z" }, + { url = "https://files.pythonhosted.org/packages/a8/3e/7b00648b086c106e81766f25322b48aa8dfa95b55e621dbdf2fdd413a117/pandas-3.0.2-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:ae37e833ff4fed0ba352f6bdd8b73ba3ab3256a85e54edfd1ab51ae40cca0af8", size = 10424801, upload-time = "2026-03-31T06:48:10.897Z" }, + { url = "https://files.pythonhosted.org/packages/da/6e/558dd09a71b53b4008e7fc8a98ec6d447e9bfb63cdaeea10e5eb9b2dabe8/pandas-3.0.2-cp314-cp314t-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:4d888a5c678a419a5bb41a2a93818e8ed9fd3172246555c0b37b7cc27027effd", size = 10345643, upload-time = "2026-03-31T06:48:13.7Z" }, + { url = "https://files.pythonhosted.org/packages/be/e3/921c93b4d9a280409451dc8d07b062b503bbec0531d2627e73a756e99a82/pandas-3.0.2-cp314-cp314t-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:b444dc64c079e84df91baa8bf613d58405645461cabca929d9178f2cd392398d", size = 10743641, upload-time = "2026-03-31T06:48:16.659Z" }, + { url = "https://files.pythonhosted.org/packages/56/ca/fd17286f24fa3b4d067965d8d5d7e14fe557dd4f979a0b068ac0deaf8228/pandas-3.0.2-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:4544c7a54920de8eeacaa1466a6b7268ecfbc9bc64ab4dbb89c6bbe94d5e0660", size = 11361993, upload-time = "2026-03-31T06:48:19.475Z" }, + { url = "https://files.pythonhosted.org/packages/e4/a5/2f6ed612056819de445a433ca1f2821ac3dab7f150d569a59e9cc105de1d/pandas-3.0.2-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:734be7551687c00fbd760dc0522ed974f82ad230d4a10f54bf51b80d44a08702", size = 11815274, upload-time = "2026-03-31T06:48:22.695Z" }, + { url = "https://files.pythonhosted.org/packages/00/2f/b622683e99ec3ce00b0854bac9e80868592c5b051733f2cf3a868e5fea26/pandas-3.0.2-cp314-cp314t-win_amd64.whl", hash = "sha256:57a07209bebcbcf768d2d13c9b78b852f9a15978dac41b9e6421a81ad4cdd276", size = 10888530, upload-time = "2026-03-31T06:48:25.806Z" }, + { url = "https://files.pythonhosted.org/packages/cb/2b/f8434233fab2bd66a02ec014febe4e5adced20e2693e0e90a07d118ed30e/pandas-3.0.2-cp314-cp314t-win_arm64.whl", hash = "sha256:5371b72c2d4d415d08765f32d689217a43227484e81b2305b52076e328f6f482", size = 9455341, upload-time = "2026-03-31T06:48:28.418Z" }, +] + +[[package]] +name = "pandocfilters" +version = "1.5.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/70/6f/3dd4940bbe001c06a65f88e36bad298bc7a0de5036115639926b0c5c0458/pandocfilters-1.5.1.tar.gz", hash = "sha256:002b4a555ee4ebc03f8b66307e287fa492e4a77b4ea14d3f934328297bb4939e", size = 8454, upload-time = "2024-01-18T20:08:13.726Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/ef/af/4fbc8cab944db5d21b7e2a5b8e9211a03a79852b1157e2c102fcc61ac440/pandocfilters-1.5.1-py2.py3-none-any.whl", hash = "sha256:93be382804a9cdb0a7267585f157e5d1731bbe5545a85b268d6f5fe6232de2bc", size = 8663, upload-time = "2024-01-18T20:08:11.28Z" }, +] + +[[package]] +name = "parso" +version = "0.8.6" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/81/76/a1e769043c0c0c9fe391b702539d594731a4362334cdf4dc25d0c09761e7/parso-0.8.6.tar.gz", hash = "sha256:2b9a0332696df97d454fa67b81618fd69c35a7b90327cbe6ba5c92d2c68a7bfd", size = 401621, upload-time = "2026-02-09T15:45:24.425Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/b6/61/fae042894f4296ec49e3f193aff5d7c18440da9e48102c3315e1bc4519a7/parso-0.8.6-py2.py3-none-any.whl", hash = "sha256:2c549f800b70a5c4952197248825584cb00f033b29c692671d3bf08bf380baff", size = 106894, upload-time = "2026-02-09T15:45:21.391Z" }, +] + +[[package]] +name = "pexpect" +version = "4.9.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "ptyprocess", marker = "sys_platform != 'emscripten' and sys_platform != 'win32'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/42/92/cc564bf6381ff43ce1f4d06852fc19a2f11d180f23dc32d9588bee2f149d/pexpect-4.9.0.tar.gz", hash = "sha256:ee7d41123f3c9911050ea2c2dac107568dc43b2d3b0c7557a33212c398ead30f", size = 166450, upload-time = "2023-11-25T09:07:26.339Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/9e/c3/059298687310d527a58bb01f3b1965787ee3b40dce76752eda8b44e9a2c5/pexpect-4.9.0-py2.py3-none-any.whl", hash = "sha256:7236d1e080e4936be2dc3e326cec0af72acf9212a7e1d060210e70a47e253523", size = 63772, upload-time = "2023-11-25T06:56:14.81Z" }, +] + +[[package]] +name = "pillow" +version = "12.2.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/8c/21/c2bcdd5906101a30244eaffc1b6e6ce71a31bd0742a01eb89e660ebfac2d/pillow-12.2.0.tar.gz", hash = "sha256:a830b1a40919539d07806aa58e1b114df53ddd43213d9c8b75847eee6c0182b5", size = 46987819, upload-time = "2026-04-01T14:46:17.687Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/4a/01/53d10cf0dbad820a8db274d259a37ba50b88b24768ddccec07355382d5ad/pillow-12.2.0-cp313-cp313-ios_13_0_arm64_iphoneos.whl", hash = "sha256:8297651f5b5679c19968abefd6bb84d95fe30ef712eb1b2d9b2d31ca61267f4c", size = 4100837, upload-time = "2026-04-01T14:43:41.506Z" }, + { url = "https://files.pythonhosted.org/packages/0f/98/f3a6657ecb698c937f6c76ee564882945f29b79bad496abcba0e84659ec5/pillow-12.2.0-cp313-cp313-ios_13_0_arm64_iphonesimulator.whl", hash = "sha256:50d8520da2a6ce0af445fa6d648c4273c3eeefbc32d7ce049f22e8b5c3daecc2", size = 4176528, upload-time = "2026-04-01T14:43:43.773Z" }, + { url = "https://files.pythonhosted.org/packages/69/bc/8986948f05e3ea490b8442ea1c1d4d990b24a7e43d8a51b2c7d8b1dced36/pillow-12.2.0-cp313-cp313-ios_13_0_x86_64_iphonesimulator.whl", hash = "sha256:766cef22385fa1091258ad7e6216792b156dc16d8d3fa607e7545b2b72061f1c", size = 3640401, upload-time = "2026-04-01T14:43:45.87Z" }, + { url = "https://files.pythonhosted.org/packages/34/46/6c717baadcd62bc8ed51d238d521ab651eaa74838291bda1f86fe1f864c9/pillow-12.2.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:5d2fd0fa6b5d9d1de415060363433f28da8b1526c1c129020435e186794b3795", size = 5308094, upload-time = "2026-04-01T14:43:48.438Z" }, + { url = "https://files.pythonhosted.org/packages/71/43/905a14a8b17fdb1ccb58d282454490662d2cb89a6bfec26af6d3520da5ec/pillow-12.2.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:56b25336f502b6ed02e889f4ece894a72612fe885889a6e8c4c80239ff6e5f5f", size = 4695402, upload-time = "2026-04-01T14:43:51.292Z" }, + { url = "https://files.pythonhosted.org/packages/73/dd/42107efcb777b16fa0393317eac58f5b5cf30e8392e266e76e51cff28c3d/pillow-12.2.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:f1c943e96e85df3d3478f7b691f229887e143f81fedab9b20205349ab04d73ed", size = 6280005, upload-time = "2026-04-01T14:43:54.242Z" }, + { url = "https://files.pythonhosted.org/packages/a8/68/b93e09e5e8549019e61acf49f65b1a8530765a7f812c77a7461bca7e4494/pillow-12.2.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:03f6fab9219220f041c74aeaa2939ff0062bd5c364ba9ce037197f4c6d498cd9", size = 8090669, upload-time = "2026-04-01T14:43:57.335Z" }, + { url = "https://files.pythonhosted.org/packages/4b/6e/3ccb54ce8ec4ddd1accd2d89004308b7b0b21c4ac3d20fa70af4760a4330/pillow-12.2.0-cp313-cp313-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:5cdfebd752ec52bf5bb4e35d9c64b40826bc5b40a13df7c3cda20a2c03a0f5ed", size = 6395194, upload-time = "2026-04-01T14:43:59.864Z" }, + { url = "https://files.pythonhosted.org/packages/67/ee/21d4e8536afd1a328f01b359b4d3997b291ffd35a237c877b331c1c3b71c/pillow-12.2.0-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:eedf4b74eda2b5a4b2b2fb4c006d6295df3bf29e459e198c90ea48e130dc75c3", size = 7082423, upload-time = "2026-04-01T14:44:02.74Z" }, + { url = "https://files.pythonhosted.org/packages/78/5f/e9f86ab0146464e8c133fe85df987ed9e77e08b29d8d35f9f9f4d6f917ba/pillow-12.2.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:00a2865911330191c0b818c59103b58a5e697cae67042366970a6b6f1b20b7f9", size = 6505667, upload-time = "2026-04-01T14:44:05.381Z" }, + { url = "https://files.pythonhosted.org/packages/ed/1e/409007f56a2fdce61584fd3acbc2bbc259857d555196cedcadc68c015c82/pillow-12.2.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:1e1757442ed87f4912397c6d35a0db6a7b52592156014706f17658ff58bbf795", size = 7208580, upload-time = "2026-04-01T14:44:08.39Z" }, + { url = "https://files.pythonhosted.org/packages/23/c4/7349421080b12fb35414607b8871e9534546c128a11965fd4a7002ccfbee/pillow-12.2.0-cp313-cp313-win32.whl", hash = "sha256:144748b3af2d1b358d41286056d0003f47cb339b8c43a9ea42f5fea4d8c66b6e", size = 6375896, upload-time = "2026-04-01T14:44:11.197Z" }, + { url = "https://files.pythonhosted.org/packages/3f/82/8a3739a5e470b3c6cbb1d21d315800d8e16bff503d1f16b03a4ec3212786/pillow-12.2.0-cp313-cp313-win_amd64.whl", hash = "sha256:390ede346628ccc626e5730107cde16c42d3836b89662a115a921f28440e6a3b", size = 7081266, upload-time = "2026-04-01T14:44:13.947Z" }, + { url = "https://files.pythonhosted.org/packages/c3/25/f968f618a062574294592f668218f8af564830ccebdd1fa6200f598e65c5/pillow-12.2.0-cp313-cp313-win_arm64.whl", hash = "sha256:8023abc91fba39036dbce14a7d6535632f99c0b857807cbbbf21ecc9f4717f06", size = 2463508, upload-time = "2026-04-01T14:44:16.312Z" }, + { url = "https://files.pythonhosted.org/packages/4d/a4/b342930964e3cb4dce5038ae34b0eab4653334995336cd486c5a8c25a00c/pillow-12.2.0-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:042db20a421b9bafecc4b84a8b6e444686bd9d836c7fd24542db3e7df7baad9b", size = 5309927, upload-time = "2026-04-01T14:44:18.89Z" }, + { url = "https://files.pythonhosted.org/packages/9f/de/23198e0a65a9cf06123f5435a5d95cea62a635697f8f03d134d3f3a96151/pillow-12.2.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:dd025009355c926a84a612fecf58bb315a3f6814b17ead51a8e48d3823d9087f", size = 4698624, upload-time = "2026-04-01T14:44:21.115Z" }, + { url = "https://files.pythonhosted.org/packages/01/a6/1265e977f17d93ea37aa28aa81bad4fa597933879fac2520d24e021c8da3/pillow-12.2.0-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:88ddbc66737e277852913bd1e07c150cc7bb124539f94c4e2df5344494e0a612", size = 6321252, upload-time = "2026-04-01T14:44:23.663Z" }, + { url = "https://files.pythonhosted.org/packages/3c/83/5982eb4a285967baa70340320be9f88e57665a387e3a53a7f0db8231a0cd/pillow-12.2.0-cp313-cp313t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:d362d1878f00c142b7e1a16e6e5e780f02be8195123f164edf7eddd911eefe7c", size = 8126550, upload-time = "2026-04-01T14:44:26.772Z" }, + { url = "https://files.pythonhosted.org/packages/4e/48/6ffc514adce69f6050d0753b1a18fd920fce8cac87620d5a31231b04bfc5/pillow-12.2.0-cp313-cp313t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:2c727a6d53cb0018aadd8018c2b938376af27914a68a492f59dfcaca650d5eea", size = 6433114, upload-time = "2026-04-01T14:44:29.615Z" }, + { url = "https://files.pythonhosted.org/packages/36/a3/f9a77144231fb8d40ee27107b4463e205fa4677e2ca2548e14da5cf18dce/pillow-12.2.0-cp313-cp313t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:efd8c21c98c5cc60653bcb311bef2ce0401642b7ce9d09e03a7da87c878289d4", size = 7115667, upload-time = "2026-04-01T14:44:32.773Z" }, + { url = "https://files.pythonhosted.org/packages/c1/fc/ac4ee3041e7d5a565e1c4fd72a113f03b6394cc72ab7089d27608f8aaccb/pillow-12.2.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:9f08483a632889536b8139663db60f6724bfcb443c96f1b18855860d7d5c0fd4", size = 6538966, upload-time = "2026-04-01T14:44:35.252Z" }, + { url = "https://files.pythonhosted.org/packages/c0/a8/27fb307055087f3668f6d0a8ccb636e7431d56ed0750e07a60547b1e083e/pillow-12.2.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:dac8d77255a37e81a2efcbd1fc05f1c15ee82200e6c240d7e127e25e365c39ea", size = 7238241, upload-time = "2026-04-01T14:44:37.875Z" }, + { url = "https://files.pythonhosted.org/packages/ad/4b/926ab182c07fccae9fcb120043464e1ff1564775ec8864f21a0ebce6ac25/pillow-12.2.0-cp313-cp313t-win32.whl", hash = "sha256:ee3120ae9dff32f121610bb08e4313be87e03efeadfc6c0d18f89127e24d0c24", size = 6379592, upload-time = "2026-04-01T14:44:40.336Z" }, + { url = "https://files.pythonhosted.org/packages/c2/c4/f9e476451a098181b30050cc4c9a3556b64c02cf6497ea421ac047e89e4b/pillow-12.2.0-cp313-cp313t-win_amd64.whl", hash = "sha256:325ca0528c6788d2a6c3d40e3568639398137346c3d6e66bb61db96b96511c98", size = 7085542, upload-time = "2026-04-01T14:44:43.251Z" }, + { url = "https://files.pythonhosted.org/packages/00/a4/285f12aeacbe2d6dc36c407dfbbe9e96d4a80b0fb710a337f6d2ad978c75/pillow-12.2.0-cp313-cp313t-win_arm64.whl", hash = "sha256:2e5a76d03a6c6dcef67edabda7a52494afa4035021a79c8558e14af25313d453", size = 2465765, upload-time = "2026-04-01T14:44:45.996Z" }, + { url = "https://files.pythonhosted.org/packages/bf/98/4595daa2365416a86cb0d495248a393dfc84e96d62ad080c8546256cb9c0/pillow-12.2.0-cp314-cp314-ios_13_0_arm64_iphoneos.whl", hash = "sha256:3adc9215e8be0448ed6e814966ecf3d9952f0ea40eb14e89a102b87f450660d8", size = 4100848, upload-time = "2026-04-01T14:44:48.48Z" }, + { url = "https://files.pythonhosted.org/packages/0b/79/40184d464cf89f6663e18dfcf7ca21aae2491fff1a16127681bf1fa9b8cf/pillow-12.2.0-cp314-cp314-ios_13_0_arm64_iphonesimulator.whl", hash = "sha256:6a9adfc6d24b10f89588096364cc726174118c62130c817c2837c60cf08a392b", size = 4176515, upload-time = "2026-04-01T14:44:51.353Z" }, + { url = "https://files.pythonhosted.org/packages/b0/63/703f86fd4c422a9cf722833670f4f71418fb116b2853ff7da722ea43f184/pillow-12.2.0-cp314-cp314-ios_13_0_x86_64_iphonesimulator.whl", hash = "sha256:6a6e67ea2e6feda684ed370f9a1c52e7a243631c025ba42149a2cc5934dec295", size = 3640159, upload-time = "2026-04-01T14:44:53.588Z" }, + { url = "https://files.pythonhosted.org/packages/71/e0/fb22f797187d0be2270f83500aab851536101b254bfa1eae10795709d283/pillow-12.2.0-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:2bb4a8d594eacdfc59d9e5ad972aa8afdd48d584ffd5f13a937a664c3e7db0ed", size = 5312185, upload-time = "2026-04-01T14:44:56.039Z" }, + { url = "https://files.pythonhosted.org/packages/ba/8c/1a9e46228571de18f8e28f16fabdfc20212a5d019f3e3303452b3f0a580d/pillow-12.2.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:80b2da48193b2f33ed0c32c38140f9d3186583ce7d516526d462645fd98660ae", size = 4695386, upload-time = "2026-04-01T14:44:58.663Z" }, + { url = "https://files.pythonhosted.org/packages/70/62/98f6b7f0c88b9addd0e87c217ded307b36be024d4ff8869a812b241d1345/pillow-12.2.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:22db17c68434de69d8ecfc2fe821569195c0c373b25cccb9cbdacf2c6e53c601", size = 6280384, upload-time = "2026-04-01T14:45:01.5Z" }, + { url = "https://files.pythonhosted.org/packages/5e/03/688747d2e91cfbe0e64f316cd2e8005698f76ada3130d0194664174fa5de/pillow-12.2.0-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:7b14cc0106cd9aecda615dd6903840a058b4700fcb817687d0ee4fc8b6e389be", size = 8091599, upload-time = "2026-04-01T14:45:04.5Z" }, + { url = "https://files.pythonhosted.org/packages/f6/35/577e22b936fcdd66537329b33af0b4ccfefaeabd8aec04b266528cddb33c/pillow-12.2.0-cp314-cp314-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:8cbeb542b2ebc6fcdacabf8aca8c1a97c9b3ad3927d46b8723f9d4f033288a0f", size = 6396021, upload-time = "2026-04-01T14:45:07.117Z" }, + { url = "https://files.pythonhosted.org/packages/11/8d/d2532ad2a603ca2b93ad9f5135732124e57811d0168155852f37fbce2458/pillow-12.2.0-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:4bfd07bc812fbd20395212969e41931001fd59eb55a60658b0e5710872e95286", size = 7083360, upload-time = "2026-04-01T14:45:09.763Z" }, + { url = "https://files.pythonhosted.org/packages/5e/26/d325f9f56c7e039034897e7380e9cc202b1e368bfd04d4cbe6a441f02885/pillow-12.2.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:9aba9a17b623ef750a4d11b742cbafffeb48a869821252b30ee21b5e91392c50", size = 6507628, upload-time = "2026-04-01T14:45:12.378Z" }, + { url = "https://files.pythonhosted.org/packages/5f/f7/769d5632ffb0988f1c5e7660b3e731e30f7f8ec4318e94d0a5d674eb65a4/pillow-12.2.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:deede7c263feb25dba4e82ea23058a235dcc2fe1f6021025dc71f2b618e26104", size = 7209321, upload-time = "2026-04-01T14:45:15.122Z" }, + { url = "https://files.pythonhosted.org/packages/6a/7a/c253e3c645cd47f1aceea6a8bacdba9991bf45bb7dfe927f7c893e89c93c/pillow-12.2.0-cp314-cp314-win32.whl", hash = "sha256:632ff19b2778e43162304d50da0181ce24ac5bb8180122cbe1bf4673428328c7", size = 6479723, upload-time = "2026-04-01T14:45:17.797Z" }, + { url = "https://files.pythonhosted.org/packages/cd/8b/601e6566b957ca50e28725cb6c355c59c2c8609751efbecd980db44e0349/pillow-12.2.0-cp314-cp314-win_amd64.whl", hash = "sha256:4e6c62e9d237e9b65fac06857d511e90d8461a32adcc1b9065ea0c0fa3a28150", size = 7217400, upload-time = "2026-04-01T14:45:20.529Z" }, + { url = "https://files.pythonhosted.org/packages/d6/94/220e46c73065c3e2951bb91c11a1fb636c8c9ad427ac3ce7d7f3359b9b2f/pillow-12.2.0-cp314-cp314-win_arm64.whl", hash = "sha256:b1c1fbd8a5a1af3412a0810d060a78b5136ec0836c8a4ef9aa11807f2a22f4e1", size = 2554835, upload-time = "2026-04-01T14:45:23.162Z" }, + { url = "https://files.pythonhosted.org/packages/b6/ab/1b426a3974cb0e7da5c29ccff4807871d48110933a57207b5a676cccc155/pillow-12.2.0-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:57850958fe9c751670e49b2cecf6294acc99e562531f4bd317fa5ddee2068463", size = 5314225, upload-time = "2026-04-01T14:45:25.637Z" }, + { url = "https://files.pythonhosted.org/packages/19/1e/dce46f371be2438eecfee2a1960ee2a243bbe5e961890146d2dee1ff0f12/pillow-12.2.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:d5d38f1411c0ed9f97bcb49b7bd59b6b7c314e0e27420e34d99d844b9ce3b6f3", size = 4698541, upload-time = "2026-04-01T14:45:28.355Z" }, + { url = "https://files.pythonhosted.org/packages/55/c3/7fbecf70adb3a0c33b77a300dc52e424dc22ad8cdc06557a2e49523b703d/pillow-12.2.0-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:5c0a9f29ca8e79f09de89293f82fc9b0270bb4af1d58bc98f540cc4aedf03166", size = 6322251, upload-time = "2026-04-01T14:45:30.924Z" }, + { url = "https://files.pythonhosted.org/packages/1c/3c/7fbc17cfb7e4fe0ef1642e0abc17fc6c94c9f7a16be41498e12e2ba60408/pillow-12.2.0-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:1610dd6c61621ae1cf811bef44d77e149ce3f7b95afe66a4512f8c59f25d9ebe", size = 8127807, upload-time = "2026-04-01T14:45:33.908Z" }, + { url = "https://files.pythonhosted.org/packages/ff/c3/a8ae14d6defd2e448493ff512fae903b1e9bd40b72efb6ec55ce0048c8ce/pillow-12.2.0-cp314-cp314t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:0a34329707af4f73cf1782a36cd2289c0368880654a2c11f027bcee9052d35dd", size = 6433935, upload-time = "2026-04-01T14:45:36.623Z" }, + { url = "https://files.pythonhosted.org/packages/6e/32/2880fb3a074847ac159d8f902cb43278a61e85f681661e7419e6596803ed/pillow-12.2.0-cp314-cp314t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:8e9c4f5b3c546fa3458a29ab22646c1c6c787ea8f5ef51300e5a60300736905e", size = 7116720, upload-time = "2026-04-01T14:45:39.258Z" }, + { url = "https://files.pythonhosted.org/packages/46/87/495cc9c30e0129501643f24d320076f4cc54f718341df18cc70ec94c44e1/pillow-12.2.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:fb043ee2f06b41473269765c2feae53fc2e2fbf96e5e22ca94fb5ad677856f06", size = 6540498, upload-time = "2026-04-01T14:45:41.879Z" }, + { url = "https://files.pythonhosted.org/packages/18/53/773f5edca692009d883a72211b60fdaf8871cbef075eaa9d577f0a2f989e/pillow-12.2.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:f278f034eb75b4e8a13a54a876cc4a5ab39173d2cdd93a638e1b467fc545ac43", size = 7239413, upload-time = "2026-04-01T14:45:44.705Z" }, + { url = "https://files.pythonhosted.org/packages/c9/e4/4b64a97d71b2a83158134abbb2f5bd3f8a2ea691361282f010998f339ec7/pillow-12.2.0-cp314-cp314t-win32.whl", hash = "sha256:6bb77b2dcb06b20f9f4b4a8454caa581cd4dd0643a08bacf821216a16d9c8354", size = 6482084, upload-time = "2026-04-01T14:45:47.568Z" }, + { url = "https://files.pythonhosted.org/packages/ba/13/306d275efd3a3453f72114b7431c877d10b1154014c1ebbedd067770d629/pillow-12.2.0-cp314-cp314t-win_amd64.whl", hash = "sha256:6562ace0d3fb5f20ed7290f1f929cae41b25ae29528f2af1722966a0a02e2aa1", size = 7225152, upload-time = "2026-04-01T14:45:50.032Z" }, + { url = "https://files.pythonhosted.org/packages/ff/6e/cf826fae916b8658848d7b9f38d88da6396895c676e8086fc0988073aaf8/pillow-12.2.0-cp314-cp314t-win_arm64.whl", hash = "sha256:aa88ccfe4e32d362816319ed727a004423aab09c5cea43c01a4b435643fa34eb", size = 2556579, upload-time = "2026-04-01T14:45:52.529Z" }, +] + +[[package]] +name = "platformdirs" +version = "4.9.6" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/9f/4a/0883b8e3802965322523f0b200ecf33d31f10991d0401162f4b23c698b42/platformdirs-4.9.6.tar.gz", hash = "sha256:3bfa75b0ad0db84096ae777218481852c0ebc6c727b3168c1b9e0118e458cf0a", size = 29400, upload-time = "2026-04-09T00:04:10.812Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/75/a6/a0a304dc33b49145b21f4808d763822111e67d1c3a32b524a1baf947b6e1/platformdirs-4.9.6-py3-none-any.whl", hash = "sha256:e61adb1d5e5cb3441b4b7710bea7e4c12250ca49439228cc1021c00dcfac0917", size = 21348, upload-time = "2026-04-09T00:04:09.463Z" }, +] + +[[package]] +name = "prometheus-client" +version = "0.25.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/1b/fb/d9aa83ffe43ce1f19e557c0971d04b90561b0cfd50762aafb01968285553/prometheus_client-0.25.0.tar.gz", hash = "sha256:5e373b75c31afb3c86f1a52fa1ad470c9aace18082d39ec0d2f918d11cc9ba28", size = 86035, upload-time = "2026-04-09T19:53:42.359Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/8d/9b/d4b1e644385499c8346fa9b622a3f030dce14cd6ef8a1871c221a17a67e7/prometheus_client-0.25.0-py3-none-any.whl", hash = "sha256:d5aec89e349a6ec230805d0df882f3807f74fd6c1a2fa86864e3c2279059fed1", size = 64154, upload-time = "2026-04-09T19:53:41.324Z" }, +] + +[[package]] +name = "prompt-toolkit" +version = "3.0.52" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "wcwidth" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/a1/96/06e01a7b38dce6fe1db213e061a4602dd6032a8a97ef6c1a862537732421/prompt_toolkit-3.0.52.tar.gz", hash = "sha256:28cde192929c8e7321de85de1ddbe736f1375148b02f2e17edd840042b1be855", size = 434198, upload-time = "2025-08-27T15:24:02.057Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/84/03/0d3ce49e2505ae70cf43bc5bb3033955d2fc9f932163e84dc0779cc47f48/prompt_toolkit-3.0.52-py3-none-any.whl", hash = "sha256:9aac639a3bbd33284347de5ad8d68ecc044b91a762dc39b7c21095fcd6a19955", size = 391431, upload-time = "2025-08-27T15:23:59.498Z" }, +] + +[[package]] +name = "psutil" +version = "7.2.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/aa/c6/d1ddf4abb55e93cebc4f2ed8b5d6dbad109ecb8d63748dd2b20ab5e57ebe/psutil-7.2.2.tar.gz", hash = "sha256:0746f5f8d406af344fd547f1c8daa5f5c33dbc293bb8d6a16d80b4bb88f59372", size = 493740, upload-time = "2026-01-28T18:14:54.428Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/51/08/510cbdb69c25a96f4ae523f733cdc963ae654904e8db864c07585ef99875/psutil-7.2.2-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:2edccc433cbfa046b980b0df0171cd25bcaeb3a68fe9022db0979e7aa74a826b", size = 130595, upload-time = "2026-01-28T18:14:57.293Z" }, + { url = "https://files.pythonhosted.org/packages/d6/f5/97baea3fe7a5a9af7436301f85490905379b1c6f2dd51fe3ecf24b4c5fbf/psutil-7.2.2-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:e78c8603dcd9a04c7364f1a3e670cea95d51ee865e4efb3556a3a63adef958ea", size = 131082, upload-time = "2026-01-28T18:14:59.732Z" }, + { url = "https://files.pythonhosted.org/packages/37/d6/246513fbf9fa174af531f28412297dd05241d97a75911ac8febefa1a53c6/psutil-7.2.2-cp313-cp313t-manylinux2010_x86_64.manylinux_2_12_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:1a571f2330c966c62aeda00dd24620425d4b0cc86881c89861fbc04549e5dc63", size = 181476, upload-time = "2026-01-28T18:15:01.884Z" }, + { url = "https://files.pythonhosted.org/packages/b8/b5/9182c9af3836cca61696dabe4fd1304e17bc56cb62f17439e1154f225dd3/psutil-7.2.2-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:917e891983ca3c1887b4ef36447b1e0873e70c933afc831c6b6da078ba474312", size = 184062, upload-time = "2026-01-28T18:15:04.436Z" }, + { url = "https://files.pythonhosted.org/packages/16/ba/0756dca669f5a9300d0cbcbfae9a4c30e446dfc7440ffe43ded5724bfd93/psutil-7.2.2-cp313-cp313t-win_amd64.whl", hash = "sha256:ab486563df44c17f5173621c7b198955bd6b613fb87c71c161f827d3fb149a9b", size = 139893, upload-time = "2026-01-28T18:15:06.378Z" }, + { url = "https://files.pythonhosted.org/packages/1c/61/8fa0e26f33623b49949346de05ec1ddaad02ed8ba64af45f40a147dbfa97/psutil-7.2.2-cp313-cp313t-win_arm64.whl", hash = "sha256:ae0aefdd8796a7737eccea863f80f81e468a1e4cf14d926bd9b6f5f2d5f90ca9", size = 135589, upload-time = "2026-01-28T18:15:08.03Z" }, + { url = "https://files.pythonhosted.org/packages/81/69/ef179ab5ca24f32acc1dac0c247fd6a13b501fd5534dbae0e05a1c48b66d/psutil-7.2.2-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:eed63d3b4d62449571547b60578c5b2c4bcccc5387148db46e0c2313dad0ee00", size = 130664, upload-time = "2026-01-28T18:15:09.469Z" }, + { url = "https://files.pythonhosted.org/packages/7b/64/665248b557a236d3fa9efc378d60d95ef56dd0a490c2cd37dafc7660d4a9/psutil-7.2.2-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:7b6d09433a10592ce39b13d7be5a54fbac1d1228ed29abc880fb23df7cb694c9", size = 131087, upload-time = "2026-01-28T18:15:11.724Z" }, + { url = "https://files.pythonhosted.org/packages/d5/2e/e6782744700d6759ebce3043dcfa661fb61e2fb752b91cdeae9af12c2178/psutil-7.2.2-cp314-cp314t-manylinux2010_x86_64.manylinux_2_12_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:1fa4ecf83bcdf6e6c8f4449aff98eefb5d0604bf88cb883d7da3d8d2d909546a", size = 182383, upload-time = "2026-01-28T18:15:13.445Z" }, + { url = "https://files.pythonhosted.org/packages/57/49/0a41cefd10cb7505cdc04dab3eacf24c0c2cb158a998b8c7b1d27ee2c1f5/psutil-7.2.2-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:e452c464a02e7dc7822a05d25db4cde564444a67e58539a00f929c51eddda0cf", size = 185210, upload-time = "2026-01-28T18:15:16.002Z" }, + { url = "https://files.pythonhosted.org/packages/dd/2c/ff9bfb544f283ba5f83ba725a3c5fec6d6b10b8f27ac1dc641c473dc390d/psutil-7.2.2-cp314-cp314t-win_amd64.whl", hash = "sha256:c7663d4e37f13e884d13994247449e9f8f574bc4655d509c3b95e9ec9e2b9dc1", size = 141228, upload-time = "2026-01-28T18:15:18.385Z" }, + { url = "https://files.pythonhosted.org/packages/f2/fc/f8d9c31db14fcec13748d373e668bc3bed94d9077dbc17fb0eebc073233c/psutil-7.2.2-cp314-cp314t-win_arm64.whl", hash = "sha256:11fe5a4f613759764e79c65cf11ebdf26e33d6dd34336f8a337aa2996d71c841", size = 136284, upload-time = "2026-01-28T18:15:19.912Z" }, + { url = "https://files.pythonhosted.org/packages/e7/36/5ee6e05c9bd427237b11b3937ad82bb8ad2752d72c6969314590dd0c2f6e/psutil-7.2.2-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:ed0cace939114f62738d808fdcecd4c869222507e266e574799e9c0faa17d486", size = 129090, upload-time = "2026-01-28T18:15:22.168Z" }, + { url = "https://files.pythonhosted.org/packages/80/c4/f5af4c1ca8c1eeb2e92ccca14ce8effdeec651d5ab6053c589b074eda6e1/psutil-7.2.2-cp36-abi3-macosx_11_0_arm64.whl", hash = "sha256:1a7b04c10f32cc88ab39cbf606e117fd74721c831c98a27dc04578deb0c16979", size = 129859, upload-time = "2026-01-28T18:15:23.795Z" }, + { url = "https://files.pythonhosted.org/packages/b5/70/5d8df3b09e25bce090399cf48e452d25c935ab72dad19406c77f4e828045/psutil-7.2.2-cp36-abi3-manylinux2010_x86_64.manylinux_2_12_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:076a2d2f923fd4821644f5ba89f059523da90dc9014e85f8e45a5774ca5bc6f9", size = 155560, upload-time = "2026-01-28T18:15:25.976Z" }, + { url = "https://files.pythonhosted.org/packages/63/65/37648c0c158dc222aba51c089eb3bdfa238e621674dc42d48706e639204f/psutil-7.2.2-cp36-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:b0726cecd84f9474419d67252add4ac0cd9811b04d61123054b9fb6f57df6e9e", size = 156997, upload-time = "2026-01-28T18:15:27.794Z" }, + { url = "https://files.pythonhosted.org/packages/8e/13/125093eadae863ce03c6ffdbae9929430d116a246ef69866dad94da3bfbc/psutil-7.2.2-cp36-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:fd04ef36b4a6d599bbdb225dd1d3f51e00105f6d48a28f006da7f9822f2606d8", size = 148972, upload-time = "2026-01-28T18:15:29.342Z" }, + { url = "https://files.pythonhosted.org/packages/04/78/0acd37ca84ce3ddffaa92ef0f571e073faa6d8ff1f0559ab1272188ea2be/psutil-7.2.2-cp36-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:b58fabe35e80b264a4e3bb23e6b96f9e45a3df7fb7eed419ac0e5947c61e47cc", size = 148266, upload-time = "2026-01-28T18:15:31.597Z" }, + { url = "https://files.pythonhosted.org/packages/b4/90/e2159492b5426be0c1fef7acba807a03511f97c5f86b3caeda6ad92351a7/psutil-7.2.2-cp37-abi3-win_amd64.whl", hash = "sha256:eb7e81434c8d223ec4a219b5fc1c47d0417b12be7ea866e24fb5ad6e84b3d988", size = 137737, upload-time = "2026-01-28T18:15:33.849Z" }, + { url = "https://files.pythonhosted.org/packages/8c/c7/7bb2e321574b10df20cbde462a94e2b71d05f9bbda251ef27d104668306a/psutil-7.2.2-cp37-abi3-win_arm64.whl", hash = "sha256:8c233660f575a5a89e6d4cb65d9f938126312bca76d8fe087b947b3a1aaac9ee", size = 134617, upload-time = "2026-01-28T18:15:36.514Z" }, +] + +[[package]] +name = "ptyprocess" +version = "0.7.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/20/e5/16ff212c1e452235a90aeb09066144d0c5a6a8c0834397e03f5224495c4e/ptyprocess-0.7.0.tar.gz", hash = "sha256:5c5d0a3b48ceee0b48485e0c26037c0acd7d29765ca3fbb5cb3831d347423220", size = 70762, upload-time = "2020-12-28T15:15:30.155Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/22/a6/858897256d0deac81a172289110f31629fc4cee19b6f01283303e18c8db3/ptyprocess-0.7.0-py2.py3-none-any.whl", hash = "sha256:4b41f3967fce3af57cc7e94b888626c18bf37a083e3651ca8feeb66d492fef35", size = 13993, upload-time = "2020-12-28T15:15:28.35Z" }, +] + +[[package]] +name = "pure-eval" +version = "0.2.3" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/cd/05/0a34433a064256a578f1783a10da6df098ceaa4a57bbeaa96a6c0352786b/pure_eval-0.2.3.tar.gz", hash = "sha256:5f4e983f40564c576c7c8635ae88db5956bb2229d7e9237d03b3c0b0190eaf42", size = 19752, upload-time = "2024-07-21T12:58:21.801Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/8e/37/efad0257dc6e593a18957422533ff0f87ede7c9c6ea010a2177d738fb82f/pure_eval-0.2.3-py3-none-any.whl", hash = "sha256:1db8e35b67b3d218d818ae653e27f06c3aa420901fa7b081ca98cbedc874e0d0", size = 11842, upload-time = "2024-07-21T12:58:20.04Z" }, +] + +[[package]] +name = "pyarrow" +version = "23.0.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/88/22/134986a4cc224d593c1afde5494d18ff629393d74cc2eddb176669f234a4/pyarrow-23.0.1.tar.gz", hash = "sha256:b8c5873e33440b2bc2f4a79d2b47017a89c5a24116c055625e6f2ee50523f019", size = 1167336, upload-time = "2026-02-16T10:14:12.39Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/47/10/2cbe4c6f0fb83d2de37249567373d64327a5e4d8db72f486db42875b08f6/pyarrow-23.0.1-cp313-cp313-macosx_12_0_arm64.whl", hash = "sha256:6b8fda694640b00e8af3c824f99f789e836720aa8c9379fb435d4c4953a756b8", size = 34210066, upload-time = "2026-02-16T10:10:45.487Z" }, + { url = "https://files.pythonhosted.org/packages/cb/4f/679fa7e84dadbaca7a65f7cdba8d6c83febbd93ca12fa4adf40ba3b6362b/pyarrow-23.0.1-cp313-cp313-macosx_12_0_x86_64.whl", hash = "sha256:8ff51b1addc469b9444b7c6f3548e19dc931b172ab234e995a60aea9f6e6025f", size = 35825526, upload-time = "2026-02-16T10:10:52.266Z" }, + { url = "https://files.pythonhosted.org/packages/f9/63/d2747d930882c9d661e9398eefc54f15696547b8983aaaf11d4a2e8b5426/pyarrow-23.0.1-cp313-cp313-manylinux_2_28_aarch64.whl", hash = "sha256:71c5be5cbf1e1cb6169d2a0980850bccb558ddc9b747b6206435313c47c37677", size = 44473279, upload-time = "2026-02-16T10:11:01.557Z" }, + { url = "https://files.pythonhosted.org/packages/b3/93/10a48b5e238de6d562a411af6467e71e7aedbc9b87f8d3a35f1560ae30fb/pyarrow-23.0.1-cp313-cp313-manylinux_2_28_x86_64.whl", hash = "sha256:9b6f4f17b43bc39d56fec96e53fe89d94bac3eb134137964371b45352d40d0c2", size = 47585798, upload-time = "2026-02-16T10:11:09.401Z" }, + { url = "https://files.pythonhosted.org/packages/5c/20/476943001c54ef078dbf9542280e22741219a184a0632862bca4feccd666/pyarrow-23.0.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:9fc13fc6c403d1337acab46a2c4346ca6c9dec5780c3c697cf8abfd5e19b6b37", size = 48179446, upload-time = "2026-02-16T10:11:17.781Z" }, + { url = "https://files.pythonhosted.org/packages/4b/b6/5dd0c47b335fcd8edba9bfab78ad961bd0fd55ebe53468cc393f45e0be60/pyarrow-23.0.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:5c16ed4f53247fa3ffb12a14d236de4213a4415d127fe9cebed33d51671113e2", size = 50623972, upload-time = "2026-02-16T10:11:26.185Z" }, + { url = "https://files.pythonhosted.org/packages/d5/09/a532297c9591a727d67760e2e756b83905dd89adb365a7f6e9c72578bcc1/pyarrow-23.0.1-cp313-cp313-win_amd64.whl", hash = "sha256:cecfb12ef629cf6be0b1887f9f86463b0dd3dc3195ae6224e74006be4736035a", size = 27540749, upload-time = "2026-02-16T10:12:23.297Z" }, + { url = "https://files.pythonhosted.org/packages/a5/8e/38749c4b1303e6ae76b3c80618f84861ae0c55dd3c2273842ea6f8258233/pyarrow-23.0.1-cp313-cp313t-macosx_12_0_arm64.whl", hash = "sha256:29f7f7419a0e30264ea261fdc0e5fe63ce5a6095003db2945d7cd78df391a7e1", size = 34471544, upload-time = "2026-02-16T10:11:32.535Z" }, + { url = "https://files.pythonhosted.org/packages/a3/73/f237b2bc8c669212f842bcfd842b04fc8d936bfc9d471630569132dc920d/pyarrow-23.0.1-cp313-cp313t-macosx_12_0_x86_64.whl", hash = "sha256:33d648dc25b51fd8055c19e4261e813dfc4d2427f068bcecc8b53d01b81b0500", size = 35949911, upload-time = "2026-02-16T10:11:39.813Z" }, + { url = "https://files.pythonhosted.org/packages/0c/86/b912195eee0903b5611bf596833def7d146ab2d301afeb4b722c57ffc966/pyarrow-23.0.1-cp313-cp313t-manylinux_2_28_aarch64.whl", hash = "sha256:cd395abf8f91c673dd3589cadc8cc1ee4e8674fa61b2e923c8dd215d9c7d1f41", size = 44520337, upload-time = "2026-02-16T10:11:47.764Z" }, + { url = "https://files.pythonhosted.org/packages/69/c2/f2a717fb824f62d0be952ea724b4f6f9372a17eed6f704b5c9526f12f2f1/pyarrow-23.0.1-cp313-cp313t-manylinux_2_28_x86_64.whl", hash = "sha256:00be9576d970c31defb5c32eb72ef585bf600ef6d0a82d5eccaae96639cf9d07", size = 47548944, upload-time = "2026-02-16T10:11:56.607Z" }, + { url = "https://files.pythonhosted.org/packages/84/a7/90007d476b9f0dc308e3bc57b832d004f848fd6c0da601375d20d92d1519/pyarrow-23.0.1-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:c2139549494445609f35a5cda4eb94e2c9e4d704ce60a095b342f82460c73a83", size = 48236269, upload-time = "2026-02-16T10:12:04.47Z" }, + { url = "https://files.pythonhosted.org/packages/b0/3f/b16fab3e77709856eb6ac328ce35f57a6d4a18462c7ca5186ef31b45e0e0/pyarrow-23.0.1-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:7044b442f184d84e2351e5084600f0d7343d6117aabcbc1ac78eb1ae11eb4125", size = 50604794, upload-time = "2026-02-16T10:12:11.797Z" }, + { url = "https://files.pythonhosted.org/packages/e9/a1/22df0620a9fac31d68397a75465c344e83c3dfe521f7612aea33e27ab6c0/pyarrow-23.0.1-cp313-cp313t-win_amd64.whl", hash = "sha256:a35581e856a2fafa12f3f54fce4331862b1cfb0bef5758347a858a4aa9d6bae8", size = 27660642, upload-time = "2026-02-16T10:12:17.746Z" }, + { url = "https://files.pythonhosted.org/packages/8d/1b/6da9a89583ce7b23ac611f183ae4843cd3a6cf54f079549b0e8c14031e73/pyarrow-23.0.1-cp314-cp314-macosx_12_0_arm64.whl", hash = "sha256:5df1161da23636a70838099d4aaa65142777185cc0cdba4037a18cee7d8db9ca", size = 34238755, upload-time = "2026-02-16T10:12:32.819Z" }, + { url = "https://files.pythonhosted.org/packages/ae/b5/d58a241fbe324dbaeb8df07be6af8752c846192d78d2272e551098f74e88/pyarrow-23.0.1-cp314-cp314-macosx_12_0_x86_64.whl", hash = "sha256:fa8e51cb04b9f8c9c5ace6bab63af9a1f88d35c0d6cbf53e8c17c098552285e1", size = 35847826, upload-time = "2026-02-16T10:12:38.949Z" }, + { url = "https://files.pythonhosted.org/packages/54/a5/8cbc83f04aba433ca7b331b38f39e000efd9f0c7ce47128670e737542996/pyarrow-23.0.1-cp314-cp314-manylinux_2_28_aarch64.whl", hash = "sha256:0b95a3994f015be13c63148fef8832e8a23938128c185ee951c98908a696e0eb", size = 44536859, upload-time = "2026-02-16T10:12:45.467Z" }, + { url = "https://files.pythonhosted.org/packages/36/2e/c0f017c405fcdc252dbccafbe05e36b0d0eb1ea9a958f081e01c6972927f/pyarrow-23.0.1-cp314-cp314-manylinux_2_28_x86_64.whl", hash = "sha256:4982d71350b1a6e5cfe1af742c53dfb759b11ce14141870d05d9e540d13bc5d1", size = 47614443, upload-time = "2026-02-16T10:12:55.525Z" }, + { url = "https://files.pythonhosted.org/packages/af/6b/2314a78057912f5627afa13ba43809d9d653e6630859618b0fd81a4e0759/pyarrow-23.0.1-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:c250248f1fe266db627921c89b47b7c06fee0489ad95b04d50353537d74d6886", size = 48232991, upload-time = "2026-02-16T10:13:04.729Z" }, + { url = "https://files.pythonhosted.org/packages/40/f2/1bcb1d3be3460832ef3370d621142216e15a2c7c62602a4ea19ec240dd64/pyarrow-23.0.1-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:5f4763b83c11c16e5f4c15601ba6dfa849e20723b46aa2617cb4bffe8768479f", size = 50645077, upload-time = "2026-02-16T10:13:14.147Z" }, + { url = "https://files.pythonhosted.org/packages/eb/3f/b1da7b61cd66566a4d4c8383d376c606d1c34a906c3f1cb35c479f59d1aa/pyarrow-23.0.1-cp314-cp314-win_amd64.whl", hash = "sha256:3a4c85ef66c134161987c17b147d6bffdca4566f9a4c1d81a0a01cdf08414ea5", size = 28234271, upload-time = "2026-02-16T10:14:09.397Z" }, + { url = "https://files.pythonhosted.org/packages/b5/78/07f67434e910a0f7323269be7bfbf58699bd0c1d080b18a1ab49ba943fe8/pyarrow-23.0.1-cp314-cp314t-macosx_12_0_arm64.whl", hash = "sha256:17cd28e906c18af486a499422740298c52d7c6795344ea5002a7720b4eadf16d", size = 34488692, upload-time = "2026-02-16T10:13:21.541Z" }, + { url = "https://files.pythonhosted.org/packages/50/76/34cf7ae93ece1f740a04910d9f7e80ba166b9b4ab9596a953e9e62b90fe1/pyarrow-23.0.1-cp314-cp314t-macosx_12_0_x86_64.whl", hash = "sha256:76e823d0e86b4fb5e1cf4a58d293036e678b5a4b03539be933d3b31f9406859f", size = 35964383, upload-time = "2026-02-16T10:13:28.63Z" }, + { url = "https://files.pythonhosted.org/packages/46/90/459b827238936d4244214be7c684e1b366a63f8c78c380807ae25ed92199/pyarrow-23.0.1-cp314-cp314t-manylinux_2_28_aarch64.whl", hash = "sha256:a62e1899e3078bf65943078b3ad2a6ddcacf2373bc06379aac61b1e548a75814", size = 44538119, upload-time = "2026-02-16T10:13:35.506Z" }, + { url = "https://files.pythonhosted.org/packages/28/a1/93a71ae5881e99d1f9de1d4554a87be37da11cd6b152239fb5bd924fdc64/pyarrow-23.0.1-cp314-cp314t-manylinux_2_28_x86_64.whl", hash = "sha256:df088e8f640c9fae3b1f495b3c64755c4e719091caf250f3a74d095ddf3c836d", size = 47571199, upload-time = "2026-02-16T10:13:42.504Z" }, + { url = "https://files.pythonhosted.org/packages/88/a3/d2c462d4ef313521eaf2eff04d204ac60775263f1fb08c374b543f79f610/pyarrow-23.0.1-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:46718a220d64677c93bc243af1d44b55998255427588e400677d7192671845c7", size = 48259435, upload-time = "2026-02-16T10:13:49.226Z" }, + { url = "https://files.pythonhosted.org/packages/cc/f1/11a544b8c3d38a759eb3fbb022039117fd633e9a7b19e4841cc3da091915/pyarrow-23.0.1-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:a09f3876e87f48bc2f13583ab551f0379e5dfb83210391e68ace404181a20690", size = 50629149, upload-time = "2026-02-16T10:13:57.238Z" }, + { url = "https://files.pythonhosted.org/packages/50/f2/c0e76a0b451ffdf0cf788932e182758eb7558953f4f27f1aff8e2518b653/pyarrow-23.0.1-cp314-cp314t-win_amd64.whl", hash = "sha256:527e8d899f14bd15b740cd5a54ad56b7f98044955373a17179d5956ddb93d9ce", size = 28365807, upload-time = "2026-02-16T10:14:03.892Z" }, +] + +[[package]] +name = "pycparser" +version = "3.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/1b/7d/92392ff7815c21062bea51aa7b87d45576f649f16458d78b7cf94b9ab2e6/pycparser-3.0.tar.gz", hash = "sha256:600f49d217304a5902ac3c37e1281c9fe94e4d0489de643a9504c5cdfdfc6b29", size = 103492, upload-time = "2026-01-21T14:26:51.89Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/0c/c3/44f3fbbfa403ea2a7c779186dc20772604442dde72947e7d01069cbe98e3/pycparser-3.0-py3-none-any.whl", hash = "sha256:b727414169a36b7d524c1c3e31839a521725078d7b2ff038656844266160a992", size = 48172, upload-time = "2026-01-21T14:26:50.693Z" }, +] + +[[package]] +name = "pycrdt" +version = "0.12.50" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "anyio" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/5d/bd/6e049694ad7fed0baf45a62629ff2c7aa1c26e0581a4d4987e0fd39fe951/pycrdt-0.12.50.tar.gz", hash = "sha256:506d4bc00d7d566de4018dca52998ab7cf97c787363bc59440d3a3bb3336d1a0", size = 84528, upload-time = "2026-03-16T09:39:15.924Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/d1/ea/cdc543c51971c513f3b23c34d17ae672dd2fab40977b8d94344c6e8099be/pycrdt-0.12.50-cp313-cp313-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl", hash = "sha256:f75c95335cacc459dbb3c4e55afbd231f8befd333c617ffad1bbe348018021de", size = 1721432, upload-time = "2026-03-16T09:38:16.738Z" }, + { url = "https://files.pythonhosted.org/packages/b6/30/cde0c58cdfb0f2e4d523443637b11b9bb5963024f5f3cd9e889b8195eab4/pycrdt-0.12.50-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3842dff93946c1b46ea8c508f7d79f07f0a8c54fe8f8e83e6cbb1f9f35a62899", size = 944575, upload-time = "2026-03-16T09:38:18.574Z" }, + { url = "https://files.pythonhosted.org/packages/df/a8/b36e98bca96b9c9b3d554ce6984128dff076a47cb350462efb122a09613e/pycrdt-0.12.50-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:fba48534acb7ba22a975c38ff531178d25a01c29d5d4ec2ecfe1c45754cde181", size = 962165, upload-time = "2026-03-16T09:38:20.112Z" }, + { url = "https://files.pythonhosted.org/packages/69/c2/38e0055416466feb9b33cfc96a95c3bd3985cdb547fdc0e556d8903e074f/pycrdt-0.12.50-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a5ca809926c3e08965b201b277c26d319c47078ba4b22178976f0455b351155b", size = 1135011, upload-time = "2026-03-16T09:38:21.952Z" }, + { url = "https://files.pythonhosted.org/packages/fe/5f/9597d1b2fcd8f1bff78308352dc8568012e1e2c2ef44a0e5ca11cd04aa81/pycrdt-0.12.50-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:bffe6a7e6a59ea1c74a53a0ffa2fee27ff54e454cff333ef952922535c7c8ffa", size = 987535, upload-time = "2026-03-16T09:38:23.459Z" }, + { url = "https://files.pythonhosted.org/packages/ed/f8/882da205925f147610ca790304a025232c164256421655e19cd9eabfca06/pycrdt-0.12.50-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:688d8cb017a729719be8f9ecf488daba24781c05a1635f725ca257aa9a90acfd", size = 956238, upload-time = "2026-03-16T09:38:25.473Z" }, + { url = "https://files.pythonhosted.org/packages/78/91/6cf0db29eebdafe8d3a27ec0a9ece583acab0959d0de22968fcc43f51d75/pycrdt-0.12.50-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:71f9dfc24636dc9789246dae4c8db39f5b9b419c1a1f6f53b782ae22e8febbef", size = 1046621, upload-time = "2026-03-16T09:38:27.349Z" }, + { url = "https://files.pythonhosted.org/packages/b4/40/f1e79a74c12439a595f1986a403e08a35abedce5929c4f464be5f2ec8109/pycrdt-0.12.50-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:a33635da609afe467e4ae644766416454535161ec7e1427294a59ed8a5e80015", size = 1121675, upload-time = "2026-03-16T09:38:28.991Z" }, + { url = "https://files.pythonhosted.org/packages/03/7f/b966b7c489e306070eef305b3f591e7ce7a34ee445cb55d1b8fd4fa6e338/pycrdt-0.12.50-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:f48c78ef3710c033d07d5de326362826eda8fa941859f06c146007d6122b3bb4", size = 1235939, upload-time = "2026-03-16T09:38:30.721Z" }, + { url = "https://files.pythonhosted.org/packages/c7/7a/0a4a74c68349ee72c3e92baad0cb9fbc6a94f2c122a228489357b8ad3507/pycrdt-0.12.50-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:c714c1582b804bd296f9b8530353bfab54386a145164e9693443e38b23392d69", size = 1222964, upload-time = "2026-03-16T09:38:32.323Z" }, + { url = "https://files.pythonhosted.org/packages/be/54/c96b470ebc5eaf355beeb8ffaf0235976e3e1fb9d4bc8a1169138c7e5063/pycrdt-0.12.50-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:d88a146090d9d6fc64687574c6014b26be1673b8b54b450fca23f115068c2852", size = 1165811, upload-time = "2026-03-16T09:38:34.05Z" }, + { url = "https://files.pythonhosted.org/packages/78/e4/070a16212142bda9cb585571066e1aa48ffcdc2ffb3540759d96dcebd141/pycrdt-0.12.50-cp313-cp313-win32.whl", hash = "sha256:a149f0f080f19b1c9a5614885e134ebbe159ee8add9fce96b81fcb3ea261df94", size = 695256, upload-time = "2026-03-16T09:38:35.705Z" }, + { url = "https://files.pythonhosted.org/packages/03/63/e0beaeabc4bb32901cff77ac9bc0edfa1b2e81a739cc5cd3990896759f94/pycrdt-0.12.50-cp313-cp313-win_amd64.whl", hash = "sha256:96db3bff011f0f85e2c95ad3337abf9553dc08d2cafb2bba6ee4b30b53a585d0", size = 748447, upload-time = "2026-03-16T09:38:37.483Z" }, + { url = "https://files.pythonhosted.org/packages/f7/5d/ae92c859ec5ee4f63d2df3702ce7a782cb054d1cef9a72d17b15a0f787f9/pycrdt-0.12.50-cp314-cp314-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl", hash = "sha256:382cf259b848db979f2cc8f37c8b1c20c46de8df10142383e8502c8eb40589ba", size = 1720667, upload-time = "2026-03-16T09:38:39.222Z" }, + { url = "https://files.pythonhosted.org/packages/f9/d7/03d5a6d806eec5cc880d17d88a2f8868bd3ddf20aea988ce9238d433cfb4/pycrdt-0.12.50-cp314-cp314-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:022450e769b8ec37027504602f3dcfc4171d0d27ebe0f04c28d9eb5a3641fdff", size = 946541, upload-time = "2026-03-16T09:38:40.918Z" }, + { url = "https://files.pythonhosted.org/packages/9a/af/4700d71886afeb406b5b6d16d36dbd15fd0d3caa37af60894aca75dc8f3e/pycrdt-0.12.50-cp314-cp314-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:41c5470f1fe5426e81986664e786508935d00050f061a5eb341af596c67c0bc7", size = 960844, upload-time = "2026-03-16T09:38:42.605Z" }, + { url = "https://files.pythonhosted.org/packages/e9/95/b3640697e6e7dd6675e8fb41c95fba89d84cf435249ed0b8c310ae7eaa10/pycrdt-0.12.50-cp314-cp314-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:bccb80466c7bcaafa1591cdd44b4f4302993324dd09b16a1c4b05f6153a0a458", size = 1136447, upload-time = "2026-03-16T09:38:44.254Z" }, + { url = "https://files.pythonhosted.org/packages/f8/50/fec4bf7fdd8b82e295be28c890a856a2d80e94d4d49098e660bb2c4520bd/pycrdt-0.12.50-cp314-cp314-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b7b2061ad56d4305fce05ddfa269a662e1137997494f74f3f0633052f8beccd4", size = 986746, upload-time = "2026-03-16T09:38:45.88Z" }, + { url = "https://files.pythonhosted.org/packages/70/40/3f82b3bc35adc4ad194a2a397d0518892516e2c40663035401eca05d9bec/pycrdt-0.12.50-cp314-cp314-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0b1d6a3aa808e3996cec15c2ec7d1613c39d872627eb1953877d21720e91b002", size = 957198, upload-time = "2026-03-16T09:38:47.609Z" }, + { url = "https://files.pythonhosted.org/packages/5e/5c/dfd19e979812e455add5942857a08ce2c28547fb68824dda44d4eb83c08b/pycrdt-0.12.50-cp314-cp314-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:8ba83048dc394e8c0d0edf5fdee073eba5d566f372bd3cc24dc8f0f4c24a36d4", size = 1048567, upload-time = "2026-03-16T09:38:49.882Z" }, + { url = "https://files.pythonhosted.org/packages/ac/02/153f511fb0f0dd32d889aede169ea0eda52d62935728b685b6815425ce9d/pycrdt-0.12.50-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:8fbf1f7b6c8200193b602ed3307b526a9cf3db7acb63191632f77d071fb595ec", size = 1122383, upload-time = "2026-03-16T09:38:51.581Z" }, + { url = "https://files.pythonhosted.org/packages/ea/fa/3fcdb4502ced4b7795516acbb12997ec7aaf726187e360494182f533a1a1/pycrdt-0.12.50-cp314-cp314-musllinux_1_2_armv7l.whl", hash = "sha256:6776ad64c8a6b270683cdecd1327289587160228401af454f570a9d971eec9a3", size = 1235274, upload-time = "2026-03-16T09:38:53.598Z" }, + { url = "https://files.pythonhosted.org/packages/69/e9/1a50a55b2b2424646e61b648a1bee42f73c1830479cb8095df428bb56b2a/pycrdt-0.12.50-cp314-cp314-musllinux_1_2_i686.whl", hash = "sha256:f4218a1e568f9b33fd676adc1d3a92fdf4c1c5b6ec3c885f227db7b7fb680b3b", size = 1224841, upload-time = "2026-03-16T09:38:55.528Z" }, + { url = "https://files.pythonhosted.org/packages/a4/62/bd919a4cf7265b4b01c2365820a5423dbe9744880a83a680339a1bf34875/pycrdt-0.12.50-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:cde948e70e3e246638e5cd8b0156c714961fba41cd44374e7c5066e797e8ec3f", size = 1168590, upload-time = "2026-03-16T09:38:57.478Z" }, + { url = "https://files.pythonhosted.org/packages/d0/b3/d0b97dbaf7c60c6e3f6d5c9ae2cd8cca3655d8fa397c41c24c44d92dc8d2/pycrdt-0.12.50-cp314-cp314-win32.whl", hash = "sha256:1d42d7f29c1e8459cd80aefd37595e8c7062817f48c59c5e5568401527718d19", size = 694709, upload-time = "2026-03-16T09:38:59.68Z" }, + { url = "https://files.pythonhosted.org/packages/72/fc/acdb8c238f9f4a6c2757b7c2cfdb39aa3c779ac465e0b6c6862c564e6350/pycrdt-0.12.50-cp314-cp314-win_amd64.whl", hash = "sha256:a4d294295120e33fef32d51e1a7a92eab444d20c07d5bde55a5a75afe58a5d41", size = 747251, upload-time = "2026-03-16T09:39:01.435Z" }, +] + +[[package]] +name = "pycrdt-store" +version = "0.1.3" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "anyio" }, + { name = "pycrdt" }, + { name = "sqlite-anyio" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/35/61/dfecafdc0c23f56d5bacc67de620b77a68f86085df21a8007628d6045248/pycrdt_store-0.1.3.tar.gz", hash = "sha256:12a0e263b2c07eb18bbe7203c828b88ba953cb93094ad37d22aeb6c619df2ef0", size = 14847, upload-time = "2025-12-11T13:29:11.454Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/b9/2d/85a1b3d6e65048c0553e0d06e21b235610ff4db0ea94cbae1bd34de385d7/pycrdt_store-0.1.3-py3-none-any.whl", hash = "sha256:2e74afc856c162706d178d23d57fd3706accbe79d849e73dd413646a7025afba", size = 11948, upload-time = "2025-12-11T13:29:10.522Z" }, +] + +[[package]] +name = "pycrdt-websocket" +version = "0.16.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "anyio" }, + { name = "pycrdt" }, + { name = "pycrdt-store" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/4f/91/a412af8792af22e7e67a7424e7b6c64baada4897777fed885a2cb825155d/pycrdt_websocket-0.16.0.tar.gz", hash = "sha256:89d4d830f41028c55cc9877635f73f94f49131ca73ffac7353d0be421150d0fd", size = 23152, upload-time = "2025-06-11T07:15:54.298Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/f4/b7/a1dd4d149fa6279f321bd7dacab66ac31e728fbae175a7d75cf8211b1f30/pycrdt_websocket-0.16.0-py3-none-any.whl", hash = "sha256:4b9ffe47c40867b7e637922680e93471fd801b6e8d6c9f6aa688fd2a17351141", size = 14568, upload-time = "2025-06-11T07:15:52.364Z" }, +] + +[[package]] +name = "pydantic" +version = "2.13.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "annotated-types" }, + { name = "pydantic-core" }, + { name = "typing-extensions" }, + { name = "typing-inspection" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/84/6b/69fd5c7194b21ebde0f8637e2a4ddc766ada29d472bfa6a5ca533d79549a/pydantic-2.13.0.tar.gz", hash = "sha256:b89b575b6e670ebf6e7448c01b41b244f471edd276cd0b6fe02e7e7aca320070", size = 843468, upload-time = "2026-04-13T10:51:35.571Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/01/d7/c3a52c61f5b7be648e919005820fbac33028c6149994cd64453f49951c17/pydantic-2.13.0-py3-none-any.whl", hash = "sha256:ab0078b90da5f3e2fd2e71e3d9b457ddcb35d0350854fbda93b451e28d56baaf", size = 471872, upload-time = "2026-04-13T10:51:33.343Z" }, +] + +[[package]] +name = "pydantic-core" +version = "2.46.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "typing-extensions" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/6f/0a/9414cddf82eda3976b14048cc0fa8f5b5d1aecb0b22e1dcd2dbfe0e139b1/pydantic_core-2.46.0.tar.gz", hash = "sha256:82d2498c96be47b47e903e1378d1d0f770097ec56ea953322f39936a7cf34977", size = 471441, upload-time = "2026-04-13T09:06:33.813Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/df/05/ab3b0742bad1d51822f1af0c4232208408902bdcfc47601f3b812e09e6c2/pydantic_core-2.46.0-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:a05900c37264c070c683c650cbca8f83d7cbb549719e645fcd81a24592eac788", size = 2116814, upload-time = "2026-04-13T09:04:12.41Z" }, + { url = "https://files.pythonhosted.org/packages/98/08/30b43d9569d69094a0899a199711c43aa58fce6ce80f6a8f7693673eb995/pydantic_core-2.46.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:8de8e482fd4f1e3f36c50c6aac46d044462615d8f12cfafc6bebeaa0909eea22", size = 1951867, upload-time = "2026-04-13T09:04:02.364Z" }, + { url = "https://files.pythonhosted.org/packages/db/a0/bf9a1ba34537c2ed3872a48195291138fdec8fe26c4009776f00d63cf0c8/pydantic_core-2.46.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c525ecf8a4cdf198327b65030a7d081867ad8e60acb01a7214fff95cf9832d47", size = 1977040, upload-time = "2026-04-13T09:06:16.088Z" }, + { url = "https://files.pythonhosted.org/packages/71/70/0ba03c20e1e118219fc18c5417b008b7e880f0e3fb38560ec4465984d471/pydantic_core-2.46.0-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:f14581aeb12e61542ce73b9bfef2bca5439d65d9ab3efe1a4d8e346b61838f9b", size = 2055284, upload-time = "2026-04-13T09:05:25.125Z" }, + { url = "https://files.pythonhosted.org/packages/58/cf/1e320acefbde7fb7158a9e5def55e0adf9a4634636098ce28dc6b978e0d3/pydantic_core-2.46.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c108067f2f7e190d0dbd81247d789ec41f9ea50ccd9265a3a46710796ac60530", size = 2238896, upload-time = "2026-04-13T09:05:01.345Z" }, + { url = "https://files.pythonhosted.org/packages/df/f5/ea8ba209756abe9eba891bb0ef3772b4c59a894eb9ad86cd5bd0dd4e3e52/pydantic_core-2.46.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1ac10967e9a7bb1b96697374513f9a1a90a59e2fb41566b5e00ee45392beac59", size = 2314353, upload-time = "2026-04-13T09:06:07.942Z" }, + { url = "https://files.pythonhosted.org/packages/e8/f8/5885350203b72e96438eee7f94de0d8f0442f4627237ca8ef75de34db1cd/pydantic_core-2.46.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7897078fe8a13b73623c0955dfb2b3d2c9acb7177aac25144758c9e5a5265aaa", size = 2098522, upload-time = "2026-04-13T09:04:23.239Z" }, + { url = "https://files.pythonhosted.org/packages/bf/88/5930b0e828e371db5a556dd3189565417ddc3d8316bb001058168aadcf5f/pydantic_core-2.46.0-cp313-cp313-manylinux_2_31_riscv64.whl", hash = "sha256:e69ce405510a419a082a78faed65bb4249cfb51232293cc675645c12f7379bf7", size = 2168757, upload-time = "2026-04-13T09:07:12.46Z" }, + { url = "https://files.pythonhosted.org/packages/da/75/63d563d3035a0548e721c38b5b69fd5626fdd51da0f09ff4467503915b82/pydantic_core-2.46.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:fd28d13eea0d8cf351dc1fe274b5070cc8e1cca2644381dee5f99de629e77cf3", size = 2202518, upload-time = "2026-04-13T09:05:44.418Z" }, + { url = "https://files.pythonhosted.org/packages/a7/53/1958eacbfddc41aadf5ae86dd85041bf054b675f34a2fa76385935f96070/pydantic_core-2.46.0-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:ee1547a6b8243e73dd10f585555e5a263395e55ce6dea618a078570a1e889aef", size = 2190148, upload-time = "2026-04-13T09:06:56.151Z" }, + { url = "https://files.pythonhosted.org/packages/c7/17/098cc6d3595e4623186f2bc6604a6195eb182e126702a90517236391e9ce/pydantic_core-2.46.0-cp313-cp313-musllinux_1_1_armv7l.whl", hash = "sha256:c3dc68dcf62db22a18ddfc3ad4960038f72b75908edc48ae014d7ac8b391d57a", size = 2342925, upload-time = "2026-04-13T09:04:17.286Z" }, + { url = "https://files.pythonhosted.org/packages/71/a7/abdb924620b1ac535c690b36ad5b8871f376104090f8842c08625cecf1d3/pydantic_core-2.46.0-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:004a2081c881abfcc6854a4623da6a09090a0d7c1398a6ae7133ca1256cee70b", size = 2383167, upload-time = "2026-04-13T09:04:52.643Z" }, + { url = "https://files.pythonhosted.org/packages/d7/c9/2ddd10f50e4b7350d2574629a0f53d8d4eb6573f9c19a6b43e6b1487a31d/pydantic_core-2.46.0-cp313-cp313-win32.whl", hash = "sha256:59d24ec8d5eaabad93097525a69d0f00f2667cb353eb6cda578b1cfff203ceef", size = 1965660, upload-time = "2026-04-13T09:06:05.877Z" }, + { url = "https://files.pythonhosted.org/packages/b5/e7/1efc38ed6f2680c032bcefa0e3ebd496a8c77e92dfdb86b07d0f2fc632b1/pydantic_core-2.46.0-cp313-cp313-win_amd64.whl", hash = "sha256:71186dad5ac325c64d68fe0e654e15fd79802e7cc42bc6f0ff822d5ad8b1ab25", size = 2069563, upload-time = "2026-04-13T09:07:14.738Z" }, + { url = "https://files.pythonhosted.org/packages/c3/1e/a325b4989e742bf7e72ed35fa124bc611fd76539c9f8cd2a9a7854473533/pydantic_core-2.46.0-cp313-cp313-win_arm64.whl", hash = "sha256:8e4503f3213f723842c9a3b53955c88a9cfbd0b288cbd1c1ae933aebeec4a1b4", size = 2034966, upload-time = "2026-04-13T09:04:21.629Z" }, + { url = "https://files.pythonhosted.org/packages/36/3b/914891d384cdbf9a6f464eb13713baa22ea1e453d4da80fb7da522079370/pydantic_core-2.46.0-cp314-cp314-macosx_10_12_x86_64.whl", hash = "sha256:4fc801c290342350ffc82d77872054a934b2e24163727263362170c1db5416ca", size = 2113349, upload-time = "2026-04-13T09:04:59.407Z" }, + { url = "https://files.pythonhosted.org/packages/35/95/3a0c6f65e231709fb3463e32943c69d10285cb50203a2130a4732053a06d/pydantic_core-2.46.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:0a36f2cc88170cc177930afcc633a8c15907ea68b59ac16bd180c2999d714940", size = 1949170, upload-time = "2026-04-13T09:06:09.935Z" }, + { url = "https://files.pythonhosted.org/packages/d1/63/d845c36a608469fe7bee226edeff0984c33dbfe7aecd755b0e7ab5a275c4/pydantic_core-2.46.0-cp314-cp314-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2a3912e0c568a1f99d4d6d3e41def40179d61424c0ca1c8c87c4877d7f6fd7fb", size = 1977914, upload-time = "2026-04-13T09:04:56.16Z" }, + { url = "https://files.pythonhosted.org/packages/08/6f/f2e7a7f85931fb31671f5378d1c7fc70606e4b36d59b1b48e1bd1ef5d916/pydantic_core-2.46.0-cp314-cp314-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:3534c3415ed1a19ab23096b628916a827f7858ec8db49ad5d7d1e44dc13c0d7b", size = 2050538, upload-time = "2026-04-13T09:05:06.789Z" }, + { url = "https://files.pythonhosted.org/packages/8c/97/f4aa7181dd9a16dd9059a99fc48fdab0c2aab68307283a5c04cf56de68c4/pydantic_core-2.46.0-cp314-cp314-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:21067396fc285609323a4db2f63a87570044abe0acddfcca8b135fc7948e3db7", size = 2236294, upload-time = "2026-04-13T09:07:03.2Z" }, + { url = "https://files.pythonhosted.org/packages/24/c1/6a5042fc32765c87101b500f394702890af04239c318b6002cfd627b710d/pydantic_core-2.46.0-cp314-cp314-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2afd85b7be186e2fe7cdbb09a3d964bcc2042f65bbcc64ad800b3c7915032655", size = 2312954, upload-time = "2026-04-13T09:06:11.919Z" }, + { url = "https://files.pythonhosted.org/packages/cb/e4/566101a561492ce8454f0844ca29c3b675a6b3a7b3ff577db85ed05c8c50/pydantic_core-2.46.0-cp314-cp314-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:67e2c2e171b78db8154da602de72ffdc473c6ee51de8a9d80c0f1cd4051abfc7", size = 2102533, upload-time = "2026-04-13T09:06:58.664Z" }, + { url = "https://files.pythonhosted.org/packages/3e/ac/adc11ee1646a5c4dd9abb09a00e7909e6dc25beddc0b1310ca734bb9b48e/pydantic_core-2.46.0-cp314-cp314-manylinux_2_31_riscv64.whl", hash = "sha256:c16ae1f3170267b1a37e16dba5c297bdf60c8b5657b147909ca8774ce7366644", size = 2169447, upload-time = "2026-04-13T09:04:11.143Z" }, + { url = "https://files.pythonhosted.org/packages/26/73/408e686b45b82d28ac19e8229e07282254dbee6a5d24c5c7cf3cf3716613/pydantic_core-2.46.0-cp314-cp314-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:133b69e1c1ba34d3702eed73f19f7f966928f9aa16663b55c2ebce0893cca42e", size = 2200672, upload-time = "2026-04-13T09:03:54.056Z" }, + { url = "https://files.pythonhosted.org/packages/0a/3b/807d5b035ec891b57b9079ce881f48263936c37bd0d154a056e7fd152afb/pydantic_core-2.46.0-cp314-cp314-musllinux_1_1_aarch64.whl", hash = "sha256:15ed8e5bde505133d96b41702f31f06829c46b05488211a5b1c7877e11de5eb5", size = 2188293, upload-time = "2026-04-13T09:07:07.614Z" }, + { url = "https://files.pythonhosted.org/packages/f1/ed/719b307516285099d1196c52769fdbe676fd677da007b9c349ae70b7226d/pydantic_core-2.46.0-cp314-cp314-musllinux_1_1_armv7l.whl", hash = "sha256:8cfc29a1c66a7f0fcb36262e92f353dd0b9c4061d558fceb022e698a801cb8ae", size = 2335023, upload-time = "2026-04-13T09:04:05.176Z" }, + { url = "https://files.pythonhosted.org/packages/8d/90/8718e4ae98c4e8a7325afdc079be82be1e131d7a47cb6c098844a9531ffe/pydantic_core-2.46.0-cp314-cp314-musllinux_1_1_x86_64.whl", hash = "sha256:e1155708540f13845bf68d5ac511a55c76cfe2e057ed12b4bf3adac1581fc5c2", size = 2377155, upload-time = "2026-04-13T09:06:18.081Z" }, + { url = "https://files.pythonhosted.org/packages/dd/dc/7172789283b963f81da2fc92b186e22de55687019079f71c4d570822502b/pydantic_core-2.46.0-cp314-cp314-win32.whl", hash = "sha256:de5635a48df6b2eef161d10ea1bc2626153197333662ba4cd700ee7ec1aba7f5", size = 1963078, upload-time = "2026-04-13T09:05:30.615Z" }, + { url = "https://files.pythonhosted.org/packages/e0/69/03a7ea4b6264def3a44eabf577528bcec2f49468c5698b2044dea54dc07e/pydantic_core-2.46.0-cp314-cp314-win_amd64.whl", hash = "sha256:f07a5af60c5e7cf53dd1ff734228bd72d0dc9938e64a75b5bb308ca350d9681e", size = 2068439, upload-time = "2026-04-13T09:04:57.729Z" }, + { url = "https://files.pythonhosted.org/packages/f5/eb/1c3afcfdee2ab6634b802ab0a0f1966df4c8b630028ec56a1cb0a710dc58/pydantic_core-2.46.0-cp314-cp314-win_arm64.whl", hash = "sha256:e7a77eca3c7d5108ff509db20aae6f80d47c7ed7516d8b96c387aacc42f3ce0f", size = 2026470, upload-time = "2026-04-13T09:05:08.654Z" }, + { url = "https://files.pythonhosted.org/packages/5c/30/1177dde61b200785c4739665e3aa03a9d4b2c25d2d0408b07d585e633965/pydantic_core-2.46.0-cp314-cp314t-macosx_10_12_x86_64.whl", hash = "sha256:5e7cdd4398bee1aaeafe049ac366b0f887451d9ae418fd8785219c13fea2f928", size = 2107447, upload-time = "2026-04-13T09:05:46.314Z" }, + { url = "https://files.pythonhosted.org/packages/b1/60/4e0f61f99bdabbbc309d364a2791e1ba31e778a4935bc43391a7bdec0744/pydantic_core-2.46.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:5c2c92d82808e27cef3f7ab3ed63d657d0c755e0dbe5b8a58342e37bdf09bd2e", size = 1926927, upload-time = "2026-04-13T09:06:20.371Z" }, + { url = "https://files.pythonhosted.org/packages/1d/d0/67f89a8269152c1d6eaa81f04e75a507372ebd8ca7382855a065222caa80/pydantic_core-2.46.0-cp314-cp314t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0bab80af91cd7014b45d1089303b5f844a9d91d7da60eabf3d5f9694b32a6655", size = 1966613, upload-time = "2026-04-13T09:07:05.389Z" }, + { url = "https://files.pythonhosted.org/packages/cd/07/8dfdc3edc78f29a80fb31f366c50203ec904cff6a4c923599bf50ac0d0ff/pydantic_core-2.46.0-cp314-cp314t-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:1e49ffdb714bc990f00b39d1ad1d683033875b5af15582f60c1f34ad3eeccfaa", size = 2032902, upload-time = "2026-04-13T09:06:42.47Z" }, + { url = "https://files.pythonhosted.org/packages/b0/2a/111c5e8fe24f99c46bcad7d3a82a8f6dbc738066e2c72c04c71f827d8c78/pydantic_core-2.46.0-cp314-cp314t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ca877240e8dbdeef3a66f751dc41e5a74893767d510c22a22fc5c0199844f0ce", size = 2244456, upload-time = "2026-04-13T09:05:36.484Z" }, + { url = "https://files.pythonhosted.org/packages/6b/7c/cfc5d11c15a63ece26e148572c77cfbb2c7f08d315a7b63ef0fe0711d753/pydantic_core-2.46.0-cp314-cp314t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:87e6843f89ecd2f596d7294e33196c61343186255b9880c4f1b725fde8b0e20d", size = 2294535, upload-time = "2026-04-13T09:06:01.689Z" }, + { url = "https://files.pythonhosted.org/packages/c4/2c/f0d744e3dab7bd026a3f4670a97a295157cff923a2666d30a15a70a7e3d0/pydantic_core-2.46.0-cp314-cp314t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e20bc5add1dd9bc3b9a3600d40632e679376569098345500799a6ad7c5d46c72", size = 2104621, upload-time = "2026-04-13T09:04:34.388Z" }, + { url = "https://files.pythonhosted.org/packages/a7/64/e7cc4698dc024264d214b51d5a47a2404221b12060dd537d76f831b2120a/pydantic_core-2.46.0-cp314-cp314t-manylinux_2_31_riscv64.whl", hash = "sha256:ee6ff79a5f0289d64a9d6696a3ce1f98f925b803dd538335a118231e26d6d827", size = 2130718, upload-time = "2026-04-13T09:04:26.23Z" }, + { url = "https://files.pythonhosted.org/packages/0b/a8/224e655fec21f7d4441438ad2ecaccb33b5a3876ce7bb2098c74a49efc14/pydantic_core-2.46.0-cp314-cp314t-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:52d35cfb58c26323101c7065508d7bb69bb56338cda9ea47a7b32be581af055d", size = 2180738, upload-time = "2026-04-13T09:05:50.253Z" }, + { url = "https://files.pythonhosted.org/packages/32/7b/b3025618ed4c4e4cbaa9882731c19625db6669896b621760ea95bc1125ef/pydantic_core-2.46.0-cp314-cp314t-musllinux_1_1_aarch64.whl", hash = "sha256:d14cc5a6f260fa78e124061eebc5769af6534fc837e9a62a47f09a2c341fa4ea", size = 2171222, upload-time = "2026-04-13T09:07:29.929Z" }, + { url = "https://files.pythonhosted.org/packages/7b/e3/68170aa1d891920af09c1f2f34df61dc5ff3a746400027155523e3400e89/pydantic_core-2.46.0-cp314-cp314t-musllinux_1_1_armv7l.whl", hash = "sha256:4f7ff859d663b6635f6307a10803d07f0d09487e16c3d36b1744af51dbf948b2", size = 2320040, upload-time = "2026-04-13T09:06:35.732Z" }, + { url = "https://files.pythonhosted.org/packages/67/1b/5e65807001b84972476300c1f49aea2b4971b7e9fffb5c2654877dadd274/pydantic_core-2.46.0-cp314-cp314t-musllinux_1_1_x86_64.whl", hash = "sha256:8ef749be6ed0d69dba31902aaa8255a9bb269ae50c93888c4df242d8bb7acd9e", size = 2377062, upload-time = "2026-04-13T09:07:39.945Z" }, + { url = "https://files.pythonhosted.org/packages/75/03/48caa9dd5f28f7662bd52bff454d9a451f6b7e5e4af95e289e5e170749c9/pydantic_core-2.46.0-cp314-cp314t-win32.whl", hash = "sha256:d93ca72870133f86360e4bb0c78cd4e6ba2a0f9f3738a6486909ffc031463b32", size = 1951028, upload-time = "2026-04-13T09:04:20.224Z" }, + { url = "https://files.pythonhosted.org/packages/87/ed/e97ff55fe28c0e6e3cba641d622b15e071370b70e5f07c496b07b65db7c9/pydantic_core-2.46.0-cp314-cp314t-win_amd64.whl", hash = "sha256:6ebb2668afd657e2127cb40f2ceb627dd78e74e9dfde14d9bf6cdd532a29ff59", size = 2048519, upload-time = "2026-04-13T09:05:10.464Z" }, + { url = "https://files.pythonhosted.org/packages/b6/51/e0db8267a287994546925f252e329eeae4121b1e77e76353418da5a3adf0/pydantic_core-2.46.0-cp314-cp314t-win_arm64.whl", hash = "sha256:4864f5bbb7993845baf9209bae1669a8a76769296a018cb569ebda9dcb4241f5", size = 2026791, upload-time = "2026-04-13T09:04:37.724Z" }, +] + +[[package]] +name = "pydantic-settings" +version = "2.13.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "pydantic" }, + { name = "python-dotenv" }, + { name = "typing-inspection" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/52/6d/fffca34caecc4a3f97bda81b2098da5e8ab7efc9a66e819074a11955d87e/pydantic_settings-2.13.1.tar.gz", hash = "sha256:b4c11847b15237fb0171e1462bf540e294affb9b86db4d9aa5c01730bdbe4025", size = 223826, upload-time = "2026-02-19T13:45:08.055Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/00/4b/ccc026168948fec4f7555b9164c724cf4125eac006e176541483d2c959be/pydantic_settings-2.13.1-py3-none-any.whl", hash = "sha256:d56fd801823dbeae7f0975e1f8c8e25c258eb75d278ea7abb5d9cebb01b56237", size = 58929, upload-time = "2026-02-19T13:45:06.034Z" }, +] + +[[package]] +name = "pygments" +version = "2.20.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/c3/b2/bc9c9196916376152d655522fdcebac55e66de6603a76a02bca1b6414f6c/pygments-2.20.0.tar.gz", hash = "sha256:6757cd03768053ff99f3039c1a36d6c0aa0b263438fcab17520b30a303a82b5f", size = 4955991, upload-time = "2026-03-29T13:29:33.898Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/f4/7e/a72dd26f3b0f4f2bf1dd8923c85f7ceb43172af56d63c7383eb62b332364/pygments-2.20.0-py3-none-any.whl", hash = "sha256:81a9e26dd42fd28a23a2d169d86d7ac03b46e2f8b59ed4698fb4785f946d0176", size = 1231151, upload-time = "2026-03-29T13:29:30.038Z" }, +] + +[[package]] +name = "pyjwt" +version = "2.12.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/c2/27/a3b6e5bf6ff856d2509292e95c8f57f0df7017cf5394921fc4e4ef40308a/pyjwt-2.12.1.tar.gz", hash = "sha256:c74a7a2adf861c04d002db713dd85f84beb242228e671280bf709d765b03672b", size = 102564, upload-time = "2026-03-13T19:27:37.25Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/e5/7a/8dd906bd22e79e47397a61742927f6747fe93242ef86645ee9092e610244/pyjwt-2.12.1-py3-none-any.whl", hash = "sha256:28ca37c070cad8ba8cd9790cd940535d40274d22f80ab87f3ac6a713e6e8454c", size = 29726, upload-time = "2026-03-13T19:27:35.677Z" }, +] + +[package.optional-dependencies] +crypto = [ + { name = "cryptography" }, +] + +[[package]] +name = "pyparsing" +version = "3.3.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/f3/91/9c6ee907786a473bf81c5f53cf703ba0957b23ab84c264080fb5a450416f/pyparsing-3.3.2.tar.gz", hash = "sha256:c777f4d763f140633dcb6d8a3eda953bf7a214dc4eff598413c070bcdc117cbc", size = 6851574, upload-time = "2026-01-21T03:57:59.36Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/10/bd/c038d7cc38edc1aa5bf91ab8068b63d4308c66c4c8bb3cbba7dfbc049f9c/pyparsing-3.3.2-py3-none-any.whl", hash = "sha256:850ba148bd908d7e2411587e247a1e4f0327839c40e2e5e6d05a007ecc69911d", size = 122781, upload-time = "2026-01-21T03:57:55.912Z" }, +] + +[[package]] +name = "python-dateutil" +version = "2.9.0.post0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "six" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/66/c0/0c8b6ad9f17a802ee498c46e004a0eb49bc148f2fd230864601a86dcf6db/python-dateutil-2.9.0.post0.tar.gz", hash = "sha256:37dd54208da7e1cd875388217d5e00ebd4179249f90fb72437e91a35459a0ad3", size = 342432, upload-time = "2024-03-01T18:36:20.211Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/ec/57/56b9bcc3c9c6a792fcbaf139543cee77261f3651ca9da0c93f5c1221264b/python_dateutil-2.9.0.post0-py2.py3-none-any.whl", hash = "sha256:a8b2bc7bffae282281c8140a97d3aa9c14da0b136dfe83f850eea9a5f7470427", size = 229892, upload-time = "2024-03-01T18:36:18.57Z" }, +] + +[[package]] +name = "python-dotenv" +version = "1.2.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/82/ed/0301aeeac3e5353ef3d94b6ec08bbcabd04a72018415dcb29e588514bba8/python_dotenv-1.2.2.tar.gz", hash = "sha256:2c371a91fbd7ba082c2c1dc1f8bf89ca22564a087c2c287cd9b662adde799cf3", size = 50135, upload-time = "2026-03-01T16:00:26.196Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/0b/d7/1959b9648791274998a9c3526f6d0ec8fd2233e4d4acce81bbae76b44b2a/python_dotenv-1.2.2-py3-none-any.whl", hash = "sha256:1d8214789a24de455a8b8bd8ae6fe3c6b69a5e3d64aa8a8e5d68e694bbcb285a", size = 22101, upload-time = "2026-03-01T16:00:25.09Z" }, +] + +[[package]] +name = "python-json-logger" +version = "4.1.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/f7/ff/3cc9165fd44106973cd7ac9facb674a65ed853494592541d339bdc9a30eb/python_json_logger-4.1.0.tar.gz", hash = "sha256:b396b9e3ed782b09ff9d6e4f1683d46c83ad0d35d2e407c09a9ebbf038f88195", size = 17573, upload-time = "2026-03-29T04:39:56.805Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/27/be/0631a861af4d1c875f096c07d34e9a63639560a717130e7a87cbc82b7e3f/python_json_logger-4.1.0-py3-none-any.whl", hash = "sha256:132994765cf75bf44554be9aa49b06ef2345d23661a96720262716438141b6b2", size = 15021, upload-time = "2026-03-29T04:39:55.266Z" }, +] + +[[package]] +name = "python-multipart" +version = "0.0.26" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/88/71/b145a380824a960ebd60e1014256dbb7d2253f2316ff2d73dfd8928ec2c3/python_multipart-0.0.26.tar.gz", hash = "sha256:08fadc45918cd615e26846437f50c5d6d23304da32c341f289a617127b081f17", size = 43501, upload-time = "2026-04-10T14:09:59.473Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/9a/22/f1925cdda983ab66fc8ec6ec8014b959262747e58bdca26a4e3d1da29d56/python_multipart-0.0.26-py3-none-any.whl", hash = "sha256:c0b169f8c4484c13b0dcf2ef0ec3a4adb255c4b7d18d8e420477d2b1dd03f185", size = 28847, upload-time = "2026-04-10T14:09:58.131Z" }, +] + +[[package]] +name = "pywin32" +version = "311" +source = { registry = "https://pypi.org/simple" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/a5/be/3fd5de0979fcb3994bfee0d65ed8ca9506a8a1260651b86174f6a86f52b3/pywin32-311-cp313-cp313-win32.whl", hash = "sha256:f95ba5a847cba10dd8c4d8fefa9f2a6cf283b8b88ed6178fa8a6c1ab16054d0d", size = 8705700, upload-time = "2025-07-14T20:13:26.471Z" }, + { url = "https://files.pythonhosted.org/packages/e3/28/e0a1909523c6890208295a29e05c2adb2126364e289826c0a8bc7297bd5c/pywin32-311-cp313-cp313-win_amd64.whl", hash = "sha256:718a38f7e5b058e76aee1c56ddd06908116d35147e133427e59a3983f703a20d", size = 9494700, upload-time = "2025-07-14T20:13:28.243Z" }, + { url = "https://files.pythonhosted.org/packages/04/bf/90339ac0f55726dce7d794e6d79a18a91265bdf3aa70b6b9ca52f35e022a/pywin32-311-cp313-cp313-win_arm64.whl", hash = "sha256:7b4075d959648406202d92a2310cb990fea19b535c7f4a78d3f5e10b926eeb8a", size = 8709318, upload-time = "2025-07-14T20:13:30.348Z" }, + { url = "https://files.pythonhosted.org/packages/c9/31/097f2e132c4f16d99a22bfb777e0fd88bd8e1c634304e102f313af69ace5/pywin32-311-cp314-cp314-win32.whl", hash = "sha256:b7a2c10b93f8986666d0c803ee19b5990885872a7de910fc460f9b0c2fbf92ee", size = 8840714, upload-time = "2025-07-14T20:13:32.449Z" }, + { url = "https://files.pythonhosted.org/packages/90/4b/07c77d8ba0e01349358082713400435347df8426208171ce297da32c313d/pywin32-311-cp314-cp314-win_amd64.whl", hash = "sha256:3aca44c046bd2ed8c90de9cb8427f581c479e594e99b5c0bb19b29c10fd6cb87", size = 9656800, upload-time = "2025-07-14T20:13:34.312Z" }, + { url = "https://files.pythonhosted.org/packages/c0/d2/21af5c535501a7233e734b8af901574572da66fcc254cb35d0609c9080dd/pywin32-311-cp314-cp314-win_arm64.whl", hash = "sha256:a508e2d9025764a8270f93111a970e1d0fbfc33f4153b388bb649b7eec4f9b42", size = 8932540, upload-time = "2025-07-14T20:13:36.379Z" }, +] + +[[package]] +name = "pywinpty" +version = "3.0.3" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/f7/54/37c7370ba91f579235049dc26cd2c5e657d2a943e01820844ffc81f32176/pywinpty-3.0.3.tar.gz", hash = "sha256:523441dc34d231fb361b4b00f8c99d3f16de02f5005fd544a0183112bcc22412", size = 31309, upload-time = "2026-02-04T21:51:09.524Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/e5/cb/58d6ed3fd429c96a90ef01ac9a617af10a6d41469219c25e7dc162abbb71/pywinpty-3.0.3-cp313-cp313-win_amd64.whl", hash = "sha256:9c91dbb026050c77bdcef964e63a4f10f01a639113c4d3658332614544c467ab", size = 2112686, upload-time = "2026-02-04T21:52:03.035Z" }, + { url = "https://files.pythonhosted.org/packages/fd/50/724ed5c38c504d4e58a88a072776a1e880d970789deaeb2b9f7bd9a5141a/pywinpty-3.0.3-cp313-cp313-win_arm64.whl", hash = "sha256:fe1f7911805127c94cf51f89ab14096c6f91ffdcacf993d2da6082b2142a2523", size = 234591, upload-time = "2026-02-04T21:52:29.821Z" }, + { url = "https://files.pythonhosted.org/packages/f7/ad/90a110538696b12b39fd8758a06d70ded899308198ad2305ac68e361126e/pywinpty-3.0.3-cp313-cp313t-win_amd64.whl", hash = "sha256:3f07a6cf1c1d470d284e614733c3d0f726d2c85e78508ea10a403140c3c0c18a", size = 2112360, upload-time = "2026-02-04T21:55:33.397Z" }, + { url = "https://files.pythonhosted.org/packages/44/0f/7ffa221757a220402bc79fda44044c3f2cc57338d878ab7d622add6f4581/pywinpty-3.0.3-cp313-cp313t-win_arm64.whl", hash = "sha256:15c7c0b6f8e9d87aabbaff76468dabf6e6121332c40fc1d83548d02a9d6a3759", size = 233107, upload-time = "2026-02-04T21:51:45.455Z" }, + { url = "https://files.pythonhosted.org/packages/28/88/2ff917caff61e55f38bcdb27de06ee30597881b2cae44fbba7627be015c4/pywinpty-3.0.3-cp314-cp314-win_amd64.whl", hash = "sha256:d4b6b7b0fe0cdcd02e956bd57cfe9f4e5a06514eecf3b5ae174da4f951b58be9", size = 2113282, upload-time = "2026-02-04T21:52:08.188Z" }, + { url = "https://files.pythonhosted.org/packages/63/32/40a775343ace542cc43ece3f1d1fce454021521ecac41c4c4573081c2336/pywinpty-3.0.3-cp314-cp314-win_arm64.whl", hash = "sha256:34789d685fc0d547ce0c8a65e5a70e56f77d732fa6e03c8f74fefb8cbb252019", size = 234207, upload-time = "2026-02-04T21:51:58.687Z" }, + { url = "https://files.pythonhosted.org/packages/8d/54/5d5e52f4cb75028104ca6faf36c10f9692389b1986d34471663b4ebebd6d/pywinpty-3.0.3-cp314-cp314t-win_amd64.whl", hash = "sha256:0c37e224a47a971d1a6e08649a1714dac4f63c11920780977829ed5c8cadead1", size = 2112910, upload-time = "2026-02-04T21:52:30.976Z" }, + { url = "https://files.pythonhosted.org/packages/0a/44/dcd184824e21d4620b06c7db9fbb15c3ad0a0f1fa2e6de79969fb82647ec/pywinpty-3.0.3-cp314-cp314t-win_arm64.whl", hash = "sha256:c4e9c3dff7d86ba81937438d5819f19f385a39d8f592d4e8af67148ceb4f6ab5", size = 233425, upload-time = "2026-02-04T21:51:56.754Z" }, +] + +[[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" }, +] + +[[package]] +name = "pyzmq" +version = "27.1.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "cffi", marker = "implementation_name == 'pypy'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/04/0b/3c9baedbdf613ecaa7aa07027780b8867f57b6293b6ee50de316c9f3222b/pyzmq-27.1.0.tar.gz", hash = "sha256:ac0765e3d44455adb6ddbf4417dcce460fc40a05978c08efdf2948072f6db540", size = 281750, upload-time = "2025-09-08T23:10:18.157Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/92/e7/038aab64a946d535901103da16b953c8c9cc9c961dadcbf3609ed6428d23/pyzmq-27.1.0-cp312-abi3-macosx_10_15_universal2.whl", hash = "sha256:452631b640340c928fa343801b0d07eb0c3789a5ffa843f6e1a9cee0ba4eb4fc", size = 1306279, upload-time = "2025-09-08T23:08:03.807Z" }, + { url = "https://files.pythonhosted.org/packages/e8/5e/c3c49fdd0f535ef45eefcc16934648e9e59dace4a37ee88fc53f6cd8e641/pyzmq-27.1.0-cp312-abi3-manylinux2014_i686.manylinux_2_17_i686.whl", hash = "sha256:1c179799b118e554b66da67d88ed66cd37a169f1f23b5d9f0a231b4e8d44a113", size = 895645, upload-time = "2025-09-08T23:08:05.301Z" }, + { url = "https://files.pythonhosted.org/packages/f8/e5/b0b2504cb4e903a74dcf1ebae157f9e20ebb6ea76095f6cfffea28c42ecd/pyzmq-27.1.0-cp312-abi3-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:3837439b7f99e60312f0c926a6ad437b067356dc2bc2ec96eb395fd0fe804233", size = 652574, upload-time = "2025-09-08T23:08:06.828Z" }, + { url = "https://files.pythonhosted.org/packages/f8/9b/c108cdb55560eaf253f0cbdb61b29971e9fb34d9c3499b0e96e4e60ed8a5/pyzmq-27.1.0-cp312-abi3-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:43ad9a73e3da1fab5b0e7e13402f0b2fb934ae1c876c51d0afff0e7c052eca31", size = 840995, upload-time = "2025-09-08T23:08:08.396Z" }, + { url = "https://files.pythonhosted.org/packages/c2/bb/b79798ca177b9eb0825b4c9998c6af8cd2a7f15a6a1a4272c1d1a21d382f/pyzmq-27.1.0-cp312-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:0de3028d69d4cdc475bfe47a6128eb38d8bc0e8f4d69646adfbcd840facbac28", size = 1642070, upload-time = "2025-09-08T23:08:09.989Z" }, + { url = "https://files.pythonhosted.org/packages/9c/80/2df2e7977c4ede24c79ae39dcef3899bfc5f34d1ca7a5b24f182c9b7a9ca/pyzmq-27.1.0-cp312-abi3-musllinux_1_2_i686.whl", hash = "sha256:cf44a7763aea9298c0aa7dbf859f87ed7012de8bda0f3977b6fb1d96745df856", size = 2021121, upload-time = "2025-09-08T23:08:11.907Z" }, + { url = "https://files.pythonhosted.org/packages/46/bd/2d45ad24f5f5ae7e8d01525eb76786fa7557136555cac7d929880519e33a/pyzmq-27.1.0-cp312-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:f30f395a9e6fbca195400ce833c731e7b64c3919aa481af4d88c3759e0cb7496", size = 1878550, upload-time = "2025-09-08T23:08:13.513Z" }, + { url = "https://files.pythonhosted.org/packages/e6/2f/104c0a3c778d7c2ab8190e9db4f62f0b6957b53c9d87db77c284b69f33ea/pyzmq-27.1.0-cp312-abi3-win32.whl", hash = "sha256:250e5436a4ba13885494412b3da5d518cd0d3a278a1ae640e113c073a5f88edd", size = 559184, upload-time = "2025-09-08T23:08:15.163Z" }, + { url = "https://files.pythonhosted.org/packages/fc/7f/a21b20d577e4100c6a41795842028235998a643b1ad406a6d4163ea8f53e/pyzmq-27.1.0-cp312-abi3-win_amd64.whl", hash = "sha256:9ce490cf1d2ca2ad84733aa1d69ce6855372cb5ce9223802450c9b2a7cba0ccf", size = 619480, upload-time = "2025-09-08T23:08:17.192Z" }, + { url = "https://files.pythonhosted.org/packages/78/c2/c012beae5f76b72f007a9e91ee9401cb88c51d0f83c6257a03e785c81cc2/pyzmq-27.1.0-cp312-abi3-win_arm64.whl", hash = "sha256:75a2f36223f0d535a0c919e23615fc85a1e23b71f40c7eb43d7b1dedb4d8f15f", size = 552993, upload-time = "2025-09-08T23:08:18.926Z" }, + { url = "https://files.pythonhosted.org/packages/60/cb/84a13459c51da6cec1b7b1dc1a47e6db6da50b77ad7fd9c145842750a011/pyzmq-27.1.0-cp313-cp313-android_24_arm64_v8a.whl", hash = "sha256:93ad4b0855a664229559e45c8d23797ceac03183c7b6f5b4428152a6b06684a5", size = 1122436, upload-time = "2025-09-08T23:08:20.801Z" }, + { url = "https://files.pythonhosted.org/packages/dc/b6/94414759a69a26c3dd674570a81813c46a078767d931a6c70ad29fc585cb/pyzmq-27.1.0-cp313-cp313-android_24_x86_64.whl", hash = "sha256:fbb4f2400bfda24f12f009cba62ad5734148569ff4949b1b6ec3b519444342e6", size = 1156301, upload-time = "2025-09-08T23:08:22.47Z" }, + { url = "https://files.pythonhosted.org/packages/a5/ad/15906493fd40c316377fd8a8f6b1f93104f97a752667763c9b9c1b71d42d/pyzmq-27.1.0-cp313-cp313t-macosx_10_15_universal2.whl", hash = "sha256:e343d067f7b151cfe4eb3bb796a7752c9d369eed007b91231e817071d2c2fec7", size = 1341197, upload-time = "2025-09-08T23:08:24.286Z" }, + { url = "https://files.pythonhosted.org/packages/14/1d/d343f3ce13db53a54cb8946594e567410b2125394dafcc0268d8dda027e0/pyzmq-27.1.0-cp313-cp313t-manylinux2014_i686.manylinux_2_17_i686.whl", hash = "sha256:08363b2011dec81c354d694bdecaef4770e0ae96b9afea70b3f47b973655cc05", size = 897275, upload-time = "2025-09-08T23:08:26.063Z" }, + { url = "https://files.pythonhosted.org/packages/69/2d/d83dd6d7ca929a2fc67d2c3005415cdf322af7751d773524809f9e585129/pyzmq-27.1.0-cp313-cp313t-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:d54530c8c8b5b8ddb3318f481297441af102517602b569146185fa10b63f4fa9", size = 660469, upload-time = "2025-09-08T23:08:27.623Z" }, + { url = "https://files.pythonhosted.org/packages/3e/cd/9822a7af117f4bc0f1952dbe9ef8358eb50a24928efd5edf54210b850259/pyzmq-27.1.0-cp313-cp313t-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:6f3afa12c392f0a44a2414056d730eebc33ec0926aae92b5ad5cf26ebb6cc128", size = 847961, upload-time = "2025-09-08T23:08:29.672Z" }, + { url = "https://files.pythonhosted.org/packages/9a/12/f003e824a19ed73be15542f172fd0ec4ad0b60cf37436652c93b9df7c585/pyzmq-27.1.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:c65047adafe573ff023b3187bb93faa583151627bc9c51fc4fb2c561ed689d39", size = 1650282, upload-time = "2025-09-08T23:08:31.349Z" }, + { url = "https://files.pythonhosted.org/packages/d5/4a/e82d788ed58e9a23995cee70dbc20c9aded3d13a92d30d57ec2291f1e8a3/pyzmq-27.1.0-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:90e6e9441c946a8b0a667356f7078d96411391a3b8f80980315455574177ec97", size = 2024468, upload-time = "2025-09-08T23:08:33.543Z" }, + { url = "https://files.pythonhosted.org/packages/d9/94/2da0a60841f757481e402b34bf4c8bf57fa54a5466b965de791b1e6f747d/pyzmq-27.1.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:add071b2d25f84e8189aaf0882d39a285b42fa3853016ebab234a5e78c7a43db", size = 1885394, upload-time = "2025-09-08T23:08:35.51Z" }, + { url = "https://files.pythonhosted.org/packages/4f/6f/55c10e2e49ad52d080dc24e37adb215e5b0d64990b57598abc2e3f01725b/pyzmq-27.1.0-cp313-cp313t-win32.whl", hash = "sha256:7ccc0700cfdf7bd487bea8d850ec38f204478681ea02a582a8da8171b7f90a1c", size = 574964, upload-time = "2025-09-08T23:08:37.178Z" }, + { url = "https://files.pythonhosted.org/packages/87/4d/2534970ba63dd7c522d8ca80fb92777f362c0f321900667c615e2067cb29/pyzmq-27.1.0-cp313-cp313t-win_amd64.whl", hash = "sha256:8085a9fba668216b9b4323be338ee5437a235fe275b9d1610e422ccc279733e2", size = 641029, upload-time = "2025-09-08T23:08:40.595Z" }, + { url = "https://files.pythonhosted.org/packages/f6/fa/f8aea7a28b0641f31d40dea42d7ef003fded31e184ef47db696bc74cd610/pyzmq-27.1.0-cp313-cp313t-win_arm64.whl", hash = "sha256:6bb54ca21bcfe361e445256c15eedf083f153811c37be87e0514934d6913061e", size = 561541, upload-time = "2025-09-08T23:08:42.668Z" }, + { url = "https://files.pythonhosted.org/packages/87/45/19efbb3000956e82d0331bafca5d9ac19ea2857722fa2caacefb6042f39d/pyzmq-27.1.0-cp314-cp314t-macosx_10_15_universal2.whl", hash = "sha256:ce980af330231615756acd5154f29813d553ea555485ae712c491cd483df6b7a", size = 1341197, upload-time = "2025-09-08T23:08:44.973Z" }, + { url = "https://files.pythonhosted.org/packages/48/43/d72ccdbf0d73d1343936296665826350cb1e825f92f2db9db3e61c2162a2/pyzmq-27.1.0-cp314-cp314t-manylinux2014_i686.manylinux_2_17_i686.whl", hash = "sha256:1779be8c549e54a1c38f805e56d2a2e5c009d26de10921d7d51cfd1c8d4632ea", size = 897175, upload-time = "2025-09-08T23:08:46.601Z" }, + { url = "https://files.pythonhosted.org/packages/2f/2e/a483f73a10b65a9ef0161e817321d39a770b2acf8bcf3004a28d90d14a94/pyzmq-27.1.0-cp314-cp314t-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:7200bb0f03345515df50d99d3db206a0a6bee1955fbb8c453c76f5bf0e08fb96", size = 660427, upload-time = "2025-09-08T23:08:48.187Z" }, + { url = "https://files.pythonhosted.org/packages/f5/d2/5f36552c2d3e5685abe60dfa56f91169f7a2d99bbaf67c5271022ab40863/pyzmq-27.1.0-cp314-cp314t-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:01c0e07d558b06a60773744ea6251f769cd79a41a97d11b8bf4ab8f034b0424d", size = 847929, upload-time = "2025-09-08T23:08:49.76Z" }, + { url = "https://files.pythonhosted.org/packages/c4/2a/404b331f2b7bf3198e9945f75c4c521f0c6a3a23b51f7a4a401b94a13833/pyzmq-27.1.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:80d834abee71f65253c91540445d37c4c561e293ba6e741b992f20a105d69146", size = 1650193, upload-time = "2025-09-08T23:08:51.7Z" }, + { url = "https://files.pythonhosted.org/packages/1c/0b/f4107e33f62a5acf60e3ded67ed33d79b4ce18de432625ce2fc5093d6388/pyzmq-27.1.0-cp314-cp314t-musllinux_1_2_i686.whl", hash = "sha256:544b4e3b7198dde4a62b8ff6685e9802a9a1ebf47e77478a5eb88eca2a82f2fd", size = 2024388, upload-time = "2025-09-08T23:08:53.393Z" }, + { url = "https://files.pythonhosted.org/packages/0d/01/add31fe76512642fd6e40e3a3bd21f4b47e242c8ba33efb6809e37076d9b/pyzmq-27.1.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:cedc4c68178e59a4046f97eca31b148ddcf51e88677de1ef4e78cf06c5376c9a", size = 1885316, upload-time = "2025-09-08T23:08:55.702Z" }, + { url = "https://files.pythonhosted.org/packages/c4/59/a5f38970f9bf07cee96128de79590bb354917914a9be11272cfc7ff26af0/pyzmq-27.1.0-cp314-cp314t-win32.whl", hash = "sha256:1f0b2a577fd770aa6f053211a55d1c47901f4d537389a034c690291485e5fe92", size = 587472, upload-time = "2025-09-08T23:08:58.18Z" }, + { url = "https://files.pythonhosted.org/packages/70/d8/78b1bad170f93fcf5e3536e70e8fadac55030002275c9a29e8f5719185de/pyzmq-27.1.0-cp314-cp314t-win_amd64.whl", hash = "sha256:19c9468ae0437f8074af379e986c5d3d7d7bfe033506af442e8c879732bedbe0", size = 661401, upload-time = "2025-09-08T23:08:59.802Z" }, + { url = "https://files.pythonhosted.org/packages/81/d6/4bfbb40c9a0b42fc53c7cf442f6385db70b40f74a783130c5d0a5aa62228/pyzmq-27.1.0-cp314-cp314t-win_arm64.whl", hash = "sha256:dc5dbf68a7857b59473f7df42650c621d7e8923fb03fa74a526890f4d33cc4d7", size = 575170, upload-time = "2025-09-08T23:09:01.418Z" }, +] + +[[package]] +name = "referencing" +version = "0.37.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "attrs" }, + { name = "rpds-py" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/22/f5/df4e9027acead3ecc63e50fe1e36aca1523e1719559c499951bb4b53188f/referencing-0.37.0.tar.gz", hash = "sha256:44aefc3142c5b842538163acb373e24cce6632bd54bdb01b21ad5863489f50d8", size = 78036, upload-time = "2025-10-13T15:30:48.871Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/2c/58/ca301544e1fa93ed4f80d724bf5b194f6e4b945841c5bfd555878eea9fcb/referencing-0.37.0-py3-none-any.whl", hash = "sha256:381329a9f99628c9069361716891d34ad94af76e461dcb0335825aecc7692231", size = 26766, upload-time = "2025-10-13T15:30:47.625Z" }, +] + +[[package]] +name = "requests" +version = "2.33.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "certifi" }, + { name = "charset-normalizer" }, + { name = "idna" }, + { name = "urllib3" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/5f/a4/98b9c7c6428a668bf7e42ebb7c79d576a1c3c1e3ae2d47e674b468388871/requests-2.33.1.tar.gz", hash = "sha256:18817f8c57c6263968bc123d237e3b8b08ac046f5456bd1e307ee8f4250d3517", size = 134120, upload-time = "2026-03-30T16:09:15.531Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/d7/8e/7540e8a2036f79a125c1d2ebadf69ed7901608859186c856fa0388ef4197/requests-2.33.1-py3-none-any.whl", hash = "sha256:4e6d1ef462f3626a1f0a0a9c42dd93c63bad33f9f1c1937509b8c5c8718ab56a", size = 64947, upload-time = "2026-03-30T16:09:13.83Z" }, +] + +[[package]] +name = "rfc3339-validator" +version = "0.1.4" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "six" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/28/ea/a9387748e2d111c3c2b275ba970b735e04e15cdb1eb30693b6b5708c4dbd/rfc3339_validator-0.1.4.tar.gz", hash = "sha256:138a2abdf93304ad60530167e51d2dfb9549521a836871b88d7f4695d0022f6b", size = 5513, upload-time = "2021-05-12T16:37:54.178Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/7b/44/4e421b96b67b2daff264473f7465db72fbdf36a07e05494f50300cc7b0c6/rfc3339_validator-0.1.4-py2.py3-none-any.whl", hash = "sha256:24f6ec1eda14ef823da9e36ec7113124b39c04d50a4d3d3a3c2859577e7791fa", size = 3490, upload-time = "2021-05-12T16:37:52.536Z" }, +] + +[[package]] +name = "rfc3986-validator" +version = "0.1.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/da/88/f270de456dd7d11dcc808abfa291ecdd3f45ff44e3b549ffa01b126464d0/rfc3986_validator-0.1.1.tar.gz", hash = "sha256:3d44bde7921b3b9ec3ae4e3adca370438eccebc676456449b145d533b240d055", size = 6760, upload-time = "2019-10-28T16:00:19.144Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/9e/51/17023c0f8f1869d8806b979a2bffa3f861f26a3f1a66b094288323fba52f/rfc3986_validator-0.1.1-py2.py3-none-any.whl", hash = "sha256:2f235c432ef459970b4306369336b9d5dbdda31b510ca1e327636e01f528bfa9", size = 4242, upload-time = "2019-10-28T16:00:13.976Z" }, +] + +[[package]] +name = "rfc3987-syntax" +version = "1.1.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "lark" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/2c/06/37c1a5557acf449e8e406a830a05bf885ac47d33270aec454ef78675008d/rfc3987_syntax-1.1.0.tar.gz", hash = "sha256:717a62cbf33cffdd16dfa3a497d81ce48a660ea691b1ddd7be710c22f00b4a0d", size = 14239, upload-time = "2025-07-18T01:05:05.015Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/7e/71/44ce230e1b7fadd372515a97e32a83011f906ddded8d03e3c6aafbdedbb7/rfc3987_syntax-1.1.0-py3-none-any.whl", hash = "sha256:6c3d97604e4c5ce9f714898e05401a0445a641cfa276432b0a648c80856f6a3f", size = 8046, upload-time = "2025-07-18T01:05:03.843Z" }, +] + +[[package]] +name = "rich" +version = "15.0.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "markdown-it-py" }, + { name = "pygments" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/c0/8f/0722ca900cc807c13a6a0c696dacf35430f72e0ec571c4275d2371fca3e9/rich-15.0.0.tar.gz", hash = "sha256:edd07a4824c6b40189fb7ac9bc4c52536e9780fbbfbddf6f1e2502c31b068c36", size = 230680, upload-time = "2026-04-12T08:24:00.75Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/82/3b/64d4899d73f91ba49a8c18a8ff3f0ea8f1c1d75481760df8c68ef5235bf5/rich-15.0.0-py3-none-any.whl", hash = "sha256:33bd4ef74232fb73fe9279a257718407f169c09b78a87ad3d296f548e27de0bb", size = 310654, upload-time = "2026-04-12T08:24:02.83Z" }, +] + +[[package]] +name = "rpds-py" +version = "0.30.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/20/af/3f2f423103f1113b36230496629986e0ef7e199d2aa8392452b484b38ced/rpds_py-0.30.0.tar.gz", hash = "sha256:dd8ff7cf90014af0c0f787eea34794ebf6415242ee1d6fa91eaba725cc441e84", size = 69469, upload-time = "2025-11-30T20:24:38.837Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/ed/dc/d61221eb88ff410de3c49143407f6f3147acf2538c86f2ab7ce65ae7d5f9/rpds_py-0.30.0-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:f83424d738204d9770830d35290ff3273fbb02b41f919870479fab14b9d303b2", size = 374887, upload-time = "2025-11-30T20:22:41.812Z" }, + { url = "https://files.pythonhosted.org/packages/fd/32/55fb50ae104061dbc564ef15cc43c013dc4a9f4527a1f4d99baddf56fe5f/rpds_py-0.30.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:e7536cd91353c5273434b4e003cbda89034d67e7710eab8761fd918ec6c69cf8", size = 358904, upload-time = "2025-11-30T20:22:43.479Z" }, + { url = "https://files.pythonhosted.org/packages/58/70/faed8186300e3b9bdd138d0273109784eea2396c68458ed580f885dfe7ad/rpds_py-0.30.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2771c6c15973347f50fece41fc447c054b7ac2ae0502388ce3b6738cd366e3d4", size = 389945, upload-time = "2025-11-30T20:22:44.819Z" }, + { url = "https://files.pythonhosted.org/packages/bd/a8/073cac3ed2c6387df38f71296d002ab43496a96b92c823e76f46b8af0543/rpds_py-0.30.0-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:0a59119fc6e3f460315fe9d08149f8102aa322299deaa5cab5b40092345c2136", size = 407783, upload-time = "2025-11-30T20:22:46.103Z" }, + { url = "https://files.pythonhosted.org/packages/77/57/5999eb8c58671f1c11eba084115e77a8899d6e694d2a18f69f0ba471ec8b/rpds_py-0.30.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:76fec018282b4ead0364022e3c54b60bf368b9d926877957a8624b58419169b7", size = 515021, upload-time = "2025-11-30T20:22:47.458Z" }, + { url = "https://files.pythonhosted.org/packages/e0/af/5ab4833eadc36c0a8ed2bc5c0de0493c04f6c06de223170bd0798ff98ced/rpds_py-0.30.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:692bef75a5525db97318e8cd061542b5a79812d711ea03dbc1f6f8dbb0c5f0d2", size = 414589, upload-time = "2025-11-30T20:22:48.872Z" }, + { url = "https://files.pythonhosted.org/packages/b7/de/f7192e12b21b9e9a68a6d0f249b4af3fdcdff8418be0767a627564afa1f1/rpds_py-0.30.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9027da1ce107104c50c81383cae773ef5c24d296dd11c99e2629dbd7967a20c6", size = 394025, upload-time = "2025-11-30T20:22:50.196Z" }, + { url = "https://files.pythonhosted.org/packages/91/c4/fc70cd0249496493500e7cc2de87504f5aa6509de1e88623431fec76d4b6/rpds_py-0.30.0-cp313-cp313-manylinux_2_31_riscv64.whl", hash = "sha256:9cf69cdda1f5968a30a359aba2f7f9aa648a9ce4b580d6826437f2b291cfc86e", size = 408895, upload-time = "2025-11-30T20:22:51.87Z" }, + { url = "https://files.pythonhosted.org/packages/58/95/d9275b05ab96556fefff73a385813eb66032e4c99f411d0795372d9abcea/rpds_py-0.30.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:a4796a717bf12b9da9d3ad002519a86063dcac8988b030e405704ef7d74d2d9d", size = 422799, upload-time = "2025-11-30T20:22:53.341Z" }, + { url = "https://files.pythonhosted.org/packages/06/c1/3088fc04b6624eb12a57eb814f0d4997a44b0d208d6cace713033ff1a6ba/rpds_py-0.30.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:5d4c2aa7c50ad4728a094ebd5eb46c452e9cb7edbfdb18f9e1221f597a73e1e7", size = 572731, upload-time = "2025-11-30T20:22:54.778Z" }, + { url = "https://files.pythonhosted.org/packages/d8/42/c612a833183b39774e8ac8fecae81263a68b9583ee343db33ab571a7ce55/rpds_py-0.30.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:ba81a9203d07805435eb06f536d95a266c21e5b2dfbf6517748ca40c98d19e31", size = 599027, upload-time = "2025-11-30T20:22:56.212Z" }, + { url = "https://files.pythonhosted.org/packages/5f/60/525a50f45b01d70005403ae0e25f43c0384369ad24ffe46e8d9068b50086/rpds_py-0.30.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:945dccface01af02675628334f7cf49c2af4c1c904748efc5cf7bbdf0b579f95", size = 563020, upload-time = "2025-11-30T20:22:58.2Z" }, + { url = "https://files.pythonhosted.org/packages/0b/5d/47c4655e9bcd5ca907148535c10e7d489044243cc9941c16ed7cd53be91d/rpds_py-0.30.0-cp313-cp313-win32.whl", hash = "sha256:b40fb160a2db369a194cb27943582b38f79fc4887291417685f3ad693c5a1d5d", size = 223139, upload-time = "2025-11-30T20:23:00.209Z" }, + { url = "https://files.pythonhosted.org/packages/f2/e1/485132437d20aa4d3e1d8b3fb5a5e65aa8139f1e097080c2a8443201742c/rpds_py-0.30.0-cp313-cp313-win_amd64.whl", hash = "sha256:806f36b1b605e2d6a72716f321f20036b9489d29c51c91f4dd29a3e3afb73b15", size = 240224, upload-time = "2025-11-30T20:23:02.008Z" }, + { url = "https://files.pythonhosted.org/packages/24/95/ffd128ed1146a153d928617b0ef673960130be0009c77d8fbf0abe306713/rpds_py-0.30.0-cp313-cp313-win_arm64.whl", hash = "sha256:d96c2086587c7c30d44f31f42eae4eac89b60dabbac18c7669be3700f13c3ce1", size = 230645, upload-time = "2025-11-30T20:23:03.43Z" }, + { url = "https://files.pythonhosted.org/packages/ff/1b/b10de890a0def2a319a2626334a7f0ae388215eb60914dbac8a3bae54435/rpds_py-0.30.0-cp313-cp313t-macosx_10_12_x86_64.whl", hash = "sha256:eb0b93f2e5c2189ee831ee43f156ed34e2a89a78a66b98cadad955972548be5a", size = 364443, upload-time = "2025-11-30T20:23:04.878Z" }, + { url = "https://files.pythonhosted.org/packages/0d/bf/27e39f5971dc4f305a4fb9c672ca06f290f7c4e261c568f3dea16a410d47/rpds_py-0.30.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:922e10f31f303c7c920da8981051ff6d8c1a56207dbdf330d9047f6d30b70e5e", size = 353375, upload-time = "2025-11-30T20:23:06.342Z" }, + { url = "https://files.pythonhosted.org/packages/40/58/442ada3bba6e8e6615fc00483135c14a7538d2ffac30e2d933ccf6852232/rpds_py-0.30.0-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cdc62c8286ba9bf7f47befdcea13ea0e26bf294bda99758fd90535cbaf408000", size = 383850, upload-time = "2025-11-30T20:23:07.825Z" }, + { url = "https://files.pythonhosted.org/packages/14/14/f59b0127409a33c6ef6f5c1ebd5ad8e32d7861c9c7adfa9a624fc3889f6c/rpds_py-0.30.0-cp313-cp313t-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:47f9a91efc418b54fb8190a6b4aa7813a23fb79c51f4bb84e418f5476c38b8db", size = 392812, upload-time = "2025-11-30T20:23:09.228Z" }, + { url = "https://files.pythonhosted.org/packages/b3/66/e0be3e162ac299b3a22527e8913767d869e6cc75c46bd844aa43fb81ab62/rpds_py-0.30.0-cp313-cp313t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1f3587eb9b17f3789ad50824084fa6f81921bbf9a795826570bda82cb3ed91f2", size = 517841, upload-time = "2025-11-30T20:23:11.186Z" }, + { url = "https://files.pythonhosted.org/packages/3d/55/fa3b9cf31d0c963ecf1ba777f7cf4b2a2c976795ac430d24a1f43d25a6ba/rpds_py-0.30.0-cp313-cp313t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:39c02563fc592411c2c61d26b6c5fe1e51eaa44a75aa2c8735ca88b0d9599daa", size = 408149, upload-time = "2025-11-30T20:23:12.864Z" }, + { url = "https://files.pythonhosted.org/packages/60/ca/780cf3b1a32b18c0f05c441958d3758f02544f1d613abf9488cd78876378/rpds_py-0.30.0-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:51a1234d8febafdfd33a42d97da7a43f5dcb120c1060e352a3fbc0c6d36e2083", size = 383843, upload-time = "2025-11-30T20:23:14.638Z" }, + { url = "https://files.pythonhosted.org/packages/82/86/d5f2e04f2aa6247c613da0c1dd87fcd08fa17107e858193566048a1e2f0a/rpds_py-0.30.0-cp313-cp313t-manylinux_2_31_riscv64.whl", hash = "sha256:eb2c4071ab598733724c08221091e8d80e89064cd472819285a9ab0f24bcedb9", size = 396507, upload-time = "2025-11-30T20:23:16.105Z" }, + { url = "https://files.pythonhosted.org/packages/4b/9a/453255d2f769fe44e07ea9785c8347edaf867f7026872e76c1ad9f7bed92/rpds_py-0.30.0-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:6bdfdb946967d816e6adf9a3d8201bfad269c67efe6cefd7093ef959683c8de0", size = 414949, upload-time = "2025-11-30T20:23:17.539Z" }, + { url = "https://files.pythonhosted.org/packages/a3/31/622a86cdc0c45d6df0e9ccb6becdba5074735e7033c20e401a6d9d0e2ca0/rpds_py-0.30.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:c77afbd5f5250bf27bf516c7c4a016813eb2d3e116139aed0096940c5982da94", size = 565790, upload-time = "2025-11-30T20:23:19.029Z" }, + { url = "https://files.pythonhosted.org/packages/1c/5d/15bbf0fb4a3f58a3b1c67855ec1efcc4ceaef4e86644665fff03e1b66d8d/rpds_py-0.30.0-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:61046904275472a76c8c90c9ccee9013d70a6d0f73eecefd38c1ae7c39045a08", size = 590217, upload-time = "2025-11-30T20:23:20.885Z" }, + { url = "https://files.pythonhosted.org/packages/6d/61/21b8c41f68e60c8cc3b2e25644f0e3681926020f11d06ab0b78e3c6bbff1/rpds_py-0.30.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:4c5f36a861bc4b7da6516dbdf302c55313afa09b81931e8280361a4f6c9a2d27", size = 555806, upload-time = "2025-11-30T20:23:22.488Z" }, + { url = "https://files.pythonhosted.org/packages/f9/39/7e067bb06c31de48de3eb200f9fc7c58982a4d3db44b07e73963e10d3be9/rpds_py-0.30.0-cp313-cp313t-win32.whl", hash = "sha256:3d4a69de7a3e50ffc214ae16d79d8fbb0922972da0356dcf4d0fdca2878559c6", size = 211341, upload-time = "2025-11-30T20:23:24.449Z" }, + { url = "https://files.pythonhosted.org/packages/0a/4d/222ef0b46443cf4cf46764d9c630f3fe4abaa7245be9417e56e9f52b8f65/rpds_py-0.30.0-cp313-cp313t-win_amd64.whl", hash = "sha256:f14fc5df50a716f7ece6a80b6c78bb35ea2ca47c499e422aa4463455dd96d56d", size = 225768, upload-time = "2025-11-30T20:23:25.908Z" }, + { url = "https://files.pythonhosted.org/packages/86/81/dad16382ebbd3d0e0328776d8fd7ca94220e4fa0798d1dc5e7da48cb3201/rpds_py-0.30.0-cp314-cp314-macosx_10_12_x86_64.whl", hash = "sha256:68f19c879420aa08f61203801423f6cd5ac5f0ac4ac82a2368a9fcd6a9a075e0", size = 362099, upload-time = "2025-11-30T20:23:27.316Z" }, + { url = "https://files.pythonhosted.org/packages/2b/60/19f7884db5d5603edf3c6bce35408f45ad3e97e10007df0e17dd57af18f8/rpds_py-0.30.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:ec7c4490c672c1a0389d319b3a9cfcd098dcdc4783991553c332a15acf7249be", size = 353192, upload-time = "2025-11-30T20:23:29.151Z" }, + { url = "https://files.pythonhosted.org/packages/bf/c4/76eb0e1e72d1a9c4703c69607cec123c29028bff28ce41588792417098ac/rpds_py-0.30.0-cp314-cp314-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f251c812357a3fed308d684a5079ddfb9d933860fc6de89f2b7ab00da481e65f", size = 384080, upload-time = "2025-11-30T20:23:30.785Z" }, + { url = "https://files.pythonhosted.org/packages/72/87/87ea665e92f3298d1b26d78814721dc39ed8d2c74b86e83348d6b48a6f31/rpds_py-0.30.0-cp314-cp314-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:ac98b175585ecf4c0348fd7b29c3864bda53b805c773cbf7bfdaffc8070c976f", size = 394841, upload-time = "2025-11-30T20:23:32.209Z" }, + { url = "https://files.pythonhosted.org/packages/77/ad/7783a89ca0587c15dcbf139b4a8364a872a25f861bdb88ed99f9b0dec985/rpds_py-0.30.0-cp314-cp314-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3e62880792319dbeb7eb866547f2e35973289e7d5696c6e295476448f5b63c87", size = 516670, upload-time = "2025-11-30T20:23:33.742Z" }, + { url = "https://files.pythonhosted.org/packages/5b/3c/2882bdac942bd2172f3da574eab16f309ae10a3925644e969536553cb4ee/rpds_py-0.30.0-cp314-cp314-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:4e7fc54e0900ab35d041b0601431b0a0eb495f0851a0639b6ef90f7741b39a18", size = 408005, upload-time = "2025-11-30T20:23:35.253Z" }, + { url = "https://files.pythonhosted.org/packages/ce/81/9a91c0111ce1758c92516a3e44776920b579d9a7c09b2b06b642d4de3f0f/rpds_py-0.30.0-cp314-cp314-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:47e77dc9822d3ad616c3d5759ea5631a75e5809d5a28707744ef79d7a1bcfcad", size = 382112, upload-time = "2025-11-30T20:23:36.842Z" }, + { url = "https://files.pythonhosted.org/packages/cf/8e/1da49d4a107027e5fbc64daeab96a0706361a2918da10cb41769244b805d/rpds_py-0.30.0-cp314-cp314-manylinux_2_31_riscv64.whl", hash = "sha256:b4dc1a6ff022ff85ecafef7979a2c6eb423430e05f1165d6688234e62ba99a07", size = 399049, upload-time = "2025-11-30T20:23:38.343Z" }, + { url = "https://files.pythonhosted.org/packages/df/5a/7ee239b1aa48a127570ec03becbb29c9d5a9eb092febbd1699d567cae859/rpds_py-0.30.0-cp314-cp314-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:4559c972db3a360808309e06a74628b95eaccbf961c335c8fe0d590cf587456f", size = 415661, upload-time = "2025-11-30T20:23:40.263Z" }, + { url = "https://files.pythonhosted.org/packages/70/ea/caa143cf6b772f823bc7929a45da1fa83569ee49b11d18d0ada7f5ee6fd6/rpds_py-0.30.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:0ed177ed9bded28f8deb6ab40c183cd1192aa0de40c12f38be4d59cd33cb5c65", size = 565606, upload-time = "2025-11-30T20:23:42.186Z" }, + { url = "https://files.pythonhosted.org/packages/64/91/ac20ba2d69303f961ad8cf55bf7dbdb4763f627291ba3d0d7d67333cced9/rpds_py-0.30.0-cp314-cp314-musllinux_1_2_i686.whl", hash = "sha256:ad1fa8db769b76ea911cb4e10f049d80bf518c104f15b3edb2371cc65375c46f", size = 591126, upload-time = "2025-11-30T20:23:44.086Z" }, + { url = "https://files.pythonhosted.org/packages/21/20/7ff5f3c8b00c8a95f75985128c26ba44503fb35b8e0259d812766ea966c7/rpds_py-0.30.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:46e83c697b1f1c72b50e5ee5adb4353eef7406fb3f2043d64c33f20ad1c2fc53", size = 553371, upload-time = "2025-11-30T20:23:46.004Z" }, + { url = "https://files.pythonhosted.org/packages/72/c7/81dadd7b27c8ee391c132a6b192111ca58d866577ce2d9b0ca157552cce0/rpds_py-0.30.0-cp314-cp314-win32.whl", hash = "sha256:ee454b2a007d57363c2dfd5b6ca4a5d7e2c518938f8ed3b706e37e5d470801ed", size = 215298, upload-time = "2025-11-30T20:23:47.696Z" }, + { url = "https://files.pythonhosted.org/packages/3e/d2/1aaac33287e8cfb07aab2e6b8ac1deca62f6f65411344f1433c55e6f3eb8/rpds_py-0.30.0-cp314-cp314-win_amd64.whl", hash = "sha256:95f0802447ac2d10bcc69f6dc28fe95fdf17940367b21d34e34c737870758950", size = 228604, upload-time = "2025-11-30T20:23:49.501Z" }, + { url = "https://files.pythonhosted.org/packages/e8/95/ab005315818cc519ad074cb7784dae60d939163108bd2b394e60dc7b5461/rpds_py-0.30.0-cp314-cp314-win_arm64.whl", hash = "sha256:613aa4771c99f03346e54c3f038e4cc574ac09a3ddfb0e8878487335e96dead6", size = 222391, upload-time = "2025-11-30T20:23:50.96Z" }, + { url = "https://files.pythonhosted.org/packages/9e/68/154fe0194d83b973cdedcdcc88947a2752411165930182ae41d983dcefa6/rpds_py-0.30.0-cp314-cp314t-macosx_10_12_x86_64.whl", hash = "sha256:7e6ecfcb62edfd632e56983964e6884851786443739dbfe3582947e87274f7cb", size = 364868, upload-time = "2025-11-30T20:23:52.494Z" }, + { url = "https://files.pythonhosted.org/packages/83/69/8bbc8b07ec854d92a8b75668c24d2abcb1719ebf890f5604c61c9369a16f/rpds_py-0.30.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:a1d0bc22a7cdc173fedebb73ef81e07faef93692b8c1ad3733b67e31e1b6e1b8", size = 353747, upload-time = "2025-11-30T20:23:54.036Z" }, + { url = "https://files.pythonhosted.org/packages/ab/00/ba2e50183dbd9abcce9497fa5149c62b4ff3e22d338a30d690f9af970561/rpds_py-0.30.0-cp314-cp314t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0d08f00679177226c4cb8c5265012eea897c8ca3b93f429e546600c971bcbae7", size = 383795, upload-time = "2025-11-30T20:23:55.556Z" }, + { url = "https://files.pythonhosted.org/packages/05/6f/86f0272b84926bcb0e4c972262f54223e8ecc556b3224d281e6598fc9268/rpds_py-0.30.0-cp314-cp314t-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:5965af57d5848192c13534f90f9dd16464f3c37aaf166cc1da1cae1fd5a34898", size = 393330, upload-time = "2025-11-30T20:23:57.033Z" }, + { url = "https://files.pythonhosted.org/packages/cb/e9/0e02bb2e6dc63d212641da45df2b0bf29699d01715913e0d0f017ee29438/rpds_py-0.30.0-cp314-cp314t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9a4e86e34e9ab6b667c27f3211ca48f73dba7cd3d90f8d5b11be56e5dbc3fb4e", size = 518194, upload-time = "2025-11-30T20:23:58.637Z" }, + { url = "https://files.pythonhosted.org/packages/ee/ca/be7bca14cf21513bdf9c0606aba17d1f389ea2b6987035eb4f62bd923f25/rpds_py-0.30.0-cp314-cp314t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e5d3e6b26f2c785d65cc25ef1e5267ccbe1b069c5c21b8cc724efee290554419", size = 408340, upload-time = "2025-11-30T20:24:00.2Z" }, + { url = "https://files.pythonhosted.org/packages/c2/c7/736e00ebf39ed81d75544c0da6ef7b0998f8201b369acf842f9a90dc8fce/rpds_py-0.30.0-cp314-cp314t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:626a7433c34566535b6e56a1b39a7b17ba961e97ce3b80ec62e6f1312c025551", size = 383765, upload-time = "2025-11-30T20:24:01.759Z" }, + { url = "https://files.pythonhosted.org/packages/4a/3f/da50dfde9956aaf365c4adc9533b100008ed31aea635f2b8d7b627e25b49/rpds_py-0.30.0-cp314-cp314t-manylinux_2_31_riscv64.whl", hash = "sha256:acd7eb3f4471577b9b5a41baf02a978e8bdeb08b4b355273994f8b87032000a8", size = 396834, upload-time = "2025-11-30T20:24:03.687Z" }, + { url = "https://files.pythonhosted.org/packages/4e/00/34bcc2565b6020eab2623349efbdec810676ad571995911f1abdae62a3a0/rpds_py-0.30.0-cp314-cp314t-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:fe5fa731a1fa8a0a56b0977413f8cacac1768dad38d16b3a296712709476fbd5", size = 415470, upload-time = "2025-11-30T20:24:05.232Z" }, + { url = "https://files.pythonhosted.org/packages/8c/28/882e72b5b3e6f718d5453bd4d0d9cf8df36fddeb4ddbbab17869d5868616/rpds_py-0.30.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:74a3243a411126362712ee1524dfc90c650a503502f135d54d1b352bd01f2404", size = 565630, upload-time = "2025-11-30T20:24:06.878Z" }, + { url = "https://files.pythonhosted.org/packages/3b/97/04a65539c17692de5b85c6e293520fd01317fd878ea1995f0367d4532fb1/rpds_py-0.30.0-cp314-cp314t-musllinux_1_2_i686.whl", hash = "sha256:3e8eeb0544f2eb0d2581774be4c3410356eba189529a6b3e36bbbf9696175856", size = 591148, upload-time = "2025-11-30T20:24:08.445Z" }, + { url = "https://files.pythonhosted.org/packages/85/70/92482ccffb96f5441aab93e26c4d66489eb599efdcf96fad90c14bbfb976/rpds_py-0.30.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:dbd936cde57abfee19ab3213cf9c26be06d60750e60a8e4dd85d1ab12c8b1f40", size = 556030, upload-time = "2025-11-30T20:24:10.956Z" }, + { url = "https://files.pythonhosted.org/packages/20/53/7c7e784abfa500a2b6b583b147ee4bb5a2b3747a9166bab52fec4b5b5e7d/rpds_py-0.30.0-cp314-cp314t-win32.whl", hash = "sha256:dc824125c72246d924f7f796b4f63c1e9dc810c7d9e2355864b3c3a73d59ade0", size = 211570, upload-time = "2025-11-30T20:24:12.735Z" }, + { url = "https://files.pythonhosted.org/packages/d0/02/fa464cdfbe6b26e0600b62c528b72d8608f5cc49f96b8d6e38c95d60c676/rpds_py-0.30.0-cp314-cp314t-win_amd64.whl", hash = "sha256:27f4b0e92de5bfbc6f86e43959e6edd1425c33b5e69aab0984a72047f2bcf1e3", size = 226532, upload-time = "2025-11-30T20:24:14.634Z" }, +] + +[[package]] +name = "send2trash" +version = "2.1.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/c5/f0/184b4b5f8d00f2a92cf96eec8967a3d550b52cf94362dad1100df9e48d57/send2trash-2.1.0.tar.gz", hash = "sha256:1c72b39f09457db3c05ce1d19158c2cbef4c32b8bedd02c155e49282b7ea7459", size = 17255, upload-time = "2026-01-14T06:27:36.056Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/1c/78/504fdd027da3b84ff1aecd9f6957e65f35134534ccc6da8628eb71e76d3f/send2trash-2.1.0-py3-none-any.whl", hash = "sha256:0da2f112e6d6bb22de6aa6daa7e144831a4febf2a87261451c4ad849fe9a873c", size = 17610, upload-time = "2026-01-14T06:27:35.218Z" }, +] + +[[package]] +name = "setuptools" +version = "82.0.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/4f/db/cfac1baf10650ab4d1c111714410d2fbb77ac5a616db26775db562c8fab2/setuptools-82.0.1.tar.gz", hash = "sha256:7d872682c5d01cfde07da7bccc7b65469d3dca203318515ada1de5eda35efbf9", size = 1152316, upload-time = "2026-03-09T12:47:17.221Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/9d/76/f789f7a86709c6b087c5a2f52f911838cad707cc613162401badc665acfe/setuptools-82.0.1-py3-none-any.whl", hash = "sha256:a59e362652f08dcd477c78bb6e7bd9d80a7995bc73ce773050228a348ce2e5bb", size = 1006223, upload-time = "2026-03-09T12:47:15.026Z" }, +] + +[[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" } +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" }, +] + +[[package]] +name = "six" +version = "1.17.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/94/e7/b2c673351809dca68a0e064b6af791aa332cf192da575fd474ed7d6f16a2/six-1.17.0.tar.gz", hash = "sha256:ff70335d468e7eb6ec65b95b99d3a2836546063f63acc5171de367e834932a81", size = 34031, upload-time = "2024-12-04T17:35:28.174Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/b7/ce/149a00dd41f10bc29e5921b496af8b574d8413afcd5e30dfa0ed46c2cc5e/six-1.17.0-py2.py3-none-any.whl", hash = "sha256:4721f391ed90541fddacab5acf947aa0d3dc7d27b2e1e8eda2be8970586c3274", size = 11050, upload-time = "2024-12-04T17:35:26.475Z" }, +] + +[[package]] +name = "soupsieve" +version = "2.8.3" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/7b/ae/2d9c981590ed9999a0d91755b47fc74f74de286b0f5cee14c9269041e6c4/soupsieve-2.8.3.tar.gz", hash = "sha256:3267f1eeea4251fb42728b6dfb746edc9acaffc4a45b27e19450b676586e8349", size = 118627, upload-time = "2026-01-20T04:27:02.457Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/46/2c/1462b1d0a634697ae9e55b3cecdcb64788e8b7d63f54d923fcd0bb140aed/soupsieve-2.8.3-py3-none-any.whl", hash = "sha256:ed64f2ba4eebeab06cc4962affce381647455978ffc1e36bb79a545b91f45a95", size = 37016, upload-time = "2026-01-20T04:27:01.012Z" }, +] + +[[package]] +name = "sqlite-anyio" +version = "0.2.8" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "anyio" }, + { name = "typing-extensions" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/20/a3/7830c95b37f1268dbb47e559d1f1ae027f3a4c36b1f7fc1b2dc5de1c5073/sqlite_anyio-0.2.8.tar.gz", hash = "sha256:d68b51a18c01a7dfa9cedbc319871ce77ab3ed0822518fb32810bb465b52d761", size = 3271, upload-time = "2026-03-02T10:37:43.466Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/7e/aa/182981b92659df83c3eb7d6f8fb0874984d72ad688fa4054cb96bc044bb0/sqlite_anyio-0.2.8-py3-none-any.whl", hash = "sha256:bbdfefb144aed2633d2618ee1508edd3abe67a00389379360949da4671640d86", size = 4041, upload-time = "2026-03-02T10:37:42.246Z" }, +] + +[[package]] +name = "sse-starlette" +version = "3.3.4" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "anyio" }, + { name = "starlette" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/26/8c/f9290339ef6d79badbc010f067cd769d6601ec11a57d78569c683fb4dd87/sse_starlette-3.3.4.tar.gz", hash = "sha256:aaf92fc067af8a5427192895ac028e947b484ac01edbc3caf00e7e7137c7bef1", size = 32427, upload-time = "2026-03-29T09:00:23.307Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/f8/7f/3de5402f39890ac5660b86bcf5c03f9d855dad5c4ed764866d7b592b46fd/sse_starlette-3.3.4-py3-none-any.whl", hash = "sha256:84bb06e58939a8b38d8341f1bc9792f06c2b53f48c608dd207582b664fc8f3c1", size = 14330, upload-time = "2026-03-29T09:00:21.846Z" }, +] + +[[package]] +name = "stack-data" +version = "0.6.3" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "asttokens" }, + { name = "executing" }, + { name = "pure-eval" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/28/e3/55dcc2cfbc3ca9c29519eb6884dd1415ecb53b0e934862d3559ddcb7e20b/stack_data-0.6.3.tar.gz", hash = "sha256:836a778de4fec4dcd1dcd89ed8abff8a221f58308462e1c4aa2a3cf30148f0b9", size = 44707, upload-time = "2023-09-30T13:58:05.479Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/f1/7b/ce1eafaf1a76852e2ec9b22edecf1daa58175c090266e9f6c64afcd81d91/stack_data-0.6.3-py3-none-any.whl", hash = "sha256:d5558e0c25a4cb0853cddad3d77da9891a08cb85dd9f9f91b9f8cd66e511e695", size = 24521, upload-time = "2023-09-30T13:58:03.53Z" }, +] + +[[package]] +name = "starlette" +version = "1.0.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "anyio" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/81/69/17425771797c36cded50b7fe44e850315d039f28b15901ab44839e70b593/starlette-1.0.0.tar.gz", hash = "sha256:6a4beaf1f81bb472fd19ea9b918b50dc3a77a6f2e190a12954b25e6ed5eea149", size = 2655289, upload-time = "2026-03-22T18:29:46.779Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/0b/c9/584bc9651441b4ba60cc4d557d8a547b5aff901af35bda3a4ee30c819b82/starlette-1.0.0-py3-none-any.whl", hash = "sha256:d3ec55e0bb321692d275455ddfd3df75fff145d009685eb40dc91fc66b03d38b", size = 72651, upload-time = "2026-03-22T18:29:45.111Z" }, +] + +[[package]] +name = "terminado" +version = "0.18.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "ptyprocess", marker = "os_name != 'nt'" }, + { name = "pywinpty", marker = "os_name == 'nt'" }, + { name = "tornado" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/8a/11/965c6fd8e5cc254f1fe142d547387da17a8ebfd75a3455f637c663fb38a0/terminado-0.18.1.tar.gz", hash = "sha256:de09f2c4b85de4765f7714688fff57d3e75bad1f909b589fde880460c753fd2e", size = 32701, upload-time = "2024-03-12T14:34:39.026Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/6a/9e/2064975477fdc887e47ad42157e214526dcad8f317a948dee17e1659a62f/terminado-0.18.1-py3-none-any.whl", hash = "sha256:a4468e1b37bb318f8a86514f65814e1afc977cf29b3992a4500d9dd305dcceb0", size = 14154, upload-time = "2024-03-12T14:34:36.569Z" }, +] + +[[package]] +name = "tinycss2" +version = "1.4.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "webencodings" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/7a/fd/7a5ee21fd08ff70d3d33a5781c255cbe779659bd03278feb98b19ee550f4/tinycss2-1.4.0.tar.gz", hash = "sha256:10c0972f6fc0fbee87c3edb76549357415e94548c1ae10ebccdea16fb404a9b7", size = 87085, upload-time = "2024-10-24T14:58:29.895Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/e6/34/ebdc18bae6aa14fbee1a08b63c015c72b64868ff7dae68808ab500c492e2/tinycss2-1.4.0-py3-none-any.whl", hash = "sha256:3a49cf47b7675da0b15d0c6e1df8df4ebd96e9394bb905a5775adb0d884c5289", size = 26610, upload-time = "2024-10-24T14:58:28.029Z" }, +] + +[[package]] +name = "tornado" +version = "6.5.5" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/f8/f1/3173dfa4a18db4a9b03e5d55325559dab51ee653763bb8745a75af491286/tornado-6.5.5.tar.gz", hash = "sha256:192b8f3ea91bd7f1f50c06955416ed76c6b72f96779b962f07f911b91e8d30e9", size = 516006, upload-time = "2026-03-10T21:31:02.067Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/59/8c/77f5097695f4dd8255ecbd08b2a1ed8ba8b953d337804dd7080f199e12bf/tornado-6.5.5-cp39-abi3-macosx_10_9_universal2.whl", hash = "sha256:487dc9cc380e29f58c7ab88f9e27cdeef04b2140862e5076a66fb6bb68bb1bfa", size = 445983, upload-time = "2026-03-10T21:30:44.28Z" }, + { url = "https://files.pythonhosted.org/packages/ab/5e/7625b76cd10f98f1516c36ce0346de62061156352353ef2da44e5c21523c/tornado-6.5.5-cp39-abi3-macosx_10_9_x86_64.whl", hash = "sha256:65a7f1d46d4bb41df1ac99f5fcb685fb25c7e61613742d5108b010975a9a6521", size = 444246, upload-time = "2026-03-10T21:30:46.571Z" }, + { url = "https://files.pythonhosted.org/packages/b2/04/7b5705d5b3c0fab088f434f9c83edac1573830ca49ccf29fb83bf7178eec/tornado-6.5.5-cp39-abi3-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:e74c92e8e65086b338fd56333fb9a68b9f6f2fe7ad532645a290a464bcf46be5", size = 447229, upload-time = "2026-03-10T21:30:48.273Z" }, + { url = "https://files.pythonhosted.org/packages/34/01/74e034a30ef59afb4097ef8659515e96a39d910b712a89af76f5e4e1f93c/tornado-6.5.5-cp39-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:435319e9e340276428bbdb4e7fa732c2d399386d1de5686cb331ec8eee754f07", size = 448192, upload-time = "2026-03-10T21:30:51.22Z" }, + { url = "https://files.pythonhosted.org/packages/be/00/fe9e02c5a96429fce1a1d15a517f5d8444f9c412e0bb9eadfbe3b0fc55bf/tornado-6.5.5-cp39-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:3f54aa540bdbfee7b9eb268ead60e7d199de5021facd276819c193c0fb28ea4e", size = 448039, upload-time = "2026-03-10T21:30:53.52Z" }, + { url = "https://files.pythonhosted.org/packages/82/9e/656ee4cec0398b1d18d0f1eb6372c41c6b889722641d84948351ae19556d/tornado-6.5.5-cp39-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:36abed1754faeb80fbd6e64db2758091e1320f6bba74a4cf8c09cd18ccce8aca", size = 447445, upload-time = "2026-03-10T21:30:55.541Z" }, + { url = "https://files.pythonhosted.org/packages/5a/76/4921c00511f88af86a33de770d64141170f1cfd9c00311aea689949e274e/tornado-6.5.5-cp39-abi3-win32.whl", hash = "sha256:dd3eafaaeec1c7f2f8fdcd5f964e8907ad788fe8a5a32c4426fbbdda621223b7", size = 448582, upload-time = "2026-03-10T21:30:57.142Z" }, + { url = "https://files.pythonhosted.org/packages/2c/23/f6c6112a04d28eed765e374435fb1a9198f73e1ec4b4024184f21faeb1ad/tornado-6.5.5-cp39-abi3-win_amd64.whl", hash = "sha256:6443a794ba961a9f619b1ae926a2e900ac20c34483eea67be4ed8f1e58d3ef7b", size = 448990, upload-time = "2026-03-10T21:30:58.857Z" }, + { url = "https://files.pythonhosted.org/packages/b7/c8/876602cbc96469911f0939f703453c1157b0c826ecb05bdd32e023397d4e/tornado-6.5.5-cp39-abi3-win_arm64.whl", hash = "sha256:2c9a876e094109333f888539ddb2de4361743e5d21eece20688e3e351e4990a6", size = 448016, upload-time = "2026-03-10T21:31:00.43Z" }, +] + +[[package]] +name = "traitlets" +version = "5.14.3" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/eb/79/72064e6a701c2183016abbbfedaba506d81e30e232a68c9f0d6f6fcd1574/traitlets-5.14.3.tar.gz", hash = "sha256:9ed0579d3502c94b4b3732ac120375cda96f923114522847de4b3bb98b96b6b7", size = 161621, upload-time = "2024-04-19T11:11:49.746Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/00/c0/8f5d070730d7836adc9c9b6408dec68c6ced86b304a9b26a14df072a6e8c/traitlets-5.14.3-py3-none-any.whl", hash = "sha256:b74e89e397b1ed28cc831db7aea759ba6640cb3de13090ca145426688ff1ac4f", size = 85359, upload-time = "2024-04-19T11:11:46.763Z" }, +] + +[[package]] +name = "typer" +version = "0.24.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "annotated-doc" }, + { name = "click" }, + { name = "rich" }, + { name = "shellingham" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/f5/24/cb09efec5cc954f7f9b930bf8279447d24618bb6758d4f6adf2574c41780/typer-0.24.1.tar.gz", hash = "sha256:e39b4732d65fbdcde189ae76cf7cd48aeae72919dea1fdfc16593be016256b45", size = 118613, upload-time = "2026-02-21T16:54:40.609Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/4a/91/48db081e7a63bb37284f9fbcefda7c44c277b18b0e13fbc36ea2335b71e6/typer-0.24.1-py3-none-any.whl", hash = "sha256:112c1f0ce578bfb4cab9ffdabc68f031416ebcc216536611ba21f04e9aa84c9e", size = 56085, upload-time = "2026-02-21T16:54:41.616Z" }, +] + +[[package]] +name = "typing-extensions" +version = "4.15.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/72/94/1a15dd82efb362ac84269196e94cf00f187f7ed21c242792a923cdb1c61f/typing_extensions-4.15.0.tar.gz", hash = "sha256:0cea48d173cc12fa28ecabc3b837ea3cf6f38c6d1136f85cbaaf598984861466", size = 109391, upload-time = "2025-08-25T13:49:26.313Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/18/67/36e9267722cc04a6b9f15c7f3441c2363321a3ea07da7ae0c0707beb2a9c/typing_extensions-4.15.0-py3-none-any.whl", hash = "sha256:f0fa19c6845758ab08074a0cfa8b7aecb71c999ca73d62883bc25cc018c4e548", size = 44614, upload-time = "2025-08-25T13:49:24.86Z" }, +] + +[[package]] +name = "typing-inspection" +version = "0.4.2" +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" } +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" }, +] + +[[package]] +name = "tzdata" +version = "2026.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/19/f5/cd531b2d15a671a40c0f66cf06bc3570a12cd56eef98960068ebbad1bf5a/tzdata-2026.1.tar.gz", hash = "sha256:67658a1903c75917309e753fdc349ac0efd8c27db7a0cb406a25be4840f87f98", size = 197639, upload-time = "2026-04-03T11:25:22.002Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/b0/70/d460bd685a170790ec89317e9bd33047988e4bce507b831f5db771e142de/tzdata-2026.1-py2.py3-none-any.whl", hash = "sha256:4b1d2be7ac37ceafd7327b961aa3a54e467efbdb563a23655fbfe0d39cfc42a9", size = 348952, upload-time = "2026-04-03T11:25:20.313Z" }, +] + +[[package]] +name = "uri-template" +version = "1.3.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/31/c7/0336f2bd0bcbada6ccef7aaa25e443c118a704f828a0620c6fa0207c1b64/uri-template-1.3.0.tar.gz", hash = "sha256:0e00f8eb65e18c7de20d595a14336e9f337ead580c70934141624b6d1ffdacc7", size = 21678, upload-time = "2023-06-21T01:49:05.374Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/e7/00/3fca040d7cf8a32776d3d81a00c8ee7457e00f80c649f1e4a863c8321ae9/uri_template-1.3.0-py3-none-any.whl", hash = "sha256:a44a133ea12d44a0c0f06d7d42a52d71282e77e2f937d8abd5655b8d56fc1363", size = 11140, upload-time = "2023-06-21T01:49:03.467Z" }, +] + +[[package]] +name = "urllib3" +version = "2.6.3" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/c7/24/5f1b3bdffd70275f6661c76461e25f024d5a38a46f04aaca912426a2b1d3/urllib3-2.6.3.tar.gz", hash = "sha256:1b62b6884944a57dbe321509ab94fd4d3b307075e0c2eae991ac71ee15ad38ed", size = 435556, upload-time = "2026-01-07T16:24:43.925Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/39/08/aaaad47bc4e9dc8c725e68f9d04865dbcb2052843ff09c97b08904852d84/urllib3-2.6.3-py3-none-any.whl", hash = "sha256:bf272323e553dfb2e87d9bfd225ca7b0f467b919d7bbd355436d3fd37cb0acd4", size = 131584, upload-time = "2026-01-07T16:24:42.685Z" }, +] + +[[package]] +name = "uvicorn" +version = "0.44.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "click", marker = "sys_platform != 'emscripten'" }, + { name = "h11", marker = "sys_platform != 'emscripten'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/5e/da/6eee1ff8b6cbeed47eeb5229749168e81eb4b7b999a1a15a7176e51410c9/uvicorn-0.44.0.tar.gz", hash = "sha256:6c942071b68f07e178264b9152f1f16dfac5da85880c4ce06366a96d70d4f31e", size = 86947, upload-time = "2026-04-06T09:23:22.826Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/b7/23/a5bbd9600dd607411fa644c06ff4951bec3a4d82c4b852374024359c19c0/uvicorn-0.44.0-py3-none-any.whl", hash = "sha256:ce937c99a2cc70279556967274414c087888e8cec9f9c94644dfca11bd3ced89", size = 69425, upload-time = "2026-04-06T09:23:21.524Z" }, +] + +[[package]] +name = "venta-web" +version = "0.1.0" +source = { virtual = "." } +dependencies = [ + { name = "jupyter" }, + { name = "jupyter-collaboration" }, + { name = "jupyter-mcp-server" }, + { name = "jupyterlab" }, + { name = "matplotlib" }, + { name = "numpy" }, + { name = "pandas" }, +] + +[package.metadata] +requires-dist = [ + { name = "jupyter", specifier = ">=1.1.1" }, + { name = "jupyter-collaboration", specifier = ">=4.3.0" }, + { name = "jupyter-mcp-server", specifier = ">=0.4.0" }, + { name = "jupyterlab", specifier = ">=4.5.6" }, + { name = "matplotlib", specifier = ">=3.10.8" }, + { name = "numpy", specifier = ">=2.4.4" }, + { name = "pandas", specifier = ">=3.0.2" }, +] + +[[package]] +name = "wcwidth" +version = "0.6.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/35/a2/8e3becb46433538a38726c948d3399905a4c7cabd0df578ede5dc51f0ec2/wcwidth-0.6.0.tar.gz", hash = "sha256:cdc4e4262d6ef9a1a57e018384cbeb1208d8abbc64176027e2c2455c81313159", size = 159684, upload-time = "2026-02-06T19:19:40.919Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/68/5a/199c59e0a824a3db2b89c5d2dade7ab5f9624dbf6448dc291b46d5ec94d3/wcwidth-0.6.0-py3-none-any.whl", hash = "sha256:1a3a1e510b553315f8e146c54764f4fb6264ffad731b3d78088cdb1478ffbdad", size = 94189, upload-time = "2026-02-06T19:19:39.646Z" }, +] + +[[package]] +name = "webcolors" +version = "25.10.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/1d/7a/eb316761ec35664ea5174709a68bbd3389de60d4a1ebab8808bfc264ed67/webcolors-25.10.0.tar.gz", hash = "sha256:62abae86504f66d0f6364c2a8520de4a0c47b80c03fc3a5f1815fedbef7c19bf", size = 53491, upload-time = "2025-10-31T07:51:03.977Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/e2/cc/e097523dd85c9cf5d354f78310927f1656c422bd7b2613b2db3e3f9a0f2c/webcolors-25.10.0-py3-none-any.whl", hash = "sha256:032c727334856fc0b968f63daa252a1ac93d33db2f5267756623c210e57a4f1d", size = 14905, upload-time = "2025-10-31T07:51:01.778Z" }, +] + +[[package]] +name = "webencodings" +version = "0.5.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/0b/02/ae6ceac1baeda530866a85075641cec12989bd8d31af6d5ab4a3e8c92f47/webencodings-0.5.1.tar.gz", hash = "sha256:b36a1c245f2d304965eb4e0a82848379241dc04b865afcc4aab16748587e1923", size = 9721, upload-time = "2017-04-05T20:21:34.189Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/f4/24/2a3e3df732393fed8b3ebf2ec078f05546de641fe1b667ee316ec1dcf3b7/webencodings-0.5.1-py2.py3-none-any.whl", hash = "sha256:a0af1213f3c2226497a97e2b3aa01a7e4bee4f403f95be16fc9acd2947514a78", size = 11774, upload-time = "2017-04-05T20:21:32.581Z" }, +] + +[[package]] +name = "websocket-client" +version = "1.9.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/2c/41/aa4bf9664e4cda14c3b39865b12251e8e7d239f4cd0e3cc1b6c2ccde25c1/websocket_client-1.9.0.tar.gz", hash = "sha256:9e813624b6eb619999a97dc7958469217c3176312b3a16a4bd1bc7e08a46ec98", size = 70576, upload-time = "2025-10-07T21:16:36.495Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/34/db/b10e48aa8fff7407e67470363eac595018441cf32d5e1001567a7aeba5d2/websocket_client-1.9.0-py3-none-any.whl", hash = "sha256:af248a825037ef591efbf6ed20cc5faa03d3b47b9e5a2230a529eeee1c1fc3ef", size = 82616, upload-time = "2025-10-07T21:16:34.951Z" }, +] + +[[package]] +name = "websockets" +version = "16.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/04/24/4b2031d72e840ce4c1ccb255f693b15c334757fc50023e4db9537080b8c4/websockets-16.0.tar.gz", hash = "sha256:5f6261a5e56e8d5c42a4497b364ea24d94d9563e8fbd44e78ac40879c60179b5", size = 179346, upload-time = "2026-01-10T09:23:47.181Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/cc/9c/baa8456050d1c1b08dd0ec7346026668cbc6f145ab4e314d707bb845bf0d/websockets-16.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:878b336ac47938b474c8f982ac2f7266a540adc3fa4ad74ae96fea9823a02cc9", size = 177364, upload-time = "2026-01-10T09:22:59.333Z" }, + { url = "https://files.pythonhosted.org/packages/7e/0c/8811fc53e9bcff68fe7de2bcbe75116a8d959ac699a3200f4847a8925210/websockets-16.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:52a0fec0e6c8d9a784c2c78276a48a2bdf099e4ccc2a4cad53b27718dbfd0230", size = 175039, upload-time = "2026-01-10T09:23:01.171Z" }, + { url = "https://files.pythonhosted.org/packages/aa/82/39a5f910cb99ec0b59e482971238c845af9220d3ab9fa76dd9162cda9d62/websockets-16.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:e6578ed5b6981005df1860a56e3617f14a6c307e6a71b4fff8c48fdc50f3ed2c", size = 175323, upload-time = "2026-01-10T09:23:02.341Z" }, + { url = "https://files.pythonhosted.org/packages/bd/28/0a25ee5342eb5d5f297d992a77e56892ecb65e7854c7898fb7d35e9b33bd/websockets-16.0-cp313-cp313-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:95724e638f0f9c350bb1c2b0a7ad0e83d9cc0c9259f3ea94e40d7b02a2179ae5", size = 184975, upload-time = "2026-01-10T09:23:03.756Z" }, + { url = "https://files.pythonhosted.org/packages/f9/66/27ea52741752f5107c2e41fda05e8395a682a1e11c4e592a809a90c6a506/websockets-16.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:c0204dc62a89dc9d50d682412c10b3542d748260d743500a85c13cd1ee4bde82", size = 186203, upload-time = "2026-01-10T09:23:05.01Z" }, + { url = "https://files.pythonhosted.org/packages/37/e5/8e32857371406a757816a2b471939d51c463509be73fa538216ea52b792a/websockets-16.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:52ac480f44d32970d66763115edea932f1c5b1312de36df06d6b219f6741eed8", size = 185653, upload-time = "2026-01-10T09:23:06.301Z" }, + { url = "https://files.pythonhosted.org/packages/9b/67/f926bac29882894669368dc73f4da900fcdf47955d0a0185d60103df5737/websockets-16.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:6e5a82b677f8f6f59e8dfc34ec06ca6b5b48bc4fcda346acd093694cc2c24d8f", size = 184920, upload-time = "2026-01-10T09:23:07.492Z" }, + { url = "https://files.pythonhosted.org/packages/3c/a1/3d6ccdcd125b0a42a311bcd15a7f705d688f73b2a22d8cf1c0875d35d34a/websockets-16.0-cp313-cp313-win32.whl", hash = "sha256:abf050a199613f64c886ea10f38b47770a65154dc37181bfaff70c160f45315a", size = 178255, upload-time = "2026-01-10T09:23:09.245Z" }, + { url = "https://files.pythonhosted.org/packages/6b/ae/90366304d7c2ce80f9b826096a9e9048b4bb760e44d3b873bb272cba696b/websockets-16.0-cp313-cp313-win_amd64.whl", hash = "sha256:3425ac5cf448801335d6fdc7ae1eb22072055417a96cc6b31b3861f455fbc156", size = 178689, upload-time = "2026-01-10T09:23:10.483Z" }, + { url = "https://files.pythonhosted.org/packages/f3/1d/e88022630271f5bd349ed82417136281931e558d628dd52c4d8621b4a0b2/websockets-16.0-cp314-cp314-macosx_10_15_universal2.whl", hash = "sha256:8cc451a50f2aee53042ac52d2d053d08bf89bcb31ae799cb4487587661c038a0", size = 177406, upload-time = "2026-01-10T09:23:12.178Z" }, + { url = "https://files.pythonhosted.org/packages/f2/78/e63be1bf0724eeb4616efb1ae1c9044f7c3953b7957799abb5915bffd38e/websockets-16.0-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:daa3b6ff70a9241cf6c7fc9e949d41232d9d7d26fd3522b1ad2b4d62487e9904", size = 175085, upload-time = "2026-01-10T09:23:13.511Z" }, + { url = "https://files.pythonhosted.org/packages/bb/f4/d3c9220d818ee955ae390cf319a7c7a467beceb24f05ee7aaaa2414345ba/websockets-16.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:fd3cb4adb94a2a6e2b7c0d8d05cb94e6f1c81a0cf9dc2694fb65c7e8d94c42e4", size = 175328, upload-time = "2026-01-10T09:23:14.727Z" }, + { url = "https://files.pythonhosted.org/packages/63/bc/d3e208028de777087e6fb2b122051a6ff7bbcca0d6df9d9c2bf1dd869ae9/websockets-16.0-cp314-cp314-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:781caf5e8eee67f663126490c2f96f40906594cb86b408a703630f95550a8c3e", size = 185044, upload-time = "2026-01-10T09:23:15.939Z" }, + { url = "https://files.pythonhosted.org/packages/ad/6e/9a0927ac24bd33a0a9af834d89e0abc7cfd8e13bed17a86407a66773cc0e/websockets-16.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:caab51a72c51973ca21fa8a18bd8165e1a0183f1ac7066a182ff27107b71e1a4", size = 186279, upload-time = "2026-01-10T09:23:17.148Z" }, + { url = "https://files.pythonhosted.org/packages/b9/ca/bf1c68440d7a868180e11be653c85959502efd3a709323230314fda6e0b3/websockets-16.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:19c4dc84098e523fd63711e563077d39e90ec6702aff4b5d9e344a60cb3c0cb1", size = 185711, upload-time = "2026-01-10T09:23:18.372Z" }, + { url = "https://files.pythonhosted.org/packages/c4/f8/fdc34643a989561f217bb477cbc47a3a07212cbda91c0e4389c43c296ebf/websockets-16.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:a5e18a238a2b2249c9a9235466b90e96ae4795672598a58772dd806edc7ac6d3", size = 184982, upload-time = "2026-01-10T09:23:19.652Z" }, + { url = "https://files.pythonhosted.org/packages/dd/d1/574fa27e233764dbac9c52730d63fcf2823b16f0856b3329fc6268d6ae4f/websockets-16.0-cp314-cp314-win32.whl", hash = "sha256:a069d734c4a043182729edd3e9f247c3b2a4035415a9172fd0f1b71658a320a8", size = 177915, upload-time = "2026-01-10T09:23:21.458Z" }, + { url = "https://files.pythonhosted.org/packages/8a/f1/ae6b937bf3126b5134ce1f482365fde31a357c784ac51852978768b5eff4/websockets-16.0-cp314-cp314-win_amd64.whl", hash = "sha256:c0ee0e63f23914732c6d7e0cce24915c48f3f1512ec1d079ed01fc629dab269d", size = 178381, upload-time = "2026-01-10T09:23:22.715Z" }, + { url = "https://files.pythonhosted.org/packages/06/9b/f791d1db48403e1f0a27577a6beb37afae94254a8c6f08be4a23e4930bc0/websockets-16.0-cp314-cp314t-macosx_10_15_universal2.whl", hash = "sha256:a35539cacc3febb22b8f4d4a99cc79b104226a756aa7400adc722e83b0d03244", size = 177737, upload-time = "2026-01-10T09:23:24.523Z" }, + { url = "https://files.pythonhosted.org/packages/bd/40/53ad02341fa33b3ce489023f635367a4ac98b73570102ad2cdd770dacc9a/websockets-16.0-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:b784ca5de850f4ce93ec85d3269d24d4c82f22b7212023c974c401d4980ebc5e", size = 175268, upload-time = "2026-01-10T09:23:25.781Z" }, + { url = "https://files.pythonhosted.org/packages/74/9b/6158d4e459b984f949dcbbb0c5d270154c7618e11c01029b9bbd1bb4c4f9/websockets-16.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:569d01a4e7fba956c5ae4fc988f0d4e187900f5497ce46339c996dbf24f17641", size = 175486, upload-time = "2026-01-10T09:23:27.033Z" }, + { url = "https://files.pythonhosted.org/packages/e5/2d/7583b30208b639c8090206f95073646c2c9ffd66f44df967981a64f849ad/websockets-16.0-cp314-cp314t-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:50f23cdd8343b984957e4077839841146f67a3d31ab0d00e6b824e74c5b2f6e8", size = 185331, upload-time = "2026-01-10T09:23:28.259Z" }, + { url = "https://files.pythonhosted.org/packages/45/b0/cce3784eb519b7b5ad680d14b9673a31ab8dcb7aad8b64d81709d2430aa8/websockets-16.0-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:152284a83a00c59b759697b7f9e9cddf4e3c7861dd0d964b472b70f78f89e80e", size = 186501, upload-time = "2026-01-10T09:23:29.449Z" }, + { url = "https://files.pythonhosted.org/packages/19/60/b8ebe4c7e89fb5f6cdf080623c9d92789a53636950f7abacfc33fe2b3135/websockets-16.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:bc59589ab64b0022385f429b94697348a6a234e8ce22544e3681b2e9331b5944", size = 186062, upload-time = "2026-01-10T09:23:31.368Z" }, + { url = "https://files.pythonhosted.org/packages/88/a8/a080593f89b0138b6cba1b28f8df5673b5506f72879322288b031337c0b8/websockets-16.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:32da954ffa2814258030e5a57bc73a3635463238e797c7375dc8091327434206", size = 185356, upload-time = "2026-01-10T09:23:32.627Z" }, + { url = "https://files.pythonhosted.org/packages/c2/b6/b9afed2afadddaf5ebb2afa801abf4b0868f42f8539bfe4b071b5266c9fe/websockets-16.0-cp314-cp314t-win32.whl", hash = "sha256:5a4b4cc550cb665dd8a47f868c8d04c8230f857363ad3c9caf7a0c3bf8c61ca6", size = 178085, upload-time = "2026-01-10T09:23:33.816Z" }, + { url = "https://files.pythonhosted.org/packages/9f/3e/28135a24e384493fa804216b79a6a6759a38cc4ff59118787b9fb693df93/websockets-16.0-cp314-cp314t-win_amd64.whl", hash = "sha256:b14dc141ed6d2dde437cddb216004bcac6a1df0935d79656387bd41632ba0bbd", size = 178531, upload-time = "2026-01-10T09:23:35.016Z" }, + { url = "https://files.pythonhosted.org/packages/6f/28/258ebab549c2bf3e64d2b0217b973467394a9cea8c42f70418ca2c5d0d2e/websockets-16.0-py3-none-any.whl", hash = "sha256:1637db62fad1dc833276dded54215f2c7fa46912301a24bd94d45d46a011ceec", size = 171598, upload-time = "2026-01-10T09:23:45.395Z" }, +] + +[[package]] +name = "widgetsnbextension" +version = "4.0.15" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/bd/f4/c67440c7fb409a71b7404b7aefcd7569a9c0d6bd071299bf4198ae7a5d95/widgetsnbextension-4.0.15.tar.gz", hash = "sha256:de8610639996f1567952d763a5a41af8af37f2575a41f9852a38f947eb82a3b9", size = 1097402, upload-time = "2025-11-01T21:15:55.178Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/3f/0e/fa3b193432cfc60c93b42f3be03365f5f909d2b3ea410295cf36df739e31/widgetsnbextension-4.0.15-py3-none-any.whl", hash = "sha256:8156704e4346a571d9ce73b84bee86a29906c9abfd7223b7228a28899ccf3366", size = 2196503, upload-time = "2025-11-01T21:15:53.565Z" }, +]