From fc85cd2abed20ebd601afcd85c1489a0801198fa Mon Sep 17 00:00:00 2001 From: Travis Herbranson Date: Fri, 22 May 2026 19:11:06 -0400 Subject: [PATCH] project init --- .gitignore | 10 + .python-version | 1 + CLAUDE.md | 67 +++ README.md | 0 config/client_secret.json | 12 + config/token.json | 1 + data/pbs_youtube.db | Bin 0 -> 1138688 bytes main.py | 159 ++++++ pyproject.toml | 15 + src/__init__.py | 0 src/auth.py | 56 ++ src/collector.py | 228 ++++++++ src/dashboard.py | 532 +++++++++++++++++ src/database.py | 91 +++ src/seed.py | 390 +++++++++++++ uv.lock | 1140 +++++++++++++++++++++++++++++++++++++ 16 files changed, 2702 insertions(+) create mode 100644 .gitignore create mode 100644 .python-version create mode 100644 CLAUDE.md create mode 100644 README.md create mode 100644 config/client_secret.json create mode 100644 config/token.json create mode 100644 data/pbs_youtube.db create mode 100644 main.py create mode 100644 pyproject.toml create mode 100644 src/__init__.py create mode 100644 src/auth.py create mode 100644 src/collector.py create mode 100644 src/dashboard.py create mode 100644 src/database.py create mode 100644 src/seed.py create mode 100644 uv.lock diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..505a3b1 --- /dev/null +++ b/.gitignore @@ -0,0 +1,10 @@ +# Python-generated files +__pycache__/ +*.py[oc] +build/ +dist/ +wheels/ +*.egg-info + +# Virtual environments +.venv diff --git a/.python-version b/.python-version new file mode 100644 index 0000000..e4fba21 --- /dev/null +++ b/.python-version @@ -0,0 +1 @@ +3.12 diff --git a/CLAUDE.md b/CLAUDE.md new file mode 100644 index 0000000..a4de6d8 --- /dev/null +++ b/CLAUDE.md @@ -0,0 +1,67 @@ +# YouTube Analytics — CLAUDE.md + +PBS YouTube channel analytics pipeline: collect data from YouTube APIs, store in SQLite, visualize with Streamlit. + +## Project Structure + +``` +main.py — Click CLI entry point (init-db, seed, collect, dashboard) +src/ + auth.py — OAuth2 authentication (YouTube Data API v3 + Analytics API v2) + collector.py — Data collection (videos, daily metrics, retention, traffic sources, channel stats) + database.py — SQLite schema (5 tables) and connection management (WAL mode, foreign keys) + dashboard.py — Streamlit dashboard (charts, tables, retention curves) + seed.py — Sample data generator (PBS plant-based cooking channel theme) +config/ — OAuth credentials (git-ignored, not committed) +data/ — SQLite database (git-ignored) +``` + +## Package Manager + +Uses **uv** (not pip, not poetry). Python >=3.12. + +```bash +uv sync # install deps from lockfile +uv add # add a dependency +uv run python main.py # run within managed venv +``` + +## CLI Commands + +```bash +uv run python main.py init-db-cmd # create database tables +uv run python main.py seed # populate with sample data +uv run python main.py collect # pull real data (requires OAuth creds in config/) +uv run python main.py dashboard # launch Streamlit dashboard +``` + +## Database + +SQLite at `data/pbs_youtube.db` with five tables: +- `videos` — video metadata (id, title, published_at, duration, type) +- `video_daily_metrics` — per-video daily stats (views, watch time, CTR, engagement) +- `video_retention` — 100-point audience retention curves per video +- `video_traffic_sources` — traffic source breakdown per video per day +- `channel_daily_metrics` — channel-level daily summary + +All inserts use `ON CONFLICT DO UPDATE` for idempotent runs. + +## Authentication + +Real YouTube API access requires: +1. Create OAuth credentials at https://console.cloud.google.com/apis/credentials +2. Download client secret JSON → save as `config/client_secret.json` +3. First run of `collect` opens browser for OAuth consent, stores token at `config/token.json` + +For development/testing, use `seed` command instead — no credentials needed. + +## Key Dependencies + +click, streamlit, plotly, pandas, google-api-python-client, google-auth-oauthlib + +## Conventions + +- All data collection functions live in `collector.py`, one function per data type +- Dashboard uses Plotly for charts via `streamlit` + `plotly` +- Duration parsing handles ISO 8601 (PT1H2M3S format) +- Shorts classified as videos ≤60 seconds diff --git a/README.md b/README.md new file mode 100644 index 0000000..e69de29 diff --git a/config/client_secret.json b/config/client_secret.json new file mode 100644 index 0000000..ea91b0a --- /dev/null +++ b/config/client_secret.json @@ -0,0 +1,12 @@ +{ + "installed": + { + "client_id":"918670827378-ngeo2grfmm82orjhru6bs8g5hrcht0cd.apps.googleusercontent.com", + "project_id":"pbs-site-486819", + "auth_uri":"https://accounts.google.com/o/oauth2/auth", + "token_uri":"https://oauth2.googleapis.com/token", + "auth_provider_x509_cert_url":"https://www.googleapis.com/oauth2/v1/certs", + "client_secret":"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", + "redirect_uris":["http://localhost"] + } +} \ No newline at end of file diff --git a/config/token.json b/config/token.json new file mode 100644 index 0000000..576f425 --- /dev/null +++ b/config/token.json @@ -0,0 +1 @@ +{"token": "ya29.a0AQvPyINTBUmYT0TS8M6C6QhWHVswoI0coM6ycnodz_mJpqITBBXXfh4sVILepbZ8fVz60Bfog95aqFl47T6NFkb5_GXGlSA_1iq-_Q0bQg_Qc2_L0J_8nZQ4ubpTr2FV5K2ipe-er3QU4999C4OXQSxdB9FEMCuNrT_r_Aa3ojqdb2OMZIKwPuw4Ctqp1cX_9RZ03kqCaCgYKAYgSARQSFQHGX2Mi62N5gg_yUtdFoY3t9Uh4lw0207", "refresh_token": "1//05Zaxlboo0cyOCgYIARAAGAUSNwF-L9IrAplENIYSCGlR4dcA07L0_f2344h793lvG2eRzFeFRgDKTYtMPso9D8DvYMbNDgNWGb4", "token_uri": "https://oauth2.googleapis.com/token", "client_id": "918670827378-ngeo2grfmm82orjhru6bs8g5hrcht0cd.apps.googleusercontent.com", "client_secret": "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", "scopes": ["https://www.googleapis.com/auth/yt-analytics.readonly", "https://www.googleapis.com/auth/youtube.readonly"], "universe_domain": "googleapis.com", "account": "", "expiry": "2026-05-04T02:25:42.357613Z"} \ No newline at end of file diff --git a/data/pbs_youtube.db b/data/pbs_youtube.db new file mode 100644 index 0000000000000000000000000000000000000000..c0c59c2244cb9d15c2b898257bf601a90fd3b3c9 GIT binary patch literal 1138688 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%0A^0rP?j_aL*npC$Y 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.3.2", + "google-api-python-client>=2.194.0", + "google-auth-httplib2>=0.3.1", + "google-auth-oauthlib>=1.3.1", + "pandas>=3.0.2", + "plotly>=6.7.0", + "streamlit>=1.56.0", +] diff --git a/src/__init__.py b/src/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/src/auth.py b/src/auth.py new file mode 100644 index 0000000..5dcd135 --- /dev/null +++ b/src/auth.py @@ -0,0 +1,56 @@ +"""YouTube API authentication module with OAuth2 token persistence. + +Replace PLACEHOLDER values with real credentials from Google Cloud Console. +See: https://console.cloud.google.com/apis/credentials +""" + +from pathlib import Path + +SCOPES = [ + "https://www.googleapis.com/auth/yt-analytics.readonly", + "https://www.googleapis.com/auth/youtube.readonly", +] + +CONFIG_DIR = Path(__file__).parent.parent / "config" +CLIENT_SECRET_PATH = CONFIG_DIR / "client_secret.json" +TOKEN_PATH = CONFIG_DIR / "token.json" + + +def get_authenticated_service(): + """Build and return authenticated YouTube API services. + + Returns a tuple of (youtube_data_api, youtube_analytics_api). + + On first run, opens a browser for OAuth consent. + Subsequent runs use the stored refresh token. + """ + from google.oauth2.credentials import Credentials + from google_auth_oauthlib.flow import InstalledAppFlow + from google.auth.transport.requests import Request + from googleapiclient.discovery import build + + creds = None + + if TOKEN_PATH.exists(): + creds = Credentials.from_authorized_user_file(str(TOKEN_PATH), SCOPES) + + if not creds or not creds.valid: + if creds and creds.expired and creds.refresh_token: + creds.refresh(Request()) + else: + if not CLIENT_SECRET_PATH.exists(): + raise FileNotFoundError( + f"Missing {CLIENT_SECRET_PATH}. Download OAuth credentials from " + "Google Cloud Console and save as config/client_secret.json" + ) + flow = InstalledAppFlow.from_client_secrets_file( + str(CLIENT_SECRET_PATH), SCOPES + ) + creds = flow.run_local_server(port=0) + + TOKEN_PATH.write_text(creds.to_json()) + + youtube = build("youtube", "v3", credentials=creds) + youtube_analytics = build("youtubeAnalytics", "v2", credentials=creds) + + return youtube, youtube_analytics diff --git a/src/collector.py b/src/collector.py new file mode 100644 index 0000000..10281cc --- /dev/null +++ b/src/collector.py @@ -0,0 +1,228 @@ +"""YouTube data collector — pulls video metadata, metrics, and retention data.""" + +import sqlite3 +from datetime import datetime, timedelta + + +def collect_video_list(youtube, conn: sqlite3.Connection) -> list[str]: + """Fetch all videos from the channel and upsert into the videos table.""" + video_ids = [] + request = youtube.channels().list(part="contentDetails", mine=True) + response = request.execute() + + uploads_playlist = response["items"][0]["contentDetails"]["relatedPlaylists"]["uploads"] + + next_page = None + while True: + pl_request = youtube.playlistItems().list( + part="snippet,contentDetails", + playlistId=uploads_playlist, + maxResults=50, + pageToken=next_page, + ) + pl_response = pl_request.execute() + + ids = [item["contentDetails"]["videoId"] for item in pl_response["items"]] + video_ids.extend(ids) + + # Batch video details (duration, type) + for i in range(0, len(ids), 50): + batch = ids[i : i + 50] + vid_request = youtube.videos().list( + part="snippet,contentDetails", id=",".join(batch) + ) + vid_response = vid_request.execute() + + for video in vid_response["items"]: + duration = _parse_duration(video["contentDetails"]["duration"]) + video_type = "short" if duration <= 60 else "video" + + conn.execute( + """INSERT INTO videos (video_id, title, published_at, duration_seconds, + video_type, thumbnail_url, description, updated_at) + VALUES (?, ?, ?, ?, ?, ?, ?, CURRENT_TIMESTAMP) + ON CONFLICT(video_id) DO UPDATE SET + title=excluded.title, duration_seconds=excluded.duration_seconds, + video_type=excluded.video_type, thumbnail_url=excluded.thumbnail_url, + description=excluded.description, updated_at=CURRENT_TIMESTAMP""", + ( + video["id"], + video["snippet"]["title"], + video["snippet"]["publishedAt"], + duration, + video_type, + video["snippet"]["thumbnails"].get("high", {}).get("url", ""), + video["snippet"].get("description", ""), + ), + ) + + conn.commit() + next_page = pl_response.get("nextPageToken") + if not next_page: + break + + print(f"Collected {len(video_ids)} videos") + return video_ids + + +def collect_daily_metrics( + youtube_analytics, conn: sqlite3.Connection, video_ids: list[str], + start_date: str | None = None, end_date: str | None = None, +) -> None: + """Fetch daily metrics for each video from the Analytics API.""" + if not end_date: + end_date = (datetime.now() - timedelta(days=2)).strftime("%Y-%m-%d") + if not start_date: + start_date = (datetime.now() - timedelta(days=30)).strftime("%Y-%m-%d") + + for vid in video_ids: + response = youtube_analytics.reports().query( + ids="channel==MINE", + startDate=start_date, + endDate=end_date, + metrics="views,estimatedMinutesWatched,averageViewDuration,averageViewPercentage,likes,dislikes,comments,shares,subscribersGained,subscribersLost", + dimensions="day", + filters=f"video=={vid}", + sort="day", + ).execute() + + for row in response.get("rows", []): + conn.execute( + """INSERT INTO video_daily_metrics + (video_id, date, views, estimated_minutes_watched, + average_view_duration_seconds, average_view_percentage, + likes, dislikes, comments, shares, + subscribers_gained, subscribers_lost) + VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) + ON CONFLICT(video_id, date) DO UPDATE SET + views=excluded.views, + estimated_minutes_watched=excluded.estimated_minutes_watched, + average_view_duration_seconds=excluded.average_view_duration_seconds, + average_view_percentage=excluded.average_view_percentage, + likes=excluded.likes, dislikes=excluded.dislikes, + comments=excluded.comments, shares=excluded.shares, + subscribers_gained=excluded.subscribers_gained, + subscribers_lost=excluded.subscribers_lost""", + (vid, row[0], *row[1:]), + ) + + conn.commit() + print(f"Collected daily metrics for {len(video_ids)} videos") + + +def collect_retention( + youtube_analytics, conn: sqlite3.Connection, video_ids: list[str], +) -> None: + """Fetch audience retention curves for each video.""" + for vid in video_ids: + response = youtube_analytics.reports().query( + ids="channel==MINE", + startDate="2020-01-01", + endDate=datetime.now().strftime("%Y-%m-%d"), + metrics="audienceWatchRatio,relativeRetentionPerformance", + dimensions="elapsedVideoTimeRatio", + filters=f"video=={vid}", + sort="elapsedVideoTimeRatio", + ).execute() + + for row in response.get("rows", []): + conn.execute( + """INSERT INTO video_retention + (video_id, elapsed_ratio, audience_watch_ratio, + relative_retention_performance, fetched_at) + VALUES (?, ?, ?, ?, CURRENT_TIMESTAMP) + ON CONFLICT(video_id, elapsed_ratio) DO UPDATE SET + audience_watch_ratio=excluded.audience_watch_ratio, + relative_retention_performance=excluded.relative_retention_performance, + fetched_at=CURRENT_TIMESTAMP""", + (vid, row[0], row[1], row[2]), + ) + + conn.commit() + print(f"Collected retention data for {len(video_ids)} videos") + + +def collect_traffic_sources( + youtube_analytics, conn: sqlite3.Connection, video_ids: list[str], + start_date: str | None = None, end_date: str | None = None, +) -> None: + """Fetch traffic source breakdown for each video.""" + if not end_date: + end_date = (datetime.now() - timedelta(days=2)).strftime("%Y-%m-%d") + if not start_date: + start_date = (datetime.now() - timedelta(days=30)).strftime("%Y-%m-%d") + + for vid in video_ids: + response = youtube_analytics.reports().query( + ids="channel==MINE", + startDate=start_date, + endDate=end_date, + metrics="views,estimatedMinutesWatched", + dimensions="day,insightTrafficSourceType", + filters=f"video=={vid}", + sort="day", + ).execute() + + for row in response.get("rows", []): + conn.execute( + """INSERT INTO video_traffic_sources + (video_id, date, traffic_source, views, estimated_minutes_watched) + VALUES (?, ?, ?, ?, ?) + ON CONFLICT(video_id, date, traffic_source) DO UPDATE SET + views=excluded.views, + estimated_minutes_watched=excluded.estimated_minutes_watched""", + (vid, row[0], row[1], row[2], row[3]), + ) + + conn.commit() + print(f"Collected traffic source data for {len(video_ids)} videos") + + +def collect_channel_metrics( + youtube_analytics, conn: sqlite3.Connection, + start_date: str | None = None, end_date: str | None = None, +) -> None: + """Fetch channel-level daily summary metrics.""" + if not end_date: + end_date = (datetime.now() - timedelta(days=2)).strftime("%Y-%m-%d") + if not start_date: + start_date = (datetime.now() - timedelta(days=30)).strftime("%Y-%m-%d") + + response = youtube_analytics.reports().query( + ids="channel==MINE", + startDate=start_date, + endDate=end_date, + metrics="views,estimatedMinutesWatched,subscribersGained,subscribersLost", + dimensions="day", + sort="day", + ).execute() + + for row in response.get("rows", []): + conn.execute( + """INSERT INTO channel_daily_metrics + (date, total_views, total_estimated_minutes_watched, + subscribers_gained, subscribers_lost, net_subscribers) + VALUES (?, ?, ?, ?, ?, ?) + ON CONFLICT(date) DO UPDATE SET + total_views=excluded.total_views, + total_estimated_minutes_watched=excluded.total_estimated_minutes_watched, + subscribers_gained=excluded.subscribers_gained, + subscribers_lost=excluded.subscribers_lost, + net_subscribers=excluded.net_subscribers""", + (row[0], row[1], row[2], row[3], row[4], row[3] - row[4]), + ) + + conn.commit() + print("Collected channel daily metrics") + + +def _parse_duration(iso_duration: str) -> int: + """Parse ISO 8601 duration (PT1H2M3S) to total seconds.""" + import re + match = re.match(r"PT(?:(\d+)H)?(?:(\d+)M)?(?:(\d+)S)?", iso_duration) + if not match: + return 0 + hours = int(match.group(1) or 0) + minutes = int(match.group(2) or 0) + seconds = int(match.group(3) or 0) + return hours * 3600 + minutes * 60 + seconds diff --git a/src/dashboard.py b/src/dashboard.py new file mode 100644 index 0000000..eaf0852 --- /dev/null +++ b/src/dashboard.py @@ -0,0 +1,532 @@ +"""Streamlit dashboard for PBS YouTube Analytics.""" + +import sqlite3 +import streamlit as st +import pandas as pd +import plotly.graph_objects as go +import plotly.express as px +from datetime import datetime, timedelta +from pathlib import Path + +from src.database import get_connection, DEFAULT_DB_PATH + + +def _render_video_tab(conn, video_type: str, start_date, end_date) -> None: + """Render content for the Videos or Shorts tab.""" + label = "Video" if video_type == "video" else "Short" + label_plural = "Videos" if video_type == "video" else "Shorts" + + # Performance table + st.subheader(f"{label_plural} Performance") + try: + video_stats = pd.read_sql_query( + f"""SELECT + v.video_id, + v.title, + v.duration_seconds, + SUM(m.views) as total_views, + SUM(m.estimated_minutes_watched) as watch_time_minutes, + ROUND(AVG(m.average_view_percentage), 2) as avg_completion_pct, + SUM(m.likes) as likes, + SUM(m.comments) as comments + FROM videos v + LEFT JOIN video_daily_metrics m ON v.video_id = m.video_id + AND m.date BETWEEN ? AND ? + WHERE v.video_type = ? + GROUP BY v.video_id + ORDER BY total_views DESC""", + conn, + params=(start_date.isoformat(), end_date.isoformat(), video_type), + ) + + if not video_stats.empty: + video_stats["Duration"] = video_stats["duration_seconds"].apply( + lambda x: f"{int(x // 60)}:{int(x % 60):02d}" if x else "0:00" + ) + video_stats["Watch Time (h)"] = (video_stats["watch_time_minutes"] / 60).round(1) + display_cols = ["title", "Duration", "total_views", "Watch Time (h)", "avg_completion_pct", "likes", "comments"] + st.dataframe( + video_stats[display_cols].rename(columns={ + "title": "Title", + "total_views": "Views", + "avg_completion_pct": "Completion %", + }), + width='stretch', + hide_index=True, + ) + else: + st.info(f"No {label_plural.lower()} data available.") + except Exception as e: + st.warning(f"Could not load {label_plural.lower()} statistics: {e}") + + st.divider() + + col1, col2 = st.columns(2) + + with col1: + st.subheader(f"Top {label_plural} by Views") + try: + top_videos = pd.read_sql_query( + f"""SELECT + v.title, + SUM(m.views) as total_views + FROM videos v + LEFT JOIN video_daily_metrics m ON v.video_id = m.video_id + AND m.date BETWEEN ? AND ? + WHERE v.video_type = ? + GROUP BY v.video_id + ORDER BY total_views DESC + LIMIT 10""", + conn, + params=(start_date.isoformat(), end_date.isoformat(), video_type), + ) + if not top_videos.empty: + fig = px.bar( + top_videos, + y="title", + x="total_views", + orientation="h", + labels={"title": "", "total_views": "Views"}, + ) + fig.update_yaxes(autorange="reversed") + fig.update_layout(showlegend=False, height=400) + st.plotly_chart(fig, width='stretch') + else: + st.info(f"No {label_plural.lower()} data available.") + except Exception as e: + st.warning(f"Could not load top {label_plural.lower()}: {e}") + + with col2: + st.subheader("Traffic Source Breakdown") + try: + traffic = pd.read_sql_query( + f"""SELECT + t.traffic_source, + SUM(t.views) as views + FROM video_traffic_sources t + JOIN videos v ON t.video_id = v.video_id + WHERE t.date BETWEEN ? AND ? + AND v.video_type = ? + GROUP BY t.traffic_source + ORDER BY views DESC""", + conn, + params=(start_date.isoformat(), end_date.isoformat(), video_type), + ) + if not traffic.empty: + fig = px.pie( + traffic, + names="traffic_source", + values="views", + labels={"traffic_source": "Source", "views": "Views"}, + ) + fig.update_layout(height=400) + st.plotly_chart(fig, width='stretch') + else: + st.info(f"No traffic data available for {label_plural.lower()}.") + except Exception as e: + st.warning(f"Could not load traffic sources: {e}") + + st.divider() + + # Per-video detail + st.subheader(f"{label} Detail") + try: + videos_of_type = pd.read_sql_query( + "SELECT video_id, title FROM videos WHERE video_type = ? ORDER BY title", + conn, + params=(video_type,), + ) + + if videos_of_type.empty: + st.info(f"No {label_plural.lower()} found.") + return + + id_to_title = dict(zip(videos_of_type["video_id"], videos_of_type["title"])) + + selected_videos = st.multiselect( + f"Select {label_plural.lower()} to explore", + options=videos_of_type["video_id"].tolist(), + format_func=lambda x: id_to_title[x], + key=f"multiselect_{video_type}", + ) + + if selected_videos: + metric_choice = st.selectbox( + "Metric", + options=["Views", "Watch Time"], + key=f"metric_select_{video_type}", + ) + if metric_choice == "Views": + y_col = "views" + y_label = "Cumulative Views" + else: + y_col = "Watch Time (h)" + y_label = "Cumulative Watch Time (h)" + + colors = px.colors.qualitative.Plotly + + st.subheader("Daily Views & Watch Time") + try: + fig = go.Figure() + for i, vid_id in enumerate(selected_videos): + daily = pd.read_sql_query( + """SELECT date, views, estimated_minutes_watched + FROM video_daily_metrics + WHERE video_id = ? AND date BETWEEN ? AND ? + ORDER BY date""", + conn, + params=(vid_id, start_date.isoformat(), end_date.isoformat()), + ) + if not daily.empty: + daily["date"] = pd.to_datetime(daily["date"]) + daily["Watch Time (h)"] = (daily["estimated_minutes_watched"] / 60).round(2) + daily["cumulative"] = daily[y_col].cumsum() + color = colors[i % len(colors)] + fig.add_trace(go.Scatter( + x=daily["date"], + y=daily["cumulative"], + name=id_to_title[vid_id], + mode="lines+markers", + line=dict(color=color), + )) + fig.update_layout( + xaxis_title="Date", + yaxis_title=y_label, + hovermode="x unified", + ) + st.plotly_chart(fig, width='stretch') + except Exception as e: + st.warning(f"Could not load daily metrics: {e}") + + st.subheader("Retention Curves") + try: + fig = go.Figure() + for i, vid_id in enumerate(selected_videos): + retention = pd.read_sql_query( + """SELECT elapsed_ratio * 100 as elapsed_pct, audience_watch_ratio + FROM video_retention + WHERE video_id = ? + ORDER BY elapsed_ratio""", + conn, + params=(vid_id,), + ) + if not retention.empty: + color = colors[i % len(colors)] + fig.add_trace(go.Scatter( + x=retention["elapsed_pct"], + y=retention["audience_watch_ratio"], + mode="lines", + name=id_to_title[vid_id], + line=dict(color=color), + )) + fig.update_layout( + xaxis_title="Video Progress (%)", + yaxis_title="Audience Watch Ratio (%)", + hovermode="x unified", + ) + st.plotly_chart(fig, width='stretch') + except Exception as e: + st.warning(f"Could not load retention curves: {e}") + + except Exception as e: + st.warning(f"Could not load {label.lower()} detail section: {e}") + + +def run_dashboard(): + """Run the Streamlit dashboard.""" + st.set_page_config(page_title="PBS YouTube Analytics", layout="wide") + st.title("PBS YouTube Analytics Dashboard") + + db_path = DEFAULT_DB_PATH + if not db_path.exists(): + st.error(f"Database not found at {db_path}. Please run 'init-db' and 'seed' first.") + return + + conn = get_connection(db_path) + + # Sidebar — date range filter only + st.sidebar.header("Filters") + + try: + min_date_result = conn.execute("SELECT MIN(date) FROM channel_daily_metrics").fetchone() + max_date_result = conn.execute("SELECT MAX(date) FROM channel_daily_metrics").fetchone() + + if min_date_result[0] and max_date_result[0]: + min_date = datetime.fromisoformat(min_date_result[0]).date() + max_date = datetime.fromisoformat(max_date_result[0]).date() + else: + min_date = datetime.now().date() - timedelta(days=30) + max_date = datetime.now().date() + except Exception: + min_date = datetime.now().date() - timedelta(days=30) + max_date = datetime.now().date() + + date_range = st.sidebar.date_input( + "Select date range", + value=(min_date, max_date), + min_value=min_date, + max_value=max_date, + ) + + if len(date_range) == 2: + start_date, end_date = date_range + else: + start_date, end_date = min_date, max_date + + # Sidebar — Data Collection + st.sidebar.divider() + st.sidebar.header("Data Collection") + + # Display any status message carried over from a previous collection run via session state + if "_collect_msg" in st.session_state: + _msg_type, _msg_text = st.session_state.pop("_collect_msg") + if _msg_type == "success": + st.sidebar.success(_msg_text) + else: + st.sidebar.error(_msg_text) + + today = datetime.now().date() + collect_start = st.sidebar.date_input( + "Start date", + value=today - timedelta(days=30), + key="collect_start", + ) + collect_end = st.sidebar.date_input( + "End date", + value=today - timedelta(days=2), + key="collect_end", + ) + + def _open_collection_conn(): + sconn = sqlite3.connect(str(db_path)) + sconn.execute("PRAGMA journal_mode=WAL") + sconn.execute("PRAGMA foreign_keys=ON") + return sconn + + if st.sidebar.button("Collect All", type="primary", use_container_width=True): + with st.spinner("Collecting all data from YouTube API..."): + try: + from src.auth import get_authenticated_service + from src.collector import ( + collect_channel_metrics, + collect_daily_metrics, + collect_retention, + collect_traffic_sources, + collect_video_list, + ) + from src.database import init_db as _init_db + + youtube, youtube_analytics = get_authenticated_service() + _init_db(db_path) + sconn = _open_collection_conn() + start_str = collect_start.isoformat() + end_str = collect_end.isoformat() + video_ids = collect_video_list(youtube, sconn) + collect_daily_metrics(youtube_analytics, sconn, video_ids, start_str, end_str) + collect_retention(youtube_analytics, sconn, video_ids) + collect_traffic_sources(youtube_analytics, sconn, video_ids, start_str, end_str) + collect_channel_metrics(youtube_analytics, sconn, start_str, end_str) + sconn.close() + st.session_state["_collect_msg"] = ("success", "All data collected successfully!") + st.rerun() + except FileNotFoundError as e: + st.sidebar.error( + f"Auth credentials not found. " + f"Save config/client_secret.json to enable collection.\n\n{e}" + ) + except Exception as e: + st.sidebar.error(f"Collection error: {e}") + + with st.sidebar.expander("Individual Steps"): + if st.button("Collect Video List", use_container_width=True, key="btn_videos"): + with st.spinner("Collecting video list..."): + try: + from src.auth import get_authenticated_service + from src.collector import collect_video_list + from src.database import init_db as _init_db + + youtube, _ = get_authenticated_service() + _init_db(db_path) + sconn = _open_collection_conn() + collect_video_list(youtube, sconn) + sconn.close() + st.session_state["_collect_msg"] = ("success", "Video list collected!") + st.rerun() + except FileNotFoundError as e: + st.sidebar.error(f"Auth credentials not found: {e}") + except Exception as e: + st.sidebar.error(f"Error: {e}") + + if st.button("Collect Daily Metrics", use_container_width=True, key="btn_daily"): + with st.spinner("Collecting daily metrics..."): + try: + from src.auth import get_authenticated_service + from src.collector import collect_daily_metrics + + _, youtube_analytics = get_authenticated_service() + sconn = _open_collection_conn() + video_ids = [r[0] for r in sconn.execute("SELECT video_id FROM videos").fetchall()] + collect_daily_metrics( + youtube_analytics, sconn, video_ids, + collect_start.isoformat(), collect_end.isoformat(), + ) + sconn.close() + st.session_state["_collect_msg"] = ("success", "Daily metrics collected!") + st.rerun() + except FileNotFoundError as e: + st.sidebar.error(f"Auth credentials not found: {e}") + except Exception as e: + st.sidebar.error(f"Error: {e}") + + if st.button("Collect Retention", use_container_width=True, key="btn_retention"): + with st.spinner("Collecting retention data..."): + try: + from src.auth import get_authenticated_service + from src.collector import collect_retention + + _, youtube_analytics = get_authenticated_service() + sconn = _open_collection_conn() + video_ids = [r[0] for r in sconn.execute("SELECT video_id FROM videos").fetchall()] + collect_retention(youtube_analytics, sconn, video_ids) + sconn.close() + st.session_state["_collect_msg"] = ("success", "Retention data collected!") + st.rerun() + except FileNotFoundError as e: + st.sidebar.error(f"Auth credentials not found: {e}") + except Exception as e: + st.sidebar.error(f"Error: {e}") + + if st.button("Collect Traffic Sources", use_container_width=True, key="btn_traffic"): + with st.spinner("Collecting traffic sources..."): + try: + from src.auth import get_authenticated_service + from src.collector import collect_traffic_sources + + _, youtube_analytics = get_authenticated_service() + sconn = _open_collection_conn() + video_ids = [r[0] for r in sconn.execute("SELECT video_id FROM videos").fetchall()] + collect_traffic_sources( + youtube_analytics, sconn, video_ids, + collect_start.isoformat(), collect_end.isoformat(), + ) + sconn.close() + st.session_state["_collect_msg"] = ("success", "Traffic sources collected!") + st.rerun() + except FileNotFoundError as e: + st.sidebar.error(f"Auth credentials not found: {e}") + except Exception as e: + st.sidebar.error(f"Error: {e}") + + if st.button("Collect Channel Metrics", use_container_width=True, key="btn_channel"): + with st.spinner("Collecting channel metrics..."): + try: + from src.auth import get_authenticated_service + from src.collector import collect_channel_metrics + + _, youtube_analytics = get_authenticated_service() + sconn = _open_collection_conn() + collect_channel_metrics( + youtube_analytics, sconn, + collect_start.isoformat(), collect_end.isoformat(), + ) + sconn.close() + st.session_state["_collect_msg"] = ("success", "Channel metrics collected!") + st.rerun() + except FileNotFoundError as e: + st.sidebar.error(f"Auth credentials not found: {e}") + except Exception as e: + st.sidebar.error(f"Error: {e}") + + # Channel overview metrics (above tabs — channel-wide) + col1, col2, col3 = st.columns(3) + try: + metrics = conn.execute( + """SELECT + SUM(total_views) as total_views, + SUM(total_estimated_minutes_watched) as total_watch_time, + SUM(subscribers_gained) as total_subs_gained + FROM channel_daily_metrics + WHERE date BETWEEN ? AND ?""", + (start_date.isoformat(), end_date.isoformat()), + ).fetchone() + + if metrics and metrics[0]: + with col1: + st.metric("Total Views", f"{int(metrics[0]):,}") + with col2: + st.metric("Watch Time (hours)", f"{int(metrics[1] / 60):,}") + with col3: + st.metric("Subscribers Gained", f"{int(metrics[2]):,}") + except Exception as e: + st.warning(f"Could not load channel metrics: {e}") + + st.divider() + + # Views over time (above tabs — channel-wide) + st.subheader("Views Over Time") + try: + daily_views = pd.read_sql_query( + """SELECT m.date, v.video_type, SUM(m.views) as views + FROM video_daily_metrics m + JOIN videos v ON m.video_id = v.video_id + WHERE m.date BETWEEN ? AND ? + GROUP BY m.date, v.video_type + ORDER BY m.date""", + conn, + params=(start_date.isoformat(), end_date.isoformat()), + ) + if not daily_views.empty: + daily_views["date"] = pd.to_datetime(daily_views["date"]) + pivoted = daily_views.pivot_table( + index="date", columns="video_type", values="views", fill_value=0 + ).reset_index() + if "short" not in pivoted.columns: + pivoted["short"] = 0 + if "video" not in pivoted.columns: + pivoted["video"] = 0 + fig = go.Figure() + fig.add_trace(go.Scatter( + x=pivoted["date"], + y=pivoted["short"], + name="Shorts", + stackgroup="one", + mode="lines", + line=dict(color="#FF7043"), + fillcolor="rgba(255, 112, 67, 0.6)", + )) + fig.add_trace(go.Scatter( + x=pivoted["date"], + y=pivoted["video"], + name="Videos", + stackgroup="one", + mode="lines", + line=dict(color="#1976D2"), + fillcolor="rgba(25, 118, 210, 0.6)", + )) + fig.update_layout( + xaxis_title="Date", + yaxis_title="Views", + hovermode="x unified", + ) + st.plotly_chart(fig, width='stretch') + else: + st.info("No data available for the selected date range.") + except Exception as e: + st.warning(f"Could not load views chart: {e}") + + st.divider() + + # Tabbed section — per-type content + videos_tab, shorts_tab = st.tabs(["Videos", "Shorts"]) + + with videos_tab: + _render_video_tab(conn, "video", start_date, end_date) + + with shorts_tab: + _render_video_tab(conn, "short", start_date, end_date) + + conn.close() + + +if __name__ == "__main__": + run_dashboard() diff --git a/src/database.py b/src/database.py new file mode 100644 index 0000000..836593e --- /dev/null +++ b/src/database.py @@ -0,0 +1,91 @@ +"""SQLite database setup and connection management for PBS YouTube Analytics.""" + +import sqlite3 +from pathlib import Path + +DEFAULT_DB_PATH = Path(__file__).parent.parent / "data" / "pbs_youtube.db" + +SCHEMA = """ +-- Video metadata from Data API +CREATE TABLE IF NOT EXISTS videos ( + video_id TEXT PRIMARY KEY, + title TEXT NOT NULL, + published_at TEXT NOT NULL, + duration_seconds INTEGER, + video_type TEXT CHECK(video_type IN ('video', 'short')), + thumbnail_url TEXT, + description TEXT, + created_at TEXT DEFAULT CURRENT_TIMESTAMP, + updated_at TEXT DEFAULT CURRENT_TIMESTAMP +); + +-- Daily aggregate metrics from Analytics API +CREATE TABLE IF NOT EXISTS video_daily_metrics ( + video_id TEXT NOT NULL, + date TEXT NOT NULL, + views INTEGER DEFAULT 0, + estimated_minutes_watched REAL DEFAULT 0, + average_view_duration_seconds REAL DEFAULT 0, + average_view_percentage REAL DEFAULT 0, + likes INTEGER DEFAULT 0, + dislikes INTEGER DEFAULT 0, + comments INTEGER DEFAULT 0, + shares INTEGER DEFAULT 0, + subscribers_gained INTEGER DEFAULT 0, + subscribers_lost INTEGER DEFAULT 0, + impressions INTEGER DEFAULT 0, + impressions_ctr REAL DEFAULT 0, + created_at TEXT DEFAULT CURRENT_TIMESTAMP, + PRIMARY KEY (video_id, date), + FOREIGN KEY (video_id) REFERENCES videos(video_id) +); + +-- Audience retention curve (100 data points per video) +CREATE TABLE IF NOT EXISTS video_retention ( + video_id TEXT NOT NULL, + elapsed_ratio REAL NOT NULL, + audience_watch_ratio REAL NOT NULL, + relative_retention_performance REAL, + fetched_at TEXT DEFAULT CURRENT_TIMESTAMP, + PRIMARY KEY (video_id, elapsed_ratio), + FOREIGN KEY (video_id) REFERENCES videos(video_id) +); + +-- Traffic source breakdown per video per day +CREATE TABLE IF NOT EXISTS video_traffic_sources ( + video_id TEXT NOT NULL, + date TEXT NOT NULL, + traffic_source TEXT NOT NULL, + views INTEGER DEFAULT 0, + estimated_minutes_watched REAL DEFAULT 0, + PRIMARY KEY (video_id, date, traffic_source), + FOREIGN KEY (video_id) REFERENCES videos(video_id) +); + +-- Channel-level daily summary +CREATE TABLE IF NOT EXISTS channel_daily_metrics ( + date TEXT PRIMARY KEY, + total_views INTEGER DEFAULT 0, + total_estimated_minutes_watched REAL DEFAULT 0, + subscribers_gained INTEGER DEFAULT 0, + subscribers_lost INTEGER DEFAULT 0, + net_subscribers INTEGER DEFAULT 0, + created_at TEXT DEFAULT CURRENT_TIMESTAMP +); +""" + + +def get_connection(db_path: Path = DEFAULT_DB_PATH) -> sqlite3.Connection: + db_path.parent.mkdir(parents=True, exist_ok=True) + conn = sqlite3.connect(str(db_path)) + conn.row_factory = sqlite3.Row + conn.execute("PRAGMA journal_mode=WAL") + conn.execute("PRAGMA foreign_keys=ON") + return conn + + +def init_db(db_path: Path = DEFAULT_DB_PATH) -> None: + conn = get_connection(db_path) + conn.executescript(SCHEMA) + conn.close() + print(f"Database initialized at {db_path}") diff --git a/src/seed.py b/src/seed.py new file mode 100644 index 0000000..02c1e00 --- /dev/null +++ b/src/seed.py @@ -0,0 +1,390 @@ +"""Seed script to populate SQLite database with realistic sample data for a PBS plant-based cooking channel.""" + +import sqlite3 +import random +from datetime import datetime, timedelta +from pathlib import Path + +from src.database import get_connection, DEFAULT_DB_PATH + + +def seed_database(db_path: Path = DEFAULT_DB_PATH) -> None: + """Populate the database with realistic sample data.""" + conn = get_connection(db_path) + + # Clear existing data + conn.execute("DELETE FROM video_traffic_sources") + conn.execute("DELETE FROM video_retention") + conn.execute("DELETE FROM video_daily_metrics") + conn.execute("DELETE FROM channel_daily_metrics") + conn.execute("DELETE FROM videos") + conn.commit() + + # Seed videos + video_ids = _seed_videos(conn) + + # Seed daily metrics for the last 30 days + _seed_daily_metrics(conn, video_ids) + + # Seed retention curves + _seed_retention(conn, video_ids) + + # Seed traffic sources + _seed_traffic_sources(conn, video_ids) + + # Seed channel daily metrics + _seed_channel_metrics(conn) + + conn.close() + print(f"Database seeded successfully at {db_path}") + + +def _seed_videos(conn: sqlite3.Connection) -> list[str]: + """Create ~18 videos: mix of shorts and long-form, PBS plant-based cooking themed.""" + videos = [ + # Shorts (30-60 seconds) + { + "video_id": "short_001", + "title": "Quick Vegan Breakfast: 30-Second Oatmeal Hack", + "duration_seconds": 45, + "video_type": "short", + "published_at": (datetime.now() - timedelta(days=25)).isoformat() + "Z", + }, + { + "video_id": "short_002", + "title": "Plant-Based Protein Smoothie Bowl", + "duration_seconds": 52, + "video_type": "short", + "published_at": (datetime.now() - timedelta(days=23)).isoformat() + "Z", + }, + { + "video_id": "short_003", + "title": "Crispy Tofu in 60 Seconds", + "duration_seconds": 58, + "video_type": "short", + "published_at": (datetime.now() - timedelta(days=21)).isoformat() + "Z", + }, + { + "video_id": "short_004", + "title": "No-Cook Hummus & Veggie Snack Hack", + "duration_seconds": 48, + "video_type": "short", + "published_at": (datetime.now() - timedelta(days=19)).isoformat() + "Z", + }, + { + "video_id": "short_005", + "title": "5-Minute Mango Sorbet", + "duration_seconds": 55, + "video_type": "short", + "published_at": (datetime.now() - timedelta(days=17)).isoformat() + "Z", + }, + { + "video_id": "short_006", + "title": "Instant Pasta Primavera Hack", + "duration_seconds": 50, + "video_type": "short", + "published_at": (datetime.now() - timedelta(days=15)).isoformat() + "Z", + }, + # Long-form videos (5-20 minutes) + { + "video_id": "long_001", + "title": "Complete Plant-Based Dinner: Mediterranean Buddha Bowl", + "duration_seconds": 12 * 60 + 30, + "video_type": "video", + "published_at": (datetime.now() - timedelta(days=28)).isoformat() + "Z", + }, + { + "video_id": "long_002", + "title": "Vegan Baking Masterclass: Chocolate Avocado Cake", + "duration_seconds": 18 * 60 + 45, + "video_type": "video", + "published_at": (datetime.now() - timedelta(days=26)).isoformat() + "Z", + }, + { + "video_id": "long_003", + "title": "How to Make Cashew Cream from Scratch", + "duration_seconds": 8 * 60 + 15, + "video_type": "video", + "published_at": (datetime.now() - timedelta(days=24)).isoformat() + "Z", + }, + { + "video_id": "long_004", + "title": "Budget Plant-Based Meal Prep for the Week", + "duration_seconds": 16 * 60 + 20, + "video_type": "video", + "published_at": (datetime.now() - timedelta(days=22)).isoformat() + "Z", + }, + { + "video_id": "long_005", + "title": "Fermentation Basics: Making Kimchi & Sauerkraut", + "duration_seconds": 19 * 60 + 10, + "video_type": "video", + "published_at": (datetime.now() - timedelta(days=20)).isoformat() + "Z", + }, + { + "video_id": "long_006", + "title": "Whole Plant-Based Thanksgiving Feast", + "duration_seconds": 22 * 60 + 30, + "video_type": "video", + "published_at": (datetime.now() - timedelta(days=18)).isoformat() + "Z", + }, + { + "video_id": "long_007", + "title": "Nutritionist Deep Dive: Plant-Based Protein Myth Busting", + "duration_seconds": 14 * 60 + 50, + "video_type": "video", + "published_at": (datetime.now() - timedelta(days=16)).isoformat() + "Z", + }, + { + "video_id": "long_008", + "title": "Zero-Waste Kitchen: Composting & Food Scraps", + "duration_seconds": 10 * 60 + 25, + "video_type": "video", + "published_at": (datetime.now() - timedelta(days=14)).isoformat() + "Z", + }, + { + "video_id": "long_009", + "title": "Street Food Around the World: Vegan Edition", + "duration_seconds": 20 * 60 + 15, + "video_type": "video", + "published_at": (datetime.now() - timedelta(days=12)).isoformat() + "Z", + }, + { + "video_id": "long_010", + "title": "How to Stock Your Plant-Based Pantry", + "duration_seconds": 11 * 60 + 40, + "video_type": "video", + "published_at": (datetime.now() - timedelta(days=10)).isoformat() + "Z", + }, + { + "video_id": "long_011", + "title": "Interview: Local Organic Farmer About Seasonal Produce", + "duration_seconds": 17 * 60 + 35, + "video_type": "video", + "published_at": (datetime.now() - timedelta(days=8)).isoformat() + "Z", + }, + { + "video_id": "long_012", + "title": "Plant-Based Athlete: How I Fuel My Training", + "duration_seconds": 15 * 60 + 20, + "video_type": "video", + "published_at": (datetime.now() - timedelta(days=6)).isoformat() + "Z", + }, + ] + + thumbnails = [ + "https://via.placeholder.com/320x180?text=Recipe", + "https://via.placeholder.com/320x180?text=Cooking", + "https://via.placeholder.com/320x180?text=Plant+Based", + ] + + descriptions = [ + "Learn how to make delicious plant-based meals at home.", + "Quick and easy vegan cooking tips for busy weeknights.", + "Discover the joy of plant-based eating with our expert guides.", + "Sustainable cooking starts in your kitchen.", + "Healthy, delicious, and 100% plant-based.", + ] + + video_ids = [] + for video in videos: + video_ids.append(video["video_id"]) + conn.execute( + """INSERT INTO videos + (video_id, title, published_at, duration_seconds, video_type, thumbnail_url, description) + VALUES (?, ?, ?, ?, ?, ?, ?)""", + ( + video["video_id"], + video["title"], + video["published_at"], + video["duration_seconds"], + video["video_type"], + random.choice(thumbnails), + random.choice(descriptions), + ), + ) + + conn.commit() + print(f"Seeded {len(video_ids)} videos") + return video_ids + + +def _seed_daily_metrics(conn: sqlite3.Connection, video_ids: list[str]) -> None: + """Seed 30 days of daily metrics for each video.""" + # Short videos get 50-500 views/day, long videos get 100-2000 views/day + start_date = datetime.now() - timedelta(days=30) + + for video_id in video_ids: + is_short = video_id.startswith("short_") + + for day_offset in range(30): + date = (start_date + timedelta(days=day_offset)).strftime("%Y-%m-%d") + + if is_short: + views = random.randint(50, 500) + estimated_minutes = views * random.uniform(0.5, 2.0) + avg_duration = random.uniform(20, 45) # seconds + ctr = random.uniform(0.8, 3.5) + else: + views = random.randint(100, 2000) + estimated_minutes = views * random.uniform(3.0, 10.0) + avg_duration = random.uniform(200, 800) # seconds + ctr = random.uniform(1.2, 4.5) + + avg_view_pct = (avg_duration / 720) * 100 if not is_short else (avg_duration / 60) * 100 + avg_view_pct = min(avg_view_pct, 100) + + likes = int(views * random.uniform(0.01, 0.05)) + comments = int(views * random.uniform(0.002, 0.015)) + shares = int(views * random.uniform(0.001, 0.008)) + impressions = int(views / random.uniform(0.15, 0.35)) + subs_gained = max(0, int(views * random.uniform(0.001, 0.012)) - 1) + + conn.execute( + """INSERT INTO video_daily_metrics + (video_id, date, views, estimated_minutes_watched, + average_view_duration_seconds, average_view_percentage, + likes, dislikes, comments, shares, + subscribers_gained, subscribers_lost, impressions, impressions_ctr) + VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)""", + ( + video_id, date, views, estimated_minutes, + avg_duration, avg_view_pct, + likes, 0, comments, shares, + subs_gained, 0, impressions, ctr, + ), + ) + + conn.commit() + print(f"Seeded daily metrics for {len(video_ids)} videos over 30 days") + + +def _seed_retention(conn: sqlite3.Connection, video_ids: list[str]) -> None: + """Seed audience retention curves (100 data points per video).""" + for video_id in video_ids: + is_short = video_id.startswith("short_") + + # Retention typically starts high and drops off + # Shorts: steep drop, longs: gradual decline + for point in range(100): + elapsed_ratio = point / 100.0 + + if is_short: + # Shorts drop off faster + audience_ratio = 100 * (1 - elapsed_ratio ** 1.2) + else: + # Long-form videos drop off more gradually + audience_ratio = 100 * (1 - elapsed_ratio ** 0.8) + + audience_ratio = max(1, audience_ratio) # Minimum 1% + + relative_perf = random.uniform(-20, 30) # Performance vs avg + + conn.execute( + """INSERT INTO video_retention + (video_id, elapsed_ratio, audience_watch_ratio, relative_retention_performance) + VALUES (?, ?, ?, ?)""", + (video_id, elapsed_ratio, audience_ratio, relative_perf), + ) + + conn.commit() + print(f"Seeded retention curves for {len(video_ids)} videos") + + +def _seed_traffic_sources(conn: sqlite3.Connection, video_ids: list[str]) -> None: + """Seed traffic source breakdown for each video-day combination.""" + sources = [ + "YouTube search", + "Suggested videos", + "Direct or unknown", + "External website", + "YouTube channel", + "Playlist", + ] + + start_date = datetime.now() - timedelta(days=30) + + for video_id in video_ids: + for day_offset in range(30): + date = (start_date + timedelta(days=day_offset)).strftime("%Y-%m-%d") + + # Get total views from video_daily_metrics + cursor = conn.execute( + "SELECT views FROM video_daily_metrics WHERE video_id = ? AND date = ?", + (video_id, date), + ) + result = cursor.fetchone() + if not result: + continue + + total_views = result[0] + + # Distribute across sources + remaining_views = total_views + for source in sources[:-1]: + source_views = int(remaining_views * random.uniform(0.05, 0.35)) + source_minutes = source_views * random.uniform(1.0, 6.0) + + conn.execute( + """INSERT INTO video_traffic_sources + (video_id, date, traffic_source, views, estimated_minutes_watched) + VALUES (?, ?, ?, ?, ?)""", + (video_id, date, source, source_views, source_minutes), + ) + remaining_views -= source_views + + # Last source gets remainder + if remaining_views > 0: + conn.execute( + """INSERT INTO video_traffic_sources + (video_id, date, traffic_source, views, estimated_minutes_watched) + VALUES (?, ?, ?, ?, ?)""", + (video_id, date, sources[-1], remaining_views, remaining_views * random.uniform(1.0, 6.0)), + ) + + conn.commit() + print(f"Seeded traffic sources for {len(video_ids)} videos over 30 days") + + +def _seed_channel_metrics(conn: sqlite3.Connection) -> None: + """Seed channel-level daily summary metrics for the last 30 days.""" + start_date = datetime.now() - timedelta(days=30) + + for day_offset in range(30): + date = (start_date + timedelta(days=day_offset)).strftime("%Y-%m-%d") + + # Get daily totals from video metrics + cursor = conn.execute( + """SELECT + SUM(views), SUM(estimated_minutes_watched) + FROM video_daily_metrics + WHERE date = ?""", + (date,), + ) + result = cursor.fetchone() + + if result and result[0]: + total_views = result[0] + total_minutes = result[1] or 0 + else: + # Fallback if no video metrics yet + total_views = random.randint(2000, 8000) + total_minutes = total_views * random.uniform(3.0, 8.0) + + subs_gained = max(0, int(total_views * random.uniform(0.001, 0.015)) - 1) + subs_lost = max(0, subs_gained - random.randint(0, int(subs_gained * 0.5))) + + conn.execute( + """INSERT INTO channel_daily_metrics + (date, total_views, total_estimated_minutes_watched, + subscribers_gained, subscribers_lost, net_subscribers) + VALUES (?, ?, ?, ?, ?, ?)""", + (date, total_views, total_minutes, subs_gained, subs_lost, subs_gained - subs_lost), + ) + + conn.commit() + print("Seeded channel daily metrics for 30 days") + + +if __name__ == "__main__": + seed_database() diff --git a/uv.lock b/uv.lock new file mode 100644 index 0000000..2e89633 --- /dev/null +++ b/uv.lock @@ -0,0 +1,1140 @@ +version = 1 +revision = 3 +requires-python = ">=3.12" +resolution-markers = [ + "python_full_version >= '3.14' and sys_platform == 'win32'", + "python_full_version >= '3.14' and sys_platform == 'emscripten'", + "python_full_version >= '3.14' and sys_platform != 'emscripten' and sys_platform != 'win32'", + "python_full_version == '3.13.*' and sys_platform == 'win32'", + "python_full_version < '3.13' and sys_platform == 'win32'", + "python_full_version == '3.13.*' and sys_platform == 'emscripten'", + "python_full_version < '3.13' and sys_platform == 'emscripten'", + "python_full_version == '3.13.*' and sys_platform != 'emscripten' and sys_platform != 'win32'", + "python_full_version < '3.13' and sys_platform != 'emscripten' and sys_platform != 'win32'", +] + +[[package]] +name = "altair" +version = "6.0.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "jinja2" }, + { name = "jsonschema" }, + { name = "narwhals" }, + { name = "packaging" }, + { name = "typing-extensions", marker = "python_full_version < '3.15'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/f7/c0/184a89bd5feba14ff3c41cfaf1dd8a82c05f5ceedbc92145e17042eb08a4/altair-6.0.0.tar.gz", hash = "sha256:614bf5ecbe2337347b590afb111929aa9c16c9527c4887d96c9bc7f6640756b4", size = 763834, upload-time = "2025-11-12T08:59:11.519Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/db/33/ef2f2409450ef6daa61459d5de5c08128e7d3edb773fefd0a324d1310238/altair-6.0.0-py3-none-any.whl", hash = "sha256:09ae95b53d5fe5b16987dccc785a7af8588f2dca50de1e7a156efa8a461515f8", size = 795410, upload-time = "2025-11-12T08:59:09.804Z" }, +] + +[[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 = "blinker" +version = "1.9.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/21/28/9b3f50ce0e048515135495f198351908d99540d69bfdc8c1d15b73dc55ce/blinker-1.9.0.tar.gz", hash = "sha256:b4ce2265a7abece45e7cc896e98dbebe6cead56bcf805a3d23136d145f5445bf", size = 22460, upload-time = "2024-11-08T17:25:47.436Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/10/cb/f2ad4230dc2eb1a74edf38f1a38b9b52277f75bef262d8908e60d957e13c/blinker-1.9.0-py3-none-any.whl", hash = "sha256:ba0efaa9080b619ff2f3459d1d500c57bddea4a6b424b60a91141db6fd2f08bc", size = 8458, upload-time = "2024-11-08T17:25:46.184Z" }, +] + +[[package]] +name = "cachetools" +version = "7.0.5" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/af/dd/57fe3fdb6e65b25a5987fd2cdc7e22db0aef508b91634d2e57d22928d41b/cachetools-7.0.5.tar.gz", hash = "sha256:0cd042c24377200c1dcd225f8b7b12b0ca53cc2c961b43757e774ebe190fd990", size = 37367, upload-time = "2026-03-09T20:51:29.451Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/06/f3/39cf3367b8107baa44f861dc802cbf16263c945b62d8265d36034fc07bea/cachetools-7.0.5-py3-none-any.whl", hash = "sha256:46bc8ebefbe485407621d0a4264b23c080cedd913921bad7ac3ed2f26c183114", size = 13918, upload-time = "2026-03-09T20:51:27.33Z" }, +] + +[[package]] +name = "certifi" +version = "2026.2.25" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/af/2d/7bf41579a8986e348fa033a31cdd0e4121114f6bce2457e8876010b092dd/certifi-2026.2.25.tar.gz", hash = "sha256:e887ab5cee78ea814d3472169153c2d12cd43b14bd03329a39a9c6e2e80bfba7", size = 155029, upload-time = "2026-02-25T02:54:17.342Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/9a/3c/c17fb3ca2d9c3acff52e30b309f538586f9f5b9c9cf454f3845fc9af4881/certifi-2026.2.25-py3-none-any.whl", hash = "sha256:027692e4402ad994f1c42e52a4997a9763c646b73e4096e4d5d6db8af1d6f0fa", size = 153684, upload-time = "2026-02-25T02:54:15.766Z" }, +] + +[[package]] +name = "cffi" +version = "2.0.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "pycparser", marker = "implementation_name != 'PyPy'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/eb/56/b1ba7935a17738ae8453301356628e8147c79dbb825bcbc73dc7401f9846/cffi-2.0.0.tar.gz", hash = "sha256:44d1b5909021139fe36001ae048dbdde8214afa20200eda0f64c068cac5d5529", size = 523588, upload-time = "2025-09-08T23:24:04.541Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/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/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.3.2" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "colorama", marker = "sys_platform == 'win32'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/57/75/31212c6bf2503fdf920d87fee5d7a86a2e3bcf444984126f13d8e4016804/click-8.3.2.tar.gz", hash = "sha256:14162b8b3b3550a7d479eafa77dfd3c38d9dc8951f6f69c78913a8f9a7540fd5", size = 302856, upload-time = "2026-04-03T19:14:45.118Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/e4/20/71885d8b97d4f3dde17b1fdb92dbd4908b00541c5a3379787137285f602e/click-8.3.2-py3-none-any.whl", hash = "sha256:1924d2c27c5653561cd2cae4548d1406039cb79b858b747cfea24924bbc1616d", size = 108379, upload-time = "2026-04-03T19:14:43.505Z" }, +] + +[[package]] +name = "colorama" +version = "0.4.6" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/d8/53/6f443c9a4a8358a93a6792e2acffb9d9d5cb0a5cfd8802644b7b1c9a02e4/colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44", size = 27697, upload-time = "2022-10-25T02:36:22.414Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/d1/d6/3965ed04c63042e047cb6a3e6ed1a63a35087b6a609aa3a15ed8ac56c221/colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6", size = 25335, upload-time = "2022-10-25T02:36:20.889Z" }, +] + +[[package]] +name = "cryptography" +version = "46.0.7" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "cffi", marker = "platform_python_implementation != 'PyPy'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/47/93/ac8f3d5ff04d54bc814e961a43ae5b0b146154c89c61b47bb07557679b18/cryptography-46.0.7.tar.gz", hash = "sha256:e4cfd68c5f3e0bfdad0d38e023239b96a2fe84146481852dffbcca442c245aa5", size = 750652, upload-time = "2026-04-08T01:57:54.692Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/0b/5d/4a8f770695d73be252331e60e526291e3df0c9b27556a90a6b47bccca4c2/cryptography-46.0.7-cp311-abi3-macosx_10_9_universal2.whl", hash = "sha256:ea42cbe97209df307fdc3b155f1b6fa2577c0defa8f1f7d3be7d31d189108ad4", size = 7179869, upload-time = "2026-04-08T01:56:17.157Z" }, + { url = "https://files.pythonhosted.org/packages/5f/45/6d80dc379b0bbc1f9d1e429f42e4cb9e1d319c7a8201beffd967c516ea01/cryptography-46.0.7-cp311-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:b36a4695e29fe69215d75960b22577197aca3f7a25b9cf9d165dcfe9d80bc325", size = 4275492, upload-time = "2026-04-08T01:56:19.36Z" }, + { url = "https://files.pythonhosted.org/packages/4a/9a/1765afe9f572e239c3469f2cb429f3ba7b31878c893b246b4b2994ffe2fe/cryptography-46.0.7-cp311-abi3-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:5ad9ef796328c5e3c4ceed237a183f5d41d21150f972455a9d926593a1dcb308", size = 4426670, upload-time = "2026-04-08T01:56:21.415Z" }, + { url = "https://files.pythonhosted.org/packages/8f/3e/af9246aaf23cd4ee060699adab1e47ced3f5f7e7a8ffdd339f817b446462/cryptography-46.0.7-cp311-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:73510b83623e080a2c35c62c15298096e2a5dc8d51c3b4e1740211839d0dea77", size = 4280275, upload-time = "2026-04-08T01:56:23.539Z" }, + { url = "https://files.pythonhosted.org/packages/0f/54/6bbbfc5efe86f9d71041827b793c24811a017c6ac0fd12883e4caa86b8ed/cryptography-46.0.7-cp311-abi3-manylinux_2_28_ppc64le.whl", hash = "sha256:cbd5fb06b62bd0721e1170273d3f4d5a277044c47ca27ee257025146c34cbdd1", size = 4928402, upload-time = "2026-04-08T01:56:25.624Z" }, + { url = "https://files.pythonhosted.org/packages/2d/cf/054b9d8220f81509939599c8bdbc0c408dbd2bdd41688616a20731371fe0/cryptography-46.0.7-cp311-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:420b1e4109cc95f0e5700eed79908cef9268265c773d3a66f7af1eef53d409ef", size = 4459985, upload-time = "2026-04-08T01:56:27.309Z" }, + { url = "https://files.pythonhosted.org/packages/f9/46/4e4e9c6040fb01c7467d47217d2f882daddeb8828f7df800cb806d8a2288/cryptography-46.0.7-cp311-abi3-manylinux_2_31_armv7l.whl", hash = "sha256:24402210aa54baae71d99441d15bb5a1919c195398a87b563df84468160a65de", size = 3990652, upload-time = "2026-04-08T01:56:29.095Z" }, + { url = "https://files.pythonhosted.org/packages/36/5f/313586c3be5a2fbe87e4c9a254207b860155a8e1f3cca99f9910008e7d08/cryptography-46.0.7-cp311-abi3-manylinux_2_34_aarch64.whl", hash = "sha256:8a469028a86f12eb7d2fe97162d0634026d92a21f3ae0ac87ed1c4a447886c83", size = 4279805, upload-time = "2026-04-08T01:56:30.928Z" }, + { url = "https://files.pythonhosted.org/packages/69/33/60dfc4595f334a2082749673386a4d05e4f0cf4df8248e63b2c3437585f2/cryptography-46.0.7-cp311-abi3-manylinux_2_34_ppc64le.whl", hash = "sha256:9694078c5d44c157ef3162e3bf3946510b857df5a3955458381d1c7cfc143ddb", size = 4892883, upload-time = "2026-04-08T01:56:32.614Z" }, + { url = "https://files.pythonhosted.org/packages/c7/0b/333ddab4270c4f5b972f980adef4faa66951a4aaf646ca067af597f15563/cryptography-46.0.7-cp311-abi3-manylinux_2_34_x86_64.whl", hash = "sha256:42a1e5f98abb6391717978baf9f90dc28a743b7d9be7f0751a6f56a75d14065b", size = 4459756, upload-time = "2026-04-08T01:56:34.306Z" }, + { url = "https://files.pythonhosted.org/packages/d2/14/633913398b43b75f1234834170947957c6b623d1701ffc7a9600da907e89/cryptography-46.0.7-cp311-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:91bbcb08347344f810cbe49065914fe048949648f6bd5c2519f34619142bbe85", size = 4410244, upload-time = "2026-04-08T01:56:35.977Z" }, + { url = "https://files.pythonhosted.org/packages/10/f2/19ceb3b3dc14009373432af0c13f46aa08e3ce334ec6eff13492e1812ccd/cryptography-46.0.7-cp311-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:5d1c02a14ceb9148cc7816249f64f623fbfee39e8c03b3650d842ad3f34d637e", size = 4674868, upload-time = "2026-04-08T01:56:38.034Z" }, + { url = "https://files.pythonhosted.org/packages/1a/bb/a5c213c19ee94b15dfccc48f363738633a493812687f5567addbcbba9f6f/cryptography-46.0.7-cp311-abi3-win32.whl", hash = "sha256:d23c8ca48e44ee015cd0a54aeccdf9f09004eba9fc96f38c911011d9ff1bd457", size = 3026504, upload-time = "2026-04-08T01:56:39.666Z" }, + { url = "https://files.pythonhosted.org/packages/2b/02/7788f9fefa1d060ca68717c3901ae7fffa21ee087a90b7f23c7a603c32ae/cryptography-46.0.7-cp311-abi3-win_amd64.whl", hash = "sha256:397655da831414d165029da9bc483bed2fe0e75dde6a1523ec2fe63f3c46046b", size = 3488363, upload-time = "2026-04-08T01:56:41.893Z" }, + { url = "https://files.pythonhosted.org/packages/7b/56/15619b210e689c5403bb0540e4cb7dbf11a6bf42e483b7644e471a2812b3/cryptography-46.0.7-cp314-cp314t-macosx_10_9_universal2.whl", hash = "sha256:d151173275e1728cf7839aaa80c34fe550c04ddb27b34f48c232193df8db5842", size = 7119671, upload-time = "2026-04-08T01:56:44Z" }, + { url = "https://files.pythonhosted.org/packages/74/66/e3ce040721b0b5599e175ba91ab08884c75928fbeb74597dd10ef13505d2/cryptography-46.0.7-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:db0f493b9181c7820c8134437eb8b0b4792085d37dbb24da050476ccb664e59c", size = 4268551, upload-time = "2026-04-08T01:56:46.071Z" }, + { url = "https://files.pythonhosted.org/packages/03/11/5e395f961d6868269835dee1bafec6a1ac176505a167f68b7d8818431068/cryptography-46.0.7-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:ebd6daf519b9f189f85c479427bbd6e9c9037862cf8fe89ee35503bd209ed902", size = 4408887, upload-time = "2026-04-08T01:56:47.718Z" }, + { url = "https://files.pythonhosted.org/packages/40/53/8ed1cf4c3b9c8e611e7122fb56f1c32d09e1fff0f1d77e78d9ff7c82653e/cryptography-46.0.7-cp314-cp314t-manylinux_2_28_aarch64.whl", hash = "sha256:b7b412817be92117ec5ed95f880defe9cf18a832e8cafacf0a22337dc1981b4d", size = 4271354, upload-time = "2026-04-08T01:56:49.312Z" }, + { url = "https://files.pythonhosted.org/packages/50/46/cf71e26025c2e767c5609162c866a78e8a2915bbcfa408b7ca495c6140c4/cryptography-46.0.7-cp314-cp314t-manylinux_2_28_ppc64le.whl", hash = "sha256:fbfd0e5f273877695cb93baf14b185f4878128b250cc9f8e617ea0c025dfb022", size = 4905845, upload-time = "2026-04-08T01:56:50.916Z" }, + { url = "https://files.pythonhosted.org/packages/c0/ea/01276740375bac6249d0a971ebdf6b4dc9ead0ee0a34ef3b5a88c1a9b0d4/cryptography-46.0.7-cp314-cp314t-manylinux_2_28_x86_64.whl", hash = "sha256:ffca7aa1d00cf7d6469b988c581598f2259e46215e0140af408966a24cf086ce", size = 4444641, upload-time = "2026-04-08T01:56:52.882Z" }, + { url = "https://files.pythonhosted.org/packages/3d/4c/7d258f169ae71230f25d9f3d06caabcff8c3baf0978e2b7d65e0acac3827/cryptography-46.0.7-cp314-cp314t-manylinux_2_31_armv7l.whl", hash = "sha256:60627cf07e0d9274338521205899337c5d18249db56865f943cbe753aa96f40f", size = 3967749, upload-time = "2026-04-08T01:56:54.597Z" }, + { url = "https://files.pythonhosted.org/packages/b5/2a/2ea0767cad19e71b3530e4cad9605d0b5e338b6a1e72c37c9c1ceb86c333/cryptography-46.0.7-cp314-cp314t-manylinux_2_34_aarch64.whl", hash = "sha256:80406c3065e2c55d7f49a9550fe0c49b3f12e5bfff5dedb727e319e1afb9bf99", size = 4270942, upload-time = "2026-04-08T01:56:56.416Z" }, + { url = "https://files.pythonhosted.org/packages/41/3d/fe14df95a83319af25717677e956567a105bb6ab25641acaa093db79975d/cryptography-46.0.7-cp314-cp314t-manylinux_2_34_ppc64le.whl", hash = "sha256:c5b1ccd1239f48b7151a65bc6dd54bcfcc15e028c8ac126d3fada09db0e07ef1", size = 4871079, upload-time = "2026-04-08T01:56:58.31Z" }, + { url = "https://files.pythonhosted.org/packages/9c/59/4a479e0f36f8f378d397f4eab4c850b4ffb79a2f0d58704b8fa0703ddc11/cryptography-46.0.7-cp314-cp314t-manylinux_2_34_x86_64.whl", hash = "sha256:d5f7520159cd9c2154eb61eb67548ca05c5774d39e9c2c4339fd793fe7d097b2", size = 4443999, upload-time = "2026-04-08T01:57:00.508Z" }, + { url = "https://files.pythonhosted.org/packages/28/17/b59a741645822ec6d04732b43c5d35e4ef58be7bfa84a81e5ae6f05a1d33/cryptography-46.0.7-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:fcd8eac50d9138c1d7fc53a653ba60a2bee81a505f9f8850b6b2888555a45d0e", size = 4399191, upload-time = "2026-04-08T01:57:02.654Z" }, + { url = "https://files.pythonhosted.org/packages/59/6a/bb2e166d6d0e0955f1e9ff70f10ec4b2824c9cfcdb4da772c7dd69cc7d80/cryptography-46.0.7-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:65814c60f8cc400c63131584e3e1fad01235edba2614b61fbfbfa954082db0ee", size = 4655782, upload-time = "2026-04-08T01:57:04.592Z" }, + { url = "https://files.pythonhosted.org/packages/95/b6/3da51d48415bcb63b00dc17c2eff3a651b7c4fed484308d0f19b30e8cb2c/cryptography-46.0.7-cp314-cp314t-win32.whl", hash = "sha256:fdd1736fed309b4300346f88f74cd120c27c56852c3838cab416e7a166f67298", size = 3002227, upload-time = "2026-04-08T01:57:06.91Z" }, + { url = "https://files.pythonhosted.org/packages/32/a8/9f0e4ed57ec9cebe506e58db11ae472972ecb0c659e4d52bbaee80ca340a/cryptography-46.0.7-cp314-cp314t-win_amd64.whl", hash = "sha256:e06acf3c99be55aa3b516397fe42f5855597f430add9c17fa46bf2e0fb34c9bb", size = 3475332, upload-time = "2026-04-08T01:57:08.807Z" }, + { url = "https://files.pythonhosted.org/packages/a7/7f/cd42fc3614386bc0c12f0cb3c4ae1fc2bbca5c9662dfed031514911d513d/cryptography-46.0.7-cp38-abi3-macosx_10_9_universal2.whl", hash = "sha256:462ad5cb1c148a22b2e3bcc5ad52504dff325d17daf5df8d88c17dda1f75f2a4", size = 7165618, upload-time = "2026-04-08T01:57:10.645Z" }, + { url = "https://files.pythonhosted.org/packages/a5/d0/36a49f0262d2319139d2829f773f1b97ef8aef7f97e6e5bd21455e5a8fb5/cryptography-46.0.7-cp38-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:84d4cced91f0f159a7ddacad249cc077e63195c36aac40b4150e7a57e84fffe7", size = 4270628, upload-time = "2026-04-08T01:57:12.885Z" }, + { url = "https://files.pythonhosted.org/packages/8a/6c/1a42450f464dda6ffbe578a911f773e54dd48c10f9895a23a7e88b3e7db5/cryptography-46.0.7-cp38-abi3-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:128c5edfe5e5938b86b03941e94fac9ee793a94452ad1365c9fc3f4f62216832", size = 4415405, upload-time = "2026-04-08T01:57:14.923Z" }, + { url = "https://files.pythonhosted.org/packages/9a/92/4ed714dbe93a066dc1f4b4581a464d2d7dbec9046f7c8b7016f5286329e2/cryptography-46.0.7-cp38-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:5e51be372b26ef4ba3de3c167cd3d1022934bc838ae9eaad7e644986d2a3d163", size = 4272715, upload-time = "2026-04-08T01:57:16.638Z" }, + { url = "https://files.pythonhosted.org/packages/b7/e6/a26b84096eddd51494bba19111f8fffe976f6a09f132706f8f1bf03f51f7/cryptography-46.0.7-cp38-abi3-manylinux_2_28_ppc64le.whl", hash = "sha256:cdf1a610ef82abb396451862739e3fc93b071c844399e15b90726ef7470eeaf2", size = 4918400, upload-time = "2026-04-08T01:57:19.021Z" }, + { url = "https://files.pythonhosted.org/packages/c7/08/ffd537b605568a148543ac3c2b239708ae0bd635064bab41359252ef88ed/cryptography-46.0.7-cp38-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:1d25aee46d0c6f1a501adcddb2d2fee4b979381346a78558ed13e50aa8a59067", size = 4450634, upload-time = "2026-04-08T01:57:21.185Z" }, + { url = "https://files.pythonhosted.org/packages/16/01/0cd51dd86ab5b9befe0d031e276510491976c3a80e9f6e31810cce46c4ad/cryptography-46.0.7-cp38-abi3-manylinux_2_31_armv7l.whl", hash = "sha256:cdfbe22376065ffcf8be74dc9a909f032df19bc58a699456a21712d6e5eabfd0", size = 3985233, upload-time = "2026-04-08T01:57:22.862Z" }, + { url = "https://files.pythonhosted.org/packages/92/49/819d6ed3a7d9349c2939f81b500a738cb733ab62fbecdbc1e38e83d45e12/cryptography-46.0.7-cp38-abi3-manylinux_2_34_aarch64.whl", hash = "sha256:abad9dac36cbf55de6eb49badd4016806b3165d396f64925bf2999bcb67837ba", size = 4271955, upload-time = "2026-04-08T01:57:24.814Z" }, + { url = "https://files.pythonhosted.org/packages/80/07/ad9b3c56ebb95ed2473d46df0847357e01583f4c52a85754d1a55e29e4d0/cryptography-46.0.7-cp38-abi3-manylinux_2_34_ppc64le.whl", hash = "sha256:935ce7e3cfdb53e3536119a542b839bb94ec1ad081013e9ab9b7cfd478b05006", size = 4879888, upload-time = "2026-04-08T01:57:26.88Z" }, + { url = "https://files.pythonhosted.org/packages/b8/c7/201d3d58f30c4c2bdbe9b03844c291feb77c20511cc3586daf7edc12a47b/cryptography-46.0.7-cp38-abi3-manylinux_2_34_x86_64.whl", hash = "sha256:35719dc79d4730d30f1c2b6474bd6acda36ae2dfae1e3c16f2051f215df33ce0", size = 4449961, upload-time = "2026-04-08T01:57:29.068Z" }, + { url = "https://files.pythonhosted.org/packages/a5/ef/649750cbf96f3033c3c976e112265c33906f8e462291a33d77f90356548c/cryptography-46.0.7-cp38-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:7bbc6ccf49d05ac8f7d7b5e2e2c33830d4fe2061def88210a126d130d7f71a85", size = 4401696, upload-time = "2026-04-08T01:57:31.029Z" }, + { url = "https://files.pythonhosted.org/packages/41/52/a8908dcb1a389a459a29008c29966c1d552588d4ae6d43f3a1a4512e0ebe/cryptography-46.0.7-cp38-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:a1529d614f44b863a7b480c6d000fe93b59acee9c82ffa027cfadc77521a9f5e", size = 4664256, upload-time = "2026-04-08T01:57:33.144Z" }, + { url = "https://files.pythonhosted.org/packages/4b/fa/f0ab06238e899cc3fb332623f337a7364f36f4bb3f2534c2bb95a35b132c/cryptography-46.0.7-cp38-abi3-win32.whl", hash = "sha256:f247c8c1a1fb45e12586afbb436ef21ff1e80670b2861a90353d9b025583d246", size = 3013001, upload-time = "2026-04-08T01:57:34.933Z" }, + { url = "https://files.pythonhosted.org/packages/d2/f1/00ce3bde3ca542d1acd8f8cfa38e446840945aa6363f9b74746394b14127/cryptography-46.0.7-cp38-abi3-win_amd64.whl", hash = "sha256:506c4ff91eff4f82bdac7633318a526b1d1309fc07ca76a3ad182cb5b686d6d3", size = 3472985, upload-time = "2026-04-08T01:57:36.714Z" }, +] + +[[package]] +name = "gitdb" +version = "4.0.12" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "smmap" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/72/94/63b0fc47eb32792c7ba1fe1b694daec9a63620db1e313033d18140c2320a/gitdb-4.0.12.tar.gz", hash = "sha256:5ef71f855d191a3326fcfbc0d5da835f26b13fbcba60c32c21091c349ffdb571", size = 394684, upload-time = "2025-01-02T07:20:46.413Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/a0/61/5c78b91c3143ed5c14207f463aecfc8f9dbb5092fb2869baf37c273b2705/gitdb-4.0.12-py3-none-any.whl", hash = "sha256:67073e15955400952c6565cc3e707c554a4eea2e428946f7a4c162fab9bd9bcf", size = 62794, upload-time = "2025-01-02T07:20:43.624Z" }, +] + +[[package]] +name = "gitpython" +version = "3.1.46" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "gitdb" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/df/b5/59d16470a1f0dfe8c793f9ef56fd3826093fc52b3bd96d6b9d6c26c7e27b/gitpython-3.1.46.tar.gz", hash = "sha256:400124c7d0ef4ea03f7310ac2fbf7151e09ff97f2a3288d64a440c584a29c37f", size = 215371, upload-time = "2026-01-01T15:37:32.073Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/6a/09/e21df6aef1e1ffc0c816f0522ddc3f6dcded766c3261813131c78a704470/gitpython-3.1.46-py3-none-any.whl", hash = "sha256:79812ed143d9d25b6d176a10bb511de0f9c67b1fa641d82097b0ab90398a2058", size = 208620, upload-time = "2026-01-01T15:37:30.574Z" }, +] + +[[package]] +name = "google-api-core" +version = "2.30.3" +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/16/ce/502a57fb0ec752026d24df1280b162294b22a0afb98a326084f9a979138b/google_api_core-2.30.3.tar.gz", hash = "sha256:e601a37f148585319b26db36e219df68c5d07b6382cff2d580e83404e44d641b", size = 177001, upload-time = "2026-04-10T00:41:28.035Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/03/15/e56f351cf6ef1cfea58e6ac226a7318ed1deb2218c4b3cc9bd9e4b786c5a/google_api_core-2.30.3-py3-none-any.whl", hash = "sha256:a85761ba72c444dad5d611c2220633480b2b6be2521eca69cca2dbb3ffd6bfe8", size = 173274, upload-time = "2026-04-09T22:57:16.198Z" }, +] + +[[package]] +name = "google-api-python-client" +version = "2.194.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "google-api-core" }, + { name = "google-auth" }, + { name = "google-auth-httplib2" }, + { name = "httplib2" }, + { name = "uritemplate" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/60/ab/e83af0eb043e4ccc49571ca7a6a49984e9d00f4e9e6e6f1238d60bc84dce/google_api_python_client-2.194.0.tar.gz", hash = "sha256:db92647bd1a90f40b79c9618461553c2b20b6a43ce7395fa6de07132dc14f023", size = 14443469, upload-time = "2026-04-08T23:07:35.757Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/b0/34/5a624e49f179aa5b0cb87b2ce8093960299030ff40423bfbde09360eb908/google_api_python_client-2.194.0-py3-none-any.whl", hash = "sha256:61eaaac3b8fc8fdf11c08af87abc3d1342d1b37319cc1b57405f86ef7697e717", size = 15016514, upload-time = "2026-04-08T23:07:33.093Z" }, +] + +[[package]] +name = "google-auth" +version = "2.49.2" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "cryptography" }, + { name = "pyasn1-modules" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/c6/fc/e925290a1ad95c975c459e2df070fac2b90954e13a0370ac505dff78cb99/google_auth-2.49.2.tar.gz", hash = "sha256:c1ae38500e73065dcae57355adb6278cf8b5c8e391994ae9cbadbcb9631ab409", size = 333958, upload-time = "2026-04-10T00:41:21.888Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/73/76/d241a5c927433420507215df6cac1b1fa4ac0ba7a794df42a84326c68da8/google_auth-2.49.2-py3-none-any.whl", hash = "sha256:c2720924dfc82dedb962c9f52cabb2ab16714fd0a6a707e40561d217574ed6d5", size = 240638, upload-time = "2026-04-10T00:41:14.501Z" }, +] + +[[package]] +name = "google-auth-httplib2" +version = "0.3.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "google-auth" }, + { name = "httplib2" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/ed/99/107612bef8d24b298bb5a7c8466f908ecda791d43f9466f5c3978f5b24c1/google_auth_httplib2-0.3.1.tar.gz", hash = "sha256:0af542e815784cb64159b4469aa5d71dd41069ba93effa006e1916b1dcd88e55", size = 11152, upload-time = "2026-03-30T22:50:26.766Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/97/e9/93afb14d23a949acaa3f4e7cc51a0024671174e116e35f42850764b99634/google_auth_httplib2-0.3.1-py3-none-any.whl", hash = "sha256:682356a90ef4ba3d06548c37e9112eea6fc00395a11b0303a644c1a86abc275c", size = 9534, upload-time = "2026-03-30T22:49:03.384Z" }, +] + +[[package]] +name = "google-auth-oauthlib" +version = "1.3.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "google-auth" }, + { name = "requests-oauthlib" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/a6/82/62482931dcbe5266a2680d0da17096f2aab983ecb320277d9556700ce00e/google_auth_oauthlib-1.3.1.tar.gz", hash = "sha256:14c22c7b3dd3d06dbe44264144409039465effdd1eef94f7ce3710e486cc4bfa", size = 21663, upload-time = "2026-03-30T22:49:56.408Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/2a/e0/cb454a95f460903e39f101e950038ec24a072ca69d0a294a6df625cc1627/google_auth_oauthlib-1.3.1-py3-none-any.whl", hash = "sha256:1a139ef23f1318756805b0e95f655c238bffd29655329a2978218248da4ee7f8", size = 19247, upload-time = "2026-03-30T20:02:23.894Z" }, +] + +[[package]] +name = "googleapis-common-protos" +version = "1.74.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "protobuf" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/20/18/a746c8344152d368a5aac738d4c857012f2c5d1fd2eac7e17b647a7861bd/googleapis_common_protos-1.74.0.tar.gz", hash = "sha256:57971e4eeeba6aad1163c1f0fc88543f965bb49129b8bb55b2b7b26ecab084f1", size = 151254, upload-time = "2026-04-02T21:23:26.679Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/b6/b0/be5d3329badb9230b765de6eea66b73abd5944bdeb5afb3562ddcd80ae84/googleapis_common_protos-1.74.0-py3-none-any.whl", hash = "sha256:702216f78610bb510e3f12ac3cafd281b7ac45cc5d86e90ad87e4d301a3426b5", size = 300743, upload-time = "2026-04-02T21:22:49.108Z" }, +] + +[[package]] +name = "httplib2" +version = "0.31.2" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "pyparsing" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/c1/1f/e86365613582c027dda5ddb64e1010e57a3d53e99ab8a72093fa13d565ec/httplib2-0.31.2.tar.gz", hash = "sha256:385e0869d7397484f4eab426197a4c020b606edd43372492337c0b4010ae5d24", size = 250800, upload-time = "2026-01-23T11:04:44.165Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/2f/90/fd509079dfcab01102c0fdd87f3a9506894bc70afcf9e9785ef6b2b3aff6/httplib2-0.31.2-py3-none-any.whl", hash = "sha256:dbf0c2fa3862acf3c55c078ea9c0bc4481d7dc5117cae71be9514912cf9f8349", size = 91099, upload-time = "2026-01-23T11:04:42.78Z" }, +] + +[[package]] +name = "idna" +version = "3.11" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/6f/6d/0703ccc57f3a7233505399edb88de3cbd678da106337b9fcde432b65ed60/idna-3.11.tar.gz", hash = "sha256:795dafcc9c04ed0c1fb032c2aa73654d8e8c5023a7df64a53f39190ada629902", size = 194582, upload-time = "2025-10-12T14:55:20.501Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/0e/61/66938bbb5fc52dbdf84594873d5b51fb1f7c7794e9c0f5bd885f30bc507b/idna-3.11-py3-none-any.whl", hash = "sha256:771a87f49d9defaf64091e6e6fe9c18d4833f140bd19464795bc32d966ca37ea", size = 71008, upload-time = "2025-10-12T14:55:18.883Z" }, +] + +[[package]] +name = "jinja2" +version = "3.1.6" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "markupsafe" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/df/bf/f7da0350254c0ed7c72f3e33cef02e048281fec7ecec5f032d4aac52226b/jinja2-3.1.6.tar.gz", hash = "sha256:0137fb05990d35f1275a587e9aee6d56da821fc83491a0fb838183be43f66d6d", size = 245115, upload-time = "2025-03-05T20:05:02.478Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/62/a1/3d680cbfd5f4b8f15abc1d571870c5fc3e594bb582bc3b64ea099db13e56/jinja2-3.1.6-py3-none-any.whl", hash = "sha256:85ece4451f492d0c13c5dd7c13a64681a86afae63a5f347908daf103ce6d2f67", size = 134899, upload-time = "2025-03-05T20:05:00.369Z" }, +] + +[[package]] +name = "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 = "markupsafe" +version = "3.0.3" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/7e/99/7690b6d4034fffd95959cbe0c02de8deb3098cc577c67bb6a24fe5d7caa7/markupsafe-3.0.3.tar.gz", hash = "sha256:722695808f4b6457b320fdc131280796bdceb04ab50fe1795cd540799ebe1698", size = 80313, upload-time = "2025-09-27T18:37:40.426Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/5a/72/147da192e38635ada20e0a2e1a51cf8823d2119ce8883f7053879c2199b5/markupsafe-3.0.3-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:d53197da72cc091b024dd97249dfc7794d6a56530370992a5e1a08983ad9230e", size = 11615, upload-time = "2025-09-27T18:36:30.854Z" }, + { url = "https://files.pythonhosted.org/packages/9a/81/7e4e08678a1f98521201c3079f77db69fb552acd56067661f8c2f534a718/markupsafe-3.0.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:1872df69a4de6aead3491198eaf13810b565bdbeec3ae2dc8780f14458ec73ce", size = 12020, upload-time = "2025-09-27T18:36:31.971Z" }, + { url = "https://files.pythonhosted.org/packages/1e/2c/799f4742efc39633a1b54a92eec4082e4f815314869865d876824c257c1e/markupsafe-3.0.3-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:3a7e8ae81ae39e62a41ec302f972ba6ae23a5c5396c8e60113e9066ef893da0d", size = 24332, upload-time = "2025-09-27T18:36:32.813Z" }, + { url = "https://files.pythonhosted.org/packages/3c/2e/8d0c2ab90a8c1d9a24f0399058ab8519a3279d1bd4289511d74e909f060e/markupsafe-3.0.3-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:d6dd0be5b5b189d31db7cda48b91d7e0a9795f31430b7f271219ab30f1d3ac9d", size = 22947, upload-time = "2025-09-27T18:36:33.86Z" }, + { url = "https://files.pythonhosted.org/packages/2c/54/887f3092a85238093a0b2154bd629c89444f395618842e8b0c41783898ea/markupsafe-3.0.3-cp312-cp312-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:94c6f0bb423f739146aec64595853541634bde58b2135f27f61c1ffd1cd4d16a", size = 21962, upload-time = "2025-09-27T18:36:35.099Z" }, + { url = "https://files.pythonhosted.org/packages/c9/2f/336b8c7b6f4a4d95e91119dc8521402461b74a485558d8f238a68312f11c/markupsafe-3.0.3-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:be8813b57049a7dc738189df53d69395eba14fb99345e0a5994914a3864c8a4b", size = 23760, upload-time = "2025-09-27T18:36:36.001Z" }, + { url = "https://files.pythonhosted.org/packages/32/43/67935f2b7e4982ffb50a4d169b724d74b62a3964bc1a9a527f5ac4f1ee2b/markupsafe-3.0.3-cp312-cp312-musllinux_1_2_riscv64.whl", hash = "sha256:83891d0e9fb81a825d9a6d61e3f07550ca70a076484292a70fde82c4b807286f", size = 21529, upload-time = "2025-09-27T18:36:36.906Z" }, + { url = "https://files.pythonhosted.org/packages/89/e0/4486f11e51bbba8b0c041098859e869e304d1c261e59244baa3d295d47b7/markupsafe-3.0.3-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:77f0643abe7495da77fb436f50f8dab76dbc6e5fd25d39589a0f1fe6548bfa2b", size = 23015, upload-time = "2025-09-27T18:36:37.868Z" }, + { url = "https://files.pythonhosted.org/packages/2f/e1/78ee7a023dac597a5825441ebd17170785a9dab23de95d2c7508ade94e0e/markupsafe-3.0.3-cp312-cp312-win32.whl", hash = "sha256:d88b440e37a16e651bda4c7c2b930eb586fd15ca7406cb39e211fcff3bf3017d", size = 14540, upload-time = "2025-09-27T18:36:38.761Z" }, + { url = "https://files.pythonhosted.org/packages/aa/5b/bec5aa9bbbb2c946ca2733ef9c4ca91c91b6a24580193e891b5f7dbe8e1e/markupsafe-3.0.3-cp312-cp312-win_amd64.whl", hash = "sha256:26a5784ded40c9e318cfc2bdb30fe164bdb8665ded9cd64d500a34fb42067b1c", size = 15105, upload-time = "2025-09-27T18:36:39.701Z" }, + { url = "https://files.pythonhosted.org/packages/e5/f1/216fc1bbfd74011693a4fd837e7026152e89c4bcf3e77b6692fba9923123/markupsafe-3.0.3-cp312-cp312-win_arm64.whl", hash = "sha256:35add3b638a5d900e807944a078b51922212fb3dedb01633a8defc4b01a3c85f", size = 13906, upload-time = "2025-09-27T18:36:40.689Z" }, + { url = "https://files.pythonhosted.org/packages/38/2f/907b9c7bbba283e68f20259574b13d005c121a0fa4c175f9bed27c4597ff/markupsafe-3.0.3-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:e1cf1972137e83c5d4c136c43ced9ac51d0e124706ee1c8aa8532c1287fa8795", size = 11622, upload-time = "2025-09-27T18:36:41.777Z" }, + { url = "https://files.pythonhosted.org/packages/9c/d9/5f7756922cdd676869eca1c4e3c0cd0df60ed30199ffd775e319089cb3ed/markupsafe-3.0.3-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:116bb52f642a37c115f517494ea5feb03889e04df47eeff5b130b1808ce7c219", size = 12029, upload-time = "2025-09-27T18:36:43.257Z" }, + { url = "https://files.pythonhosted.org/packages/00/07/575a68c754943058c78f30db02ee03a64b3c638586fba6a6dd56830b30a3/markupsafe-3.0.3-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:133a43e73a802c5562be9bbcd03d090aa5a1fe899db609c29e8c8d815c5f6de6", size = 24374, upload-time = "2025-09-27T18:36:44.508Z" }, + { url = "https://files.pythonhosted.org/packages/a9/21/9b05698b46f218fc0e118e1f8168395c65c8a2c750ae2bab54fc4bd4e0e8/markupsafe-3.0.3-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:ccfcd093f13f0f0b7fdd0f198b90053bf7b2f02a3927a30e63f3ccc9df56b676", size = 22980, upload-time = "2025-09-27T18:36:45.385Z" }, + { url = "https://files.pythonhosted.org/packages/7f/71/544260864f893f18b6827315b988c146b559391e6e7e8f7252839b1b846a/markupsafe-3.0.3-cp313-cp313-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:509fa21c6deb7a7a273d629cf5ec029bc209d1a51178615ddf718f5918992ab9", size = 21990, upload-time = "2025-09-27T18:36:46.916Z" }, + { url = "https://files.pythonhosted.org/packages/c2/28/b50fc2f74d1ad761af2f5dcce7492648b983d00a65b8c0e0cb457c82ebbe/markupsafe-3.0.3-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:a4afe79fb3de0b7097d81da19090f4df4f8d3a2b3adaa8764138aac2e44f3af1", size = 23784, upload-time = "2025-09-27T18:36:47.884Z" }, + { url = "https://files.pythonhosted.org/packages/ed/76/104b2aa106a208da8b17a2fb72e033a5a9d7073c68f7e508b94916ed47a9/markupsafe-3.0.3-cp313-cp313-musllinux_1_2_riscv64.whl", hash = "sha256:795e7751525cae078558e679d646ae45574b47ed6e7771863fcc079a6171a0fc", size = 21588, upload-time = "2025-09-27T18:36:48.82Z" }, + { url = "https://files.pythonhosted.org/packages/b5/99/16a5eb2d140087ebd97180d95249b00a03aa87e29cc224056274f2e45fd6/markupsafe-3.0.3-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:8485f406a96febb5140bfeca44a73e3ce5116b2501ac54fe953e488fb1d03b12", size = 23041, upload-time = "2025-09-27T18:36:49.797Z" }, + { url = "https://files.pythonhosted.org/packages/19/bc/e7140ed90c5d61d77cea142eed9f9c303f4c4806f60a1044c13e3f1471d0/markupsafe-3.0.3-cp313-cp313-win32.whl", hash = "sha256:bdd37121970bfd8be76c5fb069c7751683bdf373db1ed6c010162b2a130248ed", size = 14543, upload-time = "2025-09-27T18:36:51.584Z" }, + { url = "https://files.pythonhosted.org/packages/05/73/c4abe620b841b6b791f2edc248f556900667a5a1cf023a6646967ae98335/markupsafe-3.0.3-cp313-cp313-win_amd64.whl", hash = "sha256:9a1abfdc021a164803f4d485104931fb8f8c1efd55bc6b748d2f5774e78b62c5", size = 15113, upload-time = "2025-09-27T18:36:52.537Z" }, + { url = "https://files.pythonhosted.org/packages/f0/3a/fa34a0f7cfef23cf9500d68cb7c32dd64ffd58a12b09225fb03dd37d5b80/markupsafe-3.0.3-cp313-cp313-win_arm64.whl", hash = "sha256:7e68f88e5b8799aa49c85cd116c932a1ac15caaa3f5db09087854d218359e485", size = 13911, upload-time = "2025-09-27T18:36:53.513Z" }, + { url = "https://files.pythonhosted.org/packages/e4/d7/e05cd7efe43a88a17a37b3ae96e79a19e846f3f456fe79c57ca61356ef01/markupsafe-3.0.3-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:218551f6df4868a8d527e3062d0fb968682fe92054e89978594c28e642c43a73", size = 11658, upload-time = "2025-09-27T18:36:54.819Z" }, + { url = "https://files.pythonhosted.org/packages/99/9e/e412117548182ce2148bdeacdda3bb494260c0b0184360fe0d56389b523b/markupsafe-3.0.3-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:3524b778fe5cfb3452a09d31e7b5adefeea8c5be1d43c4f810ba09f2ceb29d37", size = 12066, upload-time = "2025-09-27T18:36:55.714Z" }, + { url = "https://files.pythonhosted.org/packages/bc/e6/fa0ffcda717ef64a5108eaa7b4f5ed28d56122c9a6d70ab8b72f9f715c80/markupsafe-3.0.3-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:4e885a3d1efa2eadc93c894a21770e4bc67899e3543680313b09f139e149ab19", size = 25639, upload-time = "2025-09-27T18:36:56.908Z" }, + { url = "https://files.pythonhosted.org/packages/96/ec/2102e881fe9d25fc16cb4b25d5f5cde50970967ffa5dddafdb771237062d/markupsafe-3.0.3-cp313-cp313t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:8709b08f4a89aa7586de0aadc8da56180242ee0ada3999749b183aa23df95025", size = 23569, upload-time = "2025-09-27T18:36:57.913Z" }, + { url = "https://files.pythonhosted.org/packages/4b/30/6f2fce1f1f205fc9323255b216ca8a235b15860c34b6798f810f05828e32/markupsafe-3.0.3-cp313-cp313t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:b8512a91625c9b3da6f127803b166b629725e68af71f8184ae7e7d54686a56d6", size = 23284, upload-time = "2025-09-27T18:36:58.833Z" }, + { url = "https://files.pythonhosted.org/packages/58/47/4a0ccea4ab9f5dcb6f79c0236d954acb382202721e704223a8aafa38b5c8/markupsafe-3.0.3-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:9b79b7a16f7fedff2495d684f2b59b0457c3b493778c9eed31111be64d58279f", size = 24801, upload-time = "2025-09-27T18:36:59.739Z" }, + { url = "https://files.pythonhosted.org/packages/6a/70/3780e9b72180b6fecb83a4814d84c3bf4b4ae4bf0b19c27196104149734c/markupsafe-3.0.3-cp313-cp313t-musllinux_1_2_riscv64.whl", hash = "sha256:12c63dfb4a98206f045aa9563db46507995f7ef6d83b2f68eda65c307c6829eb", size = 22769, upload-time = "2025-09-27T18:37:00.719Z" }, + { url = "https://files.pythonhosted.org/packages/98/c5/c03c7f4125180fc215220c035beac6b9cb684bc7a067c84fc69414d315f5/markupsafe-3.0.3-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:8f71bc33915be5186016f675cd83a1e08523649b0e33efdb898db577ef5bb009", size = 23642, upload-time = "2025-09-27T18:37:01.673Z" }, + { url = "https://files.pythonhosted.org/packages/80/d6/2d1b89f6ca4bff1036499b1e29a1d02d282259f3681540e16563f27ebc23/markupsafe-3.0.3-cp313-cp313t-win32.whl", hash = "sha256:69c0b73548bc525c8cb9a251cddf1931d1db4d2258e9599c28c07ef3580ef354", size = 14612, upload-time = "2025-09-27T18:37:02.639Z" }, + { url = "https://files.pythonhosted.org/packages/2b/98/e48a4bfba0a0ffcf9925fe2d69240bfaa19c6f7507b8cd09c70684a53c1e/markupsafe-3.0.3-cp313-cp313t-win_amd64.whl", hash = "sha256:1b4b79e8ebf6b55351f0d91fe80f893b4743f104bff22e90697db1590e47a218", size = 15200, upload-time = "2025-09-27T18:37:03.582Z" }, + { url = "https://files.pythonhosted.org/packages/0e/72/e3cc540f351f316e9ed0f092757459afbc595824ca724cbc5a5d4263713f/markupsafe-3.0.3-cp313-cp313t-win_arm64.whl", hash = "sha256:ad2cf8aa28b8c020ab2fc8287b0f823d0a7d8630784c31e9ee5edea20f406287", size = 13973, upload-time = "2025-09-27T18:37:04.929Z" }, + { url = "https://files.pythonhosted.org/packages/33/8a/8e42d4838cd89b7dde187011e97fe6c3af66d8c044997d2183fbd6d31352/markupsafe-3.0.3-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:eaa9599de571d72e2daf60164784109f19978b327a3910d3e9de8c97b5b70cfe", size = 11619, upload-time = "2025-09-27T18:37:06.342Z" }, + { url = "https://files.pythonhosted.org/packages/b5/64/7660f8a4a8e53c924d0fa05dc3a55c9cee10bbd82b11c5afb27d44b096ce/markupsafe-3.0.3-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:c47a551199eb8eb2121d4f0f15ae0f923d31350ab9280078d1e5f12b249e0026", size = 12029, upload-time = "2025-09-27T18:37:07.213Z" }, + { url = "https://files.pythonhosted.org/packages/da/ef/e648bfd021127bef5fa12e1720ffed0c6cbb8310c8d9bea7266337ff06de/markupsafe-3.0.3-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:f34c41761022dd093b4b6896d4810782ffbabe30f2d443ff5f083e0cbbb8c737", size = 24408, upload-time = "2025-09-27T18:37:09.572Z" }, + { url = "https://files.pythonhosted.org/packages/41/3c/a36c2450754618e62008bf7435ccb0f88053e07592e6028a34776213d877/markupsafe-3.0.3-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:457a69a9577064c05a97c41f4e65148652db078a3a509039e64d3467b9e7ef97", size = 23005, upload-time = "2025-09-27T18:37:10.58Z" }, + { url = "https://files.pythonhosted.org/packages/bc/20/b7fdf89a8456b099837cd1dc21974632a02a999ec9bf7ca3e490aacd98e7/markupsafe-3.0.3-cp314-cp314-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:e8afc3f2ccfa24215f8cb28dcf43f0113ac3c37c2f0f0806d8c70e4228c5cf4d", size = 22048, upload-time = "2025-09-27T18:37:11.547Z" }, + { url = "https://files.pythonhosted.org/packages/9a/a7/591f592afdc734f47db08a75793a55d7fbcc6902a723ae4cfbab61010cc5/markupsafe-3.0.3-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:ec15a59cf5af7be74194f7ab02d0f59a62bdcf1a537677ce67a2537c9b87fcda", size = 23821, upload-time = "2025-09-27T18:37:12.48Z" }, + { url = "https://files.pythonhosted.org/packages/7d/33/45b24e4f44195b26521bc6f1a82197118f74df348556594bd2262bda1038/markupsafe-3.0.3-cp314-cp314-musllinux_1_2_riscv64.whl", hash = "sha256:0eb9ff8191e8498cca014656ae6b8d61f39da5f95b488805da4bb029cccbfbaf", size = 21606, upload-time = "2025-09-27T18:37:13.485Z" }, + { url = "https://files.pythonhosted.org/packages/ff/0e/53dfaca23a69fbfbbf17a4b64072090e70717344c52eaaaa9c5ddff1e5f0/markupsafe-3.0.3-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:2713baf880df847f2bece4230d4d094280f4e67b1e813eec43b4c0e144a34ffe", size = 23043, upload-time = "2025-09-27T18:37:14.408Z" }, + { url = "https://files.pythonhosted.org/packages/46/11/f333a06fc16236d5238bfe74daccbca41459dcd8d1fa952e8fbd5dccfb70/markupsafe-3.0.3-cp314-cp314-win32.whl", hash = "sha256:729586769a26dbceff69f7a7dbbf59ab6572b99d94576a5592625d5b411576b9", size = 14747, upload-time = "2025-09-27T18:37:15.36Z" }, + { url = "https://files.pythonhosted.org/packages/28/52/182836104b33b444e400b14f797212f720cbc9ed6ba34c800639d154e821/markupsafe-3.0.3-cp314-cp314-win_amd64.whl", hash = "sha256:bdc919ead48f234740ad807933cdf545180bfbe9342c2bb451556db2ed958581", size = 15341, upload-time = "2025-09-27T18:37:16.496Z" }, + { url = "https://files.pythonhosted.org/packages/6f/18/acf23e91bd94fd7b3031558b1f013adfa21a8e407a3fdb32745538730382/markupsafe-3.0.3-cp314-cp314-win_arm64.whl", hash = "sha256:5a7d5dc5140555cf21a6fefbdbf8723f06fcd2f63ef108f2854de715e4422cb4", size = 14073, upload-time = "2025-09-27T18:37:17.476Z" }, + { url = "https://files.pythonhosted.org/packages/3c/f0/57689aa4076e1b43b15fdfa646b04653969d50cf30c32a102762be2485da/markupsafe-3.0.3-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:1353ef0c1b138e1907ae78e2f6c63ff67501122006b0f9abad68fda5f4ffc6ab", size = 11661, upload-time = "2025-09-27T18:37:18.453Z" }, + { url = "https://files.pythonhosted.org/packages/89/c3/2e67a7ca217c6912985ec766c6393b636fb0c2344443ff9d91404dc4c79f/markupsafe-3.0.3-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:1085e7fbddd3be5f89cc898938f42c0b3c711fdcb37d75221de2666af647c175", size = 12069, upload-time = "2025-09-27T18:37:19.332Z" }, + { url = "https://files.pythonhosted.org/packages/f0/00/be561dce4e6ca66b15276e184ce4b8aec61fe83662cce2f7d72bd3249d28/markupsafe-3.0.3-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:1b52b4fb9df4eb9ae465f8d0c228a00624de2334f216f178a995ccdcf82c4634", size = 25670, upload-time = "2025-09-27T18:37:20.245Z" }, + { url = "https://files.pythonhosted.org/packages/50/09/c419f6f5a92e5fadde27efd190eca90f05e1261b10dbd8cbcb39cd8ea1dc/markupsafe-3.0.3-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:fed51ac40f757d41b7c48425901843666a6677e3e8eb0abcff09e4ba6e664f50", size = 23598, upload-time = "2025-09-27T18:37:21.177Z" }, + { url = "https://files.pythonhosted.org/packages/22/44/a0681611106e0b2921b3033fc19bc53323e0b50bc70cffdd19f7d679bb66/markupsafe-3.0.3-cp314-cp314t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:f190daf01f13c72eac4efd5c430a8de82489d9cff23c364c3ea822545032993e", size = 23261, upload-time = "2025-09-27T18:37:22.167Z" }, + { url = "https://files.pythonhosted.org/packages/5f/57/1b0b3f100259dc9fffe780cfb60d4be71375510e435efec3d116b6436d43/markupsafe-3.0.3-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:e56b7d45a839a697b5eb268c82a71bd8c7f6c94d6fd50c3d577fa39a9f1409f5", size = 24835, upload-time = "2025-09-27T18:37:23.296Z" }, + { url = "https://files.pythonhosted.org/packages/26/6a/4bf6d0c97c4920f1597cc14dd720705eca0bf7c787aebc6bb4d1bead5388/markupsafe-3.0.3-cp314-cp314t-musllinux_1_2_riscv64.whl", hash = "sha256:f3e98bb3798ead92273dc0e5fd0f31ade220f59a266ffd8a4f6065e0a3ce0523", size = 22733, upload-time = "2025-09-27T18:37:24.237Z" }, + { url = "https://files.pythonhosted.org/packages/14/c7/ca723101509b518797fedc2fdf79ba57f886b4aca8a7d31857ba3ee8281f/markupsafe-3.0.3-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:5678211cb9333a6468fb8d8be0305520aa073f50d17f089b5b4b477ea6e67fdc", size = 23672, upload-time = "2025-09-27T18:37:25.271Z" }, + { url = "https://files.pythonhosted.org/packages/fb/df/5bd7a48c256faecd1d36edc13133e51397e41b73bb77e1a69deab746ebac/markupsafe-3.0.3-cp314-cp314t-win32.whl", hash = "sha256:915c04ba3851909ce68ccc2b8e2cd691618c4dc4c4232fb7982bca3f41fd8c3d", size = 14819, upload-time = "2025-09-27T18:37:26.285Z" }, + { url = "https://files.pythonhosted.org/packages/1a/8a/0402ba61a2f16038b48b39bccca271134be00c5c9f0f623208399333c448/markupsafe-3.0.3-cp314-cp314t-win_amd64.whl", hash = "sha256:4faffd047e07c38848ce017e8725090413cd80cbc23d86e55c587bf979e579c9", size = 15426, upload-time = "2025-09-27T18:37:27.316Z" }, + { url = "https://files.pythonhosted.org/packages/70/bc/6f1c2f612465f5fa89b95bead1f44dcb607670fd42891d8fdcd5d039f4f4/markupsafe-3.0.3-cp314-cp314t-win_arm64.whl", hash = "sha256:32001d6a8fc98c8cb5c947787c5d08b0a50663d139f1305bac5885d98d9b40fa", size = 14146, upload-time = "2025-09-27T18:37:28.327Z" }, +] + +[[package]] +name = "narwhals" +version = "2.19.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/4e/1a/bd3317c0bdbcd9ffb710ddf5250b32898f8f2c240be99494fe137feb77a7/narwhals-2.19.0.tar.gz", hash = "sha256:14fd7040b5ff211d415a82e4827b9d04c354e213e72a6d0730205ffd72e3b7ff", size = 623698, upload-time = "2026-04-06T15:50:58.786Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/37/72/e61e3091e0e00fae9d3a8ef85ece9d2cd4b5966058e1f2901ce42679eebf/narwhals-2.19.0-py3-none-any.whl", hash = "sha256:1f8dfa4a33a6dbff878c3e9be4c3b455dfcaf2a9322f1357db00e4e92e95b84b", size = 446991, upload-time = "2026-04-06T15:50:57.046Z" }, +] + +[[package]] +name = "numpy" +version = "2.4.4" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/d7/9f/b8cef5bffa569759033adda9481211426f12f53299629b410340795c2514/numpy-2.4.4.tar.gz", hash = "sha256:2d390634c5182175533585cc89f3608a4682ccb173cc9bb940b2881c8d6f8fa0", size = 20731587, upload-time = "2026-03-29T13:22:01.298Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/28/05/32396bec30fb2263770ee910142f49c1476d08e8ad41abf8403806b520ce/numpy-2.4.4-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:15716cfef24d3a9762e3acdf87e27f58dc823d1348f765bbea6bef8c639bfa1b", size = 16689272, upload-time = "2026-03-29T13:18:49.223Z" }, + { url = "https://files.pythonhosted.org/packages/c5/f3/a983d28637bfcd763a9c7aafdb6d5c0ebf3d487d1e1459ffdb57e2f01117/numpy-2.4.4-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:23cbfd4c17357c81021f21540da84ee282b9c8fba38a03b7b9d09ba6b951421e", size = 14699573, upload-time = "2026-03-29T13:18:52.629Z" }, + { url = "https://files.pythonhosted.org/packages/9b/fd/e5ecca1e78c05106d98028114f5c00d3eddb41207686b2b7de3e477b0e22/numpy-2.4.4-cp312-cp312-macosx_14_0_arm64.whl", hash = "sha256:8b3b60bb7cba2c8c81837661c488637eee696f59a877788a396d33150c35d842", size = 5204782, upload-time = "2026-03-29T13:18:55.579Z" }, + { url = "https://files.pythonhosted.org/packages/de/2f/702a4594413c1a8632092beae8aba00f1d67947389369b3777aed783fdca/numpy-2.4.4-cp312-cp312-macosx_14_0_x86_64.whl", hash = "sha256:e4a010c27ff6f210ff4c6ef34394cd61470d01014439b192ec22552ee867f2a8", size = 6552038, upload-time = "2026-03-29T13:18:57.769Z" }, + { url = "https://files.pythonhosted.org/packages/7f/37/eed308a8f56cba4d1fdf467a4fc67ef4ff4bf1c888f5fc980481890104b1/numpy-2.4.4-cp312-cp312-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:f9e75681b59ddaa5e659898085ae0eaea229d054f2ac0c7e563a62205a700121", size = 15670666, upload-time = "2026-03-29T13:19:00.341Z" }, + { url = "https://files.pythonhosted.org/packages/0a/0d/0e3ecece05b7a7e87ab9fb587855548da437a061326fff64a223b6dcb78a/numpy-2.4.4-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:81f4a14bee47aec54f883e0cad2d73986640c1590eb9bfaaba7ad17394481e6e", size = 16645480, upload-time = "2026-03-29T13:19:03.63Z" }, + { url = "https://files.pythonhosted.org/packages/34/49/f2312c154b82a286758ee2f1743336d50651f8b5195db18cdb63675ff649/numpy-2.4.4-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:62d6b0f03b694173f9fcb1fb317f7222fd0b0b103e784c6549f5e53a27718c44", size = 17020036, upload-time = "2026-03-29T13:19:07.428Z" }, + { url = "https://files.pythonhosted.org/packages/7b/e9/736d17bd77f1b0ec4f9901aaec129c00d59f5d84d5e79bba540ef12c2330/numpy-2.4.4-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:fbc356aae7adf9e6336d336b9c8111d390a05df88f1805573ebb0807bd06fd1d", size = 18368643, upload-time = "2026-03-29T13:19:10.775Z" }, + { url = "https://files.pythonhosted.org/packages/63/f6/d417977c5f519b17c8a5c3bc9e8304b0908b0e21136fe43bf628a1343914/numpy-2.4.4-cp312-cp312-win32.whl", hash = "sha256:0d35aea54ad1d420c812bfa0385c71cd7cc5bcf7c65fed95fc2cd02fe8c79827", size = 5961117, upload-time = "2026-03-29T13:19:13.464Z" }, + { url = "https://files.pythonhosted.org/packages/2d/5b/e1deebf88ff431b01b7406ca3583ab2bbb90972bbe1c568732e49c844f7e/numpy-2.4.4-cp312-cp312-win_amd64.whl", hash = "sha256:b5f0362dc928a6ecd9db58868fca5e48485205e3855957bdedea308f8672ea4a", size = 12320584, upload-time = "2026-03-29T13:19:16.155Z" }, + { url = "https://files.pythonhosted.org/packages/58/89/e4e856ac82a68c3ed64486a544977d0e7bdd18b8da75b78a577ca31c4395/numpy-2.4.4-cp312-cp312-win_arm64.whl", hash = "sha256:846300f379b5b12cc769334464656bc882e0735d27d9726568bc932fdc49d5ec", size = 10221450, upload-time = "2026-03-29T13:19:18.994Z" }, + { url = "https://files.pythonhosted.org/packages/14/1d/d0a583ce4fefcc3308806a749a536c201ed6b5ad6e1322e227ee4848979d/numpy-2.4.4-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:08f2e31ed5e6f04b118e49821397f12767934cfdd12a1ce86a058f91e004ee50", size = 16684933, upload-time = "2026-03-29T13:19:22.47Z" }, + { url = "https://files.pythonhosted.org/packages/c1/62/2b7a48fbb745d344742c0277f01286dead15f3f68e4f359fbfcf7b48f70f/numpy-2.4.4-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:e823b8b6edc81e747526f70f71a9c0a07ac4e7ad13020aa736bb7c9d67196115", size = 14694532, upload-time = "2026-03-29T13:19:25.581Z" }, + { url = "https://files.pythonhosted.org/packages/e5/87/499737bfba066b4a3bebff24a8f1c5b2dee410b209bc6668c9be692580f0/numpy-2.4.4-cp313-cp313-macosx_14_0_arm64.whl", hash = "sha256:4a19d9dba1a76618dd86b164d608566f393f8ec6ac7c44f0cc879011c45e65af", size = 5199661, upload-time = "2026-03-29T13:19:28.31Z" }, + { url = "https://files.pythonhosted.org/packages/cd/da/464d551604320d1491bc345efed99b4b7034143a85787aab78d5691d5a0e/numpy-2.4.4-cp313-cp313-macosx_14_0_x86_64.whl", hash = "sha256:d2a8490669bfe99a233298348acc2d824d496dee0e66e31b66a6022c2ad74a5c", size = 6547539, upload-time = "2026-03-29T13:19:30.97Z" }, + { url = "https://files.pythonhosted.org/packages/7d/90/8d23e3b0dafd024bf31bdec225b3bb5c2dbfa6912f8a53b8659f21216cbf/numpy-2.4.4-cp313-cp313-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:45dbed2ab436a9e826e302fcdcbe9133f9b0006e5af7168afb8963a6520da103", size = 15668806, upload-time = "2026-03-29T13:19:33.887Z" }, + { url = "https://files.pythonhosted.org/packages/d1/73/a9d864e42a01896bb5974475438f16086be9ba1f0d19d0bb7a07427c4a8b/numpy-2.4.4-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c901b15172510173f5cb310eae652908340f8dede90fff9e3bf6c0d8dfd92f83", size = 16632682, upload-time = "2026-03-29T13:19:37.336Z" }, + { url = "https://files.pythonhosted.org/packages/34/fb/14570d65c3bde4e202a031210475ae9cde9b7686a2e7dc97ee67d2833b35/numpy-2.4.4-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:99d838547ace2c4aace6c4f76e879ddfe02bb58a80c1549928477862b7a6d6ed", size = 17019810, upload-time = "2026-03-29T13:19:40.963Z" }, + { url = "https://files.pythonhosted.org/packages/8a/77/2ba9d87081fd41f6d640c83f26fb7351e536b7ce6dd9061b6af5904e8e46/numpy-2.4.4-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:0aec54fd785890ecca25a6003fd9a5aed47ad607bbac5cd64f836ad8666f4959", size = 18357394, upload-time = "2026-03-29T13:19:44.859Z" }, + { url = "https://files.pythonhosted.org/packages/a2/23/52666c9a41708b0853fa3b1a12c90da38c507a3074883823126d4e9d5b30/numpy-2.4.4-cp313-cp313-win32.whl", hash = "sha256:07077278157d02f65c43b1b26a3886bce886f95d20aabd11f87932750dfb14ed", size = 5959556, upload-time = "2026-03-29T13:19:47.661Z" }, + { url = "https://files.pythonhosted.org/packages/57/fb/48649b4971cde70d817cf97a2a2fdc0b4d8308569f1dd2f2611959d2e0cf/numpy-2.4.4-cp313-cp313-win_amd64.whl", hash = "sha256:5c70f1cc1c4efbe316a572e2d8b9b9cc44e89b95f79ca3331553fbb63716e2bf", size = 12317311, upload-time = "2026-03-29T13:19:50.67Z" }, + { url = "https://files.pythonhosted.org/packages/ba/d8/11490cddd564eb4de97b4579ef6bfe6a736cc07e94c1598590ae25415e01/numpy-2.4.4-cp313-cp313-win_arm64.whl", hash = "sha256:ef4059d6e5152fa1a39f888e344c73fdc926e1b2dd58c771d67b0acfbf2aa67d", size = 10222060, upload-time = "2026-03-29T13:19:54.229Z" }, + { url = "https://files.pythonhosted.org/packages/99/5d/dab4339177a905aad3e2221c915b35202f1ec30d750dd2e5e9d9a72b804b/numpy-2.4.4-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:4bbc7f303d125971f60ec0aaad5e12c62d0d2c925f0ab1273debd0e4ba37aba5", size = 14822302, upload-time = "2026-03-29T13:19:57.585Z" }, + { url = "https://files.pythonhosted.org/packages/eb/e4/0564a65e7d3d97562ed6f9b0fd0fb0a6f559ee444092f105938b50043876/numpy-2.4.4-cp313-cp313t-macosx_14_0_arm64.whl", hash = "sha256:4d6d57903571f86180eb98f8f0c839fa9ebbfb031356d87f1361be91e433f5b7", size = 5327407, upload-time = "2026-03-29T13:20:00.601Z" }, + { url = "https://files.pythonhosted.org/packages/29/8d/35a3a6ce5ad371afa58b4700f1c820f8f279948cca32524e0a695b0ded83/numpy-2.4.4-cp313-cp313t-macosx_14_0_x86_64.whl", hash = "sha256:4636de7fd195197b7535f231b5de9e4b36d2c440b6e566d2e4e4746e6af0ca93", size = 6647631, upload-time = "2026-03-29T13:20:02.855Z" }, + { url = "https://files.pythonhosted.org/packages/f4/da/477731acbd5a58a946c736edfdabb2ac5b34c3d08d1ba1a7b437fa0884df/numpy-2.4.4-cp313-cp313t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ad2e2ef14e0b04e544ea2fa0a36463f847f113d314aa02e5b402fdf910ef309e", size = 15727691, upload-time = "2026-03-29T13:20:06.004Z" }, + { url = "https://files.pythonhosted.org/packages/e6/db/338535d9b152beabeb511579598418ba0212ce77cf9718edd70262cc4370/numpy-2.4.4-cp313-cp313t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:5a285b3b96f951841799528cd1f4f01cd70e7e0204b4abebac9463eecfcf2a40", size = 16681241, upload-time = "2026-03-29T13:20:09.417Z" }, + { url = "https://files.pythonhosted.org/packages/e2/a9/ad248e8f58beb7a0219b413c9c7d8151c5d285f7f946c3e26695bdbbe2df/numpy-2.4.4-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:f8474c4241bc18b750be2abea9d7a9ec84f46ef861dbacf86a4f6e043401f79e", size = 17085767, upload-time = "2026-03-29T13:20:13.126Z" }, + { url = "https://files.pythonhosted.org/packages/b5/1a/3b88ccd3694681356f70da841630e4725a7264d6a885c8d442a697e1146b/numpy-2.4.4-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:4e874c976154687c1f71715b034739b45c7711bec81db01914770373d125e392", size = 18403169, upload-time = "2026-03-29T13:20:17.096Z" }, + { url = "https://files.pythonhosted.org/packages/c2/c9/fcfd5d0639222c6eac7f304829b04892ef51c96a75d479214d77e3ce6e33/numpy-2.4.4-cp313-cp313t-win32.whl", hash = "sha256:9c585a1790d5436a5374bac930dad6ed244c046ed91b2b2a3634eb2971d21008", size = 6083477, upload-time = "2026-03-29T13:20:20.195Z" }, + { url = "https://files.pythonhosted.org/packages/d5/e3/3938a61d1c538aaec8ed6fd6323f57b0c2d2d2219512434c5c878db76553/numpy-2.4.4-cp313-cp313t-win_amd64.whl", hash = "sha256:93e15038125dc1e5345d9b5b68aa7f996ec33b98118d18c6ca0d0b7d6198b7e8", size = 12457487, upload-time = "2026-03-29T13:20:22.946Z" }, + { url = "https://files.pythonhosted.org/packages/97/6a/7e345032cc60501721ef94e0e30b60f6b0bd601f9174ebd36389a2b86d40/numpy-2.4.4-cp313-cp313t-win_arm64.whl", hash = "sha256:0dfd3f9d3adbe2920b68b5cd3d51444e13a10792ec7154cd0a2f6e74d4ab3233", size = 10292002, upload-time = "2026-03-29T13:20:25.909Z" }, + { url = "https://files.pythonhosted.org/packages/6e/06/c54062f85f673dd5c04cbe2f14c3acb8c8b95e3384869bb8cc9bff8cb9df/numpy-2.4.4-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:f169b9a863d34f5d11b8698ead99febeaa17a13ca044961aa8e2662a6c7766a0", size = 16684353, upload-time = "2026-03-29T13:20:29.504Z" }, + { url = "https://files.pythonhosted.org/packages/4c/39/8a320264a84404c74cc7e79715de85d6130fa07a0898f67fb5cd5bd79908/numpy-2.4.4-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:2483e4584a1cb3092da4470b38866634bafb223cbcd551ee047633fd2584599a", size = 14704914, upload-time = "2026-03-29T13:20:33.547Z" }, + { url = "https://files.pythonhosted.org/packages/91/fb/287076b2614e1d1044235f50f03748f31fa287e3dbe6abeb35cdfa351eca/numpy-2.4.4-cp314-cp314-macosx_14_0_arm64.whl", hash = "sha256:2d19e6e2095506d1736b7d80595e0f252d76b89f5e715c35e06e937679ea7d7a", size = 5210005, upload-time = "2026-03-29T13:20:36.45Z" }, + { url = "https://files.pythonhosted.org/packages/63/eb/fcc338595309910de6ecabfcef2419a9ce24399680bfb149421fa2df1280/numpy-2.4.4-cp314-cp314-macosx_14_0_x86_64.whl", hash = "sha256:6a246d5914aa1c820c9443ddcee9c02bec3e203b0c080349533fae17727dfd1b", size = 6544974, upload-time = "2026-03-29T13:20:39.014Z" }, + { url = "https://files.pythonhosted.org/packages/44/5d/e7e9044032a716cdfaa3fba27a8e874bf1c5f1912a1ddd4ed071bf8a14a6/numpy-2.4.4-cp314-cp314-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:989824e9faf85f96ec9c7761cd8d29c531ad857bfa1daa930cba85baaecf1a9a", size = 15684591, upload-time = "2026-03-29T13:20:42.146Z" }, + { url = "https://files.pythonhosted.org/packages/98/7c/21252050676612625449b4807d6b695b9ce8a7c9e1c197ee6216c8a65c7c/numpy-2.4.4-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:27a8d92cd10f1382a67d7cf4db7ce18341b66438bdd9f691d7b0e48d104c2a9d", size = 16637700, upload-time = "2026-03-29T13:20:46.204Z" }, + { url = "https://files.pythonhosted.org/packages/b1/29/56d2bbef9465db24ef25393383d761a1af4f446a1df9b8cded4fe3a5a5d7/numpy-2.4.4-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:e44319a2953c738205bf3354537979eaa3998ed673395b964c1176083dd46252", size = 17035781, upload-time = "2026-03-29T13:20:50.242Z" }, + { url = "https://files.pythonhosted.org/packages/e3/2b/a35a6d7589d21f44cea7d0a98de5ddcbb3d421b2622a5c96b1edf18707c3/numpy-2.4.4-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:e892aff75639bbef0d2a2cfd55535510df26ff92f63c92cd84ef8d4ba5a5557f", size = 18362959, upload-time = "2026-03-29T13:20:54.019Z" }, + { url = "https://files.pythonhosted.org/packages/64/c9/d52ec581f2390e0f5f85cbfd80fb83d965fc15e9f0e1aec2195faa142cde/numpy-2.4.4-cp314-cp314-win32.whl", hash = "sha256:1378871da56ca8943c2ba674530924bb8ca40cd228358a3b5f302ad60cf875fc", size = 6008768, upload-time = "2026-03-29T13:20:56.912Z" }, + { url = "https://files.pythonhosted.org/packages/fa/22/4cc31a62a6c7b74a8730e31a4274c5dc80e005751e277a2ce38e675e4923/numpy-2.4.4-cp314-cp314-win_amd64.whl", hash = "sha256:715d1c092715954784bc79e1174fc2a90093dc4dc84ea15eb14dad8abdcdeb74", size = 12449181, upload-time = "2026-03-29T13:20:59.548Z" }, + { url = "https://files.pythonhosted.org/packages/70/2e/14cda6f4d8e396c612d1bf97f22958e92148801d7e4f110cabebdc0eef4b/numpy-2.4.4-cp314-cp314-win_arm64.whl", hash = "sha256:2c194dd721e54ecad9ad387c1d35e63dce5c4450c6dc7dd5611283dda239aabb", size = 10496035, upload-time = "2026-03-29T13:21:02.524Z" }, + { url = "https://files.pythonhosted.org/packages/b1/e8/8fed8c8d848d7ecea092dc3469643f9d10bc3a134a815a3b033da1d2039b/numpy-2.4.4-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:2aa0613a5177c264ff5921051a5719d20095ea586ca88cc802c5c218d1c67d3e", size = 14824958, upload-time = "2026-03-29T13:21:05.671Z" }, + { url = "https://files.pythonhosted.org/packages/05/1a/d8007a5138c179c2bf33ef44503e83d70434d2642877ee8fbb230e7c0548/numpy-2.4.4-cp314-cp314t-macosx_14_0_arm64.whl", hash = "sha256:42c16925aa5a02362f986765f9ebabf20de75cdefdca827d14315c568dcab113", size = 5330020, upload-time = "2026-03-29T13:21:08.635Z" }, + { url = "https://files.pythonhosted.org/packages/99/64/ffb99ac6ae93faf117bcbd5c7ba48a7f45364a33e8e458545d3633615dda/numpy-2.4.4-cp314-cp314t-macosx_14_0_x86_64.whl", hash = "sha256:874f200b2a981c647340f841730fc3a2b54c9d940566a3c4149099591e2c4c3d", size = 6650758, upload-time = "2026-03-29T13:21:10.949Z" }, + { url = "https://files.pythonhosted.org/packages/6e/6e/795cc078b78a384052e73b2f6281ff7a700e9bf53bcce2ee579d4f6dd879/numpy-2.4.4-cp314-cp314t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:c9b39d38a9bd2ae1becd7eac1303d031c5c110ad31f2b319c6e7d98b135c934d", size = 15729948, upload-time = "2026-03-29T13:21:14.047Z" }, + { url = "https://files.pythonhosted.org/packages/5f/86/2acbda8cc2af5f3d7bfc791192863b9e3e19674da7b5e533fded124d1299/numpy-2.4.4-cp314-cp314t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:b268594bccac7d7cf5844c7732e3f20c50921d94e36d7ec9b79e9857694b1b2f", size = 16679325, upload-time = "2026-03-29T13:21:17.561Z" }, + { url = "https://files.pythonhosted.org/packages/bc/59/cafd83018f4aa55e0ac6fa92aa066c0a1877b77a615ceff1711c260ffae8/numpy-2.4.4-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:ac6b31e35612a26483e20750126d30d0941f949426974cace8e6b5c58a3657b0", size = 17084883, upload-time = "2026-03-29T13:21:21.106Z" }, + { url = "https://files.pythonhosted.org/packages/f0/85/a42548db84e65ece46ab2caea3d3f78b416a47af387fcbb47ec28e660dc2/numpy-2.4.4-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:8e3ed142f2728df44263aaf5fb1f5b0b99f4070c553a0d7f033be65338329150", size = 18403474, upload-time = "2026-03-29T13:21:24.828Z" }, + { url = "https://files.pythonhosted.org/packages/ed/ad/483d9e262f4b831000062e5d8a45e342166ec8aaa1195264982bca267e62/numpy-2.4.4-cp314-cp314t-win32.whl", hash = "sha256:dddbbd259598d7240b18c9d87c56a9d2fb3b02fe266f49a7c101532e78c1d871", size = 6155500, upload-time = "2026-03-29T13:21:28.205Z" }, + { url = "https://files.pythonhosted.org/packages/c7/03/2fc4e14c7bd4ff2964b74ba90ecb8552540b6315f201df70f137faa5c589/numpy-2.4.4-cp314-cp314t-win_amd64.whl", hash = "sha256:a7164afb23be6e37ad90b2f10426149fd75aee07ca55653d2aa41e66c4ef697e", size = 12637755, upload-time = "2026-03-29T13:21:31.107Z" }, + { url = "https://files.pythonhosted.org/packages/58/78/548fb8e07b1a341746bfbecb32f2c268470f45fa028aacdbd10d9bc73aab/numpy-2.4.4-cp314-cp314t-win_arm64.whl", hash = "sha256:ba203255017337d39f89bdd58417f03c4426f12beed0440cfd933cb15f8669c7", size = 10566643, upload-time = "2026-03-29T13:21:34.339Z" }, +] + +[[package]] +name = "oauthlib" +version = "3.3.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/0b/5f/19930f824ffeb0ad4372da4812c50edbd1434f678c90c2733e1188edfc63/oauthlib-3.3.1.tar.gz", hash = "sha256:0f0f8aa759826a193cf66c12ea1af1637f87b9b4622d46e866952bb022e538c9", size = 185918, upload-time = "2025-06-19T22:48:08.269Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/be/9c/92789c596b8df838baa98fa71844d84283302f7604ed565dafe5a6b5041a/oauthlib-3.3.1-py3-none-any.whl", hash = "sha256:88119c938d2b8fb88561af5f6ee0eec8cc8d552b7bb1f712743136eb7523b7a1", size = 160065, upload-time = "2025-06-19T22:48:06.508Z" }, +] + +[[package]] +name = "packaging" +version = "26.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/65/ee/299d360cdc32edc7d2cf530f3accf79c4fca01e96ffc950d8a52213bd8e4/packaging-26.0.tar.gz", hash = "sha256:00243ae351a257117b6a241061796684b084ed1c516a08c48a3f7e147a9d80b4", size = 143416, upload-time = "2026-01-21T20:50:39.064Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/b7/b9/c538f279a4e237a006a2c98387d081e9eb060d203d8ed34467cc0f0b9b53/packaging-26.0-py3-none-any.whl", hash = "sha256:b36f1fef9334a5588b4166f8bcd26a14e521f2b55e6b9de3aaa80d3ff7a37529", size = 74366, upload-time = "2026-01-21T20:50:37.788Z" }, +] + +[[package]] +name = "pandas" +version = "3.0.2" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "numpy" }, + { name = "python-dateutil" }, + { name = "tzdata", marker = "sys_platform == 'emscripten' or sys_platform == 'win32'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/da/99/b342345300f13440fe9fe385c3c481e2d9a595ee3bab4d3219247ac94e9a/pandas-3.0.2.tar.gz", hash = "sha256:f4753e73e34c8d83221ba58f232433fca2748be8b18dbca02d242ed153945043", size = 4645855, upload-time = "2026-03-31T06:48:30.816Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/f3/b0/c20bd4d6d3f736e6bd6b55794e9cd0a617b858eaad27c8f410ea05d953b7/pandas-3.0.2-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:232a70ebb568c0c4d2db4584f338c1577d81e3af63292208d615907b698a0f18", size = 10347921, upload-time = "2026-03-31T06:46:33.36Z" }, + { url = "https://files.pythonhosted.org/packages/35/d0/4831af68ce30cc2d03c697bea8450e3225a835ef497d0d70f31b8cdde965/pandas-3.0.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:970762605cff1ca0d3f71ed4f3a769ea8f85fc8e6348f6e110b8fea7e6eb5a14", size = 9888127, upload-time = "2026-03-31T06:46:36.253Z" }, + { url = "https://files.pythonhosted.org/packages/61/a9/16ea9346e1fc4a96e2896242d9bc674764fb9049b0044c0132502f7a771e/pandas-3.0.2-cp312-cp312-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:aff4e6f4d722e0652707d7bcb190c445fe58428500c6d16005b02401764b1b3d", size = 10399577, upload-time = "2026-03-31T06:46:39.224Z" }, + { url = "https://files.pythonhosted.org/packages/c4/a8/3a61a721472959ab0ce865ef05d10b0d6bfe27ce8801c99f33d4fa996e65/pandas-3.0.2-cp312-cp312-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:ef8b27695c3d3dc78403c9a7d5e59a62d5464a7e1123b4e0042763f7104dc74f", size = 10880030, upload-time = "2026-03-31T06:46:42.412Z" }, + { url = "https://files.pythonhosted.org/packages/da/65/7225c0ea4d6ce9cb2160a7fb7f39804871049f016e74782e5dade4d14109/pandas-3.0.2-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:f8d68083e49e16b84734eb1a4dcae4259a75c90fb6e2251ab9a00b61120c06ab", size = 11409468, upload-time = "2026-03-31T06:46:45.2Z" }, + { url = "https://files.pythonhosted.org/packages/fa/5b/46e7c76032639f2132359b5cf4c785dd8cf9aea5ea64699eac752f02b9db/pandas-3.0.2-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:32cc41f310ebd4a296d93515fcac312216adfedb1894e879303987b8f1e2b97d", size = 11936381, upload-time = "2026-03-31T06:46:48.293Z" }, + { url = "https://files.pythonhosted.org/packages/7b/8b/721a9cff6fa6a91b162eb51019c6243b82b3226c71bb6c8ef4a9bd65cbc6/pandas-3.0.2-cp312-cp312-win_amd64.whl", hash = "sha256:a4785e1d6547d8427c5208b748ae2efb64659a21bd82bf440d4262d02bfa02a4", size = 9744993, upload-time = "2026-03-31T06:46:51.488Z" }, + { url = "https://files.pythonhosted.org/packages/d5/18/7f0bd34ae27b28159aa80f2a6799f47fda34f7fb938a76e20c7b7fe3b200/pandas-3.0.2-cp312-cp312-win_arm64.whl", hash = "sha256:08504503f7101300107ecdc8df73658e4347586db5cfdadabc1592e9d7e7a0fd", size = 9056118, upload-time = "2026-03-31T06:46:54.548Z" }, + { url = "https://files.pythonhosted.org/packages/bf/ca/3e639a1ea6fcd0617ca4e8ca45f62a74de33a56ae6cd552735470b22c8d3/pandas-3.0.2-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:b5918ba197c951dec132b0c5929a00c0bf05d5942f590d3c10a807f6e15a57d3", size = 10321105, upload-time = "2026-03-31T06:46:57.327Z" }, + { url = "https://files.pythonhosted.org/packages/0b/77/dbc82ff2fb0e63c6564356682bf201edff0ba16c98630d21a1fb312a8182/pandas-3.0.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:d606a041c89c0a474a4702d532ab7e73a14fe35c8d427b972a625c8e46373668", size = 9864088, upload-time = "2026-03-31T06:46:59.935Z" }, + { url = "https://files.pythonhosted.org/packages/5c/2b/341f1b04bbca2e17e13cd3f08c215b70ef2c60c5356ef1e8c6857449edc7/pandas-3.0.2-cp313-cp313-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:710246ba0616e86891b58ab95f2495143bb2bc83ab6b06747c74216f583a6ac9", size = 10369066, upload-time = "2026-03-31T06:47:02.792Z" }, + { url = "https://files.pythonhosted.org/packages/12/c5/cbb1ffefb20a93d3f0e1fdcda699fb84976210d411b008f97f48bf6ce27e/pandas-3.0.2-cp313-cp313-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:5d3cfe227c725b1f3dff4278b43d8c784656a42a9325b63af6b1492a8232209e", size = 10876780, upload-time = "2026-03-31T06:47:06.205Z" }, + { url = "https://files.pythonhosted.org/packages/98/fe/2249ae5e0a69bd0ddf17353d0a5d26611d70970111f5b3600cdc8be883e7/pandas-3.0.2-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:c3b723df9087a9a9a840e263ebd9f88b64a12075d1bf2ea401a5a42f254f084d", size = 11375181, upload-time = "2026-03-31T06:47:09.383Z" }, + { url = "https://files.pythonhosted.org/packages/de/64/77a38b09e70b6464883b8d7584ab543e748e42c1b5d337a2ee088e0df741/pandas-3.0.2-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:a3096110bf9eac0070b7208465f2740e2d8a670d5cb6530b5bb884eca495fd39", size = 11928899, upload-time = "2026-03-31T06:47:12.686Z" }, + { url = "https://files.pythonhosted.org/packages/5e/52/42855bf626868413f761addd574acc6195880ae247a5346477a4361c3acb/pandas-3.0.2-cp313-cp313-win_amd64.whl", hash = "sha256:07a10f5c36512eead51bc578eb3354ad17578b22c013d89a796ab5eee90cd991", size = 9746574, upload-time = "2026-03-31T06:47:15.64Z" }, + { url = "https://files.pythonhosted.org/packages/88/39/21304ae06a25e8bf9fc820d69b29b2c495b2ae580d1e143146c309941760/pandas-3.0.2-cp313-cp313-win_arm64.whl", hash = "sha256:5fdbfa05931071aba28b408e59226186b01eb5e92bea2ab78b65863ca3228d84", size = 9047156, upload-time = "2026-03-31T06:47:18.595Z" }, + { url = "https://files.pythonhosted.org/packages/72/20/7defa8b27d4f330a903bb68eea33be07d839c5ea6bdda54174efcec0e1d2/pandas-3.0.2-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:dbc20dea3b9e27d0e66d74c42b2d0c1bed9c2ffe92adea33633e3bedeb5ac235", size = 10756238, upload-time = "2026-03-31T06:47:22.012Z" }, + { url = "https://files.pythonhosted.org/packages/e9/95/49433c14862c636afc0e9b2db83ff16b3ad92959364e52b2955e44c8e94c/pandas-3.0.2-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:b75c347eff42497452116ce05ef461822d97ce5b9ff8df6edacb8076092c855d", size = 10408520, upload-time = "2026-03-31T06:47:25.197Z" }, + { url = "https://files.pythonhosted.org/packages/3b/f8/462ad2b5881d6b8ec8e5f7ed2ea1893faa02290d13870a1600fe72ad8efc/pandas-3.0.2-cp313-cp313t-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:d1478075142e83a5571782ad007fb201ed074bdeac7ebcc8890c71442e96adf7", size = 10324154, upload-time = "2026-03-31T06:47:28.097Z" }, + { url = "https://files.pythonhosted.org/packages/0a/65/d1e69b649cbcddda23ad6e4c40ef935340f6f652a006e5cbc3555ac8adb3/pandas-3.0.2-cp313-cp313t-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:5880314e69e763d4c8b27937090de570f1fb8d027059a7ada3f7f8e98bdcb677", size = 10714449, upload-time = "2026-03-31T06:47:30.85Z" }, + { url = "https://files.pythonhosted.org/packages/47/a4/85b59bc65b8190ea3689882db6cdf32a5003c0ccd5a586c30fdcc3ffc4fc/pandas-3.0.2-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:b5329e26898896f06035241a626d7c335daa479b9bbc82be7c2742d048e41172", size = 11338475, upload-time = "2026-03-31T06:47:34.026Z" }, + { url = "https://files.pythonhosted.org/packages/1e/c4/bc6966c6e38e5d9478b935272d124d80a589511ed1612a5d21d36f664c68/pandas-3.0.2-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:81526c4afd31971f8b62671442a4b2b51e0aa9acc3819c9f0f12a28b6fcf85f1", size = 11786568, upload-time = "2026-03-31T06:47:36.941Z" }, + { url = "https://files.pythonhosted.org/packages/e8/74/09298ca9740beed1d3504e073d67e128aa07e5ca5ca2824b0c674c0b8676/pandas-3.0.2-cp313-cp313t-win_amd64.whl", hash = "sha256:7cadd7e9a44ec13b621aec60f9150e744cfc7a3dd32924a7e2f45edff31823b0", size = 10488652, upload-time = "2026-03-31T06:47:40.612Z" }, + { url = "https://files.pythonhosted.org/packages/bb/40/c6ea527147c73b24fc15c891c3fcffe9c019793119c5742b8784a062c7db/pandas-3.0.2-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:db0dbfd2a6cdf3770aa60464d50333d8f3d9165b2f2671bcc299b72de5a6677b", size = 10326084, upload-time = "2026-03-31T06:47:43.834Z" }, + { url = "https://files.pythonhosted.org/packages/95/25/bdb9326c3b5455f8d4d3549fce7abcf967259de146fe2cf7a82368141948/pandas-3.0.2-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:0555c5882688a39317179ab4a0ed41d3ebc8812ab14c69364bbee8fb7a3f6288", size = 9914146, upload-time = "2026-03-31T06:47:46.67Z" }, + { url = "https://files.pythonhosted.org/packages/8d/77/3a227ff3337aa376c60d288e1d61c5d097131d0ac71f954d90a8f369e422/pandas-3.0.2-cp314-cp314-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:01f31a546acd5574ef77fe199bc90b55527c225c20ccda6601cf6b0fd5ed597c", size = 10444081, upload-time = "2026-03-31T06:47:49.681Z" }, + { url = "https://files.pythonhosted.org/packages/15/88/3cdd54fa279341afa10acf8d2b503556b1375245dccc9315659f795dd2e9/pandas-3.0.2-cp314-cp314-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:deeca1b5a931fdf0c2212c8a659ade6d3b1edc21f0914ce71ef24456ca7a6535", size = 10897535, upload-time = "2026-03-31T06:47:53.033Z" }, + { url = "https://files.pythonhosted.org/packages/06/9d/98cc7a7624f7932e40f434299260e2917b090a579d75937cb8a57b9d2de3/pandas-3.0.2-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:0f48afd9bb13300ffb5a3316973324c787054ba6665cda0da3fbd67f451995db", size = 11446992, upload-time = "2026-03-31T06:47:56.193Z" }, + { url = "https://files.pythonhosted.org/packages/9a/cd/19ff605cc3760e80602e6826ddef2824d8e7050ed80f2e11c4b079741dc3/pandas-3.0.2-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:6c4d8458b97a35717b62469a4ea0e85abd5ed8687277f5ccfc67f8a5126f8c53", size = 11968257, upload-time = "2026-03-31T06:47:59.137Z" }, + { url = "https://files.pythonhosted.org/packages/db/60/aba6a38de456e7341285102bede27514795c1eaa353bc0e7638b6b785356/pandas-3.0.2-cp314-cp314-win_amd64.whl", hash = "sha256:b35d14bb5d8285d9494fe93815a9e9307c0876e10f1e8e89ac5b88f728ec8dcf", size = 9865893, upload-time = "2026-03-31T06:48:02.038Z" }, + { url = "https://files.pythonhosted.org/packages/08/71/e5ec979dd2e8a093dacb8864598c0ff59a0cee0bbcdc0bfec16a51684d4f/pandas-3.0.2-cp314-cp314-win_arm64.whl", hash = "sha256:63d141b56ef686f7f0d714cfb8de4e320475b86bf4b620aa0b7da89af8cbdbbb", size = 9188644, upload-time = "2026-03-31T06:48:05.045Z" }, + { url = "https://files.pythonhosted.org/packages/f1/6c/7b45d85db19cae1eb524f2418ceaa9d85965dcf7b764ed151386b7c540f0/pandas-3.0.2-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:140f0cffb1fa2524e874dde5b477d9defe10780d8e9e220d259b2c0874c89d9d", size = 10776246, upload-time = "2026-03-31T06:48:07.789Z" }, + { url = "https://files.pythonhosted.org/packages/a8/3e/7b00648b086c106e81766f25322b48aa8dfa95b55e621dbdf2fdd413a117/pandas-3.0.2-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:ae37e833ff4fed0ba352f6bdd8b73ba3ab3256a85e54edfd1ab51ae40cca0af8", size = 10424801, upload-time = "2026-03-31T06:48:10.897Z" }, + { url = "https://files.pythonhosted.org/packages/da/6e/558dd09a71b53b4008e7fc8a98ec6d447e9bfb63cdaeea10e5eb9b2dabe8/pandas-3.0.2-cp314-cp314t-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:4d888a5c678a419a5bb41a2a93818e8ed9fd3172246555c0b37b7cc27027effd", size = 10345643, upload-time = "2026-03-31T06:48:13.7Z" }, + { url = "https://files.pythonhosted.org/packages/be/e3/921c93b4d9a280409451dc8d07b062b503bbec0531d2627e73a756e99a82/pandas-3.0.2-cp314-cp314t-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:b444dc64c079e84df91baa8bf613d58405645461cabca929d9178f2cd392398d", size = 10743641, upload-time = "2026-03-31T06:48:16.659Z" }, + { url = "https://files.pythonhosted.org/packages/56/ca/fd17286f24fa3b4d067965d8d5d7e14fe557dd4f979a0b068ac0deaf8228/pandas-3.0.2-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:4544c7a54920de8eeacaa1466a6b7268ecfbc9bc64ab4dbb89c6bbe94d5e0660", size = 11361993, upload-time = "2026-03-31T06:48:19.475Z" }, + { url = "https://files.pythonhosted.org/packages/e4/a5/2f6ed612056819de445a433ca1f2821ac3dab7f150d569a59e9cc105de1d/pandas-3.0.2-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:734be7551687c00fbd760dc0522ed974f82ad230d4a10f54bf51b80d44a08702", size = 11815274, upload-time = "2026-03-31T06:48:22.695Z" }, + { url = "https://files.pythonhosted.org/packages/00/2f/b622683e99ec3ce00b0854bac9e80868592c5b051733f2cf3a868e5fea26/pandas-3.0.2-cp314-cp314t-win_amd64.whl", hash = "sha256:57a07209bebcbcf768d2d13c9b78b852f9a15978dac41b9e6421a81ad4cdd276", size = 10888530, upload-time = "2026-03-31T06:48:25.806Z" }, + { url = "https://files.pythonhosted.org/packages/cb/2b/f8434233fab2bd66a02ec014febe4e5adced20e2693e0e90a07d118ed30e/pandas-3.0.2-cp314-cp314t-win_arm64.whl", hash = "sha256:5371b72c2d4d415d08765f32d689217a43227484e81b2305b52076e328f6f482", size = 9455341, upload-time = "2026-03-31T06:48:28.418Z" }, +] + +[[package]] +name = "pillow" +version = "12.2.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/8c/21/c2bcdd5906101a30244eaffc1b6e6ce71a31bd0742a01eb89e660ebfac2d/pillow-12.2.0.tar.gz", hash = "sha256:a830b1a40919539d07806aa58e1b114df53ddd43213d9c8b75847eee6c0182b5", size = 46987819, upload-time = "2026-04-01T14:46:17.687Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/58/be/7482c8a5ebebbc6470b3eb791812fff7d5e0216c2be3827b30b8bb6603ed/pillow-12.2.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:2d192a155bbcec180f8564f693e6fd9bccff5a7af9b32e2e4bf8c9c69dbad6b5", size = 5308279, upload-time = "2026-04-01T14:43:13.246Z" }, + { url = "https://files.pythonhosted.org/packages/d8/95/0a351b9289c2b5cbde0bacd4a83ebc44023e835490a727b2a3bd60ddc0f4/pillow-12.2.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:f3f40b3c5a968281fd507d519e444c35f0ff171237f4fdde090dd60699458421", size = 4695490, upload-time = "2026-04-01T14:43:15.584Z" }, + { url = "https://files.pythonhosted.org/packages/de/af/4e8e6869cbed569d43c416fad3dc4ecb944cb5d9492defaed89ddd6fe871/pillow-12.2.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:03e7e372d5240cc23e9f07deca4d775c0817bffc641b01e9c3af208dbd300987", size = 6284462, upload-time = "2026-04-01T14:43:18.268Z" }, + { url = "https://files.pythonhosted.org/packages/e9/9e/c05e19657fd57841e476be1ab46c4d501bffbadbafdc31a6d665f8b737b6/pillow-12.2.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:b86024e52a1b269467a802258c25521e6d742349d760728092e1bc2d135b4d76", size = 8094744, upload-time = "2026-04-01T14:43:20.716Z" }, + { url = "https://files.pythonhosted.org/packages/2b/54/1789c455ed10176066b6e7e6da1b01e50e36f94ba584dc68d9eebfe9156d/pillow-12.2.0-cp312-cp312-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:7371b48c4fa448d20d2714c9a1f775a81155050d383333e0a6c15b1123dda005", size = 6398371, upload-time = "2026-04-01T14:43:23.443Z" }, + { url = "https://files.pythonhosted.org/packages/43/e3/fdc657359e919462369869f1c9f0e973f353f9a9ee295a39b1fea8ee1a77/pillow-12.2.0-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:62f5409336adb0663b7caa0da5c7d9e7bdbaae9ce761d34669420c2a801b2780", size = 7087215, upload-time = "2026-04-01T14:43:26.758Z" }, + { url = "https://files.pythonhosted.org/packages/8b/f8/2f6825e441d5b1959d2ca5adec984210f1ec086435b0ed5f52c19b3b8a6e/pillow-12.2.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:01afa7cf67f74f09523699b4e88c73fb55c13346d212a59a2db1f86b0a63e8c5", size = 6509783, upload-time = "2026-04-01T14:43:29.56Z" }, + { url = "https://files.pythonhosted.org/packages/67/f9/029a27095ad20f854f9dba026b3ea6428548316e057e6fc3545409e86651/pillow-12.2.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:fc3d34d4a8fbec3e88a79b92e5465e0f9b842b628675850d860b8bd300b159f5", size = 7212112, upload-time = "2026-04-01T14:43:32.091Z" }, + { url = "https://files.pythonhosted.org/packages/be/42/025cfe05d1be22dbfdb4f264fe9de1ccda83f66e4fc3aac94748e784af04/pillow-12.2.0-cp312-cp312-win32.whl", hash = "sha256:58f62cc0f00fd29e64b29f4fd923ffdb3859c9f9e6105bfc37ba1d08994e8940", size = 6378489, upload-time = "2026-04-01T14:43:34.601Z" }, + { url = "https://files.pythonhosted.org/packages/5d/7b/25a221d2c761c6a8ae21bfa3874988ff2583e19cf8a27bf2fee358df7942/pillow-12.2.0-cp312-cp312-win_amd64.whl", hash = "sha256:7f84204dee22a783350679a0333981df803dac21a0190d706a50475e361c93f5", size = 7084129, upload-time = "2026-04-01T14:43:37.213Z" }, + { url = "https://files.pythonhosted.org/packages/10/e1/542a474affab20fd4a0f1836cb234e8493519da6b76899e30bcc5d990b8b/pillow-12.2.0-cp312-cp312-win_arm64.whl", hash = "sha256:af73337013e0b3b46f175e79492d96845b16126ddf79c438d7ea7ff27783a414", size = 2463612, upload-time = "2026-04-01T14:43:39.421Z" }, + { url = "https://files.pythonhosted.org/packages/4a/01/53d10cf0dbad820a8db274d259a37ba50b88b24768ddccec07355382d5ad/pillow-12.2.0-cp313-cp313-ios_13_0_arm64_iphoneos.whl", hash = "sha256:8297651f5b5679c19968abefd6bb84d95fe30ef712eb1b2d9b2d31ca61267f4c", size = 4100837, upload-time = "2026-04-01T14:43:41.506Z" }, + { url = "https://files.pythonhosted.org/packages/0f/98/f3a6657ecb698c937f6c76ee564882945f29b79bad496abcba0e84659ec5/pillow-12.2.0-cp313-cp313-ios_13_0_arm64_iphonesimulator.whl", hash = "sha256:50d8520da2a6ce0af445fa6d648c4273c3eeefbc32d7ce049f22e8b5c3daecc2", size = 4176528, upload-time = "2026-04-01T14:43:43.773Z" }, + { url = "https://files.pythonhosted.org/packages/69/bc/8986948f05e3ea490b8442ea1c1d4d990b24a7e43d8a51b2c7d8b1dced36/pillow-12.2.0-cp313-cp313-ios_13_0_x86_64_iphonesimulator.whl", hash = "sha256:766cef22385fa1091258ad7e6216792b156dc16d8d3fa607e7545b2b72061f1c", size = 3640401, upload-time = "2026-04-01T14:43:45.87Z" }, + { url = "https://files.pythonhosted.org/packages/34/46/6c717baadcd62bc8ed51d238d521ab651eaa74838291bda1f86fe1f864c9/pillow-12.2.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:5d2fd0fa6b5d9d1de415060363433f28da8b1526c1c129020435e186794b3795", size = 5308094, upload-time = "2026-04-01T14:43:48.438Z" }, + { url = "https://files.pythonhosted.org/packages/71/43/905a14a8b17fdb1ccb58d282454490662d2cb89a6bfec26af6d3520da5ec/pillow-12.2.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:56b25336f502b6ed02e889f4ece894a72612fe885889a6e8c4c80239ff6e5f5f", size = 4695402, upload-time = "2026-04-01T14:43:51.292Z" }, + { url = "https://files.pythonhosted.org/packages/73/dd/42107efcb777b16fa0393317eac58f5b5cf30e8392e266e76e51cff28c3d/pillow-12.2.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:f1c943e96e85df3d3478f7b691f229887e143f81fedab9b20205349ab04d73ed", size = 6280005, upload-time = "2026-04-01T14:43:54.242Z" }, + { url = "https://files.pythonhosted.org/packages/a8/68/b93e09e5e8549019e61acf49f65b1a8530765a7f812c77a7461bca7e4494/pillow-12.2.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:03f6fab9219220f041c74aeaa2939ff0062bd5c364ba9ce037197f4c6d498cd9", size = 8090669, upload-time = "2026-04-01T14:43:57.335Z" }, + { url = "https://files.pythonhosted.org/packages/4b/6e/3ccb54ce8ec4ddd1accd2d89004308b7b0b21c4ac3d20fa70af4760a4330/pillow-12.2.0-cp313-cp313-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:5cdfebd752ec52bf5bb4e35d9c64b40826bc5b40a13df7c3cda20a2c03a0f5ed", size = 6395194, upload-time = "2026-04-01T14:43:59.864Z" }, + { url = "https://files.pythonhosted.org/packages/67/ee/21d4e8536afd1a328f01b359b4d3997b291ffd35a237c877b331c1c3b71c/pillow-12.2.0-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:eedf4b74eda2b5a4b2b2fb4c006d6295df3bf29e459e198c90ea48e130dc75c3", size = 7082423, upload-time = "2026-04-01T14:44:02.74Z" }, + { url = "https://files.pythonhosted.org/packages/78/5f/e9f86ab0146464e8c133fe85df987ed9e77e08b29d8d35f9f9f4d6f917ba/pillow-12.2.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:00a2865911330191c0b818c59103b58a5e697cae67042366970a6b6f1b20b7f9", size = 6505667, upload-time = "2026-04-01T14:44:05.381Z" }, + { url = "https://files.pythonhosted.org/packages/ed/1e/409007f56a2fdce61584fd3acbc2bbc259857d555196cedcadc68c015c82/pillow-12.2.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:1e1757442ed87f4912397c6d35a0db6a7b52592156014706f17658ff58bbf795", size = 7208580, upload-time = "2026-04-01T14:44:08.39Z" }, + { url = "https://files.pythonhosted.org/packages/23/c4/7349421080b12fb35414607b8871e9534546c128a11965fd4a7002ccfbee/pillow-12.2.0-cp313-cp313-win32.whl", hash = "sha256:144748b3af2d1b358d41286056d0003f47cb339b8c43a9ea42f5fea4d8c66b6e", size = 6375896, upload-time = "2026-04-01T14:44:11.197Z" }, + { url = "https://files.pythonhosted.org/packages/3f/82/8a3739a5e470b3c6cbb1d21d315800d8e16bff503d1f16b03a4ec3212786/pillow-12.2.0-cp313-cp313-win_amd64.whl", hash = "sha256:390ede346628ccc626e5730107cde16c42d3836b89662a115a921f28440e6a3b", size = 7081266, upload-time = "2026-04-01T14:44:13.947Z" }, + { url = "https://files.pythonhosted.org/packages/c3/25/f968f618a062574294592f668218f8af564830ccebdd1fa6200f598e65c5/pillow-12.2.0-cp313-cp313-win_arm64.whl", hash = "sha256:8023abc91fba39036dbce14a7d6535632f99c0b857807cbbbf21ecc9f4717f06", size = 2463508, upload-time = "2026-04-01T14:44:16.312Z" }, + { url = "https://files.pythonhosted.org/packages/4d/a4/b342930964e3cb4dce5038ae34b0eab4653334995336cd486c5a8c25a00c/pillow-12.2.0-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:042db20a421b9bafecc4b84a8b6e444686bd9d836c7fd24542db3e7df7baad9b", size = 5309927, upload-time = "2026-04-01T14:44:18.89Z" }, + { url = "https://files.pythonhosted.org/packages/9f/de/23198e0a65a9cf06123f5435a5d95cea62a635697f8f03d134d3f3a96151/pillow-12.2.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:dd025009355c926a84a612fecf58bb315a3f6814b17ead51a8e48d3823d9087f", size = 4698624, upload-time = "2026-04-01T14:44:21.115Z" }, + { url = "https://files.pythonhosted.org/packages/01/a6/1265e977f17d93ea37aa28aa81bad4fa597933879fac2520d24e021c8da3/pillow-12.2.0-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:88ddbc66737e277852913bd1e07c150cc7bb124539f94c4e2df5344494e0a612", size = 6321252, upload-time = "2026-04-01T14:44:23.663Z" }, + { url = "https://files.pythonhosted.org/packages/3c/83/5982eb4a285967baa70340320be9f88e57665a387e3a53a7f0db8231a0cd/pillow-12.2.0-cp313-cp313t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:d362d1878f00c142b7e1a16e6e5e780f02be8195123f164edf7eddd911eefe7c", size = 8126550, upload-time = "2026-04-01T14:44:26.772Z" }, + { url = "https://files.pythonhosted.org/packages/4e/48/6ffc514adce69f6050d0753b1a18fd920fce8cac87620d5a31231b04bfc5/pillow-12.2.0-cp313-cp313t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:2c727a6d53cb0018aadd8018c2b938376af27914a68a492f59dfcaca650d5eea", size = 6433114, upload-time = "2026-04-01T14:44:29.615Z" }, + { url = "https://files.pythonhosted.org/packages/36/a3/f9a77144231fb8d40ee27107b4463e205fa4677e2ca2548e14da5cf18dce/pillow-12.2.0-cp313-cp313t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:efd8c21c98c5cc60653bcb311bef2ce0401642b7ce9d09e03a7da87c878289d4", size = 7115667, upload-time = "2026-04-01T14:44:32.773Z" }, + { url = "https://files.pythonhosted.org/packages/c1/fc/ac4ee3041e7d5a565e1c4fd72a113f03b6394cc72ab7089d27608f8aaccb/pillow-12.2.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:9f08483a632889536b8139663db60f6724bfcb443c96f1b18855860d7d5c0fd4", size = 6538966, upload-time = "2026-04-01T14:44:35.252Z" }, + { url = "https://files.pythonhosted.org/packages/c0/a8/27fb307055087f3668f6d0a8ccb636e7431d56ed0750e07a60547b1e083e/pillow-12.2.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:dac8d77255a37e81a2efcbd1fc05f1c15ee82200e6c240d7e127e25e365c39ea", size = 7238241, upload-time = "2026-04-01T14:44:37.875Z" }, + { url = "https://files.pythonhosted.org/packages/ad/4b/926ab182c07fccae9fcb120043464e1ff1564775ec8864f21a0ebce6ac25/pillow-12.2.0-cp313-cp313t-win32.whl", hash = "sha256:ee3120ae9dff32f121610bb08e4313be87e03efeadfc6c0d18f89127e24d0c24", size = 6379592, upload-time = "2026-04-01T14:44:40.336Z" }, + { url = "https://files.pythonhosted.org/packages/c2/c4/f9e476451a098181b30050cc4c9a3556b64c02cf6497ea421ac047e89e4b/pillow-12.2.0-cp313-cp313t-win_amd64.whl", hash = "sha256:325ca0528c6788d2a6c3d40e3568639398137346c3d6e66bb61db96b96511c98", size = 7085542, upload-time = "2026-04-01T14:44:43.251Z" }, + { url = "https://files.pythonhosted.org/packages/00/a4/285f12aeacbe2d6dc36c407dfbbe9e96d4a80b0fb710a337f6d2ad978c75/pillow-12.2.0-cp313-cp313t-win_arm64.whl", hash = "sha256:2e5a76d03a6c6dcef67edabda7a52494afa4035021a79c8558e14af25313d453", size = 2465765, upload-time = "2026-04-01T14:44:45.996Z" }, + { url = "https://files.pythonhosted.org/packages/bf/98/4595daa2365416a86cb0d495248a393dfc84e96d62ad080c8546256cb9c0/pillow-12.2.0-cp314-cp314-ios_13_0_arm64_iphoneos.whl", hash = "sha256:3adc9215e8be0448ed6e814966ecf3d9952f0ea40eb14e89a102b87f450660d8", size = 4100848, upload-time = "2026-04-01T14:44:48.48Z" }, + { url = "https://files.pythonhosted.org/packages/0b/79/40184d464cf89f6663e18dfcf7ca21aae2491fff1a16127681bf1fa9b8cf/pillow-12.2.0-cp314-cp314-ios_13_0_arm64_iphonesimulator.whl", hash = "sha256:6a9adfc6d24b10f89588096364cc726174118c62130c817c2837c60cf08a392b", size = 4176515, upload-time = "2026-04-01T14:44:51.353Z" }, + { url = "https://files.pythonhosted.org/packages/b0/63/703f86fd4c422a9cf722833670f4f71418fb116b2853ff7da722ea43f184/pillow-12.2.0-cp314-cp314-ios_13_0_x86_64_iphonesimulator.whl", hash = "sha256:6a6e67ea2e6feda684ed370f9a1c52e7a243631c025ba42149a2cc5934dec295", size = 3640159, upload-time = "2026-04-01T14:44:53.588Z" }, + { url = "https://files.pythonhosted.org/packages/71/e0/fb22f797187d0be2270f83500aab851536101b254bfa1eae10795709d283/pillow-12.2.0-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:2bb4a8d594eacdfc59d9e5ad972aa8afdd48d584ffd5f13a937a664c3e7db0ed", size = 5312185, upload-time = "2026-04-01T14:44:56.039Z" }, + { url = "https://files.pythonhosted.org/packages/ba/8c/1a9e46228571de18f8e28f16fabdfc20212a5d019f3e3303452b3f0a580d/pillow-12.2.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:80b2da48193b2f33ed0c32c38140f9d3186583ce7d516526d462645fd98660ae", size = 4695386, upload-time = "2026-04-01T14:44:58.663Z" }, + { url = "https://files.pythonhosted.org/packages/70/62/98f6b7f0c88b9addd0e87c217ded307b36be024d4ff8869a812b241d1345/pillow-12.2.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:22db17c68434de69d8ecfc2fe821569195c0c373b25cccb9cbdacf2c6e53c601", size = 6280384, upload-time = "2026-04-01T14:45:01.5Z" }, + { url = "https://files.pythonhosted.org/packages/5e/03/688747d2e91cfbe0e64f316cd2e8005698f76ada3130d0194664174fa5de/pillow-12.2.0-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:7b14cc0106cd9aecda615dd6903840a058b4700fcb817687d0ee4fc8b6e389be", size = 8091599, upload-time = "2026-04-01T14:45:04.5Z" }, + { url = "https://files.pythonhosted.org/packages/f6/35/577e22b936fcdd66537329b33af0b4ccfefaeabd8aec04b266528cddb33c/pillow-12.2.0-cp314-cp314-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:8cbeb542b2ebc6fcdacabf8aca8c1a97c9b3ad3927d46b8723f9d4f033288a0f", size = 6396021, upload-time = "2026-04-01T14:45:07.117Z" }, + { url = "https://files.pythonhosted.org/packages/11/8d/d2532ad2a603ca2b93ad9f5135732124e57811d0168155852f37fbce2458/pillow-12.2.0-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:4bfd07bc812fbd20395212969e41931001fd59eb55a60658b0e5710872e95286", size = 7083360, upload-time = "2026-04-01T14:45:09.763Z" }, + { url = "https://files.pythonhosted.org/packages/5e/26/d325f9f56c7e039034897e7380e9cc202b1e368bfd04d4cbe6a441f02885/pillow-12.2.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:9aba9a17b623ef750a4d11b742cbafffeb48a869821252b30ee21b5e91392c50", size = 6507628, upload-time = "2026-04-01T14:45:12.378Z" }, + { url = "https://files.pythonhosted.org/packages/5f/f7/769d5632ffb0988f1c5e7660b3e731e30f7f8ec4318e94d0a5d674eb65a4/pillow-12.2.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:deede7c263feb25dba4e82ea23058a235dcc2fe1f6021025dc71f2b618e26104", size = 7209321, upload-time = "2026-04-01T14:45:15.122Z" }, + { url = "https://files.pythonhosted.org/packages/6a/7a/c253e3c645cd47f1aceea6a8bacdba9991bf45bb7dfe927f7c893e89c93c/pillow-12.2.0-cp314-cp314-win32.whl", hash = "sha256:632ff19b2778e43162304d50da0181ce24ac5bb8180122cbe1bf4673428328c7", size = 6479723, upload-time = "2026-04-01T14:45:17.797Z" }, + { url = "https://files.pythonhosted.org/packages/cd/8b/601e6566b957ca50e28725cb6c355c59c2c8609751efbecd980db44e0349/pillow-12.2.0-cp314-cp314-win_amd64.whl", hash = "sha256:4e6c62e9d237e9b65fac06857d511e90d8461a32adcc1b9065ea0c0fa3a28150", size = 7217400, upload-time = "2026-04-01T14:45:20.529Z" }, + { url = "https://files.pythonhosted.org/packages/d6/94/220e46c73065c3e2951bb91c11a1fb636c8c9ad427ac3ce7d7f3359b9b2f/pillow-12.2.0-cp314-cp314-win_arm64.whl", hash = "sha256:b1c1fbd8a5a1af3412a0810d060a78b5136ec0836c8a4ef9aa11807f2a22f4e1", size = 2554835, upload-time = "2026-04-01T14:45:23.162Z" }, + { url = "https://files.pythonhosted.org/packages/b6/ab/1b426a3974cb0e7da5c29ccff4807871d48110933a57207b5a676cccc155/pillow-12.2.0-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:57850958fe9c751670e49b2cecf6294acc99e562531f4bd317fa5ddee2068463", size = 5314225, upload-time = "2026-04-01T14:45:25.637Z" }, + { url = "https://files.pythonhosted.org/packages/19/1e/dce46f371be2438eecfee2a1960ee2a243bbe5e961890146d2dee1ff0f12/pillow-12.2.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:d5d38f1411c0ed9f97bcb49b7bd59b6b7c314e0e27420e34d99d844b9ce3b6f3", size = 4698541, upload-time = "2026-04-01T14:45:28.355Z" }, + { url = "https://files.pythonhosted.org/packages/55/c3/7fbecf70adb3a0c33b77a300dc52e424dc22ad8cdc06557a2e49523b703d/pillow-12.2.0-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:5c0a9f29ca8e79f09de89293f82fc9b0270bb4af1d58bc98f540cc4aedf03166", size = 6322251, upload-time = "2026-04-01T14:45:30.924Z" }, + { url = "https://files.pythonhosted.org/packages/1c/3c/7fbc17cfb7e4fe0ef1642e0abc17fc6c94c9f7a16be41498e12e2ba60408/pillow-12.2.0-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:1610dd6c61621ae1cf811bef44d77e149ce3f7b95afe66a4512f8c59f25d9ebe", size = 8127807, upload-time = "2026-04-01T14:45:33.908Z" }, + { url = "https://files.pythonhosted.org/packages/ff/c3/a8ae14d6defd2e448493ff512fae903b1e9bd40b72efb6ec55ce0048c8ce/pillow-12.2.0-cp314-cp314t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:0a34329707af4f73cf1782a36cd2289c0368880654a2c11f027bcee9052d35dd", size = 6433935, upload-time = "2026-04-01T14:45:36.623Z" }, + { url = "https://files.pythonhosted.org/packages/6e/32/2880fb3a074847ac159d8f902cb43278a61e85f681661e7419e6596803ed/pillow-12.2.0-cp314-cp314t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:8e9c4f5b3c546fa3458a29ab22646c1c6c787ea8f5ef51300e5a60300736905e", size = 7116720, upload-time = "2026-04-01T14:45:39.258Z" }, + { url = "https://files.pythonhosted.org/packages/46/87/495cc9c30e0129501643f24d320076f4cc54f718341df18cc70ec94c44e1/pillow-12.2.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:fb043ee2f06b41473269765c2feae53fc2e2fbf96e5e22ca94fb5ad677856f06", size = 6540498, upload-time = "2026-04-01T14:45:41.879Z" }, + { url = "https://files.pythonhosted.org/packages/18/53/773f5edca692009d883a72211b60fdaf8871cbef075eaa9d577f0a2f989e/pillow-12.2.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:f278f034eb75b4e8a13a54a876cc4a5ab39173d2cdd93a638e1b467fc545ac43", size = 7239413, upload-time = "2026-04-01T14:45:44.705Z" }, + { url = "https://files.pythonhosted.org/packages/c9/e4/4b64a97d71b2a83158134abbb2f5bd3f8a2ea691361282f010998f339ec7/pillow-12.2.0-cp314-cp314t-win32.whl", hash = "sha256:6bb77b2dcb06b20f9f4b4a8454caa581cd4dd0643a08bacf821216a16d9c8354", size = 6482084, upload-time = "2026-04-01T14:45:47.568Z" }, + { url = "https://files.pythonhosted.org/packages/ba/13/306d275efd3a3453f72114b7431c877d10b1154014c1ebbedd067770d629/pillow-12.2.0-cp314-cp314t-win_amd64.whl", hash = "sha256:6562ace0d3fb5f20ed7290f1f929cae41b25ae29528f2af1722966a0a02e2aa1", size = 7225152, upload-time = "2026-04-01T14:45:50.032Z" }, + { url = "https://files.pythonhosted.org/packages/ff/6e/cf826fae916b8658848d7b9f38d88da6396895c676e8086fc0988073aaf8/pillow-12.2.0-cp314-cp314t-win_arm64.whl", hash = "sha256:aa88ccfe4e32d362816319ed727a004423aab09c5cea43c01a4b435643fa34eb", size = 2556579, upload-time = "2026-04-01T14:45:52.529Z" }, +] + +[[package]] +name = "plotly" +version = "6.7.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "narwhals" }, + { name = "packaging" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/3a/7f/0f100df1172aadf88a929a9dbb902656b0880ba4b960fe5224867159d8f4/plotly-6.7.0.tar.gz", hash = "sha256:45eea0ff27e2a23ccd62776f77eb43aa1ca03df4192b76036e380bb479b892c6", size = 6911286, upload-time = "2026-04-09T20:36:45.738Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/90/ad/cba91b3bcf04073e4d1655a5c1710ef3f457f56f7d1b79dcc3d72f4dd912/plotly-6.7.0-py3-none-any.whl", hash = "sha256:ac8aca1c25c663a59b5b9140a549264a5badde2e057d79b8c772ae2920e32ff0", size = 9898444, upload-time = "2026-04-09T20:36:39.812Z" }, +] + +[[package]] +name = "proto-plus" +version = "1.27.2" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "protobuf" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/81/0d/94dfe80193e79d55258345901acd2917523d56e8381bc4dee7fd38e3868a/proto_plus-1.27.2.tar.gz", hash = "sha256:b2adde53adadf75737c44d3dcb0104fde65250dfc83ad59168b4aa3e574b6a24", size = 57204, upload-time = "2026-03-26T22:18:57.174Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/84/f3/1fba73eeffafc998a25d59703b63f8be4fe8a5cb12eaff7386a0ba0f7125/proto_plus-1.27.2-py3-none-any.whl", hash = "sha256:6432f75893d3b9e70b9c412f1d2f03f65b11fb164b793d14ae2ca01821d22718", size = 50450, upload-time = "2026-03-26T22:13:42.927Z" }, +] + +[[package]] +name = "protobuf" +version = "7.34.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/6b/6b/a0e95cad1ad7cc3f2c6821fcab91671bd5b78bd42afb357bb4765f29bc41/protobuf-7.34.1.tar.gz", hash = "sha256:9ce42245e704cc5027be797c1db1eb93184d44d1cdd71811fb2d9b25ad541280", size = 454708, upload-time = "2026-03-20T17:34:47.036Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/ec/11/3325d41e6ee15bf1125654301211247b042563bcc898784351252549a8ad/protobuf-7.34.1-cp310-abi3-macosx_10_9_universal2.whl", hash = "sha256:d8b2cc79c4d8f62b293ad9b11ec3aebce9af481fa73e64556969f7345ebf9fc7", size = 429247, upload-time = "2026-03-20T17:34:37.024Z" }, + { url = "https://files.pythonhosted.org/packages/eb/9d/aa69df2724ff63efa6f72307b483ce0827f4347cc6d6df24b59e26659fef/protobuf-7.34.1-cp310-abi3-manylinux2014_aarch64.whl", hash = "sha256:5185e0e948d07abe94bb76ec9b8416b604cfe5da6f871d67aad30cbf24c3110b", size = 325753, upload-time = "2026-03-20T17:34:38.751Z" }, + { url = "https://files.pythonhosted.org/packages/92/e8/d174c91fd48e50101943f042b09af9029064810b734e4160bbe282fa1caa/protobuf-7.34.1-cp310-abi3-manylinux2014_s390x.whl", hash = "sha256:403b093a6e28a960372b44e5eb081775c9b056e816a8029c61231743d63f881a", size = 340198, upload-time = "2026-03-20T17:34:39.871Z" }, + { url = "https://files.pythonhosted.org/packages/53/1b/3b431694a4dc6d37b9f653f0c64b0a0d9ec074ee810710c0c3da21d67ba7/protobuf-7.34.1-cp310-abi3-manylinux2014_x86_64.whl", hash = "sha256:8ff40ce8cd688f7265326b38d5a1bed9bfdf5e6723d49961432f83e21d5713e4", size = 324267, upload-time = "2026-03-20T17:34:41.1Z" }, + { url = "https://files.pythonhosted.org/packages/85/29/64de04a0ac142fb685fd09999bc3d337943fb386f3a0ec57f92fd8203f97/protobuf-7.34.1-cp310-abi3-win32.whl", hash = "sha256:34b84ce27680df7cca9f231043ada0daa55d0c44a2ddfaa58ec1d0d89d8bf60a", size = 426628, upload-time = "2026-03-20T17:34:42.536Z" }, + { url = "https://files.pythonhosted.org/packages/4d/87/cb5e585192a22b8bd457df5a2c16a75ea0db9674c3a0a39fc9347d84e075/protobuf-7.34.1-cp310-abi3-win_amd64.whl", hash = "sha256:e97b55646e6ce5cbb0954a8c28cd39a5869b59090dfaa7df4598a7fba869468c", size = 437901, upload-time = "2026-03-20T17:34:44.112Z" }, + { url = "https://files.pythonhosted.org/packages/88/95/608f665226bca68b736b79e457fded9a2a38c4f4379a4a7614303d9db3bc/protobuf-7.34.1-py3-none-any.whl", hash = "sha256:bb3812cd53aefea2b028ef42bd780f5b96407247f20c6ef7c679807e9d188f11", size = 170715, upload-time = "2026-03-20T17:34:45.384Z" }, +] + +[[package]] +name = "pyarrow" +version = "23.0.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/88/22/134986a4cc224d593c1afde5494d18ff629393d74cc2eddb176669f234a4/pyarrow-23.0.1.tar.gz", hash = "sha256:b8c5873e33440b2bc2f4a79d2b47017a89c5a24116c055625e6f2ee50523f019", size = 1167336, upload-time = "2026-02-16T10:14:12.39Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/9a/4b/4166bb5abbfe6f750fc60ad337c43ecf61340fa52ab386da6e8dbf9e63c4/pyarrow-23.0.1-cp312-cp312-macosx_12_0_arm64.whl", hash = "sha256:f4b0dbfa124c0bb161f8b5ebb40f1a680b70279aa0c9901d44a2b5a20806039f", size = 34214575, upload-time = "2026-02-16T10:09:56.225Z" }, + { url = "https://files.pythonhosted.org/packages/e1/da/3f941e3734ac8088ea588b53e860baeddac8323ea40ce22e3d0baa865cc9/pyarrow-23.0.1-cp312-cp312-macosx_12_0_x86_64.whl", hash = "sha256:7707d2b6673f7de054e2e83d59f9e805939038eebe1763fe811ee8fa5c0cd1a7", size = 35832540, upload-time = "2026-02-16T10:10:03.428Z" }, + { url = "https://files.pythonhosted.org/packages/88/7c/3d841c366620e906d54430817531b877ba646310296df42ef697308c2705/pyarrow-23.0.1-cp312-cp312-manylinux_2_28_aarch64.whl", hash = "sha256:86ff03fb9f1a320266e0de855dee4b17da6794c595d207f89bba40d16b5c78b9", size = 44470940, upload-time = "2026-02-16T10:10:10.704Z" }, + { url = "https://files.pythonhosted.org/packages/2c/a5/da83046273d990f256cb79796a190bbf7ec999269705ddc609403f8c6b06/pyarrow-23.0.1-cp312-cp312-manylinux_2_28_x86_64.whl", hash = "sha256:813d99f31275919c383aab17f0f455a04f5a429c261cc411b1e9a8f5e4aaaa05", size = 47586063, upload-time = "2026-02-16T10:10:17.95Z" }, + { url = "https://files.pythonhosted.org/packages/5b/3c/b7d2ebcff47a514f47f9da1e74b7949138c58cfeb108cdd4ee62f43f0cf3/pyarrow-23.0.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:bf5842f960cddd2ef757d486041d57c96483efc295a8c4a0e20e704cbbf39c67", size = 48173045, upload-time = "2026-02-16T10:10:25.363Z" }, + { url = "https://files.pythonhosted.org/packages/43/b2/b40961262213beaba6acfc88698eb773dfce32ecdf34d19291db94c2bd73/pyarrow-23.0.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:564baf97c858ecc03ec01a41062e8f4698abc3e6e2acd79c01c2e97880a19730", size = 50621741, upload-time = "2026-02-16T10:10:33.477Z" }, + { url = "https://files.pythonhosted.org/packages/f6/70/1fdda42d65b28b078e93d75d371b2185a61da89dda4def8ba6ba41ebdeb4/pyarrow-23.0.1-cp312-cp312-win_amd64.whl", hash = "sha256:07deae7783782ac7250989a7b2ecde9b3c343a643f82e8a4df03d93b633006f0", size = 27620678, upload-time = "2026-02-16T10:10:39.31Z" }, + { url = "https://files.pythonhosted.org/packages/47/10/2cbe4c6f0fb83d2de37249567373d64327a5e4d8db72f486db42875b08f6/pyarrow-23.0.1-cp313-cp313-macosx_12_0_arm64.whl", hash = "sha256:6b8fda694640b00e8af3c824f99f789e836720aa8c9379fb435d4c4953a756b8", size = 34210066, upload-time = "2026-02-16T10:10:45.487Z" }, + { url = "https://files.pythonhosted.org/packages/cb/4f/679fa7e84dadbaca7a65f7cdba8d6c83febbd93ca12fa4adf40ba3b6362b/pyarrow-23.0.1-cp313-cp313-macosx_12_0_x86_64.whl", hash = "sha256:8ff51b1addc469b9444b7c6f3548e19dc931b172ab234e995a60aea9f6e6025f", size = 35825526, upload-time = "2026-02-16T10:10:52.266Z" }, + { url = "https://files.pythonhosted.org/packages/f9/63/d2747d930882c9d661e9398eefc54f15696547b8983aaaf11d4a2e8b5426/pyarrow-23.0.1-cp313-cp313-manylinux_2_28_aarch64.whl", hash = "sha256:71c5be5cbf1e1cb6169d2a0980850bccb558ddc9b747b6206435313c47c37677", size = 44473279, upload-time = "2026-02-16T10:11:01.557Z" }, + { url = "https://files.pythonhosted.org/packages/b3/93/10a48b5e238de6d562a411af6467e71e7aedbc9b87f8d3a35f1560ae30fb/pyarrow-23.0.1-cp313-cp313-manylinux_2_28_x86_64.whl", hash = "sha256:9b6f4f17b43bc39d56fec96e53fe89d94bac3eb134137964371b45352d40d0c2", size = 47585798, upload-time = "2026-02-16T10:11:09.401Z" }, + { url = "https://files.pythonhosted.org/packages/5c/20/476943001c54ef078dbf9542280e22741219a184a0632862bca4feccd666/pyarrow-23.0.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:9fc13fc6c403d1337acab46a2c4346ca6c9dec5780c3c697cf8abfd5e19b6b37", size = 48179446, upload-time = "2026-02-16T10:11:17.781Z" }, + { url = "https://files.pythonhosted.org/packages/4b/b6/5dd0c47b335fcd8edba9bfab78ad961bd0fd55ebe53468cc393f45e0be60/pyarrow-23.0.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:5c16ed4f53247fa3ffb12a14d236de4213a4415d127fe9cebed33d51671113e2", size = 50623972, upload-time = "2026-02-16T10:11:26.185Z" }, + { url = "https://files.pythonhosted.org/packages/d5/09/a532297c9591a727d67760e2e756b83905dd89adb365a7f6e9c72578bcc1/pyarrow-23.0.1-cp313-cp313-win_amd64.whl", hash = "sha256:cecfb12ef629cf6be0b1887f9f86463b0dd3dc3195ae6224e74006be4736035a", size = 27540749, upload-time = "2026-02-16T10:12:23.297Z" }, + { url = "https://files.pythonhosted.org/packages/a5/8e/38749c4b1303e6ae76b3c80618f84861ae0c55dd3c2273842ea6f8258233/pyarrow-23.0.1-cp313-cp313t-macosx_12_0_arm64.whl", hash = "sha256:29f7f7419a0e30264ea261fdc0e5fe63ce5a6095003db2945d7cd78df391a7e1", size = 34471544, upload-time = "2026-02-16T10:11:32.535Z" }, + { url = "https://files.pythonhosted.org/packages/a3/73/f237b2bc8c669212f842bcfd842b04fc8d936bfc9d471630569132dc920d/pyarrow-23.0.1-cp313-cp313t-macosx_12_0_x86_64.whl", hash = "sha256:33d648dc25b51fd8055c19e4261e813dfc4d2427f068bcecc8b53d01b81b0500", size = 35949911, upload-time = "2026-02-16T10:11:39.813Z" }, + { url = "https://files.pythonhosted.org/packages/0c/86/b912195eee0903b5611bf596833def7d146ab2d301afeb4b722c57ffc966/pyarrow-23.0.1-cp313-cp313t-manylinux_2_28_aarch64.whl", hash = "sha256:cd395abf8f91c673dd3589cadc8cc1ee4e8674fa61b2e923c8dd215d9c7d1f41", size = 44520337, upload-time = "2026-02-16T10:11:47.764Z" }, + { url = "https://files.pythonhosted.org/packages/69/c2/f2a717fb824f62d0be952ea724b4f6f9372a17eed6f704b5c9526f12f2f1/pyarrow-23.0.1-cp313-cp313t-manylinux_2_28_x86_64.whl", hash = "sha256:00be9576d970c31defb5c32eb72ef585bf600ef6d0a82d5eccaae96639cf9d07", size = 47548944, upload-time = "2026-02-16T10:11:56.607Z" }, + { url = "https://files.pythonhosted.org/packages/84/a7/90007d476b9f0dc308e3bc57b832d004f848fd6c0da601375d20d92d1519/pyarrow-23.0.1-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:c2139549494445609f35a5cda4eb94e2c9e4d704ce60a095b342f82460c73a83", size = 48236269, upload-time = "2026-02-16T10:12:04.47Z" }, + { url = "https://files.pythonhosted.org/packages/b0/3f/b16fab3e77709856eb6ac328ce35f57a6d4a18462c7ca5186ef31b45e0e0/pyarrow-23.0.1-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:7044b442f184d84e2351e5084600f0d7343d6117aabcbc1ac78eb1ae11eb4125", size = 50604794, upload-time = "2026-02-16T10:12:11.797Z" }, + { url = "https://files.pythonhosted.org/packages/e9/a1/22df0620a9fac31d68397a75465c344e83c3dfe521f7612aea33e27ab6c0/pyarrow-23.0.1-cp313-cp313t-win_amd64.whl", hash = "sha256:a35581e856a2fafa12f3f54fce4331862b1cfb0bef5758347a858a4aa9d6bae8", size = 27660642, upload-time = "2026-02-16T10:12:17.746Z" }, + { url = "https://files.pythonhosted.org/packages/8d/1b/6da9a89583ce7b23ac611f183ae4843cd3a6cf54f079549b0e8c14031e73/pyarrow-23.0.1-cp314-cp314-macosx_12_0_arm64.whl", hash = "sha256:5df1161da23636a70838099d4aaa65142777185cc0cdba4037a18cee7d8db9ca", size = 34238755, upload-time = "2026-02-16T10:12:32.819Z" }, + { url = "https://files.pythonhosted.org/packages/ae/b5/d58a241fbe324dbaeb8df07be6af8752c846192d78d2272e551098f74e88/pyarrow-23.0.1-cp314-cp314-macosx_12_0_x86_64.whl", hash = "sha256:fa8e51cb04b9f8c9c5ace6bab63af9a1f88d35c0d6cbf53e8c17c098552285e1", size = 35847826, upload-time = "2026-02-16T10:12:38.949Z" }, + { url = "https://files.pythonhosted.org/packages/54/a5/8cbc83f04aba433ca7b331b38f39e000efd9f0c7ce47128670e737542996/pyarrow-23.0.1-cp314-cp314-manylinux_2_28_aarch64.whl", hash = "sha256:0b95a3994f015be13c63148fef8832e8a23938128c185ee951c98908a696e0eb", size = 44536859, upload-time = "2026-02-16T10:12:45.467Z" }, + { url = "https://files.pythonhosted.org/packages/36/2e/c0f017c405fcdc252dbccafbe05e36b0d0eb1ea9a958f081e01c6972927f/pyarrow-23.0.1-cp314-cp314-manylinux_2_28_x86_64.whl", hash = "sha256:4982d71350b1a6e5cfe1af742c53dfb759b11ce14141870d05d9e540d13bc5d1", size = 47614443, upload-time = "2026-02-16T10:12:55.525Z" }, + { url = "https://files.pythonhosted.org/packages/af/6b/2314a78057912f5627afa13ba43809d9d653e6630859618b0fd81a4e0759/pyarrow-23.0.1-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:c250248f1fe266db627921c89b47b7c06fee0489ad95b04d50353537d74d6886", size = 48232991, upload-time = "2026-02-16T10:13:04.729Z" }, + { url = "https://files.pythonhosted.org/packages/40/f2/1bcb1d3be3460832ef3370d621142216e15a2c7c62602a4ea19ec240dd64/pyarrow-23.0.1-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:5f4763b83c11c16e5f4c15601ba6dfa849e20723b46aa2617cb4bffe8768479f", size = 50645077, upload-time = "2026-02-16T10:13:14.147Z" }, + { url = "https://files.pythonhosted.org/packages/eb/3f/b1da7b61cd66566a4d4c8383d376c606d1c34a906c3f1cb35c479f59d1aa/pyarrow-23.0.1-cp314-cp314-win_amd64.whl", hash = "sha256:3a4c85ef66c134161987c17b147d6bffdca4566f9a4c1d81a0a01cdf08414ea5", size = 28234271, upload-time = "2026-02-16T10:14:09.397Z" }, + { url = "https://files.pythonhosted.org/packages/b5/78/07f67434e910a0f7323269be7bfbf58699bd0c1d080b18a1ab49ba943fe8/pyarrow-23.0.1-cp314-cp314t-macosx_12_0_arm64.whl", hash = "sha256:17cd28e906c18af486a499422740298c52d7c6795344ea5002a7720b4eadf16d", size = 34488692, upload-time = "2026-02-16T10:13:21.541Z" }, + { url = "https://files.pythonhosted.org/packages/50/76/34cf7ae93ece1f740a04910d9f7e80ba166b9b4ab9596a953e9e62b90fe1/pyarrow-23.0.1-cp314-cp314t-macosx_12_0_x86_64.whl", hash = "sha256:76e823d0e86b4fb5e1cf4a58d293036e678b5a4b03539be933d3b31f9406859f", size = 35964383, upload-time = "2026-02-16T10:13:28.63Z" }, + { url = "https://files.pythonhosted.org/packages/46/90/459b827238936d4244214be7c684e1b366a63f8c78c380807ae25ed92199/pyarrow-23.0.1-cp314-cp314t-manylinux_2_28_aarch64.whl", hash = "sha256:a62e1899e3078bf65943078b3ad2a6ddcacf2373bc06379aac61b1e548a75814", size = 44538119, upload-time = "2026-02-16T10:13:35.506Z" }, + { url = "https://files.pythonhosted.org/packages/28/a1/93a71ae5881e99d1f9de1d4554a87be37da11cd6b152239fb5bd924fdc64/pyarrow-23.0.1-cp314-cp314t-manylinux_2_28_x86_64.whl", hash = "sha256:df088e8f640c9fae3b1f495b3c64755c4e719091caf250f3a74d095ddf3c836d", size = 47571199, upload-time = "2026-02-16T10:13:42.504Z" }, + { url = "https://files.pythonhosted.org/packages/88/a3/d2c462d4ef313521eaf2eff04d204ac60775263f1fb08c374b543f79f610/pyarrow-23.0.1-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:46718a220d64677c93bc243af1d44b55998255427588e400677d7192671845c7", size = 48259435, upload-time = "2026-02-16T10:13:49.226Z" }, + { url = "https://files.pythonhosted.org/packages/cc/f1/11a544b8c3d38a759eb3fbb022039117fd633e9a7b19e4841cc3da091915/pyarrow-23.0.1-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:a09f3876e87f48bc2f13583ab551f0379e5dfb83210391e68ace404181a20690", size = 50629149, upload-time = "2026-02-16T10:13:57.238Z" }, + { url = "https://files.pythonhosted.org/packages/50/f2/c0e76a0b451ffdf0cf788932e182758eb7558953f4f27f1aff8e2518b653/pyarrow-23.0.1-cp314-cp314t-win_amd64.whl", hash = "sha256:527e8d899f14bd15b740cd5a54ad56b7f98044955373a17179d5956ddb93d9ce", size = 28365807, upload-time = "2026-02-16T10:14:03.892Z" }, +] + +[[package]] +name = "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 = "pydeck" +version = "0.9.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "jinja2" }, + { name = "numpy" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/a1/ca/40e14e196864a0f61a92abb14d09b3d3da98f94ccb03b49cf51688140dab/pydeck-0.9.1.tar.gz", hash = "sha256:f74475ae637951d63f2ee58326757f8d4f9cd9f2a457cf42950715003e2cb605", size = 3832240, upload-time = "2024-05-10T15:36:21.153Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/ab/4c/b888e6cf58bd9db9c93f40d1c6be8283ff49d88919231afe93a6bcf61626/pydeck-0.9.1-py2.py3-none-any.whl", hash = "sha256:b3f75ba0d273fc917094fa61224f3f6076ca8752b93d46faf3bcfd9f9d59b038", size = 6900403, upload-time = "2024-05-10T15:36:17.36Z" }, +] + +[[package]] +name = "pyparsing" +version = "3.3.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/f3/91/9c6ee907786a473bf81c5f53cf703ba0957b23ab84c264080fb5a450416f/pyparsing-3.3.2.tar.gz", hash = "sha256:c777f4d763f140633dcb6d8a3eda953bf7a214dc4eff598413c070bcdc117cbc", size = 6851574, upload-time = "2026-01-21T03:57:59.36Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/10/bd/c038d7cc38edc1aa5bf91ab8068b63d4308c66c4c8bb3cbba7dfbc049f9c/pyparsing-3.3.2-py3-none-any.whl", hash = "sha256:850ba148bd908d7e2411587e247a1e4f0327839c40e2e5e6d05a007ecc69911d", size = 122781, upload-time = "2026-01-21T03:57:55.912Z" }, +] + +[[package]] +name = "python-dateutil" +version = "2.9.0.post0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "six" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/66/c0/0c8b6ad9f17a802ee498c46e004a0eb49bc148f2fd230864601a86dcf6db/python-dateutil-2.9.0.post0.tar.gz", hash = "sha256:37dd54208da7e1cd875388217d5e00ebd4179249f90fb72437e91a35459a0ad3", size = 342432, upload-time = "2024-03-01T18:36:20.211Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/ec/57/56b9bcc3c9c6a792fcbaf139543cee77261f3651ca9da0c93f5c1221264b/python_dateutil-2.9.0.post0-py2.py3-none-any.whl", hash = "sha256:a8b2bc7bffae282281c8140a97d3aa9c14da0b136dfe83f850eea9a5f7470427", size = 229892, upload-time = "2024-03-01T18:36:18.57Z" }, +] + +[[package]] +name = "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.33.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "certifi" }, + { name = "charset-normalizer" }, + { name = "idna" }, + { name = "urllib3" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/5f/a4/98b9c7c6428a668bf7e42ebb7c79d576a1c3c1e3ae2d47e674b468388871/requests-2.33.1.tar.gz", hash = "sha256:18817f8c57c6263968bc123d237e3b8b08ac046f5456bd1e307ee8f4250d3517", size = 134120, upload-time = "2026-03-30T16:09:15.531Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/d7/8e/7540e8a2036f79a125c1d2ebadf69ed7901608859186c856fa0388ef4197/requests-2.33.1-py3-none-any.whl", hash = "sha256:4e6d1ef462f3626a1f0a0a9c42dd93c63bad33f9f1c1937509b8c5c8718ab56a", size = 64947, upload-time = "2026-03-30T16:09:13.83Z" }, +] + +[[package]] +name = "requests-oauthlib" +version = "2.0.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "oauthlib" }, + { name = "requests" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/42/f2/05f29bc3913aea15eb670be136045bf5c5bbf4b99ecb839da9b422bb2c85/requests-oauthlib-2.0.0.tar.gz", hash = "sha256:b3dffaebd884d8cd778494369603a9e7b58d29111bf6b41bdc2dcd87203af4e9", size = 55650, upload-time = "2024-03-22T20:32:29.939Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/3b/5d/63d4ae3b9daea098d5d6f5da83984853c1bbacd5dc826764b249fe119d24/requests_oauthlib-2.0.0-py2.py3-none-any.whl", hash = "sha256:7dd8a5c40426b779b0868c404bdef9768deccf22749cde15852df527e6269b36", size = 24179, upload-time = "2024-03-22T20:32:28.055Z" }, +] + +[[package]] +name = "rpds-py" +version = "0.30.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/20/af/3f2f423103f1113b36230496629986e0ef7e199d2aa8392452b484b38ced/rpds_py-0.30.0.tar.gz", hash = "sha256:dd8ff7cf90014af0c0f787eea34794ebf6415242ee1d6fa91eaba725cc441e84", size = 69469, upload-time = "2025-11-30T20:24:38.837Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/03/e7/98a2f4ac921d82f33e03f3835f5bf3a4a40aa1bfdc57975e74a97b2b4bdd/rpds_py-0.30.0-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:a161f20d9a43006833cd7068375a94d035714d73a172b681d8881820600abfad", size = 375086, upload-time = "2025-11-30T20:22:17.93Z" }, + { url = "https://files.pythonhosted.org/packages/4d/a1/bca7fd3d452b272e13335db8d6b0b3ecde0f90ad6f16f3328c6fb150c889/rpds_py-0.30.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:6abc8880d9d036ecaafe709079969f56e876fcf107f7a8e9920ba6d5a3878d05", size = 359053, upload-time = "2025-11-30T20:22:19.297Z" }, + { url = "https://files.pythonhosted.org/packages/65/1c/ae157e83a6357eceff62ba7e52113e3ec4834a84cfe07fa4b0757a7d105f/rpds_py-0.30.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ca28829ae5f5d569bb62a79512c842a03a12576375d5ece7d2cadf8abe96ec28", size = 390763, upload-time = "2025-11-30T20:22:21.661Z" }, + { url = "https://files.pythonhosted.org/packages/d4/36/eb2eb8515e2ad24c0bd43c3ee9cd74c33f7ca6430755ccdb240fd3144c44/rpds_py-0.30.0-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:a1010ed9524c73b94d15919ca4d41d8780980e1765babf85f9a2f90d247153dd", size = 408951, upload-time = "2025-11-30T20:22:23.408Z" }, + { url = "https://files.pythonhosted.org/packages/d6/65/ad8dc1784a331fabbd740ef6f71ce2198c7ed0890dab595adb9ea2d775a1/rpds_py-0.30.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f8d1736cfb49381ba528cd5baa46f82fdc65c06e843dab24dd70b63d09121b3f", size = 514622, upload-time = "2025-11-30T20:22:25.16Z" }, + { url = "https://files.pythonhosted.org/packages/63/8e/0cfa7ae158e15e143fe03993b5bcd743a59f541f5952e1546b1ac1b5fd45/rpds_py-0.30.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d948b135c4693daff7bc2dcfc4ec57237a29bd37e60c2fabf5aff2bbacf3e2f1", size = 414492, upload-time = "2025-11-30T20:22:26.505Z" }, + { url = "https://files.pythonhosted.org/packages/60/1b/6f8f29f3f995c7ffdde46a626ddccd7c63aefc0efae881dc13b6e5d5bb16/rpds_py-0.30.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:47f236970bccb2233267d89173d3ad2703cd36a0e2a6e92d0560d333871a3d23", size = 394080, upload-time = "2025-11-30T20:22:27.934Z" }, + { url = "https://files.pythonhosted.org/packages/6d/d5/a266341051a7a3ca2f4b750a3aa4abc986378431fc2da508c5034d081b70/rpds_py-0.30.0-cp312-cp312-manylinux_2_31_riscv64.whl", hash = "sha256:2e6ecb5a5bcacf59c3f912155044479af1d0b6681280048b338b28e364aca1f6", size = 408680, upload-time = "2025-11-30T20:22:29.341Z" }, + { url = "https://files.pythonhosted.org/packages/10/3b/71b725851df9ab7a7a4e33cf36d241933da66040d195a84781f49c50490c/rpds_py-0.30.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:a8fa71a2e078c527c3e9dc9fc5a98c9db40bcc8a92b4e8858e36d329f8684b51", size = 423589, upload-time = "2025-11-30T20:22:31.469Z" }, + { url = "https://files.pythonhosted.org/packages/00/2b/e59e58c544dc9bd8bd8384ecdb8ea91f6727f0e37a7131baeff8d6f51661/rpds_py-0.30.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:73c67f2db7bc334e518d097c6d1e6fed021bbc9b7d678d6cc433478365d1d5f5", size = 573289, upload-time = "2025-11-30T20:22:32.997Z" }, + { url = "https://files.pythonhosted.org/packages/da/3e/a18e6f5b460893172a7d6a680e86d3b6bc87a54c1f0b03446a3c8c7b588f/rpds_py-0.30.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:5ba103fb455be00f3b1c2076c9d4264bfcb037c976167a6047ed82f23153f02e", size = 599737, upload-time = "2025-11-30T20:22:34.419Z" }, + { url = "https://files.pythonhosted.org/packages/5c/e2/714694e4b87b85a18e2c243614974413c60aa107fd815b8cbc42b873d1d7/rpds_py-0.30.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:7cee9c752c0364588353e627da8a7e808a66873672bcb5f52890c33fd965b394", size = 563120, upload-time = "2025-11-30T20:22:35.903Z" }, + { url = "https://files.pythonhosted.org/packages/6f/ab/d5d5e3bcedb0a77f4f613706b750e50a5a3ba1c15ccd3665ecc636c968fd/rpds_py-0.30.0-cp312-cp312-win32.whl", hash = "sha256:1ab5b83dbcf55acc8b08fc62b796ef672c457b17dbd7820a11d6c52c06839bdf", size = 223782, upload-time = "2025-11-30T20:22:37.271Z" }, + { url = "https://files.pythonhosted.org/packages/39/3b/f786af9957306fdc38a74cef405b7b93180f481fb48453a114bb6465744a/rpds_py-0.30.0-cp312-cp312-win_amd64.whl", hash = "sha256:a090322ca841abd453d43456ac34db46e8b05fd9b3b4ac0c78bcde8b089f959b", size = 240463, upload-time = "2025-11-30T20:22:39.021Z" }, + { url = "https://files.pythonhosted.org/packages/f3/d2/b91dc748126c1559042cfe41990deb92c4ee3e2b415f6b5234969ffaf0cc/rpds_py-0.30.0-cp312-cp312-win_arm64.whl", hash = "sha256:669b1805bd639dd2989b281be2cfd951c6121b65e729d9b843e9639ef1fd555e", size = 230868, upload-time = "2025-11-30T20:22:40.493Z" }, + { url = "https://files.pythonhosted.org/packages/ed/dc/d61221eb88ff410de3c49143407f6f3147acf2538c86f2ab7ce65ae7d5f9/rpds_py-0.30.0-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:f83424d738204d9770830d35290ff3273fbb02b41f919870479fab14b9d303b2", size = 374887, upload-time = "2025-11-30T20:22:41.812Z" }, + { url = "https://files.pythonhosted.org/packages/fd/32/55fb50ae104061dbc564ef15cc43c013dc4a9f4527a1f4d99baddf56fe5f/rpds_py-0.30.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:e7536cd91353c5273434b4e003cbda89034d67e7710eab8761fd918ec6c69cf8", size = 358904, upload-time = "2025-11-30T20:22:43.479Z" }, + { url = "https://files.pythonhosted.org/packages/58/70/faed8186300e3b9bdd138d0273109784eea2396c68458ed580f885dfe7ad/rpds_py-0.30.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2771c6c15973347f50fece41fc447c054b7ac2ae0502388ce3b6738cd366e3d4", size = 389945, upload-time = "2025-11-30T20:22:44.819Z" }, + { url = "https://files.pythonhosted.org/packages/bd/a8/073cac3ed2c6387df38f71296d002ab43496a96b92c823e76f46b8af0543/rpds_py-0.30.0-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:0a59119fc6e3f460315fe9d08149f8102aa322299deaa5cab5b40092345c2136", size = 407783, upload-time = "2025-11-30T20:22:46.103Z" }, + { url = "https://files.pythonhosted.org/packages/77/57/5999eb8c58671f1c11eba084115e77a8899d6e694d2a18f69f0ba471ec8b/rpds_py-0.30.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:76fec018282b4ead0364022e3c54b60bf368b9d926877957a8624b58419169b7", size = 515021, upload-time = "2025-11-30T20:22:47.458Z" }, + { url = "https://files.pythonhosted.org/packages/e0/af/5ab4833eadc36c0a8ed2bc5c0de0493c04f6c06de223170bd0798ff98ced/rpds_py-0.30.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:692bef75a5525db97318e8cd061542b5a79812d711ea03dbc1f6f8dbb0c5f0d2", size = 414589, upload-time = "2025-11-30T20:22:48.872Z" }, + { url = "https://files.pythonhosted.org/packages/b7/de/f7192e12b21b9e9a68a6d0f249b4af3fdcdff8418be0767a627564afa1f1/rpds_py-0.30.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9027da1ce107104c50c81383cae773ef5c24d296dd11c99e2629dbd7967a20c6", size = 394025, upload-time = "2025-11-30T20:22:50.196Z" }, + { url = "https://files.pythonhosted.org/packages/91/c4/fc70cd0249496493500e7cc2de87504f5aa6509de1e88623431fec76d4b6/rpds_py-0.30.0-cp313-cp313-manylinux_2_31_riscv64.whl", hash = "sha256:9cf69cdda1f5968a30a359aba2f7f9aa648a9ce4b580d6826437f2b291cfc86e", size = 408895, upload-time = "2025-11-30T20:22:51.87Z" }, + { url = "https://files.pythonhosted.org/packages/58/95/d9275b05ab96556fefff73a385813eb66032e4c99f411d0795372d9abcea/rpds_py-0.30.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:a4796a717bf12b9da9d3ad002519a86063dcac8988b030e405704ef7d74d2d9d", size = 422799, upload-time = "2025-11-30T20:22:53.341Z" }, + { url = "https://files.pythonhosted.org/packages/06/c1/3088fc04b6624eb12a57eb814f0d4997a44b0d208d6cace713033ff1a6ba/rpds_py-0.30.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:5d4c2aa7c50ad4728a094ebd5eb46c452e9cb7edbfdb18f9e1221f597a73e1e7", size = 572731, upload-time = "2025-11-30T20:22:54.778Z" }, + { url = "https://files.pythonhosted.org/packages/d8/42/c612a833183b39774e8ac8fecae81263a68b9583ee343db33ab571a7ce55/rpds_py-0.30.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:ba81a9203d07805435eb06f536d95a266c21e5b2dfbf6517748ca40c98d19e31", size = 599027, upload-time = "2025-11-30T20:22:56.212Z" }, + { url = "https://files.pythonhosted.org/packages/5f/60/525a50f45b01d70005403ae0e25f43c0384369ad24ffe46e8d9068b50086/rpds_py-0.30.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:945dccface01af02675628334f7cf49c2af4c1c904748efc5cf7bbdf0b579f95", size = 563020, upload-time = "2025-11-30T20:22:58.2Z" }, + { url = "https://files.pythonhosted.org/packages/0b/5d/47c4655e9bcd5ca907148535c10e7d489044243cc9941c16ed7cd53be91d/rpds_py-0.30.0-cp313-cp313-win32.whl", hash = "sha256:b40fb160a2db369a194cb27943582b38f79fc4887291417685f3ad693c5a1d5d", size = 223139, upload-time = "2025-11-30T20:23:00.209Z" }, + { url = "https://files.pythonhosted.org/packages/f2/e1/485132437d20aa4d3e1d8b3fb5a5e65aa8139f1e097080c2a8443201742c/rpds_py-0.30.0-cp313-cp313-win_amd64.whl", hash = "sha256:806f36b1b605e2d6a72716f321f20036b9489d29c51c91f4dd29a3e3afb73b15", size = 240224, upload-time = "2025-11-30T20:23:02.008Z" }, + { url = "https://files.pythonhosted.org/packages/24/95/ffd128ed1146a153d928617b0ef673960130be0009c77d8fbf0abe306713/rpds_py-0.30.0-cp313-cp313-win_arm64.whl", hash = "sha256:d96c2086587c7c30d44f31f42eae4eac89b60dabbac18c7669be3700f13c3ce1", size = 230645, upload-time = "2025-11-30T20:23:03.43Z" }, + { url = "https://files.pythonhosted.org/packages/ff/1b/b10de890a0def2a319a2626334a7f0ae388215eb60914dbac8a3bae54435/rpds_py-0.30.0-cp313-cp313t-macosx_10_12_x86_64.whl", hash = "sha256:eb0b93f2e5c2189ee831ee43f156ed34e2a89a78a66b98cadad955972548be5a", size = 364443, upload-time = "2025-11-30T20:23:04.878Z" }, + { url = "https://files.pythonhosted.org/packages/0d/bf/27e39f5971dc4f305a4fb9c672ca06f290f7c4e261c568f3dea16a410d47/rpds_py-0.30.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:922e10f31f303c7c920da8981051ff6d8c1a56207dbdf330d9047f6d30b70e5e", size = 353375, upload-time = "2025-11-30T20:23:06.342Z" }, + { url = "https://files.pythonhosted.org/packages/40/58/442ada3bba6e8e6615fc00483135c14a7538d2ffac30e2d933ccf6852232/rpds_py-0.30.0-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cdc62c8286ba9bf7f47befdcea13ea0e26bf294bda99758fd90535cbaf408000", size = 383850, upload-time = "2025-11-30T20:23:07.825Z" }, + { url = "https://files.pythonhosted.org/packages/14/14/f59b0127409a33c6ef6f5c1ebd5ad8e32d7861c9c7adfa9a624fc3889f6c/rpds_py-0.30.0-cp313-cp313t-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:47f9a91efc418b54fb8190a6b4aa7813a23fb79c51f4bb84e418f5476c38b8db", size = 392812, upload-time = "2025-11-30T20:23:09.228Z" }, + { url = "https://files.pythonhosted.org/packages/b3/66/e0be3e162ac299b3a22527e8913767d869e6cc75c46bd844aa43fb81ab62/rpds_py-0.30.0-cp313-cp313t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1f3587eb9b17f3789ad50824084fa6f81921bbf9a795826570bda82cb3ed91f2", size = 517841, upload-time = "2025-11-30T20:23:11.186Z" }, + { url = "https://files.pythonhosted.org/packages/3d/55/fa3b9cf31d0c963ecf1ba777f7cf4b2a2c976795ac430d24a1f43d25a6ba/rpds_py-0.30.0-cp313-cp313t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:39c02563fc592411c2c61d26b6c5fe1e51eaa44a75aa2c8735ca88b0d9599daa", size = 408149, upload-time = "2025-11-30T20:23:12.864Z" }, + { url = "https://files.pythonhosted.org/packages/60/ca/780cf3b1a32b18c0f05c441958d3758f02544f1d613abf9488cd78876378/rpds_py-0.30.0-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:51a1234d8febafdfd33a42d97da7a43f5dcb120c1060e352a3fbc0c6d36e2083", size = 383843, upload-time = "2025-11-30T20:23:14.638Z" }, + { url = "https://files.pythonhosted.org/packages/82/86/d5f2e04f2aa6247c613da0c1dd87fcd08fa17107e858193566048a1e2f0a/rpds_py-0.30.0-cp313-cp313t-manylinux_2_31_riscv64.whl", hash = "sha256:eb2c4071ab598733724c08221091e8d80e89064cd472819285a9ab0f24bcedb9", size = 396507, upload-time = "2025-11-30T20:23:16.105Z" }, + { url = "https://files.pythonhosted.org/packages/4b/9a/453255d2f769fe44e07ea9785c8347edaf867f7026872e76c1ad9f7bed92/rpds_py-0.30.0-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:6bdfdb946967d816e6adf9a3d8201bfad269c67efe6cefd7093ef959683c8de0", size = 414949, upload-time = "2025-11-30T20:23:17.539Z" }, + { url = "https://files.pythonhosted.org/packages/a3/31/622a86cdc0c45d6df0e9ccb6becdba5074735e7033c20e401a6d9d0e2ca0/rpds_py-0.30.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:c77afbd5f5250bf27bf516c7c4a016813eb2d3e116139aed0096940c5982da94", size = 565790, upload-time = "2025-11-30T20:23:19.029Z" }, + { url = "https://files.pythonhosted.org/packages/1c/5d/15bbf0fb4a3f58a3b1c67855ec1efcc4ceaef4e86644665fff03e1b66d8d/rpds_py-0.30.0-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:61046904275472a76c8c90c9ccee9013d70a6d0f73eecefd38c1ae7c39045a08", size = 590217, upload-time = "2025-11-30T20:23:20.885Z" }, + { url = "https://files.pythonhosted.org/packages/6d/61/21b8c41f68e60c8cc3b2e25644f0e3681926020f11d06ab0b78e3c6bbff1/rpds_py-0.30.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:4c5f36a861bc4b7da6516dbdf302c55313afa09b81931e8280361a4f6c9a2d27", size = 555806, upload-time = "2025-11-30T20:23:22.488Z" }, + { url = "https://files.pythonhosted.org/packages/f9/39/7e067bb06c31de48de3eb200f9fc7c58982a4d3db44b07e73963e10d3be9/rpds_py-0.30.0-cp313-cp313t-win32.whl", hash = "sha256:3d4a69de7a3e50ffc214ae16d79d8fbb0922972da0356dcf4d0fdca2878559c6", size = 211341, upload-time = "2025-11-30T20:23:24.449Z" }, + { url = "https://files.pythonhosted.org/packages/0a/4d/222ef0b46443cf4cf46764d9c630f3fe4abaa7245be9417e56e9f52b8f65/rpds_py-0.30.0-cp313-cp313t-win_amd64.whl", hash = "sha256:f14fc5df50a716f7ece6a80b6c78bb35ea2ca47c499e422aa4463455dd96d56d", size = 225768, upload-time = "2025-11-30T20:23:25.908Z" }, + { url = "https://files.pythonhosted.org/packages/86/81/dad16382ebbd3d0e0328776d8fd7ca94220e4fa0798d1dc5e7da48cb3201/rpds_py-0.30.0-cp314-cp314-macosx_10_12_x86_64.whl", hash = "sha256:68f19c879420aa08f61203801423f6cd5ac5f0ac4ac82a2368a9fcd6a9a075e0", size = 362099, upload-time = "2025-11-30T20:23:27.316Z" }, + { url = "https://files.pythonhosted.org/packages/2b/60/19f7884db5d5603edf3c6bce35408f45ad3e97e10007df0e17dd57af18f8/rpds_py-0.30.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:ec7c4490c672c1a0389d319b3a9cfcd098dcdc4783991553c332a15acf7249be", size = 353192, upload-time = "2025-11-30T20:23:29.151Z" }, + { url = "https://files.pythonhosted.org/packages/bf/c4/76eb0e1e72d1a9c4703c69607cec123c29028bff28ce41588792417098ac/rpds_py-0.30.0-cp314-cp314-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f251c812357a3fed308d684a5079ddfb9d933860fc6de89f2b7ab00da481e65f", size = 384080, upload-time = "2025-11-30T20:23:30.785Z" }, + { url = "https://files.pythonhosted.org/packages/72/87/87ea665e92f3298d1b26d78814721dc39ed8d2c74b86e83348d6b48a6f31/rpds_py-0.30.0-cp314-cp314-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:ac98b175585ecf4c0348fd7b29c3864bda53b805c773cbf7bfdaffc8070c976f", size = 394841, upload-time = "2025-11-30T20:23:32.209Z" }, + { url = "https://files.pythonhosted.org/packages/77/ad/7783a89ca0587c15dcbf139b4a8364a872a25f861bdb88ed99f9b0dec985/rpds_py-0.30.0-cp314-cp314-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3e62880792319dbeb7eb866547f2e35973289e7d5696c6e295476448f5b63c87", size = 516670, upload-time = "2025-11-30T20:23:33.742Z" }, + { url = "https://files.pythonhosted.org/packages/5b/3c/2882bdac942bd2172f3da574eab16f309ae10a3925644e969536553cb4ee/rpds_py-0.30.0-cp314-cp314-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:4e7fc54e0900ab35d041b0601431b0a0eb495f0851a0639b6ef90f7741b39a18", size = 408005, upload-time = "2025-11-30T20:23:35.253Z" }, + { url = "https://files.pythonhosted.org/packages/ce/81/9a91c0111ce1758c92516a3e44776920b579d9a7c09b2b06b642d4de3f0f/rpds_py-0.30.0-cp314-cp314-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:47e77dc9822d3ad616c3d5759ea5631a75e5809d5a28707744ef79d7a1bcfcad", size = 382112, upload-time = "2025-11-30T20:23:36.842Z" }, + { url = "https://files.pythonhosted.org/packages/cf/8e/1da49d4a107027e5fbc64daeab96a0706361a2918da10cb41769244b805d/rpds_py-0.30.0-cp314-cp314-manylinux_2_31_riscv64.whl", hash = "sha256:b4dc1a6ff022ff85ecafef7979a2c6eb423430e05f1165d6688234e62ba99a07", size = 399049, upload-time = "2025-11-30T20:23:38.343Z" }, + { url = "https://files.pythonhosted.org/packages/df/5a/7ee239b1aa48a127570ec03becbb29c9d5a9eb092febbd1699d567cae859/rpds_py-0.30.0-cp314-cp314-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:4559c972db3a360808309e06a74628b95eaccbf961c335c8fe0d590cf587456f", size = 415661, upload-time = "2025-11-30T20:23:40.263Z" }, + { url = "https://files.pythonhosted.org/packages/70/ea/caa143cf6b772f823bc7929a45da1fa83569ee49b11d18d0ada7f5ee6fd6/rpds_py-0.30.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:0ed177ed9bded28f8deb6ab40c183cd1192aa0de40c12f38be4d59cd33cb5c65", size = 565606, upload-time = "2025-11-30T20:23:42.186Z" }, + { url = "https://files.pythonhosted.org/packages/64/91/ac20ba2d69303f961ad8cf55bf7dbdb4763f627291ba3d0d7d67333cced9/rpds_py-0.30.0-cp314-cp314-musllinux_1_2_i686.whl", hash = "sha256:ad1fa8db769b76ea911cb4e10f049d80bf518c104f15b3edb2371cc65375c46f", size = 591126, upload-time = "2025-11-30T20:23:44.086Z" }, + { url = "https://files.pythonhosted.org/packages/21/20/7ff5f3c8b00c8a95f75985128c26ba44503fb35b8e0259d812766ea966c7/rpds_py-0.30.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:46e83c697b1f1c72b50e5ee5adb4353eef7406fb3f2043d64c33f20ad1c2fc53", size = 553371, upload-time = "2025-11-30T20:23:46.004Z" }, + { url = "https://files.pythonhosted.org/packages/72/c7/81dadd7b27c8ee391c132a6b192111ca58d866577ce2d9b0ca157552cce0/rpds_py-0.30.0-cp314-cp314-win32.whl", hash = "sha256:ee454b2a007d57363c2dfd5b6ca4a5d7e2c518938f8ed3b706e37e5d470801ed", size = 215298, upload-time = "2025-11-30T20:23:47.696Z" }, + { url = "https://files.pythonhosted.org/packages/3e/d2/1aaac33287e8cfb07aab2e6b8ac1deca62f6f65411344f1433c55e6f3eb8/rpds_py-0.30.0-cp314-cp314-win_amd64.whl", hash = "sha256:95f0802447ac2d10bcc69f6dc28fe95fdf17940367b21d34e34c737870758950", size = 228604, upload-time = "2025-11-30T20:23:49.501Z" }, + { url = "https://files.pythonhosted.org/packages/e8/95/ab005315818cc519ad074cb7784dae60d939163108bd2b394e60dc7b5461/rpds_py-0.30.0-cp314-cp314-win_arm64.whl", hash = "sha256:613aa4771c99f03346e54c3f038e4cc574ac09a3ddfb0e8878487335e96dead6", size = 222391, upload-time = "2025-11-30T20:23:50.96Z" }, + { url = "https://files.pythonhosted.org/packages/9e/68/154fe0194d83b973cdedcdcc88947a2752411165930182ae41d983dcefa6/rpds_py-0.30.0-cp314-cp314t-macosx_10_12_x86_64.whl", hash = "sha256:7e6ecfcb62edfd632e56983964e6884851786443739dbfe3582947e87274f7cb", size = 364868, upload-time = "2025-11-30T20:23:52.494Z" }, + { url = "https://files.pythonhosted.org/packages/83/69/8bbc8b07ec854d92a8b75668c24d2abcb1719ebf890f5604c61c9369a16f/rpds_py-0.30.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:a1d0bc22a7cdc173fedebb73ef81e07faef93692b8c1ad3733b67e31e1b6e1b8", size = 353747, upload-time = "2025-11-30T20:23:54.036Z" }, + { url = "https://files.pythonhosted.org/packages/ab/00/ba2e50183dbd9abcce9497fa5149c62b4ff3e22d338a30d690f9af970561/rpds_py-0.30.0-cp314-cp314t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0d08f00679177226c4cb8c5265012eea897c8ca3b93f429e546600c971bcbae7", size = 383795, upload-time = "2025-11-30T20:23:55.556Z" }, + { url = "https://files.pythonhosted.org/packages/05/6f/86f0272b84926bcb0e4c972262f54223e8ecc556b3224d281e6598fc9268/rpds_py-0.30.0-cp314-cp314t-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:5965af57d5848192c13534f90f9dd16464f3c37aaf166cc1da1cae1fd5a34898", size = 393330, upload-time = "2025-11-30T20:23:57.033Z" }, + { url = "https://files.pythonhosted.org/packages/cb/e9/0e02bb2e6dc63d212641da45df2b0bf29699d01715913e0d0f017ee29438/rpds_py-0.30.0-cp314-cp314t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9a4e86e34e9ab6b667c27f3211ca48f73dba7cd3d90f8d5b11be56e5dbc3fb4e", size = 518194, upload-time = "2025-11-30T20:23:58.637Z" }, + { url = "https://files.pythonhosted.org/packages/ee/ca/be7bca14cf21513bdf9c0606aba17d1f389ea2b6987035eb4f62bd923f25/rpds_py-0.30.0-cp314-cp314t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e5d3e6b26f2c785d65cc25ef1e5267ccbe1b069c5c21b8cc724efee290554419", size = 408340, upload-time = "2025-11-30T20:24:00.2Z" }, + { url = "https://files.pythonhosted.org/packages/c2/c7/736e00ebf39ed81d75544c0da6ef7b0998f8201b369acf842f9a90dc8fce/rpds_py-0.30.0-cp314-cp314t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:626a7433c34566535b6e56a1b39a7b17ba961e97ce3b80ec62e6f1312c025551", size = 383765, upload-time = "2025-11-30T20:24:01.759Z" }, + { url = "https://files.pythonhosted.org/packages/4a/3f/da50dfde9956aaf365c4adc9533b100008ed31aea635f2b8d7b627e25b49/rpds_py-0.30.0-cp314-cp314t-manylinux_2_31_riscv64.whl", hash = "sha256:acd7eb3f4471577b9b5a41baf02a978e8bdeb08b4b355273994f8b87032000a8", size = 396834, upload-time = "2025-11-30T20:24:03.687Z" }, + { url = "https://files.pythonhosted.org/packages/4e/00/34bcc2565b6020eab2623349efbdec810676ad571995911f1abdae62a3a0/rpds_py-0.30.0-cp314-cp314t-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:fe5fa731a1fa8a0a56b0977413f8cacac1768dad38d16b3a296712709476fbd5", size = 415470, upload-time = "2025-11-30T20:24:05.232Z" }, + { url = "https://files.pythonhosted.org/packages/8c/28/882e72b5b3e6f718d5453bd4d0d9cf8df36fddeb4ddbbab17869d5868616/rpds_py-0.30.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:74a3243a411126362712ee1524dfc90c650a503502f135d54d1b352bd01f2404", size = 565630, upload-time = "2025-11-30T20:24:06.878Z" }, + { url = "https://files.pythonhosted.org/packages/3b/97/04a65539c17692de5b85c6e293520fd01317fd878ea1995f0367d4532fb1/rpds_py-0.30.0-cp314-cp314t-musllinux_1_2_i686.whl", hash = "sha256:3e8eeb0544f2eb0d2581774be4c3410356eba189529a6b3e36bbbf9696175856", size = 591148, upload-time = "2025-11-30T20:24:08.445Z" }, + { url = "https://files.pythonhosted.org/packages/85/70/92482ccffb96f5441aab93e26c4d66489eb599efdcf96fad90c14bbfb976/rpds_py-0.30.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:dbd936cde57abfee19ab3213cf9c26be06d60750e60a8e4dd85d1ab12c8b1f40", size = 556030, upload-time = "2025-11-30T20:24:10.956Z" }, + { url = "https://files.pythonhosted.org/packages/20/53/7c7e784abfa500a2b6b583b147ee4bb5a2b3747a9166bab52fec4b5b5e7d/rpds_py-0.30.0-cp314-cp314t-win32.whl", hash = "sha256:dc824125c72246d924f7f796b4f63c1e9dc810c7d9e2355864b3c3a73d59ade0", size = 211570, upload-time = "2025-11-30T20:24:12.735Z" }, + { url = "https://files.pythonhosted.org/packages/d0/02/fa464cdfbe6b26e0600b62c528b72d8608f5cc49f96b8d6e38c95d60c676/rpds_py-0.30.0-cp314-cp314t-win_amd64.whl", hash = "sha256:27f4b0e92de5bfbc6f86e43959e6edd1425c33b5e69aab0984a72047f2bcf1e3", size = 226532, upload-time = "2025-11-30T20:24:14.634Z" }, +] + +[[package]] +name = "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 = "smmap" +version = "5.0.3" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/1f/ea/49c993d6dfdd7338c9b1000a0f36817ed7ec84577ae2e52f890d1a4ff909/smmap-5.0.3.tar.gz", hash = "sha256:4d9debb8b99007ae47165abc08670bd74cb74b5227dda7f643eccc4e9eb5642c", size = 22506, upload-time = "2026-03-09T03:43:26.1Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/c1/d4/59e74daffcb57a07668852eeeb6035af9f32cbfd7a1d2511f17d2fe6a738/smmap-5.0.3-py3-none-any.whl", hash = "sha256:c106e05d5a61449cf6ba9a1e650227ecfb141590d2a98412103ff35d89fc7b2f", size = 24390, upload-time = "2026-03-09T03:43:24.361Z" }, +] + +[[package]] +name = "streamlit" +version = "1.56.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "altair" }, + { name = "blinker" }, + { name = "cachetools" }, + { name = "click" }, + { name = "gitpython" }, + { name = "numpy" }, + { name = "packaging" }, + { name = "pandas" }, + { name = "pillow" }, + { name = "protobuf" }, + { name = "pyarrow" }, + { name = "pydeck" }, + { name = "requests" }, + { name = "tenacity" }, + { name = "toml" }, + { name = "tornado" }, + { name = "typing-extensions" }, + { name = "watchdog", marker = "sys_platform != 'darwin'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/03/85/7c669b3a1336d34ef39fa9760fbd343185f3b15db2ad0838fd78423d1c7f/streamlit-1.56.0.tar.gz", hash = "sha256:1176acfa89ae1318b79078e8efe689a9d02e8d58e325c00fc0e55fa2f3fe8d6a", size = 8559239, upload-time = "2026-03-31T22:29:38.59Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/e4/91/cb6f13a89e376ef179309d74f37a70ea0041d5e4b5ba5c4836dbf6e020ad/streamlit-1.56.0-py3-none-any.whl", hash = "sha256:8677a335734a30a51bc57ad0ec910e365d95f7c456fc02c60032927cd0729dc5", size = 9052089, upload-time = "2026-03-31T22:29:36.342Z" }, +] + +[[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 = "toml" +version = "0.10.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/be/ba/1f744cdc819428fc6b5084ec34d9b30660f6f9daaf70eead706e3203ec3c/toml-0.10.2.tar.gz", hash = "sha256:b3bda1d108d5dd99f4a20d24d9c348e91c4db7ab1b749200bded2f839ccbe68f", size = 22253, upload-time = "2020-11-01T01:40:22.204Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/44/6f/7120676b6d73228c96e17f1f794d8ab046fc910d781c8d151120c3f1569e/toml-0.10.2-py2.py3-none-any.whl", hash = "sha256:806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b", size = 16588, upload-time = "2020-11-01T01:40:20.672Z" }, +] + +[[package]] +name = "tornado" +version = "6.5.5" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/f8/f1/3173dfa4a18db4a9b03e5d55325559dab51ee653763bb8745a75af491286/tornado-6.5.5.tar.gz", hash = "sha256:192b8f3ea91bd7f1f50c06955416ed76c6b72f96779b962f07f911b91e8d30e9", size = 516006, upload-time = "2026-03-10T21:31:02.067Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/59/8c/77f5097695f4dd8255ecbd08b2a1ed8ba8b953d337804dd7080f199e12bf/tornado-6.5.5-cp39-abi3-macosx_10_9_universal2.whl", hash = "sha256:487dc9cc380e29f58c7ab88f9e27cdeef04b2140862e5076a66fb6bb68bb1bfa", size = 445983, upload-time = "2026-03-10T21:30:44.28Z" }, + { url = "https://files.pythonhosted.org/packages/ab/5e/7625b76cd10f98f1516c36ce0346de62061156352353ef2da44e5c21523c/tornado-6.5.5-cp39-abi3-macosx_10_9_x86_64.whl", hash = "sha256:65a7f1d46d4bb41df1ac99f5fcb685fb25c7e61613742d5108b010975a9a6521", size = 444246, upload-time = "2026-03-10T21:30:46.571Z" }, + { url = "https://files.pythonhosted.org/packages/b2/04/7b5705d5b3c0fab088f434f9c83edac1573830ca49ccf29fb83bf7178eec/tornado-6.5.5-cp39-abi3-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:e74c92e8e65086b338fd56333fb9a68b9f6f2fe7ad532645a290a464bcf46be5", size = 447229, upload-time = "2026-03-10T21:30:48.273Z" }, + { url = "https://files.pythonhosted.org/packages/34/01/74e034a30ef59afb4097ef8659515e96a39d910b712a89af76f5e4e1f93c/tornado-6.5.5-cp39-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:435319e9e340276428bbdb4e7fa732c2d399386d1de5686cb331ec8eee754f07", size = 448192, upload-time = "2026-03-10T21:30:51.22Z" }, + { url = "https://files.pythonhosted.org/packages/be/00/fe9e02c5a96429fce1a1d15a517f5d8444f9c412e0bb9eadfbe3b0fc55bf/tornado-6.5.5-cp39-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:3f54aa540bdbfee7b9eb268ead60e7d199de5021facd276819c193c0fb28ea4e", size = 448039, upload-time = "2026-03-10T21:30:53.52Z" }, + { url = "https://files.pythonhosted.org/packages/82/9e/656ee4cec0398b1d18d0f1eb6372c41c6b889722641d84948351ae19556d/tornado-6.5.5-cp39-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:36abed1754faeb80fbd6e64db2758091e1320f6bba74a4cf8c09cd18ccce8aca", size = 447445, upload-time = "2026-03-10T21:30:55.541Z" }, + { url = "https://files.pythonhosted.org/packages/5a/76/4921c00511f88af86a33de770d64141170f1cfd9c00311aea689949e274e/tornado-6.5.5-cp39-abi3-win32.whl", hash = "sha256:dd3eafaaeec1c7f2f8fdcd5f964e8907ad788fe8a5a32c4426fbbdda621223b7", size = 448582, upload-time = "2026-03-10T21:30:57.142Z" }, + { url = "https://files.pythonhosted.org/packages/2c/23/f6c6112a04d28eed765e374435fb1a9198f73e1ec4b4024184f21faeb1ad/tornado-6.5.5-cp39-abi3-win_amd64.whl", hash = "sha256:6443a794ba961a9f619b1ae926a2e900ac20c34483eea67be4ed8f1e58d3ef7b", size = 448990, upload-time = "2026-03-10T21:30:58.857Z" }, + { url = "https://files.pythonhosted.org/packages/b7/c8/876602cbc96469911f0939f703453c1157b0c826ecb05bdd32e023397d4e/tornado-6.5.5-cp39-abi3-win_arm64.whl", hash = "sha256:2c9a876e094109333f888539ddb2de4361743e5d21eece20688e3e351e4990a6", size = 448016, upload-time = "2026-03-10T21:31:00.43Z" }, +] + +[[package]] +name = "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 = "tzdata" +version = "2026.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/19/f5/cd531b2d15a671a40c0f66cf06bc3570a12cd56eef98960068ebbad1bf5a/tzdata-2026.1.tar.gz", hash = "sha256:67658a1903c75917309e753fdc349ac0efd8c27db7a0cb406a25be4840f87f98", size = 197639, upload-time = "2026-04-03T11:25:22.002Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/b0/70/d460bd685a170790ec89317e9bd33047988e4bce507b831f5db771e142de/tzdata-2026.1-py2.py3-none-any.whl", hash = "sha256:4b1d2be7ac37ceafd7327b961aa3a54e467efbdb563a23655fbfe0d39cfc42a9", size = 348952, upload-time = "2026-04-03T11:25:20.313Z" }, +] + +[[package]] +name = "uritemplate" +version = "4.2.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/98/60/f174043244c5306c9988380d2cb10009f91563fc4b31293d27e17201af56/uritemplate-4.2.0.tar.gz", hash = "sha256:480c2ed180878955863323eea31b0ede668795de182617fef9c6ca09e6ec9d0e", size = 33267, upload-time = "2025-06-02T15:12:06.318Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/a9/99/3ae339466c9183ea5b8ae87b34c0b897eda475d2aec2307cae60e5cd4f29/uritemplate-4.2.0-py3-none-any.whl", hash = "sha256:962201ba1c4edcab02e60f9a0d3821e82dfc5d2d6662a21abd533879bdb8a686", size = 11488, upload-time = "2025-06-02T15:12:03.405Z" }, +] + +[[package]] +name = "urllib3" +version = "2.6.3" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/c7/24/5f1b3bdffd70275f6661c76461e25f024d5a38a46f04aaca912426a2b1d3/urllib3-2.6.3.tar.gz", hash = "sha256:1b62b6884944a57dbe321509ab94fd4d3b307075e0c2eae991ac71ee15ad38ed", size = 435556, upload-time = "2026-01-07T16:24:43.925Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/39/08/aaaad47bc4e9dc8c725e68f9d04865dbcb2052843ff09c97b08904852d84/urllib3-2.6.3-py3-none-any.whl", hash = "sha256:bf272323e553dfb2e87d9bfd225ca7b0f467b919d7bbd355436d3fd37cb0acd4", size = 131584, upload-time = "2026-01-07T16:24:42.685Z" }, +] + +[[package]] +name = "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/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 = "youtube-analytics" +version = "0.1.0" +source = { virtual = "." } +dependencies = [ + { name = "click" }, + { name = "google-api-python-client" }, + { name = "google-auth-httplib2" }, + { name = "google-auth-oauthlib" }, + { name = "pandas" }, + { name = "plotly" }, + { name = "streamlit" }, +] + +[package.metadata] +requires-dist = [ + { name = "click", specifier = ">=8.3.2" }, + { name = "google-api-python-client", specifier = ">=2.194.0" }, + { name = "google-auth-httplib2", specifier = ">=0.3.1" }, + { name = "google-auth-oauthlib", specifier = ">=1.3.1" }, + { name = "pandas", specifier = ">=3.0.2" }, + { name = "plotly", specifier = ">=6.7.0" }, + { name = "streamlit", specifier = ">=1.56.0" }, +]