From 38a2b6afb184a5e3295699c17ee9ab9a94c4a7ac Mon Sep 17 00:00:00 2001 From: Martijn Govers Date: Tue, 28 Jul 2026 08:06:03 +0200 Subject: [PATCH 01/14] use pymarkdownlnt Signed-off-by: Martijn Govers update workflows Signed-off-by: Martijn Govers remove markdownlint-cli from devcontainer Signed-off-by: Martijn Govers fix pre-commit Signed-off-by: Martijn Govers more fixes Signed-off-by: Martijn Govers more fixes Signed-off-by: Martijn Govers homogenize Signed-off-by: Martijn Govers fix pyproject.toml Signed-off-by: Martijn Govers minor Signed-off-by: Martijn Govers no run locked (scoped out of pr) Signed-off-by: Martijn Govers fix ci Signed-off-by: Martijn Govers scope out npm packages from refresher Signed-off-by: Martijn Govers Refresh lock and linter dependencies Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> fix Signed-off-by: Martijn Govers --- .devcontainer/devcontainer.json | 1 - .github/workflows/check-code-quality.yml | 14 +- .../refresh-lock-and-linter-dependencies.yml | 4 +- .github/workflows/sonar.yml | 2 +- .markdownlint.yaml | 16 - .markdownlintignore | 14 - .pre-commit-config.yaml | 21 +- .pre-commit-config.yaml.jinja | 22 +- README.md | 5 +- docs/advanced_documentation/build-guide.md | 21 +- docs/advanced_documentation/c-api.md | 2 + docs/advanced_documentation/core-design.md | 2 + .../high-level-design.md | 4 + .../native-data-interface.md | 2 + docs/algorithms/lu-solver.md | 16 +- docs/algorithms/pf-algorithms.md | 4 +- docs/algorithms/sc-algorithms.md | 3 +- docs/algorithms/se-algorithms.md | 6 +- docs/algorithms/tap-changing-algorithms.md | 6 + docs/contribution/folder-structure.md | 4 +- docs/user_manual/calculations.md | 29 +- docs/user_manual/components.md | 61 +++- docs/user_manual/data-model.md | 2 + docs/user_manual/dataset-terminology.md | 4 + docs/user_manual/model-validation.md | 2 +- docs/user_manual/non-pgm-components.md | 2 +- pyproject.toml | 12 +- .../data/power_flow/generic_branch/README.md | 2 +- uv.lock | 296 ++++++++++++++++-- 29 files changed, 472 insertions(+), 107 deletions(-) delete mode 100644 .markdownlint.yaml delete mode 100644 .markdownlintignore diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index b9a674a878..096e74dcf1 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -35,7 +35,6 @@ "ms-vscode.test-adapter-converter", "njpwerner.autodocstring", "cschlosser.doxdocgen", - "davidanson.vscode-markdownlint", // version pinned (for now) since an old version (1.6.2) is installed otherwise "biomejs.biome@3.3.0" ], diff --git a/.github/workflows/check-code-quality.yml b/.github/workflows/check-code-quality.yml index 37a5662678..9598a2ce2f 100644 --- a/.github/workflows/check-code-quality.yml +++ b/.github/workflows/check-code-quality.yml @@ -32,7 +32,7 @@ jobs: - name: Install most linters from uv run: | - CC=gcc-14 CXX=g++-14 uv sync --group lint + CC=gcc-14 CXX=g++-14 uv sync --locked --group lint - name: Run mypy run: | @@ -52,14 +52,14 @@ jobs: run: | uv run --frozen gersemi -i --warnings-as-errors src/ tests/ cmake/ - - name: Install npm packages + - name: Run pymarkdown run: | - npm ci + echo "Running pymarkdown" + git ls-files -z -- '*.md' | xargs -0 -r uv run --frozen pymarkdown fix - - name: Run markdownlint + - name: Install npm packages run: | - echo "Running markdownlint" - npx markdownlint --fix . + npm ci - name: Run Biome run: | @@ -77,7 +77,7 @@ jobs: - name: Check generated code if: success() run: | - uv sync --group code-generation + uv sync --locked --group code-generation uv run --frozen code_generation/code_gen.py if [ -n "$(git status --porcelain)" ]; then echo diff --git a/.github/workflows/refresh-lock-and-linter-dependencies.yml b/.github/workflows/refresh-lock-and-linter-dependencies.yml index 4464f765c0..8ea8f37cc7 100644 --- a/.github/workflows/refresh-lock-and-linter-dependencies.yml +++ b/.github/workflows/refresh-lock-and-linter-dependencies.yml @@ -45,7 +45,7 @@ jobs: - name: Install linters from uv run: | - uv sync --only-group lint + uv sync --locked --only-group lint - name: retrieve uv package versions id: versions_uv @@ -78,7 +78,6 @@ jobs: echo "${nospecialchars_pkg}=$version" >> "$GITHUB_OUTPUT" } grab_installed_version_npm "@biomejs/biome" - grab_installed_version_npm "markdownlint-cli" - name: Update .pre-commit-config.yaml uses: cuchi/jinja2-action@8bd801365a8d36a0b20f45ee969161685de7785a # v1.3.0 @@ -91,7 +90,6 @@ jobs: mypy=${{ steps.versions_uv.outputs.mypy }} gersemi=${{ steps.versions_uv.outputs.gersemi }} biome=${{ steps.versions_npm.outputs.biomejsbiome }} - markdownlint_cli=${{ steps.versions_npm.outputs.markdownlint-cli }} - name: show changed files run: | diff --git a/.github/workflows/sonar.yml b/.github/workflows/sonar.yml index 253c9dfb60..55174c864c 100644 --- a/.github/workflows/sonar.yml +++ b/.github/workflows/sonar.yml @@ -48,7 +48,7 @@ jobs: - name: Python test and coverage run: | - CC=clang CXX=clang++ uv sync --no-default-groups --group test + CC=clang CXX=clang++ uv sync --locked --no-default-groups --group test uv run --frozen pytest - name: Run build-wrapper for C++ diff --git a/.markdownlint.yaml b/.markdownlint.yaml deleted file mode 100644 index 97271f4664..0000000000 --- a/.markdownlint.yaml +++ /dev/null @@ -1,16 +0,0 @@ -# SPDX-FileCopyrightText: Contributors to the Power Grid Model project -# -# SPDX-License-Identifier: MPL-2.0 - -# MD001/heading-increment : Heading levels should only increment by one level at a time : https://github.com/DavidAnson/markdownlint/blob/v0.37.4/doc/md001.md -MD001: false - -# MD013/line-length : Line length : https://github.com/DavidAnson/markdownlint/blob/v0.38.0/doc/md013.md -line-length: - line_length: 120 - code_blocks: false - tables: false - stern: true - -# MD024/no-duplicate-heading : Multiple headings with the same content : https://github.com/DavidAnson/markdownlint/blob/v0.37.4/doc/md024.md -MD024: false diff --git a/.markdownlintignore b/.markdownlintignore deleted file mode 100644 index 4c1d102d3f..0000000000 --- a/.markdownlintignore +++ /dev/null @@ -1,14 +0,0 @@ -# SPDX-FileCopyrightText: Contributors to the Power Grid Model project -# -# SPDX-License-Identifier: MPL-2.0 - -.git -.mypy_cache -.pytest_cache -.ruff_cache -.venv -.clangd -cpp_build -build -node_modules -python_cov_html diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index c4356b86bb..ec986b13fd 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -47,11 +47,22 @@ repos: language: system pass_filenames: true types: [ cmake ] - - repo: https://github.com/igorshubovych/markdownlint-cli # outside pypi - rev: v0.49.1 - hooks: - - id: markdownlint - args: ["--fix"] + - id: pymarkdown-fix + name: pymarkdown-fix + alias: markdown-fix + entry: uv run --frozen pymarkdown fix + language: system + pass_filenames: true + types: [ markdown ] + require_serial: true + - id: pymarkdown-scan + name: pymarkdown-scan + alias: markdown-check + entry: uv run --frozen pymarkdown scan + language: system + pass_filenames: true + types: [ markdown ] + require_serial: true # format .json and .jsonc files - repo: https://github.com/biomejs/pre-commit # outside pypi rev: v2.5.5 diff --git a/.pre-commit-config.yaml.jinja b/.pre-commit-config.yaml.jinja index 837aa3642b..2fa1a44e7f 100644 --- a/.pre-commit-config.yaml.jinja +++ b/.pre-commit-config.yaml.jinja @@ -47,11 +47,23 @@ repos: language: system pass_filenames: true types: [ cmake ] - - repo: https://github.com/igorshubovych/markdownlint-cli # outside pypi - rev: v{{ markdownlint_cli }} - hooks: - - id: markdownlint - args: ["--fix"] + - id: pymarkdown-fix + name: pymarkdown-fix + alias: markdown-fix + entry: uv run --frozen pymarkdown fix + language: system + pass_filenames: true + types: [ markdown ] + require_serial: true + - id: pymarkdown-scan + name: pymarkdown-scan + alias: markdown-check + entry: uv run --frozen pymarkdown scan + language: system + pass_filenames: true + types: [ markdown ] + require_serial: true + # format .json and .jsonc files # format .json and .jsonc files - repo: https://github.com/biomejs/pre-commit # outside pypi rev: v{{ biome }} diff --git a/README.md b/README.md index dcf7eb6c05..6969863b74 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,8 @@ SPDX-FileCopyrightText: Contributors to the Power Grid Model project -[![Power Grid Model logo](https://raw.githubusercontent.com/PowerGridModel/.github/main/artwork/svg/color.svg)](#) + +[![Power Grid Model logo](https://raw.githubusercontent.com/PowerGridModel/.github/main/artwork/svg/color.svg)](#) [![PyPI version](https://badge.fury.io/py/power-grid-model.svg?no-cache)](https://badge.fury.io/py/power-grid-model) [![PyPI Downloads](https://static.pepy.tech/badge/power-grid-model)](https://pepy.tech/project/power-grid-model) @@ -110,6 +111,7 @@ references. [![DOI](https://zenodo.org/badge/DOI/10.5281/zenodo.8054429.svg)](https://zenodo.org/record/8054429) + ```bibtex @software{Xiang_PowerGridModel_power-grid-model, author = {Xiang, Yu and Salemink, Peter and van Westering, Werner and Bharambe, Nitish and Govers, Martinus G.H. and van den Bogaard, Jonas and Stoeller, Bram and Wang, Zhen and Guo, Jerry Jinfeng and Figueroa Manrique, Santiago and Jagutis, Laurynas and Wang, Chenguang and van Raalte, Marc and {Contributors to the LF Energy project Power Grid Model}}, @@ -130,6 +132,7 @@ references. doi={10.1049/icp.2023.0633} } ``` + ## Contact diff --git a/docs/advanced_documentation/build-guide.md b/docs/advanced_documentation/build-guide.md index 2ef28e3356..44f3b21f11 100644 --- a/docs/advanced_documentation/build-guide.md +++ b/docs/advanced_documentation/build-guide.md @@ -83,7 +83,9 @@ These are handled automatically in CI. For local development, use your system's * Latest XCode release tested in CI. ```{note} -Once your compiler of choice is installed, you need to define the environment variables `CC` and `CXX` to specify the compiler. For example `export CC=clang-18` and `export CXX=clang++-18` to select the `clang` compiler in Ubuntu. +Once your compiler of choice is installed, you need to define the environment variables `CC` and `CXX` to specify the +compiler. +For example `export CC=clang-18` and `export CXX=clang++-18` to select the `clang` compiler in Ubuntu. ``` ### Build System for CMake Project @@ -97,9 +99,12 @@ This repository uses [CMake](https://cmake.org/) (version 3.23 or later) as its The table below shows the C++ build dependencies. ```{note} -The C++ dependencies below are **build-time only**. When building the Python package from source (via `uv sync`), they are automatically downloaded and used during the build — you do not need to install them manually. Manual installation is only required for standalone CMake builds. +The C++ dependencies below are **build-time only**. When building the Python package from source (via `uv sync`), they +are automatically downloaded and used during the build — you do not need to install them manually. +Manual installation is only required for standalone CMake builds. ``` + | Library name | Requirements to build Python package | Requirements to build CMake project | Remark | License | | ------------------------------------------------------------------- | ------------------------------------ | ------------------------------------------- | ----------- | ------------------------------------------------------------------------------------------------------------ | | [boost](https://www.boost.org/) | Installed automatically | CMake needs to be able find `boost` | header-only | [Boost Software License - Version 1.0](https://www.boost.org/LICENSE_1_0.txt) | @@ -107,6 +112,7 @@ The C++ dependencies below are **build-time only**. When building the Python pac | [nlohmann-json](https://github.com/nlohmann/json) | Installed automatically | CMake needs to be able find `nlohmann_json` | header-only | [MIT](https://github.com/nlohmann/json/blob/develop/LICENSE.MIT) | | [msgpack-cxx](https://github.com/msgpack/msgpack-c/tree/cpp_master) | Installed automatically | CMake needs to be able find `msgpack-cxx` | header-only | [Boost Software License - Version 1.0](https://github.com/msgpack/msgpack-c/blob/cpp_master/LICENSE_1_0.txt) | | [doctest](https://github.com/doctest/doctest) | None | CMake needs to be able find `doctest` | header-only | [MIT](https://github.com/doctest/doctest/blob/master/LICENSE.txt) | + To install the C++ dependencies for a CMake build, use your platform's package manager of choice. In the platform-specific examples below, we will give some suggestions. @@ -120,6 +126,7 @@ Set `CMAKE_PREFIX_PATH` to the installation prefix of your package manager so CM The table below shows the Python dependencies. + | Library name | Remark | License | |------------------------------------------------------------------------|------------------------|--------------------------------------------------------------------------------------------| | [numpy](https://numpy.org/) | Runtime dependency | [BSD-3](https://github.com/numpy/numpy/blob/main/LICENSE.txt) | @@ -128,6 +135,7 @@ The table below shows the Python dependencies. | [pytest-cov](https://github.com/pytest-dev/pytest-cov) | Development dependency | [MIT](https://github.com/pytest-dev/pytest-cov/blob/master/LICENSE) | | [msgpack-python](https://github.com/msgpack/msgpack-python) | Development dependency | [Apache License, Version 2.0](https://github.com/msgpack/msgpack-python/blob/main/COPYING) | | [uv](https://github.com/astral-sh/uv) | Development dependency | [Apache License, Version 2.0](https://github.com/astral-sh/uv/blob/main/LICENSE-APACHE) | + ## Build Python Package @@ -355,9 +363,11 @@ conda create --yes -p C:\conda_envs\cpp_pkgs -c conda-forge libboost-headers eig Set `CMAKE_PREFIX_PATH` so CMake can locate the C++ libraries. In PowerShell: + ```powershell $env:CMAKE_PREFIX_PATH = C:\conda_envs\cpp_pkgs\Library ``` + To make it persistent across sessions: @@ -386,14 +396,14 @@ For debugging purposes, it may be useful to build the Power Grid Model with debu To do so, the following command can be used to override the default build settings. ```powershell -uv sync --config-settings=cmake.build-type="RelWithDebInfo" +uv sync --locked --config-settings=cmake.build-type="RelWithDebInfo" ``` It is also possible to install the Power Grid Model as a full debug build, including extra sanity checks and with a lower degree of optimizations. Note this may come with a significant impact on the performance. ```powershell -uv sync --config-settings=cmake.build-type="Debug" +uv sync --locked --config-settings=cmake.build-type="Debug" ``` ### Build CMake Project @@ -464,6 +474,7 @@ As a quick start, from the root of the repository: ```{note} Test coverage is not supported on macOS. +``` ## Package tests @@ -510,7 +521,7 @@ In addition, the `power-grid-model` Python package needs to be built by followin After that, the documentation specific packages can be installed via: ```shell -uv sync --group doc +uv sync --locked --group doc ``` ```{note} diff --git a/docs/advanced_documentation/c-api.md b/docs/advanced_documentation/c-api.md index b1442faf0a..268f89800e 100644 --- a/docs/advanced_documentation/c-api.md +++ b/docs/advanced_documentation/c-api.md @@ -121,6 +121,7 @@ versions, compilers, operating systems and architectures. * an aligned size of 8 bytes * a 4 bytes alignment + ```txt <-- 3 lines. | | | | | | | <-- alignment: a line may start every 4 bytes. @@ -128,6 +129,7 @@ iiiift iiiift iiiift <-- data: 6 bytes per line: 4 bytes for the ID, 1 for | ..| ..| ..| <-- padding: (4 - (6 mod 4) = 2) bytes after every line. | | | | <-- aligned size: (6 + 2 = 8) bytes every line. ``` + #### Create and destroy buffer diff --git a/docs/advanced_documentation/core-design.md b/docs/advanced_documentation/core-design.md index 0e1d0382bc..b8ed489b13 100644 --- a/docs/advanced_documentation/core-design.md +++ b/docs/advanced_documentation/core-design.md @@ -17,6 +17,7 @@ The `MainModel` itself can be deconstructed into an API part, a dispatch part, t The logic involved in power grid calculations in turn can be devided in a number of separate modules. Coincidentally, those phases also translate to fields of expertise, which enables a reasonably clean architecture. + | Logic/control module | Description | Expertise | | -------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------- | ---------------------- | | I/O | Constructing, updating and outputting components in the power grid | Software Engineering | @@ -24,6 +25,7 @@ Coincidentally, those phases also translate to fields of expertise, which enable | $Y_{\text{bus}}$ construction/Component extraction | Constructing $Y_{\text{bus}}$ from the power grid components and topology | Electrical Engineering | | Solver construction/Grid extraction | Translation from $Y_{\text{bus}}$ to a solvable system of equations and from the solution back to physical values | Physics | | Solving | Abstract solution to the system of equations | Mathematics | + ```{note} Software Engineering obviously also plays a role in the general design, but that general design does not involve the diff --git a/docs/advanced_documentation/high-level-design.md b/docs/advanced_documentation/high-level-design.md index efadc1d193..88aaf786e6 100644 --- a/docs/advanced_documentation/high-level-design.md +++ b/docs/advanced_documentation/high-level-design.md @@ -34,18 +34,21 @@ abstraction. The following library interfaces are currently included in the power-grid-model. + | Interface type | Status | Layer | Explanation | Supported by | | -------------- | ------------ | ------------------ | --------------------------------------------------------------- | --------------------------------------------------- | | C API | Stable | Raw interface | Shared object / DLL that contains the core implementation | All programming languages with dynamic load support | | C headers | Stable | Exposition-only | Exposition-only library using dynamic linking | C and C++ | | C++ headers | Experimental | Wrapper | Handles memory management and basic error handling | C++ | | Python library | Stable | Feature-rich layer | Library with useful functions, conversions and extensive checks | Python | + Note that the Python library in turn also follows the pattern of a feature-rich library that uses a module-internal wrapper layer core module, that wraps the exposition-only core module, that exposes the raw interface. This can be visualized graphically as follows. + ```{mermaid} :title: Full design @@ -93,6 +96,7 @@ flowchart TD cpp_user -->|experimental
links +
includes| power_grid_model_cpp -->|links +
includes| power_grid_model_c python_user -->|import| power_grid_model_python -->|internal import| power_grid_model_core_python -->|internal import| power_grid_core_python -->|"CDLL
(dynamic loading)"| power_grid_model_c_dll ``` + ## Creating a custom library or interface diff --git a/docs/advanced_documentation/native-data-interface.md b/docs/advanced_documentation/native-data-interface.md index 8442217dfe..1e68a54d0f 100644 --- a/docs/advanced_documentation/native-data-interface.md +++ b/docs/advanced_documentation/native-data-interface.md @@ -119,12 +119,14 @@ The pointers are passed into C++ code so that the C++ program can write results The basic data types used in the interface between C++ and Python are shown in the table below. + | C++ type | `numpy.dtype` | null value | usage | | ----------- | ------------- | --------------------------------------------------- | --------------------------------------------------------------------------------------- | | `int32_t` | `'i4'` | - 2^31 | ids of physical components | | `int8_t` | `'i1'` | - 2^7 | enumeration types, boolean types, and small integers (e.g. tap position of transformer) | | `double` | `'f8'` | NaN ([IEEE 754](https://en.wikipedia.org/wiki/NaN)) | physical quantities (e.g. voltage) | | `double[3]` | `'(3, )f8'` | NaN ([IEEE 754](https://en.wikipedia.org/wiki/NaN)) | three-phase asymmetric physical quantities (e.g. voltage) | + *The [endianness](https://en.wikipedia.org/wiki/Endianness) of C++ and Python side is also matched. For `x86-64` platform the little endian is used, so that the `numpy.dtype` is `' 1. Initialize the permutations $\mathbf{P}$ and $\mathbf{Q}$ to the identity permutation. 2. Initialize fill-in elements to $0$. 3. Loop over all rows: $p = 0..(N-1)$: @@ -326,11 +327,12 @@ $\mathbf{M}\left[0:3, j\right]$. 2. $\mathbf{M}_p\left[0:N_p,0\right] \leftrightarrow \mathbf{M}\left[0:N_p,j_p\right]$ 6. Apply Gaussian elimination for the current pivot element: 1. $\mathbf{M}_p\left[0,0:N_p\right] \gets \frac{1}{\mathbf{M}_p[0,0]}\mathbf{M}_p\left[0,0:N_p\right]$ - 2. $\mathbf{M}_p\left[1:N_p,0:N_p\right] \gets \mathbf{M}_p\left[1:N_p,0:N_p\right] - \mathbf{M}_p\left[1:N_p,0\right] \otimes \mathbf{M}_p\left[0,0:N_p\right]$ + 2. $\mathbf{M}_p\left[1:N_p,0:N_p\right] \gets \mathbf{M}_p\left[1:N_p,0:N_p\right] - \mathbf{M}_p\left[1:N_p,0\right] \otimes \mathbf{M}_p\left[0,0:N_p\right]$ 7. Accumulate the permutation matrices: 1. In $\mathbf{P}$: swap $p \leftrightarrow p + i_p$ 2. In $\mathbf{Q}$: swap $p \leftrightarrow p + j_p$ 8. Continue with the next $p$ to factorize the the bottom-right block. + $\mathbf{L}$ is now the matrix containing the lower triangle of $\mathbf{M}$, ones on the diagonal and zeros in the upper triangle. @@ -801,7 +803,7 @@ The equation $\mathbf{L}\boldsymbol{y} = \mathbf{P}\boldsymbol{b}$ is solved as 1. Loop over all block-rows: $i=0..(N-1)$: 1. Loop over all lower-triangle off-diagonal columns (beware of sparsity): $j=0..(i-1)$: - 1. $\boldsymbol{b}\left[i\right] \gets \boldsymbol{b}\left[i\right] - \mathbf{L}\left[i,j\right] \cdot \boldsymbol{b}\left[j\right]$. + 1. $\boldsymbol{b}\left[i\right] \gets \boldsymbol{b}\left[i\right] - \mathbf{L}\left[i,j\right] \cdot \boldsymbol{b}\left[j\right]$. 2. Continue with next block-column. 2. If the matrix is a block matrix: 1. Follow the same steps within the block. @@ -815,7 +817,7 @@ The equation $Uz = y$ is solved as follows. 1. Loop over all block-rows in reverse order: $i=(N-1)..0$: 1. Loop over all upper-triangle off-diagonal columns (beware of sparsity): $j=(i+1)..0$: - 1. $\boldsymbol{b}\left[i\right] \gets \boldsymbol{b}\left[i\right] - \mathbf{U}\left[i,j\right] \cdot \boldsymbol{b}\left[j\right]$. + 1. $\boldsymbol{b}\left[i\right] \gets \boldsymbol{b}\left[i\right] - \mathbf{U}\left[i,j\right] \cdot \boldsymbol{b}\left[j\right]$. 2. Continue with next block-column. 2. Handle the diagonal element: 1. If the matrix is a block matrix: @@ -1131,7 +1133,7 @@ with dimensions $N_i\times N_j$. 3. Loop over all rows of the current block: $k = 0..(N_{i,j} - 1)$: 1. $\text{block\_row\_norm} \gets 0$. 2. Loop over all columns of the current block: $l = 0..(N_{i,j} - 1)$: - 1. $\text{block\_row\_norm} \gets \text{block\_row\_norm} + \left\|\mathbf{M}_{i,j}\left[k,l\right]\right\|$. + 1. $\text{block\_row\_norm} \gets \text{block\_row\_norm} + \left\|\mathbf{M}_{i,j}\left[k,l\right]\right\|$. 3. Calculate the new block norm: set $\text{block\_norm} \gets \max\left\{\text{block\_norm}, \text{block\_row\_norm}\right\}$. 4. Continue with the next row of the current block. @@ -1186,10 +1188,11 @@ $$ \end{bmatrix} $$ + * The regular $L_{\infty}$-norm is $\max\left\{1+3, 3, 5, \frac{1}{2}, 1, 1\right\} = 5$. * The block-wise off-diagonal infinity $L_{\infty ,\text{bwod}}$-norm is - $\max\left\{\max\left\{1, 3\right\}+\max\left\{3, 0\right\},\max\left\{5, 0\right\} + \max\left\{0, \frac{1}{2}\right\}, 1\right\} = \max\left\{3+3, 5+\frac{1}{2}, 1, 1\right\} = 6$. + The two norms clearly differ and even the elements that contribute most to the norm are different. @@ -1214,9 +1217,10 @@ $$ \end{bmatrix} $$ + * The regular $L_{\infty}$-norm is $\max\left\{20+20+2+2,30+3,100,3+1\right\} = \max\left\{44,33,100,4\right\} = 100$. * The block-wise infinity norm with diagonals would be - $\max\left\{\max\left\{20+20, 30\right\}+\max\left\{2+2, 3\right\},\max\left\{0,3\right\} + \max\left\{100, 1\right\}\right\} = \max\left\{40+4, 3+100\right\} = \max\left\{44, 103\right\} = 103$. * The $L_{\infty ,\text{bwod}}$-norm is $\max\left\{\max\left\{2+2, 3\right\},\max\left\{0,3\right\}\right\} = \max\left\{4, 3\right\} = 4$. + diff --git a/docs/algorithms/pf-algorithms.md b/docs/algorithms/pf-algorithms.md index fb1cbc92ca..ed3967e3e0 100644 --- a/docs/algorithms/pf-algorithms.md +++ b/docs/algorithms/pf-algorithms.md @@ -37,7 +37,9 @@ The following bus types can be present in the system: Note: this bus is not supported by power-grid-model yet. ```{note} -Asymmetric power flow calculations require the network to have a reference to ground. For details and internal solution of asymmetric floating grids calculations in power-grid-model, please refer to [Floating grid handling](../user_manual/calculations.md#floating-grid-handling). +Asymmetric power flow calculations require the network to have a reference to ground. +For details and internal solution of asymmetric floating grids calculations in power-grid-model, please refer to +[Floating grid handling](../user_manual/calculations.md#floating-grid-handling). ``` ## Newton-Raphson power flow diff --git a/docs/algorithms/sc-algorithms.md b/docs/algorithms/sc-algorithms.md index 8c60a8fb5f..748969050f 100644 --- a/docs/algorithms/sc-algorithms.md +++ b/docs/algorithms/sc-algorithms.md @@ -22,7 +22,8 @@ This gives the initial symmetrical short circuit current ($I_k^{\prime\prime}$) This quantity is then used to derive almost all further calculations of short circuit studies applications. ```{note} -Short-circuit calculations are currently implemented in the phase (abc) domain and therefore require a grounded network, similar to asymmetric power flow calculations. +Short-circuit calculations are currently implemented in the phase (abc) domain and therefore require a grounded network, +similar to asymmetric power flow calculations. Note that this limitation does not exist in the sequence (0-1-2) domain but is present in the phase domain calculation. ``` diff --git a/docs/algorithms/se-algorithms.md b/docs/algorithms/se-algorithms.md index a189755c9d..efd4bbef30 100644 --- a/docs/algorithms/se-algorithms.md +++ b/docs/algorithms/se-algorithms.md @@ -105,8 +105,8 @@ It is not possible to mix [power sensors](../user_manual/components.md#generic-p [current sensors](../user_manual/components.md#generic-current-sensor) on the same terminal of the same component. It is also not possible to mix [current sensors with global angle measurement type](../user_manual/components.md#global-angle-current-sensors) with -[current sensors with local angle measurement type](../user_manual/components.md#local-angle-current-sensors) on the same terminal -of the same component. +[current sensors with local angle measurement type](../user_manual/components.md#local-angle-current-sensors) on the +same terminal of the same component. However, such mixing of sensor types is allowed as long as they are on different terminals. ``` @@ -313,7 +313,7 @@ Consequently, the iteration process differs slightly from that of $\widetilde{\boldsymbol{U}}^{(k)}$ and $\widetilde{\boldsymbol{\theta}}^{(k)}$, using the prefactorized matrix. See also [Matrix-prefactorization](../user_manual/performance-guide.md#matrix-prefactorization) - Normalize the result voltage phasor angle by setting angle of slack bus to zero: - $\underline{U}_i^{(k)} = \widetilde{\underline{U}}_i^{(k)} \times |\widetilde{\underline{U}}_s^{(k)}| / \widetilde{\underline{U}}_s^{(k)}$. + $\underline{U}_i^{(k)} = \widetilde{\underline{U}}_i^{(k)} \times |\widetilde{\underline{U}}_s^{(k)}| / \widetilde{\underline{U}}_s^{(k)}$. - If the maximum deviation between $\underline{\boldsymbol{U}}^{(k)}$ and $\underline{\boldsymbol{U}}^{(k-1)}$ is smaller than the tolerance $\epsilon$, stop the iteration, otherwise continue until the maximum number of iterations is reached. diff --git a/docs/algorithms/tap-changing-algorithms.md b/docs/algorithms/tap-changing-algorithms.md index 60c82ad423..ef080bc002 100644 --- a/docs/algorithms/tap-changing-algorithms.md +++ b/docs/algorithms/tap-changing-algorithms.md @@ -41,24 +41,28 @@ regulator is automatic. The following table specifies the behaviour of regulated transformers based on the {py:class}`TapChangingStrategy ` chosen and whether `tap_pos` is regulated. + |TapChangingStrategy|tap_pos is regulated?|Initialization phase|Exploitation phase| |---|---|---|---| |{py:class}`any_valid_tap `|Yes|Set the tap position to `tap_nom` (default middle tap position)|Binary search (default)| |{py:class}`any_valid_tap `|No|Clamp the tap position to stay within `tap_min` and `tap_max`|Do not regulate| |{py:class}`min_voltage_tap ` / {py:class}`max_voltage_tap `|Yes|Set the tap position to `tap_min` or `tap_max` respectively|Do not regulate| |{py:class}`min_voltage_tap ` / {py:class}`max_voltage_tap `|No|Clamp the tap position to stay within `tap_min` and `tap_max`|Do not regulate| + Some transformer configurations require clamping due to `regulated_object` and `tap_side` pointing to different sides of the transformer. For a three-winding transformer the requirements are similar to a regular transformer with the additional consideration that the primary side tap changer regulates only the secondary or tertiary side voltages: + |Tapping on side|Regulated object|Voltage control side|`tap_side`|`regulated_object`|`control_side`| |---|---|---|---|---|---| |HV (0)|LV (1)|LV (1)|`BranchSide.from_side` / `Branch3Side.side_1`|`TransformerTapSide.side_1` / `Branch3Side.side_2`|`BranchSide.to_side` / `Branch3Side.side_2`| |HV (0)|LV (1)|HV (0)|`BranchSide.from_side` / `Branch3Side.side_1`|`TransformerTapSide.side_1` / `Branch3Side.side_2`|`BranchSide.from_side` / `Branch3Side.side_1`| |LV (1)|HV (0)|LV (1)|`BranchSide.to_side` / `Branch3Side.side_2`|`TransformerTapSide.side_2` / `Branch3Side.side_1`|`BranchSide.to_side` / `Branch3Side.side_2`| |LV (1)|HV (0)|HV (0)|`BranchSide.to_side` / `Branch3Side.side_2`|`TransformerTapSide.side_2` / `Branch3Side.side_1`|`BranchSide.from_side` / `Branch3Side.side_1`| + ## Search methods used for tap changing optimization @@ -66,11 +70,13 @@ By default, the algorithm uses binary search to find the optimal tap position to Users can also choose other search methods via {py:class}`TapChangingStrategy `: + |{py:class}`TapChangingStrategy `|Description| |---|---| |{py:class}`fast_any_tap `|Very fast search (single step per iteration)| |{py:class}`any_valid_tap `|Binary search (default)| |{py:class}`min_voltage_tap ` / {py:class}`max_voltage_tap `|Set to extreme tap and do not regulate| + ## Regulatable voltage range outside `u_band` diff --git a/docs/contribution/folder-structure.md b/docs/contribution/folder-structure.md index 199a4ef2c5..57d0e0334d 100644 --- a/docs/contribution/folder-structure.md +++ b/docs/contribution/folder-structure.md @@ -8,8 +8,9 @@ SPDX-License-Identifier: MPL-2.0 The repository folder structure is as follows. The `docs` and `scripts` folders are self-explanatory. + - The C++ calculation core is inside - {{ "[power_grid_model_c/power_grid_model/include/power_grid_model]({}/power_grid_model_c/power_grid_model/include/power_grid_model)".format(gh_link_head_tree) }}. + {{ "[power_grid_model_c/power_grid_model/include/power_grid_model]({}/power_grid_model_c/power_grid_model/include/power_grid_model)".format(gh_link_head_tree) }}. - The C API is inside {{ "[power_grid_model_c/power_grid_model_c]({}/power_grid_model_c/power_grid_model_c)".format(gh_link_head_tree) }}. - The C program example to use the C API is inside @@ -29,3 +30,4 @@ The repository folder structure is as follows. The `docs` and `scripts` folders - `data` contains validation test cases designed for every component and algorithm. Some sample network types are also included. The validation is either against popular power system analysis software or hand calculation. + diff --git a/docs/user_manual/calculations.md b/docs/user_manual/calculations.md index 47ac854f38..e97db67a98 100644 --- a/docs/user_manual/calculations.md +++ b/docs/user_manual/calculations.md @@ -124,7 +124,8 @@ However, such mixing of sensor types is allowed as long as they are on different ``` ```{warning} -The [iterative linear](../algorithms/se-algorithms.md#iterative-linear-state-estimation) and [Newton-Raphson](../algorithms/se-algorithms.md#newton-raphson-state-estimation) state +The [iterative linear](../algorithms/se-algorithms.md#iterative-linear-state-estimation) and +[Newton-Raphson](../algorithms/se-algorithms.md#newton-raphson-state-estimation) state estimation algorithms will assume angles to be zero by default (see the details about voltage sensors). In observable systems this helps better outputting correct results. On the other hand with unobservable systems, exceptions raised from calculations due to faulty results will be @@ -193,8 +194,11 @@ Output: - Current flowing through branches and fault. ```{note} -Short-circuit calculations are currently implemented in the phase (abc) domain and therefore require a grounded configurations in certain cases, similar to asymmetric power flow calculations. -For details on how floating grids are treated in power-grid-model, please refer to[Floating grid handling](calulations.md#floating-grid-handling). +Short-circuit calculations are currently implemented in the phase (abc) domain and therefore require a grounded +configurations in certain cases, similar to asymmetric power flow calculations. +For details on how floating grids are treated in power-grid-model, please refer to +[Floating grid handling](calulations.md#floating-grid-handling). +``` #### Common calculations @@ -240,7 +244,10 @@ The option affects which attributes are required and how results are exposed. for all output variables. ```{note} -In power-grid model, asymmetric calculations with certain configurations require the network to have a reference to ground. For details on how floating grids are treated in power-grid-model, please refer to [Floating grid handling](calulations.md#floating-grid-handling). +In power-grid model, asymmetric calculations with certain configurations require the network to have a reference to +ground. +For details on how floating grids are treated in power-grid-model, please refer to +[Floating grid handling](calulations.md#floating-grid-handling). ``` ```{note} @@ -287,20 +294,22 @@ right one. At the moment, the following power flow algorithms are implemented. + | Algorithm | Speed | Result | Convergence | Typical Use Cases | Algorithm call | |--------------------------------------------------------------------------------- |---------------------------------- |---------------------------------- |-------------------- |------------------------------------------------------------------------ |----------------------------------------------------------------------------------------------------------- | | [Newton-Raphson](../algorithms/pf-algorithms.md#newton-raphson-power-flow) | Medium | Accurate within `error_tolerance` | Quadratic, robust | General purpose, any type of grid | {py:class}`CalculationMethod.newton_raphson ` | | [Iterative current](../algorithms/pf-algorithms.md#iterative-current-power-flow) | Fast (Radial) Slow (Meshed) | Accurate within `error_tolerance` | Linear, less robust | Non-topological change batch calculations like timeseries, radial grids | {py:class}`CalculationMethod.iterative_current `| | [Linear](../algorithms/pf-algorithms.md#linear-power-flow) | Much Faster | Approximate | Single iteration | Large number of calculations, troubleshooting iterative methods | {py:class}`CalculationMethod.linear ` | | [Linear current](../algorithms/pf-algorithms.md#linear-current-power-flow) | Much Faster | Approximate | Single iteration | Large number of calculations | {py:class}`CalculationMethod.linear_current ` | + ```{note} By default, the [Newton-Raphson](../algorithms/pf-algorithms.md#newton-raphson-power-flow) method is used. ``` ```{note} -When all the load/generation types are of constant impedance, the [Linear](../algorithms/pf-algorithms.md#linear-power-flow) method will be the -fastest without loss of accuracy. +When all the load/generation types are of constant impedance, the +[Linear](../algorithms/pf-algorithms.md#linear-power-flow) method will be the fastest without loss of accuracy. Therefore power-grid-model will use this method regardless of the input provided by the user in this case. ``` @@ -351,9 +360,11 @@ Regulated power flow calculations are disabled by default. At the time of writing, the following regulated power flow calculation types are implemented. Please refer to their respective sections for detailed documentation. + | Regulation type | Setting | Enum values | | ----------------------------------------------------------------- | --------------------------------------------------------------------------------------- | --------------------------------------------------------------------------- | | [Automatic tap changing](#power-flow-with-automatic-tap-changing) | {py:meth}`tap_changing_strategy ` | {py:class}`TapChangingStrategy ` | + #### Power flow with automatic tap changing @@ -366,6 +377,7 @@ Power flow calculations that take the behavior of these regulators into account following strategies to the {py:meth}`tap_changing_strategy ` option. + | Algorithm | Default | Speed | Algorithm call | | --------------------------------------------------------------------------- | -------- | -------- | ----------------------------------------------------------------------------------------------------------- | | No automatic tap changing (regular power flow) | ✔ | ✔ | {py:class}`TapChangingStrategy.disabled ` | @@ -373,6 +385,7 @@ option. | Optimize tap positions for lowest possible voltage in the voltage band | | | {py:class}`TapChangingStrategy.min_voltage_tap ` | | Optimize tap positions for lowest possible voltage in the voltage band | | | {py:class}`TapChangingStrategy.max_voltage_tap ` | | Optimize tap positions for any value in the voltage band with binary search | | ✔ | {py:class}`TapChangingStrategy.fast_any_tap ` | + For detailed control logic, initialization behavior, search methods, and error handling for automatic tap changing, see [Automatic Tap Changing Algorithm Details](../algorithms/tap-changing-algorithms.md). @@ -384,10 +397,12 @@ the highest likelihood given (pseudo) measurement input. At the moment, the following state estimation algorithms are implemented. + | Algorithm | Default | Speed | Accuracy | Algorithm call | | --------- | ------- | ----- | -------- | -------------- | | [Iterative linear](../algorithms/se-algorithms.md#iterative-linear-state-estimation) | ✔ | ✔ | | {py:class}`CalculationMethod.iterative_linear ` | | [Newton-Raphson](../algorithms/se-algorithms.md#newton-raphson-state-estimation) | | | ✔ | {py:class}`CalculationMethod.newton_raphson ` | + ```{note} By default, the [Iterative linear](../algorithms/se-algorithms.md#iterative-linear-state-estimation) method is used. @@ -404,9 +419,11 @@ of short circuit studies applications. At the moment, the following short circuit algorithms are implemented. + | Algorithm | Default | Speed | Accuracy | Algorithm call | | --------- | ------- | ----- | -------- | -------------- | | [IEC 60909](../algorithms/sc-algorithms.md#iec-60909-short-circuit-calculation) | ✔ | ✔ | | {py:class}`CalculationMethod.iec60909 ` | + For detailed mathematical descriptions including the short circuit equations and IEC 60909 implementation details, see [Short Circuit Algorithm Details](../algorithms/sc-algorithms.md). diff --git a/docs/user_manual/components.md b/docs/user_manual/components.md index 639fa08157..569c90a3d3 100644 --- a/docs/user_manual/components.md +++ b/docs/user_manual/components.md @@ -21,9 +21,11 @@ The base type for all power-grid-model components. #### Input + | name | data type | unit | description | required | update | |------|-----------|------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------|:--------:|:--------------------:| | `id` | `int32_t` | - | ID of a component. The ID should be unique across all components within the same scenario, e.g., you cannot have a node with `id=5` and another line with `id=5`. | ✔ | ❌ (see below) | + If a component update is uniform and is updating all the elements with the same component type, IDs can be omitted or set to `nan`s. @@ -37,10 +39,12 @@ An example of the usage of optional IDs is given in [Power Flow Example](./Power #### Steady state output and Short circuit output + | name | data type | unit | description | |-------------|-----------|------|------------------------------------------------------------------------------------------------------------------------------------| | `id` | `int32_t` | - | ID of a component, the ID should be unique across all components, e.g., you cannot have a node with `id=5` and a line with `id=5`. | | `energized` | `int8_t` | - | Indicates if a component is energized, i.e. connected to a source | + ## Node @@ -58,6 +62,7 @@ Physically a node can be a busbar, a joint, or other similar component. #### Steady state output + | name | data type | unit | description | |-----------|-------------------|----------------------------|-------------------------------------------------------------------------------------------------| | `u_pu` | `RealValueOutput` | - | per-unit voltage magnitude | @@ -65,9 +70,10 @@ Physically a node can be a busbar, a joint, or other similar component. | `u` | `RealValueOutput` | volt (V) | voltage magnitude, line-line for symmetric calculation, line-neutral for asymmetric calculation | | `p` | `RealValueOutput` | watt (W) | active power injection | | `q` | `RealValueOutput` | volt-ampere-reactive (var) | reactive power injection | + ```{note} -The `p` and `q` output of injection follows the `generator` reference direction as mentioned in +The `p` and `q` output of injection follows the `generator` reference direction as mentioned in [Reference Direction](data-model.md#reference-direction) ``` @@ -101,6 +107,7 @@ In this case, the attribute `from_status` and `to_status` is always 1. #### Steady state output + | name | data type | unit | description | |-----------|-------------------|----------------------------|------------------------------------------------------------| | `p_from` | `RealValueOutput` | watt (W) | active power flowing into the branch at from-side | @@ -112,6 +119,7 @@ In this case, the attribute `from_status` and `to_status` is always 1. | `i_to` | `RealValueOutput` | ampere (A) | magnitude of current at to-side | | `s_to` | `RealValueOutput` | volt-ampere (VA) | apparent power flowing at to-side | | `loading` | `double` | - | relative loading of the branch, `1.0` meaning 100% loaded. | + #### Short circuit output @@ -133,6 +141,7 @@ If `i_n` is not provided, `loading` of line will be a `nan` value. #### Input + | name | data type | unit | description | required | update | valid values | |--------|-----------|------------|----------------------------------------------------|:-----------------------------------------:|:--------:|:----------------------------------:| | `r1` | `double` | ohm (Ω) | positive-sequence serial resistance | ✔ | ❌ | `r1` and `x1` cannot be both `0.0` | @@ -144,6 +153,7 @@ If `i_n` is not provided, `loading` of line will be a `nan` value. | `c0` | `double` | farad (F) | zero-sequence shunt capacitance | ✨ only for asymmetric calculations | ❌ | | | `tan0` | `double` | - | zero-sequence shunt loss factor (tan δ) | ✨ only for asymmetric calculations | ❌ | | | `i_n` | `double` | ampere (A) | rated current | ❌ | ❌ | `> 0` | + ```{note} In case of short circuit calculations, the zero-sequence parameters are required only if any of the faults in any of the @@ -191,6 +201,7 @@ An example of usage of transformer is given in [Transformer Examples](../example #### Input + | name | data type | unit | description | required | update | valid values | |--------------------|-------------------------------------------------------------|------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|:--------------------------------------------------------:|:--------:|:----------------------------------------------------------------------:| | `u1` | `double` | volt (V) | rated voltage at from-side | ✔ | ❌ | `> 0` | @@ -219,6 +230,7 @@ An example of usage of transformer is given in [Transformer Examples](../example | `x_grounding_from` | `double` | ohm (Ω) | grounding reactance at from-side, if relevant | ❌ default `0` | ❌ | | | `r_grounding_to` | `double` | ohm (Ω) | grounding resistance at to-side, if relevant | ❌ default `0` | ❌ | | | `x_grounding_to` | `double` | ohm (Ω) | grounding reactance at to-side, if relevant | ❌ default `0` | ❌ | | + ```{note} It can happen that `tap_min > tap_max`. @@ -276,6 +288,7 @@ using a `generic_branch`. #### Input + | name | data type | unit | description | required | update | valid values | |---------|-----------|------------------|-------------------------------|:----------------------:|:--------:|:------------:| | `r1` | `double` | ohm | positive-sequence resistance | ✔ | ❌ | | @@ -285,6 +298,7 @@ using a `generic_branch`. | `k` | `double` | - | off-nominal ratio | ❌ default `1.0` | ❌ | `> 0` | | `theta` | `double` | radian | angle shift | ❌ default `0.0` | ❌ | | | `sn` | `double` | volt-ampere (VA) | rated power | ❌ default `0.0` | ❌ | `>= 0` | + ```{note} The impedance (`r1`, `x1`) and admittance (`g1`, `b1`) attributes are calculated with reference to the "to" side of the @@ -347,6 +361,7 @@ $$ This representation holds for all values `r_aa` ... `r_nn`, `x_aa` ... `x_nn` and `c_aa` ... `c_cc`. If the neutral values are not provided, the last row and column from the above matrix are omitted. + | name | data type | unit | description | required | update | valid values | |--------|-----------|------------|-----------------------------------|------------------------------|:--------:|:------------:| | `r_aa` | `double` | ohm (Ω) | Series serial resistance aa | ✔ | ❌ | `> 0` | @@ -378,6 +393,7 @@ If the neutral values are not provided, the last row and column from the above m | `c0` | `double` | farad (F) | zero-sequence shunt capacitance | ✨ without a c matrix | ❌ | `> 0` | | `c1` | `double` | farad (F) | Series shunt capacitance | ✨ without a c matrix | ❌ | `> 0` | | `i_n` | `double` | ampere (A) | rated current | ❌ | ❌ | `> 0` | + For the r and x matrices providing values for the neutral phase is optional. To clarify which input values are required, please consult the tables below: @@ -480,6 +496,7 @@ In reality such switches may not exist. #### Steady state output + | name | data type | unit | description | |-----------|-------------------|----------------------------|------------------------------------------------------------| | `p_1` | `RealValueOutput` | watt (W) | active power flowing into the branch at side 1 | @@ -495,6 +512,7 @@ In reality such switches may not exist. | `i_3` | `RealValueOutput` | ampere (A) | current at side 3 | | `s_3` | `RealValueOutput` | volt-ampere (VA) | apparent power flowing at side 3 | | `loading` | `double` | - | relative loading of the branch, `1.0` meaning 100% loaded. | + #### Short circuit output @@ -516,6 +534,7 @@ An example of usage of three-winding transformer is given in #### Input + | name | data type | unit | description | required | update | valid values | |-----------------|-------------------------------------------------------------|------------------|-----------------------------------------------------------------------------------------------------------|:-------------------------------------------------------:|:--------:|:----------------------------------------------------------------------:| | `u1` | `double` | volt (V) | rated voltage at side 1 | ✔ | ❌ | `> 0` | @@ -561,6 +580,7 @@ An example of usage of three-winding transformer is given in | `x_grounding_2` | `double` | ohm (Ω) | grounding reactance at side 2, if relevant | ❌ default `0` | ❌ | | | `r_grounding_3` | `double` | ohm (Ω) | grounding resistance at side 3, if relevant | ❌ default `0` | ❌ | | | `x_grounding_3` | `double` | ohm (Ω) | grounding reactance at side 3, if relevant | ❌ default `0` | ❌ | | + ```{note} It can happen that `tap_min > tap_max`. @@ -621,6 +641,7 @@ The impedance is specified by convention as short circuit power. #### Input + | name | data type | unit | description | required | update | valid values | |---------------|-----------|------------------|----------------------------------------------------|:----------------------------:|:--------:|:------------:| | `u_ref` | `double` | - | reference voltage in per-unit | ✨ only for power flow | ✔ | `> 0` | @@ -628,6 +649,7 @@ The impedance is specified by convention as short circuit power. | `sk` | `double` | volt-ampere (VA) | short circuit power | ❌ default `1e10` | ✔ | `> 0` | | `rx_ratio` | `double` | - | R to X ratio | ❌ default `0.1` | ✔ | `>= 0` | | `z01_ratio` | `double` | - | zero-sequence to positive sequence impedance ratio | ❌ default `1.0` | ✔ | `> 0` | + #### Electric Model @@ -663,9 +685,11 @@ $$ `generic_load_gen` is an abstract load/generation [appliance](#appliance) which contains only the type of the load/generation with response to voltage. + | name | data type | unit | description | required | update | |--------|-------------------------------------------------------------|------|-------------------------------------------------|:--------:|:--------:| | `type` | {py:class}`LoadGenType ` | - | type of load/generator with response to voltage | ✔ | ❌ | + #### Load/Generator Concrete Types @@ -682,10 +706,12 @@ However, the reference direction and meaning of `RealValueInput` is different, a ##### Input + | name | data type | unit | description | required | update | |---------------|------------------|----------------------------|--------------------------|:----------------------------:|:--------:| | `p_specified` | `RealValueInput` | watt (W) | specified active power | ✨ only for power flow | ✔ | | `q_specified` | `RealValueInput` | volt-ampere-reactive (var) | specified reactive power | ✨ only for power flow | ✔ | + ##### Electric model @@ -724,12 +750,14 @@ It behaves similar to a load/generator with type `const_impedance`. #### Input + | name | data type | unit | description | required | update | |------|-----------|-------------|-------------------------------------|:----------------------------------------:|:--------:| | `g1` | `double` | siemens (S) | positive-sequence shunt conductance | ✔ | ✔ | | `b1` | `double` | siemens (S) | positive-sequence shunt susceptance | ✔ | ✔ | | `g0` | `double` | siemens (S) | zero-sequence shunt conductance | ✨ only for asymmetric calculation | ✔ | | `b0` | `double` | siemens (S) | zero-sequence shunt susceptance | ✨ only for asymmetric calculation | ✔ | + ```{note} In power-grid-model, shunts may also be used to introduce a ground reference in an otherwise floating grid. @@ -775,9 +803,11 @@ It measures the magnitude and (optionally) the angle of the voltage of a `node`. #### Input + | name | data type | unit | description | required | update | valid values | |-----------|-----------|----------|-----------------------------------------------------------------------------------------------------------------|:----------------------------------:|:--------:|:------------:| | `u_sigma` | `double` | volt (V) | standard deviation of the measurement error. Usually this is the absolute measurement error range divided by 3. | ✨ only for state estimation | ✔ | `> 0` | + #### Voltage Sensor Concrete Types @@ -793,10 +823,12 @@ In a `asym_voltage_sensor` the measured voltage is a 3-phase line-to-ground volt ##### Input + | name | data type | unit | description | required | update | valid values | |--------------------|------------------|----------|----------------------------------------------------------------------|:----------------------------------------------------------------------------------------------------------------:|:--------:|:------------:| | `u_measured` | `RealValueInput` | volt (V) | measured voltage magnitude | ✨ only for state estimation | ✔ | `> 0` | | `u_angle_measured` | `RealValueInput` | rad | measured voltage angle (only possible with phasor measurement units) | ✨ only for state estimation when a current sensor with `global_angle` `angle_measurement_type` is present | ✔ | | + ```{note} When a current sensor with `global_angle` `angle_measurement_type` is present there needs to be a voltage sensor with @@ -810,10 +842,12 @@ A sensor only has output for state estimation. For other calculation types, sensor output is undefined. ``` + | name | data type | unit | description | |--------------------|-------------------|----------|--------------------------------------------------------------------------------------------------------------------------| | `u_residual` | `RealValueOutput` | volt (V) | residual value between measured voltage magnitude and calculated voltage magnitude | | `u_angle_residual` | `RealValueOutput` | rad | residual value between measured voltage angle and calculated voltage angle (only possible with phasor measurement units) | + #### Electric Model @@ -866,10 +900,12 @@ However, such mixing of sensor types is allowed as long as they are on different ##### Input + | name | data type | unit | description | required | update | valid values | |--------------------------|-------------------------------------------------------------------------------|------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|:-----------------------------------------------------------------------------------------------------------------------------:|:--------:|:----------------------------------------------------:| | `measured_terminal_type` | {py:class}`MeasuredTerminalType ` | - | indicate if it measures an `appliance` or a `branch` | ✔ | ❌ | the terminal type should match the `measured_object` | | `power_sigma` | `double` | volt-ampere (VA) | standard deviation of the measurement error. Usually this is the absolute measurement error range divided by 3. See [Power Sensor Concrete Types](#power-sensor-concrete-types). | ✨ in certain cases for state estimation. See the explanation for [concrete types](#power-sensor-concrete-types) below. | ✔ | `> 0` | + #### Power Sensor Concrete Types @@ -883,12 +919,14 @@ They share similar attributes: the meaning of `RealValueInput` is different, as ##### Input + | name | data type | unit | description | required | update | valid values | |--------------|------------------|----------------------------|--------------------------------------------------------------------------------------------------------------------------------|:-----------------------------------:|:--------:|:------------:| | `p_measured` | `RealValueInput` | watt (W) | measured active power | ✨ only for state estimation | ✔ | | | `q_measured` | `RealValueInput` | volt-ampere-reactive (var) | measured reactive power | ✨ only for state estimation | ✔ | | | `p_sigma` | `RealValueInput` | watt (W) | standard deviation of the active power measurement error. Usually this is the absolute measurement error range divided by 3. | ❌ see the explanation below. | ✔ | `> 0` | | `q_sigma` | `RealValueInput` | volt-ampere-reactive (var) | standard deviation of the reactive power measurement error. Usually this is the absolute measurement error range divided by 3. | ❌ see the explanation below. | ✔ | `> 0` | + Valid combinations of `power_sigma`, `p_sigma` and `q_sigma` are: @@ -910,6 +948,7 @@ measurement. 2. If neither `p_sigma` nor `q_sigma` are provided, `power_sigma` represents the standard deviation of the apparent power. In this case, infinite value of `power_sigma` disables the entire measurement. + 3. Providing only one of `p_sigma` and `q_sigma` results in undefined behaviour. ``` @@ -925,10 +964,12 @@ A sensor only has output for state estimation. For other calculation types, sensor output is undefined. ``` + | name | data type | unit | description | |--------------|-------------------|----------------------------|------------------------------------------------------------------------------| | `p_residual` | `RealValueOutput` | watt (W) | residual value between measured active power and calculated active power | | `q_residual` | `RealValueOutput` | volt-ampere-reactive (var) | residual value between measured reactive power and calculated reactive power | + #### Electric Model @@ -967,12 +1008,14 @@ However, such mixing of sensor types is allowed as long as they are on different ##### Input + | name | data type | unit | description | required | update | valid values | |--------------------------|-------------------------------------------------------------------------------|------------|-------------------------------------------------------------------------------------------------------------------------------------------|:----------------------------------:|:--------:|:----------------------------------------------------:| | `measured_terminal_type` | {py:class}`MeasuredTerminalType ` | - | indicate the side of the `branch` | ✔ | ❌ | the terminal type should match the `measured_object` | | `angle_measurement_type` | {py:class}`AngleMeasurementType ` | - | indicate whether the measured angle is a global angle or a local angle; (see the [electric model](#local-angle-current-sensors) below) | ✔ | ❌ | | | `i_sigma` | `double` | ampere (A) | standard deviation of the current (`i`) measurement error. Usually this is the absolute measurement error range divided by 3. | ✨ only for state estimation | ✔ | `> 0` | | `i_angle_sigma` | `double` | rad | standard deviation of the current (`i`) phase angle measurement error. Usually this is the absolute measurement error range divided by 3. | ✨ only for state estimation | ✔ | `> 0` | + #### Current Sensor Concrete Types @@ -986,10 +1029,12 @@ They share similar attributes: the meaning of `RealValueInput` is different, as ##### Input + | name | data type | unit | description | required | update | |--------------------|------------------|------------|---------------------------------------------------------------------------------------------------------|:----------------------------------:|:--------:| | `i_measured` | `RealValueInput` | ampere (A) | measured current (`i`) magnitude | ✨ only for state estimation | ✔ | | `i_angle_measured` | `RealValueInput` | rad | measured phase angle of the current (`i`; see the [electric model](#local-angle-current-sensors) below) | ✨ only for state estimation | ✔ | + See the documentation on [state estimation calculation methods](calculations.md#state-estimation-algorithms) for details per method on how the variances are taken into account for both the global and local angle measurement types and for the @@ -1007,10 +1052,12 @@ A sensor only has output for state estimation. For other calculation types, sensor output is undefined. ``` + | name | data type | unit | description | |--------------------|-------------------|------------|---------------------------------------------------------------------------------------------| | `i_residual` | `RealValueOutput` | ampere (A) | residual value between measured current (`i`) and calculated current (`i`) | | `i_angle_residual` | `RealValueOutput` | rad | residual value between measured phase angle and calculated phase angle of the current (`i`) | + #### Electric Model @@ -1078,6 +1125,7 @@ A fault can only happen at a `node`. #### Input + | name | data type | unit | description | required | update | valid values | |----------------|-----------------------------------------------------------|---------|-----------------------------------------------------|:-------------------------------------------------------------------------------------------------------:|:--------:|:-----------------:| | `status` | `int8_t` | - | whether the fault is active | ✔ | ✔ | `0` or `1` | @@ -1086,6 +1134,7 @@ A fault can only happen at a `node`. | `fault_object` | `int32_t` | - | ID of the component where the short circuit happens | ✔ | ✔ | A valid `node` ID | | `r_f` | `double` | ohm (Ω) | short circuit resistance | ❌ default `0.0` | ✔ | | | `x_f` | `double` | ohm (Ω) | short circuit reactance | ❌ default `0.0` | ✔ | | + ```{note} Multiple faults may exist within one calculation. @@ -1119,12 +1168,14 @@ In case the `fault_phase` is not specified or is equal to `FaultPhase.default_va `fault_type`-dependent set of fault phases. The supported values of `fault_phase`, as well as its default value, are listed in the table below. + | `fault_type` | supported values of `fault_phase` | `FaultPhase.default_value` | description | |------------------------------------|---------------------------------------------------|----------------------------|------------------------------------------------------------------------| | `FaultType.three_phase` | `FaultPhase.abc` | `FaultPhase.abc` | Three phases are connected with fault impedance. | | `FaultType.single_phase_to_ground` | `FaultPhase.a`, `FaultPhase.b`, `FaultPhase.c` | `FaultPhase.a` | One phase is grounded with fault impedance, and other phases are open. | | `FaultType.two_phase` | `FaultPhase.bc`, `FaultPhase.ac`, `FaultPhase.ab` | `FaultPhase.bc` | Two phases are connected with fault impedance. | | `FaultType.two_phase_to_ground` | `FaultPhase.bc`, `FaultPhase.ac`, `FaultPhase.ab` | `FaultPhase.bc` | Two phases are connected with fault impedance then grounded. | + ## Regulator @@ -1137,10 +1188,12 @@ Which object types are supported as `regulated_object` is regulator type-depende #### Input + | name | data type | unit | description | required | update | valid values | |--------------------|-----------|------|-------------------------------------------|:--------:|:--------:|:---------------------------:| | `regulated_object` | `int32_t` | - | ID of the regulated object | ✔ | ❌ | a valid regulated object ID | | `status` | `int8_t` | - | connection status to the regulated object | ✔ | ✔ | `0` or `1` | + ### Transformer tap regulator @@ -1167,6 +1220,7 @@ The actual grid state is not changed after calculations are done. #### Input + | name | data type | unit | description | required | update | valid values | |----------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|----------|---------------------------------------------------------------------------------------------------------|:----------------------------:|:--------:|:----------------------------------------------------------------:| | `control_side` | {py:class}`BranchSide ` if the regulated object is a [transformer](#transformer) and {py:class}`Branch3Side ` if it the regulated object is a [Three-Winding Transformer](#three-winding-transformer) | - | the controlled side of the transformer | ✨ only for power flow | ❌ | `control_side` should be the relatively further side to a source | @@ -1174,6 +1228,7 @@ The actual grid state is not changed after calculations are done. | `u_band` | `double` | volt (V) | the width of the voltage band ($=2*\left(\Delta U\right)_{\text{acceptable}}$) | ✨ only for power flow | ✔ | `> 0` (see below) | | `line_drop_compensation_r` | `double` | ohm (Ω) | compensation for voltage drop due to resistance during transport (see [below](#line-drop-compensation)) | ❌ default `0.0` | ✔ | `>= 0` | | `line_drop_compensation_x` | `double` | ohm (Ω) | compensation for voltage drop due to reactance during transport (see [below](#line-drop-compensation)) | ❌ default `0.0` | ✔ | `>= 0` | + The following additional requirements exist on the input parameters. @@ -1284,18 +1339,22 @@ the voltage regulator should operate at the limit and the voltage may deviate fr #### Input + | name | data type | unit | description | required | update | valid values | | -------- | --------- | -------------------------- | --------------------------------------------------- | :--------------------------: | :------: | :----------: | | `u_ref` | `double` | - | reference voltage in per-unit at the generator node | ✨ only for power flow | ✔ | `> 0` | | `q_min` | `double` | volt-ampere-reactive (var) | minimum reactive power limit of the generator | ❌ | ✔ | | | `q_max` | `double` | volt-ampere-reactive (var) | maximum reactive power limit of the generator | ❌ | ✔ | | + #### Steady state output + | name | data type | unit | description | | ----------------- | ----------------- | -------------------------- | -------------------------------------------------------------------- | | `q` | `RealValueOutput` | volt-ampere-reactive (var) | reactive power provided by the voltage regulator | | `limit_violated` | `int8_t` | - | reactive power limit violation indicator (not yet fully implemented) | + #### Short circuit output diff --git a/docs/user_manual/data-model.md b/docs/user_manual/data-model.md index 64b2c0e55a..6778a04388 100644 --- a/docs/user_manual/data-model.md +++ b/docs/user_manual/data-model.md @@ -14,6 +14,7 @@ The components types are organized in an inheritance-like hierarchy. A sub-type has all the attributes from its parent type. The hierarchy tree of the component types is shown below. + ```{mermaid} graph LR base-->node @@ -43,6 +44,7 @@ graph LR classDef green fill:#9f6,stroke:#333,stroke-width:2px class node,line,link,generic_branch,transformer,three_winding_transformer,source,shunt,sym_load,sym_gen,asym_load,asym_gen,sym_voltage_sensor,asym_voltage_sensor,sym_power_sensor,asym_power_sensor green ``` + ```{note} The type names in the hierarchy are exactly the same as the component type names in diff --git a/docs/user_manual/dataset-terminology.md b/docs/user_manual/dataset-terminology.md index d0212ecded..2ae8ad8f21 100644 --- a/docs/user_manual/dataset-terminology.md +++ b/docs/user_manual/dataset-terminology.md @@ -204,12 +204,14 @@ graph TD The dimensions of numpy arrays and the interpretation of each dimension is as follows. + | **Data Type** | **1D** | **2D** | **3D** | | ------------------- | -------------------------------- | ---------------------------------------------------- | -------------------------------------------------------------------------- | | **SingleArray** | Corresponds to a single dataset. | ❌ | ❌ | | **DenseBatchArray** | ❌ | Batch number $\times$ Component within that batch | ❌ | | **SingleColumn** | Component within that batch. | Component within that batch $\times$ Phases ✨ | ❌ | | **BatchColumn** | ❌ | Batch number $\times$ Component within that batch | Batch number $\times$ Component within that batch $\times$ Phases ✨ | + ```{note} ✨ The "Phases" dimension is optional and is available only when the attributes are asymmetric. @@ -281,6 +283,7 @@ The batch size is the number of scenarios. ## Attributes of Components + | Attribute | Description | | ------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | name | Name of the attribute. It is exactly the same as the attribute name in `power_grid_model.power_grid_meta_data`. They are included under the enum {py:class}`AttributeType `. | @@ -292,3 +295,4 @@ The batch size is the number of scenarios. | required | Whether the attribute is required. If not, then it is optional. Note if you choose not to specify an optional attribute, it should have the null value as defined in [](../advanced_documentation/native-data-interface.md#basic-data-types). | | update | Whether the attribute can be mutated by the update call `PowerGridModel.update` on an existing instance, only applicable when this attribute is part of an input dataset. | | valid values | Whether applicable or not; an indication of value validity for the input data. | + diff --git a/docs/user_manual/model-validation.md b/docs/user_manual/model-validation.md index 6a7be1d762..5dec22a828 100644 --- a/docs/user_manual/model-validation.md +++ b/docs/user_manual/model-validation.md @@ -221,7 +221,7 @@ The circuit diagram is as follows (The node 6 is same in both lines): Gen(_22)---|_2--transformer(_31)--|_4 |_5-------line(_15)----|_6 | shunt(_29)---| shunt(_28)---|-load(_24) - + |----line(_16)-------| |---line(_19)---|_9---transformer(_32)---|_11---source(_20) | |---line(_18)---| diff --git a/docs/user_manual/non-pgm-components.md b/docs/user_manual/non-pgm-components.md index 403edd6e90..c8a6043f28 100644 --- a/docs/user_manual/non-pgm-components.md +++ b/docs/user_manual/non-pgm-components.md @@ -20,7 +20,7 @@ New contributions and ideas for modeling grid components are very welcome! ## Ideal transformer -An ideal transformer can be modeled as a [link](./components.md#link). +An ideal transformer can be modeled as a [link](./components.md#link). To this end, it is explicitly allowed to place a link between two different voltage levels. Trivially, no additional electrical parameters need to be specified. diff --git a/pyproject.toml b/pyproject.toml index 7632d2594d..7a6573aced 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -30,7 +30,9 @@ classifiers = [ "Topic :: Scientific/Engineering :: Physics", ] requires-python = ">=3.12" -dependencies = ["numpy>=2.0.0"] +dependencies = [ + "numpy>=2.0.0", +] dynamic = ["version"] [dependency-groups] @@ -44,6 +46,7 @@ lint = [ "numpy", # needed for mypy "gersemi", # CMake linter "clang-format ~= 18.0", # C/C++ formatter + "pymarkdownlnt", # Markdown linter "reuse[charset-normalizer,chardet]", # license check ] @@ -198,6 +201,13 @@ show_column_numbers = true non_interactive = true install_types = true +[tool.pymarkdown] +plugins.heading-increment.enabled = false +plugins.no-duplicate-heading.enabled = false +plugins.line-length.line_length = 120 +plugins.line-length.heading_line_length = 120 +plugins.line-length.code_block_line_length = 120 + # CI build options [tool.cibuildwheel] build-frontend = "build[uv]" diff --git a/tests/data/power_flow/generic_branch/README.md b/tests/data/power_flow/generic_branch/README.md index 1f2d46cc05..76b0929a4d 100644 --- a/tests/data/power_flow/generic_branch/README.md +++ b/tests/data/power_flow/generic_branch/README.md @@ -11,5 +11,5 @@ Test case for validation of the generic_branch component for symmetrical power f The circuit diagram is as follows: ```txt -source_4--node_1--generic_branch_3--node_2--load_5 +source_4--node_1--generic_branch_3--node_2--load_5 ``` diff --git a/uv.lock b/uv.lock index 6298a4a3e8..8edcdf9316 100644 --- a/uv.lock +++ b/uv.lock @@ -22,6 +22,34 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/7e/b3/6b4067be973ae96ba0d615946e314c5ae35f9f993eca561b356540bb0c2b/alabaster-1.0.0-py3-none-any.whl", hash = "sha256:fc6786402dc3fcb2de3cabd5fe455a2db534b371124f1f21de8731783dec828b", size = 13929, upload-time = "2024-07-26T18:15:02.05Z" }, ] +[[package]] +name = "application-file-scanner" +version = "0.6.4" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "py-walk" }, + { name = "typing-extensions" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/ea/22/e872546d298103527380955f51191ff87cd178e6aac62bb87de73c3e074f/application_file_scanner-0.6.4.tar.gz", hash = "sha256:581c48c5017345747be7f49507da84fec36d1f7b4f67003e9fbaf2f0bc6a3f66", size = 28540, upload-time = "2026-01-19T23:32:15.695Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/ca/83/e9a5a14c1b6c20ad44abcdb7bb2f34d860aa4f4ee64c526247066b6c42fb/application_file_scanner-0.6.4-py3-none-any.whl", hash = "sha256:49c211c60f1932812477facc38701d58037b07b031fdb6a6061fdee3fd53e35f", size = 15445, upload-time = "2026-01-19T23:32:14.4Z" }, +] + +[[package]] +name = "application-properties" +version = "0.9.3" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "pyjson5" }, + { name = "pyyaml" }, + { name = "tomli" }, + { name = "typing-extensions" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/c0/bb/321da0e373416080801d05b8dd9c0a8da77fe305c697adf8c025470ce170/application_properties-0.9.3.tar.gz", hash = "sha256:7dc7d8f23d11e539427e7b8e3afa70353e159c16f703bad6dd082cc6cdfeeaa8", size = 43304, upload-time = "2026-06-02T03:52:07.6Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/95/72/3ac1bda73e9c95444b1e13a0de73e847048a776e5ac5b3977c37f04167f9/application_properties-0.9.3-py3-none-any.whl", hash = "sha256:32dbd62b3fb657ec1c7fdc352590463c2ffd14950ffd258a5c091e8798d8aec0", size = 24595, upload-time = "2026-06-02T03:52:06.416Z" }, +] + [[package]] name = "appnope" version = "0.1.4" @@ -143,7 +171,7 @@ name = "cffi" version = "2.1.0" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "pycparser", marker = "implementation_name != 'PyPy'" }, + { name = "pycparser" }, ] sdist = { url = "https://files.pythonhosted.org/packages/57/5f/ff100cae70ebe9d8df1c01a00e510e45d9adb5c1fdda84791b199141de97/cffi-2.1.0.tar.gz", hash = "sha256:efc1cdd798b1aaf39b4610bba7aad28c9bea9b910f25c784ccf9ec1fa719d1f9", size = 531036, upload-time = "2026-07-06T21:34:30.382Z" } wheels = [ @@ -367,6 +395,19 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/d1/d6/3965ed04c63042e047cb6a3e6ed1a63a35087b6a609aa3a15ed8ac56c221/colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6", size = 25335, upload-time = "2022-10-25T02:36:20.889Z" }, ] +[[package]] +name = "columnar" +version = "1.4.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "toolz" }, + { name = "wcwidth" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/5e/0d/a0b2fd781050d29c9df64ac6df30b5f18b775724b79779f56fc5a8298fe9/Columnar-1.4.1.tar.gz", hash = "sha256:c3cb57273333b2ff9cfaafc86f09307419330c97faa88dcfe23df05e6fbb9c72", size = 11386, upload-time = "2021-12-27T21:58:56.123Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/06/00/a17a5657bf090b9dffdb310ac273c553a38f9252f60224da9fe62d9b60e9/Columnar-1.4.1-py3-none-any.whl", hash = "sha256:8efb692a7e6ca07dcc8f4ea889960421331a5dffa8e5af81f0a67ad8ea1fc798", size = 11845, upload-time = "2021-12-27T21:58:54.388Z" }, +] + [[package]] name = "comm" version = "0.2.3" @@ -526,11 +567,11 @@ wheels = [ [[package]] name = "fastjsonschema" -version = "2.22.0" +version = "2.22.1" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/f1/11/c802f752919c1fd83d44b3b955c6e7120c79f355d4a448c358198a11178c/fastjsonschema-2.22.0.tar.gz", hash = "sha256:6eb12e8f9900db6166c3d396d178ebdf6a4215fe22a06e19792edd612a20035a", size = 382291, upload-time = "2026-07-25T20:32:35.561Z" } +sdist = { url = "https://files.pythonhosted.org/packages/e4/98/474719c58eddaf77fa443b063693e76d49db32bbe851bcbaf58d2700119f/fastjsonschema-2.22.1.tar.gz", hash = "sha256:0b83d1ce8d7845b959dcb20e1a5c3c8883b6541d9c52ab02cce5166b75ec805f", size = 382291, upload-time = "2026-07-27T13:31:08.515Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/a4/9d/4a0f9355ca3e540b2d22d5f269212e2f227b8f277835b02d8908355245d1/fastjsonschema-2.22.0-py3-none-any.whl", hash = "sha256:60f4c92fda6f93efe3b3261638836478e1e11abc01c647e36e478199f7a86a37", size = 26248, upload-time = "2026-07-25T20:32:33.616Z" }, + { url = "https://files.pythonhosted.org/packages/17/e1/62cc96341f01bdff2ba967441939178fcd1900d11ce7e6554d9954a5d7ec/fastjsonschema-2.22.1-py3-none-any.whl", hash = "sha256:cf377ff5c9a6f4f3125fb35f75a2c5767bd824ffbcf62c209a93cd48d1453999", size = 26239, upload-time = "2026-07-27T13:31:03.251Z" }, ] [[package]] @@ -1407,7 +1448,7 @@ name = "pexpect" version = "4.9.0" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "ptyprocess", marker = "sys_platform != 'emscripten' and sys_platform != 'win32'" }, + { name = "ptyprocess" }, ] sdist = { url = "https://files.pythonhosted.org/packages/42/92/cc564bf6381ff43ce1f4d06852fc19a2f11d180f23dc32d9588bee2f149d/pexpect-4.9.0.tar.gz", hash = "sha256:ee7d41123f3c9911050ea2c2dac107568dc43b2d3b0c7557a33212c398ead30f", size = 166450, upload-time = "2023-11-25T09:07:26.339Z" } wheels = [ @@ -1452,6 +1493,7 @@ dev = [ { name = "mypy" }, { name = "numpy" }, { name = "pre-commit" }, + { name = "pymarkdownlnt" }, { name = "pytest" }, { name = "pytest-cov" }, { name = "reuse", extra = ["chardet", "charset-normalizer"] }, @@ -1479,6 +1521,7 @@ lint = [ { name = "mypy" }, { name = "numpy" }, { name = "pre-commit" }, + { name = "pymarkdownlnt" }, { name = "reuse", extra = ["chardet", "charset-normalizer"] }, { name = "ruff" }, ] @@ -1504,6 +1547,7 @@ dev = [ { name = "mypy" }, { name = "numpy" }, { name = "pre-commit" }, + { name = "pymarkdownlnt" }, { name = "pytest" }, { name = "pytest-cov" }, { name = "reuse", extras = ["charset-normalizer", "chardet"] }, @@ -1529,6 +1573,7 @@ lint = [ { name = "mypy" }, { name = "numpy" }, { name = "pre-commit" }, + { name = "pymarkdownlnt" }, { name = "reuse", extras = ["charset-normalizer", "chardet"] }, { name = "ruff" }, ] @@ -1612,6 +1657,18 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/8e/37/efad0257dc6e593a18957422533ff0f87ede7c9c6ea010a2177d738fb82f/pure_eval-0.2.3-py3-none-any.whl", hash = "sha256:1db8e35b67b3d218d818ae653e27f06c3aa420901fa7b081ca98cbedc874e0d0", size = 11842, upload-time = "2024-07-21T12:58:20.04Z" }, ] +[[package]] +name = "py-walk" +version = "0.3.3" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "sly" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/b3/b5/e2f3fab1e11d4089b1c3dfd72175fdb2408ff8028e01bdb0d308923609bb/py_walk-0.3.3.tar.gz", hash = "sha256:a1b28d6079f27203fa3098b69a98572675b3ff5bd02286c43e6dacd66615f879", size = 1815727, upload-time = "2024-10-26T14:30:39.421Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/27/38/56b67abdbf6797475dfe2f62d391b4a6ead851c76acbaf07e118e53651b6/py_walk-0.3.3-py3-none-any.whl", hash = "sha256:238fc018165138021ce0bfd9c351cdc473d3120ccc5534df35611b92608c94d5", size = 14537, upload-time = "2024-10-26T14:30:38.06Z" }, +] + [[package]] name = "pycparser" version = "3.0" @@ -1630,6 +1687,114 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/f4/7e/a72dd26f3b0f4f2bf1dd8923c85f7ceb43172af56d63c7383eb62b332364/pygments-2.20.0-py3-none-any.whl", hash = "sha256:81a9e26dd42fd28a23a2d169d86d7ac03b46e2f8b59ed4698fb4785f946d0176", size = 1231151, upload-time = "2026-03-29T13:29:30.038Z" }, ] +[[package]] +name = "pyjson5" +version = "2.0.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/f1/9a/3db19560e968d6e85b2a4ddf4b949c6ebf9dd1dcfb5a9f37736f8adeb927/pyjson5-2.0.1.tar.gz", hash = "sha256:a5b0e322e847b198a50d8a1ef16d6b2b19129644dc018d76773e81ef1487ca39", size = 352242, upload-time = "2026-05-15T16:12:54.931Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/68/41/be622b742fe4749fefa9d8a923b1cf5e51a1e8e4b4930fa8ea8c531b243d/pyjson5-2.0.1-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:ee62394660d54e76ff8a968c8194b252be23d184f05a00238d4def9624454ea6", size = 302636, upload-time = "2026-05-15T16:06:08.006Z" }, + { url = "https://files.pythonhosted.org/packages/4b/e2/50378c3bec9164c1bb983ca15ed59f8be498981b790a90d1410a1016ffe2/pyjson5-2.0.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:58dfa4cf5c327e14c530b16c23e812c021fe53b19e6f9cdfce257d8c02244895", size = 158588, upload-time = "2026-05-15T16:06:09.684Z" }, + { url = "https://files.pythonhosted.org/packages/cb/7d/5de0f82c144b6fc2fa2e3fde5517257733a91d24734b5d2415b7e991e8fd/pyjson5-2.0.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:07cb90a31f962a6de9e49592a306046ee015da73510c6d215e9481a2a21c9ac2", size = 153741, upload-time = "2026-05-15T16:06:11.114Z" }, + { url = "https://files.pythonhosted.org/packages/f5/ac/174ca02e5f3ed8245dc48247e534880bbec1528c0c4eaa768fafa9417dda/pyjson5-2.0.1-cp312-cp312-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:ef4026a90a68cd2bcb64d89ca064a1615b60a61c7694714e2b8ef30434f365b5", size = 185450, upload-time = "2026-05-15T16:06:12.883Z" }, + { url = "https://files.pythonhosted.org/packages/8f/0d/bfc553176b7e109b72f23697ab1fd1a77d7fd5c6626d6e23936f13d5884e/pyjson5-2.0.1-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:04b4929a7adf0e0720da92ac54c92d408e8057158be3ccc34da17c7767a9af78", size = 163331, upload-time = "2026-05-15T16:06:14.314Z" }, + { url = "https://files.pythonhosted.org/packages/b3/05/b0e67106f78c8ea5ffcf6ce0b8421f38a04d5f37ea88ac70123199755bcb/pyjson5-2.0.1-cp312-cp312-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:e889b039d6bffda9a6b8d822073bbdb4a60166af22f075e7faa0c03c2dfcf17b", size = 166429, upload-time = "2026-05-15T16:06:16.076Z" }, + { url = "https://files.pythonhosted.org/packages/81/3c/2366f8ecf053434470eafe1f120f2e235d13015fc50d7f06e55e39b550ab/pyjson5-2.0.1-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:a08e99d0a33463728fb016f5eec680504499c4be280dac016de2da70ec55b0db", size = 180499, upload-time = "2026-05-15T16:06:17.544Z" }, + { url = "https://files.pythonhosted.org/packages/76/65/9a70876d4dd09ce17678024266406b94b8f1edf9db6c2e3bf76cfa653a13/pyjson5-2.0.1-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:035c094feb6a9d4312183f9f34228d976102eefb971e9e3dd972d8c7900a466a", size = 187469, upload-time = "2026-05-15T16:06:19.212Z" }, + { url = "https://files.pythonhosted.org/packages/5b/43/0c0bcbf9a9ef7fdcd49dc0992a3a206244c2c2baa7b409932464cf26f1a5/pyjson5-2.0.1-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:6d178025a5317db44663dc87aab90f34674991b3da40dbedc3c108e7b03b6466", size = 176032, upload-time = "2026-05-15T16:06:21.153Z" }, + { url = "https://files.pythonhosted.org/packages/82/2c/32213674010c44db265d45e977a431cbde971c45342b483f7af337811403/pyjson5-2.0.1-cp312-cp312-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:381ca5b3172bccf9c29c5823a0173ab9118d579d0f5bb4fca20b803daa6e72d5", size = 171477, upload-time = "2026-05-15T16:06:23.017Z" }, + { url = "https://files.pythonhosted.org/packages/f1/49/da5417d592ac75a23d1ca2dfda846391ccf137edd89054b780866c592b65/pyjson5-2.0.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:8e158caf0dd7fbf7afe12f92fcc9cba26bceac4b38615c087fd592e9e3240d9f", size = 1145571, upload-time = "2026-05-15T16:06:24.757Z" }, + { url = "https://files.pythonhosted.org/packages/60/f8/1f0c326b3a3267f28b7b9e2ac07121386ec20ee8f9dd49955af4faa17ba7/pyjson5-2.0.1-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:c8010e9a02b6a0719234f8d074639f9051afe579ff0f74d3367af1d8b4c7d839", size = 1010388, upload-time = "2026-05-15T16:06:26.574Z" }, + { url = "https://files.pythonhosted.org/packages/de/c8/76f2739a8715061755f12f4d2795f6c4079aeadd166c56d0992521442d5b/pyjson5-2.0.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:3543e067d1d8ab6cb1cd41add38a42eaf82e9a7e802e8a08f1acda9f22199b00", size = 1323111, upload-time = "2026-05-15T16:06:28.805Z" }, + { url = "https://files.pythonhosted.org/packages/50/7a/683e1586fa076fb344aec23a647d67f427847b6bffb1001d56e86aa8da33/pyjson5-2.0.1-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:3e496938e7e0defc33bfbd0ff581d4ffdc428c598cc5d679232f34df27f7330a", size = 1240671, upload-time = "2026-05-15T16:06:30.473Z" }, + { url = "https://files.pythonhosted.org/packages/c0/8e/6638b0b22344b23cae1271b0211668be54b3f76183bd8d4f89a2edd8e562/pyjson5-2.0.1-cp312-cp312-musllinux_1_2_riscv64.whl", hash = "sha256:2badbc101908123905a38789cc552b99ab896a7ec0ce4fa6ee2bb7b613c85c1b", size = 1178013, upload-time = "2026-05-15T16:06:32.212Z" }, + { url = "https://files.pythonhosted.org/packages/7a/21/d44540d3cdc670e5c6e665471361f557ef8c7d56964cd433524208b3707b/pyjson5-2.0.1-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:b1b0df4898e2e046fa1e9b5df436fe11d9b681b1e5fc9877508d982d2059aaf1", size = 1354907, upload-time = "2026-05-15T16:06:33.922Z" }, + { url = "https://files.pythonhosted.org/packages/3c/74/fceedd2709760f5c85e75b508002af9b4c2da8af20a80e62b2d0e2358a15/pyjson5-2.0.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:8fcc96c429888f2293f672e33d01da8a0847cd5116a773c9a1903b8bc2f12bc1", size = 1208847, upload-time = "2026-05-15T16:06:35.883Z" }, + { url = "https://files.pythonhosted.org/packages/b8/3a/d2f062b5801b3034ecb16ffb0801d7b4a1d6abae4cd4615482dbf62f1ed8/pyjson5-2.0.1-cp312-cp312-win32.whl", hash = "sha256:48c97e2f7f02171948f8a7ed6c9b2b2faea00653a3348d9e810238a688f07b6c", size = 115562, upload-time = "2026-05-15T16:09:24.807Z" }, + { url = "https://files.pythonhosted.org/packages/26/13/2265cf16720defdc87672b68ff5edf83820bd76e59e32f8384c9cb1ae619/pyjson5-2.0.1-cp312-cp312-win_amd64.whl", hash = "sha256:8dea9976eea0aa7af8b5ad49df3fa831d6bda08ffd7bb11409d6a81961491219", size = 136176, upload-time = "2026-05-15T16:09:25.931Z" }, + { url = "https://files.pythonhosted.org/packages/9c/92/a8947e646ce642555ac22b31f44b7168c81b0e364d0f2711d571955229b6/pyjson5-2.0.1-cp312-cp312-win_arm64.whl", hash = "sha256:264ab65fb7d68a763567c2302151f1f074bf053c8479939aa8e75f5f9518fe31", size = 116752, upload-time = "2026-05-15T16:09:27.274Z" }, + { url = "https://files.pythonhosted.org/packages/93/2c/0619f89a9576f335ba63eb851e73ba507480a8c7f28a2e7de2501ed3d303/pyjson5-2.0.1-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:8a661d292801b38434d5288bf7329f9b50b3a693b1d2941c7595175842692eba", size = 301821, upload-time = "2026-05-15T16:09:28.721Z" }, + { url = "https://files.pythonhosted.org/packages/91/31/7824913ec71e7421d6a57bc06228f3e2d946d8e8f738f898572dded0dc57/pyjson5-2.0.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:1cb5c1c066038ce6e1922d9d5be23f5cd14d5b5a3c96e6358aa5d0e379014a93", size = 158201, upload-time = "2026-05-15T16:09:30.261Z" }, + { url = "https://files.pythonhosted.org/packages/bc/7d/4ddb249563a838425242342d2cf67976ccc292a831b543a92fa1a8a83b11/pyjson5-2.0.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:7417eab751817fa5f070e41975d9df4aec3532d21389073318161f63cd96d636", size = 153244, upload-time = "2026-05-15T16:09:32.04Z" }, + { url = "https://files.pythonhosted.org/packages/02/39/7622416ac0570d9ce377447bd5b2ec9383c1282e63cc6d0b65779f1336fa/pyjson5-2.0.1-cp313-cp313-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:cc4802093b4ab9039367774988486fd04754cf416c32aebf94a94bafd8b8a478", size = 185568, upload-time = "2026-05-15T16:09:33.719Z" }, + { url = "https://files.pythonhosted.org/packages/d8/90/2f317da231477b77481020d79c73bbe10625e4925ceeae77603726ef1763/pyjson5-2.0.1-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:bc3181274ed19ecb2315cf85a499bf83002554f42c72453666c616059d665a7b", size = 163169, upload-time = "2026-05-15T16:09:34.865Z" }, + { url = "https://files.pythonhosted.org/packages/02/b3/20023c3cfe2f2c2523007d7031b5b7ad7ccd8856d2665547683cebaa6f8e/pyjson5-2.0.1-cp313-cp313-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:5398306b8aa253e620af9ed8085767de9cd28d6846da45e535e80fcffa9f33d7", size = 166514, upload-time = "2026-05-15T16:09:36.383Z" }, + { url = "https://files.pythonhosted.org/packages/e2/1c/b863e502153477b2845a54b688b72436457aca5107b300fca95e98184551/pyjson5-2.0.1-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:b97b592287d52a6ec5af84dca94aab02b185f72f8ddb6fc99c58efb8891be5cd", size = 179907, upload-time = "2026-05-15T16:09:38.166Z" }, + { url = "https://files.pythonhosted.org/packages/fc/b2/413fcb76632e5f6fa89a2ec83976755b5bb4696c6d9eca9ff3c70cd717b6/pyjson5-2.0.1-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:4efbf5e910a3aa6f330a92d1ae940dda5ed662976ed5056526baaf2e1821f95d", size = 187171, upload-time = "2026-05-15T16:09:39.624Z" }, + { url = "https://files.pythonhosted.org/packages/d6/11/66151b819407ab589aef36582038257f1ef42dc065e3423b3d8274f4fcd2/pyjson5-2.0.1-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:0e042f9b869e7f21d5f53a2638e5d0cf1daaba2342127c8777c502daf972602e", size = 175564, upload-time = "2026-05-15T16:09:41.356Z" }, + { url = "https://files.pythonhosted.org/packages/f2/98/deb70690dab994474ea527cba91f43ae55928bcff498c441e812b60fc1e2/pyjson5-2.0.1-cp313-cp313-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:26074370d7a6dd38b6e8c28a2f10c790fc6dec938ec22ec3de6c93c97d195f10", size = 171530, upload-time = "2026-05-15T16:09:42.78Z" }, + { url = "https://files.pythonhosted.org/packages/a9/be/969752a3a052d00698b6e1dd926c627d7a6475a7c8dd390db148363544f8/pyjson5-2.0.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:3cb163a495096716a7a01d052b60bda0308ecfaeddcb2d50a247ba9d707e3e40", size = 1145510, upload-time = "2026-05-15T16:09:45.005Z" }, + { url = "https://files.pythonhosted.org/packages/d0/be/4c5c92cdda5a911ee4450a74281782335e7ce6715638308322beb96be639/pyjson5-2.0.1-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:5fdd66bdddc2d53421ab7427bedcd2ca9b2f1b4b3b464381aa60d305c94be38c", size = 1010114, upload-time = "2026-05-15T16:09:47.081Z" }, + { url = "https://files.pythonhosted.org/packages/89/1e/72283bc505d77dcdab7eaeb0020cf0fd79a05d2991e886d1fcfa73e88ae1/pyjson5-2.0.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:4ad222a3eff1cc93f9b70894c5f3d2ff5e46531e88feaa4818e329d5f3ae4307", size = 1322915, upload-time = "2026-05-15T16:09:48.885Z" }, + { url = "https://files.pythonhosted.org/packages/06/b4/94a09e744a6bb6e76108b61a28a7cc5ecab1b8105cacde7548359b3b74a3/pyjson5-2.0.1-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:63f5cf25113dd1bf3bfeda211d99413e58ec6b9036ff34f7b69f85f23695e9c4", size = 1240126, upload-time = "2026-05-15T16:09:50.638Z" }, + { url = "https://files.pythonhosted.org/packages/af/29/4549380cae425ee112f3c154606c35f5211c12ddf415f079c2b23f2d493b/pyjson5-2.0.1-cp313-cp313-musllinux_1_2_riscv64.whl", hash = "sha256:b0001eecce9080e6c170e978786501e8931e2075a3d15f5260e1bdd6a45e8976", size = 1178022, upload-time = "2026-05-15T16:09:52.639Z" }, + { url = "https://files.pythonhosted.org/packages/1c/1a/5a8a869e855645858e45dbd077204cec3a85b2f2e669bc3c8cefe9c4a70e/pyjson5-2.0.1-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:40371c73cc83ed81914028786a6cc5950bdf300ae82443df83a5dfa80c582fca", size = 1355161, upload-time = "2026-05-15T16:09:55.177Z" }, + { url = "https://files.pythonhosted.org/packages/82/32/827066cd946447648275a892f494f4572d78e6a79d877fa6b6c14af599d8/pyjson5-2.0.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:c9dca542eeb6e8fbbc1fe3373bfd18ae6250f1aedc78f39242ac12c8837091b8", size = 1208864, upload-time = "2026-05-15T16:09:56.919Z" }, + { url = "https://files.pythonhosted.org/packages/2d/cc/a9bc12aff47d8bfd3074a21e3fb056ec0028fac28f8ec7e0fe4449d050f5/pyjson5-2.0.1-cp313-cp313-win32.whl", hash = "sha256:d30c8b2c91d530be475a8fab6dde8c3bcd3e89b999c9e0f05aec2bf2c24b0638", size = 115461, upload-time = "2026-05-15T16:10:30.711Z" }, + { url = "https://files.pythonhosted.org/packages/c9/c7/fa3fc956fbc3fa6250c8b99ef75a8f52b691780fca1bfb368340283bd898/pyjson5-2.0.1-cp313-cp313-win_amd64.whl", hash = "sha256:67f8f5b8d3e3b2ca5f618c928729986aa00fb588c476c0d0d3a151633ff41e0d", size = 135836, upload-time = "2026-05-15T16:10:32.062Z" }, + { url = "https://files.pythonhosted.org/packages/f0/0a/e457b20d1e36a766d3ccd09c418b7ef41acabb679ff2248bb1cd38247ce6/pyjson5-2.0.1-cp313-cp313-win_arm64.whl", hash = "sha256:bdf30ce5b1242f63254d936b30af75cae237fab0ee71cc2544163c82b6bc9201", size = 116652, upload-time = "2026-05-15T16:10:33.39Z" }, + { url = "https://files.pythonhosted.org/packages/2b/4c/6266789e615576b62d2db6de26a3b4b8f4cc7a8ff23fe24e48363bca1682/pyjson5-2.0.1-cp313-cp313t-macosx_10_13_universal2.whl", hash = "sha256:954c14d40022fa40e0d36e0ebd337e9e90fd71145592d25a0e2868344e3daca0", size = 320487, upload-time = "2026-05-15T16:09:58.38Z" }, + { url = "https://files.pythonhosted.org/packages/dc/75/c4a563034805e20b274fe4db963e1d480001931d88fe70b7d082033b7dcb/pyjson5-2.0.1-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:f57529b98d21e8b76f8bc51af9d3c3057dd04a92287fd21ef7ec55255ca6f5c5", size = 166879, upload-time = "2026-05-15T16:09:59.849Z" }, + { url = "https://files.pythonhosted.org/packages/f3/d2/5e6ec3580379794e9a99a402465f74586e93e93814974172202d1254fa89/pyjson5-2.0.1-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:545b655ef0b59f39fc29e2b63b4dadd45e447ad77bad2fdca859ff4db69e21f5", size = 162235, upload-time = "2026-05-15T16:10:01.147Z" }, + { url = "https://files.pythonhosted.org/packages/5b/48/b2d0e868ef8375eb0696ddc74f71028fc4fcd26cdddaeb34485214f2dc87/pyjson5-2.0.1-cp313-cp313t-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:b519de49dd4cbf254179749e5c6bfe9bd8fd1f97e7755bff2e17cc6f79f85aa5", size = 182162, upload-time = "2026-05-15T16:10:02.523Z" }, + { url = "https://files.pythonhosted.org/packages/ce/18/fed02a3d68c3badb87394e8420b72d7cb165ade208c1e02561637409aa99/pyjson5-2.0.1-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:de48fbd0466c114c17f408be7bcbc5b3aedeb29ff5f73187022915e6d5eb7817", size = 169487, upload-time = "2026-05-15T16:10:03.876Z" }, + { url = "https://files.pythonhosted.org/packages/8b/90/dc897332dda24e949828616e8e74d7937b587a56789f3aca148fcadddde2/pyjson5-2.0.1-cp313-cp313t-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:fe6516ff9ab94368c18ff8ac0ebdb53fac9e047da093d43e67d5e7cd98cdd0bf", size = 164128, upload-time = "2026-05-15T16:10:05.588Z" }, + { url = "https://files.pythonhosted.org/packages/39/09/90104baeab58adfe63bda804174ef1806b1cabb1692e047fabc2f4aa1799/pyjson5-2.0.1-cp313-cp313t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:ea7aadacac7ac6661117b708175f6beff75e132322c08bbf3794d8ec4ba572b4", size = 184306, upload-time = "2026-05-15T16:10:06.986Z" }, + { url = "https://files.pythonhosted.org/packages/89/73/613efc3cdab5cf9ec399e6c5a0463b672e5f5cbd693a3a4d82cbdda19476/pyjson5-2.0.1-cp313-cp313t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:e5c339bcac113dfc30a1f88f23af273d67bb6169abee1684c0dd27daa71a32f9", size = 192239, upload-time = "2026-05-15T16:10:08.727Z" }, + { url = "https://files.pythonhosted.org/packages/47/2a/17b97e02b37ab9353fc9713e56470be3d2539501ed18d6c676cfbcd0a57c/pyjson5-2.0.1-cp313-cp313t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:075de0f1e5e0ffee174a8941b5d9d8af632772a6e5eebe92fb0899db7f6ab7fa", size = 177652, upload-time = "2026-05-15T16:10:10.19Z" }, + { url = "https://files.pythonhosted.org/packages/1c/43/a05331ba88fd1aa09ca418548c6b06692e34b2a64b109bb363e01ecafdeb/pyjson5-2.0.1-cp313-cp313t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:c463c9bf508c1d316191898a3c0bfc03dd3de67bdc02f480b0742ac5c859eaeb", size = 174860, upload-time = "2026-05-15T16:10:11.976Z" }, + { url = "https://files.pythonhosted.org/packages/2e/00/5d253751f4d27b7e63fdfd765041593fa588395f45b9cea496878d964448/pyjson5-2.0.1-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:54427c8cad0c1a516bad5b4457167cde1e7ef7ee563e28a944f59b3c7413b6a0", size = 1151556, upload-time = "2026-05-15T16:10:13.608Z" }, + { url = "https://files.pythonhosted.org/packages/9c/f7/a30eed477295e92dfd59553063cf82bf510a7052efc7720c9c50d0082fdb/pyjson5-2.0.1-cp313-cp313t-musllinux_1_2_armv7l.whl", hash = "sha256:ca04839cecd364cb53de7ebcd81fd5915193707d968730ea1c8d4ff5c9c2f1a8", size = 1012330, upload-time = "2026-05-15T16:10:15.171Z" }, + { url = "https://files.pythonhosted.org/packages/9c/60/80818fad90a99336f8bfc686d76d0b2d7c8bb51e8de5d031620fa1a2d7a1/pyjson5-2.0.1-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:13a2de8b14aeb576b1623c8af419510bf871b8d9cc2308db41a46bcc94d00f2f", size = 1320970, upload-time = "2026-05-15T16:10:16.863Z" }, + { url = "https://files.pythonhosted.org/packages/7c/3f/090eb3e0971d067defb58bbfd738f74a09be495c6f4f00d5d76a10755bca/pyjson5-2.0.1-cp313-cp313t-musllinux_1_2_ppc64le.whl", hash = "sha256:c8a689f5252e9791bfbc8fa916999202556a1e8c7b24dfd72de1ad84c493e10a", size = 1244775, upload-time = "2026-05-15T16:10:19.416Z" }, + { url = "https://files.pythonhosted.org/packages/61/38/e7546ad733affe51a5462bad21bceb4fd659baf24930bd141627ce56279b/pyjson5-2.0.1-cp313-cp313t-musllinux_1_2_riscv64.whl", hash = "sha256:3dc0c2c80fd9d1e4c26f8b6c91a54d38b48648b93ae3f09355856c75fda3e460", size = 1182149, upload-time = "2026-05-15T16:10:21.696Z" }, + { url = "https://files.pythonhosted.org/packages/90/2c/016647580d8a82ee53b4cb9ddb96deb4b157ccea9624bba61de4aa2cd25c/pyjson5-2.0.1-cp313-cp313t-musllinux_1_2_s390x.whl", hash = "sha256:13d78b3e2c60b81bd7e6b00e6ab24a664ba1fd64b5d86baa65c4cdfae1fff7ae", size = 1358579, upload-time = "2026-05-15T16:10:23.649Z" }, + { url = "https://files.pythonhosted.org/packages/01/45/8b84ff7a0c4d8c12a76e097c67af62abe986a18d1ab2540764dd6eaa0253/pyjson5-2.0.1-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:a7b640dbeabbd7d975170f793f90a7500cc5d510aeae9364a1bc558bcc5336ed", size = 1211015, upload-time = "2026-05-15T16:10:25.4Z" }, + { url = "https://files.pythonhosted.org/packages/cf/48/d8f34de7a7319f5966bdfd10f133e689ba01f138d2040bf792f1ca8b18e1/pyjson5-2.0.1-cp313-cp313t-win32.whl", hash = "sha256:46e7c5525034fde8abf3aaf100ed7660c1b618ccd3205544ed7c99e4c55cf201", size = 131660, upload-time = "2026-05-15T16:10:26.747Z" }, + { url = "https://files.pythonhosted.org/packages/06/aa/0bd437252134115a846ffc061078c85f8e8c325c86abcaa862c134d3c57e/pyjson5-2.0.1-cp313-cp313t-win_amd64.whl", hash = "sha256:207c00e7f9641e0358bdc848a1c0610f26f2e8bd51d73bd64e5a0ab3b725f1d8", size = 157717, upload-time = "2026-05-15T16:10:28.053Z" }, + { url = "https://files.pythonhosted.org/packages/24/61/7849b04a0dc78f73905189400ac99c45de8eec2ec451ce9c6990fb3588e5/pyjson5-2.0.1-cp313-cp313t-win_arm64.whl", hash = "sha256:4917d5b6186bfa48ec4d85326e2a09769a5f7844963307ab2710429e1f743264", size = 126281, upload-time = "2026-05-15T16:10:29.378Z" }, + { url = "https://files.pythonhosted.org/packages/89/41/70aa1cb1fb0a3ac4c9b8cd405c0c85ba935c53fdfae6271b8eae364b92d1/pyjson5-2.0.1-cp314-cp314-macosx_10_15_universal2.whl", hash = "sha256:573fecd7cad4e24d232053f9ebf331c80fe1b0ed6e2064f7614797a7f691e7ca", size = 303706, upload-time = "2026-05-15T16:10:35.163Z" }, + { url = "https://files.pythonhosted.org/packages/0c/d9/caf44bf3d33b9502dc4b8ed5d0c7a8af8fbe33001e82414c0407f39f18bd/pyjson5-2.0.1-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:a8ade508a046a5407a322c098e3b7e6033216b158a7746eb8962b7a4cdbf9248", size = 158915, upload-time = "2026-05-15T16:10:36.496Z" }, + { url = "https://files.pythonhosted.org/packages/3f/94/f2bab1ce2eac8f77e16dcd0a1ba39de20733a84b9961c3504af0dd68bceb/pyjson5-2.0.1-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:4635e349bb1d1f1e854dc790f14be31b6cb198d6453848e8d86818104074f805", size = 154199, upload-time = "2026-05-15T16:10:37.902Z" }, + { url = "https://files.pythonhosted.org/packages/82/c4/d94573ca37486af3d6a72f2582844d7d490d8e55639e0cfba371ce91442f/pyjson5-2.0.1-cp314-cp314-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:3d274697f81f143abac12ce256a06b61635c30d0f8cc11eefae7182655dac9a5", size = 186060, upload-time = "2026-05-15T16:10:39.603Z" }, + { url = "https://files.pythonhosted.org/packages/03/cc/c42e697def319b286fdcb912939c044cc94bd1cfc7338b6dbb566f817f29/pyjson5-2.0.1-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:be4e2242e55a2651fd8696cfd67ec8e04f54f4ed6c089cceea2b63763a7516d8", size = 165796, upload-time = "2026-05-15T16:10:40.967Z" }, + { url = "https://files.pythonhosted.org/packages/3f/dd/f22a5f0e619ef22b8e32520a91bd92f815d50f9ec2d67cfe5974eab9476c/pyjson5-2.0.1-cp314-cp314-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:af855c680feaa39cae4a44914ee2863eeae1549f37ce58069c747b3d4803999a", size = 165262, upload-time = "2026-05-15T16:10:42.391Z" }, + { url = "https://files.pythonhosted.org/packages/99/8b/90e22ecb12d51ccdc68325b6b051002e6103cc4600a335d9ed13828acdd9/pyjson5-2.0.1-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:bb769d90516da904e6cf0ba58f3d5830f4a5804486b5e85c5ca42ba3146d187a", size = 181608, upload-time = "2026-05-15T16:10:43.914Z" }, + { url = "https://files.pythonhosted.org/packages/e0/ab/237f9036eed73e08cf8861466d3d1182ef1c88506bd29955740dcadb24ff/pyjson5-2.0.1-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:6484c14e07aa46abeb3cb2ff0204a765260763ad7cf3f87f601f26b20ed607f3", size = 189582, upload-time = "2026-05-15T16:10:45.367Z" }, + { url = "https://files.pythonhosted.org/packages/c4/3d/3df8d5f003910a9291e5f04fa178f626e3c8553a5986dc62589ca74195ff/pyjson5-2.0.1-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:cc03673adb544324500d79b2acfe2ced038998b2aceb564d335de9cc238cbdb0", size = 176321, upload-time = "2026-05-15T16:10:47.134Z" }, + { url = "https://files.pythonhosted.org/packages/c0/d9/a458a54f780bafec1b44ee3c27cb3007a83fb7bd4f1c17ac6bf519fd6151/pyjson5-2.0.1-cp314-cp314-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:5d714daf784bec2e14fc06c0c26e4a373a6157eaeddaed2d5a7b7b6ae2aabc33", size = 171956, upload-time = "2026-05-15T16:10:49.174Z" }, + { url = "https://files.pythonhosted.org/packages/78/d8/1010e0147c8862dc0881cf3656364d3d87a5e336d290fe4cb0b92223e14c/pyjson5-2.0.1-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:5cf3ded356730e08b5941a16db6525efc0de26f35468ab09ad573056c4efc6e5", size = 1147679, upload-time = "2026-05-15T16:10:51.005Z" }, + { url = "https://files.pythonhosted.org/packages/19/2f/91c8d8cdb4a2e4bbe8f14b9b57d717988e14830f2ed4a4f08d503cb5edde/pyjson5-2.0.1-cp314-cp314-musllinux_1_2_armv7l.whl", hash = "sha256:cc00d4669fb4170c28b2c9ed3cd1c2af9f21727c55d6866030cc154f31f68747", size = 1008216, upload-time = "2026-05-15T16:10:53.252Z" }, + { url = "https://files.pythonhosted.org/packages/d7/d7/25c3f8693660a35be7bb4eb71b0d10d9a6981e986723a4881d607f0c6462/pyjson5-2.0.1-cp314-cp314-musllinux_1_2_i686.whl", hash = "sha256:a77a91c2e019476345c03cde105da44100daaabc3fa56f82f2bd9eb2ebbcb698", size = 1323856, upload-time = "2026-05-15T16:10:55.517Z" }, + { url = "https://files.pythonhosted.org/packages/c8/25/82f0f83556ff68ec0ca1129ba9afeb14149cd421dc74823cdf10c209c95c/pyjson5-2.0.1-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:9ae54e5d717982cb7a082c700ab1f7f965c6aedea6fcb003ec4bdeac4f02bf52", size = 1241860, upload-time = "2026-05-15T16:10:57.635Z" }, + { url = "https://files.pythonhosted.org/packages/c1/01/2c4695fc06a0f3f29041a875d3bb24f904c9ae7b3d8dbfa1f8db17ce995c/pyjson5-2.0.1-cp314-cp314-musllinux_1_2_riscv64.whl", hash = "sha256:ce4f5b67b3a6fab623a31d83416b51a5b2c97cb172194f214078484bbb4783a6", size = 1178443, upload-time = "2026-05-15T16:10:59.398Z" }, + { url = "https://files.pythonhosted.org/packages/9a/ae/c10f534037b096aca21b90017ac9d41f791572dc3ec31fcd92db8ddcd256/pyjson5-2.0.1-cp314-cp314-musllinux_1_2_s390x.whl", hash = "sha256:f8d2e61f7bed0b40cfe5f62375581bf56d7b5b9707c9d74747b5931149d7d376", size = 1357739, upload-time = "2026-05-15T16:11:01.189Z" }, + { url = "https://files.pythonhosted.org/packages/0c/f0/655224f78ede087aa6a295c4745423e0104dd31f67928675b1a4cea72a0a/pyjson5-2.0.1-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:2930140edd1a64eb42689993c5ae317bca2e6bc785b5dc5053bd5e9d184c98ad", size = 1209542, upload-time = "2026-05-15T16:11:03.364Z" }, + { url = "https://files.pythonhosted.org/packages/73/52/a7b2a26625136fcd0f92e17beaaae51e04923cc2e28502db354d4de061b4/pyjson5-2.0.1-cp314-cp314-win32.whl", hash = "sha256:51733f91dda897239ca10928f363ce6f4b5eadaf797e74477f6c1c3222c185a7", size = 118342, upload-time = "2026-05-15T16:11:40.009Z" }, + { url = "https://files.pythonhosted.org/packages/3a/8e/79db426fff3a41610076989d4060cc18a6508ebd3c7877155f6709eea102/pyjson5-2.0.1-cp314-cp314-win_amd64.whl", hash = "sha256:698c73aacff49ea35bbbf7f700a97785626201ea7aa2e1f1e0a4fe23788c3be2", size = 138408, upload-time = "2026-05-15T16:11:41.757Z" }, + { url = "https://files.pythonhosted.org/packages/c7/1b/385da14c05412bca15e86551dde91959686c8bddf7e78722bdc627fa6815/pyjson5-2.0.1-cp314-cp314-win_arm64.whl", hash = "sha256:d447e2e5756f89abfd0ad82d1438075bcbc701c1cc9279b43d24825aaac67356", size = 120905, upload-time = "2026-05-15T16:11:43.146Z" }, + { url = "https://files.pythonhosted.org/packages/dd/04/cd69739556d304d3ea48064ea7d47e5ff7321b0032d7ad78864bceaa0cae/pyjson5-2.0.1-cp314-cp314t-macosx_10_15_universal2.whl", hash = "sha256:5603be4f0cb9685d7c2cbd408ddec21b33f415252bee00ac7969f20b5789a1d1", size = 321150, upload-time = "2026-05-15T16:11:05.07Z" }, + { url = "https://files.pythonhosted.org/packages/84/d4/6d98268ed07a2cac1e79634fcd3dc280d2503ade5f3c465f7aa095951444/pyjson5-2.0.1-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:87267520a256b3f2dba7f2995b745e8b3f2dd72bbf8436010a5191f7809f8ab6", size = 167540, upload-time = "2026-05-15T16:11:06.822Z" }, + { url = "https://files.pythonhosted.org/packages/c8/c6/8855a9462bdbc8306cba62793e23cc2952dfcbcbcab8e0413f570c891361/pyjson5-2.0.1-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:77e58307b74019d90aff9f2781bcffbbea3315b15fc814f8fa9b8d334b956ff4", size = 162533, upload-time = "2026-05-15T16:11:08.218Z" }, + { url = "https://files.pythonhosted.org/packages/a6/a3/1092f68538ee71ed8027393ab5e71aa9c4a114e493e30a55e46e34c2ffb9/pyjson5-2.0.1-cp314-cp314t-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:dd1712038837342dea73ed526883e53c6e85a158242b6f574b9ad9cdd3199c7f", size = 184165, upload-time = "2026-05-15T16:11:09.639Z" }, + { url = "https://files.pythonhosted.org/packages/46/63/bb9f42a4047284ea59064c134c88dfac3b7f5273e40fe548d6a086cea452/pyjson5-2.0.1-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:1dba36677c77aed5d680827c65478933705ca156a34838f1250ea191ffc27662", size = 170075, upload-time = "2026-05-15T16:11:11.105Z" }, + { url = "https://files.pythonhosted.org/packages/55/2a/0379aa5184e986d0f9af2919712c148d81928ce7d2d7950407e271b1df3b/pyjson5-2.0.1-cp314-cp314t-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:04356d0c09e58907f60675d33859f269473479b90add5026231ef2fadba5207e", size = 164100, upload-time = "2026-05-15T16:11:12.909Z" }, + { url = "https://files.pythonhosted.org/packages/15/d5/2087af69695c28c7fe796afc73dec7f0b0b9bc123ec329e45928d58d4705/pyjson5-2.0.1-cp314-cp314t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:b331a0fbe2ae26f4ccb88045ebaecc00aeeeab23ff858f9a2223cedd969ec6d6", size = 184674, upload-time = "2026-05-15T16:11:14.448Z" }, + { url = "https://files.pythonhosted.org/packages/2a/06/cf1b2744e07f1689cb0ac663e162a060b81cd358474754fe9f3bf02d5398/pyjson5-2.0.1-cp314-cp314t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:5ca55878d923ba5764254ad1c020c22b33e6161b3555d1f457b8060f2b3c6c17", size = 193047, upload-time = "2026-05-15T16:11:15.969Z" }, + { url = "https://files.pythonhosted.org/packages/54/e6/a6b0deb6a3f393907c6d9115a7ac8e27557109204b56b05d3b57c51fc2ca/pyjson5-2.0.1-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:35e18d11e4c2034b78a664affe18c153a8efbf8872cf6bed7f12dc4fb819d440", size = 178712, upload-time = "2026-05-15T16:11:17.364Z" }, + { url = "https://files.pythonhosted.org/packages/6e/48/9e5c16daba56dfdb481baab85d1197e14ae3f403902fc23cdca14d14351b/pyjson5-2.0.1-cp314-cp314t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:b710a7489b6e134890eaa1fdb285e9644a1e730c1cfcf1cd90a87859b87a84a9", size = 175642, upload-time = "2026-05-15T16:11:18.781Z" }, + { url = "https://files.pythonhosted.org/packages/c3/32/f07d4dbd8cf733f9e3f3e9c9abedfbc23da1e5cfa7fed46aebae07ca6f25/pyjson5-2.0.1-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:08920c0dd6aba3fb6bc6c849e6f05731c5fb2716cd651de424ff60cdd12eae65", size = 1152219, upload-time = "2026-05-15T16:11:20.54Z" }, + { url = "https://files.pythonhosted.org/packages/01/9d/0ddbb89d381bc27f3740850d5d664c1f6f76620ad879ff5eb2506a4dfd6c/pyjson5-2.0.1-cp314-cp314t-musllinux_1_2_armv7l.whl", hash = "sha256:e166dadb3275025cff5ee8602131372a3ea171c6727b3fc6e44697348e3972c5", size = 1013305, upload-time = "2026-05-15T16:11:22.702Z" }, + { url = "https://files.pythonhosted.org/packages/bb/93/0f44886391dd2249ad9cf98c2deb3f26d1a115dd5a215629af7455765968/pyjson5-2.0.1-cp314-cp314t-musllinux_1_2_i686.whl", hash = "sha256:ea3c2b4e7b8e209e7f59bd6a925d79b69cd0a4ffa12f2df0c6af55514c8b2227", size = 1322840, upload-time = "2026-05-15T16:11:24.918Z" }, + { url = "https://files.pythonhosted.org/packages/d4/29/c478dc24dfcfc07e407ff8669df265ecc51fed5e7d47e51a01f17fd1c53f/pyjson5-2.0.1-cp314-cp314t-musllinux_1_2_ppc64le.whl", hash = "sha256:b710fc8ce00c984c8865131f05a8536163e1d3caffb9d081647879eca7424670", size = 1245221, upload-time = "2026-05-15T16:11:26.873Z" }, + { url = "https://files.pythonhosted.org/packages/e2/f0/5fef8c47c5b7052da79af6425a021040402a9a09b37c5687d91f98696a27/pyjson5-2.0.1-cp314-cp314t-musllinux_1_2_riscv64.whl", hash = "sha256:a9784d79275d1b06d95f2920c3f260ce5d3f6671f65a1fae1464f83fbfc834a0", size = 1182991, upload-time = "2026-05-15T16:11:29.258Z" }, + { url = "https://files.pythonhosted.org/packages/90/33/4d3a9d3159cdff1f1886d39f1991e6c8d5927f9b606cfc9743b5bef98c2a/pyjson5-2.0.1-cp314-cp314t-musllinux_1_2_s390x.whl", hash = "sha256:0ef86c53d0e14991b5b0fe58f225e3d8faec437aa0a70da4762525b6bc2fca10", size = 1359104, upload-time = "2026-05-15T16:11:31.651Z" }, + { url = "https://files.pythonhosted.org/packages/0f/04/20eb16c52453aea0af68a697f4058378c9ff871bd2f0bea28eb76ffe12f8/pyjson5-2.0.1-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:1d9faccf5a9e86f14104eec31c13428ef8baeb867182ce107e0c68fcc5c62477", size = 1212847, upload-time = "2026-05-15T16:11:33.767Z" }, + { url = "https://files.pythonhosted.org/packages/b9/a3/69bbe93275eafb7802a5b29230cc5c28f9b924c68d15b3ab2d43cfe19825/pyjson5-2.0.1-cp314-cp314t-win32.whl", hash = "sha256:2df497af7ab03cf82d9278a4707a83d0ae4e6d727f919a883b5ccec3f7d92650", size = 139137, upload-time = "2026-05-15T16:11:35.487Z" }, + { url = "https://files.pythonhosted.org/packages/48/45/b865ca6e0ae6887bc2b6b17cd123470ae43ac0fa04a2362d77d4b9f5bd43/pyjson5-2.0.1-cp314-cp314t-win_amd64.whl", hash = "sha256:3b31cf4f4a4f01800812865af3b02f6700cefb9377e4d9a9c6b78fdcf41fd973", size = 169412, upload-time = "2026-05-15T16:11:36.887Z" }, + { url = "https://files.pythonhosted.org/packages/68/55/02c734459fef0a955ab3e7e745df415d5f9fc873a4c288765f60f22fbc13/pyjson5-2.0.1-cp314-cp314t-win_arm64.whl", hash = "sha256:15f0d8baea89d35c6c01c60b944c778a79cac10f77f71b727f1b244e2c7a8ccb", size = 129061, upload-time = "2026-05-15T16:11:38.712Z" }, +] + [[package]] name = "pylint" version = "4.0.6" @@ -1648,6 +1813,22 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/ab/da/acb2e7d4dbd2dfb792d38c0d850481f29ad7049b356d23f56c687d35203b/pylint-4.0.6-py3-none-any.whl", hash = "sha256:d11a0e1fdb7b1cd46ec5d6fc78fee8b95f28695b2d6140e5809925f61e32ea54", size = 538389, upload-time = "2026-06-14T14:43:24.873Z" }, ] +[[package]] +name = "pymarkdownlnt" +version = "0.9.39" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "application-file-scanner" }, + { name = "application-properties" }, + { name = "columnar" }, + { name = "py-walk" }, + { name = "typing-extensions" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/d4/aa/9f6ac3a91b5c02cedb5ada2ae12fddf4954fe3faab176941a68510e9830e/pymarkdownlnt-0.9.39.tar.gz", hash = "sha256:5f422d593244942e4b545b54b512f6b7e509f907752d707695c051bfe8584948", size = 454763, upload-time = "2026-07-12T01:14:22.332Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/68/4f/9e129701e6799733fd541d0e4bc624695e70259b4c279dd43fb124e4ff63/pymarkdownlnt-0.9.39-py3-none-any.whl", hash = "sha256:3e6f32517c7cc088dc466830b43ca7a04326bd4fc62d7f5379925ae7ee2f5ad9", size = 532072, upload-time = "2026-07-12T01:14:20.995Z" }, +] + [[package]] name = "pytest" version = "9.1.1" @@ -1978,27 +2159,27 @@ wheels = [ [[package]] name = "ruff" -version = "0.15.22" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/3a/06/ae069393fc66e8ff33036d4b368003833bf6e88ccf182e17e7a2f1c754fd/ruff-0.15.22.tar.gz", hash = "sha256:3f15175b1fb580126f58285a5dae6b2ea89000136d980c64499211f116b54809", size = 4785063, upload-time = "2026-07-16T15:14:13.244Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/23/18/ee54b7ae1e121be7a28ea6da4b67564ebb0530e183a54415ab7e3bcd2c4e/ruff-0.15.22-py3-none-linux_armv6l.whl", hash = "sha256:44423e73493737f5e7c5b41d475483898ff37afcdae38bc3da5085e29af1c2d8", size = 10781258, upload-time = "2026-07-16T15:13:19.452Z" }, - { url = "https://files.pythonhosted.org/packages/2f/d2/2520cb14761ddbeaf57642a76942fc36adcbdbe53b4532241995f6fc485c/ruff-0.15.22-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:b82c6482946e9eda7ff2e091d25b8bad3f718684e1916d41bd56873cee05b697", size = 10999477, upload-time = "2026-07-16T15:13:23.318Z" }, - { url = "https://files.pythonhosted.org/packages/c9/10/74e53572aa758dfaa678c2a2646b5c5515d884b7ca56be4d2ce03ca4b560/ruff-0.15.22-py3-none-macosx_11_0_arm64.whl", hash = "sha256:11c1c715af53a09f714e011106bffc419751ec8232fcb5da42173284ea3fec6f", size = 10466716, upload-time = "2026-07-16T15:13:26.162Z" }, - { url = "https://files.pythonhosted.org/packages/1e/cc/44eaaf0844e028182f2d0a8f2190d0f359159aed0a9e5ab861d892f1ae2a/ruff-0.15.22-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:742a29cf29bddb7c8327895d6a10e0e6c5b38a96dd407af9b5d0857f809c0576", size = 10892644, upload-time = "2026-07-16T15:13:29.229Z" }, - { url = "https://files.pythonhosted.org/packages/9f/21/8edf559014d2b0f82beea19cfb713993ad802ccda16868769979c6090a84/ruff-0.15.22-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:72af58b951b0ae395935ae79763dc349bc0eb706319d28f7a33ad2cfb3cfc178", size = 10576719, upload-time = "2026-07-16T15:13:32.35Z" }, - { url = "https://files.pythonhosted.org/packages/bf/1e/3a13abd392a3b50b62e5938a831f9ab6e588358cacad5c18545b716d2182/ruff-0.15.22-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:62d425005c1835eb24e2ee4161cb90e8db263415f4a71c8c72c33abaa6c0c224", size = 11376494, upload-time = "2026-07-16T15:13:35.958Z" }, - { url = "https://files.pythonhosted.org/packages/bf/3e/422d3d95bcf04dd78e1aeac22184d4f9a8fb2c01865d39d44618484a0317/ruff-0.15.22-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e8b9b3f8779a4f08c969defc3c8c35abffaa757e601ed5ae66d6d1db6519969a", size = 12208370, upload-time = "2026-07-16T15:13:39.185Z" }, - { url = "https://files.pythonhosted.org/packages/1e/91/5d065a0e0a02bf4813f5119ad278462eed081d2b832eb7c021ade0ec9e65/ruff-0.15.22-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1e0dd1b2e4d3d585f897a0d137cbf4eaf6223bef4e8ce34d6bb12556c5f9249e", size = 11581098, upload-time = "2026-07-16T15:13:42.132Z" }, - { url = "https://files.pythonhosted.org/packages/f6/f9/a0d4871d12fae702eb1f41b686caf05f1f8b124dc6db6f784f53d74918fa/ruff-0.15.22-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:365523eb91d9224e1bcb03b022fbf0facb8f9e23792a2c53d9d4b3924bdbdebb", size = 11399422, upload-time = "2026-07-16T15:13:45.2Z" }, - { url = "https://files.pythonhosted.org/packages/18/80/c843a5176cddbceb0b7e8dd41cf9993490796c1c469348d384f5a5c13c56/ruff-0.15.22-py3-none-manylinux_2_31_riscv64.whl", hash = "sha256:fabfd168afdf29fee5be98b831efa9683c94d7c5a3b58b9ce5a2e38444589a74", size = 11381683, upload-time = "2026-07-16T15:13:48.46Z" }, - { url = "https://files.pythonhosted.org/packages/d4/00/8485de0ae92239438a36cfc51350db9b9e85c9ebdfaea91b18e422706662/ruff-0.15.22-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:225dbf095a87f1d9f90f5fd7924d2613ee452a75a4308c63a8f50f761787aa7c", size = 10850295, upload-time = "2026-07-16T15:13:51.655Z" }, - { url = "https://files.pythonhosted.org/packages/fa/91/24977ec2ec72eaf15e4394ace2959fdff2dd1e14f03e005e838023407169/ruff-0.15.22-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:1877d63b9d24ed278744f1523fd11b85540566d54641f97c566d7d9dc5ca5296", size = 10579640, upload-time = "2026-07-16T15:13:54.79Z" }, - { url = "https://files.pythonhosted.org/packages/9c/47/9b51216951974df1f263ac19da550d34252e0ed7218c25f10c5ef9ed7517/ruff-0.15.22-py3-none-musllinux_1_2_i686.whl", hash = "sha256:a1606c510bd7215680d32efab38965f7cdec3ef69f5170a3f4791404ffdd5262", size = 11105077, upload-time = "2026-07-16T15:13:57.915Z" }, - { url = "https://files.pythonhosted.org/packages/c2/47/20e9d4a3b8016778acea5fc32bb50d35d207500a17ddb529ffa6996feef8/ruff-0.15.22-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:630479b18625f5ffc373f77603a22a9f8ac0acd7ff0501178b5db28ec71e9c64", size = 11490980, upload-time = "2026-07-16T15:14:01.032Z" }, - { url = "https://files.pythonhosted.org/packages/4d/76/3f72d8fc38c1cb77b38c56a70da9d0c17700cc1cc50f9649c9d3c8f5ba71/ruff-0.15.22-py3-none-win32.whl", hash = "sha256:e5ba0e4a13fd14abbed2a77b517a3911290c6c6c59ef67784328d1668fab76cf", size = 10789165, upload-time = "2026-07-16T15:14:04.16Z" }, - { url = "https://files.pythonhosted.org/packages/cb/46/4965251734c2b6fcdca1b1b187d20bcac3af0ee5b083b89c910bb961ce3a/ruff-0.15.22-py3-none-win_amd64.whl", hash = "sha256:9be63ba1eb936acd2d1342fb8337c356353706fce233b2a15a09a97037e6acde", size = 11938297, upload-time = "2026-07-16T15:14:07.316Z" }, - { url = "https://files.pythonhosted.org/packages/57/c9/e69b1ff4c8b69093ef08b8919ab767af0569666865b39c30a8795d88d3c6/ruff-0.15.22-py3-none-win_arm64.whl", hash = "sha256:e1168075b72158510839f250027659cdd78476f40507dd517892304c41318661", size = 11298172, upload-time = "2026-07-16T15:14:10.51Z" }, +version = "0.16.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/4d/94/1e5e4967626faf12fa56999cd6222dff6992ceb086ad7945756baf70c7a7/ruff-0.16.0.tar.gz", hash = "sha256:e460aafd5495ec89efaa6ced2e4a9a581116451e1c88b9d37ef497e0f8e93982", size = 4790557, upload-time = "2026-07-23T19:11:30.981Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/4b/81/1c8818fee7ce1a04cd7d1b3172e0a8f8e4f1dc4feb7fc390e16daa8af323/ruff-0.16.0-py3-none-linux_armv6l.whl", hash = "sha256:e5115729eb08c585e5121978ba5d5b60caeae394ce21b9fb5e6cd33a1c6c9b1e", size = 10754633, upload-time = "2026-07-23T19:10:46.415Z" }, + { url = "https://files.pythonhosted.org/packages/23/df/beaf59c09d68db84304d555f188b276a77132a5d5b0b67a5c762aa143628/ruff-0.16.0-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:3c954b1d580bfa035b41654f7858cc7e71d5fc3ac5b723dd62bd9133830ed522", size = 10969164, upload-time = "2026-07-23T19:10:50.271Z" }, + { url = "https://files.pythonhosted.org/packages/42/ce/741cd197496a1abbf51352710fd15ed995d2a2be87189c1da26a450d6e83/ruff-0.16.0-py3-none-macosx_11_0_arm64.whl", hash = "sha256:e01c21d10eb1b29f47b7454e1f4056db9a3f0260c646aa88457c610291db9f81", size = 10488846, upload-time = "2026-07-23T19:10:52.639Z" }, + { url = "https://files.pythonhosted.org/packages/52/2a/a2db8e88cade358f5cdcb05674a917751074109315d014eb6352d9a893f7/ruff-0.16.0-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6e364e5ed22ed8dc05082fd78e35308618260907ac2d3c1d637b2e682415b6c9", size = 10889729, upload-time = "2026-07-23T19:10:54.89Z" }, + { url = "https://files.pythonhosted.org/packages/42/65/62a771694ebd63029dc953e27dbad40e1588bd4860ff9fe881018fddaa49/ruff-0.16.0-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:d327b8fc113a1d4421a04f3839d3752057c8dd1ee320223a6f3f52d04ada462a", size = 10568275, upload-time = "2026-07-23T19:10:56.993Z" }, + { url = "https://files.pythonhosted.org/packages/3f/e2/ced249fe8af5f086c5c58cc21cc3356d50f32f7401c5df87050c999620a7/ruff-0.16.0-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a9b50c55e263103586b3dcf5f73d479eb8cb5fdb6098fec59a62891dab653717", size = 11385112, upload-time = "2026-07-23T19:10:59.615Z" }, + { url = "https://files.pythonhosted.org/packages/87/0b/05154977a8fd69eeb6c103271f55403bfd8711f5c0f8ed07489d95a504e7/ruff-0.16.0-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:0ff4a79ce3ec0172f3241943835de1c4cb4e2dcd07f0f8c2d02603dbbbee4b17", size = 12207008, upload-time = "2026-07-23T19:11:02.154Z" }, + { url = "https://files.pythonhosted.org/packages/fb/29/98225831a3a1eab0e02f4acc6ca6559a98611dcc68b6965ff4b7234627c1/ruff-0.16.0-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e95c448fca1fb2a18372a9440926c5a6ee789639bb975c72e7ae6d0b04218ab4", size = 11650842, upload-time = "2026-07-23T19:11:04.557Z" }, + { url = "https://files.pythonhosted.org/packages/91/66/6bd3cf90500653d55dc0ffc8507aa8300bd49d0214b2e8cb4d3fef2943ba/ruff-0.16.0-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4f11a8d11010301d0a398a2fdef67691feca7294da6aef55e2150e8fa2cd520b", size = 11400718, upload-time = "2026-07-23T19:11:09.233Z" }, + { url = "https://files.pythonhosted.org/packages/8e/a2/a54eb4eae05d66364050a5d3b8a9c5ef88196531b3cbe7109d873f87f819/ruff-0.16.0-py3-none-manylinux_2_31_riscv64.whl", hash = "sha256:48044c678e9cb8698246c99b14aaccfa6601dea7379eb48a6f8f73f7a6d86cd0", size = 11426177, upload-time = "2026-07-23T19:11:11.994Z" }, + { url = "https://files.pythonhosted.org/packages/1a/be/16e3eea4b2a478a496919f5e36f17c4559e54620bd3bbac5d6affa068006/ruff-0.16.0-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:7aa0959bad8eb8bef50340154fc9b58678dae31fa4293afa38b44b6e552c0213", size = 10856126, upload-time = "2026-07-23T19:11:14.221Z" }, + { url = "https://files.pythonhosted.org/packages/a2/84/252eb8b868a16eec7257c14f504f77537e734b2d69c762e639e588e304a3/ruff-0.16.0-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:28ea2b7df8ebf7f9da6b7d47b230ab48f387c0a29be3b474c4d0740e197bb9af", size = 10571208, upload-time = "2026-07-23T19:11:16.378Z" }, + { url = "https://files.pythonhosted.org/packages/21/09/817a482f542f7570cbb4554b26e896610c7114f539b1d9e2d2145bf6bef6/ruff-0.16.0-py3-none-musllinux_1_2_i686.whl", hash = "sha256:33a3dfac8c35f81498dea9181bccc2f4c4bc8f1521a1dd9406e77643e0f0fb09", size = 11063329, upload-time = "2026-07-23T19:11:19.173Z" }, + { url = "https://files.pythonhosted.org/packages/2e/23/9403c180ca1cb9b1f7335f5c3e5305c09d49ea5b345196682a36028bde4a/ruff-0.16.0-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:a5237a0bda500d30d81b8e07a6973a5cbc772864cbf746ae2f4e8a2e01c9f4ed", size = 11489751, upload-time = "2026-07-23T19:11:21.74Z" }, + { url = "https://files.pythonhosted.org/packages/b2/1d/1b2ef7bcde851c78d7f17f1cca13fd6dc695fc4b3d6197941e72cae5b132/ruff-0.16.0-py3-none-win32.whl", hash = "sha256:7fab76fa065c873f41ff744347c6e77bcc3dfec4bcc754dc26b63d23c0f7f5fb", size = 10785885, upload-time = "2026-07-23T19:11:23.947Z" }, + { url = "https://files.pythonhosted.org/packages/b2/a3/d5e4ef7a56be3f928ffb90b94c25ba7d3cb9c7fe0736aeaaedf361770712/ruff-0.16.0-py3-none-win_amd64.whl", hash = "sha256:429c117f022bf481fabd9d551e7a3952b24c65e6ef44337ea09d90bebef14472", size = 11923141, upload-time = "2026-07-23T19:11:26.409Z" }, + { url = "https://files.pythonhosted.org/packages/cb/9a/8415f2657cbe200f41a4531ccededf135505a92d4a012229121f885b26f9/ruff-0.16.0-py3-none-win_arm64.whl", hash = "sha256:14296fedcd2705c77ab8235439278bbb38f285cf7da5528b00b3e330c3d4872d", size = 11273407, upload-time = "2026-07-23T19:11:28.705Z" }, ] [[package]] @@ -2010,6 +2191,15 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/b7/ce/149a00dd41f10bc29e5921b496af8b574d8413afcd5e30dfa0ed46c2cc5e/six-1.17.0-py2.py3-none-any.whl", hash = "sha256:4721f391ed90541fddacab5acf947aa0d3dc7d27b2e1e8eda2be8970586c3274", size = 11050, upload-time = "2024-12-04T17:35:26.475Z" }, ] +[[package]] +name = "sly" +version = "0.5" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/41/8a/59e943f7b27904c7756a7b565ffbd55f3841f5cd3d2da2b2b0713c49e488/sly-0.5.tar.gz", hash = "sha256:251d42015e8507158aec2164f06035df4a82b0314ce6450f457d7125e7649024", size = 66702, upload-time = "2022-10-25T14:35:30.592Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/8e/4d/c96d807295183f2360329cd8d8bf5e8072c53d664125b3858c04153f026e/sly-0.5-py3-none-any.whl", hash = "sha256:20485483259eec7f6ba85ff4d2e96a4e50c6621902667fc2695cc8bc2a3e5133", size = 28864, upload-time = "2022-10-25T14:35:28.054Z" }, +] + [[package]] name = "smmap" version = "5.0.3" @@ -2223,6 +2413,51 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/99/55/db07de81b5c630da5cbf5c7df646580ca26dfaefa593667fc6f2fe016d2e/tabulate-0.10.0-py3-none-any.whl", hash = "sha256:f0b0622e567335c8fabaaa659f1b33bcb6ddfe2e496071b743aa113f8774f2d3", size = 39814, upload-time = "2026-03-04T18:55:31.284Z" }, ] +[[package]] +name = "tomli" +version = "2.4.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/22/de/48c59722572767841493b26183a0d1cc411d54fd759c5607c4590b6563a6/tomli-2.4.1.tar.gz", hash = "sha256:7c7e1a961a0b2f2472c1ac5b69affa0ae1132c39adcb67aba98568702b9cc23f", size = 17543, upload-time = "2026-03-25T20:22:03.828Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/c1/ba/42f134a3fe2b370f555f44b1d72feebb94debcab01676bf918d0cb70e9aa/tomli-2.4.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:c742f741d58a28940ce01d58f0ab2ea3ced8b12402f162f4d534dfe18ba1cd6a", size = 155924, upload-time = "2026-03-25T20:21:21.626Z" }, + { url = "https://files.pythonhosted.org/packages/dc/c7/62d7a17c26487ade21c5422b646110f2162f1fcc95980ef7f63e73c68f14/tomli-2.4.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:7f86fd587c4ed9dd76f318225e7d9b29cfc5a9d43de44e5754db8d1128487085", size = 150018, upload-time = "2026-03-25T20:21:23.002Z" }, + { url = "https://files.pythonhosted.org/packages/5c/05/79d13d7c15f13bdef410bdd49a6485b1c37d28968314eabee452c22a7fda/tomli-2.4.1-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ff18e6a727ee0ab0388507b89d1bc6a22b138d1e2fa56d1ad494586d61d2eae9", size = 244948, upload-time = "2026-03-25T20:21:24.04Z" }, + { url = "https://files.pythonhosted.org/packages/10/90/d62ce007a1c80d0b2c93e02cab211224756240884751b94ca72df8a875ca/tomli-2.4.1-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:136443dbd7e1dee43c68ac2694fde36b2849865fa258d39bf822c10e8068eac5", size = 253341, upload-time = "2026-03-25T20:21:25.177Z" }, + { url = "https://files.pythonhosted.org/packages/1a/7e/caf6496d60152ad4ed09282c1885cca4eea150bfd007da84aea07bcc0a3e/tomli-2.4.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:5e262d41726bc187e69af7825504c933b6794dc3fbd5945e41a79bb14c31f585", size = 248159, upload-time = "2026-03-25T20:21:26.364Z" }, + { url = "https://files.pythonhosted.org/packages/99/e7/c6f69c3120de34bbd882c6fba7975f3d7a746e9218e56ab46a1bc4b42552/tomli-2.4.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:5cb41aa38891e073ee49d55fbc7839cfdb2bc0e600add13874d048c94aadddd1", size = 253290, upload-time = "2026-03-25T20:21:27.46Z" }, + { url = "https://files.pythonhosted.org/packages/d6/2f/4a3c322f22c5c66c4b836ec58211641a4067364f5dcdd7b974b4c5da300c/tomli-2.4.1-cp312-cp312-win32.whl", hash = "sha256:da25dc3563bff5965356133435b757a795a17b17d01dbc0f42fb32447ddfd917", size = 98141, upload-time = "2026-03-25T20:21:28.492Z" }, + { url = "https://files.pythonhosted.org/packages/24/22/4daacd05391b92c55759d55eaee21e1dfaea86ce5c571f10083360adf534/tomli-2.4.1-cp312-cp312-win_amd64.whl", hash = "sha256:52c8ef851d9a240f11a88c003eacb03c31fc1c9c4ec64a99a0f922b93874fda9", size = 108847, upload-time = "2026-03-25T20:21:29.386Z" }, + { url = "https://files.pythonhosted.org/packages/68/fd/70e768887666ddd9e9f5d85129e84910f2db2796f9096aa02b721a53098d/tomli-2.4.1-cp312-cp312-win_arm64.whl", hash = "sha256:f758f1b9299d059cc3f6546ae2af89670cb1c4d48ea29c3cacc4fe7de3058257", size = 95088, upload-time = "2026-03-25T20:21:30.677Z" }, + { url = "https://files.pythonhosted.org/packages/07/06/b823a7e818c756d9a7123ba2cda7d07bc2dd32835648d1a7b7b7a05d848d/tomli-2.4.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:36d2bd2ad5fb9eaddba5226aa02c8ec3fa4f192631e347b3ed28186d43be6b54", size = 155866, upload-time = "2026-03-25T20:21:31.65Z" }, + { url = "https://files.pythonhosted.org/packages/14/6f/12645cf7f08e1a20c7eb8c297c6f11d31c1b50f316a7e7e1e1de6e2e7b7e/tomli-2.4.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:eb0dc4e38e6a1fd579e5d50369aa2e10acfc9cace504579b2faabb478e76941a", size = 149887, upload-time = "2026-03-25T20:21:33.028Z" }, + { url = "https://files.pythonhosted.org/packages/5c/e0/90637574e5e7212c09099c67ad349b04ec4d6020324539297b634a0192b0/tomli-2.4.1-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:c7f2c7f2b9ca6bdeef8f0fa897f8e05085923eb091721675170254cbc5b02897", size = 243704, upload-time = "2026-03-25T20:21:34.51Z" }, + { url = "https://files.pythonhosted.org/packages/10/8f/d3ddb16c5a4befdf31a23307f72828686ab2096f068eaf56631e136c1fdd/tomli-2.4.1-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:f3c6818a1a86dd6dca7ddcaaf76947d5ba31aecc28cb1b67009a5877c9a64f3f", size = 251628, upload-time = "2026-03-25T20:21:36.012Z" }, + { url = "https://files.pythonhosted.org/packages/e3/f1/dbeeb9116715abee2485bf0a12d07a8f31af94d71608c171c45f64c0469d/tomli-2.4.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:d312ef37c91508b0ab2cee7da26ec0b3ed2f03ce12bd87a588d771ae15dcf82d", size = 247180, upload-time = "2026-03-25T20:21:37.136Z" }, + { url = "https://files.pythonhosted.org/packages/d3/74/16336ffd19ed4da28a70959f92f506233bd7cfc2332b20bdb01591e8b1d1/tomli-2.4.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:51529d40e3ca50046d7606fa99ce3956a617f9b36380da3b7f0dd3dd28e68cb5", size = 251674, upload-time = "2026-03-25T20:21:38.298Z" }, + { url = "https://files.pythonhosted.org/packages/16/f9/229fa3434c590ddf6c0aa9af64d3af4b752540686cace29e6281e3458469/tomli-2.4.1-cp313-cp313-win32.whl", hash = "sha256:2190f2e9dd7508d2a90ded5ed369255980a1bcdd58e52f7fe24b8162bf9fedbd", size = 97976, upload-time = "2026-03-25T20:21:39.316Z" }, + { url = "https://files.pythonhosted.org/packages/6a/1e/71dfd96bcc1c775420cb8befe7a9d35f2e5b1309798f009dca17b7708c1e/tomli-2.4.1-cp313-cp313-win_amd64.whl", hash = "sha256:8d65a2fbf9d2f8352685bc1364177ee3923d6baf5e7f43ea4959d7d8bc326a36", size = 108755, upload-time = "2026-03-25T20:21:40.248Z" }, + { url = "https://files.pythonhosted.org/packages/83/7a/d34f422a021d62420b78f5c538e5b102f62bea616d1d75a13f0a88acb04a/tomli-2.4.1-cp313-cp313-win_arm64.whl", hash = "sha256:4b605484e43cdc43f0954ddae319fb75f04cc10dd80d830540060ee7cd0243cd", size = 95265, upload-time = "2026-03-25T20:21:41.219Z" }, + { url = "https://files.pythonhosted.org/packages/3c/fb/9a5c8d27dbab540869f7c1f8eb0abb3244189ce780ba9cd73f3770662072/tomli-2.4.1-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:fd0409a3653af6c147209d267a0e4243f0ae46b011aa978b1080359fddc9b6cf", size = 155726, upload-time = "2026-03-25T20:21:42.23Z" }, + { url = "https://files.pythonhosted.org/packages/62/05/d2f816630cc771ad836af54f5001f47a6f611d2d39535364f148b6a92d6b/tomli-2.4.1-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:a120733b01c45e9a0c34aeef92bf0cf1d56cfe81ed9d47d562f9ed591a9828ac", size = 149859, upload-time = "2026-03-25T20:21:43.386Z" }, + { url = "https://files.pythonhosted.org/packages/ce/48/66341bdb858ad9bd0ceab5a86f90eddab127cf8b046418009f2125630ecb/tomli-2.4.1-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:559db847dc486944896521f68d8190be1c9e719fced785720d2216fe7022b662", size = 244713, upload-time = "2026-03-25T20:21:44.474Z" }, + { url = "https://files.pythonhosted.org/packages/df/6d/c5fad00d82b3c7a3ab6189bd4b10e60466f22cfe8a08a9394185c8a8111c/tomli-2.4.1-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:01f520d4f53ef97964a240a035ec2a869fe1a37dde002b57ebc4417a27ccd853", size = 252084, upload-time = "2026-03-25T20:21:45.62Z" }, + { url = "https://files.pythonhosted.org/packages/00/71/3a69e86f3eafe8c7a59d008d245888051005bd657760e96d5fbfb0b740c2/tomli-2.4.1-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:7f94b27a62cfad8496c8d2513e1a222dd446f095fca8987fceef261225538a15", size = 247973, upload-time = "2026-03-25T20:21:46.937Z" }, + { url = "https://files.pythonhosted.org/packages/67/50/361e986652847fec4bd5e4a0208752fbe64689c603c7ae5ea7cb16b1c0ca/tomli-2.4.1-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:ede3e6487c5ef5d28634ba3f31f989030ad6af71edfb0055cbbd14189ff240ba", size = 256223, upload-time = "2026-03-25T20:21:48.467Z" }, + { url = "https://files.pythonhosted.org/packages/8c/9a/b4173689a9203472e5467217e0154b00e260621caa227b6fa01feab16998/tomli-2.4.1-cp314-cp314-win32.whl", hash = "sha256:3d48a93ee1c9b79c04bb38772ee1b64dcf18ff43085896ea460ca8dec96f35f6", size = 98973, upload-time = "2026-03-25T20:21:49.526Z" }, + { url = "https://files.pythonhosted.org/packages/14/58/640ac93bf230cd27d002462c9af0d837779f8773bc03dee06b5835208214/tomli-2.4.1-cp314-cp314-win_amd64.whl", hash = "sha256:88dceee75c2c63af144e456745e10101eb67361050196b0b6af5d717254dddf7", size = 109082, upload-time = "2026-03-25T20:21:50.506Z" }, + { url = "https://files.pythonhosted.org/packages/d5/2f/702d5e05b227401c1068f0d386d79a589bb12bf64c3d2c72ce0631e3bc49/tomli-2.4.1-cp314-cp314-win_arm64.whl", hash = "sha256:b8c198f8c1805dc42708689ed6864951fd2494f924149d3e4bce7710f8eb5232", size = 96490, upload-time = "2026-03-25T20:21:51.474Z" }, + { url = "https://files.pythonhosted.org/packages/45/4b/b877b05c8ba62927d9865dd980e34a755de541eb65fffba52b4cc495d4d2/tomli-2.4.1-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:d4d8fe59808a54658fcc0160ecfb1b30f9089906c50b23bcb4c69eddc19ec2b4", size = 164263, upload-time = "2026-03-25T20:21:52.543Z" }, + { url = "https://files.pythonhosted.org/packages/24/79/6ab420d37a270b89f7195dec5448f79400d9e9c1826df982f3f8e97b24fd/tomli-2.4.1-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:7008df2e7655c495dd12d2a4ad038ff878d4ca4b81fccaf82b714e07eae4402c", size = 160736, upload-time = "2026-03-25T20:21:53.674Z" }, + { url = "https://files.pythonhosted.org/packages/02/e0/3630057d8eb170310785723ed5adcdfb7d50cb7e6455f85ba8a3deed642b/tomli-2.4.1-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:1d8591993e228b0c930c4bb0db464bdad97b3289fb981255d6c9a41aedc84b2d", size = 270717, upload-time = "2026-03-25T20:21:55.129Z" }, + { url = "https://files.pythonhosted.org/packages/7a/b4/1613716072e544d1a7891f548d8f9ec6ce2faf42ca65acae01d76ea06bb0/tomli-2.4.1-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:734e20b57ba95624ecf1841e72b53f6e186355e216e5412de414e3c51e5e3c41", size = 278461, upload-time = "2026-03-25T20:21:56.228Z" }, + { url = "https://files.pythonhosted.org/packages/05/38/30f541baf6a3f6df77b3df16b01ba319221389e2da59427e221ef417ac0c/tomli-2.4.1-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:8a650c2dbafa08d42e51ba0b62740dae4ecb9338eefa093aa5c78ceb546fcd5c", size = 274855, upload-time = "2026-03-25T20:21:57.653Z" }, + { url = "https://files.pythonhosted.org/packages/77/a3/ec9dd4fd2c38e98de34223b995a3b34813e6bdadf86c75314c928350ed14/tomli-2.4.1-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:504aa796fe0569bb43171066009ead363de03675276d2d121ac1a4572397870f", size = 283144, upload-time = "2026-03-25T20:21:59.089Z" }, + { url = "https://files.pythonhosted.org/packages/ef/be/605a6261cac79fba2ec0c9827e986e00323a1945700969b8ee0b30d85453/tomli-2.4.1-cp314-cp314t-win32.whl", hash = "sha256:b1d22e6e9387bf4739fbe23bfa80e93f6b0373a7f1b96c6227c32bef95a4d7a8", size = 108683, upload-time = "2026-03-25T20:22:00.214Z" }, + { url = "https://files.pythonhosted.org/packages/12/64/da524626d3b9cc40c168a13da8335fe1c51be12c0a63685cc6db7308daae/tomli-2.4.1-cp314-cp314t-win_amd64.whl", hash = "sha256:2c1c351919aca02858f740c6d33adea0c5deea37f9ecca1cc1ef9e884a619d26", size = 121196, upload-time = "2026-03-25T20:22:01.169Z" }, + { url = "https://files.pythonhosted.org/packages/5a/cd/e80b62269fc78fc36c9af5a6b89c835baa8af28ff5ad28c7028d60860320/tomli-2.4.1-cp314-cp314t-win_arm64.whl", hash = "sha256:eab21f45c7f66c13f2a9e0e1535309cee140182a9cdae1e041d02e47291e8396", size = 100393, upload-time = "2026-03-25T20:22:02.137Z" }, + { url = "https://files.pythonhosted.org/packages/7b/61/cceae43728b7de99d9b847560c262873a1f6c98202171fd5ed62640b494b/tomli-2.4.1-py3-none-any.whl", hash = "sha256:0d85819802132122da43cb86656f8d1f8c6587d54ae7dcaf30e90533028b49fe", size = 14583, upload-time = "2026-03-25T20:22:03.012Z" }, +] + [[package]] name = "tomlkit" version = "0.15.1" @@ -2232,6 +2467,15 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/13/bc/8c13eb66537dce1d2bd3a57132902f38d0e7f5bb46fa9f4daed9fe9d76ee/tomlkit-0.15.1-py3-none-any.whl", hash = "sha256:177a05aece5a8ca5266fd3c448abb47b8d352f09d477d3ca8332db4d89b24304", size = 49449, upload-time = "2026-07-17T01:48:05.728Z" }, ] +[[package]] +name = "toolz" +version = "1.1.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/11/d6/114b492226588d6ff54579d95847662fc69196bdeec318eb45393b24c192/toolz-1.1.0.tar.gz", hash = "sha256:27a5c770d068c110d9ed9323f24f1543e83b2f300a687b7891c1a6d56b697b5b", size = 52613, upload-time = "2025-10-17T04:03:21.661Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/fb/12/5911ae3eeec47800503a238d971e51722ccea5feb8569b735184d5fcdbc0/toolz-1.1.0-py3-none-any.whl", hash = "sha256:15ccc861ac51c53696de0a5d6d4607f99c210739caf987b5d2054f3efed429d8", size = 58093, upload-time = "2025-10-17T04:03:20.435Z" }, +] + [[package]] name = "tornado" version = "6.5.7" From 79f85fa94d9920e5d8c0104a2fefafb32cd0b854 Mon Sep 17 00:00:00 2001 From: Martijn Govers Date: Wed, 29 Jul 2026 08:10:34 +0200 Subject: [PATCH 02/14] lock upgrade exclude newer Signed-off-by: Martijn Govers --- .github/workflows/refresh-lock-and-linter-dependencies.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/refresh-lock-and-linter-dependencies.yml b/.github/workflows/refresh-lock-and-linter-dependencies.yml index 8ea8f37cc7..3cee9b09ea 100644 --- a/.github/workflows/refresh-lock-and-linter-dependencies.yml +++ b/.github/workflows/refresh-lock-and-linter-dependencies.yml @@ -41,7 +41,7 @@ jobs: uses: astral-sh/setup-uv@c771a70e6277c0a99b617c7a806ffedaca235ff9 # v9.0.0 - name: upgrade uv lock - run: uv lock --upgrade + run: uv lock --upgrade --exclude-newer "7 days" - name: Install linters from uv run: | From f9178a0795b2a6f760d80f69cdcfc66baf1dc47d Mon Sep 17 00:00:00 2001 From: Martijn Govers Date: Wed, 29 Jul 2026 08:11:49 +0200 Subject: [PATCH 03/14] exclude newer in uv config Signed-off-by: Martijn Govers --- .github/workflows/refresh-lock-and-linter-dependencies.yml | 2 +- pyproject.toml | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/.github/workflows/refresh-lock-and-linter-dependencies.yml b/.github/workflows/refresh-lock-and-linter-dependencies.yml index 3cee9b09ea..28d201c2f3 100644 --- a/.github/workflows/refresh-lock-and-linter-dependencies.yml +++ b/.github/workflows/refresh-lock-and-linter-dependencies.yml @@ -41,7 +41,7 @@ jobs: uses: astral-sh/setup-uv@c771a70e6277c0a99b617c7a806ffedaca235ff9 # v9.0.0 - name: upgrade uv lock - run: uv lock --upgrade --exclude-newer "7 days" + run: uv lock --upgrade - name: Install linters from uv run: | diff --git a/pyproject.toml b/pyproject.toml index 7a6573aced..d5464e55f7 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -84,6 +84,9 @@ Discussion = "https://github.com/orgs/PowerGridModel/discussions" [project.entry-points."cmake.root"] power_grid_model = "power_grid_model._core.power_grid_model_c" +[tool.uv] +exclude-newer = "7 days" + [tool.scikit-build] logging.level = "INFO" From c90bea1b088b94afd2534b2b0586664431270034 Mon Sep 17 00:00:00 2001 From: "power-grid-model-ci-bot[bot]" <249743335+power-grid-model-ci-bot[bot]@users.noreply.github.com> Date: Wed, 29 Jul 2026 06:13:15 +0000 Subject: [PATCH 04/14] Refresh lock and linter dependencies Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> --- .pre-commit-config.yaml | 3 +- package-lock.json | 78 ++++++------- uv.lock | 244 +++++++++++++++++++++------------------- 3 files changed, 168 insertions(+), 157 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index ec986b13fd..bd2cd8b678 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -63,9 +63,10 @@ repos: pass_filenames: true types: [ markdown ] require_serial: true + # format .json and .jsonc files # format .json and .jsonc files - repo: https://github.com/biomejs/pre-commit # outside pypi - rev: v2.5.5 + rev: v2.5.6 hooks: # configuration is located in biome.jsonc - id: biome-format diff --git a/package-lock.json b/package-lock.json index 6c62607f00..516499e031 100644 --- a/package-lock.json +++ b/package-lock.json @@ -10,9 +10,9 @@ } }, "node_modules/@biomejs/biome": { - "version": "2.5.5", - "resolved": "https://registry.npmjs.org/@biomejs/biome/-/biome-2.5.5.tgz", - "integrity": "sha512-r1S8nFsAG1MY+vJFZALzIvwXAJv6ejDQ0mxP21Tgr9YK3ZFtjrvbBwDdNhx1rUqvccEIeNg20cYCNzl6Cr69pQ==", + "version": "2.5.6", + "resolved": "https://registry.npmjs.org/@biomejs/biome/-/biome-2.5.6.tgz", + "integrity": "sha512-lxVNjv7UF6KfhMJfL9gaUHbWdJdHbsAj6OSmwSYNdhRuG67NxNQ4Xdvh3TUxsSK9sBzJBQhEJj3AopmmNJ5pSA==", "dev": true, "license": "MIT OR Apache-2.0", "bin": { @@ -26,20 +26,20 @@ "url": "https://opencollective.com/biome" }, "optionalDependencies": { - "@biomejs/cli-darwin-arm64": "2.5.5", - "@biomejs/cli-darwin-x64": "2.5.5", - "@biomejs/cli-linux-arm64": "2.5.5", - "@biomejs/cli-linux-arm64-musl": "2.5.5", - "@biomejs/cli-linux-x64": "2.5.5", - "@biomejs/cli-linux-x64-musl": "2.5.5", - "@biomejs/cli-win32-arm64": "2.5.5", - "@biomejs/cli-win32-x64": "2.5.5" + "@biomejs/cli-darwin-arm64": "2.5.6", + "@biomejs/cli-darwin-x64": "2.5.6", + "@biomejs/cli-linux-arm64": "2.5.6", + "@biomejs/cli-linux-arm64-musl": "2.5.6", + "@biomejs/cli-linux-x64": "2.5.6", + "@biomejs/cli-linux-x64-musl": "2.5.6", + "@biomejs/cli-win32-arm64": "2.5.6", + "@biomejs/cli-win32-x64": "2.5.6" } }, "node_modules/@biomejs/cli-darwin-arm64": { - "version": "2.5.5", - "resolved": "https://registry.npmjs.org/@biomejs/cli-darwin-arm64/-/cli-darwin-arm64-2.5.5.tgz", - "integrity": "sha512-kUrAhXVWUrwmAUnV2iXSK7umxKFysTwvqK+Ty6ptUcLY/7T3SnCAjUowE4uvwaEej6nXZ7hu/dTtbokKdsPeag==", + "version": "2.5.6", + "resolved": "https://registry.npmjs.org/@biomejs/cli-darwin-arm64/-/cli-darwin-arm64-2.5.6.tgz", + "integrity": "sha512-zMOLZP4oMrjh6m1zcSj1ud2awUPgTuMVbmQhYYWL7J8HwCnbHHBvTm7VBTRuY7epT5bez76IpKYQ11ZAqHFlnw==", "cpu": [ "arm64" ], @@ -54,9 +54,9 @@ } }, "node_modules/@biomejs/cli-darwin-x64": { - "version": "2.5.5", - "resolved": "https://registry.npmjs.org/@biomejs/cli-darwin-x64/-/cli-darwin-x64-2.5.5.tgz", - "integrity": "sha512-DamiYc5bUYZ2uxlfc+RLEPtz1Abb6PO5eTbOkufLpSGwd/7AMQAdxhFYiXmwwkJL8IsT8S7GvdgwDHqaMFAvKw==", + "version": "2.5.6", + "resolved": "https://registry.npmjs.org/@biomejs/cli-darwin-x64/-/cli-darwin-x64-2.5.6.tgz", + "integrity": "sha512-JAC1VqzvO7Th5ZplU0G2uGfkZbxEe9uDDektPAhF0JLusoz1w+T4okp2bkykI0bbaO2vslKiRfj4gU43JaGreA==", "cpu": [ "x64" ], @@ -71,9 +71,9 @@ } }, "node_modules/@biomejs/cli-linux-arm64": { - "version": "2.5.5", - "resolved": "https://registry.npmjs.org/@biomejs/cli-linux-arm64/-/cli-linux-arm64-2.5.5.tgz", - "integrity": "sha512-lRKF/pH/1RiYiBKExi3TCZVAtvzEm77aifrvcNiDFrR9WxeAnDUjDnseb6y2XV85mjitLs6SILGm2XG77cHtSQ==", + "version": "2.5.6", + "resolved": "https://registry.npmjs.org/@biomejs/cli-linux-arm64/-/cli-linux-arm64-2.5.6.tgz", + "integrity": "sha512-6XsYwCFkp5sMxl85ffhgeGpGgs6A7dRYFnkceZ7WVxvycuTnGdD5xa534Z3xfrBQ0JCMK/mujT6ZNPJoghedwg==", "cpu": [ "arm64" ], @@ -88,9 +88,9 @@ } }, "node_modules/@biomejs/cli-linux-arm64-musl": { - "version": "2.5.5", - "resolved": "https://registry.npmjs.org/@biomejs/cli-linux-arm64-musl/-/cli-linux-arm64-musl-2.5.5.tgz", - "integrity": "sha512-U4WMl/sy/E/Q73vf15VspakLRRs2LDFcCeBxJnQfXzssb88zpV6PJPaQ3ezhQ7H6Ht2/8bvuZeHgJWzmoxllZg==", + "version": "2.5.6", + "resolved": "https://registry.npmjs.org/@biomejs/cli-linux-arm64-musl/-/cli-linux-arm64-musl-2.5.6.tgz", + "integrity": "sha512-eUa3jeeYvfMt19LBeh6E5PUZpxnTC4JqNWo+EDjTtQjAr2xLGnWaxACtVU1DQqmHYbvThlJzLX+ZsYgrqh2qVw==", "cpu": [ "arm64" ], @@ -105,9 +105,9 @@ } }, "node_modules/@biomejs/cli-linux-x64": { - "version": "2.5.5", - "resolved": "https://registry.npmjs.org/@biomejs/cli-linux-x64/-/cli-linux-x64-2.5.5.tgz", - "integrity": "sha512-H/O39nJEw/2Zm/fm7hrmxxoF8kK/aU1uCoPp70ruXVbomaAdLpJJnCmL11Q2JotT8QVHH06So04Oq53lCSwSwQ==", + "version": "2.5.6", + "resolved": "https://registry.npmjs.org/@biomejs/cli-linux-x64/-/cli-linux-x64-2.5.6.tgz", + "integrity": "sha512-Pop9VXCFUhFTMfFefZ39S+u2rOPyNp5iHlxbZRwXGACHLy2r0jjiRgJHmaEKJzL3SyxlVeGShXhvvElvWowonA==", "cpu": [ "x64" ], @@ -122,9 +122,9 @@ } }, "node_modules/@biomejs/cli-linux-x64-musl": { - "version": "2.5.5", - "resolved": "https://registry.npmjs.org/@biomejs/cli-linux-x64-musl/-/cli-linux-x64-musl-2.5.5.tgz", - "integrity": "sha512-m7wC7tjX5Lrmo69dc4md8FeKpPU1NTCY1v7xUoQQ2vadWwNnBS0KZOG8471otFPHrTHihQJAjQPgMObpLvDe6A==", + "version": "2.5.6", + "resolved": "https://registry.npmjs.org/@biomejs/cli-linux-x64-musl/-/cli-linux-x64-musl-2.5.6.tgz", + "integrity": "sha512-2Vp13QdKysH3HIWLaYLhUUwbK+jbZonJD1K+Lr0d0RO4wH7mkYd43vJixEDm8cUWrowoRz4UUHF1nm9Ae7ym8A==", "cpu": [ "x64" ], @@ -139,9 +139,9 @@ } }, "node_modules/@biomejs/cli-win32-arm64": { - "version": "2.5.5", - "resolved": "https://registry.npmjs.org/@biomejs/cli-win32-arm64/-/cli-win32-arm64-2.5.5.tgz", - "integrity": "sha512-7BryINPuYypLUAH3o/o5ZdgomJ4zn3EDR0ChZJst7n32S6ZhKbgHXuYydLu+YAnx59ehGFR0z/MG6qnzQi3Yyw==", + "version": "2.5.6", + "resolved": "https://registry.npmjs.org/@biomejs/cli-win32-arm64/-/cli-win32-arm64-2.5.6.tgz", + "integrity": "sha512-tDGshcm6BdkZOCGnTDX0Y8/U4IfBSlnUU7T56nNDuPEfed+aHg+u8G36NB43fJVl0Os6+QURXIE1yuD7AaEofA==", "cpu": [ "arm64" ], @@ -156,9 +156,9 @@ } }, "node_modules/@biomejs/cli-win32-x64": { - "version": "2.5.5", - "resolved": "https://registry.npmjs.org/@biomejs/cli-win32-x64/-/cli-win32-x64-2.5.5.tgz", - "integrity": "sha512-bIBFo+n6MIxdNcVFy5CrurbKiZQiUciK3bt8+O9I4wjFZNTfXLpi+giq47522eXqW5NBc9ulx7dR1SlZKi2J5g==", + "version": "2.5.6", + "resolved": "https://registry.npmjs.org/@biomejs/cli-win32-x64/-/cli-win32-x64-2.5.6.tgz", + "integrity": "sha512-WN05KwXnTO/2J45RQPvzZMXf7tZUIofHoR35xIPfCo7pQ2RFidxI8sfb5mGsaTxdMmEOzHzOPRCdA5/fCpc7xQ==", "cpu": [ "x64" ], @@ -1177,13 +1177,13 @@ "license": "MIT" }, "node_modules/minimatch": { - "version": "10.2.5", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.5.tgz", - "integrity": "sha512-MULkVLfKGYDFYejP07QOurDLLQpcjk7Fw+7jXS2R2czRQzR56yHRveU5NDJEOviH+hETZKSkIk5c+T23GjFUMg==", + "version": "10.2.6", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.6.tgz", + "integrity": "sha512-vpLQEs+VLCr1nU0BXS07maYoFwlDAH0gngQuuttxIwutDFEMHq2blX+8vpgxDdK3J1PwjCJiep77OitTZ4Ll1A==", "dev": true, "license": "BlueOak-1.0.0", "dependencies": { - "brace-expansion": "^5.0.5" + "brace-expansion": "^5.0.8" }, "engines": { "node": "18 || 20 || >=22" diff --git a/uv.lock b/uv.lock index 8edcdf9316..9798c2966d 100644 --- a/uv.lock +++ b/uv.lock @@ -13,6 +13,10 @@ resolution-markers = [ "python_full_version < '3.14' and sys_platform != 'emscripten' and sys_platform != 'win32'", ] +[options] +exclude-newer = "0001-01-01T00:00:00Z" # This has no effect and is included for backwards compatibility when using relative exclude-newer values. +exclude-newer-span = "P7D" + [[package]] name = "alabaster" version = "1.0.0" @@ -567,11 +571,11 @@ wheels = [ [[package]] name = "fastjsonschema" -version = "2.22.1" +version = "2.21.2" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/e4/98/474719c58eddaf77fa443b063693e76d49db32bbe851bcbaf58d2700119f/fastjsonschema-2.22.1.tar.gz", hash = "sha256:0b83d1ce8d7845b959dcb20e1a5c3c8883b6541d9c52ab02cce5166b75ec805f", size = 382291, upload-time = "2026-07-27T13:31:08.515Z" } +sdist = { url = "https://files.pythonhosted.org/packages/20/b5/23b216d9d985a956623b6bd12d4086b60f0059b27799f23016af04a74ea1/fastjsonschema-2.21.2.tar.gz", hash = "sha256:b1eb43748041c880796cd077f1a07c3d94e93ae84bba5ed36800a33554ae05de", size = 374130, upload-time = "2025-08-14T18:49:36.666Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/17/e1/62cc96341f01bdff2ba967441939178fcd1900d11ce7e6554d9954a5d7ec/fastjsonschema-2.22.1-py3-none-any.whl", hash = "sha256:cf377ff5c9a6f4f3125fb35f75a2c5767bd824ffbcf62c209a93cd48d1453999", size = 26239, upload-time = "2026-07-27T13:31:03.251Z" }, + { url = "https://files.pythonhosted.org/packages/cb/a8/20d0723294217e47de6d9e2e40fd4a9d2f7c4b6ef974babd482a59743694/fastjsonschema-2.21.2-py3-none-any.whl", hash = "sha256:1c797122d0a86c5cace2e54bf4e819c36223b552017172f32c5c024a6b77e463", size = 24024, upload-time = "2025-08-14T18:49:34.776Z" }, ] [[package]] @@ -632,69 +636,69 @@ wheels = [ [[package]] name = "gitpython" -version = "3.1.57" +version = "3.1.54" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "gitdb" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/ba/0d/132ed135c871b6bf91adf16a0e43797cd535b81d4973b5d09291c54fc5ee/gitpython-3.1.57.tar.gz", hash = "sha256:c493ec57c0ef6b19743798b6a5af859c71814b524e7e6f97baa2f8e658961488", size = 225898, upload-time = "2026-07-26T07:33:26.351Z" } +sdist = { url = "https://files.pythonhosted.org/packages/5e/d5/3da0b92033887033f4c27f2dd109a303c4ca62813c7b3bb2511edb4777de/gitpython-3.1.54.tar.gz", hash = "sha256:53f2085e24a2cda300eed7c3fc5f1559ae289634b725e98acaf4791940247aa0", size = 225076, upload-time = "2026-07-22T04:08:51.403Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/41/6e/2139de986d9c7c3ac86f1f8be43858ce90bdfe2f7175e6c80c650ba15242/gitpython-3.1.57-py3-none-any.whl", hash = "sha256:4ccf7d73c10f5c9e76043fbb2675ac5a1b3ff5b41e648f56bcbed5f63792ecaf", size = 217151, upload-time = "2026-07-26T07:33:24.838Z" }, + { url = "https://files.pythonhosted.org/packages/d1/b9/876f442a28df5c068ca69b0122d5c35e65fd2d2fa9992ea5cb5944ea00a6/gitpython-3.1.54-py3-none-any.whl", hash = "sha256:b90d7b3d9bc0238681d24369130826f0dcdb0ceaa45db67cf1d4ffa4c302dedf", size = 216575, upload-time = "2026-07-22T04:08:50.05Z" }, ] [[package]] name = "greenlet" -version = "3.5.4" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/a3/74/b13368064b09053253555d3f2839cc2684d22d5aed0d2ccffbf7a6736558/greenlet-3.5.4.tar.gz", hash = "sha256:0232ae1de90a8e07867bb127d7a6ba2301e859145489f25cda8a6096dabe1d20", size = 206538, upload-time = "2026-07-22T12:47:14.468Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/f3/04/81bd731d6d1e3a469d9a4c36f5eb069bcf0cbb2d5d342c9fec22245b91fc/greenlet-3.5.4-cp312-cp312-macosx_11_0_universal2.whl", hash = "sha256:3d66250e8b09f182ede05490998c818b5961f7a3640332d44c4927caec7bbfe4", size = 295909, upload-time = "2026-07-22T11:38:09.261Z" }, - { url = "https://files.pythonhosted.org/packages/cc/dd/f5f22903a6ae70f5ea328ed0beaec92ad903f0e3b7d2845133b354abc4b8/greenlet-3.5.4-cp312-cp312-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:c90e930c9c192e5b3ee9fb8bcd920ea3926155e2e3ded39fc697323addecee17", size = 612011, upload-time = "2026-07-22T12:26:40.69Z" }, - { url = "https://files.pythonhosted.org/packages/8e/10/92a4a88d12b915d74ea5b6d288e4afefda4771647caa34442c156f7a454f/greenlet-3.5.4-cp312-cp312-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:791fdfeeb9c6e0c7b10fa151bf110d2a6974866f13dcb5b1c7efae698245893a", size = 624299, upload-time = "2026-07-22T12:29:02.089Z" }, - { url = "https://files.pythonhosted.org/packages/50/6d/0b14bb9db2989f32cd9fe7f76afedea01ee8bee3f87c07e69f24adfe7e63/greenlet-3.5.4-cp312-cp312-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:f88193799d43dbf8c8a806d6405c9c52fe2af40bf75072a606357b33cc336c7f", size = 621541, upload-time = "2026-07-22T11:51:09.464Z" }, - { url = "https://files.pythonhosted.org/packages/48/3d/25e9a2d9eb6b2e8b7ca4e80a3a26cb887cce6c8e0a87c921164f11bc5574/greenlet-3.5.4-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:b7a5f095767c4493afcd06067f2bb3b8716e3f3f9e92b99c88e7e99f885b3d4d", size = 1581444, upload-time = "2026-07-22T12:25:03.818Z" }, - { url = "https://files.pythonhosted.org/packages/b9/96/4c9bf2e2c408dcc0556edce69efa9f802e82223573c53240136a086821f1/greenlet-3.5.4-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:42afdc1ab5f66da8c586c32af9224a74a706b4f0ea0dc3a4188a0860a09c65c9", size = 1645842, upload-time = "2026-07-22T11:51:12.295Z" }, - { url = "https://files.pythonhosted.org/packages/b5/41/303ecb26a3a56122c0f4d4073ee078881847bd6b6f463ae0ec57ec20223b/greenlet-3.5.4-cp312-cp312-win_amd64.whl", hash = "sha256:60149df8f462d1b230038e6590c23c3b4768bb5d6c022b3b6e82532b34b0b8a3", size = 247169, upload-time = "2026-07-22T11:38:19.893Z" }, - { url = "https://files.pythonhosted.org/packages/a4/e3/ef56864b4c35fcb3eb3b41b869f6cc46f4cd3f5e2c68e74acde8ac433951/greenlet-3.5.4-cp312-cp312-win_arm64.whl", hash = "sha256:77d6ce04fed0d9aeed42e0f37923cc43eba9b027bdd9c34546bb4ccd143d0fe0", size = 245565, upload-time = "2026-07-22T11:38:27.061Z" }, - { url = "https://files.pythonhosted.org/packages/c0/9a/e51225dcd58713f16ccbdcc501a8da21098ea14515b7870f1f94459e5ff5/greenlet-3.5.4-cp313-cp313-macosx_11_0_universal2.whl", hash = "sha256:24e61b88cb7e1b1d794b32a10cc346ac779681d6d74ff137a3e0a444d2bf1f02", size = 294831, upload-time = "2026-07-22T11:38:53.389Z" }, - { url = "https://files.pythonhosted.org/packages/9f/ea/de50a50fadf979713ab18b46f22ad5ff5f2dcfc637a3ebdecf669801e1a5/greenlet-3.5.4-cp313-cp313-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:870d730fec833f5a06906a32596cc099b9161594642a92a520b7a88911c95356", size = 614619, upload-time = "2026-07-22T12:26:42.282Z" }, - { url = "https://files.pythonhosted.org/packages/db/c7/2aae27fea41205b8650294c301f042a2a4bb6155eea48c995b890a92f2c1/greenlet-3.5.4-cp313-cp313-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:ec5ff0d1878df6af3bf9b638a5a92a7d5693291de77c91bff10fa48519c604ef", size = 627021, upload-time = "2026-07-22T12:29:03.445Z" }, - { url = "https://files.pythonhosted.org/packages/eb/56/79fd826f9ccaae0b84e1b4ef68dabba5e105bb044ffcd448a0b782fcba9a/greenlet-3.5.4-cp313-cp313-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:d84d993f6e575c950d91a23c1345d18fe1a4310d447bf630849d7809196b52f0", size = 624002, upload-time = "2026-07-22T11:51:11.391Z" }, - { url = "https://files.pythonhosted.org/packages/0a/1a/27319f97e731298513dcba1a2e91b63e9d8811d9de22130f960b129b1bf1/greenlet-3.5.4-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:58023945f421093de5e6fa108c0985a8659d43f49e0216da25099369a121bcbd", size = 1581533, upload-time = "2026-07-22T12:25:05.322Z" }, - { url = "https://files.pythonhosted.org/packages/b1/6d/24240bf562e9786dd2799ee0a4a4dadb4ded22510f41b20245099159ac8c/greenlet-3.5.4-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:bae2728e1897aa8df8cb1af38cd48b3a743aefe29372de7b8b7a9f532501e69f", size = 1645781, upload-time = "2026-07-22T11:51:14.805Z" }, - { url = "https://files.pythonhosted.org/packages/c1/5a/442ab1a9ef7ca6bf7210e5397a95972206a91a31033a03c8900866a10039/greenlet-3.5.4-cp313-cp313-win_amd64.whl", hash = "sha256:ca5726c0b08ca35ae873557266a78b2c3f3b2b7d7401aa5ff886c2045dd0111c", size = 247133, upload-time = "2026-07-22T11:39:20.661Z" }, - { url = "https://files.pythonhosted.org/packages/3e/e6/9160210222386b1a378ff94db846b9508ca24a121cf684991561fdb69280/greenlet-3.5.4-cp313-cp313-win_arm64.whl", hash = "sha256:7c1303791d603080cac6fc3b34df51c3b75b723739c282c8029e48a0d241672f", size = 245500, upload-time = "2026-07-22T11:40:22.185Z" }, - { url = "https://files.pythonhosted.org/packages/a5/a7/6ab1d4f9cd548d15ab90da29947f2076100130bb179b0bde59f795a459e3/greenlet-3.5.4-cp314-cp314-macosx_11_0_universal2.whl", hash = "sha256:7e8afa5eac028f8140ceafe5ceec66e6aa127ddcb21452d2a564dcd2900b5f22", size = 295410, upload-time = "2026-07-22T11:40:35.747Z" }, - { url = "https://files.pythonhosted.org/packages/cd/7a/422f63b4715cbc0b24385305407adf38b48f6bb68b3e6b04090e994d0f5a/greenlet-3.5.4-cp314-cp314-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:73b37afe369021423ea53dd3123e04bffa7e93ac64429b9f50835b2e4fcae7cf", size = 661286, upload-time = "2026-07-22T12:26:43.8Z" }, - { url = "https://files.pythonhosted.org/packages/d0/31/5a1cac663bf5582190c5a714ef81364f03cde232227f39748f8ae4c11da5/greenlet-3.5.4-cp314-cp314-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:3ef964f56dfcb6f9bbef2a190d9126795eac408716aeae47b5e7c73c32aafca9", size = 673517, upload-time = "2026-07-22T12:29:04.815Z" }, - { url = "https://files.pythonhosted.org/packages/15/4a/2a82a1e3f8aaca020853ac8d12211280ca2b231aa08ea39f636f1060c319/greenlet-3.5.4-cp314-cp314-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:9c53ff01a5c53a40f2c16820ebc56d7c61a77f5fbe009dadd96292d5682f80f8", size = 670917, upload-time = "2026-07-22T11:51:13.589Z" }, - { url = "https://files.pythonhosted.org/packages/68/b0/e379a152b17bfdfa95795af4049e37c0fd1b4d81f020d426db104ed07c77/greenlet-3.5.4-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:ecca4d80d55a01ad6b23b33262662956149fbb7b2c6be2910f1705921958cbf3", size = 1628478, upload-time = "2026-07-22T12:25:06.678Z" }, - { url = "https://files.pythonhosted.org/packages/5e/43/bffdfa64f7317f954c5c1230b5dd5922676ce198689a68c1ac1ed4b1b1a5/greenlet-3.5.4-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:2ffbc533e0eaf8e80d8471411646ab88fe58f641d508c0b02b24494479f4d9ec", size = 1692021, upload-time = "2026-07-22T11:51:17.008Z" }, - { url = "https://files.pythonhosted.org/packages/d0/11/f799f9637e2c6e9b0b716015e339040598b058cf7654dfc0d67468b177ed/greenlet-3.5.4-cp314-cp314-win_amd64.whl", hash = "sha256:305f69e6c4523d7f6979ed001cff4e5853c063e5da04880296603aa0227e544c", size = 248031, upload-time = "2026-07-22T11:40:11.007Z" }, - { url = "https://files.pythonhosted.org/packages/05/75/625bcdd74d5e6b2dca1ecba3c3ac77bcf8a026c21a649a46cef23e421f97/greenlet-3.5.4-cp314-cp314-win_arm64.whl", hash = "sha256:f260930bbbbcf9caee661211235a5111c86dfe5832fdf6ae4570da1e0995320f", size = 246892, upload-time = "2026-07-22T11:40:27.357Z" }, - { url = "https://files.pythonhosted.org/packages/ec/69/35c62ed49c320cb4d98e14698ccca5467d3bfe683984172be9cb564d9ce3/greenlet-3.5.4-cp314-cp314t-macosx_11_0_universal2.whl", hash = "sha256:41ddab54e4b238f4a6c323f39b4e59e176affd5a94d461a9fb7583dac74240a3", size = 305571, upload-time = "2026-07-22T11:40:31.659Z" }, - { url = "https://files.pythonhosted.org/packages/5b/6c/64d60216b3640dcb0b62d913dd9e0d80030c09115bb2e4ba70c95d10ca45/greenlet-3.5.4-cp314-cp314t-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:b3dabe3e2809013052c68bdf0b7fa5f5f2859c43a80803131ad61af9cabd7867", size = 672568, upload-time = "2026-07-22T12:26:45.298Z" }, - { url = "https://files.pythonhosted.org/packages/5c/de/ba3ab0a96292e53039530333b0d2ae18d9e508f3a325cd7bf15f8172944c/greenlet-3.5.4-cp314-cp314t-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:27d3f00718634d4520a3a150154ac5da36f257869d41321953375b90bfbbc72c", size = 680076, upload-time = "2026-07-22T12:29:06.125Z" }, - { url = "https://files.pythonhosted.org/packages/a5/be/aeada79083c6f1c15f45d77a332f9c441af263ee298e3eb17522cd337d22/greenlet-3.5.4-cp314-cp314t-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:cbd60b5763c6543c1827e48faaf14ea9bfbad245f52b1a4d76a2a2d8884c6c66", size = 676733, upload-time = "2026-07-22T11:51:16.027Z" }, - { url = "https://files.pythonhosted.org/packages/e9/10/2392fc3a98948652ef5fd1e7275c04f861dd13f74b78a2b4309f4ee4d090/greenlet-3.5.4-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:f00f910f0e7b35416c63b23ad78b769aeccfc1775f712b43c4ee525624a2eef7", size = 1637327, upload-time = "2026-07-22T12:25:07.879Z" }, - { url = "https://files.pythonhosted.org/packages/55/c6/e7237a3dfa1f205ed0d9ea1e46d70bd2811b32d516266399fb59d28ab90a/greenlet-3.5.4-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:91c26423753b92caf41ab3f98fd547d7374d4d9fc2d85be041886c1579d9255e", size = 1697493, upload-time = "2026-07-22T11:51:19.214Z" }, - { url = "https://files.pythonhosted.org/packages/55/e3/4ba8154ba2a3d43729e499f72471b4b5c993f3826d3e24da81d5f06d6572/greenlet-3.5.4-cp314-cp314t-win_amd64.whl", hash = "sha256:ee032b91fd8ec29ec6c4cea2b8c561b178435134bd0752c7334b94e9c736c132", size = 251637, upload-time = "2026-07-22T11:40:37.44Z" }, - { url = "https://files.pythonhosted.org/packages/90/03/e3f96dfc100261a29545ddc8270cafe58f9195b6651466910e820910de77/greenlet-3.5.4-cp315-cp315-macosx_11_0_universal2.whl", hash = "sha256:178111881dd7a6c946471fda85485ec796e1043c2b939f694b096e2ecf986809", size = 296076, upload-time = "2026-07-22T11:39:38.364Z" }, - { url = "https://files.pythonhosted.org/packages/a4/3d/da52d208e5c977bce8667e784729e584e38b5785f4c1ec0f4c836e9a1c42/greenlet-3.5.4-cp315-cp315-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:d92df08dd65fede97fc37aad36c2e9dcda3b31c467f8e0c2c096456cb818e927", size = 666870, upload-time = "2026-07-22T12:26:46.691Z" }, - { url = "https://files.pythonhosted.org/packages/2d/8a/7e6dee25cb8a8cf9b362c8e597cc269593378bd916f16c736c059a52e85a/greenlet-3.5.4-cp315-cp315-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:99e8f8c4ebc4fd80aa26c1280ae9ad43a0976e786349703a181cf0bae60413e5", size = 677678, upload-time = "2026-07-22T12:29:07.508Z" }, - { url = "https://files.pythonhosted.org/packages/6c/21/5a38699fa45de749e3857d93b8f07e4c20489e77c2d35d915a2e1c456606/greenlet-3.5.4-cp315-cp315-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:394de08dad5ffcb1f50c2159d93e398d9d2da3ed437645eaa54771fa720db9f0", size = 676067, upload-time = "2026-07-22T11:51:18.163Z" }, - { url = "https://files.pythonhosted.org/packages/5e/ba/863116ab8ff1ca7a729e327800268939d182db47aa433db70e216e7d9194/greenlet-3.5.4-cp315-cp315-musllinux_1_2_aarch64.whl", hash = "sha256:c883d61f2282d72c767a14936641b3efcbde9d82f1080712aaea0b1d3126cb88", size = 1633489, upload-time = "2026-07-22T12:25:09.605Z" }, - { url = "https://files.pythonhosted.org/packages/fa/06/7466ced82818d6132462d7f26b3f83c66ea15d2b193a6c0088d558ed7d95/greenlet-3.5.4-cp315-cp315-musllinux_1_2_x86_64.whl", hash = "sha256:2a924f15d17957e252a810acefcb5942f5ca712298e8b6fcaed9a307d357522c", size = 1696584, upload-time = "2026-07-22T11:51:21.304Z" }, - { url = "https://files.pythonhosted.org/packages/f9/4d/55b638489260065de9ffce606c8b5d04507bef705de4b212a0c3d6a1a0df/greenlet-3.5.4-cp315-cp315-win_amd64.whl", hash = "sha256:ed17e5f3420360d5b459de8462efb52060399a5326a613d4cde31cef63ef95da", size = 248297, upload-time = "2026-07-22T11:42:04.055Z" }, - { url = "https://files.pythonhosted.org/packages/bb/08/9dd4ae635da93d41dc268bc34bd62a9d711ed8b8825c5d22ac910c7d6e6d/greenlet-3.5.4-cp315-cp315-win_arm64.whl", hash = "sha256:f908898d6fa484ce4b6f447ce70ea99b52c503fee419e53cf74d60a16bc9e667", size = 247423, upload-time = "2026-07-22T11:44:00.764Z" }, - { url = "https://files.pythonhosted.org/packages/19/66/7c87ed9cdbf1d49c2c6cd1c7b9dd4d16c33b24235ca03972293a1876b30c/greenlet-3.5.4-cp315-cp315t-macosx_11_0_universal2.whl", hash = "sha256:1833637f17d5e7472548a48575c394fe39f1b1890d676d162d86593610f44d8c", size = 306487, upload-time = "2026-07-22T11:41:25.118Z" }, - { url = "https://files.pythonhosted.org/packages/5b/05/0a4201e7c0054866eefc05da234f236dd4c950d0fbf9ca0517141f01b269/greenlet-3.5.4-cp315-cp315t-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:12cda9122e03341f1cb6b8207a19d7a9d375e52f1b4e9243918375f40fd7b4b9", size = 676479, upload-time = "2026-07-22T12:26:48.129Z" }, - { url = "https://files.pythonhosted.org/packages/3d/c0/4b6b8c5a3aec70f0649cd89662d120fdd6421e2bdc8e3b15c3ab5ec568d8/greenlet-3.5.4-cp315-cp315t-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:d83ae0e32d14957ab7170785a20f582635c8474deab1bfbb552b17e769a6ce25", size = 684321, upload-time = "2026-07-22T12:29:08.925Z" }, - { url = "https://files.pythonhosted.org/packages/24/c9/b49c31c9a972eee91e260445770e922244a7efc542697f51a012ec046d0f/greenlet-3.5.4-cp315-cp315t-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:9f1467de1bb767f75db0aa34c195e3a496d8d1278c796e70c24ce205d3e99cde", size = 681293, upload-time = "2026-07-22T11:51:20.43Z" }, - { url = "https://files.pythonhosted.org/packages/95/6f/7f2d4653770500eee667866016d42d7a68e3d3462f80df6b8e3fcd48a0eb/greenlet-3.5.4-cp315-cp315t-musllinux_1_2_aarch64.whl", hash = "sha256:0fa53040b78b578120eecdc0265e3f1051487cc425d11a2b7c761daadf4feaa8", size = 1642474, upload-time = "2026-07-22T12:25:10.819Z" }, - { url = "https://files.pythonhosted.org/packages/5a/d8/8cba31036a4caae448087ba5d150660ab03b4a0f54d9150f6495a3be7262/greenlet-3.5.4-cp315-cp315t-musllinux_1_2_x86_64.whl", hash = "sha256:60e0bc961d367df506660e9ac0177a76bc6d81305300704b0977d1634f76efe2", size = 1701012, upload-time = "2026-07-22T11:51:23.17Z" }, - { url = "https://files.pythonhosted.org/packages/e3/cd/3f77a4cce3bae631b08eb52f53a82a976669600337e21dfdba811cb50267/greenlet-3.5.4-cp315-cp315t-win_amd64.whl", hash = "sha256:f680e549edb3eaf21eea4e7fe101e15ec180c74b7879ab46adc080f22d4015d2", size = 251977, upload-time = "2026-07-22T11:41:38.125Z" }, - { url = "https://files.pythonhosted.org/packages/93/e8/65e8707d00fe2a49bf12f609a9b2b39ba6dd23c2810eacad877c4fc94bfe/greenlet-3.5.4-cp315-cp315t-win_arm64.whl", hash = "sha256:08fc36de8442d5c3e95b044550dbea9bf144d31ec0cc58e36fb241cb6ef6a994", size = 250538, upload-time = "2026-07-22T11:40:17.985Z" }, +version = "3.5.3" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/e2/f1/fbbfef6af0bad0548f09bc28948ea3c275b4edb19e17fc5ca9900a6a634d/greenlet-3.5.3.tar.gz", hash = "sha256:a61efc018fd3eb317eeca31aba90ee9e7f26f22884a79b6c6ec715bf71bb62f1", size = 200270, upload-time = "2026-06-26T19:28:24.832Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/5d/6e/4c37d51a2b7f82d2ff11bb6b5f7d766d9a011726624af255e843727627a3/greenlet-3.5.3-cp312-cp312-macosx_11_0_universal2.whl", hash = "sha256:719757059f5a53fd0dde23f78cffeafcdd97b21c850ddb7ca684a3c1a1f122e2", size = 288685, upload-time = "2026-06-26T18:22:08.977Z" }, + { url = "https://files.pythonhosted.org/packages/7a/73/815dd90131c1b71ebdf53dbc7c276cafec2a1173b97559f97aba72724a87/greenlet-3.5.3-cp312-cp312-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:efa9f765dd09f9d0cdac651ffdf631ee59ec5dc6ee7a73e0c012ba9c52fbdf5b", size = 604761, upload-time = "2026-06-26T19:07:10.114Z" }, + { url = "https://files.pythonhosted.org/packages/9f/57/079cfe76bcef36b153b25607ee91c6fcb58f17f8b23c86bbbeabe0c88d72/greenlet-3.5.3-cp312-cp312-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:7faba15ac005376e02a0384504e0243be3370ce010296a44a820feb342b505ab", size = 617044, upload-time = "2026-06-26T19:10:07.25Z" }, + { url = "https://files.pythonhosted.org/packages/37/87/b4d095775a3fb1bcafbb483fc206b27ebb785724c83051447737085dc54e/greenlet-3.5.3-cp312-cp312-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:87142215824be6ac05e2e8e2786eec307ccbc27c36723c3881959df654af6861", size = 614244, upload-time = "2026-06-26T18:32:17.594Z" }, + { url = "https://files.pythonhosted.org/packages/8a/70/7559b609683650fa2b95b8ab84b4ab0b26556a635d19675e12aa832d826d/greenlet-3.5.3-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:215275b1b49320987352e6c1b054acca0064f965a2c66992bed9a6f7d913f149", size = 1574210, upload-time = "2026-06-26T19:09:03.077Z" }, + { url = "https://files.pythonhosted.org/packages/ae/73/be55392074c60fc37655ca40fa6022457bfbf6718e9e342a7b0b41f96dd2/greenlet-3.5.3-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:6b1b0eed82364b0e32c4ea0f221452d33e6bb17ae094d9f72aed9851812747ea", size = 1638627, upload-time = "2026-06-26T18:31:44.748Z" }, + { url = "https://files.pythonhosted.org/packages/14/40/c57489acf8e37d74e2913d4eff63aa0dba17acccc4bdeef874dde2dbbec9/greenlet-3.5.3-cp312-cp312-win_amd64.whl", hash = "sha256:cde8adafa2365676f74a979744629589999093bc86e2484214f58e61df08902c", size = 239882, upload-time = "2026-06-26T18:23:27.518Z" }, + { url = "https://files.pythonhosted.org/packages/71/fd/6fea0e3d6600f785069481ee637e09378dd4118acdfd38ad88ae2db31c98/greenlet-3.5.3-cp312-cp312-win_arm64.whl", hash = "sha256:c4e7b79d83805475f0102008843f6eb45fd3bb0b2e88c774adab5fbaab27117d", size = 238211, upload-time = "2026-06-26T18:22:37.671Z" }, + { url = "https://files.pythonhosted.org/packages/9b/ff/a620267401db30a50cc8450ee90730e2d4a85658c055c0e760d4ed47fb13/greenlet-3.5.3-cp313-cp313-macosx_11_0_universal2.whl", hash = "sha256:c8d87c2134d871df96ecdea9cec7cbaab286dadab0f56476e57aaf9e8ac11550", size = 287609, upload-time = "2026-06-26T18:21:14.724Z" }, + { url = "https://files.pythonhosted.org/packages/d6/fa/5401ac78021c826a25b6dde0c705e0a8f29b617509f9185a31dac15fbe1b/greenlet-3.5.3-cp313-cp313-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:a2d185dd1621757e70c3861cceffd5317ab4e7ed7eb09c82994828468527ade5", size = 607435, upload-time = "2026-06-26T19:07:11.412Z" }, + { url = "https://files.pythonhosted.org/packages/e9/76/1dc144a2e56e65d36405078ed774224375ea520a1870a6e46e08bb4ac7bf/greenlet-3.5.3-cp313-cp313-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:1c514a468149bf8fbbab874188a3535cd8a48a3e353eb53a3d424296f8dbacd3", size = 619787, upload-time = "2026-06-26T19:10:08.396Z" }, + { url = "https://files.pythonhosted.org/packages/bf/87/c298cee62df1de4ad7fec32abda73526cff347fd143a6ed4ac369246668a/greenlet-3.5.3-cp313-cp313-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:915f887cf2682b66419b879423a2e072634aa7b7dce6f3ada4957cfced3f1e9a", size = 616786, upload-time = "2026-06-26T18:32:19.128Z" }, + { url = "https://files.pythonhosted.org/packages/9e/2e/e6f009885ed0705ccf33fe0583c117cfd03cde77e31a596dd5785a30762b/greenlet-3.5.3-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:766cfd421c13e450feb340cd472a3ed9957d438727b7b4593ad7c76c5d2b0deb", size = 1574316, upload-time = "2026-06-26T19:09:04.273Z" }, + { url = "https://files.pythonhosted.org/packages/ef/fe/43fd110b01e40da0adb7c90ac7ea744bef2d43dca00de5095fd2351c2a68/greenlet-3.5.3-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:2ecda9ec22edf38fa389369eaed8c3d37c05f3c54e69f69438dbb2cc1de1458b", size = 1638614, upload-time = "2026-06-26T18:31:46.297Z" }, + { url = "https://files.pythonhosted.org/packages/0f/7c/062447147a61f8b4337b156fe70d32a165fcf2f89d7ca6255e572806705c/greenlet-3.5.3-cp313-cp313-win_amd64.whl", hash = "sha256:c82304750f057167ff60d188df1d0cc1764ce9567eadf03e6a7443bcedd0b30b", size = 239850, upload-time = "2026-06-26T18:21:54.613Z" }, + { url = "https://files.pythonhosted.org/packages/c7/7e/220a7f5824a64a60443fc03b39dfac4ea63a7fb6d481efa27eafa928e7f4/greenlet-3.5.3-cp313-cp313-win_arm64.whl", hash = "sha256:dc133a1569ee667b2a6ef56ce551084aeefd87a5acbc4736d336d1e2edc6cfc4", size = 238141, upload-time = "2026-06-26T18:22:48.507Z" }, + { url = "https://files.pythonhosted.org/packages/c3/93/43e116ee114b28737ba7e12952a0d4e2f55944d0f84e42bc91ba7192a3c9/greenlet-3.5.3-cp314-cp314-macosx_11_0_universal2.whl", hash = "sha256:fd2e02fa07485778536a036222d616ab957b1d533f36b3ed98ce725d9c9d3117", size = 288202, upload-time = "2026-06-26T18:23:49.604Z" }, + { url = "https://files.pythonhosted.org/packages/82/2f/146d218299046a43d1f029fd544b3d110d0f175a09c715c7e8da4a4a345d/greenlet-3.5.3-cp314-cp314-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:df0a0628d1597eb0897b62f55d1343f772405fd25f3b2a796c76874b0c2e22e8", size = 654096, upload-time = "2026-06-26T19:07:12.71Z" }, + { url = "https://files.pythonhosted.org/packages/a0/cc/04738cafb3f45fa991ea44f9de94c47dcec964f5a972300988a6751f49d9/greenlet-3.5.3-cp314-cp314-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:ebd933a6adabc298bab47731a130fe6bfb888bd934eee37810f151159544540d", size = 666304, upload-time = "2026-06-26T19:10:09.503Z" }, + { url = "https://files.pythonhosted.org/packages/ce/aa/4e0dad5e605c270c784ab911c43da6adb136ccd4d81180f763ca429a723d/greenlet-3.5.3-cp314-cp314-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:4b9d501b40e80b70e32323c799dd9b420a5577a9601469d362ae1ffb690f3a7c", size = 663635, upload-time = "2026-06-26T18:32:20.802Z" }, + { url = "https://files.pythonhosted.org/packages/d1/50/13efdbea246fe3d3b735e191fec08fb50809f53cd2383ebe123d0809e44b/greenlet-3.5.3-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:a1fad1d11e7d6aab184107baa8e4ece11ccba3ec9599cd7efa5ff4d70d43256a", size = 1621252, upload-time = "2026-06-26T19:09:05.647Z" }, + { url = "https://files.pythonhosted.org/packages/f7/22/c0a336ae4a1410fd5f5121098e5bfbf1865f64c5ef80b4b5412886c4a332/greenlet-3.5.3-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:fad5aec764399f1b5cc347ad250a59660f20c8f8888ea6bae1f93b769cce1154", size = 1684824, upload-time = "2026-06-26T18:31:47.738Z" }, + { url = "https://files.pythonhosted.org/packages/7a/94/91aec0030bea75c4b3244251d0de60a1f3432d1ecb53ab6c437fb5c3ba61/greenlet-3.5.3-cp314-cp314-win_amd64.whl", hash = "sha256:7669aa24cf2a1041d6f7899575b494a3ab4cf68bfcc8609b1dc0be7272db835e", size = 240754, upload-time = "2026-06-26T18:22:15.669Z" }, + { url = "https://files.pythonhosted.org/packages/e5/06/68d0983e79e02138f64b4d303c500c27ddb48e5e77f3debb80888a921eae/greenlet-3.5.3-cp314-cp314-win_arm64.whl", hash = "sha256:5b4807c4082c9d1b6d9eed56fcd041863e37f2228106eef24c30ca096e238605", size = 239549, upload-time = "2026-06-26T18:22:42.996Z" }, + { url = "https://files.pythonhosted.org/packages/91/95/3e161213d7f1d378d15aa9e792093e9bfe01844680d04b7fd6e0107c9098/greenlet-3.5.3-cp314-cp314t-macosx_11_0_universal2.whl", hash = "sha256:271a8ea7c1024e8a0d7dd2be66dd66dda8a07193f41a17b9e924f7600f5b62be", size = 296389, upload-time = "2026-06-26T18:22:20.657Z" }, + { url = "https://files.pythonhosted.org/packages/00/92/715c44721abe2b4d1ae9abde4179411868a5bff312479f54e105d372f131/greenlet-3.5.3-cp314-cp314t-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:19131729ae0ddc3c2e1ef85e650169b5e37ee32e400f215f78b94d7b0d567310", size = 653382, upload-time = "2026-06-26T19:07:14.209Z" }, + { url = "https://files.pythonhosted.org/packages/a0/83/37a10372a1090a6624cca8e74c12df1a36c2dc36429ed0255b7fb1aeee23/greenlet-3.5.3-cp314-cp314t-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:1540dd8e5fc2a5aec40fbb98ef8e149fa47c89a4b4a1cf2575a14d3d1869d7a8", size = 659401, upload-time = "2026-06-26T19:10:10.876Z" }, + { url = "https://files.pythonhosted.org/packages/db/e2/d1509cad4207da559cc42986ecdd8fc67ad0d1bba2bf03023c467fd5e0f3/greenlet-3.5.3-cp314-cp314t-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:e81fa194a1d20967877bdf9c7794db2bc99063e5be36aee710c08f04c5bb087f", size = 656969, upload-time = "2026-06-26T18:32:22.272Z" }, + { url = "https://files.pythonhosted.org/packages/86/7d/eaf70de20aadca3a5884aec58362861c64ce45e7b277f47ed026926a3b89/greenlet-3.5.3-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:55cf4d777485d43110e47133cbba6d74a8885a87ec1227ef0267f9ee80c5aa21", size = 1617822, upload-time = "2026-06-26T19:09:06.893Z" }, + { url = "https://files.pythonhosted.org/packages/8a/f9/414d38fc400ae4350d4185eaad1827676f7cf5287b9136e0ed1cbbe20a7f/greenlet-3.5.3-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:12a248ba75f6a9a236375f52296c498c89ff1d8badf32deb9eca7abd5853f7da", size = 1677983, upload-time = "2026-06-26T18:31:49.396Z" }, + { url = "https://files.pythonhosted.org/packages/e4/15/7edb977e08f9bff702fe42d6c902702786ff6b9694058b4e6a2a6ac90e57/greenlet-3.5.3-cp314-cp314t-win_amd64.whl", hash = "sha256:efc6bd60ea02e085862c74a3ef64b147ffc6f1a5ea7d9f26e7a939943f68c1e3", size = 243626, upload-time = "2026-06-26T18:24:41.485Z" }, + { url = "https://files.pythonhosted.org/packages/2c/8a/93928dce91e6b3598b5e779e8d1fd6576a504640c58e78627077f6a7a91a/greenlet-3.5.3-cp315-cp315-macosx_11_0_universal2.whl", hash = "sha256:ea03f2f04367845d6b58eeed276e1e56e51f0b97d8ad5a88a7d20a91dc9056cc", size = 288860, upload-time = "2026-06-26T18:22:48.07Z" }, + { url = "https://files.pythonhosted.org/packages/4f/ca/69db42d447a1378043e2c8f19c09cbbd1263371505053c496b49066d3d16/greenlet-3.5.3-cp315-cp315-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:78dbef602fda6d97d957eb7937f70c9ce9e9527330347f8f6b6f9e554a9e7a47", size = 659747, upload-time = "2026-06-26T19:07:15.565Z" }, + { url = "https://files.pythonhosted.org/packages/a8/0b/af7ac2ef8dd41e3da1a40dda6305c23b9a03e13ba975ec916357b50f8575/greenlet-3.5.3-cp315-cp315-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:6f73857adb8fee13fa56c172bd11262f888c0c648f9fea113e777bb2c7904a81", size = 670419, upload-time = "2026-06-26T19:10:12.293Z" }, + { url = "https://files.pythonhosted.org/packages/51/1e/1d51640cacbfc455dbe9f9a9f594c49e4e244f63b9971a2f4764e46cc53d/greenlet-3.5.3-cp315-cp315-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:232fec92e823addaf02d9472cf7381e24a1d046a6ced1103c5caa4c21b9dfc1d", size = 668787, upload-time = "2026-06-26T18:32:24.298Z" }, + { url = "https://files.pythonhosted.org/packages/21/66/4030d5b0b5894500023f003bb054d9bb354dfbd1e186c3a296759172f5f5/greenlet-3.5.3-cp315-cp315-musllinux_1_2_aarch64.whl", hash = "sha256:2421c3564da9429d5586d46ca31ebb26516b5498a802cf65c041a8e8a8980d34", size = 1626305, upload-time = "2026-06-26T19:09:08.281Z" }, + { url = "https://files.pythonhosted.org/packages/0e/50/5221371c7550108dfa3c378debc41d032aa9c78e89abb01d8011cfc93289/greenlet-3.5.3-cp315-cp315-musllinux_1_2_x86_64.whl", hash = "sha256:e0f0d160f0b2e558e6c75f7930967183255dc9735e5f5b8cae58ee09c9576d8b", size = 1688631, upload-time = "2026-06-26T18:31:51.278Z" }, + { url = "https://files.pythonhosted.org/packages/68/5d/00d469daae3c65d2bf620b10eee82eb022127d483c6bc8c69fae6f3fbf17/greenlet-3.5.3-cp315-cp315-win_amd64.whl", hash = "sha256:dd99329bbc15ca78dcc583dba05d0b1b0bae01ab6c2174989f5aaee3e41ac930", size = 241027, upload-time = "2026-06-26T18:22:38.203Z" }, + { url = "https://files.pythonhosted.org/packages/e7/e8/883785b44c5780ed71e83d3e4437e710470be17a2e181e8b601e2da0dc4a/greenlet-3.5.3-cp315-cp315-win_arm64.whl", hash = "sha256:499fef2acede88c1864a57bb586b4bf533c81e1b82df7ab93451cdb47dfec227", size = 240085, upload-time = "2026-06-26T18:23:54.217Z" }, + { url = "https://files.pythonhosted.org/packages/1c/da/4f4a8450962fad137c1c8981a3f1b8919d06c829993d4d476f9c525d5173/greenlet-3.5.3-cp315-cp315t-macosx_11_0_universal2.whl", hash = "sha256:176bc16a721fa5fc294d70b87b4dfa5fbdd251b3da5d5372735ecef9bd7d6d0c", size = 297221, upload-time = "2026-06-26T18:23:27.176Z" }, + { url = "https://files.pythonhosted.org/packages/57/66/b3bfae3e220a9b63ea539a0eea681800c69ab1aada757eae8789f183e7ce/greenlet-3.5.3-cp315-cp315t-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:629b614d2b786e89c50440e246f33eea78f58a962d0bdbbcc809e6d13605903f", size = 657221, upload-time = "2026-06-26T19:07:16.973Z" }, + { url = "https://files.pythonhosted.org/packages/7b/81/b6d4d73a709684fc77e7fa034d7c2fe82cffa9fc920fadcaa659c2626213/greenlet-3.5.3-cp315-cp315t-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:2b2e857ae16f5f72142edf75f9f176fe7526ba19a2841df1420516f83831c9f2", size = 663226, upload-time = "2026-06-26T19:10:13.723Z" }, + { url = "https://files.pythonhosted.org/packages/f5/07/e210b02b589f16e74ff48b730690e4a34ffe984219fce4f3c1a0e7ec8545/greenlet-3.5.3-cp315-cp315t-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:e515757e2e36bcbf1fad09a46e1557e8b1ae1797d4b44d09da7deed88ad28608", size = 660802, upload-time = "2026-06-26T18:32:26.081Z" }, + { url = "https://files.pythonhosted.org/packages/eb/2e/5303eb3fa06bca089060f479707182a93e360683bc252acf846c3090d34e/greenlet-3.5.3-cp315-cp315t-musllinux_1_2_aarch64.whl", hash = "sha256:b363d46ed1ea431825fdb01471bb024fc08399bad1572a616e853c7684415adb", size = 1622157, upload-time = "2026-06-26T19:09:09.527Z" }, + { url = "https://files.pythonhosted.org/packages/54/70/50de47a488f14df260b50ae34fb5d56016e308b098eab02c878b5223c26a/greenlet-3.5.3-cp315-cp315t-musllinux_1_2_x86_64.whl", hash = "sha256:e44da2f5bbdaabaf7d80b73dbb430c7035771e9f244e3c8b769715c9d8fa0a16", size = 1681159, upload-time = "2026-06-26T18:31:52.986Z" }, + { url = "https://files.pythonhosted.org/packages/a7/13/1055e1dda7882073eda533e2b96c62e55bbd2db7fda6d5ece992febc7071/greenlet-3.5.3-cp315-cp315t-win_amd64.whl", hash = "sha256:8ff8bed3e3baa20a3ea261ce00526f1898ad4801d4886fd2220580ee0ad8fadf", size = 244007, upload-time = "2026-06-26T18:22:04.353Z" }, + { url = "https://files.pythonhosted.org/packages/b4/0d/ca7d15afbdc397e3401134c9e1800d51d12b829661786187a4ad08fe484f/greenlet-3.5.3-cp315-cp315t-win_arm64.whl", hash = "sha256:b7068bd09f761f3f5b4d214c2bed063186b2a86148c740b3873e3f56d79bac31", size = 242586, upload-time = "2026-06-26T18:23:37.93Z" }, ] [[package]] @@ -1381,48 +1385,54 @@ wheels = [ [[package]] name = "pandas" -version = "3.0.5" +version = "3.0.3" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "numpy" }, { name = "python-dateutil" }, { name = "tzdata", marker = "sys_platform == 'emscripten' or sys_platform == 'win32'" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/be/4f/5f3422a2afec5ffc46308b79e53291365a93748b498ac2e58bead0197916/pandas-3.0.5.tar.gz", hash = "sha256:dca3734d6ab7c906e6730f0788b0a1dbb9f2467731f9711f77995c8e9d62d712", size = 4658219, upload-time = "2026-07-22T22:19:28.819Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/1c/54/1dc810ea558d1320b597aa140a514f2fdf1d2ea09c38cf556f13ea712ec9/pandas-3.0.5-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:fa290c16964d4963fbfbc358928239cf3bd755b20e988ce944877def2f44471d", size = 10411717, upload-time = "2026-07-22T22:18:08.307Z" }, - { url = "https://files.pythonhosted.org/packages/68/56/fbe81c09195924d8b7b8d4461a20458fe80a6a5ed6b24f0314da684277e1/pandas-3.0.5-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:c2e26bb46934b8a2ca0c3de1d3d606fc5f6746584791b2db264d58cf370e08dc", size = 9957095, upload-time = "2026-07-22T22:18:10.6Z" }, - { url = "https://files.pythonhosted.org/packages/e0/51/fac252f4a913ed5eabf3c11b880a9e8d5a6c10f0b2129d0462212d238b4d/pandas-3.0.5-cp312-cp312-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:73fa87b08a7ef706f8aafda39ddaccf2a99047bea62d8c88a0361bcafb2237bc", size = 10485458, upload-time = "2026-07-22T22:18:12.834Z" }, - { url = "https://files.pythonhosted.org/packages/12/98/e976540c1addf70442be7842a18cf70884a964abbf69442504f4d2939989/pandas-3.0.5-cp312-cp312-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:d373ce03ffd84010ed9839fa73672a9c8256990532e158440c0085db7d914b34", size = 10998091, upload-time = "2026-07-22T22:18:15.209Z" }, - { url = "https://files.pythonhosted.org/packages/a4/8c/1f29b5be8d3fc47dd7567eb167fabba2085879b31e0287ce7cba6d3d2ff4/pandas-3.0.5-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:2a29c53d85ea98c5e792c59ef82ee9fbe6ca902c0d0adb6b23f45ef894cd7bf6", size = 11499501, upload-time = "2026-07-22T22:18:17.689Z" }, - { url = "https://files.pythonhosted.org/packages/9d/e2/bd9c98ad2df7b38bde002adde4cdf353519da51881634323b126c55997f9/pandas-3.0.5-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:a5ad3b02ed6bc7d7ae9b70804b2c6aa31827489d150f8e623ce82491b82085d7", size = 12060559, upload-time = "2026-07-22T22:18:20.147Z" }, - { url = "https://files.pythonhosted.org/packages/f3/9a/ffbd852d58bd74a617fe2f8ee6a58a96982271ce41cf981eab22190b4a4b/pandas-3.0.5-cp312-cp312-pyemscripten_2024_0_wasm32.whl", hash = "sha256:b2acb4650527eec6822c3dadb2b771277b65e7dae7a267d4bccf65fd1bb3fbce", size = 7197652, upload-time = "2026-07-22T22:18:22.502Z" }, - { url = "https://files.pythonhosted.org/packages/70/b5/d2d3e9ae73362ba4229651b0ee1455cf78073a1ce585f6ff693782ce263e/pandas-3.0.5-cp312-cp312-win_amd64.whl", hash = "sha256:80a611068e8a3ac23f7398c6c14eb46dc974e5cc9997f653e2dcfd1da74edd41", size = 9831691, upload-time = "2026-07-22T22:18:24.534Z" }, - { url = "https://files.pythonhosted.org/packages/52/51/dea1e89d6a6796b9c43f85a09b484ee03edb8a4c4842e73e200a8c11301c/pandas-3.0.5-cp312-cp312-win_arm64.whl", hash = "sha256:25ff585b972a18ef1fe9ffa3ac6544d9950508aa76832e5147640b6022821e49", size = 9105796, upload-time = "2026-07-22T22:18:27.064Z" }, - { url = "https://files.pythonhosted.org/packages/bf/09/7b95c4a0025227d6f118c4039b423412ac6a982db02864166185d812fbc7/pandas-3.0.5-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:c1c05a767fe8e5b4fe9e1c29806829c582052eaedb9120a3da83ba3f69e24a5b", size = 10385742, upload-time = "2026-07-22T22:18:29.346Z" }, - { url = "https://files.pythonhosted.org/packages/8d/0c/dc78fd8c4da477b4b5e8ad37295af352190d21ef63a9ee1bc071753074cc/pandas-3.0.5-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:b86765f268b56f7e665b93bce9d5df69dee7f99e595cf8fb839483ab315942a3", size = 9932067, upload-time = "2026-07-22T22:18:31.833Z" }, - { url = "https://files.pythonhosted.org/packages/3e/71/3592c055cf44df9808550f9368ceda80ff2b224d355ef73fe251dcda1802/pandas-3.0.5-cp313-cp313-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:c597ecf5616b5c420372c1d4d4c00dbbfba7398bea857dcc984347e1ea48417b", size = 10466756, upload-time = "2026-07-22T22:18:34.195Z" }, - { url = "https://files.pythonhosted.org/packages/e3/70/4363150359f95b4cb4bcbb34ca23572bb5495749a621a8f3d5a1ddfd293c/pandas-3.0.5-cp313-cp313-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:4b11c36e218331d0387cbe3a0a5f75162357a1d92d57b2b08a336ff94b19b2be", size = 10938525, upload-time = "2026-07-22T22:18:36.81Z" }, - { url = "https://files.pythonhosted.org/packages/f7/d0/317e7a0c67c0e69fa905a0161409397a7dc2d46ff611f6ca4803352c042b/pandas-3.0.5-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:cf52e1f61d229496da17dc7ab54acdee627357e7008fd4fecba3d0ba2937fa58", size = 11489303, upload-time = "2026-07-22T22:18:39.287Z" }, - { url = "https://files.pythonhosted.org/packages/f1/8d/36dade89b49e4f9d5cbdbe863772581f98c0c6d78fc39ad4c557f6f2e17e/pandas-3.0.5-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:db172144bb56422bd157812f3b021eacc255451470b31e2c633c349490a1cfee", size = 11989004, upload-time = "2026-07-22T22:18:42.208Z" }, - { url = "https://files.pythonhosted.org/packages/9c/ba/18c4ec8a746e177da05a9e7a7963781d8ea195780724f854601b6ebd6b78/pandas-3.0.5-cp313-cp313-win_amd64.whl", hash = "sha256:0d298e951f23016ce4699951d044ae6418dbc91bf68cefca0f77666fcbb4e5c6", size = 9826896, upload-time = "2026-07-22T22:18:44.539Z" }, - { url = "https://files.pythonhosted.org/packages/de/ec/28a57266b753799a87b8bc79e7887ac6fd981b8c6d2978a0b7e7b6bd708c/pandas-3.0.5-cp313-cp313-win_arm64.whl", hash = "sha256:66266d3442a5e8b3c90274c2b8b230bee42dd1c286bc822cc2f9f2c7e12b883e", size = 9094790, upload-time = "2026-07-22T22:18:47.468Z" }, - { url = "https://files.pythonhosted.org/packages/51/2f/cf6aae281264f4463f0875bcbb15fd2bb6d291cc535187dad1732475e4a9/pandas-3.0.5-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:2f264fc46911cc8131a7322a16199bbf8e353d27c10bb211f5bd0c814324dc36", size = 10390034, upload-time = "2026-07-22T22:18:49.818Z" }, - { url = "https://files.pythonhosted.org/packages/06/ec/5189518c7a7659c4bdcc6b1eb32c46c6f3c86b0661ffd84143d1112c7732/pandas-3.0.5-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:53730687fcd161883b24e10411c06d6a4c0f2275d2faf3bb2bc25deb4ba8007c", size = 9980065, upload-time = "2026-07-22T22:18:52.249Z" }, - { url = "https://files.pythonhosted.org/packages/ea/f1/598503ce8d7e3c35601e0747ba288c7864baae66380725bc12f13f884dfe/pandas-3.0.5-cp314-cp314-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:960d3ebcf249f75206899fcd2c6de53f736b7265759ced0d3e559df0b8b709b0", size = 10545532, upload-time = "2026-07-22T22:18:54.813Z" }, - { url = "https://files.pythonhosted.org/packages/fa/de/ceae2adf7034e07e9910299fe412e1819c4f0dd520700a888bcb03625448/pandas-3.0.5-cp314-cp314-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:9e94c2c5ca43bd3ca32bf64d32308887b65e5f9bfd8023ea52755107a999f93b", size = 10963120, upload-time = "2026-07-22T22:18:57.42Z" }, - { url = "https://files.pythonhosted.org/packages/66/25/86e0f4451874eb79e688deeebe3c451fec4557f8952005818d800ee8ac7e/pandas-3.0.5-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:e819dd5f62966b481a8cb649d3299ebd886a1ea91ed5a99bf7ce77c98d18ab94", size = 11563178, upload-time = "2026-07-22T22:18:59.729Z" }, - { url = "https://files.pythonhosted.org/packages/f3/45/8643daa3b4147e433adfcccefdd0380d3aad79d86b15d8999730fe1944d5/pandas-3.0.5-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:3c5ed2e7c06e91d340dfd091d7934f9bc82e4a36b95f647f090b9d1c9ac649da", size = 12028708, upload-time = "2026-07-22T22:19:02.164Z" }, - { url = "https://files.pythonhosted.org/packages/96/58/ad979ae617615576e8aafd569c9d4b62f1191d896e38f51d66ba06f3b89a/pandas-3.0.5-cp314-cp314-win_amd64.whl", hash = "sha256:cd8f7c6dc98527058ee6264219343f5392240a6f1bfa654fc5d79023020d0c92", size = 9951806, upload-time = "2026-07-22T22:19:04.596Z" }, - { url = "https://files.pythonhosted.org/packages/69/32/7ac03886b304049a9d2625ee88f59af760d8a93bd30ed9239bce7b9869a8/pandas-3.0.5-cp314-cp314-win_arm64.whl", hash = "sha256:5183427f5a8156d480f30333777bc978be93650a49a7c01db26adffe95b31e85", size = 9238297, upload-time = "2026-07-22T22:19:06.836Z" }, - { url = "https://files.pythonhosted.org/packages/be/ed/1d1f2ee5547d5167face2376d11c8b2a4c7bfff5a416ee7a9046891fab1e/pandas-3.0.5-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:303da736987d481074ca720ada325f8bd80c64ebc2d45ed79b29df3aaa4a26ca", size = 10849690, upload-time = "2026-07-22T22:19:09.391Z" }, - { url = "https://files.pythonhosted.org/packages/57/55/17e17152e98fbb0c4b1e562bc65387a2f20a80db0f4a86bf8d3a0e4248d4/pandas-3.0.5-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:3b2801bbb049d0136f6c213eae02b5fca969384fc2064dd728d8620552aa49da", size = 10509945, upload-time = "2026-07-22T22:19:11.773Z" }, - { url = "https://files.pythonhosted.org/packages/88/90/817d44dbf83facf9556f33576d9af0a241981e7bb5c00606c0bcb5df8dda/pandas-3.0.5-cp314-cp314t-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:cce3a9d11d2b1f82c69a27ec1f4948a170e2c403c4bbfa8cca62e3fdebe2ef3a", size = 10392197, upload-time = "2026-07-22T22:19:14.024Z" }, - { url = "https://files.pythonhosted.org/packages/f1/da/889f00c0a6f5aa1545add70abbf01502dff87ab577adb855bd631c54d2f2/pandas-3.0.5-cp314-cp314t-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:ef01af4d8dc6cd2c8d6c7736f149574ef93fe043811eeb5e445f2647154b5040", size = 10862726, upload-time = "2026-07-22T22:19:16.351Z" }, - { url = "https://files.pythonhosted.org/packages/bc/98/f1e934fb3c98fce859c6147c6785816c7b5b9ab7821115c5d8c4de9842b9/pandas-3.0.5-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:e2759e890db96dfcffdbd9b86c3c2cb6afaf58def482820317e06163ec1066cd", size = 11414864, upload-time = "2026-07-22T22:19:18.981Z" }, - { url = "https://files.pythonhosted.org/packages/fe/be/d448af7d657d82e1888dd8551f79c6d6fb161080b5b9752d84d910ec2319/pandas-3.0.5-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:b58b1b39d46a5862e3fb18f50d1a201398619d16a0f9f73f57eea5583cf0e63c", size = 11925105, upload-time = "2026-07-22T22:19:21.515Z" }, - { url = "https://files.pythonhosted.org/packages/29/c1/ccb4238212c8c4f496c584f3044d94e0c030ed8e1d68999db46c91c2242f/pandas-3.0.5-cp314-cp314t-win_amd64.whl", hash = "sha256:1c10461f6eeb35d8f05b6184c65c8b9991663b66c46b1d559b682cb34ae7c6ea", size = 10387612, upload-time = "2026-07-22T22:19:24.257Z" }, - { url = "https://files.pythonhosted.org/packages/d2/cf/6a51b2c38980e04c279fd2fa908a1b0982064e860444acfca4ec2e2c8359/pandas-3.0.5-cp314-cp314t-win_arm64.whl", hash = "sha256:3c5015fd1730fbf883647e88068176c839c102cea883ba1769a6f4593bfc1f8c", size = 9509776, upload-time = "2026-07-22T22:19:26.694Z" }, +sdist = { url = "https://files.pythonhosted.org/packages/f8/87/4341c6252d1c47b08768c3d25ac487362bf403f0313ddae4a2a26c9b1b4c/pandas-3.0.3.tar.gz", hash = "sha256:696a4a00a2a2a35d4e5deb3fc946641b96c944f02230e4f76137fe35d806c4fc", size = 4651414, upload-time = "2026-05-11T18:54:29.21Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/24/f1/392f8c5bfc16f66a0d2d41561c01627c228fe7ed2a0d056ef11315042570/pandas-3.0.3-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:fed2ff7fd9779120e388e285fc029bd5cf9490cdd2e4166a9ee22c0e49a9ab09", size = 10357846, upload-time = "2026-05-11T18:52:36.143Z" }, + { url = "https://files.pythonhosted.org/packages/cf/3d/b16412745651e855f357e5e66930248688378853a6e2698a214e331fba1f/pandas-3.0.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:b168fc218fd80a6cbdbdbc1a97ddc7889ed057d7eb45f50d866ceab5f39904c4", size = 9899550, upload-time = "2026-05-11T18:52:38.976Z" }, + { url = "https://files.pythonhosted.org/packages/31/a8/fa2535168fffcedf67f4f6de28d2dd903a747ca7c8ea6989451aaeb3a92f/pandas-3.0.3-cp312-cp312-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:0383c72c75cdcca61a9e116e611143902dbfd08bff356829c2f6d1cf40a9ca8c", size = 10412965, upload-time = "2026-05-11T18:52:41.915Z" }, + { url = "https://files.pythonhosted.org/packages/65/b6/09b01cdbc15224e2850365192d17b7bdebb8bdbd8780ed221fcdf0d9a515/pandas-3.0.3-cp312-cp312-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:6dc0b3fd2169c9157deed50b4d519553a3655c8c6a96027136d654592be973a9", size = 10894600, upload-time = "2026-05-11T18:52:45.02Z" }, + { url = "https://files.pythonhosted.org/packages/c9/a4/2eb28f2fccb4ced4a2c79ab2a5dee9ade1ebf44922ebad6fea158c9f95d4/pandas-3.0.3-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:7e65d5407dc0b394f509699650e4a2ec01c0514f21850f453fa60f3be79a5dbf", size = 11422824, upload-time = "2026-05-11T18:52:48.058Z" }, + { url = "https://files.pythonhosted.org/packages/f8/45/830bb57f533a4604b355e07edcb8ea18cf88b5f94e5fca92f27052d7c597/pandas-3.0.3-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:f8894dc474d648fe7b6ff0ca9b0bd73950d19952bc1a6534540762c5d79d305c", size = 11950889, upload-time = "2026-05-11T18:52:50.905Z" }, + { url = "https://files.pythonhosted.org/packages/b9/c5/fc1b368f303087d20e8c9bf3d6ceb186263cfac0ade735cd938538bea839/pandas-3.0.3-cp312-cp312-win_amd64.whl", hash = "sha256:c7be265b62cef88e253a941e4698604973736dcfe242fdb5198f0f7bc473cdcc", size = 9755463, upload-time = "2026-05-11T18:52:53.386Z" }, + { url = "https://files.pythonhosted.org/packages/86/bd/fda8f9705b1b09c6ebe14bfc0fa0e4ec8584d54ea673628f157ff55131af/pandas-3.0.3-cp312-cp312-win_arm64.whl", hash = "sha256:557409bc4178e70ee8d9ddb494798e51ebf6ea59330f6be22c51bab2a7db6c49", size = 9066158, upload-time = "2026-05-11T18:52:56.038Z" }, + { url = "https://files.pythonhosted.org/packages/c5/90/62d8302883c44308c477e222c3daf7c813a34c8e96985882fbd53d964352/pandas-3.0.3-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:67b3b64c11910cfa29f4e94a14d3bff9ee693b6fc76055e7cad549cee0aec5fa", size = 10331071, upload-time = "2026-05-11T18:52:58.838Z" }, + { url = "https://files.pythonhosted.org/packages/7f/ae/6a6493c783a101f165e4356953ba3c74d6f77f0042fa7d753da9dfbb640c/pandas-3.0.3-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:39436b377d56d2a2e52d0395bdbee171f01068e99af5250509aceeb929f765c7", size = 9875690, upload-time = "2026-05-11T18:53:01.431Z" }, + { url = "https://files.pythonhosted.org/packages/62/7c/5df8e9f56c69a2769fbe9382a5ef8f2658c007e376434e1e2cbb57ad895f/pandas-3.0.3-cp313-cp313-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:d4be06d68f9ddcfc645b87534911da79a8fbffc7573c80e0edcf42a5020624d8", size = 10381634, upload-time = "2026-05-11T18:53:04.393Z" }, + { url = "https://files.pythonhosted.org/packages/99/68/1237369725aa617bb358263d535803e3053fdbc593513ec5ed9c9896b5b6/pandas-3.0.3-cp313-cp313-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:a4eeb6830daf35a71cc09649bd823e2b542dac246cdee9614c6e4bd65028cd6a", size = 10891243, upload-time = "2026-05-11T18:53:07.643Z" }, + { url = "https://files.pythonhosted.org/packages/25/93/77d108e8af7222b4a503ebde0e30215b1c2e4f8e53a526431890f22d5586/pandas-3.0.3-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:1928e07221f82db493cd4af1e23c1bfca524a19a4699887975bff68f49a72bfb", size = 11388659, upload-time = "2026-05-11T18:53:10.634Z" }, + { url = "https://files.pythonhosted.org/packages/d0/bd/eff5b4399f332ac386c853f6cd2bd3fa2ca0061b9f36ecd9c4d7c4265649/pandas-3.0.3-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:51b1fe551acb77dac643c6fda86084d8d446c10fe64b06a9cc29c4cc8540e7f2", size = 11942880, upload-time = "2026-05-11T18:53:13.536Z" }, + { url = "https://files.pythonhosted.org/packages/2c/20/559ace4200982c3887d0b86bfd0d856a2143ef8ddab63cc07934951a964c/pandas-3.0.3-cp313-cp313-win_amd64.whl", hash = "sha256:a82d532a3351d435432cd913edbccaf8b8e01d4dd0e5ced5a8d2e8ecd94c7e44", size = 9757091, upload-time = "2026-05-11T18:53:16.306Z" }, + { url = "https://files.pythonhosted.org/packages/3a/66/69055a09fe200f29f922a3eeec4804611900b95f52d932ece3393c3c0c19/pandas-3.0.3-cp313-cp313-win_arm64.whl", hash = "sha256:275c14e0fce14a2ec20eee474aecd305478ea3c1e6f6a9d8fe219a165542717e", size = 9057282, upload-time = "2026-05-11T18:53:18.768Z" }, + { url = "https://files.pythonhosted.org/packages/57/0e/efe801b0e6811e8e650cd21b7f2608e30f08a7067e2bf6e8752b0d56ee3c/pandas-3.0.3-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:46997386d528eb40376ecd6b033cf4a8a1e5282580f68f43de875b78cba2199d", size = 10767016, upload-time = "2026-05-11T18:53:21.227Z" }, + { url = "https://files.pythonhosted.org/packages/ea/dc/eb55135a1d5f0f0519f28da1f609a206d2cad1f9c35c32d51e38dd7261ae/pandas-3.0.3-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:261e308dfb22448384b7580cf719d2f998fe2966c92893c3e77d14008af1f066", size = 10420210, upload-time = "2026-05-11T18:53:23.982Z" }, + { url = "https://files.pythonhosted.org/packages/c6/3e/b1d5d955ce33ffecb407465a60bc32769d74fcf68224b7ae67ae11d4dea4/pandas-3.0.3-cp313-cp313t-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:dd1a5d1def6a46002e964510bdc67c368aa0951df5d1d9f8365336f5a1f490cd", size = 10336126, upload-time = "2026-05-11T18:53:26.731Z" }, + { url = "https://files.pythonhosted.org/packages/f5/76/a01261711ab60a22d71b862f0de20e4c504bf80457270ad8cb42110f6abc/pandas-3.0.3-cp313-cp313t-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:d72828c20c6d6e83e1e22a6a3b47b326b71664112fa9705dcbccfd7a39b62085", size = 10728051, upload-time = "2026-05-11T18:53:29.125Z" }, + { url = "https://files.pythonhosted.org/packages/e9/21/ea191195e587b18cf682e97f433f81b2d0fbe341380e80a3e0d6e4403c8e/pandas-3.0.3-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:d26cbe1fcfc12e8fd900e2454163e466b2d3af84f7c75481df7683ffc073d870", size = 11350796, upload-time = "2026-05-11T18:53:32.056Z" }, + { url = "https://files.pythonhosted.org/packages/64/69/f0eaaf54939f0e8c6768fd06be9af2cef9b36048b96dfb9e1b2c685a807e/pandas-3.0.3-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:3e91cec1879ada0624fc3dc9953c5cbd60208e59c0db28f540c5d6d47502422f", size = 11799741, upload-time = "2026-05-11T18:53:34.985Z" }, + { url = "https://files.pythonhosted.org/packages/45/a4/865e0e510cae5fc2194de4db28be638952de942571ba9125934fd9c01d47/pandas-3.0.3-cp313-cp313t-win_amd64.whl", hash = "sha256:08d789b41f87e0905880e293cedf6197ce71fe67cc081358b1e148a491b9bd13", size = 10499958, upload-time = "2026-05-11T18:53:37.857Z" }, + { url = "https://files.pythonhosted.org/packages/86/54/effdcc3c0ff7a08037889200e148ebe94c16c4f653be078c7b3675955df1/pandas-3.0.3-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:3650109c0f22879df8bd6179ab9ee3d7f1d1d4e7e0094a3f0032d9f51e2e64ac", size = 10336065, upload-time = "2026-05-11T18:53:41.099Z" }, + { url = "https://files.pythonhosted.org/packages/68/10/bf2d6738d72748b961a3751ab89522d58c54efc36a8e1a12161216cd45cf/pandas-3.0.3-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:bab900348131a7db1f69a7309ef141fd5680f1487094193bcbbb61791573bf8f", size = 9926101, upload-time = "2026-05-11T18:53:43.515Z" }, + { url = "https://files.pythonhosted.org/packages/ae/e9/e35cf11c8a136e757b956f5f0efdcaa50aecde85ea055f1898dfc68262f3/pandas-3.0.3-cp314-cp314-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ba7e08b9ac1d54569cd1e256e3668975ed624d6826f7b68df0342b012007bddb", size = 10457553, upload-time = "2026-05-11T18:53:46.394Z" }, + { url = "https://files.pythonhosted.org/packages/58/3b/1cdec6772bdbaf7b25dab360c59f03cadf05492dd724c6540af905389b07/pandas-3.0.3-cp314-cp314-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:9d71c63ae4ebdbf70209742096f1fc46a83a0613c99d4b23766cced9ff8cd62a", size = 10914065, upload-time = "2026-05-11T18:53:49.134Z" }, + { url = "https://files.pythonhosted.org/packages/c4/c2/1ef644445fcd72e3627bceec77e3560636f87ddce4ed841afe76b83b5bf9/pandas-3.0.3-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:e3a2ec42c98ffa2565a67e08e218d06d72576d758d90facb7c00805194d8f360", size = 11459188, upload-time = "2026-05-11T18:53:52.527Z" }, + { url = "https://files.pythonhosted.org/packages/7e/49/4d8d4f42cbc9c4adc7a1870f269c02cbd6cd40d059622c06fb298addcbad/pandas-3.0.3-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:335f62418ed562cfc3c49e9e196375c28b729dcef8543abf4f9438e381bf3c76", size = 11982966, upload-time = "2026-05-11T18:53:55.043Z" }, + { url = "https://files.pythonhosted.org/packages/38/55/792619469bab9882d8bbd5865d45a72f6478762d04a9af4bf0d08c503e95/pandas-3.0.3-cp314-cp314-win_amd64.whl", hash = "sha256:3c20a521bbb85902f79f7270c80a59e1b5452d96d170c034f207181870f97ac5", size = 9876755, upload-time = "2026-05-11T18:53:58.067Z" }, + { url = "https://files.pythonhosted.org/packages/2a/af/33c469653b0ba03b50c3a98192d4c07f0c75c66b263ceb097fce0ee97d31/pandas-3.0.3-cp314-cp314-win_arm64.whl", hash = "sha256:a2d2dff8a04f3917b55ab3910c32990f8ddf7eceba114947838cefa976a68977", size = 9198658, upload-time = "2026-05-11T18:54:00.733Z" }, + { url = "https://files.pythonhosted.org/packages/a2/fa/b8c257bd76b8bd060c3a9151c1fca05e9b9c5e3af5d0f549c0356f6d143d/pandas-3.0.3-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:0d589105b3c14645af1738ff279b2995102d8f7a03b0a66dc8d95550eb513e04", size = 10787242, upload-time = "2026-05-11T18:54:03.564Z" }, + { url = "https://files.pythonhosted.org/packages/54/eb/f19206ffb0bf1919002969aa448b4702c6594845156a6f8050674855aac3/pandas-3.0.3-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:13fc1e853d9e04743d11ba75a985ccbc2a317fe07d8af61e445a6fd24dacd6a6", size = 10436369, upload-time = "2026-05-11T18:54:06.311Z" }, + { url = "https://files.pythonhosted.org/packages/fd/24/c7c39fb4fe22b71a0c2d78bf0c585c600092d85f94f086d2b3b2f6ca27e2/pandas-3.0.3-cp314-cp314t-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:819959dab7bbd0049c15623fbac4e29a191b9528160a61fb1032242d8ced2d9c", size = 10358306, upload-time = "2026-05-11T18:54:09.085Z" }, + { url = "https://files.pythonhosted.org/packages/16/ec/dd2a9eb7fa1204df88c0864164e35b228ac581062ac612ba0a67fd812e4c/pandas-3.0.3-cp314-cp314t-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:60ae316d3fd75d1858d450d0db0103ea2be3e7d4a95ec2f064f7e2ae63f7b028", size = 10758394, upload-time = "2026-05-11T18:54:11.956Z" }, + { url = "https://files.pythonhosted.org/packages/95/6e/00c61ea8e85b4f6d8d35e11852a1a4998fc7fafc91c6a602d1cc9c972d64/pandas-3.0.3-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:bd3a518890b400d32f9023722dc9a9a5c969f00b415419a3c06c043f09bb5d7d", size = 11375717, upload-time = "2026-05-11T18:54:14.539Z" }, + { url = "https://files.pythonhosted.org/packages/31/89/8fc1c268969fac43688d65fd92e67df24bd128d53cb4d2eee534cd307399/pandas-3.0.3-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:9c39be2d709d01fa972a0cabc522389fceca4f3969332ba25a7d6c5802cf976a", size = 11828897, upload-time = "2026-05-11T18:54:17.146Z" }, + { url = "https://files.pythonhosted.org/packages/56/3b/e7d20dea247a3e6dc0bd8a6953854afbedc03951def4e7371e05e7263e25/pandas-3.0.3-cp314-cp314t-win_amd64.whl", hash = "sha256:4db8c527972a821cf5286b40ccc57642a39bc62e62022b42f99f8a67fca8c3a1", size = 10900855, upload-time = "2026-05-11T18:54:19.72Z" }, + { url = "https://files.pythonhosted.org/packages/0f/54/68a0978d1ef8502b8492099beaa6e7a0c1b32e3b5d4f677f5810cb08711c/pandas-3.0.3-cp314-cp314t-win_arm64.whl", hash = "sha256:b2c95f8bfc1ee412bf482605d7bfd30c12d1d26bd59fdd91efeef1d4718decb1", size = 9466464, upload-time = "2026-05-11T18:54:22.754Z" }, ] [[package]] @@ -1601,14 +1611,14 @@ wheels = [ [[package]] name = "prompt-toolkit" -version = "3.0.53" +version = "3.0.52" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "wcwidth" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/7d/ea/39b988c938f75cb75d7045b5c69f8bfed47ee2152c8837fb403de29d6fb8/prompt_toolkit-3.0.53.tar.gz", hash = "sha256:9ec8a0ad96d5c56148b3f914aa79c1564c3fde5d2e6b876e7bc327e353cf8fa6", size = 435492, upload-time = "2026-07-26T20:56:14.758Z" } +sdist = { url = "https://files.pythonhosted.org/packages/a1/96/06e01a7b38dce6fe1db213e061a4602dd6032a8a97ef6c1a862537732421/prompt_toolkit-3.0.52.tar.gz", hash = "sha256:28cde192929c8e7321de85de1ddbe736f1375148b02f2e17edd840042b1be855", size = 434198, upload-time = "2025-08-27T15:24:02.057Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/54/6f/84908cad2d6aa5144abcf7b42709fe4fdb459bc640ec7ac5786e7693dabc/prompt_toolkit-3.0.53-py3-none-any.whl", hash = "sha256:01c0891d7f9237d5e339f7d3e42cdae80b7534abb1c7c0e3352efba6231492f2", size = 392288, upload-time = "2026-07-26T20:56:12.512Z" }, + { url = "https://files.pythonhosted.org/packages/84/03/0d3ce49e2505ae70cf43bc5bb3033955d2fc9f932163e84dc0779cc47f48/prompt_toolkit-3.0.52-py3-none-any.whl", hash = "sha256:9aac639a3bbd33284347de5ad8d68ecc044b91a762dc39b7c21095fcd6a19955", size = 391431, upload-time = "2025-08-27T15:23:59.498Z" }, ] [[package]] @@ -2159,27 +2169,27 @@ wheels = [ [[package]] name = "ruff" -version = "0.16.0" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/4d/94/1e5e4967626faf12fa56999cd6222dff6992ceb086ad7945756baf70c7a7/ruff-0.16.0.tar.gz", hash = "sha256:e460aafd5495ec89efaa6ced2e4a9a581116451e1c88b9d37ef497e0f8e93982", size = 4790557, upload-time = "2026-07-23T19:11:30.981Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/4b/81/1c8818fee7ce1a04cd7d1b3172e0a8f8e4f1dc4feb7fc390e16daa8af323/ruff-0.16.0-py3-none-linux_armv6l.whl", hash = "sha256:e5115729eb08c585e5121978ba5d5b60caeae394ce21b9fb5e6cd33a1c6c9b1e", size = 10754633, upload-time = "2026-07-23T19:10:46.415Z" }, - { url = "https://files.pythonhosted.org/packages/23/df/beaf59c09d68db84304d555f188b276a77132a5d5b0b67a5c762aa143628/ruff-0.16.0-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:3c954b1d580bfa035b41654f7858cc7e71d5fc3ac5b723dd62bd9133830ed522", size = 10969164, upload-time = "2026-07-23T19:10:50.271Z" }, - { url = "https://files.pythonhosted.org/packages/42/ce/741cd197496a1abbf51352710fd15ed995d2a2be87189c1da26a450d6e83/ruff-0.16.0-py3-none-macosx_11_0_arm64.whl", hash = "sha256:e01c21d10eb1b29f47b7454e1f4056db9a3f0260c646aa88457c610291db9f81", size = 10488846, upload-time = "2026-07-23T19:10:52.639Z" }, - { url = "https://files.pythonhosted.org/packages/52/2a/a2db8e88cade358f5cdcb05674a917751074109315d014eb6352d9a893f7/ruff-0.16.0-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6e364e5ed22ed8dc05082fd78e35308618260907ac2d3c1d637b2e682415b6c9", size = 10889729, upload-time = "2026-07-23T19:10:54.89Z" }, - { url = "https://files.pythonhosted.org/packages/42/65/62a771694ebd63029dc953e27dbad40e1588bd4860ff9fe881018fddaa49/ruff-0.16.0-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:d327b8fc113a1d4421a04f3839d3752057c8dd1ee320223a6f3f52d04ada462a", size = 10568275, upload-time = "2026-07-23T19:10:56.993Z" }, - { url = "https://files.pythonhosted.org/packages/3f/e2/ced249fe8af5f086c5c58cc21cc3356d50f32f7401c5df87050c999620a7/ruff-0.16.0-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a9b50c55e263103586b3dcf5f73d479eb8cb5fdb6098fec59a62891dab653717", size = 11385112, upload-time = "2026-07-23T19:10:59.615Z" }, - { url = "https://files.pythonhosted.org/packages/87/0b/05154977a8fd69eeb6c103271f55403bfd8711f5c0f8ed07489d95a504e7/ruff-0.16.0-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:0ff4a79ce3ec0172f3241943835de1c4cb4e2dcd07f0f8c2d02603dbbbee4b17", size = 12207008, upload-time = "2026-07-23T19:11:02.154Z" }, - { url = "https://files.pythonhosted.org/packages/fb/29/98225831a3a1eab0e02f4acc6ca6559a98611dcc68b6965ff4b7234627c1/ruff-0.16.0-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e95c448fca1fb2a18372a9440926c5a6ee789639bb975c72e7ae6d0b04218ab4", size = 11650842, upload-time = "2026-07-23T19:11:04.557Z" }, - { url = "https://files.pythonhosted.org/packages/91/66/6bd3cf90500653d55dc0ffc8507aa8300bd49d0214b2e8cb4d3fef2943ba/ruff-0.16.0-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4f11a8d11010301d0a398a2fdef67691feca7294da6aef55e2150e8fa2cd520b", size = 11400718, upload-time = "2026-07-23T19:11:09.233Z" }, - { url = "https://files.pythonhosted.org/packages/8e/a2/a54eb4eae05d66364050a5d3b8a9c5ef88196531b3cbe7109d873f87f819/ruff-0.16.0-py3-none-manylinux_2_31_riscv64.whl", hash = "sha256:48044c678e9cb8698246c99b14aaccfa6601dea7379eb48a6f8f73f7a6d86cd0", size = 11426177, upload-time = "2026-07-23T19:11:11.994Z" }, - { url = "https://files.pythonhosted.org/packages/1a/be/16e3eea4b2a478a496919f5e36f17c4559e54620bd3bbac5d6affa068006/ruff-0.16.0-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:7aa0959bad8eb8bef50340154fc9b58678dae31fa4293afa38b44b6e552c0213", size = 10856126, upload-time = "2026-07-23T19:11:14.221Z" }, - { url = "https://files.pythonhosted.org/packages/a2/84/252eb8b868a16eec7257c14f504f77537e734b2d69c762e639e588e304a3/ruff-0.16.0-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:28ea2b7df8ebf7f9da6b7d47b230ab48f387c0a29be3b474c4d0740e197bb9af", size = 10571208, upload-time = "2026-07-23T19:11:16.378Z" }, - { url = "https://files.pythonhosted.org/packages/21/09/817a482f542f7570cbb4554b26e896610c7114f539b1d9e2d2145bf6bef6/ruff-0.16.0-py3-none-musllinux_1_2_i686.whl", hash = "sha256:33a3dfac8c35f81498dea9181bccc2f4c4bc8f1521a1dd9406e77643e0f0fb09", size = 11063329, upload-time = "2026-07-23T19:11:19.173Z" }, - { url = "https://files.pythonhosted.org/packages/2e/23/9403c180ca1cb9b1f7335f5c3e5305c09d49ea5b345196682a36028bde4a/ruff-0.16.0-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:a5237a0bda500d30d81b8e07a6973a5cbc772864cbf746ae2f4e8a2e01c9f4ed", size = 11489751, upload-time = "2026-07-23T19:11:21.74Z" }, - { url = "https://files.pythonhosted.org/packages/b2/1d/1b2ef7bcde851c78d7f17f1cca13fd6dc695fc4b3d6197941e72cae5b132/ruff-0.16.0-py3-none-win32.whl", hash = "sha256:7fab76fa065c873f41ff744347c6e77bcc3dfec4bcc754dc26b63d23c0f7f5fb", size = 10785885, upload-time = "2026-07-23T19:11:23.947Z" }, - { url = "https://files.pythonhosted.org/packages/b2/a3/d5e4ef7a56be3f928ffb90b94c25ba7d3cb9c7fe0736aeaaedf361770712/ruff-0.16.0-py3-none-win_amd64.whl", hash = "sha256:429c117f022bf481fabd9d551e7a3952b24c65e6ef44337ea09d90bebef14472", size = 11923141, upload-time = "2026-07-23T19:11:26.409Z" }, - { url = "https://files.pythonhosted.org/packages/cb/9a/8415f2657cbe200f41a4531ccededf135505a92d4a012229121f885b26f9/ruff-0.16.0-py3-none-win_arm64.whl", hash = "sha256:14296fedcd2705c77ab8235439278bbb38f285cf7da5528b00b3e330c3d4872d", size = 11273407, upload-time = "2026-07-23T19:11:28.705Z" }, +version = "0.15.22" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/3a/06/ae069393fc66e8ff33036d4b368003833bf6e88ccf182e17e7a2f1c754fd/ruff-0.15.22.tar.gz", hash = "sha256:3f15175b1fb580126f58285a5dae6b2ea89000136d980c64499211f116b54809", size = 4785063, upload-time = "2026-07-16T15:14:13.244Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/23/18/ee54b7ae1e121be7a28ea6da4b67564ebb0530e183a54415ab7e3bcd2c4e/ruff-0.15.22-py3-none-linux_armv6l.whl", hash = "sha256:44423e73493737f5e7c5b41d475483898ff37afcdae38bc3da5085e29af1c2d8", size = 10781258, upload-time = "2026-07-16T15:13:19.452Z" }, + { url = "https://files.pythonhosted.org/packages/2f/d2/2520cb14761ddbeaf57642a76942fc36adcbdbe53b4532241995f6fc485c/ruff-0.15.22-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:b82c6482946e9eda7ff2e091d25b8bad3f718684e1916d41bd56873cee05b697", size = 10999477, upload-time = "2026-07-16T15:13:23.318Z" }, + { url = "https://files.pythonhosted.org/packages/c9/10/74e53572aa758dfaa678c2a2646b5c5515d884b7ca56be4d2ce03ca4b560/ruff-0.15.22-py3-none-macosx_11_0_arm64.whl", hash = "sha256:11c1c715af53a09f714e011106bffc419751ec8232fcb5da42173284ea3fec6f", size = 10466716, upload-time = "2026-07-16T15:13:26.162Z" }, + { url = "https://files.pythonhosted.org/packages/1e/cc/44eaaf0844e028182f2d0a8f2190d0f359159aed0a9e5ab861d892f1ae2a/ruff-0.15.22-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:742a29cf29bddb7c8327895d6a10e0e6c5b38a96dd407af9b5d0857f809c0576", size = 10892644, upload-time = "2026-07-16T15:13:29.229Z" }, + { url = "https://files.pythonhosted.org/packages/9f/21/8edf559014d2b0f82beea19cfb713993ad802ccda16868769979c6090a84/ruff-0.15.22-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:72af58b951b0ae395935ae79763dc349bc0eb706319d28f7a33ad2cfb3cfc178", size = 10576719, upload-time = "2026-07-16T15:13:32.35Z" }, + { url = "https://files.pythonhosted.org/packages/bf/1e/3a13abd392a3b50b62e5938a831f9ab6e588358cacad5c18545b716d2182/ruff-0.15.22-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:62d425005c1835eb24e2ee4161cb90e8db263415f4a71c8c72c33abaa6c0c224", size = 11376494, upload-time = "2026-07-16T15:13:35.958Z" }, + { url = "https://files.pythonhosted.org/packages/bf/3e/422d3d95bcf04dd78e1aeac22184d4f9a8fb2c01865d39d44618484a0317/ruff-0.15.22-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e8b9b3f8779a4f08c969defc3c8c35abffaa757e601ed5ae66d6d1db6519969a", size = 12208370, upload-time = "2026-07-16T15:13:39.185Z" }, + { url = "https://files.pythonhosted.org/packages/1e/91/5d065a0e0a02bf4813f5119ad278462eed081d2b832eb7c021ade0ec9e65/ruff-0.15.22-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1e0dd1b2e4d3d585f897a0d137cbf4eaf6223bef4e8ce34d6bb12556c5f9249e", size = 11581098, upload-time = "2026-07-16T15:13:42.132Z" }, + { url = "https://files.pythonhosted.org/packages/f6/f9/a0d4871d12fae702eb1f41b686caf05f1f8b124dc6db6f784f53d74918fa/ruff-0.15.22-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:365523eb91d9224e1bcb03b022fbf0facb8f9e23792a2c53d9d4b3924bdbdebb", size = 11399422, upload-time = "2026-07-16T15:13:45.2Z" }, + { url = "https://files.pythonhosted.org/packages/18/80/c843a5176cddbceb0b7e8dd41cf9993490796c1c469348d384f5a5c13c56/ruff-0.15.22-py3-none-manylinux_2_31_riscv64.whl", hash = "sha256:fabfd168afdf29fee5be98b831efa9683c94d7c5a3b58b9ce5a2e38444589a74", size = 11381683, upload-time = "2026-07-16T15:13:48.46Z" }, + { url = "https://files.pythonhosted.org/packages/d4/00/8485de0ae92239438a36cfc51350db9b9e85c9ebdfaea91b18e422706662/ruff-0.15.22-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:225dbf095a87f1d9f90f5fd7924d2613ee452a75a4308c63a8f50f761787aa7c", size = 10850295, upload-time = "2026-07-16T15:13:51.655Z" }, + { url = "https://files.pythonhosted.org/packages/fa/91/24977ec2ec72eaf15e4394ace2959fdff2dd1e14f03e005e838023407169/ruff-0.15.22-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:1877d63b9d24ed278744f1523fd11b85540566d54641f97c566d7d9dc5ca5296", size = 10579640, upload-time = "2026-07-16T15:13:54.79Z" }, + { url = "https://files.pythonhosted.org/packages/9c/47/9b51216951974df1f263ac19da550d34252e0ed7218c25f10c5ef9ed7517/ruff-0.15.22-py3-none-musllinux_1_2_i686.whl", hash = "sha256:a1606c510bd7215680d32efab38965f7cdec3ef69f5170a3f4791404ffdd5262", size = 11105077, upload-time = "2026-07-16T15:13:57.915Z" }, + { url = "https://files.pythonhosted.org/packages/c2/47/20e9d4a3b8016778acea5fc32bb50d35d207500a17ddb529ffa6996feef8/ruff-0.15.22-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:630479b18625f5ffc373f77603a22a9f8ac0acd7ff0501178b5db28ec71e9c64", size = 11490980, upload-time = "2026-07-16T15:14:01.032Z" }, + { url = "https://files.pythonhosted.org/packages/4d/76/3f72d8fc38c1cb77b38c56a70da9d0c17700cc1cc50f9649c9d3c8f5ba71/ruff-0.15.22-py3-none-win32.whl", hash = "sha256:e5ba0e4a13fd14abbed2a77b517a3911290c6c6c59ef67784328d1668fab76cf", size = 10789165, upload-time = "2026-07-16T15:14:04.16Z" }, + { url = "https://files.pythonhosted.org/packages/cb/46/4965251734c2b6fcdca1b1b187d20bcac3af0ee5b083b89c910bb961ce3a/ruff-0.15.22-py3-none-win_amd64.whl", hash = "sha256:9be63ba1eb936acd2d1342fb8337c356353706fce233b2a15a09a97037e6acde", size = 11938297, upload-time = "2026-07-16T15:14:07.316Z" }, + { url = "https://files.pythonhosted.org/packages/57/c9/e69b1ff4c8b69093ef08b8919ab767af0569666865b39c30a8795d88d3c6/ruff-0.15.22-py3-none-win_arm64.whl", hash = "sha256:e1168075b72158510839f250027659cdd78476f40507dd517892304c41318661", size = 11298172, upload-time = "2026-07-16T15:14:10.51Z" }, ] [[package]] From 80b3af6fe7215675906e787897d2c68bc7a53dcc Mon Sep 17 00:00:00 2001 From: Martijn Govers Date: Wed, 29 Jul 2026 10:47:00 +0200 Subject: [PATCH 05/14] remove markdownlint-cli from package.json Signed-off-by: Martijn Govers --- package.json | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/package.json b/package.json index 12899060a1..b135b3273c 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,6 @@ { "private": true, "devDependencies": { - "@biomejs/biome": "*", - "markdownlint-cli": "*" + "@biomejs/biome": "*" } } From 85ef0c9a103e18f0375abb0a5780b56a5f7fe703 Mon Sep 17 00:00:00 2001 From: "power-grid-model-ci-bot[bot]" <249743335+power-grid-model-ci-bot[bot]@users.noreply.github.com> Date: Wed, 29 Jul 2026 08:48:21 +0000 Subject: [PATCH 06/14] Refresh lock and linter dependencies Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> --- package-lock.json | 1182 +-------------------------------------------- 1 file changed, 1 insertion(+), 1181 deletions(-) diff --git a/package-lock.json b/package-lock.json index 516499e031..4e547883f7 100644 --- a/package-lock.json +++ b/package-lock.json @@ -5,8 +5,7 @@ "packages": { "": { "devDependencies": { - "@biomejs/biome": "*", - "markdownlint-cli": "*" + "@biomejs/biome": "*" } }, "node_modules/@biomejs/biome": { @@ -171,1185 +170,6 @@ "engines": { "node": ">=14.21.3" } - }, - "node_modules/@types/debug": { - "version": "4.1.13", - "resolved": "https://registry.npmjs.org/@types/debug/-/debug-4.1.13.tgz", - "integrity": "sha512-KSVgmQmzMwPlmtljOomayoR89W4FynCAi3E8PPs7vmDVPe84hT+vGPKkJfThkmXs0x0jAaa9U8uW8bbfyS2fWw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/ms": "*" - } - }, - "node_modules/@types/katex": { - "version": "0.16.8", - "resolved": "https://registry.npmjs.org/@types/katex/-/katex-0.16.8.tgz", - "integrity": "sha512-trgaNyfU+Xh2Tc+ABIb44a5AYUpicB3uwirOioeOkNPPbmgRNtcWyDeeFRzjPZENO9Vq8gvVqfhaaXWLlevVwg==", - "dev": true, - "license": "MIT" - }, - "node_modules/@types/ms": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/@types/ms/-/ms-2.1.0.tgz", - "integrity": "sha512-GsCCIZDE/p3i96vtEqx+7dBUGXrc7zeSK3wwPHIaRThS+9OhWIXRqzs4d6k1SVU8g91DrNRWxWUGhp5KXQb2VA==", - "dev": true, - "license": "MIT" - }, - "node_modules/@types/unist": { - "version": "2.0.11", - "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.11.tgz", - "integrity": "sha512-CmBKiL6NNo/OqgmMn95Fk9Whlp2mtvIv+KNpQKN2F4SjvrEesubTRWGYSg+BnWZOnlCaSTU1sMpsBOzgbYhnsA==", - "dev": true, - "license": "MIT" - }, - "node_modules/ansi-regex": { - "version": "6.2.2", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.2.2.tgz", - "integrity": "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/ansi-regex?sponsor=1" - } - }, - "node_modules/argparse": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", - "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", - "dev": true, - "license": "Python-2.0" - }, - "node_modules/balanced-match": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-4.0.4.tgz", - "integrity": "sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==", - "dev": true, - "license": "MIT", - "engines": { - "node": "18 || 20 || >=22" - } - }, - "node_modules/brace-expansion": { - "version": "5.0.8", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.8.tgz", - "integrity": "sha512-JZyDyq3D4AUifKTPOB7DELf6XsB3WdPuNxCtob1vFXPsSXhdAiHBWJ/tJ8HAc9aH84BK+5JFZLNkJKx3G9kzQg==", - "dev": true, - "license": "MIT", - "dependencies": { - "balanced-match": "^4.0.2" - }, - "engines": { - "node": "20 || >=22" - } - }, - "node_modules/character-entities": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/character-entities/-/character-entities-2.0.2.tgz", - "integrity": "sha512-shx7oQ0Awen/BRIdkjkvz54PnEEI/EjwXDSIZp86/KKdbafHh1Df/RYGBhn4hbe2+uKC9FnT5UCEdyPz3ai9hQ==", - "dev": true, - "license": "MIT", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/character-entities-legacy": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/character-entities-legacy/-/character-entities-legacy-3.0.0.tgz", - "integrity": "sha512-RpPp0asT/6ufRm//AJVwpViZbGM/MkjQFxJccQRHmISF/22NBtsHqAWmL+/pmkPWoIUJdWyeVleTl1wydHATVQ==", - "dev": true, - "license": "MIT", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/character-reference-invalid": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/character-reference-invalid/-/character-reference-invalid-2.0.1.tgz", - "integrity": "sha512-iBZ4F4wRbyORVsu0jPV7gXkOsGYjGHPmAyv+HiHG8gi5PtC9KI2j1+v8/tlibRvjoWX027ypmG/n0HtO5t7unw==", - "dev": true, - "license": "MIT", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/commander": { - "version": "15.0.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-15.0.0.tgz", - "integrity": "sha512-z67u4ZhzCL/Tydu1lJARtEZYWbWaN7oYLHbsuzocr6y4N6WZAagG3RQ4FW61V1/0+jImpj293XfrcYnd1qxtPg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=22.12.0" - } - }, - "node_modules/debug": { - "version": "4.4.3", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", - "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", - "dev": true, - "license": "MIT", - "dependencies": { - "ms": "^2.1.3" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, - "node_modules/decode-named-character-reference": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/decode-named-character-reference/-/decode-named-character-reference-1.3.0.tgz", - "integrity": "sha512-GtpQYB283KrPp6nRw50q3U9/VfOutZOe103qlN7BPP6Ad27xYnOIWv4lPzo8HCAL+mMZofJ9KEy30fq6MfaK6Q==", - "dev": true, - "license": "MIT", - "dependencies": { - "character-entities": "^2.0.0" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/deep-extend": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", - "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=4.0.0" - } - }, - "node_modules/dequal": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/dequal/-/dequal-2.0.3.tgz", - "integrity": "sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/devlop": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/devlop/-/devlop-1.1.0.tgz", - "integrity": "sha512-RWmIqhcFf1lRYBvNmr7qTNuyCt/7/ns2jbpp1+PalgE/rDQcBT0fioSMUpJ93irlUhC5hrg4cYqe6U+0ImW0rA==", - "dev": true, - "license": "MIT", - "dependencies": { - "dequal": "^2.0.0" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/entities": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", - "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==", - "dev": true, - "license": "BSD-2-Clause", - "engines": { - "node": ">=0.12" - }, - "funding": { - "url": "https://github.com/fb55/entities?sponsor=1" - } - }, - "node_modules/fdir": { - "version": "6.5.0", - "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz", - "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=12.0.0" - }, - "peerDependencies": { - "picomatch": "^3 || ^4" - }, - "peerDependenciesMeta": { - "picomatch": { - "optional": true - } - } - }, - "node_modules/get-east-asian-width": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/get-east-asian-width/-/get-east-asian-width-1.6.0.tgz", - "integrity": "sha512-QRbvDIbx6YklUe6RxeTeleMR0yv3cYH6PsPZHcnVn7xv7zO1BHN8r0XETu8n6Ye3Q+ahtSarc3WgtNWmehIBfA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/ignore": { - "version": "7.0.6", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-7.0.6.tgz", - "integrity": "sha512-BAg6QkE8W+TuQLrrw0Ugr7HegXduRuuj8/ti2kSOc+jz1dmx8/WNcjr6XGnq5YpDWxFwwaavqD0+jIUOKelTsw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 4" - } - }, - "node_modules/ini": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/ini/-/ini-7.0.0.tgz", - "integrity": "sha512-ifK0CgjALofS5bkrcTy4RaQ9Vx2Knf/eLeIO+NaswQEpH1UblrtTSCIvN71qQDMq0PeQ/SSPojvEJp9vvvfr+w==", - "dev": true, - "license": "ISC", - "engines": { - "node": "^22.22.2 || ^24.15.0 || >=26.0.0" - } - }, - "node_modules/is-alphabetical": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-alphabetical/-/is-alphabetical-2.0.1.tgz", - "integrity": "sha512-FWyyY60MeTNyeSRpkM2Iry0G9hpr7/9kD40mD/cGQEuilcZYS4okz8SN2Q6rLCJ8gbCt6fN+rC+6tMGS99LaxQ==", - "dev": true, - "license": "MIT", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/is-alphanumerical": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-alphanumerical/-/is-alphanumerical-2.0.1.tgz", - "integrity": "sha512-hmbYhX/9MUMF5uh7tOXyK/n0ZvWpad5caBA17GsC6vyuCqaWliRG5K1qS9inmUhEMaOBIW7/whAnSwveW/LtZw==", - "dev": true, - "license": "MIT", - "dependencies": { - "is-alphabetical": "^2.0.0", - "is-decimal": "^2.0.0" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/is-decimal": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-decimal/-/is-decimal-2.0.1.tgz", - "integrity": "sha512-AAB9hiomQs5DXWcRB1rqsxGUstbRroFOPPVAomNk/3XHR5JyEZChOyTWe2oayKnsSsr/kcGqF+z6yuH6HHpN0A==", - "dev": true, - "license": "MIT", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/is-hexadecimal": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-hexadecimal/-/is-hexadecimal-2.0.1.tgz", - "integrity": "sha512-DgZQp241c8oO6cA1SbTEWiXeoxV42vlcJxgH+B3hi1AiqqKruZR3ZGF8In3fj4+/y/7rHvlOZLZtgJ/4ttYGZg==", - "dev": true, - "license": "MIT", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/js-yaml": { - "version": "5.2.2", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-5.2.2.tgz", - "integrity": "sha512-dayzUzKkJ1MkuUtZglSebU43utNXH0OWQByK9rKOOuYIO8M5TV1y+n8ALMdG0rdzBnfNkOmZEqrURepb0ejqBw==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/puzrin" - }, - { - "type": "github", - "url": "https://github.com/sponsors/nodeca" - } - ], - "license": "MIT", - "dependencies": { - "argparse": "^2.0.1" - }, - "bin": { - "js-yaml": "bin/js-yaml.mjs" - } - }, - "node_modules/jsonc-parser": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-3.3.1.tgz", - "integrity": "sha512-HUgH65KyejrUFPvHFPbqOY0rsFip3Bo5wb4ngvdi1EpCYWUQDC5V+Y7mZws+DLkr4M//zQJoanu1SP+87Dv1oQ==", - "dev": true, - "license": "MIT" - }, - "node_modules/jsonpointer": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/jsonpointer/-/jsonpointer-5.0.1.tgz", - "integrity": "sha512-p/nXbhSEcu3pZRdkW1OfJhpsVtW1gd4Wa1fnQc9YLiTfAjn0312eMKimbdIQzuZl9aa9xUGaRlP9T/CJE/ditQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/katex": { - "version": "0.16.47", - "resolved": "https://registry.npmjs.org/katex/-/katex-0.16.47.tgz", - "integrity": "sha512-Eeo8Ys1doU1z+x8AZsPpQu+p/QcZBI5PeOo7QGQdy2x2m0MU/hYagBbGOmXwr5KVbEfVuWv9LpnQWeehogurjg==", - "dev": true, - "funding": [ - "https://opencollective.com/katex", - "https://github.com/sponsors/katex" - ], - "license": "MIT", - "dependencies": { - "commander": "^8.3.0" - }, - "bin": { - "katex": "cli.js" - } - }, - "node_modules/katex/node_modules/commander": { - "version": "8.3.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-8.3.0.tgz", - "integrity": "sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 12" - } - }, - "node_modules/linkify-it": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-5.0.2.tgz", - "integrity": "sha512-ONTm2jCMAVZjgQa/Fy1kScXsuOoF5NPTsoFBdE1KVIZ2vAh/r9+Bqo+0jINCBYnavTPQZz38QzFTme79ENoN3Q==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/puzrin" - }, - { - "type": "github", - "url": "https://github.com/sponsors/markdown-it" - } - ], - "license": "MIT", - "dependencies": { - "uc.micro": "^2.0.0" - } - }, - "node_modules/markdown-it": { - "version": "14.3.0", - "resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-14.3.0.tgz", - "integrity": "sha512-RCEsPjR+sr0x+AuYp601tKTkgFG4YEPLCzHST3cQ/fhlJkqAkz1L2/Qbp1j9qw5SBwQHFBoW8+hoN5xssOF0Tw==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/puzrin" - }, - { - "type": "github", - "url": "https://github.com/sponsors/markdown-it" - } - ], - "license": "MIT", - "dependencies": { - "argparse": "^2.0.1", - "entities": "^4.5.0", - "linkify-it": "^5.0.2", - "mdurl": "^2.0.0", - "punycode.js": "^2.3.1", - "uc.micro": "^2.1.0" - }, - "bin": { - "markdown-it": "bin/markdown-it.mjs" - } - }, - "node_modules/markdownlint": { - "version": "0.41.1", - "resolved": "https://registry.npmjs.org/markdownlint/-/markdownlint-0.41.1.tgz", - "integrity": "sha512-qHKeU2E1bdyNAT077go2FVTNXvYcktN5IHtF6XyeD1l0PClxzSp2tUApAV14ORI8DGX4H9bNKZEzelZp4qn8IA==", - "dev": true, - "license": "MIT", - "dependencies": { - "micromark": "4.0.2", - "micromark-core-commonmark": "2.0.3", - "micromark-extension-directive": "4.0.0", - "micromark-extension-gfm-autolink-literal": "2.1.0", - "micromark-extension-gfm-footnote": "2.1.0", - "micromark-extension-gfm-table": "2.1.1", - "micromark-extension-math": "3.1.0", - "micromark-util-types": "2.0.2", - "string-width": "8.2.1" - }, - "engines": { - "node": ">=22" - }, - "funding": { - "url": "https://github.com/sponsors/DavidAnson" - } - }, - "node_modules/markdownlint-cli": { - "version": "0.49.1", - "resolved": "https://registry.npmjs.org/markdownlint-cli/-/markdownlint-cli-0.49.1.tgz", - "integrity": "sha512-qpYqJbSYf3jv57bdnFmCaZ/Wlu6IYHp2b6SOKrKBJ7OnPrDHIKmx4NERWH49QH9viTI6yO6raVDDn5nrf60VQQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "commander": "~15.0.0", - "deep-extend": "~0.6.0", - "ignore": "~7.0.6", - "js-yaml": "~5.2.1", - "jsonc-parser": "~3.3.1", - "jsonpointer": "~5.0.1", - "markdown-it": "~14.3.0", - "markdownlint": "~0.41.1", - "minimatch": "~10.2.5", - "run-con": "~1.3.3", - "smol-toml": "~1.7.0", - "tinyglobby": "~0.2.17" - }, - "bin": { - "markdownlint": "markdownlint.js" - }, - "engines": { - "node": ">=22" - } - }, - "node_modules/mdurl": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/mdurl/-/mdurl-2.1.0.tgz", - "integrity": "sha512-1+HBaOx0zi/dQWht8rNv9MYf9qqpqL/kxI0hXImU6Y547zM6Sni8BQibt7ifgMcYtQg41ao3Ivd6cnSM86inpg==", - "dev": true, - "license": "MIT" - }, - "node_modules/micromark": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/micromark/-/micromark-4.0.2.tgz", - "integrity": "sha512-zpe98Q6kvavpCr1NPVSCMebCKfD7CA2NqZ+rykeNhONIJBpc1tFKt9hucLGwha3jNTNI8lHpctWJWoimVF4PfA==", - "dev": true, - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "@types/debug": "^4.0.0", - "debug": "^4.0.0", - "decode-named-character-reference": "^1.0.0", - "devlop": "^1.0.0", - "micromark-core-commonmark": "^2.0.0", - "micromark-factory-space": "^2.0.0", - "micromark-util-character": "^2.0.0", - "micromark-util-chunked": "^2.0.0", - "micromark-util-combine-extensions": "^2.0.0", - "micromark-util-decode-numeric-character-reference": "^2.0.0", - "micromark-util-encode": "^2.0.0", - "micromark-util-normalize-identifier": "^2.0.0", - "micromark-util-resolve-all": "^2.0.0", - "micromark-util-sanitize-uri": "^2.0.0", - "micromark-util-subtokenize": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-core-commonmark": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/micromark-core-commonmark/-/micromark-core-commonmark-2.0.3.tgz", - "integrity": "sha512-RDBrHEMSxVFLg6xvnXmb1Ayr2WzLAWjeSATAoxwKYJV94TeNavgoIdA0a9ytzDSVzBy2YKFK+emCPOEibLeCrg==", - "dev": true, - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "decode-named-character-reference": "^1.0.0", - "devlop": "^1.0.0", - "micromark-factory-destination": "^2.0.0", - "micromark-factory-label": "^2.0.0", - "micromark-factory-space": "^2.0.0", - "micromark-factory-title": "^2.0.0", - "micromark-factory-whitespace": "^2.0.0", - "micromark-util-character": "^2.0.0", - "micromark-util-chunked": "^2.0.0", - "micromark-util-classify-character": "^2.0.0", - "micromark-util-html-tag-name": "^2.0.0", - "micromark-util-normalize-identifier": "^2.0.0", - "micromark-util-resolve-all": "^2.0.0", - "micromark-util-subtokenize": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-extension-directive": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/micromark-extension-directive/-/micromark-extension-directive-4.0.0.tgz", - "integrity": "sha512-/C2nqVmXXmiseSSuCdItCMho7ybwwop6RrrRPk0KbOHW21JKoCldC+8rFOaundDoRBUWBnJJcxeA/Kvi34WQXg==", - "dev": true, - "license": "MIT", - "dependencies": { - "devlop": "^1.0.0", - "micromark-factory-space": "^2.0.0", - "micromark-factory-whitespace": "^2.0.0", - "micromark-util-character": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0", - "parse-entities": "^4.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/micromark-extension-gfm-autolink-literal": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/micromark-extension-gfm-autolink-literal/-/micromark-extension-gfm-autolink-literal-2.1.0.tgz", - "integrity": "sha512-oOg7knzhicgQ3t4QCjCWgTmfNhvQbDDnJeVu9v81r7NltNCVmhPy1fJRX27pISafdjL+SVc4d3l48Gb6pbRypw==", - "dev": true, - "license": "MIT", - "dependencies": { - "micromark-util-character": "^2.0.0", - "micromark-util-sanitize-uri": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/micromark-extension-gfm-footnote": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/micromark-extension-gfm-footnote/-/micromark-extension-gfm-footnote-2.1.0.tgz", - "integrity": "sha512-/yPhxI1ntnDNsiHtzLKYnE3vf9JZ6cAisqVDauhp4CEHxlb4uoOTxOCJ+9s51bIB8U1N1FJ1RXOKTIlD5B/gqw==", - "dev": true, - "license": "MIT", - "dependencies": { - "devlop": "^1.0.0", - "micromark-core-commonmark": "^2.0.0", - "micromark-factory-space": "^2.0.0", - "micromark-util-character": "^2.0.0", - "micromark-util-normalize-identifier": "^2.0.0", - "micromark-util-sanitize-uri": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/micromark-extension-gfm-table": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/micromark-extension-gfm-table/-/micromark-extension-gfm-table-2.1.1.tgz", - "integrity": "sha512-t2OU/dXXioARrC6yWfJ4hqB7rct14e8f7m0cbI5hUmDyyIlwv5vEtooptH8INkbLzOatzKuVbQmAYcbWoyz6Dg==", - "dev": true, - "license": "MIT", - "dependencies": { - "devlop": "^1.0.0", - "micromark-factory-space": "^2.0.0", - "micromark-util-character": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/micromark-extension-math": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/micromark-extension-math/-/micromark-extension-math-3.1.0.tgz", - "integrity": "sha512-lvEqd+fHjATVs+2v/8kg9i5Q0AP2k85H0WUOwpIVvUML8BapsMvh1XAogmQjOCsLpoKRCVQqEkQBB3NhVBcsOg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/katex": "^0.16.0", - "devlop": "^1.0.0", - "katex": "^0.16.0", - "micromark-factory-space": "^2.0.0", - "micromark-util-character": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/micromark-factory-destination": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-factory-destination/-/micromark-factory-destination-2.0.1.tgz", - "integrity": "sha512-Xe6rDdJlkmbFRExpTOmRj9N3MaWmbAgdpSrBQvCFqhezUn4AHqJHbaEnfbVYYiexVSs//tqOdY/DxhjdCiJnIA==", - "dev": true, - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "micromark-util-character": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-factory-label": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-factory-label/-/micromark-factory-label-2.0.1.tgz", - "integrity": "sha512-VFMekyQExqIW7xIChcXn4ok29YE3rnuyveW3wZQWWqF4Nv9Wk5rgJ99KzPvHjkmPXF93FXIbBp6YdW3t71/7Vg==", - "dev": true, - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "devlop": "^1.0.0", - "micromark-util-character": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-factory-space": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-2.0.1.tgz", - "integrity": "sha512-zRkxjtBxxLd2Sc0d+fbnEunsTj46SWXgXciZmHq0kDYGnck/ZSGj9/wULTV95uoeYiK5hRXP2mJ98Uo4cq/LQg==", - "dev": true, - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "micromark-util-character": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-factory-title": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-factory-title/-/micromark-factory-title-2.0.1.tgz", - "integrity": "sha512-5bZ+3CjhAd9eChYTHsjy6TGxpOFSKgKKJPJxr293jTbfry2KDoWkhBb6TcPVB4NmzaPhMs1Frm9AZH7OD4Cjzw==", - "dev": true, - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "micromark-factory-space": "^2.0.0", - "micromark-util-character": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-factory-whitespace": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-factory-whitespace/-/micromark-factory-whitespace-2.0.1.tgz", - "integrity": "sha512-Ob0nuZ3PKt/n0hORHyvoD9uZhr+Za8sFoP+OnMcnWK5lngSzALgQYKMr9RJVOWLqQYuyn6ulqGWSXdwf6F80lQ==", - "dev": true, - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "micromark-factory-space": "^2.0.0", - "micromark-util-character": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-util-character": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.1.tgz", - "integrity": "sha512-wv8tdUTJ3thSFFFJKtpYKOYiGP2+v96Hvk4Tu8KpCAsTMs6yi+nVmGh1syvSCsaxz45J6Jbw+9DD6g97+NV67Q==", - "dev": true, - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-util-chunked": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-util-chunked/-/micromark-util-chunked-2.0.1.tgz", - "integrity": "sha512-QUNFEOPELfmvv+4xiNg2sRYeS/P84pTW0TCgP5zc9FpXetHY0ab7SxKyAQCNCc1eK0459uoLI1y5oO5Vc1dbhA==", - "dev": true, - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "micromark-util-symbol": "^2.0.0" - } - }, - "node_modules/micromark-util-classify-character": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-util-classify-character/-/micromark-util-classify-character-2.0.1.tgz", - "integrity": "sha512-K0kHzM6afW/MbeWYWLjoHQv1sgg2Q9EccHEDzSkxiP/EaagNzCm7T/WMKZ3rjMbvIpvBiZgwR3dKMygtA4mG1Q==", - "dev": true, - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "micromark-util-character": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-util-combine-extensions": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-util-combine-extensions/-/micromark-util-combine-extensions-2.0.1.tgz", - "integrity": "sha512-OnAnH8Ujmy59JcyZw8JSbK9cGpdVY44NKgSM7E9Eh7DiLS2E9RNQf0dONaGDzEG9yjEl5hcqeIsj4hfRkLH/Bg==", - "dev": true, - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "micromark-util-chunked": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-util-decode-numeric-character-reference": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/micromark-util-decode-numeric-character-reference/-/micromark-util-decode-numeric-character-reference-2.0.2.tgz", - "integrity": "sha512-ccUbYk6CwVdkmCQMyr64dXz42EfHGkPQlBj5p7YVGzq8I7CtjXZJrubAYezf7Rp+bjPseiROqe7G6foFd+lEuw==", - "dev": true, - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "micromark-util-symbol": "^2.0.0" - } - }, - "node_modules/micromark-util-encode": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-util-encode/-/micromark-util-encode-2.0.1.tgz", - "integrity": "sha512-c3cVx2y4KqUnwopcO9b/SCdo2O67LwJJ/UyqGfbigahfegL9myoEFoDYZgkT7f36T0bLrM9hZTAaAyH+PCAXjw==", - "dev": true, - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT" - }, - "node_modules/micromark-util-html-tag-name": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-util-html-tag-name/-/micromark-util-html-tag-name-2.0.1.tgz", - "integrity": "sha512-2cNEiYDhCWKI+Gs9T0Tiysk136SnR13hhO8yW6BGNyhOC4qYFnwF1nKfD3HFAIXA5c45RrIG1ub11GiXeYd1xA==", - "dev": true, - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT" - }, - "node_modules/micromark-util-normalize-identifier": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-util-normalize-identifier/-/micromark-util-normalize-identifier-2.0.1.tgz", - "integrity": "sha512-sxPqmo70LyARJs0w2UclACPUUEqltCkJ6PhKdMIDuJ3gSf/Q+/GIe3WKl0Ijb/GyH9lOpUkRAO2wp0GVkLvS9Q==", - "dev": true, - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "micromark-util-symbol": "^2.0.0" - } - }, - "node_modules/micromark-util-resolve-all": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-util-resolve-all/-/micromark-util-resolve-all-2.0.1.tgz", - "integrity": "sha512-VdQyxFWFT2/FGJgwQnJYbe1jjQoNTS4RjglmSjTUlpUMa95Htx9NHeYW4rGDJzbjvCsl9eLjMQwGeElsqmzcHg==", - "dev": true, - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-util-sanitize-uri": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-util-sanitize-uri/-/micromark-util-sanitize-uri-2.0.1.tgz", - "integrity": "sha512-9N9IomZ/YuGGZZmQec1MbgxtlgougxTodVwDzzEouPKo3qFWvymFHWcnDi2vzV1ff6kas9ucW+o3yzJK9YB1AQ==", - "dev": true, - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "micromark-util-character": "^2.0.0", - "micromark-util-encode": "^2.0.0", - "micromark-util-symbol": "^2.0.0" - } - }, - "node_modules/micromark-util-subtokenize": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/micromark-util-subtokenize/-/micromark-util-subtokenize-2.1.0.tgz", - "integrity": "sha512-XQLu552iSctvnEcgXw6+Sx75GflAPNED1qx7eBJ+wydBb2KCbRZe+NwvIEEMM83uml1+2WSXpBAcp9IUCgCYWA==", - "dev": true, - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "devlop": "^1.0.0", - "micromark-util-chunked": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-util-symbol": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.1.tgz", - "integrity": "sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==", - "dev": true, - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT" - }, - "node_modules/micromark-util-types": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/micromark-util-types/-/micromark-util-types-2.0.2.tgz", - "integrity": "sha512-Yw0ECSpJoViF1qTU4DC6NwtC4aWGt1EkzaQB8KPPyCRR8z9TWeV0HbEFGTO+ZY1wB22zmxnJqhPyTpOVCpeHTA==", - "dev": true, - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT" - }, - "node_modules/minimatch": { - "version": "10.2.6", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.6.tgz", - "integrity": "sha512-vpLQEs+VLCr1nU0BXS07maYoFwlDAH0gngQuuttxIwutDFEMHq2blX+8vpgxDdK3J1PwjCJiep77OitTZ4Ll1A==", - "dev": true, - "license": "BlueOak-1.0.0", - "dependencies": { - "brace-expansion": "^5.0.8" - }, - "engines": { - "node": "18 || 20 || >=22" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/minimist": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", - "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", - "dev": true, - "license": "MIT", - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", - "dev": true, - "license": "MIT" - }, - "node_modules/parse-entities": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/parse-entities/-/parse-entities-4.0.2.tgz", - "integrity": "sha512-GG2AQYWoLgL877gQIKeRPGO1xF9+eG1ujIb5soS5gPvLQ1y2o8FL90w2QWNdf9I361Mpp7726c+lj3U0qK1uGw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/unist": "^2.0.0", - "character-entities-legacy": "^3.0.0", - "character-reference-invalid": "^2.0.0", - "decode-named-character-reference": "^1.0.0", - "is-alphanumerical": "^2.0.0", - "is-decimal": "^2.0.0", - "is-hexadecimal": "^2.0.0" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/picomatch": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.5.tgz", - "integrity": "sha512-RvwwcruNjI1ncT5xRakeyS9Lf8lcItv34KD+aif+VH9kduAyfYBipGh12274xtenIPZ119/R9BdTBa8gAwSh0A==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" - } - }, - "node_modules/punycode.js": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/punycode.js/-/punycode.js-2.3.1.tgz", - "integrity": "sha512-uxFIHU0YlHYhDQtV4R9J6a52SLx28BCjT+4ieh7IGbgwVJWO+km431c4yRlREUAsAmt/uMjQUyQHNEPf0M39CA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/run-con": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/run-con/-/run-con-1.3.3.tgz", - "integrity": "sha512-Lb7OKM9aaykzyoNiHGhSVCjZsvbyy6qDMp2vDXL+MoCfz3GfNJtHYH7uYsU3QNMyInBk++xx+EZ8xZ8Sxs5fNQ==", - "dev": true, - "license": "(BSD-2-Clause OR MIT OR Apache-2.0)", - "dependencies": { - "deep-extend": "^0.6.0", - "ini": "~7.0.0", - "minimist": "^1.2.8", - "strip-json-comments": "~3.1.1" - }, - "bin": { - "run-con": "cli.js" - } - }, - "node_modules/smol-toml": { - "version": "1.7.1", - "resolved": "https://registry.npmjs.org/smol-toml/-/smol-toml-1.7.1.tgz", - "integrity": "sha512-PPlsspAZ4jbMBu5DMFhfUGDQLu/vrL4SyBROVS37x8ynnVmFIs1VPBz1Co8Xks3TvpIaZXmU85y4DrQ+UyVFoQ==", - "dev": true, - "license": "BSD-3-Clause", - "engines": { - "node": ">= 18" - }, - "funding": { - "url": "https://github.com/sponsors/cyyynthia" - } - }, - "node_modules/string-width": { - "version": "8.2.1", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-8.2.1.tgz", - "integrity": "sha512-IIaP0g3iy9Cyy18w3M9YcaDudujEAVHKt3a3QJg1+sr/oX96TbaGUubG0hJyCjCBThFH+tFpcIyoUHUn1ogaLA==", - "dev": true, - "license": "MIT", - "dependencies": { - "get-east-asian-width": "^1.5.0", - "strip-ansi": "^7.1.2" - }, - "engines": { - "node": ">=20" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/strip-ansi": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.2.0.tgz", - "integrity": "sha512-yDPMNjp4WyfYBkHnjIRLfca1i6KMyGCtsVgoKe/z1+6vukgaENdgGBZt+ZmKPc4gavvEZ5OgHfHdrazhgNyG7w==", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-regex": "^6.2.2" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/strip-ansi?sponsor=1" - } - }, - "node_modules/strip-json-comments": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", - "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/tinyglobby": { - "version": "0.2.17", - "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.17.tgz", - "integrity": "sha512-wXR/dYpcqKmfWpEdZjiKJOwCNFndD0DMnrW/cYjVGttEkBfVgcLFHoNrlj47mjOVic9yyNu65alsgF4NQyTa2g==", - "dev": true, - "license": "MIT", - "dependencies": { - "fdir": "^6.5.0", - "picomatch": "^4.0.4" - }, - "engines": { - "node": ">=12.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/SuperchupuDev" - } - }, - "node_modules/uc.micro": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/uc.micro/-/uc.micro-2.1.0.tgz", - "integrity": "sha512-ARDJmphmdvUk6Glw7y9DQ2bFkKBHwQHLi2lsaH6PPmz/Ka9sFOBsBluozhDltWmnv9u/cF6Rt87znRTPV+yp/A==", - "dev": true, - "license": "MIT" } } } From 5857ad6241616d3f8cc32f552efa52252aaa212a Mon Sep 17 00:00:00 2001 From: Martijn Govers Date: Wed, 29 Jul 2026 17:49:09 +0200 Subject: [PATCH 07/14] Update .pre-commit-config.yaml Signed-off-by: Martijn Govers --- .pre-commit-config.yaml | 1 - 1 file changed, 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index bd2cd8b678..d1cab87a82 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -63,7 +63,6 @@ repos: pass_filenames: true types: [ markdown ] require_serial: true - # format .json and .jsonc files # format .json and .jsonc files - repo: https://github.com/biomejs/pre-commit # outside pypi rev: v2.5.6 From 0f94fe8a200a7edfeec7d147dce11b13dcd9823e Mon Sep 17 00:00:00 2001 From: Martijn Govers Date: Fri, 31 Jul 2026 14:15:17 +0200 Subject: [PATCH 08/14] remove pyml pragmas Signed-off-by: Martijn Govers --- .github/workflows/check-code-quality.yml | 1 + README.md | 2 - docs/advanced_documentation/build-guide.md | 4 -- docs/advanced_documentation/c-api.md | 2 - docs/advanced_documentation/core-design.md | 2 - .../high-level-design.md | 4 -- .../native-data-interface.md | 2 - docs/algorithms/lu-solver.md | 6 -- docs/algorithms/tap-changing-algorithms.md | 6 -- docs/contribution/folder-structure.md | 2 - docs/user_manual/calculations.md | 10 ---- docs/user_manual/components.md | 59 ------------------- docs/user_manual/data-model.md | 2 - docs/user_manual/dataset-terminology.md | 4 -- pyproject.toml | 8 +++ 15 files changed, 9 insertions(+), 105 deletions(-) diff --git a/.github/workflows/check-code-quality.yml b/.github/workflows/check-code-quality.yml index 9598a2ce2f..9e5c49c67a 100644 --- a/.github/workflows/check-code-quality.yml +++ b/.github/workflows/check-code-quality.yml @@ -56,6 +56,7 @@ jobs: run: | echo "Running pymarkdown" git ls-files -z -- '*.md' | xargs -0 -r uv run --frozen pymarkdown fix + git ls-files -z -- '*.md' | xargs -0 -r uv run --frozen pymarkdown scan - name: Install npm packages run: | diff --git a/README.md b/README.md index 6969863b74..a4664c9ef7 100644 --- a/README.md +++ b/README.md @@ -111,7 +111,6 @@ references. [![DOI](https://zenodo.org/badge/DOI/10.5281/zenodo.8054429.svg)](https://zenodo.org/record/8054429) - ```bibtex @software{Xiang_PowerGridModel_power-grid-model, author = {Xiang, Yu and Salemink, Peter and van Westering, Werner and Bharambe, Nitish and Govers, Martinus G.H. and van den Bogaard, Jonas and Stoeller, Bram and Wang, Zhen and Guo, Jerry Jinfeng and Figueroa Manrique, Santiago and Jagutis, Laurynas and Wang, Chenguang and van Raalte, Marc and {Contributors to the LF Energy project Power Grid Model}}, @@ -132,7 +131,6 @@ references. doi={10.1049/icp.2023.0633} } ``` - ## Contact diff --git a/docs/advanced_documentation/build-guide.md b/docs/advanced_documentation/build-guide.md index 44f3b21f11..8ad5fe9819 100644 --- a/docs/advanced_documentation/build-guide.md +++ b/docs/advanced_documentation/build-guide.md @@ -104,7 +104,6 @@ are automatically downloaded and used during the build — you do not need to in Manual installation is only required for standalone CMake builds. ``` - | Library name | Requirements to build Python package | Requirements to build CMake project | Remark | License | | ------------------------------------------------------------------- | ------------------------------------ | ------------------------------------------- | ----------- | ------------------------------------------------------------------------------------------------------------ | | [boost](https://www.boost.org/) | Installed automatically | CMake needs to be able find `boost` | header-only | [Boost Software License - Version 1.0](https://www.boost.org/LICENSE_1_0.txt) | @@ -112,7 +111,6 @@ Manual installation is only required for standalone CMake builds. | [nlohmann-json](https://github.com/nlohmann/json) | Installed automatically | CMake needs to be able find `nlohmann_json` | header-only | [MIT](https://github.com/nlohmann/json/blob/develop/LICENSE.MIT) | | [msgpack-cxx](https://github.com/msgpack/msgpack-c/tree/cpp_master) | Installed automatically | CMake needs to be able find `msgpack-cxx` | header-only | [Boost Software License - Version 1.0](https://github.com/msgpack/msgpack-c/blob/cpp_master/LICENSE_1_0.txt) | | [doctest](https://github.com/doctest/doctest) | None | CMake needs to be able find `doctest` | header-only | [MIT](https://github.com/doctest/doctest/blob/master/LICENSE.txt) | - To install the C++ dependencies for a CMake build, use your platform's package manager of choice. In the platform-specific examples below, we will give some suggestions. @@ -126,7 +124,6 @@ Set `CMAKE_PREFIX_PATH` to the installation prefix of your package manager so CM The table below shows the Python dependencies. - | Library name | Remark | License | |------------------------------------------------------------------------|------------------------|--------------------------------------------------------------------------------------------| | [numpy](https://numpy.org/) | Runtime dependency | [BSD-3](https://github.com/numpy/numpy/blob/main/LICENSE.txt) | @@ -135,7 +132,6 @@ The table below shows the Python dependencies. | [pytest-cov](https://github.com/pytest-dev/pytest-cov) | Development dependency | [MIT](https://github.com/pytest-dev/pytest-cov/blob/master/LICENSE) | | [msgpack-python](https://github.com/msgpack/msgpack-python) | Development dependency | [Apache License, Version 2.0](https://github.com/msgpack/msgpack-python/blob/main/COPYING) | | [uv](https://github.com/astral-sh/uv) | Development dependency | [Apache License, Version 2.0](https://github.com/astral-sh/uv/blob/main/LICENSE-APACHE) | - ## Build Python Package diff --git a/docs/advanced_documentation/c-api.md b/docs/advanced_documentation/c-api.md index 268f89800e..b1442faf0a 100644 --- a/docs/advanced_documentation/c-api.md +++ b/docs/advanced_documentation/c-api.md @@ -121,7 +121,6 @@ versions, compilers, operating systems and architectures. * an aligned size of 8 bytes * a 4 bytes alignment - ```txt <-- 3 lines. | | | | | | | <-- alignment: a line may start every 4 bytes. @@ -129,7 +128,6 @@ iiiift iiiift iiiift <-- data: 6 bytes per line: 4 bytes for the ID, 1 for | ..| ..| ..| <-- padding: (4 - (6 mod 4) = 2) bytes after every line. | | | | <-- aligned size: (6 + 2 = 8) bytes every line. ``` - #### Create and destroy buffer diff --git a/docs/advanced_documentation/core-design.md b/docs/advanced_documentation/core-design.md index b8ed489b13..0e1d0382bc 100644 --- a/docs/advanced_documentation/core-design.md +++ b/docs/advanced_documentation/core-design.md @@ -17,7 +17,6 @@ The `MainModel` itself can be deconstructed into an API part, a dispatch part, t The logic involved in power grid calculations in turn can be devided in a number of separate modules. Coincidentally, those phases also translate to fields of expertise, which enables a reasonably clean architecture. - | Logic/control module | Description | Expertise | | -------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------- | ---------------------- | | I/O | Constructing, updating and outputting components in the power grid | Software Engineering | @@ -25,7 +24,6 @@ Coincidentally, those phases also translate to fields of expertise, which enable | $Y_{\text{bus}}$ construction/Component extraction | Constructing $Y_{\text{bus}}$ from the power grid components and topology | Electrical Engineering | | Solver construction/Grid extraction | Translation from $Y_{\text{bus}}$ to a solvable system of equations and from the solution back to physical values | Physics | | Solving | Abstract solution to the system of equations | Mathematics | - ```{note} Software Engineering obviously also plays a role in the general design, but that general design does not involve the diff --git a/docs/advanced_documentation/high-level-design.md b/docs/advanced_documentation/high-level-design.md index 88aaf786e6..efadc1d193 100644 --- a/docs/advanced_documentation/high-level-design.md +++ b/docs/advanced_documentation/high-level-design.md @@ -34,21 +34,18 @@ abstraction. The following library interfaces are currently included in the power-grid-model. - | Interface type | Status | Layer | Explanation | Supported by | | -------------- | ------------ | ------------------ | --------------------------------------------------------------- | --------------------------------------------------- | | C API | Stable | Raw interface | Shared object / DLL that contains the core implementation | All programming languages with dynamic load support | | C headers | Stable | Exposition-only | Exposition-only library using dynamic linking | C and C++ | | C++ headers | Experimental | Wrapper | Handles memory management and basic error handling | C++ | | Python library | Stable | Feature-rich layer | Library with useful functions, conversions and extensive checks | Python | - Note that the Python library in turn also follows the pattern of a feature-rich library that uses a module-internal wrapper layer core module, that wraps the exposition-only core module, that exposes the raw interface. This can be visualized graphically as follows. - ```{mermaid} :title: Full design @@ -96,7 +93,6 @@ flowchart TD cpp_user -->|experimental
links +
includes| power_grid_model_cpp -->|links +
includes| power_grid_model_c python_user -->|import| power_grid_model_python -->|internal import| power_grid_model_core_python -->|internal import| power_grid_core_python -->|"CDLL
(dynamic loading)"| power_grid_model_c_dll ``` - ## Creating a custom library or interface diff --git a/docs/advanced_documentation/native-data-interface.md b/docs/advanced_documentation/native-data-interface.md index 1e68a54d0f..8442217dfe 100644 --- a/docs/advanced_documentation/native-data-interface.md +++ b/docs/advanced_documentation/native-data-interface.md @@ -119,14 +119,12 @@ The pointers are passed into C++ code so that the C++ program can write results The basic data types used in the interface between C++ and Python are shown in the table below. - | C++ type | `numpy.dtype` | null value | usage | | ----------- | ------------- | --------------------------------------------------- | --------------------------------------------------------------------------------------- | | `int32_t` | `'i4'` | - 2^31 | ids of physical components | | `int8_t` | `'i1'` | - 2^7 | enumeration types, boolean types, and small integers (e.g. tap position of transformer) | | `double` | `'f8'` | NaN ([IEEE 754](https://en.wikipedia.org/wiki/NaN)) | physical quantities (e.g. voltage) | | `double[3]` | `'(3, )f8'` | NaN ([IEEE 754](https://en.wikipedia.org/wiki/NaN)) | three-phase asymmetric physical quantities (e.g. voltage) | - *The [endianness](https://en.wikipedia.org/wiki/Endianness) of C++ and Python side is also matched. For `x86-64` platform the little endian is used, so that the `numpy.dtype` is `' 1. Initialize the permutations $\mathbf{P}$ and $\mathbf{Q}$ to the identity permutation. 2. Initialize fill-in elements to $0$. 3. Loop over all rows: $p = 0..(N-1)$: @@ -332,7 +331,6 @@ $\mathbf{M}\left[0:3, j\right]$. 1. In $\mathbf{P}$: swap $p \leftrightarrow p + i_p$ 2. In $\mathbf{Q}$: swap $p \leftrightarrow p + j_p$ 8. Continue with the next $p$ to factorize the the bottom-right block. - $\mathbf{L}$ is now the matrix containing the lower triangle of $\mathbf{M}$, ones on the diagonal and zeros in the upper triangle. @@ -1188,11 +1186,9 @@ $$ \end{bmatrix} $$ - * The regular $L_{\infty}$-norm is $\max\left\{1+3, 3, 5, \frac{1}{2}, 1, 1\right\} = 5$. * The block-wise off-diagonal infinity $L_{\infty ,\text{bwod}}$-norm is $\max\left\{\max\left\{1, 3\right\}+\max\left\{3, 0\right\},\max\left\{5, 0\right\} + \max\left\{0, \frac{1}{2}\right\}, 1\right\} = \max\left\{3+3, 5+\frac{1}{2}, 1, 1\right\} = 6$. - The two norms clearly differ and even the elements that contribute most to the norm are different. @@ -1217,10 +1213,8 @@ $$ \end{bmatrix} $$ - * The regular $L_{\infty}$-norm is $\max\left\{20+20+2+2,30+3,100,3+1\right\} = \max\left\{44,33,100,4\right\} = 100$. * The block-wise infinity norm with diagonals would be $\max\left\{\max\left\{20+20, 30\right\}+\max\left\{2+2, 3\right\},\max\left\{0,3\right\} + \max\left\{100, 1\right\}\right\} = \max\left\{40+4, 3+100\right\} = \max\left\{44, 103\right\} = 103$. * The $L_{\infty ,\text{bwod}}$-norm is $\max\left\{\max\left\{2+2, 3\right\},\max\left\{0,3\right\}\right\} = \max\left\{4, 3\right\} = 4$. - diff --git a/docs/algorithms/tap-changing-algorithms.md b/docs/algorithms/tap-changing-algorithms.md index ef080bc002..60c82ad423 100644 --- a/docs/algorithms/tap-changing-algorithms.md +++ b/docs/algorithms/tap-changing-algorithms.md @@ -41,28 +41,24 @@ regulator is automatic. The following table specifies the behaviour of regulated transformers based on the {py:class}`TapChangingStrategy ` chosen and whether `tap_pos` is regulated. - |TapChangingStrategy|tap_pos is regulated?|Initialization phase|Exploitation phase| |---|---|---|---| |{py:class}`any_valid_tap `|Yes|Set the tap position to `tap_nom` (default middle tap position)|Binary search (default)| |{py:class}`any_valid_tap `|No|Clamp the tap position to stay within `tap_min` and `tap_max`|Do not regulate| |{py:class}`min_voltage_tap ` / {py:class}`max_voltage_tap `|Yes|Set the tap position to `tap_min` or `tap_max` respectively|Do not regulate| |{py:class}`min_voltage_tap ` / {py:class}`max_voltage_tap `|No|Clamp the tap position to stay within `tap_min` and `tap_max`|Do not regulate| - Some transformer configurations require clamping due to `regulated_object` and `tap_side` pointing to different sides of the transformer. For a three-winding transformer the requirements are similar to a regular transformer with the additional consideration that the primary side tap changer regulates only the secondary or tertiary side voltages: - |Tapping on side|Regulated object|Voltage control side|`tap_side`|`regulated_object`|`control_side`| |---|---|---|---|---|---| |HV (0)|LV (1)|LV (1)|`BranchSide.from_side` / `Branch3Side.side_1`|`TransformerTapSide.side_1` / `Branch3Side.side_2`|`BranchSide.to_side` / `Branch3Side.side_2`| |HV (0)|LV (1)|HV (0)|`BranchSide.from_side` / `Branch3Side.side_1`|`TransformerTapSide.side_1` / `Branch3Side.side_2`|`BranchSide.from_side` / `Branch3Side.side_1`| |LV (1)|HV (0)|LV (1)|`BranchSide.to_side` / `Branch3Side.side_2`|`TransformerTapSide.side_2` / `Branch3Side.side_1`|`BranchSide.to_side` / `Branch3Side.side_2`| |LV (1)|HV (0)|HV (0)|`BranchSide.to_side` / `Branch3Side.side_2`|`TransformerTapSide.side_2` / `Branch3Side.side_1`|`BranchSide.from_side` / `Branch3Side.side_1`| - ## Search methods used for tap changing optimization @@ -70,13 +66,11 @@ By default, the algorithm uses binary search to find the optimal tap position to Users can also choose other search methods via {py:class}`TapChangingStrategy `: - |{py:class}`TapChangingStrategy `|Description| |---|---| |{py:class}`fast_any_tap `|Very fast search (single step per iteration)| |{py:class}`any_valid_tap `|Binary search (default)| |{py:class}`min_voltage_tap ` / {py:class}`max_voltage_tap `|Set to extreme tap and do not regulate| - ## Regulatable voltage range outside `u_band` diff --git a/docs/contribution/folder-structure.md b/docs/contribution/folder-structure.md index 57d0e0334d..5107427bda 100644 --- a/docs/contribution/folder-structure.md +++ b/docs/contribution/folder-structure.md @@ -8,7 +8,6 @@ SPDX-License-Identifier: MPL-2.0 The repository folder structure is as follows. The `docs` and `scripts` folders are self-explanatory. - - The C++ calculation core is inside {{ "[power_grid_model_c/power_grid_model/include/power_grid_model]({}/power_grid_model_c/power_grid_model/include/power_grid_model)".format(gh_link_head_tree) }}. - The C API is inside @@ -30,4 +29,3 @@ The repository folder structure is as follows. The `docs` and `scripts` folders - `data` contains validation test cases designed for every component and algorithm. Some sample network types are also included. The validation is either against popular power system analysis software or hand calculation. - diff --git a/docs/user_manual/calculations.md b/docs/user_manual/calculations.md index e97db67a98..990678a965 100644 --- a/docs/user_manual/calculations.md +++ b/docs/user_manual/calculations.md @@ -294,14 +294,12 @@ right one. At the moment, the following power flow algorithms are implemented. - | Algorithm | Speed | Result | Convergence | Typical Use Cases | Algorithm call | |--------------------------------------------------------------------------------- |---------------------------------- |---------------------------------- |-------------------- |------------------------------------------------------------------------ |----------------------------------------------------------------------------------------------------------- | | [Newton-Raphson](../algorithms/pf-algorithms.md#newton-raphson-power-flow) | Medium | Accurate within `error_tolerance` | Quadratic, robust | General purpose, any type of grid | {py:class}`CalculationMethod.newton_raphson ` | | [Iterative current](../algorithms/pf-algorithms.md#iterative-current-power-flow) | Fast (Radial) Slow (Meshed) | Accurate within `error_tolerance` | Linear, less robust | Non-topological change batch calculations like timeseries, radial grids | {py:class}`CalculationMethod.iterative_current `| | [Linear](../algorithms/pf-algorithms.md#linear-power-flow) | Much Faster | Approximate | Single iteration | Large number of calculations, troubleshooting iterative methods | {py:class}`CalculationMethod.linear ` | | [Linear current](../algorithms/pf-algorithms.md#linear-current-power-flow) | Much Faster | Approximate | Single iteration | Large number of calculations | {py:class}`CalculationMethod.linear_current ` | - ```{note} By default, the [Newton-Raphson](../algorithms/pf-algorithms.md#newton-raphson-power-flow) method is used. @@ -360,11 +358,9 @@ Regulated power flow calculations are disabled by default. At the time of writing, the following regulated power flow calculation types are implemented. Please refer to their respective sections for detailed documentation. - | Regulation type | Setting | Enum values | | ----------------------------------------------------------------- | --------------------------------------------------------------------------------------- | --------------------------------------------------------------------------- | | [Automatic tap changing](#power-flow-with-automatic-tap-changing) | {py:meth}`tap_changing_strategy ` | {py:class}`TapChangingStrategy ` | - #### Power flow with automatic tap changing @@ -377,7 +373,6 @@ Power flow calculations that take the behavior of these regulators into account following strategies to the {py:meth}`tap_changing_strategy ` option. - | Algorithm | Default | Speed | Algorithm call | | --------------------------------------------------------------------------- | -------- | -------- | ----------------------------------------------------------------------------------------------------------- | | No automatic tap changing (regular power flow) | ✔ | ✔ | {py:class}`TapChangingStrategy.disabled ` | @@ -385,7 +380,6 @@ option. | Optimize tap positions for lowest possible voltage in the voltage band | | | {py:class}`TapChangingStrategy.min_voltage_tap ` | | Optimize tap positions for lowest possible voltage in the voltage band | | | {py:class}`TapChangingStrategy.max_voltage_tap ` | | Optimize tap positions for any value in the voltage band with binary search | | ✔ | {py:class}`TapChangingStrategy.fast_any_tap ` | - For detailed control logic, initialization behavior, search methods, and error handling for automatic tap changing, see [Automatic Tap Changing Algorithm Details](../algorithms/tap-changing-algorithms.md). @@ -397,12 +391,10 @@ the highest likelihood given (pseudo) measurement input. At the moment, the following state estimation algorithms are implemented. - | Algorithm | Default | Speed | Accuracy | Algorithm call | | --------- | ------- | ----- | -------- | -------------- | | [Iterative linear](../algorithms/se-algorithms.md#iterative-linear-state-estimation) | ✔ | ✔ | | {py:class}`CalculationMethod.iterative_linear ` | | [Newton-Raphson](../algorithms/se-algorithms.md#newton-raphson-state-estimation) | | | ✔ | {py:class}`CalculationMethod.newton_raphson ` | - ```{note} By default, the [Iterative linear](../algorithms/se-algorithms.md#iterative-linear-state-estimation) method is used. @@ -419,11 +411,9 @@ of short circuit studies applications. At the moment, the following short circuit algorithms are implemented. - | Algorithm | Default | Speed | Accuracy | Algorithm call | | --------- | ------- | ----- | -------- | -------------- | | [IEC 60909](../algorithms/sc-algorithms.md#iec-60909-short-circuit-calculation) | ✔ | ✔ | | {py:class}`CalculationMethod.iec60909 ` | - For detailed mathematical descriptions including the short circuit equations and IEC 60909 implementation details, see [Short Circuit Algorithm Details](../algorithms/sc-algorithms.md). diff --git a/docs/user_manual/components.md b/docs/user_manual/components.md index 569c90a3d3..265f1b50ca 100644 --- a/docs/user_manual/components.md +++ b/docs/user_manual/components.md @@ -21,11 +21,9 @@ The base type for all power-grid-model components. #### Input - | name | data type | unit | description | required | update | |------|-----------|------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------|:--------:|:--------------------:| | `id` | `int32_t` | - | ID of a component. The ID should be unique across all components within the same scenario, e.g., you cannot have a node with `id=5` and another line with `id=5`. | ✔ | ❌ (see below) | - If a component update is uniform and is updating all the elements with the same component type, IDs can be omitted or set to `nan`s. @@ -39,12 +37,10 @@ An example of the usage of optional IDs is given in [Power Flow Example](./Power #### Steady state output and Short circuit output - | name | data type | unit | description | |-------------|-----------|------|------------------------------------------------------------------------------------------------------------------------------------| | `id` | `int32_t` | - | ID of a component, the ID should be unique across all components, e.g., you cannot have a node with `id=5` and a line with `id=5`. | | `energized` | `int8_t` | - | Indicates if a component is energized, i.e. connected to a source | - ## Node @@ -62,7 +58,6 @@ Physically a node can be a busbar, a joint, or other similar component. #### Steady state output - | name | data type | unit | description | |-----------|-------------------|----------------------------|-------------------------------------------------------------------------------------------------| | `u_pu` | `RealValueOutput` | - | per-unit voltage magnitude | @@ -70,7 +65,6 @@ Physically a node can be a busbar, a joint, or other similar component. | `u` | `RealValueOutput` | volt (V) | voltage magnitude, line-line for symmetric calculation, line-neutral for asymmetric calculation | | `p` | `RealValueOutput` | watt (W) | active power injection | | `q` | `RealValueOutput` | volt-ampere-reactive (var) | reactive power injection | - ```{note} The `p` and `q` output of injection follows the `generator` reference direction as mentioned in @@ -107,7 +101,6 @@ In this case, the attribute `from_status` and `to_status` is always 1. #### Steady state output - | name | data type | unit | description | |-----------|-------------------|----------------------------|------------------------------------------------------------| | `p_from` | `RealValueOutput` | watt (W) | active power flowing into the branch at from-side | @@ -119,7 +112,6 @@ In this case, the attribute `from_status` and `to_status` is always 1. | `i_to` | `RealValueOutput` | ampere (A) | magnitude of current at to-side | | `s_to` | `RealValueOutput` | volt-ampere (VA) | apparent power flowing at to-side | | `loading` | `double` | - | relative loading of the branch, `1.0` meaning 100% loaded. | - #### Short circuit output @@ -141,7 +133,6 @@ If `i_n` is not provided, `loading` of line will be a `nan` value. #### Input - | name | data type | unit | description | required | update | valid values | |--------|-----------|------------|----------------------------------------------------|:-----------------------------------------:|:--------:|:----------------------------------:| | `r1` | `double` | ohm (Ω) | positive-sequence serial resistance | ✔ | ❌ | `r1` and `x1` cannot be both `0.0` | @@ -153,7 +144,6 @@ If `i_n` is not provided, `loading` of line will be a `nan` value. | `c0` | `double` | farad (F) | zero-sequence shunt capacitance | ✨ only for asymmetric calculations | ❌ | | | `tan0` | `double` | - | zero-sequence shunt loss factor (tan δ) | ✨ only for asymmetric calculations | ❌ | | | `i_n` | `double` | ampere (A) | rated current | ❌ | ❌ | `> 0` | - ```{note} In case of short circuit calculations, the zero-sequence parameters are required only if any of the faults in any of the @@ -201,7 +191,6 @@ An example of usage of transformer is given in [Transformer Examples](../example #### Input - | name | data type | unit | description | required | update | valid values | |--------------------|-------------------------------------------------------------|------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|:--------------------------------------------------------:|:--------:|:----------------------------------------------------------------------:| | `u1` | `double` | volt (V) | rated voltage at from-side | ✔ | ❌ | `> 0` | @@ -230,7 +219,6 @@ An example of usage of transformer is given in [Transformer Examples](../example | `x_grounding_from` | `double` | ohm (Ω) | grounding reactance at from-side, if relevant | ❌ default `0` | ❌ | | | `r_grounding_to` | `double` | ohm (Ω) | grounding resistance at to-side, if relevant | ❌ default `0` | ❌ | | | `x_grounding_to` | `double` | ohm (Ω) | grounding reactance at to-side, if relevant | ❌ default `0` | ❌ | | - ```{note} It can happen that `tap_min > tap_max`. @@ -288,7 +276,6 @@ using a `generic_branch`. #### Input - | name | data type | unit | description | required | update | valid values | |---------|-----------|------------------|-------------------------------|:----------------------:|:--------:|:------------:| | `r1` | `double` | ohm | positive-sequence resistance | ✔ | ❌ | | @@ -298,7 +285,6 @@ using a `generic_branch`. | `k` | `double` | - | off-nominal ratio | ❌ default `1.0` | ❌ | `> 0` | | `theta` | `double` | radian | angle shift | ❌ default `0.0` | ❌ | | | `sn` | `double` | volt-ampere (VA) | rated power | ❌ default `0.0` | ❌ | `>= 0` | - ```{note} The impedance (`r1`, `x1`) and admittance (`g1`, `b1`) attributes are calculated with reference to the "to" side of the @@ -361,7 +347,6 @@ $$ This representation holds for all values `r_aa` ... `r_nn`, `x_aa` ... `x_nn` and `c_aa` ... `c_cc`. If the neutral values are not provided, the last row and column from the above matrix are omitted. - | name | data type | unit | description | required | update | valid values | |--------|-----------|------------|-----------------------------------|------------------------------|:--------:|:------------:| | `r_aa` | `double` | ohm (Ω) | Series serial resistance aa | ✔ | ❌ | `> 0` | @@ -393,7 +378,6 @@ If the neutral values are not provided, the last row and column from the above m | `c0` | `double` | farad (F) | zero-sequence shunt capacitance | ✨ without a c matrix | ❌ | `> 0` | | `c1` | `double` | farad (F) | Series shunt capacitance | ✨ without a c matrix | ❌ | `> 0` | | `i_n` | `double` | ampere (A) | rated current | ❌ | ❌ | `> 0` | - For the r and x matrices providing values for the neutral phase is optional. To clarify which input values are required, please consult the tables below: @@ -496,7 +480,6 @@ In reality such switches may not exist. #### Steady state output - | name | data type | unit | description | |-----------|-------------------|----------------------------|------------------------------------------------------------| | `p_1` | `RealValueOutput` | watt (W) | active power flowing into the branch at side 1 | @@ -512,7 +495,6 @@ In reality such switches may not exist. | `i_3` | `RealValueOutput` | ampere (A) | current at side 3 | | `s_3` | `RealValueOutput` | volt-ampere (VA) | apparent power flowing at side 3 | | `loading` | `double` | - | relative loading of the branch, `1.0` meaning 100% loaded. | - #### Short circuit output @@ -534,7 +516,6 @@ An example of usage of three-winding transformer is given in #### Input - | name | data type | unit | description | required | update | valid values | |-----------------|-------------------------------------------------------------|------------------|-----------------------------------------------------------------------------------------------------------|:-------------------------------------------------------:|:--------:|:----------------------------------------------------------------------:| | `u1` | `double` | volt (V) | rated voltage at side 1 | ✔ | ❌ | `> 0` | @@ -580,7 +561,6 @@ An example of usage of three-winding transformer is given in | `x_grounding_2` | `double` | ohm (Ω) | grounding reactance at side 2, if relevant | ❌ default `0` | ❌ | | | `r_grounding_3` | `double` | ohm (Ω) | grounding resistance at side 3, if relevant | ❌ default `0` | ❌ | | | `x_grounding_3` | `double` | ohm (Ω) | grounding reactance at side 3, if relevant | ❌ default `0` | ❌ | | - ```{note} It can happen that `tap_min > tap_max`. @@ -641,7 +621,6 @@ The impedance is specified by convention as short circuit power. #### Input - | name | data type | unit | description | required | update | valid values | |---------------|-----------|------------------|----------------------------------------------------|:----------------------------:|:--------:|:------------:| | `u_ref` | `double` | - | reference voltage in per-unit | ✨ only for power flow | ✔ | `> 0` | @@ -649,7 +628,6 @@ The impedance is specified by convention as short circuit power. | `sk` | `double` | volt-ampere (VA) | short circuit power | ❌ default `1e10` | ✔ | `> 0` | | `rx_ratio` | `double` | - | R to X ratio | ❌ default `0.1` | ✔ | `>= 0` | | `z01_ratio` | `double` | - | zero-sequence to positive sequence impedance ratio | ❌ default `1.0` | ✔ | `> 0` | - #### Electric Model @@ -685,11 +663,9 @@ $$ `generic_load_gen` is an abstract load/generation [appliance](#appliance) which contains only the type of the load/generation with response to voltage. - | name | data type | unit | description | required | update | |--------|-------------------------------------------------------------|------|-------------------------------------------------|:--------:|:--------:| | `type` | {py:class}`LoadGenType ` | - | type of load/generator with response to voltage | ✔ | ❌ | - #### Load/Generator Concrete Types @@ -706,12 +682,10 @@ However, the reference direction and meaning of `RealValueInput` is different, a ##### Input - | name | data type | unit | description | required | update | |---------------|------------------|----------------------------|--------------------------|:----------------------------:|:--------:| | `p_specified` | `RealValueInput` | watt (W) | specified active power | ✨ only for power flow | ✔ | | `q_specified` | `RealValueInput` | volt-ampere-reactive (var) | specified reactive power | ✨ only for power flow | ✔ | - ##### Electric model @@ -750,14 +724,12 @@ It behaves similar to a load/generator with type `const_impedance`. #### Input - | name | data type | unit | description | required | update | |------|-----------|-------------|-------------------------------------|:----------------------------------------:|:--------:| | `g1` | `double` | siemens (S) | positive-sequence shunt conductance | ✔ | ✔ | | `b1` | `double` | siemens (S) | positive-sequence shunt susceptance | ✔ | ✔ | | `g0` | `double` | siemens (S) | zero-sequence shunt conductance | ✨ only for asymmetric calculation | ✔ | | `b0` | `double` | siemens (S) | zero-sequence shunt susceptance | ✨ only for asymmetric calculation | ✔ | - ```{note} In power-grid-model, shunts may also be used to introduce a ground reference in an otherwise floating grid. @@ -803,11 +775,9 @@ It measures the magnitude and (optionally) the angle of the voltage of a `node`. #### Input - | name | data type | unit | description | required | update | valid values | |-----------|-----------|----------|-----------------------------------------------------------------------------------------------------------------|:----------------------------------:|:--------:|:------------:| | `u_sigma` | `double` | volt (V) | standard deviation of the measurement error. Usually this is the absolute measurement error range divided by 3. | ✨ only for state estimation | ✔ | `> 0` | - #### Voltage Sensor Concrete Types @@ -823,12 +793,10 @@ In a `asym_voltage_sensor` the measured voltage is a 3-phase line-to-ground volt ##### Input - | name | data type | unit | description | required | update | valid values | |--------------------|------------------|----------|----------------------------------------------------------------------|:----------------------------------------------------------------------------------------------------------------:|:--------:|:------------:| | `u_measured` | `RealValueInput` | volt (V) | measured voltage magnitude | ✨ only for state estimation | ✔ | `> 0` | | `u_angle_measured` | `RealValueInput` | rad | measured voltage angle (only possible with phasor measurement units) | ✨ only for state estimation when a current sensor with `global_angle` `angle_measurement_type` is present | ✔ | | - ```{note} When a current sensor with `global_angle` `angle_measurement_type` is present there needs to be a voltage sensor with @@ -842,12 +810,10 @@ A sensor only has output for state estimation. For other calculation types, sensor output is undefined. ``` - | name | data type | unit | description | |--------------------|-------------------|----------|--------------------------------------------------------------------------------------------------------------------------| | `u_residual` | `RealValueOutput` | volt (V) | residual value between measured voltage magnitude and calculated voltage magnitude | | `u_angle_residual` | `RealValueOutput` | rad | residual value between measured voltage angle and calculated voltage angle (only possible with phasor measurement units) | - #### Electric Model @@ -900,12 +866,10 @@ However, such mixing of sensor types is allowed as long as they are on different ##### Input - | name | data type | unit | description | required | update | valid values | |--------------------------|-------------------------------------------------------------------------------|------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|:-----------------------------------------------------------------------------------------------------------------------------:|:--------:|:----------------------------------------------------:| | `measured_terminal_type` | {py:class}`MeasuredTerminalType ` | - | indicate if it measures an `appliance` or a `branch` | ✔ | ❌ | the terminal type should match the `measured_object` | | `power_sigma` | `double` | volt-ampere (VA) | standard deviation of the measurement error. Usually this is the absolute measurement error range divided by 3. See [Power Sensor Concrete Types](#power-sensor-concrete-types). | ✨ in certain cases for state estimation. See the explanation for [concrete types](#power-sensor-concrete-types) below. | ✔ | `> 0` | - #### Power Sensor Concrete Types @@ -919,14 +883,12 @@ They share similar attributes: the meaning of `RealValueInput` is different, as ##### Input - | name | data type | unit | description | required | update | valid values | |--------------|------------------|----------------------------|--------------------------------------------------------------------------------------------------------------------------------|:-----------------------------------:|:--------:|:------------:| | `p_measured` | `RealValueInput` | watt (W) | measured active power | ✨ only for state estimation | ✔ | | | `q_measured` | `RealValueInput` | volt-ampere-reactive (var) | measured reactive power | ✨ only for state estimation | ✔ | | | `p_sigma` | `RealValueInput` | watt (W) | standard deviation of the active power measurement error. Usually this is the absolute measurement error range divided by 3. | ❌ see the explanation below. | ✔ | `> 0` | | `q_sigma` | `RealValueInput` | volt-ampere-reactive (var) | standard deviation of the reactive power measurement error. Usually this is the absolute measurement error range divided by 3. | ❌ see the explanation below. | ✔ | `> 0` | - Valid combinations of `power_sigma`, `p_sigma` and `q_sigma` are: @@ -948,7 +910,6 @@ measurement. 2. If neither `p_sigma` nor `q_sigma` are provided, `power_sigma` represents the standard deviation of the apparent power. In this case, infinite value of `power_sigma` disables the entire measurement. - 3. Providing only one of `p_sigma` and `q_sigma` results in undefined behaviour. ``` @@ -964,12 +925,10 @@ A sensor only has output for state estimation. For other calculation types, sensor output is undefined. ``` - | name | data type | unit | description | |--------------|-------------------|----------------------------|------------------------------------------------------------------------------| | `p_residual` | `RealValueOutput` | watt (W) | residual value between measured active power and calculated active power | | `q_residual` | `RealValueOutput` | volt-ampere-reactive (var) | residual value between measured reactive power and calculated reactive power | - #### Electric Model @@ -1008,14 +967,12 @@ However, such mixing of sensor types is allowed as long as they are on different ##### Input - | name | data type | unit | description | required | update | valid values | |--------------------------|-------------------------------------------------------------------------------|------------|-------------------------------------------------------------------------------------------------------------------------------------------|:----------------------------------:|:--------:|:----------------------------------------------------:| | `measured_terminal_type` | {py:class}`MeasuredTerminalType ` | - | indicate the side of the `branch` | ✔ | ❌ | the terminal type should match the `measured_object` | | `angle_measurement_type` | {py:class}`AngleMeasurementType ` | - | indicate whether the measured angle is a global angle or a local angle; (see the [electric model](#local-angle-current-sensors) below) | ✔ | ❌ | | | `i_sigma` | `double` | ampere (A) | standard deviation of the current (`i`) measurement error. Usually this is the absolute measurement error range divided by 3. | ✨ only for state estimation | ✔ | `> 0` | | `i_angle_sigma` | `double` | rad | standard deviation of the current (`i`) phase angle measurement error. Usually this is the absolute measurement error range divided by 3. | ✨ only for state estimation | ✔ | `> 0` | - #### Current Sensor Concrete Types @@ -1029,12 +986,10 @@ They share similar attributes: the meaning of `RealValueInput` is different, as ##### Input - | name | data type | unit | description | required | update | |--------------------|------------------|------------|---------------------------------------------------------------------------------------------------------|:----------------------------------:|:--------:| | `i_measured` | `RealValueInput` | ampere (A) | measured current (`i`) magnitude | ✨ only for state estimation | ✔ | | `i_angle_measured` | `RealValueInput` | rad | measured phase angle of the current (`i`; see the [electric model](#local-angle-current-sensors) below) | ✨ only for state estimation | ✔ | - See the documentation on [state estimation calculation methods](calculations.md#state-estimation-algorithms) for details per method on how the variances are taken into account for both the global and local angle measurement types and for the @@ -1052,12 +1007,10 @@ A sensor only has output for state estimation. For other calculation types, sensor output is undefined. ``` - | name | data type | unit | description | |--------------------|-------------------|------------|---------------------------------------------------------------------------------------------| | `i_residual` | `RealValueOutput` | ampere (A) | residual value between measured current (`i`) and calculated current (`i`) | | `i_angle_residual` | `RealValueOutput` | rad | residual value between measured phase angle and calculated phase angle of the current (`i`) | - #### Electric Model @@ -1125,7 +1078,6 @@ A fault can only happen at a `node`. #### Input - | name | data type | unit | description | required | update | valid values | |----------------|-----------------------------------------------------------|---------|-----------------------------------------------------|:-------------------------------------------------------------------------------------------------------:|:--------:|:-----------------:| | `status` | `int8_t` | - | whether the fault is active | ✔ | ✔ | `0` or `1` | @@ -1134,7 +1086,6 @@ A fault can only happen at a `node`. | `fault_object` | `int32_t` | - | ID of the component where the short circuit happens | ✔ | ✔ | A valid `node` ID | | `r_f` | `double` | ohm (Ω) | short circuit resistance | ❌ default `0.0` | ✔ | | | `x_f` | `double` | ohm (Ω) | short circuit reactance | ❌ default `0.0` | ✔ | | - ```{note} Multiple faults may exist within one calculation. @@ -1168,14 +1119,12 @@ In case the `fault_phase` is not specified or is equal to `FaultPhase.default_va `fault_type`-dependent set of fault phases. The supported values of `fault_phase`, as well as its default value, are listed in the table below. - | `fault_type` | supported values of `fault_phase` | `FaultPhase.default_value` | description | |------------------------------------|---------------------------------------------------|----------------------------|------------------------------------------------------------------------| | `FaultType.three_phase` | `FaultPhase.abc` | `FaultPhase.abc` | Three phases are connected with fault impedance. | | `FaultType.single_phase_to_ground` | `FaultPhase.a`, `FaultPhase.b`, `FaultPhase.c` | `FaultPhase.a` | One phase is grounded with fault impedance, and other phases are open. | | `FaultType.two_phase` | `FaultPhase.bc`, `FaultPhase.ac`, `FaultPhase.ab` | `FaultPhase.bc` | Two phases are connected with fault impedance. | | `FaultType.two_phase_to_ground` | `FaultPhase.bc`, `FaultPhase.ac`, `FaultPhase.ab` | `FaultPhase.bc` | Two phases are connected with fault impedance then grounded. | - ## Regulator @@ -1188,12 +1137,10 @@ Which object types are supported as `regulated_object` is regulator type-depende #### Input - | name | data type | unit | description | required | update | valid values | |--------------------|-----------|------|-------------------------------------------|:--------:|:--------:|:---------------------------:| | `regulated_object` | `int32_t` | - | ID of the regulated object | ✔ | ❌ | a valid regulated object ID | | `status` | `int8_t` | - | connection status to the regulated object | ✔ | ✔ | `0` or `1` | - ### Transformer tap regulator @@ -1220,7 +1167,6 @@ The actual grid state is not changed after calculations are done. #### Input - | name | data type | unit | description | required | update | valid values | |----------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|----------|---------------------------------------------------------------------------------------------------------|:----------------------------:|:--------:|:----------------------------------------------------------------:| | `control_side` | {py:class}`BranchSide ` if the regulated object is a [transformer](#transformer) and {py:class}`Branch3Side ` if it the regulated object is a [Three-Winding Transformer](#three-winding-transformer) | - | the controlled side of the transformer | ✨ only for power flow | ❌ | `control_side` should be the relatively further side to a source | @@ -1228,7 +1174,6 @@ The actual grid state is not changed after calculations are done. | `u_band` | `double` | volt (V) | the width of the voltage band ($=2*\left(\Delta U\right)_{\text{acceptable}}$) | ✨ only for power flow | ✔ | `> 0` (see below) | | `line_drop_compensation_r` | `double` | ohm (Ω) | compensation for voltage drop due to resistance during transport (see [below](#line-drop-compensation)) | ❌ default `0.0` | ✔ | `>= 0` | | `line_drop_compensation_x` | `double` | ohm (Ω) | compensation for voltage drop due to reactance during transport (see [below](#line-drop-compensation)) | ❌ default `0.0` | ✔ | `>= 0` | - The following additional requirements exist on the input parameters. @@ -1339,22 +1284,18 @@ the voltage regulator should operate at the limit and the voltage may deviate fr #### Input - | name | data type | unit | description | required | update | valid values | | -------- | --------- | -------------------------- | --------------------------------------------------- | :--------------------------: | :------: | :----------: | | `u_ref` | `double` | - | reference voltage in per-unit at the generator node | ✨ only for power flow | ✔ | `> 0` | | `q_min` | `double` | volt-ampere-reactive (var) | minimum reactive power limit of the generator | ❌ | ✔ | | | `q_max` | `double` | volt-ampere-reactive (var) | maximum reactive power limit of the generator | ❌ | ✔ | | - #### Steady state output - | name | data type | unit | description | | ----------------- | ----------------- | -------------------------- | -------------------------------------------------------------------- | | `q` | `RealValueOutput` | volt-ampere-reactive (var) | reactive power provided by the voltage regulator | | `limit_violated` | `int8_t` | - | reactive power limit violation indicator (not yet fully implemented) | - #### Short circuit output diff --git a/docs/user_manual/data-model.md b/docs/user_manual/data-model.md index 6778a04388..64b2c0e55a 100644 --- a/docs/user_manual/data-model.md +++ b/docs/user_manual/data-model.md @@ -14,7 +14,6 @@ The components types are organized in an inheritance-like hierarchy. A sub-type has all the attributes from its parent type. The hierarchy tree of the component types is shown below. - ```{mermaid} graph LR base-->node @@ -44,7 +43,6 @@ graph LR classDef green fill:#9f6,stroke:#333,stroke-width:2px class node,line,link,generic_branch,transformer,three_winding_transformer,source,shunt,sym_load,sym_gen,asym_load,asym_gen,sym_voltage_sensor,asym_voltage_sensor,sym_power_sensor,asym_power_sensor green ``` - ```{note} The type names in the hierarchy are exactly the same as the component type names in diff --git a/docs/user_manual/dataset-terminology.md b/docs/user_manual/dataset-terminology.md index 2ae8ad8f21..d0212ecded 100644 --- a/docs/user_manual/dataset-terminology.md +++ b/docs/user_manual/dataset-terminology.md @@ -204,14 +204,12 @@ graph TD The dimensions of numpy arrays and the interpretation of each dimension is as follows. - | **Data Type** | **1D** | **2D** | **3D** | | ------------------- | -------------------------------- | ---------------------------------------------------- | -------------------------------------------------------------------------- | | **SingleArray** | Corresponds to a single dataset. | ❌ | ❌ | | **DenseBatchArray** | ❌ | Batch number $\times$ Component within that batch | ❌ | | **SingleColumn** | Component within that batch. | Component within that batch $\times$ Phases ✨ | ❌ | | **BatchColumn** | ❌ | Batch number $\times$ Component within that batch | Batch number $\times$ Component within that batch $\times$ Phases ✨ | - ```{note} ✨ The "Phases" dimension is optional and is available only when the attributes are asymmetric. @@ -283,7 +281,6 @@ The batch size is the number of scenarios. ## Attributes of Components - | Attribute | Description | | ------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | name | Name of the attribute. It is exactly the same as the attribute name in `power_grid_model.power_grid_meta_data`. They are included under the enum {py:class}`AttributeType `. | @@ -295,4 +292,3 @@ The batch size is the number of scenarios. | required | Whether the attribute is required. If not, then it is optional. Note if you choose not to specify an optional attribute, it should have the null value as defined in [](../advanced_documentation/native-data-interface.md#basic-data-types). | | update | Whether the attribute can be mutated by the update call `PowerGridModel.update` on an existing instance, only applicable when this attribute is part of an input dataset. | | valid values | Whether applicable or not; an indication of value validity for the input data. | - diff --git a/pyproject.toml b/pyproject.toml index d5464e55f7..023607dbb1 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -207,9 +207,17 @@ install_types = true [tool.pymarkdown] plugins.heading-increment.enabled = false plugins.no-duplicate-heading.enabled = false +plugins.line-length.enabled = true plugins.line-length.line_length = 120 plugins.line-length.heading_line_length = 120 plugins.line-length.code_block_line_length = 120 +plugins.line-length.table_line_length = 1000000 +extensions.front-matter.enabled = true +extensions.linter-pragmas.enabled = true +extensions.markdown-tables.enabled = true +extensions.markdown-task-list-items.enabled = true +extensions.markdown-strikethrough.enabled = true +extensions.markdown-disallow-raw-html.enabled = true # CI build options [tool.cibuildwheel] From b00316cc32ac787635c3fccbf2e346f3e3274ca7 Mon Sep 17 00:00:00 2001 From: Martijn Govers Date: Fri, 31 Jul 2026 14:48:19 +0200 Subject: [PATCH 09/14] pymarkdownlnt configuration with less line length Signed-off-by: Martijn Govers --- .pymarkdown | 37 +++++++++++++ .pymarkdown.license | 3 ++ README.md | 2 + docs/advanced_documentation/build-guide.md | 6 +-- .../high-level-design.md | 2 + docs/algorithms/lu-solver.md | 54 ++++++++++--------- docs/algorithms/pf-algorithms.md | 4 +- docs/algorithms/sc-algorithms.md | 3 +- docs/algorithms/se-algorithms.md | 6 +-- docs/contribution/folder-structure.md | 2 +- docs/user_manual/calculations.md | 19 +++---- docs/user_manual/components.md | 2 +- docs/user_manual/model-validation.md | 2 +- docs/user_manual/non-pgm-components.md | 2 +- pyproject.toml | 15 ------ .../data/power_flow/generic_branch/README.md | 2 +- 16 files changed, 93 insertions(+), 68 deletions(-) create mode 100644 .pymarkdown create mode 100644 .pymarkdown.license diff --git a/.pymarkdown b/.pymarkdown new file mode 100644 index 0000000000..f486d20aa8 --- /dev/null +++ b/.pymarkdown @@ -0,0 +1,37 @@ +{ + "plugins": { + "heading-increment": { + "enabled": false + }, + "no-duplicate-heading": { + "enabled": false + }, + "line-length": { + "enabled": true, + "line_length": 120, + "heading_line_length": 120, + "code_block_line_length": 120, + "table_line_length": 1000000 + } + }, + "extensions": { + "front-matter": { + "enabled": true + }, + "linter-pragmas": { + "enabled": true + }, + "markdown-tables": { + "enabled": true + }, + "markdown-task-list-items": { + "enabled": false + }, + "markdown-strikethrough": { + "enabled": false + }, + "markdown-disallow-raw-html": { + "enabled": false + } + } +} \ No newline at end of file diff --git a/.pymarkdown.license b/.pymarkdown.license new file mode 100644 index 0000000000..7601059167 --- /dev/null +++ b/.pymarkdown.license @@ -0,0 +1,3 @@ +SPDX-FileCopyrightText: Contributors to the Power Grid Model project + +SPDX-License-Identifier: MPL-2.0 diff --git a/README.md b/README.md index a4664c9ef7..0b42589b4b 100644 --- a/README.md +++ b/README.md @@ -111,6 +111,7 @@ references. [![DOI](https://zenodo.org/badge/DOI/10.5281/zenodo.8054429.svg)](https://zenodo.org/record/8054429) + ```bibtex @software{Xiang_PowerGridModel_power-grid-model, author = {Xiang, Yu and Salemink, Peter and van Westering, Werner and Bharambe, Nitish and Govers, Martinus G.H. and van den Bogaard, Jonas and Stoeller, Bram and Wang, Zhen and Guo, Jerry Jinfeng and Figueroa Manrique, Santiago and Jagutis, Laurynas and Wang, Chenguang and van Raalte, Marc and {Contributors to the LF Energy project Power Grid Model}}, @@ -131,6 +132,7 @@ references. doi={10.1049/icp.2023.0633} } ``` + ## Contact diff --git a/docs/advanced_documentation/build-guide.md b/docs/advanced_documentation/build-guide.md index 8ad5fe9819..4b94e90f64 100644 --- a/docs/advanced_documentation/build-guide.md +++ b/docs/advanced_documentation/build-guide.md @@ -392,14 +392,14 @@ For debugging purposes, it may be useful to build the Power Grid Model with debu To do so, the following command can be used to override the default build settings. ```powershell -uv sync --locked --config-settings=cmake.build-type="RelWithDebInfo" +uv sync --config-settings=cmake.build-type="RelWithDebInfo" ``` It is also possible to install the Power Grid Model as a full debug build, including extra sanity checks and with a lower degree of optimizations. Note this may come with a significant impact on the performance. ```powershell -uv sync --locked --config-settings=cmake.build-type="Debug" +uv sync --config-settings=cmake.build-type="Debug" ``` ### Build CMake Project @@ -517,7 +517,7 @@ In addition, the `power-grid-model` Python package needs to be built by followin After that, the documentation specific packages can be installed via: ```shell -uv sync --locked --group doc +uv sync --group doc ``` ```{note} diff --git a/docs/advanced_documentation/high-level-design.md b/docs/advanced_documentation/high-level-design.md index efadc1d193..56c0ecb653 100644 --- a/docs/advanced_documentation/high-level-design.md +++ b/docs/advanced_documentation/high-level-design.md @@ -46,6 +46,7 @@ wrapper layer core module, that wraps the exposition-only core module, that expo This can be visualized graphically as follows. + ```{mermaid} :title: Full design @@ -93,6 +94,7 @@ flowchart TD cpp_user -->|experimental
links +
includes| power_grid_model_cpp -->|links +
includes| power_grid_model_c python_user -->|import| power_grid_model_python -->|internal import| power_grid_model_core_python -->|internal import| power_grid_core_python -->|"CDLL
(dynamic loading)"| power_grid_model_c_dll ``` + ## Creating a custom library or interface diff --git a/docs/algorithms/lu-solver.md b/docs/algorithms/lu-solver.md index 91fcff604b..eb38c1922d 100644 --- a/docs/algorithms/lu-solver.md +++ b/docs/algorithms/lu-solver.md @@ -303,6 +303,7 @@ where $i,j = 0..(N-1)$. For readbility, we use $:$ to denote a range slicing operation to along a dimension of matrix $\mathbf{M}$, e.g. $\mathbf{M}\left[0:3, j\right]$. + 1. Initialize the permutations $\mathbf{P}$ and $\mathbf{Q}$ to the identity permutation. 2. Initialize fill-in elements to $0$. 3. Loop over all rows: $p = 0..(N-1)$: @@ -331,6 +332,7 @@ $\mathbf{M}\left[0:3, j\right]$. 1. In $\mathbf{P}$: swap $p \leftrightarrow p + i_p$ 2. In $\mathbf{Q}$: swap $p \leftrightarrow p + j_p$ 8. Continue with the next $p$ to factorize the the bottom-right block. + $\mathbf{L}$ is now the matrix containing the lower triangle of $\mathbf{M}$, ones on the diagonal and zeros in the upper triangle. @@ -871,16 +873,16 @@ as well as the well-known #### Pivot perturbation algorithm -Let $\mathbf{M}$ be the matrix, $\left\|\mathbf{M}\right\|_{\infty ,\text{bwod}}$ the +Let $\mathbf{M}$ be the matrix, $\lvert\mathbf{M}\rvert _{\infty ,\text{bwod}}$ the [block-wise off-diagonal infinite norm](#block-wise-off-diagonal-infinite-matrix-norm) of the matrix. -1. $\epsilon \gets \text{perturbation\_threshold} * \left\|\mathbf{M}\right\|_{\text{bwod}}$. -2. If $|\text{pivot\_element}| \lt \epsilon$, then: - 1. If $|\text{pivot\_element}| = 0$, then: +1. $\epsilon \gets \text{perturbation\_threshold} * \lvert\mathbf{M}\rvert _{\text{bwod}}$. +2. If $\lvert\text{pivot\_element}\rvert \lt \epsilon$, then: + 1. If $\lvert\text{pivot\_element}\rvert = 0$, then: 1. $\text{phase\_shift} \gets 1$. 2. Proceed. 2. Else: - 1. $\text{phase\_shift} \gets \text{pivot\_element} / |\text{pivot\_element}|$. + 1. $\text{phase\_shift} \gets \text{pivot\_element} / \lvert\text{pivot\_element}\rvert$. 2. Proceed. 3. $\text{pivot\_element} \gets \epsilon * \text{phase\_shift}$. @@ -909,7 +911,7 @@ The residual $\boldsymbol{r}$ can be calculated. An estimation for the left-hand side can be obtained by using the pivot-perturbed matrix $\tilde{\mathbf{M}}$ instead of the original matrix $\mathbf{M}$. Convergence is reached when $\boldsymbol{r} \to \boldsymbol{0}$, which implies -$\left\|\boldsymbol{\Delta x}\right\| \to 0$. +$\lvert\boldsymbol{\Delta x}\rvert \to 0$. Solving for $\boldsymbol{\Delta x}$ and substituting back into $\boldsymbol{x}_{i+1} = \boldsymbol{x}_i + \boldsymbol{\Delta x}$ provides the next best approximation $\boldsymbol{x}_{i+1}$ for $\boldsymbol{x}$. @@ -969,12 +971,12 @@ with a few modifications described [below](#improved-backward-error-calculation) $$ \begin{aligned} D_{\text{max}} &= \max_i\left\{ - \left(\left|\mathbf{M}\right|\cdot\left|\boldsymbol{x}\right| + \left|\boldsymbol{b}\right|\right)_i + \left(\lvert\mathbf{M}\rvert\cdot\lvert\boldsymbol{x}\rvert + \lvert\boldsymbol{b}\rvert\right)_i \right\} \\ \text{backward\_error} &= \max_i \left\{ - \frac{\left|\boldsymbol{r}\right|_i}{ + \frac{\lvert\boldsymbol{r}\rvert_i}{ \max\left\{ - \left(\left|\mathbf{M}\right|\cdot\left|\boldsymbol{x}\right| + \left|\boldsymbol{b}\right|\right)_i, + \left(\lvert\mathbf{M}\rvert\cdot\lvert\boldsymbol{x}\rvert + \lvert\boldsymbol{b}\rvert\right)_i, \epsilon_{\text{backward\_error}} D_{\text{max}} \right\} } @@ -1024,8 +1026,8 @@ In power system equations, the matrix $\mathbf{M}$ in equation $\mathbf{M} \bold very discrepant entries: some may be very large while others are zero or very small (see also the [documentation on calculations](../user_manual/calculations.md)). The same may be true for the right-hand side of the equation $\boldsymbol{b}$, as well as its solution $\boldsymbol{x}$. -In fact, there may be certain rows $i$ for which both $\left|\boldsymbol{b}\left[i\right]\right|$ and -$\sum_j \left|\mathbf{M}\left[i,j\right]\right| \left|\boldsymbol{x}\left[j\right]\right|$ are small and, therefore, +In fact, there may be certain rows $i$ for which both $\lvert\boldsymbol{b}\left[i\right]\rvert$ and +$\sum_j \lvert\mathbf{M}\left[i,j\right]\rvert \lvert\boldsymbol{x}\left[j\right]\rvert$ are small and, therefore, their sum is prone to rounding errors, which may be several orders larger than machine precision. [Li99](https://www.semanticscholar.org/paper/A-Scalable-Sparse-Direct-Solver-Using-Static-Li-Demmel/7ea1c3360826ad3996f387eeb6d70815e1eb3761) @@ -1036,27 +1038,27 @@ $$ \begin{aligned} \text{backward\_error}_{\text{Li}} &= \max_i \frac{ - \left|\boldsymbol{r}_i\right| + \lvert\boldsymbol{r}_i\rvert }{ - \sum_j \left|\mathbf{M}_{i,j}\right| \left|\boldsymbol{x}_j\right| + \left|\boldsymbol{b}_i\right| + \sum_j \lvert\mathbf{M}_{i,j}\rvert \lvert\boldsymbol{x}_j\rvert + \lvert\boldsymbol{b}_i\rvert } \\ &= \max_i \frac{ - \left|\boldsymbol{b}_i - \sum_j \mathbf{M}_{i,j} \boldsymbol{x}_j\right| + \lvert\boldsymbol{b}_i - \sum_j \mathbf{M}_{i,j} \boldsymbol{x}_j\rvert }{ - \sum_j \left|\mathbf{M}_{i,j}\right| \left|\boldsymbol{x}_j\right| + \left|\boldsymbol{b}_i\right| + \sum_j \lvert\mathbf{M}_{i,j}\rvert \lvert\boldsymbol{x}_j\rvert + \lvert\boldsymbol{b}_i\rvert } \\ &= \max_i \frac{ - \left|\boldsymbol{r}_i\right| + \lvert\boldsymbol{r}_i\rvert }{ - \left(\left|\mathbf{M}\right| \cdot \left|\boldsymbol{x}\right| + \left|\boldsymbol{b}\right|\right)_i + \left(\lvert\mathbf{M}\rvert \cdot \lvert\boldsymbol{x}\rvert + \lvert\boldsymbol{b}\rvert\right)_i } \end{aligned} $$ -In this equation, the symbolic notation $\left|\mathbf{M}\right|$ and $\left|\boldsymbol{x}\right|$ are the matrix and +In this equation, the symbolic notation $\lvert\mathbf{M}\rvert$ and $\lvert\boldsymbol{x}\rvert$ are the matrix and vector with absolute values of the elements of $\mathbf{M}$ and $\boldsymbol{x}$ as elements, i.e., -$\left|\mathbf{M}\right|_{i,j} := \left|\mathbf{M}_{i,j}\right|$ and -$\left|\boldsymbol{x}\right|_i := \left|\boldsymbol{x}_i\right|$, as defined in +$\lvert\mathbf{M}\rvert_{i,j} := \lvert\mathbf{M}_{i,j}\rvert$ and +$\lvert\boldsymbol{x}\rvert_i := \lvert\boldsymbol{x}_i\rvert$, as defined in [Arioli89](https://epubs.siam.org/doi/10.1137/0610013). Due to the aforementioned, this is prone to rounding errors, and a single row with rounding errors may cause the entire @@ -1067,12 +1069,12 @@ determined by the maximum across all denominators: $$ \begin{aligned} D_{\text{max}} &= \max_i\left\{ - \left(\left|\mathbf{M}\right|\cdot\left|\boldsymbol{x}\right| + \left|\boldsymbol{b}\right|\right)_i + \left(\lvert\mathbf{M}\rvert\cdot\lvert\boldsymbol{x}\rvert + \lvert\boldsymbol{b}\rvert\right)_i \right\} \\ \text{backward\_error} &= \max_i \left\{ - \frac{\left|\boldsymbol{r}\right|_i}{ + \frac{\lvert\boldsymbol{r}\rvert_i}{ \max\left\{ - \left(\left|\mathbf{M}\right|\cdot\left|\boldsymbol{x}\right| + \left|\boldsymbol{b}\right|\right)_i, + \left(\lvert\mathbf{M}\rvert\cdot\lvert\boldsymbol{x}\rvert + \lvert\boldsymbol{b}\rvert\right)_i, \epsilon_{\text{backward\_error}} D_{\text{max}} \right\} } @@ -1131,7 +1133,7 @@ with dimensions $N_i\times N_j$. 3. Loop over all rows of the current block: $k = 0..(N_{i,j} - 1)$: 1. $\text{block\_row\_norm} \gets 0$. 2. Loop over all columns of the current block: $l = 0..(N_{i,j} - 1)$: - 1. $\text{block\_row\_norm} \gets \text{block\_row\_norm} + \left\|\mathbf{M}_{i,j}\left[k,l\right]\right\|$. + 1. $\text{block\_row\_norm} \gets \text{block\_row\_norm} + \lvert\mathbf{M}_{i,j}\left[k,l\right]\rvert$. 3. Calculate the new block norm: set $\text{block\_norm} \gets \max\left\{\text{block\_norm}, \text{block\_row\_norm}\right\}$. 4. Continue with the next row of the current block. @@ -1186,9 +1188,11 @@ $$ \end{bmatrix} $$ + * The regular $L_{\infty}$-norm is $\max\left\{1+3, 3, 5, \frac{1}{2}, 1, 1\right\} = 5$. * The block-wise off-diagonal infinity $L_{\infty ,\text{bwod}}$-norm is $\max\left\{\max\left\{1, 3\right\}+\max\left\{3, 0\right\},\max\left\{5, 0\right\} + \max\left\{0, \frac{1}{2}\right\}, 1\right\} = \max\left\{3+3, 5+\frac{1}{2}, 1, 1\right\} = 6$. + The two norms clearly differ and even the elements that contribute most to the norm are different. @@ -1213,8 +1217,10 @@ $$ \end{bmatrix} $$ + * The regular $L_{\infty}$-norm is $\max\left\{20+20+2+2,30+3,100,3+1\right\} = \max\left\{44,33,100,4\right\} = 100$. * The block-wise infinity norm with diagonals would be $\max\left\{\max\left\{20+20, 30\right\}+\max\left\{2+2, 3\right\},\max\left\{0,3\right\} + \max\left\{100, 1\right\}\right\} = \max\left\{40+4, 3+100\right\} = \max\left\{44, 103\right\} = 103$. * The $L_{\infty ,\text{bwod}}$-norm is $\max\left\{\max\left\{2+2, 3\right\},\max\left\{0,3\right\}\right\} = \max\left\{4, 3\right\} = 4$. + diff --git a/docs/algorithms/pf-algorithms.md b/docs/algorithms/pf-algorithms.md index ed3967e3e0..fb1cbc92ca 100644 --- a/docs/algorithms/pf-algorithms.md +++ b/docs/algorithms/pf-algorithms.md @@ -37,9 +37,7 @@ The following bus types can be present in the system: Note: this bus is not supported by power-grid-model yet. ```{note} -Asymmetric power flow calculations require the network to have a reference to ground. -For details and internal solution of asymmetric floating grids calculations in power-grid-model, please refer to -[Floating grid handling](../user_manual/calculations.md#floating-grid-handling). +Asymmetric power flow calculations require the network to have a reference to ground. For details and internal solution of asymmetric floating grids calculations in power-grid-model, please refer to [Floating grid handling](../user_manual/calculations.md#floating-grid-handling). ``` ## Newton-Raphson power flow diff --git a/docs/algorithms/sc-algorithms.md b/docs/algorithms/sc-algorithms.md index 748969050f..8c60a8fb5f 100644 --- a/docs/algorithms/sc-algorithms.md +++ b/docs/algorithms/sc-algorithms.md @@ -22,8 +22,7 @@ This gives the initial symmetrical short circuit current ($I_k^{\prime\prime}$) This quantity is then used to derive almost all further calculations of short circuit studies applications. ```{note} -Short-circuit calculations are currently implemented in the phase (abc) domain and therefore require a grounded network, -similar to asymmetric power flow calculations. +Short-circuit calculations are currently implemented in the phase (abc) domain and therefore require a grounded network, similar to asymmetric power flow calculations. Note that this limitation does not exist in the sequence (0-1-2) domain but is present in the phase domain calculation. ``` diff --git a/docs/algorithms/se-algorithms.md b/docs/algorithms/se-algorithms.md index efd4bbef30..a189755c9d 100644 --- a/docs/algorithms/se-algorithms.md +++ b/docs/algorithms/se-algorithms.md @@ -105,8 +105,8 @@ It is not possible to mix [power sensors](../user_manual/components.md#generic-p [current sensors](../user_manual/components.md#generic-current-sensor) on the same terminal of the same component. It is also not possible to mix [current sensors with global angle measurement type](../user_manual/components.md#global-angle-current-sensors) with -[current sensors with local angle measurement type](../user_manual/components.md#local-angle-current-sensors) on the -same terminal of the same component. +[current sensors with local angle measurement type](../user_manual/components.md#local-angle-current-sensors) on the same terminal +of the same component. However, such mixing of sensor types is allowed as long as they are on different terminals. ``` @@ -313,7 +313,7 @@ Consequently, the iteration process differs slightly from that of $\widetilde{\boldsymbol{U}}^{(k)}$ and $\widetilde{\boldsymbol{\theta}}^{(k)}$, using the prefactorized matrix. See also [Matrix-prefactorization](../user_manual/performance-guide.md#matrix-prefactorization) - Normalize the result voltage phasor angle by setting angle of slack bus to zero: - $\underline{U}_i^{(k)} = \widetilde{\underline{U}}_i^{(k)} \times |\widetilde{\underline{U}}_s^{(k)}| / \widetilde{\underline{U}}_s^{(k)}$. + $\underline{U}_i^{(k)} = \widetilde{\underline{U}}_i^{(k)} \times |\widetilde{\underline{U}}_s^{(k)}| / \widetilde{\underline{U}}_s^{(k)}$. - If the maximum deviation between $\underline{\boldsymbol{U}}^{(k)}$ and $\underline{\boldsymbol{U}}^{(k-1)}$ is smaller than the tolerance $\epsilon$, stop the iteration, otherwise continue until the maximum number of iterations is reached. diff --git a/docs/contribution/folder-structure.md b/docs/contribution/folder-structure.md index 5107427bda..199a4ef2c5 100644 --- a/docs/contribution/folder-structure.md +++ b/docs/contribution/folder-structure.md @@ -9,7 +9,7 @@ SPDX-License-Identifier: MPL-2.0 The repository folder structure is as follows. The `docs` and `scripts` folders are self-explanatory. - The C++ calculation core is inside - {{ "[power_grid_model_c/power_grid_model/include/power_grid_model]({}/power_grid_model_c/power_grid_model/include/power_grid_model)".format(gh_link_head_tree) }}. + {{ "[power_grid_model_c/power_grid_model/include/power_grid_model]({}/power_grid_model_c/power_grid_model/include/power_grid_model)".format(gh_link_head_tree) }}. - The C API is inside {{ "[power_grid_model_c/power_grid_model_c]({}/power_grid_model_c/power_grid_model_c)".format(gh_link_head_tree) }}. - The C program example to use the C API is inside diff --git a/docs/user_manual/calculations.md b/docs/user_manual/calculations.md index 990678a965..47ac854f38 100644 --- a/docs/user_manual/calculations.md +++ b/docs/user_manual/calculations.md @@ -124,8 +124,7 @@ However, such mixing of sensor types is allowed as long as they are on different ``` ```{warning} -The [iterative linear](../algorithms/se-algorithms.md#iterative-linear-state-estimation) and -[Newton-Raphson](../algorithms/se-algorithms.md#newton-raphson-state-estimation) state +The [iterative linear](../algorithms/se-algorithms.md#iterative-linear-state-estimation) and [Newton-Raphson](../algorithms/se-algorithms.md#newton-raphson-state-estimation) state estimation algorithms will assume angles to be zero by default (see the details about voltage sensors). In observable systems this helps better outputting correct results. On the other hand with unobservable systems, exceptions raised from calculations due to faulty results will be @@ -194,11 +193,8 @@ Output: - Current flowing through branches and fault. ```{note} -Short-circuit calculations are currently implemented in the phase (abc) domain and therefore require a grounded -configurations in certain cases, similar to asymmetric power flow calculations. -For details on how floating grids are treated in power-grid-model, please refer to -[Floating grid handling](calulations.md#floating-grid-handling). -``` +Short-circuit calculations are currently implemented in the phase (abc) domain and therefore require a grounded configurations in certain cases, similar to asymmetric power flow calculations. +For details on how floating grids are treated in power-grid-model, please refer to[Floating grid handling](calulations.md#floating-grid-handling). #### Common calculations @@ -244,10 +240,7 @@ The option affects which attributes are required and how results are exposed. for all output variables. ```{note} -In power-grid model, asymmetric calculations with certain configurations require the network to have a reference to -ground. -For details on how floating grids are treated in power-grid-model, please refer to -[Floating grid handling](calulations.md#floating-grid-handling). +In power-grid model, asymmetric calculations with certain configurations require the network to have a reference to ground. For details on how floating grids are treated in power-grid-model, please refer to [Floating grid handling](calulations.md#floating-grid-handling). ``` ```{note} @@ -306,8 +299,8 @@ By default, the [Newton-Raphson](../algorithms/pf-algorithms.md#newton-raphson-p ``` ```{note} -When all the load/generation types are of constant impedance, the -[Linear](../algorithms/pf-algorithms.md#linear-power-flow) method will be the fastest without loss of accuracy. +When all the load/generation types are of constant impedance, the [Linear](../algorithms/pf-algorithms.md#linear-power-flow) method will be the +fastest without loss of accuracy. Therefore power-grid-model will use this method regardless of the input provided by the user in this case. ``` diff --git a/docs/user_manual/components.md b/docs/user_manual/components.md index 265f1b50ca..639fa08157 100644 --- a/docs/user_manual/components.md +++ b/docs/user_manual/components.md @@ -67,7 +67,7 @@ Physically a node can be a busbar, a joint, or other similar component. | `q` | `RealValueOutput` | volt-ampere-reactive (var) | reactive power injection | ```{note} -The `p` and `q` output of injection follows the `generator` reference direction as mentioned in +The `p` and `q` output of injection follows the `generator` reference direction as mentioned in [Reference Direction](data-model.md#reference-direction) ``` diff --git a/docs/user_manual/model-validation.md b/docs/user_manual/model-validation.md index 5dec22a828..6a7be1d762 100644 --- a/docs/user_manual/model-validation.md +++ b/docs/user_manual/model-validation.md @@ -221,7 +221,7 @@ The circuit diagram is as follows (The node 6 is same in both lines): Gen(_22)---|_2--transformer(_31)--|_4 |_5-------line(_15)----|_6 | shunt(_29)---| shunt(_28)---|-load(_24) - + |----line(_16)-------| |---line(_19)---|_9---transformer(_32)---|_11---source(_20) | |---line(_18)---| diff --git a/docs/user_manual/non-pgm-components.md b/docs/user_manual/non-pgm-components.md index c8a6043f28..403edd6e90 100644 --- a/docs/user_manual/non-pgm-components.md +++ b/docs/user_manual/non-pgm-components.md @@ -20,7 +20,7 @@ New contributions and ideas for modeling grid components are very welcome! ## Ideal transformer -An ideal transformer can be modeled as a [link](./components.md#link). +An ideal transformer can be modeled as a [link](./components.md#link). To this end, it is explicitly allowed to place a link between two different voltage levels. Trivially, no additional electrical parameters need to be specified. diff --git a/pyproject.toml b/pyproject.toml index 023607dbb1..609e6c5cb0 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -204,21 +204,6 @@ show_column_numbers = true non_interactive = true install_types = true -[tool.pymarkdown] -plugins.heading-increment.enabled = false -plugins.no-duplicate-heading.enabled = false -plugins.line-length.enabled = true -plugins.line-length.line_length = 120 -plugins.line-length.heading_line_length = 120 -plugins.line-length.code_block_line_length = 120 -plugins.line-length.table_line_length = 1000000 -extensions.front-matter.enabled = true -extensions.linter-pragmas.enabled = true -extensions.markdown-tables.enabled = true -extensions.markdown-task-list-items.enabled = true -extensions.markdown-strikethrough.enabled = true -extensions.markdown-disallow-raw-html.enabled = true - # CI build options [tool.cibuildwheel] build-frontend = "build[uv]" diff --git a/tests/data/power_flow/generic_branch/README.md b/tests/data/power_flow/generic_branch/README.md index 76b0929a4d..1f2d46cc05 100644 --- a/tests/data/power_flow/generic_branch/README.md +++ b/tests/data/power_flow/generic_branch/README.md @@ -11,5 +11,5 @@ Test case for validation of the generic_branch component for symmetrical power f The circuit diagram is as follows: ```txt -source_4--node_1--generic_branch_3--node_2--load_5 +source_4--node_1--generic_branch_3--node_2--load_5 ``` From 7bd1df9f0864c0bda2b2ff9e4959a1b94af77183 Mon Sep 17 00:00:00 2001 From: Martijn Govers Date: Mon, 3 Aug 2026 09:03:47 +0200 Subject: [PATCH 10/14] bump even more Signed-off-by: Martijn Govers --- .github/workflows/check-code-quality.yml | 4 ++-- .pre-commit-config.yaml | 4 ++-- .pre-commit-config.yaml.jinja | 4 ++-- .vscode/tasks.json | 2 +- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/.github/workflows/check-code-quality.yml b/.github/workflows/check-code-quality.yml index 9e5c49c67a..906be32f04 100644 --- a/.github/workflows/check-code-quality.yml +++ b/.github/workflows/check-code-quality.yml @@ -55,8 +55,8 @@ jobs: - name: Run pymarkdown run: | echo "Running pymarkdown" - git ls-files -z -- '*.md' | xargs -0 -r uv run --frozen pymarkdown fix - git ls-files -z -- '*.md' | xargs -0 -r uv run --frozen pymarkdown scan + git ls-files -z -- '*.md' | xargs -0 -r uv run --frozen pymarkdown --strict-config fix + git ls-files -z -- '*.md' | xargs -0 -r uv run --frozen pymarkdown --strict-config scan - name: Install npm packages run: | diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index d1cab87a82..10477f9a0e 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -50,7 +50,7 @@ repos: - id: pymarkdown-fix name: pymarkdown-fix alias: markdown-fix - entry: uv run --frozen pymarkdown fix + entry: uv run --frozen pymarkdown --strict-config fix language: system pass_filenames: true types: [ markdown ] @@ -58,7 +58,7 @@ repos: - id: pymarkdown-scan name: pymarkdown-scan alias: markdown-check - entry: uv run --frozen pymarkdown scan + entry: uv run --frozen pymarkdown --strict-config scan language: system pass_filenames: true types: [ markdown ] diff --git a/.pre-commit-config.yaml.jinja b/.pre-commit-config.yaml.jinja index 2fa1a44e7f..e5785fef2e 100644 --- a/.pre-commit-config.yaml.jinja +++ b/.pre-commit-config.yaml.jinja @@ -50,7 +50,7 @@ repos: - id: pymarkdown-fix name: pymarkdown-fix alias: markdown-fix - entry: uv run --frozen pymarkdown fix + entry: uv run --frozen pymarkdown --strict-config fix language: system pass_filenames: true types: [ markdown ] @@ -58,7 +58,7 @@ repos: - id: pymarkdown-scan name: pymarkdown-scan alias: markdown-check - entry: uv run --frozen pymarkdown scan + entry: uv run --frozen pymarkdown --strict-config scan language: system pass_filenames: true types: [ markdown ] diff --git a/.vscode/tasks.json b/.vscode/tasks.json index 6251aede24..7825274371 100644 --- a/.vscode/tasks.json +++ b/.vscode/tasks.json @@ -54,7 +54,7 @@ { "label": "markdownlint", "type": "shell", - "command": "npx markdownlint --fix .", + "command": "pymarkdown fix .", "group": { "kind": "build", "isDefault": false From 3d48a4db08295eaca5110733a82e03a73c58b7c5 Mon Sep 17 00:00:00 2001 From: Martijn Govers Date: Mon, 3 Aug 2026 09:04:14 +0200 Subject: [PATCH 11/14] attempt silence markdownlint Signed-off-by: Martijn Govers --- docs/algorithms/lu-solver.md | 155 ++++++++++++++++++----------------- 1 file changed, 81 insertions(+), 74 deletions(-) diff --git a/docs/algorithms/lu-solver.md b/docs/algorithms/lu-solver.md index eb38c1922d..c456d5ebd5 100644 --- a/docs/algorithms/lu-solver.md +++ b/docs/algorithms/lu-solver.md @@ -303,36 +303,36 @@ where $i,j = 0..(N-1)$. For readbility, we use $:$ to denote a range slicing operation to along a dimension of matrix $\mathbf{M}$, e.g. $\mathbf{M}\left[0:3, j\right]$. - -1. Initialize the permutations $\mathbf{P}$ and $\mathbf{Q}$ to the identity permutation. -2. Initialize fill-in elements to $0$. -3. Loop over all rows: $p = 0..(N-1)$: - 1. Set the remaining matrix: $\mathbf{M}_p \gets \mathbf{M}\left[p:N,p:N\right]$ with size $N_p\times N_p$, where - $N_p := N - p$. - 2. Find largest element $\mathbf{M}_p\left[i_p,j_p\right]$ in $\mathbf{M}_p$ by magnitude. - This is the pivot element. - 3. If the magnitude of the pivot element is too small: - 1. If pivot perturbation is enabled, then: - 1. Apply [pivot perturbation](#pivot-perturbation). - 2. Proceed. - 2. Else, if the matrix is singular (pivot element is identically $0$), then: - 1. Raise a `SparseMatrixError`. - 3. Else: - 1. Proceed. - 4. Else: - 1. Proceed. - 5. Swap the first and pivot row and column of $\mathbf{M}_p$, so that the pivot element is in the top-left corner of - the remaining matrix: - 1. $\mathbf{M}_p\left[0,0:N_p\right] \leftrightarrow \mathbf{M}\left[i_p,0:N_p\right]$ - 2. $\mathbf{M}_p\left[0:N_p,0\right] \leftrightarrow \mathbf{M}\left[0:N_p,j_p\right]$ - 6. Apply Gaussian elimination for the current pivot element: - 1. $\mathbf{M}_p\left[0,0:N_p\right] \gets \frac{1}{\mathbf{M}_p[0,0]}\mathbf{M}_p\left[0,0:N_p\right]$ - 2. $\mathbf{M}_p\left[1:N_p,0:N_p\right] \gets \mathbf{M}_p\left[1:N_p,0:N_p\right] - \mathbf{M}_p\left[1:N_p,0\right] \otimes \mathbf{M}_p\left[0,0:N_p\right]$ - 7. Accumulate the permutation matrices: - 1. In $\mathbf{P}$: swap $p \leftrightarrow p + i_p$ - 2. In $\mathbf{Q}$: swap $p \leftrightarrow p + j_p$ - 8. Continue with the next $p$ to factorize the the bottom-right block. - +```{math} +\begin{algorithm} +\caption{Dense LU factorization with pivot perturbation} +\begin{algorithmic} +\State Initialize permutations $\mathbf{P}$ and $\mathbf{Q}$ to the identity permutation +\State Initialize fill-in elements to $0$ +\For{$p = 0$ \textbf{to} $N-1$} \Comment{Loop over all rows} + \State $N_p \gets N - p$ + \State $\mathbf{M}_p \gets \mathbf{M}\left[p:N,p:N\right]$ \Comment{Set the remaining matrix of size $N_p\times N_p$} + \State Find largest element $\mathbf{M}_p\left[i_p,j_p\right]$ in $\mathbf{M}_p$ by magnitude \Comment{Pivot element} + \If{magnitude of pivot element is too small} + \If{pivot perturbation is enabled} + \State Apply pivot perturbation + \ElsIf{matrix is singular (pivot element is identically $0$)} + \State \textbf{raise} SparseMatrixError + \EndIf + \EndIf + \State \Comment{Swap first and pivot row and column of $\mathbf{M}_p$} + \State $\mathbf{M}_p\left[0,0:N_p\right] \leftrightarrow \mathbf{M}_p\left[i_p,0:N_p\right]$ + \State $\mathbf{M}_p\left[0:N_p,0\right] \leftrightarrow \mathbf{M}_p\left[0:N_p,j_p\right]$ + \State \Comment{Apply Gaussian elimination for the current pivot element} + \State $\mathbf{M}_p\left[0,0:N_p\right] \gets \frac{1}{\mathbf{M}_p[0,0]}\mathbf{M}_p\left[0,0:N_p\right]$ + \State $\mathbf{M}_p\left[1:N_p,0:N_p\right] \gets \mathbf{M}_p\left[1:N_p,0:N_p\right] - \mathbf{M}_p\left[1:N_p,0\right] \otimes \mathbf{M}_p\left[0,0:N_p\right]$ + \State \Comment{Accumulate the permutation matrices} + \State In $\mathbf{P}$: swap $p \leftrightarrow p + i_p$ + \State In $\mathbf{Q}$: swap $p \leftrightarrow p + j_p$ +\EndFor +\end{algorithmic} +\end{algorithm} +``` $\mathbf{L}$ is now the matrix containing the lower triangle of $\mathbf{M}$, ones on the diagonal and zeros in the upper triangle. @@ -873,16 +873,16 @@ as well as the well-known #### Pivot perturbation algorithm -Let $\mathbf{M}$ be the matrix, $\lvert\mathbf{M}\rvert _{\infty ,\text{bwod}}$ the +Let $\mathbf{M}$ be the matrix, $\left|\mathbf{M}\right|_{\infty ,\text{bwod}}$ the [block-wise off-diagonal infinite norm](#block-wise-off-diagonal-infinite-matrix-norm) of the matrix. -1. $\epsilon \gets \text{perturbation\_threshold} * \lvert\mathbf{M}\rvert _{\text{bwod}}$. -2. If $\lvert\text{pivot\_element}\rvert \lt \epsilon$, then: - 1. If $\lvert\text{pivot\_element}\rvert = 0$, then: +1. $\epsilon \gets \text{perturbation\_threshold} * \left|\mathbf{M}\right|_{\text{bwod}}$. +2. If $\left|\text{pivot\_element}\right| \lt \epsilon$, then: + 1. If $\left|\text{pivot\_element}\right| = 0$, then: 1. $\text{phase\_shift} \gets 1$. 2. Proceed. 2. Else: - 1. $\text{phase\_shift} \gets \text{pivot\_element} / \lvert\text{pivot\_element}\rvert$. + 1. $\text{phase\_shift} \gets \text{pivot\_element} / \left|\text{pivot\_element}\right|$. 2. Proceed. 3. $\text{pivot\_element} \gets \epsilon * \text{phase\_shift}$. @@ -911,7 +911,7 @@ The residual $\boldsymbol{r}$ can be calculated. An estimation for the left-hand side can be obtained by using the pivot-perturbed matrix $\tilde{\mathbf{M}}$ instead of the original matrix $\mathbf{M}$. Convergence is reached when $\boldsymbol{r} \to \boldsymbol{0}$, which implies -$\lvert\boldsymbol{\Delta x}\rvert \to 0$. +$\left|\boldsymbol{\Delta x}\right| \to 0$. Solving for $\boldsymbol{\Delta x}$ and substituting back into $\boldsymbol{x}_{i+1} = \boldsymbol{x}_i + \boldsymbol{\Delta x}$ provides the next best approximation $\boldsymbol{x}_{i+1}$ for $\boldsymbol{x}$. @@ -971,12 +971,12 @@ with a few modifications described [below](#improved-backward-error-calculation) $$ \begin{aligned} D_{\text{max}} &= \max_i\left\{ - \left(\lvert\mathbf{M}\rvert\cdot\lvert\boldsymbol{x}\rvert + \lvert\boldsymbol{b}\rvert\right)_i + \left(\left|\mathbf{M}\right|\cdot\left|\boldsymbol{x}\right| + \left|\boldsymbol{b}\right|\right)_i \right\} \\ \text{backward\_error} &= \max_i \left\{ - \frac{\lvert\boldsymbol{r}\rvert_i}{ + \frac{\left|\boldsymbol{r}\right|_i}{ \max\left\{ - \left(\lvert\mathbf{M}\rvert\cdot\lvert\boldsymbol{x}\rvert + \lvert\boldsymbol{b}\rvert\right)_i, + \left(\left|\mathbf{M}\right|\cdot\left|\boldsymbol{x}\right| + \left|\boldsymbol{b}\right|\right)_i, \epsilon_{\text{backward\_error}} D_{\text{max}} \right\} } @@ -1026,8 +1026,8 @@ In power system equations, the matrix $\mathbf{M}$ in equation $\mathbf{M} \bold very discrepant entries: some may be very large while others are zero or very small (see also the [documentation on calculations](../user_manual/calculations.md)). The same may be true for the right-hand side of the equation $\boldsymbol{b}$, as well as its solution $\boldsymbol{x}$. -In fact, there may be certain rows $i$ for which both $\lvert\boldsymbol{b}\left[i\right]\rvert$ and -$\sum_j \lvert\mathbf{M}\left[i,j\right]\rvert \lvert\boldsymbol{x}\left[j\right]\rvert$ are small and, therefore, +In fact, there may be certain rows $i$ for which both $\left|\boldsymbol{b}\left[i\right]\right|$ and +$\sum_j \left|\mathbf{M}\left[i,j\right]\right| \left|\boldsymbol{x}\left[j\right]\right|$ are small and, therefore, their sum is prone to rounding errors, which may be several orders larger than machine precision. [Li99](https://www.semanticscholar.org/paper/A-Scalable-Sparse-Direct-Solver-Using-Static-Li-Demmel/7ea1c3360826ad3996f387eeb6d70815e1eb3761) @@ -1038,27 +1038,27 @@ $$ \begin{aligned} \text{backward\_error}_{\text{Li}} &= \max_i \frac{ - \lvert\boldsymbol{r}_i\rvert + \left|\boldsymbol{r}_i\right| }{ - \sum_j \lvert\mathbf{M}_{i,j}\rvert \lvert\boldsymbol{x}_j\rvert + \lvert\boldsymbol{b}_i\rvert + \sum_j \left|\mathbf{M}_{i,j}\right| \left|\boldsymbol{x}_j\right| + \left|\boldsymbol{b}_i\right| } \\ &= \max_i \frac{ - \lvert\boldsymbol{b}_i - \sum_j \mathbf{M}_{i,j} \boldsymbol{x}_j\rvert + \left|\boldsymbol{b}_i - \sum_j \mathbf{M}_{i,j} \boldsymbol{x}_j\right| }{ - \sum_j \lvert\mathbf{M}_{i,j}\rvert \lvert\boldsymbol{x}_j\rvert + \lvert\boldsymbol{b}_i\rvert + \sum_j \left|\mathbf{M}_{i,j}\right| \left|\boldsymbol{x}_j\right| + \left|\boldsymbol{b}_i\right| } \\ &= \max_i \frac{ - \lvert\boldsymbol{r}_i\rvert + \left|\boldsymbol{r}_i\right| }{ - \left(\lvert\mathbf{M}\rvert \cdot \lvert\boldsymbol{x}\rvert + \lvert\boldsymbol{b}\rvert\right)_i + \left(\left|\mathbf{M}\right| \cdot \left|\boldsymbol{x}\right| + \left|\boldsymbol{b}\right|\right)_i } \end{aligned} $$ -In this equation, the symbolic notation $\lvert\mathbf{M}\rvert$ and $\lvert\boldsymbol{x}\rvert$ are the matrix and +In this equation, the symbolic notation $\left|\mathbf{M}\right|$ and $\left|\boldsymbol{x}\right|$ are the matrix and vector with absolute values of the elements of $\mathbf{M}$ and $\boldsymbol{x}$ as elements, i.e., -$\lvert\mathbf{M}\rvert_{i,j} := \lvert\mathbf{M}_{i,j}\rvert$ and -$\lvert\boldsymbol{x}\rvert_i := \lvert\boldsymbol{x}_i\rvert$, as defined in +$\left|\mathbf{M}\right|_{i,j} := \left|\mathbf{M}_{i,j}\right|$ and +$\left|\boldsymbol{x}\right|_i := \left|\boldsymbol{x}_i\right|$, as defined in [Arioli89](https://epubs.siam.org/doi/10.1137/0610013). Due to the aforementioned, this is prone to rounding errors, and a single row with rounding errors may cause the entire @@ -1069,12 +1069,12 @@ determined by the maximum across all denominators: $$ \begin{aligned} D_{\text{max}} &= \max_i\left\{ - \left(\lvert\mathbf{M}\rvert\cdot\lvert\boldsymbol{x}\rvert + \lvert\boldsymbol{b}\rvert\right)_i + \left(\left|\mathbf{M}\right|\cdot\left|\boldsymbol{x}\right| + \left|\boldsymbol{b}\right|\right)_i \right\} \\ \text{backward\_error} &= \max_i \left\{ - \frac{\lvert\boldsymbol{r}\rvert_i}{ + \frac{\left|\boldsymbol{r}\right|_i}{ \max\left\{ - \left(\lvert\mathbf{M}\rvert\cdot\lvert\boldsymbol{x}\rvert + \lvert\boldsymbol{b}\rvert\right)_i, + \left(\left|\mathbf{M}\right|\cdot\left|\boldsymbol{x}\right| + \left|\boldsymbol{b}\right|\right)_i, \epsilon_{\text{backward\_error}} D_{\text{max}} \right\} } @@ -1121,27 +1121,34 @@ $\mathbf{M}\left[i,j\right]$ its block element at (0-based) indices $(i,j)$, whe In turn, let $\mathbf{M}\left[i,j\right] \equiv \mathbf{M}_{i,j}\left[0:N_{i,j},0:N_{i,j}\right]$ be the dense block with dimensions $N_i\times N_j$. -1. $\text{norm} \gets 0$. -2. Loop over all block-rows: $i = 0..(N-1)$: - 1. $\text{row\_norm} \gets 0$. - 2. Loop over all block-columns: $j = 0..(N-1)$ (beware of sparse structure): - 1. If $i = j$, then: - 1. Skip this block: continue with the next block-column. - 2. Else, calculate the $L_{\infty}$ norm of the current block and add to the current row norm: - 1. the current block: $\mathbf{M}_{i,j} \gets \mathbf{M}\left[i,j\right]$. - 2. $\text{block\_norm} \gets 0$. - 3. Loop over all rows of the current block: $k = 0..(N_{i,j} - 1)$: - 1. $\text{block\_row\_norm} \gets 0$. - 2. Loop over all columns of the current block: $l = 0..(N_{i,j} - 1)$: - 1. $\text{block\_row\_norm} \gets \text{block\_row\_norm} + \lvert\mathbf{M}_{i,j}\left[k,l\right]\rvert$. - 3. Calculate the new block norm: set - $\text{block\_norm} \gets \max\left\{\text{block\_norm}, \text{block\_row\_norm}\right\}$. - 4. Continue with the next row of the current block. - 4. $\text{row\_norm} \gets \text{row\_norm} + \text{block\_norm}$. - 5. Continue with the next block-column. - 3. Calculate the new norm: set - $\text{norm} \gets \max\left\{\text{norm}, \text{row\_norm}\right\}$. - 4. Continue with the next block-row. +```{math} +\begin{algorithm} +\caption{Block-wise off-diagonal infinite matrix norm} +\begin{algorithmic} +\State $\text{norm} \gets 0$ +\For{$i = 0$ \textbf{to} $N-1$} \Comment{Loop over all block-rows} + \State $\text{row\_norm} \gets 0$ + \For{$j = 0$ \textbf{to} $N-1$} \Comment{Loop over all block-columns (beware of sparse structure)} + \If{$i = j$} + \State \textbf{continue} \Comment{Skip this block} + \Else \Comment{Calculate the $L_{\infty}$ norm of the current block} + \State $\mathbf{M}_{i,j} \gets \mathbf{M}\left[i,j\right]$ \Comment{Get the current block} + \State $\text{block\_norm} \gets 0$ + \For{$k = 0$ \textbf{to} $N_{i,j} - 1$} \Comment{Loop over all rows of the current block} + \State $\text{block\_row\_norm} \gets 0$ + \For{$l = 0$ \textbf{to} $N_{i,j} - 1$} \Comment{Loop over all columns of the current block} + \State $\text{block\_row\_norm} \gets \text{block\_row\_norm} + \left|\mathbf{M}_{i,j}\left[k,l\right]\right|$ + \EndFor + \State $\text{block\_norm} \gets \max\left\{\text{block\_norm}, \text{block\_row\_norm}\right\}$ + \EndFor + \State $\text{row\_norm} \gets \text{row\_norm} + \text{block\_norm}$ + \EndIf + \EndFor + \State $\text{norm} \gets \max\left\{\text{norm}, \text{row\_norm}\right\}$ +\EndFor +\end{algorithmic} +\end{algorithm} +``` ##### Illustration of the block-wise off-diagonal infinite matrix norm calculation From f956d1cf99c716f4b107a1fa0d6f5b68d6917059 Mon Sep 17 00:00:00 2001 From: Martijn Govers Date: Mon, 3 Aug 2026 09:17:23 +0200 Subject: [PATCH 12/14] use 1264 Signed-off-by: Martijn Govers --- docs/algorithms/lu-solver.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/algorithms/lu-solver.md b/docs/algorithms/lu-solver.md index c456d5ebd5..bb98259eb1 100644 --- a/docs/algorithms/lu-solver.md +++ b/docs/algorithms/lu-solver.md @@ -303,7 +303,7 @@ where $i,j = 0..(N-1)$. For readbility, we use $:$ to denote a range slicing operation to along a dimension of matrix $\mathbf{M}$, e.g. $\mathbf{M}\left[0:3, j\right]$. -```{math} +$$ \begin{algorithm} \caption{Dense LU factorization with pivot perturbation} \begin{algorithmic} @@ -332,7 +332,7 @@ $\mathbf{M}\left[0:3, j\right]$. \EndFor \end{algorithmic} \end{algorithm} -``` +$$ $\mathbf{L}$ is now the matrix containing the lower triangle of $\mathbf{M}$, ones on the diagonal and zeros in the upper triangle. @@ -1121,7 +1121,7 @@ $\mathbf{M}\left[i,j\right]$ its block element at (0-based) indices $(i,j)$, whe In turn, let $\mathbf{M}\left[i,j\right] \equiv \mathbf{M}_{i,j}\left[0:N_{i,j},0:N_{i,j}\right]$ be the dense block with dimensions $N_i\times N_j$. -```{math} +$$ \begin{algorithm} \caption{Block-wise off-diagonal infinite matrix norm} \begin{algorithmic} @@ -1148,7 +1148,7 @@ with dimensions $N_i\times N_j$. \EndFor \end{algorithmic} \end{algorithm} -``` +$$ ##### Illustration of the block-wise off-diagonal infinite matrix norm calculation From 809d4caa27a4acee9a8b2fbdae9981bce7201498 Mon Sep 17 00:00:00 2001 From: Martijn Govers Date: Mon, 3 Aug 2026 10:29:03 +0200 Subject: [PATCH 13/14] use lvert/rvert only in inline latex in enumerate Signed-off-by: Martijn Govers --- docs/algorithms/lu-solver.md | 117 ++++++++++++++++------------------- 1 file changed, 55 insertions(+), 62 deletions(-) diff --git a/docs/algorithms/lu-solver.md b/docs/algorithms/lu-solver.md index bb98259eb1..464f1a90d6 100644 --- a/docs/algorithms/lu-solver.md +++ b/docs/algorithms/lu-solver.md @@ -303,36 +303,36 @@ where $i,j = 0..(N-1)$. For readbility, we use $:$ to denote a range slicing operation to along a dimension of matrix $\mathbf{M}$, e.g. $\mathbf{M}\left[0:3, j\right]$. -$$ -\begin{algorithm} -\caption{Dense LU factorization with pivot perturbation} -\begin{algorithmic} -\State Initialize permutations $\mathbf{P}$ and $\mathbf{Q}$ to the identity permutation -\State Initialize fill-in elements to $0$ -\For{$p = 0$ \textbf{to} $N-1$} \Comment{Loop over all rows} - \State $N_p \gets N - p$ - \State $\mathbf{M}_p \gets \mathbf{M}\left[p:N,p:N\right]$ \Comment{Set the remaining matrix of size $N_p\times N_p$} - \State Find largest element $\mathbf{M}_p\left[i_p,j_p\right]$ in $\mathbf{M}_p$ by magnitude \Comment{Pivot element} - \If{magnitude of pivot element is too small} - \If{pivot perturbation is enabled} - \State Apply pivot perturbation - \ElsIf{matrix is singular (pivot element is identically $0$)} - \State \textbf{raise} SparseMatrixError - \EndIf - \EndIf - \State \Comment{Swap first and pivot row and column of $\mathbf{M}_p$} - \State $\mathbf{M}_p\left[0,0:N_p\right] \leftrightarrow \mathbf{M}_p\left[i_p,0:N_p\right]$ - \State $\mathbf{M}_p\left[0:N_p,0\right] \leftrightarrow \mathbf{M}_p\left[0:N_p,j_p\right]$ - \State \Comment{Apply Gaussian elimination for the current pivot element} - \State $\mathbf{M}_p\left[0,0:N_p\right] \gets \frac{1}{\mathbf{M}_p[0,0]}\mathbf{M}_p\left[0,0:N_p\right]$ - \State $\mathbf{M}_p\left[1:N_p,0:N_p\right] \gets \mathbf{M}_p\left[1:N_p,0:N_p\right] - \mathbf{M}_p\left[1:N_p,0\right] \otimes \mathbf{M}_p\left[0,0:N_p\right]$ - \State \Comment{Accumulate the permutation matrices} - \State In $\mathbf{P}$: swap $p \leftrightarrow p + i_p$ - \State In $\mathbf{Q}$: swap $p \leftrightarrow p + j_p$ -\EndFor -\end{algorithmic} -\end{algorithm} -$$ + +1. Initialize the permutations $\mathbf{P}$ and $\mathbf{Q}$ to the identity permutation. +2. Initialize fill-in elements to $0$. +3. Loop over all rows: $p = 0..(N-1)$: + 1. Set the remaining matrix: $\mathbf{M}_p \gets \mathbf{M}\left[p:N,p:N\right]$ with size $N_p\times N_p$, where + $N_p := N - p$. + 2. Find largest element $\mathbf{M}_p\left[i_p,j_p\right]$ in $\mathbf{M}_p$ by magnitude. + This is the pivot element. + 3. If the magnitude of the pivot element is too small: + 1. If pivot perturbation is enabled, then: + 1. Apply [pivot perturbation](#pivot-perturbation). + 2. Proceed. + 2. Else, if the matrix is singular (pivot element is identically $0$), then: + 1. Raise a `SparseMatrixError`. + 3. Else: + 1. Proceed. + 4. Else: + 1. Proceed. + 5. Swap the first and pivot row and column of $\mathbf{M}_p$, so that the pivot element is in the top-left corner of + the remaining matrix: + 1. $\mathbf{M}_p\left[0,0:N_p\right] \leftrightarrow \mathbf{M}\left[i_p,0:N_p\right]$ + 2. $\mathbf{M}_p\left[0:N_p,0\right] \leftrightarrow \mathbf{M}\left[0:N_p,j_p\right]$ + 6. Apply Gaussian elimination for the current pivot element: + 1. $\mathbf{M}_p\left[0,0:N_p\right] \gets \frac{1}{\mathbf{M}_p[0,0]}\mathbf{M}_p\left[0,0:N_p\right]$ + 2. $\mathbf{M}_p\left[1:N_p,0:N_p\right] \gets \mathbf{M}_p\left[1:N_p,0:N_p\right] - \mathbf{M}_p\left[1:N_p,0\right] \otimes \mathbf{M}_p\left[0,0:N_p\right]$ + 7. Accumulate the permutation matrices: + 1. In $\mathbf{P}$: swap $p \leftrightarrow p + i_p$ + 2. In $\mathbf{Q}$: swap $p \leftrightarrow p + j_p$ + 8. Continue with the next $p$ to factorize the the bottom-right block. + $\mathbf{L}$ is now the matrix containing the lower triangle of $\mathbf{M}$, ones on the diagonal and zeros in the upper triangle. @@ -876,13 +876,13 @@ as well as the well-known Let $\mathbf{M}$ be the matrix, $\left|\mathbf{M}\right|_{\infty ,\text{bwod}}$ the [block-wise off-diagonal infinite norm](#block-wise-off-diagonal-infinite-matrix-norm) of the matrix. -1. $\epsilon \gets \text{perturbation\_threshold} * \left|\mathbf{M}\right|_{\text{bwod}}$. -2. If $\left|\text{pivot\_element}\right| \lt \epsilon$, then: - 1. If $\left|\text{pivot\_element}\right| = 0$, then: +1. $\epsilon \gets \text{perturbation\_threshold} * \lvert\mathbf{M}\rvert_{\text{bwod}}$. +2. If $\lvert\text{pivot\_element}\rvert \lt \epsilon$, then: + 1. If $\lvert\text{pivot\_element}\rvert = 0$, then: 1. $\text{phase\_shift} \gets 1$. 2. Proceed. 2. Else: - 1. $\text{phase\_shift} \gets \text{pivot\_element} / \left|\text{pivot\_element}\right|$. + 1. $\text{phase\_shift} \gets \text{pivot\_element} / \lvert\text{pivot\_element}\rvert$. 2. Proceed. 3. $\text{pivot\_element} \gets \epsilon * \text{phase\_shift}$. @@ -1121,34 +1121,27 @@ $\mathbf{M}\left[i,j\right]$ its block element at (0-based) indices $(i,j)$, whe In turn, let $\mathbf{M}\left[i,j\right] \equiv \mathbf{M}_{i,j}\left[0:N_{i,j},0:N_{i,j}\right]$ be the dense block with dimensions $N_i\times N_j$. -$$ -\begin{algorithm} -\caption{Block-wise off-diagonal infinite matrix norm} -\begin{algorithmic} -\State $\text{norm} \gets 0$ -\For{$i = 0$ \textbf{to} $N-1$} \Comment{Loop over all block-rows} - \State $\text{row\_norm} \gets 0$ - \For{$j = 0$ \textbf{to} $N-1$} \Comment{Loop over all block-columns (beware of sparse structure)} - \If{$i = j$} - \State \textbf{continue} \Comment{Skip this block} - \Else \Comment{Calculate the $L_{\infty}$ norm of the current block} - \State $\mathbf{M}_{i,j} \gets \mathbf{M}\left[i,j\right]$ \Comment{Get the current block} - \State $\text{block\_norm} \gets 0$ - \For{$k = 0$ \textbf{to} $N_{i,j} - 1$} \Comment{Loop over all rows of the current block} - \State $\text{block\_row\_norm} \gets 0$ - \For{$l = 0$ \textbf{to} $N_{i,j} - 1$} \Comment{Loop over all columns of the current block} - \State $\text{block\_row\_norm} \gets \text{block\_row\_norm} + \left|\mathbf{M}_{i,j}\left[k,l\right]\right|$ - \EndFor - \State $\text{block\_norm} \gets \max\left\{\text{block\_norm}, \text{block\_row\_norm}\right\}$ - \EndFor - \State $\text{row\_norm} \gets \text{row\_norm} + \text{block\_norm}$ - \EndIf - \EndFor - \State $\text{norm} \gets \max\left\{\text{norm}, \text{row\_norm}\right\}$ -\EndFor -\end{algorithmic} -\end{algorithm} -$$ +1. $\text{norm} \gets 0$. +2. Loop over all block-rows: $i = 0..(N-1)$: + 1. $\text{row\_norm} \gets 0$. + 2. Loop over all block-columns: $j = 0..(N-1)$ (beware of sparse structure): + 1. If $i = j$, then: + 1. Skip this block: continue with the next block-column. + 2. Else, calculate the $L_{\infty}$ norm of the current block and add to the current row norm: + 1. the current block: $\mathbf{M}_{i,j} \gets \mathbf{M}\left[i,j\right]$. + 2. $\text{block\_norm} \gets 0$. + 3. Loop over all rows of the current block: $k = 0..(N_{i,j} - 1)$: + 1. $\text{block\_row\_norm} \gets 0$. + 2. Loop over all columns of the current block: $l = 0..(N_{i,j} - 1)$: + 1. $\text{block\_row\_norm} \gets \text{block\_row\_norm} + \lvert\mathbf{M}_{i,j}\left[k,l\right]\rvert$. + 3. Calculate the new block norm: set + $\text{block\_norm} \gets \max\left\{\text{block\_norm}, \text{block\_row\_norm}\right\}$. + 4. Continue with the next row of the current block. + 4. $\text{row\_norm} \gets \text{row\_norm} + \text{block\_norm}$. + 5. Continue with the next block-column. + 3. Calculate the new norm: set + $\text{norm} \gets \max\left\{\text{norm}, \text{row\_norm}\right\}$. + 4. Continue with the next block-row. ##### Illustration of the block-wise off-diagonal infinite matrix norm calculation From 26e32d19a4babbc086c711232445a455ca5efc2b Mon Sep 17 00:00:00 2001 From: Martijn Govers Date: Mon, 3 Aug 2026 11:10:37 +0200 Subject: [PATCH 14/14] fully migrate with table support Signed-off-by: Martijn Govers --- .pymarkdown | 4 ++-- docs/algorithms/pf-algorithms.md | 4 +++- docs/algorithms/sc-algorithms.md | 3 ++- docs/algorithms/se-algorithms.md | 8 ++++--- docs/contribution/folder-structure.md | 4 +++- docs/user_manual/calculations.md | 21 ++++++++++++------- docs/user_manual/components.md | 2 +- docs/user_manual/data-model.md | 2 ++ docs/user_manual/non-pgm-components.md | 2 +- docs/user_manual/serialization.md | 12 +++++------ .../data/power_flow/generic_branch/README.md | 2 +- 11 files changed, 40 insertions(+), 24 deletions(-) diff --git a/.pymarkdown b/.pymarkdown index f486d20aa8..b519ae8657 100644 --- a/.pymarkdown +++ b/.pymarkdown @@ -8,10 +8,10 @@ }, "line-length": { "enabled": true, + "tables": false, "line_length": 120, "heading_line_length": 120, - "code_block_line_length": 120, - "table_line_length": 1000000 + "code_block_line_length": 120 } }, "extensions": { diff --git a/docs/algorithms/pf-algorithms.md b/docs/algorithms/pf-algorithms.md index fb1cbc92ca..cfa3effefb 100644 --- a/docs/algorithms/pf-algorithms.md +++ b/docs/algorithms/pf-algorithms.md @@ -37,7 +37,9 @@ The following bus types can be present in the system: Note: this bus is not supported by power-grid-model yet. ```{note} -Asymmetric power flow calculations require the network to have a reference to ground. For details and internal solution of asymmetric floating grids calculations in power-grid-model, please refer to [Floating grid handling](../user_manual/calculations.md#floating-grid-handling). +Asymmetric power flow calculations require the network to have a reference to ground. For details and internal solution +of asymmetric floating grids calculations in power-grid-model, please refer to +[Floating grid handling](../user_manual/calculations.md#floating-grid-handling). ``` ## Newton-Raphson power flow diff --git a/docs/algorithms/sc-algorithms.md b/docs/algorithms/sc-algorithms.md index 8c60a8fb5f..748969050f 100644 --- a/docs/algorithms/sc-algorithms.md +++ b/docs/algorithms/sc-algorithms.md @@ -22,7 +22,8 @@ This gives the initial symmetrical short circuit current ($I_k^{\prime\prime}$) This quantity is then used to derive almost all further calculations of short circuit studies applications. ```{note} -Short-circuit calculations are currently implemented in the phase (abc) domain and therefore require a grounded network, similar to asymmetric power flow calculations. +Short-circuit calculations are currently implemented in the phase (abc) domain and therefore require a grounded network, +similar to asymmetric power flow calculations. Note that this limitation does not exist in the sequence (0-1-2) domain but is present in the phase domain calculation. ``` diff --git a/docs/algorithms/se-algorithms.md b/docs/algorithms/se-algorithms.md index a189755c9d..949ee6dc13 100644 --- a/docs/algorithms/se-algorithms.md +++ b/docs/algorithms/se-algorithms.md @@ -105,8 +105,8 @@ It is not possible to mix [power sensors](../user_manual/components.md#generic-p [current sensors](../user_manual/components.md#generic-current-sensor) on the same terminal of the same component. It is also not possible to mix [current sensors with global angle measurement type](../user_manual/components.md#global-angle-current-sensors) with -[current sensors with local angle measurement type](../user_manual/components.md#local-angle-current-sensors) on the same terminal -of the same component. +[current sensors with local angle measurement type](../user_manual/components.md#local-angle-current-sensors) on the +same terminal of the same component. However, such mixing of sensor types is allowed as long as they are on different terminals. ``` @@ -298,6 +298,7 @@ The rationale behind to calculation is similar to that of the Consequently, the iteration process differs slightly from that of [iterative linear state estimation](#iterative-linear-state-estimation), as shown below. + - Initialization: let $\boldsymbol{U}^{(k)}$ be the column vector of the estimated voltage magnitude and $\boldsymbol{\theta}^{(k)}$ the column vector of the estimated voltage angle in k-th iteration. Let Bus $s$ be the [slack bus](../advanced_documentation/terminology.md#slack-bus-pgm-internal) which is connected to @@ -313,11 +314,12 @@ Consequently, the iteration process differs slightly from that of $\widetilde{\boldsymbol{U}}^{(k)}$ and $\widetilde{\boldsymbol{\theta}}^{(k)}$, using the prefactorized matrix. See also [Matrix-prefactorization](../user_manual/performance-guide.md#matrix-prefactorization) - Normalize the result voltage phasor angle by setting angle of slack bus to zero: - $\underline{U}_i^{(k)} = \widetilde{\underline{U}}_i^{(k)} \times |\widetilde{\underline{U}}_s^{(k)}| / \widetilde{\underline{U}}_s^{(k)}$. + $\underline{U}_i^{(k)} = \widetilde{\underline{U}}_i^{(k)} \times |\widetilde{\underline{U}}_s^{(k)}| / \widetilde{\underline{U}}_s^{(k)}$. - If the maximum deviation between $\underline{\boldsymbol{U}}^{(k)}$ and $\underline{\boldsymbol{U}}^{(k-1)}$ is smaller than the tolerance $\epsilon$, stop the iteration, otherwise continue until the maximum number of iterations is reached. Note: we're using the phasor here: $\underline{\boldsymbol{U}} = \boldsymbol{U}e^{j\boldsymbol{\theta}}$. + As for the [iterative linear](#iterative-linear-state-estimation) approach, during iterations, phase angles of voltage at each bus are updated using ones from the previous iteration. diff --git a/docs/contribution/folder-structure.md b/docs/contribution/folder-structure.md index 199a4ef2c5..83548d5838 100644 --- a/docs/contribution/folder-structure.md +++ b/docs/contribution/folder-structure.md @@ -8,8 +8,9 @@ SPDX-License-Identifier: MPL-2.0 The repository folder structure is as follows. The `docs` and `scripts` folders are self-explanatory. + - The C++ calculation core is inside - {{ "[power_grid_model_c/power_grid_model/include/power_grid_model]({}/power_grid_model_c/power_grid_model/include/power_grid_model)".format(gh_link_head_tree) }}. + {{ "[power_grid_model_c/power_grid_model/include/power_grid_model]({}/power_grid_model_c/power_grid_model/include/power_grid_model)".format(gh_link_head_tree) }}. - The C API is inside {{ "[power_grid_model_c/power_grid_model_c]({}/power_grid_model_c/power_grid_model_c)".format(gh_link_head_tree) }}. - The C program example to use the C API is inside @@ -29,3 +30,4 @@ The repository folder structure is as follows. The `docs` and `scripts` folders - `data` contains validation test cases designed for every component and algorithm. Some sample network types are also included. The validation is either against popular power system analysis software or hand calculation. + diff --git a/docs/user_manual/calculations.md b/docs/user_manual/calculations.md index 47ac854f38..f0f83edab9 100644 --- a/docs/user_manual/calculations.md +++ b/docs/user_manual/calculations.md @@ -124,8 +124,9 @@ However, such mixing of sensor types is allowed as long as they are on different ``` ```{warning} -The [iterative linear](../algorithms/se-algorithms.md#iterative-linear-state-estimation) and [Newton-Raphson](../algorithms/se-algorithms.md#newton-raphson-state-estimation) state -estimation algorithms will assume angles to be zero by default (see the details about voltage sensors). +The [iterative linear](../algorithms/se-algorithms.md#iterative-linear-state-estimation) and +[Newton-Raphson](../algorithms/se-algorithms.md#newton-raphson-state-estimation) state estimation algorithms will assume +angles to be zero by default (see the details about voltage sensors). In observable systems this helps better outputting correct results. On the other hand with unobservable systems, exceptions raised from calculations due to faulty results will be prevented. @@ -193,8 +194,11 @@ Output: - Current flowing through branches and fault. ```{note} -Short-circuit calculations are currently implemented in the phase (abc) domain and therefore require a grounded configurations in certain cases, similar to asymmetric power flow calculations. -For details on how floating grids are treated in power-grid-model, please refer to[Floating grid handling](calulations.md#floating-grid-handling). +Short-circuit calculations are currently implemented in the phase (abc) domain and therefore require a grounded +configurations in certain cases, similar to asymmetric power flow calculations. +For details on how floating grids are treated in power-grid-model, please refer to +[Floating grid handling](calulations.md#floating-grid-handling). +``` #### Common calculations @@ -240,7 +244,10 @@ The option affects which attributes are required and how results are exposed. for all output variables. ```{note} -In power-grid model, asymmetric calculations with certain configurations require the network to have a reference to ground. For details on how floating grids are treated in power-grid-model, please refer to [Floating grid handling](calulations.md#floating-grid-handling). +In power-grid model, asymmetric calculations with certain configurations require the network to have a reference to +ground. +For details on how floating grids are treated in power-grid-model, please refer to +[Floating grid handling](calulations.md#floating-grid-handling). ``` ```{note} @@ -299,8 +306,8 @@ By default, the [Newton-Raphson](../algorithms/pf-algorithms.md#newton-raphson-p ``` ```{note} -When all the load/generation types are of constant impedance, the [Linear](../algorithms/pf-algorithms.md#linear-power-flow) method will be the -fastest without loss of accuracy. +When all the load/generation types are of constant impedance, the +[Linear](../algorithms/pf-algorithms.md#linear-power-flow) method will be the fastest without loss of accuracy. Therefore power-grid-model will use this method regardless of the input provided by the user in this case. ``` diff --git a/docs/user_manual/components.md b/docs/user_manual/components.md index 639fa08157..09d902804c 100644 --- a/docs/user_manual/components.md +++ b/docs/user_manual/components.md @@ -732,7 +732,7 @@ It behaves similar to a load/generator with type `const_impedance`. | `b0` | `double` | siemens (S) | zero-sequence shunt susceptance | ✨ only for asymmetric calculation | ✔ | ```{note} -In power-grid-model, shunts may also be used to introduce a ground reference in an otherwise floating grid. +In power-grid-model, shunts may also be used to introduce a ground reference in an otherwise floating grid. ``` ```{note} diff --git a/docs/user_manual/data-model.md b/docs/user_manual/data-model.md index 64b2c0e55a..36bbb978db 100644 --- a/docs/user_manual/data-model.md +++ b/docs/user_manual/data-model.md @@ -14,6 +14,7 @@ The components types are organized in an inheritance-like hierarchy. A sub-type has all the attributes from its parent type. The hierarchy tree of the component types is shown below. + ```{mermaid} graph LR base-->node @@ -43,6 +44,7 @@ graph LR classDef green fill:#9f6,stroke:#333,stroke-width:2px class node,line,link,generic_branch,transformer,three_winding_transformer,source,shunt,sym_load,sym_gen,asym_load,asym_gen,sym_voltage_sensor,asym_voltage_sensor,sym_power_sensor,asym_power_sensor green ``` + ```{note} The type names in the hierarchy are exactly the same as the component type names in diff --git a/docs/user_manual/non-pgm-components.md b/docs/user_manual/non-pgm-components.md index 403edd6e90..c8a6043f28 100644 --- a/docs/user_manual/non-pgm-components.md +++ b/docs/user_manual/non-pgm-components.md @@ -20,7 +20,7 @@ New contributions and ideas for modeling grid components are very welcome! ## Ideal transformer -An ideal transformer can be modeled as a [link](./components.md#link). +An ideal transformer can be modeled as a [link](./components.md#link). To this end, it is explicitly allowed to place a link between two different voltage levels. Trivially, no additional electrical parameters need to be specified. diff --git a/docs/user_manual/serialization.md b/docs/user_manual/serialization.md index 06ecc9b796..f370fae914 100644 --- a/docs/user_manual/serialization.md +++ b/docs/user_manual/serialization.md @@ -225,11 +225,11 @@ The type is listed for each attribute in [Components](components.md). - [`RealValueInput`](#json-schema-realvalueinput): [`double`](#json-schema-double) for symmetric calculations. - [`RealValueInput`](#json-schema-realvalueinput): `Array` of size 3 for asymmetric calculations, one for each phase. - - [`double`](#json-schema-double) | [`null`](#json-schema-null-absence-of-value): the value for the `_a` phase, if + - [`double`](#json-schema-double) | [`null`](#json-schema-null-absence-of-value): the value for the `_a` phase, if specified. - - [`double`](#json-schema-double) | [`null`](#json-schema-null-absence-of-value): the value for the `_b` phase, if + - [`double`](#json-schema-double) | [`null`](#json-schema-null-absence-of-value): the value for the `_b` phase, if specified. - - [`double`](#json-schema-double) | [`null`](#json-schema-null-absence-of-value): the value for the `_c` phase, if + - [`double`](#json-schema-double) | [`null`](#json-schema-null-absence-of-value): the value for the `_c` phase, if specified. #### JSON schema RealValueOutput @@ -242,11 +242,11 @@ The type is listed for each attribute in [Components](components.md). - [`RealValueOutput`](#json-schema-realvalueoutput): [`double`](#json-schema-double) for symmetric calculations. - [`RealValueOutput`](#json-schema-realvalueoutput): `Array` of size 3 for asymmetric calculations, one for each phase. - - [`double`](#json-schema-double) | [`null`](#json-schema-null-absence-of-value): the value for the `_a` phase, if + - [`double`](#json-schema-double) | [`null`](#json-schema-null-absence-of-value): the value for the `_a` phase, if specified. - - [`double`](#json-schema-double) | [`null`](#json-schema-null-absence-of-value): the value for the `_b` phase, if + - [`double`](#json-schema-double) | [`null`](#json-schema-null-absence-of-value): the value for the `_b` phase, if specified. - - [`double`](#json-schema-double) | [`null`](#json-schema-null-absence-of-value): the value for the `_c` phase, if + - [`double`](#json-schema-double) | [`null`](#json-schema-null-absence-of-value): the value for the `_c` phase, if specified. #### JSON schema single dataset example diff --git a/tests/data/power_flow/generic_branch/README.md b/tests/data/power_flow/generic_branch/README.md index 1f2d46cc05..76b0929a4d 100644 --- a/tests/data/power_flow/generic_branch/README.md +++ b/tests/data/power_flow/generic_branch/README.md @@ -11,5 +11,5 @@ Test case for validation of the generic_branch component for symmetrical power f The circuit diagram is as follows: ```txt -source_4--node_1--generic_branch_3--node_2--load_5 +source_4--node_1--generic_branch_3--node_2--load_5 ```