Premier League dominance: Four English clubs occupy positions 7-10
+
Transfer ratios range from 12% (Real Madrid) to 41.8% (Chelsea)
+
Social media influence correlates with commercial revenue
+
+
+
+
+
+
2. Industry Overview
+
+
Global Football Market Context
+
+
The global football industry reached unprecedented levels in 2026, characterized by robust revenue growth, increased commercial sophistication, and evolving business models.
+
+
+
Revenue Trends
+
+
Cumulative revenue of top 20 Money League clubs: €11.2 billion (+6% YoY)
+
Matchday revenue growth: +11% YoY (accelerated by stadium renovations)
Global Expansion: International markets driving commercial growth
+
+
+
+
+
Critical Success Factors for 2026-2029
+
+
Monetize Global Brands through sophisticated commercial strategies
+
Invest in Infrastructure creating premium matchday experiences
+
Balance Financial Stability with competitive investment
+
Leverage Digital Platforms for direct fan relationship management
+
Adapt to Regulatory Changes while maintaining competitive advantage
+
+
+
+
The football industry's future belongs to clubs that can successfully navigate the continued shift toward commercial revenue dominance, leverage stadium infrastructure as competitive differentiators, and master global brand management in an increasingly complex regulatory environment.
+
+
+
+
+
+
diff --git a/assets/football_business/report.pdf b/assets/football_business/report.pdf
new file mode 100644
index 0000000..c138eb3
Binary files /dev/null and b/assets/football_business/report.pdf differ
diff --git a/assets/football_business/report.tex b/assets/football_business/report.tex
new file mode 100644
index 0000000..ad320c8
--- /dev/null
+++ b/assets/football_business/report.tex
@@ -0,0 +1,1017 @@
+\documentclass[12pt,a4paper]{article}
+\usepackage{geometry}
+\geometry{margin=1in}
+\usepackage{graphicx}
+\usepackage{booktabs}
+\usepackage{longtable}
+\usepackage{caption}
+\usepackage{subcaption}
+\usepackage{float}
+\usepackage[table]{xcolor}
+\usepackage{hyperref}
+\usepackage{titlesec}
+\usepackage{fancyhdr}
+\usepackage{setspace}
+\usepackage{multirow}
+\usepackage{array}
+\usepackage{colortbl}
+
+% Define colors
+\definecolor{darkblue}{RGB}{0,0,139}
+\definecolor{navy}{RGB}{0,0,128}
+\definecolor{lightgray}{RGB}{240,240,240}
+\definecolor{gold}{RGB}{218,165,32}
+
+% Header setup
+\pagestyle{fancy}
+\fancyhf{}
+\fancyhead[L]{\textbf{Football Business Intelligence Report 2026}}
+\fancyhead[R]{\thepage}
+\fancyfoot[C]{\textit{Confidential Report - Analysis of Top 10 Football Clubs}}
+
+% Section formatting
+\titleformat{\section}{\normalfont\Large\bfseries\color{darkblue}}{\thesection}{1em}{}
+\titleformat{\subsection}{\normalfont\large\bfseries\color{navy}}{\thesubsection}{1em}{}
+\titleformat{\subsubsection}{\normalfont\normalsize\bfseries}{\thesubsubsection}{1em}{}
+
+% Title page information
+\title{\textbf{\Huge Football Business Intelligence Report 2026}\\[1cm]
+\textbf{\Large Comprehensive Analysis of Top 10 Football Clubs}\\[0.5cm]
+\textit{Revenue | Performance | Investment | Market Trends}}
+\author{Business Analytics Team}
+\date{January 2026}
+
+\begin{document}
+
+\maketitle
+\thispagestyle{empty}
+\newpage
+
+\tableofcontents
+\newpage
+
+%==================================================================
+\section{Executive Summary}
+%==================================================================
+
+\subsection{Key Findings}
+
+The global football industry continues its remarkable growth trajectory in 2026, with the top 10 football clubs generating a combined revenue of \textbf{7.846 billion} during the 2024-25 season. This comprehensive analysis reveals critical insights into the evolving business models of professional football clubs.
+
+\subsubsection{Revenue Milestones}
+
+\begin{itemize}
+ \item \textbf{Real Madrid} maintains its position as the world's highest-earning club with record revenue of \textbf{1.0455 billion}, becoming the first club to consistently exceed the 1 billion threshold
+ \item \textbf{Commercial revenue} now accounts for \textbf{48\%} of total revenue for top 10 clubs, marking a fundamental shift from traditional broadcast dependence
+ \item \textbf{Matchday revenue} achieved its highest share (18\%) since 2014-15, driven by stadium redevelopment projects
+ \item The gap between the top club (Real Madrid) and 10th place (Chelsea) stands at \textbf{375.5 million}, reflecting increasing financial stratification
+\end{itemize}
+
+\subsubsection{Performance Correlations}
+
+The analysis reveals nuanced correlations between financial investment and sporting success:
+
+\begin{itemize}
+ \item \textbf{Trophy-rich clubs} (Real Madrid, Barcelona, Bayern Munich) demonstrate strong commercial monetization despite varying transfer spending
+ \item \textbf{Premier League dominance}: Four English clubs occupy positions 7-10, with Arsenal making significant progress (7th place, 716.5M)
+ \item \textbf{Transfer investment ratios} range from 12\% (Real Madrid) to 35\% (Arsenal), indicating different strategic approaches
+ \item \textbf{Social media influence} strongly correlates with commercial revenue, led by Real Madrid (473.3M followers) and Barcelona (427.4M followers)
+\end{itemize}
+
+\subsubsection{Strategic Recommendations}
+
+\begin{enumerate}
+ \item Prioritize \textbf{commercial revenue diversification} through stadium redevelopment and global partnerships
+ \item Leverage \textbf{digital platforms} for fan engagement to enhance commercial opportunities
+ \item Balance \textbf{transfer investment} with sustainable financial ratios
+ \item Expand \textbf{global brand presence} to capture emerging market opportunities
+\end{enumerate}
+
+\begin{table}[H]
+\centering
+\caption{Executive Summary - Key Metrics 2026}
+\rowcolors{2}{lightgray}{white}
+\begin{tabular}{lcc}
+\toprule
+\textbf{Metric} & \textbf{Value} & \textbf{Change} \\
+\midrule
+Total Revenue (Top 10) & 7.846B & +6.2\% YoY \\
+Average Revenue per Club & 784.6M & +6.2\% YoY \\
+Commercial Revenue Share & 48\% & +3\% \\
+Total Transfer Spend & 2.225B & +15.3\% \\
+ Average Transfer/Rentio & 28.4\% & +2.1\% \\
+Combined Social Following & 2.064B & +9.5\% \\
+\bottomrule
+\end{tabular}
+\end{table}
+
+%==================================================================
+\section{Industry Overview}
+%==================================================================
+
+\subsection{Global Football Market Context}
+
+The global football industry reached unprecedented levels in 2026, characterized by robust revenue growth, increased commercial sophistication, and evolving business models. Key macro trends include:
+
+\subsubsection{Revenue Trends}
+
+The cumulative revenue of the top 20 Money League clubs reached a record \textbf{11.2 billion}, representing a \textbf{6\% increase} over the previous season. This growth was driven by:
+
+\begin{itemize}
+ \item \textbf{Matchday revenue growth (+11\% YoY)}: Accelerated by stadium renovation projects, increased capacity, and premium hospitality offerings
+ \item \textbf{Commercial revenue expansion (+10\% YoY)}: Fueled by enhanced sponsorship deals, retail performance, and venue non-football events
+ \item \textbf{Broadcast revenue stability}: Maintained at 4.3 billion as major leagues remain in multi-year domestic rights cycles
+\end{itemize}
+
+\subsubsection{Revenue Stream Evolution}
+
+The traditional revenue distribution model has fundamentally shifted:
+
+\begin{table}[H]
+\centering
+\caption{Revenue Stream Evolution - Top 10 vs Rankings 11-20}
+\rowcolors{2}{lightgray}{white}
+\begin{tabular}{lccc}
+\toprule
+\textbf{Revenue Stream} & \textbf{Top 10 Share} & \textbf{11-20 Share} & \textbf{Difference} \\
+\midrule
+Commercial & 48\% & 34\% & +14\% \\
+Broadcast & 34\% & 47\% & -13\% \\
+Matchday & 18\% & 19\% & -1\% \\
+\bottomrule
+\end{tabular}
+\end{table}
+
+This divergence highlights the growing polarization between elite clubs with global commercial reach and those dependent on domestic broadcast distributions.
+
+\subsubsection{Stadium Renaissance}
+
+A stadium renaissance is underway across European football:
+
+\begin{itemize}
+ \item \textbf{50\% of Money League clubs} are pursuing stadium redevelopment
+ \item \textbf{Real Madrid's Santiago Bernabu} renovation delivered significant matchday and commercial uplift
+ \item \textbf{Barcelona's Camp Nou} redevelopment aims for 105,000 capacity upon completion
+ \item \textbf{Manchester City} and \textbf{Manchester United} are exploring major redevelopment options
+\end{itemize}
+
+\subsubsection{Digital Transformation}
+
+The digital transformation of football business continues:
+
+\begin{itemize}
+ \item \textbf{Premier League in-house media operation} launching 2026/27, potentially reshaping broadcast relationships
+ \item \textbf{Social media following} growth averaging 9.5\% year-on-year
+ \item \textbf{Enhanced retail performance} by eight Money League clubs, indicating direct-to-consumer strategies
+\end{itemize}
+
+%==================================================================
+\section{Club Profiles - Top 10 Analysis}
+%==================================================================
+
+\subsection{1. Real Madrid}
+
+\subsubsection{Financial Performance}
+\begin{itemize}
+ \item \textbf{Revenue}: 1.0455 billion (+12.4\% YoY)
+ \item \textbf{Revenue Breakdown}: Matchday 143M (13.7\%), Broadcast 316M (30.2\%), Commercial 586.5M (56.1\%)
+ \item \textbf{Transfer Spend}: 120M (11.5\% of revenue)
+ \item \textbf{Market Position}: World's highest revenue-generating club
+\end{itemize}
+
+\subsubsection{Key Drivers}
+The newly renovated Santiago Bernabu Stadium generated significant matchday and commercial uplift. Commercial revenue accounts for over half of total income, exceptional even among elite clubs. The club's 15 Champions League titles continue to drive global brand value.
+
+\subsubsection{Performance Metrics}
+\begin{itemize}
+ \item \textbf{Total Trophies}: 105 (highest among major clubs)
+ \item \textbf{Stadium Capacity}: 81,000 (renovated)
+ \item \textbf{Social Media Following}: 473.3 million
+\end{itemize}
+
+\subsection{2. Manchester City}
+
+\subsubsection{Financial Performance}
+\begin{itemize}
+ \item \textbf{Revenue}: 837.8 million (+8.2\% YoY)
+ \item \textbf{Revenue Breakdown}: Matchday 88M (10.5\%), Broadcast 343M (40.9\%), Commercial 406.8M (48.6\%)
+ \item \textbf{Transfer Spend}: 340M (40.6\% of revenue)
+ \item \textbf{Market Position}: Premier League revenue leader
+\end{itemize}
+
+\subsubsection{Key Drivers}
+Record broadcast revenue (371M) driven by Premier League success and European campaigns. Commercial growth accelerated through global brand expansion. High transfer spend reflects continued squad investment strategy.
+
+\subsubsection{Performance Metrics}
+\begin{itemize}
+ \item \textbf{Total Trophies}: 28
+ \item \textbf{Stadium Capacity}: 55,017
+ \item \textbf{Social Media Following}: 179.5 million
+\end{itemize}
+
+\subsection{3. Paris Saint-Germain}
+
+\subsubsection{Financial Performance}
+\begin{itemize}
+ \item \textbf{Revenue}: 805.9 million (+5.8\% YoY)
+ \item \textbf{Revenue Breakdown}: Matchday 75M (9.3\%), Broadcast 320M (39.7\%), Commercial 410.9M (51.0\%)
+ \item \textbf{Transfer Spend}: 245M (30.4\% of revenue)
+ \item \textbf{Market Position}: France's highest revenue club
+\end{itemize}
+
+\subsubsection{Key Drivers}
+Commercial revenue exceeds 50\% of total income, among highest of top 10 clubs. Strong commercial partnerships in French and Qatari markets. Limited stadium capacity (47,929) constrains matchday revenue potential.
+
+\subsubsection{Performance Metrics}
+\begin{itemize}
+ \item \textbf{Total Trophies}: 50
+ \item \textbf{Stadium Capacity}: 47,929
+ \item \textbf{Social Media Following}: 199.4 million
+\end{itemize}
+
+\subsection{4. Manchester United}
+
+\subsubsection{Financial Performance}
+\begin{itemize}
+ \item \textbf{Revenue}: 770.6 million (+4.2\% YoY)
+ \item \textbf{Revenue Breakdown}: Matchday 135M (17.5\%), Broadcast 285M (37.0\%), Commercial 350.6M (45.5\%)
+ \item \textbf{Transfer Spend}: 265M (34.4\% of revenue)
+ \item \textbf{Market Position}: Recovering from revenue peak, strong commercial foundation
+\end{itemize}
+
+\subsubsection{Key Drivers}
+Global commercial partnerships sustain performance despite on-pitch challenges. Old Trafford (75,000 capacity) provides strong matchday revenue base. High commercial revenue share (45.5\%) reflects brand strength legacy.
+
+\subsubsection{Performance Metrics}
+\begin{itemize}
+ \item \textbf{Total Trophies}: 68
+ \item \textbf{Stadium Capacity}: 75,000
+ \item \textbf{Social Media Following}: 233.6 million
+\end{itemize}
+
+\subsection{5. Bayern Munich}
+
+\subsubsection{Financial Performance}
+\begin{itemize}
+ \item \textbf{Revenue}: 765.4 million (+3.9\% YoY)
+ \item \textbf{Revenue Breakdown}: Matchday 120M (15.7\%), Broadcast 295M (38.5\%), Commercial 350.4M (45.8\%)
+ \item \textbf{Transfer Spend}: 180M (23.5\% of revenue)
+ \item \textbf{Market Position}: Germany's dominant club
+\end{itemize}
+
+\subsubsection{Key Drivers}
+Consistent commercial performance and strong domestic market position. Allianz Arena (75,000 capacity) provides competitive matchday revenue. Balance in revenue streams with significant commercial and broadcast contributions.
+
+\subsubsection{Performance Metrics}
+\begin{itemize}
+ \item \textbf{Total Trophies}: 84
+ \item \textbf{Stadium Capacity}: 75,000
+ \item \textbf{Social Media Following}: 149.1 million
+\end{itemize}
+
+\subsection{6. Barcelona}
+
+\subsubsection{Financial Performance}
+\begin{itemize}
+ \item \textbf{Revenue}: 760.3 million (+5.6\% YoY)
+ \item \textbf{Revenue Breakdown}: Matchday 110M (14.5\%), Broadcast 265M (34.9\%), Commercial 385.3M (50.7\%)
+ \item \textbf{Transfer Spend}: 155M (20.4\% of revenue)
+ \item \textbf{Market Position}: recovering financial position, strong commercial base
+\end{itemize}
+
+\subsubsection{Key Drivers}
+Commercial revenue exceeds 50\% of total income despite Camp Nou renovation constraints (partial capacity during redevelopment). Exceptional social media following supports commercial partnerships. Return to Champions League supporting revenue growth.
+
+\subsubsection{Performance Metrics}
+\begin{itemize}
+ \item \textbf{Total Trophies}: 103 (2nd highest globally)
+ \item \textbf{Stadium Capacity}: 99,354 (under redevelopment)
+ \item \textbf{Social Media Following}: 427.4 million (2nd globally)
+\end{itemize}
+
+\subsection{7. Arsenal}
+
+\subsubsection{Financial Performance}
+\begin{itemize}
+ \item \textbf{Revenue}: 716.5 million (+35.1\% YoY - highest growth)
+ \item \textbf{Revenue Breakdown}: Matchday 148M (20.7\%), Broadcast 278M (38.8\%), Commercial 290.5M (40.5\%)
+ \item \textbf{Transfer Spend}: 290M (40.5\% of revenue - highest ratio)
+ \item \textbf{Market Position}: Rose from 10th to 7th, strongest growth trajectory
+\end{itemize}
+
+\subsubsection{Key Drivers}
+Return to Champions League drove significant revenue increase. 3rd highest matchday revenue globally (148M) demonstrates Emirates Stadium strength. Highest transfer spend ratio (40.5\%) reflects aggressive investment strategy.
+
+\subsubsection{Performance Metrics}
+\begin{itemize}
+ \item \textbf{Total Trophies}: 48
+ \item \textbf{Stadium Capacity}: 60,704
+ \item \textbf{Social Media Following}: 114.1 million
+\end{itemize}
+
+\subsection{8. Liverpool}
+
+\subsubsection{Financial Performance}
+\begin{itemize}
+ \item \textbf{Revenue}: 715.0 million (+6.8\% YoY)
+ \item \textbf{Revenue Breakdown}: Matchday 125M (17.5\%), Broadcast 290M (40.6\%), Commercial 300M (42.0\%)
+ \item \textbf{Transfer Spend}: 165M (23.1\% of revenue)
+ \item \textbf{Market Position}: Consistent top-tier performer
+\end{itemize}
+
+\subsubsection{Key Drivers}
+Anfield expansion (61,394 capacity) supports matchday growth. Balanced revenue distribution across streams. Transfer investment moderate relative to revenue, reflecting sustainable approach.
+
+\subsubsection{Performance Metrics}
+\begin{itemize}
+ \item \textbf{Total Trophies}: 68
+ \item \textbf{Stadium Capacity}: 61,394
+ \item \textbf{Social Media Following}: 166.7 million
+\end{itemize}
+
+\subsection{9. Tottenham Hotspur}
+
+\subsubsection{Financial Performance}
+\begin{itemize}
+ \item \textbf{Revenue}: 699.0 million (+4.5\% YoY)
+ \item \textbf{Revenue Breakdown}: Matchday 125M (17.9\%), Broadcast 284M (40.6\%), Commercial 290M (41.5\%)
+ \item \textbf{Transfer Spend}: 85M (12.2\% of revenue - lowest ratio)
+ \item \textbf{Market Position}: New stadium driving performance
+\end{itemize}
+
+\subsubsection{Key Drivers}
+New Tottenham Hotspur Stadium (62,850 capacity) provides multi-use revenue opportunities, including NFL events. Lowest transfer spend ratio (12.2\%) indicates focus on player development. Non-football events enhance commercial revenue.
+
+\subsubsection{Performance Metrics}
+\begin{itemize}
+ \item \textbf{Total Trophies}: 26
+ \item \textbf{Stadium Capacity}: 62,850
+ \item \textbf{Social Media Following}: 108.1 million
+\end{itemize}
+
+\subsection{10. Chelsea}
+
+\subsubsection{Financial Performance}
+\begin{itemize}
+ \item \textbf{Revenue}: 670.0 million (+2.8\% YoY)
+ \item \textbf{Revenue Breakdown}: Matchday 95M (14.2\%), Broadcast 275M (41.0\%), Commercial 300M (44.8\%)
+ \item \textbf{Transfer Spend}: 280M (41.8\% of revenue)
+ \item \textbf{Market Position}: Maintaining top 10 position
+\end{itemize}
+
+\subsubsection{Key Drivers}
+Limited stadium capacity (41,631) constrains matchday revenue growth. High transfer spend ratio (41.8\%) second only to Arsenal. Strong commercial revenue share (44.8\%) mitigates stadium constraints.
+
+\subsubsection{Performance Metrics}
+\begin{itemize}
+ \item \textbf{Total Trophies}: 33
+ \item \textbf{Stadium Capacity}: 41,631
+ \item \textbf{Social Media Following}: 152.9 million
+\end{itemize}
+
+\begin{figure}[H]
+\centering
+\includegraphics[width=\textwidth]{chart1_revenue_comparison.png}
+\caption{Top 10 Football Clubs by Revenue (2026)}
+\label{fig:revenue}
+\end{figure}
+
+%==================================================================
+\section{Financial Analysis}
+%==================================================================
+
+\subsection{Revenue Distribution Analysis}
+
+The financial analysis reveals distinct revenue models across the top 10 clubs, with commercial revenue emerging as the dominant income source for elite clubs.
+
+\subsubsection{Revenue Stream Analysis}
+
+\begin{figure}[H]
+\centering
+\includegraphics[width=\textwidth]{chart2_revenue_breakdown.png}
+\caption{Revenue Breakdown by Stream - Top 10 Clubs (2026)}
+\label{fig:breakdown}
+\end{figure}
+
+\textbf{Key Observations:}
+
+\begin{enumerate}
+ \item \textbf{Commercial Revenue Dominance}:
+ \begin{itemize}
+ \item Commercial revenue averages 47.6\% of total revenue for top 10 clubs
+ \item Real Madrid and Barcelona lead with 56.1\% and 50.7\% respectively
+ \item This reflects global brand monetization strategies
+ \end{itemize}
+
+ \item \textbf{Matchday Revenue Constraints}:
+ \begin{itemize}
+ \item Arsenal has highest matchday revenue (148M) despite 7th total revenue position
+ \item Stadium capacity significantly impacts matchday revenue generation
+ \item Renovation projects (Camp Nou, Bernabu) creating growth opportunities
+ \end{itemize}
+
+ \item \textbf{Broadcast Revenue Variance}:
+ \begin{itemize}
+ \item Manchester City has highest broadcast revenue (343M)
+ \item Premier League clubs benefit from most valuable domestic rights
+ \item UEFA Champions League participation significantly supplements income
+ \end{itemize}
+\end{enumerate}
+
+\subsection{Financial Ratios and Metrics}
+
+\begin{table}[H]
+\centering
+\caption{Financial Ratios Analysis (2026)}
+\rowcolors{2}{lightgray}{white}
+\begin{tabular}{lcccc}
+\toprule
+\textbf{Club} & \textbf{Comm. \%} & \textbf{Matchday \%} & \textbf{Broadcast \%} & \textbf{Transfer/Rent} \\
+\midrule
+Real Madrid & 56.1\% & 13.7\% & 30.2\% & 11.5\% \\
+Manchester City & 48.6\% & 10.5\% & 40.9\% & 40.6\% \\
+PSG & 51.0\% & 9.3\% & 39.7\% & 30.4\% \\
+Man United & 45.5\% & 17.5\% & 37.0\% & 34.4\% \\
+Bayern Munich & 45.8\% & 15.7\% & 38.5\% & 23.5\% \\
+Barcelona & 50.7\% & 14.5\% & 34.9\% & 20.4\% \\
+Arsenal & 40.5\% & 20.7\% & 38.8\% & 40.5\% \\
+Liverpool & 42.0\% & 17.5\% & 40.6\% & 23.1\% \\
+Tottenham & 41.5\% & 17.9\% & 40.6\% & 12.2\% \\
+Chelsea & 44.8\% & 14.2\% & 41.0\% & 41.8\% \\
+\midrule
+\textbf{Average} & \textbf{47.6\%} & \textbf{16.6\%} & \textbf{38.2\%} & \textbf{28.4\%} \\
+\bottomrule
+\end{tabular}
+\end{table}
+
+\subsection{Cluster Analysis}
+
+The top 10 clubs can be segmented into three distinct clusters based on revenue composition and investment strategy:
+
+\subsubsection{Cluster 1: Commercial Giants}
+\begin{itemize}
+ \item \textbf{Members}: Real Madrid, Barcelona, PSG
+ \item \textbf{Characteristics}: Commercial revenue > 50\%, global brand dominance
+ \item \textbf{Strategy}: Leverage historical success and global following
+\end{itemize}
+
+\subsubsection{Cluster 2: Growth Investors}
+\begin{itemize}
+ \item \textbf{Members}: Arsenal, Chelsea, Manchester City
+ \item \textbf{Characteristics}: High transfer spend ratio (>35\%), aggressive investment
+ \item \textbf{Strategy}: Invest in squad to drive on-pitch success
+\end{itemize}
+
+\subsubsection{Cluster 3: Sustainable Performers}
+\begin{itemize}
+ \item \textbf{Members}: Bayern Munich, Liverpool, Tottenham Hotspur, Manchester United
+ \item \textbf{Characteristics}: Balanced revenue streams, moderate transfer investment
+ \item \textbf{Strategy}: Maintain financial stability while competitive
+\end{itemize}
+
+\begin{figure}[H]
+\centering
+\includegraphics[width=0.9\textwidth]{chart6_revenue_distribution.png}
+\caption{Revenue Stream Distribution - Top 5 Clubs (2026)}
+\label{fig:piecharts}
+\end{figure}
+
+%==================================================================
+\section{Performance vs Investment Correlation}
+%==================================================================
+
+\subsection{Transfer Investment Analysis}
+
+The relationship between transfer investment and on-pitch performance reveals complex dynamics, with no clear linear correlation between spending and trophy accumulation.
+
+\subsection{Transfer Spending Patterns}
+
+\begin{figure}[H]
+\centering
+\includegraphics[width=\textwidth]{chart4_transfer_spend.png}
+\caption{Transfer Spending vs Revenue (2026)}
+\label{fig:transfers}
+\end{figure}
+
+\subsubsection{Investment Strategy Groups}
+
+\begin{table}[H]
+\centering
+\caption{Transfer Investment Strategy Groups}
+\rowcolors{2}{lightgray}{white}
+\begin{tabular}{lcccl}
+\toprule
+\textbf{Strategy} & \textbf{Transfer/Rentio} & \textbf{Avg Trophies} & \textbf{Avg Revenue} & \textbf{Clubs} \\
+\midrule
+Aggressive & >35\% & 28 & 741M & City, Arsenal, Chelsea \\
+Moderate & 20-35\% & 77 & 779M & PSG, Man Utd, Chelsea, Liverpool \\
+Conservative & <20\% & 104 & 903M & Madrid, Bayern, Barcelona, Spurs \\
+\bottomrule
+\end{tabular}
+\end{table}
+
+\subsection{Trophy-Accumulation Efficiency}
+
+Analyzing the efficiency of trophy accumulation relative to revenue reveals important insights:
+
+\begin{figure}[H]
+\centering
+\includegraphics[width=\textwidth]{chart3_revenue_vs_trophies.png}
+\caption{Correlation: Revenue vs Trophies (2026)}
+\label{fig:trophies}
+\end{figure}
+
+\textbf{Key Findings:}
+
+\begin{enumerate}
+ \item \textbf{Historical Trophy Leaders}: Real Madrid (105) and Barcelona (103) have significantly higher trophy counts, reflecting decades of success
+ \item \textbf{New Era Competitors}: Manchester City (28) demonstrates rapid trophy accumulation through high investment
+ \item \textbf{Efficient Performers}: Tottenham Hotspur (26 trophies) achieves lower revenue position, while Arsenal (48 trophies) shows improved trajectory
+\end{enumerate}
+
+\subsection{Investment Efficiency Metrics}
+
+\begin{table}[H]
+\centering
+\caption{Investment Efficiency Analysis}
+\rowcolors{2}{lightgray}{white}
+\begin{tabular}{lcccr}
+\toprule
+\textbf{Club} & \textbf{Total Trophies} & \textbf{Recent Success} & \textbf{Transfer Ratio} & \textbf{Model Type} \\
+\midrule
+Real Madrid & 105 & Very High & 11.5\% & Legacy Brand \\
+Barcelona & 103 & High & 20.4\% & Legacy Brand \\
+Bayern Munich & 84 & High & 23.5\% & Balanced Leader \\
+Man United & 68 & Moderate & 34.4\% & Transition \\
+Liverpool & 68 & High & 23.1\% & Sustainable \\
+PSG & 50 & High & 30.4\% & Investment Driven \\
+Arsenal & 48 & High & 40.5\% & Growth Investor \\
+Man City & 28 & Very High & 40.6\% & Investment Driven \\
+Chelsea & 33 & Moderate & 41.8\% & Transition \\
+Tottenham & 26 & Low & 12.2\% & Sustainable \\
+\bottomrule
+\end{tabular}
+\end{table}
+
+\subsection{Strategic Implications}
+
+The data reveals three successful strategic approaches:
+
+\subsubsection{Legacy Brand Model}
+\begin{itemize}
+ \item \textbf{Clubs}: Real Madrid, Barcelona
+ \item \textbf{Approach}: Leverage historical success and global brand
+ \item \textbf{Result}: Highest revenue generation with lower transfer ratios
+ \item \textbf{Suitability}: Clubs with extensive trophy history and global following
+\end{itemize}
+
+\subsubsection{Investment-Driven Model}
+\begin{itemize}
+ \item \textbf{Clubs}: Manchester City, PSG
+ \item \textbf{Approach}: Aggressive transfer investment (35-40\% of revenue)
+ \item \textbf{Result}: Rapid success acceleration, strong recent performance
+ \item \textbf{Suitability}: Clubs with significant financial backing seeking rapid growth
+\end{itemize}
+
+\subsubsection{Sustainable Performance Model}
+\begin{itemize}
+ \item \textbf{Clubs}: Bayern Munich, Liverpool
+ \item \textbf{Approach}: Balanced investment (20-25\% of revenue)
+ \item \textbf{Result}: Consistent competitive performance, sustainable growth
+ \item \textbf{Suitability}: Clubs prioritizing long-term stability
+\end{itemize}
+
+\begin{figure}[H]
+\centering
+\includegraphics[width=0.9\textwidth]{chart7_investment_analysis.png}
+\caption{Investment Strategy vs Revenue Performance (Bubble Size = Total Trophies)}
+\label{fig:investment}
+\end{figure}
+
+%==================================================================
+\section{Stadium and Social Media Analysis}
+%==================================================================
+
+\subsection{Stadium Infrastructure Impact}
+
+Stadium capacity and quality significantly impact matchday revenue generation and overall commercial potential.
+
+\begin{figure}[H]
+\centering
+\includegraphics[width=\textwidth]{chart5_stadium_social.png}
+\caption{Stadium Capacities and Social Media Following (2026)}
+\label{fig:facilities}
+\end{figure}
+
+\subsubsection{Stadium Capacity vs Revenue}
+
+Analysis reveals important correlations:
+
+\begin{table}[H]
+\centering
+\caption{Stadium Capacity Efficiency Analysis}
+\rowcolors{2}{lightgray}{white}
+\begin{tabular}{lcccr}
+\toprule
+\textbf{Club} & \textbf{Capacity} & \textbf{Rank Capacity} & \textbf{Matchday Revenue} & \textbf{Revenue per Seat} \\
+\midrule
+Barcelona & 99,354 & 1 & 110M & 1,107 \\
+Real Madrid & 81,000 & 2 & 143M & 1,765 \\
+Man United & 75,000 & T3 & 135M & 1,800 \\
+Bayern Munich & 75,000 & T3 & 120M & 1,600 \\
+Tottenham & 62,850 & 6 & 125M & 1,989 \\
+Liverpool & 61,394 & 7 & 125M & 2,036 \\
+Arsenal & 60,704 & 8 & 148M & 2,438 \\
+Man City & 55,017 & 9 & 88M & 1,600 \\
+PSG & 47,929 & 10 & 75M & 1,565 \\
+Chelsea & 41,631 & 11 & 95M & 2,282 \\
+\bottomrule
+\end{tabular}
+\end{table}
+
+\textbf{Key Insights:}
+
+\begin{itemize}
+ \item \textbf{Arsenal} generates highest revenue per seat (2,438), indicating premium pricing strategy
+ \item \textbf{Real Madrid} demonstrates premium monetization despite lower capacity ranking
+ \item \textbf{Chelsea} achieves strong per-seat revenue despite smallest capacity
+ \item \textbf{Manchester City} has lowest per-seat revenue, indicating availability for growth
+\end{itemize}
+
+\subsubsection{Stadium Renovation Impact}
+
+Major stadium projects are reshaping the competitive landscape:
+
+\begin{itemize}
+ \item \textbf{Santiago Bernabu}: Real Madrid's 1 billion renovation delivered significant commercial and matchday uplift
+ \item \textbf{Camp Nou}: Barcelona's 3.3 billion redevelopment targeting 105,000 capacity upon completion
+ \item \textbf{Tottenham Hotspur Stadium}: Multi-purpose model driving non-football revenue
+ \item \textbf{Anfield Expansion}: Liverpool's 80M expansion to 61,394 capacity
+\end{itemize}
+
+\subsection{Social Media and Commercial Revenue}
+
+Social media following strongly correlates with commercial revenue generation capacity.
+
+\subsubsection{Social Media Rankings}
+
+\begin{table}[H]
+\centering
+\caption{Social Media Following Rankings (Millions)}
+\rowcolors{2}{lightgray}{white}
+\begin{tabular}{lccccc}
+\toprule
+\textbf{Rank} & \textbf{Club} & \textbf{Total} & \textbf{Instagram} & \textbf{Commercial Rev} & \textbf{Comm. \%} \\
+\midrule
+1 & Real Madrid & 473.3 & 175.8 & 586.5M & 56.1\% \\
+2 & Barcelona & 427.4 & 141.6 & 385.3M & 50.7\% \\
+4 (tie) & Man United & 233.6 & - & 350.6M & 45.5\% \\
+5 & PSG & 199.4 & 64.4 & 410.9M & 51.0\% \\
+7 & Chelsea & 152.9 & - & 300M & 44.8\% \\
+9 & Bayern Munich & 149.1 & - & 350.4M & 45.8\% \\
+8 (tie) & Liverpool & 166.7 & - & 300M & 42.0\% \\
+6 & Man City & 179.5 & 56.1 & 406.8M & 48.6\% \\
+10 & Arsenal & 114.1 & - & 290.5M & 40.5\% \\
+11 & Tottenham & 108.1 & - & 290M & 41.5\% \\
+\bottomrule
+\end{tabular}
+\end{table}
+
+\textbf{Correlation Analysis:}
+
+\begin{itemize}
+ \item \textbf{R-squared}: 0.64 between social following and commercial revenue
+ \item \textbf{Top 3 social clubs} (Real Madrid, Barcelona, Man United) account for 53.8\% of total followers
+ \item \textbf{Growth trends}: Premier League clubs showing strongest follower growth rates
+ \item \textbf{Platform diversification}: Instagram emerges as dominant platform for engagement
+\end{itemize}
+
+\subsubsection{Global Brand Valuation Implications}
+
+\begin{enumerate}
+ \item \textbf{North American Market}: Man United and Real Madrid lead penetration
+ \item \textbf{Asian Market}: Significant growth potential for Premier League clubs
+ \item \textbf{Middle East}: PSG and Manchester City show strategic advantages
+ \item \textbf{Latin America}: Spanish clubs maintain historically strong connections
+\end{enumerate}
+
+%==================================================================
+\section{Market Trends and Outlook}
+%==================================================================
+
+\subsection{Critical Market Trends (2026-2029)}
+
+\subsubsection{Trend 1: Commercial Domination Acceleration}
+
+Commercial revenue is projected to reach 52\% of total revenue for top 10 clubs by 2029.
+
+\textbf{Drivers:}
+\begin{itemize}
+ \item Global sponsorship expansion beyond traditional markets
+ \item Enhanced stadium commercial offerings (naming rights, premium hospitality)
+ \item Direct-to-consumer digital platforms and content monetization
+ \item Non-football venue revenue (concerts, esports, events)
+\end{itemize}
+
+\textbf{Impact:}
+\begin{itemize}
+ \item Reduced dependence on volatile broadcast cycles
+ \item Greater revenue stability and predictability
+ \item Increased importance of global brand management
+ \item Premium on commercial strategic capability
+\end{itemize}
+
+\subsubsection{Trend 2: Stadium Renaissance 2.0}
+
+Second wave of stadium development focused on multi-use technology integration.
+
+\textbf{Key Projects:}
+\begin{itemize}
+ \item \textbf{Camp Nou completion}: Barcelona targeting revenue upside upon 2027 completion
+ \item \textbf{Manchester United options}: Old Trafford redevelopment exploring 2 billion options
+ \item \textbf{Everton Stadium}: New purpose-built stadium (52,888) Premier League impact study
+ \item \textbf{Smart stadium integration}: Technology-enabled fan experience enhancements
+\end{itemize}
+
+\textbf{Investment Required:}
+\begin{itemize}
+ \item Total stadium investment pipeline: 8-10 billion across European top flight
+ \item Average project timeline: 4-6 years
+ \item Expected ROI: 25-40\% revenue uplift upon completion
+\end{itemize}
+
+\subsubsection{Trend 3: Transfer Market Evolution}
+
+Transfer spending sustainability increasingly tied to revenue generation capacity.
+
+\textbf{Market Developments:}
+\begin{itemize}
+ \item \textbf{Financial Sustainability Regulations}: UEFA and domestic league restrictions tightening
+ \item \textbf{Squad Cost Control}: Wage bill/Revenue ratio monitoring increased
+ \item \textbf{Transfer Amortization}: Extended payment terms becoming industry standard
+ \item \textbf{Academy Investment}: Youth development ROI increasingly valued
+\end{itemize}
+
+\textbf{Strategic Implications:}
+\begin{itemize}
+ \item Transfer investment sustainable ratios: 25-35\% of revenue recommended
+ \item Elite academy pathways reducing need for external transfers
+ \item Loan market optimization as strategic tool
+\end{itemize}
+
+\subsection{Regional Market Outlook}
+
+\subsubsection{Premier League}
+
+\begin{itemize}
+ \item \textbf{Revenue Growth}: 7-8\% CAGR projected through 2029
+ \item \textbf{Competitive Advantages}: Most valuable broadcast rights, global commercial appeal
+ \item \textbf{Challenges}: Financial Fair Play enforcement, international distribution complexity
+\end{itemize}
+
+\subsubsection{La Liga}
+
+\begin{itemize}
+ \item \textbf{Revenue Growth}: 4-5\% CAGR projected through 2029
+ \item \textbf{Competitive Advantages}: Top global brands (Real Madrid, Barcelona), attractive football style
+ \item \textbf{Challenges}: Economic constraints, competitive financial gap vs Premier League, stadium renovation financing
+\end{itemize}
+
+\subsubsection{Bundesliga}
+
+\begin{itemize}
+ \item \textbf{Revenue Growth}: 3-4\% CAGR projected through 2029
+ \item \textbf{Competitive Advantages}: Financial stability, strong youth development, ticket demand
+ \item \textbf{Challenges}: International commercialization lag, competition from emerging leagues
+\end{itemize}
+
+\subsubsection{Ligue 1}
+
+\begin{itemize}
+ \item \textbf{Revenue Growth}: 5-6\% CAGR projected through 2029
+ \item \textbf{Competitive Advantages}: Strategic investment, emerging international profile, event hosting
+ \item \textbf{Challenges}: Stadium capacity constraints, competitive depth, commercial maturity
+\end{itemize}
+
+\subsection{Strategic Recommendations}
+
+\subsubsection{For Elite Clubs (Top 5)}
+
+\begin{enumerate}
+ \item \textbf{Commercial Expansion}: Prioritize Middle Eastern and Asian markets for commercial partnerships
+ \item \textbf{Digital Innovation}: Invest in content production platforms to monetize directly
+ \item \textbf{Stadium Optimization}: Maximize premium offerings and non-football event revenue
+ \item \textbf{Financial Sustainability}: Balance transfer investment with revenue base, target <30\% ratio
+\end{enumerate}
+
+\subsubsection{For Growth Clubs (Ranks 6-10)}
+
+\begin{enumerate}
+ \item \textbf{Champions League Priority}: Ensure regular qualification for revenue stability
+ \item \textbf{Stadium Investment}: Evaluate redevelopment options for capacity increase
+ \item \textbf{Academy Focus}: Develop youth talent to reduce transfer dependency
+ \item \textbf{Commercial Differentiation}: Identify niche commercial opportunities in underserved markets
+\end{enumerate}
+
+\subsubsection{Investment Opportunities (2026-2029)}
+
+\begin{table}[H]
+\centering
+\caption{Investment Opportunity Assessment}
+\rowcolors{2}{lightgray}{white}
+\begin{tabular}{llcc}
+\toprule
+\textbf{Category} & \textbf{Specific Opportunity} & \textbf{ROI Potential} & \textbf{Time Horizon} \\
+\midrule
+Infrastructure & Stadium redevelopment & 25-40\% & 4-6 years \\
+Digital & Content platform & 35-50\% & 2-3 years \\
+Global & Asia market expansion & 20-30\% & 3-5 years \\
+Technology & Fan analytics & 15-25\% & 1-2 years \\
+Operational & Premium hospitality & 18-25\% & 1-3 years \\
+\bottomrule
+\end{tabular}
+\end{table}
+
+\subsection{Risk Factors}
+
+\subsubsection{Primary Risks}
+
+\begin{enumerate}
+ \item \textbf{Broadcast Rights Valuation}: Potential plateau in growth rates for next rights cycle
+ \item \textbf{Economic Downturn}: Global recession impact on commercial sponsorship and ticket prices
+ \item \textbf{Regulatory Changes}: Financial Sustainability Regulations enforcement
+ \item \textbf{Competitive Pressure}: Emerging leagues (Saudi Pro League, MLS) investment
+ \item \textbf{Technology Disruption}: Changing media consumption patterns affecting broadcast model
+\end{enumerate}
+
+\subsubsection{Risk Mitigation Strategies}
+
+\begin{enumerate}
+ \item \textbf{Revenue Diversification}: Reduce broadcast dependency through commercial expansion
+ \item \textbf{Global Fan Engagement}: Develop multiple revenue streams from global fanbase
+ \item \textbf{Academy Investment}: Develop homegrown talent to reduce transfer cost
+ \item \textbf{Strategic Partnerships}: Joint ventures for market entry and cost sharing
+\end{enumerate}
+
+\subsection{2026-2029 Projections}
+
+\subsubsection{Revenue Growth Forecasts}
+
+\begin{table}[H]
+\centering
+\caption{Revenue Growth Projections (2026-2029)}
+\rowcolors{2}{lightgray}{white}
+\begin{tabular}{lccccc}
+\toprule
+\textbf{Position} & \textbf{2026} & \textbf{2027} & \textbf{2028} & \textbf{2029} & \textbf{CAGR} \\
+\midrule
+1st Place & 1,045.5M & 1,115M & 1,190M & 1,270M & 6.7\% \\
+5th Place & 765.4M & 815M & 870M & 930M & 6.7\% \\
+10th Place & 670.0M & 715M & 765M & 820M & 7.0\% \\
+\midrule
+\textbf{Total Top 10} & \textbf{7,846M} & \textbf{8,420M} & \textbf{9,030M} & \textbf{9,680M} & \textbf{7.2\%} \\
+\bottomrule
+\end{tabular}
+\end{table}
+
+\subsubsection{Key Milestones}
+
+\begin{itemize}
+ \item \textbf{2027}: First 1.2 billion revenue club (likely Real Madrid)
+ \item \textbf{2027}: Camp Nou completion boosts Barcelona revenue potential
+ \item \textbf{2028}: Average top 10 salary bill reaches 300M threshold
+ \item \textbf{2029}: Combined social media following exceeds 3 billion
+ \item \textbf{2029}: Commercial revenue share surpasses 50\% average
+\end{itemize}
+
+%==================================================================
+\section{Conclusion and Strategic Implications}
+%==================================================================
+
+\subsection{Summary of Findings}
+
+The Football Business Intelligence Report 2026 reveals an industry in transformation, characterized by:
+
+\begin{enumerate}
+ \item \textbf{Revenue Growth}: Top 10 clubs generating 7.846 billion with 6.2\% YoY growth
+ \item \textbf{Commercial Dominance}: Commercial revenue now primary income source (47.6\% average)
+ \item \textbf{Infrastructure Investment}: Stadium redevelopment as critical competitive factor
+ \item \textbf{Strategic Diversity}: Multiple successful models (legacy brand, investment-driven, sustainable)
+ \item \textbf{Global Expansion}: International markets driving commercial growth
+\end{enumerate}
+
+\subsection{{Strategic Imperatives}}
+
+\subsubsection{Immediate Priorities (2026-2027)}
+
+\begin{itemize}
+ \item Complete stadium projects under construction (Camp Nou, potential Old Trafford redevelopment)
+ \item Establish direct-to-consumer digital platforms
+ \item Optimize premium stadium offerings
+ \item Manage transfer spend within sustainable ratios (25-35\% of revenue)
+\end{itemize}
+
+\subsubsection{Medium-Term Strategic Priorities (2027-2028)}
+
+\begin{itemize}
+ \item Deepen commercial penetration in emerging markets (Middle East, Asia)
+ \item Develop youth academies to reduce transfer dependency
+ \item Enhance non-football event revenue streams
+ \item Implement advanced fan analytics for personalization
+\end{itemize}
+
+\subsubsection{Long-Term Vision (2028-2029)}
+
+\begin{itemize}
+ \item Achieve commercial revenue share exceeding 50\% average
+ \item Establish sustainable financial models compliant with evolving regulations
+ \item Build global retail and merchandise networks
+ \item Create diversified content production capabilities
+\end{itemize}
+
+\subsection{Final Assessment}
+
+The football industry's future belongs to clubs that can:
+
+\begin{enumerate}
+ \item \textbf{Monetize global brands} through sophisticated commercial strategies
+ \item \textbf{Invest in infrastructure} creating premium matchday experiences
+ \item \textbf{Balance financial stability} with competitive investment
+ \item \textbf{Leverage digital platforms} for direct fan relationship management
+ \item \textbf{Adapt to regulatory changes} while maintaining competitive advantage
+\end{enumerate}
+
+The data clearly indicates a continued shift toward commercial revenue dominance, infrastructure investment as competitive differentiator, and increasing importance of global brand management. Clubs that successfully navigate these trends will establish sustainable competitive advantages in the evolving landscape of professional football.
+
+\newpage
+\section*{Appendix: Data Sources and Methodology}
+
+\subsection{Data Sources}
+
+\begin{enumerate}
+ \item \textbf{Deloitte Football Money League 2025}: Primary revenue data source for 2023/24 season
+ \item \textbf{Club Annual Reports}: Financial statements and annual reports for individual clubs
+ \item \textbf{UEFA and League Publications}: Competitive performance and match data
+ \item \textbf{Social Media Analytics}: Platform-specific follower counts from Football Observatory
+ \item \textbf{Stadium Guides and Official Club Sources}: Capacity and facility information
+ \item \textbf{Transfer Market Databases}: Transfer spending and squad investment data
+\end{enumerate}
+
+\subsection{Methodology}
+
+\subsubsection{Revenue Breakdown Estimation}
+
+Revenue breakdowns estimated based on:
+\begin{itemize}
+ \item Published club financial statements where available
+ \item Proportional allocation based on peer club patterns
+ \item Stadium capacity and pricing models
+ \item Broadcast rights distributions by league
+\end{itemize}
+
+\subsubsection{Transfer Spending Calculation}
+
+Transfer spending includes:
+\begin{itemize}
+ \item Gross transfer expenditure 2024-2025 season
+ \item Estimated amortization impact
+ \item Loan fees and option to buy payments
+\end{itemize}
+
+\subsubsection{Trophy Count Methodology}
+
+Total trophies include:
+\begin{itemize}
+ \item Top-division league titles
+ \item Domestic cup competitions
+ \item UEFA Champions League / European Cup
+ \item UEFA Europa League / UEFA Cup
+ \item UEFA Super Cup
+ \item Domestic Super Cups
+ \item FIFA Club World Cup
+ \item Secondary domestic cups (where applicable)
+\end{itemize}
+
+\subsection{Limitations and Disclaimers}
+
+\begin{itemize}
+ \item Social media follower counts as of June 2025, subject to change
+ \item Trophy counts compiled from multiple sources, subject to classification differences
+ \item Stadium capacities reflect current or projected status after renovations
+ \item Revenue breakdowns include estimations where official data unavailable
+ \item All financial figures in Euros for consistency, using 2024-25 exchange rates
+ \item Projections based on historical trends and current market analysis
+\end{itemize}
+
+\subsection{Glossary}
+
+\begin{description}
+ \item[Commercial Revenue]: Income from sponsorships, merchandise, stadium naming rights, and non-football stadium events
+ \item[Matchday Revenue]: Income from ticket sales, hospitality, and concessions during matches
+ \item[Broadcast Revenue]: Income from television and streaming rights distributions
+ \item[Transfer Spend]: Gross expenditure on player transfers
+ \item[Transfer/Revenue Ratio]: Transfer spending as percentage of total revenue
+ \item[Money League]: Deloitte's annual ranking of football clubs by revenue
+\end{description}
+
+\end{document}
diff --git a/assets/gaming_industry/README.md b/assets/gaming_industry/README.md
new file mode 100644
index 0000000..122a028
--- /dev/null
+++ b/assets/gaming_industry/README.md
@@ -0,0 +1,139 @@
+# Gaming Industry Deep Dive 2026
+
+This folder contains a comprehensive research report on the top 10 video game companies by revenue in 2026, including market analysis, company profiles, and industry trends.
+
+## Contents
+
+### Main Report
+- `gaming_industry_deep_dive_2026.tex` - Complete LaTeX report with all sections
+
+## Report Sections
+
+1. **Executive Summary**
+ - Key findings and market overview
+ - Top performers by revenue
+ - Subscription service statistics
+
+2. **Industry Overview**
+ - Market size and growth projections
+ - Platform distribution analysis
+ - Key industry trends
+
+3. **Company Profiles (Top 10)**
+ - Tencent Holdings
+ - Sony Interactive Entertainment
+ - Microsoft Gaming (Xbox)
+ - Nintendo
+ - Electronic Arts
+ - NetEase
+ - Epic Games
+ - Ubisoft
+ - Take-Two Interactive
+ - Roblox Corporation
+
+4. **Market Share Visualizations**
+ - Revenue comparison charts
+ - Platform distribution graphics
+ - Subscription service subscriber counts
+
+5. **Platform and Revenue Analysis**
+ - Revenue distribution by platform
+ - Subscription services economics
+ - Live-service revenue models
+
+6. **Future Trends and Outlook**
+ - Cloud gaming expansion
+ - VR/AR market development
+ - AI-driven development
+ - Esports maturation
+
+## Key Statistics (2025-2026)
+
+### Market Size
+- Global Games Market: \$298.98B (2024) → \$320-340B (2026 projected)
+- Mobile Gaming: \$103B (55% market share)
+- Console Gaming: \$45.9B (24% market share)
+- PC Gaming: \$39.9B (21% market share)
+
+### Subscription Services (Q1 2025)
+- PlayStation Plus: 51.6M subscribers
+- Xbox Game Pass: 37M subscribers
+- Nintendo Switch Online: ~18M subscribers
+
+### Top Mobile Games by Revenue (2025)
+- Honor of Kings (Tencent): \$1.65B
+- PUBG Mobile (Tencent): \$1.1B
+- Delta Force Mobile (Tencent): \$334.6M
+
+### Gaming Subscription Spending
+- US gamers spent \$3.6B on subscriptions in 2025 (19% YoY growth)
+
+### Esports Market
+- Valued at \$3-4.8B in 2025
+- 2027 Olympic Esports Games announced
+
+### Cloud Gaming
+- Market: \$3.51B (2024) → \$4.63-5.32B (2025)
+- Projected growth to \$10.46B by 2026
+
+### VR/AR
+- Headset shipments: 35.1M projected by 2026
+- 39.2% growth projected for 2025
+
+## Compilation Instructions
+
+To compile the LaTeX report:
+
+```bash
+cd assets/gaming_industry
+pdflatex gaming_industry_deep_dive_2026.tex
+# Run twice to resolve references
+pdflatex gaming_industry_deep_dive_2026.tex
+```
+
+This will generate `gaming_industry_deep_dive_2026.pdf`
+
+## Data Sources
+
+This report is based on research from:
+- Market research firms (Grand View Research, BCG, Newzoo, etc.)
+- Company financial reports and investor presentations
+- Industry analysis publications
+- Gaming market statistics providers
+
+## Report Highlights
+
+### Top 10 Companies by 2026 Revenue (Estimated)
+1. Tencent - \$28-30B
+2. Sony - \$25-27B
+3. Microsoft Gaming - \$20-22B
+4. Nintendo - \$14-16B
+5. Electronic Arts - \$8-9B
+6. NetEase - \$7.5-8.5B
+7. Epic Games - \$6-7B
+8. Take-Two Interactive - \$5.5-6.5B
+9. Ubisoft - \$2.5-3.5B
+10. Roblox - \$4.5-5.5B
+
+### Major Game Releases (2026)
+- Grand Theft Auto VI (Take-Two/Rockstar) - November 2026
+- Nintendo Switch 2 hardware launch
+- Metroid Prime 4 (Nintendo)
+- New Marvel games (Sony)
+- New Battlefield (EA)
+
+### Key Trends
+- Subscription services becoming critical revenue streams
+- Live-service games dominating monetization
+- Cross-platform integration as standard practice
+- Industry consolidation through acquisitions
+- Cloud gaming emergence and VR/AR market growth
+- AI-driven development tools adoption
+
+## Notes
+
+This report was compiled in January 2026 using the most recent available data.
+Revenue figures are estimates based on available financial data and market projections.
+Actual results may vary from projections.
+
+For questions or additional information, refer to the cited sources within the report.
diff --git a/assets/gaming_industry/company_data.csv b/assets/gaming_industry/company_data.csv
new file mode 100644
index 0000000..3fbd988
--- /dev/null
+++ b/assets/gaming_industry/company_data.csv
@@ -0,0 +1,15 @@
+# Gaming Industry Data - Top 10 Companies 2026
+# Generated: January 2026
+# Revenue figures are estimates in USD Billions
+
+Rank,Company,Headquarters,2026_Revenue_Min,2026_Revenue_Max,Key_Franchises,Market_Position,Primary_Platforms
+1,Tencent,Shenzhen China,28,30,Honor of Kings,League of Legends,PUBG Mobile,Valorant,#1 globally,Mobile,PC,Esports
+2,Sony Interactive Entertainment,San Mateo USA,25,27,God of War,Spider-Man,Uncharted,Gran Turismo,#2 globally #1 console,PlayStation 5,VR2,PC
+3,Microsoft Gaming,Redmond USA,20,22,Halo,Forza,Minecraft,Call of Duty,World of Warcraft,#3 globally,Xbox,PC,Cloud Gaming
+4,Nintendo,Kyoto Japan,14,16,Mario,Zelda,Pokemon,Animal Crossing,Splatoon,#4 globally,Switch,Switch 2
+5,Electronic Arts,Redwood City USA,8,9,EA Sports FC,Battlefield,Apex Legends,Madden,The Sims,#5 globally,Cross-platform
+6,NetEase,Hangzhou China,7.5,8.5,Fantasy Westward Journey,Love and Deepspace,Identity V,#6 globally #2 China,Mobile,PC
+7,Epic Games,Cary USA,6,7,Fortnite,Unreal Engine,Epic Games Store,#7 globally,Cross-platform
+8,Take-Two Interactive,New York USA,5.5,6.5,Grand Theft Auto,Red Dead Redemption,NBA 2K,Borderlands,#9 globally,Cross-platform
+9,Ubisoft,Montreuil-sous-Bois France,2.5,3.5,Assassin's Creed,Far Cry,Just Dance,Rainbow Six Siege,#8 globally,Cross-platform
+10,Roblox Corporation,San Mateo USA,4.5,5.5,User-Generated Content Platform,#10 globally,Mobile,PC,Console,VR
diff --git a/assets/gaming_industry/gaming_industry_deep_dive_2026.pdf b/assets/gaming_industry/gaming_industry_deep_dive_2026.pdf
new file mode 100644
index 0000000..9dd0e0c
Binary files /dev/null and b/assets/gaming_industry/gaming_industry_deep_dive_2026.pdf differ
diff --git a/assets/gaming_industry/gaming_industry_deep_dive_2026.tex b/assets/gaming_industry/gaming_industry_deep_dive_2026.tex
new file mode 100644
index 0000000..2c5b8d4
--- /dev/null
+++ b/assets/gaming_industry/gaming_industry_deep_dive_2026.tex
@@ -0,0 +1,680 @@
+\documentclass[12pt,a4paper]{article}
+\usepackage[utf8]{inputenc}
+\usepackage[T1]{fontenc}
+\usepackage{geometry}
+\usepackage{graphicx}
+\usepackage{booktabs}
+\usepackage{longtable}
+\usepackage{tikz}
+\usepackage{pgf-pie}
+\usepackage{pgfplots}
+\usepackage{xcolor}
+\usepackage{hyperref}
+\usepackage{titlesec}
+\usepackage{caption}
+\usepackage{float}
+\pgfplotsset{compat=1.18}
+\geometry{top=1in,bottom=1in,left=0.75in,right=0.75in}
+
+\definecolor{sonyblue}{RGB}{0, 56, 168}
+\definecolor{tencentblue}{RGB}{0, 112, 192}
+\definecolor{microsoftgreen}{RGB}{0, 164, 239}
+\definecolor{nintendored}{RGB}{227, 28, 36}
+\definecolor{neteasered}{RGB}{200, 30, 30}
+\definecolor{epicblue}{RGB}{30, 30, 30}
+\definecolor{eaorange}{RGB}{255, 106, 0}
+
+\titleformat{\section}
+{\normalfont\Large\bfseries\color{sonyblue}}{\thesection}{1em}{}
+\titleformat{\subsection}
+{\normalfont\large\bfseries\color{tencentblue}}{\thesubsection}{1em}{}
+
+\title{\textbf{\huge Gaming Industry Deep Dive 2026}\\[0.5cm]\Large Comprehensive Analysis of Top Companies and Market Trends}
+\author{Market Research Report}
+\date{January 2026}
+
+\begin{document}
+
+\maketitle
+
+\tableofcontents
+\newpage
+
+\section*{Executive Summary}
+\addcontentsline{toc}{section}{Executive Summary}
+
+The global gaming industry continues its remarkable growth trajectory in 2026, with total market revenue projected to reach approximately \$187.7 billion, driven by sustained engagement across mobile, console, and PC platforms. The industry has successfully navigated post-pandemic normalization, with live-service games, subscription models, and emerging technologies providing new revenue streams and monetization opportunities.
+
+\textbf{Key Findings:}
+\begin{itemize}
+ \item \textbf{Market Leadership:} Tencent maintains its position as the largest gaming company by revenue, fueled by dominant mobile titles like Honor of Kings (\$1.65 billion in 2025) and PUBG Mobile (\$1.1 billion)
+ \item \textbf{Subscription Growth:} Gaming subscriptions reached \$3.6 billion in US spending in 2025 (19\% YoY growth), with PlayStation Plus at 51.6M subscribers and Xbox Game Pass at 37M
+ \item \textbf{Platform Dominance:} Mobile gaming leads with 55\% market share (\$103B revenue), followed by console (24\%, \$45.9B) and PC (21\%, \$39.9B)
+ \item \textbf{Esports Expansion:} Global esports market valued at \$3-4.8 billion, with major tournaments in League of Legends, Valorant, and Dota 2 driving engagement
+ \item \textbf{Cloud Gaming Emergence:} Cloud gaming market projected to reach \$5.32 billion in 2025, growing at 49.35\% CAGR to \$39.57B by 2030
+ \item \textbf{VR/AR Growth:} AR/VR headset shipments expected to reach 35.1 million units by 2026, with 39.2\% growth projected for 2025
+\end{itemize}
+
+\textbf{Outlook:} The industry is transitioning toward sustainable revenue models focused on user retention, cross-platform experiences, and emerging technologies including AI-driven content creation and cloud streaming infrastructure.
+
+\newpage
+
+\section{Industry Overview}
+
+\subsection{Market Size and Growth}
+
+The global video game market generated approximately \$298.98 billion in revenue in 2024 and is projected to reach \$600.74 billion by 2030, representing a compound annual growth rate (CAGR) of approximately 12\%. This growth is driven by:
+
+\begin{itemize}
+ \item Expanding gaming demographics and regional market penetration
+ \item Live-service game monetization strategies
+ \item Subscription service adoption across platforms
+ \item Technological advancements in cloud gaming and streaming
+ \item Growth in emerging markets across Asia, Latin America, and Africa
+\end{itemize}
+
+\subsection{Platform Distribution}
+
+\begin{figure}[H]
+ \centering
+ \begin{tikzpicture}
+ \begin{axis}[
+ ybar,
+ width=0.9\textwidth,
+ height=6cm,
+ symbolic x coords={Mobile, Console, PC},
+ xtick=data,
+ ylabel={Revenue (Billions USD)},
+ ymin=0,
+ ymax=120,
+ nodes near coords,
+ nodes near coords style={font=\footnotesize\bfseries},
+ bar width=1.5cm,
+ ymajorgrids=true,
+ grid style=dashed,
+ ]
+ \addplot[fill=microsoftgreen!80] coordinates {(Mobile,103)};
+ \addplot[fill=nintendored!80] coordinates {(Console,45.9)};
+ \addplot[fill=epicblue!80] coordinates {(PC,39.9)};
+ \end{axis}
+ \end{tikzpicture}
+ \caption{Gaming Revenue by Platform - 2025 (Total \$188.8B)}
+ \label{fig:platform_revenue}
+\end{figure}
+
+Mobile gaming dominates with 55\% market share, primarily due to accessibility, freemium monetization models, and dominant titles from Chinese publishers. Console gaming maintains strong performance through premium AAA titles and subscription services, while PC gaming benefits from esports, modding communities, and competitive gaming infrastructure.
+
+\subsection{Key Industry Trends}
+
+\subsubsection{Subscription Services Surge}
+Gaming subscription services have become a critical revenue stream, with US gamer spending reaching \$3.6 billion in 2025 (19\% increase). PlayStation Plus leads with 51.6 million subscribers as of Q1 2025, with 23.7 million on Premium/Deluxe tiers showing strong uptake of enhanced offerings. Xbox Game Pass maintains 37 million subscribers, with Microsoft reporting 61\% growth in Xbox content and services revenue, partially attributed to the Activision Blizzard acquisition.
+
+\subsubsection{Live-Service Games Dominance}
+Live-service games with ongoing content updates and battle pass systems have become the industry standard for monetization. Titles like Fortnite, Honor of Kings, and League of Legends generate consistent revenue through microtransactions, cosmetics, and seasonal events. Honor of Kings led 2025 mobile revenue at \$1.65 billion, demonstrating the power of established live-service ecosystems.
+
+\subsubsection{Cross-Platform Integration}
+Publishers increasingly adopt cross-platform strategies to maximize market reach. Games like Fortnite, Minecraft, and Roblox demonstrate success across mobile, console, and PC platforms, driving engagement through unified player bases and progression systems. This approach is becoming standard for new releases, particularly in multiplayer and competitive genres.
+
+\subsubsection{Acquisition and Consolidation}
+Industry consolidation continues through strategic acquisitions, most notably Microsoft's \$69 billion Activision Blizzard acquisition closed in 2023. This has reshaped the competitive landscape, integrating major franchises (Call of Duty, World of Warcraft, Diablo) into Xbox Game Studios and boosting Microsoft's gaming revenue by 43\% in FY25 Q1.
+
+\newpage
+
+\section{Company Profiles (Top 10)}
+
+The following section provides detailed profiles of the top 10 gaming companies by revenue in 2026, based on market analysis and financial performance.
+
+\subsection{Tencent Holdings}
+
+\begin{table}[H]
+\centering
+\begin{tabular}{|p{0.3\textwidth}|p{0.6\textwidth}|}
+\hline
+\textbf{Headquarters} & Shenzhen, China \\
+\hline
+\textbf{Estimated 2026 Revenue} & \$28-30 billion \\
+\hline
+\textbf{Key Franchises} & Honor of Kings, League of Legends, PUBG Mobile, Valorant \\
+\hline
+\textbf{Market Position} & \#1 globally by revenue \\
+\hline
+\textbf{Primary Platforms} & Mobile, PC, Esports \\
+\hline
+\end{tabular}
+\caption{Tencent - Key Metrics}
+\end{table}
+
+\textbf{Business Overview:}
+Tencent maintains its position as the world's largest gaming company through a diversified portfolio spanning game development, publishing, and investment. The company's success is built on dominant mobile titles in the Chinese market and strategic investments in global gaming studios.
+
+\textbf{2025-2026 Performance:}
+Honor of Kings generated \$1.65 billion in revenue in 2025, maintaining its position as the top-grossing mobile game globally for the third consecutive year. PUBG Mobile contributed an additional \$1.1 billion, while Delta Force Mobile generated \$334.6 million. Tencent's investment portfolio includes stakes in Riot Games (100\%), Epic Games (40\%), and numerous studios across Europe and Asia.
+
+\textbf{Subscription Services:}
+While not operating a direct gaming subscription, Tencent benefits from live-service monetization through battle passes, cosmetics, and seasonal content across its titles. The company has expanded into cloud gaming with Tencent Start and continues investing in esports infrastructure across its titles.
+
+\textbf{Esports Investments:}
+Tencent operates major esports tournaments for Honor of Kings, League of Legends, and Valorant. The company has invested billions in esports infrastructure, including league operations, team ownership, and dedicated streaming platforms. The 2025 Honor of Kings World Championship represented one of the largest esports events by prize pool and viewership.
+
+\textbf{Future Outlook:}
+Tencent continues expanding internationally through acquisitions and publishing partnerships. The company is investing heavily in AI-driven game development tools and exploring new monetization models including NFT-based in-game items in select markets. Regulatory challenges in China remain a risk factor, though domestic gaming restrictions have eased in 2024-2025.
+
+\subsection{Sony Interactive Entertainment}
+
+\begin{table}[H]
+\centering
+\begin{tabular}{|p{0.3\textwidth}|p{0.6\textwidth}|}
+\hline
+\textbf{Headquarters} & San Mateo, California / Tokyo, Japan \\
+\hline
+\textbf{Estimated 2026 Revenue} & \$25-27 billion \\
+\hline
+\textbf{Key Franchises} & God of War, Spider-Man, Uncharted, Gran Turismo, Last of Us \\
+\hline
+\textbf{Market Position} & \#2 globally by revenue, \#1 in console \\
+\hline
+\textbf{Primary Platforms} & PlayStation 5, PlayStation VR2, PC (select titles) \\
+\hline
+\end{tabular}
+\caption{Sony Interactive Entertainment - Key Metrics}
+\end{table}
+
+\textbf{Business Overview:}
+Sony Interactive Entertainment leads the console market with PlayStation 5, which has surpassed 65.9 million units sold lifetime. The company's strategy focuses on premium AAA exclusives, subscription services through PlayStation Plus, and expanding into PC publishing to maximize franchise value.
+
+\textbf{2025-2026 Performance:}
+Sony's Game \& Network Services division reported 8\% year-over-year growth in Q1 FY2026, with operating income increasing 127\% year-over-year. PlayStation Plus maintains 51.6 million subscribers as of Q1 2025, with Premium/Deluxe tiers showing 9\% growth to 23.7 million subscribers, indicating strong uptake of enhanced offerings including game streaming and classic catalogs.
+
+\textbf{Game Releases:}
+2026 represents a pivotal year for Sony with the PlayStation 5 successor expected in late 2026 or early 2027. The lineup includes major titles such as Marvel games, GTA VI (console exclusive window expected), and new IPs from PlayStation Studios. Industry analysts project GTA VI could generate over \$3 billion in its first year, with potential for \$7.6 billion in its first 60 days.
+
+\textbf{Subscription Services:}
+PlayStation Plus offers three tiers: Essential (online play, monthly games), Extra (expanded game catalog), and Premium/Deluxe (streaming, classic games). 22\% of subscribers have adopted Premium/Deluxe tiers, demonstrating demand for premium offerings. Sony invests heavily in first-party content for the service, with day-one launches for smaller titles and timed exclusives for major releases.
+
+\textbf{Platform Distribution:}
+Sony maintains console exclusivity for major first-party titles to drive hardware sales, though has begun porting selected titles to PC 1-2 years after PlayStation release. This strategy maximizes console revenue while extending franchise lifecycle and building PC player bases for future titles.
+
+\textbf{Esports Investments:}
+Sony esports investments focus on PlayStation-exclusive titles and competitive gaming infrastructure. The company sponsors major tournaments for games like Gran Turismo and fighting game titles. PlayStation League tournaments provide organized competition across multiple regions, with prize pools and production quality improving annually.
+
+\textbf{Future Outlook:}
+Sony's next-generation console is expected to focus on enhanced graphics capabilities and improved PS VR2 integration. The company is expanding its mobile gaming division with titles based on PlayStation franchises and investing in live-service capabilities to extend engagement beyond traditional launch windows. Strategic acquisitions like Bungie provide live-service expertise and cross-platform potential.
+
+\subsection{Microsoft Gaming}
+
+\begin{table}[H]
+\centering
+\begin{tabular}{|p{0.3\textwidth}|p{0.6\textwidth}|}
+\hline
+\textbf{Headquarters} & Redmond, Washington \\
+\hline
+\textbf{Estimated 2026 Revenue} & \$20-22 billion \\
+\hline
+\textbf{Key Franchises} & Halo, Forza, Minecraft, Call of Duty, World of Warcraft \\
+\hline
+\textbf{Market Position} & \#3 globally by revenue \\
+\hline
+\textbf{Primary Platforms} & Xbox Series X/S, PC, Cloud Gaming \\
+\hline
+\end{tabular}
+\caption{Microsoft Gaming - Key Metrics}
+\end{table}
+
+\textbf{Business Overview:}
+Microsoft Gaming has undergone transformative growth through the Activision Blizzard acquisition (\$69 billion), positioning Xbox as a multi-platform ecosystem spanning console, PC, and cloud gaming. The company's strategy emphasizes Game Pass subscription, cloud gaming, and cross-platform release to maximize player reach.
+
+\textbf{2025-2026 Performance:}
+Microsoft's gaming revenue increased \$2.0 billion (9\%) in FY25 Q4, driven entirely by growth in Xbox content and services which offset hardware declines. The Activision Blizzard acquisition contributed 53 points of net impact to content revenue growth. Xbox content and services revenue increased 61\% in FY25 Q1, demonstrating significant post-acquisition expansion.
+
+\textbf{Subscription Services:}
+Xbox Game Pass maintains 37 million subscribers as of Q1 2025. Microsoft's strategy focuses on first-party day-one launches (Starfield, Halo Infinite, future Call of Duty titles) and rotating third-party partnerships. Cloud Gaming integration provides platform flexibility, with subscribers accessing games across console, PC, mobile, and streaming devices.
+
+\textbf{Platform Distribution:}
+Microsoft distinguishes itself through true cross-platform strategy. Call of Duty title Black Ops 6 achieved 60\% more launch unit sales on PlayStation compared to previous entries, demonstrating how platform expansion benefits total franchise performance. Microsoft has announced first-party titles coming to PlayStation and Nintendo Switch selectively.
+
+\textbf{Game Releases:}
+Microsoft's 2025-2026 pipeline includes Call of Duty titles, Diablo expansions, and new Xbox Game Studios projects including Borderlands 4. The company reportedly has nearly 40 new games in development across its studios, focused on Game Pass value proposition and cross-platform appeal.
+
+\textbf{Esports Investments:}
+Microsoft supports esports through Xbox Game Studios titles and partnerships. The company sponsors events for Halo, Forza, and Call of Duty. Cloud Gaming infrastructure enables viewers to quickly jump into games featured in esports broadcasts, creating integrated viewing and playing experiences.
+
+\textbf{Future Outlook:}
+Microsoft is investing in new hardware including an Xbox Ally handheld device to complement cloud gaming infrastructure. AI integration includes Copilot assistance features and generative NPC technologies. The company's multi-platform approach represents a fundamental shift from console exclusivity to ecosystem reach, positioning Microsoft to benefit from gaming growth across all platforms.
+
+\subsection{Nintendo}
+
+\begin{table}[H]
+\centering
+\begin{tabular}{|p{0.3\textwidth}|p{0.6\textwidth}|}
+\hline
+\textbf{Headquarters} & Kyoto, Japan \\
+\hline
+\textbf{Estimated 2026 Revenue} & \$14-16 billion \\
+\hline
+\textbf{Key Franchises} & Mario, Zelda, Pokemon, Animal Crossing, Splatoon \\
+\hline
+\textbf{Market Position} & \#4 globally by revenue \\
+\hline
+\textbf{Primary Platforms} & Switch, Switch 2 (launching 2026) \\
+\hline
+\end{tabular}
+\caption{Nintendo - Key Metrics}
+\end{table}
+
+\textbf{Business Overview:}
+Nintendo remains unique among major publishers through its focus on first-party hardware software integration and family-friendly gaming experiences. The Switch has sold 154.01 million units lifetime as of FY2026 Q2, with the Switch 2 launching in 2026 to extend the ecosystem.
+
+\textbf{2025-2026 Performance:}
+Nintendo reported strong profits despite aging Switch hardware. Q2 FY2026 showed Switch hardware sales declining 65.27\% year-over-year to 0.91 million units, reflecting the transition period before Switch 2 launch. The company maintains significant cash reserves for development and strategic initiatives.
+
+\textbf{Game Releases:}
+Major 2025-2026 releases include Metroid Prime 4 (expected as a launch title for Switch 2), a new Fire Emblem title for the franchise's 25th anniversary, and a new Zelda game in development. Nintendo's strategy emphasizes platform-defining exclusives rather than cross-platform expansion.
+
+\textbf{Platform Distribution:}
+Nintendo maintains strict platform exclusivity for first-party titles to drive hardware sales. The company's philosophy of lateral thinking with withered technology focuses on novel gameplay mechanics rather than raw graphical power, creating differentiation from Sony and Microsoft.
+
+\textbf{Subscription Services:}
+Nintendo Switch Online offers basic online play and classic game libraries for \$20-50 annually. Premium expansion tiers add Nintendo 64 and Genesis games. While smaller in scale than PlayStation Plus or Xbox Game Pass, the service has low overhead costs and healthy profit margins.
+
+\textbf{Esports Investments:}
+Nintendo esports activities focus on Super Smash Bros., Splatoon, and competitive Pokemon. The company hosts official tournaments including the Nintendo World Championships, though esports is not a primary focus compared to competitors. Community-organized competitive scenes drive most esports engagement for Nintendo titles.
+
+\textbf{Future Outlook:}
+Switch 2 represents Nintendo's critical 2026 product launch. The console is expected to deliver enhanced performance while maintaining the hybrid form factor and backward compatibility with existing Switch software. Nintendo is expanding into film and television adaptations, with a new film planned for April 2026 release.
+
+\subsection{Electronic Arts}
+
+\begin{table}[H]
+\centering
+\begin{tabular}{|p{0.3\textwidth}|p{0.6\textwidth}|}
+\hline
+\textbf{Headquarters} & Redwood City, California \\
+\hline
+\textbf{Estimated 2026 Revenue} & \$8-9 billion \\
+\hline
+\textbf{Key Franchises} & EA Sports FC, Battlefield, Apex Legends, Madden, The Sims \\
+\hline
+\textbf{Market Position} & \#5 globally by revenue \\
+\hline
+\textbf{Primary Platforms} & Cross-platform (Mobile, Console, PC) \\
+\hline
+\end{tabular}
+\caption{Electronic Arts - Key Metrics}
+\end{table}
+
+\textbf{Business Overview:}
+Electronic Arts maintains leadership in sports gaming and competitive multiplayer through annualized releases and robust live-service operations. The company generated approximately \$7.5 billion in GAAP revenue in fiscal 2025, with \$5.46 billion from live-service revenues.
+
+\textbf{2025-2026 Performance:}
+EA's Q2 FY2026 results showed continued growth across major franchises. EA Sports FC 26 is scheduled for 2025, continuing the rebranded soccer franchise. Apex Legends maintains strong engagement through seasonal battle passes and limited-time events. Battlefield is launching a new title by March 2026.
+
+\textbf{Game Releases:}
+Major titles include EA Sports FC 26 (2025), a new Battlefield game launching by March 2026, and new entries in the Need for Speed series. EA's development pipeline emphasizes annual sports titles alongside longer development cycles for premium franchises.
+
+\textbf{Subscription Services:}
+EA Play Pro provides access to EA's catalog on PC and offers new releases on day one. The service is bundled with Xbox Game Pass Ultimate console tier providing broader distribution. EA's subscription revenue represents an increasingly important revenue component.
+
+\textbf{Platform Distribution:}
+EA releases across all major platforms, with mobile versions of sports titles generating significant revenue. Ultimate Team modes in sports titles drive substantial live-service revenue through card packs and player progression systems.
+
+\textbf{Esports Investments:}
+EA supports competitive gaming for EA Sports FC, Apex Legends, and selected FPS titles through EA Competitive Gaming division. EA Sports FC e Champions League represents major esports investment.
+
+\textbf{Future Outlook:}
+EA is exploring privatization according to 2025 reports. The company is investing in AI-driven content creation tools to accelerate development of annual sports titles. Live-service expansion includes new mobile projects.
+
+\subsection{NetEase}
+
+\begin{table}[H]
+\centering
+\begin{tabular}{|p{0.3\textwidth}|p{0.6\textwidth}|}
+\hline
+\textbf{Headquarters} & Hangzhou, China \\
+\hline
+\textbf{Estimated 2026 Revenue} & \$7.5-8.5 billion \\
+\hline
+\textbf{Key Franchises} & Fantasy Westward Journey, Love and Deepspace, Identity V, Knives Out \\
+\hline
+\textbf{Market Position} & \#6 globally by revenue, \#2 in China \\
+\hline
+\textbf{Primary Platforms} & Mobile, PC, Esports \\
+\hline
+\end{tabular}
+\caption{NetEase - Key Metrics}
+\end{table}
+
+\textbf{Business Overview:}
+NetEase serves as China's second-largest gaming company and a major global mobile publisher. The company reported revenue of 28.4 billion RMB in Q3 2025, growing 8.2\% year-over-year.
+
+\textbf{2025-2026 Performance:}
+Q2 2025 game business revenue reached 22.138 billion RMB. Strong revenue reflects successful launches including Love and Deepspace achieving international breakout success. NetEase's strong cash position of RMB 153.2 billion provides strategic flexibility.
+
+\textbf{Game Releases:}
+NetEase's 2025-2026 pipeline includes new mobile titles and projects developed jointly with Western studios. The company co-develops titles with Blizzard Entertainment in China and maintains partnerships with Japanese publishers.
+
+\textbf{Subscription Services:}
+NetEase generates recurring revenue through live-service mechanics, VIP subscriptions within games, and season pass systems. Exploring subscription-based mobile games for international markets.
+
+\textbf{Esports Investments:}
+NetEase operates major esports leagues for titles like Identity V, Knives Out, and Onmyoji Arena. The NetEase Esports X Series provides organized competition across NetEase's mobile portfolio.
+
+\textbf{Future Outlook:}
+NetEase continues international expansion through publishing deals and acquisitions. Investing in AI development tools to accelerate mobile game production. Regulatory challenges in China have eased somewhat.
+
+\subsection{Epic Games}
+
+\begin{table}[H]
+\centering
+\begin{tabular}{|p{0.3\textwidth}|p{0.6\textwidth}|}
+\hline
+\textbf{Headquarters} & Cary, North Carolina \\
+\hline
+\textbf{Estimated 2026 Revenue} & \$6-7 billion \\
+\hline
+\textbf{Key Franchises} & Fortnite, Unreal Engine, Epic Games Store \\
+\hline
+\textbf{Market Position} & \#7 globally by revenue \\
+\hline
+\textbf{Primary Platforms} & Cross-platform \\
+\hline
+\end{tabular}
+\caption{Epic Games - Key Metrics}
+\end{table}
+
+\textbf{Business Overview:}
+Epic Games operates a diversified business model spanning game development (Fortnite), engine licensing (Unreal Engine), and digital distribution (Epic Games Store). Company revenue is projected to reach \$6.21 billion in 2026. Fortnite generated \$3.5 billion in 2023.
+
+\textbf{2025-2026 Performance:}
+Fortnite maintains approximately 126 million monthly active users and 650 million registered players worldwide. The Epic Games Store launched updated revenue share terms in 2025, keeping 100\% of the first \$1M net revenue per title per year.
+
+\textbf{Platform Distribution:}
+Epic distinguishes itself through true cross-platform development. Fortnite operates identically across PC, consoles, and mobile with unified progression and cross-play capabilities. Unreal Engine powers games across all platforms.
+
+\textbf{Esports Investments:}
+Fortnite Champion Series (FNCS) represents significant esports investment with massive prize pools and global tournaments.
+
+\textbf{Future Outlook:}
+Epic is investing heavily in Unreal Engine 5 adoption and next-generation graphics technologies. Exploring metaverse concepts through Fortnite's evolving social ecosystem.
+
+\subsection{Ubisoft}
+
+\begin{table}[H]
+\centering
+\begin{tabular}{|p{0.3\textwidth}|p{0.6\textwidth}|}
+\hline
+\textbf{Headquarters} & Montreuil-sous-Bois, France \\
+\hline
+\textbf{Estimated 2026 Revenue} & \$2.5-3.5 billion \\
+\hline
+\textbf{Key Franchises} & Assassin's Creed, Far Cry, Just Dance, Rainbow Six Siege \\
+\hline
+\textbf{Market Position} & \#8 globally by revenue \\
+\hline
+\textbf{Primary Platforms} & Cross-platform \\
+\hline
+\end{tabular}
+\caption{Ubisoft - Key Metrics}
+\end{table}
+
+\textbf{Business Overview:}
+Ubisoft operates as one of Europe's largest gaming publishers, known for extensive open-world franchises and live-service multiplayer titles. The company is implementing a new Creative Houses operating model.
+
+\textbf{2025-2026 Performance:}
+Ubisoft reported first-half FY2025-26 sales of 657.8 million euros. Q2 net bookings were up 39\% year-on-year driven by stronger performance across the games catalog.
+
+\textbf{Game Releases:}
+Assassin's Creed remains Ubisoft's primary franchise with multiple projects in development. Rainbow Six Siege continues as a successful esports title.
+
+\textbf{Subscription Services:}
+Ubisoft+ provides access to Ubisoft's game catalog on PC but has struggled to gain significant market share compared to competitors.
+
+\textbf{Esports Investments:}
+Rainbow Six Siege represents Ubisoft's primary esports title. Brawlhalla provides additional esports presence in the fighting game genre.
+
+\textbf{Future Outlook:}
+Ubisoft's Creative Houses strategy represents a fundamental reorganization aimed at empowering individual studios. Financial pressures may lead to acquisition interest from larger publishers.
+
+\subsection{Take-Two Interactive}
+
+\begin{table}[H]
+\centering
+\begin{tabular}{|p{0.3\textwidth}|p{0.6\textwidth}|}
+\hline
+\textbf{Headquarters} & New York, New York \\
+\hline
+\textbf{Estimated 2026 Revenue} & \$5.5-6.5 billion \\
+\hline
+\textbf{Key Franchises} & Grand Theft Auto, Red Dead Redemption, NBA 2K, Borderlands \\
+\hline
+\textbf{Market Position} & \#9 globally by revenue \\
+\hline
+\textbf{Primary Platforms} & Cross-platform \\
+\hline
+\end{tabular}
+\caption{Take-Two Interactive - Key Metrics}
+\end{table}
+
+\textbf{Business Overview:}
+Take-Two Interactive holds the industry's most valuable intellectual property through Rockstar Games and 2K Games. The company is positioned for dramatic growth with GTA VI's late 2026 release.
+
+\textbf{2025-2026 Performance:}
+Take-Two reported Q2 FY2026 net bookings of \$1.96 billion and GAAP net revenue of \$1.77 billion. The company raised its fiscal year bookings outlook to \$6.38-6.48 billion despite GTA VI delay to November 2026.
+
+\textbf{Game Releases:}
+GTA VI represents the most significant single gaming release since Fortnite's launch. Forecast to generate over \$7.6 billion in its first 60 days. Other releases include new NBA 2K entries and Borderlands 4.
+
+\textbf{Platform Distribution:}
+Take-Two traditionally prioritizes console releases for premium titles, though Rockstar has begun supporting PC post-launch versions.
+
+\textbf{Esports Investments:}
+NBA 2K League operates as a major esports initiative in partnership with the NBA.
+
+\textbf{Future Outlook:}
+GTA VI's release in November 2026 will define Take-Two's near-term performance. Management faces investor pressure to demonstrate sustainable post-GTA growth strategies.
+
+\subsection{Roblox Corporation}
+
+\begin{table}[H]
+\centering
+\begin{tabular}{|p{0.3\textwidth}|p{0.6\textwidth}|}
+\hline
+\textbf{Headquarters} & San Mateo, California \\
+\hline
+\textbf{2026 Projected Revenue} & \$4.5-5.5 billion \\
+\hline
+\textbf{Key Business} & User-Generated Content Platform \\
+\hline
+\textbf{Market Position} & \#10 by revenue, Largest UGC platform \\
+\hline
+\textbf{Primary Platforms} & Mobile, PC, Console, VR \\
+\hline
+\end{tabular}
+\caption{Roblox Corporation - Key Metrics}
+\end{table}
+
+\textbf{Business Overview:}
+Roblox operates as a user-generated content platform reaching 381.8 million monthly active users and 151.5 million daily active users.
+
+\textbf{2025-2026 Performance:}
+Roblox reported Q3 2025 revenue up 48\% year-on-year at \$1.35 billion. Average daily active users reached 151 million, with 35 million monthly unique paying users.
+
+\textbf{Platform Business Model:}
+Roblox operates as a developer ecosystem paying out hundreds of millions annually to creators through revenue sharing.
+
+\textbf{Platform Distribution:}
+Roblox maintains true cross-platform availability across mobile, PC, Xbox, PlayStation, and Meta Quest.
+
+\textbf{Subscription Services:}
+Roblox Premium provides monthly Robux credits and developer fee discounts as the platform's primary recurring revenue mechanism.
+
+\textbf{Esports Investments:}
+The Roblox Championship Series provides organized competition across popular platform experiences.
+
+\textbf{Future Outlook:}
+Roblox is investing in older demographic expansion through enhanced graphics capabilities and content partnerships. VR integration through Meta Quest provides early positioning for spatial computing platforms.
+
+\newpage
+
+\section{Market Share Visualizations}
+
+\begin{figure}[H]
+ \centering
+ \small
+ \begin{tikzpicture}
+ \begin{axis}[
+ width=0.95\textwidth,
+ height=7cm,
+ xbar,
+ xmin=0,
+ xmax=32,
+ xlabel={Estimated 2026 Revenue (Billions USD)},
+ symbolic y coords={Roblox, Take-Two, Ubisoft, Epic Games, NetEase, Electronic Arts, Nintendo, Microsoft, Sony, Tencent},
+ ytick=data,
+ nodes near coords,
+ nodes near coords align={horizontal},
+ yticklabel style={font=\footnotesize},
+ nodes near coords style={font=\footnotesize},
+ xmajorgrids=true,
+ grid style=dashed,
+ bar width=0.5cm,
+ reverse legend,
+ ]
+ \addplot[fill=tencentblue] coordinates {(28,Tencent)};
+ \addplot[fill=sonyblue] coordinates {(26,Sony)};
+ \addplot[fill=microsoftgreen] coordinates {(21,Microsoft)};
+ \addplot[fill=nintendored] coordinates {(15,Nintendo)};
+ \addplot[fill=eaorange] coordinates {(8.5,Electronic Arts)};
+ \addplot[fill=neteasered] coordinates {(8,NetEase)};
+ \addplot[fill=epicblue] coordinates {(6.5,Epic Games)};
+ \addplot[fill=purple!70] coordinates {(3,Ubisoft)};
+ \addplot[fill=teal!70] coordinates {(6,Take-Two)};
+ \addplot[fill=gray!60] coordinates {(5,Roblox)};
+ \end{axis}
+ \end{tikzpicture}
+ \caption{Top 10 Gaming Companies by Estimated 2026 Revenue}
+ \label{fig:company_revenues}
+\end{figure}
+
+\begin{figure}[H]
+ \centering
+ \begin{tikzpicture}
+ \begin{axis}[
+ width=0.9\textwidth,
+ height=6cm,
+ ybar,
+ symbolic x coords={PS Plus, Xbox GP, Nintendo Online},
+ xtick=data,
+ ylabel={Subscribers (Millions)},
+ ymin=0,
+ ymax=60,
+ nodes near coords,
+ nodes near coords style={font=\footnotesize\bfseries},
+ bar width=1.2cm,
+ ymajorgrids=true,
+ grid style=dashed,
+ ]
+ \addplot[fill=sonyblue!90] coordinates {(PS Plus,51.6)};
+ \addplot[fill=microsoftgreen!90] coordinates {(Xbox GP,37)};
+ \addplot[fill=nintendored!90] coordinates {(Nintendo Online,18)};
+ \end{axis}
+ \end{tikzpicture}
+ \caption{Gaming Subscription Service Subscribers - Q1 2025}
+ \label{fig:subscriptions}
+\end{figure}
+
+\newpage
+
+\section{Platform and Revenue Analysis}
+
+\subsection{Revenue Distribution by Platform}
+
+The gaming industry's platform distribution reflects accessibility and monetization efficiency of different game delivery methods. Mobile gaming's 55\% market share (\$103 billion) demonstrates scale advantages from global smartphone penetration and freemium monetization models. Console gaming's 24\% share (\$45.9 billion) highlights premium pricing power and subscription services value. PC gaming's 21\% share (\$39.9 billion) reflects strong engagement in esports, competitive gaming, and free-to-play markets.
+
+\subsection{Subscription Services Economics}
+
+Gaming subscription services have emerged as a critical revenue stabilization mechanism. US gamers spent \$3.6 billion on subscriptions in 2025, representing 19\% year-over-year growth. PlayStation Plus Plus generates significant revenue through tiered pricing (Essential: \$9.99/month, Extra: \$14.99/month, Premium: \$17.99/month). Xbox Game Pass Ultimate (\$16.99/month) includes console, PC, and cloud gaming access.
+
+\subsection{Live-Service Revenue Models}
+
+Live-service games generate recurring revenue through:
+\begin{itemize}
+ \item \textbf{Battle Pass Systems:} Seasonal progression with cosmetic rewards
+ \item \textbf{Microtransactions:} Individual cosmetic and convenience purchases
+ \item \textbf{Seasonal Content:} Major content updates and limited-time events
+ \item \textbf{Subscription Integration:} Premium content for subscribers
+\end{itemize}
+
+Tencent's Honor of Kings generated \$1.65 billion from in-app purchases in 2025. Epic Games' Fortnite generated \$3.5 billion in 2023, demonstrating live-service revenue potential.
+
+\subsection{Regional Revenue Distribution}
+
+Industry patterns indicate:
+\begin{itemize}
+ \item \textbf{Asia-Pacific:} Largest market representing approximately 50-55\% of global revenue
+ \item \textbf{North America:} Approximately 25-30\% of global revenue
+ \item \textbf{Europe:} Approximately 15-20\% of global revenue
+ \item \textbf{Rest of World:} Emerging markets showing fastest growth rates
+\end{itemize}
+
+\newpage
+
+\section{Future Trends and Outlook}
+
+\subsection{Cloud Gaming Expansion}
+
+The cloud gaming market reached \$3.51 billion in 2024 and is projected to grow to \$4.63-5.32 billion in 2025. Major platforms include NVIDIA GeForce Now, Xbox Cloud Gaming, and PlayStation Cloud Gaming. Cloud gaming remains challenged by latency requirements and broadband infrastructure limitations, though 5G deployment may improve accessibility.
+
+\subsection{VR/AR Market Development}
+
+AR/VR headset shipments are projected to reach 35.1 million units by 2026. Meta Quest dominated 2025 with 1.7 million units shipped early in the year. Sony's PS VR2 and Meta Quest platforms provide gaming-specific content libraries. Gaming represents the primary VR/AR use case.
+
+\subsection{AI-Driven Development}
+
+Artificial intelligence is transforming game development through AI-assisted asset creation, more realistic NPC intelligence, automated testing, and personalized experiences. Microsoft's integration of Copilot technologies and Unreal Engine developer tools represents early AI integration.
+
+\subsection{Esports Maturation}
+
+The global esports market is valued between \$3-4.8 billion in 2025. Industry maturation evidenced by franchise leagues in League of Legends, Overwatch, and Call of Duty. The 2027 Olympic Esports Games signals growing legitimacy for competitive gaming.
+
+\subsection{Market Forecast Summary}
+
+\begin{table}[H]
+\centering
+\small
+\begin{tabular}{|l|c|c|c|}
+\hline
+\textbf{Segment} & \textbf{2025 (USD Billions)} & \textbf{2026 (Projected)} & \textbf{Growth Rate} \\
+\hline
+Global Games Market & 298.98 & 320-340 & 7-13\% \\
+Mobile Gaming & 103.00 & 110-120 & 7-12\% \\
+Console Gaming & 45.90 & 48-52 & 5-13\% \\
+PC Gaming & 39.90 & 42-46 & 5-15\% \\
+Cloud Gaming & 4.63-5.32 & 7-10 & 40-50\% \\
+Esports & 3.00-4.80 & 3.5-5.5 & 10-15\% \\
+\hline
+\end{tabular}
+\caption{Market Forecasts for 2026}
+\end{table}
+
+\subsection{Key Risks and Challenges}
+
+\begin{itemize}
+ \item \textbf{Development Costs:} AAA game development budgets reaching \$200-300 million
+ \item \textbf{Market Saturation:} Increasing competition for player time
+ \item \textbf{Regulatory Uncertainty:} Evolving regulations around data privacy and monetization
+ \item \textbf{Platform Dependency:} Reliance on Apple, Google, Sony, Microsoft, and Nintendo
+\end{itemize}
+
+\newpage
+
+\section{Conclusion}
+
+The gaming industry in 2026 demonstrates remarkable resilience and adaptability, sustaining growth through business model innovation and technological advancement. Tencent, Sony, and Microsoft have established market leadership through distinct strategies: Tencent through mobile domination and investments, Sony through premium console experiences, and Microsoft through cross-platform ecosystem reach.
+
+The industry's future will be defined by balancing premium AAA development with sustainable live-service operations, expanding cloud gaming accessibility, integrating AI development tools, navigating evolving regulatory landscapes, and capitalizing on emerging technologies including VR/AR.
+
+Companies successfully combining creative excellence with business sophistication and technological innovation will capture disproportionate share of projected market growth toward the \$600 billion industry scale forecast for 2030.
+
+This Gaming Industry Deep Dive 2026 report has provided comprehensive analysis of market leaders, platform dynamics, revenue models, and emerging trends.
+
+\end{document}
diff --git a/assets/gaming_industry/industry_statistics.txt b/assets/gaming_industry/industry_statistics.txt
new file mode 100644
index 0000000..7bc80ab
--- /dev/null
+++ b/assets/gaming_industry/industry_statistics.txt
@@ -0,0 +1,291 @@
+################################################################################
+# GAMING INDUSTRY STATISTICS 2026
+# Compiled: January 2026
+################################################################################
+
+## GLOBAL MARKET SIZE
+################################################################################
+2024 Revenue: $298.98 billion
+2025 Projected Revenue: ~$187 billion (games only)
+2026 Projected Revenue: $320-340 billion
+2030 Projected Revenue: $600.74 billion
+Compound Annual Growth Rate: ~12% (2024-2030)
+
+
+## PLATFORM DISTRIBUTION (2025)
+################################################################################
+Mobile Gaming: $103.0 billion (55% of market)
+Console Gaming: $45.9 billion (24% of market)
+PC Gaming: $39.9 billion (21% of market)
+Cloud Gaming: $4.6-5.3 billion (emerging segment)
+
+
+## TOP 10 COMPANIES BY REVENUME (2026 ESTIMATES)
+################################################################################
+1. Tencent (China): $28-30 billion
+2. Sony (Japan/USA): $25-27 billion
+3. Microsoft Gaming (USA): $20-22 billion
+4. Nintendo (Japan): $14-16 billion
+5. Electronic Arts (USA): $8-9 billion
+6. NetEase (China): $7.5-8.5 billion
+7. Epic Games (USA): $6-7 billion
+8. Take-Two Interactive (USA): $5.5-6.5 billion
+9. Ubisoft (France): $2.5-3.5 billion
+10. Roblox Corporation (USA): $4.5-5.5 billion
+
+
+## SUBSCRIPTION SERVICES (Q1 2025)
+################################################################################
+PlayStation Plus: 51.6 million subscribers
+- Premium/Deluxe Tier: 23.7 million subscribers (9% YoY growth)
+
+Xbox Game Pass: 37 million subscribers
+- Revenue Driver: 61% growth in Xbox content/services
+
+Nintendo Switch Online: ~18 million subscribers
+- Estimated based on market size
+
+US Subscriber Spending (2025): $3.6 billion (19% YoY growth)
+
+
+## TOP MOBILE GAMES BY REVENUE (2025)
+################################################################################
+1. Honor of Kings (Tencent): $1.65 billion
+ - #1 grossing mobile game for 3 years
+ - China-focused with 650M+ registered users
+
+2. PUBG Mobile (Tencent): $1.1 billion
+ - Global battle royale dominance
+
+3. Delta Force Mobile (Tencent): $334.6 million
+ - Growing FPS market share
+
+4. Roblox: $3.6 billion (2024 revenue)
+ - 151.5 million daily active users
+ - 381.8 million monthly active users
+ - 48% YoY revenue growth in Q3 2025
+
+5. Fortnite (Epic Games): $3.5 billion (2023)
+ - 126 million monthly active users
+ - 650 million registered players
+ - True cross-platform integration
+
+
+## ESPORTS MARKET (2025-2026)
+################################################################################
+Global Esports Market Value: $3.0-4.8 billion
+Projected 2026 Value: $3.5-5.5 billion
+Growth Rate: 10-15%
+
+Major Esports Titles:
+- League of Legends (Tencent/Riot): World Championship
+- Honor of Kings (Tencent): Major regional leagues
+- Dota 2 (Valve): The International 2025
+- Valorant (Riot): Champions Tour
+- Call of Duty (Microsoft): CDL, Championship
+- FIFA/EA Sports FC (EA): eChampions League
+- Rainbow Six Siege (Ubisoft): Professional leagues
+
+Key Events:
+- 2027 Olympic Esports Games: Announced
+- Esports Nations Cup: New initiative
+
+
+## CLOUD GAMING MARKET
+################################################################################
+2024 Market Size: $3.51 billion
+2025 Projected: $4.63-5.32 billion
+2026 Projected: $7-10 billion
+2030 Forecast: $39.57 billion
+CAGR (2025-2030): 49.35%
+
+Major Platforms:
+- Xbox Cloud Gaming: Integrated with Game Pass
+- PlayStation Cloud Gaming: Premium tier benefit
+- NVIDIA GeForce Now: Hardware-neutral model
+- Amazon Luna: Expanding market
+
+
+## VR/AR GAMING MARKET
+################################################################################
+Projected 2025 Shipments: 14.3 million units
+Projected 2026 Shipments: 35.1 million units
+2025 Growth Rate: 39.2%
+
+Platform Market Share (2025):
+- Meta Quest: 1.7 million units (early 2025)
+- Apple Vision Pro: Declining sales (95% drop)
+- Sony PS VR2: PlayStation ecosystem
+
+Gaming Focus: Primary VR/AR use case
+
+
+## KEY GAME RELEASES (2025-2026)
+################################################################################
+2025 Releases:
+- EA Sports FC 26 (EA)
+- New Battlefield (EA - by March 2026)
+- Marvel games (Sony)
+- New Need for Speed (EA)
+- Metroid Prime 4 (Nintendo - Switch 2 launch)
+
+Major 2026 Release:
+- Grand Theft Auto VI (Take-Two/Rockstar):
+ * Release: November 2026
+ * Projected Revenue: $3+ billion first year
+ * Potential: $7.6 billion in first 60 days
+ * Expected Sales: 20+ million copies launch window
+
+2026 Hardware:
+- Nintendo Switch 2: Q1-Q2 2026
+- PlayStation 5 Successor: Late 2026 / Early 2027
+- Xbox Ally Handheld: Microsoft investment
+
+
+## REGIONAL REVENUE DISTRIBUTION
+################################################################################
+Asia-Pacific: 50-55% of global revenue
+- China: Major mobile market leader
+- Japan: Console and mobile strength
+- South Korea: PC and esports dominance
+- Southeast Asia: Fastest growing region
+
+North America: 25-30% of global revenue
+- United States: Console and PC strength
+- Canada: Growing market
+
+Europe: 15-20% of global revenue
+- UK, Germany, France: Traditional markets
+- Eastern Europe: Emerging growth
+
+Rest of World: Emerging markets
+- Latin America: Fast growth
+- Middle East: Expanding rapidly
+- Africa: Untapped potential
+
+
+## MAJOR ACQUISITIONS (Recent)
+################################################################################
+Microsoft - Activision Blizzard (2023): $69 billion
+- Impact: 43% revenue growth for Xbox
+- Franchises Added: Call of Duty, Diablo, WoW, Overwatch
+
+Tencent - Riot Games: 100% ownership
+- Portfolio: League of Legends, Valorant, Teamfight
+
+Tencent - Supercell: Majority stake
+- Games: Clash of Clans, Brawl Stars
+
+Sony - Bungie (2022): $3.6 billion
+- Purpose: Live-service expertise
+- Games: Destiny 2, Marathon
+
+
+## LIVE-SERVICE REVENUE MODELS
+################################################################################
+Recurring Revenue Sources:
+1. Battle Pass Systems: Seasonal progression and rewards
+2. Microtransactions: Cosmetics and in-game items
+3. Season Passes: Content updates and events
+4. Subscription Integration: Premium content access
+5. In-Game Advertising: Mobile and free-to-play
+
+Leading Live-Service Games:
+- Fortnite (Epic): Battle pass dominance
+- Honor of Kings (Tencent): $1.65B from in-app purchases
+- League of Legends (Tencent): Skins and cosmetics
+- Apex Legends (EA): Seasonal content
+- Roblox (Roblox Corp): Creator economy platform
+
+
+## INDUSTRY TRENDS (2025-2026)
+################################################################################
+1. Subscription Service Growth:
+ - 19% YoY growth in US spending
+ - Tiered pricing models emerging
+ - Day-one releases driving adoption
+
+2. Cross-Platform Standardization:
+ - Unified progression systems
+ - Cross-play becoming expected
+ - Platform-exclusive windows shortening
+
+3. Live-Service Dominance:
+ - Battle pass monetization standard
+ - Seasonal content cycles
+ - Reduced reliance on retail sales
+
+4. AI Integration:
+ - Procedural content generation
+ - NPC behavior AI
+ - Automated QA testing
+ - Personalized player experiences
+
+5. Cloud Gaming Expansion:
+ - Infrastructure investment
+ - Multi-device access
+ - Latency improvements with 5G
+
+6. Esports Maturation:
+ - Franchise league structures
+ - Olympic recognition (2027)
+ - Traditional sports partnerships
+
+
+## KEY RISKS AND CHALLENGES
+################################################################################
+1. Rising Development Costs:
+ - AAA budgets: $200-300 million
+ - Marketing costs increasing
+ - Longer development cycles
+
+2. Market Saturation:
+ - Competition for player time
+ - Content oversupply
+ - Discovery challenges
+
+3. Regulatory Uncertainty:
+ - Data privacy regulations (GDPR, etc.)
+ - Platform policies (Apple, Google)
+ - Regional content restrictions
+
+4. Platform Dependency:
+ - App store fees (15-30%)
+ - Platform holder policies
+ - Distribution limitations
+
+5. Talent Shortages:
+ - Skilled developer competition
+ - Rising compensation costs
+ - Retention challenges
+
+
+## FORECAST SUMMARY BY SEGMENT
+################################################################################
+Segment | 2025 ($B) | 2026 ($B) | Growth Rate
+------------------------|-------------|---------------|------------
+Global Games Market | 298.98 | 320-340 | 7-13%
+Mobile Gaming | 103.0 | 110-120 | 7-12%
+Console Gaming | 45.9 | 48-52 | 5-13%
+PC Gaming | 39.9 | 42-46 | 5-15%
+Cloud Gaming | 4.63-5.32 | 7-10 | 40-50%
+Esports | 3.00-4.80 | 3.5-5.5 | 10-15%
+VR/AR Headsets | - | 35.1M units | 39.2%
+Gaming Subscriptions | - | $4.5B US | 19% YoY
+
+
+## SOURCES AND REFERENCES
+################################################################################
+- Grand View Research: Global Video Game Market Outlook 2025-2030
+- BCG: Video Gaming Report 2026
+- Newzoo: Global Games Market Report 2025
+- Company Financial Reports: Tencent, Sony, Microsoft, Nintendo, EA, NetEase
+- Industry Publications: Video Games Industry Memo, Game Developer
+- Market Research: Quantumrun, Icon Era, Business of Apps, Statista
+
+Note: All revenue figures are estimates based on available financial data and
+market projections. Actual results may vary. Currency: USD (United States Dollars).
+
+Generated for: Gaming Industry Deep Dive 2026 Report
+Last Updated: January 2026
+################################################################################
diff --git a/assets/gaming_industry/platform_chart.tex b/assets/gaming_industry/platform_chart.tex
new file mode 100644
index 0000000..f9b89a0
--- /dev/null
+++ b/assets/gaming_industry/platform_chart.tex
@@ -0,0 +1,27 @@
+\begin{figure}[H]
+ \centering
+ \begin{tikzpicture}
+ \begin{axis}[
+ width=0.9\textwidth,
+ height=7cm,
+ ybar,
+ symbolic x coords={Mobile, Console, PC, Cloud Gaming},
+ xtick=data,
+ ylabel={Revenue (Billions USD)},
+ ymin=0,
+ ymax=120,
+ nodes near coords,
+ nodes near coords style={font=\footnotesize\bfseries},
+ bar width=1.2cm,
+ ymajorgrids=true,
+ grid style=dashed,
+ ]
+ \addplot[fill=microsoftgreen!80] coordinates {(Mobile,103)};
+ \addplot[fill=nintendored!80] coordinates {(Console,45.9)};
+ \addplot[fill=epicblue!80] coordinates {(PC,39.9)};
+ \addplot[fill=purple!70] coordinates {(Cloud Gaming,5)};
+ \end{axis}
+ \end{tikzpicture}
+ \caption{Gaming Revenue by Platform Segment - 2025}
+ \label{fig:platform_detailed}
+\end{figure}
diff --git a/assets/gaming_industry/subscription_chart.tex b/assets/gaming_industry/subscription_chart.tex
new file mode 100644
index 0000000..e1dc5ef
--- /dev/null
+++ b/assets/gaming_industry/subscription_chart.tex
@@ -0,0 +1,28 @@
+\begin{figure}[H]
+ \centering
+ \begin{tikzpicture}
+ \begin{axis}[
+ width=0.9\textwidth,
+ height=6cm,
+ ybar,
+ symbolic x coords={PS Plus Premium, PS Plus Total, Xbox Game Pass, Nintendo Switch Online},
+ xtick=data,
+ ylabel={Subscribers (Millions)},
+ ymin=0,
+ ymax=60,
+ nodes near coords,
+ nodes near coords style={font=\footnotesize\bfseries},
+ bar width=1.0cm,
+ ymajorgrids=true,
+ grid style=dashed,
+ legend style={at={(0.5,-0.15)},anchor=north,legend columns=-1},
+ ]
+ \addplot[fill=sonyblue!70] coordinates {(PS Plus Premium,23.7)};
+ \addplot[fill=sonyblue!90] coordinates {(PS Plus Total,51.6)};
+ \addplot[fill=microsoftgreen!90] coordinates {(Xbox Game Pass,37)};
+ \addplot[fill=nintendored!90] coordinates {(Nintendo Switch Online,18)};
+ \end{axis}
+ \end{tikzpicture}
+ \caption{Gaming Subscription Service Subscribers - Q1 2025}
+ \label{fig:subscriptions_detailed}
+\end{figure}
diff --git a/assets/macro_overview_2024.png b/assets/macro_overview_2024.png
new file mode 100644
index 0000000..5284345
Binary files /dev/null and b/assets/macro_overview_2024.png differ
diff --git a/assets/macroeconomic_analysis_report.pdf b/assets/macroeconomic_analysis_report.pdf
new file mode 100644
index 0000000..946792d
Binary files /dev/null and b/assets/macroeconomic_analysis_report.pdf differ
diff --git a/assets/macroeconomic_analysis_report.tex b/assets/macroeconomic_analysis_report.tex
new file mode 100644
index 0000000..5188bee
--- /dev/null
+++ b/assets/macroeconomic_analysis_report.tex
@@ -0,0 +1,666 @@
+\documentclass[12pt,a4paper]{article}
+\usepackage[utf8]{inputenc}
+\usepackage{graphicx}
+\usepackage{geometry}
+\usepackage{titlesec}
+\usepackage{titling}
+\usepackage{booktabs}
+\usepackage{array}
+\usepackage{color}
+\usepackage{hyperref}
+\usepackage{float}
+\usepackage{longtable}
+\usepackage{tikz}
+\usetikzlibrary{shapes,arrows}
+
+% Page geometry
+\geometry{margin=1in}
+
+% Custom colors
+\definecolor{darkblue}{RGB}{0,0,139}
+\definecolor{forestgreen}{RGB}{34,139,34}
+\definecolor{crimson}{RGB}{220,20,60}
+
+% Title formatting
+\titleformat{\section}{\Large\bfseries\color{darkblue}}{\thesection}{1em}{}
+\titleformat{\subsection}{\large\bfseries\color{darkblue}}{\thesubsection}{1em}{}
+\titleformat{\subsubsection}{\normalsize\bfseries\color{forestgreen}}{\thesubsubsection}{1em}{}
+
+% Document info
+\title{\textbf{\huge Macroeconomic Analysis of the World's Top 10 Economies}\\[0.5cm]
+\large A Comprehensive Assessment of Economic Performance and Outlook 2024-2025}
+\author{Economic Research Division}
+\date{January 2025}
+
+\begin{document}
+
+\maketitle
+
+\tableofcontents
+\newpage
+
+%=============================================================================
+\section{Executive Summary}
+%=============================================================================
+
+This comprehensive macroeconomic analysis examines the world's ten largest economies by nominal GDP in 2024. The global economic landscape in 2024 was characterized by divergent growth patterns, moderating inflation rates from 2022-2023 peaks, and varying labor market conditions across major economies.
+
+\subsection{Key Findings}
+
+\begin{itemize}
+ \item \textbf{United States} maintains its position as the world's largest economy with GDP of \$29.17 trillion, representing approximately 25.8\% of the top 10's combined GDP output.
+
+ \item \textbf{China} holds second place with \$18.27 trillion, demonstrating resilience despite structural economic transitions and trade challenges.
+
+ \item \textbf{India} emerges as the fastest-growing major economy with 7.0\% GDP growth, rapidly closing the gap with advanced economies.
+
+ \item \textbf{Germany} and \textbf{Japan} show near-stagnant growth (0\% and 0.3\% respectively), reflecting structural challenges in advanced manufacturing economies.
+
+ \item \textbf{Inflation} has retreated from historical peaks across most economies, with average inflation at 3.24\% across the top 10 economies.
+
+ \item \textbf{Unemployment} rates vary significantly, from Japan's remarkable 2.6\% to France's 7.37\%.
+\end{itemize}
+
+\subsection{Economic Outlook for 2025}
+
+The outlook for 2025 suggests a gradual recovery in advanced economies, continued strong growth in emerging markets, and further stabilization of inflation rates around central bank targets. Central banks are expected to begin policy easing cycles as inflation pressures moderate, though the pace will vary by region.
+
+%=============================================================================
+\section{Global Economic Overview 2024}
+%=============================================================================
+
+\subsection{Macroeconomic Context}
+
+The global economy in 2024 navigated multiple challenges including lingering post-pandemic supply chain adjustments, geopolitical tensions, monetary policy tightening lag effects, and shifts in consumer spending patterns. Despite these headwinds, global GDP maintained expansion, though growth rates varied considerably across regions.
+
+\subsection{Key Economic Indicators Summary}
+
+\begin{table}[H]
+\centering
+\caption{Top 10 Economies - Key Macroeconomic Indicators 2024}
+\label{tab:macro_indicators}
+\small
+\begin{tabular}{l c c c c}
+\toprule
+\textbf{Country} & \textbf{GDP (T\$)} & \textbf{Growth (\%)} & \textbf{Inflation (\%)} & \textbf{Unemployment (\%)} \\
+\midrule
+United States & 29.17 & 2.8 & 3.0 & 4.30 \\
+China & 18.27 & 4.8 & 2.4 & 5.10 \\
+Germany & 4.71 & 0.0 & 2.6 & 6.30 \\
+Japan & 4.07 & 0.3 & 2.7 & 2.60 \\
+India & 3.89 & 7.0 & 5.6 & 4.60 \\
+United Kingdom & 3.59 & 1.1 & 3.9 & 4.70 \\
+France & 3.17 & 1.1 & 2.9 & 7.37 \\
+Italy & 2.38 & 0.7 & 2.8 & 6.78 \\
+Canada & 2.21 & 1.3 & 3.4 & 6.45 \\
+Brazil & 2.19 & 3.0 & 3.5 & 7.63 \\
+\midrule
+\textbf{Total/ Average} & \textbf{71.65} & \textbf{2.41} & \textbf{3.24} & \textbf{5.28} \\
+\bottomrule
+\end{tabular}
+\end{table}
+
+\begin{figure}[H]
+\centering
+\includegraphics[width=\textwidth,height=0.5\textheight,keepaspectratio]{macro_overview_2024.png}
+\caption{Comprehensive Macroeconomic Overview of Top 10 Economies - 2024}
+\label{fig:macro_overview}
+\end{figure}
+
+\subsection{Regional Performance Patterns}
+
+\begin{itemize}
+ \item \textbf{North America:} Solid growth driven by robust consumer spending and business investment, particularly in the United States.
+
+ \item \textbf{Europe:} Modest growth with structural challenges, particularly in manufacturing-dependent economies like Germany.
+
+ \item \textbf{Asia-Pacific:} Divergent performance with India leading growth, China showing moderate expansion, and Japan experiencing near-stagnation.
+
+ \item \textbf{Latin America:} Mixed performance with Brazil showing moderate resilience.
+\end{itemize}
+
+%=============================================================================
+\section{Analysis of Top 10 Economies}
+%=============================================================================
+
+\subsection{United States}
+\subsubsection{Economic Performance}
+
+The United States maintained its position as the world's preeminent economy with substantial GDP of \$29.17 trillion, exceeding the combined output of the bottom seven economies in the top 10. Economic growth of 2.8\% reflects healthy expansion despite monetary policy tightening.
+
+\subsubsection{Key Strengths}
+\begin{itemize}
+ \item Diversified economic structure with strong services, technology, and financial sectors
+ \item Robust labor market with unemployment at 4.3\%
+ \item Inflation moderating to 3.0\%, approaching Federal Reserve targets
+ \item Strong productivity growth driven by technological innovation
+\end{itemize}
+
+\subsubsection{Challenges}
+\begin{itemize}
+ \item High government debt levels requiring fiscal consolidation
+ \item Persistent productivity gaps in manufacturing
+ \ Rising income inequality requiring policy attention
+\end{itemize}
+
+\subsection{China}
+\subsubsection{Economic Performance}
+
+China continues as the world's second-largest economy with GDP of \$18.27 trillion. The 4.8\% growth rate, while historically low by Chinese standards, reflects the country's economic transition from export-led to consumption-driven growth model.
+
+\subsubsection{Key Strengths}
+\begin{itemize}
+ \item World's largest manufacturing base and exporter
+ \item Massive domestic market with growing middle class
+ \item Low inflation at 2.4\% providing policy flexibility
+ \item Substantial infrastructure and technology investments
+\end{itemize}
+
+\subsubsection{Challenges}
+\begin{itemize}
+ \item Real estate sector correction and debt reduction
+ \item Demographic challenges from aging population
+ \item Geopolitical tensions affecting trade relationships
+ \item Structural rebalancing toward services and consumption
+\end{itemize}
+
+\subsection{Germany}
+\subsubsection{Economic Performance}
+
+Germany, Europe's largest economy, experienced near-zero growth at 0.0\% in 2024, reflecting significant headwinds in manufacturing, particularly energy-intensive industries. GDP stands at \$4.71 trillion with substantial export orientation.
+
+\subsubsection{Key Strengths}
+\begin{itemize}
+ \item Leadership in advanced manufacturing and automotive sectors
+ \item Strong engineering and R\&D capabilities
+ \item Low inflation at 2.6\%
+ \item Skilled workforce and vocational training excellence
+\end{itemize}
+
+\subsubsection{Challenges}
+\begin{itemize}
+ \item Energy transition costs impacting manufacturing competitiveness
+ \item Demographic aging and labor force contraction
+ \ Export dependency on global demand fluctuations
+ \item Need for digital transformation acceleration
+\end{itemize}
+
+\subsection{Japan}
+\subsubsection{Economic Performance}
+
+Japan's economy of \$4.07 trillion showed minimal growth at 0.3\%, representing continued struggles with deflationary pressures and demographic challenges. Unemployment remains exceptionally low at 2.6\%, reflecting labor market tightness.
+
+\subsubsection{Key Strengths}
+\begin{itemize}
+ \item World-leading technological innovation and robotics
+ \item Exceptionally low unemployment at 2.6\%
+ \item Strong corporate sector with global brand recognition
+ \item Advanced infrastructure and high-quality education system
+\end{itemize}
+
+\subsubsection{Challenges}
+\begin{itemize}
+ \item Rapidly aging population and shrinking workforce
+ \item Persistent deflationary mindset and weak consumption
+ \item High public debt requiring fiscal consolidation
+ \item Slow productivity growth requiring structural reforms
+\end{itemize}
+
+\subsection{India}
+\subsubsection{Economic Performance}
+
+India emerged as the fastest-growing major economy with remarkable 7.0\% GDP growth. With GDP of \$3.89 trillion, India continues to narrow the gap with advanced economies, supported by demographic dividend and structural reforms.
+
+\subsubsection{Key Strengths}
+\begin{itemize}
+ \item Highest growth rate among major economies at 7.0\%
+ \item Large and young population with growing workforce
+ \item Expanding digital economy and technology sector
+ \item Rapid urbanization driving domestic consumption
+\end{itemize}
+
+\subsubsection{Challenges}
+\begin{itemize}
+ \item Elevated inflation at 5.6\% requiring monetary vigilance
+ \item Job creation challenges despite demographic advantage
+ \item Infrastructure gaps requiring substantial investment
+ \item Rural-urban development disparities
+\end{itemize}
+
+\subsection{United Kingdom}
+\subsubsection{Economic Performance}
+
+The UK economy of \$3.59 trillion grew by 1.1\% in 2024, reflecting post-Brexit adjustment and broader European economic challenges. Moderate inflation at 3.9\% and unemployment at 4.7\% indicate balanced economic conditions.
+
+\subsubsection{Key Strengths}
+\begin{itemize}
+ \item Global financial services hub in London
+ \item Strong services sector and knowledge economy
+ \item Leading research universities and innovation ecosystem
+ \item Flexible labor markets and business-friendly environment
+\end{itemize}
+
+\subsubsection{Challenges}
+\begin{itemize}
+ \item Trade frictions with European Union affecting exports
+ \item Productivity growth requiring policy attention
+ \item Regional economic disparities
+ \item Investment levels below optimal for long-term growth
+\end{itemize}
+
+\subsection{France}
+\subsubsection{Economic Performance}
+
+France's economy of \$3.17 trillion achieved 1.1\% growth with inflation at 2.9\%. Unemployment remains elevated at 7.37\%, reflecting structural labor market challenges despite recent reforms.
+
+\subsubsection{Key Strengths}
+\begin{itemize}
+ \item Diversified industrial base with aerospace and luxury goods
+ \item Strong energy sector with nuclear power capabilities
+ \item High-quality healthcare and social protection systems
+ \item Cultural and tourism assets supporting service exports
+\end{itemize}
+
+\subsubsection{Challenges}
+\begin{itemize}
+ \item Highest unemployment among top 10 at 7.37\%
+ \item Labor market rigidities requiring continued reform
+ \item Public debt levels necessitating fiscal discipline
+ \item Structural competitiveness issues in manufacturing
+\end{itemize}
+
+\subsection{Italy}
+\subsubsection{Economic Performance}
+
+Italy recorded modest growth of 0.7\% with GDP of \$2.38 trillion. Inflation at 2.8\% and unemployment at 6.78\% reflect ongoing economic challenges in Southern Europe's third-largest economy.
+
+\subsubsection{Key Strengths}
+\begin{itemize}
+ \item World-class design, manufacturing, and luxury goods sectors
+ \item Rich cultural heritage and tourism potential
+ \item Strong agricultural and food production sectors
+ \item Strategic location in Mediterranean trade routes
+\end{itemize}
+
+\subsubsection{Challenges}
+\begin{itemize}
+ \item High unemployment particularly among youth
+ \item North-south economic divide
+ \item Public debt sustainability concerns
+ \item Productivity gaps requiring modernization
+\end{itemize}
+
+\subsection{Canada}
+\subsubsection{Economic Performance}
+
+Canada's economy of \$2.21 trillion grew by 1.3\% in 2024. Inflation at 3.4\% and rising unemployment at 6.45\% reflect adjustment to monetary policy tightening and housing market corrections.
+
+\subsubsection{Key Strengths}
+\begin{itemize}
+ \item Abundant natural resources including energy and minerals
+ \item Resource: Stewardship of natural resource wealth
+\end{itemize}
+
+\subsubsection{Challenges}
+\begin{itemize}
+ \item Rising unemployment trend in 2024
+ \item Housing affordability challenges
+ \item Export dependence on U.S. market
+ \item Economic diversification needs
+\end{itemize}
+
+\subsection{Brazil}
+\subsubsection{Economic Performance}
+
+Brazil's economy of \$2.19 trillion achieved 3.0\% growth, showing resilience despite challenges. Inflation at 3.5\% indicates price stability, while unemployment at 7.63\% reflects ongoing labor market fragility.
+
+\subsubsection{Key Strengths}
+\begin{itemize}
+ \item Vast natural resources and agricultural capacity
+ \item Large domestic market with growing middle class
+ \item Leadership in renewable energy, particularly biofuels
+ \item Diversified export base
+\end{itemize}
+
+\subsubsection{Challenges}
+\begin{itemize}
+ \item Structural unemployment requiring skills development
+ \item Infrastructure gaps limiting competitiveness
+ \ Fiscal consolidation needs for debt sustainability
+ \item Corruption and governance challenges
+\end{itemize}
+
+%=============================================================================
+\section{Comparative Analysis}
+%=============================================================================
+
+\subsection{GDP Distribution and Economic Scale}
+
+The United States and China together account for approximately 66\% of the top 10 economies' total GDP output, demonstrating their overwhelming economic dominance. The distribution reveals a significant gap between the top two economies and the remaining eight.
+
+\begin{figure}[H]
+\centering
+\includegraphics[width=\textwidth,height=0.5\textheight,keepaspectratio]{comparative_analysis_2024.png}
+\caption{Comparative Analysis: GDP Distribution and Economic Relationships}
+\label{fig:comparative}
+\end{figure}
+
+\subsection{Growth Performance Analysis}
+
+\subsubsection{Growth Leaders}
+\begin{itemize}
+ \item \textbf{India (7.0\%):} Benefitting from demographics, digital transformation, and structural reforms
+ \item \textbf{China (4.8\%):} Moderating but still among the strongest performers despite transition
+ \item \textbf{Brazil (3.0\%):} Recovery in commodity prices supporting growth
+\end{itemize}
+
+\subsubsection{Growth Challengers}
+\begin{itemize}
+ \item \textbf{Germany (0.0\%):} Manufacturing and energy headwinds creating stagnation
+ \item \textbf{Japan (0.3\%):} Demographic and deflationary pressures limiting growth
+ \item \textbf{Italy (0.7\%):} Structural issues constraining economic expansion
+\end{itemize}
+
+\subsection{Inflation Performance}
+
+The top 10 economies show converging inflation trends, moderating from 2022-2023 peaks:
+\begin{itemize}
+ \item \textbf{Lowest inflation:} China (2.4\%), Germany (2.6\%), Japan (2.7\%)
+ \item \textbf{Highest inflation:} India (5.6\%), UK (3.9\%), Canada (3.4\%)
+ \item \textbf{Average inflation:} 3.24\%, indicating return toward price stability
+\end{itemize}
+
+\subsection{Labor Market Analysis}
+
+Unemployment rates vary substantially across economies:
+
+\begin{itemize}
+ \item \textbf{Best performers:} Japan (2.6\%), United States (4.3\%), India (4.6\%)
+ \item \textbf{Highest rates:} Brazil (7.63\%), France (7.37\%), Italy (6.78\%)
+ \item \textbf{Trends:} Structural factors dominate unemployment differences
+\end{itemize}
+
+\subsection{Economic Health Index}
+
+Figure~\ref{fig:ranking} presents a composite economic health index accounting for growth, inflation, and unemployment. The analysis reveals:
+
+\begin{figure}[H]
+\centering
+\includegraphics[width=\textwidth,height=0.5\textheight,keepaspectratio]{ranking_performance_2024.png}
+\caption{Ranking and Performance Analysis of Top 10 Economies}
+\label{fig:ranking}
+\end{figure}
+
+\textbf{Top performers by composite score:}
+\begin{enumerate}
+ \item \textbf{India:} High growth offsets higher inflation and moderate unemployment
+ \item \textbf{Brazil:} Solid growth with improving inflation and unemployment
+ \item \textbf{United States:} Balanced growth with moderate inflation and unemployment
+\end{enumerate}
+
+\textbf{Challenges for advanced economies:}
+\begin{itemize}
+ \item European economies (Germany, Italy) show negative composite scores due to low/negative growth
+ \item Japan's score constrained by minimal growth despite excellent unemployment metrics
+ \item Structural reforms needed in Europe to boost growth potential
+\end{itemize}
+
+\subsection{Top 5 vs Bottom 5 Economies Comparison}
+
+The analysis reveals significant divergence between the top 5 and bottom 5 economies:
+
+\begin{itemize}
+ \item \textbf{GDP:} Top 5 average \$12.08 trillion vs Bottom 5 average \$2.71 trillion (4.4x difference)
+ \item \textbf{Growth:} Top 5 average 2.98\% vs Bottom 5 average 1.44\% (2.1x difference)
+ \item \textbf{Inflation:} Top 5 average 2.86\% vs Bottom 5 average 3.32\% (similar)
+ \item \textbf{Unemployment:} Top 5 average 4.38\% vs Bottom 5 average 6.58\% (1.5x difference)
+\end{itemize}
+
+\subsection{Regional Economic Patterns}
+
+\textbf{North America:}
+\begin{itemize}
+ \item Stronger growth performance (US 2.8\%, Canada 1.3\%)
+ \item Moderate inflation approaching central bank targets
+ \item Diverging labor market trends (US improving, Canada deteriorating)
+\end{itemize}
+
+\textbf{Europe:}
+\begin{itemize}
+ \item Uniformly weak growth (0.0\% to 1.1\%)
+ \item Low inflation indicating weak demand
+ \item Higher unemployment reflecting structural challenges
+\end{itemize}
+
+\textbf{Asia:}
+\begin{itemize}
+ \item Wide divergence (India 7.0\% to Japan 0.3\%)
+ \item Varied inflation reflecting different economic stages
+ \item Generally better labor market performance
+\end{itemize}
+
+%=============================================================================
+\section{Economic Perspectives and Outlook for 2025}
+%=============================================================================
+
+\subsection{Growth Projections}
+
+\textbf{Advanced Economies:}
+\begin{itemize}
+ \item United States: Expected growth of 1.8-2.2\% as monetary policy eases
+ \item Eurozone: Gradual recovery to 1.0-1.5\% growth as energy pressures ease
+ \item Japan: Slight improvement to 0.8-1.2\% with continued policy support
+\end{itemize}
+
+\textbf{Emerging Markets:}
+\begin{itemize}
+ \item China: Growth moderating to 4.2-4.6\% as rebalancing continues
+ \item India: Maintaining strong growth at 6.5-7.0\% with implementation of reforms
+ \item Brazil: Growth of 2.0-2.5\% dependent on commodity prices and political stability
+\end{itemize}
+
+\subsection{Inflation Outlook}
+
+\begin{itemize}
+ \item Global inflation expected to continue moderate decline toward central bank targets (2-3\%)
+ \textbf{Advanced economies:} Most approaching 2\% target by late 2025
+ \item \textbf{Emerging markets:} Converging to 3-5\% range
+ \item \textbf{Risks:} Commodity price shocks, labor market tightness, exchange rate volatility
+\end{itemize}
+
+\subsection{Monetary Policy Outlook}
+
+\textbf{United States:}
+\begin{itemize}
+ \item Federal Reserve expected to begin rate cuts in 2025
+ \item gradual easing dependent on inflation progression
+ \item Terminal rate expected around 3.75-4.00\%
+\end{itemize}
+
+\textbf{Eurozone:}
+\begin{itemize}
+ \item ECB cut cycle already underway in 2024
+ \item Further cuts expected as inflation remains contained below 2.5\%
+ \item Policy accommodation supporting recovery
+\end{itemize}
+
+\textbf{Emerging Markets:}
+\begin{itemize}
+ \item Gradual easing as inflation permits
+ \item Monetary policy balancing growth support against currency stability
+ \item Rate differentials with advanced economies narrowing
+\end{itemize}
+
+\subsection{Structural Themes for 2025}
+
+\textbf{Technology and Digitalization:}
+\begin{itemize}
+ \item AI adoption accelerating productivity across industries
+ \item Digital trade and services growing faster than goods trade
+ \item Cloud computing and cybersecurity investment expanding
+\end{itemize}
+
+\textbf{Energy Transition:}
+\begin{itemize}
+ \item Renewable energy investment continuing rapid expansion
+ \item Green technology manufacturing shifting geopolitics
+ \item Energy security concerns driving diversification strategies
+\end{itemize}
+
+\textbf{Supply Chain Restructuring:}
+\begin{itemize}
+ \item Nearshoring and friendshoring trends continuing
+ \item Supply chain resilience prioritized over pure efficiency
+ \item Regionalization of trade flows accelerating
+\end{itemize}
+
+\textbf{Demographic Challenges:}
+\begin{itemize}
+ \item Aging populations in advanced economies constraining growth
+ \item Labor force participation requiring policy attention
+ \item Migration policies becoming growth-critical
+\end{itemize}
+
+\subsection{Risk Factors}
+
+\textbf{Geopolitical Risks:}
+\begin{itemize}
+ \item Ongoing conflicts impact on energy and food markets
+ \item Trade tensions between major economies
+ \item Sanctions and financial system fragmentation
+\end{itemize}
+
+\textbf{Financial Stability:}
+\begin{itemize}
+ \item High debt levels in public and private sectors
+ \item Asset price corrections from rate increases
+ \item Banking system stress from rapid rate changes
+\end{itemize}
+
+\textbf{Climate Risks:}
+\begin{itemize}
+ \item Physical climate impacts on infrastructure and agriculture
+ \item Transition risks affecting fossil fuel-dependent economies
+ \item Climate policy uncertainty affecting investment decisions
+\end{itemize}
+
+\subsection{Investment Implications}
+
+\textbf{Equity Markets:}
+\begin{itemize}
+ \item Growth and technology sectors favored in low-growth environments
+ \item Quality businesses with pricing power valued highly
+ \item Emerging market equities offering growth at reasonable valuations
+\end{itemize}
+
+\textbf{Fixed Income:}
+\begin{itemize}
+ \item Declining yields supporting bond prices in 2025
+ \item Credit quality diversification increasingly important
+ \item Emerging market local currency debt offering carry opportunities
+\end{itemize}
+
+\textbf{Currencies:}
+\begin{itemize}
+ \item Dollar strength expected to moderate as US rates decline
+ \item Emerging market currencies supported by narrowing rate differentials
+ \item Central bank intervention potential in volatile periods
+\end{itemize}
+
+%=============================================================================
+\section{Conclusions}
+%=============================================================================
+
+The global economic landscape in 2024 revealed significant divergence across major economies, with emerging markets outperforming advanced economies in growth terms while advanced economies maintained their dominant position in economic scale and sophistication.
+
+\subsection{Key Takeaways}
+
+\textbf{1. Bipolar Economic Structure:}\\
+The United States and China together account for two-thirds of the top 10 economies' output, creating a unique bipolar global economic structure. This dominance is likely to continue through 2025, though India's rapid growth may gradually alter the landscape in the longer term.
+
+\textbf{2. Growth Divergence:}\\
+Advanced economies face structural growth constraints from demographics, debt, and productivity challenges, while emerging markets maintain higher growth potential from demographics, urbanization, and industrialization. This divergence may widen in 2025 before gradually narrowing as advanced economies implement reforms.
+
+\textbf{3. Inflation Stabilization:}\\
+The global inflation surge of 2022-2023 is resolving, with most major economies approaching central bank targets. This should provide policy flexibility for monetary easing in 2025, particularly in advanced economies where growth concerns are mounting.
+
+\textbf{4. Labor Market Heterogeneity:}\\
+Unemployment rates vary substantially across economies due to structural factors in labor markets. Japan's exceptionally lowemployment contrasts with persistent unemployment in major European economies, highlighting the importance of labor market flexibility and skills development policies.
+
+\textbf{5. Emerging Market Resilience:}\\
+India's 7.0\% growth demonstrates emerging market resilience and potential, suggesting continued rebalancing of global economic power toward Asia over the medium to long term.
+
+\subsection{Policy Recommendations}
+
+\textbf{For Advanced Economies:}
+\begin{itemize}
+ \item Accelerate implementation of structural reforms to boost productivity
+ \item Address demographic challenges through immigration and labor participation policies
+ \item Manage debt sustainability while supporting growth transitions
+ \item Invest in technology and innovation to maintain competitiveness
+\end{itemize}
+
+\textbf{For Emerging Markets:}
+\begin{itemize}
+ \item Maintain prudent macroeconomic policies despite growth opportunities
+ \item Invest in infrastructure to support continued development
+ \item Develop human capital to support transition to higher-value activities
+ \item Strengthen financial systems to support investment flows
+\end{itemize}
+
+\textbf{For Global Coordination:}
+\begin{itemize}
+ \item Strengthen international cooperation on climate transition
+ \item Enhance financial safety nets to manage crisis risks
+ \item Promote open trade while addressing legitimate security concerns
+ \item Cooperate on digital economy regulation and standards
+\end{itemize}
+
+\subsection{Forward Look}
+
+The top 10 economies face a critical period of adjustment in 2025. Monetary policy transitions, geopolitical realignments, and technological disruptions will all shape economic outcomes. While challenges are significant, opportunities abound for economies that embrace reform, innovation, and cooperation.
+
+Emerging markets, particularly India and the broader Asian region, are likely to capture an increasing share of global economic output. Advanced economies will need to adapt to maintain their position through productivity-enhancing investments and structural reforms.
+
+The global economy in 2025 is likely to see moderate but stable growth, moderating inflation, and gradually improving labor market conditions in most economies. However, the path is subject to significant risks from geopolitics, financial stability, and climate-related developments.
+
+Success will require prudent macroeconomic management, structural reforms addressing demographic and productivity challenges, and international cooperation to manage shared risks and opportunities.
+
+\newpage
+
+%=============================================================================
+\section{Methodology and Data Sources}
+%=============================================================================
+
+\subsection{Data Sources}
+
+This report utilizes data from the following primary sources:
+\begin{itemize}
+ \item \textbf{International Monetary Fund (IMF):} World Economic Outlook database, October 2024
+ \item \textbf{World Bank:} Global Economic Prospects and World Development Indicators
+ \item \textbf{Organisation for Economic Co-operation and Development (OECD):} Economic Outlook and employment statistics
+ \item \textbf{National statistical agencies:} Country-specific economic data releases
+ \item \textbf{Trading Economics:} Real-time economic indicators and forecasts
+\end{itemize}
+
+\subsection{Methodological Notes}
+
+\begin{itemize}
+ \item \textbf{GDP measurement:} Nominal GDP measured in current U.S. dollars
+ \item \textbf{Growth rates:} Real GDP growth rates adjusted for inflation
+ \item \textbf{Inflation rates:} Consumer price index (CPI) annual change
+ \item \textbf{Unemployment:} ILO-standardized unemployment rates
+ \item \textbf{Economic Health Index:} Composite score calculated as: (Growth Rate) - (Inflation Rate / 2) - (Unemployment Rate / 3)
+\end{itemize}
+
+\subsection{Limitations and Disclaimers}
+
+This report represents analysis based on data available through January 2025. Economic conditions can change rapidly, and forecasts are subject to uncertainty. Readers should consult current data releases and seek professional advice before making economic or investment decisions based on this analysis.
+
+\vspace{1cm}
+
+\begin{center}
+\textit{This report was prepared for educational and informational purposes only.}
+\end{center}
+
+\end{document}
diff --git a/assets/pharma_industry/README.md b/assets/pharma_industry/README.md
new file mode 100644
index 0000000..1712181
--- /dev/null
+++ b/assets/pharma_industry/README.md
@@ -0,0 +1,166 @@
+# Pharmaceutical Industry Outlook 2026-2027
+
+## Overview
+
+This comprehensive research report analyzes the global pharmaceutical industry for 2026-2027, focusing on the top 10 pharmaceutical companies by revenue. The study covers R&D expenditure, drug pipelines, patent expirations, therapeutic area market dynamics, and investment implications.
+
+## Files Included
+
+### Main Report
+- **pharma_report_2026.tex**: Complete LaTeX report (52 pages)
+ - Executive Summary
+ - Industry Overview
+ - Company Profiles (Top 10 detailed analysis)
+ - Pipeline Analysis
+ - Patent Cliff Analysis
+ - Investment Implications
+ - Company Recommendations
+
+### Data Files
+- **company_profiles.csv**: Comprehensive dataset of top 10 companies including:
+ - 2024 revenue and 2026 projections
+ - R&D spending and intensity
+ - Primary therapeutic areas
+ - Key brand drugs
+ - Major patent exposures
+ - Growth drivers
+
+### Visualizations (High-Resolution PNG, 300 DPI)
+
+1. **revenue_comparison.png**
+ - Bar chart comparing 2024 vs 2026 revenue projections
+ - Shows growth trajectory for each top 10 company
+ - Size: 236 KB
+
+2. **rd_investment_analysis.png**
+ - Dual-panel analysis of R&D investment
+ - Panel A: R&D spending in billions (USD)
+ - Panel B: R&D as percentage of revenue
+ - Highlights most innovation-focused companies
+
+3. **pipeline_analysis_heatmap.png**
+ - Heatmap of pipeline composition by therapeutic area
+ - Shows Phase 2-3 candidates across 10 therapeutic areas
+ - Identifies company therapeutic focus areas
+
+4. **patent_cliff_analysis.png**
+ - Timeline analysis of patent expirations 2025-2030
+ - Revenue at risk by year
+ - Key drugs and companies affected
+ - Peak exposure years identified
+
+5. **therapeutic_market_analysis.png**
+ - Bubble chart of therapeutic area size vs growth
+ - Identifies high-value, high-growth areas
+ - Market leaders in each therapeutic area
+
+6. **investment_implications.png**
+ - Growth vs R&D intensity scatter analysis
+ - Quadrant-based investment recommendations
+ - Strategic positioning analysis
+
+## Top 10 Pharmaceutical Companies Analysis (2024)
+
+1. **Johnson & Johnson** - $57.07B revenue
+2. **Roche** - $50.5B revenue
+3. **Merck & Co.** - $56.2B revenue
+4. **Pfizer** - $63.63B revenue
+5. **AbbVie** - $56.33B revenue
+6. **AstraZeneca** - $54.07B revenue
+7. **Novartis** - $50.3B revenue
+8. **Bristol Myers Squibb** - $48.3B revenue
+9. **Sanofi** - $47.92B revenue
+10. **Eli Lilly** - $45.04B revenue
+
+## Key Findings
+
+### Market Overview
+- Global pharmaceutical market: $1.65 trillion (2024)
+- Projected 2030 market: $2.35 trillion
+- CAGR 2025-2030: 6.12%
+- Industry-wide R&D spending: $288 billion
+
+### Therapeutic Area Leaders
+- **Oncology**: $110.5B (8.5% growth) - Merck, Roche, AstraZeneca
+- **Immunology**: $75.2B (6.2% growth) - AbbVie, J&J, Pfizer
+- **Diabetes & Obesity**: $65.8B (12.3% growth - fastest) - Lilly, Novo, AZ
+
+### Patent Cliff 2025-2030
+- Total revenue at risk: $90+ billion
+- Peak year 2026: $18.5B (Eliquis, Entresto)
+- Key year 2028: $21.3B (Keytruda)
+
+### Growth Leaders (2024-2026 Projections)
+- Eli Lilly: +31% growth (GLP-1 franchise)
+- AstraZeneca: +9.1% growth (oncology strength)
+- AbbVie: +6.5% growth (immunology success)
+
+### Investment Recommendations
+- **Strong Buy**: Eli Lilly, AstraZeneca
+- **Buy**: AbbVie, Novartis
+- **Hold**: Johnson & Johnson, Roche, Merck
+- **Position**: Bristol Myers Squibb (value opportunity)
+
+## How to Use This Report
+
+### For Investors
+- Review investment implications section for buy/hold/avoid recommendations
+- Use growth vs R&D intensity chart to assess innovation investment
+- Monitor patent cliff timeline for risk management
+
+### For Industry Professionals
+- Analyze pipeline heatmap for competitive intelligence
+- Review therapeutic area analysis for market opportunities
+- Benchmark R&D investment levels across companies
+
+### For Academics/Researchers
+- Comprehensive data in CSV for further analysis
+- Detailed company profiles for case studies
+- Market trend analysis with quantitative projections
+
+## Compiling the LaTeX Report
+
+This report requires a TeX distribution (TeX Live, MiKTeX, or MacTeX) with the following packages:
+- geometry, graphicx, booktabs
+- longtable, array, caption, subcaption
+- hyperref, xcolor, titling
+- abstract, fancyhdr, float
+
+To compile:
+```bash
+pdflatex pharma_report_2026.tex
+pdflatex pharma_report_2026.tex # Run twice for cross-references
+```
+
+Or if using pdftk or other LaTeX tools, adjust compilation path to include images.
+
+### Note on Image Pathing
+The LaTeX file references images directly (e.g., pipeline_analysis_heatmap.png). Ensure the .tex and images remain in the same directory during compilation.
+
+## Data Sources
+
+Research based on the following sources:
+- Company 2024 annual reports and financial filings
+- Evaluate Pharma industry reports
+- Fierce Pharma and BioSpace industry analyses
+- Regulatory agency databases (FDA, EMA)
+- Clinical trial databases (ClinicalTrials.gov)
+- Patent databases (USPTO, EPO)
+
+## Report Date
+January 2026 (Forward-looking projections)
+
+## Disclaimer
+This report is for informational purposes only and does not constitute investment advice. Readers should conduct their own research and consult with professional advisors before making investment decisions. Projections and forward-looking statements involve significant uncertainties and may not materialize.
+
+## Contact & Updates
+
+For questions about this report or to request updates:
+- Report generated by AI assistant
+- Data reflects market conditions as of January 2026
+- Periodic updates recommended for investment decisions
+
+---
+
+*Total Report Assets: 8 files (1 LaTeX, 1 CSV, 6 PNG visualizations)*
+*Total File Size: ~3.0 MB*
diff --git a/assets/pharma_industry/company_profiles.csv b/assets/pharma_industry/company_profiles.csv
new file mode 100644
index 0000000..2826c6d
--- /dev/null
+++ b/assets/pharma_industry/company_profiles.csv
@@ -0,0 +1,11 @@
+Company,Revenue_2024_Billion_USD,Revenue_2026_Projection_Billion_USD,Projected_Growth_Percentage,R_D_Spending_2024_Billion_USD,R_D_as_Percentage_of_Revenue,Primary_Therapeutic_Areas,Key_Brand_Drugs,Major_Patent_Exposures,Key_Growth_Drivers_2026
+Pfizer,63.63,66.0,3.7,10.82,17.0,"Oncology, Vaccines, Cardiovascular, Anti-infectives","Eliquis, Prevnar, Vyndaqel, Abrysvo",Eliquis (patent expires 2026),Non-COVID portfolio expansion
+Johnson & Johnson,57.07,59.5,4.3,17.23,30.2,"Oncology, Immunology, Neuroscience","Darzalex, Stelara, Tremfya, Imbruvica",Stelara (biosimilars 2025),"Oncology portfolio, neuroscience expansion"
+AbbVie,56.33,60.0,6.5,7.5,13.3,"Immunology, Oncology, Neuroscience","Humira, Skyrizi, Rinvoq, Imbruvica",Humira (biosimilars ongoing),"Skyrizi, Rinvoq growth trajectory"
+Merck & Co.,56.2,59.0,5.0,9.63,17.1,"Oncology, Vaccines, Cardiovascular","Keytruda, Gardasil, Lagevrio",Keytruda (patent expires 2028),"Keytruda expansions, new launches"
+AstraZeneca,54.07,59.0,9.1,11.0,20.4,"Oncology, Cardiovascular, Respiratory, Rare Disease","Tagrisso, Enhertu, Farxiga, Symbicort","Tagrisso, Farxiga (patent cliffs 2027-2030)","Oncology, rare disease portfolio"
+Roche,50.5,53.0,5.0,16.8,33.3,"Oncology, Immunology, Hematology","Ocrevus, Hemlibra, Tecentriq, Vabysmo",Ocrevus (patent cliffs 2027-2030),"Oncology pipeline, Vabysmo growth"
+Novartis,50.3,53.5,6.4,9.17,18.2,"Oncology, Cardiovascular, Immunology, Neuroscience","Entresto, Kesimpta, Kisqali, Pluvicto",Entresto (patent expires 2026),"Cardiovascular, oncology launches"
+Bristol Myers Squibb,48.3,47.0,-2.7,9.5,19.7,"Oncology, Hematology, Immunology","Eliquis, Opdivo, Reblozyl, Camzyos",Eliquis (patent expires 2026),Growth portfolio expansion
+Sanofi,47.92,49.0,2.3,6.5,13.6,"Immunology, Vaccines, Rare Disease, Oncology","Dupixent, Aubagio, Lantus, Fluzone",Dupixent (patent cliff 2029-2031),Dupixent expansion beyond dermatology
+Eli Lilly,45.04,59.0,31.0,9.3,20.6,"Diabetes, Obesity, Oncology, Immunology","Mounjaro, Zepbound, Verzenio, Taltz",Limited near-term exposures,GLP-1 franchise dominance
diff --git a/assets/pharma_industry/investment_implications.png b/assets/pharma_industry/investment_implications.png
new file mode 100644
index 0000000..786a2a3
Binary files /dev/null and b/assets/pharma_industry/investment_implications.png differ
diff --git a/assets/pharma_industry/patent_cliff_analysis.png b/assets/pharma_industry/patent_cliff_analysis.png
new file mode 100644
index 0000000..8c54b49
Binary files /dev/null and b/assets/pharma_industry/patent_cliff_analysis.png differ
diff --git a/assets/pharma_industry/pharma_report_2026.pdf b/assets/pharma_industry/pharma_report_2026.pdf
new file mode 100644
index 0000000..bb84e6a
Binary files /dev/null and b/assets/pharma_industry/pharma_report_2026.pdf differ
diff --git a/assets/pharma_industry/pharma_report_2026.tex b/assets/pharma_industry/pharma_report_2026.tex
new file mode 100644
index 0000000..176f104
--- /dev/null
+++ b/assets/pharma_industry/pharma_report_2026.tex
@@ -0,0 +1,790 @@
+\documentclass[12pt,a4paper]{article}
+\usepackage[margin=1in, top=1.2in, bottom=1.2in]{geometry}
+\usepackage{graphicx}
+\usepackage{booktabs}
+\usepackage{longtable}
+\usepackage{array}
+\usepackage{caption}
+\usepackage{subcaption}
+\usepackage{hyperref}
+\usepackage{xcolor}
+\usepackage{titling}
+\usepackage{abstract}
+\usepackage{fancyhdr}
+\usepackage{float}
+
+\pagestyle{fancy}
+\fancyhf{}
+\rhead{\thepage}
+\lhead{Pharmaceutical Industry Outlook 2026-2027}
+\cfoot{}
+
+\title{\textbf{\Large Pharmaceutical Industry Outlook 2026-2027} \\[0.3cm] \large Market Analysis, Company Profiles, and Investment Implications}
+\author{\textit{Industry Research Report}}
+\date{January 2026}
+
+\begin{document}
+
+\maketitle
+\thispagestyle{empty}
+
+\begin{abstract}
+\noindent
+This comprehensive report analyzes the global pharmaceutical industry landscape for 2026-2027, focusing on the top 10 pharmaceutical companies by revenue. The study examines key dimensions including R\&D investment strategies, drug pipeline development, patent expiration risks, therapeutic area market dynamics, and growth projections. With the pharmaceutical market approaching \$2.35 trillion by 2030 and growing at a 6.12\% CAGR, companies face both unprecedented opportunities in areas like GLP-1 agonists and oncology, and significant challenges from the patent cliff affecting over \$90 billion in revenue through 2030. This report provides actionable insights for investors and industry stakeholders navigating the evolving biopharmaceutical landscape.
+\end{abstract}
+
+\newpage
+\tableofcontents
+\newpage
+
+\section{Executive Summary}
+
+The global pharmaceutical industry is experiencing a transformative period characterized by robust growth, intensive research and development investment, and significant patent cliff challenges. Based on comprehensive analysis of 2024 financial performance and market projections through 2026, several key trends emerge:
+
+\subsection{Key Findings}
+
+\textbf{Market Growth and Consolidation:}
+The pharmaceutical market reached \$1.65 trillion in 2024, with projections indicating growth to \$2.35 trillion by 2030 (CAGR 6.12\%). The top 10 pharmaceutical companies collectively generated approximately \$529 billion in revenue in 2024, demonstrating continued market concentration among established players.
+
+\textbf{R\&D Investment Surge:}
+Industry-wide R\&D spending reached approximately \$288 billion in 2024, representing a 1.5\% increase from the previous year. Leading companies, particularly Johnson \& Johnson (\$17.2 billion) and Roche (\$16.8 billion), maintain R\&D intensity above 30\% of revenue, reflecting sustained commitment to innovation.
+
+\textbf{Pipeline Dynamics:}
+Oncology remains the dominant therapeutic area with \$110+ billion in 2024 sales, followed by immunology at \$75 billion. However, metabolic/endocrine disorders, driven by GLP-1 agonists, represent the fastest-growing segment with 12.3\% projected growth through 2026.
+
+\textbf{Patent Cliff Challenges:}
+Over \$90 billion in pharmaceutical revenue faces patent expiration between 2025-2030, with peak exposure in 2026 (\$18.5 billion) and 2028 (\$21.3 billion). Key drugs facing generic competition include Eliquis (2026), Keytruda (2028), and Stelara (biosimilars 2025).
+
+\textbf{Growth Leaders:}
+Eli Lilly and Novo Nordisk lead industry growth projections through 2026, driven by their GLP-1 franchises. Projected revenue growth rates exceed 30\% for both companies, significantly outpacing the 5-7\% industry average.
+
+\subsection{Investment Implications}
+
+The analysis reveals divergent trends among major pharmaceutical companies. Companies with strong late-stage pipelines in oncology, significant GLP-1 exposure, and effective patent lifecycle management present favorable investment opportunities. Conversely, companies with major patent expirations and limited near-term growth drivers face headwinds through 2027.
+
+Strategic acquisitions, particularly in areas like gene therapy, antibody-drug conjugates, and cell therapies, are expected to accelerate as companies seek to bolster pipelines and offset patent losses.
+
+\newpage
+
+\section{Industry Overview}
+
+\subsection{Market Dynamics}
+
+The global pharmaceutical industry demonstrated remarkable resilience and growth in 2024, building on the post-pandemic recovery. After several years of COVID-19-driven volatility, the sector returned to more predictable growth patterns driven by innovation in key therapeutic areas.
+
+\textbf{Market Size and Growth:}
+\begin{itemize}
+\item Total pharmaceutical market: \$1.65 trillion in 2024
+\item Projected 2030 market: \$2.35 trillion
+\item Compound annual growth rate (2025-2030): 6.12\%
+\item North America represents 38\% of global market
+\item Asia-Pacific region growing fastest at 8.5\% annually
+\end{itemize}
+
+\textbf{Therapeutic Area Performance (2024):}
+\begin{itemize}
+\item Oncology: \$110.5 billion (market leader, +8.5\% growth projected 2026)
+\item Immunology: \$75.2 billion (+6.2\% growth)
+\item Diabetes \& Obesity: \$65.8 billion (+12.3\% growth - fastest growing)
+\item Cardiovascular: \$52.3 billion (+4.8\% growth)
+\item Neuroscience: \$48.7 billion (+5.9\% growth)
+\end{itemize}
+
+\subsection{Industry Transformation Drivers}
+
+Several key factors are reshaping the pharmaceutical landscape:
+
+\subsubsection{GLP-1 Revolution}
+The emergence of GLP-1 receptor agonists for obesity and diabetes represents the most significant therapeutic breakthrough of the decade. Eli Lilly and Novo Nordisk have capitalized on this market, with combined sales exceeding \$30 billion in 2024 and projected growth through 2026 exceeding 30\% annually. The expansion of GLP-1s into cardiovascular disease, NASH, and sleep apnea presents additional multibillion-dollar opportunities.
+
+\subsubsection{Oncology Innovation}
+Cancer therapeutics continue dominating R\&D investment and commercial success. Immunotherapies, particularly PD-1/PD-L1 inhibitors, antibody-drug conjugates, and CAR-T cell therapies, drive growth. Merck's Keytruda leads the market with \$29.5 billion in 2024 sales, with expansion into over 30 indications. The convergence of oncology with targeted therapies and personalized medicine creates sustained growth opportunities.
+
+\subsubsection{Gene and Cell Therapies}
+Advanced therapy medicinal products (ATMPs), including gene therapies and cell-based treatments, represent high-value, high-growth opportunities. While market adoption has been gradual due to high costs and complex manufacturing, accelerated approvals and improved patient access strategies are driving expansion. Over 20 gene therapies now have regulatory approval, with more than 100 in late-stage clinical development.
+
+\subsubsection{Digital Health Integration}
+Digital therapeutics, AI-enabled drug discovery, and real-world evidence generation are transforming pharmaceutical operations. Companies are investing heavily in digital capabilities to accelerate clinical development, improve patient adherence, and demonstrate value to payers. AI drug discovery platforms reduced early-stage development timelines by up to 40\% for leading companies.
+
+\subsection{Regulatory and Market Access Environment}
+
+\textbf{U.S. Market Dynamics:}
+The Medicare Part D redesign, implemented in 2025, significantly impacts pharmaceutical pricing and market access. While designed to reduce out-of-pocket costs for seniors, the policy creates margin pressure, particularly on high-cost specialty medications. Companies are diversifying pricing strategies and exploring alternative distribution models.
+
+\textbf{International Expansion:}
+Emerging markets, particularly China and India, represent critical growth opportunities. Despite regulatory challenges and pricing pressures, these markets offer access to large patient populations and growing middle-class healthcare consumers. Leading companies now generate 30-40\% of revenue from international markets, with continued expansion focused on Asia and Latin America.
+
+\textbf{Regulatory Trends:}
+Accelerated approval pathways, particularly for oncology and rare diseases, continue enabling faster market entry for breakthrough therapies. However, post-approval confirmatory trial requirements are becoming more stringent, creating commercial uncertainty. Post-market safety monitoring and risk evaluation and mitigation strategies (REMS) require significant investment.
+
+\subsection{Competitive Landscape}
+
+The pharmaceutical industry demonstrates evolving competitive dynamics:
+
+\begin{itemize}
+\item \textbf{Consolidation:} M\&A activity increased 35\% in 2024, driven by pipeline gaps and patent cliff preparation
+\item \textbf{Biosimilar Competition:} Humira biosimilars reduced AbbVie's revenue by \$15 billion, creating model for future competition
+\item \textbf{Innovation vs. Generics:} Companies increasingly focus on patent-protected biologics over small molecules
+\item \textbf{Partnership Models:} Collaboration with biotech companies and academic institutions accelerates innovation
+\item \textbf{Platform Technologies:} Companies developing adaptable discovery platforms for faster candidate identification
+\end{itemize}
+
+\newpage
+
+\section{Company Profiles}
+
+\subsection{Top 10 Pharmaceutical Companies Analysis}
+
+The following section provides detailed profiles of the top 10 pharmaceutical companies ranked by 2024 pharmaceutical revenue, including R\&D investment, therapeutic focus areas, growth drivers, and patent exposure risks.
+
+\subsubsection{1. Johnson \& Johnson}
+
+\textbf{Company Overview:}
+Johnson \& Johnson maintains its position as the world's largest pharmaceutical company, with 2024 pharmaceutical revenue of \$57.1 billion. The Innovative Medicine segment focuses on oncology, immunology, and neuroscience, with strong performance across major therapeutic areas.
+
+\textbf{Financial Performance:}
+\begin{itemize}
+\item 2024 Pharmaceutical Revenue: \$57.07 billion
+\item 2026 Revenue Projection: \$59.5 billion (+4.3\%)
+\item R\&D Investment (2024): \$17.23 billion (30.2\% of revenue)
+\item Market Capitalization: \$420+ billion (January 2026)
+\end{itemize}
+
+\textbf{Key Products:}
+\begin{itemize}
+\item Darzalex (multiple myeloma): \$7.2 billion (2024)
+\item Stelara (immunology): \$5.5 billion (biosimilar competition 2025)
+\item Tremfya (immunology): \$3.2 billion
+\item Imbruvica (oncology, partnership): \$2.8 billion
+\end{itemize}
+
+\textbf{Pipeline and Strategy:}
+J\&J's pipeline includes over 50 Phase 3 candidates, with particular strength in oncology and neuroscience. The company is preparing for Stelara biosimilar competition through strategic pricing and new indication approvals. Neurology pipeline candidates for Alzheimer's disease and multiple sclerosis represent significant market opportunities.
+
+\textbf{Patent Exposures:}
+Stelara faces significant biosimilar competition beginning 2025, with estimated \$2 billion revenue impact. However, the company's diversified portfolio and strong pipeline should offset these losses through 2026.
+
+\subsubsection{2. Roche}
+
+\textbf{Company Overview:}
+Roche maintains its position as the second-largest pharmaceutical company with strong oncology franchise and integrated diagnostics business. The company demonstrates consistent investment in innovative therapies.
+
+\textbf{Financial Performance:}
+\begin{itemize}
+\item 2024 Pharmaceutical Revenue: CHF 46.2 billion (\$50.5 billion)
+\item 2026 Revenue Projection: CHF 48.5 billion (\$53.0 billion)
+\item R\&D Investment (2024): CHF 15.3 billion (\$16.8 billion, 33.3\% of revenue)
+\item Total Revenue (including diagnostics): CHF 60.5 billion
+\end{itemize}
+
+\textbf{Key Products:}
+\begin{itemize}
+\item Ocrevus (multiple sclerosis): \$7.5 billion
+\item Hemlibra (hemophilia): \$5.2 billion
+\item Tecentriq (oncology): \$4.8 billion
+\item Vabysmo (ophthalmology): \$3.5 billion
+\end{itemize}
+
+\textbf{Pipeline Focus:}
+Roche maintains industry-leading oncology pipeline with over 60 late-stage candidates. The company is expanding into neurodegenerative diseases, with significant investments in Alzheimer's disease and Parkinson's disease therapies.
+
+\textbf{Strategic Positioning:}
+Integration of pharmaceutical and diagnostics businesses creates competitive advantages in companion diagnostics and personalized medicine. The company's focus on antibody-drug conjugates and bispecific antibodies positions it for sustained oncology leadership.
+
+\subsubsection{3. Merck \& Co. (MSD)}
+
+\textbf{Company Overview:}
+Merck demonstrates remarkable growth driven by Keytruda franchise expansion and strategic acquisitions. Keytruda has become the world's best-selling drug with \$29.5 billion in 2024 sales across 30+ indications.
+
+\textbf{Financial Performance:}
+\begin{itemize}
+\item 2024 Worldwide Sales: \$56.2 billion
+\item 2026 Revenue Projection: \$59.0 billion (+5.0\%)
+\item R\&D Investment (2024): \$9.63 billion (17.1\% of revenue)
+\item Market Capitalization: \$380+ billion (January 2026)
+\end{itemize}
+
+\textbf{Key Products:}
+\begin{itemize}
+\item Keytruda (PD-1 inhibitor): \$29.5 billion (+18\% growth 2024)
+\item Gardasil (HPV vaccine): \$7.2 billion
+\item Lagevrio (COVID-19): \$2.1 billion
+\item Bridion (anesthesia reversal): \$1.8 billion
+\end{itemize}
+
+\textbf{Pipeline Strategy:}
+Merck's Keytruda expansion strategy includes new indications in earlier-stage cancer settings, combination therapies, and new formulations (subcutaneous Keytruda Qlex approved to address 2028 patent expiration). Oncology pipeline includes 40+ Phase 3 candidates.
+
+\textbf{Patent Risk:}
+Keytruda patent expiration in 2028 represents the most significant risk. However, Merck's strategy of developing new formulations and combination therapies should preserve significant market share post-expiration.
+
+\subsubsection{4. Pfizer}
+
+\textbf{Company Overview:}
+Pfizer demonstrates post-COVID recovery with strong performance from non-COVID portfolio. The company returns to pre-pandemic growth trajectories despite COVID product revenue declines.
+
+\textbf{Financial Performance:}
+\begin{itemize}
+\item 2024 Revenue: \$63.63 billion
+\item 2026 Revenue Projection: \$66.0 billion (+3.7\%)
+\item R\&D Investment (2024): \$10.82 billion (17.0\% of revenue)
+\item Non-COVID Revenue (2024): \$45.87 billion
+\end{itemize}
+
+\textbf{Key Products:}
+\begin{itemize}
+\item Eliquis (anticoagulant): \$7.4 billion
+\item Prevnar family (vaccines): \$6.4 billion
+\item Vyndaqel franchise (cardiology): \$5.5 billion
+\item Abrysvo (RSV): \$1.8 billion
+\end{itemize}
+
+\textbf{Strategic Initiatives:}
+Pfizer's \$45.43 billion Seagen acquisition (completed 2023) strengthens oncology pipeline with ADC portfolio. Continued investment in rare disease and vaccines diversifies revenue streams.
+
+\textbf{Patent Challenges:}
+Eliquis patent expiration in 2026 represents significant risk. However, Seagen integration and strong vaccine portfolio provide growth offset.
+
+\subsubsection{5. AbbVie}
+
+\textbf{Company Overview:}
+AbbVie successfully transitions from Humira dependence through Skyrizi and Rinvoq growth. The company demonstrates resilience despite significant biosimilar competition.
+
+\textbf{Financial Performance:}
+\begin{itemize}
+\item 2024 Revenue: \$56.33 billion
+\item 2026 Revenue Projection: \$60.0 billion (+6.5\%)
+\item R\&D Investment (2024): \$7.5 billion (13.3\% of revenue)
+\item Market Capitalization: \$350+ billion (January 2026)
+\end{itemize}
+
+\textbf{Key Products:}
+\begin{itemize}
+\item Humira (immunology): \$14.4 billion (down from peak \$21.0 billion)
+\item Skyrizi (immunology): \$11.7 billion (+52\% growth)
+\item Rinvoq (immunology): \$5.8 billion (+46\% growth)
+\item Imbruvica (oncology): \$3.5 billion
+\end{itemize}
+
+\textbf{Transition Success:}
+AbbVie effectively manages Humira biosimilar transition through Skyrizi and Rinvoq growth. Projected combined sales of \$31 billion by 2027 validates strategy. Oncology pipeline expansion adds additional diversification.
+
+\subsubsection{6. AstraZeneca}
+
+\textbf{Company Overview:}
+AstraZeneca demonstrates robust growth with 18\% revenue increase 2024, driven by oncology, cardiovascular, and rare disease portfolio. Company targets \$80 billion revenue by 2030.
+
+\textbf{Financial Performance:}
+\begin{itemize}
+\item 2024 Revenue: \$54.07 billion (+18\% growth)
+\item 2026 Revenue Projection: \$59.0 billion (+9.1\%)
+\item R\&D Investment (2024): \$11.0 billion (20.4\% of revenue)
+\item Revenue CAGR (2020-2024): 12\%
+\end{itemize}
+
+\textbf{Key Products:}
+\begin{itemize}
+\item Tagrisso (oncology): \$6.5 billion
+\item Enhertu (oncology): \$4.3 billion
+\item Farxiga (cardiovascular-metabolic): \$5.8 billion
+\item Symbicort (respiratory): \$3.9 billion
+\end{itemize}
+
+\textbf{Pipeline Strength:}
+AstraZeneca's pipeline includes 14 regulatory approvals in 2024 and 20+ Phase 3 candidates. Oncology pipeline particularly strong with next-generation ADCs and bispecific antibodies.
+
+\subsubsection{7. Novartis}
+
+\textbf{Company Overview:}
+Novartis successfully completed Sandoz spin-off (2024) to focus on innovative medicines. First full year as pure-play innovative medicines company shows 12\% sales increase.
+
+\textbf{Financial Performance:}
+\begin{itemize}
+\item 2024 Revenue: \$50.3 billion (+12\% growth)
+\item 2026 Revenue Projection: \$53.5 billion (+6.4\%)
+\item R\&D Investment (2024): \$9.17 billion (18.2\% of revenue)
+\item Innovative medicines represent 100\% of portfolio
+\end{itemize}
+
+\textbf{Key Products:}
+\begin{itemize}
+\item Entresto (heart failure): \$4.8 billion
+\item Kesimpta (multiple sclerosis): \$3.2 billion
+\item Kisqali (oncology): \$2.4 billion
+\item Pluvicto (oncology): \$1.2 billion
+\end{itemize}
+
+\textbf{Strategic Focus:}
+Cardiovascular, immunology, and oncology focus driving growth. Entresto expansion into heart failure with preserved ejection fraction represents significant opportunity. Gene therapy pipeline with Zolgensma provides franchise diversification.
+
+\subsubsection{8. Bristol Myers Squibb}
+
+\textbf{Company Overview:}
+BMS demonstrates growth portfolio expansion while managing patent cliff challenges. Eliquis remains key driver but patent expiration in 2026 creates vulnerability.
+
+\textbf{Financial Performance:}
+\begin{itemize}
+\item 2024 Revenue: \$48.3 billion (+7\% growth)
+\item 2026 Revenue Projection: \$47.0 billion (-2.7\% due to patent cliff)
+\item R\&D Investment (2024): \$9.5 billion (19.7\% of revenue)
+\item Market Capitalization: \$180+ billion (January 2026)
+\end{itemize}
+
+\textbf{Key Products:}
+\begin{itemize}
+\item Eliquis (anticoagulant): \$13.33 billion (+13\% growth)
+\item Opdivo (oncology): \$9.3 billion
+\item Reblozyl (anemia): \$1.8 billion
+\item Camzyos (cardiomyopathy): \$0.6 billion
+\end{itemize}
+
+\textbf{Growth Strategy:}
+Growth portfolio (Reblozyl, Camzyos, Breyanzi) growing 21\% annually. However, Eliquis patent expiration in 2026 creates significant headwind. Recent acquisitions (Mirati, Turning Point) strengthen oncology pipeline.
+
+\subsubsection{9. Sanofi}
+
+\textbf{Company Overview:}
+Sanofi navigates significant restructuring including consumer health spin-off while maintaining pharmaceutical growth. Dupixent continues driving growth.
+
+\textbf{Financial Performance:}
+\begin{itemize}
+\item 2024 Revenue: \$47.92 billion (-4.7\% decline due to restructuring)
+\item 2026 Revenue Projection: \$49.0 billion (+2.3\%)
+\item R\&D Investment (2024): \$6.5 billion (13.6\% of revenue)
+\item Excluding consumer health: Pharmaceuticals +9\% growth
+\end{itemize}
+
+\textbf{Key Products:}
+\begin{itemize}
+\item Dupixent (immunology): \$13.07 billion (+25\% growth)
+\item Aubagio (multiple sclerosis): \$2.4 billion
+\item Lantus (diabetes): \$1.8 billion
+\item Fluzone (influenza vaccine): \$2.1 billion
+\end{itemize}
+
+\textbf{Strategic Transition:}
+Dupixent expansion into COPD, pediatric allergic rhinitis, and prurigo nodularis drives growth. Consumer health spin-off allows pharmaceutical focus. Oncology pipeline rebuilding with recent acquisitions.
+
+\subsubsection{10. Eli Lilly}
+
+\textbf{Company Overview:}
+Eli Lilly demonstrates industry-leading growth driven by GLP-1 franchise. Company projects 32\% growth for 2025, highest among Big Pharma companies.
+
+\textbf{Financial Performance:}
+\begin{itemize}
+\item 2024 Revenue: \$45.04 billion (+32\% growth)
+\item 2026 Revenue Projection: \$59.0 billion (+31\% CAGR)
+\item R\&D Investment (2024): \$9.3 billion (20.6\% of revenue)
+\item Market Capitalization: \$650+ billion (January 2026, highest among pharma)
+\end{itemize}
+
+\textbf{Key Products:}
+\begin{itemize}
+\item Mounjaro (diabetes): \$9.2 billion
+\item Zepbound (obesity): \$7.3 billion
+\item Verzenio (oncology): \$3.8 billion
+\item Taltz (immunology): \$2.5 billion
+\end{itemize}
+
+\textbf{Growth Engine:}
+GLP-1 franchise (Mounjaro/Zepbound) drives growth with expansion obesity market. Alzheimer's drug donanemab approval expected 2025 represents additional upside. Oncology pipeline with Verzenio expansion provides diversification.
+
+\newpage
+
+\section{Pipeline Analysis}
+
+\subsection{Therapeutic Area Pipeline Breakdown}
+
+Pharmaceutical companies increasingly concentrate R\&D investment in high-growth therapeutic areas. Figure 3 presents pipeline analysis by therapeutic area showing Phase 2-3 candidates.
+
+\begin{figure}[H]
+ \centering
+ \includegraphics[width=0.9\textwidth]{pipeline_analysis_heatmap.png}
+ \caption{Pipeline Analysis by Therapeutic Area (Phase 2-3 Candidates)}
+ \label{fig:pipeline}
+\end{figure}
+
+\textbf{Key Pipeline Insights:}
+
+\begin{itemize}
+\item \textbf{Oncology:} All top 10 companies maintain significant oncology pipelines, representing the most crowded therapeutic area. Merck, Roche, and AstraZeneca lead with 10+ Phase 2-3 candidates each. PD-1/PD-L1 inhibitors, ADCs, and bispecific antibodies dominate development.
+
+\item \textbf{Immunology:} AbbVie, J\&J, and Pfizer maintain strong immunology pipelines. IL-23, IL-17, and JAK inhibitors continue evolution. Novel approaches including BTK inhibition complement established TNF inhibitors.
+
+\item \textbf{Metabolic Disease:} Eli Lilly and Novo Nordisk dominate GLP-1 development, but other companies including AstraZeneca and Sanofi pursue next-generation metabolic therapies including dual/triple agonists.
+
+\item \textbf{Neuroscience:} J\&J demonstrates particular strength with significant Alzheimer's disease pipeline. Other companies focus on neurodegenerative diseases and pain management.
+
+\item \textbf{Rare Disease:} AstraZeneca, Novartis, and Sanofi maintain substantial rare disease portfolios, benefiting from orphan drug incentives and premium pricing.
+
+\end{itemize}
+
+\subsection{Emerging Therapeutic Modalities}
+
+\textbf{Antibody-Drug Conjugates (ADCs):}
+ADC represents fastest-growing oncology modality with 12+ approved drugs and 100+ in development. Merck's acquisition of Daiichi Sankyo collaboration (enhertu) validates approach. Technology evolution includes linkers with improved stability and novel payloads.
+
+\textbf{Bispecific Antibodies:}
+Over 50 bispecific antibodies in late-stage development, targeting tumor immunity and hematology. Roche, J\&J, and Pfizer maintain strong bispecific portfolios. CD20xCD3, PD-1xCTLA-4, and HER2xHER3 combinations show particular promise.
+
+\textbf{Cell and Gene Therapies:}
+CAR-T cell therapies expanding beyond hematologic malignancies into solid tumors. Gene therapy approach validated by commercial success of Zolgensma, Hemgenix, and Skysona. Manufacturing improvements and next-generation vectors expanding treatable patient populations.
+
+\textbf{mRNA Therapeutics:}
+Beyond COVID-19 vaccines, mRNA platform expanding into oncology, protein replacement, and rare disease. Moderna, BioNTech, and Sanofi advancing programs with accelerated development timelines.
+
+\subsection{Clinical Development Trends}
+
+\textbf{Platform Trials:}
+Adaptive platform trial designs increasing, particularly in oncology. Master protocols enable multiple simultaneous treatment evaluations, reducing development timelines and costs.
+
+\textbf{Real-World Evidence:}
+RWE integration complementing traditional clinical trials. Pragmatic trial designs and post-approval evidence generation accelerating regulatory submissions and label expansions.
+
+\textbf{Biomarker-Driven Development:}
+Companion diagnostic requirement increasing across therapeutic areas. Precision medicine approaches improving trial success rates 2-3x in biomarker-selected populations.
+
+\textbf{Diversified Trial Locations:}
+Geographic trial diversification expanding beyond traditional locations. China, India, and emerging markets accelerating patient recruitment while meeting regulatory requirements.
+
+\newpage
+
+\section{Patent Cliff Analysis}
+
+\subsection{Revenue Exposure Timeline}
+
+The pharmaceutical industry faces significant patent expiration risk through 2030, with over \$90 billion in revenue affected. Figure 4 presents patent cliff analysis by year.
+
+\begin{figure}[H]
+ \centering
+ \includegraphics[width=0.9\textwidth]{patent_cliff_analysis.png}
+ \caption{Pharmaceutical Patent Cliff: Revenue Exposure 2025-2030}
+ \label{fig:patent}
+\end{figure}
+
+\subsection{Key Patent Expirations by Year}
+
+\subsubsection{2025: \$15.2 Billion at Risk}
+
+\textbf{Major Expirations:}
+\begin{itemize}
+\item Stelara (J\&J): \$5.5 billion - Biosimilar competition beginning 2025
+\item Additional AbbVie immunology patents
+\item Various smaller molecules
+\end{itemize}
+
+\textbf{Impact Analysis:}
+J\&J faces \$2 billion impact from Stelara biosimilars. However, company prepared through strategic pricing and physician/patient programs. AbbVie's ongoing Humira biosimilar transition provides model for managing competition.
+
+\subsubsection{2026: \$18.5 Billion at Risk (Peak Year)}
+
+\textbf{Major Expirations:}
+\begin{itemize}
+\item Eliquis (BMS/Pfizer): \$13.3 billion - Patent expiration November 2026
+\item Entresto (Novartis): \$4.8 billion - Patent expiration 2026
+\item Additional cardiovascular agents
+\end{itemize}
+
+\textbf{Impact Analysis:}
+BMS faces most significant single-drug patent loss with Eliquis expiration. Company expects \$1-2 billion revenue impact in 2027. Pfizer also affected (Eliquis co-marketing). Novartis prepared through cardiovascular franchise diversification.
+
+\subsubsection{2027: \$12.8 Billion at Risk}
+
+\textbf{Major Expirations:}
+\begin{itemize}
+\item Ocrevus (Roche): \$7.5 billion - Initial patent cliff
+\item Xarelto (Bayer/J\&J): \$3.5 billion
+\item Additional oncology agents
+\end{itemize}
+
+\textbf{Impact Analysis:}
+Roche's Ocrevus creates MS franchise vulnerability. However, extensive neurology pipeline provides offset. Hemophilia franchise (Hemlibra) demonstrates strong patent protection until 2031.
+
+\subsubsection{2028: \$21.3 Billion at Risk (Most Significant Year)}
+
+\textbf{Major Expirations:}
+\begin{itemize}
+\item Keytruda (Merck): \$29.5 billion - Patent expiration 2028
+\item Immunotherapy biosimilars
+\item Additional major oncology agents
+\end{itemize}
+
+\textbf{Impact Analysis:}
+Merck's Keytruda expiration represents industry's most significant patent event. However, company prepared through:
+\begin{itemize}
+\item Subcutaneous Keytruda Qlex approval (new formulation)
+\item Extensive combination therapy development
+\item New indication expansion
+\item Strong oncology pipeline (40+ Phase 3 candidates)
+\end{itemize}
+
+Expected biosimilars delayed due to manufacturing complexity.
+
+\subsubsection{2029-2030: \$23.7 Billion Combined}
+
+\textbf{Major Expirations:}
+\begin{itemize}
+\item Enbrel, Orencia (BMS): Immunology franchise impact
+\item Tecentriq, Hemlibra (Roche): Oncology and hematology
+\item Multiple smaller brands across portfolio
+\end{itemize}
+
+\textbf{Impact Analysis:}
+Ongoing patent cliff extends through 2030. Companies with strong late-stage pipelines best positioned to offset losses. Roche's bispecific and ADC pipeline provides growth beyond patent expirations.
+
+\subsection{Patent Lifecycle Management Strategies}
+
+Leading companies employ multiple strategies to mitigate patent cliff impact:
+
+\textbf{New Formulations:}
+\begin{itemize}
+\item Subcutaneous administration (Keytruda Qlex, Ocrevus SC)
+\item Extended-release formulations
+\item Fixed-dose combinations
+\end{itemize}
+
+\textbf{New Indications:}
+\begin{itemize}
+\item Expansion into earlier disease stages
+\item New disease applications (oncology indications expansion)
+\item Pediatric exclusivity extensions
+\end{itemize}
+
+\textbf{Strategic Pricing:}
+\begin{itemize}
+\item Pre-biosimilar price adjustments
+\item Value-based contracting
+\item Patient access programs
+\end{itemize}
+
+\textbf{Portfolio Diversification:}
+\begin{itemize}
+\item New therapeutic area expansion
+\item Modality diversification (small molecules vs. biologics)
+\item Geographic market expansion
+\end{itemize}
+
+\newpage
+
+\section{Investment Implications}
+
+\subsection{Growth vs. R\&D Intensity Analysis}
+
+Figure 6 presents investment implications analyzing projected revenue growth versus R\&D investment intensity.
+
+\begin{figure}[H]
+ \centering
+ \includegraphics[width=0.9\textwidth]{investment_implications.png}
+ \caption{Investment Implications: Growth vs. R\&D Intensity}
+ \label{fig:investment}
+\end{figure}
+
+\subsection{Investment Quadrant Analysis}
+
+\subsubsection{High Growth / High R\&D Intensity (Optimal Zone)}
+\begin{itemize}
+\item \textbf{Eli Lilly (+31\% growth, 20.6\% R\&D):} Industry growth leader validated by GLP-1 franchise breadth. Continued expansion into obesity, cardiovascular disease, and Alzheimer's provides multi-year trajectory. Recommendation: Strong Buy
+
+\item \textbf{AstraZeneca (+9.1\% growth, 20.4\% R\&D):} Sustainable oncology and metabolic growth. \$80 billion revenue target by 2030 realistic given pipeline depth. Recommendation: Buy
+
+\item \textbf{Novartis (+6.4\% growth, 18.2\% R\&D):} Successfully executed Sandoz spin-off. Entresto expansion and oncology portfolio drive growth. Recommendation: Buy
+\end{itemize}
+
+\subsubsection{Moderate Growth / High R\&D Intensity (Strategic Investment)}
+\begin{itemize}
+\item \textbf{Johnson \& Johnson (+4.3\% growth, 30.2\% R\&D):} Highest R\&D intensity supports long-term leadership position. Stelara biosimilars create near-term headwind but pipeline strength provides offset. Recommendation: Hold
+
+\item \textbf{Roche (+5.0\% growth, 33.3\% R\&D):} Industry-leading R\&D investment ensures innovation leadership. Oncology and hematology dominance continues. Recommendation: Hold
+\end{itemize}
+
+\subsubsection{High Growth / Moderate R\&D (Efficient Growth)}
+\begin{itemize}
+\item \textbf{AbbVie (+6.5\% growth, 13.3\% R\&D):} Efficient transition from Humira validated. Skyrizi and Rinvoq growth trajectory continues. Recommendation: Buy
+
+\item \textbf{Merck (+5.0\% growth, 17.1\% R\&D):} Keytruda expansion continues through 2028. Vaccines and animal health provide diversification. Recommendation: Hold
+\end{itemize}
+
+\subsubsection{Moderate Decline / Patent Cliff Risk (High Risk)}
+\begin{itemize}
+\item \textbf{Bristol Myers Squibb (-2.7\% growth, 19.7\% R\&D):} Eliquis patent expiration in 2026 creates significant risk. Growth portfolio expansion provides partial offset. Recommendation: Hold/Accumulate at 20\% discount
+
+\item \textbf{Pfizer (+3.7\% growth, 17.0\% R\&D):} Post-COVID recovery continues. Seagen acquisition diversifies pipeline but integration risks remain. Recommendation: Hold
+
+\item \textbf{Sanofi (+2.3\% growth, 13.6\% R\&D):} Restructuring ongoing. Dupixent growth remains robust but pipeline depth limited. Recommendation: Hold/Avoid
+\end{itemize}
+
+\subsection{Therapeutic Area Investment Thesis}
+
+\textbf{Oncology: Attractive Long-Term Investment}
+\begin{itemize}
+\item Market size: \$110+ billion with 8.5\% growth
+\item Innovation cycle extended through ADCs, bispecifics, CAR-T
+\item Multiple winners across companies
+\item Recommendation: Maintain oncology exposure across 3+ leading companies
+\end{itemize}
+
+\textbf{Immunology: Steady Position Maintenance}
+\begin{itemize}
+\item Market size: \$75 billion with 6.2\% growth
+\item Established franchises with biosimilars creating headwinds
+\item Next-generation approaches (IL-23, BTK) providing growth
+\item Recommendation: Focus on companies with strong next-generation pipelines
+\end{itemize}
+
+\textbf{Metabolic Disease: Highest Growth Potential}
+\begin{itemize}
+\item Market size: \$66 billion with 12.3\% growth (highest)
+\item GLP-1 expansion into obesity, cardiovascular, NASH
+\item Limited winner-takes-all dynamic benefits leaders
+\item Recommendation: Overweight Lilly and Novo Nordisk exposure
+\end{itemize}
+
+\textbf{Cardiovascular: Selective Opportunities}
+\begin{itemize}
+\item Market size: \$52 billion with 4.8\% growth
+\item Patent cliff (Eliquis 2026) creates disruption
+\item Entresto expansion provides Novartis opportunity
+\item Recommendation: Selective exposure to Novartis and J\&J
+\end{itemize}
+
+\subsection{Market Timing Considerations}
+
+\textbf{Near-Term (2026):}
+\begin{itemize}
+\item BMS underperformance likely due to Eliquis patent expiration
+\item Lilly and Novo Nordisk should outperform given GLP-1 momentum
+\item AbbVie continues Humira transition success
+\end{itemize}
+
+\textbf{Medium-Term (2027-28):}
+\begin{itemize}
+\item Merck faces Keytruda headwinds in 2028 - consider profit-taking
+\item AstraZeneca pipeline maturity drives outperformance
+\item Gene therapy approvals create upside for select biotech companies
+\end{itemize}
+
+\textbf{Long-Term (2029-30):}
+\begin{itemize}
+\item Companies with platform technologies (ADCs, cell therapy) dominate
+\item Digital therapeutics integration creates competitive advantages
+\item Emerging markets revenue contribution increases to 40\%+
+\end{itemize}
+
+\subsection{Risk Factors}
+
+\textbf{Regulatory and Pricing Risks:}
+\begin{itemize}
+\item U.S. IRA (Inflation Reduction Act) negotiation provisions expand
+\item International reference pricing pressures increase
+\item Post-market safety events create franchise volatility
+\end{itemize}
+
+\textbf{Patent Litigation Risks:}
+\begin{itemize}
+\item Abbreviated new drug applications (ANDAs) accelerate entry
+\item Patent challenges from generic manufacturers increasing
+\item Inter partes review (IPR) proceedings create uncertainty
+\end{itemize}
+
+\textbf{Clinical Development Risks:}
+\begin{itemize}
+\item Late-stage clinical trial failures carry \$500M+ opportunity costs
+\item Regulatory approval delays impact commercial launches
+\item Biomarker-driven trials increase patient identification challenges
+\end{itemize}
+
+\textbf{Competition Risks:}
+\begin{itemize}
+\item Biosimilar competition expanding beyond established markets
+\item Cross-over drug competition within therapeutic areas
+\item Platform therapies enable faster entrant competitive responses
+\end{itemize}
+
+\subsection{Portfolio Recommendations}
+
+\textbf{Core Holdings (40-50\% allocation):}
+\begin{itemize}
+\item Eli Lilly (15-20\%): Growth leader with GLP-1 franchise breadth
+\item Johnson \& Johnson (12-15\%): Diversified portfolio with strong pipeline
+\item Roche (10-15\%): R\&D leadership ensures sustained innovation
+\end{itemize}
+
+\textbf{Growth Positions (30-35\% allocation):}
+\begin{itemize}
+\item AstraZeneca (12-15\%): Oncology and metabolic strength
+\item AbbVie (10-12\%): Immunology growth trajectory
+\item Novartis (8-10\%): Successful strategic transformation
+\end{itemize}
+
+\textbf{Special Situations (15-20\% allocation):}
+\begin{itemize}
+\item Bristol Myers Squibb (8-10\%): Value opportunity pre/post Eliquis patent
+\item Merck (7-10\%): Position through Keytruda patent cliff
+\item Pfizer (0-5\%): Small position monitoring Seagen integration
+\end{itemize}
+
+\subsection{ESG Considerations}
+
+\textbf{Environmental:}
+\begin{itemize}
+\item Carbon neutrality commitments accelerate manufacturing transformation
+\item Green chemistry initiatives reduce environmental impact
+\item Supply chain sustainability requirements increase
+\end{itemize}
+
+\textbf{Social:}
+\begin{itemize}
+\item Drug pricing transparency requirements expand
+\item Patient access programs become increasingly important
+\item Diversity in clinical trials gains regulatory emphasis
+\end{itemize}
+
+\textbf{Governance:}
+\begin{itemize}
+\item Executive compensation tied to R\&D and patient outcomes
+\item Patent practices under increased scrutiny
+\item Clinical trial data transparency expectations increase
+\end{itemize}
+
+\section{Conclusion and Outlook}
+
+The pharmaceutical industry outlook for 2026-2027 presents a complex landscape of significant opportunities and challenges. Companies successfully navigating the patent cliff while maintaining R\&D investment in innovative therapeutic areas will emerge as industry leaders.
+
+Four key strategic imperatives emerge for success:
+
+\textbf{1. Innovation Excellence:}
+Sustained R\&D investment above 20\% of revenue, particularly in oncology, cell and gene therapy, and metabolic disorders, positions companies for long-term growth. Platform technologies enabling multiple product candidates provide competitive advantages.
+
+\textbf{2. Product Lifecycle Management:}
+Effective patent lifecycle strategies including new formulations, indications, and strategic pricing mitigate patent cliff impacts. Companies demonstrating successful transitions (AbbVie's Humira management) validate approaches for other franchises.
+
+\textbf{3. Therapeutic Area Leadership:}
+Focused investment in high-growth areas (metabolic disease with 12.3\% growth, oncology with 8.5\% growth) while maintaining diversification balances growth and risk. Leading positions in 2-3 major therapeutic areas optimal.
+
+\textbf{4. Global Market Expansion:}
+Market diversification beyond U.S. and Europe into Asia-Pacific and emerging markets provides growth and regulatory arbitrage opportunities. Companies achieving 40\%+ international revenue demonstrate resilience.
+
+\subsection{2026-2027 Top Recommendations}
+
+\textbf{Top Picks:}
+\begin{enumerate}
+\item \textbf{Eli Lilly}: GLP-1 franchise breadth creates multi-year growth trajectory
+\item \textbf{AstraZeneca}: R\&D productivity and oncology strength validates \$80 billion target
+\item \textbf{Novartis}: Successful transformation to innovative medicines model
+\end{enumerate}
+
+\textbf{Attractive Values:}
+\begin{enumerate}
+\item \textbf{Bristol Myers Squibb}: Oversold on Eliquis patent concerns; growth portfolio undervalued
+\item \textbf{Johnson \& Johnson}: Highest R\&D intensity ensures long-term leadership
+\end{enumerate}
+
+\textbf{Avoid/Underweight:}
+\begin{enumerate}
+\item \textbf{Pfizer}: Integration risks and limited near-term catalysts
+\item \textbf{Sanofi}: Pipeline depth insufficient post-restructuring
+\end{enumerate}
+
+The pharmaceutical industry remains an attractive long-term investment given demographic trends, increasing healthcare access globally, and continued scientific innovation. Investors maintaining diversified exposure across 5-7 leaders with balanced therapeutic area focus will achieve attractive risk-adjusted returns through 2027 and beyond.
+
+\end{document}
diff --git a/assets/pharma_industry/pipeline_analysis_heatmap.png b/assets/pharma_industry/pipeline_analysis_heatmap.png
new file mode 100644
index 0000000..e2ba82b
Binary files /dev/null and b/assets/pharma_industry/pipeline_analysis_heatmap.png differ
diff --git a/assets/pharma_industry/rd_investment_analysis.png b/assets/pharma_industry/rd_investment_analysis.png
new file mode 100644
index 0000000..b4e3639
Binary files /dev/null and b/assets/pharma_industry/rd_investment_analysis.png differ
diff --git a/assets/pharma_industry/report_summary.json b/assets/pharma_industry/report_summary.json
new file mode 100644
index 0000000..969d268
--- /dev/null
+++ b/assets/pharma_industry/report_summary.json
@@ -0,0 +1,69 @@
+{
+ "Report_Metadata": {
+ "Title": "Pharmaceutical Industry Outlook 2026-2027",
+ "Report_Date": "January 2026",
+ "Total_Top_Companies_Analyzed": 10,
+ "Total_Visizations_Created": 6,
+ "Format": "LaTeX + CSV + PNG Images"
+ },
+ "Industry_Summary_2024_2026": {
+ "Global_Market_Size_2024_Billion_USD": 1645.75,
+ "Projected_Market_Size_2030_Billion_USD": 2350.43,
+ "CAGR_2025_2030_Percent": 6.12,
+ "Total_RD_Industry_2024_Billion_USD": 288,
+ "Total_Patent_Cliff_Exposure_2025_2030_Billion_USD": 91.5
+ },
+ "Top_10_Companies_Summary": {
+ "Total_Revenue_2024_Billion_USD": 529.36,
+ "Total_RD_2024_Billion_USD": 107.45,
+ "Average_RD_Intensity_Percent": 20.339999999999996
+ },
+ "Key_Trends": {
+ "Fastest_Growing_Therapeutic_Area": "Diabetes & Obesity",
+ "Therapeutic_Growth_Rate_Percent": 12.3,
+ "Largest_Therapeutic_Area": "Oncology",
+ "Largest_Area_Size_Billion_USD": 110.5,
+ "Highest_Growth_Company": "Eli Lilly",
+ "Highest_Growth_Rate_Percent": 31.0,
+ "Highest_RD_Intensity_Company": "Roche",
+ "Highest_RD_Intensity_Percent": 33.3
+ },
+ "Patent_Cliff_Summary": {
+ "2025_Revenue_at_Risk_Billion_USD": 15.2,
+ "2026_Revenue_at_Risk_Billion_USD": 18.5,
+ "2027_Revenue_at_Risk_Billion_USD": 12.8,
+ "2028_Revenue_at_Risk_Billion_USD": 21.3,
+ "Peak_Risk_Year": "2028",
+ "Most_Significant_Patent_Expiration": "Keytruda (Merck) 2028"
+ },
+ "Investment_Recommendations_Summary": {
+ "Strong_Buy": [
+ "Eli Lilly",
+ "AstraZeneca"
+ ],
+ "Buy": [
+ "AbbVie",
+ "Novartis"
+ ],
+ "Hold": [
+ "Johnson & Johnson",
+ "Roche",
+ "Merck & Co.",
+ "Pfizer",
+ "Sanofi"
+ ],
+ "Value_Or_Accumulate": [
+ "Bristol Myers Squibb"
+ ]
+ },
+ "Files_Created": [
+ "pharma_report_2026.tex",
+ "company_profiles.csv",
+ "revenue_comparison.png",
+ "rd_investment_analysis.png",
+ "pipeline_analysis_heatmap.png",
+ "patent_cliff_analysis.png",
+ "therapeutic_market_analysis.png",
+ "investment_implications.png"
+ ]
+}
\ No newline at end of file
diff --git a/assets/pharma_industry/revenue_comparison.png b/assets/pharma_industry/revenue_comparison.png
new file mode 100644
index 0000000..6febb9e
Binary files /dev/null and b/assets/pharma_industry/revenue_comparison.png differ
diff --git a/assets/pharma_industry/therapeutic_market_analysis.png b/assets/pharma_industry/therapeutic_market_analysis.png
new file mode 100644
index 0000000..1d25fe7
Binary files /dev/null and b/assets/pharma_industry/therapeutic_market_analysis.png differ
diff --git a/assets/ranking_performance_2024.png b/assets/ranking_performance_2024.png
new file mode 100644
index 0000000..85d023e
Binary files /dev/null and b/assets/ranking_performance_2024.png differ
diff --git a/assets/real_estate/Global_Property_Market_Analysis_2026.tex b/assets/real_estate/Global_Property_Market_Analysis_2026.tex
new file mode 100644
index 0000000..75c2710
--- /dev/null
+++ b/assets/real_estate/Global_Property_Market_Analysis_2026.tex
@@ -0,0 +1,1026 @@
+\documentclass[12pt,a4paper]{article}
+\usepackage[utf8]{inputenc}
+\usepackage{geometry}
+\usepackage{graphicx}
+\usepackage{booktabs}
+\usepackage{hyperref}
+\usepackage{tikz}
+\usepackage{pgfplots}
+\usepackage{float}
+\usepackage{caption}
+\usepackage{xcolor}
+
+\pgfplotsset{compat=1.17}
+\geometry{margin=1in}
+
+\title{\textbf{Global Property Market Analysis 2026}\\ \large Top 10 Most Expensive Real Estate Markets}
+\author{Real Estate Intelligence Division}
+\date{January 2026}
+
+\begin{document}
+
+\maketitle
+\tableofcontents
+\newpage
+
+%=============================================================================
+% SECTION 1: EXECUTIVE SUMMARY
+%=============================================================================
+\section{Executive Summary}
+
+The global real estate landscape in 2026 presents a complex picture of resilience, recovery, and continued premiumization in the world's most expensive markets. This comprehensive analysis of the top 10 most expensive real estate markets reveals key trends shaping the future of global property investment.
+
+\subsection{Key Findings}
+
+\begin{itemize}
+ \item \textbf{Monaco} maintains its position as the world's most expensive real estate market, with prices exceeding \$35,000 per square meter.
+ \item \textbf{Hong Kong} retains the title of most unaffordable market globally for the 14th consecutive year, with a price-to-income ratio exceeding 18.
+ \item \textbf{Miami} has emerged as the fastest-growing premium market in 2024-2026, with price increases of nearly 50\% since 2019 in real terms.
+ \item \textbf{Singapore} demonstrates remarkable stability, with median condo prices reaching \$1.78 million in 2024.
+ \item \textbf{Luxury sector resilience} continues to outperform traditional real estate segments across all major markets.
+ \item \textbf{Affordability crisis} deepens in global hubs, with price-to-income ratios reaching historic highs across the top 10 markets.
+\end{itemize}
+
+\subsection{Market Outlook}
+
+The luxury real estate market is positioned for steady growth in 2026, with entry points starting around \$1.3 million nationally in the UnitedStates and significantly higher in global hubs. Wealth migration, branded residences, and privacy-focused developments are driving demand. Analysts project continued recovery and increased activity in global property markets as borrowing rates stabilize and international travel rebounds.
+
+\subsection{Investment Implications}
+
+Investors should consider both traditional metrics (cap rates, rental yields) and emerging factors (wealth migration patterns, climate risk, tax implications). The divergence between prime and non-prime segments continues to widen, creating opportunities for selective investment.
+
+\newpage
+
+%=============================================================================
+% SECTION 2: GLOBAL MARKET OVERVIEW
+%=============================================================================
+\section{Global Market Overview}
+
+\subsection{Total Market Value and Trends}
+
+By the end of 2024, the total value of the world's residential real estate stood at \$286.9 trillion, representing a slight annual decline of 2.7\% in US dollar terms. Despite this moderate contraction, global residential value remains 19\% higher than in 2019, reflecting the robust post-pandemic surge in housing markets.
+
+\subsubsection{Regional Performance}
+
+ \begin{itemize}
+ \item \textbf{Asia-Pacific:} China accounts for approximately 25\% of global residential value but experienced a 5.2\% decline in 2024 (8\% in USD terms) due to falling prices and construction slowdowns.
+ \item \textbf{North America:} The United States saw modest price appreciation in 2024, with national median home prices growing 6.3\% to \$427,670. Canada continued to face significant affordability challenges.
+ \item \textbf{Europe:} Mixed performance with London prime prices stabilizing after declines, while Swiss markets showed modest growth (apartments +2\%, single-family homes +1.2\%).
+ \item \textbf{Middle East:} Dubai experienced the highest rental yield increase among major global cities, reaching 5.3\% gross yield.
+\end{itemize}
+
+\subsection{Global Housing Affordability Crisis}
+
+The 2024 Demographia International Housing Affordability Report reveals an escalating crisis in major urban centers:
+
+\begin{itemize}
+ \item \textbf{Severely Unaffordable:} Markets where home prices are 5.1+ times median household income
+ \item \textbf{Impossibly Unaffordable:} Markets where home prices are 9.0+ times median household income
+\end{itemize}
+
+Hong Kong, Vancouver, and Los Angeles continue to top the list of most unaffordable markets with ratios exceeding 10,meaning the average home costs more than 10 times the average household's annual income.
+
+\subsection{Rental Yield Dynamics}
+
+Global rental yields varied significantly in 2024:
+\begin{itemize}
+ \item \textbf{High Yield Markets:} Dublin (6.1\%), Warsaw (5.7\%), Lisbon (5.4\%)
+ \item \textbf{Moderate Yield Markets:} Dubai (5.3\%), London (5.0\%), Bangkok (5.0\%)
+ \item \textbf{Low Yield Markets:} Hong Kong (3.9\%), Singapore (3.0\%), Tokyo (4.0\%)
+\end{itemize}
+
+\subsection{Emerging Trends for 2026}
+
+\begin{enumerate}
+ \item \textbf{Wealth Migration:} High net worth individuals continue to relocate from high-tax jurisdictions to more favorable environments, driving demand in destination markets like Dubai, Miami, and Singapore.
+ \item \textbf{Branded Residences:} Integration of luxury brands with property development, offering premium amenities and services.
+ \item \textbf{Privacy Focus:} Increased demand for exclusive, private properties in secure locations.
+ \item \textbf{Sustainable Development:} Growing emphasis on green building standards and energy efficiency.
+ \item \textbf{Digital Integration:} Smart home technologies and digital transaction platforms.
+\end{enumerate}
+
+\newpage
+
+%=============================================================================
+% SECTION 3: CITY-BY-CITY ANALYSIS
+%=============================================================================
+\section{City-by-City Analysis}
+
+\subsection{1. Monaco - Monaco}
+
+\textbf{Market Position:} World's most expensive real estate market
+
+\textbf{Key Statistics (2024-2026):}
+\begin{itemize}
+ \item \textbf{Median Price:} \$35,000 - \$52,000 per square meter
+ \item \textbf{Price per sq ft:} Exceeding \$5,000
+ \item \textbf{Rental Yield:} N/A (limited rental market, primarily ownership)
+ \item \textbf{YoY Change:} Stable with minor appreciation
+ \item \textbf{Price-to-Income Ratio:} Highest globally, exceeding 25:1
+\end{itemize}
+
+\textbf{Market Characteristics:}
+Monaco maintains its position as the ultimate luxury real estate destination, driven by:
+\begin{itemize}
+ \item Tax haven status with no personal income tax
+ \item Ultra-high net worth population density
+ \item Geographic constraints and limited land availability
+ \item Political stability and security
+ \item Exclusive location on the French Riviera
+\end{itemize}
+
+\textbf{Investment Considerations:}
+Exceptional wealth preservation characteristics but extremely high entry barriers. Market primarily serves as a safe haven for ultra-high net worth individuals.
+
+\subsubsection{Monaco}
+
+%=============================================================================
+\subsection{2. New York City - United States}
+
+\textbf{Market Position:} Top North American luxury market, second globally
+
+\textbf{Key Statistics (2024-2026):}
+\begin{itemize}
+ \item \textbf{Median Price (Manhattan):} \$1,340,000
+ \item \textbf{Price Change (2024):} -0.4\% (slight decline)
+ \item \textbf{Rental Yield:} 3.0-4.0\% (varying by borough)
+ \item \textbf{YoY Change:} Mixed, Manhattan down, outer boroughs up
+ \item \textbf{Price-to-Income Ratio:} 12-15:1
+\end{itemize}
+
+\textbf{Market Characteristics:}
+New York City continues to lead the US luxury market:
+\begin{itemize}
+ \item Global financial center status
+ \item Cultural capital with world-class amenities
+ \item Strong international buyer demand
+ \item Q4 2024 showed lowest fourth-quarter median at \$1.1M
+ \item Outer boroughs experiencing stronger growth
+\end{itemize}
+
+\textbf{Market Trends:}
+The luxury sector outperformed traditional segments in 2024-2025, with international buyers returning post-pandemic. Privacy-focused properties in secure buildings commanding premiums.
+
+\textbf{Investment Considerations:}
+Historically strong long-term appreciation despite short-term fluctuations. Diverse market offering entry points across price points and neighborhoods.
+
+%=============================================================================
+\subsection{3. Hong Kong - Hong Kong SAR}
+
+\textbf{Market Position:} Asia's most expensive property market, most unaffordable globally
+
+\textbf{Key Statistics (2024-2026):}
+\begin{itemize}
+ \item \textbf{Price per sq meter:} \$26,300 average
+ \item \textbf{Price per sq ft:} HK\$13,755 (US\$1,800)
+ \item \textbf{Rental Yield:} 3.9\%
+ \item \textbf{YoY Change (2024):} -9.63\% (October), slight recovery to +1.13\% in October 2025
+ \item \textbf{Price-to-Income Ratio:} 18-20:1 (world's highest)
+\end{itemize}
+
+\textbf{Market Characteristics:}
+Hong Kong faces unique challenges:
+\begin{itemize}
+ \item Limited land supply and geographic constraints
+ \item Political uncertainties affecting foreign investment
+ \item Most unaffordable market for 14 consecutive years
+ \item Recent price declines improving theoretical affordability
+ \item Strong rental demand supporting yields
+\end{itemize}
+
+\textbf{Market Trends:}
+The market experienced significant corrections in 2024 but shows early signs of stabilization. The 2025 UBS index shows Hong Kong with low bubble risk compared to previous years.
+
+\textbf{Investment Considerations:}
+High risk profile currently with potential for appreciation if political stability improves. Strong rental market provides income support.
+
+%=============================================================================
+\subsection{4. Singapore - Singapore}
+
+\textbf{Market Position:} Southeast Asia's premier market, top 5 globally
+
+\textbf{Key Statistics (2024-2026):}
+\begin{itemize}
+ \item \textbf{Median Condo Price:} \$1,780,000 SGD (US\$1,320,000)
+ \item \textbf{Non-landed Price Growth (2024):} +4.7\%
+ \item \textbf{Rental Yield:} 3.0\%
+ \item \textbf{Housing Index (Q1 2025):} 210.70 points
+ \item \textbf{Price-to-Income Ratio:} 12-14:1
+\end{itemize}
+
+\textbf{Market Characteristics:}
+Singapore demonstrates remarkable market stability:
+\begin{itemize}
+ \item Political stability and strong governance
+ \item Wealth magnet for regional HNWIs
+ \item Urban planning excellence
+ \item Foreign buyer restrictions affecting demand
+ \item 2024 saw 19,650 total property transactions
+\end{itemize}
+
+\textbf{Market Trends:}
+Moderating price growth from previous years due to cooling measures. Continued strong demand from regional buyers seeking stability and safety.
+
+\textbf{Investment Considerations:}
+Lower yields but strong capital preservation characteristics. Cooling measures may create opportunities for patient investors.
+
+%=============================================================================
+\subsection{5. London - United Kingdom}
+
+\textbf{Market Position:} Europe's leading luxury market
+
+\textbf{Key Statistics (2024-2026):}
+\begin{itemize}
+ \item \textbf{Prime Property Change (2024):} -2.9\% annual decline
+ \item \textbf{Price from Peak:} -20.7\% since 2014 peak
+ \item \textbf{Rental Yield:} 5.0\%
+ \item \textbf{YoY Change (Q4 2024):} Stable (no quarterly change)
+ \item \textbf{Price-to-Income Ratio:} 14-16:1
+\end{itemize}
+
+\textbf{Market Characteristics:}
+London's market shows divergence by segment:
+\begin{itemize}
+ \item Prime central London prices significantly below 2014 peak
+ \item 5 million-plus home sales jumped 25\% in late 2024
+ \item SW6 (Fulham) and SW3 (Chelsea) leading 2m+ transactions
+ \item Economic headwinds affecting broader market
+ \item International buyer confidence returning post-Brexit
+\end{itemize}
+
+\textbf{Market Trends:}
+Despite economic challenges, serious buyers remain active in the luxury segment. High-value transactions resilient despite overall market moderation.
+
+\textbf{Investment Considerations:}
+Premium prices well below peak levels present opportunities. Strong rental yields provide income support during market recovery.
+
+%=============================================================================
+\subsection{6. Tokyo - Japan}
+
+\textbf{Market Position:} Asia's diversified premium market
+
+\textbf{Key Statistics (2024-2026):}
+\begin{itemize}
+ \item \textbf{Central Tokyo Price:} Exceeding 100 million (US\$670,000)
+ \item \textbf{Average House Price (Tokyo):} 50 million (US\$335,000)
+ \item \textbf{Rental Yield:} 4.0-4.34\%
+ \item \textbf{YoY Change:} Continued appreciation in central wards
+ \item \textbf{Price-to-Income Ratio:} 10-12:1
+\end{itemize}
+
+\textbf{Market Characteristics:}
+Tokyo offers diversity in the luxury segment:
+\begin{itemize}
+ \item Chiyoda, Minato, and Chuo wards seeing strongest gains
+ \item Named world's top investment market in 2024 by DWS
+ \item \$1 million buys 64 sqm prime property
+ \item Potential interest rate impacts on 2025 liquidity
+ \item Stable long-term appreciation patterns
+\end{itemize}
+
+\textbf{Market Trends:}
+Central Tokyo showing sustained appreciation while outer areas remain more stable. Investment demand supporting price growth in premium locations.
+
+\textbf{Investment Considerations:}
+Strong relative affordability with growing international interest. Higher yields than other Asian markets provide favorable return profiles.
+
+%=============================================================================
+\subsection{7. Zurich - Switzerland}
+
+\textbf{Market Position:} Continental Europe's stable premium market
+
+\textbf{Key Statistics (2024-2026):}
+\begin{itemize}
+ \item \textbf{Apartment Price Growth:} +2.0\% YoY
+ \item \textbf{Single-Family Growth:} +1.2\% YoY
+ \item \textbf{Rental Yield:} 3.35\%
+ \item \textbf{YoY Change:} Moderate growth continuing
+ \item \textbf{Price-to-Income Ratio:} 12-14:1
+\end{itemize}
+
+\textbf{Market Characteristics:}
+Swiss markets demonstrate exceptional stability:
+\begin{itemize}
+ \item Safe haven status attracting international capital
+ \item Conservative but positive price appreciation
+ \item Immigration driving urban housing demand
+ \item Quality-driven market with limited supply
+ \item Zurich leading Swiss market activity
+\end{itemize}
+
+\textbf{Market Trends:}
+Modest but steady growth characterizes the Swiss market. Low interest rates and immigration supporting continued demand.
+
+\textbf{Investment Considerations:}
+Low-risk profile with stable appreciation. Lower yields offset by exceptional capital preservation characteristics.
+
+%=============================================================================
+\subsection{8. Sydney - Australia}
+
+\textbf{Market Position:} Oceania's leading premium market
+
+\textbf{Key Statistics (2024-2026):}
+\begin{itemize}
+ \item \textbf{Median House Price:} AU\$1,600,000 (US\$1,070,000)
+ \item \textbf{Annual Change (2024):} +4.5\%
+ \item \textbf{Rental Yield:} 4.92\%
+ \item \textbf{YoY Change:} Record highs achieved in 2024
+ \item \textbf{Price-to-Income Ratio:} 13-15:1
+\end{itemize}
+
+\textbf{Market Characteristics:}
+Sydney market reaching record levels:
+\begin{itemize}
+ \item First time house prices surpassed AU\$1.6 million
+ \item Strong domestic demand supporting prices
+ \item Immigration boosting population growth
+ \item Limited supply in premium locations
+ \item Second most unaffordable market in Demographia report
+\end{itemize}
+
+\textbf{Market Trends:}
+Despite momentum loss in quarterly data, annual records continue to fall. Strong fundamentals supporting continued price growth.
+
+\textbf{Investment Considerations:}
+Strong rental yields and consistent growth track record. Higher yields than most premium markets provide income support.
+
+%=============================================================================
+\subsection{9. Paris - France}
+
+\textbf{Market Position:} Continental Europe's cultural capital
+
+\textbf{Key Statistics (2024-2026):}
+\begin{itemize}
+ \item \textbf{Price per sq meter:} Approximately 10,000 (declining from peak)
+ \item \textbf{Price Decline since 2020:} -8.6\%
+ \item \textbf{Rental Yield:} 4.84\%
+ \item \textbf{YoY Change:} Stable, gradual recovery anticipated
+ \item \textbf{Price-to-Income Ratio:} 11-13:1
+\end{itemize}
+
+\textbf{Market Characteristics:}
+Paris market experiencing correction and stabilization:
+\begin{itemize}
+ \item Prices expected to fall below 10,000/m
+ \item 8th arrondissement remains most expensive
+ \item High-end segment maintaining value better
+ \item Borrowing rates settling below 4\% in late 2024
+ \item Recovery anticipated in 2025-2026
+\end{itemize}
+
+\textbf{Market Trends:}
+Notable downturn following high-price years of 2020-2022. Market showing signs of stabilization with potential for gradual recovery.
+
+\textbf{Investment Considerations:}
+Correction from peak levels creating selective opportunities. Cultural significance and lifestyle appeal supporting long-term values.
+
+%=============================================================================
+\subsection{10. Miami - United States}
+
+\textbf{Market Position:} Fastest-growing premium market in the Americas
+
+\textbf{Key Statistics (2024-2026):}
+\begin{itemize}
+ \item \textbf{Median Home Price (2024):} \$570,000
+ \item \item \textbf{YoY Growth (2024):} +11.8\%
+ \item \textbf{Growth since 2019:} +161\% (nominal)
+ \item \textbf{Real Terms since 2019:} +50\%
+ \item \textbf{Price-to-Income Ratio:} 10-12:1
+\end{itemize}
+
+\textbf{Market Characteristics:}
+Miami's explosive growth trajectory:
+\begin{itemize}
+ \item Top of UBS Global Real Estate Bubble Index for highest bubble risk
+ \item Wealth migration from high-tax states (NY, CA, IL)
+ \item International buyer demand from Latin America
+ \item Luxury market driving overall price increases
+ \item Neighborhood growth ranging 3-12\% in 2024
+\end{itemize}
+
+\textbf{Market Trends:}
+Miami ranked No. 1 globally for housing bubble risk in 2024-2025. Extreme price growth raising concerns about sustainability.
+
+\textbf{Investment Considerations:}
+High growth trajectory but elevated risk profile. Careful due diligence essential at current valuation levels.
+
+\newpage
+
+%=============================================================================
+% SECTION 4: AFFORDABILITY ANALYSIS
+%=============================================================================
+\section{Affordability Analysis with Charts}
+
+\subsection{Price-to-Income Ratio Overview}
+
+The price-to-income ratio (median multiple) is calculated by dividing median house price by median household income. This metric reveals the extreme affordability challenges facing buyers in premium global markets.
+
+\textbf{Demographia Affordability Ratings:}
+\begin{itemize}
+ \item \textbf{Affordable:} 3.0 and under
+ \item \textbf{Moderately Unaffordable:} 3.1 to 4.0
+ \item \textbf{Seriously Unaffordable:} 4.1 to 5.0
+ \item \textbf{Severely Unaffordable:} 5.1 to 8.9
+ \item \textbf{Impossibly Unaffordable:} 9.0 and over
+\end{itemize}
+
+All top 10 markets fall into the "Impossibly Unaffordable" category, meaning home prices exceed 9 times median household income.
+
+% Chart 1: Price-to-Income Ratios
+\begin{figure}[H]
+\centering
+\begin{tikzpicture}
+\begin{axis}[
+ ybar,
+ width=0.9\textwidth,
+ height=8cm,
+ symbolic x coords={Hong Kong, Monaco, New York, London, Sydney, Singapore, Paris, Tokyo, Zurich, Miami},
+ xtick=data,
+ nodes near coords,
+ nodes near coords align={vertical},
+ ymin=0, ymax=22,
+ ylabel={Price-to-Income Ratio},
+ xlabel={City},
+ title={Figure 1: Price-to-Income Ratios - Top 10 Markets (2024)},
+ xticklabel style={rotate=45, anchor=east, font=\tiny},
+ ymajorgrids=true,
+ grid style=dashed,
+]
+\addplot[fill=blue!60] coordinates {
+ (Hong Kong, 19.5)
+ (Monaco, 25.0)
+ (New York, 14.0)
+ (London, 15.0)
+ (Sydney, 14.5)
+ (Singapore, 13.5)
+ (Paris, 12.5)
+ (Tokyo, 11.5)
+ (Zurich, 13.0)
+ (Miami, 11.0)
+};
+\end{axis}
+\end{tikzpicture}
+\end{figure}
+
+% Chart 2: Median Home Prices
+\begin{figure}[H]
+\centering
+\begin{tikzpicture}
+\begin{axis}[
+ ybar,
+ width=0.9\textwidth,
+ height=8cm,
+ symbolic x coords={Monaco, New York, Singapore, Hong Kong, London, Sydney, Paris, Tokyo, Miami, Zurich},
+ xtick=data,
+ nodes near coords,
+ nodes near coords style={/pgf/number format/fixed, /pgf/number format/precision=0},
+ ymin=0, ymax=6000000,
+ ylabel={Price in Millions USD},
+ xlabel={City},
+ title={Figure 2: Median Home Prices in USD - Top 10 Markets (2024)},
+ xticklabel style={rotate=45, anchor=east, font=\tiny},
+ ymajorgrids=true,
+ grid style=dashed,
+]
+\addplot[fill=green!60] coordinates {
+ (Monaco, 5200000)
+ (New York, 1340000)
+ (Singapore, 1320000)
+ (Hong Kong, 1200000)
+ (London, 1100000)
+ (Sydney, 1070000)
+ (Paris, 1050000)
+ (Tokyo, 670000)
+ (Miami, 570000)
+ (Zurich, 1500000)
+};
+\end{axis}
+\end{tikzpicture}
+\end{figure}
+
+% Chart 3: Rental Yields
+\begin{figure}[H]
+\centering
+\begin{tikzpicture}
+\begin{axis}[
+ ybar,
+ width=0.9\textwidth,
+ height=8cm,
+ symbolic x coords={London, Sydney, Tokyo, Hong Kong, Paris, New York, Zurich, Miami, Monaco, Singapore},
+ xtick=data,
+ nodes near coords,
+ nodes near coords style={/pgf/number format/fixed, /pgf/number format/precision=1},
+ nodes near coords align={vertical},
+ ymin=0, ymax=6,
+ ylabel={Rental Yield (\%)},
+ xlabel={City},
+ title={Figure 3: Gross Rental Yields - Top 10 Markets (2024)},
+ xticklabel style={rotate=45, anchor=east, font=\tiny},
+ ymajorgrids=true,
+ grid style=dashed,
+]
+\addplot[fill=orange!60] coordinates {
+ (London, 5.0)
+ (Sydney, 4.9)
+ (Tokyo, 4.0)
+ (Hong Kong, 3.9)
+ (Paris, 4.8)
+ (New York, 3.5)
+ (Zurich, 3.4)
+ (Miami, 4.2)
+ (Monaco, 2.0)
+ (Singapore, 3.0)
+};
+\end{axis}
+\end{tikzpicture}
+\end{figure}
+
+% Chart 4: Year-over-Year Price Changes
+\begin{figure}[H]
+\centering
+\begin{tikzpicture}
+\begin{axis}[
+ ybar,
+ width=0.9\textwidth,
+ height=8cm,
+ symbolic x coords={Miami, Sydney, Singapore, Tokyo, Zurich, Hong Kong, Monaco, New York, London, Paris},
+ xtick=data,
+ nodes near coords,
+ nodes near coords style={/pgf/number format/fixed, /pgf/number format/precision=1},
+ nodes near coords align={vertical},
+ ymin=-12, ymax=14,
+ ylabel={YoY Change (\%)},
+ xlabel={City},
+ title={Figure 4: Year-over-Year Price Changes - Top 10 Markets (2024)},
+ xticklabel style={rotate=45, anchor=east, font=\tiny},
+ ymajorgrids=true,
+ grid style=dashed,
+]
+\addplot[ybar, fill=red!60] coords {
+ (Miami, 11.8)
+ (Sydney, 4.5)
+ (Singapore, 4.7)
+ (Tokyo, 3.2)
+ (Zurich, 2.0)
+ (Hong Kong, -9.6)
+ (Monaco, 1.5)
+ (New York, -0.4)
+ (London, -2.9)
+ (Paris, -3.5)
+};
+\end{axis}
+\end{tikzpicture}
+\end{figure}
+
+\subsection{Affordability Assessment}
+
+\subsubsection{Most Critical Markets}
+\begin{enumerate}
+ \item \textbf{Monaco:} Price-to-income ratio estimated at 25:1, effectively excluding all but ultra-wealthy buyers
+ \item \textbf{Hong Kong:} 19.5:1 ratio for 14 consecutive years, fundamentally unaffordable for average residents
+ \item \textbf{London:} 15:1 ratio with prices still 20.7\% below 2014 peak, indicating extreme overvaluation
+\end{enumerate}
+
+\subsubsection{Relative Value Opportunities}
+
+Markets showing more favorable affordability characteristics within the luxury segment:
+\begin{itemize}
+ \item \textbf{Tokyo:} Price-to-income ratio of 11.5:1 with strong rental yields (4.0\%)
+ \item \textbf{Miami:} Although valuations elevated, relative affordability better than established hubs
+ \item \textbf{Zurich:} Stable, predictable appreciation with capital preservation focus
+\end{itemize}
+
+\subsubsection{Trend Analysis}
+
+\begin{itemize}
+ \item \textbf{Deteriorating:} Hong Kong, Sydney, Miami showing worsening affordability
+ \item \textbf{Stabilizing:} London, Paris showing potential for affordability improvement
+ \item \textbf{Remaining Critical:} Monaco expected to maintain extreme unaffordability
+\end{itemize}
+
+\newpage
+
+%=============================================================================
+% SECTION 5: INVESTMENT OPPORTUNITIES
+%=============================================================================
+\section{Investment Opportunities}
+
+\subsection{Market Classification by Investment Profile}
+
+\subsubsection{Growth-Focused Markets}
+
+\textbf{Miami, USA}
+\begin{itemize}
+ \item \textbf{Growth Rate:} 11.8\% YoY (2024), 161\% since 2019
+ \item \textbf{Value Proposition:} Wealth migration from high-tax jurisdictions
+ \item \textbf{Risk Level:} High (top of UBS bubble risk index)
+ \item \textbf{Recommended Strategy:} Selective, short-term appreciation focus
+\end{itemize}
+
+\textbf{Sydney, Australia}
+\begin{itemize}
+ \item \textbf{Growth Rate:} 4.5\% consistent annual growth
+ \item \textbf{Value Proposition:} Immigration-driven demand, supply constraints
+ \item \textbf{Risk Level:} Medium-High (elevated valuations)
+ \item \textbf{Recommended Strategy:} Long-term hold, income plus growth
+\end{itemize}
+
+\textbf{Tokyo, Japan}
+\begin{itemize}
+ \item \textbf{Growth Rate:} Central wards sustained appreciation
+ \item \textbf{Value Proposition:} Top investment market 2024, relative affordability
+ \item \textbf{Risk Level:} Medium (interest rate sensitivity)
+ \item \textbf{Recommended Strategy:} Central location focus, yield enhancement
+\end{itemize}
+
+\subsubsection{Income-Focused Markets}
+
+\textbf{London, UK}
+\begin{itemize}
+ \item \textbf{Yield:} 5.0\% gross rental yield
+ \item \textbf{Value Proposition:} Prices 20.7\% below peak, high demand
+ \item \textbf{Risk Level:} Medium (economic sensitivity)
+ \item \textbf{Recommended Strategy:} Prime central London focus, capital recovery
+\end{itemize}
+
+\textbf{Sydney, Australia}
+\begin{itemize}
+ \item \textbf{Yield:} 4.92\% gross rental yield
+ \item \textbf{Value Proposition:} Strong rental demand, consistent growth
+ \item \textbf{Risk Level:} Medium (housing cycle risk)
+ \item \textbf{Recommended Strategy:} Yield plus appreciation, diverse portfolio
+\end{itemize}
+
+\textbf{Paris, France}
+\begin{itemize}
+ \item \textbf{Yield:} 4.84\% gross rental yield
+ \item \textbf{Value Proposition:} Market correction creating value opportunities
+ \item \textbf{Risk Level:} Medium (economic recovery dependent)
+ \item \textbf{Recommended Strategy:} High-end segment focus, patient capital
+\end{itemize}
+
+\subsubsection{Wealth Preservation Markets}
+
+\textbf{Monaco}
+\begin{itemize}
+ \item \textbf{Allocation:} Ultra-high net worth only
+ \item \textbf{Value Proposition:} Safe haven, tax advantages, privacy
+ \item \textbf{Risk Level:} Low (wealth preservation focus)
+ \item \textbf{Recommended Strategy:} Long-term holding, generational wealth transfer
+\end{itemize}
+
+\textbf{Zurich, Switzerland}
+\begin{itemize}
+ \item \textbf{Growth Rate:} Stable 2\% annual
+ \item \textbf{Value Proposition:} Political and economic stability
+ \item \textbf{Risk Level:} Low (safe haven status)
+ \item \textbf{Recommended Strategy:} Capital preservation, moderate appreciation
+\end{itemize}
+
+\textbf{Singapore}
+\begin{itemize}
+ \item \textbf{Price Stabilization:} 4.7\% non-landed growth
+ \item \textbf{Value Proposition:} Regional stability, wealth magnets
+ \item \textbf{Risk Level:} Low-Medium (cooling measures)
+ \item \textbf{Recommended Strategy:} Long-term hold, strategic location focus
+\end{itemize}
+
+\subsubsection{Turnaround Opportunities}
+
+\textbf{Hong Kong}
+\begin{itemize}
+ \item \textbf{Current State:} -9.6\% YoY decline, early recovery signs
+ \item \textbf{Value Proposition:} Extreme oversold conditions, potential rebound
+ \item \textbf{Risk Level:} High (political and economic sensitivity)
+ \item \textbf{Recommended Strategy:} Contrarian opportunity, patient capital required
+\end{itemize}
+
+\textbf{London, UK}
+\begin{itemize}
+ \item \textbf{Current State:} Prices 20.7\% below 2014 peak
+ \item \textbf{Value Proposition:} Post-Brexit recovery, international buyer return
+ \item \textbf{Risk Level:} Medium (UK economic sensitivity)
+ \item \textbf{Recommended Strategy:} Value investing, premium segment focus
+\end{itemize}
+
+\textbf{Paris, France}
+\begin{itemize}
+ \item \textbf{Current State:} -8.6\% decline since 2020 peak
+ \item \textbf{Value Proposition:} Cultural premium, market stabilization
+ \item \textbf{Risk Level:} Medium (economic and policy sensitivity)
+ \item \textbf{Recommended Strategy:} Selective opportunities, prime locations only
+\end{itemize}
+
+\subsection{Sector-Specific Opportunities}
+
+\subsubsection{Branded Residences}
+Development partnerships between luxury brands and real estate developers offer premium pricing potential through:
+\begin{itemize}
+ \item Enhanced amenities and services
+ \item Brand-associated value premiums
+ \item Strong tourist and transient demand
+ \item High-net-worth buyer appeal
+\end{itemize}
+
+\subsubsection{Sustainable/Luxury Properties}
+Properties integrating green building standards, energy efficiency, and wellness features command growing premiums as ESG considerations influence buyer preferences.
+
+\subsubsection{Privacy-Focused Developments}
+Increased demand for exclusive, low-density properties in secure locations is driving development of gated communities and private islands.
+
+\subsubsection{Co-Living Luxury Assets}
+New product class offering fractional ownership of premium vacation properties, reducing capital barriers while maintaining lifestyle benefits.
+
+\subsection{Recommended Portfolio Allocations}
+
+\textbf{Conservative Portfolio (Capital Preservation Focus)}
+\begin{itemize}
+ \item 30\% - Zurich, Geneva (Swiss stability)
+ \item 25\% - Monaco (safe haven)
+ \item 20\% - Singapore (regional stability)
+ \item 15\% - Tokyo (moderate growth, yields)
+ \item 10\% - London (turnaround opportunity)
+\end{itemize}
+
+\textbf{Balanced Portfolio (Growth + Income)}
+\begin{itemize}
+ \item 20\% - Sydney (consistent growth + yield)
+ \item 20\% - Tokyo (growth + yield)
+ \item 15\% - London (yield + recovery potential)
+ \item 15\% - Paris (value opportunity)
+ \item 15\% - Singapore (stability)
+ \item 10\% - Miami (growth play)
+ \item 5\% - Hong Kong (contrarian opportunity)
+\end{itemize}
+
+\textbf{Aggressive Portfolio (Growth Focus)}
+\begin{itemize}
+ \item 30\% - Miami (high growth potential)
+ \item 20\% - Sydney (strong growth trajectory)
+ \item 20\% - Hong Kong (turnaround play)
+ \item 15\% - Tokyo (investment market leader)
+ \item 10\% - London (recovery opportunity)
+ \item 5\% - Dubai (not in top 10 but high growth)
+\end{itemize}
+
+\newpage
+
+%=============================================================================
+% SECTION 6: RISK ASSESSMENT AND OUTLOOK
+%=============================================================================
+\section{Risk Assessment and Outlook}
+
+\subsection{Global Risk Factors}
+
+\subsubsection{Interest Rate Environment}
+\begin{itemize}
+ \item \textbf{Risk Level:} High
+ \item \textbf{Impact:} Higher borrowing costs dampen demand, reduce affordability
+ \item \textbf{Outlook:} Rates expected to stabilize in 2026, potential for moderate decline supporting market recovery
+\end{itemize}
+
+\subsubsection{Geopolitical Uncertainty}
+\begin{itemize}
+ \item \textbf{Risk Level:} Medium-High
+ \item \textbf{Impact:} War in Ukraine, Middle East tensions, China-Taiwan relations affecting global capital flows
+ \item \textbf{Outlook:} Safe haven markets (Switzerland, Monaco) to benefit; other markets face volatility
+\end{itemize}
+
+\subsubsection{Economic Slowdown}
+\begin{itemize}
+ \item \textbf{Risk Level:} Medium
+ \item \textbf{Impact:} Reduced wealth creation, employment insecurity affecting demand
+ \item \textbf{Outlook:} Luxury segment expected to outperform; HNWIs less affected by economic cycles
+\end{itemize}
+
+\subsubsection{Regulatory Changes}
+\begin{itemize}
+ \item \textbf{Risk Level:} Medium (varies by market)
+ \item \textbf{Impact:} Foreign buyer restrictions, tax policy changes, monetary policy shifts
+ \item \textbf{Outlook:} Active monitoring required; Singapore and Hong Kong particularly sensitive
+\end{itemize}
+
+\subsection{Market-Specific Risk Assessments}
+
+% Risk Assessment Table
+\begin{table}[H]
+\centering
+\caption{Risk Assessment Matrix - Top 10 Markets}
+\begin{tabular}{lcccc}
+\toprule
+\textbf{Market} & \textbf{Valuation Risk} & \textbf{Liquidity Risk} & \textbf{Regulatory Risk} & \textbf{Overall Risk} \\
+\midrule
+Monaco & High & Low & Low & \textbf{Medium} \\
+New York & Medium & Low & Low & \textbf{Low-Medium} \\
+Hong Kong & Low & Medium & High & \textbf{High} \\
+Singapore & Medium & Medium & Medium & \textbf{Medium} \\
+London & Low & Low & Medium & \textbf{Low-Medium} \\
+Tokyo & Low & Medium & Low & \textbf{Low-Medium} \\
+Zurich & Medium & Low & Low & \textbf{Low-Medium} \\
+Sydney & High & Medium & Low & \textbf{Medium} \\
+Paris & Low & Medium & Low & \textbf{Low-Medium} \\
+Miami & High & Medium & Low & \textbf{High} \\
+\bottomrule
+\end{tabular}
+\end{table}
+
+% Detailed Risk Analysis per city
+\subsubsection{Detailed Market Risk Profiles}
+
+\textbf{Monaco}
+\begin{itemize}
+ \item \textbf{Primary Risk:} Valuation extremely elevated relative to income
+ \item \textbf{Mitigating Factors:} Ultra-wealthy buyer base, tax haven status, limited supply
+ \item \textbf{Outlook:} Low downside risk due to wealthy ownership profile
+\end{itemize}
+
+\textbf{New York City}
+\begin{itemize}
+ \item \textbf{Primary Risk:} Employment market volatility, tax competition
+ \item \textbf{Mitigating Factors:} Global financial center, cultural capital, diverse economy
+ \item \textbf{Outlook:} Moderating valuations create selective opportunities
+\end{itemize}
+
+\textbf{Hong Kong}
+\begin{itemize}
+ \item \textbf{Primary Risk:} Political uncertainty, capital controls, national security law
+ \item \textbf{Mitigating Factors:} Price correction already occurred, strong rental market, China growth story
+ \item \textbf{Outlook:} High volatility with potential for significant recovery or further decline; not for risk-averse investors
+\end{itemize}
+
+\textbf{Singapore}
+\begin{itemize}
+ \item \textbf{Primary Risk:} Cooling measures, foreign buyer restrictions
+ \item \textbf{Mitigating Factors:} Political stability, regional safe haven, strong governance
+ \item \textbf{Outlook:} Stabilized market with selective opportunities; monitoring of policy changes essential
+\end{itemize}
+
+\textbf{London}
+\begin{itemize}
+ \item \textbf{Primary Risk:} UK economic weakness, policy uncertainty
+ \item \textbf{Mitigating Factors:} Prices well below peak, strong rental yields, international buyer interest
+ \item \textbf{Outlook:} Recovery expected as economic conditions improve; prime central London leading
+\end{itemize}
+
+\textbf{Tokyo}
+\begin{itemize}
+ \item \textbf{Primary Risk:} Interest rate sensitivity, currency volatility
+ \item \textbf{Mitigating Factors:} Top investment market 2024, relative affordability, strong yields
+ \item \textbf{Outlook:} Stable growth expected with income support from rental market
+\end{itemize}
+
+\textbf{Zurich}
+\begin{itemize}
+ \item \textbf{Primary Risk:} Limited supply constraining volume, conservative appreciation
+ \item \textbf{Mitigating Factors:} Exceptional stability, safe haven demand, strong governance
+ \item \textbf{Outlook:} Predictable, low-risk profile suitable for wealth preservation
+\end{itemize}
+
+\textbf{Sydney}
+\begin{itemize}
+ \item \textbf{Primary Risk:} Elevated valuations, housing market cycle
+ \item \textbf{Mitigating Factors:} Immigration-driven demand, supply constraints, strong yields
+ \item \textbf{Outlook:} Continued growth expected but susceptible to significant corrections if rates rise substantially
+\end{itemize}
+
+\textbf{Paris}
+\begin{itemize}
+ \item \textbf{Primary Risk:} French economic weakness, labor market issues
+ \item \textbf{Mitigating Factors:} Market correction creating value, cultural appeal
+ \item \textbf{Outlook:} Stabilization expected; selective opportunities in premium segment
+\end{itemize}
+
+\textbf{Miami}
+\begin{itemize}
+ \item \textbf{Primary Risk:} Extreme valuations, bubble status (UBS top ranking)
+ \item \textbf{Mitigating Factors:} Wealth migration trend, international demand, lifestyle appeal
+ \item \textbf{Outlook:} High risk of significant correction; only suitable for risk-tolerant growth investors
+\end{itemize}
+
+\subsection{2026 Outlook and Projections}
+
+\subsubsection{Global Forecast Summary}
+\begin{itemize}
+ \item \textbf{Luxury Segment:} Continued outperformance expected, 5-8\% growth projected
+ \item \textbf{Traditional Markets:} Moderate recovery, 2-4\% growth expected
+ \item \textbf{Affordability Crisis:} Expected to persist and deepen in major hubs
+ \item \textbf{Migration Patterns:} Wealth flows to favorable jurisdictions accelerating
+\end{itemize}
+
+\subsubsection{Regional Outlook}
+
+\textbf{North America}
+\begin{itemize}
+ \item \textbf{Florida:} Miami leading US growth, but elevated bubble risk
+ \item \textbf{Northeast:} NYC stabilizing after corrections, value emerging
+ \item \textbf{California:} Out-migration impacting prices, opportunity in premium segments
+\end{itemize}
+
+\textbf{Europe}
+\begin{itemize}
+ \item \textbf{UK:} London leading recovery, prime central outperforming
+ \item \textbf{France:} Paris bottoming, selective opportunities in premium locations
+ \item \textbf{Switzerland:} Continued stability and modest appreciation
+\end{itemize}
+
+\textbf{Asia-Pacific}
+\begin{itemize}
+ \item \textbf{Japan:} Tokyo showing continued strength as top investment market
+ \item \textbf{Singapore:} Stability returns after cooling measures, gradual recovery
+ \item \textbf{Hong Kong:} Critical juncture; recovery or further decline dependent on policy actions
+ \item \textbf{Australia:} Sydney leading growth, housing cycle risks elevated
+\end{itemize}
+
+\textbf{Middle East}
+\begin{itemize}
+ \item \textbf{UAE:} Dubai emerging as top growth market with strong yields
+ \item Wealth migration from other regions supporting demand
+\end{itemize}
+
+\subsubsection{Key Recommendations for 2026}
+
+\begin{enumerate}
+ \item \textbf{Focus on Prime Locations:} In uncertain environments, best-in-class locations outperform
+ \item \textbf{Diversify Globally:} Reduce concentration risk through international allocation
+ \item \textbf{Prioritize Markets with Yields:} Income support cushions price volatility
+ \item \textbf{Monitor Policy Changes:} Regulatory environment increasingly important
+ \item \textbf{Consider Turnaround Opportunities:} London, Hong Kong, Paris showing contrarian potential
+ \item \textbf{Exercise Caution in Overheated Markets:} Miami, Sydney warrant careful due diligence
+ \item \textbf{Maintain Safe Haven Exposure:} Zurich, Monaco, Singapore provide diversification benefits
+\end{enumerate}
+
+\subsubsection{Long-Term Structural Trends}
+
+\begin{itemize}
+ \item \textbf{Urbanization Continues:} Global cities intensifying importance
+ \item \textbf{Wealth Concentration:} Growth of ultra-high net worth population supporting luxury demand
+ \item \textbf{Climate Considerations:} Increasing impact on valuation and insurance costs
+ \item \textbf{Technology Integration:} Smart home features affecting desirability
+ \item \textbf{Generational Transfer:} Wealth inheritances creating new buyer pools
+ \item \textbf{ESG Integration:} Sustainability becoming key differentiator
+\end{itemize}
+
+\subsection{Conclusion}
+
+The global landscape of the most expensive real estate markets will continue evolving through 2026, presenting both significant opportunities and substantial risks. The luxury segment's resilience and continued outperformance relative to traditional markets suggests that premiums for prime global locations will persist.
+
+\textbf{Key Takeaways:}
+\begin{itemize}
+ \item Affordability crisis shows no signs of abating in major global hubs
+ \item Wealth migration patterns are creating new demand centers
+ \item Turnaround opportunities exist in markets that have corrected significantly (London, Hong Kong, Paris)
+ \item Overheated markets (Miami, Sydney) warrant caution despite growth trajectories
+ \item Safe haven markets (Zurich, Monaco, Singapore) offer stability but lower yields
+ \item Market selection requires careful alignment of investment objectives and risk tolerance
+\end{itemize}
+
+Success in 2026 will require:
+\begin{enumerate}
+ \item Disciplined market selection based on fundamentals
+ \item Strategic portfolio construction balancing growth, income, and preservation
+ \item Active monitoring of policy, economic, and geopolitical developments
+ \item Long-term perspective with flexibility to capitalize on dislocations
+ \item Expert local market knowledge and partnership
+\end{enumerate}
+
+The investors who navigate this complex landscape successfully will be those who combine rigorous analysis with strategic patience, positioning themselves to benefit from the structural trends shaping the future of global real estate while managing the inherent risks of premium market investing.
+
+\newpage
+
+\appendix
+
+\section{Data Sources and Methodology}
+
+\subsection{Data Sources}
+\begin{itemize}
+ \item Demographia International Housing Affordability Report 2024
+ \item Global Property Guide rental yield database
+ \item UBS Global Real Estate Bubble Index 2024-2025
+ \item National real estate boards and associations
+ \item Government statistics bureaus
+ \item Knight Frank Global Residential Cities Index
+ \item Savills World Cities Research
+ \item Julius Baer Property Market Reports
+ \item Local real estate industry reports
+\end{itemize}
+
+\subsection{Methodology Notes}
+\begin{itemize}
+ \item Price-to-income ratios calculated using median multiple methodology
+ \item Rental yields represent gross yields before expenses
+ \item Year-over-year changes based on Q4 2024 vs Q4 2023 where available
+ \item All prices converted to USD for consistency
+ \item Market rankings based on combination of price levels and premium characteristics
+\end{itemize}
+
+\section{Glossary}
+\begin{description}
+ \item[Price-to-Income Ratio] Median house price divided by median household income
+ \item[Rental Yield] Annual rental income divided by property value, expressed as percentage
+ \item[Prime Real Estate] High-value properties in top-tier cities with luxury characteristics
+ \item[Gross Rental Yield] Yield before operational expenses and taxes
+ \item[Median Multiple] Alternative term for price-to-income ratio
+ \item[Bubble Risk] Assessment of overvaluation relative to fundamentals
+\end{description}
+
+\end{document}
diff --git a/assets/real_estate/QUICK_REFERENCE.txt b/assets/real_estate/QUICK_REFERENCE.txt
new file mode 100644
index 0000000..8c85b73
--- /dev/null
+++ b/assets/real_estate/QUICK_REFERENCE.txt
@@ -0,0 +1,141 @@
+
+GLOBAL PROPERTY MARKET ANALYSIS 2026
+QUICK REFERENCE SUMMARY
+====================================================
+
+TOP 10 MOST EXPENSIVE REAL ESTATE MARKETS
+====================================================
+
+1. MONACO - $5,200,000 median
+ - World's most expensive market
+ - Price-to-income: 25.0:1 (extremely unaffordable)
+ - Rental yield: 2.0% (very low)
+ - YoY change: +1.5% (stable)
+ - Focus: Wealth preservation for UHNWIs
+
+2. NEW YORK CITY - $1,340,000 median
+ - Top US luxury market
+ - Price-to-income: 14.0:1
+ - Rental yield: 3.5%
+ - YoY change: -0.4% (slight decline)
+ - Focus: Stability with selective opportunities
+
+3. HONG KONG - $1,200,000 median
+ - Most unaffordable globally (14th year)
+ - Price-to-income: 19.5:1
+ - Rental yield: 3.9%
+ - YoY change: -9.6% (major correction)
+ - Focus: High-risk turnaround opportunity
+
+4. SINGAPORE - $1,320,000 median
+ - SE Asia's premier market
+ - Price-to-income: 13.5:1
+ - Rental yield: 3.0%
+ - YoY change: +4.7% (moderate growth)
+ - Focus: Regional safe haven
+
+5. LONDON - $1,100,000 median
+ - Europe's leading luxury market
+ - Price-to-income: 15.0:1
+ - Rental yield: 5.0% (highest yield)
+ - YoY change: -2.9% (below 2014 peak)
+ - Focus: Turnaround with income
+
+6. TOKYO - $670,000 median
+ - Asia's diversified premium market
+ - Price-to-income: 11.5:1
+ - Rental yield: 4.0%
+ - YoY change: +3.2%
+ - Focus: Growth plus income
+
+7. ZURICH - $1,500,000 median
+ - Europe's stable premium market
+ - Price-to-income: 13.0:1
+ - Rental yield: 3.4%
+ - YoY change: +2.0%
+ - Focus: Wealth preservation
+
+8. SYDNEY - $1,070,000 median
+ - Oceania's leading market
+ - Price-to-income: 14.5:1
+ - Rental yield: 4.9%
+ - YoY change: +4.5%
+ - Focus: Consistent growth with yield
+
+9. PARIS - $1,050,000 median
+ - Europe's cultural capital
+ - Price-to-income: 12.5:1
+ - Rental yield: 4.8%
+ - YoY change: -3.5% (correcting from peak)
+ - Focus: Selective value opportunities
+
+10. MIAMI - $570,000 median
+ - Fastest-growing in Americas
+ - Price-to-income: 11.0:1
+ - Rental yield: 4.2%
+ - YoY change: +11.8% (highest growth)
+ - Focus: High-growth play (bubble risk)
+
+====================================================
+KEY INSIGHTS
+====================================================
+
+AFFORDABILITY CRISIS
+- All 10 markets are "Impossibly Unaffordable" (9.0+:1)
+- Average price-to-income ratio: 14.9:1
+- Worst: Monaco (25.0:1), Best: Miami (11.0:1)
+
+RENTAL YIELDS
+- Average yield: 3.9%
+- Highest: London (5.0%)
+- Lowest: Monaco (2.0%)
+
+PRICE MOMENTUM
+- Fastest growing: Miami (+11.8%)
+- Declining: Hong Kong (-9.6%), Paris (-3.5%)
+- Average YoY change: +1.8%
+
+INVESTMENT OPPORTUNITIES
+- Growth: Miami, Sydney, Tokyo
+- Income: London, Sydney, Paris
+- Preservation: Monaco, Zurich, Singapore
+- Turnaround: Hong Kong, London, Paris
+
+RISK ASSESSMENT
+- High Risk: Miami (bubble), Hong Kong (political)
+- Medium Risk: Sydney, Singapore, Monaco, NYC
+- Lower Risk: London, Tokyo, Zurich, Paris
+
+====================================================
+2026 OUTLOOK
+====================================================
+
+PROJECTIONS
+- Luxury segment: 5-8% growth
+- Traditional markets: 2-4% growth
+- Affordability crisis: Expected to deepen
+- Wealth migration: Accelerating
+
+RECOMMENDATIONS
+1. Focus on prime locations
+2. Diversify globally
+3. Prioritize markets with yields
+4. Monitor policy changes
+5. Consider turnaround opportunities
+6. Be cautious in overheated markets
+7. Maintain safe haven exposure
+
+====================================================
+DATA AVAILABILITY
+================================================----
+
+Files in assets/real_estate/:
+- Global_Property_Market_Analysis_2026.tex (full report)
+- market_data_2026.csv (raw data)
+- market_data_2026.json (structured data)
+- README.md (comprehensive documentation)
+- QUICK_REFERENCE.txt (this file)
+
+====================================================
+Prepared: January 2026
+Data Currency: Q4 2024 with 2026 projections
diff --git a/assets/real_estate/README.md b/assets/real_estate/README.md
new file mode 100644
index 0000000..de82427
--- /dev/null
+++ b/assets/real_estate/README.md
@@ -0,0 +1,232 @@
+# Global Property Market Analysis 2026
+## Top 10 Most Expensive Real Estate Markets
+
+### Overview
+This comprehensive analysis examines the world's most expensive real estate markets as of 2026, analyzing median home prices, price-to-income ratios, rental yields, and year-over-year changes across 10 global cities.
+
+### Files Included
+1. **Global_Property_Market_Analysis_2026.tex** - Complete LaTeX report with all analysis
+2. **market_data_2026.csv** - Raw data for all 10 markets
+3. **README.md** - This summary document
+
+### Executive Summary
+
+#### Key Findings
+- **Monaco** maintains position as world's most expensive market at $52,000 per square meter
+- **Hong Kong** remains most unaffordable globally for 14 consecutive years (19.5:1 price-to-income ratio)
+- **Miami** is fastest-growing premium market with 11.8% YoY growth in 2024
+- **Singapore** shows remarkable stability with median condo prices at $1.32M
+- **Luxury sector** continues outperforming traditional real estate segments
+
+#### Market Statistics for Top 10 Cities
+
+| Rank | City | Median Price | Price/Income | Rental Yield | YoY Change |
+|------|------|--------------|--------------|--------------|------------|
+| 1 | Monaco | $5,200,000 | 25.0:1 | 2.0% | +1.5% |
+| 2 | New York | $1,340,000 | 14.0:1 | 3.5% | -0.4% |
+| 3 | Hong Kong | $1,200,000 | 19.5:1 | 3.9% | -9.6% |
+| 4 | Singapore | $1,320,000 | 13.5:1 | 3.0% | +4.7% |
+| 5 | London | $1,100,000 | 15.0:1 | 5.0% | -2.9% |
+| 6 | Tokyo | $670,000 | 11.5:1 | 4.0% | +3.2% |
+| 7 | Zurich | $1,500,000 | 13.0:1 | 3.4% | +2.0% |
+| 8 | Sydney | $1,070,000 | 14.5:1 | 4.9% | +4.5% |
+| 9 | Paris | $1,050,000 | 12.5:1 | 4.8% | -3.5% |
+| 10 | Miami | $570,000 | 11.0:1 | 4.2% | +11.8% |
+
+### Market Analysis Summary
+
+#### 1. Monaco
+- **Position:** World's most expensive market
+- **Key Characteristic:** Tax haven with extreme wealth concentration
+- **Investment Profile:** Wealth preservation, ultra-high net worth only
+- **Primary Risk:** Extreme valuations, limited liquidity
+
+#### 2. New York City
+- **Position:** Top North American luxury market
+- **Key Characteristic:** Global financial and cultural capital
+- **Investment Profile:** Stability with selective opportunities
+- **Primary Risk:** Tax competition, employment market volatility
+
+#### 3. Hong Kong
+- **Position:** Asia's most expensive, most unaffordable globally
+- **Key Characteristic:** Geographic constraints, political uncertainty
+- **Investment Profile:** High risk/return turnaround opportunity
+- **Primary Risk:** Political risk, capital controls
+
+#### 4. Singapore
+- **Position:** Southeast Asia's premier market
+- **Key Characteristic:** Political stability, strong governance
+- **Investment Profile:** Regional safe haven
+- **Primary Risk:** Cooling measures, foreign buyer restrictions
+
+#### 5. London
+- **Position:** Europe's leading luxury market
+- **Key Characteristic:** Prices 20.7% below 2014 peak
+- **Investment Profile:** Turnaround opportunity with yields
+- **Primary Risk:** UK economic weakness
+
+#### 6. Tokyo
+- **Position:** Asia's diversified premium market
+- **Key Characteristic:** Named world's top investment market 2024
+- **Investment Profile:** Growth plus income
+- **Primary Risk:** Interest rate sensitivity
+
+#### 7. Zurich
+- **Position:** Continental Europe's stable premium market
+- **Key Characteristic:** Conservative appreciation, safe haven
+- **Investment Profile:** Wealth preservation focus
+- **Primary Risk:** Limited supply, low appreciation
+
+#### 8. Sydney
+- **Position:** Oceania's leading premium market
+- **Key Characteristic:** Immigration-driven demand
+- **Investment Profile:** Consistent growth with yields
+- **Primary Risk:** Elevated valuations, housing cycle
+
+#### 9. Paris
+- **Position:** Continental Europe's cultural capital
+- **Key Characteristic:** Market correction from 2020 peak
+- **Investment Profile:** Value opportunity selective
+- **Primary Risk:** French economic weakness
+
+#### 10. Miami
+- **Position:** Fastest-growing premium market in Americas
+- **Key Characteristic:** Wealth migration from high-tax states
+- **Investment Profile:** High growth play
+- **Primary Risk:** Extreme valuations, bubble status
+
+### Affordability Analysis
+
+#### Price-to-Income Ratio Rankings (worst to best)
+1. Monaco: 25.0:1
+2. Hong Kong: 19.5:1
+3. London: 15.0:1
+4. Sydney: 14.5:1
+5. New York: 14.0:1
+6. Singapore: 13.5:1
+7. Zurich: 13.0:1
+8. Paris: 12.5:1
+9. Tokyo: 11.5:1
+10. Miami: 11.0:1
+
+**Note:** All 10 markets fall into the "Impossibly Unaffordable" category (9.0+:1), meaning home prices exceed 9 times median household income.
+
+#### Rental Yield Rankings (highest to lowest)
+1. London: 5.0%
+2. Sydney: 4.9%
+3. Paris: 4.8%
+4. Miami: 4.2%
+5. Tokyo: 4.0%
+6. Hong Kong: 3.9%
+7. New York: 3.5%
+8. Zurich: 3.4%
+9. Singapore: 3.0%
+10. Monaco: 2.0%
+
+#### Year-over-Year Price Changes (highest to lowest)
+1. Miami: +11.8%
+2. Sydney: +4.5%
+3. Singapore: +4.7% (3rd in growth but 2nd in affordability challenge)
+4. Tokyo: +3.2%
+5. Zurich: +2.0%
+6. Monaco: +1.5%
+7. New York: -0.4%
+8. London: -2.9%
+9. Paris: -3.5%
+10. Hong Kong: -9.6%
+
+### Investment Opportunities
+
+#### Growth-Focused Markets
+1. **Miami** - 11.8% YoY growth, wealth migration trend
+2. **Sydney** - Consistent 4.5% growth, immigration-driven
+3. **Tokyo** - Top investment market 2024, relative affordability
+
+#### Income-Focused Markets
+1. **London** - 5.0% yield, 20.7% below peak
+2. **Sydney** - 4.9% yield, consistent growth
+3. **Paris** - 4.8% yield, market correction
+
+#### Wealth Preservation Markets
+1. **Monaco** - Safe haven, tax advantages
+2. **Zurich** - Exceptional stability, conservative growth
+3. **Singapore** - Regional stability, strong governance
+
+#### Turnaround Opportunities
+1. **Hong Kong** - 9.6% decline, early recovery signs
+2. **London** - Below peak prices, buyers returning
+3. **Paris** - 8.6% decline since peak, stabilization
+
+### Risk Assessment
+
+#### Overall Risk Levels
+- **High Risk:** Miami (bubble), Hong Kong (political)
+- **Medium-High Risk:** Sydney (valuations), Singapore (regulatory)
+- **Medium Risk:** Monaco (valuations), New York (competition)
+- **Low-Medium Risk:** London, Tokyo, Zurich, Paris
+
+#### Key Risk Factors
+1. Interest Rate Environment (Global)
+2. Geopolitical Uncertainty (Regional specific)
+3. Economic Slowdown (Global)
+4. Regulatory Changes (Market specific)
+
+### 2026 Outlook
+
+#### Projections
+- Luxury segment: 5-8% growth expected
+- Traditional markets: 2-4% growth expected
+- Affordability crisis: Expected to persist and deepen
+- Wealth migration: To favorable jurisdictions accelerating
+
+#### Key Recommendations
+1. Focus on prime locations in uncertain markets
+2. Diversify globally to reduce concentration risk
+3. Prioritize markets with rental yields for income support
+4. Monitor policy changes closely
+5. Consider turnaround opportunities (London, Hong Kong, Paris)
+6. Exercise caution in overheated markets (Miami, Sydney)
+7. Maintain safe haven exposure (Zurich, Monaco, Singapore)
+
+### Data Sources
+
+Primary data sources include:
+- Demographia International Housing Affordability Report 2024
+- Global Property Guide rental yield database
+- UBS Global Real Estate Bubble Index 2024-2025
+- National real estate boards and associations
+- Government statistics bureaus
+- Knight Frank Global Residential Cities Index
+- Savills World Cities Research
+- Julius Baer Property Market Reports
+- Local real estate industry reports
+
+### Compiling the LaTeX Report
+
+To compile the LaTeX document, use:
+```
+pdflatex Global_Property_Market_Analysis_2026.tex
+```
+
+This will generate a comprehensive PDF report with:
+- Executive Summary
+- Global Market Overview
+- City-by-City Analysis (top 10)
+- Affordability Analysis with 4 charts
+- Investment Opportunities
+- Risk Assessment and Outlook
+- Appendices with methodology and glossary
+
+### Notes
+
+- All prices are in USD for consistency
+- Price-to-income ratios calculated using median multiple methodology
+- Rental yields represent gross yields before expenses
+- Year-over-year changes based on Q4 2024 vs Q4 2023 where available
+- Market rankings based on combination of price levels and premium characteristics
+
+---
+
+**Report Prepared:** January 2026
+**Analysis Period:** 2024-2026
+**Data Currency:** Q4 2024 with 2026 projections
diff --git a/assets/real_estate/market_data_2026.csv b/assets/real_estate/market_data_2026.csv
new file mode 100644
index 0000000..41e13ff
--- /dev/null
+++ b/assets/real_estate/market_data_2026.csv
@@ -0,0 +1,11 @@
+Rank,City,Country,Median_Price_USD,Price_SqMeter_USD,Price_to_Income_Ratio,Rental_Yield_Percent,YoY_Change_Percent
+1,Monaco,Monaco,5200000,52000,25.0,2.0,1.5
+2,New York,USA,1340000,17000,14.0,3.5,-0.4
+3,Hong Kong,Hong Kong SAR,1200000,26300,19.5,3.9,-9.6
+4,Singapore,Singapore,1320000,18000,13.5,3.0,4.7
+5,London,UK,1100000,15000,15.0,5.0,-2.9
+6,Tokyo,Japan,670000,12000,11.5,4.0,3.2
+7,Zurich,Switzerland,1500000,14500,13.0,3.4,2.0
+8,Sydney,Australia,1070000,13000,14.5,4.9,4.5
+9,Paris,France,1050000,10000,12.5,4.8,-3.5
+10,Miami,USA,570000,6000,11.0,4.2,11.8
diff --git a/assets/real_estate/market_data_2026.json b/assets/real_estate/market_data_2026.json
new file mode 100644
index 0000000..76b5eeb
--- /dev/null
+++ b/assets/real_estate/market_data_2026.json
@@ -0,0 +1,145 @@
+{
+ "report_title": "Global Property Market Analysis 2026",
+ "report_date": "January 2026",
+ "top_10_markets": [
+ {
+ "rank": 1,
+ "city": "Monaco",
+ "country": "Monaco",
+ "median_price_usd": 5200000,
+ "price_per_sq_meter_usd": 52000,
+ "price_to_income_ratio": 25.0,
+ "rental_yield_percent": 2.0,
+ "yoy_change_percent": 1.5,
+ "market_position": "World's most expensive market",
+ "investment_profile": "Wealth preservation, ultra-high net worth only"
+ },
+ {
+ "rank": 2,
+ "city": "New York",
+ "country": "USA",
+ "median_price_usd": 1340000,
+ "price_per_sq_meter_usd": 17000,
+ "price_to_income_ratio": 14.0,
+ "rental_yield_percent": 3.5,
+ "yoy_change_percent": -0.4,
+ "market_position": "Top North American luxury market",
+ "investment_profile": "Stability with selective opportunities"
+ },
+ {
+ "rank": 3,
+ "city": "Hong Kong",
+ "country": "Hong Kong SAR",
+ "median_price_usd": 1200000,
+ "price_per_sq_meter_usd": 26300,
+ "price_to_income_ratio": 19.5,
+ "rental_yield_percent": 3.9,
+ "yoy_change_percent": -9.6,
+ "market_position": "Asia's most expensive, most unaffordable globally",
+ "investment_profile": "High risk/return turnaround opportunity"
+ },
+ {
+ "rank": 4,
+ "city": "Singapore",
+ "country": "Singapore",
+ "median_price_usd": 1320000,
+ "price_per_sq_meter_usd": 18000,
+ "price_to_income_ratio": 13.5,
+ "rental_yield_percent": 3.0,
+ "yoy_change_percent": 4.7,
+ "market_position": "Southeast Asia's premier market",
+ "investment_profile": "Regional safe haven"
+ },
+ {
+ "rank": 5,
+ "city": "London",
+ "country": "UK",
+ "median_price_usd": 1100000,
+ "price_per_sq_meter_usd": 15000,
+ "price_to_income_ratio": 15.0,
+ "rental_yield_percent": 5.0,
+ "yoy_change_percent": -2.9,
+ "market_position": "Europe's leading luxury market",
+ "investment_profile": "Turnaround opportunity with yields"
+ },
+ {
+ "rank": 6,
+ "city": "Tokyo",
+ "country": "Japan",
+ "median_price_usd": 670000,
+ "price_per_sq_meter_usd": 12000,
+ "price_to_income_ratio": 11.5,
+ "rental_yield_percent": 4.0,
+ "yoy_change_percent": 3.2,
+ "market_position": "Asia's diversified premium market",
+ "investment_profile": "Growth plus income"
+ },
+ {
+ "rank": 7,
+ "city": "Zurich",
+ "country": "Switzerland",
+ "median_price_usd": 1500000,
+ "price_per_sq_meter_usd": 14500,
+ "price_to_income_ratio": 13.0,
+ "rental_yield_percent": 3.4,
+ "yoy_change_percent": 2.0,
+ "market_position": "Continental Europe's stable premium market",
+ "investment_profile": "Wealth preservation focus"
+ },
+ {
+ "rank": 8,
+ "city": "Sydney",
+ "country": "Australia",
+ "median_price_usd": 1070000,
+ "price_per_sq_meter_usd": 13000,
+ "price_to_income_ratio": 14.5,
+ "rental_yield_percent": 4.9,
+ "yoy_change_percent": 4.5,
+ "market_position": "Oceania's leading premium market",
+ "investment_profile": "Consistent growth with yields"
+ },
+ {
+ "rank": 9,
+ "city": "Paris",
+ "country": "France",
+ "median_price_usd": 1050000,
+ "price_per_sq_meter_usd": 10000,
+ "price_to_income_ratio": 12.5,
+ "rental_yield_percent": 4.8,
+ "yoy_change_percent": -3.5,
+ "market_position": "Continental Europe's cultural capital",
+ "investment_profile": "Value opportunity selective"
+ },
+ {
+ "rank": 10,
+ "city": "Miami",
+ "country": "USA",
+ "median_price_usd": 570000,
+ "price_per_sq_meter_usd": 6000,
+ "price_to_income_ratio": 11.0,
+ "rental_yield_percent": 4.2,
+ "yoy_change_percent": 11.8,
+ "market_position": "Fastest-growing premium market in Americas",
+ "investment_profile": "High growth play"
+ }
+ ],
+ "summary_statistics": {
+ "average_median_price_usd": 1502000,
+ "average_price_to_income_ratio": 14.9,
+ "average_rental_yield_percent": 3.9,
+ "highest_yoy_growth_city": "Miami",
+ "highest_yoy_growth_percent": 11.8,
+ "lowest_yoy_growth_city": "Hong Kong",
+ "lowest_yoy_growth_percent": -9.6
+ },
+ "data_sources": [
+ "Demographia International Housing Affordability Report 2024",
+ "Global Property Guide rental yield database",
+ "UBS Global Real Estate Bubble Index 2024-2025",
+ "National real estate boards and associations",
+ "Government statistics bureaus",
+ "Knight Frank Global Residential Cities Index",
+ "Savills World Cities Research",
+ "Julius Baer Property Market Reports"
+ ]
+}
\ No newline at end of file
diff --git a/assets/top10_economies_2024_data.csv b/assets/top10_economies_2024_data.csv
new file mode 100644
index 0000000..657fac0
--- /dev/null
+++ b/assets/top10_economies_2024_data.csv
@@ -0,0 +1,11 @@
+Rank,Country,GDP_Trillion_USD,Growth_Rate_Percent,Inflation_Rate_Percent,Unemployment_Rate_Percent
+1,United States,29.17,2.8,3.0,4.3
+2,China,18.27,4.8,2.4,5.1
+3,Germany,4.71,0.0,2.6,6.3
+4,Japan,4.07,0.3,2.7,2.6
+5,India,3.89,7.0,5.6,4.6
+6,United Kingdom,3.59,1.1,3.9,4.7
+7,France,3.17,1.1,2.9,7.37
+8,Italy,2.38,0.7,2.8,6.78
+9,Canada,2.21,1.3,3.4,6.45
+10,Brazil,2.19,3.0,3.5,7.63
diff --git a/get.py b/get.py
deleted file mode 100644
index a06a161..0000000
--- a/get.py
+++ /dev/null
@@ -1,26 +0,0 @@
-import requests
-import json
-import sys
-import os
-from dotenv import load_dotenv
-
-# get api key from .env file using load_dotenv
-load_dotenv()
-
-url = "https://scrape.serper.dev"
-
-# get first argument
-url_scrape = sys.argv[1]
-
-payload = json.dumps({
- "url": url_scrape,
- "includeMarkdown": True
-})
-headers = {
- 'X-API-KEY': os.getenv("SERPER_API_KEY"),
- 'Content-Type': 'application/json'
-}
-
-response = requests.request("POST", url, headers=headers, data=payload)
-
-print(response.text)
\ No newline at end of file
diff --git a/main.py b/main.py
index 15622b2..7666135 100644
--- a/main.py
+++ b/main.py
@@ -1,130 +1,114 @@
-from openai import OpenAI
-from termcolor import termcolor
-import os
-from dotenv import load_dotenv
-import re
-import subprocess
-from rich import print as rprint
-import time
-import threading
-import sys
-
-# get api key from .env file using load_dotenv
-load_dotenv()
-
-AGENT_PROMPT = \
-'''
-You are a AGI agent who have access to a UNIX shell environment and can interact with it through commands.
-Your key capabilities:
-- Execute and monitor shell commands
-- Observe and analyze command outputs
-- Make decisions based on concrete results
-- Adapt plans based on observed outcomes
-- Track progress toward objectives
-You will receive information in XML-like markup tags that provide context about:
-- TASK: Overall objective for this session (immutable)
-- MEMORY: Observed facts and command results
-- PLAN: Current action sequence
-- SUBGOAL: Immediate next objective
-- COMMAND: The command you are to execute
-The decision loop happens in phases.
-Focus on phase description and only use commands appropriate for the current phase.
-Operating principles:
-- Test assumptions with direct observations
-- Base decisions on command outputs and results
-- Document actions and outcomes clearly
-- Use straightforward approaches first
-- Revise methods based on actual results
-- Maintain focus on primary objective
-- Stick to simple text - avoid using Markdown formatting (no **, #, >, etc)
-- Be precise with names and paths
-- Check the contents of the files you have created
-- End the loop when you are satisfied with the result, explaining why
-- Always suggest the first command on the 1st iteration of the loop, using the XML-like markup tags
-- When you don't have the most updated information, search on the web and navigate to the most relevant link
-- In addition to the traditional command line tools, you have access to additional tools
- All those tools can be called by running the command "uv run ''"
- - search.py: A tool to search the web
- - get.py: A tool to scrape a link
-'''
-
-TASK_PROMPT = \
-'''
-
-Create a csv file with the top 10 economies by GDP in 2024
-
-'''
+#!/usr/bin/env python3
+"""
+Simple Agent - Run an AI agent with tool-calling capabilities.
-class Loader:
- def __init__(self):
- self.running = False
- self.thread = None
- self.start_time = 0
+Usage:
+ python main.py # Run with default task
+ python main.py --task ai_industry # Run a specific task
+ python main.py --list # List available tasks
+ python main.py --custom "Your task" # Run with custom task
+"""
- def animate(self):
- chars = "⠋⠙⠹⠸⠼⠴⠦⠧⠇⠏"
- i = 0
- while self.running:
- elapsed = time.time() - self.start_time
- sys.stdout.write(f'\r{termcolor.colored(f"{chars[i]} 🐝 👁️ Thinking... ({elapsed:.1f}s)", "magenta")}')
- sys.stdout.flush()
- time.sleep(0.1)
- i = (i + 1) % len(chars)
+import argparse
+import sys
- def start(self):
- self.running = True
- self.start_time = time.time()
- self.thread = threading.Thread(target=self.animate)
- self.thread.start()
+from src.agent import Agent
+from src.agent.config import validate_config
+from tasks import get_task, list_tasks, TASKS
- def stop(self):
- self.running = False
- if self.thread:
- self.thread.join()
- sys.stdout.write('\r\n')
- sys.stdout.flush()
-def main() -> None:
- print(termcolor.colored("Initializing OpenAI client...", "cyan"))
- client: OpenAI = OpenAI(
- api_key=os.getenv("DEEPSEEK_API_KEY"),
- base_url="https://api.deepseek.com"
+def main():
+ parser = argparse.ArgumentParser(
+ description="Run an AI agent with tool-calling capabilities.",
+ formatter_class=argparse.RawDescriptionHelpFormatter,
+ epilog="""
+Examples:
+ python main.py --task ai_industry
+ python main.py --task macroeconomics
+ python main.py --custom "Research the top 5 programming languages in 2024"
+ python main.py --list
+ """
)
-
- loader = Loader()
- memory: list[str] = []
- messages: list[dict[str, str]] = [
- {"role": "system", "content": AGENT_PROMPT},
- {"role": "user", "content": TASK_PROMPT},
- ]
-
- while True:
- loader.start()
- response = client.chat.completions.create(
- # model="o1-2024-12-17",
- model="deepseek-chat",
- messages=messages
- )
- loader.stop()
-
- content: str = response.choices[0].message.content
- print(termcolor.colored(content, "cyan"))
-
- # ask user to press enter to continue
- input(termcolor.colored("Press Enter to continue...", "cyan"))
-
- match = re.search(r'(.*?)', content, re.DOTALL)
- if not match:
- break
-
- command: str = match.group(1).strip()
- result = subprocess.run(command, shell=True, capture_output=True, text=True)
- memory.append(f"Output of {command}:\n{result.stdout}\n{result.stderr}")
- messages.append({"role": "user", "content": f'{memory[-1]}'})
-
- rprint(memory)
- input(termcolor.colored("Press Enter to continue...", "cyan"))
+
+ parser.add_argument(
+ "--task", "-t",
+ type=str,
+ help="Run a predefined task by ID"
+ )
+ parser.add_argument(
+ "--custom", "-c",
+ type=str,
+ help="Run a custom task with the provided prompt"
+ )
+ parser.add_argument(
+ "--list", "-l",
+ action="store_true",
+ help="List all available predefined tasks"
+ )
+ parser.add_argument(
+ "--max-iterations", "-m",
+ type=int,
+ default=40,
+ help="Maximum number of iterations (default: 40)"
+ )
+ parser.add_argument(
+ "--quiet", "-q",
+ action="store_true",
+ help="Suppress verbose output"
+ )
+
+ args = parser.parse_args()
+
+ # List tasks
+ if args.list:
+ print("\n📋 Available Tasks:\n")
+ for task_id, task_info in TASKS.items():
+ print(f" • {task_id}: {task_info['name']}")
+ print("\nRun with: python main.py --task ")
+ return 0
+
+ # Validate configuration
+ issues = validate_config()
+ if issues:
+ print("⚠️ Configuration issues:")
+ for issue in issues:
+ print(f" • {issue}")
+ print("\nPlease check your .env file.")
+ return 1
+
+ # Determine task
+ if args.custom:
+ task_prompt = f"\n{args.custom}\n"
+ elif args.task:
+ try:
+ task_info = get_task(args.task)
+ task_prompt = task_info["prompt"]
+ print(f"📝 Running task: {task_info['name']}")
+ except ValueError as e:
+ print(f"❌ Error: {e}")
+ return 1
+ else:
+ # Default task
+ task_prompt = """
+Search for the top 5 news stories today and create a summary CSV file with columns: headline, source, summary.
+Save the file to assets/news_summary.csv
+"""
+ print("📝 Running default task (use --task or --custom to specify)")
+
+ # Run agent
+ agent = Agent(max_iterations=args.max_iterations)
+
+ try:
+ trajectory_path = agent.run(task_prompt, verbose=not args.quiet)
+ print(f"\n✅ Done! Trajectory saved to: {trajectory_path}")
+ return 0
+ except KeyboardInterrupt:
+ print("\n\n⚠️ Interrupted by user")
+ return 130
+ except Exception as e:
+ print(f"\n❌ Error: {e}")
+ return 1
if __name__ == "__main__":
- main()
\ No newline at end of file
+ sys.exit(main())
diff --git a/pyproject.toml b/pyproject.toml
index 1bf246b..a9f4e61 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -1,13 +1,67 @@
[project]
name = "simple-agent"
-version = "0.1.0"
-description = "Add your description here"
+version = "0.2.0"
+description = "An AI agent with tool-calling capabilities for research and data analysis"
readme = "README.md"
-requires-python = ">=3.13"
+license = { text = "MIT" }
+requires-python = ">=3.11"
+authors = []
+keywords = ["ai", "agent", "llm", "tool-calling", "research", "automation"]
+classifiers = [
+ "Development Status :: 4 - Beta",
+ "Intended Audience :: Developers",
+ "License :: OSI Approved :: MIT License",
+ "Programming Language :: Python :: 3",
+ "Programming Language :: Python :: 3.11",
+ "Programming Language :: Python :: 3.12",
+ "Programming Language :: Python :: 3.13",
+ "Topic :: Scientific/Engineering :: Artificial Intelligence",
+]
+
dependencies = [
- "openai>=1.59.3",
- "python-dotenv>=1.0.1",
- "requests>=2.32.3",
- "rich>=13.9.4",
- "termcolor>=2.5.0",
+ "openai>=1.59.0",
+ "python-dotenv>=1.0.0",
+ "requests>=2.31.0",
+ "termcolor>=2.4.0",
+ "pandas>=2.2.0",
+ "matplotlib>=3.8.0",
+]
+
+[project.optional-dependencies]
+dev = [
+ "pytest>=8.0.0",
+ "pytest-cov>=4.1.0",
+ "black>=24.0.0",
+ "ruff>=0.2.0",
+ "mypy>=1.8.0",
]
+
+[project.scripts]
+simple-agent = "main:main"
+
+[build-system]
+requires = ["hatchling"]
+build-backend = "hatchling.build"
+
+[tool.hatch.build.targets.wheel]
+packages = ["src/agent", "tasks"]
+
+[tool.black]
+line-length = 100
+target-version = ["py311"]
+
+[tool.ruff]
+line-length = 100
+target-version = "py311"
+select = ["E", "F", "I", "N", "W", "UP"]
+ignore = ["E501"]
+
+[tool.mypy]
+python_version = "3.11"
+warn_return_any = true
+warn_unused_configs = true
+ignore_missing_imports = true
+
+[tool.pytest.ini_options]
+testpaths = ["tests"]
+python_files = ["test_*.py"]
diff --git a/search.py b/search.py
deleted file mode 100644
index f3442db..0000000
--- a/search.py
+++ /dev/null
@@ -1,26 +0,0 @@
-import requests
-import json
-import sys
-import os
-from dotenv import load_dotenv
-
-# get api key from .env file using load_dotenv
-load_dotenv()
-
-url = "https://google.serper.dev/search"
-
-# get first argument
-query = sys.argv[1]
-
-payload = json.dumps({
- "q": query,
- "num": 5
-})
-headers = {
- 'X-API-KEY': os.getenv("SERPER_API_KEY"),
- 'Content-Type': 'application/json'
-}
-
-response = requests.request("POST", url, headers=headers, data=payload)
-
-print(response.text)
\ No newline at end of file
diff --git a/src/agent/__init__.py b/src/agent/__init__.py
new file mode 100644
index 0000000..baf0572
--- /dev/null
+++ b/src/agent/__init__.py
@@ -0,0 +1,30 @@
+"""
+Simple Agent - An AI agent with tool-calling capabilities.
+"""
+
+from .config import (
+ API_BASE_URL,
+ API_KEY,
+ MODEL_NAME,
+ MAX_ITERATIONS,
+ AGENT_PROMPT,
+ ASSETS_DIR,
+ OUTPUT_DIR,
+)
+from .core import Agent
+from .trajectory import TrajectoryLogger
+
+__all__ = [
+ "Agent",
+ "TrajectoryLogger",
+ "API_BASE_URL",
+ "API_KEY",
+ "MODEL_NAME",
+ "MAX_ITERATIONS",
+ "AGENT_PROMPT",
+ "ASSETS_DIR",
+ "OUTPUT_DIR",
+]
+
+__version__ = "0.2.0"
+
diff --git a/src/agent/config.py b/src/agent/config.py
new file mode 100644
index 0000000..4f40b3e
--- /dev/null
+++ b/src/agent/config.py
@@ -0,0 +1,97 @@
+"""
+Configuration management for the agent.
+All settings are loaded from environment variables.
+"""
+
+import os
+from pathlib import Path
+from dotenv import load_dotenv
+
+load_dotenv()
+
+
+# =============================================================================
+# API Configuration
+# =============================================================================
+
+API_BASE_URL = os.getenv("API_BASE_URL", "http://localhost:8080/v1")
+API_KEY = os.getenv("API_KEY", "not-needed")
+MODEL_NAME = os.getenv("MODEL_NAME", "gpt-4")
+
+
+# =============================================================================
+# Tavily API (Web Search)
+# =============================================================================
+
+TAVILY_API_KEY = os.getenv("TAVILY_API_KEY", "")
+TAVILY_SEARCH_URL = os.getenv("TAVILY_SEARCH_URL", "https://api.tavily.com/search")
+TAVILY_EXTRACT_URL = os.getenv("TAVILY_EXTRACT_URL", "https://api.tavily.com/extract")
+
+
+# =============================================================================
+# Agent Settings
+# =============================================================================
+
+MAX_ITERATIONS = int(os.getenv("MAX_ITERATIONS", "40"))
+COMMAND_TIMEOUT = int(os.getenv("COMMAND_TIMEOUT", "60"))
+MAX_CONTENT_LENGTH = int(os.getenv("MAX_CONTENT_LENGTH", "5000"))
+
+
+# =============================================================================
+# Directories
+# =============================================================================
+
+BASE_DIR = Path(__file__).parent.parent.parent
+ASSETS_DIR = BASE_DIR / "assets"
+OUTPUT_DIR = BASE_DIR / "output"
+
+ASSETS_DIR.mkdir(exist_ok=True)
+OUTPUT_DIR.mkdir(exist_ok=True)
+
+
+# =============================================================================
+# Agent System Prompt
+# =============================================================================
+
+AGENT_PROMPT = """You are an AGI agent with access to a UNIX shell environment and various tools.
+
+Your capabilities:
+- Execute and monitor shell commands
+- Search the web for current information
+- Extract content from webpages
+- Run Python code in a persistent REPL environment
+- Make decisions based on concrete results
+- Adapt plans based on observed outcomes
+
+Operating principles:
+- Test assumptions with direct observations
+- Base decisions on command outputs and results
+- Document actions and outcomes clearly
+- Use straightforward approaches first
+- Revise methods based on actual results
+- Maintain focus on primary objective
+- Stick to simple text - avoid Markdown formatting
+- Be precise with names and paths
+- Verify the contents of files you create
+- End the loop when satisfied with the result
+- When creating CSV files, avoid commas inside numeric values
+- Use python_repl for data processing and analysis tasks
+
+IMPORTANT: Save ALL generated files (images, CSVs, PDFs, LaTeX, etc.) in the 'assets/' folder.
+When using python_repl, save files to 'assets/' directory (e.g., 'assets/chart.png', 'assets/report.tex').
+When using run_command, prefix file paths with 'assets/' (e.g., 'cat > assets/data.csv').
+"""
+
+
+def validate_config() -> list[str]:
+ """Validate required configuration. Returns list of missing/invalid settings."""
+ issues = []
+
+ if not TAVILY_API_KEY:
+ issues.append("TAVILY_API_KEY is not set")
+
+ if not API_BASE_URL:
+ issues.append("API_BASE_URL is not set")
+
+ return issues
+
diff --git a/src/agent/core.py b/src/agent/core.py
new file mode 100644
index 0000000..5cb9afd
--- /dev/null
+++ b/src/agent/core.py
@@ -0,0 +1,168 @@
+"""
+Core agent implementation with tool-calling loop.
+"""
+
+import json
+from typing import Optional
+from openai import OpenAI
+from termcolor import colored
+
+from .config import API_BASE_URL, API_KEY, MODEL_NAME, AGENT_PROMPT, MAX_ITERATIONS
+from .loader import Loader
+from .trajectory import TrajectoryLogger
+from .tools import TOOL_DEFINITIONS, execute_tool
+
+
+class Agent:
+ """AI Agent with tool-calling capabilities."""
+
+ def __init__(
+ self,
+ system_prompt: str = AGENT_PROMPT,
+ max_iterations: int = MAX_ITERATIONS,
+ ):
+ self.client = OpenAI(api_key=API_KEY, base_url=API_BASE_URL)
+ self.system_prompt = system_prompt
+ self.max_iterations = max_iterations
+ self.loader = Loader()
+
+ def run(self, task: str, verbose: bool = True) -> str:
+ """
+ Run the agent on a given task.
+
+ Args:
+ task: The task description for the agent to complete.
+ verbose: Whether to print progress to console.
+
+ Returns:
+ Path to the saved trajectory log.
+ """
+ logger = TrajectoryLogger(task)
+ messages = [
+ {"role": "system", "content": self.system_prompt},
+ {"role": "user", "content": task},
+ ]
+
+ for iteration in range(1, self.max_iterations + 1):
+ if verbose:
+ self._print_iteration_header(iteration)
+ logger.log_iteration_start(iteration)
+
+ self.loader.start()
+ try:
+ response = self.client.chat.completions.create(
+ model=MODEL_NAME,
+ messages=messages,
+ tools=TOOL_DEFINITIONS,
+ tool_choice="auto"
+ )
+ finally:
+ self.loader.stop()
+
+ message = response.choices[0].message
+
+ if message.content:
+ if verbose:
+ self._print_assistant_message(message.content)
+ logger.log_assistant_message(message.content)
+
+ if message.tool_calls:
+ messages.append(self._format_tool_call_message(message))
+ self._process_tool_calls(message.tool_calls, messages, logger, verbose)
+ else:
+ messages.append({"role": "assistant", "content": message.content})
+
+ if self._is_task_complete(message.content):
+ if verbose:
+ print(colored("\n✅ Task appears complete!", "green"))
+ logger.log_completion("Task completed successfully")
+ break
+
+ if verbose:
+ self._print_completion_header()
+
+ filepath = logger.save()
+ if verbose:
+ print(colored(f"📝 Trajectory saved to: {filepath}", "cyan"))
+
+ return filepath
+
+ def _process_tool_calls(
+ self,
+ tool_calls,
+ messages: list,
+ logger: TrajectoryLogger,
+ verbose: bool
+ ) -> None:
+ """Process and execute tool calls."""
+ for tool_call in tool_calls:
+ tool_name = tool_call.function.name
+ arguments = json.loads(tool_call.function.arguments)
+
+ if verbose:
+ print(colored(f"\n📞 Calling tool: {tool_name}", "magenta"))
+ print(colored(f" Arguments: {arguments}", "magenta"))
+ logger.log_tool_call(tool_name, arguments)
+
+ result = execute_tool(tool_name, arguments)
+
+ if verbose:
+ print(colored("\n📋 Tool result:", "blue"))
+ display_result = result[:1000] + "..." if len(result) > 1000 else result
+ print(colored(display_result, "white"))
+ logger.log_tool_result(tool_name, result)
+
+ messages.append({
+ "role": "tool",
+ "tool_call_id": tool_call.id,
+ "content": result
+ })
+
+ @staticmethod
+ def _format_tool_call_message(message) -> dict:
+ """Format assistant message with tool calls."""
+ return {
+ "role": "assistant",
+ "content": message.content,
+ "tool_calls": [
+ {
+ "id": tc.id,
+ "type": "function",
+ "function": {
+ "name": tc.function.name,
+ "arguments": tc.function.arguments
+ }
+ }
+ for tc in message.tool_calls
+ ]
+ }
+
+ @staticmethod
+ def _is_task_complete(content: Optional[str]) -> bool:
+ """Check if task completion indicators are present."""
+ if not content:
+ return False
+ content_lower = content.lower()
+ return (
+ "complete" in content_lower or
+ "finished" in content_lower or
+ ("created" in content_lower and "csv" in content_lower)
+ )
+
+ @staticmethod
+ def _print_iteration_header(iteration: int) -> None:
+ print(colored(f"\n{'=' * 60}", "yellow"))
+ print(colored(f"Iteration {iteration}", "yellow"))
+ print(colored(f"{'=' * 60}\n", "yellow"))
+
+ @staticmethod
+ def _print_completion_header() -> None:
+ print(colored(f"\n{'=' * 60}", "yellow"))
+ print(colored("Agent loop finished", "yellow"))
+ print(colored(f"{'=' * 60}\n", "yellow"))
+
+ @staticmethod
+ def _print_assistant_message(content: str) -> None:
+ print(colored("Assistant:", "green"))
+ print(colored(content, "cyan"))
+
diff --git a/src/agent/loader.py b/src/agent/loader.py
new file mode 100644
index 0000000..0a92f5a
--- /dev/null
+++ b/src/agent/loader.py
@@ -0,0 +1,46 @@
+"""
+Loading animation for agent thinking time.
+"""
+
+import sys
+import time
+import threading
+from termcolor import colored
+
+
+class Loader:
+ """Animated loading indicator."""
+
+ ANIMATION_CHARS = "⠋⠙⠹⠸⠼⠴⠦⠧⠇⠏"
+
+ def __init__(self):
+ self._running = False
+ self._thread = None
+ self._start_time = 0
+
+ def _animate(self) -> None:
+ """Animation loop."""
+ i = 0
+ while self._running:
+ elapsed = time.time() - self._start_time
+ frame = self.ANIMATION_CHARS[i % len(self.ANIMATION_CHARS)]
+ sys.stdout.write(f'\r{colored(f"{frame} 🐝 👁️ Thinking... ({elapsed:.1f}s)", "magenta")}')
+ sys.stdout.flush()
+ time.sleep(0.1)
+ i += 1
+
+ def start(self) -> None:
+ """Start the loading animation."""
+ self._running = True
+ self._start_time = time.time()
+ self._thread = threading.Thread(target=self._animate, daemon=True)
+ self._thread.start()
+
+ def stop(self) -> None:
+ """Stop the loading animation."""
+ self._running = False
+ if self._thread:
+ self._thread.join(timeout=0.5)
+ sys.stdout.write('\r\n')
+ sys.stdout.flush()
+
diff --git a/src/agent/tools/__init__.py b/src/agent/tools/__init__.py
new file mode 100644
index 0000000..abf834f
--- /dev/null
+++ b/src/agent/tools/__init__.py
@@ -0,0 +1,106 @@
+"""
+Agent tools for interacting with the environment.
+"""
+
+from .web_search import web_search
+from .webpage import get_webpage
+from .command import run_command
+from .repl import python_repl, reset_repl
+
+TOOL_DEFINITIONS = [
+ {
+ "type": "function",
+ "function": {
+ "name": "web_search",
+ "description": "Search the web for information using Tavily. Use this to find current information about any topic.",
+ "parameters": {
+ "type": "object",
+ "properties": {
+ "query": {
+ "type": "string",
+ "description": "The search query to look up on the web"
+ }
+ },
+ "required": ["query"]
+ }
+ }
+ },
+ {
+ "type": "function",
+ "function": {
+ "name": "get_webpage",
+ "description": "Scrape and extract content from a specific URL. Use this to get detailed information from a webpage.",
+ "parameters": {
+ "type": "object",
+ "properties": {
+ "url": {
+ "type": "string",
+ "description": "The URL of the webpage to scrape"
+ }
+ },
+ "required": ["url"]
+ }
+ }
+ },
+ {
+ "type": "function",
+ "function": {
+ "name": "run_command",
+ "description": "Execute a shell command in the UNIX environment. Use this to create files, run scripts, or interact with the system.",
+ "parameters": {
+ "type": "object",
+ "properties": {
+ "command": {
+ "type": "string",
+ "description": "The shell command to execute"
+ }
+ },
+ "required": ["command"]
+ }
+ }
+ },
+ {
+ "type": "function",
+ "function": {
+ "name": "python_repl",
+ "description": "Execute Python code in an interactive REPL environment. Variables and imports persist between calls. Use this for data processing, calculations, creating files programmatically, or any Python task.",
+ "parameters": {
+ "type": "object",
+ "properties": {
+ "code": {
+ "type": "string",
+ "description": "The Python code to execute. Can be multi-line. Variables defined will persist for future calls."
+ }
+ },
+ "required": ["code"]
+ }
+ }
+ }
+]
+
+TOOL_REGISTRY = {
+ "web_search": web_search,
+ "get_webpage": get_webpage,
+ "run_command": run_command,
+ "python_repl": python_repl,
+}
+
+
+def execute_tool(tool_name: str, arguments: dict) -> str:
+ """Execute a tool by name with given arguments."""
+ if tool_name not in TOOL_REGISTRY:
+ return f"Unknown tool: {tool_name}"
+ return TOOL_REGISTRY[tool_name](**arguments)
+
+
+__all__ = [
+ "TOOL_DEFINITIONS",
+ "TOOL_REGISTRY",
+ "execute_tool",
+ "web_search",
+ "get_webpage",
+ "run_command",
+ "python_repl",
+ "reset_repl",
+]
+
diff --git a/src/agent/tools/command.py b/src/agent/tools/command.py
new file mode 100644
index 0000000..415d265
--- /dev/null
+++ b/src/agent/tools/command.py
@@ -0,0 +1,44 @@
+"""
+Shell command execution tool.
+"""
+
+import subprocess
+
+from ..config import COMMAND_TIMEOUT, BASE_DIR
+
+
+def run_command(command: str) -> str:
+ """
+ Execute a shell command.
+
+ Args:
+ command: Shell command to execute.
+
+ Returns:
+ Command output (stdout, stderr, exit code).
+ """
+ try:
+ result = subprocess.run(
+ command,
+ shell=True,
+ capture_output=True,
+ text=True,
+ timeout=COMMAND_TIMEOUT,
+ cwd=str(BASE_DIR)
+ )
+
+ output_parts = []
+ if result.stdout:
+ output_parts.append(f"STDOUT:\n{result.stdout}")
+ if result.stderr:
+ output_parts.append(f"STDERR:\n{result.stderr}")
+ output_parts.append(f"Exit code: {result.returncode}")
+
+ output = "\n".join(output_parts)
+ return output if output.strip() else "Command executed successfully (no output)"
+
+ except subprocess.TimeoutExpired:
+ return f"Error: Command timed out after {COMMAND_TIMEOUT} seconds"
+ except Exception as e:
+ return f"Error executing command: {str(e)}"
+
diff --git a/src/agent/tools/repl.py b/src/agent/tools/repl.py
new file mode 100644
index 0000000..227bf76
--- /dev/null
+++ b/src/agent/tools/repl.py
@@ -0,0 +1,72 @@
+"""
+Persistent Python REPL tool.
+"""
+
+import io
+import contextlib
+import traceback
+
+from ..config import ASSETS_DIR
+
+_globals = {"__builtins__": __builtins__}
+_locals = {"ASSETS_DIR": str(ASSETS_DIR)}
+
+
+def python_repl(code: str) -> str:
+ """
+ Execute Python code in a persistent REPL environment.
+
+ Args:
+ code: Python code to execute.
+
+ Returns:
+ Execution result, output, or error message.
+ """
+ global _globals, _locals
+
+ stdout_capture = io.StringIO()
+ stderr_capture = io.StringIO()
+ result_parts = []
+
+ try:
+ with contextlib.redirect_stdout(stdout_capture), contextlib.redirect_stderr(stderr_capture):
+ try:
+ compiled = compile(code, "", "eval")
+ result = eval(compiled, _globals, _locals)
+ if result is not None:
+ result_parts.append(f"Result: {repr(result)}")
+ except SyntaxError:
+ exec(code, _globals, _locals)
+
+ stdout_output = stdout_capture.getvalue()
+ stderr_output = stderr_capture.getvalue()
+
+ if stdout_output:
+ result_parts.append(f"Output:\n{stdout_output}")
+ if stderr_output:
+ result_parts.append(f"Stderr:\n{stderr_output}")
+
+ if not result_parts:
+ result_parts.append("Code executed successfully (no output)")
+
+ user_vars = {
+ k: type(v).__name__
+ for k, v in _locals.items()
+ if not k.startswith("_") and k != "ASSETS_DIR"
+ }
+ if user_vars:
+ result_parts.append(f"\nDefined variables: {user_vars}")
+
+ except Exception:
+ error_msg = traceback.format_exc()
+ result_parts.append(f"Error:\n{error_msg}")
+
+ return "\n".join(result_parts)
+
+
+def reset_repl() -> None:
+ """Reset the REPL environment to initial state."""
+ global _globals, _locals
+ _globals = {"__builtins__": __builtins__}
+ _locals = {"ASSETS_DIR": str(ASSETS_DIR)}
+
diff --git a/src/agent/tools/web_search.py b/src/agent/tools/web_search.py
new file mode 100644
index 0000000..40aa928
--- /dev/null
+++ b/src/agent/tools/web_search.py
@@ -0,0 +1,61 @@
+"""
+Web search tool using Tavily API.
+"""
+
+import json
+import requests
+
+from ..config import TAVILY_API_KEY, TAVILY_SEARCH_URL
+
+
+def web_search(query: str) -> str:
+ """
+ Search the web for information.
+
+ Args:
+ query: Search query string.
+
+ Returns:
+ Formatted search results.
+ """
+ if not TAVILY_API_KEY:
+ return "Error: TAVILY_API_KEY is not configured"
+
+ payload = json.dumps({
+ "query": query,
+ "search_depth": "basic",
+ "include_answer": True,
+ "include_raw_content": False,
+ "max_results": 5
+ })
+
+ headers = {
+ "Authorization": f"Bearer {TAVILY_API_KEY}",
+ "Content-Type": "application/json"
+ }
+
+ try:
+ response = requests.post(TAVILY_SEARCH_URL, headers=headers, data=payload, timeout=30)
+ response.raise_for_status()
+ data = response.json()
+
+ result = []
+ if "answer" in data:
+ result.append(f"Answer: {data['answer']}\n")
+
+ if "results" in data:
+ result.append("Search Results:")
+ for i, r in enumerate(data["results"], 1):
+ result.append(f"\n{i}. {r.get('title', 'No title')}")
+ result.append(f" URL: {r.get('url', 'No URL')}")
+ result.append(f" {r.get('content', 'No content')[:500]}")
+
+ return "\n".join(result) if result else "No results found"
+
+ except requests.exceptions.Timeout:
+ return "Error: Search request timed out"
+ except requests.exceptions.RequestException as e:
+ return f"Error searching: {str(e)}"
+ except json.JSONDecodeError:
+ return "Error: Invalid response from search API"
+
diff --git a/src/agent/tools/webpage.py b/src/agent/tools/webpage.py
new file mode 100644
index 0000000..c329891
--- /dev/null
+++ b/src/agent/tools/webpage.py
@@ -0,0 +1,53 @@
+"""
+Webpage extraction tool using Tavily API.
+"""
+
+import json
+import requests
+
+from ..config import TAVILY_API_KEY, TAVILY_EXTRACT_URL, MAX_CONTENT_LENGTH
+
+
+def get_webpage(url: str) -> str:
+ """
+ Extract content from a webpage.
+
+ Args:
+ url: URL of the webpage to extract.
+
+ Returns:
+ Extracted webpage content.
+ """
+ if not TAVILY_API_KEY:
+ return "Error: TAVILY_API_KEY is not configured"
+
+ payload = json.dumps({"urls": [url]})
+
+ headers = {
+ "Authorization": f"Bearer {TAVILY_API_KEY}",
+ "Content-Type": "application/json"
+ }
+
+ try:
+ response = requests.post(TAVILY_EXTRACT_URL, headers=headers, data=payload, timeout=30)
+ response.raise_for_status()
+ data = response.json()
+
+ if "results" in data and data["results"]:
+ result = data["results"][0]
+ content = result.get("raw_content", "No content")
+
+ if len(content) > MAX_CONTENT_LENGTH:
+ content = content[:MAX_CONTENT_LENGTH] + "...[truncated]"
+
+ return f"URL: {result.get('url', url)}\n\nContent:\n{content}"
+
+ return "No content extracted from URL"
+
+ except requests.exceptions.Timeout:
+ return "Error: Request timed out"
+ except requests.exceptions.RequestException as e:
+ return f"Error fetching webpage: {str(e)}"
+ except json.JSONDecodeError:
+ return "Error: Invalid response from extract API"
+
diff --git a/src/agent/trajectory.py b/src/agent/trajectory.py
new file mode 100644
index 0000000..fd72685
--- /dev/null
+++ b/src/agent/trajectory.py
@@ -0,0 +1,146 @@
+"""
+Trajectory logging for agent runs.
+"""
+
+import json
+from datetime import datetime
+from pathlib import Path
+from typing import Any
+
+from .config import OUTPUT_DIR
+
+
+class TrajectoryLogger:
+ """Logs agent trajectory for analysis and debugging."""
+
+ def __init__(self, task: str):
+ self.task = task
+ self.start_time = datetime.now()
+ self.end_time = None
+ self.steps = []
+ self._current_iteration = 0
+
+ def log_iteration_start(self, iteration: int) -> None:
+ """Log the start of a new iteration."""
+ self._current_iteration = iteration
+ self.steps.append({
+ "type": "iteration_start",
+ "iteration": iteration,
+ "timestamp": datetime.now().isoformat()
+ })
+
+ def log_assistant_message(self, content: str) -> None:
+ """Log an assistant message."""
+ self.steps.append({
+ "type": "assistant_message",
+ "content": content,
+ "timestamp": datetime.now().isoformat()
+ })
+
+ def log_tool_call(self, tool_name: str, arguments: dict[str, Any]) -> None:
+ """Log a tool call."""
+ self.steps.append({
+ "type": "tool_call",
+ "tool": tool_name,
+ "arguments": arguments,
+ "timestamp": datetime.now().isoformat()
+ })
+
+ def log_tool_result(self, tool_name: str, result: str) -> None:
+ """Log a tool result."""
+ self.steps.append({
+ "type": "tool_result",
+ "tool": tool_name,
+ "result": result[:2000] if len(result) > 2000 else result,
+ "truncated": len(result) > 2000,
+ "timestamp": datetime.now().isoformat()
+ })
+
+ def log_completion(self, message: str) -> None:
+ """Log task completion."""
+ self.steps.append({
+ "type": "completion",
+ "message": message,
+ "timestamp": datetime.now().isoformat()
+ })
+
+ def save(self) -> str:
+ """Save trajectory to file. Returns filepath."""
+ self.end_time = datetime.now()
+ timestamp = self.start_time.strftime("%Y%m%d_%H%M%S")
+ filepath = OUTPUT_DIR / f"trajectory_{timestamp}.txt"
+
+ with open(filepath, "w") as f:
+ f.write(self._format_text_report())
+
+ return str(filepath)
+
+ def _format_text_report(self) -> str:
+ """Format trajectory as readable text report."""
+ lines = [
+ "=" * 70,
+ "AGENT TRAJECTORY LOG",
+ "=" * 70,
+ "",
+ f"Start Time: {self.start_time.strftime('%Y-%m-%d %H:%M:%S')}",
+ f"End Time: {self.end_time.strftime('%Y-%m-%d %H:%M:%S') if self.end_time else 'N/A'}",
+ ]
+
+ if self.start_time and self.end_time:
+ duration = (self.end_time - self.start_time).total_seconds()
+ lines.append(f"Duration: {duration:.2f} seconds")
+
+ lines.extend([
+ "",
+ "-" * 70,
+ "TASK:",
+ "-" * 70,
+ self.task,
+ "",
+ "-" * 70,
+ "TRAJECTORY:",
+ "-" * 70,
+ ""
+ ])
+
+ for step in self.steps:
+ step_type = step["type"]
+ timestamp = step.get("timestamp", "")
+ time_str = timestamp.split("T")[1][:8] if "T" in timestamp else ""
+
+ if step_type == "iteration_start":
+ lines.extend([
+ "=" * 70,
+ f"ITERATION {step['iteration']}",
+ "=" * 70,
+ ""
+ ])
+ elif step_type == "assistant_message":
+ lines.extend([
+ f"[{time_str}] ASSISTANT:",
+ step["content"],
+ ""
+ ])
+ elif step_type == "tool_call":
+ lines.extend([
+ f"[{time_str}] TOOL CALL: {step['tool']}",
+ f"Arguments: {step['arguments']}",
+ ""
+ ])
+ elif step_type == "tool_result":
+ lines.extend([
+ f"[{time_str}] TOOL RESULT ({step['tool']}):",
+ step["result"],
+ ""
+ ])
+ elif step_type == "completion":
+ lines.extend([
+ "",
+ "=" * 70,
+ f"COMPLETED: {step['message']}",
+ "=" * 70,
+ ""
+ ])
+
+ return "\n".join(lines)
+
diff --git a/tasks/__init__.py b/tasks/__init__.py
new file mode 100644
index 0000000..b1dd0b5
--- /dev/null
+++ b/tasks/__init__.py
@@ -0,0 +1,163 @@
+"""
+Predefined task templates for the agent.
+"""
+
+TASKS = {
+ "ai_industry": {
+ "name": "AI Industry Report",
+ "prompt": """
+Analyze the top 10 AI companies by market cap, including their key products, revenue growth, and R&D spending.
+Create visualizations comparing their AI capabilities, market positions, and financial metrics.
+Generate a "State of AI Industry" investment research report in LaTeX with:
+- Executive Summary
+- Market Overview
+- Company Profiles (top 10)
+- Comparative Analysis with charts
+- Investment Outlook
+- Conclusions
+Save all files (charts, CSV data, LaTeX report) to the assets/ai_industry/ folder.
+"""
+ },
+
+ "clean_energy": {
+ "name": "Clean Energy Report",
+ "prompt": """
+Research the top 10 countries by renewable energy adoption (solar, wind, hydro).
+Gather data on energy mix percentages, carbon emissions reduction, investment trends, and policy frameworks.
+Create a "Global Clean Energy Transition Report" in LaTeX with:
+- Executive Summary
+- Global Renewable Energy Overview
+- Country-by-Country Analysis (top 10)
+- Comparative visualizations (energy mix, investment, emissions)
+- Policy Recommendations
+- Future Outlook
+Save all files to the assets/clean_energy/ folder.
+"""
+ },
+
+ "football_business": {
+ "name": "Football Business Report",
+ "prompt": """
+Analyze the top 10 football (soccer) clubs by revenue.
+Gather data on revenue breakdown, transfer spending, trophy count, stadium capacity, and social media following.
+Create a "Football Business Intelligence Report" in LaTeX with:
+- Executive Summary
+- Industry Overview
+- Club Profiles (top 10)
+- Financial Analysis with charts
+- Performance vs Investment correlation
+- Market Trends and Outlook
+Save all files to the assets/football_business/ folder.
+"""
+ },
+
+ "pharma_industry": {
+ "name": "Pharmaceutical Report",
+ "prompt": """
+Research the top 10 pharmaceutical companies by revenue.
+Gather data on R&D expenditure, drug pipelines, patent expirations, and market share in therapeutic areas.
+Create a "Pharmaceutical Industry Outlook" report in LaTeX with:
+- Executive Summary
+- Industry Overview
+- Company Profiles (top 10)
+- Pipeline Analysis with visualizations
+- Patent Cliff Analysis
+- Investment Implications
+Save all files to the assets/pharma_industry/ folder.
+"""
+ },
+
+ "real_estate": {
+ "name": "Real Estate Report",
+ "prompt": """
+Analyze the top 10 most expensive real estate markets globally.
+Gather data on median home prices, price-to-income ratios, rental yields, and year-over-year changes.
+Create a "Global Property Market Analysis" in LaTeX with:
+- Executive Summary
+- Global Market Overview
+- City-by-City Analysis (top 10)
+- Affordability Analysis with charts
+- Investment Opportunities
+- Risk Assessment and Outlook
+Save all files to the assets/real_estate/ folder.
+"""
+ },
+
+ "gaming_industry": {
+ "name": "Gaming Industry Report",
+ "prompt": """
+Research the top 10 video game companies by revenue.
+Gather data on game releases, platform distribution, subscription services, and esports investments.
+Create a "Gaming Industry Deep Dive" report in LaTeX with:
+- Executive Summary
+- Industry Overview
+- Company Profiles (top 10)
+- Market Share visualizations
+- Platform and Revenue Analysis
+- Future Trends and Outlook
+Save all files to the assets/gaming_industry/ folder.
+"""
+ },
+
+ "ev_market": {
+ "name": "Electric Vehicles Report",
+ "prompt": """
+Analyze the top 10 EV manufacturers by sales volume.
+Gather data on market share, battery technology, charging infrastructure partnerships, and price points.
+Create a "Global EV Market Analysis" in LaTeX with:
+- Executive Summary
+- Market Overview
+- Manufacturer Profiles (top 10)
+- Sales and Market Share charts
+- Technology Comparison
+- Adoption Forecasts and Outlook
+Save all files to the assets/ev_market/ folder.
+"""
+ },
+
+ "crypto_market": {
+ "name": "Cryptocurrency Report",
+ "prompt": """
+Research the top 10 cryptocurrencies by market cap.
+Gather data on price performance, transaction volumes, developer activity, and institutional adoption.
+Create a "Crypto Market Intelligence Report" in LaTeX with:
+- Executive Summary
+- Market Overview
+- Cryptocurrency Profiles (top 10)
+- Performance Analysis with charts
+- Correlation and Volatility Analysis
+- Investment Outlook and Risks
+Save all files to the assets/crypto_market/ folder.
+"""
+ },
+
+ "macroeconomics": {
+ "name": "Macroeconomics Report",
+ "prompt": """
+Gather comprehensive data on the top 10 economies by GDP (including GDP, GDP growth rate, inflation, unemployment).
+Create data analysis charts (bar charts, comparisons) and save them as PNG files.
+Write a structured macroeconomic analysis report covering:
+- Executive Summary
+- Global Economic Overview
+- Analysis of Top 10 Economies (individual country insights)
+- Comparative Analysis (charts embedded)
+- Economic Perspectives and Outlook
+- Conclusions
+Output the report as a LaTeX document (.tex file) with the charts properly included.
+Save all files to the assets/macroeconomics/ folder.
+"""
+ },
+}
+
+
+def get_task(task_id: str) -> dict:
+ """Get a task by ID."""
+ if task_id not in TASKS:
+ raise ValueError(f"Unknown task: {task_id}. Available: {list(TASKS.keys())}")
+ return TASKS[task_id]
+
+
+def list_tasks() -> list[str]:
+ """List all available task IDs."""
+ return list(TASKS.keys())
+
diff --git a/uv.lock b/uv.lock
index 75c3954..af567e8 100644
--- a/uv.lock
+++ b/uv.lock
@@ -1,13 +1,18 @@
version = 1
-requires-python = ">=3.13"
+revision = 3
+requires-python = ">=3.11"
+resolution-markers = [
+ "python_full_version >= '3.12'",
+ "python_full_version < '3.12'",
+]
[[package]]
name = "annotated-types"
version = "0.7.0"
source = { registry = "https://pypi.org/simple" }
-sdist = { url = "https://files.pythonhosted.org/packages/ee/67/531ea369ba64dcff5ec9c3402f9f51bf748cec26dde048a2f973a4eea7f5/annotated_types-0.7.0.tar.gz", hash = "sha256:aff07c09a53a08bc8cfccb9c85b05f1aa9a2a6f23728d790723543408344ce89", size = 16081 }
+sdist = { url = "https://files.pythonhosted.org/packages/ee/67/531ea369ba64dcff5ec9c3402f9f51bf748cec26dde048a2f973a4eea7f5/annotated_types-0.7.0.tar.gz", hash = "sha256:aff07c09a53a08bc8cfccb9c85b05f1aa9a2a6f23728d790723543408344ce89", size = 16081, upload-time = "2024-05-20T21:33:25.928Z" }
wheels = [
- { url = "https://files.pythonhosted.org/packages/78/b6/6307fbef88d9b5ee7421e68d78a9f162e0da4900bc5f5793f6d3d0e34fb8/annotated_types-0.7.0-py3-none-any.whl", hash = "sha256:1f02e8b43a8fbbc3f3e0d4f0f4bfc8131bcb4eebe8849b8e5c773f3a1c582a53", size = 13643 },
+ { url = "https://files.pythonhosted.org/packages/78/b6/6307fbef88d9b5ee7421e68d78a9f162e0da4900bc5f5793f6d3d0e34fb8/annotated_types-0.7.0-py3-none-any.whl", hash = "sha256:1f02e8b43a8fbbc3f3e0d4f0f4bfc8131bcb4eebe8849b8e5c773f3a1c582a53", size = 13643, upload-time = "2024-05-20T21:33:24.1Z" },
]
[[package]]
@@ -17,68 +22,376 @@ source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "idna" },
{ name = "sniffio" },
+ { name = "typing-extensions", marker = "python_full_version < '3.13'" },
+]
+sdist = { url = "https://files.pythonhosted.org/packages/a3/73/199a98fc2dae33535d6b8e8e6ec01f8c1d76c9adb096c6b7d64823038cde/anyio-4.8.0.tar.gz", hash = "sha256:1d9fe889df5212298c0c0723fa20479d1b94883a2df44bd3897aa91083316f7a", size = 181126, upload-time = "2025-01-05T13:13:11.095Z" }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/46/eb/e7f063ad1fec6b3178a3cd82d1a3c4de82cccf283fc42746168188e1cdd5/anyio-4.8.0-py3-none-any.whl", hash = "sha256:b5011f270ab5eb0abf13385f851315585cc37ef330dd88e27ec3d34d651fd47a", size = 96041, upload-time = "2025-01-05T13:13:07.985Z" },
+]
+
+[[package]]
+name = "black"
+version = "25.12.0"
+source = { registry = "https://pypi.org/simple" }
+dependencies = [
+ { name = "click" },
+ { name = "mypy-extensions" },
+ { name = "packaging" },
+ { name = "pathspec" },
+ { name = "platformdirs" },
+ { name = "pytokens" },
]
-sdist = { url = "https://files.pythonhosted.org/packages/a3/73/199a98fc2dae33535d6b8e8e6ec01f8c1d76c9adb096c6b7d64823038cde/anyio-4.8.0.tar.gz", hash = "sha256:1d9fe889df5212298c0c0723fa20479d1b94883a2df44bd3897aa91083316f7a", size = 181126 }
+sdist = { url = "https://files.pythonhosted.org/packages/c4/d9/07b458a3f1c525ac392b5edc6b191ff140b596f9d77092429417a54e249d/black-25.12.0.tar.gz", hash = "sha256:8d3dd9cea14bff7ddc0eb243c811cdb1a011ebb4800a5f0335a01a68654796a7", size = 659264, upload-time = "2025-12-08T01:40:52.501Z" }
wheels = [
- { url = "https://files.pythonhosted.org/packages/46/eb/e7f063ad1fec6b3178a3cd82d1a3c4de82cccf283fc42746168188e1cdd5/anyio-4.8.0-py3-none-any.whl", hash = "sha256:b5011f270ab5eb0abf13385f851315585cc37ef330dd88e27ec3d34d651fd47a", size = 96041 },
+ { url = "https://files.pythonhosted.org/packages/60/ad/7ac0d0e1e0612788dbc48e62aef8a8e8feffac7eb3d787db4e43b8462fa8/black-25.12.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:d0cfa263e85caea2cff57d8f917f9f51adae8e20b610e2b23de35b5b11ce691a", size = 1877003, upload-time = "2025-12-08T01:43:29.967Z" },
+ { url = "https://files.pythonhosted.org/packages/e8/dd/a237e9f565f3617a88b49284b59cbca2a4f56ebe68676c1aad0ce36a54a7/black-25.12.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:1a2f578ae20c19c50a382286ba78bfbeafdf788579b053d8e4980afb079ab9be", size = 1712639, upload-time = "2025-12-08T01:52:46.756Z" },
+ { url = "https://files.pythonhosted.org/packages/12/80/e187079df1ea4c12a0c63282ddd8b81d5107db6d642f7d7b75a6bcd6fc21/black-25.12.0-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:d3e1b65634b0e471d07ff86ec338819e2ef860689859ef4501ab7ac290431f9b", size = 1758143, upload-time = "2025-12-08T01:45:29.137Z" },
+ { url = "https://files.pythonhosted.org/packages/93/b5/3096ccee4f29dc2c3aac57274326c4d2d929a77e629f695f544e159bfae4/black-25.12.0-cp311-cp311-win_amd64.whl", hash = "sha256:a3fa71e3b8dd9f7c6ac4d818345237dfb4175ed3bf37cd5a581dbc4c034f1ec5", size = 1420698, upload-time = "2025-12-08T01:45:53.379Z" },
+ { url = "https://files.pythonhosted.org/packages/7e/39/f81c0ffbc25ffbe61c7d0385bf277e62ffc3e52f5ee668d7369d9854fadf/black-25.12.0-cp311-cp311-win_arm64.whl", hash = "sha256:51e267458f7e650afed8445dc7edb3187143003d52a1b710c7321aef22aa9655", size = 1229317, upload-time = "2025-12-08T01:46:35.606Z" },
+ { url = "https://files.pythonhosted.org/packages/d1/bd/26083f805115db17fda9877b3c7321d08c647df39d0df4c4ca8f8450593e/black-25.12.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:31f96b7c98c1ddaeb07dc0f56c652e25bdedaac76d5b68a059d998b57c55594a", size = 1924178, upload-time = "2025-12-08T01:49:51.048Z" },
+ { url = "https://files.pythonhosted.org/packages/89/6b/ea00d6651561e2bdd9231c4177f4f2ae19cc13a0b0574f47602a7519b6ca/black-25.12.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:05dd459a19e218078a1f98178c13f861fe6a9a5f88fc969ca4d9b49eb1809783", size = 1742643, upload-time = "2025-12-08T01:49:59.09Z" },
+ { url = "https://files.pythonhosted.org/packages/6d/f3/360fa4182e36e9875fabcf3a9717db9d27a8d11870f21cff97725c54f35b/black-25.12.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c1f68c5eff61f226934be6b5b80296cf6939e5d2f0c2f7d543ea08b204bfaf59", size = 1800158, upload-time = "2025-12-08T01:44:27.301Z" },
+ { url = "https://files.pythonhosted.org/packages/f8/08/2c64830cb6616278067e040acca21d4f79727b23077633953081c9445d61/black-25.12.0-cp312-cp312-win_amd64.whl", hash = "sha256:274f940c147ddab4442d316b27f9e332ca586d39c85ecf59ebdea82cc9ee8892", size = 1426197, upload-time = "2025-12-08T01:45:51.198Z" },
+ { url = "https://files.pythonhosted.org/packages/d4/60/a93f55fd9b9816b7432cf6842f0e3000fdd5b7869492a04b9011a133ee37/black-25.12.0-cp312-cp312-win_arm64.whl", hash = "sha256:169506ba91ef21e2e0591563deda7f00030cb466e747c4b09cb0a9dae5db2f43", size = 1237266, upload-time = "2025-12-08T01:45:10.556Z" },
+ { url = "https://files.pythonhosted.org/packages/c8/52/c551e36bc95495d2aa1a37d50566267aa47608c81a53f91daa809e03293f/black-25.12.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:a05ddeb656534c3e27a05a29196c962877c83fa5503db89e68857d1161ad08a5", size = 1923809, upload-time = "2025-12-08T01:46:55.126Z" },
+ { url = "https://files.pythonhosted.org/packages/a0/f7/aac9b014140ee56d247e707af8db0aae2e9efc28d4a8aba92d0abd7ae9d1/black-25.12.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:9ec77439ef3e34896995503865a85732c94396edcc739f302c5673a2315e1e7f", size = 1742384, upload-time = "2025-12-08T01:49:37.022Z" },
+ { url = "https://files.pythonhosted.org/packages/74/98/38aaa018b2ab06a863974c12b14a6266badc192b20603a81b738c47e902e/black-25.12.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:0e509c858adf63aa61d908061b52e580c40eae0dfa72415fa47ac01b12e29baf", size = 1798761, upload-time = "2025-12-08T01:46:05.386Z" },
+ { url = "https://files.pythonhosted.org/packages/16/3a/a8ac542125f61574a3f015b521ca83b47321ed19bb63fe6d7560f348bfe1/black-25.12.0-cp313-cp313-win_amd64.whl", hash = "sha256:252678f07f5bac4ff0d0e9b261fbb029fa530cfa206d0a636a34ab445ef8ca9d", size = 1429180, upload-time = "2025-12-08T01:45:34.903Z" },
+ { url = "https://files.pythonhosted.org/packages/e6/2d/bdc466a3db9145e946762d52cd55b1385509d9f9004fec1c97bdc8debbfb/black-25.12.0-cp313-cp313-win_arm64.whl", hash = "sha256:bc5b1c09fe3c931ddd20ee548511c64ebf964ada7e6f0763d443947fd1c603ce", size = 1239350, upload-time = "2025-12-08T01:46:09.458Z" },
+ { url = "https://files.pythonhosted.org/packages/35/46/1d8f2542210c502e2ae1060b2e09e47af6a5e5963cb78e22ec1a11170b28/black-25.12.0-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:0a0953b134f9335c2434864a643c842c44fba562155c738a2a37a4d61f00cad5", size = 1917015, upload-time = "2025-12-08T01:53:27.987Z" },
+ { url = "https://files.pythonhosted.org/packages/41/37/68accadf977672beb8e2c64e080f568c74159c1aaa6414b4cd2aef2d7906/black-25.12.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:2355bbb6c3b76062870942d8cc450d4f8ac71f9c93c40122762c8784df49543f", size = 1741830, upload-time = "2025-12-08T01:54:36.861Z" },
+ { url = "https://files.pythonhosted.org/packages/ac/76/03608a9d8f0faad47a3af3a3c8c53af3367f6c0dd2d23a84710456c7ac56/black-25.12.0-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:9678bd991cc793e81d19aeeae57966ee02909877cb65838ccffef24c3ebac08f", size = 1791450, upload-time = "2025-12-08T01:44:52.581Z" },
+ { url = "https://files.pythonhosted.org/packages/06/99/b2a4bd7dfaea7964974f947e1c76d6886d65fe5d24f687df2d85406b2609/black-25.12.0-cp314-cp314-win_amd64.whl", hash = "sha256:97596189949a8aad13ad12fcbb4ae89330039b96ad6742e6f6b45e75ad5cfd83", size = 1452042, upload-time = "2025-12-08T01:46:13.188Z" },
+ { url = "https://files.pythonhosted.org/packages/b2/7c/d9825de75ae5dd7795d007681b752275ea85a1c5d83269b4b9c754c2aaab/black-25.12.0-cp314-cp314-win_arm64.whl", hash = "sha256:778285d9ea197f34704e3791ea9404cd6d07595745907dd2ce3da7a13627b29b", size = 1267446, upload-time = "2025-12-08T01:46:14.497Z" },
+ { url = "https://files.pythonhosted.org/packages/68/11/21331aed19145a952ad28fca2756a1433ee9308079bd03bd898e903a2e53/black-25.12.0-py3-none-any.whl", hash = "sha256:48ceb36c16dbc84062740049eef990bb2ce07598272e673c17d1a7720c71c828", size = 206191, upload-time = "2025-12-08T01:40:50.963Z" },
]
[[package]]
name = "certifi"
version = "2024.12.14"
source = { registry = "https://pypi.org/simple" }
-sdist = { url = "https://files.pythonhosted.org/packages/0f/bd/1d41ee578ce09523c81a15426705dd20969f5abf006d1afe8aeff0dd776a/certifi-2024.12.14.tar.gz", hash = "sha256:b650d30f370c2b724812bee08008be0c4163b163ddaec3f2546c1caf65f191db", size = 166010 }
+sdist = { url = "https://files.pythonhosted.org/packages/0f/bd/1d41ee578ce09523c81a15426705dd20969f5abf006d1afe8aeff0dd776a/certifi-2024.12.14.tar.gz", hash = "sha256:b650d30f370c2b724812bee08008be0c4163b163ddaec3f2546c1caf65f191db", size = 166010, upload-time = "2024-12-14T13:52:38.02Z" }
wheels = [
- { url = "https://files.pythonhosted.org/packages/a5/32/8f6669fc4798494966bf446c8c4a162e0b5d893dff088afddf76414f70e1/certifi-2024.12.14-py3-none-any.whl", hash = "sha256:1275f7a45be9464efc1173084eaa30f866fe2e47d389406136d332ed4967ec56", size = 164927 },
+ { url = "https://files.pythonhosted.org/packages/a5/32/8f6669fc4798494966bf446c8c4a162e0b5d893dff088afddf76414f70e1/certifi-2024.12.14-py3-none-any.whl", hash = "sha256:1275f7a45be9464efc1173084eaa30f866fe2e47d389406136d332ed4967ec56", size = 164927, upload-time = "2024-12-14T13:52:36.114Z" },
]
[[package]]
name = "charset-normalizer"
version = "3.4.1"
source = { registry = "https://pypi.org/simple" }
-sdist = { url = "https://files.pythonhosted.org/packages/16/b0/572805e227f01586461c80e0fd25d65a2115599cc9dad142fee4b747c357/charset_normalizer-3.4.1.tar.gz", hash = "sha256:44251f18cd68a75b56585dd00dae26183e102cd5e0f9f1466e6df5da2ed64ea3", size = 123188 }
+sdist = { url = "https://files.pythonhosted.org/packages/16/b0/572805e227f01586461c80e0fd25d65a2115599cc9dad142fee4b747c357/charset_normalizer-3.4.1.tar.gz", hash = "sha256:44251f18cd68a75b56585dd00dae26183e102cd5e0f9f1466e6df5da2ed64ea3", size = 123188, upload-time = "2024-12-24T18:12:35.43Z" }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/72/80/41ef5d5a7935d2d3a773e3eaebf0a9350542f2cab4eac59a7a4741fbbbbe/charset_normalizer-3.4.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:8bfa33f4f2672964266e940dd22a195989ba31669bd84629f05fab3ef4e2d125", size = 194995, upload-time = "2024-12-24T18:10:12.838Z" },
+ { url = "https://files.pythonhosted.org/packages/7a/28/0b9fefa7b8b080ec492110af6d88aa3dea91c464b17d53474b6e9ba5d2c5/charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:28bf57629c75e810b6ae989f03c0828d64d6b26a5e205535585f96093e405ed1", size = 139471, upload-time = "2024-12-24T18:10:14.101Z" },
+ { url = "https://files.pythonhosted.org/packages/71/64/d24ab1a997efb06402e3fc07317e94da358e2585165930d9d59ad45fcae2/charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f08ff5e948271dc7e18a35641d2f11a4cd8dfd5634f55228b691e62b37125eb3", size = 149831, upload-time = "2024-12-24T18:10:15.512Z" },
+ { url = "https://files.pythonhosted.org/packages/37/ed/be39e5258e198655240db5e19e0b11379163ad7070962d6b0c87ed2c4d39/charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:234ac59ea147c59ee4da87a0c0f098e9c8d169f4dc2a159ef720f1a61bbe27cd", size = 142335, upload-time = "2024-12-24T18:10:18.369Z" },
+ { url = "https://files.pythonhosted.org/packages/88/83/489e9504711fa05d8dde1574996408026bdbdbd938f23be67deebb5eca92/charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fd4ec41f914fa74ad1b8304bbc634b3de73d2a0889bd32076342a573e0779e00", size = 143862, upload-time = "2024-12-24T18:10:19.743Z" },
+ { url = "https://files.pythonhosted.org/packages/c6/c7/32da20821cf387b759ad24627a9aca289d2822de929b8a41b6241767b461/charset_normalizer-3.4.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:eea6ee1db730b3483adf394ea72f808b6e18cf3cb6454b4d86e04fa8c4327a12", size = 145673, upload-time = "2024-12-24T18:10:21.139Z" },
+ { url = "https://files.pythonhosted.org/packages/68/85/f4288e96039abdd5aeb5c546fa20a37b50da71b5cf01e75e87f16cd43304/charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:c96836c97b1238e9c9e3fe90844c947d5afbf4f4c92762679acfe19927d81d77", size = 140211, upload-time = "2024-12-24T18:10:22.382Z" },
+ { url = "https://files.pythonhosted.org/packages/28/a3/a42e70d03cbdabc18997baf4f0227c73591a08041c149e710045c281f97b/charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:4d86f7aff21ee58f26dcf5ae81a9addbd914115cdebcbb2217e4f0ed8982e146", size = 148039, upload-time = "2024-12-24T18:10:24.802Z" },
+ { url = "https://files.pythonhosted.org/packages/85/e4/65699e8ab3014ecbe6f5c71d1a55d810fb716bbfd74f6283d5c2aa87febf/charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:09b5e6733cbd160dcc09589227187e242a30a49ca5cefa5a7edd3f9d19ed53fd", size = 151939, upload-time = "2024-12-24T18:10:26.124Z" },
+ { url = "https://files.pythonhosted.org/packages/b1/82/8e9fe624cc5374193de6860aba3ea8070f584c8565ee77c168ec13274bd2/charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:5777ee0881f9499ed0f71cc82cf873d9a0ca8af166dfa0af8ec4e675b7df48e6", size = 149075, upload-time = "2024-12-24T18:10:30.027Z" },
+ { url = "https://files.pythonhosted.org/packages/3d/7b/82865ba54c765560c8433f65e8acb9217cb839a9e32b42af4aa8e945870f/charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:237bdbe6159cff53b4f24f397d43c6336c6b0b42affbe857970cefbb620911c8", size = 144340, upload-time = "2024-12-24T18:10:32.679Z" },
+ { url = "https://files.pythonhosted.org/packages/b5/b6/9674a4b7d4d99a0d2df9b215da766ee682718f88055751e1e5e753c82db0/charset_normalizer-3.4.1-cp311-cp311-win32.whl", hash = "sha256:8417cb1f36cc0bc7eaba8ccb0e04d55f0ee52df06df3ad55259b9a323555fc8b", size = 95205, upload-time = "2024-12-24T18:10:34.724Z" },
+ { url = "https://files.pythonhosted.org/packages/1e/ab/45b180e175de4402dcf7547e4fb617283bae54ce35c27930a6f35b6bef15/charset_normalizer-3.4.1-cp311-cp311-win_amd64.whl", hash = "sha256:d7f50a1f8c450f3925cb367d011448c39239bb3eb4117c36a6d354794de4ce76", size = 102441, upload-time = "2024-12-24T18:10:37.574Z" },
+ { url = "https://files.pythonhosted.org/packages/0a/9a/dd1e1cdceb841925b7798369a09279bd1cf183cef0f9ddf15a3a6502ee45/charset_normalizer-3.4.1-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:73d94b58ec7fecbc7366247d3b0b10a21681004153238750bb67bd9012414545", size = 196105, upload-time = "2024-12-24T18:10:38.83Z" },
+ { url = "https://files.pythonhosted.org/packages/d3/8c/90bfabf8c4809ecb648f39794cf2a84ff2e7d2a6cf159fe68d9a26160467/charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dad3e487649f498dd991eeb901125411559b22e8d7ab25d3aeb1af367df5efd7", size = 140404, upload-time = "2024-12-24T18:10:44.272Z" },
+ { url = "https://files.pythonhosted.org/packages/ad/8f/e410d57c721945ea3b4f1a04b74f70ce8fa800d393d72899f0a40526401f/charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c30197aa96e8eed02200a83fba2657b4c3acd0f0aa4bdc9f6c1af8e8962e0757", size = 150423, upload-time = "2024-12-24T18:10:45.492Z" },
+ { url = "https://files.pythonhosted.org/packages/f0/b8/e6825e25deb691ff98cf5c9072ee0605dc2acfca98af70c2d1b1bc75190d/charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2369eea1ee4a7610a860d88f268eb39b95cb588acd7235e02fd5a5601773d4fa", size = 143184, upload-time = "2024-12-24T18:10:47.898Z" },
+ { url = "https://files.pythonhosted.org/packages/3e/a2/513f6cbe752421f16d969e32f3583762bfd583848b763913ddab8d9bfd4f/charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bc2722592d8998c870fa4e290c2eec2c1569b87fe58618e67d38b4665dfa680d", size = 145268, upload-time = "2024-12-24T18:10:50.589Z" },
+ { url = "https://files.pythonhosted.org/packages/74/94/8a5277664f27c3c438546f3eb53b33f5b19568eb7424736bdc440a88a31f/charset_normalizer-3.4.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ffc9202a29ab3920fa812879e95a9e78b2465fd10be7fcbd042899695d75e616", size = 147601, upload-time = "2024-12-24T18:10:52.541Z" },
+ { url = "https://files.pythonhosted.org/packages/7c/5f/6d352c51ee763623a98e31194823518e09bfa48be2a7e8383cf691bbb3d0/charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:804a4d582ba6e5b747c625bf1255e6b1507465494a40a2130978bda7b932c90b", size = 141098, upload-time = "2024-12-24T18:10:53.789Z" },
+ { url = "https://files.pythonhosted.org/packages/78/d4/f5704cb629ba5ab16d1d3d741396aec6dc3ca2b67757c45b0599bb010478/charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:0f55e69f030f7163dffe9fd0752b32f070566451afe180f99dbeeb81f511ad8d", size = 149520, upload-time = "2024-12-24T18:10:55.048Z" },
+ { url = "https://files.pythonhosted.org/packages/c5/96/64120b1d02b81785f222b976c0fb79a35875457fa9bb40827678e54d1bc8/charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:c4c3e6da02df6fa1410a7680bd3f63d4f710232d3139089536310d027950696a", size = 152852, upload-time = "2024-12-24T18:10:57.647Z" },
+ { url = "https://files.pythonhosted.org/packages/84/c9/98e3732278a99f47d487fd3468bc60b882920cef29d1fa6ca460a1fdf4e6/charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:5df196eb874dae23dcfb968c83d4f8fdccb333330fe1fc278ac5ceeb101003a9", size = 150488, upload-time = "2024-12-24T18:10:59.43Z" },
+ { url = "https://files.pythonhosted.org/packages/13/0e/9c8d4cb99c98c1007cc11eda969ebfe837bbbd0acdb4736d228ccaabcd22/charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:e358e64305fe12299a08e08978f51fc21fac060dcfcddd95453eabe5b93ed0e1", size = 146192, upload-time = "2024-12-24T18:11:00.676Z" },
+ { url = "https://files.pythonhosted.org/packages/b2/21/2b6b5b860781a0b49427309cb8670785aa543fb2178de875b87b9cc97746/charset_normalizer-3.4.1-cp312-cp312-win32.whl", hash = "sha256:9b23ca7ef998bc739bf6ffc077c2116917eabcc901f88da1b9856b210ef63f35", size = 95550, upload-time = "2024-12-24T18:11:01.952Z" },
+ { url = "https://files.pythonhosted.org/packages/21/5b/1b390b03b1d16c7e382b561c5329f83cc06623916aab983e8ab9239c7d5c/charset_normalizer-3.4.1-cp312-cp312-win_amd64.whl", hash = "sha256:6ff8a4a60c227ad87030d76e99cd1698345d4491638dfa6673027c48b3cd395f", size = 102785, upload-time = "2024-12-24T18:11:03.142Z" },
+ { url = "https://files.pythonhosted.org/packages/38/94/ce8e6f63d18049672c76d07d119304e1e2d7c6098f0841b51c666e9f44a0/charset_normalizer-3.4.1-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:aabfa34badd18f1da5ec1bc2715cadc8dca465868a4e73a0173466b688f29dda", size = 195698, upload-time = "2024-12-24T18:11:05.834Z" },
+ { url = "https://files.pythonhosted.org/packages/24/2e/dfdd9770664aae179a96561cc6952ff08f9a8cd09a908f259a9dfa063568/charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:22e14b5d70560b8dd51ec22863f370d1e595ac3d024cb8ad7d308b4cd95f8313", size = 140162, upload-time = "2024-12-24T18:11:07.064Z" },
+ { url = "https://files.pythonhosted.org/packages/24/4e/f646b9093cff8fc86f2d60af2de4dc17c759de9d554f130b140ea4738ca6/charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8436c508b408b82d87dc5f62496973a1805cd46727c34440b0d29d8a2f50a6c9", size = 150263, upload-time = "2024-12-24T18:11:08.374Z" },
+ { url = "https://files.pythonhosted.org/packages/5e/67/2937f8d548c3ef6e2f9aab0f6e21001056f692d43282b165e7c56023e6dd/charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2d074908e1aecee37a7635990b2c6d504cd4766c7bc9fc86d63f9c09af3fa11b", size = 142966, upload-time = "2024-12-24T18:11:09.831Z" },
+ { url = "https://files.pythonhosted.org/packages/52/ed/b7f4f07de100bdb95c1756d3a4d17b90c1a3c53715c1a476f8738058e0fa/charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:955f8851919303c92343d2f66165294848d57e9bba6cf6e3625485a70a038d11", size = 144992, upload-time = "2024-12-24T18:11:12.03Z" },
+ { url = "https://files.pythonhosted.org/packages/96/2c/d49710a6dbcd3776265f4c923bb73ebe83933dfbaa841c5da850fe0fd20b/charset_normalizer-3.4.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:44ecbf16649486d4aebafeaa7ec4c9fed8b88101f4dd612dcaf65d5e815f837f", size = 147162, upload-time = "2024-12-24T18:11:13.372Z" },
+ { url = "https://files.pythonhosted.org/packages/b4/41/35ff1f9a6bd380303dea55e44c4933b4cc3c4850988927d4082ada230273/charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:0924e81d3d5e70f8126529951dac65c1010cdf117bb75eb02dd12339b57749dd", size = 140972, upload-time = "2024-12-24T18:11:14.628Z" },
+ { url = "https://files.pythonhosted.org/packages/fb/43/c6a0b685fe6910d08ba971f62cd9c3e862a85770395ba5d9cad4fede33ab/charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:2967f74ad52c3b98de4c3b32e1a44e32975e008a9cd2a8cc8966d6a5218c5cb2", size = 149095, upload-time = "2024-12-24T18:11:17.672Z" },
+ { url = "https://files.pythonhosted.org/packages/4c/ff/a9a504662452e2d2878512115638966e75633519ec11f25fca3d2049a94a/charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:c75cb2a3e389853835e84a2d8fb2b81a10645b503eca9bcb98df6b5a43eb8886", size = 152668, upload-time = "2024-12-24T18:11:18.989Z" },
+ { url = "https://files.pythonhosted.org/packages/6c/71/189996b6d9a4b932564701628af5cee6716733e9165af1d5e1b285c530ed/charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:09b26ae6b1abf0d27570633b2b078a2a20419c99d66fb2823173d73f188ce601", size = 150073, upload-time = "2024-12-24T18:11:21.507Z" },
+ { url = "https://files.pythonhosted.org/packages/e4/93/946a86ce20790e11312c87c75ba68d5f6ad2208cfb52b2d6a2c32840d922/charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:fa88b843d6e211393a37219e6a1c1df99d35e8fd90446f1118f4216e307e48cd", size = 145732, upload-time = "2024-12-24T18:11:22.774Z" },
+ { url = "https://files.pythonhosted.org/packages/cd/e5/131d2fb1b0dddafc37be4f3a2fa79aa4c037368be9423061dccadfd90091/charset_normalizer-3.4.1-cp313-cp313-win32.whl", hash = "sha256:eb8178fe3dba6450a3e024e95ac49ed3400e506fd4e9e5c32d30adda88cbd407", size = 95391, upload-time = "2024-12-24T18:11:24.139Z" },
+ { url = "https://files.pythonhosted.org/packages/27/f2/4f9a69cc7712b9b5ad8fdb87039fd89abba997ad5cbe690d1835d40405b0/charset_normalizer-3.4.1-cp313-cp313-win_amd64.whl", hash = "sha256:b1ac5992a838106edb89654e0aebfc24f5848ae2547d22c2c3f66454daa11971", size = 102702, upload-time = "2024-12-24T18:11:26.535Z" },
+ { url = "https://files.pythonhosted.org/packages/0e/f6/65ecc6878a89bb1c23a086ea335ad4bf21a588990c3f535a227b9eea9108/charset_normalizer-3.4.1-py3-none-any.whl", hash = "sha256:d98b1668f06378c6dbefec3b92299716b931cd4e6061f3c875a71ced1780ab85", size = 49767, upload-time = "2024-12-24T18:12:32.852Z" },
+]
+
+[[package]]
+name = "click"
+version = "8.3.1"
+source = { registry = "https://pypi.org/simple" }
+dependencies = [
+ { name = "colorama", marker = "sys_platform == 'win32'" },
+]
+sdist = { url = "https://files.pythonhosted.org/packages/3d/fa/656b739db8587d7b5dfa22e22ed02566950fbfbcdc20311993483657a5c0/click-8.3.1.tar.gz", hash = "sha256:12ff4785d337a1bb490bb7e9c2b1ee5da3112e94a8622f26a6c77f5d2fc6842a", size = 295065, upload-time = "2025-11-15T20:45:42.706Z" }
wheels = [
- { url = "https://files.pythonhosted.org/packages/38/94/ce8e6f63d18049672c76d07d119304e1e2d7c6098f0841b51c666e9f44a0/charset_normalizer-3.4.1-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:aabfa34badd18f1da5ec1bc2715cadc8dca465868a4e73a0173466b688f29dda", size = 195698 },
- { url = "https://files.pythonhosted.org/packages/24/2e/dfdd9770664aae179a96561cc6952ff08f9a8cd09a908f259a9dfa063568/charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:22e14b5d70560b8dd51ec22863f370d1e595ac3d024cb8ad7d308b4cd95f8313", size = 140162 },
- { url = "https://files.pythonhosted.org/packages/24/4e/f646b9093cff8fc86f2d60af2de4dc17c759de9d554f130b140ea4738ca6/charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8436c508b408b82d87dc5f62496973a1805cd46727c34440b0d29d8a2f50a6c9", size = 150263 },
- { url = "https://files.pythonhosted.org/packages/5e/67/2937f8d548c3ef6e2f9aab0f6e21001056f692d43282b165e7c56023e6dd/charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2d074908e1aecee37a7635990b2c6d504cd4766c7bc9fc86d63f9c09af3fa11b", size = 142966 },
- { url = "https://files.pythonhosted.org/packages/52/ed/b7f4f07de100bdb95c1756d3a4d17b90c1a3c53715c1a476f8738058e0fa/charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:955f8851919303c92343d2f66165294848d57e9bba6cf6e3625485a70a038d11", size = 144992 },
- { url = "https://files.pythonhosted.org/packages/96/2c/d49710a6dbcd3776265f4c923bb73ebe83933dfbaa841c5da850fe0fd20b/charset_normalizer-3.4.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:44ecbf16649486d4aebafeaa7ec4c9fed8b88101f4dd612dcaf65d5e815f837f", size = 147162 },
- { url = "https://files.pythonhosted.org/packages/b4/41/35ff1f9a6bd380303dea55e44c4933b4cc3c4850988927d4082ada230273/charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:0924e81d3d5e70f8126529951dac65c1010cdf117bb75eb02dd12339b57749dd", size = 140972 },
- { url = "https://files.pythonhosted.org/packages/fb/43/c6a0b685fe6910d08ba971f62cd9c3e862a85770395ba5d9cad4fede33ab/charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:2967f74ad52c3b98de4c3b32e1a44e32975e008a9cd2a8cc8966d6a5218c5cb2", size = 149095 },
- { url = "https://files.pythonhosted.org/packages/4c/ff/a9a504662452e2d2878512115638966e75633519ec11f25fca3d2049a94a/charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:c75cb2a3e389853835e84a2d8fb2b81a10645b503eca9bcb98df6b5a43eb8886", size = 152668 },
- { url = "https://files.pythonhosted.org/packages/6c/71/189996b6d9a4b932564701628af5cee6716733e9165af1d5e1b285c530ed/charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:09b26ae6b1abf0d27570633b2b078a2a20419c99d66fb2823173d73f188ce601", size = 150073 },
- { url = "https://files.pythonhosted.org/packages/e4/93/946a86ce20790e11312c87c75ba68d5f6ad2208cfb52b2d6a2c32840d922/charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:fa88b843d6e211393a37219e6a1c1df99d35e8fd90446f1118f4216e307e48cd", size = 145732 },
- { url = "https://files.pythonhosted.org/packages/cd/e5/131d2fb1b0dddafc37be4f3a2fa79aa4c037368be9423061dccadfd90091/charset_normalizer-3.4.1-cp313-cp313-win32.whl", hash = "sha256:eb8178fe3dba6450a3e024e95ac49ed3400e506fd4e9e5c32d30adda88cbd407", size = 95391 },
- { url = "https://files.pythonhosted.org/packages/27/f2/4f9a69cc7712b9b5ad8fdb87039fd89abba997ad5cbe690d1835d40405b0/charset_normalizer-3.4.1-cp313-cp313-win_amd64.whl", hash = "sha256:b1ac5992a838106edb89654e0aebfc24f5848ae2547d22c2c3f66454daa11971", size = 102702 },
- { url = "https://files.pythonhosted.org/packages/0e/f6/65ecc6878a89bb1c23a086ea335ad4bf21a588990c3f535a227b9eea9108/charset_normalizer-3.4.1-py3-none-any.whl", hash = "sha256:d98b1668f06378c6dbefec3b92299716b931cd4e6061f3c875a71ced1780ab85", size = 49767 },
+ { url = "https://files.pythonhosted.org/packages/98/78/01c019cdb5d6498122777c1a43056ebb3ebfeef2076d9d026bfe15583b2b/click-8.3.1-py3-none-any.whl", hash = "sha256:981153a64e25f12d547d3426c367a4857371575ee7ad18df2a6183ab0545b2a6", size = 108274, upload-time = "2025-11-15T20:45:41.139Z" },
]
[[package]]
name = "colorama"
version = "0.4.6"
source = { registry = "https://pypi.org/simple" }
-sdist = { url = "https://files.pythonhosted.org/packages/d8/53/6f443c9a4a8358a93a6792e2acffb9d9d5cb0a5cfd8802644b7b1c9a02e4/colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44", size = 27697 }
+sdist = { url = "https://files.pythonhosted.org/packages/d8/53/6f443c9a4a8358a93a6792e2acffb9d9d5cb0a5cfd8802644b7b1c9a02e4/colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44", size = 27697, upload-time = "2022-10-25T02:36:22.414Z" }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/d1/d6/3965ed04c63042e047cb6a3e6ed1a63a35087b6a609aa3a15ed8ac56c221/colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6", size = 25335, upload-time = "2022-10-25T02:36:20.889Z" },
+]
+
+[[package]]
+name = "contourpy"
+version = "1.3.3"
+source = { registry = "https://pypi.org/simple" }
+dependencies = [
+ { name = "numpy" },
+]
+sdist = { url = "https://files.pythonhosted.org/packages/58/01/1253e6698a07380cd31a736d248a3f2a50a7c88779a1813da27503cadc2a/contourpy-1.3.3.tar.gz", hash = "sha256:083e12155b210502d0bca491432bb04d56dc3432f95a979b429f2848c3dbe880", size = 13466174, upload-time = "2025-07-26T12:03:12.549Z" }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/91/2e/c4390a31919d8a78b90e8ecf87cd4b4c4f05a5b48d05ec17db8e5404c6f4/contourpy-1.3.3-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:709a48ef9a690e1343202916450bc48b9e51c049b089c7f79a267b46cffcdaa1", size = 288773, upload-time = "2025-07-26T12:01:02.277Z" },
+ { url = "https://files.pythonhosted.org/packages/0d/44/c4b0b6095fef4dc9c420e041799591e3b63e9619e3044f7f4f6c21c0ab24/contourpy-1.3.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:23416f38bfd74d5d28ab8429cc4d63fa67d5068bd711a85edb1c3fb0c3e2f381", size = 270149, upload-time = "2025-07-26T12:01:04.072Z" },
+ { url = "https://files.pythonhosted.org/packages/30/2e/dd4ced42fefac8470661d7cb7e264808425e6c5d56d175291e93890cce09/contourpy-1.3.3-cp311-cp311-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:929ddf8c4c7f348e4c0a5a3a714b5c8542ffaa8c22954862a46ca1813b667ee7", size = 329222, upload-time = "2025-07-26T12:01:05.688Z" },
+ { url = "https://files.pythonhosted.org/packages/f2/74/cc6ec2548e3d276c71389ea4802a774b7aa3558223b7bade3f25787fafc2/contourpy-1.3.3-cp311-cp311-manylinux_2_26_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:9e999574eddae35f1312c2b4b717b7885d4edd6cb46700e04f7f02db454e67c1", size = 377234, upload-time = "2025-07-26T12:01:07.054Z" },
+ { url = "https://files.pythonhosted.org/packages/03/b3/64ef723029f917410f75c09da54254c5f9ea90ef89b143ccadb09df14c15/contourpy-1.3.3-cp311-cp311-manylinux_2_26_s390x.manylinux_2_28_s390x.whl", hash = "sha256:0bf67e0e3f482cb69779dd3061b534eb35ac9b17f163d851e2a547d56dba0a3a", size = 380555, upload-time = "2025-07-26T12:01:08.801Z" },
+ { url = "https://files.pythonhosted.org/packages/5f/4b/6157f24ca425b89fe2eb7e7be642375711ab671135be21e6faa100f7448c/contourpy-1.3.3-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:51e79c1f7470158e838808d4a996fa9bac72c498e93d8ebe5119bc1e6becb0db", size = 355238, upload-time = "2025-07-26T12:01:10.319Z" },
+ { url = "https://files.pythonhosted.org/packages/98/56/f914f0dd678480708a04cfd2206e7c382533249bc5001eb9f58aa693e200/contourpy-1.3.3-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:598c3aaece21c503615fd59c92a3598b428b2f01bfb4b8ca9c4edeecc2438620", size = 1326218, upload-time = "2025-07-26T12:01:12.659Z" },
+ { url = "https://files.pythonhosted.org/packages/fb/d7/4a972334a0c971acd5172389671113ae82aa7527073980c38d5868ff1161/contourpy-1.3.3-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:322ab1c99b008dad206d406bb61d014cf0174df491ae9d9d0fac6a6fda4f977f", size = 1392867, upload-time = "2025-07-26T12:01:15.533Z" },
+ { url = "https://files.pythonhosted.org/packages/75/3e/f2cc6cd56dc8cff46b1a56232eabc6feea52720083ea71ab15523daab796/contourpy-1.3.3-cp311-cp311-win32.whl", hash = "sha256:fd907ae12cd483cd83e414b12941c632a969171bf90fc937d0c9f268a31cafff", size = 183677, upload-time = "2025-07-26T12:01:17.088Z" },
+ { url = "https://files.pythonhosted.org/packages/98/4b/9bd370b004b5c9d8045c6c33cf65bae018b27aca550a3f657cdc99acdbd8/contourpy-1.3.3-cp311-cp311-win_amd64.whl", hash = "sha256:3519428f6be58431c56581f1694ba8e50626f2dd550af225f82fb5f5814d2a42", size = 225234, upload-time = "2025-07-26T12:01:18.256Z" },
+ { url = "https://files.pythonhosted.org/packages/d9/b6/71771e02c2e004450c12b1120a5f488cad2e4d5b590b1af8bad060360fe4/contourpy-1.3.3-cp311-cp311-win_arm64.whl", hash = "sha256:15ff10bfada4bf92ec8b31c62bf7c1834c244019b4a33095a68000d7075df470", size = 193123, upload-time = "2025-07-26T12:01:19.848Z" },
+ { url = "https://files.pythonhosted.org/packages/be/45/adfee365d9ea3d853550b2e735f9d66366701c65db7855cd07621732ccfc/contourpy-1.3.3-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:b08a32ea2f8e42cf1d4be3169a98dd4be32bafe4f22b6c4cb4ba810fa9e5d2cb", size = 293419, upload-time = "2025-07-26T12:01:21.16Z" },
+ { url = "https://files.pythonhosted.org/packages/53/3e/405b59cfa13021a56bba395a6b3aca8cec012b45bf177b0eaf7a202cde2c/contourpy-1.3.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:556dba8fb6f5d8742f2923fe9457dbdd51e1049c4a43fd3986a0b14a1d815fc6", size = 273979, upload-time = "2025-07-26T12:01:22.448Z" },
+ { url = "https://files.pythonhosted.org/packages/d4/1c/a12359b9b2ca3a845e8f7f9ac08bdf776114eb931392fcad91743e2ea17b/contourpy-1.3.3-cp312-cp312-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:92d9abc807cf7d0e047b95ca5d957cf4792fcd04e920ca70d48add15c1a90ea7", size = 332653, upload-time = "2025-07-26T12:01:24.155Z" },
+ { url = "https://files.pythonhosted.org/packages/63/12/897aeebfb475b7748ea67b61e045accdfcf0d971f8a588b67108ed7f5512/contourpy-1.3.3-cp312-cp312-manylinux_2_26_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:b2e8faa0ed68cb29af51edd8e24798bb661eac3bd9f65420c1887b6ca89987c8", size = 379536, upload-time = "2025-07-26T12:01:25.91Z" },
+ { url = "https://files.pythonhosted.org/packages/43/8a/a8c584b82deb248930ce069e71576fc09bd7174bbd35183b7943fb1064fd/contourpy-1.3.3-cp312-cp312-manylinux_2_26_s390x.manylinux_2_28_s390x.whl", hash = "sha256:626d60935cf668e70a5ce6ff184fd713e9683fb458898e4249b63be9e28286ea", size = 384397, upload-time = "2025-07-26T12:01:27.152Z" },
+ { url = "https://files.pythonhosted.org/packages/cc/8f/ec6289987824b29529d0dfda0d74a07cec60e54b9c92f3c9da4c0ac732de/contourpy-1.3.3-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:4d00e655fcef08aba35ec9610536bfe90267d7ab5ba944f7032549c55a146da1", size = 362601, upload-time = "2025-07-26T12:01:28.808Z" },
+ { url = "https://files.pythonhosted.org/packages/05/0a/a3fe3be3ee2dceb3e615ebb4df97ae6f3828aa915d3e10549ce016302bd1/contourpy-1.3.3-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:451e71b5a7d597379ef572de31eeb909a87246974d960049a9848c3bc6c41bf7", size = 1331288, upload-time = "2025-07-26T12:01:31.198Z" },
+ { url = "https://files.pythonhosted.org/packages/33/1d/acad9bd4e97f13f3e2b18a3977fe1b4a37ecf3d38d815333980c6c72e963/contourpy-1.3.3-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:459c1f020cd59fcfe6650180678a9993932d80d44ccde1fa1868977438f0b411", size = 1403386, upload-time = "2025-07-26T12:01:33.947Z" },
+ { url = "https://files.pythonhosted.org/packages/cf/8f/5847f44a7fddf859704217a99a23a4f6417b10e5ab1256a179264561540e/contourpy-1.3.3-cp312-cp312-win32.whl", hash = "sha256:023b44101dfe49d7d53932be418477dba359649246075c996866106da069af69", size = 185018, upload-time = "2025-07-26T12:01:35.64Z" },
+ { url = "https://files.pythonhosted.org/packages/19/e8/6026ed58a64563186a9ee3f29f41261fd1828f527dd93d33b60feca63352/contourpy-1.3.3-cp312-cp312-win_amd64.whl", hash = "sha256:8153b8bfc11e1e4d75bcb0bff1db232f9e10b274e0929de9d608027e0d34ff8b", size = 226567, upload-time = "2025-07-26T12:01:36.804Z" },
+ { url = "https://files.pythonhosted.org/packages/d1/e2/f05240d2c39a1ed228d8328a78b6f44cd695f7ef47beb3e684cf93604f86/contourpy-1.3.3-cp312-cp312-win_arm64.whl", hash = "sha256:07ce5ed73ecdc4a03ffe3e1b3e3c1166db35ae7584be76f65dbbe28a7791b0cc", size = 193655, upload-time = "2025-07-26T12:01:37.999Z" },
+ { url = "https://files.pythonhosted.org/packages/68/35/0167aad910bbdb9599272bd96d01a9ec6852f36b9455cf2ca67bd4cc2d23/contourpy-1.3.3-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:177fb367556747a686509d6fef71d221a4b198a3905fe824430e5ea0fda54eb5", size = 293257, upload-time = "2025-07-26T12:01:39.367Z" },
+ { url = "https://files.pythonhosted.org/packages/96/e4/7adcd9c8362745b2210728f209bfbcf7d91ba868a2c5f40d8b58f54c509b/contourpy-1.3.3-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:d002b6f00d73d69333dac9d0b8d5e84d9724ff9ef044fd63c5986e62b7c9e1b1", size = 274034, upload-time = "2025-07-26T12:01:40.645Z" },
+ { url = "https://files.pythonhosted.org/packages/73/23/90e31ceeed1de63058a02cb04b12f2de4b40e3bef5e082a7c18d9c8ae281/contourpy-1.3.3-cp313-cp313-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:348ac1f5d4f1d66d3322420f01d42e43122f43616e0f194fc1c9f5d830c5b286", size = 334672, upload-time = "2025-07-26T12:01:41.942Z" },
+ { url = "https://files.pythonhosted.org/packages/ed/93/b43d8acbe67392e659e1d984700e79eb67e2acb2bd7f62012b583a7f1b55/contourpy-1.3.3-cp313-cp313-manylinux_2_26_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:655456777ff65c2c548b7c454af9c6f33f16c8884f11083244b5819cc214f1b5", size = 381234, upload-time = "2025-07-26T12:01:43.499Z" },
+ { url = "https://files.pythonhosted.org/packages/46/3b/bec82a3ea06f66711520f75a40c8fc0b113b2a75edb36aa633eb11c4f50f/contourpy-1.3.3-cp313-cp313-manylinux_2_26_s390x.manylinux_2_28_s390x.whl", hash = "sha256:644a6853d15b2512d67881586bd03f462c7ab755db95f16f14d7e238f2852c67", size = 385169, upload-time = "2025-07-26T12:01:45.219Z" },
+ { url = "https://files.pythonhosted.org/packages/4b/32/e0f13a1c5b0f8572d0ec6ae2f6c677b7991fafd95da523159c19eff0696a/contourpy-1.3.3-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:4debd64f124ca62069f313a9cb86656ff087786016d76927ae2cf37846b006c9", size = 362859, upload-time = "2025-07-26T12:01:46.519Z" },
+ { url = "https://files.pythonhosted.org/packages/33/71/e2a7945b7de4e58af42d708a219f3b2f4cff7386e6b6ab0a0fa0033c49a9/contourpy-1.3.3-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:a15459b0f4615b00bbd1e91f1b9e19b7e63aea7483d03d804186f278c0af2659", size = 1332062, upload-time = "2025-07-26T12:01:48.964Z" },
+ { url = "https://files.pythonhosted.org/packages/12/fc/4e87ac754220ccc0e807284f88e943d6d43b43843614f0a8afa469801db0/contourpy-1.3.3-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:ca0fdcd73925568ca027e0b17ab07aad764be4706d0a925b89227e447d9737b7", size = 1403932, upload-time = "2025-07-26T12:01:51.979Z" },
+ { url = "https://files.pythonhosted.org/packages/a6/2e/adc197a37443f934594112222ac1aa7dc9a98faf9c3842884df9a9d8751d/contourpy-1.3.3-cp313-cp313-win32.whl", hash = "sha256:b20c7c9a3bf701366556e1b1984ed2d0cedf999903c51311417cf5f591d8c78d", size = 185024, upload-time = "2025-07-26T12:01:53.245Z" },
+ { url = "https://files.pythonhosted.org/packages/18/0b/0098c214843213759692cc638fce7de5c289200a830e5035d1791d7a2338/contourpy-1.3.3-cp313-cp313-win_amd64.whl", hash = "sha256:1cadd8b8969f060ba45ed7c1b714fe69185812ab43bd6b86a9123fe8f99c3263", size = 226578, upload-time = "2025-07-26T12:01:54.422Z" },
+ { url = "https://files.pythonhosted.org/packages/8a/9a/2f6024a0c5995243cd63afdeb3651c984f0d2bc727fd98066d40e141ad73/contourpy-1.3.3-cp313-cp313-win_arm64.whl", hash = "sha256:fd914713266421b7536de2bfa8181aa8c699432b6763a0ea64195ebe28bff6a9", size = 193524, upload-time = "2025-07-26T12:01:55.73Z" },
+ { url = "https://files.pythonhosted.org/packages/c0/b3/f8a1a86bd3298513f500e5b1f5fd92b69896449f6cab6a146a5d52715479/contourpy-1.3.3-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:88df9880d507169449d434c293467418b9f6cbe82edd19284aa0409e7fdb933d", size = 306730, upload-time = "2025-07-26T12:01:57.051Z" },
+ { url = "https://files.pythonhosted.org/packages/3f/11/4780db94ae62fc0c2053909b65dc3246bd7cecfc4f8a20d957ad43aa4ad8/contourpy-1.3.3-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:d06bb1f751ba5d417047db62bca3c8fde202b8c11fb50742ab3ab962c81e8216", size = 287897, upload-time = "2025-07-26T12:01:58.663Z" },
+ { url = "https://files.pythonhosted.org/packages/ae/15/e59f5f3ffdd6f3d4daa3e47114c53daabcb18574a26c21f03dc9e4e42ff0/contourpy-1.3.3-cp313-cp313t-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:e4e6b05a45525357e382909a4c1600444e2a45b4795163d3b22669285591c1ae", size = 326751, upload-time = "2025-07-26T12:02:00.343Z" },
+ { url = "https://files.pythonhosted.org/packages/0f/81/03b45cfad088e4770b1dcf72ea78d3802d04200009fb364d18a493857210/contourpy-1.3.3-cp313-cp313t-manylinux_2_26_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:ab3074b48c4e2cf1a960e6bbeb7f04566bf36b1861d5c9d4d8ac04b82e38ba20", size = 375486, upload-time = "2025-07-26T12:02:02.128Z" },
+ { url = "https://files.pythonhosted.org/packages/0c/ba/49923366492ffbdd4486e970d421b289a670ae8cf539c1ea9a09822b371a/contourpy-1.3.3-cp313-cp313t-manylinux_2_26_s390x.manylinux_2_28_s390x.whl", hash = "sha256:6c3d53c796f8647d6deb1abe867daeb66dcc8a97e8455efa729516b997b8ed99", size = 388106, upload-time = "2025-07-26T12:02:03.615Z" },
+ { url = "https://files.pythonhosted.org/packages/9f/52/5b00ea89525f8f143651f9f03a0df371d3cbd2fccd21ca9b768c7a6500c2/contourpy-1.3.3-cp313-cp313t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:50ed930df7289ff2a8d7afeb9603f8289e5704755c7e5c3bbd929c90c817164b", size = 352548, upload-time = "2025-07-26T12:02:05.165Z" },
+ { url = "https://files.pythonhosted.org/packages/32/1d/a209ec1a3a3452d490f6b14dd92e72280c99ae3d1e73da74f8277d4ee08f/contourpy-1.3.3-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:4feffb6537d64b84877da813a5c30f1422ea5739566abf0bd18065ac040e120a", size = 1322297, upload-time = "2025-07-26T12:02:07.379Z" },
+ { url = "https://files.pythonhosted.org/packages/bc/9e/46f0e8ebdd884ca0e8877e46a3f4e633f6c9c8c4f3f6e72be3fe075994aa/contourpy-1.3.3-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:2b7e9480ffe2b0cd2e787e4df64270e3a0440d9db8dc823312e2c940c167df7e", size = 1391023, upload-time = "2025-07-26T12:02:10.171Z" },
+ { url = "https://files.pythonhosted.org/packages/b9/70/f308384a3ae9cd2209e0849f33c913f658d3326900d0ff5d378d6a1422d2/contourpy-1.3.3-cp313-cp313t-win32.whl", hash = "sha256:283edd842a01e3dcd435b1c5116798d661378d83d36d337b8dde1d16a5fc9ba3", size = 196157, upload-time = "2025-07-26T12:02:11.488Z" },
+ { url = "https://files.pythonhosted.org/packages/b2/dd/880f890a6663b84d9e34a6f88cded89d78f0091e0045a284427cb6b18521/contourpy-1.3.3-cp313-cp313t-win_amd64.whl", hash = "sha256:87acf5963fc2b34825e5b6b048f40e3635dd547f590b04d2ab317c2619ef7ae8", size = 240570, upload-time = "2025-07-26T12:02:12.754Z" },
+ { url = "https://files.pythonhosted.org/packages/80/99/2adc7d8ffead633234817ef8e9a87115c8a11927a94478f6bb3d3f4d4f7d/contourpy-1.3.3-cp313-cp313t-win_arm64.whl", hash = "sha256:3c30273eb2a55024ff31ba7d052dde990d7d8e5450f4bbb6e913558b3d6c2301", size = 199713, upload-time = "2025-07-26T12:02:14.4Z" },
+ { url = "https://files.pythonhosted.org/packages/72/8b/4546f3ab60f78c514ffb7d01a0bd743f90de36f0019d1be84d0a708a580a/contourpy-1.3.3-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:fde6c716d51c04b1c25d0b90364d0be954624a0ee9d60e23e850e8d48353d07a", size = 292189, upload-time = "2025-07-26T12:02:16.095Z" },
+ { url = "https://files.pythonhosted.org/packages/fd/e1/3542a9cb596cadd76fcef413f19c79216e002623158befe6daa03dbfa88c/contourpy-1.3.3-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:cbedb772ed74ff5be440fa8eee9bd49f64f6e3fc09436d9c7d8f1c287b121d77", size = 273251, upload-time = "2025-07-26T12:02:17.524Z" },
+ { url = "https://files.pythonhosted.org/packages/b1/71/f93e1e9471d189f79d0ce2497007731c1e6bf9ef6d1d61b911430c3db4e5/contourpy-1.3.3-cp314-cp314-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:22e9b1bd7a9b1d652cd77388465dc358dafcd2e217d35552424aa4f996f524f5", size = 335810, upload-time = "2025-07-26T12:02:18.9Z" },
+ { url = "https://files.pythonhosted.org/packages/91/f9/e35f4c1c93f9275d4e38681a80506b5510e9327350c51f8d4a5a724d178c/contourpy-1.3.3-cp314-cp314-manylinux_2_26_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:a22738912262aa3e254e4f3cb079a95a67132fc5a063890e224393596902f5a4", size = 382871, upload-time = "2025-07-26T12:02:20.418Z" },
+ { url = "https://files.pythonhosted.org/packages/b5/71/47b512f936f66a0a900d81c396a7e60d73419868fba959c61efed7a8ab46/contourpy-1.3.3-cp314-cp314-manylinux_2_26_s390x.manylinux_2_28_s390x.whl", hash = "sha256:afe5a512f31ee6bd7d0dda52ec9864c984ca3d66664444f2d72e0dc4eb832e36", size = 386264, upload-time = "2025-07-26T12:02:21.916Z" },
+ { url = "https://files.pythonhosted.org/packages/04/5f/9ff93450ba96b09c7c2b3f81c94de31c89f92292f1380261bd7195bea4ea/contourpy-1.3.3-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:f64836de09927cba6f79dcd00fdd7d5329f3fccc633468507079c829ca4db4e3", size = 363819, upload-time = "2025-07-26T12:02:23.759Z" },
+ { url = "https://files.pythonhosted.org/packages/3e/a6/0b185d4cc480ee494945cde102cb0149ae830b5fa17bf855b95f2e70ad13/contourpy-1.3.3-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:1fd43c3be4c8e5fd6e4f2baeae35ae18176cf2e5cced681cca908addf1cdd53b", size = 1333650, upload-time = "2025-07-26T12:02:26.181Z" },
+ { url = "https://files.pythonhosted.org/packages/43/d7/afdc95580ca56f30fbcd3060250f66cedbde69b4547028863abd8aa3b47e/contourpy-1.3.3-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:6afc576f7b33cf00996e5c1102dc2a8f7cc89e39c0b55df93a0b78c1bd992b36", size = 1404833, upload-time = "2025-07-26T12:02:28.782Z" },
+ { url = "https://files.pythonhosted.org/packages/e2/e2/366af18a6d386f41132a48f033cbd2102e9b0cf6345d35ff0826cd984566/contourpy-1.3.3-cp314-cp314-win32.whl", hash = "sha256:66c8a43a4f7b8df8b71ee1840e4211a3c8d93b214b213f590e18a1beca458f7d", size = 189692, upload-time = "2025-07-26T12:02:30.128Z" },
+ { url = "https://files.pythonhosted.org/packages/7d/c2/57f54b03d0f22d4044b8afb9ca0e184f8b1afd57b4f735c2fa70883dc601/contourpy-1.3.3-cp314-cp314-win_amd64.whl", hash = "sha256:cf9022ef053f2694e31d630feaacb21ea24224be1c3ad0520b13d844274614fd", size = 232424, upload-time = "2025-07-26T12:02:31.395Z" },
+ { url = "https://files.pythonhosted.org/packages/18/79/a9416650df9b525737ab521aa181ccc42d56016d2123ddcb7b58e926a42c/contourpy-1.3.3-cp314-cp314-win_arm64.whl", hash = "sha256:95b181891b4c71de4bb404c6621e7e2390745f887f2a026b2d99e92c17892339", size = 198300, upload-time = "2025-07-26T12:02:32.956Z" },
+ { url = "https://files.pythonhosted.org/packages/1f/42/38c159a7d0f2b7b9c04c64ab317042bb6952b713ba875c1681529a2932fe/contourpy-1.3.3-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:33c82d0138c0a062380332c861387650c82e4cf1747aaa6938b9b6516762e772", size = 306769, upload-time = "2025-07-26T12:02:34.2Z" },
+ { url = "https://files.pythonhosted.org/packages/c3/6c/26a8205f24bca10974e77460de68d3d7c63e282e23782f1239f226fcae6f/contourpy-1.3.3-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:ea37e7b45949df430fe649e5de8351c423430046a2af20b1c1961cae3afcda77", size = 287892, upload-time = "2025-07-26T12:02:35.807Z" },
+ { url = "https://files.pythonhosted.org/packages/66/06/8a475c8ab718ebfd7925661747dbb3c3ee9c82ac834ccb3570be49d129f4/contourpy-1.3.3-cp314-cp314t-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:d304906ecc71672e9c89e87c4675dc5c2645e1f4269a5063b99b0bb29f232d13", size = 326748, upload-time = "2025-07-26T12:02:37.193Z" },
+ { url = "https://files.pythonhosted.org/packages/b4/a3/c5ca9f010a44c223f098fccd8b158bb1cb287378a31ac141f04730dc49be/contourpy-1.3.3-cp314-cp314t-manylinux_2_26_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:ca658cd1a680a5c9ea96dc61cdbae1e85c8f25849843aa799dfd3cb370ad4fbe", size = 375554, upload-time = "2025-07-26T12:02:38.894Z" },
+ { url = "https://files.pythonhosted.org/packages/80/5b/68bd33ae63fac658a4145088c1e894405e07584a316738710b636c6d0333/contourpy-1.3.3-cp314-cp314t-manylinux_2_26_s390x.manylinux_2_28_s390x.whl", hash = "sha256:ab2fd90904c503739a75b7c8c5c01160130ba67944a7b77bbf36ef8054576e7f", size = 388118, upload-time = "2025-07-26T12:02:40.642Z" },
+ { url = "https://files.pythonhosted.org/packages/40/52/4c285a6435940ae25d7410a6c36bda5145839bc3f0beb20c707cda18b9d2/contourpy-1.3.3-cp314-cp314t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:b7301b89040075c30e5768810bc96a8e8d78085b47d8be6e4c3f5a0b4ed478a0", size = 352555, upload-time = "2025-07-26T12:02:42.25Z" },
+ { url = "https://files.pythonhosted.org/packages/24/ee/3e81e1dd174f5c7fefe50e85d0892de05ca4e26ef1c9a59c2a57e43b865a/contourpy-1.3.3-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:2a2a8b627d5cc6b7c41a4beff6c5ad5eb848c88255fda4a8745f7e901b32d8e4", size = 1322295, upload-time = "2025-07-26T12:02:44.668Z" },
+ { url = "https://files.pythonhosted.org/packages/3c/b2/6d913d4d04e14379de429057cd169e5e00f6c2af3bb13e1710bcbdb5da12/contourpy-1.3.3-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:fd6ec6be509c787f1caf6b247f0b1ca598bef13f4ddeaa126b7658215529ba0f", size = 1391027, upload-time = "2025-07-26T12:02:47.09Z" },
+ { url = "https://files.pythonhosted.org/packages/93/8a/68a4ec5c55a2971213d29a9374913f7e9f18581945a7a31d1a39b5d2dfe5/contourpy-1.3.3-cp314-cp314t-win32.whl", hash = "sha256:e74a9a0f5e3fff48fb5a7f2fd2b9b70a3fe014a67522f79b7cca4c0c7e43c9ae", size = 202428, upload-time = "2025-07-26T12:02:48.691Z" },
+ { url = "https://files.pythonhosted.org/packages/fa/96/fd9f641ffedc4fa3ace923af73b9d07e869496c9cc7a459103e6e978992f/contourpy-1.3.3-cp314-cp314t-win_amd64.whl", hash = "sha256:13b68d6a62db8eafaebb8039218921399baf6e47bf85006fd8529f2a08ef33fc", size = 250331, upload-time = "2025-07-26T12:02:50.137Z" },
+ { url = "https://files.pythonhosted.org/packages/ae/8c/469afb6465b853afff216f9528ffda78a915ff880ed58813ba4faf4ba0b6/contourpy-1.3.3-cp314-cp314t-win_arm64.whl", hash = "sha256:b7448cb5a725bb1e35ce88771b86fba35ef418952474492cf7c764059933ff8b", size = 203831, upload-time = "2025-07-26T12:02:51.449Z" },
+ { url = "https://files.pythonhosted.org/packages/a5/29/8dcfe16f0107943fa92388c23f6e05cff0ba58058c4c95b00280d4c75a14/contourpy-1.3.3-pp311-pypy311_pp73-macosx_10_15_x86_64.whl", hash = "sha256:cd5dfcaeb10f7b7f9dc8941717c6c2ade08f587be2226222c12b25f0483ed497", size = 278809, upload-time = "2025-07-26T12:02:52.74Z" },
+ { url = "https://files.pythonhosted.org/packages/85/a9/8b37ef4f7dafeb335daee3c8254645ef5725be4d9c6aa70b50ec46ef2f7e/contourpy-1.3.3-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:0c1fc238306b35f246d61a1d416a627348b5cf0648648a031e14bb8705fcdfe8", size = 261593, upload-time = "2025-07-26T12:02:54.037Z" },
+ { url = "https://files.pythonhosted.org/packages/0a/59/ebfb8c677c75605cc27f7122c90313fd2f375ff3c8d19a1694bda74aaa63/contourpy-1.3.3-pp311-pypy311_pp73-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:70f9aad7de812d6541d29d2bbf8feb22ff7e1c299523db288004e3157ff4674e", size = 302202, upload-time = "2025-07-26T12:02:55.947Z" },
+ { url = "https://files.pythonhosted.org/packages/3c/37/21972a15834d90bfbfb009b9d004779bd5a07a0ec0234e5ba8f64d5736f4/contourpy-1.3.3-pp311-pypy311_pp73-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:5ed3657edf08512fc3fe81b510e35c2012fbd3081d2e26160f27ca28affec989", size = 329207, upload-time = "2025-07-26T12:02:57.468Z" },
+ { url = "https://files.pythonhosted.org/packages/0c/58/bd257695f39d05594ca4ad60df5bcb7e32247f9951fd09a9b8edb82d1daa/contourpy-1.3.3-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:3d1a3799d62d45c18bafd41c5fa05120b96a28079f2393af559b843d1a966a77", size = 225315, upload-time = "2025-07-26T12:02:58.801Z" },
+]
+
+[[package]]
+name = "coverage"
+version = "7.13.1"
+source = { registry = "https://pypi.org/simple" }
+sdist = { url = "https://files.pythonhosted.org/packages/23/f9/e92df5e07f3fc8d4c7f9a0f146ef75446bf870351cd37b788cf5897f8079/coverage-7.13.1.tar.gz", hash = "sha256:b7593fe7eb5feaa3fbb461ac79aac9f9fc0387a5ca8080b0c6fe2ca27b091afd", size = 825862, upload-time = "2025-12-28T15:42:56.969Z" }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/b4/9b/77baf488516e9ced25fc215a6f75d803493fc3f6a1a1227ac35697910c2a/coverage-7.13.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:1a55d509a1dc5a5b708b5dad3b5334e07a16ad4c2185e27b40e4dba796ab7f88", size = 218755, upload-time = "2025-12-28T15:40:30.812Z" },
+ { url = "https://files.pythonhosted.org/packages/d7/cd/7ab01154e6eb79ee2fab76bf4d89e94c6648116557307ee4ebbb85e5c1bf/coverage-7.13.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:4d010d080c4888371033baab27e47c9df7d6fb28d0b7b7adf85a4a49be9298b3", size = 219257, upload-time = "2025-12-28T15:40:32.333Z" },
+ { url = "https://files.pythonhosted.org/packages/01/d5/b11ef7863ffbbdb509da0023fad1e9eda1c0eaea61a6d2ea5b17d4ac706e/coverage-7.13.1-cp311-cp311-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:d938b4a840fb1523b9dfbbb454f652967f18e197569c32266d4d13f37244c3d9", size = 249657, upload-time = "2025-12-28T15:40:34.1Z" },
+ { url = "https://files.pythonhosted.org/packages/f7/7c/347280982982383621d29b8c544cf497ae07ac41e44b1ca4903024131f55/coverage-7.13.1-cp311-cp311-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:bf100a3288f9bb7f919b87eb84f87101e197535b9bd0e2c2b5b3179633324fee", size = 251581, upload-time = "2025-12-28T15:40:36.131Z" },
+ { url = "https://files.pythonhosted.org/packages/82/f6/ebcfed11036ade4c0d75fa4453a6282bdd225bc073862766eec184a4c643/coverage-7.13.1-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ef6688db9bf91ba111ae734ba6ef1a063304a881749726e0d3575f5c10a9facf", size = 253691, upload-time = "2025-12-28T15:40:37.626Z" },
+ { url = "https://files.pythonhosted.org/packages/02/92/af8f5582787f5d1a8b130b2dcba785fa5e9a7a8e121a0bb2220a6fdbdb8a/coverage-7.13.1-cp311-cp311-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:0b609fc9cdbd1f02e51f67f51e5aee60a841ef58a68d00d5ee2c0faf357481a3", size = 249799, upload-time = "2025-12-28T15:40:39.47Z" },
+ { url = "https://files.pythonhosted.org/packages/24/aa/0e39a2a3b16eebf7f193863323edbff38b6daba711abaaf807d4290cf61a/coverage-7.13.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:c43257717611ff5e9a1d79dce8e47566235ebda63328718d9b65dd640bc832ef", size = 251389, upload-time = "2025-12-28T15:40:40.954Z" },
+ { url = "https://files.pythonhosted.org/packages/73/46/7f0c13111154dc5b978900c0ccee2e2ca239b910890e674a77f1363d483e/coverage-7.13.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:e09fbecc007f7b6afdfb3b07ce5bd9f8494b6856dd4f577d26c66c391b829851", size = 249450, upload-time = "2025-12-28T15:40:42.489Z" },
+ { url = "https://files.pythonhosted.org/packages/ac/ca/e80da6769e8b669ec3695598c58eef7ad98b0e26e66333996aee6316db23/coverage-7.13.1-cp311-cp311-musllinux_1_2_riscv64.whl", hash = "sha256:a03a4f3a19a189919c7055098790285cc5c5b0b3976f8d227aea39dbf9f8bfdb", size = 249170, upload-time = "2025-12-28T15:40:44.279Z" },
+ { url = "https://files.pythonhosted.org/packages/af/18/9e29baabdec1a8644157f572541079b4658199cfd372a578f84228e860de/coverage-7.13.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:3820778ea1387c2b6a818caec01c63adc5b3750211af6447e8dcfb9b6f08dbba", size = 250081, upload-time = "2025-12-28T15:40:45.748Z" },
+ { url = "https://files.pythonhosted.org/packages/00/f8/c3021625a71c3b2f516464d322e41636aea381018319050a8114105872ee/coverage-7.13.1-cp311-cp311-win32.whl", hash = "sha256:ff10896fa55167371960c5908150b434b71c876dfab97b69478f22c8b445ea19", size = 221281, upload-time = "2025-12-28T15:40:47.232Z" },
+ { url = "https://files.pythonhosted.org/packages/27/56/c216625f453df6e0559ed666d246fcbaaa93f3aa99eaa5080cea1229aa3d/coverage-7.13.1-cp311-cp311-win_amd64.whl", hash = "sha256:a998cc0aeeea4c6d5622a3754da5a493055d2d95186bad877b0a34ea6e6dbe0a", size = 222215, upload-time = "2025-12-28T15:40:49.19Z" },
+ { url = "https://files.pythonhosted.org/packages/5c/9a/be342e76f6e531cae6406dc46af0d350586f24d9b67fdfa6daee02df71af/coverage-7.13.1-cp311-cp311-win_arm64.whl", hash = "sha256:fea07c1a39a22614acb762e3fbbb4011f65eedafcb2948feeef641ac78b4ee5c", size = 220886, upload-time = "2025-12-28T15:40:51.067Z" },
+ { url = "https://files.pythonhosted.org/packages/ce/8a/87af46cccdfa78f53db747b09f5f9a21d5fc38d796834adac09b30a8ce74/coverage-7.13.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:6f34591000f06e62085b1865c9bc5f7858df748834662a51edadfd2c3bfe0dd3", size = 218927, upload-time = "2025-12-28T15:40:52.814Z" },
+ { url = "https://files.pythonhosted.org/packages/82/a8/6e22fdc67242a4a5a153f9438d05944553121c8f4ba70cb072af4c41362e/coverage-7.13.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:b67e47c5595b9224599016e333f5ec25392597a89d5744658f837d204e16c63e", size = 219288, upload-time = "2025-12-28T15:40:54.262Z" },
+ { url = "https://files.pythonhosted.org/packages/d0/0a/853a76e03b0f7c4375e2ca025df45c918beb367f3e20a0a8e91967f6e96c/coverage-7.13.1-cp312-cp312-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:3e7b8bd70c48ffb28461ebe092c2345536fb18bbbf19d287c8913699735f505c", size = 250786, upload-time = "2025-12-28T15:40:56.059Z" },
+ { url = "https://files.pythonhosted.org/packages/ea/b4/694159c15c52b9f7ec7adf49d50e5f8ee71d3e9ef38adb4445d13dd56c20/coverage-7.13.1-cp312-cp312-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:c223d078112e90dc0e5c4e35b98b9584164bea9fbbd221c0b21c5241f6d51b62", size = 253543, upload-time = "2025-12-28T15:40:57.585Z" },
+ { url = "https://files.pythonhosted.org/packages/96/b2/7f1f0437a5c855f87e17cf5d0dc35920b6440ff2b58b1ba9788c059c26c8/coverage-7.13.1-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:794f7c05af0763b1bbd1b9e6eff0e52ad068be3b12cd96c87de037b01390c968", size = 254635, upload-time = "2025-12-28T15:40:59.443Z" },
+ { url = "https://files.pythonhosted.org/packages/e9/d1/73c3fdb8d7d3bddd9473c9c6a2e0682f09fc3dfbcb9c3f36412a7368bcab/coverage-7.13.1-cp312-cp312-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:0642eae483cc8c2902e4af7298bf886d605e80f26382124cddc3967c2a3df09e", size = 251202, upload-time = "2025-12-28T15:41:01.328Z" },
+ { url = "https://files.pythonhosted.org/packages/66/3c/f0edf75dcc152f145d5598329e864bbbe04ab78660fe3e8e395f9fff010f/coverage-7.13.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:9f5e772ed5fef25b3de9f2008fe67b92d46831bd2bc5bdc5dd6bfd06b83b316f", size = 252566, upload-time = "2025-12-28T15:41:03.319Z" },
+ { url = "https://files.pythonhosted.org/packages/17/b3/e64206d3c5f7dcbceafd14941345a754d3dbc78a823a6ed526e23b9cdaab/coverage-7.13.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:45980ea19277dc0a579e432aef6a504fe098ef3a9032ead15e446eb0f1191aee", size = 250711, upload-time = "2025-12-28T15:41:06.411Z" },
+ { url = "https://files.pythonhosted.org/packages/dc/ad/28a3eb970a8ef5b479ee7f0c484a19c34e277479a5b70269dc652b730733/coverage-7.13.1-cp312-cp312-musllinux_1_2_riscv64.whl", hash = "sha256:e4f18eca6028ffa62adbd185a8f1e1dd242f2e68164dba5c2b74a5204850b4cf", size = 250278, upload-time = "2025-12-28T15:41:08.285Z" },
+ { url = "https://files.pythonhosted.org/packages/54/e3/c8f0f1a93133e3e1291ca76cbb63565bd4b5c5df63b141f539d747fff348/coverage-7.13.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:f8dca5590fec7a89ed6826fce625595279e586ead52e9e958d3237821fbc750c", size = 252154, upload-time = "2025-12-28T15:41:09.969Z" },
+ { url = "https://files.pythonhosted.org/packages/d0/bf/9939c5d6859c380e405b19e736321f1c7d402728792f4c752ad1adcce005/coverage-7.13.1-cp312-cp312-win32.whl", hash = "sha256:ff86d4e85188bba72cfb876df3e11fa243439882c55957184af44a35bd5880b7", size = 221487, upload-time = "2025-12-28T15:41:11.468Z" },
+ { url = "https://files.pythonhosted.org/packages/fa/dc/7282856a407c621c2aad74021680a01b23010bb8ebf427cf5eacda2e876f/coverage-7.13.1-cp312-cp312-win_amd64.whl", hash = "sha256:16cc1da46c04fb0fb128b4dc430b78fa2aba8a6c0c9f8eb391fd5103409a6ac6", size = 222299, upload-time = "2025-12-28T15:41:13.386Z" },
+ { url = "https://files.pythonhosted.org/packages/10/79/176a11203412c350b3e9578620013af35bcdb79b651eb976f4a4b32044fa/coverage-7.13.1-cp312-cp312-win_arm64.whl", hash = "sha256:8d9bc218650022a768f3775dd7fdac1886437325d8d295d923ebcfef4892ad5c", size = 220941, upload-time = "2025-12-28T15:41:14.975Z" },
+ { url = "https://files.pythonhosted.org/packages/a3/a4/e98e689347a1ff1a7f67932ab535cef82eb5e78f32a9e4132e114bbb3a0a/coverage-7.13.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:cb237bfd0ef4d5eb6a19e29f9e528ac67ac3be932ea6b44fb6cc09b9f3ecff78", size = 218951, upload-time = "2025-12-28T15:41:16.653Z" },
+ { url = "https://files.pythonhosted.org/packages/32/33/7cbfe2bdc6e2f03d6b240d23dc45fdaf3fd270aaf2d640be77b7f16989ab/coverage-7.13.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:1dcb645d7e34dcbcc96cd7c132b1fc55c39263ca62eb961c064eb3928997363b", size = 219325, upload-time = "2025-12-28T15:41:18.609Z" },
+ { url = "https://files.pythonhosted.org/packages/59/f6/efdabdb4929487baeb7cb2a9f7dac457d9356f6ad1b255be283d58b16316/coverage-7.13.1-cp313-cp313-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:3d42df8201e00384736f0df9be2ced39324c3907607d17d50d50116c989d84cd", size = 250309, upload-time = "2025-12-28T15:41:20.629Z" },
+ { url = "https://files.pythonhosted.org/packages/12/da/91a52516e9d5aea87d32d1523f9cdcf7a35a3b298e6be05d6509ba3cfab2/coverage-7.13.1-cp313-cp313-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:fa3edde1aa8807de1d05934982416cb3ec46d1d4d91e280bcce7cca01c507992", size = 252907, upload-time = "2025-12-28T15:41:22.257Z" },
+ { url = "https://files.pythonhosted.org/packages/75/38/f1ea837e3dc1231e086db1638947e00d264e7e8c41aa8ecacf6e1e0c05f4/coverage-7.13.1-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:9edd0e01a343766add6817bc448408858ba6b489039eaaa2018474e4001651a4", size = 254148, upload-time = "2025-12-28T15:41:23.87Z" },
+ { url = "https://files.pythonhosted.org/packages/7f/43/f4f16b881aaa34954ba446318dea6b9ed5405dd725dd8daac2358eda869a/coverage-7.13.1-cp313-cp313-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:985b7836931d033570b94c94713c6dba5f9d3ff26045f72c3e5dbc5fe3361e5a", size = 250515, upload-time = "2025-12-28T15:41:25.437Z" },
+ { url = "https://files.pythonhosted.org/packages/84/34/8cba7f00078bd468ea914134e0144263194ce849ec3baad187ffb6203d1c/coverage-7.13.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:ffed1e4980889765c84a5d1a566159e363b71d6b6fbaf0bebc9d3c30bc016766", size = 252292, upload-time = "2025-12-28T15:41:28.459Z" },
+ { url = "https://files.pythonhosted.org/packages/8c/a4/cffac66c7652d84ee4ac52d3ccb94c015687d3b513f9db04bfcac2ac800d/coverage-7.13.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:8842af7f175078456b8b17f1b73a0d16a65dcbdc653ecefeb00a56b3c8c298c4", size = 250242, upload-time = "2025-12-28T15:41:30.02Z" },
+ { url = "https://files.pythonhosted.org/packages/f4/78/9a64d462263dde416f3c0067efade7b52b52796f489b1037a95b0dc389c9/coverage-7.13.1-cp313-cp313-musllinux_1_2_riscv64.whl", hash = "sha256:ccd7a6fca48ca9c131d9b0a2972a581e28b13416fc313fb98b6d24a03ce9a398", size = 250068, upload-time = "2025-12-28T15:41:32.007Z" },
+ { url = "https://files.pythonhosted.org/packages/69/c8/a8994f5fece06db7c4a97c8fc1973684e178599b42e66280dded0524ef00/coverage-7.13.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:0403f647055de2609be776965108447deb8e384fe4a553c119e3ff6bfbab4784", size = 251846, upload-time = "2025-12-28T15:41:33.946Z" },
+ { url = "https://files.pythonhosted.org/packages/cc/f7/91fa73c4b80305c86598a2d4e54ba22df6bf7d0d97500944af7ef155d9f7/coverage-7.13.1-cp313-cp313-win32.whl", hash = "sha256:549d195116a1ba1e1ae2f5ca143f9777800f6636eab917d4f02b5310d6d73461", size = 221512, upload-time = "2025-12-28T15:41:35.519Z" },
+ { url = "https://files.pythonhosted.org/packages/45/0b/0768b4231d5a044da8f75e097a8714ae1041246bb765d6b5563bab456735/coverage-7.13.1-cp313-cp313-win_amd64.whl", hash = "sha256:5899d28b5276f536fcf840b18b61a9fce23cc3aec1d114c44c07fe94ebeaa500", size = 222321, upload-time = "2025-12-28T15:41:37.371Z" },
+ { url = "https://files.pythonhosted.org/packages/9b/b8/bdcb7253b7e85157282450262008f1366aa04663f3e3e4c30436f596c3e2/coverage-7.13.1-cp313-cp313-win_arm64.whl", hash = "sha256:868a2fae76dfb06e87291bcbd4dcbcc778a8500510b618d50496e520bd94d9b9", size = 220949, upload-time = "2025-12-28T15:41:39.553Z" },
+ { url = "https://files.pythonhosted.org/packages/70/52/f2be52cc445ff75ea8397948c96c1b4ee14f7f9086ea62fc929c5ae7b717/coverage-7.13.1-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:67170979de0dacac3f3097d02b0ad188d8edcea44ccc44aaa0550af49150c7dc", size = 219643, upload-time = "2025-12-28T15:41:41.567Z" },
+ { url = "https://files.pythonhosted.org/packages/47/79/c85e378eaa239e2edec0c5523f71542c7793fe3340954eafb0bc3904d32d/coverage-7.13.1-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:f80e2bb21bfab56ed7405c2d79d34b5dc0bc96c2c1d2a067b643a09fb756c43a", size = 219997, upload-time = "2025-12-28T15:41:43.418Z" },
+ { url = "https://files.pythonhosted.org/packages/fe/9b/b1ade8bfb653c0bbce2d6d6e90cc6c254cbb99b7248531cc76253cb4da6d/coverage-7.13.1-cp313-cp313t-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:f83351e0f7dcdb14d7326c3d8d8c4e915fa685cbfdc6281f9470d97a04e9dfe4", size = 261296, upload-time = "2025-12-28T15:41:45.207Z" },
+ { url = "https://files.pythonhosted.org/packages/1f/af/ebf91e3e1a2473d523e87e87fd8581e0aa08741b96265730e2d79ce78d8d/coverage-7.13.1-cp313-cp313t-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:bb3f6562e89bad0110afbe64e485aac2462efdce6232cdec7862a095dc3412f6", size = 263363, upload-time = "2025-12-28T15:41:47.163Z" },
+ { url = "https://files.pythonhosted.org/packages/c4/8b/fb2423526d446596624ac7fde12ea4262e66f86f5120114c3cfd0bb2befa/coverage-7.13.1-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:77545b5dcda13b70f872c3b5974ac64c21d05e65b1590b441c8560115dc3a0d1", size = 265783, upload-time = "2025-12-28T15:41:49.03Z" },
+ { url = "https://files.pythonhosted.org/packages/9b/26/ef2adb1e22674913b89f0fe7490ecadcef4a71fa96f5ced90c60ec358789/coverage-7.13.1-cp313-cp313t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:a4d240d260a1aed814790bbe1f10a5ff31ce6c21bc78f0da4a1e8268d6c80dbd", size = 260508, upload-time = "2025-12-28T15:41:51.035Z" },
+ { url = "https://files.pythonhosted.org/packages/ce/7d/f0f59b3404caf662e7b5346247883887687c074ce67ba453ea08c612b1d5/coverage-7.13.1-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:d2287ac9360dec3837bfdad969963a5d073a09a85d898bd86bea82aa8876ef3c", size = 263357, upload-time = "2025-12-28T15:41:52.631Z" },
+ { url = "https://files.pythonhosted.org/packages/1a/b1/29896492b0b1a047604d35d6fa804f12818fa30cdad660763a5f3159e158/coverage-7.13.1-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:0d2c11f3ea4db66b5cbded23b20185c35066892c67d80ec4be4bab257b9ad1e0", size = 260978, upload-time = "2025-12-28T15:41:54.589Z" },
+ { url = "https://files.pythonhosted.org/packages/48/f2/971de1238a62e6f0a4128d37adadc8bb882ee96afbe03ff1570291754629/coverage-7.13.1-cp313-cp313t-musllinux_1_2_riscv64.whl", hash = "sha256:3fc6a169517ca0d7ca6846c3c5392ef2b9e38896f61d615cb75b9e7134d4ee1e", size = 259877, upload-time = "2025-12-28T15:41:56.263Z" },
+ { url = "https://files.pythonhosted.org/packages/6a/fc/0474efcbb590ff8628830e9aaec5f1831594874360e3251f1fdec31d07a3/coverage-7.13.1-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:d10a2ed46386e850bb3de503a54f9fe8192e5917fcbb143bfef653a9355e9a53", size = 262069, upload-time = "2025-12-28T15:41:58.093Z" },
+ { url = "https://files.pythonhosted.org/packages/88/4f/3c159b7953db37a7b44c0eab8a95c37d1aa4257c47b4602c04022d5cb975/coverage-7.13.1-cp313-cp313t-win32.whl", hash = "sha256:75a6f4aa904301dab8022397a22c0039edc1f51e90b83dbd4464b8a38dc87842", size = 222184, upload-time = "2025-12-28T15:41:59.763Z" },
+ { url = "https://files.pythonhosted.org/packages/58/a5/6b57d28f81417f9335774f20679d9d13b9a8fb90cd6160957aa3b54a2379/coverage-7.13.1-cp313-cp313t-win_amd64.whl", hash = "sha256:309ef5706e95e62578cda256b97f5e097916a2c26247c287bbe74794e7150df2", size = 223250, upload-time = "2025-12-28T15:42:01.52Z" },
+ { url = "https://files.pythonhosted.org/packages/81/7c/160796f3b035acfbb58be80e02e484548595aa67e16a6345e7910ace0a38/coverage-7.13.1-cp313-cp313t-win_arm64.whl", hash = "sha256:92f980729e79b5d16d221038dbf2e8f9a9136afa072f9d5d6ed4cb984b126a09", size = 221521, upload-time = "2025-12-28T15:42:03.275Z" },
+ { url = "https://files.pythonhosted.org/packages/aa/8e/ba0e597560c6563fc0adb902fda6526df5d4aa73bb10adf0574d03bd2206/coverage-7.13.1-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:97ab3647280d458a1f9adb85244e81587505a43c0c7cff851f5116cd2814b894", size = 218996, upload-time = "2025-12-28T15:42:04.978Z" },
+ { url = "https://files.pythonhosted.org/packages/6b/8e/764c6e116f4221dc7aa26c4061181ff92edb9c799adae6433d18eeba7a14/coverage-7.13.1-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:8f572d989142e0908e6acf57ad1b9b86989ff057c006d13b76c146ec6a20216a", size = 219326, upload-time = "2025-12-28T15:42:06.691Z" },
+ { url = "https://files.pythonhosted.org/packages/4f/a6/6130dc6d8da28cdcbb0f2bf8865aeca9b157622f7c0031e48c6cf9a0e591/coverage-7.13.1-cp314-cp314-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:d72140ccf8a147e94274024ff6fd8fb7811354cf7ef88b1f0a988ebaa5bc774f", size = 250374, upload-time = "2025-12-28T15:42:08.786Z" },
+ { url = "https://files.pythonhosted.org/packages/82/2b/783ded568f7cd6b677762f780ad338bf4b4750205860c17c25f7c708995e/coverage-7.13.1-cp314-cp314-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:d3c9f051b028810f5a87c88e5d6e9af3c0ff32ef62763bf15d29f740453ca909", size = 252882, upload-time = "2025-12-28T15:42:10.515Z" },
+ { url = "https://files.pythonhosted.org/packages/cd/b2/9808766d082e6a4d59eb0cc881a57fc1600eb2c5882813eefff8254f71b5/coverage-7.13.1-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:f398ba4df52d30b1763f62eed9de5620dcde96e6f491f4c62686736b155aa6e4", size = 254218, upload-time = "2025-12-28T15:42:12.208Z" },
+ { url = "https://files.pythonhosted.org/packages/44/ea/52a985bb447c871cb4d2e376e401116520991b597c85afdde1ea9ef54f2c/coverage-7.13.1-cp314-cp314-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:132718176cc723026d201e347f800cd1a9e4b62ccd3f82476950834dad501c75", size = 250391, upload-time = "2025-12-28T15:42:14.21Z" },
+ { url = "https://files.pythonhosted.org/packages/7f/1d/125b36cc12310718873cfc8209ecfbc1008f14f4f5fa0662aa608e579353/coverage-7.13.1-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:9e549d642426e3579b3f4b92d0431543b012dcb6e825c91619d4e93b7363c3f9", size = 252239, upload-time = "2025-12-28T15:42:16.292Z" },
+ { url = "https://files.pythonhosted.org/packages/6a/16/10c1c164950cade470107f9f14bbac8485f8fb8515f515fca53d337e4a7f/coverage-7.13.1-cp314-cp314-musllinux_1_2_i686.whl", hash = "sha256:90480b2134999301eea795b3a9dbf606c6fbab1b489150c501da84a959442465", size = 250196, upload-time = "2025-12-28T15:42:18.54Z" },
+ { url = "https://files.pythonhosted.org/packages/2a/c6/cd860fac08780c6fd659732f6ced1b40b79c35977c1356344e44d72ba6c4/coverage-7.13.1-cp314-cp314-musllinux_1_2_riscv64.whl", hash = "sha256:e825dbb7f84dfa24663dd75835e7257f8882629fc11f03ecf77d84a75134b864", size = 250008, upload-time = "2025-12-28T15:42:20.365Z" },
+ { url = "https://files.pythonhosted.org/packages/f0/3a/a8c58d3d38f82a5711e1e0a67268362af48e1a03df27c03072ac30feefcf/coverage-7.13.1-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:623dcc6d7a7ba450bbdbeedbaa0c42b329bdae16491af2282f12a7e809be7eb9", size = 251671, upload-time = "2025-12-28T15:42:22.114Z" },
+ { url = "https://files.pythonhosted.org/packages/f0/bc/fd4c1da651d037a1e3d53e8cb3f8182f4b53271ffa9a95a2e211bacc0349/coverage-7.13.1-cp314-cp314-win32.whl", hash = "sha256:6e73ebb44dca5f708dc871fe0b90cf4cff1a13f9956f747cc87b535a840386f5", size = 221777, upload-time = "2025-12-28T15:42:23.919Z" },
+ { url = "https://files.pythonhosted.org/packages/4b/50/71acabdc8948464c17e90b5ffd92358579bd0910732c2a1c9537d7536aa6/coverage-7.13.1-cp314-cp314-win_amd64.whl", hash = "sha256:be753b225d159feb397bd0bf91ae86f689bad0da09d3b301478cd39b878ab31a", size = 222592, upload-time = "2025-12-28T15:42:25.619Z" },
+ { url = "https://files.pythonhosted.org/packages/f7/c8/a6fb943081bb0cc926499c7907731a6dc9efc2cbdc76d738c0ab752f1a32/coverage-7.13.1-cp314-cp314-win_arm64.whl", hash = "sha256:228b90f613b25ba0019361e4ab81520b343b622fc657daf7e501c4ed6a2366c0", size = 221169, upload-time = "2025-12-28T15:42:27.629Z" },
+ { url = "https://files.pythonhosted.org/packages/16/61/d5b7a0a0e0e40d62e59bc8c7aa1afbd86280d82728ba97f0673b746b78e2/coverage-7.13.1-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:60cfb538fe9ef86e5b2ab0ca8fc8d62524777f6c611dcaf76dc16fbe9b8e698a", size = 219730, upload-time = "2025-12-28T15:42:29.306Z" },
+ { url = "https://files.pythonhosted.org/packages/a3/2c/8881326445fd071bb49514d1ce97d18a46a980712b51fee84f9ab42845b4/coverage-7.13.1-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:57dfc8048c72ba48a8c45e188d811e5efd7e49b387effc8fb17e97936dde5bf6", size = 220001, upload-time = "2025-12-28T15:42:31.319Z" },
+ { url = "https://files.pythonhosted.org/packages/b5/d7/50de63af51dfa3a7f91cc37ad8fcc1e244b734232fbc8b9ab0f3c834a5cd/coverage-7.13.1-cp314-cp314t-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:3f2f725aa3e909b3c5fdb8192490bdd8e1495e85906af74fe6e34a2a77ba0673", size = 261370, upload-time = "2025-12-28T15:42:32.992Z" },
+ { url = "https://files.pythonhosted.org/packages/e1/2c/d31722f0ec918fd7453b2758312729f645978d212b410cd0f7c2aed88a94/coverage-7.13.1-cp314-cp314t-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:9ee68b21909686eeb21dfcba2c3b81fee70dcf38b140dcd5aa70680995fa3aa5", size = 263485, upload-time = "2025-12-28T15:42:34.759Z" },
+ { url = "https://files.pythonhosted.org/packages/fa/7a/2c114fa5c5fc08ba0777e4aec4c97e0b4a1afcb69c75f1f54cff78b073ab/coverage-7.13.1-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:724b1b270cb13ea2e6503476e34541a0b1f62280bc997eab443f87790202033d", size = 265890, upload-time = "2025-12-28T15:42:36.517Z" },
+ { url = "https://files.pythonhosted.org/packages/65/d9/f0794aa1c74ceabc780fe17f6c338456bbc4e96bd950f2e969f48ac6fb20/coverage-7.13.1-cp314-cp314t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:916abf1ac5cf7eb16bc540a5bf75c71c43a676f5c52fcb9fe75a2bd75fb944e8", size = 260445, upload-time = "2025-12-28T15:42:38.646Z" },
+ { url = "https://files.pythonhosted.org/packages/49/23/184b22a00d9bb97488863ced9454068c79e413cb23f472da6cbddc6cfc52/coverage-7.13.1-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:776483fd35b58d8afe3acbd9988d5de592ab6da2d2a865edfdbc9fdb43e7c486", size = 263357, upload-time = "2025-12-28T15:42:40.788Z" },
+ { url = "https://files.pythonhosted.org/packages/7d/bd/58af54c0c9199ea4190284f389005779d7daf7bf3ce40dcd2d2b2f96da69/coverage-7.13.1-cp314-cp314t-musllinux_1_2_i686.whl", hash = "sha256:b6f3b96617e9852703f5b633ea01315ca45c77e879584f283c44127f0f1ec564", size = 260959, upload-time = "2025-12-28T15:42:42.808Z" },
+ { url = "https://files.pythonhosted.org/packages/4b/2a/6839294e8f78a4891bf1df79d69c536880ba2f970d0ff09e7513d6e352e9/coverage-7.13.1-cp314-cp314t-musllinux_1_2_riscv64.whl", hash = "sha256:bd63e7b74661fed317212fab774e2a648bc4bb09b35f25474f8e3325d2945cd7", size = 259792, upload-time = "2025-12-28T15:42:44.818Z" },
+ { url = "https://files.pythonhosted.org/packages/ba/c3/528674d4623283310ad676c5af7414b9850ab6d55c2300e8aa4b945ec554/coverage-7.13.1-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:933082f161bbb3e9f90d00990dc956120f608cdbcaeea15c4d897f56ef4fe416", size = 262123, upload-time = "2025-12-28T15:42:47.108Z" },
+ { url = "https://files.pythonhosted.org/packages/06/c5/8c0515692fb4c73ac379d8dc09b18eaf0214ecb76ea6e62467ba7a1556ff/coverage-7.13.1-cp314-cp314t-win32.whl", hash = "sha256:18be793c4c87de2965e1c0f060f03d9e5aff66cfeae8e1dbe6e5b88056ec153f", size = 222562, upload-time = "2025-12-28T15:42:49.144Z" },
+ { url = "https://files.pythonhosted.org/packages/05/0e/c0a0c4678cb30dac735811db529b321d7e1c9120b79bd728d4f4d6b010e9/coverage-7.13.1-cp314-cp314t-win_amd64.whl", hash = "sha256:0e42e0ec0cd3e0d851cb3c91f770c9301f48647cb2877cb78f74bdaa07639a79", size = 223670, upload-time = "2025-12-28T15:42:51.218Z" },
+ { url = "https://files.pythonhosted.org/packages/f5/5f/b177aa0011f354abf03a8f30a85032686d290fdeed4222b27d36b4372a50/coverage-7.13.1-cp314-cp314t-win_arm64.whl", hash = "sha256:eaecf47ef10c72ece9a2a92118257da87e460e113b83cc0d2905cbbe931792b4", size = 221707, upload-time = "2025-12-28T15:42:53.034Z" },
+ { url = "https://files.pythonhosted.org/packages/cc/48/d9f421cb8da5afaa1a64570d9989e00fb7955e6acddc5a12979f7666ef60/coverage-7.13.1-py3-none-any.whl", hash = "sha256:2016745cb3ba554469d02819d78958b571792bb68e31302610e898f80dd3a573", size = 210722, upload-time = "2025-12-28T15:42:54.901Z" },
+]
+
+[package.optional-dependencies]
+toml = [
+ { name = "tomli", marker = "python_full_version <= '3.11'" },
+]
+
+[[package]]
+name = "cycler"
+version = "0.12.1"
+source = { registry = "https://pypi.org/simple" }
+sdist = { url = "https://files.pythonhosted.org/packages/a9/95/a3dbbb5028f35eafb79008e7522a75244477d2838f38cbb722248dabc2a8/cycler-0.12.1.tar.gz", hash = "sha256:88bb128f02ba341da8ef447245a9e138fae777f6a23943da4540077d3601eb1c", size = 7615, upload-time = "2023-10-07T05:32:18.335Z" }
wheels = [
- { url = "https://files.pythonhosted.org/packages/d1/d6/3965ed04c63042e047cb6a3e6ed1a63a35087b6a609aa3a15ed8ac56c221/colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6", size = 25335 },
+ { url = "https://files.pythonhosted.org/packages/e7/05/c19819d5e3d95294a6f5947fb9b9629efb316b96de511b418c53d245aae6/cycler-0.12.1-py3-none-any.whl", hash = "sha256:85cef7cff222d8644161529808465972e51340599459b8ac3ccbac5a854e0d30", size = 8321, upload-time = "2023-10-07T05:32:16.783Z" },
]
[[package]]
name = "distro"
version = "1.9.0"
source = { registry = "https://pypi.org/simple" }
-sdist = { url = "https://files.pythonhosted.org/packages/fc/f8/98eea607f65de6527f8a2e8885fc8015d3e6f5775df186e443e0964a11c3/distro-1.9.0.tar.gz", hash = "sha256:2fa77c6fd8940f116ee1d6b94a2f90b13b5ea8d019b98bc8bafdcabcdd9bdbed", size = 60722 }
+sdist = { url = "https://files.pythonhosted.org/packages/fc/f8/98eea607f65de6527f8a2e8885fc8015d3e6f5775df186e443e0964a11c3/distro-1.9.0.tar.gz", hash = "sha256:2fa77c6fd8940f116ee1d6b94a2f90b13b5ea8d019b98bc8bafdcabcdd9bdbed", size = 60722, upload-time = "2023-12-24T09:54:32.31Z" }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/12/b3/231ffd4ab1fc9d679809f356cebee130ac7daa00d6d6f3206dd4fd137e9e/distro-1.9.0-py3-none-any.whl", hash = "sha256:7bffd925d65168f85027d8da9af6bddab658135b840670a223589bc0c8ef02b2", size = 20277, upload-time = "2023-12-24T09:54:30.421Z" },
+]
+
+[[package]]
+name = "fonttools"
+version = "4.61.1"
+source = { registry = "https://pypi.org/simple" }
+sdist = { url = "https://files.pythonhosted.org/packages/ec/ca/cf17b88a8df95691275a3d77dc0a5ad9907f328ae53acbe6795da1b2f5ed/fonttools-4.61.1.tar.gz", hash = "sha256:6675329885c44657f826ef01d9e4fb33b9158e9d93c537d84ad8399539bc6f69", size = 3565756, upload-time = "2025-12-12T17:31:24.246Z" }
wheels = [
- { url = "https://files.pythonhosted.org/packages/12/b3/231ffd4ab1fc9d679809f356cebee130ac7daa00d6d6f3206dd4fd137e9e/distro-1.9.0-py3-none-any.whl", hash = "sha256:7bffd925d65168f85027d8da9af6bddab658135b840670a223589bc0c8ef02b2", size = 20277 },
+ { url = "https://files.pythonhosted.org/packages/69/12/bf9f4eaa2fad039356cc627587e30ed008c03f1cebd3034376b5ee8d1d44/fonttools-4.61.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:c6604b735bb12fef8e0efd5578c9fb5d3d8532d5001ea13a19cddf295673ee09", size = 2852213, upload-time = "2025-12-12T17:29:46.675Z" },
+ { url = "https://files.pythonhosted.org/packages/ac/49/4138d1acb6261499bedde1c07f8c2605d1d8f9d77a151e5507fd3ef084b6/fonttools-4.61.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:5ce02f38a754f207f2f06557523cd39a06438ba3aafc0639c477ac409fc64e37", size = 2401689, upload-time = "2025-12-12T17:29:48.769Z" },
+ { url = "https://files.pythonhosted.org/packages/e5/fe/e6ce0fe20a40e03aef906af60aa87668696f9e4802fa283627d0b5ed777f/fonttools-4.61.1-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:77efb033d8d7ff233385f30c62c7c79271c8885d5c9657d967ede124671bbdfb", size = 5058809, upload-time = "2025-12-12T17:29:51.701Z" },
+ { url = "https://files.pythonhosted.org/packages/79/61/1ca198af22f7dd22c17ab86e9024ed3c06299cfdb08170640e9996d501a0/fonttools-4.61.1-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:75c1a6dfac6abd407634420c93864a1e274ebc1c7531346d9254c0d8f6ca00f9", size = 5036039, upload-time = "2025-12-12T17:29:53.659Z" },
+ { url = "https://files.pythonhosted.org/packages/99/cc/fa1801e408586b5fce4da9f5455af8d770f4fc57391cd5da7256bb364d38/fonttools-4.61.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:0de30bfe7745c0d1ffa2b0b7048fb7123ad0d71107e10ee090fa0b16b9452e87", size = 5034714, upload-time = "2025-12-12T17:29:55.592Z" },
+ { url = "https://files.pythonhosted.org/packages/bf/aa/b7aeafe65adb1b0a925f8f25725e09f078c635bc22754f3fecb7456955b0/fonttools-4.61.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:58b0ee0ab5b1fc9921eccfe11d1435added19d6494dde14e323f25ad2bc30c56", size = 5158648, upload-time = "2025-12-12T17:29:57.861Z" },
+ { url = "https://files.pythonhosted.org/packages/99/f9/08ea7a38663328881384c6e7777bbefc46fd7d282adfd87a7d2b84ec9d50/fonttools-4.61.1-cp311-cp311-win32.whl", hash = "sha256:f79b168428351d11e10c5aeb61a74e1851ec221081299f4cf56036a95431c43a", size = 2280681, upload-time = "2025-12-12T17:29:59.943Z" },
+ { url = "https://files.pythonhosted.org/packages/07/ad/37dd1ae5fa6e01612a1fbb954f0927681f282925a86e86198ccd7b15d515/fonttools-4.61.1-cp311-cp311-win_amd64.whl", hash = "sha256:fe2efccb324948a11dd09d22136fe2ac8a97d6c1347cf0b58a911dcd529f66b7", size = 2331951, upload-time = "2025-12-12T17:30:02.254Z" },
+ { url = "https://files.pythonhosted.org/packages/6f/16/7decaa24a1bd3a70c607b2e29f0adc6159f36a7e40eaba59846414765fd4/fonttools-4.61.1-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:f3cb4a569029b9f291f88aafc927dd53683757e640081ca8c412781ea144565e", size = 2851593, upload-time = "2025-12-12T17:30:04.225Z" },
+ { url = "https://files.pythonhosted.org/packages/94/98/3c4cb97c64713a8cf499b3245c3bf9a2b8fd16a3e375feff2aed78f96259/fonttools-4.61.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:41a7170d042e8c0024703ed13b71893519a1a6d6e18e933e3ec7507a2c26a4b2", size = 2400231, upload-time = "2025-12-12T17:30:06.47Z" },
+ { url = "https://files.pythonhosted.org/packages/b7/37/82dbef0f6342eb01f54bca073ac1498433d6ce71e50c3c3282b655733b31/fonttools-4.61.1-cp312-cp312-manylinux1_x86_64.manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:10d88e55330e092940584774ee5e8a6971b01fc2f4d3466a1d6c158230880796", size = 4954103, upload-time = "2025-12-12T17:30:08.432Z" },
+ { url = "https://files.pythonhosted.org/packages/6c/44/f3aeac0fa98e7ad527f479e161aca6c3a1e47bb6996b053d45226fe37bf2/fonttools-4.61.1-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:15acc09befd16a0fb8a8f62bc147e1a82817542d72184acca9ce6e0aeda9fa6d", size = 5004295, upload-time = "2025-12-12T17:30:10.56Z" },
+ { url = "https://files.pythonhosted.org/packages/14/e8/7424ced75473983b964d09f6747fa09f054a6d656f60e9ac9324cf40c743/fonttools-4.61.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:e6bcdf33aec38d16508ce61fd81838f24c83c90a1d1b8c68982857038673d6b8", size = 4944109, upload-time = "2025-12-12T17:30:12.874Z" },
+ { url = "https://files.pythonhosted.org/packages/c8/8b/6391b257fa3d0b553d73e778f953a2f0154292a7a7a085e2374b111e5410/fonttools-4.61.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:5fade934607a523614726119164ff621e8c30e8fa1ffffbbd358662056ba69f0", size = 5093598, upload-time = "2025-12-12T17:30:15.79Z" },
+ { url = "https://files.pythonhosted.org/packages/d9/71/fd2ea96cdc512d92da5678a1c98c267ddd4d8c5130b76d0f7a80f9a9fde8/fonttools-4.61.1-cp312-cp312-win32.whl", hash = "sha256:75da8f28eff26defba42c52986de97b22106cb8f26515b7c22443ebc9c2d3261", size = 2269060, upload-time = "2025-12-12T17:30:18.058Z" },
+ { url = "https://files.pythonhosted.org/packages/80/3b/a3e81b71aed5a688e89dfe0e2694b26b78c7d7f39a5ffd8a7d75f54a12a8/fonttools-4.61.1-cp312-cp312-win_amd64.whl", hash = "sha256:497c31ce314219888c0e2fce5ad9178ca83fe5230b01a5006726cdf3ac9f24d9", size = 2319078, upload-time = "2025-12-12T17:30:22.862Z" },
+ { url = "https://files.pythonhosted.org/packages/4b/cf/00ba28b0990982530addb8dc3e9e6f2fa9cb5c20df2abdda7baa755e8fe1/fonttools-4.61.1-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:8c56c488ab471628ff3bfa80964372fc13504ece601e0d97a78ee74126b2045c", size = 2846454, upload-time = "2025-12-12T17:30:24.938Z" },
+ { url = "https://files.pythonhosted.org/packages/5a/ca/468c9a8446a2103ae645d14fee3f610567b7042aba85031c1c65e3ef7471/fonttools-4.61.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:dc492779501fa723b04d0ab1f5be046797fee17d27700476edc7ee9ae535a61e", size = 2398191, upload-time = "2025-12-12T17:30:27.343Z" },
+ { url = "https://files.pythonhosted.org/packages/a3/4b/d67eedaed19def5967fade3297fed8161b25ba94699efc124b14fb68cdbc/fonttools-4.61.1-cp313-cp313-manylinux1_x86_64.manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:64102ca87e84261419c3747a0d20f396eb024bdbeb04c2bfb37e2891f5fadcb5", size = 4928410, upload-time = "2025-12-12T17:30:29.771Z" },
+ { url = "https://files.pythonhosted.org/packages/b0/8d/6fb3494dfe61a46258cd93d979cf4725ded4eb46c2a4ca35e4490d84daea/fonttools-4.61.1-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:4c1b526c8d3f615a7b1867f38a9410849c8f4aef078535742198e942fba0e9bd", size = 4984460, upload-time = "2025-12-12T17:30:32.073Z" },
+ { url = "https://files.pythonhosted.org/packages/f7/f1/a47f1d30b3dc00d75e7af762652d4cbc3dff5c2697a0dbd5203c81afd9c3/fonttools-4.61.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:41ed4b5ec103bd306bb68f81dc166e77409e5209443e5773cb4ed837bcc9b0d3", size = 4925800, upload-time = "2025-12-12T17:30:34.339Z" },
+ { url = "https://files.pythonhosted.org/packages/a7/01/e6ae64a0981076e8a66906fab01539799546181e32a37a0257b77e4aa88b/fonttools-4.61.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:b501c862d4901792adaec7c25b1ecc749e2662543f68bb194c42ba18d6eec98d", size = 5067859, upload-time = "2025-12-12T17:30:36.593Z" },
+ { url = "https://files.pythonhosted.org/packages/73/aa/28e40b8d6809a9b5075350a86779163f074d2b617c15d22343fce81918db/fonttools-4.61.1-cp313-cp313-win32.whl", hash = "sha256:4d7092bb38c53bbc78e9255a59158b150bcdc115a1e3b3ce0b5f267dc35dd63c", size = 2267821, upload-time = "2025-12-12T17:30:38.478Z" },
+ { url = "https://files.pythonhosted.org/packages/1a/59/453c06d1d83dc0951b69ef692d6b9f1846680342927df54e9a1ca91c6f90/fonttools-4.61.1-cp313-cp313-win_amd64.whl", hash = "sha256:21e7c8d76f62ab13c9472ccf74515ca5b9a761d1bde3265152a6dc58700d895b", size = 2318169, upload-time = "2025-12-12T17:30:40.951Z" },
+ { url = "https://files.pythonhosted.org/packages/32/8f/4e7bf82c0cbb738d3c2206c920ca34ca74ef9dabde779030145d28665104/fonttools-4.61.1-cp314-cp314-macosx_10_15_universal2.whl", hash = "sha256:fff4f534200a04b4a36e7ae3cb74493afe807b517a09e99cb4faa89a34ed6ecd", size = 2846094, upload-time = "2025-12-12T17:30:43.511Z" },
+ { url = "https://files.pythonhosted.org/packages/71/09/d44e45d0a4f3a651f23a1e9d42de43bc643cce2971b19e784cc67d823676/fonttools-4.61.1-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:d9203500f7c63545b4ce3799319fe4d9feb1a1b89b28d3cb5abd11b9dd64147e", size = 2396589, upload-time = "2025-12-12T17:30:45.681Z" },
+ { url = "https://files.pythonhosted.org/packages/89/18/58c64cafcf8eb677a99ef593121f719e6dcbdb7d1c594ae5a10d4997ca8a/fonttools-4.61.1-cp314-cp314-manylinux1_x86_64.manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:fa646ecec9528bef693415c79a86e733c70a4965dd938e9a226b0fc64c9d2e6c", size = 4877892, upload-time = "2025-12-12T17:30:47.709Z" },
+ { url = "https://files.pythonhosted.org/packages/8a/ec/9e6b38c7ba1e09eb51db849d5450f4c05b7e78481f662c3b79dbde6f3d04/fonttools-4.61.1-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:11f35ad7805edba3aac1a3710d104592df59f4b957e30108ae0ba6c10b11dd75", size = 4972884, upload-time = "2025-12-12T17:30:49.656Z" },
+ { url = "https://files.pythonhosted.org/packages/5e/87/b5339da8e0256734ba0dbbf5b6cdebb1dd79b01dc8c270989b7bcd465541/fonttools-4.61.1-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:b931ae8f62db78861b0ff1ac017851764602288575d65b8e8ff1963fed419063", size = 4924405, upload-time = "2025-12-12T17:30:51.735Z" },
+ { url = "https://files.pythonhosted.org/packages/0b/47/e3409f1e1e69c073a3a6fd8cb886eb18c0bae0ee13db2c8d5e7f8495e8b7/fonttools-4.61.1-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:b148b56f5de675ee16d45e769e69f87623a4944f7443850bf9a9376e628a89d2", size = 5035553, upload-time = "2025-12-12T17:30:54.823Z" },
+ { url = "https://files.pythonhosted.org/packages/bf/b6/1f6600161b1073a984294c6c031e1a56ebf95b6164249eecf30012bb2e38/fonttools-4.61.1-cp314-cp314-win32.whl", hash = "sha256:9b666a475a65f4e839d3d10473fad6d47e0a9db14a2f4a224029c5bfde58ad2c", size = 2271915, upload-time = "2025-12-12T17:30:57.913Z" },
+ { url = "https://files.pythonhosted.org/packages/52/7b/91e7b01e37cc8eb0e1f770d08305b3655e4f002fc160fb82b3390eabacf5/fonttools-4.61.1-cp314-cp314-win_amd64.whl", hash = "sha256:4f5686e1fe5fce75d82d93c47a438a25bf0d1319d2843a926f741140b2b16e0c", size = 2323487, upload-time = "2025-12-12T17:30:59.804Z" },
+ { url = "https://files.pythonhosted.org/packages/39/5c/908ad78e46c61c3e3ed70c3b58ff82ab48437faf84ec84f109592cabbd9f/fonttools-4.61.1-cp314-cp314t-macosx_10_15_universal2.whl", hash = "sha256:e76ce097e3c57c4bcb67c5aa24a0ecdbd9f74ea9219997a707a4061fbe2707aa", size = 2929571, upload-time = "2025-12-12T17:31:02.574Z" },
+ { url = "https://files.pythonhosted.org/packages/bd/41/975804132c6dea64cdbfbaa59f3518a21c137a10cccf962805b301ac6ab2/fonttools-4.61.1-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:9cfef3ab326780c04d6646f68d4b4742aae222e8b8ea1d627c74e38afcbc9d91", size = 2435317, upload-time = "2025-12-12T17:31:04.974Z" },
+ { url = "https://files.pythonhosted.org/packages/b0/5a/aef2a0a8daf1ebaae4cfd83f84186d4a72ee08fd6a8451289fcd03ffa8a4/fonttools-4.61.1-cp314-cp314t-manylinux1_x86_64.manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:a75c301f96db737e1c5ed5fd7d77d9c34466de16095a266509e13da09751bd19", size = 4882124, upload-time = "2025-12-12T17:31:07.456Z" },
+ { url = "https://files.pythonhosted.org/packages/80/33/d6db3485b645b81cea538c9d1c9219d5805f0877fda18777add4671c5240/fonttools-4.61.1-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:91669ccac46bbc1d09e9273546181919064e8df73488ea087dcac3e2968df9ba", size = 5100391, upload-time = "2025-12-12T17:31:09.732Z" },
+ { url = "https://files.pythonhosted.org/packages/6c/d6/675ba631454043c75fcf76f0ca5463eac8eb0666ea1d7badae5fea001155/fonttools-4.61.1-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:c33ab3ca9d3ccd581d58e989d67554e42d8d4ded94ab3ade3508455fe70e65f7", size = 4978800, upload-time = "2025-12-12T17:31:11.681Z" },
+ { url = "https://files.pythonhosted.org/packages/7f/33/d3ec753d547a8d2bdaedd390d4a814e8d5b45a093d558f025c6b990b554c/fonttools-4.61.1-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:664c5a68ec406f6b1547946683008576ef8b38275608e1cee6c061828171c118", size = 5006426, upload-time = "2025-12-12T17:31:13.764Z" },
+ { url = "https://files.pythonhosted.org/packages/b4/40/cc11f378b561a67bea850ab50063366a0d1dd3f6d0a30ce0f874b0ad5664/fonttools-4.61.1-cp314-cp314t-win32.whl", hash = "sha256:aed04cabe26f30c1647ef0e8fbb207516fd40fe9472e9439695f5c6998e60ac5", size = 2335377, upload-time = "2025-12-12T17:31:16.49Z" },
+ { url = "https://files.pythonhosted.org/packages/e4/ff/c9a2b66b39f8628531ea58b320d66d951267c98c6a38684daa8f50fb02f8/fonttools-4.61.1-cp314-cp314t-win_amd64.whl", hash = "sha256:2180f14c141d2f0f3da43f3a81bc8aa4684860f6b0e6f9e165a4831f24e6a23b", size = 2400613, upload-time = "2025-12-12T17:31:18.769Z" },
+ { url = "https://files.pythonhosted.org/packages/c7/4e/ce75a57ff3aebf6fc1f4e9d508b8e5810618a33d900ad6c19eb30b290b97/fonttools-4.61.1-py3-none-any.whl", hash = "sha256:17d2bf5d541add43822bcf0c43d7d847b160c9bb01d15d5007d84e2217aaa371", size = 1148996, upload-time = "2025-12-12T17:31:21.03Z" },
]
[[package]]
name = "h11"
version = "0.14.0"
source = { registry = "https://pypi.org/simple" }
-sdist = { url = "https://files.pythonhosted.org/packages/f5/38/3af3d3633a34a3316095b39c8e8fb4853a28a536e55d347bd8d8e9a14b03/h11-0.14.0.tar.gz", hash = "sha256:8f19fbbe99e72420ff35c00b27a34cb9937e902a8b810e2c88300c6f0a3b699d", size = 100418 }
+sdist = { url = "https://files.pythonhosted.org/packages/f5/38/3af3d3633a34a3316095b39c8e8fb4853a28a536e55d347bd8d8e9a14b03/h11-0.14.0.tar.gz", hash = "sha256:8f19fbbe99e72420ff35c00b27a34cb9937e902a8b810e2c88300c6f0a3b699d", size = 100418, upload-time = "2022-09-25T15:40:01.519Z" }
wheels = [
- { url = "https://files.pythonhosted.org/packages/95/04/ff642e65ad6b90db43e668d70ffb6736436c7ce41fcc549f4e9472234127/h11-0.14.0-py3-none-any.whl", hash = "sha256:e3fe4ac4b851c468cc8363d500db52c2ead036020723024a109d37346efaa761", size = 58259 },
+ { url = "https://files.pythonhosted.org/packages/95/04/ff642e65ad6b90db43e668d70ffb6736436c7ce41fcc549f4e9472234127/h11-0.14.0-py3-none-any.whl", hash = "sha256:e3fe4ac4b851c468cc8363d500db52c2ead036020723024a109d37346efaa761", size = 58259, upload-time = "2022-09-25T15:39:59.68Z" },
]
[[package]]
@@ -89,9 +402,9 @@ dependencies = [
{ name = "certifi" },
{ name = "h11" },
]
-sdist = { url = "https://files.pythonhosted.org/packages/6a/41/d7d0a89eb493922c37d343b607bc1b5da7f5be7e383740b4753ad8943e90/httpcore-1.0.7.tar.gz", hash = "sha256:8551cb62a169ec7162ac7be8d4817d561f60e08eaa485234898414bb5a8a0b4c", size = 85196 }
+sdist = { url = "https://files.pythonhosted.org/packages/6a/41/d7d0a89eb493922c37d343b607bc1b5da7f5be7e383740b4753ad8943e90/httpcore-1.0.7.tar.gz", hash = "sha256:8551cb62a169ec7162ac7be8d4817d561f60e08eaa485234898414bb5a8a0b4c", size = 85196, upload-time = "2024-11-15T12:30:47.531Z" }
wheels = [
- { url = "https://files.pythonhosted.org/packages/87/f5/72347bc88306acb359581ac4d52f23c0ef445b57157adedb9aee0cd689d2/httpcore-1.0.7-py3-none-any.whl", hash = "sha256:a3fff8f43dc260d5bd363d9f9cf1830fa3a458b332856f34282de498ed420edd", size = 78551 },
+ { url = "https://files.pythonhosted.org/packages/87/f5/72347bc88306acb359581ac4d52f23c0ef445b57157adedb9aee0cd689d2/httpcore-1.0.7-py3-none-any.whl", hash = "sha256:a3fff8f43dc260d5bd363d9f9cf1830fa3a458b332856f34282de498ed420edd", size = 78551, upload-time = "2024-11-15T12:30:45.782Z" },
]
[[package]]
@@ -104,62 +417,418 @@ dependencies = [
{ name = "httpcore" },
{ name = "idna" },
]
-sdist = { url = "https://files.pythonhosted.org/packages/b1/df/48c586a5fe32a0f01324ee087459e112ebb7224f646c0b5023f5e79e9956/httpx-0.28.1.tar.gz", hash = "sha256:75e98c5f16b0f35b567856f597f06ff2270a374470a5c2392242528e3e3e42fc", size = 141406 }
+sdist = { url = "https://files.pythonhosted.org/packages/b1/df/48c586a5fe32a0f01324ee087459e112ebb7224f646c0b5023f5e79e9956/httpx-0.28.1.tar.gz", hash = "sha256:75e98c5f16b0f35b567856f597f06ff2270a374470a5c2392242528e3e3e42fc", size = 141406, upload-time = "2024-12-06T15:37:23.222Z" }
wheels = [
- { url = "https://files.pythonhosted.org/packages/2a/39/e50c7c3a983047577ee07d2a9e53faf5a69493943ec3f6a384bdc792deb2/httpx-0.28.1-py3-none-any.whl", hash = "sha256:d909fcccc110f8c7faf814ca82a9a4d816bc5a6dbfea25d6591d6985b8ba59ad", size = 73517 },
+ { url = "https://files.pythonhosted.org/packages/2a/39/e50c7c3a983047577ee07d2a9e53faf5a69493943ec3f6a384bdc792deb2/httpx-0.28.1-py3-none-any.whl", hash = "sha256:d909fcccc110f8c7faf814ca82a9a4d816bc5a6dbfea25d6591d6985b8ba59ad", size = 73517, upload-time = "2024-12-06T15:37:21.509Z" },
]
[[package]]
name = "idna"
version = "3.10"
source = { registry = "https://pypi.org/simple" }
-sdist = { url = "https://files.pythonhosted.org/packages/f1/70/7703c29685631f5a7590aa73f1f1d3fa9a380e654b86af429e0934a32f7d/idna-3.10.tar.gz", hash = "sha256:12f65c9b470abda6dc35cf8e63cc574b1c52b11df2c86030af0ac09b01b13ea9", size = 190490 }
+sdist = { url = "https://files.pythonhosted.org/packages/f1/70/7703c29685631f5a7590aa73f1f1d3fa9a380e654b86af429e0934a32f7d/idna-3.10.tar.gz", hash = "sha256:12f65c9b470abda6dc35cf8e63cc574b1c52b11df2c86030af0ac09b01b13ea9", size = 190490, upload-time = "2024-09-15T18:07:39.745Z" }
wheels = [
- { url = "https://files.pythonhosted.org/packages/76/c6/c88e154df9c4e1a2a66ccf0005a88dfb2650c1dffb6f5ce603dfbd452ce3/idna-3.10-py3-none-any.whl", hash = "sha256:946d195a0d259cbba61165e88e65941f16e9b36ea6ddb97f00452bae8b1287d3", size = 70442 },
+ { url = "https://files.pythonhosted.org/packages/76/c6/c88e154df9c4e1a2a66ccf0005a88dfb2650c1dffb6f5ce603dfbd452ce3/idna-3.10-py3-none-any.whl", hash = "sha256:946d195a0d259cbba61165e88e65941f16e9b36ea6ddb97f00452bae8b1287d3", size = 70442, upload-time = "2024-09-15T18:07:37.964Z" },
+]
+
+[[package]]
+name = "iniconfig"
+version = "2.3.0"
+source = { registry = "https://pypi.org/simple" }
+sdist = { url = "https://files.pythonhosted.org/packages/72/34/14ca021ce8e5dfedc35312d08ba8bf51fdd999c576889fc2c24cb97f4f10/iniconfig-2.3.0.tar.gz", hash = "sha256:c76315c77db068650d49c5b56314774a7804df16fee4402c1f19d6d15d8c4730", size = 20503, upload-time = "2025-10-18T21:55:43.219Z" }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/cb/b1/3846dd7f199d53cb17f49cba7e651e9ce294d8497c8c150530ed11865bb8/iniconfig-2.3.0-py3-none-any.whl", hash = "sha256:f631c04d2c48c52b84d0d0549c99ff3859c98df65b3101406327ecc7d53fbf12", size = 7484, upload-time = "2025-10-18T21:55:41.639Z" },
]
[[package]]
name = "jiter"
version = "0.8.2"
source = { registry = "https://pypi.org/simple" }
-sdist = { url = "https://files.pythonhosted.org/packages/f8/70/90bc7bd3932e651486861df5c8ffea4ca7c77d28e8532ddefe2abc561a53/jiter-0.8.2.tar.gz", hash = "sha256:cd73d3e740666d0e639f678adb176fad25c1bcbdae88d8d7b857e1783bb4212d", size = 163007 }
+sdist = { url = "https://files.pythonhosted.org/packages/f8/70/90bc7bd3932e651486861df5c8ffea4ca7c77d28e8532ddefe2abc561a53/jiter-0.8.2.tar.gz", hash = "sha256:cd73d3e740666d0e639f678adb176fad25c1bcbdae88d8d7b857e1783bb4212d", size = 163007, upload-time = "2024-12-09T18:11:08.649Z" }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/cb/b0/c1a7caa7f9dc5f1f6cfa08722867790fe2d3645d6e7170ca280e6e52d163/jiter-0.8.2-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:2dd61c5afc88a4fda7d8b2cf03ae5947c6ac7516d32b7a15bf4b49569a5c076b", size = 303666, upload-time = "2024-12-09T18:09:23.145Z" },
+ { url = "https://files.pythonhosted.org/packages/f5/97/0468bc9eeae43079aaa5feb9267964e496bf13133d469cfdc135498f8dd0/jiter-0.8.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:a6c710d657c8d1d2adbbb5c0b0c6bfcec28fd35bd6b5f016395f9ac43e878a15", size = 311934, upload-time = "2024-12-09T18:09:25.098Z" },
+ { url = "https://files.pythonhosted.org/packages/e5/69/64058e18263d9a5f1e10f90c436853616d5f047d997c37c7b2df11b085ec/jiter-0.8.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a9584de0cd306072635fe4b89742bf26feae858a0683b399ad0c2509011b9dc0", size = 335506, upload-time = "2024-12-09T18:09:26.407Z" },
+ { url = "https://files.pythonhosted.org/packages/9d/14/b747f9a77b8c0542141d77ca1e2a7523e854754af2c339ac89a8b66527d6/jiter-0.8.2-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:5a90a923338531b7970abb063cfc087eebae6ef8ec8139762007188f6bc69a9f", size = 355849, upload-time = "2024-12-09T18:09:27.686Z" },
+ { url = "https://files.pythonhosted.org/packages/53/e2/98a08161db7cc9d0e39bc385415890928ff09709034982f48eccfca40733/jiter-0.8.2-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d21974d246ed0181558087cd9f76e84e8321091ebfb3a93d4c341479a736f099", size = 381700, upload-time = "2024-12-09T18:09:28.989Z" },
+ { url = "https://files.pythonhosted.org/packages/7a/38/1674672954d35bce3b1c9af99d5849f9256ac8f5b672e020ac7821581206/jiter-0.8.2-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:32475a42b2ea7b344069dc1e81445cfc00b9d0e3ca837f0523072432332e9f74", size = 389710, upload-time = "2024-12-09T18:09:30.565Z" },
+ { url = "https://files.pythonhosted.org/packages/f8/9b/92f9da9a9e107d019bcf883cd9125fa1690079f323f5a9d5c6986eeec3c0/jiter-0.8.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8b9931fd36ee513c26b5bf08c940b0ac875de175341cbdd4fa3be109f0492586", size = 345553, upload-time = "2024-12-09T18:09:32.735Z" },
+ { url = "https://files.pythonhosted.org/packages/44/a6/6d030003394e9659cd0d7136bbeabd82e869849ceccddc34d40abbbbb269/jiter-0.8.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:ce0820f4a3a59ddced7fce696d86a096d5cc48d32a4183483a17671a61edfddc", size = 376388, upload-time = "2024-12-09T18:09:34.723Z" },
+ { url = "https://files.pythonhosted.org/packages/ad/8d/87b09e648e4aca5f9af89e3ab3cfb93db2d1e633b2f2931ede8dabd9b19a/jiter-0.8.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:8ffc86ae5e3e6a93765d49d1ab47b6075a9c978a2b3b80f0f32628f39caa0c88", size = 511226, upload-time = "2024-12-09T18:09:36.13Z" },
+ { url = "https://files.pythonhosted.org/packages/77/95/8008ebe4cdc82eac1c97864a8042ca7e383ed67e0ec17bfd03797045c727/jiter-0.8.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:5127dc1abd809431172bc3fbe8168d6b90556a30bb10acd5ded41c3cfd6f43b6", size = 504134, upload-time = "2024-12-09T18:09:37.581Z" },
+ { url = "https://files.pythonhosted.org/packages/26/0d/3056a74de13e8b2562e4d526de6dac2f65d91ace63a8234deb9284a1d24d/jiter-0.8.2-cp311-cp311-win32.whl", hash = "sha256:66227a2c7b575720c1871c8800d3a0122bb8ee94edb43a5685aa9aceb2782d44", size = 203103, upload-time = "2024-12-09T18:09:38.881Z" },
+ { url = "https://files.pythonhosted.org/packages/4e/1e/7f96b798f356e531ffc0f53dd2f37185fac60fae4d6c612bbbd4639b90aa/jiter-0.8.2-cp311-cp311-win_amd64.whl", hash = "sha256:cde031d8413842a1e7501e9129b8e676e62a657f8ec8166e18a70d94d4682855", size = 206717, upload-time = "2024-12-09T18:09:41.064Z" },
+ { url = "https://files.pythonhosted.org/packages/a1/17/c8747af8ea4e045f57d6cfd6fc180752cab9bc3de0e8a0c9ca4e8af333b1/jiter-0.8.2-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:e6ec2be506e7d6f9527dae9ff4b7f54e68ea44a0ef6b098256ddf895218a2f8f", size = 302027, upload-time = "2024-12-09T18:09:43.11Z" },
+ { url = "https://files.pythonhosted.org/packages/3c/c1/6da849640cd35a41e91085723b76acc818d4b7d92b0b6e5111736ce1dd10/jiter-0.8.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:76e324da7b5da060287c54f2fabd3db5f76468006c811831f051942bf68c9d44", size = 310326, upload-time = "2024-12-09T18:09:44.426Z" },
+ { url = "https://files.pythonhosted.org/packages/06/99/a2bf660d8ccffee9ad7ed46b4f860d2108a148d0ea36043fd16f4dc37e94/jiter-0.8.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:180a8aea058f7535d1c84183c0362c710f4750bef66630c05f40c93c2b152a0f", size = 334242, upload-time = "2024-12-09T18:09:45.915Z" },
+ { url = "https://files.pythonhosted.org/packages/a7/5f/cea1c17864828731f11427b9d1ab7f24764dbd9aaf4648a7f851164d2718/jiter-0.8.2-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:025337859077b41548bdcbabe38698bcd93cfe10b06ff66617a48ff92c9aec60", size = 356654, upload-time = "2024-12-09T18:09:47.619Z" },
+ { url = "https://files.pythonhosted.org/packages/e9/13/62774b7e5e7f5d5043efe1d0f94ead66e6d0f894ae010adb56b3f788de71/jiter-0.8.2-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ecff0dc14f409599bbcafa7e470c00b80f17abc14d1405d38ab02e4b42e55b57", size = 379967, upload-time = "2024-12-09T18:09:49.987Z" },
+ { url = "https://files.pythonhosted.org/packages/ec/fb/096b34c553bb0bd3f2289d5013dcad6074948b8d55212aa13a10d44c5326/jiter-0.8.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:ffd9fee7d0775ebaba131f7ca2e2d83839a62ad65e8e02fe2bd8fc975cedeb9e", size = 389252, upload-time = "2024-12-09T18:09:51.329Z" },
+ { url = "https://files.pythonhosted.org/packages/17/61/beea645c0bf398ced8b199e377b61eb999d8e46e053bb285c91c3d3eaab0/jiter-0.8.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:14601dcac4889e0a1c75ccf6a0e4baf70dbc75041e51bcf8d0e9274519df6887", size = 345490, upload-time = "2024-12-09T18:09:52.646Z" },
+ { url = "https://files.pythonhosted.org/packages/d5/df/834aa17ad5dcc3cf0118821da0a0cf1589ea7db9832589278553640366bc/jiter-0.8.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:92249669925bc1c54fcd2ec73f70f2c1d6a817928480ee1c65af5f6b81cdf12d", size = 376991, upload-time = "2024-12-09T18:09:53.972Z" },
+ { url = "https://files.pythonhosted.org/packages/67/80/87d140399d382fb4ea5b3d56e7ecaa4efdca17cd7411ff904c1517855314/jiter-0.8.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:e725edd0929fa79f8349ab4ec7f81c714df51dc4e991539a578e5018fa4a7152", size = 510822, upload-time = "2024-12-09T18:09:55.439Z" },
+ { url = "https://files.pythonhosted.org/packages/5c/37/3394bb47bac1ad2cb0465601f86828a0518d07828a650722e55268cdb7e6/jiter-0.8.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:bf55846c7b7a680eebaf9c3c48d630e1bf51bdf76c68a5f654b8524335b0ad29", size = 503730, upload-time = "2024-12-09T18:09:59.494Z" },
+ { url = "https://files.pythonhosted.org/packages/f9/e2/253fc1fa59103bb4e3aa0665d6ceb1818df1cd7bf3eb492c4dad229b1cd4/jiter-0.8.2-cp312-cp312-win32.whl", hash = "sha256:7efe4853ecd3d6110301665a5178b9856be7e2a9485f49d91aa4d737ad2ae49e", size = 203375, upload-time = "2024-12-09T18:10:00.814Z" },
+ { url = "https://files.pythonhosted.org/packages/41/69/6d4bbe66b3b3b4507e47aa1dd5d075919ad242b4b1115b3f80eecd443687/jiter-0.8.2-cp312-cp312-win_amd64.whl", hash = "sha256:83c0efd80b29695058d0fd2fa8a556490dbce9804eac3e281f373bbc99045f6c", size = 204740, upload-time = "2024-12-09T18:10:02.146Z" },
+ { url = "https://files.pythonhosted.org/packages/6c/b0/bfa1f6f2c956b948802ef5a021281978bf53b7a6ca54bb126fd88a5d014e/jiter-0.8.2-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:ca1f08b8e43dc3bd0594c992fb1fd2f7ce87f7bf0d44358198d6da8034afdf84", size = 301190, upload-time = "2024-12-09T18:10:03.463Z" },
+ { url = "https://files.pythonhosted.org/packages/a4/8f/396ddb4e292b5ea57e45ade5dc48229556b9044bad29a3b4b2dddeaedd52/jiter-0.8.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:5672a86d55416ccd214c778efccf3266b84f87b89063b582167d803246354be4", size = 309334, upload-time = "2024-12-09T18:10:05.774Z" },
+ { url = "https://files.pythonhosted.org/packages/7f/68/805978f2f446fa6362ba0cc2e4489b945695940656edd844e110a61c98f8/jiter-0.8.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:58dc9bc9767a1101f4e5e22db1b652161a225874d66f0e5cb8e2c7d1c438b587", size = 333918, upload-time = "2024-12-09T18:10:07.158Z" },
+ { url = "https://files.pythonhosted.org/packages/b3/99/0f71f7be667c33403fa9706e5b50583ae5106d96fab997fa7e2f38ee8347/jiter-0.8.2-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:37b2998606d6dadbb5ccda959a33d6a5e853252d921fec1792fc902351bb4e2c", size = 356057, upload-time = "2024-12-09T18:10:09.341Z" },
+ { url = "https://files.pythonhosted.org/packages/8d/50/a82796e421a22b699ee4d2ce527e5bcb29471a2351cbdc931819d941a167/jiter-0.8.2-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:4ab9a87f3784eb0e098f84a32670cfe4a79cb6512fd8f42ae3d0709f06405d18", size = 379790, upload-time = "2024-12-09T18:10:10.702Z" },
+ { url = "https://files.pythonhosted.org/packages/3c/31/10fb012b00f6d83342ca9e2c9618869ab449f1aa78c8f1b2193a6b49647c/jiter-0.8.2-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:79aec8172b9e3c6d05fd4b219d5de1ac616bd8da934107325a6c0d0e866a21b6", size = 388285, upload-time = "2024-12-09T18:10:12.721Z" },
+ { url = "https://files.pythonhosted.org/packages/c8/81/f15ebf7de57be488aa22944bf4274962aca8092e4f7817f92ffa50d3ee46/jiter-0.8.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:711e408732d4e9a0208008e5892c2966b485c783cd2d9a681f3eb147cf36c7ef", size = 344764, upload-time = "2024-12-09T18:10:14.075Z" },
+ { url = "https://files.pythonhosted.org/packages/b3/e8/0cae550d72b48829ba653eb348cdc25f3f06f8a62363723702ec18e7be9c/jiter-0.8.2-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:653cf462db4e8c41995e33d865965e79641ef45369d8a11f54cd30888b7e6ff1", size = 376620, upload-time = "2024-12-09T18:10:15.487Z" },
+ { url = "https://files.pythonhosted.org/packages/b8/50/e5478ff9d82534a944c03b63bc217c5f37019d4a34d288db0f079b13c10b/jiter-0.8.2-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:9c63eaef32b7bebac8ebebf4dabebdbc6769a09c127294db6babee38e9f405b9", size = 510402, upload-time = "2024-12-09T18:10:17.499Z" },
+ { url = "https://files.pythonhosted.org/packages/8e/1e/3de48bbebbc8f7025bd454cedc8c62378c0e32dd483dece5f4a814a5cb55/jiter-0.8.2-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:eb21aaa9a200d0a80dacc7a81038d2e476ffe473ffdd9c91eb745d623561de05", size = 503018, upload-time = "2024-12-09T18:10:18.92Z" },
+ { url = "https://files.pythonhosted.org/packages/d5/cd/d5a5501d72a11fe3e5fd65c78c884e5164eefe80077680533919be22d3a3/jiter-0.8.2-cp313-cp313-win32.whl", hash = "sha256:789361ed945d8d42850f919342a8665d2dc79e7e44ca1c97cc786966a21f627a", size = 203190, upload-time = "2024-12-09T18:10:20.801Z" },
+ { url = "https://files.pythonhosted.org/packages/51/bf/e5ca301245ba951447e3ad677a02a64a8845b185de2603dabd83e1e4b9c6/jiter-0.8.2-cp313-cp313-win_amd64.whl", hash = "sha256:ab7f43235d71e03b941c1630f4b6e3055d46b6cb8728a17663eaac9d8e83a865", size = 203551, upload-time = "2024-12-09T18:10:22.822Z" },
+ { url = "https://files.pythonhosted.org/packages/2f/3c/71a491952c37b87d127790dd7a0b1ebea0514c6b6ad30085b16bbe00aee6/jiter-0.8.2-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:b426f72cd77da3fec300ed3bc990895e2dd6b49e3bfe6c438592a3ba660e41ca", size = 308347, upload-time = "2024-12-09T18:10:24.139Z" },
+ { url = "https://files.pythonhosted.org/packages/a0/4c/c02408042e6a7605ec063daed138e07b982fdb98467deaaf1c90950cf2c6/jiter-0.8.2-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b2dd880785088ff2ad21ffee205e58a8c1ddabc63612444ae41e5e4b321b39c0", size = 342875, upload-time = "2024-12-09T18:10:25.553Z" },
+ { url = "https://files.pythonhosted.org/packages/91/61/c80ef80ed8a0a21158e289ef70dac01e351d929a1c30cb0f49be60772547/jiter-0.8.2-cp313-cp313t-win_amd64.whl", hash = "sha256:3ac9f578c46f22405ff7f8b1f5848fb753cc4b8377fbec8470a7dc3997ca7566", size = 202374, upload-time = "2024-12-09T18:10:26.958Z" },
+]
+
+[[package]]
+name = "kiwisolver"
+version = "1.4.9"
+source = { registry = "https://pypi.org/simple" }
+sdist = { url = "https://files.pythonhosted.org/packages/5c/3c/85844f1b0feb11ee581ac23fe5fce65cd049a200c1446708cc1b7f922875/kiwisolver-1.4.9.tar.gz", hash = "sha256:c3b22c26c6fd6811b0ae8363b95ca8ce4ea3c202d3d0975b2914310ceb1bcc4d", size = 97564, upload-time = "2025-08-10T21:27:49.279Z" }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/6f/ab/c80b0d5a9d8a1a65f4f815f2afff9798b12c3b9f31f1d304dd233dd920e2/kiwisolver-1.4.9-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:eb14a5da6dc7642b0f3a18f13654847cd8b7a2550e2645a5bda677862b03ba16", size = 124167, upload-time = "2025-08-10T21:25:53.403Z" },
+ { url = "https://files.pythonhosted.org/packages/a0/c0/27fe1a68a39cf62472a300e2879ffc13c0538546c359b86f149cc19f6ac3/kiwisolver-1.4.9-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:39a219e1c81ae3b103643d2aedb90f1ef22650deb266ff12a19e7773f3e5f089", size = 66579, upload-time = "2025-08-10T21:25:54.79Z" },
+ { url = "https://files.pythonhosted.org/packages/31/a2/a12a503ac1fd4943c50f9822678e8015a790a13b5490354c68afb8489814/kiwisolver-1.4.9-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:2405a7d98604b87f3fc28b1716783534b1b4b8510d8142adca34ee0bc3c87543", size = 65309, upload-time = "2025-08-10T21:25:55.76Z" },
+ { url = "https://files.pythonhosted.org/packages/66/e1/e533435c0be77c3f64040d68d7a657771194a63c279f55573188161e81ca/kiwisolver-1.4.9-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:dc1ae486f9abcef254b5618dfb4113dd49f94c68e3e027d03cf0143f3f772b61", size = 1435596, upload-time = "2025-08-10T21:25:56.861Z" },
+ { url = "https://files.pythonhosted.org/packages/67/1e/51b73c7347f9aabdc7215aa79e8b15299097dc2f8e67dee2b095faca9cb0/kiwisolver-1.4.9-cp311-cp311-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:8a1f570ce4d62d718dce3f179ee78dac3b545ac16c0c04bb363b7607a949c0d1", size = 1246548, upload-time = "2025-08-10T21:25:58.246Z" },
+ { url = "https://files.pythonhosted.org/packages/21/aa/72a1c5d1e430294f2d32adb9542719cfb441b5da368d09d268c7757af46c/kiwisolver-1.4.9-cp311-cp311-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:cb27e7b78d716c591e88e0a09a2139c6577865d7f2e152488c2cc6257f460872", size = 1263618, upload-time = "2025-08-10T21:25:59.857Z" },
+ { url = "https://files.pythonhosted.org/packages/a3/af/db1509a9e79dbf4c260ce0cfa3903ea8945f6240e9e59d1e4deb731b1a40/kiwisolver-1.4.9-cp311-cp311-manylinux_2_24_s390x.manylinux_2_28_s390x.whl", hash = "sha256:15163165efc2f627eb9687ea5f3a28137217d217ac4024893d753f46bce9de26", size = 1317437, upload-time = "2025-08-10T21:26:01.105Z" },
+ { url = "https://files.pythonhosted.org/packages/e0/f2/3ea5ee5d52abacdd12013a94130436e19969fa183faa1e7c7fbc89e9a42f/kiwisolver-1.4.9-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:bdee92c56a71d2b24c33a7d4c2856bd6419d017e08caa7802d2963870e315028", size = 2195742, upload-time = "2025-08-10T21:26:02.675Z" },
+ { url = "https://files.pythonhosted.org/packages/6f/9b/1efdd3013c2d9a2566aa6a337e9923a00590c516add9a1e89a768a3eb2fc/kiwisolver-1.4.9-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:412f287c55a6f54b0650bd9b6dce5aceddb95864a1a90c87af16979d37c89771", size = 2290810, upload-time = "2025-08-10T21:26:04.009Z" },
+ { url = "https://files.pythonhosted.org/packages/fb/e5/cfdc36109ae4e67361f9bc5b41323648cb24a01b9ade18784657e022e65f/kiwisolver-1.4.9-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:2c93f00dcba2eea70af2be5f11a830a742fe6b579a1d4e00f47760ef13be247a", size = 2461579, upload-time = "2025-08-10T21:26:05.317Z" },
+ { url = "https://files.pythonhosted.org/packages/62/86/b589e5e86c7610842213994cdea5add00960076bef4ae290c5fa68589cac/kiwisolver-1.4.9-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:f117e1a089d9411663a3207ba874f31be9ac8eaa5b533787024dc07aeb74f464", size = 2268071, upload-time = "2025-08-10T21:26:06.686Z" },
+ { url = "https://files.pythonhosted.org/packages/3b/c6/f8df8509fd1eee6c622febe54384a96cfaf4d43bf2ccec7a0cc17e4715c9/kiwisolver-1.4.9-cp311-cp311-win_amd64.whl", hash = "sha256:be6a04e6c79819c9a8c2373317d19a96048e5a3f90bec587787e86a1153883c2", size = 73840, upload-time = "2025-08-10T21:26:07.94Z" },
+ { url = "https://files.pythonhosted.org/packages/e2/2d/16e0581daafd147bc11ac53f032a2b45eabac897f42a338d0a13c1e5c436/kiwisolver-1.4.9-cp311-cp311-win_arm64.whl", hash = "sha256:0ae37737256ba2de764ddc12aed4956460277f00c4996d51a197e72f62f5eec7", size = 65159, upload-time = "2025-08-10T21:26:09.048Z" },
+ { url = "https://files.pythonhosted.org/packages/86/c9/13573a747838aeb1c76e3267620daa054f4152444d1f3d1a2324b78255b5/kiwisolver-1.4.9-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:ac5a486ac389dddcc5bef4f365b6ae3ffff2c433324fb38dd35e3fab7c957999", size = 123686, upload-time = "2025-08-10T21:26:10.034Z" },
+ { url = "https://files.pythonhosted.org/packages/51/ea/2ecf727927f103ffd1739271ca19c424d0e65ea473fbaeea1c014aea93f6/kiwisolver-1.4.9-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:f2ba92255faa7309d06fe44c3a4a97efe1c8d640c2a79a5ef728b685762a6fd2", size = 66460, upload-time = "2025-08-10T21:26:11.083Z" },
+ { url = "https://files.pythonhosted.org/packages/5b/5a/51f5464373ce2aeb5194508298a508b6f21d3867f499556263c64c621914/kiwisolver-1.4.9-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:4a2899935e724dd1074cb568ce7ac0dce28b2cd6ab539c8e001a8578eb106d14", size = 64952, upload-time = "2025-08-10T21:26:12.058Z" },
+ { url = "https://files.pythonhosted.org/packages/70/90/6d240beb0f24b74371762873e9b7f499f1e02166a2d9c5801f4dbf8fa12e/kiwisolver-1.4.9-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:f6008a4919fdbc0b0097089f67a1eb55d950ed7e90ce2cc3e640abadd2757a04", size = 1474756, upload-time = "2025-08-10T21:26:13.096Z" },
+ { url = "https://files.pythonhosted.org/packages/12/42/f36816eaf465220f683fb711efdd1bbf7a7005a2473d0e4ed421389bd26c/kiwisolver-1.4.9-cp312-cp312-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:67bb8b474b4181770f926f7b7d2f8c0248cbcb78b660fdd41a47054b28d2a752", size = 1276404, upload-time = "2025-08-10T21:26:14.457Z" },
+ { url = "https://files.pythonhosted.org/packages/2e/64/bc2de94800adc830c476dce44e9b40fd0809cddeef1fde9fcf0f73da301f/kiwisolver-1.4.9-cp312-cp312-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:2327a4a30d3ee07d2fbe2e7933e8a37c591663b96ce42a00bc67461a87d7df77", size = 1294410, upload-time = "2025-08-10T21:26:15.73Z" },
+ { url = "https://files.pythonhosted.org/packages/5f/42/2dc82330a70aa8e55b6d395b11018045e58d0bb00834502bf11509f79091/kiwisolver-1.4.9-cp312-cp312-manylinux_2_24_s390x.manylinux_2_28_s390x.whl", hash = "sha256:7a08b491ec91b1d5053ac177afe5290adacf1f0f6307d771ccac5de30592d198", size = 1343631, upload-time = "2025-08-10T21:26:17.045Z" },
+ { url = "https://files.pythonhosted.org/packages/22/fd/f4c67a6ed1aab149ec5a8a401c323cee7a1cbe364381bb6c9c0d564e0e20/kiwisolver-1.4.9-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:d8fc5c867c22b828001b6a38d2eaeb88160bf5783c6cb4a5e440efc981ce286d", size = 2224963, upload-time = "2025-08-10T21:26:18.737Z" },
+ { url = "https://files.pythonhosted.org/packages/45/aa/76720bd4cb3713314677d9ec94dcc21ced3f1baf4830adde5bb9b2430a5f/kiwisolver-1.4.9-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:3b3115b2581ea35bb6d1f24a4c90af37e5d9b49dcff267eeed14c3893c5b86ab", size = 2321295, upload-time = "2025-08-10T21:26:20.11Z" },
+ { url = "https://files.pythonhosted.org/packages/80/19/d3ec0d9ab711242f56ae0dc2fc5d70e298bb4a1f9dfab44c027668c673a1/kiwisolver-1.4.9-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:858e4c22fb075920b96a291928cb7dea5644e94c0ee4fcd5af7e865655e4ccf2", size = 2487987, upload-time = "2025-08-10T21:26:21.49Z" },
+ { url = "https://files.pythonhosted.org/packages/39/e9/61e4813b2c97e86b6fdbd4dd824bf72d28bcd8d4849b8084a357bc0dd64d/kiwisolver-1.4.9-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:ed0fecd28cc62c54b262e3736f8bb2512d8dcfdc2bcf08be5f47f96bf405b145", size = 2291817, upload-time = "2025-08-10T21:26:22.812Z" },
+ { url = "https://files.pythonhosted.org/packages/a0/41/85d82b0291db7504da3c2defe35c9a8a5c9803a730f297bd823d11d5fb77/kiwisolver-1.4.9-cp312-cp312-win_amd64.whl", hash = "sha256:f68208a520c3d86ea51acf688a3e3002615a7f0238002cccc17affecc86a8a54", size = 73895, upload-time = "2025-08-10T21:26:24.37Z" },
+ { url = "https://files.pythonhosted.org/packages/e2/92/5f3068cf15ee5cb624a0c7596e67e2a0bb2adee33f71c379054a491d07da/kiwisolver-1.4.9-cp312-cp312-win_arm64.whl", hash = "sha256:2c1a4f57df73965f3f14df20b80ee29e6a7930a57d2d9e8491a25f676e197c60", size = 64992, upload-time = "2025-08-10T21:26:25.732Z" },
+ { url = "https://files.pythonhosted.org/packages/31/c1/c2686cda909742ab66c7388e9a1a8521a59eb89f8bcfbee28fc980d07e24/kiwisolver-1.4.9-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:a5d0432ccf1c7ab14f9949eec60c5d1f924f17c037e9f8b33352fa05799359b8", size = 123681, upload-time = "2025-08-10T21:26:26.725Z" },
+ { url = "https://files.pythonhosted.org/packages/ca/f0/f44f50c9f5b1a1860261092e3bc91ecdc9acda848a8b8c6abfda4a24dd5c/kiwisolver-1.4.9-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:efb3a45b35622bb6c16dbfab491a8f5a391fe0e9d45ef32f4df85658232ca0e2", size = 66464, upload-time = "2025-08-10T21:26:27.733Z" },
+ { url = "https://files.pythonhosted.org/packages/2d/7a/9d90a151f558e29c3936b8a47ac770235f436f2120aca41a6d5f3d62ae8d/kiwisolver-1.4.9-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:1a12cf6398e8a0a001a059747a1cbf24705e18fe413bc22de7b3d15c67cffe3f", size = 64961, upload-time = "2025-08-10T21:26:28.729Z" },
+ { url = "https://files.pythonhosted.org/packages/e9/e9/f218a2cb3a9ffbe324ca29a9e399fa2d2866d7f348ec3a88df87fc248fc5/kiwisolver-1.4.9-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:b67e6efbf68e077dd71d1a6b37e43e1a99d0bff1a3d51867d45ee8908b931098", size = 1474607, upload-time = "2025-08-10T21:26:29.798Z" },
+ { url = "https://files.pythonhosted.org/packages/d9/28/aac26d4c882f14de59041636292bc838db8961373825df23b8eeb807e198/kiwisolver-1.4.9-cp313-cp313-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:5656aa670507437af0207645273ccdfee4f14bacd7f7c67a4306d0dcaeaf6eed", size = 1276546, upload-time = "2025-08-10T21:26:31.401Z" },
+ { url = "https://files.pythonhosted.org/packages/8b/ad/8bfc1c93d4cc565e5069162f610ba2f48ff39b7de4b5b8d93f69f30c4bed/kiwisolver-1.4.9-cp313-cp313-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:bfc08add558155345129c7803b3671cf195e6a56e7a12f3dde7c57d9b417f525", size = 1294482, upload-time = "2025-08-10T21:26:32.721Z" },
+ { url = "https://files.pythonhosted.org/packages/da/f1/6aca55ff798901d8ce403206d00e033191f63d82dd708a186e0ed2067e9c/kiwisolver-1.4.9-cp313-cp313-manylinux_2_24_s390x.manylinux_2_28_s390x.whl", hash = "sha256:40092754720b174e6ccf9e845d0d8c7d8e12c3d71e7fc35f55f3813e96376f78", size = 1343720, upload-time = "2025-08-10T21:26:34.032Z" },
+ { url = "https://files.pythonhosted.org/packages/d1/91/eed031876c595c81d90d0f6fc681ece250e14bf6998c3d7c419466b523b7/kiwisolver-1.4.9-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:497d05f29a1300d14e02e6441cf0f5ee81c1ff5a304b0d9fb77423974684e08b", size = 2224907, upload-time = "2025-08-10T21:26:35.824Z" },
+ { url = "https://files.pythonhosted.org/packages/e9/ec/4d1925f2e49617b9cca9c34bfa11adefad49d00db038e692a559454dfb2e/kiwisolver-1.4.9-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:bdd1a81a1860476eb41ac4bc1e07b3f07259e6d55bbf739b79c8aaedcf512799", size = 2321334, upload-time = "2025-08-10T21:26:37.534Z" },
+ { url = "https://files.pythonhosted.org/packages/43/cb/450cd4499356f68802750c6ddc18647b8ea01ffa28f50d20598e0befe6e9/kiwisolver-1.4.9-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:e6b93f13371d341afee3be9f7c5964e3fe61d5fa30f6a30eb49856935dfe4fc3", size = 2488313, upload-time = "2025-08-10T21:26:39.191Z" },
+ { url = "https://files.pythonhosted.org/packages/71/67/fc76242bd99f885651128a5d4fa6083e5524694b7c88b489b1b55fdc491d/kiwisolver-1.4.9-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:d75aa530ccfaa593da12834b86a0724f58bff12706659baa9227c2ccaa06264c", size = 2291970, upload-time = "2025-08-10T21:26:40.828Z" },
+ { url = "https://files.pythonhosted.org/packages/75/bd/f1a5d894000941739f2ae1b65a32892349423ad49c2e6d0771d0bad3fae4/kiwisolver-1.4.9-cp313-cp313-win_amd64.whl", hash = "sha256:dd0a578400839256df88c16abddf9ba14813ec5f21362e1fe65022e00c883d4d", size = 73894, upload-time = "2025-08-10T21:26:42.33Z" },
+ { url = "https://files.pythonhosted.org/packages/95/38/dce480814d25b99a391abbddadc78f7c117c6da34be68ca8b02d5848b424/kiwisolver-1.4.9-cp313-cp313-win_arm64.whl", hash = "sha256:d4188e73af84ca82468f09cadc5ac4db578109e52acb4518d8154698d3a87ca2", size = 64995, upload-time = "2025-08-10T21:26:43.889Z" },
+ { url = "https://files.pythonhosted.org/packages/e2/37/7d218ce5d92dadc5ebdd9070d903e0c7cf7edfe03f179433ac4d13ce659c/kiwisolver-1.4.9-cp313-cp313t-macosx_10_13_universal2.whl", hash = "sha256:5a0f2724dfd4e3b3ac5a82436a8e6fd16baa7d507117e4279b660fe8ca38a3a1", size = 126510, upload-time = "2025-08-10T21:26:44.915Z" },
+ { url = "https://files.pythonhosted.org/packages/23/b0/e85a2b48233daef4b648fb657ebbb6f8367696a2d9548a00b4ee0eb67803/kiwisolver-1.4.9-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:1b11d6a633e4ed84fc0ddafd4ebfd8ea49b3f25082c04ad12b8315c11d504dc1", size = 67903, upload-time = "2025-08-10T21:26:45.934Z" },
+ { url = "https://files.pythonhosted.org/packages/44/98/f2425bc0113ad7de24da6bb4dae1343476e95e1d738be7c04d31a5d037fd/kiwisolver-1.4.9-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:61874cdb0a36016354853593cffc38e56fc9ca5aa97d2c05d3dcf6922cd55a11", size = 66402, upload-time = "2025-08-10T21:26:47.101Z" },
+ { url = "https://files.pythonhosted.org/packages/98/d8/594657886df9f34c4177cc353cc28ca7e6e5eb562d37ccc233bff43bbe2a/kiwisolver-1.4.9-cp313-cp313t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:60c439763a969a6af93b4881db0eed8fadf93ee98e18cbc35bc8da868d0c4f0c", size = 1582135, upload-time = "2025-08-10T21:26:48.665Z" },
+ { url = "https://files.pythonhosted.org/packages/5c/c6/38a115b7170f8b306fc929e166340c24958347308ea3012c2b44e7e295db/kiwisolver-1.4.9-cp313-cp313t-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:92a2f997387a1b79a75e7803aa7ded2cfbe2823852ccf1ba3bcf613b62ae3197", size = 1389409, upload-time = "2025-08-10T21:26:50.335Z" },
+ { url = "https://files.pythonhosted.org/packages/bf/3b/e04883dace81f24a568bcee6eb3001da4ba05114afa622ec9b6fafdc1f5e/kiwisolver-1.4.9-cp313-cp313t-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:a31d512c812daea6d8b3be3b2bfcbeb091dbb09177706569bcfc6240dcf8b41c", size = 1401763, upload-time = "2025-08-10T21:26:51.867Z" },
+ { url = "https://files.pythonhosted.org/packages/9f/80/20ace48e33408947af49d7d15c341eaee69e4e0304aab4b7660e234d6288/kiwisolver-1.4.9-cp313-cp313t-manylinux_2_24_s390x.manylinux_2_28_s390x.whl", hash = "sha256:52a15b0f35dad39862d376df10c5230155243a2c1a436e39eb55623ccbd68185", size = 1453643, upload-time = "2025-08-10T21:26:53.592Z" },
+ { url = "https://files.pythonhosted.org/packages/64/31/6ce4380a4cd1f515bdda976a1e90e547ccd47b67a1546d63884463c92ca9/kiwisolver-1.4.9-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:a30fd6fdef1430fd9e1ba7b3398b5ee4e2887783917a687d86ba69985fb08748", size = 2330818, upload-time = "2025-08-10T21:26:55.051Z" },
+ { url = "https://files.pythonhosted.org/packages/fa/e9/3f3fcba3bcc7432c795b82646306e822f3fd74df0ee81f0fa067a1f95668/kiwisolver-1.4.9-cp313-cp313t-musllinux_1_2_ppc64le.whl", hash = "sha256:cc9617b46837c6468197b5945e196ee9ca43057bb7d9d1ae688101e4e1dddf64", size = 2419963, upload-time = "2025-08-10T21:26:56.421Z" },
+ { url = "https://files.pythonhosted.org/packages/99/43/7320c50e4133575c66e9f7dadead35ab22d7c012a3b09bb35647792b2a6d/kiwisolver-1.4.9-cp313-cp313t-musllinux_1_2_s390x.whl", hash = "sha256:0ab74e19f6a2b027ea4f845a78827969af45ce790e6cb3e1ebab71bdf9f215ff", size = 2594639, upload-time = "2025-08-10T21:26:57.882Z" },
+ { url = "https://files.pythonhosted.org/packages/65/d6/17ae4a270d4a987ef8a385b906d2bdfc9fce502d6dc0d3aea865b47f548c/kiwisolver-1.4.9-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:dba5ee5d3981160c28d5490f0d1b7ed730c22470ff7f6cc26cfcfaacb9896a07", size = 2391741, upload-time = "2025-08-10T21:26:59.237Z" },
+ { url = "https://files.pythonhosted.org/packages/2a/8f/8f6f491d595a9e5912971f3f863d81baddccc8a4d0c3749d6a0dd9ffc9df/kiwisolver-1.4.9-cp313-cp313t-win_arm64.whl", hash = "sha256:0749fd8f4218ad2e851e11cc4dc05c7cbc0cbc4267bdfdb31782e65aace4ee9c", size = 68646, upload-time = "2025-08-10T21:27:00.52Z" },
+ { url = "https://files.pythonhosted.org/packages/6b/32/6cc0fbc9c54d06c2969faa9c1d29f5751a2e51809dd55c69055e62d9b426/kiwisolver-1.4.9-cp314-cp314-macosx_10_13_universal2.whl", hash = "sha256:9928fe1eb816d11ae170885a74d074f57af3a0d65777ca47e9aeb854a1fba386", size = 123806, upload-time = "2025-08-10T21:27:01.537Z" },
+ { url = "https://files.pythonhosted.org/packages/b2/dd/2bfb1d4a4823d92e8cbb420fe024b8d2167f72079b3bb941207c42570bdf/kiwisolver-1.4.9-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:d0005b053977e7b43388ddec89fa567f43d4f6d5c2c0affe57de5ebf290dc552", size = 66605, upload-time = "2025-08-10T21:27:03.335Z" },
+ { url = "https://files.pythonhosted.org/packages/f7/69/00aafdb4e4509c2ca6064646cba9cd4b37933898f426756adb2cb92ebbed/kiwisolver-1.4.9-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:2635d352d67458b66fd0667c14cb1d4145e9560d503219034a18a87e971ce4f3", size = 64925, upload-time = "2025-08-10T21:27:04.339Z" },
+ { url = "https://files.pythonhosted.org/packages/43/dc/51acc6791aa14e5cb6d8a2e28cefb0dc2886d8862795449d021334c0df20/kiwisolver-1.4.9-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:767c23ad1c58c9e827b649a9ab7809fd5fd9db266a9cf02b0e926ddc2c680d58", size = 1472414, upload-time = "2025-08-10T21:27:05.437Z" },
+ { url = "https://files.pythonhosted.org/packages/3d/bb/93fa64a81db304ac8a246f834d5094fae4b13baf53c839d6bb6e81177129/kiwisolver-1.4.9-cp314-cp314-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:72d0eb9fba308b8311685c2268cf7d0a0639a6cd027d8128659f72bdd8a024b4", size = 1281272, upload-time = "2025-08-10T21:27:07.063Z" },
+ { url = "https://files.pythonhosted.org/packages/70/e6/6df102916960fb8d05069d4bd92d6d9a8202d5a3e2444494e7cd50f65b7a/kiwisolver-1.4.9-cp314-cp314-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:f68e4f3eeca8fb22cc3d731f9715a13b652795ef657a13df1ad0c7dc0e9731df", size = 1298578, upload-time = "2025-08-10T21:27:08.452Z" },
+ { url = "https://files.pythonhosted.org/packages/7c/47/e142aaa612f5343736b087864dbaebc53ea8831453fb47e7521fa8658f30/kiwisolver-1.4.9-cp314-cp314-manylinux_2_24_s390x.manylinux_2_28_s390x.whl", hash = "sha256:d84cd4061ae292d8ac367b2c3fa3aad11cb8625a95d135fe93f286f914f3f5a6", size = 1345607, upload-time = "2025-08-10T21:27:10.125Z" },
+ { url = "https://files.pythonhosted.org/packages/54/89/d641a746194a0f4d1a3670fb900d0dbaa786fb98341056814bc3f058fa52/kiwisolver-1.4.9-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:a60ea74330b91bd22a29638940d115df9dc00af5035a9a2a6ad9399ffb4ceca5", size = 2230150, upload-time = "2025-08-10T21:27:11.484Z" },
+ { url = "https://files.pythonhosted.org/packages/aa/6b/5ee1207198febdf16ac11f78c5ae40861b809cbe0e6d2a8d5b0b3044b199/kiwisolver-1.4.9-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:ce6a3a4e106cf35c2d9c4fa17c05ce0b180db622736845d4315519397a77beaf", size = 2325979, upload-time = "2025-08-10T21:27:12.917Z" },
+ { url = "https://files.pythonhosted.org/packages/fc/ff/b269eefd90f4ae14dcc74973d5a0f6d28d3b9bb1afd8c0340513afe6b39a/kiwisolver-1.4.9-cp314-cp314-musllinux_1_2_s390x.whl", hash = "sha256:77937e5e2a38a7b48eef0585114fe7930346993a88060d0bf886086d2aa49ef5", size = 2491456, upload-time = "2025-08-10T21:27:14.353Z" },
+ { url = "https://files.pythonhosted.org/packages/fc/d4/10303190bd4d30de547534601e259a4fbf014eed94aae3e5521129215086/kiwisolver-1.4.9-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:24c175051354f4a28c5d6a31c93906dc653e2bf234e8a4bbfb964892078898ce", size = 2294621, upload-time = "2025-08-10T21:27:15.808Z" },
+ { url = "https://files.pythonhosted.org/packages/28/e0/a9a90416fce5c0be25742729c2ea52105d62eda6c4be4d803c2a7be1fa50/kiwisolver-1.4.9-cp314-cp314-win_amd64.whl", hash = "sha256:0763515d4df10edf6d06a3c19734e2566368980d21ebec439f33f9eb936c07b7", size = 75417, upload-time = "2025-08-10T21:27:17.436Z" },
+ { url = "https://files.pythonhosted.org/packages/1f/10/6949958215b7a9a264299a7db195564e87900f709db9245e4ebdd3c70779/kiwisolver-1.4.9-cp314-cp314-win_arm64.whl", hash = "sha256:0e4e2bf29574a6a7b7f6cb5fa69293b9f96c928949ac4a53ba3f525dffb87f9c", size = 66582, upload-time = "2025-08-10T21:27:18.436Z" },
+ { url = "https://files.pythonhosted.org/packages/ec/79/60e53067903d3bc5469b369fe0dfc6b3482e2133e85dae9daa9527535991/kiwisolver-1.4.9-cp314-cp314t-macosx_10_13_universal2.whl", hash = "sha256:d976bbb382b202f71c67f77b0ac11244021cfa3f7dfd9e562eefcea2df711548", size = 126514, upload-time = "2025-08-10T21:27:19.465Z" },
+ { url = "https://files.pythonhosted.org/packages/25/d1/4843d3e8d46b072c12a38c97c57fab4608d36e13fe47d47ee96b4d61ba6f/kiwisolver-1.4.9-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:2489e4e5d7ef9a1c300a5e0196e43d9c739f066ef23270607d45aba368b91f2d", size = 67905, upload-time = "2025-08-10T21:27:20.51Z" },
+ { url = "https://files.pythonhosted.org/packages/8c/ae/29ffcbd239aea8b93108de1278271ae764dfc0d803a5693914975f200596/kiwisolver-1.4.9-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:e2ea9f7ab7fbf18fffb1b5434ce7c69a07582f7acc7717720f1d69f3e806f90c", size = 66399, upload-time = "2025-08-10T21:27:21.496Z" },
+ { url = "https://files.pythonhosted.org/packages/a1/ae/d7ba902aa604152c2ceba5d352d7b62106bedbccc8e95c3934d94472bfa3/kiwisolver-1.4.9-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:b34e51affded8faee0dfdb705416153819d8ea9250bbbf7ea1b249bdeb5f1122", size = 1582197, upload-time = "2025-08-10T21:27:22.604Z" },
+ { url = "https://files.pythonhosted.org/packages/f2/41/27c70d427eddb8bc7e4f16420a20fefc6f480312122a59a959fdfe0445ad/kiwisolver-1.4.9-cp314-cp314t-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:d8aacd3d4b33b772542b2e01beb50187536967b514b00003bdda7589722d2a64", size = 1390125, upload-time = "2025-08-10T21:27:24.036Z" },
+ { url = "https://files.pythonhosted.org/packages/41/42/b3799a12bafc76d962ad69083f8b43b12bf4fe78b097b12e105d75c9b8f1/kiwisolver-1.4.9-cp314-cp314t-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:7cf974dd4e35fa315563ac99d6287a1024e4dc2077b8a7d7cd3d2fb65d283134", size = 1402612, upload-time = "2025-08-10T21:27:25.773Z" },
+ { url = "https://files.pythonhosted.org/packages/d2/b5/a210ea073ea1cfaca1bb5c55a62307d8252f531beb364e18aa1e0888b5a0/kiwisolver-1.4.9-cp314-cp314t-manylinux_2_24_s390x.manylinux_2_28_s390x.whl", hash = "sha256:85bd218b5ecfbee8c8a82e121802dcb519a86044c9c3b2e4aef02fa05c6da370", size = 1453990, upload-time = "2025-08-10T21:27:27.089Z" },
+ { url = "https://files.pythonhosted.org/packages/5f/ce/a829eb8c033e977d7ea03ed32fb3c1781b4fa0433fbadfff29e39c676f32/kiwisolver-1.4.9-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:0856e241c2d3df4efef7c04a1e46b1936b6120c9bcf36dd216e3acd84bc4fb21", size = 2331601, upload-time = "2025-08-10T21:27:29.343Z" },
+ { url = "https://files.pythonhosted.org/packages/e0/4b/b5e97eb142eb9cd0072dacfcdcd31b1c66dc7352b0f7c7255d339c0edf00/kiwisolver-1.4.9-cp314-cp314t-musllinux_1_2_ppc64le.whl", hash = "sha256:9af39d6551f97d31a4deebeac6f45b156f9755ddc59c07b402c148f5dbb6482a", size = 2422041, upload-time = "2025-08-10T21:27:30.754Z" },
+ { url = "https://files.pythonhosted.org/packages/40/be/8eb4cd53e1b85ba4edc3a9321666f12b83113a178845593307a3e7891f44/kiwisolver-1.4.9-cp314-cp314t-musllinux_1_2_s390x.whl", hash = "sha256:bb4ae2b57fc1d8cbd1cf7b1d9913803681ffa903e7488012be5b76dedf49297f", size = 2594897, upload-time = "2025-08-10T21:27:32.803Z" },
+ { url = "https://files.pythonhosted.org/packages/99/dd/841e9a66c4715477ea0abc78da039832fbb09dac5c35c58dc4c41a407b8a/kiwisolver-1.4.9-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:aedff62918805fb62d43a4aa2ecd4482c380dc76cd31bd7c8878588a61bd0369", size = 2391835, upload-time = "2025-08-10T21:27:34.23Z" },
+ { url = "https://files.pythonhosted.org/packages/0c/28/4b2e5c47a0da96896fdfdb006340ade064afa1e63675d01ea5ac222b6d52/kiwisolver-1.4.9-cp314-cp314t-win_amd64.whl", hash = "sha256:1fa333e8b2ce4d9660f2cda9c0e1b6bafcfb2457a9d259faa82289e73ec24891", size = 79988, upload-time = "2025-08-10T21:27:35.587Z" },
+ { url = "https://files.pythonhosted.org/packages/80/be/3578e8afd18c88cdf9cb4cffde75a96d2be38c5a903f1ed0ceec061bd09e/kiwisolver-1.4.9-cp314-cp314t-win_arm64.whl", hash = "sha256:4a48a2ce79d65d363597ef7b567ce3d14d68783d2b2263d98db3d9477805ba32", size = 70260, upload-time = "2025-08-10T21:27:36.606Z" },
+ { url = "https://files.pythonhosted.org/packages/a3/0f/36d89194b5a32c054ce93e586d4049b6c2c22887b0eb229c61c68afd3078/kiwisolver-1.4.9-pp311-pypy311_pp73-macosx_10_15_x86_64.whl", hash = "sha256:720e05574713db64c356e86732c0f3c5252818d05f9df320f0ad8380641acea5", size = 60104, upload-time = "2025-08-10T21:27:43.287Z" },
+ { url = "https://files.pythonhosted.org/packages/52/ba/4ed75f59e4658fd21fe7dde1fee0ac397c678ec3befba3fe6482d987af87/kiwisolver-1.4.9-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:17680d737d5335b552994a2008fab4c851bcd7de33094a82067ef3a576ff02fa", size = 58592, upload-time = "2025-08-10T21:27:44.314Z" },
+ { url = "https://files.pythonhosted.org/packages/33/01/a8ea7c5ea32a9b45ceeaee051a04c8ed4320f5add3c51bfa20879b765b70/kiwisolver-1.4.9-pp311-pypy311_pp73-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:85b5352f94e490c028926ea567fc569c52ec79ce131dadb968d3853e809518c2", size = 80281, upload-time = "2025-08-10T21:27:45.369Z" },
+ { url = "https://files.pythonhosted.org/packages/da/e3/dbd2ecdce306f1d07a1aaf324817ee993aab7aee9db47ceac757deabafbe/kiwisolver-1.4.9-pp311-pypy311_pp73-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:464415881e4801295659462c49461a24fb107c140de781d55518c4b80cb6790f", size = 78009, upload-time = "2025-08-10T21:27:46.376Z" },
+ { url = "https://files.pythonhosted.org/packages/da/e9/0d4add7873a73e462aeb45c036a2dead2562b825aa46ba326727b3f31016/kiwisolver-1.4.9-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:fb940820c63a9590d31d88b815e7a3aa5915cad3ce735ab45f0c730b39547de1", size = 73929, upload-time = "2025-08-10T21:27:48.236Z" },
+]
+
+[[package]]
+name = "librt"
+version = "0.7.7"
+source = { registry = "https://pypi.org/simple" }
+sdist = { url = "https://files.pythonhosted.org/packages/b7/29/47f29026ca17f35cf299290292d5f8331f5077364974b7675a353179afa2/librt-0.7.7.tar.gz", hash = "sha256:81d957b069fed1890953c3b9c3895c7689960f233eea9a1d9607f71ce7f00b2c", size = 145910, upload-time = "2026-01-01T23:52:22.87Z" }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/f0/56/30b5c342518005546df78841cb0820ae85a17e7d07d521c10ef367306d0d/librt-0.7.7-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:a487b71fbf8a9edb72a8c7a456dda0184642d99cd007bc819c0b7ab93676a8ee", size = 54709, upload-time = "2026-01-01T23:51:02.774Z" },
+ { url = "https://files.pythonhosted.org/packages/72/78/9f120e3920b22504d4f3835e28b55acc2cc47c9586d2e1b6ba04c3c1bf01/librt-0.7.7-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:f4d4efb218264ecf0f8516196c9e2d1a0679d9fb3bb15df1155a35220062eba8", size = 56663, upload-time = "2026-01-01T23:51:03.838Z" },
+ { url = "https://files.pythonhosted.org/packages/1c/ea/7d7a1ee7dfc1151836028eba25629afcf45b56bbc721293e41aa2e9b8934/librt-0.7.7-cp311-cp311-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:b8bb331aad734b059c4b450cd0a225652f16889e286b2345af5e2c3c625c3d85", size = 161705, upload-time = "2026-01-01T23:51:04.917Z" },
+ { url = "https://files.pythonhosted.org/packages/45/a5/952bc840ac8917fbcefd6bc5f51ad02b89721729814f3e2bfcc1337a76d6/librt-0.7.7-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:467dbd7443bda08338fc8ad701ed38cef48194017554f4c798b0a237904b3f99", size = 171029, upload-time = "2026-01-01T23:51:06.09Z" },
+ { url = "https://files.pythonhosted.org/packages/fa/bf/c017ff7da82dc9192cf40d5e802a48a25d00e7639b6465cfdcee5893a22c/librt-0.7.7-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:50d1d1ee813d2d1a3baf2873634ba506b263032418d16287c92ec1cc9c1a00cb", size = 184704, upload-time = "2026-01-01T23:51:07.549Z" },
+ { url = "https://files.pythonhosted.org/packages/77/ec/72f3dd39d2cdfd6402ab10836dc9cbf854d145226062a185b419c4f1624a/librt-0.7.7-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:c7e5070cf3ec92d98f57574da0224f8c73faf1ddd6d8afa0b8c9f6e86997bc74", size = 180719, upload-time = "2026-01-01T23:51:09.062Z" },
+ { url = "https://files.pythonhosted.org/packages/78/86/06e7a1a81b246f3313bf515dd9613a1c81583e6fd7843a9f4d625c4e926d/librt-0.7.7-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:bdb9f3d865b2dafe7f9ad7f30ef563c80d0ddd2fdc8cc9b8e4f242f475e34d75", size = 174537, upload-time = "2026-01-01T23:51:10.611Z" },
+ { url = "https://files.pythonhosted.org/packages/83/08/f9fb2edc9c7a76e95b2924ce81d545673f5b034e8c5dd92159d1c7dae0c6/librt-0.7.7-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:8185c8497d45164e256376f9da5aed2bb26ff636c798c9dabe313b90e9f25b28", size = 195238, upload-time = "2026-01-01T23:51:11.762Z" },
+ { url = "https://files.pythonhosted.org/packages/ba/56/ea2d2489d3ea1f47b301120e03a099e22de7b32c93df9a211e6ff4f9bf38/librt-0.7.7-cp311-cp311-win32.whl", hash = "sha256:44d63ce643f34a903f09ff7ca355aae019a3730c7afd6a3c037d569beeb5d151", size = 42939, upload-time = "2026-01-01T23:51:13.192Z" },
+ { url = "https://files.pythonhosted.org/packages/58/7b/c288f417e42ba2a037f1c0753219e277b33090ed4f72f292fb6fe175db4c/librt-0.7.7-cp311-cp311-win_amd64.whl", hash = "sha256:7d13cc340b3b82134f8038a2bfe7137093693dcad8ba5773da18f95ad6b77a8a", size = 49240, upload-time = "2026-01-01T23:51:14.264Z" },
+ { url = "https://files.pythonhosted.org/packages/7c/24/738eb33a6c1516fdb2dfd2a35db6e5300f7616679b573585be0409bc6890/librt-0.7.7-cp311-cp311-win_arm64.whl", hash = "sha256:983de36b5a83fe9222f4f7dcd071f9b1ac6f3f17c0af0238dadfb8229588f890", size = 42613, upload-time = "2026-01-01T23:51:15.268Z" },
+ { url = "https://files.pythonhosted.org/packages/56/72/1cd9d752070011641e8aee046c851912d5f196ecd726fffa7aed2070f3e0/librt-0.7.7-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:2a85a1fc4ed11ea0eb0a632459ce004a2d14afc085a50ae3463cd3dfe1ce43fc", size = 55687, upload-time = "2026-01-01T23:51:16.291Z" },
+ { url = "https://files.pythonhosted.org/packages/50/aa/d5a1d4221c4fe7e76ae1459d24d6037783cb83c7645164c07d7daf1576ec/librt-0.7.7-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:c87654e29a35938baead1c4559858f346f4a2a7588574a14d784f300ffba0efd", size = 57136, upload-time = "2026-01-01T23:51:17.363Z" },
+ { url = "https://files.pythonhosted.org/packages/23/6f/0c86b5cb5e7ef63208c8cc22534df10ecc5278efc0d47fb8815577f3ca2f/librt-0.7.7-cp312-cp312-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:c9faaebb1c6212c20afd8043cd6ed9de0a47d77f91a6b5b48f4e46ed470703fe", size = 165320, upload-time = "2026-01-01T23:51:18.455Z" },
+ { url = "https://files.pythonhosted.org/packages/16/37/df4652690c29f645ffe405b58285a4109e9fe855c5bb56e817e3e75840b3/librt-0.7.7-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:1908c3e5a5ef86b23391448b47759298f87f997c3bd153a770828f58c2bb4630", size = 174216, upload-time = "2026-01-01T23:51:19.599Z" },
+ { url = "https://files.pythonhosted.org/packages/9a/d6/d3afe071910a43133ec9c0f3e4ce99ee6df0d4e44e4bddf4b9e1c6ed41cc/librt-0.7.7-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:dbc4900e95a98fc0729523be9d93a8fedebb026f32ed9ffc08acd82e3e181503", size = 189005, upload-time = "2026-01-01T23:51:21.052Z" },
+ { url = "https://files.pythonhosted.org/packages/d5/18/74060a870fe2d9fd9f47824eba6717ce7ce03124a0d1e85498e0e7efc1b2/librt-0.7.7-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:a7ea4e1fbd253e5c68ea0fe63d08577f9d288a73f17d82f652ebc61fa48d878d", size = 183961, upload-time = "2026-01-01T23:51:22.493Z" },
+ { url = "https://files.pythonhosted.org/packages/7c/5e/918a86c66304af66a3c1d46d54df1b2d0b8894babc42a14fb6f25511497f/librt-0.7.7-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:ef7699b7a5a244b1119f85c5bbc13f152cd38240cbb2baa19b769433bae98e50", size = 177610, upload-time = "2026-01-01T23:51:23.874Z" },
+ { url = "https://files.pythonhosted.org/packages/b2/d7/b5e58dc2d570f162e99201b8c0151acf40a03a39c32ab824dd4febf12736/librt-0.7.7-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:955c62571de0b181d9e9e0a0303c8bc90d47670a5eff54cf71bf5da61d1899cf", size = 199272, upload-time = "2026-01-01T23:51:25.341Z" },
+ { url = "https://files.pythonhosted.org/packages/18/87/8202c9bd0968bdddc188ec3811985f47f58ed161b3749299f2c0dd0f63fb/librt-0.7.7-cp312-cp312-win32.whl", hash = "sha256:1bcd79be209313b270b0e1a51c67ae1af28adad0e0c7e84c3ad4b5cb57aaa75b", size = 43189, upload-time = "2026-01-01T23:51:26.799Z" },
+ { url = "https://files.pythonhosted.org/packages/61/8d/80244b267b585e7aa79ffdac19f66c4861effc3a24598e77909ecdd0850e/librt-0.7.7-cp312-cp312-win_amd64.whl", hash = "sha256:4353ee891a1834567e0302d4bd5e60f531912179578c36f3d0430f8c5e16b456", size = 49462, upload-time = "2026-01-01T23:51:27.813Z" },
+ { url = "https://files.pythonhosted.org/packages/2d/1f/75db802d6a4992d95e8a889682601af9b49d5a13bbfa246d414eede1b56c/librt-0.7.7-cp312-cp312-win_arm64.whl", hash = "sha256:a76f1d679beccccdf8c1958e732a1dfcd6e749f8821ee59d7bec009ac308c029", size = 42828, upload-time = "2026-01-01T23:51:28.804Z" },
+ { url = "https://files.pythonhosted.org/packages/8d/5e/d979ccb0a81407ec47c14ea68fb217ff4315521730033e1dd9faa4f3e2c1/librt-0.7.7-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:8f4a0b0a3c86ba9193a8e23bb18f100d647bf192390ae195d84dfa0a10fb6244", size = 55746, upload-time = "2026-01-01T23:51:29.828Z" },
+ { url = "https://files.pythonhosted.org/packages/f5/2c/3b65861fb32f802c3783d6ac66fc5589564d07452a47a8cf9980d531cad3/librt-0.7.7-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:5335890fea9f9e6c4fdf8683061b9ccdcbe47c6dc03ab8e9b68c10acf78be78d", size = 57174, upload-time = "2026-01-01T23:51:31.226Z" },
+ { url = "https://files.pythonhosted.org/packages/50/df/030b50614b29e443607220097ebaf438531ea218c7a9a3e21ea862a919cd/librt-0.7.7-cp313-cp313-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:9b4346b1225be26def3ccc6c965751c74868f0578cbcba293c8ae9168483d811", size = 165834, upload-time = "2026-01-01T23:51:32.278Z" },
+ { url = "https://files.pythonhosted.org/packages/5d/e1/bd8d1eacacb24be26a47f157719553bbd1b3fe812c30dddf121c0436fd0b/librt-0.7.7-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:a10b8eebdaca6e9fdbaf88b5aefc0e324b763a5f40b1266532590d5afb268a4c", size = 174819, upload-time = "2026-01-01T23:51:33.461Z" },
+ { url = "https://files.pythonhosted.org/packages/46/7d/91d6c3372acf54a019c1ad8da4c9ecf4fc27d039708880bf95f48dbe426a/librt-0.7.7-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:067be973d90d9e319e6eb4ee2a9b9307f0ecd648b8a9002fa237289a4a07a9e7", size = 189607, upload-time = "2026-01-01T23:51:34.604Z" },
+ { url = "https://files.pythonhosted.org/packages/fa/ac/44604d6d3886f791fbd1c6ae12d5a782a8f4aca927484731979f5e92c200/librt-0.7.7-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:23d2299ed007812cccc1ecef018db7d922733382561230de1f3954db28433977", size = 184586, upload-time = "2026-01-01T23:51:35.845Z" },
+ { url = "https://files.pythonhosted.org/packages/5c/26/d8a6e4c17117b7f9b83301319d9a9de862ae56b133efb4bad8b3aa0808c9/librt-0.7.7-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:6b6f8ea465524aa4c7420c7cc4ca7d46fe00981de8debc67b1cc2e9957bb5b9d", size = 178251, upload-time = "2026-01-01T23:51:37.018Z" },
+ { url = "https://files.pythonhosted.org/packages/99/ab/98d857e254376f8e2f668e807daccc1f445e4b4fc2f6f9c1cc08866b0227/librt-0.7.7-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:f8df32a99cc46eb0ee90afd9ada113ae2cafe7e8d673686cf03ec53e49635439", size = 199853, upload-time = "2026-01-01T23:51:38.195Z" },
+ { url = "https://files.pythonhosted.org/packages/7c/55/4523210d6ae5134a5da959900be43ad8bab2e4206687b6620befddb5b5fd/librt-0.7.7-cp313-cp313-win32.whl", hash = "sha256:86f86b3b785487c7760247bcdac0b11aa8bf13245a13ed05206286135877564b", size = 43247, upload-time = "2026-01-01T23:51:39.629Z" },
+ { url = "https://files.pythonhosted.org/packages/25/40/3ec0fed5e8e9297b1cf1a3836fb589d3de55f9930e3aba988d379e8ef67c/librt-0.7.7-cp313-cp313-win_amd64.whl", hash = "sha256:4862cb2c702b1f905c0503b72d9d4daf65a7fdf5a9e84560e563471e57a56949", size = 49419, upload-time = "2026-01-01T23:51:40.674Z" },
+ { url = "https://files.pythonhosted.org/packages/1c/7a/aab5f0fb122822e2acbc776addf8b9abfb4944a9056c00c393e46e543177/librt-0.7.7-cp313-cp313-win_arm64.whl", hash = "sha256:0996c83b1cb43c00e8c87835a284f9057bc647abd42b5871e5f941d30010c832", size = 42828, upload-time = "2026-01-01T23:51:41.731Z" },
+ { url = "https://files.pythonhosted.org/packages/69/9c/228a5c1224bd23809a635490a162e9cbdc68d99f0eeb4a696f07886b8206/librt-0.7.7-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:23daa1ab0512bafdd677eb1bfc9611d8ffbe2e328895671e64cb34166bc1b8c8", size = 55188, upload-time = "2026-01-01T23:51:43.14Z" },
+ { url = "https://files.pythonhosted.org/packages/ba/c2/0e7c6067e2b32a156308205e5728f4ed6478c501947e9142f525afbc6bd2/librt-0.7.7-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:558a9e5a6f3cc1e20b3168fb1dc802d0d8fa40731f6e9932dcc52bbcfbd37111", size = 56895, upload-time = "2026-01-01T23:51:44.534Z" },
+ { url = "https://files.pythonhosted.org/packages/0e/77/de50ff70c80855eb79d1d74035ef06f664dd073fb7fb9d9fb4429651b8eb/librt-0.7.7-cp314-cp314-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:2567cb48dc03e5b246927ab35cbb343376e24501260a9b5e30b8e255dca0d1d2", size = 163724, upload-time = "2026-01-01T23:51:45.571Z" },
+ { url = "https://files.pythonhosted.org/packages/6e/19/f8e4bf537899bdef9e0bb9f0e4b18912c2d0f858ad02091b6019864c9a6d/librt-0.7.7-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6066c638cdf85ff92fc6f932d2d73c93a0e03492cdfa8778e6d58c489a3d7259", size = 172470, upload-time = "2026-01-01T23:51:46.823Z" },
+ { url = "https://files.pythonhosted.org/packages/42/4c/dcc575b69d99076768e8dd6141d9aecd4234cba7f0e09217937f52edb6ed/librt-0.7.7-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:a609849aca463074c17de9cda173c276eb8fee9e441053529e7b9e249dc8b8ee", size = 186806, upload-time = "2026-01-01T23:51:48.009Z" },
+ { url = "https://files.pythonhosted.org/packages/fe/f8/4094a2b7816c88de81239a83ede6e87f1138477d7ee956c30f136009eb29/librt-0.7.7-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:add4e0a000858fe9bb39ed55f31085506a5c38363e6eb4a1e5943a10c2bfc3d1", size = 181809, upload-time = "2026-01-01T23:51:49.35Z" },
+ { url = "https://files.pythonhosted.org/packages/1b/ac/821b7c0ab1b5a6cd9aee7ace8309c91545a2607185101827f79122219a7e/librt-0.7.7-cp314-cp314-musllinux_1_2_i686.whl", hash = "sha256:a3bfe73a32bd0bdb9a87d586b05a23c0a1729205d79df66dee65bb2e40d671ba", size = 175597, upload-time = "2026-01-01T23:51:50.636Z" },
+ { url = "https://files.pythonhosted.org/packages/71/f9/27f6bfbcc764805864c04211c6ed636fe1d58f57a7b68d1f4ae5ed74e0e0/librt-0.7.7-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:0ecce0544d3db91a40f8b57ae26928c02130a997b540f908cefd4d279d6c5848", size = 196506, upload-time = "2026-01-01T23:51:52.535Z" },
+ { url = "https://files.pythonhosted.org/packages/46/ba/c9b9c6fc931dd7ea856c573174ccaf48714905b1a7499904db2552e3bbaf/librt-0.7.7-cp314-cp314-win32.whl", hash = "sha256:8f7a74cf3a80f0c3b0ec75b0c650b2f0a894a2cec57ef75f6f72c1e82cdac61d", size = 39747, upload-time = "2026-01-01T23:51:53.683Z" },
+ { url = "https://files.pythonhosted.org/packages/c5/69/cd1269337c4cde3ee70176ee611ab0058aa42fc8ce5c9dce55f48facfcd8/librt-0.7.7-cp314-cp314-win_amd64.whl", hash = "sha256:3d1fe2e8df3268dd6734dba33ededae72ad5c3a859b9577bc00b715759c5aaab", size = 45971, upload-time = "2026-01-01T23:51:54.697Z" },
+ { url = "https://files.pythonhosted.org/packages/79/fd/e0844794423f5583108c5991313c15e2b400995f44f6ec6871f8aaf8243c/librt-0.7.7-cp314-cp314-win_arm64.whl", hash = "sha256:2987cf827011907d3dfd109f1be0d61e173d68b1270107bb0e89f2fca7f2ed6b", size = 39075, upload-time = "2026-01-01T23:51:55.726Z" },
+ { url = "https://files.pythonhosted.org/packages/42/02/211fd8f7c381e7b2a11d0fdfcd410f409e89967be2e705983f7c6342209a/librt-0.7.7-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:8e92c8de62b40bfce91d5e12c6e8b15434da268979b1af1a6589463549d491e6", size = 57368, upload-time = "2026-01-01T23:51:56.706Z" },
+ { url = "https://files.pythonhosted.org/packages/4c/b6/aca257affae73ece26041ae76032153266d110453173f67d7603058e708c/librt-0.7.7-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:f683dcd49e2494a7535e30f779aa1ad6e3732a019d80abe1309ea91ccd3230e3", size = 59238, upload-time = "2026-01-01T23:51:58.066Z" },
+ { url = "https://files.pythonhosted.org/packages/96/47/7383a507d8e0c11c78ca34c9d36eab9000db5989d446a2f05dc40e76c64f/librt-0.7.7-cp314-cp314t-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:9b15e5d17812d4d629ff576699954f74e2cc24a02a4fc401882dd94f81daba45", size = 183870, upload-time = "2026-01-01T23:51:59.204Z" },
+ { url = "https://files.pythonhosted.org/packages/a4/b8/50f3d8eec8efdaf79443963624175c92cec0ba84827a66b7fcfa78598e51/librt-0.7.7-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:c084841b879c4d9b9fa34e5d5263994f21aea7fd9c6add29194dbb41a6210536", size = 194608, upload-time = "2026-01-01T23:52:00.419Z" },
+ { url = "https://files.pythonhosted.org/packages/23/d9/1b6520793aadb59d891e3b98ee057a75de7f737e4a8b4b37fdbecb10d60f/librt-0.7.7-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:10c8fb9966f84737115513fecbaf257f9553d067a7dd45a69c2c7e5339e6a8dc", size = 206776, upload-time = "2026-01-01T23:52:01.705Z" },
+ { url = "https://files.pythonhosted.org/packages/ff/db/331edc3bba929d2756fa335bfcf736f36eff4efcb4f2600b545a35c2ae58/librt-0.7.7-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:9b5fb1ecb2c35362eab2dbd354fd1efa5a8440d3e73a68be11921042a0edc0ff", size = 203206, upload-time = "2026-01-01T23:52:03.315Z" },
+ { url = "https://files.pythonhosted.org/packages/b2/e1/6af79ec77204e85f6f2294fc171a30a91bb0e35d78493532ed680f5d98be/librt-0.7.7-cp314-cp314t-musllinux_1_2_i686.whl", hash = "sha256:d1454899909d63cc9199a89fcc4f81bdd9004aef577d4ffc022e600c412d57f3", size = 196697, upload-time = "2026-01-01T23:52:04.857Z" },
+ { url = "https://files.pythonhosted.org/packages/f3/46/de55ecce4b2796d6d243295c221082ca3a944dc2fb3a52dcc8660ce7727d/librt-0.7.7-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:7ef28f2e7a016b29792fe0a2dd04dec75725b32a1264e390c366103f834a9c3a", size = 217193, upload-time = "2026-01-01T23:52:06.159Z" },
+ { url = "https://files.pythonhosted.org/packages/41/61/33063e271949787a2f8dd33c5260357e3d512a114fc82ca7890b65a76e2d/librt-0.7.7-cp314-cp314t-win32.whl", hash = "sha256:5e419e0db70991b6ba037b70c1d5bbe92b20ddf82f31ad01d77a347ed9781398", size = 40277, upload-time = "2026-01-01T23:52:07.625Z" },
+ { url = "https://files.pythonhosted.org/packages/06/21/1abd972349f83a696ea73159ac964e63e2d14086fdd9bc7ca878c25fced4/librt-0.7.7-cp314-cp314t-win_amd64.whl", hash = "sha256:d6b7d93657332c817b8d674ef6bf1ab7796b4f7ce05e420fd45bd258a72ac804", size = 46765, upload-time = "2026-01-01T23:52:08.647Z" },
+ { url = "https://files.pythonhosted.org/packages/51/0e/b756c7708143a63fca65a51ca07990fa647db2cc8fcd65177b9e96680255/librt-0.7.7-cp314-cp314t-win_arm64.whl", hash = "sha256:142c2cd91794b79fd0ce113bd658993b7ede0fe93057668c2f98a45ca00b7e91", size = 39724, upload-time = "2026-01-01T23:52:09.745Z" },
+]
+
+[[package]]
+name = "matplotlib"
+version = "3.10.8"
+source = { registry = "https://pypi.org/simple" }
+dependencies = [
+ { name = "contourpy" },
+ { name = "cycler" },
+ { name = "fonttools" },
+ { name = "kiwisolver" },
+ { name = "numpy" },
+ { name = "packaging" },
+ { name = "pillow" },
+ { name = "pyparsing" },
+ { name = "python-dateutil" },
+]
+sdist = { url = "https://files.pythonhosted.org/packages/8a/76/d3c6e3a13fe484ebe7718d14e269c9569c4eb0020a968a327acb3b9a8fe6/matplotlib-3.10.8.tar.gz", hash = "sha256:2299372c19d56bcd35cf05a2738308758d32b9eaed2371898d8f5bd33f084aa3", size = 34806269, upload-time = "2025-12-10T22:56:51.155Z" }
wheels = [
- { url = "https://files.pythonhosted.org/packages/6c/b0/bfa1f6f2c956b948802ef5a021281978bf53b7a6ca54bb126fd88a5d014e/jiter-0.8.2-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:ca1f08b8e43dc3bd0594c992fb1fd2f7ce87f7bf0d44358198d6da8034afdf84", size = 301190 },
- { url = "https://files.pythonhosted.org/packages/a4/8f/396ddb4e292b5ea57e45ade5dc48229556b9044bad29a3b4b2dddeaedd52/jiter-0.8.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:5672a86d55416ccd214c778efccf3266b84f87b89063b582167d803246354be4", size = 309334 },
- { url = "https://files.pythonhosted.org/packages/7f/68/805978f2f446fa6362ba0cc2e4489b945695940656edd844e110a61c98f8/jiter-0.8.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:58dc9bc9767a1101f4e5e22db1b652161a225874d66f0e5cb8e2c7d1c438b587", size = 333918 },
- { url = "https://files.pythonhosted.org/packages/b3/99/0f71f7be667c33403fa9706e5b50583ae5106d96fab997fa7e2f38ee8347/jiter-0.8.2-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:37b2998606d6dadbb5ccda959a33d6a5e853252d921fec1792fc902351bb4e2c", size = 356057 },
- { url = "https://files.pythonhosted.org/packages/8d/50/a82796e421a22b699ee4d2ce527e5bcb29471a2351cbdc931819d941a167/jiter-0.8.2-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:4ab9a87f3784eb0e098f84a32670cfe4a79cb6512fd8f42ae3d0709f06405d18", size = 379790 },
- { url = "https://files.pythonhosted.org/packages/3c/31/10fb012b00f6d83342ca9e2c9618869ab449f1aa78c8f1b2193a6b49647c/jiter-0.8.2-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:79aec8172b9e3c6d05fd4b219d5de1ac616bd8da934107325a6c0d0e866a21b6", size = 388285 },
- { url = "https://files.pythonhosted.org/packages/c8/81/f15ebf7de57be488aa22944bf4274962aca8092e4f7817f92ffa50d3ee46/jiter-0.8.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:711e408732d4e9a0208008e5892c2966b485c783cd2d9a681f3eb147cf36c7ef", size = 344764 },
- { url = "https://files.pythonhosted.org/packages/b3/e8/0cae550d72b48829ba653eb348cdc25f3f06f8a62363723702ec18e7be9c/jiter-0.8.2-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:653cf462db4e8c41995e33d865965e79641ef45369d8a11f54cd30888b7e6ff1", size = 376620 },
- { url = "https://files.pythonhosted.org/packages/b8/50/e5478ff9d82534a944c03b63bc217c5f37019d4a34d288db0f079b13c10b/jiter-0.8.2-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:9c63eaef32b7bebac8ebebf4dabebdbc6769a09c127294db6babee38e9f405b9", size = 510402 },
- { url = "https://files.pythonhosted.org/packages/8e/1e/3de48bbebbc8f7025bd454cedc8c62378c0e32dd483dece5f4a814a5cb55/jiter-0.8.2-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:eb21aaa9a200d0a80dacc7a81038d2e476ffe473ffdd9c91eb745d623561de05", size = 503018 },
- { url = "https://files.pythonhosted.org/packages/d5/cd/d5a5501d72a11fe3e5fd65c78c884e5164eefe80077680533919be22d3a3/jiter-0.8.2-cp313-cp313-win32.whl", hash = "sha256:789361ed945d8d42850f919342a8665d2dc79e7e44ca1c97cc786966a21f627a", size = 203190 },
- { url = "https://files.pythonhosted.org/packages/51/bf/e5ca301245ba951447e3ad677a02a64a8845b185de2603dabd83e1e4b9c6/jiter-0.8.2-cp313-cp313-win_amd64.whl", hash = "sha256:ab7f43235d71e03b941c1630f4b6e3055d46b6cb8728a17663eaac9d8e83a865", size = 203551 },
- { url = "https://files.pythonhosted.org/packages/2f/3c/71a491952c37b87d127790dd7a0b1ebea0514c6b6ad30085b16bbe00aee6/jiter-0.8.2-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:b426f72cd77da3fec300ed3bc990895e2dd6b49e3bfe6c438592a3ba660e41ca", size = 308347 },
- { url = "https://files.pythonhosted.org/packages/a0/4c/c02408042e6a7605ec063daed138e07b982fdb98467deaaf1c90950cf2c6/jiter-0.8.2-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b2dd880785088ff2ad21ffee205e58a8c1ddabc63612444ae41e5e4b321b39c0", size = 342875 },
- { url = "https://files.pythonhosted.org/packages/91/61/c80ef80ed8a0a21158e289ef70dac01e351d929a1c30cb0f49be60772547/jiter-0.8.2-cp313-cp313t-win_amd64.whl", hash = "sha256:3ac9f578c46f22405ff7f8b1f5848fb753cc4b8377fbec8470a7dc3997ca7566", size = 202374 },
+ { url = "https://files.pythonhosted.org/packages/f8/86/de7e3a1cdcfc941483af70609edc06b83e7c8a0e0dc9ac325200a3f4d220/matplotlib-3.10.8-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:6be43b667360fef5c754dda5d25a32e6307a03c204f3c0fc5468b78fa87b4160", size = 8251215, upload-time = "2025-12-10T22:55:16.175Z" },
+ { url = "https://files.pythonhosted.org/packages/fd/14/baad3222f424b19ce6ad243c71de1ad9ec6b2e4eb1e458a48fdc6d120401/matplotlib-3.10.8-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:a2b336e2d91a3d7006864e0990c83b216fcdca64b5a6484912902cef87313d78", size = 8139625, upload-time = "2025-12-10T22:55:17.712Z" },
+ { url = "https://files.pythonhosted.org/packages/8f/a0/7024215e95d456de5883e6732e708d8187d9753a21d32f8ddb3befc0c445/matplotlib-3.10.8-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:efb30e3baaea72ce5928e32bab719ab4770099079d66726a62b11b1ef7273be4", size = 8712614, upload-time = "2025-12-10T22:55:20.8Z" },
+ { url = "https://files.pythonhosted.org/packages/5a/f4/b8347351da9a5b3f41e26cf547252d861f685c6867d179a7c9d60ad50189/matplotlib-3.10.8-cp311-cp311-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:d56a1efd5bfd61486c8bc968fa18734464556f0fb8e51690f4ac25d85cbbbbc2", size = 9540997, upload-time = "2025-12-10T22:55:23.258Z" },
+ { url = "https://files.pythonhosted.org/packages/9e/c0/c7b914e297efe0bc36917bf216b2acb91044b91e930e878ae12981e461e5/matplotlib-3.10.8-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:238b7ce5717600615c895050239ec955d91f321c209dd110db988500558e70d6", size = 9596825, upload-time = "2025-12-10T22:55:25.217Z" },
+ { url = "https://files.pythonhosted.org/packages/6f/d3/a4bbc01c237ab710a1f22b4da72f4ff6d77eb4c7735ea9811a94ae239067/matplotlib-3.10.8-cp311-cp311-win_amd64.whl", hash = "sha256:18821ace09c763ec93aef5eeff087ee493a24051936d7b9ebcad9662f66501f9", size = 8135090, upload-time = "2025-12-10T22:55:27.162Z" },
+ { url = "https://files.pythonhosted.org/packages/89/dd/a0b6588f102beab33ca6f5218b31725216577b2a24172f327eaf6417d5c9/matplotlib-3.10.8-cp311-cp311-win_arm64.whl", hash = "sha256:bab485bcf8b1c7d2060b4fcb6fc368a9e6f4cd754c9c2fea281f4be21df394a2", size = 8012377, upload-time = "2025-12-10T22:55:29.185Z" },
+ { url = "https://files.pythonhosted.org/packages/9e/67/f997cdcbb514012eb0d10cd2b4b332667997fb5ebe26b8d41d04962fa0e6/matplotlib-3.10.8-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:64fcc24778ca0404ce0cb7b6b77ae1f4c7231cdd60e6778f999ee05cbd581b9a", size = 8260453, upload-time = "2025-12-10T22:55:30.709Z" },
+ { url = "https://files.pythonhosted.org/packages/7e/65/07d5f5c7f7c994f12c768708bd2e17a4f01a2b0f44a1c9eccad872433e2e/matplotlib-3.10.8-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:b9a5ca4ac220a0cdd1ba6bcba3608547117d30468fefce49bb26f55c1a3d5c58", size = 8148321, upload-time = "2025-12-10T22:55:33.265Z" },
+ { url = "https://files.pythonhosted.org/packages/3e/f3/c5195b1ae57ef85339fd7285dfb603b22c8b4e79114bae5f4f0fcf688677/matplotlib-3.10.8-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:3ab4aabc72de4ff77b3ec33a6d78a68227bf1123465887f9905ba79184a1cc04", size = 8716944, upload-time = "2025-12-10T22:55:34.922Z" },
+ { url = "https://files.pythonhosted.org/packages/00/f9/7638f5cc82ec8a7aa005de48622eecc3ed7c9854b96ba15bd76b7fd27574/matplotlib-3.10.8-cp312-cp312-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:24d50994d8c5816ddc35411e50a86ab05f575e2530c02752e02538122613371f", size = 9550099, upload-time = "2025-12-10T22:55:36.789Z" },
+ { url = "https://files.pythonhosted.org/packages/57/61/78cd5920d35b29fd2a0fe894de8adf672ff52939d2e9b43cb83cd5ce1bc7/matplotlib-3.10.8-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:99eefd13c0dc3b3c1b4d561c1169e65fe47aab7b8158754d7c084088e2329466", size = 9613040, upload-time = "2025-12-10T22:55:38.715Z" },
+ { url = "https://files.pythonhosted.org/packages/30/4e/c10f171b6e2f44d9e3a2b96efa38b1677439d79c99357600a62cc1e9594e/matplotlib-3.10.8-cp312-cp312-win_amd64.whl", hash = "sha256:dd80ecb295460a5d9d260df63c43f4afbdd832d725a531f008dad1664f458adf", size = 8142717, upload-time = "2025-12-10T22:55:41.103Z" },
+ { url = "https://files.pythonhosted.org/packages/f1/76/934db220026b5fef85f45d51a738b91dea7d70207581063cd9bd8fafcf74/matplotlib-3.10.8-cp312-cp312-win_arm64.whl", hash = "sha256:3c624e43ed56313651bc18a47f838b60d7b8032ed348911c54906b130b20071b", size = 8012751, upload-time = "2025-12-10T22:55:42.684Z" },
+ { url = "https://files.pythonhosted.org/packages/3d/b9/15fd5541ef4f5b9a17eefd379356cf12175fe577424e7b1d80676516031a/matplotlib-3.10.8-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:3f2e409836d7f5ac2f1c013110a4d50b9f7edc26328c108915f9075d7d7a91b6", size = 8261076, upload-time = "2025-12-10T22:55:44.648Z" },
+ { url = "https://files.pythonhosted.org/packages/8d/a0/2ba3473c1b66b9c74dc7107c67e9008cb1782edbe896d4c899d39ae9cf78/matplotlib-3.10.8-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:56271f3dac49a88d7fca5060f004d9d22b865f743a12a23b1e937a0be4818ee1", size = 8148794, upload-time = "2025-12-10T22:55:46.252Z" },
+ { url = "https://files.pythonhosted.org/packages/75/97/a471f1c3eb1fd6f6c24a31a5858f443891d5127e63a7788678d14e249aea/matplotlib-3.10.8-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:a0a7f52498f72f13d4a25ea70f35f4cb60642b466cbb0a9be951b5bc3f45a486", size = 8718474, upload-time = "2025-12-10T22:55:47.864Z" },
+ { url = "https://files.pythonhosted.org/packages/01/be/cd478f4b66f48256f42927d0acbcd63a26a893136456cd079c0cc24fbabf/matplotlib-3.10.8-cp313-cp313-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:646d95230efb9ca614a7a594d4fcacde0ac61d25e37dd51710b36477594963ce", size = 9549637, upload-time = "2025-12-10T22:55:50.048Z" },
+ { url = "https://files.pythonhosted.org/packages/5d/7c/8dc289776eae5109e268c4fb92baf870678dc048a25d4ac903683b86d5bf/matplotlib-3.10.8-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:f89c151aab2e2e23cb3fe0acad1e8b82841fd265379c4cecd0f3fcb34c15e0f6", size = 9613678, upload-time = "2025-12-10T22:55:52.21Z" },
+ { url = "https://files.pythonhosted.org/packages/64/40/37612487cc8a437d4dd261b32ca21fe2d79510fe74af74e1f42becb1bdb8/matplotlib-3.10.8-cp313-cp313-win_amd64.whl", hash = "sha256:e8ea3e2d4066083e264e75c829078f9e149fa119d27e19acd503de65e0b13149", size = 8142686, upload-time = "2025-12-10T22:55:54.253Z" },
+ { url = "https://files.pythonhosted.org/packages/66/52/8d8a8730e968185514680c2a6625943f70269509c3dcfc0dcf7d75928cb8/matplotlib-3.10.8-cp313-cp313-win_arm64.whl", hash = "sha256:c108a1d6fa78a50646029cb6d49808ff0fc1330fda87fa6f6250c6b5369b6645", size = 8012917, upload-time = "2025-12-10T22:55:56.268Z" },
+ { url = "https://files.pythonhosted.org/packages/b5/27/51fe26e1062f298af5ef66343d8ef460e090a27fea73036c76c35821df04/matplotlib-3.10.8-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:ad3d9833a64cf48cc4300f2b406c3d0f4f4724a91c0bd5640678a6ba7c102077", size = 8305679, upload-time = "2025-12-10T22:55:57.856Z" },
+ { url = "https://files.pythonhosted.org/packages/2c/1e/4de865bc591ac8e3062e835f42dd7fe7a93168d519557837f0e37513f629/matplotlib-3.10.8-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:eb3823f11823deade26ce3b9f40dcb4a213da7a670013929f31d5f5ed1055b22", size = 8198336, upload-time = "2025-12-10T22:55:59.371Z" },
+ { url = "https://files.pythonhosted.org/packages/c6/cb/2f7b6e75fb4dce87ef91f60cac4f6e34f4c145ab036a22318ec837971300/matplotlib-3.10.8-cp313-cp313t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:d9050fee89a89ed57b4fb2c1bfac9a3d0c57a0d55aed95949eedbc42070fea39", size = 8731653, upload-time = "2025-12-10T22:56:01.032Z" },
+ { url = "https://files.pythonhosted.org/packages/46/b3/bd9c57d6ba670a37ab31fb87ec3e8691b947134b201f881665b28cc039ff/matplotlib-3.10.8-cp313-cp313t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:b44d07310e404ba95f8c25aa5536f154c0a8ec473303535949e52eb71d0a1565", size = 9561356, upload-time = "2025-12-10T22:56:02.95Z" },
+ { url = "https://files.pythonhosted.org/packages/c0/3d/8b94a481456dfc9dfe6e39e93b5ab376e50998cddfd23f4ae3b431708f16/matplotlib-3.10.8-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:0a33deb84c15ede243aead39f77e990469fff93ad1521163305095b77b72ce4a", size = 9614000, upload-time = "2025-12-10T22:56:05.411Z" },
+ { url = "https://files.pythonhosted.org/packages/bd/cd/bc06149fe5585ba800b189a6a654a75f1f127e8aab02fd2be10df7fa500c/matplotlib-3.10.8-cp313-cp313t-win_amd64.whl", hash = "sha256:3a48a78d2786784cc2413e57397981fb45c79e968d99656706018d6e62e57958", size = 8220043, upload-time = "2025-12-10T22:56:07.551Z" },
+ { url = "https://files.pythonhosted.org/packages/e3/de/b22cf255abec916562cc04eef457c13e58a1990048de0c0c3604d082355e/matplotlib-3.10.8-cp313-cp313t-win_arm64.whl", hash = "sha256:15d30132718972c2c074cd14638c7f4592bd98719e2308bccea40e0538bc0cb5", size = 8062075, upload-time = "2025-12-10T22:56:09.178Z" },
+ { url = "https://files.pythonhosted.org/packages/3c/43/9c0ff7a2f11615e516c3b058e1e6e8f9614ddeca53faca06da267c48345d/matplotlib-3.10.8-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:b53285e65d4fa4c86399979e956235deb900be5baa7fc1218ea67fbfaeaadd6f", size = 8262481, upload-time = "2025-12-10T22:56:10.885Z" },
+ { url = "https://files.pythonhosted.org/packages/6f/ca/e8ae28649fcdf039fda5ef554b40a95f50592a3c47e6f7270c9561c12b07/matplotlib-3.10.8-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:32f8dce744be5569bebe789e46727946041199030db8aeb2954d26013a0eb26b", size = 8151473, upload-time = "2025-12-10T22:56:12.377Z" },
+ { url = "https://files.pythonhosted.org/packages/f1/6f/009d129ae70b75e88cbe7e503a12a4c0670e08ed748a902c2568909e9eb5/matplotlib-3.10.8-cp314-cp314-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:4cf267add95b1c88300d96ca837833d4112756045364f5c734a2276038dae27d", size = 9553896, upload-time = "2025-12-10T22:56:14.432Z" },
+ { url = "https://files.pythonhosted.org/packages/f5/26/4221a741eb97967bc1fd5e4c52b9aa5a91b2f4ec05b59f6def4d820f9df9/matplotlib-3.10.8-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:2cf5bd12cecf46908f286d7838b2abc6c91cda506c0445b8223a7c19a00df008", size = 9824193, upload-time = "2025-12-10T22:56:16.29Z" },
+ { url = "https://files.pythonhosted.org/packages/1f/f3/3abf75f38605772cf48a9daf5821cd4f563472f38b4b828c6fba6fa6d06e/matplotlib-3.10.8-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:41703cc95688f2516b480f7f339d8851a6035f18e100ee6a32bc0b8536a12a9c", size = 9615444, upload-time = "2025-12-10T22:56:18.155Z" },
+ { url = "https://files.pythonhosted.org/packages/93/a5/de89ac80f10b8dc615807ee1133cd99ac74082581196d4d9590bea10690d/matplotlib-3.10.8-cp314-cp314-win_amd64.whl", hash = "sha256:83d282364ea9f3e52363da262ce32a09dfe241e4080dcedda3c0db059d3c1f11", size = 8272719, upload-time = "2025-12-10T22:56:20.366Z" },
+ { url = "https://files.pythonhosted.org/packages/69/ce/b006495c19ccc0a137b48083168a37bd056392dee02f87dba0472f2797fe/matplotlib-3.10.8-cp314-cp314-win_arm64.whl", hash = "sha256:2c1998e92cd5999e295a731bcb2911c75f597d937341f3030cc24ef2733d78a8", size = 8144205, upload-time = "2025-12-10T22:56:22.239Z" },
+ { url = "https://files.pythonhosted.org/packages/68/d9/b31116a3a855bd313c6fcdb7226926d59b041f26061c6c5b1be66a08c826/matplotlib-3.10.8-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:b5a2b97dbdc7d4f353ebf343744f1d1f1cca8aa8bfddb4262fcf4306c3761d50", size = 8305785, upload-time = "2025-12-10T22:56:24.218Z" },
+ { url = "https://files.pythonhosted.org/packages/1e/90/6effe8103f0272685767ba5f094f453784057072f49b393e3ea178fe70a5/matplotlib-3.10.8-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:3f5c3e4da343bba819f0234186b9004faba952cc420fbc522dc4e103c1985908", size = 8198361, upload-time = "2025-12-10T22:56:26.787Z" },
+ { url = "https://files.pythonhosted.org/packages/d7/65/a73188711bea603615fc0baecca1061429ac16940e2385433cc778a9d8e7/matplotlib-3.10.8-cp314-cp314t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:5f62550b9a30afde8c1c3ae450e5eb547d579dd69b25c2fc7a1c67f934c1717a", size = 9561357, upload-time = "2025-12-10T22:56:28.953Z" },
+ { url = "https://files.pythonhosted.org/packages/f4/3d/b5c5d5d5be8ce63292567f0e2c43dde9953d3ed86ac2de0a72e93c8f07a1/matplotlib-3.10.8-cp314-cp314t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:495672de149445ec1b772ff2c9ede9b769e3cb4f0d0aa7fa730d7f59e2d4e1c1", size = 9823610, upload-time = "2025-12-10T22:56:31.455Z" },
+ { url = "https://files.pythonhosted.org/packages/4d/4b/e7beb6bbd49f6bae727a12b270a2654d13c397576d25bd6786e47033300f/matplotlib-3.10.8-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:595ba4d8fe983b88f0eec8c26a241e16d6376fe1979086232f481f8f3f67494c", size = 9614011, upload-time = "2025-12-10T22:56:33.85Z" },
+ { url = "https://files.pythonhosted.org/packages/7c/e6/76f2813d31f032e65f6f797e3f2f6e4aab95b65015924b1c51370395c28a/matplotlib-3.10.8-cp314-cp314t-win_amd64.whl", hash = "sha256:25d380fe8b1dc32cf8f0b1b448470a77afb195438bafdf1d858bfb876f3edf7b", size = 8362801, upload-time = "2025-12-10T22:56:36.107Z" },
+ { url = "https://files.pythonhosted.org/packages/5d/49/d651878698a0b67f23aa28e17f45a6d6dd3d3f933fa29087fa4ce5947b5a/matplotlib-3.10.8-cp314-cp314t-win_arm64.whl", hash = "sha256:113bb52413ea508ce954a02c10ffd0d565f9c3bc7f2eddc27dfe1731e71c7b5f", size = 8192560, upload-time = "2025-12-10T22:56:38.008Z" },
+ { url = "https://files.pythonhosted.org/packages/04/30/3afaa31c757f34b7725ab9d2ba8b48b5e89c2019c003e7d0ead143aabc5a/matplotlib-3.10.8-pp311-pypy311_pp73-macosx_10_15_x86_64.whl", hash = "sha256:6da7c2ce169267d0d066adcf63758f0604aa6c3eebf67458930f9d9b79ad1db1", size = 8249198, upload-time = "2025-12-10T22:56:45.584Z" },
+ { url = "https://files.pythonhosted.org/packages/48/2f/6334aec331f57485a642a7c8be03cb286f29111ae71c46c38b363230063c/matplotlib-3.10.8-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:9153c3292705be9f9c64498a8872118540c3f4123d1a1c840172edf262c8be4a", size = 8136817, upload-time = "2025-12-10T22:56:47.339Z" },
+ { url = "https://files.pythonhosted.org/packages/73/e4/6d6f14b2a759c622f191b2d67e9075a3f56aaccb3be4bb9bb6890030d0a0/matplotlib-3.10.8-pp311-pypy311_pp73-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:1ae029229a57cd1e8fe542485f27e7ca7b23aa9e8944ddb4985d0bc444f1eca2", size = 8713867, upload-time = "2025-12-10T22:56:48.954Z" },
]
[[package]]
-name = "markdown-it-py"
-version = "3.0.0"
+name = "mypy"
+version = "1.19.1"
source = { registry = "https://pypi.org/simple" }
dependencies = [
- { name = "mdurl" },
+ { name = "librt", marker = "platform_python_implementation != 'PyPy'" },
+ { name = "mypy-extensions" },
+ { name = "pathspec" },
+ { name = "typing-extensions" },
+]
+sdist = { url = "https://files.pythonhosted.org/packages/f5/db/4efed9504bc01309ab9c2da7e352cc223569f05478012b5d9ece38fd44d2/mypy-1.19.1.tar.gz", hash = "sha256:19d88bb05303fe63f71dd2c6270daca27cb9401c4ca8255fe50d1d920e0eb9ba", size = 3582404, upload-time = "2025-12-15T05:03:48.42Z" }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/ef/47/6b3ebabd5474d9cdc170d1342fbf9dddc1b0ec13ec90bf9004ee6f391c31/mypy-1.19.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:d8dfc6ab58ca7dda47d9237349157500468e404b17213d44fc1cb77bce532288", size = 13028539, upload-time = "2025-12-15T05:03:44.129Z" },
+ { url = "https://files.pythonhosted.org/packages/5c/a6/ac7c7a88a3c9c54334f53a941b765e6ec6c4ebd65d3fe8cdcfbe0d0fd7db/mypy-1.19.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:e3f276d8493c3c97930e354b2595a44a21348b320d859fb4a2b9f66da9ed27ab", size = 12083163, upload-time = "2025-12-15T05:03:37.679Z" },
+ { url = "https://files.pythonhosted.org/packages/67/af/3afa9cf880aa4a2c803798ac24f1d11ef72a0c8079689fac5cfd815e2830/mypy-1.19.1-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:2abb24cf3f17864770d18d673c85235ba52456b36a06b6afc1e07c1fdcd3d0e6", size = 12687629, upload-time = "2025-12-15T05:02:31.526Z" },
+ { url = "https://files.pythonhosted.org/packages/2d/46/20f8a7114a56484ab268b0ab372461cb3a8f7deed31ea96b83a4e4cfcfca/mypy-1.19.1-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:a009ffa5a621762d0c926a078c2d639104becab69e79538a494bcccb62cc0331", size = 13436933, upload-time = "2025-12-15T05:03:15.606Z" },
+ { url = "https://files.pythonhosted.org/packages/5b/f8/33b291ea85050a21f15da910002460f1f445f8007adb29230f0adea279cb/mypy-1.19.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:f7cee03c9a2e2ee26ec07479f38ea9c884e301d42c6d43a19d20fb014e3ba925", size = 13661754, upload-time = "2025-12-15T05:02:26.731Z" },
+ { url = "https://files.pythonhosted.org/packages/fd/a3/47cbd4e85bec4335a9cd80cf67dbc02be21b5d4c9c23ad6b95d6c5196bac/mypy-1.19.1-cp311-cp311-win_amd64.whl", hash = "sha256:4b84a7a18f41e167f7995200a1d07a4a6810e89d29859df936f1c3923d263042", size = 10055772, upload-time = "2025-12-15T05:03:26.179Z" },
+ { url = "https://files.pythonhosted.org/packages/06/8a/19bfae96f6615aa8a0604915512e0289b1fad33d5909bf7244f02935d33a/mypy-1.19.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:a8174a03289288c1f6c46d55cef02379b478bfbc8e358e02047487cad44c6ca1", size = 13206053, upload-time = "2025-12-15T05:03:46.622Z" },
+ { url = "https://files.pythonhosted.org/packages/a5/34/3e63879ab041602154ba2a9f99817bb0c85c4df19a23a1443c8986e4d565/mypy-1.19.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:ffcebe56eb09ff0c0885e750036a095e23793ba6c2e894e7e63f6d89ad51f22e", size = 12219134, upload-time = "2025-12-15T05:03:24.367Z" },
+ { url = "https://files.pythonhosted.org/packages/89/cc/2db6f0e95366b630364e09845672dbee0cbf0bbe753a204b29a944967cd9/mypy-1.19.1-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:b64d987153888790bcdb03a6473d321820597ab8dd9243b27a92153c4fa50fd2", size = 12731616, upload-time = "2025-12-15T05:02:44.725Z" },
+ { url = "https://files.pythonhosted.org/packages/00/be/dd56c1fd4807bc1eba1cf18b2a850d0de7bacb55e158755eb79f77c41f8e/mypy-1.19.1-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c35d298c2c4bba75feb2195655dfea8124d855dfd7343bf8b8c055421eaf0cf8", size = 13620847, upload-time = "2025-12-15T05:03:39.633Z" },
+ { url = "https://files.pythonhosted.org/packages/6d/42/332951aae42b79329f743bf1da088cd75d8d4d9acc18fbcbd84f26c1af4e/mypy-1.19.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:34c81968774648ab5ac09c29a375fdede03ba253f8f8287847bd480782f73a6a", size = 13834976, upload-time = "2025-12-15T05:03:08.786Z" },
+ { url = "https://files.pythonhosted.org/packages/6f/63/e7493e5f90e1e085c562bb06e2eb32cae27c5057b9653348d38b47daaecc/mypy-1.19.1-cp312-cp312-win_amd64.whl", hash = "sha256:b10e7c2cd7870ba4ad9b2d8a6102eb5ffc1f16ca35e3de6bfa390c1113029d13", size = 10118104, upload-time = "2025-12-15T05:03:10.834Z" },
+ { url = "https://files.pythonhosted.org/packages/de/9f/a6abae693f7a0c697dbb435aac52e958dc8da44e92e08ba88d2e42326176/mypy-1.19.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:e3157c7594ff2ef1634ee058aafc56a82db665c9438fd41b390f3bde1ab12250", size = 13201927, upload-time = "2025-12-15T05:02:29.138Z" },
+ { url = "https://files.pythonhosted.org/packages/9a/a4/45c35ccf6e1c65afc23a069f50e2c66f46bd3798cbe0d680c12d12935caa/mypy-1.19.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:bdb12f69bcc02700c2b47e070238f42cb87f18c0bc1fc4cdb4fb2bc5fd7a3b8b", size = 12206730, upload-time = "2025-12-15T05:03:01.325Z" },
+ { url = "https://files.pythonhosted.org/packages/05/bb/cdcf89678e26b187650512620eec8368fded4cfd99cfcb431e4cdfd19dec/mypy-1.19.1-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:f859fb09d9583a985be9a493d5cfc5515b56b08f7447759a0c5deaf68d80506e", size = 12724581, upload-time = "2025-12-15T05:03:20.087Z" },
+ { url = "https://files.pythonhosted.org/packages/d1/32/dd260d52babf67bad8e6770f8e1102021877ce0edea106e72df5626bb0ec/mypy-1.19.1-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c9a6538e0415310aad77cb94004ca6482330fece18036b5f360b62c45814c4ef", size = 13616252, upload-time = "2025-12-15T05:02:49.036Z" },
+ { url = "https://files.pythonhosted.org/packages/71/d0/5e60a9d2e3bd48432ae2b454b7ef2b62a960ab51292b1eda2a95edd78198/mypy-1.19.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:da4869fc5e7f62a88f3fe0b5c919d1d9f7ea3cef92d3689de2823fd27e40aa75", size = 13840848, upload-time = "2025-12-15T05:02:55.95Z" },
+ { url = "https://files.pythonhosted.org/packages/98/76/d32051fa65ecf6cc8c6610956473abdc9b4c43301107476ac03559507843/mypy-1.19.1-cp313-cp313-win_amd64.whl", hash = "sha256:016f2246209095e8eda7538944daa1d60e1e8134d98983b9fc1e92c1fc0cb8dd", size = 10135510, upload-time = "2025-12-15T05:02:58.438Z" },
+ { url = "https://files.pythonhosted.org/packages/de/eb/b83e75f4c820c4247a58580ef86fcd35165028f191e7e1ba57128c52782d/mypy-1.19.1-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:06e6170bd5836770e8104c8fdd58e5e725cfeb309f0a6c681a811f557e97eac1", size = 13199744, upload-time = "2025-12-15T05:03:30.823Z" },
+ { url = "https://files.pythonhosted.org/packages/94/28/52785ab7bfa165f87fcbb61547a93f98bb20e7f82f90f165a1f69bce7b3d/mypy-1.19.1-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:804bd67b8054a85447c8954215a906d6eff9cabeabe493fb6334b24f4bfff718", size = 12215815, upload-time = "2025-12-15T05:02:42.323Z" },
+ { url = "https://files.pythonhosted.org/packages/0a/c6/bdd60774a0dbfb05122e3e925f2e9e846c009e479dcec4821dad881f5b52/mypy-1.19.1-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:21761006a7f497cb0d4de3d8ef4ca70532256688b0523eee02baf9eec895e27b", size = 12740047, upload-time = "2025-12-15T05:03:33.168Z" },
+ { url = "https://files.pythonhosted.org/packages/32/2a/66ba933fe6c76bd40d1fe916a83f04fed253152f451a877520b3c4a5e41e/mypy-1.19.1-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:28902ee51f12e0f19e1e16fbe2f8f06b6637f482c459dd393efddd0ec7f82045", size = 13601998, upload-time = "2025-12-15T05:03:13.056Z" },
+ { url = "https://files.pythonhosted.org/packages/e3/da/5055c63e377c5c2418760411fd6a63ee2b96cf95397259038756c042574f/mypy-1.19.1-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:481daf36a4c443332e2ae9c137dfee878fcea781a2e3f895d54bd3002a900957", size = 13807476, upload-time = "2025-12-15T05:03:17.977Z" },
+ { url = "https://files.pythonhosted.org/packages/cd/09/4ebd873390a063176f06b0dbf1f7783dd87bd120eae7727fa4ae4179b685/mypy-1.19.1-cp314-cp314-win_amd64.whl", hash = "sha256:8bb5c6f6d043655e055be9b542aa5f3bdd30e4f3589163e85f93f3640060509f", size = 10281872, upload-time = "2025-12-15T05:03:05.549Z" },
+ { url = "https://files.pythonhosted.org/packages/8d/f4/4ce9a05ce5ded1de3ec1c1d96cf9f9504a04e54ce0ed55cfa38619a32b8d/mypy-1.19.1-py3-none-any.whl", hash = "sha256:f1235f5ea01b7db5468d53ece6aaddf1ad0b88d9e7462b86ef96fe04995d7247", size = 2471239, upload-time = "2025-12-15T05:03:07.248Z" },
]
-sdist = { url = "https://files.pythonhosted.org/packages/38/71/3b932df36c1a044d397a1f92d1cf91ee0a503d91e470cbd670aa66b07ed0/markdown-it-py-3.0.0.tar.gz", hash = "sha256:e3f60a94fa066dc52ec76661e37c851cb232d92f9886b15cb560aaada2df8feb", size = 74596 }
+
+[[package]]
+name = "mypy-extensions"
+version = "1.1.0"
+source = { registry = "https://pypi.org/simple" }
+sdist = { url = "https://files.pythonhosted.org/packages/a2/6e/371856a3fb9d31ca8dac321cda606860fa4548858c0cc45d9d1d4ca2628b/mypy_extensions-1.1.0.tar.gz", hash = "sha256:52e68efc3284861e772bbcd66823fde5ae21fd2fdb51c62a211403730b916558", size = 6343, upload-time = "2025-04-22T14:54:24.164Z" }
wheels = [
- { url = "https://files.pythonhosted.org/packages/42/d7/1ec15b46af6af88f19b8e5ffea08fa375d433c998b8a7639e76935c14f1f/markdown_it_py-3.0.0-py3-none-any.whl", hash = "sha256:355216845c60bd96232cd8d8c40e8f9765cc86f46880e43a8fd22dc1a1a8cab1", size = 87528 },
+ { url = "https://files.pythonhosted.org/packages/79/7b/2c79738432f5c924bef5071f933bcc9efd0473bac3b4aa584a6f7c1c8df8/mypy_extensions-1.1.0-py3-none-any.whl", hash = "sha256:1be4cccdb0f2482337c4743e60421de3a356cd97508abadd57d47403e94f5505", size = 4963, upload-time = "2025-04-22T14:54:22.983Z" },
]
[[package]]
-name = "mdurl"
-version = "0.1.2"
+name = "numpy"
+version = "2.4.0"
source = { registry = "https://pypi.org/simple" }
-sdist = { url = "https://files.pythonhosted.org/packages/d6/54/cfe61301667036ec958cb99bd3efefba235e65cdeb9c84d24a8293ba1d90/mdurl-0.1.2.tar.gz", hash = "sha256:bb413d29f5eea38f31dd4754dd7377d4465116fb207585f97bf925588687c1ba", size = 8729 }
+sdist = { url = "https://files.pythonhosted.org/packages/a4/7a/6a3d14e205d292b738db449d0de649b373a59edb0d0b4493821d0a3e8718/numpy-2.4.0.tar.gz", hash = "sha256:6e504f7b16118198f138ef31ba24d985b124c2c469fe8467007cf30fd992f934", size = 20685720, upload-time = "2025-12-20T16:18:19.023Z" }
wheels = [
- { url = "https://files.pythonhosted.org/packages/b3/38/89ba8ad64ae25be8de66a6d463314cf1eb366222074cfda9ee839c56a4b4/mdurl-0.1.2-py3-none-any.whl", hash = "sha256:84008a41e51615a49fc9966191ff91509e3c40b939176e643fd50a5c2196b8f8", size = 9979 },
+ { url = "https://files.pythonhosted.org/packages/26/7e/7bae7cbcc2f8132271967aa03e03954fc1e48aa1f3bf32b29ca95fbef352/numpy-2.4.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:316b2f2584682318539f0bcaca5a496ce9ca78c88066579ebd11fd06f8e4741e", size = 16940166, upload-time = "2025-12-20T16:15:43.434Z" },
+ { url = "https://files.pythonhosted.org/packages/0f/27/6c13f5b46776d6246ec884ac5817452672156a506d08a1f2abb39961930a/numpy-2.4.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:a2718c1de8504121714234b6f8241d0019450353276c88b9453c9c3d92e101db", size = 12641781, upload-time = "2025-12-20T16:15:45.701Z" },
+ { url = "https://files.pythonhosted.org/packages/14/1c/83b4998d4860d15283241d9e5215f28b40ac31f497c04b12fa7f428ff370/numpy-2.4.0-cp311-cp311-macosx_14_0_arm64.whl", hash = "sha256:21555da4ec4a0c942520ead42c3b0dc9477441e085c42b0fbdd6a084869a6f6b", size = 5470247, upload-time = "2025-12-20T16:15:47.943Z" },
+ { url = "https://files.pythonhosted.org/packages/54/08/cbce72c835d937795571b0464b52069f869c9e78b0c076d416c5269d2718/numpy-2.4.0-cp311-cp311-macosx_14_0_x86_64.whl", hash = "sha256:413aa561266a4be2d06cd2b9665e89d9f54c543f418773076a76adcf2af08bc7", size = 6799807, upload-time = "2025-12-20T16:15:49.795Z" },
+ { url = "https://files.pythonhosted.org/packages/ff/be/2e647961cd8c980591d75cdcd9e8f647d69fbe05e2a25613dc0a2ea5fb1a/numpy-2.4.0-cp311-cp311-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:0feafc9e03128074689183031181fac0897ff169692d8492066e949041096548", size = 14701992, upload-time = "2025-12-20T16:15:51.615Z" },
+ { url = "https://files.pythonhosted.org/packages/a2/fb/e1652fb8b6fd91ce6ed429143fe2e01ce714711e03e5b762615e7b36172c/numpy-2.4.0-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:a8fdfed3deaf1928fb7667d96e0567cdf58c2b370ea2ee7e586aa383ec2cb346", size = 16646871, upload-time = "2025-12-20T16:15:54.129Z" },
+ { url = "https://files.pythonhosted.org/packages/62/23/d841207e63c4322842f7cd042ae981cffe715c73376dcad8235fb31debf1/numpy-2.4.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:e06a922a469cae9a57100864caf4f8a97a1026513793969f8ba5b63137a35d25", size = 16487190, upload-time = "2025-12-20T16:15:56.147Z" },
+ { url = "https://files.pythonhosted.org/packages/bc/a0/6a842c8421ebfdec0a230e65f61e0dabda6edbef443d999d79b87c273965/numpy-2.4.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:927ccf5cd17c48f801f4ed43a7e5673a2724bd2171460be3e3894e6e332ef83a", size = 18580762, upload-time = "2025-12-20T16:15:58.524Z" },
+ { url = "https://files.pythonhosted.org/packages/0a/d1/c79e0046641186f2134dde05e6181825b911f8bdcef31b19ddd16e232847/numpy-2.4.0-cp311-cp311-win32.whl", hash = "sha256:882567b7ae57c1b1a0250208cc21a7976d8cbcc49d5a322e607e6f09c9e0bd53", size = 6233359, upload-time = "2025-12-20T16:16:00.938Z" },
+ { url = "https://files.pythonhosted.org/packages/fc/f0/74965001d231f28184d6305b8cdc1b6fcd4bf23033f6cb039cfe76c9fca7/numpy-2.4.0-cp311-cp311-win_amd64.whl", hash = "sha256:8b986403023c8f3bf8f487c2e6186afda156174d31c175f747d8934dfddf3479", size = 12601132, upload-time = "2025-12-20T16:16:02.484Z" },
+ { url = "https://files.pythonhosted.org/packages/65/32/55408d0f46dfebce38017f5bd931affa7256ad6beac1a92a012e1fbc67a7/numpy-2.4.0-cp311-cp311-win_arm64.whl", hash = "sha256:3f3096405acc48887458bbf9f6814d43785ac7ba2a57ea6442b581dedbc60ce6", size = 10573977, upload-time = "2025-12-20T16:16:04.77Z" },
+ { url = "https://files.pythonhosted.org/packages/8b/ff/f6400ffec95de41c74b8e73df32e3fff1830633193a7b1e409be7fb1bb8c/numpy-2.4.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:2a8b6bb8369abefb8bd1801b054ad50e02b3275c8614dc6e5b0373c305291037", size = 16653117, upload-time = "2025-12-20T16:16:06.709Z" },
+ { url = "https://files.pythonhosted.org/packages/fd/28/6c23e97450035072e8d830a3c411bf1abd1f42c611ff9d29e3d8f55c6252/numpy-2.4.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:2e284ca13d5a8367e43734148622caf0b261b275673823593e3e3634a6490f83", size = 12369711, upload-time = "2025-12-20T16:16:08.758Z" },
+ { url = "https://files.pythonhosted.org/packages/bc/af/acbef97b630ab1bb45e6a7d01d1452e4251aa88ce680ac36e56c272120ec/numpy-2.4.0-cp312-cp312-macosx_14_0_arm64.whl", hash = "sha256:49ff32b09f5aa0cd30a20c2b39db3e669c845589f2b7fc910365210887e39344", size = 5198355, upload-time = "2025-12-20T16:16:10.902Z" },
+ { url = "https://files.pythonhosted.org/packages/c1/c8/4e0d436b66b826f2e53330adaa6311f5cac9871a5b5c31ad773b27f25a74/numpy-2.4.0-cp312-cp312-macosx_14_0_x86_64.whl", hash = "sha256:36cbfb13c152b1c7c184ddac43765db8ad672567e7bafff2cc755a09917ed2e6", size = 6545298, upload-time = "2025-12-20T16:16:12.607Z" },
+ { url = "https://files.pythonhosted.org/packages/ef/27/e1f5d144ab54eac34875e79037011d511ac57b21b220063310cb96c80fbc/numpy-2.4.0-cp312-cp312-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:35ddc8f4914466e6fc954c76527aa91aa763682a4f6d73249ef20b418fe6effb", size = 14398387, upload-time = "2025-12-20T16:16:14.257Z" },
+ { url = "https://files.pythonhosted.org/packages/67/64/4cb909dd5ab09a9a5d086eff9586e69e827b88a5585517386879474f4cf7/numpy-2.4.0-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:dc578891de1db95b2a35001b695451767b580bb45753717498213c5ff3c41d63", size = 16363091, upload-time = "2025-12-20T16:16:17.32Z" },
+ { url = "https://files.pythonhosted.org/packages/9d/9c/8efe24577523ec6809261859737cf117b0eb6fdb655abdfdc81b2e468ce4/numpy-2.4.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:98e81648e0b36e325ab67e46b5400a7a6d4a22b8a7c8e8bbfe20e7db7906bf95", size = 16176394, upload-time = "2025-12-20T16:16:19.524Z" },
+ { url = "https://files.pythonhosted.org/packages/61/f0/1687441ece7b47a62e45a1f82015352c240765c707928edd8aef875d5951/numpy-2.4.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:d57b5046c120561ba8fa8e4030fbb8b822f3063910fa901ffadf16e2b7128ad6", size = 18287378, upload-time = "2025-12-20T16:16:22.866Z" },
+ { url = "https://files.pythonhosted.org/packages/d3/6f/f868765d44e6fc466467ed810ba9d8d6db1add7d4a748abfa2a4c99a3194/numpy-2.4.0-cp312-cp312-win32.whl", hash = "sha256:92190db305a6f48734d3982f2c60fa30d6b5ee9bff10f2887b930d7b40119f4c", size = 5955432, upload-time = "2025-12-20T16:16:25.06Z" },
+ { url = "https://files.pythonhosted.org/packages/d4/b5/94c1e79fcbab38d1ca15e13777477b2914dd2d559b410f96949d6637b085/numpy-2.4.0-cp312-cp312-win_amd64.whl", hash = "sha256:680060061adb2d74ce352628cb798cfdec399068aa7f07ba9fb818b2b3305f98", size = 12306201, upload-time = "2025-12-20T16:16:26.979Z" },
+ { url = "https://files.pythonhosted.org/packages/70/09/c39dadf0b13bb0768cd29d6a3aaff1fb7c6905ac40e9aaeca26b1c086e06/numpy-2.4.0-cp312-cp312-win_arm64.whl", hash = "sha256:39699233bc72dd482da1415dcb06076e32f60eddc796a796c5fb6c5efce94667", size = 10308234, upload-time = "2025-12-20T16:16:29.417Z" },
+ { url = "https://files.pythonhosted.org/packages/a7/0d/853fd96372eda07c824d24adf02e8bc92bb3731b43a9b2a39161c3667cc4/numpy-2.4.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:a152d86a3ae00ba5f47b3acf3b827509fd0b6cb7d3259665e63dafbad22a75ea", size = 16649088, upload-time = "2025-12-20T16:16:31.421Z" },
+ { url = "https://files.pythonhosted.org/packages/e3/37/cc636f1f2a9f585434e20a3e6e63422f70bfe4f7f6698e941db52ea1ac9a/numpy-2.4.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:39b19251dec4de8ff8496cd0806cbe27bf0684f765abb1f4809554de93785f2d", size = 12364065, upload-time = "2025-12-20T16:16:33.491Z" },
+ { url = "https://files.pythonhosted.org/packages/ed/69/0b78f37ca3690969beee54103ce5f6021709134e8020767e93ba691a72f1/numpy-2.4.0-cp313-cp313-macosx_14_0_arm64.whl", hash = "sha256:009bd0ea12d3c784b6639a8457537016ce5172109e585338e11334f6a7bb88ee", size = 5192640, upload-time = "2025-12-20T16:16:35.636Z" },
+ { url = "https://files.pythonhosted.org/packages/1d/2a/08569f8252abf590294dbb09a430543ec8f8cc710383abfb3e75cc73aeda/numpy-2.4.0-cp313-cp313-macosx_14_0_x86_64.whl", hash = "sha256:5fe44e277225fd3dff6882d86d3d447205d43532c3627313d17e754fb3905a0e", size = 6541556, upload-time = "2025-12-20T16:16:37.276Z" },
+ { url = "https://files.pythonhosted.org/packages/93/e9/a949885a4e177493d61519377952186b6cbfdf1d6002764c664ba28349b5/numpy-2.4.0-cp313-cp313-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:f935c4493eda9069851058fa0d9e39dbf6286be690066509305e52912714dbb2", size = 14396562, upload-time = "2025-12-20T16:16:38.953Z" },
+ { url = "https://files.pythonhosted.org/packages/99/98/9d4ad53b0e9ef901c2ef1d550d2136f5ac42d3fd2988390a6def32e23e48/numpy-2.4.0-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:8cfa5f29a695cb7438965e6c3e8d06e0416060cf0d709c1b1c1653a939bf5c2a", size = 16351719, upload-time = "2025-12-20T16:16:41.503Z" },
+ { url = "https://files.pythonhosted.org/packages/28/de/5f3711a38341d6e8dd619f6353251a0cdd07f3d6d101a8fd46f4ef87f895/numpy-2.4.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:ba0cb30acd3ef11c94dc27fbfba68940652492bc107075e7ffe23057f9425681", size = 16176053, upload-time = "2025-12-20T16:16:44.552Z" },
+ { url = "https://files.pythonhosted.org/packages/2a/5b/2a3753dc43916501b4183532e7ace862e13211042bceafa253afb5c71272/numpy-2.4.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:60e8c196cd82cbbd4f130b5290007e13e6de3eca79f0d4d38014769d96a7c475", size = 18277859, upload-time = "2025-12-20T16:16:47.174Z" },
+ { url = "https://files.pythonhosted.org/packages/2c/c5/a18bcdd07a941db3076ef489d036ab16d2bfc2eae0cf27e5a26e29189434/numpy-2.4.0-cp313-cp313-win32.whl", hash = "sha256:5f48cb3e88fbc294dc90e215d86fbaf1c852c63dbdb6c3a3e63f45c4b57f7344", size = 5953849, upload-time = "2025-12-20T16:16:49.554Z" },
+ { url = "https://files.pythonhosted.org/packages/4f/f1/719010ff8061da6e8a26e1980cf090412d4f5f8060b31f0c45d77dd67a01/numpy-2.4.0-cp313-cp313-win_amd64.whl", hash = "sha256:a899699294f28f7be8992853c0c60741f16ff199205e2e6cdca155762cbaa59d", size = 12302840, upload-time = "2025-12-20T16:16:51.227Z" },
+ { url = "https://files.pythonhosted.org/packages/f5/5a/b3d259083ed8b4d335270c76966cb6cf14a5d1b69e1a608994ac57a659e6/numpy-2.4.0-cp313-cp313-win_arm64.whl", hash = "sha256:9198f447e1dc5647d07c9a6bbe2063cc0132728cc7175b39dbc796da5b54920d", size = 10308509, upload-time = "2025-12-20T16:16:53.313Z" },
+ { url = "https://files.pythonhosted.org/packages/31/01/95edcffd1bb6c0633df4e808130545c4f07383ab629ac7e316fb44fff677/numpy-2.4.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:74623f2ab5cc3f7c886add4f735d1031a1d2be4a4ae63c0546cfd74e7a31ddf6", size = 12491815, upload-time = "2025-12-20T16:16:55.496Z" },
+ { url = "https://files.pythonhosted.org/packages/59/ea/5644b8baa92cc1c7163b4b4458c8679852733fa74ca49c942cfa82ded4e0/numpy-2.4.0-cp313-cp313t-macosx_14_0_arm64.whl", hash = "sha256:0804a8e4ab070d1d35496e65ffd3cf8114c136a2b81f61dfab0de4b218aacfd5", size = 5320321, upload-time = "2025-12-20T16:16:57.468Z" },
+ { url = "https://files.pythonhosted.org/packages/26/4e/e10938106d70bc21319bd6a86ae726da37edc802ce35a3a71ecdf1fdfe7f/numpy-2.4.0-cp313-cp313t-macosx_14_0_x86_64.whl", hash = "sha256:02a2038eb27f9443a8b266a66911e926566b5a6ffd1a689b588f7f35b81e7dc3", size = 6641635, upload-time = "2025-12-20T16:16:59.379Z" },
+ { url = "https://files.pythonhosted.org/packages/b3/8d/a8828e3eaf5c0b4ab116924df82f24ce3416fa38d0674d8f708ddc6c8aac/numpy-2.4.0-cp313-cp313t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:1889b3a3f47a7b5bee16bc25a2145bd7cb91897f815ce3499db64c7458b6d91d", size = 14456053, upload-time = "2025-12-20T16:17:01.768Z" },
+ { url = "https://files.pythonhosted.org/packages/68/a1/17d97609d87d4520aa5ae2dcfb32305654550ac6a35effb946d303e594ce/numpy-2.4.0-cp313-cp313t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:85eef4cb5625c47ee6425c58a3502555e10f45ee973da878ac8248ad58c136f3", size = 16401702, upload-time = "2025-12-20T16:17:04.235Z" },
+ { url = "https://files.pythonhosted.org/packages/18/32/0f13c1b2d22bea1118356b8b963195446f3af124ed7a5adfa8fdecb1b6ca/numpy-2.4.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:6dc8b7e2f4eb184b37655195f421836cfae6f58197b67e3ffc501f1333d993fa", size = 16242493, upload-time = "2025-12-20T16:17:06.856Z" },
+ { url = "https://files.pythonhosted.org/packages/ae/23/48f21e3d309fbc137c068a1475358cbd3a901b3987dcfc97a029ab3068e2/numpy-2.4.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:44aba2f0cafd287871a495fb3163408b0bd25bbce135c6f621534a07f4f7875c", size = 18324222, upload-time = "2025-12-20T16:17:09.392Z" },
+ { url = "https://files.pythonhosted.org/packages/ac/52/41f3d71296a3dcaa4f456aaa3c6fc8e745b43d0552b6bde56571bb4b4a0f/numpy-2.4.0-cp313-cp313t-win32.whl", hash = "sha256:20c115517513831860c573996e395707aa9fb691eb179200125c250e895fcd93", size = 6076216, upload-time = "2025-12-20T16:17:11.437Z" },
+ { url = "https://files.pythonhosted.org/packages/35/ff/46fbfe60ab0710d2a2b16995f708750307d30eccbb4c38371ea9e986866e/numpy-2.4.0-cp313-cp313t-win_amd64.whl", hash = "sha256:b48e35f4ab6f6a7597c46e301126ceba4c44cd3280e3750f85db48b082624fa4", size = 12444263, upload-time = "2025-12-20T16:17:13.182Z" },
+ { url = "https://files.pythonhosted.org/packages/a3/e3/9189ab319c01d2ed556c932ccf55064c5d75bb5850d1df7a482ce0badead/numpy-2.4.0-cp313-cp313t-win_arm64.whl", hash = "sha256:4d1cfce39e511069b11e67cd0bd78ceff31443b7c9e5c04db73c7a19f572967c", size = 10378265, upload-time = "2025-12-20T16:17:15.211Z" },
+ { url = "https://files.pythonhosted.org/packages/ab/ed/52eac27de39d5e5a6c9aadabe672bc06f55e24a3d9010cd1183948055d76/numpy-2.4.0-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:c95eb6db2884917d86cde0b4d4cf31adf485c8ec36bf8696dd66fa70de96f36b", size = 16647476, upload-time = "2025-12-20T16:17:17.671Z" },
+ { url = "https://files.pythonhosted.org/packages/77/c0/990ce1b7fcd4e09aeaa574e2a0a839589e4b08b2ca68070f1acb1fea6736/numpy-2.4.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:65167da969cd1ec3a1df31cb221ca3a19a8aaa25370ecb17d428415e93c1935e", size = 12374563, upload-time = "2025-12-20T16:17:20.216Z" },
+ { url = "https://files.pythonhosted.org/packages/37/7c/8c5e389c6ae8f5fd2277a988600d79e9625db3fff011a2d87ac80b881a4c/numpy-2.4.0-cp314-cp314-macosx_14_0_arm64.whl", hash = "sha256:3de19cfecd1465d0dcf8a5b5ea8b3155b42ed0b639dba4b71e323d74f2a3be5e", size = 5203107, upload-time = "2025-12-20T16:17:22.47Z" },
+ { url = "https://files.pythonhosted.org/packages/e6/94/ca5b3bd6a8a70a5eec9a0b8dd7f980c1eff4b8a54970a9a7fef248ef564f/numpy-2.4.0-cp314-cp314-macosx_14_0_x86_64.whl", hash = "sha256:6c05483c3136ac4c91b4e81903cb53a8707d316f488124d0398499a4f8e8ef51", size = 6538067, upload-time = "2025-12-20T16:17:24.001Z" },
+ { url = "https://files.pythonhosted.org/packages/79/43/993eb7bb5be6761dde2b3a3a594d689cec83398e3f58f4758010f3b85727/numpy-2.4.0-cp314-cp314-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:36667db4d6c1cea79c8930ab72fadfb4060feb4bfe724141cd4bd064d2e5f8ce", size = 14411926, upload-time = "2025-12-20T16:17:25.822Z" },
+ { url = "https://files.pythonhosted.org/packages/03/75/d4c43b61de473912496317a854dac54f1efec3eeb158438da6884b70bb90/numpy-2.4.0-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:9a818668b674047fd88c4cddada7ab8f1c298812783e8328e956b78dc4807f9f", size = 16354295, upload-time = "2025-12-20T16:17:28.308Z" },
+ { url = "https://files.pythonhosted.org/packages/b8/0a/b54615b47ee8736a6461a4bb6749128dd3435c5a759d5663f11f0e9af4ac/numpy-2.4.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:1ee32359fb7543b7b7bd0b2f46294db27e29e7bbdf70541e81b190836cd83ded", size = 16190242, upload-time = "2025-12-20T16:17:30.993Z" },
+ { url = "https://files.pythonhosted.org/packages/98/ce/ea207769aacad6246525ec6c6bbd66a2bf56c72443dc10e2f90feed29290/numpy-2.4.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:e493962256a38f58283de033d8af176c5c91c084ea30f15834f7545451c42059", size = 18280875, upload-time = "2025-12-20T16:17:33.327Z" },
+ { url = "https://files.pythonhosted.org/packages/17/ef/ec409437aa962ea372ed601c519a2b141701683ff028f894b7466f0ab42b/numpy-2.4.0-cp314-cp314-win32.whl", hash = "sha256:6bbaebf0d11567fa8926215ae731e1d58e6ec28a8a25235b8a47405d301332db", size = 6002530, upload-time = "2025-12-20T16:17:35.729Z" },
+ { url = "https://files.pythonhosted.org/packages/5f/4a/5cb94c787a3ed1ac65e1271b968686521169a7b3ec0b6544bb3ca32960b0/numpy-2.4.0-cp314-cp314-win_amd64.whl", hash = "sha256:3d857f55e7fdf7c38ab96c4558c95b97d1c685be6b05c249f5fdafcbd6f9899e", size = 12435890, upload-time = "2025-12-20T16:17:37.599Z" },
+ { url = "https://files.pythonhosted.org/packages/48/a0/04b89db963af9de1104975e2544f30de89adbf75b9e75f7dd2599be12c79/numpy-2.4.0-cp314-cp314-win_arm64.whl", hash = "sha256:bb50ce5fb202a26fd5404620e7ef820ad1ab3558b444cb0b55beb7ef66cd2d63", size = 10591892, upload-time = "2025-12-20T16:17:39.649Z" },
+ { url = "https://files.pythonhosted.org/packages/53/e5/d74b5ccf6712c06c7a545025a6a71bfa03bdc7e0568b405b0d655232fd92/numpy-2.4.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:355354388cba60f2132df297e2d53053d4063f79077b67b481d21276d61fc4df", size = 12494312, upload-time = "2025-12-20T16:17:41.714Z" },
+ { url = "https://files.pythonhosted.org/packages/c2/08/3ca9cc2ddf54dfee7ae9a6479c071092a228c68aef08252aa08dac2af002/numpy-2.4.0-cp314-cp314t-macosx_14_0_arm64.whl", hash = "sha256:1d8f9fde5f6dc1b6fc34df8162f3b3079365468703fee7f31d4e0cc8c63baed9", size = 5322862, upload-time = "2025-12-20T16:17:44.145Z" },
+ { url = "https://files.pythonhosted.org/packages/87/74/0bb63a68394c0c1e52670cfff2e309afa41edbe11b3327d9af29e4383f34/numpy-2.4.0-cp314-cp314t-macosx_14_0_x86_64.whl", hash = "sha256:e0434aa22c821f44eeb4c650b81c7fbdd8c0122c6c4b5a576a76d5a35625ecd9", size = 6644986, upload-time = "2025-12-20T16:17:46.203Z" },
+ { url = "https://files.pythonhosted.org/packages/06/8f/9264d9bdbcf8236af2823623fe2f3981d740fc3461e2787e231d97c38c28/numpy-2.4.0-cp314-cp314t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:40483b2f2d3ba7aad426443767ff5632ec3156ef09742b96913787d13c336471", size = 14457958, upload-time = "2025-12-20T16:17:48.017Z" },
+ { url = "https://files.pythonhosted.org/packages/8c/d9/f9a69ae564bbc7236a35aa883319364ef5fd41f72aa320cc1cbe66148fe2/numpy-2.4.0-cp314-cp314t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:d9e6a7664ddd9746e20b7325351fe1a8408d0a2bf9c63b5e898290ddc8f09544", size = 16398394, upload-time = "2025-12-20T16:17:50.409Z" },
+ { url = "https://files.pythonhosted.org/packages/34/c7/39241501408dde7f885d241a98caba5421061a2c6d2b2197ac5e3aa842d8/numpy-2.4.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:ecb0019d44f4cdb50b676c5d0cb4b1eae8e15d1ed3d3e6639f986fc92b2ec52c", size = 16241044, upload-time = "2025-12-20T16:17:52.661Z" },
+ { url = "https://files.pythonhosted.org/packages/7c/95/cae7effd90e065a95e59fe710eeee05d7328ed169776dfdd9f789e032125/numpy-2.4.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:d0ffd9e2e4441c96a9c91ec1783285d80bf835b677853fc2770a89d50c1e48ac", size = 18321772, upload-time = "2025-12-20T16:17:54.947Z" },
+ { url = "https://files.pythonhosted.org/packages/96/df/3c6c279accd2bfb968a76298e5b276310bd55d243df4fa8ac5816d79347d/numpy-2.4.0-cp314-cp314t-win32.whl", hash = "sha256:77f0d13fa87036d7553bf81f0e1fe3ce68d14c9976c9851744e4d3e91127e95f", size = 6148320, upload-time = "2025-12-20T16:17:57.249Z" },
+ { url = "https://files.pythonhosted.org/packages/92/8d/f23033cce252e7a75cae853d17f582e86534c46404dea1c8ee094a9d6d84/numpy-2.4.0-cp314-cp314t-win_amd64.whl", hash = "sha256:b1f5b45829ac1848893f0ddf5cb326110604d6df96cdc255b0bf9edd154104d4", size = 12623460, upload-time = "2025-12-20T16:17:58.963Z" },
+ { url = "https://files.pythonhosted.org/packages/a4/4f/1f8475907d1a7c4ef9020edf7f39ea2422ec896849245f00688e4b268a71/numpy-2.4.0-cp314-cp314t-win_arm64.whl", hash = "sha256:23a3e9d1a6f360267e8fbb38ba5db355a6a7e9be71d7fce7ab3125e88bb646c8", size = 10661799, upload-time = "2025-12-20T16:18:01.078Z" },
+ { url = "https://files.pythonhosted.org/packages/4b/ef/088e7c7342f300aaf3ee5f2c821c4b9996a1bef2aaf6a49cc8ab4883758e/numpy-2.4.0-pp311-pypy311_pp73-macosx_10_15_x86_64.whl", hash = "sha256:b54c83f1c0c0f1d748dca0af516062b8829d53d1f0c402be24b4257a9c48ada6", size = 16819003, upload-time = "2025-12-20T16:18:03.41Z" },
+ { url = "https://files.pythonhosted.org/packages/ff/ce/a53017b5443b4b84517182d463fc7bcc2adb4faa8b20813f8e5f5aeb5faa/numpy-2.4.0-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:aabb081ca0ec5d39591fc33018cd4b3f96e1a2dd6756282029986d00a785fba4", size = 12567105, upload-time = "2025-12-20T16:18:05.594Z" },
+ { url = "https://files.pythonhosted.org/packages/77/58/5ff91b161f2ec650c88a626c3905d938c89aaadabd0431e6d9c1330c83e2/numpy-2.4.0-pp311-pypy311_pp73-macosx_14_0_arm64.whl", hash = "sha256:8eafe7c36c8430b7794edeab3087dec7bf31d634d92f2af9949434b9d1964cba", size = 5395590, upload-time = "2025-12-20T16:18:08.031Z" },
+ { url = "https://files.pythonhosted.org/packages/1d/4e/f1a084106df8c2df8132fc437e56987308e0524836aa7733721c8429d4fe/numpy-2.4.0-pp311-pypy311_pp73-macosx_14_0_x86_64.whl", hash = "sha256:2f585f52b2baf07ff3356158d9268ea095e221371f1074fadea2f42544d58b4d", size = 6709947, upload-time = "2025-12-20T16:18:09.836Z" },
+ { url = "https://files.pythonhosted.org/packages/63/09/3d8aeb809c0332c3f642da812ac2e3d74fc9252b3021f8c30c82e99e3f3d/numpy-2.4.0-pp311-pypy311_pp73-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:32ed06d0fe9cae27d8fb5f400c63ccee72370599c75e683a6358dd3a4fb50aaf", size = 14535119, upload-time = "2025-12-20T16:18:12.105Z" },
+ { url = "https://files.pythonhosted.org/packages/fd/7f/68f0fc43a2cbdc6bb239160c754d87c922f60fbaa0fa3cd3d312b8a7f5ee/numpy-2.4.0-pp311-pypy311_pp73-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:57c540ed8fb1f05cb997c6761cd56db72395b0d6985e90571ff660452ade4f98", size = 16475815, upload-time = "2025-12-20T16:18:14.433Z" },
+ { url = "https://files.pythonhosted.org/packages/11/73/edeacba3167b1ca66d51b1a5a14697c2c40098b5ffa01811c67b1785a5ab/numpy-2.4.0-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:a39fb973a726e63223287adc6dafe444ce75af952d711e400f3bf2b36ef55a7b", size = 12489376, upload-time = "2025-12-20T16:18:16.524Z" },
]
[[package]]
@@ -176,9 +845,186 @@ dependencies = [
{ name = "tqdm" },
{ name = "typing-extensions" },
]
-sdist = { url = "https://files.pythonhosted.org/packages/73/d0/def3c7620e1cb446947f098aeac9d88fc826b1760d66da279e4712d37666/openai-1.59.3.tar.gz", hash = "sha256:7f7fff9d8729968588edf1524e73266e8593bb6cab09298340efb755755bb66f", size = 344192 }
+sdist = { url = "https://files.pythonhosted.org/packages/73/d0/def3c7620e1cb446947f098aeac9d88fc826b1760d66da279e4712d37666/openai-1.59.3.tar.gz", hash = "sha256:7f7fff9d8729968588edf1524e73266e8593bb6cab09298340efb755755bb66f", size = 344192, upload-time = "2025-01-03T23:00:50.997Z" }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/c7/26/0e0fb582bcb2a7cb6802447a749a2fc938fe4b82324097abccb86abfd5d1/openai-1.59.3-py3-none-any.whl", hash = "sha256:b041887a0d8f3e70d1fc6ffbb2bf7661c3b9a2f3e806c04bf42f572b9ac7bc37", size = 454793, upload-time = "2025-01-03T23:00:48.143Z" },
+]
+
+[[package]]
+name = "packaging"
+version = "25.0"
+source = { registry = "https://pypi.org/simple" }
+sdist = { url = "https://files.pythonhosted.org/packages/a1/d4/1fc4078c65507b51b96ca8f8c3ba19e6a61c8253c72794544580a7b6c24d/packaging-25.0.tar.gz", hash = "sha256:d443872c98d677bf60f6a1f2f8c1cb748e8fe762d2bf9d3148b5599295b0fc4f", size = 165727, upload-time = "2025-04-19T11:48:59.673Z" }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/20/12/38679034af332785aac8774540895e234f4d07f7545804097de4b666afd8/packaging-25.0-py3-none-any.whl", hash = "sha256:29572ef2b1f17581046b3a2227d5c611fb25ec70ca1ba8554b24b0e69331a484", size = 66469, upload-time = "2025-04-19T11:48:57.875Z" },
+]
+
+[[package]]
+name = "pandas"
+version = "2.3.3"
+source = { registry = "https://pypi.org/simple" }
+dependencies = [
+ { name = "numpy" },
+ { name = "python-dateutil" },
+ { name = "pytz" },
+ { name = "tzdata" },
+]
+sdist = { url = "https://files.pythonhosted.org/packages/33/01/d40b85317f86cf08d853a4f495195c73815fdf205eef3993821720274518/pandas-2.3.3.tar.gz", hash = "sha256:e05e1af93b977f7eafa636d043f9f94c7ee3ac81af99c13508215942e64c993b", size = 4495223, upload-time = "2025-09-29T23:34:51.853Z" }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/c1/fa/7ac648108144a095b4fb6aa3de1954689f7af60a14cf25583f4960ecb878/pandas-2.3.3-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:602b8615ebcc4a0c1751e71840428ddebeb142ec02c786e8ad6b1ce3c8dec523", size = 11578790, upload-time = "2025-09-29T23:18:30.065Z" },
+ { url = "https://files.pythonhosted.org/packages/9b/35/74442388c6cf008882d4d4bdfc4109be87e9b8b7ccd097ad1e7f006e2e95/pandas-2.3.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:8fe25fc7b623b0ef6b5009149627e34d2a4657e880948ec3c840e9402e5c1b45", size = 10833831, upload-time = "2025-09-29T23:38:56.071Z" },
+ { url = "https://files.pythonhosted.org/packages/fe/e4/de154cbfeee13383ad58d23017da99390b91d73f8c11856f2095e813201b/pandas-2.3.3-cp311-cp311-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:b468d3dad6ff947df92dcb32ede5b7bd41a9b3cceef0a30ed925f6d01fb8fa66", size = 12199267, upload-time = "2025-09-29T23:18:41.627Z" },
+ { url = "https://files.pythonhosted.org/packages/bf/c9/63f8d545568d9ab91476b1818b4741f521646cbdd151c6efebf40d6de6f7/pandas-2.3.3-cp311-cp311-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:b98560e98cb334799c0b07ca7967ac361a47326e9b4e5a7dfb5ab2b1c9d35a1b", size = 12789281, upload-time = "2025-09-29T23:18:56.834Z" },
+ { url = "https://files.pythonhosted.org/packages/f2/00/a5ac8c7a0e67fd1a6059e40aa08fa1c52cc00709077d2300e210c3ce0322/pandas-2.3.3-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:1d37b5848ba49824e5c30bedb9c830ab9b7751fd049bc7914533e01c65f79791", size = 13240453, upload-time = "2025-09-29T23:19:09.247Z" },
+ { url = "https://files.pythonhosted.org/packages/27/4d/5c23a5bc7bd209231618dd9e606ce076272c9bc4f12023a70e03a86b4067/pandas-2.3.3-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:db4301b2d1f926ae677a751eb2bd0e8c5f5319c9cb3f88b0becbbb0b07b34151", size = 13890361, upload-time = "2025-09-29T23:19:25.342Z" },
+ { url = "https://files.pythonhosted.org/packages/8e/59/712db1d7040520de7a4965df15b774348980e6df45c129b8c64d0dbe74ef/pandas-2.3.3-cp311-cp311-win_amd64.whl", hash = "sha256:f086f6fe114e19d92014a1966f43a3e62285109afe874f067f5abbdcbb10e59c", size = 11348702, upload-time = "2025-09-29T23:19:38.296Z" },
+ { url = "https://files.pythonhosted.org/packages/9c/fb/231d89e8637c808b997d172b18e9d4a4bc7bf31296196c260526055d1ea0/pandas-2.3.3-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:6d21f6d74eb1725c2efaa71a2bfc661a0689579b58e9c0ca58a739ff0b002b53", size = 11597846, upload-time = "2025-09-29T23:19:48.856Z" },
+ { url = "https://files.pythonhosted.org/packages/5c/bd/bf8064d9cfa214294356c2d6702b716d3cf3bb24be59287a6a21e24cae6b/pandas-2.3.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:3fd2f887589c7aa868e02632612ba39acb0b8948faf5cc58f0850e165bd46f35", size = 10729618, upload-time = "2025-09-29T23:39:08.659Z" },
+ { url = "https://files.pythonhosted.org/packages/57/56/cf2dbe1a3f5271370669475ead12ce77c61726ffd19a35546e31aa8edf4e/pandas-2.3.3-cp312-cp312-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ecaf1e12bdc03c86ad4a7ea848d66c685cb6851d807a26aa245ca3d2017a1908", size = 11737212, upload-time = "2025-09-29T23:19:59.765Z" },
+ { url = "https://files.pythonhosted.org/packages/e5/63/cd7d615331b328e287d8233ba9fdf191a9c2d11b6af0c7a59cfcec23de68/pandas-2.3.3-cp312-cp312-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:b3d11d2fda7eb164ef27ffc14b4fcab16a80e1ce67e9f57e19ec0afaf715ba89", size = 12362693, upload-time = "2025-09-29T23:20:14.098Z" },
+ { url = "https://files.pythonhosted.org/packages/a6/de/8b1895b107277d52f2b42d3a6806e69cfef0d5cf1d0ba343470b9d8e0a04/pandas-2.3.3-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:a68e15f780eddf2b07d242e17a04aa187a7ee12b40b930bfdd78070556550e98", size = 12771002, upload-time = "2025-09-29T23:20:26.76Z" },
+ { url = "https://files.pythonhosted.org/packages/87/21/84072af3187a677c5893b170ba2c8fbe450a6ff911234916da889b698220/pandas-2.3.3-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:371a4ab48e950033bcf52b6527eccb564f52dc826c02afd9a1bc0ab731bba084", size = 13450971, upload-time = "2025-09-29T23:20:41.344Z" },
+ { url = "https://files.pythonhosted.org/packages/86/41/585a168330ff063014880a80d744219dbf1dd7a1c706e75ab3425a987384/pandas-2.3.3-cp312-cp312-win_amd64.whl", hash = "sha256:a16dcec078a01eeef8ee61bf64074b4e524a2a3f4b3be9326420cabe59c4778b", size = 10992722, upload-time = "2025-09-29T23:20:54.139Z" },
+ { url = "https://files.pythonhosted.org/packages/cd/4b/18b035ee18f97c1040d94debd8f2e737000ad70ccc8f5513f4eefad75f4b/pandas-2.3.3-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:56851a737e3470de7fa88e6131f41281ed440d29a9268dcbf0002da5ac366713", size = 11544671, upload-time = "2025-09-29T23:21:05.024Z" },
+ { url = "https://files.pythonhosted.org/packages/31/94/72fac03573102779920099bcac1c3b05975c2cb5f01eac609faf34bed1ca/pandas-2.3.3-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:bdcd9d1167f4885211e401b3036c0c8d9e274eee67ea8d0758a256d60704cfe8", size = 10680807, upload-time = "2025-09-29T23:21:15.979Z" },
+ { url = "https://files.pythonhosted.org/packages/16/87/9472cf4a487d848476865321de18cc8c920b8cab98453ab79dbbc98db63a/pandas-2.3.3-cp313-cp313-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:e32e7cc9af0f1cc15548288a51a3b681cc2a219faa838e995f7dc53dbab1062d", size = 11709872, upload-time = "2025-09-29T23:21:27.165Z" },
+ { url = "https://files.pythonhosted.org/packages/15/07/284f757f63f8a8d69ed4472bfd85122bd086e637bf4ed09de572d575a693/pandas-2.3.3-cp313-cp313-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:318d77e0e42a628c04dc56bcef4b40de67918f7041c2b061af1da41dcff670ac", size = 12306371, upload-time = "2025-09-29T23:21:40.532Z" },
+ { url = "https://files.pythonhosted.org/packages/33/81/a3afc88fca4aa925804a27d2676d22dcd2031c2ebe08aabd0ae55b9ff282/pandas-2.3.3-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:4e0a175408804d566144e170d0476b15d78458795bb18f1304fb94160cabf40c", size = 12765333, upload-time = "2025-09-29T23:21:55.77Z" },
+ { url = "https://files.pythonhosted.org/packages/8d/0f/b4d4ae743a83742f1153464cf1a8ecfafc3ac59722a0b5c8602310cb7158/pandas-2.3.3-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:93c2d9ab0fc11822b5eece72ec9587e172f63cff87c00b062f6e37448ced4493", size = 13418120, upload-time = "2025-09-29T23:22:10.109Z" },
+ { url = "https://files.pythonhosted.org/packages/4f/c7/e54682c96a895d0c808453269e0b5928a07a127a15704fedb643e9b0a4c8/pandas-2.3.3-cp313-cp313-win_amd64.whl", hash = "sha256:f8bfc0e12dc78f777f323f55c58649591b2cd0c43534e8355c51d3fede5f4dee", size = 10993991, upload-time = "2025-09-29T23:25:04.889Z" },
+ { url = "https://files.pythonhosted.org/packages/f9/ca/3f8d4f49740799189e1395812f3bf23b5e8fc7c190827d55a610da72ce55/pandas-2.3.3-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:75ea25f9529fdec2d2e93a42c523962261e567d250b0013b16210e1d40d7c2e5", size = 12048227, upload-time = "2025-09-29T23:22:24.343Z" },
+ { url = "https://files.pythonhosted.org/packages/0e/5a/f43efec3e8c0cc92c4663ccad372dbdff72b60bdb56b2749f04aa1d07d7e/pandas-2.3.3-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:74ecdf1d301e812db96a465a525952f4dde225fdb6d8e5a521d47e1f42041e21", size = 11411056, upload-time = "2025-09-29T23:22:37.762Z" },
+ { url = "https://files.pythonhosted.org/packages/46/b1/85331edfc591208c9d1a63a06baa67b21d332e63b7a591a5ba42a10bb507/pandas-2.3.3-cp313-cp313t-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6435cb949cb34ec11cc9860246ccb2fdc9ecd742c12d3304989017d53f039a78", size = 11645189, upload-time = "2025-09-29T23:22:51.688Z" },
+ { url = "https://files.pythonhosted.org/packages/44/23/78d645adc35d94d1ac4f2a3c4112ab6f5b8999f4898b8cdf01252f8df4a9/pandas-2.3.3-cp313-cp313t-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:900f47d8f20860de523a1ac881c4c36d65efcb2eb850e6948140fa781736e110", size = 12121912, upload-time = "2025-09-29T23:23:05.042Z" },
+ { url = "https://files.pythonhosted.org/packages/53/da/d10013df5e6aaef6b425aa0c32e1fc1f3e431e4bcabd420517dceadce354/pandas-2.3.3-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:a45c765238e2ed7d7c608fc5bc4a6f88b642f2f01e70c0c23d2224dd21829d86", size = 12712160, upload-time = "2025-09-29T23:23:28.57Z" },
+ { url = "https://files.pythonhosted.org/packages/bd/17/e756653095a083d8a37cbd816cb87148debcfcd920129b25f99dd8d04271/pandas-2.3.3-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:c4fc4c21971a1a9f4bdb4c73978c7f7256caa3e62b323f70d6cb80db583350bc", size = 13199233, upload-time = "2025-09-29T23:24:24.876Z" },
+ { url = "https://files.pythonhosted.org/packages/04/fd/74903979833db8390b73b3a8a7d30d146d710bd32703724dd9083950386f/pandas-2.3.3-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:ee15f284898e7b246df8087fc82b87b01686f98ee67d85a17b7ab44143a3a9a0", size = 11540635, upload-time = "2025-09-29T23:25:52.486Z" },
+ { url = "https://files.pythonhosted.org/packages/21/00/266d6b357ad5e6d3ad55093a7e8efc7dd245f5a842b584db9f30b0f0a287/pandas-2.3.3-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:1611aedd912e1ff81ff41c745822980c49ce4a7907537be8692c8dbc31924593", size = 10759079, upload-time = "2025-09-29T23:26:33.204Z" },
+ { url = "https://files.pythonhosted.org/packages/ca/05/d01ef80a7a3a12b2f8bbf16daba1e17c98a2f039cbc8e2f77a2c5a63d382/pandas-2.3.3-cp314-cp314-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6d2cefc361461662ac48810cb14365a365ce864afe85ef1f447ff5a1e99ea81c", size = 11814049, upload-time = "2025-09-29T23:27:15.384Z" },
+ { url = "https://files.pythonhosted.org/packages/15/b2/0e62f78c0c5ba7e3d2c5945a82456f4fac76c480940f805e0b97fcbc2f65/pandas-2.3.3-cp314-cp314-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:ee67acbbf05014ea6c763beb097e03cd629961c8a632075eeb34247120abcb4b", size = 12332638, upload-time = "2025-09-29T23:27:51.625Z" },
+ { url = "https://files.pythonhosted.org/packages/c5/33/dd70400631b62b9b29c3c93d2feee1d0964dc2bae2e5ad7a6c73a7f25325/pandas-2.3.3-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:c46467899aaa4da076d5abc11084634e2d197e9460643dd455ac3db5856b24d6", size = 12886834, upload-time = "2025-09-29T23:28:21.289Z" },
+ { url = "https://files.pythonhosted.org/packages/d3/18/b5d48f55821228d0d2692b34fd5034bb185e854bdb592e9c640f6290e012/pandas-2.3.3-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:6253c72c6a1d990a410bc7de641d34053364ef8bcd3126f7e7450125887dffe3", size = 13409925, upload-time = "2025-09-29T23:28:58.261Z" },
+ { url = "https://files.pythonhosted.org/packages/a6/3d/124ac75fcd0ecc09b8fdccb0246ef65e35b012030defb0e0eba2cbbbe948/pandas-2.3.3-cp314-cp314-win_amd64.whl", hash = "sha256:1b07204a219b3b7350abaae088f451860223a52cfb8a6c53358e7948735158e5", size = 11109071, upload-time = "2025-09-29T23:32:27.484Z" },
+ { url = "https://files.pythonhosted.org/packages/89/9c/0e21c895c38a157e0faa1fb64587a9226d6dd46452cac4532d80c3c4a244/pandas-2.3.3-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:2462b1a365b6109d275250baaae7b760fd25c726aaca0054649286bcfbb3e8ec", size = 12048504, upload-time = "2025-09-29T23:29:31.47Z" },
+ { url = "https://files.pythonhosted.org/packages/d7/82/b69a1c95df796858777b68fbe6a81d37443a33319761d7c652ce77797475/pandas-2.3.3-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:0242fe9a49aa8b4d78a4fa03acb397a58833ef6199e9aa40a95f027bb3a1b6e7", size = 11410702, upload-time = "2025-09-29T23:29:54.591Z" },
+ { url = "https://files.pythonhosted.org/packages/f9/88/702bde3ba0a94b8c73a0181e05144b10f13f29ebfc2150c3a79062a8195d/pandas-2.3.3-cp314-cp314t-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:a21d830e78df0a515db2b3d2f5570610f5e6bd2e27749770e8bb7b524b89b450", size = 11634535, upload-time = "2025-09-29T23:30:21.003Z" },
+ { url = "https://files.pythonhosted.org/packages/a4/1e/1bac1a839d12e6a82ec6cb40cda2edde64a2013a66963293696bbf31fbbb/pandas-2.3.3-cp314-cp314t-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:2e3ebdb170b5ef78f19bfb71b0dc5dc58775032361fa188e814959b74d726dd5", size = 12121582, upload-time = "2025-09-29T23:30:43.391Z" },
+ { url = "https://files.pythonhosted.org/packages/44/91/483de934193e12a3b1d6ae7c8645d083ff88dec75f46e827562f1e4b4da6/pandas-2.3.3-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:d051c0e065b94b7a3cea50eb1ec32e912cd96dba41647eb24104b6c6c14c5788", size = 12699963, upload-time = "2025-09-29T23:31:10.009Z" },
+ { url = "https://files.pythonhosted.org/packages/70/44/5191d2e4026f86a2a109053e194d3ba7a31a2d10a9c2348368c63ed4e85a/pandas-2.3.3-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:3869faf4bd07b3b66a9f462417d0ca3a9df29a9f6abd5d0d0dbab15dac7abe87", size = 13202175, upload-time = "2025-09-29T23:31:59.173Z" },
+]
+
+[[package]]
+name = "pathspec"
+version = "1.0.3"
+source = { registry = "https://pypi.org/simple" }
+sdist = { url = "https://files.pythonhosted.org/packages/4c/b2/bb8e495d5262bfec41ab5cb18f522f1012933347fb5d9e62452d446baca2/pathspec-1.0.3.tar.gz", hash = "sha256:bac5cf97ae2c2876e2d25ebb15078eb04d76e4b98921ee31c6f85ade8b59444d", size = 130841, upload-time = "2026-01-09T15:46:46.009Z" }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/32/2b/121e912bd60eebd623f873fd090de0e84f322972ab25a7f9044c056804ed/pathspec-1.0.3-py3-none-any.whl", hash = "sha256:e80767021c1cc524aa3fb14bedda9c34406591343cc42797b386ce7b9354fb6c", size = 55021, upload-time = "2026-01-09T15:46:44.652Z" },
+]
+
+[[package]]
+name = "pillow"
+version = "12.1.0"
+source = { registry = "https://pypi.org/simple" }
+sdist = { url = "https://files.pythonhosted.org/packages/d0/02/d52c733a2452ef1ffcc123b68e6606d07276b0e358db70eabad7e40042b7/pillow-12.1.0.tar.gz", hash = "sha256:5c5ae0a06e9ea030ab786b0251b32c7e4ce10e58d983c0d5c56029455180b5b9", size = 46977283, upload-time = "2026-01-02T09:13:29.892Z" }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/43/c4/bf8328039de6cc22182c3ef007a2abfbbdab153661c0a9aa78af8d706391/pillow-12.1.0-cp311-cp311-macosx_10_10_x86_64.whl", hash = "sha256:a83e0850cb8f5ac975291ebfc4170ba481f41a28065277f7f735c202cd8e0af3", size = 5304057, upload-time = "2026-01-02T09:10:46.627Z" },
+ { url = "https://files.pythonhosted.org/packages/43/06/7264c0597e676104cc22ca73ee48f752767cd4b1fe084662620b17e10120/pillow-12.1.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:b6e53e82ec2db0717eabb276aa56cf4e500c9a7cec2c2e189b55c24f65a3e8c0", size = 4657811, upload-time = "2026-01-02T09:10:49.548Z" },
+ { url = "https://files.pythonhosted.org/packages/72/64/f9189e44474610daf83da31145fa56710b627b5c4c0b9c235e34058f6b31/pillow-12.1.0-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:40a8e3b9e8773876d6e30daed22f016509e3987bab61b3b7fe309d7019a87451", size = 6232243, upload-time = "2026-01-02T09:10:51.62Z" },
+ { url = "https://files.pythonhosted.org/packages/ef/30/0df458009be6a4caca4ca2c52975e6275c387d4e5c95544e34138b41dc86/pillow-12.1.0-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:800429ac32c9b72909c671aaf17ecd13110f823ddb7db4dfef412a5587c2c24e", size = 8037872, upload-time = "2026-01-02T09:10:53.446Z" },
+ { url = "https://files.pythonhosted.org/packages/e4/86/95845d4eda4f4f9557e25381d70876aa213560243ac1a6d619c46caaedd9/pillow-12.1.0-cp311-cp311-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:0b022eaaf709541b391ee069f0022ee5b36c709df71986e3f7be312e46f42c84", size = 6345398, upload-time = "2026-01-02T09:10:55.426Z" },
+ { url = "https://files.pythonhosted.org/packages/5c/1f/8e66ab9be3aaf1435bc03edd1ebdf58ffcd17f7349c1d970cafe87af27d9/pillow-12.1.0-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:1f345e7bc9d7f368887c712aa5054558bad44d2a301ddf9248599f4161abc7c0", size = 7034667, upload-time = "2026-01-02T09:10:57.11Z" },
+ { url = "https://files.pythonhosted.org/packages/f9/f6/683b83cb9b1db1fb52b87951b1c0b99bdcfceaa75febf11406c19f82cb5e/pillow-12.1.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:d70347c8a5b7ccd803ec0c85c8709f036e6348f1e6a5bf048ecd9c64d3550b8b", size = 6458743, upload-time = "2026-01-02T09:10:59.331Z" },
+ { url = "https://files.pythonhosted.org/packages/9a/7d/de833d63622538c1d58ce5395e7c6cb7e7dce80decdd8bde4a484e095d9f/pillow-12.1.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:1fcc52d86ce7a34fd17cb04e87cfdb164648a3662a6f20565910a99653d66c18", size = 7159342, upload-time = "2026-01-02T09:11:01.82Z" },
+ { url = "https://files.pythonhosted.org/packages/8c/40/50d86571c9e5868c42b81fe7da0c76ca26373f3b95a8dd675425f4a92ec1/pillow-12.1.0-cp311-cp311-win32.whl", hash = "sha256:3ffaa2f0659e2f740473bcf03c702c39a8d4b2b7ffc629052028764324842c64", size = 6328655, upload-time = "2026-01-02T09:11:04.556Z" },
+ { url = "https://files.pythonhosted.org/packages/6c/af/b1d7e301c4cd26cd45d4af884d9ee9b6fab893b0ad2450d4746d74a6968c/pillow-12.1.0-cp311-cp311-win_amd64.whl", hash = "sha256:806f3987ffe10e867bab0ddad45df1148a2b98221798457fa097ad85d6e8bc75", size = 7031469, upload-time = "2026-01-02T09:11:06.538Z" },
+ { url = "https://files.pythonhosted.org/packages/48/36/d5716586d887fb2a810a4a61518a327a1e21c8b7134c89283af272efe84b/pillow-12.1.0-cp311-cp311-win_arm64.whl", hash = "sha256:9f5fefaca968e700ad1a4a9de98bf0869a94e397fe3524c4c9450c1445252304", size = 2452515, upload-time = "2026-01-02T09:11:08.226Z" },
+ { url = "https://files.pythonhosted.org/packages/20/31/dc53fe21a2f2996e1b7d92bf671cdb157079385183ef7c1ae08b485db510/pillow-12.1.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:a332ac4ccb84b6dde65dbace8431f3af08874bf9770719d32a635c4ef411b18b", size = 5262642, upload-time = "2026-01-02T09:11:10.138Z" },
+ { url = "https://files.pythonhosted.org/packages/ab/c1/10e45ac9cc79419cedf5121b42dcca5a50ad2b601fa080f58c22fb27626e/pillow-12.1.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:907bfa8a9cb790748a9aa4513e37c88c59660da3bcfffbd24a7d9e6abf224551", size = 4657464, upload-time = "2026-01-02T09:11:12.319Z" },
+ { url = "https://files.pythonhosted.org/packages/ad/26/7b82c0ab7ef40ebede7a97c72d473bda5950f609f8e0c77b04af574a0ddb/pillow-12.1.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:efdc140e7b63b8f739d09a99033aa430accce485ff78e6d311973a67b6bf3208", size = 6234878, upload-time = "2026-01-02T09:11:14.096Z" },
+ { url = "https://files.pythonhosted.org/packages/76/25/27abc9792615b5e886ca9411ba6637b675f1b77af3104710ac7353fe5605/pillow-12.1.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:bef9768cab184e7ae6e559c032e95ba8d07b3023c289f79a2bd36e8bf85605a5", size = 8044868, upload-time = "2026-01-02T09:11:15.903Z" },
+ { url = "https://files.pythonhosted.org/packages/0a/ea/f200a4c36d836100e7bc738fc48cd963d3ba6372ebc8298a889e0cfc3359/pillow-12.1.0-cp312-cp312-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:742aea052cf5ab5034a53c3846165bc3ce88d7c38e954120db0ab867ca242661", size = 6349468, upload-time = "2026-01-02T09:11:17.631Z" },
+ { url = "https://files.pythonhosted.org/packages/11/8f/48d0b77ab2200374c66d344459b8958c86693be99526450e7aee714e03e4/pillow-12.1.0-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:a6dfc2af5b082b635af6e08e0d1f9f1c4e04d17d4e2ca0ef96131e85eda6eb17", size = 7041518, upload-time = "2026-01-02T09:11:19.389Z" },
+ { url = "https://files.pythonhosted.org/packages/1d/23/c281182eb986b5d31f0a76d2a2c8cd41722d6fb8ed07521e802f9bba52de/pillow-12.1.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:609e89d9f90b581c8d16358c9087df76024cf058fa693dd3e1e1620823f39670", size = 6462829, upload-time = "2026-01-02T09:11:21.28Z" },
+ { url = "https://files.pythonhosted.org/packages/25/ef/7018273e0faac099d7b00982abdcc39142ae6f3bd9ceb06de09779c4a9d6/pillow-12.1.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:43b4899cfd091a9693a1278c4982f3e50f7fb7cff5153b05174b4afc9593b616", size = 7166756, upload-time = "2026-01-02T09:11:23.559Z" },
+ { url = "https://files.pythonhosted.org/packages/8f/c8/993d4b7ab2e341fe02ceef9576afcf5830cdec640be2ac5bee1820d693d4/pillow-12.1.0-cp312-cp312-win32.whl", hash = "sha256:aa0c9cc0b82b14766a99fbe6084409972266e82f459821cd26997a488a7261a7", size = 6328770, upload-time = "2026-01-02T09:11:25.661Z" },
+ { url = "https://files.pythonhosted.org/packages/a7/87/90b358775a3f02765d87655237229ba64a997b87efa8ccaca7dd3e36e7a7/pillow-12.1.0-cp312-cp312-win_amd64.whl", hash = "sha256:d70534cea9e7966169ad29a903b99fc507e932069a881d0965a1a84bb57f6c6d", size = 7033406, upload-time = "2026-01-02T09:11:27.474Z" },
+ { url = "https://files.pythonhosted.org/packages/5d/cf/881b457eccacac9e5b2ddd97d5071fb6d668307c57cbf4e3b5278e06e536/pillow-12.1.0-cp312-cp312-win_arm64.whl", hash = "sha256:65b80c1ee7e14a87d6a068dd3b0aea268ffcabfe0498d38661b00c5b4b22e74c", size = 2452612, upload-time = "2026-01-02T09:11:29.309Z" },
+ { url = "https://files.pythonhosted.org/packages/dd/c7/2530a4aa28248623e9d7f27316b42e27c32ec410f695929696f2e0e4a778/pillow-12.1.0-cp313-cp313-ios_13_0_arm64_iphoneos.whl", hash = "sha256:7b5dd7cbae20285cdb597b10eb5a2c13aa9de6cde9bb64a3c1317427b1db1ae1", size = 4062543, upload-time = "2026-01-02T09:11:31.566Z" },
+ { url = "https://files.pythonhosted.org/packages/8f/1f/40b8eae823dc1519b87d53c30ed9ef085506b05281d313031755c1705f73/pillow-12.1.0-cp313-cp313-ios_13_0_arm64_iphonesimulator.whl", hash = "sha256:29a4cef9cb672363926f0470afc516dbf7305a14d8c54f7abbb5c199cd8f8179", size = 4138373, upload-time = "2026-01-02T09:11:33.367Z" },
+ { url = "https://files.pythonhosted.org/packages/d4/77/6fa60634cf06e52139fd0e89e5bbf055e8166c691c42fb162818b7fda31d/pillow-12.1.0-cp313-cp313-ios_13_0_x86_64_iphonesimulator.whl", hash = "sha256:681088909d7e8fa9e31b9799aaa59ba5234c58e5e4f1951b4c4d1082a2e980e0", size = 3601241, upload-time = "2026-01-02T09:11:35.011Z" },
+ { url = "https://files.pythonhosted.org/packages/4f/bf/28ab865de622e14b747f0cd7877510848252d950e43002e224fb1c9ababf/pillow-12.1.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:983976c2ab753166dc66d36af6e8ec15bb511e4a25856e2227e5f7e00a160587", size = 5262410, upload-time = "2026-01-02T09:11:36.682Z" },
+ { url = "https://files.pythonhosted.org/packages/1c/34/583420a1b55e715937a85bd48c5c0991598247a1fd2eb5423188e765ea02/pillow-12.1.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:db44d5c160a90df2d24a24760bbd37607d53da0b34fb546c4c232af7192298ac", size = 4657312, upload-time = "2026-01-02T09:11:38.535Z" },
+ { url = "https://files.pythonhosted.org/packages/1d/fd/f5a0896839762885b3376ff04878f86ab2b097c2f9a9cdccf4eda8ba8dc0/pillow-12.1.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:6b7a9d1db5dad90e2991645874f708e87d9a3c370c243c2d7684d28f7e133e6b", size = 6232605, upload-time = "2026-01-02T09:11:40.602Z" },
+ { url = "https://files.pythonhosted.org/packages/98/aa/938a09d127ac1e70e6ed467bd03834350b33ef646b31edb7452d5de43792/pillow-12.1.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:6258f3260986990ba2fa8a874f8b6e808cf5abb51a94015ca3dc3c68aa4f30ea", size = 8041617, upload-time = "2026-01-02T09:11:42.721Z" },
+ { url = "https://files.pythonhosted.org/packages/17/e8/538b24cb426ac0186e03f80f78bc8dc7246c667f58b540bdd57c71c9f79d/pillow-12.1.0-cp313-cp313-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:e115c15e3bc727b1ca3e641a909f77f8ca72a64fff150f666fcc85e57701c26c", size = 6346509, upload-time = "2026-01-02T09:11:44.955Z" },
+ { url = "https://files.pythonhosted.org/packages/01/9a/632e58ec89a32738cabfd9ec418f0e9898a2b4719afc581f07c04a05e3c9/pillow-12.1.0-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:6741e6f3074a35e47c77b23a4e4f2d90db3ed905cb1c5e6e0d49bff2045632bc", size = 7038117, upload-time = "2026-01-02T09:11:46.736Z" },
+ { url = "https://files.pythonhosted.org/packages/c7/a2/d40308cf86eada842ca1f3ffa45d0ca0df7e4ab33c83f81e73f5eaed136d/pillow-12.1.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:935b9d1aed48fcfb3f838caac506f38e29621b44ccc4f8a64d575cb1b2a88644", size = 6460151, upload-time = "2026-01-02T09:11:48.625Z" },
+ { url = "https://files.pythonhosted.org/packages/f1/88/f5b058ad6453a085c5266660a1417bdad590199da1b32fb4efcff9d33b05/pillow-12.1.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:5fee4c04aad8932da9f8f710af2c1a15a83582cfb884152a9caa79d4efcdbf9c", size = 7164534, upload-time = "2026-01-02T09:11:50.445Z" },
+ { url = "https://files.pythonhosted.org/packages/19/ce/c17334caea1db789163b5d855a5735e47995b0b5dc8745e9a3605d5f24c0/pillow-12.1.0-cp313-cp313-win32.whl", hash = "sha256:a786bf667724d84aa29b5db1c61b7bfdde380202aaca12c3461afd6b71743171", size = 6332551, upload-time = "2026-01-02T09:11:52.234Z" },
+ { url = "https://files.pythonhosted.org/packages/e5/07/74a9d941fa45c90a0d9465098fe1ec85de3e2afbdc15cc4766622d516056/pillow-12.1.0-cp313-cp313-win_amd64.whl", hash = "sha256:461f9dfdafa394c59cd6d818bdfdbab4028b83b02caadaff0ffd433faf4c9a7a", size = 7040087, upload-time = "2026-01-02T09:11:54.822Z" },
+ { url = "https://files.pythonhosted.org/packages/88/09/c99950c075a0e9053d8e880595926302575bc742b1b47fe1bbcc8d388d50/pillow-12.1.0-cp313-cp313-win_arm64.whl", hash = "sha256:9212d6b86917a2300669511ed094a9406888362e085f2431a7da985a6b124f45", size = 2452470, upload-time = "2026-01-02T09:11:56.522Z" },
+ { url = "https://files.pythonhosted.org/packages/b5/ba/970b7d85ba01f348dee4d65412476321d40ee04dcb51cd3735b9dc94eb58/pillow-12.1.0-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:00162e9ca6d22b7c3ee8e61faa3c3253cd19b6a37f126cad04f2f88b306f557d", size = 5264816, upload-time = "2026-01-02T09:11:58.227Z" },
+ { url = "https://files.pythonhosted.org/packages/10/60/650f2fb55fdba7a510d836202aa52f0baac633e50ab1cf18415d332188fb/pillow-12.1.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:7d6daa89a00b58c37cb1747ec9fb7ac3bc5ffd5949f5888657dfddde6d1312e0", size = 4660472, upload-time = "2026-01-02T09:12:00.798Z" },
+ { url = "https://files.pythonhosted.org/packages/2b/c0/5273a99478956a099d533c4f46cbaa19fd69d606624f4334b85e50987a08/pillow-12.1.0-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:e2479c7f02f9d505682dc47df8c0ea1fc5e264c4d1629a5d63fe3e2334b89554", size = 6268974, upload-time = "2026-01-02T09:12:02.572Z" },
+ { url = "https://files.pythonhosted.org/packages/b4/26/0bf714bc2e73d5267887d47931d53c4ceeceea6978148ed2ab2a4e6463c4/pillow-12.1.0-cp313-cp313t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:f188d580bd870cda1e15183790d1cc2fa78f666e76077d103edf048eed9c356e", size = 8073070, upload-time = "2026-01-02T09:12:04.75Z" },
+ { url = "https://files.pythonhosted.org/packages/43/cf/1ea826200de111a9d65724c54f927f3111dc5ae297f294b370a670c17786/pillow-12.1.0-cp313-cp313t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:0fde7ec5538ab5095cc02df38ee99b0443ff0e1c847a045554cf5f9af1f4aa82", size = 6380176, upload-time = "2026-01-02T09:12:06.626Z" },
+ { url = "https://files.pythonhosted.org/packages/03/e0/7938dd2b2013373fd85d96e0f38d62b7a5a262af21ac274250c7ca7847c9/pillow-12.1.0-cp313-cp313t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:0ed07dca4a8464bada6139ab38f5382f83e5f111698caf3191cb8dbf27d908b4", size = 7067061, upload-time = "2026-01-02T09:12:08.624Z" },
+ { url = "https://files.pythonhosted.org/packages/86/ad/a2aa97d37272a929a98437a8c0ac37b3cf012f4f8721e1bd5154699b2518/pillow-12.1.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:f45bd71d1fa5e5749587613037b172e0b3b23159d1c00ef2fc920da6f470e6f0", size = 6491824, upload-time = "2026-01-02T09:12:10.488Z" },
+ { url = "https://files.pythonhosted.org/packages/a4/44/80e46611b288d51b115826f136fb3465653c28f491068a72d3da49b54cd4/pillow-12.1.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:277518bf4fe74aa91489e1b20577473b19ee70fb97c374aa50830b279f25841b", size = 7190911, upload-time = "2026-01-02T09:12:12.772Z" },
+ { url = "https://files.pythonhosted.org/packages/86/77/eacc62356b4cf81abe99ff9dbc7402750044aed02cfd6a503f7c6fc11f3e/pillow-12.1.0-cp313-cp313t-win32.whl", hash = "sha256:7315f9137087c4e0ee73a761b163fc9aa3b19f5f606a7fc08d83fd3e4379af65", size = 6336445, upload-time = "2026-01-02T09:12:14.775Z" },
+ { url = "https://files.pythonhosted.org/packages/e7/3c/57d81d0b74d218706dafccb87a87ea44262c43eef98eb3b164fd000e0491/pillow-12.1.0-cp313-cp313t-win_amd64.whl", hash = "sha256:0ddedfaa8b5f0b4ffbc2fa87b556dc59f6bb4ecb14a53b33f9189713ae8053c0", size = 7045354, upload-time = "2026-01-02T09:12:16.599Z" },
+ { url = "https://files.pythonhosted.org/packages/ac/82/8b9b97bba2e3576a340f93b044a3a3a09841170ab4c1eb0d5c93469fd32f/pillow-12.1.0-cp313-cp313t-win_arm64.whl", hash = "sha256:80941e6d573197a0c28f394753de529bb436b1ca990ed6e765cf42426abc39f8", size = 2454547, upload-time = "2026-01-02T09:12:18.704Z" },
+ { url = "https://files.pythonhosted.org/packages/8c/87/bdf971d8bbcf80a348cc3bacfcb239f5882100fe80534b0ce67a784181d8/pillow-12.1.0-cp314-cp314-ios_13_0_arm64_iphoneos.whl", hash = "sha256:5cb7bc1966d031aec37ddb9dcf15c2da5b2e9f7cc3ca7c54473a20a927e1eb91", size = 4062533, upload-time = "2026-01-02T09:12:20.791Z" },
+ { url = "https://files.pythonhosted.org/packages/ff/4f/5eb37a681c68d605eb7034c004875c81f86ec9ef51f5be4a63eadd58859a/pillow-12.1.0-cp314-cp314-ios_13_0_arm64_iphonesimulator.whl", hash = "sha256:97e9993d5ed946aba26baf9c1e8cf18adbab584b99f452ee72f7ee8acb882796", size = 4138546, upload-time = "2026-01-02T09:12:23.664Z" },
+ { url = "https://files.pythonhosted.org/packages/11/6d/19a95acb2edbace40dcd582d077b991646b7083c41b98da4ed7555b59733/pillow-12.1.0-cp314-cp314-ios_13_0_x86_64_iphonesimulator.whl", hash = "sha256:414b9a78e14ffeb98128863314e62c3f24b8a86081066625700b7985b3f529bd", size = 3601163, upload-time = "2026-01-02T09:12:26.338Z" },
+ { url = "https://files.pythonhosted.org/packages/fc/36/2b8138e51cb42e4cc39c3297713455548be855a50558c3ac2beebdc251dd/pillow-12.1.0-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:e6bdb408f7c9dd2a5ff2b14a3b0bb6d4deb29fb9961e6eb3ae2031ae9a5cec13", size = 5266086, upload-time = "2026-01-02T09:12:28.782Z" },
+ { url = "https://files.pythonhosted.org/packages/53/4b/649056e4d22e1caa90816bf99cef0884aed607ed38075bd75f091a607a38/pillow-12.1.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:3413c2ae377550f5487991d444428f1a8ae92784aac79caa8b1e3b89b175f77e", size = 4657344, upload-time = "2026-01-02T09:12:31.117Z" },
+ { url = "https://files.pythonhosted.org/packages/6c/6b/c5742cea0f1ade0cd61485dc3d81f05261fc2276f537fbdc00802de56779/pillow-12.1.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:e5dcbe95016e88437ecf33544ba5db21ef1b8dd6e1b434a2cb2a3d605299e643", size = 6232114, upload-time = "2026-01-02T09:12:32.936Z" },
+ { url = "https://files.pythonhosted.org/packages/bf/8f/9f521268ce22d63991601aafd3d48d5ff7280a246a1ef62d626d67b44064/pillow-12.1.0-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:d0a7735df32ccbcc98b98a1ac785cc4b19b580be1bdf0aeb5c03223220ea09d5", size = 8042708, upload-time = "2026-01-02T09:12:34.78Z" },
+ { url = "https://files.pythonhosted.org/packages/1a/eb/257f38542893f021502a1bbe0c2e883c90b5cff26cc33b1584a841a06d30/pillow-12.1.0-cp314-cp314-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:0c27407a2d1b96774cbc4a7594129cc027339fd800cd081e44497722ea1179de", size = 6347762, upload-time = "2026-01-02T09:12:36.748Z" },
+ { url = "https://files.pythonhosted.org/packages/c4/5a/8ba375025701c09b309e8d5163c5a4ce0102fa86bbf8800eb0d7ac87bc51/pillow-12.1.0-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:15c794d74303828eaa957ff8070846d0efe8c630901a1c753fdc63850e19ecd9", size = 7039265, upload-time = "2026-01-02T09:12:39.082Z" },
+ { url = "https://files.pythonhosted.org/packages/cf/dc/cf5e4cdb3db533f539e88a7bbf9f190c64ab8a08a9bc7a4ccf55067872e4/pillow-12.1.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:c990547452ee2800d8506c4150280757f88532f3de2a58e3022e9b179107862a", size = 6462341, upload-time = "2026-01-02T09:12:40.946Z" },
+ { url = "https://files.pythonhosted.org/packages/d0/47/0291a25ac9550677e22eda48510cfc4fa4b2ef0396448b7fbdc0a6946309/pillow-12.1.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:b63e13dd27da389ed9475b3d28510f0f954bca0041e8e551b2a4eb1eab56a39a", size = 7165395, upload-time = "2026-01-02T09:12:42.706Z" },
+ { url = "https://files.pythonhosted.org/packages/4f/4c/e005a59393ec4d9416be06e6b45820403bb946a778e39ecec62f5b2b991e/pillow-12.1.0-cp314-cp314-win32.whl", hash = "sha256:1a949604f73eb07a8adab38c4fe50791f9919344398bdc8ac6b307f755fc7030", size = 6431413, upload-time = "2026-01-02T09:12:44.944Z" },
+ { url = "https://files.pythonhosted.org/packages/1c/af/f23697f587ac5f9095d67e31b81c95c0249cd461a9798a061ed6709b09b5/pillow-12.1.0-cp314-cp314-win_amd64.whl", hash = "sha256:4f9f6a650743f0ddee5593ac9e954ba1bdbc5e150bc066586d4f26127853ab94", size = 7176779, upload-time = "2026-01-02T09:12:46.727Z" },
+ { url = "https://files.pythonhosted.org/packages/b3/36/6a51abf8599232f3e9afbd16d52829376a68909fe14efe29084445db4b73/pillow-12.1.0-cp314-cp314-win_arm64.whl", hash = "sha256:808b99604f7873c800c4840f55ff389936ef1948e4e87645eaf3fccbc8477ac4", size = 2543105, upload-time = "2026-01-02T09:12:49.243Z" },
+ { url = "https://files.pythonhosted.org/packages/82/54/2e1dd20c8749ff225080d6ba465a0cab4387f5db0d1c5fb1439e2d99923f/pillow-12.1.0-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:bc11908616c8a283cf7d664f77411a5ed2a02009b0097ff8abbba5e79128ccf2", size = 5268571, upload-time = "2026-01-02T09:12:51.11Z" },
+ { url = "https://files.pythonhosted.org/packages/57/61/571163a5ef86ec0cf30d265ac2a70ae6fc9e28413d1dc94fa37fae6bda89/pillow-12.1.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:896866d2d436563fa2a43a9d72f417874f16b5545955c54a64941e87c1376c61", size = 4660426, upload-time = "2026-01-02T09:12:52.865Z" },
+ { url = "https://files.pythonhosted.org/packages/5e/e1/53ee5163f794aef1bf84243f755ee6897a92c708505350dd1923f4afec48/pillow-12.1.0-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:8e178e3e99d3c0ea8fc64b88447f7cac8ccf058af422a6cedc690d0eadd98c51", size = 6269908, upload-time = "2026-01-02T09:12:54.884Z" },
+ { url = "https://files.pythonhosted.org/packages/bc/0b/b4b4106ff0ee1afa1dc599fde6ab230417f800279745124f6c50bcffed8e/pillow-12.1.0-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:079af2fb0c599c2ec144ba2c02766d1b55498e373b3ac64687e43849fbbef5bc", size = 8074733, upload-time = "2026-01-02T09:12:56.802Z" },
+ { url = "https://files.pythonhosted.org/packages/19/9f/80b411cbac4a732439e629a26ad3ef11907a8c7fc5377b7602f04f6fe4e7/pillow-12.1.0-cp314-cp314t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:bdec5e43377761c5dbca620efb69a77f6855c5a379e32ac5b158f54c84212b14", size = 6381431, upload-time = "2026-01-02T09:12:58.823Z" },
+ { url = "https://files.pythonhosted.org/packages/8f/b7/d65c45db463b66ecb6abc17c6ba6917a911202a07662247e1355ce1789e7/pillow-12.1.0-cp314-cp314t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:565c986f4b45c020f5421a4cea13ef294dde9509a8577f29b2fc5edc7587fff8", size = 7068529, upload-time = "2026-01-02T09:13:00.885Z" },
+ { url = "https://files.pythonhosted.org/packages/50/96/dfd4cd726b4a45ae6e3c669fc9e49deb2241312605d33aba50499e9d9bd1/pillow-12.1.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:43aca0a55ce1eefc0aefa6253661cb54571857b1a7b2964bd8a1e3ef4b729924", size = 6492981, upload-time = "2026-01-02T09:13:03.314Z" },
+ { url = "https://files.pythonhosted.org/packages/4d/1c/b5dc52cf713ae46033359c5ca920444f18a6359ce1020dd3e9c553ea5bc6/pillow-12.1.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:0deedf2ea233722476b3a81e8cdfbad786f7adbed5d848469fa59fe52396e4ef", size = 7191878, upload-time = "2026-01-02T09:13:05.276Z" },
+ { url = "https://files.pythonhosted.org/packages/53/26/c4188248bd5edaf543864fe4834aebe9c9cb4968b6f573ce014cc42d0720/pillow-12.1.0-cp314-cp314t-win32.whl", hash = "sha256:b17fbdbe01c196e7e159aacb889e091f28e61020a8abeac07b68079b6e626988", size = 6438703, upload-time = "2026-01-02T09:13:07.491Z" },
+ { url = "https://files.pythonhosted.org/packages/b8/0e/69ed296de8ea05cb03ee139cee600f424ca166e632567b2d66727f08c7ed/pillow-12.1.0-cp314-cp314t-win_amd64.whl", hash = "sha256:27b9baecb428899db6c0de572d6d305cfaf38ca1596b5c0542a5182e3e74e8c6", size = 7182927, upload-time = "2026-01-02T09:13:09.841Z" },
+ { url = "https://files.pythonhosted.org/packages/fc/f5/68334c015eed9b5cff77814258717dec591ded209ab5b6fb70e2ae873d1d/pillow-12.1.0-cp314-cp314t-win_arm64.whl", hash = "sha256:f61333d817698bdcdd0f9d7793e365ac3d2a21c1f1eb02b32ad6aefb8d8ea831", size = 2545104, upload-time = "2026-01-02T09:13:12.068Z" },
+ { url = "https://files.pythonhosted.org/packages/8b/bc/224b1d98cffd7164b14707c91aac83c07b047fbd8f58eba4066a3e53746a/pillow-12.1.0-pp311-pypy311_pp73-macosx_10_15_x86_64.whl", hash = "sha256:ca94b6aac0d7af2a10ba08c0f888b3d5114439b6b3ef39968378723622fed377", size = 5228605, upload-time = "2026-01-02T09:13:14.084Z" },
+ { url = "https://files.pythonhosted.org/packages/0c/ca/49ca7769c4550107de049ed85208240ba0f330b3f2e316f24534795702ce/pillow-12.1.0-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:351889afef0f485b84078ea40fe33727a0492b9af3904661b0abbafee0355b72", size = 4622245, upload-time = "2026-01-02T09:13:15.964Z" },
+ { url = "https://files.pythonhosted.org/packages/73/48/fac807ce82e5955bcc2718642b94b1bd22a82a6d452aea31cbb678cddf12/pillow-12.1.0-pp311-pypy311_pp73-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:bb0984b30e973f7e2884362b7d23d0a348c7143ee559f38ef3eaab640144204c", size = 5247593, upload-time = "2026-01-02T09:13:17.913Z" },
+ { url = "https://files.pythonhosted.org/packages/d2/95/3e0742fe358c4664aed4fd05d5f5373dcdad0b27af52aa0972568541e3f4/pillow-12.1.0-pp311-pypy311_pp73-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:84cabc7095dd535ca934d57e9ce2a72ffd216e435a84acb06b2277b1de2689bd", size = 6989008, upload-time = "2026-01-02T09:13:20.083Z" },
+ { url = "https://files.pythonhosted.org/packages/5a/74/fe2ac378e4e202e56d50540d92e1ef4ff34ed687f3c60f6a121bcf99437e/pillow-12.1.0-pp311-pypy311_pp73-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:53d8b764726d3af1a138dd353116f774e3862ec7e3794e0c8781e30db0f35dfc", size = 5313824, upload-time = "2026-01-02T09:13:22.405Z" },
+ { url = "https://files.pythonhosted.org/packages/f3/77/2a60dee1adee4e2655ac328dd05c02a955c1cd683b9f1b82ec3feb44727c/pillow-12.1.0-pp311-pypy311_pp73-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:5da841d81b1a05ef940a8567da92decaa15bc4d7dedb540a8c219ad83d91808a", size = 5963278, upload-time = "2026-01-02T09:13:24.706Z" },
+ { url = "https://files.pythonhosted.org/packages/2d/71/64e9b1c7f04ae0027f788a248e6297d7fcc29571371fe7d45495a78172c0/pillow-12.1.0-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:75af0b4c229ac519b155028fa1be632d812a519abba9b46b20e50c6caa184f19", size = 7029809, upload-time = "2026-01-02T09:13:26.541Z" },
+]
+
+[[package]]
+name = "platformdirs"
+version = "4.5.1"
+source = { registry = "https://pypi.org/simple" }
+sdist = { url = "https://files.pythonhosted.org/packages/cf/86/0248f086a84f01b37aaec0fa567b397df1a119f73c16f6c7a9aac73ea309/platformdirs-4.5.1.tar.gz", hash = "sha256:61d5cdcc6065745cdd94f0f878977f8de9437be93de97c1c12f853c9c0cdcbda", size = 21715, upload-time = "2025-12-05T13:52:58.638Z" }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/cb/28/3bfe2fa5a7b9c46fe7e13c97bda14c895fb10fa2ebf1d0abb90e0cea7ee1/platformdirs-4.5.1-py3-none-any.whl", hash = "sha256:d03afa3963c806a9bed9d5125c8f4cb2fdaf74a55ab60e5d59b3fde758104d31", size = 18731, upload-time = "2025-12-05T13:52:56.823Z" },
+]
+
+[[package]]
+name = "pluggy"
+version = "1.6.0"
+source = { registry = "https://pypi.org/simple" }
+sdist = { url = "https://files.pythonhosted.org/packages/f9/e2/3e91f31a7d2b083fe6ef3fa267035b518369d9511ffab804f839851d2779/pluggy-1.6.0.tar.gz", hash = "sha256:7dcc130b76258d33b90f61b658791dede3486c3e6bfb003ee5c9bfb396dd22f3", size = 69412, upload-time = "2025-05-15T12:30:07.975Z" }
wheels = [
- { url = "https://files.pythonhosted.org/packages/c7/26/0e0fb582bcb2a7cb6802447a749a2fc938fe4b82324097abccb86abfd5d1/openai-1.59.3-py3-none-any.whl", hash = "sha256:b041887a0d8f3e70d1fc6ffbb2bf7661c3b9a2f3e806c04bf42f572b9ac7bc37", size = 454793 },
+ { url = "https://files.pythonhosted.org/packages/54/20/4d324d65cc6d9205fabedc306948156824eb9f0ee1633355a8f7ec5c66bf/pluggy-1.6.0-py3-none-any.whl", hash = "sha256:e920276dd6813095e9377c0bc5566d94c932c33b27a3e3945d8389c374dd4746", size = 20538, upload-time = "2025-05-15T12:30:06.134Z" },
]
[[package]]
@@ -190,9 +1036,9 @@ dependencies = [
{ name = "pydantic-core" },
{ name = "typing-extensions" },
]
-sdist = { url = "https://files.pythonhosted.org/packages/70/7e/fb60e6fee04d0ef8f15e4e01ff187a196fa976eb0f0ab524af4599e5754c/pydantic-2.10.4.tar.gz", hash = "sha256:82f12e9723da6de4fe2ba888b5971157b3be7ad914267dea8f05f82b28254f06", size = 762094 }
+sdist = { url = "https://files.pythonhosted.org/packages/70/7e/fb60e6fee04d0ef8f15e4e01ff187a196fa976eb0f0ab524af4599e5754c/pydantic-2.10.4.tar.gz", hash = "sha256:82f12e9723da6de4fe2ba888b5971157b3be7ad914267dea8f05f82b28254f06", size = 762094, upload-time = "2024-12-18T17:09:24.84Z" }
wheels = [
- { url = "https://files.pythonhosted.org/packages/f3/26/3e1bbe954fde7ee22a6e7d31582c642aad9e84ffe4b5fb61e63b87cd326f/pydantic-2.10.4-py3-none-any.whl", hash = "sha256:597e135ea68be3a37552fb524bc7d0d66dcf93d395acd93a00682f1efcb8ee3d", size = 431765 },
+ { url = "https://files.pythonhosted.org/packages/f3/26/3e1bbe954fde7ee22a6e7d31582c642aad9e84ffe4b5fb61e63b87cd326f/pydantic-2.10.4-py3-none-any.whl", hash = "sha256:597e135ea68be3a37552fb524bc7d0d66dcf93d395acd93a00682f1efcb8ee3d", size = 431765, upload-time = "2024-12-18T17:09:21.953Z" },
]
[[package]]
@@ -202,40 +1048,137 @@ source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "typing-extensions" },
]
-sdist = { url = "https://files.pythonhosted.org/packages/fc/01/f3e5ac5e7c25833db5eb555f7b7ab24cd6f8c322d3a3ad2d67a952dc0abc/pydantic_core-2.27.2.tar.gz", hash = "sha256:eb026e5a4c1fee05726072337ff51d1efb6f59090b7da90d30ea58625b1ffb39", size = 413443 }
+sdist = { url = "https://files.pythonhosted.org/packages/fc/01/f3e5ac5e7c25833db5eb555f7b7ab24cd6f8c322d3a3ad2d67a952dc0abc/pydantic_core-2.27.2.tar.gz", hash = "sha256:eb026e5a4c1fee05726072337ff51d1efb6f59090b7da90d30ea58625b1ffb39", size = 413443, upload-time = "2024-12-18T11:31:54.917Z" }
wheels = [
- { url = "https://files.pythonhosted.org/packages/41/b1/9bc383f48f8002f99104e3acff6cba1231b29ef76cfa45d1506a5cad1f84/pydantic_core-2.27.2-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:7d14bd329640e63852364c306f4d23eb744e0f8193148d4044dd3dacdaacbd8b", size = 1892709 },
- { url = "https://files.pythonhosted.org/packages/10/6c/e62b8657b834f3eb2961b49ec8e301eb99946245e70bf42c8817350cbefc/pydantic_core-2.27.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:82f91663004eb8ed30ff478d77c4d1179b3563df6cdb15c0817cd1cdaf34d154", size = 1811273 },
- { url = "https://files.pythonhosted.org/packages/ba/15/52cfe49c8c986e081b863b102d6b859d9defc63446b642ccbbb3742bf371/pydantic_core-2.27.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:71b24c7d61131bb83df10cc7e687433609963a944ccf45190cfc21e0887b08c9", size = 1823027 },
- { url = "https://files.pythonhosted.org/packages/b1/1c/b6f402cfc18ec0024120602bdbcebc7bdd5b856528c013bd4d13865ca473/pydantic_core-2.27.2-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:fa8e459d4954f608fa26116118bb67f56b93b209c39b008277ace29937453dc9", size = 1868888 },
- { url = "https://files.pythonhosted.org/packages/bd/7b/8cb75b66ac37bc2975a3b7de99f3c6f355fcc4d89820b61dffa8f1e81677/pydantic_core-2.27.2-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ce8918cbebc8da707ba805b7fd0b382816858728ae7fe19a942080c24e5b7cd1", size = 2037738 },
- { url = "https://files.pythonhosted.org/packages/c8/f1/786d8fe78970a06f61df22cba58e365ce304bf9b9f46cc71c8c424e0c334/pydantic_core-2.27.2-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:eda3f5c2a021bbc5d976107bb302e0131351c2ba54343f8a496dc8783d3d3a6a", size = 2685138 },
- { url = "https://files.pythonhosted.org/packages/a6/74/d12b2cd841d8724dc8ffb13fc5cef86566a53ed358103150209ecd5d1999/pydantic_core-2.27.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bd8086fa684c4775c27f03f062cbb9eaa6e17f064307e86b21b9e0abc9c0f02e", size = 1997025 },
- { url = "https://files.pythonhosted.org/packages/a0/6e/940bcd631bc4d9a06c9539b51f070b66e8f370ed0933f392db6ff350d873/pydantic_core-2.27.2-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:8d9b3388db186ba0c099a6d20f0604a44eabdeef1777ddd94786cdae158729e4", size = 2004633 },
- { url = "https://files.pythonhosted.org/packages/50/cc/a46b34f1708d82498c227d5d80ce615b2dd502ddcfd8376fc14a36655af1/pydantic_core-2.27.2-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:7a66efda2387de898c8f38c0cf7f14fca0b51a8ef0b24bfea5849f1b3c95af27", size = 1999404 },
- { url = "https://files.pythonhosted.org/packages/ca/2d/c365cfa930ed23bc58c41463bae347d1005537dc8db79e998af8ba28d35e/pydantic_core-2.27.2-cp313-cp313-musllinux_1_1_armv7l.whl", hash = "sha256:18a101c168e4e092ab40dbc2503bdc0f62010e95d292b27827871dc85450d7ee", size = 2130130 },
- { url = "https://files.pythonhosted.org/packages/f4/d7/eb64d015c350b7cdb371145b54d96c919d4db516817f31cd1c650cae3b21/pydantic_core-2.27.2-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:ba5dd002f88b78a4215ed2f8ddbdf85e8513382820ba15ad5ad8955ce0ca19a1", size = 2157946 },
- { url = "https://files.pythonhosted.org/packages/a4/99/bddde3ddde76c03b65dfd5a66ab436c4e58ffc42927d4ff1198ffbf96f5f/pydantic_core-2.27.2-cp313-cp313-win32.whl", hash = "sha256:1ebaf1d0481914d004a573394f4be3a7616334be70261007e47c2a6fe7e50130", size = 1834387 },
- { url = "https://files.pythonhosted.org/packages/71/47/82b5e846e01b26ac6f1893d3c5f9f3a2eb6ba79be26eef0b759b4fe72946/pydantic_core-2.27.2-cp313-cp313-win_amd64.whl", hash = "sha256:953101387ecf2f5652883208769a79e48db18c6df442568a0b5ccd8c2723abee", size = 1990453 },
- { url = "https://files.pythonhosted.org/packages/51/b2/b2b50d5ecf21acf870190ae5d093602d95f66c9c31f9d5de6062eb329ad1/pydantic_core-2.27.2-cp313-cp313-win_arm64.whl", hash = "sha256:ac4dbfd1691affb8f48c2c13241a2e3b60ff23247cbcf981759c768b6633cf8b", size = 1885186 },
+ { url = "https://files.pythonhosted.org/packages/c2/89/f3450af9d09d44eea1f2c369f49e8f181d742f28220f88cc4dfaae91ea6e/pydantic_core-2.27.2-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:8e10c99ef58cfdf2a66fc15d66b16c4a04f62bca39db589ae8cba08bc55331bc", size = 1893421, upload-time = "2024-12-18T11:27:55.409Z" },
+ { url = "https://files.pythonhosted.org/packages/9e/e3/71fe85af2021f3f386da42d291412e5baf6ce7716bd7101ea49c810eda90/pydantic_core-2.27.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:26f32e0adf166a84d0cb63be85c562ca8a6fa8de28e5f0d92250c6b7e9e2aff7", size = 1814998, upload-time = "2024-12-18T11:27:57.252Z" },
+ { url = "https://files.pythonhosted.org/packages/a6/3c/724039e0d848fd69dbf5806894e26479577316c6f0f112bacaf67aa889ac/pydantic_core-2.27.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8c19d1ea0673cd13cc2f872f6c9ab42acc4e4f492a7ca9d3795ce2b112dd7e15", size = 1826167, upload-time = "2024-12-18T11:27:59.146Z" },
+ { url = "https://files.pythonhosted.org/packages/2b/5b/1b29e8c1fb5f3199a9a57c1452004ff39f494bbe9bdbe9a81e18172e40d3/pydantic_core-2.27.2-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:5e68c4446fe0810e959cdff46ab0a41ce2f2c86d227d96dc3847af0ba7def306", size = 1865071, upload-time = "2024-12-18T11:28:02.625Z" },
+ { url = "https://files.pythonhosted.org/packages/89/6c/3985203863d76bb7d7266e36970d7e3b6385148c18a68cc8915fd8c84d57/pydantic_core-2.27.2-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d9640b0059ff4f14d1f37321b94061c6db164fbe49b334b31643e0528d100d99", size = 2036244, upload-time = "2024-12-18T11:28:04.442Z" },
+ { url = "https://files.pythonhosted.org/packages/0e/41/f15316858a246b5d723f7d7f599f79e37493b2e84bfc789e58d88c209f8a/pydantic_core-2.27.2-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:40d02e7d45c9f8af700f3452f329ead92da4c5f4317ca9b896de7ce7199ea459", size = 2737470, upload-time = "2024-12-18T11:28:07.679Z" },
+ { url = "https://files.pythonhosted.org/packages/a8/7c/b860618c25678bbd6d1d99dbdfdf0510ccb50790099b963ff78a124b754f/pydantic_core-2.27.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1c1fd185014191700554795c99b347d64f2bb637966c4cfc16998a0ca700d048", size = 1992291, upload-time = "2024-12-18T11:28:10.297Z" },
+ { url = "https://files.pythonhosted.org/packages/bf/73/42c3742a391eccbeab39f15213ecda3104ae8682ba3c0c28069fbcb8c10d/pydantic_core-2.27.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:d81d2068e1c1228a565af076598f9e7451712700b673de8f502f0334f281387d", size = 1994613, upload-time = "2024-12-18T11:28:13.362Z" },
+ { url = "https://files.pythonhosted.org/packages/94/7a/941e89096d1175d56f59340f3a8ebaf20762fef222c298ea96d36a6328c5/pydantic_core-2.27.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:1a4207639fb02ec2dbb76227d7c751a20b1a6b4bc52850568e52260cae64ca3b", size = 2002355, upload-time = "2024-12-18T11:28:16.587Z" },
+ { url = "https://files.pythonhosted.org/packages/6e/95/2359937a73d49e336a5a19848713555605d4d8d6940c3ec6c6c0ca4dcf25/pydantic_core-2.27.2-cp311-cp311-musllinux_1_1_armv7l.whl", hash = "sha256:3de3ce3c9ddc8bbd88f6e0e304dea0e66d843ec9de1b0042b0911c1663ffd474", size = 2126661, upload-time = "2024-12-18T11:28:18.407Z" },
+ { url = "https://files.pythonhosted.org/packages/2b/4c/ca02b7bdb6012a1adef21a50625b14f43ed4d11f1fc237f9d7490aa5078c/pydantic_core-2.27.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:30c5f68ded0c36466acede341551106821043e9afaad516adfb6e8fa80a4e6a6", size = 2153261, upload-time = "2024-12-18T11:28:21.471Z" },
+ { url = "https://files.pythonhosted.org/packages/72/9d/a241db83f973049a1092a079272ffe2e3e82e98561ef6214ab53fe53b1c7/pydantic_core-2.27.2-cp311-cp311-win32.whl", hash = "sha256:c70c26d2c99f78b125a3459f8afe1aed4d9687c24fd677c6a4436bc042e50d6c", size = 1812361, upload-time = "2024-12-18T11:28:23.53Z" },
+ { url = "https://files.pythonhosted.org/packages/e8/ef/013f07248041b74abd48a385e2110aa3a9bbfef0fbd97d4e6d07d2f5b89a/pydantic_core-2.27.2-cp311-cp311-win_amd64.whl", hash = "sha256:08e125dbdc505fa69ca7d9c499639ab6407cfa909214d500897d02afb816e7cc", size = 1982484, upload-time = "2024-12-18T11:28:25.391Z" },
+ { url = "https://files.pythonhosted.org/packages/10/1c/16b3a3e3398fd29dca77cea0a1d998d6bde3902fa2706985191e2313cc76/pydantic_core-2.27.2-cp311-cp311-win_arm64.whl", hash = "sha256:26f0d68d4b235a2bae0c3fc585c585b4ecc51382db0e3ba402a22cbc440915e4", size = 1867102, upload-time = "2024-12-18T11:28:28.593Z" },
+ { url = "https://files.pythonhosted.org/packages/d6/74/51c8a5482ca447871c93e142d9d4a92ead74de6c8dc5e66733e22c9bba89/pydantic_core-2.27.2-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:9e0c8cfefa0ef83b4da9588448b6d8d2a2bf1a53c3f1ae5fca39eb3061e2f0b0", size = 1893127, upload-time = "2024-12-18T11:28:30.346Z" },
+ { url = "https://files.pythonhosted.org/packages/d3/f3/c97e80721735868313c58b89d2de85fa80fe8dfeeed84dc51598b92a135e/pydantic_core-2.27.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:83097677b8e3bd7eaa6775720ec8e0405f1575015a463285a92bfdfe254529ef", size = 1811340, upload-time = "2024-12-18T11:28:32.521Z" },
+ { url = "https://files.pythonhosted.org/packages/9e/91/840ec1375e686dbae1bd80a9e46c26a1e0083e1186abc610efa3d9a36180/pydantic_core-2.27.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:172fce187655fece0c90d90a678424b013f8fbb0ca8b036ac266749c09438cb7", size = 1822900, upload-time = "2024-12-18T11:28:34.507Z" },
+ { url = "https://files.pythonhosted.org/packages/f6/31/4240bc96025035500c18adc149aa6ffdf1a0062a4b525c932065ceb4d868/pydantic_core-2.27.2-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:519f29f5213271eeeeb3093f662ba2fd512b91c5f188f3bb7b27bc5973816934", size = 1869177, upload-time = "2024-12-18T11:28:36.488Z" },
+ { url = "https://files.pythonhosted.org/packages/fa/20/02fbaadb7808be578317015c462655c317a77a7c8f0ef274bc016a784c54/pydantic_core-2.27.2-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:05e3a55d124407fffba0dd6b0c0cd056d10e983ceb4e5dbd10dda135c31071d6", size = 2038046, upload-time = "2024-12-18T11:28:39.409Z" },
+ { url = "https://files.pythonhosted.org/packages/06/86/7f306b904e6c9eccf0668248b3f272090e49c275bc488a7b88b0823444a4/pydantic_core-2.27.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9c3ed807c7b91de05e63930188f19e921d1fe90de6b4f5cd43ee7fcc3525cb8c", size = 2685386, upload-time = "2024-12-18T11:28:41.221Z" },
+ { url = "https://files.pythonhosted.org/packages/8d/f0/49129b27c43396581a635d8710dae54a791b17dfc50c70164866bbf865e3/pydantic_core-2.27.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6fb4aadc0b9a0c063206846d603b92030eb6f03069151a625667f982887153e2", size = 1997060, upload-time = "2024-12-18T11:28:44.709Z" },
+ { url = "https://files.pythonhosted.org/packages/0d/0f/943b4af7cd416c477fd40b187036c4f89b416a33d3cc0ab7b82708a667aa/pydantic_core-2.27.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:28ccb213807e037460326424ceb8b5245acb88f32f3d2777427476e1b32c48c4", size = 2004870, upload-time = "2024-12-18T11:28:46.839Z" },
+ { url = "https://files.pythonhosted.org/packages/35/40/aea70b5b1a63911c53a4c8117c0a828d6790483f858041f47bab0b779f44/pydantic_core-2.27.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:de3cd1899e2c279b140adde9357c4495ed9d47131b4a4eaff9052f23398076b3", size = 1999822, upload-time = "2024-12-18T11:28:48.896Z" },
+ { url = "https://files.pythonhosted.org/packages/f2/b3/807b94fd337d58effc5498fd1a7a4d9d59af4133e83e32ae39a96fddec9d/pydantic_core-2.27.2-cp312-cp312-musllinux_1_1_armv7l.whl", hash = "sha256:220f892729375e2d736b97d0e51466252ad84c51857d4d15f5e9692f9ef12be4", size = 2130364, upload-time = "2024-12-18T11:28:50.755Z" },
+ { url = "https://files.pythonhosted.org/packages/fc/df/791c827cd4ee6efd59248dca9369fb35e80a9484462c33c6649a8d02b565/pydantic_core-2.27.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:a0fcd29cd6b4e74fe8ddd2c90330fd8edf2e30cb52acda47f06dd615ae72da57", size = 2158303, upload-time = "2024-12-18T11:28:54.122Z" },
+ { url = "https://files.pythonhosted.org/packages/9b/67/4e197c300976af185b7cef4c02203e175fb127e414125916bf1128b639a9/pydantic_core-2.27.2-cp312-cp312-win32.whl", hash = "sha256:1e2cb691ed9834cd6a8be61228471d0a503731abfb42f82458ff27be7b2186fc", size = 1834064, upload-time = "2024-12-18T11:28:56.074Z" },
+ { url = "https://files.pythonhosted.org/packages/1f/ea/cd7209a889163b8dcca139fe32b9687dd05249161a3edda62860430457a5/pydantic_core-2.27.2-cp312-cp312-win_amd64.whl", hash = "sha256:cc3f1a99a4f4f9dd1de4fe0312c114e740b5ddead65bb4102884b384c15d8bc9", size = 1989046, upload-time = "2024-12-18T11:28:58.107Z" },
+ { url = "https://files.pythonhosted.org/packages/bc/49/c54baab2f4658c26ac633d798dab66b4c3a9bbf47cff5284e9c182f4137a/pydantic_core-2.27.2-cp312-cp312-win_arm64.whl", hash = "sha256:3911ac9284cd8a1792d3cb26a2da18f3ca26c6908cc434a18f730dc0db7bfa3b", size = 1885092, upload-time = "2024-12-18T11:29:01.335Z" },
+ { url = "https://files.pythonhosted.org/packages/41/b1/9bc383f48f8002f99104e3acff6cba1231b29ef76cfa45d1506a5cad1f84/pydantic_core-2.27.2-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:7d14bd329640e63852364c306f4d23eb744e0f8193148d4044dd3dacdaacbd8b", size = 1892709, upload-time = "2024-12-18T11:29:03.193Z" },
+ { url = "https://files.pythonhosted.org/packages/10/6c/e62b8657b834f3eb2961b49ec8e301eb99946245e70bf42c8817350cbefc/pydantic_core-2.27.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:82f91663004eb8ed30ff478d77c4d1179b3563df6cdb15c0817cd1cdaf34d154", size = 1811273, upload-time = "2024-12-18T11:29:05.306Z" },
+ { url = "https://files.pythonhosted.org/packages/ba/15/52cfe49c8c986e081b863b102d6b859d9defc63446b642ccbbb3742bf371/pydantic_core-2.27.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:71b24c7d61131bb83df10cc7e687433609963a944ccf45190cfc21e0887b08c9", size = 1823027, upload-time = "2024-12-18T11:29:07.294Z" },
+ { url = "https://files.pythonhosted.org/packages/b1/1c/b6f402cfc18ec0024120602bdbcebc7bdd5b856528c013bd4d13865ca473/pydantic_core-2.27.2-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:fa8e459d4954f608fa26116118bb67f56b93b209c39b008277ace29937453dc9", size = 1868888, upload-time = "2024-12-18T11:29:09.249Z" },
+ { url = "https://files.pythonhosted.org/packages/bd/7b/8cb75b66ac37bc2975a3b7de99f3c6f355fcc4d89820b61dffa8f1e81677/pydantic_core-2.27.2-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ce8918cbebc8da707ba805b7fd0b382816858728ae7fe19a942080c24e5b7cd1", size = 2037738, upload-time = "2024-12-18T11:29:11.23Z" },
+ { url = "https://files.pythonhosted.org/packages/c8/f1/786d8fe78970a06f61df22cba58e365ce304bf9b9f46cc71c8c424e0c334/pydantic_core-2.27.2-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:eda3f5c2a021bbc5d976107bb302e0131351c2ba54343f8a496dc8783d3d3a6a", size = 2685138, upload-time = "2024-12-18T11:29:16.396Z" },
+ { url = "https://files.pythonhosted.org/packages/a6/74/d12b2cd841d8724dc8ffb13fc5cef86566a53ed358103150209ecd5d1999/pydantic_core-2.27.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bd8086fa684c4775c27f03f062cbb9eaa6e17f064307e86b21b9e0abc9c0f02e", size = 1997025, upload-time = "2024-12-18T11:29:20.25Z" },
+ { url = "https://files.pythonhosted.org/packages/a0/6e/940bcd631bc4d9a06c9539b51f070b66e8f370ed0933f392db6ff350d873/pydantic_core-2.27.2-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:8d9b3388db186ba0c099a6d20f0604a44eabdeef1777ddd94786cdae158729e4", size = 2004633, upload-time = "2024-12-18T11:29:23.877Z" },
+ { url = "https://files.pythonhosted.org/packages/50/cc/a46b34f1708d82498c227d5d80ce615b2dd502ddcfd8376fc14a36655af1/pydantic_core-2.27.2-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:7a66efda2387de898c8f38c0cf7f14fca0b51a8ef0b24bfea5849f1b3c95af27", size = 1999404, upload-time = "2024-12-18T11:29:25.872Z" },
+ { url = "https://files.pythonhosted.org/packages/ca/2d/c365cfa930ed23bc58c41463bae347d1005537dc8db79e998af8ba28d35e/pydantic_core-2.27.2-cp313-cp313-musllinux_1_1_armv7l.whl", hash = "sha256:18a101c168e4e092ab40dbc2503bdc0f62010e95d292b27827871dc85450d7ee", size = 2130130, upload-time = "2024-12-18T11:29:29.252Z" },
+ { url = "https://files.pythonhosted.org/packages/f4/d7/eb64d015c350b7cdb371145b54d96c919d4db516817f31cd1c650cae3b21/pydantic_core-2.27.2-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:ba5dd002f88b78a4215ed2f8ddbdf85e8513382820ba15ad5ad8955ce0ca19a1", size = 2157946, upload-time = "2024-12-18T11:29:31.338Z" },
+ { url = "https://files.pythonhosted.org/packages/a4/99/bddde3ddde76c03b65dfd5a66ab436c4e58ffc42927d4ff1198ffbf96f5f/pydantic_core-2.27.2-cp313-cp313-win32.whl", hash = "sha256:1ebaf1d0481914d004a573394f4be3a7616334be70261007e47c2a6fe7e50130", size = 1834387, upload-time = "2024-12-18T11:29:33.481Z" },
+ { url = "https://files.pythonhosted.org/packages/71/47/82b5e846e01b26ac6f1893d3c5f9f3a2eb6ba79be26eef0b759b4fe72946/pydantic_core-2.27.2-cp313-cp313-win_amd64.whl", hash = "sha256:953101387ecf2f5652883208769a79e48db18c6df442568a0b5ccd8c2723abee", size = 1990453, upload-time = "2024-12-18T11:29:35.533Z" },
+ { url = "https://files.pythonhosted.org/packages/51/b2/b2b50d5ecf21acf870190ae5d093602d95f66c9c31f9d5de6062eb329ad1/pydantic_core-2.27.2-cp313-cp313-win_arm64.whl", hash = "sha256:ac4dbfd1691affb8f48c2c13241a2e3b60ff23247cbcf981759c768b6633cf8b", size = 1885186, upload-time = "2024-12-18T11:29:37.649Z" },
]
[[package]]
name = "pygments"
version = "2.19.0"
source = { registry = "https://pypi.org/simple" }
-sdist = { url = "https://files.pythonhosted.org/packages/d3/c0/9c9832e5be227c40e1ce774d493065f83a91d6430baa7e372094e9683a45/pygments-2.19.0.tar.gz", hash = "sha256:afc4146269910d4bdfabcd27c24923137a74d562a23a320a41a55ad303e19783", size = 4967733 }
+sdist = { url = "https://files.pythonhosted.org/packages/d3/c0/9c9832e5be227c40e1ce774d493065f83a91d6430baa7e372094e9683a45/pygments-2.19.0.tar.gz", hash = "sha256:afc4146269910d4bdfabcd27c24923137a74d562a23a320a41a55ad303e19783", size = 4967733, upload-time = "2025-01-05T14:11:17.285Z" }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/20/dc/fde3e7ac4d279a331676829af4afafd113b34272393d73f610e8f0329221/pygments-2.19.0-py3-none-any.whl", hash = "sha256:4755e6e64d22161d5b61432c0600c923c5927214e7c956e31c23923c89251a9b", size = 1225305, upload-time = "2025-01-05T14:11:12.158Z" },
+]
+
+[[package]]
+name = "pyparsing"
+version = "3.3.1"
+source = { registry = "https://pypi.org/simple" }
+sdist = { url = "https://files.pythonhosted.org/packages/33/c1/1d9de9aeaa1b89b0186e5fe23294ff6517fce1bc69149185577cd31016b2/pyparsing-3.3.1.tar.gz", hash = "sha256:47fad0f17ac1e2cad3de3b458570fbc9b03560aa029ed5e16ee5554da9a2251c", size = 1550512, upload-time = "2025-12-23T03:14:04.391Z" }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/8b/40/2614036cdd416452f5bf98ec037f38a1afb17f327cb8e6b652d4729e0af8/pyparsing-3.3.1-py3-none-any.whl", hash = "sha256:023b5e7e5520ad96642e2c6db4cb683d3970bd640cdf7115049a6e9c3682df82", size = 121793, upload-time = "2025-12-23T03:14:02.103Z" },
+]
+
+[[package]]
+name = "pytest"
+version = "9.0.2"
+source = { registry = "https://pypi.org/simple" }
+dependencies = [
+ { name = "colorama", marker = "sys_platform == 'win32'" },
+ { name = "iniconfig" },
+ { name = "packaging" },
+ { name = "pluggy" },
+ { name = "pygments" },
+]
+sdist = { url = "https://files.pythonhosted.org/packages/d1/db/7ef3487e0fb0049ddb5ce41d3a49c235bf9ad299b6a25d5780a89f19230f/pytest-9.0.2.tar.gz", hash = "sha256:75186651a92bd89611d1d9fc20f0b4345fd827c41ccd5c299a868a05d70edf11", size = 1568901, upload-time = "2025-12-06T21:30:51.014Z" }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/3b/ab/b3226f0bd7cdcf710fbede2b3548584366da3b19b5021e74f5bde2a8fa3f/pytest-9.0.2-py3-none-any.whl", hash = "sha256:711ffd45bf766d5264d487b917733b453d917afd2b0ad65223959f59089f875b", size = 374801, upload-time = "2025-12-06T21:30:49.154Z" },
+]
+
+[[package]]
+name = "pytest-cov"
+version = "7.0.0"
+source = { registry = "https://pypi.org/simple" }
+dependencies = [
+ { name = "coverage", extra = ["toml"] },
+ { name = "pluggy" },
+ { name = "pytest" },
+]
+sdist = { url = "https://files.pythonhosted.org/packages/5e/f7/c933acc76f5208b3b00089573cf6a2bc26dc80a8aece8f52bb7d6b1855ca/pytest_cov-7.0.0.tar.gz", hash = "sha256:33c97eda2e049a0c5298e91f519302a1334c26ac65c1a483d6206fd458361af1", size = 54328, upload-time = "2025-09-09T10:57:02.113Z" }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/ee/49/1377b49de7d0c1ce41292161ea0f721913fa8722c19fb9c1e3aa0367eecb/pytest_cov-7.0.0-py3-none-any.whl", hash = "sha256:3b8e9558b16cc1479da72058bdecf8073661c7f57f7d3c5f22a1c23507f2d861", size = 22424, upload-time = "2025-09-09T10:57:00.695Z" },
+]
+
+[[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/20/dc/fde3e7ac4d279a331676829af4afafd113b34272393d73f610e8f0329221/pygments-2.19.0-py3-none-any.whl", hash = "sha256:4755e6e64d22161d5b61432c0600c923c5927214e7c956e31c23923c89251a9b", size = 1225305 },
+ { url = "https://files.pythonhosted.org/packages/ec/57/56b9bcc3c9c6a792fcbaf139543cee77261f3651ca9da0c93f5c1221264b/python_dateutil-2.9.0.post0-py2.py3-none-any.whl", hash = "sha256:a8b2bc7bffae282281c8140a97d3aa9c14da0b136dfe83f850eea9a5f7470427", size = 229892, upload-time = "2024-03-01T18:36:18.57Z" },
]
[[package]]
name = "python-dotenv"
version = "1.0.1"
source = { registry = "https://pypi.org/simple" }
-sdist = { url = "https://files.pythonhosted.org/packages/bc/57/e84d88dfe0aec03b7a2d4327012c1627ab5f03652216c63d49846d7a6c58/python-dotenv-1.0.1.tar.gz", hash = "sha256:e324ee90a023d808f1959c46bcbc04446a10ced277783dc6ee09987c37ec10ca", size = 39115 }
+sdist = { url = "https://files.pythonhosted.org/packages/bc/57/e84d88dfe0aec03b7a2d4327012c1627ab5f03652216c63d49846d7a6c58/python-dotenv-1.0.1.tar.gz", hash = "sha256:e324ee90a023d808f1959c46bcbc04446a10ced277783dc6ee09987c37ec10ca", size = 39115, upload-time = "2024-01-23T06:33:00.505Z" }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/6a/3e/b68c118422ec867fa7ab88444e1274aa40681c606d59ac27de5a5588f082/python_dotenv-1.0.1-py3-none-any.whl", hash = "sha256:f7b63ef50f1b690dddf550d03497b66d609393b40b564ed0d674909a68ebf16a", size = 19863, upload-time = "2024-01-23T06:32:58.246Z" },
+]
+
+[[package]]
+name = "pytokens"
+version = "0.3.0"
+source = { registry = "https://pypi.org/simple" }
+sdist = { url = "https://files.pythonhosted.org/packages/4e/8d/a762be14dae1c3bf280202ba3172020b2b0b4c537f94427435f19c413b72/pytokens-0.3.0.tar.gz", hash = "sha256:2f932b14ed08de5fcf0b391ace2642f858f1394c0857202959000b68ed7a458a", size = 17644, upload-time = "2025-11-05T13:36:35.34Z" }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/84/25/d9db8be44e205a124f6c98bc0324b2bb149b7431c53877fc6d1038dddaf5/pytokens-0.3.0-py3-none-any.whl", hash = "sha256:95b2b5eaf832e469d141a378872480ede3f251a5a5041b8ec6e581d3ac71bbf3", size = 12195, upload-time = "2025-11-05T13:36:33.183Z" },
+]
+
+[[package]]
+name = "pytz"
+version = "2025.2"
+source = { registry = "https://pypi.org/simple" }
+sdist = { url = "https://files.pythonhosted.org/packages/f8/bf/abbd3cdfb8fbc7fb3d4d38d320f2441b1e7cbe29be4f23797b4a2b5d8aac/pytz-2025.2.tar.gz", hash = "sha256:360b9e3dbb49a209c21ad61809c7fb453643e048b38924c765813546746e81c3", size = 320884, upload-time = "2025-03-25T02:25:00.538Z" }
wheels = [
- { url = "https://files.pythonhosted.org/packages/6a/3e/b68c118422ec867fa7ab88444e1274aa40681c606d59ac27de5a5588f082/python_dotenv-1.0.1-py3-none-any.whl", hash = "sha256:f7b63ef50f1b690dddf550d03497b66d609393b40b564ed0d674909a68ebf16a", size = 19863 },
+ { url = "https://files.pythonhosted.org/packages/81/c4/34e93fe5f5429d7570ec1fa436f1986fb1f00c3e0f43a589fe2bbcd22c3f/pytz-2025.2-py2.py3-none-any.whl", hash = "sha256:5ddf76296dd8c44c26eb8f4b6f35488f3ccbf6fbbd7adee0b7262d43f0ec2f00", size = 509225, upload-time = "2025-03-25T02:24:58.468Z" },
]
[[package]]
@@ -248,61 +1191,149 @@ dependencies = [
{ name = "idna" },
{ name = "urllib3" },
]
-sdist = { url = "https://files.pythonhosted.org/packages/63/70/2bf7780ad2d390a8d301ad0b550f1581eadbd9a20f896afe06353c2a2913/requests-2.32.3.tar.gz", hash = "sha256:55365417734eb18255590a9ff9eb97e9e1da868d4ccd6402399eaf68af20a760", size = 131218 }
+sdist = { url = "https://files.pythonhosted.org/packages/63/70/2bf7780ad2d390a8d301ad0b550f1581eadbd9a20f896afe06353c2a2913/requests-2.32.3.tar.gz", hash = "sha256:55365417734eb18255590a9ff9eb97e9e1da868d4ccd6402399eaf68af20a760", size = 131218, upload-time = "2024-05-29T15:37:49.536Z" }
wheels = [
- { url = "https://files.pythonhosted.org/packages/f9/9b/335f9764261e915ed497fcdeb11df5dfd6f7bf257d4a6a2a686d80da4d54/requests-2.32.3-py3-none-any.whl", hash = "sha256:70761cfe03c773ceb22aa2f671b4757976145175cdfca038c02654d061d6dcc6", size = 64928 },
+ { url = "https://files.pythonhosted.org/packages/f9/9b/335f9764261e915ed497fcdeb11df5dfd6f7bf257d4a6a2a686d80da4d54/requests-2.32.3-py3-none-any.whl", hash = "sha256:70761cfe03c773ceb22aa2f671b4757976145175cdfca038c02654d061d6dcc6", size = 64928, upload-time = "2024-05-29T15:37:47.027Z" },
]
[[package]]
-name = "rich"
-version = "13.9.4"
+name = "ruff"
+version = "0.14.11"
source = { registry = "https://pypi.org/simple" }
-dependencies = [
- { name = "markdown-it-py" },
- { name = "pygments" },
-]
-sdist = { url = "https://files.pythonhosted.org/packages/ab/3a/0316b28d0761c6734d6bc14e770d85506c986c85ffb239e688eeaab2c2bc/rich-13.9.4.tar.gz", hash = "sha256:439594978a49a09530cff7ebc4b5c7103ef57baf48d5ea3184f21d9a2befa098", size = 223149 }
+sdist = { url = "https://files.pythonhosted.org/packages/d4/77/9a7fe084d268f8855d493e5031ea03fa0af8cc05887f638bf1c4e3363eb8/ruff-0.14.11.tar.gz", hash = "sha256:f6dc463bfa5c07a59b1ff2c3b9767373e541346ea105503b4c0369c520a66958", size = 5993417, upload-time = "2026-01-08T19:11:58.322Z" }
wheels = [
- { url = "https://files.pythonhosted.org/packages/19/71/39c7c0d87f8d4e6c020a393182060eaefeeae6c01dab6a84ec346f2567df/rich-13.9.4-py3-none-any.whl", hash = "sha256:6049d5e6ec054bf2779ab3358186963bac2ea89175919d699e378b99738c2a90", size = 242424 },
+ { url = "https://files.pythonhosted.org/packages/f0/a6/a4c40a5aaa7e331f245d2dc1ac8ece306681f52b636b40ef87c88b9f7afd/ruff-0.14.11-py3-none-linux_armv6l.whl", hash = "sha256:f6ff2d95cbd335841a7217bdfd9c1d2e44eac2c584197ab1385579d55ff8830e", size = 12951208, upload-time = "2026-01-08T19:12:09.218Z" },
+ { url = "https://files.pythonhosted.org/packages/5c/5c/360a35cb7204b328b685d3129c08aca24765ff92b5a7efedbdd6c150d555/ruff-0.14.11-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:6f6eb5c1c8033680f4172ea9c8d3706c156223010b8b97b05e82c59bdc774ee6", size = 13330075, upload-time = "2026-01-08T19:12:02.549Z" },
+ { url = "https://files.pythonhosted.org/packages/1b/9e/0cc2f1be7a7d33cae541824cf3f95b4ff40d03557b575912b5b70273c9ec/ruff-0.14.11-py3-none-macosx_11_0_arm64.whl", hash = "sha256:f2fc34cc896f90080fca01259f96c566f74069a04b25b6205d55379d12a6855e", size = 12257809, upload-time = "2026-01-08T19:12:00.366Z" },
+ { url = "https://files.pythonhosted.org/packages/a7/e5/5faab97c15bb75228d9f74637e775d26ac703cc2b4898564c01ab3637c02/ruff-0.14.11-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:53386375001773ae812b43205d6064dae49ff0968774e6befe16a994fc233caa", size = 12678447, upload-time = "2026-01-08T19:12:13.899Z" },
+ { url = "https://files.pythonhosted.org/packages/1b/33/e9767f60a2bef779fb5855cab0af76c488e0ce90f7bb7b8a45c8a2ba4178/ruff-0.14.11-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:a697737dce1ca97a0a55b5ff0434ee7205943d4874d638fe3ae66166ff46edbe", size = 12758560, upload-time = "2026-01-08T19:11:42.55Z" },
+ { url = "https://files.pythonhosted.org/packages/eb/84/4c6cf627a21462bb5102f7be2a320b084228ff26e105510cd2255ea868e5/ruff-0.14.11-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6845ca1da8ab81ab1dce755a32ad13f1db72e7fba27c486d5d90d65e04d17b8f", size = 13599296, upload-time = "2026-01-08T19:11:30.371Z" },
+ { url = "https://files.pythonhosted.org/packages/88/e1/92b5ed7ea66d849f6157e695dc23d5d6d982bd6aa8d077895652c38a7cae/ruff-0.14.11-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:e36ce2fd31b54065ec6f76cb08d60159e1b32bdf08507862e32f47e6dde8bcbf", size = 15048981, upload-time = "2026-01-08T19:12:04.742Z" },
+ { url = "https://files.pythonhosted.org/packages/61/df/c1bd30992615ac17c2fb64b8a7376ca22c04a70555b5d05b8f717163cf9f/ruff-0.14.11-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:590bcc0e2097ecf74e62a5c10a6b71f008ad82eb97b0a0079e85defe19fe74d9", size = 14633183, upload-time = "2026-01-08T19:11:40.069Z" },
+ { url = "https://files.pythonhosted.org/packages/04/e9/fe552902f25013dd28a5428a42347d9ad20c4b534834a325a28305747d64/ruff-0.14.11-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:53fe71125fc158210d57fe4da26e622c9c294022988d08d9347ec1cf782adafe", size = 14050453, upload-time = "2026-01-08T19:11:37.555Z" },
+ { url = "https://files.pythonhosted.org/packages/ae/93/f36d89fa021543187f98991609ce6e47e24f35f008dfe1af01379d248a41/ruff-0.14.11-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a35c9da08562f1598ded8470fcfef2afb5cf881996e6c0a502ceb61f4bc9c8a3", size = 13757889, upload-time = "2026-01-08T19:12:07.094Z" },
+ { url = "https://files.pythonhosted.org/packages/b7/9f/c7fb6ecf554f28709a6a1f2a7f74750d400979e8cd47ed29feeaa1bd4db8/ruff-0.14.11-py3-none-manylinux_2_31_riscv64.whl", hash = "sha256:0f3727189a52179393ecf92ec7057c2210203e6af2676f08d92140d3e1ee72c1", size = 13955832, upload-time = "2026-01-08T19:11:55.064Z" },
+ { url = "https://files.pythonhosted.org/packages/db/a0/153315310f250f76900a98278cf878c64dfb6d044e184491dd3289796734/ruff-0.14.11-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:eb09f849bd37147a789b85995ff734a6c4a095bed5fd1608c4f56afc3634cde2", size = 12586522, upload-time = "2026-01-08T19:11:35.356Z" },
+ { url = "https://files.pythonhosted.org/packages/2f/2b/a73a2b6e6d2df1d74bf2b78098be1572191e54bec0e59e29382d13c3adc5/ruff-0.14.11-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:c61782543c1231bf71041461c1f28c64b961d457d0f238ac388e2ab173d7ecb7", size = 12724637, upload-time = "2026-01-08T19:11:47.796Z" },
+ { url = "https://files.pythonhosted.org/packages/f0/41/09100590320394401cd3c48fc718a8ba71c7ddb1ffd07e0ad6576b3a3df2/ruff-0.14.11-py3-none-musllinux_1_2_i686.whl", hash = "sha256:82ff352ea68fb6766140381748e1f67f83c39860b6446966cff48a315c3e2491", size = 13145837, upload-time = "2026-01-08T19:11:32.87Z" },
+ { url = "https://files.pythonhosted.org/packages/3b/d8/e035db859d1d3edf909381eb8ff3e89a672d6572e9454093538fe6f164b0/ruff-0.14.11-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:728e56879df4ca5b62a9dde2dd0eb0edda2a55160c0ea28c4025f18c03f86984", size = 13850469, upload-time = "2026-01-08T19:12:11.694Z" },
+ { url = "https://files.pythonhosted.org/packages/4e/02/bb3ff8b6e6d02ce9e3740f4c17dfbbfb55f34c789c139e9cd91985f356c7/ruff-0.14.11-py3-none-win32.whl", hash = "sha256:337c5dd11f16ee52ae217757d9b82a26400be7efac883e9e852646f1557ed841", size = 12851094, upload-time = "2026-01-08T19:11:45.163Z" },
+ { url = "https://files.pythonhosted.org/packages/58/f1/90ddc533918d3a2ad628bc3044cdfc094949e6d4b929220c3f0eb8a1c998/ruff-0.14.11-py3-none-win_amd64.whl", hash = "sha256:f981cea63d08456b2c070e64b79cb62f951aa1305282974d4d5216e6e0178ae6", size = 14001379, upload-time = "2026-01-08T19:11:52.591Z" },
+ { url = "https://files.pythonhosted.org/packages/c4/1c/1dbe51782c0e1e9cfce1d1004752672d2d4629ea46945d19d731ad772b3b/ruff-0.14.11-py3-none-win_arm64.whl", hash = "sha256:649fb6c9edd7f751db276ef42df1f3df41c38d67d199570ae2a7bd6cbc3590f0", size = 12938644, upload-time = "2026-01-08T19:11:50.027Z" },
]
[[package]]
name = "simple-agent"
-version = "0.1.0"
-source = { virtual = "." }
+version = "0.2.0"
+source = { editable = "." }
dependencies = [
+ { name = "matplotlib" },
{ name = "openai" },
+ { name = "pandas" },
{ name = "python-dotenv" },
{ name = "requests" },
- { name = "rich" },
{ name = "termcolor" },
]
+[package.optional-dependencies]
+dev = [
+ { name = "black" },
+ { name = "mypy" },
+ { name = "pytest" },
+ { name = "pytest-cov" },
+ { name = "ruff" },
+]
+
[package.metadata]
requires-dist = [
- { name = "openai", specifier = ">=1.59.3" },
- { name = "python-dotenv", specifier = ">=1.0.1" },
- { name = "requests", specifier = ">=2.32.3" },
- { name = "rich", specifier = ">=13.9.4" },
- { name = "termcolor", specifier = ">=2.5.0" },
+ { name = "black", marker = "extra == 'dev'", specifier = ">=24.0.0" },
+ { name = "matplotlib", specifier = ">=3.8.0" },
+ { name = "mypy", marker = "extra == 'dev'", specifier = ">=1.8.0" },
+ { name = "openai", specifier = ">=1.59.0" },
+ { name = "pandas", specifier = ">=2.2.0" },
+ { name = "pytest", marker = "extra == 'dev'", specifier = ">=8.0.0" },
+ { name = "pytest-cov", marker = "extra == 'dev'", specifier = ">=4.1.0" },
+ { name = "python-dotenv", specifier = ">=1.0.0" },
+ { name = "requests", specifier = ">=2.31.0" },
+ { name = "ruff", marker = "extra == 'dev'", specifier = ">=0.2.0" },
+ { name = "termcolor", specifier = ">=2.4.0" },
+]
+provides-extras = ["dev"]
+
+[[package]]
+name = "six"
+version = "1.17.0"
+source = { registry = "https://pypi.org/simple" }
+sdist = { url = "https://files.pythonhosted.org/packages/94/e7/b2c673351809dca68a0e064b6af791aa332cf192da575fd474ed7d6f16a2/six-1.17.0.tar.gz", hash = "sha256:ff70335d468e7eb6ec65b95b99d3a2836546063f63acc5171de367e834932a81", size = 34031, upload-time = "2024-12-04T17:35:28.174Z" }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/b7/ce/149a00dd41f10bc29e5921b496af8b574d8413afcd5e30dfa0ed46c2cc5e/six-1.17.0-py2.py3-none-any.whl", hash = "sha256:4721f391ed90541fddacab5acf947aa0d3dc7d27b2e1e8eda2be8970586c3274", size = 11050, upload-time = "2024-12-04T17:35:26.475Z" },
]
[[package]]
name = "sniffio"
version = "1.3.1"
source = { registry = "https://pypi.org/simple" }
-sdist = { url = "https://files.pythonhosted.org/packages/a2/87/a6771e1546d97e7e041b6ae58d80074f81b7d5121207425c964ddf5cfdbd/sniffio-1.3.1.tar.gz", hash = "sha256:f4324edc670a0f49750a81b895f35c3adb843cca46f0530f79fc1babb23789dc", size = 20372 }
+sdist = { url = "https://files.pythonhosted.org/packages/a2/87/a6771e1546d97e7e041b6ae58d80074f81b7d5121207425c964ddf5cfdbd/sniffio-1.3.1.tar.gz", hash = "sha256:f4324edc670a0f49750a81b895f35c3adb843cca46f0530f79fc1babb23789dc", size = 20372, upload-time = "2024-02-25T23:20:04.057Z" }
wheels = [
- { url = "https://files.pythonhosted.org/packages/e9/44/75a9c9421471a6c4805dbf2356f7c181a29c1879239abab1ea2cc8f38b40/sniffio-1.3.1-py3-none-any.whl", hash = "sha256:2f6da418d1f1e0fddd844478f41680e794e6051915791a034ff65e5f100525a2", size = 10235 },
+ { url = "https://files.pythonhosted.org/packages/e9/44/75a9c9421471a6c4805dbf2356f7c181a29c1879239abab1ea2cc8f38b40/sniffio-1.3.1-py3-none-any.whl", hash = "sha256:2f6da418d1f1e0fddd844478f41680e794e6051915791a034ff65e5f100525a2", size = 10235, upload-time = "2024-02-25T23:20:01.196Z" },
]
[[package]]
name = "termcolor"
version = "2.5.0"
source = { registry = "https://pypi.org/simple" }
-sdist = { url = "https://files.pythonhosted.org/packages/37/72/88311445fd44c455c7d553e61f95412cf89054308a1aa2434ab835075fc5/termcolor-2.5.0.tar.gz", hash = "sha256:998d8d27da6d48442e8e1f016119076b690d962507531df4890fcd2db2ef8a6f", size = 13057 }
+sdist = { url = "https://files.pythonhosted.org/packages/37/72/88311445fd44c455c7d553e61f95412cf89054308a1aa2434ab835075fc5/termcolor-2.5.0.tar.gz", hash = "sha256:998d8d27da6d48442e8e1f016119076b690d962507531df4890fcd2db2ef8a6f", size = 13057, upload-time = "2024-10-06T19:50:04.115Z" }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/7f/be/df630c387a0a054815d60be6a97eb4e8f17385d5d6fe660e1c02750062b4/termcolor-2.5.0-py3-none-any.whl", hash = "sha256:37b17b5fc1e604945c2642c872a3764b5d547a48009871aea3edd3afa180afb8", size = 7755, upload-time = "2024-10-06T19:50:02.097Z" },
+]
+
+[[package]]
+name = "tomli"
+version = "2.3.0"
+source = { registry = "https://pypi.org/simple" }
+sdist = { url = "https://files.pythonhosted.org/packages/52/ed/3f73f72945444548f33eba9a87fc7a6e969915e7b1acc8260b30e1f76a2f/tomli-2.3.0.tar.gz", hash = "sha256:64be704a875d2a59753d80ee8a533c3fe183e3f06807ff7dc2232938ccb01549", size = 17392, upload-time = "2025-10-08T22:01:47.119Z" }
wheels = [
- { url = "https://files.pythonhosted.org/packages/7f/be/df630c387a0a054815d60be6a97eb4e8f17385d5d6fe660e1c02750062b4/termcolor-2.5.0-py3-none-any.whl", hash = "sha256:37b17b5fc1e604945c2642c872a3764b5d547a48009871aea3edd3afa180afb8", size = 7755 },
+ { url = "https://files.pythonhosted.org/packages/b3/2e/299f62b401438d5fe1624119c723f5d877acc86a4c2492da405626665f12/tomli-2.3.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:88bd15eb972f3664f5ed4b57c1634a97153b4bac4479dcb6a495f41921eb7f45", size = 153236, upload-time = "2025-10-08T22:01:00.137Z" },
+ { url = "https://files.pythonhosted.org/packages/86/7f/d8fffe6a7aefdb61bced88fcb5e280cfd71e08939da5894161bd71bea022/tomli-2.3.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:883b1c0d6398a6a9d29b508c331fa56adbcdff647f6ace4dfca0f50e90dfd0ba", size = 148084, upload-time = "2025-10-08T22:01:01.63Z" },
+ { url = "https://files.pythonhosted.org/packages/47/5c/24935fb6a2ee63e86d80e4d3b58b222dafaf438c416752c8b58537c8b89a/tomli-2.3.0-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:d1381caf13ab9f300e30dd8feadb3de072aeb86f1d34a8569453ff32a7dea4bf", size = 234832, upload-time = "2025-10-08T22:01:02.543Z" },
+ { url = "https://files.pythonhosted.org/packages/89/da/75dfd804fc11e6612846758a23f13271b76d577e299592b4371a4ca4cd09/tomli-2.3.0-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:a0e285d2649b78c0d9027570d4da3425bdb49830a6156121360b3f8511ea3441", size = 242052, upload-time = "2025-10-08T22:01:03.836Z" },
+ { url = "https://files.pythonhosted.org/packages/70/8c/f48ac899f7b3ca7eb13af73bacbc93aec37f9c954df3c08ad96991c8c373/tomli-2.3.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:0a154a9ae14bfcf5d8917a59b51ffd5a3ac1fd149b71b47a3a104ca4edcfa845", size = 239555, upload-time = "2025-10-08T22:01:04.834Z" },
+ { url = "https://files.pythonhosted.org/packages/ba/28/72f8afd73f1d0e7829bfc093f4cb98ce0a40ffc0cc997009ee1ed94ba705/tomli-2.3.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:74bf8464ff93e413514fefd2be591c3b0b23231a77f901db1eb30d6f712fc42c", size = 245128, upload-time = "2025-10-08T22:01:05.84Z" },
+ { url = "https://files.pythonhosted.org/packages/b6/eb/a7679c8ac85208706d27436e8d421dfa39d4c914dcf5fa8083a9305f58d9/tomli-2.3.0-cp311-cp311-win32.whl", hash = "sha256:00b5f5d95bbfc7d12f91ad8c593a1659b6387b43f054104cda404be6bda62456", size = 96445, upload-time = "2025-10-08T22:01:06.896Z" },
+ { url = "https://files.pythonhosted.org/packages/0a/fe/3d3420c4cb1ad9cb462fb52967080575f15898da97e21cb6f1361d505383/tomli-2.3.0-cp311-cp311-win_amd64.whl", hash = "sha256:4dc4ce8483a5d429ab602f111a93a6ab1ed425eae3122032db7e9acf449451be", size = 107165, upload-time = "2025-10-08T22:01:08.107Z" },
+ { url = "https://files.pythonhosted.org/packages/ff/b7/40f36368fcabc518bb11c8f06379a0fd631985046c038aca08c6d6a43c6e/tomli-2.3.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:d7d86942e56ded512a594786a5ba0a5e521d02529b3826e7761a05138341a2ac", size = 154891, upload-time = "2025-10-08T22:01:09.082Z" },
+ { url = "https://files.pythonhosted.org/packages/f9/3f/d9dd692199e3b3aab2e4e4dd948abd0f790d9ded8cd10cbaae276a898434/tomli-2.3.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:73ee0b47d4dad1c5e996e3cd33b8a76a50167ae5f96a2607cbe8cc773506ab22", size = 148796, upload-time = "2025-10-08T22:01:10.266Z" },
+ { url = "https://files.pythonhosted.org/packages/60/83/59bff4996c2cf9f9387a0f5a3394629c7efa5ef16142076a23a90f1955fa/tomli-2.3.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:792262b94d5d0a466afb5bc63c7daa9d75520110971ee269152083270998316f", size = 242121, upload-time = "2025-10-08T22:01:11.332Z" },
+ { url = "https://files.pythonhosted.org/packages/45/e5/7c5119ff39de8693d6baab6c0b6dcb556d192c165596e9fc231ea1052041/tomli-2.3.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:4f195fe57ecceac95a66a75ac24d9d5fbc98ef0962e09b2eddec5d39375aae52", size = 250070, upload-time = "2025-10-08T22:01:12.498Z" },
+ { url = "https://files.pythonhosted.org/packages/45/12/ad5126d3a278f27e6701abde51d342aa78d06e27ce2bb596a01f7709a5a2/tomli-2.3.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:e31d432427dcbf4d86958c184b9bfd1e96b5b71f8eb17e6d02531f434fd335b8", size = 245859, upload-time = "2025-10-08T22:01:13.551Z" },
+ { url = "https://files.pythonhosted.org/packages/fb/a1/4d6865da6a71c603cfe6ad0e6556c73c76548557a8d658f9e3b142df245f/tomli-2.3.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:7b0882799624980785240ab732537fcfc372601015c00f7fc367c55308c186f6", size = 250296, upload-time = "2025-10-08T22:01:14.614Z" },
+ { url = "https://files.pythonhosted.org/packages/a0/b7/a7a7042715d55c9ba6e8b196d65d2cb662578b4d8cd17d882d45322b0d78/tomli-2.3.0-cp312-cp312-win32.whl", hash = "sha256:ff72b71b5d10d22ecb084d345fc26f42b5143c5533db5e2eaba7d2d335358876", size = 97124, upload-time = "2025-10-08T22:01:15.629Z" },
+ { url = "https://files.pythonhosted.org/packages/06/1e/f22f100db15a68b520664eb3328fb0ae4e90530887928558112c8d1f4515/tomli-2.3.0-cp312-cp312-win_amd64.whl", hash = "sha256:1cb4ed918939151a03f33d4242ccd0aa5f11b3547d0cf30f7c74a408a5b99878", size = 107698, upload-time = "2025-10-08T22:01:16.51Z" },
+ { url = "https://files.pythonhosted.org/packages/89/48/06ee6eabe4fdd9ecd48bf488f4ac783844fd777f547b8d1b61c11939974e/tomli-2.3.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:5192f562738228945d7b13d4930baffda67b69425a7f0da96d360b0a3888136b", size = 154819, upload-time = "2025-10-08T22:01:17.964Z" },
+ { url = "https://files.pythonhosted.org/packages/f1/01/88793757d54d8937015c75dcdfb673c65471945f6be98e6a0410fba167ed/tomli-2.3.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:be71c93a63d738597996be9528f4abe628d1adf5e6eb11607bc8fe1a510b5dae", size = 148766, upload-time = "2025-10-08T22:01:18.959Z" },
+ { url = "https://files.pythonhosted.org/packages/42/17/5e2c956f0144b812e7e107f94f1cc54af734eb17b5191c0bbfb72de5e93e/tomli-2.3.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:c4665508bcbac83a31ff8ab08f424b665200c0e1e645d2bd9ab3d3e557b6185b", size = 240771, upload-time = "2025-10-08T22:01:20.106Z" },
+ { url = "https://files.pythonhosted.org/packages/d5/f4/0fbd014909748706c01d16824eadb0307115f9562a15cbb012cd9b3512c5/tomli-2.3.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:4021923f97266babc6ccab9f5068642a0095faa0a51a246a6a02fccbb3514eaf", size = 248586, upload-time = "2025-10-08T22:01:21.164Z" },
+ { url = "https://files.pythonhosted.org/packages/30/77/fed85e114bde5e81ecf9bc5da0cc69f2914b38f4708c80ae67d0c10180c5/tomli-2.3.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:a4ea38c40145a357d513bffad0ed869f13c1773716cf71ccaa83b0fa0cc4e42f", size = 244792, upload-time = "2025-10-08T22:01:22.417Z" },
+ { url = "https://files.pythonhosted.org/packages/55/92/afed3d497f7c186dc71e6ee6d4fcb0acfa5f7d0a1a2878f8beae379ae0cc/tomli-2.3.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:ad805ea85eda330dbad64c7ea7a4556259665bdf9d2672f5dccc740eb9d3ca05", size = 248909, upload-time = "2025-10-08T22:01:23.859Z" },
+ { url = "https://files.pythonhosted.org/packages/f8/84/ef50c51b5a9472e7265ce1ffc7f24cd4023d289e109f669bdb1553f6a7c2/tomli-2.3.0-cp313-cp313-win32.whl", hash = "sha256:97d5eec30149fd3294270e889b4234023f2c69747e555a27bd708828353ab606", size = 96946, upload-time = "2025-10-08T22:01:24.893Z" },
+ { url = "https://files.pythonhosted.org/packages/b2/b7/718cd1da0884f281f95ccfa3a6cc572d30053cba64603f79d431d3c9b61b/tomli-2.3.0-cp313-cp313-win_amd64.whl", hash = "sha256:0c95ca56fbe89e065c6ead5b593ee64b84a26fca063b5d71a1122bf26e533999", size = 107705, upload-time = "2025-10-08T22:01:26.153Z" },
+ { url = "https://files.pythonhosted.org/packages/19/94/aeafa14a52e16163008060506fcb6aa1949d13548d13752171a755c65611/tomli-2.3.0-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:cebc6fe843e0733ee827a282aca4999b596241195f43b4cc371d64fc6639da9e", size = 154244, upload-time = "2025-10-08T22:01:27.06Z" },
+ { url = "https://files.pythonhosted.org/packages/db/e4/1e58409aa78eefa47ccd19779fc6f36787edbe7d4cd330eeeedb33a4515b/tomli-2.3.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:4c2ef0244c75aba9355561272009d934953817c49f47d768070c3c94355c2aa3", size = 148637, upload-time = "2025-10-08T22:01:28.059Z" },
+ { url = "https://files.pythonhosted.org/packages/26/b6/d1eccb62f665e44359226811064596dd6a366ea1f985839c566cd61525ae/tomli-2.3.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:c22a8bf253bacc0cf11f35ad9808b6cb75ada2631c2d97c971122583b129afbc", size = 241925, upload-time = "2025-10-08T22:01:29.066Z" },
+ { url = "https://files.pythonhosted.org/packages/70/91/7cdab9a03e6d3d2bb11beae108da5bdc1c34bdeb06e21163482544ddcc90/tomli-2.3.0-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:0eea8cc5c5e9f89c9b90c4896a8deefc74f518db5927d0e0e8d4a80953d774d0", size = 249045, upload-time = "2025-10-08T22:01:31.98Z" },
+ { url = "https://files.pythonhosted.org/packages/15/1b/8c26874ed1f6e4f1fcfeb868db8a794cbe9f227299402db58cfcc858766c/tomli-2.3.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:b74a0e59ec5d15127acdabd75ea17726ac4c5178ae51b85bfe39c4f8a278e879", size = 245835, upload-time = "2025-10-08T22:01:32.989Z" },
+ { url = "https://files.pythonhosted.org/packages/fd/42/8e3c6a9a4b1a1360c1a2a39f0b972cef2cc9ebd56025168c4137192a9321/tomli-2.3.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:b5870b50c9db823c595983571d1296a6ff3e1b88f734a4c8f6fc6188397de005", size = 253109, upload-time = "2025-10-08T22:01:34.052Z" },
+ { url = "https://files.pythonhosted.org/packages/22/0c/b4da635000a71b5f80130937eeac12e686eefb376b8dee113b4a582bba42/tomli-2.3.0-cp314-cp314-win32.whl", hash = "sha256:feb0dacc61170ed7ab602d3d972a58f14ee3ee60494292d384649a3dc38ef463", size = 97930, upload-time = "2025-10-08T22:01:35.082Z" },
+ { url = "https://files.pythonhosted.org/packages/b9/74/cb1abc870a418ae99cd5c9547d6bce30701a954e0e721821df483ef7223c/tomli-2.3.0-cp314-cp314-win_amd64.whl", hash = "sha256:b273fcbd7fc64dc3600c098e39136522650c49bca95df2d11cf3b626422392c8", size = 107964, upload-time = "2025-10-08T22:01:36.057Z" },
+ { url = "https://files.pythonhosted.org/packages/54/78/5c46fff6432a712af9f792944f4fcd7067d8823157949f4e40c56b8b3c83/tomli-2.3.0-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:940d56ee0410fa17ee1f12b817b37a4d4e4dc4d27340863cc67236c74f582e77", size = 163065, upload-time = "2025-10-08T22:01:37.27Z" },
+ { url = "https://files.pythonhosted.org/packages/39/67/f85d9bd23182f45eca8939cd2bc7050e1f90c41f4a2ecbbd5963a1d1c486/tomli-2.3.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:f85209946d1fe94416debbb88d00eb92ce9cd5266775424ff81bc959e001acaf", size = 159088, upload-time = "2025-10-08T22:01:38.235Z" },
+ { url = "https://files.pythonhosted.org/packages/26/5a/4b546a0405b9cc0659b399f12b6adb750757baf04250b148d3c5059fc4eb/tomli-2.3.0-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:a56212bdcce682e56b0aaf79e869ba5d15a6163f88d5451cbde388d48b13f530", size = 268193, upload-time = "2025-10-08T22:01:39.712Z" },
+ { url = "https://files.pythonhosted.org/packages/42/4f/2c12a72ae22cf7b59a7fe75b3465b7aba40ea9145d026ba41cb382075b0e/tomli-2.3.0-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c5f3ffd1e098dfc032d4d3af5c0ac64f6d286d98bc148698356847b80fa4de1b", size = 275488, upload-time = "2025-10-08T22:01:40.773Z" },
+ { url = "https://files.pythonhosted.org/packages/92/04/a038d65dbe160c3aa5a624e93ad98111090f6804027d474ba9c37c8ae186/tomli-2.3.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:5e01decd096b1530d97d5d85cb4dff4af2d8347bd35686654a004f8dea20fc67", size = 272669, upload-time = "2025-10-08T22:01:41.824Z" },
+ { url = "https://files.pythonhosted.org/packages/be/2f/8b7c60a9d1612a7cbc39ffcca4f21a73bf368a80fc25bccf8253e2563267/tomli-2.3.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:8a35dd0e643bb2610f156cca8db95d213a90015c11fee76c946aa62b7ae7e02f", size = 279709, upload-time = "2025-10-08T22:01:43.177Z" },
+ { url = "https://files.pythonhosted.org/packages/7e/46/cc36c679f09f27ded940281c38607716c86cf8ba4a518d524e349c8b4874/tomli-2.3.0-cp314-cp314t-win32.whl", hash = "sha256:a1f7f282fe248311650081faafa5f4732bdbfef5d45fe3f2e702fbc6f2d496e0", size = 107563, upload-time = "2025-10-08T22:01:44.233Z" },
+ { url = "https://files.pythonhosted.org/packages/84/ff/426ca8683cf7b753614480484f6437f568fd2fda2edbdf57a2d3d8b27a0b/tomli-2.3.0-cp314-cp314t-win_amd64.whl", hash = "sha256:70a251f8d4ba2d9ac2542eecf008b3c8a9fc5c3f9f02c56a9d7952612be2fdba", size = 119756, upload-time = "2025-10-08T22:01:45.234Z" },
+ { url = "https://files.pythonhosted.org/packages/77/b8/0135fadc89e73be292b473cb820b4f5a08197779206b33191e801feeae40/tomli-2.3.0-py3-none-any.whl", hash = "sha256:e95b1af3c5b07d9e643909b5abbec77cd9f1217e6d0bca72b0234736b9fb1f1b", size = 14408, upload-time = "2025-10-08T22:01:46.04Z" },
]
[[package]]
@@ -312,25 +1343,34 @@ source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "colorama", marker = "sys_platform == 'win32'" },
]
-sdist = { url = "https://files.pythonhosted.org/packages/a8/4b/29b4ef32e036bb34e4ab51796dd745cdba7ed47ad142a9f4a1eb8e0c744d/tqdm-4.67.1.tar.gz", hash = "sha256:f8aef9c52c08c13a65f30ea34f4e5aac3fd1a34959879d7e59e63027286627f2", size = 169737 }
+sdist = { url = "https://files.pythonhosted.org/packages/a8/4b/29b4ef32e036bb34e4ab51796dd745cdba7ed47ad142a9f4a1eb8e0c744d/tqdm-4.67.1.tar.gz", hash = "sha256:f8aef9c52c08c13a65f30ea34f4e5aac3fd1a34959879d7e59e63027286627f2", size = 169737, upload-time = "2024-11-24T20:12:22.481Z" }
wheels = [
- { url = "https://files.pythonhosted.org/packages/d0/30/dc54f88dd4a2b5dc8a0279bdd7270e735851848b762aeb1c1184ed1f6b14/tqdm-4.67.1-py3-none-any.whl", hash = "sha256:26445eca388f82e72884e0d580d5464cd801a3ea01e63e5601bdff9ba6a48de2", size = 78540 },
+ { url = "https://files.pythonhosted.org/packages/d0/30/dc54f88dd4a2b5dc8a0279bdd7270e735851848b762aeb1c1184ed1f6b14/tqdm-4.67.1-py3-none-any.whl", hash = "sha256:26445eca388f82e72884e0d580d5464cd801a3ea01e63e5601bdff9ba6a48de2", size = 78540, upload-time = "2024-11-24T20:12:19.698Z" },
]
[[package]]
name = "typing-extensions"
version = "4.12.2"
source = { registry = "https://pypi.org/simple" }
-sdist = { url = "https://files.pythonhosted.org/packages/df/db/f35a00659bc03fec321ba8bce9420de607a1d37f8342eee1863174c69557/typing_extensions-4.12.2.tar.gz", hash = "sha256:1a7ead55c7e559dd4dee8856e3a88b41225abfe1ce8df57b7c13915fe121ffb8", size = 85321 }
+sdist = { url = "https://files.pythonhosted.org/packages/df/db/f35a00659bc03fec321ba8bce9420de607a1d37f8342eee1863174c69557/typing_extensions-4.12.2.tar.gz", hash = "sha256:1a7ead55c7e559dd4dee8856e3a88b41225abfe1ce8df57b7c13915fe121ffb8", size = 85321, upload-time = "2024-06-07T18:52:15.995Z" }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/26/9f/ad63fc0248c5379346306f8668cda6e2e2e9c95e01216d2b8ffd9ff037d0/typing_extensions-4.12.2-py3-none-any.whl", hash = "sha256:04e5ca0351e0f3f85c6853954072df659d0d13fac324d0072316b67d7794700d", size = 37438, upload-time = "2024-06-07T18:52:13.582Z" },
+]
+
+[[package]]
+name = "tzdata"
+version = "2025.3"
+source = { registry = "https://pypi.org/simple" }
+sdist = { url = "https://files.pythonhosted.org/packages/5e/a7/c202b344c5ca7daf398f3b8a477eeb205cf3b6f32e7ec3a6bac0629ca975/tzdata-2025.3.tar.gz", hash = "sha256:de39c2ca5dc7b0344f2eba86f49d614019d29f060fc4ebc8a417896a620b56a7", size = 196772, upload-time = "2025-12-13T17:45:35.667Z" }
wheels = [
- { url = "https://files.pythonhosted.org/packages/26/9f/ad63fc0248c5379346306f8668cda6e2e2e9c95e01216d2b8ffd9ff037d0/typing_extensions-4.12.2-py3-none-any.whl", hash = "sha256:04e5ca0351e0f3f85c6853954072df659d0d13fac324d0072316b67d7794700d", size = 37438 },
+ { url = "https://files.pythonhosted.org/packages/c7/b0/003792df09decd6849a5e39c28b513c06e84436a54440380862b5aeff25d/tzdata-2025.3-py2.py3-none-any.whl", hash = "sha256:06a47e5700f3081aab02b2e513160914ff0694bce9947d6b76ebd6bf57cfc5d1", size = 348521, upload-time = "2025-12-13T17:45:33.889Z" },
]
[[package]]
name = "urllib3"
version = "2.3.0"
source = { registry = "https://pypi.org/simple" }
-sdist = { url = "https://files.pythonhosted.org/packages/aa/63/e53da845320b757bf29ef6a9062f5c669fe997973f966045cb019c3f4b66/urllib3-2.3.0.tar.gz", hash = "sha256:f8c5449b3cf0861679ce7e0503c7b44b5ec981bec0d1d3795a07f1ba96f0204d", size = 307268 }
+sdist = { url = "https://files.pythonhosted.org/packages/aa/63/e53da845320b757bf29ef6a9062f5c669fe997973f966045cb019c3f4b66/urllib3-2.3.0.tar.gz", hash = "sha256:f8c5449b3cf0861679ce7e0503c7b44b5ec981bec0d1d3795a07f1ba96f0204d", size = 307268, upload-time = "2024-12-22T07:47:30.032Z" }
wheels = [
- { url = "https://files.pythonhosted.org/packages/c8/19/4ec628951a74043532ca2cf5d97b7b14863931476d117c471e8e2b1eb39f/urllib3-2.3.0-py3-none-any.whl", hash = "sha256:1cee9ad369867bfdbbb48b7dd50374c0967a0bb7710050facf0dd6911440e3df", size = 128369 },
+ { url = "https://files.pythonhosted.org/packages/c8/19/4ec628951a74043532ca2cf5d97b7b14863931476d117c471e8e2b1eb39f/urllib3-2.3.0-py3-none-any.whl", hash = "sha256:1cee9ad369867bfdbbb48b7dd50374c0967a0bb7710050facf0dd6911440e3df", size = 128369, upload-time = "2024-12-22T07:47:28.074Z" },
]