diff --git a/.claude/skills/add-lang/SKILL.md b/.claude/skills/add-lang/SKILL.md index 1dc293d5..7b6d353b 100644 --- a/.claude/skills/add-lang/SKILL.md +++ b/.claude/skills/add-lang/SKILL.md @@ -519,7 +519,7 @@ invocation in: | `src/metrics/abc.rs` | `Abc` | | `src/metrics/cognitive.rs` | `Cognitive` | | `src/metrics/cyclomatic.rs` | `Cyclomatic` | -| `src/metrics/exit.rs` | `Exit` | +| `src/metrics/nexits.rs` | `Exit` | | `src/metrics/halstead.rs` | `Halstead` | | `src/metrics/loc.rs` | `Loc` | | `src/metrics/mi.rs` | `Mi` | @@ -541,7 +541,7 @@ Run `cargo check -p big-code-analysis` — it should now succeed. branch** — this is consistent with the existing Java and Cpp impls in this repo, and was reaffirmed for Go in commit `e0701e1`. Match the language's actual node kinds, not generic names. -- **Exit** (`src/metrics/exit.rs`): `+1` per `return`/`yield` / +- **Exit** (`src/metrics/nexits.rs`): `+1` per `return`/`yield` / language-specific exit. A multi-value return counts once. - **Halstead** (`src/metrics/halstead.rs`): wire `compute_halstead::` through the existing @@ -727,7 +727,7 @@ were: |--------|-----------:|--------------------------------------------| | `cognitive` | 9 | no-op file, simple function, sequence of same/different booleans, negated booleans, 1-level nesting, 2-level nesting, `break`/`continue`, complex `if let / else if / else`. | | `cyclomatic` | 1 | nested-control-flow representative test. (Go currently overshoots Rust here at 10 — match Rust's 1, optionally add a couple more if the language has unusual constructs.) | -| `exit` | 2 | function with no exit, function with `?` / language equivalent of early-exit. | +| `nexits` | 2 | function with no exit, function with `?` / language equivalent of early-exit. | | `halstead` | 1 | one comprehensive `_operators_and_operands` test pinning every Halstead field via `insta`. | | `loc` | 15 | blank, no-zero-blank, cloc, lloc, then **at least one `_no_*_lloc` test for each gating decision** (Rust has: `field_expression`, `parenthesized_expression`, `array_expression`, `tuple_expression`, `unit_expression`, `call_function`, `macro_invocation`, `function_in_loop`, `function_in_if`, `function_in_return`, `closure_expression`). Mirror this — every node kind your `compute` excludes from LLOC needs a dedicated test that would fail if the gating is removed. | | `nargs` | 5 | no functions/closures, single function, single closure, multiple functions, nested functions. | @@ -761,7 +761,7 @@ only when the grammar has constructs the existing repo has not seen (Go's `defer`/`go` test is the template). Do not pad the count by adding one test per ordinary branching keyword; that is what the single nested test already covers. -- **`exit`** — `_no_exit` (function with no return), and one +- **`nexits`** — `_no_exit` (function with no return), and one test per language-specific exit path (e.g. Rust's `?`, Go's multi-value return, Python's `yield`/`raise`, Ruby's `next`/`break` out of a block if you treat them as exits — document the choice). @@ -928,7 +928,7 @@ language alphabetically: `CHANGELOG.md` is present at the repo root and used. A new language warrants its own entry — do not consolidate into a batch-fix line. -Append under `Added`: +Append under `Added` within the `## [Unreleased]` section: ```markdown - Support for source files (`.`). @@ -1069,7 +1069,7 @@ Files changed: src/checker.rs src/getter.rs src/alterator.rs (if applicable) - src/metrics/{abc,cognitive,cyclomatic,exit,halstead,loc,mi,nargs,nom,npa,npm,wmc}.rs + src/metrics/{abc,cognitive,cyclomatic,nexits,halstead,loc,mi,nargs,nom,npa,npm,wmc}.rs big-code-analysis-book/src/languages.md *.snap (new insta snapshots) diff --git a/.claude/skills/audit-crate/SKILL.md b/.claude/skills/audit-crate/SKILL.md index dd68d0e3..edd93e82 100644 --- a/.claude/skills/audit-crate/SKILL.md +++ b/.claude/skills/audit-crate/SKILL.md @@ -9,9 +9,9 @@ Audit the Rust crate `$ARGUMENTS` for logic errors, unnecessary complexity, bugs, security issues, incorrect comments, and code smells. If `$ARGUMENTS` is empty, default to `big-code-analysis` — the root library -crate. The other crates in this workspace are `big-code-analysis-cli` and -`big-code-analysis-web`. The crate root is the directory containing the -crate's `Cargo.toml`. +crate. The other crates in this workspace are `big-code-analysis-cli`, +`big-code-analysis-web`, `big-code-analysis-py`, `xtask`, and `enums`. +The crate root is the directory containing the crate's `Cargo.toml`. **Resolve `$ARGUMENTS` once at the very start of the run** and use the resolved value for every subsequent reference (memory keys, `cargo -p`, issue @@ -204,7 +204,7 @@ CRATE_DIR=$(cargo metadata --format-version 1 --no-deps \ # Self-host: use this project's own CLI to measure the crate under audit. if cargo build -p big-code-analysis-cli >/dev/null 2>&1; then - ./target/debug/big-code-analysis-cli -m -O json -p "$CRATE_DIR" > /tmp/audit-metrics.json || true + ./target/debug/bca metrics -O json "$CRATE_DIR" > /tmp/audit-metrics.json || true fi ``` diff --git a/.claude/skills/audit-file/SKILL.md b/.claude/skills/audit-file/SKILL.md index 7e677a2c..93fe98f0 100644 --- a/.claude/skills/audit-file/SKILL.md +++ b/.claude/skills/audit-file/SKILL.md @@ -219,7 +219,7 @@ the audit to the highest-risk functions. ```bash if cargo build -p big-code-analysis-cli >/dev/null 2>&1; then - ./target/debug/big-code-analysis-cli -m -O json -p "$FILE_ABS" > /tmp/audit-metrics.json || true + ./target/debug/bca metrics -O json "$FILE_ABS" > /tmp/audit-metrics.json || true fi ``` diff --git a/.claude/skills/audit-naming/SKILL.md b/.claude/skills/audit-naming/SKILL.md index dcec7b32..65a2dc83 100644 --- a/.claude/skills/audit-naming/SKILL.md +++ b/.claude/skills/audit-naming/SKILL.md @@ -6,13 +6,14 @@ description: Audit naming quality in a crate or directory for misleading, incons # Audit Naming Quality Audit naming quality in `$ARGUMENTS` for misleading, inconsistent, or unclear -names across the Rust source under audit. Distinct from `audit` (logic, -security, complexity) -- this focuses exclusively on whether names tell the -truth. +names across the Rust source under audit. Distinct from `audit-crate` / +`audit-file` (logic, security, complexity) -- this focuses exclusively on +whether names tell the truth. If `$ARGUMENTS` is empty, default to `big-code-analysis` — the root library -crate. Other crates in this workspace are `big-code-analysis-cli` and -`big-code-analysis-web`. `$ARGUMENTS` may also be a directory path; in that +crate. Other crates in this workspace are `big-code-analysis-cli`, +`big-code-analysis-web`, `big-code-analysis-py`, `xtask`, and `enums`. +`$ARGUMENTS` may also be a directory path; in that case the audit is scoped to that directory. **Resolve `$ARGUMENTS` once at the very start of the run** and use the @@ -277,14 +278,14 @@ Severity definitions: | ID | Check | |----|-------| | P1 | Cross-language naming parity: when `language_rust.rs`, `language_python.rs`, etc. expose the same concept, the names match (no `is_func` in one and `is_function` in another) | -| P2 | Metric names follow the canonical metric vocabulary (`abc`, `cognitive`, `cyclomatic`, `halstead`, `loc`, `mi`, `nargs`, `nom`, `npa`, `npm`, `wmc`) — abbreviations are standard, expanded forms or alternates are inconsistent | +| P2 | Metric names follow the canonical metric vocabulary (`abc`, `cognitive`, `cyclomatic`, `halstead`, `loc`, `mi`, `nargs`, `nexits`, `nom`, `npa`, `npm`, `tokens`, `wmc`) — abbreviations are standard, expanded forms or alternates (e.g. `exit` for `nexits`) are inconsistent | | P3 | Tree-sitter node-type strings used as identifiers match the upstream grammar's exact spelling (deviations are bugs, not style) | --- ## Step 4: Group findings into issues -**Key difference from `audit`**: Group findings into coherent tickets: +**Key difference from `audit-crate` / `audit-file`**: Group findings into coherent tickets: 1. Group by **file** if multiple findings in the same file 2. Group by **theme** if the same naming pattern repeats across files diff --git a/.claude/skills/audit-tests/SKILL.md b/.claude/skills/audit-tests/SKILL.md index cb89f7bd..e47fd813 100644 --- a/.claude/skills/audit-tests/SKILL.md +++ b/.claude/skills/audit-tests/SKILL.md @@ -18,7 +18,7 @@ Determine what to audit based on `$ARGUMENTS`: |----------|-------| | *(empty)* | Tests in unstaged + staged changes (`git diff HEAD`) | | `staged` | Tests in staged changes only (`git diff --cached`) | -| `branch` | Tests in all commits on current branch vs `master` (`git diff master...HEAD`) | +| `branch` | Tests in all commits on current branch vs `main` (`git diff main...HEAD`) | | *file path* | Specific test file | | *directory path* | All test files under the directory (`tests/`, `src/**/mod.rs`, `#[cfg(test)]` modules) | diff --git a/.claude/skills/batch-fix/SKILL.md b/.claude/skills/batch-fix/SKILL.md index 81feb5c8..c0c05fe2 100644 --- a/.claude/skills/batch-fix/SKILL.md +++ b/.claude/skills/batch-fix/SKILL.md @@ -113,6 +113,10 @@ The workspace crates are: traversal, metric computation, per-language modules - `big-code-analysis-cli` — CLI binary (`big-code-analysis-cli/`) - `big-code-analysis-web` — REST API server (`big-code-analysis-web/`) +- `big-code-analysis-py` — PyO3 Python bindings (`big-code-analysis-py/`, + excluded from default-members; needs Python headers + maturin) +- `xtask` — man-page generation helper (`xtask/`, excluded from + default-members) - `enums` — code-generation helper for language enums (`enums/`, excluded from default workspace) @@ -124,7 +128,8 @@ Use these signals in priority order: - "parser", "tree-sitter", "AST", "node", "grammar", "ParserTrait" -> `big-code-analysis` - "metric", "halstead", "cyclomatic", "cognitive", "loc", "abc", "wmc", - "nargs", "nom", "npa", "npm", "exit", "mi" -> `big-code-analysis` + "nargs", "nom", "npa", "npm", "nexits", "exit", "tokens", "mi" -> + `big-code-analysis` - "checker", "getter", "alterator", "spaces" -> `big-code-analysis` - "language X", a specific language name (rust, python, javascript, c, cpp, java, kotlin, typescript, etc.), or `src/languages/` path -> @@ -133,6 +138,9 @@ Use these signals in priority order: CLI flags) -> `big-code-analysis-cli` - "REST", "API", "server", "HTTP", "endpoint", "route" -> `big-code-analysis-web` + - "Python", "PyO3", "maturin", "stub", "`_native.pyi`", "wheel" -> + `big-code-analysis-py` + - "man page", "manpage", "xtask" -> `xtask` - "language enum", "enum generation", "code generation", `enums/templates/`, `enums/src/` -> `enums` 3. **Ambiguous**: If the crate cannot be determined from labels or keywords, @@ -528,6 +536,14 @@ After all waves are processed, if any merges succeeded: ```bash git checkout +``` + +Then run `make pre-commit` — the canonical gate per "Validation gates" +in `AGENTS.md` (it adds udeps, doc warnings, the lint families, the +self-scan gates, and `make snapshot-anchors` on top of the cargo trio). +If `make` is unavailable, fall back to: + +```bash cargo fmt --all -- --check cargo clippy --workspace --all-targets -- -D warnings cargo test --workspace --all-features @@ -739,12 +755,13 @@ Follow the `/fix-issue` workflow: cause is repeated, fix all instances. Similarly, if metric code under `src/metrics/` has the same anti-pattern in multiple metrics, fix all of them. -5. **Plan the fix using sequential thinking.** Use the - `sequential-thinking:sequentialthinking` MCP tool to reason through the - resolution step by step before writing any code. The sequential thinking - process MUST: - - **Start** with `thoughtNumber: 1`, an initial `totalThoughts` estimate - (typically 5-8), and `nextThoughtNeeded: true`. +5. **Plan the fix with explicit step-by-step reasoning.** If the + `sequential-thinking:sequentialthinking` MCP tool is available, use it + (start with `thoughtNumber: 1`, a `totalThoughts` estimate of typically + 5-8, and `nextThoughtNeeded: true`; adjust `totalThoughts` as + understanding evolves and use `isRevision` to correct earlier + reasoning; conclude with `nextThoughtNeeded: false`). If it is not + configured, reason through the same phases inline. The plan MUST: - **Analyze** the root cause — not just the symptom. Trace the data/control flow that leads to the bug. - **Enumerate approaches** and evaluate trade-offs (simplicity, @@ -761,15 +778,12 @@ Follow the `/fix-issue` workflow: code, or any other anti-pattern from `AGENTS.md`, redesign before proceeding. - **Verify completeness** — confirm the plan covers implementation, - tests for **every affected language**, and documentation before - concluding. - - **Conclude** with `nextThoughtNeeded: false` and a final plan summary. - - Adjust `totalThoughts` up or down as understanding evolves. Use - `isRevision` if earlier reasoning needs correction. + tests for **every affected language**, and documentation, and + conclude with a final plan summary. 6. **Implement the fix.** Execute the plan from step 5. Before changing any public API, run `find_referencing_symbols` (or workspace-wide `rg`) to enumerate every call site. If the implementation reveals issues the plan - missed, revise via sequential thinking before proceeding. + missed, revise the plan the same way before proceeding. 7. Self-review the implementation: - Correctness: root cause addressed, not just symptom? - Performance: appropriate algorithms and data structures? No O(n²) on @@ -795,7 +809,18 @@ Follow the `/fix-issue` workflow: language affected. - **Snapshot tests** (`insta`): if existing snapshots changed, run `cargo insta test --review` and accept each diff individually rather - than blindly accepting all. + than blindly accepting all. Every **new** + `insta::assert_json_snapshot!(metric.…)` must be anchored (inline + expected block, integer `assert_eq!` above the call, or an + `// expected: ` comment) — bare snapshots fail + `make snapshot-anchors`. + - **Integration-snapshot submodule**: a behaviour-changing metric / + traversal / alterator fix generates `.snap.new` inside + `tests/repositories/big-code-analysis-output/`. Follow the submodule + discipline in `AGENTS.md`: accept the snapshots, push them to the + submodule remote, and record the new submodule SHA in the **same** + commit as the fix (`git add tests/repositories/big-code-analysis-output` + is exempt from the "only files you changed" staging rule). - **Regression check**: `cargo test --workspace --all-features` and `cargo clippy --workspace --all-targets -- -D warnings` must pass. - Tests must actually assert what they claim — no silent fallbacks @@ -836,8 +861,8 @@ directly: - Helper functions that duplicate standard library or crate functionality - Duplicate logic across sibling language modules that should live in a shared helper, trait method, or macro (the project already uses - `c_langs_macros/`, `src/macros.rs`, and `src/c_macro.rs` for shared - structure) + `src/c_langs_macros/`, `src/macros/`, and `src/c_macro.rs` for shared + structure; follow `.claude/rules/macro-comments.md` when consolidating) **Clarity**: diff --git a/.claude/skills/cleanup-crate/SKILL.md b/.claude/skills/cleanup-crate/SKILL.md index 6f808abb..a91c59fe 100644 --- a/.claude/skills/cleanup-crate/SKILL.md +++ b/.claude/skills/cleanup-crate/SKILL.md @@ -68,8 +68,8 @@ Parse `$ARGUMENTS` as: ` [--dry-run] [--aggressive]` ## Constraints - **Deletions only**: no refactoring, no API changes, no behavioral changes -- **Do not merge to master**: leave the integration branch for the user - (note: this repo's default branch is `master`, not `main`) +- **Do not merge to main**: leave the integration branch for the user + (this repo's default branch is `main`) - **Skip on failure**: if any removal area fails, discard it and log the reason - **No re-examination**: skip files already reviewed in prior runs - **Never remove test code** @@ -108,7 +108,7 @@ If there are uncommitted changes, abort: ### 0c: Create integration branch ```bash -git checkout -b cleanup/ master +git checkout -b cleanup/ main ``` If the branch already exists from a prior partial run, check it out and @@ -328,7 +328,9 @@ cargo check -p If check fails, attempt to fix (one retry); otherwise SKIP. -If check passes, run the full validation: +If check passes, run the fast per-agent validation (the canonical +`make pre-commit` gate runs once on the integration branch in Step 4 — +do not pay its full cost per removal area): ```bash cargo fmt --all -- --check @@ -336,8 +338,6 @@ cargo clippy --workspace --all-targets -- -D warnings cargo test --workspace --all-features ``` -(If `pre-commit` is installed, also run `pre-commit run --all-files`.) - If validation fails: - If the failure is in code you changed, attempt to fix it (one retry). @@ -379,7 +379,8 @@ Return SUCCESS (branch, commit hash, files, removed symbols) or SKIPPED ## Step 4: Integrate successful changes -> **Branch mode**: Skip — integration happens inline in Step 3. +> **Branch mode**: Skip the merges — integration happened inline in +> Step 3 — but still run the validation gate below. For each successful worktree agent: @@ -390,7 +391,12 @@ git merge --no-edit If a merge conflict: `git merge --abort` and log as conflict. -After all merges, run the full validation suite on the integration branch. +After all merges (or directly, in branch mode), run `make pre-commit` on +the integration branch — the canonical validation gate (see "Validation +gates" in `AGENTS.md`; it adds udeps, doc warnings, the lint families, +the self-scan gates, and `make snapshot-anchors` on top of the cargo +trio run in 3e). If `make` is unavailable, fall back to the raw cargo +gates from 3e. --- @@ -449,7 +455,7 @@ Branch: cleanup/ ``` Remind the user: "Integration branch `cleanup/` is ready for -review. Merge to `master` when satisfied." +review. Merge to `main` when satisfied." If approval-required items exist, suggest `--aggressive`. @@ -457,7 +463,7 @@ If approval-required items exist, suggest `--aggressive`. ## Guardrails -- Do NOT merge `cleanup/` into `master` +- Do NOT merge `cleanup/` into `main` - Do NOT remove public API items unless `--aggressive` is set - Do NOT remove items re-exported from `src/lib.rs` - Do NOT remove trait implementations diff --git a/.claude/skills/doc-author/SKILL.md b/.claude/skills/doc-author/SKILL.md index 97db1558..7163e106 100644 --- a/.claude/skills/doc-author/SKILL.md +++ b/.claude/skills/doc-author/SKILL.md @@ -13,7 +13,8 @@ source under `big-code-analysis-book/src/`). is an editor helper that applies those rules. If the skill and the convention disagree, the convention wins. For lessons-learned entries use the `lessons-learned` skill; for changelog entries follow the -changelog rules in `AGENTS.md`. This skill does neither. +`## Changelog` section of `docs/conventions/documentation.md` (plus the +stability-contract rules in `AGENTS.md`). This skill does neither. ## Arguments diff --git a/.claude/skills/fix-issue/SKILL.md b/.claude/skills/fix-issue/SKILL.md index 022f1689..c7f453e9 100644 --- a/.claude/skills/fix-issue/SKILL.md +++ b/.claude/skills/fix-issue/SKILL.md @@ -6,9 +6,9 @@ description: Complete workflow for fixing GitHub issues including investigation, # Fix GitHub Issue Workflow 1. Read the GitHub issue thoroughly (`gh issue view ` plus all comments). -2. If Serena (or another LSP-based code intelligence MCP) is available, activate - the project (`serena:activate_project`) so symbol-level navigation and editing - are the default. LSP tools are preferred over text-based search/edit for code; +2. If Serena (or another LSP-based code intelligence MCP) is available, read its + instructions manual (`serena:initial_instructions`) so symbol-level navigation + and editing are the default. LSP tools are preferred over text-based search/edit for code; fall back to `rg`/`fd` and the built-in Grep/Glob tools only when LSP is unavailable. Never use legacy `grep`/`find`. 3. Re-read any relevant project conventions (e.g., `CLAUDE.md`, `README.md`, and @@ -23,12 +23,14 @@ description: Complete workflow for fixing GitHub issues including investigation, `src/languages/` modules deliberately mirror each other; a bug in one language's metric implementation often exists in several. Fix all instances — do not leave known-broken siblings for a follow-up. -6. **Plan the fix using sequential thinking.** Use the - `sequential-thinking:sequentialthinking` MCP tool to reason through the - resolution step by step before writing any code. The sequential thinking - process MUST: - - **Start** with `thoughtNumber: 1`, an initial `totalThoughts` estimate - (typically 5-8), and `nextThoughtNeeded: true`. +6. **Plan the fix with explicit step-by-step reasoning.** If the + `sequential-thinking:sequentialthinking` MCP tool is available, use it + (start with `thoughtNumber: 1`, a `totalThoughts` estimate of typically + 5-8, and `nextThoughtNeeded: true`; adjust `totalThoughts` as + understanding evolves and use `isRevision` to correct earlier reasoning; + conclude with `nextThoughtNeeded: false`). If it is not configured, + reason through the same phases inline — the tool is a vehicle, not the + requirement. The plan MUST: - **Analyze** the root cause — not just the symptom. Trace the data/control flow that leads to the bug. - **Enumerate approaches** and evaluate trade-offs (simplicity, correctness, @@ -43,13 +45,11 @@ description: Complete workflow for fixing GitHub issues including investigation, unexplained abbreviation, a `to_string_lossy()` on an identifier path, `unsafe` code, or any other anti-pattern, redesign before proceeding. - **Verify completeness** — confirm the plan covers implementation, tests - for **every affected language**, and documentation before concluding. - - **Conclude** with `nextThoughtNeeded: false` and a final plan summary. - - Adjust `totalThoughts` up or down as understanding evolves. Use - `isRevision` if earlier reasoning needs correction. + for **every affected language**, and documentation, and conclude with a + final plan summary. 7. **Implement the fix.** Do NOT stop after planning — execute the plan from - step 6. If the implementation reveals issues the plan missed, revise via - sequential thinking before proceeding. Before changing any public API, run + step 6. If the implementation reveals issues the plan missed, revise the + plan the same way before proceeding. Before changing any public API, run `find_referencing_symbols` (or equivalent) to enumerate every call site. Remember: this crate is published on crates.io; public API breaks affect downstream users. @@ -68,6 +68,11 @@ description: Complete workflow for fixing GitHub issues including investigation, - Tests must actually assert what they claim — no silent fallbacks (`unwrap_or_else` that swallows failures), no missing assertions, no coupling to incidental host/filesystem details. + - **Test-via-revert for defensive refactors**: if the fix pins an + invariant rather than repairing a live bug, follow + `.claude/rules/testing.md` — prove the new test fails against the + pre-fix code before trusting it, and revert safely (never a + file-level restore over uncommitted work). 9. **Review the changes** for: - **Correctness**: Does the fix actually address the root cause, not just the symptom? @@ -88,10 +93,10 @@ description: Complete workflow for fixing GitHub issues including investigation, 10. Fix any issues found in review. If the fixes were non-trivial, re-review. Do NOT commit with known issues and plan to fix them in a follow-up — that is how fix-up chains happen. -11. Run `make pre-commit` as the final gate before committing. It runs - `cargo fmt --check`, the pair of clippy invocations, the workspace - tests with all features, `cargo +nightly udeps`, and the markdown / - TOML / shell / Makefile lint families in one parallel pass. If +11. Run `make pre-commit` as the final gate before committing. It is the + canonical entry point for the full validation gate (see "Validation + gates" in `AGENTS.md` for the current stage list — do not rely on a + from-memory subset). If `make` is unavailable, fall back to running the cargo gates manually (`cargo fmt --all -- --check`, `cargo clippy --workspace --all-targets -- -D warnings`, `cargo test --workspace --all-features`) plus `rumdl check` @@ -108,8 +113,10 @@ description: Complete workflow for fixing GitHub issues including investigation, change (rebuild first; never test stale). 13. **Update all documentation.** Review and update each of the following as applicable: - - `CHANGELOG.md` — add an entry under the appropriate section (Added, - Changed, Fixed) if the project keeps one. + - `CHANGELOG.md` — add an entry under `## [Unreleased]`. Public-API + changes must be cross-referenced against `STABILITY.md`; a + source-level break deferred to the next major bump is marked + **(breaking)** (see AGENTS.md "Editing principles"). - `README.md` — if user-facing behavior, install steps, or supported languages changed. - `big-code-analysis-book/` — if the change affects documented metrics, diff --git a/.claude/skills/improve-crate/SKILL.md b/.claude/skills/improve-crate/SKILL.md index e246637e..7b867ce1 100644 --- a/.claude/skills/improve-crate/SKILL.md +++ b/.claude/skills/improve-crate/SKILL.md @@ -28,7 +28,9 @@ Parse `$ARGUMENTS` as: ` [--dry-run]` ## Constraints - **Safe refactors only**: no public API changes, no data model changes, - no cross-crate changes + no cross-crate changes, no behavioral changes (improvements must be + behavior-neutral — observable output, including metric values, stays + identical) - **No public API breaks**: this is a published library — `lib.rs` re-exports, public traits (`ParserTrait`, `LanguageInfo`, etc.), and public types (`Metrics`, `FuncSpace`, language enums) are off-limits @@ -36,7 +38,7 @@ Parse `$ARGUMENTS` as: ` [--dry-run]` - **Cross-language parity**: per-language modules under `src/languages/` deliberately mirror each other; any change to one usually requires the same change to all sibling language modules -- **Do not merge to master**: leave the integration branch for the user +- **Do not merge to main**: leave the integration branch for the user - **Skip on failure** - **No re-examination**: skip files/symbols already reviewed in prior runs @@ -72,7 +74,7 @@ If dirty, abort. ### 0c: Create integration branch ```bash -git checkout -b improve/ master +git checkout -b improve/ main ``` If the branch already exists from a prior partial run, check it out and @@ -112,7 +114,7 @@ crate under improvement: ```bash cargo build -p big-code-analysis-cli >/dev/null 2>&1 -./target/debug/big-code-analysis-cli -m -O json -p "$CRATE_DIR" \ +./target/debug/bca metrics -O json "$CRATE_DIR" \ > /tmp/improve-metrics.json || true ``` @@ -294,7 +296,8 @@ full. Apply fixes directly: - Manual error-mapping chains replaceable by a single `From` impl - Identical match arms that can be consolidated - Helpers duplicated across `language_*.rs` that could move to - `src/macros.rs` / `c_langs_macros/` / a shared module + `src/macros/` / `src/c_langs_macros/` / a shared module (follow + `.claude/rules/macro-comments.md` when consolidating into macros) **Clarity**: @@ -368,21 +371,29 @@ change, public-trait change), STOP and report SKIPPED. ### 3e: Validate +Run the fast per-agent gate (the canonical `make pre-commit` gate runs +once on the integration branch in Step 4 — do not pay its full cost per +change area): + ```bash cargo fmt --all -- --check cargo clippy --workspace --all-targets -- -D warnings cargo test --workspace --all-features ``` -If `pre-commit` is installed, run `pre-commit run --all-files`. - If validation fails: - If the failure is in code you changed, attempt to fix (one retry). - Otherwise SKIP. For snapshot test changes: run `cargo insta test --review` and accept or -reject each snapshot deliberately. Do NOT blindly accept. +reject each snapshot deliberately. Do NOT blindly accept. If a change +shifts snapshots under `tests/repositories/big-code-analysis-output/` +(the integration-snapshot submodule), it is behaviour-changing: follow +the submodule discipline in `AGENTS.md` (accepted snapshots pushed to +the submodule remote, new submodule SHA recorded in the same commit) — +or treat the change as out of scope for this skill and SKIP, since +improvements here must stay behavior-neutral. ### 3f: Commit @@ -401,7 +412,9 @@ git commit -m "" ``` Commit format: `(): `, e.g. -`refactor(big-code-analysis): simplify halstead operator classification`. +`refactor(big-code-analysis): deduplicate operand-span helpers`. (Keep +examples behavior-neutral — a change that reclassifies operators would +shift metric values and trigger the submodule discipline in 3e.) ### 3g: Report result @@ -413,7 +426,8 @@ SUCCESS (branch, commit, files, summary) or SKIPPED (reason). ## Step 4: Integrate successful changes -> **Branch mode**: Skip — integration happens inline in Step 3. +> **Branch mode**: Skip the merges — integration happened inline in +> Step 3 — but still run the validation gate below. ```bash git checkout improve/ @@ -422,7 +436,12 @@ git merge --no-edit If conflict: `git merge --abort` and log. -After all merges, run the full validation suite. If it fails, bisect: +After all merges (or directly, in branch mode), run `make pre-commit` on +the integration branch — the canonical validation gate (see "Validation +gates" in `AGENTS.md`; it adds udeps, doc warnings, the lint families, +the self-scan threshold gates, and `make snapshot-anchors` on top of the +cargo trio run in 3e). If `make` is unavailable, fall back to the raw +cargo gates from 3e. If it fails, bisect: ```bash git revert -m 1 @@ -478,13 +497,13 @@ Branch: improve/ ``` Remind the user: "Integration branch `improve/` is ready for -review. Merge to `master` when satisfied." +review. Merge to `main` when satisfied." --- ## Guardrails -- Do NOT merge `improve/` into `master` +- Do NOT merge `improve/` into `main` - Do NOT change public APIs, public traits, or data models - Do NOT change items re-exported from `src/lib.rs` without authorization - Do NOT introduce per-language inconsistency in `src/languages/` diff --git a/.claude/skills/issue-plan/SKILL.md b/.claude/skills/issue-plan/SKILL.md index 75baa17f..c202185c 100644 --- a/.claude/skills/issue-plan/SKILL.md +++ b/.claude/skills/issue-plan/SKILL.md @@ -28,7 +28,7 @@ body text — do not rely on the title alone. Before planning, understand the relevant code: -1. Check whether the issue is already resolved (the fix is merged on `master` +1. Check whether the issue is already resolved (the fix is merged on `main` and the described behavior no longer applies). If so, add a comment explaining what resolved it (commit, PR, or code reference), apply the label `resolved` (create it first if needed: @@ -36,7 +36,9 @@ Before planning, understand the relevant code: and stop. Do NOT close the issue — leave that for a human. 2. Identify which crate(s), modules, or files the issue relates to. The workspace contains `big-code-analysis` (root library), - `big-code-analysis-cli`, and `big-code-analysis-web`. Per-language + `big-code-analysis-cli`, `big-code-analysis-web`, + `big-code-analysis-py` (PyO3 bindings), `xtask` (man-page + generation), and `enums` (language-enum codegen). Per-language logic lives under `src/languages/` (one `language_.rs` per supported language) and metric implementations under `src/metrics/`. 3. Use Serena LSP tools (`find_symbol`, `get_symbols_overview`, @@ -53,12 +55,13 @@ Before planning, understand the relevant code: ## Step 3: Develop a resolution plan using sequential thinking -Use the `sequential-thinking:sequentialthinking` MCP tool to reason through -the resolution step by step. The sequential thinking process MUST: +Reason through the resolution step by step. If the +`sequential-thinking:sequentialthinking` MCP tool is available, use it +(start with `thoughtNumber: 1`, a `totalThoughts` estimate of typically +5–8, and `nextThoughtNeeded: true`); otherwise work through the same +phases inline. The reasoning MUST: -1. **Start** with `thoughtNumber: 1`, an initial `totalThoughts` estimate - (typically 5–8), and `nextThoughtNeeded: true`. -2. **Analyze** the issue: root cause, affected code, potential approaches. +1. **Analyze** the issue: root cause, affected code, potential approaches. 3. **Evaluate** trade-offs (simplicity, correctness, performance, scope, risk to public API, risk of cross-language inconsistency). 4. **Propose** a concrete step-by-step resolution plan. @@ -169,7 +172,9 @@ separate comment. ## Guardrails -- **Always use sequential thinking**: Do not skip Step 3. +- **Always plan before rating**: Do not skip Step 3 (use the + sequential-thinking MCP tool when configured; otherwise reason + through the same phases inline). - **Preserve the original body**: Append only. - **Temp files for body updates**: Always use `--body-file`. - **No premature closure**: Do NOT close the issue. A human decides. diff --git a/.claude/skills/issue-triage/SKILL.md b/.claude/skills/issue-triage/SKILL.md index 118c5a7a..6b7416b7 100644 --- a/.claude/skills/issue-triage/SKILL.md +++ b/.claude/skills/issue-triage/SKILL.md @@ -13,7 +13,7 @@ creation, modification, or closing. - Empty → all qualifying open issues - `` → filter to issues whose title starts with that crate name (one of `big-code-analysis`, `big-code-analysis-cli`, - `big-code-analysis-web`) + `big-code-analysis-web`, `big-code-analysis-py`) - `` → filter to issues whose title or body references a specific language module (e.g., `python`, `rust`, `java`) @@ -21,26 +21,23 @@ creation, modification, or closing. ## Step 1: Fetch issues -### 1a: Ensure label vocabulary exists +### 1a: Check the label vocabulary `gh issue list --label ` returns empty rather than erroring, so -querying a non-existent label silently filters it out. Provision the -labels this skill expects up front: +querying a non-existent label silently filters it out. This skill is +read-only — do **not** create labels. Detect which expected labels are +missing and surface them instead: ```bash -ensure_label() { - local name="$1" color="$2" desc="$3" - if ! gh label list --limit 200 --json name --jq '.[].name' | grep -qx "$name"; then - gh label create "$name" --color "$color" --description "$desc" - fi -} -ensure_label refactor "fbca04" "Refactor without behavior change" -ensure_label security "ee0701" "Security-relevant finding" -ensure_label upstream-grammar "fbca04" "Cannot be fixed locally; needs upstream tree-sitter grammar change" +have="$(gh label list --limit 200 --json name --jq '.[].name')" +for l in bug enhancement documentation refactor security upstream-grammar; do + printf '%s\n' "$have" | rg -qx "$l" || echo "missing label: $l" +done ``` -`bug`, `enhancement`, and `documentation` already exist on most GitHub -repos; `low-priority` is provisioned by `issue-plan`. +List any missing labels in the report's caveats section (issues carrying +them cannot be grouped by label, and a maintainer or `issue-plan` run +must provision them). `low-priority` is provisioned by `issue-plan`. ### 1b: Query and merge diff --git a/.claude/skills/review/SKILL.md b/.claude/skills/review/SKILL.md index ba116154..e41d93fd 100644 --- a/.claude/skills/review/SKILL.md +++ b/.claude/skills/review/SKILL.md @@ -16,7 +16,7 @@ Determine what to review based on `$ARGUMENTS`: |----------|-------| | *(empty)* | Unstaged + staged changes (`git diff HEAD`) | | `staged` | Staged changes only (`git diff --cached`) | -| `branch` | All commits on current branch vs `master` (`git diff master...HEAD`) | +| `branch` | All commits on current branch vs `main` (`git diff main...HEAD`) | | `pr ` | Pull request diff (`gh pr diff `) | | `` | Single commit (`git show `) | | `..` | Commit range | diff --git a/.claude/skills/rust-optimize/SKILL.md b/.claude/skills/rust-optimize/SKILL.md index b871c042..b03c7fd3 100644 --- a/.claude/skills/rust-optimize/SKILL.md +++ b/.claude/skills/rust-optimize/SKILL.md @@ -6,7 +6,7 @@ description: > and better type-system modeling including newtypes, enums, and trait design. Use when asked to simplify, shorten, optimize, clean up, or modernize Rust code. argument-hint: "[file-or-crate] [--dry-run]" -allowed-tools: Read, Grep, Glob, Bash(cargo:*), Bash(rustc:*), Bash(rustfmt:*), Bash(clippy:*) +allowed-tools: Read, Grep, Glob, Bash(cargo:*), Bash(rustc:*) --- # Rust Code Optimizer @@ -27,7 +27,7 @@ Parse `$ARGUMENTS` as: `[target] [--dry-run]` |----------|-------| | *(empty)* | Unstaged + staged changes (`git diff HEAD`) | | `staged` | Staged changes only (`git diff --cached`) | -| `branch` | All commits on current branch vs `master` (`git diff master...HEAD`) | +| `branch` | All commits on current branch vs `main` (`git diff main...HEAD`) | | *crate name* | All `.rs` files in the crate (e.g. `big-code-analysis`, `big-code-analysis-cli`, `big-code-analysis-web`) | | *file or directory path* | Specific file or directory | | `--dry-run` | Stop after presenting the plan — do not apply changes | @@ -44,7 +44,7 @@ Parse `$ARGUMENTS` as: `[target] [--dry-run]` 3. **Create a working branch** when the target is a crate or directory: ```bash - git checkout -b optimize/ master + git checkout -b optimize/ main ``` If the branch already exists from a prior run, check it out and continue. @@ -117,7 +117,7 @@ Parse `$ARGUMENTS` as: `[target] [--dry-run]` 13. **Summarize** the diff: before/after line counts, categories applied. If a working branch was created, remind the user: - "Branch `optimize/` is ready for review. Merge to master when satisfied." + "Branch `optimize/` is ready for review. Merge to main when satisfied." --- @@ -274,8 +274,10 @@ Convert a slice to a fixed-size array reference without `try_into().unwrap()`. // BEFORE let arr: &[u8; 4] = chunk.try_into().unwrap(); -// AFTER (1.93) -let Some(arr) = chunk.as_array::<4>() else { panic!("wrong size") }; +// AFTER (1.93) — propagate the error; `panic!` is banned in non-test code +let Some(arr) = chunk.as_array::<4>() else { + return Err(Error::WrongChunkSize); +}; ``` ### D2. `fmt::from_fn` (requires 1.93) @@ -323,7 +325,9 @@ Eliminates custom `Serialize`/`Deserialize` impls on single-field wrappers. If 3+ types share identical method implementations differing only in type name, extract a `macro_rules!` to generate them. (This pattern is already used heavily across `src/languages/` — prefer extending the existing macros over inventing new -ones.) +ones.) When consolidating, follow `.claude/rules/macro-comments.md`: keep the +macro body minimal and hoist per-call rationale comments above each invocation, +never into the macro definition. --- @@ -355,7 +359,10 @@ Move rarely-used dependencies behind feature flags to reduce default compile sco ## Upgrade Decision Matrix -When an optimization requires a newer Rust version, flag it clearly: +This workspace's MSRV is already 1.94 (`rust-version` in the root +`Cargo.toml`), so every feature below is available without any bump — +apply them freely. The matrix matters only for hypothetical features +newer than the current MSRV; flag those clearly: | Optimization | Min Rust | Impact | |---|---|---| @@ -368,7 +375,8 @@ When an optimization requires a newer Rust version, flag it clearly: | `cfg` on `asm!` lines | 1.93 | Less asm block duplication | | Zeroed alloc helpers | 1.92 | Cleaner zero-init large buffers | -Always state upgrade requirement in the plan and let the user decide. +For anything above the current MSRV, state the upgrade requirement in the +plan and let the user decide. --- @@ -450,9 +458,9 @@ on Tier 2. Skip Tier 3 unless the user specifically requests it. - Do NOT change observable behavior (error messages, return types, side effects) - Do NOT add dependencies without explicit user approval - Do NOT touch code outside the target scope from `$ARGUMENTS` -- Do NOT apply patterns that require an MSRV bump without flagging it in the plan +- Do NOT apply patterns that require an MSRV bump past 1.94 without flagging it in the plan - Do NOT sacrifice readability for line-count reduction - Do NOT use `unsafe` code (project-wide ban) -- Do NOT merge the `optimize/` branch into `master` — leave it for the user +- Do NOT merge the `optimize/` branch into `main` — leave it for the user - Do NOT re-examine files/symbols marked clean in Serena memory (unless they have new git changes) - When in doubt about whether a transformation is safe, leave the code alone diff --git a/.claude/skills/scan-project/SKILL.md b/.claude/skills/scan-project/SKILL.md index 8629e42b..cfd99205 100644 --- a/.claude/skills/scan-project/SKILL.md +++ b/.claude/skills/scan-project/SKILL.md @@ -1,6 +1,6 @@ --- name: scan-project -description: Workspace-wide scan for logic errors, security issues, and metrics calculation bugs across all crates and all language modules. Runs 6 parallel sub-agents, one per scope partition, and applies a 50-question checklist that encodes every lesson in docs/development/lessons_learned.md. Files GitHub issues with fix plans. READ-ONLY — no commits, no file modifications. +description: Scan of the core library, CLI, and web crates for logic errors, security issues, and metrics calculation bugs across all language modules. Runs 6 parallel sub-agents, one per scope partition, and applies a 50-question checklist distilled from the highest-recurrence lessons in docs/development/lessons_learned.md. Files GitHub issues with fix plans. READ-ONLY — no commits, no file modifications. --- # Scan Project @@ -11,11 +11,16 @@ issues, and metrics calculation bugs. Unlike `audit-crate` (which audits one crate at a time with a general checklist), this skill: -- **Covers the whole workspace** in one invocation. +- **Covers the core library plus the CLI and web crates** in one + invocation (`big-code-analysis-py`, `xtask`, `enums`, and the vendored + `tree-sitter-*` grammar crates are out of scope — audit those with + `audit-crate`). - **Runs 6 sub-agents in parallel**, one per scope partition. -- **Applies a 50-question checklist** that encodes every lesson documented in - `docs/development/lessons_learned.md`, with 20 questions dedicated to - metrics calculation bugs that the general checklist does not cover. +- **Applies a 50-question checklist** distilled from the highest-recurrence + lessons in `docs/development/lessons_learned.md`, with 20 questions + dedicated to metrics calculation bugs that the general checklist does not + cover. (The lessons file keeps growing; when revising this checklist, + sweep lessons added since the last revision for new question material.) ## ABSOLUTE CONSTRAINTS @@ -171,7 +176,7 @@ The CLI binary is `bca` (declared as `[[bin]] name = "bca"` in ```bash if cargo build -p big-code-analysis-cli 2>/tmp/scan-cli-build.log; then - ./target/debug/bca -m -O json -p src/ \ + ./target/debug/bca metrics -O json src/ \ > /tmp/scan-metrics.json 2>/tmp/scan-metrics.err || true fi ``` @@ -234,7 +239,7 @@ Files: - `src/metrics/abc.rs` - `src/metrics/cognitive.rs` - `src/metrics/cyclomatic.rs` -- `src/metrics/exit.rs` +- `src/metrics/nexits.rs` - `src/metrics/halstead.rs` - `src/metrics/loc.rs` - `src/metrics/mi.rs` @@ -276,7 +281,9 @@ Report any discrepancy as a separate FINDING. ### Partition C — C-family language modules Files: +- `src/languages/language_c.rs` - `src/languages/language_cpp.rs` +- `src/languages/language_mozcpp.rs` - `src/languages/language_csharp.rs` - `src/languages/language_java.rs` - `src/languages/language_kotlin.rs` @@ -285,9 +292,8 @@ Checklist focus: all 50 questions. Special attention to Q32, Q37–Q42 (grammar root, else-if structural model, cross-language parity, dispatch gaps). Build the same sibling-parity audit table as Partition B for this language -family. The parity table covers the C/C++ side (`cpp` only — there is no -`language_c.rs` or `language_mozcpp.rs` in this workspace) and the JVM/ -managed side (`csharp`, `java`, `kotlin`). +family. The parity table covers the C/C++ side (`c`, `cpp`, `mozcpp`) and +the JVM/managed side (`csharp`, `java`, `kotlin`). ### Partition D — Other language modules @@ -303,6 +309,8 @@ Files (every `src/languages/language_*.rs` not in B or C): - `src/languages/language_tcl.rs` - `src/languages/language_elixir.rs` - `src/languages/language_groovy.rs` +- `src/languages/language_objc.rs` +- `src/languages/language_irules.rs` - `src/languages/language_ccomment.rs` - `src/languages/language_preproc.rs` @@ -321,7 +329,7 @@ Files: - `src/node.rs` - `src/parser.rs` - `src/traits.rs` -- `src/macros.rs` +- `src/macros/` (all files) - `src/c_macro.rs` - `src/lib.rs` @@ -442,8 +450,9 @@ Track depth per file: `full` | `partial` | `skimmed`. ### Section G — Metrics Calculation Bugs (Q31–Q50) -These questions encode every lesson in `docs/development/lessons_learned.md`. -Apply them to every file in Partitions A–D. +These questions distill the highest-recurrence metrics lessons from +`docs/development/lessons_learned.md`. Apply them to every file in +Partitions A–D. #### No-op trait implementations (Lesson 1) @@ -486,7 +495,7 @@ Apply them to every file in Partitions A–D. #### `_min` sentinel leak (Lesson 3 — extended) 34. For every `_min()` accessor across all metric files (`cognitive_min`, - `cyclomatic_min`, `exit_min`, `abc_min`, `nom_min`, `nargs_min`, and any + `cyclomatic_min`, `nexits_min`, `abc_min`, `nom_min`, `nargs_min`, and any others): is the `usize::MAX → 0.0` collapse applied (as in `src/metrics/tokens.rs:115-127` and `src/metrics/loc.rs`)? Any accessor that returns `usize::MAX as f64` or `f64::MAX` to callers (including JSON diff --git a/.claude/skills/simplify-rust/SKILL.md b/.claude/skills/simplify-rust/SKILL.md index 2657f1bb..ba8c6b60 100644 --- a/.claude/skills/simplify-rust/SKILL.md +++ b/.claude/skills/simplify-rust/SKILL.md @@ -17,7 +17,7 @@ Determine what to review based on `$ARGUMENTS`: |----------|-------| | *(empty)* | Unstaged + staged changes (`git diff HEAD`) | | `staged` | Staged changes only (`git diff --cached`) | -| `branch` | All commits on current branch vs `master` (`git diff master...HEAD`) | +| `branch` | All commits on current branch vs `main` (`git diff main...HEAD`) | | *path* | Specific file or directory (any argument that isn't a keyword above) | ## Process @@ -55,6 +55,9 @@ Look for duplicated logic and missing abstractions. - Helper functions that duplicate standard library or crate functionality - Per-language duplicated logic in `src/languages/` that could be expressed via a trait method or macro instead of being copied across language modules + (when consolidating into a macro, follow `.claude/rules/macro-comments.md`: + hoist per-language rationale comments above each invocation, not into the + macro body) **Do NOT extract**: one-off logic into tiny helpers that obscure the flow. Three similar lines are better than a premature abstraction. diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 00000000..c0b3bc07 --- /dev/null +++ b/.dockerignore @@ -0,0 +1,20 @@ +# The image only COPYs docker/mcp.json; everything else is bind-mounted at +# run time, so keep the build context tiny. Exclude build artefacts, VCS +# metadata, vendored fixtures, and per-developer state. +target +enums/target +big-code-analysis-book/book +.git +tests/repositories +node_modules +**/node_modules +big-code-analysis-py/.venv +**/__pycache__ +**/.pytest_cache +**/.mypy_cache +**/.ruff_cache +**/*.so +out +dist +.serena +.mcp.json diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index fc2f1363..f91d7ad5 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -629,19 +629,19 @@ jobs: # pyrightconfig.json's venvPath="." + venv=".venv" pair (relative # to pyrightconfig.json's location). A repo-root venv would leave # pyright unable to resolve the maturin-built _native module. - # Tool versions: keep these bounds in lockstep with - # big-code-analysis-py/pyproject.toml's [project.optional-dependencies].dev - # and with the ruff-pre-commit `rev:` in .pre-commit-config.yaml. - # Drift between the three is silent and breaks the local-CI parity - # guarantee of `make pre-commit` vs this job. + # requirements/dev.txt is the hash-pinned export of uv.lock's + # `dev` extra (regenerated by `make py-relock`), so this job + # installs the exact resolved set `make py-bootstrap` uses + # locally — no floor-vs-lockfile drift — and `--require-hashes` + # pins the supply chain (OpenSSF Scorecard Pinned-Dependencies). + # Keep the ruff-pre-commit `rev:` in .pre-commit-config.yaml in + # lockstep with the ruff version resolved there. - name: Create venv + install Python toolchain working-directory: big-code-analysis-py run: | python -m venv .venv source .venv/bin/activate - pip install --upgrade pip - pip install "ruff>=0.6,<0.16" "mypy>=1.10" "pyright>=1.1.380" \ - "maturin>=1.7,<2.0" "pytest>=8.0" + pip install --require-hashes -r requirements/dev.txt # maturin develop must precede mypy / pyright so the _native # extension is resolvable from the venv. Both type checkers # treat the .pyi stub as authoritative, but they still need to @@ -718,21 +718,26 @@ jobs: # Cross-platform venv inside big-code-analysis-py/ (matches # pyrightconfig.json + the python-lint job + the local Makefile # convention). bash on Linux/macOS, PowerShell on Windows. + # requirements/dev.txt is the hash-pinned export of uv.lock's + # `dev` extra (regenerated by `make py-relock`): exact resolved + # versions with `--require-hashes` supply-chain pinning (OpenSSF + # Scorecard Pinned-Dependencies). It carries a few lint-only + # tools this job does not run (ruff / mypy / pyright) — the cost + # of installing them is preferred over maintaining a second, + # driftable pin set. - name: Create venv + install deps (Unix) if: runner.os != 'Windows' working-directory: big-code-analysis-py run: | python -m venv .venv - .venv/bin/pip install --upgrade pip - .venv/bin/pip install "maturin>=1.7,<2.0" "pytest>=8.0" "pytest-cov>=5.0" + .venv/bin/pip install --require-hashes -r requirements/dev.txt - name: Create venv + install deps (Windows) if: runner.os == 'Windows' working-directory: big-code-analysis-py shell: pwsh run: | python -m venv .venv - .venv\Scripts\python.exe -m pip install --upgrade pip - .venv\Scripts\python.exe -m pip install "maturin>=1.7,<2.0" "pytest>=8.0" + .venv\Scripts\python.exe -m pip install --require-hashes -r requirements/dev.txt # maturin develop uses the default (debug) profile to match the # local `make py-test` recipe — same .so layout end-to-end, so # local-CI parity issues surface in CI rather than only on a @@ -820,18 +825,13 @@ jobs: run: | python -m venv .venv source .venv/bin/activate - pip install --upgrade pip - # Install the [examples] extra contents directly (no `pip - # install -e .`) so we don't pay for a maturin PEP 517 - # build on top of the explicit `maturin develop` below. - # The version floors mirror the [examples] table in - # pyproject.toml — keep them in lockstep. - pip install \ - "jupyter>=1.0" \ - "nbconvert>=7.0" \ - "pandas>=2.0" \ - "matplotlib>=3.7" \ - "maturin>=1.7,<2.0" + # requirements/examples.txt is the hash-pinned export of + # uv.lock's [examples] extra (regenerated by `make + # py-relock`) — installing it directly (no `pip install -e + # .`) avoids a maturin PEP 517 build on top of the explicit + # `maturin develop` below, and `--require-hashes` pins the + # supply chain (OpenSSF Scorecard Pinned-Dependencies). + pip install --require-hashes -r requirements/examples.txt - name: maturin develop working-directory: big-code-analysis-py run: | diff --git a/.github/workflows/python-cli-wheels.yml b/.github/workflows/python-cli-wheels.yml index eb403422..8b518bed 100644 --- a/.github/workflows/python-cli-wheels.yml +++ b/.github/workflows/python-cli-wheels.yml @@ -338,11 +338,15 @@ jobs: run: | set -euo pipefail ls -la dist/ - python -m pip install --upgrade pip - # --no-index makes an accidental PyPI fallback (e.g. a wheel - # whose platform tag does not match this runner) fail loudly - # rather than silently installing a stale published version. - python -m pip install --no-index --find-links=dist big-code-analysis-cli + # Install the just-built wheel by path; the build job's verify + # step guarantees dist/ holds exactly one wheel, and --no-index + # makes an accidental PyPI fallback (e.g. a wheel whose + # platform tag does not match this runner) fail loudly rather + # than silently installing a stale published version. --no-deps + # is a no-op today (the bin wheel has zero Python runtime deps) + # but keeps a future dep addition from being resolved unpinned + # here (OpenSSF Scorecard Pinned-Dependencies). + python -m pip install --no-index --no-deps dist/*.whl # The console script lands in the setup-python interpreter's # scripts dir, which is on PATH. The assertions (version # lockstep against EXPECTED_TAG, the all-languages grammar set, diff --git a/.github/workflows/python-wheels.yml b/.github/workflows/python-wheels.yml index 2f88efe3..dabf2101 100644 --- a/.github/workflows/python-wheels.yml +++ b/.github/workflows/python-wheels.yml @@ -281,12 +281,17 @@ jobs: run: | set -euo pipefail ls -la dist/ - python -m pip install --upgrade pip - # Install only from the local dist; --no-index makes accidental - # PyPI fallback (e.g. when the wheel name does not match the - # current interpreter) fail loudly rather than silently install - # a stale published version. - python -m pip install --no-index --find-links=dist big-code-analysis + # Install the just-built wheel by path; the build job's verify + # step guarantees every wheel in dist/ matches this arch's + # abi3 pattern (and pip would fail loudly on a duplicate), and + # --no-index makes accidental PyPI fallback (e.g. when the + # wheel name does not match the current interpreter) fail + # loudly rather than silently install a stale published + # version. --no-deps is a no-op today (the wheel has zero + # Python runtime deps) but keeps a future dep addition from + # being resolved unpinned here (OpenSSF Scorecard + # Pinned-Dependencies). + python -m pip install --no-index --no-deps dist/*.whl # Exercise the public API surface that #103 enumerates: # analyze_source returns a dict, flatten_spaces yields function diff --git a/.github/workflows/smoke-dryrun.yml b/.github/workflows/smoke-dryrun.yml index f662f00d..e266a2b3 100644 --- a/.github/workflows/smoke-dryrun.yml +++ b/.github/workflows/smoke-dryrun.yml @@ -103,6 +103,12 @@ jobs: python -m venv .venv # shellcheck disable=SC1091 # venv activate script is created above . .venv/bin/activate - python -m pip install --upgrade pip maturin + # requirements/dev.txt is the hash-pinned export of uv.lock's + # `dev` extra (regenerated by `make py-relock`); the smoke only + # needs maturin from it, but reusing the one pinned set keeps + # `--require-hashes` supply-chain pinning (OpenSSF Scorecard + # Pinned-Dependencies) without a second driftable pin file. + python -m pip install --require-hashes \ + -r big-code-analysis-py/requirements/dev.txt maturin develop --manifest-path big-code-analysis-py/Cargo.toml python scripts/smoke/lib_wheel_smoke.py diff --git a/.gitignore b/.gitignore index 469fd8af..c3acf5bb 100644 --- a/.gitignore +++ b/.gitignore @@ -23,6 +23,11 @@ big-code-analysis-py/python/big_code_analysis/_native*.so *.pyc abuild-keys/ +# Dev-container corporate/proxy CA certs — dropped in per-environment to +# build behind a TLS-intercepting proxy; never commit them (see +# docker/README.md). The .gitkeep placeholder keeps the dir tracked. +docker/certs/*.crt + # CLI pip-wheel build artefacts. `python-cli-wheels.yml` stages the # generated TPL, a copy of the workspace LICENSE, and the `man/` pages # into the CLI crate directory and builds wheels under `dist/` there; diff --git a/AGENTS.md b/AGENTS.md index df73551c..3b209631 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -36,8 +36,9 @@ and `cargo run -p big-code-analysis-web --`. - `src/lib.rs` — public re-exports; this is the published API surface. - `src/languages/` — one `language_.rs` per supported language. These - modules deliberately mirror each other; macros under `c_langs_macros/`, - `src/macros.rs`, and `src/c_macro.rs` generate the shared structure. A + modules deliberately mirror each other; macros under + `src/c_langs_macros/`, `src/macros/`, and `src/c_macro.rs` generate the + shared structure. A bug in one language module typically exists in several — fix all affected siblings together. - `src/metrics/` — individual metric implementations: `abc.rs`, @@ -60,20 +61,20 @@ and `cargo run -p big-code-analysis-web --`. ## Editing principles -- This is a published `1.x` library (`big-code-analysis` on crates.io) +- This is a published `2.x` library (`big-code-analysis` on crates.io) with a written stability contract in [`STABILITY.md`](./STABILITY.md). Treat `lib.rs` re-exports, public traits (`ParserTrait`, `LanguageInfo`, etc.), and public types (`Metrics`, `FuncSpace`, - language enums) as a stable API surface. Within `1.x`, additive - changes belong under a minor bump; breaking shape changes are - reserved for `2.0` and must be planned deliberately — never slip a - SemVer break into a patch or minor release. Public-API changes - must be cross-referenced against `STABILITY.md` and recorded in - the `## [Unreleased]` section of `CHANGELOG.md`; if the change is - a source-level break that must wait for `2.0`, mark the entry - **(breaking)** and note that it is deferred to the next major - bump (the release-prep commit then moves the entry into the - appropriate version section). + language enums) as a stable API surface. Within the current major + line, additive changes belong under a minor bump; breaking shape + changes are reserved for the next major (`3.0`) and must be planned + deliberately — never slip a SemVer break into a patch or minor + release. Public-API changes must be cross-referenced against + `STABILITY.md` and recorded in the `## [Unreleased]` section of + `CHANGELOG.md`; if the change is a source-level break that must + wait for the next major, mark the entry **(breaking)** and note + that it is deferred to the next major bump (the release-prep + commit then moves the entry into the appropriate version section). - For code files: prefer LSP / symbol-level editing (`replace_symbol_body`, `insert_before/after_symbol`) over line-based edits when available. Read the file (or use a symbol overview) before @@ -114,15 +115,19 @@ and `cargo run -p big-code-analysis-web --`. `uv sync --locked --extra dev` from the checked-in `uv.lock`, producing a reproducible dev environment shared across contributors who use this path. After editing `pyproject.toml` deps, run - `make py-relock` (which runs `uv lock`) to regenerate the lockfile; - bootstrap will fail-loud rather than silently rewriting it. Install - uv with `curl -LsSf https://astral.sh/uv/install.sh | sh`, + `make py-relock`, which regenerates `uv.lock` **and** the + hash-pinned exports under `big-code-analysis-py/requirements/` + (`dev.txt`, `examples.txt`); bootstrap will fail-loud rather than + silently rewriting the lockfile. Install uv with + `curl -LsSf https://astral.sh/uv/install.sh | sh`, `brew install uv`, or `pipx install uv`. Alternative provisioning paths (`mise install` via `mise.toml`, direct `pipx install`, plain `pip install -e .[dev]`) remain functional but bypass `uv.lock` — - resolved versions can drift from peers and from CI. CI itself does - not yet consume `uv.lock` (workflows pip-install pyproject floors); - closing that gap is tracked as a follow-up. + resolved versions can drift from peers and from CI. CI consumes + `uv.lock` through those requirements exports (`pip install + --require-hashes -r …` in the workflows, per OpenSSF Scorecard + Pinned-Dependencies), so a `uv.lock` change and its regenerated + exports must land in the same commit. - **GitHub Actions linting**: any edit under `.github/workflows/` must be validated with `make actionlint` before commit. The Makefile target invokes `actionlint` at the repo root, which @@ -375,8 +380,8 @@ weigh them, do not drive them to zero at any cost. ## Tree-sitter grammars -External grammar crates are version-pinned (`=0.23.x`, etc.) in the root -`Cargo.toml`. Treat the pinned version as fixed: +External grammar crates are version-pinned (`=0.23.5`, `=0.26.10`, +etc.) in the root `Cargo.toml`. Treat the pinned version as fixed: - Do not loosen pins to a range without explicit user approval. - Bumping a grammar version is a deliberate, separate change — usually diff --git a/CHANGELOG.md b/CHANGELOG.md index f6fde4b1..c88e3cb6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -57,6 +57,29 @@ for historical reference. ### Security +- Cleared the two RUSTSEC advisories behind the OpenSSF Scorecard + Vulnerabilities alert: `anyhow` `1.0.102` → `1.0.103` (unsound + `Error::downcast_mut()`, RUSTSEC-2026-0190) and `memmap2` `0.9.10` + → `0.9.11` (unchecked pointer offset in the `advise_range` / + `flush_range` family, RUSTSEC-2026-0186). Both are transitive + dependencies (via `wit-parser` and `gix` respectively); neither + affected API is called directly by this workspace. +- Removed `test_ext`, a 4.3 MB compiled debug binary accidentally + committed at the repository root (flagged by the OpenSSF Scorecard + Binary-Artifacts check). Nothing referenced it. +- CI Python tooling is now hash-pinned (OpenSSF Scorecard + Pinned-Dependencies). Workflows install from + `big-code-analysis-py/requirements/{dev,examples}.txt` — exports of + `uv.lock` regenerated by `make py-relock` — with `pip install + --require-hashes`, replacing the floor-range `pip install`s; this + also closes the long-tracked "CI does not consume `uv.lock`" gap. + The wheel smoke jobs install the just-built wheel by explicit + `dist/*.whl` path with `--no-deps` (the build jobs already verify + exactly one wheel per artifact), and the unpinned + `pip install --upgrade pip` steps are gone. `pytest-cov` joins the + `dev` extra and `maturin` the `examples` extra so the exports cover + exactly what each CI job needs. + - Cleared three RUSTSEC advisories flagged by the `cargo-deny` gate. `crossbeam-epoch` (a shipped transitive dependency via `crossbeam`) moves `0.9.18` → `0.9.20` for the invalid-pointer-dereference in its diff --git a/CLAUDE.md b/CLAUDE.md index fc519fef..ad2e2839 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -15,9 +15,8 @@ destroys other agents' in-progress work: - Never run `git worktree remove`, `git worktree prune`, or `rm -rf` on any worktree directory. -- Never `cd` to the main repository, check out `master` (the default - branch of this repo, *not* `main`), or write files outside your - worktree. +- Never `cd` to the main repository, check out `main` (this repo's + default branch), or write files outside your worktree. - Never use `/clean_gone` or any command that removes worktrees. - The only entity that may remove a worktree is the Claude Code runtime that created it (automatic cleanup on session end). @@ -47,6 +46,8 @@ destroys other agents' in-progress work: | Skill | Use when… | |-------|-----------| +| `add-lang` | Adding a new tree-sitter language end-to-end (grammar crate, enum, Checker/Getter/Alterator, metrics, tests, docs) | +| `batch-fix` | Fixing several GitHub issues at once on an integration branch (parallel worktrees per crate) | | `simplify-rust` | Reviewing a diff for reuse / clarity / efficiency, applying fixes inline | | `rust-optimize` | Reducing verbosity / modernizing Rust syntax with pedantic-clippy triage | | `review` | Read-only review of a diff, branch, PR, or commit range | @@ -54,7 +55,7 @@ destroys other agents' in-progress work: | `audit-crate` | Read-only crate-level audit that files GitHub issues for findings | | `audit-file` | Read-only single-file audit that files GitHub issues for findings | | `audit-naming` | Read-only crate-level audit of naming quality | -| `scan-project` | Workspace-wide scan for logic errors, security issues, and metrics calculation bugs (6 parallel agents, 50-question checklist) | +| `scan-project` | Scanning the core library + CLI + web crates for logic errors, security issues, and metrics calculation bugs (6 parallel agents, 50-question checklist) | | `cleanup-crate` | Removing dead code, unused imports, and unreachable paths from one crate | | `improve-crate` | Safe code-improvement workflow for one crate (clarity / reuse / efficiency) | | `issue-plan` | Reading an issue, building a sequential-thinking plan, rating it, applying `low-priority` | @@ -66,3 +67,12 @@ destroys other agents' in-progress work: The `audit-crate`, `audit-file`, `audit-naming`, `scan-project`, `issue-triage`, and `review` skills are read-only and must not modify the working tree; all other skills may edit code as part of their workflow. + +### Hooks + +`.claude/hooks/bca-check.sh` (the per-edit `bca check` feedback loop) is +opt-in and **not registered by default** — to enable it, copy the +`PostToolUse` registration snippet from +[`recipes/agent-feedback.md`](big-code-analysis-book/src/recipes/agent-feedback.md) +into your `.claude/settings.local.json`. It never blocks an edit and +no-ops silently when no `bca` binary is available. diff --git a/Cargo.lock b/Cargo.lock index cdf53016..c008fc6b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -288,9 +288,9 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.102" +version = "1.0.103" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f202df86484c868dbad7eaa557ef785d5c66295e41b460ef922eca0723b842c" +checksum = "2a4385e2e34eb35d6b3efe798b9eb88096925d87726c0798709bf56d9ed84af3" [[package]] name = "arc-swap" @@ -2935,9 +2935,9 @@ checksum = "f8ca58f447f06ed17d5fc4043ce1b10dd205e060fb3ce5b979b8ed8e59ff3f79" [[package]] name = "memmap2" -version = "0.9.10" +version = "0.9.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "714098028fe011992e1c3962653c96b2d578c4b4bce9036e15ff220319b1e0e3" +checksum = "d1219ed1b7f229ee7104d281dd01d6802fe28bb6e95d292942c4daacdeb798c0" dependencies = [ "libc", ] diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 00000000..9bb3ab04 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,343 @@ +# Dev container for big-code-analysis. +# +# Ships every runtime and tool needed to (a) run Claude Code plus the +# project's MCP servers (Context7, codegraph, Serena) and (b) run the full +# `make pre-commit` / `make ci` validation gate against a mounted checkout: +# Rust (stable 1.94 + nightly for udeps), Python 3.12 (+ uv/maturin), Node +# (for the npx-launched MCP servers), and the pinned lint tools. +# +# Tool versions are pinned to the same releases CI uses (see +# .github/workflows/ci.yml and mise.toml) so behaviour matches CI. Every +# downloaded binary is SHA256-verified, mirroring the project's +# pinned-dependency discipline. +# +# The three MCP servers (Context7, codegraph, Serena) are registered into +# Claude Code's user scope at build time from docker/mcp.json, so `claude` +# launches them as stdio subprocesses with no extra flags — no +# docker-compose, no separate server containers. +# +# Build/run via the Makefile: `make dev-env-build`, `make dev-env-run`, +# `make dev-env-shell` (see docker/README.md). The Makefile passes the +# host UID/GID as build args so the mounted repo stays writable. + +FROM ubuntu:noble + +# UID/GID for the in-container `dev` user. Defaults match the maintainer's +# host (2424); `make dev-env-build` overrides them with the caller's +# `id -u` / `id -g` so bind-mounted files are owned correctly. +ARG USER_UID=2424 +ARG USER_GID=2424 + +ENV DEBIAN_FRONTEND=noninteractive +ENV RUSTUP_HOME=/usr/local/rustup +ENV CARGO_HOME=/usr/local/cargo +# uv installs its managed tools (ruff/mypy/maturin/serena) into a system +# location with shims on the system PATH, so they survive the /home/dev +# volume mount at runtime rather than being shadowed by it. +ENV UV_TOOL_DIR=/opt/uv/tools +ENV UV_TOOL_BIN_DIR=/usr/local/bin +ENV PATH=/usr/local/cargo/bin:/home/dev/.local/bin:/usr/local/bin:$PATH + +# Toolchain / release pins. Keep these in lockstep with the sources noted: +# RUST_VERSION -> Cargo.toml workspace.package.rust-version +# NODE_MAJOR -> NodeSource line (>= 22.6 required by codegraph) +# RUMDL/…/ACTIONLINT -> .github/workflows/ci.yml lint job +ENV RUST_VERSION=1.94.0 +ENV NODE_MAJOR=24 +ENV RUMDL_VERSION=0.2.2 +ENV TAPLO_VERSION=0.10.0 +ENV SHFMT_VERSION=3.12.0 +ENV SHELLCHECK_VERSION=0.10.0 +ENV CHECKMAKE_VERSION=0.2.2 +ENV ACTIONLINT_VERSION=1.7.12 + +# --------------------------------------------------------------------------- +# APT repositories: GitHub CLI + NodeSource. Keyrings are fetched and +# dearmored explicitly rather than piped through apt-key (deprecated). +# --------------------------------------------------------------------------- +RUN apt-get update --quiet --quiet && \ + apt-get install --yes --no-install-recommends \ + ca-certificates curl gnupg wget && \ + rm -rf /var/lib/apt/lists/* + +# Optional corporate/proxy root CAs. Drop PEM `.crt` files into docker/certs/ +# to build behind a TLS-intercepting proxy (Netskope, Zscaler, corporate +# MITM, …); the directory ships empty so nothing environment-specific is +# committed. Certs are added to the system trust store here — before any +# HTTPS fetch below — and the env vars point every toolchain that keeps its +# own CA store (Node, Python, Cargo, git) at the same bundle, so an added CA +# is honored everywhere. With an empty docker/certs/ this is a no-op. +COPY docker/certs/ /usr/local/share/ca-certificates/corp-extra/ +RUN update-ca-certificates +ENV SSL_CERT_FILE=/etc/ssl/certs/ca-certificates.crt \ + NODE_EXTRA_CA_CERTS=/etc/ssl/certs/ca-certificates.crt \ + REQUESTS_CA_BUNDLE=/etc/ssl/certs/ca-certificates.crt \ + CARGO_HTTP_CAINFO=/etc/ssl/certs/ca-certificates.crt \ + GIT_SSL_CAINFO=/etc/ssl/certs/ca-certificates.crt + +RUN mkdir --parents --mode 0755 /etc/apt/keyrings && \ + wget --quiet --output-document=- https://cli.github.com/packages/githubcli-archive-keyring.gpg \ + > /etc/apt/keyrings/githubcli-archive-keyring.gpg && \ + chmod go+r /etc/apt/keyrings/githubcli-archive-keyring.gpg && \ + echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/githubcli-archive-keyring.gpg] https://cli.github.com/packages stable main" \ + > /etc/apt/sources.list.d/github-cli.list && \ + wget --quiet --output-document=- https://deb.nodesource.com/gpgkey/nodesource-repo.gpg.key \ + | gpg --dearmor --output /usr/share/keyrings/nodesource.gpg && \ + echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/nodesource.gpg] https://deb.nodesource.com/node_${NODE_MAJOR}.x nodistro main" \ + > /etc/apt/sources.list.d/nodesource.list + +# --------------------------------------------------------------------------- +# Base packages: build toolchain (Rust cc / tree-sitter grammars, node-gyp +# for codegraph's better-sqlite3), Python 3.12 headers (PyO3/maturin), +# C/C++ LSP + language servers' native deps, and the search/CLI tools the +# project's conventions require (ripgrep, fd-find). +# --------------------------------------------------------------------------- +RUN apt-get update --quiet --quiet && \ + apt-get upgrade --quiet --quiet --yes && \ + apt-get install --yes --no-install-recommends \ + gh \ + git \ + build-essential \ + pkg-config \ + libssl-dev \ + clang \ + clangd \ + nodejs \ + python3 \ + python3-dev \ + python3-venv \ + python3-pip \ + patchelf \ + ripgrep \ + fd-find \ + jq \ + less \ + vim \ + tree \ + unzip \ + procps \ + sudo \ + xz-utils && \ + apt-get clean && \ + rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* + +# --------------------------------------------------------------------------- +# Rust: stable (pinned) + nightly (for `cargo +nightly udeps`), with the +# components the gate needs. rust-analyzer doubles as the Rust LSP. +# --------------------------------------------------------------------------- +RUN set -eux; \ + wget --https-only --output-document=/tmp/rustup-init https://sh.rustup.rs; \ + chmod +x /tmp/rustup-init; \ + /tmp/rustup-init -y --no-modify-path --profile minimal --default-toolchain "$RUST_VERSION"; \ + rm /tmp/rustup-init; \ + rustup component add rustfmt clippy rust-analyzer llvm-tools-preview; \ + rustup toolchain install nightly --profile minimal; \ + rustup default "$RUST_VERSION" + +# Cargo dev/CI tools via cargo-binstall (prebuilt binaries — no long +# compiles). cargo-nextest / cargo-llvm-cov mirror CI; cargo-about / +# cargo-deny back `make release-check`; mdbook backs `make book`. +RUN set -eux; \ + curl -fsSL https://raw.githubusercontent.com/cargo-bins/cargo-binstall/main/install-from-binstall-release.sh | bash; \ + cargo binstall --no-confirm \ + cargo-udeps \ + cargo-insta \ + cargo-nextest \ + cargo-llvm-cov \ + cargo-about \ + cargo-deny \ + mdbook; \ + rm -rf "$CARGO_HOME/registry" "$CARGO_HOME/git" /tmp/* + +# --------------------------------------------------------------------------- +# taplo (TOML formatter/linter + LSP) — SHA256-verified release binary. +# --------------------------------------------------------------------------- +RUN <<'EOF' +set -eux +ARCH=$(uname -m) +case "$ARCH" in + x86_64) SHA256="8fe196b894ccf9072f98d4e1013a180306e17d244830b03986ee5e8eabeb6156" ;; + aarch64) SHA256="033681d01eec8376c3fd38fa3703c79316f5e14bb013d859943b60a07bccdcc3" ;; + *) echo "Unsupported architecture: $ARCH" && exit 1 ;; +esac +wget --quiet -O /tmp/taplo.gz "https://github.com/tamasfe/taplo/releases/download/${TAPLO_VERSION}/taplo-linux-${ARCH}.gz" +echo "${SHA256} /tmp/taplo.gz" | sha256sum --check +gunzip /tmp/taplo.gz +install -m 0755 /tmp/taplo /usr/local/bin/taplo +rm -f /tmp/taplo +taplo --version +EOF + +# --------------------------------------------------------------------------- +# shfmt (shell formatter) — SHA256-verified release binary. +# --------------------------------------------------------------------------- +RUN <<'EOF' +set -eux +case $(dpkg --print-architecture) in + amd64) SHFMT_ARCH="amd64"; SHA256="d9fbb2a9c33d13f47e7618cf362a914d029d02a6df124064fff04fd688a745ea" ;; + arm64) SHFMT_ARCH="arm64"; SHA256="5f3fe3fa6a9f766e6a182ba79a94bef8afedafc57db0b1ad32b0f67fae971ba4" ;; + *) echo "Unsupported architecture: $(dpkg --print-architecture)" && exit 1 ;; +esac +wget --quiet -O /tmp/shfmt "https://github.com/mvdan/sh/releases/download/v${SHFMT_VERSION}/shfmt_v${SHFMT_VERSION}_linux_${SHFMT_ARCH}" +echo "${SHA256} /tmp/shfmt" | sha256sum --check +install -m 0755 /tmp/shfmt /usr/local/bin/shfmt +rm -f /tmp/shfmt +shfmt --version +EOF + +# --------------------------------------------------------------------------- +# shellcheck (shell linter) — SHA256-verified release tarball. +# --------------------------------------------------------------------------- +RUN <<'EOF' +set -eux +ARCH=$(uname -m) +case "$ARCH" in + x86_64) SHA256="6c881ab0698e4e6ea235245f22832860544f17ba386442fe7e9d629f8cbedf87" ;; + aarch64) SHA256="324a7e89de8fa2aed0d0c28f3dab59cf84c6d74264022c00c22af665ed1a09bb" ;; + *) echo "Unsupported architecture: $ARCH" && exit 1 ;; +esac +wget --quiet -O /tmp/shellcheck.tar.xz "https://github.com/koalaman/shellcheck/releases/download/v${SHELLCHECK_VERSION}/shellcheck-v${SHELLCHECK_VERSION}.linux.${ARCH}.tar.xz" +echo "${SHA256} /tmp/shellcheck.tar.xz" | sha256sum --check +tar -xJf /tmp/shellcheck.tar.xz -C /tmp +install -m 0755 "/tmp/shellcheck-v${SHELLCHECK_VERSION}/shellcheck" /usr/local/bin/shellcheck +rm -rf /tmp/shellcheck.tar.xz "/tmp/shellcheck-v${SHELLCHECK_VERSION}" +shellcheck --version +EOF + +# --------------------------------------------------------------------------- +# rumdl (Markdown linter/formatter) — SHA256-verified release tarball. +# --------------------------------------------------------------------------- +RUN <<'EOF' +set -eux +case $(dpkg --print-architecture) in + amd64) TRIPLE="x86_64-unknown-linux-gnu"; SHA256="d38ad81c51221990d5e0204b4746f8c980a77de235aa875c2f30f02f9a19bb1a" ;; + arm64) TRIPLE="aarch64-unknown-linux-gnu"; SHA256="f64e74228bfd25ef83a7b8f7da44911d5f3c4b69ecfa6482c7f06de1e210255d" ;; + *) echo "Unsupported architecture: $(dpkg --print-architecture)" && exit 1 ;; +esac +wget --quiet -O /tmp/rumdl.tgz "https://github.com/rvben/rumdl/releases/download/v${RUMDL_VERSION}/rumdl-v${RUMDL_VERSION}-${TRIPLE}.tar.gz" +echo "${SHA256} /tmp/rumdl.tgz" | sha256sum --check +tar -xzf /tmp/rumdl.tgz -C /tmp +install -m 0755 /tmp/rumdl /usr/local/bin/rumdl +rm -f /tmp/rumdl.tgz /tmp/rumdl +rumdl --version +EOF + +# --------------------------------------------------------------------------- +# actionlint (GitHub Actions linter) — SHA256-verified release tarball. +# --------------------------------------------------------------------------- +RUN <<'EOF' +set -eux +case $(dpkg --print-architecture) in + amd64) ACTIONLINT_ARCH="amd64"; SHA256="8aca8db96f1b94770f1b0d72b6dddcb1ebb8123cb3712530b08cc387b349a3d8" ;; + arm64) ACTIONLINT_ARCH="arm64"; SHA256="325e971b6ba9bfa504672e29be93c24981eeb1c07576d730e9f7c8805afff0c6" ;; + *) echo "Unsupported architecture: $(dpkg --print-architecture)" && exit 1 ;; +esac +wget --quiet -O /tmp/actionlint.tgz "https://github.com/rhysd/actionlint/releases/download/v${ACTIONLINT_VERSION}/actionlint_${ACTIONLINT_VERSION}_linux_${ACTIONLINT_ARCH}.tar.gz" +echo "${SHA256} /tmp/actionlint.tgz" | sha256sum --check +tar -xzf /tmp/actionlint.tgz -C /tmp actionlint +install -m 0755 /tmp/actionlint /usr/local/bin/actionlint +rm -f /tmp/actionlint.tgz /tmp/actionlint +actionlint -version +EOF + +# --------------------------------------------------------------------------- +# checkmake (Makefile linter) — SHA256-verified release binary. amd64 uses +# the exact CI pin (mrtazz/checkmake 0.2.2); arm64 uses the checkmake/ +# checkmake fork (see CHECKMAKE_FORK_VERSION note above). Any other arch +# continues without it (`make makefile-check` becomes the one missing gate). +# --------------------------------------------------------------------------- +RUN <<'EOF' +set -eux +# mrtazz/checkmake 0.2.2 (the CI pin) ships an amd64 Linux binary only. On +# arm64, fall back to the maintained checkmake/checkmake fork (v0.3.2), which +# publishes arm64 builds and uses the same rules + .checkmake.ini format. +CHECKMAKE_FORK_VERSION="0.3.2" +case $(dpkg --print-architecture) in + amd64) + wget --quiet -O /tmp/checkmake "https://github.com/mrtazz/checkmake/releases/download/${CHECKMAKE_VERSION}/checkmake-${CHECKMAKE_VERSION}.linux.amd64" + echo "bedd033b06f2563809855ec2a9950c7a81acea6cd82937fd2f124e2c1c5fc3d5 /tmp/checkmake" | sha256sum --check + ;; + arm64) + wget --quiet -O /tmp/checkmake "https://github.com/checkmake/checkmake/releases/download/v${CHECKMAKE_FORK_VERSION}/checkmake-v${CHECKMAKE_FORK_VERSION}.linux.arm64" + echo "409167c4abb99407bd232c3bbd351b8a39df57997feafde5a08bddffb0f2dcb4 /tmp/checkmake" | sha256sum --check + ;; + *) + echo "WARNING: no checkmake build for $(dpkg --print-architecture); skipping (make makefile-check will be unavailable)" + ;; +esac +if [ -f /tmp/checkmake ]; then + install -m 0755 /tmp/checkmake /usr/local/bin/checkmake + rm -f /tmp/checkmake + checkmake --version +fi +EOF + +# --------------------------------------------------------------------------- +# Python tooling. uv is the project's canonical bootstrap (`make +# py-bootstrap` => `uv sync --locked`). ruff/mypy/maturin install as uv +# tools into the system location (see UV_TOOL_* above); pyright ships as a +# Node package so it uses the system Node instead of downloading its own. +# --------------------------------------------------------------------------- +RUN set -eux; \ + curl -LsSf https://astral.sh/uv/install.sh | env UV_INSTALL_DIR=/usr/local/bin sh; \ + mkdir -p "$UV_TOOL_DIR"; \ + uv tool install --python 3.12 ruff; \ + uv tool install --python 3.12 mypy; \ + uv tool install --python 3.12 maturin; \ + rm -rf /root/.cache + +# --------------------------------------------------------------------------- +# Node global packages, installed to the SYSTEM prefix (/usr) so they +# survive the /home/dev volume: Claude Code, the two npx-launched MCP +# servers (codegraph, Context7), plus the Python/Bash language servers. +# codegraph builds better-sqlite3 natively here (build-essential + python3). +# --------------------------------------------------------------------------- +RUN set -eux; \ + npm install -g \ + @anthropic-ai/claude-code \ + @optave/codegraph \ + @upstash/context7-mcp \ + pyright \ + bash-language-server; \ + npm cache clean --force; \ + rm -rf /root/.npm /tmp/* + +# Serena MCP server (LSP-backed code intelligence), pre-installed as a uv +# tool so it launches offline. Exposes the `serena` console script. +RUN set -eux; \ + uv tool install --python 3.12 git+https://github.com/oraios/serena; \ + rm -rf /root/.cache + +# --------------------------------------------------------------------------- +# Non-root dev user. UID/GID come from build args so bind-mounted repo +# files are owned by the caller. ubuntu:noble ships a default `ubuntu` +# user/group at UID/GID 1000, so remove it first — otherwise a host UID/GID +# of 1000 (the common Linux default) collides and useradd fails. dev owns +# the Rust dirs so it can add toolchains/components/crates at runtime. +# --------------------------------------------------------------------------- +RUN set -eux; \ + userdel --remove ubuntu 2>/dev/null || true; \ + groupadd --gid "$USER_GID" dev; \ + useradd --uid "$USER_UID" --gid "$USER_GID" --shell /bin/bash --create-home dev; \ + usermod --append --groups sudo dev; \ + echo 'dev ALL=(ALL) NOPASSWD:ALL' > /etc/sudoers.d/dev; \ + chmod 0440 /etc/sudoers.d/dev; \ + chown --recursive dev:dev "$RUSTUP_HOME" "$CARGO_HOME" + +USER dev +WORKDIR /home/dev/source/big-code-analysis + +# Runtime npm globals (as dev) land under the home dir, out of /usr. +RUN mkdir -p /home/dev/.local/bin && npm config set prefix /home/dev/.local + +# Register the MCP servers into Claude Code's user scope, sourced from the +# single committed definition so there is no drift. `claude` then launches +# Context7 / codegraph / Serena as stdio subprocesses in every session. +COPY --chown=dev:dev docker/mcp.json /home/dev/.config/bca/mcp.json +RUN set -eux; \ + for name in $(jq -r '.mcpServers | keys[]' /home/dev/.config/bca/mcp.json); do \ + cfg=$(jq -c ".mcpServers[\"${name}\"]" /home/dev/.config/bca/mcp.json); \ + claude mcp add-json --scope user "${name}" "${cfg}"; \ + done + +CMD ["bash"] diff --git a/Makefile b/Makefile index 9e747ab4..af293db8 100644 --- a/Makefile +++ b/Makefile @@ -59,7 +59,7 @@ FIND_EXCLUDE := $(foreach dir,$(EXCLUDE_DIRS),! -path './$(dir)/*') # warnings on `$(2)`, e.g. $(call find-by-ext,md,). find-by-ext = $(if $(FD),$(FD) --extension $(1) $(FD_EXCLUDE) $(2),find . -name "*.$(1)" -type f $(FIND_EXCLUDE)) -.PHONY: help check-tools build build-release check test test-doc fmt fmt-check markdown-fmt markdown-lint shellcheck sh-fmt sh-fmt-check toml-fmt toml-fmt-check toml-lint makefile-check actionlint snapshot-anchors grammar-marker-sync grammar-marker-sync-test check-versions check-manpage-assets enums-check enums-codegen-drift enums-codegen-drift-test self-scan self-scan-headroom self-scan-write-baseline self-scan-write-baseline-headroom vcs lint clippy udeps insta-review insta-accept clean distclean install install-cli install-web doc doc-open doc-check doc-check-docsrs book book-serve book-deploy all pre-commit ci release-check verify-changelog pkg-deb-local pkg-rpm-local py-bootstrap py-sync py-relock py-clean py-fmt py-fmt-check py-lint py-typecheck py-test py-stubtest smoke smoke-cli smoke-lib _check-find _pc-fmt _pc-clippy _pc-test _pc-doc-check _pc-udeps _pc-shellcheck _pc-markdown-lint _pc-toml-lint _pc-makefile-check _pc-actionlint _pc-snapshot-anchors _pc-grammar-marker-sync _pc-grammar-marker-sync-test _pc-check-versions _pc-check-versions-test _pc-check-grammar-crate-test _pc-check-manpage-assets _pc-enums-check _pc-enums-codegen-drift _pc-enums-codegen-drift-test _pc-self-scan _pc-self-scan-headroom _pc-py-fmt _pc-py-typecheck _pc-py-test _pc-py-stubtest _ci-fmt-check _ci-clippy _ci-test _ci-doc-check _ci-build _ci-udeps _ci-shellcheck _ci-markdown-lint _ci-toml-lint _ci-makefile-check _ci-actionlint _ci-snapshot-anchors _ci-grammar-marker-sync _ci-grammar-marker-sync-test _ci-check-versions _ci-check-versions-test _ci-check-grammar-crate-test _ci-check-manpage-assets _ci-enums-check _ci-enums-codegen-drift _ci-enums-codegen-drift-test _ci-enums-codegen-drift-test _ci-self-scan _ci-self-scan-headroom _ci-cargo-pipeline _ci-py-fmt-check _ci-py-lint _ci-py-typecheck _ci-py-test _ci-py-stubtest +.PHONY: help check-tools build build-release check test test-doc fmt fmt-check markdown-fmt markdown-lint shellcheck sh-fmt sh-fmt-check toml-fmt toml-fmt-check toml-lint makefile-check actionlint snapshot-anchors grammar-marker-sync grammar-marker-sync-test check-versions check-manpage-assets enums-check enums-codegen-drift enums-codegen-drift-test self-scan self-scan-headroom self-scan-write-baseline self-scan-write-baseline-headroom vcs lint clippy udeps insta-review insta-accept clean distclean install install-cli install-web doc doc-open doc-check doc-check-docsrs book book-serve book-deploy all pre-commit ci release-check verify-changelog pkg-deb-local pkg-rpm-local dev-env-build dev-env-run dev-env-shell dev-env-rm py-bootstrap py-sync py-relock py-clean py-fmt py-fmt-check py-lint py-typecheck py-test py-stubtest smoke smoke-cli smoke-lib _check-find _pc-fmt _pc-clippy _pc-test _pc-doc-check _pc-udeps _pc-shellcheck _pc-markdown-lint _pc-toml-lint _pc-makefile-check _pc-actionlint _pc-snapshot-anchors _pc-grammar-marker-sync _pc-grammar-marker-sync-test _pc-check-versions _pc-check-versions-test _pc-check-grammar-crate-test _pc-check-manpage-assets _pc-enums-check _pc-enums-codegen-drift _pc-enums-codegen-drift-test _pc-self-scan _pc-self-scan-headroom _pc-py-fmt _pc-py-typecheck _pc-py-test _pc-py-stubtest _ci-fmt-check _ci-clippy _ci-test _ci-doc-check _ci-build _ci-udeps _ci-shellcheck _ci-markdown-lint _ci-toml-lint _ci-makefile-check _ci-actionlint _ci-snapshot-anchors _ci-grammar-marker-sync _ci-grammar-marker-sync-test _ci-check-versions _ci-check-versions-test _ci-check-grammar-crate-test _ci-check-manpage-assets _ci-enums-check _ci-enums-codegen-drift _ci-enums-codegen-drift-test _ci-enums-codegen-drift-test _ci-self-scan _ci-self-scan-headroom _ci-cargo-pipeline _ci-py-fmt-check _ci-py-lint _ci-py-typecheck _ci-py-test _ci-py-stubtest # Default target help: @@ -154,6 +154,12 @@ help: @echo " verify-changelog Verify CHANGELOG.md has section for VERSION=x.y.z" @echo " pkg-deb-local Build .deb locally (host target, no CI matrix)" @echo " pkg-rpm-local Build .rpm locally (host target, no CI matrix)" + @echo "" + @echo "Dev container (Claude Code + MCP servers):" + @echo " dev-env-build Build the dev image (Rust/Python/Node + MCP servers)" + @echo " dev-env-run Start the dev container (detached, repo mounted)" + @echo " dev-env-shell Open a shell in the running dev container" + @echo " dev-env-rm Stop and remove the dev container" # --------------------------------------------------------------------------- # Prerequisites @@ -561,11 +567,18 @@ py-sync: py-bootstrap # dev-extra floor). Separated from py-bootstrap so lockfile churn is # always a deliberate, reviewable act — `make py-bootstrap` will not # silently update the lockfile on contributors' machines. +# The hash-pinned exports under big-code-analysis-py/requirements/ +# are regenerated in the same breath: CI installs its Python tooling +# with `pip install --require-hashes -r` from those files (OpenSSF +# Scorecard Pinned-Dependencies), so they must always mirror uv.lock. py-relock: @command -v uv >/dev/null 2>&1 || { \ echo "ERROR: uv missing — install via 'curl -LsSf https://astral.sh/uv/install.sh | sh' (or 'brew install uv', 'pipx install uv')"; \ exit 1; } @cd "$(BCA_PY_DIR)" && uv lock + @cd "$(BCA_PY_DIR)" && mkdir -p requirements && \ + uv export --locked --no-emit-project --extra dev -o requirements/dev.txt && \ + uv export --locked --no-emit-project --extra examples -o requirements/examples.txt # `scripts/smoke` is a second, separate ruff invocation rather than an extra # path on the bindings call: `--config` would otherwise re-root the bindings @@ -1305,3 +1318,41 @@ pkg-rpm-local: cargo generate-rpm -p big-code-analysis-cli --payload-compress zstd --output out/ cargo generate-rpm -p big-code-analysis-web --payload-compress zstd --output out/ @ls -lh out/*.rpm + +# --------------------------------------------------------------------------- +# Dev container +# +# A self-contained image with every runtime and tool needed to run Claude +# Code plus the project's MCP servers (Context7, codegraph, Serena) and the +# full validation gate against a mounted checkout. See docker/README.md. +# +# Plain `docker build` / `docker run` — no docker-compose. The build args +# pass the caller's UID/GID so the bind-mounted repo stays writable; the +# container mounts this repo at $(DEV_MOUNT) and Claude launches the MCP +# servers itself (they are registered into its user scope at image build). +# --------------------------------------------------------------------------- +DEV_IMAGE := big-code-analysis-dev:latest +DEV_CONTAINER := big-code-analysis-dev +DEV_MOUNT := /home/dev/source/big-code-analysis + +dev-env-build: + docker build \ + --build-arg USER_UID=$(shell id -u) \ + --build-arg USER_GID=$(shell id -g) \ + --tag $(DEV_IMAGE) \ + --file $(BASE_DIR)Dockerfile "$(BASE_DIR)" + +dev-env-run: + docker run --detach --init \ + --name $(DEV_CONTAINER) \ + --volume "$(BASE_DIR):$(DEV_MOUNT)" \ + --env ANTHROPIC_API_KEY \ + --env CODEGRAPH_LLM_API_KEY \ + $(DEV_IMAGE) sleep infinity + @echo "Started $(DEV_CONTAINER). Open a shell with: make dev-env-shell" + +dev-env-shell: + docker exec --interactive --tty --workdir $(DEV_MOUNT) $(DEV_CONTAINER) bash + +dev-env-rm: + docker rm --force $(DEV_CONTAINER) diff --git a/big-code-analysis-py/pyproject.toml b/big-code-analysis-py/pyproject.toml index c3287d9a..baa54fe0 100644 --- a/big-code-analysis-py/pyproject.toml +++ b/big-code-analysis-py/pyproject.toml @@ -51,11 +51,14 @@ environments = ["sys_platform != 'emscripten' and python_full_version < '3.15'"] # the resolved set matches the checked-in `uv.lock`). `uv pip install # -e .[dev]` and `pip install -e .[dev]` still work but bypass the # lockfile — they re-resolve from the version bounds below and can -# drift from CI / from peers. Pinned floors track the earliest -# versions exercised by CI; the upper bound on maturin stays open -# within the 1.x series. +# drift from CI / from peers. CI installs the same locked set via the +# hash-pinned exports under requirements/ (regenerated alongside +# uv.lock by `make py-relock`), so the floors below only bound +# un-locked installs; the upper bound on maturin stays open within +# the 1.x series. dev = [ "pytest>=8.0", + "pytest-cov>=5.0", "mypy>=1.10", "ruff>=0.6,<0.16", "pyright>=1.1.380", @@ -69,7 +72,16 @@ dev = [ # floors track the earliest versions that the notebook exercises; # nbconvert is pinned to >=7 so the API used in the CI step # (`jupyter nbconvert --execute --to notebook --inplace`) is stable. -examples = ["jupyter>=1.0", "nbconvert>=7.0", "pandas>=2.0", "matplotlib>=3.7"] +# maturin is included so the extra covers the notebook run end-to-end +# from source (`maturin develop` precedes the nbconvert execution both +# in CI and locally). +examples = [ + "jupyter>=1.0", + "nbconvert>=7.0", + "pandas>=2.0", + "matplotlib>=3.7", + "maturin>=1.7,<2.0", +] [tool.coverage.run] branch = true diff --git a/big-code-analysis-py/requirements/dev.txt b/big-code-analysis-py/requirements/dev.txt new file mode 100644 index 00000000..d22814f5 --- /dev/null +++ b/big-code-analysis-py/requirements/dev.txt @@ -0,0 +1,278 @@ +# This file was autogenerated by uv via the following command: +# uv export --locked --no-emit-project --extra dev -o requirements/dev.txt +ast-serialize==0.5.0 ; python_full_version < '3.15' and sys_platform != 'emscripten' \ + --hash=sha256:061ee58bdb52341c8201a6df41182a977736bae3b7ded87ca7176ca25a8a47ab \ + --hash=sha256:0668aa9459cfa8c9c49ddd2163ebcf43088ba045ef7492af6fe22e0098303101 \ + --hash=sha256:104e4a35bd7c124173c41760ef9aaea17ddb3f86c65cb643671d59afbe3ee94c \ + --hash=sha256:143a4ef63285a075871908fda3672dc21864b83a8ec3ee12304aa3e4c5387b9a \ + --hash=sha256:16db7c62ec0b8efe1d7afd283a388d8f74f2605d56032e5a37747d2de8dba027 \ + --hash=sha256:1943db345233cc7194a470f13afa9c59772c0b123dea0c9414c4d4ca54369759 \ + --hash=sha256:239a4c354e8d676e9d94631d1d4a64edc6b266f86ff3a5a80aedd344f342c01d \ + --hash=sha256:2782c36237c46dd1674542f2109740ea5ea485a169bf1431939ada0434e17934 \ + --hash=sha256:27d51654fc240a1e87e742d353d98eb45b75f62f129086b3596ab53df2ac2a43 \ + --hash=sha256:36be371028fc1675acb38a331bde160dbab7ff907fdf00b67eb6911aa106951b \ + --hash=sha256:5499e8797edff2a9186aa313ed382c6b422e798e9332d9953badcee6e69a88f2 \ + --hash=sha256:5880091bfe6f4f986f22866375c2e884843e7a0b6343ae41aeea659613d879b6 \ + --hash=sha256:6848f2a093fb5548751a9a09bff8fcd229e2bbeb0e3331f391b6ae6d26cd9903 \ + --hash=sha256:787baedb0262cc49e8ce37cc15c00ae818e46a165a3b36f5e21ed174998104cb \ + --hash=sha256:7d1a2de9de5be04652f0ed60738356ef94f66db37924a9499fffe98dc491aa0b \ + --hash=sha256:832d4c998e0b091fd60a6d6bceee535483c4d490de9ba85003af835225719261 \ + --hash=sha256:842d1c004bb466c7df036f95fabef789570541922b10976b12f5592a69cf0b38 \ + --hash=sha256:8f5c14f169eb0972c0c21bada5358b23d6047c76583b005234f865b11f1fa00a \ + --hash=sha256:92a31c9c20d25a076edaeec76b128a3535d74a24f340b9a8a7e96c9b86dc9642 \ + --hash=sha256:9cc22cf0c9be65e71cf88fda130af60d61eb4a79370ad4cfe7900d48a4aa2211 \ + --hash=sha256:b0c06d760909b095cc466356dfccd05a1c7233a6ca191c020dca2c6a6f16c24c \ + --hash=sha256:b15219e9cdc9f53f6f4cb51c009203507228226148c05c5e8fe451c28b435eb3 \ + --hash=sha256:b54f60c1d78767a53b67eaa663f0dfac3afe606aa07f1301572f588b73d64809 \ + --hash=sha256:b725026bafa801dbd7310eb13a75f0a2e370e7e51b2cb225f9d21fcfadf919ee \ + --hash=sha256:baf5eb061eb5bccade4128ad42da33787d72f6013809cd1b590376ece8b3c937 \ + --hash=sha256:be5173fb66f9b49026d9d5a2ff0fc7c7009077107c0eb285b2d60fdf1fe10bd1 \ + --hash=sha256:bf683d6363edf2b39eed6b6d4fe22d34b6203867a67e27134d9e2a2680c4bc4a \ + --hash=sha256:cae65289fc456fde04af979a2be09302ef5d8ab92ef23e596d6746dc267ada27 \ + --hash=sha256:cf25572c526add400f26a4750dc6ce0c3bb93fc1f75e7ae0cad4ce4f2cd5c590 \ + --hash=sha256:df1c00022cbbcb064bfaa505aa9c9295362443ce5dacb459d1331d3da353f887 \ + --hash=sha256:e42d729ef2be96a14efbad355093284739e3670ece3e534f82cc8832790911d9 \ + --hash=sha256:f66173891548c9f2726bf27957b41cabce12fa679dc6da505ddbde4d4b3b31cf \ + --hash=sha256:f8015cd071ac1339924ee2b8098c93e00e155f30a16f40ec9816fcf84f4753f6 + # via mypy +colorama==0.4.6 ; python_full_version < '3.15' and sys_platform == 'win32' \ + --hash=sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44 \ + --hash=sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6 + # via pytest +coverage==7.15.0 ; python_full_version < '3.15' and sys_platform != 'emscripten' \ + --hash=sha256:02adc79a920c73c647c5d117f55747df7f2de94571884758ce8bc58e04f0a796 \ + --hash=sha256:08fb028000ed0aaa0a4cbdfbb98be7cb42f370db973fbbb469733505ab20e13e \ + --hash=sha256:0bf781da64326b677be344df505171435b6f58716108606621d5d27d964fff8b \ + --hash=sha256:0bfc0be1f702042207a93a00523b1065ee1fe951e96edf311581c0bbc2e34888 \ + --hash=sha256:0e4950c9d6d3e39c64c991814ff315e2d0b9cb8152363594212c9e55208c0a8f \ + --hash=sha256:110cbdf8d2e216577312cf06ccf85539c0e5a5420ef747e4a4719b5e483c88cd \ + --hash=sha256:13fb759be317fdc62e0f56bffdf61cfcb45c7761ad6b71e3e583e71a67ae753c \ + --hash=sha256:20c8a976c365c8cb12f0cbd099508772ea41fb5fa80657a8506df0e11bd278c5 \ + --hash=sha256:20d9ccc4ebd0edc434d86dfd2a1dd2a8efa6b6b3073d0485a394fee86459ebb4 \ + --hash=sha256:27f31ecb458da3f859aab3f15ada871eb7a7768807d88df4a9f186bb17737970 \ + --hash=sha256:2bcf9afaf064172c6ec3c58a325a9957ad1178c05dd934e25f253321776e0676 \ + --hash=sha256:2c57a275078ee3fa185f83e400f765bc764a549de66d99b47881645cbd4ea629 \ + --hash=sha256:2c5d4619214f1d9993e7b00a8600d14614b7e9d84e89507460b126aa5e6559e5 \ + --hash=sha256:2c6f0fa473003905c6d5bac328ee4eba9fbea654f15bc24b8a3274b23363fa99 \ + --hash=sha256:31e5c3e70c85307ea35a12964e2e40f56ca2ee4b1c8c721ccf4609d17071080b \ + --hash=sha256:346771144d34f7fa84ec28386f78e0f31653f33cf35e19d253d5b35f9e8201da \ + --hash=sha256:363ab38cc78b615f11c9cac3cf1d7eef950c18b9fdedfb9066f59461dcf84d68 \ + --hash=sha256:3812c61afc6685c7999b39320779ab8f43b7a3081fdb0def39976e56fbdb9a21 \ + --hash=sha256:3bb3040e9f4bbe26fcb0cd7cc85ac63e630d3f3a9c74f027abf4caa27e706663 \ + --hash=sha256:41cb79af843222e11da87127ad0ecbfa878abadd0f770a4a99391a27d3887324 \ + --hash=sha256:52f9a4d2c4c56c8848bc2f524916698354b0211488b38c49ad9ae54f6cafbff6 \ + --hash=sha256:54fd9c53a5fafff509195f1b6a3f9be615d8e8362a3629ff1de23d270c03c86b \ + --hash=sha256:56da6a4cbe8f7e9e80bd072ca9cefe67d7106a440a7ec06519ec6507ac94ad19 \ + --hash=sha256:5be4caf3b28836f078abe700f8944dac4a65d78f16d6c600c89cb624e5535782 \ + --hash=sha256:5f764a3fa339bde6b3aa97657f5a6a3a9451e4a5b4ea98a2892c773a43525f77 \ + --hash=sha256:65a6b6164ee5c39e2f3803f314292d6c61a607ba7fee253d1e03c42dc3903502 \ + --hash=sha256:6c664c5444b1d970b1b2a450e21fb19ee5c9cfdf151ded2dda37260031cca0da \ + --hash=sha256:6cb3602054ccbe9f0d8c2dc04bbeba90d5719236e2cd06e042ddd6d3fc7b6e37 \ + --hash=sha256:6eb7c300fbed667fd6e3588eba71c1904cdb06110ca6fdf908c26bdd88b8e382 \ + --hash=sha256:75128817f95a5c45bb01d65fd2d8b9cb54bbe03d81608fb70e3e14b437ad56c2 \ + --hash=sha256:769e8ece11a596315ebf5aa7ec383aeeed016c091d2bf6363ffb996d41529092 \ + --hash=sha256:781a704516e2d8346fbbd5be6c6f3412dd824785146528b3a01816f26c081007 \ + --hash=sha256:7d2008989ef8fe54188d3f3bfa2e3099b025af11e90a6a1b9e7dc433d04263d8 \ + --hash=sha256:87b47553097ba185ed964866078e7e63adea9f5f51b5f39691c34f30afd21080 \ + --hash=sha256:94c9686bfe8a9a6810297aecbd99beaa3445f9e8dc2f80b1382cca0d86b64461 \ + --hash=sha256:9887bb428fe2d4cd4bee89bac1a6c9932f484afd5b36fbd4ff6ea5f825bb1f5e \ + --hash=sha256:9ac3fe7a1435986463eaa8ee253ae2f2a268709ba4ae5c7dd1f52a05391ad78f \ + --hash=sha256:9bd671c25f9d85f09d7ec481d0e43d5139f486c06a37139847a7ce569788af72 \ + --hash=sha256:a263060f1de0b4b74b4e089c2a70b8003b3781c733329a9c8fd54995328f9950 \ + --hash=sha256:ab282853ed5fbd64bbb162f19cb8fcb7087187508a6374b4f9c34ec1577c4e8f \ + --hash=sha256:aeefb2dd178fe7eee79f0ad25d75855cb35ee9ed472db2c5ea06f5b4fd00cec5 \ + --hash=sha256:b5fb23fa2de9dce1f5c36c09066d8fcda16cd96e8e26686caa2d7cb9b567d65c \ + --hash=sha256:b75ee5e8cb7575636ac598719b4307ac529ec8fcd79608a35c3cd4d4dada812d \ + --hash=sha256:baf06bc987115d6fb938d403f7eab684a057766c490367999a2b71a6883110c6 \ + --hash=sha256:bb25d825d885ca8036795dacfc3924d33091fc76d71ebc99420c6b79e77d96fa \ + --hash=sha256:bbcbb317c2e5ded5b21104af81c29f391be2af98d065693ffbe8d23949b948e5 \ + --hash=sha256:bd4a1b44bcb65ee29e947ac92bbee04956df3a6bfc6143641bb6cae7ede00fc9 \ + --hash=sha256:c48decf16e0dfd5b049c7d5e82200c23c08126719142998d4f172444e3d0529e \ + --hash=sha256:cc78d9843bd576fbe2118248258d485e968dc535f95ed504a7b0867ba9b51389 \ + --hash=sha256:cec79341dbe6281484024979976d0c7f22beae08b4a254655decd25d42cbe766 \ + --hash=sha256:d34a010905fb6401324ba016b5da03d574967f7b21ce48ea41e66f0f1f95f641 \ + --hash=sha256:d5cf007add5ab4bb8fa9f4c77e3732127c9e6cad501d7db43355fbfafca0be84 \ + --hash=sha256:dd58ad1404704303ca8d4f4b8a1095e7cbc7040ef17a66df1e6619aa10176430 \ + --hash=sha256:e4d0bb73455bf97ab243a8f12c37c686ccf1c13bb614b7b85f1d062f06f42b2c \ + --hash=sha256:f00d5ae1dd2fe13fb8186e3e7d37bcbd8b25c0d764ff7d1b32cef9be058510a8 \ + --hash=sha256:f0405f2ff97b1c4c0e782cb32e02f32369bcf2e6b618b591d67e1ea754575dfe \ + --hash=sha256:f58185f06edf6ad68ec9fb155d63ef650c82f3fbd7e1770e2867751fb13158f4 \ + --hash=sha256:f64627d55def5a43282d70e08396672692f77e4da610a5bb8bb4060b432b6859 \ + --hash=sha256:f948fd5ba1b9cbca91f0ae08b4c1ce2b139509149a435e2585d056d57d70bf01 \ + --hash=sha256:fb7dc0c3b7d8a1077abea0b8546ebc5e26d6ef6ecefc2f0f5ad2b8a53bdad837 \ + --hash=sha256:fe9c87ff42e5472d80d21704972e1f96e104a0a599d77c5e35db5a3c562e2571 \ + --hash=sha256:ffb31267816b93b075302248cc1737506081b4f163df4401e9df1a6424aafabe + # via pytest-cov +iniconfig==2.3.0 ; python_full_version < '3.15' and sys_platform != 'emscripten' \ + --hash=sha256:c76315c77db068650d49c5b56314774a7804df16fee4402c1f19d6d15d8c4730 \ + --hash=sha256:f631c04d2c48c52b84d0d0549c99ff3859c98df65b3101406327ecc7d53fbf12 + # via pytest +librt==0.11.0 ; python_full_version < '3.15' and platform_python_implementation != 'PyPy' and sys_platform != 'emscripten' \ + --hash=sha256:05fb8fb2ab90e21c8d12ea240d744ad514da9baf381ebfa70d91d20d21713175 \ + --hash=sha256:070aa8c26c0a74774317a72df8851facc7f0f012a5b406557ac56992d92e1ec8 \ + --hash=sha256:075dc3ef4458a278e0195cbf6ac9d38808d9b906c5a6c7f7f79c3888276a3fb1 \ + --hash=sha256:0add982e0e7b9fc14cf4b33789d5f13f66581889b88c2f58099f6ce8f92617bd \ + --hash=sha256:0d1029d7e1ae1a7e647ed6fb5df8c4ce2dffefb7a9f5fd1376a4554d96dac09f \ + --hash=sha256:0dc56b1f8d06e60db362cc3fdae206681817f86ce4725d34511473487f12a34b \ + --hash=sha256:137e79445c896a0ea7b265f52d23954e05b64222ee1af69e2cb34219067cbb67 \ + --hash=sha256:28edb433edde181112a908c78907af28f964eabc15f4dd16c9d66c834302677c \ + --hash=sha256:2b481d846ac894c4e8403c5fd0e87c5d11d6499e404b474602508a224ff531c8 \ + --hash=sha256:2f10cf143e4a9bb0f4f5af568a00df94a2d69ef41c2579584454bb0fe5cc642c \ + --hash=sha256:32bcc918c0148eb7e3d57385125bac7e5f9e4359d05f07448b09f6f778c2f31c \ + --hash=sha256:40071fc5fe0ce8daa6de616702314a01e1250711682b0523d6ab8d4525910cb3 \ + --hash=sha256:4a017a95e5837dc15a8c5661d60e05daa96b90908b1aa6b7acdf443cd25c8ebd \ + --hash=sha256:4a9a237d13addb93715b6fee74023d5ee3469b53fce527626c0e088aa585805f \ + --hash=sha256:4ce1f21fbe589bc1afd7872dece84fb0e1144f794a288e58a10d2c54a55c43be \ + --hash=sha256:557183ddc36babe46b27dd60facbd5adb4492181a5be887587d57cda6e092f21 \ + --hash=sha256:5ba067f4aadae8fda802d91d2124c90c42195ff32d9161d3549e6d05cfe26f96 \ + --hash=sha256:5ddd17bd87b2c56ddd60e546a7984a2e64c4e8eab92fb4cf3830a48ad5469d51 \ + --hash=sha256:621db29691044bdeda22e789e482e1b0f3a985d90e3426c9c6d17606416205ea \ + --hash=sha256:6bf14feb84b05ae945277395451998c89c54d0def4070eb5c08de544930b245a \ + --hash=sha256:75672f0bc524ede266287d532d7923dbce94c7514ad07627bac3d0c6d92cc4d9 \ + --hash=sha256:78dc31f7fdfe9c9d0eb0e8f42d139db230e826415bbcabd9f0e9faaaee909894 \ + --hash=sha256:78fddc31cd4d3caa897ad5d31f856b1faadc9474021ad6cb182b9018793e254e \ + --hash=sha256:7aef3cf1d5af86e770ab04bfd993dfc4ae8b8c17f66fb77dd4a7d50de7bbb1a3 \ + --hash=sha256:7c39513d8b7477a2e1ed8c43fc21c524e8d5a0f8d4e8b7b074dbdbe7820a08e2 \ + --hash=sha256:7da327dacd7be8f8ec36547373550744a3cc0e536d54665cd83f8bcd961200e8 \ + --hash=sha256:83d3e1f72bd42f6c5c0b7daec530c3f829bd02db42c70b8ddf0c2d90a2459930 \ + --hash=sha256:8ca8aa88751a775870b764e93bad5135385f563cb8dcee399abf034ea4d3cb47 \ + --hash=sha256:936c5995f3514a42111f20099397d8177c79b4d7e70961e396c6f5a0a3566766 \ + --hash=sha256:96f044bb325fd9cf1a723015638c219e9143f0dfbc0ca54c565df2b7fc748b44 \ + --hash=sha256:970b09f7044ea2b64c9da42fd3d335666518cfd1c6e8a182c95da73d0214b41e \ + --hash=sha256:9bc0ca6ad9381cbe8e4aa6e5726e4c80c78115a6e9723c599ed1d73e092bc49d \ + --hash=sha256:a9010e2ed5b3a9e158c5fd966b3ab7e834bb3d3aacc8f66c91dd4b57a3799230 \ + --hash=sha256:aa0dd688aab3f7914d3e6e5e3554978e0383312fb8e771d84be008a35b9ee548 \ + --hash=sha256:ab73e8db5e3f564d812c1f5c3a175930a5f9bc96ccb5e3b22a34d7858b401cf7 \ + --hash=sha256:aea3caa317752e3a466fa8af45d91ee0ea8c7fdd96e42b0a8dd9b76a7931eba1 \ + --hash=sha256:b1ecbd9819deccc39b7542bf4d2a740d8a620694d39989e58661d3763458f8d4 \ + --hash=sha256:b87504f1690a23b9a2cca841191a04f83895d4fc2dd04df91d82b1a04ca2ad46 \ + --hash=sha256:bc3ce6b33c5828d9e80592011a5c584cb2ce86edbc4088405f70da47dc1d1b3b \ + --hash=sha256:bd43992b4473d42f12ff9e68326079f0696d9d4e6000e8f39a0238d482ba6ee2 \ + --hash=sha256:c1f708d8ae9c56cf38a903c44297243d2ec83fd82b396b977e0144a3e76217e3 \ + --hash=sha256:cae74872be221df4374d10fec61f93ed1513b9546ea84f2c0bf73ab3e9bd0b03 \ + --hash=sha256:cca6644054e78746d8d4ef238681f9c34ff8b584fe6b988ecebb8db3b15e622a \ + --hash=sha256:d1b36540d7aaf9b9101b3a6f376c8d8e9f7a9aec93ed05918f2c69d493ffef72 \ + --hash=sha256:d2277a05f6dcb9fd13db9566aac4fabd68c3ea1ea46ee5567d4eef8efa495a2f \ + --hash=sha256:d5b0eea49f5562861ee8d757a32ef7d559c1d35be2aaaa1ec28941d74c9ffc8a \ + --hash=sha256:de3bf945454d032f9e390b85c4072e0a0570bf825421c8be0e71209fa65e1abe \ + --hash=sha256:dee008f20b542e3cd162ba338a7f9ec0f6d23d395f66fe8aeeec3c9d067ea253 \ + --hash=sha256:efbb343ab2ce3540f4ecbe6315d677ed70f37cd9a72b1e58066c918ca83acbaa \ + --hash=sha256:f5fb36b8c6c63fdcbb1d526d94c0d1331610d43f4118cc1beb4efef4f3faacb2 \ + --hash=sha256:f8e3e8056dd674e279741485e2e512d6e9a751c7455809d0114e6ebf8d781085 \ + --hash=sha256:f9743fc99135d5f78d2454435615f6dec0473ca507c26ce9d92b10b562a280d3 \ + --hash=sha256:fa475675db22290c3158e1d42326d0f5a65f04f44a0e68c3630a25b53560fb9c + # via mypy +maturin==1.13.3 ; python_full_version < '3.15' and sys_platform != 'emscripten' \ + --hash=sha256:0ef257e692cc756c87af5bea95ddfe7d3ac49d3376a7a87f728d63f06e7b6f8b \ + --hash=sha256:1cc0a110b224ca90406b668a3e3c1f5a515062e59e26292f6dbaf5fd4909c6f3 \ + --hash=sha256:2389fe92d017cea9d94e521fa0175314a4c52f79a1057b901fbc9f8686ef7d0b \ + --hash=sha256:3cc13929ca82aefa4adbf0f2c35419369796213c6fb0eb24e914945f50ef5d8c \ + --hash=sha256:3db93337ed97e60ffc878aa8b493cd7ae44d3a5e1a37256db3a4491f57565018 \ + --hash=sha256:4667ef609ab446c1b5e0bfe4f9fb99699ab6d8548433f8d1a684256e0b67217f \ + --hash=sha256:49fd6ab08da28098ccf37afca24cdba72376ba9c1eedf9dd25ff82ed771961ff \ + --hash=sha256:4cd478e6e4c56251e48ed079b8efd55b30bc5c09cf695a1bdafaeb582ee735a0 \ + --hash=sha256:53b08bd075649ce96513ad9abf241a43cb685ed6e9e7790f8dbc2d66e95d8323 \ + --hash=sha256:771e1e9e71a278e56db01552e0d1acfd1464259f9575b6e72842f893cd299079 \ + --hash=sha256:a2675e25f313034ae6f57388cf14818f87d8961c4a96795287f3e155f59beb11 \ + --hash=sha256:b6741d7bf4af97da937528fd1e523c6ab54f53d9a21870fa735d6e67fd88e273 \ + --hash=sha256:c00ea6428dea17bf616fe93770837634454b28c2de1a876e42ef8036c616079a \ + --hash=sha256:def4a435ea9d2ee93b18ba579dc8c9cf898889a66f312cd379b5e374ec3e3ad6 + # via big-code-analysis +mypy==2.1.0 ; python_full_version < '3.15' and sys_platform != 'emscripten' \ + --hash=sha256:022c771234936ceac541ebaf836fe9e2abeb3f5e09aff21588fe543ff006fe21 \ + --hash=sha256:20509760fd791c51579d573153407d226385ec1f8bcce55d730b354f3336bc22 \ + --hash=sha256:244358bf1c0da7722230bce60683d52e8e9fd030554926f15b747a84efb5b3af \ + --hash=sha256:35aac3bb114e03888f535d5eb51b8bafbb3266586b599da1940f9b1be3ec5bd5 \ + --hash=sha256:498207db725cec88829a6a5c2fc771205fd043719ef98bc49aba8fb9fc4e6d57 \ + --hash=sha256:49890d4f76ac9e06ec117f9e09f3174da70a620a0c300953d8595c926e80947f \ + --hash=sha256:4ec7c57657493c7a75534df2751c8ae2cda383c16ecc55d2106c54476b1b16f6 \ + --hash=sha256:4f910fe825376a7b66ef7ca8c98e5a149e8cd64c19ae71d84047a74ee060d4e6 \ + --hash=sha256:5431d42af987ebd92ba2f71d45c85ed41d8e6ca9f5fd209a69f68f707d2469e5 \ + --hash=sha256:5fdf2941a07434af755837d9880f7d7d25f1dacb1af9dcd4b9b66f2220a3024e \ + --hash=sha256:6753d0c1fdd6b1a23b9e4f283ce80b2153b724adcb2653b20b85a8a28ac6436b \ + --hash=sha256:7354c5a7f69d9345c3d6e69921d57088eea3ddeeb6b20d34c1b3855b02c36ec2 \ + --hash=sha256:761be68e023ef5d94678772396a8af1220030f80837a3afd8d0aef3b419666f4 \ + --hash=sha256:767fe8c66dc3e01e19e1737d4c38ebefead16125e1b8e58ad421903b376f5c65 \ + --hash=sha256:7d5e5cad0efeba72b93cd17490cc0d69c5ac9ca132994fe3fb0314808aeeb83e \ + --hash=sha256:81e76ad12c2d804512e9b13240d1588316531bfba07558286078bfbce9613633 \ + --hash=sha256:82208da9e09414d520e912d3e462d454854bed0810b71540bb016dcbca7308fd \ + --hash=sha256:8de55a8c861f2a49331f807be98d90caeceeef520bde13d43a160207f8af613e \ + --hash=sha256:98ebb6589bb3b6d0c6f0c459d53ca55b8091fbc13d277c4041c885392e8195e8 \ + --hash=sha256:a663814603a5c563fb87a4f96fb473eeb30d1f5a4885afcf44f9db000a366289 \ + --hash=sha256:b33b6cd332695bba180d55e717a79d3038e479a2c49cc5eb3d53603409b9a5d7 \ + --hash=sha256:b84802e7b5a6daf1f5e15bc9fcd7ddae77be13981ffab037f1c67bb84d67d135 \ + --hash=sha256:bf03e12003084a67395184d3eb8cbd6a489dc3655b5664b28c210a9e2403ab0b \ + --hash=sha256:c90345fc182dc363b891350457ec69c35140858538f38b4540845afcc32b1aef \ + --hash=sha256:d8161b6ff4392410023224f0969d17db93e1e154bc3e4ba62598e720723ae211 \ + --hash=sha256:e195b817c13f02352a9c124301f9f30f078405444679b6753c1b96b6eed37285 \ + --hash=sha256:e583edc957cfb0deb142079162ae826f58449b116c1d442f2d91c69d9fced081 \ + --hash=sha256:e79ebc1b904b84f0310dff7469655a9c36c7a68bddb37bdd42b67a332df61d08 \ + --hash=sha256:ecfe70d43775ab99562ab128ce49854a362044c9f894961f68f898c23cb7429d \ + --hash=sha256:ff715050c127d724fd260a2e666e7747fdd83511c0c47d449d98238970aef780 + # via big-code-analysis +mypy-extensions==1.1.0 ; python_full_version < '3.15' and sys_platform != 'emscripten' \ + --hash=sha256:1be4cccdb0f2482337c4743e60421de3a356cd97508abadd57d47403e94f5505 \ + --hash=sha256:52e68efc3284861e772bbcd66823fde5ae21fd2fdb51c62a211403730b916558 + # via mypy +nodeenv==1.10.0 ; python_full_version < '3.15' and sys_platform != 'emscripten' \ + --hash=sha256:5bb13e3eed2923615535339b3c620e76779af4cb4c6a90deccc9e36b274d3827 \ + --hash=sha256:996c191ad80897d076bdfba80a41994c2b47c68e224c542b48feba42ba00f8bb + # via pyright +packaging==26.2 ; python_full_version < '3.15' and sys_platform != 'emscripten' \ + --hash=sha256:5fc45236b9446107ff2415ce77c807cee2862cb6fac22b8a73826d0693b0980e \ + --hash=sha256:ff452ff5a3e828ce110190feff1178bb1f2ea2281fa2075aadb987c2fb221661 + # via pytest +pathspec==1.1.1 ; python_full_version < '3.15' and sys_platform != 'emscripten' \ + --hash=sha256:17db5ecd524104a120e173814c90367a96a98d07c45b2e10c2f3919fff91bf5a \ + --hash=sha256:a00ce642f577bf7f473932318056212bc4f8bfdf53128c78bbd5af0b9b20b189 + # via mypy +pluggy==1.6.0 ; python_full_version < '3.15' and sys_platform != 'emscripten' \ + --hash=sha256:7dcc130b76258d33b90f61b658791dede3486c3e6bfb003ee5c9bfb396dd22f3 \ + --hash=sha256:e920276dd6813095e9377c0bc5566d94c932c33b27a3e3945d8389c374dd4746 + # via + # pytest + # pytest-cov +pygments==2.20.0 ; python_full_version < '3.15' and sys_platform != 'emscripten' \ + --hash=sha256:6757cd03768053ff99f3039c1a36d6c0aa0b263438fcab17520b30a303a82b5f \ + --hash=sha256:81a9e26dd42fd28a23a2d169d86d7ac03b46e2f8b59ed4698fb4785f946d0176 + # via pytest +pyright==1.1.409 ; python_full_version < '3.15' and sys_platform != 'emscripten' \ + --hash=sha256:986ee05beca9e077c165758ad123667c679e050059a2546aa02473930394bc93 \ + --hash=sha256:aa3ea228cab90c845c7a60d28db7a844c04315356392aa09fafcee98c8c22fb3 + # via big-code-analysis +pytest==9.0.3 ; python_full_version < '3.15' and sys_platform != 'emscripten' \ + --hash=sha256:2c5efc453d45394fdd706ade797c0a81091eccd1d6e4bccfcd476e2b8e0ab5d9 \ + --hash=sha256:b86ada508af81d19edeb213c681b1d48246c1a91d304c6c81a427674c17eb91c + # via + # big-code-analysis + # pytest-cov +pytest-cov==7.1.0 ; python_full_version < '3.15' and sys_platform != 'emscripten' \ + --hash=sha256:30674f2b5f6351aa09702a9c8c364f6a01c27aae0c1366ae8016160d1efc56b2 \ + --hash=sha256:a0461110b7865f9a271aa1b51e516c9a95de9d696734a2f71e3e78f46e1d4678 + # via big-code-analysis +ruff==0.15.14 ; python_full_version < '3.15' and sys_platform != 'emscripten' \ + --hash=sha256:049b5326e53ed80978f2fc041a280603f69dd6b0c95464342a2bb4572d9d9e2f \ + --hash=sha256:48d5909d7d06276ce7dde6d32bfa4b0d4cb2651145cd8ee4b440722cbc77832f \ + --hash=sha256:48e866b165be4a9bdbf310f7d3c9a07edef2fe8cd63ffeb4e00bb590506ebf9f \ + --hash=sha256:49072d36abdbe97a8dd7f480afe9c675699c0c495d4c84076e2c1203c4550581 \ + --hash=sha256:6d0c1ad2a0ab718d39b6d8fd2217981ce4d625cd96a720095f798fb47d8b13e6 \ + --hash=sha256:715c543cf450c4888251f91c52f1942a800541d9bddd7ac060aa4e6b77ae7cba \ + --hash=sha256:72ebab6013ec887d439d8b7593737a0a4ffb06d45d209d4e4bf2e92813082d3f \ + --hash=sha256:802342981e056db3851a7836e5b070f8f15f67d4a685ae2a6160939d364b2902 \ + --hash=sha256:8a24a4f7605d7003a6674d4387651effd939dead3fddd0f36561eb77a9a2e542 \ + --hash=sha256:8dd2db9416e487c8d4b01fa7056bb02c4d05969d4f8d17a08c229c2f4ff3c108 \ + --hash=sha256:958522aee105068640c2c2ceae08f413ae44d922f52a1374ac13d6a96032fc93 \ + --hash=sha256:9a6bbc0333f1ab053423bcbf6226477d266ca7cec7738c4c8e3f55647803f3c4 \ + --hash=sha256:bb01d645694e3ec0102105d07ef2d53703970407d59c04e59d3ba0b7a1d53553 \ + --hash=sha256:be4ff55af755bd71a00ab3dc6bd7ffc467bd76e0df6881e286c2e3d23e8fb43b \ + --hash=sha256:ca8cbfa94c4f90984a67561978602746d4cd27103568f745fa90eee3f0d4107d \ + --hash=sha256:d4ed42e6696c8dfa5f06728e6441993901f548eb92d73bc472cb5a38d1395fbf \ + --hash=sha256:f3707da619a143a2e8830e2abab8224478d69ace2d28cb6c20543ae97c36bf61 \ + --hash=sha256:ff47b90a9ef6a40c9e2f3b479c1fb78531adf055b94c1eba0a7ba04b31951826 + # via big-code-analysis +typing-extensions==4.15.0 ; python_full_version < '3.15' and sys_platform != 'emscripten' \ + --hash=sha256:0cea48d173cc12fa28ecabc3b837ea3cf6f38c6d1136f85cbaaf598984861466 \ + --hash=sha256:f0fa19c6845758ab08074a0cfa8b7aecb71c999ca73d62883bc25cc018c4e548 + # via + # mypy + # pyright diff --git a/big-code-analysis-py/requirements/examples.txt b/big-code-analysis-py/requirements/examples.txt new file mode 100644 index 00000000..67cf987c --- /dev/null +++ b/big-code-analysis-py/requirements/examples.txt @@ -0,0 +1,1302 @@ +# This file was autogenerated by uv via the following command: +# uv export --locked --no-emit-project --extra examples -o requirements/examples.txt +anyio==4.13.0 ; python_full_version < '3.15' and sys_platform != 'emscripten' \ + --hash=sha256:08b310f9e24a9594186fd75b4f73f4a4152069e3853f1ed8bfbf58369f4ad708 \ + --hash=sha256:334b70e641fd2221c1505b3890c69882fe4a2df910cba14d97019b90b24439dc + # via + # httpx + # jupyter-server +appnope==0.1.4 ; python_full_version < '3.15' and sys_platform == 'darwin' \ + --hash=sha256:1de3860566df9caf38f01f86f65e0e13e379af54f9e4bee1e66b48f2efffd1ee \ + --hash=sha256:502575ee11cd7a28c0205f379b525beefebab9d161b7c964670864014ed7213c + # via ipykernel +argon2-cffi==25.1.0 ; python_full_version < '3.15' and sys_platform != 'emscripten' \ + --hash=sha256:694ae5cc8a42f4c4e2bf2ca0e64e51e23a040c6a517a85074683d3959e1346c1 \ + --hash=sha256:fdc8b074db390fccb6eb4a3604ae7231f219aa669a2652e0f20e16ba513d5741 + # via jupyter-server +argon2-cffi-bindings==25.1.0 ; python_full_version < '3.15' and sys_platform != 'emscripten' \ + --hash=sha256:1db89609c06afa1a214a69a462ea741cf735b29a57530478c06eb81dd403de99 \ + --hash=sha256:1e021e87faa76ae0d413b619fe2b65ab9a037f24c60a1e6cc43457ae20de6dc6 \ + --hash=sha256:2630b6240b495dfab90aebe159ff784d08ea999aa4b0d17efa734055a07d2f44 \ + --hash=sha256:3c6702abc36bf3ccba3f802b799505def420a1b7039862014a65db3205967f5a \ + --hash=sha256:3d3f05610594151994ca9ccb3c771115bdb4daef161976a266f0dd8aa9996b8f \ + --hash=sha256:473bcb5f82924b1becbb637b63303ec8d10e84c8d241119419897a26116515d2 \ + --hash=sha256:7aef0c91e2c0fbca6fc68e7555aa60ef7008a739cbe045541e438373bc54d2b0 \ + --hash=sha256:84a461d4d84ae1295871329b346a97f68eade8c53b6ed9a7ca2d7467f3c8ff6f \ + --hash=sha256:87c33a52407e4c41f3b70a9c2d3f6056d88b10dad7695be708c5021673f55623 \ + --hash=sha256:8b8efee945193e667a396cbc7b4fb7d357297d6234d30a489905d96caabde56b \ + --hash=sha256:a1c70058c6ab1e352304ac7e3b52554daadacd8d453c1752e547c76e9c99ac44 \ + --hash=sha256:a98cd7d17e9f7ce244c0803cad3c23a7d379c301ba618a5fa76a67d116618b98 \ + --hash=sha256:aecba1723ae35330a008418a91ea6cfcedf6d31e5fbaa056a166462ff066d500 \ + --hash=sha256:b0fdbcf513833809c882823f98dc2f931cf659d9a1429616ac3adebb49f5db94 \ + --hash=sha256:b55aec3565b65f56455eebc9b9f34130440404f27fe21c3b375bf1ea4d8fbae6 \ + --hash=sha256:b957f3e6ea4d55d820e40ff76f450952807013d361a65d7f28acc0acbf29229d \ + --hash=sha256:ba92837e4a9aa6a508c8d2d7883ed5a8f6c308c89a4790e1e447a220deb79a85 \ + --hash=sha256:c4f9665de60b1b0e99bcd6be4f17d90339698ce954cfd8d9cf4f91c995165a92 \ + --hash=sha256:c87b72589133f0346a1cb8d5ecca4b933e3c9b64656c9d175270a000e73b288d \ + --hash=sha256:d3e924cfc503018a714f94a49a149fdc0b644eaead5d1f089330399134fa028a \ + --hash=sha256:e2fd3bfbff3c5d74fef31a722f729bf93500910db650c925c2d6ef879a7e51cb + # via argon2-cffi +arrow==1.4.0 ; python_full_version < '3.15' and sys_platform != 'emscripten' \ + --hash=sha256:749f0769958ebdc79c173ff0b0670d59051a535fa26e8eba02953dc19eb43205 \ + --hash=sha256:ed0cc050e98001b8779e84d461b0098c4ac597e88704a655582b21d116e526d7 + # via isoduration +asttokens==3.0.1 ; python_full_version < '3.15' and sys_platform != 'emscripten' \ + --hash=sha256:15a3ebc0f43c2d0a50eeafea25e19046c68398e487b9f1f5b517f7c0f40f976a \ + --hash=sha256:71a4ee5de0bde6a31d64f6b13f2293ac190344478f081c3d1bccfcf5eacb0cb7 + # via stack-data +async-lru==2.3.0 ; python_full_version < '3.15' and sys_platform != 'emscripten' \ + --hash=sha256:89bdb258a0140d7313cf8f4031d816a042202faa61d0ab310a0a538baa1c24b6 \ + --hash=sha256:eea27b01841909316f2cc739807acea1c623df2be8c5cfad7583286397bb8315 + # via jupyterlab +attrs==26.1.0 ; python_full_version < '3.15' and sys_platform != 'emscripten' \ + --hash=sha256:c647aa4a12dfbad9333ca4e71fe62ddc36f4e63b2d260a37a8b83d2f043ac309 \ + --hash=sha256:d03ceb89cb322a8fd706d4fb91940737b6642aa36998fe130a9bc96c985eff32 + # via + # jsonschema + # referencing +babel==2.18.0 ; python_full_version < '3.15' and sys_platform != 'emscripten' \ + --hash=sha256:b80b99a14bd085fcacfa15c9165f651fbb3406e66cc603abf11c5750937c992d \ + --hash=sha256:e2b422b277c2b9a9630c1d7903c2a00d0830c409c59ac8cae9081c92f1aeba35 + # via jupyterlab-server +beautifulsoup4==4.14.3 ; python_full_version < '3.15' and sys_platform != 'emscripten' \ + --hash=sha256:0918bfe44902e6ad8d57732ba310582e98da931428d231a5ecb9e7c703a735bb \ + --hash=sha256:6292b1c5186d356bba669ef9f7f051757099565ad9ada5dd630bd9de5fa7fb86 + # via nbconvert +bleach==6.4.0 ; python_full_version < '3.15' and sys_platform != 'emscripten' \ + --hash=sha256:4202482733d85cedd04e59fcb2f89f4e4c7c385a78d3c3c23c30446843a37452 \ + --hash=sha256:4b6b6a54fff2e69a3dde9d21cc6301220bee3c3cb792187d11403fd795031081 + # via nbconvert +certifi==2026.5.20 ; python_full_version < '3.15' and sys_platform != 'emscripten' \ + --hash=sha256:3c52e209ba0a4ad7aebe60436a4ab349c39e1e602e8c134221e546902ad25897 \ + --hash=sha256:69dea482ab64caa7b9f6aba1c6bf48bb6a5448d1c0f1b17ab42ad8c763a5344d + # via + # httpcore + # httpx + # requests +cffi==2.0.0 ; python_full_version < '3.15' and sys_platform != 'emscripten' \ + --hash=sha256:00bdf7acc5f795150faa6957054fbbca2439db2f775ce831222b66f192f03beb \ + --hash=sha256:07b271772c100085dd28b74fa0cd81c8fb1a3ba18b21e03d7c27f3436a10606b \ + --hash=sha256:087067fa8953339c723661eda6b54bc98c5625757ea62e95eb4898ad5e776e9f \ + --hash=sha256:0a1527a803f0a659de1af2e1fd700213caba79377e27e4693648c2923da066f9 \ + --hash=sha256:12873ca6cb9b0f0d3a0da705d6086fe911591737a59f28b7936bdfed27c0d47c \ + --hash=sha256:19f705ada2530c1167abacb171925dd886168931e0a7b78f5bffcae5c6b5be75 \ + --hash=sha256:1e3a615586f05fc4065a8b22b8152f0c1b00cdbc60596d187c2a74f9e3036e4e \ + --hash=sha256:1fc9ea04857caf665289b7a75923f2c6ed559b8298a1b8c49e59f7dd95c8481e \ + --hash=sha256:203a48d1fb583fc7d78a4c6655692963b860a417c0528492a6bc21f1aaefab25 \ + --hash=sha256:21d1152871b019407d8ac3985f6775c079416c282e431a4da6afe7aefd2bccbe \ + --hash=sha256:24b6f81f1983e6df8db3adc38562c83f7d4a0c36162885ec7f7b77c7dcbec97b \ + --hash=sha256:256f80b80ca3853f90c21b23ee78cd008713787b1b1e93eae9f3d6a7134abd91 \ + --hash=sha256:28a3a209b96630bca57cce802da70c266eb08c6e97e5afd61a75611ee6c64592 \ + --hash=sha256:2c8f814d84194c9ea681642fd164267891702542f028a15fc97d4674b6206187 \ + --hash=sha256:38100abb9d1b1435bc4cc340bb4489635dc2f0da7456590877030c9b3d40b0c1 \ + --hash=sha256:3925dd22fa2b7699ed2617149842d2e6adde22b262fcbfada50e3d195e4b3a94 \ + --hash=sha256:3e17ed538242334bf70832644a32a7aae3d83b57567f9fd60a26257e992b79ba \ + --hash=sha256:44d1b5909021139fe36001ae048dbdde8214afa20200eda0f64c068cac5d5529 \ + --hash=sha256:45d5e886156860dc35862657e1494b9bae8dfa63bf56796f2fb56e1679fc0bca \ + --hash=sha256:4671d9dd5ec934cb9a73e7ee9676f9362aba54f7f34910956b84d727b0d73fb6 \ + --hash=sha256:6c6c373cfc5c83a975506110d17457138c8c63016b563cc9ed6e056a82f13ce4 \ + --hash=sha256:6d02d6655b0e54f54c4ef0b94eb6be0607b70853c45ce98bd278dc7de718be5d \ + --hash=sha256:6d50360be4546678fc1b79ffe7a66265e28667840010348dd69a314145807a1b \ + --hash=sha256:737fe7d37e1a1bffe70bd5754ea763a62a066dc5913ca57e957824b72a85e205 \ + --hash=sha256:74a03b9698e198d47562765773b4a8309919089150a0bb17d829ad7b44b60d27 \ + --hash=sha256:7553fb2090d71822f02c629afe6042c299edf91ba1bf94951165613553984512 \ + --hash=sha256:7a66c7204d8869299919db4d5069a82f1561581af12b11b3c9f48c584eb8743d \ + --hash=sha256:7cc09976e8b56f8cebd752f7113ad07752461f48a58cbba644139015ac24954c \ + --hash=sha256:81afed14892743bbe14dacb9e36d9e0e504cd204e0b165062c488942b9718037 \ + --hash=sha256:8eca2a813c1cb7ad4fb74d368c2ffbbb4789d377ee5bb8df98373c2cc0dee76c \ + --hash=sha256:92b68146a71df78564e4ef48af17551a5ddd142e5190cdf2c5624d0c3ff5b2e8 \ + --hash=sha256:9a67fc9e8eb39039280526379fb3a70023d77caec1852002b4da7e8b270c4dd9 \ + --hash=sha256:afb8db5439b81cf9c9d0c80404b60c3cc9c3add93e114dcae767f1477cb53775 \ + --hash=sha256:b1e74d11748e7e98e2f426ab176d4ed720a64412b6a15054378afdb71e0f37dc \ + --hash=sha256:b21e08af67b8a103c71a250401c78d5e0893beff75e28c53c98f4de42f774062 \ + --hash=sha256:c654de545946e0db659b3400168c9ad31b5d29593291482c43e3564effbcee13 \ + --hash=sha256:c8d3b5532fc71b7a77c09192b4a5a200ea992702734a2e9279a37f2478236f26 \ + --hash=sha256:d48a880098c96020b02d5a1f7d9251308510ce8858940e6fa99ece33f610838b \ + --hash=sha256:d68b6cef7827e8641e8ef16f4494edda8b36104d79773a334beaa1e3521430f6 \ + --hash=sha256:d9b29c1f0ae438d5ee9acb31cadee00a58c46cc9c0b2f9038c6b0b3470877a8c \ + --hash=sha256:d9b97165e8aed9272a6bb17c01e3cc5871a594a446ebedc996e2397a1c1ea8ef \ + --hash=sha256:da68248800ad6320861f129cd9c1bf96ca849a2771a59e0344e88681905916f5 \ + --hash=sha256:da902562c3e9c550df360bfa53c035b2f241fed6d9aef119048073680ace4a18 \ + --hash=sha256:dbd5c7a25a7cb98f5ca55d258b103a2054f859a46ae11aaf23134f9cc0d356ad \ + --hash=sha256:dd4f05f54a52fb558f1ba9f528228066954fee3ebe629fc1660d874d040ae5a3 \ + --hash=sha256:f93fd8e5c8c0a4aa1f424d6173f14a892044054871c771f8566e4008eaa359d2 \ + --hash=sha256:fc33c5141b55ed366cfaad382df24fe7dcbc686de5be719b207bb248e3053dc5 + # via + # argon2-cffi-bindings + # pyzmq +charset-normalizer==3.4.7 ; python_full_version < '3.15' and sys_platform != 'emscripten' \ + --hash=sha256:03853ed82eeebbce3c2abfdbc98c96dc205f32a79627688ac9a27370ea61a49c \ + --hash=sha256:0c96c3b819b5c3e9e165495db84d41914d6894d55181d2d108cc1a69bfc9cce0 \ + --hash=sha256:0ea948db76d31190bf08bd371623927ee1339d5f2a0b4b1b4a4439a65298703c \ + --hash=sha256:0f7eb884681e3938906ed0434f20c63046eacd0111c4ba96f27b76084cd679f5 \ + --hash=sha256:1c2aed2e5e41f24ea8ef1590b8e848a79b56f3a5564a65ceec43c9d692dc7d8a \ + --hash=sha256:203104ed3e428044fd943bc4bf45fa73c0730391f9621e37fe39ecf477b128cb \ + --hash=sha256:2257141f39fe65a3fdf38aeccae4b953e5f3b3324f4ff0daf9f15b8518666a2c \ + --hash=sha256:298930cec56029e05497a76988377cbd7457ba864beeea92ad7e844fe74cd1f1 \ + --hash=sha256:2d6eb928e13016cea4f1f21d1e10c1cebd5a421bc57ddf5b1142ae3f86824fab \ + --hash=sha256:3534e7dcbdcf757da6b85a0bbf5b6868786d5982dd959b065e65481644817a18 \ + --hash=sha256:3946fa46a0cf3e4c8cb1cc52f56bb536310d34f25f01ca9b6c16afa767dab110 \ + --hash=sha256:3bec022aec2c514d9cf199522a802bd007cd588ab17ab2525f20f9c34d067c18 \ + --hash=sha256:3c9a494bc5ec77d43cea229c4f6db1e4d8fe7e1bbffa8b6f0f0032430ff8ab44 \ + --hash=sha256:3dce51d0f5e7951f8bb4900c257dad282f49190fdbebecd4ba99bcc41fef404d \ + --hash=sha256:3dedcc22d73ec993f42055eff4fcfed9318d1eeb9a6606c55892a26964964e48 \ + --hash=sha256:4042d5c8f957e15221d423ba781e85d553722fc4113f523f2feb7b188cc34c5e \ + --hash=sha256:481551899c856c704d58119b5025793fa6730adda3571971af568f66d2424bb5 \ + --hash=sha256:4dc1e73c36828f982bfe79fadf5919923f8a6f4df2860804db9a98c48824ce8d \ + --hash=sha256:54523e136b8948060c0fa0bc7b1b50c32c186f2fceee897a495406bb6e311d2b \ + --hash=sha256:5649fd1c7bade02f320a462fdefd0b4bd3ce036065836d4f42e0de958038e116 \ + --hash=sha256:56be790f86bfb2c98fb742ce566dfb4816e5a83384616ab59c49e0604d49c51d \ + --hash=sha256:5b77459df20e08151cd6f8b9ef8ef1f961ef73d85c21a555c7eed5b79410ec10 \ + --hash=sha256:5ed6ab538499c8644b8a3e18debabcd7ce684f3fa91cf867521a7a0279cab2d6 \ + --hash=sha256:6178f72c5508bfc5fd446a5905e698c6212932f25bcdd4b47a757a50605a90e2 \ + --hash=sha256:64f02c6841d7d83f832cd97ccf8eb8a906d06eb95d5276069175c696b024b60a \ + --hash=sha256:67f6279d125ca0046a7fd386d01b311c6363844deac3e5b069b514ba3e63c246 \ + --hash=sha256:6c114670c45346afedc0d947faf3c7f701051d2518b943679c8ff88befe14f8e \ + --hash=sha256:708838739abf24b2ceb208d0e22403dd018faeef86ddac04319a62ae884c4f15 \ + --hash=sha256:715479b9a2802ecac752a3b0efa2b0b60285cf962ee38414211abdfccc233b41 \ + --hash=sha256:733784b6d6def852c814bce5f318d25da2ee65dd4839a0718641c696e09a2960 \ + --hash=sha256:752a45dc4a6934060b3b0dab47e04edc3326575f82be64bc4fc293914566503e \ + --hash=sha256:7579e913a5339fb8fa133f6bbcfd8e6749696206cf05acdbdca71a1b436d8e72 \ + --hash=sha256:7804338df6fcc08105c7745f1502ba68d900f45fd770d5bdd5288ddccb8a42d8 \ + --hash=sha256:80d04837f55fc81da168b98de4f4b797ef007fc8a79ab71c6ec9bc4dd662b15b \ + --hash=sha256:8778f0c7a52e56f75d12dae53ae320fae900a8b9b4164b981b9c5ce059cd1fcb \ + --hash=sha256:8d828b6667a32a728a1ad1d93957cdf37489c57b97ae6c4de2860fa749b8fc1e \ + --hash=sha256:92a0a01ead5e668468e952e4238cccd7c537364eb7d851ab144ab6627dbbe12f \ + --hash=sha256:a180c5e59792af262bf263b21a3c49353f25945d8d9f70628e73de370d55e1e1 \ + --hash=sha256:a277ab8928b9f299723bc1a2dabb1265911b1a76341f90a510368ca44ad9ab66 \ + --hash=sha256:a5fe03b42827c13cdccd08e6c0247b6a6d4b5e3cdc53fd1749f5896adcdc2356 \ + --hash=sha256:a89c23ef8d2c6b27fd200a42aa4ac72786e7c60d40efdc76e6011260b6e949c4 \ + --hash=sha256:ae89db9e5f98a11a4bf50407d4363e7b09b31e55bc117b4f7d80aab97ba009e5 \ + --hash=sha256:aed52fea0513bac0ccde438c188c8a471c4e0f457c2dd20cdbf6ea7a450046c7 \ + --hash=sha256:bb6d88045545b26da47aa879dd4a89a71d1dce0f0e549b1abcb31dfe4a8eac49 \ + --hash=sha256:bd6c2a1c7573c64738d716488d2cdd3c00e340e4835707d8fdb8dc1a66ef164e \ + --hash=sha256:c03a41a8784091e67a39648f70c5f97b5b6a37f216896d44d2cdcb82615339a0 \ + --hash=sha256:c35abb8bfff0185efac5878da64c45dafd2b37fb0383add1be155a763c1f083d \ + --hash=sha256:c36c333c39be2dbca264d7803333c896ab8fa7d4d6f0ab7edb7dfd7aea6e98c0 \ + --hash=sha256:c45e9440fb78f8ddabcf714b68f936737a121355bf59f3907f4e17721b9d1aae \ + --hash=sha256:ce3412fbe1e31eb81ea42f4169ed94861c56e643189e1e75f0041f3fe7020abe \ + --hash=sha256:cf1493cd8607bec4d8a7b9b004e699fcf8f9103a9284cc94962cb73d20f9d4a3 \ + --hash=sha256:d6038d37043bced98a66e68d3aa2b6a35505dc01328cd65217cefe82f25def44 \ + --hash=sha256:e044c39e41b92c845bc815e5ae4230804e8e7bc29e399b0437d64222d92809dd \ + --hash=sha256:e1421b502d83040e6d7fb2fb18dff63957f720da3d77b2fbd3187ceb63755d7b \ + --hash=sha256:e712b419df8ba5e42b226c510472b37bd57b38e897d3eca5e8cfd410a29fa859 \ + --hash=sha256:e74327fb75de8986940def6e8dee4f127cc9752bee7355bb323cc5b2659b6d46 \ + --hash=sha256:e8ac484bf18ce6975760921bb6148041faa8fef0547200386ea0b52b5d27bf7b \ + --hash=sha256:eca9705049ad3c7345d574e3510665cb2cf844c2f2dcfe675332677f081cbd46 \ + --hash=sha256:edac0f1ab77644605be2cbba52e6b7f630731fc42b34cb0f634be1a6eface56a \ + --hash=sha256:effc3f449787117233702311a1b7d8f59cba9ced946ba727bdc329ec69028e24 \ + --hash=sha256:f495a1652cf3fbab2eb0639776dad966c2fb874d79d87ca07f9d5f059b8bd215 \ + --hash=sha256:f496c9c3cc02230093d8330875c4c3cdfc3b73612a5fd921c65d39cbcef08063 \ + --hash=sha256:f59099f9b66f0d7145115e6f80dd8b1d847176df89b234a5a6b3f00437aa0832 \ + --hash=sha256:f59ad4c0e8f6bba240a9bb85504faa1ab438237199d4cce5f622761507b8f6a6 \ + --hash=sha256:fbccdc05410c9ee21bbf16a35f4c1d16123dcdeb8a1d38f33654fa21d0234f79 \ + --hash=sha256:fea24543955a6a729c45a73fe90e08c743f0b3334bbf3201e6c4bc1b0c7fa464 + # via requests +colorama==0.4.6 ; python_full_version < '3.15' and sys_platform == 'win32' \ + --hash=sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44 \ + --hash=sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6 + # via ipython +comm==0.2.3 ; python_full_version < '3.15' and sys_platform != 'emscripten' \ + --hash=sha256:2dc8048c10962d55d7ad693be1e7045d891b7ce8d999c97963a5e3e99c055971 \ + --hash=sha256:c615d91d75f7f04f095b30d1c1711babd43bdc6419c1be9886a85f2f4e489417 + # via + # ipykernel + # ipywidgets +contourpy==1.3.3 ; python_full_version < '3.15' and sys_platform != 'emscripten' \ + --hash=sha256:023b44101dfe49d7d53932be418477dba359649246075c996866106da069af69 \ + --hash=sha256:07ce5ed73ecdc4a03ffe3e1b3e3c1166db35ae7584be76f65dbbe28a7791b0cc \ + --hash=sha256:083e12155b210502d0bca491432bb04d56dc3432f95a979b429f2848c3dbe880 \ + --hash=sha256:13b68d6a62db8eafaebb8039218921399baf6e47bf85006fd8529f2a08ef33fc \ + --hash=sha256:177fb367556747a686509d6fef71d221a4b198a3905fe824430e5ea0fda54eb5 \ + --hash=sha256:1cadd8b8969f060ba45ed7c1b714fe69185812ab43bd6b86a9123fe8f99c3263 \ + --hash=sha256:1fd43c3be4c8e5fd6e4f2baeae35ae18176cf2e5cced681cca908addf1cdd53b \ + --hash=sha256:22e9b1bd7a9b1d652cd77388465dc358dafcd2e217d35552424aa4f996f524f5 \ + --hash=sha256:283edd842a01e3dcd435b1c5116798d661378d83d36d337b8dde1d16a5fc9ba3 \ + --hash=sha256:2a2a8b627d5cc6b7c41a4beff6c5ad5eb848c88255fda4a8745f7e901b32d8e4 \ + --hash=sha256:2b7e9480ffe2b0cd2e787e4df64270e3a0440d9db8dc823312e2c940c167df7e \ + --hash=sha256:33c82d0138c0a062380332c861387650c82e4cf1747aaa6938b9b6516762e772 \ + --hash=sha256:348ac1f5d4f1d66d3322420f01d42e43122f43616e0f194fc1c9f5d830c5b286 \ + --hash=sha256:3c30273eb2a55024ff31ba7d052dde990d7d8e5450f4bbb6e913558b3d6c2301 \ + --hash=sha256:451e71b5a7d597379ef572de31eeb909a87246974d960049a9848c3bc6c41bf7 \ + --hash=sha256:459c1f020cd59fcfe6650180678a9993932d80d44ccde1fa1868977438f0b411 \ + --hash=sha256:4d00e655fcef08aba35ec9610536bfe90267d7ab5ba944f7032549c55a146da1 \ + --hash=sha256:4debd64f124ca62069f313a9cb86656ff087786016d76927ae2cf37846b006c9 \ + --hash=sha256:4feffb6537d64b84877da813a5c30f1422ea5739566abf0bd18065ac040e120a \ + --hash=sha256:50ed930df7289ff2a8d7afeb9603f8289e5704755c7e5c3bbd929c90c817164b \ + --hash=sha256:556dba8fb6f5d8742f2923fe9457dbdd51e1049c4a43fd3986a0b14a1d815fc6 \ + --hash=sha256:626d60935cf668e70a5ce6ff184fd713e9683fb458898e4249b63be9e28286ea \ + --hash=sha256:644a6853d15b2512d67881586bd03f462c7ab755db95f16f14d7e238f2852c67 \ + --hash=sha256:655456777ff65c2c548b7c454af9c6f33f16c8884f11083244b5819cc214f1b5 \ + --hash=sha256:66c8a43a4f7b8df8b71ee1840e4211a3c8d93b214b213f590e18a1beca458f7d \ + --hash=sha256:6afc576f7b33cf00996e5c1102dc2a8f7cc89e39c0b55df93a0b78c1bd992b36 \ + --hash=sha256:6c3d53c796f8647d6deb1abe867daeb66dcc8a97e8455efa729516b997b8ed99 \ + --hash=sha256:8153b8bfc11e1e4d75bcb0bff1db232f9e10b274e0929de9d608027e0d34ff8b \ + --hash=sha256:87acf5963fc2b34825e5b6b048f40e3635dd547f590b04d2ab317c2619ef7ae8 \ + --hash=sha256:88df9880d507169449d434c293467418b9f6cbe82edd19284aa0409e7fdb933d \ + --hash=sha256:92d9abc807cf7d0e047b95ca5d957cf4792fcd04e920ca70d48add15c1a90ea7 \ + --hash=sha256:95b181891b4c71de4bb404c6621e7e2390745f887f2a026b2d99e92c17892339 \ + --hash=sha256:a15459b0f4615b00bbd1e91f1b9e19b7e63aea7483d03d804186f278c0af2659 \ + --hash=sha256:a22738912262aa3e254e4f3cb079a95a67132fc5a063890e224393596902f5a4 \ + --hash=sha256:ab2fd90904c503739a75b7c8c5c01160130ba67944a7b77bbf36ef8054576e7f \ + --hash=sha256:ab3074b48c4e2cf1a960e6bbeb7f04566bf36b1861d5c9d4d8ac04b82e38ba20 \ + --hash=sha256:afe5a512f31ee6bd7d0dda52ec9864c984ca3d66664444f2d72e0dc4eb832e36 \ + --hash=sha256:b08a32ea2f8e42cf1d4be3169a98dd4be32bafe4f22b6c4cb4ba810fa9e5d2cb \ + --hash=sha256:b20c7c9a3bf701366556e1b1984ed2d0cedf999903c51311417cf5f591d8c78d \ + --hash=sha256:b2e8faa0ed68cb29af51edd8e24798bb661eac3bd9f65420c1887b6ca89987c8 \ + --hash=sha256:b7301b89040075c30e5768810bc96a8e8d78085b47d8be6e4c3f5a0b4ed478a0 \ + --hash=sha256:b7448cb5a725bb1e35ce88771b86fba35ef418952474492cf7c764059933ff8b \ + --hash=sha256:ca0fdcd73925568ca027e0b17ab07aad764be4706d0a925b89227e447d9737b7 \ + --hash=sha256:ca658cd1a680a5c9ea96dc61cdbae1e85c8f25849843aa799dfd3cb370ad4fbe \ + --hash=sha256:cbedb772ed74ff5be440fa8eee9bd49f64f6e3fc09436d9c7d8f1c287b121d77 \ + --hash=sha256:cf9022ef053f2694e31d630feaacb21ea24224be1c3ad0520b13d844274614fd \ + --hash=sha256:d002b6f00d73d69333dac9d0b8d5e84d9724ff9ef044fd63c5986e62b7c9e1b1 \ + --hash=sha256:d06bb1f751ba5d417047db62bca3c8fde202b8c11fb50742ab3ab962c81e8216 \ + --hash=sha256:d304906ecc71672e9c89e87c4675dc5c2645e1f4269a5063b99b0bb29f232d13 \ + --hash=sha256:e4e6b05a45525357e382909a4c1600444e2a45b4795163d3b22669285591c1ae \ + --hash=sha256:e74a9a0f5e3fff48fb5a7f2fd2b9b70a3fe014a67522f79b7cca4c0c7e43c9ae \ + --hash=sha256:ea37e7b45949df430fe649e5de8351c423430046a2af20b1c1961cae3afcda77 \ + --hash=sha256:f64836de09927cba6f79dcd00fdd7d5329f3fccc633468507079c829ca4db4e3 \ + --hash=sha256:fd6ec6be509c787f1caf6b247f0b1ca598bef13f4ddeaa126b7658215529ba0f \ + --hash=sha256:fd914713266421b7536de2bfa8181aa8c699432b6763a0ea64195ebe28bff6a9 \ + --hash=sha256:fde6c716d51c04b1c25d0b90364d0be954624a0ee9d60e23e850e8d48353d07a + # via matplotlib +cycler==0.12.1 ; python_full_version < '3.15' and sys_platform != 'emscripten' \ + --hash=sha256:85cef7cff222d8644161529808465972e51340599459b8ac3ccbac5a854e0d30 \ + --hash=sha256:88bb128f02ba341da8ef447245a9e138fae777f6a23943da4540077d3601eb1c + # via matplotlib +debugpy==1.8.20 ; python_full_version < '3.15' and sys_platform != 'emscripten' \ + --hash=sha256:077a7447589ee9bc1ff0cdf443566d0ecf540ac8aa7333b775ebcb8ce9f4ecad \ + --hash=sha256:352036a99dd35053b37b7803f748efc456076f929c6a895556932eaf2d23b07f \ + --hash=sha256:4057ac68f892064e5f98209ab582abfee3b543fb55d2e87610ddc133a954d390 \ + --hash=sha256:4ae3135e2089905a916909ef31922b2d733d756f66d87345b3e5e52b7a55f13d \ + --hash=sha256:55bc8701714969f1ab89a6d5f2f3d40c36f91b2cbe2f65d98bf8196f6a6a2c33 \ + --hash=sha256:5be9bed9ae3be00665a06acaa48f8329d2b9632f15fd09f6a9a8c8d9907e54d7 \ + --hash=sha256:5dff4bb27027821fdfcc9e8f87309a28988231165147c31730128b1c983e282a \ + --hash=sha256:84562982dd7cf5ebebfdea667ca20a064e096099997b175fe204e86817f64eaf \ + --hash=sha256:88f47850a4284b88bd2bfee1f26132147d5d504e4e86c22485dfa44b97e19b4b \ + --hash=sha256:9c74df62fc064cd5e5eaca1353a3ef5a5d50da5eb8058fcef63106f7bebe6173 \ + --hash=sha256:a1a8f851e7cf171330679ef6997e9c579ef6dd33c9098458bd9986a0f4ca52e3 \ + --hash=sha256:a98eec61135465b062846112e5ecf2eebb855305acc1dfbae43b72903b8ab5be \ + --hash=sha256:da11dea6447b2cadbf8ce2bec59ecea87cc18d2c574980f643f2d2dfe4862393 \ + --hash=sha256:eb506e45943cab2efb7c6eafdd65b842f3ae779f020c82221f55aca9de135ed7 + # via ipykernel +decorator==5.3.1 ; python_full_version < '3.15' and sys_platform != 'emscripten' \ + --hash=sha256:4cbcdd55a6efadb9dbea26b858f4fb3264567b52d69ca0d25b721b553f60ea82 \ + --hash=sha256:f47fe6fdbd2edd623ecfe36875d37aba411624e2670dd395dddae1358689bb3c + # via ipython +defusedxml==0.7.1 ; python_full_version < '3.15' and sys_platform != 'emscripten' \ + --hash=sha256:1bb3032db185915b62d7c6209c5a8792be6a32ab2fedacc84e01b52c51aa3e69 \ + --hash=sha256:a352e7e428770286cc899e2542b6cdaedb2b4953ff269a210103ec58f6198a61 + # via nbconvert +executing==2.2.1 ; python_full_version < '3.15' and sys_platform != 'emscripten' \ + --hash=sha256:3632cc370565f6648cc328b32435bd120a1e4ebb20c77e3fdde9a13cd1e533c4 \ + --hash=sha256:760643d3452b4d777d295bb167ccc74c64a81df23fb5e08eff250c425a4b2017 + # via stack-data +fastjsonschema==2.21.2 ; python_full_version < '3.15' and sys_platform != 'emscripten' \ + --hash=sha256:1c797122d0a86c5cace2e54bf4e819c36223b552017172f32c5c024a6b77e463 \ + --hash=sha256:b1eb43748041c880796cd077f1a07c3d94e93ae84bba5ed36800a33554ae05de + # via nbformat +fonttools==4.63.0 ; python_full_version < '3.15' and sys_platform != 'emscripten' \ + --hash=sha256:0eac00b9118c3c2f87d272e45341871c5b3066baa3c86897fa634a7c3fb59096 \ + --hash=sha256:1e874792a8212b44583ea02189d9e693906b2f78b261f372f95d6c563210ac1d \ + --hash=sha256:22135da48a348785c5e2d5d2d9d6bec5ed44adacbaeb9db12d9493bf6c6bfa68 \ + --hash=sha256:22693918177bd9ceabec4736d338045f357769416fc6b0b2508eefef75b08616 \ + --hash=sha256:27fdc65af8da6f88b9c6121c47a464cbe359fcfff7ff6fc2d37a1f395d755b78 \ + --hash=sha256:308f957cdeaf8abe4e5f2f124902ef405448af92c90f80e302a3b771c2e6116b \ + --hash=sha256:37dd23e621e3b0aef1baa70a303b80aaf38449632cfc8fd2a55fb285bbccfc02 \ + --hash=sha256:445af2eab030a16b9171ea8bdda7ebf7d96bda2df88ee182a464252f6e05e20d \ + --hash=sha256:51394295f1a51de8b5f30bdb1e1b9a4231536c7064ef5c6e211eec19fa36036f \ + --hash=sha256:58dc6bb86a78d782f00f9190ca02c119cf5bbe2807536e361e18d42019f877d8 \ + --hash=sha256:59ac449f8cca9b4ffa08d2e7bbadad87ce710d69d1eda5c3c1ce579baa987272 \ + --hash=sha256:6b2248c5decb223562f7902ff6325077a073f608ee8e33e88ad88db734eb9f49 \ + --hash=sha256:6d4741eb179121cab9eea4cb2393d24492373a260d7945006358c08cfbf45419 \ + --hash=sha256:6db5140a60a5d731d21ec076745b40a310607731b0a565b50776393188649001 \ + --hash=sha256:6e528da43bc3791085f8cb6141b1d13e459226790240340fcbb4625649238b03 \ + --hash=sha256:796f27556dbe094c4824f75ca85267e4df776c79036c8441469a4df37038c196 \ + --hash=sha256:7d76edbff9014094dbf03bd2d074709dfa6ec7aba13d838c937a2b33d2d6a86e \ + --hash=sha256:7d782fac32985914c351556f68ac0855391572bcd87de50e05970d3cd4c96fc5 \ + --hash=sha256:85be818f5506e8a7753153def2c9550178f0ecae6a47b5e0e8dbb23f7cc90380 \ + --hash=sha256:948428a275741f0b64b113c955425a953314f4b9ab9997f73a72c83e68e569c8 \ + --hash=sha256:9ced0bd02ac751dd6319b0da88aaef24414e3b0dbc32bb4f24944821a3741a27 \ + --hash=sha256:9e12f105d2b6342c559c298afb674006bb2893afc7102dcf8a1b55b0486b4e40 \ + --hash=sha256:a9faff9e0c1f76f9fd55899d2ce785832efebab37eb8ae13995853aef178bef0 \ + --hash=sha256:af2fd1664d00a397d75f806985ddb36282091c2131a73a6485c23b4a34722263 \ + --hash=sha256:ba04cb5891d4c0c21b6da95eda8d7b090021508a294fff33464fc7d241e0856b \ + --hash=sha256:bf00f21eb5fb721dbaf73d1e9da6d02a1af7768f2ebcf9798be98beab8ba90f6 \ + --hash=sha256:c1aaa4b9c75798400ac043ce04d74e7830376c85095a5a6ed7cba2f17a266bf4 \ + --hash=sha256:c2a2a42198b696a6f48fad91709afb55176e66a5e566131219dba372fb7f8c59 \ + --hash=sha256:caeb583deeb5168e694b65cda8b4ee62abedfa66cf88488734466f2366b9c4e0 \ + --hash=sha256:ccf41f2efdf56994d22d73bef4ced1052161958169428d06ba9724ea9e9a64be \ + --hash=sha256:cd7e9857e5e63738b9d9fd707bc1f59c8b09e5177726d23664db393c59bb08bd \ + --hash=sha256:ee08ebfa58f6e1aeff5697ab9582105bb620008c1caafb681e4c557e7483027b \ + --hash=sha256:ef3048ef05dbb552b89817713d9cac912e00d0fde4a3105c00d29e52e10c89af \ + --hash=sha256:fd1e3094f42d806d3d7c79162fc59e5910fcbe3a7360c385b8da969bc4493745 + # via matplotlib +fqdn==1.5.1 ; python_full_version < '3.15' and sys_platform != 'emscripten' \ + --hash=sha256:105ed3677e767fb5ca086a0c1f4bb66ebc3c100be518f0e0d755d9eae164d89f \ + --hash=sha256:3a179af3761e4df6eb2e026ff9e1a3033d3587bf980a0b1b2e1e5d08d7358014 + # via jsonschema +h11==0.16.0 ; python_full_version < '3.15' and sys_platform != 'emscripten' \ + --hash=sha256:4e35b956cf45792e4caa5885e69fba00bdbc6ffafbfa020300e549b208ee5ff1 \ + --hash=sha256:63cf8bbe7522de3bf65932fda1d9c2772064ffb3dae62d55932da54b31cb6c86 + # via httpcore +httpcore==1.0.9 ; python_full_version < '3.15' and sys_platform != 'emscripten' \ + --hash=sha256:2d400746a40668fc9dec9810239072b40b4484b640a8c38fd654a024c7a1bf55 \ + --hash=sha256:6e34463af53fd2ab5d807f399a9b45ea31c3dfa2276f15a2c3f00afff6e176e8 + # via httpx +httpx==0.28.1 ; python_full_version < '3.15' and sys_platform != 'emscripten' \ + --hash=sha256:75e98c5f16b0f35b567856f597f06ff2270a374470a5c2392242528e3e3e42fc \ + --hash=sha256:d909fcccc110f8c7faf814ca82a9a4d816bc5a6dbfea25d6591d6985b8ba59ad + # via jupyterlab +idna==3.16 ; python_full_version < '3.15' and sys_platform != 'emscripten' \ + --hash=sha256:cc246e3a3f89580c3a951b5ad298ca4638078b2cdd4f115654332b5c26daded5 \ + --hash=sha256:d7a6da03db833450fca25d2358ac9ff06cd624577a4aea3a596d5c0f77b8e03d + # via + # anyio + # httpx + # jsonschema + # requests +ipykernel==7.2.0 ; python_full_version < '3.15' and sys_platform != 'emscripten' \ + --hash=sha256:18ed160b6dee2cbb16e5f3575858bc19d8f1fe6046a9a680c708494ce31d909e \ + --hash=sha256:3bbd4420d2b3cc105cbdf3756bfc04500b1e52f090a90716851f3916c62e1661 + # via + # jupyter + # jupyter-console + # jupyterlab +ipython==9.13.0 ; python_full_version < '3.15' and sys_platform != 'emscripten' \ + --hash=sha256:57f9d4639e20818d328d287c7b549af3d05f12486ea8f2e7f73e52a36ec4d201 \ + --hash=sha256:7e834b6afc99f020e3f05966ced34792f40267d64cb1ea9043886dab0dde5967 + # via + # ipykernel + # ipywidgets + # jupyter-console +ipython-pygments-lexers==1.1.1 ; python_full_version < '3.15' and sys_platform != 'emscripten' \ + --hash=sha256:09c0138009e56b6854f9535736f4171d855c8c08a563a0dcd8022f78355c7e81 \ + --hash=sha256:a9462224a505ade19a605f71f8fa63c2048833ce50abc86768a0d81d876dc81c + # via ipython +ipywidgets==8.1.8 ; python_full_version < '3.15' and sys_platform != 'emscripten' \ + --hash=sha256:61f969306b95f85fba6b6986b7fe45d73124d1d9e3023a8068710d47a22ea668 \ + --hash=sha256:ecaca67aed704a338f88f67b1181b58f821ab5dc89c1f0f5ef99db43c1c2921e + # via jupyter +isoduration==20.11.0 ; python_full_version < '3.15' and sys_platform != 'emscripten' \ + --hash=sha256:ac2f9015137935279eac671f94f89eb00584f940f5dc49462a0c4ee692ba1bd9 \ + --hash=sha256:b2904c2a4228c3d44f409c8ae8e2370eb21a26f7ac2ec5446df141dde3452042 + # via jsonschema +jedi==0.20.0 ; python_full_version < '3.15' and sys_platform != 'emscripten' \ + --hash=sha256:7bdd9c2634f56713299976f4cbd59cb3fa92165cc5e05ea811fb253480728b67 \ + --hash=sha256:c3f4ccbd276696f4b19c54618d4fb18f9fc24b0aef02acf704b23f487daa1011 + # via ipython +jinja2==3.1.6 ; python_full_version < '3.15' and sys_platform != 'emscripten' \ + --hash=sha256:0137fb05990d35f1275a587e9aee6d56da821fc83491a0fb838183be43f66d6d \ + --hash=sha256:85ece4451f492d0c13c5dd7c13a64681a86afae63a5f347908daf103ce6d2f67 + # via + # jupyter-server + # jupyterlab + # jupyterlab-server + # nbconvert +json5==0.14.0 ; python_full_version < '3.15' and sys_platform != 'emscripten' \ + --hash=sha256:56cf861bab076b1178eb8c92e1311d273a9b9acea2ccc82c276abf839ebaef3a \ + --hash=sha256:b3f492fad9f6cdbced8b7d40b28b9b1c9701c5f561bef0d33b81c2ff433fefcb + # via jupyterlab-server +jsonpointer==3.1.1 ; python_full_version < '3.15' and sys_platform != 'emscripten' \ + --hash=sha256:0b801c7db33a904024f6004d526dcc53bbb8a4a0f4e32bfd10beadf60adf1900 \ + --hash=sha256:8ff8b95779d071ba472cf5bc913028df06031797532f08a7d5b602d8b2a488ca + # via jsonschema +jsonschema==4.26.0 ; python_full_version < '3.15' and sys_platform != 'emscripten' \ + --hash=sha256:0c26707e2efad8aa1bfc5b7ce170f3fccc2e4918ff85989ba9ffa9facb2be326 \ + --hash=sha256:d489f15263b8d200f8387e64b4c3a75f06629559fb73deb8fdfb525f2dab50ce + # via + # jupyter-events + # jupyterlab-server + # nbformat +jsonschema-specifications==2025.9.1 ; python_full_version < '3.15' and sys_platform != 'emscripten' \ + --hash=sha256:98802fee3a11ee76ecaca44429fda8a41bff98b00a0f2838151b113f210cc6fe \ + --hash=sha256:b540987f239e745613c7a9176f3edb72b832a4ac465cf02712288397832b5e8d + # via jsonschema +jupyter==1.1.1 ; python_full_version < '3.15' and sys_platform != 'emscripten' \ + --hash=sha256:7a59533c22af65439b24bbe60373a4e95af8f16ac65a6c00820ad378e3f7cc83 \ + --hash=sha256:d55467bceabdea49d7e3624af7e33d59c37fff53ed3a350e1ac957bed731de7a + # via big-code-analysis +jupyter-client==8.8.0 ; python_full_version < '3.15' and sys_platform != 'emscripten' \ + --hash=sha256:d556811419a4f2d96c869af34e854e3f059b7cc2d6d01a9cd9c85c267691be3e \ + --hash=sha256:f93a5b99c5e23a507b773d3a1136bd6e16c67883ccdbd9a829b0bbdb98cd7d7a + # via + # ipykernel + # jupyter-console + # jupyter-server + # nbclient +jupyter-console==6.6.3 ; python_full_version < '3.15' and sys_platform != 'emscripten' \ + --hash=sha256:309d33409fcc92ffdad25f0bcdf9a4a9daa61b6f341177570fdac03de5352485 \ + --hash=sha256:566a4bf31c87adbfadf22cdf846e3069b59a71ed5da71d6ba4d8aaad14a53539 + # via jupyter +jupyter-core==5.9.1 ; python_full_version < '3.15' and sys_platform != 'emscripten' \ + --hash=sha256:4d09aaff303b9566c3ce657f580bd089ff5c91f5f89cf7d8846c3cdf465b5508 \ + --hash=sha256:ebf87fdc6073d142e114c72c9e29a9d7ca03fad818c5d300ce2adc1fb0743407 + # via + # ipykernel + # jupyter-client + # jupyter-console + # jupyter-server + # jupyterlab + # nbclient + # nbconvert + # nbformat +jupyter-events==0.12.1 ; python_full_version < '3.15' and sys_platform != 'emscripten' \ + --hash=sha256:c366585253f537a627da52fa7ca7410c5b5301fe893f511e7b077c2d93ec8bcf \ + --hash=sha256:faff25f77218335752f35f23c5fe6e4a392a7bd99a5939ccb9b8fbf594636cf3 + # via jupyter-server +jupyter-lsp==2.3.1 ; python_full_version < '3.15' and sys_platform != 'emscripten' \ + --hash=sha256:71b954d834e85ff3096400554f2eefaf7fe37053036f9a782b0f7c5e42dadb81 \ + --hash=sha256:fdf8a4aa7d85813976d6e29e95e6a2c8f752701f926f2715305249a3829805a6 + # via jupyterlab +jupyter-server==2.20.0 ; python_full_version < '3.15' and sys_platform != 'emscripten' \ + --hash=sha256:b5778ba337d8015a3dc2b80803ecdd5ac18d3797fddf61a50ea5fb472b4ebe14 \ + --hash=sha256:c3b67c93c471e947c18b5026f04f21614218adb706df8f48227d3ee8e0a7cdcc + # via + # jupyter-lsp + # jupyterlab + # jupyterlab-server + # notebook + # notebook-shim +jupyter-server-terminals==0.5.4 ; python_full_version < '3.15' and sys_platform != 'emscripten' \ + --hash=sha256:55be353fc74a80bc7f3b20e6be50a55a61cd525626f578dcb66a5708e2007d14 \ + --hash=sha256:bbda128ed41d0be9020349f9f1f2a4ab9952a73ed5f5ac9f1419794761fb87f5 + # via jupyter-server +jupyterlab==4.5.9 ; python_full_version < '3.15' and sys_platform != 'emscripten' \ + --hash=sha256:5ff0f908e8ac0afbed32b106fdef360f101c0a6654d1bf4a81e98a293ae1b336 \ + --hash=sha256:dd79a073fecae7a39066ea99e4627ed6c76269ac926e95a810e1e1df6358d865 + # via + # jupyter + # notebook +jupyterlab-pygments==0.3.0 ; python_full_version < '3.15' and sys_platform != 'emscripten' \ + --hash=sha256:721aca4d9029252b11cfa9d185e5b5af4d54772bb8072f9b7036f4170054d35d \ + --hash=sha256:841a89020971da1d8693f1a99997aefc5dc424bb1b251fd6322462a1b8842780 + # via nbconvert +jupyterlab-server==2.28.0 ; python_full_version < '3.15' and sys_platform != 'emscripten' \ + --hash=sha256:35baa81898b15f93573e2deca50d11ac0ae407ebb688299d3a5213265033712c \ + --hash=sha256:e4355b148fdcf34d312bbbc80f22467d6d20460e8b8736bf235577dd18506968 + # via + # jupyterlab + # notebook +jupyterlab-widgets==3.0.16 ; python_full_version < '3.15' and sys_platform != 'emscripten' \ + --hash=sha256:423da05071d55cf27a9e602216d35a3a65a3e41cdf9c5d3b643b814ce38c19e0 \ + --hash=sha256:45fa36d9c6422cf2559198e4db481aa243c7a32d9926b500781c830c80f7ecf8 + # via ipywidgets +kiwisolver==1.5.0 ; python_full_version < '3.15' and sys_platform != 'emscripten' \ + --hash=sha256:012b1eb16e28718fa782b5e61dc6f2da1f0792ca73bd05d54de6cb9561665fc9 \ + --hash=sha256:0255a027391d52944eae1dbb5d4cc5903f57092f3674e8e544cdd2622826b3f0 \ + --hash=sha256:0b85aad90cea8ac6797a53b5d5f2e967334fa4d1149f031c4537569972596cb8 \ + --hash=sha256:0bf3acf1419fa93064a4c2189ac0b58e3be7872bf6ee6177b0d4c63dc4cea276 \ + --hash=sha256:0c50b89ffd3e1a911c69a1dd3de7173c0cd10b130f56222e57898683841e4f96 \ + --hash=sha256:0cbe94b69b819209a62cb27bdfa5dc2a8977d8de2f89dfd97ba4f53ed3af754e \ + --hash=sha256:0e3aafb33aed7479377e5e9a82e9d4bf87063741fc99fc7ae48b0f16e32bdd6f \ + --hash=sha256:1465387ac63576c3e125e5337a6892b9e99e0627d52317f3ca79e6930d889d15 \ + --hash=sha256:16b85d37c2cbb3253226d26e64663f755d88a03439a9c47df6246b35defbdfb7 \ + --hash=sha256:1b0feb50971481a2cc44d94e88bdb02cdd497618252ae226b8eb1201b957e368 \ + --hash=sha256:1d49a49ac4cbfb7c1375301cd1ec90169dfeae55ff84710d782260ce77a75a02 \ + --hash=sha256:1d9daea4ea6b9be74fe2f01f7fbade8d6ffab263e781274cffca0dba9be9eec9 \ + --hash=sha256:1dd9b0b119a350976a6d781e7278ec7aca0b201e1a9e2d23d9804afecb6ca681 \ + --hash=sha256:1f1489f769582498610e015a8ef2d36f28f505ab3096d0e16b4858a9ec214f57 \ + --hash=sha256:2a075bd7bd19c70cf67c8badfa36cf7c5d8de3c9ddb8420c51e10d9c50e94920 \ + --hash=sha256:332b4f0145c30b5f5ad9374881133e5aa64320428a57c2c2b61e9d891a51c2f3 \ + --hash=sha256:377815a8616074cabbf3f53354e1d040c35815a134e01d7614b7692e4bf8acfa \ + --hash=sha256:38f4a703656f493b0ad185211ccfca7f0386120f022066b018eb5296d8613e23 \ + --hash=sha256:3ac2360e93cb41be81121755c6462cff3beaa9967188c866e5fce5cf13170859 \ + --hash=sha256:3cdcb35dc9d807259c981a85531048ede628eabcffb3239adf3d17463518992d \ + --hash=sha256:413b820229730d358efd838ecbab79902fe97094565fdc80ddb6b0a18c18a581 \ + --hash=sha256:4432b835675f0ea7414aab3d37d119f7226d24869b7a829caeab49ebda407b0c \ + --hash=sha256:4db576bb8c3ef9365f8b40fe0f671644de6736ae2c27a2c62d7d8a1b4329f099 \ + --hash=sha256:4e7f886f47ab881692f278ae901039a234e4025a68e6dfab514263a0b1c4ae05 \ + --hash=sha256:4e9750bc21b886308024f8a54ccb9a2cc38ac9fa813bf4348434e3d54f337ff9 \ + --hash=sha256:5060731cc3ed12ca3a8b57acd4aeca5bbc2f49216dd0bec1650a1acd89486bcd \ + --hash=sha256:5092eb5b1172947f57d6ea7d89b2f29650414e4293c47707eb499ec07a0ac796 \ + --hash=sha256:5124d1ea754509b09e53738ec185584cc609aae4a3b510aaf4ed6aa047ef9303 \ + --hash=sha256:530a3fd64c87cffa844d4b6b9768774763d9caa299e9b75d8eca6a4423b31314 \ + --hash=sha256:56fa888f10d0f367155e76ce849fa1166fc9730d13bd2d65a2aa13b6f5424489 \ + --hash=sha256:58f812017cd2985c21fbffb4864d59174d4903dd66fa23815e74bbc7a0e2dd57 \ + --hash=sha256:5ae8e62c147495b01a0f4765c878e9bfdf843412446a247e28df59936e99e797 \ + --hash=sha256:5b233ea3e165e43e35dba1d2b8ecc21cf070b45b65ae17dd2747d2713d942021 \ + --hash=sha256:6783e069732715ad0c3ce96dbf21dbc2235ab0593f2baf6338101f70371f4028 \ + --hash=sha256:6ab8ba9152203feec73758dad83af9a0bbe05001eb4639e547207c40cfb52083 \ + --hash=sha256:70d593af6a6ca332d1df73d519fddb5148edb15cd90d5f0155e3746a6d4fcc65 \ + --hash=sha256:72ec46b7eba5b395e0a7b63025490d3214c11013f4aacb4f5e8d6c3041829588 \ + --hash=sha256:7a32f72973f0f950c1920475d5c5ea3d971b81b6f0ec53b8d0a956cc965f22e0 \ + --hash=sha256:7a4aa69609f40fce3cbc3f87b2061f042eee32f94b8f11db707b66a26461591a \ + --hash=sha256:7c60d3c9b06fb23bd9c6139281ccbdc384297579ae037f08ae90c69f6845c0b1 \ + --hash=sha256:80aa065ffd378ff784822a6d7c3212f2d5f5e9c3589614b5c228b311fd3063ac \ + --hash=sha256:893ff3a711d1b515ba9da14ee090519bad4610ed1962fbe298a434e8c5f8db53 \ + --hash=sha256:89fc958c702ee9a745e4700378f5d23fddbc46ff89e8fdbf5395c24d5c1452a3 \ + --hash=sha256:8df31fe574b8b3993cc61764f40941111b25c2d9fea13d3ce24a49907cd2d615 \ + --hash=sha256:9027d773c4ff81487181a925945743413f6069634d0b122d0b37684ccf4f1e18 \ + --hash=sha256:940dda65d5e764406b9fb92761cbf462e4e63f712ab60ed98f70552e496f3bf1 \ + --hash=sha256:b0f172dc8ffaccb8522d7c5d899de00133f2f1ca7b0a49b7da98e901de87bf2d \ + --hash=sha256:b2af221f268f5af85e776a73d62b0845fc8baf8ef0abfae79d29c77d0e776aaf \ + --hash=sha256:bb5136fb5352d3f422df33f0c879a1b0c204004324150cc3b5e3c4f310c9049f \ + --hash=sha256:bc4d8e252f532ab46a1de9349e2d27b91fce46736a9eedaa37beaca66f574ed4 \ + --hash=sha256:bdd3e53429ff02aa319ba59dfe4ceeec345bf46cf180ec2cf6fd5b942e7975e9 \ + --hash=sha256:be12f931839a3bdfe28b584db0e640a65a8bcbc24560ae3fdb025a449b3d754e \ + --hash=sha256:c0e1403fd7c26d77c1f03e096dc58a5c726503fa0db0456678b8668f76f521e3 \ + --hash=sha256:c31c13da98624f957b0fb1b5bae5383b2333c2c3f6793d9825dd5ce79b525cb7 \ + --hash=sha256:c95cab08d1965db3d84a121f1c7ce7479bdd4072c9b3dafd8fecce48a2e6b902 \ + --hash=sha256:cdee07c4d7f6d72008d3f73b9bf027f4e11550224c7c50d8df1ae4a37c1402a6 \ + --hash=sha256:ce9bf03dad3b46408c08649c6fbd6ca28a9fce0eb32fdfffa6775a13103b5310 \ + --hash=sha256:d168fda2dbff7b9b5f38e693182d792a938c31db4dac3a80a4888de603c99554 \ + --hash=sha256:d1ffeb80b5676463d7a7d56acbe8e37a20ce725570e09549fe738e02ca6b7e1e \ + --hash=sha256:d36ca54cb4c6c4686f7cbb7b817f66f5911c12ddb519450bbe86707155028f87 \ + --hash=sha256:d4193f3d9dc3f6f79aaed0e5637f45d98850ebf01f7ca20e69457f3e8946b66a \ + --hash=sha256:d618fd27420381a4f6044faa71f46d8bfd911bd077c555f7138ed88729bfbe79 \ + --hash=sha256:d76e2d8c75051d58177e762164d2e9ab92886534e3a12e795f103524f221dd8e \ + --hash=sha256:db485b3847d182b908b483b2ed133c66d88d49cacf98fd278fadafe11b4478d1 \ + --hash=sha256:dda366d548e89a90d88a86c692377d18d8bd64b39c1fb2b92cb31370e2896bbd \ + --hash=sha256:e315e5ec90d88e140f57696ff85b484ff68bb311e36f2c414aa4286293e6dee0 \ + --hash=sha256:e4415a8db000bf49a6dd1c478bf70062eaacff0f462b92b0ba68791a905861f9 \ + --hash=sha256:e7a116ae737f0000343218c4edf5bd45893bfeaff0993c0b215d7124c9f77646 \ + --hash=sha256:e7c4c09a490dc4d4a7f8cbee56c606a320f9dc28cf92a7157a39d1ce7676a657 \ + --hash=sha256:ed3a984b31da7481b103f68776f7128a89ef26ed40f4dc41a2223cda7fb24819 \ + --hash=sha256:f18c2d9782259a6dc132fdc7a63c168cbc74b35284b6d75c673958982a378384 \ + --hash=sha256:f443b4825c50a51ee68585522ab4a1d1257fac65896f282b4c6763337ac9f5d2 \ + --hash=sha256:f6764a4ccab3078db14a632420930f6186058750df066b8ea2a7106df91d3203 \ + --hash=sha256:f7c7553b13f69c1b29a5bde08ddc6d9d0c8bfb84f9ed01c30db25944aeb852a7 \ + --hash=sha256:fa6248cd194edff41d7ea9425ced8ca3a6f838bfb295f6f1d6e6bb694a8518df \ + --hash=sha256:fa8eb9ecdb7efb0b226acec134e0d709e87a909fa4971a54c0c4f6e88635484c \ + --hash=sha256:fc20894c3d21194d8041a28b65622d5b86db786da6e3cfe73f0c762951a61167 \ + --hash=sha256:fc4d3f1fb9ca0ae9f97b095963bc6326f1dbfd3779d6679a1e016b9baaa153d3 \ + --hash=sha256:fd40bb9cd0891c4c3cb1ddf83f8bbfa15731a248fdc8162669405451e2724b09 + # via matplotlib +lark==1.3.1 ; python_full_version < '3.15' and sys_platform != 'emscripten' \ + --hash=sha256:b426a7a6d6d53189d318f2b6236ab5d6429eaf09259f1ca33eb716eed10d2905 \ + --hash=sha256:c629b661023a014c37da873b4ff58a817398d12635d3bbb2c5a03be7fe5d1e12 + # via rfc3987-syntax +markupsafe==3.0.3 ; python_full_version < '3.15' and sys_platform != 'emscripten' \ + --hash=sha256:0eb9ff8191e8498cca014656ae6b8d61f39da5f95b488805da4bb029cccbfbaf \ + --hash=sha256:1085e7fbddd3be5f89cc898938f42c0b3c711fdcb37d75221de2666af647c175 \ + --hash=sha256:116bb52f642a37c115f517494ea5feb03889e04df47eeff5b130b1808ce7c219 \ + --hash=sha256:12c63dfb4a98206f045aa9563db46507995f7ef6d83b2f68eda65c307c6829eb \ + --hash=sha256:133a43e73a802c5562be9bbcd03d090aa5a1fe899db609c29e8c8d815c5f6de6 \ + --hash=sha256:1353ef0c1b138e1907ae78e2f6c63ff67501122006b0f9abad68fda5f4ffc6ab \ + --hash=sha256:1872df69a4de6aead3491198eaf13810b565bdbeec3ae2dc8780f14458ec73ce \ + --hash=sha256:1b4b79e8ebf6b55351f0d91fe80f893b4743f104bff22e90697db1590e47a218 \ + --hash=sha256:1b52b4fb9df4eb9ae465f8d0c228a00624de2334f216f178a995ccdcf82c4634 \ + --hash=sha256:218551f6df4868a8d527e3062d0fb968682fe92054e89978594c28e642c43a73 \ + --hash=sha256:26a5784ded40c9e318cfc2bdb30fe164bdb8665ded9cd64d500a34fb42067b1c \ + --hash=sha256:2713baf880df847f2bece4230d4d094280f4e67b1e813eec43b4c0e144a34ffe \ + --hash=sha256:32001d6a8fc98c8cb5c947787c5d08b0a50663d139f1305bac5885d98d9b40fa \ + --hash=sha256:3524b778fe5cfb3452a09d31e7b5adefeea8c5be1d43c4f810ba09f2ceb29d37 \ + --hash=sha256:35add3b638a5d900e807944a078b51922212fb3dedb01633a8defc4b01a3c85f \ + --hash=sha256:3a7e8ae81ae39e62a41ec302f972ba6ae23a5c5396c8e60113e9066ef893da0d \ + --hash=sha256:457a69a9577064c05a97c41f4e65148652db078a3a509039e64d3467b9e7ef97 \ + --hash=sha256:4e885a3d1efa2eadc93c894a21770e4bc67899e3543680313b09f139e149ab19 \ + --hash=sha256:4faffd047e07c38848ce017e8725090413cd80cbc23d86e55c587bf979e579c9 \ + --hash=sha256:509fa21c6deb7a7a273d629cf5ec029bc209d1a51178615ddf718f5918992ab9 \ + --hash=sha256:5678211cb9333a6468fb8d8be0305520aa073f50d17f089b5b4b477ea6e67fdc \ + --hash=sha256:5a7d5dc5140555cf21a6fefbdbf8723f06fcd2f63ef108f2854de715e4422cb4 \ + --hash=sha256:69c0b73548bc525c8cb9a251cddf1931d1db4d2258e9599c28c07ef3580ef354 \ + --hash=sha256:722695808f4b6457b320fdc131280796bdceb04ab50fe1795cd540799ebe1698 \ + --hash=sha256:729586769a26dbceff69f7a7dbbf59ab6572b99d94576a5592625d5b411576b9 \ + --hash=sha256:77f0643abe7495da77fb436f50f8dab76dbc6e5fd25d39589a0f1fe6548bfa2b \ + --hash=sha256:795e7751525cae078558e679d646ae45574b47ed6e7771863fcc079a6171a0fc \ + --hash=sha256:7e68f88e5b8799aa49c85cd116c932a1ac15caaa3f5db09087854d218359e485 \ + --hash=sha256:83891d0e9fb81a825d9a6d61e3f07550ca70a076484292a70fde82c4b807286f \ + --hash=sha256:8485f406a96febb5140bfeca44a73e3ce5116b2501ac54fe953e488fb1d03b12 \ + --hash=sha256:8709b08f4a89aa7586de0aadc8da56180242ee0ada3999749b183aa23df95025 \ + --hash=sha256:8f71bc33915be5186016f675cd83a1e08523649b0e33efdb898db577ef5bb009 \ + --hash=sha256:915c04ba3851909ce68ccc2b8e2cd691618c4dc4c4232fb7982bca3f41fd8c3d \ + --hash=sha256:94c6f0bb423f739146aec64595853541634bde58b2135f27f61c1ffd1cd4d16a \ + --hash=sha256:9a1abfdc021a164803f4d485104931fb8f8c1efd55bc6b748d2f5774e78b62c5 \ + --hash=sha256:9b79b7a16f7fedff2495d684f2b59b0457c3b493778c9eed31111be64d58279f \ + --hash=sha256:a4afe79fb3de0b7097d81da19090f4df4f8d3a2b3adaa8764138aac2e44f3af1 \ + --hash=sha256:ad2cf8aa28b8c020ab2fc8287b0f823d0a7d8630784c31e9ee5edea20f406287 \ + --hash=sha256:b8512a91625c9b3da6f127803b166b629725e68af71f8184ae7e7d54686a56d6 \ + --hash=sha256:bdc919ead48f234740ad807933cdf545180bfbe9342c2bb451556db2ed958581 \ + --hash=sha256:bdd37121970bfd8be76c5fb069c7751683bdf373db1ed6c010162b2a130248ed \ + --hash=sha256:be8813b57049a7dc738189df53d69395eba14fb99345e0a5994914a3864c8a4b \ + --hash=sha256:c47a551199eb8eb2121d4f0f15ae0f923d31350ab9280078d1e5f12b249e0026 \ + --hash=sha256:ccfcd093f13f0f0b7fdd0f198b90053bf7b2f02a3927a30e63f3ccc9df56b676 \ + --hash=sha256:d53197da72cc091b024dd97249dfc7794d6a56530370992a5e1a08983ad9230e \ + --hash=sha256:d6dd0be5b5b189d31db7cda48b91d7e0a9795f31430b7f271219ab30f1d3ac9d \ + --hash=sha256:d88b440e37a16e651bda4c7c2b930eb586fd15ca7406cb39e211fcff3bf3017d \ + --hash=sha256:e1cf1972137e83c5d4c136c43ced9ac51d0e124706ee1c8aa8532c1287fa8795 \ + --hash=sha256:e56b7d45a839a697b5eb268c82a71bd8c7f6c94d6fd50c3d577fa39a9f1409f5 \ + --hash=sha256:e8afc3f2ccfa24215f8cb28dcf43f0113ac3c37c2f0f0806d8c70e4228c5cf4d \ + --hash=sha256:eaa9599de571d72e2daf60164784109f19978b327a3910d3e9de8c97b5b70cfe \ + --hash=sha256:ec15a59cf5af7be74194f7ab02d0f59a62bdcf1a537677ce67a2537c9b87fcda \ + --hash=sha256:f190daf01f13c72eac4efd5c430a8de82489d9cff23c364c3ea822545032993e \ + --hash=sha256:f34c41761022dd093b4b6896d4810782ffbabe30f2d443ff5f083e0cbbb8c737 \ + --hash=sha256:f3e98bb3798ead92273dc0e5fd0f31ade220f59a266ffd8a4f6065e0a3ce0523 \ + --hash=sha256:fed51ac40f757d41b7c48425901843666a6677e3e8eb0abcff09e4ba6e664f50 + # via + # jinja2 + # nbconvert +matplotlib==3.10.9 ; python_full_version < '3.15' and sys_platform != 'emscripten' \ + --hash=sha256:09218df8a93712bd6ea133e83a153c755448cf7868316c531cffcc43f69d1cc9 \ + --hash=sha256:10cc5ce06d10231c36f40e875f3c7e8050362a4ee8f0ee5d29a6b3277d57bb42 \ + --hash=sha256:172db52c9e683f5d12eaf57f0f54834190e12581fe1cc2a19595a8f5acb4e77d \ + --hash=sha256:2dc9477819ffd78ad12a20df1d9d6a6bd4fec6aaa9072681465fddca052f1456 \ + --hash=sha256:3225f4e1edcb8c86c884ddf79ebe20ecd0a67d30188f279897554ccd8fded4dc \ + --hash=sha256:336b9acc64d309063126edcdaca00db9373af3c476bb94388fe9c5a53ad13e6f \ + --hash=sha256:345f6f68ecc8da0ca56fad2ea08fde1a115eda530079eca185d50a7bc3e146c6 \ + --hash=sha256:34cf8167e023ad956c15f36302911d5406bd99a9862c1a8499ea6f7c0e015dc2 \ + --hash=sha256:41cb28c2bd769aa3e98322c6ab09854cbcc52ab69d2759d681bba3e327b2b320 \ + --hash=sha256:4e42042d54db34fda4e95a7bd3e5789c2a995d2dad3eb8850232ee534092fbbf \ + --hash=sha256:4edcfbd8565339aa62f1cd4012f7180926fdbe71850f7b0d3c379c175cd6b66c \ + --hash=sha256:59476c6d29d612b8e9bb6ce8c5b631be6ba8f9e3a2421f22a02b192c7dd28716 \ + --hash=sha256:6b63d9c7c769b88ab81e10dc86e4e0607cf56817b9f9e6cf24b2a5f1693b8e38 \ + --hash=sha256:6be157fe17fc37cb95ac1d7374cf717ce9259616edec911a78d9d26dae8522d4 \ + --hash=sha256:6c63ebcd8b4b169eb2f5c200552ae6b8be8999a005b6b507ed76fb8d7d674fe2 \ + --hash=sha256:7a8d66a55def891c33147ba3ba9bfcabf0b526a43764c818acbb4525e5ed0838 \ + --hash=sha256:82368699727bfb7b0182e1aa13082e3c08e092fa1a25d3e1fd92405bff96f6d4 \ + --hash=sha256:8f3bcac1ca5ed000a6f4337d47ba67dfddf37ed6a46c15fd7f014997f7bf865f \ + --hash=sha256:97e35e8d39ccc85859095e01a53847432ba9a53ddf7986f7a54a11b73d0e143f \ + --hash=sha256:a49f1eadc84ca85fd72fa4e89e70e61bf86452df6f971af04b12c60761a0772c \ + --hash=sha256:aba1615dabe83188e19d4f75a253c6a08423e04c1425e64039f800050a69de6b \ + --hash=sha256:ae20801130378b82d647ff5047c07316295b68dc054ca6b3c13519d0ea624285 \ + --hash=sha256:b1b745c489cd1a77a0dc1120a05dc87af9798faebc913601feb8c73d89bf2d1e \ + --hash=sha256:b2b9516251cb89ff618d757daec0e2ed1bf21248013844a853d87ef85ab3081d \ + --hash=sha256:b580440f1ff81a0e34122051a3dfabb7e4b7f9e380629929bde0eff9af72165f \ + --hash=sha256:ba7b3b8ef09eab7df0e86e9ae086faa433efbfbdb46afcb3aa16aabf779469a8 \ + --hash=sha256:c27df8b3848f32a83d1767566595e43cfaa4460380974da06f4279a7ec143c39 \ + --hash=sha256:d091f9d758b34aaaaa6331d13574bf01891d903b3dec59bfff458ef7551de5d6 \ + --hash=sha256:d75d11c949914165976c621b2324f9ef162af7ebf4b057ddf95dd1dba7e5edcf \ + --hash=sha256:d843374407c4017a6403b59c6c81606773d136f3259d5b6da3131bc814542cc2 \ + --hash=sha256:da4e09638420548f31c354032a6250e473c68e5a4e96899b4844cf39ddea23fe \ + --hash=sha256:de2445a0c6690d21b7eb6ce071cebad6d40a2e9bdf10d039074a96ba19797b99 \ + --hash=sha256:e9fae004b941b23ff2edcf1567a857ed77bafc8086ffa258190462328434faf8 \ + --hash=sha256:f0c3c28d9fbcc1fe7a03be236d73430cf6409c41fb2383a7ac52fe932b072cb1 \ + --hash=sha256:f4399f64b3e94cd500195490972ae1ee81170df1636fa15364d157d5bdd7b921 \ + --hash=sha256:fd66508e8c6877d98e586654b608a0456db8d7e8a546eb1e2600efd957302358 + # via big-code-analysis +matplotlib-inline==0.2.2 ; python_full_version < '3.15' and sys_platform != 'emscripten' \ + --hash=sha256:3c821cf1c209f59fb2d2d64abbf5b23b67bcb2210d663f9918dd851c6da1fcf6 \ + --hash=sha256:72f3fe8fce36b70d4a5b612f899090cd0401deddc4ea90e1572b9f4bfb058c79 + # via + # ipykernel + # ipython +maturin==1.13.3 ; python_full_version < '3.15' and sys_platform != 'emscripten' \ + --hash=sha256:0ef257e692cc756c87af5bea95ddfe7d3ac49d3376a7a87f728d63f06e7b6f8b \ + --hash=sha256:1cc0a110b224ca90406b668a3e3c1f5a515062e59e26292f6dbaf5fd4909c6f3 \ + --hash=sha256:2389fe92d017cea9d94e521fa0175314a4c52f79a1057b901fbc9f8686ef7d0b \ + --hash=sha256:3cc13929ca82aefa4adbf0f2c35419369796213c6fb0eb24e914945f50ef5d8c \ + --hash=sha256:3db93337ed97e60ffc878aa8b493cd7ae44d3a5e1a37256db3a4491f57565018 \ + --hash=sha256:4667ef609ab446c1b5e0bfe4f9fb99699ab6d8548433f8d1a684256e0b67217f \ + --hash=sha256:49fd6ab08da28098ccf37afca24cdba72376ba9c1eedf9dd25ff82ed771961ff \ + --hash=sha256:4cd478e6e4c56251e48ed079b8efd55b30bc5c09cf695a1bdafaeb582ee735a0 \ + --hash=sha256:53b08bd075649ce96513ad9abf241a43cb685ed6e9e7790f8dbc2d66e95d8323 \ + --hash=sha256:771e1e9e71a278e56db01552e0d1acfd1464259f9575b6e72842f893cd299079 \ + --hash=sha256:a2675e25f313034ae6f57388cf14818f87d8961c4a96795287f3e155f59beb11 \ + --hash=sha256:b6741d7bf4af97da937528fd1e523c6ab54f53d9a21870fa735d6e67fd88e273 \ + --hash=sha256:c00ea6428dea17bf616fe93770837634454b28c2de1a876e42ef8036c616079a \ + --hash=sha256:def4a435ea9d2ee93b18ba579dc8c9cf898889a66f312cd379b5e374ec3e3ad6 + # via big-code-analysis +mistune==3.2.1 ; python_full_version < '3.15' and sys_platform != 'emscripten' \ + --hash=sha256:78cdb0ba5e938053ccf63651b352508d2efa9411dc8810bfb05f2dc5140c0048 \ + --hash=sha256:7c8e5501d38bac1582e067e46c8343f17d57ea1aaa735823f3aba1fd59c88a28 + # via nbconvert +nbclient==0.10.4 ; python_full_version < '3.15' and sys_platform != 'emscripten' \ + --hash=sha256:1e54091b16e6da39e297b0ece3e10f6f29f4ac4e8ee515d29f8a7099bd6553c9 \ + --hash=sha256:9162df5a7373d70d606527300a95a975a47c137776cd942e52d9c7e29ff83440 + # via nbconvert +nbconvert==7.17.1 ; python_full_version < '3.15' and sys_platform != 'emscripten' \ + --hash=sha256:34d0d0a7e73ce3cbab6c5aae8f4f468797280b01fd8bd2ca746da8569eddd7d2 \ + --hash=sha256:aa85c087b435e7bf1ffd03319f658e285f2b89eccab33bc1ba7025495ab3e7c8 + # via + # big-code-analysis + # jupyter + # jupyter-server +nbformat==5.10.4 ; python_full_version < '3.15' and sys_platform != 'emscripten' \ + --hash=sha256:322168b14f937a5d11362988ecac2a4952d3d8e3a2cbeb2319584631226d5b3a \ + --hash=sha256:3b48d6c8fbca4b299bf3982ea7db1af21580e4fec269ad087b9e81588891200b + # via + # jupyter-server + # nbclient + # nbconvert +nest-asyncio==1.6.0 ; python_full_version < '3.15' and sys_platform != 'emscripten' \ + --hash=sha256:6f172d5449aca15afd6c646851f4e31e02c598d553a667e38cafa997cfec55fe \ + --hash=sha256:87af6efd6b5e897c81050477ef65c62e2b2f35d51703cae01aff2905b1852e1c + # via ipykernel +notebook==7.5.6 ; python_full_version < '3.15' and sys_platform != 'emscripten' \ + --hash=sha256:4dde3f8fb55fa8fb7946d58c6e869ce9baf46d00fc070664f62604569d0faca0 \ + --hash=sha256:621174aade80108f0020b0f00738000b215f75fa3cd90771ad7aa0f24536a4e1 + # via jupyter +notebook-shim==0.2.4 ; python_full_version < '3.15' and sys_platform != 'emscripten' \ + --hash=sha256:411a5be4e9dc882a074ccbcae671eda64cceb068767e9a3419096986560e1cef \ + --hash=sha256:b4b2cfa1b65d98307ca24361f5b30fe785b53c3fd07b7a47e89acb5e6ac638cb + # via + # jupyterlab + # notebook +numpy==2.4.6 ; python_full_version < '3.15' and sys_platform != 'emscripten' \ + --hash=sha256:001fbb8e08d942dd57599e781f2472269ee7f2755fae407b4f67b2f0b17da3f1 \ + --hash=sha256:043191bfa8eab18c776647b62723ac9dddece59743b13f49b2016094129c2b3f \ + --hash=sha256:06ca2f61ec4385a07a6977c55ba998a4466c123642b4a32694d3128fce18c079 \ + --hash=sha256:0a041d3d761dc3c35cc56ce0351506a02bcbc25f7b169f652435141a17db9096 \ + --hash=sha256:0c9136e14ed34a9e343a31c533d78a9813a69a3148332bce5e9821cb2f996e66 \ + --hash=sha256:112b06a867b235ef466ed3508ddf0238050df9c727cafb5301ac385b899189a1 \ + --hash=sha256:17f9ade344e7d9b464a084d69bcf18fc691cb1db67c62ed80820bf4926d78f0e \ + --hash=sha256:1e978ec1e8bd0e0e4de6bb75de9d30cbb74db6b6a2bb727618613703ca0167dd \ + --hash=sha256:25c692919ac5a01f170a3bfcd62d745b24fd095c353d50812637d6fcab442e75 \ + --hash=sha256:260a5d70215b61ab4fadf5c7baacd64821842975eea312125ed3c39a6391b063 \ + --hash=sha256:29a287e0cf63ff528da061de6b9f64a4618da591ca1046aafc54062e40ca7eab \ + --hash=sha256:29cb7f67d10b479ff07c17d33e39f78c07f71c40ef30d63c153d340e96cd3fb4 \ + --hash=sha256:3213d622a0283a39a93d188f3cf72b26862df52fbb4ca3697f51705016523d41 \ + --hash=sha256:33111801a01c12a8a1e3721f0a9232f8cfc8ae2c6b7098167e6f623c6073f402 \ + --hash=sha256:357cc07a6d7b0b182ff02249616a03742827ebb1277546b5c7cd7f7620a45698 \ + --hash=sha256:38efbc8de75c7a0fc1ac190162d892787f3f47b57cc291231aafee36b80982b7 \ + --hash=sha256:4081eb135ac24158bd51cdfbef16f1c64df7063b1143f24731387137c092bec8 \ + --hash=sha256:40fdc1ae7125e518ea98e53e69a4ebc27e1fd50510c47b7ea130cf21e5e1d42b \ + --hash=sha256:511dbaf848decaaaf4b4ca48032619fb3138710c4bf7da7617765edad1ef96b0 \ + --hash=sha256:56b39e5e0622a09a25bf5baf62f4bcf0cb8a41ae6e2819cf49bbc5a74c083f91 \ + --hash=sha256:5f9fb9157b4ce2971008323afe46053787b526ef624fea915b261468a8421a0f \ + --hash=sha256:6180d8b35af935aed8ece3a85e0a43f87393ae0ac87c8d2c8bd2c993f7270ef3 \ + --hash=sha256:68bb27509ac1b9a3443094260f6326150663b06abe40b73a2f81160623da5b67 \ + --hash=sha256:6f41ae150c4e32db4f3310cdaf64b1593a03dbabe29eec77fc9b50fe64061df6 \ + --hash=sha256:7265a2f3d436e54ef9f2b52b5c937e6be778781bd97a590319d7348f1c1ca997 \ + --hash=sha256:72fbe16c6fac95aedf5937fa873445cec2110be35d8a4e9433d7501fd98dae6b \ + --hash=sha256:7d92c3819208a60205a12a245c91ad70cb0a85336659b19b834205573ac8456e \ + --hash=sha256:81a1cca95ed5bb92aa8b10dd2cdc9a0d3853a50fad926c28b5d7e8ea54389627 \ + --hash=sha256:90f9849678c75fe7afa2d348ac842c168b0a4d3d61919687216dfc547976d853 \ + --hash=sha256:9cd5ffd25db4e7ba6a375693b3fc0fc1791ec636c17db3720da19bde7180ec43 \ + --hash=sha256:a0df0043bdb289bde1f62da130d20df23d58b45429f752bc7a8fc5325a225ecd \ + --hash=sha256:a2c306dea656c12c68f51f4cea133cbe78ca7435eb28c735eac1d3ebe73be6e8 \ + --hash=sha256:a7830bab239b79cda9c08c2da014761cafb48da6150e1da17ac06283f43b6089 \ + --hash=sha256:a7c711e21628b52034bb5ab8d1bce291f752fcc5e92accc615778acee1ff4778 \ + --hash=sha256:aaf159caa35993cb1f56fb9b8e4610d35758e7ca005412eb1daa856a78c9c4b1 \ + --hash=sha256:ae506e6902902557576a26ff33eda8695e7ecb3cb36c3b573a0765dee114ebdb \ + --hash=sha256:b507f5c4c1d508876d1819b6bf9a49d365b96320b5d4993426b33a23ca4b8261 \ + --hash=sha256:bf162abab1c1a736333192707cef898e735a5ca00f38f27eeedf44b39d9e85eb \ + --hash=sha256:c1a2af6c6ef86344a6b0db6b97834208bf598db514f2b155042439b62605601a \ + --hash=sha256:c4fc99836233ea196540b17ab0983aff60ed07941751930f5f4d05bc3b3b7359 \ + --hash=sha256:d581b735e177fdcdce6fed8e7e8880a3fb6ee4e3653a3ac6af01c6f4c03effc5 \ + --hash=sha256:d8e8286dd7cea7895157318d1b91cdacac64c479f3cbc8dce548331728484751 \ + --hash=sha256:dfa20cc6ca228e6b155b11da03825975ce66aea520985dbbddf0f2a5a495c605 \ + --hash=sha256:e3e5193ef5a3dc73bceee50f7fdc2c90dbb76c42df8d8fae3d1067a583df579e \ + --hash=sha256:e3eeb0aabd6bd5ce64faae67e9935203a6991b4bc2a485a767fbafb2c5125f45 \ + --hash=sha256:e5805d5a22fd19c8ccff10a9561f9df94436b0545619ea579db2d3c35294bce2 \ + --hash=sha256:e85b752a1e912b70eaad4fafbd4d1238007ab221de2009b9a2f5ae7461239895 \ + --hash=sha256:eaf7fa2de5c0be8ae6ff8e9bea2ccd725e980541244521d8d4b5f3354a27babe \ + --hash=sha256:ebfb099f8dcf083deef3ac1ca4c1503f387cf76296fcb3816b66f5ecb5f54fdb \ + --hash=sha256:ece3d2cfe132e7d51f44a832b303895e6f2d499c5e74dfbdb06ee246147a304a \ + --hash=sha256:ede83e07a75dd06bc501566c1eca2afc0d61677c1472ac9ad93fdee6e638a48d \ + --hash=sha256:ef4aea96ce4d3b074422cb4f2f64e216bf9e213004bb58ecfdf50ea02ea8eb9a \ + --hash=sha256:f3a3570c4a2a16746ac2c31a7c7c7b0c186b95ce902e33db6f28094ed7387dda \ + --hash=sha256:f74a575920ab21fe304421a3fc28793d82e299cae9eccb37084e9fc7f3617c20 + # via + # contourpy + # matplotlib + # pandas +packaging==26.2 ; python_full_version < '3.15' and sys_platform != 'emscripten' \ + --hash=sha256:5fc45236b9446107ff2415ce77c807cee2862cb6fac22b8a73826d0693b0980e \ + --hash=sha256:ff452ff5a3e828ce110190feff1178bb1f2ea2281fa2075aadb987c2fb221661 + # via + # ipykernel + # jupyter-events + # jupyter-server + # jupyterlab + # jupyterlab-server + # matplotlib + # nbconvert +pandas==3.0.3 ; python_full_version < '3.15' and sys_platform != 'emscripten' \ + --hash=sha256:0383c72c75cdcca61a9e116e611143902dbfd08bff356829c2f6d1cf40a9ca8c \ + --hash=sha256:08d789b41f87e0905880e293cedf6197ce71fe67cc081358b1e148a491b9bd13 \ + --hash=sha256:0d589105b3c14645af1738ff279b2995102d8f7a03b0a66dc8d95550eb513e04 \ + --hash=sha256:13fc1e853d9e04743d11ba75a985ccbc2a317fe07d8af61e445a6fd24dacd6a6 \ + --hash=sha256:1928e07221f82db493cd4af1e23c1bfca524a19a4699887975bff68f49a72bfb \ + --hash=sha256:261e308dfb22448384b7580cf719d2f998fe2966c92893c3e77d14008af1f066 \ + --hash=sha256:275c14e0fce14a2ec20eee474aecd305478ea3c1e6f6a9d8fe219a165542717e \ + --hash=sha256:335f62418ed562cfc3c49e9e196375c28b729dcef8543abf4f9438e381bf3c76 \ + --hash=sha256:3650109c0f22879df8bd6179ab9ee3d7f1d1d4e7e0094a3f0032d9f51e2e64ac \ + --hash=sha256:39436b377d56d2a2e52d0395bdbee171f01068e99af5250509aceeb929f765c7 \ + --hash=sha256:3c20a521bbb85902f79f7270c80a59e1b5452d96d170c034f207181870f97ac5 \ + --hash=sha256:3e91cec1879ada0624fc3dc9953c5cbd60208e59c0db28f540c5d6d47502422f \ + --hash=sha256:46997386d528eb40376ecd6b033cf4a8a1e5282580f68f43de875b78cba2199d \ + --hash=sha256:4db8c527972a821cf5286b40ccc57642a39bc62e62022b42f99f8a67fca8c3a1 \ + --hash=sha256:51b1fe551acb77dac643c6fda86084d8d446c10fe64b06a9cc29c4cc8540e7f2 \ + --hash=sha256:557409bc4178e70ee8d9ddb494798e51ebf6ea59330f6be22c51bab2a7db6c49 \ + --hash=sha256:60ae316d3fd75d1858d450d0db0103ea2be3e7d4a95ec2f064f7e2ae63f7b028 \ + --hash=sha256:67b3b64c11910cfa29f4e94a14d3bff9ee693b6fc76055e7cad549cee0aec5fa \ + --hash=sha256:696a4a00a2a2a35d4e5deb3fc946641b96c944f02230e4f76137fe35d806c4fc \ + --hash=sha256:6dc0b3fd2169c9157deed50b4d519553a3655c8c6a96027136d654592be973a9 \ + --hash=sha256:7e65d5407dc0b394f509699650e4a2ec01c0514f21850f453fa60f3be79a5dbf \ + --hash=sha256:819959dab7bbd0049c15623fbac4e29a191b9528160a61fb1032242d8ced2d9c \ + --hash=sha256:9c39be2d709d01fa972a0cabc522389fceca4f3969332ba25a7d6c5802cf976a \ + --hash=sha256:9d71c63ae4ebdbf70209742096f1fc46a83a0613c99d4b23766cced9ff8cd62a \ + --hash=sha256:a2d2dff8a04f3917b55ab3910c32990f8ddf7eceba114947838cefa976a68977 \ + --hash=sha256:a4eeb6830daf35a71cc09649bd823e2b542dac246cdee9614c6e4bd65028cd6a \ + --hash=sha256:a82d532a3351d435432cd913edbccaf8b8e01d4dd0e5ced5a8d2e8ecd94c7e44 \ + --hash=sha256:b168fc218fd80a6cbdbdbc1a97ddc7889ed057d7eb45f50d866ceab5f39904c4 \ + --hash=sha256:b2c95f8bfc1ee412bf482605d7bfd30c12d1d26bd59fdd91efeef1d4718decb1 \ + --hash=sha256:ba7e08b9ac1d54569cd1e256e3668975ed624d6826f7b68df0342b012007bddb \ + --hash=sha256:bab900348131a7db1f69a7309ef141fd5680f1487094193bcbbb61791573bf8f \ + --hash=sha256:bd3a518890b400d32f9023722dc9a9a5c969f00b415419a3c06c043f09bb5d7d \ + --hash=sha256:c7be265b62cef88e253a941e4698604973736dcfe242fdb5198f0f7bc473cdcc \ + --hash=sha256:d26cbe1fcfc12e8fd900e2454163e466b2d3af84f7c75481df7683ffc073d870 \ + --hash=sha256:d4be06d68f9ddcfc645b87534911da79a8fbffc7573c80e0edcf42a5020624d8 \ + --hash=sha256:d72828c20c6d6e83e1e22a6a3b47b326b71664112fa9705dcbccfd7a39b62085 \ + --hash=sha256:dd1a5d1def6a46002e964510bdc67c368aa0951df5d1d9f8365336f5a1f490cd \ + --hash=sha256:e3a2ec42c98ffa2565a67e08e218d06d72576d758d90facb7c00805194d8f360 \ + --hash=sha256:f8894dc474d648fe7b6ff0ca9b0bd73950d19952bc1a6534540762c5d79d305c \ + --hash=sha256:fed2ff7fd9779120e388e285fc029bd5cf9490cdd2e4166a9ee22c0e49a9ab09 + # via big-code-analysis +pandocfilters==1.5.1 ; python_full_version < '3.15' and sys_platform != 'emscripten' \ + --hash=sha256:002b4a555ee4ebc03f8b66307e287fa492e4a77b4ea14d3f934328297bb4939e \ + --hash=sha256:93be382804a9cdb0a7267585f157e5d1731bbe5545a85b268d6f5fe6232de2bc + # via nbconvert +parso==0.8.7 ; python_full_version < '3.15' and sys_platform != 'emscripten' \ + --hash=sha256:a8926eb2a1b915486941fdbd31e86a4baf88fe8c210f25f2f35ecec5b574ca1c \ + --hash=sha256:eaaac4c9fdd5e9e8852dc778d2d7405897ec510f2a298071453e5e3a07914bb1 + # via jedi +pexpect==4.9.0 ; python_full_version < '3.15' and sys_platform != 'emscripten' and sys_platform != 'win32' \ + --hash=sha256:7236d1e080e4936be2dc3e326cec0af72acf9212a7e1d060210e70a47e253523 \ + --hash=sha256:ee7d41123f3c9911050ea2c2dac107568dc43b2d3b0c7557a33212c398ead30f + # via ipython +pillow==12.2.0 ; python_full_version < '3.15' and sys_platform != 'emscripten' \ + --hash=sha256:00a2865911330191c0b818c59103b58a5e697cae67042366970a6b6f1b20b7f9 \ + --hash=sha256:01afa7cf67f74f09523699b4e88c73fb55c13346d212a59a2db1f86b0a63e8c5 \ + --hash=sha256:03e7e372d5240cc23e9f07deca4d775c0817bffc641b01e9c3af208dbd300987 \ + --hash=sha256:03f6fab9219220f041c74aeaa2939ff0062bd5c364ba9ce037197f4c6d498cd9 \ + --hash=sha256:042db20a421b9bafecc4b84a8b6e444686bd9d836c7fd24542db3e7df7baad9b \ + --hash=sha256:0a34329707af4f73cf1782a36cd2289c0368880654a2c11f027bcee9052d35dd \ + --hash=sha256:144748b3af2d1b358d41286056d0003f47cb339b8c43a9ea42f5fea4d8c66b6e \ + --hash=sha256:1610dd6c61621ae1cf811bef44d77e149ce3f7b95afe66a4512f8c59f25d9ebe \ + --hash=sha256:1e1757442ed87f4912397c6d35a0db6a7b52592156014706f17658ff58bbf795 \ + --hash=sha256:22db17c68434de69d8ecfc2fe821569195c0c373b25cccb9cbdacf2c6e53c601 \ + --hash=sha256:2bb4a8d594eacdfc59d9e5ad972aa8afdd48d584ffd5f13a937a664c3e7db0ed \ + --hash=sha256:2c727a6d53cb0018aadd8018c2b938376af27914a68a492f59dfcaca650d5eea \ + --hash=sha256:2d192a155bbcec180f8564f693e6fd9bccff5a7af9b32e2e4bf8c9c69dbad6b5 \ + --hash=sha256:2e5a76d03a6c6dcef67edabda7a52494afa4035021a79c8558e14af25313d453 \ + --hash=sha256:325ca0528c6788d2a6c3d40e3568639398137346c3d6e66bb61db96b96511c98 \ + --hash=sha256:390ede346628ccc626e5730107cde16c42d3836b89662a115a921f28440e6a3b \ + --hash=sha256:3adc9215e8be0448ed6e814966ecf3d9952f0ea40eb14e89a102b87f450660d8 \ + --hash=sha256:4bfd07bc812fbd20395212969e41931001fd59eb55a60658b0e5710872e95286 \ + --hash=sha256:4e6c62e9d237e9b65fac06857d511e90d8461a32adcc1b9065ea0c0fa3a28150 \ + --hash=sha256:50d8520da2a6ce0af445fa6d648c4273c3eeefbc32d7ce049f22e8b5c3daecc2 \ + --hash=sha256:56b25336f502b6ed02e889f4ece894a72612fe885889a6e8c4c80239ff6e5f5f \ + --hash=sha256:57850958fe9c751670e49b2cecf6294acc99e562531f4bd317fa5ddee2068463 \ + --hash=sha256:58f62cc0f00fd29e64b29f4fd923ffdb3859c9f9e6105bfc37ba1d08994e8940 \ + --hash=sha256:5c0a9f29ca8e79f09de89293f82fc9b0270bb4af1d58bc98f540cc4aedf03166 \ + --hash=sha256:5cdfebd752ec52bf5bb4e35d9c64b40826bc5b40a13df7c3cda20a2c03a0f5ed \ + --hash=sha256:5d2fd0fa6b5d9d1de415060363433f28da8b1526c1c129020435e186794b3795 \ + --hash=sha256:62f5409336adb0663b7caa0da5c7d9e7bdbaae9ce761d34669420c2a801b2780 \ + --hash=sha256:632ff19b2778e43162304d50da0181ce24ac5bb8180122cbe1bf4673428328c7 \ + --hash=sha256:6562ace0d3fb5f20ed7290f1f929cae41b25ae29528f2af1722966a0a02e2aa1 \ + --hash=sha256:6a6e67ea2e6feda684ed370f9a1c52e7a243631c025ba42149a2cc5934dec295 \ + --hash=sha256:6a9adfc6d24b10f89588096364cc726174118c62130c817c2837c60cf08a392b \ + --hash=sha256:6bb77b2dcb06b20f9f4b4a8454caa581cd4dd0643a08bacf821216a16d9c8354 \ + --hash=sha256:7371b48c4fa448d20d2714c9a1f775a81155050d383333e0a6c15b1123dda005 \ + --hash=sha256:766cef22385fa1091258ad7e6216792b156dc16d8d3fa607e7545b2b72061f1c \ + --hash=sha256:7b14cc0106cd9aecda615dd6903840a058b4700fcb817687d0ee4fc8b6e389be \ + --hash=sha256:7f84204dee22a783350679a0333981df803dac21a0190d706a50475e361c93f5 \ + --hash=sha256:8023abc91fba39036dbce14a7d6535632f99c0b857807cbbbf21ecc9f4717f06 \ + --hash=sha256:80b2da48193b2f33ed0c32c38140f9d3186583ce7d516526d462645fd98660ae \ + --hash=sha256:8297651f5b5679c19968abefd6bb84d95fe30ef712eb1b2d9b2d31ca61267f4c \ + --hash=sha256:88ddbc66737e277852913bd1e07c150cc7bb124539f94c4e2df5344494e0a612 \ + --hash=sha256:8cbeb542b2ebc6fcdacabf8aca8c1a97c9b3ad3927d46b8723f9d4f033288a0f \ + --hash=sha256:8e9c4f5b3c546fa3458a29ab22646c1c6c787ea8f5ef51300e5a60300736905e \ + --hash=sha256:9aba9a17b623ef750a4d11b742cbafffeb48a869821252b30ee21b5e91392c50 \ + --hash=sha256:9f08483a632889536b8139663db60f6724bfcb443c96f1b18855860d7d5c0fd4 \ + --hash=sha256:a830b1a40919539d07806aa58e1b114df53ddd43213d9c8b75847eee6c0182b5 \ + --hash=sha256:aa88ccfe4e32d362816319ed727a004423aab09c5cea43c01a4b435643fa34eb \ + --hash=sha256:af73337013e0b3b46f175e79492d96845b16126ddf79c438d7ea7ff27783a414 \ + --hash=sha256:b1c1fbd8a5a1af3412a0810d060a78b5136ec0836c8a4ef9aa11807f2a22f4e1 \ + --hash=sha256:b86024e52a1b269467a802258c25521e6d742349d760728092e1bc2d135b4d76 \ + --hash=sha256:d362d1878f00c142b7e1a16e6e5e780f02be8195123f164edf7eddd911eefe7c \ + --hash=sha256:d5d38f1411c0ed9f97bcb49b7bd59b6b7c314e0e27420e34d99d844b9ce3b6f3 \ + --hash=sha256:dac8d77255a37e81a2efcbd1fc05f1c15ee82200e6c240d7e127e25e365c39ea \ + --hash=sha256:dd025009355c926a84a612fecf58bb315a3f6814b17ead51a8e48d3823d9087f \ + --hash=sha256:deede7c263feb25dba4e82ea23058a235dcc2fe1f6021025dc71f2b618e26104 \ + --hash=sha256:ee3120ae9dff32f121610bb08e4313be87e03efeadfc6c0d18f89127e24d0c24 \ + --hash=sha256:eedf4b74eda2b5a4b2b2fb4c006d6295df3bf29e459e198c90ea48e130dc75c3 \ + --hash=sha256:efd8c21c98c5cc60653bcb311bef2ce0401642b7ce9d09e03a7da87c878289d4 \ + --hash=sha256:f1c943e96e85df3d3478f7b691f229887e143f81fedab9b20205349ab04d73ed \ + --hash=sha256:f278f034eb75b4e8a13a54a876cc4a5ab39173d2cdd93a638e1b467fc545ac43 \ + --hash=sha256:f3f40b3c5a968281fd507d519e444c35f0ff171237f4fdde090dd60699458421 \ + --hash=sha256:fb043ee2f06b41473269765c2feae53fc2e2fbf96e5e22ca94fb5ad677856f06 \ + --hash=sha256:fc3d34d4a8fbec3e88a79b92e5465e0f9b842b628675850d860b8bd300b159f5 + # via matplotlib +platformdirs==4.9.6 ; python_full_version < '3.15' and sys_platform != 'emscripten' \ + --hash=sha256:3bfa75b0ad0db84096ae777218481852c0ebc6c727b3168c1b9e0118e458cf0a \ + --hash=sha256:e61adb1d5e5cb3441b4b7710bea7e4c12250ca49439228cc1021c00dcfac0917 + # via jupyter-core +prometheus-client==0.25.0 ; python_full_version < '3.15' and sys_platform != 'emscripten' \ + --hash=sha256:5e373b75c31afb3c86f1a52fa1ad470c9aace18082d39ec0d2f918d11cc9ba28 \ + --hash=sha256:d5aec89e349a6ec230805d0df882f3807f74fd6c1a2fa86864e3c2279059fed1 + # via jupyter-server +prompt-toolkit==3.0.52 ; python_full_version < '3.15' and sys_platform != 'emscripten' \ + --hash=sha256:28cde192929c8e7321de85de1ddbe736f1375148b02f2e17edd840042b1be855 \ + --hash=sha256:9aac639a3bbd33284347de5ad8d68ecc044b91a762dc39b7c21095fcd6a19955 + # via + # ipython + # jupyter-console +psutil==7.2.2 ; python_full_version < '3.15' and sys_platform != 'emscripten' \ + --hash=sha256:0746f5f8d406af344fd547f1c8daa5f5c33dbc293bb8d6a16d80b4bb88f59372 \ + --hash=sha256:076a2d2f923fd4821644f5ba89f059523da90dc9014e85f8e45a5774ca5bc6f9 \ + --hash=sha256:11fe5a4f613759764e79c65cf11ebdf26e33d6dd34336f8a337aa2996d71c841 \ + --hash=sha256:1a571f2330c966c62aeda00dd24620425d4b0cc86881c89861fbc04549e5dc63 \ + --hash=sha256:1a7b04c10f32cc88ab39cbf606e117fd74721c831c98a27dc04578deb0c16979 \ + --hash=sha256:1fa4ecf83bcdf6e6c8f4449aff98eefb5d0604bf88cb883d7da3d8d2d909546a \ + --hash=sha256:2edccc433cbfa046b980b0df0171cd25bcaeb3a68fe9022db0979e7aa74a826b \ + --hash=sha256:7b6d09433a10592ce39b13d7be5a54fbac1d1228ed29abc880fb23df7cb694c9 \ + --hash=sha256:8c233660f575a5a89e6d4cb65d9f938126312bca76d8fe087b947b3a1aaac9ee \ + --hash=sha256:917e891983ca3c1887b4ef36447b1e0873e70c933afc831c6b6da078ba474312 \ + --hash=sha256:ab486563df44c17f5173621c7b198955bd6b613fb87c71c161f827d3fb149a9b \ + --hash=sha256:ae0aefdd8796a7737eccea863f80f81e468a1e4cf14d926bd9b6f5f2d5f90ca9 \ + --hash=sha256:b0726cecd84f9474419d67252add4ac0cd9811b04d61123054b9fb6f57df6e9e \ + --hash=sha256:b58fabe35e80b264a4e3bb23e6b96f9e45a3df7fb7eed419ac0e5947c61e47cc \ + --hash=sha256:c7663d4e37f13e884d13994247449e9f8f574bc4655d509c3b95e9ec9e2b9dc1 \ + --hash=sha256:e452c464a02e7dc7822a05d25db4cde564444a67e58539a00f929c51eddda0cf \ + --hash=sha256:e78c8603dcd9a04c7364f1a3e670cea95d51ee865e4efb3556a3a63adef958ea \ + --hash=sha256:eb7e81434c8d223ec4a219b5fc1c47d0417b12be7ea866e24fb5ad6e84b3d988 \ + --hash=sha256:ed0cace939114f62738d808fdcecd4c869222507e266e574799e9c0faa17d486 \ + --hash=sha256:eed63d3b4d62449571547b60578c5b2c4bcccc5387148db46e0c2313dad0ee00 \ + --hash=sha256:fd04ef36b4a6d599bbdb225dd1d3f51e00105f6d48a28f006da7f9822f2606d8 + # via + # ipykernel + # ipython +ptyprocess==0.7.0 ; (python_full_version < '3.15' and os_name != 'nt' and sys_platform != 'emscripten') or (python_full_version < '3.15' and sys_platform != 'emscripten' and sys_platform != 'win32') \ + --hash=sha256:4b41f3967fce3af57cc7e94b888626c18bf37a083e3651ca8feeb66d492fef35 \ + --hash=sha256:5c5d0a3b48ceee0b48485e0c26037c0acd7d29765ca3fbb5cb3831d347423220 + # via + # pexpect + # terminado +pure-eval==0.2.3 ; python_full_version < '3.15' and sys_platform != 'emscripten' \ + --hash=sha256:1db8e35b67b3d218d818ae653e27f06c3aa420901fa7b081ca98cbedc874e0d0 \ + --hash=sha256:5f4e983f40564c576c7c8635ae88db5956bb2229d7e9237d03b3c0b0190eaf42 + # via stack-data +pycparser==3.0 ; python_full_version < '3.15' and implementation_name != 'PyPy' and sys_platform != 'emscripten' \ + --hash=sha256:600f49d217304a5902ac3c37e1281c9fe94e4d0489de643a9504c5cdfdfc6b29 \ + --hash=sha256:b727414169a36b7d524c1c3e31839a521725078d7b2ff038656844266160a992 + # via cffi +pygments==2.20.0 ; python_full_version < '3.15' and sys_platform != 'emscripten' \ + --hash=sha256:6757cd03768053ff99f3039c1a36d6c0aa0b263438fcab17520b30a303a82b5f \ + --hash=sha256:81a9e26dd42fd28a23a2d169d86d7ac03b46e2f8b59ed4698fb4785f946d0176 + # via + # ipython + # ipython-pygments-lexers + # jupyter-console + # nbconvert +pyparsing==3.3.2 ; python_full_version < '3.15' and sys_platform != 'emscripten' \ + --hash=sha256:850ba148bd908d7e2411587e247a1e4f0327839c40e2e5e6d05a007ecc69911d \ + --hash=sha256:c777f4d763f140633dcb6d8a3eda953bf7a214dc4eff598413c070bcdc117cbc + # via matplotlib +python-dateutil==2.9.0.post0 ; python_full_version < '3.15' and sys_platform != 'emscripten' \ + --hash=sha256:37dd54208da7e1cd875388217d5e00ebd4179249f90fb72437e91a35459a0ad3 \ + --hash=sha256:a8b2bc7bffae282281c8140a97d3aa9c14da0b136dfe83f850eea9a5f7470427 + # via + # arrow + # jupyter-client + # matplotlib + # pandas +python-json-logger==4.1.0 ; python_full_version < '3.15' and sys_platform != 'emscripten' \ + --hash=sha256:132994765cf75bf44554be9aa49b06ef2345d23661a96720262716438141b6b2 \ + --hash=sha256:b396b9e3ed782b09ff9d6e4f1683d46c83ad0d35d2e407c09a9ebbf038f88195 + # via jupyter-events +pywinpty==3.0.3 ; python_full_version < '3.15' and os_name == 'nt' and sys_platform != 'emscripten' \ + --hash=sha256:0c37e224a47a971d1a6e08649a1714dac4f63c11920780977829ed5c8cadead1 \ + --hash=sha256:15c7c0b6f8e9d87aabbaff76468dabf6e6121332c40fc1d83548d02a9d6a3759 \ + --hash=sha256:15e79d870e18b678fb8a5a6105fd38496b55697c66e6fc0378236026bc4d59e9 \ + --hash=sha256:34789d685fc0d547ce0c8a65e5a70e56f77d732fa6e03c8f74fefb8cbb252019 \ + --hash=sha256:3f07a6cf1c1d470d284e614733c3d0f726d2c85e78508ea10a403140c3c0c18a \ + --hash=sha256:523441dc34d231fb361b4b00f8c99d3f16de02f5005fd544a0183112bcc22412 \ + --hash=sha256:9c91dbb026050c77bdcef964e63a4f10f01a639113c4d3658332614544c467ab \ + --hash=sha256:c4e9c3dff7d86ba81937438d5819f19f385a39d8f592d4e8af67148ceb4f6ab5 \ + --hash=sha256:c9081df0e49ffa86d15db4a6ba61530630e48707f987df42c9d3313537e81fc0 \ + --hash=sha256:d4b6b7b0fe0cdcd02e956bd57cfe9f4e5a06514eecf3b5ae174da4f951b58be9 \ + --hash=sha256:fe1f7911805127c94cf51f89ab14096c6f91ffdcacf993d2da6082b2142a2523 + # via + # jupyter-server + # jupyter-server-terminals + # terminado +pyyaml==6.0.3 ; python_full_version < '3.15' and sys_platform != 'emscripten' \ + --hash=sha256:00c4bdeba853cc34e7dd471f16b4114f4162dc03e6b7afcc2128711f0eca823c \ + --hash=sha256:02893d100e99e03eda1c8fd5c441d8c60103fd175728e23e431db1b589cf5ab3 \ + --hash=sha256:0f29edc409a6392443abf94b9cf89ce99889a1dd5376d94316ae5145dfedd5d6 \ + --hash=sha256:16249ee61e95f858e83976573de0f5b2893b3677ba71c9dd36b9cf8be9ac6d65 \ + --hash=sha256:2283a07e2c21a2aa78d9c4442724ec1eb15f5e42a723b99cb3d822d48f5f7ad1 \ + --hash=sha256:34d5fcd24b8445fadc33f9cf348c1047101756fd760b4dacb5c3e99755703310 \ + --hash=sha256:41715c910c881bc081f1e8872880d3c650acf13dfa8214bad49ed4cede7c34ea \ + --hash=sha256:4a2e8cebe2ff6ab7d1050ecd59c25d4c8bd7e6f400f5f82b96557ac0abafd0ac \ + --hash=sha256:4ad1906908f2f5ae4e5a8ddfce73c320c2a1429ec52eafd27138b7f1cbe341c9 \ + --hash=sha256:501a031947e3a9025ed4405a168e6ef5ae3126c59f90ce0cd6f2bfc477be31b7 \ + --hash=sha256:5190d403f121660ce8d1d2c1bb2ef1bd05b5f68533fc5c2ea899bd15f4399b35 \ + --hash=sha256:5498cd1645aa724a7c71c8f378eb29ebe23da2fc0d7a08071d89469bf1d2defb \ + --hash=sha256:5fcd34e47f6e0b794d17de1b4ff496c00986e1c83f7ab2fb8fcfe9616ff7477b \ + --hash=sha256:5fdec68f91a0c6739b380c83b951e2c72ac0197ace422360e6d5a959d8d97b2c \ + --hash=sha256:64386e5e707d03a7e172c0701abfb7e10f0fb753ee1d773128192742712a98fd \ + --hash=sha256:66e1674c3ef6f541c35191caae2d429b967b99e02040f5ba928632d9a7f0f065 \ + --hash=sha256:6adc77889b628398debc7b65c073bcb99c4a0237b248cacaf3fe8a557563ef6c \ + --hash=sha256:79005a0d97d5ddabfeeea4cf676af11e647e41d81c9a7722a193022accdb6b7c \ + --hash=sha256:7c6610def4f163542a622a73fb39f534f8c101d690126992300bf3207eab9764 \ + --hash=sha256:7f047e29dcae44602496db43be01ad42fc6f1cc0d8cd6c83d342306c32270196 \ + --hash=sha256:8d1fab6bb153a416f9aeb4b8763bc0f22a5586065f86f7664fc23339fc1c1fac \ + --hash=sha256:8da9669d359f02c0b91ccc01cac4a67f16afec0dac22c2ad09f46bee0697eba8 \ + --hash=sha256:8dc52c23056b9ddd46818a57b78404882310fb473d63f17b07d5c40421e47f8e \ + --hash=sha256:9149cad251584d5fb4981be1ecde53a1ca46c891a79788c0df828d2f166bda28 \ + --hash=sha256:93dda82c9c22deb0a405ea4dc5f2d0cda384168e466364dec6255b293923b2f3 \ + --hash=sha256:96b533f0e99f6579b3d4d4995707cf36df9100d67e0c8303a0c55b27b5f99bc5 \ + --hash=sha256:a33284e20b78bd4a18c8c2282d549d10bc8408a2a7ff57653c0cf0b9be0afce5 \ + --hash=sha256:a80cb027f6b349846a3bf6d73b5e95e782175e52f22108cfa17876aaeff93702 \ + --hash=sha256:b3bc83488de33889877a0f2543ade9f70c67d66d9ebb4ac959502e12de895788 \ + --hash=sha256:ba1cc08a7ccde2d2ec775841541641e4548226580ab850948cbfda66a1befcdc \ + --hash=sha256:c1ff362665ae507275af2853520967820d9124984e0f7466736aea23d8611fba \ + --hash=sha256:c458b6d084f9b935061bc36216e8a69a7e293a2f1e68bf956dcd9e6cbcd143f5 \ + --hash=sha256:d0eae10f8159e8fdad514efdc92d74fd8d682c933a6dd088030f3834bc8e6b26 \ + --hash=sha256:d76623373421df22fb4cf8817020cbb7ef15c725b9d5e45f17e189bfc384190f \ + --hash=sha256:ebc55a14a21cb14062aa4162f906cd962b28e2e9ea38f9b4391244cd8de4ae0b \ + --hash=sha256:eda16858a3cab07b80edaf74336ece1f986ba330fdb8ee0d6c0d68fe82bc96be \ + --hash=sha256:ee2922902c45ae8ccada2c5b501ab86c36525b883eff4255313a253a3160861c \ + --hash=sha256:f7057c9a337546edc7973c0d3ba84ddcdf0daa14533c2065749c9075001090e6 \ + --hash=sha256:fc09d0aa354569bc501d4e787133afc08552722d3ab34836a80547331bb5d4a0 + # via jupyter-events +pyzmq==27.1.0 ; python_full_version < '3.15' and sys_platform != 'emscripten' \ + --hash=sha256:01c0e07d558b06a60773744ea6251f769cd79a41a97d11b8bf4ab8f034b0424d \ + --hash=sha256:08363b2011dec81c354d694bdecaef4770e0ae96b9afea70b3f47b973655cc05 \ + --hash=sha256:0de3028d69d4cdc475bfe47a6128eb38d8bc0e8f4d69646adfbcd840facbac28 \ + --hash=sha256:1779be8c549e54a1c38f805e56d2a2e5c009d26de10921d7d51cfd1c8d4632ea \ + --hash=sha256:19c9468ae0437f8074af379e986c5d3d7d7bfe033506af442e8c879732bedbe0 \ + --hash=sha256:1c179799b118e554b66da67d88ed66cd37a169f1f23b5d9f0a231b4e8d44a113 \ + --hash=sha256:1f0b2a577fd770aa6f053211a55d1c47901f4d537389a034c690291485e5fe92 \ + --hash=sha256:250e5436a4ba13885494412b3da5d518cd0d3a278a1ae640e113c073a5f88edd \ + --hash=sha256:3837439b7f99e60312f0c926a6ad437b067356dc2bc2ec96eb395fd0fe804233 \ + --hash=sha256:43ad9a73e3da1fab5b0e7e13402f0b2fb934ae1c876c51d0afff0e7c052eca31 \ + --hash=sha256:452631b640340c928fa343801b0d07eb0c3789a5ffa843f6e1a9cee0ba4eb4fc \ + --hash=sha256:544b4e3b7198dde4a62b8ff6685e9802a9a1ebf47e77478a5eb88eca2a82f2fd \ + --hash=sha256:6bb54ca21bcfe361e445256c15eedf083f153811c37be87e0514934d6913061e \ + --hash=sha256:6f3afa12c392f0a44a2414056d730eebc33ec0926aae92b5ad5cf26ebb6cc128 \ + --hash=sha256:7200bb0f03345515df50d99d3db206a0a6bee1955fbb8c453c76f5bf0e08fb96 \ + --hash=sha256:75a2f36223f0d535a0c919e23615fc85a1e23b71f40c7eb43d7b1dedb4d8f15f \ + --hash=sha256:7ccc0700cfdf7bd487bea8d850ec38f204478681ea02a582a8da8171b7f90a1c \ + --hash=sha256:8085a9fba668216b9b4323be338ee5437a235fe275b9d1610e422ccc279733e2 \ + --hash=sha256:80d834abee71f65253c91540445d37c4c561e293ba6e741b992f20a105d69146 \ + --hash=sha256:90e6e9441c946a8b0a667356f7078d96411391a3b8f80980315455574177ec97 \ + --hash=sha256:93ad4b0855a664229559e45c8d23797ceac03183c7b6f5b4428152a6b06684a5 \ + --hash=sha256:9ce490cf1d2ca2ad84733aa1d69ce6855372cb5ce9223802450c9b2a7cba0ccf \ + --hash=sha256:ac0765e3d44455adb6ddbf4417dcce460fc40a05978c08efdf2948072f6db540 \ + --hash=sha256:add071b2d25f84e8189aaf0882d39a285b42fa3853016ebab234a5e78c7a43db \ + --hash=sha256:c65047adafe573ff023b3187bb93faa583151627bc9c51fc4fb2c561ed689d39 \ + --hash=sha256:ce980af330231615756acd5154f29813d553ea555485ae712c491cd483df6b7a \ + --hash=sha256:cedc4c68178e59a4046f97eca31b148ddcf51e88677de1ef4e78cf06c5376c9a \ + --hash=sha256:cf44a7763aea9298c0aa7dbf859f87ed7012de8bda0f3977b6fb1d96745df856 \ + --hash=sha256:d54530c8c8b5b8ddb3318f481297441af102517602b569146185fa10b63f4fa9 \ + --hash=sha256:dc5dbf68a7857b59473f7df42650c621d7e8923fb03fa74a526890f4d33cc4d7 \ + --hash=sha256:e343d067f7b151cfe4eb3bb796a7752c9d369eed007b91231e817071d2c2fec7 \ + --hash=sha256:f30f395a9e6fbca195400ce833c731e7b64c3919aa481af4d88c3759e0cb7496 \ + --hash=sha256:fbb4f2400bfda24f12f009cba62ad5734148569ff4949b1b6ec3b519444342e6 + # via + # ipykernel + # jupyter-client + # jupyter-console + # jupyter-server +referencing==0.37.0 ; python_full_version < '3.15' and sys_platform != 'emscripten' \ + --hash=sha256:381329a9f99628c9069361716891d34ad94af76e461dcb0335825aecc7692231 \ + --hash=sha256:44aefc3142c5b842538163acb373e24cce6632bd54bdb01b21ad5863489f50d8 + # via + # jsonschema + # jsonschema-specifications + # jupyter-events +requests==2.34.2 ; python_full_version < '3.15' and sys_platform != 'emscripten' \ + --hash=sha256:2a0d60c172f83ac6ab31e4554906c0f3b3588d37b5cb939b1c061f4907e278e0 \ + --hash=sha256:f288924cae4e29463698d6d60bc6a4da69c89185ad1e0bcc4104f584e960b9ed + # via jupyterlab-server +rfc3339-validator==0.1.4 ; python_full_version < '3.15' and sys_platform != 'emscripten' \ + --hash=sha256:138a2abdf93304ad60530167e51d2dfb9549521a836871b88d7f4695d0022f6b \ + --hash=sha256:24f6ec1eda14ef823da9e36ec7113124b39c04d50a4d3d3a3c2859577e7791fa + # via + # jsonschema + # jupyter-events +rfc3986-validator==0.1.1 ; python_full_version < '3.15' and sys_platform != 'emscripten' \ + --hash=sha256:2f235c432ef459970b4306369336b9d5dbdda31b510ca1e327636e01f528bfa9 \ + --hash=sha256:3d44bde7921b3b9ec3ae4e3adca370438eccebc676456449b145d533b240d055 + # via + # jsonschema + # jupyter-events +rfc3987-syntax==1.1.0 ; python_full_version < '3.15' and sys_platform != 'emscripten' \ + --hash=sha256:6c3d97604e4c5ce9f714898e05401a0445a641cfa276432b0a648c80856f6a3f \ + --hash=sha256:717a62cbf33cffdd16dfa3a497d81ce48a660ea691b1ddd7be710c22f00b4a0d + # via jsonschema +rpds-py==0.30.0 ; python_full_version < '3.15' and sys_platform != 'emscripten' \ + --hash=sha256:0a59119fc6e3f460315fe9d08149f8102aa322299deaa5cab5b40092345c2136 \ + --hash=sha256:0d08f00679177226c4cb8c5265012eea897c8ca3b93f429e546600c971bcbae7 \ + --hash=sha256:0ed177ed9bded28f8deb6ab40c183cd1192aa0de40c12f38be4d59cd33cb5c65 \ + --hash=sha256:1ab5b83dbcf55acc8b08fc62b796ef672c457b17dbd7820a11d6c52c06839bdf \ + --hash=sha256:1f3587eb9b17f3789ad50824084fa6f81921bbf9a795826570bda82cb3ed91f2 \ + --hash=sha256:2771c6c15973347f50fece41fc447c054b7ac2ae0502388ce3b6738cd366e3d4 \ + --hash=sha256:27f4b0e92de5bfbc6f86e43959e6edd1425c33b5e69aab0984a72047f2bcf1e3 \ + --hash=sha256:2e6ecb5a5bcacf59c3f912155044479af1d0b6681280048b338b28e364aca1f6 \ + --hash=sha256:39c02563fc592411c2c61d26b6c5fe1e51eaa44a75aa2c8735ca88b0d9599daa \ + --hash=sha256:3d4a69de7a3e50ffc214ae16d79d8fbb0922972da0356dcf4d0fdca2878559c6 \ + --hash=sha256:3e62880792319dbeb7eb866547f2e35973289e7d5696c6e295476448f5b63c87 \ + --hash=sha256:3e8eeb0544f2eb0d2581774be4c3410356eba189529a6b3e36bbbf9696175856 \ + --hash=sha256:4559c972db3a360808309e06a74628b95eaccbf961c335c8fe0d590cf587456f \ + --hash=sha256:46e83c697b1f1c72b50e5ee5adb4353eef7406fb3f2043d64c33f20ad1c2fc53 \ + --hash=sha256:47e77dc9822d3ad616c3d5759ea5631a75e5809d5a28707744ef79d7a1bcfcad \ + --hash=sha256:47f236970bccb2233267d89173d3ad2703cd36a0e2a6e92d0560d333871a3d23 \ + --hash=sha256:47f9a91efc418b54fb8190a6b4aa7813a23fb79c51f4bb84e418f5476c38b8db \ + --hash=sha256:4c5f36a861bc4b7da6516dbdf302c55313afa09b81931e8280361a4f6c9a2d27 \ + --hash=sha256:4e7fc54e0900ab35d041b0601431b0a0eb495f0851a0639b6ef90f7741b39a18 \ + --hash=sha256:51a1234d8febafdfd33a42d97da7a43f5dcb120c1060e352a3fbc0c6d36e2083 \ + --hash=sha256:5965af57d5848192c13534f90f9dd16464f3c37aaf166cc1da1cae1fd5a34898 \ + --hash=sha256:5ba103fb455be00f3b1c2076c9d4264bfcb037c976167a6047ed82f23153f02e \ + --hash=sha256:5d4c2aa7c50ad4728a094ebd5eb46c452e9cb7edbfdb18f9e1221f597a73e1e7 \ + --hash=sha256:61046904275472a76c8c90c9ccee9013d70a6d0f73eecefd38c1ae7c39045a08 \ + --hash=sha256:613aa4771c99f03346e54c3f038e4cc574ac09a3ddfb0e8878487335e96dead6 \ + --hash=sha256:626a7433c34566535b6e56a1b39a7b17ba961e97ce3b80ec62e6f1312c025551 \ + --hash=sha256:669b1805bd639dd2989b281be2cfd951c6121b65e729d9b843e9639ef1fd555e \ + --hash=sha256:68f19c879420aa08f61203801423f6cd5ac5f0ac4ac82a2368a9fcd6a9a075e0 \ + --hash=sha256:692bef75a5525db97318e8cd061542b5a79812d711ea03dbc1f6f8dbb0c5f0d2 \ + --hash=sha256:6abc8880d9d036ecaafe709079969f56e876fcf107f7a8e9920ba6d5a3878d05 \ + --hash=sha256:6bdfdb946967d816e6adf9a3d8201bfad269c67efe6cefd7093ef959683c8de0 \ + --hash=sha256:73c67f2db7bc334e518d097c6d1e6fed021bbc9b7d678d6cc433478365d1d5f5 \ + --hash=sha256:74a3243a411126362712ee1524dfc90c650a503502f135d54d1b352bd01f2404 \ + --hash=sha256:76fec018282b4ead0364022e3c54b60bf368b9d926877957a8624b58419169b7 \ + --hash=sha256:7cee9c752c0364588353e627da8a7e808a66873672bcb5f52890c33fd965b394 \ + --hash=sha256:7e6ecfcb62edfd632e56983964e6884851786443739dbfe3582947e87274f7cb \ + --hash=sha256:806f36b1b605e2d6a72716f321f20036b9489d29c51c91f4dd29a3e3afb73b15 \ + --hash=sha256:9027da1ce107104c50c81383cae773ef5c24d296dd11c99e2629dbd7967a20c6 \ + --hash=sha256:922e10f31f303c7c920da8981051ff6d8c1a56207dbdf330d9047f6d30b70e5e \ + --hash=sha256:945dccface01af02675628334f7cf49c2af4c1c904748efc5cf7bbdf0b579f95 \ + --hash=sha256:95f0802447ac2d10bcc69f6dc28fe95fdf17940367b21d34e34c737870758950 \ + --hash=sha256:9a4e86e34e9ab6b667c27f3211ca48f73dba7cd3d90f8d5b11be56e5dbc3fb4e \ + --hash=sha256:9cf69cdda1f5968a30a359aba2f7f9aa648a9ce4b580d6826437f2b291cfc86e \ + --hash=sha256:a090322ca841abd453d43456ac34db46e8b05fd9b3b4ac0c78bcde8b089f959b \ + --hash=sha256:a1010ed9524c73b94d15919ca4d41d8780980e1765babf85f9a2f90d247153dd \ + --hash=sha256:a161f20d9a43006833cd7068375a94d035714d73a172b681d8881820600abfad \ + --hash=sha256:a1d0bc22a7cdc173fedebb73ef81e07faef93692b8c1ad3733b67e31e1b6e1b8 \ + --hash=sha256:a4796a717bf12b9da9d3ad002519a86063dcac8988b030e405704ef7d74d2d9d \ + --hash=sha256:a8fa71a2e078c527c3e9dc9fc5a98c9db40bcc8a92b4e8858e36d329f8684b51 \ + --hash=sha256:ac98b175585ecf4c0348fd7b29c3864bda53b805c773cbf7bfdaffc8070c976f \ + --hash=sha256:acd7eb3f4471577b9b5a41baf02a978e8bdeb08b4b355273994f8b87032000a8 \ + --hash=sha256:ad1fa8db769b76ea911cb4e10f049d80bf518c104f15b3edb2371cc65375c46f \ + --hash=sha256:b40fb160a2db369a194cb27943582b38f79fc4887291417685f3ad693c5a1d5d \ + --hash=sha256:b4dc1a6ff022ff85ecafef7979a2c6eb423430e05f1165d6688234e62ba99a07 \ + --hash=sha256:ba81a9203d07805435eb06f536d95a266c21e5b2dfbf6517748ca40c98d19e31 \ + --hash=sha256:c77afbd5f5250bf27bf516c7c4a016813eb2d3e116139aed0096940c5982da94 \ + --hash=sha256:ca28829ae5f5d569bb62a79512c842a03a12576375d5ece7d2cadf8abe96ec28 \ + --hash=sha256:cdc62c8286ba9bf7f47befdcea13ea0e26bf294bda99758fd90535cbaf408000 \ + --hash=sha256:d948b135c4693daff7bc2dcfc4ec57237a29bd37e60c2fabf5aff2bbacf3e2f1 \ + --hash=sha256:d96c2086587c7c30d44f31f42eae4eac89b60dabbac18c7669be3700f13c3ce1 \ + --hash=sha256:dbd936cde57abfee19ab3213cf9c26be06d60750e60a8e4dd85d1ab12c8b1f40 \ + --hash=sha256:dc824125c72246d924f7f796b4f63c1e9dc810c7d9e2355864b3c3a73d59ade0 \ + --hash=sha256:dd8ff7cf90014af0c0f787eea34794ebf6415242ee1d6fa91eaba725cc441e84 \ + --hash=sha256:e5d3e6b26f2c785d65cc25ef1e5267ccbe1b069c5c21b8cc724efee290554419 \ + --hash=sha256:e7536cd91353c5273434b4e003cbda89034d67e7710eab8761fd918ec6c69cf8 \ + --hash=sha256:eb0b93f2e5c2189ee831ee43f156ed34e2a89a78a66b98cadad955972548be5a \ + --hash=sha256:eb2c4071ab598733724c08221091e8d80e89064cd472819285a9ab0f24bcedb9 \ + --hash=sha256:ec7c4490c672c1a0389d319b3a9cfcd098dcdc4783991553c332a15acf7249be \ + --hash=sha256:ee454b2a007d57363c2dfd5b6ca4a5d7e2c518938f8ed3b706e37e5d470801ed \ + --hash=sha256:f14fc5df50a716f7ece6a80b6c78bb35ea2ca47c499e422aa4463455dd96d56d \ + --hash=sha256:f251c812357a3fed308d684a5079ddfb9d933860fc6de89f2b7ab00da481e65f \ + --hash=sha256:f83424d738204d9770830d35290ff3273fbb02b41f919870479fab14b9d303b2 \ + --hash=sha256:f8d1736cfb49381ba528cd5baa46f82fdc65c06e843dab24dd70b63d09121b3f \ + --hash=sha256:fe5fa731a1fa8a0a56b0977413f8cacac1768dad38d16b3a296712709476fbd5 + # via + # jsonschema + # referencing +send2trash==2.1.0 ; python_full_version < '3.15' and sys_platform != 'emscripten' \ + --hash=sha256:0da2f112e6d6bb22de6aa6daa7e144831a4febf2a87261451c4ad849fe9a873c \ + --hash=sha256:1c72b39f09457db3c05ce1d19158c2cbef4c32b8bedd02c155e49282b7ea7459 + # via jupyter-server +setuptools==82.0.1 ; python_full_version < '3.15' and sys_platform != 'emscripten' \ + --hash=sha256:7d872682c5d01cfde07da7bccc7b65469d3dca203318515ada1de5eda35efbf9 \ + --hash=sha256:a59e362652f08dcd477c78bb6e7bd9d80a7995bc73ce773050228a348ce2e5bb + # via jupyterlab +six==1.17.0 ; python_full_version < '3.15' and sys_platform != 'emscripten' \ + --hash=sha256:4721f391ed90541fddacab5acf947aa0d3dc7d27b2e1e8eda2be8970586c3274 \ + --hash=sha256:ff70335d468e7eb6ec65b95b99d3a2836546063f63acc5171de367e834932a81 + # via + # python-dateutil + # rfc3339-validator +soupsieve==2.8.4 ; python_full_version < '3.15' and sys_platform != 'emscripten' \ + --hash=sha256:e121fd02e975c695e4e9e8774a5ee35d74714b59307868dcc5319ad2d9e3328e \ + --hash=sha256:e7e6b0769c8f51ed59acab6e994b00621096cfb1c640a7509295987388fbaf65 + # via beautifulsoup4 +stack-data==0.6.3 ; python_full_version < '3.15' and sys_platform != 'emscripten' \ + --hash=sha256:836a778de4fec4dcd1dcd89ed8abff8a221f58308462e1c4aa2a3cf30148f0b9 \ + --hash=sha256:d5558e0c25a4cb0853cddad3d77da9891a08cb85dd9f9f91b9f8cd66e511e695 + # via ipython +terminado==0.18.1 ; python_full_version < '3.15' and sys_platform != 'emscripten' \ + --hash=sha256:a4468e1b37bb318f8a86514f65814e1afc977cf29b3992a4500d9dd305dcceb0 \ + --hash=sha256:de09f2c4b85de4765f7714688fff57d3e75bad1f909b589fde880460c753fd2e + # via + # jupyter-server + # jupyter-server-terminals +tinycss2==1.4.0 ; python_full_version < '3.15' and sys_platform != 'emscripten' \ + --hash=sha256:10c0972f6fc0fbee87c3edb76549357415e94548c1ae10ebccdea16fb404a9b7 \ + --hash=sha256:3a49cf47b7675da0b15d0c6e1df8df4ebd96e9394bb905a5775adb0d884c5289 + # via bleach +tornado==6.5.7 ; python_full_version < '3.15' and sys_platform != 'emscripten' \ + --hash=sha256:148b2eb15c2c765a50796172c1e499649b35f30d2e3c3d3e15913cfa56bfb163 \ + --hash=sha256:66c513a76cda70d53907bc27cf1447557699c2e95aa48ba27a442ff61c3ddfc2 \ + --hash=sha256:7778b30bef919231265e91c69963ce0f49a1e9c07ac900bbe75b19ce2575ba92 \ + --hash=sha256:8a46347a18f23fb92b396beebe0fb78f61dda0cc302445202c16203d8a18848b \ + --hash=sha256:8d759e71906ee783f8867b93bf26a265743da4c1e2f4a018464c1ba019862972 \ + --hash=sha256:9da38de27f1da3b78a966f0dae12b5a1ea9afe72ca805d84ff06508272ddf100 \ + --hash=sha256:de942f843533a039ef9fa3d9c88c7cd8a7c94553fb5ad0154270989b3d99a2c4 \ + --hash=sha256:e726f0c75da7726eec023aa62751ff8878bd2737e34fbdd33b1ae5897d2200f5 \ + --hash=sha256:f8de3bf12d3efdd0cbe7c8887868198f8a91415e3f29fcf258d9b8eb7b1d9ae4 \ + --hash=sha256:ff934fce95643af5f11efdae618eaa73d469dc588641e5c8d19295a0c65c4796 + # via + # ipykernel + # jupyter-client + # jupyter-server + # jupyterlab + # notebook + # terminado +traitlets==5.15.0 ; python_full_version < '3.15' and sys_platform != 'emscripten' \ + --hash=sha256:4fead733f81cf1c4c938e06f8ca4633896833c9d89eff878159457f4d4392971 \ + --hash=sha256:fb36a18867a6803deab09f3c5e0fa81bb7b26a5c9e82501c9933f759166eff40 + # via + # ipykernel + # ipython + # ipywidgets + # jupyter-client + # jupyter-console + # jupyter-core + # jupyter-events + # jupyter-server + # jupyterlab + # matplotlib-inline + # nbclient + # nbconvert + # nbformat +typing-extensions==4.15.0 ; python_full_version < '3.15' and sys_platform != 'emscripten' \ + --hash=sha256:0cea48d173cc12fa28ecabc3b837ea3cf6f38c6d1136f85cbaaf598984861466 \ + --hash=sha256:f0fa19c6845758ab08074a0cfa8b7aecb71c999ca73d62883bc25cc018c4e548 + # via + # anyio + # beautifulsoup4 + # referencing +tzdata==2026.2 ; python_full_version < '3.15' and sys_platform != 'emscripten' \ + --hash=sha256:9173fde7d80d9018e02a662e168e5a2d04f87c41ea174b139fbef642eda62d10 \ + --hash=sha256:bbe9af844f658da81a5f95019480da3a89415801f6cc966806612cc7169bffe7 + # via + # arrow + # pandas +uri-template==1.3.0 ; python_full_version < '3.15' and sys_platform != 'emscripten' \ + --hash=sha256:0e00f8eb65e18c7de20d595a14336e9f337ead580c70934141624b6d1ffdacc7 \ + --hash=sha256:a44a133ea12d44a0c0f06d7d42a52d71282e77e2f937d8abd5655b8d56fc1363 + # via jsonschema +urllib3==2.7.0 ; python_full_version < '3.15' and sys_platform != 'emscripten' \ + --hash=sha256:231e0ec3b63ceb14667c67be60f2f2c40a518cb38b03af60abc813da26505f4c \ + --hash=sha256:9fb4c81ebbb1ce9531cce37674bbc6f1360472bc18ca9a553ede278ef7276897 + # via requests +wcwidth==0.7.0 ; python_full_version < '3.15' and sys_platform != 'emscripten' \ + --hash=sha256:5d69154c429a82910e241c738cd0e2976fac8a2dd47a1a805f4afed1c0f136f2 \ + --hash=sha256:90e3a7ea092341c44b99562e75d09e4d5160fe7a3974c6fb842a101a95e7eed0 + # via prompt-toolkit +webcolors==25.10.0 ; python_full_version < '3.15' and sys_platform != 'emscripten' \ + --hash=sha256:032c727334856fc0b968f63daa252a1ac93d33db2f5267756623c210e57a4f1d \ + --hash=sha256:62abae86504f66d0f6364c2a8520de4a0c47b80c03fc3a5f1815fedbef7c19bf + # via jsonschema +webencodings==0.5.1 ; python_full_version < '3.15' and sys_platform != 'emscripten' \ + --hash=sha256:a0af1213f3c2226497a97e2b3aa01a7e4bee4f403f95be16fc9acd2947514a78 \ + --hash=sha256:b36a1c245f2d304965eb4e0a82848379241dc04b865afcc4aab16748587e1923 + # via + # bleach + # tinycss2 +websocket-client==1.9.0 ; python_full_version < '3.15' and sys_platform != 'emscripten' \ + --hash=sha256:9e813624b6eb619999a97dc7958469217c3176312b3a16a4bd1bc7e08a46ec98 \ + --hash=sha256:af248a825037ef591efbf6ed20cc5faa03d3b47b9e5a2230a529eeee1c1fc3ef + # via jupyter-server +widgetsnbextension==4.0.15 ; python_full_version < '3.15' and sys_platform != 'emscripten' \ + --hash=sha256:8156704e4346a571d9ce73b84bee86a29906c9abfd7223b7228a28899ccf3366 \ + --hash=sha256:de8610639996f1567952d763a5a41af8af37f2575a41f9852a38f947eb82a3b9 + # via ipywidgets diff --git a/big-code-analysis-py/uv.lock b/big-code-analysis-py/uv.lock index 250f47ef..de00d7a8 100644 --- a/big-code-analysis-py/uv.lock +++ b/big-code-analysis-py/uv.lock @@ -186,11 +186,13 @@ dev = [ { name = "mypy", marker = "python_full_version < '3.15' and sys_platform != 'emscripten'" }, { name = "pyright", marker = "python_full_version < '3.15' and sys_platform != 'emscripten'" }, { name = "pytest", marker = "python_full_version < '3.15' and sys_platform != 'emscripten'" }, + { name = "pytest-cov", marker = "python_full_version < '3.15' and sys_platform != 'emscripten'" }, { name = "ruff", marker = "python_full_version < '3.15' and sys_platform != 'emscripten'" }, ] examples = [ { name = "jupyter", marker = "python_full_version < '3.15' and sys_platform != 'emscripten'" }, { name = "matplotlib", marker = "python_full_version < '3.15' and sys_platform != 'emscripten'" }, + { name = "maturin", marker = "python_full_version < '3.15' and sys_platform != 'emscripten'" }, { name = "nbconvert", marker = "python_full_version < '3.15' and sys_platform != 'emscripten'" }, { name = "pandas", marker = "python_full_version < '3.15' and sys_platform != 'emscripten'" }, ] @@ -200,11 +202,13 @@ requires-dist = [ { name = "jupyter", marker = "extra == 'examples'", specifier = ">=1.0" }, { name = "matplotlib", marker = "extra == 'examples'", specifier = ">=3.7" }, { name = "maturin", marker = "extra == 'dev'", specifier = ">=1.7,<2.0" }, + { name = "maturin", marker = "extra == 'examples'", specifier = ">=1.7,<2.0" }, { name = "mypy", marker = "extra == 'dev'", specifier = ">=1.10" }, { name = "nbconvert", marker = "extra == 'examples'", specifier = ">=7.0" }, { name = "pandas", marker = "extra == 'examples'", specifier = ">=2.0" }, { name = "pyright", marker = "extra == 'dev'", specifier = ">=1.1.380" }, { name = "pytest", marker = "extra == 'dev'", specifier = ">=8.0" }, + { name = "pytest-cov", marker = "extra == 'dev'", specifier = ">=5.0" }, { name = "ruff", marker = "extra == 'dev'", specifier = ">=0.6,<0.16" }, ] provides-extras = ["dev", "examples"] @@ -449,6 +453,75 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/ae/8c/469afb6465b853afff216f9528ffda78a915ff880ed58813ba4faf4ba0b6/contourpy-1.3.3-cp314-cp314t-win_arm64.whl", hash = "sha256:b7448cb5a725bb1e35ce88771b86fba35ef418952474492cf7c764059933ff8b", size = 203831, upload-time = "2025-07-26T12:02:51.449Z" }, ] +[[package]] +name = "coverage" +version = "7.15.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/cc/8b/adeb62ea8951f13c4c7fef2e7a85e1a06b499c8d8237ea589d496029e53f/coverage-7.15.0.tar.gz", hash = "sha256:9ac3fe7a1435986463eaa8ee253ae2f2a268709ba4ae5c7dd1f52a05391ad78f", size = 925362, upload-time = "2026-07-02T13:10:50.535Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/2a/74/fd4c0901137c4f8d81a76ada99e43c65163b4c94a02ece107a4ec0c6b615/coverage-7.15.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:b75ee5e8cb7575636ac598719b4307ac529ec8fcd79608a35c3cd4d4dada812d", size = 220838, upload-time = "2026-07-02T13:09:02.084Z" }, + { url = "https://files.pythonhosted.org/packages/0f/2e/2347583467bd7f0402635101a916961915cc68fce652cd0db5f173ea04fc/coverage-7.15.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:ffb31267816b93b075302248cc1737506081b4f163df4401e9df1a6424aafabe", size = 221197, upload-time = "2026-07-02T13:09:03.617Z" }, + { url = "https://files.pythonhosted.org/packages/f0/17/99fa688541ae1d6e84543a0e544f83de0c944815b63e9e7b1ed411d15036/coverage-7.15.0-cp312-cp312-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:e4d0bb73455bf97ab243a8f12c37c686ccf1c13bb614b7b85f1d062f06f42b2c", size = 252705, upload-time = "2026-07-02T13:09:05.059Z" }, + { url = "https://files.pythonhosted.org/packages/fb/02/6a95a5cd83b74839017ef9cf48d2d8c9ae60af919e17a3f336e6f9f1b7bd/coverage-7.15.0-cp312-cp312-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:20d9ccc4ebd0edc434d86dfd2a1dd2a8efa6b6b3073d0485a394fee86459ebb4", size = 255441, upload-time = "2026-07-02T13:09:06.559Z" }, + { url = "https://files.pythonhosted.org/packages/67/f2/406f6c57d600f68185942422c4c00f1a3255d60aee6e5fd961425cd9987e/coverage-7.15.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:20c8a976c365c8cb12f0cbd099508772ea41fb5fa80657a8506df0e11bd278c5", size = 256556, upload-time = "2026-07-02T13:09:08.197Z" }, + { url = "https://files.pythonhosted.org/packages/74/8e/d3fa48489c15ecdec1ba48fd61f68798555dddd2f6716f9ad42adeb1a2a9/coverage-7.15.0-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:f948fd5ba1b9cbca91f0ae08b4c1ce2b139509149a435e2585d056d57d70bf01", size = 258815, upload-time = "2026-07-02T13:09:09.691Z" }, + { url = "https://files.pythonhosted.org/packages/47/2e/2d40ddd110462c6a2769677cf7f1c119a52b45f568978fc6c98e4cc0dd0f/coverage-7.15.0-cp312-cp312-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:f58185f06edf6ad68ec9fb155d63ef650c82f3fbd7e1770e2867751fb13158f4", size = 253117, upload-time = "2026-07-02T13:09:11.212Z" }, + { url = "https://files.pythonhosted.org/packages/51/c0/310782f0d7c3cb2b5ac05ba8d205fe91f24a36f6bf3256098f1782181c38/coverage-7.15.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:02adc79a920c73c647c5d117f55747df7f2de94571884758ce8bc58e04f0a796", size = 254475, upload-time = "2026-07-02T13:09:13.029Z" }, + { url = "https://files.pythonhosted.org/packages/86/f7/702da6c275f8ae6ade423d2877243122932c9b27f5403003b9ef8c927d12/coverage-7.15.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:6eb7c300fbed667fd6e3588eba71c1904cdb06110ca6fdf908c26bdd88b8e382", size = 252619, upload-time = "2026-07-02T13:09:14.699Z" }, + { url = "https://files.pythonhosted.org/packages/fb/84/c5b15a7e5ecba4e56218d772d99fe80a63e63f8d11f12783723a6005ab45/coverage-7.15.0-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:b5fb23fa2de9dce1f5c36c09066d8fcda16cd96e8e26686caa2d7cb9b567d65c", size = 256689, upload-time = "2026-07-02T13:09:16.103Z" }, + { url = "https://files.pythonhosted.org/packages/95/2f/c8b07559b57701230c61b23a953858c052890c12ef568d81780c6c46e92e/coverage-7.15.0-cp312-cp312-musllinux_1_2_riscv64.whl", hash = "sha256:cec79341dbe6281484024979976d0c7f22beae08b4a254655decd25d42cbe766", size = 252189, upload-time = "2026-07-02T13:09:17.828Z" }, + { url = "https://files.pythonhosted.org/packages/6b/80/6d2f049dd3fd3dbfd60b62ba6b2162a04009e2c002ce70b24cf3878dec7a/coverage-7.15.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:6c664c5444b1d970b1b2a450e21fb19ee5c9cfdf151ded2dda37260031cca0da", size = 254059, upload-time = "2026-07-02T13:09:19.304Z" }, + { url = "https://files.pythonhosted.org/packages/ce/92/b0287a2c42031d25c628f815f89a3cd9f8268ee78bb1252c9356cda1c689/coverage-7.15.0-cp312-cp312-win32.whl", hash = "sha256:5f764a3fa339bde6b3aa97657f5a6a3a9451e4a5b4ea98a2892c773a43525f77", size = 222893, upload-time = "2026-07-02T13:09:20.812Z" }, + { url = "https://files.pythonhosted.org/packages/a9/69/e34c481915fecb499b3146975061dac528752e37706edc1804f32c822469/coverage-7.15.0-cp312-cp312-win_amd64.whl", hash = "sha256:52f9a4d2c4c56c8848bc2f524916698354b0211488b38c49ad9ae54f6cafbff6", size = 223429, upload-time = "2026-07-02T13:09:22.315Z" }, + { url = "https://files.pythonhosted.org/packages/fe/98/6e878f0b571d32684ef3f38d7c03db241ca5b82a5da8a5391596a8f209c4/coverage-7.15.0-cp312-cp312-win_arm64.whl", hash = "sha256:31e5c3e70c85307ea35a12964e2e40f56ca2ee4b1c8c721ccf4609d17071080b", size = 222810, upload-time = "2026-07-02T13:09:23.812Z" }, + { url = "https://files.pythonhosted.org/packages/76/04/145a3748098bcc86b631a85408d2c3dc5c104e0bd86d605468239b25b6c4/coverage-7.15.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:5be4caf3b28836f078abe700f8944dac4a65d78f16d6c600c89cb624e5535782", size = 220863, upload-time = "2026-07-02T13:09:25.371Z" }, + { url = "https://files.pythonhosted.org/packages/a4/5c/4ed55708fed2c64b63c9bc5715daef670872202101938869b7fe5d5fbb8f/coverage-7.15.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:dd58ad1404704303ca8d4f4b8a1095e7cbc7040ef17a66df1e6619aa10176430", size = 221230, upload-time = "2026-07-02T13:09:26.897Z" }, + { url = "https://files.pythonhosted.org/packages/7b/19/3a80b97d3b2a5c77a01ae359c6bed20c13738fe3d9380f08616d4fec0281/coverage-7.15.0-cp313-cp313-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:bbcbb317c2e5ded5b21104af81c29f391be2af98d065693ffbe8d23949b948e5", size = 252227, upload-time = "2026-07-02T13:09:28.543Z" }, + { url = "https://files.pythonhosted.org/packages/a1/fa/b70062750686bd7da454da27927622f48bbac6990ac7a4c4a4653e7b0036/coverage-7.15.0-cp313-cp313-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:27f31ecb458da3f859aab3f15ada871eb7a7768807d88df4a9f186bb17737970", size = 254823, upload-time = "2026-07-02T13:09:30.177Z" }, + { url = "https://files.pythonhosted.org/packages/a9/09/dad6a75a2e561b9dc5086a8c5257a7591d584246f67e23e70d2995b89ab6/coverage-7.15.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:13fb759be317fdc62e0f56bffdf61cfcb45c7761ad6b71e3e583e71a67ae753c", size = 256059, upload-time = "2026-07-02T13:09:31.979Z" }, + { url = "https://files.pythonhosted.org/packages/e6/e7/b5d2941fa9564573d44b693a871ff3156f0c42cbefe977a09fa7fdc59971/coverage-7.15.0-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:d5cf007add5ab4bb8fa9f4c77e3732127c9e6cad501d7db43355fbfafca0be84", size = 258190, upload-time = "2026-07-02T13:09:34.035Z" }, + { url = "https://files.pythonhosted.org/packages/7c/1d/8e895bcde3c57ccd46d896dda5f2b3d5df761a1b0c6c9d450d175dedc632/coverage-7.15.0-cp313-cp313-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:cc78d9843bd576fbe2118248258d485e968dc535f95ed504a7b0867ba9b51389", size = 252456, upload-time = "2026-07-02T13:09:35.765Z" }, + { url = "https://files.pythonhosted.org/packages/14/4c/f6997da343ddeb959be82c3b05322793f92c071ad45f7cb8a96336e2dd5f/coverage-7.15.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:a263060f1de0b4b74b4e089c2a70b8003b3781c733329a9c8fd54995328f9950", size = 254192, upload-time = "2026-07-02T13:09:37.445Z" }, + { url = "https://files.pythonhosted.org/packages/17/27/a0bc09d032267b9da89d95a2d874cfbef2a5aebbf0e87cf7aba221d79a99/coverage-7.15.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:c48decf16e0dfd5b049c7d5e82200c23c08126719142998d4f172444e3d0529e", size = 252153, upload-time = "2026-07-02T13:09:39.422Z" }, + { url = "https://files.pythonhosted.org/packages/54/c0/77fc233d9fba07b244c40948c53fe27308b8f21732fb3417f87fbd6fd992/coverage-7.15.0-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:08fb028000ed0aaa0a4cbdfbb98be7cb42f370db973fbbb469733505ab20e13e", size = 256310, upload-time = "2026-07-02T13:09:41.006Z" }, + { url = "https://files.pythonhosted.org/packages/d5/24/601cecfb5825becacb8d45219a018a3b55b9dbaec624efdb0ea249d08be2/coverage-7.15.0-cp313-cp313-musllinux_1_2_riscv64.whl", hash = "sha256:fb7dc0c3b7d8a1077abea0b8546ebc5e26d6ef6ecefc2f0f5ad2b8a53bdad837", size = 251974, upload-time = "2026-07-02T13:09:42.733Z" }, + { url = "https://files.pythonhosted.org/packages/47/1e/6f45e5a5b3d5484318d368702af6716b5ab8913b0428bec981a562fcf296/coverage-7.15.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:6cb3602054ccbe9f0d8c2dc04bbeba90d5719236e2cd06e042ddd6d3fc7b6e37", size = 253745, upload-time = "2026-07-02T13:09:44.376Z" }, + { url = "https://files.pythonhosted.org/packages/8e/db/4df027a77bd11d0e527f44c53557c76e54ad027413d0304252ea3a78d67e/coverage-7.15.0-cp313-cp313-win32.whl", hash = "sha256:0bf781da64326b677be344df505171435b6f58716108606621d5d27d964fff8b", size = 222902, upload-time = "2026-07-02T13:09:46.122Z" }, + { url = "https://files.pythonhosted.org/packages/a0/10/0355894d34e231f2c5449e71287e81a50793a325df2e2b027b7bcd9dfd19/coverage-7.15.0-cp313-cp313-win_amd64.whl", hash = "sha256:2c57a275078ee3fa185f83e400f765bc764a549de66d99b47881645cbd4ea629", size = 223444, upload-time = "2026-07-02T13:09:47.687Z" }, + { url = "https://files.pythonhosted.org/packages/06/ef/bb725f263befaaff851203ab338e68af15e195d7f7b5f323162532d9b6a8/coverage-7.15.0-cp313-cp313-win_arm64.whl", hash = "sha256:3812c61afc6685c7999b39320779ab8f43b7a3081fdb0def39976e56fbdb9a21", size = 222839, upload-time = "2026-07-02T13:09:49.717Z" }, + { url = "https://files.pythonhosted.org/packages/4f/9c/1e3ca54f72a3185ece06c58d871099898c48f0ed6430d17b6ab75f0d180a/coverage-7.15.0-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:41cb79af843222e11da87127ad0ecbfa878abadd0f770a4a99391a27d3887324", size = 220906, upload-time = "2026-07-02T13:09:51.339Z" }, + { url = "https://files.pythonhosted.org/packages/09/37/f718613d83b274880382f6b67e78f3802549ae39b0b3e65ae5b5974df56e/coverage-7.15.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:7d2008989ef8fe54188d3f3bfa2e3099b025af11e90a6a1b9e7dc433d04263d8", size = 221239, upload-time = "2026-07-02T13:09:53.138Z" }, + { url = "https://files.pythonhosted.org/packages/a7/ce/22bae91e0b75445f68d365c7643ed0aa4880bbf77450ee74ca65bdae53a7/coverage-7.15.0-cp314-cp314-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:769e8ece11a596315ebf5aa7ec383aeeed016c091d2bf6363ffb996d41529092", size = 252286, upload-time = "2026-07-02T13:09:54.996Z" }, + { url = "https://files.pythonhosted.org/packages/dd/1e/bec5e32aa508615d9d7a2790effb25fb4dc28606e995816afe400b25ece3/coverage-7.15.0-cp314-cp314-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:65a6b6164ee5c39e2f3803f314292d6c61a607ba7fee253d1e03c42dc3903502", size = 254789, upload-time = "2026-07-02T13:09:56.678Z" }, + { url = "https://files.pythonhosted.org/packages/17/29/0e865435b4354e4a7c03b1b7920046d31d0a273d55decefea27e011cb9bf/coverage-7.15.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:75128817f95a5c45bb01d65fd2d8b9cb54bbe03d81608fb70e3e14b437ad56c2", size = 256135, upload-time = "2026-07-02T13:09:58.343Z" }, + { url = "https://files.pythonhosted.org/packages/84/ff/33a870b58a13325d62fc0a6c8f01fa0ff667cef60c7498e2382a147dfa18/coverage-7.15.0-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:9887bb428fe2d4cd4bee89bac1a6c9932f484afd5b36fbd4ff6ea5f825bb1f5e", size = 258449, upload-time = "2026-07-02T13:10:00.057Z" }, + { url = "https://files.pythonhosted.org/packages/18/7b/6fffe596bf3ddba8462758d02c5dad730fd91055a6634aa2e4226229181a/coverage-7.15.0-cp314-cp314-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:0bfc0be1f702042207a93a00523b1065ee1fe951e96edf311581c0bbc2e34888", size = 252313, upload-time = "2026-07-02T13:10:01.946Z" }, + { url = "https://files.pythonhosted.org/packages/58/1b/11468dd6c1676ab831a70cb9a8d4e198e8607fa0b7220ab918b73fe9bfbd/coverage-7.15.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:f64627d55def5a43282d70e08396672692f77e4da610a5bb8bb4060b432b6859", size = 254142, upload-time = "2026-07-02T13:10:04.065Z" }, + { url = "https://files.pythonhosted.org/packages/79/41/29328e21d16b1b95092c30dd700e08cf915bd3734f836df8f3bdb0e8fa9f/coverage-7.15.0-cp314-cp314-musllinux_1_2_i686.whl", hash = "sha256:2c6f0fa473003905c6d5bac328ee4eba9fbea654f15bc24b8a3274b23363fa99", size = 252108, upload-time = "2026-07-02T13:10:06.11Z" }, + { url = "https://files.pythonhosted.org/packages/9b/de/05ccfb990439655b35afbfd8e0d13fe66677565a7d4eb38c3f5ef2635e1c/coverage-7.15.0-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:2bcf9afaf064172c6ec3c58a325a9957ad1178c05dd934e25f253321776e0676", size = 256385, upload-time = "2026-07-02T13:10:08.141Z" }, + { url = "https://files.pythonhosted.org/packages/51/0e/486828a3d2695ea7a2609f17ff572f6b01905e608379440a11da4b8dffbe/coverage-7.15.0-cp314-cp314-musllinux_1_2_riscv64.whl", hash = "sha256:baf06bc987115d6fb938d403f7eab684a057766c490367999a2b71a6883110c6", size = 251923, upload-time = "2026-07-02T13:10:10.179Z" }, + { url = "https://files.pythonhosted.org/packages/18/c7/03582b6715f078e5e558354c87616d945b9894cda2dace8e4009b17035e4/coverage-7.15.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:f0405f2ff97b1c4c0e782cb32e02f32369bcf2e6b618b591d67e1ea754575dfe", size = 253580, upload-time = "2026-07-02T13:10:12.052Z" }, + { url = "https://files.pythonhosted.org/packages/db/dc/9e578bbaf2ecb4959a81b7e7601ad8cca772cba2892e8d144cb749b4a71a/coverage-7.15.0-cp314-cp314-win32.whl", hash = "sha256:ab282853ed5fbd64bbb162f19cb8fcb7087187508a6374b4f9c34ec1577c4e8f", size = 223107, upload-time = "2026-07-02T13:10:13.994Z" }, + { url = "https://files.pythonhosted.org/packages/ae/3e/c8c3b75d8dbe0e35f7b0cc3ff5e949fc59500f70b21d0398813f66740664/coverage-7.15.0-cp314-cp314-win_amd64.whl", hash = "sha256:3bb3040e9f4bbe26fcb0cd7cc85ac63e630d3f3a9c74f027abf4caa27e706663", size = 223597, upload-time = "2026-07-02T13:10:15.906Z" }, + { url = "https://files.pythonhosted.org/packages/cd/bc/3cbc9fb036eb388519bccd521f783499c39b64256013fbc362782f196fe1/coverage-7.15.0-cp314-cp314-win_arm64.whl", hash = "sha256:346771144d34f7fa84ec28386f78e0f31653f33cf35e19d253d5b35f9e8201da", size = 223020, upload-time = "2026-07-02T13:10:17.844Z" }, + { url = "https://files.pythonhosted.org/packages/28/00/199c4a8d656dff63102577a056c0fce2ff6a79e40adac092fc986c49cbf1/coverage-7.15.0-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:d34a010905fb6401324ba016b5da03d574967f7b21ce48ea41e66f0f1f95f641", size = 221638, upload-time = "2026-07-02T13:10:19.703Z" }, + { url = "https://files.pythonhosted.org/packages/ba/8e/9d0092c96a3d3a26951ecc7020826aa57bcb1b119ca81acbba996884ab13/coverage-7.15.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:bb25d825d885ca8036795dacfc3924d33091fc76d71ebc99420c6b79e77d96fa", size = 221903, upload-time = "2026-07-02T13:10:21.514Z" }, + { url = "https://files.pythonhosted.org/packages/6d/b4/c0ca3028f42c9a08e51feb4561ef1192e5de99797cd1db5b04590c215bda/coverage-7.15.0-cp314-cp314t-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:94c9686bfe8a9a6810297aecbd99beaa3445f9e8dc2f80b1382cca0d86b64461", size = 263267, upload-time = "2026-07-02T13:10:23.261Z" }, + { url = "https://files.pythonhosted.org/packages/5f/aa/a375e3846e5d3c013dc600b2a3231089055c73d77f5393dd2192a8d64da6/coverage-7.15.0-cp314-cp314t-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:9bd671c25f9d85f09d7ec481d0e43d5139f486c06a37139847a7ce569788af72", size = 265390, upload-time = "2026-07-02T13:10:25.152Z" }, + { url = "https://files.pythonhosted.org/packages/92/e1/5783cdabb797305e1c9e4809fea496d31834c51fa772514f73dc148bcfc9/coverage-7.15.0-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:110cbdf8d2e216577312cf06ccf85539c0e5a5420ef747e4a4719b5e483c88cd", size = 267811, upload-time = "2026-07-02T13:10:27.249Z" }, + { url = "https://files.pythonhosted.org/packages/85/31/96d8bbf58b8e9193bc8389574a91a0db48355ee98feb66aa6bf8d1b32eea/coverage-7.15.0-cp314-cp314t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:2c5d4619214f1d9993e7b00a8600d14614b7e9d84e89507460b126aa5e6559e5", size = 268928, upload-time = "2026-07-02T13:10:29.242Z" }, + { url = "https://files.pythonhosted.org/packages/5e/7a/5294567e811a1cb7eda93140c628fa050d66189da28da320f93d1d815c73/coverage-7.15.0-cp314-cp314t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:781a704516e2d8346fbbd5be6c6f3412dd824785146528b3a01816f26c081007", size = 262378, upload-time = "2026-07-02T13:10:31.107Z" }, + { url = "https://files.pythonhosted.org/packages/69/3f/3f48538421f899f28946f90a3d272136a4686e1abf461cc9249a783ee0f3/coverage-7.15.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:bd4a1b44bcb65ee29e947ac92bbee04956df3a6bfc6143641bb6cae7ede00fc9", size = 265263, upload-time = "2026-07-02T13:10:32.942Z" }, + { url = "https://files.pythonhosted.org/packages/ce/d3/092df15efcab8a9c1467ee960eb8019bbad3f9300d115d89ea6195f369ff/coverage-7.15.0-cp314-cp314t-musllinux_1_2_i686.whl", hash = "sha256:0e4950c9d6d3e39c64c991814ff315e2d0b9cb8152363594212c9e55208c0a8f", size = 262866, upload-time = "2026-07-02T13:10:35.104Z" }, + { url = "https://files.pythonhosted.org/packages/e5/ab/0254d2b88665efb2c57ad368cc77ab5de3435bd8d5add4729c1b0e79431e/coverage-7.15.0-cp314-cp314t-musllinux_1_2_ppc64le.whl", hash = "sha256:fe9c87ff42e5472d80d21704972e1f96e104a0a599d77c5e35db5a3c562e2571", size = 266599, upload-time = "2026-07-02T13:10:37.05Z" }, + { url = "https://files.pythonhosted.org/packages/a8/79/1cfa4023e489ce6fbc7be4a5d442dbc375edb4f4fda39a352cedb53263c2/coverage-7.15.0-cp314-cp314t-musllinux_1_2_riscv64.whl", hash = "sha256:f00d5ae1dd2fe13fb8186e3e7d37bcbd8b25c0d764ff7d1b32cef9be058510a8", size = 261714, upload-time = "2026-07-02T13:10:38.966Z" }, + { url = "https://files.pythonhosted.org/packages/b7/eb/fee5c8665656be63f497418d410484637c438172568688e8ac92e06574e7/coverage-7.15.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:363ab38cc78b615f11c9cac3cf1d7eef950c18b9fdedfb9066f59461dcf84d68", size = 264025, upload-time = "2026-07-02T13:10:40.789Z" }, + { url = "https://files.pythonhosted.org/packages/ab/99/63005db722f91edc81abc16302f9cc2f6228c1679e46e15be9ae144b14d0/coverage-7.15.0-cp314-cp314t-win32.whl", hash = "sha256:54fd9c53a5fafff509195f1b6a3f9be615d8e8362a3629ff1de23d270c03c86b", size = 223413, upload-time = "2026-07-02T13:10:42.597Z" }, + { url = "https://files.pythonhosted.org/packages/c1/e8/2bc6181c4fb06f1a6b981eb85330cc57bfad7e3f710fc9c9d350013ba228/coverage-7.15.0-cp314-cp314t-win_amd64.whl", hash = "sha256:87b47553097ba185ed964866078e7e63adea9f5f51b5f39691c34f30afd21080", size = 224245, upload-time = "2026-07-02T13:10:44.47Z" }, + { url = "https://files.pythonhosted.org/packages/79/b8/4d959bf9cc45d0cfed2f4d35cafcab978cdb6ea02eb5100009cd740632a3/coverage-7.15.0-cp314-cp314t-win_arm64.whl", hash = "sha256:aeefb2dd178fe7eee79f0ad25d75855cb35ee9ed472db2c5ea06f5b4fd00cec5", size = 223558, upload-time = "2026-07-02T13:10:46.368Z" }, + { url = "https://files.pythonhosted.org/packages/52/30/21b2ad45959cd50e909e02ebac1e30b4ceb7162e91c11d4c570223a458b7/coverage-7.15.0-py3-none-any.whl", hash = "sha256:56da6a4cbe8f7e9e80bd072ca9cefe67d7106a440a7ec06519ec6507ac94ad19", size = 212632, upload-time = "2026-07-02T13:10:48.641Z" }, +] + [[package]] name = "cycler" version = "0.12.1" @@ -1825,6 +1898,20 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/d4/24/a372aaf5c9b7208e7112038812994107bc65a84cd00e0354a88c2c77a617/pytest-9.0.3-py3-none-any.whl", hash = "sha256:2c5efc453d45394fdd706ade797c0a81091eccd1d6e4bccfcd476e2b8e0ab5d9", size = 375249, upload-time = "2026-04-07T17:16:16.13Z" }, ] +[[package]] +name = "pytest-cov" +version = "7.1.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "coverage", marker = "python_full_version < '3.15' and sys_platform != 'emscripten'" }, + { name = "pluggy", marker = "python_full_version < '3.15' and sys_platform != 'emscripten'" }, + { name = "pytest", marker = "python_full_version < '3.15' and sys_platform != 'emscripten'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/b1/51/a849f96e117386044471c8ec2bd6cfebacda285da9525c9106aeb28da671/pytest_cov-7.1.0.tar.gz", hash = "sha256:30674f2b5f6351aa09702a9c8c364f6a01c27aae0c1366ae8016160d1efc56b2", size = 55592, upload-time = "2026-03-21T20:11:16.284Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/9d/7a/d968e294073affff457b041c2be9868a40c1c71f4a35fcc1e45e5493067b/pytest_cov-7.1.0-py3-none-any.whl", hash = "sha256:a0461110b7865f9a271aa1b51e516c9a95de9d696734a2f71e3e78f46e1d4678", size = 22876, upload-time = "2026-03-21T20:11:14.438Z" }, +] + [[package]] name = "python-dateutil" version = "2.9.0.post0" diff --git a/docker/README.md b/docker/README.md new file mode 100644 index 00000000..06a5a78a --- /dev/null +++ b/docker/README.md @@ -0,0 +1,87 @@ +# Dev container + +A self-contained image for running [Claude Code](https://docs.claude.com/en/docs/claude-code) +and this project's MCP servers against a mounted checkout, plus the full +`make pre-commit` / `make ci` validation gate. It bundles every runtime and +tool the workspace needs: + +- **Rust** — stable `1.94` (matching `Cargo.toml`) plus `nightly` for + `cargo +nightly udeps`; components `rustfmt`, `clippy`, `rust-analyzer` + (the Rust LSP), `llvm-tools-preview`; and the cargo tools the gate uses + (`cargo-udeps`, `cargo-insta`, `cargo-nextest`, `cargo-llvm-cov`, + `cargo-about`, `cargo-deny`, `mdbook`). +- **Python** — 3.12 with `uv` (the canonical `make py-bootstrap` path), + `maturin`, `ruff`, `mypy`, and `pyright` (the Python LSP). +- **Node** — for the npx-launched MCP servers, plus `bash-language-server`. +- **Lint tooling** pinned to the CI versions and SHA256-verified: `rumdl`, + `taplo`, `shellcheck`, `shfmt`, `checkmake` (amd64 only), `actionlint`. +- **MCP servers** — [Context7](https://github.com/upstash/context7), + [codegraph](https://github.com/optave/ops-codegraph-tool), and + [Serena](https://github.com/oraios/serena). + +## MCP servers + +The three servers are defined once in [`docker/mcp.json`](./mcp.json) and +registered into Claude Code's **user scope** at image-build time. Claude +launches each as a stdio subprocess automatically — there is no +docker-compose and no separate server container. Verify inside the +container with: + +```bash +claude mcp list +``` + +To change which servers are wired in, edit `docker/mcp.json` and rebuild +(`make dev-env-build`). + +**codegraph** needs a graph built once per checkout before its tools work: + +```bash +cd /home/dev/source/big-code-analysis +codegraph build # writes .codegraph/graph.db +``` + +## Usage + +Drive everything from the repo root via the Makefile: + +```bash +make dev-env-build # build the image (passes your host UID/GID) +make dev-env-run # start it detached, with the repo bind-mounted +make dev-env-shell # open a shell inside it +# ... inside the container: +claude # MCP servers are already registered +make pre-commit # the usual validation gate works here too +make dev-env-rm # stop and remove the container when done +``` + +The container mounts this repository at +`/home/dev/source/big-code-analysis`. The build passes your host UID/GID +(`id -u` / `id -g`) so files written in the mounted checkout keep the right +ownership on the host. + +## Authentication + +Claude Code state lives in the container's home directory, which persists +for the life of the container (until `make dev-env-rm`). Authenticate +either way: + +- **Interactive**: run `claude` and log in once; the session persists + across `make dev-env-shell` invocations. +- **API key**: `export ANTHROPIC_API_KEY=…` on the host before + `make dev-env-run` — it is forwarded into the container. + `CODEGRAPH_LLM_API_KEY` is forwarded the same way for codegraph's + optional LLM features. + +## Architecture notes + +Images build on `linux/amd64` and `linux/arm64`. `checkmake` is the one +tool without a single cross-arch source: amd64 uses the exact CI pin +(`mrtazz/checkmake` 0.2.2, amd64-only upstream), and arm64 falls back to the +maintained `checkmake/checkmake` fork (v0.3.2, same rules and +`.checkmake.ini` format). On any other architecture the build continues +without it and `make makefile-check` is the single unavailable gate. + +Developer tools install to system locations (`/usr/local`, `/opt`) so they +are never shadowed by a mounted home directory. Only user state (Claude +credentials, shell history, caches) lives under `/home/dev`. diff --git a/docker/certs/.gitkeep b/docker/certs/.gitkeep new file mode 100644 index 00000000..27f12a12 --- /dev/null +++ b/docker/certs/.gitkeep @@ -0,0 +1,3 @@ +# Drop corporate/proxy root CA certificates (PEM, *.crt) here to build the +# dev image behind a TLS-intercepting proxy. Files are git-ignored so +# nothing environment-specific is committed. See docker/README.md. diff --git a/docker/mcp.json b/docker/mcp.json new file mode 100644 index 00000000..67b7a3ad --- /dev/null +++ b/docker/mcp.json @@ -0,0 +1,22 @@ +{ + "mcpServers": { + "context7": { + "command": "context7-mcp", + "args": [] + }, + "codegraph": { + "command": "codegraph", + "args": ["mcp"] + }, + "serena": { + "command": "serena", + "args": [ + "start-mcp-server", + "--context", + "ide-assistant", + "--project", + "/home/dev/source/big-code-analysis" + ] + } + } +} diff --git a/test_ext b/test_ext deleted file mode 100755 index ee866dc5..00000000 Binary files a/test_ext and /dev/null differ