diff --git a/.github/workflows/build_docs.yml b/.github/workflows/build_docs.yml index 1ac4929..f75fdb3 100644 --- a/.github/workflows/build_docs.yml +++ b/.github/workflows/build_docs.yml @@ -1,44 +1,56 @@ name: Build Docs + on: push: branches: - master - main - docs + pull_request: + branches: + - master + - main + permissions: contents: write + jobs: - deploy: + render: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 - - uses: actions/setup-python@v4 + - uses: actions/checkout@v4 + + - uses: quarto-dev/quarto-actions/setup@v2 + + - uses: actions/setup-python@v5 with: python-version: "3.12" - - run: echo "cache_id=$(date --utc '+%V')" >> $GITHUB_ENV - - uses: actions/cache@v3 - with: - key: mkdocs-material-${{ env.cache_id }} - path: .cache - restore-keys: | - mkdocs-material- + - name: Install OS dependencies - shell: bash -el {0} run: | - sudo apt update - sudo apt install -y build-essential zlib1g-dev libcurl4-openssl-dev - - name: Install the package - shell: bash -el {0} + sudo apt-get update + sudo apt-get remove -y libcurl4-openssl-dev || true + sudo apt-get install -y \ + build-essential \ + zlib1g-dev \ + libcurl4-gnutls-dev \ + bedtools \ + libhts-dev \ + samtools + + - name: Install PlotNado docs environment run: | - pip install numpy cython - git clone https://github.com/hiclib/iced.git - cd iced - for fn in $(find . -iname "*.pyx"); do cython $fn; done - pip install . -v - cd .. - rm -rf iced - pip install . -v - - name: Install Mkdocs plugins - run: pip install mkdocs-material mkdocstrings-python mkdocs-click pygments mkdocs-gen-files mkdocs-jupyter mkdocs-autorefs mkdocs-literate-nav mkdocs-section-index - - name: Build the documentation - run: mkdocs gh-deploy --force + python -m pip install --upgrade pip uv + uv pip install --system -e ".[docs]" + + - name: Render Quarto documentation + run: quarto render + + - name: Publish Quarto site + if: github.event_name == 'push' + uses: quarto-dev/quarto-actions/publish@v2 + with: + target: gh-pages + render: false + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.gitignore b/.gitignore index 7f21b62..155c3a4 100644 --- a/.gitignore +++ b/.gitignore @@ -38,3 +38,6 @@ demo_genome_browser.py pr_docs.txt test_parser.py examples/output/* + +/.quarto/ +**/*.quarto_ipynb diff --git a/README.md b/README.md index f8f1bc2..f8c6490 100644 --- a/README.md +++ b/README.md @@ -92,6 +92,10 @@ fig.bigwig(signal, title="Synthetic signal", style="fill", color="#1f77b4") fig.save("quickstart.png", "chr1:1,010,000-1,080,000") ``` +Output: + + + `GenomicFigure()` uses publication-style defaults automatically. Use `GenomicFigure(theme=None)` to opt out. ## CLI Quick Start @@ -129,6 +133,10 @@ fig = GenomicFigure.from_template("template.yaml") fig.save("browser_view.png", region="chr1:1,000,000-1,100,000") ``` +Output: + + + ## What The Template Looks Like The generated YAML is meant to be human-editable: @@ -188,8 +196,8 @@ BigWigTrack.options_markdown() ```bash uv sync --extra docs -uv run mkdocs build --strict -uv run mkdocs serve +quarto render +quarto preview ``` ## Development diff --git a/_quarto.yml b/_quarto.yml new file mode 100644 index 0000000..bb9e825 --- /dev/null +++ b/_quarto.yml @@ -0,0 +1,98 @@ +project: + type: website + output-dir: site + execute-dir: project + render: + - index.qmd + - docs/*.qmd + - docs/reference/*.qmd + +website: + title: "PlotNado Documentation" + description: "Publication-ready genome browser figures in Python." + site-url: "https://alsmith151.github.io/plotnado" + repo-url: "https://github.com/alsmith151/plotnado" + repo-actions: [edit, issue] + favicon: docs/images/Logo.jpeg + search: + location: navbar + type: overlay + navbar: + logo: docs/images/Logo.jpeg + left: + - text: Home + href: index.qmd + - text: Getting Started + menu: + - text: Installation + href: docs/installation.qmd + - text: Quick Start + href: docs/quickstart.qmd + - text: Track Construction + href: docs/quickstart_tracks.qmd + - text: Guides + menu: + - text: Track Catalog + href: docs/track_catalog.qmd + - text: Data Inputs + href: docs/data_inputs.qmd + - text: Figure Workflows + href: docs/figure_workflows.qmd + - text: Aesthetics + href: docs/aesthetics.qmd + - text: Recipes + href: docs/recipes.qmd + - text: Best Practices + href: docs/best_practices.qmd + - text: Reference + menu: + - text: Overview + href: docs/reference.qmd + - text: API Reference + href: docs/api_reference.qmd + - text: Track Aliases + href: docs/track_aliases.qmd + - text: Living Gallery + href: docs/example_coverage.qmd + - text: Reference Summary + href: docs/reference/SUMMARY.qmd + - text: CLI + href: docs/cli.qmd + - text: Examples + menu: + - text: Living Gallery + href: docs/example_coverage.qmd + - text: Basic Example + href: docs/basic_example.qmd + - text: Simple Overlays + href: docs/simple_overlays.qmd + - text: Worked Examples + href: docs/worked_examples.qmd + - text: Help + menu: + - text: FAQ + href: docs/faq.qmd + - text: Troubleshooting + href: docs/troubleshooting.qmd + - text: Changelog + href: docs/changelog.qmd + +format: + html: + theme: + light: [cosmo, docs/stylesheets/plotnado.scss] + dark: [darkly, docs/stylesheets/plotnado.scss] + toc: true + toc-depth: 4 + code-copy: true + code-overflow: wrap + page-layout: full + +execute: + enabled: true + warning: false + message: false + error: false + freeze: false + +metadata-files: [] diff --git a/docs/aesthetics.md b/docs/aesthetics.qmd similarity index 89% rename from docs/aesthetics.md rename to docs/aesthetics.qmd index 428eae1..250a70e 100644 --- a/docs/aesthetics.md +++ b/docs/aesthetics.qmd @@ -1,8 +1,8 @@ # Aesthetics -This guide is about the visual layer: how tracks scale, label, color, and share space. For exact field names, pair it with [Aesthetics Reference](aesthetics_reference.md). +This guide is about the visual layer: how tracks scale, label, color, and share space. For exact field names, pair it with [Aesthetics Reference](aesthetics_reference.qmd). -The rendered panels on this page are generated by [scripts/gen_docs_images.py](https://github.com/alsmith151/plotnado/blob/main/scripts/gen_docs_images.py). Runnable source scripts for the overlapping track combinations are collected on [Example Coverage](example_coverage.md). +The rendered panels on this page are paired with live Quarto examples in the [Living Gallery](example_coverage.qmd), where the code cells and output are rendered together from the current package. Every track kwarg is routed automatically — aesthetics fields go into the style model, label fields go into the label model. You do not need to nest anything manually: @@ -17,13 +17,17 @@ fig.bigwig( ) ``` +Output: + + + --- ## BigWig styles `style` controls how the signal is drawn. The four options: -Runnable example: [BigWig styles](example_coverage.md#bigwig-styles) +Runnable example: [BigWig styles](example_coverage.qmd#bigwig-styles) ```python fig.bigwig(signal, title="fill", style="fill", color="#1f77b4") @@ -114,7 +118,7 @@ fig.bigwig( BED tracks support `display="expanded"` for stacked intervals and `show_labels=True` for name text. narrowPeak adds score-based coloring via `color_by` and optional summit lines. -Runnable example: [BED and narrowPeak](example_coverage.md#bed-and-narrowpeak) +Runnable example: [BED and narrowPeak](example_coverage.qmd#bed-and-narrowpeak) ```python fig.bed( @@ -142,7 +146,7 @@ fig.narrowpeak( `overlay()` draws multiple signals in one panel. `autoscale(True)` and `autoscale_group` now treat overlays as first-class signal panels rather than leaving them on an isolated scale. -Runnable example: [Overlay, autoscale, and highlight](example_coverage.md#overlay-autoscale-and-highlight) +Runnable example: [Overlay, autoscale, and highlight](example_coverage.qmd#overlay-autoscale-and-highlight) Key rules: @@ -171,8 +175,9 @@ fig.overlay(  -!!! tip "When overlay scaling looks wrong" - If the overlay panel should match nearby signal tracks, put `autoscale_group` on the overlay itself. Putting it only on the nested component tracks does not synchronize the panel with sibling axes. +::: {.callout-tip title="When overlay scaling looks wrong"} +If the overlay panel should match nearby signal tracks, put `autoscale_group` on the overlay itself. Putting it only on the nested component tracks does not synchronize the panel with sibling axes. +::: --- @@ -180,7 +185,7 @@ fig.overlay( `display="collapsed"` fits all genes on one row. `display="expanded"` stacks overlapping genes. -Related runnable example: [Gene label strategies](example_coverage.md#gene-label-strategies) +Related runnable example: [Gene label strategies](example_coverage.qmd#gene-label-strategies) ```python fig.genes("hg38", title="display='collapsed'", display="collapsed") @@ -195,7 +200,7 @@ fig.genes("hg38", title="display='expanded'", display="expanded") Arc width and color can be driven by a `score` column using `color_by_score=True` and any matplotlib colormap. -Runnable example: [Links, hline, and vline](example_coverage.md#links-hline-and-vline) +Runnable example: [Links, hline, and vline](example_coverage.qmd#links-hline-and-vline) ```python fig.links(links_df, title="Loops", color_by_score=True, cmap="viridis", alpha=0.8) diff --git a/docs/aesthetics_reference.md b/docs/aesthetics_reference.md deleted file mode 100644 index 68ac1a3..0000000 --- a/docs/aesthetics_reference.md +++ /dev/null @@ -1,41 +0,0 @@ -# Aesthetics Reference - -Use this page when you want the fastest route to track fields and styling options without reading source. - -Every track exposes three groups of fields: - -- `track`: constructor-level fields such as `title`, `height`, `autoscale_group`, and `color_group` -- `aesthetics`: visual controls such as `style`, `color`, `alpha`, `min_value`, and `max_value` -- `label`: title and scale annotation controls such as `plot_scale`, `title_location`, and `scale_location` - -## Discover fields at runtime - -```python -from plotnado import GenomicFigure, BigWigTrack, list_options - -GenomicFigure.track_options("bigwig") -GenomicFigure.track_options("overlay") -GenomicFigure.track_options_markdown("genes") - -BigWigTrack.options() -BigWigTrack.options_markdown() -list_options(BigWigTrack) -``` - -## High-value fields by category - -| Category | Common fields | Notes | -| --- | --- | --- | -| Track | `title`, `height`, `autoscale_group`, `color_group` | These apply to the whole track panel | -| Aesthetics | `color`, `alpha`, `style`, `min_value`, `max_value` | These affect how the track is drawn | -| Label | `plot_title`, `plot_scale`, `title_location`, `scale_location` | These control title and scale text | - -## Overlay-specific guidance - -Overlay tracks are scaled as a single panel. - -- `autoscale_group` belongs on the overlay itself when the whole panel should match sibling signal tracks. -- Explicit overlay `min_value` / `max_value` overrides grouped or global autoscale on that edge. -- `show_labels=False` is useful when the overlay is dense and the panel title carries enough meaning. - -For behavior details, see [Aesthetics](aesthetics.md) and [Reference](reference.md). \ No newline at end of file diff --git a/docs/aesthetics_reference.qmd b/docs/aesthetics_reference.qmd new file mode 100644 index 0000000..932ffe7 --- /dev/null +++ b/docs/aesthetics_reference.qmd @@ -0,0 +1,349 @@ +# Aesthetics Reference + +Use this page when you want the fastest route to track fields and styling options without reading source. + +Every track exposes three groups of fields: + +- `track`: constructor-level fields such as `title`, `height`, `autoscale_group`, and `color_group` +- `aesthetics`: visual controls such as `style`, `color`, `alpha`, `min_value`, and `max_value` +- `label`: title and scale annotation controls such as `plot_scale`, `title_location`, and `scale_location` + +## Discover fields at runtime + +```python +from plotnado import GenomicFigure, BigWigTrack, list_options + +GenomicFigure.track_options("bigwig") +GenomicFigure.track_options("overlay") +GenomicFigure.track_options_markdown("genes") + +BigWigTrack.options() +BigWigTrack.options_markdown() +list_options(BigWigTrack) +``` + +## High-value fields by category + +| Category | Common fields | Notes | +| --- | --- | --- | +| Track | `title`, `height`, `autoscale_group`, `color_group` | These apply to the whole track panel | +| Aesthetics | `color`, `alpha`, `style`, `min_value`, `max_value` | These affect how the track is drawn | +| Label | `plot_title`, `plot_scale`, `title_location`, `scale_location` | These control title and scale text | + +## Track Option Index + +These anchors are stable targets for the [Track Catalog](track_catalog.qmd). Use the runtime calls shown in each section for the complete field table in your installed version. + +### BigWig / bedGraph {#options-bigwig} + +Aliases: `bigwig`, `bw`, `signal`, `bedgraph` + +Runtime reference: + +```python +GenomicFigure.track_options("bigwig") +GenomicFigure.track_options_markdown("bigwig") +``` + +High-value controls: + +| Area | Fields | +| --- | --- | +| Signal drawing | `style`, `color`, `alpha`, `linewidth`, `scatter_point_size` | +| Signal limits | `min_value`, `max_value`, `smoothing_window`, `smoothing_method` | +| Figure coordination | `autoscale_group`, `color_group`, `height` | +| Labels | `title`, `plot_scale`, `scale_location`, `label_on_track`, `label_box_enabled` | + +### Overlay / BigWig overlay {#options-overlay} + +Aliases: `overlay`, `bigwig_overlay` + +Runtime reference: + +```python +GenomicFigure.track_options("overlay") +GenomicFigure.track_options_markdown("overlay") +``` + +Overlay tracks are scaled as a single panel. + +- `autoscale_group` belongs on the overlay itself when the whole panel should match sibling signal tracks. +- Explicit overlay `min_value` / `max_value` overrides grouped or global autoscale on that edge. +- `show_labels=False` is useful when the overlay is dense and the panel title carries enough meaning. + +High-value controls: + +| Area | Fields | +| --- | --- | +| Components | `tracks`, `colors`, `alpha`, `show_labels` | +| Shared scale | `min_value`, `max_value`, `autoscale_group` | +| Labels | `title`, `plot_scale`, `scale_location`, `label_on_track` | + +### BigWig collection {#options-bigwig-collection} + +Alias: `bigwig_collection` + +Runtime reference: + +```python +GenomicFigure.track_options("bigwig_collection") +GenomicFigure.track_options_markdown("bigwig_collection") +``` + +High-value controls: + +| Area | Fields | +| --- | --- | +| Inputs | `files`, `labels` | +| Styling | `colors`, `alpha`, `height` | +| Coordination | `title`, `color_group` | + +### BigWig diff {#options-bigwig-diff} + +Alias: `bigwig_diff` + +Runtime reference: + +```python +GenomicFigure.track_options("bigwig_diff") +GenomicFigure.track_options_markdown("bigwig_diff") +``` + +High-value controls: + +| Area | Fields | +| --- | --- | +| Inputs | `data_a`, `data_b`, `method` | +| Positive/negative signal | `positive_color`, `negative_color`, `bar_alpha` | +| Scale | `min_value`, `max_value`, `height` | + +### BED / annotation / unknown fallback {#options-bed} + +Aliases: `bed`, `annotation`, `unknown` + +Runtime reference: + +```python +GenomicFigure.track_options("bed") +GenomicFigure.track_options_markdown("bed") +``` + +High-value controls: + +| Area | Fields | +| --- | --- | +| Interval layout | `display`, `interval_height`, `max_rows`, `draw_edges` | +| Labels | `show_labels`, `label_field`, `font_size`, `title` | +| Styling | `color`, `alpha`, `height`, `color_group` | + +### NarrowPeak {#options-narrowpeak} + +Alias: `narrowpeak` + +Runtime reference: + +```python +GenomicFigure.track_options("narrowpeak") +GenomicFigure.track_options_markdown("narrowpeak") +``` + +High-value controls: + +| Area | Fields | +| --- | --- | +| Peak layout | `display`, `show_summit`, `show_labels` | +| Score styling | `color_by`, `cmap`, `color`, `alpha` | +| Labels | `label_field`, `font_size`, `title` | + +### Genes / gene {#options-genes} + +Aliases: `genes`, `gene` + +Runtime reference: + +```python +GenomicFigure.track_options("genes") +GenomicFigure.track_options_markdown("genes") +``` + +High-value controls: + +| Area | Fields | +| --- | --- | +| Annotation source | `genome`, `data` | +| Layout | `display`, `minimum_gene_length`, `max_number_of_rows`, `height` | +| Gene labels | `show_labels`, `gene_label_font_size`, `color` | + +### Links {#options-links} + +Alias: `links` + +Runtime reference: + +```python +GenomicFigure.track_options("links") +GenomicFigure.track_options_markdown("links") +``` + +High-value controls: + +| Area | Fields | +| --- | --- | +| Input | BEDPE-like `data`, optional `score` | +| Arc styling | `color_by_score`, `cmap`, `alpha`, `linewidth` | +| Labels/layout | `title`, `height` | + +### Highlight {#options-highlight} + +Alias: `highlight` + +Runtime reference: + +```python +GenomicFigure.track_options("highlight") +GenomicFigure.track_options_markdown("highlight") +``` + +High-value controls: + +| Area | Fields | +| --- | --- | +| Input | BED-like file/table or inline `fig.highlight(...)` region | +| Styling | `color`, `alpha` | +| Behavior | Drawn behind tracks; does not change y-axis limits | + +### HLine / VLine {#options-lines} + +Aliases: `hline`, `vline` + +Runtime reference: + +```python +GenomicFigure.track_options("hline") +GenomicFigure.track_options("vline") +``` + +High-value controls: + +| Area | Fields | +| --- | --- | +| Position | y-value for `hline`, genomic x-position for `vline` | +| Styling | `color`, `linewidth`, `linestyle`, `alpha` | +| Behavior | Drawn as reference marks over existing panels | + +### Cooler / Cooler average {#options-cooler} + +Aliases: `cooler`, `cooler_average` + +Runtime reference: + +```python +GenomicFigure.track_options("cooler") +GenomicFigure.track_options("cooler_average") +``` + +High-value controls: + +| Area | Fields | +| --- | --- | +| Input | cooler-compatible path(s) | +| Matrix rendering | `balance`, `cmap`, `min_value`, `max_value` | +| Layout | `height`, `title` | + +### CapCruncher {#options-capcruncher} + +Alias: `capcruncher` + +Runtime reference: + +```python +GenomicFigure.track_options("capcruncher") +GenomicFigure.track_options_markdown("capcruncher") +``` + +High-value controls: + +| Area | Fields | +| --- | --- | +| Input | CapCruncher HDF5 reporters store | +| Viewpoint | `viewpoint` | +| Matrix rendering | `balance`, `cmap`, `min_value`, `max_value` | + +### QuantNado coverage {#options-quantnado-coverage} + +Aliases: `quantnado_coverage`, `quantnado_stranded_coverage` + +Runtime reference: + +```python +GenomicFigure.track_options("quantnado_coverage") +GenomicFigure.track_options("quantnado_stranded_coverage") +``` + +High-value controls: + +| Area | Fields | +| --- | --- | +| Input | QuantNado object name plus `dataset_path` | +| Coverage styling | `color`, `fill`, `reverse_color` | +| Scale/layout | `min_value`, `max_value`, `height`, `title` | + +### QuantNado methylation {#options-quantnado-methylation} + +Alias: `quantnado_methylation` + +Runtime reference: + +```python +GenomicFigure.track_options("quantnado_methylation") +GenomicFigure.track_options_markdown("quantnado_methylation") +``` + +High-value controls: + +| Area | Fields | +| --- | --- | +| Input | QuantNado methylation dataset | +| Point styling | `color`, `point_size`, `alpha` | +| Scale/layout | methylation percentage scale, `height`, `title` | + +### QuantNado variant {#options-quantnado-variant} + +Alias: `quantnado_variant` + +Runtime reference: + +```python +GenomicFigure.track_options("quantnado_variant") +GenomicFigure.track_options_markdown("quantnado_variant") +``` + +High-value controls: + +| Area | Fields | +| --- | --- | +| Input | QuantNado variant dataset | +| Genotype styling | `het_color`, `hom_alt_color`, `marker_size` | +| Scale/layout | allele-balance scale, `height`, `title` | + +### Structural tracks {#options-structural} + +Aliases: `scalebar`, `scale`, `axis`, `spacer` + +Runtime reference: + +```python +GenomicFigure.track_options("scalebar") +GenomicFigure.track_options("axis") +GenomicFigure.track_options("spacer") +``` + +High-value controls: + +| Track | Fields | +| --- | --- | +| `scalebar` / `scale` | `plot_scale`, `scale_location`, `scale_size`, `height` | +| `axis` | `num_ticks`, tick/label styling, `height` | +| `spacer` | `height` | + +For behavior details, see [Reference](reference.qmd) and [Track Catalog](track_catalog.qmd). diff --git a/docs/api_reference.md b/docs/api_reference.qmd similarity index 89% rename from docs/api_reference.md rename to docs/api_reference.qmd index 5135b1f..8796d85 100644 --- a/docs/api_reference.md +++ b/docs/api_reference.qmd @@ -2,8 +2,8 @@ Use this section when you need API-level details beyond the task-oriented guides. -- Generated module/class reference: [Reference Summary](reference/SUMMARY.md) -- Auto-generated options reference for every track: [Aesthetics Reference](aesthetics_reference.md) +- Generated module/class reference: [Reference Summary](reference/SUMMARY.qmd) +- Auto-generated options reference for every track: [Aesthetics Reference](aesthetics_reference.qmd) ## Discover options at runtime @@ -32,7 +32,7 @@ Each option payload is split into: - `aesthetics`: style model fields (`aesthetics={...}` or shorthand kwargs). - `label`: label controls (`label={...}` or shorthand kwargs). -If you want a browsable summary rather than runtime output, start with [Aesthetics Reference](aesthetics_reference.md). +If you want a browsable summary rather than runtime output, start with [Aesthetics Reference](aesthetics_reference.qmd). ## `GenomicFigure` helper methods: automatic kwargs @@ -56,6 +56,10 @@ gf.bigwig( ) ``` +Output: + + + `color_group` is a track-level kwarg and works well with `gf.autocolor()` for consistent sample coloring: ```python @@ -65,6 +69,10 @@ gf.bed("sampleA.bigBed", title="A peaks", color_group="sampleA") gf.bigwig("sampleA.bw", title="A signal", color_group="sampleA") ``` +Output: + + + ## Common entry points - `plotnado.GenomicFigure`: high-level composition (`add_track`, `plot`, `plot_regions`, `plot_gene`, `from_template`, `from_igv_session`, `to_toml`, `from_toml`). @@ -91,4 +99,4 @@ After a figure is built, tracks can be edited in-place. All editing methods return `self` for chaining. -For practical usage, prefer [Quick Start](quickstart.md), [Track Catalog](track_catalog.md), and [Recipes](recipes.md). +For practical usage, prefer [Quick Start](quickstart.qmd), [Track Catalog](track_catalog.qmd), and [Recipes](recipes.qmd). diff --git a/docs/basic_example.ipynb b/docs/basic_example.ipynb deleted file mode 100644 index 03d7777..0000000 --- a/docs/basic_example.ipynb +++ /dev/null @@ -1,447 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "# Basic Example (New API)\n", - "\n", - "A quick walkthrough for plotting multiple BigWig tracks with the current PlotNado API." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Imports" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "from plotnado import GenomicFigure, LabelConfig" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Define the BigWig files that we want to plot\n", - "\n", - "**Note**: The BigWig files are not included in the dataset, as it is possible to just use remote URLs to plot the data I'm going to use data stored on the CCB Oxford HPC.\n", - "\n", - "To make life easier I'm going to make a dictionary of the BigWig files that I want to plot. You could just add these one by one to the plot if you wanted to." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "bigwigs = {\n", - " 'MV4;11 0nM EPZ H3K79me2': 'https://userweb.molbiol.ox.ac.uk/public/project/milne_group/cchahrou/orlando_chip/hg38_dm6/MV4110nMH3K79me2_bigWig.bigWig',\n", - " 'MV4;11 0.5nM EPZ H3K79me2': 'https://userweb.molbiol.ox.ac.uk/public/project/milne_group/cchahrou/orlando_chip/hg38_dm6/MV41105nMH3K79me2_bigWig.bigWig',\n", - " 'MV4;11 2nM EPZ H3K79me2': 'https://userweb.molbiol.ox.ac.uk/public/project/milne_group/cchahrou/orlando_chip/hg38_dm6/MV4112nMH3K79me2_bigWig.bigWig',\n", - " 'MV4;11 5nM EPZ H3K79me2': 'https://userweb.molbiol.ox.ac.uk/public/project/milne_group/cchahrou/orlando_chip/hg38_dm6/MV4115nMH3K79me2_bigWig.bigWig',\n", - "}" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "# Generate the plot\n", - "\n", - "This example builds a figure with:\n", - "\n", - "- scale bar\n", - "- gene annotations\n", - "- 4 BigWig tracks\n", - "- genomic coordinate axis" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "figure = Figure().autocolor()\n", - "figure.add_track(\"scalebar\")\n", - "figure.add_track(\n", - " \"genes\",\n", - " genome=\"hg38\",\n", - " minimum_gene_length=100_000,\n", - " height=0.5,\n", - " display=\"collapsed\",\n", - ")\n", - "\n", - "for name, url in bigwigs.items():\n", - " figure.add_track(\n", - " \"bigwig\",\n", - " data=url,\n", - " title=name,\n", - " style=\"fill\",\n", - " autoscale_group=\"H3K79me2\",\n", - " min_value=0,\n", - " label=LabelConfig(plot_title=True, plot_scale=True),\n", - " )\n", - "\n", - "figure.add_track(\"axis\")" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "# Display the plot\n", - "\n", - "You've got multiple options for displaying the plot:\n", - "\n", - "* Display it in a Jupyter notebook\n", - "* Save it to a file\n", - "* Save it as a template for later use or plotting using the CLI" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Define the region to plot\n", - "\n", - "There are two ways to define the region to plot:\n", - "\n", - "1. Use a set of genomic coordinates\n", - "1. Use a gene name (this must be from a genome that is supported by the package)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "region_to_plot = 'chr9:77,620,642-78,119,542' # Define the region to plot, this is a region around the GNAQ gene\n", - "gene_to_plot = 'GNAQ' # Define the gene to plot, this is the GNAQ gene" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Perform the plotting" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### By Region" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "figure.plot(region_to_plot) # Plot the region" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### By Gene" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "figure.plot_gene(gene_to_plot)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Save the plot" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "figure.save(\n", - " path=\"GNAQ_H3K79me2.png\",\n", - " region=region_to_plot,\n", - " dpi=300,\n", - ")" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Examine the saved plot\n", - "\n", - "" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Save the plot as a template\n", - "\n", - "This is useful if you want to use the same plot settings for multiple plots, it also allows you to edit the plot settings with standard text editors and then you can either use the PlotNado CLI to generate the plot or you can read in the template and plot it again using the API." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "try:\n", - " import tomli_w # noqa: F401\n", - "except ImportError:\n", - " import subprocess\n", - " import sys\n", - " subprocess.check_call([sys.executable, \"-m\", \"pip\", \"install\", \"tomli-w\"])\n", - "figure.to_toml(\"H3K79me2.toml\")" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Examine the template\n", - "\n", - "The TOML template stores figure and track settings that can be reloaded with `Figure.from_toml(...)`." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Re-load the template and plot it\n", - "\n", - "`Figure.from_toml(...)` reconstructs the figure and tracks.\n", - "If you want auto colors again, call `.autocolor()` on the loaded figure." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "new_figure = Figure.from_toml(\"H3K79me2.toml\").autocolor()\n", - "new_figure.plot(region_to_plot)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## CLI replotting\n", - "\n", - "You can regenerate a figure from a template with the CLI:\n", - "\n", - "```bash\n", - "plotnado plot --template H3K79me2.toml --region chr9:77620642-78119542 --output GNAQ_H3K79me2_cli.png\n", - "```" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "# Customizing the plot\n", - "\n", - "A few common customizations with the new API:\n", - "\n", - "1. Changing track colors\n", - "2. Changing label/scale presentation\n", - "3. Switching BigWig rendering styles" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "figure = Figure()\n", - "figure.add_track(\"scalebar\")\n", - "figure.add_track(\n", - " \"genes\",\n", - " genome=\"hg38\",\n", - " minimum_gene_length=100_000,\n", - " height=0.5,\n", - " display=\"collapsed\",\n", - ")\n", - "\n", - "bigwig_colours = {\n", - " \"MV4;11 0nM EPZ H3K79me2\": \"red\",\n", - " \"MV4;11 0.5nM EPZ H3K79me2\": \"blue\",\n", - " \"MV4;11 2nM EPZ H3K79me2\": \"green\",\n", - " \"MV4;11 5nM EPZ H3K79me2\": \"purple\",\n", - "}\n", - "\n", - "for name, url in bigwigs.items():\n", - " figure.add_track(\n", - " \"bigwig\",\n", - " data=url,\n", - " title=name,\n", - " style=\"fill\",\n", - " color=bigwig_colours[name],\n", - " autoscale_group=\"H3K79me2\",\n", - " min_value=0,\n", - " label=LabelConfig(\n", - " plot_title=True,\n", - " plot_scale=True,\n", - " data_range_style=\"text\",\n", - " label_box_enabled=True,\n", - " label_box_alpha=0.8,\n", - " ),\n", - " )\n", - "\n", - "figure.add_track(\"axis\")\n", - "figure.plot_gene(\"GNAQ\")" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Changing BigWig styles\n", - "\n", - "Supported styles include `line`, `fill`, `fragment`, and `scatter`." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "figure = Figure()\n", - "figure.add_track(\"scalebar\")\n", - "figure.add_track(\n", - " \"genes\",\n", - " genome=\"hg38\",\n", - " minimum_gene_length=100_000,\n", - " height=0.5,\n", - " display=\"collapsed\",\n", - ")\n", - "\n", - "bigwig_colours = {\n", - " \"MV4;11 0nM EPZ H3K79me2\": \"red\",\n", - " \"MV4;11 0.5nM EPZ H3K79me2\": \"blue\",\n", - " \"MV4;11 2nM EPZ H3K79me2\": \"green\",\n", - " \"MV4;11 5nM EPZ H3K79me2\": \"purple\",\n", - "}\n", - "\n", - "styles = [\"line\", \"fill\", \"fragment\", \"scatter\"]\n", - "\n", - "for i, (name, url) in enumerate(bigwigs.items()):\n", - " style = styles[i]\n", - " figure.add_track(\n", - " \"bigwig\",\n", - " data=url,\n", - " title=f\"{name} ({style})\",\n", - " style=style,\n", - " color=bigwig_colours[name],\n", - " autoscale_group=\"H3K79me2\",\n", - " min_value=0,\n", - " label=LabelConfig(plot_title=True, plot_scale=True, data_range_style=\"text\"),\n", - " )\n", - "\n", - "figure.add_track(\"axis\")\n", - "figure.plot_gene(\"GNAQ\")" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Changing line width and alpha\n", - "\n", - "Instead of changing unsupported bin settings, adjust visual emphasis with `linewidth` and `alpha`." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "figure = Figure()\n", - "figure.add_track(\"scalebar\")\n", - "figure.add_track(\n", - " \"genes\",\n", - " genome=\"hg38\",\n", - " minimum_gene_length=100_000,\n", - " height=0.5,\n", - " display=\"collapsed\",\n", - ")\n", - "\n", - "settings = [\n", - " (0.4, 0.8),\n", - " (0.8, 0.8),\n", - " (1.2, 0.7),\n", - " (1.8, 0.6),\n", - "]\n", - "\n", - "for linewidth, alpha in settings:\n", - " figure.add_track(\n", - " \"bigwig\",\n", - " data=\"https://userweb.molbiol.ox.ac.uk/public/project/milne_group/cchahrou/orlando_chip/hg38_dm6/MV4110nMH3K79me2_bigWig.bigWig\",\n", - " title=f\"linewidth={linewidth}, alpha={alpha}\",\n", - " style=\"line\",\n", - " color=\"red\",\n", - " autoscale_group=\"H3K79me2\",\n", - " min_value=0,\n", - " linewidth=linewidth,\n", - " alpha=alpha,\n", - " label=LabelConfig(plot_title=True, plot_scale=True, data_range_style=\"text\"),\n", - " )\n", - "\n", - "figure.add_track(\"axis\")\n", - "figure.plot_gene(\"GNAQ\")" - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": ".venv", - "language": "python", - "name": "python3" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.12.6" - } - }, - "nbformat": 4, - "nbformat_minor": 2 -} diff --git a/docs/basic_example.qmd b/docs/basic_example.qmd new file mode 100644 index 0000000..a0dd4ef --- /dev/null +++ b/docs/basic_example.qmd @@ -0,0 +1,80 @@ +--- +title: Basic Example +jupyter: python3 +execute: + echo: true + warning: false + message: false +--- + +This page is an executable PlotNado walkthrough. Each plotting cell builds the figure with the public API and displays the plot it creates. + +## Setup + +```{python} +import numpy as np +import pandas as pd + +from plotnado import GenomicFigure +``` + +```{python} +#| echo: false +REGION = "chr1:1,010,000-1,080,000" + + +def signal(phase=0.0, scale=1.0, step=1_000): + bins = np.arange(1_000_000, 1_100_000, step) + values = scale * (4 + 2 * np.sin(np.linspace(phase, 6 + phase, bins.shape[0]))) + return pd.DataFrame( + {"chrom": "chr1", "start": bins, "end": bins + step, "value": values} + ) + + +def bed_intervals(): + return pd.DataFrame( + { + "chrom": ["chr1"] * 5, + "start": [1_012_000, 1_022_000, 1_038_000, 1_055_000, 1_068_000], + "end": [1_016_000, 1_028_000, 1_046_000, 1_062_000, 1_074_000], + "name": ["a", "b", "c", "d", "e"], + } + ) +``` + +## Build a first figure + +```{python} +fig = GenomicFigure(width=11, track_height=1.2) +fig.scalebar() +fig.axis() +fig.genes("hg38", title="Genes") +fig.bigwig(signal(), title="Synthetic signal", style="fill", color="#1f77b4") + +fig.plot(REGION) +``` + +## Add intervals and semantic colors + +```{python} +fig = GenomicFigure(width=11, track_height=1.1) +fig.autocolor() +fig.scalebar() +fig.axis() +fig.bigwig(signal(0.0), title="Sample A signal", color_group="A", style="fill") +fig.bed(bed_intervals(), title="Sample A peaks", color_group="A", display="expanded") +fig.bigwig(signal(1.5), title="Sample B signal", color_group="B", style="fill") +fig.bed(bed_intervals(), title="Sample B peaks", color_group="B", display="expanded") + +fig.plot(REGION) +``` + +## Save the figure + +```{python} +fig.save("docs/GNAQ_H3K79me2.png", region=REGION, dpi=180) +``` + +The saved file is the same figure definition rendered to disk. + + diff --git a/docs/best_practices.md b/docs/best_practices.qmd similarity index 95% rename from docs/best_practices.md rename to docs/best_practices.qmd index 869782a..94f3f43 100644 --- a/docs/best_practices.md +++ b/docs/best_practices.qmd @@ -30,6 +30,10 @@ gf.bed("B.bigBed", title="B peaks", color_group="B") gf.bigwig("B.bw", title="B signal", color_group="B") ``` +Output: + + + ## Use aliases for speed, models for strictness - Use alias helpers (`fig.bigwig(...)`, `fig.bed(...)`) for exploratory work. @@ -61,7 +65,7 @@ GenomicFigure.track_options_markdown("genes") ```bash uv run pytest tests/ -v -uv run mkdocs build --strict +quarto render ``` - Prefer example scripts in `examples/` as regression fixtures for plotting behavior. diff --git a/docs/changelog.md b/docs/changelog.qmd similarity index 100% rename from docs/changelog.md rename to docs/changelog.qmd diff --git a/docs/cli.md b/docs/cli.qmd similarity index 92% rename from docs/cli.md rename to docs/cli.qmd index ef58435..8505fe0 100644 --- a/docs/cli.md +++ b/docs/cli.qmd @@ -71,6 +71,10 @@ Render a template for one or more regions: plotnado plot template.yaml --region chr1:1,000,000-1,100,000 --output output.png ``` +Output: + + + Useful options: - `--region` / `-r`: genomic region or gene name; repeat for multiple outputs @@ -88,6 +92,10 @@ plotnado plot template.yaml --region chr1:1,000,000-2,000,000 --region chr2:5,00 plotnado plot template.yaml --region chr1:1,000,000-2,000,000 --output plot.pdf --dpi 300 ``` +Output: + + + Gene-name resolution requires `genome` to be defined in the template. ## Python bridge @@ -100,3 +108,7 @@ from plotnado import GenomicFigure fig = GenomicFigure.from_template("template.yaml") fig.save("output.png", region="chr1:1,000,000-1,100,000") ``` + +Output: + + diff --git a/docs/data_inputs.md b/docs/data_inputs.qmd similarity index 100% rename from docs/data_inputs.md rename to docs/data_inputs.qmd diff --git a/docs/example_coverage.md b/docs/example_coverage.md deleted file mode 100644 index 6d2aa43..0000000 --- a/docs/example_coverage.md +++ /dev/null @@ -1,174 +0,0 @@ -# Example Coverage - -This page maps track types to runnable examples and rendered outputs. - -The default run of [examples/run_examples.py](https://github.com/alsmith151/plotnado/blob/main/examples/run_examples.py) replays the local example set. Remote Blueprint `bigwig_collection` / `bigwig_diff` coverage is opt-in with `python examples/run_examples.py --include-remote` because those scripts stream public BigWig files instead of checking large fixtures into the repo. - -Rendered PNG outputs are written into `examples/output/` and synced into `docs/images/examples/`, so the gallery below shows the same results produced by the current code. - -## Runnable script coverage - -| Track / alias | Coverage level | Example path | -|---|---|---| -| `scalebar` | Full runnable | [examples/quickstart/01_first_plot.py](https://github.com/alsmith151/plotnado/blob/main/examples/quickstart/01_first_plot.py) | -| `axis` | Full runnable | [examples/quickstart/01_first_plot.py](https://github.com/alsmith151/plotnado/blob/main/examples/quickstart/01_first_plot.py) | -| `genes` | Full runnable | [examples/recipes/03_gene_label_strategies.py](https://github.com/alsmith151/plotnado/blob/main/examples/recipes/03_gene_label_strategies.py) | -| `bigwig` | Full runnable | [examples/tracks/01_bigwig_styles.py](https://github.com/alsmith151/plotnado/blob/main/examples/tracks/01_bigwig_styles.py) | -| `bed` | Full runnable | [examples/tracks/02_bed_and_narrowpeak.py](https://github.com/alsmith151/plotnado/blob/main/examples/tracks/02_bed_and_narrowpeak.py) | -| `narrowpeak` | Full runnable | [examples/tracks/02_bed_and_narrowpeak.py](https://github.com/alsmith151/plotnado/blob/main/examples/tracks/02_bed_and_narrowpeak.py) | -| `links` | Full runnable | [examples/tracks/03_links_annotations.py](https://github.com/alsmith151/plotnado/blob/main/examples/tracks/03_links_annotations.py) | -| `hline` | Full runnable | [examples/tracks/03_links_annotations.py](https://github.com/alsmith151/plotnado/blob/main/examples/tracks/03_links_annotations.py) | -| `vline` | Full runnable | [examples/tracks/03_links_annotations.py](https://github.com/alsmith151/plotnado/blob/main/examples/tracks/03_links_annotations.py) | -| `bigwig_collection` | Runnable from remote Blueprint data | [examples/tracks/04_bigwig_collection_and_diff.py](https://github.com/alsmith151/plotnado/blob/main/examples/tracks/04_bigwig_collection_and_diff.py) | -| `bigwig_diff` | Runnable from remote Blueprint data | [examples/tracks/04_bigwig_collection_and_diff.py](https://github.com/alsmith151/plotnado/blob/main/examples/tracks/04_bigwig_collection_and_diff.py) | -| `cooler` | Full runnable | [examples/tracks/05_matrix_tracks.py](https://github.com/alsmith151/plotnado/blob/main/examples/tracks/05_matrix_tracks.py) | -| `capcruncher` | Full runnable | [examples/tracks/05_matrix_tracks.py](https://github.com/alsmith151/plotnado/blob/main/examples/tracks/05_matrix_tracks.py) | -| `cooler_average` | Full runnable | [examples/tracks/05_matrix_tracks.py](https://github.com/alsmith151/plotnado/blob/main/examples/tracks/05_matrix_tracks.py) | -| `quantnado_coverage` | Full runnable | [examples/tracks/06_quantnado_tracks.py](https://github.com/alsmith151/plotnado/blob/main/examples/tracks/06_quantnado_tracks.py) | -| `quantnado_stranded_coverage` | Full runnable | [examples/tracks/06_quantnado_tracks.py](https://github.com/alsmith151/plotnado/blob/main/examples/tracks/06_quantnado_tracks.py) | -| `quantnado_methylation` | Full runnable | [examples/tracks/06_quantnado_tracks.py](https://github.com/alsmith151/plotnado/blob/main/examples/tracks/06_quantnado_tracks.py) | -| `quantnado_variant` | Full runnable | [examples/tracks/06_quantnado_tracks.py](https://github.com/alsmith151/plotnado/blob/main/examples/tracks/06_quantnado_tracks.py) | -| `highlight` | Full runnable | [examples/recipes/01_autoscale_overlay_highlight.py](https://github.com/alsmith151/plotnado/blob/main/examples/recipes/01_autoscale_overlay_highlight.py) | -| `overlay` | Full runnable | [examples/recipes/01_autoscale_overlay_highlight.py](https://github.com/alsmith151/plotnado/blob/main/examples/recipes/01_autoscale_overlay_highlight.py) | - -## Runnable Example Gallery - -### Basic figure - -Minimal scale bar, axis, genes, and one in-memory signal track. - -Source: [examples/basic_figure.py](https://github.com/alsmith151/plotnado/blob/main/examples/basic_figure.py) - - - -### Advanced features - -Autocolor, highlight overlays, interval tracks, grouped autoscaling, and reference lines in one figure. - -Source: [examples/advanced_features.py](https://github.com/alsmith151/plotnado/blob/main/examples/advanced_features.py) - - - -### Quickstart first plot - -The minimal quickstart script used from the installation guide. - -Source: [examples/quickstart/01_first_plot.py](https://github.com/alsmith151/plotnado/blob/main/examples/quickstart/01_first_plot.py) - - - -### Alias and options discovery - -Demonstrates `available_track_aliases()` and `track_options(...)` and saves a small multi-track plot. - -Source: [examples/quickstart/02_aliases_and_options.py](https://github.com/alsmith151/plotnado/blob/main/examples/quickstart/02_aliases_and_options.py) - - - -### BigWig styles - -Compares `fill`, `fragment`, `scatter`, and `std` BigWig render modes. - -Source: [examples/tracks/01_bigwig_styles.py](https://github.com/alsmith151/plotnado/blob/main/examples/tracks/01_bigwig_styles.py) - - - -### BED and narrowPeak - -Compares stacked BED intervals with score-colored narrowPeak rendering. - -Source: [examples/tracks/02_bed_and_narrowpeak.py](https://github.com/alsmith151/plotnado/blob/main/examples/tracks/02_bed_and_narrowpeak.py) - - - -### Links, hline, and vline - -Shows BEDPE-style links together with horizontal and vertical annotation lines. - -Source: [examples/tracks/03_links_annotations.py](https://github.com/alsmith151/plotnado/blob/main/examples/tracks/03_links_annotations.py) - - - -### BigWig collection and diff - -Fetches two public Blueprint plasma-cell RNA BigWigs once, stages tiny local crops for the target window in a temporary directory, then renders a `bigwig_collection` panel and a matching `bigwig_diff` panel from those local files. - -Source: [examples/tracks/04_bigwig_collection_and_diff.py](https://github.com/alsmith151/plotnado/blob/main/examples/tracks/04_bigwig_collection_and_diff.py) - - - -### Cooler and cooler_average - -Uses the checked-in GM12878 cooler fixture for a direct matrix view plus a simple averaged view built from the same file twice. - -Source: [examples/tracks/05_matrix_tracks.py](https://github.com/alsmith151/plotnado/blob/main/examples/tracks/05_matrix_tracks.py) - - - -### CapCruncher viewpoint matrix - -Uses the checked-in reporters-store fixture and resolves the `Slc25A37` viewpoint to the cooler group inside the HDF5 container. - -Source: [examples/tracks/05_matrix_tracks.py](https://github.com/alsmith151/plotnado/blob/main/examples/tracks/05_matrix_tracks.py) - - - -### QuantNado coverage and stranded coverage - -Uses local on-disk QuantNado fixtures to render real ATAC coverage and stranded RNA signal. - -Source: [examples/tracks/06_quantnado_tracks.py](https://github.com/alsmith151/plotnado/blob/main/examples/tracks/06_quantnado_tracks.py) - - - -### QuantNado methylation and variant tracks - -The same script also renders file-backed methylation and variant panels from the compact test fixtures. - -Source: [examples/tracks/06_quantnado_tracks.py](https://github.com/alsmith151/plotnado/blob/main/examples/tracks/06_quantnado_tracks.py) - - - - - -### Overlay, autoscale, and highlight - -Demonstrates a shared overlay panel, grouped autoscaling, and region highlighting. - -Source: [examples/recipes/01_autoscale_overlay_highlight.py](https://github.com/alsmith151/plotnado/blob/main/examples/recipes/01_autoscale_overlay_highlight.py) - - - -### Theme, labels, and TOML round-trip - -Applies the publication theme, saves a TOML figure definition, and reloads it to render again. - -Source: [examples/recipes/02_theme_labels_toml.py](https://github.com/alsmith151/plotnado/blob/main/examples/recipes/02_theme_labels_toml.py) - - - -Reloaded from TOML: - - - -### Gene label strategies - -Compares staggered, suppressed, and auto-expanded gene label placement strategies. - -Source: [examples/recipes/03_gene_label_strategies.py](https://github.com/alsmith151/plotnado/blob/main/examples/recipes/03_gene_label_strategies.py) - - - -## Validate option coverage quickly - -Use runtime metadata to inspect every field (track, aesthetics, label): - -```python -from plotnado import GenomicFigure - -for alias in sorted(GenomicFigure.available_track_aliases()): - print(alias) - GenomicFigure.track_options(alias) -``` - -For full generated tables, see [Aesthetics Reference](aesthetics_reference.md). diff --git a/docs/example_coverage.qmd b/docs/example_coverage.qmd new file mode 100644 index 0000000..cfe023d --- /dev/null +++ b/docs/example_coverage.qmd @@ -0,0 +1,609 @@ +--- +title: Living Example Gallery +jupyter: python3 +execute: + echo: true + warning: false + message: false +--- + +This gallery is rendered by Quarto from the code shown on this page. The helper data below keeps the examples deterministic; each gallery entry then shows the key PlotNado calls followed by the figure produced by the current package version. + +## Shared setup + +```{python} +#| code-fold: true +#| code-summary: "Imports and deterministic example data" +from __future__ import annotations + +import importlib.util +import os +import tempfile +from pathlib import Path + +import numpy as np +import pandas as pd + +from plotnado import GenomicFigure, Theme +``` + +```{python} +#| code-fold: true +#| code-summary: "Synthetic signals, intervals, links, genes, and fixtures" +REGION = "chr1:1,010,000-1,080,000" +REPO_ROOT = Path.cwd() +TEST_DATA_DIR = REPO_ROOT / "tests" / "data" +QUANTNADO_FIXTURE_DIR = TEST_DATA_DIR / "quantnado" + + +def has_module(module_name: str) -> bool: + return importlib.util.find_spec(module_name) is not None + + +def unavailable_example_figure(example_name: str, requirement: str): + import matplotlib.pyplot as plt + + fig, ax = plt.subplots(figsize=(9, 1.8)) + ax.axis("off") + ax.text( + 0.5, + 0.5, + f"{example_name} requires: {requirement}", + ha="center", + va="center", + fontsize=11, + ) + plt.close(fig) + return fig + + +BLUEPRINT_BIGWIGS = { + "T12-15 plasma cell RNA": "http://ftp.ebi.ac.uk/pub/databases/blueprint/data/homo_sapiens/GRCh38/tonsil/T12-15/plasma_cell/RNA-Seq/IDIBAPS/T12-15-PC.signal.star_grape2_crg.GRCh38.20150815.bw", + "T12-16 plasma cell RNA": "http://ftp.ebi.ac.uk/pub/databases/blueprint/data/homo_sapiens/GRCh38/tonsil/T12-16/plasma_cell/RNA-Seq/IDIBAPS/T12-16-PC.signal.star_grape2_crg.GRCh38.20150815.bw", +} +BLUEPRINT_REGION = "chr1:155,190,000-155,220,000" + + +def cache_bigwig_crop(label: str, url: str, cache_dir: Path) -> Path: + import pybigtools + + from plotnado.tracks import GenomicRegion + from plotnado.tracks.bigwig import BigWigTrack + + cache_dir.mkdir(parents=True, exist_ok=True) + cache_path = cache_dir / f"{label.lower().replace(' ', '_').replace('-', '_')}.bw" + if cache_path.exists(): + return cache_path + + region = GenomicRegion(chromosome="chr1", start=155_190_000, end=155_220_000) + data = BigWigTrack(data=url).fetch_data(region) + if data.empty: + raise ValueError(f"No Blueprint signal fetched for {label} in {BLUEPRINT_REGION}") + + records = [ + ("chr1", int(row.start), int(row.end), float(row.value)) + for row in data.itertuples(index=False) + ] + pybigtools.open(str(cache_path), "w").write({"chr1": 155_220_000}, records) + return cache_path + + +def synthetic_signal( + start: int = 1_000_000, + end: int = 1_100_000, + step: int = 1_000, + phase: float = 0.0, + scale: float = 1.0, +) -> pd.DataFrame: + bins = np.arange(start, end, step) + values = scale * (5.0 + 2.0 * np.sin(np.linspace(phase, 6 * np.pi + phase, bins.shape[0]))) + return pd.DataFrame({"chrom": "chr1", "start": bins, "end": bins + step, "value": values}) + + +def review_signal(scale: float, phase: float = 0.0) -> pd.DataFrame: + bins = np.arange(1_000_000, 1_120_000, 1_000) + values = scale * (1.2 + np.sin(np.linspace(phase, 6 + phase, bins.shape[0]))) + return pd.DataFrame({"chrom": "chr1", "start": bins, "end": bins + 1_000, "value": values}) + + +def style_signal(style_shift: float) -> pd.DataFrame: + bins = np.arange(1_000_000, 1_090_000, 1_000) + values = 5 + 2.4 * np.sin(np.linspace(style_shift, 7 + style_shift, bins.shape[0])) + return pd.DataFrame({"chrom": "chr1", "start": bins, "end": bins + 1_000, "value": values}) + + +def bed_intervals() -> pd.DataFrame: + return pd.DataFrame( + { + "chrom": ["chr1", "chr1", "chr1", "chr1"], + "start": [1_008_000, 1_020_000, 1_050_000, 1_066_000], + "end": [1_014_000, 1_032_000, 1_061_000, 1_074_000], + "name": ["a", "b", "c", "d"], + } + ) + + +def narrowpeaks() -> pd.DataFrame: + return pd.DataFrame( + { + "chrom": ["chr1", "chr1", "chr1"], + "start": [1_012_000, 1_038_000, 1_060_000], + "end": [1_018_000, 1_047_000, 1_070_000], + "name": ["np1", "np2", "np3"], + "score": [300, 700, 500], + "strand": [".", ".", "."], + "signalValue": [12.0, 48.0, 30.0], + "pValue": [5.2, 12.3, 8.1], + "qValue": [4.1, 10.0, 6.2], + "peak": [1200, 1800, 2200], + } + ) + + +def link_df() -> pd.DataFrame: + return pd.DataFrame( + { + "chrom1": ["chr1", "chr1", "chr1"], + "start1": [1_010_000, 1_022_000, 1_042_000], + "end1": [1_012_000, 1_024_000, 1_045_000], + "chrom2": ["chr1", "chr1", "chr1"], + "start2": [1_035_000, 1_054_000, 1_072_000], + "end2": [1_037_000, 1_056_000, 1_074_000], + "score": [2.2, 6.5, 9.8], + } + ) + + +def dense_gene_annotations() -> pd.DataFrame: + records = [] + starts = [1_010_000, 1_013_500, 1_017_000, 1_020_500, 1_024_000, 1_028_000, 1_031_500] + lengths = [6_000, 5_500, 6_300, 5_200, 5_800, 5_400, 6_100] + + for index, (start, length) in enumerate(zip(starts, lengths), start=1): + records.append( + { + "chrom": "chr1", + "start": start, + "end": start + length, + "geneid": f"GENE_LONG_NAME_GOES_ON_FOR_A_WHILE_{index}", + "strand": "+" if index % 2 else "-", + "block_count": 3, + "block_starts": [0, int(length * 0.42), int(length * 0.78)], + "block_sizes": [int(length * 0.16), int(length * 0.12), int(length * 0.18)], + } + ) + + return pd.DataFrame.from_records(records) +``` + +## Track coverage + +| Track / alias | Coverage level | Gallery entry | +|---|---|---| +| `scalebar` | Live rendered | [Basic figure](#basic-figure), [Quickstart first plot](#quickstart-first-plot) | +| `axis` | Live rendered | [Basic figure](#basic-figure), [Links, hline, and vline](#links-hline-and-vline) | +| `genes` | Live rendered | [Basic figure](#basic-figure), [Gene label strategies](#gene-label-strategies) | +| `bigwig` | Live rendered | [BigWig styles](#bigwig-styles) | +| `bed` | Live rendered | [BED and narrowPeak](#bed-and-narrowpeak) | +| `narrowpeak` | Live rendered | [BED and narrowPeak](#bed-and-narrowpeak) | +| `links` | Live rendered | [Links, hline, and vline](#links-hline-and-vline) | +| `hline` | Live rendered | [Links, hline, and vline](#links-hline-and-vline) | +| `vline` | Live rendered | [Links, hline, and vline](#links-hline-and-vline) | +| `bigwig_collection` | Live rendered when remote examples are enabled | [BigWig collection and diff](#bigwig-collection-and-diff) | +| `bigwig_diff` | Live rendered when remote examples are enabled | [BigWig collection and diff](#bigwig-collection-and-diff) | +| `cooler` | Live rendered when optional dependencies are installed | [Cooler and cooler_average](#cooler-and-cooler_average) | +| `capcruncher` | Live rendered when optional dependencies are installed | [CapCruncher viewpoint matrix](#capcruncher-viewpoint-matrix) | +| `quantnado_*` | Live rendered when optional dependencies are installed | [QuantNado tracks](#quantnado-coverage-and-stranded-coverage) | +| `highlight` | Live rendered | [Overlay, autoscale, and highlight](#overlay-autoscale-and-highlight) | +| `overlay` | Live rendered | [Overlay, autoscale, and highlight](#overlay-autoscale-and-highlight) | + +## Basic figure + +Minimal scale bar, axis, genes, and one in-memory signal track. + +```{python} +fig = GenomicFigure(width=12, track_height=1.4) +fig.scalebar(position="left") +fig.axis() +fig.genes("hg38", title="Genes") +fig.bigwig( + synthetic_signal(), + title="Synthetic signal", + style="fill", + color="#1f77b4", + alpha=0.8, +) + +fig.plot(REGION) +``` + +## Advanced features + +Autocolor, highlights, interval tracks, grouped autoscaling, and reference lines in one figure. + +```{python} +fig = GenomicFigure(width=12, track_height=1.3) +fig.autocolor("tab10") +fig.highlight("chr1:1,030,000-1,045,000") +fig.highlight_style(color="#f6d55c", alpha=0.2) + +fig.scalebar(position="right") +fig.axis(num_ticks=5) +fig.genes("hg38", title="Genes") +fig.bed(bed_intervals(), title="Intervals", display="expanded", show_labels=True) +fig.bigwig(review_signal(4.0), title="Control", style="fill", autoscale_group="signal") +fig.bigwig(review_signal(5.2, phase=0.8), title="Treatment", style="fill", autoscale_group="signal") +fig.bigwig(review_signal(3.0, phase=1.3), title="Input", style="fragment") +fig.vline(1_060_000, color="#333333", linewidth=1.0) +fig.hline(0.0, color="#666666", linewidth=0.6) + +fig.plot("chr1:1,000,000-1,110,000") +``` + +## Quickstart first plot + +The minimal first plot used in the quickstart flow. + +```{python} +fig = GenomicFigure(width=11) +fig.scalebar() +fig.axis() +fig.genes("hg38", title="Genes") +fig.bigwig( + synthetic_signal(scale=1.2), + title="Synthetic ChIP", + color="#1f77b4", + style="fill", +) + +fig.plot(REGION) +``` + +## Alias and options discovery + +Use `add_track(...)` when track names come from config, CLI inputs, or other runtime values. + +```{python} +fig = GenomicFigure().autocolor("Set2") +fig.add_track("scalebar") +fig.add_track("axis") +fig.add_track("bigwig", data=synthetic_signal(phase=0.0), title="Replicate A", alpha=0.7) +fig.add_track("bigwig", data=synthetic_signal(phase=0.8), title="Replicate B", alpha=0.7) + +fig.plot("chr1:1,005,000-1,070,000") +``` + +## BigWig styles + +Compare `fill`, `fragment`, `scatter`, and `std` BigWig render modes. + +```{python} +fig = GenomicFigure(track_height=1.25) +fig.scalebar() +fig.bigwig(style_signal(0.0), title="fill", style="fill", color="#1f77b4") +fig.bigwig(style_signal(0.8), title="fragment", style="fragment", color="#d62728") +fig.bigwig(style_signal(1.6), title="scatter", style="scatter", color="#2ca02c", scatter_point_size=10) +fig.bigwig(style_signal(2.4), title="std", style="std", color="#9467bd") + +fig.plot(REGION) +``` + +## BED and narrowPeak + +Stack BED intervals and color narrowPeak intervals by a score-like field. + +```{python} +fig = GenomicFigure(track_height=1.25) +fig.scalebar() +fig.axis() +fig.bed(bed_intervals(), title="BED intervals", display="expanded", show_labels=True) +fig.narrowpeak( + narrowpeaks(), + title="narrowPeak", + color_by="signalValue", + cmap="Oranges", + show_labels=True, + show_summit=True, +) + +fig.plot("chr1:1,005,000-1,078,000") +``` + +## Links, hline, and vline + +Draw BEDPE-style links with horizontal and vertical annotation lines. + +```{python} +fig = GenomicFigure(track_height=1.2) +fig.axis() +fig.links(link_df(), title="Loops", color_by_score=True, cmap="viridis", alpha=0.8) +fig.hline(0.1, color="#666666", linewidth=0.8) +fig.vline(1_048_000, color="#222222", linewidth=1.0) + +fig.plot("chr1:1,005,000-1,078,000") +``` + +## BigWig collection and diff + +This remote-backed example is opt-in for docs builds because it streams public Blueprint BigWig data. Set `PLOTNADO_RENDER_REMOTE_EXAMPLES=1` to render it live. + +```{python} +if os.environ.get("PLOTNADO_RENDER_REMOTE_EXAMPLES") == "1": + labels = list(BLUEPRINT_BIGWIGS.keys()) + with tempfile.TemporaryDirectory(prefix="plotnado-blueprint-") as tmpdir: + files = [ + str(cache_bigwig_crop(label, url, Path(tmpdir))) + for label, url in BLUEPRINT_BIGWIGS.items() + ] + + fig = GenomicFigure(track_height=1.15) + fig.axis() + fig.scalebar() + fig.bigwig_collection( + files, + title="Blueprint plasma-cell RNA collection", + labels=labels, + colors=["#d55e00", "#0072b2"], + alpha=0.75, + ) + fig.bigwig_diff( + files[0], + files[1], + title="T12-15 minus T12-16", + positive_color="#b22222", + negative_color="#1f5aa6", + bar_alpha=0.5, + ) + output = fig.plot(BLUEPRINT_REGION) +else: + output = unavailable_example_figure( + "BigWig collection/diff example", + "PLOTNADO_RENDER_REMOTE_EXAMPLES=1", + ) + +output +``` + +## Overlay, autoscale, and highlight + +Synchronize ordinary signal tracks and an overlay panel with one `autoscale_group`. + +```{python} +fig = GenomicFigure(track_height=1.25) +fig.autoscale(True) +fig.highlight("chr1:1,032,000-1,046,000") +fig.highlight_style(color="#ffdd57", alpha=0.22) + +fig.axis() +fig.bigwig(review_signal(2.0), title="Group A", autoscale_group="g1", style="fill", color="#1f77b4") +fig.bigwig(review_signal(10.0, 1.2), title="Group B", autoscale_group="g1", style="fill", color="#d62728") +fig.overlay( + [review_signal(4.2, 0.9), review_signal(3.5, 1.5)], + title="Overlay", + autoscale_group="g1", + colors=["#2ca02c", "#9467bd"], + alpha=0.55, +) + +fig.plot("chr1:1,005,000-1,085,000") +``` + +## Theme, labels, and TOML round-trip + +Apply the publication theme and configure label and scale placement. + +```{python} +fig = GenomicFigure(theme=Theme.publication()) +fig.scalebar(plot_scale=True, scale_size=10) +fig.axis(num_ticks=4) +fig.bigwig( + synthetic_signal(end=1_090_000), + title="Publication theme", + color="#2c7fb8", + label_box_enabled=True, + label_box_alpha=0.85, + title_location="left", + scale_location="right", +) + +fig.plot(REGION) +``` + +The same figure definition can be persisted and loaded again. + +```{python} +with tempfile.TemporaryDirectory() as tmpdir: + toml_path = Path(tmpdir) / "theme_labels.toml" + + fig = GenomicFigure(theme=Theme.publication()) + fig.scalebar(plot_scale=True, scale_size=10) + fig.axis(num_ticks=4) + fig.genes("hg38", title="Genes", title_location="left") + + fig.to_toml(str(toml_path)) + loaded = GenomicFigure.from_toml(str(toml_path)) + output = loaded.plot(REGION) + +output +``` + +## Gene label strategies + +Compare staggered labels, suppressed labels, and automatic row expansion. + +```{python} +genes_df = dense_gene_annotations() + +fig = GenomicFigure(width=12, track_height=1.2) +fig.scalebar() +fig.axis() +fig.genes( + data=genes_df, + title="Method: Staggered labels + connectors", + display="collapsed", + label_overlap_strategy="stagger", + label_max_chars=120, +) +fig.genes( + data=genes_df, + title="Method: Suppress overlaps (offset labels)", + display="collapsed", + label_overlap_strategy="suppress", + label_max_chars=120, +) +fig.genes( + data=genes_df, + title="Method: Auto-expand rows + suppress overlaps", + display="collapsed", + label_overlap_strategy="auto_expand", + max_number_of_rows=6, + label_max_chars=120, +) + +fig.plot("chr1:1,006,000-1,040,000") +``` + +## Cooler and cooler_average + +Use the checked-in cooler fixture for a direct matrix view and a simple averaged view. + +```{python} +cooler_path = TEST_DATA_DIR / "hg19.GM12878-MboI.matrix.2000kb.cool" + +if has_module("cooler") and cooler_path.exists(): + fig = GenomicFigure(track_height=2.1) + fig.axis() + fig.cooler( + str(cooler_path), + title="GM12878 2 Mb cooler", + balance=False, + cmap="YlOrRd", + max_value=60, + ) + fig.cooler_average( + [str(cooler_path), str(cooler_path)], + title="Cooler average (same file twice)", + balance=False, + cmap="viridis", + max_value=60, + ) + output = fig.plot("chr1:0-10,000,000") +else: + output = unavailable_example_figure("Cooler example", "cooler") + +output +``` + +## CapCruncher viewpoint matrix + +Resolve a CapCruncher viewpoint inside the checked-in HDF5 fixture. + +```{python} +capcruncher_path = TEST_DATA_DIR / "capcruncher" / "SAMPLE-A_REP1.hdf5" + +if has_module("capcruncher") and capcruncher_path.exists(): + fig = GenomicFigure(track_height=2.4) + fig.axis() + fig.capcruncher( + str(capcruncher_path), + title="CapCruncher viewpoint Slc25A37", + viewpoint="Slc25A37", + balance=False, + cmap="magma", + ) + output = fig.plot("chr14:69,878,303-69,879,094") +else: + output = unavailable_example_figure("CapCruncher example", "capcruncher") + +output +``` + +## QuantNado coverage and stranded coverage + +Render local on-disk QuantNado ATAC and RNA fixtures. + +```{python} +atac_path = QUANTNADO_FIXTURE_DIR / "atac_chr22.zarr" +rna_path = QUANTNADO_FIXTURE_DIR / "rna_chr22.zarr" + +if has_module("quantnado") and atac_path.exists() and rna_path.exists(): + fig = GenomicFigure(track_height=1.2) + fig.axis() + fig.quantnado_coverage( + "atac", + dataset_path=str(atac_path), + title="ATAC coverage", + color="#1f78b4", + fill=True, + ) + fig.quantnado_stranded_coverage( + "rna", + dataset_path=str(rna_path), + title="RNA stranded coverage", + color="#d7301f", + reverse_color="#4575b4", + ) + output = fig.plot("chr22:10,520,211-10,520,711") +else: + output = unavailable_example_figure("QuantNado signal example", "quantnado") + +output +``` + +## QuantNado methylation + +Render methylation percentages from a local QuantNado fixture. + +```{python} +meth_path = QUANTNADO_FIXTURE_DIR / "meth_chr22.zarr" + +if has_module("quantnado") and meth_path.exists(): + fig = GenomicFigure(track_height=1.2) + fig.axis() + fig.quantnado_methylation( + "meth", + dataset_path=str(meth_path), + title="Methylation percentage", + color="#238b45", + point_size=22, + ) + output = fig.plot("chr22:100-360") +else: + output = unavailable_example_figure("QuantNado methylation example", "quantnado") + +output +``` + +## QuantNado variant + +Render variant allele balance from a local QuantNado fixture. + +```{python} +snp_path = QUANTNADO_FIXTURE_DIR / "snp_chr1.zarr" + +if has_module("quantnado") and snp_path.exists(): + fig = GenomicFigure(track_height=1.2) + fig.axis() + fig.quantnado_variant( + "snp", + dataset_path=str(snp_path), + title="Variant allele balance", + het_color="#756bb1", + hom_alt_color="#d7301f", + marker_size=38, + ) + output = fig.plot("chr1:54,721-55,221") +else: + output = unavailable_example_figure("QuantNado variant example", "quantnado") + +output +``` + +## Runtime option discovery + +The gallery focuses on rendered examples. Use runtime metadata when you need to inspect every available alias or option field. + +```{python} +aliases = sorted(GenomicFigure.available_track_aliases()) +aliases[:10], len(aliases) +``` diff --git a/docs/faq.md b/docs/faq.qmd similarity index 94% rename from docs/faq.md rename to docs/faq.qmd index 34b00cc..f0fb44f 100644 --- a/docs/faq.md +++ b/docs/faq.qmd @@ -33,7 +33,7 @@ Treat the overlay as the unit of scaling: ## What is the recommended coding style? -Use a single `GenomicFigure` instance (`gf`) and chain helper methods. See [Track Construction](quickstart_tracks.md). +Use a single `GenomicFigure` instance (`gf`) and chain helper methods. See [Track Construction](quickstart_tracks.qmd). ## How do I share figure definitions? diff --git a/docs/figure_workflows.md b/docs/figure_workflows.qmd similarity index 83% rename from docs/figure_workflows.md rename to docs/figure_workflows.qmd index 0063320..30e403e 100644 --- a/docs/figure_workflows.md +++ b/docs/figure_workflows.qmd @@ -6,18 +6,30 @@ gf.plot("chr1:1,000,000-1,100,000") ``` +Output: + + + ## Extend around region ```python gf.plot("chr1:1,000,000-1,050,000", extend=0.25) ``` +Output: + + + ## Plot many regions ```python gf.plot_regions(["chr1:1,000,000-1,050,000", "chr1:1,060,000-1,110,000"], ncols=2) ``` +Output: + + + `plot_regions` also accepts a BED path. ## Plot by gene symbol @@ -26,6 +38,10 @@ gf.plot_regions(["chr1:1,000,000-1,050,000", "chr1:1,060,000-1,110,000"], ncols= gf.plot_gene("GNAQ", extend=0.5) ``` +Output: + + + ## Load from an IGV session Convert a saved IGV `.xml` session directly into a `GenomicFigure`: @@ -37,6 +53,10 @@ fig, locus = GenomicFigure.from_igv_session("session.xml") fig.plot(locus) # locus is the session's saved view region ``` +Output: + + + Track colors, fixed scales (`min`/`max`), autoscale groups, and gene annotations are all preserved. The session locus is returned alongside the figure so you can use it directly or override it. @@ -52,6 +72,10 @@ fig = GenomicFigure.from_template(session.template) fig.plot(session.locus) ``` +Output: + + + ## Edit tracks after building a figure Access and mutate individual tracks by title (case-insensitive) or index: @@ -108,4 +132,8 @@ loaded = GenomicFigure.from_toml("figure.toml") loaded.save("figure.png", "chr1:1,000,000-1,100,000") ``` +Output: + + + See [examples/recipes/02_theme_labels_toml.py](https://github.com/alsmith151/plotnado/blob/main/examples/recipes/02_theme_labels_toml.py) for a full round-trip script. diff --git a/docs/index.md b/docs/index.md deleted file mode 100644 index ba99e6a..0000000 --- a/docs/index.md +++ /dev/null @@ -1,145 +0,0 @@ -# PlotNado - -
Genome browser figures without the browser
-PlotNado composes BigWig signals, genes, peaks, interactions, and overlays into clean genome-browser style figures with a high-level API and a file-driven CLI.
- -
- A composed PlotNado figure with signal, annotation, and structural tracks.
-Most readers need one of three routes: get a figure rendered quickly, understand which track type to use, or tune the figure until it is publication-ready.
-Start Here
-Use the Quick Start when you want a working figure with minimal setup and clear defaults.
- -Build With Confidence
-Learn which track to reach for, what each one expects, and where to find concrete examples.
- -Tune The Result
-Use the aesthetics and recipes guides when the figure works but does not yet communicate clearly.
- -PlotNado offers a fluent Python API for notebooks and pipelines, plus a CLI that turns genomic inputs into editable YAML templates.
-Python API
-Add tracks one method at a time and save the result in a single region-specific render step.
- -```python -from plotnado import GenomicFigure - -fig = GenomicFigure(theme="publication") -fig.scalebar() -fig.axis() -fig.genes("hg38") -fig.bigwig("signal.bw", title="ChIP signal", style="fill") -fig.save("output.png", region="chr1:1,010,000-1,080,000") -``` -CLI + YAML
-This route is useful when the inputs already exist on disk and you want a reproducible, file-driven workflow.
- -```bash -plotnado init *.bw peaks.narrowpeak --auto --output template.yaml -plotnado validate template.yaml -plotnado plot template.yaml --region chr1:1,000,000-1,100,000 --output out.png -``` -Need Options Fast?
-Every track exposes discoverable options, so you do not have to guess field names or dig through source first.
- -```python -from plotnado import GenomicFigure - -GenomicFigure.track_options("overlay") -GenomicFigure.track_options_markdown("bigwig") -``` -The docs include plotted outputs, not just code snippets, so you can see what each configuration actually produces.
-
- Start from a minimal stack: scale bar, axis, genes, and one signal track.
-
- Overlay multiple signals in one panel while keeping y-scaling explicit and readable.
-
- Refine color, labels, and spacing once the track composition is correct.
-If the figure is blank or scaling looks wrong, go straight to Troubleshooting. If you are deciding between track types, start with the Track Catalog. If you want exact parameters, jump to Reference and API Reference.
-
+ scalebar, axis, genesStructural context tracks plus a gene annotation panel.
+
+ bigwig, bedgraphContinuous signal rendered as fill, fragments, points, or standard-deviation bands.
+
+ overlay, highlightMultiple signals on one y-axis with a highlighted interval.
+
+ bed, narrowpeakInterval rectangles, labels, peak scores, and summit markers.
+
+ links, hline, vlineInteraction arcs with horizontal and vertical reference lines.
+
+ cooler, cooler_averageContact matrix tracks for cooler-compatible files.
+Genome browser figures without the browser
+ +# Publication‑ready genomic tracks in Python. + +PlotNado composes BigWig signals, genes, peaks, interactions, and overlays into clean genome-browser style figures with a high-level API and a file-driven CLI.
+ +::: {.pn-actions} +Start with Quick Start +Browse track catalog +Explore the CLI +::: + +::: {.pn-stats} +::: {.pn-stat} +**Python API** + +Chain one track method at a time. +::: + +::: {.pn-stat} +**CLI + YAML** + +Infer, edit, validate, and render templates. +::: + +::: {.pn-stat} +**Track-first design** + +Signals, annotations, overlays, and matrices. +::: +::: +::: + +::: {.pn-hero__visual} + + +A composed PlotNado figure with signal, annotation, and structural tracks.
+::: +::: + +::: {.pn-section} +## Pick your entry point + +Most readers need one of three routes: get a figure rendered quickly, understand which track type to use, or tune the figure until it is publication-ready. +::: + +::: {.pn-card-grid} +::: {.pn-card} +Start Here
+ +### Install and render your first figure + +Use the Quick Start when you want a working figure with minimal setup and clear defaults. + +::: {.pn-linklist} +[Installation](docs/installation.qmd) +[Quick Start](docs/quickstart.qmd) +[Track construction patterns](docs/quickstart_tracks.qmd) +::: +::: + +::: {.pn-card} +Build With Confidence
+ +### Choose the right track and input model + +Learn which track to reach for, what each one expects, and where to find concrete examples. + +::: {.pn-linklist} +[Track Catalog](docs/track_catalog.qmd) +[Data Inputs](docs/data_inputs.qmd) +[Living Gallery](docs/example_coverage.qmd) +::: +::: + +::: {.pn-card} +Tune The Result
+ +### Dial in styling, scaling, and layout + +Use the aesthetics and recipes guides when the figure works but does not yet communicate clearly. + +::: {.pn-linklist} +[Aesthetics](docs/aesthetics.qmd) +[Recipes](docs/recipes.qmd) +[Troubleshooting](docs/troubleshooting.qmd) +::: +::: +::: + +::: {.pn-section} +## Two workflows, one rendering model + +PlotNado offers a fluent Python API for notebooks and pipelines, plus a CLI that turns genomic inputs into editable YAML templates. +::: + +::: {.pn-card-grid} +::: {.pn-card} +Python API
+ +### Compose tracks directly in code + +Add tracks one method at a time and save the result in a single region-specific render step. + +```python +from plotnado import GenomicFigure + +fig = GenomicFigure(theme="publication") +fig.scalebar() +fig.axis() +fig.genes("hg38") +fig.bigwig("signal.bw", title="ChIP signal", style="fill") +fig.save("output.png", region="chr1:1,010,000-1,080,000") +``` + +Output
+ +{.pn-code-output} +::: + +::: {.pn-card} +CLI + YAML
+ +### Infer a template, then edit and render it + +This route is useful when the inputs already exist on disk and you want a reproducible, file-driven workflow. + +```bash +plotnado init *.bw peaks.narrowpeak --auto --output template.yaml +plotnado validate template.yaml +plotnado plot template.yaml --region chr1:1,000,000-1,100,000 --output out.png +``` + +Output
+ +{.pn-code-output} +::: + +::: {.pn-card} +Need Options Fast?
+ +### Inspect the runtime metadata + +Every track exposes discoverable options, so you do not have to guess field names or dig through source first. + +```python +from plotnado import GenomicFigure + +GenomicFigure.track_options("overlay") +GenomicFigure.track_options_markdown("bigwig") +``` +::: +::: + +::: {.pn-section} +## Rendered examples + +The docs include plotted outputs, not just code snippets, so you can see what each configuration actually produces. +::: + +::: {.pn-showcase} +::: {.pn-showcase__item} + + +### First figure + +Start from a minimal stack: scale bar, axis, genes, and one signal track. +::: + +::: {.pn-showcase__item} + + +### Overlay + autoscale + +Overlay multiple signals in one panel while keeping y-scaling explicit and readable. +::: + +::: {.pn-showcase__item} + + +### Theme-driven polish + +Refine color, labels, and spacing once the track composition is correct. +::: +::: + +::: {.pn-section} +## Where to go next + +If the figure is blank or scaling looks wrong, go straight to Troubleshooting. If you are deciding between track types, start with the Track Catalog. If you want exact parameters, jump to Reference and API Reference.
+::: diff --git a/mkdocs.yaml b/mkdocs.yaml deleted file mode 100644 index a04d15f..0000000 --- a/mkdocs.yaml +++ /dev/null @@ -1,105 +0,0 @@ -site_name: PlotNado Documentation -site_description: Publication-ready genome browser figures in Python. -nav: - - Home: index.md - - Getting Started: - - Installation: installation.md - - Quick Start: quickstart.md - - Track Construction: quickstart_tracks.md - - Guides: - - Track Catalog: track_catalog.md - - Data Inputs: data_inputs.md - - Figure Workflows: figure_workflows.md - - Aesthetics: aesthetics.md - - Recipes: recipes.md - - Best Practices: best_practices.md - - Reference: - - Overview: reference.md - - API Reference: api_reference.md - - Track Aliases: track_aliases.md - - Example Coverage: example_coverage.md - - CLI: - - CLI Guide: cli.md - - Examples: - - Worked Examples: worked_examples.ipynb - - Basic Notebook: basic_example.ipynb - - Help: - - FAQ: faq.md - - Troubleshooting: troubleshooting.md - - Meta: - - Changelog: changelog.md - -theme: - name: material - logo: images/Logo.jpeg - favicon: images/Logo.jpeg - font: - text: IBM Plex Sans - code: IBM Plex Mono - palette: - - scheme: default - primary: custom - accent: custom - toggle: - icon: material/weather-night - name: Switch to dark mode - - scheme: slate - primary: custom - accent: custom - toggle: - icon: material/weather-sunny - name: Switch to light mode - features: - - navigation.tabs - - navigation.sections - - navigation.expand - - navigation.top - - toc.follow - - search.highlight - - search.suggest - - content.code.copy - - content.action.edit - icon: - repo: fontawesome/brands/github - edit: material/pencil - view: material/eye -markdown_extensions: - - toc: - permalink: true - toc_depth: 4 - - attr_list - - md_in_html - - pymdownx.highlight: - use_pygments: true - line_spans: __span - pygments_lang_class: true - - pymdownx.inlinehilite - - pymdownx.snippets - - pymdownx.superfences - - pymdownx.details - - mkdocs-click - - admonition - - codehilite: - guess_lang: false -extra_css: - - stylesheets/extra.css - -plugins: - - search - - mkdocs-jupyter: - include: - - "*.ipynb" - execute: false - -hooks: - - scripts/mkdocs_hooks.py - -repo_url: https://github.com/alsmith151/plotnado -repo_name: alsmith151/plotnado -edit_uri: edit/main/docs/ - -validation: - nav: - omitted_files: ignore -extra: - generator: false diff --git a/pyproject.toml b/pyproject.toml index 2dd777c..bef004a 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -32,16 +32,12 @@ toml = ["tomli; python_version < '3.11'", "tomli-w"] notebook = ["ipywidgets>=8"] dev = ["pytest", "pytest-cov", "pytest-mock", "pytest-assume", "pre-commit", "ipywidgets>=8"] docs = [ - "mkdocs==1.6.1", - "mkdocs-material>=9.5.18", - "mkdocstrings>=1.0.3", - "mkdocs-literate-nav>=0.6.2", - "mkdocs-gen-files>=0.6.0", - "mkdocs-jupyter>=0.25.1", - "mkdocs-click>=0.9.0", - "pymdown-extensions>=10.21", + "jupyter>=1.1.1", + "ipykernel>=6.29.0", "tomli-w", - "mkdocstrings[python]>=1.0.3", + "cooler", + "capcruncher", + "quantnado", ] all = [ "cooler", @@ -55,15 +51,8 @@ all = [ "pytest-mock", "pytest-assume", "pre-commit", - "mkdocs==1.6.1", - "mkdocs-material>=9.5.18", - "mkdocstrings>=1.0.3", - "mkdocs-literate-nav>=0.6.2", - "mkdocs-gen-files>=0.6.0", - "mkdocs-jupyter>=0.25.1", - "mkdocs-click>=0.9.0", - "pymdown-extensions>=10.21", - "mkdocstrings[python]>=1.0.3", + "jupyter>=1.1.1", + "ipykernel>=6.29.0", ] diff --git a/scripts/gen_ref_pages.py b/scripts/gen_ref_pages.py deleted file mode 100644 index 3b33459..0000000 --- a/scripts/gen_ref_pages.py +++ /dev/null @@ -1,126 +0,0 @@ -"""Generate code and track-option reference pages.""" - -from pathlib import Path - -import mkdocs_gen_files - -from plotnado.figure import GenomicFigure -from plotnado.tracks.registry import registry - -nav = mkdocs_gen_files.Nav() - - -def _markdown_cell(value: object) -> str: - return str(value).replace("|", "\\|") - -for path in sorted(Path("plotnado").rglob("*.py")): - - module_path = path.relative_to(".").with_suffix("") - doc_path = module_path.with_suffix(".md") - full_doc_path = Path("reference", doc_path) - - parts = list(module_path.parts) - - if module_path.stem == "__init__": - continue - elif parts[-1] == "__init__": - parts = parts[:-1] - doc_path = doc_path.with_name("index.md") - full_doc_path = full_doc_path.with_name("index.md") - elif parts[-1] == "__main__": - continue - - nav[parts] = doc_path.as_posix() - - with mkdocs_gen_files.open(full_doc_path, "w") as fd: - identifier = ".".join(parts) - print("::: " + identifier, file=fd) - - mkdocs_gen_files.set_edit_path(full_doc_path, path) - -with mkdocs_gen_files.open("reference/SUMMARY.md", "w") as nav_file: - nav_file.writelines(nav.build_literate_nav()) - - -def _format_section_rows(options: dict[str, dict], section: str) -> list[str]: - rows = [ - f"### {section.title()} fields", - "", - "| Name | Type | Default | Choices | Required | Description |", - "|---|---|---|---|---|---|", - ] - section_data = options.get(section, {}) - for field_name, meta in sorted(section_data.items()): - description = _markdown_cell(meta.get("description") or "—") - choices = meta.get("choices") or [] - choices_text = _markdown_cell(", ".join(str(choice) for choice in choices) if choices else "—") - type_cell = _markdown_cell(meta["type"]) - default_cell = _markdown_cell(meta["default"]) - required_cell = _markdown_cell(meta["required"]) - rows.append( - f"| {field_name} | {type_cell} | {default_cell} | {choices_text} | {required_cell} | {description} |" - ) - rows.append("") - return rows - - -def _generate_aesthetics_reference() -> None: - alias_map = GenomicFigure.available_track_aliases() - class_by_aliases: dict[str, list[str]] = {} - class_by_name: dict[str, type] = {} - for alias, class_name in alias_map.items(): - class_by_aliases.setdefault(class_name, []).append(alias) - track_cls = registry.get(alias).cls - class_by_name[class_name] = track_cls - - lines = [ - "# Aesthetics Reference", - "", - "This page is auto-generated from runtime model metadata (`Track.options()`).", - "", - "Track styles are configured through nested `aesthetics=...` models.", - "When using `GenomicFigure` helper methods (for example `gf.bigwig(...)`),", - "aesthetics and label kwargs can also be passed directly and are routed automatically.", - "", - "Shorthand example:", - "", - "```python", - "gf.bigwig(", - " \"signal.bw\",", - " title=\"Sample\",", - " title_color=\"black\",", - " style=\"std\",", - " color=\"#1f77b4\",", - " alpha=0.8,", - ")", - "```", - "", - "Equivalent explicit form:", - "", - "```python", - "gf.bigwig(", - " \"signal.bw\",", - " aesthetics={\"style\": \"std\", \"color\": \"#1f77b4\", \"alpha\": 0.8},", - " label={\"title\": \"Sample\", \"title_color\": \"black\"},", - ")", - "```", - "", - ] - - for class_name in sorted(class_by_name): - track_cls = class_by_name[class_name] - aliases = ", ".join(f"`{alias}`" for alias in sorted(class_by_aliases[class_name])) - lines.append(f"## {class_name}") - lines.append("") - lines.append(f"Aliases: {aliases}") - lines.append("") - options = track_cls.options() - lines.extend(_format_section_rows(options, "track")) - lines.extend(_format_section_rows(options, "aesthetics")) - lines.extend(_format_section_rows(options, "label")) - - with mkdocs_gen_files.open("aesthetics_reference.md", "w") as handle: - handle.write("\n".join(lines)) - - -_generate_aesthetics_reference() diff --git a/scripts/mkdocs_hooks.py b/scripts/mkdocs_hooks.py deleted file mode 100644 index 4d88cee..0000000 --- a/scripts/mkdocs_hooks.py +++ /dev/null @@ -1,56 +0,0 @@ -"""MkDocs hooks for build-time warning hygiene.""" - -from __future__ import annotations - -import logging -import sys -import warnings - - -def on_startup(**_: object) -> None: - warnings.filterwarnings( - "ignore", - message=r".*parseString.*deprecated.*", - ) - warnings.filterwarnings( - "ignore", - message=r".*resetCache.*deprecated.*", - ) - warnings.filterwarnings( - "ignore", - message=r".*enablePackrat.*deprecated.*", - ) - - class _SuppressExternalHtmlNoise(logging.Filter): - def filter(self, record: logging.LogRecord) -> bool: - message = record.getMessage() - if " Div at " in message and "unclosed" in message and "closing implicitly" in message: - return False - return True - - logging.getLogger().addFilter(_SuppressExternalHtmlNoise()) - - class _FilteredStderr: - def __init__(self, wrapped): - self._wrapped = wrapped - - def write(self, text: str) -> int: - if ( - " Div at " in text - and "unclosed" in text - and "closing implicitly" in text - ): - return len(text) - return self._wrapped.write(text) - - def flush(self) -> None: - self._wrapped.flush() - - def isatty(self) -> bool: - return self._wrapped.isatty() - - @property - def encoding(self): - return self._wrapped.encoding - - sys.stderr = _FilteredStderr(sys.stderr) diff --git a/uv.lock b/uv.lock index e977bd2..5e266e5 100644 --- a/uv.lock +++ b/uv.lock @@ -70,6 +70,19 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/3b/00/2344469e2084fb287c2e0b57b72910309874c3245463acd6cf5e3db69324/appdirs-1.4.4-py2.py3-none-any.whl", hash = "sha256:a841dacd6b99318a741b166adb07e19ee71a274450e68237b4650ca1055ab128", size = 9566, upload-time = "2020-05-11T07:59:49.499Z" }, ] +[[package]] +name = "anyio" +version = "4.13.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "idna" }, + { name = "typing-extensions", marker = "python_full_version < '3.13'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/19/14/2c5dd9f512b66549ae92767a9c7b330ae88e1932ca57876909410251fe13/anyio-4.13.0.tar.gz", hash = "sha256:334b70e641fd2221c1505b3890c69882fe4a2df910cba14d97019b90b24439dc", size = 231622 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/da/42/e921fccf5015463e32a3cf6ee7f980a6ed0f395ceeaa45060b61d86486c2/anyio-4.13.0-py3-none-any.whl", hash = "sha256:08b310f9e24a9594186fd75b4f73f4a4152069e3853f1ed8bfbf58369f4ad708", size = 114353 }, +] + [[package]] name = "appnope" version = "0.1.4" @@ -110,6 +123,62 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/ed/c9/d7977eaacb9df673210491da99e6a247e93df98c715fc43fd136ce1d3d33/arrow-1.4.0-py3-none-any.whl", hash = "sha256:749f0769958ebdc79c173ff0b0670d59051a535fa26e8eba02953dc19eb43205", size = 68797, upload-time = "2025-10-18T17:46:45.663Z" }, ] +[[package]] +name = "argon2-cffi" +version = "25.1.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "argon2-cffi-bindings" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/0e/89/ce5af8a7d472a67cc819d5d998aa8c82c5d860608c4db9f46f1162d7dab9/argon2_cffi-25.1.0.tar.gz", hash = "sha256:694ae5cc8a42f4c4e2bf2ca0e64e51e23a040c6a517a85074683d3959e1346c1", size = 45706 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/4f/d3/a8b22fa575b297cd6e3e3b0155c7e25db170edf1c74783d6a31a2490b8d9/argon2_cffi-25.1.0-py3-none-any.whl", hash = "sha256:fdc8b074db390fccb6eb4a3604ae7231f219aa669a2652e0f20e16ba513d5741", size = 14657 }, +] + +[[package]] +name = "argon2-cffi-bindings" +version = "25.1.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "cffi" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/5c/2d/db8af0df73c1cf454f71b2bbe5e356b8c1f8041c979f505b3d3186e520a9/argon2_cffi_bindings-25.1.0.tar.gz", hash = "sha256:b957f3e6ea4d55d820e40ff76f450952807013d361a65d7f28acc0acbf29229d", size = 1783441 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/60/97/3c0a35f46e52108d4707c44b95cfe2afcafc50800b5450c197454569b776/argon2_cffi_bindings-25.1.0-cp314-cp314t-macosx_10_13_universal2.whl", hash = "sha256:3d3f05610594151994ca9ccb3c771115bdb4daef161976a266f0dd8aa9996b8f", size = 54393 }, + { url = "https://files.pythonhosted.org/packages/9d/f4/98bbd6ee89febd4f212696f13c03ca302b8552e7dbf9c8efa11ea4a388c3/argon2_cffi_bindings-25.1.0-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:8b8efee945193e667a396cbc7b4fb7d357297d6234d30a489905d96caabde56b", size = 29328 }, + { url = "https://files.pythonhosted.org/packages/43/24/90a01c0ef12ac91a6be05969f29944643bc1e5e461155ae6559befa8f00b/argon2_cffi_bindings-25.1.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:3c6702abc36bf3ccba3f802b799505def420a1b7039862014a65db3205967f5a", size = 31269 }, + { url = "https://files.pythonhosted.org/packages/d4/d3/942aa10782b2697eee7af5e12eeff5ebb325ccfb86dd8abda54174e377e4/argon2_cffi_bindings-25.1.0-cp314-cp314t-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:a1c70058c6ab1e352304ac7e3b52554daadacd8d453c1752e547c76e9c99ac44", size = 86558 }, + { url = "https://files.pythonhosted.org/packages/0d/82/b484f702fec5536e71836fc2dbc8c5267b3f6e78d2d539b4eaa6f0db8bf8/argon2_cffi_bindings-25.1.0-cp314-cp314t-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:e2fd3bfbff3c5d74fef31a722f729bf93500910db650c925c2d6ef879a7e51cb", size = 92364 }, + { url = "https://files.pythonhosted.org/packages/c9/c1/a606ff83b3f1735f3759ad0f2cd9e038a0ad11a3de3b6c673aa41c24bb7b/argon2_cffi_bindings-25.1.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:c4f9665de60b1b0e99bcd6be4f17d90339698ce954cfd8d9cf4f91c995165a92", size = 85637 }, + { url = "https://files.pythonhosted.org/packages/44/b4/678503f12aceb0262f84fa201f6027ed77d71c5019ae03b399b97caa2f19/argon2_cffi_bindings-25.1.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:ba92837e4a9aa6a508c8d2d7883ed5a8f6c308c89a4790e1e447a220deb79a85", size = 91934 }, + { url = "https://files.pythonhosted.org/packages/f0/c7/f36bd08ef9bd9f0a9cff9428406651f5937ce27b6c5b07b92d41f91ae541/argon2_cffi_bindings-25.1.0-cp314-cp314t-win32.whl", hash = "sha256:84a461d4d84ae1295871329b346a97f68eade8c53b6ed9a7ca2d7467f3c8ff6f", size = 28158 }, + { url = "https://files.pythonhosted.org/packages/b3/80/0106a7448abb24a2c467bf7d527fe5413b7fdfa4ad6d6a96a43a62ef3988/argon2_cffi_bindings-25.1.0-cp314-cp314t-win_amd64.whl", hash = "sha256:b55aec3565b65f56455eebc9b9f34130440404f27fe21c3b375bf1ea4d8fbae6", size = 32597 }, + { url = "https://files.pythonhosted.org/packages/05/b8/d663c9caea07e9180b2cb662772865230715cbd573ba3b5e81793d580316/argon2_cffi_bindings-25.1.0-cp314-cp314t-win_arm64.whl", hash = "sha256:87c33a52407e4c41f3b70a9c2d3f6056d88b10dad7695be708c5021673f55623", size = 28231 }, + { url = "https://files.pythonhosted.org/packages/1d/57/96b8b9f93166147826da5f90376e784a10582dd39a393c99bb62cfcf52f0/argon2_cffi_bindings-25.1.0-cp39-abi3-macosx_10_9_universal2.whl", hash = "sha256:aecba1723ae35330a008418a91ea6cfcedf6d31e5fbaa056a166462ff066d500", size = 54121 }, + { url = "https://files.pythonhosted.org/packages/0a/08/a9bebdb2e0e602dde230bdde8021b29f71f7841bd54801bcfd514acb5dcf/argon2_cffi_bindings-25.1.0-cp39-abi3-macosx_10_9_x86_64.whl", hash = "sha256:2630b6240b495dfab90aebe159ff784d08ea999aa4b0d17efa734055a07d2f44", size = 29177 }, + { url = "https://files.pythonhosted.org/packages/b6/02/d297943bcacf05e4f2a94ab6f462831dc20158614e5d067c35d4e63b9acb/argon2_cffi_bindings-25.1.0-cp39-abi3-macosx_11_0_arm64.whl", hash = "sha256:7aef0c91e2c0fbca6fc68e7555aa60ef7008a739cbe045541e438373bc54d2b0", size = 31090 }, + { url = "https://files.pythonhosted.org/packages/c1/93/44365f3d75053e53893ec6d733e4a5e3147502663554b4d864587c7828a7/argon2_cffi_bindings-25.1.0-cp39-abi3-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:1e021e87faa76ae0d413b619fe2b65ab9a037f24c60a1e6cc43457ae20de6dc6", size = 81246 }, + { url = "https://files.pythonhosted.org/packages/09/52/94108adfdd6e2ddf58be64f959a0b9c7d4ef2fa71086c38356d22dc501ea/argon2_cffi_bindings-25.1.0-cp39-abi3-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:d3e924cfc503018a714f94a49a149fdc0b644eaead5d1f089330399134fa028a", size = 87126 }, + { url = "https://files.pythonhosted.org/packages/72/70/7a2993a12b0ffa2a9271259b79cc616e2389ed1a4d93842fac5a1f923ffd/argon2_cffi_bindings-25.1.0-cp39-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:c87b72589133f0346a1cb8d5ecca4b933e3c9b64656c9d175270a000e73b288d", size = 80343 }, + { url = "https://files.pythonhosted.org/packages/78/9a/4e5157d893ffc712b74dbd868c7f62365618266982b64accab26bab01edc/argon2_cffi_bindings-25.1.0-cp39-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:1db89609c06afa1a214a69a462ea741cf735b29a57530478c06eb81dd403de99", size = 86777 }, + { url = "https://files.pythonhosted.org/packages/74/cd/15777dfde1c29d96de7f18edf4cc94c385646852e7c7b0320aa91ccca583/argon2_cffi_bindings-25.1.0-cp39-abi3-win32.whl", hash = "sha256:473bcb5f82924b1becbb637b63303ec8d10e84c8d241119419897a26116515d2", size = 27180 }, + { url = "https://files.pythonhosted.org/packages/e2/c6/a759ece8f1829d1f162261226fbfd2c6832b3ff7657384045286d2afa384/argon2_cffi_bindings-25.1.0-cp39-abi3-win_amd64.whl", hash = "sha256:a98cd7d17e9f7ce244c0803cad3c23a7d379c301ba618a5fa76a67d116618b98", size = 31715 }, + { url = "https://files.pythonhosted.org/packages/42/b9/f8d6fa329ab25128b7e98fd83a3cb34d9db5b059a9847eddb840a0af45dd/argon2_cffi_bindings-25.1.0-cp39-abi3-win_arm64.whl", hash = "sha256:b0fdbcf513833809c882823f98dc2f931cf659d9a1429616ac3adebb49f5db94", size = 27149 }, +] + +[[package]] +name = "arrow" +version = "1.4.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "python-dateutil" }, + { name = "tzdata" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/b9/33/032cdc44182491aa708d06a68b62434140d8c50820a087fac7af37703357/arrow-1.4.0.tar.gz", hash = "sha256:ed0cc050e98001b8779e84d461b0098c4ac597e88704a655582b21d116e526d7", size = 152931 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/ed/c9/d7977eaacb9df673210491da99e6a247e93df98c715fc43fd136ce1d3d33/arrow-1.4.0-py3-none-any.whl", hash = "sha256:749f0769958ebdc79c173ff0b0670d59051a535fa26e8eba02953dc19eb43205", size = 68797 }, +] + [[package]] name = "asciitree" version = "0.3.3" @@ -125,6 +194,15 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/d2/39/e7eaf1799466a4aef85b6a4fe7bd175ad2b1c6345066aa33f1f58d4b18d0/asttokens-3.0.1-py3-none-any.whl", hash = "sha256:15a3ebc0f43c2d0a50eeafea25e19046c68398e487b9f1f5b517f7c0f40f976a", size = 27047, upload-time = "2025-11-15T16:43:16.109Z" }, ] +[[package]] +name = "async-lru" +version = "2.3.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/e8/1f/989ecfef8e64109a489fff357450cb73fa73a865a92bd8c272170a6922c2/async_lru-2.3.0.tar.gz", hash = "sha256:89bdb258a0140d7313cf8f4031d816a042202faa61d0ab310a0a538baa1c24b6", size = 16332 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/e5/e2/c2e3abf398f80732e58b03be77bde9022550d221dd8781bf586bd4d97cc1/async_lru-2.3.0-py3-none-any.whl", hash = "sha256:eea27b01841909316f2cc739807acea1c623df2be8c5cfad7583286397bb8315", size = 8403 }, +] + [[package]] name = "attrs" version = "26.1.0" @@ -144,17 +222,84 @@ wheels = [ ] [[package]] -name = "backrefs" -version = "6.2" +name = "bamnado" +version = "0.5.8" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/4e/a6/e325ec73b638d3ede4421b5445d4a0b8b219481826cc079d510100af356c/backrefs-6.2.tar.gz", hash = "sha256:f44ff4d48808b243b6c0cdc6231e22195c32f77046018141556c66f8bab72a49", size = 7012303, upload-time = "2026-02-16T19:10:15.828Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/1b/39/3765df263e08a4df37f4f43cb5aa3c6c17a4bdd42ecfe841e04c26037171/backrefs-6.2-py310-none-any.whl", hash = "sha256:0fdc7b012420b6b144410342caeb8adc54c6866cf12064abc9bb211302e496f8", size = 381075, upload-time = "2026-02-16T19:10:04.322Z" }, - { url = "https://files.pythonhosted.org/packages/0f/f0/35240571e1b67ffb19dafb29ab34150b6f59f93f717b041082cdb1bfceb1/backrefs-6.2-py311-none-any.whl", hash = "sha256:08aa7fae530c6b2361d7bdcbda1a7c454e330cc9dbcd03f5c23205e430e5c3be", size = 392874, upload-time = "2026-02-16T19:10:06.314Z" }, - { url = "https://files.pythonhosted.org/packages/e3/63/77e8c9745b4d227cce9f5e0a6f68041278c5f9b18588b35905f5f19c1beb/backrefs-6.2-py312-none-any.whl", hash = "sha256:c3f4b9cb2af8cda0d87ab4f57800b57b95428488477be164dd2b47be54db0c90", size = 398787, upload-time = "2026-02-16T19:10:08.274Z" }, - { url = "https://files.pythonhosted.org/packages/c5/71/c754b1737ad99102e03fa3235acb6cb6d3ac9d6f596cbc3e5f236705abd8/backrefs-6.2-py313-none-any.whl", hash = "sha256:12df81596ab511f783b7d87c043ce26bc5b0288cf3bb03610fe76b8189282b2b", size = 400747, upload-time = "2026-02-16T19:10:09.791Z" }, - { url = "https://files.pythonhosted.org/packages/af/75/be12ba31a6eb20dccef2320cd8ccb3f7d9013b68ba4c70156259fee9e409/backrefs-6.2-py314-none-any.whl", hash = "sha256:e5f805ae09819caa1aa0623b4a83790e7028604aa2b8c73ba602c4454e665de7", size = 412602, upload-time = "2026-02-16T19:10:12.317Z" }, - { url = "https://files.pythonhosted.org/packages/21/f8/d02f650c47d05034dcd6f9c8cf94f39598b7a89c00ecda0ecb2911bc27e9/backrefs-6.2-py39-none-any.whl", hash = "sha256:664e33cd88c6840b7625b826ecf2555f32d491800900f5a541f772c485f7cda7", size = 381077, upload-time = "2026-02-16T19:10:13.74Z" }, +dependencies = [ + { name = "numpy" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/80/85/1ca66c652498638fed9edf1f53cb5f58f8ad5a0cd7d285545cf2752c8e95/bamnado-0.5.8.tar.gz", hash = "sha256:d951c9c5c1cb6aecda72839841e25eb0c76b29504e4a3dc7c72fed01d535aa18", size = 98047 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/f5/a5/85da2ce0814ade22bc8e7fde0ea3acee28839697cc3457ecc53820091cbf/bamnado-0.5.8-cp310-abi3-macosx_10_12_x86_64.whl", hash = "sha256:830bfed5dba5fa4ef0d86b6cf90edec8f11706b9989cee06339e728b9ee4acca", size = 755526 }, + { url = "https://files.pythonhosted.org/packages/19/6b/c583b80efec55de7fef3ff4d1e6db868fb8a2bd5e737165a7a0b6c89536d/bamnado-0.5.8-cp310-abi3-macosx_11_0_arm64.whl", hash = "sha256:1a379b0c19ec9daa31dab920f87679df2cc4be1ce2c3e08e728d90246a9349e0", size = 710084 }, + { url = "https://files.pythonhosted.org/packages/2b/a4/935262711deb646f8454a01fc7a86a17abe2599003a4199b3aa44965ab21/bamnado-0.5.8-cp310-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:21bae01516adc6f694530677740510a4678c4923f98059d564869b550601131a", size = 2287257 }, + { url = "https://files.pythonhosted.org/packages/dd/ae/acd15a8e4e4e46a4854fb6bcb6d4841f834d2971620eea9b0bcd2d007abd/bamnado-0.5.8-cp310-abi3-win_amd64.whl", hash = "sha256:e6f53069cf031b2b2e6a7166dd1a9b8eabbf39af5f348d7afd9108b2c7828aa6", size = 900961 }, +] + +[[package]] +name = "bcrypt" +version = "5.0.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/d4/36/3329e2518d70ad8e2e5817d5a4cac6bba05a47767ec416c7d020a965f408/bcrypt-5.0.0.tar.gz", hash = "sha256:f748f7c2d6fd375cc93d3fba7ef4a9e3a092421b8dbf34d8d4dc06be9492dfdd", size = 25386 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/13/85/3e65e01985fddf25b64ca67275bb5bdb4040bd1a53b66d355c6c37c8a680/bcrypt-5.0.0-cp313-cp313t-macosx_10_12_universal2.whl", hash = "sha256:f3c08197f3039bec79cee59a606d62b96b16669cff3949f21e74796b6e3cd2be", size = 481806 }, + { url = "https://files.pythonhosted.org/packages/44/dc/01eb79f12b177017a726cbf78330eb0eb442fae0e7b3dfd84ea2849552f3/bcrypt-5.0.0-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:200af71bc25f22006f4069060c88ed36f8aa4ff7f53e67ff04d2ab3f1e79a5b2", size = 268626 }, + { url = "https://files.pythonhosted.org/packages/8c/cf/e82388ad5959c40d6afd94fb4743cc077129d45b952d46bdc3180310e2df/bcrypt-5.0.0-cp313-cp313t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:baade0a5657654c2984468efb7d6c110db87ea63ef5a4b54732e7e337253e44f", size = 271853 }, + { url = "https://files.pythonhosted.org/packages/ec/86/7134b9dae7cf0efa85671651341f6afa695857fae172615e960fb6a466fa/bcrypt-5.0.0-cp313-cp313t-manylinux_2_28_aarch64.whl", hash = "sha256:c58b56cdfb03202b3bcc9fd8daee8e8e9b6d7e3163aa97c631dfcfcc24d36c86", size = 269793 }, + { url = "https://files.pythonhosted.org/packages/cc/82/6296688ac1b9e503d034e7d0614d56e80c5d1a08402ff856a4549cb59207/bcrypt-5.0.0-cp313-cp313t-manylinux_2_28_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:4bfd2a34de661f34d0bda43c3e4e79df586e4716ef401fe31ea39d69d581ef23", size = 289930 }, + { url = "https://files.pythonhosted.org/packages/d1/18/884a44aa47f2a3b88dd09bc05a1e40b57878ecd111d17e5bba6f09f8bb77/bcrypt-5.0.0-cp313-cp313t-manylinux_2_28_x86_64.whl", hash = "sha256:ed2e1365e31fc73f1825fa830f1c8f8917ca1b3ca6185773b349c20fd606cec2", size = 272194 }, + { url = "https://files.pythonhosted.org/packages/0e/8f/371a3ab33c6982070b674f1788e05b656cfbf5685894acbfef0c65483a59/bcrypt-5.0.0-cp313-cp313t-manylinux_2_34_aarch64.whl", hash = "sha256:83e787d7a84dbbfba6f250dd7a5efd689e935f03dd83b0f919d39349e1f23f83", size = 269381 }, + { url = "https://files.pythonhosted.org/packages/b1/34/7e4e6abb7a8778db6422e88b1f06eb07c47682313997ee8a8f9352e5a6f1/bcrypt-5.0.0-cp313-cp313t-manylinux_2_34_x86_64.whl", hash = "sha256:137c5156524328a24b9fac1cb5db0ba618bc97d11970b39184c1d87dc4bf1746", size = 271750 }, + { url = "https://files.pythonhosted.org/packages/c0/1b/54f416be2499bd72123c70d98d36c6cd61a4e33d9b89562c22481c81bb30/bcrypt-5.0.0-cp313-cp313t-musllinux_1_1_aarch64.whl", hash = "sha256:38cac74101777a6a7d3b3e3cfefa57089b5ada650dce2baf0cbdd9d65db22a9e", size = 303757 }, + { url = "https://files.pythonhosted.org/packages/13/62/062c24c7bcf9d2826a1a843d0d605c65a755bc98002923d01fd61270705a/bcrypt-5.0.0-cp313-cp313t-musllinux_1_1_x86_64.whl", hash = "sha256:d8d65b564ec849643d9f7ea05c6d9f0cd7ca23bdd4ac0c2dbef1104ab504543d", size = 306740 }, + { url = "https://files.pythonhosted.org/packages/d5/c8/1fdbfc8c0f20875b6b4020f3c7dc447b8de60aa0be5faaf009d24242aec9/bcrypt-5.0.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:741449132f64b3524e95cd30e5cd3343006ce146088f074f31ab26b94e6c75ba", size = 334197 }, + { url = "https://files.pythonhosted.org/packages/a6/c1/8b84545382d75bef226fbc6588af0f7b7d095f7cd6a670b42a86243183cd/bcrypt-5.0.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:212139484ab3207b1f0c00633d3be92fef3c5f0af17cad155679d03ff2ee1e41", size = 352974 }, + { url = "https://files.pythonhosted.org/packages/10/a6/ffb49d4254ed085e62e3e5dd05982b4393e32fe1e49bb1130186617c29cd/bcrypt-5.0.0-cp313-cp313t-win32.whl", hash = "sha256:9d52ed507c2488eddd6a95bccee4e808d3234fa78dd370e24bac65a21212b861", size = 148498 }, + { url = "https://files.pythonhosted.org/packages/48/a9/259559edc85258b6d5fc5471a62a3299a6aa37a6611a169756bf4689323c/bcrypt-5.0.0-cp313-cp313t-win_amd64.whl", hash = "sha256:f6984a24db30548fd39a44360532898c33528b74aedf81c26cf29c51ee47057e", size = 145853 }, + { url = "https://files.pythonhosted.org/packages/2d/df/9714173403c7e8b245acf8e4be8876aac64a209d1b392af457c79e60492e/bcrypt-5.0.0-cp313-cp313t-win_arm64.whl", hash = "sha256:9fffdb387abe6aa775af36ef16f55e318dcda4194ddbf82007a6f21da29de8f5", size = 139626 }, + { url = "https://files.pythonhosted.org/packages/f8/14/c18006f91816606a4abe294ccc5d1e6f0e42304df5a33710e9e8e95416e1/bcrypt-5.0.0-cp314-cp314t-macosx_10_12_universal2.whl", hash = "sha256:4870a52610537037adb382444fefd3706d96d663ac44cbb2f37e3919dca3d7ef", size = 481862 }, + { url = "https://files.pythonhosted.org/packages/67/49/dd074d831f00e589537e07a0725cf0e220d1f0d5d8e85ad5bbff251c45aa/bcrypt-5.0.0-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:48f753100931605686f74e27a7b49238122aa761a9aefe9373265b8b7aa43ea4", size = 268544 }, + { url = "https://files.pythonhosted.org/packages/f5/91/50ccba088b8c474545b034a1424d05195d9fcbaaf802ab8bfe2be5a4e0d7/bcrypt-5.0.0-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:f70aadb7a809305226daedf75d90379c397b094755a710d7014b8b117df1ebbf", size = 271787 }, + { url = "https://files.pythonhosted.org/packages/aa/e7/d7dba133e02abcda3b52087a7eea8c0d4f64d3e593b4fffc10c31b7061f3/bcrypt-5.0.0-cp314-cp314t-manylinux_2_28_aarch64.whl", hash = "sha256:744d3c6b164caa658adcb72cb8cc9ad9b4b75c7db507ab4bc2480474a51989da", size = 269753 }, + { url = "https://files.pythonhosted.org/packages/33/fc/5b145673c4b8d01018307b5c2c1fc87a6f5a436f0ad56607aee389de8ee3/bcrypt-5.0.0-cp314-cp314t-manylinux_2_28_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:a28bc05039bdf3289d757f49d616ab3efe8cf40d8e8001ccdd621cd4f98f4fc9", size = 289587 }, + { url = "https://files.pythonhosted.org/packages/27/d7/1ff22703ec6d4f90e62f1a5654b8867ef96bafb8e8102c2288333e1a6ca6/bcrypt-5.0.0-cp314-cp314t-manylinux_2_28_x86_64.whl", hash = "sha256:7f277a4b3390ab4bebe597800a90da0edae882c6196d3038a73adf446c4f969f", size = 272178 }, + { url = "https://files.pythonhosted.org/packages/c8/88/815b6d558a1e4d40ece04a2f84865b0fef233513bd85fd0e40c294272d62/bcrypt-5.0.0-cp314-cp314t-manylinux_2_34_aarch64.whl", hash = "sha256:79cfa161eda8d2ddf29acad370356b47f02387153b11d46042e93a0a95127493", size = 269295 }, + { url = "https://files.pythonhosted.org/packages/51/8c/e0db387c79ab4931fc89827d37608c31cc57b6edc08ccd2386139028dc0d/bcrypt-5.0.0-cp314-cp314t-manylinux_2_34_x86_64.whl", hash = "sha256:a5393eae5722bcef046a990b84dff02b954904c36a194f6cfc817d7dca6c6f0b", size = 271700 }, + { url = "https://files.pythonhosted.org/packages/06/83/1570edddd150f572dbe9fc00f6203a89fc7d4226821f67328a85c330f239/bcrypt-5.0.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:7f4c94dec1b5ab5d522750cb059bb9409ea8872d4494fd152b53cca99f1ddd8c", size = 334034 }, + { url = "https://files.pythonhosted.org/packages/c9/f2/ea64e51a65e56ae7a8a4ec236c2bfbdd4b23008abd50ac33fbb2d1d15424/bcrypt-5.0.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:0cae4cb350934dfd74c020525eeae0a5f79257e8a201c0c176f4b84fdbf2a4b4", size = 352766 }, + { url = "https://files.pythonhosted.org/packages/d7/d4/1a388d21ee66876f27d1a1f41287897d0c0f1712ef97d395d708ba93004c/bcrypt-5.0.0-cp314-cp314t-win32.whl", hash = "sha256:b17366316c654e1ad0306a6858e189fc835eca39f7eb2cafd6aaca8ce0c40a2e", size = 152449 }, + { url = "https://files.pythonhosted.org/packages/3f/61/3291c2243ae0229e5bca5d19f4032cecad5dfb05a2557169d3a69dc0ba91/bcrypt-5.0.0-cp314-cp314t-win_amd64.whl", hash = "sha256:92864f54fb48b4c718fc92a32825d0e42265a627f956bc0361fe869f1adc3e7d", size = 149310 }, + { url = "https://files.pythonhosted.org/packages/3e/89/4b01c52ae0c1a681d4021e5dd3e45b111a8fb47254a274fa9a378d8d834b/bcrypt-5.0.0-cp314-cp314t-win_arm64.whl", hash = "sha256:dd19cf5184a90c873009244586396a6a884d591a5323f0e8a5922560718d4993", size = 143761 }, + { url = "https://files.pythonhosted.org/packages/84/29/6237f151fbfe295fe3e074ecc6d44228faa1e842a81f6d34a02937ee1736/bcrypt-5.0.0-cp38-abi3-macosx_10_12_universal2.whl", hash = "sha256:fc746432b951e92b58317af8e0ca746efe93e66555f1b40888865ef5bf56446b", size = 494553 }, + { url = "https://files.pythonhosted.org/packages/45/b6/4c1205dde5e464ea3bd88e8742e19f899c16fa8916fb8510a851fae985b5/bcrypt-5.0.0-cp38-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:c2388ca94ffee269b6038d48747f4ce8df0ffbea43f31abfa18ac72f0218effb", size = 275009 }, + { url = "https://files.pythonhosted.org/packages/3b/71/427945e6ead72ccffe77894b2655b695ccf14ae1866cd977e185d606dd2f/bcrypt-5.0.0-cp38-abi3-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:560ddb6ec730386e7b3b26b8b4c88197aaed924430e7b74666a586ac997249ef", size = 278029 }, + { url = "https://files.pythonhosted.org/packages/17/72/c344825e3b83c5389a369c8a8e58ffe1480b8a699f46c127c34580c4666b/bcrypt-5.0.0-cp38-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:d79e5c65dcc9af213594d6f7f1fa2c98ad3fc10431e7aa53c176b441943efbdd", size = 275907 }, + { url = "https://files.pythonhosted.org/packages/0b/7e/d4e47d2df1641a36d1212e5c0514f5291e1a956a7749f1e595c07a972038/bcrypt-5.0.0-cp38-abi3-manylinux_2_28_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:2b732e7d388fa22d48920baa267ba5d97cca38070b69c0e2d37087b381c681fd", size = 296500 }, + { url = "https://files.pythonhosted.org/packages/0f/c3/0ae57a68be2039287ec28bc463b82e4b8dc23f9d12c0be331f4782e19108/bcrypt-5.0.0-cp38-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:0c8e093ea2532601a6f686edbc2c6b2ec24131ff5c52f7610dd64fa4553b5464", size = 278412 }, + { url = "https://files.pythonhosted.org/packages/45/2b/77424511adb11e6a99e3a00dcc7745034bee89036ad7d7e255a7e47be7d8/bcrypt-5.0.0-cp38-abi3-manylinux_2_34_aarch64.whl", hash = "sha256:5b1589f4839a0899c146e8892efe320c0fa096568abd9b95593efac50a87cb75", size = 275486 }, + { url = "https://files.pythonhosted.org/packages/43/0a/405c753f6158e0f3f14b00b462d8bca31296f7ecfc8fc8bc7919c0c7d73a/bcrypt-5.0.0-cp38-abi3-manylinux_2_34_x86_64.whl", hash = "sha256:89042e61b5e808b67daf24a434d89bab164d4de1746b37a8d173b6b14f3db9ff", size = 277940 }, + { url = "https://files.pythonhosted.org/packages/62/83/b3efc285d4aadc1fa83db385ec64dcfa1707e890eb42f03b127d66ac1b7b/bcrypt-5.0.0-cp38-abi3-musllinux_1_1_aarch64.whl", hash = "sha256:e3cf5b2560c7b5a142286f69bde914494b6d8f901aaa71e453078388a50881c4", size = 310776 }, + { url = "https://files.pythonhosted.org/packages/95/7d/47ee337dacecde6d234890fe929936cb03ebc4c3a7460854bbd9c97780b8/bcrypt-5.0.0-cp38-abi3-musllinux_1_1_x86_64.whl", hash = "sha256:f632fd56fc4e61564f78b46a2269153122db34988e78b6be8b32d28507b7eaeb", size = 312922 }, + { url = "https://files.pythonhosted.org/packages/d6/3a/43d494dfb728f55f4e1cf8fd435d50c16a2d75493225b54c8d06122523c6/bcrypt-5.0.0-cp38-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:801cad5ccb6b87d1b430f183269b94c24f248dddbbc5c1f78b6ed231743e001c", size = 341367 }, + { url = "https://files.pythonhosted.org/packages/55/ab/a0727a4547e383e2e22a630e0f908113db37904f58719dc48d4622139b5c/bcrypt-5.0.0-cp38-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:3cf67a804fc66fc217e6914a5635000259fbbbb12e78a99488e4d5ba445a71eb", size = 359187 }, + { url = "https://files.pythonhosted.org/packages/1b/bb/461f352fdca663524b4643d8b09e8435b4990f17fbf4fea6bc2a90aa0cc7/bcrypt-5.0.0-cp38-abi3-win32.whl", hash = "sha256:3abeb543874b2c0524ff40c57a4e14e5d3a66ff33fb423529c88f180fd756538", size = 153752 }, + { url = "https://files.pythonhosted.org/packages/41/aa/4190e60921927b7056820291f56fc57d00d04757c8b316b2d3c0d1d6da2c/bcrypt-5.0.0-cp38-abi3-win_amd64.whl", hash = "sha256:35a77ec55b541e5e583eb3436ffbbf53b0ffa1fa16ca6782279daf95d146dcd9", size = 150881 }, + { url = "https://files.pythonhosted.org/packages/54/12/cd77221719d0b39ac0b55dbd39358db1cd1246e0282e104366ebbfb8266a/bcrypt-5.0.0-cp38-abi3-win_arm64.whl", hash = "sha256:cde08734f12c6a4e28dc6755cd11d3bdfea608d93d958fffbe95a7026ebe4980", size = 144931 }, + { url = "https://files.pythonhosted.org/packages/5d/ba/2af136406e1c3839aea9ecadc2f6be2bcd1eff255bd451dd39bcf302c47a/bcrypt-5.0.0-cp39-abi3-macosx_10_12_universal2.whl", hash = "sha256:0c418ca99fd47e9c59a301744d63328f17798b5947b0f791e9af3c1c499c2d0a", size = 495313 }, + { url = "https://files.pythonhosted.org/packages/ac/ee/2f4985dbad090ace5ad1f7dd8ff94477fe089b5fab2040bd784a3d5f187b/bcrypt-5.0.0-cp39-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:ddb4e1500f6efdd402218ffe34d040a1196c072e07929b9820f363a1fd1f4191", size = 275290 }, + { url = "https://files.pythonhosted.org/packages/e4/6e/b77ade812672d15cf50842e167eead80ac3514f3beacac8902915417f8b7/bcrypt-5.0.0-cp39-abi3-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:7aeef54b60ceddb6f30ee3db090351ecf0d40ec6e2abf41430997407a46d2254", size = 278253 }, + { url = "https://files.pythonhosted.org/packages/36/c4/ed00ed32f1040f7990dac7115f82273e3c03da1e1a1587a778d8cea496d8/bcrypt-5.0.0-cp39-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:f0ce778135f60799d89c9693b9b398819d15f1921ba15fe719acb3178215a7db", size = 276084 }, + { url = "https://files.pythonhosted.org/packages/e7/c4/fa6e16145e145e87f1fa351bbd54b429354fd72145cd3d4e0c5157cf4c70/bcrypt-5.0.0-cp39-abi3-manylinux_2_28_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:a71f70ee269671460b37a449f5ff26982a6f2ba493b3eabdd687b4bf35f875ac", size = 297185 }, + { url = "https://files.pythonhosted.org/packages/24/b4/11f8a31d8b67cca3371e046db49baa7c0594d71eb40ac8121e2fc0888db0/bcrypt-5.0.0-cp39-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:f8429e1c410b4073944f03bd778a9e066e7fad723564a52ff91841d278dfc822", size = 278656 }, + { url = "https://files.pythonhosted.org/packages/ac/31/79f11865f8078e192847d2cb526e3fa27c200933c982c5b2869720fa5fce/bcrypt-5.0.0-cp39-abi3-manylinux_2_34_aarch64.whl", hash = "sha256:edfcdcedd0d0f05850c52ba3127b1fce70b9f89e0fe5ff16517df7e81fa3cbb8", size = 275662 }, + { url = "https://files.pythonhosted.org/packages/d4/8d/5e43d9584b3b3591a6f9b68f755a4da879a59712981ef5ad2a0ac1379f7a/bcrypt-5.0.0-cp39-abi3-manylinux_2_34_x86_64.whl", hash = "sha256:611f0a17aa4a25a69362dcc299fda5c8a3d4f160e2abb3831041feb77393a14a", size = 278240 }, + { url = "https://files.pythonhosted.org/packages/89/48/44590e3fc158620f680a978aafe8f87a4c4320da81ed11552f0323aa9a57/bcrypt-5.0.0-cp39-abi3-musllinux_1_1_aarch64.whl", hash = "sha256:db99dca3b1fdc3db87d7c57eac0c82281242d1eabf19dcb8a6b10eb29a2e72d1", size = 311152 }, + { url = "https://files.pythonhosted.org/packages/5f/85/e4fbfc46f14f47b0d20493669a625da5827d07e8a88ee460af6cd9768b44/bcrypt-5.0.0-cp39-abi3-musllinux_1_1_x86_64.whl", hash = "sha256:5feebf85a9cefda32966d8171f5db7e3ba964b77fdfe31919622256f80f9cf42", size = 313284 }, + { url = "https://files.pythonhosted.org/packages/25/ae/479f81d3f4594456a01ea2f05b132a519eff9ab5768a70430fa1132384b1/bcrypt-5.0.0-cp39-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:3ca8a166b1140436e058298a34d88032ab62f15aae1c598580333dc21d27ef10", size = 341643 }, + { url = "https://files.pythonhosted.org/packages/df/d2/36a086dee1473b14276cd6ea7f61aef3b2648710b5d7f1c9e032c29b859f/bcrypt-5.0.0-cp39-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:61afc381250c3182d9078551e3ac3a41da14154fbff647ddf52a769f588c4172", size = 359698 }, + { url = "https://files.pythonhosted.org/packages/c0/f6/688d2cd64bfd0b14d805ddb8a565e11ca1fb0fd6817175d58b10052b6d88/bcrypt-5.0.0-cp39-abi3-win32.whl", hash = "sha256:64d7ce196203e468c457c37ec22390f1a61c85c6f0b8160fd752940ccfb3a683", size = 153725 }, + { url = "https://files.pythonhosted.org/packages/9f/b9/9d9a641194a730bda138b3dfe53f584d61c58cd5230e37566e83ec2ffa0d/bcrypt-5.0.0-cp39-abi3-win_amd64.whl", hash = "sha256:64ee8434b0da054d830fa8e89e1c8bf30061d539044a39524ff7dec90481e5c2", size = 150912 }, + { url = "https://files.pythonhosted.org/packages/27/44/d2ef5e87509158ad2187f4dd0852df80695bb1ee0cfe0a684727b01a69e0/bcrypt-5.0.0-cp39-abi3-win_arm64.whl", hash = "sha256:f2347d3534e76bf50bca5500989d6c1d05ed64b440408057a37673282c654927", size = 144953 }, ] [[package]] @@ -984,6 +1129,15 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/fd/ba/56147c165442cc5ba7e82ecf301c9a68353cede498185869e6e02b4c264f/fonttools-4.62.1-py3-none-any.whl", hash = "sha256:7487782e2113861f4ddcc07c3436450659e3caa5e470b27dc2177cade2d8e7fd", size = 1152647, upload-time = "2026-03-13T13:54:22.735Z" }, ] +[[package]] +name = "fqdn" +version = "1.5.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/30/3e/a80a8c077fd798951169626cde3e239adeba7dab75deb3555716415bd9b0/fqdn-1.5.1.tar.gz", hash = "sha256:105ed3677e767fb5ca086a0c1f4bb66ebc3c100be518f0e0d755d9eae164d89f", size = 6015 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/cf/58/8acf1b3e91c58313ce5cb67df61001fc9dcd21be4fadb76c1a2d540e09ed/fqdn-1.5.1-py3-none-any.whl", hash = "sha256:3a179af3761e4df6eb2e026ff9e1a3033d3587bf980a0b1b2e1e5d08d7358014", size = 9121 }, +] + [[package]] name = "fsspec" version = "2026.3.0" @@ -1005,30 +1159,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/f7/ec/67fbef5d497f86283db54c22eec6f6140243aae73265799baaaa19cd17fb/ghp_import-2.1.0-py3-none-any.whl", hash = "sha256:8337dd7b50877f163d4c0289bc1f1c7f127550241988d568c1db512c4324a619", size = 11034, upload-time = "2022-05-02T15:47:14.552Z" }, ] -[[package]] -name = "gitdb" -version = "4.0.12" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "smmap" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/72/94/63b0fc47eb32792c7ba1fe1b694daec9a63620db1e313033d18140c2320a/gitdb-4.0.12.tar.gz", hash = "sha256:5ef71f855d191a3326fcfbc0d5da835f26b13fbcba60c32c21091c349ffdb571", size = 394684, upload-time = "2025-01-02T07:20:46.413Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/a0/61/5c78b91c3143ed5c14207f463aecfc8f9dbb5092fb2869baf37c273b2705/gitdb-4.0.12-py3-none-any.whl", hash = "sha256:67073e15955400952c6565cc3e707c554a4eea2e428946f7a4c162fab9bd9bcf", size = 62794, upload-time = "2025-01-02T07:20:43.624Z" }, -] - -[[package]] -name = "gitpython" -version = "3.1.50" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "gitdb" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/33/f6/354ae6491228b5eb40e10d89c4d13c651fe1cf7556e35ebdded50cff57ce/gitpython-3.1.50.tar.gz", hash = "sha256:80da2d12504d52e1f998772dc5baf6e553f8d2fcfe1fcc226c9d9a2ee3372dcc", size = 219798, upload-time = "2026-05-06T04:01:26.571Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/20/7a/1c6e3562dfd8950adbb11ffbc65d21e7c89d01a6e4f137fa981056de25c5/gitpython-3.1.50-py3-none-any.whl", hash = "sha256:d352abe2908d07355014abdd21ddf798c2a961469239afec4962e9da884858f9", size = 212507, upload-time = "2026-05-06T04:01:23.799Z" }, -] - [[package]] name = "google-crc32c" version = "1.8.0" @@ -1052,15 +1182,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/08/a5/7b059810934a09fb3ccb657e0843813c1fee1183d3bc2c8041800374aa2c/google_crc32c-1.8.0-cp314-cp314-win_amd64.whl", hash = "sha256:d511b3153e7011a27ab6ee6bb3a5404a55b994dc1a7322c0b87b29606d9790e2", size = 34878, upload-time = "2025-12-16T00:35:23.142Z" }, ] -[[package]] -name = "griffelib" -version = "2.0.2" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/9d/82/74f4a3310cdabfbb10da554c3a672847f1ed33c6f61dd472681ce7f1fe67/griffelib-2.0.2.tar.gz", hash = "sha256:3cf20b3bc470e83763ffbf236e0076b1211bac1bc67de13daf494640f2de707e", size = 166461, upload-time = "2026-03-27T11:34:51.091Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/11/8c/c9138d881c79aa0ea9ed83cbd58d5ca75624378b38cee225dcf5c42cc91f/griffelib-2.0.2-py3-none-any.whl", hash = "sha256:925c857658fb1ba40c0772c37acbc2ab650bd794d9c1b9726922e36ea4117ea1", size = 142357, upload-time = "2026-03-27T11:34:46.275Z" }, -] - [[package]] name = "gtfreader" version = "0.2.0" @@ -1074,6 +1195,15 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/b3/56/239b5706022121ddee92b036fe51fd93d0f482c7efe386cf08b4ec894a66/gtfreader-0.2.0-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e98c7c4e5c2e2d44341261ab3bd8bb47846b4cf6b494c97fc57e0b6a886e9b5d", size = 215090, upload-time = "2026-03-18T21:28:56.176Z" }, ] +[[package]] +name = "h11" +version = "0.16.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/01/ee/02a2c011bdab74c6fb3c75474d40b3052059d95df7e73351460c8588d963/h11-0.16.0.tar.gz", hash = "sha256:4e35b956cf45792e4caa5885e69fba00bdbc6ffafbfa020300e549b208ee5ff1", size = 101250 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/04/4b/29cac41a4d98d144bf5f6d33995617b185d14b22401f75ca86f384e87ff1/h11-0.16.0-py3-none-any.whl", hash = "sha256:63cf8bbe7522de3bf65932fda1d9c2772064ffb3dae62d55932da54b31cb6c86", size = 37515 }, +] + [[package]] name = "h5py" version = "3.16.0" @@ -1134,8 +1264,36 @@ wheels = [ ] [[package]] -name = "humanfriendly" -version = "10.0" +name = "httpcore" +version = "1.0.9" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "certifi" }, + { name = "h11" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/06/94/82699a10bca87a5556c9c59b5963f2d039dbd239f25bc2a63907a05a14cb/httpcore-1.0.9.tar.gz", hash = "sha256:6e34463af53fd2ab5d807f399a9b45ea31c3dfa2276f15a2c3f00afff6e176e8", size = 85484 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/7e/f5/f66802a942d491edb555dd61e3a9961140fd64c90bce1eafd741609d334d/httpcore-1.0.9-py3-none-any.whl", hash = "sha256:2d400746a40668fc9dec9810239072b40b4484b640a8c38fd654a024c7a1bf55", size = 78784 }, +] + +[[package]] +name = "httpx" +version = "0.28.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "anyio" }, + { name = "certifi" }, + { name = "httpcore" }, + { name = "idna" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/b1/df/48c586a5fe32a0f01324ee087459e112ebb7224f646c0b5023f5e79e9956/httpx-0.28.1.tar.gz", hash = "sha256:75e98c5f16b0f35b567856f597f06ff2270a374470a5c2392242528e3e3e42fc", size = 141406 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/2a/39/e50c7c3a983047577ee07d2a9e53faf5a69493943ec3f6a384bdc792deb2/httpx-0.28.1-py3-none-any.whl", hash = "sha256:d909fcccc110f8c7faf814ca82a9a4d816bc5a6dbfea25d6591d6985b8ba59ad", size = 73517 }, +] + +[[package]] +name = "iced" +version = "0.6.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "pyreadline3", marker = "sys_platform == 'win32'" }, @@ -1265,6 +1423,18 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/56/6d/0d9848617b9f753b87f214f1c682592f7ca42de085f564352f10f0843026/ipywidgets-8.1.8-py3-none-any.whl", hash = "sha256:ecaca67aed704a338f88f67b1181b58f821ab5dc89c1f0f5ef99db43c1c2921e", size = 139808, upload-time = "2025-11-01T21:18:10.956Z" }, ] +[[package]] +name = "isoduration" +version = "20.11.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "arrow" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/7c/1a/3c8edc664e06e6bd06cce40c6b22da5f1429aa4224d0c590f3be21c91ead/isoduration-20.11.0.tar.gz", hash = "sha256:ac2f9015137935279eac671f94f89eb00584f940f5dc49462a0c4ee692ba1bd9", size = 11649 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/7b/55/e5326141505c5d5e34c5e0935d2908a74e4561eca44108fbfb9c13d2911a/isoduration-20.11.0-py3-none-any.whl", hash = "sha256:b2904c2a4228c3d44f409c8ae8e2370eb21a26f7ac2ec5446df141dde3452042", size = 11321 }, +] + [[package]] name = "jedi" version = "0.19.2" @@ -1311,6 +1481,24 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/7b/91/984aca2ec129e2757d1e4e3c81c3fcda9d0f85b74670a094cc443d9ee949/joblib-1.5.3-py3-none-any.whl", hash = "sha256:5fc3c5039fc5ca8c0276333a188bbd59d6b7ab37fe6632daa76bc7f9ec18e713", size = 309071, upload-time = "2025-12-15T08:41:44.973Z" }, ] +[[package]] +name = "json5" +version = "0.14.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/9c/4b/6f8906aaf67d501e259b0adab4d312945bb7211e8b8d4dcc77c92320edaa/json5-0.14.0.tar.gz", hash = "sha256:b3f492fad9f6cdbced8b7d40b28b9b1c9701c5f561bef0d33b81c2ff433fefcb", size = 52656 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/b8/42/cf027b4ac873b076189d935b135397675dac80cb29acb13e1ab86ad6c631/json5-0.14.0-py3-none-any.whl", hash = "sha256:56cf861bab076b1178eb8c92e1311d273a9b9acea2ccc82c276abf839ebaef3a", size = 36271 }, +] + +[[package]] +name = "jsonpointer" +version = "3.1.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/18/c7/af399a2e7a67fd18d63c40c5e62d3af4e67b836a2107468b6a5ea24c4304/jsonpointer-3.1.1.tar.gz", hash = "sha256:0b801c7db33a904024f6004d526dcc53bbb8a4a0f4e32bfd10beadf60adf1900", size = 9068 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/9e/6a/a83720e953b1682d2d109d3c2dbb0bc9bf28cc1cbc205be4ef4be5da709d/jsonpointer-3.1.1-py3-none-any.whl", hash = "sha256:8ff8b95779d071ba472cf5bc913028df06031797532f08a7d5b602d8b2a488ca", size = 7659 }, +] + [[package]] name = "jsonschema" version = "4.26.0" @@ -1326,6 +1514,19 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/69/90/f63fb5873511e014207a475e2bb4e8b2e570d655b00ac19a9a0ca0a385ee/jsonschema-4.26.0-py3-none-any.whl", hash = "sha256:d489f15263b8d200f8387e64b4c3a75f06629559fb73deb8fdfb525f2dab50ce", size = 90630, upload-time = "2026-01-07T13:41:05.306Z" }, ] +[package.optional-dependencies] +format-nongpl = [ + { name = "fqdn" }, + { name = "idna" }, + { name = "isoduration" }, + { name = "jsonpointer" }, + { name = "rfc3339-validator" }, + { name = "rfc3986-validator" }, + { name = "rfc3987-syntax" }, + { name = "uri-template" }, + { name = "webcolors" }, +] + [[package]] name = "jsonschema-specifications" version = "2025.9.1" @@ -1338,6 +1539,23 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/41/45/1a4ed80516f02155c51f51e8cedb3c1902296743db0bbc66608a0db2814f/jsonschema_specifications-2025.9.1-py3-none-any.whl", hash = "sha256:98802fee3a11ee76ecaca44429fda8a41bff98b00a0f2838151b113f210cc6fe", size = 18437, upload-time = "2025-09-08T01:34:57.871Z" }, ] +[[package]] +name = "jupyter" +version = "1.1.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "ipykernel" }, + { name = "ipywidgets" }, + { name = "jupyter-console" }, + { name = "jupyterlab" }, + { name = "nbconvert" }, + { name = "notebook" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/58/f3/af28ea964ab8bc1e472dba2e82627d36d470c51f5cd38c37502eeffaa25e/jupyter-1.1.1.tar.gz", hash = "sha256:d55467bceabdea49d7e3624af7e33d59c37fff53ed3a350e1ac957bed731de7a", size = 5714959 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/38/64/285f20a31679bf547b75602702f7800e74dbabae36ef324f716c02804753/jupyter-1.1.1-py2.py3-none-any.whl", hash = "sha256:7a59533c22af65439b24bbe60373a4e95af8f16ac65a6c00820ad378e3f7cc83", size = 2657 }, +] + [[package]] name = "jupyter-client" version = "8.8.0" @@ -1354,6 +1572,25 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/2d/0b/ceb7694d864abc0a047649aec263878acb9f792e1fec3e676f22dc9015e3/jupyter_client-8.8.0-py3-none-any.whl", hash = "sha256:f93a5b99c5e23a507b773d3a1136bd6e16c67883ccdbd9a829b0bbdb98cd7d7a", size = 107371, upload-time = "2026-01-08T13:55:45.562Z" }, ] +[[package]] +name = "jupyter-console" +version = "6.6.3" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "ipykernel" }, + { name = "ipython" }, + { name = "jupyter-client" }, + { name = "jupyter-core" }, + { name = "prompt-toolkit" }, + { name = "pygments" }, + { name = "pyzmq" }, + { name = "traitlets" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/bd/2d/e2fd31e2fc41c14e2bcb6c976ab732597e907523f6b2420305f9fc7fdbdb/jupyter_console-6.6.3.tar.gz", hash = "sha256:566a4bf31c87adbfadf22cdf846e3069b59a71ed5da71d6ba4d8aaad14a53539", size = 34363 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/ca/77/71d78d58f15c22db16328a476426f7ac4a60d3a5a7ba3b9627ee2f7903d4/jupyter_console-6.6.3-py3-none-any.whl", hash = "sha256:309d33409fcc92ffdad25f0bcdf9a4a9daa61b6f341177570fdac03de5352485", size = 24510 }, +] + [[package]] name = "jupyter-core" version = "5.9.1" @@ -1368,56 +1605,136 @@ wheels = [ ] [[package]] -name = "jupyterlab-pygments" -version = "0.3.0" +name = "jupyter-events" +version = "0.12.1" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/90/51/9187be60d989df97f5f0aba133fa54e7300f17616e065d1ada7d7646b6d6/jupyterlab_pygments-0.3.0.tar.gz", hash = "sha256:721aca4d9029252b11cfa9d185e5b5af4d54772bb8072f9b7036f4170054d35d", size = 512900, upload-time = "2023-11-23T09:26:37.44Z" } +dependencies = [ + { name = "jsonschema", extra = ["format-nongpl"] }, + { name = "packaging" }, + { name = "python-json-logger" }, + { name = "pyyaml" }, + { name = "referencing" }, + { name = "rfc3339-validator" }, + { name = "rfc3986-validator" }, + { name = "traitlets" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/18/f8/475c4241b2b75af0deaae453ed003c6c851766dbc44d332d8baf245dc931/jupyter_events-0.12.1.tar.gz", hash = "sha256:faff25f77218335752f35f23c5fe6e4a392a7bd99a5939ccb9b8fbf594636cf3", size = 62854 } wheels = [ - { url = "https://files.pythonhosted.org/packages/b1/dd/ead9d8ea85bf202d90cc513b533f9c363121c7792674f78e0d8a854b63b4/jupyterlab_pygments-0.3.0-py3-none-any.whl", hash = "sha256:841a89020971da1d8693f1a99997aefc5dc424bb1b251fd6322462a1b8842780", size = 15884, upload-time = "2023-11-23T09:26:34.325Z" }, + { url = "https://files.pythonhosted.org/packages/eb/6c/6fcde0c8f616ed360ffd3587f7db9e225a7e62b583a04494d2f069cf64ea/jupyter_events-0.12.1-py3-none-any.whl", hash = "sha256:c366585253f537a627da52fa7ca7410c5b5301fe893f511e7b077c2d93ec8bcf", size = 19512 }, ] [[package]] -name = "jupyterlab-widgets" -version = "3.0.16" +name = "jupyter-lsp" +version = "2.3.1" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/26/2d/ef58fed122b268c69c0aa099da20bc67657cdfb2e222688d5731bd5b971d/jupyterlab_widgets-3.0.16.tar.gz", hash = "sha256:423da05071d55cf27a9e602216d35a3a65a3e41cdf9c5d3b643b814ce38c19e0", size = 897423, upload-time = "2025-11-01T21:11:29.724Z" } +dependencies = [ + { name = "jupyter-server" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/36/ff/1e4a61f5170a9a1d978f3ac3872449de6c01fc71eaf89657824c878b1549/jupyter_lsp-2.3.1.tar.gz", hash = "sha256:fdf8a4aa7d85813976d6e29e95e6a2c8f752701f926f2715305249a3829805a6", size = 55677 } wheels = [ - { url = "https://files.pythonhosted.org/packages/ab/b5/36c712098e6191d1b4e349304ef73a8d06aed77e56ceaac8c0a306c7bda1/jupyterlab_widgets-3.0.16-py3-none-any.whl", hash = "sha256:45fa36d9c6422cf2559198e4db481aa243c7a32d9926b500781c830c80f7ecf8", size = 914926, upload-time = "2025-11-01T21:11:28.008Z" }, + { url = "https://files.pythonhosted.org/packages/23/e8/9d61dcbd1dce8ef418f06befd4ac084b4720429c26b0b1222bc218685eff/jupyter_lsp-2.3.1-py3-none-any.whl", hash = "sha256:71b954d834e85ff3096400554f2eefaf7fe37053036f9a782b0f7c5e42dadb81", size = 77513 }, ] [[package]] -name = "jupytext" -version = "1.19.1" +name = "jupyter-server" +version = "2.17.0" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "markdown-it-py" }, - { name = "mdit-py-plugins" }, + { name = "anyio" }, + { name = "argon2-cffi" }, + { name = "jinja2" }, + { name = "jupyter-client" }, + { name = "jupyter-core" }, + { name = "jupyter-events" }, + { name = "jupyter-server-terminals" }, + { name = "nbconvert" }, { name = "nbformat" }, { name = "packaging" }, - { name = "pyyaml" }, + { name = "prometheus-client" }, + { name = "pywinpty", marker = "os_name == 'nt'" }, + { name = "pyzmq" }, + { name = "send2trash" }, + { name = "terminado" }, + { name = "tornado" }, + { name = "traitlets" }, + { name = "websocket-client" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/13/a5/80c02f307c8ce863cb33e27daf049315e9d96979e14eead700923b5ec9cc/jupytext-1.19.1.tar.gz", hash = "sha256:82587c07e299173c70ed5e8ec7e75183edf1be289ed518bab49ad0d4e3d5f433", size = 4307829, upload-time = "2026-01-25T21:35:13.276Z" } +sdist = { url = "https://files.pythonhosted.org/packages/5b/ac/e040ec363d7b6b1f11304cc9f209dac4517ece5d5e01821366b924a64a50/jupyter_server-2.17.0.tar.gz", hash = "sha256:c38ea898566964c888b4772ae1ed58eca84592e88251d2cfc4d171f81f7e99d5", size = 731949 } wheels = [ - { url = "https://files.pythonhosted.org/packages/16/5a/736dd2f4535dbf3bf26523f9158c011389ef88dd06ec2eef67fd744f1c7b/jupytext-1.19.1-py3-none-any.whl", hash = "sha256:d8975035155d034bdfde5c0c37891425314b7ea8d3a6c4b5d18c294348714cd9", size = 170478, upload-time = "2026-01-25T21:35:11.17Z" }, + { url = "https://files.pythonhosted.org/packages/92/80/a24767e6ca280f5a49525d987bf3e4d7552bf67c8be07e8ccf20271f8568/jupyter_server-2.17.0-py3-none-any.whl", hash = "sha256:e8cb9c7db4251f51ed307e329b81b72ccf2056ff82d50524debde1ee1870e13f", size = 388221 }, ] [[package]] -name = "keras" -version = "3.14.1" +name = "jupyter-server-terminals" +version = "0.5.4" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "absl-py" }, - { name = "h5py" }, - { name = "ml-dtypes" }, - { name = "namex" }, - { name = "numpy" }, - { name = "optree" }, + { name = "pywinpty", marker = "os_name == 'nt'" }, + { name = "terminado" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/f4/a7/bcd0a9b0cbba88986fe944aaaf91bfda603e5a50bda8ed15123f381a3b2f/jupyter_server_terminals-0.5.4.tar.gz", hash = "sha256:bbda128ed41d0be9020349f9f1f2a4ab9952a73ed5f5ac9f1419794761fb87f5", size = 31770 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/d1/2d/6674563f71c6320841fc300911a55143925112a72a883e2ca71fba4c618d/jupyter_server_terminals-0.5.4-py3-none-any.whl", hash = "sha256:55be353fc74a80bc7f3b20e6be50a55a61cd525626f578dcb66a5708e2007d14", size = 13704 }, +] + +[[package]] +name = "jupyterlab" +version = "4.5.7" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "async-lru" }, + { name = "httpx" }, + { name = "ipykernel" }, + { name = "jinja2" }, + { name = "jupyter-core" }, + { name = "jupyter-lsp" }, + { name = "jupyter-server" }, + { name = "jupyterlab-server" }, + { name = "notebook-shim" }, { name = "packaging" }, - { name = "rich" }, + { name = "setuptools" }, + { name = "tornado" }, + { name = "traitlets" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/2b/22/8440ec827762146e7cdecf04335bd348795899d29dc6ae82238707353a2c/jupyterlab-4.5.7.tar.gz", hash = "sha256:55a9822c4754da305f41e113452c68383e214dcf96de760146af89ce5d5117b0", size = 23992763 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/3d/aa/537b8f7d80e799af19af35fb3ddfc970b951088a13c57dd9387dcfbb7f61/jupyterlab-4.5.7-py3-none-any.whl", hash = "sha256:fba4cb0e2c44a52859669d8c98b45de029d5e515f8407bf8534d2a8fc5f0964d", size = 12450123 }, ] -sdist = { url = "https://files.pythonhosted.org/packages/35/e7/97a7664581b73e4f9ff1d3a767a493b6ac5d3e0ed1926bd2b6b2c8bbccd7/keras-3.14.1.tar.gz", hash = "sha256:ef479173102ad29db89b53c232efdc3fb5ad57c28bc27ead59f3e78a1eecd05b", size = 1263647, upload-time = "2026-05-07T21:43:35.112Z" } + +[[package]] +name = "jupyterlab-pygments" +version = "0.3.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/90/51/9187be60d989df97f5f0aba133fa54e7300f17616e065d1ada7d7646b6d6/jupyterlab_pygments-0.3.0.tar.gz", hash = "sha256:721aca4d9029252b11cfa9d185e5b5af4d54772bb8072f9b7036f4170054d35d", size = 512900 } wheels = [ - { url = "https://files.pythonhosted.org/packages/02/03/184267c1d09783dd070f1ddfd0d4beb7503139dfc7bd75b422867cf282fd/keras-3.14.1-py3-none-any.whl", hash = "sha256:ebd2c14d2af3c9de18083604d408483996407fc7d2f9ebd1d565961f96608c29", size = 1628606, upload-time = "2026-05-07T21:43:32.737Z" }, + { url = "https://files.pythonhosted.org/packages/b1/dd/ead9d8ea85bf202d90cc513b533f9c363121c7792674f78e0d8a854b63b4/jupyterlab_pygments-0.3.0-py3-none-any.whl", hash = "sha256:841a89020971da1d8693f1a99997aefc5dc424bb1b251fd6322462a1b8842780", size = 15884 }, +] + +[[package]] +name = "jupyterlab-server" +version = "2.28.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "babel" }, + { name = "jinja2" }, + { name = "json5" }, + { name = "jsonschema" }, + { name = "jupyter-server" }, + { name = "packaging" }, + { name = "requests" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/d6/2c/90153f189e421e93c4bb4f9e3f59802a1f01abd2ac5cf40b152d7f735232/jupyterlab_server-2.28.0.tar.gz", hash = "sha256:35baa81898b15f93573e2deca50d11ac0ae407ebb688299d3a5213265033712c", size = 76996 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/e0/07/a000fe835f76b7e1143242ab1122e6362ef1c03f23f83a045c38859c2ae0/jupyterlab_server-2.28.0-py3-none-any.whl", hash = "sha256:e4355b148fdcf34d312bbbc80f22467d6d20460e8b8736bf235577dd18506968", size = 59830 }, +] + +[[package]] +name = "jupyterlab-widgets" +version = "3.0.16" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/26/2d/ef58fed122b268c69c0aa099da20bc67657cdfb2e222688d5731bd5b971d/jupyterlab_widgets-3.0.16.tar.gz", hash = "sha256:423da05071d55cf27a9e602216d35a3a65a3e41cdf9c5d3b643b814ce38c19e0", size = 897423 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/ab/b5/36c712098e6191d1b4e349304ef73a8d06aed77e56ceaac8c0a306c7bda1/jupyterlab_widgets-3.0.16-py3-none-any.whl", hash = "sha256:45fa36d9c6422cf2559198e4db481aa243c7a32d9926b500781c830c80f7ecf8", size = 914926 }, ] [[package]] @@ -1535,6 +1852,15 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/47/15/7d459a8e2a43f17c1db129b997b7bb7aa7f000a0967bab87c28b8c5cf448/leidenalg-0.11.0-cp38-abi3-win_amd64.whl", hash = "sha256:5e789c0960008d185413344a402d0587580c441644d4d20bf57c96f25d4d1710", size = 1990321, upload-time = "2025-10-31T17:14:40.892Z" }, ] +[[package]] +name = "lark" +version = "1.3.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/da/34/28fff3ab31ccff1fd4f6c7c7b0ceb2b6968d8ea4950663eadcb5720591a0/lark-1.3.1.tar.gz", hash = "sha256:b426a7a6d6d53189d318f2b6236ab5d6429eaf09259f1ca33eb716eed10d2905", size = 382732 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/82/3d/14ce75ef66813643812f3093ab17e46d3a206942ce7376d31ec2d36229e7/lark-1.3.1-py3-none-any.whl", hash = "sha256:c629b661023a014c37da873b4ff58a817398d12635d3bbb2c5a03be7fe5d1e12", size = 113151 }, +] + [[package]] name = "llvmlite" version = "0.47.0" @@ -1586,15 +1912,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/03/0a/4f6fed21aa246c6b49b561ca55facacc2a44b87d65b8b92362a8e99ba202/loguru-0.7.2-py3-none-any.whl", hash = "sha256:003d71e3d3ed35f0f8984898359d65b79e5b21943f78af86aa5491210429b8eb", size = 62549, upload-time = "2023-09-11T15:24:35.016Z" }, ] -[[package]] -name = "markdown" -version = "3.10.2" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/2b/f4/69fa6ed85ae003c2378ffa8f6d2e3234662abd02c10d216c0ba96081a238/markdown-3.10.2.tar.gz", hash = "sha256:994d51325d25ad8aa7ce4ebaec003febcce822c3f8c911e3b17c52f7f589f950", size = 368805, upload-time = "2026-02-09T14:57:26.942Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/de/1f/77fa3081e4f66ca3576c896ae5d31c3002ac6607f9747d2e3aa49227e464/markdown-3.10.2-py3-none-any.whl", hash = "sha256:e91464b71ae3ee7afd3017d9f358ef0baf158fd9a298db92f1d4761133824c36", size = 108180, upload-time = "2026-02-09T14:57:25.787Z" }, -] - [[package]] name = "markdown-it-py" version = "4.0.0" @@ -1736,18 +2053,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/af/33/ee4519fa02ed11a94aef9559552f3b17bb863f2ecfe1a35dc7f548cde231/matplotlib_inline-0.2.1-py3-none-any.whl", hash = "sha256:d56ce5156ba6085e00a9d54fead6ed29a9c47e215cd1bba2e976ef39f5710a76", size = 9516, upload-time = "2025-10-23T09:00:20.675Z" }, ] -[[package]] -name = "mdit-py-plugins" -version = "0.5.0" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "markdown-it-py" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/b2/fd/a756d36c0bfba5f6e39a1cdbdbfdd448dc02692467d83816dff4592a1ebc/mdit_py_plugins-0.5.0.tar.gz", hash = "sha256:f4918cb50119f50446560513a8e311d574ff6aaed72606ddae6d35716fe809c6", size = 44655, upload-time = "2025-08-11T07:25:49.083Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/fb/86/dd6e5db36df29e76c7a7699123569a4a18c1623ce68d826ed96c62643cae/mdit_py_plugins-0.5.0-py3-none-any.whl", hash = "sha256:07a08422fc1936a5d26d146759e9155ea466e842f5ab2f7d2266dd084c8dab1f", size = 57205, upload-time = "2025-08-11T07:25:47.597Z" }, -] - [[package]] name = "mdurl" version = "0.1.2" @@ -1773,15 +2078,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/93/84/648dc9326dbb31d2dbcbe30d089f2f126a274f8e0b8a539818b9d1bd6f55/memelite-0.2.0-py3-none-any.whl", hash = "sha256:6ccb38963e09b938b8412a05cab8244caa87e03e44c9c985af6a913b0d2ef5f0", size = 23419, upload-time = "2025-06-05T10:52:39.48Z" }, ] -[[package]] -name = "mergedeep" -version = "1.3.4" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/3a/41/580bb4006e3ed0361b8151a01d324fb03f420815446c7def45d02f74c270/mergedeep-1.3.4.tar.gz", hash = "sha256:0096d52e9dad9939c3d975a774666af186eda617e6ca84df4c94dec30004f2a8", size = 4661, upload-time = "2021-02-05T18:55:30.623Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/2c/19/04f9b178c2d8a15b076c8b5140708fa6ffc5601fb6f1e975537072df5b2a/mergedeep-1.3.4-py3-none-any.whl", hash = "sha256:70775750742b25c0d8f36c55aed03d24c3384d17c951b3175d898bd778ef0307", size = 6354, upload-time = "2021-02-05T18:55:29.583Z" }, -] - [[package]] name = "mistune" version = "3.2.0" @@ -1792,183 +2088,8 @@ wheels = [ ] [[package]] -name = "mkdocs" -version = "1.6.1" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "click" }, - { name = "colorama", marker = "sys_platform == 'win32'" }, - { name = "ghp-import" }, - { name = "jinja2" }, - { name = "markdown" }, - { name = "markupsafe" }, - { name = "mergedeep" }, - { name = "mkdocs-get-deps" }, - { name = "packaging" }, - { name = "pathspec" }, - { name = "pyyaml" }, - { name = "pyyaml-env-tag" }, - { name = "watchdog" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/bc/c6/bbd4f061bd16b378247f12953ffcb04786a618ce5e904b8c5a01a0309061/mkdocs-1.6.1.tar.gz", hash = "sha256:7b432f01d928c084353ab39c57282f29f92136665bdd6abf7c1ec8d822ef86f2", size = 3889159, upload-time = "2024-08-30T12:24:06.899Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/22/5b/dbc6a8cddc9cfa9c4971d59fb12bb8d42e161b7e7f8cc89e49137c5b279c/mkdocs-1.6.1-py3-none-any.whl", hash = "sha256:db91759624d1647f3f34aa0c3f327dd2601beae39a366d6e064c03468d35c20e", size = 3864451, upload-time = "2024-08-30T12:24:05.054Z" }, -] - -[[package]] -name = "mkdocs-autorefs" -version = "1.4.4" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "markdown" }, - { name = "markupsafe" }, - { name = "mkdocs" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/52/c0/f641843de3f612a6b48253f39244165acff36657a91cc903633d456ae1ac/mkdocs_autorefs-1.4.4.tar.gz", hash = "sha256:d54a284f27a7346b9c38f1f852177940c222da508e66edc816a0fa55fc6da197", size = 56588, upload-time = "2026-02-10T15:23:55.105Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/28/de/a3e710469772c6a89595fc52816da05c1e164b4c866a89e3cb82fb1b67c5/mkdocs_autorefs-1.4.4-py3-none-any.whl", hash = "sha256:834ef5408d827071ad1bc69e0f39704fa34c7fc05bc8e1c72b227dfdc5c76089", size = 25530, upload-time = "2026-02-10T15:23:53.817Z" }, -] - -[[package]] -name = "mkdocs-click" -version = "0.9.0" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "click" }, - { name = "markdown" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/a1/c7/8c25f3a3b379def41e6d0bb5c4beeab7aa8a394b17e749f498504102cfa5/mkdocs_click-0.9.0.tar.gz", hash = "sha256:6050917628d4740517541422b607404d044117bc31b770c4f9e9e1939a50c908", size = 18720, upload-time = "2025-04-07T16:59:36.387Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/e9/fc/9124ab36e2341e78d8d9c669511bd70f52ea0de8105760c31fabec1f9396/mkdocs_click-0.9.0-py3-none-any.whl", hash = "sha256:5208e828f4f68f63c847c1ef7be48edee9964090390afc8f5b3d4cbe5ea9bbed", size = 15104, upload-time = "2025-04-07T16:59:34.807Z" }, -] - -[[package]] -name = "mkdocs-gen-files" -version = "0.6.1" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "mkdocs" }, - { name = "properdocs" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/43/43/428f312149c161cae557eecd35f3c4a82b867998b1d47fb29fdfe927be26/mkdocs_gen_files-0.6.1.tar.gz", hash = "sha256:57d7ff2229e23d077e46d14a33db6d37c8823f6ce1a503c874c1764a71679763", size = 8746, upload-time = "2026-03-16T23:26:09.31Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/ee/1b/3075eb67fe66e19db059f0a25744c4e56978a309603a20e1d3353d545b5e/mkdocs_gen_files-0.6.1-py3-none-any.whl", hash = "sha256:b3182bfc6219e35b8d26658cb988368659d5d023aac30c2a819247558fc12189", size = 8282, upload-time = "2026-03-16T23:26:08.292Z" }, -] - -[[package]] -name = "mkdocs-get-deps" -version = "0.2.2" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "mergedeep" }, - { name = "platformdirs" }, - { name = "pyyaml" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/ce/25/b3cccb187655b9393572bde9b09261d267c3bf2f2cdabe347673be5976a6/mkdocs_get_deps-0.2.2.tar.gz", hash = "sha256:8ee8d5f316cdbbb2834bc1df6e69c08fe769a83e040060de26d3c19fad3599a1", size = 11047, upload-time = "2026-03-10T02:46:33.632Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/88/29/744136411e785c4b0b744d5413e56555265939ab3a104c6a4b719dad33fd/mkdocs_get_deps-0.2.2-py3-none-any.whl", hash = "sha256:e7878cbeac04860b8b5e0ca31d3abad3df9411a75a32cde82f8e44b6c16ff650", size = 9555, upload-time = "2026-03-10T02:46:32.256Z" }, -] - -[[package]] -name = "mkdocs-jupyter" -version = "0.26.3" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "ipykernel" }, - { name = "jupytext" }, - { name = "mkdocs" }, - { name = "mkdocs-material" }, - { name = "nbconvert" }, - { name = "pygments" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/00/aa/f8d15409a9a3112486994a80d5a975694c7d145c4f8b5b484aeb383420ef/mkdocs_jupyter-0.26.3.tar.gz", hash = "sha256:e1e8bd48a1b96542e84e3028e3066112bac7b94d95ab69f8b91305c84003ca26", size = 1628353, upload-time = "2026-04-17T18:56:31.517Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/13/95/cf3f7fe4910cf0365fa8ea0c731f4b8a624d97cd76ea777913ac8d0868e2/mkdocs_jupyter-0.26.3-py3-none-any.whl", hash = "sha256:cd6644fb578131157194d750fd4d10fc2fd8f1e84e00036ee62df3b5b4b84c82", size = 1459740, upload-time = "2026-04-17T18:56:30.031Z" }, -] - -[[package]] -name = "mkdocs-literate-nav" -version = "0.6.3" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "mkdocs" }, - { name = "properdocs" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/01/af/dd3776a7a713f798f79bec7eb9c661d5cfb83ddc17d9a3667595e53e1559/mkdocs_literate_nav-0.6.3.tar.gz", hash = "sha256:edbaca22343f861fe4e34aac47d55a0c9955c640dbf02eea99fe631e914cf9ee", size = 17526, upload-time = "2026-03-16T23:26:50.688Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/4e/2c/bcf1ae903975ad6f169abb05c1eb0f94395478364deb89270cf034081b29/mkdocs_literate_nav-0.6.3-py3-none-any.whl", hash = "sha256:2c421561280fa9184f88cbf399bebbd4cc17ee507e978a31ce11fd6f3aabf233", size = 13355, upload-time = "2026-03-16T23:26:49.562Z" }, -] - -[[package]] -name = "mkdocs-material" -version = "9.7.6" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "babel" }, - { name = "backrefs" }, - { name = "colorama" }, - { name = "jinja2" }, - { name = "markdown" }, - { name = "mkdocs" }, - { name = "mkdocs-material-extensions" }, - { name = "paginate" }, - { name = "pygments" }, - { name = "pymdown-extensions" }, - { name = "requests" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/45/29/6d2bcf41ae40802c4beda2432396fff97b8456fb496371d1bc7aad6512ec/mkdocs_material-9.7.6.tar.gz", hash = "sha256:00bdde50574f776d328b1862fe65daeaf581ec309bd150f7bff345a098c64a69", size = 4097959, upload-time = "2026-03-19T15:41:58.161Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/2c/01/bc663630c510822c95c47a66af9fa7a443c295b47d5f041e5e6ae62ef659/mkdocs_material-9.7.6-py3-none-any.whl", hash = "sha256:71b84353921b8ea1ba84fe11c50912cc512da8fe0881038fcc9a0761c0e635ba", size = 9305470, upload-time = "2026-03-19T15:41:55.217Z" }, -] - -[[package]] -name = "mkdocs-material-extensions" -version = "1.3.1" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/79/9b/9b4c96d6593b2a541e1cb8b34899a6d021d208bb357042823d4d2cabdbe7/mkdocs_material_extensions-1.3.1.tar.gz", hash = "sha256:10c9511cea88f568257f960358a467d12b970e1f7b2c0e5fb2bb48cab1928443", size = 11847, upload-time = "2023-11-22T19:09:45.208Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/5b/54/662a4743aa81d9582ee9339d4ffa3c8fd40a4965e033d77b9da9774d3960/mkdocs_material_extensions-1.3.1-py3-none-any.whl", hash = "sha256:adff8b62700b25cb77b53358dad940f3ef973dd6db797907c49e3c2ef3ab4e31", size = 8728, upload-time = "2023-11-22T19:09:43.465Z" }, -] - -[[package]] -name = "mkdocstrings" -version = "1.0.4" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "jinja2" }, - { name = "markdown" }, - { name = "markupsafe" }, - { name = "mkdocs" }, - { name = "mkdocs-autorefs" }, - { name = "pymdown-extensions" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/1d/5d/f888d4d3eb31359b327bc9b17a212d6ef03fe0b0682fbb3fc2cb849fb12b/mkdocstrings-1.0.4.tar.gz", hash = "sha256:3969a6515b77db65fd097b53c1b7aa4ae840bd71a2ee62a6a3e89503446d7172", size = 100088, upload-time = "2026-04-15T09:16:53.376Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/6e/94/be70f8ee9c45f2f62b39a1f0e9303bc20e138a8f3b8e50ffd89498e177e1/mkdocstrings-1.0.4-py3-none-any.whl", hash = "sha256:63464b4b29053514f32a1dbbf604e52876d5e638111b0c295ab7ed3cac73ca9b", size = 35560, upload-time = "2026-04-15T09:16:51.436Z" }, -] - -[package.optional-dependencies] -python = [ - { name = "mkdocstrings-python" }, -] - -[[package]] -name = "mkdocstrings-python" -version = "2.0.3" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "griffelib" }, - { name = "mkdocs-autorefs" }, - { name = "mkdocstrings" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/29/33/c225eaf898634bdda489a6766fc35d1683c640bffe0e0acd10646b13536d/mkdocstrings_python-2.0.3.tar.gz", hash = "sha256:c518632751cc869439b31c9d3177678ad2bfa5c21b79b863956ad68fc92c13b8", size = 199083, upload-time = "2026-02-20T10:38:36.368Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/32/28/79f0f8de97cce916d5ae88a7bee1ad724855e83e6019c0b4d5b3fabc80f3/mkdocstrings_python-2.0.3-py3-none-any.whl", hash = "sha256:0b83513478bdfd803ff05aa43e9b1fca9dd22bcd9471f09ca6257f009bc5ee12", size = 104779, upload-time = "2026-02-20T10:38:34.517Z" }, -] - -[[package]] -name = "ml-dtypes" -version = "0.4.1" +name = "msgpack" +version = "1.1.2" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "numpy" }, @@ -2164,6 +2285,34 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/88/b2/d0896bdcdc8d28a7fc5717c305f1a861c26e18c05047949fb371034d98bd/nodeenv-1.10.0-py2.py3-none-any.whl", hash = "sha256:5bb13e3eed2923615535339b3c620e76779af4cb4c6a90deccc9e36b274d3827", size = 23438, upload-time = "2025-12-20T14:08:52.782Z" }, ] +[[package]] +name = "notebook" +version = "7.5.6" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "jupyter-server" }, + { name = "jupyterlab" }, + { name = "jupyterlab-server" }, + { name = "notebook-shim" }, + { name = "tornado" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/2a/c2/cf59bd2e6f2c8b976b52477e3e53bf6f97bc714ed046a51821afb428eaee/notebook-7.5.6.tar.gz", hash = "sha256:621174aade80108f0020b0f00738000b215f75fa3cd90771ad7aa0f24536a4e1", size = 14170814 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/e9/d6/1fd0646b9bbd9efbb0b8ae21b2325fbef515769a5621c03e31d8eb8da587/notebook-7.5.6-py3-none-any.whl", hash = "sha256:4dde3f8fb55fa8fb7946d58c6e869ce9baf46d00fc070664f62604569d0faca0", size = 14581730 }, +] + +[[package]] +name = "notebook-shim" +version = "0.2.4" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "jupyter-server" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/54/d2/92fa3243712b9a3e8bafaf60aac366da1cada3639ca767ff4b5b3654ec28/notebook_shim-0.2.4.tar.gz", hash = "sha256:b4b2cfa1b65d98307ca24361f5b30fe785b53c3fd07b7a47e89acb5e6ac638cb", size = 13167 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/f9/33/bd5b9137445ea4b680023eb0469b2bb969d61303dedb2aac6560ff3d14a1/notebook_shim-0.2.4-py3-none-any.whl", hash = "sha256:411a5be4e9dc882a074ccbcae671eda64cceb068767e9a3419096986560e1cef", size = 13307 }, +] + [[package]] name = "numba" version = "0.65.0" @@ -2465,15 +2614,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/7a/c2/920ef838e2f0028c8262f16101ec09ebd5969864e5a64c4c05fad0617c56/packaging-26.1-py3-none-any.whl", hash = "sha256:5d9c0669c6285e491e0ced2eee587eaf67b670d94a19e94e3984a481aba6802f", size = 95831, upload-time = "2026-04-14T21:12:47.56Z" }, ] -[[package]] -name = "paginate" -version = "0.5.7" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/ec/46/68dde5b6bc00c1296ec6466ab27dddede6aec9af1b99090e1107091b3b84/paginate-0.5.7.tar.gz", hash = "sha256:22bd083ab41e1a8b4f3690544afb2c60c25e5c9a63a30fa2f483f6c60c8e5945", size = 19252, upload-time = "2024-08-25T14:17:24.139Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/90/96/04b8e52da071d28f5e21a805b19cb9390aa17a47462ac87f5e2696b9566d/paginate-0.5.7-py2.py3-none-any.whl", hash = "sha256:b885e2af73abcf01d9559fd5216b57ef722f8c42affbb63942377668e35c7591", size = 13746, upload-time = "2024-08-25T14:17:22.55Z" }, -] - [[package]] name = "pandas" version = "2.1.1" @@ -2528,15 +2668,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/b6/61/fae042894f4296ec49e3f193aff5d7c18440da9e48102c3315e1bc4519a7/parso-0.8.6-py2.py3-none-any.whl", hash = "sha256:2c549f800b70a5c4952197248825584cb00f033b29c692671d3bf08bf380baff", size = 106894, upload-time = "2026-02-09T15:45:21.391Z" }, ] -[[package]] -name = "pathspec" -version = "1.0.4" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/fa/36/e27608899f9b8d4dff0617b2d9ab17ca5608956ca44461ac14ac48b44015/pathspec-1.0.4.tar.gz", hash = "sha256:0210e2ae8a21a9137c0d470578cb0e595af87edaa6ebf12ff176f14a02e0e645", size = 131200, upload-time = "2026-01-27T03:59:46.938Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/ef/3c/2c197d226f9ea224a9ab8d197933f9da0ae0aac5b6e0f884e2b8d9c8e9f7/pathspec-1.0.4-py3-none-any.whl", hash = "sha256:fb6ae2fd4e7c921a165808a552060e722767cfa526f99ca5156ed2ce45a5c723", size = 55206, upload-time = "2026-01-27T03:59:45.137Z" }, -] - [[package]] name = "pexpect" version = "4.9.0" @@ -2629,6 +2760,7 @@ wheels = [ [[package]] name = "plotnado" +version = "0.4.dev13" source = { editable = "." } dependencies = [ { name = "loguru" }, @@ -2650,16 +2782,10 @@ dependencies = [ all = [ { name = "capcruncher" }, { name = "cooler" }, + { name = "ipykernel" }, { name = "ipywidgets" }, - { name = "mkdocs" }, - { name = "mkdocs-click" }, - { name = "mkdocs-gen-files" }, - { name = "mkdocs-jupyter" }, - { name = "mkdocs-literate-nav" }, - { name = "mkdocs-material" }, - { name = "mkdocstrings", extra = ["python"] }, + { name = "jupyter" }, { name = "pre-commit" }, - { name = "pymdown-extensions" }, { name = "pytest" }, { name = "pytest-assume" }, { name = "pytest-cov" }, @@ -2680,14 +2806,11 @@ dev = [ { name = "pytest-mock" }, ] docs = [ - { name = "mkdocs" }, - { name = "mkdocs-click" }, - { name = "mkdocs-gen-files" }, - { name = "mkdocs-jupyter" }, - { name = "mkdocs-literate-nav" }, - { name = "mkdocs-material" }, - { name = "mkdocstrings", extra = ["python"] }, - { name = "pymdown-extensions" }, + { name = "capcruncher" }, + { name = "cooler" }, + { name = "ipykernel" }, + { name = "jupyter" }, + { name = "quantnado" }, { name = "tomli-w" }, ] notebook = [ @@ -2704,29 +2827,19 @@ toml = [ requires-dist = [ { name = "capcruncher", marker = "extra == 'all'" }, { name = "capcruncher", marker = "extra == 'cooler'" }, + { name = "capcruncher", marker = "extra == 'docs'" }, { name = "cooler", marker = "extra == 'all'" }, { name = "cooler", marker = "extra == 'cooler'" }, + { name = "cooler", marker = "extra == 'docs'" }, + { name = "ipykernel", marker = "extra == 'all'", specifier = ">=6.29.0" }, + { name = "ipykernel", marker = "extra == 'docs'", specifier = ">=6.29.0" }, { name = "ipywidgets", marker = "extra == 'all'", specifier = ">=8" }, { name = "ipywidgets", marker = "extra == 'dev'", specifier = ">=8" }, { name = "ipywidgets", marker = "extra == 'notebook'", specifier = ">=8" }, + { name = "jupyter", marker = "extra == 'all'", specifier = ">=1.1.1" }, + { name = "jupyter", marker = "extra == 'docs'", specifier = ">=1.1.1" }, { name = "loguru" }, { name = "matplotlib" }, - { name = "mkdocs", marker = "extra == 'all'", specifier = "==1.6.1" }, - { name = "mkdocs", marker = "extra == 'docs'", specifier = "==1.6.1" }, - { name = "mkdocs-click", marker = "extra == 'all'", specifier = ">=0.9.0" }, - { name = "mkdocs-click", marker = "extra == 'docs'", specifier = ">=0.9.0" }, - { name = "mkdocs-gen-files", marker = "extra == 'all'", specifier = ">=0.6.0" }, - { name = "mkdocs-gen-files", marker = "extra == 'docs'", specifier = ">=0.6.0" }, - { name = "mkdocs-jupyter", marker = "extra == 'all'", specifier = ">=0.25.1" }, - { name = "mkdocs-jupyter", marker = "extra == 'docs'", specifier = ">=0.25.1" }, - { name = "mkdocs-literate-nav", marker = "extra == 'all'", specifier = ">=0.6.2" }, - { name = "mkdocs-literate-nav", marker = "extra == 'docs'", specifier = ">=0.6.2" }, - { name = "mkdocs-material", marker = "extra == 'all'", specifier = ">=9.5.18" }, - { name = "mkdocs-material", marker = "extra == 'docs'", specifier = ">=9.5.18" }, - { name = "mkdocstrings", marker = "extra == 'all'", specifier = ">=1.0.3" }, - { name = "mkdocstrings", marker = "extra == 'docs'", specifier = ">=1.0.3" }, - { name = "mkdocstrings", extras = ["python"], marker = "extra == 'all'", specifier = ">=1.0.3" }, - { name = "mkdocstrings", extras = ["python"], marker = "extra == 'docs'", specifier = ">=1.0.3" }, { name = "numpy" }, { name = "pandas" }, { name = "pandera" }, @@ -2734,8 +2847,6 @@ requires-dist = [ { name = "pre-commit", marker = "extra == 'dev'" }, { name = "pybigtools" }, { name = "pydantic", specifier = ">=2.0.0" }, - { name = "pymdown-extensions", marker = "extra == 'all'", specifier = ">=10.21" }, - { name = "pymdown-extensions", marker = "extra == 'docs'", specifier = ">=10.21" }, { name = "pyranges1" }, { name = "pytest", marker = "extra == 'all'" }, { name = "pytest", marker = "extra == 'dev'" }, @@ -2747,6 +2858,7 @@ requires-dist = [ { name = "pytest-mock", marker = "extra == 'dev'" }, { name = "pyyaml" }, { name = "quantnado", marker = "extra == 'all'" }, + { name = "quantnado", marker = "extra == 'docs'" }, { name = "quantnado", marker = "extra == 'quantnado'" }, { name = "rich" }, { name = "tomli", marker = "python_full_version < '3.11' and extra == 'all'" }, @@ -2813,53 +2925,24 @@ wheels = [ ] [[package]] -name = "prompt-toolkit" -version = "3.0.52" +name = "prometheus-client" +version = "0.25.0" source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "wcwidth" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/a1/96/06e01a7b38dce6fe1db213e061a4602dd6032a8a97ef6c1a862537732421/prompt_toolkit-3.0.52.tar.gz", hash = "sha256:28cde192929c8e7321de85de1ddbe736f1375148b02f2e17edd840042b1be855", size = 434198, upload-time = "2025-08-27T15:24:02.057Z" } +sdist = { url = "https://files.pythonhosted.org/packages/1b/fb/d9aa83ffe43ce1f19e557c0971d04b90561b0cfd50762aafb01968285553/prometheus_client-0.25.0.tar.gz", hash = "sha256:5e373b75c31afb3c86f1a52fa1ad470c9aace18082d39ec0d2f918d11cc9ba28", size = 86035 } wheels = [ - { url = "https://files.pythonhosted.org/packages/84/03/0d3ce49e2505ae70cf43bc5bb3033955d2fc9f932163e84dc0779cc47f48/prompt_toolkit-3.0.52-py3-none-any.whl", hash = "sha256:9aac639a3bbd33284347de5ad8d68ecc044b91a762dc39b7c21095fcd6a19955", size = 391431, upload-time = "2025-08-27T15:23:59.498Z" }, + { url = "https://files.pythonhosted.org/packages/8d/9b/d4b1e644385499c8346fa9b622a3f030dce14cd6ef8a1871c221a17a67e7/prometheus_client-0.25.0-py3-none-any.whl", hash = "sha256:d5aec89e349a6ec230805d0df882f3807f74fd6c1a2fa86864e3c2279059fed1", size = 64154 }, ] [[package]] -name = "properdocs" -version = "1.6.7" +name = "prompt-toolkit" +version = "3.0.52" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "click" }, - { name = "colorama", marker = "sys_platform == 'win32'" }, - { name = "ghp-import" }, - { name = "jinja2" }, - { name = "markdown" }, - { name = "markupsafe" }, - { name = "packaging" }, - { name = "pathspec" }, - { name = "platformdirs" }, - { name = "pyyaml" }, - { name = "pyyaml-env-tag" }, - { name = "watchdog" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/ec/29/f27a4e1eddf72ed3db6e47818fbafe6debbf09fd7051f9c1a007239b46ef/properdocs-1.6.7.tar.gz", hash = "sha256:adc7b16e562890af0e098a7e5b02e3a81c20894a87d6a28d345c9300de73c26e", size = 276141, upload-time = "2026-03-20T20:07:48.167Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/bd/4d/fc923f5c85318ee8cc903566dc4e0ebe41b2dfc1d2ecf5546db232397ed6/properdocs-1.6.7-py3-none-any.whl", hash = "sha256:6fa0cfa2e01bf338f684892c8a506cf70ea88ae7f3479c933b6fa20168101cbd", size = 225406, upload-time = "2026-03-20T20:07:46.875Z" }, + { name = "wcwidth" }, ] - -[[package]] -name = "protobuf" -version = "7.34.1" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/6b/6b/a0e95cad1ad7cc3f2c6821fcab91671bd5b78bd42afb357bb4765f29bc41/protobuf-7.34.1.tar.gz", hash = "sha256:9ce42245e704cc5027be797c1db1eb93184d44d1cdd71811fb2d9b25ad541280", size = 454708, upload-time = "2026-03-20T17:34:47.036Z" } +sdist = { url = "https://files.pythonhosted.org/packages/a1/96/06e01a7b38dce6fe1db213e061a4602dd6032a8a97ef6c1a862537732421/prompt_toolkit-3.0.52.tar.gz", hash = "sha256:28cde192929c8e7321de85de1ddbe736f1375148b02f2e17edd840042b1be855", size = 434198 } wheels = [ - { url = "https://files.pythonhosted.org/packages/ec/11/3325d41e6ee15bf1125654301211247b042563bcc898784351252549a8ad/protobuf-7.34.1-cp310-abi3-macosx_10_9_universal2.whl", hash = "sha256:d8b2cc79c4d8f62b293ad9b11ec3aebce9af481fa73e64556969f7345ebf9fc7", size = 429247, upload-time = "2026-03-20T17:34:37.024Z" }, - { url = "https://files.pythonhosted.org/packages/eb/9d/aa69df2724ff63efa6f72307b483ce0827f4347cc6d6df24b59e26659fef/protobuf-7.34.1-cp310-abi3-manylinux2014_aarch64.whl", hash = "sha256:5185e0e948d07abe94bb76ec9b8416b604cfe5da6f871d67aad30cbf24c3110b", size = 325753, upload-time = "2026-03-20T17:34:38.751Z" }, - { url = "https://files.pythonhosted.org/packages/92/e8/d174c91fd48e50101943f042b09af9029064810b734e4160bbe282fa1caa/protobuf-7.34.1-cp310-abi3-manylinux2014_s390x.whl", hash = "sha256:403b093a6e28a960372b44e5eb081775c9b056e816a8029c61231743d63f881a", size = 340198, upload-time = "2026-03-20T17:34:39.871Z" }, - { url = "https://files.pythonhosted.org/packages/53/1b/3b431694a4dc6d37b9f653f0c64b0a0d9ec074ee810710c0c3da21d67ba7/protobuf-7.34.1-cp310-abi3-manylinux2014_x86_64.whl", hash = "sha256:8ff40ce8cd688f7265326b38d5a1bed9bfdf5e6723d49961432f83e21d5713e4", size = 324267, upload-time = "2026-03-20T17:34:41.1Z" }, - { url = "https://files.pythonhosted.org/packages/85/29/64de04a0ac142fb685fd09999bc3d337943fb386f3a0ec57f92fd8203f97/protobuf-7.34.1-cp310-abi3-win32.whl", hash = "sha256:34b84ce27680df7cca9f231043ada0daa55d0c44a2ddfaa58ec1d0d89d8bf60a", size = 426628, upload-time = "2026-03-20T17:34:42.536Z" }, - { url = "https://files.pythonhosted.org/packages/4d/87/cb5e585192a22b8bd457df5a2c16a75ea0db9674c3a0a39fc9347d84e075/protobuf-7.34.1-cp310-abi3-win_amd64.whl", hash = "sha256:e97b55646e6ce5cbb0954a8c28cd39a5869b59090dfaa7df4598a7fba869468c", size = 437901, upload-time = "2026-03-20T17:34:44.112Z" }, - { url = "https://files.pythonhosted.org/packages/88/95/608f665226bca68b736b79e457fded9a2a38c4f4379a4a7614303d9db3bc/protobuf-7.34.1-py3-none-any.whl", hash = "sha256:bb3812cd53aefea2b028ef42bd780f5b96407247f20c6ef7c679807e9d188f11", size = 170715, upload-time = "2026-03-20T17:34:45.384Z" }, + { url = "https://files.pythonhosted.org/packages/84/03/0d3ce49e2505ae70cf43bc5bb3033955d2fc9f932163e84dc0779cc47f48/prompt_toolkit-3.0.52-py3-none-any.whl", hash = "sha256:9aac639a3bbd33284347de5ad8d68ecc044b91a762dc39b7c21095fcd6a19955", size = 391431 }, ] [[package]] @@ -3113,21 +3196,8 @@ wheels = [ ] [[package]] -name = "pymdown-extensions" -version = "10.21.2" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "markdown" }, - { name = "pyyaml" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/df/08/f1c908c581fd11913da4711ea7ba32c0eee40b0190000996bb863b0c9349/pymdown_extensions-10.21.2.tar.gz", hash = "sha256:c3f55a5b8a1d0edf6699e35dcbea71d978d34ff3fa79f3d807b8a5b3fa90fbdc", size = 853922, upload-time = "2026-03-29T15:01:55.233Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/f7/27/a2fc51a4a122dfd1015e921ae9d22fee3d20b0b8080d9a704578bf9deece/pymdown_extensions-10.21.2-py3-none-any.whl", hash = "sha256:5c0fd2a2bea14eb39af8ff284f1066d898ab2187d81b889b75d46d4348c01638", size = 268901, upload-time = "2026-03-29T15:01:53.244Z" }, -] - -[[package]] -name = "pyparsing" -version = "3.3.2" +name = "pynacl" +version = "1.6.2" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/f3/91/9c6ee907786a473bf81c5f53cf703ba0957b23ab84c264080fb5a450416f/pyparsing-3.3.2.tar.gz", hash = "sha256:c777f4d763f140633dcb6d8a3eda953bf7a214dc4eff598413c070bcdc117cbc", size = 6851574, upload-time = "2026-01-21T03:57:59.36Z" } wheels = [ @@ -3296,6 +3366,33 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/ec/dd/96da98f892250475bdf2328112d7468abdd4acc7b902b6af23f4ed958ea0/pytz-2026.2-py2.py3-none-any.whl", hash = "sha256:04156e608bee23d3792fd45c94ae47fae1036688e75032eea2e3bf0323d1f126", size = 510141, upload-time = "2026-05-04T01:35:27.408Z" }, ] +[[package]] +name = "python-json-logger" +version = "4.1.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/f7/ff/3cc9165fd44106973cd7ac9facb674a65ed853494592541d339bdc9a30eb/python_json_logger-4.1.0.tar.gz", hash = "sha256:b396b9e3ed782b09ff9d6e4f1683d46c83ad0d35d2e407c09a9ebbf038f88195", size = 17573 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/27/be/0631a861af4d1c875f096c07d34e9a63639560a717130e7a87cbc82b7e3f/python_json_logger-4.1.0-py3-none-any.whl", hash = "sha256:132994765cf75bf44554be9aa49b06ef2345d23661a96720262716438141b6b2", size = 15021 }, +] + +[[package]] +name = "pywinpty" +version = "3.0.3" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/f7/54/37c7370ba91f579235049dc26cd2c5e657d2a943e01820844ffc81f32176/pywinpty-3.0.3.tar.gz", hash = "sha256:523441dc34d231fb361b4b00f8c99d3f16de02f5005fd544a0183112bcc22412", size = 31309 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/7c/d4/aeb5e1784d2c5bff6e189138a9ca91a090117459cea0c30378e1f2db3d54/pywinpty-3.0.3-cp312-cp312-win_amd64.whl", hash = "sha256:c9081df0e49ffa86d15db4a6ba61530630e48707f987df42c9d3313537e81fc0", size = 2113098 }, + { url = "https://files.pythonhosted.org/packages/b9/53/7278223c493ccfe4883239cf06c823c56460a8010e0fc778eef67858dc14/pywinpty-3.0.3-cp312-cp312-win_arm64.whl", hash = "sha256:15e79d870e18b678fb8a5a6105fd38496b55697c66e6fc0378236026bc4d59e9", size = 234901 }, + { url = "https://files.pythonhosted.org/packages/e5/cb/58d6ed3fd429c96a90ef01ac9a617af10a6d41469219c25e7dc162abbb71/pywinpty-3.0.3-cp313-cp313-win_amd64.whl", hash = "sha256:9c91dbb026050c77bdcef964e63a4f10f01a639113c4d3658332614544c467ab", size = 2112686 }, + { url = "https://files.pythonhosted.org/packages/fd/50/724ed5c38c504d4e58a88a072776a1e880d970789deaeb2b9f7bd9a5141a/pywinpty-3.0.3-cp313-cp313-win_arm64.whl", hash = "sha256:fe1f7911805127c94cf51f89ab14096c6f91ffdcacf993d2da6082b2142a2523", size = 234591 }, + { url = "https://files.pythonhosted.org/packages/f7/ad/90a110538696b12b39fd8758a06d70ded899308198ad2305ac68e361126e/pywinpty-3.0.3-cp313-cp313t-win_amd64.whl", hash = "sha256:3f07a6cf1c1d470d284e614733c3d0f726d2c85e78508ea10a403140c3c0c18a", size = 2112360 }, + { url = "https://files.pythonhosted.org/packages/44/0f/7ffa221757a220402bc79fda44044c3f2cc57338d878ab7d622add6f4581/pywinpty-3.0.3-cp313-cp313t-win_arm64.whl", hash = "sha256:15c7c0b6f8e9d87aabbaff76468dabf6e6121332c40fc1d83548d02a9d6a3759", size = 233107 }, + { url = "https://files.pythonhosted.org/packages/28/88/2ff917caff61e55f38bcdb27de06ee30597881b2cae44fbba7627be015c4/pywinpty-3.0.3-cp314-cp314-win_amd64.whl", hash = "sha256:d4b6b7b0fe0cdcd02e956bd57cfe9f4e5a06514eecf3b5ae174da4f951b58be9", size = 2113282 }, + { url = "https://files.pythonhosted.org/packages/63/32/40a775343ace542cc43ece3f1d1fce454021521ecac41c4c4573081c2336/pywinpty-3.0.3-cp314-cp314-win_arm64.whl", hash = "sha256:34789d685fc0d547ce0c8a65e5a70e56f77d732fa6e03c8f74fefb8cbb252019", size = 234207 }, + { url = "https://files.pythonhosted.org/packages/8d/54/5d5e52f4cb75028104ca6faf36c10f9692389b1986d34471663b4ebebd6d/pywinpty-3.0.3-cp314-cp314t-win_amd64.whl", hash = "sha256:0c37e224a47a971d1a6e08649a1714dac4f63c11920780977829ed5c8cadead1", size = 2112910 }, + { url = "https://files.pythonhosted.org/packages/0a/44/dcd184824e21d4620b06c7db9fbb15c3ad0a0f1fa2e6de79969fb82647ec/pywinpty-3.0.3-cp314-cp314t-win_arm64.whl", hash = "sha256:c4e9c3dff7d86ba81937438d5819f19f385a39d8f592d4e8af67148ceb4f6ab5", size = 233425 }, +] + [[package]] name = "pyyaml" version = "6.0.3" @@ -3342,18 +3439,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/f1/12/de94a39c2ef588c7e6455cfbe7343d3b2dc9d6b6b2f40c4c6565744c873d/pyyaml-6.0.3-cp314-cp314t-win_arm64.whl", hash = "sha256:ebc55a14a21cb14062aa4162f906cd962b28e2e9ea38f9b4391244cd8de4ae0b", size = 149341, upload-time = "2025-09-25T21:32:56.828Z" }, ] -[[package]] -name = "pyyaml-env-tag" -version = "1.1" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "pyyaml" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/eb/2e/79c822141bfd05a853236b504869ebc6b70159afc570e1d5a20641782eaa/pyyaml_env_tag-1.1.tar.gz", hash = "sha256:2eb38b75a2d21ee0475d6d97ec19c63287a7e140231e4214969d0eac923cd7ff", size = 5737, upload-time = "2025-05-13T15:24:01.64Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/04/11/432f32f8097b03e3cd5fe57e88efb685d964e2e5178a48ed61e841f7fdce/pyyaml_env_tag-1.1-py3-none-any.whl", hash = "sha256:17109e1a528561e32f026364712fee1264bc2ea6715120891174ed1b980d2e04", size = 4722, upload-time = "2025-05-13T15:23:59.629Z" }, -] - [[package]] name = "pyzmq" version = "27.1.0" @@ -3453,6 +3538,39 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/66/11/e295e07d4ae500144177f875a8de11daa4d86b8246ab41c76a98ce9280ca/reretry-0.11.8-py2.py3-none-any.whl", hash = "sha256:5ec1084cd9644271ee386d34cd5dd24bdb3e91d55961b076d1a31d585ad68a79", size = 5609, upload-time = "2022-12-18T11:08:49.1Z" }, ] +[[package]] +name = "rfc3339-validator" +version = "0.1.4" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "six" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/28/ea/a9387748e2d111c3c2b275ba970b735e04e15cdb1eb30693b6b5708c4dbd/rfc3339_validator-0.1.4.tar.gz", hash = "sha256:138a2abdf93304ad60530167e51d2dfb9549521a836871b88d7f4695d0022f6b", size = 5513 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/7b/44/4e421b96b67b2daff264473f7465db72fbdf36a07e05494f50300cc7b0c6/rfc3339_validator-0.1.4-py2.py3-none-any.whl", hash = "sha256:24f6ec1eda14ef823da9e36ec7113124b39c04d50a4d3d3a3c2859577e7791fa", size = 3490 }, +] + +[[package]] +name = "rfc3986-validator" +version = "0.1.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/da/88/f270de456dd7d11dcc808abfa291ecdd3f45ff44e3b549ffa01b126464d0/rfc3986_validator-0.1.1.tar.gz", hash = "sha256:3d44bde7921b3b9ec3ae4e3adca370438eccebc676456449b145d533b240d055", size = 6760 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/9e/51/17023c0f8f1869d8806b979a2bffa3f861f26a3f1a66b094288323fba52f/rfc3986_validator-0.1.1-py2.py3-none-any.whl", hash = "sha256:2f235c432ef459970b4306369336b9d5dbdda31b510ca1e327636e01f528bfa9", size = 4242 }, +] + +[[package]] +name = "rfc3987-syntax" +version = "1.1.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "lark" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/2c/06/37c1a5557acf449e8e406a830a05bf885ac47d33270aec454ef78675008d/rfc3987_syntax-1.1.0.tar.gz", hash = "sha256:717a62cbf33cffdd16dfa3a497d81ce48a660ea691b1ddd7be710c22f00b4a0d", size = 14239 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/7e/71/44ce230e1b7fadd372515a97e32a83011f906ddded8d03e3c6aafbdedbb7/rfc3987_syntax-1.1.0-py3-none-any.whl", hash = "sha256:6c3d97604e4c5ce9f714898e05401a0445a641cfa276432b0a648c80856f6a3f", size = 8046 }, +] + [[package]] name = "rich" version = "15.0.0" @@ -3725,6 +3843,24 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/e1/e3/c164c88b2e5ce7b24d667b9bd83589cf4f3520d97cad01534cd3c4f55fdb/setuptools-81.0.0-py3-none-any.whl", hash = "sha256:fdd925d5c5d9f62e4b74b30d6dd7828ce236fd6ed998a08d81de62ce5a6310d6", size = 1062021, upload-time = "2026-02-06T21:10:37.175Z" }, ] +[[package]] +name = "send2trash" +version = "2.1.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/c5/f0/184b4b5f8d00f2a92cf96eec8967a3d550b52cf94362dad1100df9e48d57/send2trash-2.1.0.tar.gz", hash = "sha256:1c72b39f09457db3c05ce1d19158c2cbef4c32b8bedd02c155e49282b7ea7459", size = 17255 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/1c/78/504fdd027da3b84ff1aecd9f6957e65f35134534ccc6da8628eb71e76d3f/send2trash-2.1.0-py3-none-any.whl", hash = "sha256:0da2f112e6d6bb22de6aa6daa7e144831a4febf2a87261451c4ad849fe9a873c", size = 17610 }, +] + +[[package]] +name = "setuptools" +version = "82.0.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/4f/db/cfac1baf10650ab4d1c111714410d2fbb77ac5a616db26775db562c8fab2/setuptools-82.0.1.tar.gz", hash = "sha256:7d872682c5d01cfde07da7bccc7b65469d3dca203318515ada1de5eda35efbf9", size = 1152316 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/9d/76/f789f7a86709c6b087c5a2f52f911838cad707cc613162401badc665acfe/setuptools-82.0.1-py3-none-any.whl", hash = "sha256:a59e362652f08dcd477c78bb6e7bd9d80a7995bc73ce773050228a348ce2e5bb", size = 1006223 }, +] + [[package]] name = "shellingham" version = "1.5.4" @@ -3934,6 +4070,20 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/24/99/4772b8e00a136f3e01236de33b0efda31ee7077203ba5967fcc76da94d65/texttable-1.7.0-py2.py3-none-any.whl", hash = "sha256:72227d592c82b3d7f672731ae73e4d1f88cd8e2ef5b075a7a7f01a23a3743917", size = 10768, upload-time = "2023-10-03T09:48:10.434Z" }, ] +[[package]] +name = "terminado" +version = "0.18.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "ptyprocess", marker = "os_name != 'nt'" }, + { name = "pywinpty", marker = "os_name == 'nt'" }, + { name = "tornado" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/8a/11/965c6fd8e5cc254f1fe142d547387da17a8ebfd75a3455f637c663fb38a0/terminado-0.18.1.tar.gz", hash = "sha256:de09f2c4b85de4765f7714688fff57d3e75bad1f909b589fde880460c753fd2e", size = 32701 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/6a/9e/2064975477fdc887e47ad42157e214526dcad8f317a948dee17e1659a62f/terminado-0.18.1-py3-none-any.whl", hash = "sha256:a4468e1b37bb318f8a86514f65814e1afc977cf29b3992a4500d9dd305dcceb0", size = 14154 }, +] + [[package]] name = "threadpoolctl" version = "3.6.0" @@ -4159,6 +4309,15 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/b0/70/d460bd685a170790ec89317e9bd33047988e4bce507b831f5db771e142de/tzdata-2026.1-py2.py3-none-any.whl", hash = "sha256:4b1d2be7ac37ceafd7327b961aa3a54e467efbdb563a23655fbfe0d39cfc42a9", size = 348952, upload-time = "2026-04-03T11:25:20.313Z" }, ] +[[package]] +name = "uri-template" +version = "1.3.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/31/c7/0336f2bd0bcbada6ccef7aaa25e443c118a704f828a0620c6fa0207c1b64/uri-template-1.3.0.tar.gz", hash = "sha256:0e00f8eb65e18c7de20d595a14336e9f337ead580c70934141624b6d1ffdacc7", size = 21678 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/e7/00/3fca040d7cf8a32776d3d81a00c8ee7457e00f80c649f1e4a863c8321ae9/uri_template-1.3.0-py3-none-any.whl", hash = "sha256:a44a133ea12d44a0c0f06d7d42a52d71282e77e2f937d8abd5655b8d56fc1363", size = 11140 }, +] + [[package]] name = "urllib3" version = "2.6.3" @@ -4213,36 +4372,21 @@ wheels = [ ] [[package]] -name = "watchdog" -version = "6.0.0" +name = "wcwidth" +version = "0.6.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/db/7d/7f3d619e951c88ed75c6037b246ddcf2d322812ee8ea189be89511721d54/watchdog-6.0.0.tar.gz", hash = "sha256:9ddf7c82fda3ae8e24decda1338ede66e1c99883db93711d8fb941eaa2d8c282", size = 131220, upload-time = "2024-11-01T14:07:13.037Z" } +sdist = { url = "https://files.pythonhosted.org/packages/35/a2/8e3becb46433538a38726c948d3399905a4c7cabd0df578ede5dc51f0ec2/wcwidth-0.6.0.tar.gz", hash = "sha256:cdc4e4262d6ef9a1a57e018384cbeb1208d8abbc64176027e2c2455c81313159", size = 159684 } wheels = [ - { url = "https://files.pythonhosted.org/packages/39/ea/3930d07dafc9e286ed356a679aa02d777c06e9bfd1164fa7c19c288a5483/watchdog-6.0.0-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:bdd4e6f14b8b18c334febb9c4425a878a2ac20efd1e0b231978e7b150f92a948", size = 96471, upload-time = "2024-11-01T14:06:37.745Z" }, - { url = "https://files.pythonhosted.org/packages/12/87/48361531f70b1f87928b045df868a9fd4e253d9ae087fa4cf3f7113be363/watchdog-6.0.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:c7c15dda13c4eb00d6fb6fc508b3c0ed88b9d5d374056b239c4ad1611125c860", size = 88449, upload-time = "2024-11-01T14:06:39.748Z" }, - { url = "https://files.pythonhosted.org/packages/5b/7e/8f322f5e600812e6f9a31b75d242631068ca8f4ef0582dd3ae6e72daecc8/watchdog-6.0.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:6f10cb2d5902447c7d0da897e2c6768bca89174d0c6e1e30abec5421af97a5b0", size = 89054, upload-time = "2024-11-01T14:06:41.009Z" }, - { url = "https://files.pythonhosted.org/packages/68/98/b0345cabdce2041a01293ba483333582891a3bd5769b08eceb0d406056ef/watchdog-6.0.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:490ab2ef84f11129844c23fb14ecf30ef3d8a6abafd3754a6f75ca1e6654136c", size = 96480, upload-time = "2024-11-01T14:06:42.952Z" }, - { url = "https://files.pythonhosted.org/packages/85/83/cdf13902c626b28eedef7ec4f10745c52aad8a8fe7eb04ed7b1f111ca20e/watchdog-6.0.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:76aae96b00ae814b181bb25b1b98076d5fc84e8a53cd8885a318b42b6d3a5134", size = 88451, upload-time = "2024-11-01T14:06:45.084Z" }, - { url = "https://files.pythonhosted.org/packages/fe/c4/225c87bae08c8b9ec99030cd48ae9c4eca050a59bf5c2255853e18c87b50/watchdog-6.0.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:a175f755fc2279e0b7312c0035d52e27211a5bc39719dd529625b1930917345b", size = 89057, upload-time = "2024-11-01T14:06:47.324Z" }, - { url = "https://files.pythonhosted.org/packages/a9/c7/ca4bf3e518cb57a686b2feb4f55a1892fd9a3dd13f470fca14e00f80ea36/watchdog-6.0.0-py3-none-manylinux2014_aarch64.whl", hash = "sha256:7607498efa04a3542ae3e05e64da8202e58159aa1fa4acddf7678d34a35d4f13", size = 79079, upload-time = "2024-11-01T14:06:59.472Z" }, - { url = "https://files.pythonhosted.org/packages/5c/51/d46dc9332f9a647593c947b4b88e2381c8dfc0942d15b8edc0310fa4abb1/watchdog-6.0.0-py3-none-manylinux2014_armv7l.whl", hash = "sha256:9041567ee8953024c83343288ccc458fd0a2d811d6a0fd68c4c22609e3490379", size = 79078, upload-time = "2024-11-01T14:07:01.431Z" }, - { url = "https://files.pythonhosted.org/packages/d4/57/04edbf5e169cd318d5f07b4766fee38e825d64b6913ca157ca32d1a42267/watchdog-6.0.0-py3-none-manylinux2014_i686.whl", hash = "sha256:82dc3e3143c7e38ec49d61af98d6558288c415eac98486a5c581726e0737c00e", size = 79076, upload-time = "2024-11-01T14:07:02.568Z" }, - { url = "https://files.pythonhosted.org/packages/ab/cc/da8422b300e13cb187d2203f20b9253e91058aaf7db65b74142013478e66/watchdog-6.0.0-py3-none-manylinux2014_ppc64.whl", hash = "sha256:212ac9b8bf1161dc91bd09c048048a95ca3a4c4f5e5d4a7d1b1a7d5752a7f96f", size = 79077, upload-time = "2024-11-01T14:07:03.893Z" }, - { url = "https://files.pythonhosted.org/packages/2c/3b/b8964e04ae1a025c44ba8e4291f86e97fac443bca31de8bd98d3263d2fcf/watchdog-6.0.0-py3-none-manylinux2014_ppc64le.whl", hash = "sha256:e3df4cbb9a450c6d49318f6d14f4bbc80d763fa587ba46ec86f99f9e6876bb26", size = 79078, upload-time = "2024-11-01T14:07:05.189Z" }, - { url = "https://files.pythonhosted.org/packages/62/ae/a696eb424bedff7407801c257d4b1afda455fe40821a2be430e173660e81/watchdog-6.0.0-py3-none-manylinux2014_s390x.whl", hash = "sha256:2cce7cfc2008eb51feb6aab51251fd79b85d9894e98ba847408f662b3395ca3c", size = 79077, upload-time = "2024-11-01T14:07:06.376Z" }, - { url = "https://files.pythonhosted.org/packages/b5/e8/dbf020b4d98251a9860752a094d09a65e1b436ad181faf929983f697048f/watchdog-6.0.0-py3-none-manylinux2014_x86_64.whl", hash = "sha256:20ffe5b202af80ab4266dcd3e91aae72bf2da48c0d33bdb15c66658e685e94e2", size = 79078, upload-time = "2024-11-01T14:07:07.547Z" }, - { url = "https://files.pythonhosted.org/packages/07/f6/d0e5b343768e8bcb4cda79f0f2f55051bf26177ecd5651f84c07567461cf/watchdog-6.0.0-py3-none-win32.whl", hash = "sha256:07df1fdd701c5d4c8e55ef6cf55b8f0120fe1aef7ef39a1c6fc6bc2e606d517a", size = 79065, upload-time = "2024-11-01T14:07:09.525Z" }, - { url = "https://files.pythonhosted.org/packages/db/d9/c495884c6e548fce18a8f40568ff120bc3a4b7b99813081c8ac0c936fa64/watchdog-6.0.0-py3-none-win_amd64.whl", hash = "sha256:cbafb470cf848d93b5d013e2ecb245d4aa1c8fd0504e863ccefa32445359d680", size = 79070, upload-time = "2024-11-01T14:07:10.686Z" }, - { url = "https://files.pythonhosted.org/packages/33/e8/e40370e6d74ddba47f002a32919d91310d6074130fe4e17dabcafc15cbf1/watchdog-6.0.0-py3-none-win_ia64.whl", hash = "sha256:a1914259fa9e1454315171103c6a30961236f508b9b623eae470268bbcc6a22f", size = 79067, upload-time = "2024-11-01T14:07:11.845Z" }, + { url = "https://files.pythonhosted.org/packages/68/5a/199c59e0a824a3db2b89c5d2dade7ab5f9624dbf6448dc291b46d5ec94d3/wcwidth-0.6.0-py3-none-any.whl", hash = "sha256:1a3a1e510b553315f8e146c54764f4fb6264ffad731b3d78088cdb1478ffbdad", size = 94189 }, ] [[package]] -name = "wcwidth" -version = "0.6.0" +name = "webcolors" +version = "25.10.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/35/a2/8e3becb46433538a38726c948d3399905a4c7cabd0df578ede5dc51f0ec2/wcwidth-0.6.0.tar.gz", hash = "sha256:cdc4e4262d6ef9a1a57e018384cbeb1208d8abbc64176027e2c2455c81313159", size = 159684, upload-time = "2026-02-06T19:19:40.919Z" } +sdist = { url = "https://files.pythonhosted.org/packages/1d/7a/eb316761ec35664ea5174709a68bbd3389de60d4a1ebab8808bfc264ed67/webcolors-25.10.0.tar.gz", hash = "sha256:62abae86504f66d0f6364c2a8520de4a0c47b80c03fc3a5f1815fedbef7c19bf", size = 53491 } wheels = [ - { url = "https://files.pythonhosted.org/packages/68/5a/199c59e0a824a3db2b89c5d2dade7ab5f9624dbf6448dc291b46d5ec94d3/wcwidth-0.6.0-py3-none-any.whl", hash = "sha256:1a3a1e510b553315f8e146c54764f4fb6264ffad731b3d78088cdb1478ffbdad", size = 94189, upload-time = "2026-02-06T19:19:39.646Z" }, + { url = "https://files.pythonhosted.org/packages/e2/cc/e097523dd85c9cf5d354f78310927f1656c422bd7b2613b2db3e3f9a0f2c/webcolors-25.10.0-py3-none-any.whl", hash = "sha256:032c727334856fc0b968f63daa252a1ac93d33db2f5267756623c210e57a4f1d", size = 14905 }, ] [[package]] @@ -4254,6 +4398,15 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/f4/24/2a3e3df732393fed8b3ebf2ec078f05546de641fe1b667ee316ec1dcf3b7/webencodings-0.5.1-py2.py3-none-any.whl", hash = "sha256:a0af1213f3c2226497a97e2b3aa01a7e4bee4f403f95be16fc9acd2947514a78", size = 11774, upload-time = "2017-04-05T20:21:32.581Z" }, ] +[[package]] +name = "websocket-client" +version = "1.9.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/2c/41/aa4bf9664e4cda14c3b39865b12251e8e7d239f4cd0e3cc1b6c2ccde25c1/websocket_client-1.9.0.tar.gz", hash = "sha256:9e813624b6eb619999a97dc7958469217c3176312b3a16a4bd1bc7e08a46ec98", size = 70576 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/34/db/b10e48aa8fff7407e67470363eac595018441cf32d5e1001567a7aeba5d2/websocket_client-1.9.0-py3-none-any.whl", hash = "sha256:af248a825037ef591efbf6ed20cc5faa03d3b47b9e5a2230a529eeee1c1fc3ef", size = 82616 }, +] + [[package]] name = "widgetsnbextension" version = "4.0.15"