diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml new file mode 100644 index 0000000..bec0041 --- /dev/null +++ b/.github/workflows/build.yml @@ -0,0 +1,31 @@ +name: build + +on: + push: + branches: main + pull_request: + +jobs: + build: + runs-on: ubuntu-latest + timeout-minutes: 30 + + steps: + - run: | + echo "github.event_name=${{ github.event_name }}" + echo "github.event.workflow_run.conclusion=${{ github.event.workflow_run.conclusion }}" + - name: Checkout repository + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd + + - name: Install build dependencies + run: | + pip install -U pip build + + - name: Build package artifacts and install wheel + run: | + python -m build + pip install dist/isaricanalytics*.whl + + - name: Test wheel import + run: | + python -c "import isaricanalytics; print(isaricanalytics.__version__)" diff --git a/.github/workflows/pre-commit.yml b/.github/workflows/pre-commit.yml index c719208..6de71ec 100644 --- a/.github/workflows/pre-commit.yml +++ b/.github/workflows/pre-commit.yml @@ -2,19 +2,20 @@ name: pre-commit on: push: - branches: [main] + branches: main pull_request: jobs: pre-commit: runs-on: ubuntu-latest + timeout-minutes: 10 steps: - name: Checkout repository - uses: actions/checkout@v4 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd - name: Set up Python - uses: actions/setup-python@v5 + uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 with: python-version: "3.11" diff --git a/.github/workflows/test-python-versions-coverage.yml b/.github/workflows/test-python-versions-coverage.yml deleted file mode 100644 index 282b79d..0000000 --- a/.github/workflows/test-python-versions-coverage.yml +++ /dev/null @@ -1,53 +0,0 @@ -name: Tests (python versions) - -on: - push: - branches: [main, dev] - pull_request: - branches: [main, dev] - workflow_dispatch: - -jobs: - - test: - name: Python tests and coverage - runs-on: ubuntu-latest - permissions: - contents: read - pull-requests: write - - strategy: - fail-fast: false - matrix: - python-version: ["3.11"] - # Note: Latest version is tested by os tests - - steps: - - uses: actions/checkout@v6 - - - name: Set up Python ${{ matrix.python-version }} - uses: actions/setup-python@v6 - with: - python-version: ${{ matrix.python-version }} - - - name: Run tests - run: | - pip install pdm &&\ - pdm install -v -dG "test" --no-editable --no-self &&\ - pdm run -v python -m pytest --code-highlight=yes --color=yes --verbosity=3 -p pytest_cov --cov=isaricanalytics --cov-report=term-missing --cov-report=xml - - - name: Upload coverage XML - uses: actions/upload-artifact@v4 - with: - name: coverage-xml - path: coverage.xml - if-no-files-found: error - - - name: Upload coverage report to Codecov - continue-on-error: true - uses: codecov/codecov-action@v5 - with: - files: ./coverage.xml - token: ${{ secrets.CODECOV_TOKEN }} - fail_ci_if_error: false - verbose: true diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml new file mode 100644 index 0000000..22c60b2 --- /dev/null +++ b/.github/workflows/test.yml @@ -0,0 +1,59 @@ +name: Tests and Coverage + +on: + push: + branches: + - main + pull_request: + +jobs: + unit-test: + runs-on: ubuntu-latest + timeout-minutes: 30 + + steps: + - run: | + echo "github.event_name=${{ github.event_name }}" + echo "github.event.workflow_run.conclusion=${{ github.event.workflow_run.conclusion }}" + - name: Checkout repository + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd + + - name: Set up Python + uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 + with: + python-version: "3.11" + + - name: Install project and unit test dependencies + run: | + python -m pip install --upgrade pip + pip install -e ".[test]" + + - name: Run pytest with coverage + env: + PYTEST_DISABLE_PLUGIN_AUTOLOAD: "1" + run: | + python -m pytest \ + --code-highlight=yes \ + --color=yes \ + --verbosity=3 \ + -p pytest_cov \ + --cov=isaricanalytics \ + --cov-report=term-missing \ + --cov-report=xml \ + --cov-report=html + + - name: Upload coverage.xml artifact + uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f + with: + name: coverage-xml + path: coverage.xml + if-no-files-found: error + + - name: Upload coverage report to Codecov (best effort) + continue-on-error: true + uses: codecov/codecov-action@57e3a136b779b570ffcdbf80b3bdc90e7fab3de2 + with: + files: ./coverage.xml + token: ${{ secrets.CODECOV_TOKEN }} + fail_ci_if_error: false + verbose: true diff --git a/.readthedocs.yaml b/.readthedocs.yaml index 5b6161f..81805ec 100644 --- a/.readthedocs.yaml +++ b/.readthedocs.yaml @@ -10,7 +10,6 @@ build: os: ubuntu-lts-latest tools: python: "3.11" - # You can also specify other tool versions: # nodejs: "20" # rust: "1.70" diff --git a/CITATION.cff b/CITATION.cff new file mode 100644 index 0000000..622a5bf --- /dev/null +++ b/CITATION.cff @@ -0,0 +1,40 @@ +cff-version: 1.2.0 +title: IsaricAnalytics +message: Data analysis toolkit to support fast analysis of clinical data during emerging infectious disease outbreaks. +type: software +authors: + - name-particle: Tom + family-names: Edinburgh + email: tom.edinburgh@ndm.ox.ac.uk + orcid: 0000-0002-3599-7133 + - name-particle: Esteban + family-names: Garcia-Gallo + email: esteban.garcia@ndm.ox.ac.uk + orcid: 0000-0002-8030-9985 + - name-particle: Igor + family-names: Peres + email: igor.peres@puc-rio.br + orcid: + - name-particle: Tomoe + family-names: Gusberti + email: tomoegusberti@gmail.com + orcid: + - name-particle: Luiz + family-names: Raffaini + email: lemraffaini@gmail.com + orcid: +repository-code: 'https://github.com/ISARICResearch/IsaricAnalytics' +url: 'https://github.com/ISARICResearch/IsaricAnalytics' +abstract: Data analysis toolkit to support fast analysis of clinical data during emerging infectious disease outbreaks. +keywords: + - isaric + - infectious disease + - pandemic + - disease outbreak + - clinical epidemiology + - disease outbreak response + - data analysis + - data analytics +license: MIT +version: 0.2.0 +date-released: diff --git a/README.md b/README.md index 79ac7f5..2724097 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ [![CodeQL](https://github.com/ISARICResearch/IsaricAnalytics/actions/workflows/github-code-scanning/codeql/badge.svg)](https://github.com/ISARICResearch/IsaricAnalytics/actions/workflows/github-code-scanning/codeql) [![pre-commit](https://github.com/ISARICResearch/IsaricAnalytics/actions/workflows/pre-commit.yml/badge.svg)](https://github.com/ISARICResearch/IsaricAnalytics/actions/workflows/pre-commit.yml) -[![Tests (python versions)](https://github.com/ISARICResearch/IsaricAnalytics/actions/workflows/test-python-versions-coverage.yml/badge.svg)](https://github.com/ISARICResearch/IsaricAnalytics/actions/workflows/test-python-versions-coverage.yml) +[![Tests (python versions)](https://github.com/ISARICResearch/IsaricAnalytics/actions/workflows/test.yml/badge.svg)](https://github.com/ISARICResearch/IsaricAnalytics/actions/workflows/test.yml) [![codecov](https://codecov.io/gh/ISARICResearch/IsaricAnalytics/graph/badge.svg?token=Q0A84OK6E5)](https://codecov.io/gh/ISARICResearch/IsaricAnalytics) [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT) @@ -22,3 +22,7 @@ characteristics that allow some automation during research analyses and the re-u elements of analysis pipelines to similar contexts. This package is designed to support Reusable Analytical Pipelines for Infectious Diseases (RAPIDs), which is based on the concept of [Reproducible Analytical Pipelines](https://analysisfunction.civilservice.gov.uk/support/reproducible-analytical-pipelines/). + +## Documentation + +Project documentation is available at https://isaricanalytics.readthedocs.io/en/latest. It is built with [Sphinx](https://www.sphinx-doc.org/en/) from content and configuration defined in the [`docs`](https://github.com/ISARICResearch/VERTEX/tree/main/docs) subfolder. diff --git a/docs/_static/css/custom.css b/docs/_static/css/custom.css new file mode 100644 index 0000000..b6b14a8 --- /dev/null +++ b/docs/_static/css/custom.css @@ -0,0 +1,3 @@ +.theme-toggle-container { + display: none; +} diff --git a/docs/_static/isaric-logo.png b/docs/_static/isaric-logo.png new file mode 100644 index 0000000..c5e8373 Binary files /dev/null and b/docs/_static/isaric-logo.png differ diff --git a/docs/_static/osi-badge-light.svg b/docs/_static/osi-badge-light.svg new file mode 100644 index 0000000..06969ce --- /dev/null +++ b/docs/_static/osi-badge-light.svg @@ -0,0 +1,142 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/docs/conf.py b/docs/conf.py index 57bfca4..8181390 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -10,6 +10,12 @@ from datetime import datetime # -- 3rd party libraries -- +from docutils import nodes +from sphinx.addnodes import pending_xref +from sphinx.application import Sphinx +from sphinx.environment import BuildEnvironment +from sphinx.ext.intersphinx import missing_reference + # -- Internal libraries -- import isaricanalytics from isaricanalytics import __version__ @@ -102,9 +108,9 @@ # https://www.sphinx-doc.org/en/master/usage/extensions/autodoc.html#confval-autodoc_default_options autodoc_default_options = { "exclude-members": "", - "member-order": "bysource", + "member-order": "alphabetical", "private-members": False, - "special-members": "__init__,__new__", + "special-members": "", } # Sphinx autodoc autosummary settings @@ -124,6 +130,7 @@ #'dash': ('https://dash.plotly.com/', None), "numpy": ("https://numpy.org/doc/stable/", None), "pandas": ("https://pandas.pydata.org/pandas-docs/stable/", None), + "plotly": ("https://plotly.com/python-api-reference/", None), "Python": ("https://docs.python.org/3", None), "scikit-learn": ("https://scikit-learn.org/stable/", None), "scipy": ("https://docs.scipy.org/doc/scipy/", None), @@ -131,6 +138,34 @@ "statsmodels": ("https://www.statsmodels.org/stable", None), } + +# A custom solution from: +# +# https://stackoverflow.com/questions/73528299/link-to-plotly-graph-objects-figure-with-intersphinx +# +# to handle Intersphinx problems with the Plotly domain. +def fix_reference( + app: Sphinx, env: BuildEnvironment, node: pending_xref, contnode: nodes.TextElement +) -> nodes.reference | None: + """ + Fix some intersphinx references that are broken. + """ + if node["refdomain"] == "py": + # strange imports in plotly require a hardcoded redirect + if node["reftarget"] == "plotly.graph_objs._figure.Figure": + node["reftarget"] = "plotly.graph_objects.Figure" + return missing_reference(app, env, node, contnode) + + return None + + +def setup(app: Sphinx) -> None: + """ + Force sphinx to fix additional things on setup. + """ + app.connect("missing-reference", fix_reference) + + # Static template paths templates_path = ["_templates"] @@ -150,7 +185,7 @@ ] # The name of the Pygments (syntax highlighting) style to use. -pygments_style = "sphinx" +# pygments_style = "sphinx" # A list of prefixes that are ignored when creating the module index. # (new in Sphinx 0.6) @@ -193,20 +228,87 @@ # HTML theme options html_theme = "furo" -html_theme_options = {} +html_theme_options = { + # Since Furo doesn't allow us to disable dark mode, we make dark mode + # equivalent to light mode by overriding all colors back to their light value. + # See: https://github.com/pradyunsg/furo/issues/28 + "dark_css_variables": { + # Taken from: https://github.com/pradyunsg/furo/blob/c682d5d3502f3fa713c909eebbf9f3afa0f469d9/src/furo/assets/styles/variables/_colors.scss + "color-problematic": "#b30000", + # Base Colors + "color-foreground-primary": "black", # for main text and headings + "color-foreground-secondary": "#5a5c63", # for secondary text + "color-foreground-muted": "#646776", # for muted text + "color-foreground-border": "#878787", # for content borders + "color-background-primary": "white", # for content + "color-background-secondary": "#f8f9fb", # for navigation + ToC + "color-background-hover": "#efeff4ff", # for navigation-item hover + "color-background-hover--transparent": "#efeff400", + "color-background-border": "#eeebee", # for UI borders + "color-background-item": "#ccc", # for "background" items (eg: copybutton) + # Announcements + "color-announcement-background": "#000000dd", + "color-announcement-text": "#eeebee", + # Brand colors + "color-brand-primary": "#2962ff", + "color-brand-content": "#2a5adf", + # Highlighted text (search) + "color-highlighted-background": "#ddeeff", + # GUI Labels + "color-guilabel-background": "#ddeeff80", + "color-guilabel-border": "#bedaf580", + # API documentation + "color-api-keyword": "var(--color-foreground-secondary)", + "color-highlight-on-target": "#ffffcc", + # Admonitions + "color-admonition-background": "transparent", + # Cards + "color-card-border": "var(--color-background-secondary)", + "color-card-background": "transparent", + "color-card-marginals-background": "var(--color-background-hover)", + # Code blocks + "color-code-foreground": "black", + "color-code-background": "#f8f9fb", + }, + "footer_icons": [ + { + "name": "ISARICAnalytics@GitHub", + "url": "https://github.com/ISARICResearch/ISARICAnalytics", + "html": """ + + + + """, # noqa : E501 + "class": "", + }, + ], +} + +# Override the default sidebar listing by commenting out the ethical ads sidebar. +html_sidebars = { + "**": [ + "sidebar/scroll-start.html", + "sidebar/brand.html", + "sidebar/search.html", + "sidebar/navigation.html", + # "sidebar/ethical-ads.html", + "sidebar/scroll-end.html", + ] +} -# html_logo = '_static/logo.png' +# Force pygments style in dark mode back to the light variant +pygments_dark_style = "tango" + +html_logo = "_static/isaric-logo.png" # Relative path (from the ``docs`` folder) to the static files folder - so # ``_static`` should be one level below ``docs``. html_static_path = ["_static"] -# Custom CSS file(s) - currently source the Font Awesome CSS classes to support -# Font Awesome icons. for more information see: -# -# https://sphinx-design.readthedocs.io/en/latest/badges_buttons.html#fontawesome-icons -# -# html_css_files = [] +# Custom CSS file(s) +html_css_files = [ + "css/custom.css", +] # Timestamp format for the last page updated time html_last_updated_fmt = "%b %d, %Y" diff --git a/docs/index.rst b/docs/index.rst index fdcea06..f51a96e 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -1,16 +1,55 @@ -.. isaricanalytics documentation master file, created by - sphinx-quickstart on Wed Apr 8 09:51:09 2026. - You can adapt this file completely to your liking, but it should at least - contain the root `toctree` directive. +================ +ISARIC Analytics +================ -isaricanalytics documentation -============================= +The `ISARIC Analytics `_ library (:code:`isaricanalytics`) is for users requiring or interested in: -Add your content using ``reStructuredText`` syntax. See the -`reStructuredText `_ -documentation for details. +- REDCap data extraction +- ISARIC data analytics +- ISARIC data visualisation +ISARICAnalytics is licensed under the open source compliant `MIT license `_. + +.. image:: _static/osi-badge-light.svg + :target: https://opensource.org/license/mit + :height: 200px + :width: 200px + +Installation +------------ + +Install with :program:`pip` directly from GitHub using: + +.. code:: shell + + pip install -U git+https://github.com/ISARICResearch/ISARICAnalytics + +This will install the default ``main`` branch of the repo, including all package dependencies (and sub-dependencies) - if you want a specific branch, tag or commit SHA use + +.. code:: shell + + pip install -U git+https://github.com/ISARICResearch/ISARICAnalytics@ + +The minimum required Python version is 3.11. + +Documentation +------------- + +The documentation is currently limited to an API reference for all the core public libraries, but user tutorials, a visualisation gallery and additional documentation will be added in the future. .. toctree:: - :maxdepth: 2 + :maxdepth: 1 :caption: Contents: + + sources/api-reference + sources/redcap-data + sources/analytics + sources/visualisation + sources/contributing + +Indices and tables +================== + +* :ref:`genindex` +* :ref:`modindex` +* :ref:`search` diff --git a/docs/sources/analytics.rst b/docs/sources/analytics.rst new file mode 100644 index 0000000..76615bb --- /dev/null +++ b/docs/sources/analytics.rst @@ -0,0 +1,9 @@ +========= +Analytics +========= + +A guide to ISARIC data analytics. + +.. todo:: + + TODO diff --git a/docs/sources/api-reference.rst b/docs/sources/api-reference.rst new file mode 100644 index 0000000..a7eac73 --- /dev/null +++ b/docs/sources/api-reference.rst @@ -0,0 +1,15 @@ +============= +API Reference +============= + +``isaricanalytics`` API reference. + +.. toctree:: + :maxdepth: 1 + :name: api_reference_toc + :caption: Contents: + + isaricanalytics/redcap_data + isaricanalytics/analytics + isaricanalytics/visualisation + isaricanalytics/utils diff --git a/docs/sources/contributing.rst b/docs/sources/contributing.rst new file mode 100644 index 0000000..135d38f --- /dev/null +++ b/docs/sources/contributing.rst @@ -0,0 +1,9 @@ +============ +Contributing +============ + +Guide for developers and contributors. + +.. todo:: + + TODO diff --git a/docs/sources/isaricanalytics/analytics.rst b/docs/sources/isaricanalytics/analytics.rst new file mode 100644 index 0000000..64f152d --- /dev/null +++ b/docs/sources/isaricanalytics/analytics.rst @@ -0,0 +1,7 @@ +============================= +``isaricanalytics.analytics`` +============================= + +.. automodule:: isaricanalytics.analytics + :members: + :special-members: diff --git a/docs/sources/isaricanalytics/redcap_data.rst b/docs/sources/isaricanalytics/redcap_data.rst new file mode 100644 index 0000000..ed2f066 --- /dev/null +++ b/docs/sources/isaricanalytics/redcap_data.rst @@ -0,0 +1,7 @@ +=============================== +``isaricanalytics.redcap_data`` +=============================== + +.. automodule:: isaricanalytics.redcap_data + :members: + :special-members: diff --git a/docs/sources/isaricanalytics/utils.rst b/docs/sources/isaricanalytics/utils.rst new file mode 100644 index 0000000..9bbf295 --- /dev/null +++ b/docs/sources/isaricanalytics/utils.rst @@ -0,0 +1,7 @@ +========================= +``isaricanalytics.utils`` +========================= + +.. automodule:: isaricanalytics.utils + :members: + :special-members: diff --git a/docs/sources/isaricanalytics/visualisation.rst b/docs/sources/isaricanalytics/visualisation.rst new file mode 100644 index 0000000..56b1557 --- /dev/null +++ b/docs/sources/isaricanalytics/visualisation.rst @@ -0,0 +1,7 @@ +================================= +``isaricanalytics.visualisation`` +================================= + +.. automodule:: isaricanalytics.visualisation + :members: + :special-members: diff --git a/docs/sources/redcap-data.rst b/docs/sources/redcap-data.rst new file mode 100644 index 0000000..f68b301 --- /dev/null +++ b/docs/sources/redcap-data.rst @@ -0,0 +1,9 @@ +=========== +REDCap Data +=========== + +A guide to REDCap data extraction. + +.. todo:: + + TODO diff --git a/docs/sources/visualisation.rst b/docs/sources/visualisation.rst new file mode 100644 index 0000000..2ca45fa --- /dev/null +++ b/docs/sources/visualisation.rst @@ -0,0 +1,9 @@ +============= +Visualisation +============= + +A figure/plot allery and user guides for visualising ISARIC data. + +.. todo:: + + TODO diff --git a/isaricanalytics/__init__.py b/isaricanalytics/__init__.py index 3dc1f76..d3ec452 100644 --- a/isaricanalytics/__init__.py +++ b/isaricanalytics/__init__.py @@ -1 +1 @@ -__version__ = "0.1.0" +__version__ = "0.2.0" diff --git a/isaricanalytics/IsaricAnalytics.py b/isaricanalytics/analytics.py similarity index 56% rename from isaricanalytics/IsaricAnalytics.py rename to isaricanalytics/analytics.py index 4c32974..68841e3 100644 --- a/isaricanalytics/IsaricAnalytics.py +++ b/isaricanalytics/analytics.py @@ -1,7 +1,58 @@ +from __future__ import annotations + +__all__ = [ + "convert_categorical_to_onehot", + "convert_onehot_to_categorical", + "create_grouped_results", + "descriptive_comparison_table", + "descriptive_table", + "execute_cox_model", + "execute_glm_regression", + "execute_glmm_regression", + "execute_kaplan_meier", + "extend_dictionary", + "format_descriptive_table_variables", + "format_pvalue", + "format_variables", + "from_timeA_to_timeB", + "get_chi2_pvalue", + "get_counts", + "get_descriptive_data", + "get_fisher_exact_pvalue", + "get_mean_and_stdev", + "get_median_interquartile_range", + "get_modelling_data", + "get_n_percent_value", + "get_parameter_ranking", + "get_proportions", + "get_pyramid_data", + "get_upset_counts_intersections", + "get_variables_by_section_and_type", + "impute_miss_val", + "lasso_var_sel_binary", + "mannwhitneyu", + "mean_std_str", + "median_iqr_str", + "n_percent_str", + "norm", + "regression_summary_table", + "remove_single_binary_outcome_predictors", + "rmv_high_corr", + "rmv_low_var", + "trim_field_label", + "variance_influence_factor_backwards_elimination", +] + + +# -- IMPORTS -- + +# -- Standard libraries -- +import typing import warnings +# -- 3rd party libraries -- import numpy as np -import pandas as pd +import pandas import statsmodels.api as sm import statsmodels.formula.api as smf from lifelines import CoxPHFitter, KaplanMeierFitter @@ -14,6 +65,12 @@ from statsmodels.genmod.bayes_mixed_glm import BinomialBayesMixedGLM from statsmodels.stats.outliers_influence import variance_inflation_factor +# -- Internal libraries -- + + +pd = pandas # An alias to allow Pandas code refs to work independently +# of Pandas Intersphinx refs in type hinting and docstrings + ############################################ ############################################ # General preprocessing @@ -21,32 +78,46 @@ ############################################ -def extend_dictionary(dictionary, new_variable_dict, data, sep="___"): - """Add new custom variables to the VERTEX dictionary. - - Args: - dictionary (pd.DataFrame): - VERTEX dictionary containing columns 'field_name', 'form_name', - 'field_type', 'field_label', 'parent', 'branching_logic'. - new_variable_dict (dict): - A dict with the same keys as the dictionary columns, the values for - each item can be a string or a list. - data (pd.DataFrame): - pandas dataframe containing the data for the project. The columns - of this dataframe must include the variables in - new_variable_dict['field_type']. - sep (str): separator for creating new one-hot-encoded variable names. - - Returns: - dictionary (pd.DataFrame): - VERTEX dictionary containing the original variables, plus the new - variables and any one-hot-encoded variables derived from this.""" +def extend_dictionary( + dictionary: pandas.DataFrame, + new_variable_dict: dict[str, typing.Any], + data: pandas.DataFrame, + sep: str = "___", +) -> pandas.DataFrame: + """:py:class:`pandas.DataFrame` : Returns the VERTEX dictionary with new custom variables added. + + Parameters + ---------- + dictionary : pandas.DataFrame + VERTEX dictionary containing columns ``"field_name"``, ``"form_name"``, + ``"field_type"``, ``"field_label"``, ``"parent"``, ``"branching_logic"``. + + new_variable_dict : dict + A dict with the same keys as the dictionary columns, the values for + each item can be a string or a list. + + data : pandas.DataFrame + Pandas dataframe containing the data for the project. The columns of + this dataframe must include the variables in + ``new_variable_dict["field_type"]``. + + sep : str + Separator for creating new one-hot-encoded variable names. + + Returns + ------- + pandas.DataFrame + VERTEX dictionary containing the original variables, plus the new + variables and any one-hot-encoded variables derived from this. + """ # noqa : E501 # Convert dict values to list if all are strings (otherwise a pandas error) if all(isinstance(v, str) for v in new_variable_dict.values()): new_variable_dict = {k: [v] for k, v in new_variable_dict.items()} + new_dictionary = pd.DataFrame.from_dict(new_variable_dict) new_dictionary["index"] = np.nan dictionary = dictionary.reset_index(drop=False) + for ind in new_dictionary.index: parent = new_dictionary.loc[ind, "parent"] if parent not in new_dictionary["field_name"].values: @@ -72,6 +143,7 @@ def extend_dictionary(dictionary, new_variable_dict, data, sep="___"): ) # new_ind = new_ind + 0.1 new_dictionary.loc[ind, "index"] = new_ind + categorical_ind = new_dictionary["field_type"].isin(["categorical"]) new_dictionary_list = [new_dictionary] ind_list = [ @@ -79,6 +151,7 @@ def extend_dictionary(dictionary, new_variable_dict, data, sep="___"): for ind in categorical_ind.loc[categorical_ind].index if new_dictionary.loc[ind, "field_name"] in data.columns ] + for ind in ind_list: variable = new_dictionary.loc[ind, "field_name"] options = data[variable].drop_duplicates().sort_values().dropna() @@ -103,19 +176,21 @@ def extend_dictionary(dictionary, new_variable_dict, data, sep="___"): len(options), ) new_dictionary_list += [add_options] + dictionary = pd.concat([dictionary] + new_dictionary_list, axis=0) dictionary = dictionary.sort_values(by="index").drop(columns="index") dictionary = dictionary.reset_index(drop=True) + return dictionary def get_variables_by_section_and_type( - df, - dictionary, - required_variables=None, - include_sections=["demog"], - include_types=["binary", "categorical", "numeric"], - exclude_suffix=[ + data: pandas.DataFrame, + dictionary: pandas.DataFrame, + required_variables: typing.Iterable[str] | None = None, + include_sections: typing.Iterable[str] = ["demog"], + include_types: typing.Iterable[str] = ["binary", "categorical", "numeric"], + exclude_suffixes: typing.Iterable[str] = [ "_units", "addi", "otherl2", @@ -124,12 +199,43 @@ def get_variables_by_section_and_type( "_unlisted", "otherl3", ], - include_subjid=False, -): - """ - Get all variables in the dataframe from specified sections and types, - plus any required variables. - """ + include_subjid: bool = False, +) -> list[str]: + """:py:class:`list` : Returns a list of all variables in the dataframe from specified sections and types, plus any required variables. + + Parameters + ---------- + data : pandas.DataFrame + Incoming data. + + dictionary : pandas.DataFrame + Data dictionary. + + required_variables : typing.Iterable, default=None + Optional iterable of required variable names, defaults to ``None``. + + include_sections : typing.Iterable, default=["demog"] + Optional iterable of names of sections to include, defaults to + ``["demog"]``. + + include_types : typing.Iterable, default=["binary", "categorical", "numeric"] + Optional iterable of variable type names, defaults to + ``["binary", "categorical", "numeric"]``. + + exclude_suffixes : typing.Iterable, default=``["_units", "addi", "otherl2", "item", "_oth", "_unlisted", "otherl3"]`` + Optional iterable of suffixes to exclude, defaults to + ``["_units", "addi", "otherl2", "item", "_oth", "_unlisted", "otherl3"]``. + + include_subjid : bool, default=False + Optional boolean to indicate whether to include subject ID, defaults + to ``False``. + + Returns + ------- + list + A list of all variables in the dataframe from specified sections and + types, plus any required variables. + """ # noqa : E501 if "section" in dictionary.columns: # TODO: this should always be True in future include_ind = dictionary["section"].isin(include_sections) else: @@ -141,7 +247,7 @@ def get_variables_by_section_and_type( # lambda x: x.endswith(tuple('___' + x for x in exclude_suffix))) == 0) include_ind &= ( dictionary["field_name"].apply( - lambda x: x.endswith(tuple(x for x in exclude_suffix)) + lambda x: x.endswith(tuple(x for x in exclude_suffixes)) ) == 0 ) @@ -150,28 +256,63 @@ def get_variables_by_section_and_type( if include_subjid: include_ind |= dictionary["field_name"] == "subjid" include_variables = dictionary.loc[include_ind, "field_name"].tolist() - include_variables = [col for col in include_variables if col in df.columns] - return include_variables + return [col for col in include_variables if col in data.columns] -def convert_categorical_to_onehot( - df, dictionary, categorical_columns, sep="___", missing_val="nan", drop_first=False -): - """Convert categorical variables into onehot-encoded variables.""" - categorical_columns = [col for col in df.columns if col in categorical_columns] - df.loc[:, categorical_columns] = df[categorical_columns].fillna(missing_val) - df = pd.get_dummies(df, columns=categorical_columns, prefix_sep=sep) +def convert_categorical_to_onehot( + data: pandas.DataFrame, + dictionary: pandas.DataFrame, + categorical_columns: typing.Iterable[str], + sep: str = "___", + missing_val: str = "nan", + drop_first: bool = False, +) -> pandas.DataFrame: + """:py:class:`pandas.DataFrame` : Returns the given dataframe with categorical variable columns converted to onehot-encoded variable columns. + + Parameters + ---------- + data : pandas.DataFrame + The incoming data. + + dictionary : pandas.DataFrame + The data dictionary. + + categorical_columns : typing.Iterable + An iterable of categorical column names. + + sep : str, default="___" + Field-value separator, defaults to ``"___"`` + + missing_val : str, default="nan" + Optional value with which to replace missing values, defaults to + ``"nan"``. + + drop_first : bool, default=False + Optional boolean to indicate how to drop categorical columns [?], + defaults to ``False``. + + Returns + ------- + pandas.DataFrame + The original dataframe with the categorical -> one-hot-encoded variable + columns. + """ # noqa : E501 + categorical_columns = [col for col in data.columns if col in categorical_columns] + + data.loc[:, categorical_columns] = data[categorical_columns].fillna(missing_val) + data = pd.get_dummies(data, columns=categorical_columns, prefix_sep=sep) for categorical_column in categorical_columns: onehot_columns = [ - var for var in df.columns if var.split(sep)[0] == categorical_column + var for var in data.columns if var.split(sep)[0] == categorical_column ] - df[onehot_columns] = df[onehot_columns].astype(object) - if (categorical_column + sep + missing_val) in df.columns: - mask = df[categorical_column + sep + missing_val] == 1 - df.loc[mask, onehot_columns] = np.nan - df = df.drop(columns=[categorical_column + sep + missing_val]) + data[onehot_columns] = data[onehot_columns].astype(object) + + if (categorical_column + sep + missing_val) in data.columns: + mask = data[categorical_column + sep + missing_val] == 1 + data.loc[mask, onehot_columns] = np.nan + data = data.drop(columns=[categorical_column + sep + missing_val]) elif ( drop_first and isinstance(dictionary, pd.DataFrame) @@ -185,54 +326,122 @@ def convert_categorical_to_onehot( axis=1, ) if drop_column_ind.any(): - df = df.drop( + data = data.drop( columns=[dictionary.loc[drop_column_ind, "field_name"].values[0]] ) if isinstance(dictionary, pd.DataFrame) and "field_name" in dictionary.columns: - columns = [col for col in dictionary["field_name"].values if col in df.columns] + columns = [ + col for col in dictionary["field_name"].values if col in data.columns + ] columns += [ - col for col in df.columns if col not in dictionary["field_name"].values + col for col in data.columns if col not in dictionary["field_name"].values ] - df = df[columns] + data = data[columns] - return df + return data def convert_onehot_to_categorical( - df, dictionary, categorical_columns, sep="___", missing_val="nan" -): - """Convert onehot-encoded variables into categorical variables.""" - df = pd.concat([df, pd.DataFrame(columns=categorical_columns)], axis=1) + data: pandas.DataFrame, + dictionary: pandas.DataFrame, + categorical_columns: typing.Iterable[str], + sep: str = "___", + missing_val: str = "nan", +) -> pandas.DataFrame: + """:py:class:`pandas.DataFrame` : Returns the given dataframe with onehot-encoded variable columns to categorical variable columns. + + Parameters + ---------- + data : pandas.DataFrame + The incoming data. + + dictionary : pandas.DataFrame + Data dictionary. + + categorical_columns : typing.Iterable + An iterable of categorical column names. + + sep : str, default="___" + Optional field-value separator, defaults to ``"___"``. + + missing_val : str, default="nan" + Optional value with which to replace missing values, defaults to + ``"nan"``. + + Returns + ------- + pandas.DataFrame + The original dataframe with the one-hot-encoded -> categorical variable + columns. + """ # noqa : E501 + data = pd.concat([data, pd.DataFrame(columns=categorical_columns)], axis=1) + for categorical_column in categorical_columns: onehot_columns = list( - df.columns[df.columns.str.startswith(categorical_column + sep)] + data.columns[data.columns.str.startswith(categorical_column + sep)] ) # Preserve missingness - df.loc[:, categorical_column + sep + missing_val] = ( - df[onehot_columns].any(axis=1) == 0 - ) | (df[onehot_columns].isna().any(axis=1)) + data.loc[:, categorical_column + sep + missing_val] = ( + data[onehot_columns].any(axis=1) == 0 + ) | (data[onehot_columns].isna().any(axis=1)) + with pd.option_context("future.no_silent_downcasting", True): - df.loc[:, onehot_columns] = df[onehot_columns].fillna(False) + data.loc[:, onehot_columns] = data[onehot_columns].fillna(False) onehot_columns += [categorical_column + sep + missing_val] - df.loc[:, categorical_column] = pd.from_dummies(df[onehot_columns], sep=sep) - df = df.drop(columns=onehot_columns) + data.loc[:, categorical_column] = pd.from_dummies(data[onehot_columns], sep=sep) + data = data.drop(columns=onehot_columns) + + columns = [col for col in dictionary["field_name"].values if col in data.columns] + columns += [ + col for col in data.columns if col not in dictionary["field_name"].values + ] + data = data[columns] - columns = [col for col in dictionary["field_name"].values if col in df.columns] - columns += [col for col in df.columns if col not in dictionary["field_name"].values] - df = df[columns] - return df + return data def from_timeA_to_timeB( - data, - dictionary, - timeA_column, - timeB_column, - timediff_column, - timediff_label, - time_unit="days", -): + data: pandas.DataFrame, + dictionary: pandas.DataFrame, + timeA_column: str, + timeB_column: str, + timediff_column: str, + timediff_label: str, + time_unit: str = "days", +) -> tuple[pd.DataFrame]: + """:py:class:`tuple` : Returns the data and data dictionary updated with time difference calculation between two given data columns. + + Parameters + ---------- + data : pandas.DataFrame + The incoming data. + + dictionary : pandas.DataFrame + The data dictionary. + + timeA_column : str + The name of the first time column. + + timeB_column : str + The name of the second time column. + + timediff_column : str + The name of the column for storing the time difference of the two + given time columns. + + timediff_label : str + A label to attach to the time difference column. + + time_unit : str, default="days" + An optional indicator of which time unit to use for the time difference + calculation, defaults to ``"days"``. + + Returns + ------- + tuple + The data and data dictionary updated with time difference information. + """ # noqa : E501 if time_unit == "days": data[timediff_column] = (data[timeB_column] - data[timeA_column]).dt.days elif time_unit == "months": @@ -241,6 +450,7 @@ def from_timeA_to_timeB( ) * 12 + (data[timeB_column].dt.month - data[timeA_column].dt.month) elif time_unit == "months": data[timediff_column] = data[timeB_column].dt.year - data[timeA_column].dt.year + time_dict = { "field_name": timediff_column, "form_name": dictionary.loc[ @@ -253,6 +463,7 @@ def from_timeA_to_timeB( ].values[0], } dictionary = extend_dictionary(dictionary, time_dict, data) + return data, dictionary @@ -263,7 +474,37 @@ def from_timeA_to_timeB( ############################################ -def median_iqr_str(series, add_spaces=False, dp=1, mfw=4, min_n=3): +def get_median_interquartile_range( + series: pandas.Series, + add_spaces: bool = False, + dp: int = 1, + mfw: int = 4, + min_n: int = 3, +) -> str: + """:py:class:`str` : Returns the median interquartile range (IQR) of a given series of values as a string. + + Parameters + ---------- + series : pandas.Series + The input series for which to calculate the IQR. + + add_spaces : bool, default=False + Add spacing in the string. + + dp : int, default=1 + No description available. + + mfw : int, default=4 + No description available. + + min_n : int, default=3 + No description available. + + Returns + ------- + str + The IQR as a string. + """ # noqa : E501 if series.notna().sum() < min_n: output_str = "N/A" elif add_spaces: @@ -277,10 +518,90 @@ def median_iqr_str(series, add_spaces=False, dp=1, mfw=4, min_n=3): output_str += "%.*f" % (dp, series.quantile(0.25)) + "-" output_str += "%.*f" % (dp, series.quantile(0.75)) + ") | " output_str += str(int(series.notna().sum())) + return output_str -def mean_std_str(series, add_spaces=False, dp=1, mfw=4, min_n=3): +def median_iqr_str( + series: pandas.Series, + add_spaces: bool = False, + dp: int = 1, + mfw: int = 4, + min_n: int = 3, +) -> str: + """:py:class:`str` : Returns the median interquartile range (IQR) of a given series of values as a formatted string. + + .. warning:: + + DEPRECATED. Please use :py:func:`~isaricanalytics.analytics.get_median_interquartile_range` instead. + + Parameters + ---------- + series : pandas.Series + The input series for which to calculate the IQR. + + add_spaces : bool, default=False + Add spacing in the string. + + dp : int, default=1 + No description available. + + mfw : int, default=4 + No description available. + + min_n : int, default=3 + No description available. + + Returns + ------- + str + The IQR as a string. + """ # noqa : E501 + warnings.warn( + ( + "`analytics.median_iqr_str` is deprecated; " + "please use `analytics.get_median_interquartile_range` instead." + ), + DeprecationWarning, + stacklevel=2, + ) + + return get_median_interquartile_range( + series, add_spaces=add_spaces, dp=dp, mfw=mfw, min_n=min_n + ) + + +def get_mean_and_stdev( + series: pandas.Series, + add_spaces: bool = False, + dp: int = 1, + mfw: int = 4, + min_n: int = 3, +) -> str: + """:py:class:`str` : Returns the mean and standard deviation of a series of values as a formatted string. + + Parameters + ---------- + series : pandas.Series + The input series for which to calculate the mean and st. dev. + + add_spaces : bool, default=False + Add spacing in the string. + + dp : int, default=1 + No description available. + + mfw : int, default=4 + No description available. + + min_n : int, default=3 + No description available. + + Returns + ------- + str + The mean and st. dev. as a formatted string. + """ # noqa : E501 if series.notna().sum() < min_n: output_str = "N/A" elif add_spaces: @@ -292,10 +613,90 @@ def mean_std_str(series, add_spaces=False, dp=1, mfw=4, min_n=3): output_str = "%.*f" % (dp, series.mean()) + " (" output_str += "%.*f" % (dp, series.std()) + ") | " output_str += str(int(series.notna().sum())) + return output_str -def n_percent_str(series, add_spaces=False, dp=1, mfw=4, min_n=1): +def mean_std_str( + series: pandas.Series, + add_spaces: bool = False, + dp: int = 1, + mfw: int = 4, + min_n: int = 3, +) -> str: + """:py:class:`str` : Returns the mean and standard deviation of a series of values as a formatted string. + + .. warning:: + + DEPRECATED. Please use :py:func:`~isaricanalytics.analytics.get_mean_and_stdev` instead. + + Parameters + ---------- + series : pandas.Series + The input series for which to calculate the mean and st. dev. + + add_spaces : bool, default=False + Add spacing in the string. + + dp : int, default=1 + No description available. + + mfw : int, default=4 + No description available. + + min_n : int, default=3 + No description available. + + Returns + ------- + str + The mean and st. dev. as a formatted string. + """ # noqa : E501 + warnings.warn( + ( + "`analytics.mean_std_str` is deprecated; " + "please use `analytics.get_mean_and_stdev` instead." + ), + DeprecationWarning, + stacklevel=2, + ) + + return get_mean_and_stdev( + series, add_spaces=add_spaces, dp=dp, mfw=mfw, min_n=min_n + ) + + +def get_n_percent_value( + series: pandas.Series, + add_spaces: bool = False, + dp: int = 1, + mfw: int = 4, + min_n: int = 1, +) -> str: + """:py:class:`str` : Returns the n-percent value of a series as a string. + + Parameters + ---------- + series : pandas.Series + The input series. + + add_spaces : bool, default=False + Add spacing around the string. + + dp : int, default=1 + No description available. + + mfw : int, default=1 + No description available. + + min_n : int, default=1 + No description available. + + Returns + ------- + str + The n-percent value of the series as a string. + """ # noqa : E501 if series.notna().sum() < min_n: output_str = "N/A" elif add_spaces: @@ -311,10 +712,86 @@ def n_percent_str(series, add_spaces=False, dp=1, mfw=4, min_n=1): percent = "%.*f" % (dp, 100 * series.mean()) denom = str(int(series.notna().sum())) output_str = f"{count} ({percent}) | {denom}" + return output_str -def get_chi2_pvalue(x, y, x_cat=[True, False], y_cat=[True, False]): +def n_percent_str( + series: pandas.Series, + add_spaces: bool = False, + dp: int = 1, + mfw: int = 4, + min_n: int = 1, +) -> str: + """:py:class:`str` : Returns the n-percent value of a series as a string. + + .. warning:: + + DEPRECATED. Please use :py:func:`~isaricanalytics.analytics.get_n_percent_value` instead. + + Parameters + ---------- + series : pandas.Series + The input series. + + add_spaces : bool, default=False + Add spacing around the string. + + dp : int, default=1 + No description available. + + mfw : int, default=1 + No description available. + + min_n : int, default=1 + No description available. + + Returns + ------- + str + The n-percent value of the series as a string. + """ # noqa : E501 + warnings.warn( + ( + "`analytics.n_percent_str` is deprecated; " + "please use `analytics.get_n_percent_value` instead." + ), + DeprecationWarning, + stacklevel=2, + ) + + return get_n_percent_value( + series, add_spaces=add_spaces, dp=dp, mfw=mfw, min_n=min_n + ) + + +def get_chi2_pvalue( + x: pandas.Series, + y: pandas.Series, + x_cat: typing.Iterable[typing.Any] = [True, False], + y_cat: typing.Iterable[typing.Any] = [True, False], +) -> float: + """:py:class:`float` : Returns the :math`p`-value for a Chi-squared test. + + Parameters + ---------- + x : pandas.Series + The first series/factor. + + y : pandas.Series + The second series/factor. + + x_cat : typing.Iterable + An iterable of categories by which to group the first series. + + y_cat : typing.Iterable + An interable of categories by which to group the second series. + + Returns + ------- + float + The :math:`p`-value for the test. + """ # noqa : E501 try: print(x.name) contingency = pd.crosstab( @@ -326,10 +803,37 @@ def get_chi2_pvalue(x, y, x_cat=[True, False], y_cat=[True, False]): pvalue = chi2_contingency(contingency).pvalue except ValueError: pvalue = np.nan + return pvalue -def get_fisher_exact_pvalue(x, y, x_cat=[True, False], y_cat=[True, False]): +def get_fisher_exact_pvalue( + x: pandas.Series, + y: pandas.Series, + x_cat: typing.Iterable[typing.Any] = [True, False], + y_cat: typing.Iterable[typing.Any] = [True, False], +): + """:py:class:`float` : Returns the :math:`p`-value for a Fisher exact test. + + Parameters + ---------- + x : pandas.Series + The first series/factor. + + y : pandas.Series + The second series/factor. + + x_cat : typing.Iterable + An iterable of categories by which to group the first series. + + y_cat : typing.Iterable + An interable of categories by which to group the second series. + + Returns + ------- + float + The :math:`p`-value for the test. + """ # noqa : E501 try: contingency = pd.crosstab( pd.Categorical(x.loc[x.notna()], categories=x_cat), @@ -344,33 +848,63 @@ def get_fisher_exact_pvalue(x, y, x_cat=[True, False], y_cat=[True, False]): pvalue = result.pvalue except ValueError: pvalue = np.nan + return pvalue -def format_pvalue(pvalue, dp=3, min_val=0.001, significance={"*": 0.05, "**": 0.01}): +def format_pvalue( + pvalue: float, + dp: int = 3, + min_val: float = 0.001, + significance: dict[str, float] = {"*": 0.05, "**": 0.01}, +) -> str: + """:py:class:`str` : Returns a formatted :math:`p`-value string. + + Parameters + ---------- + pvalue : float + The :math:`p`-value. + + dp : int, default=3 + Optional. No description available, defaults to :math:`3`. + + min_val : float, default=0.001 + Optional. No description available, defaults to :math:`0.001`. + + significance : dict, default={"*": 0.05, "**": 0.01}. + Dict of significance levels, defaults to ``{"*": 0.05, "**": 0.01}``. + + Returns + ------- + str + The formatted :math:`p`-value string. + """ # noqa : E501 if pvalue < min_val: pvalue_str = f"<{min_val}" elif np.isnan(pvalue): pvalue_str = "" else: pvalue_str = "%.*f" % (dp, pvalue) + for key in significance: level = significance[key] min_threshold = max([v for k, v in significance.items() if (k != key)] + [0]) + if min_threshold > level: min_threshold = 0 if (pvalue < level) & (pvalue > (min_threshold - 1e-8)): pvalue_str = pvalue_str + f" ({key})" + return pvalue_str def get_descriptive_data( - data, - dictionary, - by_column=None, - include_sections=["demog"], - include_types=["binary", "categorical", "numeric"], - exclude_suffix=[ + data: pandas.DataFrame, + dictionary: pandas.DataFrame, + by_column: str | None = None, + include_sections: typing.Iterable[str] = ["demog"], + include_types: typing.Iterable[str] = ["binary", "categorical", "numeric"], + exclude_suffix: typing.Iterable[str] = [ "_units", "addi", "otherl2", @@ -379,14 +913,55 @@ def get_descriptive_data( "_unlisted", "otherl3", ], - include_subjid=False, - exclude_negatives=True, - sep="___", -): - df = data.copy() + include_subjid: bool = False, + exclude_negatives: bool = True, + sep: str = "___", +) -> pandas.DataFrame: + """:py:class:`pandas.DataFrame` : Returns descriptive data. + + Parameters + ---------- + data : pandas.DataFrame + Incoming data. + + dictionary : pandas.DataFrame + Data dictionary. + + by_column : str, default=None + Optional. No description available, defaults to ``None``. + + include_sections : typing.Iterable, default=["demog"] + Optional list of names of sections to include, defaults to + ``["demog"]``. + + include_types : typing.Iterable, default=["binary", "categorical", "numeric"] + Optional iterable of variable type names, defaults to + ``["binary", "categorical", "numeric"]``. + + exclude_suffix : typing.Iterable, default=["_units", "addi", "otherl2", "item", "_oth", "_unlisted", "otherl3"] + Optional iterable of suffixes to exclude, defaults to + ``["_units", "addi", "otherl2", "item", "_oth", "_unlisted", "otherl3"]``. + + include_subjid : bool, default=False + Optional boolean to indicate whether to include subject ID, defaults to + ``False``. + + exclude_negatives : bool, default=True + Optional boolean to indicate whether to drop negatives, defaults to + ``True``. + + sep : str, default="___" + Optional field-value separator, defaults to ``"___"``. + + Returns + ------- + pandas.DataFrame + Returns the descriptive data. + """ # noqa : E501 + _data = data.copy() include_columns = get_variables_by_section_and_type( - df, + _data, dictionary, include_types=include_types, include_subjid=include_subjid, @@ -395,57 +970,88 @@ def get_descriptive_data( ) if (by_column is not None) & (by_column not in include_columns): include_columns = [by_column] + include_columns - df = df[include_columns].dropna(axis=1, how="all").copy() + _data = _data[include_columns].dropna(axis=1, how="all").copy() # Convert categorical variables to onehot-encoded binary columns categorical_ind = dictionary["field_type"] == "categorical" columns = dictionary.loc[categorical_ind, "field_name"].tolist() columns = [col for col in columns if col != by_column] - df = convert_categorical_to_onehot( - df, dictionary, categorical_columns=columns, sep=sep + _data = convert_categorical_to_onehot( + _data, dictionary, categorical_columns=columns, sep=sep ) - if (by_column is not None) & (by_column not in df.columns): - df = convert_onehot_to_categorical( - df, dictionary, categorical_columns=[by_column], sep=sep + if (by_column is not None) & (by_column not in _data.columns): + _data = convert_onehot_to_categorical( + _data, dictionary, categorical_columns=[by_column], sep=sep ) negative_values = ("no", "never smoked") negative_columns = [ - col for col in df.columns if col.split(sep)[-1].lower() in negative_values + col for col in _data.columns if col.split(sep)[-1].lower() in negative_values ] if exclude_negatives: - df.drop(columns=negative_columns, inplace=True) + _data.drop(columns=negative_columns, inplace=True) # Remove columns with only NaN values - df = df.dropna(axis=1, how="all") - df.fillna({by_column: "Unknown"}, inplace=True) - return df + _data = _data.dropna(axis=1, how="all") + _data.fillna({by_column: "Unknown"}, inplace=True) + + return _data def descriptive_table( - data, - dictionary, - by_column=None, - include_totals=True, - column_reorder=None, - include_raw_variable_name=False, - sep="___", -): - """ - Descriptive table for binary (including onehot-encoded categorical) and - numerical variables in data. The descriptive table will have seperate - columns for each category that exists for the variable 'by_column', if - this is provided. - """ - df = data.copy() + data: pandas.DataFrame, + dictionary: pandas.DataFrame, + by_column: str | None = None, + include_totals: bool = True, + column_reorder: typing.Iterable[str] | None = None, + include_raw_variable_name: bool = False, + sep: str = "___", +) -> tuple[pandas.DataFrame, str]: + """:py:class:`tuple` : Returns the descriptive table and table key for binary and numerical variables in the data. + + The descriptive table will have separate columns for each category that + exists for the ``by_column`` variable, if this is provided. + + Parameters + ---------- + data : pandas.DataFrame + Incoming data. + + dictionary : pandas.DataFrame + Data dictionary. + + by_column : str, default=None + Optional. No description available, defaults to ``None``. + + include_totals : bool, default=None + Optional. No description available, defaults to ``None``. + + column_reorder : typing.Iterable, default=None + Optional iterable of names of columns to reorder by, defaults to + ``None``. + + include_raw_variable_name : bool, default=False + Optional boolean indicating whether to include the raw variable name, + defaults to ``False``. + + sep : str, default="___" + Optional field-value separator, defaults to ``"___"``. + + Returns + ------- + tuple + Returns the descriptive table and table key for binary and numerical + variables in the data. + """ # noqa : E501 + _data = data.copy() numeric_ind = dictionary["field_type"] == "numeric" numeric_columns = dictionary.loc[numeric_ind, "field_name"].tolist() - numeric_columns = [col for col in numeric_columns if col in df.columns] + numeric_columns = [col for col in numeric_columns if col in _data.columns] binary_ind = dictionary["field_type"] == "binary" binary_columns = dictionary.loc[binary_ind, "field_name"].tolist() - binary_columns = [col for col in binary_columns if col in df.columns] + binary_columns = [col for col in binary_columns if col in _data.columns] # Add columns for section headers and categorical questions index = numeric_columns + binary_columns @@ -454,76 +1060,113 @@ def descriptive_table( index = table_dictionary["field_name"].tolist() table_columns = ["Variable", "All"] + if by_column is not None: - add_columns = list(df[by_column].unique()) + add_columns = list(_data[by_column].unique()) if column_reorder is not None: table_columns += [col for col in column_reorder if col in add_columns] table_columns += [col for col in add_columns if col not in column_reorder] else: table_columns += add_columns + table_columns += ["Raw variable name"] table = pd.DataFrame("", index=index, columns=table_columns) - table["Raw variable name"] = [var if var in df.columns else "" for var in index] + table["Raw variable name"] = [var if var in _data.columns else "" for var in index] table["Variable"] = format_descriptive_table_variables( table_dictionary, sep=sep ).tolist() - mfw = int(np.log10(df.shape[0])) + 1 # Min field width, for formatting - table.loc[numeric_columns, "All"] = df[numeric_columns].apply( + mfw = int(np.log10(_data.shape[0])) + 1 # Min field width, for formatting + table.loc[numeric_columns, "All"] = _data[numeric_columns].apply( median_iqr_str, mfw=mfw ) - table.loc[binary_columns, "All"] = df[binary_columns].apply(n_percent_str, mfw=mfw) + table.loc[binary_columns, "All"] = _data[binary_columns].apply( + n_percent_str, mfw=mfw + ) totals = pd.DataFrame(columns=table_columns, index=["totals"]) totals["Variable"] = "Totals" - totals["All"] = df.shape[0] + totals["All"] = _data.shape[0] if by_column is not None: - choices_values = df[by_column].unique() + choices_values = _data[by_column].unique() for value in choices_values: - ind = df[by_column] == value + ind = _data[by_column] == value mfw = int(np.log10(ind.sum())) + 1 # Min field width, for format - table.loc[numeric_columns, value] = df.loc[ind, numeric_columns].apply( + table.loc[numeric_columns, value] = _data.loc[ind, numeric_columns].apply( median_iqr_str, mfw=mfw ) - table.loc[binary_columns, value] = df.loc[ind, binary_columns].apply( + table.loc[binary_columns, value] = _data.loc[ind, binary_columns].apply( n_percent_str, mfw=mfw ) totals[value] = ind.sum() table = table.reset_index(drop=True) + if include_totals: table = pd.concat([totals, table], axis=0).reset_index(drop=True) + table_key = "KEY
(*) Count (%) | N
(+) Median (IQR) | N" + if include_raw_variable_name is False: table.drop(columns=["Raw variable name"], inplace=True) + return table, table_key def descriptive_comparison_table( - data, - dictionary, - by_column=None, - include_totals=True, - column_reorder=None, - sep="___", - pvalue_significance={"*": 0.05, "**": 0.01}, -): - """ - Descriptive table for binary (including onehot-encoded categorical) and - numerical variables in data. The descriptive table will have seperate - columns for each category that exists for the variable 'by_column', if - this is provided. - """ - df = data.copy() + data: pandas.DataFrame, + dictionary: pandas.DataFrame, + by_column: str | None = None, + include_totals: bool = True, + column_reorder: typing.Iterable[str] | None = None, + sep: str = "___", + pvalue_significance: dict[str, float] = {"*": 0.05, "**": 0.01}, +) -> tuple[pd.DataFrame, str]: + """:py:class:`tuple` : Returns the descriptive comparison table and table key for binary (including onehot-encoded categorical) and numerical variables in data. + + The descriptive table will have separate columns for each category that + exists for the ``by_column`` variable, if this is provided. + + Parameters + ---------- + data : pandas.DataFrame + Incoming data. + + dictionary : pandas.DataFrame + Data dictionary. + + by_column : str, default=None + Optional. No description available, defaults to ``None``. + + include_totals : bool, default=None + Optional. No description available, defaults to ``None``. + + column_reorder : typing.Iterable, default=None + Optional iterable of names of columns to reorder by, defaults to + ``None``. + + sep : str, default="___" + Optional field-value separator, defaults to ``"___"``. + + pvalue_significance : dict, default={"*": 0.05, "**": 0.01} + A dict of significance levels, defaults to ``{"*": 0.05, "**": 0.01}``. + + Returns + ------- + tuple + Returns the descriptive comparison table and table key for binary and + numerical variables in the data. + """ # noqa : E501 + _data = data.copy() numeric_ind = dictionary["field_type"] == "numeric" numeric_columns = dictionary.loc[numeric_ind, "field_name"].tolist() - numeric_columns = [col for col in numeric_columns if col in df.columns] + numeric_columns = [col for col in numeric_columns if col in _data.columns] binary_ind = dictionary["field_type"] == "binary" binary_columns = dictionary.loc[binary_ind, "field_name"].tolist() - binary_columns = [col for col in binary_columns if col in df.columns] + binary_columns = [col for col in binary_columns if col in _data.columns] # Add columns for section headers and categorical questions index = numeric_columns + binary_columns @@ -533,7 +1176,7 @@ def descriptive_comparison_table( table_columns = ["Variable", "All"] if by_column is not None: - add_columns = list(df[by_column].unique()) + add_columns = list(_data[by_column].unique()) if column_reorder is not None: table_columns += [col for col in column_reorder if col in add_columns] table_columns += [col for col in add_columns if col not in column_reorder] @@ -546,35 +1189,37 @@ def descriptive_comparison_table( table_dictionary, sep=sep, binary_symbol="†" ).tolist() - mfw = int(np.log10(df.shape[0])) + 1 # Min field width, for formatting - table.loc[numeric_columns, "All"] = df[numeric_columns].apply( + mfw = int(np.log10(_data.shape[0])) + 1 # Min field width, for formatting + table.loc[numeric_columns, "All"] = _data[numeric_columns].apply( median_iqr_str, mfw=mfw ) - table.loc[binary_columns, "All"] = df[binary_columns].apply(n_percent_str, mfw=mfw) + table.loc[binary_columns, "All"] = _data[binary_columns].apply( + n_percent_str, mfw=mfw + ) totals = pd.DataFrame(columns=table_columns, index=["totals"]) totals["Variable"] = "Totals" - totals["All"] = df.shape[0] + totals["All"] = _data.shape[0] if by_column is not None: - by_column_values = df[by_column].unique() + by_column_values = _data[by_column].unique() for value in by_column_values: - ind = df[by_column] == value + ind = _data[by_column] == value mfw = int(np.log10(ind.sum())) + 1 # Min field width, for format - table.loc[numeric_columns, value] = df.loc[ind, numeric_columns].apply( + table.loc[numeric_columns, value] = _data.loc[ind, numeric_columns].apply( median_iqr_str, mfw=mfw ) - table.loc[binary_columns, value] = df.loc[ind, binary_columns].apply( + table.loc[binary_columns, value] = _data.loc[ind, binary_columns].apply( n_percent_str, mfw=mfw ) totals[value] = ind.sum() if len(by_column_values) == 2: - y = df[by_column] == by_column_values[0] + y = _data[by_column] == by_column_values[0] pvalues = pd.Series(index=table.index) - pvalues.loc[numeric_columns] = df[numeric_columns].apply( + pvalues.loc[numeric_columns] = _data[numeric_columns].apply( lambda x: mannwhitneyu(x, y, nan_policy="omit").pvalue, axis=0 ) - pvalues.loc[binary_columns] = df[binary_columns].apply( + pvalues.loc[binary_columns] = _data[binary_columns].apply( lambda x: get_fisher_exact_pvalue(x, y), axis=0 ) table["p-value"] = pvalues.apply( @@ -593,6 +1238,7 @@ def descriptive_comparison_table( if (pvalues < v).any() ] ) + return table, table_key @@ -603,20 +1249,64 @@ def descriptive_comparison_table( ############################################ -def trim_field_label(x, max_len=40): +def trim_field_label(x: str, max_len: int = 40) -> str: + """:py:class:`str` : Trims field label using an optional max. length parameter that defaults to 40 characters. + + Parameters + ---------- + x : str + The input field label. + + max_len : int, default=40 + An optional maximum length parameter to use for trimming, defaults to + :math:`40`. + + Returns + ------- + str + The trimmed field label. + """ # noqa : E501 if len(x) > max_len: x = " ".join(x[:max_len].split(" ")[:-1]) + " ..." + return x def format_descriptive_table_variables( - dictionary, - max_len=100, - add_key=True, - sep="___", - binary_symbol="*", - numeric_symbol="+", -): + dictionary: pandas.DataFrame, + max_len: int = 100, + add_key: bool = True, + sep: str = "___", + binary_symbol: str = "*", + numeric_symbol: str = "+", +) -> str: + """:py:class:`str` : Returns a formatted string of the descriptive table variable field names. + + Parameters + ---------- + dictionary : pandas.DataFrame + The data dictionary. + + max_len : int, default=100 + Optional maximum length of field names, defaults to :math:`100`. + + add_key : bool, default=True + Optional. No description available, defaults to ``True``. + + sep : str, default="___" + Optional field-value separator, defaults to ``"___"``. + + binary_symbol : str, default="*" + Optional. No description available, defaults to ``"*"``. + + numeric_symbol : str, default="*" + Optional. No description available, defaults to ``"+"``. + + Returns + ------- + str + A formatted string of the descriptive table variable field names. + """ # noqa : E501 name = dictionary["field_name"].apply(lambda x: " ↳ " if sep in x else "") name += dictionary["field_type"].map({"section": ""}).fillna("") name += ( @@ -626,6 +1316,7 @@ def format_descriptive_table_variables( ) name += dictionary["field_type"].map({"section": ""}).fillna("") name += dictionary["field_name"].apply(lambda x: "" if sep in x else "") + if add_key is True: field_type = ( dictionary["field_type"] @@ -639,10 +1330,32 @@ def format_descriptive_table_variables( .fillna("") ) name += field_type * (dictionary["field_name"].str.contains(sep) == 0) + return name -def format_variables(dictionary, max_len=40, sep="___"): +def format_variables( + dictionary: pandas.DataFrame, max_len: int = 40, sep: str = "___" +) -> str: + """:py:class:`str` : Returns a formatted string of the descriptive table variable field names. + + Parameters + ---------- + dictionary : pandas.DataFrame + The data dictionary. + + max_len : int, default=40 + Optional maximum length of field names, defaults to :math:`40`. + + sep : str, default="___" + Optional field-value separator, defaults to ``"___"``. + + Returns + ------- + str + A formatted string of the descriptive table variable field names. + """ # noqa : E501 + def get_parent_label(x): if pd.isna(x) or not isinstance(x, str): return "" @@ -674,8 +1387,34 @@ def get_parent_label(x): ############################################ -def get_counts(df, dictionary, max_n_variables=10, sep="___"): - counts = df.apply(lambda x: x.sum()).T.reset_index() +def get_counts( + data: pandas.DataFrame, + dictionary: pandas.DataFrame, + max_n_variables: int = 10, + sep: str = "___", +) -> pandas.DataFrame: + """:py:class:`pandas.DataFrame` : Returns a dataframe of variable column counts. + + Parameters + ---------- + data : pandas.DataFrame + The incoming data. + + dictionary : pandas.DataFrame + The data dictionary. + + max_n_variables : int, default=10 + Optional number of variables for which to take counts, defaults to + :math:`10`. + + sep : str, default="___" + Optional field-value separator, defaults to ``"___"``. + + Returns + ------- + The variable column counts dataframe. + """ # noqa : E501 + counts = data.apply(lambda x: x.sum()).T.reset_index() counts.columns = ["variable", "count"] counts = counts.sort_values(by=["count"], ascending=False).reset_index(drop=True) @@ -688,29 +1427,52 @@ def get_counts(df, dictionary, max_n_variables=10, sep="___"): short_format_dict = dict(zip(dictionary["field_name"], short_format)) counts["label"] = counts["variable"].map(format_dict) counts["short_label"] = counts["variable"].map(short_format_dict) + return counts def get_proportions( - df, - dictionary, - max_n_variables=10, - ignore_branching_logic=False, - branching_logic="", - sep="___", -): + data: pandas.DataFrame, + dictionary: pandas.DataFrame, + max_n_variables: int = 10, + ignore_branching_logic: bool = False, + branching_logic: str = "", + sep: str = "___", +) -> pandas.DataFrame: + """:py:class:`pandas.DataFrame` : Returns a dataframe of proportional counts for variable columns. + + Parameters + ---------- + data : pandas.DataFrame + The incoming data. + + dictionary : pandas.DataFrame + The data dictionary. + + max_n_variables : int, default=10 + Optional number of variables for which to take counts, defaults to + :math:`10`. + + sep : str, default="___" + Optional field-value separator, defaults to ``"___"``. + + Returns + ------- + pandas.DataFrame + A dataframe of proportional counts for variable columns. + """ # noqa : E501 if ignore_branching_logic: - columns = [col for col in df.columns] + columns = [col for col in data.columns] else: dictionary_subset = dictionary.loc[ (dictionary["branching_logic"] == branching_logic) ] columns = [ - col for col in df.columns if col in dictionary_subset["field_name"].values + col for col in data.columns if col in dictionary_subset["field_name"].values ] if len(columns) == 0: branching_logic = dictionary.loc[ - dictionary["field_name"].isin(df.columns), "branching_logic" + dictionary["field_name"].isin(data.columns), "branching_logic" ] branching_logic = branching_logic.values[0] dictionary_subset = dictionary.loc[ @@ -718,17 +1480,19 @@ def get_proportions( ] columns = [ col - for col in df.columns + for col in data.columns if col in dictionary_subset["field_name"].values ] + proportions = ( - df[columns].apply(lambda x: (x.sum() / x.count(), x.sum())).T.reset_index() + data[columns].apply(lambda x: (x.sum() / x.count(), x.sum())).T.reset_index() ) proportions.columns = ["variable", "proportion", "count"] proportions = proportions.sort_values(by=["count"], ascending=False).reset_index( drop=True ) + if proportions.shape[0] > max_n_variables: proportions = proportions.head(max_n_variables) @@ -743,17 +1507,42 @@ def get_proportions( short_format_dict = dict(zip(dictionary["field_name"], short_format)) proportions["label"] = proportions["variable"].map(format_dict) proportions["short_label"] = proportions["variable"].map(short_format_dict) + return proportions def get_upset_counts_intersections( - df, - dictionary, - proportions=None, # Deprecated - variables=None, - n_variables=5, - sep="___", -): + data: pandas.DataFrame, + dictionary: pandas.DataFrame, + variables: list[str] | None = None, + n_variables: int = 5, + sep: str = "___", +) -> tuple[pandas.DataFrame]: + """:py:class:`pandas.DataFrame` : Returns a dataframe of upset counts intersections. + + Parameters + ---------- + data : pandas.DataFrame + The incoming data. + + dictionary : pandas.DataFrame + The data dictionary. + + variables : list, default=None + Optional list of names of variable columns for which to take counts, + defaults to ``None``. + + n_variables : int, default=5 + Optional limit for the number of variable columns, defaults to :math:`5`. + + sep : str, default="___" + Optional field-value separator, defaults to ``"___"``. + + Returns + ------- + pandas.DataFrame + A dataframe of upset counts intersections. + """ # noqa : E501 # Convert variables and column names into their formatted names long_format = format_variables(dictionary, max_len=1000, sep=sep) short_format = format_variables(dictionary, max_len=40, sep=sep) @@ -761,29 +1550,30 @@ def get_upset_counts_intersections( short_format_dict = dict(zip(dictionary["field_name"], short_format)) if variables is None: - variables = df.columns.tolist() + variables = data.columns.tolist() binary_columns = dictionary.loc[ (dictionary["field_type"] == "binary"), "field_name" ].tolist() variables = [col for col in variables if col in binary_columns] - variables = [var for var in variables if df[var].sum() > 0] - df = df[variables].astype(float).fillna(0) + variables = [var for var in variables if data[var].sum() > 0] + data = data[variables].astype(float).fillna(0) - counts = df.sum().astype(int).reset_index().rename(columns={0: "count"}) + counts = data.sum().astype(int).reset_index().rename(columns={0: "count"}) counts = counts.sort_values(by="count", ascending=False).reset_index(drop=True) counts["short_label"] = counts["index"].map(short_format_dict) counts["label"] = counts["index"].map(format_dict) variable_order_dict = dict(zip(counts["index"], counts.index)) variables = counts["index"].tolist() + if n_variables is not None: variables = variables[:n_variables] - df = df[variables] + data = data[variables] counts = counts.loc[counts["index"].isin(variables)] - intersections = df.loc[df.any(axis=1)].value_counts().reset_index() + intersections = data.loc[data.any(axis=1)].value_counts().reset_index() intersections["index"] = intersections.drop(columns="count").apply( lambda x: tuple(col for col in x.index if x[col] == 1), axis=1 ) @@ -806,20 +1596,50 @@ def get_upset_counts_intersections( ) keep_columns = ["index", "label", "count"] intersections = intersections[keep_columns].reset_index(drop=True) + return counts, intersections -def get_pyramid_data(df, column_dict, left_side="Female", right_side="Male"): +def get_pyramid_data( + data: pandas.DataFrame, + column_dict: dict[str, str], + left_side: str = "Female", + right_side: str = "Male", +) -> pandas.DataFrame: + """:py:class:`pandas.DataFrame` : Returns dual stack pyramid data. + + Parameters + ---------- + data : pandas.DataFrame + The incoming data. + + column_dict : dict + Dict of pyramid keys and data column names. + + left_side : str, default="Female" + Optional label for the left side of the pyramid, defaults to + ``"Female"``. + + right_side : str, default="Male" + Optional label for the right side of the pyramid, defaults to + ``"Male"``. + + Returns + ------- + pandas.DataFrame + Dual stack pyramid data. + """ keys = ["side", "y_axis", "stack_group"] # assert all(key in tuple(column_dict.keys()) for key in keys), 'Error' columns = [column_dict[key] for key in keys] - df_pyramid = df[["subjid"] + columns].copy() + df_pyramid = data[["subjid"] + columns].copy() df_pyramid = df_pyramid.groupby(columns, observed=True).count().reset_index() df_pyramid.rename(columns={"subjid": "value"}, inplace=True) df_pyramid.rename(columns={v: k for k, v in column_dict.items()}, inplace=True) df_pyramid = df_pyramid.loc[df_pyramid["side"].isin([left_side, right_side])] df_pyramid.loc[:, "left_side"] = df_pyramid["side"] == left_side df_pyramid = df_pyramid.sort_values(by="y_axis").reset_index(drop=True) + return df_pyramid @@ -831,13 +1651,21 @@ def get_pyramid_data(df, column_dict, left_side="Female", right_side="Male"): def get_modelling_data( - data, - dictionary, - outcome_columns, - include_sections=["demog", "comor", "adsym", "vacci", "vital", "sympt", "labs"], - required_variables=None, - include_types=["binary", "categorical", "numeric"], - exclude_suffix=[ + data: pandas.DataFrame, + dictionary: pandas.DataFrame, + outcome_columns: str | typing.Iterable[str], + include_sections: typing.Iterable[str] = [ + "demog", + "comor", + "adsym", + "vacci", + "vital", + "sympt", + "labs", + ], + required_variables: typing.Iterable[str] | None = None, + include_types: typing.Iterable[str] = ["binary", "categorical", "numeric"], + exclude_suffix: typing.Iterable[str] = [ "_units", "addi", "otherl2", @@ -846,19 +1674,69 @@ def get_modelling_data( "_unlisted", "otherl3", ], - include_subjid=False, - exclude_negatives=True, - fillna=True, - drop_first=False, - sep="___", -): - df = data.copy() + include_subjid: bool = False, + exclude_negatives: bool = True, + fillna: bool = True, + drop_first: bool = False, + sep: str = "___", +) -> pandas.DataFrame: + """:py:class:`pandas.DataFrame` : Returns modelling data. + + Parameters + ---------- + data : pandas.DataFrame + Incoming data. + + dictionary : pandas.DataFrame + Data dictionary. + + outcome_columns : typing.Iterable + Outcome columns. + + include_sections : typing.Iterable, default=["demog", "comor", "adsym", "vacci", "vital", "sympt", "labs"] + Optional list of names of sections to include, defaults to + ``["demog", "comor", "adsym", "vacci", "vital", "sympt", "labs"]``. + + required_variables: typing.Iterable, default=None + Required variable column names, defaults to ``None``. + + include_types : typing.Iterable, default=["binary", "categorical", "numeric"] + Optional iterable of variable type names, defaults to + ``["binary", "categorical", "numeric"]``. + + exclude_suffix : typing.Iterable, default=["_units", "addi", "otherl2", "item", "_oth", "_unlisted", "otherl3"] + Optional iterable of suffixes to exclude, defaults to + ``["_units", "addi", "otherl2", "item", "_oth", "_unlisted", "otherl3"]``. + + include_subjid : bool, default=False + Optional boolean to indicate whether to include subject ID, defaults to + ``False``. + + exclude_negatives : bool, default=True + Optional boolean to indicate whether to drop negatives, defaults to + ``True``. + + fillna : bool, default=True + Optional boolean to fill nulls, defaults to ``True``. + + drop_first : bool, default=False + Optional boolean relating to dropping columns, defaults to ``False``. + + sep : str, default="___" + Optional field-value separator, defaults to ``"___"``. + + Returns + ------- + pandas.DataFrame + Returns the modelling data. + """ # noqa : E501 + _data = data.copy() if isinstance(outcome_columns, str): outcome_columns = [outcome_columns] include_columns = get_variables_by_section_and_type( - df, + _data, dictionary, required_variables=required_variables, include_types=include_types, @@ -869,64 +1747,91 @@ def get_modelling_data( for outcome_column in outcome_columns: if outcome_column not in include_columns: include_columns = [outcome_column] + include_columns - df = df[include_columns].dropna(axis=1, how="all").copy() + _data = _data[include_columns].dropna(axis=1, how="all").copy() # Convert categorical variables to onehot-encoded binary columns categorical_ind = dictionary["field_type"] == "categorical" columns = dictionary.loc[categorical_ind, "field_name"].tolist() columns = [col for col in columns if col not in tuple(outcome_columns)] - df = convert_categorical_to_onehot( - df, dictionary, categorical_columns=columns, drop_first=drop_first, sep=sep + _data = convert_categorical_to_onehot( + _data, dictionary, categorical_columns=columns, drop_first=drop_first, sep=sep ) binary_ind = dictionary["field_type"] == "binary" columns = dictionary.loc[binary_ind, "field_name"].tolist() - columns = [col for col in columns if col in df.columns] + columns = [col for col in columns if col in _data.columns] if fillna is True: with pd.option_context("future.no_silent_downcasting", True): - df[columns] = df[columns].fillna(False) + _data[columns] = _data[columns].fillna(False) negative_values = ("no", "never smoked") negative_columns = [ - col for col in df.columns if col.split(sep)[-1].lower() in negative_values + col for col in _data.columns if col.split(sep)[-1].lower() in negative_values ] if exclude_negatives: - df.drop(columns=negative_columns, inplace=True) - return df + _data.drop(columns=negative_columns, inplace=True) + + return _data def variance_influence_factor_backwards_elimination( - data, dictionary, predictors_list, sep="___" -): - df = data.copy() + data: pandas.DataFrame, + dictionary: pandas.DataFrame, + predictors_list: typing.Iterable[str], + sep: str = "___", +) -> tuple[typing.Iterable[str], pandas.DataFrame]: + """:py:class:`tuple` : Returns an iterable of retained columns and the VIF backwards elimination data. + + Parameters + ---------- + data : pandas.DataFrame + Incoming data. + + dictionary : pandas.DataFrame + Data dictionary. + + predictors_list : typing.Iterable + Iterable of predictor variable column names. + + sep : str, default="___" + Optional field-value separator, defaults to ``"___"``. + + Returns + ------- + tuple + An iterable of retained columns and the VIF backwards elimination data. + """ # noqa : E501 + _data = data.copy() numeric_ind = dictionary["field_type"] == "numeric" numeric_columns = dictionary.loc[numeric_ind, "field_name"].tolist() - numeric_columns = [col for col in numeric_columns if col in df.columns] + numeric_columns = [col for col in numeric_columns if col in _data.columns] numeric_columns = [col for col in numeric_columns if col in predictors_list] categorical_ind = dictionary["field_type"].isin(["binary"]) categorical_columns = dictionary.loc[categorical_ind, "field_name"].tolist() - categorical_columns = [col for col in categorical_columns if col in df.columns] + categorical_columns = [col for col in categorical_columns if col in _data.columns] categorical_columns = [col for col in categorical_columns if col in predictors_list] - df[numeric_columns] = (df[numeric_columns] - df[numeric_columns].mean()) / df[ - numeric_columns - ].std() + _data[numeric_columns] = ( + _data[numeric_columns] - _data[numeric_columns].mean() + ) / _data[numeric_columns].std() - df = 1.0 * pd.concat([df[numeric_columns], df[categorical_columns]], axis=1).astype( - float - ) + _data = 1.0 * pd.concat( + [_data[numeric_columns], _data[categorical_columns]], axis=1 + ).astype(float) - keep_columns = df.columns + keep_columns = _data.columns iterative_vif = pd.DataFrame(keep_columns, columns=["variable"]) + with warnings.catch_warnings(): warnings.filterwarnings("ignore", category=RuntimeWarning) iterative_vif["vif_iter_1"] = [ - variance_inflation_factor(df[keep_columns].values, ii) + variance_inflation_factor(_data[keep_columns].values, ii) for ii in range(len(keep_columns)) ] n = 1 + while (iterative_vif["vif_iter_" + str(n)] > 10).any(): remove_column = iterative_vif.loc[ iterative_vif["vif_iter_" + str(n)].idxmax(), "variable" @@ -940,43 +1845,59 @@ def variance_influence_factor_backwards_elimination( with warnings.catch_warnings(): warnings.filterwarnings("ignore", category=RuntimeWarning) vif["vif_iter_" + str(n)] = [ - variance_inflation_factor(df[keep_columns].values, ii) + variance_inflation_factor(_data[keep_columns].values, ii) for ii in range(len(keep_columns)) ] iterative_vif = pd.merge(iterative_vif, vif, how="left", on="variable") + return keep_columns, iterative_vif def remove_single_binary_outcome_predictors( - data, dictionary, predictors_list, outcome_str -): - """ - Removes binary predictors that are associated with only one outcome (e.g. - if all patients with some_variable=1 have outcome=1) - - Parameters: - - data: Pandas DataFrame containing the data. - - outcome_str: Name of the response variable. - - predictors_list: List of predictor variable names. - - Returns: - - updated_predictors_list: List of predictor variable names excluding - any that can't be used in the logistic regression model. - """ - df = data.copy() + data: pandas.DataFrame, + dictionary: pandas.DataFrame, + predictors: typing.Iterable[str], + outcome: str, +) -> typing.Iterable[str]: + """:py:class:`typing.Iterable` : Returns a list of retained columns in the data after removing single binary outcome predictor columns. + + Removes binary predictors that are associated with only one outcome, e.g. + if all patients with ``some_variable=1`` have ``outcome=1``. + + Parameters + ---------- + data: pandas.DataFrame + The incoming data. + + dictionary: pandas.DataFrame + The data dictionary. + + predictors: typing.Iterable + Iterable of predictor variable column names. + + outcome : str + The outcome string. + + Returns + ------- + typing.Iterable: + List of predictor variable column names excluding any that can't be + used in the logistic regression model. + """ # noqa : E501 + _data = data.copy() numeric_ind = dictionary["field_type"] == "numeric" numeric_columns = dictionary.loc[numeric_ind, "field_name"].tolist() - numeric_columns = [col for col in numeric_columns if col in df.columns] - numeric_columns = [col for col in numeric_columns if col in predictors_list] + numeric_columns = [col for col in numeric_columns if col in _data.columns] + numeric_columns = [col for col in numeric_columns if col in predictors] categorical_ind = dictionary["field_type"].isin(["binary"]) categorical_columns = dictionary.loc[categorical_ind, "field_name"].tolist() categorical_columns = [col for col in categorical_columns if col in data.columns] - categorical_columns = [col for col in categorical_columns if col in predictors_list] + categorical_columns = [col for col in categorical_columns if col in predictors] result = ( - df.groupby(outcome_str)[categorical_columns] + _data.groupby(outcome)[categorical_columns] .apply( lambda x: x.isin([True]).any() & x.isin([False]).any(), include_groups=False ) @@ -984,17 +1905,46 @@ def remove_single_binary_outcome_predictors( ) keep_columns = result.loc[result.all(axis=1)].index.tolist() keep_columns = keep_columns + numeric_columns + return keep_columns def regression_summary_table( - table, - dictionary, - highlight_predictors=None, - pvalue_significance=None, - result_type="OddsRatio", - sep="___", -): + table: pandas.DataFrame, + dictionary: pandas.DataFrame, + highlight_predictors: dict[str, typing.Iterable[str]] | None = None, + pvalue_significance: float | None = None, + result_type: str = "OddsRatio", + sep: str = "___", +) -> pandas.DataFrame: + """:py:class:`pandas.DataFrame` : Returns a regression summary table. + + Parameters + ---------- + table : pandas.DataFrame + The incoming table. + + dictionary : pandas.DataFrame + The data dictionary. + + highlight_predictors : dict, default=None + Optional. No description available, defaults to ``None``. + + pvalue_significance : int, default=5 + Optional :math:`p`-value significance level, defaults to ``None``. + + result_type : str, default="OddsRatio" + Optional. No description avaiable, defaults to ``"OddsRatio"``. + + sep : str, default="___" + Optional field-value separator, defaults to ``"___"``. + + Returns + ------- + pandas.DataFrame + Regression summary table. + """ # noqa : E501 + # Convert variables and column names into their formatted names variables = table["Variable"].tolist() new_variables = ( variables @@ -1085,58 +2035,79 @@ def regression_summary_table( } table["Variable"] = table["Variable"].map(mapping_dict) table["Variable"] = table["Variable"] + add_key + return table def execute_glmm_regression( - elr_dataframe_df, - elr_outcome_str, - elr_predictors_list, - elr_groups_str, - model_type="linear", - print_results=True, - labels=False, - reg_type="multi", -): - """ - Executes a mixed effects model for linear or logistic regression. - - Parameters: - - elr_dataframe_df: Pandas DataFrame containing the data. - - elr_outcome_str: Name of the response variable. - - elr_predictors_list: List of predictor variable names. - - elr_groups_str: Name of the variable that defines the groups (random effect). - - model_type: 'linear' for linear regression or 'logistic' for logistic regression. - - print_results: If True, prints the summary of the results. - - labels: (Optional) Dictionary to map variable names to readable labels. - - reg_type: 'uni' or 'multi', to rename the output columns. - - Returns: - - elr_summary_df: DataFrame with the model results. - """ - + elr_dataframe_df: pandas.DataFrame, + elr_outcome: str, + elr_predictors: typing.Iterable[str], + elr_groups: str, + model_type: str = "linear", + print_results: bool = True, + labels: dict[str, str] | None = None, + reg_type: str = "multi", +) -> pandas.DataFrame: + """:py:class:`pandas.DataFrame` : Executes a mixed effects model for linear or logistic regression. + + Parameters + ---------- + elr_dataframe_df : pandas.DataFrame + The incoming data. + + elr_outcome : str + Name of the response variable. + + elr_predictors : typing.Iterable + Iterable of predictor variable names. + + elr_groups : str + Name of the variable that defines the groups (random effect). + + model_type : str, default="linear" + Optional regression model type - use ``"linear"`` for linear regression + or ``"logistic"`` for logistic regression; defaults to ``"linear"``. + + print_results : bool, default=True + Optional indicator of whether to print the results summary, defaults to + ``True``. + + labels : dict, default=None + Optional map of variable names to readable labels, defaults to + ``None``. + + reg_type : str, default="multi" + Optional regression type - ``"uni"`` for univariate, ``"multi"`` for + multivariate. Defaults to ``"multi"``. + + Returns + ------- + pandas.DataFrame + The model results. + """ # noqa : E501 # Builds the formula - elr_formula_str = elr_outcome_str + " ~ " + " + ".join(elr_predictors_list) + elr_formula_str = elr_outcome + " ~ " + " + ".join(elr_predictors) # Converts predictor categorical variables elr_categorical_vars_list = elr_dataframe_df.select_dtypes( include=["object", "category"] ) elr_categorical_vars_list = elr_categorical_vars_list.columns.intersection( - elr_predictors_list + elr_predictors ) for elr_var_str in elr_categorical_vars_list: elr_dataframe_df[elr_var_str] = elr_dataframe_df[elr_var_str].astype("category") # Converts the groups column to string to ensure that the values are hashable - elr_dataframe_df[elr_groups_str] = elr_dataframe_df[elr_groups_str].astype(str) + elr_dataframe_df[elr_groups] = elr_dataframe_df[elr_groups].astype(str) if model_type.lower() == "linear": # Mixed linear model using MixedLM (following your function) elr_model_obj = smf.mixedlm( formula=elr_formula_str, data=elr_dataframe_df, - groups=elr_dataframe_df[elr_groups_str], + groups=elr_dataframe_df[elr_groups], ) elr_result_obj = elr_model_obj.fit() @@ -1153,12 +2124,11 @@ def execute_glmm_regression( "p-value": pvalues.values, } ) - elif model_type.lower() == "logistic": # Mixed logistic model using BinomialBayesMixedGLM (Bayesian approach via VB) # Defines vc_formula for random effect (random intercept per group) - vc_formula = {elr_groups_str: "0 + C({})".format(elr_groups_str)} + vc_formula = {elr_groups: "0 + C({})".format(elr_groups)} elr_model_obj = BinomialBayesMixedGLM.from_formula( formula=elr_formula_str, vc_formulas=vc_formula, data=elr_dataframe_df @@ -1310,31 +2280,49 @@ def elr_parse_variable_name(var_name): def execute_glm_regression( - elr_dataframe_df, - elr_outcome_str, - elr_predictors_list, - model_type="linear", - print_results=True, - labels=False, - reg_type="Multi", -): - """ - Executes a GLM (Generalized Linear Model) for linear or logistic regression. - - Parameters: - - elr_dataframe_df: Pandas DataFrame containing the data. - - elr_outcome_str: Name of the response variable. - - elr_predictors_list: List of predictor variable names. - - model_type: 'linear' for linear regression (Gaussian) or 'logistic' for - logistic regression (Binomial). - - print_results: If True, prints the results table. - - labels: (Optional) Dictionary to map variable names to readable labels. - - reg_type: Type of regression ('uni' or 'multi') to rename the output columns. - - Returns: - - summary_df: DataFrame with the model results. - """ - + elr_dataframe_df: pandas.DataFrame, + elr_outcome: str, + elr_predictors: typing.Iterable, + model_type: str = "linear", + print_results: bool = True, + labels: dict[str, str] | None = None, + reg_type: str = "Multi", +) -> pandas.DataFrame: + """:py:class:`pandas.DataFrame` : Executes a GLM (Generalized Linear Model) for linear or logistic regression. + + Parameters + ---------- + elr_dataframe_df : pandas.DataFrame + The incoming data. + + elr_outcome : str + Name of the response variable. + + elr_predictors: typing.Iterable + Iterable of predictor variable names. + + model_type : str, default="linear" + Optional indicator regression model type - use ``"linear"`` for linear + regression (Gaussian) or ``"logistic"`` for logistic regression + (Binomial); defaults to ``"linear"``. + + print_results : bool, default=True + Optional indicator of whether to print the results table, defaults to + ``True``. + + labels : dict, default=None + Optional map of variable names to readable labels, defaults to + ``None``.`. + + reg_type : str, default="multi" + Optional regression type - ``"uni"`` for univariate, ``"multi"`` for + multivariate. Defaults to ``"multi"``. + + Returns + -------- + pandas.DataFrame + The model results. + """ # noqa : E501 # Defines the family according to model_type if model_type.lower() == "logistic": family = sm.families.Binomial() @@ -1344,12 +2332,12 @@ def execute_glm_regression( raise ValueError("model_type must be 'linear' or 'logistic'") # Builds the formula - formula = elr_outcome_str + " ~ " + " + ".join(elr_predictors_list) + formula = elr_outcome + " ~ " + " + ".join(elr_predictors) # Converts categorical variables to 'category' type categorical_vars = elr_dataframe_df.select_dtypes( include=["object", "category"] - ).columns.intersection(elr_predictors_list) + ).columns.intersection(elr_predictors) for var in categorical_vars: elr_dataframe_df[var] = elr_dataframe_df[var].astype("category") @@ -1478,50 +2466,63 @@ def parse_variable_name(var_name): return summary_df -def execute_cox_model(df, duration_col, event_col, predictors, labels=None): - """ - Performs a Cox Proportional Hazards model without weights and - returns a summary of the results. - - Parameters: - - df: Pandas DataFrame containing the data. - - duration_col: String with the name of the time variable. - - event_col: String with the name of the outcome variable (binary event). - - predictors: List of strings with the names of predictor variables. - - labels (Optional): - Dictionary mapping variable names to readable labels. - Default is None. - - Returns: - - summary_df: DataFrame with the results of the Cox model. - """ +def execute_cox_model( + data: pandas.DataFrame, + duration_col: str, + event_col: str, + predictors: typing.Iterable[str], + labels: dict[str, str] | None = None, +) -> pandas.DataFrame: + """:py:class:`pandas.DataFrame` : Executes a Cox Proportional Hazards model without weights and returns a summary of the results. + + Parameters + ---------- + data : pandas.DataFrame + The incoming data. + + duration_col : str + Name of the time variable. + + event_col : str + Name of the outcome variable (binary event). + predictors : typing.Iterable + Names of predictor variables. + + labels : dict, default=None + Dictionary mapping variable names to readable labels, default=``None``. + + Returns + ------- + pandas.DataFrame + The model results. + """ # noqa : E501 # Ensure categorical variables are treated appropriately - categorical_vars = df.select_dtypes( + categorical_vars = data.select_dtypes( include=["object", "category"] ).columns.intersection(predictors) for var in categorical_vars: - df[var] = df[var].astype("category") + data[var] = data[var].astype("category") # Convert categorical variables to dummies - df = pd.get_dummies(df, columns=categorical_vars, drop_first=True) + data = pd.get_dummies(data, columns=categorical_vars, drop_first=True) # Ensure numerical variables have the correct type - df[duration_col] = pd.to_numeric(df[duration_col], errors="coerce") - df[event_col] = pd.to_numeric(df[event_col], errors="coerce") + data[duration_col] = pd.to_numeric(data[duration_col], errors="coerce") + data[event_col] = pd.to_numeric(data[event_col], errors="coerce") # Update predictors to include one-hot encoded columns predictors = [ c - for c in df.columns + for c in data.columns if c in predictors or any(c.startswith(p + "_") for p in categorical_vars) ] # Remove rows with missing values in essential columns - df = df.dropna(subset=[duration_col, event_col] + predictors) + data = data.dropna(subset=[duration_col, event_col] + predictors) # Select relevant columns - df_cox = df[[duration_col, event_col] + predictors] + df_cox = data[[duration_col, event_col] + predictors] # Fit the Cox model cph = CoxPHFitter() @@ -1549,19 +2550,54 @@ def execute_cox_model(df, duration_col, event_col, predictors, labels=None): return summary_df -def execute_kaplan_meier(df, duration_col, event_col, group_col, alpha=0.05, n_times=5): +def execute_kaplan_meier( + data: pandas.DataFrame, + duration_col: str, + event_col: str, + group_col: str, + alpha=0.05, + n_times=5, +) -> tuple[pandas.DataFrame, pandas.DataFrame, float]: + """:py:class:`tuple` : Executes the Kaplan-Meier model and returns the results. + + Parameters + ---------- + data : pandas.DataFrame + The incoming data. + + duration_col : str + Name of the time variable. + + event_col : str + Name of the outcome variable (binary event). + + group_col : str + Name of the grouping column. + + alpha : float, default=0.05 + Optional alpha, defaults to :math:`0.05`. + + n_times : int, default=5 + Optional. No description available, defaults to :math:`5`. + + Returns + ------- + pandas.DataFrame + A tuple consisting of the model results, risk table and the + :math:`p`-value. + """ # noqa : E501 # Remove rows with missing values in relevant columns - df = df.dropna(subset=[duration_col, event_col, group_col]) + data = data.dropna(subset=[duration_col, event_col, group_col]) kmf = KaplanMeierFitter() - unique_groups = df[group_col].sort_values().unique() + unique_groups = data[group_col].sort_values().unique() df_km = pd.DataFrame(columns=["timeline"]) - max_time = (df[duration_col].max() // n_times) * (n_times + 1) + max_time = (data[duration_col].max() // n_times) * (n_times + 1) times = np.arange(0, max_time, n_times) # Compute survival curves and confidence intervals for each group for group in unique_groups: - group_data = df[df[group_col] == group] + group_data = data[data[group_col] == group] kmf.fit( group_data[duration_col], event_observed=group_data[event_col], @@ -1584,8 +2620,8 @@ def execute_kaplan_meier(df, duration_col, event_col, group_col, alpha=0.05, n_t # Perform log-rank test if len(unique_groups) == 2: - group1_data = df[df[group_col] == unique_groups[0]] - group2_data = df[df[group_col] == unique_groups[1]] + group1_data = data[data[group_col] == unique_groups[0]] + group2_data = data[data[group_col] == unique_groups[1]] result = logrank_test( group1_data[duration_col], group2_data[duration_col], @@ -1595,7 +2631,7 @@ def execute_kaplan_meier(df, duration_col, event_col, group_col, alpha=0.05, n_t p_value = result.p_value elif len(unique_groups) > 2: result = multivariate_logrank_test( - df[duration_col], df[group_col], df[event_col] + data[duration_col], data[group_col], data[event_col] ) p_value = result.p_value else: @@ -1604,7 +2640,8 @@ def execute_kaplan_meier(df, duration_col, event_col, group_col, alpha=0.05, n_t # Generate risk table: number of individuals at risk over time risk_counts = { group: [ - ((df[group_col] == group) & (df[duration_col] >= t)).sum() for t in times + ((data[group_col] == group) & (data[duration_col] >= t)).sum() + for t in times ] for group in unique_groups } @@ -1625,108 +2662,144 @@ def execute_kaplan_meier(df, duration_col, event_col, group_col, alpha=0.05, n_t def impute_miss_val( - df, - dictionary, - outcome_column="outco_binary_outcome", - missing_threshold=0.7, - verbose=False, -): - """ + data: pandas.DataFrame, + dictionary: pandas.DataFrame, + outcome_column: str = "outco_binary_outcome", + missing_threshold: float = 0.7, + verbose: bool = False, +) -> pandas.DataFrame: + """:py:class:`pandas.DataFrame` : The data with missing values imputed. + Imputes missing values or drops columns based on missing value proportion - and median + and median. - Returns: - - df: DataFrame with missing values imputed or columns dropped - """ + Parameters + ---------- + data : pandas.DataFrame + The incoming data. + + dictionary : pandas.DataFrame + The data dictionary. + + outcome_column : str, default="outco_binary_outcome" + Optional outcome column, defaults to ``"outco_binary_outcome"``. + + missing_threshold : float, default=0.7 + A proportional imputation threshold for missing values, defaults to + :math:`0.7`. + + verbose, bool=False + Optional indicator of whether to print imputations summary, defaults + to ``False``. + + Returns + ------- + pandas.DataFrame + Data with missing values imputed or columns dropped. + """ # noqa : E501 keep_columns = ["subjid", outcome_column] numeric_ind = dictionary["field_type"] == "numeric" numeric_columns = dictionary.loc[numeric_ind, "field_name"].tolist() - numeric_columns = [col for col in numeric_columns if col in df.columns] + numeric_columns = [col for col in numeric_columns if col in data.columns] binary_ind = dictionary["field_type"] == "binary" binary_columns = dictionary.loc[binary_ind, "field_name"].tolist() - binary_columns = [col for col in binary_columns if col in df.columns] + binary_columns = [col for col in binary_columns if col in data.columns] categorical_ind = dictionary["field_type"].isin(["binary"]) categorical_columns = dictionary.loc[categorical_ind, "field_name"].tolist() - categorical_columns = [col for col in categorical_columns if col in df.columns] + categorical_columns = [col for col in categorical_columns if col in data.columns] # Calculate the proportion of missing values in each column - missing_proportions = df.isnull().mean() + missing_proportions = data.isnull().mean() # Identify columns to drop columns_to_drop = missing_proportions[ (missing_proportions > missing_threshold) ].index.tolist() columns_to_drop = [col for col in columns_to_drop if col not in keep_columns] - df = df.drop(columns=columns_to_drop) + data = data.drop(columns=columns_to_drop) - impute_columns = [col for col in df.columns if col not in keep_columns] + impute_columns = [col for col in data.columns if col not in keep_columns] # Impute missing values in remaining columns for col in impute_columns: if col in numeric_columns: - df[col] = df[col].fillna(df[col].median()) + data[col] = data[col].fillna(data[col].median()) if col in (binary_columns + categorical_columns): - df[col] = df[col].fillna(df[col].mode().values[0]) + data[col] = data[col].fillna(data[col].mode().values[0]) if verbose: print("\nSummary after Imputation") - print("Size of remaining data:", df.shape) - return df + print("Size of remaining data:", data.shape) + return data -def rmv_low_var( - df, - dictionary, - mad_threshold=0.1, - freq_threshold=0.05, - outcome_column="outco_binary_outcome", - verbose=False, -): - """ - Removes numerical variables with Median Absolute Deviation (MAD) below a - threshold. - Excludes binary columns from MAD calculation. - Removes binary columns with very low frequencies - Returns: - - df: pandas DataFrame with low MAD columns removed - """ +def rmv_low_var( + data: pandas.DataFrame, + dictionary: pandas.DataFrame, + mad_threshold: float = 0.1, + freq_threshold: float = 0.05, + outcome_column: str = "outco_binary_outcome", + verbose: bool = False, +) -> pandas.DataFrame: + """:py:class:`pandas.DataFrame` : Removes numerical variables from the data with Median Absolute Deviation (MAD) below a given threshold. + + Excludes binary columns from MAD calculation. Removes binary columns with + very low frequencies. + + Parameters + ---------- + data : pandas.DataFrame + The incoming data. + + dictionary : pandas.DataFrame + The data dictionary. + + mad_threshold : float, default=0.1 + Optional MAD threshold, defaults to :math:`0.1`. + + freq_threshold : float, default=0.5 + Optional frequency threshold, defaults to :math:`0.05`. + + outcome_column : str, default=``"outco_binary_outcome"`` + Optional outcome column, defaults to ``"outco_binary_outcome"``. + + verbose : bool, default=False + Optional indicator of whether to print MAD analysis summary. + + Returns + ------- + pandas.DataFrame + The data with low MAD columns removed. + """ # noqa : E501 keep_columns = ["subjid", outcome_column] numeric_ind = dictionary["field_type"] == "numeric" numeric_columns = dictionary.loc[numeric_ind, "field_name"].tolist() - numeric_columns = [col for col in numeric_columns if col in df.columns] + numeric_columns = [col for col in numeric_columns if col in data.columns] binary_ind = dictionary["field_type"] == "binary" binary_columns = dictionary.loc[binary_ind, "field_name"].tolist() - binary_columns = [col for col in binary_columns if col in df.columns] + binary_columns = [col for col in binary_columns if col in data.columns] # Remove single-valued columns first - single_value_columns = df.columns[df.nunique() == 1] + single_value_columns = data.columns[data.nunique() == 1] single_value_columns = [ col for col in single_value_columns if col not in keep_columns ] - df = df.drop(columns=single_value_columns) - - # Select numeric columns - # numeric_columns = df.select_dtypes(include=[np.number]).columns - - # Select numeric columns and identify binary columns - # numeric_cols = df.select_dtypes(include=[np.number]).columns - # binary_cols = df.columns[df.nunique() == 2] - # non_binary_cols = numeric_cols.difference(binary_cols) + data = data.drop(columns=single_value_columns) # Calculate low frequency binary numeric column # Handle binary columns - convert to numeric first - binary_counts = df[binary_columns].mean(axis=0) + binary_counts = data[binary_columns].mean(axis=0) binary_counts = binary_counts.apply(lambda x: min((x, 1 - x))) exclude_binary_columns = [ col for col in binary_columns if (binary_counts[col] < freq_threshold) ] mad_series = ( - df[numeric_columns] + data[numeric_columns] .apply(lambda x: x / x.abs().max(), axis=0) .apply(lambda x: np.median(np.abs(x - np.median(x)))) ) @@ -1740,8 +2813,8 @@ def rmv_low_var( # 3. Non-binary numeric columns with MAD above threshold # Start with all CAT columns exclude_columns = exclude_binary_columns + exclude_numeric_columns - keep_columns = [col for col in df.columns if col not in exclude_columns] - df = df[keep_columns] + keep_columns = [col for col in data.columns if col not in exclude_columns] + data = data[keep_columns] if verbose: print("\nMAD Analysis Summary:") @@ -1752,33 +2825,53 @@ def rmv_low_var( {len(binary_columns) - len(exclude_binary_columns)}""") print(f"""Columns removed due to low MAD: \ {len(numeric_columns) - len(exclude_numeric_columns)}""") - return df + return data -def rmv_high_corr( - df, - dictionary, - outcome_column="outco_binary_outcome", - correlation_threshold=0.5, - verbose=False, -): - """ - Removes variables if there is high multicollinearity, arbitrarily selecting - one variable to remove if the correlation between two variables is above - a threshold. - Returns: - - df: pandas DataFrame with high correlation variables removed - """ +def rmv_high_corr( + data: pandas.DataFrame, + dictionary: pandas.DataFrame, + outcome_column: str = "outco_binary_outcome", + correlation_threshold: float = 0.5, + verbose: bool = False, +) -> pandas.DataFrame: + """:py:class:`pandas.DataFrame` : Removes variables in the data with high multicollinearity. + + Arbitrarily selecting one variable to remove if the correlation between two + variables is above a threshold. + + Parameters + ---------- + data : pandas.DataFrame + The incoming data. + + dictionary : pandas.DataFrame + The data dictionary. + + outcome_column : str, default=``"outco_binary_outcome"`` + Optional outcome column, defaults to ``"outco_binary_outcome"``. + + correlation_threshold : float, default=0.5 + Optional correlation threshold, defaults to :math:`0.5`. + + verbose : bool, default=False + Optional indicator of whether to print correlation summary. + + Returns + ------- + pandas.DataFrame + The data with high correlation variables removed. + """ # noqa : E501 keep_columns = ["subjid", outcome_column] numeric_ind = dictionary["field_type"] == "numeric" numeric_columns = dictionary.loc[numeric_ind, "field_name"].tolist() - numeric_columns = [col for col in numeric_columns if col in df.columns] + numeric_columns = [col for col in numeric_columns if col in data.columns] # Step 1: Select numeric columns only # numeric_cols = df.select_dtypes(include=[np.number]).columns - df_numeric = df[numeric_columns] # DataFrame with only numeric columns + df_numeric = data[numeric_columns] # DataFrame with only numeric columns # Step 2: Calculate the correlation matrix corr_matrix = df_numeric.corr().abs() @@ -1794,57 +2887,78 @@ def rmv_high_corr( # Step 4: Drop highly correlated columns (arbitrarily drop second column) exclude_columns = corr_pairs["level_1"].unique().tolist() exclude_columns = [col for col in exclude_columns if col not in keep_columns] - - # # Step 3: Identify highly correlated columns with a double loop - # to_drop = set() # Use a set to avoid duplicates - # num_cols = corr_matrix.shape[0] - # - # for i in range(num_cols): - # for j in range(i + 1, num_cols): # Only look at the upper triangle - # if corr_matrix.iloc[i, j] > correlation_threshold: - # # Identify the columns with high correlation - # # col1 = corr_matrix.columns[i] # ?? - # col2 = corr_matrix.columns[j] - # - # # Add one of the columns to `to_drop` - # to_drop.add(col2) # Arbitrarily drop the second column - # - # # Step 4: Drop highly correlated columns - # exclude_columns = [col for col in list(to_drop) if col not in keep_columns] - df = df.drop(columns=exclude_columns) + data = data.drop(columns=exclude_columns) if verbose: print("\nCORR Summary") print(f"Columns removed due to high correlation: \ {len(exclude_columns)}") - return df + + return data def lasso_var_sel_binary( - df, - outcome_column="mapped_outcome", - metric="balanced_accuracy", - threshold=1e-3, - gridsearch_params={ + data: pandas.DataFrame, + outcome_column: str = "mapped_outcome", + metric: str = "balanced_accuracy", + threshold: float = 1e-3, + gridsearch_params: dict[str, typing.Iterable[float]] = { "l1_ratios": [0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9], "Cs": [1e-3, 3.16e-3, 1e-2, 3.16e-2, 1e-1, 3.16e-1, 1, 3.16, 10], }, - random_state=42, - verbose=False, - sep="___", -): - """ - Prepare data and select features using binary logistic regression with - elastic net penalty. + random_state: int = 42, + verbose: bool = False, + sep: str = "___", +) -> tuple[typing.Any]: + """:py:class:`tuple` : Prepares data and selects features using binary logistic regression with elastic net penalty. + Specifically designed for binary outcomes only. - """ - if outcome_column not in df.columns: + + Parameters + ---------- + data : pandas.DataFrame + The incoming data. + + outcome_column : str, default="mapped_outcome" + Optional outcome column, defaults to ``"mapped_outcome"``. + + metric : str, default="balanced_accuracy" + Optional metric, defaults to ``"balanced_accuracy"``. + + threshold : float, default=1e-3 + Optional threshold, defaults to :math:`0.001`. + + gridsearch_params : dict, default={"l1_ratios": [0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9], "Cs": [1e-3, 3.16e-3, 1e-2, 3.16e-2, 1e-1, 3.16e-1, 1, 3.16, 10]} + Optional grid search params, defaults to: + :: + + { + "l1_ratios": [0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9], + "Cs": [1e-3, 3.16e-3, 1e-2, 3.16e-2, 1e-1, 3.16e-1, 1, 3.16, 10] + } + + random_state : int, default=42 + Optional random state, defaults to :math:`42`. + + verbose : bool, default=False + Optional indicator of whether to print the analysis, defaults to + ``False``. + + sep : str, default="___" + Optional field-value separator, defaults to ``"___"``. + + Returns + ------- + tuple + Results tuple. + """ # noqa : E501 + if outcome_column not in data.columns: error_str = f"Outcome column {outcome_column} not found in DataFrame" raise ValueError(error_str) # Separate predictors and outcome - y = df[outcome_column].copy() - X_ini = df.drop(columns=[outcome_column]) + y = data[outcome_column].copy() + X_ini = data.drop(columns=[outcome_column]) if verbose: print(f"\nInitial shape of X: {X_ini.shape}") @@ -2067,11 +3181,32 @@ def lasso_var_sel_binary( ) -def create_grouped_results(selected_features, feature_importance, sep="___"): - """ - Create a DataFrame with all categories listed under their main fields, - with main fields sorted by their maximum coefficient magnitude. - """ +def create_grouped_results( + selected_features: typing.Iterable[str], + feature_importance: dict[str, float], + sep: str = "___", +) -> tuple[pd.DataFrame, typing.Iterable[str], typing.Iterable[str]]: + """:py:class:`tuple` : Creates and returns grouped feature results. + + The main dataFrame lists categories under their main fields, with main + fields sorted by their maximum coefficient magnitude. + + Parameters + ---------- + selected_features : typing.Iterable + An iterable of selected feature names. + + feature_importance : dict + A dict of feature names and coefficient weights. + + sep : str, default="___" + Optional field-value separator, defaults to ``"___"``. + + Returns + ---------- + tuple + Feature results. + """ # noqa : E501 # Step 1: Identify one-hot encoded and regular features categorical_fields = set() regular_features = [] @@ -2146,11 +3281,27 @@ def create_grouped_results(selected_features, feature_importance, sep="___"): return pd.DataFrame(results), sorted_fields, categorical_fields -def get_parameter_ranking(logistic, n_top=10, threshold=1e-3): - """ - Create a ranking of parameter combinations using stored scores - and coefficient paths. - """ +def get_parameter_ranking( + logistic: typing.Any, n_top: int = 10, threshold: float = 1e-3 +) -> pandas.DataFrame: + """:py:class:pd.DataFrame : Returns a dataframe of rankings of parameter combinations using stored scores and coefficient paths. + + Parameters + ---------- + logistic : typing.Any + The logistic model. + + n_top : int, default=10 + Optional number of top ranking features to select, defaults to :math:`10`. + + threshold : float, default=1e-3 + Optional ranking threshold, defaults to :math:`0.001`. + + Returns + ------- + pandas.DataFrame + The dataframe of parameter rankings. + """ # noqa : E501 # Create empty list to store parameter information param_scores = [] @@ -2167,16 +3318,12 @@ def get_parameter_ranking(logistic, n_top=10, threshold=1e-3): for C_idx, C in enumerate(Cs): # Get mean score across folds for this parameter combination score = logistic.scores_[first_class][:, C_idx, l1_ratio_idx].mean() - # fold_ind = ( - # logistic.scores_[first_class][:, C_idx, l1_ratio_idx].argmax()) + # Get coefficients for this parameter combination coef0 = logistic.coefs_paths_[first_class][0, C_idx, l1_ratio_idx, :] coef1 = logistic.coefs_paths_[first_class][1, C_idx, l1_ratio_idx, :] coef2 = logistic.coefs_paths_[first_class][2, C_idx, l1_ratio_idx, :] - # # Average across folds # Why is this the mean? - # mean_coef = np.mean(coef_path, axis=0) - # Count non-zero coefficients n_features0 = np.sum(np.abs(coef0) > threshold) n_features1 = np.sum(np.abs(coef1) > threshold) diff --git a/isaricanalytics/getREDCapData.py b/isaricanalytics/redcap_data.py similarity index 55% rename from isaricanalytics/getREDCapData.py rename to isaricanalytics/redcap_data.py index 459c292..53eb247 100644 --- a/isaricanalytics/getREDCapData.py +++ b/isaricanalytics/redcap_data.py @@ -1,22 +1,86 @@ +from __future__ import annotations + +__all__ = [ + "add_answer_dict", + "add_onehot_variables", + "combine_unlisted_variables", + "convert_dictionary_field_type", + "convert_onehot_to_binary", + "get_branching_logic_variables", + "get_data_dictionary", + "get_df_forms", + "get_df_map", + "get_events_and_forms_info", + "get_form_event", + "get_label", + "get_labels", + "get_missing_data_codes", + "get_records", + "get_redcap_data", + "get_section_prefix", + "get_value", + "get_values", + "harmonise_age", + "homogenise_variables", + "initial_data_processing", + "is_unlisted_item", + "is_yesno", + "is_yesno_question", + "list_categorical_onehot_columns", + "list_checkbox_onehot_columns", + "load_countries_table", + "load_units_conversion_table", + "map_variable", + "rename_checkbox_variables", + "replace_with_nan_for_missing_code_checkbox", + "resolve_checkbox_branching_logic", + "user_assigned_to_dag", +] + + +# -- IMPORTS -- + +# -- Standard libraries -- import io import time +import typing +import warnings from pathlib import Path +# -- 3rd party libraries -- import numpy as np -import pandas as pd +import pandas import requests +# -- Internal libraries -- from isaricanalytics.logging.logger import setup_logger logger = setup_logger(__name__) +pd = pandas # An alias to allow Pandas code refs to work independently +# of Pandas Intersphinx refs in type hinting and docstrings ############################################ -# Functions that call to the API +# API-calling functions ############################################ -def user_assigned_to_dag(redcap_url, redcap_api_key): +def user_assigned_to_dag(redcap_url: str, redcap_api_key: str) -> bool: + """:py:class:`bool` : Whether the user is assigned to a data access group (DAG). + + Parameters + ---------- + redcap_url : str + REDCap URL. + + redcap_api_key : str + REDCap API key. + + Returns + ------- + bool + Whether the user is assigned to a REDCap DAG. + """ conex = { "token": redcap_api_key, "content": "dag", @@ -24,15 +88,39 @@ def user_assigned_to_dag(redcap_url, redcap_api_key): "returnFormat": "json", } response = requests.post(redcap_url, data=conex) - output = response.status_code == 403 - return output + + return response.status_code == 403 def get_records( - redcap_url, redcap_api_key, data_access_groups=None, user_assigned_to_dag=False -): - """Fetch records from the REDCap API""" + redcap_url: str, + redcap_api_key: str, + data_access_groups: typing.Iterable[str] | None = None, + user_assigned_to_dag: bool = False, +) -> pandas.DataFrame: + """:py:class:`pandas.DataFrame` : Returns a dataframe of records from the REDCap API. + + Parameters + ---------- + redcap_url : str + REDCap URL. + + redcap_api_key : str + REDCap API key. + + data_access_groups : typing.Iterable, default=None + An iterable of data access group names. + + user_assigned_to_dag : bool, default=False + Whether the user is assigned to a data access group (DAG). + + Returns + ------- + pandas.DataFrame + Records from the REDCap API data. + """ # noqa : E501 started = time.perf_counter() + if (data_access_groups is None) or (user_assigned_to_dag is False): logger.info("REDCap records export: requesting all records") conex = { @@ -51,18 +139,19 @@ def get_records( } response = requests.post(redcap_url, data=conex) logger.debug("HTTP Status: " + str(response.status_code)) - df = pd.read_csv( + data = pd.read_csv( io.StringIO(response.text), dtype={"subjid": "str"}, keep_default_na=False ) if data_access_groups is not None: - ind = df["redcap_data_access_group"].isin(data_access_groups) - df = df.loc[ind].reset_index(drop=True) + ind = data["redcap_data_access_group"].isin(data_access_groups) + data = data.loc[ind].reset_index(drop=True) else: logger.info( "REDCap records export: requesting DAG-scoped records for " f"{len(data_access_groups)} DAG(s)" ) df_list = [] + for dag in data_access_groups: unique_group = dag.replace("-", "").replace(" ", "_").lower()[:18] conex = { @@ -75,8 +164,8 @@ def get_records( response = requests.post(redcap_url, data=conex) if response.text != "1": logger.warning( - f"Data access group ID: {dag}. Warning: Could not \ -switch DAG to unique group name: {unique_group}" + f"Data access group ID: {dag}. Warning: Could not" + f"switch DAG to unique group name: {unique_group}" ) continue conex = { @@ -114,19 +203,35 @@ def get_records( ) continue if len(df_list) > 0: - df = pd.concat(df_list, axis=0) + data = pd.concat(df_list, axis=0) else: - df = None + data = None + elapsed = time.perf_counter() - started - row_count = 0 if df is None else len(df) + row_count = 0 if data is None else len(data) logger.info( f"REDCap records export complete in {elapsed:.1f}s " f"(rows={row_count})" ) - return df + return data + + +def get_data_dictionary(redcap_url: str, redcap_api_key: str) -> pandas.DataFrame: + """:py:class:`pandas.DataFrame` : Returns a data dictionary from the REDCap API. + + Parameters + ---------- + redcap_url : str + REDCap URL. -def get_data_dictionary(redcap_url, redcap_api_key): - """Fetch the data dictionary from the REDCap API""" + redcap_api_key : str + REDCap API key. + + Returns + ------- + pandas.DataFrame + Data dictionary from the REDCap API. + """ conex = { "token": redcap_api_key, "content": "metadata", @@ -135,13 +240,26 @@ def get_data_dictionary(redcap_url, redcap_api_key): } # Make the API request response = requests.post(redcap_url, data=conex) - df = pd.read_csv(io.StringIO(response.text), keep_default_na=False) - return df + return pd.read_csv(io.StringIO(response.text), keep_default_na=False) -def get_form_event(redcap_url, redcap_api_key): - """Get events, forms and their mapppings from the REDCap API and merge - into a single dataframe.""" + +def get_events_and_forms_info(redcap_url: str, redcap_api_key: str) -> pandas.DataFrame: + """:py:class:`pandas.DataFrame` : Returns a combined dataframe of events, forms and their mapppings from the REDCap API. + + Parameters + ---------- + redcap_url : str + REDCap URL. + + redcap_api_key : str + REDCap API key. + + Returns + ------- + pandas.DataFrame + Events, forms and their mapppings from the REDCap API. + """ # noqa: E501 conex = { "token": redcap_api_key, "content": "event", @@ -163,6 +281,7 @@ def get_form_event(redcap_url, redcap_api_key): "format": "csv", "returnFormat": "json", } + # Make the API request response = requests.post(redcap_url, data=conex) if response.status_code == 200: @@ -180,6 +299,7 @@ def get_form_event(redcap_url, redcap_api_key): "format": "csv", "returnFormat": "json", } + # Make the API request response = requests.post(redcap_url, data=conex) if response.status_code == 200: @@ -199,50 +319,195 @@ def get_form_event(redcap_url, redcap_api_key): form_event = pd.merge( form_event, event, on=["unique_event_name", "arm_num"], how="left" ) + return form, form_event -def get_missing_data_codes(redcap_url, redcap_api_key): - """Get missing data codes from REDCAP API, using the project metadata""" +def get_form_event(redcap_url: str, redcap_api_key: str) -> pandas.DataFrame: + """:py:class:`pandas.DataFrame` : Returns a combined dataframe of events, forms and their mapppings from the REDCap API. + + .. warning:: + + DEPRECATED. + + Parameters + ---------- + redcap_url : str + REDCap URL. + + redcap_api_key : str + REDCap API key. + + Returns + ------- + pandas.DataFrame + Events, forms and their mapppings from the REDCap API. + """ # noqa: E501 + warnings.warn( + ( + "`redcap_data.get_form_event` is deprecated; " + "use `redcap_data.get_events_and_forms_info` instead." + ), + DeprecationWarning, + stacklevel=2, + ) + + return get_events_and_forms_info(redcap_url, redcap_api_key) + + +def get_missing_data_codes(redcap_url: str, redcap_api_key: str) -> dict[str, str]: + """:py:class:`dict` : Returns missing data codes from the REDCAP API, using the project metadata. + + Parameters + ---------- + redcap_url : str + REDCap URL. + + redcap_api_key : str + REDCap API key. + + Returns + ------- + dict + A dict of missing data codes from the REDCap API, using the project + metadata. An empty dict is returned in the case there are no missing + data codes. + + """ # noqa: E501 conex = { "token": redcap_api_key, "content": "project", "format": "csv", "returnFormat": "json", } + response = requests.post(redcap_url, data=conex) - df = pd.read_csv(io.StringIO(response.text), keep_default_na=False) - if df["missing_data_codes"].isna().all(): - missing_data_codes = dict() + + data = pd.read_csv(io.StringIO(response.text), keep_default_na=False) + + if data["missing_data_codes"].isna().all(): + return dict() else: - missing_data_codes = df["missing_data_codes"].values[0] - missing_data_codes = dict( + missing_data_codes = data["missing_data_codes"].values[0] + return dict( zip( [x.split(",")[1].strip() for x in missing_data_codes.split("|")], [x.split(",")[0].strip() for x in missing_data_codes.split("|")], ) ) - return missing_data_codes -############################################ -# Functions for processing the data dictionary -############################################ +########################################################## +# Functions related to the data dictionary +########################################################## + + +def get_values(x: typing.Iterable[str]) -> list[str]: + """:py:class:`list` : Returns a list of values. + + Parameters + ---------- + x : typing.Iterable + An iterable of value tuples. + + Returns + ------- + list + A list of values. + """ + return [y.split(",")[0] for y in x] + +def get_value(x: typing.Iterable[str]) -> list[str]: + """:py:class:`list` : Returns a list of values. -def get_value(x): - values = [y.split(",")[0] for y in x] - return values + .. warning:: + DEPRECATED. -def get_label(x): - labels = [",".join(y.split(",")[1:]).strip() for y in x] - return labels + Parameters + ---------- + x : typing.Iterable + An iterable of value tuples. + Returns + ------- + list + A list of values. + """ + warnings.warn( + ( + "`redcap_data.get_value` is deprecated; " + "use `redcap_data.get_values` instead." + ), + DeprecationWarning, + stacklevel=2, + ) + + return get_values(x) + + +def get_labels(x: typing.Iterable[str]) -> list[str]: + """:py:class:`list` : Returns a list of labels. + + Parameters + ---------- + x : typing.Iterable + An iterable of label tuples. + + Returns + ------- + list + A list of labels. + """ + return [",".join(y.split(",")[1:]).strip() for y in x] + + +def get_label(x: typing.Iterable[str]) -> list[str]: + """:py:class:`list` : Returns a list of labels. + + .. warning:: + + DEPRECATED. -def add_answer_dict(dictionary): - """Add a lookup dict of labels/values to the dictionary from REDCap schema. - By default, ignore Yes/No/Unknown radio variables.""" + Parameters + ---------- + x : typing.Iterable + An iterable of label tuples. + + Returns + ------- + list + A list of labels. + """ + warnings.warn( + ( + "`redcap_data.get_label` is deprecated; " + "use `redcap_data.get_labels` instead." + ), + DeprecationWarning, + stacklevel=2, + ) + + return get_labels(x) + + +def add_answer_dict(dictionary: pandas.DataFrame) -> pandas.DataFrame: + """:py:class:`pandas.DataFrame` : Returns the REDCap schema data dictionary with a lookup dict of labels and values. + + By default, ignores Yes/No/Unknown radio variables. + + Parameters + ---------- + dictionary : pandas.DataFrame + REDCap schema data dictionary. + + Returns + ------- + pandas.DataFrame + An updated REDCap schema data dictionary with a lookup dict of labels + and values. + """ # noqa: E501 new_dictionary = dictionary.copy() # Get categories from dictionary answers = new_dictionary["select_choices_or_calculations"].copy() @@ -262,34 +527,107 @@ def add_answer_dict(dictionary): answers = answers.apply(lambda x: dict(zip(get_label(x), get_value(x)))) answers.name = "answer_dict" new_dictionary = pd.concat([new_dictionary, answers], axis=1) + return new_dictionary -def list_categorical_onehot_columns(dictionary_row, data, sep="___"): +def list_categorical_onehot_columns( + dictionary_row: dict[str, typing.Any], data: pandas.DataFrame, sep: str = "___" +) -> list[str]: + """:py:class:`list` Returns a list of categorical onehot-encoded columns in the given dataframe. + + Parameters + ---------- + dictionary_row : dict + A row of the data dictionary. + + data : pandas.DataFrame + The incoming data. + + sep : str, default="___" + Separator of field/variable name and value in the list. + + Returns + ------- + list + A list of categorical onehot-encoded columns in the given dataframe. + """ # noqa: E501 variable = dictionary_row["field_name"] answers = dictionary_row["answer_dict"].keys() - output = [variable + sep + y for y in answers if y in data[variable].values] - return output + return [variable + sep + y for y in answers if y in data[variable].values] + + +def list_checkbox_onehot_columns( + dictionary_row: dict[str, typing.Any], data: pandas.DataFrame, sep: str = "___" +) -> list[str]: + """:py:class:`list` Returns a list of checkbox onehot-encoded columns in the given dataframe. + + Parameters + ---------- + dictionary_row : dict + A row of the data dictionary. + + data : pandas.DataFrame + The incoming data. -def list_checkbox_onehot_columns(dictionary_row, data, sep="___"): + sep : str, default="___" + Optional separator of field/variable name and value in the list. + + Returns + ------- + list + A list of checkbox onehot-encoded columns in the given dataframe. + """ # noqa: E501 variable = dictionary_row["field_name"] answers = dictionary_row["answer_dict"].keys() columns = [variable + sep + x for x in answers] - output = [col for col in columns if col in data.columns] - return output + + return [col for col in columns if col in data.columns] -def get_section_prefix(x): - output = x.split("_data")[-1] if x.startswith("daily") else x.split("_")[0] - return output +def get_section_prefix(x: str) -> str: + """:py:class:`str` : Returns the section prefix. + Parameters + ---------- + x : str + Section name/value. + + Returns + ------- + str + The section prefix. + """ + return x.split("_data")[-1] if x.startswith("daily") else x.split("_")[0] -def add_onehot_variables(data, dictionary, sep="___"): - """Add new rows to the dictionary for onehot-encoded categorical variables, + +def add_onehot_variables( + data: pandas.DataFrame, dictionary: pandas.DataFrame, sep: str = "___" +) -> pandas.DataFrame: + """:py:class:`pandas.DataFrame` : Returns the data dictionary with rows for onehot-encoded categorical variables. + + Add new rows to the dictionary for onehot-encoded categorical variables, using only the answers that exist within the data, e.g. if checkbox columns exist (after removing columns with only 'Unchecked') or if radio column - answers are present for at least one subjid.""" + answers are present for at least one subjid. + + Parameters + ---------- + data : pandas.DataFrame + The incoming data. + + dictionary : pandas.DataFrame + The data dictionary. + + sep : str, default="___" + Optional separator of field/variable names and values. + + Returns + ------- + pandas.DataFrame + The data dictionary with rows for onehot-encoded categorical variables. + """ # noqa: E501 new_dictionary = dictionary.copy() new_dictionary["parent"] = "" ind = new_dictionary["field_name"].str.contains("_") @@ -356,19 +694,76 @@ def add_onehot_variables(data, dictionary, sep="___"): sections.index -= 0.5 new_dictionary = pd.concat([new_dictionary, sections], axis=0) new_dictionary = new_dictionary.sort_index().reset_index(drop=True) + return new_dictionary -def is_yesno(x): - """Check if a Yes/No/Unknown question. Remove spaces in case of different - versions of the same string.""" - output = x.replace(" ", "") in ("1,Yes|0,No|99,Unknown", "1,Yes|0,No") - # output = output.isin(['1,Yes|0,No|99,Unknown', '1,Yes|0,No']) - return output +def is_yesno_question(x: str) -> str: + """:py:class:`str` : Returns a cleaned version of a Yes/No/Unknown question string. + + Checks if the string is a Yes/No/Unknown question, and removes spaces in + case there are variations in the same string. + + Parameters + ---------- + x : str + A question string. + + Returns + ------- + str + A cleaned version of the string if it is a Yes/No/Unknown question. + Otherwise the original is returned. + """ + return x.replace(" ", "") in ("1,Yes|0,No|99,Unknown", "1,Yes|0,No") + + +def is_yesno(x: str) -> str: + """:py:class:`str` : Returns a cleaned version of a Yes/No/Unknown question string. + + .. warning:: + + DEPRECATED. + + Checks if the string is a Yes/No/Unknown question, and removes spaces in + case there are variations in the same string. + + Parameters + ---------- + x : str + A question string. + + Returns + ------- + str + A cleaned version of the string if it is a Yes/No/Unknown question. + Otherwise the original is returned. + """ + warnings.warn( + ( + "`redcap_data.is_yesno` is deprecated; " + "use `redcap_data.is_yesno_question` instead." + ), + DeprecationWarning, + stacklevel=2, + ) + + return is_yesno_question(x) -def convert_dictionary_field_type(dictionary): - """Get a dictionary of variable types, based on REDCAP structure""" +def convert_dictionary_field_type(dictionary: pandas.DataFrame) -> pandas.DataFrame: + """:py:class:`pandas.DataFrame` : Return a dictionary of variable types, based on REDCAP structure. + + Parameters + ---------- + dictionary : pandas.DataFrame + The REDCap data dictionary. + + Returns + ------- + pandas.DataFrame + a dictionary of variable types, based on REDCAP structure. + """ # noqa : E501 new_dictionary = dictionary.copy() val_column = "text_validation_type_or_show_slider_number" @@ -401,65 +796,116 @@ def convert_dictionary_field_type(dictionary): return new_dictionary -def replace_with_nan_for_missing_code_checkbox(df, missing_data_codes): - """Convert checkbox values to NaN when a missing code checkbox is 'Checked'""" +def replace_with_nan_for_missing_code_checkbox( + data: pandas.DataFrame, missing_data_codes: dict[str, typing.Any] +) -> pandas.DataFrame: + """:py:class:`pandas.DataFrame` : Return the input dataframe with missing code checkbox values converted to NaN. + + Parameters + ---------- + data : pandas.DataFrame + The incoming data. + + missing_data_codes : dict + A dict of missing code keys and values. + + Returns + ------- + pandas.DataFrame + The input dataframe with missing code checkbox values converted to NaN. + """ # noqa : E501 missing_data_values = [x.lower() for x in missing_data_codes.values()] missing_columns = [ - col for col in df.columns if col.split("___")[-1] in missing_data_values + col for col in data.columns if col.split("___")[-1] in missing_data_values ] - nan_mask = (df[missing_columns] == "Checked").T.reset_index() + nan_mask = (data[missing_columns] == "Checked").T.reset_index() nan_mask["index"] = nan_mask["index"].apply(lambda x: x.split("___")[0]) nan_mask = nan_mask.groupby("index").any() - columns = [col for col in df.columns if col.split("___")[0] in nan_mask.index] + columns = [col for col in data.columns if col.split("___")[0] in nan_mask.index] nan_mask = nan_mask.loc[[col.split("___")[0] for col in columns]] nan_mask["column"] = columns nan_mask = nan_mask.set_index("column").T - df[nan_mask] = np.nan - return df + data[nan_mask] = np.nan + + return data ############################################ -# Functions for processing the data +# Data transformations ############################################ -def is_unlisted_item(x): - output = "".join([y for y in x if y.isdigit() is False]).endswith("unlisted_item") - return output +def is_unlisted_item(x: typing.Iterable[str]) -> str: + """:py:class:`str` : + + Parameters + --------- + x : typing.Iterable + An iterable of strings. + + Returns + ------- + str + - + """ + return "".join([y for y in x if y.isdigit() is False]).endswith("unlisted_item") + +def combine_unlisted_variables( + data: pandas.DataFrame, dictionary: pandas.DataFrame, sep: str = "___" +) -> tuple[pandas.DataFrame]: + """:py:class:`tuple` : Combine variables in repetitions of a question. -def combine_unlisted_variables(df, dictionary, sep="___"): - """Combine variables that exist in repeated versions of the same question + Combine variables that exist in repeated versions of the same question (e.g. additional dropdown questions asked after Yes/No/Unknown questions - for established variables) + for established variables). + + Parameters + ---------- + data : pandas.DataFrame + The incoming data. + + dictionary : pandas.DataFrame + The REDCap data dictionary. + + sep : str, default="___" + Optional value separator. + + Returns + ------- + tuple + The update data and data dictionary. """ unlisted_ind = dictionary["field_name"].str.endswith("unlisted") unlisted_columns = dictionary.loc[unlisted_ind, "field_name"] unlisted_item_ind = dictionary["field_name"].apply(is_unlisted_item) unlisted_item_columns = dictionary.loc[unlisted_item_ind, "field_name"] - unlisted_item_columns = [col for col in unlisted_item_columns if col in df.columns] + unlisted_item_columns = [ + col for col in unlisted_item_columns if col in data.columns + ] unlisted_columns_dict = { k: [v for v in unlisted_item_columns if k in v] for k in unlisted_columns } new_dictionary_list = [] + for ind in unlisted_columns.index: column = dictionary.loc[ind, "field_name"] - values = df[unlisted_columns_dict[column]].stack().unique() + values = data[unlisted_columns_dict[column]].stack().unique() values = [val for val in values if val not in (np.nan, "", "Other")] - new_df = pd.DataFrame( - index=df.index, columns=[column + "_item" + sep + x for x in values] + new_data = pd.DataFrame( + index=data.index, columns=[column + "_item" + sep + x for x in values] ) for value in values: # it's too slow... - yes_ind = (df[unlisted_columns_dict[column]] == value).any(axis=1) - new_df.loc[yes_ind, column + "_item" + sep + value] = True - column_loc = df.columns.get_loc(column) - df = pd.concat( - [df.iloc[:, :column_loc], new_df, df.iloc[:, column_loc:]], axis=1 + yes_ind = (data[unlisted_columns_dict[column]] == value).any(axis=1) + new_data.loc[yes_ind, column + "_item" + sep + value] = True + column_loc = data.columns.get_loc(column) + data = pd.concat( + [data.iloc[:, :column_loc], new_data, data.iloc[:, column_loc:]], axis=1 ) new_dictionary_index = ind + np.linspace(0.1, 0.9, len(values)) new_dictionary = pd.DataFrame( @@ -474,14 +920,33 @@ def combine_unlisted_variables(df, dictionary, sep="___"): new_dictionary["form_name"] = dictionary.loc[ind, "form_name"] new_dictionary["branching_logic"] = dictionary.loc[ind, "branching_logic"] new_dictionary_list.append(new_dictionary) + dictionary = pd.concat([dictionary] + new_dictionary_list, axis=0) dictionary = dictionary.sort_index().reset_index(drop=True) - return df, dictionary + return data, dictionary + + +def rename_checkbox_variables( + data: pandas.DataFrame, dictionary: pandas.DataFrame +) -> pandas.DataFrame: + """:py:class:`pandas.DataFrame` : Rename checkbox variable columns. + + By default the suffix is their answer option value. Convert this answer + option value to the answer option name. -def rename_checkbox_variables(df, dictionary): - """Rename checkbox variable columns. By default the suffix is their answer - option value. Convert this answer option value to the answer option name. + Parameters + ---------- + data : pandas.DataFrame + The incoming data. + + dictionary : pandas.DataFrame + The REDCap data dictionary. + + Returns + ------- + pandas.DataFrame + The updated data. """ checkbox_ind = dictionary["field_type"] == "checkbox" answer_dict = dictionary.loc[checkbox_ind, "answer_dict"] @@ -495,135 +960,219 @@ def rename_checkbox_variables(df, dictionary): # value codes, if they exist name_values = [x + "___" + y.lower() for x, y in zip(names, values)] name_labels = [x + "___" + y for x, y in zip(names, labels)] - df.rename(columns=dict(zip(name_values, name_labels)), inplace=True) - return df + data.rename(columns=dict(zip(name_values, name_labels)), inplace=True) + return data -def get_branching_logic_variables(branching_logic): - """Get all variables included in the branching logic - (including checkboxes variables)""" - var_names = [x.split("]")[0] for x in branching_logic.split("[")[1:]] - # Change any checkbox variable from bracket form to its one-hot column name - var_names = [x.replace("(", "___").replace(")", "") for x in var_names] - return var_names +def get_branching_logic_variables(branching_logic: str) -> list[str]: + """:py:class:`list` : Return all variables included in the branching logic (including checkboxes variables). -def resolve_checkbox_branching_logic(df, dictionary): - """By default, a cell is marked as 'Unchecked' in the absence of the + Parameters + ---------- + branching_logic : str + THe branching logic string. + + Returns + ------- + list + The list of all variables included in the branching logic. + """ # noqa : E501 + return [ + x.split("]")[0].replace("(", "___").replace(")", "") + for x in branching_logic.split("[")[1:] + ] + + +def resolve_checkbox_branching_logic( + data: pd.DataFrame, dictionary: pd.DataFrame +) -> pd.DataFrame: + """:py:class:`pandas.DataFrame` : Resolves checkbox logic. + + By default, a cell is marked as 'Unchecked' in the absence of the positive, even if the question was not asked to the subjid. If the question was not asked to the subjid because of the branching logic, then set this to be NaN instead. This does not completely check the branching logic, - which is a data quality issue!""" + which is a data quality issue!. + + Parameters + ---------- + data : pandas.DataFrame + The incoming data. + + dictionary : pandas.DataFrame + The REDCap data dictionary. + + Returns + ------- + pandas.DataFrame + The data with the checkbox branching logic resolved. + """ checkbox_ind = dictionary.loc[(dictionary["field_type"] == "checkbox")] branching_logic_variables = dictionary["branching_logic"].apply( get_branching_logic_variables ) + for ind in checkbox_ind.index: branching_logic_columns = [ - col for col in df.columns if col in branching_logic_variables.loc[ind] + col for col in data.columns if col in branching_logic_variables.loc[ind] ] - remove_ind = df[branching_logic_columns].isna().any(axis=1) + remove_ind = data[branching_logic_columns].isna().any(axis=1) checkbox_columns = [ col - for col in df.columns + for col in data.columns if (col.split("___")[0] == dictionary.loc[ind, "field_name"]) ] - df.loc[remove_ind, checkbox_columns] = np.nan - return df - - -def harmonise_age(df, age_columns=["demog_age", "demog_age_units"]): - """Deprecated, age should now be included in conversion_table.csv. - Convert age from any units into age in years.""" - df = df.rename(columns=dict(zip(age_columns, ["demog_age", "demog_age_units"]))) - df.loc[:, "demog_age"] = pd.to_numeric(df["demog_age"], errors="coerce") - df.loc[:, "demog_age"] = df["demog_age"].astype(float) - df.loc[(df["demog_age_units"] == "Months"), "demog_age"] *= 1 / 12 - df.loc[(df["demog_age_units"] == "Days"), "demog_age"] *= 1 / 365 + data.loc[remove_ind, checkbox_columns] = np.nan + + return data + + +def harmonise_age( + data: pandas.DataFrame, + age_columns: typing.Iterable[str] = ["demog_age", "demog_age_units"], +) -> pd.DataFrame: + """:py:class:`pandas.DataFrame` : The data with ages harmonised. + + .. warning:: + + DEPRECATED. Age should now be included in `conversion_table.csv`. + Convert age from any units into age in years. + + Parameters + ---------- + data : pandas.DataFrame + The incoming data. + + age_columns : typing.Iterable, default=["demog_age", "demog_age_units"] + An iterable (e.g. list) of age columns. + + Returns + ------- + pandas.DataFrame + The data with ages harmonised. + """ + warnings.warn( + ( + "`redcap_data.harmonise_age` is deprecated. " + "Age should now be included in `conversion_table.csv`. " + "Convert age from any units into age in years." + ), + DeprecationWarning, + stacklevel=2, + ) + + data = data.rename(columns=dict(zip(age_columns, ["demog_age", "demog_age_units"]))) + data.loc[:, "demog_age"] = pd.to_numeric(data["demog_age"], errors="coerce") + data.loc[:, "demog_age"] = data["demog_age"].astype(float) + data.loc[(data["demog_age_units"] == "Months"), "demog_age"] *= 1 / 12 + data.loc[(data["demog_age_units"] == "Days"), "demog_age"] *= 1 / 365 unit_list = ["Days", "Months", "Years"] # Standardize the units to 'Years' - df.loc[df["demog_age_units"].isin(unit_list), "demog_age_units"] = "Years" - return df + data.loc[data["demog_age_units"].isin(unit_list), "demog_age_units"] = "Years" + return data -def map_variable(variable, mapping_dict, other_value_str="Other / Unknown"): - """Map a variable according to a dict. Any non-NaN value not in the dict - keys is converted to other_value_str.""" - other_value_ind = (variable.isin(mapping_dict.keys()) == 0) & variable.notna() + +def map_variable( + variable: pandas.Series, + mapping_dict: dict[str, typing.Any], + non_nan_value: str = "Other / Unknown", +) -> pandas.Series: + """:py:class:`pandas.Series` : Map a variable column using a dict. + + Any non-NaN value not in the dict keys is converted to the value specified + by ``other_value_str``. + + Parameters + ---------- + variable : pandas.Series + The variable column to map. + + mapping_dict : dict + The mapping dict. + + non_nan_value : str, default="Other / Unknown" + Optional value with which to replace non-NaN values not in the dict + keys. + """ + non_nan_value_ind = (variable.isin(mapping_dict.keys()) == 0) & variable.notna() variable = variable.map(mapping_dict) - variable.loc[other_value_ind] = other_value_str + variable.loc[non_nan_value_ind] = non_nan_value + return variable -def load_conversion_table() -> pd.DataFrame: +def load_units_conversion_table() -> pandas.DataFrame: """:py:class:`pandas.DataFrame` : Loads the conversion table from a CSV. Returns ------- - pd.DataFrame + pandas.DataFrame The conversion table. """ try: - # Lookup table in an `assets` subfolder of the current folder + # Lookup table in an `assets` subfolder adjacent to the current folder return pd.read_csv( - Path(__file__).parent.joinpath("assets", "conversion_table.csv") + Path(__file__).parent.parent.joinpath("assets", "conversion_table.csv") ) except FileNotFoundError: - try: - # Lookup table in an `assets` subfolder of the parent folder - return pd.read_csv( - Path(__file__).parent.parent.joinpath("assets", "conversion_table.csv") - ) - except FileNotFoundError: - # Otherwise just get it from VERTEX assets on GitHub - return pd.read_csv( - "https://raw.githubusercontent.com/ISARICResearch/" - "VERTEX/refs/heads/main/assets/conversion_table.csv" - ) + # Otherwise just get it from VERTEX assets on GitHub + return pd.read_csv( + "https://raw.githubusercontent.com/ISARICResearch/" + "VERTEX/refs/heads/main/assets/conversion_table.csv" + ) -def load_countries(encoding="latin-1") -> pd.DataFrame: +def load_countries_table(encoding: str = "latin-1") -> pandas.DataFrame: """:py:class:`pandas.DataFrame` : Loads countries from a CSV. + Parameters + ---------- + encoding : str, default="latin-1" + Optional file encoding. + Returns ------- - pd.DataFrame - The conversion table. + pandas.DataFrame + The countries table. """ try: - # Lookup table in an `assets` subfolder of the current folder + # Lookup table in an `assets` subfolder adjacent to the current + # folder. return pd.read_csv( - Path(__file__).parent.joinpath("assets", "countries.csv"), encoding=encoding + Path(__file__).parent.parent.joinpath("assets", "countries.csv"), + encoding=encoding, ) except FileNotFoundError: - try: - # Lookup table in an `assets` subfolder of the parent folder - return pd.read_csv( - Path(__file__).parent.parent.joinpath("assets", "countries.csv"), - encoding=encoding, - ) - except FileNotFoundError: - # Otherwise just get it from VERTEX assets on GitHub - return pd.read_csv( - "https://raw.githubusercontent.com/ISARICResearch/" - "VERTEX/refs/heads/main/assets/countries.csv", - encoding=encoding, - ) + # Otherwise just get it from VERTEX assets on GitHub + return pd.read_csv( + "https://raw.githubusercontent.com/ISARICResearch/" + "VERTEX/refs/heads/main/assets/countries.csv", + encoding=encoding, + ) -def homogenise_variables(df, dictionary): - """ - Converts variables in a DataFrame based on a conversion table. +def homogenise_variables( + data: pandas.DataFrame, dictionary: pandas.DataFrame +) -> tuple[pd.DataFrame]: + """:py:class:`pandas.DataFrame` : Converts variables in given units in the data based on a conversion table. - Parameters: - df: DataFrame containing values and their units. - conversion_table: DataFrame containing conversion specifications. + Parameters + ---------- + data : pandas.DataFrame + The incoming data. + + dictionary : pandas.DataFrame + Conversion table/dictionary, as a Pandas dataframe. + + Returns + ------- + pandas.DataFrame + The data with unit conversions applied. + """ # noqa : E501 + conversion_table = load_units_conversion_table() - Returns: - pd.DataFrame: DataFrame with all specified values converted to the - desired units. - """ - conversion_table = load_conversion_table() for index, row in conversion_table.iterrows(): from_unit = row["from_unit"] to_unit = row["to_unit"] @@ -633,7 +1182,7 @@ def homogenise_variables(df, dictionary): try: # Ensure that the value column is numeric - df.loc[:, value_col] = pd.to_numeric(df[value_col], errors="coerce") + data.loc[:, value_col] = pd.to_numeric(data[value_col], errors="coerce") # Check if the variable is labs_lymphocyte or labs_neutrophil check_ind = ( @@ -644,51 +1193,71 @@ def homogenise_variables(df, dictionary): if check_ind: # Convert absolute count to percentage using total WBC count total_wbc_col = "labs_wbccount" - if total_wbc_col in df.columns: + if total_wbc_col in data.columns: # Ensure the total WBC count column is numeric - df.loc[:, total_wbc_col] = pd.to_numeric( - df[total_wbc_col], errors="coerce" + data.loc[:, total_wbc_col] = pd.to_numeric( + data[total_wbc_col], errors="coerce" ) # Apply conversion only to non-empty values mask = ( - (df[unit_col] == from_unit) - & df[value_col].notna() - & df[total_wbc_col].notna() + (data[unit_col] == from_unit) + & data[value_col].notna() + & data[total_wbc_col].notna() ) - df.loc[mask, value_col] = 100 * ( - df.loc[mask, value_col] / df.loc[mask, total_wbc_col] + data.loc[mask, value_col] = 100 * ( + data.loc[mask, value_col] / data.loc[mask, total_wbc_col] ) - df.loc[mask, unit_col] = to_unit + data.loc[mask, unit_col] = to_unit continue # Only apply the conversion if the factor is not NaN and the # value_col is not empty if not pd.isna(conversion_factor): - mask = (df[unit_col] == from_unit) & df[value_col].notna() + mask = (data[unit_col] == from_unit) & data[value_col].notna() # Apply the conversion - df.loc[mask, value_col] *= conversion_factor + data.loc[mask, value_col] *= conversion_factor # Set all units to the target unit - df.loc[df[unit_col] == from_unit, unit_col] = to_unit + data.loc[data[unit_col] == from_unit, unit_col] = to_unit dictionary_ind = dictionary["field_name"] == value_col dictionary.loc[dictionary_ind, "field_label"] += f" ({to_unit})" except Exception: pass + if "demog_age" not in conversion_table["variable"]: try: - df = harmonise_age(df) + data = harmonise_age(data) except Exception: pass - return df, dictionary + return data, dictionary + + +def convert_onehot_to_binary( + data: pandas.DataFrame, dictionary: pandas.DataFrame +) -> pandas.DataFrame: + """:py:class:`pandas.DataFrame` : Converts onehot-encoded columns in the data. -def convert_onehot_to_binary(df, dictionary): - """Convert onehot-encoded columns to True/False/NaN and discard answers - from the data dictionary, if they exist.""" + The conversions will be True/False/NaN values, and answers from the data + dictionary discarded if they exist. + + Parameters + ---------- + data : pandas.DataFrame + The incoming data. + + dictionary : pandas.DataFrame + The REDCap data dictionary. + + Returns + ------- + pandas.DataFrame + The data with the one-hot columns appropriately converted. + """ binary_ind = dictionary["field_type"] == "binary" binary_columns = dictionary.loc[binary_ind, "field_name"].tolist() - binary_columns = [col for col in binary_columns if col in df.columns] + binary_columns = [col for col in binary_columns if col in data.columns] mapping_dict = { "Yes": True, "Checked": True, @@ -697,20 +1266,43 @@ def convert_onehot_to_binary(df, dictionary): "Unknown": np.nan, } with pd.option_context("future.no_silent_downcasting", True): - df.loc[:, binary_columns] = df[binary_columns].replace(mapping_dict) - return df + data.loc[:, binary_columns] = data[binary_columns].replace(mapping_dict) + + return data ############################################ -# Main functions +# Initial data processing ############################################ -def initial_data_processing(data, dictionary, missing_data_codes): - """Initial processing of complete pandas dataframe, after REDCAP API call""" +def initial_data_processing( + data: pandas.DataFrame, + dictionary: pandas.DataFrame, + missing_data_codes: dict[str, typing.Any], +) -> tuple[pandas.DataFrame]: + """:py:class:`tuple` : Initial processing function invoked after the REDCap API call. + + Parameters + ---------- + data : pandas.DataFrame + The incoming REDCap data. + + dictionary : pandas.DataFrame + The REDCap data dictionary. + + missing_data_codes : dict + The dict of missing code keys and values. + + Returns + ------- + tuple + A tuple consisting of the updated data and data dictionary dataframes. + """ # noqa : E501 # Replace empty cells or 'Unknown' with NaN with pd.option_context("future.no_silent_downcasting", True): data = data.replace(["", "Unknown", "unknown"], np.nan) + # Replace missing data codes with NaN if missing_data_codes is not None: with pd.option_context("future.no_silent_downcasting", True): @@ -797,8 +1389,25 @@ def initial_data_processing(data, dictionary, missing_data_codes): return data, new_dictionary -def get_df_map(data, dictionary): - """Convert single-event rows into one row per patient.""" +def get_df_map( + data: pandas.DataFrame, dictionary: pandas.DataFrame +) -> tuple[pandas.DataFrame | dict[str, typing.Any]]: + """:py:class:`pandas.DataFrame` : Returns a dataframe with single-event rows converted to a format with one row per patient. + + Parameters + ---------- + data : pandas.DataFrame + The incoming REDCap data. + + dictionary : pandas.DataFrame + The REDCap data. + + Returns + ------- + tuple + Three dataframes, consisting of the transformed data. the data + dictionary, and the quality report. + """ # noqa : E501 df_map = data.copy() forms = ["presentation", "daily", "outcome"] columns = dictionary.loc[dictionary["form_name"].isin(forms), "field_name"].tolist() @@ -856,12 +1465,31 @@ def get_df_map(data, dictionary): dictionary = pd.concat([dictionary, pd.DataFrame.from_dict(outcome_dict)], axis=0) dictionary = dictionary.reset_index(drop=True) logger.debug(f"Data contains {df_map.shape[0]} patients") + return df_map, dictionary, quality_report -def get_df_forms(data, dictionary): +def get_df_forms( + data: pandas.DataFrame, dictionary: pandas.DataFrame +) -> dict[str, pandas.DataFrame]: + """:py:class:`dict` : Returns a dict of clinical form names and associated dataframes. + + Parameters + ---------- + data : pandas.DataFrame + The incoming REDCap data. + + dictionary : pandas.DataFrame + The data dictionary. + + Returns + ------- + dict + The dict of clinical form names and associated dataframes. + """ # noqa : E501 forms = dictionary["form_name"].unique() df_forms_dict = {} + for form in forms: columns = dictionary.loc[dictionary["form_name"] == form, "field_name"].tolist() columns = [col for col in columns if col in data.columns] @@ -869,17 +1497,36 @@ def get_df_forms(data, dictionary): columns = ["subjid"] + columns ind = data["form_name"].apply(lambda x: form in x.split(",")) df_forms_dict[form] = data.loc[ind, columns].reset_index(drop=True) + return df_forms_dict def get_redcap_data( - redcap_url, - redcap_api_key, - data_access_groups=None, - user_assigned_to_dag=False, - country_mapping=None, -): - """Get data from REDCap API and transform into analysis-ready dataframes""" + redcap_url: str, + redcap_api_key: str, + data_access_groups: typing.Iterable[str] | None = None, + user_assigned_to_dag: bool | None = False, + country_mapping: dict | None = None, +) -> tuple[pandas.DataFrame | dict[str, pandas.DataFrame] | dict[str, typing.Any]]: + """:py:class:`tuple` : Returns data from REDCap API and transforms them into analysis-ready dataframes. + + Parameters + ---------- + redcap_url : str + The REDCap database URL. + + redcap_api_key : str + The REDCap API key. + + data_access_groups : typing.Iterable, default=None + Optional iterable of data access group (DAG) names. + + user_assigned_to_dag : bool, default=None + Whether the user is assigned to a DAG. + + country_mapping : dict + The countries table. + """ # noqa : E501 total_started = time.perf_counter() logger.info("REDCap data pipeline start") @@ -954,7 +1601,7 @@ def get_redcap_data( ) if "demog_country" in dictionary["field_name"].values: - countries = load_countries(encoding="latin-1") + countries = load_countries_table(encoding="latin-1") df_map["country_iso"] = df_map["demog_country"].replace( dict(zip(countries["Country"], countries["Code"])) ) diff --git a/isaricanalytics/utils.py b/isaricanalytics/utils.py new file mode 100644 index 0000000..299a1f4 --- /dev/null +++ b/isaricanalytics/utils.py @@ -0,0 +1,90 @@ +from __future__ import annotations + +__all__ = [ + "clean_figure_table", + "strip_html", + "strip_nonstandard_unicode_chars", +] + +# -- IMPORTS -- + +# -- Standard libraries -- +import re +import typing + +# -- 3rd party libraries -- +import pandas + +# -- Internal libraries -- + + +def strip_html(value: typing.Any) -> str | typing.Any: + """:py:class:`typing.Any` : Strip HTML elements from a value. + + Parameters + ---------- + value : typing.Any + A value. + + Returns + ------- + str, typing.Any + Either a string stripped of all HTML elements, or the original non- + string value. + """ + if isinstance(value, str): + return re.sub(r"<.*?>", "", value) + + return value + + +def strip_nonstandard_unicode_chars(value: typing.Any) -> str | typing.Any: + """:py:class:`typing.Any` : Strip non-standard Unicode characters from a value. + + The non-standard Unicode characters of interest are defined within the + function itself, and are currently limited to the "↳" (U+21B3) character, + but may be extended to include other characters. + + Parameters + ---------- + value : typing.Any + A value. + + Returns + ------- + str, typing.Any + Either a string stripped of all non-standard Unicode characters, or the + original non- string value. + """ + nonstandard_unicode_chars = "↳" + + if isinstance(value, str): + return re.sub(rf"[{nonstandard_unicode_chars}]", "", value) + + return value + + +def clean_figure_table(figure_table: pandas.DataFrame) -> pandas.DataFrame: + """:py:class:`pandas.DataFrame` : A cleaned figure table dataframe. + + The cleaning steps are unique to the Plotly graph object table format from + which the table CSVs were originally, which contain HTML styling elements + and non-standard (non-alphabetic) Unicode characters. The cleaning is the + removal of such characters. + + Parameters + ---------- + figure_table : pandas.DataFrame + The original figure table as a Pandas dataframe. + + Returns + ------- + pandas.DataFrame + The cleaned figure table. + """ + # The use of `pandas.DataFrame.map` here is not absolutely optimal, as + # `map` applies changes across the dataframe element-wise, but is the + # safer choice given that the dataframe may contain a number of non-string + # columns which cannot be known in advance, while the cleaning steps + # currently only apply to string values. + return figure_table.map(strip_html).map(strip_nonstandard_unicode_chars) diff --git a/isaricanalytics/IsaricDraw.py b/isaricanalytics/visualisation.py similarity index 68% rename from isaricanalytics/IsaricDraw.py rename to isaricanalytics/visualisation.py index 5560eaa..7635257 100644 --- a/isaricanalytics/IsaricDraw.py +++ b/isaricanalytics/visualisation.py @@ -1,56 +1,47 @@ -import json -import os -import sys - +from __future__ import annotations + +__all__ = [ + "fig_bar_chart", + "fig_bar_line_chart", + "fig_count_chart", + "fig_dual_stack_pyramid", + "fig_flowchart", + "fig_forest_plot", + "fig_frequency_chart", + "fig_heatmaps", + "fig_kaplan_meier", + "fig_line_chart", + "fig_pie", + "fig_placeholder", + "fig_sankey", + "fig_sunburst", + "fig_table", + "fig_text", + "fig_timelines", + "fig_upset", + "hex_to_rgb", + "hex_to_rgba", + "rgb_to_rgba", +] + +# -- IMPORTS -- + +# -- Standard libraries -- +import typing + +# -- 3rd party libraries -- import numpy as np -import pandas as pd +import pandas +import plotly import plotly.express as px import plotly.graph_objs as go from plotly.subplots import make_subplots +# -- Internal libraries -- -def get_graph_id(suffix, frame=1): - fig_name = sys._getframe(frame).f_code.co_name - graph_id = suffix + "/" + fig_name - return graph_id - - -def save_inputs_to_file(local_args): - fig_name = sys._getframe(1).f_code.co_name - # Create and use a copy - _local_args = dict(local_args) - data = _local_args.pop("data") - # Convert to list (if not already) - data = data if isinstance(data, tuple) else (data,) - path = _local_args["filepath"] - suffix = _local_args["suffix"] - - if _local_args["graph_id"] is None: - graph_id = get_graph_id(_local_args["suffix"], frame=2) - else: - graph_id = suffix + "/" + _local_args["graph_id"] - - fig_data = [graph_id + "_data___" + str(ii) + ".csv" for ii in range(len(data))] - _local_args["graph_id"] = None - _local_args["filepath"] = "" - _local_args["save_inputs"] = False - metadata = { - "fig_id": graph_id, - "fig_name": fig_name, - "fig_arguments": _local_args, - "fig_data": fig_data, - } - os.makedirs(os.path.dirname(path), exist_ok=True) - metadata_json_file = os.path.join(path, graph_id + "_metadata.json") - with open(metadata_json_file, "w") as file: - json.dump(metadata, file, indent=4) - file.write("\n") - for ii in range(len(data)): - data[ii].to_csv( - os.path.join(path, graph_id + "_data___" + str(ii) + ".csv"), index=False - ) - return data, metadata +pd = pandas # An alias to allow Pandas code refs to work independently +# of Pandas Intersphinx refs in type hinting and docstrings ############################################ ############################################ @@ -60,29 +51,36 @@ def save_inputs_to_file(local_args): def fig_placeholder( - data, - title="Placeholder scatter plot", - xlabel="", - ylabel="", - height=450, - suffix="", - filepath="", - save_inputs=False, - graph_id=None, - graph_label="", - graph_about="", -): - # ---- - # Every figure must start with this - if save_inputs: - inputs = save_inputs_to_file(locals()) - - if graph_id is None: - graph_id = get_graph_id(suffix) - else: - graph_id = suffix + "/" + graph_id - # ---- - + data: pandas.DataFrame, + title: str = "Placeholder scatter plot", + xlabel: str = "", + ylabel: str = "", + height: int = 450, +) -> plotly.graph_objs.Figure: + """:py:class:`plotly.graph_objs.Figure` : Returns a placeholder scatter plot. + + Parameters + ---------- + data : pandas.DataFrame + Incoming data. + + title : str, default="Placeholder scatter plot" + Figure title. + + xlabel : str, default="" + Figure x-axis label. + + ylabel : str, default="" + Figure y-axis label. + + height : int, default=450 + Figure height. + + Returns + ------- + plotly.graph_objs.Figure + The Plotly figure. + """ if data is None: x = [1, 2, 3, 4, 5] y = np.random.uniform(low=10, high=15, size=5) @@ -105,38 +103,52 @@ def fig_placeholder( minreducedwidth=500, ) - # ---- - # Every figure return the same outputs - return fig, graph_id, graph_label, graph_about + return fig def fig_pie( - data, - title="Pie chart", - xlabel="", - ylabel="", - base_color_map=None, - names="", - values="", - height=450, - suffix="", - filepath="", - save_inputs=False, - graph_id=None, - graph_label="", - graph_about="", + data: pandas.DataFrame, + title: str = "Pie chart", + xlabel: str = "", + ylabel: str = "", + base_color_map: dict[str, str] | None = None, + names: str | int | pd.Series | typing.Iterable = "", + values: str | int | pd.Series | typing.Iterable = "", + height: int = 450, ): - # ---- - # Every figure must start with this - if save_inputs: - inputs = save_inputs_to_file(locals()) + """:py:class:`plotly.graph_objs.Figure` : Returns a pie chart figure. - if graph_id is None: - graph_id = get_graph_id(suffix) - else: - graph_id = suffix + "/" + graph_id - # ---- + Parameters + ---------- + data : pandas.DataFrame + Incoming data. + + title : str, default="Placeholder scatter plot" + Figure title. + xlabel : str, default="" + Figure x-axis label. + + ylabel : str, default="" + Figure y-axis label. + + base_color_map : dict + Map of sector values and colours. + + names : str, int, pd.Series, typing.Iterable, default="" + Sector name(s)/label(s). + + values : str, int, pd.Series, typing.Iterable, default="" + Sector values. + + height : int, default=450 + Figure height. + + Returns + ------- + plotly.graph_objs.Figure + The Plotly figure. + """ df = data.copy() fig = px.pie( @@ -156,40 +168,60 @@ def fig_pie( minreducedwidth=500, ) - # ---- - # Every figure must return the same outputs - return fig, graph_id, graph_label, graph_about + return fig def fig_timelines( - data, - title="Timeline", - label_col="", - group_col="", - start_date="start_date", - end_date="end_date", - size_col=None, - min_width=2, - max_width=10, - height=500, - suffix="", - filepath="", - save_inputs=False, - graph_id=None, - graph_label="", - graph_about="", -): - # ---- - # Every figure must start with this - if save_inputs: - inputs = save_inputs_to_file(locals()) - - if graph_id is None: - graph_id = get_graph_id(suffix) - else: - graph_id = suffix + "/" + graph_id - # ---- - + data: pandas.DataFrame, + title: str = "Timeline", + label_col: str = "", + group_col: str = "", + start_date: str = "start_date", + end_date: str = "end_date", + size_col: str | None = None, + min_width: int = 2, + max_width: int = 10, + height: int = 500, +) -> plotly.graph_objs.Figure: + """:py:class:`plotly.graph_objs.Figure` : Returns a timeline figure. + + Parameters + ---------- + data : pandas.DataFrame + Incoming data. + + title : str, default="Timeline" + Figure title. + + label_col : str, default="" + Label column. + + group_col : str, default="" + Group column. + + start_date : str, default="start_date" + Start date column. + + end_date : str, default="end_date" + End date column. + + size_col : str, None, default=None + Size column. + + min_width : int, default=2 + Figure minimum width. + + max_width : int, default=10 + Figure maximum width. + + height : int, default=500 + Figure height. + + Returns + ------- + plotly.graph_objs.Figure + The Plotly figure. + """ df = data.copy() df[start_date] = pd.to_datetime(df[start_date]) df[end_date] = pd.to_datetime(df[end_date]) @@ -260,36 +292,45 @@ def fig_timelines( minreducedwidth=500, ) - # ---- - # Every figure must return the same outputs - return fig, graph_id, graph_label, graph_about + return fig def fig_sunburst( - data, - title="Sunburst Chart", - path=["level0", "level1"], - values="values", - base_color_map=None, - height=430, - suffix="", - filepath="", - save_inputs=False, - graph_id=None, - graph_label="", - graph_about="", -): - # ---- - # Every figure must start with this - if save_inputs: - inputs = save_inputs_to_file(locals()) - - if graph_id is None: - graph_id = get_graph_id(suffix) - else: - graph_id = suffix + "/" + graph_id - # ---- - + data: pandas.DataFrame, + title: str = "Sunburst Chart", + path: list[str | int] | pd.Series | typing.Iterable | None = ["level0", "level1"], + values: str | int | pd.Series | typing.Iterable = "values", + base_color_map: dict[str, str] | None = None, + height: int = 430, +) -> plotly.graph_objs.Figure: + """:py:class:`plotly.graph_objs.Figure` : Returns a sunburst plot. + + Parameters + ---------- + data : pandas.DataFrame + Incoming data. + + title : str, default="Sunburst Chart" + Figure title. + + path : str, int, pd.Series, typing.Iterable, None, default=["level0", "level1"] + Column names defining a hierarhy of sectors, from root to leaves. + + values : str, int, pd.Series, typing.Iterable, default="values" + A column name in the data defining sector values, or a Pandas Series + or an iterable containing sector values. + + base_color_map : dict, default=None + Map of sector values/marks and colours. + + height : int, default=430 + Figure height. + + Returns + ------- + plotly.graph_objs.Figure + The Plotly figure. + """ df = data.copy() fig = px.sunburst( @@ -312,39 +353,58 @@ def fig_sunburst( minreducedwidth=500, ) - # ---- - # Every figure must return the same outputs - return fig, graph_id, graph_label, graph_about + return fig def fig_bar_chart( - data, - title="Bar Chart", - xlabel="", - ylabel="", - index_column="index", - barmode="stack", - xaxis_tickformat="%m-%Y", - base_color_map=None, - height=340, - suffix="", - filepath="", - save_inputs=False, - graph_id=None, - graph_label="", - graph_about="", -): - # ---- - # Every figure must start with this - if save_inputs: - inputs = save_inputs_to_file(locals()) - - if graph_id is None: - graph_id = get_graph_id(suffix) - else: - graph_id = suffix + "/" + graph_id - # ---- - + data: pandas.DataFrame, + title: str = "Bar Chart", + xlabel: str = "", + ylabel: str = "", + index_column: str = "index", + barmode: str = "stack", + xaxis_tickformat: str = "%m-%Y", + base_color_map: dict[str, str] | None = None, + height: int = 340, +) -> plotly.graph_objs.Figure: + """:py:class:`plotly.graph_objs.Figure` : Returns a bar chart. + + Parameters + ---------- + data : pandas.DataFrame + Incoming data. + + title : str, default="Bar Chart" + Figure title. + + xlabel : str, default="" + Figure x-axis label. + + ylabel : str, default="" + Figure y-axis label. + + index_column : str, default="index" + Index column. + + barmode : str, default="stack" + How bars with the same location coordinate are displayed: possible + values are `"stack"`, `"relative"`, `"group"`, `"overlay"``. For + reference see the `Plotly documentation `_. + + xaxis_tickformat : str, default="%m-%Y" + x-axis tick format. + + base_color_map : dict, default=None + Map of bar values and colours. + + height : int, default=340 + Figure height. + + Returns + ------- + plotly.graph_objs.Figure + The Plotly figure. + """ df = data.copy() df = df.set_index(index_column) @@ -397,33 +457,33 @@ def fig_bar_chart( ) fig = go.Figure(data=traces, layout=layout) - # ---- - # Every figure must return the same outputs - return fig, graph_id, graph_label, graph_about + return fig def fig_upset( - data, - title="Upset Plot", - height=480, - suffix="", - filepath="", - save_inputs=False, - graph_id=None, - graph_label="", - graph_about="", -): - # ---- - # Every figure must start with this - if save_inputs: - inputs = save_inputs_to_file(locals()) - - if graph_id is None: - graph_id = get_graph_id(suffix) - else: - graph_id = suffix + "/" + graph_id - # ---- - + data: tuple[pd.DataFrame], + title: str = "Upset Plot", + height: int = 480, +) -> plotly.graph_objs.Figure: + """:py:class:`plotly.graph_objs.Figure` : Returns an upset plot. + + Parameters + ---------- + data : tuple + Incoming data as two Pandas dataframes, the first for counts, and the + second for intersections. + + title : str, default="Upset Plot" + Figure title. + + height : int, default=480 + Figure height. + + Returns + ------- + plotly.graph_objs.Figure + The Plotly figure. + """ counts = data[0].copy() intersections = data[1].copy() @@ -582,36 +642,44 @@ def fig_upset( minreducedwidth=500, ) - # ---- - # Every figure must return the same outputs - return fig, graph_id, graph_label, graph_about + return fig def fig_count_chart( - data, - title="Count Chart", - xlabel="Count", - ylabel="Variable", - base_color_map=None, - height=350, - suffix="", - filepath="", - save_inputs=False, - graph_id=None, - graph_label="", - graph_about="", -): - # ---- - # Every figure must start with this - if save_inputs: - inputs = save_inputs_to_file(locals()) - - if graph_id is None: - graph_id = get_graph_id(suffix) - else: - graph_id = suffix + "/" + graph_id - # ---- - + data: pandas.DataFrame, + title: str = "Count Chart", + xlabel: str = "Count", + ylabel: str = "Variable", + base_color_map: dict[str, str] | None = None, + height: int = 350, +) -> plotly.graph_objs.Figure: + """:py:class:`plotly.graph_objs.Figure` : Returns a count chart. + + Parameters + ---------- + data : pandas.DataFrame + Incoming data. + + title : str, default="Count Chart" + Figure title. + + xlabel : str, default="Count" + Figure x-axis label. + + ylabel : str, default="Variable" + Figure y-axis label. + + base_color_map : dict, default=None + Map of bar values and colours. + + height : int, default=350 + Figure height. + + Returns + ------- + plotly.graph_objs.Figure + The Plotly figure. + """ df = data.copy() column_names = ["label", "count", "short_label"] @@ -676,36 +744,44 @@ def fig_count_chart( fig = go.Figure(data=traces, layout=layout) - # ---- - # Every figure must return the same outputs - return fig, graph_id, graph_label, graph_about + return fig def fig_frequency_chart( - data, - title="Frequency Chart", - xlabel="Proportion", - ylabel="Variable", - base_color_map=None, - height=350, - suffix="", - filepath="", - save_inputs=False, - graph_id=None, - graph_label="", - graph_about="", -): - # ---- - # Every figure must start with this - if save_inputs: - inputs = save_inputs_to_file(locals()) - - if graph_id is None: - graph_id = get_graph_id(suffix) - else: - graph_id = suffix + "/" + graph_id - # ---- - + data: pandas.DataFrame, + title: str = "Frequency Chart", + xlabel: str = "Proportion", + ylabel: str = "Variable", + base_color_map: dict[str, str] | None = None, + height: int = 350, +) -> plotly.graph_objs.Figure: + """:py:class:`plotly.graph_objs.Figure` : Returns a frequency chart. + + Parameters + ---------- + data : pandas.DataFrame + Incoming data. + + title : str, default="Frequency Chart" + Figure title. + + xlabel : str, default="Proportion" + Figure x-axis label. + + ylabel : str, default="Variable" + Figure y-axis label. + + base_color_map : dict + Map of bar values and colours. + + height : int, default=350 + Figure height. + + Returns + ------- + plotly.graph_objs.Figure + The Plotly figure. + """ df = data.copy() column_names = ["label", "proportion", "short_label"] @@ -794,34 +870,36 @@ def fig_frequency_chart( fig = go.Figure(data=traces, layout=layout) - # ---- - # Every figure must return the same outputs - return fig, graph_id, graph_label, graph_about + return fig def fig_table( - data, - table_key="", - columnwidth=None, - height=500, - suffix="", - filepath="", - save_inputs=False, - graph_id=None, - graph_label="", - graph_about="", -): - # ---- - # Every figure must start with this - if save_inputs: - inputs = save_inputs_to_file(locals()) - - if graph_id is None: - graph_id = get_graph_id(suffix) - else: - graph_id = suffix + "/" + graph_id - # ---- - + data: pandas.DataFrame, + table_key: str = "", + columnwidth: typing.Iterable[int | float] | None = None, + height: int = 500, +) -> plotly.graph_objs.Figure: + """:py:class:`plotly.graph_objs.Figure` : Returns a table figure. + + Parameters + ---------- + data : pandas.DataFrame + Incoming data. + + table_key : str, default="" + Table key. + + columnwidth : typing.Iterable, default=None + An iterable of column widths. + + height : int, default=500 + Figure height. + + Returns + ------- + plotly.graph_objs.Figure + The Plotly figure. + """ df = data.copy() bf_columns = ["" + x + "" for x in df.columns] @@ -863,36 +941,44 @@ def fig_table( minreducedwidth=500, ) - # ---- - # Every figure must return the same outputs - return fig, graph_id, graph_label, graph_about + return fig def fig_dual_stack_pyramid( - data, - title="Dual-Sided Stacked Pyramid Chart", - xlabel="Count", - ylabel="Category", - base_color_map=None, - height=430, - suffix="", - filepath="", - save_inputs=False, - graph_id=None, - graph_label="", - graph_about="", -): - # ---- - # Every figure must start with this - if save_inputs: - inputs = save_inputs_to_file(locals()) - - if graph_id is None: - graph_id = get_graph_id(suffix) - else: - graph_id = suffix + "/" + graph_id - # ---- - + data: pandas.DataFrame, + title: str = "Dual-Sided Stacked Pyramid Chart", + xlabel: str = "Count", + ylabel: str = "Category", + base_color_map: dict[str, str] | None = None, + height: int = 430, +) -> plotly.graph_objs.Figure: + """:py:class:`plotly.graph_objs.Figure` : Returns a dual-sided stacked pyramid chart. + + Parameters + ---------- + data : pandas.DataFrame + Incoming data. + + title : str, default="Dual-Sided Stacked Pyramid Chart" + Figure title. + + xlabel : str, default="Count" + Figure x-axis label. + + ylabel : str, default="Category" + Figure y-axis label. + + base_color_map : dict, default=None + Map of bar values and colours. + + height : int, default=430 + Figure height. + + Returns + ------- + plotly.graph_objs.Figure + The Plotly figure. + """ # noqa : E501 df = data.copy() # Error Handling @@ -1029,32 +1115,28 @@ def fig_dual_stack_pyramid( ) fig = go.Figure(data=traces, layout=layout) - # ---- - # Every figure must return the same outputs - return fig, graph_id, graph_label, graph_about + return fig def fig_flowchart( - data, - height=430, - suffix="", - filepath="", - save_inputs=False, - graph_id=None, - graph_label="", - graph_about="", -): - # ---- - # Every figure must start with this - if save_inputs: - inputs = save_inputs_to_file(locals()) - - if graph_id is None: - graph_id = get_graph_id(suffix) - else: - graph_id = suffix + "/" + graph_id - # ---- - + data: pandas.DataFrame, + height: int = 430, +) -> plotly.graph_objs.Figure: + """:py:class:`plotly.graph_objs.Figure` : Returns a flowchart. + + Parameters + ---------- + data : pandas.DataFrame + Incoming data. + + height : int, default=430 + Figure height. + + Returns + ------- + plotly.graph_objs.Figure + The Plotly figure. + """ df = data.copy() arrows = [] @@ -1115,39 +1197,56 @@ def fig_flowchart( fig = go.Figure(layout=layout) - # ---- - # Every figure must return the same outputs - return fig, graph_id, graph_label, graph_about + return fig def fig_forest_plot( - data, - title="Forest Plot", - xlabel="Odds Ratio (95% CI)", - ylabel="", - reorder=True, - labels=["Variable", "OddsRatio", "LowerCI", "UpperCI"], - marker=None, - noeffect_line=True, - height=600, - suffix="", - filepath="", - save_inputs=False, - graph_id=None, - graph_label="", - graph_about="", -): - # ---- - # Every figure must start with this - if save_inputs: - inputs = save_inputs_to_file(locals()) - - if graph_id is None: - graph_id = get_graph_id(suffix) - else: - graph_id = suffix + "/" + graph_id - # ---- - + data: pandas.DataFrame, + title: str = "Forest Plot", + xlabel: str = "Odds Ratio (95% CI)", + ylabel: str = "", + reorder: bool = True, + labels: typing.Iterable[str] = ["Variable", "OddsRatio", "LowerCI", "UpperCI"], + marker: dict[str, typing.Any] | None = None, + noeffect_line: bool = True, + height: int = 600, +) -> plotly.graph_objs.Figure: + """:py:class:`plotly.graph_objs.Figure` : Returns a forest plot. + + Parameters + ---------- + data : pandas.DataFrame + Incoming data. + + title : str, default="Forest Plot" + Figure title. + + xlabel : str, default="Odds Ratio (95% CI)" + Figure x-axis label. + + ylabel : str, default="" + Figure y-axis label. + + reorder : bool, default=True + Sort values. + + labels : typing.Iterable, default=["Variable", "OddsRatio", "LowerCI", "UpperCI"] + Column of labels. + + marker : dict, default=None + Marker properties dict. + + no_effect_line : bool, default=True + Add no effect line. + + height : int, default=600 + Figure height. + + Returns + ------- + plotly.graph_objs.Figure + The Plotly figure. + """ df = data.copy() # Ordering Values -> Descending Order @@ -1228,32 +1327,28 @@ def fig_forest_plot( ) fig = go.Figure(data=traces, layout=layout) - # ---- - # Every figure must return the same outputs - return fig, graph_id, graph_label, graph_about + return fig def fig_text( - data, - height=430, - suffix="", - filepath="", - save_inputs=False, - graph_id=None, - graph_label="", - graph_about="", -): - # ---- - # Every figure must start with this - if save_inputs: - inputs = save_inputs_to_file(locals()) - - if graph_id is None: - graph_id = get_graph_id(suffix) - else: - graph_id = suffix + "/" + graph_id - # ---- - + data: pandas.DataFrame, + height: int = 430, +) -> plotly.graph_objs.Figure: + """:py:class:`plotly.graph_objs.Figure` : Returns a figure with an annotation. + + Parameters + ---------- + data : pandas.DataFrame + Incoming data. + + height : int, default=430 + Figure height. + + Returns + ------- + plotly.graph_objs.Figure + The Plotly figure. + """ fig = go.Figure() text = "
".join(data["paragraphs"].values) @@ -1269,40 +1364,61 @@ def fig_text( minreducedwidth=500, ) - # ---- - # Every figure must return the same outputs - return fig, graph_id, graph_label, graph_about + return fig def fig_kaplan_meier( - data, - title="Kaplan-Meier Plot", - xlabel="Time (days)", - ylabel="Survival Probability", - groups=None, - index_column="index", - base_color_map=None, - xlim=None, - p_value=None, - height=800, - suffix="", - filepath="", - save_inputs=False, - graph_id=None, - graph_label="", - graph_about="", -): - # ---- - # Every figure must start with this - if save_inputs: - inputs = save_inputs_to_file(locals()) - - if graph_id is None: - graph_id = get_graph_id(suffix) - else: - graph_id = suffix + "/" + graph_id - # ---- - + data: tuple[pd.DataFrame], + title: str = "Kaplan-Meier Plot", + xlabel: str = "Time (days)", + ylabel: str = "Survival Probability", + groups: typing.Iterable[str] | None = None, + index_column: str = "index", + base_color_map: dict[str, str] | None = None, + xlim: typing.Iterable[float | int] | None = None, + p_value: float | None = None, + height: int = 480, +) -> plotly.graph_objs.Figure: + """:py:class:`plotly.graph_objs.Figure` : Returns a Kaplan-Meier plot. + + Parameters + ---------- + data : tuple + Incoming data as two Pandas dataframes, the first for the plot, and the + second for the risk table. + + title : str, default="Kaplan-Meier Plot" + Figure title. + + xlabel : str, default="Time (days)" + Figure x-axis label. + + ylabel : str, default="Survival Probability" + Figure y-axis label. + + groups : typing.Iterable, default=None + Groups. + + index_column : str, default="index" + Index column. + + base_color_map : dict, default=None + Colour map. + + xlim : typing.Iterable, default=None + xlim. + + p_value : float, default=None + p-value. + + height : int, default=480 + Figure height. + + Returns + ------- + plotly.graph_objs.Figure + The Plotly figure. + """ df_km = data[0].copy() risk_table = data[1].copy() @@ -1504,40 +1620,60 @@ def fig_kaplan_meier( minreducedwidth=500, ) - # ---- - # Every figure must return the same outputs - return fig, graph_id, graph_label, graph_about + return fig def fig_line_chart( - data, - title="Line chart", - xlabel="", - ylabel="", - line_column="", - index_column="index", - lower_column=None, - upper_column=None, - line_color=None, - height=340, - suffix="", - filepath="", - save_inputs=False, - graph_id=None, - graph_label="", - graph_about="", -): - # ---- - # Every figure must start with this - if save_inputs: - inputs = save_inputs_to_file(locals()) - - if graph_id is None: - graph_id = get_graph_id(suffix) - else: - graph_id = suffix + "/" + graph_id - # ---- - + data: pandas.DataFrame, + title: str = "Line chart", + xlabel: str = "", + ylabel: str = "", + height: int = 480, + line_column: str = "", + index_column: str = "index", + lower_column: str | None = None, + upper_column: str | None = None, + line_color: str | None = None, +) -> plotly.graph_objs.Figure: + """:py:class:`plotly.graph_objs.Figure` : Returns a line chart. + + Parameters + ---------- + data : pandas.DataFrame + Incoming data. + + title : str, default="Line chart" + Figure title. + + xlabel : str, default="" + Figure x-axis label. + + ylabel : str, default="" + Figure y-axis label. + + height : int, default=480 + Figure height. + + line_column : str, default="" + Line column. + + index_column : str, default="index" + Index column. + + lower_column : str, default=None + Lower column. + + upper_column : str, default=None + Upper column. + + line_color : str, default=None + Line colour. + + Returns + ------- + plotly.graph_objs.Figure + The Plotly figure. + """ df = data.copy() # Ensure correct index @@ -1592,43 +1728,69 @@ def fig_line_chart( fig = go.Figure(data=data, layout=layout) - # ---- - # Every figure must return the same outputs - return fig, graph_id, graph_label, graph_about + return fig def fig_bar_line_chart( - data, - title="Combined bar line chart", - xlabel="", - ylabel_left="", - ylabel_right="", - bar_column="", - line_column="", - index_column="index", - lower_column=None, - upper_column=None, - bar_color=None, - line_color=None, - height=500, - suffix="", - filepath="", - save_inputs=False, - graph_id=None, - graph_label="", - graph_about="", -): - # ---- - # Every figure must start with this - if save_inputs: - inputs = save_inputs_to_file(locals()) - - if graph_id is None: - graph_id = get_graph_id(suffix) - else: - graph_id = suffix + "/" + graph_id - # ---- - + data: pandas.DataFrame, + title: str = "Combined bar line chart", + xlabel: str = "", + ylabel_left: str = "", + ylabel_right: str = "", + bar_column: str = "", + line_column: str = "", + index_column: str = "index", + lower_column: str | None = None, + upper_column: str | None = None, + bar_color: str | None = None, + line_color: str | None = None, + height: int = 500, +) -> plotly.graph_objs.Figure: + """:py:class:`plotly.graph_objs.Figure` : Returns a bar-line chart. + + Parameters + ---------- + data : pandas.DataFrame + Incoming data. + + title : str, default="Combined bar line chart" + Figure title. + + xlabel : str, default="" + Figure x-axis label. + + ylabel : str, default="" + Figure y-axis label. + + bar_column : str, default="" + Bar column. + + line_column : str, default="" + Line column. + + index_column : str, default="index" + Index column. + + lower_column : str, default=None + Lower column. + + upper_column : str, default=None + Upper column. + + bar_color : str, default=None + Bar colour. + + line_color : str, default=None + Line colour. + + height : int, default=500 + Figure height. + + Returns + ------- + plotly.graph_objs.Figure + The Plotly figure. + """ df = data.copy() # Ensure correct index @@ -1705,42 +1867,68 @@ def fig_bar_line_chart( ) fig = go.Figure(data=data, layout=layout) - # ---- - # Every figure must return the same outputs - return fig, graph_id, graph_label, graph_about + return fig def fig_heatmaps( - data, - title="", - subplot_titles=None, - ylabel="", - xlabel="", - colorbar_label="", - index_column="index", - zmin=None, - zmax=None, - include_annotations=False, - base_color_map=None, - height=750, - suffix="", - filepath="", - save_inputs=False, - graph_id=None, - graph_label="", - graph_about="", -): - # ---- - # Every figure must start with this - if save_inputs: - inputs = save_inputs_to_file(locals()) - - if graph_id is None: - graph_id = get_graph_id(suffix) - else: - graph_id = suffix + "/" + graph_id - # ---- - + data: pandas.DataFrame, + title: str = "", + subplot_titles: list[str] | None = None, + ylabel: str = "", + xlabel: str = "", + colorbar_label: str = "", + index_column: str = "index", + zmin: float | None = None, + zmax: float | None = None, + include_annotations: bool = False, + base_color_map: dict[str, str] | None = None, + height: int = 750, +) -> plotly.graph_objs.Figure: + """:py:class:`plotly.graph_objs.Figure` : Returns a heatmaps chart. + + Parameters + ---------- + data : pandas.DataFrame + Incoming data. + + title : str, default="" + Figure title. + + subplot_titles : list, default=None + Subplot titles. + + xlabel : str, default="" + Figure x-axis label. + + ylabel : str, default="" + Figure y-axis label. + + colorbar_label : str, default="" + Colour bar label. + + index_column : str, default="index" + Index column. + + zmin : float, default=None + zmin. + + zmax : float, default=None + zmax. + + include_annotations : bool, default=False + Include annotations. + + base_color_map : dict, default=None + Colour map. + + height : int, default=750 + Figure height. + + Returns + ------- + plotly.graph_objs.Figure + The Plotly figure. + """ if isinstance(data, tuple) is False: data = (data,) @@ -1809,32 +1997,28 @@ def fig_heatmaps( col=1, ) - # ---- - # Every figure must return the same outputs - return fig, graph_id, graph_label, graph_about + return fig def fig_sankey( - data, - height=500, - suffix="", - filepath="", - save_inputs=False, - graph_id="sankey", - graph_label="", - graph_about="", -): - # ---- - # Every figure must start with this - if save_inputs: - inputs = save_inputs_to_file(locals()) - - if graph_id is None: - graph_id = get_graph_id(suffix) - else: - graph_id = suffix + "/" + graph_id - # ---- - + data: pandas.DataFrame, + height: int = 500, +) -> plotly.graph_objs.Figure: + """:py:class:`plotly.graph_objs.Figure` : Returns a Sankey plot. + + Parameters + ---------- + data : pandas.DataFrame + Incoming data. + + height : int, default=500 + Figure height. + + Returns + ------- + plotly.graph_objs.Figure + The Plotly figure. + """ node = data[0].copy() link = data[1].copy() annotations = data[2].copy() @@ -1866,9 +2050,7 @@ def fig_sankey( ), ) - # ---- - # Every figure must return the same outputs - return fig, graph_id, graph_label, graph_about + return fig ############################################ @@ -1878,14 +2060,42 @@ def fig_sankey( ############################################ -def hex_to_rgb(hex_color): - """Convert a hex color to an RGB tuple.""" +def hex_to_rgb(hex_color: str) -> tuple[int]: + """:py:class:`tuple` : Converts a hex colour to an RGB colour tuple. + + Parameters + ---------- + hex_color : str + Hex colour string. + + Returns + ------- + tuple + RGB colour tuple. + """ hex_color = hex_color.lstrip("#") rgb_color = tuple(int(hex_color[i : i + 2], 16) for i in (0, 2, 4)) return rgb_color -def hex_to_rgba(hex_color, opacity): +def hex_to_rgba(hex_color: str, opacity: float) -> str: + """:py:class:`str` : Converts a hex colour to an RGBA (red-green-blue-alpha) + colour string. + + Parameters + ---------- + hex_color : str + Hex colour string. + + opacity : float + Opacity/transparency, a value between 0.0 (fully transparent) and + 1.0 (fully opaque). + + Returns + ------- + str + An RGBA colour string (RGB + opacity/transparency). + """ hex_color = hex_color.lstrip("#") hlen = len(hex_color) rgba_color = "rgba(" + ", ".join( @@ -1895,12 +2105,22 @@ def hex_to_rgba(hex_color, opacity): return rgba_color -def rgb_to_rgba(rgb_value, alpha): - """ - Adds the alpha channel to an RGB Value and returns it as an RGBA Value - :param rgb_value: Input RGB Value - :param alpha: Alpha Value to add in range [0,1] - :return: RGBA Value - """ - rgba_color = f"rgba{rgb_value[3:-1]}, {alpha})" +def rgb_to_rgba(rgb_color: tuple[int], alpha: float) -> str: + """:py:class:`str` : Converts an RGB colour tuple and alpha value to an RGBA colour string. + + Parameters + ---------- + rgb_color : tuple + RGB color tuple. + + alpha : float + Opacity/transparency value between 0.0 (fully transparent) and 1.0 + (fully opaque). + + Returns + ------- + str + RGBA colour string. + """ # noqa: E501 + rgba_color = f"rgba({rgb_color[0]}, {rgb_color[1]}, {rgb_color[2]}, {alpha})" return rgba_color diff --git a/pylock.toml b/pylock.toml deleted file mode 100644 index 93292cd..0000000 --- a/pylock.toml +++ /dev/null @@ -1,3149 +0,0 @@ -lock-version = "1.0" -requires-python = ">=3.11" -environments = [ - "python_version >= \"3.11\"", -] -extras = ["docs", "test"] -dependency-groups = ["default"] -default-groups = ["default"] -created-by = "pdm" -[[packages]] -name = "accessible-pygments" -version = "0.0.5" -requires-python = ">=3.9" -sdist = {name = "accessible_pygments-0.0.5.tar.gz", url = "https://files.pythonhosted.org/packages/bc/c1/bbac6a50d02774f91572938964c582fff4270eee73ab822a4aeea4d8b11b/accessible_pygments-0.0.5.tar.gz", hashes = {sha256 = "40918d3e6a2b619ad424cb91e556bd3bd8865443d9f22f1dcdf79e33c8046872"}} -wheels = [ - {name = "accessible_pygments-0.0.5-py3-none-any.whl",url = "https://files.pythonhosted.org/packages/8d/3f/95338030883d8c8b91223b4e21744b04d11b161a3ef117295d8241f50ab4/accessible_pygments-0.0.5-py3-none-any.whl",hashes = {sha256 = "88ae3211e68a1d0b011504b2ffc1691feafce124b845bd072ab6f9f66f34d4b7"}}, -] -marker = "\"docs\" in extras" - -[packages.tool.pdm] -dependencies = [ - "pygments>=1.5", -] - -[[packages]] -name = "alabaster" -version = "1.0.0" -requires-python = ">=3.10" -sdist = {name = "alabaster-1.0.0.tar.gz", url = "https://files.pythonhosted.org/packages/a6/f8/d9c74d0daf3f742840fd818d69cfae176fa332022fd44e3469487d5a9420/alabaster-1.0.0.tar.gz", hashes = {sha256 = "c00dca57bca26fa62a6d7d0a9fcce65f3e026e9bfe33e9c538fd3fbb2144fd9e"}} -wheels = [ - {name = "alabaster-1.0.0-py3-none-any.whl",url = "https://files.pythonhosted.org/packages/7e/b3/6b4067be973ae96ba0d615946e314c5ae35f9f993eca561b356540bb0c2b/alabaster-1.0.0-py3-none-any.whl",hashes = {sha256 = "fc6786402dc3fcb2de3cabd5fe455a2db534b371124f1f21de8731783dec828b"}}, -] -marker = "\"docs\" in extras" - -[packages.tool.pdm] -dependencies = [] - -[[packages]] -name = "anyio" -version = "4.13.0" -requires-python = ">=3.10" -sdist = {name = "anyio-4.13.0.tar.gz", url = "https://files.pythonhosted.org/packages/19/14/2c5dd9f512b66549ae92767a9c7b330ae88e1932ca57876909410251fe13/anyio-4.13.0.tar.gz", hashes = {sha256 = "334b70e641fd2221c1505b3890c69882fe4a2df910cba14d97019b90b24439dc"}} -wheels = [ - {name = "anyio-4.13.0-py3-none-any.whl",url = "https://files.pythonhosted.org/packages/da/42/e921fccf5015463e32a3cf6ee7f980a6ed0f395ceeaa45060b61d86486c2/anyio-4.13.0-py3-none-any.whl",hashes = {sha256 = "08b310f9e24a9594186fd75b4f73f4a4152069e3853f1ed8bfbf58369f4ad708"}}, -] -marker = "\"docs\" in extras" - -[packages.tool.pdm] -dependencies = [ - "exceptiongroup>=1.0.2; python_version < \"3.11\"", - "idna>=2.8", - "typing-extensions>=4.5; python_version < \"3.13\"", -] - -[[packages]] -name = "appnope" -version = "0.1.4" -requires-python = ">=3.6" -sdist = {name = "appnope-0.1.4.tar.gz", url = "https://files.pythonhosted.org/packages/35/5d/752690df9ef5b76e169e68d6a129fa6d08a7100ca7f754c89495db3c6019/appnope-0.1.4.tar.gz", hashes = {sha256 = "1de3860566df9caf38f01f86f65e0e13e379af54f9e4bee1e66b48f2efffd1ee"}} -wheels = [ - {name = "appnope-0.1.4-py2.py3-none-any.whl",url = "https://files.pythonhosted.org/packages/81/29/5ecc3a15d5a33e31b26c11426c45c501e439cb865d0bff96315d86443b78/appnope-0.1.4-py2.py3-none-any.whl",hashes = {sha256 = "502575ee11cd7a28c0205f379b525beefebab9d161b7c964670864014ed7213c"}}, -] -marker = "platform_system == \"Darwin\" and \"docs\" in extras" - -[packages.tool.pdm] -dependencies = [] - -[[packages]] -name = "astroid" -version = "4.0.4" -requires-python = ">=3.10.0" -sdist = {name = "astroid-4.0.4.tar.gz", url = "https://files.pythonhosted.org/packages/07/63/0adf26577da5eff6eb7a177876c1cfa213856be9926a000f65c4add9692b/astroid-4.0.4.tar.gz", hashes = {sha256 = "986fed8bcf79fb82c78b18a53352a0b287a73817d6dbcfba3162da36667c49a0"}} -wheels = [ - {name = "astroid-4.0.4-py3-none-any.whl",url = "https://files.pythonhosted.org/packages/b0/cf/1c5f42b110e57bc5502eb80dbc3b03d256926062519224835ef08134f1f9/astroid-4.0.4-py3-none-any.whl",hashes = {sha256 = "52f39653876c7dec3e3afd4c2696920e05c83832b9737afc21928f2d2eb7a753"}}, -] -marker = "\"docs\" in extras" - -[packages.tool.pdm] -dependencies = [ - "typing-extensions>=4; python_version < \"3.11\"", -] - -[[packages]] -name = "asttokens" -version = "3.0.1" -requires-python = ">=3.8" -sdist = {name = "asttokens-3.0.1.tar.gz", url = "https://files.pythonhosted.org/packages/be/a5/8e3f9b6771b0b408517c82d97aed8f2036509bc247d46114925e32fe33f0/asttokens-3.0.1.tar.gz", hashes = {sha256 = "71a4ee5de0bde6a31d64f6b13f2293ac190344478f081c3d1bccfcf5eacb0cb7"}} -wheels = [ - {name = "asttokens-3.0.1-py3-none-any.whl",url = "https://files.pythonhosted.org/packages/d2/39/e7eaf1799466a4aef85b6a4fe7bd175ad2b1c6345066aa33f1f58d4b18d0/asttokens-3.0.1-py3-none-any.whl",hashes = {sha256 = "15a3ebc0f43c2d0a50eeafea25e19046c68398e487b9f1f5b517f7c0f40f976a"}}, -] -marker = "\"docs\" in extras" - -[packages.tool.pdm] -dependencies = [] - -[[packages]] -name = "attrs" -version = "26.1.0" -requires-python = ">=3.9" -sdist = {name = "attrs-26.1.0.tar.gz", url = "https://files.pythonhosted.org/packages/9a/8e/82a0fe20a541c03148528be8cac2408564a6c9a0cc7e9171802bc1d26985/attrs-26.1.0.tar.gz", hashes = {sha256 = "d03ceb89cb322a8fd706d4fb91940737b6642aa36998fe130a9bc96c985eff32"}} -wheels = [ - {name = "attrs-26.1.0-py3-none-any.whl",url = "https://files.pythonhosted.org/packages/64/b4/17d4b0b2a2dc85a6df63d1157e028ed19f90d4cd97c36717afef2bc2f395/attrs-26.1.0-py3-none-any.whl",hashes = {sha256 = "c647aa4a12dfbad9333ca4e71fe62ddc36f4e63b2d260a37a8b83d2f043ac309"}}, -] -marker = "\"docs\" in extras" - -[packages.tool.pdm] -dependencies = [] - -[[packages]] -name = "autograd" -version = "1.8.0" -requires-python = ">=3.9" -sdist = {name = "autograd-1.8.0.tar.gz", url = "https://files.pythonhosted.org/packages/67/1c/3c24ec03c8ba4decc742b1df5a10c52f98c84ca8797757f313e7bdcdf276/autograd-1.8.0.tar.gz", hashes = {sha256 = "107374ded5b09fc8643ac925348c0369e7b0e73bbed9565ffd61b8fd04425683"}} -wheels = [ - {name = "autograd-1.8.0-py3-none-any.whl",url = "https://files.pythonhosted.org/packages/84/ea/e16f0c423f7d83cf8b79cae9452040fb7b2e020c7439a167ee7c317de448/autograd-1.8.0-py3-none-any.whl",hashes = {sha256 = "4ab9084294f814cf56c280adbe19612546a35574d67c574b04933c7d2ecb7d78"}}, -] -marker = "\"default\" in dependency_groups" - -[packages.tool.pdm] -dependencies = [ - "numpy<3", -] - -[[packages]] -name = "autograd-gamma" -version = "0.5.0" -sdist = {name = "autograd-gamma-0.5.0.tar.gz", url = "https://files.pythonhosted.org/packages/85/ae/7f2031ea76140444b2453fa139041e5afd4a09fc5300cfefeb1103291f80/autograd-gamma-0.5.0.tar.gz", hashes = {sha256 = "f27abb7b8bb9cffc8badcbf59f3fe44a9db39e124ecacf1992b6d952934ac9c4"}} -marker = "\"default\" in dependency_groups" - -[packages.tool.pdm] -dependencies = [ - "autograd>=1.2.0", - "scipy>=1.2.0", -] - -[[packages]] -name = "babel" -version = "2.18.0" -requires-python = ">=3.8" -sdist = {name = "babel-2.18.0.tar.gz", url = "https://files.pythonhosted.org/packages/7d/b2/51899539b6ceeeb420d40ed3cd4b7a40519404f9baf3d4ac99dc413a834b/babel-2.18.0.tar.gz", hashes = {sha256 = "b80b99a14bd085fcacfa15c9165f651fbb3406e66cc603abf11c5750937c992d"}} -wheels = [ - {name = "babel-2.18.0-py3-none-any.whl",url = "https://files.pythonhosted.org/packages/77/f5/21d2de20e8b8b0408f0681956ca2c69f1320a3848ac50e6e7f39c6159675/babel-2.18.0-py3-none-any.whl",hashes = {sha256 = "e2b422b277c2b9a9630c1d7903c2a00d0830c409c59ac8cae9081c92f1aeba35"}}, -] -marker = "\"docs\" in extras" - -[packages.tool.pdm] -dependencies = [ - "pytz>=2015.7; python_version < \"3.9\"", -] - -[[packages]] -name = "beautifulsoup4" -version = "4.14.3" -requires-python = ">=3.7.0" -sdist = {name = "beautifulsoup4-4.14.3.tar.gz", url = "https://files.pythonhosted.org/packages/c3/b0/1c6a16426d389813b48d95e26898aff79abbde42ad353958ad95cc8c9b21/beautifulsoup4-4.14.3.tar.gz", hashes = {sha256 = "6292b1c5186d356bba669ef9f7f051757099565ad9ada5dd630bd9de5fa7fb86"}} -wheels = [ - {name = "beautifulsoup4-4.14.3-py3-none-any.whl",url = "https://files.pythonhosted.org/packages/1a/39/47f9197bdd44df24d67ac8893641e16f386c984a0619ef2ee4c51fbbc019/beautifulsoup4-4.14.3-py3-none-any.whl",hashes = {sha256 = "0918bfe44902e6ad8d57732ba310582e98da931428d231a5ecb9e7c703a735bb"}}, -] -marker = "\"docs\" in extras" - -[packages.tool.pdm] -dependencies = [ - "soupsieve>=1.6.1", - "typing-extensions>=4.0.0", -] - -[[packages]] -name = "bleach" -version = "6.3.0" -requires-python = ">=3.10" -sdist = {name = "bleach-6.3.0.tar.gz", url = "https://files.pythonhosted.org/packages/07/18/3c8523962314be6bf4c8989c79ad9531c825210dd13a8669f6b84336e8bd/bleach-6.3.0.tar.gz", hashes = {sha256 = "6f3b91b1c0a02bb9a78b5a454c92506aa0fdf197e1d5e114d2e00c6f64306d22"}} -wheels = [ - {name = "bleach-6.3.0-py3-none-any.whl",url = "https://files.pythonhosted.org/packages/cd/3a/577b549de0cc09d95f11087ee63c739bba856cd3952697eec4c4bb91350a/bleach-6.3.0-py3-none-any.whl",hashes = {sha256 = "fe10ec77c93ddf3d13a73b035abaac7a9f5e436513864ccdad516693213c65d6"}}, -] -marker = "\"docs\" in extras" - -[packages.tool.pdm] -dependencies = [ - "webencodings", -] - -[[packages]] -name = "certifi" -version = "2026.2.25" -requires-python = ">=3.7" -sdist = {name = "certifi-2026.2.25.tar.gz", url = "https://files.pythonhosted.org/packages/af/2d/7bf41579a8986e348fa033a31cdd0e4121114f6bce2457e8876010b092dd/certifi-2026.2.25.tar.gz", hashes = {sha256 = "e887ab5cee78ea814d3472169153c2d12cd43b14bd03329a39a9c6e2e80bfba7"}} -wheels = [ - {name = "certifi-2026.2.25-py3-none-any.whl",url = "https://files.pythonhosted.org/packages/9a/3c/c17fb3ca2d9c3acff52e30b309f538586f9f5b9c9cf454f3845fc9af4881/certifi-2026.2.25-py3-none-any.whl",hashes = {sha256 = "027692e4402ad994f1c42e52a4997a9763c646b73e4096e4d5d6db8af1d6f0fa"}}, -] -marker = "\"default\" in dependency_groups or \"docs\" in extras" - -[packages.tool.pdm] -dependencies = [] - -[[packages]] -name = "cffi" -version = "2.0.0" -requires-python = ">=3.9" -sdist = {name = "cffi-2.0.0.tar.gz", url = "https://files.pythonhosted.org/packages/eb/56/b1ba7935a17738ae8453301356628e8147c79dbb825bcbc73dc7401f9846/cffi-2.0.0.tar.gz", hashes = {sha256 = "44d1b5909021139fe36001ae048dbdde8214afa20200eda0f64c068cac5d5529"}} -wheels = [ - {name = "cffi-2.0.0-cp314-cp314-macosx_10_13_x86_64.whl",url = "https://files.pythonhosted.org/packages/92/c4/3ce07396253a83250ee98564f8d7e9789fab8e58858f35d07a9a2c78de9f/cffi-2.0.0-cp314-cp314-macosx_10_13_x86_64.whl",hashes = {sha256 = "fc33c5141b55ed366cfaad382df24fe7dcbc686de5be719b207bb248e3053dc5"}}, - {name = "cffi-2.0.0-cp314-cp314-macosx_11_0_arm64.whl",url = "https://files.pythonhosted.org/packages/59/dd/27e9fa567a23931c838c6b02d0764611c62290062a6d4e8ff7863daf9730/cffi-2.0.0-cp314-cp314-macosx_11_0_arm64.whl",hashes = {sha256 = "c654de545946e0db659b3400168c9ad31b5d29593291482c43e3564effbcee13"}}, - {name = "cffi-2.0.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.whl",url = "https://files.pythonhosted.org/packages/d6/43/0e822876f87ea8a4ef95442c3d766a06a51fc5298823f884ef87aaad168c/cffi-2.0.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.whl",hashes = {sha256 = "24b6f81f1983e6df8db3adc38562c83f7d4a0c36162885ec7f7b77c7dcbec97b"}}, - {name = "cffi-2.0.0-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl",url = "https://files.pythonhosted.org/packages/b4/89/76799151d9c2d2d1ead63c2429da9ea9d7aac304603de0c6e8764e6e8e70/cffi-2.0.0-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl",hashes = {sha256 = "12873ca6cb9b0f0d3a0da705d6086fe911591737a59f28b7936bdfed27c0d47c"}}, - {name = "cffi-2.0.0-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.whl",url = "https://files.pythonhosted.org/packages/bb/dd/3465b14bb9e24ee24cb88c9e3730f6de63111fffe513492bf8c808a3547e/cffi-2.0.0-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.whl",hashes = {sha256 = "d9b97165e8aed9272a6bb17c01e3cc5871a594a446ebedc996e2397a1c1ea8ef"}}, - {name = "cffi-2.0.0-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.whl",url = "https://files.pythonhosted.org/packages/47/d9/d83e293854571c877a92da46fdec39158f8d7e68da75bf73581225d28e90/cffi-2.0.0-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.whl",hashes = {sha256 = "afb8db5439b81cf9c9d0c80404b60c3cc9c3add93e114dcae767f1477cb53775"}}, - {name = "cffi-2.0.0-cp314-cp314-musllinux_1_2_aarch64.whl",url = "https://files.pythonhosted.org/packages/2b/0f/1f177e3683aead2bb00f7679a16451d302c436b5cbf2505f0ea8146ef59e/cffi-2.0.0-cp314-cp314-musllinux_1_2_aarch64.whl",hashes = {sha256 = "737fe7d37e1a1bffe70bd5754ea763a62a066dc5913ca57e957824b72a85e205"}}, - {name = "cffi-2.0.0-cp314-cp314-musllinux_1_2_x86_64.whl",url = "https://files.pythonhosted.org/packages/c6/0f/cafacebd4b040e3119dcb32fed8bdef8dfe94da653155f9d0b9dc660166e/cffi-2.0.0-cp314-cp314-musllinux_1_2_x86_64.whl",hashes = {sha256 = "38100abb9d1b1435bc4cc340bb4489635dc2f0da7456590877030c9b3d40b0c1"}}, - {name = "cffi-2.0.0-cp314-cp314-win32.whl",url = "https://files.pythonhosted.org/packages/3e/aa/df335faa45b395396fcbc03de2dfcab242cd61a9900e914fe682a59170b1/cffi-2.0.0-cp314-cp314-win32.whl",hashes = {sha256 = "087067fa8953339c723661eda6b54bc98c5625757ea62e95eb4898ad5e776e9f"}}, - {name = "cffi-2.0.0-cp314-cp314-win_amd64.whl",url = "https://files.pythonhosted.org/packages/bb/92/882c2d30831744296ce713f0feb4c1cd30f346ef747b530b5318715cc367/cffi-2.0.0-cp314-cp314-win_amd64.whl",hashes = {sha256 = "203a48d1fb583fc7d78a4c6655692963b860a417c0528492a6bc21f1aaefab25"}}, - {name = "cffi-2.0.0-cp314-cp314-win_arm64.whl",url = "https://files.pythonhosted.org/packages/9f/2c/98ece204b9d35a7366b5b2c6539c350313ca13932143e79dc133ba757104/cffi-2.0.0-cp314-cp314-win_arm64.whl",hashes = {sha256 = "dbd5c7a25a7cb98f5ca55d258b103a2054f859a46ae11aaf23134f9cc0d356ad"}}, - {name = "cffi-2.0.0-cp314-cp314t-macosx_10_13_x86_64.whl",url = "https://files.pythonhosted.org/packages/3e/61/c768e4d548bfa607abcda77423448df8c471f25dbe64fb2ef6d555eae006/cffi-2.0.0-cp314-cp314t-macosx_10_13_x86_64.whl",hashes = {sha256 = "9a67fc9e8eb39039280526379fb3a70023d77caec1852002b4da7e8b270c4dd9"}}, - {name = "cffi-2.0.0-cp314-cp314t-macosx_11_0_arm64.whl",url = "https://files.pythonhosted.org/packages/2c/ea/5f76bce7cf6fcd0ab1a1058b5af899bfbef198bea4d5686da88471ea0336/cffi-2.0.0-cp314-cp314t-macosx_11_0_arm64.whl",hashes = {sha256 = "7a66c7204d8869299919db4d5069a82f1561581af12b11b3c9f48c584eb8743d"}}, - {name = "cffi-2.0.0-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.whl",url = "https://files.pythonhosted.org/packages/be/b4/c56878d0d1755cf9caa54ba71e5d049479c52f9e4afc230f06822162ab2f/cffi-2.0.0-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.whl",hashes = {sha256 = "7cc09976e8b56f8cebd752f7113ad07752461f48a58cbba644139015ac24954c"}}, - {name = "cffi-2.0.0-cp314-cp314t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl",url = "https://files.pythonhosted.org/packages/e0/0d/eb704606dfe8033e7128df5e90fee946bbcb64a04fcdaa97321309004000/cffi-2.0.0-cp314-cp314t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl",hashes = {sha256 = "92b68146a71df78564e4ef48af17551a5ddd142e5190cdf2c5624d0c3ff5b2e8"}}, - {name = "cffi-2.0.0-cp314-cp314t-manylinux2014_s390x.manylinux_2_17_s390x.whl",url = "https://files.pythonhosted.org/packages/d8/19/3c435d727b368ca475fb8742ab97c9cb13a0de600ce86f62eab7fa3eea60/cffi-2.0.0-cp314-cp314t-manylinux2014_s390x.manylinux_2_17_s390x.whl",hashes = {sha256 = "b1e74d11748e7e98e2f426ab176d4ed720a64412b6a15054378afdb71e0f37dc"}}, - {name = "cffi-2.0.0-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl",url = "https://files.pythonhosted.org/packages/d0/44/681604464ed9541673e486521497406fadcc15b5217c3e326b061696899a/cffi-2.0.0-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl",hashes = {sha256 = "28a3a209b96630bca57cce802da70c266eb08c6e97e5afd61a75611ee6c64592"}}, - {name = "cffi-2.0.0-cp314-cp314t-musllinux_1_2_aarch64.whl",url = "https://files.pythonhosted.org/packages/25/8e/342a504ff018a2825d395d44d63a767dd8ebc927ebda557fecdaca3ac33a/cffi-2.0.0-cp314-cp314t-musllinux_1_2_aarch64.whl",hashes = {sha256 = "7553fb2090d71822f02c629afe6042c299edf91ba1bf94951165613553984512"}}, - {name = "cffi-2.0.0-cp314-cp314t-musllinux_1_2_x86_64.whl",url = "https://files.pythonhosted.org/packages/e1/5e/b666bacbbc60fbf415ba9988324a132c9a7a0448a9a8f125074671c0f2c3/cffi-2.0.0-cp314-cp314t-musllinux_1_2_x86_64.whl",hashes = {sha256 = "6c6c373cfc5c83a975506110d17457138c8c63016b563cc9ed6e056a82f13ce4"}}, - {name = "cffi-2.0.0-cp314-cp314t-win32.whl",url = "https://files.pythonhosted.org/packages/a0/1d/ec1a60bd1a10daa292d3cd6bb0b359a81607154fb8165f3ec95fe003b85c/cffi-2.0.0-cp314-cp314t-win32.whl",hashes = {sha256 = "1fc9ea04857caf665289b7a75923f2c6ed559b8298a1b8c49e59f7dd95c8481e"}}, - {name = "cffi-2.0.0-cp314-cp314t-win_amd64.whl",url = "https://files.pythonhosted.org/packages/bf/41/4c1168c74fac325c0c8156f04b6749c8b6a8f405bbf91413ba088359f60d/cffi-2.0.0-cp314-cp314t-win_amd64.whl",hashes = {sha256 = "d68b6cef7827e8641e8ef16f4494edda8b36104d79773a334beaa1e3521430f6"}}, - {name = "cffi-2.0.0-cp314-cp314t-win_arm64.whl",url = "https://files.pythonhosted.org/packages/ae/3a/dbeec9d1ee0844c679f6bb5d6ad4e9f198b1224f4e7a32825f47f6192b0c/cffi-2.0.0-cp314-cp314t-win_arm64.whl",hashes = {sha256 = "0a1527a803f0a659de1af2e1fd700213caba79377e27e4693648c2923da066f9"}}, - {name = "cffi-2.0.0-cp313-cp313-macosx_10_13_x86_64.whl",url = "https://files.pythonhosted.org/packages/4b/8d/a0a47a0c9e413a658623d014e91e74a50cdd2c423f7ccfd44086ef767f90/cffi-2.0.0-cp313-cp313-macosx_10_13_x86_64.whl",hashes = {sha256 = "00bdf7acc5f795150faa6957054fbbca2439db2f775ce831222b66f192f03beb"}}, - {name = "cffi-2.0.0-cp313-cp313-macosx_11_0_arm64.whl",url = "https://files.pythonhosted.org/packages/4a/d2/a6c0296814556c68ee32009d9c2ad4f85f2707cdecfd7727951ec228005d/cffi-2.0.0-cp313-cp313-macosx_11_0_arm64.whl",hashes = {sha256 = "45d5e886156860dc35862657e1494b9bae8dfa63bf56796f2fb56e1679fc0bca"}}, - {name = "cffi-2.0.0-cp313-cp313-manylinux1_i686.manylinux2014_i686.manylinux_2_17_i686.manylinux_2_5_i686.whl",url = "https://files.pythonhosted.org/packages/b0/1e/d22cc63332bd59b06481ceaac49d6c507598642e2230f201649058a7e704/cffi-2.0.0-cp313-cp313-manylinux1_i686.manylinux2014_i686.manylinux_2_17_i686.manylinux_2_5_i686.whl",hashes = {sha256 = "07b271772c100085dd28b74fa0cd81c8fb1a3ba18b21e03d7c27f3436a10606b"}}, - {name = "cffi-2.0.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.whl",url = "https://files.pythonhosted.org/packages/a9/f5/a2c23eb03b61a0b8747f211eb716446c826ad66818ddc7810cc2cc19b3f2/cffi-2.0.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.whl",hashes = {sha256 = "d48a880098c96020b02d5a1f7d9251308510ce8858940e6fa99ece33f610838b"}}, - {name = "cffi-2.0.0-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl",url = "https://files.pythonhosted.org/packages/f2/7f/e6647792fc5850d634695bc0e6ab4111ae88e89981d35ac269956605feba/cffi-2.0.0-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl",hashes = {sha256 = "f93fd8e5c8c0a4aa1f424d6173f14a892044054871c771f8566e4008eaa359d2"}}, - {name = "cffi-2.0.0-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.whl",url = "https://files.pythonhosted.org/packages/cb/1e/a5a1bd6f1fb30f22573f76533de12a00bf274abcdc55c8edab639078abb6/cffi-2.0.0-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.whl",hashes = {sha256 = "dd4f05f54a52fb558f1ba9f528228066954fee3ebe629fc1660d874d040ae5a3"}}, - {name = "cffi-2.0.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl",url = "https://files.pythonhosted.org/packages/98/df/0a1755e750013a2081e863e7cd37e0cdd02664372c754e5560099eb7aa44/cffi-2.0.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl",hashes = {sha256 = "c8d3b5532fc71b7a77c09192b4a5a200ea992702734a2e9279a37f2478236f26"}}, - {name = "cffi-2.0.0-cp313-cp313-musllinux_1_2_aarch64.whl",url = "https://files.pythonhosted.org/packages/50/e1/a969e687fcf9ea58e6e2a928ad5e2dd88cc12f6f0ab477e9971f2309b57c/cffi-2.0.0-cp313-cp313-musllinux_1_2_aarch64.whl",hashes = {sha256 = "d9b29c1f0ae438d5ee9acb31cadee00a58c46cc9c0b2f9038c6b0b3470877a8c"}}, - {name = "cffi-2.0.0-cp313-cp313-musllinux_1_2_x86_64.whl",url = "https://files.pythonhosted.org/packages/36/54/0362578dd2c9e557a28ac77698ed67323ed5b9775ca9d3fe73fe191bb5d8/cffi-2.0.0-cp313-cp313-musllinux_1_2_x86_64.whl",hashes = {sha256 = "6d50360be4546678fc1b79ffe7a66265e28667840010348dd69a314145807a1b"}}, - {name = "cffi-2.0.0-cp313-cp313-win32.whl",url = "https://files.pythonhosted.org/packages/eb/6d/bf9bda840d5f1dfdbf0feca87fbdb64a918a69bca42cfa0ba7b137c48cb8/cffi-2.0.0-cp313-cp313-win32.whl",hashes = {sha256 = "74a03b9698e198d47562765773b4a8309919089150a0bb17d829ad7b44b60d27"}}, - {name = "cffi-2.0.0-cp313-cp313-win_amd64.whl",url = "https://files.pythonhosted.org/packages/37/18/6519e1ee6f5a1e579e04b9ddb6f1676c17368a7aba48299c3759bbc3c8b3/cffi-2.0.0-cp313-cp313-win_amd64.whl",hashes = {sha256 = "19f705ada2530c1167abacb171925dd886168931e0a7b78f5bffcae5c6b5be75"}}, - {name = "cffi-2.0.0-cp313-cp313-win_arm64.whl",url = "https://files.pythonhosted.org/packages/cb/0e/02ceeec9a7d6ee63bb596121c2c8e9b3a9e150936f4fbef6ca1943e6137c/cffi-2.0.0-cp313-cp313-win_arm64.whl",hashes = {sha256 = "256f80b80ca3853f90c21b23ee78cd008713787b1b1e93eae9f3d6a7134abd91"}}, - {name = "cffi-2.0.0-cp312-cp312-macosx_10_13_x86_64.whl",url = "https://files.pythonhosted.org/packages/ea/47/4f61023ea636104d4f16ab488e268b93008c3d0bb76893b1b31db1f96802/cffi-2.0.0-cp312-cp312-macosx_10_13_x86_64.whl",hashes = {sha256 = "6d02d6655b0e54f54c4ef0b94eb6be0607b70853c45ce98bd278dc7de718be5d"}}, - {name = "cffi-2.0.0-cp312-cp312-macosx_11_0_arm64.whl",url = "https://files.pythonhosted.org/packages/df/a2/781b623f57358e360d62cdd7a8c681f074a71d445418a776eef0aadb4ab4/cffi-2.0.0-cp312-cp312-macosx_11_0_arm64.whl",hashes = {sha256 = "8eca2a813c1cb7ad4fb74d368c2ffbbb4789d377ee5bb8df98373c2cc0dee76c"}}, - {name = "cffi-2.0.0-cp312-cp312-manylinux1_i686.manylinux2014_i686.manylinux_2_17_i686.manylinux_2_5_i686.whl",url = "https://files.pythonhosted.org/packages/ff/df/a4f0fbd47331ceeba3d37c2e51e9dfc9722498becbeec2bd8bc856c9538a/cffi-2.0.0-cp312-cp312-manylinux1_i686.manylinux2014_i686.manylinux_2_17_i686.manylinux_2_5_i686.whl",hashes = {sha256 = "21d1152871b019407d8ac3985f6775c079416c282e431a4da6afe7aefd2bccbe"}}, - {name = "cffi-2.0.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.whl",url = "https://files.pythonhosted.org/packages/d5/72/12b5f8d3865bf0f87cf1404d8c374e7487dcf097a1c91c436e72e6badd83/cffi-2.0.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.whl",hashes = {sha256 = "b21e08af67b8a103c71a250401c78d5e0893beff75e28c53c98f4de42f774062"}}, - {name = "cffi-2.0.0-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl",url = "https://files.pythonhosted.org/packages/c2/95/7a135d52a50dfa7c882ab0ac17e8dc11cec9d55d2c18dda414c051c5e69e/cffi-2.0.0-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl",hashes = {sha256 = "1e3a615586f05fc4065a8b22b8152f0c1b00cdbc60596d187c2a74f9e3036e4e"}}, - {name = "cffi-2.0.0-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.whl",url = "https://files.pythonhosted.org/packages/3a/c8/15cb9ada8895957ea171c62dc78ff3e99159ee7adb13c0123c001a2546c1/cffi-2.0.0-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.whl",hashes = {sha256 = "81afed14892743bbe14dacb9e36d9e0e504cd204e0b165062c488942b9718037"}}, - {name = "cffi-2.0.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl",url = "https://files.pythonhosted.org/packages/78/2d/7fa73dfa841b5ac06c7b8855cfc18622132e365f5b81d02230333ff26e9e/cffi-2.0.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl",hashes = {sha256 = "3e17ed538242334bf70832644a32a7aae3d83b57567f9fd60a26257e992b79ba"}}, - {name = "cffi-2.0.0-cp312-cp312-musllinux_1_2_aarch64.whl",url = "https://files.pythonhosted.org/packages/07/e0/267e57e387b4ca276b90f0434ff88b2c2241ad72b16d31836adddfd6031b/cffi-2.0.0-cp312-cp312-musllinux_1_2_aarch64.whl",hashes = {sha256 = "3925dd22fa2b7699ed2617149842d2e6adde22b262fcbfada50e3d195e4b3a94"}}, - {name = "cffi-2.0.0-cp312-cp312-musllinux_1_2_x86_64.whl",url = "https://files.pythonhosted.org/packages/b6/75/1f2747525e06f53efbd878f4d03bac5b859cbc11c633d0fb81432d98a795/cffi-2.0.0-cp312-cp312-musllinux_1_2_x86_64.whl",hashes = {sha256 = "2c8f814d84194c9ea681642fd164267891702542f028a15fc97d4674b6206187"}}, - {name = "cffi-2.0.0-cp312-cp312-win32.whl",url = "https://files.pythonhosted.org/packages/7b/2b/2b6435f76bfeb6bbf055596976da087377ede68df465419d192acf00c437/cffi-2.0.0-cp312-cp312-win32.whl",hashes = {sha256 = "da902562c3e9c550df360bfa53c035b2f241fed6d9aef119048073680ace4a18"}}, - {name = "cffi-2.0.0-cp312-cp312-win_amd64.whl",url = "https://files.pythonhosted.org/packages/f8/ed/13bd4418627013bec4ed6e54283b1959cf6db888048c7cf4b4c3b5b36002/cffi-2.0.0-cp312-cp312-win_amd64.whl",hashes = {sha256 = "da68248800ad6320861f129cd9c1bf96ca849a2771a59e0344e88681905916f5"}}, - {name = "cffi-2.0.0-cp312-cp312-win_arm64.whl",url = "https://files.pythonhosted.org/packages/95/31/9f7f93ad2f8eff1dbc1c3656d7ca5bfd8fb52c9d786b4dcf19b2d02217fa/cffi-2.0.0-cp312-cp312-win_arm64.whl",hashes = {sha256 = "4671d9dd5ec934cb9a73e7ee9676f9362aba54f7f34910956b84d727b0d73fb6"}}, - {name = "cffi-2.0.0-cp311-cp311-macosx_10_13_x86_64.whl",url = "https://files.pythonhosted.org/packages/12/4a/3dfd5f7850cbf0d06dc84ba9aa00db766b52ca38d8b86e3a38314d52498c/cffi-2.0.0-cp311-cp311-macosx_10_13_x86_64.whl",hashes = {sha256 = "b4c854ef3adc177950a8dfc81a86f5115d2abd545751a304c5bcf2c2c7283cfe"}}, - {name = "cffi-2.0.0-cp311-cp311-macosx_11_0_arm64.whl",url = "https://files.pythonhosted.org/packages/4f/8b/f0e4c441227ba756aafbe78f117485b25bb26b1c059d01f137fa6d14896b/cffi-2.0.0-cp311-cp311-macosx_11_0_arm64.whl",hashes = {sha256 = "2de9a304e27f7596cd03d16f1b7c72219bd944e99cc52b84d0145aefb07cbd3c"}}, - {name = "cffi-2.0.0-cp311-cp311-manylinux1_i686.manylinux2014_i686.manylinux_2_17_i686.manylinux_2_5_i686.whl",url = "https://files.pythonhosted.org/packages/b1/b7/1200d354378ef52ec227395d95c2576330fd22a869f7a70e88e1447eb234/cffi-2.0.0-cp311-cp311-manylinux1_i686.manylinux2014_i686.manylinux_2_17_i686.manylinux_2_5_i686.whl",hashes = {sha256 = "baf5215e0ab74c16e2dd324e8ec067ef59e41125d3eade2b863d294fd5035c92"}}, - {name = "cffi-2.0.0-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.whl",url = "https://files.pythonhosted.org/packages/b8/56/6033f5e86e8cc9bb629f0077ba71679508bdf54a9a5e112a3c0b91870332/cffi-2.0.0-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.whl",hashes = {sha256 = "730cacb21e1bdff3ce90babf007d0a0917cc3e6492f336c2f0134101e0944f93"}}, - {name = "cffi-2.0.0-cp311-cp311-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl",url = "https://files.pythonhosted.org/packages/dc/7f/55fecd70f7ece178db2f26128ec41430d8720f2d12ca97bf8f0a628207d5/cffi-2.0.0-cp311-cp311-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl",hashes = {sha256 = "6824f87845e3396029f3820c206e459ccc91760e8fa24422f8b0c3d1731cbec5"}}, - {name = "cffi-2.0.0-cp311-cp311-manylinux2014_s390x.manylinux_2_17_s390x.whl",url = "https://files.pythonhosted.org/packages/84/ef/a7b77c8bdc0f77adc3b46888f1ad54be8f3b7821697a7b89126e829e676a/cffi-2.0.0-cp311-cp311-manylinux2014_s390x.manylinux_2_17_s390x.whl",hashes = {sha256 = "9de40a7b0323d889cf8d23d1ef214f565ab154443c42737dfe52ff82cf857664"}}, - {name = "cffi-2.0.0-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl",url = "https://files.pythonhosted.org/packages/d7/91/500d892b2bf36529a75b77958edfcd5ad8e2ce4064ce2ecfeab2125d72d1/cffi-2.0.0-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl",hashes = {sha256 = "8941aaadaf67246224cee8c3803777eed332a19d909b47e29c9842ef1e79ac26"}}, - {name = "cffi-2.0.0-cp311-cp311-musllinux_1_2_aarch64.whl",url = "https://files.pythonhosted.org/packages/44/64/58f6255b62b101093d5df22dcb752596066c7e89dd725e0afaed242a61be/cffi-2.0.0-cp311-cp311-musllinux_1_2_aarch64.whl",hashes = {sha256 = "a05d0c237b3349096d3981b727493e22147f934b20f6f125a3eba8f994bec4a9"}}, - {name = "cffi-2.0.0-cp311-cp311-musllinux_1_2_i686.whl",url = "https://files.pythonhosted.org/packages/ab/49/fa72cebe2fd8a55fbe14956f9970fe8eb1ac59e5df042f603ef7c8ba0adc/cffi-2.0.0-cp311-cp311-musllinux_1_2_i686.whl",hashes = {sha256 = "94698a9c5f91f9d138526b48fe26a199609544591f859c870d477351dc7b2414"}}, - {name = "cffi-2.0.0-cp311-cp311-musllinux_1_2_x86_64.whl",url = "https://files.pythonhosted.org/packages/0b/28/dd0967a76aab36731b6ebfe64dec4e981aff7e0608f60c2d46b46982607d/cffi-2.0.0-cp311-cp311-musllinux_1_2_x86_64.whl",hashes = {sha256 = "5fed36fccc0612a53f1d4d9a816b50a36702c28a2aa880cb8a122b3466638743"}}, - {name = "cffi-2.0.0-cp311-cp311-win32.whl",url = "https://files.pythonhosted.org/packages/2b/c0/015b25184413d7ab0a410775fdb4a50fca20f5589b5dab1dbbfa3baad8ce/cffi-2.0.0-cp311-cp311-win32.whl",hashes = {sha256 = "c649e3a33450ec82378822b3dad03cc228b8f5963c0c12fc3b1e0ab940f768a5"}}, - {name = "cffi-2.0.0-cp311-cp311-win_amd64.whl",url = "https://files.pythonhosted.org/packages/ae/8f/dc5531155e7070361eb1b7e4c1a9d896d0cb21c49f807a6c03fd63fc877e/cffi-2.0.0-cp311-cp311-win_amd64.whl",hashes = {sha256 = "66f011380d0e49ed280c789fbd08ff0d40968ee7b665575489afa95c98196ab5"}}, - {name = "cffi-2.0.0-cp311-cp311-win_arm64.whl",url = "https://files.pythonhosted.org/packages/95/5c/1b493356429f9aecfd56bc171285a4c4ac8697f76e9bbbbb105e537853a1/cffi-2.0.0-cp311-cp311-win_arm64.whl",hashes = {sha256 = "c6638687455baf640e37344fe26d37c404db8b80d037c3d29f58fe8d1c3b194d"}}, -] -marker = "implementation_name == \"pypy\" and \"docs\" in extras" - -[packages.tool.pdm] -dependencies = [ - "pycparser; implementation_name != \"PyPy\"", -] - -[[packages]] -name = "charset-normalizer" -version = "3.4.7" -requires-python = ">=3.7" -sdist = {name = "charset_normalizer-3.4.7.tar.gz", url = "https://files.pythonhosted.org/packages/e7/a1/67fe25fac3c7642725500a3f6cfe5821ad557c3abb11c9d20d12c7008d3e/charset_normalizer-3.4.7.tar.gz", hashes = {sha256 = "ae89db9e5f98a11a4bf50407d4363e7b09b31e55bc117b4f7d80aab97ba009e5"}} -wheels = [ - {name = "charset_normalizer-3.4.7-cp314-cp314-macosx_10_15_universal2.whl",url = "https://files.pythonhosted.org/packages/97/c8/c67cb8c70e19ef1960b97b22ed2a1567711de46c4ddf19799923adc836c2/charset_normalizer-3.4.7-cp314-cp314-macosx_10_15_universal2.whl",hashes = {sha256 = "c36c333c39be2dbca264d7803333c896ab8fa7d4d6f0ab7edb7dfd7aea6e98c0"}}, - {name = "charset_normalizer-3.4.7-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl",url = "https://files.pythonhosted.org/packages/99/85/c091fdee33f20de70d6c8b522743b6f831a2f1cd3ff86de4c6a827c48a76/charset_normalizer-3.4.7-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl",hashes = {sha256 = "1c2aed2e5e41f24ea8ef1590b8e848a79b56f3a5564a65ceec43c9d692dc7d8a"}}, - {name = "charset_normalizer-3.4.7-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl",url = "https://files.pythonhosted.org/packages/87/1c/ab2ce611b984d2fd5d86a5a8a19c1ae26acac6bad967da4967562c75114d/charset_normalizer-3.4.7-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl",hashes = {sha256 = "54523e136b8948060c0fa0bc7b1b50c32c186f2fceee897a495406bb6e311d2b"}}, - {name = "charset_normalizer-3.4.7-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl",url = "https://files.pythonhosted.org/packages/a8/29/2b1d2cb00bf085f59d29eb773ce58ec2d325430f8c216804a0a5cd83cbca/charset_normalizer-3.4.7-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl",hashes = {sha256 = "715479b9a2802ecac752a3b0efa2b0b60285cf962ee38414211abdfccc233b41"}}, - {name = "charset_normalizer-3.4.7-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl",url = "https://files.pythonhosted.org/packages/47/5c/032c2d5a07fe4d4855fea851209cca2b6f03ebeb6d4e3afdb3358386a684/charset_normalizer-3.4.7-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl",hashes = {sha256 = "bd6c2a1c7573c64738d716488d2cdd3c00e340e4835707d8fdb8dc1a66ef164e"}}, - {name = "charset_normalizer-3.4.7-cp314-cp314-manylinux_2_31_armv7l.whl",url = "https://files.pythonhosted.org/packages/2c/c2/356065d5a8b78ed04499cae5f339f091946a6a74f91e03476c33f0ab7100/charset_normalizer-3.4.7-cp314-cp314-manylinux_2_31_armv7l.whl",hashes = {sha256 = "c45e9440fb78f8ddabcf714b68f936737a121355bf59f3907f4e17721b9d1aae"}}, - {name = "charset_normalizer-3.4.7-cp314-cp314-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl",url = "https://files.pythonhosted.org/packages/0c/cd/a32a84217ced5039f53b29f460962abb2d4420def55afabe45b1c3c7483d/charset_normalizer-3.4.7-cp314-cp314-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl",hashes = {sha256 = "3534e7dcbdcf757da6b85a0bbf5b6868786d5982dd959b065e65481644817a18"}}, - {name = "charset_normalizer-3.4.7-cp314-cp314-musllinux_1_2_aarch64.whl",url = "https://files.pythonhosted.org/packages/44/86/58e6f13ce26cc3b8f4a36b94a0f22ae2f00a72534520f4ae6857c4b81f89/charset_normalizer-3.4.7-cp314-cp314-musllinux_1_2_aarch64.whl",hashes = {sha256 = "e8ac484bf18ce6975760921bb6148041faa8fef0547200386ea0b52b5d27bf7b"}}, - {name = "charset_normalizer-3.4.7-cp314-cp314-musllinux_1_2_armv7l.whl",url = "https://files.pythonhosted.org/packages/8f/fe/d17c32dc72e17e155e06883efa84514ca375f8a528ba2546bee73fc4df81/charset_normalizer-3.4.7-cp314-cp314-musllinux_1_2_armv7l.whl",hashes = {sha256 = "a5fe03b42827c13cdccd08e6c0247b6a6d4b5e3cdc53fd1749f5896adcdc2356"}}, - {name = "charset_normalizer-3.4.7-cp314-cp314-musllinux_1_2_ppc64le.whl",url = "https://files.pythonhosted.org/packages/6a/29/f33daa50b06525a237451cdb6c69da366c381a3dadcd833fa5676bc468b3/charset_normalizer-3.4.7-cp314-cp314-musllinux_1_2_ppc64le.whl",hashes = {sha256 = "2d6eb928e13016cea4f1f21d1e10c1cebd5a421bc57ddf5b1142ae3f86824fab"}}, - {name = "charset_normalizer-3.4.7-cp314-cp314-musllinux_1_2_riscv64.whl",url = "https://files.pythonhosted.org/packages/b6/6e/52c84015394a6a0bdcd435210a7e944c5f94ea1055f5cc5d56c5fe368e7b/charset_normalizer-3.4.7-cp314-cp314-musllinux_1_2_riscv64.whl",hashes = {sha256 = "e74327fb75de8986940def6e8dee4f127cc9752bee7355bb323cc5b2659b6d46"}}, - {name = "charset_normalizer-3.4.7-cp314-cp314-musllinux_1_2_s390x.whl",url = "https://files.pythonhosted.org/packages/8c/d7/4353be581b373033fb9198bf1da3cf8f09c1082561e8e922aa7b39bf9fe8/charset_normalizer-3.4.7-cp314-cp314-musllinux_1_2_s390x.whl",hashes = {sha256 = "d6038d37043bced98a66e68d3aa2b6a35505dc01328cd65217cefe82f25def44"}}, - {name = "charset_normalizer-3.4.7-cp314-cp314-musllinux_1_2_x86_64.whl",url = "https://files.pythonhosted.org/packages/30/45/99d18aa925bd1740098ccd3060e238e21115fffbfdcb8f3ece837d0ace6c/charset_normalizer-3.4.7-cp314-cp314-musllinux_1_2_x86_64.whl",hashes = {sha256 = "7579e913a5339fb8fa133f6bbcfd8e6749696206cf05acdbdca71a1b436d8e72"}}, - {name = "charset_normalizer-3.4.7-cp314-cp314-win32.whl",url = "https://files.pythonhosted.org/packages/5c/05/5ee478aa53f4bb7996482153d4bfe1b89e0f087f0ab6b294fcf92d595873/charset_normalizer-3.4.7-cp314-cp314-win32.whl",hashes = {sha256 = "5b77459df20e08151cd6f8b9ef8ef1f961ef73d85c21a555c7eed5b79410ec10"}}, - {name = "charset_normalizer-3.4.7-cp314-cp314-win_amd64.whl",url = "https://files.pythonhosted.org/packages/48/77/72dcb0921b2ce86420b2d79d454c7022bf5be40202a2a07906b9f2a35c97/charset_normalizer-3.4.7-cp314-cp314-win_amd64.whl",hashes = {sha256 = "92a0a01ead5e668468e952e4238cccd7c537364eb7d851ab144ab6627dbbe12f"}}, - {name = "charset_normalizer-3.4.7-cp314-cp314-win_arm64.whl",url = "https://files.pythonhosted.org/packages/c6/a3/c2369911cd72f02386e4e340770f6e158c7980267da16af8f668217abaa0/charset_normalizer-3.4.7-cp314-cp314-win_arm64.whl",hashes = {sha256 = "67f6279d125ca0046a7fd386d01b311c6363844deac3e5b069b514ba3e63c246"}}, - {name = "charset_normalizer-3.4.7-cp314-cp314t-macosx_10_15_universal2.whl",url = "https://files.pythonhosted.org/packages/94/09/7e8a7f73d24dba1f0035fbbf014d2c36828fc1bf9c88f84093e57d315935/charset_normalizer-3.4.7-cp314-cp314t-macosx_10_15_universal2.whl",hashes = {sha256 = "effc3f449787117233702311a1b7d8f59cba9ced946ba727bdc329ec69028e24"}}, - {name = "charset_normalizer-3.4.7-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl",url = "https://files.pythonhosted.org/packages/8d/da/96975ddb11f8e977f706f45cddd8540fd8242f71ecdb5d18a80723dcf62c/charset_normalizer-3.4.7-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl",hashes = {sha256 = "fbccdc05410c9ee21bbf16a35f4c1d16123dcdeb8a1d38f33654fa21d0234f79"}}, - {name = "charset_normalizer-3.4.7-cp314-cp314t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl",url = "https://files.pythonhosted.org/packages/e5/e8/1d63bf8ef2d388e95c64b2098f45f84758f6d102a087552da1485912637b/charset_normalizer-3.4.7-cp314-cp314t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl",hashes = {sha256 = "733784b6d6def852c814bce5f318d25da2ee65dd4839a0718641c696e09a2960"}}, - {name = "charset_normalizer-3.4.7-cp314-cp314t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl",url = "https://files.pythonhosted.org/packages/9b/40/e5ff04233e70da2681fa43969ad6f66ca5611d7e669be0246c4c7aaf6dc8/charset_normalizer-3.4.7-cp314-cp314t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl",hashes = {sha256 = "a89c23ef8d2c6b27fd200a42aa4ac72786e7c60d40efdc76e6011260b6e949c4"}}, - {name = "charset_normalizer-3.4.7-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl",url = "https://files.pythonhosted.org/packages/be/c1/06c6c49d5a5450f76899992f1ee40b41d076aee9279b49cf9974d2f313d5/charset_normalizer-3.4.7-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl",hashes = {sha256 = "6c114670c45346afedc0d947faf3c7f701051d2518b943679c8ff88befe14f8e"}}, - {name = "charset_normalizer-3.4.7-cp314-cp314t-manylinux_2_31_armv7l.whl",url = "https://files.pythonhosted.org/packages/2b/9f/f2ff16fb050946169e3e1f82134d107e5d4ae72647ec8a1b1446c148480f/charset_normalizer-3.4.7-cp314-cp314t-manylinux_2_31_armv7l.whl",hashes = {sha256 = "a180c5e59792af262bf263b21a3c49353f25945d8d9f70628e73de370d55e1e1"}}, - {name = "charset_normalizer-3.4.7-cp314-cp314t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl",url = "https://files.pythonhosted.org/packages/69/d5/a527c0cd8d64d2eab7459784fb4169a0ac76e5a6fc5237337982fd61347e/charset_normalizer-3.4.7-cp314-cp314t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl",hashes = {sha256 = "3c9a494bc5ec77d43cea229c4f6db1e4d8fe7e1bbffa8b6f0f0032430ff8ab44"}}, - {name = "charset_normalizer-3.4.7-cp314-cp314t-musllinux_1_2_aarch64.whl",url = "https://files.pythonhosted.org/packages/7e/80/8a7b8104a3e203074dc9aa2c613d4b726c0e136bad1cc734594b02867972/charset_normalizer-3.4.7-cp314-cp314t-musllinux_1_2_aarch64.whl",hashes = {sha256 = "8d828b6667a32a728a1ad1d93957cdf37489c57b97ae6c4de2860fa749b8fc1e"}}, - {name = "charset_normalizer-3.4.7-cp314-cp314t-musllinux_1_2_armv7l.whl",url = "https://files.pythonhosted.org/packages/02/9a/b759b503d507f375b2b5c153e4d2ee0a75aa215b7f2489cf314f4541f2c0/charset_normalizer-3.4.7-cp314-cp314t-musllinux_1_2_armv7l.whl",hashes = {sha256 = "cf1493cd8607bec4d8a7b9b004e699fcf8f9103a9284cc94962cb73d20f9d4a3"}}, - {name = "charset_normalizer-3.4.7-cp314-cp314t-musllinux_1_2_ppc64le.whl",url = "https://files.pythonhosted.org/packages/c2/4e/0f3f5d47b86bdb79256e7290b26ac847a2832d9a4033f7eb2cd4bcf4bb5b/charset_normalizer-3.4.7-cp314-cp314t-musllinux_1_2_ppc64le.whl",hashes = {sha256 = "0c96c3b819b5c3e9e165495db84d41914d6894d55181d2d108cc1a69bfc9cce0"}}, - {name = "charset_normalizer-3.4.7-cp314-cp314t-musllinux_1_2_riscv64.whl",url = "https://files.pythonhosted.org/packages/96/23/bce28734eb3ed2c91dcf93abeb8a5cf393a7b2749725030bb630e554fdd8/charset_normalizer-3.4.7-cp314-cp314t-musllinux_1_2_riscv64.whl",hashes = {sha256 = "752a45dc4a6934060b3b0dab47e04edc3326575f82be64bc4fc293914566503e"}}, - {name = "charset_normalizer-3.4.7-cp314-cp314t-musllinux_1_2_s390x.whl",url = "https://files.pythonhosted.org/packages/2c/6f/6e897c6984cc4d41af319b077f2f600fc8214eb2fe2d6bcb79141b882400/charset_normalizer-3.4.7-cp314-cp314t-musllinux_1_2_s390x.whl",hashes = {sha256 = "8778f0c7a52e56f75d12dae53ae320fae900a8b9b4164b981b9c5ce059cd1fcb"}}, - {name = "charset_normalizer-3.4.7-cp314-cp314t-musllinux_1_2_x86_64.whl",url = "https://files.pythonhosted.org/packages/76/22/ef7bd0fe480a0ae9b656189ec00744b60933f68b4f42a7bb06589f6f576a/charset_normalizer-3.4.7-cp314-cp314t-musllinux_1_2_x86_64.whl",hashes = {sha256 = "ce3412fbe1e31eb81ea42f4169ed94861c56e643189e1e75f0041f3fe7020abe"}}, - {name = "charset_normalizer-3.4.7-cp314-cp314t-win32.whl",url = "https://files.pythonhosted.org/packages/c5/a7/0e0ab3e0b5bc1219bd80a6a0d4d72ca74d9250cb2382b7c699c147e06017/charset_normalizer-3.4.7-cp314-cp314t-win32.whl",hashes = {sha256 = "c03a41a8784091e67a39648f70c5f97b5b6a37f216896d44d2cdcb82615339a0"}}, - {name = "charset_normalizer-3.4.7-cp314-cp314t-win_amd64.whl",url = "https://files.pythonhosted.org/packages/7a/1d/29d32e0fb40864b1f878c7f5a0b343ae676c6e2b271a2d55cc3a152391da/charset_normalizer-3.4.7-cp314-cp314t-win_amd64.whl",hashes = {sha256 = "03853ed82eeebbce3c2abfdbc98c96dc205f32a79627688ac9a27370ea61a49c"}}, - {name = "charset_normalizer-3.4.7-cp314-cp314t-win_arm64.whl",url = "https://files.pythonhosted.org/packages/de/32/d92444ad05c7a6e41fb2036749777c163baf7a0301a040cb672d6b2b1ae9/charset_normalizer-3.4.7-cp314-cp314t-win_arm64.whl",hashes = {sha256 = "c35abb8bfff0185efac5878da64c45dafd2b37fb0383add1be155a763c1f083d"}}, - {name = "charset_normalizer-3.4.7-cp313-cp313-macosx_10_13_universal2.whl",url = "https://files.pythonhosted.org/packages/c1/3b/66777e39d3ae1ddc77ee606be4ec6d8cbd4c801f65e5a1b6f2b11b8346dd/charset_normalizer-3.4.7-cp313-cp313-macosx_10_13_universal2.whl",hashes = {sha256 = "f496c9c3cc02230093d8330875c4c3cdfc3b73612a5fd921c65d39cbcef08063"}}, - {name = "charset_normalizer-3.4.7-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl",url = "https://files.pythonhosted.org/packages/2e/4e/b7f84e617b4854ade48a1b7915c8ccfadeba444d2a18c291f696e37f0d3b/charset_normalizer-3.4.7-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl",hashes = {sha256 = "0ea948db76d31190bf08bd371623927ee1339d5f2a0b4b1b4a4439a65298703c"}}, - {name = "charset_normalizer-3.4.7-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl",url = "https://files.pythonhosted.org/packages/c4/bb/ec73c0257c9e11b268f018f068f5d00aa0ef8c8b09f7753ebd5f2880e248/charset_normalizer-3.4.7-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl",hashes = {sha256 = "a277ab8928b9f299723bc1a2dabb1265911b1a76341f90a510368ca44ad9ab66"}}, - {name = "charset_normalizer-3.4.7-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl",url = "https://files.pythonhosted.org/packages/85/fb/32d1f5033484494619f701e719429c69b766bfc4dbc61aa9e9c8c166528b/charset_normalizer-3.4.7-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl",hashes = {sha256 = "3bec022aec2c514d9cf199522a802bd007cd588ab17ab2525f20f9c34d067c18"}}, - {name = "charset_normalizer-3.4.7-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl",url = "https://files.pythonhosted.org/packages/fa/07/330e3a0dda4c404d6da83b327270906e9654a24f6c546dc886a0eb0ffb23/charset_normalizer-3.4.7-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl",hashes = {sha256 = "e044c39e41b92c845bc815e5ae4230804e8e7bc29e399b0437d64222d92809dd"}}, - {name = "charset_normalizer-3.4.7-cp313-cp313-manylinux_2_31_armv7l.whl",url = "https://files.pythonhosted.org/packages/e3/7c/fc890655786e423f02556e0216d4b8c6bcb6bdfa890160dc66bf52dee468/charset_normalizer-3.4.7-cp313-cp313-manylinux_2_31_armv7l.whl",hashes = {sha256 = "f495a1652cf3fbab2eb0639776dad966c2fb874d79d87ca07f9d5f059b8bd215"}}, - {name = "charset_normalizer-3.4.7-cp313-cp313-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl",url = "https://files.pythonhosted.org/packages/d8/97/bfb18b3db2aed3b90cf54dc292ad79fdd5ad65c4eae454099475cbeadd0d/charset_normalizer-3.4.7-cp313-cp313-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl",hashes = {sha256 = "e712b419df8ba5e42b226c510472b37bd57b38e897d3eca5e8cfd410a29fa859"}}, - {name = "charset_normalizer-3.4.7-cp313-cp313-musllinux_1_2_aarch64.whl",url = "https://files.pythonhosted.org/packages/6f/a5/a581c13798546a7fd557c82614a5c65a13df2157e9ad6373166d2a3e645d/charset_normalizer-3.4.7-cp313-cp313-musllinux_1_2_aarch64.whl",hashes = {sha256 = "7804338df6fcc08105c7745f1502ba68d900f45fd770d5bdd5288ddccb8a42d8"}}, - {name = "charset_normalizer-3.4.7-cp313-cp313-musllinux_1_2_armv7l.whl",url = "https://files.pythonhosted.org/packages/8c/bf/b3ab5bcb478e4193d517644b0fb2bf5497fbceeaa7a1bc0f4d5b50953861/charset_normalizer-3.4.7-cp313-cp313-musllinux_1_2_armv7l.whl",hashes = {sha256 = "481551899c856c704d58119b5025793fa6730adda3571971af568f66d2424bb5"}}, - {name = "charset_normalizer-3.4.7-cp313-cp313-musllinux_1_2_ppc64le.whl",url = "https://files.pythonhosted.org/packages/e7/4e/23efd79b65d314fa320ec6017b4b5834d5c12a58ba4610aa353af2e2f577/charset_normalizer-3.4.7-cp313-cp313-musllinux_1_2_ppc64le.whl",hashes = {sha256 = "f59099f9b66f0d7145115e6f80dd8b1d847176df89b234a5a6b3f00437aa0832"}}, - {name = "charset_normalizer-3.4.7-cp313-cp313-musllinux_1_2_riscv64.whl",url = "https://files.pythonhosted.org/packages/b9/9f/1e1941bc3f0e01df116e68dc37a55c4d249df5e6fa77f008841aef68264f/charset_normalizer-3.4.7-cp313-cp313-musllinux_1_2_riscv64.whl",hashes = {sha256 = "f59ad4c0e8f6bba240a9bb85504faa1ab438237199d4cce5f622761507b8f6a6"}}, - {name = "charset_normalizer-3.4.7-cp313-cp313-musllinux_1_2_s390x.whl",url = "https://files.pythonhosted.org/packages/80/0f/088cbb3020d44428964a6c97fe1edfb1b9550396bf6d278330281e8b709c/charset_normalizer-3.4.7-cp313-cp313-musllinux_1_2_s390x.whl",hashes = {sha256 = "3dedcc22d73ec993f42055eff4fcfed9318d1eeb9a6606c55892a26964964e48"}}, - {name = "charset_normalizer-3.4.7-cp313-cp313-musllinux_1_2_x86_64.whl",url = "https://files.pythonhosted.org/packages/6a/9f/130394f9bbe06f4f63e22641d32fc9b202b7e251c9aef4db044324dac493/charset_normalizer-3.4.7-cp313-cp313-musllinux_1_2_x86_64.whl",hashes = {sha256 = "64f02c6841d7d83f832cd97ccf8eb8a906d06eb95d5276069175c696b024b60a"}}, - {name = "charset_normalizer-3.4.7-cp313-cp313-win32.whl",url = "https://files.pythonhosted.org/packages/73/55/c469897448a06e49f8fa03f6caae97074fde823f432a98f979cc42b90e69/charset_normalizer-3.4.7-cp313-cp313-win32.whl",hashes = {sha256 = "4042d5c8f957e15221d423ba781e85d553722fc4113f523f2feb7b188cc34c5e"}}, - {name = "charset_normalizer-3.4.7-cp313-cp313-win_amd64.whl",url = "https://files.pythonhosted.org/packages/5d/78/1b74c5bbb3f99b77a1715c91b3e0b5bdb6fe302d95ace4f5b1bec37b0167/charset_normalizer-3.4.7-cp313-cp313-win_amd64.whl",hashes = {sha256 = "3946fa46a0cf3e4c8cb1cc52f56bb536310d34f25f01ca9b6c16afa767dab110"}}, - {name = "charset_normalizer-3.4.7-cp313-cp313-win_arm64.whl",url = "https://files.pythonhosted.org/packages/68/86/46bd42279d323deb8687c4a5a811fd548cb7d1de10cf6535d099877a9a9f/charset_normalizer-3.4.7-cp313-cp313-win_arm64.whl",hashes = {sha256 = "80d04837f55fc81da168b98de4f4b797ef007fc8a79ab71c6ec9bc4dd662b15b"}}, - {name = "charset_normalizer-3.4.7-cp312-cp312-macosx_10_13_universal2.whl",url = "https://files.pythonhosted.org/packages/0c/eb/4fc8d0a7110eb5fc9cc161723a34a8a6c200ce3b4fbf681bc86feee22308/charset_normalizer-3.4.7-cp312-cp312-macosx_10_13_universal2.whl",hashes = {sha256 = "eca9705049ad3c7345d574e3510665cb2cf844c2f2dcfe675332677f081cbd46"}}, - {name = "charset_normalizer-3.4.7-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl",url = "https://files.pythonhosted.org/packages/f8/e3/0fadc706008ac9d7b9b5be6dc767c05f9d3e5df51744ce4cc9605de7b9f4/charset_normalizer-3.4.7-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl",hashes = {sha256 = "6178f72c5508bfc5fd446a5905e698c6212932f25bcdd4b47a757a50605a90e2"}}, - {name = "charset_normalizer-3.4.7-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl",url = "https://files.pythonhosted.org/packages/42/f0/3dd1045c47f4a4604df85ec18ad093912ae1344ac706993aff91d38773a2/charset_normalizer-3.4.7-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl",hashes = {sha256 = "e1421b502d83040e6d7fb2fb18dff63957f720da3d77b2fbd3187ceb63755d7b"}}, - {name = "charset_normalizer-3.4.7-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl",url = "https://files.pythonhosted.org/packages/dc/67/675a46eb016118a2fbde5a277a5d15f4f69d5f3f5f338e5ee2f8948fcf43/charset_normalizer-3.4.7-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl",hashes = {sha256 = "edac0f1ab77644605be2cbba52e6b7f630731fc42b34cb0f634be1a6eface56a"}}, - {name = "charset_normalizer-3.4.7-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl",url = "https://files.pythonhosted.org/packages/4b/f8/d0118a2f5f23b02cd166fa385c60f9b0d4f9194f574e2b31cef350ad7223/charset_normalizer-3.4.7-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl",hashes = {sha256 = "5649fd1c7bade02f320a462fdefd0b4bd3ce036065836d4f42e0de958038e116"}}, - {name = "charset_normalizer-3.4.7-cp312-cp312-manylinux_2_31_armv7l.whl",url = "https://files.pythonhosted.org/packages/b1/f1/6d2b0b261b6c4ceef0fcb0d17a01cc5bc53586c2d4796fa04b5c540bc13d/charset_normalizer-3.4.7-cp312-cp312-manylinux_2_31_armv7l.whl",hashes = {sha256 = "203104ed3e428044fd943bc4bf45fa73c0730391f9621e37fe39ecf477b128cb"}}, - {name = "charset_normalizer-3.4.7-cp312-cp312-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl",url = "https://files.pythonhosted.org/packages/6f/c0/7b1f943f7e87cc3db9626ba17807d042c38645f0a1d4415c7a14afb5591f/charset_normalizer-3.4.7-cp312-cp312-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl",hashes = {sha256 = "298930cec56029e05497a76988377cbd7457ba864beeea92ad7e844fe74cd1f1"}}, - {name = "charset_normalizer-3.4.7-cp312-cp312-musllinux_1_2_aarch64.whl",url = "https://files.pythonhosted.org/packages/38/dd/5a9ab159fe45c6e72079398f277b7d2b523e7f716acc489726115a910097/charset_normalizer-3.4.7-cp312-cp312-musllinux_1_2_aarch64.whl",hashes = {sha256 = "708838739abf24b2ceb208d0e22403dd018faeef86ddac04319a62ae884c4f15"}}, - {name = "charset_normalizer-3.4.7-cp312-cp312-musllinux_1_2_armv7l.whl",url = "https://files.pythonhosted.org/packages/d5/ff/531a1cad5ca855d1c1a8b69cb71abfd6d85c0291580146fda7c82857caa1/charset_normalizer-3.4.7-cp312-cp312-musllinux_1_2_armv7l.whl",hashes = {sha256 = "0f7eb884681e3938906ed0434f20c63046eacd0111c4ba96f27b76084cd679f5"}}, - {name = "charset_normalizer-3.4.7-cp312-cp312-musllinux_1_2_ppc64le.whl",url = "https://files.pythonhosted.org/packages/c1/4c/a5fb52d528a8ca41f7598cb619409ece30a169fbdf9cdce592e53b46c3a6/charset_normalizer-3.4.7-cp312-cp312-musllinux_1_2_ppc64le.whl",hashes = {sha256 = "4dc1e73c36828f982bfe79fadf5919923f8a6f4df2860804db9a98c48824ce8d"}}, - {name = "charset_normalizer-3.4.7-cp312-cp312-musllinux_1_2_riscv64.whl",url = "https://files.pythonhosted.org/packages/59/7a/071feed8124111a32b316b33ae4de83d36923039ef8cf48120266844285b/charset_normalizer-3.4.7-cp312-cp312-musllinux_1_2_riscv64.whl",hashes = {sha256 = "aed52fea0513bac0ccde438c188c8a471c4e0f457c2dd20cdbf6ea7a450046c7"}}, - {name = "charset_normalizer-3.4.7-cp312-cp312-musllinux_1_2_s390x.whl",url = "https://files.pythonhosted.org/packages/fd/35/f7dba3994312d7ba508e041eaac39a36b120f32d4c8662b8814dab876431/charset_normalizer-3.4.7-cp312-cp312-musllinux_1_2_s390x.whl",hashes = {sha256 = "fea24543955a6a729c45a73fe90e08c743f0b3334bbf3201e6c4bc1b0c7fa464"}}, - {name = "charset_normalizer-3.4.7-cp312-cp312-musllinux_1_2_x86_64.whl",url = "https://files.pythonhosted.org/packages/8a/2d/a572df5c9204ab7688ec1edc895a73ebded3b023bb07364710b05dd1c9be/charset_normalizer-3.4.7-cp312-cp312-musllinux_1_2_x86_64.whl",hashes = {sha256 = "bb6d88045545b26da47aa879dd4a89a71d1dce0f0e549b1abcb31dfe4a8eac49"}}, - {name = "charset_normalizer-3.4.7-cp312-cp312-win32.whl",url = "https://files.pythonhosted.org/packages/86/eb/890922a8b03a568ca2f336c36585a4713c55d4d67bf0f0c78924be6315ca/charset_normalizer-3.4.7-cp312-cp312-win32.whl",hashes = {sha256 = "2257141f39fe65a3fdf38aeccae4b953e5f3b3324f4ff0daf9f15b8518666a2c"}}, - {name = "charset_normalizer-3.4.7-cp312-cp312-win_amd64.whl",url = "https://files.pythonhosted.org/packages/35/d9/0e7dffa06c5ab081f75b1b786f0aefc88365825dfcd0ac544bdb7b2b6853/charset_normalizer-3.4.7-cp312-cp312-win_amd64.whl",hashes = {sha256 = "5ed6ab538499c8644b8a3e18debabcd7ce684f3fa91cf867521a7a0279cab2d6"}}, - {name = "charset_normalizer-3.4.7-cp312-cp312-win_arm64.whl",url = "https://files.pythonhosted.org/packages/9e/5d/481bcc2a7c88ea6b0878c299547843b2521ccbc40980cb406267088bc701/charset_normalizer-3.4.7-cp312-cp312-win_arm64.whl",hashes = {sha256 = "56be790f86bfb2c98fb742ce566dfb4816e5a83384616ab59c49e0604d49c51d"}}, - {name = "charset_normalizer-3.4.7-cp311-cp311-macosx_10_9_universal2.whl",url = "https://files.pythonhosted.org/packages/c2/d7/b5b7020a0565c2e9fa8c09f4b5fa6232feb326b8c20081ccded47ea368fd/charset_normalizer-3.4.7-cp311-cp311-macosx_10_9_universal2.whl",hashes = {sha256 = "7641bb8895e77f921102f72833904dcd9901df5d6d72a2ab8f31d04b7e51e4e7"}}, - {name = "charset_normalizer-3.4.7-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl",url = "https://files.pythonhosted.org/packages/5a/53/58c29116c340e5456724ecd2fff4196d236b98f3da97b404bc5e51ac3493/charset_normalizer-3.4.7-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl",hashes = {sha256 = "202389074300232baeb53ae2569a60901f7efadd4245cf3a3bf0617d60b439d7"}}, - {name = "charset_normalizer-3.4.7-cp311-cp311-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl",url = "https://files.pythonhosted.org/packages/b2/02/e8146dc6591a37a00e5144c63f29fb7c97a734ea8a111190783c0e60ab63/charset_normalizer-3.4.7-cp311-cp311-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl",hashes = {sha256 = "30b8d1d8c52a48c2c5690e152c169b673487a2a58de1ec7393196753063fcd5e"}}, - {name = "charset_normalizer-3.4.7-cp311-cp311-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl",url = "https://files.pythonhosted.org/packages/fb/73/77486c4cd58f1267bf17db420e930c9afa1b3be3fe8c8b8ebbebc9624359/charset_normalizer-3.4.7-cp311-cp311-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl",hashes = {sha256 = "532bc9bf33a68613fd7d65e4b1c71a6a38d7d42604ecf239c77392e9b4e8998c"}}, - {name = "charset_normalizer-3.4.7-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl",url = "https://files.pythonhosted.org/packages/a1/fa/f74eb381a7d94ded44739e9d94de18dc5edc9c17fb8c11f0a6890696c0a9/charset_normalizer-3.4.7-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl",hashes = {sha256 = "2fe249cb4651fd12605b7288b24751d8bfd46d35f12a20b1ba33dea122e690df"}}, - {name = "charset_normalizer-3.4.7-cp311-cp311-manylinux_2_31_armv7l.whl",url = "https://files.pythonhosted.org/packages/dc/92/42bd3cefcf7687253fb86694b45f37b733c97f59af3724f356fa92b8c344/charset_normalizer-3.4.7-cp311-cp311-manylinux_2_31_armv7l.whl",hashes = {sha256 = "65bcd23054beab4d166035cabbc868a09c1a49d1efe458fe8e4361215df40265"}}, - {name = "charset_normalizer-3.4.7-cp311-cp311-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl",url = "https://files.pythonhosted.org/packages/4c/3d/069e7184e2aa3b3cddc700e3dd267413dc259854adc3380421c805c6a17d/charset_normalizer-3.4.7-cp311-cp311-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl",hashes = {sha256 = "08e721811161356f97b4059a9ba7bafb23ea5ee2255402c42881c214e173c6b4"}}, - {name = "charset_normalizer-3.4.7-cp311-cp311-musllinux_1_2_aarch64.whl",url = "https://files.pythonhosted.org/packages/62/51/9d56feb5f2e7074c46f93e0ebdbe61f0848ee246e2f0d89f8e20b89ebb8f/charset_normalizer-3.4.7-cp311-cp311-musllinux_1_2_aarch64.whl",hashes = {sha256 = "e060d01aec0a910bdccb8be71faf34e7799ce36950f8294c8bf612cba65a2c9e"}}, - {name = "charset_normalizer-3.4.7-cp311-cp311-musllinux_1_2_armv7l.whl",url = "https://files.pythonhosted.org/packages/d2/59/893d8f99cc4c837dda1fe2f1139079703deb9f321aabcb032355de13b6c7/charset_normalizer-3.4.7-cp311-cp311-musllinux_1_2_armv7l.whl",hashes = {sha256 = "38c0109396c4cfc574d502df99742a45c72c08eff0a36158b6f04000043dbf38"}}, - {name = "charset_normalizer-3.4.7-cp311-cp311-musllinux_1_2_ppc64le.whl",url = "https://files.pythonhosted.org/packages/7d/1d/ee6f3be3464247578d1ed5c46de545ccc3d3ff933695395c402c21fa6b77/charset_normalizer-3.4.7-cp311-cp311-musllinux_1_2_ppc64le.whl",hashes = {sha256 = "1c2a768fdd44ee4a9339a9b0b130049139b8ce3c01d2ce09f67f5a68048d477c"}}, - {name = "charset_normalizer-3.4.7-cp311-cp311-musllinux_1_2_riscv64.whl",url = "https://files.pythonhosted.org/packages/54/bb/8fb0a946296ea96a488928bdce8ef99023998c48e4713af533e9bb98ef07/charset_normalizer-3.4.7-cp311-cp311-musllinux_1_2_riscv64.whl",hashes = {sha256 = "1a87ca9d5df6fe460483d9a5bbf2b18f620cbed41b432e2bddb686228282d10b"}}, - {name = "charset_normalizer-3.4.7-cp311-cp311-musllinux_1_2_s390x.whl",url = "https://files.pythonhosted.org/packages/9a/bc/015b2387f913749f82afd4fcba07846d05b6d784dd16123cb66860e0237d/charset_normalizer-3.4.7-cp311-cp311-musllinux_1_2_s390x.whl",hashes = {sha256 = "d635aab80466bc95771bb78d5370e74d36d1fe31467b6b29b8b57b2a3cd7d22c"}}, - {name = "charset_normalizer-3.4.7-cp311-cp311-musllinux_1_2_x86_64.whl",url = "https://files.pythonhosted.org/packages/17/ab/63133691f56baae417493cba6b7c641571a2130eb7bceba6773367ab9ec5/charset_normalizer-3.4.7-cp311-cp311-musllinux_1_2_x86_64.whl",hashes = {sha256 = "ae196f021b5e7c78e918242d217db021ed2a6ace2bc6ae94c0fc596221c7f58d"}}, - {name = "charset_normalizer-3.4.7-cp311-cp311-win32.whl",url = "https://files.pythonhosted.org/packages/06/6d/3be70e827977f20db77c12a97e6a9f973631a45b8d186c084527e53e77a4/charset_normalizer-3.4.7-cp311-cp311-win32.whl",hashes = {sha256 = "adb2597b428735679446b46c8badf467b4ca5f5056aae4d51a19f9570301b1ad"}}, - {name = "charset_normalizer-3.4.7-cp311-cp311-win_amd64.whl",url = "https://files.pythonhosted.org/packages/20/d9/5f67790f06b735d7c7637171bbfd89882ad67201891b7275e51116ed8207/charset_normalizer-3.4.7-cp311-cp311-win_amd64.whl",hashes = {sha256 = "8e385e4267ab76874ae30db04c627faaaf0b509e1ccc11a95b3fc3e83f855c00"}}, - {name = "charset_normalizer-3.4.7-cp311-cp311-win_arm64.whl",url = "https://files.pythonhosted.org/packages/ca/83/6413f36c5a34afead88ce6f66684d943d91f233d76dd083798f9602b75ae/charset_normalizer-3.4.7-cp311-cp311-win_arm64.whl",hashes = {sha256 = "d4a48e5b3c2a489fae013b7589308a40146ee081f6f509e047e0e096084ceca1"}}, - {name = "charset_normalizer-3.4.7-py3-none-any.whl",url = "https://files.pythonhosted.org/packages/db/8f/61959034484a4a7c527811f4721e75d02d653a35afb0b6054474d8185d4c/charset_normalizer-3.4.7-py3-none-any.whl",hashes = {sha256 = "3dce51d0f5e7951f8bb4900c257dad282f49190fdbebecd4ba99bcc41fef404d"}}, -] -marker = "\"default\" in dependency_groups or \"docs\" in extras" - -[packages.tool.pdm] -dependencies = [] - -[[packages]] -name = "click" -version = "8.3.2" -requires-python = ">=3.10" -sdist = {name = "click-8.3.2.tar.gz", url = "https://files.pythonhosted.org/packages/57/75/31212c6bf2503fdf920d87fee5d7a86a2e3bcf444984126f13d8e4016804/click-8.3.2.tar.gz", hashes = {sha256 = "14162b8b3b3550a7d479eafa77dfd3c38d9dc8951f6f69c78913a8f9a7540fd5"}} -wheels = [ - {name = "click-8.3.2-py3-none-any.whl",url = "https://files.pythonhosted.org/packages/e4/20/71885d8b97d4f3dde17b1fdb92dbd4908b00541c5a3379787137285f602e/click-8.3.2-py3-none-any.whl",hashes = {sha256 = "1924d2c27c5653561cd2cae4548d1406039cb79b858b747cfea24924bbc1616d"}}, -] -marker = "\"docs\" in extras" - -[packages.tool.pdm] -dependencies = [ - "colorama; platform_system == \"Windows\"", -] - -[[packages]] -name = "colorama" -version = "0.4.6" -requires-python = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*,>=2.7" -sdist = {name = "colorama-0.4.6.tar.gz", url = "https://files.pythonhosted.org/packages/d8/53/6f443c9a4a8358a93a6792e2acffb9d9d5cb0a5cfd8802644b7b1c9a02e4/colorama-0.4.6.tar.gz", hashes = {sha256 = "08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44"}} -wheels = [ - {name = "colorama-0.4.6-py2.py3-none-any.whl",url = "https://files.pythonhosted.org/packages/d1/d6/3965ed04c63042e047cb6a3e6ed1a63a35087b6a609aa3a15ed8ac56c221/colorama-0.4.6-py2.py3-none-any.whl",hashes = {sha256 = "4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6"}}, -] -marker = "\"docs\" in extras or \"test\" in extras" - -[packages.tool.pdm] -dependencies = [] - -[[packages]] -name = "comm" -version = "0.2.3" -requires-python = ">=3.8" -sdist = {name = "comm-0.2.3.tar.gz", url = "https://files.pythonhosted.org/packages/4c/13/7d740c5849255756bc17888787313b61fd38a0a8304fc4f073dfc46122aa/comm-0.2.3.tar.gz", hashes = {sha256 = "2dc8048c10962d55d7ad693be1e7045d891b7ce8d999c97963a5e3e99c055971"}} -wheels = [ - {name = "comm-0.2.3-py3-none-any.whl",url = "https://files.pythonhosted.org/packages/60/97/891a0971e1e4a8c5d2b20bbe0e524dc04548d2307fee33cdeba148fd4fc7/comm-0.2.3-py3-none-any.whl",hashes = {sha256 = "c615d91d75f7f04f095b30d1c1711babd43bdc6419c1be9886a85f2f4e489417"}}, -] -marker = "\"docs\" in extras" - -[packages.tool.pdm] -dependencies = [] - -[[packages]] -name = "contourpy" -version = "1.3.3" -requires-python = ">=3.11" -sdist = {name = "contourpy-1.3.3.tar.gz", url = "https://files.pythonhosted.org/packages/58/01/1253e6698a07380cd31a736d248a3f2a50a7c88779a1813da27503cadc2a/contourpy-1.3.3.tar.gz", hashes = {sha256 = "083e12155b210502d0bca491432bb04d56dc3432f95a979b429f2848c3dbe880"}} -wheels = [ - {name = "contourpy-1.3.3-cp314-cp314-macosx_10_13_x86_64.whl",url = "https://files.pythonhosted.org/packages/72/8b/4546f3ab60f78c514ffb7d01a0bd743f90de36f0019d1be84d0a708a580a/contourpy-1.3.3-cp314-cp314-macosx_10_13_x86_64.whl",hashes = {sha256 = "fde6c716d51c04b1c25d0b90364d0be954624a0ee9d60e23e850e8d48353d07a"}}, - {name = "contourpy-1.3.3-cp314-cp314-macosx_11_0_arm64.whl",url = "https://files.pythonhosted.org/packages/fd/e1/3542a9cb596cadd76fcef413f19c79216e002623158befe6daa03dbfa88c/contourpy-1.3.3-cp314-cp314-macosx_11_0_arm64.whl",hashes = {sha256 = "cbedb772ed74ff5be440fa8eee9bd49f64f6e3fc09436d9c7d8f1c287b121d77"}}, - {name = "contourpy-1.3.3-cp314-cp314-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl",url = "https://files.pythonhosted.org/packages/b1/71/f93e1e9471d189f79d0ce2497007731c1e6bf9ef6d1d61b911430c3db4e5/contourpy-1.3.3-cp314-cp314-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl",hashes = {sha256 = "22e9b1bd7a9b1d652cd77388465dc358dafcd2e217d35552424aa4f996f524f5"}}, - {name = "contourpy-1.3.3-cp314-cp314-manylinux_2_26_ppc64le.manylinux_2_28_ppc64le.whl",url = "https://files.pythonhosted.org/packages/91/f9/e35f4c1c93f9275d4e38681a80506b5510e9327350c51f8d4a5a724d178c/contourpy-1.3.3-cp314-cp314-manylinux_2_26_ppc64le.manylinux_2_28_ppc64le.whl",hashes = {sha256 = "a22738912262aa3e254e4f3cb079a95a67132fc5a063890e224393596902f5a4"}}, - {name = "contourpy-1.3.3-cp314-cp314-manylinux_2_26_s390x.manylinux_2_28_s390x.whl",url = "https://files.pythonhosted.org/packages/b5/71/47b512f936f66a0a900d81c396a7e60d73419868fba959c61efed7a8ab46/contourpy-1.3.3-cp314-cp314-manylinux_2_26_s390x.manylinux_2_28_s390x.whl",hashes = {sha256 = "afe5a512f31ee6bd7d0dda52ec9864c984ca3d66664444f2d72e0dc4eb832e36"}}, - {name = "contourpy-1.3.3-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl",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",hashes = {sha256 = "f64836de09927cba6f79dcd00fdd7d5329f3fccc633468507079c829ca4db4e3"}}, - {name = "contourpy-1.3.3-cp314-cp314-musllinux_1_2_aarch64.whl",url = "https://files.pythonhosted.org/packages/3e/a6/0b185d4cc480ee494945cde102cb0149ae830b5fa17bf855b95f2e70ad13/contourpy-1.3.3-cp314-cp314-musllinux_1_2_aarch64.whl",hashes = {sha256 = "1fd43c3be4c8e5fd6e4f2baeae35ae18176cf2e5cced681cca908addf1cdd53b"}}, - {name = "contourpy-1.3.3-cp314-cp314-musllinux_1_2_x86_64.whl",url = "https://files.pythonhosted.org/packages/43/d7/afdc95580ca56f30fbcd3060250f66cedbde69b4547028863abd8aa3b47e/contourpy-1.3.3-cp314-cp314-musllinux_1_2_x86_64.whl",hashes = {sha256 = "6afc576f7b33cf00996e5c1102dc2a8f7cc89e39c0b55df93a0b78c1bd992b36"}}, - {name = "contourpy-1.3.3-cp314-cp314-win32.whl",url = "https://files.pythonhosted.org/packages/e2/e2/366af18a6d386f41132a48f033cbd2102e9b0cf6345d35ff0826cd984566/contourpy-1.3.3-cp314-cp314-win32.whl",hashes = {sha256 = "66c8a43a4f7b8df8b71ee1840e4211a3c8d93b214b213f590e18a1beca458f7d"}}, - {name = "contourpy-1.3.3-cp314-cp314-win_amd64.whl",url = "https://files.pythonhosted.org/packages/7d/c2/57f54b03d0f22d4044b8afb9ca0e184f8b1afd57b4f735c2fa70883dc601/contourpy-1.3.3-cp314-cp314-win_amd64.whl",hashes = {sha256 = "cf9022ef053f2694e31d630feaacb21ea24224be1c3ad0520b13d844274614fd"}}, - {name = "contourpy-1.3.3-cp314-cp314-win_arm64.whl",url = "https://files.pythonhosted.org/packages/18/79/a9416650df9b525737ab521aa181ccc42d56016d2123ddcb7b58e926a42c/contourpy-1.3.3-cp314-cp314-win_arm64.whl",hashes = {sha256 = "95b181891b4c71de4bb404c6621e7e2390745f887f2a026b2d99e92c17892339"}}, - {name = "contourpy-1.3.3-cp314-cp314t-macosx_10_13_x86_64.whl",url = "https://files.pythonhosted.org/packages/1f/42/38c159a7d0f2b7b9c04c64ab317042bb6952b713ba875c1681529a2932fe/contourpy-1.3.3-cp314-cp314t-macosx_10_13_x86_64.whl",hashes = {sha256 = "33c82d0138c0a062380332c861387650c82e4cf1747aaa6938b9b6516762e772"}}, - {name = "contourpy-1.3.3-cp314-cp314t-macosx_11_0_arm64.whl",url = "https://files.pythonhosted.org/packages/c3/6c/26a8205f24bca10974e77460de68d3d7c63e282e23782f1239f226fcae6f/contourpy-1.3.3-cp314-cp314t-macosx_11_0_arm64.whl",hashes = {sha256 = "ea37e7b45949df430fe649e5de8351c423430046a2af20b1c1961cae3afcda77"}}, - {name = "contourpy-1.3.3-cp314-cp314t-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl",url = "https://files.pythonhosted.org/packages/66/06/8a475c8ab718ebfd7925661747dbb3c3ee9c82ac834ccb3570be49d129f4/contourpy-1.3.3-cp314-cp314t-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl",hashes = {sha256 = "d304906ecc71672e9c89e87c4675dc5c2645e1f4269a5063b99b0bb29f232d13"}}, - {name = "contourpy-1.3.3-cp314-cp314t-manylinux_2_26_ppc64le.manylinux_2_28_ppc64le.whl",url = "https://files.pythonhosted.org/packages/b4/a3/c5ca9f010a44c223f098fccd8b158bb1cb287378a31ac141f04730dc49be/contourpy-1.3.3-cp314-cp314t-manylinux_2_26_ppc64le.manylinux_2_28_ppc64le.whl",hashes = {sha256 = "ca658cd1a680a5c9ea96dc61cdbae1e85c8f25849843aa799dfd3cb370ad4fbe"}}, - {name = "contourpy-1.3.3-cp314-cp314t-manylinux_2_26_s390x.manylinux_2_28_s390x.whl",url = "https://files.pythonhosted.org/packages/80/5b/68bd33ae63fac658a4145088c1e894405e07584a316738710b636c6d0333/contourpy-1.3.3-cp314-cp314t-manylinux_2_26_s390x.manylinux_2_28_s390x.whl",hashes = {sha256 = "ab2fd90904c503739a75b7c8c5c01160130ba67944a7b77bbf36ef8054576e7f"}}, - {name = "contourpy-1.3.3-cp314-cp314t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl",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",hashes = {sha256 = "b7301b89040075c30e5768810bc96a8e8d78085b47d8be6e4c3f5a0b4ed478a0"}}, - {name = "contourpy-1.3.3-cp314-cp314t-musllinux_1_2_aarch64.whl",url = "https://files.pythonhosted.org/packages/24/ee/3e81e1dd174f5c7fefe50e85d0892de05ca4e26ef1c9a59c2a57e43b865a/contourpy-1.3.3-cp314-cp314t-musllinux_1_2_aarch64.whl",hashes = {sha256 = "2a2a8b627d5cc6b7c41a4beff6c5ad5eb848c88255fda4a8745f7e901b32d8e4"}}, - {name = "contourpy-1.3.3-cp314-cp314t-musllinux_1_2_x86_64.whl",url = "https://files.pythonhosted.org/packages/3c/b2/6d913d4d04e14379de429057cd169e5e00f6c2af3bb13e1710bcbdb5da12/contourpy-1.3.3-cp314-cp314t-musllinux_1_2_x86_64.whl",hashes = {sha256 = "fd6ec6be509c787f1caf6b247f0b1ca598bef13f4ddeaa126b7658215529ba0f"}}, - {name = "contourpy-1.3.3-cp314-cp314t-win32.whl",url = "https://files.pythonhosted.org/packages/93/8a/68a4ec5c55a2971213d29a9374913f7e9f18581945a7a31d1a39b5d2dfe5/contourpy-1.3.3-cp314-cp314t-win32.whl",hashes = {sha256 = "e74a9a0f5e3fff48fb5a7f2fd2b9b70a3fe014a67522f79b7cca4c0c7e43c9ae"}}, - {name = "contourpy-1.3.3-cp314-cp314t-win_amd64.whl",url = "https://files.pythonhosted.org/packages/fa/96/fd9f641ffedc4fa3ace923af73b9d07e869496c9cc7a459103e6e978992f/contourpy-1.3.3-cp314-cp314t-win_amd64.whl",hashes = {sha256 = "13b68d6a62db8eafaebb8039218921399baf6e47bf85006fd8529f2a08ef33fc"}}, - {name = "contourpy-1.3.3-cp314-cp314t-win_arm64.whl",url = "https://files.pythonhosted.org/packages/ae/8c/469afb6465b853afff216f9528ffda78a915ff880ed58813ba4faf4ba0b6/contourpy-1.3.3-cp314-cp314t-win_arm64.whl",hashes = {sha256 = "b7448cb5a725bb1e35ce88771b86fba35ef418952474492cf7c764059933ff8b"}}, - {name = "contourpy-1.3.3-cp313-cp313-macosx_10_13_x86_64.whl",url = "https://files.pythonhosted.org/packages/68/35/0167aad910bbdb9599272bd96d01a9ec6852f36b9455cf2ca67bd4cc2d23/contourpy-1.3.3-cp313-cp313-macosx_10_13_x86_64.whl",hashes = {sha256 = "177fb367556747a686509d6fef71d221a4b198a3905fe824430e5ea0fda54eb5"}}, - {name = "contourpy-1.3.3-cp313-cp313-macosx_11_0_arm64.whl",url = "https://files.pythonhosted.org/packages/96/e4/7adcd9c8362745b2210728f209bfbcf7d91ba868a2c5f40d8b58f54c509b/contourpy-1.3.3-cp313-cp313-macosx_11_0_arm64.whl",hashes = {sha256 = "d002b6f00d73d69333dac9d0b8d5e84d9724ff9ef044fd63c5986e62b7c9e1b1"}}, - {name = "contourpy-1.3.3-cp313-cp313-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl",url = "https://files.pythonhosted.org/packages/73/23/90e31ceeed1de63058a02cb04b12f2de4b40e3bef5e082a7c18d9c8ae281/contourpy-1.3.3-cp313-cp313-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl",hashes = {sha256 = "348ac1f5d4f1d66d3322420f01d42e43122f43616e0f194fc1c9f5d830c5b286"}}, - {name = "contourpy-1.3.3-cp313-cp313-manylinux_2_26_ppc64le.manylinux_2_28_ppc64le.whl",url = "https://files.pythonhosted.org/packages/ed/93/b43d8acbe67392e659e1d984700e79eb67e2acb2bd7f62012b583a7f1b55/contourpy-1.3.3-cp313-cp313-manylinux_2_26_ppc64le.manylinux_2_28_ppc64le.whl",hashes = {sha256 = "655456777ff65c2c548b7c454af9c6f33f16c8884f11083244b5819cc214f1b5"}}, - {name = "contourpy-1.3.3-cp313-cp313-manylinux_2_26_s390x.manylinux_2_28_s390x.whl",url = "https://files.pythonhosted.org/packages/46/3b/bec82a3ea06f66711520f75a40c8fc0b113b2a75edb36aa633eb11c4f50f/contourpy-1.3.3-cp313-cp313-manylinux_2_26_s390x.manylinux_2_28_s390x.whl",hashes = {sha256 = "644a6853d15b2512d67881586bd03f462c7ab755db95f16f14d7e238f2852c67"}}, - {name = "contourpy-1.3.3-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl",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",hashes = {sha256 = "4debd64f124ca62069f313a9cb86656ff087786016d76927ae2cf37846b006c9"}}, - {name = "contourpy-1.3.3-cp313-cp313-musllinux_1_2_aarch64.whl",url = "https://files.pythonhosted.org/packages/33/71/e2a7945b7de4e58af42d708a219f3b2f4cff7386e6b6ab0a0fa0033c49a9/contourpy-1.3.3-cp313-cp313-musllinux_1_2_aarch64.whl",hashes = {sha256 = "a15459b0f4615b00bbd1e91f1b9e19b7e63aea7483d03d804186f278c0af2659"}}, - {name = "contourpy-1.3.3-cp313-cp313-musllinux_1_2_x86_64.whl",url = "https://files.pythonhosted.org/packages/12/fc/4e87ac754220ccc0e807284f88e943d6d43b43843614f0a8afa469801db0/contourpy-1.3.3-cp313-cp313-musllinux_1_2_x86_64.whl",hashes = {sha256 = "ca0fdcd73925568ca027e0b17ab07aad764be4706d0a925b89227e447d9737b7"}}, - {name = "contourpy-1.3.3-cp313-cp313-win32.whl",url = "https://files.pythonhosted.org/packages/a6/2e/adc197a37443f934594112222ac1aa7dc9a98faf9c3842884df9a9d8751d/contourpy-1.3.3-cp313-cp313-win32.whl",hashes = {sha256 = "b20c7c9a3bf701366556e1b1984ed2d0cedf999903c51311417cf5f591d8c78d"}}, - {name = "contourpy-1.3.3-cp313-cp313-win_amd64.whl",url = "https://files.pythonhosted.org/packages/18/0b/0098c214843213759692cc638fce7de5c289200a830e5035d1791d7a2338/contourpy-1.3.3-cp313-cp313-win_amd64.whl",hashes = {sha256 = "1cadd8b8969f060ba45ed7c1b714fe69185812ab43bd6b86a9123fe8f99c3263"}}, - {name = "contourpy-1.3.3-cp313-cp313-win_arm64.whl",url = "https://files.pythonhosted.org/packages/8a/9a/2f6024a0c5995243cd63afdeb3651c984f0d2bc727fd98066d40e141ad73/contourpy-1.3.3-cp313-cp313-win_arm64.whl",hashes = {sha256 = "fd914713266421b7536de2bfa8181aa8c699432b6763a0ea64195ebe28bff6a9"}}, - {name = "contourpy-1.3.3-cp313-cp313t-macosx_10_13_x86_64.whl",url = "https://files.pythonhosted.org/packages/c0/b3/f8a1a86bd3298513f500e5b1f5fd92b69896449f6cab6a146a5d52715479/contourpy-1.3.3-cp313-cp313t-macosx_10_13_x86_64.whl",hashes = {sha256 = "88df9880d507169449d434c293467418b9f6cbe82edd19284aa0409e7fdb933d"}}, - {name = "contourpy-1.3.3-cp313-cp313t-macosx_11_0_arm64.whl",url = "https://files.pythonhosted.org/packages/3f/11/4780db94ae62fc0c2053909b65dc3246bd7cecfc4f8a20d957ad43aa4ad8/contourpy-1.3.3-cp313-cp313t-macosx_11_0_arm64.whl",hashes = {sha256 = "d06bb1f751ba5d417047db62bca3c8fde202b8c11fb50742ab3ab962c81e8216"}}, - {name = "contourpy-1.3.3-cp313-cp313t-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl",url = "https://files.pythonhosted.org/packages/ae/15/e59f5f3ffdd6f3d4daa3e47114c53daabcb18574a26c21f03dc9e4e42ff0/contourpy-1.3.3-cp313-cp313t-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl",hashes = {sha256 = "e4e6b05a45525357e382909a4c1600444e2a45b4795163d3b22669285591c1ae"}}, - {name = "contourpy-1.3.3-cp313-cp313t-manylinux_2_26_ppc64le.manylinux_2_28_ppc64le.whl",url = "https://files.pythonhosted.org/packages/0f/81/03b45cfad088e4770b1dcf72ea78d3802d04200009fb364d18a493857210/contourpy-1.3.3-cp313-cp313t-manylinux_2_26_ppc64le.manylinux_2_28_ppc64le.whl",hashes = {sha256 = "ab3074b48c4e2cf1a960e6bbeb7f04566bf36b1861d5c9d4d8ac04b82e38ba20"}}, - {name = "contourpy-1.3.3-cp313-cp313t-manylinux_2_26_s390x.manylinux_2_28_s390x.whl",url = "https://files.pythonhosted.org/packages/0c/ba/49923366492ffbdd4486e970d421b289a670ae8cf539c1ea9a09822b371a/contourpy-1.3.3-cp313-cp313t-manylinux_2_26_s390x.manylinux_2_28_s390x.whl",hashes = {sha256 = "6c3d53c796f8647d6deb1abe867daeb66dcc8a97e8455efa729516b997b8ed99"}}, - {name = "contourpy-1.3.3-cp313-cp313t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl",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",hashes = {sha256 = "50ed930df7289ff2a8d7afeb9603f8289e5704755c7e5c3bbd929c90c817164b"}}, - {name = "contourpy-1.3.3-cp313-cp313t-musllinux_1_2_aarch64.whl",url = "https://files.pythonhosted.org/packages/32/1d/a209ec1a3a3452d490f6b14dd92e72280c99ae3d1e73da74f8277d4ee08f/contourpy-1.3.3-cp313-cp313t-musllinux_1_2_aarch64.whl",hashes = {sha256 = "4feffb6537d64b84877da813a5c30f1422ea5739566abf0bd18065ac040e120a"}}, - {name = "contourpy-1.3.3-cp313-cp313t-musllinux_1_2_x86_64.whl",url = "https://files.pythonhosted.org/packages/bc/9e/46f0e8ebdd884ca0e8877e46a3f4e633f6c9c8c4f3f6e72be3fe075994aa/contourpy-1.3.3-cp313-cp313t-musllinux_1_2_x86_64.whl",hashes = {sha256 = "2b7e9480ffe2b0cd2e787e4df64270e3a0440d9db8dc823312e2c940c167df7e"}}, - {name = "contourpy-1.3.3-cp313-cp313t-win32.whl",url = "https://files.pythonhosted.org/packages/b9/70/f308384a3ae9cd2209e0849f33c913f658d3326900d0ff5d378d6a1422d2/contourpy-1.3.3-cp313-cp313t-win32.whl",hashes = {sha256 = "283edd842a01e3dcd435b1c5116798d661378d83d36d337b8dde1d16a5fc9ba3"}}, - {name = "contourpy-1.3.3-cp313-cp313t-win_amd64.whl",url = "https://files.pythonhosted.org/packages/b2/dd/880f890a6663b84d9e34a6f88cded89d78f0091e0045a284427cb6b18521/contourpy-1.3.3-cp313-cp313t-win_amd64.whl",hashes = {sha256 = "87acf5963fc2b34825e5b6b048f40e3635dd547f590b04d2ab317c2619ef7ae8"}}, - {name = "contourpy-1.3.3-cp313-cp313t-win_arm64.whl",url = "https://files.pythonhosted.org/packages/80/99/2adc7d8ffead633234817ef8e9a87115c8a11927a94478f6bb3d3f4d4f7d/contourpy-1.3.3-cp313-cp313t-win_arm64.whl",hashes = {sha256 = "3c30273eb2a55024ff31ba7d052dde990d7d8e5450f4bbb6e913558b3d6c2301"}}, - {name = "contourpy-1.3.3-cp312-cp312-macosx_10_13_x86_64.whl",url = "https://files.pythonhosted.org/packages/be/45/adfee365d9ea3d853550b2e735f9d66366701c65db7855cd07621732ccfc/contourpy-1.3.3-cp312-cp312-macosx_10_13_x86_64.whl",hashes = {sha256 = "b08a32ea2f8e42cf1d4be3169a98dd4be32bafe4f22b6c4cb4ba810fa9e5d2cb"}}, - {name = "contourpy-1.3.3-cp312-cp312-macosx_11_0_arm64.whl",url = "https://files.pythonhosted.org/packages/53/3e/405b59cfa13021a56bba395a6b3aca8cec012b45bf177b0eaf7a202cde2c/contourpy-1.3.3-cp312-cp312-macosx_11_0_arm64.whl",hashes = {sha256 = "556dba8fb6f5d8742f2923fe9457dbdd51e1049c4a43fd3986a0b14a1d815fc6"}}, - {name = "contourpy-1.3.3-cp312-cp312-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl",url = "https://files.pythonhosted.org/packages/d4/1c/a12359b9b2ca3a845e8f7f9ac08bdf776114eb931392fcad91743e2ea17b/contourpy-1.3.3-cp312-cp312-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl",hashes = {sha256 = "92d9abc807cf7d0e047b95ca5d957cf4792fcd04e920ca70d48add15c1a90ea7"}}, - {name = "contourpy-1.3.3-cp312-cp312-manylinux_2_26_ppc64le.manylinux_2_28_ppc64le.whl",url = "https://files.pythonhosted.org/packages/63/12/897aeebfb475b7748ea67b61e045accdfcf0d971f8a588b67108ed7f5512/contourpy-1.3.3-cp312-cp312-manylinux_2_26_ppc64le.manylinux_2_28_ppc64le.whl",hashes = {sha256 = "b2e8faa0ed68cb29af51edd8e24798bb661eac3bd9f65420c1887b6ca89987c8"}}, - {name = "contourpy-1.3.3-cp312-cp312-manylinux_2_26_s390x.manylinux_2_28_s390x.whl",url = "https://files.pythonhosted.org/packages/43/8a/a8c584b82deb248930ce069e71576fc09bd7174bbd35183b7943fb1064fd/contourpy-1.3.3-cp312-cp312-manylinux_2_26_s390x.manylinux_2_28_s390x.whl",hashes = {sha256 = "626d60935cf668e70a5ce6ff184fd713e9683fb458898e4249b63be9e28286ea"}}, - {name = "contourpy-1.3.3-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl",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",hashes = {sha256 = "4d00e655fcef08aba35ec9610536bfe90267d7ab5ba944f7032549c55a146da1"}}, - {name = "contourpy-1.3.3-cp312-cp312-musllinux_1_2_aarch64.whl",url = "https://files.pythonhosted.org/packages/05/0a/a3fe3be3ee2dceb3e615ebb4df97ae6f3828aa915d3e10549ce016302bd1/contourpy-1.3.3-cp312-cp312-musllinux_1_2_aarch64.whl",hashes = {sha256 = "451e71b5a7d597379ef572de31eeb909a87246974d960049a9848c3bc6c41bf7"}}, - {name = "contourpy-1.3.3-cp312-cp312-musllinux_1_2_x86_64.whl",url = "https://files.pythonhosted.org/packages/33/1d/acad9bd4e97f13f3e2b18a3977fe1b4a37ecf3d38d815333980c6c72e963/contourpy-1.3.3-cp312-cp312-musllinux_1_2_x86_64.whl",hashes = {sha256 = "459c1f020cd59fcfe6650180678a9993932d80d44ccde1fa1868977438f0b411"}}, - {name = "contourpy-1.3.3-cp312-cp312-win32.whl",url = "https://files.pythonhosted.org/packages/cf/8f/5847f44a7fddf859704217a99a23a4f6417b10e5ab1256a179264561540e/contourpy-1.3.3-cp312-cp312-win32.whl",hashes = {sha256 = "023b44101dfe49d7d53932be418477dba359649246075c996866106da069af69"}}, - {name = "contourpy-1.3.3-cp312-cp312-win_amd64.whl",url = "https://files.pythonhosted.org/packages/19/e8/6026ed58a64563186a9ee3f29f41261fd1828f527dd93d33b60feca63352/contourpy-1.3.3-cp312-cp312-win_amd64.whl",hashes = {sha256 = "8153b8bfc11e1e4d75bcb0bff1db232f9e10b274e0929de9d608027e0d34ff8b"}}, - {name = "contourpy-1.3.3-cp312-cp312-win_arm64.whl",url = "https://files.pythonhosted.org/packages/d1/e2/f05240d2c39a1ed228d8328a78b6f44cd695f7ef47beb3e684cf93604f86/contourpy-1.3.3-cp312-cp312-win_arm64.whl",hashes = {sha256 = "07ce5ed73ecdc4a03ffe3e1b3e3c1166db35ae7584be76f65dbbe28a7791b0cc"}}, - {name = "contourpy-1.3.3-cp311-cp311-macosx_10_9_x86_64.whl",url = "https://files.pythonhosted.org/packages/91/2e/c4390a31919d8a78b90e8ecf87cd4b4c4f05a5b48d05ec17db8e5404c6f4/contourpy-1.3.3-cp311-cp311-macosx_10_9_x86_64.whl",hashes = {sha256 = "709a48ef9a690e1343202916450bc48b9e51c049b089c7f79a267b46cffcdaa1"}}, - {name = "contourpy-1.3.3-cp311-cp311-macosx_11_0_arm64.whl",url = "https://files.pythonhosted.org/packages/0d/44/c4b0b6095fef4dc9c420e041799591e3b63e9619e3044f7f4f6c21c0ab24/contourpy-1.3.3-cp311-cp311-macosx_11_0_arm64.whl",hashes = {sha256 = "23416f38bfd74d5d28ab8429cc4d63fa67d5068bd711a85edb1c3fb0c3e2f381"}}, - {name = "contourpy-1.3.3-cp311-cp311-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl",url = "https://files.pythonhosted.org/packages/30/2e/dd4ced42fefac8470661d7cb7e264808425e6c5d56d175291e93890cce09/contourpy-1.3.3-cp311-cp311-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl",hashes = {sha256 = "929ddf8c4c7f348e4c0a5a3a714b5c8542ffaa8c22954862a46ca1813b667ee7"}}, - {name = "contourpy-1.3.3-cp311-cp311-manylinux_2_26_ppc64le.manylinux_2_28_ppc64le.whl",url = "https://files.pythonhosted.org/packages/f2/74/cc6ec2548e3d276c71389ea4802a774b7aa3558223b7bade3f25787fafc2/contourpy-1.3.3-cp311-cp311-manylinux_2_26_ppc64le.manylinux_2_28_ppc64le.whl",hashes = {sha256 = "9e999574eddae35f1312c2b4b717b7885d4edd6cb46700e04f7f02db454e67c1"}}, - {name = "contourpy-1.3.3-cp311-cp311-manylinux_2_26_s390x.manylinux_2_28_s390x.whl",url = "https://files.pythonhosted.org/packages/03/b3/64ef723029f917410f75c09da54254c5f9ea90ef89b143ccadb09df14c15/contourpy-1.3.3-cp311-cp311-manylinux_2_26_s390x.manylinux_2_28_s390x.whl",hashes = {sha256 = "0bf67e0e3f482cb69779dd3061b534eb35ac9b17f163d851e2a547d56dba0a3a"}}, - {name = "contourpy-1.3.3-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl",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",hashes = {sha256 = "51e79c1f7470158e838808d4a996fa9bac72c498e93d8ebe5119bc1e6becb0db"}}, - {name = "contourpy-1.3.3-cp311-cp311-musllinux_1_2_aarch64.whl",url = "https://files.pythonhosted.org/packages/98/56/f914f0dd678480708a04cfd2206e7c382533249bc5001eb9f58aa693e200/contourpy-1.3.3-cp311-cp311-musllinux_1_2_aarch64.whl",hashes = {sha256 = "598c3aaece21c503615fd59c92a3598b428b2f01bfb4b8ca9c4edeecc2438620"}}, - {name = "contourpy-1.3.3-cp311-cp311-musllinux_1_2_x86_64.whl",url = "https://files.pythonhosted.org/packages/fb/d7/4a972334a0c971acd5172389671113ae82aa7527073980c38d5868ff1161/contourpy-1.3.3-cp311-cp311-musllinux_1_2_x86_64.whl",hashes = {sha256 = "322ab1c99b008dad206d406bb61d014cf0174df491ae9d9d0fac6a6fda4f977f"}}, - {name = "contourpy-1.3.3-cp311-cp311-win32.whl",url = "https://files.pythonhosted.org/packages/75/3e/f2cc6cd56dc8cff46b1a56232eabc6feea52720083ea71ab15523daab796/contourpy-1.3.3-cp311-cp311-win32.whl",hashes = {sha256 = "fd907ae12cd483cd83e414b12941c632a969171bf90fc937d0c9f268a31cafff"}}, - {name = "contourpy-1.3.3-cp311-cp311-win_amd64.whl",url = "https://files.pythonhosted.org/packages/98/4b/9bd370b004b5c9d8045c6c33cf65bae018b27aca550a3f657cdc99acdbd8/contourpy-1.3.3-cp311-cp311-win_amd64.whl",hashes = {sha256 = "3519428f6be58431c56581f1694ba8e50626f2dd550af225f82fb5f5814d2a42"}}, - {name = "contourpy-1.3.3-cp311-cp311-win_arm64.whl",url = "https://files.pythonhosted.org/packages/d9/b6/71771e02c2e004450c12b1120a5f488cad2e4d5b590b1af8bad060360fe4/contourpy-1.3.3-cp311-cp311-win_arm64.whl",hashes = {sha256 = "15ff10bfada4bf92ec8b31c62bf7c1834c244019b4a33095a68000d7075df470"}}, - {name = "contourpy-1.3.3-pp311-pypy311_pp73-macosx_10_15_x86_64.whl",url = "https://files.pythonhosted.org/packages/a5/29/8dcfe16f0107943fa92388c23f6e05cff0ba58058c4c95b00280d4c75a14/contourpy-1.3.3-pp311-pypy311_pp73-macosx_10_15_x86_64.whl",hashes = {sha256 = "cd5dfcaeb10f7b7f9dc8941717c6c2ade08f587be2226222c12b25f0483ed497"}}, - {name = "contourpy-1.3.3-pp311-pypy311_pp73-macosx_11_0_arm64.whl",url = "https://files.pythonhosted.org/packages/85/a9/8b37ef4f7dafeb335daee3c8254645ef5725be4d9c6aa70b50ec46ef2f7e/contourpy-1.3.3-pp311-pypy311_pp73-macosx_11_0_arm64.whl",hashes = {sha256 = "0c1fc238306b35f246d61a1d416a627348b5cf0648648a031e14bb8705fcdfe8"}}, - {name = "contourpy-1.3.3-pp311-pypy311_pp73-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl",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",hashes = {sha256 = "70f9aad7de812d6541d29d2bbf8feb22ff7e1c299523db288004e3157ff4674e"}}, - {name = "contourpy-1.3.3-pp311-pypy311_pp73-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl",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",hashes = {sha256 = "5ed3657edf08512fc3fe81b510e35c2012fbd3081d2e26160f27ca28affec989"}}, - {name = "contourpy-1.3.3-pp311-pypy311_pp73-win_amd64.whl",url = "https://files.pythonhosted.org/packages/0c/58/bd257695f39d05594ca4ad60df5bcb7e32247f9951fd09a9b8edb82d1daa/contourpy-1.3.3-pp311-pypy311_pp73-win_amd64.whl",hashes = {sha256 = "3d1a3799d62d45c18bafd41c5fa05120b96a28079f2393af559b843d1a966a77"}}, -] -marker = "\"default\" in dependency_groups or \"docs\" in extras" - -[packages.tool.pdm] -dependencies = [ - "numpy>=1.25", -] - -[[packages]] -name = "coverage" -version = "7.13.5" -requires-python = ">=3.10" -sdist = {name = "coverage-7.13.5.tar.gz", url = "https://files.pythonhosted.org/packages/9d/e0/70553e3000e345daff267cec284ce4cbf3fc141b6da229ac52775b5428f1/coverage-7.13.5.tar.gz", hashes = {sha256 = "c81f6515c4c40141f83f502b07bbfa5c240ba25bbe73da7b33f1e5b6120ff179"}} -wheels = [ - {name = "coverage-7.13.5-cp314-cp314-macosx_10_15_x86_64.whl",url = "https://files.pythonhosted.org/packages/8e/77/39703f0d1d4b478bfd30191d3c14f53caf596fac00efb3f8f6ee23646439/coverage-7.13.5-cp314-cp314-macosx_10_15_x86_64.whl",hashes = {sha256 = "fbabfaceaeb587e16f7008f7795cd80d20ec548dc7f94fbb0d4ec2e038ce563f"}}, - {name = "coverage-7.13.5-cp314-cp314-macosx_11_0_arm64.whl",url = "https://files.pythonhosted.org/packages/e2/3e/51dff36d99ae14639a133d9b164d63e628532e2974d8b1edb99dd1ebc733/coverage-7.13.5-cp314-cp314-macosx_11_0_arm64.whl",hashes = {sha256 = "9bb2a28101a443669a423b665939381084412b81c3f8c0fcfbac57f4e30b5b8e"}}, - {name = "coverage-7.13.5-cp314-cp314-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl",url = "https://files.pythonhosted.org/packages/6a/6c/1f1917b01eb647c2f2adc9962bd66c79eb978951cab61bdc1acab3290c07/coverage-7.13.5-cp314-cp314-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl",hashes = {sha256 = "bd3a2fbc1c6cccb3c5106140d87cc6a8715110373ef42b63cf5aea29df8c217a"}}, - {name = "coverage-7.13.5-cp314-cp314-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl",url = "https://files.pythonhosted.org/packages/22/e5/06b1f88f42a5a99df42ce61208bdec3bddb3d261412874280a19796fc09c/coverage-7.13.5-cp314-cp314-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl",hashes = {sha256 = "6c36ddb64ed9d7e496028d1d00dfec3e428e0aabf4006583bb1839958d280510"}}, - {name = "coverage-7.13.5-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl",url = "https://files.pythonhosted.org/packages/80/28/2a148a51e5907e504fa7b85490277734e6771d8844ebcc48764a15e28155/coverage-7.13.5-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl",hashes = {sha256 = "380e8e9084d8eb38db3a9176a1a4f3c0082c3806fa0dc882d1d87abc3c789247"}}, - {name = "coverage-7.13.5-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl",url = "https://files.pythonhosted.org/packages/61/77/50e8d3d85cc0b7ebe09f30f151d670e302c7ff4a1bf6243f71dd8b0981fa/coverage-7.13.5-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl",hashes = {sha256 = "e808af52a0513762df4d945ea164a24b37f2f518cbe97e03deaa0ee66139b4d6"}}, - {name = "coverage-7.13.5-cp314-cp314-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl",url = "https://files.pythonhosted.org/packages/3b/c4/b5fd1d4b7bf8d0e75d997afd3925c59ba629fc8616f1b3aae7605132e256/coverage-7.13.5-cp314-cp314-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl",hashes = {sha256 = "e301d30dd7e95ae068671d746ba8c34e945a82682e62918e41b2679acd2051a0"}}, - {name = "coverage-7.13.5-cp314-cp314-musllinux_1_2_aarch64.whl",url = "https://files.pythonhosted.org/packages/f8/66/6ea21f910e92d69ef0b1c3346ea5922a51bad4446c9126db2ae96ee24c4c/coverage-7.13.5-cp314-cp314-musllinux_1_2_aarch64.whl",hashes = {sha256 = "800bc829053c80d240a687ceeb927a94fd108bbdc68dfbe505d0d75ab578a882"}}, - {name = "coverage-7.13.5-cp314-cp314-musllinux_1_2_i686.whl",url = "https://files.pythonhosted.org/packages/9e/ea/879c83cb5d61aa2a35fb80e72715e92672daef8191b84911a643f533840c/coverage-7.13.5-cp314-cp314-musllinux_1_2_i686.whl",hashes = {sha256 = "0b67af5492adb31940ee418a5a655c28e48165da5afab8c7fa6fd72a142f8740"}}, - {name = "coverage-7.13.5-cp314-cp314-musllinux_1_2_ppc64le.whl",url = "https://files.pythonhosted.org/packages/8a/fb/616d95d3adb88b9803b275580bdeee8bd1b69a886d057652521f83d7322f/coverage-7.13.5-cp314-cp314-musllinux_1_2_ppc64le.whl",hashes = {sha256 = "c9136ff29c3a91e25b1d1552b5308e53a1e0653a23e53b6366d7c2dcbbaf8a16"}}, - {name = "coverage-7.13.5-cp314-cp314-musllinux_1_2_riscv64.whl",url = "https://files.pythonhosted.org/packages/1c/93/25e6917c90ec1c9a56b0b26f6cad6408e5f13bb6b35d484a0d75c9cf000d/coverage-7.13.5-cp314-cp314-musllinux_1_2_riscv64.whl",hashes = {sha256 = "cff784eef7f0b8f6cb28804fbddcfa99f89efe4cc35fb5627e3ac58f91ed3ac0"}}, - {name = "coverage-7.13.5-cp314-cp314-musllinux_1_2_x86_64.whl",url = "https://files.pythonhosted.org/packages/fc/7b/dc1776b0464145a929deed214aef9fb1493f159b59ff3c7eeeedf91eddd0/coverage-7.13.5-cp314-cp314-musllinux_1_2_x86_64.whl",hashes = {sha256 = "68a4953be99b17ac3c23b6efbc8a38330d99680c9458927491d18700ef23ded0"}}, - {name = "coverage-7.13.5-cp314-cp314-win32.whl",url = "https://files.pythonhosted.org/packages/ea/fb/99cbbc56a26e07762a2740713f3c8f9f3f3106e3a3dd8cc4474954bccd34/coverage-7.13.5-cp314-cp314-win32.whl",hashes = {sha256 = "35a31f2b1578185fbe6aa2e74cea1b1d0bbf4c552774247d9160d29b80ed56cc"}}, - {name = "coverage-7.13.5-cp314-cp314-win_amd64.whl",url = "https://files.pythonhosted.org/packages/8d/b7/4758d4f73fb536347cc5e4ad63662f9d60ba9118cb6785e9616b2ce5d7fa/coverage-7.13.5-cp314-cp314-win_amd64.whl",hashes = {sha256 = "2aa055ae1857258f9e0045be26a6d62bdb47a72448b62d7b55f4820f361a2633"}}, - {name = "coverage-7.13.5-cp314-cp314-win_arm64.whl",url = "https://files.pythonhosted.org/packages/2c/f2/24d84e1dfe70f8ac9fdf30d338239860d0d1d5da0bda528959d0ebc9da28/coverage-7.13.5-cp314-cp314-win_arm64.whl",hashes = {sha256 = "1b11eef33edeae9d142f9b4358edb76273b3bfd30bc3df9a4f95d0e49caf94e8"}}, - {name = "coverage-7.13.5-cp314-cp314t-macosx_10_15_x86_64.whl",url = "https://files.pythonhosted.org/packages/60/5b/4a168591057b3668c2428bff25dd3ebc21b629d666d90bcdfa0217940e84/coverage-7.13.5-cp314-cp314t-macosx_10_15_x86_64.whl",hashes = {sha256 = "10a0c37f0b646eaff7cce1874c31d1f1ccb297688d4c747291f4f4c70741cc8b"}}, - {name = "coverage-7.13.5-cp314-cp314t-macosx_11_0_arm64.whl",url = "https://files.pythonhosted.org/packages/f5/21/1fd5c4dbfe4a58b6b99649125635df46decdfd4a784c3cd6d410d303e370/coverage-7.13.5-cp314-cp314t-macosx_11_0_arm64.whl",hashes = {sha256 = "b5db73ba3c41c7008037fa731ad5459fc3944cb7452fc0aa9f822ad3533c583c"}}, - {name = "coverage-7.13.5-cp314-cp314t-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl",url = "https://files.pythonhosted.org/packages/d6/fe/2a924b3055a5e7e4512655a9d4609781b0d62334fa0140c3e742926834e2/coverage-7.13.5-cp314-cp314t-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl",hashes = {sha256 = "750db93a81e3e5a9831b534be7b1229df848b2e125a604fe6651e48aa070e5f9"}}, - {name = "coverage-7.13.5-cp314-cp314t-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl",url = "https://files.pythonhosted.org/packages/d7/0d/c8928f2bd518c45990fe1a2ab8db42e914ef9b726c975facc4282578c3eb/coverage-7.13.5-cp314-cp314t-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl",hashes = {sha256 = "9ddb4f4a5479f2539644be484da179b653273bca1a323947d48ab107b3ed1f29"}}, - {name = "coverage-7.13.5-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl",url = "https://files.pythonhosted.org/packages/ef/ae/4ae35bbd9a0af9d820362751f0766582833c211224b38665c0f8de3d487f/coverage-7.13.5-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl",hashes = {sha256 = "d8a7a2049c14f413163e2bdabd37e41179b1d1ccb10ffc6ccc4b7a718429c607"}}, - {name = "coverage-7.13.5-cp314-cp314t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl",url = "https://files.pythonhosted.org/packages/9c/20/d326174c55af36f74eac6ae781612d9492f060ce8244b570bb9d50d9d609/coverage-7.13.5-cp314-cp314t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl",hashes = {sha256 = "e1c85e0b6c05c592ea6d8768a66a254bfb3874b53774b12d4c89c481eb78cb90"}}, - {name = "coverage-7.13.5-cp314-cp314t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl",url = "https://files.pythonhosted.org/packages/7a/5e/31484d62cbd0eabd3412e30d74386ece4a0837d4f6c3040a653878bfc019/coverage-7.13.5-cp314-cp314t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl",hashes = {sha256 = "777c4d1eff1b67876139d24288aaf1817f6c03d6bae9c5cc8d27b83bcfe38fe3"}}, - {name = "coverage-7.13.5-cp314-cp314t-musllinux_1_2_aarch64.whl",url = "https://files.pythonhosted.org/packages/e9/d8/49a72d6de146eebb0b7e48cc0f4bc2c0dd858e3d4790ab2b39a2872b62bd/coverage-7.13.5-cp314-cp314t-musllinux_1_2_aarch64.whl",hashes = {sha256 = "6697e29b93707167687543480a40f0db8f356e86d9f67ddf2e37e2dfd91a9dab"}}, - {name = "coverage-7.13.5-cp314-cp314t-musllinux_1_2_i686.whl",url = "https://files.pythonhosted.org/packages/06/3b/0351f1bd566e6e4dd39e978efe7958bde1d32f879e85589de147654f57bb/coverage-7.13.5-cp314-cp314t-musllinux_1_2_i686.whl",hashes = {sha256 = "8fdf453a942c3e4d99bd80088141c4c6960bb232c409d9c3558e2dbaa3998562"}}, - {name = "coverage-7.13.5-cp314-cp314t-musllinux_1_2_ppc64le.whl",url = "https://files.pythonhosted.org/packages/5d/ce/796a2a2f4017f554d7810f5c573449b35b1e46788424a548d4d19201b222/coverage-7.13.5-cp314-cp314t-musllinux_1_2_ppc64le.whl",hashes = {sha256 = "32ca0c0114c9834a43f045a87dcebd69d108d8ffb666957ea65aa132f50332e2"}}, - {name = "coverage-7.13.5-cp314-cp314t-musllinux_1_2_riscv64.whl",url = "https://files.pythonhosted.org/packages/3d/16/d5ae91455541d1a78bc90abf495be600588aff8f6db5c8b0dae739fa39c9/coverage-7.13.5-cp314-cp314t-musllinux_1_2_riscv64.whl",hashes = {sha256 = "8769751c10f339021e2638cd354e13adeac54004d1941119b2c96fe5276d45ea"}}, - {name = "coverage-7.13.5-cp314-cp314t-musllinux_1_2_x86_64.whl",url = "https://files.pythonhosted.org/packages/48/11/07f413dba62db21fb3fad5d0de013a50e073cc4e2dc4306e770360f6dfc8/coverage-7.13.5-cp314-cp314t-musllinux_1_2_x86_64.whl",hashes = {sha256 = "cec2d83125531bd153175354055cdb7a09987af08a9430bd173c937c6d0fba2a"}}, - {name = "coverage-7.13.5-cp314-cp314t-win32.whl",url = "https://files.pythonhosted.org/packages/91/15/d792371332eb4663115becf4bad47e047d16234b1aff687b1b18c58d60ae/coverage-7.13.5-cp314-cp314t-win32.whl",hashes = {sha256 = "0cd9ed7a8b181775459296e402ca4fb27db1279740a24e93b3b41942ebe4b215"}}, - {name = "coverage-7.13.5-cp314-cp314t-win_amd64.whl",url = "https://files.pythonhosted.org/packages/db/51/37221f59a111dca5e85be7dbf09696323b5b9f13ff65e0641d535ed06ea8/coverage-7.13.5-cp314-cp314t-win_amd64.whl",hashes = {sha256 = "301e3b7dfefecaca37c9f1aa6f0049b7d4ab8dd933742b607765d757aca77d43"}}, - {name = "coverage-7.13.5-cp314-cp314t-win_arm64.whl",url = "https://files.pythonhosted.org/packages/54/83/6acacc889de8987441aa7d5adfbdbf33d288dad28704a67e574f1df9bcbb/coverage-7.13.5-cp314-cp314t-win_arm64.whl",hashes = {sha256 = "9dacc2ad679b292709e0f5fc1ac74a6d4d5562e424058962c7bb0c658ad25e45"}}, - {name = "coverage-7.13.5-cp313-cp313-macosx_10_13_x86_64.whl",url = "https://files.pythonhosted.org/packages/74/8c/74fedc9663dcf168b0a059d4ea756ecae4da77a489048f94b5f512a8d0b3/coverage-7.13.5-cp313-cp313-macosx_10_13_x86_64.whl",hashes = {sha256 = "5ec4af212df513e399cf11610cc27063f1586419e814755ab362e50a85ea69c1"}}, - {name = "coverage-7.13.5-cp313-cp313-macosx_11_0_arm64.whl",url = "https://files.pythonhosted.org/packages/0c/c9/44fb661c55062f0818a6ffd2685c67aa30816200d5f2817543717d4b92eb/coverage-7.13.5-cp313-cp313-macosx_11_0_arm64.whl",hashes = {sha256 = "941617e518602e2d64942c88ec8499f7fbd49d3f6c4327d3a71d43a1973032f3"}}, - {name = "coverage-7.13.5-cp313-cp313-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl",url = "https://files.pythonhosted.org/packages/5f/13/93419671cee82b780bab7ea96b67c8ef448f5f295f36bf5031154ec9a790/coverage-7.13.5-cp313-cp313-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl",hashes = {sha256 = "da305e9937617ee95c2e39d8ff9f040e0487cbf1ac174f777ed5eddd7a7c1f26"}}, - {name = "coverage-7.13.5-cp313-cp313-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl",url = "https://files.pythonhosted.org/packages/ac/68/1666e3a4462f8202d836920114fa7a5ee9275d1fa45366d336c551a162dd/coverage-7.13.5-cp313-cp313-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl",hashes = {sha256 = "78e696e1cc714e57e8b25760b33a8b1026b7048d270140d25dafe1b0a1ee05a3"}}, - {name = "coverage-7.13.5-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl",url = "https://files.pythonhosted.org/packages/4e/5e/3ee3b835647be646dcf3c65a7c6c18f87c27326a858f72ab22c12730773d/coverage-7.13.5-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl",hashes = {sha256 = "02ca0eed225b2ff301c474aeeeae27d26e2537942aa0f87491d3e147e784a82b"}}, - {name = "coverage-7.13.5-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl",url = "https://files.pythonhosted.org/packages/44/b3/cb5bd1a04cfcc49ede6cd8409d80bee17661167686741e041abc7ee1b9a9/coverage-7.13.5-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl",hashes = {sha256 = "04690832cbea4e4663d9149e05dba142546ca05cb1848816760e7f58285c970a"}}, - {name = "coverage-7.13.5-cp313-cp313-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl",url = "https://files.pythonhosted.org/packages/1b/66/c1dceb7b9714473800b075f5c8a84f4588f887a90eb8645282031676e242/coverage-7.13.5-cp313-cp313-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl",hashes = {sha256 = "0590e44dd2745c696a778f7bab6aa95256de2cbc8b8cff4f7db8ff09813d6969"}}, - {name = "coverage-7.13.5-cp313-cp313-musllinux_1_2_aarch64.whl",url = "https://files.pythonhosted.org/packages/b7/62/5502b73b97aa2e53ea22a39cf8649ff44827bef76d90bf638777daa27a9d/coverage-7.13.5-cp313-cp313-musllinux_1_2_aarch64.whl",hashes = {sha256 = "d7cfad2d6d81dd298ab6b89fe72c3b7b05ec7544bdda3b707ddaecff8d25c161"}}, - {name = "coverage-7.13.5-cp313-cp313-musllinux_1_2_i686.whl",url = "https://files.pythonhosted.org/packages/7d/37/7792c2d69854397ca77a55c4646e5897c467928b0e27f2d235d83b5d08c6/coverage-7.13.5-cp313-cp313-musllinux_1_2_i686.whl",hashes = {sha256 = "e092b9499de38ae0fbfbc603a74660eb6ff3e869e507b50d85a13b6db9863e15"}}, - {name = "coverage-7.13.5-cp313-cp313-musllinux_1_2_ppc64le.whl",url = "https://files.pythonhosted.org/packages/a3/23/bc866fb6163be52a8a9e5d708ba0d3b1283c12158cefca0a8bbb6e247a43/coverage-7.13.5-cp313-cp313-musllinux_1_2_ppc64le.whl",hashes = {sha256 = "48c39bc4a04d983a54a705a6389512883d4a3b9862991b3617d547940e9f52b1"}}, - {name = "coverage-7.13.5-cp313-cp313-musllinux_1_2_riscv64.whl",url = "https://files.pythonhosted.org/packages/7d/8b/ef67e1c222ef49860701d346b8bbb70881bef283bd5f6cbba68a39a086c7/coverage-7.13.5-cp313-cp313-musllinux_1_2_riscv64.whl",hashes = {sha256 = "2d3807015f138ffea1ed9afeeb8624fd781703f2858b62a8dd8da5a0994c57b6"}}, - {name = "coverage-7.13.5-cp313-cp313-musllinux_1_2_x86_64.whl",url = "https://files.pythonhosted.org/packages/46/0d/866d1f74f0acddbb906db212e096dee77a8e2158ca5e6bb44729f9d93298/coverage-7.13.5-cp313-cp313-musllinux_1_2_x86_64.whl",hashes = {sha256 = "ee2aa19e03161671ec964004fb74b2257805d9710bf14a5c704558b9d8dbaf17"}}, - {name = "coverage-7.13.5-cp313-cp313-win32.whl",url = "https://files.pythonhosted.org/packages/7a/f5/be742fec31118f02ce42b21c6af187ad6a344fed546b56ca60caacc6a9a0/coverage-7.13.5-cp313-cp313-win32.whl",hashes = {sha256 = "ce1998c0483007608c8382f4ff50164bfc5bd07a2246dd272aa4043b75e61e85"}}, - {name = "coverage-7.13.5-cp313-cp313-win_amd64.whl",url = "https://files.pythonhosted.org/packages/66/40/7732d648ab9d069a46e686043241f01206348e2bbf128daea85be4d6414b/coverage-7.13.5-cp313-cp313-win_amd64.whl",hashes = {sha256 = "631efb83f01569670a5e866ceb80fe483e7c159fac6f167e6571522636104a0b"}}, - {name = "coverage-7.13.5-cp313-cp313-win_arm64.whl",url = "https://files.pythonhosted.org/packages/48/af/fea819c12a095781f6ccd504890aaddaf88b8fab263c4940e82c7b770124/coverage-7.13.5-cp313-cp313-win_arm64.whl",hashes = {sha256 = "f4cd16206ad171cbc2470dbea9103cf9a7607d5fe8c242fdf1edf36174020664"}}, - {name = "coverage-7.13.5-cp313-cp313t-macosx_10_13_x86_64.whl",url = "https://files.pythonhosted.org/packages/23/d2/17879af479df7fbbd44bd528a31692a48f6b25055d16482fdf5cdb633805/coverage-7.13.5-cp313-cp313t-macosx_10_13_x86_64.whl",hashes = {sha256 = "0428cbef5783ad91fe240f673cc1f76b25e74bbfe1a13115e4aa30d3f538162d"}}, - {name = "coverage-7.13.5-cp313-cp313t-macosx_11_0_arm64.whl",url = "https://files.pythonhosted.org/packages/5b/4c/d20e554f988c8f91d6a02c5118f9abbbf73a8768a3048cb4962230d5743f/coverage-7.13.5-cp313-cp313t-macosx_11_0_arm64.whl",hashes = {sha256 = "e0b216a19534b2427cc201a26c25da4a48633f29a487c61258643e89d28200c0"}}, - {name = "coverage-7.13.5-cp313-cp313t-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl",url = "https://files.pythonhosted.org/packages/29/9c/f9f5277b95184f764b24e7231e166dfdb5780a46d408a2ac665969416d61/coverage-7.13.5-cp313-cp313t-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl",hashes = {sha256 = "972a9cd27894afe4bc2b1480107054e062df08e671df7c2f18c205e805ccd806"}}, - {name = "coverage-7.13.5-cp313-cp313t-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl",url = "https://files.pythonhosted.org/packages/d5/f6/7f1ab39393eeb50cfe4747ae8ef0e4fc564b989225aa1152e13a180d74f8/coverage-7.13.5-cp313-cp313t-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl",hashes = {sha256 = "4b59148601efcd2bac8c4dbf1f0ad6391693ccf7a74b8205781751637076aee3"}}, - {name = "coverage-7.13.5-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl",url = "https://files.pythonhosted.org/packages/a0/d7/62c084fb489ed9c6fbdf57e006752e7c516ea46fd690e5ed8b8617c7d52e/coverage-7.13.5-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl",hashes = {sha256 = "505d7083c8b0c87a8fa8c07370c285847c1f77739b22e299ad75a6af6c32c5c9"}}, - {name = "coverage-7.13.5-cp313-cp313t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl",url = "https://files.pythonhosted.org/packages/a9/f6/df63d8660e1a0bff6125947afda112a0502736f470d62ca68b288ea762d8/coverage-7.13.5-cp313-cp313t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl",hashes = {sha256 = "60365289c3741e4db327e7baff2a4aaacf22f788e80fa4683393891b70a89fbd"}}, - {name = "coverage-7.13.5-cp313-cp313t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl",url = "https://files.pythonhosted.org/packages/5b/02/353ca81d36779bd108f6d384425f7139ac3c58c750dcfaafe5d0bee6436b/coverage-7.13.5-cp313-cp313t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl",hashes = {sha256 = "1b88c69c8ef5d4b6fe7dea66d6636056a0f6a7527c440e890cf9259011f5e606"}}, - {name = "coverage-7.13.5-cp313-cp313t-musllinux_1_2_aarch64.whl",url = "https://files.pythonhosted.org/packages/2c/16/2e79106d5749bcaf3aee6d309123548e3276517cd7851faa8da213bc61bf/coverage-7.13.5-cp313-cp313t-musllinux_1_2_aarch64.whl",hashes = {sha256 = "5b13955d31d1633cf9376908089b7cebe7d15ddad7aeaabcbe969a595a97e95e"}}, - {name = "coverage-7.13.5-cp313-cp313t-musllinux_1_2_i686.whl",url = "https://files.pythonhosted.org/packages/29/c7/c29e0c59ffa6942030ae6f50b88ae49988e7e8da06de7ecdbf49c6d4feae/coverage-7.13.5-cp313-cp313t-musllinux_1_2_i686.whl",hashes = {sha256 = "f70c9ab2595c56f81a89620e22899eea8b212a4041bd728ac6f4a28bf5d3ddd0"}}, - {name = "coverage-7.13.5-cp313-cp313t-musllinux_1_2_ppc64le.whl",url = "https://files.pythonhosted.org/packages/40/48/097cdc3db342f34006a308ab41c3a7c11c3f0d84750d340f45d88a782e00/coverage-7.13.5-cp313-cp313t-musllinux_1_2_ppc64le.whl",hashes = {sha256 = "084b84a8c63e8d6fc7e3931b316a9bcafca1458d753c539db82d31ed20091a87"}}, - {name = "coverage-7.13.5-cp313-cp313t-musllinux_1_2_riscv64.whl",url = "https://files.pythonhosted.org/packages/bb/1f/4994af354689e14fd03a75f8ec85a9a68d94e0188bbdab3fc1516b55e512/coverage-7.13.5-cp313-cp313t-musllinux_1_2_riscv64.whl",hashes = {sha256 = "ad14385487393e386e2ea988b09d62dd42c397662ac2dabc3832d71253eee479"}}, - {name = "coverage-7.13.5-cp313-cp313t-musllinux_1_2_x86_64.whl",url = "https://files.pythonhosted.org/packages/22/c6/9bb9ef55903e628033560885f5c31aa227e46878118b63ab15dc7ba87797/coverage-7.13.5-cp313-cp313t-musllinux_1_2_x86_64.whl",hashes = {sha256 = "7f2c47b36fe7709a6e83bfadf4eefb90bd25fbe4014d715224c4316f808e59a2"}}, - {name = "coverage-7.13.5-cp313-cp313t-win32.whl",url = "https://files.pythonhosted.org/packages/14/4f/f5df9007e50b15e53e01edea486814783a7f019893733d9e4d6caad75557/coverage-7.13.5-cp313-cp313t-win32.whl",hashes = {sha256 = "67e9bc5449801fad0e5dff329499fb090ba4c5800b86805c80617b4e29809b2a"}}, - {name = "coverage-7.13.5-cp313-cp313t-win_amd64.whl",url = "https://files.pythonhosted.org/packages/e1/98/aa7fccaa97d0f3192bec013c4e6fd6d294a6ed44b640e6bb61f479e00ed5/coverage-7.13.5-cp313-cp313t-win_amd64.whl",hashes = {sha256 = "da86cdcf10d2519e10cabb8ac2de03da1bcb6e4853790b7fbd48523332e3a819"}}, - {name = "coverage-7.13.5-cp313-cp313t-win_arm64.whl",url = "https://files.pythonhosted.org/packages/3d/8b/e5c469f7352651e5f013198e9e21f97510b23de957dd06a84071683b4b60/coverage-7.13.5-cp313-cp313t-win_arm64.whl",hashes = {sha256 = "0ecf12ecb326fe2c339d93fc131816f3a7367d223db37817208905c89bded911"}}, - {name = "coverage-7.13.5-cp312-cp312-macosx_10_13_x86_64.whl",url = "https://files.pythonhosted.org/packages/a0/c3/a396306ba7db865bf96fc1fb3b7fd29bcbf3d829df642e77b13555163cd6/coverage-7.13.5-cp312-cp312-macosx_10_13_x86_64.whl",hashes = {sha256 = "460cf0114c5016fa841214ff5564aa4864f11948da9440bc97e21ad1f4ba1e01"}}, - {name = "coverage-7.13.5-cp312-cp312-macosx_11_0_arm64.whl",url = "https://files.pythonhosted.org/packages/a6/16/a68a19e5384e93f811dccc51034b1fd0b865841c390e3c931dcc4699e035/coverage-7.13.5-cp312-cp312-macosx_11_0_arm64.whl",hashes = {sha256 = "0e223ce4b4ed47f065bfb123687686512e37629be25cc63728557ae7db261422"}}, - {name = "coverage-7.13.5-cp312-cp312-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl",url = "https://files.pythonhosted.org/packages/29/72/20b917c6793af3a5ceb7fb9c50033f3ec7865f2911a1416b34a7cfa0813b/coverage-7.13.5-cp312-cp312-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl",hashes = {sha256 = "6e3370441f4513c6252bf042b9c36d22491142385049243253c7e48398a15a9f"}}, - {name = "coverage-7.13.5-cp312-cp312-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl",url = "https://files.pythonhosted.org/packages/8c/49/cd14b789536ac6a4778c453c6a2338bc0a2fb60c5a5a41b4008328b9acc1/coverage-7.13.5-cp312-cp312-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl",hashes = {sha256 = "03ccc709a17a1de074fb1d11f217342fb0d2b1582ed544f554fc9fc3f07e95f5"}}, - {name = "coverage-7.13.5-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl",url = "https://files.pythonhosted.org/packages/9d/00/7b0edcfe64e2ed4c0340dac14a52ad0f4c9bd0b8b5e531af7d55b703db7c/coverage-7.13.5-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl",hashes = {sha256 = "3f4818d065964db3c1c66dc0fbdac5ac692ecbc875555e13374fdbe7eedb4376"}}, - {name = "coverage-7.13.5-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl",url = "https://files.pythonhosted.org/packages/93/89/7ffc4ba0f5d0a55c1e84ea7cee39c9fc06af7b170513d83fbf3bbefce280/coverage-7.13.5-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl",hashes = {sha256 = "012d5319e66e9d5a218834642d6c35d265515a62f01157a45bcc036ecf947256"}}, - {name = "coverage-7.13.5-cp312-cp312-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl",url = "https://files.pythonhosted.org/packages/81/bd/73ddf85f93f7e6fa83e77ccecb6162d9415c79007b4bc124008a4995e4a7/coverage-7.13.5-cp312-cp312-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl",hashes = {sha256 = "8dd02af98971bdb956363e4827d34425cb3df19ee550ef92855b0acb9c7ce51c"}}, - {name = "coverage-7.13.5-cp312-cp312-musllinux_1_2_aarch64.whl",url = "https://files.pythonhosted.org/packages/a0/81/278aff4e8dec4926a0bcb9486320752811f543a3ce5b602cc7a29978d073/coverage-7.13.5-cp312-cp312-musllinux_1_2_aarch64.whl",hashes = {sha256 = "f08fd75c50a760c7eb068ae823777268daaf16a80b918fa58eea888f8e3919f5"}}, - {name = "coverage-7.13.5-cp312-cp312-musllinux_1_2_i686.whl",url = "https://files.pythonhosted.org/packages/70/ee/fe1621488e2e0a58d7e94c4800f0d96f79671553488d401a612bebae324b/coverage-7.13.5-cp312-cp312-musllinux_1_2_i686.whl",hashes = {sha256 = "843ea8643cf967d1ac7e8ecd4bb00c99135adf4816c0c0593fdcc47b597fcf09"}}, - {name = "coverage-7.13.5-cp312-cp312-musllinux_1_2_ppc64le.whl",url = "https://files.pythonhosted.org/packages/37/a6/f79fb37aa104b562207cc23cb5711ab6793608e246cae1e93f26b2236ed9/coverage-7.13.5-cp312-cp312-musllinux_1_2_ppc64le.whl",hashes = {sha256 = "9d44d7aa963820b1b971dbecd90bfe5fe8f81cff79787eb6cca15750bd2f79b9"}}, - {name = "coverage-7.13.5-cp312-cp312-musllinux_1_2_riscv64.whl",url = "https://files.pythonhosted.org/packages/75/f0/ed15262a58ec81ce457ceb717b7f78752a1713556b19081b76e90896e8d4/coverage-7.13.5-cp312-cp312-musllinux_1_2_riscv64.whl",hashes = {sha256 = "7132bed4bd7b836200c591410ae7d97bf7ae8be6fc87d160b2bd881df929e7bf"}}, - {name = "coverage-7.13.5-cp312-cp312-musllinux_1_2_x86_64.whl",url = "https://files.pythonhosted.org/packages/0f/e9/9129958f20e7e9d4d56d51d42ccf708d15cac355ff4ac6e736e97a9393d2/coverage-7.13.5-cp312-cp312-musllinux_1_2_x86_64.whl",hashes = {sha256 = "a698e363641b98843c517817db75373c83254781426e94ada3197cabbc2c919c"}}, - {name = "coverage-7.13.5-cp312-cp312-win32.whl",url = "https://files.pythonhosted.org/packages/a4/d7/0ad9b15812d81272db94379fe4c6df8fd17781cc7671fdfa30c76ba5ff7b/coverage-7.13.5-cp312-cp312-win32.whl",hashes = {sha256 = "bdba0a6b8812e8c7df002d908a9a2ea3c36e92611b5708633c50869e6d922fdf"}}, - {name = "coverage-7.13.5-cp312-cp312-win_amd64.whl",url = "https://files.pythonhosted.org/packages/29/3d/821a9a5799fac2556bcf0bd37a70d1d11fa9e49784b6d22e92e8b2f85f18/coverage-7.13.5-cp312-cp312-win_amd64.whl",hashes = {sha256 = "d2c87e0c473a10bffe991502eac389220533024c8082ec1ce849f4218dded810"}}, - {name = "coverage-7.13.5-cp312-cp312-win_arm64.whl",url = "https://files.pythonhosted.org/packages/d4/fa/2238c2ad08e35cf4f020ea721f717e09ec3152aea75d191a7faf3ef009a8/coverage-7.13.5-cp312-cp312-win_arm64.whl",hashes = {sha256 = "bf69236a9a81bdca3bff53796237aab096cdbf8d78a66ad61e992d9dac7eb2de"}}, - {name = "coverage-7.13.5-cp311-cp311-macosx_10_9_x86_64.whl",url = "https://files.pythonhosted.org/packages/4b/37/d24c8f8220ff07b839b2c043ea4903a33b0f455abe673ae3c03bbdb7f212/coverage-7.13.5-cp311-cp311-macosx_10_9_x86_64.whl",hashes = {sha256 = "66a80c616f80181f4d643b0f9e709d97bcea413ecd9631e1dedc7401c8e6695d"}}, - {name = "coverage-7.13.5-cp311-cp311-macosx_11_0_arm64.whl",url = "https://files.pythonhosted.org/packages/35/8b/cd129b0ca4afe886a6ce9d183c44d8301acbd4ef248622e7c49a23145605/coverage-7.13.5-cp311-cp311-macosx_11_0_arm64.whl",hashes = {sha256 = "145ede53ccbafb297c1c9287f788d1bc3efd6c900da23bf6931b09eafc931587"}}, - {name = "coverage-7.13.5-cp311-cp311-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl",url = "https://files.pythonhosted.org/packages/55/2f/e0e5b237bffdb5d6c530ce87cc1d413a5b7d7dfd60fb067ad6d254c35c76/coverage-7.13.5-cp311-cp311-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl",hashes = {sha256 = "0672854dc733c342fa3e957e0605256d2bf5934feeac328da9e0b5449634a642"}}, - {name = "coverage-7.13.5-cp311-cp311-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl",url = "https://files.pythonhosted.org/packages/92/be/b1afb692be85b947f3401375851484496134c5554e67e822c35f28bf2fbc/coverage-7.13.5-cp311-cp311-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl",hashes = {sha256 = "ec10e2a42b41c923c2209b846126c6582db5e43a33157e9870ba9fb70dc7854b"}}, - {name = "coverage-7.13.5-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl",url = "https://files.pythonhosted.org/packages/da/69/2f47bb6fa1b8d1e3e5d0c4be8ccb4313c63d742476a619418f85740d597b/coverage-7.13.5-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl",hashes = {sha256 = "be3d4bbad9d4b037791794ddeedd7d64a56f5933a2c1373e18e9e568b9141686"}}, - {name = "coverage-7.13.5-cp311-cp311-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl",url = "https://files.pythonhosted.org/packages/d5/d0/79db81da58965bd29dabc8f4ad2a2af70611a57cba9d1ec006f072f30a54/coverage-7.13.5-cp311-cp311-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl",hashes = {sha256 = "4d2afbc5cc54d286bfb54541aa50b64cdb07a718227168c87b9e2fb8f25e1743"}}, - {name = "coverage-7.13.5-cp311-cp311-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl",url = "https://files.pythonhosted.org/packages/e5/32/d0d7cc8168f91ddab44c0ce4806b969df5f5fdfdbb568eaca2dbc2a04936/coverage-7.13.5-cp311-cp311-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl",hashes = {sha256 = "3ad050321264c49c2fa67bb599100456fc51d004b82534f379d16445da40fb75"}}, - {name = "coverage-7.13.5-cp311-cp311-musllinux_1_2_aarch64.whl",url = "https://files.pythonhosted.org/packages/4d/06/a055311d891ddbe231cd69fdd20ea4be6e3603ffebddf8704b8ca8e10a3c/coverage-7.13.5-cp311-cp311-musllinux_1_2_aarch64.whl",hashes = {sha256 = "7300c8a6d13335b29bb76d7651c66af6bd8658517c43499f110ddc6717bfc209"}}, - {name = "coverage-7.13.5-cp311-cp311-musllinux_1_2_i686.whl",url = "https://files.pythonhosted.org/packages/d6/f6/d0fd2d21e29a657b5f77a2fe7082e1568158340dceb941954f776dce1b7b/coverage-7.13.5-cp311-cp311-musllinux_1_2_i686.whl",hashes = {sha256 = "eb07647a5738b89baab047f14edd18ded523de60f3b30e75c2acc826f79c839a"}}, - {name = "coverage-7.13.5-cp311-cp311-musllinux_1_2_ppc64le.whl",url = "https://files.pythonhosted.org/packages/4e/ab/0d7fb2efc2e9a5eb7ddcc6e722f834a69b454b7e6e5888c3a8567ecffb31/coverage-7.13.5-cp311-cp311-musllinux_1_2_ppc64le.whl",hashes = {sha256 = "9adb6688e3b53adffefd4a52d72cbd8b02602bfb8f74dcd862337182fd4d1a4e"}}, - {name = "coverage-7.13.5-cp311-cp311-musllinux_1_2_riscv64.whl",url = "https://files.pythonhosted.org/packages/ba/6f/7467b917bbf5408610178f62a49c0ed4377bb16c1657f689cc61470da8ce/coverage-7.13.5-cp311-cp311-musllinux_1_2_riscv64.whl",hashes = {sha256 = "7c8d4bc913dd70b93488d6c496c77f3aff5ea99a07e36a18f865bca55adef8bd"}}, - {name = "coverage-7.13.5-cp311-cp311-musllinux_1_2_x86_64.whl",url = "https://files.pythonhosted.org/packages/75/2c/1172fb689df92135f5bfbbd69fc83017a76d24ea2e2f3a1154007e2fb9f8/coverage-7.13.5-cp311-cp311-musllinux_1_2_x86_64.whl",hashes = {sha256 = "0e3c426ffc4cd952f54ee9ffbdd10345709ecc78a3ecfd796a57236bfad0b9b8"}}, - {name = "coverage-7.13.5-cp311-cp311-win32.whl",url = "https://files.pythonhosted.org/packages/67/21/9ac389377380a07884e3b48ba7a620fcd9dbfaf1d40565facdc6b36ec9ef/coverage-7.13.5-cp311-cp311-win32.whl",hashes = {sha256 = "259b69bb83ad9894c4b25be2528139eecba9a82646ebdda2d9db1ba28424a6bf"}}, - {name = "coverage-7.13.5-cp311-cp311-win_amd64.whl",url = "https://files.pythonhosted.org/packages/af/7f/4cd8a92531253f9d7c1bbecd9fa1b472907fb54446ca768c59b531248dc5/coverage-7.13.5-cp311-cp311-win_amd64.whl",hashes = {sha256 = "258354455f4e86e3e9d0d17571d522e13b4e1e19bf0f8596bcf9476d61e7d8a9"}}, - {name = "coverage-7.13.5-cp311-cp311-win_arm64.whl",url = "https://files.pythonhosted.org/packages/12/a6/1d3f6155fb0010ca68eba7fe48ca6c9da7385058b77a95848710ecf189b1/coverage-7.13.5-cp311-cp311-win_arm64.whl",hashes = {sha256 = "bff95879c33ec8da99fc9b6fe345ddb5be6414b41d6d1ad1c8f188d26f36e028"}}, - {name = "coverage-7.13.5-py3-none-any.whl",url = "https://files.pythonhosted.org/packages/9e/ee/a4cf96b8ce1e566ed238f0659ac2d3f007ed1d14b181bcb684e19561a69a/coverage-7.13.5-py3-none-any.whl",hashes = {sha256 = "34b02417cf070e173989b3db962f7ed56d2f644307b2cf9d5a0f258e13084a61"}}, -] -marker = "\"test\" in extras" - -[packages.tool.pdm] -dependencies = [] - -[[packages]] -name = "cycler" -version = "0.12.1" -requires-python = ">=3.8" -sdist = {name = "cycler-0.12.1.tar.gz", url = "https://files.pythonhosted.org/packages/a9/95/a3dbbb5028f35eafb79008e7522a75244477d2838f38cbb722248dabc2a8/cycler-0.12.1.tar.gz", hashes = {sha256 = "88bb128f02ba341da8ef447245a9e138fae777f6a23943da4540077d3601eb1c"}} -wheels = [ - {name = "cycler-0.12.1-py3-none-any.whl",url = "https://files.pythonhosted.org/packages/e7/05/c19819d5e3d95294a6f5947fb9b9629efb316b96de511b418c53d245aae6/cycler-0.12.1-py3-none-any.whl",hashes = {sha256 = "85cef7cff222d8644161529808465972e51340599459b8ac3ccbac5a854e0d30"}}, -] -marker = "\"default\" in dependency_groups or \"docs\" in extras" - -[packages.tool.pdm] -dependencies = [] - -[[packages]] -name = "debugpy" -version = "1.8.20" -requires-python = ">=3.8" -sdist = {name = "debugpy-1.8.20.tar.gz", url = "https://files.pythonhosted.org/packages/e0/b7/cd8080344452e4874aae67c40d8940e2b4d47b01601a8fd9f44786c757c7/debugpy-1.8.20.tar.gz", hashes = {sha256 = "55bc8701714969f1ab89a6d5f2f3d40c36f91b2cbe2f65d98bf8196f6a6a2c33"}} -wheels = [ - {name = "debugpy-1.8.20-cp314-cp314-macosx_15_0_universal2.whl",url = "https://files.pythonhosted.org/packages/33/2e/f6cb9a8a13f5058f0a20fe09711a7b726232cd5a78c6a7c05b2ec726cff9/debugpy-1.8.20-cp314-cp314-macosx_15_0_universal2.whl",hashes = {sha256 = "9c74df62fc064cd5e5eaca1353a3ef5a5d50da5eb8058fcef63106f7bebe6173"}}, - {name = "debugpy-1.8.20-cp314-cp314-manylinux_2_34_x86_64.whl",url = "https://files.pythonhosted.org/packages/c5/56/6ddca50b53624e1ca3ce1d1e49ff22db46c47ea5fb4c0cc5c9b90a616364/debugpy-1.8.20-cp314-cp314-manylinux_2_34_x86_64.whl",hashes = {sha256 = "077a7447589ee9bc1ff0cdf443566d0ecf540ac8aa7333b775ebcb8ce9f4ecad"}}, - {name = "debugpy-1.8.20-cp314-cp314-win32.whl",url = "https://files.pythonhosted.org/packages/c5/d9/d64199c14a0d4c476df46c82470a3ce45c8d183a6796cfb5e66533b3663c/debugpy-1.8.20-cp314-cp314-win32.whl",hashes = {sha256 = "352036a99dd35053b37b7803f748efc456076f929c6a895556932eaf2d23b07f"}}, - {name = "debugpy-1.8.20-cp314-cp314-win_amd64.whl",url = "https://files.pythonhosted.org/packages/e0/d9/1f07395b54413432624d61524dfd98c1a7c7827d2abfdb8829ac92638205/debugpy-1.8.20-cp314-cp314-win_amd64.whl",hashes = {sha256 = "a98eec61135465b062846112e5ecf2eebb855305acc1dfbae43b72903b8ab5be"}}, - {name = "debugpy-1.8.20-cp313-cp313-macosx_15_0_universal2.whl",url = "https://files.pythonhosted.org/packages/15/e2/fc500524cc6f104a9d049abc85a0a8b3f0d14c0a39b9c140511c61e5b40b/debugpy-1.8.20-cp313-cp313-macosx_15_0_universal2.whl",hashes = {sha256 = "5dff4bb27027821fdfcc9e8f87309a28988231165147c31730128b1c983e282a"}}, - {name = "debugpy-1.8.20-cp313-cp313-manylinux_2_34_x86_64.whl",url = "https://files.pythonhosted.org/packages/90/83/fb33dcea789ed6018f8da20c5a9bc9d82adc65c0c990faed43f7c955da46/debugpy-1.8.20-cp313-cp313-manylinux_2_34_x86_64.whl",hashes = {sha256 = "84562982dd7cf5ebebfdea667ca20a064e096099997b175fe204e86817f64eaf"}}, - {name = "debugpy-1.8.20-cp313-cp313-win32.whl",url = "https://files.pythonhosted.org/packages/a6/25/b1e4a01bfb824d79a6af24b99ef291e24189080c93576dfd9b1a2815cd0f/debugpy-1.8.20-cp313-cp313-win32.whl",hashes = {sha256 = "da11dea6447b2cadbf8ce2bec59ecea87cc18d2c574980f643f2d2dfe4862393"}}, - {name = "debugpy-1.8.20-cp313-cp313-win_amd64.whl",url = "https://files.pythonhosted.org/packages/13/f7/a0b368ce54ffff9e9028c098bd2d28cfc5b54f9f6c186929083d4c60ba58/debugpy-1.8.20-cp313-cp313-win_amd64.whl",hashes = {sha256 = "eb506e45943cab2efb7c6eafdd65b842f3ae779f020c82221f55aca9de135ed7"}}, - {name = "debugpy-1.8.20-cp312-cp312-macosx_15_0_universal2.whl",url = "https://files.pythonhosted.org/packages/14/57/7f34f4736bfb6e00f2e4c96351b07805d83c9a7b33d28580ae01374430f7/debugpy-1.8.20-cp312-cp312-macosx_15_0_universal2.whl",hashes = {sha256 = "4ae3135e2089905a916909ef31922b2d733d756f66d87345b3e5e52b7a55f13d"}}, - {name = "debugpy-1.8.20-cp312-cp312-manylinux_2_34_x86_64.whl",url = "https://files.pythonhosted.org/packages/ab/78/b193a3975ca34458f6f0e24aaf5c3e3da72f5401f6054c0dfd004b41726f/debugpy-1.8.20-cp312-cp312-manylinux_2_34_x86_64.whl",hashes = {sha256 = "88f47850a4284b88bd2bfee1f26132147d5d504e4e86c22485dfa44b97e19b4b"}}, - {name = "debugpy-1.8.20-cp312-cp312-win32.whl",url = "https://files.pythonhosted.org/packages/c1/55/f14deb95eaf4f30f07ef4b90a8590fc05d9e04df85ee379712f6fb6736d7/debugpy-1.8.20-cp312-cp312-win32.whl",hashes = {sha256 = "4057ac68f892064e5f98209ab582abfee3b543fb55d2e87610ddc133a954d390"}}, - {name = "debugpy-1.8.20-cp312-cp312-win_amd64.whl",url = "https://files.pythonhosted.org/packages/a1/39/2bef246368bd42f9bd7cba99844542b74b84dacbdbea0833e610f384fee8/debugpy-1.8.20-cp312-cp312-win_amd64.whl",hashes = {sha256 = "a1a8f851e7cf171330679ef6997e9c579ef6dd33c9098458bd9986a0f4ca52e3"}}, - {name = "debugpy-1.8.20-cp311-cp311-macosx_15_0_universal2.whl",url = "https://files.pythonhosted.org/packages/51/56/c3baf5cbe4dd77427fd9aef99fcdade259ad128feeb8a786c246adb838e5/debugpy-1.8.20-cp311-cp311-macosx_15_0_universal2.whl",hashes = {sha256 = "eada6042ad88fa1571b74bd5402ee8b86eded7a8f7b827849761700aff171f1b"}}, - {name = "debugpy-1.8.20-cp311-cp311-manylinux_2_34_x86_64.whl",url = "https://files.pythonhosted.org/packages/9a/7d/4fa79a57a8e69fe0d9763e98d1110320f9ecd7f1f362572e3aafd7417c9d/debugpy-1.8.20-cp311-cp311-manylinux_2_34_x86_64.whl",hashes = {sha256 = "7de0b7dfeedc504421032afba845ae2a7bcc32ddfb07dae2c3ca5442f821c344"}}, - {name = "debugpy-1.8.20-cp311-cp311-win32.whl",url = "https://files.pythonhosted.org/packages/7d/f2/1e8f8affe51e12a26f3a8a8a4277d6e60aa89d0a66512f63b1e799d424a4/debugpy-1.8.20-cp311-cp311-win32.whl",hashes = {sha256 = "773e839380cf459caf73cc533ea45ec2737a5cc184cf1b3b796cd4fd98504fec"}}, - {name = "debugpy-1.8.20-cp311-cp311-win_amd64.whl",url = "https://files.pythonhosted.org/packages/d5/92/1cb532e88560cbee973396254b21bece8c5d7c2ece958a67afa08c9f10dc/debugpy-1.8.20-cp311-cp311-win_amd64.whl",hashes = {sha256 = "1f7650546e0eded1902d0f6af28f787fa1f1dbdbc97ddabaf1cd963a405930cb"}}, - {name = "debugpy-1.8.20-py2.py3-none-any.whl",url = "https://files.pythonhosted.org/packages/e0/c3/7f67dea8ccf8fdcb9c99033bbe3e90b9e7395415843accb81428c441be2d/debugpy-1.8.20-py2.py3-none-any.whl",hashes = {sha256 = "5be9bed9ae3be00665a06acaa48f8329d2b9632f15fd09f6a9a8c8d9907e54d7"}}, -] -marker = "\"docs\" in extras" - -[packages.tool.pdm] -dependencies = [] - -[[packages]] -name = "decorator" -version = "5.2.1" -requires-python = ">=3.8" -sdist = {name = "decorator-5.2.1.tar.gz", url = "https://files.pythonhosted.org/packages/43/fa/6d96a0978d19e17b68d634497769987b16c8f4cd0a7a05048bec693caa6b/decorator-5.2.1.tar.gz", hashes = {sha256 = "65f266143752f734b0a7cc83c46f4618af75b8c5911b00ccb61d0ac9b6da0360"}} -wheels = [ - {name = "decorator-5.2.1-py3-none-any.whl",url = "https://files.pythonhosted.org/packages/4e/8c/f3147f5c4b73e7550fe5f9352eaa956ae838d5c51eb58e7a25b9f3e2643b/decorator-5.2.1-py3-none-any.whl",hashes = {sha256 = "d316bb415a2d9e2d2b3abcc4084c6502fc09240e292cd76a76afc106a1c8e04a"}}, -] -marker = "\"docs\" in extras" - -[packages.tool.pdm] -dependencies = [] - -[[packages]] -name = "defusedxml" -version = "0.7.1" -requires-python = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" -sdist = {name = "defusedxml-0.7.1.tar.gz", url = "https://files.pythonhosted.org/packages/0f/d5/c66da9b79e5bdb124974bfe172b4daf3c984ebd9c2a06e2b8a4dc7331c72/defusedxml-0.7.1.tar.gz", hashes = {sha256 = "1bb3032db185915b62d7c6209c5a8792be6a32ab2fedacc84e01b52c51aa3e69"}} -wheels = [ - {name = "defusedxml-0.7.1-py2.py3-none-any.whl",url = "https://files.pythonhosted.org/packages/07/6c/aa3f2f849e01cb6a001cd8554a88d4c77c5c1a31c95bdf1cf9301e6d9ef4/defusedxml-0.7.1-py2.py3-none-any.whl",hashes = {sha256 = "a352e7e428770286cc899e2542b6cdaedb2b4953ff269a210103ec58f6198a61"}}, -] -marker = "\"docs\" in extras" - -[packages.tool.pdm] -dependencies = [] - -[[packages]] -name = "dill" -version = "0.4.1" -requires-python = ">=3.9" -sdist = {name = "dill-0.4.1.tar.gz", url = "https://files.pythonhosted.org/packages/81/e1/56027a71e31b02ddc53c7d65b01e68edf64dea2932122fe7746a516f75d5/dill-0.4.1.tar.gz", hashes = {sha256 = "423092df4182177d4d8ba8290c8a5b640c66ab35ec7da59ccfa00f6fa3eea5fa"}} -wheels = [ - {name = "dill-0.4.1-py3-none-any.whl",url = "https://files.pythonhosted.org/packages/1e/77/dc8c558f7593132cf8fefec57c4f60c83b16941c574ac5f619abb3ae7933/dill-0.4.1-py3-none-any.whl",hashes = {sha256 = "1e1ce33e978ae97fcfcff5638477032b801c46c7c65cf717f95fbc2248f79a9d"}}, -] -marker = "python_version >= \"3.11\" and \"docs\" in extras" - -[packages.tool.pdm] -dependencies = [] - -[[packages]] -name = "docutils" -version = "0.22.4" -requires-python = ">=3.9" -sdist = {name = "docutils-0.22.4.tar.gz", url = "https://files.pythonhosted.org/packages/ae/b6/03bb70946330e88ffec97aefd3ea75ba575cb2e762061e0e62a213befee8/docutils-0.22.4.tar.gz", hashes = {sha256 = "4db53b1fde9abecbb74d91230d32ab626d94f6badfc575d6db9194a49df29968"}} -wheels = [ - {name = "docutils-0.22.4-py3-none-any.whl",url = "https://files.pythonhosted.org/packages/02/10/5da547df7a391dcde17f59520a231527b8571e6f46fc8efb02ccb370ab12/docutils-0.22.4-py3-none-any.whl",hashes = {sha256 = "d0013f540772d1420576855455d050a2180186c91c15779301ac2ccb3eeb68de"}}, -] -marker = "\"docs\" in extras" - -[packages.tool.pdm] -dependencies = [] - -[[packages]] -name = "executing" -version = "2.2.1" -requires-python = ">=3.8" -sdist = {name = "executing-2.2.1.tar.gz", url = "https://files.pythonhosted.org/packages/cc/28/c14e053b6762b1044f34a13aab6859bbf40456d37d23aa286ac24cfd9a5d/executing-2.2.1.tar.gz", hashes = {sha256 = "3632cc370565f6648cc328b32435bd120a1e4ebb20c77e3fdde9a13cd1e533c4"}} -wheels = [ - {name = "executing-2.2.1-py2.py3-none-any.whl",url = "https://files.pythonhosted.org/packages/c1/ea/53f2148663b321f21b5a606bd5f191517cf40b7072c0497d3c92c4a13b1e/executing-2.2.1-py2.py3-none-any.whl",hashes = {sha256 = "760643d3452b4d777d295bb167ccc74c64a81df23fb5e08eff250c425a4b2017"}}, -] -marker = "\"docs\" in extras" - -[packages.tool.pdm] -dependencies = [] - -[[packages]] -name = "fastjsonschema" -version = "2.21.2" -sdist = {name = "fastjsonschema-2.21.2.tar.gz", url = "https://files.pythonhosted.org/packages/20/b5/23b216d9d985a956623b6bd12d4086b60f0059b27799f23016af04a74ea1/fastjsonschema-2.21.2.tar.gz", hashes = {sha256 = "b1eb43748041c880796cd077f1a07c3d94e93ae84bba5ed36800a33554ae05de"}} -wheels = [ - {name = "fastjsonschema-2.21.2-py3-none-any.whl",url = "https://files.pythonhosted.org/packages/cb/a8/20d0723294217e47de6d9e2e40fd4a9d2f7c4b6ef974babd482a59743694/fastjsonschema-2.21.2-py3-none-any.whl",hashes = {sha256 = "1c797122d0a86c5cace2e54bf4e819c36223b552017172f32c5c024a6b77e463"}}, -] -marker = "\"docs\" in extras" - -[packages.tool.pdm] -dependencies = [] - -[[packages]] -name = "fonttools" -version = "4.62.1" -requires-python = ">=3.10" -sdist = {name = "fonttools-4.62.1.tar.gz", url = "https://files.pythonhosted.org/packages/9a/08/7012b00a9a5874311b639c3920270c36ee0c445b69d9989a85e5c92ebcb0/fonttools-4.62.1.tar.gz", hashes = {sha256 = "e54c75fd6041f1122476776880f7c3c3295ffa31962dc6ebe2543c00dca58b5d"}} -wheels = [ - {name = "fonttools-4.62.1-cp314-cp314-macosx_10_15_universal2.whl",url = "https://files.pythonhosted.org/packages/36/f0/2888cdac391807d68d90dcb16ef858ddc1b5309bfc6966195a459dd326e2/fonttools-4.62.1-cp314-cp314-macosx_10_15_universal2.whl",hashes = {sha256 = "fa1d16210b6b10a826d71bed68dd9ec24a9e218d5a5e2797f37c573e7ec215ca"}}, - {name = "fonttools-4.62.1-cp314-cp314-macosx_10_15_x86_64.whl",url = "https://files.pythonhosted.org/packages/4b/b2/e521803081f8dc35990816b82da6360fa668a21b44da4b53fc9e77efcd62/fonttools-4.62.1-cp314-cp314-macosx_10_15_x86_64.whl",hashes = {sha256 = "aa69d10ed420d8121118e628ad47d86e4caa79ba37f968597b958f6cceab7eca"}}, - {name = "fonttools-4.62.1-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl",url = "https://files.pythonhosted.org/packages/00/a4/8c3511ff06e53110039358dbbdc1a65d72157a054638387aa2ada300a8b8/fonttools-4.62.1-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl",hashes = {sha256 = "bd13b7999d59c5eb1c2b442eb2d0c427cb517a0b7a1f5798fc5c9e003f5ff782"}}, - {name = "fonttools-4.62.1-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.whl",url = "https://files.pythonhosted.org/packages/28/63/cd0c3b26afe60995a5295f37c246a93d454023726c3261cfbb3559969bb9/fonttools-4.62.1-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.whl",hashes = {sha256 = "8d337fdd49a79b0d51c4da87bc38169d21c3abbf0c1aa9367eff5c6656fb6dae"}}, - {name = "fonttools-4.62.1-cp314-cp314-musllinux_1_2_aarch64.whl",url = "https://files.pythonhosted.org/packages/70/b9/ac677cb07c24c685cf34f64e140617d58789d67a3dd524164b63648c6114/fonttools-4.62.1-cp314-cp314-musllinux_1_2_aarch64.whl",hashes = {sha256 = "d241cdc4a67b5431c6d7f115fdf63335222414995e3a1df1a41e1182acd4bcc7"}}, - {name = "fonttools-4.62.1-cp314-cp314-musllinux_1_2_x86_64.whl",url = "https://files.pythonhosted.org/packages/e6/10/11c08419a14b85b7ca9a9faca321accccc8842dd9e0b1c8a72908de05945/fonttools-4.62.1-cp314-cp314-musllinux_1_2_x86_64.whl",hashes = {sha256 = "c05557a78f8fa514da0f869556eeda40887a8abc77c76ee3f74cf241778afd5a"}}, - {name = "fonttools-4.62.1-cp314-cp314-win32.whl",url = "https://files.pythonhosted.org/packages/4e/3c/12eea4a4cf054e7ab058ed5ceada43b46809fce2bf319017c4d63ae55bb4/fonttools-4.62.1-cp314-cp314-win32.whl",hashes = {sha256 = "49a445d2f544ce4a69338694cad575ba97b9a75fff02720da0882d1a73f12800"}}, - {name = "fonttools-4.62.1-cp314-cp314-win_amd64.whl",url = "https://files.pythonhosted.org/packages/6b/67/74b070029043186b5dd13462c958cb7c7f811be0d2e634309d9a1ffb1505/fonttools-4.62.1-cp314-cp314-win_amd64.whl",hashes = {sha256 = "1eecc128c86c552fb963fe846ca4e011b1be053728f798185a1687502f6d398e"}}, - {name = "fonttools-4.62.1-cp314-cp314t-macosx_10_15_universal2.whl",url = "https://files.pythonhosted.org/packages/42/c5/4d2ed3ca6e33617fc5624467da353337f06e7f637707478903c785bd8e20/fonttools-4.62.1-cp314-cp314t-macosx_10_15_universal2.whl",hashes = {sha256 = "1596aeaddf7f78e21e68293c011316a25267b3effdaccaf4d59bc9159d681b82"}}, - {name = "fonttools-4.62.1-cp314-cp314t-macosx_10_15_x86_64.whl",url = "https://files.pythonhosted.org/packages/1f/e9/7ab11ddfda48ed0f89b13380e5595ba572619c27077be0b2c447a63ff351/fonttools-4.62.1-cp314-cp314t-macosx_10_15_x86_64.whl",hashes = {sha256 = "8f8fca95d3bb3208f59626a4b0ea6e526ee51f5a8ad5d91821c165903e8d9260"}}, - {name = "fonttools-4.62.1-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl",url = "https://files.pythonhosted.org/packages/b2/10/a800fa090b5e8819942e54e19b55fc7c21fe14a08757c3aa3ca8db358939/fonttools-4.62.1-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl",hashes = {sha256 = "ee91628c08e76f77b533d65feb3fbe6d9dad699f95be51cf0d022db94089cdc4"}}, - {name = "fonttools-4.62.1-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl",url = "https://files.pythonhosted.org/packages/37/dc/8ccd45033fffd74deb6912fa1ca524643f584b94c87a16036855b498a1ed/fonttools-4.62.1-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl",hashes = {sha256 = "5f37df1cac61d906e7b836abe356bc2f34c99d4477467755c216b72aa3dc748b"}}, - {name = "fonttools-4.62.1-cp314-cp314t-musllinux_1_2_aarch64.whl",url = "https://files.pythonhosted.org/packages/99/eb/e618adefb839598d25ac8136cd577925d6c513dc0d931d93b8af956210f0/fonttools-4.62.1-cp314-cp314t-musllinux_1_2_aarch64.whl",hashes = {sha256 = "92bb00a947e666169c99b43753c4305fc95a890a60ef3aeb2a6963e07902cc87"}}, - {name = "fonttools-4.62.1-cp314-cp314t-musllinux_1_2_x86_64.whl",url = "https://files.pythonhosted.org/packages/d9/5f/9b5c9bfaa8ec82def8d8168c4f13615990d6ce5996fe52bd49bfb5e05134/fonttools-4.62.1-cp314-cp314t-musllinux_1_2_x86_64.whl",hashes = {sha256 = "bdfe592802ef939a0e33106ea4a318eeb17822c7ee168c290273cbd5fabd746c"}}, - {name = "fonttools-4.62.1-cp314-cp314t-win32.whl",url = "https://files.pythonhosted.org/packages/90/aa/dfbbe24c6a6afc5c203d90cc0343e24bcbb09e76d67c4d6eef8c2558d7ba/fonttools-4.62.1-cp314-cp314t-win32.whl",hashes = {sha256 = "b820fcb92d4655513d8402d5b219f94481c4443d825b4372c75a2072aa4b357a"}}, - {name = "fonttools-4.62.1-cp314-cp314t-win_amd64.whl",url = "https://files.pythonhosted.org/packages/13/6f/ae9c4e4dd417948407b680855c2c7790efb52add6009aaecff1e3bc50e8e/fonttools-4.62.1-cp314-cp314t-win_amd64.whl",hashes = {sha256 = "59b372b4f0e113d3746b88985f1c796e7bf830dd54b28374cd85c2b8acd7583e"}}, - {name = "fonttools-4.62.1-cp313-cp313-macosx_10_13_universal2.whl",url = "https://files.pythonhosted.org/packages/3b/56/6f389de21c49555553d6a5aeed5ac9767631497ac836c4f076273d15bd72/fonttools-4.62.1-cp313-cp313-macosx_10_13_universal2.whl",hashes = {sha256 = "c22b1014017111c401469e3acc5433e6acf6ebcc6aa9efb538a533c800971c79"}}, - {name = "fonttools-4.62.1-cp313-cp313-macosx_10_13_x86_64.whl",url = "https://files.pythonhosted.org/packages/03/c5/0e3966edd5ec668d41dfe418787726752bc07e2f5fd8c8f208615e61fa89/fonttools-4.62.1-cp313-cp313-macosx_10_13_x86_64.whl",hashes = {sha256 = "68959f5fc58ed4599b44aad161c2837477d7f35f5f79402d97439974faebfebe"}}, - {name = "fonttools-4.62.1-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl",url = "https://files.pythonhosted.org/packages/52/94/e6ac4b44026de7786fe46e3bfa0c87e51d5d70a841054065d49cd62bb909/fonttools-4.62.1-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl",hashes = {sha256 = "ef46db46c9447103b8f3ff91e8ba009d5fe181b1920a83757a5762551e32bb68"}}, - {name = "fonttools-4.62.1-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl",url = "https://files.pythonhosted.org/packages/e2/98/8b1e801939839d405f1f122e7d175cebe9aeb4e114f95bfc45e3152af9a7/fonttools-4.62.1-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl",hashes = {sha256 = "6706d1cb1d5e6251a97ad3c1b9347505c5615c112e66047abbef0f8545fa30d1"}}, - {name = "fonttools-4.62.1-cp313-cp313-musllinux_1_2_aarch64.whl",url = "https://files.pythonhosted.org/packages/46/76/7d051671e938b1881670528fec69cc4044315edd71a229c7fd712eaa5119/fonttools-4.62.1-cp313-cp313-musllinux_1_2_aarch64.whl",hashes = {sha256 = "2e7abd2b1e11736f58c1de27819e1955a53267c21732e78243fa2fa2e5c1e069"}}, - {name = "fonttools-4.62.1-cp313-cp313-musllinux_1_2_x86_64.whl",url = "https://files.pythonhosted.org/packages/1f/ae/b41f8628ec0be3c1b934fc12b84f4576a5c646119db4d3bdd76a217c90b5/fonttools-4.62.1-cp313-cp313-musllinux_1_2_x86_64.whl",hashes = {sha256 = "403d28ce06ebfc547fbcb0cb8b7f7cc2f7a2d3e1a67ba9a34b14632df9e080f9"}}, - {name = "fonttools-4.62.1-cp313-cp313-win32.whl",url = "https://files.pythonhosted.org/packages/f2/f6/53a1e9469331a23dcc400970a27a4caa3d9f6edbf5baab0260285238b884/fonttools-4.62.1-cp313-cp313-win32.whl",hashes = {sha256 = "93c316e0f5301b2adbe6a5f658634307c096fd5aae60a5b3412e4f3e1728ab24"}}, - {name = "fonttools-4.62.1-cp313-cp313-win_amd64.whl",url = "https://files.pythonhosted.org/packages/38/60/35186529de1db3c01f5ad625bde07c1f576305eab6d86bbda4c58445f721/fonttools-4.62.1-cp313-cp313-win_amd64.whl",hashes = {sha256 = "7aa21ff53e28a9c2157acbc44e5b401149d3c9178107130e82d74ceb500e5056"}}, - {name = "fonttools-4.62.1-cp312-cp312-macosx_10_13_universal2.whl",url = "https://files.pythonhosted.org/packages/47/d4/dbacced3953544b9a93088cc10ef2b596d348c983d5c67a404fa41ec51ba/fonttools-4.62.1-cp312-cp312-macosx_10_13_universal2.whl",hashes = {sha256 = "90365821debbd7db678809c7491ca4acd1e0779b9624cdc6ddaf1f31992bf974"}}, - {name = "fonttools-4.62.1-cp312-cp312-macosx_10_13_x86_64.whl",url = "https://files.pythonhosted.org/packages/66/9e/a769c8e99b81e5a87ab7e5e7236684de4e96246aae17274e5347d11ebd78/fonttools-4.62.1-cp312-cp312-macosx_10_13_x86_64.whl",hashes = {sha256 = "12859ff0b47dd20f110804c3e0d0970f7b832f561630cd879969011541a464a9"}}, - {name = "fonttools-4.62.1-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl",url = "https://files.pythonhosted.org/packages/69/64/f19a9e3911968c37e1e620e14dfc5778299e1474f72f4e57c5ec771d9489/fonttools-4.62.1-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl",hashes = {sha256 = "9c125ffa00c3d9003cdaaf7f2c79e6e535628093e14b5de1dccb08859b680936"}}, - {name = "fonttools-4.62.1-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl",url = "https://files.pythonhosted.org/packages/9b/8a/99c8b3c3888c5c474c08dbfd7c8899786de9604b727fcefb055b42c84bba/fonttools-4.62.1-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl",hashes = {sha256 = "149f7d84afca659d1a97e39a4778794a2f83bf344c5ee5134e09995086cc2392"}}, - {name = "fonttools-4.62.1-cp312-cp312-musllinux_1_2_aarch64.whl",url = "https://files.pythonhosted.org/packages/d1/c6/0f904540d3e6ab463c1243a0d803504826a11604c72dd58c2949796a1762/fonttools-4.62.1-cp312-cp312-musllinux_1_2_aarch64.whl",hashes = {sha256 = "0aa72c43a601cfa9273bb1ae0518f1acadc01ee181a6fc60cd758d7fdadffc04"}}, - {name = "fonttools-4.62.1-cp312-cp312-musllinux_1_2_x86_64.whl",url = "https://files.pythonhosted.org/packages/29/0b/5cbef6588dc9bd6b5c9ad6a4d5a8ca384d0cea089da31711bbeb4f9654a6/fonttools-4.62.1-cp312-cp312-musllinux_1_2_x86_64.whl",hashes = {sha256 = "19177c8d96c7c36359266e571c5173bcee9157b59cfc8cb0153c5673dc5a3a7d"}}, - {name = "fonttools-4.62.1-cp312-cp312-win32.whl",url = "https://files.pythonhosted.org/packages/4a/47/b3a5342d381595ef439adec67848bed561ab7fdb1019fa522e82101b7d9c/fonttools-4.62.1-cp312-cp312-win32.whl",hashes = {sha256 = "a24decd24d60744ee8b4679d38e88b8303d86772053afc29b19d23bb8207803c"}}, - {name = "fonttools-4.62.1-cp312-cp312-win_amd64.whl",url = "https://files.pythonhosted.org/packages/28/b1/0c2ab56a16f409c6c8a68816e6af707827ad5d629634691ff60a52879792/fonttools-4.62.1-cp312-cp312-win_amd64.whl",hashes = {sha256 = "9e7863e10b3de72376280b515d35b14f5eeed639d1aa7824f4cf06779ec65e42"}}, - {name = "fonttools-4.62.1-cp311-cp311-macosx_10_9_universal2.whl",url = "https://files.pythonhosted.org/packages/88/39/23ff32561ec8d45a4d48578b4d241369d9270dc50926c017570e60893701/fonttools-4.62.1-cp311-cp311-macosx_10_9_universal2.whl",hashes = {sha256 = "40975849bac44fb0b9253d77420c6d8b523ac4dcdcefeff6e4d706838a5b80f7"}}, - {name = "fonttools-4.62.1-cp311-cp311-macosx_10_9_x86_64.whl",url = "https://files.pythonhosted.org/packages/24/7f/66d3f8a9338a9b67fe6e1739f47e1cd5cee78bd3bc1206ef9b0b982289a5/fonttools-4.62.1-cp311-cp311-macosx_10_9_x86_64.whl",hashes = {sha256 = "9dde91633f77fa576879a0c76b1d89de373cae751a98ddf0109d54e173b40f14"}}, - {name = "fonttools-4.62.1-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl",url = "https://files.pythonhosted.org/packages/aa/53/5276ceba7bff95da7793a07c5284e1da901cf00341ce5e2f3273056c0cca/fonttools-4.62.1-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl",hashes = {sha256 = "6acb4109f8bee00fec985c8c7afb02299e35e9c94b57287f3ea542f28bd0b0a7"}}, - {name = "fonttools-4.62.1-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl",url = "https://files.pythonhosted.org/packages/cc/a1/40a5c4d8e28b0851d53a8eeeb46fbd73c325a2a9a165f290a5ed90e6c597/fonttools-4.62.1-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl",hashes = {sha256 = "1c5c25671ce8805e0d080e2ffdeca7f1e86778c5cbfbeae86d7f866d8830517b"}}, - {name = "fonttools-4.62.1-cp311-cp311-musllinux_1_2_aarch64.whl",url = "https://files.pythonhosted.org/packages/e3/be/d378fca4c65ea1956fee6d90ace6e861776809cbbc5af22388a090c3c092/fonttools-4.62.1-cp311-cp311-musllinux_1_2_aarch64.whl",hashes = {sha256 = "a5d8825e1140f04e6c99bb7d37a9e31c172f3bc208afbe02175339e699c710e1"}}, - {name = "fonttools-4.62.1-cp311-cp311-musllinux_1_2_x86_64.whl",url = "https://files.pythonhosted.org/packages/f8/d9/ae6a1d0693a4185a84605679c8a1f719a55df87b9c6e8e817bfdd9ef5936/fonttools-4.62.1-cp311-cp311-musllinux_1_2_x86_64.whl",hashes = {sha256 = "268abb1cb221e66c014acc234e872b7870d8b5d4657a83a8f4205094c32d2416"}}, - {name = "fonttools-4.62.1-cp311-cp311-win32.whl",url = "https://files.pythonhosted.org/packages/54/6c/af95d9c4efb15cabff22642b608342f2bd67137eea6107202d91b5b03184/fonttools-4.62.1-cp311-cp311-win32.whl",hashes = {sha256 = "942b03094d7edbb99bdf1ae7e9090898cad7bf9030b3d21f33d7072dbcb51a53"}}, - {name = "fonttools-4.62.1-cp311-cp311-win_amd64.whl",url = "https://files.pythonhosted.org/packages/d3/97/bf54c5b3f2be34e1f143e6db838dfdc54f2ffa3e68c738934c82f3b2a08d/fonttools-4.62.1-cp311-cp311-win_amd64.whl",hashes = {sha256 = "e8514f4924375f77084e81467e63238b095abda5107620f49421c368a6017ed2"}}, - {name = "fonttools-4.62.1-py3-none-any.whl",url = "https://files.pythonhosted.org/packages/fd/ba/56147c165442cc5ba7e82ecf301c9a68353cede498185869e6e02b4c264f/fonttools-4.62.1-py3-none-any.whl",hashes = {sha256 = "7487782e2113861f4ddcc07c3436450659e3caa5e470b27dc2177cade2d8e7fd"}}, -] -marker = "\"default\" in dependency_groups or \"docs\" in extras" - -[packages.tool.pdm] -dependencies = [] - -[[packages]] -name = "formulaic" -version = "1.2.1" -requires-python = ">=3.9" -sdist = {name = "formulaic-1.2.1.tar.gz", url = "https://files.pythonhosted.org/packages/6a/8b/8038d2af289a5cc194fa0a255fe964a1a04e0e6ca4426aed8841a4b571e6/formulaic-1.2.1.tar.gz", hashes = {sha256 = "dc79476baa2d811b35798893eb2f2c1e51edee8d7a9c1429b400e56f4e0beccc"}} -wheels = [ - {name = "formulaic-1.2.1-py3-none-any.whl",url = "https://files.pythonhosted.org/packages/1a/9d/c2c8b51b32f829a16fe042db30ad1dcef7947bf1dcf77c2cfd7b6f37b83a/formulaic-1.2.1-py3-none-any.whl",hashes = {sha256 = "661d6d2467aa961b9afb3a1e2a187494239793c63eb729e422d1307afa98b43b"}}, -] -marker = "\"default\" in dependency_groups" - -[packages.tool.pdm] -dependencies = [ - "interface-meta>=1.2.0", - "narwhals>=1.17", - "numpy>=1.20.0", - "pandas>=1.3", - "scipy>=1.6", - "typing-extensions>=4.2.0", - "wrapt>=1.0; python_version < \"3.13\"", - "wrapt>=1.17.0rc1; python_version >= \"3.13\"", -] - -[[packages]] -name = "furo" -version = "2025.12.19" -requires-python = ">=3.8" -sdist = {name = "furo-2025.12.19.tar.gz", url = "https://files.pythonhosted.org/packages/ec/20/5f5ad4da6a5a27c80f2ed2ee9aee3f9e36c66e56e21c00fde467b2f8f88f/furo-2025.12.19.tar.gz", hashes = {sha256 = "188d1f942037d8b37cd3985b955839fea62baa1730087dc29d157677c857e2a7"}} -wheels = [ - {name = "furo-2025.12.19-py3-none-any.whl",url = "https://files.pythonhosted.org/packages/f4/b2/50e9b292b5cac13e9e81272c7171301abc753a60460d21505b606e15cf21/furo-2025.12.19-py3-none-any.whl",hashes = {sha256 = "bb0ead5309f9500130665a26bee87693c41ce4dbdff864dbfb6b0dae4673d24f"}}, -] -marker = "\"docs\" in extras" - -[packages.tool.pdm] -dependencies = [ - "accessible-pygments>=0.0.5", - "beautifulsoup4", - "pygments>=2.7", - "sphinx-basic-ng>=1.0.0.beta2", - "sphinx<10.0,>=7.0", -] - -[[packages]] -name = "h11" -version = "0.16.0" -requires-python = ">=3.8" -sdist = {name = "h11-0.16.0.tar.gz", url = "https://files.pythonhosted.org/packages/01/ee/02a2c011bdab74c6fb3c75474d40b3052059d95df7e73351460c8588d963/h11-0.16.0.tar.gz", hashes = {sha256 = "4e35b956cf45792e4caa5885e69fba00bdbc6ffafbfa020300e549b208ee5ff1"}} -wheels = [ - {name = "h11-0.16.0-py3-none-any.whl",url = "https://files.pythonhosted.org/packages/04/4b/29cac41a4d98d144bf5f6d33995617b185d14b22401f75ca86f384e87ff1/h11-0.16.0-py3-none-any.whl",hashes = {sha256 = "63cf8bbe7522de3bf65932fda1d9c2772064ffb3dae62d55932da54b31cb6c86"}}, -] -marker = "\"docs\" in extras" - -[packages.tool.pdm] -dependencies = [] - -[[packages]] -name = "idna" -version = "3.11" -requires-python = ">=3.8" -sdist = {name = "idna-3.11.tar.gz", url = "https://files.pythonhosted.org/packages/6f/6d/0703ccc57f3a7233505399edb88de3cbd678da106337b9fcde432b65ed60/idna-3.11.tar.gz", hashes = {sha256 = "795dafcc9c04ed0c1fb032c2aa73654d8e8c5023a7df64a53f39190ada629902"}} -wheels = [ - {name = "idna-3.11-py3-none-any.whl",url = "https://files.pythonhosted.org/packages/0e/61/66938bbb5fc52dbdf84594873d5b51fb1f7c7794e9c0f5bd885f30bc507b/idna-3.11-py3-none-any.whl",hashes = {sha256 = "771a87f49d9defaf64091e6e6fe9c18d4833f140bd19464795bc32d966ca37ea"}}, -] -marker = "\"default\" in dependency_groups or \"docs\" in extras" - -[packages.tool.pdm] -dependencies = [] - -[[packages]] -name = "imagesize" -version = "1.5.0" -requires-python = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,>=2.7" -sdist = {name = "imagesize-1.5.0.tar.gz", url = "https://files.pythonhosted.org/packages/cf/59/4b0dd64676aa6fb4986a755790cb6fc558559cf0084effad516820208ec3/imagesize-1.5.0.tar.gz", hashes = {sha256 = "8bfc5363a7f2133a89f0098451e0bcb1cd71aba4dc02bbcecb39d99d40e1b94f"}} -wheels = [ - {name = "imagesize-1.5.0-py2.py3-none-any.whl",url = "https://files.pythonhosted.org/packages/1e/b1/a0662b03103c66cf77101a187f396ea91167cd9b7d5d3a2e465ad2c7ee9b/imagesize-1.5.0-py2.py3-none-any.whl",hashes = {sha256 = "32677681b3f434c2cb496f00e89c5a291247b35b1f527589909e008057da5899"}}, -] -marker = "\"docs\" in extras" - -[packages.tool.pdm] -dependencies = [] - -[[packages]] -name = "iniconfig" -version = "2.3.0" -requires-python = ">=3.10" -sdist = {name = "iniconfig-2.3.0.tar.gz", url = "https://files.pythonhosted.org/packages/72/34/14ca021ce8e5dfedc35312d08ba8bf51fdd999c576889fc2c24cb97f4f10/iniconfig-2.3.0.tar.gz", hashes = {sha256 = "c76315c77db068650d49c5b56314774a7804df16fee4402c1f19d6d15d8c4730"}} -wheels = [ - {name = "iniconfig-2.3.0-py3-none-any.whl",url = "https://files.pythonhosted.org/packages/cb/b1/3846dd7f199d53cb17f49cba7e651e9ce294d8497c8c150530ed11865bb8/iniconfig-2.3.0-py3-none-any.whl",hashes = {sha256 = "f631c04d2c48c52b84d0d0549c99ff3859c98df65b3101406327ecc7d53fbf12"}}, -] -marker = "\"test\" in extras" - -[packages.tool.pdm] -dependencies = [] - -[[packages]] -name = "interface-meta" -version = "1.3.0" -requires-python = ">=3.7,<4.0" -sdist = {name = "interface_meta-1.3.0.tar.gz", url = "https://files.pythonhosted.org/packages/4d/75/10526292b332f3479c246750a96f6ec11a28e297839a9c25583b2aadc119/interface_meta-1.3.0.tar.gz", hashes = {sha256 = "8a4493f8bdb73fb9655dcd5115bc897e207319e36c8835f39c516a2d7e9d79a1"}} -wheels = [ - {name = "interface_meta-1.3.0-py3-none-any.whl",url = "https://files.pythonhosted.org/packages/02/3f/a6ec28c88e2d8e54d32598a1e0b5208a4baa72a8e7f6e241beab5731eb9d/interface_meta-1.3.0-py3-none-any.whl",hashes = {sha256 = "de35dc5241431886e709e20a14d6597ed07c9f1e8b4bfcffde2190ca5b700ee8"}}, -] -marker = "\"default\" in dependency_groups" - -[packages.tool.pdm] -dependencies = [] - -[[packages]] -name = "ipykernel" -version = "7.2.0" -requires-python = ">=3.10" -sdist = {name = "ipykernel-7.2.0.tar.gz", url = "https://files.pythonhosted.org/packages/ca/8d/b68b728e2d06b9e0051019640a40a9eb7a88fcd82c2e1b5ce70bef5ff044/ipykernel-7.2.0.tar.gz", hashes = {sha256 = "18ed160b6dee2cbb16e5f3575858bc19d8f1fe6046a9a680c708494ce31d909e"}} -wheels = [ - {name = "ipykernel-7.2.0-py3-none-any.whl",url = "https://files.pythonhosted.org/packages/82/b9/e73d5d9f405cba7706c539aa8b311b49d4c2f3d698d9c12f815231169c71/ipykernel-7.2.0-py3-none-any.whl",hashes = {sha256 = "3bbd4420d2b3cc105cbdf3756bfc04500b1e52f090a90716851f3916c62e1661"}}, -] -marker = "\"docs\" in extras" - -[packages.tool.pdm] -dependencies = [ - "appnope>=0.1.2; platform_system == \"Darwin\"", - "comm>=0.1.1", - "debugpy>=1.6.5", - "ipython>=7.23.1", - "jupyter-client>=8.8.0", - "jupyter-core!=6.0.*,>=5.1", - "matplotlib-inline>=0.1", - "nest-asyncio>=1.4", - "packaging>=22", - "psutil>=5.7", - "pyzmq>=25", - "tornado>=6.4.1", - "traitlets>=5.4.0", -] - -[[packages]] -name = "ipython" -version = "9.10.1" -requires-python = ">=3.11" -sdist = {name = "ipython-9.10.1.tar.gz", url = "https://files.pythonhosted.org/packages/c5/25/daae0e764047b0a2480c7bbb25d48f4f509b5818636562eeac145d06dfee/ipython-9.10.1.tar.gz", hashes = {sha256 = "e170e9b2a44312484415bdb750492699bf329233b03f2557a9692cce6466ada4"}} -wheels = [ - {name = "ipython-9.10.1-py3-none-any.whl",url = "https://files.pythonhosted.org/packages/01/09/ba70f8d662d5671687da55ad2cc0064cf795b15e1eea70907532202e7c97/ipython-9.10.1-py3-none-any.whl",hashes = {sha256 = "82d18ae9fb9164ded080c71ef92a182ee35ee7db2395f67616034bebb020a232"}}, -] -marker = "\"docs\" in extras" - -[packages.tool.pdm] -dependencies = [ - "colorama>=0.4.4; sys_platform == \"win32\"", - "decorator>=4.3.2", - "ipython-pygments-lexers>=1.0.0", - "jedi>=0.18.1", - "matplotlib-inline>=0.1.5", - "pexpect>4.3; sys_platform != \"win32\" and sys_platform != \"emscripten\"", - "prompt-toolkit<3.1.0,>=3.0.41", - "pygments>=2.11.0", - "stack-data>=0.6.0", - "traitlets>=5.13.0", - "typing-extensions>=4.6; python_version < \"3.12\"", -] - -[[packages]] -name = "ipython-pygments-lexers" -version = "1.1.1" -requires-python = ">=3.8" -sdist = {name = "ipython_pygments_lexers-1.1.1.tar.gz", url = "https://files.pythonhosted.org/packages/ef/4c/5dd1d8af08107f88c7f741ead7a40854b8ac24ddf9ae850afbcf698aa552/ipython_pygments_lexers-1.1.1.tar.gz", hashes = {sha256 = "09c0138009e56b6854f9535736f4171d855c8c08a563a0dcd8022f78355c7e81"}} -wheels = [ - {name = "ipython_pygments_lexers-1.1.1-py3-none-any.whl",url = "https://files.pythonhosted.org/packages/d9/33/1f075bf72b0b747cb3288d011319aaf64083cf2efef8354174e3ed4540e2/ipython_pygments_lexers-1.1.1-py3-none-any.whl",hashes = {sha256 = "a9462224a505ade19a605f71f8fa63c2048833ce50abc86768a0d81d876dc81c"}}, -] -marker = "\"docs\" in extras" - -[packages.tool.pdm] -dependencies = [ - "pygments", -] - -[[packages]] -name = "ipywidgets" -version = "8.1.8" -requires-python = ">=3.7" -sdist = {name = "ipywidgets-8.1.8.tar.gz", url = "https://files.pythonhosted.org/packages/4c/ae/c5ce1edc1afe042eadb445e95b0671b03cee61895264357956e61c0d2ac0/ipywidgets-8.1.8.tar.gz", hashes = {sha256 = "61f969306b95f85fba6b6986b7fe45d73124d1d9e3023a8068710d47a22ea668"}} -wheels = [ - {name = "ipywidgets-8.1.8-py3-none-any.whl",url = "https://files.pythonhosted.org/packages/56/6d/0d9848617b9f753b87f214f1c682592f7ca42de085f564352f10f0843026/ipywidgets-8.1.8-py3-none-any.whl",hashes = {sha256 = "ecaca67aed704a338f88f67b1181b58f821ab5dc89c1f0f5ef99db43c1c2921e"}}, -] -marker = "\"docs\" in extras" - -[packages.tool.pdm] -dependencies = [ - "comm>=0.1.3", - "ipython>=6.1.0", - "jupyterlab-widgets~=3.0.15", - "traitlets>=4.3.1", - "widgetsnbextension~=4.0.14", -] - -[[packages]] -name = "isort" -version = "8.0.1" -requires-python = ">=3.10.0" -sdist = {name = "isort-8.0.1.tar.gz", url = "https://files.pythonhosted.org/packages/ef/7c/ec4ab396d31b3b395e2e999c8f46dec78c5e29209fac49d1f4dace04041d/isort-8.0.1.tar.gz", hashes = {sha256 = "171ac4ff559cdc060bcfff550bc8404a486fee0caab245679c2abe7cb253c78d"}} -wheels = [ - {name = "isort-8.0.1-py3-none-any.whl",url = "https://files.pythonhosted.org/packages/3e/95/c7c34aa53c16353c56d0b802fba48d5f5caa2cdee7958acbcb795c830416/isort-8.0.1-py3-none-any.whl",hashes = {sha256 = "28b89bc70f751b559aeca209e6120393d43fbe2490de0559662be7a9787e3d75"}}, -] -marker = "\"docs\" in extras" - -[packages.tool.pdm] -dependencies = [] - -[[packages]] -name = "jedi" -version = "0.19.2" -requires-python = ">=3.6" -sdist = {name = "jedi-0.19.2.tar.gz", url = "https://files.pythonhosted.org/packages/72/3a/79a912fbd4d8dd6fbb02bf69afd3bb72cf0c729bb3063c6f4498603db17a/jedi-0.19.2.tar.gz", hashes = {sha256 = "4770dc3de41bde3966b02eb84fbcf557fb33cce26ad23da12c742fb50ecb11f0"}} -wheels = [ - {name = "jedi-0.19.2-py2.py3-none-any.whl",url = "https://files.pythonhosted.org/packages/c0/5a/9cac0c82afec3d09ccd97c8b6502d48f165f9124db81b4bcb90b4af974ee/jedi-0.19.2-py2.py3-none-any.whl",hashes = {sha256 = "a8ef22bde8490f57fe5c7681a3c83cb58874daf72b4784de3cce5b6ef6edb5b9"}}, -] -marker = "\"docs\" in extras" - -[packages.tool.pdm] -dependencies = [ - "parso<0.9.0,>=0.8.4", -] - -[[packages]] -name = "jinja2" -version = "3.1.6" -requires-python = ">=3.7" -sdist = {name = "jinja2-3.1.6.tar.gz", url = "https://files.pythonhosted.org/packages/df/bf/f7da0350254c0ed7c72f3e33cef02e048281fec7ecec5f032d4aac52226b/jinja2-3.1.6.tar.gz", hashes = {sha256 = "0137fb05990d35f1275a587e9aee6d56da821fc83491a0fb838183be43f66d6d"}} -wheels = [ - {name = "jinja2-3.1.6-py3-none-any.whl",url = "https://files.pythonhosted.org/packages/62/a1/3d680cbfd5f4b8f15abc1d571870c5fc3e594bb582bc3b64ea099db13e56/jinja2-3.1.6-py3-none-any.whl",hashes = {sha256 = "85ece4451f492d0c13c5dd7c13a64681a86afae63a5f347908daf103ce6d2f67"}}, -] -marker = "\"docs\" in extras" - -[packages.tool.pdm] -dependencies = [ - "MarkupSafe>=2.0", -] - -[[packages]] -name = "joblib" -version = "1.5.3" -requires-python = ">=3.9" -sdist = {name = "joblib-1.5.3.tar.gz", url = "https://files.pythonhosted.org/packages/41/f2/d34e8b3a08a9cc79a50b2208a93dce981fe615b64d5a4d4abee421d898df/joblib-1.5.3.tar.gz", hashes = {sha256 = "8561a3269e6801106863fd0d6d84bb737be9e7631e33aaed3fb9ce5953688da3"}} -wheels = [ - {name = "joblib-1.5.3-py3-none-any.whl",url = "https://files.pythonhosted.org/packages/7b/91/984aca2ec129e2757d1e4e3c81c3fcda9d0f85b74670a094cc443d9ee949/joblib-1.5.3-py3-none-any.whl",hashes = {sha256 = "5fc3c5039fc5ca8c0276333a188bbd59d6b7ab37fe6632daa76bc7f9ec18e713"}}, -] -marker = "\"default\" in dependency_groups" - -[packages.tool.pdm] -dependencies = [] - -[[packages]] -name = "jsonschema" -version = "4.26.0" -requires-python = ">=3.10" -sdist = {name = "jsonschema-4.26.0.tar.gz", url = "https://files.pythonhosted.org/packages/b3/fc/e067678238fa451312d4c62bf6e6cf5ec56375422aee02f9cb5f909b3047/jsonschema-4.26.0.tar.gz", hashes = {sha256 = "0c26707e2efad8aa1bfc5b7ce170f3fccc2e4918ff85989ba9ffa9facb2be326"}} -wheels = [ - {name = "jsonschema-4.26.0-py3-none-any.whl",url = "https://files.pythonhosted.org/packages/69/90/f63fb5873511e014207a475e2bb4e8b2e570d655b00ac19a9a0ca0a385ee/jsonschema-4.26.0-py3-none-any.whl",hashes = {sha256 = "d489f15263b8d200f8387e64b4c3a75f06629559fb73deb8fdfb525f2dab50ce"}}, -] -marker = "\"docs\" in extras" - -[packages.tool.pdm] -dependencies = [ - "attrs>=22.2.0", - "jsonschema-specifications>=2023.03.6", - "referencing>=0.28.4", - "rpds-py>=0.25.0", -] - -[[packages]] -name = "jsonschema-specifications" -version = "2025.9.1" -requires-python = ">=3.9" -sdist = {name = "jsonschema_specifications-2025.9.1.tar.gz", url = "https://files.pythonhosted.org/packages/19/74/a633ee74eb36c44aa6d1095e7cc5569bebf04342ee146178e2d36600708b/jsonschema_specifications-2025.9.1.tar.gz", hashes = {sha256 = "b540987f239e745613c7a9176f3edb72b832a4ac465cf02712288397832b5e8d"}} -wheels = [ - {name = "jsonschema_specifications-2025.9.1-py3-none-any.whl",url = "https://files.pythonhosted.org/packages/41/45/1a4ed80516f02155c51f51e8cedb3c1902296743db0bbc66608a0db2814f/jsonschema_specifications-2025.9.1-py3-none-any.whl",hashes = {sha256 = "98802fee3a11ee76ecaca44429fda8a41bff98b00a0f2838151b113f210cc6fe"}}, -] -marker = "\"docs\" in extras" - -[packages.tool.pdm] -dependencies = [ - "referencing>=0.31.0", -] - -[[packages]] -name = "jupyter-client" -version = "8.8.0" -requires-python = ">=3.10" -sdist = {name = "jupyter_client-8.8.0.tar.gz", url = "https://files.pythonhosted.org/packages/05/e4/ba649102a3bc3fbca54e7239fb924fd434c766f855693d86de0b1f2bec81/jupyter_client-8.8.0.tar.gz", hashes = {sha256 = "d556811419a4f2d96c869af34e854e3f059b7cc2d6d01a9cd9c85c267691be3e"}} -wheels = [ - {name = "jupyter_client-8.8.0-py3-none-any.whl",url = "https://files.pythonhosted.org/packages/2d/0b/ceb7694d864abc0a047649aec263878acb9f792e1fec3e676f22dc9015e3/jupyter_client-8.8.0-py3-none-any.whl",hashes = {sha256 = "f93a5b99c5e23a507b773d3a1136bd6e16c67883ccdbd9a829b0bbdb98cd7d7a"}}, -] -marker = "\"docs\" in extras" - -[packages.tool.pdm] -dependencies = [ - "jupyter-core>=5.1", - "python-dateutil>=2.8.2", - "pyzmq>=25.0", - "tornado>=6.4.1", - "traitlets>=5.3", -] - -[[packages]] -name = "jupyter-core" -version = "5.9.1" -requires-python = ">=3.10" -sdist = {name = "jupyter_core-5.9.1.tar.gz", url = "https://files.pythonhosted.org/packages/02/49/9d1284d0dc65e2c757b74c6687b6d319b02f822ad039e5c512df9194d9dd/jupyter_core-5.9.1.tar.gz", hashes = {sha256 = "4d09aaff303b9566c3ce657f580bd089ff5c91f5f89cf7d8846c3cdf465b5508"}} -wheels = [ - {name = "jupyter_core-5.9.1-py3-none-any.whl",url = "https://files.pythonhosted.org/packages/e7/e7/80988e32bf6f73919a113473a604f5a8f09094de312b9d52b79c2df7612b/jupyter_core-5.9.1-py3-none-any.whl",hashes = {sha256 = "ebf87fdc6073d142e114c72c9e29a9d7ca03fad818c5d300ce2adc1fb0743407"}}, -] -marker = "\"docs\" in extras" - -[packages.tool.pdm] -dependencies = [ - "platformdirs>=2.5", - "traitlets>=5.3", -] - -[[packages]] -name = "jupyter-sphinx" -version = "0.5.3" -requires-python = ">=3.8" -sdist = {name = "jupyter_sphinx-0.5.3.tar.gz", url = "https://files.pythonhosted.org/packages/1a/b5/40f540cc9e54ee829f79daac43456a8d5ab4b70c8d26f0b9eca0dfcb4ad5/jupyter_sphinx-0.5.3.tar.gz", hashes = {sha256 = "2e23699a3a1cf5db31b10981da5aa32606ee730f6b73a844d1e76d800756af56"}} -wheels = [ - {name = "jupyter_sphinx-0.5.3-py3-none-any.whl",url = "https://files.pythonhosted.org/packages/6f/1c/45251d4b9624e42b9e4f369dae2a64f5ea19b9387ba492ceb7be65343dda/jupyter_sphinx-0.5.3-py3-none-any.whl",hashes = {sha256 = "a67b3208d4da5b3508dbb8260d3b359ae476c36c6c642747b78a2520e5be0b05"}}, -] -marker = "\"docs\" in extras" - -[packages.tool.pdm] -dependencies = [ - "ipykernel>=4.5.1", - "ipython", - "ipywidgets>=7.0.0", - "nbconvert>=5.5", - "nbformat", - "sphinx>=7", -] - -[[packages]] -name = "jupyterlab-pygments" -version = "0.3.0" -requires-python = ">=3.8" -sdist = {name = "jupyterlab_pygments-0.3.0.tar.gz", url = "https://files.pythonhosted.org/packages/90/51/9187be60d989df97f5f0aba133fa54e7300f17616e065d1ada7d7646b6d6/jupyterlab_pygments-0.3.0.tar.gz", hashes = {sha256 = "721aca4d9029252b11cfa9d185e5b5af4d54772bb8072f9b7036f4170054d35d"}} -wheels = [ - {name = "jupyterlab_pygments-0.3.0-py3-none-any.whl",url = "https://files.pythonhosted.org/packages/b1/dd/ead9d8ea85bf202d90cc513b533f9c363121c7792674f78e0d8a854b63b4/jupyterlab_pygments-0.3.0-py3-none-any.whl",hashes = {sha256 = "841a89020971da1d8693f1a99997aefc5dc424bb1b251fd6322462a1b8842780"}}, -] -marker = "\"docs\" in extras" - -[packages.tool.pdm] -dependencies = [] - -[[packages]] -name = "jupyterlab-widgets" -version = "3.0.16" -requires-python = ">=3.7" -sdist = {name = "jupyterlab_widgets-3.0.16.tar.gz", url = "https://files.pythonhosted.org/packages/26/2d/ef58fed122b268c69c0aa099da20bc67657cdfb2e222688d5731bd5b971d/jupyterlab_widgets-3.0.16.tar.gz", hashes = {sha256 = "423da05071d55cf27a9e602216d35a3a65a3e41cdf9c5d3b643b814ce38c19e0"}} -wheels = [ - {name = "jupyterlab_widgets-3.0.16-py3-none-any.whl",url = "https://files.pythonhosted.org/packages/ab/b5/36c712098e6191d1b4e349304ef73a8d06aed77e56ceaac8c0a306c7bda1/jupyterlab_widgets-3.0.16-py3-none-any.whl",hashes = {sha256 = "45fa36d9c6422cf2559198e4db481aa243c7a32d9926b500781c830c80f7ecf8"}}, -] -marker = "\"docs\" in extras" - -[packages.tool.pdm] -dependencies = [] - -[[packages]] -name = "kiwisolver" -version = "1.5.0" -requires-python = ">=3.10" -sdist = {name = "kiwisolver-1.5.0.tar.gz", url = "https://files.pythonhosted.org/packages/d0/67/9c61eccb13f0bdca9307614e782fec49ffdde0f7a2314935d489fa93cd9c/kiwisolver-1.5.0.tar.gz", hashes = {sha256 = "d4193f3d9dc3f6f79aaed0e5637f45d98850ebf01f7ca20e69457f3e8946b66a"}} -wheels = [ - {name = "kiwisolver-1.5.0-cp314-cp314-macosx_10_15_universal2.whl",url = "https://files.pythonhosted.org/packages/e4/d7/060f45052f2a01ad5762c8fdecd6d7a752b43400dc29ff75cd47225a40fd/kiwisolver-1.5.0-cp314-cp314-macosx_10_15_universal2.whl",hashes = {sha256 = "8df31fe574b8b3993cc61764f40941111b25c2d9fea13d3ce24a49907cd2d615"}}, - {name = "kiwisolver-1.5.0-cp314-cp314-macosx_10_15_x86_64.whl",url = "https://files.pythonhosted.org/packages/c2/a7/78da680eadd06ff35edef6ef68a1ad273bad3e2a0936c9a885103230aece/kiwisolver-1.5.0-cp314-cp314-macosx_10_15_x86_64.whl",hashes = {sha256 = "1d49a49ac4cbfb7c1375301cd1ec90169dfeae55ff84710d782260ce77a75a02"}}, - {name = "kiwisolver-1.5.0-cp314-cp314-macosx_11_0_arm64.whl",url = "https://files.pythonhosted.org/packages/49/b2/97980f3ad4fae37dd7fe31626e2bf75fbf8bdf5d303950ec1fab39a12da8/kiwisolver-1.5.0-cp314-cp314-macosx_11_0_arm64.whl",hashes = {sha256 = "0cbe94b69b819209a62cb27bdfa5dc2a8977d8de2f89dfd97ba4f53ed3af754e"}}, - {name = "kiwisolver-1.5.0-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.whl",url = "https://files.pythonhosted.org/packages/e7/f9/b06c934a6aa8bc91f566bd2a214fd04c30506c2d9e2b6b171953216a65b6/kiwisolver-1.5.0-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.whl",hashes = {sha256 = "80aa065ffd378ff784822a6d7c3212f2d5f5e9c3589614b5c228b311fd3063ac"}}, - {name = "kiwisolver-1.5.0-cp314-cp314-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl",url = "https://files.pythonhosted.org/packages/6b/f0/f768ae564a710135630672981231320bc403cf9152b5596ec5289de0f106/kiwisolver-1.5.0-cp314-cp314-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl",hashes = {sha256 = "4e7f886f47ab881692f278ae901039a234e4025a68e6dfab514263a0b1c4ae05"}}, - {name = "kiwisolver-1.5.0-cp314-cp314-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl",url = "https://files.pythonhosted.org/packages/e2/9f/1de7aad00697325f05238a5f2eafbd487fb637cc27a558b5367a5f37fb7f/kiwisolver-1.5.0-cp314-cp314-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl",hashes = {sha256 = "5060731cc3ed12ca3a8b57acd4aeca5bbc2f49216dd0bec1650a1acd89486bcd"}}, - {name = "kiwisolver-1.5.0-cp314-cp314-manylinux_2_24_s390x.manylinux_2_28_s390x.whl",url = "https://files.pythonhosted.org/packages/5a/c2/297f25141d2e468e0ce7f7a7b92e0cf8918143a0cbd3422c1ad627e85a06/kiwisolver-1.5.0-cp314-cp314-manylinux_2_24_s390x.manylinux_2_28_s390x.whl",hashes = {sha256 = "7a4aa69609f40fce3cbc3f87b2061f042eee32f94b8f11db707b66a26461591a"}}, - {name = "kiwisolver-1.5.0-cp314-cp314-manylinux_2_39_riscv64.whl",url = "https://files.pythonhosted.org/packages/b9/d3/f4c73a02eb41520c47610207b21afa8cdd18fdbf64ffd94674ae21c4812d/kiwisolver-1.5.0-cp314-cp314-manylinux_2_39_riscv64.whl",hashes = {sha256 = "d168fda2dbff7b9b5f38e693182d792a938c31db4dac3a80a4888de603c99554"}}, - {name = "kiwisolver-1.5.0-cp314-cp314-musllinux_1_2_aarch64.whl",url = "https://files.pythonhosted.org/packages/7b/46/d3f2efef7732fcda98d22bf4ad5d3d71d545167a852ca710a494f4c15343/kiwisolver-1.5.0-cp314-cp314-musllinux_1_2_aarch64.whl",hashes = {sha256 = "413b820229730d358efd838ecbab79902fe97094565fdc80ddb6b0a18c18a581"}}, - {name = "kiwisolver-1.5.0-cp314-cp314-musllinux_1_2_ppc64le.whl",url = "https://files.pythonhosted.org/packages/3f/ec/2d9756bf2b6d26ae4349b8d3662fb3993f16d80c1f971c179ce862b9dbae/kiwisolver-1.5.0-cp314-cp314-musllinux_1_2_ppc64le.whl",hashes = {sha256 = "5124d1ea754509b09e53738ec185584cc609aae4a3b510aaf4ed6aa047ef9303"}}, - {name = "kiwisolver-1.5.0-cp314-cp314-musllinux_1_2_riscv64.whl",url = "https://files.pythonhosted.org/packages/8f/9f/876a0a0f2260f1bde92e002b3019a5fabc35e0939c7d945e0fa66185eb20/kiwisolver-1.5.0-cp314-cp314-musllinux_1_2_riscv64.whl",hashes = {sha256 = "e4415a8db000bf49a6dd1c478bf70062eaacff0f462b92b0ba68791a905861f9"}}, - {name = "kiwisolver-1.5.0-cp314-cp314-musllinux_1_2_s390x.whl",url = "https://files.pythonhosted.org/packages/6c/4f/ba3624dfac23a64d54ac4179832860cb537c1b0af06024936e82ca4154a0/kiwisolver-1.5.0-cp314-cp314-musllinux_1_2_s390x.whl",hashes = {sha256 = "d618fd27420381a4f6044faa71f46d8bfd911bd077c555f7138ed88729bfbe79"}}, - {name = "kiwisolver-1.5.0-cp314-cp314-musllinux_1_2_x86_64.whl",url = "https://files.pythonhosted.org/packages/39/b7/97716b190ab98911b20d10bf92eca469121ec483b8ce0edd314f51bc85af/kiwisolver-1.5.0-cp314-cp314-musllinux_1_2_x86_64.whl",hashes = {sha256 = "5092eb5b1172947f57d6ea7d89b2f29650414e4293c47707eb499ec07a0ac796"}}, - {name = "kiwisolver-1.5.0-cp314-cp314-win_amd64.whl",url = "https://files.pythonhosted.org/packages/a3/36/4e551e8aa55c9188bca9abb5096805edbf7431072b76e2298e34fd3a3008/kiwisolver-1.5.0-cp314-cp314-win_amd64.whl",hashes = {sha256 = "d76e2d8c75051d58177e762164d2e9ab92886534e3a12e795f103524f221dd8e"}}, - {name = "kiwisolver-1.5.0-cp314-cp314-win_arm64.whl",url = "https://files.pythonhosted.org/packages/70/15/9b90f7df0e31a003c71649cf66ef61c3c1b862f48c81007fa2383c8bd8d7/kiwisolver-1.5.0-cp314-cp314-win_arm64.whl",hashes = {sha256 = "fa6248cd194edff41d7ea9425ced8ca3a6f838bfb295f6f1d6e6bb694a8518df"}}, - {name = "kiwisolver-1.5.0-cp314-cp314t-macosx_10_15_universal2.whl",url = "https://files.pythonhosted.org/packages/17/01/7dc8c5443ff42b38e72731643ed7cf1ed9bf01691ae5cdca98501999ed83/kiwisolver-1.5.0-cp314-cp314t-macosx_10_15_universal2.whl",hashes = {sha256 = "d1ffeb80b5676463d7a7d56acbe8e37a20ce725570e09549fe738e02ca6b7e1e"}}, - {name = "kiwisolver-1.5.0-cp314-cp314t-macosx_10_15_x86_64.whl",url = "https://files.pythonhosted.org/packages/46/8a/b4ebe46ebaac6a303417fab10c2e165c557ddaff558f9699d302b256bc53/kiwisolver-1.5.0-cp314-cp314t-macosx_10_15_x86_64.whl",hashes = {sha256 = "bc4d8e252f532ab46a1de9349e2d27b91fce46736a9eedaa37beaca66f574ed4"}}, - {name = "kiwisolver-1.5.0-cp314-cp314t-macosx_11_0_arm64.whl",url = "https://files.pythonhosted.org/packages/60/35/10a844afc5f19d6f567359bf4789e26661755a2f36200d5d1ed8ad0126e5/kiwisolver-1.5.0-cp314-cp314t-macosx_11_0_arm64.whl",hashes = {sha256 = "6783e069732715ad0c3ce96dbf21dbc2235ab0593f2baf6338101f70371f4028"}}, - {name = "kiwisolver-1.5.0-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl",url = "https://files.pythonhosted.org/packages/f8/8a/685b297052dd041dcebce8e8787b58923b6e78acc6115a0dc9189011c44b/kiwisolver-1.5.0-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl",hashes = {sha256 = "e7c4c09a490dc4d4a7f8cbee56c606a320f9dc28cf92a7157a39d1ce7676a657"}}, - {name = "kiwisolver-1.5.0-cp314-cp314t-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl",url = "https://files.pythonhosted.org/packages/9e/80/04865e3d4638ac5bddec28908916df4a3075b8c6cc101786a96803188b96/kiwisolver-1.5.0-cp314-cp314t-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl",hashes = {sha256 = "2a075bd7bd19c70cf67c8badfa36cf7c5d8de3c9ddb8420c51e10d9c50e94920"}}, - {name = "kiwisolver-1.5.0-cp314-cp314t-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl",url = "https://files.pythonhosted.org/packages/ba/01/77a19cacc0893fa13fafa46d1bba06fb4dc2360b3292baf4b56d8e067b24/kiwisolver-1.5.0-cp314-cp314t-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl",hashes = {sha256 = "bdd3e53429ff02aa319ba59dfe4ceeec345bf46cf180ec2cf6fd5b942e7975e9"}}, - {name = "kiwisolver-1.5.0-cp314-cp314t-manylinux_2_24_s390x.manylinux_2_28_s390x.whl",url = "https://files.pythonhosted.org/packages/53/39/bcaf5d0cca50e604cfa9b4e3ae1d64b50ca1ae5b754122396084599ef903/kiwisolver-1.5.0-cp314-cp314t-manylinux_2_24_s390x.manylinux_2_28_s390x.whl",hashes = {sha256 = "3cdcb35dc9d807259c981a85531048ede628eabcffb3239adf3d17463518992d"}}, - {name = "kiwisolver-1.5.0-cp314-cp314t-manylinux_2_39_riscv64.whl",url = "https://files.pythonhosted.org/packages/d0/7a/72c187abc6975f6978c3e39b7cf67aeb8b3c0a8f9790aa7fd412855e9e1f/kiwisolver-1.5.0-cp314-cp314t-manylinux_2_39_riscv64.whl",hashes = {sha256 = "70d593af6a6ca332d1df73d519fddb5148edb15cd90d5f0155e3746a6d4fcc65"}}, - {name = "kiwisolver-1.5.0-cp314-cp314t-musllinux_1_2_aarch64.whl",url = "https://files.pythonhosted.org/packages/c7/ca/cf5b25783ebbd59143b4371ed0c8428a278abe68d6d0104b01865b1bbd0f/kiwisolver-1.5.0-cp314-cp314t-musllinux_1_2_aarch64.whl",hashes = {sha256 = "377815a8616074cabbf3f53354e1d040c35815a134e01d7614b7692e4bf8acfa"}}, - {name = "kiwisolver-1.5.0-cp314-cp314t-musllinux_1_2_ppc64le.whl",url = "https://files.pythonhosted.org/packages/4a/e5/b1f492adc516796e88751282276745340e2a72dcd0d36cf7173e0daf3210/kiwisolver-1.5.0-cp314-cp314t-musllinux_1_2_ppc64le.whl",hashes = {sha256 = "0255a027391d52944eae1dbb5d4cc5903f57092f3674e8e544cdd2622826b3f0"}}, - {name = "kiwisolver-1.5.0-cp314-cp314t-musllinux_1_2_riscv64.whl",url = "https://files.pythonhosted.org/packages/e6/e5/9b21fbe91a61b8f409d74a26498706e97a48008bfcd1864373d32a6ba31c/kiwisolver-1.5.0-cp314-cp314t-musllinux_1_2_riscv64.whl",hashes = {sha256 = "012b1eb16e28718fa782b5e61dc6f2da1f0792ca73bd05d54de6cb9561665fc9"}}, - {name = "kiwisolver-1.5.0-cp314-cp314t-musllinux_1_2_s390x.whl",url = "https://files.pythonhosted.org/packages/b1/02/83f47986138310f95ea95531f851b2a62227c11cbc3e690ae1374fe49f0f/kiwisolver-1.5.0-cp314-cp314t-musllinux_1_2_s390x.whl",hashes = {sha256 = "0e3aafb33aed7479377e5e9a82e9d4bf87063741fc99fc7ae48b0f16e32bdd6f"}}, - {name = "kiwisolver-1.5.0-cp314-cp314t-musllinux_1_2_x86_64.whl",url = "https://files.pythonhosted.org/packages/07/18/43a5f24608d8c313dd189cf838c8e68d75b115567c6279de7796197cfb6a/kiwisolver-1.5.0-cp314-cp314t-musllinux_1_2_x86_64.whl",hashes = {sha256 = "e7a116ae737f0000343218c4edf5bd45893bfeaff0993c0b215d7124c9f77646"}}, - {name = "kiwisolver-1.5.0-cp314-cp314t-win_amd64.whl",url = "https://files.pythonhosted.org/packages/3b/b5/98222136d839b8afabcaa943b09bd05888c2d36355b7e448550211d1fca4/kiwisolver-1.5.0-cp314-cp314t-win_amd64.whl",hashes = {sha256 = "1dd9b0b119a350976a6d781e7278ec7aca0b201e1a9e2d23d9804afecb6ca681"}}, - {name = "kiwisolver-1.5.0-cp314-cp314t-win_arm64.whl",url = "https://files.pythonhosted.org/packages/99/a2/ca7dc962848040befed12732dff6acae7fb3c4f6fc4272b3f6c9a30b8713/kiwisolver-1.5.0-cp314-cp314t-win_arm64.whl",hashes = {sha256 = "58f812017cd2985c21fbffb4864d59174d4903dd66fa23815e74bbc7a0e2dd57"}}, - {name = "kiwisolver-1.5.0-cp313-cp313-macosx_10_13_universal2.whl",url = "https://files.pythonhosted.org/packages/9d/69/024d6711d5ba575aa65d5538042e99964104e97fa153a9f10bc369182bc2/kiwisolver-1.5.0-cp313-cp313-macosx_10_13_universal2.whl",hashes = {sha256 = "fd40bb9cd0891c4c3cb1ddf83f8bbfa15731a248fdc8162669405451e2724b09"}}, - {name = "kiwisolver-1.5.0-cp313-cp313-macosx_10_13_x86_64.whl",url = "https://files.pythonhosted.org/packages/ce/48/adbb40df306f587054a348831220812b9b1d787aff714cfbc8556e38fccd/kiwisolver-1.5.0-cp313-cp313-macosx_10_13_x86_64.whl",hashes = {sha256 = "c0e1403fd7c26d77c1f03e096dc58a5c726503fa0db0456678b8668f76f521e3"}}, - {name = "kiwisolver-1.5.0-cp313-cp313-macosx_11_0_arm64.whl",url = "https://files.pythonhosted.org/packages/a8/3a/d0a972b34e1c63e2409413104216cd1caa02c5a37cb668d1687d466c1c45/kiwisolver-1.5.0-cp313-cp313-macosx_11_0_arm64.whl",hashes = {sha256 = "dda366d548e89a90d88a86c692377d18d8bd64b39c1fb2b92cb31370e2896bbd"}}, - {name = "kiwisolver-1.5.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl",url = "https://files.pythonhosted.org/packages/2b/0a/7b98e1e119878a27ba8618ca1e18b14f992ff1eda40f47bccccf4de44121/kiwisolver-1.5.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl",hashes = {sha256 = "332b4f0145c30b5f5ad9374881133e5aa64320428a57c2c2b61e9d891a51c2f3"}}, - {name = "kiwisolver-1.5.0-cp313-cp313-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl",url = "https://files.pythonhosted.org/packages/18/d8/55638d89ffd27799d5cc3d8aa28e12f4ce7a64d67b285114dbedc8ea4136/kiwisolver-1.5.0-cp313-cp313-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl",hashes = {sha256 = "0c50b89ffd3e1a911c69a1dd3de7173c0cd10b130f56222e57898683841e4f96"}}, - {name = "kiwisolver-1.5.0-cp313-cp313-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl",url = "https://files.pythonhosted.org/packages/b8/97/b4c8d0d18421ecceba20ad8701358453b88e32414e6f6950b5a4bad54e65/kiwisolver-1.5.0-cp313-cp313-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl",hashes = {sha256 = "4db576bb8c3ef9365f8b40fe0f671644de6736ae2c27a2c62d7d8a1b4329f099"}}, - {name = "kiwisolver-1.5.0-cp313-cp313-manylinux_2_24_s390x.manylinux_2_28_s390x.whl",url = "https://files.pythonhosted.org/packages/c4/10/f862f94b6389d8957448ec9df59450b81bec4abb318805375c401a1e6892/kiwisolver-1.5.0-cp313-cp313-manylinux_2_24_s390x.manylinux_2_28_s390x.whl",hashes = {sha256 = "0b85aad90cea8ac6797a53b5d5f2e967334fa4d1149f031c4537569972596cb8"}}, - {name = "kiwisolver-1.5.0-cp313-cp313-manylinux_2_39_riscv64.whl",url = "https://files.pythonhosted.org/packages/a3/6a/f1650af35821eaf09de398ec0bc2aefc8f211f0cda50204c9f1673741ba9/kiwisolver-1.5.0-cp313-cp313-manylinux_2_39_riscv64.whl",hashes = {sha256 = "d36ca54cb4c6c4686f7cbb7b817f66f5911c12ddb519450bbe86707155028f87"}}, - {name = "kiwisolver-1.5.0-cp313-cp313-musllinux_1_2_aarch64.whl",url = "https://files.pythonhosted.org/packages/de/19/d7fb82984b9238115fe629c915007be608ebd23dc8629703d917dbfaffd4/kiwisolver-1.5.0-cp313-cp313-musllinux_1_2_aarch64.whl",hashes = {sha256 = "38f4a703656f493b0ad185211ccfca7f0386120f022066b018eb5296d8613e23"}}, - {name = "kiwisolver-1.5.0-cp313-cp313-musllinux_1_2_ppc64le.whl",url = "https://files.pythonhosted.org/packages/7f/b9/46b7f386589fd222dac9e9de9c956ce5bcefe2ee73b4e79891381dda8654/kiwisolver-1.5.0-cp313-cp313-musllinux_1_2_ppc64le.whl",hashes = {sha256 = "3ac2360e93cb41be81121755c6462cff3beaa9967188c866e5fce5cf13170859"}}, - {name = "kiwisolver-1.5.0-cp313-cp313-musllinux_1_2_riscv64.whl",url = "https://files.pythonhosted.org/packages/92/8b/95e237cf3d9c642960153c769ddcbe278f182c8affb20cecc1cc983e7cc5/kiwisolver-1.5.0-cp313-cp313-musllinux_1_2_riscv64.whl",hashes = {sha256 = "c95cab08d1965db3d84a121f1c7ce7479bdd4072c9b3dafd8fecce48a2e6b902"}}, - {name = "kiwisolver-1.5.0-cp313-cp313-musllinux_1_2_s390x.whl",url = "https://files.pythonhosted.org/packages/1b/95/980c9df53501892784997820136c01f62bc1865e31b82b9560f980c0e649/kiwisolver-1.5.0-cp313-cp313-musllinux_1_2_s390x.whl",hashes = {sha256 = "fc20894c3d21194d8041a28b65622d5b86db786da6e3cfe73f0c762951a61167"}}, - {name = "kiwisolver-1.5.0-cp313-cp313-musllinux_1_2_x86_64.whl",url = "https://files.pythonhosted.org/packages/cb/32/900647fd0840abebe1561792c6b31e6a7c0e278fc3973d30572a965ca14c/kiwisolver-1.5.0-cp313-cp313-musllinux_1_2_x86_64.whl",hashes = {sha256 = "7a32f72973f0f950c1920475d5c5ea3d971b81b6f0ec53b8d0a956cc965f22e0"}}, - {name = "kiwisolver-1.5.0-cp313-cp313-win_amd64.whl",url = "https://files.pythonhosted.org/packages/be/8a/be60e3bbcf513cc5a50f4a3e88e1dcecebb79c1ad607a7222877becaa101/kiwisolver-1.5.0-cp313-cp313-win_amd64.whl",hashes = {sha256 = "0bf3acf1419fa93064a4c2189ac0b58e3be7872bf6ee6177b0d4c63dc4cea276"}}, - {name = "kiwisolver-1.5.0-cp313-cp313-win_arm64.whl",url = "https://files.pythonhosted.org/packages/4d/d2/64be2e429eb4fca7f7e1c52a91b12663aeaf25de3895e5cca0f47ef2a8d0/kiwisolver-1.5.0-cp313-cp313-win_arm64.whl",hashes = {sha256 = "fa8eb9ecdb7efb0b226acec134e0d709e87a909fa4971a54c0c4f6e88635484c"}}, - {name = "kiwisolver-1.5.0-cp313-cp313t-macosx_10_13_universal2.whl",url = "https://files.pythonhosted.org/packages/b0/69/ce68dd0c85755ae2de490bf015b62f2cea5f6b14ff00a463f9d0774449ff/kiwisolver-1.5.0-cp313-cp313t-macosx_10_13_universal2.whl",hashes = {sha256 = "db485b3847d182b908b483b2ed133c66d88d49cacf98fd278fadafe11b4478d1"}}, - {name = "kiwisolver-1.5.0-cp313-cp313t-macosx_10_13_x86_64.whl",url = "https://files.pythonhosted.org/packages/74/aa/937aac021cf9d4349990d47eb319309a51355ed1dbdc9c077cdc9224cb11/kiwisolver-1.5.0-cp313-cp313t-macosx_10_13_x86_64.whl",hashes = {sha256 = "be12f931839a3bdfe28b584db0e640a65a8bcbc24560ae3fdb025a449b3d754e"}}, - {name = "kiwisolver-1.5.0-cp313-cp313t-macosx_11_0_arm64.whl",url = "https://files.pythonhosted.org/packages/ee/20/3a87fbece2c40ad0f6f0aefa93542559159c5f99831d596050e8afae7a9f/kiwisolver-1.5.0-cp313-cp313t-macosx_11_0_arm64.whl",hashes = {sha256 = "16b85d37c2cbb3253226d26e64663f755d88a03439a9c47df6246b35defbdfb7"}}, - {name = "kiwisolver-1.5.0-cp313-cp313t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl",url = "https://files.pythonhosted.org/packages/f0/7f/f943879cda9007c45e1f7dba216d705c3a18d6b35830e488b6c6a4e7cdf0/kiwisolver-1.5.0-cp313-cp313t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl",hashes = {sha256 = "4432b835675f0ea7414aab3d37d119f7226d24869b7a829caeab49ebda407b0c"}}, - {name = "kiwisolver-1.5.0-cp313-cp313t-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl",url = "https://files.pythonhosted.org/packages/37/f8/4d4f85cc1870c127c88d950913370dd76138482161cd07eabbc450deff01/kiwisolver-1.5.0-cp313-cp313t-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl",hashes = {sha256 = "1b0feb50971481a2cc44d94e88bdb02cdd497618252ae226b8eb1201b957e368"}}, - {name = "kiwisolver-1.5.0-cp313-cp313t-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl",url = "https://files.pythonhosted.org/packages/04/0b/65dd2916c84d252b244bd405303220f729e7c17c9d7d33dca6feeff9ffc4/kiwisolver-1.5.0-cp313-cp313t-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl",hashes = {sha256 = "56fa888f10d0f367155e76ce849fa1166fc9730d13bd2d65a2aa13b6f5424489"}}, - {name = "kiwisolver-1.5.0-cp313-cp313t-manylinux_2_24_s390x.manylinux_2_28_s390x.whl",url = "https://files.pythonhosted.org/packages/39/5c/2606a373247babce9b1d056c03a04b65f3cf5290a8eac5d7bdead0a17e21/kiwisolver-1.5.0-cp313-cp313t-manylinux_2_24_s390x.manylinux_2_28_s390x.whl",hashes = {sha256 = "940dda65d5e764406b9fb92761cbf462e4e63f712ab60ed98f70552e496f3bf1"}}, - {name = "kiwisolver-1.5.0-cp313-cp313t-manylinux_2_39_riscv64.whl",url = "https://files.pythonhosted.org/packages/d5/d1/c6078b5756670658e9192a2ef11e939c92918833d2745f85cd14a6004bdf/kiwisolver-1.5.0-cp313-cp313t-manylinux_2_39_riscv64.whl",hashes = {sha256 = "89fc958c702ee9a745e4700378f5d23fddbc46ff89e8fdbf5395c24d5c1452a3"}}, - {name = "kiwisolver-1.5.0-cp313-cp313t-musllinux_1_2_aarch64.whl",url = "https://files.pythonhosted.org/packages/cb/c8/7def6ddf16eb2b3741d8b172bdaa9af882b03c78e9b0772975408801fa63/kiwisolver-1.5.0-cp313-cp313t-musllinux_1_2_aarch64.whl",hashes = {sha256 = "9027d773c4ff81487181a925945743413f6069634d0b122d0b37684ccf4f1e18"}}, - {name = "kiwisolver-1.5.0-cp313-cp313t-musllinux_1_2_ppc64le.whl",url = "https://files.pythonhosted.org/packages/9e/87/2ac1fce0eb1e616fcd3c35caa23e665e9b1948bb984f4764790924594128/kiwisolver-1.5.0-cp313-cp313t-musllinux_1_2_ppc64le.whl",hashes = {sha256 = "5b233ea3e165e43e35dba1d2b8ecc21cf070b45b65ae17dd2747d2713d942021"}}, - {name = "kiwisolver-1.5.0-cp313-cp313t-musllinux_1_2_riscv64.whl",url = "https://files.pythonhosted.org/packages/67/13/c6700ccc6cc218716bfcda4935e4b2997039869b4ad8a94f364c5a3b8e63/kiwisolver-1.5.0-cp313-cp313t-musllinux_1_2_riscv64.whl",hashes = {sha256 = "ce9bf03dad3b46408c08649c6fbd6ca28a9fce0eb32fdfffa6775a13103b5310"}}, - {name = "kiwisolver-1.5.0-cp313-cp313t-musllinux_1_2_s390x.whl",url = "https://files.pythonhosted.org/packages/1b/bd/877056304626943ff0f1f44c08f584300c199b887cb3176cd7e34f1515f1/kiwisolver-1.5.0-cp313-cp313t-musllinux_1_2_s390x.whl",hashes = {sha256 = "fc4d3f1fb9ca0ae9f97b095963bc6326f1dbfd3779d6679a1e016b9baaa153d3"}}, - {name = "kiwisolver-1.5.0-cp313-cp313t-musllinux_1_2_x86_64.whl",url = "https://files.pythonhosted.org/packages/75/19/c60626c47bf0f8ac5dcf72c6c98e266d714f2fbbfd50cf6dab5ede3aaa50/kiwisolver-1.5.0-cp313-cp313t-musllinux_1_2_x86_64.whl",hashes = {sha256 = "f443b4825c50a51ee68585522ab4a1d1257fac65896f282b4c6763337ac9f5d2"}}, - {name = "kiwisolver-1.5.0-cp313-cp313t-win_arm64.whl",url = "https://files.pythonhosted.org/packages/47/84/6a6d5e5bb8273756c27b7d810d47f7ef2f1f9b9fd23c9ee9a3f8c75c9cef/kiwisolver-1.5.0-cp313-cp313t-win_arm64.whl",hashes = {sha256 = "893ff3a711d1b515ba9da14ee090519bad4610ed1962fbe298a434e8c5f8db53"}}, - {name = "kiwisolver-1.5.0-cp312-cp312-macosx_10_13_universal2.whl",url = "https://files.pythonhosted.org/packages/4d/b2/818b74ebea34dabe6d0c51cb1c572e046730e64844da6ed646d5298c40ce/kiwisolver-1.5.0-cp312-cp312-macosx_10_13_universal2.whl",hashes = {sha256 = "4e9750bc21b886308024f8a54ccb9a2cc38ac9fa813bf4348434e3d54f337ff9"}}, - {name = "kiwisolver-1.5.0-cp312-cp312-macosx_10_13_x86_64.whl",url = "https://files.pythonhosted.org/packages/bf/d9/405320f8077e8e1c5c4bd6adc45e1e6edf6d727b6da7f2e2533cf58bff71/kiwisolver-1.5.0-cp312-cp312-macosx_10_13_x86_64.whl",hashes = {sha256 = "72ec46b7eba5b395e0a7b63025490d3214c11013f4aacb4f5e8d6c3041829588"}}, - {name = "kiwisolver-1.5.0-cp312-cp312-macosx_11_0_arm64.whl",url = "https://files.pythonhosted.org/packages/99/9f/795fedf35634f746151ca8839d05681ceb6287fbed6cc1c9bf235f7887c2/kiwisolver-1.5.0-cp312-cp312-macosx_11_0_arm64.whl",hashes = {sha256 = "ed3a984b31da7481b103f68776f7128a89ef26ed40f4dc41a2223cda7fb24819"}}, - {name = "kiwisolver-1.5.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl",url = "https://files.pythonhosted.org/packages/c4/13/680c54afe3e65767bed7ec1a15571e1a2f1257128733851ade24abcefbcc/kiwisolver-1.5.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl",hashes = {sha256 = "bb5136fb5352d3f422df33f0c879a1b0c204004324150cc3b5e3c4f310c9049f"}}, - {name = "kiwisolver-1.5.0-cp312-cp312-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl",url = "https://files.pythonhosted.org/packages/c8/2f/cebfcdb60fd6a9b0f6b47a9337198bcbad6fbe15e68189b7011fd914911f/kiwisolver-1.5.0-cp312-cp312-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl",hashes = {sha256 = "b2af221f268f5af85e776a73d62b0845fc8baf8ef0abfae79d29c77d0e776aaf"}}, - {name = "kiwisolver-1.5.0-cp312-cp312-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl",url = "https://files.pythonhosted.org/packages/f2/0d/9b782923aada3fafb1d6b84e13121954515c669b18af0c26e7d21f579855/kiwisolver-1.5.0-cp312-cp312-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl",hashes = {sha256 = "b0f172dc8ffaccb8522d7c5d899de00133f2f1ca7b0a49b7da98e901de87bf2d"}}, - {name = "kiwisolver-1.5.0-cp312-cp312-manylinux_2_24_s390x.manylinux_2_28_s390x.whl",url = "https://files.pythonhosted.org/packages/27/70/83241b6634b04fe44e892688d5208332bde130f38e610c0418f9ede47ded/kiwisolver-1.5.0-cp312-cp312-manylinux_2_24_s390x.manylinux_2_28_s390x.whl",hashes = {sha256 = "6ab8ba9152203feec73758dad83af9a0bbe05001eb4639e547207c40cfb52083"}}, - {name = "kiwisolver-1.5.0-cp312-cp312-manylinux_2_39_riscv64.whl",url = "https://files.pythonhosted.org/packages/e4/db/30ed226fb271ae1a6431fc0fe0edffb2efe23cadb01e798caeb9f2ceae8f/kiwisolver-1.5.0-cp312-cp312-manylinux_2_39_riscv64.whl",hashes = {sha256 = "cdee07c4d7f6d72008d3f73b9bf027f4e11550224c7c50d8df1ae4a37c1402a6"}}, - {name = "kiwisolver-1.5.0-cp312-cp312-musllinux_1_2_aarch64.whl",url = "https://files.pythonhosted.org/packages/ec/bd/c314595208e4c9587652d50959ead9e461995389664e490f4dce7ff0f782/kiwisolver-1.5.0-cp312-cp312-musllinux_1_2_aarch64.whl",hashes = {sha256 = "7c60d3c9b06fb23bd9c6139281ccbdc384297579ae037f08ae90c69f6845c0b1"}}, - {name = "kiwisolver-1.5.0-cp312-cp312-musllinux_1_2_ppc64le.whl",url = "https://files.pythonhosted.org/packages/c1/43/0499cec932d935229b5543d073c2b87c9c22846aab48881e9d8d6e742a2d/kiwisolver-1.5.0-cp312-cp312-musllinux_1_2_ppc64le.whl",hashes = {sha256 = "e315e5ec90d88e140f57696ff85b484ff68bb311e36f2c414aa4286293e6dee0"}}, - {name = "kiwisolver-1.5.0-cp312-cp312-musllinux_1_2_riscv64.whl",url = "https://files.pythonhosted.org/packages/3d/6f/79b0d760907965acfd9d61826a3d41f8f093c538f55cd2633d3f0db269f6/kiwisolver-1.5.0-cp312-cp312-musllinux_1_2_riscv64.whl",hashes = {sha256 = "1465387ac63576c3e125e5337a6892b9e99e0627d52317f3ca79e6930d889d15"}}, - {name = "kiwisolver-1.5.0-cp312-cp312-musllinux_1_2_s390x.whl",url = "https://files.pythonhosted.org/packages/ab/31/01d0537c41cb75a551a438c3c7a80d0c60d60b81f694dac83dd436aec0d0/kiwisolver-1.5.0-cp312-cp312-musllinux_1_2_s390x.whl",hashes = {sha256 = "530a3fd64c87cffa844d4b6b9768774763d9caa299e9b75d8eca6a4423b31314"}}, - {name = "kiwisolver-1.5.0-cp312-cp312-musllinux_1_2_x86_64.whl",url = "https://files.pythonhosted.org/packages/e4/34/8aefdd0be9cfd00a44509251ba864f5caf2991e36772e61c408007e7f417/kiwisolver-1.5.0-cp312-cp312-musllinux_1_2_x86_64.whl",hashes = {sha256 = "1d9daea4ea6b9be74fe2f01f7fbade8d6ffab263e781274cffca0dba9be9eec9"}}, - {name = "kiwisolver-1.5.0-cp312-cp312-win_amd64.whl",url = "https://files.pythonhosted.org/packages/ad/cf/0348374369ca588f8fe9c338fae49fa4e16eeb10ffb3d012f23a54578a9e/kiwisolver-1.5.0-cp312-cp312-win_amd64.whl",hashes = {sha256 = "f18c2d9782259a6dc132fdc7a63c168cbc74b35284b6d75c673958982a378384"}}, - {name = "kiwisolver-1.5.0-cp312-cp312-win_arm64.whl",url = "https://files.pythonhosted.org/packages/28/26/192b26196e2316e2bd29deef67e37cdf9870d9af8e085e521afff0fed526/kiwisolver-1.5.0-cp312-cp312-win_arm64.whl",hashes = {sha256 = "f7c7553b13f69c1b29a5bde08ddc6d9d0c8bfb84f9ed01c30db25944aeb852a7"}}, - {name = "kiwisolver-1.5.0-cp311-cp311-macosx_10_9_universal2.whl",url = "https://files.pythonhosted.org/packages/12/dd/a495a9c104be1c476f0386e714252caf2b7eca883915422a64c50b88c6f5/kiwisolver-1.5.0-cp311-cp311-macosx_10_9_universal2.whl",hashes = {sha256 = "9eed0f7edbb274413b6ee781cca50541c8c0facd3d6fd289779e494340a2b85c"}}, - {name = "kiwisolver-1.5.0-cp311-cp311-macosx_10_9_x86_64.whl",url = "https://files.pythonhosted.org/packages/11/60/37b4047a2af0cf5ef6d8b4b26e91829ae6fc6a2d1f74524bcb0e7cd28a32/kiwisolver-1.5.0-cp311-cp311-macosx_10_9_x86_64.whl",hashes = {sha256 = "3c4923e404d6bcd91b6779c009542e5647fef32e4a5d75e115e3bbac6f2335eb"}}, - {name = "kiwisolver-1.5.0-cp311-cp311-macosx_11_0_arm64.whl",url = "https://files.pythonhosted.org/packages/0a/aa/510dc933d87767584abfe03efa445889996c70c2990f6f87c3ebaa0a18c5/kiwisolver-1.5.0-cp311-cp311-macosx_11_0_arm64.whl",hashes = {sha256 = "0df54df7e686afa55e6f21fb86195224a6d9beb71d637e8d7920c95cf0f89aac"}}, - {name = "kiwisolver-1.5.0-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl",url = "https://files.pythonhosted.org/packages/80/46/bddc13df6c2a40741e0cc7865bb1c9ed4796b6760bd04ce5fae3928ef917/kiwisolver-1.5.0-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl",hashes = {sha256 = "2517e24d7315eb51c10664cdb865195df38ab74456c677df67bb47f12d088a27"}}, - {name = "kiwisolver-1.5.0-cp311-cp311-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl",url = "https://files.pythonhosted.org/packages/fd/d6/76621246f5165e5372f02f5e6f3f48ea336a8f9e96e43997d45b240ed8cd/kiwisolver-1.5.0-cp311-cp311-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl",hashes = {sha256 = "ff710414307fefa903e0d9bdf300972f892c23477829f49504e59834f4195398"}}, - {name = "kiwisolver-1.5.0-cp311-cp311-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl",url = "https://files.pythonhosted.org/packages/b2/c1/31559ec6fb39a5b48035ce29bb63ade628f321785f38c384dee3e2c08bc1/kiwisolver-1.5.0-cp311-cp311-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl",hashes = {sha256 = "6176c1811d9d5a04fa391c490cc44f451e240697a16977f11c6f722efb9041db"}}, - {name = "kiwisolver-1.5.0-cp311-cp311-manylinux_2_24_s390x.manylinux_2_28_s390x.whl",url = "https://files.pythonhosted.org/packages/5e/ef/1cb8276f2d29cc6a41e0a042f27946ca347d3a4a75acf85d0a16aa6dcc82/kiwisolver-1.5.0-cp311-cp311-manylinux_2_24_s390x.manylinux_2_28_s390x.whl",hashes = {sha256 = "50847dca5d197fcbd389c805aa1a1cf32f25d2e7273dc47ab181a517666b68cc"}}, - {name = "kiwisolver-1.5.0-cp311-cp311-manylinux_2_39_riscv64.whl",url = "https://files.pythonhosted.org/packages/4c/e4/5ba3cecd7ce6236ae4a80f67e5d5531287337d0e1f076ca87a5abe4cd5d0/kiwisolver-1.5.0-cp311-cp311-manylinux_2_39_riscv64.whl",hashes = {sha256 = "01808c6d15f4c3e8559595d6d1fe6411c68e4a3822b4b9972b44473b24f4e679"}}, - {name = "kiwisolver-1.5.0-cp311-cp311-musllinux_1_2_aarch64.whl",url = "https://files.pythonhosted.org/packages/5a/69/dc61f7ae9a2f071f26004ced87f078235b5507ab6e5acd78f40365655034/kiwisolver-1.5.0-cp311-cp311-musllinux_1_2_aarch64.whl",hashes = {sha256 = "f1f9f4121ec58628c96baa3de1a55a4e3a333c5102c8e94b64e23bf7b2083309"}}, - {name = "kiwisolver-1.5.0-cp311-cp311-musllinux_1_2_ppc64le.whl",url = "https://files.pythonhosted.org/packages/e5/7b/abbe0f1b5afa85f8d084b73e90e5f801c0939eba16ac2e49af7c61a6c28d/kiwisolver-1.5.0-cp311-cp311-musllinux_1_2_ppc64le.whl",hashes = {sha256 = "b7d335370ae48a780c6e6a6bbfa97342f563744c39c35562f3f367665f5c1de2"}}, - {name = "kiwisolver-1.5.0-cp311-cp311-musllinux_1_2_riscv64.whl",url = "https://files.pythonhosted.org/packages/8a/80/5908ae149d96d81580d604c7f8aefd0e98f4fd728cf172f477e9f2a81744/kiwisolver-1.5.0-cp311-cp311-musllinux_1_2_riscv64.whl",hashes = {sha256 = "800ee55980c18545af444d93fdd60c56b580db5cc54867d8cbf8a1dc0829938c"}}, - {name = "kiwisolver-1.5.0-cp311-cp311-musllinux_1_2_s390x.whl",url = "https://files.pythonhosted.org/packages/84/08/a78cb776f8c085b7143142ce479859cfec086bd09ee638a317040b6ef420/kiwisolver-1.5.0-cp311-cp311-musllinux_1_2_s390x.whl",hashes = {sha256 = "c438f6ca858697c9ab67eb28246c92508af972e114cac34e57a6d4ba17a3ac08"}}, - {name = "kiwisolver-1.5.0-cp311-cp311-musllinux_1_2_x86_64.whl",url = "https://files.pythonhosted.org/packages/b1/e1/65584da5356ed6cb12c63791a10b208860ac40a83de165cb6a6751a686e3/kiwisolver-1.5.0-cp311-cp311-musllinux_1_2_x86_64.whl",hashes = {sha256 = "8c63c91f95173f9c2a67c7c526b2cea976828a0e7fced9cdcead2802dc10f8a4"}}, - {name = "kiwisolver-1.5.0-cp311-cp311-win_amd64.whl",url = "https://files.pythonhosted.org/packages/be/6c/28f17390b62b8f2f520e2915095b3c94d88681ecf0041e75389d9667f202/kiwisolver-1.5.0-cp311-cp311-win_amd64.whl",hashes = {sha256 = "beb7f344487cdcb9e1efe4b7a29681b74d34c08f0043a327a74da852a6749e7b"}}, - {name = "kiwisolver-1.5.0-cp311-cp311-win_arm64.whl",url = "https://files.pythonhosted.org/packages/d8/0e/2ee5debc4f77a625778fec5501ff3e8036fe361b7ee28ae402a485bb9694/kiwisolver-1.5.0-cp311-cp311-win_arm64.whl",hashes = {sha256 = "ad4ae4ffd1ee9cd11357b4c66b612da9888f4f4daf2f36995eda64bd45370cac"}}, - {name = "kiwisolver-1.5.0-pp311-pypy311_pp73-macosx_10_15_x86_64.whl",url = "https://files.pythonhosted.org/packages/e9/eb/5fcbbbf9a0e2c3a35effb88831a483345326bbc3a030a3b5b69aee647f84/kiwisolver-1.5.0-pp311-pypy311_pp73-macosx_10_15_x86_64.whl",hashes = {sha256 = "ec4c85dc4b687c7f7f15f553ff26a98bfe8c58f5f7f0ac8905f0ba4c7be60232"}}, - {name = "kiwisolver-1.5.0-pp311-pypy311_pp73-macosx_11_0_arm64.whl",url = "https://files.pythonhosted.org/packages/c3/9b/e17104555bb4db148fd52327feea1e96be4b88e8e008b029002c281a21ab/kiwisolver-1.5.0-pp311-pypy311_pp73-macosx_11_0_arm64.whl",hashes = {sha256 = "12e91c215a96e39f57989c8912ae761286ac5a9584d04030ceb3368a357f017a"}}, - {name = "kiwisolver-1.5.0-pp311-pypy311_pp73-manylinux2014_x86_64.manylinux_2_17_x86_64.whl",url = "https://files.pythonhosted.org/packages/48/44/2b5b95b7aa39fb2d8d9d956e0f3d5d45aef2ae1d942d4c3ffac2f9cfed1a/kiwisolver-1.5.0-pp311-pypy311_pp73-manylinux2014_x86_64.manylinux_2_17_x86_64.whl",hashes = {sha256 = "be4a51a55833dc29ab5d7503e7bcb3b3af3402d266018137127450005cdfe737"}}, - {name = "kiwisolver-1.5.0-pp311-pypy311_pp73-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl",url = "https://files.pythonhosted.org/packages/52/7d/7157f9bba6b455cfb4632ed411e199fc8b8977642c2b12082e1bd9e6d173/kiwisolver-1.5.0-pp311-pypy311_pp73-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl",hashes = {sha256 = "daae526907e262de627d8f70058a0f64acc9e2641c164c99c8f594b34a799a16"}}, - {name = "kiwisolver-1.5.0-pp311-pypy311_pp73-win_amd64.whl",url = "https://files.pythonhosted.org/packages/0a/dd/8050c947d435c8d4bc94e3252f4d8bb8a76cfb424f043a8680be637a57f1/kiwisolver-1.5.0-pp311-pypy311_pp73-win_amd64.whl",hashes = {sha256 = "59cd8683f575d96df5bb48f6add94afc055012c29e28124fcae2b63661b9efb1"}}, -] -marker = "\"default\" in dependency_groups or \"docs\" in extras" - -[packages.tool.pdm] -dependencies = [] - -[[packages]] -name = "lifelines" -version = "0.30.0" -requires-python = ">=3.9" -sdist = {name = "lifelines-0.30.0.tar.gz", url = "https://files.pythonhosted.org/packages/ea/4f/f0b363278d40baf7d7a03217bee839cb880946c62109f243391c8754bb09/lifelines-0.30.0.tar.gz", hashes = {sha256 = "f7f6f6275fcb167fe0f5b1ef98f868993f9c074cb74b1dd6e92736efa854be18"}} -wheels = [ - {name = "lifelines-0.30.0-py3-none-any.whl",url = "https://files.pythonhosted.org/packages/14/f7/379e185a75ac8166ac70756d0ba68d9a2b02b555c7fde4983246752396bd/lifelines-0.30.0-py3-none-any.whl",hashes = {sha256 = "ac7c602c8aceced9770d3977817c9d99c250ed8cd86f2567fa0d23e4e8014bf9"}}, -] -marker = "\"default\" in dependency_groups" - -[packages.tool.pdm] -dependencies = [ - "autograd-gamma>=0.3", - "autograd>=1.5", - "formulaic>=0.2.2", - "matplotlib>=3.0", - "numpy>=1.14.0", - "pandas>=2.1", - "scipy>=1.7.0", -] - -[[packages]] -name = "markdown-it-py" -version = "4.0.0" -requires-python = ">=3.10" -sdist = {name = "markdown_it_py-4.0.0.tar.gz", url = "https://files.pythonhosted.org/packages/5b/f5/4ec618ed16cc4f8fb3b701563655a69816155e79e24a17b651541804721d/markdown_it_py-4.0.0.tar.gz", hashes = {sha256 = "cb0a2b4aa34f932c007117b194e945bd74e0ec24133ceb5bac59009cda1cb9f3"}} -wheels = [ - {name = "markdown_it_py-4.0.0-py3-none-any.whl",url = "https://files.pythonhosted.org/packages/94/54/e7d793b573f298e1c9013b8c4dade17d481164aa517d1d7148619c2cedbf/markdown_it_py-4.0.0-py3-none-any.whl",hashes = {sha256 = "87327c59b172c5011896038353a81343b6754500a08cd7a4973bb48c6d578147"}}, -] -marker = "\"docs\" in extras" - -[packages.tool.pdm] -dependencies = [ - "mdurl~=0.1", -] - -[[packages]] -name = "markupsafe" -version = "3.0.3" -requires-python = ">=3.9" -sdist = {name = "markupsafe-3.0.3.tar.gz", url = "https://files.pythonhosted.org/packages/7e/99/7690b6d4034fffd95959cbe0c02de8deb3098cc577c67bb6a24fe5d7caa7/markupsafe-3.0.3.tar.gz", hashes = {sha256 = "722695808f4b6457b320fdc131280796bdceb04ab50fe1795cd540799ebe1698"}} -wheels = [ - {name = "markupsafe-3.0.3-cp314-cp314-macosx_10_13_x86_64.whl",url = "https://files.pythonhosted.org/packages/33/8a/8e42d4838cd89b7dde187011e97fe6c3af66d8c044997d2183fbd6d31352/markupsafe-3.0.3-cp314-cp314-macosx_10_13_x86_64.whl",hashes = {sha256 = "eaa9599de571d72e2daf60164784109f19978b327a3910d3e9de8c97b5b70cfe"}}, - {name = "markupsafe-3.0.3-cp314-cp314-macosx_11_0_arm64.whl",url = "https://files.pythonhosted.org/packages/b5/64/7660f8a4a8e53c924d0fa05dc3a55c9cee10bbd82b11c5afb27d44b096ce/markupsafe-3.0.3-cp314-cp314-macosx_11_0_arm64.whl",hashes = {sha256 = "c47a551199eb8eb2121d4f0f15ae0f923d31350ab9280078d1e5f12b249e0026"}}, - {name = "markupsafe-3.0.3-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl",url = "https://files.pythonhosted.org/packages/da/ef/e648bfd021127bef5fa12e1720ffed0c6cbb8310c8d9bea7266337ff06de/markupsafe-3.0.3-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl",hashes = {sha256 = "f34c41761022dd093b4b6896d4810782ffbabe30f2d443ff5f083e0cbbb8c737"}}, - {name = "markupsafe-3.0.3-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl",url = "https://files.pythonhosted.org/packages/41/3c/a36c2450754618e62008bf7435ccb0f88053e07592e6028a34776213d877/markupsafe-3.0.3-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl",hashes = {sha256 = "457a69a9577064c05a97c41f4e65148652db078a3a509039e64d3467b9e7ef97"}}, - {name = "markupsafe-3.0.3-cp314-cp314-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl",url = "https://files.pythonhosted.org/packages/bc/20/b7fdf89a8456b099837cd1dc21974632a02a999ec9bf7ca3e490aacd98e7/markupsafe-3.0.3-cp314-cp314-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl",hashes = {sha256 = "e8afc3f2ccfa24215f8cb28dcf43f0113ac3c37c2f0f0806d8c70e4228c5cf4d"}}, - {name = "markupsafe-3.0.3-cp314-cp314-musllinux_1_2_aarch64.whl",url = "https://files.pythonhosted.org/packages/9a/a7/591f592afdc734f47db08a75793a55d7fbcc6902a723ae4cfbab61010cc5/markupsafe-3.0.3-cp314-cp314-musllinux_1_2_aarch64.whl",hashes = {sha256 = "ec15a59cf5af7be74194f7ab02d0f59a62bdcf1a537677ce67a2537c9b87fcda"}}, - {name = "markupsafe-3.0.3-cp314-cp314-musllinux_1_2_riscv64.whl",url = "https://files.pythonhosted.org/packages/7d/33/45b24e4f44195b26521bc6f1a82197118f74df348556594bd2262bda1038/markupsafe-3.0.3-cp314-cp314-musllinux_1_2_riscv64.whl",hashes = {sha256 = "0eb9ff8191e8498cca014656ae6b8d61f39da5f95b488805da4bb029cccbfbaf"}}, - {name = "markupsafe-3.0.3-cp314-cp314-musllinux_1_2_x86_64.whl",url = "https://files.pythonhosted.org/packages/ff/0e/53dfaca23a69fbfbbf17a4b64072090e70717344c52eaaaa9c5ddff1e5f0/markupsafe-3.0.3-cp314-cp314-musllinux_1_2_x86_64.whl",hashes = {sha256 = "2713baf880df847f2bece4230d4d094280f4e67b1e813eec43b4c0e144a34ffe"}}, - {name = "markupsafe-3.0.3-cp314-cp314-win32.whl",url = "https://files.pythonhosted.org/packages/46/11/f333a06fc16236d5238bfe74daccbca41459dcd8d1fa952e8fbd5dccfb70/markupsafe-3.0.3-cp314-cp314-win32.whl",hashes = {sha256 = "729586769a26dbceff69f7a7dbbf59ab6572b99d94576a5592625d5b411576b9"}}, - {name = "markupsafe-3.0.3-cp314-cp314-win_amd64.whl",url = "https://files.pythonhosted.org/packages/28/52/182836104b33b444e400b14f797212f720cbc9ed6ba34c800639d154e821/markupsafe-3.0.3-cp314-cp314-win_amd64.whl",hashes = {sha256 = "bdc919ead48f234740ad807933cdf545180bfbe9342c2bb451556db2ed958581"}}, - {name = "markupsafe-3.0.3-cp314-cp314-win_arm64.whl",url = "https://files.pythonhosted.org/packages/6f/18/acf23e91bd94fd7b3031558b1f013adfa21a8e407a3fdb32745538730382/markupsafe-3.0.3-cp314-cp314-win_arm64.whl",hashes = {sha256 = "5a7d5dc5140555cf21a6fefbdbf8723f06fcd2f63ef108f2854de715e4422cb4"}}, - {name = "markupsafe-3.0.3-cp314-cp314t-macosx_10_13_x86_64.whl",url = "https://files.pythonhosted.org/packages/3c/f0/57689aa4076e1b43b15fdfa646b04653969d50cf30c32a102762be2485da/markupsafe-3.0.3-cp314-cp314t-macosx_10_13_x86_64.whl",hashes = {sha256 = "1353ef0c1b138e1907ae78e2f6c63ff67501122006b0f9abad68fda5f4ffc6ab"}}, - {name = "markupsafe-3.0.3-cp314-cp314t-macosx_11_0_arm64.whl",url = "https://files.pythonhosted.org/packages/89/c3/2e67a7ca217c6912985ec766c6393b636fb0c2344443ff9d91404dc4c79f/markupsafe-3.0.3-cp314-cp314t-macosx_11_0_arm64.whl",hashes = {sha256 = "1085e7fbddd3be5f89cc898938f42c0b3c711fdcb37d75221de2666af647c175"}}, - {name = "markupsafe-3.0.3-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl",url = "https://files.pythonhosted.org/packages/f0/00/be561dce4e6ca66b15276e184ce4b8aec61fe83662cce2f7d72bd3249d28/markupsafe-3.0.3-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl",hashes = {sha256 = "1b52b4fb9df4eb9ae465f8d0c228a00624de2334f216f178a995ccdcf82c4634"}}, - {name = "markupsafe-3.0.3-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl",url = "https://files.pythonhosted.org/packages/50/09/c419f6f5a92e5fadde27efd190eca90f05e1261b10dbd8cbcb39cd8ea1dc/markupsafe-3.0.3-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl",hashes = {sha256 = "fed51ac40f757d41b7c48425901843666a6677e3e8eb0abcff09e4ba6e664f50"}}, - {name = "markupsafe-3.0.3-cp314-cp314t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl",url = "https://files.pythonhosted.org/packages/22/44/a0681611106e0b2921b3033fc19bc53323e0b50bc70cffdd19f7d679bb66/markupsafe-3.0.3-cp314-cp314t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl",hashes = {sha256 = "f190daf01f13c72eac4efd5c430a8de82489d9cff23c364c3ea822545032993e"}}, - {name = "markupsafe-3.0.3-cp314-cp314t-musllinux_1_2_aarch64.whl",url = "https://files.pythonhosted.org/packages/5f/57/1b0b3f100259dc9fffe780cfb60d4be71375510e435efec3d116b6436d43/markupsafe-3.0.3-cp314-cp314t-musllinux_1_2_aarch64.whl",hashes = {sha256 = "e56b7d45a839a697b5eb268c82a71bd8c7f6c94d6fd50c3d577fa39a9f1409f5"}}, - {name = "markupsafe-3.0.3-cp314-cp314t-musllinux_1_2_riscv64.whl",url = "https://files.pythonhosted.org/packages/26/6a/4bf6d0c97c4920f1597cc14dd720705eca0bf7c787aebc6bb4d1bead5388/markupsafe-3.0.3-cp314-cp314t-musllinux_1_2_riscv64.whl",hashes = {sha256 = "f3e98bb3798ead92273dc0e5fd0f31ade220f59a266ffd8a4f6065e0a3ce0523"}}, - {name = "markupsafe-3.0.3-cp314-cp314t-musllinux_1_2_x86_64.whl",url = "https://files.pythonhosted.org/packages/14/c7/ca723101509b518797fedc2fdf79ba57f886b4aca8a7d31857ba3ee8281f/markupsafe-3.0.3-cp314-cp314t-musllinux_1_2_x86_64.whl",hashes = {sha256 = "5678211cb9333a6468fb8d8be0305520aa073f50d17f089b5b4b477ea6e67fdc"}}, - {name = "markupsafe-3.0.3-cp314-cp314t-win32.whl",url = "https://files.pythonhosted.org/packages/fb/df/5bd7a48c256faecd1d36edc13133e51397e41b73bb77e1a69deab746ebac/markupsafe-3.0.3-cp314-cp314t-win32.whl",hashes = {sha256 = "915c04ba3851909ce68ccc2b8e2cd691618c4dc4c4232fb7982bca3f41fd8c3d"}}, - {name = "markupsafe-3.0.3-cp314-cp314t-win_amd64.whl",url = "https://files.pythonhosted.org/packages/1a/8a/0402ba61a2f16038b48b39bccca271134be00c5c9f0f623208399333c448/markupsafe-3.0.3-cp314-cp314t-win_amd64.whl",hashes = {sha256 = "4faffd047e07c38848ce017e8725090413cd80cbc23d86e55c587bf979e579c9"}}, - {name = "markupsafe-3.0.3-cp314-cp314t-win_arm64.whl",url = "https://files.pythonhosted.org/packages/70/bc/6f1c2f612465f5fa89b95bead1f44dcb607670fd42891d8fdcd5d039f4f4/markupsafe-3.0.3-cp314-cp314t-win_arm64.whl",hashes = {sha256 = "32001d6a8fc98c8cb5c947787c5d08b0a50663d139f1305bac5885d98d9b40fa"}}, - {name = "markupsafe-3.0.3-cp313-cp313-macosx_10_13_x86_64.whl",url = "https://files.pythonhosted.org/packages/38/2f/907b9c7bbba283e68f20259574b13d005c121a0fa4c175f9bed27c4597ff/markupsafe-3.0.3-cp313-cp313-macosx_10_13_x86_64.whl",hashes = {sha256 = "e1cf1972137e83c5d4c136c43ced9ac51d0e124706ee1c8aa8532c1287fa8795"}}, - {name = "markupsafe-3.0.3-cp313-cp313-macosx_11_0_arm64.whl",url = "https://files.pythonhosted.org/packages/9c/d9/5f7756922cdd676869eca1c4e3c0cd0df60ed30199ffd775e319089cb3ed/markupsafe-3.0.3-cp313-cp313-macosx_11_0_arm64.whl",hashes = {sha256 = "116bb52f642a37c115f517494ea5feb03889e04df47eeff5b130b1808ce7c219"}}, - {name = "markupsafe-3.0.3-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl",url = "https://files.pythonhosted.org/packages/00/07/575a68c754943058c78f30db02ee03a64b3c638586fba6a6dd56830b30a3/markupsafe-3.0.3-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl",hashes = {sha256 = "133a43e73a802c5562be9bbcd03d090aa5a1fe899db609c29e8c8d815c5f6de6"}}, - {name = "markupsafe-3.0.3-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl",url = "https://files.pythonhosted.org/packages/a9/21/9b05698b46f218fc0e118e1f8168395c65c8a2c750ae2bab54fc4bd4e0e8/markupsafe-3.0.3-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl",hashes = {sha256 = "ccfcd093f13f0f0b7fdd0f198b90053bf7b2f02a3927a30e63f3ccc9df56b676"}}, - {name = "markupsafe-3.0.3-cp313-cp313-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl",url = "https://files.pythonhosted.org/packages/7f/71/544260864f893f18b6827315b988c146b559391e6e7e8f7252839b1b846a/markupsafe-3.0.3-cp313-cp313-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl",hashes = {sha256 = "509fa21c6deb7a7a273d629cf5ec029bc209d1a51178615ddf718f5918992ab9"}}, - {name = "markupsafe-3.0.3-cp313-cp313-musllinux_1_2_aarch64.whl",url = "https://files.pythonhosted.org/packages/c2/28/b50fc2f74d1ad761af2f5dcce7492648b983d00a65b8c0e0cb457c82ebbe/markupsafe-3.0.3-cp313-cp313-musllinux_1_2_aarch64.whl",hashes = {sha256 = "a4afe79fb3de0b7097d81da19090f4df4f8d3a2b3adaa8764138aac2e44f3af1"}}, - {name = "markupsafe-3.0.3-cp313-cp313-musllinux_1_2_riscv64.whl",url = "https://files.pythonhosted.org/packages/ed/76/104b2aa106a208da8b17a2fb72e033a5a9d7073c68f7e508b94916ed47a9/markupsafe-3.0.3-cp313-cp313-musllinux_1_2_riscv64.whl",hashes = {sha256 = "795e7751525cae078558e679d646ae45574b47ed6e7771863fcc079a6171a0fc"}}, - {name = "markupsafe-3.0.3-cp313-cp313-musllinux_1_2_x86_64.whl",url = "https://files.pythonhosted.org/packages/b5/99/16a5eb2d140087ebd97180d95249b00a03aa87e29cc224056274f2e45fd6/markupsafe-3.0.3-cp313-cp313-musllinux_1_2_x86_64.whl",hashes = {sha256 = "8485f406a96febb5140bfeca44a73e3ce5116b2501ac54fe953e488fb1d03b12"}}, - {name = "markupsafe-3.0.3-cp313-cp313-win32.whl",url = "https://files.pythonhosted.org/packages/19/bc/e7140ed90c5d61d77cea142eed9f9c303f4c4806f60a1044c13e3f1471d0/markupsafe-3.0.3-cp313-cp313-win32.whl",hashes = {sha256 = "bdd37121970bfd8be76c5fb069c7751683bdf373db1ed6c010162b2a130248ed"}}, - {name = "markupsafe-3.0.3-cp313-cp313-win_amd64.whl",url = "https://files.pythonhosted.org/packages/05/73/c4abe620b841b6b791f2edc248f556900667a5a1cf023a6646967ae98335/markupsafe-3.0.3-cp313-cp313-win_amd64.whl",hashes = {sha256 = "9a1abfdc021a164803f4d485104931fb8f8c1efd55bc6b748d2f5774e78b62c5"}}, - {name = "markupsafe-3.0.3-cp313-cp313-win_arm64.whl",url = "https://files.pythonhosted.org/packages/f0/3a/fa34a0f7cfef23cf9500d68cb7c32dd64ffd58a12b09225fb03dd37d5b80/markupsafe-3.0.3-cp313-cp313-win_arm64.whl",hashes = {sha256 = "7e68f88e5b8799aa49c85cd116c932a1ac15caaa3f5db09087854d218359e485"}}, - {name = "markupsafe-3.0.3-cp313-cp313t-macosx_10_13_x86_64.whl",url = "https://files.pythonhosted.org/packages/e4/d7/e05cd7efe43a88a17a37b3ae96e79a19e846f3f456fe79c57ca61356ef01/markupsafe-3.0.3-cp313-cp313t-macosx_10_13_x86_64.whl",hashes = {sha256 = "218551f6df4868a8d527e3062d0fb968682fe92054e89978594c28e642c43a73"}}, - {name = "markupsafe-3.0.3-cp313-cp313t-macosx_11_0_arm64.whl",url = "https://files.pythonhosted.org/packages/99/9e/e412117548182ce2148bdeacdda3bb494260c0b0184360fe0d56389b523b/markupsafe-3.0.3-cp313-cp313t-macosx_11_0_arm64.whl",hashes = {sha256 = "3524b778fe5cfb3452a09d31e7b5adefeea8c5be1d43c4f810ba09f2ceb29d37"}}, - {name = "markupsafe-3.0.3-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl",url = "https://files.pythonhosted.org/packages/bc/e6/fa0ffcda717ef64a5108eaa7b4f5ed28d56122c9a6d70ab8b72f9f715c80/markupsafe-3.0.3-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl",hashes = {sha256 = "4e885a3d1efa2eadc93c894a21770e4bc67899e3543680313b09f139e149ab19"}}, - {name = "markupsafe-3.0.3-cp313-cp313t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl",url = "https://files.pythonhosted.org/packages/96/ec/2102e881fe9d25fc16cb4b25d5f5cde50970967ffa5dddafdb771237062d/markupsafe-3.0.3-cp313-cp313t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl",hashes = {sha256 = "8709b08f4a89aa7586de0aadc8da56180242ee0ada3999749b183aa23df95025"}}, - {name = "markupsafe-3.0.3-cp313-cp313t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl",url = "https://files.pythonhosted.org/packages/4b/30/6f2fce1f1f205fc9323255b216ca8a235b15860c34b6798f810f05828e32/markupsafe-3.0.3-cp313-cp313t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl",hashes = {sha256 = "b8512a91625c9b3da6f127803b166b629725e68af71f8184ae7e7d54686a56d6"}}, - {name = "markupsafe-3.0.3-cp313-cp313t-musllinux_1_2_aarch64.whl",url = "https://files.pythonhosted.org/packages/58/47/4a0ccea4ab9f5dcb6f79c0236d954acb382202721e704223a8aafa38b5c8/markupsafe-3.0.3-cp313-cp313t-musllinux_1_2_aarch64.whl",hashes = {sha256 = "9b79b7a16f7fedff2495d684f2b59b0457c3b493778c9eed31111be64d58279f"}}, - {name = "markupsafe-3.0.3-cp313-cp313t-musllinux_1_2_riscv64.whl",url = "https://files.pythonhosted.org/packages/6a/70/3780e9b72180b6fecb83a4814d84c3bf4b4ae4bf0b19c27196104149734c/markupsafe-3.0.3-cp313-cp313t-musllinux_1_2_riscv64.whl",hashes = {sha256 = "12c63dfb4a98206f045aa9563db46507995f7ef6d83b2f68eda65c307c6829eb"}}, - {name = "markupsafe-3.0.3-cp313-cp313t-musllinux_1_2_x86_64.whl",url = "https://files.pythonhosted.org/packages/98/c5/c03c7f4125180fc215220c035beac6b9cb684bc7a067c84fc69414d315f5/markupsafe-3.0.3-cp313-cp313t-musllinux_1_2_x86_64.whl",hashes = {sha256 = "8f71bc33915be5186016f675cd83a1e08523649b0e33efdb898db577ef5bb009"}}, - {name = "markupsafe-3.0.3-cp313-cp313t-win32.whl",url = "https://files.pythonhosted.org/packages/80/d6/2d1b89f6ca4bff1036499b1e29a1d02d282259f3681540e16563f27ebc23/markupsafe-3.0.3-cp313-cp313t-win32.whl",hashes = {sha256 = "69c0b73548bc525c8cb9a251cddf1931d1db4d2258e9599c28c07ef3580ef354"}}, - {name = "markupsafe-3.0.3-cp313-cp313t-win_amd64.whl",url = "https://files.pythonhosted.org/packages/2b/98/e48a4bfba0a0ffcf9925fe2d69240bfaa19c6f7507b8cd09c70684a53c1e/markupsafe-3.0.3-cp313-cp313t-win_amd64.whl",hashes = {sha256 = "1b4b79e8ebf6b55351f0d91fe80f893b4743f104bff22e90697db1590e47a218"}}, - {name = "markupsafe-3.0.3-cp313-cp313t-win_arm64.whl",url = "https://files.pythonhosted.org/packages/0e/72/e3cc540f351f316e9ed0f092757459afbc595824ca724cbc5a5d4263713f/markupsafe-3.0.3-cp313-cp313t-win_arm64.whl",hashes = {sha256 = "ad2cf8aa28b8c020ab2fc8287b0f823d0a7d8630784c31e9ee5edea20f406287"}}, - {name = "markupsafe-3.0.3-cp312-cp312-macosx_10_13_x86_64.whl",url = "https://files.pythonhosted.org/packages/5a/72/147da192e38635ada20e0a2e1a51cf8823d2119ce8883f7053879c2199b5/markupsafe-3.0.3-cp312-cp312-macosx_10_13_x86_64.whl",hashes = {sha256 = "d53197da72cc091b024dd97249dfc7794d6a56530370992a5e1a08983ad9230e"}}, - {name = "markupsafe-3.0.3-cp312-cp312-macosx_11_0_arm64.whl",url = "https://files.pythonhosted.org/packages/9a/81/7e4e08678a1f98521201c3079f77db69fb552acd56067661f8c2f534a718/markupsafe-3.0.3-cp312-cp312-macosx_11_0_arm64.whl",hashes = {sha256 = "1872df69a4de6aead3491198eaf13810b565bdbeec3ae2dc8780f14458ec73ce"}}, - {name = "markupsafe-3.0.3-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl",url = "https://files.pythonhosted.org/packages/1e/2c/799f4742efc39633a1b54a92eec4082e4f815314869865d876824c257c1e/markupsafe-3.0.3-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl",hashes = {sha256 = "3a7e8ae81ae39e62a41ec302f972ba6ae23a5c5396c8e60113e9066ef893da0d"}}, - {name = "markupsafe-3.0.3-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl",url = "https://files.pythonhosted.org/packages/3c/2e/8d0c2ab90a8c1d9a24f0399058ab8519a3279d1bd4289511d74e909f060e/markupsafe-3.0.3-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl",hashes = {sha256 = "d6dd0be5b5b189d31db7cda48b91d7e0a9795f31430b7f271219ab30f1d3ac9d"}}, - {name = "markupsafe-3.0.3-cp312-cp312-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl",url = "https://files.pythonhosted.org/packages/2c/54/887f3092a85238093a0b2154bd629c89444f395618842e8b0c41783898ea/markupsafe-3.0.3-cp312-cp312-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl",hashes = {sha256 = "94c6f0bb423f739146aec64595853541634bde58b2135f27f61c1ffd1cd4d16a"}}, - {name = "markupsafe-3.0.3-cp312-cp312-musllinux_1_2_aarch64.whl",url = "https://files.pythonhosted.org/packages/c9/2f/336b8c7b6f4a4d95e91119dc8521402461b74a485558d8f238a68312f11c/markupsafe-3.0.3-cp312-cp312-musllinux_1_2_aarch64.whl",hashes = {sha256 = "be8813b57049a7dc738189df53d69395eba14fb99345e0a5994914a3864c8a4b"}}, - {name = "markupsafe-3.0.3-cp312-cp312-musllinux_1_2_riscv64.whl",url = "https://files.pythonhosted.org/packages/32/43/67935f2b7e4982ffb50a4d169b724d74b62a3964bc1a9a527f5ac4f1ee2b/markupsafe-3.0.3-cp312-cp312-musllinux_1_2_riscv64.whl",hashes = {sha256 = "83891d0e9fb81a825d9a6d61e3f07550ca70a076484292a70fde82c4b807286f"}}, - {name = "markupsafe-3.0.3-cp312-cp312-musllinux_1_2_x86_64.whl",url = "https://files.pythonhosted.org/packages/89/e0/4486f11e51bbba8b0c041098859e869e304d1c261e59244baa3d295d47b7/markupsafe-3.0.3-cp312-cp312-musllinux_1_2_x86_64.whl",hashes = {sha256 = "77f0643abe7495da77fb436f50f8dab76dbc6e5fd25d39589a0f1fe6548bfa2b"}}, - {name = "markupsafe-3.0.3-cp312-cp312-win32.whl",url = "https://files.pythonhosted.org/packages/2f/e1/78ee7a023dac597a5825441ebd17170785a9dab23de95d2c7508ade94e0e/markupsafe-3.0.3-cp312-cp312-win32.whl",hashes = {sha256 = "d88b440e37a16e651bda4c7c2b930eb586fd15ca7406cb39e211fcff3bf3017d"}}, - {name = "markupsafe-3.0.3-cp312-cp312-win_amd64.whl",url = "https://files.pythonhosted.org/packages/aa/5b/bec5aa9bbbb2c946ca2733ef9c4ca91c91b6a24580193e891b5f7dbe8e1e/markupsafe-3.0.3-cp312-cp312-win_amd64.whl",hashes = {sha256 = "26a5784ded40c9e318cfc2bdb30fe164bdb8665ded9cd64d500a34fb42067b1c"}}, - {name = "markupsafe-3.0.3-cp312-cp312-win_arm64.whl",url = "https://files.pythonhosted.org/packages/e5/f1/216fc1bbfd74011693a4fd837e7026152e89c4bcf3e77b6692fba9923123/markupsafe-3.0.3-cp312-cp312-win_arm64.whl",hashes = {sha256 = "35add3b638a5d900e807944a078b51922212fb3dedb01633a8defc4b01a3c85f"}}, - {name = "markupsafe-3.0.3-cp311-cp311-macosx_10_9_x86_64.whl",url = "https://files.pythonhosted.org/packages/08/db/fefacb2136439fc8dd20e797950e749aa1f4997ed584c62cfb8ef7c2be0e/markupsafe-3.0.3-cp311-cp311-macosx_10_9_x86_64.whl",hashes = {sha256 = "1cc7ea17a6824959616c525620e387f6dd30fec8cb44f649e31712db02123dad"}}, - {name = "markupsafe-3.0.3-cp311-cp311-macosx_11_0_arm64.whl",url = "https://files.pythonhosted.org/packages/e1/2e/5898933336b61975ce9dc04decbc0a7f2fee78c30353c5efba7f2d6ff27a/markupsafe-3.0.3-cp311-cp311-macosx_11_0_arm64.whl",hashes = {sha256 = "4bd4cd07944443f5a265608cc6aab442e4f74dff8088b0dfc8238647b8f6ae9a"}}, - {name = "markupsafe-3.0.3-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl",url = "https://files.pythonhosted.org/packages/1d/09/adf2df3699d87d1d8184038df46a9c80d78c0148492323f4693df54e17bb/markupsafe-3.0.3-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl",hashes = {sha256 = "6b5420a1d9450023228968e7e6a9ce57f65d148ab56d2313fcd589eee96a7a50"}}, - {name = "markupsafe-3.0.3-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl",url = "https://files.pythonhosted.org/packages/30/ac/0273f6fcb5f42e314c6d8cd99effae6a5354604d461b8d392b5ec9530a54/markupsafe-3.0.3-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl",hashes = {sha256 = "0bf2a864d67e76e5c9a34dc26ec616a66b9888e25e7b9460e1c76d3293bd9dbf"}}, - {name = "markupsafe-3.0.3-cp311-cp311-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl",url = "https://files.pythonhosted.org/packages/19/ae/31c1be199ef767124c042c6c3e904da327a2f7f0cd63a0337e1eca2967a8/markupsafe-3.0.3-cp311-cp311-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl",hashes = {sha256 = "bc51efed119bc9cfdf792cdeaa4d67e8f6fcccab66ed4bfdd6bde3e59bfcbb2f"}}, - {name = "markupsafe-3.0.3-cp311-cp311-musllinux_1_2_aarch64.whl",url = "https://files.pythonhosted.org/packages/b2/76/7edcab99d5349a4532a459e1fe64f0b0467a3365056ae550d3bcf3f79e1e/markupsafe-3.0.3-cp311-cp311-musllinux_1_2_aarch64.whl",hashes = {sha256 = "068f375c472b3e7acbe2d5318dea141359e6900156b5b2ba06a30b169086b91a"}}, - {name = "markupsafe-3.0.3-cp311-cp311-musllinux_1_2_riscv64.whl",url = "https://files.pythonhosted.org/packages/a4/28/6e74cdd26d7514849143d69f0bf2399f929c37dc2b31e6829fd2045b2765/markupsafe-3.0.3-cp311-cp311-musllinux_1_2_riscv64.whl",hashes = {sha256 = "7be7b61bb172e1ed687f1754f8e7484f1c8019780f6f6b0786e76bb01c2ae115"}}, - {name = "markupsafe-3.0.3-cp311-cp311-musllinux_1_2_x86_64.whl",url = "https://files.pythonhosted.org/packages/62/7e/a145f36a5c2945673e590850a6f8014318d5577ed7e5920a4b3448e0865d/markupsafe-3.0.3-cp311-cp311-musllinux_1_2_x86_64.whl",hashes = {sha256 = "f9e130248f4462aaa8e2552d547f36ddadbeaa573879158d721bbd33dfe4743a"}}, - {name = "markupsafe-3.0.3-cp311-cp311-win32.whl",url = "https://files.pythonhosted.org/packages/0f/62/d9c46a7f5c9adbeeeda52f5b8d802e1094e9717705a645efc71b0913a0a8/markupsafe-3.0.3-cp311-cp311-win32.whl",hashes = {sha256 = "0db14f5dafddbb6d9208827849fad01f1a2609380add406671a26386cdf15a19"}}, - {name = "markupsafe-3.0.3-cp311-cp311-win_amd64.whl",url = "https://files.pythonhosted.org/packages/83/8a/4414c03d3f891739326e1783338e48fb49781cc915b2e0ee052aa490d586/markupsafe-3.0.3-cp311-cp311-win_amd64.whl",hashes = {sha256 = "de8a88e63464af587c950061a5e6a67d3632e36df62b986892331d4620a35c01"}}, - {name = "markupsafe-3.0.3-cp311-cp311-win_arm64.whl",url = "https://files.pythonhosted.org/packages/35/73/893072b42e6862f319b5207adc9ae06070f095b358655f077f69a35601f0/markupsafe-3.0.3-cp311-cp311-win_arm64.whl",hashes = {sha256 = "3b562dd9e9ea93f13d53989d23a7e775fdfd1066c33494ff43f5418bc8c58a5c"}}, -] -marker = "\"docs\" in extras" - -[packages.tool.pdm] -dependencies = [] - -[[packages]] -name = "matplotlib" -version = "3.10.8" -requires-python = ">=3.10" -sdist = {name = "matplotlib-3.10.8.tar.gz", url = "https://files.pythonhosted.org/packages/8a/76/d3c6e3a13fe484ebe7718d14e269c9569c4eb0020a968a327acb3b9a8fe6/matplotlib-3.10.8.tar.gz", hashes = {sha256 = "2299372c19d56bcd35cf05a2738308758d32b9eaed2371898d8f5bd33f084aa3"}} -wheels = [ - {name = "matplotlib-3.10.8-cp314-cp314-macosx_10_13_x86_64.whl",url = "https://files.pythonhosted.org/packages/3c/43/9c0ff7a2f11615e516c3b058e1e6e8f9614ddeca53faca06da267c48345d/matplotlib-3.10.8-cp314-cp314-macosx_10_13_x86_64.whl",hashes = {sha256 = "b53285e65d4fa4c86399979e956235deb900be5baa7fc1218ea67fbfaeaadd6f"}}, - {name = "matplotlib-3.10.8-cp314-cp314-macosx_11_0_arm64.whl",url = "https://files.pythonhosted.org/packages/6f/ca/e8ae28649fcdf039fda5ef554b40a95f50592a3c47e6f7270c9561c12b07/matplotlib-3.10.8-cp314-cp314-macosx_11_0_arm64.whl",hashes = {sha256 = "32f8dce744be5569bebe789e46727946041199030db8aeb2954d26013a0eb26b"}}, - {name = "matplotlib-3.10.8-cp314-cp314-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl",url = "https://files.pythonhosted.org/packages/f1/6f/009d129ae70b75e88cbe7e503a12a4c0670e08ed748a902c2568909e9eb5/matplotlib-3.10.8-cp314-cp314-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl",hashes = {sha256 = "4cf267add95b1c88300d96ca837833d4112756045364f5c734a2276038dae27d"}}, - {name = "matplotlib-3.10.8-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl",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",hashes = {sha256 = "2cf5bd12cecf46908f286d7838b2abc6c91cda506c0445b8223a7c19a00df008"}}, - {name = "matplotlib-3.10.8-cp314-cp314-musllinux_1_2_x86_64.whl",url = "https://files.pythonhosted.org/packages/1f/f3/3abf75f38605772cf48a9daf5821cd4f563472f38b4b828c6fba6fa6d06e/matplotlib-3.10.8-cp314-cp314-musllinux_1_2_x86_64.whl",hashes = {sha256 = "41703cc95688f2516b480f7f339d8851a6035f18e100ee6a32bc0b8536a12a9c"}}, - {name = "matplotlib-3.10.8-cp314-cp314-win_amd64.whl",url = "https://files.pythonhosted.org/packages/93/a5/de89ac80f10b8dc615807ee1133cd99ac74082581196d4d9590bea10690d/matplotlib-3.10.8-cp314-cp314-win_amd64.whl",hashes = {sha256 = "83d282364ea9f3e52363da262ce32a09dfe241e4080dcedda3c0db059d3c1f11"}}, - {name = "matplotlib-3.10.8-cp314-cp314-win_arm64.whl",url = "https://files.pythonhosted.org/packages/69/ce/b006495c19ccc0a137b48083168a37bd056392dee02f87dba0472f2797fe/matplotlib-3.10.8-cp314-cp314-win_arm64.whl",hashes = {sha256 = "2c1998e92cd5999e295a731bcb2911c75f597d937341f3030cc24ef2733d78a8"}}, - {name = "matplotlib-3.10.8-cp314-cp314t-macosx_10_13_x86_64.whl",url = "https://files.pythonhosted.org/packages/68/d9/b31116a3a855bd313c6fcdb7226926d59b041f26061c6c5b1be66a08c826/matplotlib-3.10.8-cp314-cp314t-macosx_10_13_x86_64.whl",hashes = {sha256 = "b5a2b97dbdc7d4f353ebf343744f1d1f1cca8aa8bfddb4262fcf4306c3761d50"}}, - {name = "matplotlib-3.10.8-cp314-cp314t-macosx_11_0_arm64.whl",url = "https://files.pythonhosted.org/packages/1e/90/6effe8103f0272685767ba5f094f453784057072f49b393e3ea178fe70a5/matplotlib-3.10.8-cp314-cp314t-macosx_11_0_arm64.whl",hashes = {sha256 = "3f5c3e4da343bba819f0234186b9004faba952cc420fbc522dc4e103c1985908"}}, - {name = "matplotlib-3.10.8-cp314-cp314t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl",url = "https://files.pythonhosted.org/packages/d7/65/a73188711bea603615fc0baecca1061429ac16940e2385433cc778a9d8e7/matplotlib-3.10.8-cp314-cp314t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl",hashes = {sha256 = "5f62550b9a30afde8c1c3ae450e5eb547d579dd69b25c2fc7a1c67f934c1717a"}}, - {name = "matplotlib-3.10.8-cp314-cp314t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl",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",hashes = {sha256 = "495672de149445ec1b772ff2c9ede9b769e3cb4f0d0aa7fa730d7f59e2d4e1c1"}}, - {name = "matplotlib-3.10.8-cp314-cp314t-musllinux_1_2_x86_64.whl",url = "https://files.pythonhosted.org/packages/4d/4b/e7beb6bbd49f6bae727a12b270a2654d13c397576d25bd6786e47033300f/matplotlib-3.10.8-cp314-cp314t-musllinux_1_2_x86_64.whl",hashes = {sha256 = "595ba4d8fe983b88f0eec8c26a241e16d6376fe1979086232f481f8f3f67494c"}}, - {name = "matplotlib-3.10.8-cp314-cp314t-win_amd64.whl",url = "https://files.pythonhosted.org/packages/7c/e6/76f2813d31f032e65f6f797e3f2f6e4aab95b65015924b1c51370395c28a/matplotlib-3.10.8-cp314-cp314t-win_amd64.whl",hashes = {sha256 = "25d380fe8b1dc32cf8f0b1b448470a77afb195438bafdf1d858bfb876f3edf7b"}}, - {name = "matplotlib-3.10.8-cp314-cp314t-win_arm64.whl",url = "https://files.pythonhosted.org/packages/5d/49/d651878698a0b67f23aa28e17f45a6d6dd3d3f933fa29087fa4ce5947b5a/matplotlib-3.10.8-cp314-cp314t-win_arm64.whl",hashes = {sha256 = "113bb52413ea508ce954a02c10ffd0d565f9c3bc7f2eddc27dfe1731e71c7b5f"}}, - {name = "matplotlib-3.10.8-cp313-cp313-macosx_10_13_x86_64.whl",url = "https://files.pythonhosted.org/packages/3d/b9/15fd5541ef4f5b9a17eefd379356cf12175fe577424e7b1d80676516031a/matplotlib-3.10.8-cp313-cp313-macosx_10_13_x86_64.whl",hashes = {sha256 = "3f2e409836d7f5ac2f1c013110a4d50b9f7edc26328c108915f9075d7d7a91b6"}}, - {name = "matplotlib-3.10.8-cp313-cp313-macosx_11_0_arm64.whl",url = "https://files.pythonhosted.org/packages/8d/a0/2ba3473c1b66b9c74dc7107c67e9008cb1782edbe896d4c899d39ae9cf78/matplotlib-3.10.8-cp313-cp313-macosx_11_0_arm64.whl",hashes = {sha256 = "56271f3dac49a88d7fca5060f004d9d22b865f743a12a23b1e937a0be4818ee1"}}, - {name = "matplotlib-3.10.8-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl",url = "https://files.pythonhosted.org/packages/75/97/a471f1c3eb1fd6f6c24a31a5858f443891d5127e63a7788678d14e249aea/matplotlib-3.10.8-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl",hashes = {sha256 = "a0a7f52498f72f13d4a25ea70f35f4cb60642b466cbb0a9be951b5bc3f45a486"}}, - {name = "matplotlib-3.10.8-cp313-cp313-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl",url = "https://files.pythonhosted.org/packages/01/be/cd478f4b66f48256f42927d0acbcd63a26a893136456cd079c0cc24fbabf/matplotlib-3.10.8-cp313-cp313-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl",hashes = {sha256 = "646d95230efb9ca614a7a594d4fcacde0ac61d25e37dd51710b36477594963ce"}}, - {name = "matplotlib-3.10.8-cp313-cp313-musllinux_1_2_x86_64.whl",url = "https://files.pythonhosted.org/packages/5d/7c/8dc289776eae5109e268c4fb92baf870678dc048a25d4ac903683b86d5bf/matplotlib-3.10.8-cp313-cp313-musllinux_1_2_x86_64.whl",hashes = {sha256 = "f89c151aab2e2e23cb3fe0acad1e8b82841fd265379c4cecd0f3fcb34c15e0f6"}}, - {name = "matplotlib-3.10.8-cp313-cp313-win_amd64.whl",url = "https://files.pythonhosted.org/packages/64/40/37612487cc8a437d4dd261b32ca21fe2d79510fe74af74e1f42becb1bdb8/matplotlib-3.10.8-cp313-cp313-win_amd64.whl",hashes = {sha256 = "e8ea3e2d4066083e264e75c829078f9e149fa119d27e19acd503de65e0b13149"}}, - {name = "matplotlib-3.10.8-cp313-cp313-win_arm64.whl",url = "https://files.pythonhosted.org/packages/66/52/8d8a8730e968185514680c2a6625943f70269509c3dcfc0dcf7d75928cb8/matplotlib-3.10.8-cp313-cp313-win_arm64.whl",hashes = {sha256 = "c108a1d6fa78a50646029cb6d49808ff0fc1330fda87fa6f6250c6b5369b6645"}}, - {name = "matplotlib-3.10.8-cp313-cp313t-macosx_10_13_x86_64.whl",url = "https://files.pythonhosted.org/packages/b5/27/51fe26e1062f298af5ef66343d8ef460e090a27fea73036c76c35821df04/matplotlib-3.10.8-cp313-cp313t-macosx_10_13_x86_64.whl",hashes = {sha256 = "ad3d9833a64cf48cc4300f2b406c3d0f4f4724a91c0bd5640678a6ba7c102077"}}, - {name = "matplotlib-3.10.8-cp313-cp313t-macosx_11_0_arm64.whl",url = "https://files.pythonhosted.org/packages/2c/1e/4de865bc591ac8e3062e835f42dd7fe7a93168d519557837f0e37513f629/matplotlib-3.10.8-cp313-cp313t-macosx_11_0_arm64.whl",hashes = {sha256 = "eb3823f11823deade26ce3b9f40dcb4a213da7a670013929f31d5f5ed1055b22"}}, - {name = "matplotlib-3.10.8-cp313-cp313t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl",url = "https://files.pythonhosted.org/packages/c6/cb/2f7b6e75fb4dce87ef91f60cac4f6e34f4c145ab036a22318ec837971300/matplotlib-3.10.8-cp313-cp313t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl",hashes = {sha256 = "d9050fee89a89ed57b4fb2c1bfac9a3d0c57a0d55aed95949eedbc42070fea39"}}, - {name = "matplotlib-3.10.8-cp313-cp313t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl",url = "https://files.pythonhosted.org/packages/46/b3/bd9c57d6ba670a37ab31fb87ec3e8691b947134b201f881665b28cc039ff/matplotlib-3.10.8-cp313-cp313t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl",hashes = {sha256 = "b44d07310e404ba95f8c25aa5536f154c0a8ec473303535949e52eb71d0a1565"}}, - {name = "matplotlib-3.10.8-cp313-cp313t-musllinux_1_2_x86_64.whl",url = "https://files.pythonhosted.org/packages/c0/3d/8b94a481456dfc9dfe6e39e93b5ab376e50998cddfd23f4ae3b431708f16/matplotlib-3.10.8-cp313-cp313t-musllinux_1_2_x86_64.whl",hashes = {sha256 = "0a33deb84c15ede243aead39f77e990469fff93ad1521163305095b77b72ce4a"}}, - {name = "matplotlib-3.10.8-cp313-cp313t-win_amd64.whl",url = "https://files.pythonhosted.org/packages/bd/cd/bc06149fe5585ba800b189a6a654a75f1f127e8aab02fd2be10df7fa500c/matplotlib-3.10.8-cp313-cp313t-win_amd64.whl",hashes = {sha256 = "3a48a78d2786784cc2413e57397981fb45c79e968d99656706018d6e62e57958"}}, - {name = "matplotlib-3.10.8-cp313-cp313t-win_arm64.whl",url = "https://files.pythonhosted.org/packages/e3/de/b22cf255abec916562cc04eef457c13e58a1990048de0c0c3604d082355e/matplotlib-3.10.8-cp313-cp313t-win_arm64.whl",hashes = {sha256 = "15d30132718972c2c074cd14638c7f4592bd98719e2308bccea40e0538bc0cb5"}}, - {name = "matplotlib-3.10.8-cp312-cp312-macosx_10_13_x86_64.whl",url = "https://files.pythonhosted.org/packages/9e/67/f997cdcbb514012eb0d10cd2b4b332667997fb5ebe26b8d41d04962fa0e6/matplotlib-3.10.8-cp312-cp312-macosx_10_13_x86_64.whl",hashes = {sha256 = "64fcc24778ca0404ce0cb7b6b77ae1f4c7231cdd60e6778f999ee05cbd581b9a"}}, - {name = "matplotlib-3.10.8-cp312-cp312-macosx_11_0_arm64.whl",url = "https://files.pythonhosted.org/packages/7e/65/07d5f5c7f7c994f12c768708bd2e17a4f01a2b0f44a1c9eccad872433e2e/matplotlib-3.10.8-cp312-cp312-macosx_11_0_arm64.whl",hashes = {sha256 = "b9a5ca4ac220a0cdd1ba6bcba3608547117d30468fefce49bb26f55c1a3d5c58"}}, - {name = "matplotlib-3.10.8-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl",url = "https://files.pythonhosted.org/packages/3e/f3/c5195b1ae57ef85339fd7285dfb603b22c8b4e79114bae5f4f0fcf688677/matplotlib-3.10.8-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl",hashes = {sha256 = "3ab4aabc72de4ff77b3ec33a6d78a68227bf1123465887f9905ba79184a1cc04"}}, - {name = "matplotlib-3.10.8-cp312-cp312-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl",url = "https://files.pythonhosted.org/packages/00/f9/7638f5cc82ec8a7aa005de48622eecc3ed7c9854b96ba15bd76b7fd27574/matplotlib-3.10.8-cp312-cp312-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl",hashes = {sha256 = "24d50994d8c5816ddc35411e50a86ab05f575e2530c02752e02538122613371f"}}, - {name = "matplotlib-3.10.8-cp312-cp312-musllinux_1_2_x86_64.whl",url = "https://files.pythonhosted.org/packages/57/61/78cd5920d35b29fd2a0fe894de8adf672ff52939d2e9b43cb83cd5ce1bc7/matplotlib-3.10.8-cp312-cp312-musllinux_1_2_x86_64.whl",hashes = {sha256 = "99eefd13c0dc3b3c1b4d561c1169e65fe47aab7b8158754d7c084088e2329466"}}, - {name = "matplotlib-3.10.8-cp312-cp312-win_amd64.whl",url = "https://files.pythonhosted.org/packages/30/4e/c10f171b6e2f44d9e3a2b96efa38b1677439d79c99357600a62cc1e9594e/matplotlib-3.10.8-cp312-cp312-win_amd64.whl",hashes = {sha256 = "dd80ecb295460a5d9d260df63c43f4afbdd832d725a531f008dad1664f458adf"}}, - {name = "matplotlib-3.10.8-cp312-cp312-win_arm64.whl",url = "https://files.pythonhosted.org/packages/f1/76/934db220026b5fef85f45d51a738b91dea7d70207581063cd9bd8fafcf74/matplotlib-3.10.8-cp312-cp312-win_arm64.whl",hashes = {sha256 = "3c624e43ed56313651bc18a47f838b60d7b8032ed348911c54906b130b20071b"}}, - {name = "matplotlib-3.10.8-cp311-cp311-macosx_10_12_x86_64.whl",url = "https://files.pythonhosted.org/packages/f8/86/de7e3a1cdcfc941483af70609edc06b83e7c8a0e0dc9ac325200a3f4d220/matplotlib-3.10.8-cp311-cp311-macosx_10_12_x86_64.whl",hashes = {sha256 = "6be43b667360fef5c754dda5d25a32e6307a03c204f3c0fc5468b78fa87b4160"}}, - {name = "matplotlib-3.10.8-cp311-cp311-macosx_11_0_arm64.whl",url = "https://files.pythonhosted.org/packages/fd/14/baad3222f424b19ce6ad243c71de1ad9ec6b2e4eb1e458a48fdc6d120401/matplotlib-3.10.8-cp311-cp311-macosx_11_0_arm64.whl",hashes = {sha256 = "a2b336e2d91a3d7006864e0990c83b216fcdca64b5a6484912902cef87313d78"}}, - {name = "matplotlib-3.10.8-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl",url = "https://files.pythonhosted.org/packages/8f/a0/7024215e95d456de5883e6732e708d8187d9753a21d32f8ddb3befc0c445/matplotlib-3.10.8-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl",hashes = {sha256 = "efb30e3baaea72ce5928e32bab719ab4770099079d66726a62b11b1ef7273be4"}}, - {name = "matplotlib-3.10.8-cp311-cp311-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl",url = "https://files.pythonhosted.org/packages/5a/f4/b8347351da9a5b3f41e26cf547252d861f685c6867d179a7c9d60ad50189/matplotlib-3.10.8-cp311-cp311-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl",hashes = {sha256 = "d56a1efd5bfd61486c8bc968fa18734464556f0fb8e51690f4ac25d85cbbbbc2"}}, - {name = "matplotlib-3.10.8-cp311-cp311-musllinux_1_2_x86_64.whl",url = "https://files.pythonhosted.org/packages/9e/c0/c7b914e297efe0bc36917bf216b2acb91044b91e930e878ae12981e461e5/matplotlib-3.10.8-cp311-cp311-musllinux_1_2_x86_64.whl",hashes = {sha256 = "238b7ce5717600615c895050239ec955d91f321c209dd110db988500558e70d6"}}, - {name = "matplotlib-3.10.8-cp311-cp311-win_amd64.whl",url = "https://files.pythonhosted.org/packages/6f/d3/a4bbc01c237ab710a1f22b4da72f4ff6d77eb4c7735ea9811a94ae239067/matplotlib-3.10.8-cp311-cp311-win_amd64.whl",hashes = {sha256 = "18821ace09c763ec93aef5eeff087ee493a24051936d7b9ebcad9662f66501f9"}}, - {name = "matplotlib-3.10.8-cp311-cp311-win_arm64.whl",url = "https://files.pythonhosted.org/packages/89/dd/a0b6588f102beab33ca6f5218b31725216577b2a24172f327eaf6417d5c9/matplotlib-3.10.8-cp311-cp311-win_arm64.whl",hashes = {sha256 = "bab485bcf8b1c7d2060b4fcb6fc368a9e6f4cd754c9c2fea281f4be21df394a2"}}, - {name = "matplotlib-3.10.8-pp311-pypy311_pp73-macosx_10_15_x86_64.whl",url = "https://files.pythonhosted.org/packages/04/30/3afaa31c757f34b7725ab9d2ba8b48b5e89c2019c003e7d0ead143aabc5a/matplotlib-3.10.8-pp311-pypy311_pp73-macosx_10_15_x86_64.whl",hashes = {sha256 = "6da7c2ce169267d0d066adcf63758f0604aa6c3eebf67458930f9d9b79ad1db1"}}, - {name = "matplotlib-3.10.8-pp311-pypy311_pp73-macosx_11_0_arm64.whl",url = "https://files.pythonhosted.org/packages/48/2f/6334aec331f57485a642a7c8be03cb286f29111ae71c46c38b363230063c/matplotlib-3.10.8-pp311-pypy311_pp73-macosx_11_0_arm64.whl",hashes = {sha256 = "9153c3292705be9f9c64498a8872118540c3f4123d1a1c840172edf262c8be4a"}}, - {name = "matplotlib-3.10.8-pp311-pypy311_pp73-manylinux2014_x86_64.manylinux_2_17_x86_64.whl",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",hashes = {sha256 = "1ae029229a57cd1e8fe542485f27e7ca7b23aa9e8944ddb4985d0bc444f1eca2"}}, -] -marker = "\"default\" in dependency_groups or \"docs\" in extras" - -[packages.tool.pdm] -dependencies = [ - "contourpy>=1.0.1", - "cycler>=0.10", - "fonttools>=4.22.0", - "kiwisolver>=1.3.1", - "numpy>=1.23", - "packaging>=20.0", - "pillow>=8", - "pyparsing>=3", - "python-dateutil>=2.7", -] - -[[packages]] -name = "matplotlib-inline" -version = "0.2.1" -requires-python = ">=3.9" -sdist = {name = "matplotlib_inline-0.2.1.tar.gz", url = "https://files.pythonhosted.org/packages/c7/74/97e72a36efd4ae2bccb3463284300f8953f199b5ffbc04cbbb0ec78f74b1/matplotlib_inline-0.2.1.tar.gz", hashes = {sha256 = "e1ee949c340d771fc39e241ea75683deb94762c8fa5f2927ec57c83c4dffa9fe"}} -wheels = [ - {name = "matplotlib_inline-0.2.1-py3-none-any.whl",url = "https://files.pythonhosted.org/packages/af/33/ee4519fa02ed11a94aef9559552f3b17bb863f2ecfe1a35dc7f548cde231/matplotlib_inline-0.2.1-py3-none-any.whl",hashes = {sha256 = "d56ce5156ba6085e00a9d54fead6ed29a9c47e215cd1bba2e976ef39f5710a76"}}, -] -marker = "\"docs\" in extras" - -[packages.tool.pdm] -dependencies = [ - "traitlets", -] - -[[packages]] -name = "mccabe" -version = "0.7.0" -requires-python = ">=3.6" -sdist = {name = "mccabe-0.7.0.tar.gz", url = "https://files.pythonhosted.org/packages/e7/ff/0ffefdcac38932a54d2b5eed4e0ba8a408f215002cd178ad1df0f2806ff8/mccabe-0.7.0.tar.gz", hashes = {sha256 = "348e0240c33b60bbdf4e523192ef919f28cb2c3d7d5c7794f74009290f236325"}} -wheels = [ - {name = "mccabe-0.7.0-py2.py3-none-any.whl",url = "https://files.pythonhosted.org/packages/27/1a/1f68f9ba0c207934b35b86a8ca3aad8395a3d6dd7921c0686e23853ff5a9/mccabe-0.7.0-py2.py3-none-any.whl",hashes = {sha256 = "6c2d30ab6be0e4a46919781807b4f0d834ebdd6c6e3dca0bda5a15f863427b6e"}}, -] -marker = "\"docs\" in extras" - -[packages.tool.pdm] -dependencies = [] - -[[packages]] -name = "mdit-py-plugins" -version = "0.5.0" -requires-python = ">=3.10" -sdist = {name = "mdit_py_plugins-0.5.0.tar.gz", url = "https://files.pythonhosted.org/packages/b2/fd/a756d36c0bfba5f6e39a1cdbdbfdd448dc02692467d83816dff4592a1ebc/mdit_py_plugins-0.5.0.tar.gz", hashes = {sha256 = "f4918cb50119f50446560513a8e311d574ff6aaed72606ddae6d35716fe809c6"}} -wheels = [ - {name = "mdit_py_plugins-0.5.0-py3-none-any.whl",url = "https://files.pythonhosted.org/packages/fb/86/dd6e5db36df29e76c7a7699123569a4a18c1623ce68d826ed96c62643cae/mdit_py_plugins-0.5.0-py3-none-any.whl",hashes = {sha256 = "07a08422fc1936a5d26d146759e9155ea466e842f5ab2f7d2266dd084c8dab1f"}}, -] -marker = "\"docs\" in extras" - -[packages.tool.pdm] -dependencies = [ - "markdown-it-py<5.0.0,>=2.0.0", -] - -[[packages]] -name = "mdurl" -version = "0.1.2" -requires-python = ">=3.7" -sdist = {name = "mdurl-0.1.2.tar.gz", url = "https://files.pythonhosted.org/packages/d6/54/cfe61301667036ec958cb99bd3efefba235e65cdeb9c84d24a8293ba1d90/mdurl-0.1.2.tar.gz", hashes = {sha256 = "bb413d29f5eea38f31dd4754dd7377d4465116fb207585f97bf925588687c1ba"}} -wheels = [ - {name = "mdurl-0.1.2-py3-none-any.whl",url = "https://files.pythonhosted.org/packages/b3/38/89ba8ad64ae25be8de66a6d463314cf1eb366222074cfda9ee839c56a4b4/mdurl-0.1.2-py3-none-any.whl",hashes = {sha256 = "84008a41e51615a49fc9966191ff91509e3c40b939176e643fd50a5c2196b8f8"}}, -] -marker = "\"docs\" in extras" - -[packages.tool.pdm] -dependencies = [] - -[[packages]] -name = "mistune" -version = "3.2.0" -requires-python = ">=3.8" -sdist = {name = "mistune-3.2.0.tar.gz", url = "https://files.pythonhosted.org/packages/9d/55/d01f0c4b45ade6536c51170b9043db8b2ec6ddf4a35c7ea3f5f559ac935b/mistune-3.2.0.tar.gz", hashes = {sha256 = "708487c8a8cdd99c9d90eb3ed4c3ed961246ff78ac82f03418f5183ab70e398a"}} -wheels = [ - {name = "mistune-3.2.0-py3-none-any.whl",url = "https://files.pythonhosted.org/packages/9b/f7/4a5e785ec9fbd65146a27b6b70b6cdc161a66f2024e4b04ac06a67f5578b/mistune-3.2.0-py3-none-any.whl",hashes = {sha256 = "febdc629a3c78616b94393c6580551e0e34cc289987ec6c35ed3f4be42d0eee1"}}, -] -marker = "\"docs\" in extras" - -[packages.tool.pdm] -dependencies = [ - "typing-extensions; python_version < \"3.11\"", -] - -[[packages]] -name = "myst-parser" -version = "5.0.0" -requires-python = ">=3.11" -sdist = {name = "myst_parser-5.0.0.tar.gz", url = "https://files.pythonhosted.org/packages/33/fa/7b45eef11b7971f0beb29d27b7bfe0d747d063aa29e170d9edd004733c8a/myst_parser-5.0.0.tar.gz", hashes = {sha256 = "f6f231452c56e8baa662cc352c548158f6a16fcbd6e3800fc594978002b94f3a"}} -wheels = [ - {name = "myst_parser-5.0.0-py3-none-any.whl",url = "https://files.pythonhosted.org/packages/d3/ac/686789b9145413f1a61878c407210e41bfdb097976864e0913078b24098c/myst_parser-5.0.0-py3-none-any.whl",hashes = {sha256 = "ab31e516024918296e169139072b81592336f2fef55b8986aa31c9f04b5f7211"}}, -] -marker = "\"docs\" in extras" - -[packages.tool.pdm] -dependencies = [ - "docutils<0.23,>=0.20", - "jinja2", - "markdown-it-py~=4.0", - "mdit-py-plugins~=0.5", - "pyyaml", - "sphinx<10,>=8", -] - -[[packages]] -name = "narwhals" -version = "2.19.0" -requires-python = ">=3.9" -sdist = {name = "narwhals-2.19.0.tar.gz", url = "https://files.pythonhosted.org/packages/4e/1a/bd3317c0bdbcd9ffb710ddf5250b32898f8f2c240be99494fe137feb77a7/narwhals-2.19.0.tar.gz", hashes = {sha256 = "14fd7040b5ff211d415a82e4827b9d04c354e213e72a6d0730205ffd72e3b7ff"}} -wheels = [ - {name = "narwhals-2.19.0-py3-none-any.whl",url = "https://files.pythonhosted.org/packages/37/72/e61e3091e0e00fae9d3a8ef85ece9d2cd4b5966058e1f2901ce42679eebf/narwhals-2.19.0-py3-none-any.whl",hashes = {sha256 = "1f8dfa4a33a6dbff878c3e9be4c3b455dfcaf2a9322f1357db00e4e92e95b84b"}}, -] -marker = "\"default\" in dependency_groups" - -[packages.tool.pdm] -dependencies = [] - -[[packages]] -name = "nb2plots" -version = "0.7.2" -requires-python = ">=3.7" -sdist = {name = "nb2plots-0.7.2.tar.gz", url = "https://files.pythonhosted.org/packages/47/1c/56467472e0dd8824f21d55ef2f38f245d1d60667e05995aa28a8a953380d/nb2plots-0.7.2.tar.gz", hashes = {sha256 = "4f0de757fce4d4f6937ebfa2ffbabb7feb87134c61c944055e95a1999aab2d8b"}} -marker = "\"docs\" in extras" - -[packages.tool.pdm] -dependencies = [ - "ipython[notebook]>=7.16.3", - "matplotlib>=3.2", - "nbconvert>=6.0.7", - "numpy>=1.20", - "sphinx>=4", - "sphinxtesters>=0.2.3", - "texext>=0.6.6", -] - -[[packages]] -name = "nbclient" -version = "0.10.4" -requires-python = ">=3.10.0" -sdist = {name = "nbclient-0.10.4.tar.gz", url = "https://files.pythonhosted.org/packages/56/91/1c1d5a4b9a9ebba2b4e32b8c852c2975c872aec1fe42ab5e516b2cecd193/nbclient-0.10.4.tar.gz", hashes = {sha256 = "1e54091b16e6da39e297b0ece3e10f6f29f4ac4e8ee515d29f8a7099bd6553c9"}} -wheels = [ - {name = "nbclient-0.10.4-py3-none-any.whl",url = "https://files.pythonhosted.org/packages/83/a0/5b0c2f11142ed1dddec842457d3f65eaf71a0080894eb6f018755b319c3a/nbclient-0.10.4-py3-none-any.whl",hashes = {sha256 = "9162df5a7373d70d606527300a95a975a47c137776cd942e52d9c7e29ff83440"}}, -] -marker = "\"docs\" in extras" - -[packages.tool.pdm] -dependencies = [ - "jupyter-client>=6.1.12", - "jupyter-core!=5.0.*,>=4.12", - "nbformat>=5.1.3", - "traitlets>=5.4", -] - -[[packages]] -name = "nbconvert" -version = "7.17.1" -requires-python = ">=3.9" -sdist = {name = "nbconvert-7.17.1.tar.gz", url = "https://files.pythonhosted.org/packages/01/b1/708e53fe2e429c103c6e6e159106bcf0357ac41aa4c28772bd8402339051/nbconvert-7.17.1.tar.gz", hashes = {sha256 = "34d0d0a7e73ce3cbab6c5aae8f4f468797280b01fd8bd2ca746da8569eddd7d2"}} -wheels = [ - {name = "nbconvert-7.17.1-py3-none-any.whl",url = "https://files.pythonhosted.org/packages/67/f8/bb0a9d5f46819c821dc1f004aa2cc29b1d91453297dbf5ff20470f00f193/nbconvert-7.17.1-py3-none-any.whl",hashes = {sha256 = "aa85c087b435e7bf1ffd03319f658e285f2b89eccab33bc1ba7025495ab3e7c8"}}, -] -marker = "\"docs\" in extras" - -[packages.tool.pdm] -dependencies = [ - "beautifulsoup4", - "bleach[css]!=5.0.0", - "defusedxml", - "importlib-metadata>=3.6; python_version < \"3.10\"", - "jinja2>=3.0", - "jupyter-core>=4.7", - "jupyterlab-pygments", - "markupsafe>=2.0", - "mistune<4,>=2.0.3", - "nbclient>=0.5.0", - "nbformat>=5.7", - "packaging", - "pandocfilters>=1.4.1", - "pygments>=2.4.1", - "traitlets>=5.1", -] - -[[packages]] -name = "nbformat" -version = "5.10.4" -requires-python = ">=3.8" -sdist = {name = "nbformat-5.10.4.tar.gz", url = "https://files.pythonhosted.org/packages/6d/fd/91545e604bc3dad7dca9ed03284086039b294c6b3d75c0d2fa45f9e9caf3/nbformat-5.10.4.tar.gz", hashes = {sha256 = "322168b14f937a5d11362988ecac2a4952d3d8e3a2cbeb2319584631226d5b3a"}} -wheels = [ - {name = "nbformat-5.10.4-py3-none-any.whl",url = "https://files.pythonhosted.org/packages/a9/82/0340caa499416c78e5d8f5f05947ae4bc3cba53c9f038ab6e9ed964e22f1/nbformat-5.10.4-py3-none-any.whl",hashes = {sha256 = "3b48d6c8fbca4b299bf3982ea7db1af21580e4fec269ad087b9e81588891200b"}}, -] -marker = "\"docs\" in extras" - -[packages.tool.pdm] -dependencies = [ - "fastjsonschema>=2.15", - "jsonschema>=2.6", - "jupyter-core!=5.0.*,>=4.12", - "traitlets>=5.1", -] - -[[packages]] -name = "nest-asyncio" -version = "1.6.0" -requires-python = ">=3.5" -sdist = {name = "nest_asyncio-1.6.0.tar.gz", url = "https://files.pythonhosted.org/packages/83/f8/51569ac65d696c8ecbee95938f89d4abf00f47d58d48f6fbabfe8f0baefe/nest_asyncio-1.6.0.tar.gz", hashes = {sha256 = "6f172d5449aca15afd6c646851f4e31e02c598d553a667e38cafa997cfec55fe"}} -wheels = [ - {name = "nest_asyncio-1.6.0-py3-none-any.whl",url = "https://files.pythonhosted.org/packages/a0/c4/c2971a3ba4c6103a3d10c4b0f24f461ddc027f0f09763220cf35ca1401b3/nest_asyncio-1.6.0-py3-none-any.whl",hashes = {sha256 = "87af6efd6b5e897c81050477ef65c62e2b2f35d51703cae01aff2905b1852e1c"}}, -] -marker = "\"docs\" in extras" - -[packages.tool.pdm] -dependencies = [] - -[[packages]] -name = "numpy" -version = "1.26.4" -requires-python = ">=3.9" -sdist = {name = "numpy-1.26.4.tar.gz", url = "https://files.pythonhosted.org/packages/65/6e/09db70a523a96d25e115e71cc56a6f9031e7b8cd166c1ac8438307c14058/numpy-1.26.4.tar.gz", hashes = {sha256 = "2a02aba9ed12e4ac4eb3ea9421c420301a0c6460d9830d74a9df87efa4912010"}} -wheels = [ - {name = "numpy-1.26.4-cp312-cp312-macosx_10_9_x86_64.whl",url = "https://files.pythonhosted.org/packages/95/12/8f2020a8e8b8383ac0177dc9570aad031a3beb12e38847f7129bacd96228/numpy-1.26.4-cp312-cp312-macosx_10_9_x86_64.whl",hashes = {sha256 = "b3ce300f3644fb06443ee2222c2201dd3a89ea6040541412b8fa189341847218"}}, - {name = "numpy-1.26.4-cp312-cp312-macosx_11_0_arm64.whl",url = "https://files.pythonhosted.org/packages/75/5b/ca6c8bd14007e5ca171c7c03102d17b4f4e0ceb53957e8c44343a9546dcc/numpy-1.26.4-cp312-cp312-macosx_11_0_arm64.whl",hashes = {sha256 = "03a8c78d01d9781b28a6989f6fa1bb2c4f2d51201cf99d3dd875df6fbd96b23b"}}, - {name = "numpy-1.26.4-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl",url = "https://files.pythonhosted.org/packages/79/f8/97f10e6755e2a7d027ca783f63044d5b1bc1ae7acb12afe6a9b4286eac17/numpy-1.26.4-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl",hashes = {sha256 = "9fad7dcb1aac3c7f0584a5a8133e3a43eeb2fe127f47e3632d43d677c66c102b"}}, - {name = "numpy-1.26.4-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",url = "https://files.pythonhosted.org/packages/0f/50/de23fde84e45f5c4fda2488c759b69990fd4512387a8632860f3ac9cd225/numpy-1.26.4-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",hashes = {sha256 = "675d61ffbfa78604709862923189bad94014bef562cc35cf61d3a07bba02a7ed"}}, - {name = "numpy-1.26.4-cp312-cp312-musllinux_1_1_aarch64.whl",url = "https://files.pythonhosted.org/packages/4c/0c/9c603826b6465e82591e05ca230dfc13376da512b25ccd0894709b054ed0/numpy-1.26.4-cp312-cp312-musllinux_1_1_aarch64.whl",hashes = {sha256 = "ab47dbe5cc8210f55aa58e4805fe224dac469cde56b9f731a4c098b91917159a"}}, - {name = "numpy-1.26.4-cp312-cp312-musllinux_1_1_x86_64.whl",url = "https://files.pythonhosted.org/packages/76/8c/2ba3902e1a0fc1c74962ea9bb33a534bb05984ad7ff9515bf8d07527cadd/numpy-1.26.4-cp312-cp312-musllinux_1_1_x86_64.whl",hashes = {sha256 = "1dda2e7b4ec9dd512f84935c5f126c8bd8b9f2fc001e9f54af255e8c5f16b0e0"}}, - {name = "numpy-1.26.4-cp312-cp312-win32.whl",url = "https://files.pythonhosted.org/packages/28/4a/46d9e65106879492374999e76eb85f87b15328e06bd1550668f79f7b18c6/numpy-1.26.4-cp312-cp312-win32.whl",hashes = {sha256 = "50193e430acfc1346175fcbdaa28ffec49947a06918b7b92130744e81e640110"}}, - {name = "numpy-1.26.4-cp312-cp312-win_amd64.whl",url = "https://files.pythonhosted.org/packages/16/2e/86f24451c2d530c88daf997cb8d6ac622c1d40d19f5a031ed68a4b73a374/numpy-1.26.4-cp312-cp312-win_amd64.whl",hashes = {sha256 = "08beddf13648eb95f8d867350f6a018a4be2e5ad54c8d8caed89ebca558b2818"}}, - {name = "numpy-1.26.4-cp311-cp311-macosx_10_9_x86_64.whl",url = "https://files.pythonhosted.org/packages/11/57/baae43d14fe163fa0e4c47f307b6b2511ab8d7d30177c491960504252053/numpy-1.26.4-cp311-cp311-macosx_10_9_x86_64.whl",hashes = {sha256 = "4c66707fabe114439db9068ee468c26bbdf909cac0fb58686a42a24de1760c71"}}, - {name = "numpy-1.26.4-cp311-cp311-macosx_11_0_arm64.whl",url = "https://files.pythonhosted.org/packages/1a/2e/151484f49fd03944c4a3ad9c418ed193cfd02724e138ac8a9505d056c582/numpy-1.26.4-cp311-cp311-macosx_11_0_arm64.whl",hashes = {sha256 = "edd8b5fe47dab091176d21bb6de568acdd906d1887a4584a15a9a96a1dca06ef"}}, - {name = "numpy-1.26.4-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl",url = "https://files.pythonhosted.org/packages/79/ae/7e5b85136806f9dadf4878bf73cf223fe5c2636818ba3ab1c585d0403164/numpy-1.26.4-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl",hashes = {sha256 = "7ab55401287bfec946ced39700c053796e7cc0e3acbef09993a9ad2adba6ca6e"}}, - {name = "numpy-1.26.4-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",url = "https://files.pythonhosted.org/packages/3a/d0/edc009c27b406c4f9cbc79274d6e46d634d139075492ad055e3d68445925/numpy-1.26.4-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",hashes = {sha256 = "666dbfb6ec68962c033a450943ded891bed2d54e6755e35e5835d63f4f6931d5"}}, - {name = "numpy-1.26.4-cp311-cp311-musllinux_1_1_aarch64.whl",url = "https://files.pythonhosted.org/packages/09/bf/2b1aaf8f525f2923ff6cfcf134ae5e750e279ac65ebf386c75a0cf6da06a/numpy-1.26.4-cp311-cp311-musllinux_1_1_aarch64.whl",hashes = {sha256 = "96ff0b2ad353d8f990b63294c8986f1ec3cb19d749234014f4e7eb0112ceba5a"}}, - {name = "numpy-1.26.4-cp311-cp311-musllinux_1_1_x86_64.whl",url = "https://files.pythonhosted.org/packages/df/a0/4e0f14d847cfc2a633a1c8621d00724f3206cfeddeb66d35698c4e2cf3d2/numpy-1.26.4-cp311-cp311-musllinux_1_1_x86_64.whl",hashes = {sha256 = "60dedbb91afcbfdc9bc0b1f3f402804070deed7392c23eb7a7f07fa857868e8a"}}, - {name = "numpy-1.26.4-cp311-cp311-win32.whl",url = "https://files.pythonhosted.org/packages/d2/b7/a734c733286e10a7f1a8ad1ae8c90f2d33bf604a96548e0a4a3a6739b468/numpy-1.26.4-cp311-cp311-win32.whl",hashes = {sha256 = "1af303d6b2210eb850fcf03064d364652b7120803a0b872f5211f5234b399f20"}}, - {name = "numpy-1.26.4-cp311-cp311-win_amd64.whl",url = "https://files.pythonhosted.org/packages/3f/6b/5610004206cf7f8e7ad91c5a85a8c71b2f2f8051a0c0c4d5916b76d6cbb2/numpy-1.26.4-cp311-cp311-win_amd64.whl",hashes = {sha256 = "cd25bcecc4974d09257ffcd1f098ee778f7834c3ad767fe5db785be9a4aa9cb2"}}, -] -marker = "\"default\" in dependency_groups or \"docs\" in extras" - -[packages.tool.pdm] -dependencies = [] - -[[packages]] -name = "numpydoc" -version = "1.10.0" -requires-python = ">=3.10" -sdist = {name = "numpydoc-1.10.0.tar.gz", url = "https://files.pythonhosted.org/packages/e9/3c/dfccc9e7dee357fb2aa13c3890d952a370dd0ed071e0f7ed62ed0df567c1/numpydoc-1.10.0.tar.gz", hashes = {sha256 = "3f7970f6eee30912260a6b31ac72bba2432830cd6722569ec17ee8d3ef5ffa01"}} -wheels = [ - {name = "numpydoc-1.10.0-py3-none-any.whl",url = "https://files.pythonhosted.org/packages/62/5e/3a6a3e90f35cea3853c45e5d5fb9b7192ce4384616f932cf7591298ab6e1/numpydoc-1.10.0-py3-none-any.whl",hashes = {sha256 = "3149da9874af890bcc2a82ef7aae5484e5aa81cb2778f08e3c307ba6d963721b"}}, -] -marker = "\"docs\" in extras" - -[packages.tool.pdm] -dependencies = [ - "sphinx>=6", - "tomli>=1.1.0; python_version < \"3.11\"", -] - -[[packages]] -name = "packaging" -version = "26.0" -requires-python = ">=3.8" -sdist = {name = "packaging-26.0.tar.gz", url = "https://files.pythonhosted.org/packages/65/ee/299d360cdc32edc7d2cf530f3accf79c4fca01e96ffc950d8a52213bd8e4/packaging-26.0.tar.gz", hashes = {sha256 = "00243ae351a257117b6a241061796684b084ed1c516a08c48a3f7e147a9d80b4"}} -wheels = [ - {name = "packaging-26.0-py3-none-any.whl",url = "https://files.pythonhosted.org/packages/b7/b9/c538f279a4e237a006a2c98387d081e9eb060d203d8ed34467cc0f0b9b53/packaging-26.0-py3-none-any.whl",hashes = {sha256 = "b36f1fef9334a5588b4166f8bcd26a14e521f2b55e6b9de3aaa80d3ff7a37529"}}, -] -marker = "\"default\" in dependency_groups or \"docs\" in extras or \"test\" in extras" - -[packages.tool.pdm] -dependencies = [] - -[[packages]] -name = "pandas" -version = "2.2.1" -requires-python = ">=3.9" -sdist = {name = "pandas-2.2.1.tar.gz", url = "https://files.pythonhosted.org/packages/3d/59/2afa81b9fb300c90531803c0fd43ff4548074fa3e8d0f747ef63b3b5e77a/pandas-2.2.1.tar.gz", hashes = {sha256 = "0ab90f87093c13f3e8fa45b48ba9f39181046e8f3317d3aadb2fffbb1b978572"}} -wheels = [ - {name = "pandas-2.2.1-cp312-cp312-macosx_10_9_x86_64.whl",url = "https://files.pythonhosted.org/packages/ed/b9/660353ce2b1bd5b6e0f5c992836d91909c0da1ccb59c16565ad0a37e839d/pandas-2.2.1-cp312-cp312-macosx_10_9_x86_64.whl",hashes = {sha256 = "88ecb5c01bb9ca927ebc4098136038519aa5d66b44671861ffab754cae75102c"}}, - {name = "pandas-2.2.1-cp312-cp312-macosx_11_0_arm64.whl",url = "https://files.pythonhosted.org/packages/19/4e/6a7f400d4b65f82e37eefa7dbbe3e6f0a4fa542ca7ebb68c787eeebdc497/pandas-2.2.1-cp312-cp312-macosx_11_0_arm64.whl",hashes = {sha256 = "04f6ec3baec203c13e3f8b139fb0f9f86cd8c0b94603ae3ae8ce9a422e9f5bee"}}, - {name = "pandas-2.2.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl",url = "https://files.pythonhosted.org/packages/d7/2b/3e00e92a6b430313da68b15e925c6dba05f672d716cf3b02bcd3d0381974/pandas-2.2.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl",hashes = {sha256 = "a935a90a76c44fe170d01e90a3594beef9e9a6220021acfb26053d01426f7dc2"}}, - {name = "pandas-2.2.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",url = "https://files.pythonhosted.org/packages/78/f4/19f1dda9ab1eaa38301e445925f92b303d415d4c4115e56c0d62774421f7/pandas-2.2.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",hashes = {sha256 = "c391f594aae2fd9f679d419e9a4d5ba4bce5bb13f6a989195656e7dc4b95c8f0"}}, - {name = "pandas-2.2.1-cp312-cp312-musllinux_1_1_aarch64.whl",url = "https://files.pythonhosted.org/packages/6f/cd/8b84912b5bfab19b1fcea2f732d2e3a2d134d558f141e9dffa5dbfd9d23b/pandas-2.2.1-cp312-cp312-musllinux_1_1_aarch64.whl",hashes = {sha256 = "9d1265545f579edf3f8f0cb6f89f234f5e44ba725a34d86535b1a1d38decbccc"}}, - {name = "pandas-2.2.1-cp312-cp312-musllinux_1_1_x86_64.whl",url = "https://files.pythonhosted.org/packages/11/e7/65bf50aff86da6554cdffdcd87ced857c79a29dfaf1d85fdf97955d76d02/pandas-2.2.1-cp312-cp312-musllinux_1_1_x86_64.whl",hashes = {sha256 = "11940e9e3056576ac3244baef2fedade891977bcc1cb7e5cc8f8cc7d603edc89"}}, - {name = "pandas-2.2.1-cp312-cp312-win_amd64.whl",url = "https://files.pythonhosted.org/packages/71/00/6beaeeba7f075d15ea167a5caa039b861e58ff2f58a5b659abb9b544c8f6/pandas-2.2.1-cp312-cp312-win_amd64.whl",hashes = {sha256 = "4acf681325ee1c7f950d058b05a820441075b0dd9a2adf5c4835b9bc056bf4fb"}}, - {name = "pandas-2.2.1-cp311-cp311-macosx_10_9_x86_64.whl",url = "https://files.pythonhosted.org/packages/f1/8b/617792ad1feef330e87d7459584a1f91aa8aea373d8b168ac5d24fddd808/pandas-2.2.1-cp311-cp311-macosx_10_9_x86_64.whl",hashes = {sha256 = "f821213d48f4ab353d20ebc24e4faf94ba40d76680642fb7ce2ea31a3ad94f9b"}}, - {name = "pandas-2.2.1-cp311-cp311-macosx_11_0_arm64.whl",url = "https://files.pythonhosted.org/packages/a5/78/1d859bfb619c067e3353ed079248ae9532c105c4e018fa9a776d04b34572/pandas-2.2.1-cp311-cp311-macosx_11_0_arm64.whl",hashes = {sha256 = "c70e00c2d894cb230e5c15e4b1e1e6b2b478e09cf27cc593a11ef955b9ecc81a"}}, - {name = "pandas-2.2.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl",url = "https://files.pythonhosted.org/packages/91/bf/8c57707e440f944ba2cf3d6f6ae6c29883fac20fbe5d2ad485229149f273/pandas-2.2.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl",hashes = {sha256 = "e97fbb5387c69209f134893abc788a6486dbf2f9e511070ca05eed4b930b1b02"}}, - {name = "pandas-2.2.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",url = "https://files.pythonhosted.org/packages/d4/47/1ccf9f62d2674d3ca3e95452c5f9dd114234d1535dec77c96528bf6a31fc/pandas-2.2.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",hashes = {sha256 = "101d0eb9c5361aa0146f500773395a03839a5e6ecde4d4b6ced88b7e5a1a6403"}}, - {name = "pandas-2.2.1-cp311-cp311-musllinux_1_1_aarch64.whl",url = "https://files.pythonhosted.org/packages/e3/da/9522ba4b32b20a344c37a970d7835d261df1427d943e02d48820253833ee/pandas-2.2.1-cp311-cp311-musllinux_1_1_aarch64.whl",hashes = {sha256 = "7d2ed41c319c9fb4fd454fe25372028dfa417aacb9790f68171b2e3f06eae8cd"}}, - {name = "pandas-2.2.1-cp311-cp311-musllinux_1_1_x86_64.whl",url = "https://files.pythonhosted.org/packages/e0/c3/da6ffa0d3d510c378f6e46496cf7f84f35e15836d0de4e9880f40247eb60/pandas-2.2.1-cp311-cp311-musllinux_1_1_x86_64.whl",hashes = {sha256 = "af5d3c00557d657c8773ef9ee702c61dd13b9d7426794c9dfeb1dc4a0bf0ebc7"}}, - {name = "pandas-2.2.1-cp311-cp311-win_amd64.whl",url = "https://files.pythonhosted.org/packages/61/11/1812ef6cbd7433ad240f72161ce5f84c4c450cede4db080365d371d29117/pandas-2.2.1-cp311-cp311-win_amd64.whl",hashes = {sha256 = "06cf591dbaefb6da9de8472535b185cba556d0ce2e6ed28e21d919704fef1a9e"}}, -] -marker = "\"default\" in dependency_groups" - -[packages.tool.pdm] -dependencies = [ - "numpy<2,>=1.22.4; python_version < \"3.11\"", - "numpy<2,>=1.23.2; python_version == \"3.11\"", - "numpy<2,>=1.26.0; python_version >= \"3.12\"", - "python-dateutil>=2.8.2", - "pytz>=2020.1", - "tzdata>=2022.7", -] - -[[packages]] -name = "pandocfilters" -version = "1.5.1" -requires-python = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" -sdist = {name = "pandocfilters-1.5.1.tar.gz", url = "https://files.pythonhosted.org/packages/70/6f/3dd4940bbe001c06a65f88e36bad298bc7a0de5036115639926b0c5c0458/pandocfilters-1.5.1.tar.gz", hashes = {sha256 = "002b4a555ee4ebc03f8b66307e287fa492e4a77b4ea14d3f934328297bb4939e"}} -wheels = [ - {name = "pandocfilters-1.5.1-py2.py3-none-any.whl",url = "https://files.pythonhosted.org/packages/ef/af/4fbc8cab944db5d21b7e2a5b8e9211a03a79852b1157e2c102fcc61ac440/pandocfilters-1.5.1-py2.py3-none-any.whl",hashes = {sha256 = "93be382804a9cdb0a7267585f157e5d1731bbe5545a85b268d6f5fe6232de2bc"}}, -] -marker = "\"docs\" in extras" - -[packages.tool.pdm] -dependencies = [] - -[[packages]] -name = "parso" -version = "0.8.6" -requires-python = ">=3.6" -sdist = {name = "parso-0.8.6.tar.gz", url = "https://files.pythonhosted.org/packages/81/76/a1e769043c0c0c9fe391b702539d594731a4362334cdf4dc25d0c09761e7/parso-0.8.6.tar.gz", hashes = {sha256 = "2b9a0332696df97d454fa67b81618fd69c35a7b90327cbe6ba5c92d2c68a7bfd"}} -wheels = [ - {name = "parso-0.8.6-py2.py3-none-any.whl",url = "https://files.pythonhosted.org/packages/b6/61/fae042894f4296ec49e3f193aff5d7c18440da9e48102c3315e1bc4519a7/parso-0.8.6-py2.py3-none-any.whl",hashes = {sha256 = "2c549f800b70a5c4952197248825584cb00f033b29c692671d3bf08bf380baff"}}, -] -marker = "\"docs\" in extras" - -[packages.tool.pdm] -dependencies = [] - -[[packages]] -name = "patsy" -version = "1.0.2" -requires-python = ">=3.6" -sdist = {name = "patsy-1.0.2.tar.gz", url = "https://files.pythonhosted.org/packages/be/44/ed13eccdd0519eff265f44b670d46fbb0ec813e2274932dc1c0e48520f7d/patsy-1.0.2.tar.gz", hashes = {sha256 = "cdc995455f6233e90e22de72c37fcadb344e7586fb83f06696f54d92f8ce74c0"}} -wheels = [ - {name = "patsy-1.0.2-py2.py3-none-any.whl",url = "https://files.pythonhosted.org/packages/f1/70/ba4b949bdc0490ab78d545459acd7702b211dfccf7eb89bbc1060f52818d/patsy-1.0.2-py2.py3-none-any.whl",hashes = {sha256 = "37bfddbc58fcf0362febb5f54f10743f8b21dd2aa73dec7e7ef59d1b02ae668a"}}, -] -marker = "\"default\" in dependency_groups" - -[packages.tool.pdm] -dependencies = [ - "numpy>=1.4", -] - -[[packages]] -name = "pexpect" -version = "4.9.0" -sdist = {name = "pexpect-4.9.0.tar.gz", url = "https://files.pythonhosted.org/packages/42/92/cc564bf6381ff43ce1f4d06852fc19a2f11d180f23dc32d9588bee2f149d/pexpect-4.9.0.tar.gz", hashes = {sha256 = "ee7d41123f3c9911050ea2c2dac107568dc43b2d3b0c7557a33212c398ead30f"}} -wheels = [ - {name = "pexpect-4.9.0-py2.py3-none-any.whl",url = "https://files.pythonhosted.org/packages/9e/c3/059298687310d527a58bb01f3b1965787ee3b40dce76752eda8b44e9a2c5/pexpect-4.9.0-py2.py3-none-any.whl",hashes = {sha256 = "7236d1e080e4936be2dc3e326cec0af72acf9212a7e1d060210e70a47e253523"}}, -] -marker = "(sys_platform != \"win32\" and sys_platform != \"emscripten\") and \"docs\" in extras" - -[packages.tool.pdm] -dependencies = [ - "ptyprocess>=0.5", -] - -[[packages]] -name = "pillow" -version = "12.2.0" -requires-python = ">=3.10" -sdist = {name = "pillow-12.2.0.tar.gz", url = "https://files.pythonhosted.org/packages/8c/21/c2bcdd5906101a30244eaffc1b6e6ce71a31bd0742a01eb89e660ebfac2d/pillow-12.2.0.tar.gz", hashes = {sha256 = "a830b1a40919539d07806aa58e1b114df53ddd43213d9c8b75847eee6c0182b5"}} -wheels = [ - {name = "pillow-12.2.0-cp314-cp314-ios_13_0_arm64_iphoneos.whl",url = "https://files.pythonhosted.org/packages/bf/98/4595daa2365416a86cb0d495248a393dfc84e96d62ad080c8546256cb9c0/pillow-12.2.0-cp314-cp314-ios_13_0_arm64_iphoneos.whl",hashes = {sha256 = "3adc9215e8be0448ed6e814966ecf3d9952f0ea40eb14e89a102b87f450660d8"}}, - {name = "pillow-12.2.0-cp314-cp314-ios_13_0_arm64_iphonesimulator.whl",url = "https://files.pythonhosted.org/packages/0b/79/40184d464cf89f6663e18dfcf7ca21aae2491fff1a16127681bf1fa9b8cf/pillow-12.2.0-cp314-cp314-ios_13_0_arm64_iphonesimulator.whl",hashes = {sha256 = "6a9adfc6d24b10f89588096364cc726174118c62130c817c2837c60cf08a392b"}}, - {name = "pillow-12.2.0-cp314-cp314-ios_13_0_x86_64_iphonesimulator.whl",url = "https://files.pythonhosted.org/packages/b0/63/703f86fd4c422a9cf722833670f4f71418fb116b2853ff7da722ea43f184/pillow-12.2.0-cp314-cp314-ios_13_0_x86_64_iphonesimulator.whl",hashes = {sha256 = "6a6e67ea2e6feda684ed370f9a1c52e7a243631c025ba42149a2cc5934dec295"}}, - {name = "pillow-12.2.0-cp314-cp314-macosx_10_15_x86_64.whl",url = "https://files.pythonhosted.org/packages/71/e0/fb22f797187d0be2270f83500aab851536101b254bfa1eae10795709d283/pillow-12.2.0-cp314-cp314-macosx_10_15_x86_64.whl",hashes = {sha256 = "2bb4a8d594eacdfc59d9e5ad972aa8afdd48d584ffd5f13a937a664c3e7db0ed"}}, - {name = "pillow-12.2.0-cp314-cp314-macosx_11_0_arm64.whl",url = "https://files.pythonhosted.org/packages/ba/8c/1a9e46228571de18f8e28f16fabdfc20212a5d019f3e3303452b3f0a580d/pillow-12.2.0-cp314-cp314-macosx_11_0_arm64.whl",hashes = {sha256 = "80b2da48193b2f33ed0c32c38140f9d3186583ce7d516526d462645fd98660ae"}}, - {name = "pillow-12.2.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.whl",url = "https://files.pythonhosted.org/packages/70/62/98f6b7f0c88b9addd0e87c217ded307b36be024d4ff8869a812b241d1345/pillow-12.2.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.whl",hashes = {sha256 = "22db17c68434de69d8ecfc2fe821569195c0c373b25cccb9cbdacf2c6e53c601"}}, - {name = "pillow-12.2.0-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.whl",url = "https://files.pythonhosted.org/packages/5e/03/688747d2e91cfbe0e64f316cd2e8005698f76ada3130d0194664174fa5de/pillow-12.2.0-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.whl",hashes = {sha256 = "7b14cc0106cd9aecda615dd6903840a058b4700fcb817687d0ee4fc8b6e389be"}}, - {name = "pillow-12.2.0-cp314-cp314-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl",url = "https://files.pythonhosted.org/packages/f6/35/577e22b936fcdd66537329b33af0b4ccfefaeabd8aec04b266528cddb33c/pillow-12.2.0-cp314-cp314-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl",hashes = {sha256 = "8cbeb542b2ebc6fcdacabf8aca8c1a97c9b3ad3927d46b8723f9d4f033288a0f"}}, - {name = "pillow-12.2.0-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl",url = "https://files.pythonhosted.org/packages/11/8d/d2532ad2a603ca2b93ad9f5135732124e57811d0168155852f37fbce2458/pillow-12.2.0-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl",hashes = {sha256 = "4bfd07bc812fbd20395212969e41931001fd59eb55a60658b0e5710872e95286"}}, - {name = "pillow-12.2.0-cp314-cp314-musllinux_1_2_aarch64.whl",url = "https://files.pythonhosted.org/packages/5e/26/d325f9f56c7e039034897e7380e9cc202b1e368bfd04d4cbe6a441f02885/pillow-12.2.0-cp314-cp314-musllinux_1_2_aarch64.whl",hashes = {sha256 = "9aba9a17b623ef750a4d11b742cbafffeb48a869821252b30ee21b5e91392c50"}}, - {name = "pillow-12.2.0-cp314-cp314-musllinux_1_2_x86_64.whl",url = "https://files.pythonhosted.org/packages/5f/f7/769d5632ffb0988f1c5e7660b3e731e30f7f8ec4318e94d0a5d674eb65a4/pillow-12.2.0-cp314-cp314-musllinux_1_2_x86_64.whl",hashes = {sha256 = "deede7c263feb25dba4e82ea23058a235dcc2fe1f6021025dc71f2b618e26104"}}, - {name = "pillow-12.2.0-cp314-cp314-win32.whl",url = "https://files.pythonhosted.org/packages/6a/7a/c253e3c645cd47f1aceea6a8bacdba9991bf45bb7dfe927f7c893e89c93c/pillow-12.2.0-cp314-cp314-win32.whl",hashes = {sha256 = "632ff19b2778e43162304d50da0181ce24ac5bb8180122cbe1bf4673428328c7"}}, - {name = "pillow-12.2.0-cp314-cp314-win_amd64.whl",url = "https://files.pythonhosted.org/packages/cd/8b/601e6566b957ca50e28725cb6c355c59c2c8609751efbecd980db44e0349/pillow-12.2.0-cp314-cp314-win_amd64.whl",hashes = {sha256 = "4e6c62e9d237e9b65fac06857d511e90d8461a32adcc1b9065ea0c0fa3a28150"}}, - {name = "pillow-12.2.0-cp314-cp314-win_arm64.whl",url = "https://files.pythonhosted.org/packages/d6/94/220e46c73065c3e2951bb91c11a1fb636c8c9ad427ac3ce7d7f3359b9b2f/pillow-12.2.0-cp314-cp314-win_arm64.whl",hashes = {sha256 = "b1c1fbd8a5a1af3412a0810d060a78b5136ec0836c8a4ef9aa11807f2a22f4e1"}}, - {name = "pillow-12.2.0-cp314-cp314t-macosx_10_15_x86_64.whl",url = "https://files.pythonhosted.org/packages/b6/ab/1b426a3974cb0e7da5c29ccff4807871d48110933a57207b5a676cccc155/pillow-12.2.0-cp314-cp314t-macosx_10_15_x86_64.whl",hashes = {sha256 = "57850958fe9c751670e49b2cecf6294acc99e562531f4bd317fa5ddee2068463"}}, - {name = "pillow-12.2.0-cp314-cp314t-macosx_11_0_arm64.whl",url = "https://files.pythonhosted.org/packages/19/1e/dce46f371be2438eecfee2a1960ee2a243bbe5e961890146d2dee1ff0f12/pillow-12.2.0-cp314-cp314t-macosx_11_0_arm64.whl",hashes = {sha256 = "d5d38f1411c0ed9f97bcb49b7bd59b6b7c314e0e27420e34d99d844b9ce3b6f3"}}, - {name = "pillow-12.2.0-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.whl",url = "https://files.pythonhosted.org/packages/55/c3/7fbecf70adb3a0c33b77a300dc52e424dc22ad8cdc06557a2e49523b703d/pillow-12.2.0-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.whl",hashes = {sha256 = "5c0a9f29ca8e79f09de89293f82fc9b0270bb4af1d58bc98f540cc4aedf03166"}}, - {name = "pillow-12.2.0-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl",url = "https://files.pythonhosted.org/packages/1c/3c/7fbc17cfb7e4fe0ef1642e0abc17fc6c94c9f7a16be41498e12e2ba60408/pillow-12.2.0-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl",hashes = {sha256 = "1610dd6c61621ae1cf811bef44d77e149ce3f7b95afe66a4512f8c59f25d9ebe"}}, - {name = "pillow-12.2.0-cp314-cp314t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl",url = "https://files.pythonhosted.org/packages/ff/c3/a8ae14d6defd2e448493ff512fae903b1e9bd40b72efb6ec55ce0048c8ce/pillow-12.2.0-cp314-cp314t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl",hashes = {sha256 = "0a34329707af4f73cf1782a36cd2289c0368880654a2c11f027bcee9052d35dd"}}, - {name = "pillow-12.2.0-cp314-cp314t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl",url = "https://files.pythonhosted.org/packages/6e/32/2880fb3a074847ac159d8f902cb43278a61e85f681661e7419e6596803ed/pillow-12.2.0-cp314-cp314t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl",hashes = {sha256 = "8e9c4f5b3c546fa3458a29ab22646c1c6c787ea8f5ef51300e5a60300736905e"}}, - {name = "pillow-12.2.0-cp314-cp314t-musllinux_1_2_aarch64.whl",url = "https://files.pythonhosted.org/packages/46/87/495cc9c30e0129501643f24d320076f4cc54f718341df18cc70ec94c44e1/pillow-12.2.0-cp314-cp314t-musllinux_1_2_aarch64.whl",hashes = {sha256 = "fb043ee2f06b41473269765c2feae53fc2e2fbf96e5e22ca94fb5ad677856f06"}}, - {name = "pillow-12.2.0-cp314-cp314t-musllinux_1_2_x86_64.whl",url = "https://files.pythonhosted.org/packages/18/53/773f5edca692009d883a72211b60fdaf8871cbef075eaa9d577f0a2f989e/pillow-12.2.0-cp314-cp314t-musllinux_1_2_x86_64.whl",hashes = {sha256 = "f278f034eb75b4e8a13a54a876cc4a5ab39173d2cdd93a638e1b467fc545ac43"}}, - {name = "pillow-12.2.0-cp314-cp314t-win32.whl",url = "https://files.pythonhosted.org/packages/c9/e4/4b64a97d71b2a83158134abbb2f5bd3f8a2ea691361282f010998f339ec7/pillow-12.2.0-cp314-cp314t-win32.whl",hashes = {sha256 = "6bb77b2dcb06b20f9f4b4a8454caa581cd4dd0643a08bacf821216a16d9c8354"}}, - {name = "pillow-12.2.0-cp314-cp314t-win_amd64.whl",url = "https://files.pythonhosted.org/packages/ba/13/306d275efd3a3453f72114b7431c877d10b1154014c1ebbedd067770d629/pillow-12.2.0-cp314-cp314t-win_amd64.whl",hashes = {sha256 = "6562ace0d3fb5f20ed7290f1f929cae41b25ae29528f2af1722966a0a02e2aa1"}}, - {name = "pillow-12.2.0-cp314-cp314t-win_arm64.whl",url = "https://files.pythonhosted.org/packages/ff/6e/cf826fae916b8658848d7b9f38d88da6396895c676e8086fc0988073aaf8/pillow-12.2.0-cp314-cp314t-win_arm64.whl",hashes = {sha256 = "aa88ccfe4e32d362816319ed727a004423aab09c5cea43c01a4b435643fa34eb"}}, - {name = "pillow-12.2.0-cp313-cp313-ios_13_0_arm64_iphoneos.whl",url = "https://files.pythonhosted.org/packages/4a/01/53d10cf0dbad820a8db274d259a37ba50b88b24768ddccec07355382d5ad/pillow-12.2.0-cp313-cp313-ios_13_0_arm64_iphoneos.whl",hashes = {sha256 = "8297651f5b5679c19968abefd6bb84d95fe30ef712eb1b2d9b2d31ca61267f4c"}}, - {name = "pillow-12.2.0-cp313-cp313-ios_13_0_arm64_iphonesimulator.whl",url = "https://files.pythonhosted.org/packages/0f/98/f3a6657ecb698c937f6c76ee564882945f29b79bad496abcba0e84659ec5/pillow-12.2.0-cp313-cp313-ios_13_0_arm64_iphonesimulator.whl",hashes = {sha256 = "50d8520da2a6ce0af445fa6d648c4273c3eeefbc32d7ce049f22e8b5c3daecc2"}}, - {name = "pillow-12.2.0-cp313-cp313-ios_13_0_x86_64_iphonesimulator.whl",url = "https://files.pythonhosted.org/packages/69/bc/8986948f05e3ea490b8442ea1c1d4d990b24a7e43d8a51b2c7d8b1dced36/pillow-12.2.0-cp313-cp313-ios_13_0_x86_64_iphonesimulator.whl",hashes = {sha256 = "766cef22385fa1091258ad7e6216792b156dc16d8d3fa607e7545b2b72061f1c"}}, - {name = "pillow-12.2.0-cp313-cp313-macosx_10_13_x86_64.whl",url = "https://files.pythonhosted.org/packages/34/46/6c717baadcd62bc8ed51d238d521ab651eaa74838291bda1f86fe1f864c9/pillow-12.2.0-cp313-cp313-macosx_10_13_x86_64.whl",hashes = {sha256 = "5d2fd0fa6b5d9d1de415060363433f28da8b1526c1c129020435e186794b3795"}}, - {name = "pillow-12.2.0-cp313-cp313-macosx_11_0_arm64.whl",url = "https://files.pythonhosted.org/packages/71/43/905a14a8b17fdb1ccb58d282454490662d2cb89a6bfec26af6d3520da5ec/pillow-12.2.0-cp313-cp313-macosx_11_0_arm64.whl",hashes = {sha256 = "56b25336f502b6ed02e889f4ece894a72612fe885889a6e8c4c80239ff6e5f5f"}}, - {name = "pillow-12.2.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.whl",url = "https://files.pythonhosted.org/packages/73/dd/42107efcb777b16fa0393317eac58f5b5cf30e8392e266e76e51cff28c3d/pillow-12.2.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.whl",hashes = {sha256 = "f1c943e96e85df3d3478f7b691f229887e143f81fedab9b20205349ab04d73ed"}}, - {name = "pillow-12.2.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl",url = "https://files.pythonhosted.org/packages/a8/68/b93e09e5e8549019e61acf49f65b1a8530765a7f812c77a7461bca7e4494/pillow-12.2.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl",hashes = {sha256 = "03f6fab9219220f041c74aeaa2939ff0062bd5c364ba9ce037197f4c6d498cd9"}}, - {name = "pillow-12.2.0-cp313-cp313-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl",url = "https://files.pythonhosted.org/packages/4b/6e/3ccb54ce8ec4ddd1accd2d89004308b7b0b21c4ac3d20fa70af4760a4330/pillow-12.2.0-cp313-cp313-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl",hashes = {sha256 = "5cdfebd752ec52bf5bb4e35d9c64b40826bc5b40a13df7c3cda20a2c03a0f5ed"}}, - {name = "pillow-12.2.0-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl",url = "https://files.pythonhosted.org/packages/67/ee/21d4e8536afd1a328f01b359b4d3997b291ffd35a237c877b331c1c3b71c/pillow-12.2.0-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl",hashes = {sha256 = "eedf4b74eda2b5a4b2b2fb4c006d6295df3bf29e459e198c90ea48e130dc75c3"}}, - {name = "pillow-12.2.0-cp313-cp313-musllinux_1_2_aarch64.whl",url = "https://files.pythonhosted.org/packages/78/5f/e9f86ab0146464e8c133fe85df987ed9e77e08b29d8d35f9f9f4d6f917ba/pillow-12.2.0-cp313-cp313-musllinux_1_2_aarch64.whl",hashes = {sha256 = "00a2865911330191c0b818c59103b58a5e697cae67042366970a6b6f1b20b7f9"}}, - {name = "pillow-12.2.0-cp313-cp313-musllinux_1_2_x86_64.whl",url = "https://files.pythonhosted.org/packages/ed/1e/409007f56a2fdce61584fd3acbc2bbc259857d555196cedcadc68c015c82/pillow-12.2.0-cp313-cp313-musllinux_1_2_x86_64.whl",hashes = {sha256 = "1e1757442ed87f4912397c6d35a0db6a7b52592156014706f17658ff58bbf795"}}, - {name = "pillow-12.2.0-cp313-cp313-win32.whl",url = "https://files.pythonhosted.org/packages/23/c4/7349421080b12fb35414607b8871e9534546c128a11965fd4a7002ccfbee/pillow-12.2.0-cp313-cp313-win32.whl",hashes = {sha256 = "144748b3af2d1b358d41286056d0003f47cb339b8c43a9ea42f5fea4d8c66b6e"}}, - {name = "pillow-12.2.0-cp313-cp313-win_amd64.whl",url = "https://files.pythonhosted.org/packages/3f/82/8a3739a5e470b3c6cbb1d21d315800d8e16bff503d1f16b03a4ec3212786/pillow-12.2.0-cp313-cp313-win_amd64.whl",hashes = {sha256 = "390ede346628ccc626e5730107cde16c42d3836b89662a115a921f28440e6a3b"}}, - {name = "pillow-12.2.0-cp313-cp313-win_arm64.whl",url = "https://files.pythonhosted.org/packages/c3/25/f968f618a062574294592f668218f8af564830ccebdd1fa6200f598e65c5/pillow-12.2.0-cp313-cp313-win_arm64.whl",hashes = {sha256 = "8023abc91fba39036dbce14a7d6535632f99c0b857807cbbbf21ecc9f4717f06"}}, - {name = "pillow-12.2.0-cp313-cp313t-macosx_10_13_x86_64.whl",url = "https://files.pythonhosted.org/packages/4d/a4/b342930964e3cb4dce5038ae34b0eab4653334995336cd486c5a8c25a00c/pillow-12.2.0-cp313-cp313t-macosx_10_13_x86_64.whl",hashes = {sha256 = "042db20a421b9bafecc4b84a8b6e444686bd9d836c7fd24542db3e7df7baad9b"}}, - {name = "pillow-12.2.0-cp313-cp313t-macosx_11_0_arm64.whl",url = "https://files.pythonhosted.org/packages/9f/de/23198e0a65a9cf06123f5435a5d95cea62a635697f8f03d134d3f3a96151/pillow-12.2.0-cp313-cp313t-macosx_11_0_arm64.whl",hashes = {sha256 = "dd025009355c926a84a612fecf58bb315a3f6814b17ead51a8e48d3823d9087f"}}, - {name = "pillow-12.2.0-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.whl",url = "https://files.pythonhosted.org/packages/01/a6/1265e977f17d93ea37aa28aa81bad4fa597933879fac2520d24e021c8da3/pillow-12.2.0-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.whl",hashes = {sha256 = "88ddbc66737e277852913bd1e07c150cc7bb124539f94c4e2df5344494e0a612"}}, - {name = "pillow-12.2.0-cp313-cp313t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl",url = "https://files.pythonhosted.org/packages/3c/83/5982eb4a285967baa70340320be9f88e57665a387e3a53a7f0db8231a0cd/pillow-12.2.0-cp313-cp313t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl",hashes = {sha256 = "d362d1878f00c142b7e1a16e6e5e780f02be8195123f164edf7eddd911eefe7c"}}, - {name = "pillow-12.2.0-cp313-cp313t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl",url = "https://files.pythonhosted.org/packages/4e/48/6ffc514adce69f6050d0753b1a18fd920fce8cac87620d5a31231b04bfc5/pillow-12.2.0-cp313-cp313t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl",hashes = {sha256 = "2c727a6d53cb0018aadd8018c2b938376af27914a68a492f59dfcaca650d5eea"}}, - {name = "pillow-12.2.0-cp313-cp313t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl",url = "https://files.pythonhosted.org/packages/36/a3/f9a77144231fb8d40ee27107b4463e205fa4677e2ca2548e14da5cf18dce/pillow-12.2.0-cp313-cp313t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl",hashes = {sha256 = "efd8c21c98c5cc60653bcb311bef2ce0401642b7ce9d09e03a7da87c878289d4"}}, - {name = "pillow-12.2.0-cp313-cp313t-musllinux_1_2_aarch64.whl",url = "https://files.pythonhosted.org/packages/c1/fc/ac4ee3041e7d5a565e1c4fd72a113f03b6394cc72ab7089d27608f8aaccb/pillow-12.2.0-cp313-cp313t-musllinux_1_2_aarch64.whl",hashes = {sha256 = "9f08483a632889536b8139663db60f6724bfcb443c96f1b18855860d7d5c0fd4"}}, - {name = "pillow-12.2.0-cp313-cp313t-musllinux_1_2_x86_64.whl",url = "https://files.pythonhosted.org/packages/c0/a8/27fb307055087f3668f6d0a8ccb636e7431d56ed0750e07a60547b1e083e/pillow-12.2.0-cp313-cp313t-musllinux_1_2_x86_64.whl",hashes = {sha256 = "dac8d77255a37e81a2efcbd1fc05f1c15ee82200e6c240d7e127e25e365c39ea"}}, - {name = "pillow-12.2.0-cp313-cp313t-win32.whl",url = "https://files.pythonhosted.org/packages/ad/4b/926ab182c07fccae9fcb120043464e1ff1564775ec8864f21a0ebce6ac25/pillow-12.2.0-cp313-cp313t-win32.whl",hashes = {sha256 = "ee3120ae9dff32f121610bb08e4313be87e03efeadfc6c0d18f89127e24d0c24"}}, - {name = "pillow-12.2.0-cp313-cp313t-win_amd64.whl",url = "https://files.pythonhosted.org/packages/c2/c4/f9e476451a098181b30050cc4c9a3556b64c02cf6497ea421ac047e89e4b/pillow-12.2.0-cp313-cp313t-win_amd64.whl",hashes = {sha256 = "325ca0528c6788d2a6c3d40e3568639398137346c3d6e66bb61db96b96511c98"}}, - {name = "pillow-12.2.0-cp313-cp313t-win_arm64.whl",url = "https://files.pythonhosted.org/packages/00/a4/285f12aeacbe2d6dc36c407dfbbe9e96d4a80b0fb710a337f6d2ad978c75/pillow-12.2.0-cp313-cp313t-win_arm64.whl",hashes = {sha256 = "2e5a76d03a6c6dcef67edabda7a52494afa4035021a79c8558e14af25313d453"}}, - {name = "pillow-12.2.0-cp312-cp312-macosx_10_13_x86_64.whl",url = "https://files.pythonhosted.org/packages/58/be/7482c8a5ebebbc6470b3eb791812fff7d5e0216c2be3827b30b8bb6603ed/pillow-12.2.0-cp312-cp312-macosx_10_13_x86_64.whl",hashes = {sha256 = "2d192a155bbcec180f8564f693e6fd9bccff5a7af9b32e2e4bf8c9c69dbad6b5"}}, - {name = "pillow-12.2.0-cp312-cp312-macosx_11_0_arm64.whl",url = "https://files.pythonhosted.org/packages/d8/95/0a351b9289c2b5cbde0bacd4a83ebc44023e835490a727b2a3bd60ddc0f4/pillow-12.2.0-cp312-cp312-macosx_11_0_arm64.whl",hashes = {sha256 = "f3f40b3c5a968281fd507d519e444c35f0ff171237f4fdde090dd60699458421"}}, - {name = "pillow-12.2.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.whl",url = "https://files.pythonhosted.org/packages/de/af/4e8e6869cbed569d43c416fad3dc4ecb944cb5d9492defaed89ddd6fe871/pillow-12.2.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.whl",hashes = {sha256 = "03e7e372d5240cc23e9f07deca4d775c0817bffc641b01e9c3af208dbd300987"}}, - {name = "pillow-12.2.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl",url = "https://files.pythonhosted.org/packages/e9/9e/c05e19657fd57841e476be1ab46c4d501bffbadbafdc31a6d665f8b737b6/pillow-12.2.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl",hashes = {sha256 = "b86024e52a1b269467a802258c25521e6d742349d760728092e1bc2d135b4d76"}}, - {name = "pillow-12.2.0-cp312-cp312-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl",url = "https://files.pythonhosted.org/packages/2b/54/1789c455ed10176066b6e7e6da1b01e50e36f94ba584dc68d9eebfe9156d/pillow-12.2.0-cp312-cp312-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl",hashes = {sha256 = "7371b48c4fa448d20d2714c9a1f775a81155050d383333e0a6c15b1123dda005"}}, - {name = "pillow-12.2.0-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl",url = "https://files.pythonhosted.org/packages/43/e3/fdc657359e919462369869f1c9f0e973f353f9a9ee295a39b1fea8ee1a77/pillow-12.2.0-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl",hashes = {sha256 = "62f5409336adb0663b7caa0da5c7d9e7bdbaae9ce761d34669420c2a801b2780"}}, - {name = "pillow-12.2.0-cp312-cp312-musllinux_1_2_aarch64.whl",url = "https://files.pythonhosted.org/packages/8b/f8/2f6825e441d5b1959d2ca5adec984210f1ec086435b0ed5f52c19b3b8a6e/pillow-12.2.0-cp312-cp312-musllinux_1_2_aarch64.whl",hashes = {sha256 = "01afa7cf67f74f09523699b4e88c73fb55c13346d212a59a2db1f86b0a63e8c5"}}, - {name = "pillow-12.2.0-cp312-cp312-musllinux_1_2_x86_64.whl",url = "https://files.pythonhosted.org/packages/67/f9/029a27095ad20f854f9dba026b3ea6428548316e057e6fc3545409e86651/pillow-12.2.0-cp312-cp312-musllinux_1_2_x86_64.whl",hashes = {sha256 = "fc3d34d4a8fbec3e88a79b92e5465e0f9b842b628675850d860b8bd300b159f5"}}, - {name = "pillow-12.2.0-cp312-cp312-win32.whl",url = "https://files.pythonhosted.org/packages/be/42/025cfe05d1be22dbfdb4f264fe9de1ccda83f66e4fc3aac94748e784af04/pillow-12.2.0-cp312-cp312-win32.whl",hashes = {sha256 = "58f62cc0f00fd29e64b29f4fd923ffdb3859c9f9e6105bfc37ba1d08994e8940"}}, - {name = "pillow-12.2.0-cp312-cp312-win_amd64.whl",url = "https://files.pythonhosted.org/packages/5d/7b/25a221d2c761c6a8ae21bfa3874988ff2583e19cf8a27bf2fee358df7942/pillow-12.2.0-cp312-cp312-win_amd64.whl",hashes = {sha256 = "7f84204dee22a783350679a0333981df803dac21a0190d706a50475e361c93f5"}}, - {name = "pillow-12.2.0-cp312-cp312-win_arm64.whl",url = "https://files.pythonhosted.org/packages/10/e1/542a474affab20fd4a0f1836cb234e8493519da6b76899e30bcc5d990b8b/pillow-12.2.0-cp312-cp312-win_arm64.whl",hashes = {sha256 = "af73337013e0b3b46f175e79492d96845b16126ddf79c438d7ea7ff27783a414"}}, - {name = "pillow-12.2.0-cp311-cp311-macosx_10_10_x86_64.whl",url = "https://files.pythonhosted.org/packages/68/e1/748f5663efe6edcfc4e74b2b93edfb9b8b99b67f21a854c3ae416500a2d9/pillow-12.2.0-cp311-cp311-macosx_10_10_x86_64.whl",hashes = {sha256 = "8be29e59487a79f173507c30ddf57e733a357f67881430449bb32614075a40ab"}}, - {name = "pillow-12.2.0-cp311-cp311-macosx_11_0_arm64.whl",url = "https://files.pythonhosted.org/packages/47/a1/d5ff69e747374c33a3b53b9f98cca7889fce1fd03d79cdc4e1bccc6c5a87/pillow-12.2.0-cp311-cp311-macosx_11_0_arm64.whl",hashes = {sha256 = "71cde9a1e1551df7d34a25462fc60325e8a11a82cc2e2f54578e5e9a1e153d65"}}, - {name = "pillow-12.2.0-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.whl",url = "https://files.pythonhosted.org/packages/df/21/e3fbdf54408a973c7f7f89a23b2cb97a7ef30c61ab4142af31eee6aebc88/pillow-12.2.0-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.whl",hashes = {sha256 = "f490f9368b6fc026f021db16d7ec2fbf7d89e2edb42e8ec09d2c60505f5729c7"}}, - {name = "pillow-12.2.0-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl",url = "https://files.pythonhosted.org/packages/d3/f1/00b7278c7dd52b17ad4329153748f87b6756ec195ff786c2bdf12518337d/pillow-12.2.0-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl",hashes = {sha256 = "8bd7903a5f2a4545f6fd5935c90058b89d30045568985a71c79f5fd6edf9b91e"}}, - {name = "pillow-12.2.0-cp311-cp311-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl",url = "https://files.pythonhosted.org/packages/ad/cf/220a5994ef1b10e70e85748b75649d77d506499352be135a4989c957b701/pillow-12.2.0-cp311-cp311-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl",hashes = {sha256 = "3997232e10d2920a68d25191392e3a4487d8183039e1c74c2297f00ed1c50705"}}, - {name = "pillow-12.2.0-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl",url = "https://files.pythonhosted.org/packages/e9/bd/e51a61b1054f09437acfbc2ff9106c30d1eb76bc1453d428399946781253/pillow-12.2.0-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl",hashes = {sha256 = "e74473c875d78b8e9d5da2a70f7099549f9eb37ded4e2f6a463e60125bccd176"}}, - {name = "pillow-12.2.0-cp311-cp311-musllinux_1_2_aarch64.whl",url = "https://files.pythonhosted.org/packages/6b/3d/45132c57d5fb4b5744567c3817026480ac7fc3ce5d4c47902bc0e7f6f853/pillow-12.2.0-cp311-cp311-musllinux_1_2_aarch64.whl",hashes = {sha256 = "56a3f9c60a13133a98ecff6197af34d7824de9b7b38c3654861a725c970c197b"}}, - {name = "pillow-12.2.0-cp311-cp311-musllinux_1_2_x86_64.whl",url = "https://files.pythonhosted.org/packages/7d/2e/9df2fc1e82097b1df3dce58dc43286aa01068e918c07574711fcc53e6fb4/pillow-12.2.0-cp311-cp311-musllinux_1_2_x86_64.whl",hashes = {sha256 = "90e6f81de50ad6b534cab6e5aef77ff6e37722b2f5d908686f4a5c9eba17a909"}}, - {name = "pillow-12.2.0-cp311-cp311-win32.whl",url = "https://files.pythonhosted.org/packages/bd/2e/2941e42858ebb67e50ae741473de81c2984e6eff7b397017623c676e2e8d/pillow-12.2.0-cp311-cp311-win32.whl",hashes = {sha256 = "8c984051042858021a54926eb597d6ee3012393ce9c181814115df4c60b9a808"}}, - {name = "pillow-12.2.0-cp311-cp311-win_amd64.whl",url = "https://files.pythonhosted.org/packages/69/42/836b6f3cd7f3e5fa10a1f1a5420447c17966044c8fbf589cc0452d5502db/pillow-12.2.0-cp311-cp311-win_amd64.whl",hashes = {sha256 = "6e6b2a0c538fc200b38ff9eb6628228b77908c319a005815f2dde585a0664b60"}}, - {name = "pillow-12.2.0-cp311-cp311-win_arm64.whl",url = "https://files.pythonhosted.org/packages/c2/88/549194b5d6f1f494b485e493edc6693c0a16f4ada488e5bd974ed1f42fad/pillow-12.2.0-cp311-cp311-win_arm64.whl",hashes = {sha256 = "9a8a34cc89c67a65ea7437ce257cea81a9dad65b29805f3ecee8c8fe8ff25ffe"}}, - {name = "pillow-12.2.0-pp311-pypy311_pp73-macosx_10_15_x86_64.whl",url = "https://files.pythonhosted.org/packages/4e/b7/2437044fb910f499610356d1352e3423753c98e34f915252aafecc64889f/pillow-12.2.0-pp311-pypy311_pp73-macosx_10_15_x86_64.whl",hashes = {sha256 = "0538bd5e05efec03ae613fd89c4ce0368ecd2ba239cc25b9f9be7ed426b0af1f"}}, - {name = "pillow-12.2.0-pp311-pypy311_pp73-macosx_11_0_arm64.whl",url = "https://files.pythonhosted.org/packages/f6/f4/8316e31de11b780f4ac08ef3654a75555e624a98db1056ecb2122d008d5a/pillow-12.2.0-pp311-pypy311_pp73-macosx_11_0_arm64.whl",hashes = {sha256 = "394167b21da716608eac917c60aa9b969421b5dcbbe02ae7f013e7b85811c69d"}}, - {name = "pillow-12.2.0-pp311-pypy311_pp73-manylinux2014_aarch64.manylinux_2_17_aarch64.whl",url = "https://files.pythonhosted.org/packages/d4/37/664fca7201f8bb2aa1d20e2c3d5564a62e6ae5111741966c8319ca802361/pillow-12.2.0-pp311-pypy311_pp73-manylinux2014_aarch64.manylinux_2_17_aarch64.whl",hashes = {sha256 = "5d04bfa02cc2d23b497d1e90a0f927070043f6cbf303e738300532379a4b4e0f"}}, - {name = "pillow-12.2.0-pp311-pypy311_pp73-manylinux2014_x86_64.manylinux_2_17_x86_64.whl",url = "https://files.pythonhosted.org/packages/49/62/5b0ed78fce87346be7a5cfcfaaad91f6a1f98c26f86bdbafa2066c647ef6/pillow-12.2.0-pp311-pypy311_pp73-manylinux2014_x86_64.manylinux_2_17_x86_64.whl",hashes = {sha256 = "0c838a5125cee37e68edec915651521191cef1e6aa336b855f495766e77a366e"}}, - {name = "pillow-12.2.0-pp311-pypy311_pp73-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl",url = "https://files.pythonhosted.org/packages/c3/28/ec0fc38107fc32536908034e990c47914c57cd7c5a3ece4d8d8f7ffd7e27/pillow-12.2.0-pp311-pypy311_pp73-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl",hashes = {sha256 = "4a6c9fa44005fa37a91ebfc95d081e8079757d2e904b27103f4f5fa6f0bf78c0"}}, - {name = "pillow-12.2.0-pp311-pypy311_pp73-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl",url = "https://files.pythonhosted.org/packages/5e/8b/51b0eddcfa2180d60e41f06bd6d0a62202b20b59c68f5a132e615b75aecf/pillow-12.2.0-pp311-pypy311_pp73-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl",hashes = {sha256 = "25373b66e0dd5905ed63fa3cae13c82fbddf3079f2c8bf15c6fb6a35586324c1"}}, - {name = "pillow-12.2.0-pp311-pypy311_pp73-win_amd64.whl",url = "https://files.pythonhosted.org/packages/bc/60/5382c03e1970de634027cee8e1b7d39776b778b81812aaf45b694dfe9e28/pillow-12.2.0-pp311-pypy311_pp73-win_amd64.whl",hashes = {sha256 = "bfa9c230d2fe991bed5318a5f119bd6780cda2915cca595393649fc118ab895e"}}, -] -marker = "\"default\" in dependency_groups or \"docs\" in extras" - -[packages.tool.pdm] -dependencies = [] - -[[packages]] -name = "platformdirs" -version = "4.9.6" -requires-python = ">=3.10" -sdist = {name = "platformdirs-4.9.6.tar.gz", url = "https://files.pythonhosted.org/packages/9f/4a/0883b8e3802965322523f0b200ecf33d31f10991d0401162f4b23c698b42/platformdirs-4.9.6.tar.gz", hashes = {sha256 = "3bfa75b0ad0db84096ae777218481852c0ebc6c727b3168c1b9e0118e458cf0a"}} -wheels = [ - {name = "platformdirs-4.9.6-py3-none-any.whl",url = "https://files.pythonhosted.org/packages/75/a6/a0a304dc33b49145b21f4808d763822111e67d1c3a32b524a1baf947b6e1/platformdirs-4.9.6-py3-none-any.whl",hashes = {sha256 = "e61adb1d5e5cb3441b4b7710bea7e4c12250ca49439228cc1021c00dcfac0917"}}, -] -marker = "\"docs\" in extras" - -[packages.tool.pdm] -dependencies = [] - -[[packages]] -name = "plotly" -version = "6.1.1" -requires-python = ">=3.8" -sdist = {name = "plotly-6.1.1.tar.gz", url = "https://files.pythonhosted.org/packages/8a/7c/f396bc817975252afbe7af102ce09cd12ac40a8e90b8699a857d1b15c8a3/plotly-6.1.1.tar.gz", hashes = {sha256 = "84a4f3d36655f1328fa3155377c7e8a9533196697d5b79a4bc5e905bdd09a433"}} -wheels = [ - {name = "plotly-6.1.1-py3-none-any.whl",url = "https://files.pythonhosted.org/packages/75/f3/f8cb7066f761e2530e1280889e3413769891e349fca35ee7290e4ace35f5/plotly-6.1.1-py3-none-any.whl",hashes = {sha256 = "9cca7167406ebf7ff541422738402159ec3621a608ff7b3e2f025573a1c76225"}}, -] -marker = "\"default\" in dependency_groups" - -[packages.tool.pdm] -dependencies = [ - "narwhals>=1.15.1", - "packaging", -] - -[[packages]] -name = "pluggy" -version = "1.6.0" -requires-python = ">=3.9" -sdist = {name = "pluggy-1.6.0.tar.gz", url = "https://files.pythonhosted.org/packages/f9/e2/3e91f31a7d2b083fe6ef3fa267035b518369d9511ffab804f839851d2779/pluggy-1.6.0.tar.gz", hashes = {sha256 = "7dcc130b76258d33b90f61b658791dede3486c3e6bfb003ee5c9bfb396dd22f3"}} -wheels = [ - {name = "pluggy-1.6.0-py3-none-any.whl",url = "https://files.pythonhosted.org/packages/54/20/4d324d65cc6d9205fabedc306948156824eb9f0ee1633355a8f7ec5c66bf/pluggy-1.6.0-py3-none-any.whl",hashes = {sha256 = "e920276dd6813095e9377c0bc5566d94c932c33b27a3e3945d8389c374dd4746"}}, -] -marker = "\"test\" in extras" - -[packages.tool.pdm] -dependencies = [] - -[[packages]] -name = "prompt-toolkit" -version = "3.0.52" -requires-python = ">=3.8" -sdist = {name = "prompt_toolkit-3.0.52.tar.gz", url = "https://files.pythonhosted.org/packages/a1/96/06e01a7b38dce6fe1db213e061a4602dd6032a8a97ef6c1a862537732421/prompt_toolkit-3.0.52.tar.gz", hashes = {sha256 = "28cde192929c8e7321de85de1ddbe736f1375148b02f2e17edd840042b1be855"}} -wheels = [ - {name = "prompt_toolkit-3.0.52-py3-none-any.whl",url = "https://files.pythonhosted.org/packages/84/03/0d3ce49e2505ae70cf43bc5bb3033955d2fc9f932163e84dc0779cc47f48/prompt_toolkit-3.0.52-py3-none-any.whl",hashes = {sha256 = "9aac639a3bbd33284347de5ad8d68ecc044b91a762dc39b7c21095fcd6a19955"}}, -] -marker = "\"docs\" in extras" - -[packages.tool.pdm] -dependencies = [ - "wcwidth", -] - -[[packages]] -name = "psutil" -version = "7.2.2" -requires-python = ">=3.6" -sdist = {name = "psutil-7.2.2.tar.gz", url = "https://files.pythonhosted.org/packages/aa/c6/d1ddf4abb55e93cebc4f2ed8b5d6dbad109ecb8d63748dd2b20ab5e57ebe/psutil-7.2.2.tar.gz", hashes = {sha256 = "0746f5f8d406af344fd547f1c8daa5f5c33dbc293bb8d6a16d80b4bb88f59372"}} -wheels = [ - {name = "psutil-7.2.2-cp314-cp314t-macosx_10_15_x86_64.whl",url = "https://files.pythonhosted.org/packages/81/69/ef179ab5ca24f32acc1dac0c247fd6a13b501fd5534dbae0e05a1c48b66d/psutil-7.2.2-cp314-cp314t-macosx_10_15_x86_64.whl",hashes = {sha256 = "eed63d3b4d62449571547b60578c5b2c4bcccc5387148db46e0c2313dad0ee00"}}, - {name = "psutil-7.2.2-cp314-cp314t-macosx_11_0_arm64.whl",url = "https://files.pythonhosted.org/packages/7b/64/665248b557a236d3fa9efc378d60d95ef56dd0a490c2cd37dafc7660d4a9/psutil-7.2.2-cp314-cp314t-macosx_11_0_arm64.whl",hashes = {sha256 = "7b6d09433a10592ce39b13d7be5a54fbac1d1228ed29abc880fb23df7cb694c9"}}, - {name = "psutil-7.2.2-cp314-cp314t-manylinux2010_x86_64.manylinux_2_12_x86_64.manylinux_2_28_x86_64.whl",url = "https://files.pythonhosted.org/packages/d5/2e/e6782744700d6759ebce3043dcfa661fb61e2fb752b91cdeae9af12c2178/psutil-7.2.2-cp314-cp314t-manylinux2010_x86_64.manylinux_2_12_x86_64.manylinux_2_28_x86_64.whl",hashes = {sha256 = "1fa4ecf83bcdf6e6c8f4449aff98eefb5d0604bf88cb883d7da3d8d2d909546a"}}, - {name = "psutil-7.2.2-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl",url = "https://files.pythonhosted.org/packages/57/49/0a41cefd10cb7505cdc04dab3eacf24c0c2cb158a998b8c7b1d27ee2c1f5/psutil-7.2.2-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl",hashes = {sha256 = "e452c464a02e7dc7822a05d25db4cde564444a67e58539a00f929c51eddda0cf"}}, - {name = "psutil-7.2.2-cp314-cp314t-win_amd64.whl",url = "https://files.pythonhosted.org/packages/dd/2c/ff9bfb544f283ba5f83ba725a3c5fec6d6b10b8f27ac1dc641c473dc390d/psutil-7.2.2-cp314-cp314t-win_amd64.whl",hashes = {sha256 = "c7663d4e37f13e884d13994247449e9f8f574bc4655d509c3b95e9ec9e2b9dc1"}}, - {name = "psutil-7.2.2-cp314-cp314t-win_arm64.whl",url = "https://files.pythonhosted.org/packages/f2/fc/f8d9c31db14fcec13748d373e668bc3bed94d9077dbc17fb0eebc073233c/psutil-7.2.2-cp314-cp314t-win_arm64.whl",hashes = {sha256 = "11fe5a4f613759764e79c65cf11ebdf26e33d6dd34336f8a337aa2996d71c841"}}, - {name = "psutil-7.2.2-cp313-cp313t-macosx_10_13_x86_64.whl",url = "https://files.pythonhosted.org/packages/51/08/510cbdb69c25a96f4ae523f733cdc963ae654904e8db864c07585ef99875/psutil-7.2.2-cp313-cp313t-macosx_10_13_x86_64.whl",hashes = {sha256 = "2edccc433cbfa046b980b0df0171cd25bcaeb3a68fe9022db0979e7aa74a826b"}}, - {name = "psutil-7.2.2-cp313-cp313t-macosx_11_0_arm64.whl",url = "https://files.pythonhosted.org/packages/d6/f5/97baea3fe7a5a9af7436301f85490905379b1c6f2dd51fe3ecf24b4c5fbf/psutil-7.2.2-cp313-cp313t-macosx_11_0_arm64.whl",hashes = {sha256 = "e78c8603dcd9a04c7364f1a3e670cea95d51ee865e4efb3556a3a63adef958ea"}}, - {name = "psutil-7.2.2-cp313-cp313t-manylinux2010_x86_64.manylinux_2_12_x86_64.manylinux_2_28_x86_64.whl",url = "https://files.pythonhosted.org/packages/37/d6/246513fbf9fa174af531f28412297dd05241d97a75911ac8febefa1a53c6/psutil-7.2.2-cp313-cp313t-manylinux2010_x86_64.manylinux_2_12_x86_64.manylinux_2_28_x86_64.whl",hashes = {sha256 = "1a571f2330c966c62aeda00dd24620425d4b0cc86881c89861fbc04549e5dc63"}}, - {name = "psutil-7.2.2-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl",url = "https://files.pythonhosted.org/packages/b8/b5/9182c9af3836cca61696dabe4fd1304e17bc56cb62f17439e1154f225dd3/psutil-7.2.2-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl",hashes = {sha256 = "917e891983ca3c1887b4ef36447b1e0873e70c933afc831c6b6da078ba474312"}}, - {name = "psutil-7.2.2-cp313-cp313t-win_amd64.whl",url = "https://files.pythonhosted.org/packages/16/ba/0756dca669f5a9300d0cbcbfae9a4c30e446dfc7440ffe43ded5724bfd93/psutil-7.2.2-cp313-cp313t-win_amd64.whl",hashes = {sha256 = "ab486563df44c17f5173621c7b198955bd6b613fb87c71c161f827d3fb149a9b"}}, - {name = "psutil-7.2.2-cp313-cp313t-win_arm64.whl",url = "https://files.pythonhosted.org/packages/1c/61/8fa0e26f33623b49949346de05ec1ddaad02ed8ba64af45f40a147dbfa97/psutil-7.2.2-cp313-cp313t-win_arm64.whl",hashes = {sha256 = "ae0aefdd8796a7737eccea863f80f81e468a1e4cf14d926bd9b6f5f2d5f90ca9"}}, - {name = "psutil-7.2.2-cp37-abi3-win_amd64.whl",url = "https://files.pythonhosted.org/packages/b4/90/e2159492b5426be0c1fef7acba807a03511f97c5f86b3caeda6ad92351a7/psutil-7.2.2-cp37-abi3-win_amd64.whl",hashes = {sha256 = "eb7e81434c8d223ec4a219b5fc1c47d0417b12be7ea866e24fb5ad6e84b3d988"}}, - {name = "psutil-7.2.2-cp37-abi3-win_arm64.whl",url = "https://files.pythonhosted.org/packages/8c/c7/7bb2e321574b10df20cbde462a94e2b71d05f9bbda251ef27d104668306a/psutil-7.2.2-cp37-abi3-win_arm64.whl",hashes = {sha256 = "8c233660f575a5a89e6d4cb65d9f938126312bca76d8fe087b947b3a1aaac9ee"}}, - {name = "psutil-7.2.2-cp36-abi3-macosx_10_9_x86_64.whl",url = "https://files.pythonhosted.org/packages/e7/36/5ee6e05c9bd427237b11b3937ad82bb8ad2752d72c6969314590dd0c2f6e/psutil-7.2.2-cp36-abi3-macosx_10_9_x86_64.whl",hashes = {sha256 = "ed0cace939114f62738d808fdcecd4c869222507e266e574799e9c0faa17d486"}}, - {name = "psutil-7.2.2-cp36-abi3-macosx_11_0_arm64.whl",url = "https://files.pythonhosted.org/packages/80/c4/f5af4c1ca8c1eeb2e92ccca14ce8effdeec651d5ab6053c589b074eda6e1/psutil-7.2.2-cp36-abi3-macosx_11_0_arm64.whl",hashes = {sha256 = "1a7b04c10f32cc88ab39cbf606e117fd74721c831c98a27dc04578deb0c16979"}}, - {name = "psutil-7.2.2-cp36-abi3-manylinux2010_x86_64.manylinux_2_12_x86_64.manylinux_2_28_x86_64.whl",url = "https://files.pythonhosted.org/packages/b5/70/5d8df3b09e25bce090399cf48e452d25c935ab72dad19406c77f4e828045/psutil-7.2.2-cp36-abi3-manylinux2010_x86_64.manylinux_2_12_x86_64.manylinux_2_28_x86_64.whl",hashes = {sha256 = "076a2d2f923fd4821644f5ba89f059523da90dc9014e85f8e45a5774ca5bc6f9"}}, - {name = "psutil-7.2.2-cp36-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl",url = "https://files.pythonhosted.org/packages/63/65/37648c0c158dc222aba51c089eb3bdfa238e621674dc42d48706e639204f/psutil-7.2.2-cp36-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl",hashes = {sha256 = "b0726cecd84f9474419d67252add4ac0cd9811b04d61123054b9fb6f57df6e9e"}}, - {name = "psutil-7.2.2-cp36-abi3-musllinux_1_2_aarch64.whl",url = "https://files.pythonhosted.org/packages/8e/13/125093eadae863ce03c6ffdbae9929430d116a246ef69866dad94da3bfbc/psutil-7.2.2-cp36-abi3-musllinux_1_2_aarch64.whl",hashes = {sha256 = "fd04ef36b4a6d599bbdb225dd1d3f51e00105f6d48a28f006da7f9822f2606d8"}}, - {name = "psutil-7.2.2-cp36-abi3-musllinux_1_2_x86_64.whl",url = "https://files.pythonhosted.org/packages/04/78/0acd37ca84ce3ddffaa92ef0f571e073faa6d8ff1f0559ab1272188ea2be/psutil-7.2.2-cp36-abi3-musllinux_1_2_x86_64.whl",hashes = {sha256 = "b58fabe35e80b264a4e3bb23e6b96f9e45a3df7fb7eed419ac0e5947c61e47cc"}}, -] -marker = "\"docs\" in extras" - -[packages.tool.pdm] -dependencies = [] - -[[packages]] -name = "ptyprocess" -version = "0.7.0" -sdist = {name = "ptyprocess-0.7.0.tar.gz", url = "https://files.pythonhosted.org/packages/20/e5/16ff212c1e452235a90aeb09066144d0c5a6a8c0834397e03f5224495c4e/ptyprocess-0.7.0.tar.gz", hashes = {sha256 = "5c5d0a3b48ceee0b48485e0c26037c0acd7d29765ca3fbb5cb3831d347423220"}} -wheels = [ - {name = "ptyprocess-0.7.0-py2.py3-none-any.whl",url = "https://files.pythonhosted.org/packages/22/a6/858897256d0deac81a172289110f31629fc4cee19b6f01283303e18c8db3/ptyprocess-0.7.0-py2.py3-none-any.whl",hashes = {sha256 = "4b41f3967fce3af57cc7e94b888626c18bf37a083e3651ca8feeb66d492fef35"}}, -] -marker = "(sys_platform != \"win32\" and sys_platform != \"emscripten\") and \"docs\" in extras" - -[packages.tool.pdm] -dependencies = [] - -[[packages]] -name = "pure-eval" -version = "0.2.3" -sdist = {name = "pure_eval-0.2.3.tar.gz", url = "https://files.pythonhosted.org/packages/cd/05/0a34433a064256a578f1783a10da6df098ceaa4a57bbeaa96a6c0352786b/pure_eval-0.2.3.tar.gz", hashes = {sha256 = "5f4e983f40564c576c7c8635ae88db5956bb2229d7e9237d03b3c0b0190eaf42"}} -wheels = [ - {name = "pure_eval-0.2.3-py3-none-any.whl",url = "https://files.pythonhosted.org/packages/8e/37/efad0257dc6e593a18957422533ff0f87ede7c9c6ea010a2177d738fb82f/pure_eval-0.2.3-py3-none-any.whl",hashes = {sha256 = "1db8e35b67b3d218d818ae653e27f06c3aa420901fa7b081ca98cbedc874e0d0"}}, -] -marker = "\"docs\" in extras" - -[packages.tool.pdm] -dependencies = [] - -[[packages]] -name = "pycparser" -version = "3.0" -requires-python = ">=3.10" -sdist = {name = "pycparser-3.0.tar.gz", url = "https://files.pythonhosted.org/packages/1b/7d/92392ff7815c21062bea51aa7b87d45576f649f16458d78b7cf94b9ab2e6/pycparser-3.0.tar.gz", hashes = {sha256 = "600f49d217304a5902ac3c37e1281c9fe94e4d0489de643a9504c5cdfdfc6b29"}} -wheels = [ - {name = "pycparser-3.0-py3-none-any.whl",url = "https://files.pythonhosted.org/packages/0c/c3/44f3fbbfa403ea2a7c779186dc20772604442dde72947e7d01069cbe98e3/pycparser-3.0-py3-none-any.whl",hashes = {sha256 = "b727414169a36b7d524c1c3e31839a521725078d7b2ff038656844266160a992"}}, -] -marker = "implementation_name == \"pypy\" and \"docs\" in extras" - -[packages.tool.pdm] -dependencies = [] - -[[packages]] -name = "pygments" -version = "2.20.0" -requires-python = ">=3.9" -sdist = {name = "pygments-2.20.0.tar.gz", url = "https://files.pythonhosted.org/packages/c3/b2/bc9c9196916376152d655522fdcebac55e66de6603a76a02bca1b6414f6c/pygments-2.20.0.tar.gz", hashes = {sha256 = "6757cd03768053ff99f3039c1a36d6c0aa0b263438fcab17520b30a303a82b5f"}} -wheels = [ - {name = "pygments-2.20.0-py3-none-any.whl",url = "https://files.pythonhosted.org/packages/f4/7e/a72dd26f3b0f4f2bf1dd8923c85f7ceb43172af56d63c7383eb62b332364/pygments-2.20.0-py3-none-any.whl",hashes = {sha256 = "81a9e26dd42fd28a23a2d169d86d7ac03b46e2f8b59ed4698fb4785f946d0176"}}, -] -marker = "\"docs\" in extras or \"test\" in extras" - -[packages.tool.pdm] -dependencies = [] - -[[packages]] -name = "pylint" -version = "4.0.5" -requires-python = ">=3.10.0" -sdist = {name = "pylint-4.0.5.tar.gz", url = "https://files.pythonhosted.org/packages/e4/b6/74d9a8a68b8067efce8d07707fe6a236324ee1e7808d2eb3646ec8517c7d/pylint-4.0.5.tar.gz", hashes = {sha256 = "8cd6a618df75deb013bd7eb98327a95f02a6fb839205a6bbf5456ef96afb317c"}} -wheels = [ - {name = "pylint-4.0.5-py3-none-any.whl",url = "https://files.pythonhosted.org/packages/d5/6f/9ac2548e290764781f9e7e2aaf0685b086379dabfb29ca38536985471eaf/pylint-4.0.5-py3-none-any.whl",hashes = {sha256 = "00f51c9b14a3b3ae08cff6b2cdd43f28165c78b165b628692e428fb1f8dc2cf2"}}, -] -marker = "\"docs\" in extras" - -[packages.tool.pdm] -dependencies = [ - "astroid<=4.1.dev0,>=4.0.2", - "colorama>=0.4.5; sys_platform == \"win32\"", - "dill>=0.2; python_version < \"3.11\"", - "dill>=0.3.6; python_version >= \"3.11\"", - "dill>=0.3.7; python_version >= \"3.12\"", - "isort!=5.13,<9,>=5", - "mccabe<0.8,>=0.6", - "platformdirs>=2.2", - "tomli>=1.1; python_version < \"3.11\"", - "tomlkit>=0.10.1", - "typing-extensions>=3.10; python_version < \"3.10\"", -] - -[[packages]] -name = "pyparsing" -version = "3.3.2" -requires-python = ">=3.9" -sdist = {name = "pyparsing-3.3.2.tar.gz", url = "https://files.pythonhosted.org/packages/f3/91/9c6ee907786a473bf81c5f53cf703ba0957b23ab84c264080fb5a450416f/pyparsing-3.3.2.tar.gz", hashes = {sha256 = "c777f4d763f140633dcb6d8a3eda953bf7a214dc4eff598413c070bcdc117cbc"}} -wheels = [ - {name = "pyparsing-3.3.2-py3-none-any.whl",url = "https://files.pythonhosted.org/packages/10/bd/c038d7cc38edc1aa5bf91ab8068b63d4308c66c4c8bb3cbba7dfbc049f9c/pyparsing-3.3.2-py3-none-any.whl",hashes = {sha256 = "850ba148bd908d7e2411587e247a1e4f0327839c40e2e5e6d05a007ecc69911d"}}, -] -marker = "\"default\" in dependency_groups or \"docs\" in extras" - -[packages.tool.pdm] -dependencies = [] - -[[packages]] -name = "pytest" -version = "8.4.2" -requires-python = ">=3.9" -sdist = {name = "pytest-8.4.2.tar.gz", url = "https://files.pythonhosted.org/packages/a3/5c/00a0e072241553e1a7496d638deababa67c5058571567b92a7eaa258397c/pytest-8.4.2.tar.gz", hashes = {sha256 = "86c0d0b93306b961d58d62a4db4879f27fe25513d4b969df351abdddb3c30e01"}} -wheels = [ - {name = "pytest-8.4.2-py3-none-any.whl",url = "https://files.pythonhosted.org/packages/a8/a4/20da314d277121d6534b3a980b29035dcd51e6744bd79075a6ce8fa4eb8d/pytest-8.4.2-py3-none-any.whl",hashes = {sha256 = "872f880de3fc3a5bdc88a11b39c9710c3497a547cfa9320bc3c5e62fbf272e79"}}, -] -marker = "\"test\" in extras" - -[packages.tool.pdm] -dependencies = [ - "colorama>=0.4; sys_platform == \"win32\"", - "exceptiongroup>=1; python_version < \"3.11\"", - "iniconfig>=1", - "packaging>=20", - "pluggy<2,>=1.5", - "pygments>=2.7.2", - "tomli>=1; python_version < \"3.11\"", -] - -[[packages]] -name = "pytest-cov" -version = "7.0.0" -requires-python = ">=3.9" -sdist = {name = "pytest_cov-7.0.0.tar.gz", url = "https://files.pythonhosted.org/packages/5e/f7/c933acc76f5208b3b00089573cf6a2bc26dc80a8aece8f52bb7d6b1855ca/pytest_cov-7.0.0.tar.gz", hashes = {sha256 = "33c97eda2e049a0c5298e91f519302a1334c26ac65c1a483d6206fd458361af1"}} -wheels = [ - {name = "pytest_cov-7.0.0-py3-none-any.whl",url = "https://files.pythonhosted.org/packages/ee/49/1377b49de7d0c1ce41292161ea0f721913fa8722c19fb9c1e3aa0367eecb/pytest_cov-7.0.0-py3-none-any.whl",hashes = {sha256 = "3b8e9558b16cc1479da72058bdecf8073661c7f57f7d3c5f22a1c23507f2d861"}}, -] -marker = "\"test\" in extras" - -[packages.tool.pdm] -dependencies = [ - "coverage[toml]>=7.10.6", - "pluggy>=1.2", - "pytest>=7", -] - -[[packages]] -name = "python-dateutil" -version = "2.9.0.post0" -requires-python = "!=3.0.*,!=3.1.*,!=3.2.*,>=2.7" -sdist = {name = "python-dateutil-2.9.0.post0.tar.gz", url = "https://files.pythonhosted.org/packages/66/c0/0c8b6ad9f17a802ee498c46e004a0eb49bc148f2fd230864601a86dcf6db/python-dateutil-2.9.0.post0.tar.gz", hashes = {sha256 = "37dd54208da7e1cd875388217d5e00ebd4179249f90fb72437e91a35459a0ad3"}} -wheels = [ - {name = "python_dateutil-2.9.0.post0-py2.py3-none-any.whl",url = "https://files.pythonhosted.org/packages/ec/57/56b9bcc3c9c6a792fcbaf139543cee77261f3651ca9da0c93f5c1221264b/python_dateutil-2.9.0.post0-py2.py3-none-any.whl",hashes = {sha256 = "a8b2bc7bffae282281c8140a97d3aa9c14da0b136dfe83f850eea9a5f7470427"}}, -] -marker = "\"default\" in dependency_groups or \"docs\" in extras" - -[packages.tool.pdm] -dependencies = [ - "six>=1.5", -] - -[[packages]] -name = "pytz" -version = "2026.1.post1" -sdist = {name = "pytz-2026.1.post1.tar.gz", url = "https://files.pythonhosted.org/packages/56/db/b8721d71d945e6a8ac63c0fc900b2067181dbb50805958d4d4661cf7d277/pytz-2026.1.post1.tar.gz", hashes = {sha256 = "3378dde6a0c3d26719182142c56e60c7f9af7e968076f31aae569d72a0358ee1"}} -wheels = [ - {name = "pytz-2026.1.post1-py2.py3-none-any.whl",url = "https://files.pythonhosted.org/packages/10/99/781fe0c827be2742bcc775efefccb3b048a3a9c6ce9aec0cbf4a101677e5/pytz-2026.1.post1-py2.py3-none-any.whl",hashes = {sha256 = "f2fd16142fda348286a75e1a524be810bb05d444e5a081f37f7affc635035f7a"}}, -] -marker = "\"default\" in dependency_groups" - -[packages.tool.pdm] -dependencies = [] - -[[packages]] -name = "pyyaml" -version = "6.0.3" -requires-python = ">=3.8" -sdist = {name = "pyyaml-6.0.3.tar.gz", url = "https://files.pythonhosted.org/packages/05/8e/961c0007c59b8dd7729d542c61a4d537767a59645b82a0b521206e1e25c2/pyyaml-6.0.3.tar.gz", hashes = {sha256 = "d76623373421df22fb4cf8817020cbb7ef15c725b9d5e45f17e189bfc384190f"}} -wheels = [ - {name = "pyyaml-6.0.3-cp314-cp314-macosx_10_13_x86_64.whl",url = "https://files.pythonhosted.org/packages/9d/8c/f4bd7f6465179953d3ac9bc44ac1a8a3e6122cf8ada906b4f96c60172d43/pyyaml-6.0.3-cp314-cp314-macosx_10_13_x86_64.whl",hashes = {sha256 = "8d1fab6bb153a416f9aeb4b8763bc0f22a5586065f86f7664fc23339fc1c1fac"}}, - {name = "pyyaml-6.0.3-cp314-cp314-macosx_11_0_arm64.whl",url = "https://files.pythonhosted.org/packages/bd/9c/4d95bb87eb2063d20db7b60faa3840c1b18025517ae857371c4dd55a6b3a/pyyaml-6.0.3-cp314-cp314-macosx_11_0_arm64.whl",hashes = {sha256 = "34d5fcd24b8445fadc33f9cf348c1047101756fd760b4dacb5c3e99755703310"}}, - {name = "pyyaml-6.0.3-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl",url = "https://files.pythonhosted.org/packages/92/b5/47e807c2623074914e29dabd16cbbdd4bf5e9b2db9f8090fa64411fc5382/pyyaml-6.0.3-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl",hashes = {sha256 = "501a031947e3a9025ed4405a168e6ef5ae3126c59f90ce0cd6f2bfc477be31b7"}}, - {name = "pyyaml-6.0.3-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl",url = "https://files.pythonhosted.org/packages/02/9e/e5e9b168be58564121efb3de6859c452fccde0ab093d8438905899a3a483/pyyaml-6.0.3-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl",hashes = {sha256 = "b3bc83488de33889877a0f2543ade9f70c67d66d9ebb4ac959502e12de895788"}}, - {name = "pyyaml-6.0.3-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl",url = "https://files.pythonhosted.org/packages/88/f9/16491d7ed2a919954993e48aa941b200f38040928474c9e85ea9e64222c3/pyyaml-6.0.3-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl",hashes = {sha256 = "c458b6d084f9b935061bc36216e8a69a7e293a2f1e68bf956dcd9e6cbcd143f5"}}, - {name = "pyyaml-6.0.3-cp314-cp314-musllinux_1_2_aarch64.whl",url = "https://files.pythonhosted.org/packages/dd/3f/5989debef34dc6397317802b527dbbafb2b4760878a53d4166579111411e/pyyaml-6.0.3-cp314-cp314-musllinux_1_2_aarch64.whl",hashes = {sha256 = "7c6610def4f163542a622a73fb39f534f8c101d690126992300bf3207eab9764"}}, - {name = "pyyaml-6.0.3-cp314-cp314-musllinux_1_2_x86_64.whl",url = "https://files.pythonhosted.org/packages/d7/ce/af88a49043cd2e265be63d083fc75b27b6ed062f5f9fd6cdc223ad62f03e/pyyaml-6.0.3-cp314-cp314-musllinux_1_2_x86_64.whl",hashes = {sha256 = "5190d403f121660ce8d1d2c1bb2ef1bd05b5f68533fc5c2ea899bd15f4399b35"}}, - {name = "pyyaml-6.0.3-cp314-cp314-win_amd64.whl",url = "https://files.pythonhosted.org/packages/23/20/bb6982b26a40bb43951265ba29d4c246ef0ff59c9fdcdf0ed04e0687de4d/pyyaml-6.0.3-cp314-cp314-win_amd64.whl",hashes = {sha256 = "4a2e8cebe2ff6ab7d1050ecd59c25d4c8bd7e6f400f5f82b96557ac0abafd0ac"}}, - {name = "pyyaml-6.0.3-cp314-cp314-win_arm64.whl",url = "https://files.pythonhosted.org/packages/f4/f4/a4541072bb9422c8a883ab55255f918fa378ecf083f5b85e87fc2b4eda1b/pyyaml-6.0.3-cp314-cp314-win_arm64.whl",hashes = {sha256 = "93dda82c9c22deb0a405ea4dc5f2d0cda384168e466364dec6255b293923b2f3"}}, - {name = "pyyaml-6.0.3-cp314-cp314t-macosx_10_13_x86_64.whl",url = "https://files.pythonhosted.org/packages/7c/f9/07dd09ae774e4616edf6cda684ee78f97777bdd15847253637a6f052a62f/pyyaml-6.0.3-cp314-cp314t-macosx_10_13_x86_64.whl",hashes = {sha256 = "02893d100e99e03eda1c8fd5c441d8c60103fd175728e23e431db1b589cf5ab3"}}, - {name = "pyyaml-6.0.3-cp314-cp314t-macosx_11_0_arm64.whl",url = "https://files.pythonhosted.org/packages/4e/78/8d08c9fb7ce09ad8c38ad533c1191cf27f7ae1effe5bb9400a46d9437fcf/pyyaml-6.0.3-cp314-cp314t-macosx_11_0_arm64.whl",hashes = {sha256 = "c1ff362665ae507275af2853520967820d9124984e0f7466736aea23d8611fba"}}, - {name = "pyyaml-6.0.3-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl",url = "https://files.pythonhosted.org/packages/7b/5b/3babb19104a46945cf816d047db2788bcaf8c94527a805610b0289a01c6b/pyyaml-6.0.3-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl",hashes = {sha256 = "6adc77889b628398debc7b65c073bcb99c4a0237b248cacaf3fe8a557563ef6c"}}, - {name = "pyyaml-6.0.3-cp314-cp314t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl",url = "https://files.pythonhosted.org/packages/8b/cc/dff0684d8dc44da4d22a13f35f073d558c268780ce3c6ba1b87055bb0b87/pyyaml-6.0.3-cp314-cp314t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl",hashes = {sha256 = "a80cb027f6b349846a3bf6d73b5e95e782175e52f22108cfa17876aaeff93702"}}, - {name = "pyyaml-6.0.3-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl",url = "https://files.pythonhosted.org/packages/b1/5e/f77dc6b9036943e285ba76b49e118d9ea929885becb0a29ba8a7c75e29fe/pyyaml-6.0.3-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl",hashes = {sha256 = "00c4bdeba853cc34e7dd471f16b4114f4162dc03e6b7afcc2128711f0eca823c"}}, - {name = "pyyaml-6.0.3-cp314-cp314t-musllinux_1_2_aarch64.whl",url = "https://files.pythonhosted.org/packages/ce/88/a9db1376aa2a228197c58b37302f284b5617f56a5d959fd1763fb1675ce6/pyyaml-6.0.3-cp314-cp314t-musllinux_1_2_aarch64.whl",hashes = {sha256 = "66e1674c3ef6f541c35191caae2d429b967b99e02040f5ba928632d9a7f0f065"}}, - {name = "pyyaml-6.0.3-cp314-cp314t-musllinux_1_2_x86_64.whl",url = "https://files.pythonhosted.org/packages/da/92/1446574745d74df0c92e6aa4a7b0b3130706a4142b2d1a5869f2eaa423c6/pyyaml-6.0.3-cp314-cp314t-musllinux_1_2_x86_64.whl",hashes = {sha256 = "16249ee61e95f858e83976573de0f5b2893b3677ba71c9dd36b9cf8be9ac6d65"}}, - {name = "pyyaml-6.0.3-cp314-cp314t-win_amd64.whl",url = "https://files.pythonhosted.org/packages/f0/7a/1c7270340330e575b92f397352af856a8c06f230aa3e76f86b39d01b416a/pyyaml-6.0.3-cp314-cp314t-win_amd64.whl",hashes = {sha256 = "4ad1906908f2f5ae4e5a8ddfce73c320c2a1429ec52eafd27138b7f1cbe341c9"}}, - {name = "pyyaml-6.0.3-cp314-cp314t-win_arm64.whl",url = "https://files.pythonhosted.org/packages/f1/12/de94a39c2ef588c7e6455cfbe7343d3b2dc9d6b6b2f40c4c6565744c873d/pyyaml-6.0.3-cp314-cp314t-win_arm64.whl",hashes = {sha256 = "ebc55a14a21cb14062aa4162f906cd962b28e2e9ea38f9b4391244cd8de4ae0b"}}, - {name = "pyyaml-6.0.3-cp313-cp313-macosx_10_13_x86_64.whl",url = "https://files.pythonhosted.org/packages/d1/11/0fd08f8192109f7169db964b5707a2f1e8b745d4e239b784a5a1dd80d1db/pyyaml-6.0.3-cp313-cp313-macosx_10_13_x86_64.whl",hashes = {sha256 = "8da9669d359f02c0b91ccc01cac4a67f16afec0dac22c2ad09f46bee0697eba8"}}, - {name = "pyyaml-6.0.3-cp313-cp313-macosx_11_0_arm64.whl",url = "https://files.pythonhosted.org/packages/b1/16/95309993f1d3748cd644e02e38b75d50cbc0d9561d21f390a76242ce073f/pyyaml-6.0.3-cp313-cp313-macosx_11_0_arm64.whl",hashes = {sha256 = "2283a07e2c21a2aa78d9c4442724ec1eb15f5e42a723b99cb3d822d48f5f7ad1"}}, - {name = "pyyaml-6.0.3-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl",url = "https://files.pythonhosted.org/packages/50/31/b20f376d3f810b9b2371e72ef5adb33879b25edb7a6d072cb7ca0c486398/pyyaml-6.0.3-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl",hashes = {sha256 = "ee2922902c45ae8ccada2c5b501ab86c36525b883eff4255313a253a3160861c"}}, - {name = "pyyaml-6.0.3-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl",url = "https://files.pythonhosted.org/packages/49/1e/a55ca81e949270d5d4432fbbd19dfea5321eda7c41a849d443dc92fd1ff7/pyyaml-6.0.3-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl",hashes = {sha256 = "a33284e20b78bd4a18c8c2282d549d10bc8408a2a7ff57653c0cf0b9be0afce5"}}, - {name = "pyyaml-6.0.3-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl",url = "https://files.pythonhosted.org/packages/74/27/e5b8f34d02d9995b80abcef563ea1f8b56d20134d8f4e5e81733b1feceb2/pyyaml-6.0.3-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl",hashes = {sha256 = "0f29edc409a6392443abf94b9cf89ce99889a1dd5376d94316ae5145dfedd5d6"}}, - {name = "pyyaml-6.0.3-cp313-cp313-musllinux_1_2_aarch64.whl",url = "https://files.pythonhosted.org/packages/f9/11/ba845c23988798f40e52ba45f34849aa8a1f2d4af4b798588010792ebad6/pyyaml-6.0.3-cp313-cp313-musllinux_1_2_aarch64.whl",hashes = {sha256 = "f7057c9a337546edc7973c0d3ba84ddcdf0daa14533c2065749c9075001090e6"}}, - {name = "pyyaml-6.0.3-cp313-cp313-musllinux_1_2_x86_64.whl",url = "https://files.pythonhosted.org/packages/3d/e0/7966e1a7bfc0a45bf0a7fb6b98ea03fc9b8d84fa7f2229e9659680b69ee3/pyyaml-6.0.3-cp313-cp313-musllinux_1_2_x86_64.whl",hashes = {sha256 = "eda16858a3cab07b80edaf74336ece1f986ba330fdb8ee0d6c0d68fe82bc96be"}}, - {name = "pyyaml-6.0.3-cp313-cp313-win32.whl",url = "https://files.pythonhosted.org/packages/de/94/980b50a6531b3019e45ddeada0626d45fa85cbe22300844a7983285bed3b/pyyaml-6.0.3-cp313-cp313-win32.whl",hashes = {sha256 = "d0eae10f8159e8fdad514efdc92d74fd8d682c933a6dd088030f3834bc8e6b26"}}, - {name = "pyyaml-6.0.3-cp313-cp313-win_amd64.whl",url = "https://files.pythonhosted.org/packages/97/c9/39d5b874e8b28845e4ec2202b5da735d0199dbe5b8fb85f91398814a9a46/pyyaml-6.0.3-cp313-cp313-win_amd64.whl",hashes = {sha256 = "79005a0d97d5ddabfeeea4cf676af11e647e41d81c9a7722a193022accdb6b7c"}}, - {name = "pyyaml-6.0.3-cp313-cp313-win_arm64.whl",url = "https://files.pythonhosted.org/packages/73/e8/2bdf3ca2090f68bb3d75b44da7bbc71843b19c9f2b9cb9b0f4ab7a5a4329/pyyaml-6.0.3-cp313-cp313-win_arm64.whl",hashes = {sha256 = "5498cd1645aa724a7c71c8f378eb29ebe23da2fc0d7a08071d89469bf1d2defb"}}, - {name = "pyyaml-6.0.3-cp312-cp312-macosx_10_13_x86_64.whl",url = "https://files.pythonhosted.org/packages/d1/33/422b98d2195232ca1826284a76852ad5a86fe23e31b009c9886b2d0fb8b2/pyyaml-6.0.3-cp312-cp312-macosx_10_13_x86_64.whl",hashes = {sha256 = "7f047e29dcae44602496db43be01ad42fc6f1cc0d8cd6c83d342306c32270196"}}, - {name = "pyyaml-6.0.3-cp312-cp312-macosx_11_0_arm64.whl",url = "https://files.pythonhosted.org/packages/89/a0/6cf41a19a1f2f3feab0e9c0b74134aa2ce6849093d5517a0c550fe37a648/pyyaml-6.0.3-cp312-cp312-macosx_11_0_arm64.whl",hashes = {sha256 = "fc09d0aa354569bc501d4e787133afc08552722d3ab34836a80547331bb5d4a0"}}, - {name = "pyyaml-6.0.3-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl",url = "https://files.pythonhosted.org/packages/ed/23/7a778b6bd0b9a8039df8b1b1d80e2e2ad78aa04171592c8a5c43a56a6af4/pyyaml-6.0.3-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl",hashes = {sha256 = "9149cad251584d5fb4981be1ecde53a1ca46c891a79788c0df828d2f166bda28"}}, - {name = "pyyaml-6.0.3-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl",url = "https://files.pythonhosted.org/packages/65/30/d7353c338e12baef4ecc1b09e877c1970bd3382789c159b4f89d6a70dc09/pyyaml-6.0.3-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl",hashes = {sha256 = "5fdec68f91a0c6739b380c83b951e2c72ac0197ace422360e6d5a959d8d97b2c"}}, - {name = "pyyaml-6.0.3-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl",url = "https://files.pythonhosted.org/packages/8b/9d/b3589d3877982d4f2329302ef98a8026e7f4443c765c46cfecc8858c6b4b/pyyaml-6.0.3-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl",hashes = {sha256 = "ba1cc08a7ccde2d2ec775841541641e4548226580ab850948cbfda66a1befcdc"}}, - {name = "pyyaml-6.0.3-cp312-cp312-musllinux_1_2_aarch64.whl",url = "https://files.pythonhosted.org/packages/05/c0/b3be26a015601b822b97d9149ff8cb5ead58c66f981e04fedf4e762f4bd4/pyyaml-6.0.3-cp312-cp312-musllinux_1_2_aarch64.whl",hashes = {sha256 = "8dc52c23056b9ddd46818a57b78404882310fb473d63f17b07d5c40421e47f8e"}}, - {name = "pyyaml-6.0.3-cp312-cp312-musllinux_1_2_x86_64.whl",url = "https://files.pythonhosted.org/packages/be/8e/98435a21d1d4b46590d5459a22d88128103f8da4c2d4cb8f14f2a96504e1/pyyaml-6.0.3-cp312-cp312-musllinux_1_2_x86_64.whl",hashes = {sha256 = "41715c910c881bc081f1e8872880d3c650acf13dfa8214bad49ed4cede7c34ea"}}, - {name = "pyyaml-6.0.3-cp312-cp312-win32.whl",url = "https://files.pythonhosted.org/packages/74/93/7baea19427dcfbe1e5a372d81473250b379f04b1bd3c4c5ff825e2327202/pyyaml-6.0.3-cp312-cp312-win32.whl",hashes = {sha256 = "96b533f0e99f6579b3d4d4995707cf36df9100d67e0c8303a0c55b27b5f99bc5"}}, - {name = "pyyaml-6.0.3-cp312-cp312-win_amd64.whl",url = "https://files.pythonhosted.org/packages/86/bf/899e81e4cce32febab4fb42bb97dcdf66bc135272882d1987881a4b519e9/pyyaml-6.0.3-cp312-cp312-win_amd64.whl",hashes = {sha256 = "5fcd34e47f6e0b794d17de1b4ff496c00986e1c83f7ab2fb8fcfe9616ff7477b"}}, - {name = "pyyaml-6.0.3-cp312-cp312-win_arm64.whl",url = "https://files.pythonhosted.org/packages/1a/08/67bd04656199bbb51dbed1439b7f27601dfb576fb864099c7ef0c3e55531/pyyaml-6.0.3-cp312-cp312-win_arm64.whl",hashes = {sha256 = "64386e5e707d03a7e172c0701abfb7e10f0fb753ee1d773128192742712a98fd"}}, - {name = "pyyaml-6.0.3-cp311-cp311-macosx_10_13_x86_64.whl",url = "https://files.pythonhosted.org/packages/6d/16/a95b6757765b7b031c9374925bb718d55e0a9ba8a1b6a12d25962ea44347/pyyaml-6.0.3-cp311-cp311-macosx_10_13_x86_64.whl",hashes = {sha256 = "44edc647873928551a01e7a563d7452ccdebee747728c1080d881d68af7b997e"}}, - {name = "pyyaml-6.0.3-cp311-cp311-macosx_11_0_arm64.whl",url = "https://files.pythonhosted.org/packages/16/19/13de8e4377ed53079ee996e1ab0a9c33ec2faf808a4647b7b4c0d46dd239/pyyaml-6.0.3-cp311-cp311-macosx_11_0_arm64.whl",hashes = {sha256 = "652cb6edd41e718550aad172851962662ff2681490a8a711af6a4d288dd96824"}}, - {name = "pyyaml-6.0.3-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl",url = "https://files.pythonhosted.org/packages/0c/62/d2eb46264d4b157dae1275b573017abec435397aa59cbcdab6fc978a8af4/pyyaml-6.0.3-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl",hashes = {sha256 = "10892704fc220243f5305762e276552a0395f7beb4dbf9b14ec8fd43b57f126c"}}, - {name = "pyyaml-6.0.3-cp311-cp311-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl",url = "https://files.pythonhosted.org/packages/10/cb/16c3f2cf3266edd25aaa00d6c4350381c8b012ed6f5276675b9eba8d9ff4/pyyaml-6.0.3-cp311-cp311-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl",hashes = {sha256 = "850774a7879607d3a6f50d36d04f00ee69e7fc816450e5f7e58d7f17f1ae5c00"}}, - {name = "pyyaml-6.0.3-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl",url = "https://files.pythonhosted.org/packages/71/60/917329f640924b18ff085ab889a11c763e0b573da888e8404ff486657602/pyyaml-6.0.3-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl",hashes = {sha256 = "b8bb0864c5a28024fac8a632c443c87c5aa6f215c0b126c449ae1a150412f31d"}}, - {name = "pyyaml-6.0.3-cp311-cp311-musllinux_1_2_aarch64.whl",url = "https://files.pythonhosted.org/packages/dd/6f/529b0f316a9fd167281a6c3826b5583e6192dba792dd55e3203d3f8e655a/pyyaml-6.0.3-cp311-cp311-musllinux_1_2_aarch64.whl",hashes = {sha256 = "1d37d57ad971609cf3c53ba6a7e365e40660e3be0e5175fa9f2365a379d6095a"}}, - {name = "pyyaml-6.0.3-cp311-cp311-musllinux_1_2_x86_64.whl",url = "https://files.pythonhosted.org/packages/f2/6a/b627b4e0c1dd03718543519ffb2f1deea4a1e6d42fbab8021936a4d22589/pyyaml-6.0.3-cp311-cp311-musllinux_1_2_x86_64.whl",hashes = {sha256 = "37503bfbfc9d2c40b344d06b2199cf0e96e97957ab1c1b546fd4f87e53e5d3e4"}}, - {name = "pyyaml-6.0.3-cp311-cp311-win32.whl",url = "https://files.pythonhosted.org/packages/45/91/47a6e1c42d9ee337c4839208f30d9f09caa9f720ec7582917b264defc875/pyyaml-6.0.3-cp311-cp311-win32.whl",hashes = {sha256 = "8098f252adfa6c80ab48096053f512f2321f0b998f98150cea9bd23d83e1467b"}}, - {name = "pyyaml-6.0.3-cp311-cp311-win_amd64.whl",url = "https://files.pythonhosted.org/packages/da/e3/ea007450a105ae919a72393cb06f122f288ef60bba2dc64b26e2646fa315/pyyaml-6.0.3-cp311-cp311-win_amd64.whl",hashes = {sha256 = "9f3bfb4965eb874431221a3ff3fdcddc7e74e3b07799e0e84ca4a0f867d449bf"}}, -] -marker = "\"docs\" in extras" - -[packages.tool.pdm] -dependencies = [] - -[[packages]] -name = "pyzmq" -version = "27.1.0" -requires-python = ">=3.8" -sdist = {name = "pyzmq-27.1.0.tar.gz", url = "https://files.pythonhosted.org/packages/04/0b/3c9baedbdf613ecaa7aa07027780b8867f57b6293b6ee50de316c9f3222b/pyzmq-27.1.0.tar.gz", hashes = {sha256 = "ac0765e3d44455adb6ddbf4417dcce460fc40a05978c08efdf2948072f6db540"}} -wheels = [ - {name = "pyzmq-27.1.0-cp314-cp314t-macosx_10_15_universal2.whl",url = "https://files.pythonhosted.org/packages/87/45/19efbb3000956e82d0331bafca5d9ac19ea2857722fa2caacefb6042f39d/pyzmq-27.1.0-cp314-cp314t-macosx_10_15_universal2.whl",hashes = {sha256 = "ce980af330231615756acd5154f29813d553ea555485ae712c491cd483df6b7a"}}, - {name = "pyzmq-27.1.0-cp314-cp314t-manylinux2014_i686.manylinux_2_17_i686.whl",url = "https://files.pythonhosted.org/packages/48/43/d72ccdbf0d73d1343936296665826350cb1e825f92f2db9db3e61c2162a2/pyzmq-27.1.0-cp314-cp314t-manylinux2014_i686.manylinux_2_17_i686.whl",hashes = {sha256 = "1779be8c549e54a1c38f805e56d2a2e5c009d26de10921d7d51cfd1c8d4632ea"}}, - {name = "pyzmq-27.1.0-cp314-cp314t-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl",url = "https://files.pythonhosted.org/packages/2f/2e/a483f73a10b65a9ef0161e817321d39a770b2acf8bcf3004a28d90d14a94/pyzmq-27.1.0-cp314-cp314t-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl",hashes = {sha256 = "7200bb0f03345515df50d99d3db206a0a6bee1955fbb8c453c76f5bf0e08fb96"}}, - {name = "pyzmq-27.1.0-cp314-cp314t-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl",url = "https://files.pythonhosted.org/packages/f5/d2/5f36552c2d3e5685abe60dfa56f91169f7a2d99bbaf67c5271022ab40863/pyzmq-27.1.0-cp314-cp314t-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl",hashes = {sha256 = "01c0e07d558b06a60773744ea6251f769cd79a41a97d11b8bf4ab8f034b0424d"}}, - {name = "pyzmq-27.1.0-cp314-cp314t-musllinux_1_2_aarch64.whl",url = "https://files.pythonhosted.org/packages/c4/2a/404b331f2b7bf3198e9945f75c4c521f0c6a3a23b51f7a4a401b94a13833/pyzmq-27.1.0-cp314-cp314t-musllinux_1_2_aarch64.whl",hashes = {sha256 = "80d834abee71f65253c91540445d37c4c561e293ba6e741b992f20a105d69146"}}, - {name = "pyzmq-27.1.0-cp314-cp314t-musllinux_1_2_i686.whl",url = "https://files.pythonhosted.org/packages/1c/0b/f4107e33f62a5acf60e3ded67ed33d79b4ce18de432625ce2fc5093d6388/pyzmq-27.1.0-cp314-cp314t-musllinux_1_2_i686.whl",hashes = {sha256 = "544b4e3b7198dde4a62b8ff6685e9802a9a1ebf47e77478a5eb88eca2a82f2fd"}}, - {name = "pyzmq-27.1.0-cp314-cp314t-musllinux_1_2_x86_64.whl",url = "https://files.pythonhosted.org/packages/0d/01/add31fe76512642fd6e40e3a3bd21f4b47e242c8ba33efb6809e37076d9b/pyzmq-27.1.0-cp314-cp314t-musllinux_1_2_x86_64.whl",hashes = {sha256 = "cedc4c68178e59a4046f97eca31b148ddcf51e88677de1ef4e78cf06c5376c9a"}}, - {name = "pyzmq-27.1.0-cp314-cp314t-win32.whl",url = "https://files.pythonhosted.org/packages/c4/59/a5f38970f9bf07cee96128de79590bb354917914a9be11272cfc7ff26af0/pyzmq-27.1.0-cp314-cp314t-win32.whl",hashes = {sha256 = "1f0b2a577fd770aa6f053211a55d1c47901f4d537389a034c690291485e5fe92"}}, - {name = "pyzmq-27.1.0-cp314-cp314t-win_amd64.whl",url = "https://files.pythonhosted.org/packages/70/d8/78b1bad170f93fcf5e3536e70e8fadac55030002275c9a29e8f5719185de/pyzmq-27.1.0-cp314-cp314t-win_amd64.whl",hashes = {sha256 = "19c9468ae0437f8074af379e986c5d3d7d7bfe033506af442e8c879732bedbe0"}}, - {name = "pyzmq-27.1.0-cp314-cp314t-win_arm64.whl",url = "https://files.pythonhosted.org/packages/81/d6/4bfbb40c9a0b42fc53c7cf442f6385db70b40f74a783130c5d0a5aa62228/pyzmq-27.1.0-cp314-cp314t-win_arm64.whl",hashes = {sha256 = "dc5dbf68a7857b59473f7df42650c621d7e8923fb03fa74a526890f4d33cc4d7"}}, - {name = "pyzmq-27.1.0-cp313-cp313-android_24_arm64_v8a.whl",url = "https://files.pythonhosted.org/packages/60/cb/84a13459c51da6cec1b7b1dc1a47e6db6da50b77ad7fd9c145842750a011/pyzmq-27.1.0-cp313-cp313-android_24_arm64_v8a.whl",hashes = {sha256 = "93ad4b0855a664229559e45c8d23797ceac03183c7b6f5b4428152a6b06684a5"}}, - {name = "pyzmq-27.1.0-cp313-cp313-android_24_x86_64.whl",url = "https://files.pythonhosted.org/packages/dc/b6/94414759a69a26c3dd674570a81813c46a078767d931a6c70ad29fc585cb/pyzmq-27.1.0-cp313-cp313-android_24_x86_64.whl",hashes = {sha256 = "fbb4f2400bfda24f12f009cba62ad5734148569ff4949b1b6ec3b519444342e6"}}, - {name = "pyzmq-27.1.0-cp313-cp313t-macosx_10_15_universal2.whl",url = "https://files.pythonhosted.org/packages/a5/ad/15906493fd40c316377fd8a8f6b1f93104f97a752667763c9b9c1b71d42d/pyzmq-27.1.0-cp313-cp313t-macosx_10_15_universal2.whl",hashes = {sha256 = "e343d067f7b151cfe4eb3bb796a7752c9d369eed007b91231e817071d2c2fec7"}}, - {name = "pyzmq-27.1.0-cp313-cp313t-manylinux2014_i686.manylinux_2_17_i686.whl",url = "https://files.pythonhosted.org/packages/14/1d/d343f3ce13db53a54cb8946594e567410b2125394dafcc0268d8dda027e0/pyzmq-27.1.0-cp313-cp313t-manylinux2014_i686.manylinux_2_17_i686.whl",hashes = {sha256 = "08363b2011dec81c354d694bdecaef4770e0ae96b9afea70b3f47b973655cc05"}}, - {name = "pyzmq-27.1.0-cp313-cp313t-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl",url = "https://files.pythonhosted.org/packages/69/2d/d83dd6d7ca929a2fc67d2c3005415cdf322af7751d773524809f9e585129/pyzmq-27.1.0-cp313-cp313t-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl",hashes = {sha256 = "d54530c8c8b5b8ddb3318f481297441af102517602b569146185fa10b63f4fa9"}}, - {name = "pyzmq-27.1.0-cp313-cp313t-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl",url = "https://files.pythonhosted.org/packages/3e/cd/9822a7af117f4bc0f1952dbe9ef8358eb50a24928efd5edf54210b850259/pyzmq-27.1.0-cp313-cp313t-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl",hashes = {sha256 = "6f3afa12c392f0a44a2414056d730eebc33ec0926aae92b5ad5cf26ebb6cc128"}}, - {name = "pyzmq-27.1.0-cp313-cp313t-musllinux_1_2_aarch64.whl",url = "https://files.pythonhosted.org/packages/9a/12/f003e824a19ed73be15542f172fd0ec4ad0b60cf37436652c93b9df7c585/pyzmq-27.1.0-cp313-cp313t-musllinux_1_2_aarch64.whl",hashes = {sha256 = "c65047adafe573ff023b3187bb93faa583151627bc9c51fc4fb2c561ed689d39"}}, - {name = "pyzmq-27.1.0-cp313-cp313t-musllinux_1_2_i686.whl",url = "https://files.pythonhosted.org/packages/d5/4a/e82d788ed58e9a23995cee70dbc20c9aded3d13a92d30d57ec2291f1e8a3/pyzmq-27.1.0-cp313-cp313t-musllinux_1_2_i686.whl",hashes = {sha256 = "90e6e9441c946a8b0a667356f7078d96411391a3b8f80980315455574177ec97"}}, - {name = "pyzmq-27.1.0-cp313-cp313t-musllinux_1_2_x86_64.whl",url = "https://files.pythonhosted.org/packages/d9/94/2da0a60841f757481e402b34bf4c8bf57fa54a5466b965de791b1e6f747d/pyzmq-27.1.0-cp313-cp313t-musllinux_1_2_x86_64.whl",hashes = {sha256 = "add071b2d25f84e8189aaf0882d39a285b42fa3853016ebab234a5e78c7a43db"}}, - {name = "pyzmq-27.1.0-cp313-cp313t-win32.whl",url = "https://files.pythonhosted.org/packages/4f/6f/55c10e2e49ad52d080dc24e37adb215e5b0d64990b57598abc2e3f01725b/pyzmq-27.1.0-cp313-cp313t-win32.whl",hashes = {sha256 = "7ccc0700cfdf7bd487bea8d850ec38f204478681ea02a582a8da8171b7f90a1c"}}, - {name = "pyzmq-27.1.0-cp313-cp313t-win_amd64.whl",url = "https://files.pythonhosted.org/packages/87/4d/2534970ba63dd7c522d8ca80fb92777f362c0f321900667c615e2067cb29/pyzmq-27.1.0-cp313-cp313t-win_amd64.whl",hashes = {sha256 = "8085a9fba668216b9b4323be338ee5437a235fe275b9d1610e422ccc279733e2"}}, - {name = "pyzmq-27.1.0-cp313-cp313t-win_arm64.whl",url = "https://files.pythonhosted.org/packages/f6/fa/f8aea7a28b0641f31d40dea42d7ef003fded31e184ef47db696bc74cd610/pyzmq-27.1.0-cp313-cp313t-win_arm64.whl",hashes = {sha256 = "6bb54ca21bcfe361e445256c15eedf083f153811c37be87e0514934d6913061e"}}, - {name = "pyzmq-27.1.0-cp312-abi3-macosx_10_15_universal2.whl",url = "https://files.pythonhosted.org/packages/92/e7/038aab64a946d535901103da16b953c8c9cc9c961dadcbf3609ed6428d23/pyzmq-27.1.0-cp312-abi3-macosx_10_15_universal2.whl",hashes = {sha256 = "452631b640340c928fa343801b0d07eb0c3789a5ffa843f6e1a9cee0ba4eb4fc"}}, - {name = "pyzmq-27.1.0-cp312-abi3-manylinux2014_i686.manylinux_2_17_i686.whl",url = "https://files.pythonhosted.org/packages/e8/5e/c3c49fdd0f535ef45eefcc16934648e9e59dace4a37ee88fc53f6cd8e641/pyzmq-27.1.0-cp312-abi3-manylinux2014_i686.manylinux_2_17_i686.whl",hashes = {sha256 = "1c179799b118e554b66da67d88ed66cd37a169f1f23b5d9f0a231b4e8d44a113"}}, - {name = "pyzmq-27.1.0-cp312-abi3-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl",url = "https://files.pythonhosted.org/packages/f8/e5/b0b2504cb4e903a74dcf1ebae157f9e20ebb6ea76095f6cfffea28c42ecd/pyzmq-27.1.0-cp312-abi3-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl",hashes = {sha256 = "3837439b7f99e60312f0c926a6ad437b067356dc2bc2ec96eb395fd0fe804233"}}, - {name = "pyzmq-27.1.0-cp312-abi3-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl",url = "https://files.pythonhosted.org/packages/f8/9b/c108cdb55560eaf253f0cbdb61b29971e9fb34d9c3499b0e96e4e60ed8a5/pyzmq-27.1.0-cp312-abi3-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl",hashes = {sha256 = "43ad9a73e3da1fab5b0e7e13402f0b2fb934ae1c876c51d0afff0e7c052eca31"}}, - {name = "pyzmq-27.1.0-cp312-abi3-musllinux_1_2_aarch64.whl",url = "https://files.pythonhosted.org/packages/c2/bb/b79798ca177b9eb0825b4c9998c6af8cd2a7f15a6a1a4272c1d1a21d382f/pyzmq-27.1.0-cp312-abi3-musllinux_1_2_aarch64.whl",hashes = {sha256 = "0de3028d69d4cdc475bfe47a6128eb38d8bc0e8f4d69646adfbcd840facbac28"}}, - {name = "pyzmq-27.1.0-cp312-abi3-musllinux_1_2_i686.whl",url = "https://files.pythonhosted.org/packages/9c/80/2df2e7977c4ede24c79ae39dcef3899bfc5f34d1ca7a5b24f182c9b7a9ca/pyzmq-27.1.0-cp312-abi3-musllinux_1_2_i686.whl",hashes = {sha256 = "cf44a7763aea9298c0aa7dbf859f87ed7012de8bda0f3977b6fb1d96745df856"}}, - {name = "pyzmq-27.1.0-cp312-abi3-musllinux_1_2_x86_64.whl",url = "https://files.pythonhosted.org/packages/46/bd/2d45ad24f5f5ae7e8d01525eb76786fa7557136555cac7d929880519e33a/pyzmq-27.1.0-cp312-abi3-musllinux_1_2_x86_64.whl",hashes = {sha256 = "f30f395a9e6fbca195400ce833c731e7b64c3919aa481af4d88c3759e0cb7496"}}, - {name = "pyzmq-27.1.0-cp312-abi3-win32.whl",url = "https://files.pythonhosted.org/packages/e6/2f/104c0a3c778d7c2ab8190e9db4f62f0b6957b53c9d87db77c284b69f33ea/pyzmq-27.1.0-cp312-abi3-win32.whl",hashes = {sha256 = "250e5436a4ba13885494412b3da5d518cd0d3a278a1ae640e113c073a5f88edd"}}, - {name = "pyzmq-27.1.0-cp312-abi3-win_amd64.whl",url = "https://files.pythonhosted.org/packages/fc/7f/a21b20d577e4100c6a41795842028235998a643b1ad406a6d4163ea8f53e/pyzmq-27.1.0-cp312-abi3-win_amd64.whl",hashes = {sha256 = "9ce490cf1d2ca2ad84733aa1d69ce6855372cb5ce9223802450c9b2a7cba0ccf"}}, - {name = "pyzmq-27.1.0-cp312-abi3-win_arm64.whl",url = "https://files.pythonhosted.org/packages/78/c2/c012beae5f76b72f007a9e91ee9401cb88c51d0f83c6257a03e785c81cc2/pyzmq-27.1.0-cp312-abi3-win_arm64.whl",hashes = {sha256 = "75a2f36223f0d535a0c919e23615fc85a1e23b71f40c7eb43d7b1dedb4d8f15f"}}, - {name = "pyzmq-27.1.0-cp311-cp311-macosx_10_15_universal2.whl",url = "https://files.pythonhosted.org/packages/06/5d/305323ba86b284e6fcb0d842d6adaa2999035f70f8c38a9b6d21ad28c3d4/pyzmq-27.1.0-cp311-cp311-macosx_10_15_universal2.whl",hashes = {sha256 = "226b091818d461a3bef763805e75685e478ac17e9008f49fce2d3e52b3d58b86"}}, - {name = "pyzmq-27.1.0-cp311-cp311-manylinux2014_i686.manylinux_2_17_i686.whl",url = "https://files.pythonhosted.org/packages/bd/a0/fc7e78a23748ad5443ac3275943457e8452da67fda347e05260261108cbc/pyzmq-27.1.0-cp311-cp311-manylinux2014_i686.manylinux_2_17_i686.whl",hashes = {sha256 = "0790a0161c281ca9723f804871b4027f2e8b5a528d357c8952d08cd1a9c15581"}}, - {name = "pyzmq-27.1.0-cp311-cp311-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl",url = "https://files.pythonhosted.org/packages/7e/22/37d15eb05f3bdfa4abea6f6d96eb3bb58585fbd3e4e0ded4e743bc650c97/pyzmq-27.1.0-cp311-cp311-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl",hashes = {sha256 = "c895a6f35476b0c3a54e3eb6ccf41bf3018de937016e6e18748317f25d4e925f"}}, - {name = "pyzmq-27.1.0-cp311-cp311-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl",url = "https://files.pythonhosted.org/packages/b1/c4/2a6fe5111a01005fc7af3878259ce17684fabb8852815eda6225620f3c59/pyzmq-27.1.0-cp311-cp311-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl",hashes = {sha256 = "5bbf8d3630bf96550b3be8e1fc0fea5cbdc8d5466c1192887bd94869da17a63e"}}, - {name = "pyzmq-27.1.0-cp311-cp311-musllinux_1_2_aarch64.whl",url = "https://files.pythonhosted.org/packages/cb/eb/bfdcb41d0db9cd233d6fb22dc131583774135505ada800ebf14dfb0a7c40/pyzmq-27.1.0-cp311-cp311-musllinux_1_2_aarch64.whl",hashes = {sha256 = "15c8bd0fe0dabf808e2d7a681398c4e5ded70a551ab47482067a572c054c8e2e"}}, - {name = "pyzmq-27.1.0-cp311-cp311-musllinux_1_2_i686.whl",url = "https://files.pythonhosted.org/packages/ab/21/e3180ca269ed4a0de5c34417dfe71a8ae80421198be83ee619a8a485b0c7/pyzmq-27.1.0-cp311-cp311-musllinux_1_2_i686.whl",hashes = {sha256 = "bafcb3dd171b4ae9f19ee6380dfc71ce0390fefaf26b504c0e5f628d7c8c54f2"}}, - {name = "pyzmq-27.1.0-cp311-cp311-musllinux_1_2_x86_64.whl",url = "https://files.pythonhosted.org/packages/3b/b1/5e21d0b517434b7f33588ff76c177c5a167858cc38ef740608898cd329f2/pyzmq-27.1.0-cp311-cp311-musllinux_1_2_x86_64.whl",hashes = {sha256 = "e829529fcaa09937189178115c49c504e69289abd39967cd8a4c215761373394"}}, - {name = "pyzmq-27.1.0-cp311-cp311-win32.whl",url = "https://files.pythonhosted.org/packages/03/f2/44913a6ff6941905efc24a1acf3d3cb6146b636c546c7406c38c49c403d4/pyzmq-27.1.0-cp311-cp311-win32.whl",hashes = {sha256 = "6df079c47d5902af6db298ec92151db82ecb557af663098b92f2508c398bb54f"}}, - {name = "pyzmq-27.1.0-cp311-cp311-win_amd64.whl",url = "https://files.pythonhosted.org/packages/23/6d/d8d92a0eb270a925c9b4dd039c0b4dc10abc2fcbc48331788824ef113935/pyzmq-27.1.0-cp311-cp311-win_amd64.whl",hashes = {sha256 = "190cbf120fbc0fc4957b56866830def56628934a9d112aec0e2507aa6a032b97"}}, - {name = "pyzmq-27.1.0-cp311-cp311-win_arm64.whl",url = "https://files.pythonhosted.org/packages/ae/14/01afebc96c5abbbd713ecfc7469cfb1bc801c819a74ed5c9fad9a48801cb/pyzmq-27.1.0-cp311-cp311-win_arm64.whl",hashes = {sha256 = "eca6b47df11a132d1745eb3b5b5e557a7dae2c303277aa0e69c6ba91b8736e07"}}, - {name = "pyzmq-27.1.0-pp311-pypy311_pp73-macosx_10_15_x86_64.whl",url = "https://files.pythonhosted.org/packages/4c/c6/c4dcdecdbaa70969ee1fdced6d7b8f60cfabe64d25361f27ac4665a70620/pyzmq-27.1.0-pp311-pypy311_pp73-macosx_10_15_x86_64.whl",hashes = {sha256 = "18770c8d3563715387139060d37859c02ce40718d1faf299abddcdcc6a649066"}}, - {name = "pyzmq-27.1.0-pp311-pypy311_pp73-manylinux2014_i686.manylinux_2_17_i686.whl",url = "https://files.pythonhosted.org/packages/3e/79/f38c92eeaeb03a2ccc2ba9866f0439593bb08c5e3b714ac1d553e5c96e25/pyzmq-27.1.0-pp311-pypy311_pp73-manylinux2014_i686.manylinux_2_17_i686.whl",hashes = {sha256 = "ac25465d42f92e990f8d8b0546b01c391ad431c3bf447683fdc40565941d0604"}}, - {name = "pyzmq-27.1.0-pp311-pypy311_pp73-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl",url = "https://files.pythonhosted.org/packages/49/0e/3f0d0d335c6b3abb9b7b723776d0b21fa7f3a6c819a0db6097059aada160/pyzmq-27.1.0-pp311-pypy311_pp73-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl",hashes = {sha256 = "53b40f8ae006f2734ee7608d59ed661419f087521edbfc2149c3932e9c14808c"}}, - {name = "pyzmq-27.1.0-pp311-pypy311_pp73-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl",url = "https://files.pythonhosted.org/packages/a1/cf/f2b3784d536250ffd4be70e049f3b60981235d70c6e8ce7e3ef21e1adb25/pyzmq-27.1.0-pp311-pypy311_pp73-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl",hashes = {sha256 = "f605d884e7c8be8fe1aa94e0a783bf3f591b84c24e4bc4f3e7564c82ac25e271"}}, - {name = "pyzmq-27.1.0-pp311-pypy311_pp73-win_amd64.whl",url = "https://files.pythonhosted.org/packages/01/1b/5dbe84eefc86f48473947e2f41711aded97eecef1231f4558f1f02713c12/pyzmq-27.1.0-pp311-pypy311_pp73-win_amd64.whl",hashes = {sha256 = "c9f7f6e13dff2e44a6afeaf2cf54cee5929ad64afaf4d40b50f93c58fc687355"}}, -] -marker = "\"docs\" in extras" - -[packages.tool.pdm] -dependencies = [ - "cffi; implementation_name == \"pypy\"", -] - -[[packages]] -name = "referencing" -version = "0.37.0" -requires-python = ">=3.10" -sdist = {name = "referencing-0.37.0.tar.gz", url = "https://files.pythonhosted.org/packages/22/f5/df4e9027acead3ecc63e50fe1e36aca1523e1719559c499951bb4b53188f/referencing-0.37.0.tar.gz", hashes = {sha256 = "44aefc3142c5b842538163acb373e24cce6632bd54bdb01b21ad5863489f50d8"}} -wheels = [ - {name = "referencing-0.37.0-py3-none-any.whl",url = "https://files.pythonhosted.org/packages/2c/58/ca301544e1fa93ed4f80d724bf5b194f6e4b945841c5bfd555878eea9fcb/referencing-0.37.0-py3-none-any.whl",hashes = {sha256 = "381329a9f99628c9069361716891d34ad94af76e461dcb0335825aecc7692231"}}, -] -marker = "\"docs\" in extras" - -[packages.tool.pdm] -dependencies = [ - "attrs>=22.2.0", - "rpds-py>=0.7.0", - "typing-extensions>=4.4.0; python_version < \"3.13\"", -] - -[[packages]] -name = "requests" -version = "2.33.1" -requires-python = ">=3.10" -sdist = {name = "requests-2.33.1.tar.gz", url = "https://files.pythonhosted.org/packages/5f/a4/98b9c7c6428a668bf7e42ebb7c79d576a1c3c1e3ae2d47e674b468388871/requests-2.33.1.tar.gz", hashes = {sha256 = "18817f8c57c6263968bc123d237e3b8b08ac046f5456bd1e307ee8f4250d3517"}} -wheels = [ - {name = "requests-2.33.1-py3-none-any.whl",url = "https://files.pythonhosted.org/packages/d7/8e/7540e8a2036f79a125c1d2ebadf69ed7901608859186c856fa0388ef4197/requests-2.33.1-py3-none-any.whl",hashes = {sha256 = "4e6d1ef462f3626a1f0a0a9c42dd93c63bad33f9f1c1937509b8c5c8718ab56a"}}, -] -marker = "\"default\" in dependency_groups or \"docs\" in extras" - -[packages.tool.pdm] -dependencies = [ - "certifi>=2023.5.7", - "charset-normalizer<4,>=2", - "idna<4,>=2.5", - "urllib3<3,>=1.26", -] - -[[packages]] -name = "roman-numerals" -version = "4.1.0" -requires-python = ">=3.10" -sdist = {name = "roman_numerals-4.1.0.tar.gz", url = "https://files.pythonhosted.org/packages/ae/f9/41dc953bbeb056c17d5f7a519f50fdf010bd0553be2d630bc69d1e022703/roman_numerals-4.1.0.tar.gz", hashes = {sha256 = "1af8b147eb1405d5839e78aeb93131690495fe9da5c91856cb33ad55a7f1e5b2"}} -wheels = [ - {name = "roman_numerals-4.1.0-py3-none-any.whl",url = "https://files.pythonhosted.org/packages/04/54/6f679c435d28e0a568d8e8a7c0a93a09010818634c3c3907fc98d8983770/roman_numerals-4.1.0-py3-none-any.whl",hashes = {sha256 = "647ba99caddc2cc1e55a51e4360689115551bf4476d90e8162cf8c345fe233c7"}}, -] -marker = "\"docs\" in extras" - -[packages.tool.pdm] -dependencies = [] - -[[packages]] -name = "rpds-py" -version = "0.30.0" -requires-python = ">=3.10" -sdist = {name = "rpds_py-0.30.0.tar.gz", url = "https://files.pythonhosted.org/packages/20/af/3f2f423103f1113b36230496629986e0ef7e199d2aa8392452b484b38ced/rpds_py-0.30.0.tar.gz", hashes = {sha256 = "dd8ff7cf90014af0c0f787eea34794ebf6415242ee1d6fa91eaba725cc441e84"}} -wheels = [ - {name = "rpds_py-0.30.0-cp314-cp314-macosx_10_12_x86_64.whl",url = "https://files.pythonhosted.org/packages/86/81/dad16382ebbd3d0e0328776d8fd7ca94220e4fa0798d1dc5e7da48cb3201/rpds_py-0.30.0-cp314-cp314-macosx_10_12_x86_64.whl",hashes = {sha256 = "68f19c879420aa08f61203801423f6cd5ac5f0ac4ac82a2368a9fcd6a9a075e0"}}, - {name = "rpds_py-0.30.0-cp314-cp314-macosx_11_0_arm64.whl",url = "https://files.pythonhosted.org/packages/2b/60/19f7884db5d5603edf3c6bce35408f45ad3e97e10007df0e17dd57af18f8/rpds_py-0.30.0-cp314-cp314-macosx_11_0_arm64.whl",hashes = {sha256 = "ec7c4490c672c1a0389d319b3a9cfcd098dcdc4783991553c332a15acf7249be"}}, - {name = "rpds_py-0.30.0-cp314-cp314-manylinux_2_17_aarch64.manylinux2014_aarch64.whl",url = "https://files.pythonhosted.org/packages/bf/c4/76eb0e1e72d1a9c4703c69607cec123c29028bff28ce41588792417098ac/rpds_py-0.30.0-cp314-cp314-manylinux_2_17_aarch64.manylinux2014_aarch64.whl",hashes = {sha256 = "f251c812357a3fed308d684a5079ddfb9d933860fc6de89f2b7ab00da481e65f"}}, - {name = "rpds_py-0.30.0-cp314-cp314-manylinux_2_17_armv7l.manylinux2014_armv7l.whl",url = "https://files.pythonhosted.org/packages/72/87/87ea665e92f3298d1b26d78814721dc39ed8d2c74b86e83348d6b48a6f31/rpds_py-0.30.0-cp314-cp314-manylinux_2_17_armv7l.manylinux2014_armv7l.whl",hashes = {sha256 = "ac98b175585ecf4c0348fd7b29c3864bda53b805c773cbf7bfdaffc8070c976f"}}, - {name = "rpds_py-0.30.0-cp314-cp314-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl",url = "https://files.pythonhosted.org/packages/77/ad/7783a89ca0587c15dcbf139b4a8364a872a25f861bdb88ed99f9b0dec985/rpds_py-0.30.0-cp314-cp314-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl",hashes = {sha256 = "3e62880792319dbeb7eb866547f2e35973289e7d5696c6e295476448f5b63c87"}}, - {name = "rpds_py-0.30.0-cp314-cp314-manylinux_2_17_s390x.manylinux2014_s390x.whl",url = "https://files.pythonhosted.org/packages/5b/3c/2882bdac942bd2172f3da574eab16f309ae10a3925644e969536553cb4ee/rpds_py-0.30.0-cp314-cp314-manylinux_2_17_s390x.manylinux2014_s390x.whl",hashes = {sha256 = "4e7fc54e0900ab35d041b0601431b0a0eb495f0851a0639b6ef90f7741b39a18"}}, - {name = "rpds_py-0.30.0-cp314-cp314-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",url = "https://files.pythonhosted.org/packages/ce/81/9a91c0111ce1758c92516a3e44776920b579d9a7c09b2b06b642d4de3f0f/rpds_py-0.30.0-cp314-cp314-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",hashes = {sha256 = "47e77dc9822d3ad616c3d5759ea5631a75e5809d5a28707744ef79d7a1bcfcad"}}, - {name = "rpds_py-0.30.0-cp314-cp314-manylinux_2_31_riscv64.whl",url = "https://files.pythonhosted.org/packages/cf/8e/1da49d4a107027e5fbc64daeab96a0706361a2918da10cb41769244b805d/rpds_py-0.30.0-cp314-cp314-manylinux_2_31_riscv64.whl",hashes = {sha256 = "b4dc1a6ff022ff85ecafef7979a2c6eb423430e05f1165d6688234e62ba99a07"}}, - {name = "rpds_py-0.30.0-cp314-cp314-manylinux_2_5_i686.manylinux1_i686.whl",url = "https://files.pythonhosted.org/packages/df/5a/7ee239b1aa48a127570ec03becbb29c9d5a9eb092febbd1699d567cae859/rpds_py-0.30.0-cp314-cp314-manylinux_2_5_i686.manylinux1_i686.whl",hashes = {sha256 = "4559c972db3a360808309e06a74628b95eaccbf961c335c8fe0d590cf587456f"}}, - {name = "rpds_py-0.30.0-cp314-cp314-musllinux_1_2_aarch64.whl",url = "https://files.pythonhosted.org/packages/70/ea/caa143cf6b772f823bc7929a45da1fa83569ee49b11d18d0ada7f5ee6fd6/rpds_py-0.30.0-cp314-cp314-musllinux_1_2_aarch64.whl",hashes = {sha256 = "0ed177ed9bded28f8deb6ab40c183cd1192aa0de40c12f38be4d59cd33cb5c65"}}, - {name = "rpds_py-0.30.0-cp314-cp314-musllinux_1_2_i686.whl",url = "https://files.pythonhosted.org/packages/64/91/ac20ba2d69303f961ad8cf55bf7dbdb4763f627291ba3d0d7d67333cced9/rpds_py-0.30.0-cp314-cp314-musllinux_1_2_i686.whl",hashes = {sha256 = "ad1fa8db769b76ea911cb4e10f049d80bf518c104f15b3edb2371cc65375c46f"}}, - {name = "rpds_py-0.30.0-cp314-cp314-musllinux_1_2_x86_64.whl",url = "https://files.pythonhosted.org/packages/21/20/7ff5f3c8b00c8a95f75985128c26ba44503fb35b8e0259d812766ea966c7/rpds_py-0.30.0-cp314-cp314-musllinux_1_2_x86_64.whl",hashes = {sha256 = "46e83c697b1f1c72b50e5ee5adb4353eef7406fb3f2043d64c33f20ad1c2fc53"}}, - {name = "rpds_py-0.30.0-cp314-cp314-win32.whl",url = "https://files.pythonhosted.org/packages/72/c7/81dadd7b27c8ee391c132a6b192111ca58d866577ce2d9b0ca157552cce0/rpds_py-0.30.0-cp314-cp314-win32.whl",hashes = {sha256 = "ee454b2a007d57363c2dfd5b6ca4a5d7e2c518938f8ed3b706e37e5d470801ed"}}, - {name = "rpds_py-0.30.0-cp314-cp314-win_amd64.whl",url = "https://files.pythonhosted.org/packages/3e/d2/1aaac33287e8cfb07aab2e6b8ac1deca62f6f65411344f1433c55e6f3eb8/rpds_py-0.30.0-cp314-cp314-win_amd64.whl",hashes = {sha256 = "95f0802447ac2d10bcc69f6dc28fe95fdf17940367b21d34e34c737870758950"}}, - {name = "rpds_py-0.30.0-cp314-cp314-win_arm64.whl",url = "https://files.pythonhosted.org/packages/e8/95/ab005315818cc519ad074cb7784dae60d939163108bd2b394e60dc7b5461/rpds_py-0.30.0-cp314-cp314-win_arm64.whl",hashes = {sha256 = "613aa4771c99f03346e54c3f038e4cc574ac09a3ddfb0e8878487335e96dead6"}}, - {name = "rpds_py-0.30.0-cp314-cp314t-macosx_10_12_x86_64.whl",url = "https://files.pythonhosted.org/packages/9e/68/154fe0194d83b973cdedcdcc88947a2752411165930182ae41d983dcefa6/rpds_py-0.30.0-cp314-cp314t-macosx_10_12_x86_64.whl",hashes = {sha256 = "7e6ecfcb62edfd632e56983964e6884851786443739dbfe3582947e87274f7cb"}}, - {name = "rpds_py-0.30.0-cp314-cp314t-macosx_11_0_arm64.whl",url = "https://files.pythonhosted.org/packages/83/69/8bbc8b07ec854d92a8b75668c24d2abcb1719ebf890f5604c61c9369a16f/rpds_py-0.30.0-cp314-cp314t-macosx_11_0_arm64.whl",hashes = {sha256 = "a1d0bc22a7cdc173fedebb73ef81e07faef93692b8c1ad3733b67e31e1b6e1b8"}}, - {name = "rpds_py-0.30.0-cp314-cp314t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl",url = "https://files.pythonhosted.org/packages/ab/00/ba2e50183dbd9abcce9497fa5149c62b4ff3e22d338a30d690f9af970561/rpds_py-0.30.0-cp314-cp314t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl",hashes = {sha256 = "0d08f00679177226c4cb8c5265012eea897c8ca3b93f429e546600c971bcbae7"}}, - {name = "rpds_py-0.30.0-cp314-cp314t-manylinux_2_17_armv7l.manylinux2014_armv7l.whl",url = "https://files.pythonhosted.org/packages/05/6f/86f0272b84926bcb0e4c972262f54223e8ecc556b3224d281e6598fc9268/rpds_py-0.30.0-cp314-cp314t-manylinux_2_17_armv7l.manylinux2014_armv7l.whl",hashes = {sha256 = "5965af57d5848192c13534f90f9dd16464f3c37aaf166cc1da1cae1fd5a34898"}}, - {name = "rpds_py-0.30.0-cp314-cp314t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl",url = "https://files.pythonhosted.org/packages/cb/e9/0e02bb2e6dc63d212641da45df2b0bf29699d01715913e0d0f017ee29438/rpds_py-0.30.0-cp314-cp314t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl",hashes = {sha256 = "9a4e86e34e9ab6b667c27f3211ca48f73dba7cd3d90f8d5b11be56e5dbc3fb4e"}}, - {name = "rpds_py-0.30.0-cp314-cp314t-manylinux_2_17_s390x.manylinux2014_s390x.whl",url = "https://files.pythonhosted.org/packages/ee/ca/be7bca14cf21513bdf9c0606aba17d1f389ea2b6987035eb4f62bd923f25/rpds_py-0.30.0-cp314-cp314t-manylinux_2_17_s390x.manylinux2014_s390x.whl",hashes = {sha256 = "e5d3e6b26f2c785d65cc25ef1e5267ccbe1b069c5c21b8cc724efee290554419"}}, - {name = "rpds_py-0.30.0-cp314-cp314t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",url = "https://files.pythonhosted.org/packages/c2/c7/736e00ebf39ed81d75544c0da6ef7b0998f8201b369acf842f9a90dc8fce/rpds_py-0.30.0-cp314-cp314t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",hashes = {sha256 = "626a7433c34566535b6e56a1b39a7b17ba961e97ce3b80ec62e6f1312c025551"}}, - {name = "rpds_py-0.30.0-cp314-cp314t-manylinux_2_31_riscv64.whl",url = "https://files.pythonhosted.org/packages/4a/3f/da50dfde9956aaf365c4adc9533b100008ed31aea635f2b8d7b627e25b49/rpds_py-0.30.0-cp314-cp314t-manylinux_2_31_riscv64.whl",hashes = {sha256 = "acd7eb3f4471577b9b5a41baf02a978e8bdeb08b4b355273994f8b87032000a8"}}, - {name = "rpds_py-0.30.0-cp314-cp314t-manylinux_2_5_i686.manylinux1_i686.whl",url = "https://files.pythonhosted.org/packages/4e/00/34bcc2565b6020eab2623349efbdec810676ad571995911f1abdae62a3a0/rpds_py-0.30.0-cp314-cp314t-manylinux_2_5_i686.manylinux1_i686.whl",hashes = {sha256 = "fe5fa731a1fa8a0a56b0977413f8cacac1768dad38d16b3a296712709476fbd5"}}, - {name = "rpds_py-0.30.0-cp314-cp314t-musllinux_1_2_aarch64.whl",url = "https://files.pythonhosted.org/packages/8c/28/882e72b5b3e6f718d5453bd4d0d9cf8df36fddeb4ddbbab17869d5868616/rpds_py-0.30.0-cp314-cp314t-musllinux_1_2_aarch64.whl",hashes = {sha256 = "74a3243a411126362712ee1524dfc90c650a503502f135d54d1b352bd01f2404"}}, - {name = "rpds_py-0.30.0-cp314-cp314t-musllinux_1_2_i686.whl",url = "https://files.pythonhosted.org/packages/3b/97/04a65539c17692de5b85c6e293520fd01317fd878ea1995f0367d4532fb1/rpds_py-0.30.0-cp314-cp314t-musllinux_1_2_i686.whl",hashes = {sha256 = "3e8eeb0544f2eb0d2581774be4c3410356eba189529a6b3e36bbbf9696175856"}}, - {name = "rpds_py-0.30.0-cp314-cp314t-musllinux_1_2_x86_64.whl",url = "https://files.pythonhosted.org/packages/85/70/92482ccffb96f5441aab93e26c4d66489eb599efdcf96fad90c14bbfb976/rpds_py-0.30.0-cp314-cp314t-musllinux_1_2_x86_64.whl",hashes = {sha256 = "dbd936cde57abfee19ab3213cf9c26be06d60750e60a8e4dd85d1ab12c8b1f40"}}, - {name = "rpds_py-0.30.0-cp314-cp314t-win32.whl",url = "https://files.pythonhosted.org/packages/20/53/7c7e784abfa500a2b6b583b147ee4bb5a2b3747a9166bab52fec4b5b5e7d/rpds_py-0.30.0-cp314-cp314t-win32.whl",hashes = {sha256 = "dc824125c72246d924f7f796b4f63c1e9dc810c7d9e2355864b3c3a73d59ade0"}}, - {name = "rpds_py-0.30.0-cp314-cp314t-win_amd64.whl",url = "https://files.pythonhosted.org/packages/d0/02/fa464cdfbe6b26e0600b62c528b72d8608f5cc49f96b8d6e38c95d60c676/rpds_py-0.30.0-cp314-cp314t-win_amd64.whl",hashes = {sha256 = "27f4b0e92de5bfbc6f86e43959e6edd1425c33b5e69aab0984a72047f2bcf1e3"}}, - {name = "rpds_py-0.30.0-cp313-cp313-macosx_10_12_x86_64.whl",url = "https://files.pythonhosted.org/packages/ed/dc/d61221eb88ff410de3c49143407f6f3147acf2538c86f2ab7ce65ae7d5f9/rpds_py-0.30.0-cp313-cp313-macosx_10_12_x86_64.whl",hashes = {sha256 = "f83424d738204d9770830d35290ff3273fbb02b41f919870479fab14b9d303b2"}}, - {name = "rpds_py-0.30.0-cp313-cp313-macosx_11_0_arm64.whl",url = "https://files.pythonhosted.org/packages/fd/32/55fb50ae104061dbc564ef15cc43c013dc4a9f4527a1f4d99baddf56fe5f/rpds_py-0.30.0-cp313-cp313-macosx_11_0_arm64.whl",hashes = {sha256 = "e7536cd91353c5273434b4e003cbda89034d67e7710eab8761fd918ec6c69cf8"}}, - {name = "rpds_py-0.30.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl",url = "https://files.pythonhosted.org/packages/58/70/faed8186300e3b9bdd138d0273109784eea2396c68458ed580f885dfe7ad/rpds_py-0.30.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl",hashes = {sha256 = "2771c6c15973347f50fece41fc447c054b7ac2ae0502388ce3b6738cd366e3d4"}}, - {name = "rpds_py-0.30.0-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl",url = "https://files.pythonhosted.org/packages/bd/a8/073cac3ed2c6387df38f71296d002ab43496a96b92c823e76f46b8af0543/rpds_py-0.30.0-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl",hashes = {sha256 = "0a59119fc6e3f460315fe9d08149f8102aa322299deaa5cab5b40092345c2136"}}, - {name = "rpds_py-0.30.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl",url = "https://files.pythonhosted.org/packages/77/57/5999eb8c58671f1c11eba084115e77a8899d6e694d2a18f69f0ba471ec8b/rpds_py-0.30.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl",hashes = {sha256 = "76fec018282b4ead0364022e3c54b60bf368b9d926877957a8624b58419169b7"}}, - {name = "rpds_py-0.30.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl",url = "https://files.pythonhosted.org/packages/e0/af/5ab4833eadc36c0a8ed2bc5c0de0493c04f6c06de223170bd0798ff98ced/rpds_py-0.30.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl",hashes = {sha256 = "692bef75a5525db97318e8cd061542b5a79812d711ea03dbc1f6f8dbb0c5f0d2"}}, - {name = "rpds_py-0.30.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",url = "https://files.pythonhosted.org/packages/b7/de/f7192e12b21b9e9a68a6d0f249b4af3fdcdff8418be0767a627564afa1f1/rpds_py-0.30.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",hashes = {sha256 = "9027da1ce107104c50c81383cae773ef5c24d296dd11c99e2629dbd7967a20c6"}}, - {name = "rpds_py-0.30.0-cp313-cp313-manylinux_2_31_riscv64.whl",url = "https://files.pythonhosted.org/packages/91/c4/fc70cd0249496493500e7cc2de87504f5aa6509de1e88623431fec76d4b6/rpds_py-0.30.0-cp313-cp313-manylinux_2_31_riscv64.whl",hashes = {sha256 = "9cf69cdda1f5968a30a359aba2f7f9aa648a9ce4b580d6826437f2b291cfc86e"}}, - {name = "rpds_py-0.30.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl",url = "https://files.pythonhosted.org/packages/58/95/d9275b05ab96556fefff73a385813eb66032e4c99f411d0795372d9abcea/rpds_py-0.30.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl",hashes = {sha256 = "a4796a717bf12b9da9d3ad002519a86063dcac8988b030e405704ef7d74d2d9d"}}, - {name = "rpds_py-0.30.0-cp313-cp313-musllinux_1_2_aarch64.whl",url = "https://files.pythonhosted.org/packages/06/c1/3088fc04b6624eb12a57eb814f0d4997a44b0d208d6cace713033ff1a6ba/rpds_py-0.30.0-cp313-cp313-musllinux_1_2_aarch64.whl",hashes = {sha256 = "5d4c2aa7c50ad4728a094ebd5eb46c452e9cb7edbfdb18f9e1221f597a73e1e7"}}, - {name = "rpds_py-0.30.0-cp313-cp313-musllinux_1_2_i686.whl",url = "https://files.pythonhosted.org/packages/d8/42/c612a833183b39774e8ac8fecae81263a68b9583ee343db33ab571a7ce55/rpds_py-0.30.0-cp313-cp313-musllinux_1_2_i686.whl",hashes = {sha256 = "ba81a9203d07805435eb06f536d95a266c21e5b2dfbf6517748ca40c98d19e31"}}, - {name = "rpds_py-0.30.0-cp313-cp313-musllinux_1_2_x86_64.whl",url = "https://files.pythonhosted.org/packages/5f/60/525a50f45b01d70005403ae0e25f43c0384369ad24ffe46e8d9068b50086/rpds_py-0.30.0-cp313-cp313-musllinux_1_2_x86_64.whl",hashes = {sha256 = "945dccface01af02675628334f7cf49c2af4c1c904748efc5cf7bbdf0b579f95"}}, - {name = "rpds_py-0.30.0-cp313-cp313-win32.whl",url = "https://files.pythonhosted.org/packages/0b/5d/47c4655e9bcd5ca907148535c10e7d489044243cc9941c16ed7cd53be91d/rpds_py-0.30.0-cp313-cp313-win32.whl",hashes = {sha256 = "b40fb160a2db369a194cb27943582b38f79fc4887291417685f3ad693c5a1d5d"}}, - {name = "rpds_py-0.30.0-cp313-cp313-win_amd64.whl",url = "https://files.pythonhosted.org/packages/f2/e1/485132437d20aa4d3e1d8b3fb5a5e65aa8139f1e097080c2a8443201742c/rpds_py-0.30.0-cp313-cp313-win_amd64.whl",hashes = {sha256 = "806f36b1b605e2d6a72716f321f20036b9489d29c51c91f4dd29a3e3afb73b15"}}, - {name = "rpds_py-0.30.0-cp313-cp313-win_arm64.whl",url = "https://files.pythonhosted.org/packages/24/95/ffd128ed1146a153d928617b0ef673960130be0009c77d8fbf0abe306713/rpds_py-0.30.0-cp313-cp313-win_arm64.whl",hashes = {sha256 = "d96c2086587c7c30d44f31f42eae4eac89b60dabbac18c7669be3700f13c3ce1"}}, - {name = "rpds_py-0.30.0-cp313-cp313t-macosx_10_12_x86_64.whl",url = "https://files.pythonhosted.org/packages/ff/1b/b10de890a0def2a319a2626334a7f0ae388215eb60914dbac8a3bae54435/rpds_py-0.30.0-cp313-cp313t-macosx_10_12_x86_64.whl",hashes = {sha256 = "eb0b93f2e5c2189ee831ee43f156ed34e2a89a78a66b98cadad955972548be5a"}}, - {name = "rpds_py-0.30.0-cp313-cp313t-macosx_11_0_arm64.whl",url = "https://files.pythonhosted.org/packages/0d/bf/27e39f5971dc4f305a4fb9c672ca06f290f7c4e261c568f3dea16a410d47/rpds_py-0.30.0-cp313-cp313t-macosx_11_0_arm64.whl",hashes = {sha256 = "922e10f31f303c7c920da8981051ff6d8c1a56207dbdf330d9047f6d30b70e5e"}}, - {name = "rpds_py-0.30.0-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl",url = "https://files.pythonhosted.org/packages/40/58/442ada3bba6e8e6615fc00483135c14a7538d2ffac30e2d933ccf6852232/rpds_py-0.30.0-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl",hashes = {sha256 = "cdc62c8286ba9bf7f47befdcea13ea0e26bf294bda99758fd90535cbaf408000"}}, - {name = "rpds_py-0.30.0-cp313-cp313t-manylinux_2_17_armv7l.manylinux2014_armv7l.whl",url = "https://files.pythonhosted.org/packages/14/14/f59b0127409a33c6ef6f5c1ebd5ad8e32d7861c9c7adfa9a624fc3889f6c/rpds_py-0.30.0-cp313-cp313t-manylinux_2_17_armv7l.manylinux2014_armv7l.whl",hashes = {sha256 = "47f9a91efc418b54fb8190a6b4aa7813a23fb79c51f4bb84e418f5476c38b8db"}}, - {name = "rpds_py-0.30.0-cp313-cp313t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl",url = "https://files.pythonhosted.org/packages/b3/66/e0be3e162ac299b3a22527e8913767d869e6cc75c46bd844aa43fb81ab62/rpds_py-0.30.0-cp313-cp313t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl",hashes = {sha256 = "1f3587eb9b17f3789ad50824084fa6f81921bbf9a795826570bda82cb3ed91f2"}}, - {name = "rpds_py-0.30.0-cp313-cp313t-manylinux_2_17_s390x.manylinux2014_s390x.whl",url = "https://files.pythonhosted.org/packages/3d/55/fa3b9cf31d0c963ecf1ba777f7cf4b2a2c976795ac430d24a1f43d25a6ba/rpds_py-0.30.0-cp313-cp313t-manylinux_2_17_s390x.manylinux2014_s390x.whl",hashes = {sha256 = "39c02563fc592411c2c61d26b6c5fe1e51eaa44a75aa2c8735ca88b0d9599daa"}}, - {name = "rpds_py-0.30.0-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",url = "https://files.pythonhosted.org/packages/60/ca/780cf3b1a32b18c0f05c441958d3758f02544f1d613abf9488cd78876378/rpds_py-0.30.0-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",hashes = {sha256 = "51a1234d8febafdfd33a42d97da7a43f5dcb120c1060e352a3fbc0c6d36e2083"}}, - {name = "rpds_py-0.30.0-cp313-cp313t-manylinux_2_31_riscv64.whl",url = "https://files.pythonhosted.org/packages/82/86/d5f2e04f2aa6247c613da0c1dd87fcd08fa17107e858193566048a1e2f0a/rpds_py-0.30.0-cp313-cp313t-manylinux_2_31_riscv64.whl",hashes = {sha256 = "eb2c4071ab598733724c08221091e8d80e89064cd472819285a9ab0f24bcedb9"}}, - {name = "rpds_py-0.30.0-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.whl",url = "https://files.pythonhosted.org/packages/4b/9a/453255d2f769fe44e07ea9785c8347edaf867f7026872e76c1ad9f7bed92/rpds_py-0.30.0-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.whl",hashes = {sha256 = "6bdfdb946967d816e6adf9a3d8201bfad269c67efe6cefd7093ef959683c8de0"}}, - {name = "rpds_py-0.30.0-cp313-cp313t-musllinux_1_2_aarch64.whl",url = "https://files.pythonhosted.org/packages/a3/31/622a86cdc0c45d6df0e9ccb6becdba5074735e7033c20e401a6d9d0e2ca0/rpds_py-0.30.0-cp313-cp313t-musllinux_1_2_aarch64.whl",hashes = {sha256 = "c77afbd5f5250bf27bf516c7c4a016813eb2d3e116139aed0096940c5982da94"}}, - {name = "rpds_py-0.30.0-cp313-cp313t-musllinux_1_2_i686.whl",url = "https://files.pythonhosted.org/packages/1c/5d/15bbf0fb4a3f58a3b1c67855ec1efcc4ceaef4e86644665fff03e1b66d8d/rpds_py-0.30.0-cp313-cp313t-musllinux_1_2_i686.whl",hashes = {sha256 = "61046904275472a76c8c90c9ccee9013d70a6d0f73eecefd38c1ae7c39045a08"}}, - {name = "rpds_py-0.30.0-cp313-cp313t-musllinux_1_2_x86_64.whl",url = "https://files.pythonhosted.org/packages/6d/61/21b8c41f68e60c8cc3b2e25644f0e3681926020f11d06ab0b78e3c6bbff1/rpds_py-0.30.0-cp313-cp313t-musllinux_1_2_x86_64.whl",hashes = {sha256 = "4c5f36a861bc4b7da6516dbdf302c55313afa09b81931e8280361a4f6c9a2d27"}}, - {name = "rpds_py-0.30.0-cp313-cp313t-win32.whl",url = "https://files.pythonhosted.org/packages/f9/39/7e067bb06c31de48de3eb200f9fc7c58982a4d3db44b07e73963e10d3be9/rpds_py-0.30.0-cp313-cp313t-win32.whl",hashes = {sha256 = "3d4a69de7a3e50ffc214ae16d79d8fbb0922972da0356dcf4d0fdca2878559c6"}}, - {name = "rpds_py-0.30.0-cp313-cp313t-win_amd64.whl",url = "https://files.pythonhosted.org/packages/0a/4d/222ef0b46443cf4cf46764d9c630f3fe4abaa7245be9417e56e9f52b8f65/rpds_py-0.30.0-cp313-cp313t-win_amd64.whl",hashes = {sha256 = "f14fc5df50a716f7ece6a80b6c78bb35ea2ca47c499e422aa4463455dd96d56d"}}, - {name = "rpds_py-0.30.0-cp312-cp312-macosx_10_12_x86_64.whl",url = "https://files.pythonhosted.org/packages/03/e7/98a2f4ac921d82f33e03f3835f5bf3a4a40aa1bfdc57975e74a97b2b4bdd/rpds_py-0.30.0-cp312-cp312-macosx_10_12_x86_64.whl",hashes = {sha256 = "a161f20d9a43006833cd7068375a94d035714d73a172b681d8881820600abfad"}}, - {name = "rpds_py-0.30.0-cp312-cp312-macosx_11_0_arm64.whl",url = "https://files.pythonhosted.org/packages/4d/a1/bca7fd3d452b272e13335db8d6b0b3ecde0f90ad6f16f3328c6fb150c889/rpds_py-0.30.0-cp312-cp312-macosx_11_0_arm64.whl",hashes = {sha256 = "6abc8880d9d036ecaafe709079969f56e876fcf107f7a8e9920ba6d5a3878d05"}}, - {name = "rpds_py-0.30.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl",url = "https://files.pythonhosted.org/packages/65/1c/ae157e83a6357eceff62ba7e52113e3ec4834a84cfe07fa4b0757a7d105f/rpds_py-0.30.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl",hashes = {sha256 = "ca28829ae5f5d569bb62a79512c842a03a12576375d5ece7d2cadf8abe96ec28"}}, - {name = "rpds_py-0.30.0-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl",url = "https://files.pythonhosted.org/packages/d4/36/eb2eb8515e2ad24c0bd43c3ee9cd74c33f7ca6430755ccdb240fd3144c44/rpds_py-0.30.0-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl",hashes = {sha256 = "a1010ed9524c73b94d15919ca4d41d8780980e1765babf85f9a2f90d247153dd"}}, - {name = "rpds_py-0.30.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl",url = "https://files.pythonhosted.org/packages/d6/65/ad8dc1784a331fabbd740ef6f71ce2198c7ed0890dab595adb9ea2d775a1/rpds_py-0.30.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl",hashes = {sha256 = "f8d1736cfb49381ba528cd5baa46f82fdc65c06e843dab24dd70b63d09121b3f"}}, - {name = "rpds_py-0.30.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl",url = "https://files.pythonhosted.org/packages/63/8e/0cfa7ae158e15e143fe03993b5bcd743a59f541f5952e1546b1ac1b5fd45/rpds_py-0.30.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl",hashes = {sha256 = "d948b135c4693daff7bc2dcfc4ec57237a29bd37e60c2fabf5aff2bbacf3e2f1"}}, - {name = "rpds_py-0.30.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",url = "https://files.pythonhosted.org/packages/60/1b/6f8f29f3f995c7ffdde46a626ddccd7c63aefc0efae881dc13b6e5d5bb16/rpds_py-0.30.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",hashes = {sha256 = "47f236970bccb2233267d89173d3ad2703cd36a0e2a6e92d0560d333871a3d23"}}, - {name = "rpds_py-0.30.0-cp312-cp312-manylinux_2_31_riscv64.whl",url = "https://files.pythonhosted.org/packages/6d/d5/a266341051a7a3ca2f4b750a3aa4abc986378431fc2da508c5034d081b70/rpds_py-0.30.0-cp312-cp312-manylinux_2_31_riscv64.whl",hashes = {sha256 = "2e6ecb5a5bcacf59c3f912155044479af1d0b6681280048b338b28e364aca1f6"}}, - {name = "rpds_py-0.30.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl",url = "https://files.pythonhosted.org/packages/10/3b/71b725851df9ab7a7a4e33cf36d241933da66040d195a84781f49c50490c/rpds_py-0.30.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl",hashes = {sha256 = "a8fa71a2e078c527c3e9dc9fc5a98c9db40bcc8a92b4e8858e36d329f8684b51"}}, - {name = "rpds_py-0.30.0-cp312-cp312-musllinux_1_2_aarch64.whl",url = "https://files.pythonhosted.org/packages/00/2b/e59e58c544dc9bd8bd8384ecdb8ea91f6727f0e37a7131baeff8d6f51661/rpds_py-0.30.0-cp312-cp312-musllinux_1_2_aarch64.whl",hashes = {sha256 = "73c67f2db7bc334e518d097c6d1e6fed021bbc9b7d678d6cc433478365d1d5f5"}}, - {name = "rpds_py-0.30.0-cp312-cp312-musllinux_1_2_i686.whl",url = "https://files.pythonhosted.org/packages/da/3e/a18e6f5b460893172a7d6a680e86d3b6bc87a54c1f0b03446a3c8c7b588f/rpds_py-0.30.0-cp312-cp312-musllinux_1_2_i686.whl",hashes = {sha256 = "5ba103fb455be00f3b1c2076c9d4264bfcb037c976167a6047ed82f23153f02e"}}, - {name = "rpds_py-0.30.0-cp312-cp312-musllinux_1_2_x86_64.whl",url = "https://files.pythonhosted.org/packages/5c/e2/714694e4b87b85a18e2c243614974413c60aa107fd815b8cbc42b873d1d7/rpds_py-0.30.0-cp312-cp312-musllinux_1_2_x86_64.whl",hashes = {sha256 = "7cee9c752c0364588353e627da8a7e808a66873672bcb5f52890c33fd965b394"}}, - {name = "rpds_py-0.30.0-cp312-cp312-win32.whl",url = "https://files.pythonhosted.org/packages/6f/ab/d5d5e3bcedb0a77f4f613706b750e50a5a3ba1c15ccd3665ecc636c968fd/rpds_py-0.30.0-cp312-cp312-win32.whl",hashes = {sha256 = "1ab5b83dbcf55acc8b08fc62b796ef672c457b17dbd7820a11d6c52c06839bdf"}}, - {name = "rpds_py-0.30.0-cp312-cp312-win_amd64.whl",url = "https://files.pythonhosted.org/packages/39/3b/f786af9957306fdc38a74cef405b7b93180f481fb48453a114bb6465744a/rpds_py-0.30.0-cp312-cp312-win_amd64.whl",hashes = {sha256 = "a090322ca841abd453d43456ac34db46e8b05fd9b3b4ac0c78bcde8b089f959b"}}, - {name = "rpds_py-0.30.0-cp312-cp312-win_arm64.whl",url = "https://files.pythonhosted.org/packages/f3/d2/b91dc748126c1559042cfe41990deb92c4ee3e2b415f6b5234969ffaf0cc/rpds_py-0.30.0-cp312-cp312-win_arm64.whl",hashes = {sha256 = "669b1805bd639dd2989b281be2cfd951c6121b65e729d9b843e9639ef1fd555e"}}, - {name = "rpds_py-0.30.0-cp311-cp311-macosx_10_12_x86_64.whl",url = "https://files.pythonhosted.org/packages/4d/6e/f964e88b3d2abee2a82c1ac8366da848fce1c6d834dc2132c3fda3970290/rpds_py-0.30.0-cp311-cp311-macosx_10_12_x86_64.whl",hashes = {sha256 = "a2bffea6a4ca9f01b3f8e548302470306689684e61602aa3d141e34da06cf425"}}, - {name = "rpds_py-0.30.0-cp311-cp311-macosx_11_0_arm64.whl",url = "https://files.pythonhosted.org/packages/94/ba/24e5ebb7c1c82e74c4e4f33b2112a5573ddc703915b13a073737b59b86e0/rpds_py-0.30.0-cp311-cp311-macosx_11_0_arm64.whl",hashes = {sha256 = "dc4f992dfe1e2bc3ebc7444f6c7051b4bc13cd8e33e43511e8ffd13bf407010d"}}, - {name = "rpds_py-0.30.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl",url = "https://files.pythonhosted.org/packages/84/86/04dbba1b087227747d64d80c3b74df946b986c57af0a9f0c98726d4d7a3b/rpds_py-0.30.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl",hashes = {sha256 = "422c3cb9856d80b09d30d2eb255d0754b23e090034e1deb4083f8004bd0761e4"}}, - {name = "rpds_py-0.30.0-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl",url = "https://files.pythonhosted.org/packages/42/bb/1463f0b1722b7f45431bdd468301991d1328b16cffe0b1c2918eba2c4eee/rpds_py-0.30.0-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl",hashes = {sha256 = "07ae8a593e1c3c6b82ca3292efbe73c30b61332fd612e05abee07c79359f292f"}}, - {name = "rpds_py-0.30.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl",url = "https://files.pythonhosted.org/packages/99/ee/2520700a5c1f2d76631f948b0736cdf9b0acb25abd0ca8e889b5c62ac2e3/rpds_py-0.30.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl",hashes = {sha256 = "12f90dd7557b6bd57f40abe7747e81e0c0b119bef015ea7726e69fe550e394a4"}}, - {name = "rpds_py-0.30.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl",url = "https://files.pythonhosted.org/packages/e0/ad/bd0331f740f5705cc555a5e17fdf334671262160270962e69a2bdef3bf76/rpds_py-0.30.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl",hashes = {sha256 = "99b47d6ad9a6da00bec6aabe5a6279ecd3c06a329d4aa4771034a21e335c3a97"}}, - {name = "rpds_py-0.30.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",url = "https://files.pythonhosted.org/packages/f8/1e/372195d326549bb51f0ba0f2ecb9874579906b97e08880e7a65c3bef1a99/rpds_py-0.30.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",hashes = {sha256 = "33f559f3104504506a44bb666b93a33f5d33133765b0c216a5bf2f1e1503af89"}}, - {name = "rpds_py-0.30.0-cp311-cp311-manylinux_2_31_riscv64.whl",url = "https://files.pythonhosted.org/packages/ab/2b/d88bb33294e3e0c76bc8f351a3721212713629ffca1700fa94979cb3eae8/rpds_py-0.30.0-cp311-cp311-manylinux_2_31_riscv64.whl",hashes = {sha256 = "946fe926af6e44f3697abbc305ea168c2c31d3e3ef1058cf68f379bf0335a78d"}}, - {name = "rpds_py-0.30.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl",url = "https://files.pythonhosted.org/packages/50/32/c759a8d42bcb5289c1fac697cd92f6fe01a018dd937e62ae77e0e7f15702/rpds_py-0.30.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl",hashes = {sha256 = "495aeca4b93d465efde585977365187149e75383ad2684f81519f504f5c13038"}}, - {name = "rpds_py-0.30.0-cp311-cp311-musllinux_1_2_aarch64.whl",url = "https://files.pythonhosted.org/packages/2b/81/e729761dbd55ddf5d84ec4ff1f47857f4374b0f19bdabfcf929164da3e24/rpds_py-0.30.0-cp311-cp311-musllinux_1_2_aarch64.whl",hashes = {sha256 = "d9a0ca5da0386dee0655b4ccdf46119df60e0f10da268d04fe7cc87886872ba7"}}, - {name = "rpds_py-0.30.0-cp311-cp311-musllinux_1_2_i686.whl",url = "https://files.pythonhosted.org/packages/14/f6/69066a924c3557c9c30baa6ec3a0aa07526305684c6f86c696b08860726c/rpds_py-0.30.0-cp311-cp311-musllinux_1_2_i686.whl",hashes = {sha256 = "8d6d1cc13664ec13c1b84241204ff3b12f9bb82464b8ad6e7a5d3486975c2eed"}}, - {name = "rpds_py-0.30.0-cp311-cp311-musllinux_1_2_x86_64.whl",url = "https://files.pythonhosted.org/packages/5f/48/905896b1eb8a05630d20333d1d8ffd162394127b74ce0b0784ae04498d32/rpds_py-0.30.0-cp311-cp311-musllinux_1_2_x86_64.whl",hashes = {sha256 = "3896fa1be39912cf0757753826bc8bdc8ca331a28a7c4ae46b7a21280b06bb85"}}, - {name = "rpds_py-0.30.0-cp311-cp311-win32.whl",url = "https://files.pythonhosted.org/packages/22/16/cd3027c7e279d22e5eb431dd3c0fbc677bed58797fe7581e148f3f68818b/rpds_py-0.30.0-cp311-cp311-win32.whl",hashes = {sha256 = "55f66022632205940f1827effeff17c4fa7ae1953d2b74a8581baaefb7d16f8c"}}, - {name = "rpds_py-0.30.0-cp311-cp311-win_amd64.whl",url = "https://files.pythonhosted.org/packages/fa/5b/e7b7aa136f28462b344e652ee010d4de26ee9fd16f1bfd5811f5153ccf89/rpds_py-0.30.0-cp311-cp311-win_amd64.whl",hashes = {sha256 = "a51033ff701fca756439d641c0ad09a41d9242fa69121c7d8769604a0a629825"}}, - {name = "rpds_py-0.30.0-cp311-cp311-win_arm64.whl",url = "https://files.pythonhosted.org/packages/14/a6/364bba985e4c13658edb156640608f2c9e1d3ea3c81b27aa9d889fff0e31/rpds_py-0.30.0-cp311-cp311-win_arm64.whl",hashes = {sha256 = "47b0ef6231c58f506ef0b74d44e330405caa8428e770fec25329ed2cb971a229"}}, - {name = "rpds_py-0.30.0-pp311-pypy311_pp73-macosx_10_12_x86_64.whl",url = "https://files.pythonhosted.org/packages/69/71/3f34339ee70521864411f8b6992e7ab13ac30d8e4e3309e07c7361767d91/rpds_py-0.30.0-pp311-pypy311_pp73-macosx_10_12_x86_64.whl",hashes = {sha256 = "c2262bdba0ad4fc6fb5545660673925c2d2a5d9e2e0fb603aad545427be0fc58"}}, - {name = "rpds_py-0.30.0-pp311-pypy311_pp73-macosx_11_0_arm64.whl",url = "https://files.pythonhosted.org/packages/57/09/f183df9b8f2d66720d2ef71075c59f7e1b336bec7ee4c48f0a2b06857653/rpds_py-0.30.0-pp311-pypy311_pp73-macosx_11_0_arm64.whl",hashes = {sha256 = "ee6af14263f25eedc3bb918a3c04245106a42dfd4f5c2285ea6f997b1fc3f89a"}}, - {name = "rpds_py-0.30.0-pp311-pypy311_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl",url = "https://files.pythonhosted.org/packages/7a/68/5c2594e937253457342e078f0cc1ded3dd7b2ad59afdbf2d354869110a02/rpds_py-0.30.0-pp311-pypy311_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl",hashes = {sha256 = "3adbb8179ce342d235c31ab8ec511e66c73faa27a47e076ccc92421add53e2bb"}}, - {name = "rpds_py-0.30.0-pp311-pypy311_pp73-manylinux_2_17_armv7l.manylinux2014_armv7l.whl",url = "https://files.pythonhosted.org/packages/49/5c/31ef1afd70b4b4fbdb2800249f34c57c64beb687495b10aec0365f53dfc4/rpds_py-0.30.0-pp311-pypy311_pp73-manylinux_2_17_armv7l.manylinux2014_armv7l.whl",hashes = {sha256 = "250fa00e9543ac9b97ac258bd37367ff5256666122c2d0f2bc97577c60a1818c"}}, - {name = "rpds_py-0.30.0-pp311-pypy311_pp73-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl",url = "https://files.pythonhosted.org/packages/e3/63/0cfbea38d05756f3440ce6534d51a491d26176ac045e2707adc99bb6e60a/rpds_py-0.30.0-pp311-pypy311_pp73-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl",hashes = {sha256 = "9854cf4f488b3d57b9aaeb105f06d78e5529d3145b1e4a41750167e8c213c6d3"}}, - {name = "rpds_py-0.30.0-pp311-pypy311_pp73-manylinux_2_17_s390x.manylinux2014_s390x.whl",url = "https://files.pythonhosted.org/packages/42/e6/01e1f72a2456678b0f618fc9a1a13f882061690893c192fcad9f2926553a/rpds_py-0.30.0-pp311-pypy311_pp73-manylinux_2_17_s390x.manylinux2014_s390x.whl",hashes = {sha256 = "993914b8e560023bc0a8bf742c5f303551992dcb85e247b1e5c7f4a7d145bda5"}}, - {name = "rpds_py-0.30.0-pp311-pypy311_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",url = "https://files.pythonhosted.org/packages/b8/25/8df56677f209003dcbb180765520c544525e3ef21ea72279c98b9aa7c7fb/rpds_py-0.30.0-pp311-pypy311_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",hashes = {sha256 = "58edca431fb9b29950807e301826586e5bbf24163677732429770a697ffe6738"}}, - {name = "rpds_py-0.30.0-pp311-pypy311_pp73-manylinux_2_31_riscv64.whl",url = "https://files.pythonhosted.org/packages/4a/b4/0a771378c5f16f8115f796d1f437950158679bcd2a7c68cf251cfb00ed5b/rpds_py-0.30.0-pp311-pypy311_pp73-manylinux_2_31_riscv64.whl",hashes = {sha256 = "dea5b552272a944763b34394d04577cf0f9bd013207bc32323b5a89a53cf9c2f"}}, - {name = "rpds_py-0.30.0-pp311-pypy311_pp73-manylinux_2_5_i686.manylinux1_i686.whl",url = "https://files.pythonhosted.org/packages/36/d8/456dbba0af75049dc6f63ff295a2f92766b9d521fa00de67a2bd6427d57a/rpds_py-0.30.0-pp311-pypy311_pp73-manylinux_2_5_i686.manylinux1_i686.whl",hashes = {sha256 = "ba3af48635eb83d03f6c9735dfb21785303e73d22ad03d489e88adae6eab8877"}}, - {name = "rpds_py-0.30.0-pp311-pypy311_pp73-musllinux_1_2_aarch64.whl",url = "https://files.pythonhosted.org/packages/13/64/b4d76f227d5c45a7e0b796c674fd81b0a6c4fbd48dc29271857d8219571c/rpds_py-0.30.0-pp311-pypy311_pp73-musllinux_1_2_aarch64.whl",hashes = {sha256 = "dff13836529b921e22f15cb099751209a60009731a68519630a24d61f0b1b30a"}}, - {name = "rpds_py-0.30.0-pp311-pypy311_pp73-musllinux_1_2_i686.whl",url = "https://files.pythonhosted.org/packages/20/91/092bacadeda3edf92bf743cc96a7be133e13a39cdbfd7b5082e7ab638406/rpds_py-0.30.0-pp311-pypy311_pp73-musllinux_1_2_i686.whl",hashes = {sha256 = "1b151685b23929ab7beec71080a8889d4d6d9fa9a983d213f07121205d48e2c4"}}, - {name = "rpds_py-0.30.0-pp311-pypy311_pp73-musllinux_1_2_x86_64.whl",url = "https://files.pythonhosted.org/packages/d1/b7/b95708304cd49b7b6f82fdd039f1748b66ec2b21d6a45180910802f1abf1/rpds_py-0.30.0-pp311-pypy311_pp73-musllinux_1_2_x86_64.whl",hashes = {sha256 = "ac37f9f516c51e5753f27dfdef11a88330f04de2d564be3991384b2f3535d02e"}}, -] -marker = "\"docs\" in extras" - -[packages.tool.pdm] -dependencies = [] - -[[packages]] -name = "scikit-learn" -version = "1.5.2" -requires-python = ">=3.9" -sdist = {name = "scikit_learn-1.5.2.tar.gz", url = "https://files.pythonhosted.org/packages/37/59/44985a2bdc95c74e34fef3d10cb5d93ce13b0e2a7baefffe1b53853b502d/scikit_learn-1.5.2.tar.gz", hashes = {sha256 = "b4237ed7b3fdd0a4882792e68ef2545d5baa50aca3bb45aa7df468138ad8f94d"}} -wheels = [ - {name = "scikit_learn-1.5.2-cp313-cp313-macosx_10_13_x86_64.whl",url = "https://files.pythonhosted.org/packages/a4/50/8891028437858cc510e13578fe7046574a60c2aaaa92b02d64aac5b1b412/scikit_learn-1.5.2-cp313-cp313-macosx_10_13_x86_64.whl",hashes = {sha256 = "e9a702e2de732bbb20d3bad29ebd77fc05a6b427dc49964300340e4c9328b3f5"}}, - {name = "scikit_learn-1.5.2-cp313-cp313-macosx_12_0_arm64.whl",url = "https://files.pythonhosted.org/packages/d2/79/17feef8a1c14149436083bec0e61d7befb4812e272d5b20f9d79ea3e9ab1/scikit_learn-1.5.2-cp313-cp313-macosx_12_0_arm64.whl",hashes = {sha256 = "b0768ad641981f5d3a198430a1d31c3e044ed2e8a6f22166b4d546a5116d7908"}}, - {name = "scikit_learn-1.5.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl",url = "https://files.pythonhosted.org/packages/b1/c8/f08313f9e2e656bd0905930ae8bf99a573ea21c34666a813b749c338202f/scikit_learn-1.5.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl",hashes = {sha256 = "178ddd0a5cb0044464fc1bfc4cca5b1833bfc7bb022d70b05db8530da4bb3dd3"}}, - {name = "scikit_learn-1.5.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",url = "https://files.pythonhosted.org/packages/a7/48/fbfb4dc72bed0fe31fe045fb30e924909ad03f717c36694351612973b1a9/scikit_learn-1.5.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",hashes = {sha256 = "f7284ade780084d94505632241bf78c44ab3b6f1e8ccab3d2af58e0e950f9c12"}}, - {name = "scikit_learn-1.5.2-cp313-cp313-win_amd64.whl",url = "https://files.pythonhosted.org/packages/a5/e7/0c869f9e60d225a77af90d2aefa7a4a4c0e745b149325d1450f0f0ce5399/scikit_learn-1.5.2-cp313-cp313-win_amd64.whl",hashes = {sha256 = "b7b0f9a0b1040830d38c39b91b3a44e1b643f4b36e36567b80b7c6bd2202a27f"}}, - {name = "scikit_learn-1.5.2-cp312-cp312-macosx_10_9_x86_64.whl",url = "https://files.pythonhosted.org/packages/a4/db/b485c1ac54ff3bd9e7e6b39d3cc6609c4c76a65f52ab0a7b22b6c3ab0e9d/scikit_learn-1.5.2-cp312-cp312-macosx_10_9_x86_64.whl",hashes = {sha256 = "f932a02c3f4956dfb981391ab24bda1dbd90fe3d628e4b42caef3e041c67707a"}}, - {name = "scikit_learn-1.5.2-cp312-cp312-macosx_12_0_arm64.whl",url = "https://files.pythonhosted.org/packages/54/1a/7deb52fa23aebb855431ad659b3c6a2e1709ece582cb3a63d66905e735fe/scikit_learn-1.5.2-cp312-cp312-macosx_12_0_arm64.whl",hashes = {sha256 = "3b923d119d65b7bd555c73be5423bf06c0105678ce7e1f558cb4b40b0a5502b1"}}, - {name = "scikit_learn-1.5.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl",url = "https://files.pythonhosted.org/packages/a1/32/4a7a205b14c11225609b75b28402c196e4396ac754dab6a81971b811781c/scikit_learn-1.5.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl",hashes = {sha256 = "f60021ec1574e56632be2a36b946f8143bf4e5e6af4a06d85281adc22938e0dd"}}, - {name = "scikit_learn-1.5.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",url = "https://files.pythonhosted.org/packages/c6/29/044048c5e911373827c0e1d3051321b9183b2a4f8d4e2f11c08fcff83f13/scikit_learn-1.5.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",hashes = {sha256 = "394397841449853c2290a32050382edaec3da89e35b3e03d6cc966aebc6a8ae6"}}, - {name = "scikit_learn-1.5.2-cp312-cp312-win_amd64.whl",url = "https://files.pythonhosted.org/packages/aa/ce/c0b912f2f31aeb1b756a6ba56bcd84dd1f8a148470526a48515a3f4d48cd/scikit_learn-1.5.2-cp312-cp312-win_amd64.whl",hashes = {sha256 = "57cc1786cfd6bd118220a92ede80270132aa353647684efa385a74244a41e3b1"}}, - {name = "scikit_learn-1.5.2-cp311-cp311-macosx_10_9_x86_64.whl",url = "https://files.pythonhosted.org/packages/ff/91/609961972f694cb9520c4c3d201e377a26583e1eb83bc5a334c893729214/scikit_learn-1.5.2-cp311-cp311-macosx_10_9_x86_64.whl",hashes = {sha256 = "03b6158efa3faaf1feea3faa884c840ebd61b6484167c711548fce208ea09445"}}, - {name = "scikit_learn-1.5.2-cp311-cp311-macosx_12_0_arm64.whl",url = "https://files.pythonhosted.org/packages/cd/7a/19fe32c810c5ceddafcfda16276d98df299c8649e24e84d4f00df4a91e01/scikit_learn-1.5.2-cp311-cp311-macosx_12_0_arm64.whl",hashes = {sha256 = "1ff45e26928d3b4eb767a8f14a9a6efbf1cbff7c05d1fb0f95f211a89fd4f5de"}}, - {name = "scikit_learn-1.5.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl",url = "https://files.pythonhosted.org/packages/4c/75/62e49f8a62bf3c60b0e64d0fce540578ee4f0e752765beb2e1dc7c6d6098/scikit_learn-1.5.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl",hashes = {sha256 = "f763897fe92d0e903aa4847b0aec0e68cadfff77e8a0687cabd946c89d17e675"}}, - {name = "scikit_learn-1.5.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",url = "https://files.pythonhosted.org/packages/49/21/3723de321531c9745e40f1badafd821e029d346155b6c79704e0b7197552/scikit_learn-1.5.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",hashes = {sha256 = "f8b0ccd4a902836493e026c03256e8b206656f91fbcc4fde28c57a5b752561f1"}}, - {name = "scikit_learn-1.5.2-cp311-cp311-win_amd64.whl",url = "https://files.pythonhosted.org/packages/17/1c/ccdd103cfcc9435a18819856fbbe0c20b8fa60bfc3343580de4be13f0668/scikit_learn-1.5.2-cp311-cp311-win_amd64.whl",hashes = {sha256 = "6c16d84a0d45e4894832b3c4d0bf73050939e21b99b01b6fd59cbb0cf39163b6"}}, -] -marker = "\"default\" in dependency_groups" - -[packages.tool.pdm] -dependencies = [ - "joblib>=1.2.0", - "numpy>=1.19.5", - "scipy>=1.6.0", - "threadpoolctl>=3.1.0", -] - -[[packages]] -name = "scipy" -version = "1.12.0" -requires-python = ">=3.9" -sdist = {name = "scipy-1.12.0.tar.gz", url = "https://files.pythonhosted.org/packages/30/85/cdbf2c3c460fe5aae812917866392068a88d02f07de0fe31ce738734c477/scipy-1.12.0.tar.gz", hashes = {sha256 = "4bf5abab8a36d20193c698b0f1fc282c1d083c94723902c447e5d2f1780936a3"}} -wheels = [ - {name = "scipy-1.12.0-cp312-cp312-macosx_10_9_x86_64.whl",url = "https://files.pythonhosted.org/packages/0d/4a/b2b2cae0c5dfd46361245a67102886ed7188805bdf7044e36fe838bbcf26/scipy-1.12.0-cp312-cp312-macosx_10_9_x86_64.whl",hashes = {sha256 = "e7e76cc48638228212c747ada851ef355c2bb5e7f939e10952bc504c11f4e372"}}, - {name = "scipy-1.12.0-cp312-cp312-macosx_12_0_arm64.whl",url = "https://files.pythonhosted.org/packages/71/ba/744bbdd65eb3fce1412dd4633fc425ad39e6b4068b5b158aee1cd3afeb54/scipy-1.12.0-cp312-cp312-macosx_12_0_arm64.whl",hashes = {sha256 = "f7ce148dffcd64ade37b2df9315541f9adad6efcaa86866ee7dd5db0c8f041c3"}}, - {name = "scipy-1.12.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl",url = "https://files.pythonhosted.org/packages/db/fd/81feac476e1ae495b51b8c3636aee1f50a1c5ca2a3557f5b0043d4e2fb02/scipy-1.12.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl",hashes = {sha256 = "9c39f92041f490422924dfdb782527a4abddf4707616e07b021de33467f917bc"}}, - {name = "scipy-1.12.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",url = "https://files.pythonhosted.org/packages/11/7d/850bfe9462fff393130519eb54f97d43ad9c280ec4297b4cb98b7c2e96cd/scipy-1.12.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",hashes = {sha256 = "a7ebda398f86e56178c2fa94cad15bf457a218a54a35c2a7b4490b9f9cb2676c"}}, - {name = "scipy-1.12.0-cp312-cp312-musllinux_1_1_x86_64.whl",url = "https://files.pythonhosted.org/packages/7e/7f/504b7b3834d8c9229831c6c58a44943e29a34004eeb34c7ff150add4e001/scipy-1.12.0-cp312-cp312-musllinux_1_1_x86_64.whl",hashes = {sha256 = "95e5c750d55cf518c398a8240571b0e0782c2d5a703250872f36eaf737751338"}}, - {name = "scipy-1.12.0-cp312-cp312-win_amd64.whl",url = "https://files.pythonhosted.org/packages/f3/31/91a2a3c5eb85d2bfa86d7c98f2df5d77dcdefb3d80ca9f9037ad04393acf/scipy-1.12.0-cp312-cp312-win_amd64.whl",hashes = {sha256 = "e646d8571804a304e1da01040d21577685ce8e2db08ac58e543eaca063453e1c"}}, - {name = "scipy-1.12.0-cp311-cp311-macosx_10_9_x86_64.whl",url = "https://files.pythonhosted.org/packages/c3/32/7915195ca4643508fe9730691eaed57b879646279572b10b02bdadf165c5/scipy-1.12.0-cp311-cp311-macosx_10_9_x86_64.whl",hashes = {sha256 = "408c68423f9de16cb9e602528be4ce0d6312b05001f3de61fe9ec8b1263cad08"}}, - {name = "scipy-1.12.0-cp311-cp311-macosx_12_0_arm64.whl",url = "https://files.pythonhosted.org/packages/21/d4/e6c57acc61e59cd46acca27af1f400094d5dee218e372cc604b8162b97cb/scipy-1.12.0-cp311-cp311-macosx_12_0_arm64.whl",hashes = {sha256 = "5adfad5dbf0163397beb4aca679187d24aec085343755fcdbdeb32b3679f254c"}}, - {name = "scipy-1.12.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl",url = "https://files.pythonhosted.org/packages/e3/c5/d40abc1a857c1c6519e1a4e096d6aee86861eddac019fb736b6af8a58d25/scipy-1.12.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl",hashes = {sha256 = "c3003652496f6e7c387b1cf63f4bb720951cfa18907e998ea551e6de51a04467"}}, - {name = "scipy-1.12.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",url = "https://files.pythonhosted.org/packages/d4/b8/7169935f9a2ea9e274ad8c21d6133d492079e6ebc3fc69a915c2375616b0/scipy-1.12.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",hashes = {sha256 = "8b8066bce124ee5531d12a74b617d9ac0ea59245246410e19bca549656d9a40a"}}, - {name = "scipy-1.12.0-cp311-cp311-musllinux_1_1_x86_64.whl",url = "https://files.pythonhosted.org/packages/64/e7/4dbb779d09d1cb757ddbe42cae7c4fe8270497566bb902138d637b04d88c/scipy-1.12.0-cp311-cp311-musllinux_1_1_x86_64.whl",hashes = {sha256 = "8bee4993817e204d761dba10dbab0774ba5a8612e57e81319ea04d84945375ba"}}, - {name = "scipy-1.12.0-cp311-cp311-win_amd64.whl",url = "https://files.pythonhosted.org/packages/9a/25/5b30cb3efc9566f0ebeaeca1976150316353c17031ad7868ef46de5ab8dc/scipy-1.12.0-cp311-cp311-win_amd64.whl",hashes = {sha256 = "a24024d45ce9a675c1fb8494e8e5244efea1c7a09c60beb1eeb80373d0fecc70"}}, -] -marker = "\"default\" in dependency_groups" - -[packages.tool.pdm] -dependencies = [ - "numpy<1.29.0,>=1.22.4", -] - -[[packages]] -name = "six" -version = "1.17.0" -requires-python = "!=3.0.*,!=3.1.*,!=3.2.*,>=2.7" -sdist = {name = "six-1.17.0.tar.gz", url = "https://files.pythonhosted.org/packages/94/e7/b2c673351809dca68a0e064b6af791aa332cf192da575fd474ed7d6f16a2/six-1.17.0.tar.gz", hashes = {sha256 = "ff70335d468e7eb6ec65b95b99d3a2836546063f63acc5171de367e834932a81"}} -wheels = [ - {name = "six-1.17.0-py2.py3-none-any.whl",url = "https://files.pythonhosted.org/packages/b7/ce/149a00dd41f10bc29e5921b496af8b574d8413afcd5e30dfa0ed46c2cc5e/six-1.17.0-py2.py3-none-any.whl",hashes = {sha256 = "4721f391ed90541fddacab5acf947aa0d3dc7d27b2e1e8eda2be8970586c3274"}}, -] -marker = "\"default\" in dependency_groups or \"docs\" in extras" - -[packages.tool.pdm] -dependencies = [] - -[[packages]] -name = "snowballstemmer" -version = "3.0.1" -requires-python = "!=3.0.*,!=3.1.*,!=3.2.*" -sdist = {name = "snowballstemmer-3.0.1.tar.gz", url = "https://files.pythonhosted.org/packages/75/a7/9810d872919697c9d01295633f5d574fb416d47e535f258272ca1f01f447/snowballstemmer-3.0.1.tar.gz", hashes = {sha256 = "6d5eeeec8e9f84d4d56b847692bacf79bc2c8e90c7f80ca4444ff8b6f2e52895"}} -wheels = [ - {name = "snowballstemmer-3.0.1-py3-none-any.whl",url = "https://files.pythonhosted.org/packages/c8/78/3565d011c61f5a43488987ee32b6f3f656e7f107ac2782dd57bdd7d91d9a/snowballstemmer-3.0.1-py3-none-any.whl",hashes = {sha256 = "6cd7b3897da8d6c9ffb968a6781fa6532dce9c3618a4b127d920dab764a19064"}}, -] -marker = "\"docs\" in extras" - -[packages.tool.pdm] -dependencies = [] - -[[packages]] -name = "soupsieve" -version = "2.8.3" -requires-python = ">=3.9" -sdist = {name = "soupsieve-2.8.3.tar.gz", url = "https://files.pythonhosted.org/packages/7b/ae/2d9c981590ed9999a0d91755b47fc74f74de286b0f5cee14c9269041e6c4/soupsieve-2.8.3.tar.gz", hashes = {sha256 = "3267f1eeea4251fb42728b6dfb746edc9acaffc4a45b27e19450b676586e8349"}} -wheels = [ - {name = "soupsieve-2.8.3-py3-none-any.whl",url = "https://files.pythonhosted.org/packages/46/2c/1462b1d0a634697ae9e55b3cecdcb64788e8b7d63f54d923fcd0bb140aed/soupsieve-2.8.3-py3-none-any.whl",hashes = {sha256 = "ed64f2ba4eebeab06cc4962affce381647455978ffc1e36bb79a545b91f45a95"}}, -] -marker = "\"docs\" in extras" - -[packages.tool.pdm] -dependencies = [] - -[[packages]] -name = "sphinx" -version = "9.0.4" -requires-python = ">=3.11" -sdist = {name = "sphinx-9.0.4.tar.gz", url = "https://files.pythonhosted.org/packages/42/50/a8c6ccc36d5eacdfd7913ddccd15a9cee03ecafc5ee2bc40e1f168d85022/sphinx-9.0.4.tar.gz", hashes = {sha256 = "594ef59d042972abbc581d8baa577404abe4e6c3b04ef61bd7fc2acbd51f3fa3"}} -wheels = [ - {name = "sphinx-9.0.4-py3-none-any.whl",url = "https://files.pythonhosted.org/packages/c6/3f/4bbd76424c393caead2e1eb89777f575dee5c8653e2d4b6afd7a564f5974/sphinx-9.0.4-py3-none-any.whl",hashes = {sha256 = "5bebc595a5e943ea248b99c13814c1c5e10b3ece718976824ffa7959ff95fffb"}}, -] -marker = "\"docs\" in extras" - -[packages.tool.pdm] -dependencies = [ - "Jinja2>=3.1", - "Pygments>=2.17", - "alabaster>=0.7.14", - "babel>=2.13", - "colorama>=0.4.6; sys_platform == \"win32\"", - "docutils<0.23,>=0.20", - "imagesize>=1.3", - "packaging>=23.0", - "requests>=2.30.0", - "roman-numerals>=1.0.0", - "snowballstemmer>=2.2", - "sphinxcontrib-applehelp>=1.0.7", - "sphinxcontrib-devhelp>=1.0.6", - "sphinxcontrib-htmlhelp>=2.0.6", - "sphinxcontrib-jsmath>=1.0.1", - "sphinxcontrib-qthelp>=1.0.6", - "sphinxcontrib-serializinghtml>=1.1.9", -] - -[[packages]] -name = "sphinx-autobuild" -version = "2025.8.25" -requires-python = ">=3.11" -sdist = {name = "sphinx_autobuild-2025.8.25.tar.gz", url = "https://files.pythonhosted.org/packages/e0/3c/a59a3a453d4133777f7ed2e83c80b7dc817d43c74b74298ca0af869662ad/sphinx_autobuild-2025.8.25.tar.gz", hashes = {sha256 = "9cf5aab32853c8c31af572e4fecdc09c997e2b8be5a07daf2a389e270e85b213"}} -wheels = [ - {name = "sphinx_autobuild-2025.8.25-py3-none-any.whl",url = "https://files.pythonhosted.org/packages/d7/20/56411b52f917696995f5ad27d2ea7e9492c84a043c5b49a3a3173573cd93/sphinx_autobuild-2025.8.25-py3-none-any.whl",hashes = {sha256 = "b750ac7d5a18603e4665294323fd20f6dcc0a984117026d1986704fa68f0379a"}}, -] -marker = "\"docs\" in extras" - -[packages.tool.pdm] -dependencies = [ - "Sphinx", - "colorama>=0.4.6", - "starlette>=0.35", - "uvicorn>=0.25", - "watchfiles>=0.20", - "websockets>=11", -] - -[[packages]] -name = "sphinx-basic-ng" -version = "1.0.0b2" -requires-python = ">=3.7" -sdist = {name = "sphinx_basic_ng-1.0.0b2.tar.gz", url = "https://files.pythonhosted.org/packages/98/0b/a866924ded68efec7a1759587a4e478aec7559d8165fac8b2ad1c0e774d6/sphinx_basic_ng-1.0.0b2.tar.gz", hashes = {sha256 = "9ec55a47c90c8c002b5960c57492ec3021f5193cb26cebc2dc4ea226848651c9"}} -wheels = [ - {name = "sphinx_basic_ng-1.0.0b2-py3-none-any.whl",url = "https://files.pythonhosted.org/packages/3c/dd/018ce05c532a22007ac58d4f45232514cd9d6dd0ee1dc374e309db830983/sphinx_basic_ng-1.0.0b2-py3-none-any.whl",hashes = {sha256 = "eb09aedbabfb650607e9b4b68c9d240b90b1e1be221d6ad71d61c52e29f7932b"}}, -] -marker = "\"docs\" in extras" - -[packages.tool.pdm] -dependencies = [ - "sphinx>=4.0", -] - -[[packages]] -name = "sphinx-copybutton" -version = "0.5.2" -requires-python = ">=3.7" -sdist = {name = "sphinx-copybutton-0.5.2.tar.gz", url = "https://files.pythonhosted.org/packages/fc/2b/a964715e7f5295f77509e59309959f4125122d648f86b4fe7d70ca1d882c/sphinx-copybutton-0.5.2.tar.gz", hashes = {sha256 = "4cf17c82fb9646d1bc9ca92ac280813a3b605d8c421225fd9913154103ee1fbd"}} -wheels = [ - {name = "sphinx_copybutton-0.5.2-py3-none-any.whl",url = "https://files.pythonhosted.org/packages/9e/48/1ea60e74949eecb12cdd6ac43987f9fd331156388dcc2319b45e2ebb81bf/sphinx_copybutton-0.5.2-py3-none-any.whl",hashes = {sha256 = "fb543fd386d917746c9a2c50360c7905b605726b9355cd26e9974857afeae06e"}}, -] -marker = "\"docs\" in extras" - -[packages.tool.pdm] -dependencies = [ - "sphinx>=1.8", -] - -[[packages]] -name = "sphinx-design" -version = "0.7.0" -requires-python = ">=3.11" -sdist = {name = "sphinx_design-0.7.0.tar.gz", url = "https://files.pythonhosted.org/packages/13/7b/804f311da4663a4aecc6cf7abd83443f3d4ded970826d0c958edc77d4527/sphinx_design-0.7.0.tar.gz", hashes = {sha256 = "d2a3f5b19c24b916adb52f97c5f00efab4009ca337812001109084a740ec9b7a"}} -wheels = [ - {name = "sphinx_design-0.7.0-py3-none-any.whl",url = "https://files.pythonhosted.org/packages/30/cf/45dd359f6ca0c3762ce0490f681da242f0530c49c81050c035c016bfdd3a/sphinx_design-0.7.0-py3-none-any.whl",hashes = {sha256 = "f82bf179951d58f55dca78ab3706aeafa496b741a91b1911d371441127d64282"}}, -] -marker = "\"docs\" in extras" - -[packages.tool.pdm] -dependencies = [ - "sphinx<10,>=7", -] - -[[packages]] -name = "sphinx-gallery" -version = "0.20.0" -requires-python = ">=3.10" -sdist = {name = "sphinx_gallery-0.20.0.tar.gz", url = "https://files.pythonhosted.org/packages/5f/14/9238ac61932299b38c20c7c37dbfe60348c0348ea4d400f9ef25875b3bf7/sphinx_gallery-0.20.0.tar.gz", hashes = {sha256 = "70281510c6183d812d3595957005ccf555c5a793f207410f6cd16a25bf08d735"}} -wheels = [ - {name = "sphinx_gallery-0.20.0-py3-none-any.whl",url = "https://files.pythonhosted.org/packages/27/fd/818a53d4da56ef2da7b08f77bb3a825635941d1fcc6b6a490995dec1a81c/sphinx_gallery-0.20.0-py3-none-any.whl",hashes = {sha256 = "188b7456e269649945825661b76cdbfbf0b70c2cfd5b75c9a11fe52519879e4d"}}, -] -marker = "\"docs\" in extras" - -[packages.tool.pdm] -dependencies = [ - "pillow", - "sphinx>=5", -] - -[[packages]] -name = "sphinxcontrib-applehelp" -version = "2.0.0" -requires-python = ">=3.9" -sdist = {name = "sphinxcontrib_applehelp-2.0.0.tar.gz", url = "https://files.pythonhosted.org/packages/ba/6e/b837e84a1a704953c62ef8776d45c3e8d759876b4a84fe14eba2859106fe/sphinxcontrib_applehelp-2.0.0.tar.gz", hashes = {sha256 = "2f29ef331735ce958efa4734873f084941970894c6090408b079c61b2e1c06d1"}} -wheels = [ - {name = "sphinxcontrib_applehelp-2.0.0-py3-none-any.whl",url = "https://files.pythonhosted.org/packages/5d/85/9ebeae2f76e9e77b952f4b274c27238156eae7979c5421fba91a28f4970d/sphinxcontrib_applehelp-2.0.0-py3-none-any.whl",hashes = {sha256 = "4cd3f0ec4ac5dd9c17ec65e9ab272c9b867ea77425228e68ecf08d6b28ddbdb5"}}, -] -marker = "\"docs\" in extras" - -[packages.tool.pdm] -dependencies = [] - -[[packages]] -name = "sphinxcontrib-devhelp" -version = "2.0.0" -requires-python = ">=3.9" -sdist = {name = "sphinxcontrib_devhelp-2.0.0.tar.gz", url = "https://files.pythonhosted.org/packages/f6/d2/5beee64d3e4e747f316bae86b55943f51e82bb86ecd325883ef65741e7da/sphinxcontrib_devhelp-2.0.0.tar.gz", hashes = {sha256 = "411f5d96d445d1d73bb5d52133377b4248ec79db5c793ce7dbe59e074b4dd1ad"}} -wheels = [ - {name = "sphinxcontrib_devhelp-2.0.0-py3-none-any.whl",url = "https://files.pythonhosted.org/packages/35/7a/987e583882f985fe4d7323774889ec58049171828b58c2217e7f79cdf44e/sphinxcontrib_devhelp-2.0.0-py3-none-any.whl",hashes = {sha256 = "aefb8b83854e4b0998877524d1029fd3e6879210422ee3780459e28a1f03a8a2"}}, -] -marker = "\"docs\" in extras" - -[packages.tool.pdm] -dependencies = [] - -[[packages]] -name = "sphinxcontrib-htmlhelp" -version = "2.1.0" -requires-python = ">=3.9" -sdist = {name = "sphinxcontrib_htmlhelp-2.1.0.tar.gz", url = "https://files.pythonhosted.org/packages/43/93/983afd9aa001e5201eab16b5a444ed5b9b0a7a010541e0ddfbbfd0b2470c/sphinxcontrib_htmlhelp-2.1.0.tar.gz", hashes = {sha256 = "c9e2916ace8aad64cc13a0d233ee22317f2b9025b9cf3295249fa985cc7082e9"}} -wheels = [ - {name = "sphinxcontrib_htmlhelp-2.1.0-py3-none-any.whl",url = "https://files.pythonhosted.org/packages/0a/7b/18a8c0bcec9182c05a0b3ec2a776bba4ead82750a55ff798e8d406dae604/sphinxcontrib_htmlhelp-2.1.0-py3-none-any.whl",hashes = {sha256 = "166759820b47002d22914d64a075ce08f4c46818e17cfc9470a9786b759b19f8"}}, -] -marker = "\"docs\" in extras" - -[packages.tool.pdm] -dependencies = [] - -[[packages]] -name = "sphinxcontrib-jsmath" -version = "1.0.1" -requires-python = ">=3.5" -sdist = {name = "sphinxcontrib-jsmath-1.0.1.tar.gz", url = "https://files.pythonhosted.org/packages/b2/e8/9ed3830aeed71f17c026a07a5097edcf44b692850ef215b161b8ad875729/sphinxcontrib-jsmath-1.0.1.tar.gz", hashes = {sha256 = "a9925e4a4587247ed2191a22df5f6970656cb8ca2bd6284309578f2153e0c4b8"}} -wheels = [ - {name = "sphinxcontrib_jsmath-1.0.1-py2.py3-none-any.whl",url = "https://files.pythonhosted.org/packages/c2/42/4c8646762ee83602e3fb3fbe774c2fac12f317deb0b5dbeeedd2d3ba4b77/sphinxcontrib_jsmath-1.0.1-py2.py3-none-any.whl",hashes = {sha256 = "2ec2eaebfb78f3f2078e73666b1415417a116cc848b72e5172e596c871103178"}}, -] -marker = "\"docs\" in extras" - -[packages.tool.pdm] -dependencies = [] - -[[packages]] -name = "sphinxcontrib-qthelp" -version = "2.0.0" -requires-python = ">=3.9" -sdist = {name = "sphinxcontrib_qthelp-2.0.0.tar.gz", url = "https://files.pythonhosted.org/packages/68/bc/9104308fc285eb3e0b31b67688235db556cd5b0ef31d96f30e45f2e51cae/sphinxcontrib_qthelp-2.0.0.tar.gz", hashes = {sha256 = "4fe7d0ac8fc171045be623aba3e2a8f613f8682731f9153bb2e40ece16b9bbab"}} -wheels = [ - {name = "sphinxcontrib_qthelp-2.0.0-py3-none-any.whl",url = "https://files.pythonhosted.org/packages/27/83/859ecdd180cacc13b1f7e857abf8582a64552ea7a061057a6c716e790fce/sphinxcontrib_qthelp-2.0.0-py3-none-any.whl",hashes = {sha256 = "b18a828cdba941ccd6ee8445dbe72ffa3ef8cbe7505d8cd1fa0d42d3f2d5f3eb"}}, -] -marker = "\"docs\" in extras" - -[packages.tool.pdm] -dependencies = [] - -[[packages]] -name = "sphinxcontrib-serializinghtml" -version = "2.0.0" -requires-python = ">=3.9" -sdist = {name = "sphinxcontrib_serializinghtml-2.0.0.tar.gz", url = "https://files.pythonhosted.org/packages/3b/44/6716b257b0aa6bfd51a1b31665d1c205fb12cb5ad56de752dfa15657de2f/sphinxcontrib_serializinghtml-2.0.0.tar.gz", hashes = {sha256 = "e9d912827f872c029017a53f0ef2180b327c3f7fd23c87229f7a8e8b70031d4d"}} -wheels = [ - {name = "sphinxcontrib_serializinghtml-2.0.0-py3-none-any.whl",url = "https://files.pythonhosted.org/packages/52/a7/d2782e4e3f77c8450f727ba74a8f12756d5ba823d81b941f1b04da9d033a/sphinxcontrib_serializinghtml-2.0.0-py3-none-any.whl",hashes = {sha256 = "6e2cb0eef194e10c27ec0023bfeb25badbbb5868244cf5bc5bdc04e4464bf331"}}, -] -marker = "\"docs\" in extras" - -[packages.tool.pdm] -dependencies = [] - -[[packages]] -name = "sphinxtesters" -version = "0.2.4" -requires-python = ">=3.8" -sdist = {name = "sphinxtesters-0.2.4.tar.gz", url = "https://files.pythonhosted.org/packages/aa/08/93af63fc5c6fd4c66b84a92c0048c5d2134fd168c6d763b01a476a3496f1/sphinxtesters-0.2.4.tar.gz", hashes = {sha256 = "09c456e1cd61ec99b64851e2990d2152fdf05bb53d87f3b294f22d73f939d6ca"}} -marker = "\"docs\" in extras" - -[packages.tool.pdm] -dependencies = [ - "sphinx>=1.4", -] - -[[packages]] -name = "stack-data" -version = "0.6.3" -sdist = {name = "stack_data-0.6.3.tar.gz", url = "https://files.pythonhosted.org/packages/28/e3/55dcc2cfbc3ca9c29519eb6884dd1415ecb53b0e934862d3559ddcb7e20b/stack_data-0.6.3.tar.gz", hashes = {sha256 = "836a778de4fec4dcd1dcd89ed8abff8a221f58308462e1c4aa2a3cf30148f0b9"}} -wheels = [ - {name = "stack_data-0.6.3-py3-none-any.whl",url = "https://files.pythonhosted.org/packages/f1/7b/ce1eafaf1a76852e2ec9b22edecf1daa58175c090266e9f6c64afcd81d91/stack_data-0.6.3-py3-none-any.whl",hashes = {sha256 = "d5558e0c25a4cb0853cddad3d77da9891a08cb85dd9f9f91b9f8cd66e511e695"}}, -] -marker = "\"docs\" in extras" - -[packages.tool.pdm] -dependencies = [ - "asttokens>=2.1.0", - "executing>=1.2.0", - "pure-eval", -] - -[[packages]] -name = "starlette" -version = "1.0.0" -requires-python = ">=3.10" -sdist = {name = "starlette-1.0.0.tar.gz", url = "https://files.pythonhosted.org/packages/81/69/17425771797c36cded50b7fe44e850315d039f28b15901ab44839e70b593/starlette-1.0.0.tar.gz", hashes = {sha256 = "6a4beaf1f81bb472fd19ea9b918b50dc3a77a6f2e190a12954b25e6ed5eea149"}} -wheels = [ - {name = "starlette-1.0.0-py3-none-any.whl",url = "https://files.pythonhosted.org/packages/0b/c9/584bc9651441b4ba60cc4d557d8a547b5aff901af35bda3a4ee30c819b82/starlette-1.0.0-py3-none-any.whl",hashes = {sha256 = "d3ec55e0bb321692d275455ddfd3df75fff145d009685eb40dc91fc66b03d38b"}}, -] -marker = "\"docs\" in extras" - -[packages.tool.pdm] -dependencies = [ - "anyio<5,>=3.6.2", - "typing-extensions>=4.10.0; python_version < \"3.13\"", -] - -[[packages]] -name = "statsmodels" -version = "0.14.1" -requires-python = ">=3.8" -sdist = {name = "statsmodels-0.14.1.tar.gz", url = "https://files.pythonhosted.org/packages/4b/80/c4e279a6a13468ae2f1f01af2a07ddb44f397ac4d7636af13c5b3b83dde1/statsmodels-0.14.1.tar.gz", hashes = {sha256 = "2260efdc1ef89f39c670a0bd8151b1d0843567781bcafec6cda0534eb47a94f6"}} -wheels = [ - {name = "statsmodels-0.14.1-cp312-cp312-macosx_10_9_x86_64.whl",url = "https://files.pythonhosted.org/packages/2e/e7/636f44ea2e42327feaf7e82d9943a17010b6bd1d2aee1691a82f6f8df26d/statsmodels-0.14.1-cp312-cp312-macosx_10_9_x86_64.whl",hashes = {sha256 = "f32a7cd424cf33304a54daee39d32cccf1d0265e652c920adeaeedff6d576457"}}, - {name = "statsmodels-0.14.1-cp312-cp312-macosx_11_0_arm64.whl",url = "https://files.pythonhosted.org/packages/dc/5e/ab969ede80024d1d988ffd4f60c2026ae16b647c41f867fabaa4d4e77cb8/statsmodels-0.14.1-cp312-cp312-macosx_11_0_arm64.whl",hashes = {sha256 = "f8c30181c084173d662aaf0531867667be2ff1bee103b84feb64f149f792dbd2"}}, - {name = "statsmodels-0.14.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl",url = "https://files.pythonhosted.org/packages/35/41/1000c2eb2ad62530a2c2a59a6de987bc8acb3362eb4c93a476e4a541d11c/statsmodels-0.14.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl",hashes = {sha256 = "2de2b97413913d52ad6342dece2d653e77f78620013b7705fad291d4e4266ccb"}}, - {name = "statsmodels-0.14.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",url = "https://files.pythonhosted.org/packages/d2/21/929083f9f4fa876ae3cf0d37483b52acc71c050afd4e802cbe5d7ed2f1fa/statsmodels-0.14.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",hashes = {sha256 = "c3420f88289c593ba2bca33619023059c476674c160733bd7d858564787c83d3"}}, - {name = "statsmodels-0.14.1-cp312-cp312-musllinux_1_1_x86_64.whl",url = "https://files.pythonhosted.org/packages/05/00/82b2f1a53b94b4c6f540efd9f1d8ff583d4e616908e5faf61b497b9e4814/statsmodels-0.14.1-cp312-cp312-musllinux_1_1_x86_64.whl",hashes = {sha256 = "c008e16096f24f0514e53907890ccac6589a16ad6c81c218f2ee6752fdada555"}}, - {name = "statsmodels-0.14.1-cp312-cp312-win_amd64.whl",url = "https://files.pythonhosted.org/packages/52/fc/4c0e654ab177558a657eaba369e5a25fbf700f95f1d122f6c083525d58c4/statsmodels-0.14.1-cp312-cp312-win_amd64.whl",hashes = {sha256 = "bc0351d279c4e080f0ce638a3d886d312aa29eade96042e3ba0a73771b1abdfb"}}, - {name = "statsmodels-0.14.1-cp311-cp311-macosx_10_9_x86_64.whl",url = "https://files.pythonhosted.org/packages/59/21/67f47ce99670a0f14f45419d37544fb5b2431c2f12ba34680f5729464cbe/statsmodels-0.14.1-cp311-cp311-macosx_10_9_x86_64.whl",hashes = {sha256 = "b69a63ad6c979a6e4cde11870ffa727c76a318c225a7e509f031fbbdfb4e416a"}}, - {name = "statsmodels-0.14.1-cp311-cp311-macosx_11_0_arm64.whl",url = "https://files.pythonhosted.org/packages/a1/ab/a43022ffd46fe5083773f36285a334713023ae86bab828708d17993fbb7b/statsmodels-0.14.1-cp311-cp311-macosx_11_0_arm64.whl",hashes = {sha256 = "7562cb18a90a114f39fab6f1c25b9c7b39d9cd5f433d0044b430ca9d44a8b52c"}}, - {name = "statsmodels-0.14.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl",url = "https://files.pythonhosted.org/packages/9a/f4/f9b83f8ffe00bc8d22ac6916ced94b1f622909c2f168bdd38d1afb7046e7/statsmodels-0.14.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl",hashes = {sha256 = "b3abaca4b963259a2bf349c7609cfbb0ce64ad5fb3d92d6f08e21453e4890248"}}, - {name = "statsmodels-0.14.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",url = "https://files.pythonhosted.org/packages/d7/e4/5c13fa7ac57bbee2bd0061efff851891a5d166587958d3aa5b6328f23f00/statsmodels-0.14.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",hashes = {sha256 = "b0f727fe697f6406d5f677b67211abe5a55101896abdfacdb3f38410405f6ad8"}}, - {name = "statsmodels-0.14.1-cp311-cp311-musllinux_1_1_x86_64.whl",url = "https://files.pythonhosted.org/packages/6a/e7/4a962975321d69c403089c175bb6735b517a31e31f5cdab8e37eedfdcea0/statsmodels-0.14.1-cp311-cp311-musllinux_1_1_x86_64.whl",hashes = {sha256 = "b6838ac6bdb286daabb5e91af90fd4258f09d0cec9aace78cc441cb2b17df428"}}, - {name = "statsmodels-0.14.1-cp311-cp311-win_amd64.whl",url = "https://files.pythonhosted.org/packages/9a/b2/13833f94076dcc2709137fee92157ef5a0099a11ddff4f4b7cb301b35357/statsmodels-0.14.1-cp311-cp311-win_amd64.whl",hashes = {sha256 = "709bfcef2dbe66f705b17e56d1021abad02243ee1a5d1efdb90f9bad8b06a329"}}, -] -marker = "\"default\" in dependency_groups" - -[packages.tool.pdm] -dependencies = [ - "numpy<2,>=1.18", - "numpy<2,>=1.22.3; python_version == \"3.10\" and platform_system == \"Windows\" and platform_python_implementation != \"PyPy\"", - "packaging>=21.3", - "pandas!=2.1.0,>=1.0", - "patsy>=0.5.4", - "scipy!=1.9.2,>=1.4", - "scipy!=1.9.2,>=1.4; sys_platform == \"win32\"", -] - -[[packages]] -name = "texext" -version = "0.6.8" -sdist = {name = "texext-0.6.8.tar.gz", url = "https://files.pythonhosted.org/packages/a6/73/5dc7e7955e4c5a45de3ef1467cfe498233cc3aba2a3c50ff41a55d667c42/texext-0.6.8.tar.gz", hashes = {sha256 = "6c3ccc5578f93a1bd0051fcba25e92d259620d3d9c9031738570e7d78603e7a3"}} -marker = "\"docs\" in extras" - -[packages.tool.pdm] -dependencies = [ - "docutils>=0.19", - "sphinx>=7", -] - -[[packages]] -name = "threadpoolctl" -version = "3.6.0" -requires-python = ">=3.9" -sdist = {name = "threadpoolctl-3.6.0.tar.gz", url = "https://files.pythonhosted.org/packages/b7/4d/08c89e34946fce2aec4fbb45c9016efd5f4d7f24af8e5d93296e935631d8/threadpoolctl-3.6.0.tar.gz", hashes = {sha256 = "8ab8b4aa3491d812b623328249fab5302a68d2d71745c8a4c719a2fcaba9f44e"}} -wheels = [ - {name = "threadpoolctl-3.6.0-py3-none-any.whl",url = "https://files.pythonhosted.org/packages/32/d5/f9a850d79b0851d1d4ef6456097579a9005b31fea68726a4ae5f2d82ddd9/threadpoolctl-3.6.0-py3-none-any.whl",hashes = {sha256 = "43a0b8fd5a2928500110039e43a5eed8480b918967083ea48dc3ab9f13c4a7fb"}}, -] -marker = "\"default\" in dependency_groups" - -[packages.tool.pdm] -dependencies = [] - -[[packages]] -name = "tinycss2" -version = "1.4.0" -requires-python = ">=3.8" -sdist = {name = "tinycss2-1.4.0.tar.gz", url = "https://files.pythonhosted.org/packages/7a/fd/7a5ee21fd08ff70d3d33a5781c255cbe779659bd03278feb98b19ee550f4/tinycss2-1.4.0.tar.gz", hashes = {sha256 = "10c0972f6fc0fbee87c3edb76549357415e94548c1ae10ebccdea16fb404a9b7"}} -wheels = [ - {name = "tinycss2-1.4.0-py3-none-any.whl",url = "https://files.pythonhosted.org/packages/e6/34/ebdc18bae6aa14fbee1a08b63c015c72b64868ff7dae68808ab500c492e2/tinycss2-1.4.0-py3-none-any.whl",hashes = {sha256 = "3a49cf47b7675da0b15d0c6e1df8df4ebd96e9394bb905a5775adb0d884c5289"}}, -] -marker = "\"docs\" in extras" - -[packages.tool.pdm] -dependencies = [ - "webencodings>=0.4", -] - -[[packages]] -name = "tomlkit" -version = "0.14.0" -requires-python = ">=3.9" -sdist = {name = "tomlkit-0.14.0.tar.gz", url = "https://files.pythonhosted.org/packages/c3/af/14b24e41977adb296d6bd1fb59402cf7d60ce364f90c890bd2ec65c43b5a/tomlkit-0.14.0.tar.gz", hashes = {sha256 = "cf00efca415dbd57575befb1f6634c4f42d2d87dbba376128adb42c121b87064"}} -wheels = [ - {name = "tomlkit-0.14.0-py3-none-any.whl",url = "https://files.pythonhosted.org/packages/b5/11/87d6d29fb5d237229d67973a6c9e06e048f01cf4994dee194ab0ea841814/tomlkit-0.14.0-py3-none-any.whl",hashes = {sha256 = "592064ed85b40fa213469f81ac584f67a4f2992509a7c3ea2d632208623a3680"}}, -] -marker = "\"docs\" in extras" - -[packages.tool.pdm] -dependencies = [] - -[[packages]] -name = "tornado" -version = "6.5.5" -requires-python = ">=3.9" -sdist = {name = "tornado-6.5.5.tar.gz", url = "https://files.pythonhosted.org/packages/f8/f1/3173dfa4a18db4a9b03e5d55325559dab51ee653763bb8745a75af491286/tornado-6.5.5.tar.gz", hashes = {sha256 = "192b8f3ea91bd7f1f50c06955416ed76c6b72f96779b962f07f911b91e8d30e9"}} -wheels = [ - {name = "tornado-6.5.5-cp39-abi3-macosx_10_9_universal2.whl",url = "https://files.pythonhosted.org/packages/59/8c/77f5097695f4dd8255ecbd08b2a1ed8ba8b953d337804dd7080f199e12bf/tornado-6.5.5-cp39-abi3-macosx_10_9_universal2.whl",hashes = {sha256 = "487dc9cc380e29f58c7ab88f9e27cdeef04b2140862e5076a66fb6bb68bb1bfa"}}, - {name = "tornado-6.5.5-cp39-abi3-macosx_10_9_x86_64.whl",url = "https://files.pythonhosted.org/packages/ab/5e/7625b76cd10f98f1516c36ce0346de62061156352353ef2da44e5c21523c/tornado-6.5.5-cp39-abi3-macosx_10_9_x86_64.whl",hashes = {sha256 = "65a7f1d46d4bb41df1ac99f5fcb685fb25c7e61613742d5108b010975a9a6521"}}, - {name = "tornado-6.5.5-cp39-abi3-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl",url = "https://files.pythonhosted.org/packages/b2/04/7b5705d5b3c0fab088f434f9c83edac1573830ca49ccf29fb83bf7178eec/tornado-6.5.5-cp39-abi3-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl",hashes = {sha256 = "e74c92e8e65086b338fd56333fb9a68b9f6f2fe7ad532645a290a464bcf46be5"}}, - {name = "tornado-6.5.5-cp39-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl",url = "https://files.pythonhosted.org/packages/34/01/74e034a30ef59afb4097ef8659515e96a39d910b712a89af76f5e4e1f93c/tornado-6.5.5-cp39-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl",hashes = {sha256 = "435319e9e340276428bbdb4e7fa732c2d399386d1de5686cb331ec8eee754f07"}}, - {name = "tornado-6.5.5-cp39-abi3-musllinux_1_2_aarch64.whl",url = "https://files.pythonhosted.org/packages/be/00/fe9e02c5a96429fce1a1d15a517f5d8444f9c412e0bb9eadfbe3b0fc55bf/tornado-6.5.5-cp39-abi3-musllinux_1_2_aarch64.whl",hashes = {sha256 = "3f54aa540bdbfee7b9eb268ead60e7d199de5021facd276819c193c0fb28ea4e"}}, - {name = "tornado-6.5.5-cp39-abi3-musllinux_1_2_x86_64.whl",url = "https://files.pythonhosted.org/packages/82/9e/656ee4cec0398b1d18d0f1eb6372c41c6b889722641d84948351ae19556d/tornado-6.5.5-cp39-abi3-musllinux_1_2_x86_64.whl",hashes = {sha256 = "36abed1754faeb80fbd6e64db2758091e1320f6bba74a4cf8c09cd18ccce8aca"}}, - {name = "tornado-6.5.5-cp39-abi3-win32.whl",url = "https://files.pythonhosted.org/packages/5a/76/4921c00511f88af86a33de770d64141170f1cfd9c00311aea689949e274e/tornado-6.5.5-cp39-abi3-win32.whl",hashes = {sha256 = "dd3eafaaeec1c7f2f8fdcd5f964e8907ad788fe8a5a32c4426fbbdda621223b7"}}, - {name = "tornado-6.5.5-cp39-abi3-win_amd64.whl",url = "https://files.pythonhosted.org/packages/2c/23/f6c6112a04d28eed765e374435fb1a9198f73e1ec4b4024184f21faeb1ad/tornado-6.5.5-cp39-abi3-win_amd64.whl",hashes = {sha256 = "6443a794ba961a9f619b1ae926a2e900ac20c34483eea67be4ed8f1e58d3ef7b"}}, - {name = "tornado-6.5.5-cp39-abi3-win_arm64.whl",url = "https://files.pythonhosted.org/packages/b7/c8/876602cbc96469911f0939f703453c1157b0c826ecb05bdd32e023397d4e/tornado-6.5.5-cp39-abi3-win_arm64.whl",hashes = {sha256 = "2c9a876e094109333f888539ddb2de4361743e5d21eece20688e3e351e4990a6"}}, -] -marker = "\"docs\" in extras" - -[packages.tool.pdm] -dependencies = [] - -[[packages]] -name = "traitlets" -version = "5.14.3" -requires-python = ">=3.8" -sdist = {name = "traitlets-5.14.3.tar.gz", url = "https://files.pythonhosted.org/packages/eb/79/72064e6a701c2183016abbbfedaba506d81e30e232a68c9f0d6f6fcd1574/traitlets-5.14.3.tar.gz", hashes = {sha256 = "9ed0579d3502c94b4b3732ac120375cda96f923114522847de4b3bb98b96b6b7"}} -wheels = [ - {name = "traitlets-5.14.3-py3-none-any.whl",url = "https://files.pythonhosted.org/packages/00/c0/8f5d070730d7836adc9c9b6408dec68c6ced86b304a9b26a14df072a6e8c/traitlets-5.14.3-py3-none-any.whl",hashes = {sha256 = "b74e89e397b1ed28cc831db7aea759ba6640cb3de13090ca145426688ff1ac4f"}}, -] -marker = "\"docs\" in extras" - -[packages.tool.pdm] -dependencies = [] - -[[packages]] -name = "typing-extensions" -version = "4.15.0" -requires-python = ">=3.9" -sdist = {name = "typing_extensions-4.15.0.tar.gz", url = "https://files.pythonhosted.org/packages/72/94/1a15dd82efb362ac84269196e94cf00f187f7ed21c242792a923cdb1c61f/typing_extensions-4.15.0.tar.gz", hashes = {sha256 = "0cea48d173cc12fa28ecabc3b837ea3cf6f38c6d1136f85cbaaf598984861466"}} -wheels = [ - {name = "typing_extensions-4.15.0-py3-none-any.whl",url = "https://files.pythonhosted.org/packages/18/67/36e9267722cc04a6b9f15c7f3441c2363321a3ea07da7ae0c0707beb2a9c/typing_extensions-4.15.0-py3-none-any.whl",hashes = {sha256 = "f0fa19c6845758ab08074a0cfa8b7aecb71c999ca73d62883bc25cc018c4e548"}}, -] -marker = "\"default\" in dependency_groups or \"docs\" in extras" - -[packages.tool.pdm] -dependencies = [] - -[[packages]] -name = "tzdata" -version = "2026.1" -requires-python = ">=2" -sdist = {name = "tzdata-2026.1.tar.gz", url = "https://files.pythonhosted.org/packages/19/f5/cd531b2d15a671a40c0f66cf06bc3570a12cd56eef98960068ebbad1bf5a/tzdata-2026.1.tar.gz", hashes = {sha256 = "67658a1903c75917309e753fdc349ac0efd8c27db7a0cb406a25be4840f87f98"}} -wheels = [ - {name = "tzdata-2026.1-py2.py3-none-any.whl",url = "https://files.pythonhosted.org/packages/b0/70/d460bd685a170790ec89317e9bd33047988e4bce507b831f5db771e142de/tzdata-2026.1-py2.py3-none-any.whl",hashes = {sha256 = "4b1d2be7ac37ceafd7327b961aa3a54e467efbdb563a23655fbfe0d39cfc42a9"}}, -] -marker = "\"default\" in dependency_groups" - -[packages.tool.pdm] -dependencies = [] - -[[packages]] -name = "urllib3" -version = "2.6.3" -requires-python = ">=3.9" -sdist = {name = "urllib3-2.6.3.tar.gz", url = "https://files.pythonhosted.org/packages/c7/24/5f1b3bdffd70275f6661c76461e25f024d5a38a46f04aaca912426a2b1d3/urllib3-2.6.3.tar.gz", hashes = {sha256 = "1b62b6884944a57dbe321509ab94fd4d3b307075e0c2eae991ac71ee15ad38ed"}} -wheels = [ - {name = "urllib3-2.6.3-py3-none-any.whl",url = "https://files.pythonhosted.org/packages/39/08/aaaad47bc4e9dc8c725e68f9d04865dbcb2052843ff09c97b08904852d84/urllib3-2.6.3-py3-none-any.whl",hashes = {sha256 = "bf272323e553dfb2e87d9bfd225ca7b0f467b919d7bbd355436d3fd37cb0acd4"}}, -] -marker = "\"default\" in dependency_groups or \"docs\" in extras" - -[packages.tool.pdm] -dependencies = [] - -[[packages]] -name = "uvicorn" -version = "0.44.0" -requires-python = ">=3.10" -sdist = {name = "uvicorn-0.44.0.tar.gz", url = "https://files.pythonhosted.org/packages/5e/da/6eee1ff8b6cbeed47eeb5229749168e81eb4b7b999a1a15a7176e51410c9/uvicorn-0.44.0.tar.gz", hashes = {sha256 = "6c942071b68f07e178264b9152f1f16dfac5da85880c4ce06366a96d70d4f31e"}} -wheels = [ - {name = "uvicorn-0.44.0-py3-none-any.whl",url = "https://files.pythonhosted.org/packages/b7/23/a5bbd9600dd607411fa644c06ff4951bec3a4d82c4b852374024359c19c0/uvicorn-0.44.0-py3-none-any.whl",hashes = {sha256 = "ce937c99a2cc70279556967274414c087888e8cec9f9c94644dfca11bd3ced89"}}, -] -marker = "\"docs\" in extras" - -[packages.tool.pdm] -dependencies = [ - "click>=7.0", - "h11>=0.8", - "typing-extensions>=4.0; python_version < \"3.11\"", -] - -[[packages]] -name = "watchfiles" -version = "1.1.1" -requires-python = ">=3.9" -sdist = {name = "watchfiles-1.1.1.tar.gz", url = "https://files.pythonhosted.org/packages/c2/c9/8869df9b2a2d6c59d79220a4db37679e74f807c559ffe5265e08b227a210/watchfiles-1.1.1.tar.gz", hashes = {sha256 = "a173cb5c16c4f40ab19cecf48a534c409f7ea983ab8fed0741304a1c0a31b3f2"}} -wheels = [ - {name = "watchfiles-1.1.1-cp314-cp314-macosx_10_12_x86_64.whl",url = "https://files.pythonhosted.org/packages/c3/f4/0872229324ef69b2c3edec35e84bd57a1289e7d3fe74588048ed8947a323/watchfiles-1.1.1-cp314-cp314-macosx_10_12_x86_64.whl",hashes = {sha256 = "d1715143123baeeaeadec0528bb7441103979a1d5f6fd0e1f915383fea7ea6d5"}}, - {name = "watchfiles-1.1.1-cp314-cp314-macosx_11_0_arm64.whl",url = "https://files.pythonhosted.org/packages/7b/22/16d5331eaed1cb107b873f6ae1b69e9ced582fcf0c59a50cd84f403b1c32/watchfiles-1.1.1-cp314-cp314-macosx_11_0_arm64.whl",hashes = {sha256 = "39574d6370c4579d7f5d0ad940ce5b20db0e4117444e39b6d8f99db5676c52fd"}}, - {name = "watchfiles-1.1.1-cp314-cp314-manylinux_2_17_aarch64.manylinux2014_aarch64.whl",url = "https://files.pythonhosted.org/packages/b2/7e/5643bfff5acb6539b18483128fdc0ef2cccc94a5b8fbda130c823e8ed636/watchfiles-1.1.1-cp314-cp314-manylinux_2_17_aarch64.manylinux2014_aarch64.whl",hashes = {sha256 = "7365b92c2e69ee952902e8f70f3ba6360d0d596d9299d55d7d386df84b6941fb"}}, - {name = "watchfiles-1.1.1-cp314-cp314-manylinux_2_17_armv7l.manylinux2014_armv7l.whl",url = "https://files.pythonhosted.org/packages/51/2e/c410993ba5025a9f9357c376f48976ef0e1b1aefb73b97a5ae01a5972755/watchfiles-1.1.1-cp314-cp314-manylinux_2_17_armv7l.manylinux2014_armv7l.whl",hashes = {sha256 = "bfff9740c69c0e4ed32416f013f3c45e2ae42ccedd1167ef2d805c000b6c71a5"}}, - {name = "watchfiles-1.1.1-cp314-cp314-manylinux_2_17_i686.manylinux2014_i686.whl",url = "https://files.pythonhosted.org/packages/8e/a4/2df3b404469122e8680f0fcd06079317e48db58a2da2950fb45020947734/watchfiles-1.1.1-cp314-cp314-manylinux_2_17_i686.manylinux2014_i686.whl",hashes = {sha256 = "b27cf2eb1dda37b2089e3907d8ea92922b673c0c427886d4edc6b94d8dfe5db3"}}, - {name = "watchfiles-1.1.1-cp314-cp314-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl",url = "https://files.pythonhosted.org/packages/ea/84/4587ba5b1f267167ee715b7f66e6382cca6938e0a4b870adad93e44747e6/watchfiles-1.1.1-cp314-cp314-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl",hashes = {sha256 = "526e86aced14a65a5b0ec50827c745597c782ff46b571dbfe46192ab9e0b3c33"}}, - {name = "watchfiles-1.1.1-cp314-cp314-manylinux_2_17_s390x.manylinux2014_s390x.whl",url = "https://files.pythonhosted.org/packages/6a/0f/c6988c91d06e93cd0bb3d4a808bcf32375ca1904609835c3031799e3ecae/watchfiles-1.1.1-cp314-cp314-manylinux_2_17_s390x.manylinux2014_s390x.whl",hashes = {sha256 = "04e78dd0b6352db95507fd8cb46f39d185cf8c74e4cf1e4fbad1d3df96faf510"}}, - {name = "watchfiles-1.1.1-cp314-cp314-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",url = "https://files.pythonhosted.org/packages/b4/36/ded8aebea91919485b7bbabbd14f5f359326cb5ec218cd67074d1e426d74/watchfiles-1.1.1-cp314-cp314-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",hashes = {sha256 = "5c85794a4cfa094714fb9c08d4a218375b2b95b8ed1666e8677c349906246c05"}}, - {name = "watchfiles-1.1.1-cp314-cp314-musllinux_1_1_aarch64.whl",url = "https://files.pythonhosted.org/packages/98/e0/8c9bdba88af756a2fce230dd365fab2baf927ba42cd47521ee7498fd5211/watchfiles-1.1.1-cp314-cp314-musllinux_1_1_aarch64.whl",hashes = {sha256 = "74d5012b7630714b66be7b7b7a78855ef7ad58e8650c73afc4c076a1f480a8d6"}}, - {name = "watchfiles-1.1.1-cp314-cp314-musllinux_1_1_x86_64.whl",url = "https://files.pythonhosted.org/packages/2a/84/a95db05354bf2d19e438520d92a8ca475e578c647f78f53197f5a2f17aaf/watchfiles-1.1.1-cp314-cp314-musllinux_1_1_x86_64.whl",hashes = {sha256 = "8fbe85cb3201c7d380d3d0b90e63d520f15d6afe217165d7f98c9c649654db81"}}, - {name = "watchfiles-1.1.1-cp314-cp314-win32.whl",url = "https://files.pythonhosted.org/packages/1d/ce/d8acdc8de545de995c339be67711e474c77d643555a9bb74a9334252bd55/watchfiles-1.1.1-cp314-cp314-win32.whl",hashes = {sha256 = "3fa0b59c92278b5a7800d3ee7733da9d096d4aabcfabb9a928918bd276ef9b9b"}}, - {name = "watchfiles-1.1.1-cp314-cp314-win_amd64.whl",url = "https://files.pythonhosted.org/packages/c4/c9/a74487f72d0451524be827e8edec251da0cc1fcf111646a511ae752e1a3d/watchfiles-1.1.1-cp314-cp314-win_amd64.whl",hashes = {sha256 = "c2047d0b6cea13b3316bdbafbfa0c4228ae593d995030fda39089d36e64fc03a"}}, - {name = "watchfiles-1.1.1-cp314-cp314-win_arm64.whl",url = "https://files.pythonhosted.org/packages/df/b8/8ac000702cdd496cdce998c6f4ee0ca1f15977bba51bdf07d872ebdfc34c/watchfiles-1.1.1-cp314-cp314-win_arm64.whl",hashes = {sha256 = "842178b126593addc05acf6fce960d28bc5fae7afbaa2c6c1b3a7b9460e5be02"}}, - {name = "watchfiles-1.1.1-cp314-cp314t-macosx_10_12_x86_64.whl",url = "https://files.pythonhosted.org/packages/47/a8/e3af2184707c29f0f14b1963c0aace6529f9d1b8582d5b99f31bbf42f59e/watchfiles-1.1.1-cp314-cp314t-macosx_10_12_x86_64.whl",hashes = {sha256 = "88863fbbc1a7312972f1c511f202eb30866370ebb8493aef2812b9ff28156a21"}}, - {name = "watchfiles-1.1.1-cp314-cp314t-macosx_11_0_arm64.whl",url = "https://files.pythonhosted.org/packages/c0/ec/e47e307c2f4bd75f9f9e8afbe3876679b18e1bcec449beca132a1c5ffb2d/watchfiles-1.1.1-cp314-cp314t-macosx_11_0_arm64.whl",hashes = {sha256 = "55c7475190662e202c08c6c0f4d9e345a29367438cf8e8037f3155e10a88d5a5"}}, - {name = "watchfiles-1.1.1-cp314-cp314t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl",url = "https://files.pythonhosted.org/packages/d5/a0/ad235642118090f66e7b2f18fd5c42082418404a79205cdfca50b6309c13/watchfiles-1.1.1-cp314-cp314t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl",hashes = {sha256 = "3f53fa183d53a1d7a8852277c92b967ae99c2d4dcee2bfacff8868e6e30b15f7"}}, - {name = "watchfiles-1.1.1-cp314-cp314t-manylinux_2_17_armv7l.manylinux2014_armv7l.whl",url = "https://files.pythonhosted.org/packages/df/85/97fa10fd5ff3332ae17e7e40e20784e419e28521549780869f1413742e9d/watchfiles-1.1.1-cp314-cp314t-manylinux_2_17_armv7l.manylinux2014_armv7l.whl",hashes = {sha256 = "6aae418a8b323732fa89721d86f39ec8f092fc2af67f4217a2b07fd3e93c6101"}}, - {name = "watchfiles-1.1.1-cp314-cp314t-manylinux_2_17_i686.manylinux2014_i686.whl",url = "https://files.pythonhosted.org/packages/47/c2/9059c2e8966ea5ce678166617a7f75ecba6164375f3b288e50a40dc6d489/watchfiles-1.1.1-cp314-cp314t-manylinux_2_17_i686.manylinux2014_i686.whl",hashes = {sha256 = "f096076119da54a6080e8920cbdaac3dbee667eb91dcc5e5b78840b87415bd44"}}, - {name = "watchfiles-1.1.1-cp314-cp314t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl",url = "https://files.pythonhosted.org/packages/94/44/d90a9ec8ac309bc26db808a13e7bfc0e4e78b6fc051078a554e132e80160/watchfiles-1.1.1-cp314-cp314t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl",hashes = {sha256 = "00485f441d183717038ed2e887a7c868154f216877653121068107b227a2f64c"}}, - {name = "watchfiles-1.1.1-cp314-cp314t-manylinux_2_17_s390x.manylinux2014_s390x.whl",url = "https://files.pythonhosted.org/packages/95/68/4e3479b20ca305cfc561db3ed207a8a1c745ee32bf24f2026a129d0ddb6e/watchfiles-1.1.1-cp314-cp314t-manylinux_2_17_s390x.manylinux2014_s390x.whl",hashes = {sha256 = "a55f3e9e493158d7bfdb60a1165035f1cf7d320914e7b7ea83fe22c6023b58fc"}}, - {name = "watchfiles-1.1.1-cp314-cp314t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",url = "https://files.pythonhosted.org/packages/4f/55/2af26693fd15165c4ff7857e38330e1b61ab8c37d15dc79118cdba115b7a/watchfiles-1.1.1-cp314-cp314t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",hashes = {sha256 = "8c91ed27800188c2ae96d16e3149f199d62f86c7af5f5f4d2c61a3ed8cd3666c"}}, - {name = "watchfiles-1.1.1-cp314-cp314t-musllinux_1_1_aarch64.whl",url = "https://files.pythonhosted.org/packages/66/1d/d0d200b10c9311ec25d2273f8aad8c3ef7cc7ea11808022501811208a750/watchfiles-1.1.1-cp314-cp314t-musllinux_1_1_aarch64.whl",hashes = {sha256 = "311ff15a0bae3714ffb603e6ba6dbfba4065ab60865d15a6ec544133bdb21099"}}, - {name = "watchfiles-1.1.1-cp314-cp314t-musllinux_1_1_x86_64.whl",url = "https://files.pythonhosted.org/packages/e3/bd/fa9bb053192491b3867ba07d2343d9f2252e00811567d30ae8d0f78136fe/watchfiles-1.1.1-cp314-cp314t-musllinux_1_1_x86_64.whl",hashes = {sha256 = "a916a2932da8f8ab582f242c065f5c81bed3462849ca79ee357dd9551b0e9b01"}}, - {name = "watchfiles-1.1.1-cp313-cp313-macosx_10_12_x86_64.whl",url = "https://files.pythonhosted.org/packages/bb/f4/f750b29225fe77139f7ae5de89d4949f5a99f934c65a1f1c0b248f26f747/watchfiles-1.1.1-cp313-cp313-macosx_10_12_x86_64.whl",hashes = {sha256 = "130e4876309e8686a5e37dba7d5e9bc77e6ed908266996ca26572437a5271e18"}}, - {name = "watchfiles-1.1.1-cp313-cp313-macosx_11_0_arm64.whl",url = "https://files.pythonhosted.org/packages/2b/f9/f07a295cde762644aa4c4bb0f88921d2d141af45e735b965fb2e87858328/watchfiles-1.1.1-cp313-cp313-macosx_11_0_arm64.whl",hashes = {sha256 = "5f3bde70f157f84ece3765b42b4a52c6ac1a50334903c6eaf765362f6ccca88a"}}, - {name = "watchfiles-1.1.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl",url = "https://files.pythonhosted.org/packages/bc/11/fc2502457e0bea39a5c958d86d2cb69e407a4d00b85735ca724bfa6e0d1a/watchfiles-1.1.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl",hashes = {sha256 = "14e0b1fe858430fc0251737ef3824c54027bedb8c37c38114488b8e131cf8219"}}, - {name = "watchfiles-1.1.1-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl",url = "https://files.pythonhosted.org/packages/e3/1f/d66bc15ea0b728df3ed96a539c777acfcad0eb78555ad9efcaa1274688f0/watchfiles-1.1.1-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl",hashes = {sha256 = "f27db948078f3823a6bb3b465180db8ebecf26dd5dae6f6180bd87383b6b4428"}}, - {name = "watchfiles-1.1.1-cp313-cp313-manylinux_2_17_i686.manylinux2014_i686.whl",url = "https://files.pythonhosted.org/packages/be/90/9f4a65c0aec3ccf032703e6db02d89a157462fbb2cf20dd415128251cac0/watchfiles-1.1.1-cp313-cp313-manylinux_2_17_i686.manylinux2014_i686.whl",hashes = {sha256 = "059098c3a429f62fc98e8ec62b982230ef2c8df68c79e826e37b895bc359a9c0"}}, - {name = "watchfiles-1.1.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl",url = "https://files.pythonhosted.org/packages/37/57/ee347af605d867f712be7029bb94c8c071732a4b44792e3176fa3c612d39/watchfiles-1.1.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl",hashes = {sha256 = "bfb5862016acc9b869bb57284e6cb35fdf8e22fe59f7548858e2f971d045f150"}}, - {name = "watchfiles-1.1.1-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl",url = "https://files.pythonhosted.org/packages/a8/78/cc5ab0b86c122047f75e8fc471c67a04dee395daf847d3e59381996c8707/watchfiles-1.1.1-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl",hashes = {sha256 = "319b27255aacd9923b8a276bb14d21a5f7ff82564c744235fc5eae58d95422ae"}}, - {name = "watchfiles-1.1.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",url = "https://files.pythonhosted.org/packages/62/da/def65b170a3815af7bd40a3e7010bf6ab53089ef1b75d05dd5385b87cf08/watchfiles-1.1.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",hashes = {sha256 = "c755367e51db90e75b19454b680903631d41f9e3607fbd941d296a020c2d752d"}}, - {name = "watchfiles-1.1.1-cp313-cp313-musllinux_1_1_aarch64.whl",url = "https://files.pythonhosted.org/packages/57/99/da6573ba71166e82d288d4df0839128004c67d2778d3b566c138695f5c0b/watchfiles-1.1.1-cp313-cp313-musllinux_1_1_aarch64.whl",hashes = {sha256 = "c22c776292a23bfc7237a98f791b9ad3144b02116ff10d820829ce62dff46d0b"}}, - {name = "watchfiles-1.1.1-cp313-cp313-musllinux_1_1_x86_64.whl",url = "https://files.pythonhosted.org/packages/a8/51/7439c4dd39511368849eb1e53279cd3454b4a4dbace80bab88feeb83c6b5/watchfiles-1.1.1-cp313-cp313-musllinux_1_1_x86_64.whl",hashes = {sha256 = "3a476189be23c3686bc2f4321dd501cb329c0a0469e77b7b534ee10129ae6374"}}, - {name = "watchfiles-1.1.1-cp313-cp313-win32.whl",url = "https://files.pythonhosted.org/packages/95/9c/8ed97d4bba5db6fdcdb2b298d3898f2dd5c20f6b73aee04eabe56c59677e/watchfiles-1.1.1-cp313-cp313-win32.whl",hashes = {sha256 = "bf0a91bfb5574a2f7fc223cf95eeea79abfefa404bf1ea5e339c0c1560ae99a0"}}, - {name = "watchfiles-1.1.1-cp313-cp313-win_amd64.whl",url = "https://files.pythonhosted.org/packages/1f/f3/c14e28429f744a260d8ceae18bf58c1d5fa56b50d006a7a9f80e1882cb0d/watchfiles-1.1.1-cp313-cp313-win_amd64.whl",hashes = {sha256 = "52e06553899e11e8074503c8e716d574adeeb7e68913115c4b3653c53f9bae42"}}, - {name = "watchfiles-1.1.1-cp313-cp313-win_arm64.whl",url = "https://files.pythonhosted.org/packages/dc/61/fe0e56c40d5cd29523e398d31153218718c5786b5e636d9ae8ae79453d27/watchfiles-1.1.1-cp313-cp313-win_arm64.whl",hashes = {sha256 = "ac3cc5759570cd02662b15fbcd9d917f7ecd47efe0d6b40474eafd246f91ea18"}}, - {name = "watchfiles-1.1.1-cp313-cp313t-macosx_10_12_x86_64.whl",url = "https://files.pythonhosted.org/packages/79/42/e0a7d749626f1e28c7108a99fb9bf524b501bbbeb9b261ceecde644d5a07/watchfiles-1.1.1-cp313-cp313t-macosx_10_12_x86_64.whl",hashes = {sha256 = "563b116874a9a7ce6f96f87cd0b94f7faf92d08d0021e837796f0a14318ef8da"}}, - {name = "watchfiles-1.1.1-cp313-cp313t-macosx_11_0_arm64.whl",url = "https://files.pythonhosted.org/packages/15/49/08732f90ce0fbbc13913f9f215c689cfc9ced345fb1bcd8829a50007cc8d/watchfiles-1.1.1-cp313-cp313t-macosx_11_0_arm64.whl",hashes = {sha256 = "3ad9fe1dae4ab4212d8c91e80b832425e24f421703b5a42ef2e4a1e215aff051"}}, - {name = "watchfiles-1.1.1-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl",url = "https://files.pythonhosted.org/packages/27/0d/7c315d4bd5f2538910491a0393c56bf70d333d51bc5b34bee8e68e8cea19/watchfiles-1.1.1-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl",hashes = {sha256 = "ce70f96a46b894b36eba678f153f052967a0d06d5b5a19b336ab0dbbd029f73e"}}, - {name = "watchfiles-1.1.1-cp313-cp313t-manylinux_2_17_armv7l.manylinux2014_armv7l.whl",url = "https://files.pythonhosted.org/packages/c3/24/9e096de47a4d11bc4df41e9d1e61776393eac4cb6eb11b3e23315b78b2cc/watchfiles-1.1.1-cp313-cp313t-manylinux_2_17_armv7l.manylinux2014_armv7l.whl",hashes = {sha256 = "cb467c999c2eff23a6417e58d75e5828716f42ed8289fe6b77a7e5a91036ca70"}}, - {name = "watchfiles-1.1.1-cp313-cp313t-manylinux_2_17_i686.manylinux2014_i686.whl",url = "https://files.pythonhosted.org/packages/cc/0f/e8dea6375f1d3ba5fcb0b3583e2b493e77379834c74fd5a22d66d85d6540/watchfiles-1.1.1-cp313-cp313t-manylinux_2_17_i686.manylinux2014_i686.whl",hashes = {sha256 = "836398932192dae4146c8f6f737d74baeac8b70ce14831a239bdb1ca882fc261"}}, - {name = "watchfiles-1.1.1-cp313-cp313t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl",url = "https://files.pythonhosted.org/packages/ac/5b/df24cfc6424a12deb41503b64d42fbea6b8cb357ec62ca84a5a3476f654a/watchfiles-1.1.1-cp313-cp313t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl",hashes = {sha256 = "743185e7372b7bc7c389e1badcc606931a827112fbbd37f14c537320fca08620"}}, - {name = "watchfiles-1.1.1-cp313-cp313t-manylinux_2_17_s390x.manylinux2014_s390x.whl",url = "https://files.pythonhosted.org/packages/8f/b5/853b6757f7347de4e9b37e8cc3289283fb983cba1ab4d2d7144694871d9c/watchfiles-1.1.1-cp313-cp313t-manylinux_2_17_s390x.manylinux2014_s390x.whl",hashes = {sha256 = "afaeff7696e0ad9f02cbb8f56365ff4686ab205fcf9c4c5b6fdfaaa16549dd04"}}, - {name = "watchfiles-1.1.1-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",url = "https://files.pythonhosted.org/packages/e1/f7/0a4467be0a56e80447c8529c9fce5b38eab4f513cb3d9bf82e7392a5696b/watchfiles-1.1.1-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",hashes = {sha256 = "3f7eb7da0eb23aa2ba036d4f616d46906013a68caf61b7fdbe42fc8b25132e77"}}, - {name = "watchfiles-1.1.1-cp313-cp313t-musllinux_1_1_aarch64.whl",url = "https://files.pythonhosted.org/packages/8e/e0/82583485ea00137ddf69bc84a2db88bd92ab4a6e3c405e5fb878ead8d0e7/watchfiles-1.1.1-cp313-cp313t-musllinux_1_1_aarch64.whl",hashes = {sha256 = "831a62658609f0e5c64178211c942ace999517f5770fe9436be4c2faeba0c0ef"}}, - {name = "watchfiles-1.1.1-cp313-cp313t-musllinux_1_1_x86_64.whl",url = "https://files.pythonhosted.org/packages/28/9a/a785356fccf9fae84c0cc90570f11702ae9571036fb25932f1242c82191c/watchfiles-1.1.1-cp313-cp313t-musllinux_1_1_x86_64.whl",hashes = {sha256 = "f9a2ae5c91cecc9edd47e041a930490c31c3afb1f5e6d71de3dc671bfaca02bf"}}, - {name = "watchfiles-1.1.1-cp312-cp312-macosx_10_12_x86_64.whl",url = "https://files.pythonhosted.org/packages/74/d5/f039e7e3c639d9b1d09b07ea412a6806d38123f0508e5f9b48a87b0a76cc/watchfiles-1.1.1-cp312-cp312-macosx_10_12_x86_64.whl",hashes = {sha256 = "8c89f9f2f740a6b7dcc753140dd5e1ab9215966f7a3530d0c0705c83b401bd7d"}}, - {name = "watchfiles-1.1.1-cp312-cp312-macosx_11_0_arm64.whl",url = "https://files.pythonhosted.org/packages/a5/96/a881a13aa1349827490dab2d363c8039527060cfcc2c92cc6d13d1b1049e/watchfiles-1.1.1-cp312-cp312-macosx_11_0_arm64.whl",hashes = {sha256 = "bd404be08018c37350f0d6e34676bd1e2889990117a2b90070b3007f172d0610"}}, - {name = "watchfiles-1.1.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl",url = "https://files.pythonhosted.org/packages/4b/5b/d3b460364aeb8da471c1989238ea0e56bec24b6042a68046adf3d9ddb01c/watchfiles-1.1.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl",hashes = {sha256 = "8526e8f916bb5b9a0a777c8317c23ce65de259422bba5b31325a6fa6029d33af"}}, - {name = "watchfiles-1.1.1-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl",url = "https://files.pythonhosted.org/packages/b9/44/5769cb62d4ed055cb17417c0a109a92f007114a4e07f30812a73a4efdb11/watchfiles-1.1.1-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl",hashes = {sha256 = "2edc3553362b1c38d9f06242416a5d8e9fe235c204a4072e988ce2e5bb1f69f6"}}, - {name = "watchfiles-1.1.1-cp312-cp312-manylinux_2_17_i686.manylinux2014_i686.whl",url = "https://files.pythonhosted.org/packages/19/0c/286b6301ded2eccd4ffd0041a1b726afda999926cf720aab63adb68a1e36/watchfiles-1.1.1-cp312-cp312-manylinux_2_17_i686.manylinux2014_i686.whl",hashes = {sha256 = "30f7da3fb3f2844259cba4720c3fc7138eb0f7b659c38f3bfa65084c7fc7abce"}}, - {name = "watchfiles-1.1.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl",url = "https://files.pythonhosted.org/packages/c7/2b/8530ed41112dd4a22f4dcfdb5ccf6a1baad1ff6eed8dc5a5f09e7e8c41c7/watchfiles-1.1.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl",hashes = {sha256 = "f8979280bdafff686ba5e4d8f97840f929a87ed9cdf133cbbd42f7766774d2aa"}}, - {name = "watchfiles-1.1.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl",url = "https://files.pythonhosted.org/packages/ce/d2/f5f9fb49489f184f18470d4f99f4e862a4b3e9ac2865688eb2099e3d837a/watchfiles-1.1.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl",hashes = {sha256 = "dcc5c24523771db3a294c77d94771abcfcb82a0e0ee8efd910c37c59ec1b31bb"}}, - {name = "watchfiles-1.1.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",url = "https://files.pythonhosted.org/packages/cf/68/5707da262a119fb06fbe214d82dd1fe4a6f4af32d2d14de368d0349eb52a/watchfiles-1.1.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",hashes = {sha256 = "1db5d7ae38ff20153d542460752ff397fcf5c96090c1230803713cf3147a6803"}}, - {name = "watchfiles-1.1.1-cp312-cp312-musllinux_1_1_aarch64.whl",url = "https://files.pythonhosted.org/packages/66/ab/3cbb8756323e8f9b6f9acb9ef4ec26d42b2109bce830cc1f3468df20511d/watchfiles-1.1.1-cp312-cp312-musllinux_1_1_aarch64.whl",hashes = {sha256 = "28475ddbde92df1874b6c5c8aaeb24ad5be47a11f87cde5a28ef3835932e3e94"}}, - {name = "watchfiles-1.1.1-cp312-cp312-musllinux_1_1_x86_64.whl",url = "https://files.pythonhosted.org/packages/78/46/7152ec29b8335f80167928944a94955015a345440f524d2dfe63fc2f437b/watchfiles-1.1.1-cp312-cp312-musllinux_1_1_x86_64.whl",hashes = {sha256 = "36193ed342f5b9842edd3532729a2ad55c4160ffcfa3700e0d54be496b70dd43"}}, - {name = "watchfiles-1.1.1-cp312-cp312-win32.whl",url = "https://files.pythonhosted.org/packages/0a/bf/95895e78dd75efe9a7f31733607f384b42eb5feb54bd2eb6ed57cc2e94f4/watchfiles-1.1.1-cp312-cp312-win32.whl",hashes = {sha256 = "859e43a1951717cc8de7f4c77674a6d389b106361585951d9e69572823f311d9"}}, - {name = "watchfiles-1.1.1-cp312-cp312-win_amd64.whl",url = "https://files.pythonhosted.org/packages/87/0a/90eb755f568de2688cb220171c4191df932232c20946966c27a59c400850/watchfiles-1.1.1-cp312-cp312-win_amd64.whl",hashes = {sha256 = "91d4c9a823a8c987cce8fa2690923b069966dabb196dd8d137ea2cede885fde9"}}, - {name = "watchfiles-1.1.1-cp312-cp312-win_arm64.whl",url = "https://files.pythonhosted.org/packages/36/76/f322701530586922fbd6723c4f91ace21364924822a8772c549483abed13/watchfiles-1.1.1-cp312-cp312-win_arm64.whl",hashes = {sha256 = "a625815d4a2bdca61953dbba5a39d60164451ef34c88d751f6c368c3ea73d404"}}, - {name = "watchfiles-1.1.1-cp311-cp311-macosx_10_12_x86_64.whl",url = "https://files.pythonhosted.org/packages/1f/f8/2c5f479fb531ce2f0564eda479faecf253d886b1ab3630a39b7bf7362d46/watchfiles-1.1.1-cp311-cp311-macosx_10_12_x86_64.whl",hashes = {sha256 = "f57b396167a2565a4e8b5e56a5a1c537571733992b226f4f1197d79e94cf0ae5"}}, - {name = "watchfiles-1.1.1-cp311-cp311-macosx_11_0_arm64.whl",url = "https://files.pythonhosted.org/packages/fe/cd/f515660b1f32f65df671ddf6f85bfaca621aee177712874dc30a97397977/watchfiles-1.1.1-cp311-cp311-macosx_11_0_arm64.whl",hashes = {sha256 = "421e29339983e1bebc281fab40d812742268ad057db4aee8c4d2bce0af43b741"}}, - {name = "watchfiles-1.1.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl",url = "https://files.pythonhosted.org/packages/7b/c3/28b7dc99733eab43fca2d10f55c86e03bd6ab11ca31b802abac26b23d161/watchfiles-1.1.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl",hashes = {sha256 = "6e43d39a741e972bab5d8100b5cdacf69db64e34eb19b6e9af162bccf63c5cc6"}}, - {name = "watchfiles-1.1.1-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl",url = "https://files.pythonhosted.org/packages/4a/24/33e71113b320030011c8e4316ccca04194bf0cbbaeee207f00cbc7d6b9f5/watchfiles-1.1.1-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl",hashes = {sha256 = "f537afb3276d12814082a2e9b242bdcf416c2e8fd9f799a737990a1dbe906e5b"}}, - {name = "watchfiles-1.1.1-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl",url = "https://files.pythonhosted.org/packages/f4/c3/3c9a55f255aa57b91579ae9e98c88704955fa9dac3e5614fb378291155df/watchfiles-1.1.1-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl",hashes = {sha256 = "b2cd9e04277e756a2e2d2543d65d1e2166d6fd4c9b183f8808634fda23f17b14"}}, - {name = "watchfiles-1.1.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl",url = "https://files.pythonhosted.org/packages/49/36/506447b73eb46c120169dc1717fe2eff07c234bb3232a7200b5f5bd816e9/watchfiles-1.1.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl",hashes = {sha256 = "5f3f58818dc0b07f7d9aa7fe9eb1037aecb9700e63e1f6acfed13e9fef648f5d"}}, - {name = "watchfiles-1.1.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl",url = "https://files.pythonhosted.org/packages/82/ab/5f39e752a9838ec4d52e9b87c1e80f1ee3ccdbe92e183c15b6577ab9de16/watchfiles-1.1.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl",hashes = {sha256 = "9bb9f66367023ae783551042d31b1d7fd422e8289eedd91f26754a66f44d5cff"}}, - {name = "watchfiles-1.1.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",url = "https://files.pythonhosted.org/packages/af/b9/a419292f05e302dea372fa7e6fda5178a92998411f8581b9830d28fb9edb/watchfiles-1.1.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",hashes = {sha256 = "aebfd0861a83e6c3d1110b78ad54704486555246e542be3e2bb94195eabb2606"}}, - {name = "watchfiles-1.1.1-cp311-cp311-musllinux_1_1_aarch64.whl",url = "https://files.pythonhosted.org/packages/b0/c3/d5932fd62bde1a30c36e10c409dc5d54506726f08cb3e1d8d0ba5e2bc8db/watchfiles-1.1.1-cp311-cp311-musllinux_1_1_aarch64.whl",hashes = {sha256 = "5fac835b4ab3c6487b5dbad78c4b3724e26bcc468e886f8ba8cc4306f68f6701"}}, - {name = "watchfiles-1.1.1-cp311-cp311-musllinux_1_1_x86_64.whl",url = "https://files.pythonhosted.org/packages/f7/77/16bddd9779fafb795f1a94319dc965209c5641db5bf1edbbccace6d1b3c0/watchfiles-1.1.1-cp311-cp311-musllinux_1_1_x86_64.whl",hashes = {sha256 = "399600947b170270e80134ac854e21b3ccdefa11a9529a3decc1327088180f10"}}, - {name = "watchfiles-1.1.1-cp311-cp311-win32.whl",url = "https://files.pythonhosted.org/packages/46/ef/f2ecb9a0f342b4bfad13a2787155c6ee7ce792140eac63a34676a2feeef2/watchfiles-1.1.1-cp311-cp311-win32.whl",hashes = {sha256 = "de6da501c883f58ad50db3a32ad397b09ad29865b5f26f64c24d3e3281685849"}}, - {name = "watchfiles-1.1.1-cp311-cp311-win_amd64.whl",url = "https://files.pythonhosted.org/packages/94/bc/f42d71125f19731ea435c3948cad148d31a64fccde3867e5ba4edee901f9/watchfiles-1.1.1-cp311-cp311-win_amd64.whl",hashes = {sha256 = "35c53bd62a0b885bf653ebf6b700d1bf05debb78ad9292cf2a942b23513dc4c4"}}, - {name = "watchfiles-1.1.1-cp311-cp311-win_arm64.whl",url = "https://files.pythonhosted.org/packages/57/c9/a30f897351f95bbbfb6abcadafbaca711ce1162f4db95fc908c98a9165f3/watchfiles-1.1.1-cp311-cp311-win_arm64.whl",hashes = {sha256 = "57ca5281a8b5e27593cb7d82c2ac927ad88a96ed406aa446f6344e4328208e9e"}}, - {name = "watchfiles-1.1.1-pp311-pypy311_pp73-macosx_10_12_x86_64.whl",url = "https://files.pythonhosted.org/packages/d3/8e/e500f8b0b77be4ff753ac94dc06b33d8f0d839377fee1b78e8c8d8f031bf/watchfiles-1.1.1-pp311-pypy311_pp73-macosx_10_12_x86_64.whl",hashes = {sha256 = "db476ab59b6765134de1d4fe96a1a9c96ddf091683599be0f26147ea1b2e4b88"}}, - {name = "watchfiles-1.1.1-pp311-pypy311_pp73-macosx_11_0_arm64.whl",url = "https://files.pythonhosted.org/packages/bd/95/615e72cd27b85b61eec764a5ca51bd94d40b5adea5ff47567d9ebc4d275a/watchfiles-1.1.1-pp311-pypy311_pp73-macosx_11_0_arm64.whl",hashes = {sha256 = "89eef07eee5e9d1fda06e38822ad167a044153457e6fd997f8a858ab7564a336"}}, - {name = "watchfiles-1.1.1-pp311-pypy311_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl",url = "https://files.pythonhosted.org/packages/c9/81/e7fe958ce8a7fb5c73cc9fb07f5aeaf755e6aa72498c57d760af760c91f8/watchfiles-1.1.1-pp311-pypy311_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl",hashes = {sha256 = "ce19e06cbda693e9e7686358af9cd6f5d61312ab8b00488bc36f5aabbaf77e24"}}, - {name = "watchfiles-1.1.1-pp311-pypy311_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",url = "https://files.pythonhosted.org/packages/6e/d4/ed38dd3b1767193de971e694aa544356e63353c33a85d948166b5ff58b9e/watchfiles-1.1.1-pp311-pypy311_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",hashes = {sha256 = "3e6f39af2eab0118338902798b5aa6664f46ff66bc0280de76fca67a7f262a49"}}, -] -marker = "\"docs\" in extras" - -[packages.tool.pdm] -dependencies = [ - "anyio>=3.0.0", -] - -[[packages]] -name = "wcwidth" -version = "0.6.0" -requires-python = ">=3.8" -sdist = {name = "wcwidth-0.6.0.tar.gz", url = "https://files.pythonhosted.org/packages/35/a2/8e3becb46433538a38726c948d3399905a4c7cabd0df578ede5dc51f0ec2/wcwidth-0.6.0.tar.gz", hashes = {sha256 = "cdc4e4262d6ef9a1a57e018384cbeb1208d8abbc64176027e2c2455c81313159"}} -wheels = [ - {name = "wcwidth-0.6.0-py3-none-any.whl",url = "https://files.pythonhosted.org/packages/68/5a/199c59e0a824a3db2b89c5d2dade7ab5f9624dbf6448dc291b46d5ec94d3/wcwidth-0.6.0-py3-none-any.whl",hashes = {sha256 = "1a3a1e510b553315f8e146c54764f4fb6264ffad731b3d78088cdb1478ffbdad"}}, -] -marker = "\"docs\" in extras" - -[packages.tool.pdm] -dependencies = [] - -[[packages]] -name = "webencodings" -version = "0.5.1" -sdist = {name = "webencodings-0.5.1.tar.gz", url = "https://files.pythonhosted.org/packages/0b/02/ae6ceac1baeda530866a85075641cec12989bd8d31af6d5ab4a3e8c92f47/webencodings-0.5.1.tar.gz", hashes = {sha256 = "b36a1c245f2d304965eb4e0a82848379241dc04b865afcc4aab16748587e1923"}} -wheels = [ - {name = "webencodings-0.5.1-py2.py3-none-any.whl",url = "https://files.pythonhosted.org/packages/f4/24/2a3e3df732393fed8b3ebf2ec078f05546de641fe1b667ee316ec1dcf3b7/webencodings-0.5.1-py2.py3-none-any.whl",hashes = {sha256 = "a0af1213f3c2226497a97e2b3aa01a7e4bee4f403f95be16fc9acd2947514a78"}}, -] -marker = "\"docs\" in extras" - -[packages.tool.pdm] -dependencies = [] - -[[packages]] -name = "websockets" -version = "16.0" -requires-python = ">=3.10" -sdist = {name = "websockets-16.0.tar.gz", url = "https://files.pythonhosted.org/packages/04/24/4b2031d72e840ce4c1ccb255f693b15c334757fc50023e4db9537080b8c4/websockets-16.0.tar.gz", hashes = {sha256 = "5f6261a5e56e8d5c42a4497b364ea24d94d9563e8fbd44e78ac40879c60179b5"}} -wheels = [ - {name = "websockets-16.0-cp314-cp314-macosx_10_15_universal2.whl",url = "https://files.pythonhosted.org/packages/f3/1d/e88022630271f5bd349ed82417136281931e558d628dd52c4d8621b4a0b2/websockets-16.0-cp314-cp314-macosx_10_15_universal2.whl",hashes = {sha256 = "8cc451a50f2aee53042ac52d2d053d08bf89bcb31ae799cb4487587661c038a0"}}, - {name = "websockets-16.0-cp314-cp314-macosx_10_15_x86_64.whl",url = "https://files.pythonhosted.org/packages/f2/78/e63be1bf0724eeb4616efb1ae1c9044f7c3953b7957799abb5915bffd38e/websockets-16.0-cp314-cp314-macosx_10_15_x86_64.whl",hashes = {sha256 = "daa3b6ff70a9241cf6c7fc9e949d41232d9d7d26fd3522b1ad2b4d62487e9904"}}, - {name = "websockets-16.0-cp314-cp314-macosx_11_0_arm64.whl",url = "https://files.pythonhosted.org/packages/bb/f4/d3c9220d818ee955ae390cf319a7c7a467beceb24f05ee7aaaa2414345ba/websockets-16.0-cp314-cp314-macosx_11_0_arm64.whl",hashes = {sha256 = "fd3cb4adb94a2a6e2b7c0d8d05cb94e6f1c81a0cf9dc2694fb65c7e8d94c42e4"}}, - {name = "websockets-16.0-cp314-cp314-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl",url = "https://files.pythonhosted.org/packages/63/bc/d3e208028de777087e6fb2b122051a6ff7bbcca0d6df9d9c2bf1dd869ae9/websockets-16.0-cp314-cp314-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl",hashes = {sha256 = "781caf5e8eee67f663126490c2f96f40906594cb86b408a703630f95550a8c3e"}}, - {name = "websockets-16.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl",url = "https://files.pythonhosted.org/packages/ad/6e/9a0927ac24bd33a0a9af834d89e0abc7cfd8e13bed17a86407a66773cc0e/websockets-16.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl",hashes = {sha256 = "caab51a72c51973ca21fa8a18bd8165e1a0183f1ac7066a182ff27107b71e1a4"}}, - {name = "websockets-16.0-cp314-cp314-musllinux_1_2_aarch64.whl",url = "https://files.pythonhosted.org/packages/b9/ca/bf1c68440d7a868180e11be653c85959502efd3a709323230314fda6e0b3/websockets-16.0-cp314-cp314-musllinux_1_2_aarch64.whl",hashes = {sha256 = "19c4dc84098e523fd63711e563077d39e90ec6702aff4b5d9e344a60cb3c0cb1"}}, - {name = "websockets-16.0-cp314-cp314-musllinux_1_2_x86_64.whl",url = "https://files.pythonhosted.org/packages/c4/f8/fdc34643a989561f217bb477cbc47a3a07212cbda91c0e4389c43c296ebf/websockets-16.0-cp314-cp314-musllinux_1_2_x86_64.whl",hashes = {sha256 = "a5e18a238a2b2249c9a9235466b90e96ae4795672598a58772dd806edc7ac6d3"}}, - {name = "websockets-16.0-cp314-cp314-win32.whl",url = "https://files.pythonhosted.org/packages/dd/d1/574fa27e233764dbac9c52730d63fcf2823b16f0856b3329fc6268d6ae4f/websockets-16.0-cp314-cp314-win32.whl",hashes = {sha256 = "a069d734c4a043182729edd3e9f247c3b2a4035415a9172fd0f1b71658a320a8"}}, - {name = "websockets-16.0-cp314-cp314-win_amd64.whl",url = "https://files.pythonhosted.org/packages/8a/f1/ae6b937bf3126b5134ce1f482365fde31a357c784ac51852978768b5eff4/websockets-16.0-cp314-cp314-win_amd64.whl",hashes = {sha256 = "c0ee0e63f23914732c6d7e0cce24915c48f3f1512ec1d079ed01fc629dab269d"}}, - {name = "websockets-16.0-cp314-cp314t-macosx_10_15_universal2.whl",url = "https://files.pythonhosted.org/packages/06/9b/f791d1db48403e1f0a27577a6beb37afae94254a8c6f08be4a23e4930bc0/websockets-16.0-cp314-cp314t-macosx_10_15_universal2.whl",hashes = {sha256 = "a35539cacc3febb22b8f4d4a99cc79b104226a756aa7400adc722e83b0d03244"}}, - {name = "websockets-16.0-cp314-cp314t-macosx_10_15_x86_64.whl",url = "https://files.pythonhosted.org/packages/bd/40/53ad02341fa33b3ce489023f635367a4ac98b73570102ad2cdd770dacc9a/websockets-16.0-cp314-cp314t-macosx_10_15_x86_64.whl",hashes = {sha256 = "b784ca5de850f4ce93ec85d3269d24d4c82f22b7212023c974c401d4980ebc5e"}}, - {name = "websockets-16.0-cp314-cp314t-macosx_11_0_arm64.whl",url = "https://files.pythonhosted.org/packages/74/9b/6158d4e459b984f949dcbbb0c5d270154c7618e11c01029b9bbd1bb4c4f9/websockets-16.0-cp314-cp314t-macosx_11_0_arm64.whl",hashes = {sha256 = "569d01a4e7fba956c5ae4fc988f0d4e187900f5497ce46339c996dbf24f17641"}}, - {name = "websockets-16.0-cp314-cp314t-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl",url = "https://files.pythonhosted.org/packages/e5/2d/7583b30208b639c8090206f95073646c2c9ffd66f44df967981a64f849ad/websockets-16.0-cp314-cp314t-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl",hashes = {sha256 = "50f23cdd8343b984957e4077839841146f67a3d31ab0d00e6b824e74c5b2f6e8"}}, - {name = "websockets-16.0-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl",url = "https://files.pythonhosted.org/packages/45/b0/cce3784eb519b7b5ad680d14b9673a31ab8dcb7aad8b64d81709d2430aa8/websockets-16.0-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl",hashes = {sha256 = "152284a83a00c59b759697b7f9e9cddf4e3c7861dd0d964b472b70f78f89e80e"}}, - {name = "websockets-16.0-cp314-cp314t-musllinux_1_2_aarch64.whl",url = "https://files.pythonhosted.org/packages/19/60/b8ebe4c7e89fb5f6cdf080623c9d92789a53636950f7abacfc33fe2b3135/websockets-16.0-cp314-cp314t-musllinux_1_2_aarch64.whl",hashes = {sha256 = "bc59589ab64b0022385f429b94697348a6a234e8ce22544e3681b2e9331b5944"}}, - {name = "websockets-16.0-cp314-cp314t-musllinux_1_2_x86_64.whl",url = "https://files.pythonhosted.org/packages/88/a8/a080593f89b0138b6cba1b28f8df5673b5506f72879322288b031337c0b8/websockets-16.0-cp314-cp314t-musllinux_1_2_x86_64.whl",hashes = {sha256 = "32da954ffa2814258030e5a57bc73a3635463238e797c7375dc8091327434206"}}, - {name = "websockets-16.0-cp314-cp314t-win32.whl",url = "https://files.pythonhosted.org/packages/c2/b6/b9afed2afadddaf5ebb2afa801abf4b0868f42f8539bfe4b071b5266c9fe/websockets-16.0-cp314-cp314t-win32.whl",hashes = {sha256 = "5a4b4cc550cb665dd8a47f868c8d04c8230f857363ad3c9caf7a0c3bf8c61ca6"}}, - {name = "websockets-16.0-cp314-cp314t-win_amd64.whl",url = "https://files.pythonhosted.org/packages/9f/3e/28135a24e384493fa804216b79a6a6759a38cc4ff59118787b9fb693df93/websockets-16.0-cp314-cp314t-win_amd64.whl",hashes = {sha256 = "b14dc141ed6d2dde437cddb216004bcac6a1df0935d79656387bd41632ba0bbd"}}, - {name = "websockets-16.0-cp313-cp313-macosx_10_13_universal2.whl",url = "https://files.pythonhosted.org/packages/cc/9c/baa8456050d1c1b08dd0ec7346026668cbc6f145ab4e314d707bb845bf0d/websockets-16.0-cp313-cp313-macosx_10_13_universal2.whl",hashes = {sha256 = "878b336ac47938b474c8f982ac2f7266a540adc3fa4ad74ae96fea9823a02cc9"}}, - {name = "websockets-16.0-cp313-cp313-macosx_10_13_x86_64.whl",url = "https://files.pythonhosted.org/packages/7e/0c/8811fc53e9bcff68fe7de2bcbe75116a8d959ac699a3200f4847a8925210/websockets-16.0-cp313-cp313-macosx_10_13_x86_64.whl",hashes = {sha256 = "52a0fec0e6c8d9a784c2c78276a48a2bdf099e4ccc2a4cad53b27718dbfd0230"}}, - {name = "websockets-16.0-cp313-cp313-macosx_11_0_arm64.whl",url = "https://files.pythonhosted.org/packages/aa/82/39a5f910cb99ec0b59e482971238c845af9220d3ab9fa76dd9162cda9d62/websockets-16.0-cp313-cp313-macosx_11_0_arm64.whl",hashes = {sha256 = "e6578ed5b6981005df1860a56e3617f14a6c307e6a71b4fff8c48fdc50f3ed2c"}}, - {name = "websockets-16.0-cp313-cp313-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl",url = "https://files.pythonhosted.org/packages/bd/28/0a25ee5342eb5d5f297d992a77e56892ecb65e7854c7898fb7d35e9b33bd/websockets-16.0-cp313-cp313-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl",hashes = {sha256 = "95724e638f0f9c350bb1c2b0a7ad0e83d9cc0c9259f3ea94e40d7b02a2179ae5"}}, - {name = "websockets-16.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl",url = "https://files.pythonhosted.org/packages/f9/66/27ea52741752f5107c2e41fda05e8395a682a1e11c4e592a809a90c6a506/websockets-16.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl",hashes = {sha256 = "c0204dc62a89dc9d50d682412c10b3542d748260d743500a85c13cd1ee4bde82"}}, - {name = "websockets-16.0-cp313-cp313-musllinux_1_2_aarch64.whl",url = "https://files.pythonhosted.org/packages/37/e5/8e32857371406a757816a2b471939d51c463509be73fa538216ea52b792a/websockets-16.0-cp313-cp313-musllinux_1_2_aarch64.whl",hashes = {sha256 = "52ac480f44d32970d66763115edea932f1c5b1312de36df06d6b219f6741eed8"}}, - {name = "websockets-16.0-cp313-cp313-musllinux_1_2_x86_64.whl",url = "https://files.pythonhosted.org/packages/9b/67/f926bac29882894669368dc73f4da900fcdf47955d0a0185d60103df5737/websockets-16.0-cp313-cp313-musllinux_1_2_x86_64.whl",hashes = {sha256 = "6e5a82b677f8f6f59e8dfc34ec06ca6b5b48bc4fcda346acd093694cc2c24d8f"}}, - {name = "websockets-16.0-cp313-cp313-win32.whl",url = "https://files.pythonhosted.org/packages/3c/a1/3d6ccdcd125b0a42a311bcd15a7f705d688f73b2a22d8cf1c0875d35d34a/websockets-16.0-cp313-cp313-win32.whl",hashes = {sha256 = "abf050a199613f64c886ea10f38b47770a65154dc37181bfaff70c160f45315a"}}, - {name = "websockets-16.0-cp313-cp313-win_amd64.whl",url = "https://files.pythonhosted.org/packages/6b/ae/90366304d7c2ce80f9b826096a9e9048b4bb760e44d3b873bb272cba696b/websockets-16.0-cp313-cp313-win_amd64.whl",hashes = {sha256 = "3425ac5cf448801335d6fdc7ae1eb22072055417a96cc6b31b3861f455fbc156"}}, - {name = "websockets-16.0-cp312-cp312-macosx_10_13_universal2.whl",url = "https://files.pythonhosted.org/packages/84/7b/bac442e6b96c9d25092695578dda82403c77936104b5682307bd4deb1ad4/websockets-16.0-cp312-cp312-macosx_10_13_universal2.whl",hashes = {sha256 = "71c989cbf3254fbd5e84d3bff31e4da39c43f884e64f2551d14bb3c186230f00"}}, - {name = "websockets-16.0-cp312-cp312-macosx_10_13_x86_64.whl",url = "https://files.pythonhosted.org/packages/b0/fe/136ccece61bd690d9c1f715baaeefd953bb2360134de73519d5df19d29ca/websockets-16.0-cp312-cp312-macosx_10_13_x86_64.whl",hashes = {sha256 = "8b6e209ffee39ff1b6d0fa7bfef6de950c60dfb91b8fcead17da4ee539121a79"}}, - {name = "websockets-16.0-cp312-cp312-macosx_11_0_arm64.whl",url = "https://files.pythonhosted.org/packages/40/1e/9771421ac2286eaab95b8575b0cb701ae3663abf8b5e1f64f1fd90d0a673/websockets-16.0-cp312-cp312-macosx_11_0_arm64.whl",hashes = {sha256 = "86890e837d61574c92a97496d590968b23c2ef0aeb8a9bc9421d174cd378ae39"}}, - {name = "websockets-16.0-cp312-cp312-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl",url = "https://files.pythonhosted.org/packages/18/29/71729b4671f21e1eaa5d6573031ab810ad2936c8175f03f97f3ff164c802/websockets-16.0-cp312-cp312-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl",hashes = {sha256 = "9b5aca38b67492ef518a8ab76851862488a478602229112c4b0d58d63a7a4d5c"}}, - {name = "websockets-16.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl",url = "https://files.pythonhosted.org/packages/97/bb/21c36b7dbbafc85d2d480cd65df02a1dc93bf76d97147605a8e27ff9409d/websockets-16.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl",hashes = {sha256 = "e0334872c0a37b606418ac52f6ab9cfd17317ac26365f7f65e203e2d0d0d359f"}}, - {name = "websockets-16.0-cp312-cp312-musllinux_1_2_aarch64.whl",url = "https://files.pythonhosted.org/packages/4a/34/9bf8df0c0cf88fa7bfe36678dc7b02970c9a7d5e065a3099292db87b1be2/websockets-16.0-cp312-cp312-musllinux_1_2_aarch64.whl",hashes = {sha256 = "a0b31e0b424cc6b5a04b8838bbaec1688834b2383256688cf47eb97412531da1"}}, - {name = "websockets-16.0-cp312-cp312-musllinux_1_2_x86_64.whl",url = "https://files.pythonhosted.org/packages/47/88/4dd516068e1a3d6ab3c7c183288404cd424a9a02d585efbac226cb61ff2d/websockets-16.0-cp312-cp312-musllinux_1_2_x86_64.whl",hashes = {sha256 = "485c49116d0af10ac698623c513c1cc01c9446c058a4e61e3bf6c19dff7335a2"}}, - {name = "websockets-16.0-cp312-cp312-win32.whl",url = "https://files.pythonhosted.org/packages/91/d6/7d4553ad4bf1c0421e1ebd4b18de5d9098383b5caa1d937b63df8d04b565/websockets-16.0-cp312-cp312-win32.whl",hashes = {sha256 = "eaded469f5e5b7294e2bdca0ab06becb6756ea86894a47806456089298813c89"}}, - {name = "websockets-16.0-cp312-cp312-win_amd64.whl",url = "https://files.pythonhosted.org/packages/c3/f0/f3a17365441ed1c27f850a80b2bc680a0fa9505d733fe152fdf5e98c1c0b/websockets-16.0-cp312-cp312-win_amd64.whl",hashes = {sha256 = "5569417dc80977fc8c2d43a86f78e0a5a22fee17565d78621b6bb264a115d4ea"}}, - {name = "websockets-16.0-cp311-cp311-macosx_10_9_universal2.whl",url = "https://files.pythonhosted.org/packages/f2/db/de907251b4ff46ae804ad0409809504153b3f30984daf82a1d84a9875830/websockets-16.0-cp311-cp311-macosx_10_9_universal2.whl",hashes = {sha256 = "31a52addea25187bde0797a97d6fc3d2f92b6f72a9370792d65a6e84615ac8a8"}}, - {name = "websockets-16.0-cp311-cp311-macosx_10_9_x86_64.whl",url = "https://files.pythonhosted.org/packages/f3/fa/abe89019d8d8815c8781e90d697dec52523fb8ebe308bf11664e8de1877e/websockets-16.0-cp311-cp311-macosx_10_9_x86_64.whl",hashes = {sha256 = "417b28978cdccab24f46400586d128366313e8a96312e4b9362a4af504f3bbad"}}, - {name = "websockets-16.0-cp311-cp311-macosx_11_0_arm64.whl",url = "https://files.pythonhosted.org/packages/58/5d/88ea17ed1ded2079358b40d31d48abe90a73c9e5819dbcde1606e991e2ad/websockets-16.0-cp311-cp311-macosx_11_0_arm64.whl",hashes = {sha256 = "af80d74d4edfa3cb9ed973a0a5ba2b2a549371f8a741e0800cb07becdd20f23d"}}, - {name = "websockets-16.0-cp311-cp311-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl",url = "https://files.pythonhosted.org/packages/d2/ae/0ee92b33087a33632f37a635e11e1d99d429d3d323329675a6022312aac2/websockets-16.0-cp311-cp311-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl",hashes = {sha256 = "08d7af67b64d29823fed316505a89b86705f2b7981c07848fb5e3ea3020c1abe"}}, - {name = "websockets-16.0-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl",url = "https://files.pythonhosted.org/packages/c8/c5/27178df583b6c5b31b29f526ba2da5e2f864ecc79c99dae630a85d68c304/websockets-16.0-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl",hashes = {sha256 = "7be95cfb0a4dae143eaed2bcba8ac23f4892d8971311f1b06f3c6b78952ee70b"}}, - {name = "websockets-16.0-cp311-cp311-musllinux_1_2_aarch64.whl",url = "https://files.pythonhosted.org/packages/87/05/536652aa84ddc1c018dbb7e2c4cbcd0db884580bf8e95aece7593fde526f/websockets-16.0-cp311-cp311-musllinux_1_2_aarch64.whl",hashes = {sha256 = "d6297ce39ce5c2e6feb13c1a996a2ded3b6832155fcfc920265c76f24c7cceb5"}}, - {name = "websockets-16.0-cp311-cp311-musllinux_1_2_x86_64.whl",url = "https://files.pythonhosted.org/packages/6d/e2/d5332c90da12b1e01f06fb1b85c50cfc489783076547415bf9f0a659ec19/websockets-16.0-cp311-cp311-musllinux_1_2_x86_64.whl",hashes = {sha256 = "1c1b30e4f497b0b354057f3467f56244c603a79c0d1dafce1d16c283c25f6e64"}}, - {name = "websockets-16.0-cp311-cp311-win32.whl",url = "https://files.pythonhosted.org/packages/77/fb/d3f9576691cae9253b51555f841bc6600bf0a983a461c79500ace5a5b364/websockets-16.0-cp311-cp311-win32.whl",hashes = {sha256 = "5f451484aeb5cafee1ccf789b1b66f535409d038c56966d6101740c1614b86c6"}}, - {name = "websockets-16.0-cp311-cp311-win_amd64.whl",url = "https://files.pythonhosted.org/packages/54/67/eaff76b3dbaf18dcddabc3b8c1dba50b483761cccff67793897945b37408/websockets-16.0-cp311-cp311-win_amd64.whl",hashes = {sha256 = "8d7f0659570eefb578dacde98e24fb60af35350193e4f56e11190787bee77dac"}}, - {name = "websockets-16.0-pp311-pypy311_pp73-macosx_10_15_x86_64.whl",url = "https://files.pythonhosted.org/packages/72/07/c98a68571dcf256e74f1f816b8cc5eae6eb2d3d5cfa44d37f801619d9166/websockets-16.0-pp311-pypy311_pp73-macosx_10_15_x86_64.whl",hashes = {sha256 = "349f83cd6c9a415428ee1005cadb5c2c56f4389bc06a9af16103c3bc3dcc8b7d"}}, - {name = "websockets-16.0-pp311-pypy311_pp73-macosx_11_0_arm64.whl",url = "https://files.pythonhosted.org/packages/7e/52/93e166a81e0305b33fe416338be92ae863563fe7bce446b0f687b9df5aea/websockets-16.0-pp311-pypy311_pp73-macosx_11_0_arm64.whl",hashes = {sha256 = "4a1aba3340a8dca8db6eb5a7986157f52eb9e436b74813764241981ca4888f03"}}, - {name = "websockets-16.0-pp311-pypy311_pp73-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl",url = "https://files.pythonhosted.org/packages/56/0c/2dbf513bafd24889d33de2ff0368190a0e69f37bcfa19009ef819fe4d507/websockets-16.0-pp311-pypy311_pp73-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl",hashes = {sha256 = "f4a32d1bd841d4bcbffdcb3d2ce50c09c3909fbead375ab28d0181af89fd04da"}}, - {name = "websockets-16.0-pp311-pypy311_pp73-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl",url = "https://files.pythonhosted.org/packages/a5/8f/aea9c71cc92bf9b6cc0f7f70df8f0b420636b6c96ef4feee1e16f80f75dd/websockets-16.0-pp311-pypy311_pp73-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl",hashes = {sha256 = "0298d07ee155e2e9fda5be8a9042200dd2e3bb0b8a38482156576f863a9d457c"}}, - {name = "websockets-16.0-pp311-pypy311_pp73-win_amd64.whl",url = "https://files.pythonhosted.org/packages/9a/3f/f70e03f40ffc9a30d817eef7da1be72ee4956ba8d7255c399a01b135902a/websockets-16.0-pp311-pypy311_pp73-win_amd64.whl",hashes = {sha256 = "a653aea902e0324b52f1613332ddf50b00c06fdaf7e92624fbf8c77c78fa5767"}}, - {name = "websockets-16.0-py3-none-any.whl",url = "https://files.pythonhosted.org/packages/6f/28/258ebab549c2bf3e64d2b0217b973467394a9cea8c42f70418ca2c5d0d2e/websockets-16.0-py3-none-any.whl",hashes = {sha256 = "1637db62fad1dc833276dded54215f2c7fa46912301a24bd94d45d46a011ceec"}}, -] -marker = "\"docs\" in extras" - -[packages.tool.pdm] -dependencies = [] - -[[packages]] -name = "widgetsnbextension" -version = "4.0.15" -requires-python = ">=3.7" -sdist = {name = "widgetsnbextension-4.0.15.tar.gz", url = "https://files.pythonhosted.org/packages/bd/f4/c67440c7fb409a71b7404b7aefcd7569a9c0d6bd071299bf4198ae7a5d95/widgetsnbextension-4.0.15.tar.gz", hashes = {sha256 = "de8610639996f1567952d763a5a41af8af37f2575a41f9852a38f947eb82a3b9"}} -wheels = [ - {name = "widgetsnbextension-4.0.15-py3-none-any.whl",url = "https://files.pythonhosted.org/packages/3f/0e/fa3b193432cfc60c93b42f3be03365f5f909d2b3ea410295cf36df739e31/widgetsnbextension-4.0.15-py3-none-any.whl",hashes = {sha256 = "8156704e4346a571d9ce73b84bee86a29906c9abfd7223b7228a28899ccf3366"}}, -] -marker = "\"docs\" in extras" - -[packages.tool.pdm] -dependencies = [] - -[[packages]] -name = "wrapt" -version = "2.2.0rc3" -requires-python = ">=3.9" -sdist = {name = "wrapt-2.2.0rc3.tar.gz", url = "https://files.pythonhosted.org/packages/38/07/09130d19f55b839f8e9915600426b573f2c569c727af950b924b8b152c1c/wrapt-2.2.0rc3.tar.gz", hashes = {sha256 = "ed13b1a7fe884c566c5f43005275781995d0cf7df563893968a187c881755522"}} -wheels = [ - {name = "wrapt-2.2.0rc3-cp314-cp314-macosx_10_15_x86_64.whl",url = "https://files.pythonhosted.org/packages/0c/57/4f27842a4d8bf393e1466efed0072f78aaad00e5201cc8f514b9702ac629/wrapt-2.2.0rc3-cp314-cp314-macosx_10_15_x86_64.whl",hashes = {sha256 = "8d898c0004cd6ab95b3e00059ffe3ede6925fcaf7e2a9dcdb30eef3ddcc78372"}}, - {name = "wrapt-2.2.0rc3-cp314-cp314-macosx_11_0_arm64.whl",url = "https://files.pythonhosted.org/packages/75/15/b0a797ecfe80d1161fb7ea22ffd46bc0026ce0ff403bed47553c7fad3332/wrapt-2.2.0rc3-cp314-cp314-macosx_11_0_arm64.whl",hashes = {sha256 = "65b03d053ca24fa3ea5ed8d989133793754750d72ab4f4dc43f9d75f9149265c"}}, - {name = "wrapt-2.2.0rc3-cp314-cp314-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl",url = "https://files.pythonhosted.org/packages/67/7a/e8d1b5bac41c453b52756af1d4d07494216259f975e0ccfc9bfed4f596ff/wrapt-2.2.0rc3-cp314-cp314-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl",hashes = {sha256 = "990c5de27e6ef54d81554e44d4b4b46d7f9da9f336a8a94c25131c52f29477b3"}}, - {name = "wrapt-2.2.0rc3-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl",url = "https://files.pythonhosted.org/packages/dd/e3/1dc8e456209feae8ff33e92db1cbc922e9575b0fe8d273a4237a313e6a4d/wrapt-2.2.0rc3-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl",hashes = {sha256 = "91e8534d7400faca16ad963362c65c4b652c04a4c466dde3731711623ff37208"}}, - {name = "wrapt-2.2.0rc3-cp314-cp314-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl",url = "https://files.pythonhosted.org/packages/2e/b0/8b77a11aaf4fa137f832ed0c434dfe82945dfa32cabb77e32c808a04a990/wrapt-2.2.0rc3-cp314-cp314-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl",hashes = {sha256 = "c9ce8df6846080e5b98d692f44539fa0a55c53cd5ce155d1e0a5b2602fff3c3f"}}, - {name = "wrapt-2.2.0rc3-cp314-cp314-musllinux_1_2_aarch64.whl",url = "https://files.pythonhosted.org/packages/7e/cc/9ad5d4f831841bc584dca392b9e774f65b01e5a9765df30ab2d1213e4f27/wrapt-2.2.0rc3-cp314-cp314-musllinux_1_2_aarch64.whl",hashes = {sha256 = "df3215d229ef749b9f22583f65492babf665da43e69d032be5002bdb49ea1658"}}, - {name = "wrapt-2.2.0rc3-cp314-cp314-musllinux_1_2_riscv64.whl",url = "https://files.pythonhosted.org/packages/44/53/f39ecd0bcedf33b390b8ea9b57c0d71a447efa5d92d47537c3cedfb7d7df/wrapt-2.2.0rc3-cp314-cp314-musllinux_1_2_riscv64.whl",hashes = {sha256 = "cc44d18cce2978e495ed966191f286069c6b0b71c70023e3e40d41815ff23657"}}, - {name = "wrapt-2.2.0rc3-cp314-cp314-musllinux_1_2_x86_64.whl",url = "https://files.pythonhosted.org/packages/ec/69/de9fc0f01064c97a6adc6dec5c064862a9c249d4fe852e739c047d10e072/wrapt-2.2.0rc3-cp314-cp314-musllinux_1_2_x86_64.whl",hashes = {sha256 = "dd21c9d4bdc9e2415898bf4fa84d572099e6af3d973cda3d1ad8ec4bcf02ef07"}}, - {name = "wrapt-2.2.0rc3-cp314-cp314-win32.whl",url = "https://files.pythonhosted.org/packages/77/21/2ee00b66a703b3f4e03afa1ee896808f7c93870d55b29bf92e1fa8132880/wrapt-2.2.0rc3-cp314-cp314-win32.whl",hashes = {sha256 = "0de1071e6236945fec242cb3dcfc126df4cd97e9dc2cbab073958e43cb92689b"}}, - {name = "wrapt-2.2.0rc3-cp314-cp314-win_amd64.whl",url = "https://files.pythonhosted.org/packages/f1/ba/95c28d7df311bc7c0bbbf6a2ddd27e49cecb4116fb608ffef254008dc364/wrapt-2.2.0rc3-cp314-cp314-win_amd64.whl",hashes = {sha256 = "aa22a1c80cfedc34c4b2e008a16ed54135540346ae60a498f669fac254f07d70"}}, - {name = "wrapt-2.2.0rc3-cp314-cp314-win_arm64.whl",url = "https://files.pythonhosted.org/packages/38/ec/c9ea13f1d64b423cd5b7796285969f8d2302b4bfcbb9230a48db72fe26a9/wrapt-2.2.0rc3-cp314-cp314-win_arm64.whl",hashes = {sha256 = "60a5aa6ef766369732fdf4d7f9341de02bb45bfc65564c162719a5f21ae77106"}}, - {name = "wrapt-2.2.0rc3-cp314-cp314t-macosx_10_15_x86_64.whl",url = "https://files.pythonhosted.org/packages/07/74/d609a43264122759a806a1c13dc708905f68109f369902322c6720518cf5/wrapt-2.2.0rc3-cp314-cp314t-macosx_10_15_x86_64.whl",hashes = {sha256 = "a8e215eeaec45a5272cff9870cf3c02d9642b2baf0d05f435374e1eb113e37c7"}}, - {name = "wrapt-2.2.0rc3-cp314-cp314t-macosx_11_0_arm64.whl",url = "https://files.pythonhosted.org/packages/5f/b6/b409700e417478c18ced9ecdcdb9a4151903cb4fc46423deb13a2ecfcc14/wrapt-2.2.0rc3-cp314-cp314t-macosx_11_0_arm64.whl",hashes = {sha256 = "d0404ee67d0bf24f69ef741222e055e78a1f29d8dc25ad11b515a1e2d5a2c082"}}, - {name = "wrapt-2.2.0rc3-cp314-cp314t-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl",url = "https://files.pythonhosted.org/packages/f6/32/6a5e70ba41fbd308b1018366268e1834853acab876a3a15ff2b3be1a410e/wrapt-2.2.0rc3-cp314-cp314t-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl",hashes = {sha256 = "d9fe7df6f84287b2849fbb5ff3f6d82b5e90a9d77f25ef0c179cd5304e663d31"}}, - {name = "wrapt-2.2.0rc3-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl",url = "https://files.pythonhosted.org/packages/7d/2e/228a38c264be3b60eec508352f6beb2adce9a5528054a2c71da9115ee1ff/wrapt-2.2.0rc3-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl",hashes = {sha256 = "65f6565e2dc14e897bc1c3c7b40dd705443e8ab1dc1119cff2163487a0354d2e"}}, - {name = "wrapt-2.2.0rc3-cp314-cp314t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl",url = "https://files.pythonhosted.org/packages/dd/ea/96ce6f797a3a6b06a7d4b2633caac8e16c7425a1b6faa13d7a7062e3e026/wrapt-2.2.0rc3-cp314-cp314t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl",hashes = {sha256 = "d234a031d0cd30a58a58c54a2fc62e8c0ca4c8c08db79822c9823c4669ececab"}}, - {name = "wrapt-2.2.0rc3-cp314-cp314t-musllinux_1_2_aarch64.whl",url = "https://files.pythonhosted.org/packages/86/28/7bc00b27e50de403e2d64a1698b1a0ec6ad1aabc60ec97a0c40dbe2add54/wrapt-2.2.0rc3-cp314-cp314t-musllinux_1_2_aarch64.whl",hashes = {sha256 = "c57c2357ba8edb5731bc627636ae44fe8282132ed41fb3240dd8befb50990324"}}, - {name = "wrapt-2.2.0rc3-cp314-cp314t-musllinux_1_2_riscv64.whl",url = "https://files.pythonhosted.org/packages/fe/ac/0e176d41ad099d9ce9d8abb0783c206729771b634e2d8d2ae8c9137d4658/wrapt-2.2.0rc3-cp314-cp314t-musllinux_1_2_riscv64.whl",hashes = {sha256 = "f4dc124f1f893711a00fc953090afcbe2ff1ef37fa3c6bccf90556c49f0c6198"}}, - {name = "wrapt-2.2.0rc3-cp314-cp314t-musllinux_1_2_x86_64.whl",url = "https://files.pythonhosted.org/packages/52/c7/e3c9dae54305a1161e917912f8b65280eee716fde468384e91649c5fbaba/wrapt-2.2.0rc3-cp314-cp314t-musllinux_1_2_x86_64.whl",hashes = {sha256 = "c6aab1869ee1dbfcb19be9276f2464673c3f4bb3ee91ae32eb3726e51ffe5ebd"}}, - {name = "wrapt-2.2.0rc3-cp314-cp314t-win32.whl",url = "https://files.pythonhosted.org/packages/36/d4/05117de84485eaa26266ae8bcff33e3b2efd9d4c82298e30b01f4d8a91ba/wrapt-2.2.0rc3-cp314-cp314t-win32.whl",hashes = {sha256 = "db1e3a3884cc04cba171ef895ba9e1491fd21e45faaea86ad9fe3c7fee7fcf30"}}, - {name = "wrapt-2.2.0rc3-cp314-cp314t-win_amd64.whl",url = "https://files.pythonhosted.org/packages/0f/92/f2db8bdff5fa952b7b9ea443ee233dbbe03137f30e27ca5a34bfaa1206aa/wrapt-2.2.0rc3-cp314-cp314t-win_amd64.whl",hashes = {sha256 = "7ac0b3a0e13f8eedeb557304d5dfd4ba2d80408e9b595bc4c6e8ea385e3483a8"}}, - {name = "wrapt-2.2.0rc3-cp314-cp314t-win_arm64.whl",url = "https://files.pythonhosted.org/packages/ec/9f/1dc14a35e1d0e477dc74ed0ad95da8250b401803bb6a41529666c6d0988d/wrapt-2.2.0rc3-cp314-cp314t-win_arm64.whl",hashes = {sha256 = "f5f679a3a35dfe744f5a878d97e018e6051c3dafc55ccc8ed19f058e35896484"}}, - {name = "wrapt-2.2.0rc3-cp313-cp313-macosx_10_13_x86_64.whl",url = "https://files.pythonhosted.org/packages/05/30/26e0eca25e039803ec1881ce167a273475046ae60171cb96448db616df8a/wrapt-2.2.0rc3-cp313-cp313-macosx_10_13_x86_64.whl",hashes = {sha256 = "fd0d18c4cf1d807d1acead5a58f356c46b31b3caecccd92065ae58c7f043fbca"}}, - {name = "wrapt-2.2.0rc3-cp313-cp313-macosx_11_0_arm64.whl",url = "https://files.pythonhosted.org/packages/83/e2/93c16932428f58023cdcaa7eb6653a20d8fe4e24de668c98afadcdb1e234/wrapt-2.2.0rc3-cp313-cp313-macosx_11_0_arm64.whl",hashes = {sha256 = "7526e5fc731f4e1fefb617111f6071b2d4360c8fad19e937b2af6b1cb87c5653"}}, - {name = "wrapt-2.2.0rc3-cp313-cp313-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl",url = "https://files.pythonhosted.org/packages/26/10/3d92539ee2e475333aa62f0bb22fd521335ee3c52f293454a37510ce32ca/wrapt-2.2.0rc3-cp313-cp313-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl",hashes = {sha256 = "16f4eaf6112e10c6a77fac62763b7ea62db2b36c87ae5782e14a496d8c242d18"}}, - {name = "wrapt-2.2.0rc3-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl",url = "https://files.pythonhosted.org/packages/e7/29/a627cc823dac52b5448339a82664f0d3a7405f452e2d49ed0ce9da07fb5a/wrapt-2.2.0rc3-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl",hashes = {sha256 = "9c5665cdc7667579db641b200869eb81bcdd70f05e789799135c668b9fa6ab86"}}, - {name = "wrapt-2.2.0rc3-cp313-cp313-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl",url = "https://files.pythonhosted.org/packages/c4/3f/5ed1cf8228154dd80db5847239bc8f52cd3cb7135c5c558c891212ea9cb0/wrapt-2.2.0rc3-cp313-cp313-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl",hashes = {sha256 = "0eb8c176ba23ae1b75cd94851441737b9c1d5761d51912443436ae2ceb3490de"}}, - {name = "wrapt-2.2.0rc3-cp313-cp313-musllinux_1_2_aarch64.whl",url = "https://files.pythonhosted.org/packages/09/39/21abf3414bd51052edc24744d04c887d6dd4fa75746d860ae2fa001348b7/wrapt-2.2.0rc3-cp313-cp313-musllinux_1_2_aarch64.whl",hashes = {sha256 = "0174a7874b64bdd2e1f5aeb90b95bd35af2a70e9d2b4539abc12bb588ecd7e51"}}, - {name = "wrapt-2.2.0rc3-cp313-cp313-musllinux_1_2_riscv64.whl",url = "https://files.pythonhosted.org/packages/1f/35/a0be5b943e9a948839ed249d8e9f5fad87836c7d987c32bd01ff4be99c22/wrapt-2.2.0rc3-cp313-cp313-musllinux_1_2_riscv64.whl",hashes = {sha256 = "0d25acd07566df8e00c7ae87175ff74b1e20864c19afd943e51a9b9bed3f47dc"}}, - {name = "wrapt-2.2.0rc3-cp313-cp313-musllinux_1_2_x86_64.whl",url = "https://files.pythonhosted.org/packages/3b/14/83d268fdc932c204e399d5966c6db185f96458cb07096aef16bf809a922a/wrapt-2.2.0rc3-cp313-cp313-musllinux_1_2_x86_64.whl",hashes = {sha256 = "eb7f17a5d1438f7df4176b2ba9c0f157df564726385cb5b0778d815bf4b637c2"}}, - {name = "wrapt-2.2.0rc3-cp313-cp313-win32.whl",url = "https://files.pythonhosted.org/packages/03/eb/8ffb3fa781c0d407cea764a7e4ab69996494952337507005195cdcfe0c3d/wrapt-2.2.0rc3-cp313-cp313-win32.whl",hashes = {sha256 = "06df2cd319933ceba8e3274e95f34c7bee8496e9c73de74189a8dc57a3769af2"}}, - {name = "wrapt-2.2.0rc3-cp313-cp313-win_amd64.whl",url = "https://files.pythonhosted.org/packages/a9/20/253f33f0879c0c4e1945b71485e60d79f9c4d32ddfa25e866d8b97cac0fe/wrapt-2.2.0rc3-cp313-cp313-win_amd64.whl",hashes = {sha256 = "093c5f7882a55f08d26f491d97570c3bdc2cb551bc396971099df610c76aa517"}}, - {name = "wrapt-2.2.0rc3-cp313-cp313-win_arm64.whl",url = "https://files.pythonhosted.org/packages/d2/90/9fb671613be4bb1ebcde40c5d9b99a3adc10479c4955f5e68d0e251821e5/wrapt-2.2.0rc3-cp313-cp313-win_arm64.whl",hashes = {sha256 = "2de3813a0c45e72d27443ee72bad95a080c7964d7f0861e865641547c014429b"}}, - {name = "wrapt-2.2.0rc3-cp313-cp313t-macosx_10_13_x86_64.whl",url = "https://files.pythonhosted.org/packages/78/cb/6b25dbb0e249e2e471a0c0eebc55b1879dfdf70b5ad394533250663bd4e7/wrapt-2.2.0rc3-cp313-cp313t-macosx_10_13_x86_64.whl",hashes = {sha256 = "9991d25aac1bd21f5c79c599aa50ed2f5dfcb2283e270bf2f6989a89a587e411"}}, - {name = "wrapt-2.2.0rc3-cp313-cp313t-macosx_11_0_arm64.whl",url = "https://files.pythonhosted.org/packages/16/c2/0be1965f30e8979c950b7a7d1f738626e09301636cdf136f673496f0f523/wrapt-2.2.0rc3-cp313-cp313t-macosx_11_0_arm64.whl",hashes = {sha256 = "9aeef0adae70a896135f6d3f476d66a2e513c1e9aea79ede7ae5e3132e84af13"}}, - {name = "wrapt-2.2.0rc3-cp313-cp313t-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl",url = "https://files.pythonhosted.org/packages/a5/6f/0ab718d4cfa900d023e77795ded8d9b6e73e413e6520eeb09b17c57eecdb/wrapt-2.2.0rc3-cp313-cp313t-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl",hashes = {sha256 = "664f7a6afd694fb7f9aa6b6f1e172a0f63467a4e933cc6db500b222cad870844"}}, - {name = "wrapt-2.2.0rc3-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl",url = "https://files.pythonhosted.org/packages/6d/99/f8660f1884ce78b92f35ec49a790dc43b2207ff97f285be5ffa2a9f64980/wrapt-2.2.0rc3-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl",hashes = {sha256 = "e0c28c7dda874d1380a2e185528a9e7177879d24e49661a2c1e8f154c33613e4"}}, - {name = "wrapt-2.2.0rc3-cp313-cp313t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl",url = "https://files.pythonhosted.org/packages/4c/af/a62320bab40b41df3e1b80ca7d1f0d8b8b6da2268d064ca160f0143e95a9/wrapt-2.2.0rc3-cp313-cp313t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl",hashes = {sha256 = "d76fcc7e8b903e4cf461853a5e924b7f9a563595eb9048d7fa1fd6dbc9484fe6"}}, - {name = "wrapt-2.2.0rc3-cp313-cp313t-musllinux_1_2_aarch64.whl",url = "https://files.pythonhosted.org/packages/44/e1/c35ad67f1ed93e20d4e9f3067a82314eaa31cb4b7596b0b27fa39061a186/wrapt-2.2.0rc3-cp313-cp313t-musllinux_1_2_aarch64.whl",hashes = {sha256 = "512f86d21d9ffb5cfe0392f429c6184dabc2878ab19f0fc9b4bf745620ed8b0a"}}, - {name = "wrapt-2.2.0rc3-cp313-cp313t-musllinux_1_2_riscv64.whl",url = "https://files.pythonhosted.org/packages/be/ea/25bdf71827a8aa98cd713cb6da3463c79e2e5c55ce07316393d43b9c7eb2/wrapt-2.2.0rc3-cp313-cp313t-musllinux_1_2_riscv64.whl",hashes = {sha256 = "c90c7b8f5947f062bbf8f01110c41250d8e0aec89d0df977ebdcf29f143afaa4"}}, - {name = "wrapt-2.2.0rc3-cp313-cp313t-musllinux_1_2_x86_64.whl",url = "https://files.pythonhosted.org/packages/de/25/80b5ae1b93811fb61160db9aca676a2634967e895227ba9ce33e7f9a35da/wrapt-2.2.0rc3-cp313-cp313t-musllinux_1_2_x86_64.whl",hashes = {sha256 = "e09a1108f4d76548d1e3366435c762160e404661570276ca18f478b9f729eb8b"}}, - {name = "wrapt-2.2.0rc3-cp313-cp313t-win32.whl",url = "https://files.pythonhosted.org/packages/b4/77/e65b4361b652f11392a20be805ea5689e8167370e6874ac472b3cefaf068/wrapt-2.2.0rc3-cp313-cp313t-win32.whl",hashes = {sha256 = "b5e6b0efcba38ce327ff8547fb7d5c93170c6979692f758eecd7fb096691c22b"}}, - {name = "wrapt-2.2.0rc3-cp313-cp313t-win_amd64.whl",url = "https://files.pythonhosted.org/packages/d6/8d/9138d6401b7150c5f014446897adde112fbdbb03c2bf31b7609a5ec9f9e5/wrapt-2.2.0rc3-cp313-cp313t-win_amd64.whl",hashes = {sha256 = "b1fa573979b545558f419ce1489b34024aeeab64c0e2e1648fd055ebf2b2f37e"}}, - {name = "wrapt-2.2.0rc3-cp313-cp313t-win_arm64.whl",url = "https://files.pythonhosted.org/packages/6e/e7/50f4e9d187d6c1cac8c29e0c635cad9763f49eefc6da5da68ce155e26ef4/wrapt-2.2.0rc3-cp313-cp313t-win_arm64.whl",hashes = {sha256 = "bfd50e6dd9982a624ce0f4f21ebd4e8fa37e3664aba76eca321471041bd63b28"}}, - {name = "wrapt-2.2.0rc3-cp312-cp312-macosx_10_13_x86_64.whl",url = "https://files.pythonhosted.org/packages/f0/f1/3cd2112e119e3ea82947e1ab431299c239ef7cde58cc97884c9fecf67fbc/wrapt-2.2.0rc3-cp312-cp312-macosx_10_13_x86_64.whl",hashes = {sha256 = "d303a284255346a3603741e6b1fcb46864e3f27b211ce7cac20af0aa569f79e8"}}, - {name = "wrapt-2.2.0rc3-cp312-cp312-macosx_11_0_arm64.whl",url = "https://files.pythonhosted.org/packages/81/35/ab9f40d400ed0a2d39ed83e95f22242e0a29f5ce1de72a09792973f79a3f/wrapt-2.2.0rc3-cp312-cp312-macosx_11_0_arm64.whl",hashes = {sha256 = "f44139c54780b15bf9ad1a0e14a5d421fc5658f0f4bc3c3e50ed0960943b8aa1"}}, - {name = "wrapt-2.2.0rc3-cp312-cp312-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl",url = "https://files.pythonhosted.org/packages/5e/ba/f570b1d0c02ec19f4bbf39a8154dac676b484cc6f7f8cde42f333eb3bd6e/wrapt-2.2.0rc3-cp312-cp312-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl",hashes = {sha256 = "959ee73202b3780e1ff926314e81702c2231eae788d6316520b841a4f261486f"}}, - {name = "wrapt-2.2.0rc3-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl",url = "https://files.pythonhosted.org/packages/ce/6f/506eff0fdef6cb8bdb78ef3e29bd8984e467eb046a3d1190d9e15162fa71/wrapt-2.2.0rc3-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl",hashes = {sha256 = "405fa7fc28692799355faacf5ba1aa25bd37583ac8d29fbe10f39b494fe334ed"}}, - {name = "wrapt-2.2.0rc3-cp312-cp312-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl",url = "https://files.pythonhosted.org/packages/1a/38/bd221cefa1141836a07c9df21625359ddde7fc882342fc01c060e5f13947/wrapt-2.2.0rc3-cp312-cp312-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl",hashes = {sha256 = "f07d07f0f3d54fc2fa5f7a7364a123e607d41f87738636c622460faee6d384cb"}}, - {name = "wrapt-2.2.0rc3-cp312-cp312-musllinux_1_2_aarch64.whl",url = "https://files.pythonhosted.org/packages/e5/71/31794f781f738d131121a80fdbe62497cd5de8c9dc80c95e036b220a968f/wrapt-2.2.0rc3-cp312-cp312-musllinux_1_2_aarch64.whl",hashes = {sha256 = "402440b7714f6da36047a9f18282927c98c07158aa49c68f62a670e37e9b96c7"}}, - {name = "wrapt-2.2.0rc3-cp312-cp312-musllinux_1_2_riscv64.whl",url = "https://files.pythonhosted.org/packages/cd/56/eb662e32a91e25ccd76f83da167cde4b3d2d9c05602f277eec059f7217b6/wrapt-2.2.0rc3-cp312-cp312-musllinux_1_2_riscv64.whl",hashes = {sha256 = "3bd7c1dd9863a76e611ce95b4d3cf1c665de2e4c8f68430ba9990b8cba224e85"}}, - {name = "wrapt-2.2.0rc3-cp312-cp312-musllinux_1_2_x86_64.whl",url = "https://files.pythonhosted.org/packages/0d/5f/5e5769af8a73bce03afcab236aa3fc38522b09f74cdc1433afac6cde2f76/wrapt-2.2.0rc3-cp312-cp312-musllinux_1_2_x86_64.whl",hashes = {sha256 = "ce60034d4cc4ae2c61cdc63284963330efbb5a62cd674e19b0478fc0969a66f9"}}, - {name = "wrapt-2.2.0rc3-cp312-cp312-win32.whl",url = "https://files.pythonhosted.org/packages/e1/53/26f579e9eeaa57b90716a5830868ab185506a53fd4572c221a4a188f9c4e/wrapt-2.2.0rc3-cp312-cp312-win32.whl",hashes = {sha256 = "dfad8b093a8e63db4ab1aab6cdd885d75171e0c75dcac1f9d66acdd4a918b76d"}}, - {name = "wrapt-2.2.0rc3-cp312-cp312-win_amd64.whl",url = "https://files.pythonhosted.org/packages/4a/4a/edcfe15a929979efc3937cca26ce459b5db09abfa9e93eb79f2597c9c383/wrapt-2.2.0rc3-cp312-cp312-win_amd64.whl",hashes = {sha256 = "248591aeff15ba463f7888fcf3ce1b012508600d02f208ee2b6486ac270a5951"}}, - {name = "wrapt-2.2.0rc3-cp312-cp312-win_arm64.whl",url = "https://files.pythonhosted.org/packages/1a/de/d599cf92667e6d2b5985d576e2eb3c93c7ddf49d7f9e3bf4799768af6538/wrapt-2.2.0rc3-cp312-cp312-win_arm64.whl",hashes = {sha256 = "3204b133a0f83728546b0a4df0917e26abc96c59ee91a906fdcd65bd2ccb8cae"}}, - {name = "wrapt-2.2.0rc3-cp311-cp311-macosx_10_9_x86_64.whl",url = "https://files.pythonhosted.org/packages/88/db/c114873d0b28de13e9ecfc544fc28931d59c469b1217a08a8b5ad12fec39/wrapt-2.2.0rc3-cp311-cp311-macosx_10_9_x86_64.whl",hashes = {sha256 = "cf6c20d8e347b513d3843347b41b9f9a1b3a38877ebd124980d64e02841aff55"}}, - {name = "wrapt-2.2.0rc3-cp311-cp311-macosx_11_0_arm64.whl",url = "https://files.pythonhosted.org/packages/d7/f8/1657979ab5e0ef54c7cced88c05f05dad38340835ef44bb2842f26c271e3/wrapt-2.2.0rc3-cp311-cp311-macosx_11_0_arm64.whl",hashes = {sha256 = "0164ac2c37658f0a219db35c24dc0c20fe5f1a02afc34c5c75818181d489842e"}}, - {name = "wrapt-2.2.0rc3-cp311-cp311-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl",url = "https://files.pythonhosted.org/packages/e8/b6/6861418529338eba2b52034513916e45bb6170da23e295dd9ea19dfa45ba/wrapt-2.2.0rc3-cp311-cp311-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl",hashes = {sha256 = "5e9df9d7b66ea193265970d55d45869ef65d8711b9469ee588120444342bc580"}}, - {name = "wrapt-2.2.0rc3-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl",url = "https://files.pythonhosted.org/packages/e5/43/0d4d1efa5cd248e072155205962dee8c75b1b85e4fb6ec0ba80381332dc2/wrapt-2.2.0rc3-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl",hashes = {sha256 = "b2b5c1a53ac1beb52fb02274edebf3114533715820cc25c41640329e6250f0a6"}}, - {name = "wrapt-2.2.0rc3-cp311-cp311-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl",url = "https://files.pythonhosted.org/packages/de/25/84ef175fbf36b06624aa2853be5ecbf5083530784ac8e3bb3a3b164ec708/wrapt-2.2.0rc3-cp311-cp311-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl",hashes = {sha256 = "e11f2e170d9eddbf213627503af9178798ef9fc819e78c1e8d18927325418c26"}}, - {name = "wrapt-2.2.0rc3-cp311-cp311-musllinux_1_2_aarch64.whl",url = "https://files.pythonhosted.org/packages/1f/32/097debf07223beceb8391258ccc93d0109f39e0369e28659aa330093a1e4/wrapt-2.2.0rc3-cp311-cp311-musllinux_1_2_aarch64.whl",hashes = {sha256 = "0711a9985bf6340ec8d9314ed281629e281238873160803908574483fb2c1919"}}, - {name = "wrapt-2.2.0rc3-cp311-cp311-musllinux_1_2_riscv64.whl",url = "https://files.pythonhosted.org/packages/a9/c6/036dde151c8cbfde3a8908300c938149a022a1cd58ba008e696a45daeb16/wrapt-2.2.0rc3-cp311-cp311-musllinux_1_2_riscv64.whl",hashes = {sha256 = "bacee6c2f4df4920fa4728841a79c1021b9dbe623c35be4f7505ca09457cda61"}}, - {name = "wrapt-2.2.0rc3-cp311-cp311-musllinux_1_2_x86_64.whl",url = "https://files.pythonhosted.org/packages/5c/40/dd6d2b6fb9d05c2fdc727a6f48c15596a4c54f5eadc5f284b92d557224eb/wrapt-2.2.0rc3-cp311-cp311-musllinux_1_2_x86_64.whl",hashes = {sha256 = "97701673217c449df62b96d8a61db03a59c5719dd1f0d5367b16f9cb154581d6"}}, - {name = "wrapt-2.2.0rc3-cp311-cp311-win32.whl",url = "https://files.pythonhosted.org/packages/1a/5c/fb253482098e2c02558b818c8a38f11111734ec698250ca2dc5fcfe0e6b4/wrapt-2.2.0rc3-cp311-cp311-win32.whl",hashes = {sha256 = "9805e432eebd88420f7e874ead4d46e0ae99cb6993633dda8c1da961d67a6068"}}, - {name = "wrapt-2.2.0rc3-cp311-cp311-win_amd64.whl",url = "https://files.pythonhosted.org/packages/fc/1e/82be79da7e232055a6fce9d55ef56e0fadbc62572c9a28a2d0cd9c527de8/wrapt-2.2.0rc3-cp311-cp311-win_amd64.whl",hashes = {sha256 = "46fb5a9b3b5dcd886f1321102dc00a5baee959882ff37576ebc5b0f6b829e1b5"}}, - {name = "wrapt-2.2.0rc3-cp311-cp311-win_arm64.whl",url = "https://files.pythonhosted.org/packages/ff/cd/9331f2f077c64cd35e893dc10682d55c369c2cbba3c6e1c02e453d712710/wrapt-2.2.0rc3-cp311-cp311-win_arm64.whl",hashes = {sha256 = "736480d112c84531fa8ce58ae87184cec095ca875749da4041c5ee11e497e9dc"}}, - {name = "wrapt-2.2.0rc3-py3-none-any.whl",url = "https://files.pythonhosted.org/packages/7d/3a/9492c966cee45f466c47f67d61b9df6f3240ced9ec97c47ad1c87f758b02/wrapt-2.2.0rc3-py3-none-any.whl",hashes = {sha256 = "00f85862d333af74ce062cd785c39dabaa1bbe7c6fc27c9872b398261eeea2be"}}, -] -marker = "\"default\" in dependency_groups" - -[packages.tool.pdm] -dependencies = [] - -[tool.pdm] -hashes = {sha256 = "3c7d5baee0bc97d17be158f336000b85517a6a15d5b6df73eb88e8617745d48d"} - -[[tool.pdm.targets]] -requires_python = ">=3.11" diff --git a/pyproject.toml b/pyproject.toml index 168d507..ff4eba4 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -6,6 +6,9 @@ build-backend = "setuptools.build_meta" name = "isaricanalytics" dynamic = ["version"] description = "Data analysis toolkit to support fast analysis of clinical data during emerging infectious disease outbreaks." + +# Contributors list includes VERTEX contributors of the code migrated from +# VERTEX (`getREDCapData`, `IsaricAnalytics`, `IsaricDraw`) authors = [ { name = "Tom Edinburgh", email = "tom.edinburgh@ndm.ox.ac.uk" }, { name = "Esteban Garcia-Gallo", email = "esteban.garcia@ndm.ox.ac.uk" }, @@ -13,16 +16,40 @@ authors = [ { name = "Carlos Lima", email = "carlos.jlima@ufpe.br" }, { name = "Tomoe Gusberti", email = "tomoegusberti@gmail.com" }, { name = "Luiz Raffaini", email = "lemraffaini@gmail.com" }, - { name = "Sandeep Murthy", email = "sandeep.murthy@ndm.ox.ac.uk" } ] + +maintainers = [ + { name = "Sandeep Murthy", email = "sandeep.murthy@ndm.ox.ac.uk" }, + { name = "Alasdair Wilson", email = "alasdair.wilson@dtc.ox.ac.uk" }, +] + readme = "README.md" keywords = [ "isaric", + "infectious-diseases", "disease-outbreaks", "clinical-data", "data-analysis", "data-analytics", ] + + +# Not strictly required as this isn't a public Python package, but still good +# to have. +classifiers = [ + "Environment :: Console", + "License :: OSI Approved :: MIT License", + "Programming Language :: Python :: 3", + "Programming Language :: Python :: 3.11", + "Programming Language :: Python :: 3.12", + "Programming Language :: Python :: 3.13", + "Programming Language :: Python :: 3.14", + "Development Status :: 5 - Production/Stable", + "Operating System :: POSIX :: Linux", + "Operating System :: MacOS", + "Operating System :: Microsoft :: Windows", +] + requires-python = ">=3.11" dependencies = [ "lifelines==0.30.0", @@ -31,14 +58,18 @@ dependencies = [ "plotly==6.1.1", "requests>=2.32.4", "scikit-learn==1.5.2", - "scipy==1.12.0", - "statsmodels==0.14.1", + "scipy>=1.12.0", + "statsmodels>=0.14.1", ] [project.optional-dependencies] +pre-commit = [ + "pre-commit", +] + test = [ - "pytest==8.4.2", - "pytest-cov==7.0.0" + "pytest>=8.4.2", + "pytest-cov>=7.0.0" ] docs = [ diff --git a/tests/unit/assets/conversion_table.csv b/tests/unit/assets/conversion_table.csv new file mode 100644 index 0000000..1dbf5c2 --- /dev/null +++ b/tests/unit/assets/conversion_table.csv @@ -0,0 +1,14 @@ +from_unit,to_unit,variable,variable_unit,conversion_factor,conversion_offset +umol/L,mg/dL,labs_creatinine,labs_creatinine_units,88.4,0 +mmol/L,mg/dL,labs_ureanitro,labs_ureanitro_units,0.357,0 +10^9/L,%,labs_neutrophil,labs_neutrophil_units,, +F,C,vital_highesttem,vital_highesttem_units,0.5556,-17.7778 +umol/L,mg/dL,labs_bilirubin,labs_bilirubin_units,17.1,0 +10^9/L,%,labs_lymphocyte,labs_lymphocyte_units,, +"Fraction, 0.21-1.0","%, 21-100",vital_fio2spo2,vital_fio2spo2_units,100.0,0 +mg,mmol/L,labs_lactate,labs_lactate_units,0.0555,0 +mEq/L,mmol/L,labs_hco3,labs_hco3_units,1.0,0 +L/L,%,labs_hematocrit,labs_hematocrit_units,100.0,0 +mg/dL,ng/mL,labs_tropi,labs_tropi_units,10000.0,0 +mmol/L,Not done,comor_hba1c,comor_hba1c_units,1.0,0 +g/L,g/dL,labs_haemo,labs_haemo_units,10.0,0 diff --git a/tests/unit/assets/countries.csv b/tests/unit/assets/countries.csv new file mode 100644 index 0000000..cc83a7a --- /dev/null +++ b/tests/unit/assets/countries.csv @@ -0,0 +1,219 @@ +Country,Code,Region,Income group +Aruba,ABW,Latin America & Caribbean,High income +Afghanistan,AFG,South Asia,Low income +Angola,AGO,Sub-Saharan Africa,Lower middle income +Albania,ALB,Europe & Central Asia,Upper middle income +Andorra,AND,Europe & Central Asia,High income +United Arab Emirates,ARE,Middle East & North Africa,High income +Argentina,ARG,Latin America & Caribbean,Upper middle income +Armenia,ARM,Europe & Central Asia,Upper middle income +American Samoa,ASM,East Asia & Pacific,High income +Antigua and Barbuda,ATG,Latin America & Caribbean,High income +Australia,AUS,East Asia & Pacific,High income +Austria,AUT,Europe & Central Asia,High income +Azerbaijan,AZE,Europe & Central Asia,Upper middle income +Burundi,BDI,Sub-Saharan Africa,Low income +Belgium,BEL,Europe & Central Asia,High income +Benin,BEN,Sub-Saharan Africa,Lower middle income +Burkina Faso,BFA,Sub-Saharan Africa,Low income +Bangladesh,BGD,South Asia,Lower middle income +Bulgaria,BGR,Europe & Central Asia,Upper middle income +Bahrain,BHR,Middle East & North Africa,High income +"Bahamas, The",BHS,Latin America & Caribbean,High income +Bosnia and Herzegovina,BIH,Europe & Central Asia,Upper middle income +Belarus,BLR,Europe & Central Asia,Upper middle income +Belize,BLZ,Latin America & Caribbean,Upper middle income +Bermuda,BMU,North America,High income +Bolivia,BOL,Latin America & Caribbean,Lower middle income +Brazil,BRA,Latin America & Caribbean,Upper middle income +Barbados,BRB,Latin America & Caribbean,High income +Brunei Darussalam,BRN,East Asia & Pacific,High income +Bhutan,BTN,South Asia,Lower middle income +Botswana,BWA,Sub-Saharan Africa,Upper middle income +Central African Republic,CAF,Sub-Saharan Africa,Low income +Canada,CAN,North America,High income +Switzerland,CHE,Europe & Central Asia,High income +Channel Islands,CHI,Europe & Central Asia,High income +Chile,CHL,Latin America & Caribbean,High income +China,CHN,East Asia & Pacific,Upper middle income +Côte d’Ivoire,CIV,Sub-Saharan Africa,Lower middle income +Cameroon,CMR,Sub-Saharan Africa,Lower middle income +"Congo, Dem. Rep.",COD,Sub-Saharan Africa,Low income +"Congo, Rep.",COG,Sub-Saharan Africa,Lower middle income +Colombia,COL,Latin America & Caribbean,Upper middle income +Comoros,COM,Sub-Saharan Africa,Lower middle income +Cabo Verde,CPV,Sub-Saharan Africa,Lower middle income +Costa Rica,CRI,Latin America & Caribbean,Upper middle income +Cuba,CUB,Latin America & Caribbean,Upper middle income +Curaçao,CUW,Latin America & Caribbean,High income +Cayman Islands,CYM,Latin America & Caribbean,High income +Cyprus,CYP,Europe & Central Asia,High income +Czechia,CZE,Europe & Central Asia,High income +Germany,DEU,Europe & Central Asia,High income +Djibouti,DJI,Middle East & North Africa,Lower middle income +Dominica,DMA,Latin America & Caribbean,Upper middle income +Denmark,DNK,Europe & Central Asia,High income +Dominican Republic,DOM,Latin America & Caribbean,Upper middle income +Algeria,DZA,Middle East & North Africa,Lower middle income +Ecuador,ECU,Latin America & Caribbean,Upper middle income +"Egypt, Arab Rep.",EGY,Middle East & North Africa,Lower middle income +Eritrea,ERI,Sub-Saharan Africa,Low income +Spain,ESP,Europe & Central Asia,High income +Estonia,EST,Europe & Central Asia,High income +Ethiopia,ETH,Sub-Saharan Africa,Low income +Finland,FIN,Europe & Central Asia,High income +Fiji,FJI,East Asia & Pacific,Upper middle income +France,FRA,Europe & Central Asia,High income +Faroe Islands,FRO,Europe & Central Asia,High income +"Micronesia, Fed. Sts.",FSM,East Asia & Pacific,Lower middle income +Gabon,GAB,Sub-Saharan Africa,Upper middle income +United Kingdom,GBR,Europe & Central Asia,High income +Georgia,GEO,Europe & Central Asia,Upper middle income +Ghana,GHA,Sub-Saharan Africa,Lower middle income +Gibraltar,GIB,Europe & Central Asia,High income +Guinea,GIN,Sub-Saharan Africa,Lower middle income +"Gambia, The",GMB,Sub-Saharan Africa,Low income +Guinea-Bissau,GNB,Sub-Saharan Africa,Low income +Equatorial Guinea,GNQ,Sub-Saharan Africa,Upper middle income +Greece,GRC,Europe & Central Asia,High income +Grenada,GRD,Latin America & Caribbean,Upper middle income +Greenland,GRL,Europe & Central Asia,High income +Guatemala,GTM,Latin America & Caribbean,Upper middle income +Guam,GUM,East Asia & Pacific,High income +Guyana,GUY,Latin America & Caribbean,High income +"Hong Kong SAR, China",HKG,East Asia & Pacific,High income +Honduras,HND,Latin America & Caribbean,Lower middle income +Croatia,HRV,Europe & Central Asia,High income +Haiti,HTI,Latin America & Caribbean,Lower middle income +Hungary,HUN,Europe & Central Asia,High income +Indonesia,IDN,East Asia & Pacific,Upper middle income +Isle of Man,IMN,Europe & Central Asia,High income +India,IND,South Asia,Lower middle income +Ireland,IRL,Europe & Central Asia,High income +"Iran, Islamic Rep.",IRN,Middle East & North Africa,Lower middle income +Iraq,IRQ,Middle East & North Africa,Upper middle income +Iceland,ISL,Europe & Central Asia,High income +Israel,ISR,Middle East & North Africa,High income +Italy,ITA,Europe & Central Asia,High income +Jamaica,JAM,Latin America & Caribbean,Upper middle income +Jordan,JOR,Middle East & North Africa,Lower middle income +Japan,JPN,East Asia & Pacific,High income +Kazakhstan,KAZ,Europe & Central Asia,Upper middle income +Kenya,KEN,Sub-Saharan Africa,Lower middle income +Kyrgyz Republic,KGZ,Europe & Central Asia,Lower middle income +Cambodia,KHM,East Asia & Pacific,Lower middle income +Kiribati,KIR,East Asia & Pacific,Lower middle income +St. Kitts and Nevis,KNA,Latin America & Caribbean,High income +"Korea, Rep.",KOR,East Asia & Pacific,High income +Kuwait,KWT,Middle East & North Africa,High income +Lao PDR,LAO,East Asia & Pacific,Lower middle income +Lebanon,LBN,Middle East & North Africa,Lower middle income +Liberia,LBR,Sub-Saharan Africa,Low income +Libya,LBY,Middle East & North Africa,Upper middle income +St. Lucia,LCA,Latin America & Caribbean,Upper middle income +Liechtenstein,LIE,Europe & Central Asia,High income +Sri Lanka,LKA,South Asia,Lower middle income +Lesotho,LSO,Sub-Saharan Africa,Lower middle income +Lithuania,LTU,Europe & Central Asia,High income +Luxembourg,LUX,Europe & Central Asia,High income +Latvia,LVA,Europe & Central Asia,High income +"Macao SAR, China",MAC,East Asia & Pacific,High income +St. Martin (French part),MAF,Latin America & Caribbean,High income +Morocco,MAR,Middle East & North Africa,Lower middle income +Monaco,MCO,Europe & Central Asia,High income +Moldova,MDA,Europe & Central Asia,Upper middle income +Madagascar,MDG,Sub-Saharan Africa,Low income +Maldives,MDV,South Asia,Upper middle income +Mexico,MEX,Latin America & Caribbean,Upper middle income +Marshall Islands,MHL,East Asia & Pacific,Upper middle income +North Macedonia,MKD,Europe & Central Asia,Upper middle income +Mali,MLI,Sub-Saharan Africa,Low income +Malta,MLT,Middle East & North Africa,High income +Myanmar,MMR,East Asia & Pacific,Lower middle income +Montenegro,MNE,Europe & Central Asia,Upper middle income +Mongolia,MNG,East Asia & Pacific,Lower middle income +Northern Mariana Islands,MNP,East Asia & Pacific,High income +Mozambique,MOZ,Sub-Saharan Africa,Low income +Mauritania,MRT,Sub-Saharan Africa,Lower middle income +Mauritius,MUS,Sub-Saharan Africa,Upper middle income +Malawi,MWI,Sub-Saharan Africa,Low income +Malaysia,MYS,East Asia & Pacific,Upper middle income +Namibia,NAM,Sub-Saharan Africa,Upper middle income +New Caledonia,NCL,East Asia & Pacific,High income +Niger,NER,Sub-Saharan Africa,Low income +Nigeria,NGA,Sub-Saharan Africa,Lower middle income +Nicaragua,NIC,Latin America & Caribbean,Lower middle income +Netherlands,NLD,Europe & Central Asia,High income +Norway,NOR,Europe & Central Asia,High income +Nepal,NPL,South Asia,Lower middle income +Nauru,NRU,East Asia & Pacific,High income +New Zealand,NZL,East Asia & Pacific,High income +Oman,OMN,Middle East & North Africa,High income +Pakistan,PAK,South Asia,Lower middle income +Panama,PAN,Latin America & Caribbean,High income +Peru,PER,Latin America & Caribbean,Upper middle income +Philippines,PHL,East Asia & Pacific,Lower middle income +Palau,PLW,East Asia & Pacific,Upper middle income +Papua New Guinea,PNG,East Asia & Pacific,Lower middle income +Poland,POL,Europe & Central Asia,High income +Puerto Rico,PRI,Latin America & Caribbean,High income +"Korea, Dem. People's Rep.",PRK,East Asia & Pacific,Low income +Portugal,PRT,Europe & Central Asia,High income +Paraguay,PRY,Latin America & Caribbean,Upper middle income +West Bank and Gaza,PSE,Middle East & North Africa,Upper middle income +French Polynesia,PYF,East Asia & Pacific,High income +Qatar,QAT,Middle East & North Africa,High income +Romania,ROU,Europe & Central Asia,High income +Russian Federation,RUS,Europe & Central Asia,Upper middle income +Rwanda,RWA,Sub-Saharan Africa,Low income +Saudi Arabia,SAU,Middle East & North Africa,High income +Sudan,SDN,Sub-Saharan Africa,Low income +Senegal,SEN,Sub-Saharan Africa,Lower middle income +Singapore,SGP,East Asia & Pacific,High income +Solomon Islands,SLB,East Asia & Pacific,Lower middle income +Sierra Leone,SLE,Sub-Saharan Africa,Low income +El Salvador,SLV,Latin America & Caribbean,Upper middle income +San Marino,SMR,Europe & Central Asia,High income +Somalia,SOM,Sub-Saharan Africa,Low income +Serbia,SRB,Europe & Central Asia,Upper middle income +South Sudan,SSD,Sub-Saharan Africa,Low income +São Tomé and Príncipe,STP,Sub-Saharan Africa,Lower middle income +Suriname,SUR,Latin America & Caribbean,Upper middle income +Slovak Republic,SVK,Europe & Central Asia,High income +Slovenia,SVN,Europe & Central Asia,High income +Sweden,SWE,Europe & Central Asia,High income +Eswatini,SWZ,Sub-Saharan Africa,Lower middle income +Sint Maarten (Dutch part),SXM,Latin America & Caribbean,High income +Seychelles,SYC,Sub-Saharan Africa,High income +Syrian Arab Republic,SYR,Middle East & North Africa,Low income +Turks and Caicos Islands,TCA,Latin America & Caribbean,High income +Chad,TCD,Sub-Saharan Africa,Low income +Togo,TGO,Sub-Saharan Africa,Low income +Thailand,THA,East Asia & Pacific,Upper middle income +Tajikistan,TJK,Europe & Central Asia,Lower middle income +Turkmenistan,TKM,Europe & Central Asia,Upper middle income +Timor-Leste,TLS,East Asia & Pacific,Lower middle income +Tonga,TON,East Asia & Pacific,Upper middle income +Trinidad and Tobago,TTO,Latin America & Caribbean,High income +Tunisia,TUN,Middle East & North Africa,Lower middle income +Türkiye,TUR,Europe & Central Asia,Upper middle income +Tuvalu,TUV,East Asia & Pacific,Upper middle income +"Taiwan, China",TWN,East Asia & Pacific,High income +Tanzania,TZA,Sub-Saharan Africa,Lower middle income +Uganda,UGA,Sub-Saharan Africa,Low income +Ukraine,UKR,Europe & Central Asia,Lower middle income +Uruguay,URY,Latin America & Caribbean,High income +United States,USA,North America,High income +Uzbekistan,UZB,Europe & Central Asia,Lower middle income +St. Vincent and the Grenadines,VCT,Latin America & Caribbean,Upper middle income +"Venezuela, RB",VEN,Latin America & Caribbean, +British Virgin Islands,VGB,Latin America & Caribbean,High income +Virgin Islands (U.S.),VIR,Latin America & Caribbean,High income +Vietnam,VNM,East Asia & Pacific,Lower middle income +Vanuatu,VUT,East Asia & Pacific,Lower middle income +Samoa,WSM,East Asia & Pacific,Lower middle income +Kosovo,XKX,Europe & Central Asia,Upper middle income +"Yemen, Rep.",YEM,Middle East & North Africa,Low income +South Africa,ZAF,Sub-Saharan Africa,Upper middle income +Zambia,ZMB,Sub-Saharan Africa,Lower middle income +Zimbabwe,ZWE,Sub-Saharan Africa,Lower middle income diff --git a/tests/unit/test_analytics.py b/tests/unit/test_analytics.py index f8a987c..4226f85 100644 --- a/tests/unit/test_analytics.py +++ b/tests/unit/test_analytics.py @@ -1,6 +1,6 @@ import pandas as pd -from isaricanalytics.IsaricAnalytics import ( +from isaricanalytics.analytics import ( convert_categorical_to_onehot, convert_onehot_to_categorical, from_timeA_to_timeB, diff --git a/tests/unit/test_redcap_data.py b/tests/unit/test_redcap_data.py new file mode 100644 index 0000000..9e07a8c --- /dev/null +++ b/tests/unit/test_redcap_data.py @@ -0,0 +1,90 @@ +# -- IMPORTS -- + +# -- Standard libraries -- +import unittest.mock as mock +from pathlib import Path + +# -- 3rd party libraries -- +import pandas as pd +from pandas.testing import assert_frame_equal + +# -- Internal libraries -- +from isaricanalytics.redcap_data import ( + load_countries_table, + load_units_conversion_table, +) + + +class TestLoadUnitsConversionTable: + def test_load_units_conversion_table__from_local_assets(self): + with Path(__file__).parent.parent.parent.joinpath( + "assets", "conversion_table.csv" + ) as local_assets_csv_path: + expected_table = pd.read_csv( + Path(__file__).parent.joinpath("assets", "conversion_table.csv") + ) + + with mock.patch( + "isaricanalytics.redcap_data.pd.read_csv", + mock.MagicMock(return_value=expected_table), + ) as mock_pd_read_csv: + received_table = load_units_conversion_table() + mock_pd_read_csv.assert_called_once_with(local_assets_csv_path) + assert_frame_equal(received_table, expected_table) + + def test_load_units_conversion_table__from_vertex_github(self): + with mock.patch( + "isaricanalytics.redcap_data.Path", side_effect=FileNotFoundError + ): + expected_table = pd.read_csv( + Path(__file__).parent.joinpath("assets", "conversion_table.csv") + ) + + with mock.patch( + "isaricanalytics.redcap_data.pd.read_csv", + mock.MagicMock(return_value=expected_table), + ) as mock_pd_read_csv: + received_table = load_units_conversion_table() + mock_pd_read_csv.assert_called_once_with( + "https://raw.githubusercontent.com/ISARICResearch/VERTEX/refs/heads/main/assets/conversion_table.csv" + ) + assert_frame_equal(received_table, expected_table) + + +class TestLoadCountriesTable: + def test_load_countries_table__from_local_assets(self): + local_assets_csv_path = Path(__file__).parent.parent.parent.joinpath( + "assets", "countries.csv" + ) + expected_table = pd.read_csv( + Path(__file__).parent.joinpath("assets", "countries.csv") + ) + + with mock.patch( + "isaricanalytics.redcap_data.pd.read_csv", + mock.MagicMock(return_value=expected_table), + ) as mock_pd_read_csv: + received_table = load_countries_table(encoding="latin-1") + mock_pd_read_csv.assert_called_once_with( + local_assets_csv_path, encoding="latin-1" + ) + assert_frame_equal(received_table, expected_table) + + def test_load_countries_table__from_vertex_github(self): + with mock.patch( + "isaricanalytics.redcap_data.Path", side_effect=FileNotFoundError + ): + expected_table = pd.read_csv( + Path(__file__).parent.joinpath("assets", "countries.csv") + ) + + with mock.patch( + "isaricanalytics.redcap_data.pd.read_csv", + mock.MagicMock(return_value=expected_table), + ) as mock_pd_read_csv: + received_table = load_countries_table(encoding="latin-1") + mock_pd_read_csv.assert_called_once_with( + "https://raw.githubusercontent.com/ISARICResearch/VERTEX/refs/heads/main/assets/countries.csv", + encoding="latin-1", + ) + assert_frame_equal(received_table, expected_table) diff --git a/tests/unit/test_utils.py b/tests/unit/test_utils.py new file mode 100644 index 0000000..8af465d --- /dev/null +++ b/tests/unit/test_utils.py @@ -0,0 +1,39 @@ +# -- IMPORTS -- + +# -- Standard libraries -- + +# -- 3rd party libraries -- +import pytest + +# -- Internal libraries -- +from isaricanalytics.utils import ( + strip_html, + strip_nonstandard_unicode_chars, +) + + +@pytest.mark.parametrize( + ("value", "expected"), + [ + (-1, -1), + (True, True), + ("Value", "Value"), + ("Value", "Value"), + ], +) +def test_strip_html(value, expected): + assert strip_html(value) == expected + + +@pytest.mark.parametrize( + ("value", "expected"), + [ + (-1, -1), + (True, True), + ("Value", "Value"), + ("Value", "Value"), + ("↳ Value", " Value"), + ], +) +def test_strip_nonstandard_unicode_chars(value, expected): + assert strip_nonstandard_unicode_chars(value) == expected diff --git a/tests/unit/test_visualisation.py b/tests/unit/test_visualisation.py new file mode 100644 index 0000000..056b7a6 --- /dev/null +++ b/tests/unit/test_visualisation.py @@ -0,0 +1,833 @@ +# -- IMPORTS -- + +# -- Standard libraries -- + +# -- 3rd party libraries -- +import pandas as pd +import plotly.graph_objs as go +import pytest +from numpy.testing import assert_array_equal + +# -- Internal libraries -- +from isaricanalytics.utils import strip_html +from isaricanalytics.visualisation import ( + fig_bar_chart, + fig_count_chart, + fig_dual_stack_pyramid, + fig_forest_plot, + fig_frequency_chart, + fig_kaplan_meier, + fig_pie, + fig_placeholder, + fig_sunburst, + fig_table, + fig_timelines, + hex_to_rgb, + hex_to_rgba, + rgb_to_rgba, +) + + +class TestFigBarChart: + def test_fig_bar_chart(self): + data_in = pd.DataFrame().assign( + time=["06:00", "09:00", "12:00", "15:00", "18:00", "21:00"], + temperature=[12.0, 15.5, 18.9, 20.2, 18.5, 15.8], + ) + fig_out = fig_bar_chart( + data_in, + title="Test bar chart - time vs temperature (Celsius)", + xlabel="Time of day", + ylabel="Temperature (Celsius)", + index_column="time", + height=340, + ) + + assert isinstance(fig_out, go.Figure) + assert ( + fig_out.layout.title.text + == "Test bar chart - time vs temperature (Celsius)" + ) + assert fig_out.layout.height == 340 + assert isinstance(fig_out.data[0], go._bar.Bar) + assert_array_equal(fig_out.data[0].x, data_in["time"].values) + assert_array_equal(fig_out.data[0].y, data_in["temperature"].values) + + +class TestFigCountChart: + def test_fig_count_chart(self): + data_in = pd.DataFrame().assign( + label=["Mathematics", "Economics", "Physics", "Physiology or Medicine"], + count=[2, 3, 2, 3], + short_label=[ + "Mathematics", + "Economics", + "Physics", + "Physiology or Medicine", + ], + ) + fig_out = fig_count_chart( + data_in, + title="Test count chart - students by major field", + xlabel="Count", + ylabel="Student Major Field", + height=350, + ) + + assert isinstance(fig_out, go.Figure) + assert fig_out.layout.title.text == "Test count chart - students by major field" + assert fig_out.layout.height == 350 + assert len(fig_out.data) == 4 + assert all(isinstance(data_item, go._bar.Bar) for data_item in fig_out.data) + + +class TestFigDualStackedPyramid: + def test_fig_dual_stack_pyramid(self): + # Test data taken from the dual stacked pyramid chart in the Dengue + # demo project with synthetic data. + data_in = pd.DataFrame( + columns=["side", "y_axis", "stack_group", "value", "left_side"], + data=[ + ["Female", "0-5", "Censored", 2, True], + ["Female", "0-5", "Death", 1, True], + ["Female", "0-5", "Discharged", 3, True], + ["Male", "0-5", "Death", 13, False], + ["Male", "0-5", "Censored", 18, False], + ["Male", "0-5", "Discharged", 12, False], + ["Male", "6-10", "Death", 5, False], + ["Male", "6-10", "Discharged", 2, False], + ["Male", "6-10", "Censored", 5, False], + ["Female", "6-10", "Censored", 3, True], + ["Female", "6-10", "Death", 1, True], + ["Male", "11-15", "Censored", 2, False], + ["Male", "11-15", "Death", 3, False], + ["Male", "16-20", "Death", 1, False], + ["Female", "16-20", "Censored", 1, True], + ["Female", "16-20", "Discharged", 1, True], + ["Female", "16-20", "Death", 1, True], + ["Male", "16-20", "Discharged", 1, False], + ["Male", "16-20", "Censored", 4, False], + ["Male", "21-25", "Death", 2, False], + ["Male", "21-25", "Censored", 1, False], + ["Female", "26-30", "Discharged", 1, True], + ["Male", "26-30", "Censored", 6, False], + ["Male", "26-30", "Discharged", 4, False], + ["Female", "26-30", "Censored", 1, True], + ["Male", "26-30", "Death", 2, False], + ["Male", "31-35", "Death", 2, False], + ["Male", "31-35", "Discharged", 3, False], + ["Male", "31-35", "Censored", 3, False], + ["Male", "36-40", "Discharged", 2, False], + ["Male", "36-40", "Death", 1, False], + ["Male", "36-40", "Censored", 4, False], + ["Female", "36-40", "Censored", 1, True], + ["Female", "36-40", "Death", 1, True], + ["Female", "36-40", "Discharged", 1, True], + ["Female", "41-45", "Censored", 1, True], + ["Male", "41-45", "Censored", 5, False], + ["Male", "41-45", "Death", 1, False], + ["Male", "41-45", "Discharged", 3, False], + ["Male", "46-50", "Censored", 5, False], + ["Male", "46-50", "Death", 4, False], + ["Male", "46-50", "Discharged", 4, False], + ["Female", "46-50", "Censored", 1, True], + ["Female", "51-55", "Censored", 1, True], + ["Male", "51-55", "Death", 1, False], + ["Male", "51-55", "Discharged", 2, False], + ["Male", "51-55", "Censored", 1, False], + ["Male", "56-60", "Death", 1, False], + ["Male", "56-60", "Discharged", 4, False], + ["Male", "56-60", "Censored", 3, False], + ["Female", "56-60", "Death", 1, True], + ["Female", "61-65", "Censored", 1, True], + ["Male", "61-65", "Discharged", 2, False], + ["Male", "61-65", "Death", 4, False], + ["Male", "61-65", "Censored", 5, False], + ["Male", "66-70", "Discharged", 2, False], + ["Male", "66-70", "Censored", 5, False], + ["Male", "66-70", "Death", 2, False], + ["Female", "66-70", "Discharged", 1, True], + ["Male", "71-75", "Discharged", 1, False], + ["Female", "71-75", "Death", 1, True], + ["Male", "71-75", "Censored", 3, False], + ["Male", "71-75", "Death", 1, False], + ["Male", "76-80", "Discharged", 1, False], + ["Male", "76-80", "Death", 1, False], + ["Male", "76-80", "Censored", 3, False], + ["Female", "76-80", "Censored", 1, True], + ["Male", "81-85", "Censored", 6, False], + ["Male", "81-85", "Death", 2, False], + ["Male", "81-85", "Discharged", 1, False], + ["Female", "81-85", "Death", 2, True], + ["Male", "86-90", "Death", 2, False], + ["Male", "86-90", "Censored", 7, False], + ["Male", "86-90", "Discharged", 2, False], + ["Male", "91-95", "Discharged", 1, False], + ["Male", "91-95", "Death", 2, False], + ["Female", "91-95", "Censored", 1, True], + ["Female", "91-95", "Death", 1, True], + ["Male", "91-95", "Censored", 3, False], + ["Male", "96-100", "Death", 2, False], + ["Male", "96-100", "Censored", 3, False], + ["Male", "96-100", "Discharged", 2, False], + ], + ) + fig_out = fig_dual_stack_pyramid( + data_in, + title=( + "Test dual-sided population pyramid chart - " + "showing age, sex and outcome" + ), + ylabel="Age Group", + base_color_map={ + "Discharged": "#00C26F", + "Censored": "#FFF500", + "Death": "#DF0069", + }, + height=430, + ) + + assert isinstance(fig_out, go.Figure) + assert ( + fig_out.layout.title.text + == "Test dual-sided population pyramid chart - showing age, sex and outcome" + ) + assert fig_out.layout.height == 430 + + # Bar charts for the no. of combinations of sex and outcome = 2 x 3 = 6 + assert len(fig_out.data) == 6 + assert all(isinstance(data_item, go._bar.Bar) for data_item in fig_out.data) + + +class TestFigForestPlot: + def test_fig_forest_plot(self): + data_in = pd.DataFrame( + columns=[ + "Variable", + "OddsRatio (multi)", + "LowerCI (multi)", + "UpperCI (multi)", + "p-value (multi)", + ], + data=[ + ["Sex at birth, Male", 1.949, 1.149, 3.307, 0.0134], + ["Age", 1.01, 0.998, 1.021, 0.1012], + [ + "Type of liver disease, Moderate or severe", + 0.584, + 0.183, + 1.864, + 0.3642, + ], + ["Obesity", 1.181, 0.679, 2.054, 0.555], + ["Hypertension (physician diagnosed)", 2.399, 1.431, 4.022, 0.0009], + [ + "Vaccinated for seasonal influenza (ever)", + 1.644, + 0.98, + 2.758, + 0.0594, + ], + ["Fever", 1.379, 0.766, 2.484, 0.2841], + ["Headache", 0.787, 0.469, 1.32, 0.3634], + [ + "Glasgow Coma Score (GCS / 15), Moderate (9 to 11)", + 1.801, + 0.96, + 3.38, + 0.0669, + ], + [ + "Glasgow Coma Score (GCS / 15), Severe (less than 9)", + 2.878, + 1.526, + 5.426, + 0.0011, + ], + ["Platelets (10^3/uL), Low (under 1.5)", 1.536, 0.706, 3.339, 0.2789], + ["Platelets (10^3/uL), High (over 4.5)", 4.741, 1.336, 16.829, 0.016], + ["Employed as a healthcare worker", 0.644, 0.309, 1.341, 0.2398], + ["Ever smoked", 1.53, 0.842, 2.781, 0.1631], + ["Diabetes mellitus", 2.174, 1.231, 3.838, 0.0074], + [ + "Stage of chronic kidney disease, Stage 1", + 1.607, + 0.427, + 6.048, + 0.4833, + ], + [ + "Stage of chronic kidney disease, Stage 2", + 0.627, + 0.194, + 2.021, + 0.4339, + ], + [ + "Stage of chronic kidney disease, Stage 3a", + 0.895, + 0.281, + 2.852, + 0.8507, + ], + [ + "Stage of chronic kidney disease, Stage 3b or 4 or 5", + 1.798, + 0.485, + 6.674, + 0.3803, + ], + ["Type of liver disease, Mild", 2.089, 0.975, 4.473, 0.058], + ], + ) + fig_out = fig_forest_plot( + data_in, + title="Test forest plot - anytime in-hospital mortality", + xlabel="Odds Ratio (95% CI)", + ylabel="", + labels=[ + "Variable", + "OddsRatio (multi)", + "LowerCI (multi)", + "UpperCI (multi)", + "p-value (multi)", + ], + height=600, + ) + + assert isinstance(fig_out, go.Figure) + assert ( + fig_out.layout.title.text + == "Test forest plot - anytime in-hospital mortality" + ) + assert fig_out.layout.xaxis.title.text == "Odds Ratio (95% CI)" + assert fig_out.layout.height == 600 + assert len(fig_out.data) == 21 + assert all( + isinstance(data_item, go._scatter.Scatter) for data_item in fig_out.data + ) + assert set(fig_out.data[0].x) == set(data_in["OddsRatio (multi)"]) + assert set(fig_out.data[0].y) == set(data_in["Variable"]) + + +class TestFigFrequencyChart: + def test_fig_frequency_chart(self): + data_in = pd.DataFrame().assign( + label=["Mathematics", "Economics", "Physics", "Physiology or Medicine"], + proportion=[0.3, 0.15, 0.1, 0.45], + short_label=[ + "Mathematics", + "Economics", + "Physics", + "Physiology or Medicine", + ], + ) + fig_out = fig_frequency_chart( + data_in, + title="Test frequency chart - student majors by field", + xlabel="Percentage", + ylabel="Student Major Field", + height=350, + ) + + assert isinstance(fig_out, go.Figure) + assert ( + fig_out.layout.title.text + == "Test frequency chart - student majors by field" + ) + assert fig_out.layout.height == 350 + assert len(fig_out.data) == 8 + assert all(isinstance(data_item, go._bar.Bar) for data_item in fig_out.data) + + +class TestFigKaplanMeier: + def test_fig_kaplan_meier(self): + km_data_in = pd.DataFrame( + columns=[ + "timeline", + "0-39", + "0-39_lower_0.95", + "0-39_upper_0.95", + "40-64", + "40-64_lower_0.95", + "40-64_upper_0.95", + ">64", + ">64_lower_0.95", + ">64_upper_0.95", + ], + data=[ + [0.0, 100.0, 100.0, 100.0, 100.0, 100.0, 100.0, 100.0, 100.0, 100.0], + [ + 3.0, + 98.18181818181826, + 96.39735054616156, + 99.08657016907878, + 99.55752212389378, + 96.90088134700424, + 99.93755232321789, + 98.81889763779525, + 96.38311787603637, + 99.61753753722978, + ], + [ + 4.0, + 98.18181818181826, + 96.39735054616156, + 99.08657016907878, + 98.89820078532492, + 95.54952547737416, + 99.73073978542168, + 98.81889763779525, + 96.38311787603637, + 99.61753753722978, + ], + [ + 5.0, + 95.36768963520568, + 92.60698242810584, + 97.11347866289374, + 98.89820078532492, + 95.54952547737416, + 99.73073978542168, + 98.81889763779525, + 96.38311787603637, + 99.61753753722978, + ], + [ + 6.0, + 94.42810648609036, + 91.27618131269512, + 96.46318369215324, + 97.999126232731, + 93.65495711588476, + 99.37876135264092, + 97.948246557286, + 95.13505854819972, + 99.14196321338244, + ], + [ + 7.0, + 91.84103507551256, + 87.53090853993217, + 94.7060430396404, + 96.7096640454582, + 90.86213734535134, + 98.8386876127919, + 94.94983084634872, + 91.034097752017, + 97.18164888548608, + ], + [ + 8.0, + 84.61758287856217, + 77.37293717865721, + 89.6953188510786, + 92.59435919245998, + 82.6454677155429, + 96.94188674506084, + 90.42841032985592, + 85.10140816062759, + 93.91813320008492, + ], + [ + 9.0, + 76.15582459070596, + 65.80771668823222, + 83.75137248761123, + 89.16493848162813, + 75.70020536177844, + 95.385530380624, + 87.01601748721983, + 80.64628925994477, + 91.3999519629908, + ], + [ + 10.0, + 66.22245616583126, + 51.45905617744299, + 77.43915318100328, + 72.44651251632285, + 48.96117462409049, + 86.46098576504949, + 82.3751632212348, + 74.49383017790512, + 88.01469585065641, + ], + [ + 11.0, + 52.97796493266499, + 32.231842991966055, + 70.01448228633087, + 63.39069845178251, + 36.1082330026806, + 81.54643352355325, + 77.11717407945385, + 67.23047069641812, + 84.36189542328422, + ], + [ + 12.0, + None, + None, + None, + None, + None, + None, + 69.13953538157931, + 56.100461856710325, + 79.0082809666679, + ], + [ + 13.0, + None, + None, + None, + None, + None, + None, + 61.00547239551115, + 44.7978150272324, + 73.77461192167068, + ], + [ + 14.0, + None, + None, + None, + None, + None, + None, + 47.44870075206421, + 26.8197019105621, + 65.55170703215035, + ], + [ + 15.0, + None, + None, + None, + None, + None, + None, + 37.95896060165138, + 16.243468770788308, + 59.67418998689532, + ], + ], + ) + risktable_data_in = pd.DataFrame( + columns=["Group", "0", "5", "10", "15"], + data=[ + ["0-39", 512, 314, 23, 0], + ["40-64", 233, 151, 16, 0], + [">64", 255, 254, 75, 5], + ], + ) + + fig_out = fig_kaplan_meier( + (km_data_in, risktable_data_in), + title="Test Kaplan-Meier plot - in-hospital mortality", + xlabel="Time (days)", + ylabel="Survival Probability", + index_column="Group", + p_value=0.004799680324617032, + height=480, + ) + + assert isinstance(fig_out, go.Figure) + assert ( + fig_out.layout.annotations[0].text + == "Test Kaplan-Meier plot - in-hospital mortality" + ) + assert fig_out.layout.xaxis.title.text == "Time (days)" + assert fig_out.layout.yaxis.title.text == "Survival Probability" + assert fig_out.layout.height == 480 + + +class TestFigPie: + def test_fig_pie(self): + data_in = pd.DataFrame().assign( + country=["Country A", "Country B", "Country C", "Country D", "Country E"], + population=[10000000, 2000000, 5000000, 12000000, 1000000], + ) + fig_out = fig_pie( + data_in, + title="Test pie chart - countries and populations", + xlabel="", + ylabel="", + base_color_map={ + 10000000: "maroon", + 12000000: "red", + 1000000: "pink", + 2000000: "green", + 5000000: "yellow", + }, + names=data_in["country"], + values=data_in["population"], + height=450, + ) + + assert isinstance(fig_out, go.Figure) + assert fig_out.layout.title.text == "Test pie chart - countries and populations" + assert fig_out.layout.height == 450 + assert isinstance(fig_out.data[0], go._pie.Pie) + assert_array_equal(fig_out.data[0].labels, data_in["country"]) + assert_array_equal(fig_out.data[0].values, data_in["population"]) + + +class TestFigPlaceholder: + def test_fig_placeholder__no_data(self): + fig_out = fig_placeholder( + None, + title="Test placeholder scatter plot - no data", + xlabel="x", + ylabel="y", + height=450, + ) + + assert isinstance(fig_out, go.Figure) + assert fig_out.layout.title.text == "Test placeholder scatter plot - no data" + assert fig_out.layout.xaxis.title.text == "x" + assert fig_out.layout.yaxis.title.text == "y" + assert fig_out.layout.height == 450 + assert isinstance(fig_out.data[0], go._scatter.Scatter) + assert_array_equal(fig_out.data[0].x, [1, 2, 3, 4, 5]) + assert len(fig_out.data[0].y) == 5 + assert min(fig_out.data[0].y) >= 10 + assert max(fig_out.data[0].y) <= 15 + + def test_fig_placeholder__custom_data(self): + data_in = pd.DataFrame().assign(x=[1, 2, 3, 4, 5], y=[1, 4, 9, 16, 25]) + fig_out = fig_placeholder( + data_in, + title="Test placeholder scatter plot - custom data", + xlabel="x", + ylabel="y", + height=450, + ) + + assert isinstance(fig_out, go.Figure) + assert ( + fig_out.layout.title.text == "Test placeholder scatter plot - custom data" + ) + assert fig_out.layout.xaxis.title.text == "x" + assert fig_out.layout.yaxis.title.text == "y" + assert fig_out.layout.height == 450 + assert isinstance(fig_out.data[0], go._scatter.Scatter) + assert_array_equal(fig_out.data[0].x, data_in["x"]) + assert_array_equal(fig_out.data[0].y, data_in["y"]) + + +class TestFigSunburst: + def test_fig_sunburst(self): + data_in = pd.DataFrame().assign( + total_bill=[16.99, 10.34, 21.01, 23.68, 24.59], + tip=[1.01, 1.66, 3.50, 3.31, 3.61], + sex=["Female", "Male", "Male", "Male", "Female"], + smoker=["No", "No", "No", "No", "No"], + day=["Sun", "Sat", "Fri", "Fri", "Sun"], + occasion=["Dinner", "Lunch", "Drinks", "Drinks", "Dinner"], + ) + fig_out = fig_sunburst( + data_in, + title="Test sunburst chart - restaurant bills by day, occasion, sex", + path=["day", "occasion", "sex"], + values="total_bill", + height=430, + ) + + assert isinstance(fig_out, go.Figure) + assert ( + fig_out.layout.title.text + == "Test sunburst chart - restaurant bills by day, occasion, sex" + ) + assert fig_out.layout.height == 430 + assert isinstance(fig_out.data[0], go._sunburst.Sunburst) + + +class TestFigTable: + def test_fig_table(self): + data_in = pd.DataFrame().assign( + A=["A1", "A2", "A3", "A4", "A5"], + B=["B1", "B2", "B3", "B4", "B5"], + C=["C1", "C2", "C3", "C4", "C5"], + ) + fig_out = fig_table( + data_in, + table_key="test_table_key", + columnwidth=[0.1] * 3, + height=500, + ) + + assert isinstance(fig_out, go.Figure) + assert fig_out.layout.title.text == "test_table_key" + assert fig_out.layout.height == 500 + assert isinstance(fig_out.data[0], go._table.Table) + assert_array_equal( + [strip_html(val) for val in fig_out.data[0].header.values], + data_in.columns.tolist(), + ) + for i, col in zip([0, 1, 2], ["A", "B", "C"]): + assert_array_equal(fig_out.data[0].cells.values[i], data_in[col].values) + + +class TestFigText: + def test_fig_text(self): + data_in = pd.DataFrame( + "Test disclaimer text", columns=["paragraphs"], index=range(1) + ) + fig_out = fig_table( + data_in, + height=430, + ) + + assert isinstance(fig_out, go.Figure) + assert fig_out.layout.height == 430 + assert isinstance(fig_out.data[0], go._table.Table) + assert fig_out.data[0].cells.values[0][0] == "Test disclaimer text" + + +class TestFigTimelines: + def test_fig_timelines__no_size_col(self): + data_in = pd.DataFrame().assign( + task=["Phase A", "Phase B", "Phase C"], + start=["2026-01-01", "2026-03-05", "2026-02-20"], + end=["2026-02-28", "2026-04-15", "2026-05-30"], + ) + # One task per group, vice versa + fig_out = fig_timelines( + data_in, + title="Test timelines plot - job phases", + label_col="task", + group_col="task", + start_date="start", + end_date="end", + size_col=None, + height=500, + ) + + assert isinstance(fig_out, go.Figure) + assert fig_out.layout.title.text == "Test timelines plot - job phases" + assert all( + isinstance(data_item, go._scatter.Scatter) for data_item in fig_out.data + ) + assert_array_equal([t.legendgroup for t in fig_out.data], data_in["task"]) + assert all( + isinstance(data_item, go._scatter.Scatter) for data_item in fig_out.data + ) + for i, task in enumerate(data_in["task"]): + assert ( + str(fig_out.data[i].x[0].date()) + == data_in[data_in["task"] == task]["start"].at[i] + ) + assert ( + str(fig_out.data[i].x[1].date()) + == data_in[data_in["task"] == task]["end"].at[i] + ) + + def test_fig_timelines__size_col(self): + data_in = pd.DataFrame().assign( + task=["Phase A", "Phase B", "Phase C"], + start=["2026-01-01", "2026-03-05", "2026-02-20"], + end=["2026-02-28", "2026-04-15", "2026-05-30"], + line_width=[2, 2.5, 4], + ) + # One task per group, vice versa + fig_out = fig_timelines( + data_in, + title="Test timelines plot - job phases", + label_col="task", + group_col="task", + start_date="start", + end_date="end", + size_col="line_width", + height=500, + ) + + assert isinstance(fig_out, go.Figure) + assert fig_out.layout.title.text == "Test timelines plot - job phases" + assert all( + isinstance(data_item, go._scatter.Scatter) for data_item in fig_out.data + ) + assert_array_equal([t.legendgroup for t in fig_out.data], data_in["task"]) + assert all( + isinstance(data_item, go._scatter.Scatter) for data_item in fig_out.data + ) + for i, task in enumerate(data_in["task"]): + assert ( + str(fig_out.data[i].x[0].date()) + == data_in[data_in["task"] == task]["start"].at[i] + ) + assert ( + str(fig_out.data[i].x[1].date()) + == data_in[data_in["task"] == task]["end"].at[i] + ) + + +class TestHexToRgb: + @pytest.mark.parametrize( + """hex_color, + expected_rgb_color""", + [ + ( + "#000000", + (0, 0, 0), + ), + ( + "#ffffff", + (255, 255, 255), + ), + ( + "#092227", + (9, 34, 39), + ), + ( + "#d9384b", + (217, 56, 75), + ), + ], + ) + def test_hex_to_rgb(self, hex_color, expected_rgb_color): + assert hex_to_rgb(hex_color) == expected_rgb_color + + +class TestHexToRgba: + @pytest.mark.parametrize( + """hex_color, + opacity, + expected_rgba_string""", + [ + ( + "#000000", + 0.0, + "rgba(0, 0, 0, 0.0)", + ), + ( + "#092227", + 0.5, + "rgba(9, 34, 39, 0.5)", + ), + ( + "#ffffff", + 1.0, + "rgba(255, 255, 255, 1.0)", + ), + ], + ) + def test_hex_to_rgba(self, hex_color, opacity, expected_rgba_string): + assert hex_to_rgba(hex_color, opacity) == expected_rgba_string + + +class TestRgbToRgba: + @pytest.mark.parametrize( + """rgb_color, + alpha, + expected_rgba_string""", + [ + ((0, 0, 0), 0.0, "rgba(0, 0, 0, 0.0)"), + ((9, 34, 39), 0.5, "rgba(9, 34, 39, 0.5)"), + ((255, 255, 255), 1.0, "rgba(255, 255, 255, 1.0)"), + ], + ) + def test_rgb_to_rgba(self, rgb_color, alpha, expected_rgba_string): + assert rgb_to_rgba(rgb_color, alpha) == expected_rgba_string