diff --git a/samples/community/agent/adk/gemini_enterprise/README.md b/samples/community/agent/adk/gemini_enterprise/v0_8/README.md similarity index 100% rename from samples/community/agent/adk/gemini_enterprise/README.md rename to samples/community/agent/adk/gemini_enterprise/v0_8/README.md diff --git a/samples/community/agent/adk/gemini_enterprise/agent_engine/.env.example b/samples/community/agent/adk/gemini_enterprise/v0_8/agent_engine/.env.example similarity index 100% rename from samples/community/agent/adk/gemini_enterprise/agent_engine/.env.example rename to samples/community/agent/adk/gemini_enterprise/v0_8/agent_engine/.env.example diff --git a/samples/community/agent/adk/gemini_enterprise/agent_engine/.gcloudignore b/samples/community/agent/adk/gemini_enterprise/v0_8/agent_engine/.gcloudignore similarity index 100% rename from samples/community/agent/adk/gemini_enterprise/agent_engine/.gcloudignore rename to samples/community/agent/adk/gemini_enterprise/v0_8/agent_engine/.gcloudignore diff --git a/samples/community/agent/adk/gemini_enterprise/agent_engine/README.md b/samples/community/agent/adk/gemini_enterprise/v0_8/agent_engine/README.md similarity index 100% rename from samples/community/agent/adk/gemini_enterprise/agent_engine/README.md rename to samples/community/agent/adk/gemini_enterprise/v0_8/agent_engine/README.md diff --git a/samples/community/agent/adk/gemini_enterprise/agent_engine/__init__.py b/samples/community/agent/adk/gemini_enterprise/v0_8/agent_engine/__init__.py similarity index 100% rename from samples/community/agent/adk/gemini_enterprise/agent_engine/__init__.py rename to samples/community/agent/adk/gemini_enterprise/v0_8/agent_engine/__init__.py diff --git a/samples/community/agent/adk/gemini_enterprise/agent_engine/agent.py b/samples/community/agent/adk/gemini_enterprise/v0_8/agent_engine/agent.py similarity index 100% rename from samples/community/agent/adk/gemini_enterprise/agent_engine/agent.py rename to samples/community/agent/adk/gemini_enterprise/v0_8/agent_engine/agent.py diff --git a/samples/community/agent/adk/gemini_enterprise/agent_engine/agent_executor.py b/samples/community/agent/adk/gemini_enterprise/v0_8/agent_engine/agent_executor.py similarity index 100% rename from samples/community/agent/adk/gemini_enterprise/agent_engine/agent_executor.py rename to samples/community/agent/adk/gemini_enterprise/v0_8/agent_engine/agent_executor.py diff --git a/samples/community/agent/adk/gemini_enterprise/agent_engine/contact_data.json b/samples/community/agent/adk/gemini_enterprise/v0_8/agent_engine/contact_data.json similarity index 100% rename from samples/community/agent/adk/gemini_enterprise/agent_engine/contact_data.json rename to samples/community/agent/adk/gemini_enterprise/v0_8/agent_engine/contact_data.json diff --git a/samples/community/agent/adk/gemini_enterprise/agent_engine/deploy.py b/samples/community/agent/adk/gemini_enterprise/v0_8/agent_engine/deploy.py similarity index 100% rename from samples/community/agent/adk/gemini_enterprise/agent_engine/deploy.py rename to samples/community/agent/adk/gemini_enterprise/v0_8/agent_engine/deploy.py diff --git a/samples/community/agent/adk/gemini_enterprise/agent_engine/examples/0.8/action_confirmation.json b/samples/community/agent/adk/gemini_enterprise/v0_8/agent_engine/examples/0.8/action_confirmation.json similarity index 100% rename from samples/community/agent/adk/gemini_enterprise/agent_engine/examples/0.8/action_confirmation.json rename to samples/community/agent/adk/gemini_enterprise/v0_8/agent_engine/examples/0.8/action_confirmation.json diff --git a/samples/community/agent/adk/gemini_enterprise/agent_engine/examples/0.8/contact_card.json b/samples/community/agent/adk/gemini_enterprise/v0_8/agent_engine/examples/0.8/contact_card.json similarity index 100% rename from samples/community/agent/adk/gemini_enterprise/agent_engine/examples/0.8/contact_card.json rename to samples/community/agent/adk/gemini_enterprise/v0_8/agent_engine/examples/0.8/contact_card.json diff --git a/samples/community/agent/adk/gemini_enterprise/agent_engine/examples/0.8/contact_list.json b/samples/community/agent/adk/gemini_enterprise/v0_8/agent_engine/examples/0.8/contact_list.json similarity index 100% rename from samples/community/agent/adk/gemini_enterprise/agent_engine/examples/0.8/contact_list.json rename to samples/community/agent/adk/gemini_enterprise/v0_8/agent_engine/examples/0.8/contact_list.json diff --git a/samples/community/agent/adk/gemini_enterprise/agent_engine/examples/0.8/follow_success.json b/samples/community/agent/adk/gemini_enterprise/v0_8/agent_engine/examples/0.8/follow_success.json similarity index 100% rename from samples/community/agent/adk/gemini_enterprise/agent_engine/examples/0.8/follow_success.json rename to samples/community/agent/adk/gemini_enterprise/v0_8/agent_engine/examples/0.8/follow_success.json diff --git a/samples/community/agent/adk/gemini_enterprise/agent_engine/prompt_builder.py b/samples/community/agent/adk/gemini_enterprise/v0_8/agent_engine/prompt_builder.py similarity index 100% rename from samples/community/agent/adk/gemini_enterprise/agent_engine/prompt_builder.py rename to samples/community/agent/adk/gemini_enterprise/v0_8/agent_engine/prompt_builder.py diff --git a/samples/community/agent/adk/gemini_enterprise/agent_engine/pyproject.toml b/samples/community/agent/adk/gemini_enterprise/v0_8/agent_engine/pyproject.toml similarity index 100% rename from samples/community/agent/adk/gemini_enterprise/agent_engine/pyproject.toml rename to samples/community/agent/adk/gemini_enterprise/v0_8/agent_engine/pyproject.toml diff --git a/samples/community/agent/adk/gemini_enterprise/agent_engine/tools.py b/samples/community/agent/adk/gemini_enterprise/v0_8/agent_engine/tools.py similarity index 100% rename from samples/community/agent/adk/gemini_enterprise/agent_engine/tools.py rename to samples/community/agent/adk/gemini_enterprise/v0_8/agent_engine/tools.py diff --git a/samples/community/agent/adk/gemini_enterprise/cloud_run/.gcloudignore b/samples/community/agent/adk/gemini_enterprise/v0_8/cloud_run/.gcloudignore similarity index 100% rename from samples/community/agent/adk/gemini_enterprise/cloud_run/.gcloudignore rename to samples/community/agent/adk/gemini_enterprise/v0_8/cloud_run/.gcloudignore diff --git a/samples/community/agent/adk/gemini_enterprise/cloud_run/README.md b/samples/community/agent/adk/gemini_enterprise/v0_8/cloud_run/README.md similarity index 100% rename from samples/community/agent/adk/gemini_enterprise/cloud_run/README.md rename to samples/community/agent/adk/gemini_enterprise/v0_8/cloud_run/README.md diff --git a/samples/community/agent/adk/gemini_enterprise/cloud_run/__init__.py b/samples/community/agent/adk/gemini_enterprise/v0_8/cloud_run/__init__.py similarity index 100% rename from samples/community/agent/adk/gemini_enterprise/cloud_run/__init__.py rename to samples/community/agent/adk/gemini_enterprise/v0_8/cloud_run/__init__.py diff --git a/samples/community/agent/adk/gemini_enterprise/cloud_run/agent.py b/samples/community/agent/adk/gemini_enterprise/v0_8/cloud_run/agent.py similarity index 100% rename from samples/community/agent/adk/gemini_enterprise/cloud_run/agent.py rename to samples/community/agent/adk/gemini_enterprise/v0_8/cloud_run/agent.py diff --git a/samples/community/agent/adk/gemini_enterprise/cloud_run/agent_executor.py b/samples/community/agent/adk/gemini_enterprise/v0_8/cloud_run/agent_executor.py similarity index 100% rename from samples/community/agent/adk/gemini_enterprise/cloud_run/agent_executor.py rename to samples/community/agent/adk/gemini_enterprise/v0_8/cloud_run/agent_executor.py diff --git a/samples/community/agent/adk/gemini_enterprise/cloud_run/contact_data.json b/samples/community/agent/adk/gemini_enterprise/v0_8/cloud_run/contact_data.json similarity index 100% rename from samples/community/agent/adk/gemini_enterprise/cloud_run/contact_data.json rename to samples/community/agent/adk/gemini_enterprise/v0_8/cloud_run/contact_data.json diff --git a/samples/community/agent/adk/gemini_enterprise/cloud_run/deploy.sh b/samples/community/agent/adk/gemini_enterprise/v0_8/cloud_run/deploy.sh similarity index 100% rename from samples/community/agent/adk/gemini_enterprise/cloud_run/deploy.sh rename to samples/community/agent/adk/gemini_enterprise/v0_8/cloud_run/deploy.sh diff --git a/samples/community/agent/adk/gemini_enterprise/cloud_run/examples/0.8/action_confirmation.json b/samples/community/agent/adk/gemini_enterprise/v0_8/cloud_run/examples/0.8/action_confirmation.json similarity index 100% rename from samples/community/agent/adk/gemini_enterprise/cloud_run/examples/0.8/action_confirmation.json rename to samples/community/agent/adk/gemini_enterprise/v0_8/cloud_run/examples/0.8/action_confirmation.json diff --git a/samples/community/agent/adk/gemini_enterprise/cloud_run/examples/0.8/contact_card.json b/samples/community/agent/adk/gemini_enterprise/v0_8/cloud_run/examples/0.8/contact_card.json similarity index 100% rename from samples/community/agent/adk/gemini_enterprise/cloud_run/examples/0.8/contact_card.json rename to samples/community/agent/adk/gemini_enterprise/v0_8/cloud_run/examples/0.8/contact_card.json diff --git a/samples/community/agent/adk/gemini_enterprise/cloud_run/examples/0.8/contact_list.json b/samples/community/agent/adk/gemini_enterprise/v0_8/cloud_run/examples/0.8/contact_list.json similarity index 100% rename from samples/community/agent/adk/gemini_enterprise/cloud_run/examples/0.8/contact_list.json rename to samples/community/agent/adk/gemini_enterprise/v0_8/cloud_run/examples/0.8/contact_list.json diff --git a/samples/community/agent/adk/gemini_enterprise/cloud_run/examples/0.8/follow_success.json b/samples/community/agent/adk/gemini_enterprise/v0_8/cloud_run/examples/0.8/follow_success.json similarity index 100% rename from samples/community/agent/adk/gemini_enterprise/cloud_run/examples/0.8/follow_success.json rename to samples/community/agent/adk/gemini_enterprise/v0_8/cloud_run/examples/0.8/follow_success.json diff --git a/samples/community/agent/adk/gemini_enterprise/cloud_run/main.py b/samples/community/agent/adk/gemini_enterprise/v0_8/cloud_run/main.py similarity index 100% rename from samples/community/agent/adk/gemini_enterprise/cloud_run/main.py rename to samples/community/agent/adk/gemini_enterprise/v0_8/cloud_run/main.py diff --git a/samples/community/agent/adk/gemini_enterprise/cloud_run/prompt_builder.py b/samples/community/agent/adk/gemini_enterprise/v0_8/cloud_run/prompt_builder.py similarity index 100% rename from samples/community/agent/adk/gemini_enterprise/cloud_run/prompt_builder.py rename to samples/community/agent/adk/gemini_enterprise/v0_8/cloud_run/prompt_builder.py diff --git a/samples/community/agent/adk/gemini_enterprise/cloud_run/pyproject.toml b/samples/community/agent/adk/gemini_enterprise/v0_8/cloud_run/pyproject.toml similarity index 100% rename from samples/community/agent/adk/gemini_enterprise/cloud_run/pyproject.toml rename to samples/community/agent/adk/gemini_enterprise/v0_8/cloud_run/pyproject.toml diff --git a/samples/community/agent/adk/gemini_enterprise/cloud_run/tools.py b/samples/community/agent/adk/gemini_enterprise/v0_8/cloud_run/tools.py similarity index 100% rename from samples/community/agent/adk/gemini_enterprise/cloud_run/tools.py rename to samples/community/agent/adk/gemini_enterprise/v0_8/cloud_run/tools.py diff --git a/samples/community/agent/adk/gemini_enterprise/v0_9/.env.example b/samples/community/agent/adk/gemini_enterprise/v0_9/.env.example new file mode 100644 index 0000000000..c4522b4ecf --- /dev/null +++ b/samples/community/agent/adk/gemini_enterprise/v0_9/.env.example @@ -0,0 +1,7 @@ +# Copy this file to .env and fill in your API key +# Get your API key at: https://aistudio.google.com/apikey + +GEMINI_API_KEY=your_gemini_api_key_here + +# Optional: Use Vertex AI instead of Gemini API +# GOOGLE_GENAI_USE_VERTEXAI=TRUE diff --git a/samples/community/agent/adk/gemini_enterprise/v0_9/.gcloudignore b/samples/community/agent/adk/gemini_enterprise/v0_9/.gcloudignore new file mode 100644 index 0000000000..9027fa78b4 --- /dev/null +++ b/samples/community/agent/adk/gemini_enterprise/v0_9/.gcloudignore @@ -0,0 +1,15 @@ +# Ignore common Python build artifacts +__pycache__/ +*.pyc +*.pyo +build/ +dist/ +*.egg-info/ +.venv/ +venv/ + +.adk/ + +# Do not upload local environment / secrets +.env +.env.example diff --git a/samples/community/agent/adk/gemini_enterprise/v0_9/.gitignore b/samples/community/agent/adk/gemini_enterprise/v0_9/.gitignore new file mode 100644 index 0000000000..1af12aec1f --- /dev/null +++ b/samples/community/agent/adk/gemini_enterprise/v0_9/.gitignore @@ -0,0 +1,20 @@ +# Local environment / secrets — never commit +.env + +# Python build artifacts +__pycache__/ +*.pyc +*.pyo +build/ +dist/ +*.egg-info/ + +# Virtual environments +.venv/ +venv/ + +# ADK local state +.adk/ + +# Generated prompt dump (from `python prompt_builder.py`) +generated_prompt.txt diff --git a/samples/community/agent/adk/gemini_enterprise/v0_9/README.md b/samples/community/agent/adk/gemini_enterprise/v0_9/README.md new file mode 100644 index 0000000000..bfc8108252 --- /dev/null +++ b/samples/community/agent/adk/gemini_enterprise/v0_9/README.md @@ -0,0 +1,121 @@ +# A2UI v0.9 Demo agent sample + +This sample uses the Agent Development Kit (ADK) and A2UI SDK to +create an "A2UI v0.9 Demo" agent that can be deployed to GCP Cloud Run. The agent +showcases what can be built with Gemini Enterprise A2UI v0.9, rendering rich, +interactive UIs from the Material component catalog and the Gemini Enterprise +custom components (`Canvas`, `IFrameSrcdoc`, `IFrameUrl`). + +Ask the agent **"what can you do?"** and it renders an A2UI `Canvas` listing the available demos. It can demo: + +- **Material components**: cards, text, buttons, icons, images, badges. +- **Forms & inputs**: `MaterialInput`, `MaterialSelect`, `MaterialCheckbox`, + `MaterialRadioButton`, `MaterialSlideToggle`, `MaterialSlider`, + `MaterialChips`, `MaterialButtonToggle`, `MaterialDatepicker`, + `MaterialTimepicker`. +- **Tabs & layout**: `MaterialTabs`, `MaterialExpansionPanel`, + `MaterialGridList`, `MaterialRow`, `MaterialColumn`. +- **Data display**: `MaterialTable`, `MaterialProgressBar`, + `MaterialProgressSpinner`. +- **Dialogs & menus**: `MaterialDialog`, `MaterialMenu`. +- **Canvas**: render content in a resizable side panel (`Canvas` root). +- **Iframe**: `IFrameSrcdoc` (sandboxed agent-supplied HTML) and `IFrameUrl` + (allowlisted embedded URL). +- **Restaurant finder**: find restaurants and book a table. + +This started as a port of the upstream +[A2UI restaurant_finder sample](https://github.com/a2ui-project/a2ui/tree/main/samples/agent/adk/restaurant_finder) +with these notable differences: + +1. **A2UI v0.9 only.** Support for A2UI v0.8 has been removed. The agent only + advertises and serves the A2UI v0.9 extension. +2. **Gemini Enterprise composite catalog.** Instead of the bundled + `BasicCatalog`, the agent uses the A2UI v0.9 Gemini Enterprise composite + catalog (`gemini_enterprise_composite_catalog.json`), which unions the + standard Material catalog, the basic catalog, and the Gemini Enterprise + custom components (`Canvas`, `IFrameSrcdoc`, `IFrameUrl`). Example UI + templates under `examples/0.9/` use `Material*`, `Canvas`, and `IFrame*` + components. +3. **Generic demo.** The agent is no longer restaurant-specific; it generates + whichever UI best demonstrates the components requested. + +## Prerequisites + +- Python 3.14 or higher +- [uv](https://docs.astral.sh/uv/) +- Access to an LLM and API key + +## Running the Sample + +1. Create an environment file with your API key: + + `cp .env.example .env` + + Edit `.env` with your actual API key (do not commit .env) + +2. Run the agent server: + + `uv run .` + +3. In another terminal window: + + - verify that the agent is available via A2A: + + ``` + curl http://localhost:10002/.well-known/agent-card.json + ``` + + - send a message to the agent: + + ``` + curl http://localhost:10002 \ + -H 'Content-Type: application/json' \ + -d '{ + "jsonrpc": "2.0", + "id": 1, + "method": "message/send", + "params": { + "message": { + "role": "user", + "parts": [{"text": "What can you do?"}], + "messageId": "1" + } + } + }' + ``` + +## Deploying to Cloud Run + +`deploy.sh` deploys the agent to Cloud Run from source: + +``` +./deploy.sh [MODEL_NAME] +``` + +## Updating the component catalog + +`gemini_enterprise_composite_catalog.json` is a copy of the public A2UI v0.9 +Gemini Enterprise composite catalog: + +``` +https://www.gstatic.com/vertexaisearch/a2ui/v0_9/gemini_enterprise_composite_catalog.json +``` + +If the catalog adds or removes components, also update the example templates in +`examples/0.9/` so they continue to validate (the agent loads examples with +`validate_examples=True`). + +## Disclaimer + +Important: The sample code provided is for demonstration purposes and +illustrates the mechanics of A2UI and the Agent-to-Agent (A2A) protocol. When +building production applications, it is critical to treat any agent operating +outside of your direct control as a potentially untrusted entity. + +All operational data received from an external agent—including its AgentCard, +messages, artifacts, and task statuses—should be handled as untrusted input. Any +UI definition or data stream received must be treated as untrusted. Developers +are responsible for implementing appropriate security measures—such as input +sanitization, Content Security Policies (CSP), strict isolation for optional +embedded content, and secure credential handling—to protect their systems and +users. diff --git a/samples/community/agent/adk/gemini_enterprise/v0_9/__init__.py b/samples/community/agent/adk/gemini_enterprise/v0_9/__init__.py new file mode 100644 index 0000000000..48c55d1a39 --- /dev/null +++ b/samples/community/agent/adk/gemini_enterprise/v0_9/__init__.py @@ -0,0 +1,15 @@ +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from . import agent diff --git a/samples/community/agent/adk/gemini_enterprise/v0_9/__main__.py b/samples/community/agent/adk/gemini_enterprise/v0_9/__main__.py new file mode 100644 index 0000000000..4bd905a032 --- /dev/null +++ b/samples/community/agent/adk/gemini_enterprise/v0_9/__main__.py @@ -0,0 +1,98 @@ +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import logging +import os + +from a2a.server.apps import A2AStarletteApplication +from a2a.server.request_handlers import DefaultRequestHandler +from a2a.server.tasks import InMemoryTaskStore +from agent import A2uiDemoAgent +from agent_executor import A2uiDemoAgentExecutor +import click +from dotenv import load_dotenv +from starlette.middleware.cors import CORSMiddleware +from starlette.staticfiles import StaticFiles + +load_dotenv() + +logging.basicConfig(level=logging.INFO) +logger = logging.getLogger(__name__) + + +class MissingAPIKeyError(Exception): + """Exception for missing API key.""" + + +@click.command() +@click.option("--host", default="localhost") +@click.option("--port", default=10002) +def main(host, port): + try: + # Check for API key only if Vertex AI is not configured + if not os.getenv("GOOGLE_GENAI_USE_VERTEXAI") == "TRUE": + if not os.getenv("GEMINI_API_KEY"): + raise MissingAPIKeyError( + "GEMINI_API_KEY environment variable not set and" + " GOOGLE_GENAI_USE_VERTEXAI is not TRUE." + ) + + base_url = f"http://{host}:{port}" + + agent = A2uiDemoAgent(base_url=base_url) + + agent_executor = A2uiDemoAgentExecutor(agent) + + request_handler = DefaultRequestHandler( + agent_executor=agent_executor, + task_store=InMemoryTaskStore(), + ) + server = A2AStarletteApplication( + agent_card=agent.agent_card, http_handler=request_handler + ) + import uvicorn + + app = server.build() + + app.add_middleware( + CORSMiddleware, + allow_origin_regex=r"http://localhost:\d+", + allow_credentials=True, + allow_methods=["*"], + allow_headers=["*"], + ) + + # Serve restaurant images from the local `images/` directory if + # present. The directory only contains binary image assets and may be + # omitted; the server still starts (image URLs will simply 404). + images_dir = os.path.join(os.path.dirname(__file__), "images") + if os.path.isdir(images_dir): + app.mount("/static", StaticFiles(directory=images_dir), name="static") + else: + logger.warning( + "No 'images' directory found at %s; /static will not be served.", + images_dir, + ) + + uvicorn.run(app, host=host, port=port) + except MissingAPIKeyError as e: + logger.error(f"Error: {e}") + exit(1) + except Exception as e: + logger.error(f"An error occurred during server startup: {e}") + exit(1) + + +if __name__ == "__main__": + main() diff --git a/samples/community/agent/adk/gemini_enterprise/v0_9/agent.py b/samples/community/agent/adk/gemini_enterprise/v0_9/agent.py new file mode 100644 index 0000000000..c050b51095 --- /dev/null +++ b/samples/community/agent/adk/gemini_enterprise/v0_9/agent.py @@ -0,0 +1,464 @@ +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from collections import OrderedDict +from collections.abc import AsyncIterable +import json +import logging +import os +from typing import Any, Optional + +from a2a.types import ( + AgentCapabilities, + AgentCard, + AgentSkill, + Part, + TextPart, +) +from a2ui.a2a.extension import get_a2ui_agent_extension +from a2ui.a2a.parts import parse_response_to_parts, stream_response_to_parts +from a2ui.parser.parser import parse_response +from a2ui.schema.catalog import CatalogConfig +from a2ui.schema.common_modifiers import remove_strict_validation +from a2ui.schema.constants import ( + A2UI_CLOSE_TAG, + A2UI_OPEN_TAG, + VERSION_0_9, +) +from a2ui.schema.manager import A2uiSchemaManager +from google.adk.agents import run_config +from google.adk.agents.llm_agent import LlmAgent +from google.adk.artifacts import InMemoryArtifactService +from google.adk.memory.in_memory_memory_service import InMemoryMemoryService +from google.adk.models import Gemini +from google.adk.runners import Runner +from google.adk.sessions import InMemorySessionService +from google.genai import types +import jsonschema +from prompt_builder import ( + ROLE_DESCRIPTION, + UI_DESCRIPTION, + get_text_prompt, +) +from tools import get_restaurants + +logger = logging.getLogger(__name__) + +# A2UI version supported by this agent. Only v0.9 is supported. +A2UI_VERSION = VERSION_0_9 + +# Name of the component catalog this agent advertises and validates against. +COMPOSITE_CATALOG_NAME = "composite" + +# Path to the A2UI v0.9 Gemini Enterprise composite catalog (copied into this +# agent's directory). The composite catalog is the union of the standard +# Material catalog, the basic catalog, and the Gemini Enterprise custom catalog, +# so a single surface can mix all three component families. Sourced from +# https://www.gstatic.com/vertexaisearch/a2ui/v0_9/gemini_enterprise_composite_catalog.json. +COMPOSITE_CATALOG_PATH = os.path.join( + os.path.dirname(__file__), "gemini_enterprise_composite_catalog.json" +) + + +class A2uiDemoAgent: + """A generic agent that demos A2UI v0.9 Material and custom components.""" + + SUPPORTED_CONTENT_TYPES = ["text", "text/plain"] + + def __init__(self, base_url: str): + self.base_url = base_url + self._agent_name = "A2UI v0.9 Demo" + self._user_id = "remote_agent" + self._text_runner: Optional[Runner] = self._build_runner( + self._build_llm_agent() + ) + + self._schema_manager: A2uiSchemaManager = self._build_schema_manager() + self._ui_runner: Runner = self._build_runner( + self._build_llm_agent(self._schema_manager) + ) + self._parsers = OrderedDict() + self._max_parsers = 1000 # Max active sessions to keep in memory + + self._agent_card = self._build_agent_card() + + @property + def agent_card(self) -> AgentCard: + return self._agent_card + + def _build_schema_manager(self) -> A2uiSchemaManager: + return A2uiSchemaManager( + version=A2UI_VERSION, + catalogs=[ + CatalogConfig.from_path( + name=COMPOSITE_CATALOG_NAME, + catalog_path=COMPOSITE_CATALOG_PATH, + examples_path=f"examples/{A2UI_VERSION}", + ) + ], + schema_modifiers=[remove_strict_validation], + ) + + def _build_agent_card(self) -> AgentCard: + ext = get_a2ui_agent_extension( + A2UI_VERSION, + self._schema_manager.accepts_inline_catalogs, + self._schema_manager.supported_catalog_ids, + ) + + capabilities = AgentCapabilities( + streaming=True, + extensions=[ext], + ) + demo_skill = AgentSkill( + id="a2ui_demo", + name="A2UI v0.9 Component Demo", + description=( + "Demonstrates A2UI v0.9 UIs built from the Material catalog and" + " Gemini Enterprise custom components: cards, forms & inputs," + " tabs, tables, progress indicators, dialogs & menus, the" + " Canvas side panel, and the Iframe (IFrameSrcdoc / IFrameUrl)" + " components." + ), + tags=["a2ui", "demo", "material", "canvas", "iframe"], + examples=[ + "What can you do?", + "Show me a demo of Material components", + "Render a contact form", + "Show a data table of recent orders", + "Demo the Canvas side panel", + "Show an IFrameSrcdoc with custom HTML", + "Embed a web page with IFrameUrl", + ], + ) + restaurant_skill = AgentSkill( + id="find_restaurants", + name="Find Restaurants Tool", + description=( + "Helps find restaurants based on user criteria (e.g., cuisine," + " location) and renders the results as an A2UI list." + ), + tags=["restaurant", "finder"], + examples=["Find me the top 10 chinese restaurants in the US"], + ) + + return AgentCard( + name="A2UI v0.9 Demo", + description=( + "A demo agent that showcases A2UI v0.9 UIs built from the" + " Material component catalog and Gemini Enterprise custom" + " components (Canvas, Iframe). Ask it 'what can you do?' to see" + " the available demos." + ), + url=self.base_url, + version="1.0.0", + default_input_modes=A2uiDemoAgent.SUPPORTED_CONTENT_TYPES, + default_output_modes=A2uiDemoAgent.SUPPORTED_CONTENT_TYPES, + capabilities=capabilities, + skills=[demo_skill, restaurant_skill], + ) + + def _build_runner(self, agent: LlmAgent) -> Runner: + return Runner( + app_name=self._agent_name, + agent=agent, + artifact_service=InMemoryArtifactService(), + session_service=InMemorySessionService(), + memory_service=InMemoryMemoryService(), + ) + + def get_processing_message(self) -> str: + return "Building an A2UI demo for you..." + + def _build_llm_agent( + self, schema_manager: Optional[A2uiSchemaManager] = None + ) -> LlmAgent: + """Builds the LLM agent for the A2UI demo agent.""" + model_env = os.getenv("MODEL") or "gemini-2.5-flash" + model_name = model_env.split("/")[-1] + + instruction = ( + schema_manager.generate_system_prompt( + role_description=ROLE_DESCRIPTION, + ui_description=UI_DESCRIPTION, + include_schema=True, + include_examples=True, + validate_examples=True, + ) + if schema_manager + else get_text_prompt() + ) + + return LlmAgent( + model=Gemini(model=model_name), + name="a2ui_demo_agent", + description=( + "An agent that demos A2UI v0.9 Material and custom components," + " and can also find restaurants and help book tables." + ), + instruction=instruction, + tools=[get_restaurants], + ) + + async def stream( + self, + query, + session_id, + ui_version: Optional[str] = None, + use_streaming: bool = True, + ) -> AsyncIterable[dict[str, Any]]: + session_state = {"base_url": self.base_url, "expression": "{expression}"} + + # Always use UI version 0.9 + ui_version = A2UI_VERSION + + # Determine which runner to use based on whether the a2ui extension is active. + if ui_version: + runner = self._ui_runner + schema_manager = self._schema_manager + selected_catalog = ( + schema_manager.get_selected_catalog() if schema_manager else None + ) + else: + runner = self._text_runner + schema_manager = None + selected_catalog = None + + session = await runner.session_service.get_session( + app_name=self._agent_name, + user_id=self._user_id, + session_id=session_id, + ) + if session is None: + session = await runner.session_service.create_session( + app_name=self._agent_name, + user_id=self._user_id, + state=session_state, + session_id=session_id, + ) + elif "base_url" not in session.state: + session.state["base_url"] = self.base_url + + # --- Begin: UI Validation and Retry Logic --- + max_retries = 1 # Total 2 attempts + attempt = 0 + current_query_text = query + + # Ensure schema was loaded + if ui_version and (not selected_catalog or not selected_catalog.catalog_schema): + logger.error( + "--- A2uiDemoAgent.stream: A2UI_SCHEMA is not loaded. " + "Cannot perform UI validation. ---" + ) + yield { + "is_task_complete": True, + "parts": [ + Part( + root=TextPart( + text=( + "I'm sorry, I'm facing an internal configuration" + " error with my UI components. Please contact" + " support." + ) + ) + ) + ], + } + return + + async def token_stream(current_message, full_content_list): + """Runs the model and yields its non-thought text parts. + + Defined once here (rather than inside the retry loop) so it is not + recreated on every attempt. The per-attempt `current_message` and + `full_content_list` are passed in; streamed text is accumulated into + `full_content_list` so the caller can validate/parse the full response. + """ + async for event in runner.run_async( + user_id=self._user_id, + session_id=session.id, + run_config=run_config.RunConfig( + streaming_mode=( + run_config.StreamingMode.SSE + if use_streaming + else run_config.StreamingMode.NONE + ) + ), + new_message=current_message, + ): + if event.content and event.content.parts: + for p in event.content.parts: + # Skip the model's "thought"/reasoning parts. Thinking + # models emit parts with thought=True (and .text set); + # streaming these would surface raw reasoning in the UI + # and corrupt the content we later validate/parse. + if p.text and not getattr(p, "thought", False): + full_content_list.append(p.text) + yield p.text + + while attempt <= max_retries: + attempt += 1 + logger.info( + f"--- A2uiDemoAgent.stream: Attempt {attempt}/{max_retries + 1} " + f"for session {session_id} ---" + ) + + current_message = types.Content( + role="user", parts=[types.Part.from_text(text=current_query_text)] + ) + + full_content_list = [] + parts_streamed = False + + if selected_catalog: + from a2ui.parser.streaming import A2uiStreamParser + + if session_id in self._parsers: + self._parsers.move_to_end(session_id) + else: + self._parsers[session_id] = A2uiStreamParser( + catalog=selected_catalog + ) + if len(self._parsers) > self._max_parsers: + self._parsers.popitem(last=False) + + async for part in stream_response_to_parts( + self._parsers[session_id], + token_stream(current_message, full_content_list), + version=ui_version, + ): + parts_streamed = True + yield { + "is_task_complete": False, + "parts": [part], + } + else: + async for token in token_stream(current_message, full_content_list): + yield { + "is_task_complete": False, + "updates": token, + } + + final_response_content = "".join(full_content_list) + + is_valid = False + error_message = "" + + if ui_version: + logger.info( + "--- A2uiDemoAgent.stream: Validating UI response (Attempt" + f" {attempt})... ---" + ) + try: + response_parts = parse_response(final_response_content) + + for part in response_parts: + if not part.a2ui_json: + continue + + parsed_json_data = part.a2ui_json + + # --- Validation Steps --- + # Check if it validates against the A2UI_SCHEMA + # This will raise jsonschema.exceptions.ValidationError if it fails + logger.info( + "--- A2uiDemoAgent.stream: Validating against" + " A2UI_SCHEMA... ---" + ) + selected_catalog.validator.validate(parsed_json_data) + # --- End Validation Steps --- + + logger.info( + "--- A2uiDemoAgent.stream: UI JSON successfully parsed AND" + " validated against schema. Validation OK (Attempt" + f" {attempt}). ---" + ) + is_valid = True + + except ( + ValueError, + json.JSONDecodeError, + jsonschema.exceptions.ValidationError, + ) as e: + logger.warning( + f"--- A2uiDemoAgent.stream: A2UI validation failed: {e}" + f" (Attempt {attempt}) ---" + ) + logger.warning( + "--- Failed response content:" + f" {final_response_content[:500]}... ---" + ) + error_message = f"Validation failed: {e}." + + else: # Not using UI, so text is always "valid" + is_valid = True + + if is_valid: + logger.info( + "--- A2uiDemoAgent.stream: Response is valid. Sending final" + f" response (Attempt {attempt}). ---" + ) + final_parts = parse_response_to_parts( + final_response_content, fallback_text="OK.", version=ui_version + ) + + # Always include the full parts in the final message. Even when + # streaming working chunks, many A2UI clients only render the + # final message's parts (treating working updates as progress/ + # "thought"). Sending empty final parts caused all content to be + # shown as thoughts with nothing rendered. + yield { + "is_task_complete": True, + "parts": final_parts, + } + return # We're done, exit the generator + + # --- If we're here, it means validation failed --- + + if attempt <= max_retries: + logger.warning( + "--- A2uiDemoAgent.stream: Retrying..." + f" ({attempt}/{max_retries + 1}) ---" + ) + # Prepare the query for the retry + current_query_text = ( + f"Your previous response was invalid. {error_message} You MUST" + " generate a valid response that strictly follows the A2UI JSON" + " SCHEMA. The response MUST be a JSON list of A2UI messages. Ensure" + f" each JSON part is wrapped in '{A2UI_OPEN_TAG}' and" + f" '{A2UI_CLOSE_TAG}' tags. Please retry the original request:" + f" '{query}'" + ) + # Loop continues... + + # --- If we're here, it means we've exhausted retries --- + logger.error( + "--- A2uiDemoAgent.stream: Max retries exhausted. Sending text-only" + " error. ---" + ) + yield { + "is_task_complete": True, + "parts": [ + Part( + root=TextPart( + text=( + "I'm sorry, I'm having trouble generating the interface" + " for that request right now. Please try again in a" + " moment." + ) + ) + ) + ], + } + # --- End: UI Validation and Retry Logic --- diff --git a/samples/community/agent/adk/gemini_enterprise/v0_9/agent_executor.py b/samples/community/agent/adk/gemini_enterprise/v0_9/agent_executor.py new file mode 100644 index 0000000000..3a512544f2 --- /dev/null +++ b/samples/community/agent/adk/gemini_enterprise/v0_9/agent_executor.py @@ -0,0 +1,202 @@ +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import logging + +from a2a.server.agent_execution import AgentExecutor, RequestContext +from a2a.server.events import EventQueue +from a2a.server.tasks import TaskUpdater +from a2a.types import ( + DataPart, + Part, + Task, + TaskState, + TextPart, + UnsupportedOperationError, +) +from a2a.utils import ( + new_agent_parts_message, + new_task, +) +from a2a.utils.errors import ServerError +from a2ui.a2a.extension import try_activate_a2ui_extension +from agent import A2uiDemoAgent + +logger = logging.getLogger(__name__) + +# The A2UI v0.9 client-to-server message envelope tags every message with this +# wire-protocol version string. It is the `version` value in a message shaped +# like `{"version": "v0.9", "action": {...}}` per the A2UI v0.9 client-to-server +# spec. Note this wire value ("v0.9") intentionally differs from the a2ui SDK's +# version constant a2ui.schema.constants.VERSION_0_9 ("0.9"). +A2UI_CLIENT_MESSAGE_VERSION = "v0.9" + + +class A2uiDemoAgentExecutor(AgentExecutor): + """AgentExecutor for the A2UI v0.9 Demo agent.""" + + def __init__(self, agent: A2uiDemoAgent): + self._agent = agent + + async def execute( + self, + context: RequestContext, + event_queue: EventQueue, + ) -> None: + query = "" + ui_event_part = None + action = None + + logger.info( + f"--- Client requested extensions: {context.requested_extensions} ---" + ) + active_ui_version = try_activate_a2ui_extension(context, self._agent.agent_card) + + # Determine which agent to use based on whether the a2ui extension is active. + if active_ui_version: + logger.info( + "--- AGENT_EXECUTOR: A2UI extension is active. Using UI agent. ---" + ) + else: + logger.info( + "--- AGENT_EXECUTOR: A2UI extension is not active. Using text agent." + " ---" + ) + + # This executor only supports non-streaming responses for now. Streaming + # will be re-enabled once the backend changes it requires are in place. + use_streaming = False + if context.message and context.message.parts: + logger.info( + f"--- AGENT_EXECUTOR: Processing {len(context.message.parts)} message" + " parts ---" + ) + for i, part in enumerate(context.message.parts): + if isinstance(part.root, DataPart): + data = part.root.data + version = data.get("version") if isinstance(data, dict) else None + event = ( + data.get("action") + if isinstance(data, dict) + and version == A2UI_CLIENT_MESSAGE_VERSION + else None + ) + if isinstance(event, dict) and event.get("name"): + logger.info( + f" Part {i}: Found a2ui v0.9 client action payload." + ) + ui_event_part = event + else: + logger.info(f" Part {i}: DataPart (data: {data})") + elif isinstance(part.root, TextPart): + logger.info(f" Part {i}: TextPart (text: {part.root.text})") + else: + logger.info(f" Part {i}: Unknown part type ({type(part.root)})") + + if ui_event_part: + logger.info(f"Received a2ui ClientEvent: {ui_event_part}") + action = ui_event_part.get("name") + ctx = ui_event_part.get("context") + if not isinstance(ctx, dict): + ctx = {} + + if action and action.startswith("run_demo"): + # The "what can you do?" card renders a button per demo. The demo key is + # encoded directly in the EVENT NAME as `run_demo_` (e.g. + # `run_demo_iframe_srcdoc`) so it is always present and never lost - + # unlike an event `context` value, which the model may omit or fail to + # bind. We still fall back to a `demo` context value (or the bare + # `run_demo` name) for backward compatibility. + demo = "" + if action.startswith("run_demo_"): + demo = action[len("run_demo_") :] + if not demo: + demo = ctx.get("demo", "") + if not demo and ctx: + demo = next(iter(ctx.values())) + demo = demo or "unknown" + query = ( + f"The user clicked the '{demo}' demo button. Render the A2UI UI for" + f" the '{demo}' demo now. Respond ONLY with the A2UI UI JSON." + " Do NOT call any tool and do NOT ask which demo to show." + ) + + elif action == "book_restaurant": + restaurant_name = ctx.get("restaurantName", "Unknown Restaurant") + address = ctx.get("address", "Address not provided") + image_url = ctx.get("imageUrl", "") + query = ( + f"USER_WANTS_TO_BOOK: {restaurant_name}, Address: {address}," + f" ImageURL: {image_url}" + ) + + elif action == "submit_booking": + restaurant_name = ctx.get("restaurantName", "Unknown Restaurant") + party_size = ctx.get("partySize", "Unknown Size") + reservation_time = ctx.get("reservationTime", "Unknown Time") + dietary_reqs = ctx.get("dietary", "None") + image_url = ctx.get("imageUrl", "") + query = ( + f"User submitted a booking for {restaurant_name} for {party_size}" + f" people at {reservation_time} with dietary requirements:" + f" {dietary_reqs}. The image URL is {image_url}" + ) + + else: + query = f"User submitted an event: {action} with data: {ctx}" + else: + logger.info("No a2ui UI event part found. Falling back to text input.") + query = context.get_user_input() + + logger.info(f"--- AGENT_EXECUTOR: Final query for LLM: '{query}' ---") + + task = context.current_task + + if not task: + task = new_task(context.message) + await event_queue.enqueue_event(task) + updater = TaskUpdater(event_queue, task.id, task.context_id) + + # Non-streaming: drain the agent's response and only act on the final + # (is_task_complete=True) item. Intermediate working updates are ignored + # so the client receives a single, complete response. + final_parts: list[Part] = [] + async for item in self._agent.stream( + query, task.context_id, active_ui_version, use_streaming=use_streaming + ): + if item.get("is_task_complete"): + final_parts = item["parts"] + + self._log_parts(final_parts) + + await updater.update_status( + TaskState.completed, + new_agent_parts_message(final_parts, task.context_id, task.id), + final=True, + ) + + def _log_parts(self, parts: list[Part]): + logger.info("--- FINAL PARTS TO BE SENT ---") + for i, part in enumerate(parts): + logger.info(" - Part %d: Type = %s", i, type(part.root)) + if isinstance(part.root, TextPart): + logger.info(" - Text: %s...", part.root.text[:200]) + elif isinstance(part.root, DataPart): + logger.info(" - Data: %s...", str(part.root.data)[:200]) + logger.info("-----------------------------") + + async def cancel( + self, request: RequestContext, event_queue: EventQueue + ) -> Task | None: + raise ServerError(error=UnsupportedOperationError()) diff --git a/samples/community/agent/adk/gemini_enterprise/v0_9/deploy.sh b/samples/community/agent/adk/gemini_enterprise/v0_9/deploy.sh new file mode 100755 index 0000000000..7417c82ed7 --- /dev/null +++ b/samples/community/agent/adk/gemini_enterprise/v0_9/deploy.sh @@ -0,0 +1,81 @@ +#!/bin/bash +# Copyright 2026 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Deploys the A2UI v0.9 Demo agent to Cloud Run from source. + +# Exit immediately if a command exits with a non-zero status. +set -e + +# --- Configuration --- +if [[ "$#" -lt 2 ]]; then + echo "Usage: $0 [MODEL_NAME]" + echo "MODEL_NAME can be 'gemini-2.5-pro' or 'gemini-2.5-flash' (default)." + exit 1 +fi + +PROJECT_ID=$1 +SERVICE_NAME=$2 +MODEL_NAME=${3:-"gemini-2.5-flash"} + +# Validate model name +if [[ "$MODEL_NAME" != "gemini-2.5-pro" && "$MODEL_NAME" != "gemini-2.5-flash" ]]; then + echo "Invalid model name. Please use 'gemini-2.5-pro' or 'gemini-2.5-flash'." + exit 1 +fi + +# The region to deploy to +REGION="us-central1" + +# The memory to allocate to the service +MEMORY="1Gi" + +# --- Deployment --- + +echo "Starting deployment of service '$SERVICE_NAME' to project '$PROJECT_ID' in region '$REGION' with model '$MODEL_NAME'..." + +# Deploy to Cloud Run from source code +gcloud run deploy "$SERVICE_NAME" \ + --source . \ + --project "$PROJECT_ID" \ + --region "$REGION" \ + --memory "$MEMORY" \ + --no-allow-unauthenticated \ + --set-env-vars=GOOGLE_CLOUD_PROJECT="$PROJECT_ID",GOOGLE_CLOUD_LOCATION="$REGION",GOOGLE_GENAI_USE_VERTEXAI=TRUE,MODEL="$MODEL_NAME",GOOGLE_PYTHON_PACKAGE_MANAGER=uv + + +echo "Deployment complete." +echo "Service URL: $(gcloud run services describe "$SERVICE_NAME" \ + --platform managed \ + --region "$REGION" \ + --project "$PROJECT_ID" \ + --format 'value(status.url)')" + +# After the initial deployment, get the service URL +SERVICE_URL=$(gcloud run services describe "$SERVICE_NAME" \ + --project="$PROJECT_ID" \ + --region="$REGION" \ + --format='value(status.url)') + +# Update the service to set the AGENT_URL environment variable so the agent +# advertises its public URL in its AgentCard. +echo "Updating service with its public URL: $SERVICE_URL" +gcloud run services update "$SERVICE_NAME" \ + --project="$PROJECT_ID" \ + --region="$REGION" \ + --update-env-vars=AGENT_URL="$SERVICE_URL" + + +echo "Deployment Complete!" +echo "Agent URL: ${SERVICE_URL}" diff --git a/samples/community/agent/adk/gemini_enterprise/v0_9/examples/0.9/booking_form.json b/samples/community/agent/adk/gemini_enterprise/v0_9/examples/0.9/booking_form.json new file mode 100644 index 0000000000..62ea2ca3ed --- /dev/null +++ b/samples/community/agent/adk/gemini_enterprise/v0_9/examples/0.9/booking_form.json @@ -0,0 +1,136 @@ +[ + { + "version": "v0.9", + "createSurface": { + "surfaceId": "booking-form", + "catalogId": "https://a2ui.org/specification/v0_9/material_catalog.json", + "theme": { + "primaryColor": "#FF0000", + "font": "Roboto" + } + } + }, + { + "version": "v0.9", + "updateComponents": { + "surfaceId": "booking-form", + "components": [ + { + "id": "root", + "component": "MaterialColumn", + "children": [ + "booking-title", + "restaurant-image", + "restaurant-address", + "party-size-field", + "date-field", + "time-field", + "dietary-field", + "submit-button" + ] + }, + { + "id": "booking-title", + "component": "MaterialText", + "usageHint": "h2", + "text": { + "path": "/title" + } + }, + { + "id": "restaurant-image", + "component": "MaterialImage", + "url": { + "path": "/imageUrl" + } + }, + { + "id": "restaurant-address", + "component": "MaterialText", + "text": { + "path": "/address" + } + }, + { + "id": "party-size-field", + "component": "MaterialInput", + "label": "Party Size", + "type": "number", + "value": { + "path": "/partySize" + } + }, + { + "id": "date-field", + "component": "MaterialDatepicker", + "label": "Date", + "value": { + "path": "/reservationDate" + } + }, + { + "id": "time-field", + "component": "MaterialTimepicker", + "label": "Time", + "value": { + "path": "/reservationTime" + } + }, + { + "id": "dietary-field", + "component": "MaterialInput", + "label": "Dietary Requirements", + "value": { + "path": "/dietary" + } + }, + { + "id": "submit-button", + "component": "MaterialButton", + "label": "Submit Reservation", + "variant": "primary", + "action": { + "event": { + "name": "submit_booking", + "context": { + "prompt": "Submit my reservation", + "restaurantName": { + "path": "/restaurantName" + }, + "partySize": { + "path": "/partySize" + }, + "reservationTime": { + "path": "/reservationTime" + }, + "dietary": { + "path": "/dietary" + }, + "imageUrl": { + "path": "/imageUrl" + } + } + } + } + } + ] + } + }, + { + "version": "v0.9", + "updateDataModel": { + "surfaceId": "booking-form", + "path": "/", + "value": { + "title": "Book a Table at [RestaurantName]", + "address": "[Restaurant Address]", + "restaurantName": "[RestaurantName]", + "partySize": "2", + "reservationDate": "", + "reservationTime": "", + "dietary": "", + "imageUrl": "" + } + } + } +] diff --git a/samples/community/agent/adk/gemini_enterprise/v0_9/examples/0.9/canvas_side_panel.json b/samples/community/agent/adk/gemini_enterprise/v0_9/examples/0.9/canvas_side_panel.json new file mode 100644 index 0000000000..6ce177d716 --- /dev/null +++ b/samples/community/agent/adk/gemini_enterprise/v0_9/examples/0.9/canvas_side_panel.json @@ -0,0 +1,73 @@ +[ + { + "version": "v0.9", + "createSurface": { + "surfaceId": "canvas-demo", + "catalogId": "https://a2ui.org/specification/v0_9/material_catalog.json", + "theme": { + "primaryColor": "#1a73e8", + "font": "Roboto" + } + } + }, + { + "version": "v0.9", + "updateComponents": { + "surfaceId": "canvas-demo", + "components": [ + { + "id": "root", + "component": "Canvas", + "cardTitle": "Quarterly Report", + "cardDescription": "Open to view the Q3 sales breakdown", + "cardIcon": "table_chart", + "autoOpen": true, + "children": ["panel-column"] + }, + { + "id": "panel-column", + "component": "MaterialColumn", + "align": "stretch", + "style": {"gap": "12px"}, + "children": ["panel-title", "summary-text", "sales-table"] + }, + { + "id": "panel-title", + "component": "MaterialText", + "text": "Q3 Sales by Region", + "usageHint": "h2" + }, + { + "id": "summary-text", + "component": "MaterialText", + "text": "Total revenue grew 12% quarter-over-quarter, led by the APAC region.", + "usageHint": "body" + }, + { + "id": "sales-table", + "component": "MaterialTable", + "rows": {"path": "/rows"}, + "columns": [ + {"header": "Region", "field": "region"}, + {"header": "Revenue", "field": "revenue"}, + {"header": "Growth", "field": "growth"} + ] + } + ] + } + }, + { + "version": "v0.9", + "updateDataModel": { + "surfaceId": "canvas-demo", + "path": "/", + "value": { + "rows": [ + {"region": "North America", "revenue": "$4.2M", "growth": "+8%"}, + {"region": "EMEA", "revenue": "$3.1M", "growth": "+5%"}, + {"region": "APAC", "revenue": "$2.8M", "growth": "+21%"} + ] + } + } + } +] diff --git a/samples/community/agent/adk/gemini_enterprise/v0_9/examples/0.9/confirmation.json b/samples/community/agent/adk/gemini_enterprise/v0_9/examples/0.9/confirmation.json new file mode 100644 index 0000000000..45ea20bb5d --- /dev/null +++ b/samples/community/agent/adk/gemini_enterprise/v0_9/examples/0.9/confirmation.json @@ -0,0 +1,100 @@ +[ + { + "version": "v0.9", + "createSurface": { + "surfaceId": "confirmation", + "catalogId": "https://a2ui.org/specification/v0_9/material_catalog.json", + "theme": { + "primaryColor": "#FF0000", + "font": "Roboto" + } + } + }, + { + "version": "v0.9", + "updateComponents": { + "surfaceId": "confirmation", + "components": [ + { + "id": "root", + "component": "MaterialCard", + "children": ["confirmation-column"] + }, + { + "id": "confirmation-column", + "component": "MaterialColumn", + "children": [ + "confirm-title", + "confirm-image", + "divider1", + "confirm-details", + "divider2", + "confirm-dietary", + "divider3", + "confirm-text" + ] + }, + { + "id": "confirm-title", + "component": "MaterialText", + "usageHint": "h2", + "text": { + "path": "/title" + } + }, + { + "id": "confirm-image", + "component": "MaterialImage", + "url": { + "path": "/imageUrl" + } + }, + { + "id": "confirm-details", + "component": "MaterialText", + "text": { + "path": "/bookingDetails" + } + }, + { + "id": "confirm-dietary", + "component": "MaterialText", + "text": { + "path": "/dietaryRequirements" + } + }, + { + "id": "confirm-text", + "component": "MaterialText", + "usageHint": "h5", + "text": "We look forward to seeing you!" + }, + { + "id": "divider1", + "component": "MaterialDivider" + }, + { + "id": "divider2", + "component": "MaterialDivider" + }, + { + "id": "divider3", + "component": "MaterialDivider" + } + ] + } + }, + { + "version": "v0.9", + "updateDataModel": { + "surfaceId": "confirmation", + "path": "/", + "value": { + "title": "Booking at [RestaurantName]", + "bookingDetails": "[PartySize] people at [Time]", + "dietaryRequirements": "Dietary Requirements: [Requirements]", + "imageUrl": "[ImageUrl]" + } + } + } +] diff --git a/samples/community/agent/adk/gemini_enterprise/v0_9/examples/0.9/iframe_srcdoc.json b/samples/community/agent/adk/gemini_enterprise/v0_9/examples/0.9/iframe_srcdoc.json new file mode 100644 index 0000000000..cbe494a259 --- /dev/null +++ b/samples/community/agent/adk/gemini_enterprise/v0_9/examples/0.9/iframe_srcdoc.json @@ -0,0 +1,45 @@ +[ + { + "version": "v0.9", + "createSurface": { + "surfaceId": "iframe-srcdoc-demo", + "catalogId": "https://a2ui.org/specification/v0_9/material_catalog.json", + "theme": { + "primaryColor": "#1a73e8", + "font": "Roboto" + } + } + }, + { + "version": "v0.9", + "updateComponents": { + "surfaceId": "iframe-srcdoc-demo", + "components": [ + { + "id": "root", + "component": "MaterialCard", + "children": ["column"] + }, + { + "id": "column", + "component": "MaterialColumn", + "align": "stretch", + "style": {"gap": "12px"}, + "children": ["title", "html-frame"] + }, + { + "id": "title", + "component": "MaterialText", + "text": "Custom HTML (IFrameSrcdoc)", + "usageHint": "h2" + }, + { + "id": "html-frame", + "component": "IFrameSrcdoc", + "height": 260, + "htmlContent": "

Hello from an iframe

This HTML was supplied by the agent and rendered in a sandboxed frame.

" + } + ] + } + } +] diff --git a/samples/community/agent/adk/gemini_enterprise/v0_9/examples/0.9/iframe_url_canvas.json b/samples/community/agent/adk/gemini_enterprise/v0_9/examples/0.9/iframe_url_canvas.json new file mode 100644 index 0000000000..89db462aa9 --- /dev/null +++ b/samples/community/agent/adk/gemini_enterprise/v0_9/examples/0.9/iframe_url_canvas.json @@ -0,0 +1,36 @@ +[ + { + "version": "v0.9", + "createSurface": { + "surfaceId": "iframe-url-demo", + "catalogId": "https://a2ui.org/specification/v0_9/material_catalog.json", + "theme": { + "primaryColor": "#1a73e8", + "font": "Roboto" + } + } + }, + { + "version": "v0.9", + "updateComponents": { + "surfaceId": "iframe-url-demo", + "components": [ + { + "id": "root", + "component": "Canvas", + "cardTitle": "Embedded Web Page", + "cardDescription": "Open to view an allowlisted URL in the side panel", + "cardIcon": "public", + "autoOpen": true, + "children": ["url-frame"] + }, + { + "id": "url-frame", + "component": "IFrameUrl", + "url": "https://www.google.com/search?q=a2ui", + "height": 600 + } + ] + } + } +] diff --git a/samples/community/agent/adk/gemini_enterprise/v0_9/examples/0.9/material_card_flight_status.json b/samples/community/agent/adk/gemini_enterprise/v0_9/examples/0.9/material_card_flight_status.json new file mode 100644 index 0000000000..36bc272f6b --- /dev/null +++ b/samples/community/agent/adk/gemini_enterprise/v0_9/examples/0.9/material_card_flight_status.json @@ -0,0 +1,198 @@ +[ + { + "version": "v0.9", + "createSurface": { + "surfaceId": "flight-status", + "catalogId": "https://a2ui.org/specification/v0_9/material_catalog.json", + "theme": { + "primaryColor": "#1a73e8", + "font": "Roboto" + } + } + }, + { + "version": "v0.9", + "updateComponents": { + "surfaceId": "flight-status", + "components": [ + { + "id": "root", + "component": "MaterialCard", + "style": {"padding": "8px 8px 0px 8px"}, + "children": ["main-column"] + }, + { + "id": "main-column", + "component": "MaterialColumn", + "align": "stretch", + "children": ["header-row", "route-row", "divider", "times-row"] + }, + { + "id": "header-row", + "component": "MaterialRow", + "justify": "spaceBetween", + "align": "center", + "children": ["flight-info", "actions"] + }, + { + "id": "flight-info", + "component": "MaterialRow", + "align": "center", + "children": ["flight-icon", "flight-number"] + }, + { + "id": "flight-icon", + "component": "MaterialIcon", + "icon": "flight", + "color": "primary" + }, + { + "id": "flight-number", + "component": "MaterialText", + "text": "OS 87 \u2022 Vienna to NY", + "usageHint": "h3" + }, + { + "id": "actions", + "component": "MaterialRow", + "children": ["share-btn", "bookmark-btn"] + }, + { + "id": "share-btn", + "component": "MaterialIconButton", + "icon": "share", + "ariaLabel": "Share flight", + "action": { + "event": { + "name": "share_flight", + "context": {"prompt": "Share this flight"} + } + } + }, + { + "id": "bookmark-btn", + "component": "MaterialIconButton", + "icon": "bookmark_border", + "ariaLabel": "Bookmark flight", + "action": { + "event": { + "name": "bookmark_flight", + "context": {"prompt": "Bookmark this flight"} + } + } + }, + { + "id": "route-row", + "component": "MaterialRow", + "justify": "spaceBetween", + "align": "center", + "children": ["origin-col", "arrow-icon", "dest-col"] + }, + { + "id": "origin-col", + "component": "MaterialColumn", + "children": ["origin-code", "origin-name"] + }, + { + "id": "origin-code", + "component": "MaterialText", + "text": "VIE", + "usageHint": "h1" + }, + { + "id": "origin-name", + "component": "MaterialText", + "text": "Vienna", + "usageHint": "caption" + }, + { + "id": "arrow-icon", + "component": "MaterialIcon", + "icon": "trending_flat" + }, + { + "id": "dest-col", + "component": "MaterialColumn", + "align": "end", + "children": ["dest-code", "dest-name"] + }, + { + "id": "dest-code", + "component": "MaterialText", + "text": "JFK", + "usageHint": "h1" + }, + { + "id": "dest-name", + "component": "MaterialText", + "text": "New York", + "usageHint": "caption" + }, + { + "id": "divider", + "component": "MaterialDivider" + }, + { + "id": "times-row", + "component": "MaterialRow", + "justify": "spaceBetween", + "children": ["dep-col", "status-col", "arr-col"] + }, + { + "id": "dep-col", + "component": "MaterialColumn", + "children": ["dep-label", "dep-time"] + }, + { + "id": "dep-label", + "component": "MaterialText", + "text": "Departs", + "usageHint": "caption" + }, + { + "id": "dep-time", + "component": "MaterialText", + "text": "10:15 AM", + "usageHint": "h4" + }, + { + "id": "status-col", + "component": "MaterialColumn", + "align": "center", + "children": ["status-label", "status-value"] + }, + { + "id": "status-label", + "component": "MaterialText", + "text": "Status", + "usageHint": "caption" + }, + { + "id": "status-value", + "component": "MaterialText", + "text": "On Time", + "usageHint": "body", + "style": {"fontWeight": "bold"} + }, + { + "id": "arr-col", + "component": "MaterialColumn", + "align": "end", + "children": ["arr-label", "arr-time"] + }, + { + "id": "arr-label", + "component": "MaterialText", + "text": "Arrives", + "usageHint": "caption" + }, + { + "id": "arr-time", + "component": "MaterialText", + "text": "2:30 PM", + "usageHint": "h4" + } + ] + } + } +] diff --git a/samples/community/agent/adk/gemini_enterprise/v0_9/examples/0.9/material_dashboard.json b/samples/community/agent/adk/gemini_enterprise/v0_9/examples/0.9/material_dashboard.json new file mode 100644 index 0000000000..03dea22278 --- /dev/null +++ b/samples/community/agent/adk/gemini_enterprise/v0_9/examples/0.9/material_dashboard.json @@ -0,0 +1,168 @@ +[ + { + "version": "v0.9", + "createSurface": { + "surfaceId": "dashboard", + "catalogId": "https://a2ui.org/specification/v0_9/material_catalog.json", + "theme": { + "primaryColor": "#1a73e8", + "font": "Roboto" + } + } + }, + { + "version": "v0.9", + "updateComponents": { + "surfaceId": "dashboard", + "components": [ + { + "id": "root", + "component": "MaterialCard", + "children": ["main-column"] + }, + { + "id": "main-column", + "component": "MaterialColumn", + "align": "stretch", + "children": ["header", "grid", "storage-header", "storage-bar"] + }, + { + "id": "header", + "component": "MaterialRow", + "justify": "spaceBetween", + "align": "center", + "children": ["title", "status-badge", "menu"] + }, + { + "id": "title", + "component": "MaterialText", + "text": "System Status", + "usageHint": "h2" + }, + { + "id": "status-badge", + "component": "MaterialBadge", + "text": "Live", + "color": "primary", + "children": ["status-icon"] + }, + { + "id": "status-icon", + "component": "MaterialIcon", + "icon": "cloud_done" + }, + { + "id": "menu", + "component": "MaterialMenu", + "icon": "more_vert", + "ariaLabel": "Options", + "action": { + "event": { + "name": "menu_action", + "context": {"prompt": "Open the dashboard options menu"} + } + }, + "options": [ + {"label": "Refresh", "value": "refresh"}, + {"label": "Settings", "value": "settings"} + ] + }, + { + "id": "grid", + "component": "MaterialGridList", + "cols": 2, + "rowHeight": "120px", + "children": ["cpu-card", "mem-card"] + }, + { + "id": "cpu-card", + "component": "MaterialCard", + "appearance": "outlined", + "children": ["cpu-col"] + }, + { + "id": "cpu-col", + "component": "MaterialColumn", + "align": "center", + "children": ["cpu-label", "cpu-spinner"] + }, + { + "id": "cpu-label", + "component": "MaterialText", + "text": "CPU Load", + "usageHint": "caption" + }, + { + "id": "cpu-spinner", + "component": "MaterialProgressSpinner", + "value": {"path": "/cpuUsage"}, + "mode": "determinate", + "diameter": 50, + "color": "warn", + "ariaLabel": "CPU usage" + }, + { + "id": "mem-card", + "component": "MaterialCard", + "appearance": "outlined", + "children": ["mem-col"] + }, + { + "id": "mem-col", + "component": "MaterialColumn", + "align": "center", + "children": ["mem-label", "mem-spinner"] + }, + { + "id": "mem-label", + "component": "MaterialText", + "text": "Memory", + "usageHint": "caption" + }, + { + "id": "mem-spinner", + "component": "MaterialProgressSpinner", + "value": {"path": "/memUsage"}, + "mode": "determinate", + "diameter": 50, + "color": "primary", + "ariaLabel": "Memory usage" + }, + { + "id": "storage-header", + "component": "MaterialRow", + "justify": "spaceBetween", + "children": ["storage-label", "storage-pct"] + }, + { + "id": "storage-label", + "component": "MaterialText", + "text": "Storage Used", + "usageHint": "body" + }, + { + "id": "storage-pct", + "component": "MaterialText", + "text": "78%", + "usageHint": "body" + }, + { + "id": "storage-bar", + "component": "MaterialProgressBar", + "value": 78, + "mode": "determinate", + "color": "accent", + "ariaLabel": "Storage usage" + } + ] + } + }, + { + "version": "v0.9", + "updateDataModel": { + "surfaceId": "dashboard", + "path": "/", + "value": {"cpuUsage": 65, "memUsage": 42} + } + } +] diff --git a/samples/community/agent/adk/gemini_enterprise/v0_9/examples/0.9/material_dialog.json b/samples/community/agent/adk/gemini_enterprise/v0_9/examples/0.9/material_dialog.json new file mode 100644 index 0000000000..a2b2b0d3cb --- /dev/null +++ b/samples/community/agent/adk/gemini_enterprise/v0_9/examples/0.9/material_dialog.json @@ -0,0 +1,102 @@ +[ + { + "version": "v0.9", + "createSurface": { + "surfaceId": "checkout", + "catalogId": "https://a2ui.org/specification/v0_9/material_catalog.json", + "theme": { + "primaryColor": "#1a73e8", + "font": "Roboto" + } + } + }, + { + "version": "v0.9", + "updateComponents": { + "surfaceId": "checkout", + "components": [ + { + "id": "root", + "component": "MaterialCard", + "children": ["main-column", "confirm-dialog"] + }, + { + "id": "main-column", + "component": "MaterialColumn", + "align": "stretch", + "style": {"gap": "12px"}, + "children": ["title", "shipping-panel", "billing-check", "pay-btn"] + }, + { + "id": "title", + "component": "MaterialText", + "text": "Checkout", + "usageHint": "h2" + }, + { + "id": "shipping-panel", + "component": "MaterialExpansionPanel", + "title": "1600 Amphitheatre Pkwy", + "children": ["shipping-col"] + }, + { + "id": "shipping-col", + "component": "MaterialColumn", + "children": ["addr-text1", "addr-text2"] + }, + { + "id": "addr-text1", + "component": "MaterialText", + "text": "Mountain View, CA 94043", + "usageHint": "body" + }, + { + "id": "addr-text2", + "component": "MaterialText", + "text": "Standard Delivery (3-5 days)", + "usageHint": "caption" + }, + { + "id": "billing-check", + "component": "MaterialCheckbox", + "label": "Billing address same as shipping", + "checked": {"path": "/sameBilling"}, + "color": "primary" + }, + { + "id": "pay-btn", + "component": "MaterialButton", + "label": "Place Order ($199.99)", + "color": "primary", + "variant": "flat", + "action": { + "event": { + "name": "confirm_checkout", + "context": {"prompt": "Confirm my checkout"} + } + } + }, + { + "id": "confirm-dialog", + "component": "MaterialDialog", + "title": "Confirmation", + "open": {"path": "/isConfirmDialogOpen"}, + "children": ["confirm-text"] + }, + { + "id": "confirm-text", + "component": "MaterialText", + "text": "Thank you! Your order has been placed." + } + ] + } + }, + { + "version": "v0.9", + "updateDataModel": { + "surfaceId": "checkout", + "path": "/", + "value": {"sameBilling": true, "isConfirmDialogOpen": false} + } + } +] diff --git a/samples/community/agent/adk/gemini_enterprise/v0_9/examples/0.9/material_input_form.json b/samples/community/agent/adk/gemini_enterprise/v0_9/examples/0.9/material_input_form.json new file mode 100644 index 0000000000..d3b6bc9ebb --- /dev/null +++ b/samples/community/agent/adk/gemini_enterprise/v0_9/examples/0.9/material_input_form.json @@ -0,0 +1,104 @@ +[ + { + "version": "v0.9", + "createSurface": { + "surfaceId": "signup-form", + "catalogId": "https://a2ui.org/specification/v0_9/material_catalog.json", + "theme": { + "primaryColor": "#1a73e8", + "font": "Roboto" + } + } + }, + { + "version": "v0.9", + "updateComponents": { + "surfaceId": "signup-form", + "components": [ + { + "id": "root", + "component": "MaterialCard", + "children": ["form-column"] + }, + { + "id": "form-column", + "component": "MaterialColumn", + "align": "stretch", + "style": {"gap": "12px"}, + "children": [ + "title", + "name-input", + "email-input", + "message-input", + "subscribe-toggle", + "submit-button" + ] + }, + { + "id": "title", + "component": "MaterialText", + "text": "Contact Us", + "usageHint": "h2" + }, + { + "id": "name-input", + "component": "MaterialInput", + "label": "Full Name", + "value": {"path": "/name"} + }, + { + "id": "email-input", + "component": "MaterialInput", + "label": "Email", + "type": "email", + "value": {"path": "/email"} + }, + { + "id": "message-input", + "component": "MaterialInput", + "label": "Message", + "value": {"path": "/message"} + }, + { + "id": "subscribe-toggle", + "component": "MaterialSlideToggle", + "label": "Subscribe to newsletter", + "checked": {"path": "/subscribe"}, + "color": "primary" + }, + { + "id": "submit-button", + "component": "MaterialButton", + "label": "Send Message", + "color": "primary", + "variant": "flat", + "action": { + "event": { + "name": "submit_contact", + "context": { + "prompt": "Submit the contact form", + "name": {"path": "/name"}, + "email": {"path": "/email"}, + "message": {"path": "/message"}, + "subscribe": {"path": "/subscribe"} + } + } + } + } + ] + } + }, + { + "version": "v0.9", + "updateDataModel": { + "surfaceId": "signup-form", + "path": "/", + "value": { + "name": "", + "email": "", + "message": "", + "subscribe": true + } + } + } +] diff --git a/samples/community/agent/adk/gemini_enterprise/v0_9/examples/0.9/material_preferences_tabs.json b/samples/community/agent/adk/gemini_enterprise/v0_9/examples/0.9/material_preferences_tabs.json new file mode 100644 index 0000000000..8618aa4fb3 --- /dev/null +++ b/samples/community/agent/adk/gemini_enterprise/v0_9/examples/0.9/material_preferences_tabs.json @@ -0,0 +1,175 @@ +[ + { + "version": "v0.9", + "createSurface": { + "surfaceId": "preferences", + "catalogId": "https://a2ui.org/specification/v0_9/material_catalog.json", + "theme": { + "primaryColor": "#1a73e8", + "font": "Roboto" + } + } + }, + { + "version": "v0.9", + "updateComponents": { + "surfaceId": "preferences", + "components": [ + { + "id": "root", + "component": "MaterialCard", + "style": {"height": "450px"}, + "children": ["main-column"] + }, + { + "id": "main-column", + "component": "MaterialColumn", + "align": "stretch", + "children": ["title", "tabs"] + }, + { + "id": "title", + "component": "MaterialText", + "text": "Preferences", + "usageHint": "h2" + }, + { + "id": "tabs", + "component": "MaterialTabs", + "activeTab": {"path": "/activeTab"}, + "tabs": [ + {"label": "General", "content": "tab-general"}, + {"label": "Notifications", "content": "tab-notif"}, + {"label": "Appearance", "content": "tab-app"} + ] + }, + { + "id": "tab-general", + "component": "MaterialColumn", + "align": "stretch", + "style": {"gap": "12px"}, + "children": ["lang-select", "auto-update-toggle"] + }, + { + "id": "lang-select", + "component": "MaterialSelect", + "label": "Language", + "value": {"path": "/lang"}, + "options": [ + {"label": "English", "value": "en"}, + {"label": "Spanish", "value": "es"}, + {"label": "French", "value": "fr"} + ] + }, + { + "id": "auto-update-toggle", + "component": "MaterialSlideToggle", + "label": "Auto-update components", + "checked": {"path": "/autoUpdate"}, + "color": "primary" + }, + { + "id": "tab-notif", + "component": "MaterialColumn", + "align": "stretch", + "style": {"gap": "8px"}, + "children": ["push-toggle", "freq-label", "freq-radio"] + }, + { + "id": "push-toggle", + "component": "MaterialSlideToggle", + "label": "Push Notifications", + "checked": {"path": "/pushNotif"}, + "color": "primary" + }, + { + "id": "freq-label", + "component": "MaterialText", + "text": "Notification Frequency", + "usageHint": "h4" + }, + { + "id": "freq-radio", + "component": "MaterialRadioButton", + "value": {"path": "/notifFreq"}, + "color": "primary", + "options": [ + {"label": "Instant", "value": "instant"}, + {"label": "Daily Summary", "value": "daily"}, + {"label": "Weekly Digest", "value": "weekly"} + ] + }, + { + "id": "tab-app", + "component": "MaterialColumn", + "align": "stretch", + "children": [ + "theme-label", + "theme-toggle", + "volume-label", + "volume-slider", + "cuisine-chips" + ] + }, + { + "id": "theme-label", + "component": "MaterialText", + "text": "Theme", + "usageHint": "h4" + }, + { + "id": "theme-toggle", + "component": "MaterialButtonToggle", + "value": {"path": "/theme"}, + "options": [ + {"label": "Light", "value": "light"}, + {"label": "Dark", "value": "dark"} + ] + }, + { + "id": "volume-label", + "component": "MaterialText", + "text": "UI Volume", + "usageHint": "h4" + }, + { + "id": "volume-slider", + "component": "MaterialSlider", + "value": {"path": "/volume"}, + "min": 0, + "max": 100, + "step": 10, + "color": "primary" + }, + { + "id": "cuisine-chips", + "component": "MaterialChips", + "value": {"path": "/tags"}, + "ariaLabel": "Interests", + "options": [ + {"label": "News", "value": "news"}, + {"label": "Sports", "value": "sports"}, + {"label": "Tech", "value": "tech"} + ] + } + ] + } + }, + { + "version": "v0.9", + "updateDataModel": { + "surfaceId": "preferences", + "path": "/", + "value": { + "activeTab": 0, + "lang": "en", + "autoUpdate": true, + "pushNotif": true, + "notifFreq": "daily", + "theme": "light", + "volume": 80, + "tags": "tech" + } + } + } +] diff --git a/samples/community/agent/adk/gemini_enterprise/v0_9/examples/0.9/material_table_orders.json b/samples/community/agent/adk/gemini_enterprise/v0_9/examples/0.9/material_table_orders.json new file mode 100644 index 0000000000..4e68cfcdf8 --- /dev/null +++ b/samples/community/agent/adk/gemini_enterprise/v0_9/examples/0.9/material_table_orders.json @@ -0,0 +1,75 @@ +[ + { + "version": "v0.9", + "createSurface": { + "surfaceId": "orders", + "catalogId": "https://a2ui.org/specification/v0_9/material_catalog.json", + "theme": { + "primaryColor": "#1a73e8", + "font": "Roboto" + } + } + }, + { + "version": "v0.9", + "updateComponents": { + "surfaceId": "orders", + "components": [ + { + "id": "root", + "component": "MaterialCard", + "children": ["main-column"] + }, + { + "id": "main-column", + "component": "MaterialColumn", + "align": "stretch", + "children": ["header", "filter-chips", "table"] + }, + { + "id": "header", + "component": "MaterialText", + "text": "Recent Orders", + "usageHint": "h2" + }, + { + "id": "filter-chips", + "component": "MaterialChips", + "value": {"path": "/filter"}, + "ariaLabel": "Filter orders", + "options": [ + {"label": "All", "value": "all"}, + {"label": "Completed", "value": "comp"}, + {"label": "Pending", "value": "pend"} + ] + }, + { + "id": "table", + "component": "MaterialTable", + "rows": {"path": "/orders"}, + "columns": [ + {"header": "Order #", "field": "id"}, + {"header": "Item", "field": "item"}, + {"header": "Status", "field": "status"}, + {"header": "Total", "field": "total"} + ] + } + ] + } + }, + { + "version": "v0.9", + "updateDataModel": { + "surfaceId": "orders", + "path": "/", + "value": { + "filter": "all", + "orders": [ + {"id": "ORD-101", "item": "Wireless Mouse", "status": "Shipped", "total": "$29.99"}, + {"id": "ORD-102", "item": "Mechanical Keyboard", "status": "Pending", "total": "$149.50"}, + {"id": "ORD-103", "item": "USB-C Hub", "status": "Delivered", "total": "$45.00"} + ] + } + } + } +] diff --git a/samples/community/agent/adk/gemini_enterprise/v0_9/examples/0.9/single_column_list.json b/samples/community/agent/adk/gemini_enterprise/v0_9/examples/0.9/single_column_list.json new file mode 100644 index 0000000000..83fb3d2b36 --- /dev/null +++ b/samples/community/agent/adk/gemini_enterprise/v0_9/examples/0.9/single_column_list.json @@ -0,0 +1,166 @@ +[ + { + "version": "v0.9", + "createSurface": { + "surfaceId": "default", + "catalogId": "https://a2ui.org/specification/v0_9/material_catalog.json", + "theme": { + "primaryColor": "#FF0000", + "font": "Roboto" + } + } + }, + { + "version": "v0.9", + "updateComponents": { + "surfaceId": "default", + "components": [ + { + "id": "root", + "component": "Canvas", + "cardTitle": "Restaurant results", + "cardDescription": "Open to browse the restaurants we found", + "cardIcon": "restaurant", + "autoOpen": true, + "children": ["results-column"] + }, + { + "id": "results-column", + "component": "MaterialColumn", + "children": ["title-heading", "item-list"] + }, + { + "id": "title-heading", + "component": "MaterialText", + "usageHint": "h1", + "text": { + "path": "/title" + } + }, + { + "id": "item-list", + "component": "MaterialColumn", + "children": { + "componentId": "item-card-template", + "path": "/items" + } + }, + { + "id": "item-card-template", + "component": "MaterialCard", + "children": ["card-layout"] + }, + { + "id": "card-layout", + "component": "MaterialRow", + "children": ["card-image", "card-details"] + }, + { + "id": "card-image", + "component": "MaterialImage", + "weight": 1, + "url": { + "path": "imageUrl" + } + }, + { + "id": "card-details", + "component": "MaterialColumn", + "weight": 2, + "children": [ + "template-name", + "template-rating", + "template-detail", + "template-link", + "template-book-button" + ] + }, + { + "id": "template-name", + "component": "MaterialText", + "usageHint": "h3", + "text": { + "path": "name" + } + }, + { + "id": "template-rating", + "component": "MaterialText", + "text": { + "path": "rating" + } + }, + { + "id": "template-detail", + "component": "MaterialText", + "text": { + "path": "detail" + } + }, + { + "id": "template-link", + "component": "MaterialText", + "text": { + "path": "infoLink" + } + }, + { + "id": "template-book-button", + "component": "MaterialButton", + "label": "Book Now", + "variant": "primary", + "action": { + "event": { + "name": "book_restaurant", + "context": { + "prompt": "Book a table at this restaurant", + "restaurantName": { + "path": "name" + }, + "imageUrl": { + "path": "imageUrl" + }, + "address": { + "path": "address" + } + } + } + } + } + ] + } + }, + { + "version": "v0.9", + "updateDataModel": { + "surfaceId": "default", + "path": "/title", + "value": "Found Restaurants" + } + }, + { + "version": "v0.9", + "updateDataModel": { + "surfaceId": "default", + "path": "/items", + "value": [ + { + "name": "The Fancy Place", + "rating": "★★★★★", + "detail": "Fine dining experience", + "infoLink": "https://fancyplace.com", + "imageUrl": "https://picsum.photos/200/300?random=1", + "address": "123 Luxury Ave, Food City" + }, + { + "name": "Quick Bites", + "rating": "★★★★☆", + "detail": "Casual and fast", + "infoLink": "https://quickbites.com", + "imageUrl": "https://picsum.photos/200/300?random=2", + "address": "456 Fast Lane, Quick Town" + } + ] + } + } +] diff --git a/samples/community/agent/adk/gemini_enterprise/v0_9/examples/0.9/two_column_list.json b/samples/community/agent/adk/gemini_enterprise/v0_9/examples/0.9/two_column_list.json new file mode 100644 index 0000000000..1db5ac923a --- /dev/null +++ b/samples/community/agent/adk/gemini_enterprise/v0_9/examples/0.9/two_column_list.json @@ -0,0 +1,228 @@ +[ + { + "version": "v0.9", + "createSurface": { + "surfaceId": "default", + "catalogId": "https://a2ui.org/specification/v0_9/material_catalog.json", + "theme": { + "primaryColor": "#FF0000", + "font": "Roboto" + } + } + }, + { + "version": "v0.9", + "updateComponents": { + "surfaceId": "default", + "components": [ + { + "id": "root", + "component": "Canvas", + "cardTitle": "Restaurant results", + "cardDescription": "Open to browse the restaurants we found", + "cardIcon": "restaurant", + "autoOpen": true, + "children": ["results-column"] + }, + { + "id": "results-column", + "component": "MaterialColumn", + "children": ["title-heading", "restaurant-list"] + }, + { + "id": "title-heading", + "component": "MaterialText", + "usageHint": "h1", + "text": { + "path": "/title" + } + }, + { + "id": "restaurant-list", + "component": "MaterialColumn", + "children": { + "componentId": "row-template", + "path": "/items" + } + }, + { + "id": "row-template", + "component": "MaterialRow", + "children": ["card-template-left", "card-template-right"] + }, + { + "id": "card-template-left", + "component": "MaterialCard", + "weight": 1, + "children": ["card-layout-left"] + }, + { + "id": "card-layout-left", + "component": "MaterialColumn", + "children": ["template-image-left", "card-details-left"] + }, + { + "id": "template-image-left", + "component": "MaterialImage", + "url": { + "path": "0/imageUrl" + } + }, + { + "id": "card-details-left", + "component": "MaterialColumn", + "children": [ + "template-name-left", + "template-rating-left", + "template-detail-left", + "template-book-button-left" + ] + }, + { + "id": "template-name-left", + "component": "MaterialText", + "usageHint": "h3", + "text": { + "path": "0/name" + } + }, + { + "id": "template-rating-left", + "component": "MaterialText", + "text": { + "path": "0/rating" + } + }, + { + "id": "template-detail-left", + "component": "MaterialText", + "text": { + "path": "0/detail" + } + }, + { + "id": "template-book-button-left", + "component": "MaterialButton", + "label": "Book Now", + "action": { + "event": { + "name": "book_restaurant", + "context": { + "prompt": "Book a table at this restaurant", + "restaurantName": { + "path": "0/name" + }, + "imageUrl": { + "path": "0/imageUrl" + }, + "address": { + "path": "0/address" + } + } + } + } + }, + { + "id": "card-template-right", + "component": "MaterialCard", + "weight": 1, + "children": ["card-layout-right"] + }, + { + "id": "card-layout-right", + "component": "MaterialColumn", + "children": ["template-image-right", "card-details-right"] + }, + { + "id": "template-image-right", + "component": "MaterialImage", + "url": { + "path": "1/imageUrl" + } + }, + { + "id": "card-details-right", + "component": "MaterialColumn", + "children": [ + "template-name-right", + "template-rating-right", + "template-detail-right", + "template-book-button-right" + ] + }, + { + "id": "template-name-right", + "component": "MaterialText", + "usageHint": "h3", + "text": { + "path": "1/name" + } + }, + { + "id": "template-rating-right", + "component": "MaterialText", + "text": { + "path": "1/rating" + } + }, + { + "id": "template-detail-right", + "component": "MaterialText", + "text": { + "path": "1/detail" + } + }, + { + "id": "template-book-button-right", + "component": "MaterialButton", + "label": "Book Now", + "action": { + "event": { + "name": "book_restaurant", + "context": { + "prompt": "Book a table at this restaurant", + "restaurantName": { + "path": "1/name" + }, + "imageUrl": { + "path": "1/imageUrl" + }, + "address": { + "path": "1/address" + } + } + } + } + } + ] + } + }, + { + "version": "v0.9", + "updateDataModel": { + "surfaceId": "default", + "path": "/", + "value": { + "title": "Top Restaurants", + "items": [ + [ + { + "name": "The Fancy Place", + "rating": "★★★★★", + "detail": "Fine dining experience", + "imageUrl": "https://picsum.photos/200/300?random=1", + "address": "123 Luxury Ave, Food City" + }, + { + "name": "Quick Bites", + "rating": "★★★★☆", + "detail": "Casual and fast", + "imageUrl": "https://picsum.photos/200/300?random=2", + "address": "456 Fast Lane, Quick Town" + } + ] + ] + } + } + } +] diff --git a/samples/community/agent/adk/gemini_enterprise/v0_9/gemini_enterprise_composite_catalog.json b/samples/community/agent/adk/gemini_enterprise/v0_9/gemini_enterprise_composite_catalog.json new file mode 100644 index 0000000000..4e71523bdb --- /dev/null +++ b/samples/community/agent/adk/gemini_enterprise/v0_9/gemini_enterprise_composite_catalog.json @@ -0,0 +1,3425 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "https://www.gstatic.com/vertexaisearch/a2ui/v0_9/gemini_enterprise_composite_catalog.json", + "title": "A2UI Gemini Enterprise Composite Catalog (v0.9)", + "description": "Composite Gemini Enterprise A2UI v0.9 catalog: the union of the standard Material catalog, the basic catalog, and the Gemini Enterprise custom catalog. Lets a single surface mix all three component families.", + "catalogId": "https://www.gstatic.com/vertexaisearch/a2ui/v0_9/gemini_enterprise_composite_catalog.json", + "components": { + "MaterialText": { + "description": "A component used for rendering text with theme-based typography.", + "allOf": [ + { + "$ref": "#/$defs/MaterialComponentCommon" + }, + { + "type": "object", + "properties": { + "component": { + "const": "MaterialText" + }, + "text": { + "description": "The text content to be displayed in the component.", + "$ref": "https://a2ui.org/specification/v0_9/common_types.json#/$defs/DynamicString" + }, + "usageHint": { + "description": "An optional hint that determines the typography and visual style of the text, mapping to standard Material Design typography tokens. Supported values are: 'h1', 'h2', 'h3', 'h4', 'h5', 'caption', 'body', 'subtitle1', 'subtitle2', 'body1', 'body2'. Defaults to 'body'.", + "enum": [ + "h1", + "h2", + "h3", + "h4", + "h5", + "caption", + "body", + "subtitle1", + "subtitle2", + "body1", + "body2" + ] + } + }, + "required": ["component", "text"] + } + ] + }, + "MaterialButton": { + "description": "A button component that handles user clicks and dispatches actions to the backend.", + "allOf": [ + { + "$ref": "#/$defs/MaterialComponentCommon" + }, + { + "type": "object", + "properties": { + "component": { + "const": "MaterialButton" + }, + "label": { + "description": "The text label displayed on the button.", + "$ref": "https://a2ui.org/specification/v0_9/common_types.json#/$defs/DynamicString" + }, + "leadingIcon": { + "description": "The name of an optional Material Icon to display before the button label (e.g., 'search').", + "$ref": "https://a2ui.org/specification/v0_9/common_types.json#/$defs/DynamicString" + }, + "trailingIcon": { + "description": "The name of an optional Material Icon to display after the button label (e.g., 'arrow_forward').", + "$ref": "https://a2ui.org/specification/v0_9/common_types.json#/$defs/DynamicString" + }, + "color": { + "description": "The theme color palette to apply to the button. Supported values are 'primary', 'accent', and 'warn'.", + "$ref": "https://a2ui.org/specification/v0_9/common_types.json#/$defs/DynamicString" + }, + "disabled": { + "description": "Whether the button is disabled and cannot be clicked or focused by the user (true if disabled, otherwise enabled).", + "$ref": "https://a2ui.org/specification/v0_9/common_types.json#/$defs/DynamicBoolean" + }, + "variant": { + "description": "The visual style variant of the button. Supported values are 'raised', 'flat', 'stroked', and 'basic' (default).", + "$ref": "https://a2ui.org/specification/v0_9/common_types.json#/$defs/DynamicString" + }, + "action": { + "description": "The action to be dispatched to the backend when the button is clicked.", + "$ref": "https://a2ui.org/specification/v0_9/common_types.json#/$defs/Action" + }, + "tooltip": { + "description": "Tooltip text displayed when the user hovers over the button.", + "$ref": "https://a2ui.org/specification/v0_9/common_types.json#/$defs/DynamicString" + }, + "ariaLabel": { + "description": "The ARIA label used for accessibility to describe the button to screen readers when the visual text is insufficient or not present.", + "$ref": "https://a2ui.org/specification/v0_9/common_types.json#/$defs/DynamicString" + }, + "ariaLabelledby": { + "description": "The ID of an element (or space-separated IDs of elements) that labels the button, providing an accessible name for screen readers.", + "$ref": "https://a2ui.org/specification/v0_9/common_types.json#/$defs/DynamicString" + }, + "ariaDescribedby": { + "description": "The ID of an element (or space-separated IDs of elements) that describes the button, providing additional context for screen readers.", + "$ref": "https://a2ui.org/specification/v0_9/common_types.json#/$defs/DynamicString" + } + }, + "required": ["component"] + } + ] + }, + "MaterialIconButton": { + "description": "A compact button displaying only an icon that dispatches an action when clicked.", + "allOf": [ + { + "$ref": "#/$defs/MaterialComponentCommon" + }, + { + "type": "object", + "properties": { + "component": { + "const": "MaterialIconButton" + }, + "icon": { + "description": "The name of the Material Icon to display inside the button (e.g., 'search' or 'settings').", + "$ref": "https://a2ui.org/specification/v0_9/common_types.json#/$defs/DynamicString" + }, + "ariaLabel": { + "description": "The ARIA label used for accessibility to describe the button's action to screen readers. This is required since the button only contains an icon.", + "$ref": "https://a2ui.org/specification/v0_9/common_types.json#/$defs/DynamicString" + }, + "ariaLabelledby": { + "description": "The ID of an element (or space-separated IDs of elements) that labels the icon button, providing an accessible name for screen readers.", + "$ref": "https://a2ui.org/specification/v0_9/common_types.json#/$defs/DynamicString" + }, + "ariaDescribedby": { + "description": "The ID of an element (or space-separated IDs of elements) that describes the icon button, providing additional context for screen readers.", + "$ref": "https://a2ui.org/specification/v0_9/common_types.json#/$defs/DynamicString" + }, + "color": { + "description": "The theme color palette to apply to the button. Supported values are 'primary', 'accent', and 'warn'.", + "$ref": "https://a2ui.org/specification/v0_9/common_types.json#/$defs/DynamicString" + }, + "disabled": { + "description": "Whether the button is disabled and cannot be clicked or focused by the user (true if disabled, otherwise enabled).", + "$ref": "https://a2ui.org/specification/v0_9/common_types.json#/$defs/DynamicBoolean" + }, + "action": { + "description": "The action to be dispatched to the backend when the button is clicked.", + "$ref": "https://a2ui.org/specification/v0_9/common_types.json#/$defs/Action" + }, + "tooltip": { + "description": "Tooltip text displayed when the user hovers over the button.", + "$ref": "https://a2ui.org/specification/v0_9/common_types.json#/$defs/DynamicString" + } + }, + "required": ["component", "icon", "action"] + } + ] + }, + "MaterialInput": { + "description": "An input field component for text entry, supporting validation and two-way data binding.", + "allOf": [ + { + "$ref": "#/$defs/MaterialComponentCommon" + }, + { + "type": "object", + "properties": { + "component": { + "const": "MaterialInput" + }, + "label": { + "description": "The floating label text displayed above the input field.", + "$ref": "https://a2ui.org/specification/v0_9/common_types.json#/$defs/DynamicString" + }, + "placeholder": { + "description": "The placeholder text displayed inside the input field when it is empty.", + "$ref": "https://a2ui.org/specification/v0_9/common_types.json#/$defs/DynamicString" + }, + "value": { + "description": "The current text value of the input field, supporting two-way data binding.", + "$ref": "https://a2ui.org/specification/v0_9/common_types.json#/$defs/DynamicString" + }, + "ariaLabelledby": { + "description": "The ID of an element (or space-separated IDs of elements) that labels the input field, providing an accessible name for screen readers.", + "$ref": "https://a2ui.org/specification/v0_9/common_types.json#/$defs/DynamicString" + }, + "ariaDescribedby": { + "description": "The ID of an element (or space-separated IDs of elements) that describes the input field, used for accessibility.", + "$ref": "https://a2ui.org/specification/v0_9/common_types.json#/$defs/DynamicString" + }, + "ariaLabel": { + "description": "The ARIA label used for accessibility to describe the input field to screen readers.", + "$ref": "https://a2ui.org/specification/v0_9/common_types.json#/$defs/DynamicString" + }, + "disabled": { + "description": "Whether the input field is disabled and cannot be interacted with (true if disabled, otherwise enabled).", + "$ref": "https://a2ui.org/specification/v0_9/common_types.json#/$defs/DynamicBoolean" + }, + "name": { + "description": "The name attribute of the input element, useful for form submission and identifying the field.", + "$ref": "https://a2ui.org/specification/v0_9/common_types.json#/$defs/DynamicString" + }, + "readonly": { + "description": "Whether the input field is read-only, preventing the user from changing its value while keeping it focusable (true if read-only, otherwise editable).", + "$ref": "https://a2ui.org/specification/v0_9/common_types.json#/$defs/DynamicBoolean" + }, + "type": { + "description": "The type of input control to display, such as 'text' (default), 'email', 'number', 'tel', or 'date'. 'password' is not allowed.", + "oneOf": [ + { + "type": "string", + "enum": ["text", "number", "email", "tel", "date"] + }, + { + "$ref": "https://a2ui.org/specification/v0_9/common_types.json#/$defs/DataBinding" + }, + { + "allOf": [ + { + "$ref": "https://a2ui.org/specification/v0_9/common_types.json#/$defs/FunctionCall" + }, + { + "properties": { + "returnType": { + "const": "string" + } + } + } + ] + } + ] + }, + "validationRegexp": { + "description": "An optional regular expression pattern used to validate the input value. If the value does not match, a validation error is displayed.", + "$ref": "https://a2ui.org/specification/v0_9/common_types.json#/$defs/DynamicString" + }, + "checks": { + "description": "An array of validation rules (each containing a dynamic boolean condition and an error message) that are reactively evaluated to determine the input's validity.", + "type": "array", + "items": { + "$ref": "https://a2ui.org/specification/v0_9/common_types.json#/$defs/CheckRule" + } + } + }, + "required": ["component"] + } + ] + }, + "MaterialRow": { + "description": "A container component for laying out child components horizontally.", + "allOf": [ + { + "$ref": "#/$defs/MaterialComponentCommon" + }, + { + "type": "object", + "properties": { + "component": { + "const": "MaterialRow" + }, + "children": { + "description": "A list of child components to be rendered horizontally inside the row.", + "$ref": "https://a2ui.org/specification/v0_9/common_types.json#/$defs/ChildList" + }, + "justify": { + "description": "Optional horizontal alignment (justify-content) of the child components within the row. Supported values are: 'center', 'end', 'spaceAround', 'spaceBetween', 'spaceEvenly', 'start' (default).", + "enum": ["center", "end", "spaceAround", "spaceBetween", "spaceEvenly", "start"] + }, + "align": { + "description": "Optional vertical alignment (align-items) of the child components within the row. Supported values are: 'start', 'center', 'end', 'stretch' (default).", + "enum": ["start", "center", "end", "stretch"] + } + }, + "required": ["component", "children"] + } + ] + }, + "MaterialColumn": { + "description": "A container component for laying out child components vertically.", + "allOf": [ + { + "$ref": "#/$defs/MaterialComponentCommon" + }, + { + "type": "object", + "properties": { + "component": { + "const": "MaterialColumn" + }, + "children": { + "description": "A list of child components to be rendered vertically inside the column.", + "$ref": "https://a2ui.org/specification/v0_9/common_types.json#/$defs/ChildList" + }, + "justify": { + "description": "Optional vertical alignment (justify-content) of the child components within the column. Supported values are: 'start' (default), 'center', 'end', 'spaceBetween', 'spaceAround', 'spaceEvenly'.", + "enum": ["start", "center", "end", "spaceBetween", "spaceAround", "spaceEvenly"] + }, + "align": { + "description": "Optional horizontal alignment (align-items) of the child components within the column. Supported values are: 'center', 'end', 'start', 'stretch' (default).", + "enum": ["center", "end", "start", "stretch"] + } + }, + "required": ["component", "children"] + } + ] + }, + "MaterialCard": { + "description": "A container component that presents content and actions in a single topic card.", + "allOf": [ + { + "$ref": "#/$defs/MaterialComponentCommon" + }, + { + "type": "object", + "properties": { + "component": { + "const": "MaterialCard" + }, + "appearance": { + "description": "The visual style appearance of the card. Supported values are 'outlined' (card with a border) and 'raised' (card with an elevation shadow, default).", + "enum": ["outlined", "raised"] + }, + "align": { + "description": "Optional alignment (align-items) of the child components within the card. Supported values are: 'start' (default), 'center', 'end', 'stretch'.", + "enum": ["center", "end", "start", "stretch"] + }, + "ariaLabel": { + "description": "The ARIA label used for accessibility to describe the card to screen readers.", + "$ref": "https://a2ui.org/specification/v0_9/common_types.json#/$defs/DynamicString" + }, + "ariaLabelledby": { + "description": "The ID of an element (or space-separated IDs of elements) that labels the card, providing an accessible name for screen readers.", + "$ref": "https://a2ui.org/specification/v0_9/common_types.json#/$defs/DynamicString" + }, + "children": { + "description": "A list of child components to be rendered inside the card content area.", + "$ref": "https://a2ui.org/specification/v0_9/common_types.json#/$defs/ChildList" + } + }, + "required": ["component", "children"] + } + ] + }, + "MaterialIcon": { + "description": "A2UI wrapper for the Angular Material Icon component, used to render icons.", + "allOf": [ + { + "$ref": "#/$defs/MaterialComponentCommon" + }, + { + "type": "object", + "properties": { + "component": { + "const": "MaterialIcon" + }, + "icon": { + "description": "The name of the Material Design icon to render (e.g., 'home', 'search', 'favorite'). It must correspond to a valid name in the Material Icons font set.", + "$ref": "https://a2ui.org/specification/v0_9/common_types.json#/$defs/DynamicString" + }, + "color": { + "description": "The color palette theme to apply to the icon. Supported values are 'primary', 'accent', and 'warn'.", + "$ref": "https://a2ui.org/specification/v0_9/common_types.json#/$defs/DynamicString" + } + }, + "required": ["component", "icon"] + } + ] + }, + "MaterialSelect": { + "description": "A2UI wrapper for the Angular Material Select component, supporting single selection from a list of options.", + "allOf": [ + { + "$ref": "#/$defs/MaterialComponentCommon" + }, + { + "type": "object", + "properties": { + "component": { + "const": "MaterialSelect" + }, + "label": { + "description": "The label text displayed above or inside the select field.", + "$ref": "https://a2ui.org/specification/v0_9/common_types.json#/$defs/DynamicString" + }, + "placeholder": { + "description": "The placeholder text displayed in the select field when no value is selected.", + "$ref": "https://a2ui.org/specification/v0_9/common_types.json#/$defs/DynamicString" + }, + "value": { + "description": "The currently selected value. It supports two-way data binding and triggers updates when the user makes a selection.", + "$ref": "https://a2ui.org/specification/v0_9/common_types.json#/$defs/DynamicString" + }, + "ariaLabel": { + "description": "The ARIA label applied to the select component for accessibility purposes.", + "$ref": "https://a2ui.org/specification/v0_9/common_types.json#/$defs/DynamicString" + }, + "ariaLabelledby": { + "description": "The ID of an element (or space-separated IDs of elements) that labels the select dropdown, providing an accessible name for screen readers.", + "$ref": "https://a2ui.org/specification/v0_9/common_types.json#/$defs/DynamicString" + }, + "ariaDescribedby": { + "description": "The ID of an element (or space-separated IDs of elements) that describes the select dropdown, providing additional context for screen readers.", + "$ref": "https://a2ui.org/specification/v0_9/common_types.json#/$defs/DynamicString" + }, + "disabled": { + "description": "Whether the select component is disabled and cannot be interacted with (true if disabled, otherwise enabled).", + "$ref": "https://a2ui.org/specification/v0_9/common_types.json#/$defs/DynamicBoolean" + }, + "options": { + "description": "The list of options available for selection. Each option is an object containing a 'label' (what the user sees) and a 'value' (the underlying value). This can be a static array or a dynamic data binding.", + "oneOf": [ + { + "type": "array", + "items": { + "$ref": "#/$defs/SelectOption" + } + }, + { + "$ref": "https://a2ui.org/specification/v0_9/common_types.json#/$defs/DataBinding" + } + ] + }, + "checks": { + "description": "An array of validation rules (each containing a dynamic boolean condition and an error message) that are reactively evaluated to determine the input's validity.", + "type": "array", + "items": { + "$ref": "https://a2ui.org/specification/v0_9/common_types.json#/$defs/CheckRule" + } + } + }, + "required": ["component", "options"] + } + ] + }, + "MaterialCheckbox": { + "description": "A2UI wrapper for the Angular Material Checkbox component, supporting boolean state binding.", + "allOf": [ + { + "$ref": "#/$defs/MaterialComponentCommon" + }, + { + "type": "object", + "properties": { + "component": { + "const": "MaterialCheckbox" + }, + "label": { + "description": "The text label to display next to the checkbox.", + "$ref": "https://a2ui.org/specification/v0_9/common_types.json#/$defs/DynamicString" + }, + "checked": { + "description": "Whether the checkbox is currently checked (true if checked, otherwise unchecked). This supports two-way data binding and triggers updates when the state changes.", + "$ref": "https://a2ui.org/specification/v0_9/common_types.json#/$defs/DynamicBoolean" + }, + "disabled": { + "description": "Whether the checkbox is disabled and cannot be interacted with (true if disabled, otherwise enabled).", + "$ref": "https://a2ui.org/specification/v0_9/common_types.json#/$defs/DynamicBoolean" + }, + "color": { + "description": "The theme color of the checkbox. Supported values are 'primary', 'accent', and 'warn'.", + "$ref": "https://a2ui.org/specification/v0_9/common_types.json#/$defs/DynamicString" + }, + "labelPosition": { + "description": "Position of the label relative to the checkbox. Defaults to 'after'.", + "enum": ["before", "after"] + }, + "ariaLabel": { + "description": "The ARIA label applied to the checkbox component for accessibility when no text label is visible.", + "$ref": "https://a2ui.org/specification/v0_9/common_types.json#/$defs/DynamicString" + }, + "ariaLabelledby": { + "description": "The ID of an element (or space-separated IDs of elements) that labels the checkbox, providing an accessible name for screen readers.", + "$ref": "https://a2ui.org/specification/v0_9/common_types.json#/$defs/DynamicString" + }, + "ariaDescribedby": { + "description": "The ID of an element that describes the checkbox, used for assistive technologies.", + "$ref": "https://a2ui.org/specification/v0_9/common_types.json#/$defs/DynamicString" + }, + "tooltip": { + "description": "Tooltip text to show when hovering over the checkbox.", + "$ref": "https://a2ui.org/specification/v0_9/common_types.json#/$defs/DynamicString" + }, + "checks": { + "description": "An array of validation rules (each containing a dynamic boolean condition and an error message) that are reactively evaluated to determine the input's validity.", + "type": "array", + "items": { + "$ref": "https://a2ui.org/specification/v0_9/common_types.json#/$defs/CheckRule" + } + } + }, + "required": ["component"] + } + ] + }, + "MaterialBadge": { + "description": "A2UI container component that wraps children and applies a badge to the container.", + "allOf": [ + { + "$ref": "#/$defs/MaterialComponentCommon" + }, + { + "type": "object", + "properties": { + "component": { + "const": "MaterialBadge" + }, + "text": { + "description": "The text content to display inside the badge. Typically a small number or status character.", + "$ref": "https://a2ui.org/specification/v0_9/common_types.json#/$defs/DynamicString" + }, + "color": { + "description": "The color theme of the badge. Supported values are 'primary', 'accent', and 'warn'.", + "$ref": "https://a2ui.org/specification/v0_9/common_types.json#/$defs/DynamicString" + }, + "position": { + "description": "The position of the badge relative to the element it is attached to. Defaults to 'above after'.", + "enum": ["above after", "above before", "below after", "below before"] + }, + "size": { + "description": "The size of the badge. Defaults to 'medium'.", + "enum": ["small", "medium", "large"] + }, + "overlap": { + "description": "Whether the badge should overlap its parent element content (true if overlapping, otherwise not). Defaults to true.", + "$ref": "https://a2ui.org/specification/v0_9/common_types.json#/$defs/DynamicBoolean" + }, + "disabled": { + "description": "Whether the badge is disabled, which can affect its appearance (true if disabled, otherwise enabled).", + "$ref": "https://a2ui.org/specification/v0_9/common_types.json#/$defs/DynamicBoolean" + }, + "hidden": { + "description": "Whether the badge is hidden (true if hidden, otherwise visible).", + "$ref": "https://a2ui.org/specification/v0_9/common_types.json#/$defs/DynamicBoolean" + }, + "description": { + "description": "A description of the badge, used for accessibility (e.g., screen readers).", + "$ref": "https://a2ui.org/specification/v0_9/common_types.json#/$defs/DynamicString" + }, + "children": { + "description": "The content/elements that the badge is attached to and will be rendered inside the badge container.", + "$ref": "https://a2ui.org/specification/v0_9/common_types.json#/$defs/ChildList" + } + }, + "required": ["component", "children"] + } + ] + }, + "MaterialButtonToggle": { + "description": "A2UI wrapper for the Angular Material Button Toggle component, supporting single selection from a list of options.", + "allOf": [ + { + "$ref": "#/$defs/MaterialComponentCommon" + }, + { + "type": "object", + "properties": { + "component": { + "const": "MaterialButtonToggle" + }, + "value": { + "description": "The currently selected value of the button toggle group. Supports two-way data binding.", + "$ref": "https://a2ui.org/specification/v0_9/common_types.json#/$defs/DynamicString" + }, + "options": { + "description": "The list of toggle options. Each option contains a 'label' to display on the button and an associated 'value' that is set when selected. This can be a static array or a dynamic data binding.", + "oneOf": [ + { + "type": "array", + "items": { + "$ref": "#/$defs/SelectOption" + } + }, + { + "$ref": "https://a2ui.org/specification/v0_9/common_types.json#/$defs/DataBinding" + } + ] + }, + "disabled": { + "description": "Whether the entire button toggle group is disabled and cannot be interacted with (true if disabled, otherwise enabled).", + "$ref": "https://a2ui.org/specification/v0_9/common_types.json#/$defs/DynamicBoolean" + }, + "ariaLabel": { + "description": "The ARIA label for the button toggle group, used for accessibility.", + "$ref": "https://a2ui.org/specification/v0_9/common_types.json#/$defs/DynamicString" + }, + "ariaLabelledby": { + "description": "The ID of an element (or space-separated IDs of elements) that labels the button toggle group, providing an accessible name for screen readers.", + "$ref": "https://a2ui.org/specification/v0_9/common_types.json#/$defs/DynamicString" + }, + "ariaDescribedby": { + "description": "The ID of an element (or space-separated IDs of elements) that describes the button toggle group, providing additional context for screen readers.", + "$ref": "https://a2ui.org/specification/v0_9/common_types.json#/$defs/DynamicString" + }, + "appearance": { + "description": "The visual style of the buttons. Defaults to 'standard'.", + "enum": ["legacy", "standard"] + }, + "vertical": { + "description": "Whether the buttons in the group should be stacked vertically instead of horizontally (true if vertical, otherwise horizontal).", + "$ref": "https://a2ui.org/specification/v0_9/common_types.json#/$defs/DynamicBoolean" + } + }, + "required": ["component", "options"] + } + ] + }, + "MaterialChips": { + "description": "A2UI wrapper for the Angular Material Chips component, supporting single selection from a list of chip options.", + "allOf": [ + { + "$ref": "#/$defs/MaterialComponentCommon" + }, + { + "type": "object", + "properties": { + "component": { + "const": "MaterialChips" + }, + "value": { + "description": "The value of the currently selected chip. Supports two-way data binding.", + "$ref": "https://a2ui.org/specification/v0_9/common_types.json#/$defs/DynamicString" + }, + "options": { + "description": "The list of chip options. Each chip contains a 'label' to display and an associated 'value' that is set when the chip is selected. This can be a static array or a dynamic data binding.", + "oneOf": [ + { + "type": "array", + "items": { + "$ref": "#/$defs/SelectOption" + } + }, + { + "$ref": "https://a2ui.org/specification/v0_9/common_types.json#/$defs/DataBinding" + } + ] + }, + "disabled": { + "description": "Whether the entire chip list is disabled and cannot be interacted with (true if disabled, otherwise enabled).", + "$ref": "https://a2ui.org/specification/v0_9/common_types.json#/$defs/DynamicBoolean" + }, + "ariaLabel": { + "description": "The ARIA label for the chip list, used for accessibility.", + "$ref": "https://a2ui.org/specification/v0_9/common_types.json#/$defs/DynamicString" + }, + "ariaLabelledby": { + "description": "The ID of an element (or space-separated IDs of elements) that labels the chips component, providing an accessible name for screen readers.", + "$ref": "https://a2ui.org/specification/v0_9/common_types.json#/$defs/DynamicString" + }, + "ariaDescribedby": { + "description": "The ID of an element (or space-separated IDs of elements) that describes the chips component, providing additional context for screen readers.", + "$ref": "https://a2ui.org/specification/v0_9/common_types.json#/$defs/DynamicString" + }, + "action": { + "description": "The action to dispatch when a chip is selected.", + "$ref": "https://a2ui.org/specification/v0_9/common_types.json#/$defs/Action" + } + }, + "required": ["component", "options"] + } + ] + }, + "MaterialDatepicker": { + "description": "A2UI wrapper for the Angular Material Datepicker component, supporting picking a date from a calendar popup.", + "allOf": [ + { + "$ref": "#/$defs/MaterialComponentCommon" + }, + { + "type": "object", + "properties": { + "component": { + "const": "MaterialDatepicker" + }, + "label": { + "description": "The label text displayed above or inside the datepicker input field.", + "$ref": "https://a2ui.org/specification/v0_9/common_types.json#/$defs/DynamicString" + }, + "placeholder": { + "description": "The placeholder text displayed inside the datepicker input field when it is empty.", + "$ref": "https://a2ui.org/specification/v0_9/common_types.json#/$defs/DynamicString" + }, + "value": { + "description": "The currently selected date value. Supports two-way data binding and is updated with the local date object (containing year, month, and day) when a date is picked.", + "$ref": "#/$defs/DynamicDate" + }, + "ariaLabelledby": { + "description": "The ID of an element (or space-separated IDs of elements) that labels the datepicker, providing an accessible name for screen readers.", + "$ref": "https://a2ui.org/specification/v0_9/common_types.json#/$defs/DynamicString" + }, + "ariaDescribedby": { + "description": "The ID of an element that describes the datepicker input, used for accessibility.", + "$ref": "https://a2ui.org/specification/v0_9/common_types.json#/$defs/DynamicString" + }, + "ariaLabel": { + "description": "The ARIA label applied to the datepicker input for accessibility.", + "$ref": "https://a2ui.org/specification/v0_9/common_types.json#/$defs/DynamicString" + }, + "disabled": { + "description": "Whether the datepicker is disabled and cannot be interacted with (true if disabled, otherwise enabled).", + "$ref": "https://a2ui.org/specification/v0_9/common_types.json#/$defs/DynamicBoolean" + }, + "checks": { + "description": "An array of validation rules (each containing a dynamic boolean condition and an error message) that are reactively evaluated to determine the input's validity.", + "type": "array", + "items": { + "$ref": "https://a2ui.org/specification/v0_9/common_types.json#/$defs/CheckRule" + } + } + }, + "required": ["component"] + } + ] + }, + "MaterialDialog": { + "description": "A2UI wrapper for the Angular Material Dialog component. Renders children inside a popup dialog.", + "allOf": [ + { + "$ref": "#/$defs/MaterialComponentCommon" + }, + { + "type": "object", + "properties": { + "component": { + "const": "MaterialDialog" + }, + "open": { + "description": "Whether the dialog is open (true if open, otherwise closed). It supports two-way binding and will automatically update to false when the dialog is dismissed by the user.", + "$ref": "https://a2ui.org/specification/v0_9/common_types.json#/$defs/DynamicBoolean" + }, + "title": { + "description": "The text header displayed at the top of the dialog.", + "$ref": "https://a2ui.org/specification/v0_9/common_types.json#/$defs/DynamicString" + }, + "disableClose": { + "description": "Whether closing the dialog by clicking outside of it or pressing the Escape key is disabled (true if disabled, otherwise enabled).", + "$ref": "https://a2ui.org/specification/v0_9/common_types.json#/$defs/DynamicBoolean" + }, + "width": { + "description": "The width of the dialog container, specified as a CSS value (e.g., '500px', '50vw').", + "$ref": "https://a2ui.org/specification/v0_9/common_types.json#/$defs/DynamicString" + }, + "height": { + "description": "The height of the dialog container, specified as a CSS value (e.g., '400px', '50vh').", + "$ref": "https://a2ui.org/specification/v0_9/common_types.json#/$defs/DynamicString" + }, + "ariaLabel": { + "description": "The ARIA label used for accessibility to describe the dialog to screen readers.", + "$ref": "https://a2ui.org/specification/v0_9/common_types.json#/$defs/DynamicString" + }, + "ariaLabelledby": { + "description": "The ID of an element (or space-separated IDs of elements) that labels the dialog, providing an accessible name for screen readers.", + "$ref": "https://a2ui.org/specification/v0_9/common_types.json#/$defs/DynamicString" + }, + "ariaDescribedby": { + "description": "The ID of an element (or space-separated IDs of elements) that describes the dialog, providing additional context for screen readers.", + "$ref": "https://a2ui.org/specification/v0_9/common_types.json#/$defs/DynamicString" + }, + "children": { + "description": "A list of child components to be rendered inside the body of the dialog.", + "$ref": "https://a2ui.org/specification/v0_9/common_types.json#/$defs/ChildList" + } + }, + "required": ["component", "children"] + } + ] + }, + "MaterialDivider": { + "description": "A2UI wrapper for the Angular Material Divider component. Renders a dividing line.", + "allOf": [ + { + "$ref": "#/$defs/MaterialComponentCommon" + }, + { + "type": "object", + "properties": { + "component": { + "const": "MaterialDivider" + }, + "inset": { + "description": "Whether the divider has an inset margin at the start, typically used to align it with text content (true if inset, otherwise full-width).", + "$ref": "https://a2ui.org/specification/v0_9/common_types.json#/$defs/DynamicBoolean" + }, + "vertical": { + "description": "Whether the divider should be oriented vertically instead of horizontally (true if vertical, otherwise horizontal).", + "$ref": "https://a2ui.org/specification/v0_9/common_types.json#/$defs/DynamicBoolean" + } + }, + "required": ["component"] + } + ] + }, + "MaterialExpansionPanel": { + "description": "A2UI wrapper for the Angular Material Expansion Panel component. Supports expanding and collapsing content.", + "allOf": [ + { + "$ref": "#/$defs/MaterialComponentCommon" + }, + { + "type": "object", + "properties": { + "component": { + "const": "MaterialExpansionPanel" + }, + "expanded": { + "description": "Whether the panel is expanded (true if expanded, otherwise collapsed). It supports two-way binding and updates automatically when the user toggles the panel.", + "$ref": "https://a2ui.org/specification/v0_9/common_types.json#/$defs/DynamicBoolean" + }, + "title": { + "description": "The primary text displayed in the expansion panel's header.", + "$ref": "https://a2ui.org/specification/v0_9/common_types.json#/$defs/DynamicString" + }, + "description": { + "description": "Secondary summary text displayed in the panel header, typically providing additional context or status.", + "$ref": "https://a2ui.org/specification/v0_9/common_types.json#/$defs/DynamicString" + }, + "disabled": { + "description": "Whether the expansion panel is disabled, preventing the user from expanding or collapsing it (true if disabled, otherwise enabled).", + "$ref": "https://a2ui.org/specification/v0_9/common_types.json#/$defs/DynamicBoolean" + }, + "ariaLabel": { + "description": "The ARIA label used for accessibility to describe the expansion panel to screen readers.", + "$ref": "https://a2ui.org/specification/v0_9/common_types.json#/$defs/DynamicString" + }, + "ariaLabelledby": { + "description": "The ID of an element (or space-separated IDs of elements) that labels the expansion panel, providing an accessible name for screen readers.", + "$ref": "https://a2ui.org/specification/v0_9/common_types.json#/$defs/DynamicString" + }, + "ariaDescribedby": { + "description": "The ID of an element (or space-separated IDs of elements) that describes the expansion panel, providing additional context for screen readers.", + "$ref": "https://a2ui.org/specification/v0_9/common_types.json#/$defs/DynamicString" + }, + "children": { + "description": "A list of child components to be rendered inside the expandable body of the panel.", + "$ref": "https://a2ui.org/specification/v0_9/common_types.json#/$defs/ChildList" + } + }, + "required": ["component", "children"] + } + ] + }, + "MaterialGridList": { + "description": "A2UI container component for grid layout. Arranges child components into tiles.", + "allOf": [ + { + "$ref": "#/$defs/MaterialComponentCommon" + }, + { + "type": "object", + "properties": { + "component": { + "const": "MaterialGridList" + }, + "children": { + "description": "A list of child components to be rendered as individual tiles within the grid.", + "$ref": "https://a2ui.org/specification/v0_9/common_types.json#/$defs/ChildList" + }, + "cols": { + "description": "The number of columns in the grid list. Defaults to 2.", + "$ref": "https://a2ui.org/specification/v0_9/common_types.json#/$defs/DynamicNumber" + }, + "rowHeight": { + "description": "The height of each row in the grid. Can be a fixed pixel value (e.g., '100px'), a ratio (e.g., '4:3', '1:1'), or 'fit' to automatically adjust based on container height. Defaults to '1:1'.", + "$ref": "https://a2ui.org/specification/v0_9/common_types.json#/$defs/DynamicString" + }, + "gutterSize": { + "description": "The size of the spacing (gutter) between grid tiles, specified as a CSS value (e.g., '8px', '1rem'). Defaults to '1px'.", + "$ref": "https://a2ui.org/specification/v0_9/common_types.json#/$defs/DynamicString" + } + }, + "required": ["component", "children"] + } + ] + }, + "MaterialMenu": { + "description": "A2UI wrapper for the Angular Material Menu component. Provides a trigger button and dropdown menu items.", + "allOf": [ + { + "$ref": "#/$defs/MaterialComponentCommon" + }, + { + "type": "object", + "properties": { + "component": { + "const": "MaterialMenu" + }, + "label": { + "description": "The text label displayed on the menu trigger button.", + "$ref": "https://a2ui.org/specification/v0_9/common_types.json#/$defs/DynamicString" + }, + "icon": { + "description": "Optional name of the icon (e.g., from Material Icons) to display inside the menu trigger button, alongside or instead of the label.", + "$ref": "https://a2ui.org/specification/v0_9/common_types.json#/$defs/DynamicString" + }, + "disabled": { + "description": "Whether the menu trigger button is disabled, preventing the user from opening the menu (true if disabled, otherwise enabled).", + "$ref": "https://a2ui.org/specification/v0_9/common_types.json#/$defs/DynamicBoolean" + }, + "value": { + "description": "The value of the currently selected menu option. It supports two-way binding and updates when a menu item is clicked.", + "$ref": "https://a2ui.org/specification/v0_9/common_types.json#/$defs/DynamicString" + }, + "options": { + "description": "An array of options to display in the menu, where each option has a 'label' and a 'value', or a data binding to such an array.", + "oneOf": [ + { + "type": "array", + "items": { + "$ref": "#/$defs/SelectOption" + } + }, + { + "$ref": "https://a2ui.org/specification/v0_9/common_types.json#/$defs/DataBinding" + } + ] + }, + "action": { + "description": "The action to dispatch when a menu item is clicked. The action is triggered after the selected value is updated.", + "$ref": "https://a2ui.org/specification/v0_9/common_types.json#/$defs/Action" + }, + "ariaLabel": { + "description": "The ARIA label used for accessibility to describe the menu trigger button to screen readers.", + "$ref": "https://a2ui.org/specification/v0_9/common_types.json#/$defs/DynamicString" + }, + "ariaLabelledby": { + "description": "The ID of an element (or space-separated IDs of elements) that labels the menu, providing an accessible name for screen readers.", + "$ref": "https://a2ui.org/specification/v0_9/common_types.json#/$defs/DynamicString" + }, + "ariaDescribedby": { + "description": "The ID of an element (or space-separated IDs of elements) that describes the menu, providing additional context for screen readers.", + "$ref": "https://a2ui.org/specification/v0_9/common_types.json#/$defs/DynamicString" + } + }, + "required": ["component", "options"] + } + ] + }, + "MaterialProgressBar": { + "description": "A2UI wrapper for the Angular Material Progress Bar component.", + "allOf": [ + { + "$ref": "#/$defs/MaterialComponentCommon" + }, + { + "type": "object", + "properties": { + "component": { + "const": "MaterialProgressBar" + }, + "value": { + "description": "The current progress value of the progress bar, expected to be between 0 and 100. Defaults to 0. Only used in 'determinate' and 'buffer' modes.", + "$ref": "https://a2ui.org/specification/v0_9/common_types.json#/$defs/DynamicNumber" + }, + "mode": { + "description": "The progress display mode. Can be 'determinate', 'indeterminate', 'buffer', or 'query'. Defaults to 'determinate'.", + "$ref": "https://a2ui.org/specification/v0_9/common_types.json#/$defs/DynamicString" + }, + "bufferValue": { + "description": "The buffer progress value, expected to be between 0 and 100. Defaults to 0. Only used when the mode is set to 'buffer'.", + "$ref": "https://a2ui.org/specification/v0_9/common_types.json#/$defs/DynamicNumber" + }, + "color": { + "description": "Theme color palette for the progress bar. Can be 'primary', 'accent', or 'warn'.", + "$ref": "https://a2ui.org/specification/v0_9/common_types.json#/$defs/DynamicString" + }, + "ariaLabel": { + "description": "Accessible label for the progress bar, used by screen readers to describe what progress is being made.", + "$ref": "https://a2ui.org/specification/v0_9/common_types.json#/$defs/DynamicString" + }, + "ariaLabelledby": { + "description": "The ID of an element (or space-separated IDs of elements) that labels the progress bar, providing an accessible name for screen readers.", + "$ref": "https://a2ui.org/specification/v0_9/common_types.json#/$defs/DynamicString" + } + }, + "required": ["component"] + } + ] + }, + "MaterialProgressSpinner": { + "description": "A2UI wrapper for the Angular Material Progress Spinner component.", + "allOf": [ + { + "$ref": "#/$defs/MaterialComponentCommon" + }, + { + "type": "object", + "properties": { + "component": { + "const": "MaterialProgressSpinner" + }, + "value": { + "description": "The current progress value of the spinner, expected to be between 0 and 100. Defaults to 0. Only used in 'determinate' mode.", + "$ref": "https://a2ui.org/specification/v0_9/common_types.json#/$defs/DynamicNumber" + }, + "mode": { + "description": "The progress display mode. Can be 'determinate' or 'indeterminate'. Defaults to 'determinate'.", + "$ref": "https://a2ui.org/specification/v0_9/common_types.json#/$defs/DynamicString" + }, + "diameter": { + "description": "The diameter of the spinner in pixels. Defaults to 40.", + "$ref": "https://a2ui.org/specification/v0_9/common_types.json#/$defs/DynamicNumber" + }, + "strokeWidth": { + "description": "The thickness of the spinner's stroke in pixels. Defaults to 4.", + "$ref": "https://a2ui.org/specification/v0_9/common_types.json#/$defs/DynamicNumber" + }, + "color": { + "description": "Theme color palette for the spinner. Can be 'primary', 'accent', or 'warn'.", + "$ref": "https://a2ui.org/specification/v0_9/common_types.json#/$defs/DynamicString" + }, + "ariaLabel": { + "description": "Accessible label for the spinner, used by screen readers to describe what progress is being made.", + "$ref": "https://a2ui.org/specification/v0_9/common_types.json#/$defs/DynamicString" + }, + "ariaLabelledby": { + "description": "The ID of an element (or space-separated IDs of elements) that labels the progress spinner, providing an accessible name for screen readers.", + "$ref": "https://a2ui.org/specification/v0_9/common_types.json#/$defs/DynamicString" + } + }, + "required": ["component"] + } + ] + }, + "MaterialRadioButton": { + "description": "A2UI wrapper for the Angular Material Radio Button component.", + "allOf": [ + { + "$ref": "#/$defs/MaterialComponentCommon" + }, + { + "type": "object", + "properties": { + "component": { + "const": "MaterialRadioButton" + }, + "value": { + "description": "The value of the currently selected radio button. Updating this property changes the selected option, and it is updated when the user makes a selection.", + "$ref": "https://a2ui.org/specification/v0_9/common_types.json#/$defs/DynamicString" + }, + "options": { + "description": "The list of options to display in the radio button group, where each option has a display label and a corresponding string value.", + "oneOf": [ + { + "type": "array", + "items": { + "$ref": "#/$defs/SelectOption" + } + }, + { + "$ref": "https://a2ui.org/specification/v0_9/common_types.json#/$defs/DataBinding" + } + ] + }, + "disabled": { + "description": "Whether the entire radio button group is disabled, preventing user interaction (true if disabled, otherwise enabled).", + "$ref": "https://a2ui.org/specification/v0_9/common_types.json#/$defs/DynamicBoolean" + }, + "ariaLabel": { + "description": "The accessibility label (ARIA label) for the radio button group, used by screen readers to describe its purpose.", + "$ref": "https://a2ui.org/specification/v0_9/common_types.json#/$defs/DynamicString" + }, + "ariaLabelledby": { + "description": "The ID of an element (or space-separated IDs of elements) that labels the radio button, providing an accessible name for screen readers.", + "$ref": "https://a2ui.org/specification/v0_9/common_types.json#/$defs/DynamicString" + }, + "ariaDescribedby": { + "description": "The ID of an element (or space-separated IDs of elements) that describes the radio button, providing additional context for screen readers.", + "$ref": "https://a2ui.org/specification/v0_9/common_types.json#/$defs/DynamicString" + }, + "color": { + "description": "The theme color palette for the radio buttons. Expected values are 'primary', 'accent', or 'warn'.", + "$ref": "https://a2ui.org/specification/v0_9/common_types.json#/$defs/DynamicString" + }, + "labelPosition": { + "description": "Position of the label relative to the radio button indicator. Defaults to 'after'.", + "enum": ["before", "after"] + } + }, + "required": ["component", "options"] + } + ] + }, + "MaterialSlideToggle": { + "description": "A2UI wrapper for the Angular Material Slide Toggle component, supporting boolean state binding.", + "allOf": [ + { + "$ref": "#/$defs/MaterialComponentCommon" + }, + { + "type": "object", + "properties": { + "component": { + "const": "MaterialSlideToggle" + }, + "label": { + "description": "The text label displayed alongside the slide toggle.", + "$ref": "https://a2ui.org/specification/v0_9/common_types.json#/$defs/DynamicString" + }, + "checked": { + "description": "Whether the slide toggle is checked (true if checked, otherwise unchecked). Supports two-way binding to track user toggle actions.", + "$ref": "https://a2ui.org/specification/v0_9/common_types.json#/$defs/DynamicBoolean" + }, + "disabled": { + "description": "Whether the slide toggle is disabled and cannot be interacted with (true if disabled, otherwise enabled).", + "$ref": "https://a2ui.org/specification/v0_9/common_types.json#/$defs/DynamicBoolean" + }, + "color": { + "description": "The theme color palette for the slide toggle. Expected values are 'primary', 'accent', or 'warn'.", + "$ref": "https://a2ui.org/specification/v0_9/common_types.json#/$defs/DynamicString" + }, + "labelPosition": { + "description": "Position of the label relative to the slide toggle switch. Defaults to 'after'.", + "enum": ["before", "after"] + }, + "ariaLabel": { + "description": "The accessibility label (ARIA label) for the slide toggle switch, used by screen readers.", + "$ref": "https://a2ui.org/specification/v0_9/common_types.json#/$defs/DynamicString" + }, + "ariaLabelledby": { + "description": "The ID of an element (or space-separated IDs of elements) that labels the slide toggle, providing an accessible name for screen readers.", + "$ref": "https://a2ui.org/specification/v0_9/common_types.json#/$defs/DynamicString" + }, + "ariaDescribedby": { + "description": "The ID of an element that describes the slide toggle, used to provide additional accessibility context.", + "$ref": "https://a2ui.org/specification/v0_9/common_types.json#/$defs/DynamicString" + }, + "tooltip": { + "description": "Tooltip text displayed when the user hovers over the slide toggle.", + "$ref": "https://a2ui.org/specification/v0_9/common_types.json#/$defs/DynamicString" + }, + "required": { + "description": "Whether the slide toggle is required (true if required, otherwise optional).", + "$ref": "https://a2ui.org/specification/v0_9/common_types.json#/$defs/DynamicBoolean" + } + }, + "required": ["component"] + } + ] + }, + "MaterialSlider": { + "description": "A2UI wrapper for the Angular Material Slider component.", + "allOf": [ + { + "$ref": "#/$defs/MaterialComponentCommon" + }, + { + "type": "object", + "properties": { + "component": { + "const": "MaterialSlider" + }, + "value": { + "description": "The current numeric value of the slider. It supports two-way binding and is updated as the user drags the slider thumb.", + "$ref": "https://a2ui.org/specification/v0_9/common_types.json#/$defs/DynamicNumber" + }, + "min": { + "description": "The minimum allowable numeric value for the slider. Defaults to 0.", + "$ref": "https://a2ui.org/specification/v0_9/common_types.json#/$defs/DynamicNumber" + }, + "max": { + "description": "The maximum allowable numeric value for the slider. Defaults to 100.", + "$ref": "https://a2ui.org/specification/v0_9/common_types.json#/$defs/DynamicNumber" + }, + "step": { + "description": "The size of each increment or decrement step when moving the slider. Defaults to 1.", + "$ref": "https://a2ui.org/specification/v0_9/common_types.json#/$defs/DynamicNumber" + }, + "disabled": { + "description": "Whether the slider is disabled, preventing any user interaction (true if disabled, otherwise enabled).", + "$ref": "https://a2ui.org/specification/v0_9/common_types.json#/$defs/DynamicBoolean" + }, + "color": { + "description": "The theme color palette for the slider. Expected values are 'primary', 'accent', or 'warn'.", + "$ref": "https://a2ui.org/specification/v0_9/common_types.json#/$defs/DynamicString" + }, + "ariaLabel": { + "description": "The accessibility label (ARIA label) for the slider, helping screen reader users understand its purpose.", + "$ref": "https://a2ui.org/specification/v0_9/common_types.json#/$defs/DynamicString" + }, + "ariaLabelledby": { + "description": "The ID of an element (or space-separated IDs of elements) that labels the slider, providing an accessible name for screen readers.", + "$ref": "https://a2ui.org/specification/v0_9/common_types.json#/$defs/DynamicString" + }, + "ariaDescribedby": { + "description": "The ID of an element (or space-separated IDs of elements) that describes the slider, providing additional context for screen readers.", + "$ref": "https://a2ui.org/specification/v0_9/common_types.json#/$defs/DynamicString" + } + }, + "required": ["component"] + } + ] + }, + "MaterialTable": { + "description": "A2UI wrapper for the Angular Material Table component.", + "allOf": [ + { + "$ref": "#/$defs/MaterialComponentCommon" + }, + { + "type": "object", + "properties": { + "component": { + "const": "MaterialTable" + }, + "columns": { + "description": "The definition of the columns to display in the table. Each column object requires a 'header' (display text for the column header) and a 'field' (the key in the row data used to populate this column).", + "type": "array", + "items": { + "type": "object", + "properties": { + "header": { + "description": "The display text for the column header.", + "type": "string" + }, + "field": { + "description": "The key in the row data used to populate this column.", + "type": "string" + } + }, + "required": ["header", "field"] + } + }, + "rows": { + "description": "The data source representing the rows of the table. Each row is an object where the keys correspond to the 'field' properties of the defined columns.", + "oneOf": [ + { + "type": "array", + "items": { + "type": "object", + "additionalProperties": { + "type": "string" + } + } + }, + { + "$ref": "https://a2ui.org/specification/v0_9/common_types.json#/$defs/DataBinding" + } + ] + }, + "ariaLabel": { + "description": "The accessibility label (ARIA label) for the table, used by screen readers to describe the table content.", + "$ref": "https://a2ui.org/specification/v0_9/common_types.json#/$defs/DynamicString" + }, + "caption": { + "description": "A text caption or title displayed for the table, providing description or context for screen readers.", + "$ref": "https://a2ui.org/specification/v0_9/common_types.json#/$defs/DynamicString" + }, + "ariaLabelledby": { + "description": "The ID of an element that labels the table, providing an accessible name for screen readers.", + "$ref": "https://a2ui.org/specification/v0_9/common_types.json#/$defs/DynamicString" + } + }, + "required": ["component", "columns", "rows"] + } + ] + }, + "MaterialTabs": { + "description": "A2UI wrapper for the Angular Material Tabs component.", + "allOf": [ + { + "$ref": "#/$defs/MaterialComponentCommon" + }, + { + "type": "object", + "properties": { + "component": { + "const": "MaterialTabs" + }, + "tabs": { + "description": "The list of tabs to display. Each tab requires a 'label' (the text displayed on the tab header) and a 'content' property containing the ID of the component to render when this tab is selected.", + "type": "array", + "items": { + "type": "object", + "properties": { + "label": { + "description": "The text displayed on the tab header.", + "type": "string" + }, + "content": { + "description": "The ID of the component to render when this tab is selected.", + "$ref": "https://a2ui.org/specification/v0_9/common_types.json#/$defs/ComponentId" + } + }, + "required": ["label", "content"] + } + }, + "activeTab": { + "description": "The index of the currently active tab (0-indexed). Supports two-way binding to update when the user switches tabs.", + "$ref": "https://a2ui.org/specification/v0_9/common_types.json#/$defs/DynamicNumber" + }, + "ariaLabel": { + "description": "The ARIA label used for accessibility to describe the tabs component to screen readers.", + "$ref": "https://a2ui.org/specification/v0_9/common_types.json#/$defs/DynamicString" + }, + "ariaLabelledby": { + "description": "The ID of an element (or space-separated IDs of elements) that labels the tabs component, providing an accessible name for screen readers.", + "$ref": "https://a2ui.org/specification/v0_9/common_types.json#/$defs/DynamicString" + } + }, + "required": ["component", "tabs"] + } + ] + }, + "MaterialTimepicker": { + "description": "A2UI wrapper for the Angular Material Timepicker component.", + "allOf": [ + { + "$ref": "#/$defs/MaterialComponentCommon" + }, + { + "type": "object", + "properties": { + "component": { + "const": "MaterialTimepicker" + }, + "label": { + "description": "The text label displayed above or inside the timepicker input field.", + "$ref": "https://a2ui.org/specification/v0_9/common_types.json#/$defs/DynamicString" + }, + "placeholder": { + "description": "The placeholder text shown in the input field when no time is selected.", + "$ref": "https://a2ui.org/specification/v0_9/common_types.json#/$defs/DynamicString" + }, + "value": { + "description": "The selected time value, represented as an ISO 8601 string. Supports two-way binding to update when the user selects a time.", + "$ref": "#/$defs/DynamicDateTime" + }, + "ariaLabelledby": { + "description": "The ID of an element (or space-separated IDs of elements) that labels the timepicker, providing an accessible name for screen readers.", + "$ref": "https://a2ui.org/specification/v0_9/common_types.json#/$defs/DynamicString" + }, + "ariaDescribedby": { + "description": "The ID of an element that describes the timepicker, providing additional accessibility context.", + "$ref": "https://a2ui.org/specification/v0_9/common_types.json#/$defs/DynamicString" + }, + "ariaLabel": { + "description": "The accessibility label (ARIA label) for the timepicker input, used by screen readers.", + "$ref": "https://a2ui.org/specification/v0_9/common_types.json#/$defs/DynamicString" + }, + "disabled": { + "description": "Whether the timepicker is disabled, preventing user selection or input (true if disabled, otherwise enabled).", + "$ref": "https://a2ui.org/specification/v0_9/common_types.json#/$defs/DynamicBoolean" + }, + "checks": { + "description": "An array of validation rules (each containing a dynamic boolean condition and an error message) that are reactively evaluated to determine the input's validity.", + "type": "array", + "items": { + "$ref": "https://a2ui.org/specification/v0_9/common_types.json#/$defs/CheckRule" + } + } + }, + "required": ["component"] + } + ] + }, + "MaterialImage": { + "description": "A2UI component for rendering an image in a Material Design context.", + "allOf": [ + { + "$ref": "#/$defs/MaterialComponentCommon" + }, + { + "type": "object", + "properties": { + "component": { + "const": "MaterialImage" + }, + "url": { + "description": "The source URL of the image to be displayed.", + "$ref": "https://a2ui.org/specification/v0_9/common_types.json#/$defs/DynamicString" + }, + "alt": { + "description": "Alternative text describing the image content for accessibility and screen readers.", + "$ref": "https://a2ui.org/specification/v0_9/common_types.json#/$defs/DynamicString" + }, + "fit": { + "description": "Specifies how the image should be resized to fit its container, corresponding to the CSS 'object-fit' property.", + "enum": ["fill", "contain", "cover", "scaleDown", "none"] + }, + "width": { + "description": "The width of the image element (e.g., '100%', '300px').", + "$ref": "https://a2ui.org/specification/v0_9/common_types.json#/$defs/DynamicString" + }, + "height": { + "description": "The height of the image element (e.g., 'auto', '200px').", + "$ref": "https://a2ui.org/specification/v0_9/common_types.json#/$defs/DynamicString" + }, + "aspectRatio": { + "description": "The preferred aspect ratio for the image, expressed as a ratio (e.g., '16/9', '1').", + "$ref": "https://a2ui.org/specification/v0_9/common_types.json#/$defs/DynamicString" + }, + "roundedCorners": { + "description": "Whether the image has rounded corners (true if rounded, otherwise not).", + "$ref": "https://a2ui.org/specification/v0_9/common_types.json#/$defs/DynamicBoolean" + }, + "borderRadius": { + "description": "A custom border-radius value to apply to the image (e.g., '8px', '50%'). Overrides roundedCorners if both are specified.", + "$ref": "https://a2ui.org/specification/v0_9/common_types.json#/$defs/DynamicString" + } + }, + "required": ["component", "url"] + } + ] + }, + "Text": { + "type": "object", + "allOf": [ + { + "$ref": "https://a2ui.org/specification/v0_9/common_types.json#/$defs/ComponentCommon" + }, + { + "$ref": "#/$defs/CatalogComponentCommon" + }, + { + "type": "object", + "properties": { + "component": { + "const": "Text" + }, + "text": { + "$ref": "https://a2ui.org/specification/v0_9/common_types.json#/$defs/DynamicString", + "description": "The text content to display. While simple Markdown formatting is supported (i.e. without HTML, images, or links), utilizing dedicated UI components is generally preferred for a richer and more structured presentation." + }, + "variant": { + "type": "string", + "description": "A hint for the base text style.", + "enum": ["h1", "h2", "h3", "h4", "h5", "caption", "body"], + "default": "body" + } + }, + "required": ["component", "text"] + } + ], + "unevaluatedProperties": false + }, + "Image": { + "type": "object", + "allOf": [ + { + "$ref": "https://a2ui.org/specification/v0_9/common_types.json#/$defs/ComponentCommon" + }, + { + "$ref": "#/$defs/CatalogComponentCommon" + }, + { + "type": "object", + "properties": { + "component": { + "const": "Image" + }, + "url": { + "$ref": "https://a2ui.org/specification/v0_9/common_types.json#/$defs/DynamicString", + "description": "The URL of the image to display." + }, + "description": { + "$ref": "https://a2ui.org/specification/v0_9/common_types.json#/$defs/DynamicString", + "description": "Accessibility text for the image." + }, + "fit": { + "type": "string", + "description": "Specifies how the image should be resized to fit its container. This corresponds to the CSS 'object-fit' property.", + "enum": ["contain", "cover", "fill", "none", "scaleDown"], + "default": "fill" + }, + "variant": { + "type": "string", + "description": "A hint for the image size and style.", + "enum": ["icon", "avatar", "smallFeature", "mediumFeature", "largeFeature", "header"], + "default": "mediumFeature" + } + }, + "required": ["component", "url"] + } + ], + "unevaluatedProperties": false + }, + "Icon": { + "type": "object", + "allOf": [ + { + "$ref": "https://a2ui.org/specification/v0_9/common_types.json#/$defs/ComponentCommon" + }, + { + "$ref": "#/$defs/CatalogComponentCommon" + }, + { + "type": "object", + "properties": { + "component": { + "const": "Icon" + }, + "name": { + "description": "The name of the icon to display.", + "oneOf": [ + { + "type": "string", + "enum": [ + "accountCircle", + "add", + "arrowBack", + "arrowForward", + "attachFile", + "calendarToday", + "call", + "camera", + "check", + "close", + "delete", + "download", + "edit", + "event", + "error", + "fastForward", + "favorite", + "favoriteOff", + "folder", + "help", + "home", + "info", + "locationOn", + "lock", + "lockOpen", + "mail", + "menu", + "moreVert", + "moreHoriz", + "notificationsOff", + "notifications", + "pause", + "payment", + "person", + "phone", + "photo", + "play", + "print", + "refresh", + "rewind", + "search", + "send", + "settings", + "share", + "shoppingCart", + "skipNext", + "skipPrevious", + "star", + "starHalf", + "starOff", + "stop", + "upload", + "visibility", + "visibilityOff", + "volumeDown", + "volumeMute", + "volumeOff", + "volumeUp", + "warning" + ] + }, + { + "type": "object", + "properties": { + "svgPath": { + "type": "string" + } + }, + "required": ["svgPath"], + "additionalProperties": false + }, + { + "$ref": "https://a2ui.org/specification/v0_9/common_types.json#/$defs/DataBinding" + } + ] + } + }, + "required": ["component", "name"] + } + ], + "unevaluatedProperties": false + }, + "Video": { + "type": "object", + "allOf": [ + { + "$ref": "https://a2ui.org/specification/v0_9/common_types.json#/$defs/ComponentCommon" + }, + { + "$ref": "#/$defs/CatalogComponentCommon" + }, + { + "type": "object", + "properties": { + "component": { + "const": "Video" + }, + "url": { + "$ref": "https://a2ui.org/specification/v0_9/common_types.json#/$defs/DynamicString", + "description": "The URL of the video to display." + } + }, + "required": ["component", "url"] + } + ], + "unevaluatedProperties": false + }, + "AudioPlayer": { + "type": "object", + "allOf": [ + { + "$ref": "https://a2ui.org/specification/v0_9/common_types.json#/$defs/ComponentCommon" + }, + { + "$ref": "#/$defs/CatalogComponentCommon" + }, + { + "type": "object", + "properties": { + "component": { + "const": "AudioPlayer" + }, + "url": { + "$ref": "https://a2ui.org/specification/v0_9/common_types.json#/$defs/DynamicString", + "description": "The URL of the audio to be played." + }, + "description": { + "description": "A description of the audio, such as a title or summary.", + "$ref": "https://a2ui.org/specification/v0_9/common_types.json#/$defs/DynamicString" + } + }, + "required": ["component", "url"] + } + ], + "unevaluatedProperties": false + }, + "Row": { + "type": "object", + "allOf": [ + { + "$ref": "https://a2ui.org/specification/v0_9/common_types.json#/$defs/ComponentCommon" + }, + { + "$ref": "#/$defs/CatalogComponentCommon" + }, + { + "type": "object", + "description": "A layout component that arranges its children horizontally. To create a grid layout, nest Columns within this Row.", + "properties": { + "component": { + "const": "Row" + }, + "children": { + "description": "Defines the children. Use an array of strings for a fixed set of children, or a template object to generate children from a data list. Children cannot be defined inline, they must be referred to by ID.", + "$ref": "https://a2ui.org/specification/v0_9/common_types.json#/$defs/ChildList" + }, + "justify": { + "type": "string", + "description": "Defines the arrangement of children along the main axis (horizontally). Use 'spaceBetween' to push items to the edges, or 'start'/'end'/'center' to pack them together.", + "enum": [ + "center", + "end", + "spaceAround", + "spaceBetween", + "spaceEvenly", + "start", + "stretch" + ], + "default": "start" + }, + "align": { + "type": "string", + "description": "Defines the alignment of children along the cross axis (vertically). This is similar to the CSS 'align-items' property, but uses camelCase values (e.g., 'start').", + "enum": ["start", "center", "end", "stretch"], + "default": "stretch" + } + }, + "required": ["component", "children"] + } + ], + "unevaluatedProperties": false + }, + "Column": { + "type": "object", + "allOf": [ + { + "$ref": "https://a2ui.org/specification/v0_9/common_types.json#/$defs/ComponentCommon" + }, + { + "$ref": "#/$defs/CatalogComponentCommon" + }, + { + "type": "object", + "description": "A layout component that arranges its children vertically. To create a grid layout, nest Rows within this Column.", + "properties": { + "component": { + "const": "Column" + }, + "children": { + "description": "Defines the children. Use an array of strings for a fixed set of children, or a template object to generate children from a data list. Children cannot be defined inline, they must be referred to by ID.", + "$ref": "https://a2ui.org/specification/v0_9/common_types.json#/$defs/ChildList" + }, + "justify": { + "type": "string", + "description": "Defines the arrangement of children along the main axis (vertically). Use 'spaceBetween' to push items to the edges (e.g. header at top, footer at bottom), or 'start'/'end'/'center' to pack them together.", + "enum": [ + "start", + "center", + "end", + "spaceBetween", + "spaceAround", + "spaceEvenly", + "stretch" + ], + "default": "start" + }, + "align": { + "type": "string", + "description": "Defines the alignment of children along the cross axis (horizontally). This is similar to the CSS 'align-items' property.", + "enum": ["center", "end", "start", "stretch"], + "default": "stretch" + } + }, + "required": ["component", "children"] + } + ], + "unevaluatedProperties": false + }, + "List": { + "type": "object", + "allOf": [ + { + "$ref": "https://a2ui.org/specification/v0_9/common_types.json#/$defs/ComponentCommon" + }, + { + "$ref": "#/$defs/CatalogComponentCommon" + }, + { + "type": "object", + "properties": { + "component": { + "const": "List" + }, + "children": { + "description": "Defines the children. Use an array of strings for a fixed set of children, or a template object to generate children from a data list.", + "$ref": "https://a2ui.org/specification/v0_9/common_types.json#/$defs/ChildList" + }, + "direction": { + "type": "string", + "description": "The direction in which the list items are laid out.", + "enum": ["vertical", "horizontal"], + "default": "vertical" + }, + "align": { + "type": "string", + "description": "Defines the alignment of children along the cross axis.", + "enum": ["start", "center", "end", "stretch"], + "default": "stretch" + } + }, + "required": ["component", "children"] + } + ], + "unevaluatedProperties": false + }, + "Card": { + "type": "object", + "allOf": [ + { + "$ref": "https://a2ui.org/specification/v0_9/common_types.json#/$defs/ComponentCommon" + }, + { + "$ref": "#/$defs/CatalogComponentCommon" + }, + { + "type": "object", + "properties": { + "component": { + "const": "Card" + }, + "child": { + "$ref": "https://a2ui.org/specification/v0_9/common_types.json#/$defs/ComponentId", + "description": "The ID of the single child component to be rendered inside the card. To display multiple elements, you MUST wrap them in a layout component (like Column or Row) and pass that container's ID here. Do NOT pass multiple IDs or a non-existent ID. Do NOT define the child component inline." + } + }, + "required": ["component", "child"] + } + ], + "unevaluatedProperties": false + }, + "Tabs": { + "type": "object", + "allOf": [ + { + "$ref": "https://a2ui.org/specification/v0_9/common_types.json#/$defs/ComponentCommon" + }, + { + "$ref": "#/$defs/CatalogComponentCommon" + }, + { + "type": "object", + "properties": { + "component": { + "const": "Tabs" + }, + "tabs": { + "type": "array", + "description": "An array of objects, where each object defines a tab with a title and a child component.", + "minItems": 1, + "items": { + "type": "object", + "properties": { + "title": { + "description": "The tab title.", + "$ref": "https://a2ui.org/specification/v0_9/common_types.json#/$defs/DynamicString" + }, + "child": { + "$ref": "https://a2ui.org/specification/v0_9/common_types.json#/$defs/ComponentId", + "description": "The ID of the child component. Do NOT define the component inline." + } + }, + "required": ["title", "child"], + "additionalProperties": false + } + } + }, + "required": ["component", "tabs"] + } + ], + "unevaluatedProperties": false + }, + "Modal": { + "type": "object", + "allOf": [ + { + "$ref": "https://a2ui.org/specification/v0_9/common_types.json#/$defs/ComponentCommon" + }, + { + "$ref": "#/$defs/CatalogComponentCommon" + }, + { + "type": "object", + "properties": { + "component": { + "const": "Modal" + }, + "trigger": { + "$ref": "https://a2ui.org/specification/v0_9/common_types.json#/$defs/ComponentId", + "description": "The ID of the component that opens the modal when interacted with (e.g., a button). Do NOT define the component inline." + }, + "content": { + "$ref": "https://a2ui.org/specification/v0_9/common_types.json#/$defs/ComponentId", + "description": "The ID of the component to be displayed inside the modal. Do NOT define the component inline." + } + }, + "required": ["component", "trigger", "content"] + } + ], + "unevaluatedProperties": false + }, + "Divider": { + "type": "object", + "allOf": [ + { + "$ref": "https://a2ui.org/specification/v0_9/common_types.json#/$defs/ComponentCommon" + }, + { + "$ref": "#/$defs/CatalogComponentCommon" + }, + { + "type": "object", + "properties": { + "component": { + "const": "Divider" + }, + "axis": { + "type": "string", + "description": "The orientation of the divider.", + "enum": ["horizontal", "vertical"], + "default": "horizontal" + } + }, + "required": ["component"] + } + ], + "unevaluatedProperties": false + }, + "Button": { + "type": "object", + "allOf": [ + { + "$ref": "https://a2ui.org/specification/v0_9/common_types.json#/$defs/ComponentCommon" + }, + { + "$ref": "#/$defs/CatalogComponentCommon" + }, + { + "$ref": "https://a2ui.org/specification/v0_9/common_types.json#/$defs/Checkable" + }, + { + "type": "object", + "properties": { + "component": { + "const": "Button" + }, + "child": { + "$ref": "https://a2ui.org/specification/v0_9/common_types.json#/$defs/ComponentId", + "description": "The ID of the child component. Use a 'Text' component for a labeled button. Only use an 'Icon' if the requirements explicitly ask for an icon-only button. Do NOT define the child component inline." + }, + "variant": { + "type": "string", + "description": "A hint for the button style. If omitted, a default button style is used. 'primary' indicates this is the main call-to-action button. 'borderless' means the button has no visual border or background, making its child content appear like a clickable link.", + "enum": ["default", "primary", "borderless"], + "default": "default" + }, + "action": { + "$ref": "https://a2ui.org/specification/v0_9/common_types.json#/$defs/Action" + } + }, + "required": ["component", "child", "action"] + } + ], + "unevaluatedProperties": false + }, + "TextField": { + "type": "object", + "allOf": [ + { + "$ref": "https://a2ui.org/specification/v0_9/common_types.json#/$defs/ComponentCommon" + }, + { + "$ref": "#/$defs/CatalogComponentCommon" + }, + { + "$ref": "https://a2ui.org/specification/v0_9/common_types.json#/$defs/Checkable" + }, + { + "type": "object", + "properties": { + "component": { + "const": "TextField" + }, + "label": { + "$ref": "https://a2ui.org/specification/v0_9/common_types.json#/$defs/DynamicString", + "description": "The text label for the input field." + }, + "value": { + "$ref": "https://a2ui.org/specification/v0_9/common_types.json#/$defs/DynamicString", + "description": "The value of the text field." + }, + "variant": { + "type": "string", + "description": "The type of input field to display.", + "enum": ["longText", "number", "shortText", "obscured"], + "default": "shortText" + }, + "validationRegexp": { + "type": "string", + "description": "A regular expression used for client-side validation of the input." + } + }, + "required": ["component", "label"] + } + ], + "unevaluatedProperties": false + }, + "CheckBox": { + "type": "object", + "allOf": [ + { + "$ref": "https://a2ui.org/specification/v0_9/common_types.json#/$defs/ComponentCommon" + }, + { + "$ref": "#/$defs/CatalogComponentCommon" + }, + { + "$ref": "https://a2ui.org/specification/v0_9/common_types.json#/$defs/Checkable" + }, + { + "type": "object", + "properties": { + "component": { + "const": "CheckBox" + }, + "label": { + "$ref": "https://a2ui.org/specification/v0_9/common_types.json#/$defs/DynamicString", + "description": "The text to display next to the checkbox." + }, + "value": { + "$ref": "https://a2ui.org/specification/v0_9/common_types.json#/$defs/DynamicBoolean", + "description": "The current state of the checkbox (true for checked, false for unchecked)." + } + }, + "required": ["component", "label", "value"] + } + ], + "unevaluatedProperties": false + }, + "ChoicePicker": { + "type": "object", + "allOf": [ + { + "$ref": "https://a2ui.org/specification/v0_9/common_types.json#/$defs/ComponentCommon" + }, + { + "$ref": "#/$defs/CatalogComponentCommon" + }, + { + "$ref": "https://a2ui.org/specification/v0_9/common_types.json#/$defs/Checkable" + }, + { + "type": "object", + "description": "A component that allows selecting one or more options from a list.", + "properties": { + "component": { + "const": "ChoicePicker" + }, + "label": { + "$ref": "https://a2ui.org/specification/v0_9/common_types.json#/$defs/DynamicString", + "description": "The label for the group of options." + }, + "variant": { + "type": "string", + "description": "A hint for how the choice picker should be displayed and behave.", + "enum": ["multipleSelection", "mutuallyExclusive"], + "default": "mutuallyExclusive" + }, + "options": { + "type": "array", + "description": "The list of available options to choose from.", + "items": { + "type": "object", + "properties": { + "label": { + "description": "The text to display for this option.", + "$ref": "https://a2ui.org/specification/v0_9/common_types.json#/$defs/DynamicString" + }, + "value": { + "type": "string", + "description": "The stable value associated with this option." + } + }, + "required": ["label", "value"], + "additionalProperties": false + } + }, + "value": { + "$ref": "https://a2ui.org/specification/v0_9/common_types.json#/$defs/DynamicStringList", + "description": "The list of currently selected values. This should be bound to a string array in the data model." + }, + "displayStyle": { + "type": "string", + "description": "The display style of the component.", + "enum": ["checkbox", "chips"], + "default": "checkbox" + }, + "filterable": { + "type": "boolean", + "description": "If true, displays a search input to filter the options.", + "default": false + } + }, + "required": ["component", "options", "value"] + } + ], + "unevaluatedProperties": false + }, + "Slider": { + "type": "object", + "allOf": [ + { + "$ref": "https://a2ui.org/specification/v0_9/common_types.json#/$defs/ComponentCommon" + }, + { + "$ref": "#/$defs/CatalogComponentCommon" + }, + { + "$ref": "https://a2ui.org/specification/v0_9/common_types.json#/$defs/Checkable" + }, + { + "type": "object", + "properties": { + "component": { + "const": "Slider" + }, + "label": { + "$ref": "https://a2ui.org/specification/v0_9/common_types.json#/$defs/DynamicString", + "description": "The label for the slider." + }, + "min": { + "type": "number", + "description": "The minimum value of the slider.", + "default": 0 + }, + "max": { + "type": "number", + "description": "The maximum value of the slider." + }, + "value": { + "$ref": "https://a2ui.org/specification/v0_9/common_types.json#/$defs/DynamicNumber", + "description": "The current value of the slider." + } + }, + "required": ["component", "value", "max"] + } + ], + "unevaluatedProperties": false + }, + "DateTimeInput": { + "type": "object", + "allOf": [ + { + "$ref": "https://a2ui.org/specification/v0_9/common_types.json#/$defs/ComponentCommon" + }, + { + "$ref": "#/$defs/CatalogComponentCommon" + }, + { + "$ref": "https://a2ui.org/specification/v0_9/common_types.json#/$defs/Checkable" + }, + { + "type": "object", + "properties": { + "component": { + "const": "DateTimeInput" + }, + "value": { + "$ref": "https://a2ui.org/specification/v0_9/common_types.json#/$defs/DynamicString", + "description": "The selected date and/or time value in ISO 8601 format. If not yet set, initialize with an empty string." + }, + "enableDate": { + "type": "boolean", + "description": "If true, allows the user to select a date.", + "default": false + }, + "enableTime": { + "type": "boolean", + "description": "If true, allows the user to select a time.", + "default": false + }, + "min": { + "allOf": [ + { + "$ref": "https://a2ui.org/specification/v0_9/common_types.json#/$defs/DynamicString" + }, + { + "if": { + "type": "string" + }, + "then": { + "oneOf": [ + { + "format": "date" + }, + { + "format": "time" + }, + { + "format": "date-time" + } + ] + } + } + ], + "description": "The minimum allowed date/time in ISO 8601 format." + }, + "max": { + "allOf": [ + { + "$ref": "https://a2ui.org/specification/v0_9/common_types.json#/$defs/DynamicString" + }, + { + "if": { + "type": "string" + }, + "then": { + "oneOf": [ + { + "format": "date" + }, + { + "format": "time" + }, + { + "format": "date-time" + } + ] + } + } + ], + "description": "The maximum allowed date/time in ISO 8601 format." + }, + "label": { + "$ref": "https://a2ui.org/specification/v0_9/common_types.json#/$defs/DynamicString", + "description": "The text label for the input field." + } + }, + "required": ["component", "value"] + } + ], + "unevaluatedProperties": false + }, + "Canvas": { + "description": "A surface-root component that renders its content in a persistent, resizable side panel (a 'canvas') instead of inline in the chat stream. When a surface is rooted in a Canvas, the chat stream shows a compact opener card (configured by cardTitle/cardDescription/cardIcon); opening it (via a click, or automatically when autoOpen is true) renders the Canvas's children inside the side panel. Canvas must be the root component of its surface.", + "allOf": [ + { + "$ref": "#/$defs/CustomComponentCommonProps" + }, + { + "type": "object", + "properties": { + "component": { + "const": "Canvas" + }, + "children": { + "description": "A list of child components to be rendered vertically inside the side panel when the canvas is open.", + "$ref": "https://a2ui.org/specification/v0_9/common_types.json#/$defs/ChildList" + }, + "autoOpen": { + "description": "Optional flag controlling whether the side panel auto-opens when this content arrives. Defaults to true (auto-open). Set to false to keep the in-stream card collapsed and require the user to click it to open the panel.", + "$ref": "https://a2ui.org/specification/v0_9/common_types.json#/$defs/DynamicBoolean" + }, + "cardTitle": { + "description": "Optional title for the in-stream triggering card shown when this content opens in the side panel. Defaults to 'Interactive content'.", + "$ref": "https://a2ui.org/specification/v0_9/common_types.json#/$defs/DynamicString" + }, + "cardDescription": { + "description": "Optional description shown below the title on the in-stream triggering card.", + "$ref": "https://a2ui.org/specification/v0_9/common_types.json#/$defs/DynamicString" + }, + "cardIcon": { + "description": "Optional Material Symbols icon token (e.g. 'table_chart') for the in-stream triggering card. Defaults to 'apps'.", + "$ref": "https://a2ui.org/specification/v0_9/common_types.json#/$defs/DynamicString" + } + }, + "required": ["component", "children"] + } + ] + }, + "IFrameSrcdoc": { + "description": "Renders agent-supplied HTML content inside a sandboxed iframe. The HTML is rendered via a SafeContentFrame with an enforced Content-Security-Policy of `connect-src 'none'`, preventing the embedded content from making any outbound network connections. Interactions inside the frame can be surfaced back to the agent via `a2ui_action` postMessage events.", + "allOf": [ + { + "$ref": "#/$defs/CustomComponentCommonProps" + }, + { + "type": "object", + "properties": { + "component": { + "const": "IFrameSrcdoc" + }, + "htmlContent": { + "description": "The HTML document (or fragment) to render inside the sandboxed iframe.", + "$ref": "https://a2ui.org/specification/v0_9/common_types.json#/$defs/DynamicString" + }, + "height": { + "description": "Optional fixed height in pixels for the iframe. When omitted the iframe defaults to a 4/3 aspect ratio.", + "$ref": "https://a2ui.org/specification/v0_9/common_types.json#/$defs/DynamicNumber" + } + }, + "required": ["component", "htmlContent"] + } + ] + }, + "IFrameUrl": { + "description": "Renders an allowlisted URL inside a direct iframe using safe, intent-based src assignment. URLs whose host is not in the widget's allowlist are blocked and replaced with a security-error message. Interactions inside the frame can be surfaced back to the agent via `a2ui_action` postMessage events (validated against the iframe's origin).", + "allOf": [ + { + "$ref": "#/$defs/CustomComponentCommonProps" + }, + { + "type": "object", + "properties": { + "component": { + "const": "IFrameUrl" + }, + "url": { + "description": "The URL to load inside the iframe. Must resolve to an allowlisted host to be rendered.", + "$ref": "https://a2ui.org/specification/v0_9/common_types.json#/$defs/DynamicString" + }, + "height": { + "description": "Optional fixed height in pixels for the iframe. When omitted the iframe defaults to a 4/3 aspect ratio.", + "$ref": "https://a2ui.org/specification/v0_9/common_types.json#/$defs/DynamicNumber" + } + }, + "required": ["component", "url"] + } + ] + }, + "VegaChart": { + "description": "Renders a Vega-Lite chart using the @safe_vega library.", + "allOf": [ + { + "$ref": "#/$defs/CustomComponentCommonProps" + }, + { + "type": "object", + "properties": { + "component": { + "const": "VegaChart" + }, + "spec": { + "description": "The Vega-Lite spec to render as a JSON object.", + "$ref": "https://a2ui.org/specification/v0_9/common_types.json#/$defs/DynamicValue" + }, + "height": { + "description": "Optional height of the chart in pixels. Defaults to 290.", + "$ref": "https://a2ui.org/specification/v0_9/common_types.json#/$defs/DynamicNumber" + } + }, + "required": ["component", "spec"] + } + ] + }, + "GcbpTable": { + "description": "GcbpTable table component from GCBP catalog. Renders structured data into columns and rows with support for sorting.", + "allOf": [ + { + "$ref": "#/$defs/CustomComponentCommonProps" + }, + { + "type": "object", + "properties": { + "component": { + "const": "GcbpTable" + }, + "columns": { + "type": "array", + "description": "The list of columns to display in the table.", + "items": { + "type": "object", + "properties": { + "header": { + "type": "string", + "description": "The title of the column to display in the header." + }, + "field": { + "type": "string", + "description": "The field name in the row data that supplies the value for this column." + }, + "sortable": { + "type": "boolean", + "description": "Optional flag indicating whether this column can be sorted." + } + }, + "required": ["header", "field"] + } + }, + "rows": { + "description": "The data rows to display in the table. Can be a static array of objects or bound to the data model.", + "oneOf": [ + { + "type": "array", + "items": { + "type": "object", + "additionalProperties": { + "type": "string" + } + } + }, + { + "$ref": "https://a2ui.org/specification/v0_9/common_types.json#/$defs/DataBinding" + } + ] + }, + "ariaLabel": { + "description": "Optional ARIA label for the table.", + "$ref": "https://a2ui.org/specification/v0_9/common_types.json#/$defs/DynamicString" + }, + "ariaLabelledby": { + "description": "Optional ARIA labelledby for the table.", + "$ref": "https://a2ui.org/specification/v0_9/common_types.json#/$defs/DynamicString" + }, + "caption": { + "description": "Optional caption for the table.", + "$ref": "https://a2ui.org/specification/v0_9/common_types.json#/$defs/DynamicString" + } + }, + "required": ["component", "columns", "rows"] + } + ] + }, + "InteractiveChart": { + "description": "Renders a Looker Studio visualization chart.", + "allOf": [ + { + "$ref": "#/$defs/CustomComponentCommonProps" + }, + { + "type": "object", + "properties": { + "component": { + "const": "InteractiveChart" + }, + "chartData": { + "description": "The Studio Viz chart data.", + "$ref": "https://a2ui.org/specification/v0_9/common_types.json#/$defs/DynamicValue" + } + }, + "required": ["component", "chartData"] + } + ] + } + }, + "functions": { + "areComponentsValid": { + "type": "object", + "description": "Checks if all specified components are valid.", + "properties": { + "call": { + "const": "areComponentsValid" + }, + "args": { + "type": "object", + "properties": { + "componentIds": { + "type": "array", + "items": { + "type": "string" + }, + "description": "The IDs of the components to validate." + } + }, + "required": ["componentIds"], + "additionalProperties": false + }, + "returnType": { + "const": "boolean" + } + }, + "required": ["call", "args"] + }, + "dateIsBeforeOrEqual": { + "type": "object", + "description": "Checks if date a is before or equal to date b.", + "properties": { + "call": { + "const": "dateIsBeforeOrEqual" + }, + "args": { + "type": "object", + "properties": { + "a": { + "$ref": "#/$defs/DynamicDate" + }, + "b": { + "$ref": "#/$defs/DynamicDate" + } + }, + "required": ["a", "b"], + "additionalProperties": false + }, + "returnType": { + "const": "boolean" + } + }, + "required": ["call", "args"], + "unevaluatedProperties": false + }, + "dateIsBefore": { + "type": "object", + "description": "Checks if date a is before date b.", + "properties": { + "call": { + "const": "dateIsBefore" + }, + "args": { + "type": "object", + "properties": { + "a": { + "$ref": "#/$defs/DynamicDate" + }, + "b": { + "$ref": "#/$defs/DynamicDate" + } + }, + "required": ["a", "b"], + "additionalProperties": false + }, + "returnType": { + "const": "boolean" + } + }, + "required": ["call", "args"], + "unevaluatedProperties": false + }, + "dateEquals": { + "type": "object", + "description": "Checks if date a is equal to date b.", + "properties": { + "call": { + "const": "dateEquals" + }, + "args": { + "type": "object", + "properties": { + "a": { + "$ref": "#/$defs/DynamicDate" + }, + "b": { + "$ref": "#/$defs/DynamicDate" + } + }, + "required": ["a", "b"], + "additionalProperties": false + }, + "returnType": { + "const": "boolean" + } + }, + "required": ["call", "args"], + "unevaluatedProperties": false + }, + "required": { + "type": "object", + "description": "Checks that the value is not null, undefined, or empty.", + "properties": { + "call": { + "const": "required" + }, + "args": { + "type": "object", + "properties": { + "value": { + "description": "The value to check." + } + }, + "required": ["value"], + "additionalProperties": false + }, + "returnType": { + "const": "boolean" + } + }, + "required": ["call", "args"], + "unevaluatedProperties": false + }, + "regex": { + "type": "object", + "description": "Checks that the value matches a regular expression string.", + "properties": { + "call": { + "const": "regex" + }, + "args": { + "type": "object", + "properties": { + "value": { + "$ref": "https://a2ui.org/specification/v0_9/common_types.json#/$defs/DynamicString" + }, + "pattern": { + "type": "string", + "description": "The regex pattern to match against." + } + }, + "required": ["value", "pattern"], + "unevaluatedProperties": false + }, + "returnType": { + "const": "boolean" + } + }, + "required": ["call", "args"], + "unevaluatedProperties": false + }, + "length": { + "type": "object", + "description": "Checks string length constraints.", + "properties": { + "call": { + "const": "length" + }, + "args": { + "type": "object", + "properties": { + "value": { + "$ref": "https://a2ui.org/specification/v0_9/common_types.json#/$defs/DynamicString" + }, + "min": { + "type": "integer", + "minimum": 0, + "description": "The minimum allowed length." + }, + "max": { + "type": "integer", + "minimum": 0, + "description": "The maximum allowed length." + } + }, + "required": ["value"], + "anyOf": [ + { + "required": ["min"] + }, + { + "required": ["max"] + } + ], + "unevaluatedProperties": false + }, + "returnType": { + "const": "boolean" + } + }, + "required": ["call", "args"], + "unevaluatedProperties": false + }, + "numeric": { + "type": "object", + "description": "Checks numeric range constraints.", + "properties": { + "call": { + "const": "numeric" + }, + "args": { + "type": "object", + "properties": { + "value": { + "$ref": "https://a2ui.org/specification/v0_9/common_types.json#/$defs/DynamicNumber" + }, + "min": { + "type": "number", + "description": "The minimum allowed value." + }, + "max": { + "type": "number", + "description": "The maximum allowed value." + } + }, + "required": ["value"], + "anyOf": [ + { + "required": ["min"] + }, + { + "required": ["max"] + } + ], + "unevaluatedProperties": false + }, + "returnType": { + "const": "boolean" + } + }, + "required": ["call", "args"], + "unevaluatedProperties": false + }, + "email": { + "type": "object", + "description": "Checks that the value is a valid email address.", + "properties": { + "call": { + "const": "email" + }, + "args": { + "type": "object", + "properties": { + "value": { + "$ref": "https://a2ui.org/specification/v0_9/common_types.json#/$defs/DynamicString" + } + }, + "required": ["value"], + "unevaluatedProperties": false + }, + "returnType": { + "const": "boolean" + } + }, + "required": ["call", "args"], + "unevaluatedProperties": false + }, + "formatString": { + "type": "object", + "description": "Performs string interpolation of data model values and other functions in the catalog functions list and returns the resulting string. The value string can contain interpolated expressions in the `${expression}` format. Supported expression types include: JSON Pointer paths to the data model (e.g., `${/absolute/path}` or `${relative/path}`), and client-side function calls (e.g., `${now()}`). Function arguments must be named (e.g., `${formatDate(value:${/currentDate}, format:'MM-dd')}`). To include a literal `${` sequence, escape it as `\\${`.", + "properties": { + "call": { + "const": "formatString" + }, + "args": { + "type": "object", + "properties": { + "value": { + "$ref": "https://a2ui.org/specification/v0_9/common_types.json#/$defs/DynamicString" + } + }, + "required": ["value"], + "unevaluatedProperties": false + }, + "returnType": { + "const": "string" + } + }, + "required": ["call", "args"], + "unevaluatedProperties": false + }, + "formatNumber": { + "type": "object", + "description": "Formats a number with the specified grouping and decimal precision.", + "properties": { + "call": { + "const": "formatNumber" + }, + "args": { + "type": "object", + "properties": { + "value": { + "$ref": "https://a2ui.org/specification/v0_9/common_types.json#/$defs/DynamicNumber", + "description": "The number to format." + }, + "decimals": { + "$ref": "https://a2ui.org/specification/v0_9/common_types.json#/$defs/DynamicNumber", + "description": "Optional. The number of decimal places to show. Defaults to 0 or 2 depending on locale." + }, + "grouping": { + "$ref": "https://a2ui.org/specification/v0_9/common_types.json#/$defs/DynamicBoolean", + "description": "Optional. If true, uses locale-specific grouping separators (e.g. '1,000'). If false, returns raw digits (e.g. '1000'). Defaults to true." + } + }, + "required": ["value"], + "unevaluatedProperties": false + }, + "returnType": { + "const": "string" + } + }, + "required": ["call", "args"], + "unevaluatedProperties": false + }, + "formatCurrency": { + "type": "object", + "description": "Formats a number as a currency string.", + "properties": { + "call": { + "const": "formatCurrency" + }, + "args": { + "type": "object", + "properties": { + "value": { + "$ref": "https://a2ui.org/specification/v0_9/common_types.json#/$defs/DynamicNumber", + "description": "The monetary amount." + }, + "currency": { + "$ref": "https://a2ui.org/specification/v0_9/common_types.json#/$defs/DynamicString", + "description": "The ISO 4217 currency code (e.g., 'USD', 'EUR')." + }, + "decimals": { + "$ref": "https://a2ui.org/specification/v0_9/common_types.json#/$defs/DynamicNumber", + "description": "Optional. The number of decimal places to show. Defaults to 0 or 2 depending on locale." + }, + "grouping": { + "$ref": "https://a2ui.org/specification/v0_9/common_types.json#/$defs/DynamicBoolean", + "description": "Optional. If true, uses locale-specific grouping separators (e.g. '1,000'). If false, returns raw digits (e.g. '1000'). Defaults to true." + } + }, + "required": ["currency", "value"], + "unevaluatedProperties": false + }, + "returnType": { + "const": "string" + } + }, + "required": ["call", "args"], + "unevaluatedProperties": false + }, + "formatDate": { + "type": "object", + "description": "Formats a timestamp into a string using a pattern.", + "properties": { + "call": { + "const": "formatDate" + }, + "args": { + "type": "object", + "properties": { + "value": { + "$ref": "https://a2ui.org/specification/v0_9/common_types.json#/$defs/DynamicValue", + "description": "The date to format." + }, + "format": { + "$ref": "https://a2ui.org/specification/v0_9/common_types.json#/$defs/DynamicString", + "description": "A Unicode TR35 date pattern string.\n\nToken Reference:\n- Year: 'yy' (26), 'yyyy' (2026)\n- Month: 'M' (1), 'MM' (01), 'MMM' (Jan), 'MMMM' (January)\n- Day: 'd' (1), 'dd' (01), 'E' (Tue), 'EEEE' (Tuesday)\n- Hour (12h): 'h' (1-12), 'hh' (01-12) - requires 'a' for AM/PM\n- Hour (24h): 'H' (0-23), 'HH' (00-23) - Military Time\n- Minute: 'mm' (00-59)\n- Second: 'ss' (00-59)\n- Period: 'a' (AM/PM)\n\nExamples:\n- 'MMM dd, yyyy' -> 'Jan 16, 2026'\n- 'HH:mm' -> '14:30' (Military)\n- 'h:mm a' -> '2:30 PM'\n- 'EEEE, d MMMM' -> 'Friday, 16 January'" + } + }, + "required": ["format", "value"], + "unevaluatedProperties": false + }, + "returnType": { + "const": "string" + } + }, + "required": ["call", "args"], + "unevaluatedProperties": false + }, + "pluralize": { + "type": "object", + "description": "Returns a localized string based on the Common Locale Data Repository (CLDR) plural category of the count (zero, one, two, few, many, other). Requires an 'other' fallback. For English, just use 'one' and 'other'.", + "properties": { + "call": { + "const": "pluralize" + }, + "args": { + "type": "object", + "properties": { + "value": { + "$ref": "https://a2ui.org/specification/v0_9/common_types.json#/$defs/DynamicNumber", + "description": "The numeric value used to determine the plural category." + }, + "zero": { + "$ref": "https://a2ui.org/specification/v0_9/common_types.json#/$defs/DynamicString", + "description": "String for the 'zero' category (e.g., 0 items)." + }, + "one": { + "$ref": "https://a2ui.org/specification/v0_9/common_types.json#/$defs/DynamicString", + "description": "String for the 'one' category (e.g., 1 item)." + }, + "two": { + "$ref": "https://a2ui.org/specification/v0_9/common_types.json#/$defs/DynamicString", + "description": "String for the 'two' category (used in Arabic, Welsh, etc.)." + }, + "few": { + "$ref": "https://a2ui.org/specification/v0_9/common_types.json#/$defs/DynamicString", + "description": "String for the 'few' category (e.g., small groups in Slavic languages)." + }, + "many": { + "$ref": "https://a2ui.org/specification/v0_9/common_types.json#/$defs/DynamicString", + "description": "String for the 'many' category (e.g., large groups in various languages)." + }, + "other": { + "$ref": "https://a2ui.org/specification/v0_9/common_types.json#/$defs/DynamicString", + "description": "The default/fallback string (used for general plural cases)." + } + }, + "required": ["value", "other"], + "unevaluatedProperties": false + }, + "returnType": { + "const": "string" + } + }, + "required": ["call", "args"], + "unevaluatedProperties": false + }, + "openUrl": { + "type": "object", + "description": "Opens the specified URL in a browser or handler. This function has no return value.", + "properties": { + "call": { + "const": "openUrl" + }, + "args": { + "type": "object", + "properties": { + "url": { + "type": "string", + "format": "uri", + "description": "The URL to open." + } + }, + "required": ["url"], + "additionalProperties": false + }, + "returnType": { + "const": "void" + } + }, + "required": ["call", "args"], + "unevaluatedProperties": false + }, + "and": { + "type": "object", + "description": "Performs a logical AND operation on a list of boolean values.", + "properties": { + "call": { + "const": "and" + }, + "args": { + "type": "object", + "properties": { + "values": { + "type": "array", + "description": "The list of boolean values to evaluate.", + "items": { + "$ref": "https://a2ui.org/specification/v0_9/common_types.json#/$defs/DynamicBoolean" + }, + "minItems": 2 + } + }, + "required": ["values"], + "unevaluatedProperties": false + }, + "returnType": { + "const": "boolean" + } + }, + "required": ["call", "args"], + "unevaluatedProperties": false + }, + "or": { + "type": "object", + "description": "Performs a logical OR operation on a list of boolean values.", + "properties": { + "call": { + "const": "or" + }, + "args": { + "type": "object", + "properties": { + "values": { + "type": "array", + "description": "The list of boolean values to evaluate.", + "items": { + "$ref": "https://a2ui.org/specification/v0_9/common_types.json#/$defs/DynamicBoolean" + }, + "minItems": 2 + } + }, + "required": ["values"], + "unevaluatedProperties": false + }, + "returnType": { + "const": "boolean" + } + }, + "required": ["call", "args"], + "unevaluatedProperties": false + }, + "not": { + "type": "object", + "description": "Performs a logical NOT operation on a boolean value.", + "properties": { + "call": { + "const": "not" + }, + "args": { + "type": "object", + "properties": { + "value": { + "$ref": "https://a2ui.org/specification/v0_9/common_types.json#/$defs/DynamicBoolean", + "description": "The boolean value to negate." + } + }, + "required": ["value"], + "unevaluatedProperties": false + }, + "returnType": { + "const": "boolean" + } + }, + "required": ["call", "args"], + "unevaluatedProperties": false + } + }, + "$defs": { + "DynamicDateTime": { + "description": "Represents a value that can be either a literal datetime string (RFC 3339), a path to a datetime string in the data model, or a function call returning a datetime string.", + "oneOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "$ref": "https://a2ui.org/specification/v0_9/common_types.json#/$defs/DataBinding" + }, + { + "allOf": [ + { + "$ref": "https://a2ui.org/specification/v0_9/common_types.json#/$defs/FunctionCall" + }, + { + "properties": { + "returnType": { + "const": "string" + } + } + } + ] + } + ] + }, + "DynamicDate": { + "description": "Represents a value that can be either a literal date object, a path to a date object in the data model, or a function call returning a date object.", + "oneOf": [ + { + "type": "object", + "properties": { + "year": { + "type": "integer" + }, + "month": { + "type": "integer", + "minimum": 1, + "maximum": 12 + }, + "day": { + "type": "integer", + "minimum": 1, + "maximum": 31 + } + }, + "required": ["year", "month", "day"] + }, + { + "$ref": "https://a2ui.org/specification/v0_9/common_types.json#/$defs/DataBinding" + }, + { + "allOf": [ + { + "$ref": "https://a2ui.org/specification/v0_9/common_types.json#/$defs/FunctionCall" + }, + { + "properties": { + "returnType": { + "const": "object" + } + } + } + ] + } + ] + }, + "SelectOption": { + "type": "object", + "properties": { + "label": { + "description": "The display label for the option.", + "type": "string" + }, + "value": { + "description": "The underlying value for the option.", + "type": "string" + } + }, + "required": ["label", "value"] + }, + "MaterialComponentCommon": { + "allOf": [ + { + "$ref": "https://a2ui.org/specification/v0_9/common_types.json#/$defs/ComponentCommon" + }, + { + "type": "object", + "properties": { + "weight": { + "type": "number", + "description": "Optional layout weight, used to specify how the component sizes relative to its siblings in a flex layout (e.g., inside a row or column)." + }, + "style": { + "type": "object", + "$comment": "SECURITY: Do not add layout/positioning properties (e.g., position, top, left, zIndex, opacity, transform, pointerEvents) to this allowlist. Doing so enables CWE-1021 UI Redressing and Clickjacking attacks. Only safe, in-flow cosmetic properties (e.g., margin, padding, color, flex) are permitted.", + "additionalProperties": false, + "properties": { + "alignItems": { + "type": "string" + }, + "alignSelf": { + "type": "string" + }, + "background": { + "type": "string" + }, + "backgroundColor": { + "type": "string" + }, + "border": { + "type": "string" + }, + "borderRadius": { + "type": "string" + }, + "color": { + "type": "string" + }, + "display": { + "type": "string" + }, + "flexDirection": { + "type": "string" + }, + "flexWrap": { + "type": "string" + }, + "fontSize": { + "type": "string" + }, + "fontWeight": { + "type": "string" + }, + "gap": { + "type": "string" + }, + "height": { + "type": "string" + }, + "justifyContent": { + "type": "string" + }, + "margin": { + "type": "string" + }, + "marginBottom": { + "type": "string" + }, + "marginInlineEnd": { + "type": "string" + }, + "marginInlineStart": { + "type": "string" + }, + "marginLeft": { + "type": "string" + }, + "marginRight": { + "type": "string" + }, + "marginTop": { + "type": "string" + }, + "maxHeight": { + "type": "string" + }, + "maxWidth": { + "type": "string" + }, + "minHeight": { + "type": "string" + }, + "minWidth": { + "type": "string" + }, + "padding": { + "type": "string" + }, + "paddingBottom": { + "type": "string" + }, + "paddingInlineEnd": { + "type": "string" + }, + "paddingInlineStart": { + "type": "string" + }, + "paddingLeft": { + "type": "string" + }, + "paddingRight": { + "type": "string" + }, + "paddingTop": { + "type": "string" + }, + "textAlign": { + "type": "string" + }, + "textDecoration": { + "type": "string" + }, + "width": { + "type": "string" + } + }, + "description": "Optional custom inline CSS styles represented as a key-value map to apply directly to the component's root element." + } + } + } + ] + }, + "CatalogComponentCommon": { + "type": "object", + "properties": { + "weight": { + "type": "number", + "description": "The relative weight of this component within a Row or Column. This is similar to the CSS 'flex-grow' property. Note: this may ONLY be set when the component is a direct descendant of a Row or Column." + } + } + }, + "CustomComponentCommonProps": { + "allOf": [ + { + "$ref": "https://a2ui.org/specification/v0_9/common_types.json#/$defs/ComponentCommon" + }, + { + "type": "object", + "properties": { + "weight": { + "type": "number", + "description": "Optional layout weight, used to specify how the component sizes relative to its siblings in a flex layout (e.g., inside a row or column)." + } + } + } + ] + }, + "anyComponent": { + "type": "object", + "oneOf": [ + { + "$ref": "#/components/MaterialText" + }, + { + "$ref": "#/components/MaterialButton" + }, + { + "$ref": "#/components/MaterialIconButton" + }, + { + "$ref": "#/components/MaterialInput" + }, + { + "$ref": "#/components/MaterialRow" + }, + { + "$ref": "#/components/MaterialColumn" + }, + { + "$ref": "#/components/MaterialCard" + }, + { + "$ref": "#/components/MaterialIcon" + }, + { + "$ref": "#/components/MaterialSelect" + }, + { + "$ref": "#/components/MaterialCheckbox" + }, + { + "$ref": "#/components/MaterialBadge" + }, + { + "$ref": "#/components/MaterialButtonToggle" + }, + { + "$ref": "#/components/MaterialChips" + }, + { + "$ref": "#/components/MaterialDatepicker" + }, + { + "$ref": "#/components/MaterialDialog" + }, + { + "$ref": "#/components/MaterialDivider" + }, + { + "$ref": "#/components/MaterialExpansionPanel" + }, + { + "$ref": "#/components/MaterialGridList" + }, + { + "$ref": "#/components/MaterialMenu" + }, + { + "$ref": "#/components/MaterialProgressBar" + }, + { + "$ref": "#/components/MaterialProgressSpinner" + }, + { + "$ref": "#/components/MaterialRadioButton" + }, + { + "$ref": "#/components/MaterialSlideToggle" + }, + { + "$ref": "#/components/MaterialSlider" + }, + { + "$ref": "#/components/MaterialTable" + }, + { + "$ref": "#/components/MaterialTabs" + }, + { + "$ref": "#/components/MaterialTimepicker" + }, + { + "$ref": "#/components/MaterialImage" + }, + { + "$ref": "#/components/Text" + }, + { + "$ref": "#/components/Image" + }, + { + "$ref": "#/components/Icon" + }, + { + "$ref": "#/components/Video" + }, + { + "$ref": "#/components/AudioPlayer" + }, + { + "$ref": "#/components/Row" + }, + { + "$ref": "#/components/Column" + }, + { + "$ref": "#/components/List" + }, + { + "$ref": "#/components/Card" + }, + { + "$ref": "#/components/Tabs" + }, + { + "$ref": "#/components/Modal" + }, + { + "$ref": "#/components/Divider" + }, + { + "$ref": "#/components/Button" + }, + { + "$ref": "#/components/TextField" + }, + { + "$ref": "#/components/CheckBox" + }, + { + "$ref": "#/components/ChoicePicker" + }, + { + "$ref": "#/components/Slider" + }, + { + "$ref": "#/components/DateTimeInput" + }, + { + "$ref": "#/components/Canvas" + }, + { + "$ref": "#/components/IFrameSrcdoc" + }, + { + "$ref": "#/components/IFrameUrl" + }, + { + "$ref": "#/components/VegaChart" + }, + { + "$ref": "#/components/GcbpTable" + }, + { + "$ref": "#/components/InteractiveChart" + } + ] + }, + "anyFunction": { + "oneOf": [ + { + "$ref": "#/functions/areComponentsValid" + }, + { + "$ref": "#/functions/dateIsBeforeOrEqual" + }, + { + "$ref": "#/functions/dateIsBefore" + }, + { + "$ref": "#/functions/dateEquals" + }, + { + "$ref": "#/functions/required" + }, + { + "$ref": "#/functions/regex" + }, + { + "$ref": "#/functions/length" + }, + { + "$ref": "#/functions/numeric" + }, + { + "$ref": "#/functions/email" + }, + { + "$ref": "#/functions/formatString" + }, + { + "$ref": "#/functions/formatNumber" + }, + { + "$ref": "#/functions/formatCurrency" + }, + { + "$ref": "#/functions/formatDate" + }, + { + "$ref": "#/functions/pluralize" + }, + { + "$ref": "#/functions/openUrl" + }, + { + "$ref": "#/functions/and" + }, + { + "$ref": "#/functions/or" + }, + { + "$ref": "#/functions/not" + } + ] + }, + "theme": { + "type": "object", + "additionalProperties": true, + "properties": { + "primaryColor": { + "type": "string", + "description": "The primary brand color used for highlights (e.g., primary buttons, active borders). Renderers may generate variants of this color for different contexts. Format: Hexadecimal code (e.g., '#00BFFF').", + "pattern": "^#[0-9a-fA-F]{6}$" + }, + "iconUrl": { + "type": "string", + "format": "uri", + "description": "A URL for an image that identifies the agent or tool associated with the surface." + }, + "agentDisplayName": { + "type": "string", + "description": "Text to be displayed next to the surface to identify the agent or tool that created it." + } + } + } + } +} diff --git a/samples/community/agent/adk/gemini_enterprise/v0_9/main.py b/samples/community/agent/adk/gemini_enterprise/v0_9/main.py new file mode 100644 index 0000000000..ea6057bff5 --- /dev/null +++ b/samples/community/agent/adk/gemini_enterprise/v0_9/main.py @@ -0,0 +1,91 @@ +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +"""Cloud Run entry point for the A2UI v0.9 Demo agent. + +Cloud Run invokes the `start` script (see [project.scripts] in pyproject.toml), +which runs `serve()`. The server binds to 0.0.0.0 and the port provided by the +`PORT` environment variable (defaults to 8080). +""" + +import logging +import os + +from a2a.server.apps import A2AStarletteApplication +from a2a.server.request_handlers import DefaultRequestHandler +from a2a.server.tasks import InMemoryTaskStore +from agent import A2uiDemoAgent +from agent_executor import A2uiDemoAgentExecutor +from dotenv import load_dotenv +from starlette.middleware.cors import CORSMiddleware +from starlette.staticfiles import StaticFiles +import uvicorn + +load_dotenv() + +logging.basicConfig(level=logging.INFO) +logger = logging.getLogger(__name__) + + +def serve(): + """Starts the A2UI v0.9 Demo server.""" + try: + host = "0.0.0.0" + port = int(os.environ.get("PORT", 8080)) + + # On Cloud Run, the public URL of the service is provided via AGENT_URL + # (set by deploy.sh after the service is created). Fall back to the local + # host:port for local runs. + base_url = os.environ.get("AGENT_URL", f"http://{host}:{port}") + + agent = A2uiDemoAgent(base_url=base_url) + agent_executor = A2uiDemoAgentExecutor(agent=agent) + request_handler = DefaultRequestHandler( + agent_executor=agent_executor, + task_store=InMemoryTaskStore(), + ) + server = A2AStarletteApplication( + agent_card=agent.agent_card, http_handler=request_handler + ) + + app = server.build() + + app.add_middleware( + CORSMiddleware, + allow_origin_regex=r"https?://.*", + allow_credentials=True, + allow_methods=["*"], + allow_headers=["*"], + ) + + # Serve restaurant images from the local `images/` directory if present. + images_dir = os.path.join(os.path.dirname(__file__), "images") + if os.path.isdir(images_dir): + app.mount("/static", StaticFiles(directory=images_dir), name="static") + else: + logger.warning( + "No 'images' directory found at %s; /static will not be served.", + images_dir, + ) + + logger.info("Running server on %s:%s (base_url=%s)", host, port, base_url) + uvicorn.run(app, host=host, port=port) + + except Exception as e: # pylint: disable=broad-except + logger.error("An error occurred during server startup: %s", e) + exit(1) + + +if __name__ == "__main__": + serve() diff --git a/samples/community/agent/adk/gemini_enterprise/v0_9/prompt_builder.py b/samples/community/agent/adk/gemini_enterprise/v0_9/prompt_builder.py new file mode 100644 index 0000000000..fde6abc935 --- /dev/null +++ b/samples/community/agent/adk/gemini_enterprise/v0_9/prompt_builder.py @@ -0,0 +1,160 @@ +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import os + +from a2ui.schema.catalog import CatalogConfig +from a2ui.schema.common_modifiers import remove_strict_validation +from a2ui.schema.constants import VERSION_0_9 +from a2ui.schema.manager import A2uiSchemaManager + +COMPOSITE_CATALOG_PATH = os.path.join( + os.path.dirname(__file__), "gemini_enterprise_composite_catalog.json" +) + +ROLE_DESCRIPTION = ( + 'You are the "A2UI v0.9 Demo" agent. Your job is to showcase what can be' + " built with A2UI (Agent-to-UI) v0.9 and the Material component catalog." + " Your final output MUST be an A2UI UI JSON response built from the" + " provided catalog. For any request, generate a rich, interactive UI that" + " best demonstrates the relevant components." +) + +UI_DESCRIPTION = """ +- You MUST only use components from the provided catalog. Never invent generic component names like `Column`, `Text`, or `List`; always use the catalog names (e.g. `MaterialColumn`, `MaterialRow`, `MaterialCard`, `MaterialText`, `MaterialImage`, `MaterialButton`, `MaterialInput`). +- The catalog has no list component. To render a dynamic list of items, use a `MaterialColumn` (or `MaterialGridList`) whose `children` is a template object: `{"componentId": "", "path": "/items"}`. +- Always wrap the top-level content in a `MaterialCard` root (id `root`) unless the surface specifically calls for a `Canvas` root (e.g. the "what can you do?" card, and the canvas / embedded-URL demos). +- Whenever a component dispatches an action `event`, add a short, human-readable `prompt` string to the event `context` that describes the user's intent (e.g. `"prompt": "Show me the forms demo"` or `"prompt": "Book a table at this restaurant"`). The client uses `context.prompt` as the user's chat message; without it a generic "User action triggered" message is shown instead. `prompt` is a plain literal string, separate from any other context values (which may be literals or `{ "path": "..." }` data bindings). +- CRITICAL: Every response MUST use a NEW, UNIQUE `surfaceId`. Do NOT reuse a `surfaceId` across responses, and do NOT copy the `surfaceId` literals from the examples (e.g. do not use `default`, `preferences`, `dashboard`, `checkout`, etc. verbatim). Generate a fresh, descriptive-but-unique id each time, e.g. by appending a random suffix such as `demo-forms-a7f3c9` or `canvas-8b21`. The SAME `surfaceId` MUST be used consistently within a single response for its `createSurface`, `updateComponents`, and `updateDataModel` messages, but MUST differ from every prior response. (Reusing a `surfaceId` currently confuses the renderer.) + +## Available demos + +You are a general-purpose A2UI demo. When the user asks for one of the demos below (or something similar), generate the matching UI. Use the ---BEGIN --- / ---END --- examples as references, but adapt content to the request. Each demo has a canonical `demo` key (shown in `backticks`) used by the "what can you do?" card and by `RUN_DEMO` requests. + +- `gallery` — **Material components gallery**: cards, text, buttons, icons, images, dividers, badges (see `material_card_flight_status`). +- `forms` — **Forms & inputs**: `MaterialInput`, `MaterialSelect`, `MaterialCheckbox`, `MaterialRadioButton`, `MaterialSlideToggle`, `MaterialSlider`, `MaterialChips`, `MaterialButtonToggle`, `MaterialDatepicker`, `MaterialTimepicker` (see `material_input_form`). +- `tabs` — **Tabs & layout**: `MaterialTabs`, `MaterialExpansionPanel`, `MaterialGridList`, `MaterialRow`, `MaterialColumn` (see `material_preferences_tabs`). +- `table` — **Data display**: `MaterialTable`, `MaterialProgressBar`, `MaterialProgressSpinner` (see `material_table_orders`, `material_dashboard`). +- `dialog` — **Dialogs & menus**: `MaterialDialog`, `MaterialMenu` (see `material_dialog`). +- `canvas` — **Canvas (side panel)**: root a surface in a `Canvas` to render content in a resizable side panel with an in-stream opener card (see `canvas_side_panel`). +- `iframe_srcdoc` — **Iframe (custom HTML)**: `IFrameSrcdoc` renders agent-supplied HTML in a sandboxed frame (see `iframe_srcdoc`). +- `iframe_url` — **Iframe (embedded URL)**: `IFrameUrl` renders an allowlisted URL; for a side panel, nest it inside a `Canvas` (see `iframe_url_canvas`). +- `restaurants` — **Restaurant finder**: use the `get_restaurants` tool, then render a list (see `single_column_list`, `two_column_list`) or a booking form (`booking_form`, `confirmation`). + +## Component-specific rules + +- `Canvas` MUST be the root component of its surface. Set `cardTitle`, `cardDescription`, `cardIcon`, and `autoOpen` to configure the in-stream opener card. +- `IFrameSrcdoc` requires an `htmlContent` string (a full, self-contained HTML document). To surface an in-frame click back to the agent, have the HTML `postMessage` a `{type: 'a2ui_action', action: '', data: {...}}` payload to its parent. +- `IFrameUrl` requires a `url`. Only allowlisted hosts render; otherwise a security error is shown. +- `MaterialTabs`: the `content` of each tab is the id of another component in the same surface. Those components MUST also be reachable (include them as children of the tabs component's parent structure or referenced via tab content). + +## "What can you do?" requests + +If the user asks what you can do (e.g. "what can you do?", "help", "show me a demo", "list demos"), respond with an A2UI `Canvas` root (id `root`) so the demo list opens in a resizable side panel and stays there (see `canvas_side_panel` for the `Canvas` structure). Configure the Canvas opener card with `cardTitle` (e.g. "A2UI v0.9 Demo"), a short `cardDescription`, a `cardIcon` (e.g. "widgets"), and `autoOpen: true`. Inside the Canvas, use a `MaterialColumn` of `MaterialButton`s (one per demo), preceded by a `MaterialText` heading and a short description. This both answers the question AND showcases A2UI itself. + +Each demo button's action MUST encode the demo key directly in the event `name` as `run_demo_`, and set a short, human-readable `prompt` in the event `context`. For example, the "Iframe (Custom HTML)" button MUST be: + +``` +"action": { + "event": { + "name": "run_demo_iframe_srcdoc", + "context": { + "prompt": "Show me the custom-HTML iframe demo" + } + } +} +``` + +CRITICAL rules for these buttons: +- The event `name` MUST be `run_demo_` followed by the exact canonical demo key from "Available demos" (`gallery`, `forms`, `tabs`, `table`, `dialog`, `canvas`, `iframe_srcdoc`, `iframe_url`, `restaurants`). So the valid event names are exactly: `run_demo_gallery`, `run_demo_forms`, `run_demo_tabs`, `run_demo_table`, `run_demo_dialog`, `run_demo_canvas`, `run_demo_iframe_srcdoc`, `run_demo_iframe_url`, `run_demo_restaurants`. +- These `run_demo_*` strings are CLIENT-SIDE A2UI event names that you put inside a button's `action.event.name` field of your UI JSON. They are NOT tools or functions, and you MUST NEVER call them as a function/tool. The ONLY tool you may ever call is `get_restaurants`. +- The demo key MUST live ONLY in the event `name`, never in `context`. The `context` MUST carry only the literal `prompt` string — do NOT put the demo key there, and do NOT use a data-binding object like `{ "path": "..." }` — so the key can never be lost. +- The button `label` is the human-readable name (e.g. "Iframe (Custom HTML)"), but the event `name` MUST use the exact key (e.g. `run_demo_iframe_srcdoc`). + +## Handling a demo button click + +When the user clicks a demo button, you will receive a plain-text query like: "The user clicked the '' demo button. Render the A2UI UI for the '' demo now." + +You MUST respond by IMMEDIATELY generating the A2UI UI JSON for that demo. Do NOT call any tool (except that the `restaurants` demo requires calling `get_restaurants`). Do NOT emit a function call named after the demo — the demo name is NOT a tool. Do NOT ask the user which demo they want; the demo name is already given. + +Map the demo name to the UI to render: +- `gallery` → the Material components gallery (see `material_card_flight_status`). +- `forms` → the forms & inputs demo (see `material_input_form`). +- `tabs` → the tabs & layout demo (see `material_preferences_tabs`). +- `table` → the data table / dashboard demo (see `material_table_orders`). +- `dialog` → the dialogs & menus demo (see `material_dialog`). +- `canvas` → the Canvas side-panel demo (see `canvas_side_panel`). +- `iframe_srcdoc` → the custom-HTML iframe demo (see `iframe_srcdoc`). +- `iframe_url` → the embedded-URL iframe demo (see `iframe_url_canvas`). +- `restaurants` → call `get_restaurants`, then render a restaurant list. + +If the demo name is `unknown` or unrecognized, render the "what can you do?" demo card instead. + +## Restaurant demo specifics + +- If the query is for a list of restaurants, use the data from the `get_restaurants` tool to populate the `updateDataModel` message. Always specify `path: "/items"` and a `value` that is an array of restaurants. +- If there are 5 or fewer restaurants, use the `single_column_list` template; if more than 5, use the `two_column_list` template. +- If the query is to book a restaurant (e.g., "USER_WANTS_TO_BOOK..."), use the `booking_form` template. +- If the query is a booking submission (e.g., "User submitted a booking..."), use the `confirmation` template. +""" + + +def get_text_prompt() -> str: + """Constructs the prompt for a text-only (no A2UI) fallback agent.""" + return """ + You are the "A2UI v0.9 Demo" agent, but the client did not enable the A2UI + UI extension, so your output MUST be a plain text response. + + - If the user asks what you can do, list the demos you support: a Material + components gallery, forms & inputs, tabs & layout, data tables, progress + indicators, dialogs & menus, a Canvas side panel, iframe components + (custom HTML and embedded URLs), and a restaurant finder. Mention that + these are best experienced in an A2UI-capable client. + - For finding restaurants: call the `get_restaurants` tool (extract cuisine, + location, and count from the query), then format the results as clear, + human-readable text, preserving any markdown links from the tool. + - For booking a table (a query like 'USER_WANTS_TO_BOOK...'): ask the user + for the details needed to book (party size, date, time, dietary needs). + - For confirming a booking (a query like 'User submitted a booking...'): + respond with a simple text confirmation of the booking details. + """ + + +if __name__ == "__main__": + # Example of how to use the A2UI Schema Manager to generate a system prompt. + version = VERSION_0_9 + demo_prompt = A2uiSchemaManager( + version, + catalogs=[ + CatalogConfig.from_path( + name="composite", + catalog_path=COMPOSITE_CATALOG_PATH, + examples_path=f"examples/{version}", + ) + ], + schema_modifiers=[remove_strict_validation], + ).generate_system_prompt( + role_description=ROLE_DESCRIPTION, + ui_description=UI_DESCRIPTION, + include_schema=True, + include_examples=True, + validate_examples=True, + ) + + print(demo_prompt) + + # This demonstrates how you could save the prompt to a file for inspection. + with open("generated_prompt.txt", "w") as f: + f.write(demo_prompt) + print("\nGenerated prompt saved to generated_prompt.txt") diff --git a/samples/community/agent/adk/gemini_enterprise/v0_9/pyproject.toml b/samples/community/agent/adk/gemini_enterprise/v0_9/pyproject.toml new file mode 100644 index 0000000000..93c8b4b6ff --- /dev/null +++ b/samples/community/agent/adk/gemini_enterprise/v0_9/pyproject.toml @@ -0,0 +1,53 @@ +# Copyright 2026 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +[project] +name = "a2ui-v09-demo" +version = "0.1.0" +description = "Sample ADK-based agent that demonstrates A2UI (Agent-to-UI) v0.9, served over the A2A protocol." +readme = "README.md" +requires-python = ">=3.14" +dependencies = [ + # The `http-server` extra pulls in `starlette` and `sse-starlette`, which + # are required by A2AStarletteApplication / JSONRPCApplication. + "a2a-sdk[http-server]>=0.3.25,<0.4", + "click>=8.1.8", + "google-adk>=1.28.1", + "google-genai>=1.27.0", + "python-dotenv>=1.1.0", + "uvicorn", + # Required for Vertex AI when GOOGLE_GENAI_USE_VERTEXAI=TRUE (Cloud Run). + "google-cloud-aiplatform>=1.84", + "jsonschema>=4.0.0", + # Published A2UI agent SDK (schema manager, catalog loading, parsing). + "a2ui-agent-sdk>=0.3.0", +] + +[tool.hatch.build.targets.wheel] +packages = ["."] + +[build-system] +requires = ["hatchling"] +build-backend = "hatchling.build" + +[tool.hatch.metadata] +allow-direct-references = true + +[[tool.uv.index]] +url = "https://pypi.org/simple" +default = true + +# Cloud Run buildpacks run the `start` script to launch the server. +[project.scripts] +start = "main:serve" diff --git a/samples/community/agent/adk/gemini_enterprise/v0_9/restaurant_data.json b/samples/community/agent/adk/gemini_enterprise/v0_9/restaurant_data.json new file mode 100644 index 0000000000..e354d145e7 --- /dev/null +++ b/samples/community/agent/adk/gemini_enterprise/v0_9/restaurant_data.json @@ -0,0 +1,66 @@ +[ + { + "name": "Xi'an Famous Foods", + "detail": "Spicy and savory hand-pulled noodles.", + "imageUrl": "http://localhost:10002/static/shrimpchowmein.jpeg", + "rating": "★★★★☆", + "infoLink": "[More Info](https://www.xianfoods.com/)", + "address": "81 St Marks Pl, New York, NY 10003" + }, + { + "name": "Han Dynasty", + "detail": "Authentic Szechuan cuisine.", + "imageUrl": "http://localhost:10002/static/mapotofu.jpeg", + "rating": "★★★★☆", + "infoLink": "[More Info](https://www.handynasty.net/)", + "address": "90 3rd Ave, New York, NY 10003" + }, + { + "name": "RedFarm", + "detail": "Modern Chinese with a farm-to-table approach.", + "imageUrl": "http://localhost:10002/static/beefbroccoli.jpeg", + "rating": "★★★★☆", + "infoLink": "[More Info](https://www.redfarmnyc.com/)", + "address": "529 Hudson St, New York, NY 10014" + }, + { + "name": "Mott 32", + "detail": "Upscale Cantonese dining.", + "imageUrl": "http://localhost:10002/static/springrolls.jpeg", + "rating": "★★★★★", + "infoLink": "[More Info](https://mott32.com/newyork/)", + "address": "111 W 57th St, New York, NY 10019" + }, + { + "name": "Hwa Yuan Szechuan", + "detail": "Famous for its cold noodles with sesame sauce.", + "imageUrl": "http://localhost:10002/static/kungpao.jpeg", + "rating": "★★★★☆", + "infoLink": "[More Info](https://hwayuannyc.com/)", + "address": "40 E Broadway, New York, NY 10002" + }, + { + "name": "Cafe China", + "detail": "Szechuan food in a 1930s Shanghai setting.", + "imageUrl": "http://localhost:10002/static/mapotofu.jpeg", + "rating": "★★★★☆", + "infoLink": "[More Info](https://www.cafechinanyc.com/)", + "address": "59 W 37th St, New York, NY 10018" + }, + { + "name": "Philippe Chow", + "detail": "High-end Beijing-style cuisine.", + "imageUrl": "http://localhost:10002/static/beefbroccoli.jpeg", + "rating": "★★★★☆", + "infoLink": "[More Info](https://www.philippechow.com/)", + "address": "33 E 60th St, New York, NY 10022" + }, + { + "name": "Chinese Tuxedo", + "detail": "Contemporary Chinese in a former opera house.", + "imageUrl": "http://localhost:10002/static/mapotofu.jpeg", + "rating": "★★★★☆", + "infoLink": "[More Info](https://chinesetuxedo.com/)", + "address": "5 Doyers St, New York, NY 10013" + } +] diff --git a/samples/community/agent/adk/gemini_enterprise/v0_9/tools.py b/samples/community/agent/adk/gemini_enterprise/v0_9/tools.py new file mode 100644 index 0000000000..3b7d769caa --- /dev/null +++ b/samples/community/agent/adk/gemini_enterprise/v0_9/tools.py @@ -0,0 +1,65 @@ +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import json +import logging +import os + +from google.adk.tools.tool_context import ToolContext + +logger = logging.getLogger(__name__) + + +def get_restaurants( + cuisine: str, location: str, tool_context: ToolContext, count: int = 5 +) -> str: + """Call this tool to get a list of restaurants based on a cuisine and location. + + 'count' is the number of restaurants to return. + """ + logger.info(f"--- TOOL CALLED: get_restaurants (count: {count}) ---") + logger.info(f" - Cuisine: {cuisine}") + logger.info(f" - Location: {location}") + + items = [] + if ( + location + and isinstance(location, str) + and ("new york" in location.lower() or "ny" in location.lower()) + ): + try: + script_dir = os.path.dirname(__file__) + file_path = os.path.join(script_dir, "restaurant_data.json") + with open(file_path) as f: + restaurant_data_str = f.read() + if base_url := tool_context.state.get("base_url"): + restaurant_data_str = restaurant_data_str.replace( + "http://localhost:10002", base_url + ) + logger.info(f"Updated base URL from tool context: {base_url}") + all_items = json.loads(restaurant_data_str) + + # Slice the list to return only the requested number of items + items = all_items[:count] + logger.info( + f" - Success: Found {len(all_items)} restaurants, returning" + f" {len(items)}." + ) + + except FileNotFoundError: + logger.error(f" - Error: restaurant_data.json not found at {file_path}") + except json.JSONDecodeError: + logger.error(f" - Error: Failed to decode JSON from {file_path}") + + return json.dumps(items) diff --git a/samples/community/agent/adk/gemini_enterprise/v0_9/uv.lock b/samples/community/agent/adk/gemini_enterprise/v0_9/uv.lock new file mode 100644 index 0000000000..1be69920f5 --- /dev/null +++ b/samples/community/agent/adk/gemini_enterprise/v0_9/uv.lock @@ -0,0 +1,1612 @@ +version = 1 +revision = 3 +requires-python = ">=3.11" +resolution-markers = [ + "python_full_version >= '3.14'", + "python_full_version == '3.13.*'", + "python_full_version < '3.13'", +] + +[[package]] +name = "a2a-sdk" +version = "0.3.26" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "google-api-core" }, + { name = "httpx" }, + { name = "httpx-sse" }, + { name = "protobuf" }, + { name = "pydantic" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/be/97/a6840e01795b182ce751ca165430d46459927cde9bfab838087cbb24aef7/a2a_sdk-0.3.26.tar.gz", hash = "sha256:44068e2d037afbb07ab899267439e9bc7eaa7ac2af94f1e8b239933c993ad52d", size = 274598, upload-time = "2026-04-09T15:21:13.902Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/dd/d5/51f4ee1bf3b736add42a542d3c8a3fd3fa85f3d36c17972127defc46c26f/a2a_sdk-0.3.26-py3-none-any.whl", hash = "sha256:754e0573f6d33b225c1d8d51f640efa69cbbed7bdfb06ce9c3540ea9f58d4a91", size = 151016, upload-time = "2026-04-09T15:21:12.35Z" }, +] + +[package.optional-dependencies] +http-server = [ + { name = "fastapi" }, + { name = "sse-starlette" }, + { name = "starlette" }, +] + +[[package]] +name = "a2ui-agent-sdk" +version = "0.3.0" +source = { registry = "https://pypi.org/simple" } +resolution-markers = [ + "python_full_version >= '3.14'", +] +dependencies = [ + { name = "a2a-sdk", marker = "python_full_version >= '3.14'" }, + { name = "a2ui-core", version = "0.1.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.14'" }, + { name = "google-adk", marker = "python_full_version >= '3.14'" }, + { name = "google-genai", marker = "python_full_version >= '3.14'" }, + { name = "jsonschema", marker = "python_full_version >= '3.14'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/af/b4/5210113ebfd374a59b2deea9daa239f5d979351e4365e07408cb0af37212/a2ui_agent_sdk-0.3.0.tar.gz", hash = "sha256:6d9b0add1be377f8863c4a840fb6f931702af294535142dbbe2ad76e78bf76b6", size = 125265, upload-time = "2026-06-23T20:52:52.693Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/76/61/1898f0ae71c8a179c4def61b82316b8333d497e703374158fff80a9d0d9d/a2ui_agent_sdk-0.3.0-py3-none-any.whl", hash = "sha256:34ad8ec9b08c79c8f96b64928077345822d2f1c0936ff7f8c4374d3d8965e8ff", size = 88732, upload-time = "2026-06-23T20:52:50.296Z" }, +] + +[[package]] +name = "a2ui-agent-sdk" +version = "0.4.0" +source = { registry = "https://pypi.org/simple" } +resolution-markers = [ + "python_full_version == '3.13.*'", + "python_full_version < '3.13'", +] +dependencies = [ + { name = "a2a-sdk", marker = "python_full_version < '3.14'" }, + { name = "a2ui-core", version = "0.1.1", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.14'" }, + { name = "antlr4-python3-runtime", marker = "python_full_version < '3.14'" }, + { name = "google-adk", marker = "python_full_version < '3.14'" }, + { name = "google-genai", marker = "python_full_version < '3.14'" }, + { name = "jsonschema", marker = "python_full_version < '3.14'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/36/57/1911d62db025dec6200b410e858d2691aebdf77fc2cf436837a012452f92/a2ui_agent_sdk-0.4.0.tar.gz", hash = "sha256:4b431b92a7ff55846a3e4b7fb18d591c27e6a673986b039ecdab2758e76c0074", size = 128897, upload-time = "2026-07-08T06:25:04.037Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/60/76/6bcf71e51bd22cfff88ab88757e5f7f658bbe172ab0411abb3acb7f3ec82/a2ui_agent_sdk-0.4.0-py3-none-any.whl", hash = "sha256:3a073bf93998f277d00f77baf37402ac95ab2b6048aa7e4f9e1db9c95be364c9", size = 129873, upload-time = "2026-07-08T06:25:01.577Z" }, +] + +[[package]] +name = "a2ui-core" +version = "0.1.0" +source = { registry = "https://pypi.org/simple" } +resolution-markers = [ + "python_full_version >= '3.14'", +] +dependencies = [ + { name = "jsonschema", marker = "python_full_version >= '3.14'" }, + { name = "pydantic", marker = "python_full_version >= '3.14'" }, + { name = "referencing", marker = "python_full_version >= '3.14'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/db/54/dd964dea4d38c242aaa8854f19ad0a5ead6b917740364522c4483310cb3d/a2ui_core-0.1.0.tar.gz", hash = "sha256:007d77ae8b389a07021813c67bc80578159fe2f4872f849c8fa0b08002c34424", size = 99684, upload-time = "2026-06-23T20:21:02.092Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/df/c4/f36880eff24bbb9cc7a9e0591d21070563a56878507be7845a88f1667769/a2ui_core-0.1.0-py3-none-any.whl", hash = "sha256:f32ddab09ff3094dd77f66654907fdc1b0075f631f93fc08936c664013f39511", size = 72225, upload-time = "2026-06-23T20:20:57.167Z" }, +] + +[[package]] +name = "a2ui-core" +version = "0.1.1" +source = { registry = "https://pypi.org/simple" } +resolution-markers = [ + "python_full_version == '3.13.*'", + "python_full_version < '3.13'", +] +dependencies = [ + { name = "jsonschema", marker = "python_full_version < '3.14'" }, + { name = "pydantic", marker = "python_full_version < '3.14'" }, + { name = "referencing", marker = "python_full_version < '3.14'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/d9/51/477ea2d173f77d54f1a3b963fafc811a228427d077442bc7b6cc7409787d/a2ui_core-0.1.1.tar.gz", hash = "sha256:591df9357cd84a3ccf409132a741eb1fbb060be73de0eebb3dcfdd4c7b33180d", size = 84241, upload-time = "2026-07-08T03:49:36.958Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/2e/14/2344f6edc4b381db477d4387a28d1c84a56614962cc16f55074be981a12a/a2ui_core-0.1.1-py3-none-any.whl", hash = "sha256:8857e1942b8b1bab530efa0c20f6f9048c5771b47b3b98b3bc1ca28d39480069", size = 75389, upload-time = "2026-07-08T03:49:35.698Z" }, +] + +[[package]] +name = "a2ui-v09-demo" +version = "0.1.0" +source = { editable = "." } +dependencies = [ + { name = "a2a-sdk", extra = ["http-server"] }, + { name = "a2ui-agent-sdk", version = "0.3.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.14'" }, + { name = "a2ui-agent-sdk", version = "0.4.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.14'" }, + { name = "click" }, + { name = "google-adk" }, + { name = "google-cloud-aiplatform" }, + { name = "google-genai" }, + { name = "jsonschema" }, + { name = "python-dotenv" }, + { name = "uvicorn" }, +] + +[package.metadata] +requires-dist = [ + { name = "a2a-sdk", extras = ["http-server"], specifier = ">=0.3.25,<0.4" }, + { name = "a2ui-agent-sdk", specifier = ">=0.3.0" }, + { name = "click", specifier = ">=8.1.8" }, + { name = "google-adk", specifier = ">=1.28.1" }, + { name = "google-cloud-aiplatform", specifier = ">=1.84" }, + { name = "google-genai", specifier = ">=1.27.0" }, + { name = "jsonschema", specifier = ">=4.0.0" }, + { name = "python-dotenv", specifier = ">=1.1.0" }, + { name = "uvicorn" }, +] + +[[package]] +name = "aiosqlite" +version = "0.22.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/4e/8a/64761f4005f17809769d23e518d915db74e6310474e733e3593cfc854ef1/aiosqlite-0.22.1.tar.gz", hash = "sha256:043e0bd78d32888c0a9ca90fc788b38796843360c855a7262a532813133a0650", size = 14821, upload-time = "2025-12-23T19:25:43.997Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/00/b7/e3bf5133d697a08128598c8d0abc5e16377b51465a33756de24fa7dee953/aiosqlite-0.22.1-py3-none-any.whl", hash = "sha256:21c002eb13823fad740196c5a2e9d8e62f6243bd9e7e4a1f87fb5e44ecb4fceb", size = 17405, upload-time = "2025-12-23T19:25:42.139Z" }, +] + +[[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 = "antlr4-python3-runtime" +version = "4.13.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/33/5f/2cdf6f7aca3b20d3f316e9f505292e1f256a32089bd702034c29ebde6242/antlr4_python3_runtime-4.13.2.tar.gz", hash = "sha256:909b647e1d2fc2b70180ac586df3933e38919c85f98ccc656a96cd3f25ef3916", size = 117467, upload-time = "2024-08-03T19:00:12.757Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/89/03/a851e84fcbb85214dc637b6378121ef9a0dd61b4c65264675d8a5c9b1ae7/antlr4_python3_runtime-4.13.2-py3-none-any.whl", hash = "sha256:fe3835eb8d33daece0e799090eda89719dbccee7aa39ef94eed3818cafa5a7e8", size = 144462, upload-time = "2024-08-03T19:00:11.134Z" }, +] + +[[package]] +name = "anyio" +version = "4.13.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "idna" }, + { name = "typing-extensions", marker = "python_full_version < '3.13'" }, +] +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 = "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 = "authlib" +version = "1.7.2" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "cryptography" }, + { name = "joserfc" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/36/98/7d93f30d029643c0275dbc0bd6d5a6f670661ee6c9a94d93af7ab4887600/authlib-1.7.2.tar.gz", hash = "sha256:2cea25fefcd4e7173bdf1372c0afc265c8034b23a8cd5dcb6a9164b826c64231", size = 176511, upload-time = "2026-05-06T08:10:23.116Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/fb/95/adcb68e20c34162e9135f370d6e31737719c2b6f94bc953fe7ed1f10fe21/authlib-1.7.2-py2.py3-none-any.whl", hash = "sha256:3e1faedc9d87e7d56a164eca3ccb6ace0d61b94abe83e92242f8dc8bba9b4a9f", size = 259548, upload-time = "2026-05-06T08:10:21.436Z" }, +] + +[[package]] +name = "certifi" +version = "2026.5.20" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/f3/ce/ee2ecad540810a79593028e88299baeae54d346cc7a0d94b6199988b89b1/certifi-2026.5.20.tar.gz", hash = "sha256:69dea482ab64caa7b9f6aba1c6bf48bb6a5448d1c0f1b17ab42ad8c763a5344d", size = 135422, upload-time = "2026-05-20T11:46:50.073Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/59/8c/57e832b7af6d7c5abe66eb3fbe3a3a32f4d11ea23a1aa7131371035be991/certifi-2026.5.20-py3-none-any.whl", hash = "sha256:3c52e209ba0a4ad7aebe60436a4ab349c39e1e602e8c134221e546902ad25897", size = 134134, upload-time = "2026-05-20T11:46:48.578Z" }, +] + +[[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/12/4a/3dfd5f7850cbf0d06dc84ba9aa00db766b52ca38d8b86e3a38314d52498c/cffi-2.0.0-cp311-cp311-macosx_10_13_x86_64.whl", hash = "sha256:b4c854ef3adc177950a8dfc81a86f5115d2abd545751a304c5bcf2c2c7283cfe", size = 184344, upload-time = "2025-09-08T23:22:26.456Z" }, + { url = "https://files.pythonhosted.org/packages/4f/8b/f0e4c441227ba756aafbe78f117485b25bb26b1c059d01f137fa6d14896b/cffi-2.0.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:2de9a304e27f7596cd03d16f1b7c72219bd944e99cc52b84d0145aefb07cbd3c", size = 180560, upload-time = "2025-09-08T23:22:28.197Z" }, + { url = "https://files.pythonhosted.org/packages/b1/b7/1200d354378ef52ec227395d95c2576330fd22a869f7a70e88e1447eb234/cffi-2.0.0-cp311-cp311-manylinux1_i686.manylinux2014_i686.manylinux_2_17_i686.manylinux_2_5_i686.whl", hash = "sha256:baf5215e0ab74c16e2dd324e8ec067ef59e41125d3eade2b863d294fd5035c92", size = 209613, upload-time = "2025-09-08T23:22:29.475Z" }, + { url = "https://files.pythonhosted.org/packages/b8/56/6033f5e86e8cc9bb629f0077ba71679508bdf54a9a5e112a3c0b91870332/cffi-2.0.0-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:730cacb21e1bdff3ce90babf007d0a0917cc3e6492f336c2f0134101e0944f93", size = 216476, upload-time = "2025-09-08T23:22:31.063Z" }, + { url = "https://files.pythonhosted.org/packages/dc/7f/55fecd70f7ece178db2f26128ec41430d8720f2d12ca97bf8f0a628207d5/cffi-2.0.0-cp311-cp311-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:6824f87845e3396029f3820c206e459ccc91760e8fa24422f8b0c3d1731cbec5", size = 203374, upload-time = "2025-09-08T23:22:32.507Z" }, + { url = "https://files.pythonhosted.org/packages/84/ef/a7b77c8bdc0f77adc3b46888f1ad54be8f3b7821697a7b89126e829e676a/cffi-2.0.0-cp311-cp311-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:9de40a7b0323d889cf8d23d1ef214f565ab154443c42737dfe52ff82cf857664", size = 202597, upload-time = "2025-09-08T23:22:34.132Z" }, + { url = "https://files.pythonhosted.org/packages/d7/91/500d892b2bf36529a75b77958edfcd5ad8e2ce4064ce2ecfeab2125d72d1/cffi-2.0.0-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:8941aaadaf67246224cee8c3803777eed332a19d909b47e29c9842ef1e79ac26", size = 215574, upload-time = "2025-09-08T23:22:35.443Z" }, + { url = "https://files.pythonhosted.org/packages/44/64/58f6255b62b101093d5df22dcb752596066c7e89dd725e0afaed242a61be/cffi-2.0.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:a05d0c237b3349096d3981b727493e22147f934b20f6f125a3eba8f994bec4a9", size = 218971, upload-time = "2025-09-08T23:22:36.805Z" }, + { url = "https://files.pythonhosted.org/packages/ab/49/fa72cebe2fd8a55fbe14956f9970fe8eb1ac59e5df042f603ef7c8ba0adc/cffi-2.0.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:94698a9c5f91f9d138526b48fe26a199609544591f859c870d477351dc7b2414", size = 211972, upload-time = "2025-09-08T23:22:38.436Z" }, + { url = "https://files.pythonhosted.org/packages/0b/28/dd0967a76aab36731b6ebfe64dec4e981aff7e0608f60c2d46b46982607d/cffi-2.0.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:5fed36fccc0612a53f1d4d9a816b50a36702c28a2aa880cb8a122b3466638743", size = 217078, upload-time = "2025-09-08T23:22:39.776Z" }, + { url = "https://files.pythonhosted.org/packages/2b/c0/015b25184413d7ab0a410775fdb4a50fca20f5589b5dab1dbbfa3baad8ce/cffi-2.0.0-cp311-cp311-win32.whl", hash = "sha256:c649e3a33450ec82378822b3dad03cc228b8f5963c0c12fc3b1e0ab940f768a5", size = 172076, upload-time = "2025-09-08T23:22:40.95Z" }, + { url = "https://files.pythonhosted.org/packages/ae/8f/dc5531155e7070361eb1b7e4c1a9d896d0cb21c49f807a6c03fd63fc877e/cffi-2.0.0-cp311-cp311-win_amd64.whl", hash = "sha256:66f011380d0e49ed280c789fbd08ff0d40968ee7b665575489afa95c98196ab5", size = 182820, upload-time = "2025-09-08T23:22:42.463Z" }, + { url = "https://files.pythonhosted.org/packages/95/5c/1b493356429f9aecfd56bc171285a4c4ac8697f76e9bbbbb105e537853a1/cffi-2.0.0-cp311-cp311-win_arm64.whl", hash = "sha256:c6638687455baf640e37344fe26d37c404db8b80d037c3d29f58fe8d1c3b194d", size = 177635, upload-time = "2025-09-08T23:22:43.623Z" }, + { url = "https://files.pythonhosted.org/packages/ea/47/4f61023ea636104d4f16ab488e268b93008c3d0bb76893b1b31db1f96802/cffi-2.0.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:6d02d6655b0e54f54c4ef0b94eb6be0607b70853c45ce98bd278dc7de718be5d", size = 185271, upload-time = "2025-09-08T23:22:44.795Z" }, + { url = "https://files.pythonhosted.org/packages/df/a2/781b623f57358e360d62cdd7a8c681f074a71d445418a776eef0aadb4ab4/cffi-2.0.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:8eca2a813c1cb7ad4fb74d368c2ffbbb4789d377ee5bb8df98373c2cc0dee76c", size = 181048, upload-time = "2025-09-08T23:22:45.938Z" }, + { url = "https://files.pythonhosted.org/packages/ff/df/a4f0fbd47331ceeba3d37c2e51e9dfc9722498becbeec2bd8bc856c9538a/cffi-2.0.0-cp312-cp312-manylinux1_i686.manylinux2014_i686.manylinux_2_17_i686.manylinux_2_5_i686.whl", hash = "sha256:21d1152871b019407d8ac3985f6775c079416c282e431a4da6afe7aefd2bccbe", size = 212529, upload-time = "2025-09-08T23:22:47.349Z" }, + { url = "https://files.pythonhosted.org/packages/d5/72/12b5f8d3865bf0f87cf1404d8c374e7487dcf097a1c91c436e72e6badd83/cffi-2.0.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:b21e08af67b8a103c71a250401c78d5e0893beff75e28c53c98f4de42f774062", size = 220097, upload-time = "2025-09-08T23:22:48.677Z" }, + { url = "https://files.pythonhosted.org/packages/c2/95/7a135d52a50dfa7c882ab0ac17e8dc11cec9d55d2c18dda414c051c5e69e/cffi-2.0.0-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:1e3a615586f05fc4065a8b22b8152f0c1b00cdbc60596d187c2a74f9e3036e4e", size = 207983, upload-time = "2025-09-08T23:22:50.06Z" }, + { url = "https://files.pythonhosted.org/packages/3a/c8/15cb9ada8895957ea171c62dc78ff3e99159ee7adb13c0123c001a2546c1/cffi-2.0.0-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:81afed14892743bbe14dacb9e36d9e0e504cd204e0b165062c488942b9718037", size = 206519, upload-time = "2025-09-08T23:22:51.364Z" }, + { url = "https://files.pythonhosted.org/packages/78/2d/7fa73dfa841b5ac06c7b8855cfc18622132e365f5b81d02230333ff26e9e/cffi-2.0.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:3e17ed538242334bf70832644a32a7aae3d83b57567f9fd60a26257e992b79ba", size = 219572, upload-time = "2025-09-08T23:22:52.902Z" }, + { url = "https://files.pythonhosted.org/packages/07/e0/267e57e387b4ca276b90f0434ff88b2c2241ad72b16d31836adddfd6031b/cffi-2.0.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:3925dd22fa2b7699ed2617149842d2e6adde22b262fcbfada50e3d195e4b3a94", size = 222963, upload-time = "2025-09-08T23:22:54.518Z" }, + { url = "https://files.pythonhosted.org/packages/b6/75/1f2747525e06f53efbd878f4d03bac5b859cbc11c633d0fb81432d98a795/cffi-2.0.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:2c8f814d84194c9ea681642fd164267891702542f028a15fc97d4674b6206187", size = 221361, upload-time = "2025-09-08T23:22:55.867Z" }, + { url = "https://files.pythonhosted.org/packages/7b/2b/2b6435f76bfeb6bbf055596976da087377ede68df465419d192acf00c437/cffi-2.0.0-cp312-cp312-win32.whl", hash = "sha256:da902562c3e9c550df360bfa53c035b2f241fed6d9aef119048073680ace4a18", size = 172932, upload-time = "2025-09-08T23:22:57.188Z" }, + { url = "https://files.pythonhosted.org/packages/f8/ed/13bd4418627013bec4ed6e54283b1959cf6db888048c7cf4b4c3b5b36002/cffi-2.0.0-cp312-cp312-win_amd64.whl", hash = "sha256:da68248800ad6320861f129cd9c1bf96ca849a2771a59e0344e88681905916f5", size = 183557, upload-time = "2025-09-08T23:22:58.351Z" }, + { url = "https://files.pythonhosted.org/packages/95/31/9f7f93ad2f8eff1dbc1c3656d7ca5bfd8fb52c9d786b4dcf19b2d02217fa/cffi-2.0.0-cp312-cp312-win_arm64.whl", hash = "sha256:4671d9dd5ec934cb9a73e7ee9676f9362aba54f7f34910956b84d727b0d73fb6", size = 177762, upload-time = "2025-09-08T23:22:59.668Z" }, + { 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/c2/d7/b5b7020a0565c2e9fa8c09f4b5fa6232feb326b8c20081ccded47ea368fd/charset_normalizer-3.4.7-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:7641bb8895e77f921102f72833904dcd9901df5d6d72a2ab8f31d04b7e51e4e7", size = 309705, upload-time = "2026-04-02T09:26:02.191Z" }, + { url = "https://files.pythonhosted.org/packages/5a/53/58c29116c340e5456724ecd2fff4196d236b98f3da97b404bc5e51ac3493/charset_normalizer-3.4.7-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:202389074300232baeb53ae2569a60901f7efadd4245cf3a3bf0617d60b439d7", size = 206419, upload-time = "2026-04-02T09:26:03.583Z" }, + { url = "https://files.pythonhosted.org/packages/b2/02/e8146dc6591a37a00e5144c63f29fb7c97a734ea8a111190783c0e60ab63/charset_normalizer-3.4.7-cp311-cp311-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:30b8d1d8c52a48c2c5690e152c169b673487a2a58de1ec7393196753063fcd5e", size = 227901, upload-time = "2026-04-02T09:26:04.738Z" }, + { url = "https://files.pythonhosted.org/packages/fb/73/77486c4cd58f1267bf17db420e930c9afa1b3be3fe8c8b8ebbebc9624359/charset_normalizer-3.4.7-cp311-cp311-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:532bc9bf33a68613fd7d65e4b1c71a6a38d7d42604ecf239c77392e9b4e8998c", size = 222742, upload-time = "2026-04-02T09:26:06.36Z" }, + { url = "https://files.pythonhosted.org/packages/a1/fa/f74eb381a7d94ded44739e9d94de18dc5edc9c17fb8c11f0a6890696c0a9/charset_normalizer-3.4.7-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:2fe249cb4651fd12605b7288b24751d8bfd46d35f12a20b1ba33dea122e690df", size = 214061, upload-time = "2026-04-02T09:26:08.347Z" }, + { url = "https://files.pythonhosted.org/packages/dc/92/42bd3cefcf7687253fb86694b45f37b733c97f59af3724f356fa92b8c344/charset_normalizer-3.4.7-cp311-cp311-manylinux_2_31_armv7l.whl", hash = "sha256:65bcd23054beab4d166035cabbc868a09c1a49d1efe458fe8e4361215df40265", size = 199239, upload-time = "2026-04-02T09:26:09.823Z" }, + { url = "https://files.pythonhosted.org/packages/4c/3d/069e7184e2aa3b3cddc700e3dd267413dc259854adc3380421c805c6a17d/charset_normalizer-3.4.7-cp311-cp311-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:08e721811161356f97b4059a9ba7bafb23ea5ee2255402c42881c214e173c6b4", size = 210173, upload-time = "2026-04-02T09:26:10.953Z" }, + { url = "https://files.pythonhosted.org/packages/62/51/9d56feb5f2e7074c46f93e0ebdbe61f0848ee246e2f0d89f8e20b89ebb8f/charset_normalizer-3.4.7-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:e060d01aec0a910bdccb8be71faf34e7799ce36950f8294c8bf612cba65a2c9e", size = 209841, upload-time = "2026-04-02T09:26:12.142Z" }, + { url = "https://files.pythonhosted.org/packages/d2/59/893d8f99cc4c837dda1fe2f1139079703deb9f321aabcb032355de13b6c7/charset_normalizer-3.4.7-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:38c0109396c4cfc574d502df99742a45c72c08eff0a36158b6f04000043dbf38", size = 200304, upload-time = "2026-04-02T09:26:13.711Z" }, + { url = "https://files.pythonhosted.org/packages/7d/1d/ee6f3be3464247578d1ed5c46de545ccc3d3ff933695395c402c21fa6b77/charset_normalizer-3.4.7-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:1c2a768fdd44ee4a9339a9b0b130049139b8ce3c01d2ce09f67f5a68048d477c", size = 229455, upload-time = "2026-04-02T09:26:14.941Z" }, + { url = "https://files.pythonhosted.org/packages/54/bb/8fb0a946296ea96a488928bdce8ef99023998c48e4713af533e9bb98ef07/charset_normalizer-3.4.7-cp311-cp311-musllinux_1_2_riscv64.whl", hash = "sha256:1a87ca9d5df6fe460483d9a5bbf2b18f620cbed41b432e2bddb686228282d10b", size = 210036, upload-time = "2026-04-02T09:26:16.478Z" }, + { url = "https://files.pythonhosted.org/packages/9a/bc/015b2387f913749f82afd4fcba07846d05b6d784dd16123cb66860e0237d/charset_normalizer-3.4.7-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:d635aab80466bc95771bb78d5370e74d36d1fe31467b6b29b8b57b2a3cd7d22c", size = 224739, upload-time = "2026-04-02T09:26:17.751Z" }, + { url = "https://files.pythonhosted.org/packages/17/ab/63133691f56baae417493cba6b7c641571a2130eb7bceba6773367ab9ec5/charset_normalizer-3.4.7-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:ae196f021b5e7c78e918242d217db021ed2a6ace2bc6ae94c0fc596221c7f58d", size = 216277, upload-time = "2026-04-02T09:26:18.981Z" }, + { url = "https://files.pythonhosted.org/packages/06/6d/3be70e827977f20db77c12a97e6a9f973631a45b8d186c084527e53e77a4/charset_normalizer-3.4.7-cp311-cp311-win32.whl", hash = "sha256:adb2597b428735679446b46c8badf467b4ca5f5056aae4d51a19f9570301b1ad", size = 147819, upload-time = "2026-04-02T09:26:20.295Z" }, + { url = "https://files.pythonhosted.org/packages/20/d9/5f67790f06b735d7c7637171bbfd89882ad67201891b7275e51116ed8207/charset_normalizer-3.4.7-cp311-cp311-win_amd64.whl", hash = "sha256:8e385e4267ab76874ae30db04c627faaaf0b509e1ccc11a95b3fc3e83f855c00", size = 159281, upload-time = "2026-04-02T09:26:21.74Z" }, + { url = "https://files.pythonhosted.org/packages/ca/83/6413f36c5a34afead88ce6f66684d943d91f233d76dd083798f9602b75ae/charset_normalizer-3.4.7-cp311-cp311-win_arm64.whl", hash = "sha256:d4a48e5b3c2a489fae013b7589308a40146ee081f6f509e047e0e096084ceca1", size = 147843, upload-time = "2026-04-02T09:26:22.901Z" }, + { url = "https://files.pythonhosted.org/packages/0c/eb/4fc8d0a7110eb5fc9cc161723a34a8a6c200ce3b4fbf681bc86feee22308/charset_normalizer-3.4.7-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:eca9705049ad3c7345d574e3510665cb2cf844c2f2dcfe675332677f081cbd46", size = 311328, upload-time = "2026-04-02T09:26:24.331Z" }, + { url = "https://files.pythonhosted.org/packages/f8/e3/0fadc706008ac9d7b9b5be6dc767c05f9d3e5df51744ce4cc9605de7b9f4/charset_normalizer-3.4.7-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6178f72c5508bfc5fd446a5905e698c6212932f25bcdd4b47a757a50605a90e2", size = 208061, upload-time = "2026-04-02T09:26:25.568Z" }, + { url = "https://files.pythonhosted.org/packages/42/f0/3dd1045c47f4a4604df85ec18ad093912ae1344ac706993aff91d38773a2/charset_normalizer-3.4.7-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:e1421b502d83040e6d7fb2fb18dff63957f720da3d77b2fbd3187ceb63755d7b", size = 229031, upload-time = "2026-04-02T09:26:26.865Z" }, + { url = "https://files.pythonhosted.org/packages/dc/67/675a46eb016118a2fbde5a277a5d15f4f69d5f3f5f338e5ee2f8948fcf43/charset_normalizer-3.4.7-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:edac0f1ab77644605be2cbba52e6b7f630731fc42b34cb0f634be1a6eface56a", size = 225239, upload-time = "2026-04-02T09:26:28.044Z" }, + { url = "https://files.pythonhosted.org/packages/4b/f8/d0118a2f5f23b02cd166fa385c60f9b0d4f9194f574e2b31cef350ad7223/charset_normalizer-3.4.7-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:5649fd1c7bade02f320a462fdefd0b4bd3ce036065836d4f42e0de958038e116", size = 216589, upload-time = "2026-04-02T09:26:29.239Z" }, + { url = "https://files.pythonhosted.org/packages/b1/f1/6d2b0b261b6c4ceef0fcb0d17a01cc5bc53586c2d4796fa04b5c540bc13d/charset_normalizer-3.4.7-cp312-cp312-manylinux_2_31_armv7l.whl", hash = "sha256:203104ed3e428044fd943bc4bf45fa73c0730391f9621e37fe39ecf477b128cb", size = 202733, upload-time = "2026-04-02T09:26:30.5Z" }, + { url = "https://files.pythonhosted.org/packages/6f/c0/7b1f943f7e87cc3db9626ba17807d042c38645f0a1d4415c7a14afb5591f/charset_normalizer-3.4.7-cp312-cp312-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:298930cec56029e05497a76988377cbd7457ba864beeea92ad7e844fe74cd1f1", size = 212652, upload-time = "2026-04-02T09:26:31.709Z" }, + { url = "https://files.pythonhosted.org/packages/38/dd/5a9ab159fe45c6e72079398f277b7d2b523e7f716acc489726115a910097/charset_normalizer-3.4.7-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:708838739abf24b2ceb208d0e22403dd018faeef86ddac04319a62ae884c4f15", size = 211229, upload-time = "2026-04-02T09:26:33.282Z" }, + { url = "https://files.pythonhosted.org/packages/d5/ff/531a1cad5ca855d1c1a8b69cb71abfd6d85c0291580146fda7c82857caa1/charset_normalizer-3.4.7-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:0f7eb884681e3938906ed0434f20c63046eacd0111c4ba96f27b76084cd679f5", size = 203552, upload-time = "2026-04-02T09:26:34.845Z" }, + { url = "https://files.pythonhosted.org/packages/c1/4c/a5fb52d528a8ca41f7598cb619409ece30a169fbdf9cdce592e53b46c3a6/charset_normalizer-3.4.7-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:4dc1e73c36828f982bfe79fadf5919923f8a6f4df2860804db9a98c48824ce8d", size = 230806, upload-time = "2026-04-02T09:26:36.152Z" }, + { url = "https://files.pythonhosted.org/packages/59/7a/071feed8124111a32b316b33ae4de83d36923039ef8cf48120266844285b/charset_normalizer-3.4.7-cp312-cp312-musllinux_1_2_riscv64.whl", hash = "sha256:aed52fea0513bac0ccde438c188c8a471c4e0f457c2dd20cdbf6ea7a450046c7", size = 212316, upload-time = "2026-04-02T09:26:37.672Z" }, + { url = "https://files.pythonhosted.org/packages/fd/35/f7dba3994312d7ba508e041eaac39a36b120f32d4c8662b8814dab876431/charset_normalizer-3.4.7-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:fea24543955a6a729c45a73fe90e08c743f0b3334bbf3201e6c4bc1b0c7fa464", size = 227274, upload-time = "2026-04-02T09:26:38.93Z" }, + { url = "https://files.pythonhosted.org/packages/8a/2d/a572df5c9204ab7688ec1edc895a73ebded3b023bb07364710b05dd1c9be/charset_normalizer-3.4.7-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:bb6d88045545b26da47aa879dd4a89a71d1dce0f0e549b1abcb31dfe4a8eac49", size = 218468, upload-time = "2026-04-02T09:26:40.17Z" }, + { url = "https://files.pythonhosted.org/packages/86/eb/890922a8b03a568ca2f336c36585a4713c55d4d67bf0f0c78924be6315ca/charset_normalizer-3.4.7-cp312-cp312-win32.whl", hash = "sha256:2257141f39fe65a3fdf38aeccae4b953e5f3b3324f4ff0daf9f15b8518666a2c", size = 148460, upload-time = "2026-04-02T09:26:41.416Z" }, + { url = "https://files.pythonhosted.org/packages/35/d9/0e7dffa06c5ab081f75b1b786f0aefc88365825dfcd0ac544bdb7b2b6853/charset_normalizer-3.4.7-cp312-cp312-win_amd64.whl", hash = "sha256:5ed6ab538499c8644b8a3e18debabcd7ce684f3fa91cf867521a7a0279cab2d6", size = 159330, upload-time = "2026-04-02T09:26:42.554Z" }, + { url = "https://files.pythonhosted.org/packages/9e/5d/481bcc2a7c88ea6b0878c299547843b2521ccbc40980cb406267088bc701/charset_normalizer-3.4.7-cp312-cp312-win_arm64.whl", hash = "sha256:56be790f86bfb2c98fb742ce566dfb4816e5a83384616ab59c49e0604d49c51d", size = 147828, upload-time = "2026-04-02T09:26:44.075Z" }, + { 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.4.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "colorama", marker = "sys_platform == 'win32'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/9b/98/518d8e5081007684232226f475082b30087d0f585e8457db087298259f49/click-8.4.1.tar.gz", hash = "sha256:918b5633eddf6b41c32d4f454bf0de810065c74e3f7dbf8ee5452f8be88d3e96", size = 353007, upload-time = "2026-05-22T04:08:37.769Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/c7/0d/67e5b4109ea4a837e80daa87c2c696711955e40449a97e8926672534def2/click-8.4.1-py3-none-any.whl", hash = "sha256:482be17c6991b8c19c5429a1e995d9b0efdbb63172824c41f99965dc0ade8ec2", size = 116639, upload-time = "2026-05-22T04:08:35.26Z" }, +] + +[[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 = "cryptography" +version = "48.0.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "cffi", marker = "platform_python_implementation != 'PyPy'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/12/45/870e7f4bef50e5f53b9f51d4428aee5290eedf58ba443f16b1ebb7ab8e66/cryptography-48.0.1.tar.gz", hash = "sha256:266f4ee051abb2f725b74ef8072b521ce1feacf685a3364fa6a6b45548db791a", size = 832989, upload-time = "2026-06-09T22:32:31.8Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/1b/bc/ee4137cbbe105652c0ee4252792b78fc8e7afa4b8e61d9d5dc05a7f45731/cryptography-48.0.1-cp311-abi3-macosx_10_9_universal2.whl", hash = "sha256:3e4a1a3232eef2e6c732827d5722db29a0cc8b27af2a4d865b094cf954be9ca1", size = 8008324, upload-time = "2026-06-09T22:31:00.702Z" }, + { url = "https://files.pythonhosted.org/packages/d5/85/6379d42181bfc713094f081360fc5784d6c816b599d45e7f082502d173ce/cryptography-48.0.1-cp311-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:32143b24adb918f078134e1e230f1eb8cc04886b92c28b5f0041aaf3e5699225", size = 4696243, upload-time = "2026-06-09T22:32:33.446Z" }, + { url = "https://files.pythonhosted.org/packages/9c/87/c85d147b53323c7eb4d850920c8901377323c2a0ff8d79c262d4fee89aa2/cryptography-48.0.1-cp311-abi3-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:f0d27a5696721ef7a672b8c810f6aded391058e0b9486e63e6d93baf765da691", size = 4713235, upload-time = "2026-06-09T22:31:40.141Z" }, + { url = "https://files.pythonhosted.org/packages/79/58/67cbf8cf1ee7c54b439ca07bbecf8362c07afc11a3724fea70f745784add/cryptography-48.0.1-cp311-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:eb86ce1af36fe65041b6db9a8bb064ee621a7e5fded0f80d475ec243477cd242", size = 4702323, upload-time = "2026-06-09T22:31:42.191Z" }, + { url = "https://files.pythonhosted.org/packages/89/c6/24266ac10c47f6cd2a865f4446062b466da1d1f10b27189eac00e61bf0c9/cryptography-48.0.1-cp311-abi3-manylinux_2_28_ppc64le.whl", hash = "sha256:b024e784ad6c077ee0147b35ea9cbfc1e34e1fd4c1dcca214c2794d73a12df08", size = 5300085, upload-time = "2026-06-09T22:31:58.703Z" }, + { url = "https://files.pythonhosted.org/packages/d2/bb/cc4b78784f97efc8c5874c2a9743708d172be6663024b34a0467885ae0c8/cryptography-48.0.1-cp311-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:3752f2dbc8f07a30aad2932c986cea495b03bb554887828225da104f732852b6", size = 4746137, upload-time = "2026-06-09T22:31:31.01Z" }, + { url = "https://files.pythonhosted.org/packages/1f/52/0c44de3f5267f8fbe8e835138017522a333436166e406f0db9b9e6e3033f/cryptography-48.0.1-cp311-abi3-manylinux_2_31_armv7l.whl", hash = "sha256:bd81490cd5801d755cf97bb68ac191f14b708470b1c7cf4580f669b9c9264cd8", size = 4333867, upload-time = "2026-06-09T22:32:28.096Z" }, + { url = "https://files.pythonhosted.org/packages/9a/2e/772d7adbfa931537bc401640b7cac9976bff689bda187833e5d63b428e49/cryptography-48.0.1-cp311-abi3-manylinux_2_34_aarch64.whl", hash = "sha256:66fd0771e7b9c6dcd44cf1120690d2338d16d72795cf40cae2786a39eba65429", size = 4701805, upload-time = "2026-06-09T22:31:38.284Z" }, + { url = "https://files.pythonhosted.org/packages/f8/a3/b06844f303873493c963caf581c04df31c7035e0c1b0f02c4814d319ec80/cryptography-48.0.1-cp311-abi3-manylinux_2_34_ppc64le.whl", hash = "sha256:3fd2ca57062b241c856670b073487d2e86c4637937ca5601e48f97bf8e11fc8f", size = 5258461, upload-time = "2026-06-09T22:31:04.187Z" }, + { url = "https://files.pythonhosted.org/packages/9f/13/8b765e2e12b07c74941caadb9d1c8fdc006c4dfbf2b8f2d610519758954d/cryptography-48.0.1-cp311-abi3-manylinux_2_34_x86_64.whl", hash = "sha256:0ee6ea481db1ab889cba043ec1eda17bb9c1ea79db6722f779c3667f9f70322f", size = 4745488, upload-time = "2026-06-09T22:32:30.07Z" }, + { url = "https://files.pythonhosted.org/packages/2e/aa/48972bce55049b32a94f4907eda4d75fa385aad8a39506cc2fc72196ecf0/cryptography-48.0.1-cp311-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:f2ceef93cb096aa3c4cc4b5c94ca6131f9196d28c64d6111533402a9b2054d41", size = 4830256, upload-time = "2026-06-09T22:31:43.868Z" }, + { url = "https://files.pythonhosted.org/packages/47/a2/e5079a032fb85cf6005046ca92bbd78b0c82dad2b5751ab8c311659da06f/cryptography-48.0.1-cp311-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:9bd3f92d76217892b15df84ca256c2c113d386fdda7a7d8691aeeced976507c6", size = 4979117, upload-time = "2026-06-09T22:31:05.845Z" }, + { url = "https://files.pythonhosted.org/packages/b7/a0/8f50cae9c74e718ed769d63ed5c74bd0ea830c9550a74629cebd1b9c7bc7/cryptography-48.0.1-cp311-abi3-win32.whl", hash = "sha256:b9a32b876490d66c8bcc9963ef220199569748434ab01a9d6aaeabf88e7f5158", size = 3304154, upload-time = "2026-06-09T22:32:16.845Z" }, + { url = "https://files.pythonhosted.org/packages/c5/69/0572c77dbace6fef72f33755bd52ea399c71367250d366237f8691826b9e/cryptography-48.0.1-cp311-abi3-win_amd64.whl", hash = "sha256:39489bfca54c7a1f6b297efcd8bc608ab92d16c4ca631b0cad4da46724588b24", size = 3817138, upload-time = "2026-06-09T22:32:00.388Z" }, + { url = "https://files.pythonhosted.org/packages/42/06/3e768b4c3bc78201583fa35a0e18f640dd782ff41afba88f8545481a8874/cryptography-48.0.1-cp314-cp314t-macosx_10_9_universal2.whl", hash = "sha256:f817adc181390bd54f2f700107a7419040fb7c1bdf2fc26f36551a06a68c3345", size = 7989830, upload-time = "2026-06-09T22:31:07.8Z" }, + { url = "https://files.pythonhosted.org/packages/8a/13/6476736484b94041110c8340a3eb63962fea4975baea8cb4a512adb44d4d/cryptography-48.0.1-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:d5d30989c6917b478b5817902e85fddaea2261efa8648383d965381ccb9e1ac4", size = 4689201, upload-time = "2026-06-09T22:31:09.745Z" }, + { url = "https://files.pythonhosted.org/packages/79/62/65a87f34d2a431546e2509b85d55e8c90df86d668f6731da64d538512ac2/cryptography-48.0.1-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:df637c05205ea7c1d7fbcbe54bbfea648a52951155f997af13d895d0ecc96991", size = 4702822, upload-time = "2026-06-09T22:32:24.409Z" }, + { url = "https://files.pythonhosted.org/packages/7f/59/810b5204b0a9b10f4b6bc06bd551a8b609803cd931806bc3b71884b225e5/cryptography-48.0.1-cp314-cp314t-manylinux_2_28_aarch64.whl", hash = "sha256:869c3b8a53bfe27147832df48b32adadf558249d50e76cb3769d40e986b13265", size = 4694875, upload-time = "2026-06-09T22:32:08.737Z" }, + { url = "https://files.pythonhosted.org/packages/24/dc/d8ca05ffea724eec6d232ea6f18e74c269eb6bdfdcc9bfba689790d1325f/cryptography-48.0.1-cp314-cp314t-manylinux_2_28_ppc64le.whl", hash = "sha256:e361afba8918070d376df76f408a4f67fec0ee9cff81a99e48fe9a233ef59e17", size = 5290385, upload-time = "2026-06-09T22:31:15.212Z" }, + { url = "https://files.pythonhosted.org/packages/03/8c/3be6cb4da181f5bb6c19cf560c2359d60644a6b5fc5b57854e528f47b296/cryptography-48.0.1-cp314-cp314t-manylinux_2_28_x86_64.whl", hash = "sha256:d069066deead00ac7f090be101be875a06855908f7ec004c27b8fefb4acfb411", size = 4737082, upload-time = "2026-06-09T22:32:22.66Z" }, + { url = "https://files.pythonhosted.org/packages/aa/f6/d5f60a5a1434dbfd949e227fd0065d194c7e6b6ac526b17f5c06152b8231/cryptography-48.0.1-cp314-cp314t-manylinux_2_31_armv7l.whl", hash = "sha256:09f73a725d582cef64b91281a322cd798d14a33b2b6f2b7ad9531dc336d84c02", size = 4325328, upload-time = "2026-06-09T22:32:10.777Z" }, + { url = "https://files.pythonhosted.org/packages/17/b7/ba75dd947a14b6ad907b01ae8f6b5b348cdd1b48142f0063dee9e20c1d9d/cryptography-48.0.1-cp314-cp314t-manylinux_2_34_aarch64.whl", hash = "sha256:15254441469dd6bf027039453288e2072124f8b6603563f5d759e1c9b69273fa", size = 4694530, upload-time = "2026-06-09T22:31:53.105Z" }, + { url = "https://files.pythonhosted.org/packages/62/29/50d6b9e8aff12d8b67afaeb3569335e32dc83a5723e3bbded24fdac9f809/cryptography-48.0.1-cp314-cp314t-manylinux_2_34_ppc64le.whl", hash = "sha256:8ace4507d1e6533c125f4fac754f8bb8b6a74c08e92179dabd7e16571a3efbf3", size = 5245046, upload-time = "2026-06-09T22:31:25.774Z" }, + { url = "https://files.pythonhosted.org/packages/9f/04/618f4115cfc0add0838c82507aa18a346089428da8653ad38b3ff36f5cb3/cryptography-48.0.1-cp314-cp314t-manylinux_2_34_x86_64.whl", hash = "sha256:b4e391975f038e66432328639620a4aff2d307513b004f1ca06d6225bced815c", size = 4736660, upload-time = "2026-06-09T22:32:12.676Z" }, + { url = "https://files.pythonhosted.org/packages/24/9c/06e062462a0de28a3b3911322eded4c16deb9f441b1b7575d3dc59488ab5/cryptography-48.0.1-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:42fcd8e26fe555d9b3577a135f5091fefa0aa4e99129c23fb56787a1bd4ada72", size = 4822229, upload-time = "2026-06-09T22:31:17.062Z" }, + { url = "https://files.pythonhosted.org/packages/f4/be/0561971eaaee4b8a0e7d5113c536921063ab91aaf23278ac374eaf881e11/cryptography-48.0.1-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:c1400da5e32a43253392277eac7490a60e497d810a63dd5608d71bbd7af507c9", size = 4966364, upload-time = "2026-06-09T22:31:32.842Z" }, + { url = "https://files.pythonhosted.org/packages/a4/27/728c77876f12b000820b69ae490f3c4083775e79e07827e9e60be07ad209/cryptography-48.0.1-cp314-cp314t-win32.whl", hash = "sha256:0df56b056bc17c1b7d6821dfa65216e62bd232d8ab05eb3db44e71d235651471", size = 3278498, upload-time = "2026-06-09T22:31:29.154Z" }, + { url = "https://files.pythonhosted.org/packages/06/e3/79a612c6d7b1e6ee0edd43633d53035bec2cfb78c82b76f7864f39e36f34/cryptography-48.0.1-cp314-cp314t-win_amd64.whl", hash = "sha256:9de21387aa95e2a895823d0745b430bed4f33503ba9ab5e0b5311f33e37d66d2", size = 3798790, upload-time = "2026-06-09T22:31:56.697Z" }, + { url = "https://files.pythonhosted.org/packages/ca/6c/00fa2a95997164c8b2072ce327c23d4ab20809ccc323ea5fab91e53a4bba/cryptography-48.0.1-cp39-abi3-macosx_10_9_universal2.whl", hash = "sha256:4fdc69f8e4316bcf0c8c8ec1f26f285d12e8142d88d96c876a59a03be3f6ae67", size = 7987408, upload-time = "2026-06-09T22:32:20.777Z" }, + { url = "https://files.pythonhosted.org/packages/b0/d9/45f309a7e4e5f3f8f121d6d3be9e94024a7726ec598d6e08ae04edb2f04d/cryptography-48.0.1-cp39-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:48fe40804d4caa2288f24e70ca8c64c42dd826da0ad7e4f1b41b2128d679e6c8", size = 4690196, upload-time = "2026-06-09T22:31:54.74Z" }, + { url = "https://files.pythonhosted.org/packages/5f/9f/a1bc8bcc798811b8527eb374bbccf30a3f3e806829d967118222bf1125eb/cryptography-48.0.1-cp39-abi3-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:86be3b1b0b6bf09482fb50a979c508d2950ed95f5621ec77f4e385962006b83a", size = 4696782, upload-time = "2026-06-09T22:31:45.615Z" }, + { url = "https://files.pythonhosted.org/packages/66/c2/81a4fb4e4373c500bb526bc337ac5719dd31dd15b970b84a238168c6aa08/cryptography-48.0.1-cp39-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:4ab0a343c807bbcd90c971cd1ecf072937cd01847a9e002bef88fb47ac6be577", size = 4696618, upload-time = "2026-06-09T22:31:11.564Z" }, + { url = "https://files.pythonhosted.org/packages/e5/0b/aa68b221dde92d09cb29a024ede17550ee21e77a404e59fc093c82bb51e1/cryptography-48.0.1-cp39-abi3-manylinux_2_28_ppc64le.whl", hash = "sha256:9621de99d2da096006b629979efd8ae7eb2d8b822488d0c89ee4000c306c59b1", size = 5289970, upload-time = "2026-06-09T22:31:20.368Z" }, + { url = "https://files.pythonhosted.org/packages/78/13/fba657f958d2af66ea959a4ba01212632089249d34af1ae48054136344d7/cryptography-48.0.1-cp39-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:88c852a0ae366e262e5a1744b685e6a433dc8788dd2a277e418bf4904203609d", size = 4731873, upload-time = "2026-06-09T22:31:22.253Z" }, + { url = "https://files.pythonhosted.org/packages/4c/4c/9a964756d24a26b3e34dfcb16f961b89838786e6700b635b0d1e3adff4b6/cryptography-48.0.1-cp39-abi3-manylinux_2_31_armv7l.whl", hash = "sha256:43c5835e2cb98c8733d86f57d6fc879b613f5c3478607281c3e36daffc6dd8a6", size = 4330804, upload-time = "2026-06-09T22:31:36.56Z" }, + { url = "https://files.pythonhosted.org/packages/4b/0f/a10f3a6eb12950a10e3a874070283aa2dd5875b2bfd15fad8a3e17b3f13e/cryptography-48.0.1-cp39-abi3-manylinux_2_34_aarch64.whl", hash = "sha256:fe0180af5bf9236518a087e35bf2d9a347d5f5f51e63c579d683ddff424e3d46", size = 4696217, upload-time = "2026-06-09T22:31:13.351Z" }, + { url = "https://files.pythonhosted.org/packages/f3/6f/5cd12f951165ea73ef85266775d97e4c763b2474ccfd816dd69d3a18d6f8/cryptography-48.0.1-cp39-abi3-manylinux_2_34_ppc64le.whl", hash = "sha256:b7a2d1a937a738a881737cec135a38bb61470589b17515b9f73f571d0ae10401", size = 5245252, upload-time = "2026-06-09T22:32:02.193Z" }, + { url = "https://files.pythonhosted.org/packages/68/ab/8aaa12e4516ec4464033ab79b6f3b592bd5a92102467c4ace8a0d970203f/cryptography-48.0.1-cp39-abi3-manylinux_2_34_x86_64.whl", hash = "sha256:b74ca3b8e5ecdd833bf6a002ca41b4793bb27fb8f1c06ffaf2643c9e9140e31b", size = 4731388, upload-time = "2026-06-09T22:32:04.019Z" }, + { url = "https://files.pythonhosted.org/packages/1b/24/50027ea4dca85ec1f40688f3c24fb32ccacd520583c9592c3cc95628e6fb/cryptography-48.0.1-cp39-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:2c37f2461406063b417837f5f3daab668652acd82423efcd7f0a9f04be972de1", size = 4824186, upload-time = "2026-06-09T22:32:18.707Z" }, + { url = "https://files.pythonhosted.org/packages/52/41/04cb5eb17085ade6f50cc611fb657df6a0f5885350de8764ece89c050197/cryptography-48.0.1-cp39-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:86fe77abb1bd87afb251d4d02ada7ecf53a32cee9b67d976abb2e45a13297475", size = 4964539, upload-time = "2026-06-09T22:31:18.793Z" }, + { url = "https://files.pythonhosted.org/packages/36/bf/ed70785c496e89d7e73b7cda2d21f2447fd6d4e821714b8d04ff217fed92/cryptography-48.0.1-cp39-abi3-win32.whl", hash = "sha256:6b2c0c3e6ccf3ade7750f836ef3ee36eea250cc467d45c256895573ac08cc6f1", size = 3282307, upload-time = "2026-06-09T22:30:53.162Z" }, + { url = "https://files.pythonhosted.org/packages/b3/ff/371ea7d252656ee1eb6d83eeeef3d1d0c6baf1d6497687d081ea03814670/cryptography-48.0.1-cp39-abi3-win_amd64.whl", hash = "sha256:9a49ca6c81417f6a5edb50375a60cccdd70fa0a91a5211829dbea74eba94d2ac", size = 3793408, upload-time = "2026-06-09T22:32:15.191Z" }, + { url = "https://files.pythonhosted.org/packages/a9/d3/eb4e394e587341fdad09a09101fa76478ead3a78b0ad63e55c22f0d75c02/cryptography-48.0.1-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:08a597acce1ff37f347400087776599e2348a3a8bc53b44120e463cd274efe4a", size = 3951747, upload-time = "2026-06-09T22:31:23.871Z" }, + { url = "https://files.pythonhosted.org/packages/e0/4a/3f43451b4f858bfceaaaffc649e6e787e8d4fb332a1d443af39ab02cc8f1/cryptography-48.0.1-pp311-pypy311_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:735824ec41b7f74a7c45fb1591349333e4c696cb6c044e5f46356e560143e4cd", size = 4641226, upload-time = "2026-06-09T22:31:02.532Z" }, + { url = "https://files.pythonhosted.org/packages/73/4e/855584c2c23b09e4ce2d3b9c30e983e679cd60b068c513c6bbdb91e11782/cryptography-48.0.1-pp311-pypy311_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:92a46e1d638daa264ba2971c0b0489c9409787943efae4d60ffda3d091ef832c", size = 4668958, upload-time = "2026-06-09T22:32:06.213Z" }, + { url = "https://files.pythonhosted.org/packages/42/3b/d35750e41d803d1e516fd6d6011f065424924da7af1748cef4cc9cb3ede1/cryptography-48.0.1-pp311-pypy311_pp73-manylinux_2_34_aarch64.whl", hash = "sha256:7e234ac052af99f2700826a5c29ea99d9c1b1f80341cde62d11c8154dc8e0bd9", size = 4640793, upload-time = "2026-06-09T22:32:26.331Z" }, + { url = "https://files.pythonhosted.org/packages/ca/aa/cdb7181fe865285e87e96825aaab239400f1de0c3bfba9bd9769b79f1a92/cryptography-48.0.1-pp311-pypy311_pp73-manylinux_2_34_x86_64.whl", hash = "sha256:33842cf0888951cef5bc7ac724ab844a42044c1727b967b7f8997289a0464f92", size = 4668505, upload-time = "2026-06-09T22:31:27.534Z" }, + { url = "https://files.pythonhosted.org/packages/5d/8c/ce3823c06c2804f194f9e64f0d67fa3f4094a39f2bb1a990cd03603af8fc/cryptography-48.0.1-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:6184ca7b174f28d7c703f1290d4b297217c45355f77a98f67e9b7f14549ac54a", size = 3742204, upload-time = "2026-06-09T22:31:34.773Z" }, +] + +[[package]] +name = "distro" +version = "1.9.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/fc/f8/98eea607f65de6527f8a2e8885fc8015d3e6f5775df186e443e0964a11c3/distro-1.9.0.tar.gz", hash = "sha256:2fa77c6fd8940f116ee1d6b94a2f90b13b5ea8d019b98bc8bafdcabcdd9bdbed", size = 60722, upload-time = "2023-12-24T09:54:32.31Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/12/b3/231ffd4ab1fc9d679809f356cebee130ac7daa00d6d6f3206dd4fd137e9e/distro-1.9.0-py3-none-any.whl", hash = "sha256:7bffd925d65168f85027d8da9af6bddab658135b840670a223589bc0c8ef02b2", size = 20277, upload-time = "2023-12-24T09:54:30.421Z" }, +] + +[[package]] +name = "docstring-parser" +version = "0.18.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/e0/4d/f332313098c1de1b2d2ff91cf2674415cc7cddab2ca1b01ae29774bd5fdf/docstring_parser-0.18.0.tar.gz", hash = "sha256:292510982205c12b1248696f44959db3cdd1740237a968ea1e2e7a900eeb2015", size = 29341, upload-time = "2026-04-14T04:09:19.867Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/a7/5f/ed01f9a3cdffbd5a008556fc7b2a08ddb1cc6ace7effa7340604b1d16699/docstring_parser-0.18.0-py3-none-any.whl", hash = "sha256:b3fcbed555c47d8479be0796ef7e19c2670d428d72e96da63f3a40122860374b", size = 22484, upload-time = "2026-04-14T04:09:18.638Z" }, +] + +[[package]] +name = "fastapi" +version = "0.136.3" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "annotated-doc" }, + { name = "pydantic" }, + { name = "starlette" }, + { name = "typing-extensions" }, + { name = "typing-inspection" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/81/2d/ff8d91d7b564d464629a0fd50a4489c97fcb836ac230bf3a7269232a9b1f/fastapi-0.136.3.tar.gz", hash = "sha256:e487fae93ad408e6f47641ee4dfe389864fd7bec92e547ea8498fc13f43e83ab", size = 396410, upload-time = "2026-05-23T18:53:15.192Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/e0/82/45359b62a067409bd929ae8a56b8ed13e5a8c8a61194b3c236920999ab83/fastapi-0.136.3-py3-none-any.whl", hash = "sha256:3d2a69bdf04b7e9f3afa292c3bc7a98816bbfafa10bc9b45f3f3700d2f761620", size = 117481, upload-time = "2026-05-23T18:53:16.924Z" }, +] + +[[package]] +name = "google-adk" +version = "2.2.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "aiosqlite" }, + { name = "authlib" }, + { name = "click" }, + { name = "fastapi" }, + { name = "google-auth", extra = ["pyopenssl"] }, + { name = "google-genai" }, + { name = "graphviz" }, + { name = "httpx" }, + { name = "jsonschema" }, + { name = "opentelemetry-api" }, + { name = "opentelemetry-sdk" }, + { name = "packaging" }, + { name = "pydantic" }, + { name = "python-dotenv" }, + { name = "python-multipart" }, + { name = "pyyaml" }, + { name = "requests" }, + { name = "starlette" }, + { name = "tenacity" }, + { name = "typing-extensions" }, + { name = "tzlocal" }, + { name = "uvicorn" }, + { name = "watchdog" }, + { name = "websockets" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/4a/65/3ff3f50b10dac3323ddecd694515e9f9ed345886e0eaf666d0e42c90748b/google_adk-2.2.0.tar.gz", hash = "sha256:04cb6318aba8829fe7c941ee1b456ccb4745253898c13595708c9eb07b4582ff", size = 3391545, upload-time = "2026-06-04T22:15:12.9Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/64/f5/44a3b20b17bac130497f2d1dde8b93c90cfc026983cd94f24488d540ea70/google_adk-2.2.0-py3-none-any.whl", hash = "sha256:ebdf3d931dc2b9c5b30d995358fc2ae99d59594c48a4aaf7496869ccd2c5f245", size = 3912613, upload-time = "2026-06-04T22:15:15.411Z" }, +] + +[[package]] +name = "google-api-core" +version = "2.31.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "google-auth" }, + { name = "googleapis-common-protos" }, + { name = "proto-plus" }, + { name = "protobuf" }, + { name = "requests" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/c6/22/155cadf1d49272a9cf48f3168c0f3874fa13397297e611a5ea00cd093880/google_api_core-2.31.0.tar.gz", hash = "sha256:2be84ee0f584c48e6bde1b36766e23348b361fb7e55e56135fc76ce1c397f9c2", size = 176492, upload-time = "2026-06-03T14:52:17.257Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/86/40/9bdbb60b03a332bd45acb8703da08bbc27d991d35286b62e42acc86d243a/google_api_core-2.31.0-py3-none-any.whl", hash = "sha256:ef79fb3784c71cbac89cbd03301ba0c8fb8ad2aa95d7f9204dd9628f7adf59ab", size = 173102, upload-time = "2026-06-03T14:51:26.729Z" }, +] + +[package.optional-dependencies] +grpc = [ + { name = "grpcio" }, + { name = "grpcio-status" }, +] + +[[package]] +name = "google-auth" +version = "2.53.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "cryptography" }, + { name = "pyasn1-modules" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/c6/ad/ff781329bbbdc0974a098d996e89c9e1f7024262f9e3eec442fbb9ad1ac6/google_auth-2.53.0.tar.gz", hash = "sha256:e7e6aa16f6bee7b2b264830fd04f08087a1d5a836df516251a5d15327b246c9c", size = 335844, upload-time = "2026-05-15T20:53:07.928Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/4a/c9/db44165ba7c581268c6d46017ef63339110378305062830104fc7fa144cb/google_auth-2.53.0-py3-none-any.whl", hash = "sha256:6e7449917c599b35126a99ec268ec6880301f2fea41dce198fe8fd83ff642b68", size = 246071, upload-time = "2026-05-15T20:53:05.609Z" }, +] + +[package.optional-dependencies] +pyopenssl = [ + { name = "pyopenssl" }, +] +requests = [ + { name = "requests" }, +] + +[[package]] +name = "google-cloud-aiplatform" +version = "1.157.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "certifi" }, + { name = "docstring-parser" }, + { name = "google-api-core", extra = ["grpc"] }, + { name = "google-auth" }, + { name = "google-cloud-bigquery" }, + { name = "google-cloud-resource-manager" }, + { name = "google-cloud-storage" }, + { name = "google-genai" }, + { name = "packaging" }, + { name = "proto-plus" }, + { name = "protobuf" }, + { name = "pydantic" }, + { name = "typing-extensions" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/e0/d9/e2a5f5a8535bbc8f68729796f3fc2d68d59a72818fb44f6544edbc2592e4/google_cloud_aiplatform-1.157.0.tar.gz", hash = "sha256:ce8413ed3584c4896f7656b663214c24e91c2c89426f1c91fbd1d220ffda23af", size = 11064992, upload-time = "2026-06-10T00:19:33.643Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/e3/82/3ec2ba56dc1fa71ef783348a0c519721879dbc8f1e568534e6d4b4856ccd/google_cloud_aiplatform-1.157.0-py2.py3-none-any.whl", hash = "sha256:0ca499ac5648988916fc089f9e94bd99667eefba13f6936475247f4a0bf86634", size = 9200777, upload-time = "2026-06-10T00:19:30.181Z" }, +] + +[[package]] +name = "google-cloud-bigquery" +version = "3.41.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "google-api-core", extra = ["grpc"] }, + { name = "google-auth" }, + { name = "google-cloud-core" }, + { name = "google-resumable-media" }, + { name = "packaging" }, + { name = "python-dateutil" }, + { name = "requests" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/ce/13/6515c7aab55a4a0cf708ffd309fb9af5bab54c13e32dc22c5acd6497193c/google_cloud_bigquery-3.41.0.tar.gz", hash = "sha256:2217e488b47ed576360c9b2cc07d59d883a54b83167c0ef37f915c26b01a06fe", size = 513434, upload-time = "2026-03-30T22:50:55.347Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/40/33/1d3902efadef9194566d499d61507e1f038454e0b55499d2d7f8ab2a4fee/google_cloud_bigquery-3.41.0-py3-none-any.whl", hash = "sha256:2a5b5a737b401cbd824a6e5eac7554100b878668d908e6548836b5d8aaa4dcaa", size = 262343, upload-time = "2026-03-30T22:48:45.444Z" }, +] + +[[package]] +name = "google-cloud-core" +version = "2.6.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "google-api-core" }, + { name = "google-auth" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/a8/dd/1eef226e470369b26824a505c34482c0b493bc35fe8e0c6b003b5feca21a/google_cloud_core-2.6.0.tar.gz", hash = "sha256:e76149739f90fac1fc6757c09f47eaccb3145b54adbd7759b0f7c4b235f46c83", size = 36001, upload-time = "2026-05-07T08:04:04.124Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/84/4a/98da8930ab109c73d9a5d13782a9ebb81ea8c111f6d534a567b71d23e52b/google_cloud_core-2.6.0-py3-none-any.whl", hash = "sha256:6d63ac8e5eca6d9e4319d0a1e2265fadcd7f1049904378caecfa01cf52dd869e", size = 29390, upload-time = "2026-05-07T08:02:34.672Z" }, +] + +[[package]] +name = "google-cloud-resource-manager" +version = "1.17.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "google-api-core", extra = ["grpc"] }, + { name = "google-auth" }, + { name = "grpc-google-iam-v1" }, + { name = "grpcio" }, + { name = "proto-plus" }, + { name = "protobuf" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/b2/1a/13060cabf553d52d151d2afc26b39561e82853380d499dd525a0d422d9f0/google_cloud_resource_manager-1.17.0.tar.gz", hash = "sha256:0f486b62e2c58ff992a3a50fa0f4a96eef7750aa6c971bb373398ccb91828660", size = 464971, upload-time = "2026-03-26T22:17:29.204Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/3d/f7/661d7a9023e877a226b5683429c3662f75a29ef45cb1464cf39adb689218/google_cloud_resource_manager-1.17.0-py3-none-any.whl", hash = "sha256:e479baf4b014a57f298e01b8279e3290b032e3476d69c8e5e1427af8f82739a5", size = 404403, upload-time = "2026-03-26T22:15:26.57Z" }, +] + +[[package]] +name = "google-cloud-storage" +version = "3.11.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "google-api-core" }, + { name = "google-auth" }, + { name = "google-cloud-core" }, + { name = "google-crc32c" }, + { name = "google-resumable-media" }, + { name = "requests" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/22/09/8953e2993e604c8882fd441b5b2de624a2dfe7e6144c6166d7b477509596/google_cloud_storage-3.11.0.tar.gz", hash = "sha256:498bf37c999028f69a245f586b5e50d89f59df1fafc0e3a93783ac56be2a456b", size = 17335639, upload-time = "2026-06-03T16:14:04.649Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/09/7e/ee0dd1a67ac75d29d0c438969d85d4fadbc4bcab47b0a8ccfa7eb22f643c/google_cloud_storage-3.11.0-py3-none-any.whl", hash = "sha256:cfcc33aa6b899ec9dd1771286f8e79fbed5c35c1c174718071b079aa827f37c2", size = 339654, upload-time = "2026-06-03T16:12:46.052Z" }, +] + +[[package]] +name = "google-crc32c" +version = "1.8.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/03/41/4b9c02f99e4c5fb477122cd5437403b552873f014616ac1d19ac8221a58d/google_crc32c-1.8.0.tar.gz", hash = "sha256:a428e25fb7691024de47fecfbff7ff957214da51eddded0da0ae0e0f03a2cf79", size = 14192, upload-time = "2025-12-16T00:35:25.142Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/5d/ef/21ccfaab3d5078d41efe8612e0ed0bfc9ce22475de074162a91a25f7980d/google_crc32c-1.8.0-cp311-cp311-macosx_12_0_arm64.whl", hash = "sha256:014a7e68d623e9a4222d663931febc3033c5c7c9730785727de2a81f87d5bab8", size = 31298, upload-time = "2025-12-16T00:20:32.241Z" }, + { url = "https://files.pythonhosted.org/packages/c5/b8/f8413d3f4b676136e965e764ceedec904fe38ae8de0cdc52a12d8eb1096e/google_crc32c-1.8.0-cp311-cp311-macosx_12_0_x86_64.whl", hash = "sha256:86cfc00fe45a0ac7359e5214a1704e51a99e757d0272554874f419f79838c5f7", size = 30872, upload-time = "2025-12-16T00:33:58.785Z" }, + { url = "https://files.pythonhosted.org/packages/f6/fd/33aa4ec62b290477181c55bb1c9302c9698c58c0ce9a6ab4874abc8b0d60/google_crc32c-1.8.0-cp311-cp311-manylinux1_x86_64.manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:19b40d637a54cb71e0829179f6cb41835f0fbd9e8eb60552152a8b52c36cbe15", size = 33243, upload-time = "2025-12-16T00:40:21.46Z" }, + { url = "https://files.pythonhosted.org/packages/71/03/4820b3bd99c9653d1a5210cb32f9ba4da9681619b4d35b6a052432df4773/google_crc32c-1.8.0-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:17446feb05abddc187e5441a45971b8394ea4c1b6efd88ab0af393fd9e0a156a", size = 33608, upload-time = "2025-12-16T00:40:22.204Z" }, + { url = "https://files.pythonhosted.org/packages/7c/43/acf61476a11437bf9733fb2f70599b1ced11ec7ed9ea760fdd9a77d0c619/google_crc32c-1.8.0-cp311-cp311-win_amd64.whl", hash = "sha256:71734788a88f551fbd6a97be9668a0020698e07b2bf5b3aa26a36c10cdfb27b2", size = 34439, upload-time = "2025-12-16T00:35:20.458Z" }, + { url = "https://files.pythonhosted.org/packages/e9/5f/7307325b1198b59324c0fa9807cafb551afb65e831699f2ce211ad5c8240/google_crc32c-1.8.0-cp312-cp312-macosx_12_0_arm64.whl", hash = "sha256:4b8286b659c1335172e39563ab0a768b8015e88e08329fa5321f774275fc3113", size = 31300, upload-time = "2025-12-16T00:21:56.723Z" }, + { url = "https://files.pythonhosted.org/packages/21/8e/58c0d5d86e2220e6a37befe7e6a94dd2f6006044b1a33edf1ff6d9f7e319/google_crc32c-1.8.0-cp312-cp312-macosx_12_0_x86_64.whl", hash = "sha256:2a3dc3318507de089c5384cc74d54318401410f82aa65b2d9cdde9d297aca7cb", size = 30867, upload-time = "2025-12-16T00:38:31.302Z" }, + { url = "https://files.pythonhosted.org/packages/ce/a9/a780cc66f86335a6019f557a8aaca8fbb970728f0efd2430d15ff1beae0e/google_crc32c-1.8.0-cp312-cp312-manylinux1_x86_64.manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:14f87e04d613dfa218d6135e81b78272c3b904e2a7053b841481b38a7d901411", size = 33364, upload-time = "2025-12-16T00:40:22.96Z" }, + { url = "https://files.pythonhosted.org/packages/21/3f/3457ea803db0198c9aaca2dd373750972ce28a26f00544b6b85088811939/google_crc32c-1.8.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:cb5c869c2923d56cb0c8e6bcdd73c009c36ae39b652dbe46a05eb4ef0ad01454", size = 33740, upload-time = "2025-12-16T00:40:23.96Z" }, + { url = "https://files.pythonhosted.org/packages/df/c0/87c2073e0c72515bb8733d4eef7b21548e8d189f094b5dad20b0ecaf64f6/google_crc32c-1.8.0-cp312-cp312-win_amd64.whl", hash = "sha256:3cc0c8912038065eafa603b238abf252e204accab2a704c63b9e14837a854962", size = 34437, upload-time = "2025-12-16T00:35:21.395Z" }, + { url = "https://files.pythonhosted.org/packages/d1/db/000f15b41724589b0e7bc24bc7a8967898d8d3bc8caf64c513d91ef1f6c0/google_crc32c-1.8.0-cp313-cp313-macosx_12_0_arm64.whl", hash = "sha256:3ebb04528e83b2634857f43f9bb8ef5b2bbe7f10f140daeb01b58f972d04736b", size = 31297, upload-time = "2025-12-16T00:23:20.709Z" }, + { url = "https://files.pythonhosted.org/packages/d7/0d/8ebed0c39c53a7e838e2a486da8abb0e52de135f1b376ae2f0b160eb4c1a/google_crc32c-1.8.0-cp313-cp313-macosx_12_0_x86_64.whl", hash = "sha256:450dc98429d3e33ed2926fc99ee81001928d63460f8538f21a5d6060912a8e27", size = 30867, upload-time = "2025-12-16T00:43:14.628Z" }, + { url = "https://files.pythonhosted.org/packages/ce/42/b468aec74a0354b34c8cbf748db20d6e350a68a2b0912e128cabee49806c/google_crc32c-1.8.0-cp313-cp313-manylinux1_x86_64.manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:3b9776774b24ba76831609ffbabce8cdf6fa2bd5e9df37b594221c7e333a81fa", size = 33344, upload-time = "2025-12-16T00:40:24.742Z" }, + { url = "https://files.pythonhosted.org/packages/1c/e8/b33784d6fc77fb5062a8a7854e43e1e618b87d5ddf610a88025e4de6226e/google_crc32c-1.8.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:89c17d53d75562edfff86679244830599ee0a48efc216200691de8b02ab6b2b8", size = 33694, upload-time = "2025-12-16T00:40:25.505Z" }, + { url = "https://files.pythonhosted.org/packages/92/b1/d3cbd4d988afb3d8e4db94ca953df429ed6db7282ed0e700d25e6c7bfc8d/google_crc32c-1.8.0-cp313-cp313-win_amd64.whl", hash = "sha256:57a50a9035b75643996fbf224d6661e386c7162d1dfdab9bc4ca790947d1007f", size = 34435, upload-time = "2025-12-16T00:35:22.107Z" }, + { url = "https://files.pythonhosted.org/packages/21/88/8ecf3c2b864a490b9e7010c84fd203ec8cf3b280651106a3a74dd1b0ca72/google_crc32c-1.8.0-cp314-cp314-macosx_12_0_arm64.whl", hash = "sha256:e6584b12cb06796d285d09e33f63309a09368b9d806a551d8036a4207ea43697", size = 31301, upload-time = "2025-12-16T00:24:48.527Z" }, + { url = "https://files.pythonhosted.org/packages/36/c6/f7ff6c11f5ca215d9f43d3629163727a272eabc356e5c9b2853df2bfe965/google_crc32c-1.8.0-cp314-cp314-macosx_12_0_x86_64.whl", hash = "sha256:f4b51844ef67d6cf2e9425983274da75f18b1597bb2c998e1c0a0e8d46f8f651", size = 30868, upload-time = "2025-12-16T00:48:12.163Z" }, + { url = "https://files.pythonhosted.org/packages/56/15/c25671c7aad70f8179d858c55a6ae8404902abe0cdcf32a29d581792b491/google_crc32c-1.8.0-cp314-cp314-manylinux1_x86_64.manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:b0d1a7afc6e8e4635564ba8aa5c0548e3173e41b6384d7711a9123165f582de2", size = 33381, upload-time = "2025-12-16T00:40:26.268Z" }, + { url = "https://files.pythonhosted.org/packages/42/fa/f50f51260d7b0ef5d4898af122d8a7ec5a84e2984f676f746445f783705f/google_crc32c-1.8.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:8b3f68782f3cbd1bce027e48768293072813469af6a61a86f6bb4977a4380f21", size = 33734, upload-time = "2025-12-16T00:40:27.028Z" }, + { url = "https://files.pythonhosted.org/packages/08/a5/7b059810934a09fb3ccb657e0843813c1fee1183d3bc2c8041800374aa2c/google_crc32c-1.8.0-cp314-cp314-win_amd64.whl", hash = "sha256:d511b3153e7011a27ab6ee6bb3a5404a55b994dc1a7322c0b87b29606d9790e2", size = 34878, upload-time = "2025-12-16T00:35:23.142Z" }, + { url = "https://files.pythonhosted.org/packages/52/c5/c171e4d8c44fec1422d801a6d2e5d7ddabd733eeda505c79730ee9607f07/google_crc32c-1.8.0-pp311-pypy311_pp73-manylinux1_x86_64.manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:87fa445064e7db928226b2e6f0d5304ab4cd0339e664a4e9a25029f384d9bb93", size = 28615, upload-time = "2025-12-16T00:40:29.298Z" }, + { url = "https://files.pythonhosted.org/packages/9c/97/7d75fe37a7a6ed171a2cf17117177e7aab7e6e0d115858741b41e9dd4254/google_crc32c-1.8.0-pp311-pypy311_pp73-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:f639065ea2042d5c034bf258a9f085eaa7af0cd250667c0635a3118e8f92c69c", size = 28800, upload-time = "2025-12-16T00:40:30.322Z" }, +] + +[[package]] +name = "google-genai" +version = "2.8.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "anyio" }, + { name = "distro" }, + { name = "google-auth", extra = ["requests"] }, + { name = "httpx" }, + { name = "pydantic" }, + { name = "requests" }, + { name = "sniffio" }, + { name = "tenacity" }, + { name = "typing-extensions" }, + { name = "websockets" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/5b/52/0244e310812f3063d09d60b30ae29ab7df9343bd005744cd5eeaa6ba39b4/google_genai-2.8.0.tar.gz", hash = "sha256:37a9b3cb127d763e7f4ca47452ae3562c87728773bd1b149f7b559c239da2bc1", size = 564955, upload-time = "2026-06-03T22:55:38.397Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/e2/de/747ad1aa49e902da9a4699081c282a1ed8ceed3b4d295fd99a6d286e09e4/google_genai-2.8.0-py3-none-any.whl", hash = "sha256:4da0a223a100f4b37f609a68b835e3326ab0fa313314dc0fd9d34e76ee293844", size = 832497, upload-time = "2026-06-03T22:55:36.598Z" }, +] + +[[package]] +name = "google-resumable-media" +version = "2.10.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "google-crc32c" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/48/f8/1ca5781d6be9cb9f73f7d40f4958c4bd1226a60598e3e39e1d6aaf838c4b/google_resumable_media-2.10.0.tar.gz", hash = "sha256:e324bc9d0fdae4c52a08ae90456edc4e71ece858399e1217ac0eb3a51d6bc6ee", size = 2164570, upload-time = "2026-06-03T16:14:26.103Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/b0/d8/00c6854ac1512bb9eaf13bd3f8f28222f7674947fc510a4ff7616f2efc80/google_resumable_media-2.10.0-py3-none-any.whl", hash = "sha256:88152884bee37b2bf36a0ab81ad8c7fd12212c9803dd981d77c1b35b02d34e7c", size = 81533, upload-time = "2026-06-03T16:13:12.51Z" }, +] + +[[package]] +name = "googleapis-common-protos" +version = "1.75.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "protobuf" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/b5/c8/f439cffde755cffa462bfbb156278fa6f9d09119719af9814b858fd4f81f/googleapis_common_protos-1.75.0.tar.gz", hash = "sha256:53a062ff3c32552fbd62c11fe23768b78e4ddf0494d5e5fd97d3f4689c75fbbd", size = 151035, upload-time = "2026-05-07T08:04:49.423Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/e7/c8/e2645aa8ed02fd4c7a2f59d68783b65b1f3cbdfe39a6308e156509d1fee8/googleapis_common_protos-1.75.0-py3-none-any.whl", hash = "sha256:961ed60399c457ceb0ee8f285a84c870aabc9c6a832b9d37bb281b5bebde43ed", size = 300631, upload-time = "2026-05-07T08:03:30.345Z" }, +] + +[package.optional-dependencies] +grpc = [ + { name = "grpcio" }, +] + +[[package]] +name = "graphviz" +version = "0.21" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/f8/b3/3ac91e9be6b761a4b30d66ff165e54439dcd48b83f4e20d644867215f6ca/graphviz-0.21.tar.gz", hash = "sha256:20743e7183be82aaaa8ad6c93f8893c923bd6658a04c32ee115edb3c8a835f78", size = 200434, upload-time = "2025-06-15T09:35:05.824Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/91/4c/e0ce1ef95d4000ebc1c11801f9b944fa5910ecc15b5e351865763d8657f8/graphviz-0.21-py3-none-any.whl", hash = "sha256:54f33de9f4f911d7e84e4191749cac8cc5653f815b06738c54db9a15ab8b1e42", size = 47300, upload-time = "2025-06-15T09:35:04.433Z" }, +] + +[[package]] +name = "grpc-google-iam-v1" +version = "0.14.4" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "googleapis-common-protos", extra = ["grpc"] }, + { name = "grpcio" }, + { name = "protobuf" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/44/4f/d098419ad0bfc06c9ce440575f05aa22d8973b6c276e86ac7890093d3c37/grpc_google_iam_v1-0.14.4.tar.gz", hash = "sha256:392b3796947ed6334e61171d9ab06bf7eb357f554e5fc7556ad7aab6d0e17038", size = 23706, upload-time = "2026-04-01T01:57:49.813Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/89/22/c2dd50c09bf679bd38173656cd4402d2511e563b33bc88f90009cf50613c/grpc_google_iam_v1-0.14.4-py3-none-any.whl", hash = "sha256:412facc320fcbd94034b4df3d557662051d4d8adfa86e0ddb4dca70a3f739964", size = 32675, upload-time = "2026-04-01T01:57:47.69Z" }, +] + +[[package]] +name = "grpcio" +version = "1.81.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "typing-extensions" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/15/f3/23f47b24f8d8c2028eba501db3acfbb2f592cbb5995eaa6e363a627b74d7/grpcio-1.81.0.tar.gz", hash = "sha256:a5acd7efd3b1fe9b4eb0bcaaa1507eed68a0ad0678b654c3f7b464df9ba9dca5", size = 13032272, upload-time = "2026-06-01T05:56:22.827Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/45/a8/9916ab10a0201f4c7afb6918125aa2f38a7626ee18ffbc066dd9cb04a74d/grpcio-1.81.0-cp311-cp311-linux_armv7l.whl", hash = "sha256:794e6aa648e8df47d8f908dc8c3b42347d04ec58438f1dcd4e445f09b4f6b0ce", size = 6093557, upload-time = "2026-06-01T05:54:32.64Z" }, + { url = "https://files.pythonhosted.org/packages/a7/43/99e969a048904a65df3129ee53c5f523b7c4e43127786460cac4bee82470/grpcio-1.81.0-cp311-cp311-macosx_11_0_universal2.whl", hash = "sha256:cd78145b7f7784661c524624f3526c9c6f891b30a4b54cb93a40806d0d0d61e9", size = 12075345, upload-time = "2026-06-01T05:54:35.77Z" }, + { url = "https://files.pythonhosted.org/packages/83/70/4c3a204e190333768d4f63f4ff56bd0bf405f05b9188f3a59a8bcf161f8b/grpcio-1.81.0-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:638ccc1b86f7540170a169cb900799b9296a1381e47879ce60b0de9d3db73d33", size = 6640664, upload-time = "2026-06-01T05:54:38.854Z" }, + { url = "https://files.pythonhosted.org/packages/2e/a9/0fa17ac8b4e29cf59b26915be6cab8c0d4583ce24a6208a287b6e5f6d072/grpcio-1.81.0-cp311-cp311-manylinux2014_i686.manylinux_2_17_i686.whl", hash = "sha256:21ec30b9ea320c8207ea7cd05873ad64aa69fdd0e81b6758b3347983ba20b50a", size = 7332542, upload-time = "2026-06-01T05:54:41.39Z" }, + { url = "https://files.pythonhosted.org/packages/f4/18/7c8e3d0dda2fb7a17076fcd6c9085209eabad3354696c64230f87b3a14eb/grpcio-1.81.0-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:dbdb99986548a7e87f8343805ef315fd4eb50ffaabf4fb1206e42f2542bb805d", size = 6842564, upload-time = "2026-06-01T05:54:43.57Z" }, + { url = "https://files.pythonhosted.org/packages/f6/19/2f1726c2e03ad3f3fe241e6b41534532ad580d595de14a4054ad84999c80/grpcio-1.81.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:c36f5d5e97944cbda2d4096b4ae262e6e68506246b61582acf1b8591607f3ccc", size = 7446236, upload-time = "2026-06-01T05:54:46.042Z" }, + { url = "https://files.pythonhosted.org/packages/a7/dc/0321f892212e2c0bfe248cea24c00d7d7111639688ec5ffd8e36b5c02fe6/grpcio-1.81.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:9f355384e5543ab77a755a7085225ecc19f32b76032e851cbd8145715d79dec8", size = 8445633, upload-time = "2026-06-01T05:54:48.809Z" }, + { url = "https://files.pythonhosted.org/packages/e5/20/0e7ea7494955cf1beea3077b2fd2c04c84d4480c2ae85a1e1cfa150c62d7/grpcio-1.81.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:77eb4e9fe61486bd1198cc7236ebb0f70e66234e63c0348f40bc2553ed16a88b", size = 7873958, upload-time = "2026-06-01T05:54:52.135Z" }, + { url = "https://files.pythonhosted.org/packages/d3/9e/6438e226046c2a0778060e2b1d791a4827277bbd9d223013c2c63ee7435e/grpcio-1.81.0-cp311-cp311-win32.whl", hash = "sha256:7915a2e63acdc05264a206e1bddfd8e1fb8a29e406c18d72d30f8c124e021374", size = 4202110, upload-time = "2026-06-01T05:54:54.134Z" }, + { url = "https://files.pythonhosted.org/packages/42/6b/d0895e93d65b186f5f1737fcc186d7faa487e2d9d934eda111a37a309869/grpcio-1.81.0-cp311-cp311-win_amd64.whl", hash = "sha256:5e925a70fe99fe5794f7beca0ea034c75f068afcc356d79047e73f99cdcca34c", size = 4940942, upload-time = "2026-06-01T05:54:56.749Z" }, + { url = "https://files.pythonhosted.org/packages/82/d5/896a3aaf07068d707d88b282a04914b872db4d32d3c7e6d88e43a3b911fa/grpcio-1.81.0-cp312-cp312-linux_armv7l.whl", hash = "sha256:57b3b0e73a518fa286959b40c3eddd02703504ca186e8b7b2945954519bd8b2c", size = 6053538, upload-time = "2026-06-01T05:54:58.965Z" }, + { url = "https://files.pythonhosted.org/packages/68/6a/7e3eafa4727cd405ff917605ed2949e2af162f233f5cbdd773723a5fea7d/grpcio-1.81.0-cp312-cp312-macosx_11_0_universal2.whl", hash = "sha256:8bb1789c94322a13336a2b6c58d9c14d68f8628b6e24205a799c69f5bf8516ce", size = 12053447, upload-time = "2026-06-01T05:55:01.862Z" }, + { url = "https://files.pythonhosted.org/packages/16/79/a4302aa82428de48a922421f522b027a1a727ab4d0926368454aa953d36d/grpcio-1.81.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:e4d053900a0d24b75d7521139a3872150301b3d6bde3bed5e12318fb25791e4d", size = 6595872, upload-time = "2026-06-01T05:55:04.946Z" }, + { url = "https://files.pythonhosted.org/packages/b4/1f/7ff2850eaefbecf99af3f624dbb28dd1ad6c5fd4c1d8c26909ed6482673b/grpcio-1.81.0-cp312-cp312-manylinux2014_i686.manylinux_2_17_i686.whl", hash = "sha256:db217c2e52931719f9937bd12082cd4d7b495b35803d5760686975c285924bf8", size = 7303857, upload-time = "2026-06-01T05:55:07.205Z" }, + { url = "https://files.pythonhosted.org/packages/e2/98/1f3896a9baae1f2aedf4e99c55291d6fa1f30ad9603d63bc18bda967b53e/grpcio-1.81.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:19f201da7b4e5c0559198abe5a97157e726f3abe6e8f5e832d4a50740f6dcc22", size = 6809676, upload-time = "2026-06-01T05:55:09.513Z" }, + { url = "https://files.pythonhosted.org/packages/34/8b/3441983718095208c5d797fd3239882e97ea89a629f41c8df94b4eef4df9/grpcio-1.81.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:275144b0115353339dbb8a6f28a9cf8997b5bf40e37f8f66ac0b0ea57e95b43f", size = 7412654, upload-time = "2026-06-01T05:55:12.777Z" }, + { url = "https://files.pythonhosted.org/packages/3c/98/1eddf07df6e4fe85cf67502a793f7b05468b2dca3d1ef35b972cf5d54468/grpcio-1.81.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:5192857589f223e5a98ff0e31f6e551b19040e647d17bfe10116c8a2ce3b8696", size = 8408026, upload-time = "2026-06-01T05:55:15.514Z" }, + { url = "https://files.pythonhosted.org/packages/5c/73/3860341e6a1f5347be6ab35c6c0e1e3a8eb59d010388207fd561dcf01a88/grpcio-1.81.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:c6ff087cb1f563f47b504b4e29e684129fc5ae4863faf3ebca08a327764ee6cb", size = 7849498, upload-time = "2026-06-01T05:55:18.078Z" }, + { url = "https://files.pythonhosted.org/packages/ae/3f/0ea06bd85c701966aa3f8f37314f2ed83520d2b7590f42d643d445d8bc8b/grpcio-1.81.0-cp312-cp312-win32.whl", hash = "sha256:98c6240f563178fc5877bd50e6ff274463e53e1472128f4110742450739659fa", size = 4184161, upload-time = "2026-06-01T05:55:20.127Z" }, + { url = "https://files.pythonhosted.org/packages/39/e3/a7c387406827a86f99ad7838b995bf9b4a182ffe2d2c439ed2873efec952/grpcio-1.81.0-cp312-cp312-win_amd64.whl", hash = "sha256:87e33b7afcfb3585121b5f007d2c52b8c534104d18f556e840d35193ca2a9141", size = 4929958, upload-time = "2026-06-01T05:55:22.736Z" }, + { url = "https://files.pythonhosted.org/packages/f3/29/779ee53c931d0fd55c1d459fde43e485172caa3ac87cbd43d003a13a0185/grpcio-1.81.0-cp313-cp313-linux_armv7l.whl", hash = "sha256:62bbe463c9f0f2ff24e31bd25f8dd8b4bae78900e315915a3195a0ef1471a855", size = 6054973, upload-time = "2026-06-01T05:55:25.043Z" }, + { url = "https://files.pythonhosted.org/packages/9e/b6/7211807926b5a17f8d9a5d47c739a163d6812fefe3e4714e81cf92945ed7/grpcio-1.81.0-cp313-cp313-macosx_11_0_universal2.whl", hash = "sha256:43c121e135ae44d1559b430db2b2dfad7421cbbe40e1deba506c7dc62b439719", size = 12048662, upload-time = "2026-06-01T05:55:28.453Z" }, + { url = "https://files.pythonhosted.org/packages/64/89/b1b93ef6b34bd20bbaf707fa99133bc9cc302139d5ec6f77a165c7169796/grpcio-1.81.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:f345de40ef2e65f63645d53d251824e6070e07804827c5b00ec2e44555f9f901", size = 6599116, upload-time = "2026-06-01T05:55:31.185Z" }, + { url = "https://files.pythonhosted.org/packages/eb/bc/c89f9b9d1c22895715356a1e009554dae66319e97826bb4d30bcda7d29e8/grpcio-1.81.0-cp313-cp313-manylinux2014_i686.manylinux_2_17_i686.whl", hash = "sha256:8c0855a350886f713b9e458e2a10d208009dcaa849f574e39cd6067db1fe1279", size = 7307591, upload-time = "2026-06-01T05:55:33.463Z" }, + { url = "https://files.pythonhosted.org/packages/65/4a/1df2a4cb4a1386e066ab7e4175e34bb884b35ccb60d3621c09c84af6aabb/grpcio-1.81.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:a524cd530900bd24511fcb7f2ed144da4ea37711c4b094475d0bceca7a93a170", size = 6811797, upload-time = "2026-06-01T05:55:36.731Z" }, + { url = "https://files.pythonhosted.org/packages/8d/dc/fa189d20601a1be25b08850cfb733879bbb1047b62a8feec3a60e3e1a87b/grpcio-1.81.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:e7746ba3e6efc9e2b748eff59470a2b8684d5a9ec607c6580bcaa5be175820bc", size = 7415131, upload-time = "2026-06-01T05:55:39.451Z" }, + { url = "https://files.pythonhosted.org/packages/ad/a3/5625c48cb48d23c6631b3e5294f88e4c751f22a52591ae78859fab96dca1/grpcio-1.81.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:aaaa4f7f2057d795952e4eacf3f342be8b5b156992f6ac85023c8b98794ebd47", size = 8408398, upload-time = "2026-06-01T05:55:42.219Z" }, + { url = "https://files.pythonhosted.org/packages/75/34/0f8202c6809a46c2b4d69125ef3667c40b1c211f8e19930e5fa1f1197039/grpcio-1.81.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:0fba53cb96004b2b7fb758b46b2288cb49d0b658316a4e73f3ef67230616ee65", size = 7844481, upload-time = "2026-06-01T05:55:44.849Z" }, + { url = "https://files.pythonhosted.org/packages/c0/95/c3366b5b5edf4c4adc90f2e29ca16e57965a8e56dc8d2ee89565ba1905bb/grpcio-1.81.0-cp313-cp313-win32.whl", hash = "sha256:c197e2ef75a442528072b29e9755da299110e8610e8bcbb59a6b4cf55384f005", size = 4182777, upload-time = "2026-06-01T05:55:47.459Z" }, + { url = "https://files.pythonhosted.org/packages/a9/a7/932f2f748511a32e641a2aba0d30dded3ed6e8bc330e0924e4d5d86853e6/grpcio-1.81.0-cp313-cp313-win_amd64.whl", hash = "sha256:194eddfacc84d80f50512e9fd4ee851d5f2499f18f299c95aa8fb4748f0537e0", size = 4928085, upload-time = "2026-06-01T05:55:50.158Z" }, + { url = "https://files.pythonhosted.org/packages/c5/1d/28b231333857deb840bc3d182ae087510170ea6d68f21393aeb0fe499530/grpcio-1.81.0-cp314-cp314-linux_armv7l.whl", hash = "sha256:a9351055f52660b58f3d4890ea66188b5134399f82b11aa0c55bd4b99eff5390", size = 6055712, upload-time = "2026-06-01T05:55:52.889Z" }, + { url = "https://files.pythonhosted.org/packages/e8/b8/999c14f9dff0fc47549d2e827cba1343ddc18e1d1bf0d06d2cf628eecbd9/grpcio-1.81.0-cp314-cp314-macosx_11_0_universal2.whl", hash = "sha256:300f3337b6425fd16ead9a4f9b2ac25801acb64aa5bc0b99eb69901645b2b1d2", size = 12057189, upload-time = "2026-06-01T05:55:55.952Z" }, + { url = "https://files.pythonhosted.org/packages/1e/3d/1fbde079572562af65351151d840525a13879eb7b481d35b55cd64c6127a/grpcio-1.81.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:97bbd623f7ded558fd4f7cb5a4f600c4d4de65c5dd364c83a5b14b2a10a2d3b5", size = 6608136, upload-time = "2026-06-01T05:55:59.069Z" }, + { url = "https://files.pythonhosted.org/packages/32/89/1f17cb6882abfd8e5a303a25d5d1665abef5a8c499a96198c65a651d1b85/grpcio-1.81.0-cp314-cp314-manylinux2014_i686.manylinux_2_17_i686.whl", hash = "sha256:ff83d889e3ebf6341c8c7864ad8031591ad5ca61599072fc511644d1eb962d2b", size = 7307045, upload-time = "2026-06-01T05:56:02.376Z" }, + { url = "https://files.pythonhosted.org/packages/48/5a/f98e91b2e755652e637ea2144318b0229b290062199f761b445fe1fa6015/grpcio-1.81.0-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:c4fe218c5a35e1d87a5a26544237f1fa41dfd9cbd3c856b0810a30061f8b0aaf", size = 6812794, upload-time = "2026-06-01T05:56:05.777Z" }, + { url = "https://files.pythonhosted.org/packages/0a/0c/77892d715ac41e7ec0ace2a50080ffb64e189188056f607a66fe0014d1ee/grpcio-1.81.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:b8b025b6af43ee0ad4a70307025d77bcab5adde7c4597786010d802c203e9fc5", size = 7422767, upload-time = "2026-06-01T05:56:08.524Z" }, + { url = "https://files.pythonhosted.org/packages/3f/b8/aa04590c6564714d94954515f15a236e59d4b9b3ad01e615f1b706d7792d/grpcio-1.81.0-cp314-cp314-musllinux_1_2_i686.whl", hash = "sha256:3d4e0ce5a40a998cf608c8ba60ecfe18fdf364a9aa193ae4ac3faeecd0e86757", size = 8408551, upload-time = "2026-06-01T05:56:11.283Z" }, + { url = "https://files.pythonhosted.org/packages/43/3d/4f4a3450a1973568910c6909cb74abbf2126f68aefae5976962f9f7ad50d/grpcio-1.81.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:aa948712c8e5fa40ec250870bda14bc7578e1bb832a8912d9d2a0f720518edbe", size = 7846468, upload-time = "2026-06-01T05:56:14.536Z" }, + { url = "https://files.pythonhosted.org/packages/88/f4/5827fd248221ad3b44161c23ce9b5f4ee405b04fc6da5fd402a9aa87a84a/grpcio-1.81.0-cp314-cp314-win32.whl", hash = "sha256:fbbe81314a9d92156abce8b62c09364eb8bafc0ca2a19919a45ec64b5c6cb664", size = 4264427, upload-time = "2026-06-01T05:56:17.192Z" }, + { url = "https://files.pythonhosted.org/packages/0c/e8/127dc2b246096ad50ef7c8d9b7b31d757787aeb796368bcdd4454e4204c4/grpcio-1.81.0-cp314-cp314-win_amd64.whl", hash = "sha256:b93cee313cae4e113fbb3a0ce1ea5633db6f63cfde2b2dc1d817429026b2a50b", size = 5070848, upload-time = "2026-06-01T05:56:19.735Z" }, +] + +[[package]] +name = "grpcio-status" +version = "1.81.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "googleapis-common-protos" }, + { name = "grpcio" }, + { name = "protobuf" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/01/b6/cdc177114997d15c887fb09ccfd16705c8ceb8b4ca2487902b54a7bfd1af/grpcio_status-1.81.0.tar.gz", hash = "sha256:b6fe9788cfdd1f0f63c0528a1e0bfdb41e8ff0583e920d2d8e8888598c01bb69", size = 13900, upload-time = "2026-06-01T06:00:32.638Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/f3/b7/5aa346bf1cdecd4ed64b86c10a4d5a089ce3da89145f8328caf0b22b240d/grpcio_status-1.81.0-py3-none-any.whl", hash = "sha256:10eb4c2309db902dc26c1873e80a821bf794be772c10dfd83030f7f59f165fab", size = 14634, upload-time = "2026-06-01T06:00:13.345Z" }, +] + +[[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.18" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/cd/63/9496c57188a2ee585e0f1db071d75089a11e98aa86eb99d9d7618fc1edce/idna-3.18.tar.gz", hash = "sha256:ffb385a7e039654cef1ab9ef32c6fafe283c0c0467bba1d9029738ce4a14a848", size = 196711, upload-time = "2026-06-02T14:34:07.794Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/1e/5e/d4e9f1a599fb8e573b7b87160658329fbf28d19eac2718f51fc3def3aa5a/idna-3.18-py3-none-any.whl", hash = "sha256:7f952cbe720b688055e3f87de14f5c3e5fdaa8bc3928985c4077ca689de849a2", size = 65455, upload-time = "2026-06-02T14:34:06.319Z" }, +] + +[[package]] +name = "importlib-metadata" +version = "8.7.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "zipp" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/f3/49/3b30cad09e7771a4982d9975a8cbf64f00d4a1ececb53297f1d9a7be1b10/importlib_metadata-8.7.1.tar.gz", hash = "sha256:49fef1ae6440c182052f407c8d34a68f72efc36db9ca90dc0113398f2fdde8bb", size = 57107, upload-time = "2025-12-21T10:00:19.278Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/fa/5e/f8e9a1d23b9c20a551a8a02ea3637b4642e22c2626e3a13a9a29cdea99eb/importlib_metadata-8.7.1-py3-none-any.whl", hash = "sha256:5a1f80bf1daa489495071efbb095d75a634cf28a8bc299581244063b53176151", size = 27865, upload-time = "2025-12-21T10:00:18.329Z" }, +] + +[[package]] +name = "joserfc" +version = "1.7.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "cryptography" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/44/90/25cb27518750218e4f850be63d8bbb2343efaad1c01c3571aaa4b3c33bd7/joserfc-1.7.1.tar.gz", hash = "sha256:77d0b76514879c68c6f433bc5b7357a4ab72008ff1e33d8379fd11d72bd8ca81", size = 233181, upload-time = "2026-06-08T07:21:33.412Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/b3/00/fa62404c3e347f946faa13aa21085205f9cc06ad17671e37f81a51662ae8/joserfc-1.7.1-py3-none-any.whl", hash = "sha256:b3e3d655612e2e1ef67b2600f2f420e12e537b020208fab1761fad647319c164", size = 70423, upload-time = "2026-06-08T07:21:32.001Z" }, +] + +[[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]] +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 = "opentelemetry-api" +version = "1.41.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "importlib-metadata" }, + { name = "typing-extensions" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/fa/fc/b7564cbef36601aef0d6c9bc01f7badb64be8e862c2e1c3c5c3b43b53e4f/opentelemetry_api-1.41.1.tar.gz", hash = "sha256:0ad1814d73b875f84494387dae86ce0b12c68556331ce6ce8fe789197c949621", size = 71416, upload-time = "2026-04-24T13:15:38.262Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/29/59/3e7118ed140f76b0982ba4321bdaed1997a0473f9720de2d10788a577033/opentelemetry_api-1.41.1-py3-none-any.whl", hash = "sha256:a22df900e75c76dc08440710e51f52f1aa6b451b429298896023e60db5b3139f", size = 69007, upload-time = "2026-04-24T13:15:15.662Z" }, +] + +[[package]] +name = "opentelemetry-sdk" +version = "1.41.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "opentelemetry-api" }, + { name = "opentelemetry-semantic-conventions" }, + { name = "typing-extensions" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/58/d0/54ee30dab82fb0acda23d144502771ff76ef8728459c83c3e89ef9fb1825/opentelemetry_sdk-1.41.1.tar.gz", hash = "sha256:724b615e1215b5aeacda0abb8a6a8922c9a1853068948bd0bd225a56d0c792e6", size = 230180, upload-time = "2026-04-24T13:15:50.991Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/b4/e7/a1420b698aad018e1cf60fdbaaccbe49021fb415e2a0d81c242f4c518f54/opentelemetry_sdk-1.41.1-py3-none-any.whl", hash = "sha256:edee379c126c1bce952b0c812b48fe8ff35b30df0eecf17e98afa4d598b7d85d", size = 180213, upload-time = "2026-04-24T13:15:33.767Z" }, +] + +[[package]] +name = "opentelemetry-semantic-conventions" +version = "0.62b1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "opentelemetry-api" }, + { name = "typing-extensions" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/9e/de/911ac9e309052aca1b20b2d5549d3db45d1011e1a610e552c6ccdd1b64f8/opentelemetry_semantic_conventions-0.62b1.tar.gz", hash = "sha256:c5cc6e04a7f8c7cdd30be2ed81499fa4e75bfbd52c9cb70d40af1f9cd3619802", size = 145750, upload-time = "2026-04-24T13:15:52.236Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/eb/a6/83dc2ab6fa397ee66fba04fe2e74bdf7be3b3870005359ceb7689103c058/opentelemetry_semantic_conventions-0.62b1-py3-none-any.whl", hash = "sha256:cf506938103d331fbb78eded0d9788095f7fd59016f2bda813c3324e5a74a93c", size = 231620, upload-time = "2026-04-24T13:15:35.454Z" }, +] + +[[package]] +name = "packaging" +version = "26.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/d7/f1/e7a6dd94a8d4a5626c03e4e99c87f241ba9e350cd9e6d75123f992427270/packaging-26.2.tar.gz", hash = "sha256:ff452ff5a3e828ce110190feff1178bb1f2ea2281fa2075aadb987c2fb221661", size = 228134, upload-time = "2026-04-24T20:15:23.917Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/df/b2/87e62e8c3e2f4b32e5fe99e0b86d576da1312593b39f47d8ceef365e95ed/packaging-26.2-py3-none-any.whl", hash = "sha256:5fc45236b9446107ff2415ce77c807cee2862cb6fac22b8a73826d0693b0980e", size = 100195, upload-time = "2026-04-24T20:15:22.081Z" }, +] + +[[package]] +name = "proto-plus" +version = "1.28.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "protobuf" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/c9/56/e647b0c675392d2da368da7b6f158f7368b18542fd6f7d7400a2f39de000/proto_plus-1.28.0.tar.gz", hash = "sha256:38e5696342835b08fc116f30a25665b29531cda9d5d5643e9b81fc312385abd9", size = 57221, upload-time = "2026-05-07T08:04:50.811Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/7c/20/b122d4626976acb81132036d2ad1bb35a1a8775fceb837ec30964622516a/proto_plus-1.28.0-py3-none-any.whl", hash = "sha256:a630604310899e73c59ec302e5765c058d412b2f090b9c79c8822589f14955b8", size = 50410, upload-time = "2026-05-07T08:03:31.962Z" }, +] + +[[package]] +name = "protobuf" +version = "6.33.6" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/66/70/e908e9c5e52ef7c3a6c7902c9dfbb34c7e29c25d2f81ade3856445fd5c94/protobuf-6.33.6.tar.gz", hash = "sha256:a6768d25248312c297558af96a9f9c929e8c4cee0659cb07e780731095f38135", size = 444531, upload-time = "2026-03-18T19:05:00.988Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/fc/9f/2f509339e89cfa6f6a4c4ff50438db9ca488dec341f7e454adad60150b00/protobuf-6.33.6-cp310-abi3-win32.whl", hash = "sha256:7d29d9b65f8afef196f8334e80d6bc1d5d4adedb449971fefd3723824e6e77d3", size = 425739, upload-time = "2026-03-18T19:04:48.373Z" }, + { url = "https://files.pythonhosted.org/packages/76/5d/683efcd4798e0030c1bab27374fd13a89f7c2515fb1f3123efdfaa5eab57/protobuf-6.33.6-cp310-abi3-win_amd64.whl", hash = "sha256:0cd27b587afca21b7cfa59a74dcbd48a50f0a6400cfb59391340ad729d91d326", size = 437089, upload-time = "2026-03-18T19:04:50.381Z" }, + { url = "https://files.pythonhosted.org/packages/5c/01/a3c3ed5cd186f39e7880f8303cc51385a198a81469d53d0fdecf1f64d929/protobuf-6.33.6-cp39-abi3-macosx_10_9_universal2.whl", hash = "sha256:9720e6961b251bde64edfdab7d500725a2af5280f3f4c87e57c0208376aa8c3a", size = 427737, upload-time = "2026-03-18T19:04:51.866Z" }, + { url = "https://files.pythonhosted.org/packages/ee/90/b3c01fdec7d2f627b3a6884243ba328c1217ed2d978def5c12dc50d328a3/protobuf-6.33.6-cp39-abi3-manylinux2014_aarch64.whl", hash = "sha256:e2afbae9b8e1825e3529f88d514754e094278bb95eadc0e199751cdd9a2e82a2", size = 324610, upload-time = "2026-03-18T19:04:53.096Z" }, + { url = "https://files.pythonhosted.org/packages/9b/ca/25afc144934014700c52e05103c2421997482d561f3101ff352e1292fb81/protobuf-6.33.6-cp39-abi3-manylinux2014_s390x.whl", hash = "sha256:c96c37eec15086b79762ed265d59ab204dabc53056e3443e702d2681f4b39ce3", size = 339381, upload-time = "2026-03-18T19:04:54.616Z" }, + { url = "https://files.pythonhosted.org/packages/16/92/d1e32e3e0d894fe00b15ce28ad4944ab692713f2e7f0a99787405e43533a/protobuf-6.33.6-cp39-abi3-manylinux2014_x86_64.whl", hash = "sha256:e9db7e292e0ab79dd108d7f1a94fe31601ce1ee3f7b79e0692043423020b0593", size = 323436, upload-time = "2026-03-18T19:04:55.768Z" }, + { url = "https://files.pythonhosted.org/packages/c4/72/02445137af02769918a93807b2b7890047c32bfb9f90371cbc12688819eb/protobuf-6.33.6-py3-none-any.whl", hash = "sha256:77179e006c476e69bf8e8ce866640091ec42e1beb80b213c3900006ecfba6901", size = 170656, upload-time = "2026-03-18T19:04:59.826Z" }, +] + +[[package]] +name = "pyasn1" +version = "0.6.3" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/5c/5f/6583902b6f79b399c9c40674ac384fd9cd77805f9e6205075f828ef11fb2/pyasn1-0.6.3.tar.gz", hash = "sha256:697a8ecd6d98891189184ca1fa05d1bb00e2f84b5977c481452050549c8a72cf", size = 148685, upload-time = "2026-03-17T01:06:53.382Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/5d/a0/7d793dce3fa811fe047d6ae2431c672364b462850c6235ae306c0efd025f/pyasn1-0.6.3-py3-none-any.whl", hash = "sha256:a80184d120f0864a52a073acc6fc642847d0be408e7c7252f31390c0f4eadcde", size = 83997, upload-time = "2026-03-17T01:06:52.036Z" }, +] + +[[package]] +name = "pyasn1-modules" +version = "0.4.2" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "pyasn1" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/e9/e6/78ebbb10a8c8e4b61a59249394a4a594c1a7af95593dc933a349c8d00964/pyasn1_modules-0.4.2.tar.gz", hash = "sha256:677091de870a80aae844b1ca6134f54652fa2c8c5a52aa396440ac3106e941e6", size = 307892, upload-time = "2025-03-28T02:41:22.17Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/47/8d/d529b5d697919ba8c11ad626e835d4039be708a35b0d22de83a269a6682c/pyasn1_modules-0.4.2-py3-none-any.whl", hash = "sha256:29253a9207ce32b64c3ac6600edc75368f98473906e8fd1043bd6b5b1de2c14a", size = 181259, upload-time = "2025-03-28T02:41:19.028Z" }, +] + +[[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 = "pydantic" +version = "2.13.4" +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/18/a5/b60d21ac674192f8ab0ba4e9fd860690f9b4a6e51ca5df118733b487d8d6/pydantic-2.13.4.tar.gz", hash = "sha256:c40756b57adaa8b1efeeced5c196f3f3b7c435f90e84ea7f443901bec8099ef6", size = 844775, upload-time = "2026-05-06T13:43:05.343Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/fd/7b/122376b1fd3c62c1ed9dc80c931ace4844b3c55407b6fb2d199377c9736f/pydantic-2.13.4-py3-none-any.whl", hash = "sha256:45a282cde31d808236fd7ea9d919b128653c8b38b393d1c4ab335c62924d9aba", size = 472262, upload-time = "2026-05-06T13:43:02.641Z" }, +] + +[[package]] +name = "pydantic-core" +version = "2.46.4" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "typing-extensions" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/9d/56/921726b776ace8d8f5db44c4ef961006580d91dc52b803c489fafd1aa249/pydantic_core-2.46.4.tar.gz", hash = "sha256:62f875393d7f270851f20523dd2e29f082bcc82292d66db2b64ea71f64b6e1c1", size = 471464, upload-time = "2026-05-06T13:37:06.98Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/5c/fa/6d7708d2cfc1a832acb6aeb0cd16e801902df8a0f583bb3b4b527fde022e/pydantic_core-2.46.4-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:0e96592440881c74a213e5ad528e2b24d3d4f940de2766bed9010ab1d9e51594", size = 2111872, upload-time = "2026-05-06T13:40:27.596Z" }, + { url = "https://files.pythonhosted.org/packages/ae/6f/aa064a3e74b5745afbdf250594f38e7ead05e2d651bcb35994b9417a0d4d/pydantic_core-2.46.4-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:e0d65b8c354be7fb5f720c3caa8bc940bc2d20ce749c8e06135f07f8ed95dd7c", size = 1948255, upload-time = "2026-05-06T13:39:12.574Z" }, + { url = "https://files.pythonhosted.org/packages/43/3a/41114a9f7569b84b4d84e7a018c57c56347dac30c0d4a872946ec4e36c46/pydantic_core-2.46.4-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7bfb192b3f4b9e8a89b6277b6ce787564f62cfd272055f6e685726b111dc7826", size = 1972827, upload-time = "2026-05-06T13:38:19.841Z" }, + { url = "https://files.pythonhosted.org/packages/ef/25/1ab42e8048fe551934d9884e8d64daa7e990ad386f310a15981aeb6a5b08/pydantic_core-2.46.4-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:9037063db01f09b09e237c282b6792bd4da634b5402c4e7f0c61effed7701a04", size = 2041051, upload-time = "2026-05-06T13:38:10.447Z" }, + { url = "https://files.pythonhosted.org/packages/94/c2/1a934597ddf08da410385b3b7aae91956a5a76c635effef456074fad7e88/pydantic_core-2.46.4-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:fc010ab034c8c7452522748bf937df58020d256ccae0874463d1f4d01758af8e", size = 2221314, upload-time = "2026-05-06T13:40:13.089Z" }, + { url = "https://files.pythonhosted.org/packages/02/6d/9e8ad178c9c4df27ad3c8f25d1fe2a7ab0d2ba0559fad4aee5d3d1f16771/pydantic_core-2.46.4-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8c5dac79fa1614d1e06ca695109c6105923bd9c7d1d6c918d4e637b7e6b32fd3", size = 2285146, upload-time = "2026-05-06T13:38:59.224Z" }, + { url = "https://files.pythonhosted.org/packages/80/50/540cd3aeefc041beb111125c4bff779831a2111fc6b15a9138cda277d32c/pydantic_core-2.46.4-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f9fa868638bf362d3d138ea55829cefb3d5f4b0d7f142234382a15e2485dbec4", size = 2089685, upload-time = "2026-05-06T13:38:17.762Z" }, + { url = "https://files.pythonhosted.org/packages/6b/a4/b440ad35f05f6a38f89fa0f149accb3f0e02be94ca5e15f3c449a61b4bc9/pydantic_core-2.46.4-cp311-cp311-manylinux_2_31_riscv64.whl", hash = "sha256:17299feefe090f2caa5b8e37222bb5f663e4935a8bfa6931d4102e5df1a9f398", size = 2115420, upload-time = "2026-05-06T13:37:58.195Z" }, + { url = "https://files.pythonhosted.org/packages/99/61/de4f55db8dfd57bfdfa9a12ec90fe1b57c4f41062f7ca86f08586b3e0ac0/pydantic_core-2.46.4-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:4c63ebc82684aa89d9a3bcbd13d515b3be44250dc68dd3bd81526c1cb31286c3", size = 2165122, upload-time = "2026-05-06T13:37:01.167Z" }, + { url = "https://files.pythonhosted.org/packages/f7/52/7c529d7bdb2d1068bd52f51fe32572c8301f9a4febf1948f10639f1436f5/pydantic_core-2.46.4-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:aaa2a54443eff1950ba5ddc6b6ccda0d9c84a364276a62f969bdf2a390650848", size = 2182573, upload-time = "2026-05-06T13:38:45.04Z" }, + { url = "https://files.pythonhosted.org/packages/37/b3/7c40325848ba78247f2812dcf9c7274e38cd801820ca6dd9fe63bcfb0eb4/pydantic_core-2.46.4-cp311-cp311-musllinux_1_1_armv7l.whl", hash = "sha256:18e5ceec2ab67e6d5f1a9085e5a24c9c4e2ac4545730bfe668680bca05e555f3", size = 2317139, upload-time = "2026-05-06T13:37:15.539Z" }, + { url = "https://files.pythonhosted.org/packages/d9/37/f913f81a657c865b75da6c0dbed79876073c2a43b5bd9edbe8da785e4d49/pydantic_core-2.46.4-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:a0f62d0a58f4e7da165457e995725421e0064f2255d8eccebc49f41bbc23b109", size = 2360433, upload-time = "2026-05-06T13:37:30.099Z" }, + { url = "https://files.pythonhosted.org/packages/c4/67/6acaa1be2567f9256b056d8477158cac7240813956ce86e49deae8e173b4/pydantic_core-2.46.4-cp311-cp311-win32.whl", hash = "sha256:041bde0a48fd37cf71cab1c9d56d3e8625a3793fef1f7dd232b3ff37e978ecda", size = 1985513, upload-time = "2026-05-06T13:38:15.669Z" }, + { url = "https://files.pythonhosted.org/packages/aa/e6/c505f83dfeda9a2e5c995cfd872949e4d05e12f7feb3dca72f633daefa94/pydantic_core-2.46.4-cp311-cp311-win_amd64.whl", hash = "sha256:6f2eeda33a839975441c86a4119e1383c50b47faf0cbb5176985565c6bb02c33", size = 2071114, upload-time = "2026-05-06T13:40:35.416Z" }, + { url = "https://files.pythonhosted.org/packages/0f/da/7a263a96d965d9d0df5e8de8a475f33495451117035b09acb110288c381f/pydantic_core-2.46.4-cp311-cp311-win_arm64.whl", hash = "sha256:14f4c5d6db102bd796a627bbb3a17b4cf4574b9ae861d8b7c9a9661c6dd3362d", size = 2044298, upload-time = "2026-05-06T13:38:29.754Z" }, + { url = "https://files.pythonhosted.org/packages/ce/8c/af022f0af448d7747c5154288d46b5f2bc5f17366eaa0e23e9aa04d59f3b/pydantic_core-2.46.4-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:3245406455a5d98187ec35530fd772b1d799b26667980872c8d4614991e2c4a2", size = 2106158, upload-time = "2026-05-06T13:38:57.215Z" }, + { url = "https://files.pythonhosted.org/packages/19/95/6195171e385007300f0f5574592e467c568becce2d937a0b6804f218bc49/pydantic_core-2.46.4-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:962ccbab7b642487b1d8b7df90ef677e03134cf1fd8880bf698649b22a69371f", size = 1951724, upload-time = "2026-05-06T13:37:02.697Z" }, + { url = "https://files.pythonhosted.org/packages/8e/bc/f47d1ff9cbb1620e1b5b697eef06010035735f07820180e74178226b27b3/pydantic_core-2.46.4-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8233f2947cf85404441fd7e0085f53b10c93e0ee78611099b5c7237e36aacbf7", size = 1975742, upload-time = "2026-05-06T13:37:09.448Z" }, + { url = "https://files.pythonhosted.org/packages/5b/11/9b9a5b0306345664a2da6410877af6e8082481b5884b3ddd78d47c6013ce/pydantic_core-2.46.4-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:3a233125ac121aa3ffba9a2b59edfc4a985a76092dc8279586ab4b71390875e7", size = 2052418, upload-time = "2026-05-06T13:37:38.234Z" }, + { url = "https://files.pythonhosted.org/packages/f1/b7/a65fec226f5d78fc39f4a13c4cc0c768c22b113438f60c14adc9d2865038/pydantic_core-2.46.4-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5b712b53160b79a5850310b912a5ef8e57e56947c8ad690c227f5c9d7e561712", size = 2232274, upload-time = "2026-05-06T13:38:27.753Z" }, + { url = "https://files.pythonhosted.org/packages/68/f0/92039db98b907ef49269a8271f67db9cb78ae2fc68062ef7e4e77adb5f61/pydantic_core-2.46.4-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9401557acd873c3a7f3eb9383edef8ac4968f9510e340f4808d427e75667e7b4", size = 2309940, upload-time = "2026-05-06T13:38:05.353Z" }, + { url = "https://files.pythonhosted.org/packages/5f/97/2aab507d3d00ca626e8e57c1eac6a79e4e5fbcc63eb99733ff55d1717f65/pydantic_core-2.46.4-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:926c9541b14b12b1681dca8a0b75feb510b06c6341b70a8e500c2fdcff837cce", size = 2094516, upload-time = "2026-05-06T13:39:10.577Z" }, + { url = "https://files.pythonhosted.org/packages/22/37/a8aca44d40d737dde2bc05b3c6c07dff0de07ce6f82e9f3167aeaf4d5dea/pydantic_core-2.46.4-cp312-cp312-manylinux_2_31_riscv64.whl", hash = "sha256:56cb4851bcaf3d117eddcef4fe66afd750a50274b0da8e22be256d10e5611987", size = 2136854, upload-time = "2026-05-06T13:40:22.59Z" }, + { url = "https://files.pythonhosted.org/packages/24/99/fcef1b79238c06a8cbec70819ac722ba76e02bc8ada9b0fd66eba40da01b/pydantic_core-2.46.4-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:c68fcd102d71ea85c5b2dfac3f4f8476eff42a9e078fd5faefff6d145063536b", size = 2180306, upload-time = "2026-05-06T13:40:10.666Z" }, + { url = "https://files.pythonhosted.org/packages/ae/6c/fc44000918855b42779d007ae63b0532794739027b2f417321cddbc44f6a/pydantic_core-2.46.4-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:b2f69dec1725e79a012d920df1707de5caf7ed5e08f3be4435e25803efc47458", size = 2190044, upload-time = "2026-05-06T13:40:43.231Z" }, + { url = "https://files.pythonhosted.org/packages/6b/65/d9cadc9f1920d7a127ad2edba16c1db7916e59719285cd6c94600b0080ba/pydantic_core-2.46.4-cp312-cp312-musllinux_1_1_armv7l.whl", hash = "sha256:8d0820e8192167f80d88d64038e609c31452eeca865b4e1d9950a27a4609b00b", size = 2329133, upload-time = "2026-05-06T13:39:57.365Z" }, + { url = "https://files.pythonhosted.org/packages/d0/cf/c873d91679f3a30bcf5e7ac280ce5573483e72295307685120d0d5ad3416/pydantic_core-2.46.4-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:fbdb89b3e1c94a30cc5edfce477c6e6a5dc4d8f84665b455c27582f211a1c72c", size = 2374464, upload-time = "2026-05-06T13:38:06.976Z" }, + { url = "https://files.pythonhosted.org/packages/47/bd/6f2fc8188f31bf10590f1e98e7b306336161fac930a8c514cd7bd828c7dc/pydantic_core-2.46.4-cp312-cp312-win32.whl", hash = "sha256:9aa768456404a8bf48a4406685ac2bec8e72b62c69313734fa3b73cf33b3a894", size = 1974823, upload-time = "2026-05-06T13:40:47.985Z" }, + { url = "https://files.pythonhosted.org/packages/40/8c/985c1d41ea1107c2534abd9870e4ed5c8e7669b5c308297835c001e7a1c4/pydantic_core-2.46.4-cp312-cp312-win_amd64.whl", hash = "sha256:e9c26f834c65f5752f3f06cb08cb86a913ceb7274d0db6e267808a708b46bc89", size = 2072919, upload-time = "2026-05-06T13:39:21.153Z" }, + { url = "https://files.pythonhosted.org/packages/c4/ba/f463d006e0c47373ca7ec5e1a261c59dc01ef4d62b2657af925fb0deee3a/pydantic_core-2.46.4-cp312-cp312-win_arm64.whl", hash = "sha256:4fc73cb559bdb54b1134a706a2802a4cddd27a0633f5abb7e53056268751ac6a", size = 2027604, upload-time = "2026-05-06T13:39:03.753Z" }, + { url = "https://files.pythonhosted.org/packages/51/a2/5d30b469c5267a17b39dec53208222f76a8d351dfac4af661888c5aee77d/pydantic_core-2.46.4-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:5d5902252db0d3cedf8d4a1bc68f70eeb430f7e4c7104c8c476753519b423008", size = 2106306, upload-time = "2026-05-06T13:37:48.029Z" }, + { url = "https://files.pythonhosted.org/packages/c1/81/4fa520eaffa8bd7d1525e644cd6d39e7d60b1592bc5b516693c7340b50f1/pydantic_core-2.46.4-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:c94f0688e7b8d0a67abf40e57a7eaaecd17cc9586706a31b76c031f63df052b4", size = 1951906, upload-time = "2026-05-06T13:37:17.012Z" }, + { url = "https://files.pythonhosted.org/packages/03/d5/fd02da45b659668b05923b17ba3a0100a0a3d5541e3bd8fcc4ecb711309e/pydantic_core-2.46.4-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f027324c56cd5406ca49c124b0db10e56c69064fec039acc571c29020cc87c76", size = 1976802, upload-time = "2026-05-06T13:37:35.113Z" }, + { url = "https://files.pythonhosted.org/packages/21/f2/95727e1368be3d3ed485eaab7adbd7dda408f33f7a36e8b48e0144002b91/pydantic_core-2.46.4-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:e739fee756ba1010f8bcccb534252e85a35fe45ae92c295a06059ce58b74ccd3", size = 2052446, upload-time = "2026-05-06T13:37:12.313Z" }, + { url = "https://files.pythonhosted.org/packages/9c/86/5d99feea3f77c7234b8718075b23db11532773c1a0dbd9b9490215dc2eeb/pydantic_core-2.46.4-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9d56801be94b86a9da183e5f3766e6310752b99ff647e38b09a9500d88e46e76", size = 2232757, upload-time = "2026-05-06T13:39:01.149Z" }, + { url = "https://files.pythonhosted.org/packages/d2/3a/508ac615935ef7588cf6d9e9b91309fdc2da751af865e02a9098de88258c/pydantic_core-2.46.4-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2412e734dcb48da14d4e4006b82b46b74f2518b8a26ee7e58c6844a6cd6d03c4", size = 2309275, upload-time = "2026-05-06T13:37:41.406Z" }, + { url = "https://files.pythonhosted.org/packages/07/f8/41db9de19d7987d6b04715a02b3b40aea467000275d9d758ffaa31af7d50/pydantic_core-2.46.4-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9551187363ffc0de2a00b2e47c25aeaeb1020b69b668762966df15fc5659dd5a", size = 2094467, upload-time = "2026-05-06T13:39:18.847Z" }, + { url = "https://files.pythonhosted.org/packages/2c/e2/f35033184cb11d0052daf4416e8e10a502ea2ac006fc4f459aee872727d1/pydantic_core-2.46.4-cp313-cp313-manylinux_2_31_riscv64.whl", hash = "sha256:0186750b482eefa11d7f435892b09c5c606193ef3375bcf94aa00ae6bfb66262", size = 2134417, upload-time = "2026-05-06T13:40:17.944Z" }, + { url = "https://files.pythonhosted.org/packages/7e/7b/6ceeb1cc90e193862f444ebe373d8fdf613f0a82572dde03fb10734c6c71/pydantic_core-2.46.4-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:5855698a4856556d86e8e6cd8434bc3ac0314ee8e12089ae0e143f64c6256e4e", size = 2179782, upload-time = "2026-05-06T13:40:32.618Z" }, + { url = "https://files.pythonhosted.org/packages/5a/f2/c8d7773ede6af08036423a00ae0ceffce266c3c52a096c435d68c896083f/pydantic_core-2.46.4-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:cbaf13819775b7f769bf4a1f066cb6df7a28d4480081a589828ef190226881cd", size = 2188782, upload-time = "2026-05-06T13:36:51.018Z" }, + { url = "https://files.pythonhosted.org/packages/59/31/0c864784e31f09f05cdd87606f08923b9c9e7f6e51dd27f20f62f975ce9f/pydantic_core-2.46.4-cp313-cp313-musllinux_1_1_armv7l.whl", hash = "sha256:633147d34cf4550417f12e2b1a0383973bdf5cdfde212cb09e9a581cf10820be", size = 2328334, upload-time = "2026-05-06T13:40:37.764Z" }, + { url = "https://files.pythonhosted.org/packages/c2/eb/4f6c8a41efa30baa755590f4141abf3a8c370fab610915733e74134a7270/pydantic_core-2.46.4-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:82cf5301172168103724d49a1444d3378cb20cdee30b116a1bd6031236298a5d", size = 2372986, upload-time = "2026-05-06T13:39:34.152Z" }, + { url = "https://files.pythonhosted.org/packages/5b/24/b375a480d53113860c299764bfe9f349a3dc9108b3adc0d7f0d786492ebf/pydantic_core-2.46.4-cp313-cp313-win32.whl", hash = "sha256:9fa8ae11da9e2b3126c6426f147e0fba88d96d65921799bb30c6abd1cb2c97fb", size = 1973693, upload-time = "2026-05-06T13:37:55.072Z" }, + { url = "https://files.pythonhosted.org/packages/7e/e8/cff247591966f2d22ec8c003cd7587e27b7ba7b81ab2fb888e3ab75dc285/pydantic_core-2.46.4-cp313-cp313-win_amd64.whl", hash = "sha256:6b3ace8194b0e5204818c92802dcdca7fc6d88aabbb799d7c795540d9cd6d292", size = 2071819, upload-time = "2026-05-06T13:38:49.139Z" }, + { url = "https://files.pythonhosted.org/packages/c6/1a/f4aee670d5670e9e148e0c82c7db98d780be566c6e6a97ee8035528ca0b3/pydantic_core-2.46.4-cp313-cp313-win_arm64.whl", hash = "sha256:184c081504d17f1c1066e430e117142b2c77d9448a97f7b65c6ac9fd9aee238d", size = 2027411, upload-time = "2026-05-06T13:40:45.796Z" }, + { url = "https://files.pythonhosted.org/packages/8d/74/228a26ddad29c6672b805d9fd78e8d251cd04004fa7eed0e622096cd0250/pydantic_core-2.46.4-cp314-cp314-macosx_10_12_x86_64.whl", hash = "sha256:428e04521a40150c85216fc8b85e8d39fece235a9cf5e383761238c7fa9b96fb", size = 2102079, upload-time = "2026-05-06T13:38:41.019Z" }, + { url = "https://files.pythonhosted.org/packages/ad/1f/8970b150a4b4365623ae00fc88603491f763c627311ae8031e3111356d6e/pydantic_core-2.46.4-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:23ace664830ee0bfe014a0c7bc248b1f7f25ed7ad103852c317624a1083af462", size = 1952179, upload-time = "2026-05-06T13:36:59.812Z" }, + { url = "https://files.pythonhosted.org/packages/95/30/5211a831ae054928054b2f79731661087a2bc5c01e825c672b3a4a8f1b3e/pydantic_core-2.46.4-cp314-cp314-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ce5c1d2a8b27468f433ca974829c44060b8097eedc39933e3c206a90ee49c4a9", size = 1978926, upload-time = "2026-05-06T13:37:39.933Z" }, + { url = "https://files.pythonhosted.org/packages/57/e9/689668733b1eb67adeef047db3c2e8788fcf65a7fd9c9e2b46b7744fe245/pydantic_core-2.46.4-cp314-cp314-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:7283d57845ecf5a163403eb0702dfc220cc4fbdd18919cb5ccea4f95ee1cdab4", size = 2046785, upload-time = "2026-05-06T13:38:01.995Z" }, + { url = "https://files.pythonhosted.org/packages/60/d9/6715260422ff50a2109878fd24d948a6c3446bb2664f34ee78cd972b3acd/pydantic_core-2.46.4-cp314-cp314-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8daafc69c93ee8a0204506a3b6b30f586ef54028f52aeeeb5c4cfc5184fd5914", size = 2228733, upload-time = "2026-05-06T13:40:50.371Z" }, + { url = "https://files.pythonhosted.org/packages/18/ae/fdb2f64316afca925640f8e70bb1a564b0ec2721c1389e25b8eb4bf9a299/pydantic_core-2.46.4-cp314-cp314-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:cd2213145bcc2ba85884d0ac63d222fece9209678f77b9b4d76f054c561adb28", size = 2307534, upload-time = "2026-05-06T13:37:21.531Z" }, + { url = "https://files.pythonhosted.org/packages/89/1d/8eff589b45bb8190a9d12c49cfad0f176a5cbd1534908a6b5125e2886239/pydantic_core-2.46.4-cp314-cp314-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7a5f930472650a82629163023e630d160863fce524c616f4e5186e5de9d9a49b", size = 2099732, upload-time = "2026-05-06T13:39:31.942Z" }, + { url = "https://files.pythonhosted.org/packages/06/d5/ee5a3366637fee41dee51a1fc91562dcf12ddbc68fda34e6b253da2324bb/pydantic_core-2.46.4-cp314-cp314-manylinux_2_31_riscv64.whl", hash = "sha256:c1b3f518abeca3aa13c712fd202306e145abf59a18b094a6bafb2d2bbf59192c", size = 2129627, upload-time = "2026-05-06T13:37:25.033Z" }, + { url = "https://files.pythonhosted.org/packages/94/33/2414be571d2c6a6c4d08be21f9292b6d3fdb08949a97b6dfe985017821db/pydantic_core-2.46.4-cp314-cp314-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:1a7dd0b3ee80d90150e3495a3a13ac34dbcbfd4f012996a6a1d8900e91b5c0fb", size = 2179141, upload-time = "2026-05-06T13:37:14.046Z" }, + { url = "https://files.pythonhosted.org/packages/7b/79/7daa95be995be0eecc4cf75064cb33f9bbbfe3fe0158caf2f0d4a996a5c7/pydantic_core-2.46.4-cp314-cp314-musllinux_1_1_aarch64.whl", hash = "sha256:3fb702cd90b0446a3a1c5e470bfa0dd23c0233b676a9099ddcc964fa6ca13898", size = 2184325, upload-time = "2026-05-06T13:36:53.615Z" }, + { url = "https://files.pythonhosted.org/packages/9f/cb/d0a382f5c0de8a222dc61c65348e0ce831b1f68e0a018450d31c2cace3a5/pydantic_core-2.46.4-cp314-cp314-musllinux_1_1_armv7l.whl", hash = "sha256:b8458003118a712e66286df6a707db01c52c0f52f7db8e4a38f0da1d3b94fc4e", size = 2323990, upload-time = "2026-05-06T13:40:29.971Z" }, + { url = "https://files.pythonhosted.org/packages/05/db/d9ba624cc4a5aced1598e88c04fdbd8310c8a69b9d38b9a3d39ce3a61ed7/pydantic_core-2.46.4-cp314-cp314-musllinux_1_1_x86_64.whl", hash = "sha256:372429a130e469c9cd698925ce5fc50940b7a1336b0d82038e63d5bbc4edc519", size = 2369978, upload-time = "2026-05-06T13:37:23.027Z" }, + { url = "https://files.pythonhosted.org/packages/f2/20/d15df15ba918c423461905802bfd2981c3af0bfa0e40d05e13edbfa48bc3/pydantic_core-2.46.4-cp314-cp314-win32.whl", hash = "sha256:85bb3611ff1802f3ee7fdd7dbff26b56f343fb432d57a4728fdd49b6ef35e2f4", size = 1966354, upload-time = "2026-05-06T13:38:03.499Z" }, + { url = "https://files.pythonhosted.org/packages/fc/b6/6b8de4c0a7d7ab3004c439c80c5c1e0a3e8d78bbae19379b01960383d9e5/pydantic_core-2.46.4-cp314-cp314-win_amd64.whl", hash = "sha256:811ff8e9c313ab425368bcbb36e5c4ebd7108c2bbf4e4089cfbb0b01eff63fac", size = 2072238, upload-time = "2026-05-06T13:39:40.807Z" }, + { url = "https://files.pythonhosted.org/packages/32/36/51eb763beec1f4cf59b1db243a7dcc39cbb41230f050a09b9d69faaf0a48/pydantic_core-2.46.4-cp314-cp314-win_arm64.whl", hash = "sha256:bfec22eab3c8cc2ceec0248aec886624116dc079afa027ecc8ad4a7e62010f8a", size = 2018251, upload-time = "2026-05-06T13:37:26.72Z" }, + { url = "https://files.pythonhosted.org/packages/e8/91/855af51d625b23aa987116a19e231d2aaef9c4a415273ddc189b79a45fee/pydantic_core-2.46.4-cp314-cp314t-macosx_10_12_x86_64.whl", hash = "sha256:af8244b2bef6aaad6d92cda81372de7f8c8d36c9f0c3ea36e827c60e7d9467a0", size = 2099593, upload-time = "2026-05-06T13:39:47.682Z" }, + { url = "https://files.pythonhosted.org/packages/fb/1b/8784a54c65edb5f49f0a14d6977cf1b209bba85a4c77445b255c2de58ab3/pydantic_core-2.46.4-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:5a4330cdbc57162e4b3aa303f588ba752257694c9c9be3e7ebb11b4aca659b5d", size = 1935226, upload-time = "2026-05-06T13:40:40.428Z" }, + { url = "https://files.pythonhosted.org/packages/e8/e7/1955d28d1afc56dd4b3ad7cc0cf39df1b9852964cf16e5d13912756d6d6b/pydantic_core-2.46.4-cp314-cp314t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:29c61fc04a3d840155ff08e475a04809278972fe6aef51e2720554e96367e34b", size = 1974605, upload-time = "2026-05-06T13:37:32.029Z" }, + { url = "https://files.pythonhosted.org/packages/93/e2/3fedbf0ba7a22850e6e9fd78117f1c0f10f950182344d8a6c535d468fdd8/pydantic_core-2.46.4-cp314-cp314t-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:c50f2528cf200c5eed56faf3f4e22fcd5f38c157a8b78576e6ba3168ec35f000", size = 2030777, upload-time = "2026-05-06T13:38:55.239Z" }, + { url = "https://files.pythonhosted.org/packages/f8/61/46be275fcaaba0b4f5b9669dd852267ce1ff616592dccf7a7845588df091/pydantic_core-2.46.4-cp314-cp314t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:0cbe8b01f948de4286c74cdd6c667aceb38f5c1e26f0693b3983d9d74887c65e", size = 2236641, upload-time = "2026-05-06T13:37:08.096Z" }, + { url = "https://files.pythonhosted.org/packages/60/db/12e93e46a8bac9988be3c016860f83293daea8c716c029c9ace279036f2f/pydantic_core-2.46.4-cp314-cp314t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:617d7e2ca7dcb8c5cf6bcb8c59b8832c94b36196bbf1cbd1bfb56ed341905edd", size = 2286404, upload-time = "2026-05-06T13:40:20.221Z" }, + { url = "https://files.pythonhosted.org/packages/e2/4a/4d8b19008f38d31c53b8219cfedc2e3d5de5fe99d90076b7e767de29274f/pydantic_core-2.46.4-cp314-cp314t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7027560ee92211647d0d34e3f7cd6f50da56399d26a9c8ad0da286d3869a53f3", size = 2109219, upload-time = "2026-05-06T13:38:12.153Z" }, + { url = "https://files.pythonhosted.org/packages/88/70/3cbc40978fefb7bb09c6708d40d4ad1a5d70fd7213c3d17f971de868ec1f/pydantic_core-2.46.4-cp314-cp314t-manylinux_2_31_riscv64.whl", hash = "sha256:f99626688942fb746e545232e7726926f3be91b5975f8b55327665fafda991c7", size = 2110594, upload-time = "2026-05-06T13:40:02.971Z" }, + { url = "https://files.pythonhosted.org/packages/9d/20/b8d36736216e29491125531685b2f9e61aa5b4b2599893f8268551da3338/pydantic_core-2.46.4-cp314-cp314t-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:fc3e9034a63de20e15e8ade85358bc6efc614008cab72898b4b4952bea0509ff", size = 2159542, upload-time = "2026-05-06T13:39:27.506Z" }, + { url = "https://files.pythonhosted.org/packages/1d/a2/367df868eb584dacf6bf82a389272406d7178e301c4ac82545ab98bc2dd9/pydantic_core-2.46.4-cp314-cp314t-musllinux_1_1_aarch64.whl", hash = "sha256:97e7cf2be5c77b7d1a9713a05605d49460d02c6078d38d8bef3cbe323c548424", size = 2168146, upload-time = "2026-05-06T13:38:31.93Z" }, + { url = "https://files.pythonhosted.org/packages/c1/b8/4460f77f7e201893f649a29ab355dddd3beee8a97bcb1a320db414f9a06e/pydantic_core-2.46.4-cp314-cp314t-musllinux_1_1_armv7l.whl", hash = "sha256:3bf92c5d0e00fefaab325a4d27828fe6b6e2a21848686b5b60d2d9eeb09d76c6", size = 2306309, upload-time = "2026-05-06T13:37:44.717Z" }, + { url = "https://files.pythonhosted.org/packages/64/c4/be2639293acd87dc8ddbcec41a73cee9b2ebf996fe6d892a1a74e88ad3f7/pydantic_core-2.46.4-cp314-cp314t-musllinux_1_1_x86_64.whl", hash = "sha256:3ecbc122d18468d06ca279dc26a8c2e2d5acb10943bb35e36ae92096dc3b5565", size = 2369736, upload-time = "2026-05-06T13:37:05.645Z" }, + { url = "https://files.pythonhosted.org/packages/30/a6/9f9f380dbb301f67023bf8f707aaa75daadf84f7152d95c410fd7e81d994/pydantic_core-2.46.4-cp314-cp314t-win32.whl", hash = "sha256:e846ae7835bf0703ae43f534ab79a867146dadd59dc9ca5c8b53d5c8f7c9ef02", size = 1955575, upload-time = "2026-05-06T13:38:51.116Z" }, + { url = "https://files.pythonhosted.org/packages/40/1f/f1eb9eb350e795d1af8586289746f5c5677d16043040d63710e22abc43c9/pydantic_core-2.46.4-cp314-cp314t-win_amd64.whl", hash = "sha256:2108ba5c1c1eca18030634489dc544844144ee36357f2f9f780b93e7ddbb44b5", size = 2051624, upload-time = "2026-05-06T13:38:21.672Z" }, + { url = "https://files.pythonhosted.org/packages/f6/d2/42dd53d0a85c27606f316d3aa5d2869c4e8470a5ed6dec30e4a1abe19192/pydantic_core-2.46.4-cp314-cp314t-win_arm64.whl", hash = "sha256:4fcbe087dbc2068af7eda3aa87634eba216dbda64d1ae73c8684b621d33f6596", size = 2017325, upload-time = "2026-05-06T13:40:52.723Z" }, + { url = "https://files.pythonhosted.org/packages/ee/a4/73995fd4ebbb46ba0ee51e6fa049b8f02c40daebb762208feda8a6b7894d/pydantic_core-2.46.4-graalpy311-graalpy242_311_native-macosx_10_12_x86_64.whl", hash = "sha256:14d4edf427bdcf950a8a02d7cb44a08614388dd6e1bdcbf4f67504fa7887da9c", size = 2111589, upload-time = "2026-05-06T13:37:10.817Z" }, + { url = "https://files.pythonhosted.org/packages/fb/7f/f37d3a5e8bfcc2e403f5c57a730f2d815693fb42119e8ea48b3789335af1/pydantic_core-2.46.4-graalpy311-graalpy242_311_native-macosx_11_0_arm64.whl", hash = "sha256:0ce40cd7b21210e99342afafbd4d0f76d784eb5b1d60f3bdc566be4983c6c73b", size = 1944552, upload-time = "2026-05-06T13:36:56.717Z" }, + { url = "https://files.pythonhosted.org/packages/15/3c/d7eb777b3ff43e8433a4efb39a17aa8fd98a4ee8561a24a67ef5db07b2d6/pydantic_core-2.46.4-graalpy311-graalpy242_311_native-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:90884113d8b48f760e9587002789ddd741e76ab9f89518cd1e43b1f1a52ec44b", size = 1982984, upload-time = "2026-05-06T13:39:06.207Z" }, + { url = "https://files.pythonhosted.org/packages/63/87/70b9f40170a81afd55ca26c9b2acb25c20d64bcfbf888fafecb3ba077d4c/pydantic_core-2.46.4-graalpy311-graalpy242_311_native-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:66ce7632c22d837c95301830e111ad0128a32b8207533b60896a96c4915192ea", size = 2138417, upload-time = "2026-05-06T13:39:45.476Z" }, + { url = "https://files.pythonhosted.org/packages/9d/1d/8987ad40f65ae1432753072f214fb5c74fe47ffbd0698bb9cbbb585664f8/pydantic_core-2.46.4-graalpy312-graalpy250_312_native-macosx_10_12_x86_64.whl", hash = "sha256:1d8ba486450b14f3b1d63bc521d410ec7565e52f887b9fb671791886436a42f7", size = 2095527, upload-time = "2026-05-06T13:39:52.283Z" }, + { url = "https://files.pythonhosted.org/packages/64/d3/84c282a7eee1d3ac4c0377546ef5a1ea436ce26840d9ac3b7ed54a377507/pydantic_core-2.46.4-graalpy312-graalpy250_312_native-macosx_11_0_arm64.whl", hash = "sha256:3009f12e4e90b7f88b4f9adb1b0c4a3d58fe7820f3238c190047209d148026df", size = 1936024, upload-time = "2026-05-06T13:40:15.671Z" }, + { url = "https://files.pythonhosted.org/packages/d7/ca/eac61596cdeb4d7e174d3dc0bd8a6238f14f75f97a24e7b7db4c7e7340a0/pydantic_core-2.46.4-graalpy312-graalpy250_312_native-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ad785e92e6dc634c21555edc8bd6b64957ab844541bcb96a1366c202951ae526", size = 1990696, upload-time = "2026-05-06T13:38:34.717Z" }, + { url = "https://files.pythonhosted.org/packages/fa/c3/7c8b240552251faf6b3a957db200fcfbbcec36763c050428b601e0c9b83b/pydantic_core-2.46.4-graalpy312-graalpy250_312_native-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:00c603d540afdd6b80eb39f078f33ebd46211f02f33e34a32d9f053bba711de0", size = 2147590, upload-time = "2026-05-06T13:39:29.883Z" }, + { url = "https://files.pythonhosted.org/packages/11/cb/428de0385b6c8d44b716feba566abfacfbd23ee3c4439faa789a1456242f/pydantic_core-2.46.4-pp311-pypy311_pp73-macosx_10_12_x86_64.whl", hash = "sha256:0c563b08bca408dc7f65f700633d8442fffb2421fc47b8101377e9fd65051ff0", size = 2112782, upload-time = "2026-05-06T13:37:04.016Z" }, + { url = "https://files.pythonhosted.org/packages/0b/b5/6a17bdadd0fc1f170adfd05a20d37c832f52b117b4d9131da1f41bb097ce/pydantic_core-2.46.4-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:db06ffe51636ffe9ca531fe9023dd64bdd794be8754cb5df57c5498ae5b518a7", size = 1952146, upload-time = "2026-05-06T13:39:43.092Z" }, + { url = "https://files.pythonhosted.org/packages/2a/dc/03734d80e362cd43ef65428e9de77c730ce7f2f11c60d2b1e1b39f0fbf99/pydantic_core-2.46.4-pp311-pypy311_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:133878133d271ade3d41d1bfb2a45ec38dbdbda40bc065921c6b04e4630127e2", size = 2134492, upload-time = "2026-05-06T13:36:58.124Z" }, + { url = "https://files.pythonhosted.org/packages/de/df/5e5ffc085ed07cc22d298134d3d911c63e91f6a0eb91fe646750a3209910/pydantic_core-2.46.4-pp311-pypy311_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:9bc519fbf2b7578398853d815009ae5e4d4603d12f4e3f91da8c06852d3da3e9", size = 2156604, upload-time = "2026-05-06T13:37:49.88Z" }, + { url = "https://files.pythonhosted.org/packages/81/44/6e112a4253e56f5705467cbab7ab5e91ee7398ba3d56d358635958893d3e/pydantic_core-2.46.4-pp311-pypy311_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:c7a7bd4e39e8e4c12c39cd480356842b6a8a06e41b23a55a5e3e191718838ddf", size = 2183828, upload-time = "2026-05-06T13:37:43.053Z" }, + { url = "https://files.pythonhosted.org/packages/ac/ad/5565071e937d8e752842ac241463944c9eb14c87e2d269f2658a5bd05e98/pydantic_core-2.46.4-pp311-pypy311_pp73-musllinux_1_1_armv7l.whl", hash = "sha256:d396ec2b979760aaf3218e76c24e65bd0aca24983298653b3a9d7a45f9e47b30", size = 2310000, upload-time = "2026-05-06T13:37:56.694Z" }, + { url = "https://files.pythonhosted.org/packages/4f/c3/66883a5cec183e7fba4d024b4cbbe61851a63750ef606b0afecc46d1f2bf/pydantic_core-2.46.4-pp311-pypy311_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:86e1a4418c6cd97d60c95c71164158eaf7324fae7b0923264016baa993eba6fc", size = 2361286, upload-time = "2026-05-06T13:40:05.667Z" }, + { url = "https://files.pythonhosted.org/packages/4b/2d/69abac8f838090bbecd5df894befb2c2619e7996a98ddb949db9f3b93225/pydantic_core-2.46.4-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:d51026d73fcfd93610abc7b27789c26b313920fcfb20e27462d74a7f8b06e983", size = 2193071, upload-time = "2026-05-06T13:38:08.682Z" }, +] + +[[package]] +name = "pyopenssl" +version = "26.2.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "cryptography" }, + { name = "typing-extensions", marker = "python_full_version < '3.13'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/1a/51/27a5ad5f939d08f690a326ef9582cda7140555180db71695f6fb747d6a36/pyopenssl-26.2.0.tar.gz", hash = "sha256:8c6fcecd1183a7fc897548dfe388b0cdb7f37e018200d8409cf33959dbe35387", size = 182195, upload-time = "2026-05-04T23:06:09.72Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/73/b8/a0e2790ae249d6f38c9f66de7a211621a7ab2650217bcd04e1262f578a56/pyopenssl-26.2.0-py3-none-any.whl", hash = "sha256:4f9d971bc5298b8bc1fab282803da04bf000c755d4ad9d99b52de2569ca19a70", size = 55823, upload-time = "2026-05-04T23:06:08.395Z" }, +] + +[[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-multipart" +version = "0.0.32" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/5b/42/55c32bb9b12693c092ad250a0e82edb5b31ddeda6eb772de5f308b3804ad/python_multipart-0.0.32.tar.gz", hash = "sha256:be54b7f3fa167bb83e4fcd936b887b708f4e57fe75911c02aebf53efaf8d938e", size = 46881, upload-time = "2026-06-04T16:18:58.647Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/e1/04/e8135ebd1ad02c56ec633277529b2602ff99ff634be76cdba5744cf554fd/python_multipart-0.0.32-py3-none-any.whl", hash = "sha256:ff6d3f776f16878c894e52e107296ffc890e913c611b1a4ec6c44e2821fe2e23", size = 30042, upload-time = "2026-06-04T16:18:57.319Z" }, +] + +[[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/6d/16/a95b6757765b7b031c9374925bb718d55e0a9ba8a1b6a12d25962ea44347/pyyaml-6.0.3-cp311-cp311-macosx_10_13_x86_64.whl", hash = "sha256:44edc647873928551a01e7a563d7452ccdebee747728c1080d881d68af7b997e", size = 185826, upload-time = "2025-09-25T21:31:58.655Z" }, + { url = "https://files.pythonhosted.org/packages/16/19/13de8e4377ed53079ee996e1ab0a9c33ec2faf808a4647b7b4c0d46dd239/pyyaml-6.0.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:652cb6edd41e718550aad172851962662ff2681490a8a711af6a4d288dd96824", size = 175577, upload-time = "2025-09-25T21:32:00.088Z" }, + { url = "https://files.pythonhosted.org/packages/0c/62/d2eb46264d4b157dae1275b573017abec435397aa59cbcdab6fc978a8af4/pyyaml-6.0.3-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:10892704fc220243f5305762e276552a0395f7beb4dbf9b14ec8fd43b57f126c", size = 775556, upload-time = "2025-09-25T21:32:01.31Z" }, + { url = "https://files.pythonhosted.org/packages/10/cb/16c3f2cf3266edd25aaa00d6c4350381c8b012ed6f5276675b9eba8d9ff4/pyyaml-6.0.3-cp311-cp311-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:850774a7879607d3a6f50d36d04f00ee69e7fc816450e5f7e58d7f17f1ae5c00", size = 882114, upload-time = "2025-09-25T21:32:03.376Z" }, + { url = "https://files.pythonhosted.org/packages/71/60/917329f640924b18ff085ab889a11c763e0b573da888e8404ff486657602/pyyaml-6.0.3-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:b8bb0864c5a28024fac8a632c443c87c5aa6f215c0b126c449ae1a150412f31d", size = 806638, upload-time = "2025-09-25T21:32:04.553Z" }, + { url = "https://files.pythonhosted.org/packages/dd/6f/529b0f316a9fd167281a6c3826b5583e6192dba792dd55e3203d3f8e655a/pyyaml-6.0.3-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:1d37d57ad971609cf3c53ba6a7e365e40660e3be0e5175fa9f2365a379d6095a", size = 767463, upload-time = "2025-09-25T21:32:06.152Z" }, + { url = "https://files.pythonhosted.org/packages/f2/6a/b627b4e0c1dd03718543519ffb2f1deea4a1e6d42fbab8021936a4d22589/pyyaml-6.0.3-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:37503bfbfc9d2c40b344d06b2199cf0e96e97957ab1c1b546fd4f87e53e5d3e4", size = 794986, upload-time = "2025-09-25T21:32:07.367Z" }, + { url = "https://files.pythonhosted.org/packages/45/91/47a6e1c42d9ee337c4839208f30d9f09caa9f720ec7582917b264defc875/pyyaml-6.0.3-cp311-cp311-win32.whl", hash = "sha256:8098f252adfa6c80ab48096053f512f2321f0b998f98150cea9bd23d83e1467b", size = 142543, upload-time = "2025-09-25T21:32:08.95Z" }, + { url = "https://files.pythonhosted.org/packages/da/e3/ea007450a105ae919a72393cb06f122f288ef60bba2dc64b26e2646fa315/pyyaml-6.0.3-cp311-cp311-win_amd64.whl", hash = "sha256:9f3bfb4965eb874431221a3ff3fdcddc7e74e3b07799e0e84ca4a0f867d449bf", size = 158763, upload-time = "2025-09-25T21:32:09.96Z" }, + { url = "https://files.pythonhosted.org/packages/d1/33/422b98d2195232ca1826284a76852ad5a86fe23e31b009c9886b2d0fb8b2/pyyaml-6.0.3-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:7f047e29dcae44602496db43be01ad42fc6f1cc0d8cd6c83d342306c32270196", size = 182063, upload-time = "2025-09-25T21:32:11.445Z" }, + { url = "https://files.pythonhosted.org/packages/89/a0/6cf41a19a1f2f3feab0e9c0b74134aa2ce6849093d5517a0c550fe37a648/pyyaml-6.0.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:fc09d0aa354569bc501d4e787133afc08552722d3ab34836a80547331bb5d4a0", size = 173973, upload-time = "2025-09-25T21:32:12.492Z" }, + { url = "https://files.pythonhosted.org/packages/ed/23/7a778b6bd0b9a8039df8b1b1d80e2e2ad78aa04171592c8a5c43a56a6af4/pyyaml-6.0.3-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:9149cad251584d5fb4981be1ecde53a1ca46c891a79788c0df828d2f166bda28", size = 775116, upload-time = "2025-09-25T21:32:13.652Z" }, + { url = "https://files.pythonhosted.org/packages/65/30/d7353c338e12baef4ecc1b09e877c1970bd3382789c159b4f89d6a70dc09/pyyaml-6.0.3-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:5fdec68f91a0c6739b380c83b951e2c72ac0197ace422360e6d5a959d8d97b2c", size = 844011, upload-time = "2025-09-25T21:32:15.21Z" }, + { url = "https://files.pythonhosted.org/packages/8b/9d/b3589d3877982d4f2329302ef98a8026e7f4443c765c46cfecc8858c6b4b/pyyaml-6.0.3-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:ba1cc08a7ccde2d2ec775841541641e4548226580ab850948cbfda66a1befcdc", size = 807870, upload-time = "2025-09-25T21:32:16.431Z" }, + { url = "https://files.pythonhosted.org/packages/05/c0/b3be26a015601b822b97d9149ff8cb5ead58c66f981e04fedf4e762f4bd4/pyyaml-6.0.3-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:8dc52c23056b9ddd46818a57b78404882310fb473d63f17b07d5c40421e47f8e", size = 761089, upload-time = "2025-09-25T21:32:17.56Z" }, + { url = "https://files.pythonhosted.org/packages/be/8e/98435a21d1d4b46590d5459a22d88128103f8da4c2d4cb8f14f2a96504e1/pyyaml-6.0.3-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:41715c910c881bc081f1e8872880d3c650acf13dfa8214bad49ed4cede7c34ea", size = 790181, upload-time = "2025-09-25T21:32:18.834Z" }, + { url = "https://files.pythonhosted.org/packages/74/93/7baea19427dcfbe1e5a372d81473250b379f04b1bd3c4c5ff825e2327202/pyyaml-6.0.3-cp312-cp312-win32.whl", hash = "sha256:96b533f0e99f6579b3d4d4995707cf36df9100d67e0c8303a0c55b27b5f99bc5", size = 137658, upload-time = "2025-09-25T21:32:20.209Z" }, + { url = "https://files.pythonhosted.org/packages/86/bf/899e81e4cce32febab4fb42bb97dcdf66bc135272882d1987881a4b519e9/pyyaml-6.0.3-cp312-cp312-win_amd64.whl", hash = "sha256:5fcd34e47f6e0b794d17de1b4ff496c00986e1c83f7ab2fb8fcfe9616ff7477b", size = 154003, upload-time = "2025-09-25T21:32:21.167Z" }, + { url = "https://files.pythonhosted.org/packages/1a/08/67bd04656199bbb51dbed1439b7f27601dfb576fb864099c7ef0c3e55531/pyyaml-6.0.3-cp312-cp312-win_arm64.whl", hash = "sha256:64386e5e707d03a7e172c0701abfb7e10f0fb753ee1d773128192742712a98fd", size = 140344, upload-time = "2025-09-25T21:32:22.617Z" }, + { 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 = "referencing" +version = "0.37.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "attrs" }, + { name = "rpds-py" }, + { name = "typing-extensions", marker = "python_full_version < '3.13'" }, +] +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.34.2" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "certifi" }, + { name = "charset-normalizer" }, + { name = "idna" }, + { name = "urllib3" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/ac/c3/e2a2b89f2d3e2179abd6d00ebd70bff6273f37fb3e0cc209f48b39d00cbf/requests-2.34.2.tar.gz", hash = "sha256:f288924cae4e29463698d6d60bc6a4da69c89185ad1e0bcc4104f584e960b9ed", size = 142856, upload-time = "2026-05-14T19:25:27.735Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/a0/f4/c67b0b3f1b9245e8d266f0f112c500d50e5b4e83cb6f3b71b6528104182a/requests-2.34.2-py3-none-any.whl", hash = "sha256:2a0d60c172f83ac6ab31e4554906c0f3b3588d37b5cb939b1c061f4907e278e0", size = 73075, upload-time = "2026-05-14T19:25:26.443Z" }, +] + +[[package]] +name = "rpds-py" +version = "2026.5.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/2e/43/25a8dcd3feedd735039a8f0b5b7e3b118232b5eae288c4fd9ab200d41094/rpds_py-2026.5.1.tar.gz", hash = "sha256:07b24fea40541e28570e5b795a4a38fbdcd12550c06bd0748005ecc8116ca256", size = 64459, upload-time = "2026-05-28T12:02:13.232Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/4f/a0/acf8b6fc20bfdcd3a45bd3f57680fb198e157b7e997b9123b10763798bd2/rpds_py-2026.5.1-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:3397a5ed7174dc2786bb214030232fc36fe8e5584fec43a9952cc542b1a12036", size = 355609, upload-time = "2026-05-28T11:58:50.78Z" }, + { url = "https://files.pythonhosted.org/packages/b6/95/f8203fd997484b1690a6869cd0e503b6c3c6be55b0ecc36d1a491fe742f0/rpds_py-2026.5.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:99ab6ba7bfa2cb0f96a04e3652355bf04e3f51aceb1e943b8541dab7ba4828cc", size = 348460, upload-time = "2026-05-28T11:58:52.374Z" }, + { url = "https://files.pythonhosted.org/packages/33/8c/b47326ad2f0be545a5e5c1a55937a12afaea7d392ba2837bb9680f57e6c9/rpds_py-2026.5.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d0efbe45632665e53e3db8fe1e5692db58fc5cb9bab4459d570b83efefe11164", size = 381031, upload-time = "2026-05-28T11:58:53.775Z" }, + { url = "https://files.pythonhosted.org/packages/22/0b/e83bbd97ffac6f6389b605cd4e1c8ac5761dc7e977769c9255d8c5adb7bd/rpds_py-2026.5.1-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:01d17b29c0c23d82b1f4751147ec49cf451f1fc2554eb9ef5f957e55d2656ead", size = 387121, upload-time = "2026-05-28T11:58:55.243Z" }, + { url = "https://files.pythonhosted.org/packages/fd/0e/d285d1bc8864245919c61e1ca82263e4a66d337759c3a4cef72766ff9afc/rpds_py-2026.5.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:7559f72b94ae52659086c595dfa017cde03155f7832071d30959049052cb3ece", size = 501026, upload-time = "2026-05-28T11:58:56.788Z" }, + { url = "https://files.pythonhosted.org/packages/86/06/ccb2109a1e543437b5e43816f2b43b9554cc6783145528a4e3711e05c011/rpds_py-2026.5.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9e25b7088f9ccbfc0dfcaa52bf969300ca229e10ecf758974ebcbb080a4b37bb", size = 391865, upload-time = "2026-05-28T11:58:58.298Z" }, + { url = "https://files.pythonhosted.org/packages/3d/33/237173db1cfef10105b3839a24de00eb8d2a523711add4632447cdf0aedd/rpds_py-2026.5.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:613fc4ee9eaef26dc5840666214dd6fbcebcf32f46e76f4abc473059f4e13dda", size = 378012, upload-time = "2026-05-28T11:58:59.589Z" }, + { url = "https://files.pythonhosted.org/packages/97/64/1eae54e34d5161f9969295e80bd6b62a55f2b6ac5f2a5b60d02c2140e758/rpds_py-2026.5.1-cp311-cp311-manylinux_2_31_riscv64.whl", hash = "sha256:85264a90ff4c05c1568dd65f5921c837614b67c60358fb4c17df3b7f2e90690a", size = 391111, upload-time = "2026-05-28T11:59:01.104Z" }, + { url = "https://files.pythonhosted.org/packages/d8/34/5bb334a5a0f65d77869217c4654f34c78a7d11b93938a3c076a2edeafc52/rpds_py-2026.5.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:fe71bca7d547acb17027c7fd1624ff8aae623499c498d3e7011182c4de5c25e0", size = 409225, upload-time = "2026-05-28T11:59:02.433Z" }, + { url = "https://files.pythonhosted.org/packages/16/0f/007ec21283b5b040b4ec3bd95e0402591e22bfa7d5c93dfe01c465c2d2d7/rpds_py-2026.5.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:a05fa4f41f37ec97c9c260441a940450a192f78d774d2b097eee1379f1e1246a", size = 556487, upload-time = "2026-05-28T11:59:04.012Z" }, + { url = "https://files.pythonhosted.org/packages/ff/10/5437c94508169b6b22d8418fef7a66e9ffb5f3b9e9c94460f2eedafe06ff/rpds_py-2026.5.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:df1d2a1996755b24b9ecee92cb4d36c28f86f464a6a173349c26bab41e94b8c2", size = 620798, upload-time = "2026-05-28T11:59:05.485Z" }, + { url = "https://files.pythonhosted.org/packages/e0/d5/9937dce4d6bda74157b954e7d1460db05a22f5929dccfeeba1ed27a93df0/rpds_py-2026.5.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:8895840ac4809e5f60c88fd07617cd71326e73d6e5a8aa783c5c0f7c24985de2", size = 584053, upload-time = "2026-05-28T11:59:06.837Z" }, + { url = "https://files.pythonhosted.org/packages/6c/31/750617dd0ae1752471bf43f9e41d263398fae7cde7849d23b8574a70e617/rpds_py-2026.5.1-cp311-cp311-win32.whl", hash = "sha256:3684a59b158a7683aaeb8e25352e9a9dd2122cec78f2d8530266e4f91b4c7b3f", size = 214390, upload-time = "2026-05-28T11:59:08.402Z" }, + { url = "https://files.pythonhosted.org/packages/3c/bb/3dcab0e1d9516303f2eb672a5d6f62eca5a69e2886301e9c8c54b520c39b/rpds_py-2026.5.1-cp311-cp311-win_amd64.whl", hash = "sha256:7bd530e6a530bb3ea892f194fafa455f3516ac25ecf7143fd33c09be62b0470a", size = 231097, upload-time = "2026-05-28T11:59:09.786Z" }, + { url = "https://files.pythonhosted.org/packages/49/d6/c6bbf5cb1cf12b9732df8074b57f6ef8341ba884c95d40632ae8bddb44e4/rpds_py-2026.5.1-cp311-cp311-win_arm64.whl", hash = "sha256:0a5ae4dbe43c1076983b72616496919872ae7bbe7a1e21cc48336bc3154d130b", size = 226361, upload-time = "2026-05-28T11:59:11.079Z" }, + { url = "https://files.pythonhosted.org/packages/d4/e7/a78582dc57caa592dcc7d4fb69b61390561e908eb3d2f5df5928a8e354c0/rpds_py-2026.5.1-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:3abe24a66e57adcfa645d718063a5fa5103ecc71ddbf26d78af8f9368018ff1d", size = 353040, upload-time = "2026-05-28T11:59:12.531Z" }, + { url = "https://files.pythonhosted.org/packages/a3/43/35e3f136343aef451e545ce8c38d36c2f93c0ed88703db8b64ba2b205c68/rpds_py-2026.5.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:58b1d94308ddf0b1982f61f2eb54bf92997c9ece8a8093ef014250f4a517906c", size = 345775, upload-time = "2026-05-28T11:59:13.827Z" }, + { url = "https://files.pythonhosted.org/packages/20/e1/0f2160c5982d3157734d5cb3ed63d8b2d583a73c9864f77b666449f32cf8/rpds_py-2026.5.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0fa92420128dadce7f54bd73ba1825a273e9268fe9e35dbf7e6362890efa4e08", size = 376329, upload-time = "2026-05-28T11:59:15.271Z" }, + { url = "https://files.pythonhosted.org/packages/d0/11/ee0ba42aff83bf4effdbc576673c6be64c5e173978c3f6d537e94482f77d/rpds_py-2026.5.1-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:ca653c6546386227cd9800d1bef6a348099acf8db4250341da6d90f663d6dfcb", size = 383539, upload-time = "2026-05-28T11:59:16.665Z" }, + { url = "https://files.pythonhosted.org/packages/11/df/d94aa6a499d4ac40afe2d7620f2c597fd3c0f182e854ad7cf3f596a81cb6/rpds_py-2026.5.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:66c93681c4729e4e3ecba31b8179fae083ff3118841672835140338b4b9867c1", size = 494674, upload-time = "2026-05-28T11:59:17.991Z" }, + { url = "https://files.pythonhosted.org/packages/1f/75/33d30f43bb2f458de11979486a591b1bf6e5651765ed1704c6197c2dc773/rpds_py-2026.5.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:40ff257542e04796880e011e15cd4dc21c2599975df2aaa8f2c8495ca574e1a5", size = 389268, upload-time = "2026-05-28T11:59:19.434Z" }, + { url = "https://files.pythonhosted.org/packages/f4/1e/2c9096fc19d5fd084b0184ca2b651e659aa0a37e6fdbecf6ece47f147fe1/rpds_py-2026.5.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b6825cc329b290e93c5f6a9be2393118a763f6ccf6abd83704e0c102ca583644", size = 376280, upload-time = "2026-05-28T11:59:21Z" }, + { url = "https://files.pythonhosted.org/packages/b9/e5/61ec9f8be8211ea7f48448195549e4aaf02004083475493b0e137702ecb2/rpds_py-2026.5.1-cp312-cp312-manylinux_2_31_riscv64.whl", hash = "sha256:de42116e69cb53b911cc34aee5ab98f36c597b822545045d49e938818b99e5e4", size = 387233, upload-time = "2026-05-28T11:59:22.454Z" }, + { url = "https://files.pythonhosted.org/packages/0d/ca/bcec1005c4f4a234f92a29078631fee49206c7265ccae966f18fd332e80e/rpds_py-2026.5.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:c0f920015df2a504bebaba6d4c31ccf3fcf942f92655c086da30b671aad19aa6", size = 405009, upload-time = "2026-05-28T11:59:23.845Z" }, + { url = "https://files.pythonhosted.org/packages/72/e6/4d5718c5cf26c522dc7c9999e238da1e77380b81d0c5d1df11e271ddfeb1/rpds_py-2026.5.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:0408a24e44feb919423dc6d9da677cb5cddb894d2ca9e763967d156d9c60fab4", size = 553113, upload-time = "2026-05-28T11:59:25.184Z" }, + { url = "https://files.pythonhosted.org/packages/d4/25/2ee807bdb3e1f0b7eddf7782acd5665a8b5205a331a7d7244a52c4812fd9/rpds_py-2026.5.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:cea68bcd53467561ae2f96a6bdad1544299ba97b5b0ddcd5ac3d376e5c781c24", size = 618838, upload-time = "2026-05-28T11:59:26.749Z" }, + { url = "https://files.pythonhosted.org/packages/6a/c1/7d4c26f167f8c41501cc073d30ee22082b16ce358cf5b00ec97cbc7804ea/rpds_py-2026.5.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:4be8b1d2a705cc37d08256004e1d07de143fa0075c8e85a3df020b776f62b732", size = 582436, upload-time = "2026-05-28T11:59:28.11Z" }, + { url = "https://files.pythonhosted.org/packages/04/1d/9d12b0a337bab46f4769f8857f4007e3b2d639e14f9a44a0efe157696e64/rpds_py-2026.5.1-cp312-cp312-win32.whl", hash = "sha256:6736718bd4fc49cbcb538ba30516fdbef161522acefb739657d48b97bd864fed", size = 212734, upload-time = "2026-05-28T11:59:29.689Z" }, + { url = "https://files.pythonhosted.org/packages/c5/93/e4116f2de7f56bc7406a76033dc501811ddeb22b7f056b92d632871ebb0c/rpds_py-2026.5.1-cp312-cp312-win_amd64.whl", hash = "sha256:0a7d1eec967df0e9b22614a5e177622e0c89611d03727fa0cb48e45028907870", size = 229045, upload-time = "2026-05-28T11:59:31.033Z" }, + { url = "https://files.pythonhosted.org/packages/cb/53/6c3419d85eb2ec5938a37627c585b42d76a63bb731d6e42ed4b079ebf486/rpds_py-2026.5.1-cp312-cp312-win_arm64.whl", hash = "sha256:1841d067089e117142d79b98aa0df2f08b52f2ecc1819dd2700636c0db74a473", size = 223967, upload-time = "2026-05-28T11:59:32.318Z" }, + { url = "https://files.pythonhosted.org/packages/6c/32/14c961ad295f490eb0849ada8b79683e93a59b9de3afdd983eaf55fa6867/rpds_py-2026.5.1-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:efef4ac29c6ff495531eb17ee705b62841ecaa291b7c7077e848ea03e237164d", size = 352787, upload-time = "2026-05-28T11:59:33.655Z" }, + { url = "https://files.pythonhosted.org/packages/ca/bb/d1b85117967c11191441a7274ae616c65d93901d082c588f89a50a8da5ae/rpds_py-2026.5.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:c39f5b67a8a2e67179ada2a954227d670fe65fa9098457f698f56ddf248709b3", size = 345179, upload-time = "2026-05-28T11:59:35Z" }, + { url = "https://files.pythonhosted.org/packages/7c/46/d84105f062e626a1b233f863907288a4708c2d833b8b4c6fb2764bc080c0/rpds_py-2026.5.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b5c30f3f04eef4fbd362226a6f31d7c8895ca4fbb6e0b790f6890a98d8da8559", size = 376173, upload-time = "2026-05-28T11:59:36.43Z" }, + { url = "https://files.pythonhosted.org/packages/e2/ae/469d7959ce5b1201e1de135dc735b86db3b35dd0d1734f6a44246d5f061c/rpds_py-2026.5.1-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:277f6c82f0580848796c7ecc8a7173aa3bfb928e4ff831261c2f60a81dc270db", size = 383162, upload-time = "2026-05-28T11:59:37.995Z" }, + { url = "https://files.pythonhosted.org/packages/dc/a2/57853d31a1116a561aa072794602ad3f6341e18d70a8523f1bd5b9fc1e5a/rpds_py-2026.5.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:63c2c4c213f1a4e3f3de28ecab029dbdee976324e729c0d7a55211be72576b02", size = 495093, upload-time = "2026-05-28T11:59:39.453Z" }, + { url = "https://files.pythonhosted.org/packages/99/63/3a8eabcad9314b7daf5c65f451d2c33d989235cd8a5762186cf2c3f5a4f8/rpds_py-2026.5.1-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3350ec808fb538fe71a1f94dfaa0e29c598dfad805ce49f0caec5ae3183c652b", size = 389829, upload-time = "2026-05-28T11:59:40.896Z" }, + { url = "https://files.pythonhosted.org/packages/4b/25/05678d97fc25e2622df14dc530fb82023174ecfff6733991ed0d78f167bd/rpds_py-2026.5.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b1b964e3ab599e718dc46c018d104b1ebc007cbc6567d827c94a687fca56d77e", size = 374786, upload-time = "2026-05-28T11:59:42.626Z" }, + { url = "https://files.pythonhosted.org/packages/88/d1/8c90b6431e80a3b91b284a5c7c8c0c4f9c006444d90477a740d6e0f9c694/rpds_py-2026.5.1-cp313-cp313-manylinux_2_31_riscv64.whl", hash = "sha256:19cb09fab7b7fc96b2a6e28f2e34b72a3705ff27b37edb77455316e5d3f3dc9b", size = 386920, upload-time = "2026-05-28T11:59:44.124Z" }, + { url = "https://files.pythonhosted.org/packages/ff/99/4638f672ab356682d633ee0da9255f5b67ce6efd0b85eb94ad3e255e65a5/rpds_py-2026.5.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:abe76bcdba31e576cb83eeb8797aa0d882b738fef6dc65d0601fc753806a5b46", size = 405059, upload-time = "2026-05-28T11:59:47.177Z" }, + { url = "https://files.pythonhosted.org/packages/66/3f/3546524b6eb4cc2e1f363a3d638fa52f6c24faae3500c25fb488b02f1740/rpds_py-2026.5.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:8bff7073db3899158fff55ebf57b113a67030af26f80a18978f9f0aa60250ddf", size = 553030, upload-time = "2026-05-28T11:59:48.603Z" }, + { url = "https://files.pythonhosted.org/packages/c6/c3/7b3388c796fcf471bd17194242d4dc1a7608567c0fa422bcc1c5e79f9c1e/rpds_py-2026.5.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:8ba264fa49be666cd9cc56bf34ec7002fb3d27a4aee5bcb4d43d0d18feb1bb6f", size = 618975, upload-time = "2026-05-28T11:59:50.314Z" }, + { url = "https://files.pythonhosted.org/packages/61/1e/a3cb07f2795075d1d88efddae2f541359fde5f08c81ee114c29c2949c90a/rpds_py-2026.5.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:4860b603ddda0475a8885499b3729e90229d480105b42651962a5397d995fa89", size = 581178, upload-time = "2026-05-28T11:59:51.673Z" }, + { url = "https://files.pythonhosted.org/packages/a1/74/e758c03a5ef46f04c37f2651a2893db846d569ba8a7bca469d4b58939bcd/rpds_py-2026.5.1-cp313-cp313-win32.whl", hash = "sha256:7944270ae71383f6e2657dd7d5ce4eeb4ac2d0059a6738f0510583d462ab4842", size = 212481, upload-time = "2026-05-28T11:59:53.148Z" }, + { url = "https://files.pythonhosted.org/packages/70/ec/a2aca432db9c7359b40fa393eeeaa0d166c2f70175be956e75fa24197c44/rpds_py-2026.5.1-cp313-cp313-win_amd64.whl", hash = "sha256:88647f43a73c4e01be19b04ceef0c8d3a1958153604d13c773becd8016f2a0cf", size = 228519, upload-time = "2026-05-28T11:59:54.505Z" }, + { url = "https://files.pythonhosted.org/packages/29/60/a73bfdd45b096574556acf303bbd9fa9eed36ca8a818b514e2a5d5fe2b9d/rpds_py-2026.5.1-cp313-cp313-win_arm64.whl", hash = "sha256:453895624ecf7db7063b1004e44037522bbaef9ff6a945e59bc71662d7a03abd", size = 223446, upload-time = "2026-05-28T11:59:56.081Z" }, + { url = "https://files.pythonhosted.org/packages/18/e2/408105fd611823f00882aea810f3989a30d26b1bab8b6beb20f98c724e0e/rpds_py-2026.5.1-cp313-cp313t-macosx_10_12_x86_64.whl", hash = "sha256:b4e4bc98639ec915f512fde3aa7a95e0041d95d9c3cc86eea841fa63cb1e8600", size = 355287, upload-time = "2026-05-28T11:59:57.448Z" }, + { url = "https://files.pythonhosted.org/packages/8d/58/5c4a43436843c90d0f6d19f82c200c80e3843ca9fa07b237623327f6d384/rpds_py-2026.5.1-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:cacedb7a6e167680acba45ad5716e89067d225dc80da0d7040cae8c81d4572fa", size = 347033, upload-time = "2026-05-28T11:59:58.881Z" }, + { url = "https://files.pythonhosted.org/packages/fb/c2/1a71acdacaf4e259b10278fb87b039ded3cf80041bcd89dd8a3ea702ded6/rpds_py-2026.5.1-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:68700371c5d7ae1412862ddfa719090925c93ecf351c566d66f09d04b136ea00", size = 376891, upload-time = "2026-05-28T12:00:00.516Z" }, + { url = "https://files.pythonhosted.org/packages/c2/c8/535f3d9b65addd8e28aa87b83c6e526799c3717a88273db8ea795beeef7a/rpds_py-2026.5.1-cp313-cp313t-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:296c799becfa849c779c8725494fe9ed94959ed886787df4364b058465bad7f0", size = 385646, upload-time = "2026-05-28T12:00:02.394Z" }, + { url = "https://files.pythonhosted.org/packages/1c/91/dc033f313345c354ade914dbe73cdb90b615a4409ea02430d5356794f3d8/rpds_py-2026.5.1-cp313-cp313t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d3858b908218ee108d0bbfb2095ccc237648053c9bf98affad7cb079acaf1d97", size = 498830, upload-time = "2026-05-28T12:00:04.189Z" }, + { url = "https://files.pythonhosted.org/packages/27/fc/90fcbea459dbb8ddc18a2e0fd1de9412b48bc84ffff2db771cf714bacfd6/rpds_py-2026.5.1-cp313-cp313t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:4fb8d2e7cb2f850b169806d61d1b991738acec96500a75c30f49caf064ce7cef", size = 392830, upload-time = "2026-05-28T12:00:05.797Z" }, + { url = "https://files.pythonhosted.org/packages/b2/1d/46cd11a228c9750684a798d98f878be6f614aa762438da7378f035e79e35/rpds_py-2026.5.1-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:27b74c10ed6a8f190f4287f53bcfea348b92a84a9c9f70d30183d1e6172d580d", size = 379613, upload-time = "2026-05-28T12:00:07.433Z" }, + { url = "https://files.pythonhosted.org/packages/24/4a/d9b0c6af3a1de03eb93741bbe8be2bdce84d8fda8224f3005451d86df389/rpds_py-2026.5.1-cp313-cp313t-manylinux_2_31_riscv64.whl", hash = "sha256:b9a6528956191c48c52294a592dbd4a8386d7048bdb25c0efcb6b966466c6d83", size = 388183, upload-time = "2026-05-28T12:00:09.227Z" }, + { url = "https://files.pythonhosted.org/packages/c5/b4/db7aaabdda6d020afc87d981bcc2f57a434c7dec60ecfc2ab3dd50b20351/rpds_py-2026.5.1-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:af03e34e860047bc7a352b842856fcf78798fbb81132cc98bd2f907ab4eb9cd2", size = 408578, upload-time = "2026-05-28T12:00:10.779Z" }, + { url = "https://files.pythonhosted.org/packages/08/d6/070f6a41cbb343e2ac4171859bf3f3623e0ab002f72619d6d505313ec2de/rpds_py-2026.5.1-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:fea6e836d10abbe191d557d33bd58bd5987725fe63aa1eefe557d230209855bd", size = 553573, upload-time = "2026-05-28T12:00:12.443Z" }, + { url = "https://files.pythonhosted.org/packages/75/ab/1a71ea3589c4345dac0a0518f0e6a031cb42689277851b683c46d27463a5/rpds_py-2026.5.1-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:fc0c0f878ea770a0a8a462456c5ad36fc9fe6358e6b76fdadc7f17575e0b8bf1", size = 620861, upload-time = "2026-05-28T12:00:14.09Z" }, + { url = "https://files.pythonhosted.org/packages/8a/22/9bf80a56069c0c443fcfefac639a86a744550a2898817a6dfd3e26654924/rpds_py-2026.5.1-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:e0b360f316d966b048b085857630b3cc51f3db2f07b06f440eac8f695374d1e3", size = 585633, upload-time = "2026-05-28T12:00:15.66Z" }, + { url = "https://files.pythonhosted.org/packages/da/68/3b2c0a75c9e04125696f84ebdbbf304acf5a40b58ba4481cdb98a922c3ba/rpds_py-2026.5.1-cp313-cp313t-win32.whl", hash = "sha256:a2999883eedf72fdfb7520b92c7d4ec2572a71ff40239377aa604cc529eecafc", size = 210074, upload-time = "2026-05-28T12:00:17.291Z" }, + { url = "https://files.pythonhosted.org/packages/e7/8b/609157d5a25d37d4f29f92840ba531f416907c34ae5c5739dd21fc2bef98/rpds_py-2026.5.1-cp313-cp313t-win_amd64.whl", hash = "sha256:e07be2a9d7122bd6e82dea89814ef8dc893feb1aae97fec1630f3263bbb30e55", size = 228635, upload-time = "2026-05-28T12:00:18.73Z" }, + { url = "https://files.pythonhosted.org/packages/d4/6f/19c1918a4b590d8de87e712e4abe4b3875771eff60216fb6153cf6665c68/rpds_py-2026.5.1-cp314-cp314-macosx_10_12_x86_64.whl", hash = "sha256:1f2c391c3059798093b65df23aca2cac150460ae9c630d99dec83d703d9485b9", size = 349756, upload-time = "2026-05-28T12:00:20.217Z" }, + { url = "https://files.pythonhosted.org/packages/e5/60/a06fe7da34eca79dacbf958a2ba0c6eea85bc2b29de20080bf40f72f66fa/rpds_py-2026.5.1-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:413b424f7c4ee65ab5e5be91f5731be0f8b41a1ee2b12dfe810d716312e95a78", size = 343831, upload-time = "2026-05-28T12:00:21.711Z" }, + { url = "https://files.pythonhosted.org/packages/bf/ec/b2333b97b90e2a6ef6ca8ad386ee284968e74bcfe113b3f1a8d9036429a9/rpds_py-2026.5.1-cp314-cp314-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2c595a1d9255dce0599e13130d1440ab2506654f2b50294226ee06402f8fef63", size = 375127, upload-time = "2026-05-28T12:00:23.326Z" }, + { url = "https://files.pythonhosted.org/packages/14/7f/e00aae54067f2b488c4637961d5f58204d470795fc791085fa3f15060d2e/rpds_py-2026.5.1-cp314-cp314-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:1c27c5f6102eac8c03e7595a00827a53b271ba40a53b59ff8709170e0855ea4a", size = 379034, upload-time = "2026-05-28T12:00:24.89Z" }, + { url = "https://files.pythonhosted.org/packages/be/cc/423999bbb8ae8dc93c77fc1d5e984ade5eb89d237d3bb884ccfa72ae2890/rpds_py-2026.5.1-cp314-cp314-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:6c7fcf61d44cacecaf3aea542b0e053db77972a4573e7ceda16fb2b399161195", size = 490823, upload-time = "2026-05-28T12:00:26.676Z" }, + { url = "https://files.pythonhosted.org/packages/0f/aa/c671bf660f12e68d3c52ff86c7066ed1372df5a0f4f2ff584e419b8207e7/rpds_py-2026.5.1-cp314-cp314-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2c817a189d4ee14290420e5ff051e4dd6baa13f3edf84685071dee07a6d538ee", size = 388144, upload-time = "2026-05-28T12:00:28.577Z" }, + { url = "https://files.pythonhosted.org/packages/19/c8/d63bb75b68afe77b229e3021c6031bcaf01da5db5b0e69d0d10f9ba679a7/rpds_py-2026.5.1-cp314-cp314-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:21846aac0ed2e0589f38c12dc44e77bb64e494b771eadbcf169cba00566ba7ba", size = 371959, upload-time = "2026-05-28T12:00:30.304Z" }, + { url = "https://files.pythonhosted.org/packages/82/35/c51122014d8274ff37dc606d60049c3db7d83da02b5b282511e5a906a9a6/rpds_py-2026.5.1-cp314-cp314-manylinux_2_31_riscv64.whl", hash = "sha256:b317c87a13f769a4e787819bd508aaa5d69aa09b0880de9af6d3a8a54571cdec", size = 383558, upload-time = "2026-05-28T12:00:31.764Z" }, + { url = "https://files.pythonhosted.org/packages/e3/f9/2790cb99c136a5363acdeacf5c27c56f3de0d4118a1f48fca83404c99c89/rpds_py-2026.5.1-cp314-cp314-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:ce87129d9f2c14fa6c4a8601fb80eb4488c80d38a20cd13758ef11123e14995d", size = 402789, upload-time = "2026-05-28T12:00:33.247Z" }, + { url = "https://files.pythonhosted.org/packages/e5/1b/e4fb584f8c75d35c38150ff6a332cda949e6f97acba1f4fd123b14ab56fe/rpds_py-2026.5.1-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:9cdddb6c1207d284d94fd1530adf57fbd797fe7c4b8704ba85f49414f2557e7d", size = 551405, upload-time = "2026-05-28T12:00:34.819Z" }, + { url = "https://files.pythonhosted.org/packages/d8/f7/a6731b4216cb3793ea1af5391da240f5683dacc0d13e034fe5fc3503f240/rpds_py-2026.5.1-cp314-cp314-musllinux_1_2_i686.whl", hash = "sha256:4e237e139f94d3c036fd28eb9f564c99055476ff4ff05cd42be55ce349b5aa02", size = 616975, upload-time = "2026-05-28T12:00:36.268Z" }, + { url = "https://files.pythonhosted.org/packages/2c/ea/2e051a81d95d8e63f4b35a1c463a87e8766bc3d083c067c5dfb6bf220747/rpds_py-2026.5.1-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:ed0954b524873214369184a9c82b0eaa45a3fbb9a798cd95b17e0d98499e7ea0", size = 578701, upload-time = "2026-05-28T12:00:37.82Z" }, + { url = "https://files.pythonhosted.org/packages/65/56/b5f6fdb2083e32bca8a8993d89e70db114b4756c9e2c38421328126689d2/rpds_py-2026.5.1-cp314-cp314-win32.whl", hash = "sha256:2d88621d6a7d4dfa633d21abe90f280bb205274e16b1d1e61c6ad4640b2453b7", size = 209806, upload-time = "2026-05-28T12:00:39.492Z" }, + { url = "https://files.pythonhosted.org/packages/fb/80/65a5aa96c155e611d1ed844e4e1f57f3e36b021f396d9f8585d756e6b90d/rpds_py-2026.5.1-cp314-cp314-win_amd64.whl", hash = "sha256:cef8ac28d26f4dda3533060c20fbf80a325458fa9fd23ea72a73cdfa8e978838", size = 225985, upload-time = "2026-05-28T12:00:40.94Z" }, + { url = "https://files.pythonhosted.org/packages/27/7c/ad185212e87b05f196daef92bc5f3caf07298eb47c295b5585c3dd3093ac/rpds_py-2026.5.1-cp314-cp314-win_arm64.whl", hash = "sha256:eaaea962c68cdc68d4a533ba985ab8e9484277910bbfaa2ab3ef7732667bfed8", size = 221219, upload-time = "2026-05-28T12:00:43.15Z" }, + { url = "https://files.pythonhosted.org/packages/23/58/e14ae18759020334646b031e708ab4158d653a938822bfb7b95ef2e93aa3/rpds_py-2026.5.1-cp314-cp314t-macosx_10_12_x86_64.whl", hash = "sha256:21942f52dbbd5f8758bf021213d28bd45c39e873e65e2407faf5f1846f5761ad", size = 352148, upload-time = "2026-05-28T12:00:44.638Z" }, + { url = "https://files.pythonhosted.org/packages/31/9b/5f4a1e2f960bca3ac5d052b139dd31eed97b259f9d909173821760d542e8/rpds_py-2026.5.1-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:f414556f6e3958300ff941e40c9f97e3dc9774ddd1b3434c475d73dd354bbed3", size = 345196, upload-time = "2026-05-28T12:00:46.14Z" }, + { url = "https://files.pythonhosted.org/packages/1a/71/1d9574d6a2fa20ab60eaa55c7467f5aa20cbc770f341a05f09c0876f59e2/rpds_py-2026.5.1-cp314-cp314t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ef1013a8625c74043210190b246f5b1551e09757c1f356c6e4160ef96c5bc081", size = 374981, upload-time = "2026-05-28T12:00:47.531Z" }, + { url = "https://files.pythonhosted.org/packages/0c/9a/37e99f4915a80aa71670263c1267f7ae0af95f53a3f61e6c3bdc016d4515/rpds_py-2026.5.1-cp314-cp314t-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:cc68e231a77a5f0d774ae278a1f8e55c0456501820847c1e4efb3829f3441df6", size = 379961, upload-time = "2026-05-28T12:00:49.216Z" }, + { url = "https://files.pythonhosted.org/packages/a8/ff/6e73f74b89d2e0715e0fc86b7dde893f9a61ae2f9b256ff3bdfe41ac4e94/rpds_py-2026.5.1-cp314-cp314t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9baffb505aff33acc69b422a19f77806680f3c8632227d79f48de8a810d1c2c5", size = 495965, upload-time = "2026-05-28T12:00:51.111Z" }, + { url = "https://files.pythonhosted.org/packages/ea/e0/425faba25f59d74d4638b267f7c7a80e8649d2ef4db10a19b0c4a71e6e6f/rpds_py-2026.5.1-cp314-cp314t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b8d2f912928d426e8cfa396f7f3f8d29a59e6689c86dcca3c420730c1096322b", size = 389526, upload-time = "2026-05-28T12:00:52.77Z" }, + { url = "https://files.pythonhosted.org/packages/c6/76/7a41960e3fddae47fab43a28684d5da981401dffd88253de0944148654cb/rpds_py-2026.5.1-cp314-cp314t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:90f628283be835db980c941767d41c9a27b5239e54ba0a9c1335247e82406964", size = 376190, upload-time = "2026-05-28T12:00:54.215Z" }, + { url = "https://files.pythonhosted.org/packages/27/60/5f38dc70824fc6951b51d35377e577a3a3a4c81a6769cc5a2de25ebe0ad1/rpds_py-2026.5.1-cp314-cp314t-manylinux_2_31_riscv64.whl", hash = "sha256:1ebb2f0ab7e16132995a72de805170e0203df0c3dd22e1ef1cd1fdd90bd7a131", size = 383921, upload-time = "2026-05-28T12:00:55.673Z" }, + { url = "https://files.pythonhosted.org/packages/60/1a/d60a38caa1505f4b9483c3fbbde12c94e1079154f4f401a6da96f7e77621/rpds_py-2026.5.1-cp314-cp314t-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:f3df3d16ded76f1f8c9cdebd0e1ea55fdf4c23b812de189814da7cf229c22a81", size = 404766, upload-time = "2026-05-28T12:00:57.518Z" }, + { url = "https://files.pythonhosted.org/packages/87/ff/602fd3f174d6425f0bce05ad0dfbec0e96b38d0f7d08a79af5aa20083885/rpds_py-2026.5.1-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:9af8905b8f854990e40d5206aa5ac58d9b0fe0b7f351ff2bb086c20f6c8c6a47", size = 551343, upload-time = "2026-05-28T12:00:58.978Z" }, + { url = "https://files.pythonhosted.org/packages/b8/c1/1be13327acdbead3eca1fde03b6a34dbb011f1e864e217f0d32cc1779a7f/rpds_py-2026.5.1-cp314-cp314t-musllinux_1_2_i686.whl", hash = "sha256:036a36a87fb1cd3b214d11c4b3c4f7d2ddad933625dca1c900b56a057c07740a", size = 618502, upload-time = "2026-05-28T12:01:00.656Z" }, + { url = "https://files.pythonhosted.org/packages/f3/d7/afb49b49d7f2be8b7ba1a9f0977fa5168003437b93086726f066544e8351/rpds_py-2026.5.1-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:62ae3853454fe9ef283a03c96c2d835d39e84b14643a9d62c82ef0fb87d702ca", size = 581916, upload-time = "2026-05-28T12:01:02.22Z" }, + { url = "https://files.pythonhosted.org/packages/25/d1/dbef8c1f8a10f07beb62b5f054e20099fd9924b3ec001b8f0b6ac7813a85/rpds_py-2026.5.1-cp314-cp314t-win32.whl", hash = "sha256:6c3d771a46ec18b12af06ce36243a9a80b07a5d0515236332d90863ca8bb326a", size = 207855, upload-time = "2026-05-28T12:01:03.821Z" }, + { url = "https://files.pythonhosted.org/packages/2a/72/bfa4e61ab8e7dc1c8adf397e05e6cbdd4239357bd72b248d3de662f23915/rpds_py-2026.5.1-cp314-cp314t-win_amd64.whl", hash = "sha256:c93c629be4636cf54337bd5f06c104d55e42ced54d681f6fe21ae510a65116f6", size = 225422, upload-time = "2026-05-28T12:01:05.194Z" }, + { url = "https://files.pythonhosted.org/packages/27/3a/7b5da92b640f67b6717ccafc83cdd06bfa7ff2395c3685c68922bb54d703/rpds_py-2026.5.1-cp315-cp315-macosx_10_12_x86_64.whl", hash = "sha256:3574b55c604b8f75dacb007136508bbc0db406e626301778096a133327e7f2fb", size = 349576, upload-time = "2026-05-28T12:01:06.722Z" }, + { url = "https://files.pythonhosted.org/packages/d7/8a/2aafd7ad355a1bd48ca76e2262b74b15e6432b5a1efe150efd4d779cd55d/rpds_py-2026.5.1-cp315-cp315-macosx_11_0_arm64.whl", hash = "sha256:94068eb3ae6d43f5a786b7db96a406a34e6d5c24489feef32fd6e8946ea7b291", size = 343640, upload-time = "2026-05-28T12:01:08.441Z" }, + { url = "https://files.pythonhosted.org/packages/f7/7d/6c9523c1abbe840a1b7fba3c516d48e1d3487cc80fea4366c4071cf56784/rpds_py-2026.5.1-cp315-cp315-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f3a5b10e8ce894825f380a8f1b6444cf73c294dfea62afbb2d13e3a9e630cec1", size = 375322, upload-time = "2026-05-28T12:01:09.934Z" }, + { url = "https://files.pythonhosted.org/packages/5a/5d/0b7b03fb1dc509321f01de3149784ab773e34c8573022029af8076afcb9c/rpds_py-2026.5.1-cp315-cp315-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:fc09f82e63d4bcd58149572f857a431bae851dc747e313c3b5bdf7abb907fda8", size = 379066, upload-time = "2026-05-28T12:01:11.48Z" }, + { url = "https://files.pythonhosted.org/packages/d7/e2/8ef6012999ebf1cb1c22f876d9ce5e63d960fd4631d2af3202d3f480aa25/rpds_py-2026.5.1-cp315-cp315-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e10464d17df3b582745c25cec695cb9558bca2cb6ddb631aee1787fc72c767b2", size = 494586, upload-time = "2026-05-28T12:01:13.051Z" }, + { url = "https://files.pythonhosted.org/packages/80/af/1eeb029bec67582c226b7809172207cd005073af4ebd906e65ff494f4983/rpds_py-2026.5.1-cp315-cp315-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:ba05adbf15d994c38ec0b7ab32e858e5110c21e9009a00a86545fd220f84e038", size = 388415, upload-time = "2026-05-28T12:01:14.631Z" }, + { url = "https://files.pythonhosted.org/packages/18/23/ffbe10711c4d766c1cab0557d6906c074f795814863c67b351355d29354a/rpds_py-2026.5.1-cp315-cp315-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:77c004fdc7b891967106f78ddfd7b076bfe6813c6139c6fff6aed3bcaa960b26", size = 372427, upload-time = "2026-05-28T12:01:16.153Z" }, + { url = "https://files.pythonhosted.org/packages/bd/3a/30ba4a6ad457e5b070c18d742a33fb77d8d922b565cc881f8a5313d63bfe/rpds_py-2026.5.1-cp315-cp315-manylinux_2_31_riscv64.whl", hash = "sha256:83bcf894486c9d78dd290d3c0124ff6dd8875d3025e2090a8ec49fcc37c55fdd", size = 383615, upload-time = "2026-05-28T12:01:17.809Z" }, + { url = "https://files.pythonhosted.org/packages/d3/69/62e242b53ce39c0814bd24e1a6e6eba6c92be716277745f317f9540a2e7b/rpds_py-2026.5.1-cp315-cp315-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:c3df104083952a0e0c6f10de33e440eabe98fb6317d23e1a58c68f6df08d01b9", size = 402786, upload-time = "2026-05-28T12:01:19.419Z" }, + { url = "https://files.pythonhosted.org/packages/38/c1/a770b9c186928a1ed0f7e6d7ae50e7f3950ed23e3f9e366dbc8e38cb55de/rpds_py-2026.5.1-cp315-cp315-musllinux_1_2_aarch64.whl", hash = "sha256:980450826cf22e133c57e0835070bdd0dd3f73b9b708c3ce223def2cb9469e14", size = 551583, upload-time = "2026-05-28T12:01:21.013Z" }, + { url = "https://files.pythonhosted.org/packages/21/7c/68e8579b95375b70d2a963103c42e705856cdb98569258bd807f4423891c/rpds_py-2026.5.1-cp315-cp315-musllinux_1_2_i686.whl", hash = "sha256:205dde846f24332ab0c1188699a043b8d165b79bb84529ce272c45048ff6be01", size = 616941, upload-time = "2026-05-28T12:01:22.548Z" }, + { url = "https://files.pythonhosted.org/packages/70/a1/a6135aed5730ff03ab957182259987ac11e55fb392a28dc6f0592048a280/rpds_py-2026.5.1-cp315-cp315-musllinux_1_2_x86_64.whl", hash = "sha256:3966b82dd563176396df030f3dd52a6e54cb69b718e95e78bd555ed3d1e0185d", size = 578349, upload-time = "2026-05-28T12:01:24.118Z" }, + { url = "https://files.pythonhosted.org/packages/09/6e/f24201a76a84e6c49d0bdfdfcb735210e21701e9b21c5bfc0ba497dd62f6/rpds_py-2026.5.1-cp315-cp315-win32.whl", hash = "sha256:7818f8d0a415be74d2be3590b0a1c1f463a642f4d0217e7d10602dceef5b79aa", size = 209922, upload-time = "2026-05-28T12:01:25.522Z" }, + { url = "https://files.pythonhosted.org/packages/9e/e4/966bc240bb0485fc265278f6de44d05834bf0b3618886e0b22e33d54c49a/rpds_py-2026.5.1-cp315-cp315-win_amd64.whl", hash = "sha256:b3cc20c0d800af78fd0fac68086e28c1856cec51ea528bb81ea851aa40d39325", size = 226003, upload-time = "2026-05-28T12:01:27.062Z" }, + { url = "https://files.pythonhosted.org/packages/5c/5c/a15a59269cd5e74472734516c73795c15eccfc841b3d4b0228c3f53f19d0/rpds_py-2026.5.1-cp315-cp315-win_arm64.whl", hash = "sha256:3609e9939a8a76cd904cf98a3f1f13b5dc7e150adeaee89e0ea09652ea213e16", size = 221245, upload-time = "2026-05-28T12:01:28.51Z" }, + { url = "https://files.pythonhosted.org/packages/e0/22/135ce03804e179a71ceb13be095deda4a279bc88f7a6b8fa161c5ad44e12/rpds_py-2026.5.1-cp315-cp315t-macosx_10_12_x86_64.whl", hash = "sha256:5d333a7127d4b307601ac37792bee01bb95c867cbfacf21b6375b804d6bbd723", size = 352015, upload-time = "2026-05-28T12:01:30.214Z" }, + { url = "https://files.pythonhosted.org/packages/3b/5f/f1f6d2652eb9d848f6eb369d8db83a2da6249bb49ad2c2a48f45d54538d3/rpds_py-2026.5.1-cp315-cp315t-macosx_11_0_arm64.whl", hash = "sha256:b5f077b44a4f7808520f66dae234988d867deb9aed9be5da057ce9ba831b2a41", size = 345016, upload-time = "2026-05-28T12:01:31.656Z" }, + { url = "https://files.pythonhosted.org/packages/88/66/b74182775691ea2290c99e52ac8d5db844e56fbec90ce421f107658c8314/rpds_py-2026.5.1-cp315-cp315t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:55d8f9b7b78c9538fc9e04e82ec0e888ff0c3cffcfad152c77e57cd09351a98a", size = 374775, upload-time = "2026-05-28T12:01:33.136Z" }, + { url = "https://files.pythonhosted.org/packages/ff/8f/15e5a61d9f0a43902d36561d4f07cae6ae9f4716be825159fd72717f33af/rpds_py-2026.5.1-cp315-cp315t-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:e3a8ae58895ac107ed934a6bf51e5846f95c53b9b940c2c6d310838fd5846358", size = 380270, upload-time = "2026-05-28T12:01:34.574Z" }, + { url = "https://files.pythonhosted.org/packages/02/c3/f859b12763a80540cdf2af0f15b19904cf756a71d7bdd3f82ff3e5b1bbf9/rpds_py-2026.5.1-cp315-cp315t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:0957cf3c2b8632ec7aaebffebea8005b353cc2a237b6e2ae3c2cac0820704cfb", size = 495285, upload-time = "2026-05-28T12:01:36.127Z" }, + { url = "https://files.pythonhosted.org/packages/1c/c7/ff27c2ac8411d30b03b1829fd88cae8dad1a4d0da48dd25e57c4038042e6/rpds_py-2026.5.1-cp315-cp315t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c396c1304de421050b3681ea70f371874b54d41b0151e96109758144c231e30b", size = 389581, upload-time = "2026-05-28T12:01:37.635Z" }, + { url = "https://files.pythonhosted.org/packages/6e/67/fe92ee32a6cc05c77228a2f8b1762e7124f386ec20ff83d0757b762d58d0/rpds_py-2026.5.1-cp315-cp315t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:aad1bff7f666b9598e573815affd666aac6a13a585dde336f843e33350c7fadc", size = 376041, upload-time = "2026-05-28T12:01:39.307Z" }, + { url = "https://files.pythonhosted.org/packages/f8/91/b4d6685c27aba55bd82f25b278be8237038117d05f9659a6213ad3408130/rpds_py-2026.5.1-cp315-cp315t-manylinux_2_31_riscv64.whl", hash = "sha256:656a042550878f12d45752452d47094b7cfe5ad1e9d7b87b5a22ad3ae5ff8015", size = 383946, upload-time = "2026-05-28T12:01:41.043Z" }, + { url = "https://files.pythonhosted.org/packages/bd/79/2c1d832a53c8e0f8e98fc970ec257b950fecd4f62be2ab7182b500a0cbc8/rpds_py-2026.5.1-cp315-cp315t-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:73c4bd4f70294737b5206a3e8e30ccadbf8a60301831c8ea23eec5dbeea1ecfa", size = 405526, upload-time = "2026-05-28T12:01:43.032Z" }, + { url = "https://files.pythonhosted.org/packages/78/c4/c98117b03c6a8581ab2c2dfccfe9a5ad82bd8128a3c28b46a6ad2d97c393/rpds_py-2026.5.1-cp315-cp315t-musllinux_1_2_aarch64.whl", hash = "sha256:43bca78665423cabae77146f2fe7ce55272b6c8d55d82cca83effd42c7e13972", size = 551165, upload-time = "2026-05-28T12:01:44.648Z" }, + { url = "https://files.pythonhosted.org/packages/3b/c1/bc479ca069200af730881b1bd525e3114b2b391a351509fcb1b772f28086/rpds_py-2026.5.1-cp315-cp315t-musllinux_1_2_i686.whl", hash = "sha256:42d0f20e85e549c870749d0e247f0c10d318a45b7e9676d575d2dcb04a1b2e66", size = 618778, upload-time = "2026-05-28T12:01:46.337Z" }, + { url = "https://files.pythonhosted.org/packages/77/65/38ab2f90df44c2febfb63cc10ced40763d9b4bc94d173e734528663fe7f5/rpds_py-2026.5.1-cp315-cp315t-musllinux_1_2_x86_64.whl", hash = "sha256:b1be5c35683684d5331b93600c210e8367c254683d8a6df6bd21bd2da3a334fb", size = 581839, upload-time = "2026-05-28T12:01:48.109Z" }, + { url = "https://files.pythonhosted.org/packages/15/2d/ce1f605fe036aadd460e5822e578c6c7ec3a860936cca37d6e0f299daa77/rpds_py-2026.5.1-cp315-cp315t-win32.whl", hash = "sha256:75808f6c38ce7749bb68cc2770161aae5045e6c6f6781a9782e74b93304399df", size = 207866, upload-time = "2026-05-28T12:01:49.648Z" }, + { url = "https://files.pythonhosted.org/packages/79/cb/966040123eb102371559746908ef2c9471f4d43e17ec9a645a2258dab64b/rpds_py-2026.5.1-cp315-cp315t-win_amd64.whl", hash = "sha256:90bd6630002a1c7f09e7843dd79f0d24f3d2897cc25a753480917865d14f15b3", size = 225441, upload-time = "2026-05-28T12:01:51.408Z" }, + { url = "https://files.pythonhosted.org/packages/42/56/3fe0fb34820ff667be791b3a3c22b85e8bcba54e9c832f47438c191fa7be/rpds_py-2026.5.1-pp311-pypy311_pp73-macosx_10_12_x86_64.whl", hash = "sha256:edf2765d84e42447f112ad877af8fe1db0089aaec5b28e88d6eab45e7fe99cea", size = 357151, upload-time = "2026-05-28T12:01:53.43Z" }, + { url = "https://files.pythonhosted.org/packages/8b/f2/3eb9ccdb9f143b8c9b003978898cb497f942a324c077401e6b8834238e63/rpds_py-2026.5.1-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:ad3773236e95f7f33991eb125224b7da66f206504d032a253a02da7e134519fb", size = 350195, upload-time = "2026-05-28T12:01:54.901Z" }, + { url = "https://files.pythonhosted.org/packages/a7/24/dbda232bc4f3ed732120692ab0d2c8402cb020516556d8bee622dcef2413/rpds_py-2026.5.1-pp311-pypy311_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a04df86b3f0fade39ec8fd0e0aab089b1da9fbd2b48df778a57ef96f5e7d38df", size = 381850, upload-time = "2026-05-28T12:01:56.601Z" }, + { url = "https://files.pythonhosted.org/packages/40/30/32e769839a358f78810c234f160f2cc21d1e4e47e1c0e0e0d535be5a0219/rpds_py-2026.5.1-pp311-pypy311_pp73-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:6142dbd80c4df62a5d899f0d616d417f84e0bc8d32526c8e5589019d75d028a7", size = 387899, upload-time = "2026-05-28T12:01:58.212Z" }, + { url = "https://files.pythonhosted.org/packages/ab/86/ec84d243aadb3b34b71dd26a010d0930b2d284ff5fc9a69fec53810ee6fd/rpds_py-2026.5.1-pp311-pypy311_pp73-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:0b35217adefe87f2fe4db7e9766cabe84744bfe9616d9667be18988928c7f2dc", size = 501618, upload-time = "2026-05-28T12:01:59.888Z" }, + { url = "https://files.pythonhosted.org/packages/74/25/b60e52686bbff777a64f9e4f4d3dd57980dc846913777177a2c92e4937aa/rpds_py-2026.5.1-pp311-pypy311_pp73-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b95d5e11fc712b752081183a55a244c03cd00570489edd7014d8899f8ceb8162", size = 394003, upload-time = "2026-05-28T12:02:01.482Z" }, + { url = "https://files.pythonhosted.org/packages/9b/c7/b3a6a588cc2219510ef3f42e207483a93950bedd1e3a0fd4015c95cff9e5/rpds_py-2026.5.1-pp311-pypy311_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:141c9498daf2ace9eda35d2b0e376f9ea8b058d84f2aef4f96fccfd449a2f251", size = 379778, upload-time = "2026-05-28T12:02:03.197Z" }, + { url = "https://files.pythonhosted.org/packages/31/00/c7dba3fc8a3da8cb3f6db1eb3386be4d79c2e97c6890d20eb9ac66ae8c43/rpds_py-2026.5.1-pp311-pypy311_pp73-manylinux_2_31_riscv64.whl", hash = "sha256:6f249f8b860a200ad35193af961183ebe9132710484e6f6ce0cf89fd83c63a9a", size = 392359, upload-time = "2026-05-28T12:02:04.817Z" }, + { url = "https://files.pythonhosted.org/packages/93/dd/472ba494c70753f93745992c99855bee0636daf74e6984e5e003f150316f/rpds_py-2026.5.1-pp311-pypy311_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:e4abbf391a70be864920858bf360f4fb380577c9a0f732438a1996726e2c195b", size = 412820, upload-time = "2026-05-28T12:02:06.401Z" }, + { url = "https://files.pythonhosted.org/packages/1d/6f/93831a3bfe789542ed0c1d0d74b78b440f055d6dc3ea4640eba2d95e6e23/rpds_py-2026.5.1-pp311-pypy311_pp73-musllinux_1_2_aarch64.whl", hash = "sha256:c74005a7bb87752acf351c93897ec63ad77a07a0da7ecad9c050e32e7286ba34", size = 557243, upload-time = "2026-05-28T12:02:08.013Z" }, + { url = "https://files.pythonhosted.org/packages/1f/ff/0b3d604614ffc77522c6b288fdbce68957eb583da1002aa65ba38ac0ee40/rpds_py-2026.5.1-pp311-pypy311_pp73-musllinux_1_2_i686.whl", hash = "sha256:8213afbe8a3a906fb9acb2014423fe3359ee783d0bf90995f70623a3217bfa6c", size = 623541, upload-time = "2026-05-28T12:02:09.661Z" }, + { url = "https://files.pythonhosted.org/packages/ea/ea/e7b0251441da9adfeaebcf29601d10f2a1455fcf0772fae9e7e19032bd96/rpds_py-2026.5.1-pp311-pypy311_pp73-musllinux_1_2_x86_64.whl", hash = "sha256:8c43a8a973270fd173bf48cdf80bbe66312421cba68d40845034f174f2389049", size = 586326, upload-time = "2026-05-28T12:02:11.47Z" }, +] + +[[package]] +name = "six" +version = "1.17.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/94/e7/b2c673351809dca68a0e064b6af791aa332cf192da575fd474ed7d6f16a2/six-1.17.0.tar.gz", hash = "sha256:ff70335d468e7eb6ec65b95b99d3a2836546063f63acc5171de367e834932a81", size = 34031, upload-time = "2024-12-04T17:35:28.174Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/b7/ce/149a00dd41f10bc29e5921b496af8b574d8413afcd5e30dfa0ed46c2cc5e/six-1.17.0-py2.py3-none-any.whl", hash = "sha256:4721f391ed90541fddacab5acf947aa0d3dc7d27b2e1e8eda2be8970586c3274", size = 11050, upload-time = "2024-12-04T17:35:26.475Z" }, +] + +[[package]] +name = "sniffio" +version = "1.3.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/a2/87/a6771e1546d97e7e041b6ae58d80074f81b7d5121207425c964ddf5cfdbd/sniffio-1.3.1.tar.gz", hash = "sha256:f4324edc670a0f49750a81b895f35c3adb843cca46f0530f79fc1babb23789dc", size = 20372, upload-time = "2024-02-25T23:20:04.057Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/e9/44/75a9c9421471a6c4805dbf2356f7c181a29c1879239abab1ea2cc8f38b40/sniffio-1.3.1-py3-none-any.whl", hash = "sha256:2f6da418d1f1e0fddd844478f41680e794e6051915791a034ff65e5f100525a2", size = 10235, upload-time = "2024-02-25T23:20:01.196Z" }, +] + +[[package]] +name = "sse-starlette" +version = "3.4.4" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "anyio" }, + { name = "starlette" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/f7/2b/58abc2d1fd397e7dde08e947e05c884d8ef2f78d5e2588c17a12d42d6994/sse_starlette-3.4.4.tar.gz", hash = "sha256:07e0fa0460138baf25cdd5fb28683472c3995dc1642225191b3832d62526bcb0", size = 31819, upload-time = "2026-05-12T17:37:17.019Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/dc/67/805710444ea8cc75fbf70b920ed431a560c4bf9c57f7d5a3117213189399/sse_starlette-3.4.4-py3-none-any.whl", hash = "sha256:3f4dd50d8aed2771a091f3a83000323fc3844541c16b4fe585ae2420cc6df973", size = 16514, upload-time = "2026-05-12T17:37:15.601Z" }, +] + +[[package]] +name = "starlette" +version = "1.2.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "anyio" }, + { name = "typing-extensions", marker = "python_full_version < '3.13'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/25/44/ec35f1b6e83094b997da438a02c8c9b0ade2b1e84cfc48bd4656780760a6/starlette-1.2.1.tar.gz", hash = "sha256:9b9b5ebb992e67d6093741e63c2f59e4f6fff986f81163c087867bd7b924b3f6", size = 2701854, upload-time = "2026-05-31T01:07:51.847Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/1c/54/196d0c1db10af76baa4f64894448505d60d3cdf70ef92cbb35f46a4e4c71/starlette-1.2.1-py3-none-any.whl", hash = "sha256:4de0082d08c8f6764a85a54cf1120d6939507a19905c7768acad2a9f875d2b89", size = 73350, upload-time = "2026-05-31T01:07:50.09Z" }, +] + +[[package]] +name = "tenacity" +version = "9.1.4" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/47/c6/ee486fd809e357697ee8a44d3d69222b344920433d3b6666ccd9b374630c/tenacity-9.1.4.tar.gz", hash = "sha256:adb31d4c263f2bd041081ab33b498309a57c77f9acf2db65aadf0898179cf93a", size = 49413, upload-time = "2026-02-07T10:45:33.841Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/d7/c1/eb8f9debc45d3b7918a32ab756658a0904732f75e555402972246b0b8e71/tenacity-9.1.4-py3-none-any.whl", hash = "sha256:6095a360c919085f28c6527de529e76a06ad89b23659fa881ae0649b867a9d55", size = 28926, upload-time = "2026-02-07T10:45:32.24Z" }, +] + +[[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.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/ba/19/1b9b0e29f30c6d35cb345486df41110984ea67ae69dddbc0e8a100999493/tzdata-2026.2.tar.gz", hash = "sha256:9173fde7d80d9018e02a662e168e5a2d04f87c41ea174b139fbef642eda62d10", size = 198254, upload-time = "2026-04-24T15:22:08.651Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/ce/e4/dccd7f47c4b64213ac01ef921a1337ee6e30e8c6466046018326977efd95/tzdata-2026.2-py2.py3-none-any.whl", hash = "sha256:bbe9af844f658da81a5f95019480da3a89415801f6cc966806612cc7169bffe7", size = 349321, upload-time = "2026-04-24T15:22:05.876Z" }, +] + +[[package]] +name = "tzlocal" +version = "5.3.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "tzdata", marker = "sys_platform == 'win32'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/8b/2e/c14812d3d4d9cd1773c6be938f89e5735a1f11a9f184ac3639b93cef35d5/tzlocal-5.3.1.tar.gz", hash = "sha256:cceffc7edecefea1f595541dbd6e990cb1ea3d19bf01b2809f362a03dd7921fd", size = 30761, upload-time = "2025-03-05T21:17:41.549Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/c2/14/e2a54fabd4f08cd7af1c07030603c3356b74da07f7cc056e600436edfa17/tzlocal-5.3.1-py3-none-any.whl", hash = "sha256:eb1a66c3ef5847adf7a834f1be0800581b683b5608e74f86ecbcef8ab91bb85d", size = 18026, upload-time = "2025-03-05T21:17:39.857Z" }, +] + +[[package]] +name = "urllib3" +version = "2.7.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/53/0c/06f8b233b8fd13b9e5ee11424ef85419ba0d8ba0b3138bf360be2ff56953/urllib3-2.7.0.tar.gz", hash = "sha256:231e0ec3b63ceb14667c67be60f2f2c40a518cb38b03af60abc813da26505f4c", size = 433602, upload-time = "2026-05-07T16:13:18.596Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/7f/3e/5db95bcf282c52709639744ca2a8b149baccf648e39c8cc87553df9eae0c/urllib3-2.7.0-py3-none-any.whl", hash = "sha256:9fb4c81ebbb1ce9531cce37674bbc6f1360472bc18ca9a553ede278ef7276897", size = 131087, upload-time = "2026-05-07T16:13:17.151Z" }, +] + +[[package]] +name = "uvicorn" +version = "0.49.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "click" }, + { name = "h11" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/c4/1f/fa18009dea8469069cca78a4e877a008ab78f08b064bfc9ab891579077ff/uvicorn-0.49.0.tar.gz", hash = "sha256:ebf4271aa580d9de97f93192d4595176df6e91f9aae919ca73e4fc07df1e66a3", size = 91284, upload-time = "2026-06-03T22:01:30.448Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/88/fa/e1388bbcf24ef3274f45c0c1c7b501fd14971037c1b6ee23610553307497/uvicorn-0.49.0-py3-none-any.whl", hash = "sha256:ba3d14c3ee7e41c6c654c46c9eb489d33213cdd30aa1696eab1374337c13f68f", size = 71376, upload-time = "2026-06-03T22:01:29.037Z" }, +] + +[[package]] +name = "watchdog" +version = "6.0.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/db/7d/7f3d619e951c88ed75c6037b246ddcf2d322812ee8ea189be89511721d54/watchdog-6.0.0.tar.gz", hash = "sha256:9ddf7c82fda3ae8e24decda1338ede66e1c99883db93711d8fb941eaa2d8c282", size = 131220, upload-time = "2024-11-01T14:07:13.037Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/e0/24/d9be5cd6642a6aa68352ded4b4b10fb0d7889cb7f45814fb92cecd35f101/watchdog-6.0.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:6eb11feb5a0d452ee41f824e271ca311a09e250441c262ca2fd7ebcf2461a06c", size = 96393, upload-time = "2024-11-01T14:06:31.756Z" }, + { url = "https://files.pythonhosted.org/packages/63/7a/6013b0d8dbc56adca7fdd4f0beed381c59f6752341b12fa0886fa7afc78b/watchdog-6.0.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:ef810fbf7b781a5a593894e4f439773830bdecb885e6880d957d5b9382a960d2", size = 88392, upload-time = "2024-11-01T14:06:32.99Z" }, + { url = "https://files.pythonhosted.org/packages/d1/40/b75381494851556de56281e053700e46bff5b37bf4c7267e858640af5a7f/watchdog-6.0.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:afd0fe1b2270917c5e23c2a65ce50c2a4abb63daafb0d419fde368e272a76b7c", size = 89019, upload-time = "2024-11-01T14:06:34.963Z" }, + { url = "https://files.pythonhosted.org/packages/39/ea/3930d07dafc9e286ed356a679aa02d777c06e9bfd1164fa7c19c288a5483/watchdog-6.0.0-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:bdd4e6f14b8b18c334febb9c4425a878a2ac20efd1e0b231978e7b150f92a948", size = 96471, upload-time = "2024-11-01T14:06:37.745Z" }, + { url = "https://files.pythonhosted.org/packages/12/87/48361531f70b1f87928b045df868a9fd4e253d9ae087fa4cf3f7113be363/watchdog-6.0.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:c7c15dda13c4eb00d6fb6fc508b3c0ed88b9d5d374056b239c4ad1611125c860", size = 88449, upload-time = "2024-11-01T14:06:39.748Z" }, + { url = "https://files.pythonhosted.org/packages/5b/7e/8f322f5e600812e6f9a31b75d242631068ca8f4ef0582dd3ae6e72daecc8/watchdog-6.0.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:6f10cb2d5902447c7d0da897e2c6768bca89174d0c6e1e30abec5421af97a5b0", size = 89054, upload-time = "2024-11-01T14:06:41.009Z" }, + { url = "https://files.pythonhosted.org/packages/68/98/b0345cabdce2041a01293ba483333582891a3bd5769b08eceb0d406056ef/watchdog-6.0.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:490ab2ef84f11129844c23fb14ecf30ef3d8a6abafd3754a6f75ca1e6654136c", size = 96480, upload-time = "2024-11-01T14:06:42.952Z" }, + { url = "https://files.pythonhosted.org/packages/85/83/cdf13902c626b28eedef7ec4f10745c52aad8a8fe7eb04ed7b1f111ca20e/watchdog-6.0.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:76aae96b00ae814b181bb25b1b98076d5fc84e8a53cd8885a318b42b6d3a5134", size = 88451, upload-time = "2024-11-01T14:06:45.084Z" }, + { url = "https://files.pythonhosted.org/packages/fe/c4/225c87bae08c8b9ec99030cd48ae9c4eca050a59bf5c2255853e18c87b50/watchdog-6.0.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:a175f755fc2279e0b7312c0035d52e27211a5bc39719dd529625b1930917345b", size = 89057, upload-time = "2024-11-01T14:06:47.324Z" }, + { url = "https://files.pythonhosted.org/packages/a9/c7/ca4bf3e518cb57a686b2feb4f55a1892fd9a3dd13f470fca14e00f80ea36/watchdog-6.0.0-py3-none-manylinux2014_aarch64.whl", hash = "sha256:7607498efa04a3542ae3e05e64da8202e58159aa1fa4acddf7678d34a35d4f13", size = 79079, upload-time = "2024-11-01T14:06:59.472Z" }, + { url = "https://files.pythonhosted.org/packages/5c/51/d46dc9332f9a647593c947b4b88e2381c8dfc0942d15b8edc0310fa4abb1/watchdog-6.0.0-py3-none-manylinux2014_armv7l.whl", hash = "sha256:9041567ee8953024c83343288ccc458fd0a2d811d6a0fd68c4c22609e3490379", size = 79078, upload-time = "2024-11-01T14:07:01.431Z" }, + { url = "https://files.pythonhosted.org/packages/d4/57/04edbf5e169cd318d5f07b4766fee38e825d64b6913ca157ca32d1a42267/watchdog-6.0.0-py3-none-manylinux2014_i686.whl", hash = "sha256:82dc3e3143c7e38ec49d61af98d6558288c415eac98486a5c581726e0737c00e", size = 79076, upload-time = "2024-11-01T14:07:02.568Z" }, + { url = "https://files.pythonhosted.org/packages/ab/cc/da8422b300e13cb187d2203f20b9253e91058aaf7db65b74142013478e66/watchdog-6.0.0-py3-none-manylinux2014_ppc64.whl", hash = "sha256:212ac9b8bf1161dc91bd09c048048a95ca3a4c4f5e5d4a7d1b1a7d5752a7f96f", size = 79077, upload-time = "2024-11-01T14:07:03.893Z" }, + { url = "https://files.pythonhosted.org/packages/2c/3b/b8964e04ae1a025c44ba8e4291f86e97fac443bca31de8bd98d3263d2fcf/watchdog-6.0.0-py3-none-manylinux2014_ppc64le.whl", hash = "sha256:e3df4cbb9a450c6d49318f6d14f4bbc80d763fa587ba46ec86f99f9e6876bb26", size = 79078, upload-time = "2024-11-01T14:07:05.189Z" }, + { url = "https://files.pythonhosted.org/packages/62/ae/a696eb424bedff7407801c257d4b1afda455fe40821a2be430e173660e81/watchdog-6.0.0-py3-none-manylinux2014_s390x.whl", hash = "sha256:2cce7cfc2008eb51feb6aab51251fd79b85d9894e98ba847408f662b3395ca3c", size = 79077, upload-time = "2024-11-01T14:07:06.376Z" }, + { url = "https://files.pythonhosted.org/packages/b5/e8/dbf020b4d98251a9860752a094d09a65e1b436ad181faf929983f697048f/watchdog-6.0.0-py3-none-manylinux2014_x86_64.whl", hash = "sha256:20ffe5b202af80ab4266dcd3e91aae72bf2da48c0d33bdb15c66658e685e94e2", size = 79078, upload-time = "2024-11-01T14:07:07.547Z" }, + { url = "https://files.pythonhosted.org/packages/07/f6/d0e5b343768e8bcb4cda79f0f2f55051bf26177ecd5651f84c07567461cf/watchdog-6.0.0-py3-none-win32.whl", hash = "sha256:07df1fdd701c5d4c8e55ef6cf55b8f0120fe1aef7ef39a1c6fc6bc2e606d517a", size = 79065, upload-time = "2024-11-01T14:07:09.525Z" }, + { url = "https://files.pythonhosted.org/packages/db/d9/c495884c6e548fce18a8f40568ff120bc3a4b7b99813081c8ac0c936fa64/watchdog-6.0.0-py3-none-win_amd64.whl", hash = "sha256:cbafb470cf848d93b5d013e2ecb245d4aa1c8fd0504e863ccefa32445359d680", size = 79070, upload-time = "2024-11-01T14:07:10.686Z" }, + { url = "https://files.pythonhosted.org/packages/33/e8/e40370e6d74ddba47f002a32919d91310d6074130fe4e17dabcafc15cbf1/watchdog-6.0.0-py3-none-win_ia64.whl", hash = "sha256:a1914259fa9e1454315171103c6a30961236f508b9b623eae470268bbcc6a22f", size = 79067, upload-time = "2024-11-01T14:07:11.845Z" }, +] + +[[package]] +name = "websockets" +version = "15.0.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/21/e6/26d09fab466b7ca9c7737474c52be4f76a40301b08362eb2dbc19dcc16c1/websockets-15.0.1.tar.gz", hash = "sha256:82544de02076bafba038ce055ee6412d68da13ab47f0c60cab827346de828dee", size = 177016, upload-time = "2025-03-05T20:03:41.606Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/9f/32/18fcd5919c293a398db67443acd33fde142f283853076049824fc58e6f75/websockets-15.0.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:823c248b690b2fd9303ba00c4f66cd5e2d8c3ba4aa968b2779be9532a4dad431", size = 175423, upload-time = "2025-03-05T20:01:56.276Z" }, + { url = "https://files.pythonhosted.org/packages/76/70/ba1ad96b07869275ef42e2ce21f07a5b0148936688c2baf7e4a1f60d5058/websockets-15.0.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:678999709e68425ae2593acf2e3ebcbcf2e69885a5ee78f9eb80e6e371f1bf57", size = 173082, upload-time = "2025-03-05T20:01:57.563Z" }, + { url = "https://files.pythonhosted.org/packages/86/f2/10b55821dd40eb696ce4704a87d57774696f9451108cff0d2824c97e0f97/websockets-15.0.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:d50fd1ee42388dcfb2b3676132c78116490976f1300da28eb629272d5d93e905", size = 173330, upload-time = "2025-03-05T20:01:59.063Z" }, + { url = "https://files.pythonhosted.org/packages/a5/90/1c37ae8b8a113d3daf1065222b6af61cc44102da95388ac0018fcb7d93d9/websockets-15.0.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d99e5546bf73dbad5bf3547174cd6cb8ba7273062a23808ffea025ecb1cf8562", size = 182878, upload-time = "2025-03-05T20:02:00.305Z" }, + { url = "https://files.pythonhosted.org/packages/8e/8d/96e8e288b2a41dffafb78e8904ea7367ee4f891dafc2ab8d87e2124cb3d3/websockets-15.0.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:66dd88c918e3287efc22409d426c8f729688d89a0c587c88971a0faa2c2f3792", size = 181883, upload-time = "2025-03-05T20:02:03.148Z" }, + { url = "https://files.pythonhosted.org/packages/93/1f/5d6dbf551766308f6f50f8baf8e9860be6182911e8106da7a7f73785f4c4/websockets-15.0.1-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8dd8327c795b3e3f219760fa603dcae1dcc148172290a8ab15158cf85a953413", size = 182252, upload-time = "2025-03-05T20:02:05.29Z" }, + { url = "https://files.pythonhosted.org/packages/d4/78/2d4fed9123e6620cbf1706c0de8a1632e1a28e7774d94346d7de1bba2ca3/websockets-15.0.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:8fdc51055e6ff4adeb88d58a11042ec9a5eae317a0a53d12c062c8a8865909e8", size = 182521, upload-time = "2025-03-05T20:02:07.458Z" }, + { url = "https://files.pythonhosted.org/packages/e7/3b/66d4c1b444dd1a9823c4a81f50231b921bab54eee2f69e70319b4e21f1ca/websockets-15.0.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:693f0192126df6c2327cce3baa7c06f2a117575e32ab2308f7f8216c29d9e2e3", size = 181958, upload-time = "2025-03-05T20:02:09.842Z" }, + { url = "https://files.pythonhosted.org/packages/08/ff/e9eed2ee5fed6f76fdd6032ca5cd38c57ca9661430bb3d5fb2872dc8703c/websockets-15.0.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:54479983bd5fb469c38f2f5c7e3a24f9a4e70594cd68cd1fa6b9340dadaff7cf", size = 181918, upload-time = "2025-03-05T20:02:11.968Z" }, + { url = "https://files.pythonhosted.org/packages/d8/75/994634a49b7e12532be6a42103597b71098fd25900f7437d6055ed39930a/websockets-15.0.1-cp311-cp311-win32.whl", hash = "sha256:16b6c1b3e57799b9d38427dda63edcbe4926352c47cf88588c0be4ace18dac85", size = 176388, upload-time = "2025-03-05T20:02:13.32Z" }, + { url = "https://files.pythonhosted.org/packages/98/93/e36c73f78400a65f5e236cd376713c34182e6663f6889cd45a4a04d8f203/websockets-15.0.1-cp311-cp311-win_amd64.whl", hash = "sha256:27ccee0071a0e75d22cb35849b1db43f2ecd3e161041ac1ee9d2352ddf72f065", size = 176828, upload-time = "2025-03-05T20:02:14.585Z" }, + { url = "https://files.pythonhosted.org/packages/51/6b/4545a0d843594f5d0771e86463606a3988b5a09ca5123136f8a76580dd63/websockets-15.0.1-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:3e90baa811a5d73f3ca0bcbf32064d663ed81318ab225ee4f427ad4e26e5aff3", size = 175437, upload-time = "2025-03-05T20:02:16.706Z" }, + { url = "https://files.pythonhosted.org/packages/f4/71/809a0f5f6a06522af902e0f2ea2757f71ead94610010cf570ab5c98e99ed/websockets-15.0.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:592f1a9fe869c778694f0aa806ba0374e97648ab57936f092fd9d87f8bc03665", size = 173096, upload-time = "2025-03-05T20:02:18.832Z" }, + { url = "https://files.pythonhosted.org/packages/3d/69/1a681dd6f02180916f116894181eab8b2e25b31e484c5d0eae637ec01f7c/websockets-15.0.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:0701bc3cfcb9164d04a14b149fd74be7347a530ad3bbf15ab2c678a2cd3dd9a2", size = 173332, upload-time = "2025-03-05T20:02:20.187Z" }, + { url = "https://files.pythonhosted.org/packages/a6/02/0073b3952f5bce97eafbb35757f8d0d54812b6174ed8dd952aa08429bcc3/websockets-15.0.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e8b56bdcdb4505c8078cb6c7157d9811a85790f2f2b3632c7d1462ab5783d215", size = 183152, upload-time = "2025-03-05T20:02:22.286Z" }, + { url = "https://files.pythonhosted.org/packages/74/45/c205c8480eafd114b428284840da0b1be9ffd0e4f87338dc95dc6ff961a1/websockets-15.0.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0af68c55afbd5f07986df82831c7bff04846928ea8d1fd7f30052638788bc9b5", size = 182096, upload-time = "2025-03-05T20:02:24.368Z" }, + { url = "https://files.pythonhosted.org/packages/14/8f/aa61f528fba38578ec553c145857a181384c72b98156f858ca5c8e82d9d3/websockets-15.0.1-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:64dee438fed052b52e4f98f76c5790513235efaa1ef7f3f2192c392cd7c91b65", size = 182523, upload-time = "2025-03-05T20:02:25.669Z" }, + { url = "https://files.pythonhosted.org/packages/ec/6d/0267396610add5bc0d0d3e77f546d4cd287200804fe02323797de77dbce9/websockets-15.0.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:d5f6b181bb38171a8ad1d6aa58a67a6aa9d4b38d0f8c5f496b9e42561dfc62fe", size = 182790, upload-time = "2025-03-05T20:02:26.99Z" }, + { url = "https://files.pythonhosted.org/packages/02/05/c68c5adbf679cf610ae2f74a9b871ae84564462955d991178f95a1ddb7dd/websockets-15.0.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:5d54b09eba2bada6011aea5375542a157637b91029687eb4fdb2dab11059c1b4", size = 182165, upload-time = "2025-03-05T20:02:30.291Z" }, + { url = "https://files.pythonhosted.org/packages/29/93/bb672df7b2f5faac89761cb5fa34f5cec45a4026c383a4b5761c6cea5c16/websockets-15.0.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:3be571a8b5afed347da347bfcf27ba12b069d9d7f42cb8c7028b5e98bbb12597", size = 182160, upload-time = "2025-03-05T20:02:31.634Z" }, + { url = "https://files.pythonhosted.org/packages/ff/83/de1f7709376dc3ca9b7eeb4b9a07b4526b14876b6d372a4dc62312bebee0/websockets-15.0.1-cp312-cp312-win32.whl", hash = "sha256:c338ffa0520bdb12fbc527265235639fb76e7bc7faafbb93f6ba80d9c06578a9", size = 176395, upload-time = "2025-03-05T20:02:33.017Z" }, + { url = "https://files.pythonhosted.org/packages/7d/71/abf2ebc3bbfa40f391ce1428c7168fb20582d0ff57019b69ea20fa698043/websockets-15.0.1-cp312-cp312-win_amd64.whl", hash = "sha256:fcd5cf9e305d7b8338754470cf69cf81f420459dbae8a3b40cee57417f4614a7", size = 176841, upload-time = "2025-03-05T20:02:34.498Z" }, + { url = "https://files.pythonhosted.org/packages/cb/9f/51f0cf64471a9d2b4d0fc6c534f323b664e7095640c34562f5182e5a7195/websockets-15.0.1-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:ee443ef070bb3b6ed74514f5efaa37a252af57c90eb33b956d35c8e9c10a1931", size = 175440, upload-time = "2025-03-05T20:02:36.695Z" }, + { url = "https://files.pythonhosted.org/packages/8a/05/aa116ec9943c718905997412c5989f7ed671bc0188ee2ba89520e8765d7b/websockets-15.0.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:5a939de6b7b4e18ca683218320fc67ea886038265fd1ed30173f5ce3f8e85675", size = 173098, upload-time = "2025-03-05T20:02:37.985Z" }, + { url = "https://files.pythonhosted.org/packages/ff/0b/33cef55ff24f2d92924923c99926dcce78e7bd922d649467f0eda8368923/websockets-15.0.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:746ee8dba912cd6fc889a8147168991d50ed70447bf18bcda7039f7d2e3d9151", size = 173329, upload-time = "2025-03-05T20:02:39.298Z" }, + { url = "https://files.pythonhosted.org/packages/31/1d/063b25dcc01faa8fada1469bdf769de3768b7044eac9d41f734fd7b6ad6d/websockets-15.0.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:595b6c3969023ecf9041b2936ac3827e4623bfa3ccf007575f04c5a6aa318c22", size = 183111, upload-time = "2025-03-05T20:02:40.595Z" }, + { url = "https://files.pythonhosted.org/packages/93/53/9a87ee494a51bf63e4ec9241c1ccc4f7c2f45fff85d5bde2ff74fcb68b9e/websockets-15.0.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3c714d2fc58b5ca3e285461a4cc0c9a66bd0e24c5da9911e30158286c9b5be7f", size = 182054, upload-time = "2025-03-05T20:02:41.926Z" }, + { url = "https://files.pythonhosted.org/packages/ff/b2/83a6ddf56cdcbad4e3d841fcc55d6ba7d19aeb89c50f24dd7e859ec0805f/websockets-15.0.1-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0f3c1e2ab208db911594ae5b4f79addeb3501604a165019dd221c0bdcabe4db8", size = 182496, upload-time = "2025-03-05T20:02:43.304Z" }, + { url = "https://files.pythonhosted.org/packages/98/41/e7038944ed0abf34c45aa4635ba28136f06052e08fc2168520bb8b25149f/websockets-15.0.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:229cf1d3ca6c1804400b0a9790dc66528e08a6a1feec0d5040e8b9eb14422375", size = 182829, upload-time = "2025-03-05T20:02:48.812Z" }, + { url = "https://files.pythonhosted.org/packages/e0/17/de15b6158680c7623c6ef0db361da965ab25d813ae54fcfeae2e5b9ef910/websockets-15.0.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:756c56e867a90fb00177d530dca4b097dd753cde348448a1012ed6c5131f8b7d", size = 182217, upload-time = "2025-03-05T20:02:50.14Z" }, + { url = "https://files.pythonhosted.org/packages/33/2b/1f168cb6041853eef0362fb9554c3824367c5560cbdaad89ac40f8c2edfc/websockets-15.0.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:558d023b3df0bffe50a04e710bc87742de35060580a293c2a984299ed83bc4e4", size = 182195, upload-time = "2025-03-05T20:02:51.561Z" }, + { url = "https://files.pythonhosted.org/packages/86/eb/20b6cdf273913d0ad05a6a14aed4b9a85591c18a987a3d47f20fa13dcc47/websockets-15.0.1-cp313-cp313-win32.whl", hash = "sha256:ba9e56e8ceeeedb2e080147ba85ffcd5cd0711b89576b83784d8605a7df455fa", size = 176393, upload-time = "2025-03-05T20:02:53.814Z" }, + { url = "https://files.pythonhosted.org/packages/1b/6c/c65773d6cab416a64d191d6ee8a8b1c68a09970ea6909d16965d26bfed1e/websockets-15.0.1-cp313-cp313-win_amd64.whl", hash = "sha256:e09473f095a819042ecb2ab9465aee615bd9c2028e4ef7d933600a8401c79561", size = 176837, upload-time = "2025-03-05T20:02:55.237Z" }, + { url = "https://files.pythonhosted.org/packages/fa/a8/5b41e0da817d64113292ab1f8247140aac61cbf6cfd085d6a0fa77f4984f/websockets-15.0.1-py3-none-any.whl", hash = "sha256:f7a866fbc1e97b5c617ee4116daaa09b722101d4a3c170c787450ba409f9736f", size = 169743, upload-time = "2025-03-05T20:03:39.41Z" }, +] + +[[package]] +name = "zipp" +version = "4.1.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/b9/d8/eab98a517c14134c0b2eb4e2387bc5f457334293ec5d2dd3857ec2966802/zipp-4.1.0.tar.gz", hash = "sha256:4cb57381f544315db7688e976e922a2b18cdb513d21cc194eb42232ba2a3e602", size = 26214, upload-time = "2026-05-18T20:08:57.967Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/3a/13/547360d81e6d88d58492968ffda9f9542854f11310ee556fef14260cc886/zipp-4.1.0-py3-none-any.whl", hash = "sha256:25ad4e16390cd314347dd8f1de67a2ac538ae658ed4ab9db16029c07c188e97f", size = 10238, upload-time = "2026-05-18T20:08:57.045Z" }, +]