diff --git a/.gitattributes b/.gitattributes index 72e0ae75..5b14b347 100644 --- a/.gitattributes +++ b/.gitattributes @@ -3,3 +3,4 @@ *.ico filter=lfs diff=lfs merge=lfs -text *.pfd filter=lfs diff=lfs merge=lfs -text .vscode/*.json linguist-language=jsonc +*.webp filter=lfs diff=lfs merge=lfs -text diff --git a/.github/dependabot.yml b/.github/dependabot.yml index eac7872b..3d52c3cb 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -5,3 +5,5 @@ updates: target-branch: "develop" schedule: interval: "monthly" + cooldown: + default-days: 7 diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 11e908ca..3f47ccba 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -26,14 +26,15 @@ jobs: runs-on: ubuntu-latest strategy: + fail-fast: false matrix: - python-version: ["3.11", "3.12", "3.13"] #, "3.13t", "3.14-dev"] # waiting for pyproj support + python-version: ["3.12", "3.13", "3.13t", "3.14", "3.14t"] permissions: contents: read steps: - - uses: actions/checkout@v5 + - uses: actions/checkout@v6 with: lfs: false persist-credentials: false @@ -42,7 +43,7 @@ jobs: run: git lfs ls-files -l | cut -d' ' -f1 | sort > .lfs-assets-id - name: Cache git LFS - uses: actions/cache@v4 + uses: actions/cache@v5 with: path: .git/lfs key: git-lfs-v1-${{ matrix.python-version }}-${{ hashFiles('.lfs-assets-id') }} @@ -58,13 +59,9 @@ jobs: git lfs prune --verify-remote - name: Install uv - uses: astral-sh/setup-uv@v6 + uses: astral-sh/setup-uv@v7 with: enable-cache: true - - - name: Set up Python ${{ matrix.python-version }} - uses: actions/setup-python@v5 - with: python-version: ${{ matrix.python-version }} - name: Install dependencies @@ -73,12 +70,12 @@ jobs: - name: Test with pytest run: | - uv run pytest -vv -n=auto --durations=25 --cov --cov-report=html roseau + uv run pytest -vv --durations=25 --cov --cov-report=html roseau env: ROSEAU_LOAD_FLOW_LICENSE_KEY: ${{ secrets.ROSEAU_LOAD_FLOW_LICENSE_KEY }} - name: Archive code coverage results - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@v6 if: ${{ always() }} with: name: code-coverage-report-${{ runner.os }}-python-${{ matrix.python-version }} diff --git a/.github/workflows/pre-commit.yml b/.github/workflows/pre-commit.yml index 73e87079..b0f5da41 100644 --- a/.github/workflows/pre-commit.yml +++ b/.github/workflows/pre-commit.yml @@ -22,11 +22,32 @@ jobs: permissions: contents: read steps: - - uses: actions/checkout@v5 + - uses: actions/checkout@v6 with: lfs: false persist-credentials: false - - uses: actions/setup-python@v5 + + - name: Create LFS file list + run: git lfs ls-files -l | cut -d' ' -f1 | sort > .lfs-assets-id + + - name: Cache git LFS + uses: actions/cache@v5 + with: + path: .git/lfs + key: git-lfs-v1-${{ matrix.python-version }}-${{ hashFiles('.lfs-assets-id') }} + restore-keys: | + git-lfs-v1-${{ matrix.python-version }} + git-lfs-v1 + git-lfs + + - name: Git LFS + run: | + git lfs checkout + git lfs pull + git lfs prune --verify-remote + + - uses: actions/setup-python@v6 with: python-version: "3.13" + - uses: pre-commit/action@v3.0.1 diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index bcd46696..73e118c0 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -11,11 +11,11 @@ repos: - id: end-of-file-fixer - id: trailing-whitespace - repo: https://github.com/astral-sh/uv-pre-commit - rev: 0.8.14 + rev: 0.9.26 hooks: - id: uv-lock - repo: https://github.com/python-jsonschema/check-jsonschema - rev: 0.33.3 + rev: 0.36.0 hooks: - id: check-github-workflows - id: check-dependabot @@ -23,28 +23,28 @@ repos: - repo: https://github.com/adhtruong/mirrors-typos # See https://github.com/crate-ci/typos/issues/390 # repo: https://github.com/crate-ci/typos - rev: v1.36.0 + rev: v1.42.1 hooks: - id: typos args: [--force-exclude] - repo: https://github.com/woodruffw/zizmor-pre-commit - rev: v1.12.1 + rev: v1.22.0 hooks: - id: zizmor - repo: https://github.com/astral-sh/ruff-pre-commit - rev: v0.12.11 + rev: v0.14.13 hooks: - id: ruff-check args: [--fix] - id: ruff-format - repo: https://github.com/adamchainz/blacken-docs - rev: 1.19.1 + rev: 1.20.0 hooks: - id: blacken-docs files: ^doc/.*\.md$ args: [-l 90] - repo: https://github.com/executablebooks/mdformat - rev: 0.7.22 + rev: 1.0.0 hooks: - id: mdformat additional_dependencies: @@ -57,7 +57,7 @@ repos: - mdformat-deflist exclude: ^.github/.*\.md$ - repo: https://github.com/rbubley/mirrors-prettier - rev: v3.6.2 + rev: v3.8.0 hooks: - id: prettier args: ["--print-width", "120"] @@ -69,8 +69,18 @@ repos: - id: latexindent args: [-l, -m, -s, -wd] - repo: https://github.com/biomejs/pre-commit - rev: v2.2.2 + rev: v2.3.11 hooks: - id: biome-check types_or: [json, html, css] files: ".*" # Override default files regex that excludes html, rely on `types_or` instead + - repo: https://github.com/tombi-toml/tombi-pre-commit + rev: v0.7.19 + hooks: + - id: tombi-format + - id: tombi-lint + - repo: https://github.com/oxipng/oxipng + rev: v10.0.0 + hooks: + - id: oxipng + args: ["-o", "4", "--strip", "safe", "--alpha"] diff --git a/.vscode/extensions.json b/.vscode/extensions.json index 51acae9d..aa20fc64 100644 --- a/.vscode/extensions.json +++ b/.vscode/extensions.json @@ -1,8 +1,6 @@ { "recommendations": [ "charliermarsh.ruff", - "esbenp.prettier-vscode", "ms-python.python", - "ms-python.vscode-pylance", ], } diff --git a/README.md b/README.md index 25fc0fcf..f996217c 100644 --- a/README.md +++ b/README.md @@ -25,7 +25,7 @@ In addition to the following **unique** set of features: -This project is compatible with Python version 3.11 and newer. The +This project is compatible with Python version 3.12 and newer. The [installation instructions](https://roseau-load-flow.roseautechnologies.com/en/latest/Installation.html) will guide you through the installation process. If you are new to _Roseau Load Flow_, we recommend you start with the [getting started tutorial](https://roseau-load-flow.roseautechnologies.com/en/latest/usage/Getting_Started.html). You @@ -51,15 +51,21 @@ Read more at [License](https://roseau-load-flow.roseautechnologies.com/en/latest _Roseau Load Flow_ ships with a sample of 20 low-voltage and 20 medium-voltage feeder networks. Each network is provided with its summer and winter load points. -To go further, you can also use -[these 150 distribution networks](https://www.data.gouv.fr/fr/datasets/departs-hta-representatifs-pour-lanalyse-des-reseaux-de-distribution-francais/), -published by [Mines Paris Tech](https://www.minesparis.psl.eu/) in _Roseau Load Flow_ format. Supplied with their -respective coefficients, these representative networks can be used to simulate the entire French distribution network. + + +We also maintain a set of 150 MV feeders representative of the French distribution system at +https://github.com/RoseauTechnologies/Representative_French_Power_Grids. Each feeder is modeled with its downstream LV +networks. The repository also contains the cluster size that indicates how representative is each network of the French +distribution system. These networks are the result of the study +[Representative MV feeders for the analysis of French distribution networks](https://www.roseautechnologies.com/en/electrical-model-of-the-french-distribution-network/), +made and published by [Mines Paris Tech](https://www.minesparis.psl.eu/). + +
- Catalogue of networks + Catalogue of networks
## Bug reports / Feature requests diff --git a/biome.jsonc b/biome.jsonc index 9ce6e159..b8ff818c 100644 --- a/biome.jsonc +++ b/biome.jsonc @@ -1,5 +1,5 @@ { - "$schema": "https://biomejs.dev/schemas/2.2.2/schema.json", + "$schema": "https://biomejs.dev/schemas/2.3.11/schema.json", "vcs": { "enabled": false, "clientKind": "git", @@ -7,7 +7,7 @@ }, "files": { "ignoreUnknown": false, - "maxSize": 2097152 // 2 MiB to accommodate the networks Catalogue.html file (1.6 MiB) + "includes": ["**", "!doc/_static/**/*.html"] }, "formatter": { "enabled": true, @@ -38,6 +38,9 @@ "html": { "formatter": { "enabled": true // Enable experimental HTML formatting + }, + "linter": { + "enabled": false // Disable linting generated HTML files } } } diff --git a/doc/Changelog.md b/doc/Changelog.md index 810ec145..4eb46286 100644 --- a/doc/Changelog.md +++ b/doc/Changelog.md @@ -19,6 +19,66 @@ og:description: See what's new in the latest release of Roseau Load Flow ! # Changelog +## Version 0.14.0 + +- {gh-pr}`435` {gh-issue}`436` Add `rlf.converters.kron_reduction` function to perform Kron reduction on any nxn matrix + reducing it to an (n-1)x(n-1) matrix by eliminating the last row and column. Also add `eliminate_neutral` parameter to + `rlf.LineParameters.to_sym` to optionally eliminate the neutral conductor using Kron's reduction when converting line + parameters to symmetrical components. + +- {gh-pr}`434` {gh-issue}`422` Add LV line parameters to the catalogue (e.g. `U_AL_3x150+70`). You can get all added LV + lines with `rlf.LineParameters.get_catalogue(r"^[UOT]_[A-Z]+_3x(\d+)\+(\d+(?:\.\d+)?)$")`. + +- {gh-pr}`429` {gh-issue}`298` Add `rlf.plotting.voltage_profile` function to plot the voltage profile of a network. The + function returns an object with `plot_matplotlib()` and `plot_plotly()` methods to create plots using Matplotlib or + Plotly respectively. + +- {gh-pr}`427` Add missing transformer tap to the edge data in the graph generated by `ElectricalNetwork.to_graph`. + +- {gh-pr}`426` Add `rlf.plotting.plot_results_interactive_map` for plotting a network with load flow results on an + interactive map. Buses are colored according to their voltage levels and lines are colored according to their loading + levels. + +- {gh-pr}`425` Enforce the following deprecations: + + - The `side` parameter of `rlf.GroundConnection`, `rlf.plotting.plot_voltage_phasors` and + `rlf.plotting.plot_symmetrical_voltages` is removed. Pass a branch side directly instead (e.g. + `rlf.GroundConnection(ground=ground, element=transformer.side_hv)`). + - The `potentials` attribute and constructor parameter of `Bus` is removed. Use `initial_potentials` instead. + - The `bus` of a disconnected load or source no longer returns `None`. Use the new `is_disconnected` property to check + if the load or source is disconnected. + - The `phase` parameter of `rlf.PotentialRef` is removed. Use `phases` instead. + - The `res_voltages_hv` and `res_voltages_lv` attributes of `rlf.Transformer` are removed. Use `.res_voltages` + instead. + - Deprecated names in `rlf.constants`, `rlf.types` and `rlf.sym` modules are removed. + - Deprecated modules in the `rlf.utils` package are removed. This package is for internal use only and should not be + considered stable. + +- {gh-pr}`421` Improve initial voltage guesses in the Newton algorithm for networks involving delta connected sources. + +- {gh-pr}`419` {gh-pr}`420` Require Python 3.12 or newer and bump the minimum supported versions of some dependencies + per [SPEC-0](https://scientific-python.org/specs/spec-0000/). + +- {gh-pr}`418` Many improvements to the styles of interactive map plots: + + - Different voltage levels are represented with different marker sizes and line widths. Nominal voltages are used to + determine the voltage levels automatically. If nominal voltages are not available, they are inferred from the + transformers and sources + - Underground lines are dashed while other lines are solid including lines with unknown line type + - Transformers are now represented with a square icon with a divider in the middle and with both HV and LV buses + information in the tooltip and popup + - Sourcers are represented with a bigger square icon + - If the new parameter `fit_bounds` is set to `True` (default), the bounds of the map will be automatically adjusted + using `folium.FitOverlays` to fit the network elements. + + Note that the markers of buses, transformers and sources now use the `folium.DivIcon` icon which means the style + function must now return a style dictionary of the form `{'html': ...}` for these elements. + +- {gh-pr}`413` Restore bus and layers to the layer control in the interactive map plot. This was broken in version + 0.13.0. + +- {gh-pr}`404` Fix filtering catalogues using compiled regular expressions with newer versions of pandas. + ## Version 0.13.1 - Fix a bug where license validation failed when the English (US) language was not installed on the system (observed on diff --git a/doc/License.md b/doc/License.md index 049c66b9..14ec5729 100644 --- a/doc/License.md +++ b/doc/License.md @@ -104,7 +104,7 @@ section. Create a new variable called `ROSEAU_LOAD_FLOW_LICENSE_KEY`, with the v variable is personal to you, and the toggle will allow you to enable access to the license key for notebooks of your choice. -```{image} /_static/2024_09_16_Google_Colab_Environment_Variable.png +```{image} /_static/2024_09_16_Google_Colab_Environment_Variable.webp --- alt: Google Colab environment variable align: center @@ -148,7 +148,7 @@ this file when you run your code (including when using Jupyter Notebooks in VS C If you are using [PyCharm](https://www.jetbrains.com/pycharm/), you can add the environment variable to your _Python Console_ settings as indicated in the screenshot below: -```{image} /_static/2024_01_12_Pycharm_Console_Environment_Variable.png +```{image} /_static/2024_01_12_Pycharm_Console_Environment_Variable.webp --- alt: Pycharm Console environment variable align: center diff --git a/doc/_static/2024_01_12_Pycharm_Console_Environment_Variable.png b/doc/_static/2024_01_12_Pycharm_Console_Environment_Variable.png deleted file mode 100644 index 2ace59ab..00000000 --- a/doc/_static/2024_01_12_Pycharm_Console_Environment_Variable.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:8e6e87a83caae20dfd721cb269926dc95e2d25170aba2425fc55f15c0cfbe244 -size 112823 diff --git a/doc/_static/2024_01_12_Pycharm_Console_Environment_Variable.webp b/doc/_static/2024_01_12_Pycharm_Console_Environment_Variable.webp new file mode 100644 index 00000000..22f319f1 --- /dev/null +++ b/doc/_static/2024_01_12_Pycharm_Console_Environment_Variable.webp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:55dc4d5907aaf6c1941edfed13b0c8f85c26a957b262986872136eeeb7aea54c +size 42980 diff --git a/doc/_static/2024_09_16_Google_Colab_Environment_Variable.png b/doc/_static/2024_09_16_Google_Colab_Environment_Variable.png deleted file mode 100644 index b3ff0016..00000000 --- a/doc/_static/2024_09_16_Google_Colab_Environment_Variable.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:4d0a5e9a1f3daee0a3e8dc46ebe7aee5fc66bb6c1ba03381d03f972ddcc00d61 -size 77012 diff --git a/doc/_static/2024_09_16_Google_Colab_Environment_Variable.webp b/doc/_static/2024_09_16_Google_Colab_Environment_Variable.webp new file mode 100644 index 00000000..615e5db5 --- /dev/null +++ b/doc/_static/2024_09_16_Google_Colab_Environment_Variable.webp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:dfef9142f46690f39f20da4a0c18010619cde541772191a672c917d483ed1bb1 +size 36662 diff --git a/doc/_static/Advanced/Floating_Neutral_Auto.png b/doc/_static/Advanced/Floating_Neutral_Auto.png deleted file mode 100644 index 79a4e6f4..00000000 --- a/doc/_static/Advanced/Floating_Neutral_Auto.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:fb82d047655d02de61f91e69348040bddde6ebca1d77b51c5963824a4817f20d -size 40667 diff --git a/doc/_static/Advanced/Floating_Neutral_Auto.webp b/doc/_static/Advanced/Floating_Neutral_Auto.webp new file mode 100644 index 00000000..e74b7eb6 --- /dev/null +++ b/doc/_static/Advanced/Floating_Neutral_Auto.webp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:9a9189c7070b68ed4a83c3d0138a4f1341b5e6dba5c7bc508063fed5e0f0cf51 +size 17574 diff --git a/doc/_static/Advanced/Floating_Neutral_Manual.png b/doc/_static/Advanced/Floating_Neutral_Manual.png deleted file mode 100644 index 6fd4befa..00000000 --- a/doc/_static/Advanced/Floating_Neutral_Manual.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:24030c2e85cae186064bfa5a15b2b7e1a0126c1000fae814258489ce075842b3 -size 37304 diff --git a/doc/_static/Advanced/Floating_Neutral_Manual.webp b/doc/_static/Advanced/Floating_Neutral_Manual.webp new file mode 100644 index 00000000..8c9a8b26 --- /dev/null +++ b/doc/_static/Advanced/Floating_Neutral_Manual.webp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:6dea8390a8902992449a1de692eaa3fb5fb84d46ece873692f365690b2d06d15 +size 17850 diff --git a/doc/_static/Advanced/Floating_Neutral_Transformer.png b/doc/_static/Advanced/Floating_Neutral_Transformer.png deleted file mode 100644 index fce4393f..00000000 --- a/doc/_static/Advanced/Floating_Neutral_Transformer.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:4ef4faa064c8926e7b8eb095d42dfe1551cc583f9f63d1f0e91c28eb86893565 -size 62670 diff --git a/doc/_static/Advanced/Floating_Neutral_Transformer.webp b/doc/_static/Advanced/Floating_Neutral_Transformer.webp new file mode 100644 index 00000000..33dad2c7 --- /dev/null +++ b/doc/_static/Advanced/Floating_Neutral_Transformer.webp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:825bd6300cee8bf8bbf2004885fe90e452eb4d62740be7df73799826278b48d9 +size 26092 diff --git a/doc/_static/Advanced/Goldstein_And_Price.svg b/doc/_static/Advanced/Goldstein_And_Price.svg index 292ae89a..09b8c226 100644 --- a/doc/_static/Advanced/Goldstein_And_Price.svg +++ b/doc/_static/Advanced/Goldstein_And_Price.svg @@ -1 +1 @@ - + diff --git a/doc/_static/Bus.svg b/doc/_static/Bus.svg index cdec364c..23ee6a50 100644 --- a/doc/_static/Bus.svg +++ b/doc/_static/Bus.svg @@ -1 +1 @@ - + diff --git a/doc/_static/Ground.svg b/doc/_static/Ground.svg index d54e4113..2fdcdb90 100644 --- a/doc/_static/Ground.svg +++ b/doc/_static/Ground.svg @@ -1 +1 @@ - + diff --git a/doc/_static/IO/DGS_Export_Window.png b/doc/_static/IO/DGS_Export_Window.png deleted file mode 100644 index d63e2766..00000000 --- a/doc/_static/IO/DGS_Export_Window.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:e4f2844a5b6413fd6733da9ede65d64d1434ca75f2e3e5c990230656796f5486 -size 25741 diff --git a/doc/_static/IO/DGS_Export_Window.webp b/doc/_static/IO/DGS_Export_Window.webp new file mode 100644 index 00000000..df38b9d8 --- /dev/null +++ b/doc/_static/IO/DGS_Export_Window.webp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:5badd0f2543bb3007f58889ecca4dbae5807eae1a5a73e1366a3ac3d150f3206 +size 15430 diff --git a/doc/_static/IO/DGS_How_To_Export.png b/doc/_static/IO/DGS_How_To_Export.png deleted file mode 100644 index 4eb72622..00000000 --- a/doc/_static/IO/DGS_How_To_Export.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:b3cec19c51c9a0fa0d5f8eff09c969daae5e018c97ac999152357781175f9a8f -size 38218 diff --git a/doc/_static/IO/DGS_How_To_Export.webp b/doc/_static/IO/DGS_How_To_Export.webp new file mode 100644 index 00000000..de2df364 --- /dev/null +++ b/doc/_static/IO/DGS_How_To_Export.webp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:8f01c9ff695e88f25d61eba20b370a6060675ab2ff8446101304f62f3982f4bc +size 20620 diff --git a/doc/_static/IO/DGS_Line_Basic_Data.png b/doc/_static/IO/DGS_Line_Basic_Data.png deleted file mode 100644 index be7bc7bb..00000000 --- a/doc/_static/IO/DGS_Line_Basic_Data.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:e3bf4c98e15bbf8ee9163eb5d129220523e76669368fcc1f4d5c5604e7283fe1 -size 42332 diff --git a/doc/_static/IO/DGS_Line_Basic_Data.webp b/doc/_static/IO/DGS_Line_Basic_Data.webp new file mode 100644 index 00000000..457190c2 --- /dev/null +++ b/doc/_static/IO/DGS_Line_Basic_Data.webp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:32a28dbffdf2e80eb30987e9540ae644bc7f726390c7523de2cb34be595301d1 +size 29450 diff --git a/doc/_static/IO/DGS_Line_Load_Flow.png b/doc/_static/IO/DGS_Line_Load_Flow.png deleted file mode 100644 index 552b372e..00000000 --- a/doc/_static/IO/DGS_Line_Load_Flow.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:5499518321f6386729327b0b1cf56c3f980b227b1f3c6e920223ba750d640aae -size 39237 diff --git a/doc/_static/IO/DGS_Line_Load_Flow.webp b/doc/_static/IO/DGS_Line_Load_Flow.webp new file mode 100644 index 00000000..929f94c1 --- /dev/null +++ b/doc/_static/IO/DGS_Line_Load_Flow.webp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b6d691e60d6363ccd0175e9e1c11caf272b268a275be0022b6e15011e2e7b633 +size 25236 diff --git a/doc/_static/IO/DGS_Two_Winding_Three_Phase_Transformer_Basic_Data.png b/doc/_static/IO/DGS_Two_Winding_Three_Phase_Transformer_Basic_Data.png deleted file mode 100644 index 1b2335e0..00000000 --- a/doc/_static/IO/DGS_Two_Winding_Three_Phase_Transformer_Basic_Data.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:26f3c81a7e229499f09d37b744d5fc569fbe203f3e431a9ac155e8785aa3af46 -size 47452 diff --git a/doc/_static/IO/DGS_Two_Winding_Three_Phase_Transformer_Basic_Data.webp b/doc/_static/IO/DGS_Two_Winding_Three_Phase_Transformer_Basic_Data.webp new file mode 100644 index 00000000..ff48f661 --- /dev/null +++ b/doc/_static/IO/DGS_Two_Winding_Three_Phase_Transformer_Basic_Data.webp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:4f761f7be9356db343916bba7d2933b3166a2b2f43e75f3578374d9309ae5aa8 +size 29680 diff --git a/doc/_static/IO/DGS_Two_Winding_Three_Phase_Transformer_Load_Flow.png b/doc/_static/IO/DGS_Two_Winding_Three_Phase_Transformer_Load_Flow.png deleted file mode 100644 index 8ddbf2e7..00000000 --- a/doc/_static/IO/DGS_Two_Winding_Three_Phase_Transformer_Load_Flow.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:9043d604f43465e48af45a9113896bc749addf8b23665d8a9dec307f7190a39f -size 38999 diff --git a/doc/_static/IO/DGS_Two_Winding_Three_Phase_Transformer_Load_Flow.webp b/doc/_static/IO/DGS_Two_Winding_Three_Phase_Transformer_Load_Flow.webp new file mode 100644 index 00000000..cafe260d --- /dev/null +++ b/doc/_static/IO/DGS_Two_Winding_Three_Phase_Transformer_Load_Flow.webp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:74df90e62cc3c3ac0825b67561423e896d7e2394852537f0573631cb3e8a2b12 +size 24098 diff --git a/doc/_static/Line/American_Shunt_Line.svg b/doc/_static/Line/American_Shunt_Line.svg index f1928def..4acd9665 100644 --- a/doc/_static/Line/American_Shunt_Line.svg +++ b/doc/_static/Line/American_Shunt_Line.svg @@ -1 +1 @@ - + diff --git a/doc/_static/Line/American_Simplified_Line.svg b/doc/_static/Line/American_Simplified_Line.svg index debb628b..01863287 100644 --- a/doc/_static/Line/American_Simplified_Line.svg +++ b/doc/_static/Line/American_Simplified_Line.svg @@ -1 +1 @@ - + diff --git a/doc/_static/Line/European_Shunt_Line.svg b/doc/_static/Line/European_Shunt_Line.svg index 856168d7..9dc001f1 100644 --- a/doc/_static/Line/European_Shunt_Line.svg +++ b/doc/_static/Line/European_Shunt_Line.svg @@ -1 +1 @@ - + diff --git a/doc/_static/Line/European_Simplified_Line.svg b/doc/_static/Line/European_Simplified_Line.svg index f82b4ee8..f45128f0 100644 --- a/doc/_static/Line/European_Simplified_Line.svg +++ b/doc/_static/Line/European_Simplified_Line.svg @@ -1 +1 @@ - + diff --git a/doc/_static/Line/Image_Method_Circle.svg b/doc/_static/Line/Image_Method_Circle.svg index 6418d25c..1d64ae38 100644 --- a/doc/_static/Line/Image_Method_Circle.svg +++ b/doc/_static/Line/Image_Method_Circle.svg @@ -1 +1 @@ - + diff --git a/doc/_static/Line/Image_Method_Plane.svg b/doc/_static/Line/Image_Method_Plane.svg index 1b0ee8c4..3bdf9b61 100644 --- a/doc/_static/Line/Image_Method_Plane.svg +++ b/doc/_static/Line/Image_Method_Plane.svg @@ -1 +1 @@ - + diff --git a/doc/_static/Line/References/NF C 33-209 Network aerial bundled conductors 3-phases + neutral messenger 54.6 mm2.pdf b/doc/_static/Line/References/NF C 33-209 Network aerial bundled conductors 3-phases + neutral messenger 54.6 mm2.pdf new file mode 100644 index 00000000..3cd395f6 Binary files /dev/null and b/doc/_static/Line/References/NF C 33-209 Network aerial bundled conductors 3-phases + neutral messenger 54.6 mm2.pdf differ diff --git a/doc/_static/Line/References/NF C 33-209 Torsades de reseau 3 phases + neutre-porteur 70 mm2.pdf b/doc/_static/Line/References/NF C 33-209 Torsades de reseau 3 phases + neutre-porteur 70 mm2.pdf new file mode 100644 index 00000000..e60ee458 Binary files /dev/null and b/doc/_static/Line/References/NF C 33-209 Torsades de reseau 3 phases + neutre-porteur 70 mm2.pdf differ diff --git a/doc/_static/Line/References/NF C 33-209 Torsades de reseau 3 phases + neutre-porteur.pdf b/doc/_static/Line/References/NF C 33-209 Torsades de reseau 3 phases + neutre-porteur.pdf new file mode 100644 index 00000000..6b18b836 Binary files /dev/null and b/doc/_static/Line/References/NF C 33-209 Torsades de reseau 3 phases + neutre-porteur.pdf differ diff --git a/doc/_static/Line/References/NF C 33-210 Standard or antitermite cables.pdf b/doc/_static/Line/References/NF C 33-210 Standard or antitermite cables.pdf new file mode 100644 index 00000000..fabcb329 Binary files /dev/null and b/doc/_static/Line/References/NF C 33-210 Standard or antitermite cables.pdf differ diff --git a/doc/_static/Line/References/NF-C-33-209.png b/doc/_static/Line/References/NF-C-33-209.png new file mode 100644 index 00000000..b442bcb3 --- /dev/null +++ b/doc/_static/Line/References/NF-C-33-209.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:6001af4d5e9e03cb91477069fd5e3776a86a0f0d089d76c0395800f92caee0b7 +size 124544 diff --git a/doc/_static/Line/References/NF-C-33-210.png b/doc/_static/Line/References/NF-C-33-210.png new file mode 100644 index 00000000..e5dc5d45 --- /dev/null +++ b/doc/_static/Line/References/NF-C-33-210.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:cdbf0c51c2ec6701818498db34005749bc3d539e53854d9760ecd6ed2eb52050 +size 246239 diff --git a/doc/_static/Line/References/NF-C-33-210_ampacity.png b/doc/_static/Line/References/NF-C-33-210_ampacity.png new file mode 100644 index 00000000..b95b2598 --- /dev/null +++ b/doc/_static/Line/References/NF-C-33-210_ampacity.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:c8adab200d959743caced97ee4b433ef7b5a2df03f90093564b1192d22cb795e +size 135104 diff --git a/doc/_static/Line/Twisted_Geometry.svg b/doc/_static/Line/Twisted_Geometry.svg index c9272c87..ddd512b6 100644 --- a/doc/_static/Line/Twisted_Geometry.svg +++ b/doc/_static/Line/Twisted_Geometry.svg @@ -1 +1 @@ - + diff --git a/doc/_static/Line/Twisted_Geometry_Details.svg b/doc/_static/Line/Twisted_Geometry_Details.svg index 2403780b..9580e21c 100644 --- a/doc/_static/Line/Twisted_Geometry_Details.svg +++ b/doc/_static/Line/Twisted_Geometry_Details.svg @@ -1 +1 @@ - + diff --git a/doc/_static/Line/Underground_Geometry.svg b/doc/_static/Line/Underground_Geometry.svg index 1491662a..eeb6abc8 100644 --- a/doc/_static/Line/Underground_Geometry.svg +++ b/doc/_static/Line/Underground_Geometry.svg @@ -1 +1 @@ - + diff --git a/doc/_static/Line/Underground_Geometry_Details.svg b/doc/_static/Line/Underground_Geometry_Details.svg index 577653fc..3b5090df 100644 --- a/doc/_static/Line/Underground_Geometry_Details.svg +++ b/doc/_static/Line/Underground_Geometry_Details.svg @@ -1 +1 @@ - + diff --git a/doc/_static/Load/American_Delta_Load.svg b/doc/_static/Load/American_Delta_Load.svg index 40a7cce5..e734cb92 100644 --- a/doc/_static/Load/American_Delta_Load.svg +++ b/doc/_static/Load/American_Delta_Load.svg @@ -1 +1 @@ - + diff --git a/doc/_static/Load/American_Star_Load.svg b/doc/_static/Load/American_Star_Load.svg index 3a682808..118c6110 100644 --- a/doc/_static/Load/American_Star_Load.svg +++ b/doc/_static/Load/American_Star_Load.svg @@ -1 +1 @@ - + diff --git a/doc/_static/Load/European_Delta_Load.svg b/doc/_static/Load/European_Delta_Load.svg index d32a93c4..e6845053 100644 --- a/doc/_static/Load/European_Delta_Load.svg +++ b/doc/_static/Load/European_Delta_Load.svg @@ -1 +1 @@ - + diff --git a/doc/_static/Load/European_Star_Load.svg b/doc/_static/Load/European_Star_Load.svg index 424bab8f..179deeda 100644 --- a/doc/_static/Load/European_Star_Load.svg +++ b/doc/_static/Load/European_Star_Load.svg @@ -1 +1 @@ - + diff --git a/doc/_static/Load/FlexibleLoad/Constant_P_Projection.svg b/doc/_static/Load/FlexibleLoad/Constant_P_Projection.svg index a094f3f4..2deabbd9 100644 --- a/doc/_static/Load/FlexibleLoad/Constant_P_Projection.svg +++ b/doc/_static/Load/FlexibleLoad/Constant_P_Projection.svg @@ -1 +1 @@ - + diff --git a/doc/_static/Load/FlexibleLoad/Constant_Q_Projection.svg b/doc/_static/Load/FlexibleLoad/Constant_Q_Projection.svg index e1bd73f8..d4722cad 100644 --- a/doc/_static/Load/FlexibleLoad/Constant_Q_Projection.svg +++ b/doc/_static/Load/FlexibleLoad/Constant_Q_Projection.svg @@ -1 +1 @@ - + diff --git a/doc/_static/Load/FlexibleLoad/Control_PU_Cons.svg b/doc/_static/Load/FlexibleLoad/Control_PU_Cons.svg index 4100f481..a062dc12 100644 --- a/doc/_static/Load/FlexibleLoad/Control_PU_Cons.svg +++ b/doc/_static/Load/FlexibleLoad/Control_PU_Cons.svg @@ -1 +1 @@ - + diff --git a/doc/_static/Load/FlexibleLoad/Control_PU_Prod.svg b/doc/_static/Load/FlexibleLoad/Control_PU_Prod.svg index 72d378f4..9385b521 100644 --- a/doc/_static/Load/FlexibleLoad/Control_PU_Prod.svg +++ b/doc/_static/Load/FlexibleLoad/Control_PU_Prod.svg @@ -1 +1 @@ - + diff --git a/doc/_static/Load/FlexibleLoad/Control_QU.svg b/doc/_static/Load/FlexibleLoad/Control_QU.svg index 52007490..e79bff1c 100644 --- a/doc/_static/Load/FlexibleLoad/Control_QU.svg +++ b/doc/_static/Load/FlexibleLoad/Control_QU.svg @@ -1 +1 @@ - + diff --git a/doc/_static/Load/FlexibleLoad/Domain_Pconst_QU_Eucl.svg b/doc/_static/Load/FlexibleLoad/Domain_Pconst_QU_Eucl.svg index 6ef97b5c..425d2736 100644 --- a/doc/_static/Load/FlexibleLoad/Domain_Pconst_QU_Eucl.svg +++ b/doc/_static/Load/FlexibleLoad/Domain_Pconst_QU_Eucl.svg @@ -1 +1 @@ - + diff --git a/doc/_static/Load/FlexibleLoad/Domain_Pconst_QU_P.svg b/doc/_static/Load/FlexibleLoad/Domain_Pconst_QU_P.svg index ce6a44ab..41465565 100644 --- a/doc/_static/Load/FlexibleLoad/Domain_Pconst_QU_P.svg +++ b/doc/_static/Load/FlexibleLoad/Domain_Pconst_QU_P.svg @@ -1 +1 @@ - + diff --git a/doc/_static/Load/FlexibleLoad/Domain_Pconst_QU_Q.svg b/doc/_static/Load/FlexibleLoad/Domain_Pconst_QU_Q.svg index 29b79bf2..6ac139e7 100644 --- a/doc/_static/Load/FlexibleLoad/Domain_Pconst_QU_Q.svg +++ b/doc/_static/Load/FlexibleLoad/Domain_Pconst_QU_Q.svg @@ -1 +1 @@ - + diff --git a/doc/_static/Load/FlexibleLoad/Domain_Pconst_QU_Qmin_Qmax.svg b/doc/_static/Load/FlexibleLoad/Domain_Pconst_QU_Qmin_Qmax.svg index 6ff2fa8f..ee0c69cd 100644 --- a/doc/_static/Load/FlexibleLoad/Domain_Pconst_QU_Qmin_Qmax.svg +++ b/doc/_static/Load/FlexibleLoad/Domain_Pconst_QU_Qmin_Qmax.svg @@ -1 +1 @@ - + diff --git a/doc/_static/Load/FlexibleLoad/Domain_Pconst_Qconst.svg b/doc/_static/Load/FlexibleLoad/Domain_Pconst_Qconst.svg index b22a81fd..12d53bc6 100644 --- a/doc/_static/Load/FlexibleLoad/Domain_Pconst_Qconst.svg +++ b/doc/_static/Load/FlexibleLoad/Domain_Pconst_Qconst.svg @@ -1 +1 @@ - + diff --git a/doc/_static/Load/FlexibleLoad/Domain_PmaxU_QU.svg b/doc/_static/Load/FlexibleLoad/Domain_PmaxU_QU.svg index d2a1051b..1dc2f807 100644 --- a/doc/_static/Load/FlexibleLoad/Domain_PmaxU_QU.svg +++ b/doc/_static/Load/FlexibleLoad/Domain_PmaxU_QU.svg @@ -1 +1 @@ - + diff --git a/doc/_static/Load/FlexibleLoad/Domain_PmaxU_Qconst.svg b/doc/_static/Load/FlexibleLoad/Domain_PmaxU_Qconst.svg index 499ca3bf..2f5dc0a5 100644 --- a/doc/_static/Load/FlexibleLoad/Domain_PmaxU_Qconst.svg +++ b/doc/_static/Load/FlexibleLoad/Domain_PmaxU_Qconst.svg @@ -1 +1 @@ - + diff --git a/doc/_static/Load/FlexibleLoad/Euclidean_Projection.svg b/doc/_static/Load/FlexibleLoad/Euclidean_Projection.svg index db253dd5..24141142 100644 --- a/doc/_static/Load/FlexibleLoad/Euclidean_Projection.svg +++ b/doc/_static/Load/FlexibleLoad/Euclidean_Projection.svg @@ -1 +1 @@ - + diff --git a/doc/_static/Load/FlexibleLoad/Pconst_QU_Eucl_Control_Curve_Example.svg b/doc/_static/Load/FlexibleLoad/Pconst_QU_Eucl_Control_Curve_Example.svg index 6fe91f69..53628429 100644 --- a/doc/_static/Load/FlexibleLoad/Pconst_QU_Eucl_Control_Curve_Example.svg +++ b/doc/_static/Load/FlexibleLoad/Pconst_QU_Eucl_Control_Curve_Example.svg @@ -1 +1 @@ - + diff --git a/doc/_static/Load/FlexibleLoad/Pconst_QU_Eucl_Trajectory_Example.svg b/doc/_static/Load/FlexibleLoad/Pconst_QU_Eucl_Trajectory_Example.svg index f701d1de..a9d54d98 100644 --- a/doc/_static/Load/FlexibleLoad/Pconst_QU_Eucl_Trajectory_Example.svg +++ b/doc/_static/Load/FlexibleLoad/Pconst_QU_Eucl_Trajectory_Example.svg @@ -1 +1 @@ - + diff --git a/doc/_static/Load/FlexibleLoad/Pconst_QU_P_Control_Curve_Example.svg b/doc/_static/Load/FlexibleLoad/Pconst_QU_P_Control_Curve_Example.svg index 583d6887..41455b37 100644 --- a/doc/_static/Load/FlexibleLoad/Pconst_QU_P_Control_Curve_Example.svg +++ b/doc/_static/Load/FlexibleLoad/Pconst_QU_P_Control_Curve_Example.svg @@ -1 +1 @@ - + diff --git a/doc/_static/Load/FlexibleLoad/Pconst_QU_P_Trajectory_Example.svg b/doc/_static/Load/FlexibleLoad/Pconst_QU_P_Trajectory_Example.svg index 275643bb..9ce3be98 100644 --- a/doc/_static/Load/FlexibleLoad/Pconst_QU_P_Trajectory_Example.svg +++ b/doc/_static/Load/FlexibleLoad/Pconst_QU_P_Trajectory_Example.svg @@ -1 +1 @@ - + diff --git a/doc/_static/Load/FlexibleLoad/Pconst_QU_Q_Control_Curve_Example.svg b/doc/_static/Load/FlexibleLoad/Pconst_QU_Q_Control_Curve_Example.svg index 85d838d7..a8ec6a46 100644 --- a/doc/_static/Load/FlexibleLoad/Pconst_QU_Q_Control_Curve_Example.svg +++ b/doc/_static/Load/FlexibleLoad/Pconst_QU_Q_Control_Curve_Example.svg @@ -1 +1 @@ - + diff --git a/doc/_static/Load/FlexibleLoad/Pconst_QU_Q_Trajectory_Example.svg b/doc/_static/Load/FlexibleLoad/Pconst_QU_Q_Trajectory_Example.svg index 8c3587d4..8b6af3a5 100644 --- a/doc/_static/Load/FlexibleLoad/Pconst_QU_Q_Trajectory_Example.svg +++ b/doc/_static/Load/FlexibleLoad/Pconst_QU_Q_Trajectory_Example.svg @@ -1 +1 @@ - + diff --git a/doc/_static/Load/FlexibleLoad/Pconst_QU_Qmin_Qmax_Control_Curve_Example.svg b/doc/_static/Load/FlexibleLoad/Pconst_QU_Qmin_Qmax_Control_Curve_Example.svg index 21040376..e528d51b 100644 --- a/doc/_static/Load/FlexibleLoad/Pconst_QU_Qmin_Qmax_Control_Curve_Example.svg +++ b/doc/_static/Load/FlexibleLoad/Pconst_QU_Qmin_Qmax_Control_Curve_Example.svg @@ -1 +1 @@ - + diff --git a/doc/_static/Load/FlexibleLoad/Pconst_QU_Qmin_Qmax_Trajectory_Example.svg b/doc/_static/Load/FlexibleLoad/Pconst_QU_Qmin_Qmax_Trajectory_Example.svg index e7dda17e..f9f40651 100644 --- a/doc/_static/Load/FlexibleLoad/Pconst_QU_Qmin_Qmax_Trajectory_Example.svg +++ b/doc/_static/Load/FlexibleLoad/Pconst_QU_Qmin_Qmax_Trajectory_Example.svg @@ -1 +1 @@ - + diff --git a/doc/_static/Load/FlexibleLoad/PmaxU_QU_Sequential_1_Trajectory_Example.svg b/doc/_static/Load/FlexibleLoad/PmaxU_QU_Sequential_1_Trajectory_Example.svg index 3ef38744..c48e850a 100644 --- a/doc/_static/Load/FlexibleLoad/PmaxU_QU_Sequential_1_Trajectory_Example.svg +++ b/doc/_static/Load/FlexibleLoad/PmaxU_QU_Sequential_1_Trajectory_Example.svg @@ -1 +1 @@ - + diff --git a/doc/_static/Load/FlexibleLoad/PmaxU_QU_Sequential_2_Trajectory_Example.svg b/doc/_static/Load/FlexibleLoad/PmaxU_QU_Sequential_2_Trajectory_Example.svg index 0fb5ffc9..ea6513a7 100644 --- a/doc/_static/Load/FlexibleLoad/PmaxU_QU_Sequential_2_Trajectory_Example.svg +++ b/doc/_static/Load/FlexibleLoad/PmaxU_QU_Sequential_2_Trajectory_Example.svg @@ -1 +1 @@ - + diff --git a/doc/_static/Load/FlexibleLoad/PmaxU_QU_Simultaneous_2_Trajectory_Example.svg b/doc/_static/Load/FlexibleLoad/PmaxU_QU_Simultaneous_2_Trajectory_Example.svg index 91fd76e0..f5a190f0 100644 --- a/doc/_static/Load/FlexibleLoad/PmaxU_QU_Simultaneous_2_Trajectory_Example.svg +++ b/doc/_static/Load/FlexibleLoad/PmaxU_QU_Simultaneous_2_Trajectory_Example.svg @@ -1 +1 @@ - + diff --git a/doc/_static/Load/FlexibleLoad/PmaxU_QU_Simultaneous_Trajectory_Example.svg b/doc/_static/Load/FlexibleLoad/PmaxU_QU_Simultaneous_Trajectory_Example.svg index d1881102..bf24400b 100644 --- a/doc/_static/Load/FlexibleLoad/PmaxU_QU_Simultaneous_Trajectory_Example.svg +++ b/doc/_static/Load/FlexibleLoad/PmaxU_QU_Simultaneous_Trajectory_Example.svg @@ -1 +1 @@ - + diff --git a/doc/_static/Load/FlexibleLoad/PmaxU_Qconst_Control_Curve_Example.svg b/doc/_static/Load/FlexibleLoad/PmaxU_Qconst_Control_Curve_Example.svg index f2b06f98..3a751c18 100644 --- a/doc/_static/Load/FlexibleLoad/PmaxU_Qconst_Control_Curve_Example.svg +++ b/doc/_static/Load/FlexibleLoad/PmaxU_Qconst_Control_Curve_Example.svg @@ -1 +1 @@ - + diff --git a/doc/_static/Load/FlexibleLoad/PmaxU_Qconst_Trajectory_Example.svg b/doc/_static/Load/FlexibleLoad/PmaxU_Qconst_Trajectory_Example.svg index 6cd6f5fc..533117f9 100644 --- a/doc/_static/Load/FlexibleLoad/PmaxU_Qconst_Trajectory_Example.svg +++ b/doc/_static/Load/FlexibleLoad/PmaxU_Qconst_Trajectory_Example.svg @@ -1 +1 @@ - + diff --git a/doc/_static/Network/Catalogue.html b/doc/_static/Network/Catalogue.html index 92e73130..663a2fce 100644 --- a/doc/_static/Network/Catalogue.html +++ b/doc/_static/Network/Catalogue.html @@ -1,45966 +1,1741 @@ - - - - - - - +Available networks
+ ${handleObject(layer.feature.properties[v]).toLocaleString()} + `).join(``))+``,div},{maxWidth:800,sticky:!1,className:`foliumtooltip`}),geo_json_17955351ec79b7fc71d8b3c014bb9b57.bindPopup(function(layer){let div=L.DomUtil.create(`div`),handleObject=feature=>feature===null?``:typeof feature==`object`?JSON.stringify(feature):feature,fields=[`network`,`id`,`phases`,`nominal_voltage`,`min_voltage_level`,`max_voltage_level`],aliases=[`Network: `,`Id:`,`Phases:`,`Un (V):`,`Umin (%):`,`Umax (%):`];return div.innerHTML=``+String(fields.map((v,i)=>` + + + + `).join(``))+`
${aliases[i].toLocaleString()}${handleObject(layer.feature.properties[v]).toLocaleString()}
`,div},{className:`foliumpopup`}),geo_json_17955351ec79b7fc71d8b3c014bb9b57.addTo(feature_group_3f19c85fb4db6bdc6be1e3299d4464e9);function geo_json_e40c8f6088d6ba014632e0b246e82ad0_styler(feature){switch(feature.id){case`0`:case`1`:case`19`:case`20`:case`21`:case`22`:case`24`:case`25`:case`26`:case`27`:case`28`:case`29`:case`30`:case`36`:case`38`:case`53`:case`54`:case`55`:case`57`:case`58`:case`59`:case`60`:case`64`:case`65`:case`66`:case`67`:case`69`:case`74`:case`76`:case`77`:case`78`:case`85`:case`87`:case`88`:case`91`:case`92`:case`101`:case`102`:case`103`:case`104`:case`105`:case`106`:case`107`:case`108`:case`109`:case`110`:case`111`:case`112`:case`113`:case`114`:case`118`:case`119`:case`120`:case`121`:case`122`:case`123`:case`124`:case`125`:return{color:`#234e83`,dashArray:`5, 5`,weight:3};default:return{color:`#234e83`,dashArray:null,weight:3}}}function geo_json_e40c8f6088d6ba014632e0b246e82ad0_highlighter(feature){switch(feature.id){default:return{color:`#cad40e`}}}function geo_json_e40c8f6088d6ba014632e0b246e82ad0_onEachFeature(feature,layer){layer.on({mouseout:function(e){typeof e.target.setStyle==`function`&&geo_json_e40c8f6088d6ba014632e0b246e82ad0.resetStyle(e.target)},mouseover:function(e){if(typeof e.target.setStyle==`function`){let highlightStyle=geo_json_e40c8f6088d6ba014632e0b246e82ad0_highlighter(e.target.feature);e.target.setStyle(highlightStyle)}}})}var geo_json_e40c8f6088d6ba014632e0b246e82ad0=L.geoJson(null,{onEachFeature:geo_json_e40c8f6088d6ba014632e0b246e82ad0_onEachFeature,style:geo_json_e40c8f6088d6ba014632e0b246e82ad0_styler});function geo_json_e40c8f6088d6ba014632e0b246e82ad0_add(data){geo_json_e40c8f6088d6ba014632e0b246e82ad0.addData(data)}geo_json_e40c8f6088d6ba014632e0b246e82ad0_add({bbox:[-1.471709586496959,48.66494015250545,-1.315198632188688,48.70845136474554],features:[{bbox:[-1.3243096308857334,48.67552963511552,-1.315198632188688,48.677222514427754],geometry:{coordinates:[[-1.315508137717839,48.67552963511552],[-1.315503463460778,48.675545112303986],[-1.315503463460778,48.675545112303986],[-1.315500848189535,48.675556242851165],[-1.315198632188688,48.67596371052023],[-1.317871088132522,48.67581209610027],[-1.318670051393893,48.67576675473115],[-1.31964092142359,48.67575020213779],[-1.320984238145868,48.67572728247795],[-1.323541968796889,48.675683594843576],[-1.323852907070429,48.67567706472819],[-1.324195198699835,48.675669862746695],[-1.324284678894714,48.6757184090606],[-1.32427595282035,48.67581334177527],[-1.324208562736317,48.67602188193846],[-1.324198289130883,48.67612822738935],[-1.324179048878627,48.676327443285246],[-1.324177927879868,48.67653988530394],[-1.324248646680606,48.67691893742712],[-1.324288793975336,48.6771142230753],[-1.324305348212575,48.67719477859688],[-1.324306673367868,48.677208199294995],[-1.3243096308857334,48.677222514427754]],type:`LineString`},id:`0`,properties:{ampacity:325,approximate_nominal_voltage:2e4,bus1_id:`HVMVFeeder14`,bus2_id:`MVLV06299`,element_type:`line`,id:`MVBranch39944`,insulator:null,length:.8907821128978984,line_type:`underground`,material:`aac`,max_loading:100,network:`MV Feeder 210`,parameters_id:`U_AL_150`,phases:`abc`,section:150},type:`Feature`},{bbox:[-1.360816212595922,48.70030435899507,-1.359583849886216,48.701166484045686],geometry:{coordinates:[[-1.360816212595922,48.70113087837448],[-1.360816212595922,48.70113087837448],[-1.360722700562462,48.701166484045686],[-1.360614861951732,48.701021506245404],[-1.360437527815529,48.700889501225184],[-1.360278885836657,48.7008039301189],[-1.359583849886216,48.700391396539366],[-1.359690288894828,48.70030435899507],[-1.359690288894828,48.70030435899507]],type:`LineString`},id:`1`,properties:{ampacity:325,approximate_nominal_voltage:2e4,bus1_id:`MVBus17524`,bus2_id:`MVLV12961`,element_type:`line`,id:`MVBranch36942`,insulator:null,length:.14178813460374382,line_type:`underground`,material:`aac`,max_loading:100,network:`MV Feeder 210`,parameters_id:`U_AL_150`,phases:`abc`,section:150},type:`Feature`},{bbox:[-1.36250058294375,48.699920974017196,-1.360816212595922,48.70113087837448],geometry:{coordinates:[[-1.36250058294375,48.699920974017196],[-1.36250058294375,48.699920974017196],[-1.3617748995242,48.70059026302006],[-1.360816212595922,48.70113087837448],[-1.360816212595922,48.70113087837448]],type:`LineString`},id:`2`,properties:{ampacity:193,approximate_nominal_voltage:2e4,bus1_id:`MVBus17523`,bus2_id:`MVBus17524`,element_type:`line`,id:`MVBranch24943`,insulator:null,length:.1843169641640161,line_type:`overhead`,material:`aaac`,max_loading:100,network:`MV Feeder 210`,parameters_id:`O_AM_54`,phases:`abc`,section:54},type:`Feature`},{bbox:[-1.363787332955464,48.70687745644073,-1.362017012011286,48.707740359055315],geometry:{coordinates:[[-1.363787332955464,48.70687745644073],[-1.363787332955464,48.70687745644073],[-1.362017012011286,48.707740359055315],[-1.362017012011286,48.707740359055315]],type:`LineString`},id:`3`,properties:{ampacity:193,approximate_nominal_voltage:2e4,bus1_id:`MVBus17533`,bus2_id:`MVLV08691`,element_type:`line`,id:`MVBranch30656`,insulator:null,length:.16181702009734078,line_type:`overhead`,material:`aaac`,max_loading:100,network:`MV Feeder 210`,parameters_id:`O_AM_54`,phases:`abc`,section:54},type:`Feature`},{bbox:[-1.372474957363736,48.708006097671856,-1.371470530798074,48.70819963640383],geometry:{coordinates:[[-1.371470530798074,48.708006097671856],[-1.371470530798074,48.708006097671856],[-1.372474957363736,48.70819963640383],[-1.372474957363736,48.70819963640383]],type:`LineString`},id:`4`,properties:{ampacity:193,approximate_nominal_voltage:2e4,bus1_id:`MVBus17536`,bus2_id:`MVLV05594`,element_type:`line`,id:`MVBranch24945`,insulator:null,length:.07699349789243165,line_type:`overhead`,material:`aaac`,max_loading:100,network:`MV Feeder 210`,parameters_id:`O_AM_54`,phases:`abc`,section:54},type:`Feature`},{bbox:[-1.372263248440009,48.70572814874992,-1.371470530798074,48.708006097671856],geometry:{coordinates:[[-1.371470530798074,48.708006097671856],[-1.371470530798074,48.708006097671856],[-1.372263248440009,48.70572814874992],[-1.372263248440009,48.70572814874992]],type:`LineString`},id:`5`,properties:{ampacity:193,approximate_nominal_voltage:2e4,bus1_id:`MVBus17536`,bus2_id:`MVLV15838`,element_type:`line`,id:`MVBranch22299`,insulator:null,length:.25994927894914815,line_type:`overhead`,material:`aaac`,max_loading:100,network:`MV Feeder 210`,parameters_id:`O_AM_54`,phases:`abc`,section:54},type:`Feature`},{bbox:[-1.371470530798074,48.70773714942973,-1.365482557431456,48.70845136474554],geometry:{coordinates:[[-1.365482557431456,48.70845136474554],[-1.365482557431456,48.70845136474554],[-1.370137877277229,48.70773714942973],[-1.371470530798074,48.708006097671856],[-1.371470530798074,48.708006097671856]],type:`LineString`},id:`6`,properties:{ampacity:193,approximate_nominal_voltage:2e4,bus1_id:`MVBus17535`,bus2_id:`MVBus17536`,element_type:`line`,id:`MVBranch12787`,insulator:null,length:.4542496808028074,line_type:`overhead`,material:`aaac`,max_loading:100,network:`MV Feeder 210`,parameters_id:`O_AM_54`,phases:`abc`,section:54},type:`Feature`},{bbox:[-1.365482557431456,48.70687745644073,-1.363787332955464,48.70845136474554],geometry:{coordinates:[[-1.363787332955464,48.70687745644073],[-1.363787332955464,48.70687745644073],[-1.365482557431456,48.70845136474554],[-1.365482557431456,48.70845136474554]],type:`LineString`},id:`7`,properties:{ampacity:193,approximate_nominal_voltage:2e4,bus1_id:`MVBus17533`,bus2_id:`MVBus17535`,element_type:`line`,id:`MVBranch02961`,insulator:null,length:.21494311509699743,line_type:`overhead`,material:`aaac`,max_loading:100,network:`MV Feeder 210`,parameters_id:`O_AM_54`,phases:`abc`,section:54},type:`Feature`},{bbox:[-1.363787332955464,48.70493345667249,-1.361706222495278,48.70687745644073],geometry:{coordinates:[[-1.361706222495278,48.70493345667249],[-1.361706222495278,48.70493345667249],[-1.363787332955464,48.70687745644073],[-1.363787332955464,48.70687745644073]],type:`LineString`},id:`8`,properties:{ampacity:193,approximate_nominal_voltage:2e4,bus1_id:`MVBus17532`,bus2_id:`MVBus17533`,element_type:`line`,id:`MVBranch30654`,insulator:null,length:.26494540274416534,line_type:`overhead`,material:`aaac`,max_loading:100,network:`MV Feeder 210`,parameters_id:`O_AM_54`,phases:`abc`,section:54},type:`Feature`},{bbox:[-1.362654078028266,48.70439394941558,-1.361706222495278,48.70493345667249],geometry:{coordinates:[[-1.362654078028266,48.70439394941558],[-1.362654078028266,48.70439394941558],[-1.361706222495278,48.70493345667249],[-1.361706222495278,48.70493345667249]],type:`LineString`},id:`9`,properties:{ampacity:193,approximate_nominal_voltage:2e4,bus1_id:`MVBus17530`,bus2_id:`MVBus17532`,element_type:`line`,id:`MVBranch22297`,insulator:null,length:.09201445378229363,line_type:`overhead`,material:`aaac`,max_loading:100,network:`MV Feeder 210`,parameters_id:`O_AM_54`,phases:`abc`,section:54},type:`Feature`},{bbox:[-1.362654078028266,48.70373258684646,-1.361146143854642,48.70439394941558],geometry:{coordinates:[[-1.362654078028266,48.70439394941558],[-1.362654078028266,48.70439394941558],[-1.361721892311404,48.70427438531108],[-1.361146143854642,48.70373258684646],[-1.361146143854642,48.70373258684646]],type:`LineString`},id:`10`,properties:{ampacity:193,approximate_nominal_voltage:2e4,bus1_id:`MVBus17530`,bus2_id:`MVLV12960`,element_type:`line`,id:`MVBranch07873`,insulator:null,length:.1435499370827407,line_type:`overhead`,material:`aaac`,max_loading:100,network:`MV Feeder 210`,parameters_id:`O_AM_54`,phases:`abc`,section:54},type:`Feature`},{bbox:[-1.365766216776604,48.70323344674769,-1.362654078028266,48.70439394941558],geometry:{coordinates:[[-1.365766216776604,48.70323344674769],[-1.365766216776604,48.70323344674769],[-1.363833946287064,48.70377351832192],[-1.362654078028266,48.70439394941558],[-1.362654078028266,48.70439394941558]],type:`LineString`},id:`11`,properties:{ampacity:193,approximate_nominal_voltage:2e4,bus1_id:`MVBus17529`,bus2_id:`MVBus17530`,element_type:`line`,id:`MVBranch02960`,insulator:null,length:.2653000495495086,line_type:`overhead`,material:`aaac`,max_loading:100,network:`MV Feeder 210`,parameters_id:`O_AM_54`,phases:`abc`,section:54},type:`Feature`},{bbox:[-1.366857582095782,48.702909804508195,-1.365766216776604,48.70323344674769],geometry:{coordinates:[[-1.366857582095782,48.702909804508195],[-1.366857582095782,48.702909804508195],[-1.365766216776604,48.70323344674769],[-1.365766216776604,48.70323344674769]],type:`LineString`},id:`12`,properties:{ampacity:193,approximate_nominal_voltage:2e4,bus1_id:`MVBus17528`,bus2_id:`MVBus17529`,element_type:`line`,id:`MVBranch30655`,insulator:null,length:.08802463182829624,line_type:`overhead`,material:`aaac`,max_loading:100,network:`MV Feeder 210`,parameters_id:`O_AM_54`,phases:`abc`,section:54},type:`Feature`},{bbox:[-1.36985327513618,48.70171789916646,-1.369391365276649,48.702312360854734],geometry:{coordinates:[[-1.369391365276649,48.702312360854734],[-1.369391365276649,48.702312360854734],[-1.36985327513618,48.70171789916646],[-1.36985327513618,48.70171789916646]],type:`LineString`},id:`13`,properties:{ampacity:193,approximate_nominal_voltage:2e4,bus1_id:`MVBus17540`,bus2_id:`MVLV11643`,element_type:`line`,id:`MVBranch22300`,insulator:null,length:.0743375036506505,line_type:`overhead`,material:`aaac`,max_loading:100,network:`MV Feeder 210`,parameters_id:`O_AM_54`,phases:`abc`,section:54},type:`Feature`},{bbox:[-1.369391365276649,48.702312360854734,-1.368602686985163,48.702762027953426],geometry:{coordinates:[[-1.368602686985163,48.702762027953426],[-1.368602686985163,48.702762027953426],[-1.369391365276649,48.702312360854734],[-1.369391365276649,48.702312360854734]],type:`LineString`},id:`14`,properties:{ampacity:193,approximate_nominal_voltage:2e4,bus1_id:`MVBus17539`,bus2_id:`MVBus17540`,element_type:`line`,id:`MVBranch22298`,insulator:null,length:.07661917327285778,line_type:`overhead`,material:`aaac`,max_loading:100,network:`MV Feeder 210`,parameters_id:`O_AM_54`,phases:`abc`,section:54},type:`Feature`},{bbox:[-1.368602686985163,48.702762027953426,-1.366857582095782,48.702909804508195],geometry:{coordinates:[[-1.366857582095782,48.702909804508195],[-1.366857582095782,48.702909804508195],[-1.368602686985163,48.702762027953426],[-1.368602686985163,48.702762027953426]],type:`LineString`},id:`15`,properties:{ampacity:193,approximate_nominal_voltage:2e4,bus1_id:`MVBus17528`,bus2_id:`MVBus17539`,element_type:`line`,id:`MVBranch07874`,insulator:null,length:.12949731231923822,line_type:`overhead`,material:`aaac`,max_loading:100,network:`MV Feeder 210`,parameters_id:`O_AM_54`,phases:`abc`,section:54},type:`Feature`},{bbox:[-1.366857582095782,48.702909804508195,-1.365080155168652,48.702931226958164],geometry:{coordinates:[[-1.365080155168652,48.702931226958164],[-1.365080155168652,48.702931226958164],[-1.366857582095782,48.702909804508195],[-1.366857582095782,48.702909804508195]],type:`LineString`},id:`16`,properties:{ampacity:193,approximate_nominal_voltage:2e4,bus1_id:`MVBus17527`,bus2_id:`MVBus17528`,element_type:`line`,id:`MVBranch30653`,insulator:null,length:.13085094399203137,line_type:`overhead`,material:`aaac`,max_loading:100,network:`MV Feeder 210`,parameters_id:`O_AM_54`,phases:`abc`,section:54},type:`Feature`},{bbox:[-1.365080155168652,48.702221813021815,-1.364469760819947,48.702931226958164],geometry:{coordinates:[[-1.364469760819947,48.702221813021815],[-1.364469760819947,48.702221813021815],[-1.365080155168652,48.702931226958164],[-1.365080155168652,48.702931226958164]],type:`LineString`},id:`17`,properties:{ampacity:193,approximate_nominal_voltage:2e4,bus1_id:`MVBus17526`,bus2_id:`MVBus17527`,element_type:`line`,id:`MVBranch24944`,insulator:null,length:.09078650728206882,line_type:`overhead`,material:`aaac`,max_loading:100,network:`MV Feeder 210`,parameters_id:`O_AM_54`,phases:`abc`,section:54},type:`Feature`},{bbox:[-1.364469760819947,48.699920974017196,-1.36250058294375,48.702221813021815],geometry:{coordinates:[[-1.36250058294375,48.699920974017196],[-1.36250058294375,48.699920974017196],[-1.364469760819947,48.702221813021815],[-1.364469760819947,48.702221813021815]],type:`LineString`},id:`18`,properties:{ampacity:193,approximate_nominal_voltage:2e4,bus1_id:`MVBus17523`,bus2_id:`MVBus17526`,element_type:`line`,id:`MVBranch12786`,insulator:null,length:.29406741281526205,line_type:`overhead`,material:`aaac`,max_loading:100,network:`MV Feeder 210`,parameters_id:`O_AM_54`,phases:`abc`,section:54},type:`Feature`},{bbox:[-1.362568397912248,48.698372926745066,-1.361872248455002,48.699920974017196],geometry:{coordinates:[[-1.361872248455002,48.698372926745066],[-1.361872248455002,48.698372926745066],[-1.361903822228889,48.698406874351],[-1.362246996694102,48.699408941615545],[-1.362333415609004,48.699680825794466],[-1.362568397912248,48.69985650909679],[-1.362545617311338,48.69987737599273],[-1.36250058294375,48.699920974017196],[-1.36250058294375,48.699920974017196]],type:`LineString`},id:`19`,properties:{ampacity:325,approximate_nominal_voltage:2e4,bus1_id:`MVBus17515`,bus2_id:`MVBus17523`,element_type:`line`,id:`MVBranch41216`,insulator:null,length:.1844208420110156,line_type:`underground`,material:`aac`,max_loading:100,network:`MV Feeder 210`,parameters_id:`U_AL_150`,phases:`abc`,section:150},type:`Feature`},{bbox:[-1.381057295037861,48.68853566517583,-1.380593480920253,48.68951313748911],geometry:{coordinates:[[-1.380593480920253,48.68951313748911],[-1.380593480920253,48.68951313748911],[-1.380601431977655,48.689423217060465],[-1.38072919403013,48.68853566517583],[-1.380949803263799,48.68854929502677],[-1.381057295037861,48.68857227401332],[-1.381057295037861,48.68857227401332]],type:`LineString`},id:`20`,properties:{ampacity:325,approximate_nominal_voltage:2e4,bus1_id:`MVBus17518`,bus2_id:`MVLV11234`,element_type:`line`,id:`MVBranch39173`,insulator:null,length:.13379285548725914,line_type:`underground`,material:`aac`,max_loading:100,network:`MV Feeder 210`,parameters_id:`U_AL_150`,phases:`abc`,section:150},type:`Feature`},{bbox:[-1.386101834131236,48.69020544337535,-1.386086307107507,48.69024982994571],geometry:{coordinates:[[-1.386095076128499,48.69020544337535],[-1.386095076128499,48.69020544337535],[-1.386101834131236,48.690227313961685],[-1.386094764648589,48.69023810923906],[-1.386091738376708,48.69024273053422],[-1.386086307107507,48.69024982994571],[-1.386086307107507,48.69024982994571]],type:`LineString`},id:`21`,properties:{ampacity:325,approximate_nominal_voltage:2e4,bus1_id:`MVBus17519`,bus2_id:`MVLV02676`,element_type:`line`,id:`MVBranch34168`,insulator:null,length:.00523601712228864,line_type:`underground`,material:`aac`,max_loading:100,network:`MV Feeder 210`,parameters_id:`U_AL_150`,phases:`abc`,section:150},type:`Feature`},{bbox:[-1.387228378138695,48.69645566648759,-1.386320350855856,48.69681708545298],geometry:{coordinates:[[-1.387228378138695,48.69648346340322],[-1.387228378138695,48.69648346340322],[-1.387221166791382,48.69649361522939],[-1.387205265351858,48.696487392402446],[-1.387107118643517,48.69645566648759],[-1.387097484203143,48.69645685076047],[-1.387090828303885,48.6964626118196],[-1.387029614602151,48.69657625091903],[-1.386869072729956,48.69681438074435],[-1.386866615728102,48.69681708545298],[-1.386858597780683,48.69681616728629],[-1.386355132658147,48.696695396202],[-1.386347399884585,48.6966975105803],[-1.386320350855856,48.69674688889175],[-1.386320350855856,48.69674688889175]],type:`LineString`},id:`22`,properties:{ampacity:325,approximate_nominal_voltage:2e4,bus1_id:`MVBus24053`,bus2_id:`MVLV00763`,element_type:`line`,id:`MVBranch34079`,insulator:null,length:.10141843723377124,line_type:`underground`,material:`aac`,max_loading:100,network:`MV Feeder 210`,parameters_id:`U_AL_150`,phases:`abc`,section:150},type:`Feature`},{bbox:[-1.390456896571498,48.694092429012166,-1.387228378138695,48.69648346340322],geometry:{coordinates:[[-1.390456896571498,48.694092429012166],[-1.390456896571498,48.694092429012166],[-1.387379276762682,48.696449094264764],[-1.387228378138695,48.69648346340322],[-1.387228378138695,48.69648346340322]],type:`LineString`},id:`23`,properties:{ampacity:193,approximate_nominal_voltage:2e4,bus1_id:`MVBus24052`,bus2_id:`MVBus24053`,element_type:`line`,id:`MVBranch11541`,insulator:null,length:.3581761272426037,line_type:`overhead`,material:`aaac`,max_loading:100,network:`MV Feeder 210`,parameters_id:`O_AM_54`,phases:`abc`,section:54},type:`Feature`},{bbox:[-1.396689119419465,48.6779615913739,-1.393845086303829,48.68008386227141],geometry:{coordinates:[[-1.396689119419465,48.68008386227141],[-1.396689119419465,48.68008386227141],[-1.396648913020269,48.6800488988877],[-1.394611413407245,48.67796960367503],[-1.394568048039803,48.6779615913739],[-1.394163276971984,48.678118702457],[-1.393845086303829,48.678271396765766],[-1.393859245371176,48.678398121997645],[-1.393859245371176,48.678398121997645]],type:`LineString`},id:`24`,properties:{ampacity:325,approximate_nominal_voltage:2e4,bus1_id:`MVBus24062`,bus2_id:`MVLV04069`,element_type:`line`,id:`MVBranch46121`,insulator:null,length:.3614631350164427,line_type:`underground`,material:`aac`,max_loading:100,network:`MV Feeder 210`,parameters_id:`U_AL_150`,phases:`abc`,section:150},type:`Feature`},{bbox:[-1.397198756611179,48.68000258900063,-1.397175010325148,48.68002106022296],geometry:{coordinates:[[-1.397175010325148,48.680005646047306],[-1.397175010325148,48.680005646047306],[-1.397190364000473,48.68000258900063],[-1.397198756611179,48.68002106022296],[-1.397198756611179,48.68002106022296]],type:`LineString`},id:`25`,properties:{ampacity:325,approximate_nominal_voltage:2e4,bus1_id:`MVBus24064`,bus2_id:`MVLV02107`,element_type:`line`,id:`MVBranch33185`,insulator:null,length:.0033256646425244354,line_type:`underground`,material:`aac`,max_loading:100,network:`MV Feeder 210`,parameters_id:`U_AL_150`,phases:`abc`,section:150},type:`Feature`},{bbox:[-1.397175010325148,48.680005646047306,-1.396689119419465,48.68008386227141],geometry:{coordinates:[[-1.396689119419465,48.68008386227141],[-1.396689119419465,48.68008386227141],[-1.396782321176775,48.68007733774667],[-1.39687384253284,48.68005762884955],[-1.396968701387716,48.680047119542785],[-1.397175010325148,48.680005646047306],[-1.397175010325148,48.680005646047306]],type:`LineString`},id:`26`,properties:{ampacity:325,approximate_nominal_voltage:2e4,bus1_id:`MVBus24062`,bus2_id:`MVBus24064`,element_type:`line`,id:`MVBranch36644`,insulator:null,length:.0369480354900679,line_type:`underground`,material:`aac`,max_loading:100,network:`MV Feeder 210`,parameters_id:`U_AL_150`,phases:`abc`,section:150},type:`Feature`},{bbox:[-1.396689119419465,48.68008386227141,-1.396086853166442,48.68016686423779],geometry:{coordinates:[[-1.396086853166442,48.68016686423779],[-1.396086853166442,48.68016686423779],[-1.3962942121381,48.68013299922341],[-1.396488560143423,48.680102081053114],[-1.396575419622532,48.68009182387137],[-1.396689119419465,48.68008386227141],[-1.396689119419465,48.68008386227141]],type:`LineString`},id:`27`,properties:{ampacity:325,approximate_nominal_voltage:2e4,bus1_id:`MVBus24061`,bus2_id:`MVBus24062`,element_type:`line`,id:`MVBranch46471`,insulator:null,length:.045362740179136773,line_type:`underground`,material:`aac`,max_loading:100,network:`MV Feeder 210`,parameters_id:`U_AL_150`,phases:`abc`,section:150},type:`Feature`},{bbox:[-1.396086853166442,48.68016686423779,-1.391320095620501,48.68124807997599],geometry:{coordinates:[[-1.391320095620501,48.68124807997599],[-1.391320095620501,48.68124807997599],[-1.3913757704759,48.68123100504328],[-1.391452827194984,48.681200551730086],[-1.391544113131154,48.68117144180778],[-1.391578032857149,48.681158560168356],[-1.391641417684,48.681142691530205],[-1.391897231031268,48.68105881697471],[-1.392092195181681,48.68099718313847],[-1.392155718516572,48.68097169020065],[-1.392199012704665,48.68095631793636],[-1.392217767946615,48.6809516068197],[-1.392488320110357,48.680862183213534],[-1.392779260671652,48.68076771742702],[-1.392878950410615,48.68073737928427],[-1.392982213665771,48.680710636158025],[-1.393036820873943,48.68069650057501],[-1.393043528466283,48.68068316045334],[-1.393055312133606,48.680676742711626],[-1.393447343467384,48.68059026342986],[-1.393795017824657,48.6805354138882],[-1.393828374426592,48.68053988988404],[-1.394255996709342,48.68047636899161],[-1.394377170388082,48.68047255692166],[-1.395322544559519,48.68030720020886],[-1.395635422344027,48.680253989044964],[-1.395963743339719,48.680200299979205],[-1.39599587277191,48.68018351390004],[-1.396086853166442,48.68016686423779],[-1.396086853166442,48.68016686423779]],type:`LineString`},id:`28`,properties:{ampacity:325,approximate_nominal_voltage:2e4,bus1_id:`MVBus24059`,bus2_id:`MVBus24061`,element_type:`line`,id:`MVBranch35687`,insulator:null,length:.3744445791717937,line_type:`underground`,material:`aac`,max_loading:100,network:`MV Feeder 210`,parameters_id:`U_AL_150`,phases:`abc`,section:150},type:`Feature`},{bbox:[-1.391322168393567,48.68124807997599,-1.391311522906812,48.68128407741701],geometry:{coordinates:[[-1.391320095620501,48.68124807997599],[-1.391320095620501,48.68124807997599],[-1.391322168393567,48.68125291913266],[-1.391311904977682,48.68125609434967],[-1.391311522906812,48.681261190645955],[-1.391314507522578,48.68127685361685],[-1.391318871202315,48.68128407741701],[-1.391318871202315,48.68128407741701]],type:`LineString`},id:`29`,properties:{ampacity:325,approximate_nominal_voltage:2e4,bus1_id:`MVBus24059`,bus2_id:`MVLV06953`,element_type:`line`,id:`MVBranch36643`,insulator:null,length:.004581756372837862,line_type:`underground`,material:`aac`,max_loading:100,network:`MV Feeder 210`,parameters_id:`U_AL_150`,phases:`abc`,section:150},type:`Feature`},{bbox:[-1.391320095620501,48.68124807997599,-1.387263325437987,48.683362598407236],geometry:{coordinates:[[-1.387495141567356,48.683362598407236],[-1.387495141567356,48.683362598407236],[-1.387759531943309,48.683293500990985],[-1.387814024954069,48.683271074752916],[-1.387826894829556,48.683254949865876],[-1.387818960470286,48.68323790351911],[-1.387722623145225,48.683139639342485],[-1.387673180435401,48.68309690931768],[-1.387558220629858,48.683028367596606],[-1.387263325437987,48.68285935388355],[-1.387269844746174,48.68276289905099],[-1.387348437646504,48.682715311813894],[-1.387356786475741,48.68269716024084],[-1.387678417238547,48.682493012673895],[-1.387817559710464,48.682414421857445],[-1.38796727720281,48.68234478542403],[-1.388823713394605,48.682060441880395],[-1.389429594414714,48.68186397150588],[-1.389752429232078,48.681758351969066],[-1.389808653669071,48.68175272492027],[-1.390279612206967,48.68158793534494],[-1.39031602673959,48.68158293056698],[-1.390789840058094,48.681425401097336],[-1.391079557085955,48.68133008729849],[-1.391174642348653,48.681298806546174],[-1.391199538592418,48.68128573171901],[-1.391223663864039,48.68127574069037],[-1.391294163018651,48.681258829737715],[-1.391320095620501,48.68124807997599],[-1.391320095620501,48.68124807997599]],type:`LineString`},id:`30`,properties:{ampacity:325,approximate_nominal_voltage:2e4,bus1_id:`MVBus24058`,bus2_id:`MVBus24059`,element_type:`line`,id:`MVBranch34976`,insulator:null,length:.4450064142173554,line_type:`underground`,material:`aac`,max_loading:100,network:`MV Feeder 210`,parameters_id:`U_AL_150`,phases:`abc`,section:150},type:`Feature`},{bbox:[-1.387495141567356,48.68286061089437,-1.387208961037065,48.683362598407236],geometry:{coordinates:[[-1.387495141567356,48.683362598407236],[-1.387495141567356,48.683362598407236],[-1.387208961037065,48.68286061089437],[-1.387208961037065,48.68286061089437]],type:`LineString`},id:`31`,properties:{ampacity:193,approximate_nominal_voltage:2e4,bus1_id:`MVBus24058`,bus2_id:`MVLV08246`,element_type:`line`,id:`MVBranch15994`,insulator:null,length:.059667850234072076,line_type:`overhead`,material:`aaac`,max_loading:100,network:`MV Feeder 210`,parameters_id:`O_AM_54`,phases:`abc`,section:54},type:`Feature`},{bbox:[-1.388369912450079,48.683362598407236,-1.387495141567356,48.684359890565865],geometry:{coordinates:[[-1.388369912450079,48.684359890565865],[-1.388369912450079,48.684359890565865],[-1.387495141567356,48.683362598407236],[-1.387495141567356,48.683362598407236]],type:`LineString`},id:`32`,properties:{ampacity:193,approximate_nominal_voltage:2e4,bus1_id:`MVBus24057`,bus2_id:`MVBus24058`,element_type:`line`,id:`MVBranch18995`,insulator:null,length:.1282511394554021,line_type:`overhead`,material:`aaac`,max_loading:100,network:`MV Feeder 210`,parameters_id:`O_AM_54`,phases:`abc`,section:54},type:`Feature`},{bbox:[-1.389247638808418,48.684359890565865,-1.388369912450079,48.68704140487774],geometry:{coordinates:[[-1.388369912450079,48.684359890565865],[-1.388369912450079,48.684359890565865],[-1.389247638808418,48.68704140487774],[-1.389247638808418,48.68704140487774]],type:`LineString`},id:`33`,properties:{ampacity:193,approximate_nominal_voltage:2e4,bus1_id:`MVBus24057`,bus2_id:`MVLV15406`,element_type:`line`,id:`MVBranch32126`,insulator:null,length:.3051172412161234,line_type:`overhead`,material:`aaac`,max_loading:100,network:`MV Feeder 210`,parameters_id:`O_AM_54`,phases:`abc`,section:54},type:`Feature`},{bbox:[-1.389136030184977,48.68430691391075,-1.388369912450079,48.684359890565865],geometry:{coordinates:[[-1.389136030184977,48.68430691391075],[-1.389136030184977,48.68430691391075],[-1.388369912450079,48.684359890565865],[-1.388369912450079,48.684359890565865]],type:`LineString`},id:`34`,properties:{ampacity:193,approximate_nominal_voltage:2e4,bus1_id:`MVBus24056`,bus2_id:`MVBus24057`,element_type:`line`,id:`MVBranch11544`,insulator:null,length:.05671839189802176,line_type:`overhead`,material:`aaac`,max_loading:100,network:`MV Feeder 210`,parameters_id:`O_AM_54`,phases:`abc`,section:54},type:`Feature`},{bbox:[-1.398561158560935,48.68430691391075,-1.389136030184977,48.687535479227805],geometry:{coordinates:[[-1.398561158560935,48.687535479227805],[-1.398561158560935,48.687535479227805],[-1.393362724182627,48.685320816196224],[-1.389136030184977,48.68430691391075],[-1.389136030184977,48.68430691391075]],type:`LineString`},id:`35`,properties:{ampacity:193,approximate_nominal_voltage:2e4,bus1_id:`MVBus24055`,bus2_id:`MVBus24056`,element_type:`line`,id:`MVBranch23661`,insulator:null,length:.7861628831366249,line_type:`overhead`,material:`aaac`,max_loading:100,network:`MV Feeder 210`,parameters_id:`O_AM_54`,phases:`abc`,section:54},type:`Feature`},{bbox:[-1.402903063269356,48.67418637690393,-1.401395938329806,48.67482940726141],geometry:{coordinates:[[-1.402903063269356,48.67421149659865],[-1.402903063269356,48.67421149659865],[-1.402887778117972,48.67418637690393],[-1.402720340785575,48.67422309006748],[-1.402290181691711,48.674372968677645],[-1.402012558869709,48.67450738187695],[-1.401711911452538,48.67470258749458],[-1.401594889014558,48.67482389147757],[-1.401395938329806,48.67482940726141],[-1.401395938329806,48.67482940726141]],type:`LineString`},id:`36`,properties:{ampacity:325,approximate_nominal_voltage:2e4,bus1_id:`MVBus24095`,bus2_id:`MVLV00545`,element_type:`line`,id:`MVBranch32880`,insulator:null,length:.13880575619861452,line_type:`underground`,material:`aac`,max_loading:100,network:`MV Feeder 210`,parameters_id:`U_AL_150`,phases:`abc`,section:150},type:`Feature`},{bbox:[-1.406207660086664,48.67421149659865,-1.402903063269356,48.675123055199464],geometry:{coordinates:[[-1.406207660086664,48.675123055199464],[-1.406207660086664,48.675123055199464],[-1.403474306377468,48.67473982769423],[-1.403066889562038,48.67459093187115],[-1.402903063269356,48.67421149659865],[-1.402903063269356,48.67421149659865]],type:`LineString`},id:`37`,properties:{ampacity:193,approximate_nominal_voltage:2e4,bus1_id:`MVBus24094`,bus2_id:`MVBus24095`,element_type:`line`,id:`MVBranch25434`,insulator:null,length:.2839203535914608,line_type:`overhead`,material:`aaac`,max_loading:100,network:`MV Feeder 210`,parameters_id:`O_AM_54`,phases:`abc`,section:54},type:`Feature`},{bbox:[-1.410183009384582,48.67251969634844,-1.407329364348828,48.67378715489126],geometry:{coordinates:[[-1.407329364348828,48.67378715489126],[-1.407329364348828,48.67378715489126],[-1.407502142525449,48.67373881085122],[-1.407422703141767,48.67334726719784],[-1.408353765225652,48.67308637801645],[-1.409229507508,48.67286043468729],[-1.410183009384582,48.67258309151386],[-1.410177531992409,48.67251969634844],[-1.410177531992409,48.67251969634844]],type:`LineString`},id:`38`,properties:{ampacity:325,approximate_nominal_voltage:2e4,bus1_id:`MVBus24097`,bus2_id:`MVLV03222`,element_type:`line`,id:`MVBranch43826`,insulator:null,length:.28518296092705764,line_type:`underground`,material:`aac`,max_loading:100,network:`MV Feeder 210`,parameters_id:`U_AL_150`,phases:`abc`,section:150},type:`Feature`},{bbox:[-1.407329364348828,48.67378715489126,-1.406207660086664,48.675123055199464],geometry:{coordinates:[[-1.406207660086664,48.675123055199464],[-1.406207660086664,48.675123055199464],[-1.407329364348828,48.67378715489126],[-1.407329364348828,48.67378715489126]],type:`LineString`},id:`39`,properties:{ampacity:193,approximate_nominal_voltage:2e4,bus1_id:`MVBus24094`,bus2_id:`MVBus24097`,element_type:`line`,id:`MVBranch31519`,insulator:null,length:.16998122619689254,line_type:`overhead`,material:`aaac`,max_loading:100,network:`MV Feeder 210`,parameters_id:`O_AM_54`,phases:`abc`,section:54},type:`Feature`},{bbox:[-1.410767426786093,48.675123055199464,-1.406207660086664,48.67586486863645],geometry:{coordinates:[[-1.410767426786093,48.67586486863645],[-1.410767426786093,48.67586486863645],[-1.406207660086664,48.675123055199464],[-1.406207660086664,48.675123055199464]],type:`LineString`},id:`40`,properties:{ampacity:193,approximate_nominal_voltage:2e4,bus1_id:`MVBus24093`,bus2_id:`MVBus24094`,element_type:`line`,id:`MVBranch31518`,insulator:null,length:.34579223003823056,line_type:`overhead`,material:`aaac`,max_loading:100,network:`MV Feeder 210`,parameters_id:`O_AM_54`,phases:`abc`,section:54},type:`Feature`},{bbox:[-1.411978407328498,48.67586486863645,-1.410767426786093,48.676764286658575],geometry:{coordinates:[[-1.411978407328498,48.676764286658575],[-1.411978407328498,48.676764286658575],[-1.41094935900405,48.67588938241899],[-1.410767426786093,48.67586486863645],[-1.410767426786093,48.67586486863645]],type:`LineString`},id:`41`,properties:{ampacity:193,approximate_nominal_voltage:2e4,bus1_id:`MVBus24092`,bus2_id:`MVBus24093`,element_type:`line`,id:`MVBranch08364`,insulator:null,length:.13699784465097406,line_type:`overhead`,material:`aaac`,max_loading:100,network:`MV Feeder 210`,parameters_id:`O_AM_54`,phases:`abc`,section:54},type:`Feature`},{bbox:[-1.413074070122556,48.676764286658575,-1.411978407328498,48.67823125435254],geometry:{coordinates:[[-1.413074070122556,48.67823125435254],[-1.413074070122556,48.67823125435254],[-1.411978407328498,48.676764286658575],[-1.411978407328498,48.676764286658575]],type:`LineString`},id:`42`,properties:{ampacity:193,approximate_nominal_voltage:2e4,bus1_id:`MVBus24069`,bus2_id:`MVBus24092`,element_type:`line`,id:`MVBranch08363`,insulator:null,length:.18199606601879115,line_type:`overhead`,material:`aaac`,max_loading:100,network:`MV Feeder 210`,parameters_id:`O_AM_54`,phases:`abc`,section:54},type:`Feature`},{bbox:[-1.424667185742581,48.68251880629374,-1.420420507191141,48.68634791867971],geometry:{coordinates:[[-1.424667185742581,48.68251880629374],[-1.424667185742581,48.68251880629374],[-1.423863031695593,48.683377524794466],[-1.422193673110718,48.68412332239577],[-1.421450216052972,48.68482593791207],[-1.420420507191141,48.68634791867971],[-1.420420507191141,48.68634791867971]],type:`LineString`},id:`43`,properties:{ampacity:193,approximate_nominal_voltage:2e4,bus1_id:`MVBus24076`,bus2_id:`MVLV10453`,element_type:`line`,id:`MVBranch01918`,insulator:null,length:.5415034548556188,line_type:`overhead`,material:`aaac`,max_loading:100,network:`MV Feeder 210`,parameters_id:`O_AM_54`,phases:`abc`,section:54},type:`Feature`},{bbox:[-1.424667185742581,48.68251880629374,-1.424579380339677,48.68254398026742],geometry:{coordinates:[[-1.424667185742581,48.68251880629374],[-1.424667185742581,48.68251880629374],[-1.424579380339677,48.68254398026742],[-1.424579380339677,48.68254398026742]],type:`LineString`},id:`44`,properties:{ampacity:193,approximate_nominal_voltage:2e4,bus1_id:`MVBus24076`,bus2_id:`MVLV09363`,element_type:`line`,id:`MVBranch15313`,insulator:null,length:.007045636627968056,line_type:`overhead`,material:`aaac`,max_loading:100,network:`MV Feeder 210`,parameters_id:`O_AM_54`,phases:`abc`,section:54},type:`Feature`},{bbox:[-1.424667185742581,48.677875121617966,-1.420328922524153,48.68251880629374],geometry:{coordinates:[[-1.420328922524153,48.677875121617966],[-1.420328922524153,48.677875121617966],[-1.424667185742581,48.68251880629374],[-1.424667185742581,48.68251880629374]],type:`LineString`},id:`45`,properties:{ampacity:193,approximate_nominal_voltage:2e4,bus1_id:`MVBus24075`,bus2_id:`MVBus24076`,element_type:`line`,id:`MVBranch19971`,insulator:null,length:.6072243094713089,line_type:`overhead`,material:`aaac`,max_loading:100,network:`MV Feeder 210`,parameters_id:`O_AM_54`,phases:`abc`,section:54},type:`Feature`},{bbox:[-1.420328922524153,48.67734764388789,-1.419810117061095,48.677875121617966],geometry:{coordinates:[[-1.419810117061095,48.67734764388789],[-1.419810117061095,48.67734764388789],[-1.420328922524153,48.677875121617966],[-1.420328922524153,48.677875121617966]],type:`LineString`},id:`46`,properties:{ampacity:193,approximate_nominal_voltage:2e4,bus1_id:`MVBus24073`,bus2_id:`MVBus24075`,element_type:`line`,id:`MVBranch15245`,insulator:null,length:.07000292723351449,line_type:`overhead`,material:`aaac`,max_loading:100,network:`MV Feeder 210`,parameters_id:`O_AM_54`,phases:`abc`,section:54},type:`Feature`},{bbox:[-1.419810117061095,48.67734764388789,-1.417411347774322,48.6790354886807],geometry:{coordinates:[[-1.419810117061095,48.67734764388789],[-1.419810117061095,48.67734764388789],[-1.418765738504619,48.677922375626466],[-1.417411347774322,48.6790354886807],[-1.417411347774322,48.6790354886807]],type:`LineString`},id:`47`,properties:{ampacity:193,approximate_nominal_voltage:2e4,bus1_id:`MVBus24073`,bus2_id:`MVLV13819`,element_type:`line`,id:`MVBranch15246`,insulator:null,length:.2589656697239327,line_type:`overhead`,material:`aaac`,max_loading:100,network:`MV Feeder 210`,parameters_id:`O_AM_54`,phases:`abc`,section:54},type:`Feature`},{bbox:[-1.421340042028947,48.67636068076991,-1.419810117061095,48.67734764388789],geometry:{coordinates:[[-1.421340042028947,48.67636068076991],[-1.421340042028947,48.67636068076991],[-1.420540495730062,48.67693633672361],[-1.419810117061095,48.67734764388789],[-1.419810117061095,48.67734764388789]],type:`LineString`},id:`48`,properties:{ampacity:193,approximate_nominal_voltage:2e4,bus1_id:`MVBus24072`,bus2_id:`MVBus24073`,element_type:`line`,id:`MVBranch25436`,insulator:null,length:.15758264210247439,line_type:`overhead`,material:`aaac`,max_loading:100,network:`MV Feeder 210`,parameters_id:`O_AM_54`,phases:`abc`,section:54},type:`Feature`},{bbox:[-1.425622793335055,48.67636068076991,-1.421340042028947,48.67794155813378],geometry:{coordinates:[[-1.421340042028947,48.67636068076991],[-1.421340042028947,48.67636068076991],[-1.425056590474113,48.67762732364768],[-1.425622793335055,48.67794155813378],[-1.425622793335055,48.67794155813378]],type:`LineString`},id:`49`,properties:{ampacity:193,approximate_nominal_voltage:2e4,bus1_id:`MVBus24072`,bus2_id:`MVLV18922`,element_type:`line`,id:`MVBranch23142`,insulator:null,length:.36222154559153724,line_type:`overhead`,material:`aaac`,max_loading:100,network:`MV Feeder 210`,parameters_id:`O_AM_54`,phases:`abc`,section:54},type:`Feature`},{bbox:[-1.422160776516778,48.674440314166944,-1.420630681455058,48.67636068076991],geometry:{coordinates:[[-1.420630681455058,48.674440314166944],[-1.420630681455058,48.674440314166944],[-1.421303413674681,48.67445303930767],[-1.422160776516778,48.675074482838696],[-1.421881023752388,48.67595325142352],[-1.421340042028947,48.67636068076991],[-1.421340042028947,48.67636068076991]],type:`LineString`},id:`50`,properties:{ampacity:193,approximate_nominal_voltage:2e4,bus1_id:`MVBus24071`,bus2_id:`MVBus24072`,element_type:`line`,id:`MVBranch23141`,insulator:null,length:.30337749386023144,line_type:`overhead`,material:`aaac`,max_loading:100,network:`MV Feeder 210`,parameters_id:`O_AM_54`,phases:`abc`,section:54},type:`Feature`},{bbox:[-1.420630681455058,48.67443548826671,-1.419991973797182,48.674440314166944],geometry:{coordinates:[[-1.419991973797182,48.67443548826671],[-1.419991973797182,48.67443548826671],[-1.420630681455058,48.674440314166944],[-1.420630681455058,48.674440314166944]],type:`LineString`},id:`51`,properties:{ampacity:193,approximate_nominal_voltage:2e4,bus1_id:`MVBus24070`,bus2_id:`MVBus24071`,element_type:`line`,id:`MVBranch11155`,insulator:null,length:.04704228768803644,line_type:`overhead`,material:`aaac`,max_loading:100,network:`MV Feeder 210`,parameters_id:`O_AM_54`,phases:`abc`,section:54},type:`Feature`},{bbox:[-1.42136624107891,48.67316204924771,-1.419761534530391,48.67352763843192],geometry:{coordinates:[[-1.42136624107891,48.67352763843192],[-1.42136624107891,48.67352763843192],[-1.419920011013785,48.6734160725615],[-1.419761534530391,48.67316204924771],[-1.419761534530391,48.67316204924771]],type:`LineString`},id:`52`,properties:{ampacity:193,approximate_nominal_voltage:2e4,bus1_id:`MVBus24080`,bus2_id:`MVLV00547`,element_type:`line`,id:`MVBranch25435`,insulator:null,length:.13779793646463212,line_type:`overhead`,material:`aaac`,max_loading:100,network:`MV Feeder 210`,parameters_id:`O_AM_54`,phases:`abc`,section:54},type:`Feature`},{bbox:[-1.425433424469281,48.6704288218968,-1.424157252985195,48.670483873139204],geometry:{coordinates:[[-1.425433424469281,48.6704288218968],[-1.425433424469281,48.6704288218968],[-1.425361813066418,48.670451620745325],[-1.425078663899435,48.67046836136561],[-1.424623894900225,48.670481105600174],[-1.424211243860411,48.670483873139204],[-1.424157252985195,48.67046024446686],[-1.424157252985195,48.67046024446686]],type:`LineString`},id:`53`,properties:{ampacity:325,approximate_nominal_voltage:2e4,bus1_id:`MVBus24082`,bus2_id:`MVLV02728`,element_type:`line`,id:`MVBranch41860`,insulator:null,length:.09547606697053757,line_type:`underground`,material:`aac`,max_loading:100,network:`MV Feeder 210`,parameters_id:`U_AL_150`,phases:`abc`,section:150},type:`Feature`},{bbox:[-1.424019455111165,48.667992607111934,-1.423949664678889,48.66801072517383],geometry:{coordinates:[[-1.424019455111165,48.667992607111934],[-1.424019455111165,48.667992607111934],[-1.423991554665524,48.66801072517383],[-1.423949664678889,48.6680024069041],[-1.423949664678889,48.6680024069041]],type:`LineString`},id:`54`,properties:{ampacity:325,approximate_nominal_voltage:2e4,bus1_id:`MVBus24090`,bus2_id:`MVLV14266`,element_type:`line`,id:`MVBranch47852`,insulator:null,length:.0060991198454417115,line_type:`underground`,material:`aac`,max_loading:100,network:`MV Feeder 210`,parameters_id:`U_AL_150`,phases:`abc`,section:150},type:`Feature`},{bbox:[-1.42773882512684,48.66672807735636,-1.424019455111165,48.667992607111934],geometry:{coordinates:[[-1.42773882512684,48.667518960930806],[-1.42773882512684,48.667518960930806],[-1.427625944923735,48.66750760645042],[-1.427284113732512,48.66743188815125],[-1.427021639730295,48.667357105414936],[-1.426533446103999,48.66718559291378],[-1.425410181177729,48.666811433669615],[-1.425238835752817,48.66678363710558],[-1.425143248448931,48.66672807735636],[-1.424936393180271,48.66680628167733],[-1.424829594309627,48.66689721253386],[-1.42436465981737,48.66755902753136],[-1.424172230332951,48.667815763092705],[-1.424019455111165,48.667992607111934],[-1.424019455111165,48.667992607111934]],type:`LineString`},id:`55`,properties:{ampacity:325,approximate_nominal_voltage:2e4,bus1_id:`MVBus24085`,bus2_id:`MVBus24090`,element_type:`line`,id:`MVBranch33616`,insulator:null,length:.37774257520662646,line_type:`underground`,material:`aac`,max_loading:100,network:`MV Feeder 210`,parameters_id:`U_AL_150`,phases:`abc`,section:150},type:`Feature`},{bbox:[-1.438557514204313,48.665013198677705,-1.435905350518214,48.66571332634098],geometry:{coordinates:[[-1.438557514204313,48.66571332634098],[-1.438557514204313,48.66571332634098],[-1.435905350518214,48.665013198677705],[-1.435905350518214,48.665013198677705]],type:`LineString`},id:`56`,properties:{ampacity:193,approximate_nominal_voltage:2e4,bus1_id:`MVBus39974`,bus2_id:`MVLV18920`,element_type:`line`,id:`MVBranch08365`,insulator:null,length:.21030284000132166,line_type:`overhead`,material:`aaac`,max_loading:100,network:`MV Feeder 210`,parameters_id:`O_AM_54`,phases:`abc`,section:54},type:`Feature`},{bbox:[-1.471709586496959,48.67365783095757,-1.452859664487246,48.6843057564178],geometry:{coordinates:[[-1.454111420613221,48.67365783095757],[-1.454111420613221,48.67365783095757],[-1.452869137586615,48.67521355033912],[-1.452859664487246,48.675253242242846],[-1.452918824683785,48.67534661635604],[-1.452891483259132,48.67540384263697],[-1.453878103457793,48.67656219092895],[-1.453874099031162,48.67679155352529],[-1.453773358658158,48.6769571987286],[-1.453611963211757,48.67713094690073],[-1.453426777794724,48.677354176343954],[-1.453245303144872,48.67766060058007],[-1.453250092824149,48.67793832200117],[-1.453276628510095,48.67806878893098],[-1.45339418352316,48.6782786707411],[-1.453578179266918,48.678412699238436],[-1.453782994328737,48.67852528308369],[-1.454086000736322,48.678566019708],[-1.454390489163225,48.678586442199475],[-1.454785641113466,48.67861295542413],[-1.45539974326333,48.67870188544613],[-1.456062695059952,48.678794082577085],[-1.457150163214201,48.679020704631384],[-1.458038894472679,48.679168724680785],[-1.458899745289258,48.67932809655063],[-1.459506361138027,48.67947358896414],[-1.460242190582365,48.67972907747678],[-1.461114544187156,48.680077155369126],[-1.462816384053341,48.6808138484481],[-1.464202643618057,48.68141389267702],[-1.464900489793405,48.68167536746043],[-1.465903467893022,48.6818903386856],[-1.466618503782603,48.68205774238269],[-1.467086104963352,48.68220767349192],[-1.467734965386224,48.68257346478001],[-1.468127601128452,48.68288392994266],[-1.468524223605521,48.68319755066873],[-1.468855231581498,48.683383552661674],[-1.469296303729002,48.68356868554966],[-1.469783126460011,48.683706119835186],[-1.470153882234667,48.68374362536548],[-1.470255748742938,48.68369708764026],[-1.470545857490608,48.683572558820366],[-1.470958795346202,48.68358385201439],[-1.471216002099142,48.68370079965435],[-1.47131322589933,48.68380020562558],[-1.471635983278531,48.684130172901796],[-1.471709586496959,48.68423921020579],[-1.471657732047025,48.68428979476064],[-1.471512364074963,48.6843057564178],[-1.47151580687234,48.684277424479994],[-1.471496954704484,48.684283897260315],[-1.471496954704484,48.684283897260315]],type:`LineString`},id:`57`,properties:{ampacity:325,approximate_nominal_voltage:2e4,bus1_id:`MVBus39986`,bus2_id:`MVBus39989`,element_type:`line`,id:`MVBranch44485`,insulator:null,length:2.1540794924293905,line_type:`underground`,material:`aac`,max_loading:100,network:`MV Feeder 210`,parameters_id:`U_AL_150`,phases:`abc`,section:150},type:`Feature`},{bbox:[-1.456265619588171,48.67258680799679,-1.454133606341398,48.67364249809416],geometry:{coordinates:[[-1.454133606341398,48.67364249809416],[-1.454133606341398,48.67364249809416],[-1.4541725680368,48.67357862747877],[-1.454178728141187,48.67356899944076],[-1.454218958046013,48.6735238334756],[-1.454264495217655,48.67346908471265],[-1.454321700159414,48.67341241504533],[-1.45435423135338,48.67337292164041],[-1.454430642005505,48.67327980327606],[-1.454488681120271,48.67320028499911],[-1.454511747888592,48.67317020127465],[-1.45456351300606,48.67310080060492],[-1.454612325323693,48.67301661872196],[-1.454623822620292,48.672999125729426],[-1.454641536256091,48.67297482859888],[-1.454664248841753,48.67294063454721],[-1.454721439502256,48.672866821704936],[-1.454743205831589,48.67283866032237],[-1.454781471001512,48.67279358392653],[-1.454797278113478,48.67277631306957],[-1.454903203350935,48.672676536097434],[-1.454926893563537,48.672657060330124],[-1.454975649378707,48.67261274629773],[-1.455001257845182,48.67259814970873],[-1.455010528756687,48.67259447856786],[-1.455033900027318,48.67258852070583],[-1.455056222027711,48.67258680799679],[-1.455093711225001,48.67258961379867],[-1.455118470900897,48.67259375356931],[-1.45513651275814,48.6725989360819],[-1.455189199988478,48.6726137646719],[-1.455197741414115,48.67261648824631],[-1.455266142267885,48.672640533387415],[-1.455323431540651,48.672663502972156],[-1.455387921434535,48.67269167774245],[-1.455456942862276,48.67272274027245],[-1.455543810411399,48.672760584328145],[-1.45563645931521,48.67280000725657],[-1.4556841196372,48.67282210574247],[-1.455742810702578,48.67285069077081],[-1.455800027946779,48.6728791879226],[-1.455813728807923,48.672887073937574],[-1.455821183509333,48.672890732142434],[-1.455830310471647,48.67289403088996],[-1.455840224843539,48.672895270642684],[-1.455855526182402,48.672900135741365],[-1.455941809813138,48.67293518145967],[-1.455974336144249,48.67294855775469],[-1.455984729565733,48.67295487569655],[-1.456008638505341,48.672968959571314],[-1.456061114868594,48.67300417762797],[-1.456115073269813,48.67303791739178],[-1.456124932747906,48.67304287552983],[-1.456196478538126,48.673082082136574],[-1.456238660980065,48.67310712737256],[-1.456252367115327,48.6731175059378],[-1.456255738113806,48.67312180769581],[-1.456259903898959,48.67313123154897],[-1.456265619588171,48.67314308959205],[-1.456255345960154,48.673153506275305],[-1.456255345960154,48.673153506275305]],type:`LineString`},id:`58`,properties:{ampacity:325,approximate_nominal_voltage:2e4,bus1_id:`MVBus39987`,bus2_id:`MVLV14633`,element_type:`line`,id:`MVBranch34104`,insulator:null,length:.2488833099190807,line_type:`underground`,material:`aac`,max_loading:100,network:`MV Feeder 210`,parameters_id:`U_AL_150`,phases:`abc`,section:150},type:`Feature`},{bbox:[-1.454133606341398,48.67364249809416,-1.454111420613221,48.67365783095757],geometry:{coordinates:[[-1.454111420613221,48.67365783095757],[-1.454111420613221,48.67365783095757],[-1.454133606341398,48.67364249809416],[-1.454133606341398,48.67364249809416]],type:`LineString`},id:`59`,properties:{ampacity:325,approximate_nominal_voltage:2e4,bus1_id:`MVBus39986`,bus2_id:`MVBus39987`,element_type:`line`,id:`MVBranch33356`,insulator:null,length:.002361576150954956,line_type:`underground`,material:`aac`,max_loading:100,network:`MV Feeder 210`,parameters_id:`U_AL_150`,phases:`abc`,section:150},type:`Feature`},{bbox:[-1.454111420613221,48.67360108655294,-1.453998689564143,48.67365783095757],geometry:{coordinates:[[-1.453998689564143,48.67360108655294],[-1.453998689564143,48.67360108655294],[-1.454111420613221,48.67365783095757],[-1.454111420613221,48.67365783095757]],type:`LineString`},id:`60`,properties:{ampacity:325,approximate_nominal_voltage:2e4,bus1_id:`MVBus39985`,bus2_id:`MVBus39986`,element_type:`line`,id:`MVBranch46239`,insulator:null,length:.010428310529919476,line_type:`underground`,material:`aac`,max_loading:100,network:`MV Feeder 210`,parameters_id:`U_AL_150`,phases:`abc`,section:150},type:`Feature`},{bbox:[-1.453998689564143,48.67139846929151,-1.448362516861079,48.67360108655294],geometry:{coordinates:[[-1.448362516861079,48.67139846929151],[-1.448362516861079,48.67139846929151],[-1.450727879884109,48.67314634305642],[-1.453998689564143,48.67360108655294],[-1.453998689564143,48.67360108655294]],type:`LineString`},id:`61`,properties:{ampacity:357,approximate_nominal_voltage:2e4,bus1_id:`MVBus39983`,bus2_id:`MVBus39985`,element_type:`line`,id:`MVBranch31520`,insulator:null,length:.5071576179737199,line_type:`overhead`,material:`aaac`,max_loading:100,network:`MV Feeder 210`,parameters_id:`O_AM_148`,phases:`abc`,section:148},type:`Feature`},{bbox:[-1.449205686310729,48.67094761063653,-1.448362516861079,48.67139846929151],geometry:{coordinates:[[-1.448362516861079,48.67139846929151],[-1.448362516861079,48.67139846929151],[-1.449205686310729,48.67094761063653],[-1.449205686310729,48.67094761063653]],type:`LineString`},id:`62`,properties:{ampacity:193,approximate_nominal_voltage:2e4,bus1_id:`MVBus39983`,bus2_id:`MVLV00544`,element_type:`line`,id:`MVBranch19972`,insulator:null,length:.07981412800351775,line_type:`overhead`,material:`aaac`,max_loading:100,network:`MV Feeder 210`,parameters_id:`O_AM_54`,phases:`abc`,section:54},type:`Feature`},{bbox:[-1.448362516861079,48.66907708140258,-1.445506049849497,48.67139846929151],geometry:{coordinates:[[-1.445506049849497,48.66907708140258],[-1.445506049849497,48.66907708140258],[-1.448362516861079,48.67139846929151],[-1.448362516861079,48.67139846929151]],type:`LineString`},id:`63`,properties:{ampacity:357,approximate_nominal_voltage:2e4,bus1_id:`MVBus39982`,bus2_id:`MVBus39983`,element_type:`line`,id:`MVBranch19973`,insulator:null,length:.333021028751415,line_type:`overhead`,material:`aaac`,max_loading:100,network:`MV Feeder 210`,parameters_id:`O_AM_148`,phases:`abc`,section:148},type:`Feature`},{bbox:[-1.445506049849497,48.668776616576054,-1.44375635095643,48.66967631292724],geometry:{coordinates:[[-1.44375635095643,48.668776616576054],[-1.44375635095643,48.668776616576054],[-1.445016178665306,48.66967538193563],[-1.445044547761066,48.66967631292724],[-1.445201614001252,48.66950798717624],[-1.44533275307121,48.66926638040962],[-1.445427472704872,48.669089900926714],[-1.445506049849497,48.66907708140258],[-1.445506049849497,48.66907708140258]],type:`LineString`},id:`64`,properties:{ampacity:325,approximate_nominal_voltage:2e4,bus1_id:`MVBus39981`,bus2_id:`MVBus39982`,element_type:`line`,id:`MVBranch43829`,insulator:null,length:.2158172278970547,line_type:`underground`,material:`aac`,max_loading:100,network:`MV Feeder 210`,parameters_id:`U_AL_150`,phases:`abc`,section:150},type:`Feature`},{bbox:[-1.443343047955685,48.668471426684015,-1.443288177621643,48.66847284504271],geometry:{coordinates:[[-1.443343047955685,48.66847284504271],[-1.443343047955685,48.66847284504271],[-1.443288177621643,48.668471426684015],[-1.443288177621643,48.668471426684015]],type:`LineString`},id:`65`,properties:{ampacity:325,approximate_nominal_voltage:2e4,bus1_id:`MVBus39990`,bus2_id:`MVLV18919`,element_type:`line`,id:`MVBranch43828`,insulator:null,length:.004044616944947565,line_type:`underground`,material:`aac`,max_loading:100,network:`MV Feeder 210`,parameters_id:`U_AL_150`,phases:`abc`,section:150},type:`Feature`},{bbox:[-1.443773467700237,48.66847284504271,-1.443343047955685,48.668776616576054],geometry:{coordinates:[[-1.44375635095643,48.668776616576054],[-1.44375635095643,48.668776616576054],[-1.443750278118606,48.66873325448024],[-1.443773467700237,48.66871601970379],[-1.44373218248448,48.66866074962074],[-1.44365965172971,48.668617490680106],[-1.443450919490711,48.66851969296421],[-1.443354882037418,48.668480512965324],[-1.443343047955685,48.66847284504271],[-1.443343047955685,48.66847284504271]],type:`LineString`},id:`66`,properties:{ampacity:325,approximate_nominal_voltage:2e4,bus1_id:`MVBus39981`,bus2_id:`MVBus39990`,element_type:`line`,id:`MVBranch40282`,insulator:null,length:.04981559861077533,line_type:`underground`,material:`aac`,max_loading:100,network:`MV Feeder 210`,parameters_id:`U_AL_150`,phases:`abc`,section:150},type:`Feature`},{bbox:[-1.444502883565754,48.668319010605344,-1.44375635095643,48.668776616576054],geometry:{coordinates:[[-1.444227964428699,48.668319010605344],[-1.444227964428699,48.668319010605344],[-1.444299152272503,48.6683254786251],[-1.444502883565754,48.668578741240715],[-1.44375635095643,48.668776616576054],[-1.44375635095643,48.668776616576054]],type:`LineString`},id:`67`,properties:{ampacity:325,approximate_nominal_voltage:2e4,bus1_id:`MVBus39980`,bus2_id:`MVBus39981`,element_type:`line`,id:`MVBranch48254`,insulator:null,length:.09643044361056909,line_type:`underground`,material:`aac`,max_loading:100,network:`MV Feeder 210`,parameters_id:`U_AL_150`,phases:`abc`,section:150},type:`Feature`},{bbox:[-1.444227964428699,48.66690877873582,-1.443199968358023,48.668319010605344],geometry:{coordinates:[[-1.443199968358023,48.66690877873582],[-1.443199968358023,48.66690877873582],[-1.444227964428699,48.668319010605344],[-1.444227964428699,48.668319010605344]],type:`LineString`},id:`68`,properties:{ampacity:357,approximate_nominal_voltage:2e4,bus1_id:`MVBus39978`,bus2_id:`MVBus39980`,element_type:`line`,id:`MVBranch25438`,insulator:null,length:.17414570776249913,line_type:`overhead`,material:`aaac`,max_loading:100,network:`MV Feeder 210`,parameters_id:`O_AM_148`,phases:`abc`,section:148},type:`Feature`},{bbox:[-1.446079710619304,48.6655489870267,-1.443199968358023,48.66690877873582],geometry:{coordinates:[[-1.443199968358023,48.66690877873582],[-1.443199968358023,48.66690877873582],[-1.444758776426216,48.66613386722032],[-1.446034959286904,48.6655489870267],[-1.446079710619304,48.66557326975702],[-1.446079710619304,48.66557326975702]],type:`LineString`},id:`69`,properties:{ampacity:325,approximate_nominal_voltage:2e4,bus1_id:`MVBus39978`,bus2_id:`MVLV06448`,element_type:`line`,id:`MVBranch43827`,insulator:null,length:.26213193633513093,line_type:`underground`,material:`aac`,max_loading:100,network:`MV Feeder 210`,parameters_id:`U_AL_150`,phases:`abc`,section:150},type:`Feature`},{bbox:[-1.443199968358023,48.66627762495946,-1.441570933640071,48.66690877873582],geometry:{coordinates:[[-1.441570933640071,48.66627762495946],[-1.441570933640071,48.66627762495946],[-1.443199968358023,48.66690877873582],[-1.443199968358023,48.66690877873582]],type:`LineString`},id:`70`,properties:{ampacity:357,approximate_nominal_voltage:2e4,bus1_id:`MVBus39976`,bus2_id:`MVBus39978`,element_type:`line`,id:`MVBranch11156`,insulator:null,length:.13901236964835756,line_type:`overhead`,material:`aaac`,max_loading:100,network:`MV Feeder 210`,parameters_id:`O_AM_148`,phases:`abc`,section:148},type:`Feature`},{bbox:[-1.441570933640071,48.66627762495946,-1.438449788295261,48.67104614339778],geometry:{coordinates:[[-1.441570933640071,48.66627762495946],[-1.441570933640071,48.66627762495946],[-1.440918679186523,48.667310323510996],[-1.438662520784315,48.66925218910298],[-1.438449788295261,48.67104614339778],[-1.438449788295261,48.67104614339778]],type:`LineString`},id:`71`,properties:{ampacity:193,approximate_nominal_voltage:2e4,bus1_id:`MVBus39976`,bus2_id:`MVLV09015`,element_type:`line`,id:`MVBranch15247`,insulator:null,length:.597075270951156,line_type:`overhead`,material:`aaac`,max_loading:100,network:`MV Feeder 210`,parameters_id:`O_AM_54`,phases:`abc`,section:54},type:`Feature`},{bbox:[-1.441570933640071,48.66571332634098,-1.438557514204313,48.66627762495946],geometry:{coordinates:[[-1.438557514204313,48.66571332634098],[-1.438557514204313,48.66571332634098],[-1.441570933640071,48.66627762495946],[-1.441570933640071,48.66627762495946]],type:`LineString`},id:`72`,properties:{ampacity:357,approximate_nominal_voltage:2e4,bus1_id:`MVBus39974`,bus2_id:`MVBus39976`,element_type:`line`,id:`MVBranch25437`,insulator:null,length:.23066760853106663,line_type:`overhead`,material:`aaac`,max_loading:100,network:`MV Feeder 210`,parameters_id:`O_AM_148`,phases:`abc`,section:148},type:`Feature`},{bbox:[-1.438557514204313,48.66571332634098,-1.437540172188118,48.66623721183292],geometry:{coordinates:[[-1.437540172188118,48.66623721183292],[-1.437540172188118,48.66623721183292],[-1.438557514204313,48.66571332634098],[-1.438557514204313,48.66571332634098]],type:`LineString`},id:`73`,properties:{ampacity:357,approximate_nominal_voltage:2e4,bus1_id:`MVBus24089`,bus2_id:`MVBus39974`,element_type:`line`,id:`MVBranch01974`,insulator:null,length:.09491870161658982,line_type:`overhead`,material:`aaac`,max_loading:100,network:`MV Feeder 210`,parameters_id:`O_AM_148`,phases:`abc`,section:148},type:`Feature`},{bbox:[-1.437604584918256,48.66494015250545,-1.429711720954316,48.66740399771851],geometry:{coordinates:[[-1.429737921743526,48.66740399771851],[-1.429737921743526,48.66740399771851],[-1.429711720954316,48.667347992059526],[-1.429745098384111,48.667312105440324],[-1.429792832944832,48.667283114939146],[-1.430600538216654,48.667162099257006],[-1.431267185860128,48.66708041423658],[-1.43198630630097,48.667035555474946],[-1.432243495645382,48.66699438050295],[-1.432432678805019,48.6669315373857],[-1.432628963779213,48.66685196387979],[-1.435725693945472,48.66495492278176],[-1.435886014741506,48.66497381296566],[-1.435951745674166,48.66494015250545],[-1.436119799943683,48.66495440472515],[-1.436858835884234,48.665017086724],[-1.43697981519529,48.665059032466075],[-1.437019059340632,48.66514211392453],[-1.437106449289927,48.665659984314104],[-1.43714728610558,48.6657650088189],[-1.437218640286552,48.665909404864394],[-1.437307400738446,48.66600646047312],[-1.437604584918256,48.66619192963684],[-1.437540172188118,48.66623721183292],[-1.437540172188118,48.66623721183292]],type:`LineString`},id:`74`,properties:{ampacity:325,approximate_nominal_voltage:2e4,bus1_id:`MVBus24086`,bus2_id:`MVBus24089`,element_type:`line`,id:`MVBranch38639`,insulator:null,length:.7845793482250173,line_type:`underground`,material:`aac`,max_loading:100,network:`MV Feeder 210`,parameters_id:`U_AL_150`,phases:`abc`,section:150},type:`Feature`},{bbox:[-1.432209635049518,48.66816721336321,-1.430226347180375,48.67056922323461],geometry:{coordinates:[[-1.430226347180375,48.66816721336321],[-1.430226347180375,48.66816721336321],[-1.430588113036341,48.668625325386294],[-1.432209635049518,48.67056922323461],[-1.432209635049518,48.67056922323461]],type:`LineString`},id:`75`,properties:{ampacity:193,approximate_nominal_voltage:2e4,bus1_id:`MVBus24087`,bus2_id:`MVLV06447`,element_type:`line`,id:`MVBranch08366`,insulator:null,length:.30445850037463673,line_type:`overhead`,material:`aaac`,max_loading:100,network:`MV Feeder 210`,parameters_id:`O_AM_54`,phases:`abc`,section:54},type:`Feature`},{bbox:[-1.430322567466328,48.66740399771851,-1.429737921743526,48.66816904089627],geometry:{coordinates:[[-1.429737921743526,48.66740399771851],[-1.429737921743526,48.66740399771851],[-1.430322567466328,48.66814847999149],[-1.430244168935322,48.66816904089627],[-1.430226347180375,48.66816721336321],[-1.430226347180375,48.66816721336321]],type:`LineString`},id:`76`,properties:{ampacity:325,approximate_nominal_voltage:2e4,bus1_id:`MVBus24086`,bus2_id:`MVBus24087`,element_type:`line`,id:`MVBranch45559`,insulator:null,length:.10085818204908785,line_type:`underground`,material:`aac`,max_loading:100,network:`MV Feeder 210`,parameters_id:`U_AL_150`,phases:`abc`,section:150},type:`Feature`},{bbox:[-1.429737921743526,48.66732761483808,-1.42773882512684,48.667518960930806],geometry:{coordinates:[[-1.42773882512684,48.667518960930806],[-1.42773882512684,48.667518960930806],[-1.428264344005357,48.66750835777458],[-1.428661787035208,48.667467173483466],[-1.429479811508234,48.66732761483808],[-1.429614903110496,48.66736333333185],[-1.429690343340474,48.667355780407235],[-1.429737921743526,48.66740399771851],[-1.429737921743526,48.66740399771851]],type:`LineString`},id:`77`,properties:{ampacity:325,approximate_nominal_voltage:2e4,bus1_id:`MVBus24085`,bus2_id:`MVBus24086`,element_type:`line`,id:`MVBranch44739`,insulator:null,length:.15331713080544543,line_type:`underground`,material:`aac`,max_loading:100,network:`MV Feeder 210`,parameters_id:`U_AL_150`,phases:`abc`,section:150},type:`Feature`},{bbox:[-1.42773882512684,48.667518960930806,-1.427522044306043,48.66832932598601],geometry:{coordinates:[[-1.427550443876756,48.66832702556939],[-1.427550443876756,48.66832702556939],[-1.427541195017932,48.66832932598601],[-1.427522044306043,48.668323589666684],[-1.427713619882294,48.66752098506874],[-1.42773882512684,48.667518960930806],[-1.42773882512684,48.667518960930806]],type:`LineString`},id:`78`,properties:{ampacity:325,approximate_nominal_voltage:2e4,bus1_id:`MVBus24084`,bus2_id:`MVBus24085`,element_type:`line`,id:`MVBranch47851`,insulator:null,length:.09450681050023824,line_type:`underground`,material:`aac`,max_loading:100,network:`MV Feeder 210`,parameters_id:`U_AL_150`,phases:`abc`,section:150},type:`Feature`},{bbox:[-1.427550443876756,48.66832702556939,-1.425433424469281,48.6704288218968],geometry:{coordinates:[[-1.425433424469281,48.6704288218968],[-1.425433424469281,48.6704288218968],[-1.427550443876756,48.66832702556939],[-1.427550443876756,48.66832702556939]],type:`LineString`},id:`79`,properties:{ampacity:357,approximate_nominal_voltage:2e4,bus1_id:`MVBus24082`,bus2_id:`MVBus24084`,element_type:`line`,id:`MVBranch32483`,insulator:null,length:.2809661659950674,line_type:`overhead`,material:`aaac`,max_loading:100,network:`MV Feeder 210`,parameters_id:`O_AM_148`,phases:`abc`,section:148},type:`Feature`},{bbox:[-1.425433424469281,48.6704288218968,-1.423458086823049,48.672063747279815],geometry:{coordinates:[[-1.423458086823049,48.672063747279815],[-1.423458086823049,48.672063747279815],[-1.425433424469281,48.6704288218968],[-1.425433424469281,48.6704288218968]],type:`LineString`},id:`80`,properties:{ampacity:357,approximate_nominal_voltage:2e4,bus1_id:`MVBus24081`,bus2_id:`MVBus24082`,element_type:`line`,id:`MVBranch23143`,insulator:null,length:.23285469633794945,line_type:`overhead`,material:`aaac`,max_loading:100,network:`MV Feeder 210`,parameters_id:`O_AM_148`,phases:`abc`,section:148},type:`Feature`},{bbox:[-1.423458086823049,48.672063747279815,-1.42136624107891,48.67352763843192],geometry:{coordinates:[[-1.42136624107891,48.67352763843192],[-1.42136624107891,48.67352763843192],[-1.423458086823049,48.672063747279815],[-1.423458086823049,48.672063747279815]],type:`LineString`},id:`81`,properties:{ampacity:357,approximate_nominal_voltage:2e4,bus1_id:`MVBus24080`,bus2_id:`MVBus24081`,element_type:`line`,id:`MVBranch15244`,insulator:null,length:.22413447280940296,line_type:`overhead`,material:`aaac`,max_loading:100,network:`MV Feeder 210`,parameters_id:`O_AM_148`,phases:`abc`,section:148},type:`Feature`},{bbox:[-1.42136624107891,48.67352763843192,-1.419991973797182,48.67443548826671],geometry:{coordinates:[[-1.419991973797182,48.67443548826671],[-1.419991973797182,48.67443548826671],[-1.42136624107891,48.67352763843192],[-1.42136624107891,48.67352763843192]],type:`LineString`},id:`82`,properties:{ampacity:357,approximate_nominal_voltage:2e4,bus1_id:`MVBus24070`,bus2_id:`MVBus24080`,element_type:`line`,id:`MVBranch23140`,insulator:null,length:.1429546741306491,line_type:`overhead`,material:`aaac`,max_loading:100,network:`MV Feeder 210`,parameters_id:`O_AM_148`,phases:`abc`,section:148},type:`Feature`},{bbox:[-1.419991973797182,48.67443548826671,-1.413074070122556,48.67823125435254],geometry:{coordinates:[[-1.413074070122556,48.67823125435254],[-1.413074070122556,48.67823125435254],[-1.418220642622635,48.67558838087891],[-1.419991973797182,48.67443548826671],[-1.419991973797182,48.67443548826671]],type:`LineString`},id:`83`,properties:{ampacity:357,approximate_nominal_voltage:2e4,bus1_id:`MVBus24069`,bus2_id:`MVBus24070`,element_type:`line`,id:`MVBranch11154`,insulator:null,length:.6625168530605734,line_type:`overhead`,material:`aaac`,max_loading:100,network:`MV Feeder 210`,parameters_id:`O_AM_148`,phases:`abc`,section:148},type:`Feature`},{bbox:[-1.413074070122556,48.67823125435254,-1.408493773037451,48.68069081868821],geometry:{coordinates:[[-1.408493773037451,48.68069081868821],[-1.408493773037451,48.68069081868821],[-1.413074070122556,48.67823125435254],[-1.413074070122556,48.67823125435254]],type:`LineString`},id:`84`,properties:{ampacity:357,approximate_nominal_voltage:2e4,bus1_id:`MVBus24068`,bus2_id:`MVBus24069`,element_type:`line`,id:`MVBranch15243`,insulator:null,length:.43425352725613486,line_type:`overhead`,material:`aaac`,max_loading:100,network:`MV Feeder 210`,parameters_id:`O_AM_148`,phases:`abc`,section:148},type:`Feature`},{bbox:[-1.413039955009211,48.68122377495599,-1.411072946287639,48.681710134344065],geometry:{coordinates:[[-1.411072946287639,48.68122377495599],[-1.411072946287639,48.68122377495599],[-1.412726298448994,48.68168800584517],[-1.413039955009211,48.681710134344065],[-1.413039955009211,48.681710134344065]],type:`LineString`},id:`85`,properties:{ampacity:325,approximate_nominal_voltage:2e4,bus1_id:`MVBus24101`,bus2_id:`MVLV10323`,element_type:`line`,id:`MVBranch40281`,insulator:null,length:.1554685335100641,line_type:`underground`,material:`aac`,max_loading:100,network:`MV Feeder 210`,parameters_id:`U_AL_150`,phases:`abc`,section:150},type:`Feature`},{bbox:[-1.411072946287639,48.68091651992885,-1.40965762004385,48.68122377495599],geometry:{coordinates:[[-1.40965762004385,48.68091651992885],[-1.40965762004385,48.68091651992885],[-1.411072946287639,48.68122377495599],[-1.411072946287639,48.68122377495599]],type:`LineString`},id:`86`,properties:{ampacity:193,approximate_nominal_voltage:2e4,bus1_id:`MVBus24100`,bus2_id:`MVBus24101`,element_type:`line`,id:`MVBranch23139`,insulator:null,length:.10967942847151416,line_type:`overhead`,material:`aaac`,max_loading:100,network:`MV Feeder 210`,parameters_id:`O_AM_54`,phases:`abc`,section:54},type:`Feature`},{bbox:[-1.410873154098373,48.6846248924926,-1.410457520575412,48.68472414481989],geometry:{coordinates:[[-1.410457520575412,48.6846248924926],[-1.410457520575412,48.6846248924926],[-1.410526256898795,48.68463218763467],[-1.410853373558316,48.6847031927041],[-1.410873154098373,48.68470856092348],[-1.410867808177468,48.68472414481989],[-1.410867808177468,48.68472414481989]],type:`LineString`},id:`87`,properties:{ampacity:325,approximate_nominal_voltage:2e4,bus1_id:`MVBus24104`,bus2_id:`MVLV10324`,element_type:`line`,id:`MVBranch40775`,insulator:null,length:.03382471807901016,line_type:`underground`,material:`aac`,max_loading:100,network:`MV Feeder 210`,parameters_id:`U_AL_150`,phases:`abc`,section:150},type:`Feature`},{bbox:[-1.409966510573871,48.68709324149833,-1.409510396586243,48.687969213263976],geometry:{coordinates:[[-1.409907100020805,48.68709324149833],[-1.409907100020805,48.68709324149833],[-1.409966510573871,48.68710442214782],[-1.409618473717378,48.687710370706036],[-1.409510396586243,48.6879607020776],[-1.409563445224697,48.687969213263976],[-1.409563445224697,48.687969213263976]],type:`LineString`},id:`88`,properties:{ampacity:325,approximate_nominal_voltage:2e4,bus1_id:`MVBus24108`,bus2_id:`MVLV00546`,element_type:`line`,id:`MVBranch43460`,insulator:null,length:.10961108702116706,line_type:`underground`,material:`aac`,max_loading:100,network:`MV Feeder 210`,parameters_id:`U_AL_150`,phases:`abc`,section:150},type:`Feature`},{bbox:[-1.410557522651376,48.685621609766095,-1.409907100020805,48.68709324149833],geometry:{coordinates:[[-1.410557522651376,48.685621609766095],[-1.410557522651376,48.685621609766095],[-1.409907100020805,48.68709324149833],[-1.409907100020805,48.68709324149833]],type:`LineString`},id:`89`,properties:{ampacity:193,approximate_nominal_voltage:2e4,bus1_id:`MVBus24107`,bus2_id:`MVBus24108`,element_type:`line`,id:`MVBranch19974`,insulator:null,length:.1705142628444711,line_type:`overhead`,material:`aaac`,max_loading:100,network:`MV Feeder 210`,parameters_id:`O_AM_54`,phases:`abc`,section:54},type:`Feature`},{bbox:[-1.410557522651376,48.6846345578222,-1.41052130409578,48.685621609766095],geometry:{coordinates:[[-1.41052130409578,48.6846345578222],[-1.41052130409578,48.6846345578222],[-1.410557522651376,48.685621609766095],[-1.410557522651376,48.685621609766095]],type:`LineString`},id:`90`,properties:{ampacity:193,approximate_nominal_voltage:2e4,bus1_id:`MVBus24106`,bus2_id:`MVBus24107`,element_type:`line`,id:`MVBranch15248`,insulator:null,length:.10979615455757827,line_type:`overhead`,material:`aaac`,max_loading:100,network:`MV Feeder 210`,parameters_id:`O_AM_54`,phases:`abc`,section:54},type:`Feature`},{bbox:[-1.41052130409578,48.6846248924926,-1.410457520575412,48.6846345578222],geometry:{coordinates:[[-1.410457520575412,48.6846248924926],[-1.410457520575412,48.6846248924926],[-1.41052130409578,48.6846345578222],[-1.41052130409578,48.6846345578222]],type:`LineString`},id:`91`,properties:{ampacity:325,approximate_nominal_voltage:2e4,bus1_id:`MVBus24104`,bus2_id:`MVBus24106`,element_type:`line`,id:`MVBranch37630`,insulator:null,length:.004817968050677522,line_type:`underground`,material:`aac`,max_loading:100,network:`MV Feeder 210`,parameters_id:`U_AL_150`,phases:`abc`,section:150},type:`Feature`},{bbox:[-1.410457520575412,48.68359763038951,-1.410094731272296,48.6846248924926],geometry:{coordinates:[[-1.410375244576262,48.68359763038951],[-1.410375244576262,48.68359763038951],[-1.41024833874059,48.68399934277218],[-1.410279603008094,48.68403941670856],[-1.410094731272296,48.68454334180209],[-1.410457520575412,48.6846248924926],[-1.410457520575412,48.6846248924926]],type:`LineString`},id:`92`,properties:{ampacity:325,approximate_nominal_voltage:2e4,bus1_id:`MVBus24103`,bus2_id:`MVBus24104`,element_type:`line`,id:`MVBranch32881`,insulator:null,length:.13653314559085525,line_type:`underground`,material:`aac`,max_loading:100,network:`MV Feeder 210`,parameters_id:`U_AL_150`,phases:`abc`,section:150},type:`Feature`},{bbox:[-1.410375244576262,48.68091651992885,-1.40965762004385,48.68359763038951],geometry:{coordinates:[[-1.40965762004385,48.68091651992885],[-1.40965762004385,48.68091651992885],[-1.410375244576262,48.68359763038951],[-1.410375244576262,48.68359763038951]],type:`LineString`},id:`93`,properties:{ampacity:193,approximate_nominal_voltage:2e4,bus1_id:`MVBus24100`,bus2_id:`MVBus24103`,element_type:`line`,id:`MVBranch08367`,insulator:null,length:.3027957426010854,line_type:`overhead`,material:`aaac`,max_loading:100,network:`MV Feeder 210`,parameters_id:`O_AM_54`,phases:`abc`,section:54},type:`Feature`},{bbox:[-1.40965762004385,48.68080865138281,-1.409110034494963,48.68091651992885],geometry:{coordinates:[[-1.409110034494963,48.68080865138281],[-1.409110034494963,48.68080865138281],[-1.40965762004385,48.68091651992885],[-1.40965762004385,48.68091651992885]],type:`LineString`},id:`94`,properties:{ampacity:193,approximate_nominal_voltage:2e4,bus1_id:`MVBus24099`,bus2_id:`MVBus24100`,element_type:`line`,id:`MVBranch08362`,insulator:null,length:.042069559422674464,line_type:`overhead`,material:`aaac`,max_loading:100,network:`MV Feeder 210`,parameters_id:`O_AM_54`,phases:`abc`,section:54},type:`Feature`},{bbox:[-1.409110034494963,48.68069081868821,-1.408493773037451,48.68080865138281],geometry:{coordinates:[[-1.408493773037451,48.68069081868821],[-1.408493773037451,48.68069081868821],[-1.409110034494963,48.68080865138281],[-1.409110034494963,48.68080865138281]],type:`LineString`},id:`95`,properties:{ampacity:193,approximate_nominal_voltage:2e4,bus1_id:`MVBus24068`,bus2_id:`MVBus24099`,element_type:`line`,id:`MVBranch23138`,insulator:null,length:.047234359365897635,line_type:`overhead`,material:`aaac`,max_loading:100,network:`MV Feeder 210`,parameters_id:`O_AM_54`,phases:`abc`,section:54},type:`Feature`},{bbox:[-1.408493773037451,48.68069081868821,-1.398561158560935,48.687535479227805],geometry:{coordinates:[[-1.398561158560935,48.687535479227805],[-1.398561158560935,48.687535479227805],[-1.403644517387418,48.68335067722083],[-1.408493773037451,48.68069081868821],[-1.408493773037451,48.68069081868821]],type:`LineString`},id:`96`,properties:{ampacity:357,approximate_nominal_voltage:2e4,bus1_id:`MVBus24055`,bus2_id:`MVBus24068`,element_type:`line`,id:`MVBranch28134`,insulator:null,length:1.0608890004938134,line_type:`overhead`,material:`aaac`,max_loading:100,network:`MV Feeder 210`,parameters_id:`O_AM_148`,phases:`abc`,section:148},type:`Feature`},{bbox:[-1.398561158560935,48.687535479227805,-1.390456896571498,48.694092429012166],geometry:{coordinates:[[-1.390456896571498,48.694092429012166],[-1.390456896571498,48.694092429012166],[-1.398561158560935,48.687535479227805],[-1.398561158560935,48.687535479227805]],type:`LineString`},id:`97`,properties:{ampacity:357,approximate_nominal_voltage:2e4,bus1_id:`MVBus24052`,bus2_id:`MVBus24055`,element_type:`line`,id:`MVBranch28132`,insulator:null,length:.9421676332786787,line_type:`overhead`,material:`aaac`,max_loading:100,network:`MV Feeder 210`,parameters_id:`O_AM_148`,phases:`abc`,section:148},type:`Feature`},{bbox:[-1.390456896571498,48.6936695244645,-1.389640377977582,48.694092429012166],geometry:{coordinates:[[-1.389640377977582,48.6936695244645],[-1.389640377977582,48.6936695244645],[-1.390344271878809,48.69403410174598],[-1.390456896571498,48.694092429012166],[-1.390456896571498,48.694092429012166]],type:`LineString`},id:`98`,properties:{ampacity:357,approximate_nominal_voltage:2e4,bus1_id:`MVBus24051`,bus2_id:`MVBus24052`,element_type:`line`,id:`MVBranch11542`,insulator:null,length:.07632215258057966,line_type:`overhead`,material:`aaac`,max_loading:100,network:`MV Feeder 210`,parameters_id:`O_AM_148`,phases:`abc`,section:148},type:`Feature`},{bbox:[-1.389640377977582,48.692516906896316,-1.386585620553674,48.6936695244645],geometry:{coordinates:[[-1.386585620553674,48.692516906896316],[-1.386585620553674,48.692516906896316],[-1.389640377977582,48.6936695244645],[-1.389640377977582,48.6936695244645]],type:`LineString`},id:`99`,properties:{ampacity:357,approximate_nominal_voltage:2e4,bus1_id:`MVBus24050`,bus2_id:`MVBus24051`,element_type:`line`,id:`MVBranch11543`,insulator:null,length:.25885409503143514,line_type:`overhead`,material:`aaac`,max_loading:100,network:`MV Feeder 210`,parameters_id:`O_AM_148`,phases:`abc`,section:148},type:`Feature`},{bbox:[-1.388721682538931,48.691644860892694,-1.386585620553674,48.692516906896316],geometry:{coordinates:[[-1.386585620553674,48.692516906896316],[-1.386585620553674,48.692516906896316],[-1.387398231874811,48.691644860892694],[-1.388721682538931,48.69170724856656],[-1.388721682538931,48.69170724856656]],type:`LineString`},id:`100`,properties:{ampacity:193,approximate_nominal_voltage:2e4,bus1_id:`MVBus24050`,bus2_id:`MVLV05135`,element_type:`line`,id:`MVBranch01719`,insulator:null,length:.21162633478045764,line_type:`overhead`,material:`aaac`,max_loading:100,network:`MV Feeder 210`,parameters_id:`O_AM_54`,phases:`abc`,section:54},type:`Feature`},{bbox:[-1.386710197058936,48.69022637502021,-1.3860685283105134,48.692516906896316],geometry:{coordinates:[[-1.3860685283105134,48.69022637502021],[-1.386091642208641,48.69026055987068],[-1.386107806027131,48.690259845618584],[-1.38612993102133,48.690258863290296],[-1.386172893328841,48.69025694803313],[-1.386258900261758,48.69036720873158],[-1.386327665262383,48.69048419259067],[-1.386429285337267,48.69070998267635],[-1.386663235642549,48.691295983208455],[-1.386710197058936,48.69195325464215],[-1.386656207449652,48.69214037516906],[-1.386536543614332,48.692507486905285],[-1.386585620553674,48.692516906896316],[-1.386585620553674,48.692516906896316]],type:`LineString`},id:`101`,properties:{ampacity:325,approximate_nominal_voltage:2e4,bus1_id:`MVLV00762`,bus2_id:`MVBus24050`,element_type:`line`,id:`MVBranch37164`,insulator:null,length:.26724134465610405,line_type:`underground`,material:`aac`,max_loading:100,network:`MV Feeder 210`,parameters_id:`U_AL_150`,phases:`abc`,section:150},type:`Feature`},{bbox:[-1.386095076128499,48.69018758536089,-1.386045414412386,48.69022637502021],geometry:{coordinates:[[-1.386095076128499,48.69020544337535],[-1.386095076128499,48.69020544337535],[-1.386074007914371,48.69018758536089],[-1.386045414412386,48.69019219016974],[-1.3860685283105134,48.69022637502021]],type:`LineString`},id:`102`,properties:{ampacity:325,approximate_nominal_voltage:2e4,bus1_id:`MVBus17519`,bus2_id:`MVLV00762`,element_type:`line`,id:`MVBranch44418`,insulator:null,length:.004686436383422953,line_type:`underground`,material:`aac`,max_loading:100,network:`MV Feeder 210`,parameters_id:`U_AL_150`,phases:`abc`,section:150},type:`Feature`},{bbox:[-1.386095076128499,48.68948115099424,-1.380593480920253,48.69020544337535],geometry:{coordinates:[[-1.380593480920253,48.68951313748911],[-1.380593480920253,48.68951313748911],[-1.38077081939404,48.68948115099424],[-1.381030922180158,48.689499239232546],[-1.381622620649323,48.68956621593823],[-1.381944230603197,48.68960261206002],[-1.382239983321192,48.689632835058646],[-1.382604941018307,48.6897730193813],[-1.382898135881761,48.689885640459785],[-1.382989438641679,48.68992070666759],[-1.383080417712247,48.689951436619616],[-1.383271623296468,48.69000498448029],[-1.383466377608706,48.690039928558214],[-1.38378629455312,48.69006798618082],[-1.385773855373496,48.69015142674052],[-1.38606803163353,48.69014075498917],[-1.386095076128499,48.69020544337535],[-1.386095076128499,48.69020544337535]],type:`LineString`},id:`103`,properties:{ampacity:325,approximate_nominal_voltage:2e4,bus1_id:`MVBus17518`,bus2_id:`MVBus17519`,element_type:`line`,id:`MVBranch46238`,insulator:null,length:.4240344987125137,line_type:`underground`,material:`aac`,max_loading:100,network:`MV Feeder 210`,parameters_id:`U_AL_150`,phases:`abc`,section:150},type:`Feature`},{bbox:[-1.380593480920253,48.68951313748911,-1.37140828752311,48.69474338047859],geometry:{coordinates:[[-1.37140828752311,48.69474338047859],[-1.37140828752311,48.69474338047859],[-1.372108316379351,48.694582899499785],[-1.372776995364991,48.69443116937401],[-1.372929536273884,48.69437481928326],[-1.373004567322684,48.69433308611805],[-1.373035696173742,48.694315771215955],[-1.373972817438306,48.69362667631505],[-1.376669605229281,48.6916538042244],[-1.378349128400386,48.69065179067016],[-1.378658397432478,48.69041424189457],[-1.378829116825462,48.69020588613805],[-1.379202004593425,48.68971142133887],[-1.379492650503138,48.68956048905799],[-1.380181593777458,48.6896592059833],[-1.380266592034214,48.68959851050389],[-1.380593480920253,48.68951313748911],[-1.380593480920253,48.68951313748911]],type:`LineString`},id:`104`,properties:{ampacity:325,approximate_nominal_voltage:2e4,bus1_id:`MVBus17517`,bus2_id:`MVBus17518`,element_type:`line`,id:`MVBranch44435`,insulator:null,length:.9319581720426843,line_type:`underground`,material:`aac`,max_loading:100,network:`MV Feeder 210`,parameters_id:`U_AL_150`,phases:`abc`,section:150},type:`Feature`},{bbox:[-1.37140828752311,48.69474338047859,-1.370008749538573,48.69492079156123],geometry:{coordinates:[[-1.370008749538573,48.69484206776048],[-1.370008749538573,48.69484206776048],[-1.370130340391536,48.694836576401244],[-1.370526610360428,48.69492079156123],[-1.370932620593153,48.69485299475301],[-1.371160826341029,48.69480660998835],[-1.37140828752311,48.69474338047859],[-1.37140828752311,48.69474338047859]],type:`LineString`},id:`105`,properties:{ampacity:325,approximate_nominal_voltage:2e4,bus1_id:`MVBus17516`,bus2_id:`MVBus17517`,element_type:`line`,id:`MVBranch44436`,insulator:null,length:.10753804778842857,line_type:`underground`,material:`aac`,max_loading:100,network:`MV Feeder 210`,parameters_id:`U_AL_150`,phases:`abc`,section:150},type:`Feature`},{bbox:[-1.370008749538573,48.694818957991565,-1.361872248455002,48.698372926745066],geometry:{coordinates:[[-1.361872248455002,48.698372926745066],[-1.361872248455002,48.698372926745066],[-1.362629132935457,48.69820729445299],[-1.363029158829987,48.698095998025224],[-1.363488279660191,48.697927858271804],[-1.363445651687543,48.697882998763404],[-1.363943521716062,48.69764855349933],[-1.364231319150016,48.69749610333351],[-1.36457856618481,48.69726222393793],[-1.364770989793346,48.69708974795057],[-1.36483850397913,48.696999384142416],[-1.365211141359183,48.696401900265855],[-1.365418667508216,48.696168229810155],[-1.365710520367382,48.69589424122478],[-1.366081966636756,48.69563355063961],[-1.366487098573561,48.695415116903014],[-1.366719934502484,48.695316485999676],[-1.367397492595332,48.695120975029496],[-1.368102260761573,48.6949390347851],[-1.368517781569113,48.69486045702395],[-1.368673419887827,48.6948394790163],[-1.368859647394755,48.694818957991565],[-1.369176061861146,48.69484622794454],[-1.369633161489022,48.69488625253494],[-1.369840137641254,48.694909858321765],[-1.370008749538573,48.69484206776048],[-1.370008749538573,48.69484206776048]],type:`LineString`},id:`106`,properties:{ampacity:325,approximate_nominal_voltage:2e4,bus1_id:`MVBus17515`,bus2_id:`MVBus17516`,element_type:`line`,id:`MVBranch36563`,insulator:null,length:.7716718945900013,line_type:`underground`,material:`aac`,max_loading:100,network:`MV Feeder 210`,parameters_id:`U_AL_150`,phases:`abc`,section:150},type:`Feature`},{bbox:[-1.361872248455002,48.698372926745066,-1.361047371992327,48.69858050796095],geometry:{coordinates:[[-1.3610517542755765,48.69858050796095],[-1.361059704093303,48.698579612269214],[-1.361047371992327,48.698535238367704],[-1.361872248455002,48.698372926745066],[-1.361872248455002,48.698372926745066]],type:`LineString`},id:`107`,properties:{ampacity:325,approximate_nominal_voltage:2e4,bus1_id:`MVLV15837`,bus2_id:`MVBus17515`,element_type:`line`,id:`MVBranch33353`,insulator:null,length:.06836447371794643,line_type:`underground`,material:`aac`,max_loading:100,network:`MV Feeder 210`,parameters_id:`U_AL_150`,phases:`abc`,section:150},type:`Feature`},{bbox:[-1.3610517542755765,48.69854465511206,-1.350033533716369,48.702045632317834],geometry:{coordinates:[[-1.350033533716369,48.70073831530751],[-1.350033533716369,48.70073831530751],[-1.350355480420248,48.70102878261073],[-1.351309816091185,48.70180708948788],[-1.351610455483424,48.70196548142909],[-1.351673413354848,48.701995963152626],[-1.352029744876275,48.702045632317834],[-1.352466636103471,48.70201232314792],[-1.352800204288034,48.70194984956354],[-1.353656496921582,48.70172500086173],[-1.354121832772898,48.70156831496038],[-1.355020097991785,48.70112971664497],[-1.355881836396744,48.70070569137057],[-1.357240705657859,48.70004739372588],[-1.358256195357674,48.69955330392023],[-1.360036412980531,48.69869517239255],[-1.3600609520485,48.69870418900822],[-1.360092750498626,48.69871588589524],[-1.360997867228555,48.69854465511206],[-1.361038303263266,48.69857133489028],[-1.36104380445785,48.69858140365268],[-1.3610517542755765,48.69858050796095]],type:`LineString`},id:`108`,properties:{ampacity:325,approximate_nominal_voltage:2e4,bus1_id:`MVBus08235`,bus2_id:`MVLV15837`,element_type:`line`,id:`MVBranch40837`,insulator:null,length:.9959524767430119,line_type:`underground`,material:`aac`,max_loading:100,network:`MV Feeder 210`,parameters_id:`U_AL_150`,phases:`abc`,section:150},type:`Feature`},{bbox:[-1.350033533716369,48.7002449228178,-1.349583389791825,48.70073831530751],geometry:{coordinates:[[-1.349583389791825,48.7002449228178],[-1.349583389791825,48.7002449228178],[-1.349748385026399,48.700405797260046],[-1.349781547229223,48.70045533745463],[-1.349800820063233,48.70047637057669],[-1.349827137474714,48.700499551351136],[-1.349847027596675,48.70052334577209],[-1.349979562527859,48.700651457832706],[-1.350028618635357,48.7006979575111],[-1.35003056868882,48.70070743515395],[-1.350025023888087,48.700721833846366],[-1.350024986880549,48.70072457049264],[-1.350033533716369,48.70073831530751],[-1.350033533716369,48.70073831530751]],type:`LineString`},id:`109`,properties:{ampacity:325,approximate_nominal_voltage:2e4,bus1_id:`MVBus08234`,bus2_id:`MVBus08235`,element_type:`line`,id:`MVBranch46980`,insulator:null,length:.06487991476065545,line_type:`underground`,material:`aac`,max_loading:100,network:`MV Feeder 210`,parameters_id:`U_AL_150`,phases:`abc`,section:150},type:`Feature`},{bbox:[-1.349583389791825,48.69988795473,-1.349083292062529,48.7002449228178],geometry:{coordinates:[[-1.349090863664277,48.69988795473],[-1.349090863664277,48.69988795473],[-1.349083292062529,48.6999270719708],[-1.349083883067351,48.69994077613723],[-1.349084843037833,48.69994185311251],[-1.349140909608321,48.699974323001385],[-1.349236045168364,48.700020975213334],[-1.34927393985865,48.70003642681342],[-1.349387010003084,48.700105179590416],[-1.349472006439018,48.700153577233394],[-1.349507683804376,48.70017111322575],[-1.349583389791825,48.7002449228178],[-1.349583389791825,48.7002449228178]],type:`LineString`},id:`110`,properties:{ampacity:325,approximate_nominal_voltage:2e4,bus1_id:`MVBus08233`,bus2_id:`MVBus08234`,element_type:`line`,id:`MVBranch43224`,insulator:null,length:.05627094231677252,line_type:`underground`,material:`aac`,max_loading:100,network:`MV Feeder 210`,parameters_id:`U_AL_150`,phases:`abc`,section:150},type:`Feature`},{bbox:[-1.349100811857249,48.69449777888983,-1.332662258481913,48.69988795473],geometry:{coordinates:[[-1.332662258481913,48.69470601327688],[-1.332662258481913,48.69470601327688],[-1.334403533710343,48.69449777888983],[-1.334737608012648,48.6945385588819],[-1.337468319551824,48.69479076262023],[-1.338560174992908,48.69473600803719],[-1.339110950367838,48.69497772569214],[-1.34053457433403,48.69551252079587],[-1.341229118621193,48.695859813180384],[-1.34158065555616,48.695897432347785],[-1.342253607540212,48.69588639859719],[-1.343161387869735,48.696007641304966],[-1.343470742121568,48.69609375099156],[-1.343958767360514,48.696412422257495],[-1.344769412777089,48.69680510651728],[-1.344847696755994,48.696914724780584],[-1.344956332284714,48.69700472937253],[-1.345113240552836,48.69707922515018],[-1.345667425411271,48.69728612809096],[-1.346037144688256,48.69742153130377],[-1.346199396336957,48.697577745085724],[-1.34633565051282,48.69770890446633],[-1.346533287484332,48.69776112271589],[-1.346800660298467,48.69780184396979],[-1.347026872166945,48.69780208131676],[-1.347239757547525,48.69777251551116],[-1.347525615978146,48.697598373510864],[-1.347794053666933,48.69737428185959],[-1.348056445531613,48.69726054460816],[-1.348144026797379,48.697322099639194],[-1.348054099550095,48.6976186904504],[-1.347825443439531,48.69791500087517],[-1.347917694846003,48.69823806607235],[-1.34838789439191,48.69920109903526],[-1.349100811857249,48.69984036815978],[-1.349090863664277,48.69988795473],[-1.349090863664277,48.69988795473]],type:`LineString`},id:`111`,properties:{ampacity:325,approximate_nominal_voltage:2e4,bus1_id:`MVBus08232`,bus2_id:`MVBus08233`,element_type:`line`,id:`MVBranch41215`,insulator:null,length:1.5972493115269248,line_type:`underground`,material:`aac`,max_loading:100,network:`MV Feeder 210`,parameters_id:`U_AL_150`,phases:`abc`,section:150},type:`Feature`},{bbox:[-1.332662258481913,48.69470601327688,-1.332456160398833,48.694750388404394],geometry:{coordinates:[[-1.332456160398833,48.694750388404394],[-1.332456160398833,48.694750388404394],[-1.332662258481913,48.69470601327688],[-1.332662258481913,48.69470601327688]],type:`LineString`},id:`112`,properties:{ampacity:325,approximate_nominal_voltage:2e4,bus1_id:`MVBus08231`,bus2_id:`MVBus08232`,element_type:`line`,id:`MVBranch42831`,insulator:null,length:.015954819992476985,line_type:`underground`,material:`aac`,max_loading:100,network:`MV Feeder 210`,parameters_id:`U_AL_150`,phases:`abc`,section:150},type:`Feature`},{bbox:[-1.332456160398833,48.694750388404394,-1.332438253321401,48.694808666564086],geometry:{coordinates:[[-1.3324397522750886,48.69480756439362],[-1.332438253321401,48.694808666564086],[-1.332443502553064,48.69479156034865],[-1.332456160398833,48.694750388404394],[-1.332456160398833,48.694750388404394]],type:`LineString`},id:`113`,properties:{ampacity:325,approximate_nominal_voltage:2e4,bus1_id:`MVLV16807`,bus2_id:`MVBus08231`,element_type:`line`,id:`MVBranch37724`,insulator:null,length:.0066134739308626985,line_type:`underground`,material:`aac`,max_loading:100,network:`MV Feeder 210`,parameters_id:`U_AL_150`,phases:`abc`,section:150},type:`Feature`},{bbox:[-1.337811745653045,48.69348041079462,-1.337017272071378,48.69361150583635],geometry:{coordinates:[[-1.337017272071378,48.69361150583635],[-1.337017272071378,48.69361150583635],[-1.337811745653045,48.69348041079462],[-1.337811745653045,48.69348041079462]],type:`LineString`},id:`114`,properties:{ampacity:325,approximate_nominal_voltage:2e4,bus1_id:`MVBus08990`,bus2_id:`MVLV08873`,element_type:`line`,id:`MVBranch39299`,insulator:null,length:.060278301216926226,line_type:`underground`,material:`aac`,max_loading:100,network:`MV Feeder 210`,parameters_id:`U_AL_150`,phases:`abc`,section:150},type:`Feature`},{bbox:[-1.337017272071378,48.693054819581505,-1.336768360474335,48.69361150583635],geometry:{coordinates:[[-1.337017272071378,48.69361150583635],[-1.337017272071378,48.69361150583635],[-1.336768360474335,48.693054819581505],[-1.336768360474335,48.693054819581505]],type:`LineString`},id:`115`,properties:{ampacity:193,approximate_nominal_voltage:2e4,bus1_id:`MVBus08990`,bus2_id:`MVLV13668`,element_type:`line`,id:`MVBranch10895`,insulator:null,length:.06456087593189838,line_type:`overhead`,material:`aaac`,max_loading:100,network:`MV Feeder 210`,parameters_id:`O_AM_54`,phases:`abc`,section:54},type:`Feature`},{bbox:[-1.337017272071378,48.69361150583635,-1.333868868924871,48.69442417043966],geometry:{coordinates:[[-1.333868868924871,48.69442417043966],[-1.333868868924871,48.69442417043966],[-1.335151937095821,48.69432457617282],[-1.337017272071378,48.69361150583635],[-1.337017272071378,48.69361150583635]],type:`LineString`},id:`116`,properties:{ampacity:193,approximate_nominal_voltage:2e4,bus1_id:`MVBus08989`,bus2_id:`MVBus08990`,element_type:`line`,id:`MVBranch31282`,insulator:null,length:.2536788424847895,line_type:`overhead`,material:`aaac`,max_loading:100,network:`MV Feeder 210`,parameters_id:`O_AM_54`,phases:`abc`,section:54},type:`Feature`},{bbox:[-1.333868868924871,48.69442417043966,-1.332769653966778,48.694856436515416],geometry:{coordinates:[[-1.332769653966778,48.694856436515416],[-1.332769653966778,48.694856436515416],[-1.333868868924871,48.69442417043966],[-1.333868868924871,48.69442417043966]],type:`LineString`},id:`117`,properties:{ampacity:193,approximate_nominal_voltage:2e4,bus1_id:`MVBus08988`,bus2_id:`MVBus08989`,element_type:`line`,id:`MVBranch08117`,insulator:null,length:.09412263973083554,line_type:`overhead`,material:`aaac`,max_loading:100,network:`MV Feeder 210`,parameters_id:`O_AM_54`,phases:`abc`,section:54},type:`Feature`},{bbox:[-1.332769653966778,48.69475012796576,-1.332696716348577,48.694856436515416],geometry:{coordinates:[[-1.332696716348577,48.69475012796576],[-1.332696716348577,48.69475012796576],[-1.332752887698223,48.69475831550576],[-1.332769653966778,48.694856436515416],[-1.332769653966778,48.694856436515416]],type:`LineString`},id:`118`,properties:{ampacity:325,approximate_nominal_voltage:2e4,bus1_id:`MVBus08987`,bus2_id:`MVBus08988`,element_type:`line`,id:`MVBranch47750`,insulator:null,length:.015215285499410657,line_type:`underground`,material:`aac`,max_loading:100,network:`MV Feeder 210`,parameters_id:`U_AL_150`,phases:`abc`,section:150},type:`Feature`},{bbox:[-1.332696716348577,48.69475012796576,-1.3324397522750886,48.69480869206709],geometry:{coordinates:[[-1.3324397522750886,48.69480756439362],[-1.332464774190726,48.69480869206709],[-1.33246573472015,48.69479283430077],[-1.332466383988903,48.69478219619294],[-1.332696716348577,48.69475012796576],[-1.332696716348577,48.69475012796576]],type:`LineString`},id:`119`,properties:{ampacity:325,approximate_nominal_voltage:2e4,bus1_id:`MVLV16807`,bus2_id:`MVBus08987`,element_type:`line`,id:`MVBranch42299`,insulator:null,length:.020276337243253024,line_type:`underground`,material:`aac`,max_loading:100,network:`MV Feeder 210`,parameters_id:`U_AL_150`,phases:`abc`,section:150},type:`Feature`},{bbox:[-1.3324397522750886,48.6947431871332,-1.332311951909265,48.69480756439362],geometry:{coordinates:[[-1.332311951909265,48.6947431871332],[-1.332311951909265,48.6947431871332],[-1.332414749754649,48.69475008560281],[-1.332415855968401,48.6947915696613],[-1.332416229313139,48.694805334549706],[-1.3324397522750886,48.69480756439362]],type:`LineString`},id:`120`,properties:{ampacity:325,approximate_nominal_voltage:2e4,bus1_id:`MVBus05030`,bus2_id:`MVLV16807`,element_type:`line`,id:`MVBranch42832`,insulator:null,length:.013751403625483079,line_type:`underground`,material:`aac`,max_loading:100,network:`MV Feeder 210`,parameters_id:`U_AL_150`,phases:`abc`,section:150},type:`Feature`},{bbox:[-1.332311951909265,48.688034195862905,-1.324149148043669,48.695141656384756],geometry:{coordinates:[[-1.324403471836129,48.688034195862905],[-1.324403471836129,48.688034195862905],[-1.324149148043669,48.68933663489254],[-1.324197080192804,48.68939333858261],[-1.325885968473182,48.68982120486558],[-1.326481505570192,48.69026083730953],[-1.326639205462656,48.69044737913898],[-1.326887269601804,48.69081554133641],[-1.326980765300025,48.69104141783925],[-1.327044222623438,48.69129157273886],[-1.327143567736885,48.69175069380194],[-1.327343998045295,48.69239344320849],[-1.327523947418851,48.69284541269855],[-1.327567107178485,48.69300748878106],[-1.327597607039506,48.69320728091928],[-1.327569335173674,48.69340129401491],[-1.327476282131494,48.69365103710961],[-1.327290667822254,48.69399224550509],[-1.327292636982018,48.69399087092771],[-1.327302797151854,48.69421180737148],[-1.327498179998498,48.694775445551336],[-1.32758157405069,48.69511069261121],[-1.327637773349822,48.695141656384756],[-1.329139158360847,48.694888540438],[-1.32964290487591,48.69474310803858],[-1.330271496452614,48.69459518180074],[-1.330520721003228,48.69457099219727],[-1.330933520974348,48.694591559250384],[-1.332311951909265,48.6947431871332],[-1.332311951909265,48.6947431871332]],type:`LineString`},id:`121`,properties:{ampacity:325,approximate_nominal_voltage:2e4,bus1_id:`MVBus05028`,bus2_id:`MVBus05030`,element_type:`line`,id:`MVBranch37908`,insulator:null,length:1.2704878570324705,line_type:`underground`,material:`aac`,max_loading:100,network:`MV Feeder 210`,parameters_id:`U_AL_150`,phases:`abc`,section:150},type:`Feature`},{bbox:[-1.32466065492585,48.68801559589586,-1.324403471836129,48.6880640048316],geometry:{coordinates:[[-1.324403471836129,48.688034195862905],[-1.324403471836129,48.688034195862905],[-1.324437008831657,48.68801559589586],[-1.324656330660879,48.688047950325824],[-1.32466065492585,48.6880640048316],[-1.32466065492585,48.6880640048316]],type:`LineString`},id:`122`,properties:{ampacity:325,approximate_nominal_voltage:2e4,bus1_id:`MVBus05028`,bus2_id:`MVLV06298`,element_type:`line`,id:`MVBranch44419`,insulator:null,length:.02157870615750059,line_type:`underground`,material:`aac`,max_loading:100,network:`MV Feeder 210`,parameters_id:`U_AL_150`,phases:`abc`,section:150},type:`Feature`},{bbox:[-1.324731743147127,48.68391926354705,-1.322727629500577,48.688034195862905],geometry:{coordinates:[[-1.324640695755288,48.68391926354705],[-1.324640695755288,48.68391926354705],[-1.324731743147127,48.684102385727634],[-1.324612607398126,48.68420823112392],[-1.324210835737492,48.68469847354835],[-1.323733355875409,48.68508555428773],[-1.323247151129281,48.68609235665885],[-1.323186423057092,48.68614168790656],[-1.322964822084235,48.68662253126854],[-1.322727629500577,48.68774974573568],[-1.324392042278423,48.6880208802085],[-1.324403471836129,48.688034195862905],[-1.324403471836129,48.688034195862905]],type:`LineString`},id:`123`,properties:{ampacity:325,approximate_nominal_voltage:2e4,bus1_id:`MVBus05027`,bus2_id:`MVBus05028`,element_type:`line`,id:`MVBranch35638`,insulator:null,length:.5887167838332982,line_type:`underground`,material:`aac`,max_loading:100,network:`MV Feeder 210`,parameters_id:`U_AL_150`,phases:`abc`,section:150},type:`Feature`},{bbox:[-1.324966571570778,48.681828081809556,-1.324633327379154,48.68391926354705],geometry:{coordinates:[[-1.324633327379154,48.681828081809556],[-1.324633327379154,48.681828081809556],[-1.324756396743055,48.682263798619054],[-1.3248669507068,48.6824916253855],[-1.324952123147225,48.68272566173774],[-1.324966571570778,48.68292236987251],[-1.32496292375523,48.68311335585766],[-1.324855378890781,48.6835003575958],[-1.324686040704435,48.683860535074125],[-1.324640695755288,48.68391926354705],[-1.324640695755288,48.68391926354705]],type:`LineString`},id:`124`,properties:{ampacity:325,approximate_nominal_voltage:2e4,bus1_id:`MVBus05026`,bus2_id:`MVBus05027`,element_type:`line`,id:`MVBranch33354`,insulator:null,length:.23885803889542243,line_type:`underground`,material:`aac`,max_loading:100,network:`MV Feeder 210`,parameters_id:`U_AL_150`,phases:`abc`,section:150},type:`Feature`},{bbox:[-1.324843979689097,48.677222514427754,-1.323915414415546,48.681828081809556],geometry:{coordinates:[[-1.3243096308857334,48.677222514427754],[-1.324312588403599,48.67723682956052],[-1.324316950961365,48.67724610720035],[-1.324407539328749,48.67746690264696],[-1.324752016524325,48.67788046022347],[-1.324843979689097,48.67805145172044],[-1.324824957712141,48.678204525954555],[-1.324608374901279,48.67845408006145],[-1.324270214418594,48.67935067307869],[-1.32398527816498,48.67968059475105],[-1.323915414415546,48.680238257520585],[-1.324401306984702,48.6815097737912],[-1.324552530119515,48.68169822823113],[-1.324633327379154,48.681828081809556],[-1.324633327379154,48.681828081809556]],type:`LineString`},id:`125`,properties:{ampacity:325,approximate_nominal_voltage:2e4,bus1_id:`MVLV06299`,bus2_id:`MVBus05026`,element_type:`line`,id:`MVBranch44484`,insulator:null,length:.5407812374987008,line_type:`underground`,material:`aac`,max_loading:100,network:`MV Feeder 210`,parameters_id:`U_AL_150`,phases:`abc`,section:150},type:`Feature`}],type:`FeatureCollection`}),geo_json_e40c8f6088d6ba014632e0b246e82ad0.bindTooltip(function(layer){let div=L.DomUtil.create(`div`),handleObject=feature=>feature===null?``:typeof feature==`object`?JSON.stringify(feature):feature,fields=[`network`,`id`,`phases`,`bus1_id`,`bus2_id`,`parameters_id`,`length`,`line_type`,`material`,`insulator`,`section`,`ampacity`,`max_loading`],aliases=[`Network: `,`Id:`,`Phases:`,`Bus1:`,`Bus2:`,`Parameters:`,`Length (km):`,`Line Type:`,`Material:`,`Insulator:`,`Section (mm²):`,`Ampacity (A):`,`Max loading (%):`];return div.innerHTML=``+String(fields.map((v,i)=>` + - - - - - - - - - - - - + + `).join(``))+`
${aliases[i].toLocaleString()}${handleObject(layer.feature.properties[v]).toLocaleString()}
`,div},{maxWidth:800,sticky:!1,className:`foliumtooltip`}),geo_json_e40c8f6088d6ba014632e0b246e82ad0.bindPopup(function(layer){let div=L.DomUtil.create(`div`),handleObject=feature=>feature===null?``:typeof feature==`object`?JSON.stringify(feature):feature,fields=[`network`,`id`,`phases`,`bus1_id`,`bus2_id`,`parameters_id`,`length`,`line_type`,`material`,`insulator`,`section`,`ampacity`,`max_loading`],aliases=[`Network: `,`Id:`,`Phases:`,`Bus1:`,`Bus2:`,`Parameters:`,`Length (km):`,`Line Type:`,`Material:`,`Insulator:`,`Section (mm²):`,`Ampacity (A):`,`Max loading (%):`];return div.innerHTML=``+String(fields.map((v,i)=>` + - - + + `).join(``))+`
${aliases[i].toLocaleString()}${handleObject(layer.feature.properties[v]).toLocaleString()}
`,div},{className:`foliumpopup`}),geo_json_e40c8f6088d6ba014632e0b246e82ad0.addTo(feature_group_3f19c85fb4db6bdc6be1e3299d4464e9),feature_group_3f19c85fb4db6bdc6be1e3299d4464e9.addTo(map_7d482f8980e12f7966cc91514feaac7d);var feature_group_11e134aa3dacd55c5ddbc606c90f6b30=L.featureGroup({});function geo_json_55759814c7d79f475fa4073771b49b78_styler(feature){switch(feature.id){case`0`:return{html:` +
+
+
+
+ `};default:return{html:` +
+
+
+
+ `}}}function geo_json_55759814c7d79f475fa4073771b49b78_highlighter(feature){switch(feature.id){default:return{color:`#cad40e`,fillColor:`#cad40e`}}}function geo_json_55759814c7d79f475fa4073771b49b78_pointToLayer(feature,latlng){var opts={};opts.icon=new L.DivIcon({className:`empty`});let style=geo_json_55759814c7d79f475fa4073771b49b78_styler(feature);return Object.assign(opts.icon.options,style),new L.Marker(latlng,opts)}function geo_json_55759814c7d79f475fa4073771b49b78_onEachFeature(feature,layer){layer.on({mouseout:function(e){typeof e.target.setStyle==`function`&&geo_json_55759814c7d79f475fa4073771b49b78.resetStyle(e.target)},mouseover:function(e){if(typeof e.target.setStyle==`function`){let highlightStyle=geo_json_55759814c7d79f475fa4073771b49b78_highlighter(e.target.feature);e.target.setStyle(highlightStyle)}}})}var geo_json_55759814c7d79f475fa4073771b49b78=L.geoJson(null,{onEachFeature:geo_json_55759814c7d79f475fa4073771b49b78_onEachFeature,style:geo_json_55759814c7d79f475fa4073771b49b78_styler,pointToLayer:geo_json_55759814c7d79f475fa4073771b49b78_pointToLayer});function geo_json_55759814c7d79f475fa4073771b49b78_add(data){geo_json_55759814c7d79f475fa4073771b49b78.addData(data)}geo_json_55759814c7d79f475fa4073771b49b78_add({bbox:[-1.751702612915616,49.65155465719737,-1.6706848356208555,49.65987962629042],features:[{bbox:[-1.751702612915616,49.653801085335864,-1.751702612915616,49.653801085335864],geometry:{coordinates:[-1.751702612915616,49.653801085335864],type:`Point`},id:`0`,properties:{approximate_nominal_voltage:2e4,element_type:`bus`,id:`HVMV15`,is_source:!0,max_voltage_level:105,min_voltage_level:95,network:`MV Feeder 217`,nominal_voltage:2e4,phases:`abc`},type:`Feature`},{bbox:[-1.751702612915616,49.653801085335864,-1.751702612915616,49.653801085335864],geometry:{coordinates:[-1.751702612915616,49.653801085335864],type:`Point`},id:`1`,properties:{approximate_nominal_voltage:2e4,element_type:`bus`,id:`HVMVFeeder15`,is_source:!1,max_voltage_level:105,min_voltage_level:95,network:`MV Feeder 217`,nominal_voltage:2e4,phases:`abc`},type:`Feature`},{bbox:[-1.679931285366726,49.65155465719737,-1.679931285366726,49.65155465719737],geometry:{coordinates:[-1.679931285366726,49.65155465719737],type:`Point`},id:`2`,properties:{approximate_nominal_voltage:2e4,element_type:`bus`,id:`MVLV13410`,is_source:!1,max_voltage_level:105,min_voltage_level:95,network:`MV Feeder 217`,nominal_voltage:2e4,phases:`abc`},type:`Feature`},{bbox:[-1.676470873384789,49.653553577574854,-1.676470873384789,49.653553577574854],geometry:{coordinates:[-1.676470873384789,49.653553577574854],type:`Point`},id:`3`,properties:{approximate_nominal_voltage:2e4,element_type:`bus`,id:`MVBus32481`,is_source:!1,max_voltage_level:105,min_voltage_level:95,network:`MV Feeder 217`,nominal_voltage:2e4,phases:`abc`},type:`Feature`},{bbox:[-1.6806498367623357,49.654726771172655,-1.6806498367623357,49.654726771172655],geometry:{coordinates:[-1.6806498367623357,49.654726771172655],type:`Point`},id:`4`,properties:{approximate_nominal_voltage:2e4,element_type:`bus`,id:`MVLV10768`,is_source:!1,max_voltage_level:105,min_voltage_level:95,network:`MV Feeder 217`,nominal_voltage:2e4,phases:`abc`},type:`Feature`},{bbox:[-1.678922603714337,49.65539083429302,-1.678922603714337,49.65539083429302],geometry:{coordinates:[-1.678922603714337,49.65539083429302],type:`Point`},id:`5`,properties:{approximate_nominal_voltage:2e4,element_type:`bus`,id:`MVLV01697`,is_source:!1,max_voltage_level:105,min_voltage_level:95,network:`MV Feeder 217`,nominal_voltage:2e4,phases:`abc`},type:`Feature`},{bbox:[-1.6780747779003309,49.655274905822935,-1.6780747779003309,49.655274905822935],geometry:{coordinates:[-1.6780747779003309,49.655274905822935],type:`Point`},id:`6`,properties:{approximate_nominal_voltage:2e4,element_type:`bus`,id:`MVLV09696`,is_source:!1,max_voltage_level:105,min_voltage_level:95,network:`MV Feeder 217`,nominal_voltage:2e4,phases:`abc`},type:`Feature`},{bbox:[-1.6773448547737,49.65466658066605,-1.6773448547737,49.65466658066605],geometry:{coordinates:[-1.6773448547737,49.65466658066605],type:`Point`},id:`7`,properties:{approximate_nominal_voltage:2e4,element_type:`bus`,id:`MVLV09700`,is_source:!1,max_voltage_level:105,min_voltage_level:95,network:`MV Feeder 217`,nominal_voltage:2e4,phases:`abc`},type:`Feature`},{bbox:[-1.6752788266700036,49.65550693267713,-1.6752788266700036,49.65550693267713],geometry:{coordinates:[-1.6752788266700036,49.65550693267713],type:`Point`},id:`8`,properties:{approximate_nominal_voltage:2e4,element_type:`bus`,id:`MVLV10776`,is_source:!1,max_voltage_level:105,min_voltage_level:95,network:`MV Feeder 217`,nominal_voltage:2e4,phases:`abc`},type:`Feature`},{bbox:[-1.67396768671466,49.655955025085554,-1.67396768671466,49.655955025085554],geometry:{coordinates:[-1.67396768671466,49.655955025085554],type:`Point`},id:`9`,properties:{approximate_nominal_voltage:2e4,element_type:`bus`,id:`MVLV01698`,is_source:!1,max_voltage_level:105,min_voltage_level:95,network:`MV Feeder 217`,nominal_voltage:2e4,phases:`abc`},type:`Feature`},{bbox:[-1.674277152501746,49.65696686252891,-1.674277152501746,49.65696686252891],geometry:{coordinates:[-1.674277152501746,49.65696686252891],type:`Point`},id:`10`,properties:{approximate_nominal_voltage:2e4,element_type:`bus`,id:`MVBus26721`,is_source:!1,max_voltage_level:105,min_voltage_level:95,network:`MV Feeder 217`,nominal_voltage:2e4,phases:`abc`},type:`Feature`},{bbox:[-1.6706848356208555,49.656587653461884,-1.6706848356208555,49.656587653461884],geometry:{coordinates:[-1.6706848356208555,49.656587653461884],type:`Point`},id:`11`,properties:{approximate_nominal_voltage:2e4,element_type:`bus`,id:`MVLV01706`,is_source:!1,max_voltage_level:105,min_voltage_level:95,network:`MV Feeder 217`,nominal_voltage:2e4,phases:`abc`},type:`Feature`},{bbox:[-1.673893732207176,49.65699408075931,-1.673893732207176,49.65699408075931],geometry:{coordinates:[-1.673893732207176,49.65699408075931],type:`Point`},id:`12`,properties:{approximate_nominal_voltage:2e4,element_type:`bus`,id:`MVBus22604`,is_source:!1,max_voltage_level:105,min_voltage_level:95,network:`MV Feeder 217`,nominal_voltage:2e4,phases:`abc`},type:`Feature`},{bbox:[-1.678752083502674,49.657632600450846,-1.678752083502674,49.657632600450846],geometry:{coordinates:[-1.678752083502674,49.657632600450846],type:`Point`},id:`13`,properties:{approximate_nominal_voltage:2e4,element_type:`bus`,id:`MVBus22603`,is_source:!1,max_voltage_level:105,min_voltage_level:95,network:`MV Feeder 217`,nominal_voltage:2e4,phases:`abc`},type:`Feature`},{bbox:[-1.687000916584208,49.65872643345839,-1.687000916584208,49.65872643345839],geometry:{coordinates:[-1.687000916584208,49.65872643345839],type:`Point`},id:`14`,properties:{approximate_nominal_voltage:2e4,element_type:`bus`,id:`MVBus22602`,is_source:!1,max_voltage_level:105,min_voltage_level:95,network:`MV Feeder 217`,nominal_voltage:2e4,phases:`abc`},type:`Feature`},{bbox:[-1.6899144761105565,49.65734579505471,-1.6899144761105565,49.65734579505471],geometry:{coordinates:[-1.6899144761105565,49.65734579505471],type:`Point`},id:`15`,properties:{approximate_nominal_voltage:2e4,element_type:`bus`,id:`MVBus21726`,is_source:!1,max_voltage_level:105,min_voltage_level:95,network:`MV Feeder 217`,nominal_voltage:2e4,phases:`abc`},type:`Feature`},{bbox:[-1.6931544029856775,49.65682690034362,-1.6931544029856775,49.65682690034362],geometry:{coordinates:[-1.6931544029856775,49.65682690034362],type:`Point`},id:`16`,properties:{approximate_nominal_voltage:2e4,element_type:`bus`,id:`MVLV09710`,is_source:!1,max_voltage_level:105,min_voltage_level:95,network:`MV Feeder 217`,nominal_voltage:2e4,phases:`abc`},type:`Feature`},{bbox:[-1.694653623707265,49.657307207334895,-1.694653623707265,49.657307207334895],geometry:{coordinates:[-1.694653623707265,49.657307207334895],type:`Point`},id:`17`,properties:{approximate_nominal_voltage:2e4,element_type:`bus`,id:`MVBus20891`,is_source:!1,max_voltage_level:105,min_voltage_level:95,network:`MV Feeder 217`,nominal_voltage:2e4,phases:`abc`},type:`Feature`},{bbox:[-1.694881325517064,49.65753685714968,-1.694881325517064,49.65753685714968],geometry:{coordinates:[-1.694881325517064,49.65753685714968],type:`Point`},id:`18`,properties:{approximate_nominal_voltage:2e4,element_type:`bus`,id:`MVBus20890`,is_source:!1,max_voltage_level:105,min_voltage_level:95,network:`MV Feeder 217`,nominal_voltage:2e4,phases:`abc`},type:`Feature`},{bbox:[-1.6956447814282445,49.65763502482898,-1.6956447814282445,49.65763502482898],geometry:{coordinates:[-1.6956447814282445,49.65763502482898],type:`Point`},id:`19`,properties:{approximate_nominal_voltage:2e4,element_type:`bus`,id:`MVLV12764`,is_source:!1,max_voltage_level:105,min_voltage_level:95,network:`MV Feeder 217`,nominal_voltage:2e4,phases:`abc`},type:`Feature`},{bbox:[-1.697825356573214,49.65683842436038,-1.697825356573214,49.65683842436038],geometry:{coordinates:[-1.697825356573214,49.65683842436038],type:`Point`},id:`20`,properties:{approximate_nominal_voltage:2e4,element_type:`bus`,id:`MVLV08518`,is_source:!1,max_voltage_level:105,min_voltage_level:95,network:`MV Feeder 217`,nominal_voltage:2e4,phases:`abc`},type:`Feature`},{bbox:[-1.699553504846526,49.65715834002786,-1.699553504846526,49.65715834002786],geometry:{coordinates:[-1.699553504846526,49.65715834002786],type:`Point`},id:`21`,properties:{approximate_nominal_voltage:2e4,element_type:`bus`,id:`MVLV15647`,is_source:!1,max_voltage_level:105,min_voltage_level:95,network:`MV Feeder 217`,nominal_voltage:2e4,phases:`abc`},type:`Feature`},{bbox:[-1.7005694121374195,49.65663345325234,-1.7005694121374195,49.65663345325234],geometry:{coordinates:[-1.7005694121374195,49.65663345325234],type:`Point`},id:`22`,properties:{approximate_nominal_voltage:2e4,element_type:`bus`,id:`MVLV11487`,is_source:!1,max_voltage_level:105,min_voltage_level:95,network:`MV Feeder 217`,nominal_voltage:2e4,phases:`abc`},type:`Feature`},{bbox:[-1.7018474404969435,49.65682712281345,-1.7018474404969435,49.65682712281345],geometry:{coordinates:[-1.7018474404969435,49.65682712281345],type:`Point`},id:`23`,properties:{approximate_nominal_voltage:2e4,element_type:`bus`,id:`MVLV08517`,is_source:!1,max_voltage_level:105,min_voltage_level:95,network:`MV Feeder 217`,nominal_voltage:2e4,phases:`abc`},type:`Feature`},{bbox:[-1.7044656244128835,49.657095165588956,-1.7044656244128835,49.657095165588956],geometry:{coordinates:[-1.7044656244128835,49.657095165588956],type:`Point`},id:`24`,properties:{approximate_nominal_voltage:2e4,element_type:`bus`,id:`MVLV08514`,is_source:!1,max_voltage_level:105,min_voltage_level:95,network:`MV Feeder 217`,nominal_voltage:2e4,phases:`abc`},type:`Feature`},{bbox:[-1.704521667859076,49.65632654314429,-1.704521667859076,49.65632654314429],geometry:{coordinates:[-1.704521667859076,49.65632654314429],type:`Point`},id:`25`,properties:{approximate_nominal_voltage:2e4,element_type:`bus`,id:`MVLV08515`,is_source:!1,max_voltage_level:105,min_voltage_level:95,network:`MV Feeder 217`,nominal_voltage:2e4,phases:`abc`},type:`Feature`},{bbox:[-1.7065522989454331,49.658565793845284,-1.7065522989454331,49.658565793845284],geometry:{coordinates:[-1.7065522989454331,49.658565793845284],type:`Point`},id:`26`,properties:{approximate_nominal_voltage:2e4,element_type:`bus`,id:`MVLV12761`,is_source:!1,max_voltage_level:105,min_voltage_level:95,network:`MV Feeder 217`,nominal_voltage:2e4,phases:`abc`},type:`Feature`},{bbox:[-1.7079120407255814,49.65821598234879,-1.7079120407255814,49.65821598234879],geometry:{coordinates:[-1.7079120407255814,49.65821598234879],type:`Point`},id:`27`,properties:{approximate_nominal_voltage:2e4,element_type:`bus`,id:`MVLV11486`,is_source:!1,max_voltage_level:105,min_voltage_level:95,network:`MV Feeder 217`,nominal_voltage:2e4,phases:`abc`},type:`Feature`},{bbox:[-1.708997902725297,49.65748382115472,-1.708997902725297,49.65748382115472],geometry:{coordinates:[-1.708997902725297,49.65748382115472],type:`Point`},id:`28`,properties:{approximate_nominal_voltage:2e4,element_type:`bus`,id:`MVBus13302`,is_source:!1,max_voltage_level:105,min_voltage_level:95,network:`MV Feeder 217`,nominal_voltage:2e4,phases:`abc`},type:`Feature`},{bbox:[-1.7093355253425884,49.65668006698276,-1.7093355253425884,49.65668006698276],geometry:{coordinates:[-1.7093355253425884,49.65668006698276],type:`Point`},id:`29`,properties:{approximate_nominal_voltage:2e4,element_type:`bus`,id:`MVLV15648`,is_source:!1,max_voltage_level:105,min_voltage_level:95,network:`MV Feeder 217`,nominal_voltage:2e4,phases:`abc`},type:`Feature`},{bbox:[-1.709027337065763,49.6575131235305,-1.709027337065763,49.6575131235305],geometry:{coordinates:[-1.709027337065763,49.6575131235305],type:`Point`},id:`30`,properties:{approximate_nominal_voltage:2e4,element_type:`bus`,id:`MVBus12338`,is_source:!1,max_voltage_level:105,min_voltage_level:95,network:`MV Feeder 217`,nominal_voltage:2e4,phases:`abc`},type:`Feature`},{bbox:[-1.7102518017180843,49.65805029431179,-1.7102518017180843,49.65805029431179],geometry:{coordinates:[-1.7102518017180843,49.65805029431179],type:`Point`},id:`31`,properties:{approximate_nominal_voltage:2e4,element_type:`bus`,id:`MVLV04334`,is_source:!1,max_voltage_level:105,min_voltage_level:95,network:`MV Feeder 217`,nominal_voltage:2e4,phases:`abc`},type:`Feature`},{bbox:[-1.712256396489699,49.658696483631566,-1.712256396489699,49.658696483631566],geometry:{coordinates:[-1.712256396489699,49.658696483631566],type:`Point`},id:`32`,properties:{approximate_nominal_voltage:2e4,element_type:`bus`,id:`MVBus11449`,is_source:!1,max_voltage_level:105,min_voltage_level:95,network:`MV Feeder 217`,nominal_voltage:2e4,phases:`abc`},type:`Feature`},{bbox:[-1.7123893567716906,49.65869383173553,-1.7123893567716906,49.65869383173553],geometry:{coordinates:[-1.7123893567716906,49.65869383173553],type:`Point`},id:`33`,properties:{approximate_nominal_voltage:2e4,element_type:`bus`,id:`MVLV12762`,is_source:!1,max_voltage_level:105,min_voltage_level:95,network:`MV Feeder 217`,nominal_voltage:2e4,phases:`abc`},type:`Feature`},{bbox:[-1.712231384433458,49.65739404176467,-1.712231384433458,49.65739404176467],geometry:{coordinates:[-1.712231384433458,49.65739404176467],type:`Point`},id:`34`,properties:{approximate_nominal_voltage:2e4,element_type:`bus`,id:`MVBus09389`,is_source:!1,max_voltage_level:105,min_voltage_level:95,network:`MV Feeder 217`,nominal_voltage:2e4,phases:`abc`},type:`Feature`},{bbox:[-1.7134923699166786,49.656042385779635,-1.7134923699166786,49.656042385779635],geometry:{coordinates:[-1.7134923699166786,49.656042385779635],type:`Point`},id:`35`,properties:{approximate_nominal_voltage:2e4,element_type:`bus`,id:`MVLV16887`,is_source:!1,max_voltage_level:105,min_voltage_level:95,network:`MV Feeder 217`,nominal_voltage:2e4,phases:`abc`},type:`Feature`},{bbox:[-1.715447633958364,49.654538430245495,-1.715447633958364,49.654538430245495],geometry:{coordinates:[-1.715447633958364,49.654538430245495],type:`Point`},id:`36`,properties:{approximate_nominal_voltage:2e4,element_type:`bus`,id:`MVBus01888`,is_source:!1,max_voltage_level:105,min_voltage_level:95,network:`MV Feeder 217`,nominal_voltage:2e4,phases:`abc`},type:`Feature`},{bbox:[-1.723625804781101,49.65673682886024,-1.723625804781101,49.65673682886024],geometry:{coordinates:[-1.723625804781101,49.65673682886024],type:`Point`},id:`37`,properties:{approximate_nominal_voltage:2e4,element_type:`bus`,id:`MVBus01887`,is_source:!1,max_voltage_level:105,min_voltage_level:95,network:`MV Feeder 217`,nominal_voltage:2e4,phases:`abc`},type:`Feature`},{bbox:[-1.727382824582085,49.656858137125596,-1.727382824582085,49.656858137125596],geometry:{coordinates:[-1.727382824582085,49.656858137125596],type:`Point`},id:`38`,properties:{approximate_nominal_voltage:2e4,element_type:`bus`,id:`MVBus01886`,is_source:!1,max_voltage_level:105,min_voltage_level:95,network:`MV Feeder 217`,nominal_voltage:2e4,phases:`abc`},type:`Feature`},{bbox:[-1.727739462930876,49.65677285538332,-1.727739462930876,49.65677285538332],geometry:{coordinates:[-1.727739462930876,49.65677285538332],type:`Point`},id:`39`,properties:{approximate_nominal_voltage:2e4,element_type:`bus`,id:`MVBus01885`,is_source:!1,max_voltage_level:105,min_voltage_level:95,network:`MV Feeder 217`,nominal_voltage:2e4,phases:`abc`},type:`Feature`},{bbox:[-1.728312906960772,49.656559479695645,-1.728312906960772,49.656559479695645],geometry:{coordinates:[-1.728312906960772,49.656559479695645],type:`Point`},id:`40`,properties:{approximate_nominal_voltage:2e4,element_type:`bus`,id:`MVBus01884`,is_source:!1,max_voltage_level:105,min_voltage_level:95,network:`MV Feeder 217`,nominal_voltage:2e4,phases:`abc`},type:`Feature`},{bbox:[-1.733888052209557,49.656314900145844,-1.733888052209557,49.656314900145844],geometry:{coordinates:[-1.733888052209557,49.656314900145844],type:`Point`},id:`41`,properties:{approximate_nominal_voltage:2e4,element_type:`bus`,id:`MVBus01883`,is_source:!1,max_voltage_level:105,min_voltage_level:95,network:`MV Feeder 217`,nominal_voltage:2e4,phases:`abc`},type:`Feature`},{bbox:[-1.740479446878883,49.65987962629042,-1.740479446878883,49.65987962629042],geometry:{coordinates:[-1.740479446878883,49.65987962629042],type:`Point`},id:`42`,properties:{approximate_nominal_voltage:2e4,element_type:`bus`,id:`MVBus01882`,is_source:!1,max_voltage_level:105,min_voltage_level:95,network:`MV Feeder 217`,nominal_voltage:2e4,phases:`abc`},type:`Feature`},{bbox:[-1.75134861697713,49.6546228164401,-1.75134861697713,49.6546228164401],geometry:{coordinates:[-1.75134861697713,49.6546228164401],type:`Point`},id:`43`,properties:{approximate_nominal_voltage:2e4,element_type:`bus`,id:`MVBus01881`,is_source:!1,max_voltage_level:105,min_voltage_level:95,network:`MV Feeder 217`,nominal_voltage:2e4,phases:`abc`},type:`Feature`}],type:`FeatureCollection`}),geo_json_55759814c7d79f475fa4073771b49b78.bindTooltip(function(layer){let div=L.DomUtil.create(`div`),handleObject=feature=>feature===null?``:typeof feature==`object`?JSON.stringify(feature):feature,fields=[`network`,`id`,`phases`,`nominal_voltage`,`min_voltage_level`,`max_voltage_level`],aliases=[`Network: `,`Id:`,`Phases:`,`Un (V):`,`Umin (%):`,`Umax (%):`];return div.innerHTML=``+String(fields.map((v,i)=>` + - + + `).join(``))+`
${aliases[i].toLocaleString()}${handleObject(layer.feature.properties[v]).toLocaleString()}
`,div},{maxWidth:800,sticky:!1,className:`foliumtooltip`}),geo_json_55759814c7d79f475fa4073771b49b78.bindPopup(function(layer){let div=L.DomUtil.create(`div`),handleObject=feature=>feature===null?``:typeof feature==`object`?JSON.stringify(feature):feature,fields=[`network`,`id`,`phases`,`nominal_voltage`,`min_voltage_level`,`max_voltage_level`],aliases=[`Network: `,`Id:`,`Phases:`,`Un (V):`,`Umin (%):`,`Umax (%):`];return div.innerHTML=``+String(fields.map((v,i)=>` + - + + `).join(``))+`
${aliases[i].toLocaleString()}${handleObject(layer.feature.properties[v]).toLocaleString()}
`,div},{className:`foliumpopup`}),geo_json_55759814c7d79f475fa4073771b49b78.addTo(feature_group_11e134aa3dacd55c5ddbc606c90f6b30);function geo_json_0490a447eb076da705c8c5ea5bd1a2fb_styler(feature){switch(feature.id){default:return{color:`#234e83`,dashArray:`5, 5`,weight:3}}}function geo_json_0490a447eb076da705c8c5ea5bd1a2fb_highlighter(feature){switch(feature.id){default:return{color:`#cad40e`}}}function geo_json_0490a447eb076da705c8c5ea5bd1a2fb_onEachFeature(feature,layer){layer.on({mouseout:function(e){typeof e.target.setStyle==`function`&&geo_json_0490a447eb076da705c8c5ea5bd1a2fb.resetStyle(e.target)},mouseover:function(e){if(typeof e.target.setStyle==`function`){let highlightStyle=geo_json_0490a447eb076da705c8c5ea5bd1a2fb_highlighter(e.target.feature);e.target.setStyle(highlightStyle)}}})}var geo_json_0490a447eb076da705c8c5ea5bd1a2fb=L.geoJson(null,{onEachFeature:geo_json_0490a447eb076da705c8c5ea5bd1a2fb_onEachFeature,style:geo_json_0490a447eb076da705c8c5ea5bd1a2fb_styler});function geo_json_0490a447eb076da705c8c5ea5bd1a2fb_add(data){geo_json_0490a447eb076da705c8c5ea5bd1a2fb.addData(data)}geo_json_0490a447eb076da705c8c5ea5bd1a2fb_add({bbox:[-1.751814757753236,49.65152996245496,-1.67057193383152,49.661351719623156],features:[{bbox:[-1.751814757753236,49.653801085335864,-1.75134861697713,49.6546228164401],geometry:{coordinates:[[-1.751702612915616,49.653801085335864],[-1.751748734460548,49.65384507495183],[-1.751748734460548,49.65384507495183],[-1.751790150159045,49.65387028475741],[-1.751810276327588,49.653882545108324],[-1.751814757753236,49.65389524435384],[-1.751729575993817,49.65395420280918],[-1.751750236824847,49.65398470050129],[-1.751694134911765,49.65402853028565],[-1.751692487066552,49.65403907159969],[-1.751699941927443,49.654046877174686],[-1.751709491778441,49.654048334955746],[-1.751726443067687,49.654059695439734],[-1.75173645898574,49.654076290348044],[-1.751739217834648,49.6540951449433],[-1.75173215522583,49.65411554554525],[-1.751722757422452,49.65412997291849],[-1.751723830062776,49.654135575152736],[-1.751742356405606,49.654165191753165],[-1.751764818899627,49.654189828179526],[-1.751764648988911,49.65419548140606],[-1.751690469929741,49.65426935566007],[-1.751501935380691,49.65445071012209],[-1.751420572147751,49.65453570827406],[-1.75134861697713,49.6546228164401],[-1.75134861697713,49.6546228164401]],type:`LineString`},id:`0`,properties:{ampacity:325,approximate_nominal_voltage:2e4,bus1_id:`HVMVFeeder15`,bus2_id:`MVBus01881`,element_type:`line`,id:`MVBranch34116`,insulator:null,length:.1036641105058596,line_type:`underground`,material:`aac`,max_loading:100,network:`MV Feeder 217`,parameters_id:`U_AL_150`,phases:`abc`,section:150},type:`Feature`},{bbox:[-1.679931285366726,49.65152996245496,-1.676424765437117,49.653553577574854],geometry:{coordinates:[[-1.676470873384789,49.653553577574854],[-1.676470873384789,49.653553577574854],[-1.676424765437117,49.653482511979],[-1.676521421331345,49.65344053000349],[-1.676858481206689,49.65325319473666],[-1.678152565183635,49.65269022736848],[-1.678544385244714,49.65250613193956],[-1.679098718928381,49.65214385975146],[-1.679151650142219,49.652057816640855],[-1.679181001130015,49.651886589081585],[-1.679277799252331,49.65181342328669],[-1.679907774876601,49.65152996245496],[-1.679918713866793,49.65154223352049],[-1.679931285366726,49.65155465719737],[-1.679931285366726,49.65155465719737]],type:`LineString`},id:`1`,properties:{ampacity:325,approximate_nominal_voltage:2e4,bus1_id:`MVBus32481`,bus2_id:`MVLV13410`,element_type:`line`,id:`MVBranch35243`,insulator:null,length:.3519938016465228,line_type:`underground`,material:`aac`,max_loading:100,network:`MV Feeder 217`,parameters_id:`U_AL_150`,phases:`abc`,section:150},type:`Feature`},{bbox:[-1.6806498367623357,49.653553577574854,-1.676459009396345,49.65477043741846],geometry:{coordinates:[[-1.6806498367623357,49.654726771172655],[-1.680649452577199,49.654724005287015],[-1.680620082467265,49.654724108466446],[-1.680617720428734,49.654724366761755],[-1.680198212687284,49.65477043741846],[-1.680146921626781,49.65409595873909],[-1.679058120325391,49.65423091938446],[-1.678679042911614,49.654259357440885],[-1.678125611370777,49.654225392366186],[-1.677614535697321,49.65411612883299],[-1.677087691774939,49.653949763364736],[-1.676459009396345,49.65365816574056],[-1.676468589659444,49.65355518204723],[-1.676470873384789,49.653553577574854],[-1.676470873384789,49.653553577574854]],type:`LineString`},id:`2`,properties:{ampacity:325,approximate_nominal_voltage:2e4,bus1_id:`MVLV10768`,bus2_id:`MVBus32481`,element_type:`line`,id:`MVBranch44845`,insulator:null,length:.4045281743946701,line_type:`underground`,material:`aac`,max_loading:100,network:`MV Feeder 217`,parameters_id:`U_AL_150`,phases:`abc`,section:150},type:`Feature`},{bbox:[-1.680650220947472,49.65416198357893,-1.678736703536458,49.65539083429302],geometry:{coordinates:[[-1.678922603714337,49.65539083429302],[-1.678925256693174,49.65538451001746],[-1.678910414981441,49.655375102131124],[-1.678736703536458,49.65526499317018],[-1.678829534214599,49.655010547963066],[-1.678973702731857,49.65484076098087],[-1.679144308889874,49.65428376571825],[-1.680034460154386,49.65416198357893],[-1.680088848218442,49.65482375205744],[-1.680622201035775,49.65473798528497],[-1.680629997114304,49.65473672820811],[-1.680650220947472,49.654729537058294],[-1.6806498367623357,49.654726771172655]],type:`LineString`},id:`3`,properties:{ampacity:325,approximate_nominal_voltage:2e4,bus1_id:`MVLV01697`,bus2_id:`MVLV10768`,element_type:`line`,id:`MVBranch43579`,insulator:null,length:.3141553288143411,line_type:`underground`,material:`aac`,max_loading:100,network:`MV Feeder 217`,parameters_id:`U_AL_150`,phases:`abc`,section:150},type:`Feature`},{bbox:[-1.678922603714337,49.655274905822935,-1.678072690905384,49.655404254920114],geometry:{coordinates:[[-1.6780747779003309,49.655274905822935],[-1.678072690905384,49.65527962414078],[-1.678089181314788,49.65528780839687],[-1.678144418098371,49.6553152181978],[-1.67866190791389,49.65530000143054],[-1.678875756206534,49.655404254920114],[-1.678899802351542,49.65540039026296],[-1.6789199507355,49.65539715856858],[-1.678922603714337,49.65539083429302]],type:`LineString`},id:`4`,properties:{ampacity:325,approximate_nominal_voltage:2e4,bus1_id:`MVLV09696`,bus2_id:`MVLV01697`,element_type:`line`,id:`MVBranch40080`,insulator:null,length:.06652125023066995,line_type:`underground`,material:`aac`,max_loading:100,network:`MV Feeder 217`,parameters_id:`U_AL_150`,phases:`abc`,section:150},type:`Feature`},{bbox:[-1.679010455358163,49.6542011840085,-1.6773448547737,49.655274905822935],geometry:{coordinates:[[-1.6773448547737,49.65466658066605],[-1.677346619628273,49.65466691776358],[-1.67735420638769,49.6546543824335],[-1.677628463706782,49.6542011840085],[-1.678113900867778,49.654302342084655],[-1.678667036130465,49.654332711132014],[-1.679010455358163,49.65430911684581],[-1.678880187127391,49.654799883819],[-1.678770591808817,49.65490092737212],[-1.678634464207953,49.65523611346554],[-1.678097528581897,49.655268926155365],[-1.678076864895278,49.65527018750508],[-1.6780747779003309,49.655274905822935]],type:`LineString`},id:`5`,properties:{ampacity:325,approximate_nominal_voltage:2e4,bus1_id:`MVLV09700`,bus2_id:`MVLV09696`,element_type:`line`,id:`MVBranch35242`,insulator:null,length:.3056172779538304,line_type:`underground`,material:`aac`,max_loading:100,network:`MV Feeder 217`,parameters_id:`U_AL_150`,phases:`abc`,section:150},type:`Feature`},{bbox:[-1.677494415781153,49.653734955738095,-1.675208568631158,49.65550693267713],geometry:{coordinates:[[-1.6752788266700036,49.65550693267713],[-1.67528166988927,49.65550337182224],[-1.67526690675527,49.655493897992116],[-1.675208568631158,49.65545645555238],[-1.676192776458766,49.65384476857928],[-1.676286536254999,49.65377038451844],[-1.67637377763908,49.653734955738095],[-1.677036721521781,49.65400466253389],[-1.677494415781153,49.654173412998034],[-1.677347146971025,49.65465303404376],[-1.677343089919127,49.65466624356853],[-1.6773448547737,49.65466658066605]],type:`LineString`},id:`6`,properties:{ampacity:325,approximate_nominal_voltage:2e4,bus1_id:`MVLV10776`,bus2_id:`MVLV09700`,element_type:`line`,id:`MVBranch47234`,insulator:null,length:.36876498865043383,line_type:`underground`,material:`aac`,max_loading:100,network:`MV Feeder 217`,parameters_id:`U_AL_150`,phases:`abc`,section:150},type:`Feature`},{bbox:[-1.6752788266700036,49.65547623289931,-1.67396768671466,49.655980358059864],geometry:{coordinates:[[-1.67396768671466,49.655955025085554],[-1.673969891318883,49.65595329290034],[-1.67398785998382,49.65596002583815],[-1.674042081236127,49.655980358059864],[-1.674226487934641,49.655844313039566],[-1.674444469242429,49.655508999198744],[-1.674715024543798,49.65547623289931],[-1.675128102066041,49.6555744962176],[-1.675176000480159,49.65549899947378],[-1.675255547689846,49.65550814095187],[-1.675275983450737,49.65551049353201],[-1.6752788266700036,49.65550693267713]],type:`LineString`},id:`7`,properties:{ampacity:325,approximate_nominal_voltage:2e4,bus1_id:`MVLV01698`,bus2_id:`MVLV10776`,element_type:`line`,id:`MVBranch32648`,insulator:null,length:.13470701833430523,line_type:`underground`,material:`aac`,max_loading:100,network:`MV Feeder 217`,parameters_id:`U_AL_150`,phases:`abc`,section:150},type:`Feature`},{bbox:[-1.675071025881376,49.655558698636405,-1.673965482110437,49.65696686252891],geometry:{coordinates:[[-1.674277152501746,49.65696686252891],[-1.674277152501746,49.65696686252891],[-1.675071025881376,49.6556395065306],[-1.674725960202185,49.655558698636405],[-1.674487217505072,49.6555903649928],[-1.674286160954233,49.65589538000418],[-1.674089395171112,49.65604986454216],[-1.673979041567607,49.65596695458006],[-1.673965482110437,49.655956757270765],[-1.67396768671466,49.655955025085554]],type:`LineString`},id:`8`,properties:{ampacity:325,approximate_nominal_voltage:2e4,bus1_id:`MVBus26721`,bus2_id:`MVLV01698`,element_type:`line`,id:`MVBranch41423`,insulator:null,length:.2753332481217924,line_type:`underground`,material:`aac`,max_loading:100,network:`MV Feeder 217`,parameters_id:`U_AL_150`,phases:`abc`,section:150},type:`Feature`},{bbox:[-1.674277152501746,49.656586512850396,-1.670635519700989,49.65699482395728],geometry:{coordinates:[[-1.6706848356208555,49.656587653461884],[-1.670690085727147,49.656586512850396],[-1.67070169883703,49.6565976832098],[-1.670635519700989,49.656687766511745],[-1.67064106690749,49.65696571458043],[-1.672937131365823,49.65694244508355],[-1.673393205346661,49.65694342208668],[-1.673714225148667,49.656963056106264],[-1.674125972813084,49.65699482395728],[-1.674275818087714,49.656969091911975],[-1.674277152501746,49.65696686252891],[-1.674277152501746,49.65696686252891]],type:`LineString`},id:`9`,properties:{ampacity:325,approximate_nominal_voltage:2e4,bus1_id:`MVLV01706`,bus2_id:`MVBus26721`,element_type:`line`,id:`MVBranch36813`,insulator:null,length:.30693215195631945,line_type:`underground`,material:`aac`,max_loading:100,network:`MV Feeder 217`,parameters_id:`U_AL_150`,phases:`abc`,section:150},type:`Feature`},{bbox:[-1.673893732207176,49.656587653461884,-1.67057193383152,49.65699408075931],geometry:{coordinates:[[-1.673893732207176,49.65699408075931],[-1.673893732207176,49.65699408075931],[-1.673707310915567,49.65697781693429],[-1.673406236814339,49.65695676628434],[-1.673209625311018,49.6569555239853],[-1.672890090963208,49.65695318556568],[-1.672307056857197,49.65696001158772],[-1.670580370829152,49.65698705886373],[-1.67057193383152,49.656677104031814],[-1.670680684591789,49.65660224611452],[-1.670679585514564,49.656588794073365],[-1.6706848356208555,49.656587653461884]],type:`LineString`},id:`10`,properties:{ampacity:325,approximate_nominal_voltage:2e4,bus1_id:`MVBus22604`,bus2_id:`MVLV01706`,element_type:`line`,id:`MVBranch38007`,insulator:null,length:.2869541126249135,line_type:`underground`,material:`aac`,max_loading:100,network:`MV Feeder 217`,parameters_id:`U_AL_150`,phases:`abc`,section:150},type:`Feature`},{bbox:[-1.678752083502674,49.65699408075931,-1.673893732207176,49.657632600450846],geometry:{coordinates:[[-1.678752083502674,49.657632600450846],[-1.678752083502674,49.657632600450846],[-1.678655771591739,49.657619943933625],[-1.67854619816165,49.65760546145833],[-1.678443407774987,49.65759479130411],[-1.678341877746072,49.65757989779403],[-1.678140109130628,49.657554545845564],[-1.678041590760031,49.6575425375894],[-1.67783766814151,49.6575162135232],[-1.677539407645088,49.65747819134837],[-1.677336141016467,49.65745139506758],[-1.67707260443018,49.65741790267715],[-1.676933881645884,49.65739929630037],[-1.676827859548407,49.65738574657],[-1.676619652239228,49.657357764183985],[-1.676530441792488,49.6573467947611],[-1.676437178503299,49.6573343141322],[-1.676244579576855,49.6573080523875],[-1.676050342062734,49.65728455138865],[-1.675954139358735,49.65726991981983],[-1.675892723527981,49.65726327047057],[-1.675856254239052,49.65725714244844],[-1.67569549060223,49.65724570429279],[-1.675651975270466,49.65724385646937],[-1.675641965335153,49.6572426867701],[-1.675631965147522,49.65723583359685],[-1.675569391305867,49.657209367441276],[-1.675398407174624,49.65718528332874],[-1.67531716495159,49.6571754067692],[-1.675186271725575,49.65715594555002],[-1.675092779518475,49.65714582769529],[-1.674930244527375,49.657125428348955],[-1.674868614969784,49.65711887563815],[-1.674804747012458,49.6571097533888],[-1.674692561111355,49.657094958714595],[-1.674600142995935,49.65708546130469],[-1.674486934848108,49.65707070034376],[-1.674416818339161,49.65705979780329],[-1.674329314720484,49.65704814991709],[-1.674269819481414,49.65703756051881],[-1.674195246251969,49.65702687757574],[-1.674086000254391,49.65701881003487],[-1.673966304130941,49.657014011399724],[-1.673934457361715,49.65701363757407],[-1.673928516287633,49.65701154152207],[-1.673927343536305,49.65700543865399],[-1.673924391873185,49.65700014113187],[-1.673922973085514,49.656996896986335],[-1.673920117920933,49.65699564280755],[-1.673893732207176,49.65699408075931],[-1.673893732207176,49.65699408075931]],type:`LineString`},id:`11`,properties:{ampacity:325,approximate_nominal_voltage:2e4,bus1_id:`MVBus22603`,bus2_id:`MVBus22604`,element_type:`line`,id:`MVBranch45639`,insulator:null,length:.35978615142983944,line_type:`underground`,material:`aac`,max_loading:100,network:`MV Feeder 217`,parameters_id:`U_AL_150`,phases:`abc`,section:150},type:`Feature`},{bbox:[-1.687000916584208,49.657632600450846,-1.678752083502674,49.65872643345839],geometry:{coordinates:[[-1.687000916584208,49.65872643345839],[-1.687000916584208,49.65872643345839],[-1.686970742780532,49.658721825850186],[-1.686864833669288,49.65871276818489],[-1.686750491666597,49.65869620350682],[-1.686520660235055,49.65866625932611],[-1.6862083366353,49.65862557849003],[-1.685909066963389,49.6585867108749],[-1.685685278281926,49.6585573195575],[-1.685476654697023,49.65853280104184],[-1.685442421346384,49.65852870571752],[-1.685112527216627,49.65849354312171],[-1.68488785090189,49.65846447661544],[-1.684736289368716,49.658441063276726],[-1.684603220068488,49.658427124465256],[-1.684470644531766,49.658411190775794],[-1.684344595507814,49.65839826826076],[-1.684220756570289,49.658380524186136],[-1.684094066483814,49.65836456531888],[-1.683971924911957,49.65835007376753],[-1.683761701283773,49.65832087554532],[-1.683691553446464,49.65831032985342],[-1.683572945631358,49.65829427269268],[-1.683356190893484,49.65826673860415],[-1.683221700182995,49.65824951836259],[-1.683098453486965,49.658232598763526],[-1.682968009314595,49.65821469524507],[-1.682850931220949,49.65819888330731],[-1.682764141959558,49.65818897097931],[-1.6826586781223,49.65817569546537],[-1.682623811273247,49.6581705862859],[-1.682558714169335,49.65816435932101],[-1.682453680575476,49.65814336288646],[-1.682345827490233,49.65812297260189],[-1.682233236042189,49.658107136908164],[-1.682123664688506,49.6580979810145],[-1.682014125147201,49.65808272714925],[-1.681904761130945,49.658071280114264],[-1.681797002800972,49.65805876350617],[-1.681580726631921,49.658023917601746],[-1.681473886690803,49.65801145113601],[-1.68136716295708,49.65799711930074],[-1.68126114165059,49.657983438468484],[-1.681110470795186,49.65796302152122],[-1.681041500542145,49.65795404484363],[-1.68093167446423,49.65794006745609],[-1.680756367723196,49.65791674545396],[-1.680650300094999,49.657902472140094],[-1.680544953383338,49.65789224832794],[-1.68044501573429,49.657874552005886],[-1.68034703628985,49.65786518043657],[-1.680244269316751,49.65785148058563],[-1.680161831826119,49.65783718652244],[-1.680092302984831,49.65782779623007],[-1.680008059258093,49.65781712301027],[-1.679921209671613,49.65780484569685],[-1.679752365909624,49.657782314814504],[-1.67968053626866,49.65777343231517],[-1.679465260113473,49.657744736240076],[-1.679356242520934,49.65773116224051],[-1.679204681506407,49.65771085345038],[-1.679075473908005,49.65768786006316],[-1.679026837248203,49.65768184914107],[-1.67897866340961,49.65767344885779],[-1.678926035329053,49.65766477377808],[-1.678883054155872,49.65765933940972],[-1.678846191645214,49.65765192143305],[-1.678785217146016,49.657641742870545],[-1.678752083502674,49.657632600450846],[-1.678752083502674,49.657632600450846]],type:`LineString`},id:`12`,properties:{ampacity:325,approximate_nominal_voltage:2e4,bus1_id:`MVBus22602`,bus2_id:`MVBus22603`,element_type:`line`,id:`MVBranch47802`,insulator:null,length:.6082420532559634,line_type:`underground`,material:`aac`,max_loading:100,network:`MV Feeder 217`,parameters_id:`U_AL_150`,phases:`abc`,section:150},type:`Feature`},{bbox:[-1.6899144761105565,49.657320094654246,-1.687000916584208,49.65875235679245],geometry:{coordinates:[[-1.6899144761105565,49.65734579505471],[-1.689902106191688,49.65734719597764],[-1.689893952537334,49.65733253099631],[-1.689883517880255,49.657327042259574],[-1.689866566150205,49.65732760652712],[-1.689851832710317,49.65732714375777],[-1.689837756416026,49.657320094654246],[-1.689811194338158,49.65732472864215],[-1.689770822990218,49.65734147643931],[-1.68974781289917,49.65735056931736],[-1.689639749072734,49.657403291763586],[-1.689584894501837,49.65743133942712],[-1.689495601152914,49.657486359498435],[-1.689369875436402,49.657567141318275],[-1.689210031692182,49.65767072116982],[-1.689133511386455,49.65772489319007],[-1.688932299690713,49.657873138758184],[-1.688824045288466,49.65796416534145],[-1.688729443121585,49.658049333075624],[-1.688672923286662,49.65809700313144],[-1.688567768981974,49.6581783583668],[-1.688447336562443,49.65826937611586],[-1.688292981370783,49.658385675994005],[-1.688230391886822,49.65843771123023],[-1.688178301282593,49.65846026177342],[-1.688100506152315,49.65850656213375],[-1.68805498079456,49.65852963155985],[-1.68801859926527,49.65854728007973],[-1.687985278906541,49.65856282143969],[-1.68797193962116,49.65856756360029],[-1.687904903945472,49.65859592573689],[-1.687836406772483,49.658618761177216],[-1.687773406152993,49.65864173744049],[-1.687707055307805,49.65866421364127],[-1.687632341914936,49.658685340380906],[-1.687597756271063,49.658693981598304],[-1.6875535692144,49.65870295120399],[-1.687513904909563,49.65871218398774],[-1.687477338221695,49.658720998979575],[-1.687435773069277,49.658727911989054],[-1.687385894109799,49.65873725072297],[-1.687284757646732,49.658750749410686],[-1.687245627175155,49.65875235679245],[-1.687226644410474,49.65875176526927],[-1.687185800600312,49.65874974274826],[-1.687137085084551,49.65874398943454],[-1.687033931127971,49.65873175588405],[-1.687000916584208,49.65872643345839],[-1.687000916584208,49.65872643345839]],type:`LineString`},id:`13`,properties:{ampacity:325,approximate_nominal_voltage:2e4,bus1_id:`MVBus21726`,bus2_id:`MVBus22602`,element_type:`line`,id:`MVBranch43082`,insulator:null,length:.27575724267606383,line_type:`underground`,material:`aac`,max_loading:100,network:`MV Feeder 217`,parameters_id:`U_AL_150`,phases:`abc`,section:150},type:`Feature`},{bbox:[-1.693418858866021,49.65682690034362,-1.6899144761105565,49.65734579505471],geometry:{coordinates:[[-1.6931544029856775,49.65682690034362],[-1.693152510105437,49.656832830966096],[-1.693140690954655,49.65683523901614],[-1.6931427118128,49.65683942511384],[-1.693151481587454,49.65684750491125],[-1.693209476595427,49.65690091227353],[-1.693252669441853,49.65691759306439],[-1.693316316485088,49.656947701527976],[-1.693373238151906,49.656981046487076],[-1.693400287616367,49.657004307973416],[-1.693417151422491,49.65703119104043],[-1.693418858866021,49.657062598676404],[-1.693374304427203,49.65708774214384],[-1.693298166698752,49.65712023250288],[-1.693244050883247,49.65714217841551],[-1.69316248707433,49.657169813689386],[-1.693107868783109,49.65718522978719],[-1.692888546978312,49.65723633810071],[-1.692779778709486,49.65726048203007],[-1.692698423186007,49.65727621305517],[-1.692654583441833,49.657281315287605],[-1.692542193906826,49.657285058904975],[-1.692484466808352,49.65728620836523],[-1.692424940469563,49.657286851204006],[-1.692292977895417,49.65728550935727],[-1.692259680432823,49.65728221209627],[-1.692186219099461,49.657281979071804],[-1.692110428824001,49.65727856831186],[-1.692049488588526,49.65727656932213],[-1.691962037720081,49.65727547120089],[-1.691854401241619,49.65727450571742],[-1.69169634795539,49.65727709853729],[-1.691577772454402,49.65727863729285],[-1.691391974011256,49.657284563616756],[-1.691212884622486,49.65729212768768],[-1.69108212142755,49.65730193115109],[-1.690998013026594,49.65731000121259],[-1.690813290305129,49.657319550737675],[-1.690697196909293,49.65732322711233],[-1.69051864108191,49.657326150283794],[-1.690323406593425,49.65732380134952],[-1.690219763089159,49.65731972499459],[-1.690038602812441,49.65730440762694],[-1.689973494217544,49.65730382327296],[-1.689957419253372,49.65730619281971],[-1.689938164927739,49.6573130295151],[-1.689928953469567,49.65731723884458],[-1.689922508665218,49.65732525878499],[-1.689926846029425,49.65734439413178],[-1.6899144761105565,49.65734579505471]],type:`LineString`},id:`14`,properties:{ampacity:325,approximate_nominal_voltage:2e4,bus1_id:`MVLV09710`,bus2_id:`MVBus21726`,element_type:`line`,id:`MVBranch42413`,insulator:null,length:.29618321913091505,line_type:`underground`,material:`aac`,max_loading:100,network:`MV Feeder 217`,parameters_id:`U_AL_150`,phases:`abc`,section:150},type:`Feature`},{bbox:[-1.694653623707265,49.656818451549476,-1.692711097980776,49.65733100782697],geometry:{coordinates:[[-1.694653623707265,49.657307207334895],[-1.694653623707265,49.657307207334895],[-1.694648566234924,49.657308239155654],[-1.694616194921495,49.657292834828844],[-1.694596778440511,49.65726626179332],[-1.694512415501688,49.65720139614901],[-1.694445549994414,49.65717316705252],[-1.694191078550513,49.65711696436926],[-1.694134447528161,49.6571158569682],[-1.69406229696653,49.65711800936961],[-1.693954598809285,49.6571400864365],[-1.693845082201221,49.65717595544083],[-1.69371451513302,49.6572215181459],[-1.693658901335396,49.65723923375691],[-1.693418375417,49.657295635655856],[-1.693343187764655,49.65731071200743],[-1.693264776748028,49.65731970890518],[-1.693142450457068,49.657327246203685],[-1.693015767034796,49.65733100782697],[-1.692887212891164,49.657323546138336],[-1.692811884510095,49.65731494078992],[-1.692721682262498,49.65728324371582],[-1.692711097980776,49.65728077265942],[-1.692711156367779,49.657279583714285],[-1.692735809065025,49.657273753742984],[-1.692739415519118,49.65727153837497],[-1.692740306193944,49.657266859621686],[-1.692772970921632,49.65725584390002],[-1.693065527594914,49.657190012477756],[-1.693106803183528,49.657178934615764],[-1.693158118507119,49.65716379041707],[-1.693240604745891,49.657135908596906],[-1.693368485511657,49.6570808949317],[-1.693409573087288,49.657057629485564],[-1.693405926102143,49.65703585441595],[-1.693390492821437,49.65701024557583],[-1.693365773667793,49.656988426172354],[-1.693308320628536,49.656955017980884],[-1.693248146998977,49.65692591785079],[-1.693207826064977,49.656910346367596],[-1.693125303768984,49.65683596744389],[-1.693128378483538,49.65682842827083],[-1.693130756861769,49.65682259388035],[-1.693135790036104,49.656818451549476],[-1.693156295865918,49.656820969721146],[-1.6931544029856775,49.65682690034362]],type:`LineString`},id:`15`,properties:{ampacity:325,approximate_nominal_voltage:2e4,bus1_id:`MVBus20891`,bus2_id:`MVLV09710`,element_type:`line`,id:`MVBranch37274`,insulator:null,length:.2472968140411514,line_type:`underground`,material:`aac`,max_loading:100,network:`MV Feeder 217`,parameters_id:`U_AL_150`,phases:`abc`,section:150},type:`Feature`},{bbox:[-1.694972633356441,49.657307207334895,-1.694653623707265,49.657574856348404],geometry:{coordinates:[[-1.694881325517064,49.65753685714968],[-1.694881325517064,49.65753685714968],[-1.694870805593646,49.657538529645755],[-1.694867677118124,49.657541007914595],[-1.694864664470505,49.6575433744138],[-1.694863785438515,49.657545570887244],[-1.694864353970346,49.65754890611801],[-1.694865902262429,49.65755131844428],[-1.694869182876066,49.657554266536636],[-1.694872469706283,49.65755554182855],[-1.694900047651829,49.65756428058578],[-1.69495085752137,49.657573045378875],[-1.69497044900775,49.657574856348404],[-1.694972621131005,49.65757359695261],[-1.694972633356441,49.6575718250351],[-1.694970869752442,49.657570193235706],[-1.694950269519778,49.65756263374962],[-1.694811584170032,49.6574286644253],[-1.694754658072436,49.65738985285587],[-1.694675833199034,49.65732705985422],[-1.694653623707265,49.657307207334895],[-1.694653623707265,49.657307207334895]],type:`LineString`},id:`16`,properties:{ampacity:325,approximate_nominal_voltage:2e4,bus1_id:`MVBus20890`,bus2_id:`MVBus20891`,element_type:`line`,id:`MVBranch38558`,insulator:null,length:.0485068386520877,line_type:`underground`,material:`aac`,max_loading:100,network:`MV Feeder 217`,parameters_id:`U_AL_150`,phases:`abc`,section:150},type:`Feature`},{bbox:[-1.6956447814282445,49.65752805771521,-1.694881325517064,49.657635245435976],geometry:{coordinates:[[-1.6956447814282445,49.65763502482898],[-1.695624540251472,49.657635245435976],[-1.69561746988984,49.65762308953775],[-1.695596591587301,49.657584524501154],[-1.694976984193771,49.65752805771521],[-1.694881325517064,49.65753685714968],[-1.694881325517064,49.65753685714968]],type:`LineString`},id:`17`,properties:{ampacity:325,approximate_nominal_voltage:2e4,bus1_id:`MVLV12764`,bus2_id:`MVBus20890`,element_type:`line`,id:`MVBranch39585`,insulator:null,length:.058144213787439426,line_type:`underground`,material:`aac`,max_loading:100,network:`MV Feeder 217`,parameters_id:`U_AL_150`,phases:`abc`,section:150},type:`Feature`},{bbox:[-1.697840623409652,49.656686811786194,-1.6956447814282445,49.65763502482898],geometry:{coordinates:[[-1.697825356573214,49.65683842436038],[-1.697835514737378,49.65683550921616],[-1.697838602035088,49.65682218732805],[-1.697840623409652,49.65681342419931],[-1.697778838018975,49.656686811786194],[-1.697146739811798,49.65684296795896],[-1.69739248718273,49.65756831420456],[-1.696496172131778,49.65761570120611],[-1.696265553264628,49.65763343469004],[-1.695681449886193,49.65758803548188],[-1.695669456761429,49.65762239072309],[-1.695665022605017,49.65763480422198],[-1.6956447814282445,49.65763502482898]],type:`LineString`},id:`18`,properties:{ampacity:325,approximate_nominal_voltage:2e4,bus1_id:`MVLV08518`,bus2_id:`MVLV12764`,element_type:`line`,id:`MVBranch39229`,insulator:null,length:.2782026664562803,line_type:`underground`,material:`aac`,max_loading:100,network:`MV Feeder 217`,parameters_id:`U_AL_150`,phases:`abc`,section:150},type:`Feature`},{bbox:[-1.699553504846526,49.65672671709386,-1.697218490084788,49.657565011758095],geometry:{coordinates:[[-1.699553504846526,49.65715834002786],[-1.699539917015647,49.65716648646911],[-1.699532716875093,49.657179118335385],[-1.699439304912264,49.6573431103775],[-1.699263351694736,49.65739605663836],[-1.699336463270182,49.65745834504667],[-1.699268465181139,49.657458014960646],[-1.69920943625858,49.65746546981428],[-1.699113182504093,49.657408485634605],[-1.698304527016932,49.65755999876808],[-1.698062893911774,49.6575567010572],[-1.697461583041591,49.657565011758095],[-1.697218490084788,49.656871994905885],[-1.697744693442282,49.65672671709386],[-1.697786406850478,49.65682882008235],[-1.697797954859862,49.656833839394665],[-1.69781519840905,49.6568413395046],[-1.697825356573214,49.65683842436038]],type:`LineString`},id:`19`,properties:{ampacity:325,approximate_nominal_voltage:2e4,bus1_id:`MVLV15647`,bus2_id:`MVLV08518`,element_type:`line`,id:`MVBranch43708`,insulator:null,length:.3185546944113785,line_type:`underground`,material:`aac`,max_loading:100,network:`MV Feeder 217`,parameters_id:`U_AL_150`,phases:`abc`,section:150},type:`Feature`},{bbox:[-1.700642458227036,49.65663345325234,-1.699553504846526,49.65715834002786],geometry:{coordinates:[[-1.7005694121374195,49.65663345325234],[-1.700567982202967,49.656634112466065],[-1.700578541704473,49.65664571103876],[-1.700633692345302,49.6567063051086],[-1.700642458227036,49.656812258665404],[-1.700306136582797,49.65692212180891],[-1.699922879766692,49.65708494217042],[-1.699587068199308,49.65714653256768],[-1.699567092677405,49.65715019358661],[-1.699553504846526,49.65715834002786]],type:`LineString`},id:`20`,properties:{ampacity:325,approximate_nominal_voltage:2e4,bus1_id:`MVLV11487`,bus2_id:`MVLV15647`,element_type:`line`,id:`MVBranch39714`,insulator:null,length:.10807935641066367,line_type:`underground`,material:`aac`,max_loading:100,network:`MV Feeder 217`,parameters_id:`U_AL_150`,phases:`abc`,section:150},type:`Feature`},{bbox:[-1.701866146588843,49.656632794038615,-1.7005694121374195,49.65687343948882],geometry:{coordinates:[[-1.7018474404969435,49.65682712281345],[-1.701845819779519,49.6568245870875],[-1.701862948465297,49.65681699209384],[-1.701866146588843,49.656815572417344],[-1.70151764275735,49.65681149732632],[-1.701052135176404,49.656834914108856],[-1.700747383895348,49.65687343948882],[-1.700678846977321,49.65671554402016],[-1.700584261442887,49.65664307418332],[-1.700570842071872,49.656632794038615],[-1.7005694121374195,49.65663345325234]],type:`LineString`},id:`21`,properties:{ampacity:325,approximate_nominal_voltage:2e4,bus1_id:`MVLV08517`,bus2_id:`MVLV11487`,element_type:`line`,id:`MVBranch48139`,insulator:null,length:.11338442666594911,line_type:`underground`,material:`aac`,max_loading:100,network:`MV Feeder 217`,parameters_id:`U_AL_150`,phases:`abc`,section:150},type:`Feature`},{bbox:[-1.704537865828387,49.65679434696009,-1.7018474404969435,49.657095165588956],geometry:{coordinates:[[-1.7044656244128835,49.657095165588956],[-1.70446457262951,49.65709255693235],[-1.704483189309966,49.65708661143169],[-1.704537865828387,49.65706917381683],[-1.704527658725012,49.65679488388282],[-1.704336196685355,49.65679434696009],[-1.701970101623435,49.65681465555627],[-1.701869445153427,49.656827134535476],[-1.701849061214368,49.65682965853941],[-1.7018474404969435,49.65682712281345]],type:`LineString`},id:`22`,properties:{ampacity:325,approximate_nominal_voltage:2e4,bus1_id:`MVLV08514`,bus2_id:`MVLV08517`,element_type:`line`,id:`MVBranch34514`,insulator:null,length:.22999332122252053,line_type:`underground`,material:`aac`,max_loading:100,network:`MV Feeder 217`,parameters_id:`U_AL_150`,phases:`abc`,section:150},type:`Feature`},{bbox:[-1.704600877122317,49.65632654314429,-1.7044656244128835,49.657097774245564],geometry:{coordinates:[[-1.704521667859076,49.65632654314429],[-1.704517901734163,49.656329533078605],[-1.704529522185396,49.65634070022345],[-1.704551489265828,49.65636181811624],[-1.704600877122317,49.65709309298921],[-1.70448739715825,49.657097055026256],[-1.704466676196257,49.657097774245564],[-1.7044656244128835,49.657095165588956]],type:`LineString`},id:`23`,properties:{ampacity:325,approximate_nominal_voltage:2e4,bus1_id:`MVLV08515`,bus2_id:`MVLV08514`,element_type:`line`,id:`MVBranch48138`,insulator:null,length:.0954492734387459,line_type:`underground`,material:`aac`,max_loading:100,network:`MV Feeder 217`,parameters_id:`U_AL_150`,phases:`abc`,section:150},type:`Feature`},{bbox:[-1.7065522989454331,49.65632355320998,-1.704521667859076,49.65866156864659],geometry:{coordinates:[[-1.7065522989454331,49.658565793845284],[-1.706541827948999,49.65857742491355],[-1.706531335866019,49.658589052188546],[-1.706465928106193,49.65866156864659],[-1.706357742718672,49.65844381625389],[-1.706249486789871,49.65787307454641],[-1.706179981081413,49.65731809616411],[-1.705463418519071,49.65740881212725],[-1.705422985876509,49.65730576926649],[-1.705572328002484,49.65728345028136],[-1.705621360881812,49.657255634576565],[-1.705643949030106,49.657226931042544],[-1.705636377162732,49.657185773595714],[-1.705617410761321,49.65715761340412],[-1.705003391939472,49.656878257686316],[-1.704779965956333,49.65682661494423],[-1.704621314587347,49.656820432037435],[-1.704585739342022,49.656339910157776],[-1.704544587394893,49.65632874945311],[-1.704525433983989,49.65632355320998],[-1.704521667859076,49.65632654314429]],type:`LineString`},id:`24`,properties:{ampacity:325,approximate_nominal_voltage:2e4,bus1_id:`MVLV12761`,bus2_id:`MVLV08515`,element_type:`line`,id:`MVBranch38115`,insulator:null,length:.3950658324564448,line_type:`underground`,material:`aac`,max_loading:100,network:`MV Feeder 217`,parameters_id:`U_AL_150`,phases:`abc`,section:150},type:`Feature`},{bbox:[-1.707912555263027,49.65821598234879,-1.7065522989454331,49.658565793845284],geometry:{coordinates:[[-1.7079120407255814,49.65821598234879],[-1.707912555263027,49.65822098296406],[-1.707893846422766,49.658226815163104],[-1.70728082013845,49.658417934068844],[-1.706987688532517,49.65839573781715],[-1.706732680877934,49.65836500960757],[-1.706573219851772,49.65854252791546],[-1.706562769941867,49.658554162777016],[-1.7065522989454331,49.658565793845284]],type:`LineString`},id:`25`,properties:{ampacity:325,approximate_nominal_voltage:2e4,bus1_id:`MVLV11486`,bus2_id:`MVLV12761`,element_type:`line`,id:`MVBranch35158`,insulator:null,length:.1149889768842972,line_type:`underground`,material:`aac`,max_loading:100,network:`MV Feeder 217`,parameters_id:`U_AL_150`,phases:`abc`,section:150},type:`Feature`},{bbox:[-1.708997902725297,49.657271455070045,-1.707765211274663,49.65821598234879],geometry:{coordinates:[[-1.708997902725297,49.65748382115472],[-1.708997902725297,49.65748382115472],[-1.70899080914577,49.65749200778738],[-1.708641350771502,49.65735922107077],[-1.708317824143707,49.657271455070045],[-1.708232158722505,49.65749326945597],[-1.708031958614799,49.65762181227458],[-1.707995714311626,49.657971564930534],[-1.707765211274663,49.658052551836846],[-1.707832434285355,49.6581942833001],[-1.707891788280491,49.65820681270175],[-1.707911526188136,49.65821098173353],[-1.7079120407255814,49.65821598234879]],type:`LineString`},id:`26`,properties:{ampacity:325,approximate_nominal_voltage:2e4,bus1_id:`MVBus13302`,bus2_id:`MVLV11486`,element_type:`line`,id:`MVBranch44963`,insulator:null,length:.181775916833722,line_type:`underground`,material:`aac`,max_loading:100,network:`MV Feeder 217`,parameters_id:`U_AL_150`,phases:`abc`,section:150},type:`Feature`},{bbox:[-1.709340489381714,49.65664595843759,-1.708997902725297,49.65748382115472],geometry:{coordinates:[[-1.7093355253425884,49.65668006698276],[-1.709340489381714,49.65667367361657],[-1.709329753267087,49.6566621445962],[-1.709314685856429,49.65664595843759],[-1.70925708239761,49.65667047439064],[-1.7091817362423,49.65671543026812],[-1.709140181584584,49.65676640494441],[-1.709119175557376,49.656831071376075],[-1.709128857491687,49.65691448596497],[-1.709231752244283,49.65718554132338],[-1.709204094962056,49.657270249726935],[-1.709079928431331,49.65741235692905],[-1.709050308659278,49.65742330230102],[-1.708997902725297,49.65748382115472],[-1.708997902725297,49.65748382115472]],type:`LineString`},id:`27`,properties:{ampacity:325,approximate_nominal_voltage:2e4,bus1_id:`MVLV15648`,bus2_id:`MVBus13302`,element_type:`line`,id:`MVBranch36355`,insulator:null,length:.10806723339486324,line_type:`underground`,material:`aac`,max_loading:100,network:`MV Feeder 217`,parameters_id:`U_AL_150`,phases:`abc`,section:150},type:`Feature`},{bbox:[-1.7093355253425884,49.65668006698276,-1.709027337065763,49.6575131235305],geometry:{coordinates:[[-1.709027337065763,49.6575131235305],[-1.709027337065763,49.6575131235305],[-1.709078447439429,49.65744483349543],[-1.70910413685254,49.65743672632054],[-1.709243868571788,49.65728147298309],[-1.70927004463494,49.657178802084346],[-1.709171592842444,49.65691119515829],[-1.709161114035063,49.656835019230506],[-1.709178943717271,49.65678216730157],[-1.709213577618374,49.65673143308517],[-1.709282230422975,49.65668940781868],[-1.709309897104711,49.656687718058556],[-1.709330561303463,49.65668646034894],[-1.7093355253425884,49.65668006698276]],type:`LineString`},id:`28`,properties:{ampacity:325,approximate_nominal_voltage:2e4,bus1_id:`MVBus12338`,bus2_id:`MVLV15648`,element_type:`line`,id:`MVBranch47369`,insulator:null,length:.10369591850421968,line_type:`underground`,material:`aac`,max_loading:100,network:`MV Feeder 217`,parameters_id:`U_AL_150`,phases:`abc`,section:150},type:`Feature`},{bbox:[-1.7102518017180843,49.6575131235305,-1.709027236507815,49.65805029431179],geometry:{coordinates:[[-1.7102518017180843,49.65805029431179],[-1.710237028957051,49.65804681383888],[-1.710235630991269,49.65803409122527],[-1.710233210541606,49.65798894880261],[-1.709742877897143,49.65781336148406],[-1.709027236507815,49.657513252788995],[-1.709027337065763,49.6575131235305],[-1.709027337065763,49.6575131235305]],type:`LineString`},id:`29`,properties:{ampacity:325,approximate_nominal_voltage:2e4,bus1_id:`MVLV04334`,bus2_id:`MVBus12338`,element_type:`line`,id:`MVBranch32752`,insulator:null,length:.10840662368023206,line_type:`underground`,material:`aac`,max_loading:100,network:`MV Feeder 217`,parameters_id:`U_AL_150`,phases:`abc`,section:150},type:`Feature`},{bbox:[-1.712256396489699,49.658025946056945,-1.7102518017180843,49.658696483631566],geometry:{coordinates:[[-1.712256396489699,49.658696483631566],[-1.712256396489699,49.658696483631566],[-1.710321852037981,49.658025946056945],[-1.710282778109626,49.658045355239715],[-1.710266574479118,49.65805377478471],[-1.7102518017180843,49.65805029431179]],type:`LineString`},id:`30`,properties:{ampacity:325,approximate_nominal_voltage:2e4,bus1_id:`MVBus11449`,bus2_id:`MVLV04334`,element_type:`line`,id:`MVBranch39715`,insulator:null,length:.1633930998192143,line_type:`underground`,material:`aac`,max_loading:100,network:`MV Feeder 217`,parameters_id:`U_AL_150`,phases:`abc`,section:150},type:`Feature`},{bbox:[-1.712391430825098,49.65869383173553,-1.712256396489699,49.658722602724524],geometry:{coordinates:[[-1.7123893567716906,49.65869383173553],[-1.712391430825098,49.65869962544148],[-1.712366463491168,49.65870984935149],[-1.712329867044583,49.658722602724524],[-1.712256396489699,49.658696483631566],[-1.712256396489699,49.658696483631566]],type:`LineString`},id:`31`,properties:{ampacity:325,approximate_nominal_voltage:2e4,bus1_id:`MVLV12762`,bus2_id:`MVBus11449`,element_type:`line`,id:`MVBranch40786`,insulator:null,length:.011178451298859964,line_type:`underground`,material:`aac`,max_loading:100,network:`MV Feeder 217`,parameters_id:`U_AL_150`,phases:`abc`,section:150},type:`Feature`},{bbox:[-1.7123893567716906,49.657020368759845,-1.710900130160686,49.65869383173553],geometry:{coordinates:[[-1.712231384433458,49.65739404176467],[-1.712231384433458,49.65739404176467],[-1.712192984930894,49.6574121610954],[-1.712159321627441,49.65741875531577],[-1.712145875642629,49.657418288129165],[-1.712130679684726,49.65741375193847],[-1.712115156745159,49.65740509911443],[-1.711907540458581,49.657280918818046],[-1.711916605385292,49.65727052579175],[-1.711725937688394,49.65713753178156],[-1.711583842498299,49.65702903526348],[-1.711572488149354,49.657020368759845],[-1.711558455636018,49.657020712484226],[-1.711543004997499,49.65702168818157],[-1.71152412661641,49.6570241544492],[-1.711495638379682,49.657030152654194],[-1.711471050112896,49.657040606532085],[-1.711427640974446,49.65706314674895],[-1.711326401126814,49.65713576828944],[-1.711178373342992,49.657241591156435],[-1.711129545502673,49.65730718898692],[-1.710964863616365,49.65743007013069],[-1.710917324898205,49.657471785508555],[-1.710902208297853,49.65748604090393],[-1.710900130160686,49.657490921444534],[-1.710903842733294,49.65750662407541],[-1.710943091855127,49.65756513807867],[-1.711091955908279,49.65770985551921],[-1.711172613908541,49.657764933515004],[-1.71127897930944,49.657801489868255],[-1.711395063912293,49.657840247784556],[-1.711606505041342,49.65791019285251],[-1.711681734703578,49.65793702679832],[-1.711779863054719,49.65798096249784],[-1.711870622953638,49.6580343261077],[-1.712056337251808,49.6581450223316],[-1.712245397356525,49.65826661315606],[-1.712324524894339,49.658324718178164],[-1.712350010711977,49.65834770431951],[-1.712353846470791,49.65836041726462],[-1.712354377241995,49.65837599254943],[-1.712347265709976,49.65839319050284],[-1.712216987090673,49.65855367044792],[-1.71219274716793,49.65857305135032],[-1.712191541104686,49.65858890957691],[-1.712193644176653,49.65860649152026],[-1.712198457245705,49.65861825451696],[-1.712223707211668,49.65863391067126],[-1.71235660303629,49.6586886063232],[-1.712366471624233,49.65869286219185],[-1.712372867915333,49.658693340519584],[-1.712387282718283,49.658688038029595],[-1.7123893567716906,49.65869383173553]],type:`LineString`},id:`32`,properties:{ampacity:325,approximate_nominal_voltage:2e4,bus1_id:`MVBus09389`,bus2_id:`MVLV12762`,element_type:`line`,id:`MVBranch33113`,insulator:null,length:.33609166663042095,line_type:`underground`,material:`aac`,max_loading:100,network:`MV Feeder 217`,parameters_id:`U_AL_150`,phases:`abc`,section:150},type:`Feature`},{bbox:[-1.713518356067376,49.65552876662905,-1.711668127535593,49.65739404176467],geometry:{coordinates:[[-1.7134923699166786,49.656042385779635],[-1.713485327983641,49.65603534658393],[-1.713509722594212,49.65601863092429],[-1.713518356067376,49.65600176855485],[-1.713516623396457,49.6559923394178],[-1.71339757826996,49.65586730012102],[-1.713061830997298,49.65552876662905],[-1.713022374869907,49.655547164491274],[-1.712983219393751,49.65556934713522],[-1.712941021202669,49.6555887989746],[-1.712115718830422,49.65593034753014],[-1.711730719092233,49.65608848126368],[-1.711675834553732,49.65611913028859],[-1.711668127535593,49.65613859631369],[-1.711689943331042,49.656157074266176],[-1.711909209699889,49.65638021466925],[-1.711927197560893,49.656420429795006],[-1.712045895311028,49.65654130047773],[-1.712066626044882,49.65665720397143],[-1.712493720851563,49.65708091694548],[-1.712596763887438,49.657184290066596],[-1.712616120654328,49.65720371345815],[-1.712605257166425,49.65721761988691],[-1.712231384433458,49.65739404176467],[-1.712231384433458,49.65739404176467]],type:`LineString`},id:`33`,properties:{ampacity:325,approximate_nominal_voltage:2e4,bus1_id:`MVLV16887`,bus2_id:`MVBus09389`,element_type:`line`,id:`MVBranch38550`,insulator:null,length:.36205172525827967,line_type:`underground`,material:`aac`,max_loading:100,network:`MV Feeder 217`,parameters_id:`U_AL_150`,phases:`abc`,section:150},type:`Feature`},{bbox:[-1.715571036710964,49.654538430245495,-1.713073893758862,49.65604942497534],geometry:{coordinates:[[-1.715447633958364,49.654538430245495],[-1.715447633958364,49.654538430245495],[-1.715448192070262,49.65460696204013],[-1.715457004433096,49.6546500380675],[-1.715471451256319,49.65469969675278],[-1.715498603110257,49.654796617488635],[-1.715526802946384,49.65491560687598],[-1.715556713031621,49.65504286608316],[-1.715567040711619,49.65508827435797],[-1.715570275973833,49.6551110251187],[-1.715571036710964,49.655132617801705],[-1.715564102439639,49.65519436836121],[-1.71555179727194,49.655249716275684],[-1.715530624332355,49.655313742345704],[-1.715489586974421,49.65542933186875],[-1.715414558894032,49.65562509579396],[-1.715402884330536,49.6556427256538],[-1.715388083085744,49.65565639560863],[-1.715372240448655,49.65566236683133],[-1.715351608436699,49.65566524317796],[-1.715312147792104,49.655666672968934],[-1.715260598108026,49.65566222189718],[-1.715152477351462,49.65563005324065],[-1.71508526536511,49.655598465577974],[-1.715020937895638,49.65555803148393],[-1.71498123049807,49.65552202435255],[-1.714894808491883,49.65542981362902],[-1.714823166712625,49.655365839066796],[-1.71474497215027,49.655310563942564],[-1.714658157317202,49.65526289744951],[-1.714576855973218,49.65523301340164],[-1.714461502531446,49.655200277069156],[-1.71438049769835,49.65518701922765],[-1.714302012179009,49.655179666014696],[-1.714125088683956,49.655184925691366],[-1.714045455182909,49.65518892341494],[-1.713974032499748,49.65520595513098],[-1.713930000794875,49.65521940775234],[-1.713805483504456,49.65526483536296],[-1.713580541187305,49.65536220340899],[-1.713317541539384,49.65547082699354],[-1.713257574448967,49.655490136501335],[-1.713201716977964,49.65549666483663],[-1.713154040780268,49.65549755066954],[-1.713105457586083,49.65549730680938],[-1.713073893758862,49.65551479298841],[-1.713232659435066,49.655672728402635],[-1.713342741318447,49.65578643159105],[-1.713512475201262,49.655959133893184],[-1.713535733563725,49.65598425370082],[-1.713540888669226,49.65600398162917],[-1.713529570082037,49.65603080774028],[-1.713499411849716,49.65604942497534],[-1.7134923699166786,49.656042385779635]],type:`LineString`},id:`34`,properties:{ampacity:325,approximate_nominal_voltage:2e4,bus1_id:`MVBus01888`,bus2_id:`MVLV16887`,element_type:`line`,id:`MVBranch37385`,insulator:null,length:.39624899055842877,line_type:`underground`,material:`aac`,max_loading:100,network:`MV Feeder 217`,parameters_id:`U_AL_150`,phases:`abc`,section:150},type:`Feature`},{bbox:[-1.723625804781101,49.65334802969377,-1.715447633958364,49.657693756377626],geometry:{coordinates:[[-1.723625804781101,49.65673682886024],[-1.723625804781101,49.65673682886024],[-1.723520377064923,49.656727616140266],[-1.723422239509832,49.65671706153705],[-1.723311255510849,49.65671043616149],[-1.723198071900167,49.65669323725738],[-1.723127687111947,49.65669077053708],[-1.722701786187468,49.65666164777939],[-1.722598063002425,49.65666565914847],[-1.722487643297865,49.65665811482743],[-1.721660003373815,49.65657170621557],[-1.721549796078765,49.65656682472705],[-1.721538047690914,49.65656453908364],[-1.721481223908684,49.65654553767339],[-1.721465358631225,49.656543390140634],[-1.721448147102664,49.65654503768671],[-1.721255295561688,49.65660136244499],[-1.721069041713968,49.65666818473525],[-1.720715544870907,49.65682262907381],[-1.720625975255681,49.656869589236436],[-1.720559774543294,49.656919515420164],[-1.720502049314613,49.65697237663683],[-1.720432929839997,49.657027229656556],[-1.720368762404759,49.65707172793302],[-1.720011956842451,49.65733730345117],[-1.719951248175017,49.65738715296471],[-1.719840359650761,49.65746667914164],[-1.719546904359343,49.65767631694214],[-1.719519017524534,49.65769091177698],[-1.719509007047312,49.657693756377626],[-1.719501528831518,49.657691866901644],[-1.71947780320136,49.6576811159884],[-1.719446489720156,49.65766692355118],[-1.719227931378966,49.657576259766756],[-1.71900357914789,49.657490762758826],[-1.718885676065933,49.65744245086185],[-1.718681878423483,49.657368404133045],[-1.718654363643581,49.65735999227237],[-1.718534760648144,49.657332267095995],[-1.718410586473253,49.65730750072945],[-1.718162801127251,49.657240835877104],[-1.718011097134541,49.6571830809291],[-1.717981256567952,49.65716945924549],[-1.717977370360496,49.65716274615818],[-1.718043519437144,49.657084622500825],[-1.718045612695117,49.65708081142184],[-1.718041416313051,49.657076293929585],[-1.717999506135629,49.65704938112844],[-1.717887107372415,49.65698595611869],[-1.717832819310818,49.656942048523675],[-1.717730881850192,49.65680516306199],[-1.717691274506387,49.65674084477619],[-1.71767883685665,49.6567110825568],[-1.717562557812384,49.656502197440894],[-1.717554983546297,49.65648533842219],[-1.717554640217861,49.65643277929776],[-1.717493476214133,49.656356746702166],[-1.717495896332177,49.65633893221701],[-1.717447994085462,49.65618250205623],[-1.717439573011385,49.6561006550268],[-1.717461902305589,49.656001905449315],[-1.717487775937777,49.655815008627954],[-1.717500134567444,49.65563914002085],[-1.717514947328719,49.655542198021614],[-1.717514531824025,49.65544048776329],[-1.717503391856739,49.655336645997224],[-1.717488942745687,49.655245360880855],[-1.717460651659158,49.65514862256692],[-1.717420766249411,49.65506284813152],[-1.717375544103659,49.65497632630912],[-1.717274162708445,49.65478000763229],[-1.717167398701707,49.654606566567345],[-1.717061652365184,49.654433720776446],[-1.716959036949793,49.65427010427631],[-1.716914447426297,49.654185422525465],[-1.7168409726092,49.654008698305404],[-1.716811740245133,49.65391821420138],[-1.716763546412261,49.65375806135427],[-1.716732522799451,49.653638078556575],[-1.716689212363299,49.65343795173439],[-1.71667331127041,49.65336443948759],[-1.716670378709844,49.65335769438859],[-1.716662418509404,49.653353914472994],[-1.716653156141748,49.65335204865622],[-1.716596781264168,49.65334802969377],[-1.716559930839835,49.653348644085064],[-1.716551546324883,49.65335172175416],[-1.716544091,49.65336038866352],[-1.716472226277132,49.653426869160796],[-1.716395457773024,49.65349787533786],[-1.716316735389152,49.65356242728845],[-1.716236904998456,49.65364318499962],[-1.716023337473649,49.65386188282999],[-1.715893174600961,49.65400872264407],[-1.715704903113184,49.65422035831509],[-1.71553225529787,49.65439942059411],[-1.715471504984857,49.65444283069003],[-1.715456092169358,49.65446605331468],[-1.715449572571996,49.65448649605519],[-1.715447633958364,49.654538430245495],[-1.715447633958364,49.654538430245495]],type:`LineString`},id:`35`,properties:{ampacity:325,approximate_nominal_voltage:2e4,bus1_id:`MVBus01887`,bus2_id:`MVBus01888`,element_type:`line`,id:`MVBranch43049`,insulator:null,length:1.0872513297341535,line_type:`underground`,material:`aac`,max_loading:100,network:`MV Feeder 217`,parameters_id:`U_AL_150`,phases:`abc`,section:150},type:`Feature`},{bbox:[-1.727382824582085,49.65673682886024,-1.723625804781101,49.65688309901938],geometry:{coordinates:[[-1.727382824582085,49.656858137125596],[-1.727382824582085,49.656858137125596],[-1.727255130419084,49.656876141052194],[-1.727120294379758,49.65688309901938],[-1.726979327246614,49.65688004717326],[-1.726843528677935,49.65687180364602],[-1.726712400318607,49.65686184736043],[-1.726577844568127,49.65685563908711],[-1.726303410859262,49.656853436636425],[-1.726171836378063,49.656854564681474],[-1.72585793709381,49.656842095274015],[-1.725666382306666,49.65683313312166],[-1.725605568753938,49.656832576567226],[-1.725485392503197,49.656832808501164],[-1.725251464483659,49.65683062826861],[-1.725025826734552,49.656825228625394],[-1.724798199183486,49.65682180180917],[-1.724685456448137,49.65681849206072],[-1.7245698809084,49.65681631146881],[-1.72445706960357,49.65681214051932],[-1.72435163705248,49.65680356715185],[-1.724250281210615,49.6567924378171],[-1.723947318268317,49.6567544799531],[-1.723840359322548,49.656747782887855],[-1.723728787517464,49.65674490955833],[-1.723625804781101,49.65673682886024],[-1.723625804781101,49.65673682886024]],type:`LineString`},id:`36`,properties:{ampacity:325,approximate_nominal_voltage:2e4,bus1_id:`MVBus01886`,bus2_id:`MVBus01887`,element_type:`line`,id:`MVBranch40756`,insulator:null,length:.2724446957927151,line_type:`underground`,material:`aac`,max_loading:100,network:`MV Feeder 217`,parameters_id:`U_AL_150`,phases:`abc`,section:150},type:`Feature`},{bbox:[-1.727739462930876,49.65677285538332,-1.727382824582085,49.656858137125596],geometry:{coordinates:[[-1.727739462930876,49.65677285538332],[-1.727739462930876,49.65677285538332],[-1.727707492689713,49.656786411383656],[-1.727596864159143,49.656817960710654],[-1.727485560714758,49.656841394270465],[-1.727382824582085,49.656858137125596],[-1.727382824582085,49.656858137125596]],type:`LineString`},id:`37`,properties:{ampacity:325,approximate_nominal_voltage:2e4,bus1_id:`MVBus01885`,bus2_id:`MVBus01886`,element_type:`line`,id:`MVBranch42412`,insulator:null,length:.027578746668158054,line_type:`underground`,material:`aac`,max_loading:100,network:`MV Feeder 217`,parameters_id:`U_AL_150`,phases:`abc`,section:150},type:`Feature`},{bbox:[-1.728312906960772,49.656559479695645,-1.727739462930876,49.65677285538332],geometry:{coordinates:[[-1.728312906960772,49.656559479695645],[-1.728312906960772,49.656559479695645],[-1.728274454180884,49.65656660814347],[-1.728233685202301,49.656576826950065],[-1.728205776997936,49.656585732281826],[-1.728161474180365,49.65660270638717],[-1.728061212388786,49.65664456408184],[-1.727946166206508,49.65668029090196],[-1.727817705683487,49.65673592842011],[-1.727739462930876,49.65677285538332],[-1.727739462930876,49.65677285538332]],type:`LineString`},id:`38`,properties:{ampacity:325,approximate_nominal_voltage:2e4,bus1_id:`MVBus01884`,bus2_id:`MVBus01885`,element_type:`line`,id:`MVBranch34037`,insulator:null,length:.047953236893901165,line_type:`underground`,material:`aac`,max_loading:100,network:`MV Feeder 217`,parameters_id:`U_AL_150`,phases:`abc`,section:150},type:`Feature`},{bbox:[-1.733888052209557,49.65595011823244,-1.728312906960772,49.656559479695645],geometry:{coordinates:[[-1.733888052209557,49.656314900145844],[-1.733888052209557,49.656314900145844],[-1.733820007778513,49.65628016708811],[-1.733763752106464,49.656247869986075],[-1.733710070903023,49.65621450602487],[-1.733640511623304,49.6561677376844],[-1.733539253676595,49.65610372684678],[-1.733467343239139,49.65606480720204],[-1.733343931417372,49.65601790833194],[-1.733283539586307,49.65600024638956],[-1.73320693907129,49.65598811172926],[-1.733134113689259,49.65598058015306],[-1.732764388265359,49.655963883059265],[-1.732455019590271,49.655959030137886],[-1.732308861926483,49.65595895590221],[-1.732156086784187,49.65595632535174],[-1.732071515123761,49.655956948938424],[-1.731988798417747,49.65595391300292],[-1.731813324684369,49.655956200132806],[-1.731619674397655,49.655955501280054],[-1.731515826317521,49.65595011823244],[-1.731404434610655,49.65595192214882],[-1.731288262322996,49.65596359881823],[-1.731171657834058,49.65598582931513],[-1.731065502343024,49.656015756745845],[-1.730869722261673,49.656073949329844],[-1.730761570787878,49.65611115571432],[-1.73043046871671,49.65621412200755],[-1.730326055201905,49.656244538733],[-1.730217744128323,49.656268989382525],[-1.729903556452437,49.65634230320746],[-1.729795845570611,49.656351535697574],[-1.729682898084139,49.65636597102383],[-1.729570647608569,49.65637438471132],[-1.729448850872821,49.65638989066015],[-1.729213793071298,49.65644594757036],[-1.729129184628637,49.65646852136912],[-1.729014250779628,49.6564953967068],[-1.728901490965555,49.65651601191794],[-1.728791966639698,49.65652491776152],[-1.728662672874595,49.65653622350812],[-1.728516880886691,49.65654596131145],[-1.728475245323393,49.65653576004882],[-1.728411991139697,49.65654194149451],[-1.728370140263912,49.656547799304136],[-1.728312906960772,49.656559479695645],[-1.728312906960772,49.656559479695645]],type:`LineString`},id:`39`,properties:{ampacity:325,approximate_nominal_voltage:2e4,bus1_id:`MVBus01883`,bus2_id:`MVBus01884`,element_type:`line`,id:`MVBranch42411`,insulator:null,length:.42800395801572233,line_type:`underground`,material:`aac`,max_loading:100,network:`MV Feeder 217`,parameters_id:`U_AL_150`,phases:`abc`,section:150},type:`Feature`},{bbox:[-1.740510884394161,49.656314900145844,-1.733888052209557,49.65987962629042],geometry:{coordinates:[[-1.740479446878883,49.65987962629042],[-1.740479446878883,49.65987962629042],[-1.740474071432376,49.65985329702724],[-1.740475099216177,49.65984155390997],[-1.740480619730333,49.659832635948426],[-1.74049378387742,49.65982090644167],[-1.740501648745728,49.65981254794499],[-1.740507517331799,49.65980382508198],[-1.740510880721519,49.65979668843317],[-1.740510884394161,49.659788594891516],[-1.74050937689303,49.65978204506886],[-1.740500875379599,49.65976997565485],[-1.740421007668303,49.659690249537704],[-1.74022852633044,49.659502935316866],[-1.740108664693464,49.65937833446222],[-1.739964296243733,49.6592305039367],[-1.739948388256929,49.659212083450164],[-1.739936335416193,49.65920098798228],[-1.739922300862214,49.65918953664039],[-1.739893746325947,49.659173035119764],[-1.739879121085537,49.65916649570173],[-1.739831249884304,49.659121688670226],[-1.739767953307384,49.659048211167374],[-1.739676058101628,49.65892459189616],[-1.739615603991094,49.658841441313264],[-1.739602095296559,49.65881612347223],[-1.739593072243265,49.65878938650556],[-1.739574501702686,49.658651578794704],[-1.739563651314382,49.65853651422431],[-1.739564241361584,49.658453644657506],[-1.739562513116073,49.65844433250798],[-1.739556691304043,49.658433027032444],[-1.739549264879466,49.658426253989326],[-1.739527369643052,49.658415067486075],[-1.739513122167437,49.658405107066926],[-1.739506132999521,49.65839150282499],[-1.739504943559619,49.658327433987914],[-1.739501605994963,49.65818315074582],[-1.739493288053887,49.65811187615185],[-1.739453961641885,49.657968805593946],[-1.739377911403589,49.65776457213422],[-1.739304317806408,49.65757026470002],[-1.739266299317639,49.65750105197944],[-1.739256976487962,49.65748407315334],[-1.739246116056332,49.657470212647816],[-1.739232476857514,49.657455555495524],[-1.739217779813456,49.65744412639509],[-1.739198824306653,49.65743262495761],[-1.739179044079239,49.657423282576474],[-1.739130507250704,49.657407022537775],[-1.739061957345631,49.65739080731378],[-1.739025458978518,49.657385643274345],[-1.738915539587075,49.65737315995609],[-1.738881067549643,49.657371335834526],[-1.738860053103217,49.65736890541017],[-1.738821540846347,49.657357784054184],[-1.73876757639012,49.6573507354131],[-1.73867161536302,49.65733663053159],[-1.738601732838121,49.65733025300006],[-1.73850233662905,49.65732567907416],[-1.738398217897442,49.65732250515459],[-1.738194313133802,49.657314904991445],[-1.738089932756446,49.65730845728815],[-1.737982516156575,49.657292966200124],[-1.737882857629756,49.65726656634259],[-1.737746916927861,49.65722037258456],[-1.737698927096434,49.65720384177042],[-1.737601693439361,49.65717640678765],[-1.73750784755023,49.65715963986516],[-1.737408183156507,49.657151530966466],[-1.737311770684144,49.65714753902869],[-1.737215513894139,49.657147921212555],[-1.737108532106675,49.65714306206995],[-1.737006773914737,49.65714307181737],[-1.736910746753859,49.65713852702422],[-1.736814255557686,49.657122801883055],[-1.736724861578887,49.65710384310347],[-1.736637269834277,49.657083861353335],[-1.736461741207677,49.65704200284033],[-1.73626444365085,49.65699363795306],[-1.736175947284714,49.65697533200083],[-1.735876871097662,49.65690555558378],[-1.73557208872794,49.65683283210489],[-1.735297533928657,49.65677000744627],[-1.735204918608509,49.656747469017866],[-1.735109019192504,49.656726129183966],[-1.734880330154187,49.65666885490597],[-1.734524089167194,49.65655414752372],[-1.734355293943281,49.656491097487056],[-1.73427080139386,49.656456126886056],[-1.734259751213325,49.65645079741933],[-1.734249204739566,49.65644258233416],[-1.734240217541812,49.65643099647164],[-1.734232635057423,49.65642121582566],[-1.73422233807747,49.65641352290978],[-1.734205948614401,49.65640551345711],[-1.734109939342267,49.6563730705961],[-1.734051494509664,49.656356728369346],[-1.733969098249313,49.656338809084446],[-1.733888052209557,49.656314900145844],[-1.733888052209557,49.656314900145844]],type:`LineString`},id:`40`,properties:{ampacity:325,approximate_nominal_voltage:2e4,bus1_id:`MVBus01882`,bus2_id:`MVBus01883`,element_type:`line`,id:`MVBranch34946`,insulator:null,length:.7059455867207443,line_type:`underground`,material:`aac`,max_loading:100,network:`MV Feeder 217`,parameters_id:`U_AL_150`,phases:`abc`,section:150},type:`Feature`},{bbox:[-1.75134861697713,49.6546228164401,-1.740274413606927,49.661351719623156],geometry:{coordinates:[[-1.75134861697713,49.6546228164401],[-1.75134861697713,49.6546228164401],[-1.751301699863922,49.654679626910905],[-1.751224296376544,49.65476771947278],[-1.751100546133867,49.6548972883225],[-1.751052576033689,49.654996076649034],[-1.751044408350226,49.655049167363906],[-1.751003680661414,49.655114248702745],[-1.750901483223386,49.65519511233728],[-1.750794860278051,49.65526725852473],[-1.750704441102756,49.65534006208172],[-1.75039486080823,49.65556098118696],[-1.75011787106141,49.65575459326522],[-1.749888936348456,49.655912318591824],[-1.749655937995882,49.656058076413316],[-1.749388737788516,49.65619571752415],[-1.749247494883003,49.65626217011036],[-1.749129755819926,49.6563427566015],[-1.748892816046397,49.65647049847278],[-1.748772980648936,49.656540669802745],[-1.748513557560205,49.65669780317539],[-1.748186064783585,49.65692013000711],[-1.747983666507208,49.65706807916889],[-1.747642077288224,49.657300556491506],[-1.747516729666441,49.65738703651531],[-1.747388981747892,49.65748246427945],[-1.7472760210709,49.657560863966594],[-1.7471836220006,49.657640188043864],[-1.746934468053926,49.65781859834436],[-1.746526064290259,49.658154217090946],[-1.746164656561502,49.65841493919094],[-1.745754213658427,49.658724526713115],[-1.745452963376744,49.65895863891651],[-1.745214800654465,49.659158724246375],[-1.744923711583319,49.65937412884914],[-1.744573940809986,49.65963748318975],[-1.744491303074585,49.659699713023215],[-1.74438219095979,49.65979272771007],[-1.744198002184347,49.659834102921934],[-1.744122641731567,49.65983999045752],[-1.744064463406356,49.659839875727315],[-1.744000344370419,49.65984203868371],[-1.743862639428613,49.65987398568658],[-1.743638085419002,49.659918691013885],[-1.743442887572666,49.65998781915069],[-1.743212138485946,49.660083208629096],[-1.743084759818112,49.66014327731511],[-1.7427775612443,49.660310245114104],[-1.742533892358992,49.660445025208595],[-1.742360146615032,49.66054527117987],[-1.742178625896325,49.66063077022418],[-1.741827036292318,49.660779915779905],[-1.741334539666645,49.660985302414524],[-1.741161366808124,49.661056570729464],[-1.741063903212354,49.6610966810873],[-1.74092799477829,49.661147682404945],[-1.74077063337072,49.661203956936156],[-1.740341448723128,49.661343132411396],[-1.740302514703939,49.661351719623156],[-1.740290461268839,49.66135066902887],[-1.740283184756773,49.66134196655046],[-1.740274413606927,49.66131821574936],[-1.740310141813682,49.661051161297074],[-1.740339303023295,49.66088039681988],[-1.740344908404654,49.66083028057313],[-1.740359131482788,49.66074761715677],[-1.740384337160247,49.660660240124315],[-1.740420562289238,49.66056428137167],[-1.740481426478069,49.66038339262529],[-1.740501661219831,49.66029189355094],[-1.740514314072042,49.66014336661246],[-1.740512856267667,49.66010903671811],[-1.740479446878883,49.65987962629042],[-1.740479446878883,49.65987962629042]],type:`LineString`},id:`41`,properties:{ampacity:325,approximate_nominal_voltage:2e4,bus1_id:`MVBus01881`,bus2_id:`MVBus01882`,element_type:`line`,id:`MVBranch42102`,insulator:null,length:1.2806813373079808,line_type:`underground`,material:`aac`,max_loading:100,network:`MV Feeder 217`,parameters_id:`U_AL_150`,phases:`abc`,section:150},type:`Feature`}],type:`FeatureCollection`}),geo_json_0490a447eb076da705c8c5ea5bd1a2fb.bindTooltip(function(layer){let div=L.DomUtil.create(`div`),handleObject=feature=>feature===null?``:typeof feature==`object`?JSON.stringify(feature):feature,fields=[`network`,`id`,`phases`,`bus1_id`,`bus2_id`,`parameters_id`,`length`,`line_type`,`material`,`insulator`,`section`,`ampacity`,`max_loading`],aliases=[`Network: `,`Id:`,`Phases:`,`Bus1:`,`Bus2:`,`Parameters:`,`Length (km):`,`Line Type:`,`Material:`,`Insulator:`,`Section (mm²):`,`Ampacity (A):`,`Max loading (%):`];return div.innerHTML=``+String(fields.map((v,i)=>` + - - - -
- - - + + `).join(``))+`
${aliases[i].toLocaleString()}${handleObject(layer.feature.properties[v]).toLocaleString()}
`,div},{className:`foliumpopup`}),geo_json_1e96dffde20de5de66d829e7669ccf31.addTo(feature_group_ea015669d5adfed39380bf7b6cf64c9b),feature_group_ea015669d5adfed39380bf7b6cf64c9b.addTo(map_7d482f8980e12f7966cc91514feaac7d);var layer_control_01a86e5c5394fc382d56b1f2e682a484_layers={base_layers:{openstreetmap:tile_layer_63357c2428797a23f0bb66f6d6eae8af},overlays:{LVFeeder00939:feature_group_95e4b647bc383d84d1fff0a249103177,LVFeeder02639:feature_group_021b45074c06a8a2c4a58e10c9db7b3c,LVFeeder04790:feature_group_7fc557d6b290c2db1a75414cc22f8404,LVFeeder06713:feature_group_0721421ae89c1535e5f1b57630684f86,LVFeeder06926:feature_group_acbf775e7557ba4eb83e38f0d400c4c2,LVFeeder06975:feature_group_6a7ba51d6e9607e73c4a6822a6ca1605,LVFeeder18498:feature_group_18e496aa3e3d91a3e91f7612d466ac13,LVFeeder18769:feature_group_26e7ae53893dfee42a32d4287be3f6ae,LVFeeder19558:feature_group_439dfcceedcc343851129d22fe71acc2,LVFeeder20256:feature_group_179f38af346280ea8214d8d403b151ba,LVFeeder23832:feature_group_0b776efa7b36bc211cd1944ba14337a2,LVFeeder24400:feature_group_5f05ef093451a8e45420fa775267fff8,LVFeeder27429:feature_group_6430b4de871e2e96cd3bfed86d6ff00f,LVFeeder27681:feature_group_e6cede792c6f09dff6ba304cd4c891a9,LVFeeder30216:feature_group_3d629df283e279f6891ee86e408141cd,LVFeeder31441:feature_group_fd57dc08b208d8a277485569f0c68ec6,LVFeeder36284:feature_group_b4d4e436dbb5833c1b339a91826623c6,LVFeeder36360:feature_group_3cd98fdcfb3c504b341b2ee413c50ff1,LVFeeder37263:feature_group_f53cf56b4daae763312e6b021c8a7b2f,LVFeeder38211:feature_group_c792b25116aa9d6955d395fef8ac7c96,MVFeeder004:feature_group_d945c2b36fd35d15b60e06a3c3d30074,MVFeeder011:feature_group_89c5e76ba75f9721d38194d9b77d61d0,MVFeeder015:feature_group_6bd8b924adba97ce87164a09dda8b4ea,MVFeeder032:feature_group_ffea355ffbc9e1f60bec9b59a38b5fef,MVFeeder041:feature_group_87267aa9ce2d4d22126c29124fa483cd,MVFeeder063:feature_group_ba475180e4d063d791db8ce375f6f93e,MVFeeder078:feature_group_50e770361f62542f605c3f80d9077c9f,MVFeeder115:feature_group_f0439f3b1ae74ca9eb2de6c56c52cb79,MVFeeder128:feature_group_80c621ca832ffd26d0331ea13cab4397,MVFeeder151:feature_group_535eb61dc35c26bebffc2f655d43c11b,MVFeeder159:feature_group_e102e952f5781f9fe3c5641d34adb927,MVFeeder176:feature_group_33632f72a2aea414f5ac7dcc5a292125,MVFeeder210:feature_group_3f19c85fb4db6bdc6be1e3299d4464e9,MVFeeder217:feature_group_11e134aa3dacd55c5ddbc606c90f6b30,MVFeeder232:feature_group_197852427684f11542f9b4b24da850b8,MVFeeder251:feature_group_927499cdb611cbddc74cb45234c50571,MVFeeder290:feature_group_0c52f6e5a930bf183f527dafac2ec422,MVFeeder312:feature_group_f556628b158dde1c4032d3fd47c731d2,MVFeeder320:feature_group_80ddbc233d959271501db250f1639dbe,MVFeeder339:feature_group_ea015669d5adfed39380bf7b6cf64c9b}};let layer_control_01a86e5c5394fc382d56b1f2e682a484=L.control.layers(layer_control_01a86e5c5394fc382d56b1f2e682a484_layers.base_layers,layer_control_01a86e5c5394fc382d56b1f2e682a484_layers.overlays,{position:`bottomright`,collapsed:!1,autoZIndex:!0}).addTo(map_7d482f8980e12f7966cc91514feaac7d);new L.Draggable(layer_control_01a86e5c5394fc382d56b1f2e682a484.getContainer()).enable();function customFlyToBounds(){let bounds=L.latLngBounds([]);map_7d482f8980e12f7966cc91514feaac7d.eachLayer(function(layer){typeof layer.getBounds==`function`&&bounds.extend(layer.getBounds())}),bounds.isValid()&&map_7d482f8980e12f7966cc91514feaac7d.fitBounds(bounds,{padding:[30,30]})}map_7d482f8980e12f7966cc91514feaac7d.on(`overlayadd`,customFlyToBounds),customFlyToBounds(); diff --git a/doc/_static/Network/Catalogue.png b/doc/_static/Network/Catalogue.png deleted file mode 100644 index 92318bfc..00000000 --- a/doc/_static/Network/Catalogue.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:2b9bbb6e5877e092cadf53bafb8f562191dfdfb211918f15a8e4448270e129f8 -size 442137 diff --git a/doc/_static/Network/Catalogue.webp b/doc/_static/Network/Catalogue.webp new file mode 100644 index 00000000..139f6422 --- /dev/null +++ b/doc/_static/Network/Catalogue.webp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:dbd149183b8c33a923c954caac3aae22675176595a85f6d7ba69308d8313163b +size 51312 diff --git a/doc/_static/Network/LVFeeder00939.html b/doc/_static/Network/LVFeeder00939.html index 05b90f67..8ff90307 100644 --- a/doc/_static/Network/LVFeeder00939.html +++ b/doc/_static/Network/LVFeeder00939.html @@ -1,640 +1,53 @@ - - - - LV Feeder 00939 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

LV Feeder 00939

- -
- -

LV Feeder 00939

- + ${handleObject(layer.feature.properties[v]).toLocaleString()} + `).join(``))+``,div},{className:`foliumpopup`}),geo_json_e1b043e5a83ac36e70af49a8b5750e72.addTo(feature_group_sub_group_9e45d0b8bca8c6a2301e82fccb060e3e),feature_group_sub_group_9e45d0b8bca8c6a2301e82fccb060e3e.addTo(map_5226106ef9ed2d2d63524d7fa656aebf);var layer_control_0f994d18fa29635519d41595f393a9fa_layers={base_layers:{openstreetmap:tile_layer_fb2a161f46b318bf443987688ff99649},overlays:{"Electrical Network":feature_group_b93c05fb45ed195c32d7ba7bc9bd6177,Buses:feature_group_sub_group_7f7a2758cc96729051114b8e54518e4a,Lines:feature_group_sub_group_cd92e38d13e1c0ecbb39983ac7d8f2ea,Transformers:feature_group_sub_group_9e45d0b8bca8c6a2301e82fccb060e3e}};let layer_control_0f994d18fa29635519d41595f393a9fa=L.control.layers(layer_control_0f994d18fa29635519d41595f393a9fa_layers.base_layers,layer_control_0f994d18fa29635519d41595f393a9fa_layers.overlays,{position:`bottomright`,collapsed:!1,autoZIndex:!0}).addTo(map_5226106ef9ed2d2d63524d7fa656aebf);new L.Draggable(layer_control_0f994d18fa29635519d41595f393a9fa.getContainer()).enable();var feature_group_b93c05fb45ed195c32d7ba7bc9bd6177searchControl=new L.Control.Search({layer:feature_group_b93c05fb45ed195c32d7ba7bc9bd6177,propertyName:`id`,collapsed:!1,textPlaceholder:`Search network elements...`,position:`topleft`,initial:!1,hideMarkerOnCollapse:!0});feature_group_b93c05fb45ed195c32d7ba7bc9bd6177searchControl.on(`search:locationfound`,function(e){feature_group_b93c05fb45ed195c32d7ba7bc9bd6177.setStyle(function(feature){return feature.properties.style}),e.layer._popup&&e.layer.openPopup()}),feature_group_b93c05fb45ed195c32d7ba7bc9bd6177searchControl.on(`search:collapsed`,function(e){feature_group_b93c05fb45ed195c32d7ba7bc9bd6177.setStyle(function(feature){return feature.properties.style})}),map_5226106ef9ed2d2d63524d7fa656aebf.addControl(feature_group_b93c05fb45ed195c32d7ba7bc9bd6177searchControl);function customFlyToBounds(){let bounds=L.latLngBounds([]);map_5226106ef9ed2d2d63524d7fa656aebf.eachLayer(function(layer){typeof layer.getBounds==`function`&&bounds.extend(layer.getBounds())}),bounds.isValid()&&map_5226106ef9ed2d2d63524d7fa656aebf.fitBounds(bounds,{padding:[30,30]})}map_5226106ef9ed2d2d63524d7fa656aebf.on(`overlayadd`,customFlyToBounds),customFlyToBounds(); diff --git a/doc/_static/Network/LVFeeder02639.html b/doc/_static/Network/LVFeeder02639.html index ccc1e483..e9498d0a 100644 --- a/doc/_static/Network/LVFeeder02639.html +++ b/doc/_static/Network/LVFeeder02639.html @@ -1,608 +1,53 @@ - - - - LV Feeder 02639 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

LV Feeder 02639

- -
- -

LV Feeder 02639

- + ${handleObject(layer.feature.properties[v]).toLocaleString()} + `).join(``))+``,div},{className:`foliumpopup`}),geo_json_7cb04590e07cd314c98b8faf205c1c2c.addTo(feature_group_sub_group_88bdc18a49d2bd0befbfdd89e533725e),feature_group_sub_group_88bdc18a49d2bd0befbfdd89e533725e.addTo(map_a72caed6f689196c96aa612eca4671d1);var layer_control_dc1f3c92f7d7dd81200ffbdca38c22dc_layers={base_layers:{openstreetmap:tile_layer_93f9d3b8e6313d74198566cb706aa7f3},overlays:{"Electrical Network":feature_group_aee3802931e6a3fcf90ee3ade44bb29c,Buses:feature_group_sub_group_ced39fa2c3b9574ac2238555ade4f915,Lines:feature_group_sub_group_0e7882e4ce61e7f323af2c36c4d42654,Transformers:feature_group_sub_group_88bdc18a49d2bd0befbfdd89e533725e}};let layer_control_dc1f3c92f7d7dd81200ffbdca38c22dc=L.control.layers(layer_control_dc1f3c92f7d7dd81200ffbdca38c22dc_layers.base_layers,layer_control_dc1f3c92f7d7dd81200ffbdca38c22dc_layers.overlays,{position:`bottomright`,collapsed:!1,autoZIndex:!0}).addTo(map_a72caed6f689196c96aa612eca4671d1);new L.Draggable(layer_control_dc1f3c92f7d7dd81200ffbdca38c22dc.getContainer()).enable();var feature_group_aee3802931e6a3fcf90ee3ade44bb29csearchControl=new L.Control.Search({layer:feature_group_aee3802931e6a3fcf90ee3ade44bb29c,propertyName:`id`,collapsed:!1,textPlaceholder:`Search network elements...`,position:`topleft`,initial:!1,hideMarkerOnCollapse:!0});feature_group_aee3802931e6a3fcf90ee3ade44bb29csearchControl.on(`search:locationfound`,function(e){feature_group_aee3802931e6a3fcf90ee3ade44bb29c.setStyle(function(feature){return feature.properties.style}),e.layer._popup&&e.layer.openPopup()}),feature_group_aee3802931e6a3fcf90ee3ade44bb29csearchControl.on(`search:collapsed`,function(e){feature_group_aee3802931e6a3fcf90ee3ade44bb29c.setStyle(function(feature){return feature.properties.style})}),map_a72caed6f689196c96aa612eca4671d1.addControl(feature_group_aee3802931e6a3fcf90ee3ade44bb29csearchControl);function customFlyToBounds(){let bounds=L.latLngBounds([]);map_a72caed6f689196c96aa612eca4671d1.eachLayer(function(layer){typeof layer.getBounds==`function`&&bounds.extend(layer.getBounds())}),bounds.isValid()&&map_a72caed6f689196c96aa612eca4671d1.fitBounds(bounds,{padding:[30,30]})}map_a72caed6f689196c96aa612eca4671d1.on(`overlayadd`,customFlyToBounds),customFlyToBounds(); diff --git a/doc/_static/Network/LVFeeder04790.html b/doc/_static/Network/LVFeeder04790.html index eebcc85e..3379ce72 100644 --- a/doc/_static/Network/LVFeeder04790.html +++ b/doc/_static/Network/LVFeeder04790.html @@ -1,504 +1,53 @@ - - - - LV Feeder 04790 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

LV Feeder 04790

- -
- -

LV Feeder 04790

- + ${handleObject(layer.feature.properties[v]).toLocaleString()} + `).join(``))+``,div},{className:`foliumpopup`}),geo_json_494b7be2cc962499cc600e9a21a34480.addTo(feature_group_sub_group_0ae6bd870903a893595bd2db3740317c),feature_group_sub_group_0ae6bd870903a893595bd2db3740317c.addTo(map_9e819de0168f57e265e8d94e40771cf9);var layer_control_610e914a72c7d88b923a835d520fb3cc_layers={base_layers:{openstreetmap:tile_layer_c1903064d5693caf4809431756823ad2},overlays:{"Electrical Network":feature_group_802fca8e4dcd599e7f6c5e34f1411270,Buses:feature_group_sub_group_94d4fa02a20d02fa8e4fc8462e6d9431,Lines:feature_group_sub_group_3dc19f155cef4743b1034f4e9fa2d556,Transformers:feature_group_sub_group_0ae6bd870903a893595bd2db3740317c}};let layer_control_610e914a72c7d88b923a835d520fb3cc=L.control.layers(layer_control_610e914a72c7d88b923a835d520fb3cc_layers.base_layers,layer_control_610e914a72c7d88b923a835d520fb3cc_layers.overlays,{position:`bottomright`,collapsed:!1,autoZIndex:!0}).addTo(map_9e819de0168f57e265e8d94e40771cf9);new L.Draggable(layer_control_610e914a72c7d88b923a835d520fb3cc.getContainer()).enable();var feature_group_802fca8e4dcd599e7f6c5e34f1411270searchControl=new L.Control.Search({layer:feature_group_802fca8e4dcd599e7f6c5e34f1411270,propertyName:`id`,collapsed:!1,textPlaceholder:`Search network elements...`,position:`topleft`,initial:!1,hideMarkerOnCollapse:!0});feature_group_802fca8e4dcd599e7f6c5e34f1411270searchControl.on(`search:locationfound`,function(e){feature_group_802fca8e4dcd599e7f6c5e34f1411270.setStyle(function(feature){return feature.properties.style}),e.layer._popup&&e.layer.openPopup()}),feature_group_802fca8e4dcd599e7f6c5e34f1411270searchControl.on(`search:collapsed`,function(e){feature_group_802fca8e4dcd599e7f6c5e34f1411270.setStyle(function(feature){return feature.properties.style})}),map_9e819de0168f57e265e8d94e40771cf9.addControl(feature_group_802fca8e4dcd599e7f6c5e34f1411270searchControl);function customFlyToBounds(){let bounds=L.latLngBounds([]);map_9e819de0168f57e265e8d94e40771cf9.eachLayer(function(layer){typeof layer.getBounds==`function`&&bounds.extend(layer.getBounds())}),bounds.isValid()&&map_9e819de0168f57e265e8d94e40771cf9.fitBounds(bounds,{padding:[30,30]})}map_9e819de0168f57e265e8d94e40771cf9.on(`overlayadd`,customFlyToBounds),customFlyToBounds(); diff --git a/doc/_static/Network/LVFeeder06713.html b/doc/_static/Network/LVFeeder06713.html index 734c21ea..401575c5 100644 --- a/doc/_static/Network/LVFeeder06713.html +++ b/doc/_static/Network/LVFeeder06713.html @@ -1,432 +1,53 @@ - - - - LV Feeder 06713 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

LV Feeder 06713

- -
- -

LV Feeder 06713

- + ${handleObject(layer.feature.properties[v]).toLocaleString()} + `).join(``))+``,div},{className:`foliumpopup`}),geo_json_ef1fa1654ea6f0776bbf43106628198d.addTo(feature_group_sub_group_bc205aa868409aa5f46eb2a52bb45d2a),feature_group_sub_group_bc205aa868409aa5f46eb2a52bb45d2a.addTo(map_53f5f9ceaff655d65cd0813b286a7fc1);var layer_control_10bf038b372207bf487a7ab55ad43832_layers={base_layers:{openstreetmap:tile_layer_e4d376262f0525f2b2df5c06e382348b},overlays:{"Electrical Network":feature_group_e121070c248424ec927e335e46251464,Buses:feature_group_sub_group_cca94177898b59119de4e56bd6f1fd77,Lines:feature_group_sub_group_95eaf393929167e6272c78ff64decf71,Transformers:feature_group_sub_group_bc205aa868409aa5f46eb2a52bb45d2a}};let layer_control_10bf038b372207bf487a7ab55ad43832=L.control.layers(layer_control_10bf038b372207bf487a7ab55ad43832_layers.base_layers,layer_control_10bf038b372207bf487a7ab55ad43832_layers.overlays,{position:`bottomright`,collapsed:!1,autoZIndex:!0}).addTo(map_53f5f9ceaff655d65cd0813b286a7fc1);new L.Draggable(layer_control_10bf038b372207bf487a7ab55ad43832.getContainer()).enable();var feature_group_e121070c248424ec927e335e46251464searchControl=new L.Control.Search({layer:feature_group_e121070c248424ec927e335e46251464,propertyName:`id`,collapsed:!1,textPlaceholder:`Search network elements...`,position:`topleft`,initial:!1,hideMarkerOnCollapse:!0});feature_group_e121070c248424ec927e335e46251464searchControl.on(`search:locationfound`,function(e){feature_group_e121070c248424ec927e335e46251464.setStyle(function(feature){return feature.properties.style}),e.layer._popup&&e.layer.openPopup()}),feature_group_e121070c248424ec927e335e46251464searchControl.on(`search:collapsed`,function(e){feature_group_e121070c248424ec927e335e46251464.setStyle(function(feature){return feature.properties.style})}),map_53f5f9ceaff655d65cd0813b286a7fc1.addControl(feature_group_e121070c248424ec927e335e46251464searchControl);function customFlyToBounds(){let bounds=L.latLngBounds([]);map_53f5f9ceaff655d65cd0813b286a7fc1.eachLayer(function(layer){typeof layer.getBounds==`function`&&bounds.extend(layer.getBounds())}),bounds.isValid()&&map_53f5f9ceaff655d65cd0813b286a7fc1.fitBounds(bounds,{padding:[30,30]})}map_53f5f9ceaff655d65cd0813b286a7fc1.on(`overlayadd`,customFlyToBounds),customFlyToBounds(); diff --git a/doc/_static/Network/LVFeeder06926.html b/doc/_static/Network/LVFeeder06926.html index d23603b3..cde22e06 100644 --- a/doc/_static/Network/LVFeeder06926.html +++ b/doc/_static/Network/LVFeeder06926.html @@ -1,433 +1,53 @@ - - - - LV Feeder 06926 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

LV Feeder 06926

- -
- -

LV Feeder 06926

- + ${handleObject(layer.feature.properties[v]).toLocaleString()} + `).join(``))+``,div},{className:`foliumpopup`}),geo_json_59cf9e77abf7bc130bb998a193aa83f8.addTo(feature_group_sub_group_13b771dc6bca2cd6468f40d9dac1b115),feature_group_sub_group_13b771dc6bca2cd6468f40d9dac1b115.addTo(map_46cc3b5138a5af65cce2386aca624d01);var layer_control_243342f4de1a089a84d25c621a05b8b0_layers={base_layers:{openstreetmap:tile_layer_9952c3bbf75cda86ea15cf16592c879c},overlays:{"Electrical Network":feature_group_5bd204619c2e208e25eeb203c2d2af2b,Buses:feature_group_sub_group_c50b61b5ed7d09c733e0d4af424c8380,Lines:feature_group_sub_group_3f18fa3a414d730e7e72f57804231e1a,Transformers:feature_group_sub_group_13b771dc6bca2cd6468f40d9dac1b115}};let layer_control_243342f4de1a089a84d25c621a05b8b0=L.control.layers(layer_control_243342f4de1a089a84d25c621a05b8b0_layers.base_layers,layer_control_243342f4de1a089a84d25c621a05b8b0_layers.overlays,{position:`bottomright`,collapsed:!1,autoZIndex:!0}).addTo(map_46cc3b5138a5af65cce2386aca624d01);new L.Draggable(layer_control_243342f4de1a089a84d25c621a05b8b0.getContainer()).enable();var feature_group_5bd204619c2e208e25eeb203c2d2af2bsearchControl=new L.Control.Search({layer:feature_group_5bd204619c2e208e25eeb203c2d2af2b,propertyName:`id`,collapsed:!1,textPlaceholder:`Search network elements...`,position:`topleft`,initial:!1,hideMarkerOnCollapse:!0});feature_group_5bd204619c2e208e25eeb203c2d2af2bsearchControl.on(`search:locationfound`,function(e){feature_group_5bd204619c2e208e25eeb203c2d2af2b.setStyle(function(feature){return feature.properties.style}),e.layer._popup&&e.layer.openPopup()}),feature_group_5bd204619c2e208e25eeb203c2d2af2bsearchControl.on(`search:collapsed`,function(e){feature_group_5bd204619c2e208e25eeb203c2d2af2b.setStyle(function(feature){return feature.properties.style})}),map_46cc3b5138a5af65cce2386aca624d01.addControl(feature_group_5bd204619c2e208e25eeb203c2d2af2bsearchControl);function customFlyToBounds(){let bounds=L.latLngBounds([]);map_46cc3b5138a5af65cce2386aca624d01.eachLayer(function(layer){typeof layer.getBounds==`function`&&bounds.extend(layer.getBounds())}),bounds.isValid()&&map_46cc3b5138a5af65cce2386aca624d01.fitBounds(bounds,{padding:[30,30]})}map_46cc3b5138a5af65cce2386aca624d01.on(`overlayadd`,customFlyToBounds),customFlyToBounds(); diff --git a/doc/_static/Network/LVFeeder06975.html b/doc/_static/Network/LVFeeder06975.html index 89dd904d..0e555366 100644 --- a/doc/_static/Network/LVFeeder06975.html +++ b/doc/_static/Network/LVFeeder06975.html @@ -1,566 +1,53 @@ - - - - LV Feeder 06975 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

LV Feeder 06975

- -
- -

LV Feeder 06975

- + ${handleObject(layer.feature.properties[v]).toLocaleString()} + `).join(``))+``,div},{className:`foliumpopup`}),geo_json_6afd748a1091c0e3addb045c2c213026.addTo(feature_group_sub_group_5713701e8c4c690714f81c15a3058cc2),feature_group_sub_group_5713701e8c4c690714f81c15a3058cc2.addTo(map_fa573a14d53801d02a78529ad1cc7979);var layer_control_b5bbaa926c2ca84785552dd34990fe3a_layers={base_layers:{openstreetmap:tile_layer_f80204df167f13c0040dba71ee947154},overlays:{"Electrical Network":feature_group_76e6645483d1e2b7ab85d501ac9a7362,Buses:feature_group_sub_group_2f3397d27019b68b8b3414b378fc2f86,Lines:feature_group_sub_group_1e332bd3e61b4d8380765a7842efa338,Transformers:feature_group_sub_group_5713701e8c4c690714f81c15a3058cc2}};let layer_control_b5bbaa926c2ca84785552dd34990fe3a=L.control.layers(layer_control_b5bbaa926c2ca84785552dd34990fe3a_layers.base_layers,layer_control_b5bbaa926c2ca84785552dd34990fe3a_layers.overlays,{position:`bottomright`,collapsed:!1,autoZIndex:!0}).addTo(map_fa573a14d53801d02a78529ad1cc7979);new L.Draggable(layer_control_b5bbaa926c2ca84785552dd34990fe3a.getContainer()).enable();var feature_group_76e6645483d1e2b7ab85d501ac9a7362searchControl=new L.Control.Search({layer:feature_group_76e6645483d1e2b7ab85d501ac9a7362,propertyName:`id`,collapsed:!1,textPlaceholder:`Search network elements...`,position:`topleft`,initial:!1,hideMarkerOnCollapse:!0});feature_group_76e6645483d1e2b7ab85d501ac9a7362searchControl.on(`search:locationfound`,function(e){feature_group_76e6645483d1e2b7ab85d501ac9a7362.setStyle(function(feature){return feature.properties.style}),e.layer._popup&&e.layer.openPopup()}),feature_group_76e6645483d1e2b7ab85d501ac9a7362searchControl.on(`search:collapsed`,function(e){feature_group_76e6645483d1e2b7ab85d501ac9a7362.setStyle(function(feature){return feature.properties.style})}),map_fa573a14d53801d02a78529ad1cc7979.addControl(feature_group_76e6645483d1e2b7ab85d501ac9a7362searchControl);function customFlyToBounds(){let bounds=L.latLngBounds([]);map_fa573a14d53801d02a78529ad1cc7979.eachLayer(function(layer){typeof layer.getBounds==`function`&&bounds.extend(layer.getBounds())}),bounds.isValid()&&map_fa573a14d53801d02a78529ad1cc7979.fitBounds(bounds,{padding:[30,30]})}map_fa573a14d53801d02a78529ad1cc7979.on(`overlayadd`,customFlyToBounds),customFlyToBounds(); diff --git a/doc/_static/Network/LVFeeder18498.html b/doc/_static/Network/LVFeeder18498.html index 145a0b1d..e9e290c5 100644 --- a/doc/_static/Network/LVFeeder18498.html +++ b/doc/_static/Network/LVFeeder18498.html @@ -1,1120 +1,53 @@ - - - - LV Feeder 18498 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

LV Feeder 18498

- -
- -

LV Feeder 18498

- + ${handleObject(layer.feature.properties[v]).toLocaleString()} + `).join(``))+``,div},{className:`foliumpopup`}),geo_json_40d7d5ef0abe296e9b53f802a66b7240.addTo(feature_group_sub_group_178fe47511b72e1412b53d7fcf26fce5),feature_group_sub_group_178fe47511b72e1412b53d7fcf26fce5.addTo(map_0730d5ebf44160f49b4e23b339b9d6f2);var layer_control_05cf1b56761a13fc3943b3ca865e44a0_layers={base_layers:{openstreetmap:tile_layer_292bc20ebf86d2a84bc72f100ec3617c},overlays:{"Electrical Network":feature_group_be0088934a9164afb093dd7d6a3e4917,Buses:feature_group_sub_group_a656c3ae2abe71a02f0cb96ce062c20e,Lines:feature_group_sub_group_5ffb072338e4d8f2410634ccdb91eb7c,Transformers:feature_group_sub_group_178fe47511b72e1412b53d7fcf26fce5}};let layer_control_05cf1b56761a13fc3943b3ca865e44a0=L.control.layers(layer_control_05cf1b56761a13fc3943b3ca865e44a0_layers.base_layers,layer_control_05cf1b56761a13fc3943b3ca865e44a0_layers.overlays,{position:`bottomright`,collapsed:!1,autoZIndex:!0}).addTo(map_0730d5ebf44160f49b4e23b339b9d6f2);new L.Draggable(layer_control_05cf1b56761a13fc3943b3ca865e44a0.getContainer()).enable();var feature_group_be0088934a9164afb093dd7d6a3e4917searchControl=new L.Control.Search({layer:feature_group_be0088934a9164afb093dd7d6a3e4917,propertyName:`id`,collapsed:!1,textPlaceholder:`Search network elements...`,position:`topleft`,initial:!1,hideMarkerOnCollapse:!0});feature_group_be0088934a9164afb093dd7d6a3e4917searchControl.on(`search:locationfound`,function(e){feature_group_be0088934a9164afb093dd7d6a3e4917.setStyle(function(feature){return feature.properties.style}),e.layer._popup&&e.layer.openPopup()}),feature_group_be0088934a9164afb093dd7d6a3e4917searchControl.on(`search:collapsed`,function(e){feature_group_be0088934a9164afb093dd7d6a3e4917.setStyle(function(feature){return feature.properties.style})}),map_0730d5ebf44160f49b4e23b339b9d6f2.addControl(feature_group_be0088934a9164afb093dd7d6a3e4917searchControl);function customFlyToBounds(){let bounds=L.latLngBounds([]);map_0730d5ebf44160f49b4e23b339b9d6f2.eachLayer(function(layer){typeof layer.getBounds==`function`&&bounds.extend(layer.getBounds())}),bounds.isValid()&&map_0730d5ebf44160f49b4e23b339b9d6f2.fitBounds(bounds,{padding:[30,30]})}map_0730d5ebf44160f49b4e23b339b9d6f2.on(`overlayadd`,customFlyToBounds),customFlyToBounds(); diff --git a/doc/_static/Network/LVFeeder18769.html b/doc/_static/Network/LVFeeder18769.html index 9f1dea4f..c0e9015e 100644 --- a/doc/_static/Network/LVFeeder18769.html +++ b/doc/_static/Network/LVFeeder18769.html @@ -1,593 +1,53 @@ - - - - LV Feeder 18769 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

LV Feeder 18769

- -
- -

LV Feeder 18769

- + ${handleObject(layer.feature.properties[v]).toLocaleString()} + `).join(``))+``,div},{className:`foliumpopup`}),geo_json_db0f75584f592ce70a8e14742bcee27e.addTo(feature_group_sub_group_bfd0498a32af040022ed5a031b437c6b),feature_group_sub_group_bfd0498a32af040022ed5a031b437c6b.addTo(map_aac16bd1f9835a5183a130c7d9c7c889);var layer_control_0bd620c2982be9acdc65e8d6eba57581_layers={base_layers:{openstreetmap:tile_layer_8b95117b07911a18d0b7182e48a3a8b7},overlays:{"Electrical Network":feature_group_ee94c86f7efe97b4198225f17ba72b02,Buses:feature_group_sub_group_0ab863f5909d19457cc8b09eb987dd5e,Lines:feature_group_sub_group_bd2aa9fc7c083050a7bcc01a7fe8223a,Transformers:feature_group_sub_group_bfd0498a32af040022ed5a031b437c6b}};let layer_control_0bd620c2982be9acdc65e8d6eba57581=L.control.layers(layer_control_0bd620c2982be9acdc65e8d6eba57581_layers.base_layers,layer_control_0bd620c2982be9acdc65e8d6eba57581_layers.overlays,{position:`bottomright`,collapsed:!1,autoZIndex:!0}).addTo(map_aac16bd1f9835a5183a130c7d9c7c889);new L.Draggable(layer_control_0bd620c2982be9acdc65e8d6eba57581.getContainer()).enable();var feature_group_ee94c86f7efe97b4198225f17ba72b02searchControl=new L.Control.Search({layer:feature_group_ee94c86f7efe97b4198225f17ba72b02,propertyName:`id`,collapsed:!1,textPlaceholder:`Search network elements...`,position:`topleft`,initial:!1,hideMarkerOnCollapse:!0});feature_group_ee94c86f7efe97b4198225f17ba72b02searchControl.on(`search:locationfound`,function(e){feature_group_ee94c86f7efe97b4198225f17ba72b02.setStyle(function(feature){return feature.properties.style}),e.layer._popup&&e.layer.openPopup()}),feature_group_ee94c86f7efe97b4198225f17ba72b02searchControl.on(`search:collapsed`,function(e){feature_group_ee94c86f7efe97b4198225f17ba72b02.setStyle(function(feature){return feature.properties.style})}),map_aac16bd1f9835a5183a130c7d9c7c889.addControl(feature_group_ee94c86f7efe97b4198225f17ba72b02searchControl);function customFlyToBounds(){let bounds=L.latLngBounds([]);map_aac16bd1f9835a5183a130c7d9c7c889.eachLayer(function(layer){typeof layer.getBounds==`function`&&bounds.extend(layer.getBounds())}),bounds.isValid()&&map_aac16bd1f9835a5183a130c7d9c7c889.fitBounds(bounds,{padding:[30,30]})}map_aac16bd1f9835a5183a130c7d9c7c889.on(`overlayadd`,customFlyToBounds),customFlyToBounds(); diff --git a/doc/_static/Network/LVFeeder19558.html b/doc/_static/Network/LVFeeder19558.html index 05cdf907..537fd20e 100644 --- a/doc/_static/Network/LVFeeder19558.html +++ b/doc/_static/Network/LVFeeder19558.html @@ -1,437 +1,53 @@ - - - - LV Feeder 19558 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

LV Feeder 19558

- -
- -

LV Feeder 19558

- + ${handleObject(layer.feature.properties[v]).toLocaleString()} + `).join(``))+``,div},{className:`foliumpopup`}),geo_json_ca44cf02936fb0a38fe488f5e1516ff9.addTo(feature_group_sub_group_3b286abd814fe439075bdd9d1cea9e4a),feature_group_sub_group_3b286abd814fe439075bdd9d1cea9e4a.addTo(map_9185301459d7cfd2ecad55c77a98f326);var layer_control_956339b6ce2cc4e9f44e97bbe13b152e_layers={base_layers:{openstreetmap:tile_layer_3218794acb105c0c4f6ebe0b1772a6fc},overlays:{"Electrical Network":feature_group_ac168e268cb1334c17473582c8667c4c,Buses:feature_group_sub_group_cf242c1b095174d23906a50170830334,Lines:feature_group_sub_group_5d59aa481a8c73ed561558bab2a61b7c,Transformers:feature_group_sub_group_3b286abd814fe439075bdd9d1cea9e4a}};let layer_control_956339b6ce2cc4e9f44e97bbe13b152e=L.control.layers(layer_control_956339b6ce2cc4e9f44e97bbe13b152e_layers.base_layers,layer_control_956339b6ce2cc4e9f44e97bbe13b152e_layers.overlays,{position:`bottomright`,collapsed:!1,autoZIndex:!0}).addTo(map_9185301459d7cfd2ecad55c77a98f326);new L.Draggable(layer_control_956339b6ce2cc4e9f44e97bbe13b152e.getContainer()).enable();var feature_group_ac168e268cb1334c17473582c8667c4csearchControl=new L.Control.Search({layer:feature_group_ac168e268cb1334c17473582c8667c4c,propertyName:`id`,collapsed:!1,textPlaceholder:`Search network elements...`,position:`topleft`,initial:!1,hideMarkerOnCollapse:!0});feature_group_ac168e268cb1334c17473582c8667c4csearchControl.on(`search:locationfound`,function(e){feature_group_ac168e268cb1334c17473582c8667c4c.setStyle(function(feature){return feature.properties.style}),e.layer._popup&&e.layer.openPopup()}),feature_group_ac168e268cb1334c17473582c8667c4csearchControl.on(`search:collapsed`,function(e){feature_group_ac168e268cb1334c17473582c8667c4c.setStyle(function(feature){return feature.properties.style})}),map_9185301459d7cfd2ecad55c77a98f326.addControl(feature_group_ac168e268cb1334c17473582c8667c4csearchControl);function customFlyToBounds(){let bounds=L.latLngBounds([]);map_9185301459d7cfd2ecad55c77a98f326.eachLayer(function(layer){typeof layer.getBounds==`function`&&bounds.extend(layer.getBounds())}),bounds.isValid()&&map_9185301459d7cfd2ecad55c77a98f326.fitBounds(bounds,{padding:[30,30]})}map_9185301459d7cfd2ecad55c77a98f326.on(`overlayadd`,customFlyToBounds),customFlyToBounds(); diff --git a/doc/_static/Network/LVFeeder20256.html b/doc/_static/Network/LVFeeder20256.html index ca1530d8..85ce1472 100644 --- a/doc/_static/Network/LVFeeder20256.html +++ b/doc/_static/Network/LVFeeder20256.html @@ -1,669 +1,53 @@ - - - - LV Feeder 20256 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

LV Feeder 20256

- -
- -

LV Feeder 20256

- + ${handleObject(layer.feature.properties[v]).toLocaleString()} + `).join(``))+``,div},{className:`foliumpopup`}),geo_json_7649ad5d1eae48afbd382193a98edb26.addTo(feature_group_sub_group_9d5f66a831873417c3f7ee5c20ac4382),feature_group_sub_group_9d5f66a831873417c3f7ee5c20ac4382.addTo(map_bcffa8b93f22462e090c17f382043dac);var layer_control_15652587d8b5cc952f16fd4838ea9a2c_layers={base_layers:{openstreetmap:tile_layer_896cb97507a343b61a7a69bbff162e4f},overlays:{"Electrical Network":feature_group_9117995a9c379ee254047637326b548d,Buses:feature_group_sub_group_bf4d8326ee4130462a1eaaef108394f2,Lines:feature_group_sub_group_be07db8ba5235dfcba362b8b4b74578d,Transformers:feature_group_sub_group_9d5f66a831873417c3f7ee5c20ac4382}};let layer_control_15652587d8b5cc952f16fd4838ea9a2c=L.control.layers(layer_control_15652587d8b5cc952f16fd4838ea9a2c_layers.base_layers,layer_control_15652587d8b5cc952f16fd4838ea9a2c_layers.overlays,{position:`bottomright`,collapsed:!1,autoZIndex:!0}).addTo(map_bcffa8b93f22462e090c17f382043dac);new L.Draggable(layer_control_15652587d8b5cc952f16fd4838ea9a2c.getContainer()).enable();var feature_group_9117995a9c379ee254047637326b548dsearchControl=new L.Control.Search({layer:feature_group_9117995a9c379ee254047637326b548d,propertyName:`id`,collapsed:!1,textPlaceholder:`Search network elements...`,position:`topleft`,initial:!1,hideMarkerOnCollapse:!0});feature_group_9117995a9c379ee254047637326b548dsearchControl.on(`search:locationfound`,function(e){feature_group_9117995a9c379ee254047637326b548d.setStyle(function(feature){return feature.properties.style}),e.layer._popup&&e.layer.openPopup()}),feature_group_9117995a9c379ee254047637326b548dsearchControl.on(`search:collapsed`,function(e){feature_group_9117995a9c379ee254047637326b548d.setStyle(function(feature){return feature.properties.style})}),map_bcffa8b93f22462e090c17f382043dac.addControl(feature_group_9117995a9c379ee254047637326b548dsearchControl);function customFlyToBounds(){let bounds=L.latLngBounds([]);map_bcffa8b93f22462e090c17f382043dac.eachLayer(function(layer){typeof layer.getBounds==`function`&&bounds.extend(layer.getBounds())}),bounds.isValid()&&map_bcffa8b93f22462e090c17f382043dac.fitBounds(bounds,{padding:[30,30]})}map_bcffa8b93f22462e090c17f382043dac.on(`overlayadd`,customFlyToBounds),customFlyToBounds(); diff --git a/doc/_static/Network/LVFeeder23832.html b/doc/_static/Network/LVFeeder23832.html index ac606d80..2beb406e 100644 --- a/doc/_static/Network/LVFeeder23832.html +++ b/doc/_static/Network/LVFeeder23832.html @@ -1,436 +1,53 @@ - - - - LV Feeder 23832 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

LV Feeder 23832

- -
- -

LV Feeder 23832

- + ${handleObject(layer.feature.properties[v]).toLocaleString()} + `).join(``))+``,div},{className:`foliumpopup`}),geo_json_2f2c5cf1e58de9edeb1fcc3298d8d324.addTo(feature_group_sub_group_ef33e1981763fbe773ad7079c5660865),feature_group_sub_group_ef33e1981763fbe773ad7079c5660865.addTo(map_3641224b384eac4623505e3b8d1eedfb);var layer_control_65ad09dc0acb815cc428e6e5ca17108c_layers={base_layers:{openstreetmap:tile_layer_e4098e8818729c8231e6ef1652be44e1},overlays:{"Electrical Network":feature_group_d83dc5a70e299a25acda0d14eb4e2c16,Buses:feature_group_sub_group_2549771fe270155ffa77877b4aafbe14,Lines:feature_group_sub_group_7773457035c69d823af658c2b902ea94,Transformers:feature_group_sub_group_ef33e1981763fbe773ad7079c5660865}};let layer_control_65ad09dc0acb815cc428e6e5ca17108c=L.control.layers(layer_control_65ad09dc0acb815cc428e6e5ca17108c_layers.base_layers,layer_control_65ad09dc0acb815cc428e6e5ca17108c_layers.overlays,{position:`bottomright`,collapsed:!1,autoZIndex:!0}).addTo(map_3641224b384eac4623505e3b8d1eedfb);new L.Draggable(layer_control_65ad09dc0acb815cc428e6e5ca17108c.getContainer()).enable();var feature_group_d83dc5a70e299a25acda0d14eb4e2c16searchControl=new L.Control.Search({layer:feature_group_d83dc5a70e299a25acda0d14eb4e2c16,propertyName:`id`,collapsed:!1,textPlaceholder:`Search network elements...`,position:`topleft`,initial:!1,hideMarkerOnCollapse:!0});feature_group_d83dc5a70e299a25acda0d14eb4e2c16searchControl.on(`search:locationfound`,function(e){feature_group_d83dc5a70e299a25acda0d14eb4e2c16.setStyle(function(feature){return feature.properties.style}),e.layer._popup&&e.layer.openPopup()}),feature_group_d83dc5a70e299a25acda0d14eb4e2c16searchControl.on(`search:collapsed`,function(e){feature_group_d83dc5a70e299a25acda0d14eb4e2c16.setStyle(function(feature){return feature.properties.style})}),map_3641224b384eac4623505e3b8d1eedfb.addControl(feature_group_d83dc5a70e299a25acda0d14eb4e2c16searchControl);function customFlyToBounds(){let bounds=L.latLngBounds([]);map_3641224b384eac4623505e3b8d1eedfb.eachLayer(function(layer){typeof layer.getBounds==`function`&&bounds.extend(layer.getBounds())}),bounds.isValid()&&map_3641224b384eac4623505e3b8d1eedfb.fitBounds(bounds,{padding:[30,30]})}map_3641224b384eac4623505e3b8d1eedfb.on(`overlayadd`,customFlyToBounds),customFlyToBounds(); diff --git a/doc/_static/Network/LVFeeder24400.html b/doc/_static/Network/LVFeeder24400.html index 04f6a6c4..aa911553 100644 --- a/doc/_static/Network/LVFeeder24400.html +++ b/doc/_static/Network/LVFeeder24400.html @@ -1,472 +1,53 @@ - - - - LV Feeder 24400 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

LV Feeder 24400

- -
- -

LV Feeder 24400

- + ${handleObject(layer.feature.properties[v]).toLocaleString()} + `).join(``))+``,div},{className:`foliumpopup`}),geo_json_c30ee70288347e56d3bf52db893fd911.addTo(feature_group_sub_group_07a5a2ff061ed8cb9f7207a8f2735553),feature_group_sub_group_07a5a2ff061ed8cb9f7207a8f2735553.addTo(map_44b262bfcd7b271c8ff872976a8bd2de);var layer_control_9dc91c8ecc7d17c63b6e6edc119954a1_layers={base_layers:{openstreetmap:tile_layer_484e17709c4099d6ed8f93db64250944},overlays:{"Electrical Network":feature_group_78341bd611987e05e10339fd0423ed70,Buses:feature_group_sub_group_cdb8f2569f8a8dace86132adcc07b85c,Lines:feature_group_sub_group_08c0acaba01462c277ceaf4f10c689f8,Transformers:feature_group_sub_group_07a5a2ff061ed8cb9f7207a8f2735553}};let layer_control_9dc91c8ecc7d17c63b6e6edc119954a1=L.control.layers(layer_control_9dc91c8ecc7d17c63b6e6edc119954a1_layers.base_layers,layer_control_9dc91c8ecc7d17c63b6e6edc119954a1_layers.overlays,{position:`bottomright`,collapsed:!1,autoZIndex:!0}).addTo(map_44b262bfcd7b271c8ff872976a8bd2de);new L.Draggable(layer_control_9dc91c8ecc7d17c63b6e6edc119954a1.getContainer()).enable();var feature_group_78341bd611987e05e10339fd0423ed70searchControl=new L.Control.Search({layer:feature_group_78341bd611987e05e10339fd0423ed70,propertyName:`id`,collapsed:!1,textPlaceholder:`Search network elements...`,position:`topleft`,initial:!1,hideMarkerOnCollapse:!0});feature_group_78341bd611987e05e10339fd0423ed70searchControl.on(`search:locationfound`,function(e){feature_group_78341bd611987e05e10339fd0423ed70.setStyle(function(feature){return feature.properties.style}),e.layer._popup&&e.layer.openPopup()}),feature_group_78341bd611987e05e10339fd0423ed70searchControl.on(`search:collapsed`,function(e){feature_group_78341bd611987e05e10339fd0423ed70.setStyle(function(feature){return feature.properties.style})}),map_44b262bfcd7b271c8ff872976a8bd2de.addControl(feature_group_78341bd611987e05e10339fd0423ed70searchControl);function customFlyToBounds(){let bounds=L.latLngBounds([]);map_44b262bfcd7b271c8ff872976a8bd2de.eachLayer(function(layer){typeof layer.getBounds==`function`&&bounds.extend(layer.getBounds())}),bounds.isValid()&&map_44b262bfcd7b271c8ff872976a8bd2de.fitBounds(bounds,{padding:[30,30]})}map_44b262bfcd7b271c8ff872976a8bd2de.on(`overlayadd`,customFlyToBounds),customFlyToBounds(); diff --git a/doc/_static/Network/LVFeeder27429.html b/doc/_static/Network/LVFeeder27429.html index c11ee09e..cb07add2 100644 --- a/doc/_static/Network/LVFeeder27429.html +++ b/doc/_static/Network/LVFeeder27429.html @@ -1,785 +1,53 @@ - - - - LV Feeder 27429 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

LV Feeder 27429

- -
- -

LV Feeder 27429

- + ${handleObject(layer.feature.properties[v]).toLocaleString()} + `).join(``))+``,div},{className:`foliumpopup`}),geo_json_e38304bb4aae95696a48b2497e5a55b8.addTo(feature_group_sub_group_8e65d45b4fc478d4aa49c28b5601fd97),feature_group_sub_group_8e65d45b4fc478d4aa49c28b5601fd97.addTo(map_2c9267e4f3e2aa97c3d61c1ca2758ef6);var layer_control_5b7166d1bba400807f14bd3027c4055c_layers={base_layers:{openstreetmap:tile_layer_7b8c15863eece0c87e74b1a56cef9b63},overlays:{"Electrical Network":feature_group_3c841659dcf76e788d3e0355621f6596,Buses:feature_group_sub_group_e95cf0796d3ef7043b50d2c572b681e2,Lines:feature_group_sub_group_129cf9312d114b8eef0ad7f10830ca91,Transformers:feature_group_sub_group_8e65d45b4fc478d4aa49c28b5601fd97}};let layer_control_5b7166d1bba400807f14bd3027c4055c=L.control.layers(layer_control_5b7166d1bba400807f14bd3027c4055c_layers.base_layers,layer_control_5b7166d1bba400807f14bd3027c4055c_layers.overlays,{position:`bottomright`,collapsed:!1,autoZIndex:!0}).addTo(map_2c9267e4f3e2aa97c3d61c1ca2758ef6);new L.Draggable(layer_control_5b7166d1bba400807f14bd3027c4055c.getContainer()).enable();var feature_group_3c841659dcf76e788d3e0355621f6596searchControl=new L.Control.Search({layer:feature_group_3c841659dcf76e788d3e0355621f6596,propertyName:`id`,collapsed:!1,textPlaceholder:`Search network elements...`,position:`topleft`,initial:!1,hideMarkerOnCollapse:!0});feature_group_3c841659dcf76e788d3e0355621f6596searchControl.on(`search:locationfound`,function(e){feature_group_3c841659dcf76e788d3e0355621f6596.setStyle(function(feature){return feature.properties.style}),e.layer._popup&&e.layer.openPopup()}),feature_group_3c841659dcf76e788d3e0355621f6596searchControl.on(`search:collapsed`,function(e){feature_group_3c841659dcf76e788d3e0355621f6596.setStyle(function(feature){return feature.properties.style})}),map_2c9267e4f3e2aa97c3d61c1ca2758ef6.addControl(feature_group_3c841659dcf76e788d3e0355621f6596searchControl);function customFlyToBounds(){let bounds=L.latLngBounds([]);map_2c9267e4f3e2aa97c3d61c1ca2758ef6.eachLayer(function(layer){typeof layer.getBounds==`function`&&bounds.extend(layer.getBounds())}),bounds.isValid()&&map_2c9267e4f3e2aa97c3d61c1ca2758ef6.fitBounds(bounds,{padding:[30,30]})}map_2c9267e4f3e2aa97c3d61c1ca2758ef6.on(`overlayadd`,customFlyToBounds),customFlyToBounds(); diff --git a/doc/_static/Network/LVFeeder27681.html b/doc/_static/Network/LVFeeder27681.html index 39ae1af3..82b88efb 100644 --- a/doc/_static/Network/LVFeeder27681.html +++ b/doc/_static/Network/LVFeeder27681.html @@ -1,433 +1,53 @@ - - - - LV Feeder 27681 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

LV Feeder 27681

- -
- -

LV Feeder 27681

- + ${handleObject(layer.feature.properties[v]).toLocaleString()} + `).join(``))+``,div},{className:`foliumpopup`}),geo_json_31dd75f589554b6a35ff2987d0ad0ebb.addTo(feature_group_sub_group_5be9c01bf2059f1ec3d87d8419079029),feature_group_sub_group_5be9c01bf2059f1ec3d87d8419079029.addTo(map_612baab8a5fe30945e87e0214c901b49);var layer_control_45411a244ded398ddf733fa58c09e519_layers={base_layers:{openstreetmap:tile_layer_203b67435483b43d9124672538e3eb6e},overlays:{"Electrical Network":feature_group_a6362d8d2b157f195c0e128f02f56158,Buses:feature_group_sub_group_4afdba4996e1305905a00f578aeeb254,Lines:feature_group_sub_group_3c5266c30e46f169ff1decbfae51228d,Transformers:feature_group_sub_group_5be9c01bf2059f1ec3d87d8419079029}};let layer_control_45411a244ded398ddf733fa58c09e519=L.control.layers(layer_control_45411a244ded398ddf733fa58c09e519_layers.base_layers,layer_control_45411a244ded398ddf733fa58c09e519_layers.overlays,{position:`bottomright`,collapsed:!1,autoZIndex:!0}).addTo(map_612baab8a5fe30945e87e0214c901b49);new L.Draggable(layer_control_45411a244ded398ddf733fa58c09e519.getContainer()).enable();var feature_group_a6362d8d2b157f195c0e128f02f56158searchControl=new L.Control.Search({layer:feature_group_a6362d8d2b157f195c0e128f02f56158,propertyName:`id`,collapsed:!1,textPlaceholder:`Search network elements...`,position:`topleft`,initial:!1,hideMarkerOnCollapse:!0});feature_group_a6362d8d2b157f195c0e128f02f56158searchControl.on(`search:locationfound`,function(e){feature_group_a6362d8d2b157f195c0e128f02f56158.setStyle(function(feature){return feature.properties.style}),e.layer._popup&&e.layer.openPopup()}),feature_group_a6362d8d2b157f195c0e128f02f56158searchControl.on(`search:collapsed`,function(e){feature_group_a6362d8d2b157f195c0e128f02f56158.setStyle(function(feature){return feature.properties.style})}),map_612baab8a5fe30945e87e0214c901b49.addControl(feature_group_a6362d8d2b157f195c0e128f02f56158searchControl);function customFlyToBounds(){let bounds=L.latLngBounds([]);map_612baab8a5fe30945e87e0214c901b49.eachLayer(function(layer){typeof layer.getBounds==`function`&&bounds.extend(layer.getBounds())}),bounds.isValid()&&map_612baab8a5fe30945e87e0214c901b49.fitBounds(bounds,{padding:[30,30]})}map_612baab8a5fe30945e87e0214c901b49.on(`overlayadd`,customFlyToBounds),customFlyToBounds(); diff --git a/doc/_static/Network/LVFeeder30216.html b/doc/_static/Network/LVFeeder30216.html index e903eab0..94cd7301 100644 --- a/doc/_static/Network/LVFeeder30216.html +++ b/doc/_static/Network/LVFeeder30216.html @@ -1,672 +1,53 @@ - - - - LV Feeder 30216 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

LV Feeder 30216

- -
- -

LV Feeder 30216

- + ${handleObject(layer.feature.properties[v]).toLocaleString()} + `).join(``))+``,div},{className:`foliumpopup`}),geo_json_f283a839d9ccd6a37592f24f21b97cd1.addTo(feature_group_sub_group_54a0621aa6b695fd274c9d018dbb7eb3),feature_group_sub_group_54a0621aa6b695fd274c9d018dbb7eb3.addTo(map_e056056a7a85def64eb6f38080e3a6f3);var layer_control_2d5072e4a5ad8bfa70e23ba4e17e6579_layers={base_layers:{openstreetmap:tile_layer_d129139e2b66de74f64d6744a5662fe1},overlays:{"Electrical Network":feature_group_fa43ca2d33bdc6fcf4941bae7c68f50f,Buses:feature_group_sub_group_113fe18066c54e4ed8d50781220d4aa2,Lines:feature_group_sub_group_192e9bbea65d222c44d9b6fb8f13dd3a,Transformers:feature_group_sub_group_54a0621aa6b695fd274c9d018dbb7eb3}};let layer_control_2d5072e4a5ad8bfa70e23ba4e17e6579=L.control.layers(layer_control_2d5072e4a5ad8bfa70e23ba4e17e6579_layers.base_layers,layer_control_2d5072e4a5ad8bfa70e23ba4e17e6579_layers.overlays,{position:`bottomright`,collapsed:!1,autoZIndex:!0}).addTo(map_e056056a7a85def64eb6f38080e3a6f3);new L.Draggable(layer_control_2d5072e4a5ad8bfa70e23ba4e17e6579.getContainer()).enable();var feature_group_fa43ca2d33bdc6fcf4941bae7c68f50fsearchControl=new L.Control.Search({layer:feature_group_fa43ca2d33bdc6fcf4941bae7c68f50f,propertyName:`id`,collapsed:!1,textPlaceholder:`Search network elements...`,position:`topleft`,initial:!1,hideMarkerOnCollapse:!0});feature_group_fa43ca2d33bdc6fcf4941bae7c68f50fsearchControl.on(`search:locationfound`,function(e){feature_group_fa43ca2d33bdc6fcf4941bae7c68f50f.setStyle(function(feature){return feature.properties.style}),e.layer._popup&&e.layer.openPopup()}),feature_group_fa43ca2d33bdc6fcf4941bae7c68f50fsearchControl.on(`search:collapsed`,function(e){feature_group_fa43ca2d33bdc6fcf4941bae7c68f50f.setStyle(function(feature){return feature.properties.style})}),map_e056056a7a85def64eb6f38080e3a6f3.addControl(feature_group_fa43ca2d33bdc6fcf4941bae7c68f50fsearchControl);function customFlyToBounds(){let bounds=L.latLngBounds([]);map_e056056a7a85def64eb6f38080e3a6f3.eachLayer(function(layer){typeof layer.getBounds==`function`&&bounds.extend(layer.getBounds())}),bounds.isValid()&&map_e056056a7a85def64eb6f38080e3a6f3.fitBounds(bounds,{padding:[30,30]})}map_e056056a7a85def64eb6f38080e3a6f3.on(`overlayadd`,customFlyToBounds),customFlyToBounds(); diff --git a/doc/_static/Network/LVFeeder31441.html b/doc/_static/Network/LVFeeder31441.html index dad3f17c..5bea30d7 100644 --- a/doc/_static/Network/LVFeeder31441.html +++ b/doc/_static/Network/LVFeeder31441.html @@ -1,485 +1,53 @@ - - - - LV Feeder 31441 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

LV Feeder 31441

- -
- -

LV Feeder 31441

- + ${handleObject(layer.feature.properties[v]).toLocaleString()} + `).join(``))+``,div},{className:`foliumpopup`}),geo_json_05707e6d66b1b77d0d050416c3a35be1.addTo(feature_group_sub_group_1cb5e0b1f33971f6203abd5ec40d7f0a),feature_group_sub_group_1cb5e0b1f33971f6203abd5ec40d7f0a.addTo(map_9f605aec557ccea8771d3db6ac1e0374);var layer_control_405193280e00fda4956597362a42da3a_layers={base_layers:{openstreetmap:tile_layer_89974fb08050688b86f7267e58e90d52},overlays:{"Electrical Network":feature_group_876e0989c05e657fd48cac95bdc38ce6,Buses:feature_group_sub_group_b56c297d612e14e743cfa56ef1c7e2da,Lines:feature_group_sub_group_e28c679b01b0b5d6b2bc724d8b3f79d1,Transformers:feature_group_sub_group_1cb5e0b1f33971f6203abd5ec40d7f0a}};let layer_control_405193280e00fda4956597362a42da3a=L.control.layers(layer_control_405193280e00fda4956597362a42da3a_layers.base_layers,layer_control_405193280e00fda4956597362a42da3a_layers.overlays,{position:`bottomright`,collapsed:!1,autoZIndex:!0}).addTo(map_9f605aec557ccea8771d3db6ac1e0374);new L.Draggable(layer_control_405193280e00fda4956597362a42da3a.getContainer()).enable();var feature_group_876e0989c05e657fd48cac95bdc38ce6searchControl=new L.Control.Search({layer:feature_group_876e0989c05e657fd48cac95bdc38ce6,propertyName:`id`,collapsed:!1,textPlaceholder:`Search network elements...`,position:`topleft`,initial:!1,hideMarkerOnCollapse:!0});feature_group_876e0989c05e657fd48cac95bdc38ce6searchControl.on(`search:locationfound`,function(e){feature_group_876e0989c05e657fd48cac95bdc38ce6.setStyle(function(feature){return feature.properties.style}),e.layer._popup&&e.layer.openPopup()}),feature_group_876e0989c05e657fd48cac95bdc38ce6searchControl.on(`search:collapsed`,function(e){feature_group_876e0989c05e657fd48cac95bdc38ce6.setStyle(function(feature){return feature.properties.style})}),map_9f605aec557ccea8771d3db6ac1e0374.addControl(feature_group_876e0989c05e657fd48cac95bdc38ce6searchControl);function customFlyToBounds(){let bounds=L.latLngBounds([]);map_9f605aec557ccea8771d3db6ac1e0374.eachLayer(function(layer){typeof layer.getBounds==`function`&&bounds.extend(layer.getBounds())}),bounds.isValid()&&map_9f605aec557ccea8771d3db6ac1e0374.fitBounds(bounds,{padding:[30,30]})}map_9f605aec557ccea8771d3db6ac1e0374.on(`overlayadd`,customFlyToBounds),customFlyToBounds(); diff --git a/doc/_static/Network/LVFeeder36284.html b/doc/_static/Network/LVFeeder36284.html index 33a9d646..daca6650 100644 --- a/doc/_static/Network/LVFeeder36284.html +++ b/doc/_static/Network/LVFeeder36284.html @@ -1,515 +1,53 @@ - - - - LV Feeder 36284 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

LV Feeder 36284

- -
- -

LV Feeder 36284

- + ${handleObject(layer.feature.properties[v]).toLocaleString()} + `).join(``))+``,div},{className:`foliumpopup`}),geo_json_02b5323e51a122aff33becf98c0a38ef.addTo(feature_group_sub_group_733d604dec22bbdc6995be9348d06549),feature_group_sub_group_733d604dec22bbdc6995be9348d06549.addTo(map_840a6a23c0761a6aa2d6ac27c37957ff);var layer_control_d5eadffb1dbdd0cd663fd04b463cdf27_layers={base_layers:{openstreetmap:tile_layer_24d98ed59a1aea3da231fb85b1f19cb8},overlays:{"Electrical Network":feature_group_7ed7496f6e9cf99668bf698f0a3f38d3,Buses:feature_group_sub_group_bb4be413636a4445599068b054da97f6,Lines:feature_group_sub_group_11b45b84c9caecfa9abba1a2d82f55a6,Transformers:feature_group_sub_group_733d604dec22bbdc6995be9348d06549}};let layer_control_d5eadffb1dbdd0cd663fd04b463cdf27=L.control.layers(layer_control_d5eadffb1dbdd0cd663fd04b463cdf27_layers.base_layers,layer_control_d5eadffb1dbdd0cd663fd04b463cdf27_layers.overlays,{position:`bottomright`,collapsed:!1,autoZIndex:!0}).addTo(map_840a6a23c0761a6aa2d6ac27c37957ff);new L.Draggable(layer_control_d5eadffb1dbdd0cd663fd04b463cdf27.getContainer()).enable();var feature_group_7ed7496f6e9cf99668bf698f0a3f38d3searchControl=new L.Control.Search({layer:feature_group_7ed7496f6e9cf99668bf698f0a3f38d3,propertyName:`id`,collapsed:!1,textPlaceholder:`Search network elements...`,position:`topleft`,initial:!1,hideMarkerOnCollapse:!0});feature_group_7ed7496f6e9cf99668bf698f0a3f38d3searchControl.on(`search:locationfound`,function(e){feature_group_7ed7496f6e9cf99668bf698f0a3f38d3.setStyle(function(feature){return feature.properties.style}),e.layer._popup&&e.layer.openPopup()}),feature_group_7ed7496f6e9cf99668bf698f0a3f38d3searchControl.on(`search:collapsed`,function(e){feature_group_7ed7496f6e9cf99668bf698f0a3f38d3.setStyle(function(feature){return feature.properties.style})}),map_840a6a23c0761a6aa2d6ac27c37957ff.addControl(feature_group_7ed7496f6e9cf99668bf698f0a3f38d3searchControl);function customFlyToBounds(){let bounds=L.latLngBounds([]);map_840a6a23c0761a6aa2d6ac27c37957ff.eachLayer(function(layer){typeof layer.getBounds==`function`&&bounds.extend(layer.getBounds())}),bounds.isValid()&&map_840a6a23c0761a6aa2d6ac27c37957ff.fitBounds(bounds,{padding:[30,30]})}map_840a6a23c0761a6aa2d6ac27c37957ff.on(`overlayadd`,customFlyToBounds),customFlyToBounds(); diff --git a/doc/_static/Network/LVFeeder36360.html b/doc/_static/Network/LVFeeder36360.html index cea30a9d..09848aea 100644 --- a/doc/_static/Network/LVFeeder36360.html +++ b/doc/_static/Network/LVFeeder36360.html @@ -1,681 +1,53 @@ - - - - LV Feeder 36360 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

LV Feeder 36360

- -
- -

LV Feeder 36360

- + ${handleObject(layer.feature.properties[v]).toLocaleString()} + `).join(``))+``,div},{className:`foliumpopup`}),geo_json_58d97fb7a9b1bde3788eece4b9afd17e.addTo(feature_group_sub_group_8e4c8edc6bd40d723aed912ebe6cabc7),feature_group_sub_group_8e4c8edc6bd40d723aed912ebe6cabc7.addTo(map_553429ddb6abcffaa4912554cf1928f9);var layer_control_1eabbaba9a529e32f21f772cee573e5d_layers={base_layers:{openstreetmap:tile_layer_4e893537c706d42020d401adcdf651c7},overlays:{"Electrical Network":feature_group_87d526cd6c0f6fbf9dec46ea0bce9273,Buses:feature_group_sub_group_65dfdb2fc8abeab8b4ab5f8001c25aa0,Lines:feature_group_sub_group_c7d3ab2c9da6d3ac8028281f2a297425,Transformers:feature_group_sub_group_8e4c8edc6bd40d723aed912ebe6cabc7}};let layer_control_1eabbaba9a529e32f21f772cee573e5d=L.control.layers(layer_control_1eabbaba9a529e32f21f772cee573e5d_layers.base_layers,layer_control_1eabbaba9a529e32f21f772cee573e5d_layers.overlays,{position:`bottomright`,collapsed:!1,autoZIndex:!0}).addTo(map_553429ddb6abcffaa4912554cf1928f9);new L.Draggable(layer_control_1eabbaba9a529e32f21f772cee573e5d.getContainer()).enable();var feature_group_87d526cd6c0f6fbf9dec46ea0bce9273searchControl=new L.Control.Search({layer:feature_group_87d526cd6c0f6fbf9dec46ea0bce9273,propertyName:`id`,collapsed:!1,textPlaceholder:`Search network elements...`,position:`topleft`,initial:!1,hideMarkerOnCollapse:!0});feature_group_87d526cd6c0f6fbf9dec46ea0bce9273searchControl.on(`search:locationfound`,function(e){feature_group_87d526cd6c0f6fbf9dec46ea0bce9273.setStyle(function(feature){return feature.properties.style}),e.layer._popup&&e.layer.openPopup()}),feature_group_87d526cd6c0f6fbf9dec46ea0bce9273searchControl.on(`search:collapsed`,function(e){feature_group_87d526cd6c0f6fbf9dec46ea0bce9273.setStyle(function(feature){return feature.properties.style})}),map_553429ddb6abcffaa4912554cf1928f9.addControl(feature_group_87d526cd6c0f6fbf9dec46ea0bce9273searchControl);function customFlyToBounds(){let bounds=L.latLngBounds([]);map_553429ddb6abcffaa4912554cf1928f9.eachLayer(function(layer){typeof layer.getBounds==`function`&&bounds.extend(layer.getBounds())}),bounds.isValid()&&map_553429ddb6abcffaa4912554cf1928f9.fitBounds(bounds,{padding:[30,30]})}map_553429ddb6abcffaa4912554cf1928f9.on(`overlayadd`,customFlyToBounds),customFlyToBounds(); diff --git a/doc/_static/Network/LVFeeder37263.html b/doc/_static/Network/LVFeeder37263.html index 28b287e6..fa9b653a 100644 --- a/doc/_static/Network/LVFeeder37263.html +++ b/doc/_static/Network/LVFeeder37263.html @@ -1,439 +1,53 @@ - - - - LV Feeder 37263 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

LV Feeder 37263

- -
- -

LV Feeder 37263

- + ${handleObject(layer.feature.properties[v]).toLocaleString()} + `).join(``))+``,div},{className:`foliumpopup`}),geo_json_edeb213154cf2d65fe6eaa4e247d2352.addTo(feature_group_sub_group_9382afbe244eb96aca9378a5126a7ad9),feature_group_sub_group_9382afbe244eb96aca9378a5126a7ad9.addTo(map_2451c58fd1bc0c1398cbba9fd5ccab3b);var layer_control_1eb3a6790fd8bd8389f53e57d319fd64_layers={base_layers:{openstreetmap:tile_layer_f32b553678a11bee888901f4d65abbfd},overlays:{"Electrical Network":feature_group_ca2504a6abb7e720807d7378e6449609,Buses:feature_group_sub_group_c8050209b1cdf9e38b7c39bb224f939d,Lines:feature_group_sub_group_b3389b25f373563ee571679b5c5c36a4,Transformers:feature_group_sub_group_9382afbe244eb96aca9378a5126a7ad9}};let layer_control_1eb3a6790fd8bd8389f53e57d319fd64=L.control.layers(layer_control_1eb3a6790fd8bd8389f53e57d319fd64_layers.base_layers,layer_control_1eb3a6790fd8bd8389f53e57d319fd64_layers.overlays,{position:`bottomright`,collapsed:!1,autoZIndex:!0}).addTo(map_2451c58fd1bc0c1398cbba9fd5ccab3b);new L.Draggable(layer_control_1eb3a6790fd8bd8389f53e57d319fd64.getContainer()).enable();var feature_group_ca2504a6abb7e720807d7378e6449609searchControl=new L.Control.Search({layer:feature_group_ca2504a6abb7e720807d7378e6449609,propertyName:`id`,collapsed:!1,textPlaceholder:`Search network elements...`,position:`topleft`,initial:!1,hideMarkerOnCollapse:!0});feature_group_ca2504a6abb7e720807d7378e6449609searchControl.on(`search:locationfound`,function(e){feature_group_ca2504a6abb7e720807d7378e6449609.setStyle(function(feature){return feature.properties.style}),e.layer._popup&&e.layer.openPopup()}),feature_group_ca2504a6abb7e720807d7378e6449609searchControl.on(`search:collapsed`,function(e){feature_group_ca2504a6abb7e720807d7378e6449609.setStyle(function(feature){return feature.properties.style})}),map_2451c58fd1bc0c1398cbba9fd5ccab3b.addControl(feature_group_ca2504a6abb7e720807d7378e6449609searchControl);function customFlyToBounds(){let bounds=L.latLngBounds([]);map_2451c58fd1bc0c1398cbba9fd5ccab3b.eachLayer(function(layer){typeof layer.getBounds==`function`&&bounds.extend(layer.getBounds())}),bounds.isValid()&&map_2451c58fd1bc0c1398cbba9fd5ccab3b.fitBounds(bounds,{padding:[30,30]})}map_2451c58fd1bc0c1398cbba9fd5ccab3b.on(`overlayadd`,customFlyToBounds),customFlyToBounds(); diff --git a/doc/_static/Network/LVFeeder38211.html b/doc/_static/Network/LVFeeder38211.html index ada1bdc4..d0804cd0 100644 --- a/doc/_static/Network/LVFeeder38211.html +++ b/doc/_static/Network/LVFeeder38211.html @@ -1,553 +1,53 @@ - - - - LV Feeder 38211 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

LV Feeder 38211

- -
- -

LV Feeder 38211

- + ${handleObject(layer.feature.properties[v]).toLocaleString()} + `).join(``))+``,div},{className:`foliumpopup`}),geo_json_f86c974c9621743e559eff2be345091b.addTo(feature_group_sub_group_9b2f99c65424a92170aa007ce05b6f78),feature_group_sub_group_9b2f99c65424a92170aa007ce05b6f78.addTo(map_aef5f6d696f1477afa5cda845ce73ad3);var layer_control_32a9ca93bc0797760bbc130353c836e4_layers={base_layers:{openstreetmap:tile_layer_0416494fae0ea7122af023c06f7d180d},overlays:{"Electrical Network":feature_group_8dcd770b700162e348aa2782ac4bba8e,Buses:feature_group_sub_group_11bac3935ccbc2ab49023b0a58716650,Lines:feature_group_sub_group_1cbddad57048e7b816546b8fd21cec3a,Transformers:feature_group_sub_group_9b2f99c65424a92170aa007ce05b6f78}};let layer_control_32a9ca93bc0797760bbc130353c836e4=L.control.layers(layer_control_32a9ca93bc0797760bbc130353c836e4_layers.base_layers,layer_control_32a9ca93bc0797760bbc130353c836e4_layers.overlays,{position:`bottomright`,collapsed:!1,autoZIndex:!0}).addTo(map_aef5f6d696f1477afa5cda845ce73ad3);new L.Draggable(layer_control_32a9ca93bc0797760bbc130353c836e4.getContainer()).enable();var feature_group_8dcd770b700162e348aa2782ac4bba8esearchControl=new L.Control.Search({layer:feature_group_8dcd770b700162e348aa2782ac4bba8e,propertyName:`id`,collapsed:!1,textPlaceholder:`Search network elements...`,position:`topleft`,initial:!1,hideMarkerOnCollapse:!0});feature_group_8dcd770b700162e348aa2782ac4bba8esearchControl.on(`search:locationfound`,function(e){feature_group_8dcd770b700162e348aa2782ac4bba8e.setStyle(function(feature){return feature.properties.style}),e.layer._popup&&e.layer.openPopup()}),feature_group_8dcd770b700162e348aa2782ac4bba8esearchControl.on(`search:collapsed`,function(e){feature_group_8dcd770b700162e348aa2782ac4bba8e.setStyle(function(feature){return feature.properties.style})}),map_aef5f6d696f1477afa5cda845ce73ad3.addControl(feature_group_8dcd770b700162e348aa2782ac4bba8esearchControl);function customFlyToBounds(){let bounds=L.latLngBounds([]);map_aef5f6d696f1477afa5cda845ce73ad3.eachLayer(function(layer){typeof layer.getBounds==`function`&&bounds.extend(layer.getBounds())}),bounds.isValid()&&map_aef5f6d696f1477afa5cda845ce73ad3.fitBounds(bounds,{padding:[30,30]})}map_aef5f6d696f1477afa5cda845ce73ad3.on(`overlayadd`,customFlyToBounds),customFlyToBounds(); diff --git a/doc/_static/Network/MVFeeder004.html b/doc/_static/Network/MVFeeder004.html index a24812c2..70f65bd2 100644 --- a/doc/_static/Network/MVFeeder004.html +++ b/doc/_static/Network/MVFeeder004.html @@ -1,1031 +1,37 @@ - - - - MV Feeder 004 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

MV Feeder 004

- -
- -

MV Feeder 004

- + ${handleObject(layer.feature.properties[v]).toLocaleString()} + `).join(``))+``,div},{className:`foliumpopup`}),geo_json_bcc6e0a1008ba52aaebb7ecc4bb803a1.addTo(feature_group_sub_group_732dad6b6e511d51f98527ceca2d5e23),feature_group_sub_group_732dad6b6e511d51f98527ceca2d5e23.addTo(map_b20c079c0aeea016c09ba870ddbbe6c5);var layer_control_348f7a05d9e9d996f28dc1d83f6835bc_layers={base_layers:{openstreetmap:tile_layer_33194f77b3ab2b6b42f61aee9771e19c},overlays:{"Electrical Network":feature_group_bbccab990bea586ff0f68f38554a6610,Buses:feature_group_sub_group_a890883b65ede3c2161e21fc974208a8,Lines:feature_group_sub_group_732dad6b6e511d51f98527ceca2d5e23}};let layer_control_348f7a05d9e9d996f28dc1d83f6835bc=L.control.layers(layer_control_348f7a05d9e9d996f28dc1d83f6835bc_layers.base_layers,layer_control_348f7a05d9e9d996f28dc1d83f6835bc_layers.overlays,{position:`bottomright`,collapsed:!1,autoZIndex:!0}).addTo(map_b20c079c0aeea016c09ba870ddbbe6c5);new L.Draggable(layer_control_348f7a05d9e9d996f28dc1d83f6835bc.getContainer()).enable();var feature_group_bbccab990bea586ff0f68f38554a6610searchControl=new L.Control.Search({layer:feature_group_bbccab990bea586ff0f68f38554a6610,propertyName:`id`,collapsed:!1,textPlaceholder:`Search network elements...`,position:`topleft`,initial:!1,hideMarkerOnCollapse:!0});feature_group_bbccab990bea586ff0f68f38554a6610searchControl.on(`search:locationfound`,function(e){feature_group_bbccab990bea586ff0f68f38554a6610.setStyle(function(feature){return feature.properties.style}),e.layer._popup&&e.layer.openPopup()}),feature_group_bbccab990bea586ff0f68f38554a6610searchControl.on(`search:collapsed`,function(e){feature_group_bbccab990bea586ff0f68f38554a6610.setStyle(function(feature){return feature.properties.style})}),map_b20c079c0aeea016c09ba870ddbbe6c5.addControl(feature_group_bbccab990bea586ff0f68f38554a6610searchControl);function customFlyToBounds(){let bounds=L.latLngBounds([]);map_b20c079c0aeea016c09ba870ddbbe6c5.eachLayer(function(layer){typeof layer.getBounds==`function`&&bounds.extend(layer.getBounds())}),bounds.isValid()&&map_b20c079c0aeea016c09ba870ddbbe6c5.fitBounds(bounds,{padding:[30,30]})}map_b20c079c0aeea016c09ba870ddbbe6c5.on(`overlayadd`,customFlyToBounds),customFlyToBounds(); diff --git a/doc/_static/Network/MVFeeder011.html b/doc/_static/Network/MVFeeder011.html index 38597bf5..05304470 100644 --- a/doc/_static/Network/MVFeeder011.html +++ b/doc/_static/Network/MVFeeder011.html @@ -1,2736 +1,37 @@ - - - - MV Feeder 011 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

MV Feeder 011

- -
- -

MV Feeder 011

- + ${handleObject(layer.feature.properties[v]).toLocaleString()} + `).join(``))+``,div},{className:`foliumpopup`}),geo_json_d19ac68f7150f42c8dcf8d40fefaac3b.addTo(feature_group_sub_group_89b1a5319cb5bfb9ab586e3acf9ae3fb),feature_group_sub_group_89b1a5319cb5bfb9ab586e3acf9ae3fb.addTo(map_dd58a2cf6cbf834c3254e5dd50de21c5);var layer_control_133d2e6907e9a03f0df33bfb8ad5acec_layers={base_layers:{openstreetmap:tile_layer_1cb3e0caf2cd3aef11db7049c48399b1},overlays:{"Electrical Network":feature_group_f96313327808bfcc1b71eec0319fc499,Buses:feature_group_sub_group_1b8d481ebf7d60aeeabea3b4430ddc87,Lines:feature_group_sub_group_89b1a5319cb5bfb9ab586e3acf9ae3fb}};let layer_control_133d2e6907e9a03f0df33bfb8ad5acec=L.control.layers(layer_control_133d2e6907e9a03f0df33bfb8ad5acec_layers.base_layers,layer_control_133d2e6907e9a03f0df33bfb8ad5acec_layers.overlays,{position:`bottomright`,collapsed:!1,autoZIndex:!0}).addTo(map_dd58a2cf6cbf834c3254e5dd50de21c5);new L.Draggable(layer_control_133d2e6907e9a03f0df33bfb8ad5acec.getContainer()).enable();var feature_group_f96313327808bfcc1b71eec0319fc499searchControl=new L.Control.Search({layer:feature_group_f96313327808bfcc1b71eec0319fc499,propertyName:`id`,collapsed:!1,textPlaceholder:`Search network elements...`,position:`topleft`,initial:!1,hideMarkerOnCollapse:!0});feature_group_f96313327808bfcc1b71eec0319fc499searchControl.on(`search:locationfound`,function(e){feature_group_f96313327808bfcc1b71eec0319fc499.setStyle(function(feature){return feature.properties.style}),e.layer._popup&&e.layer.openPopup()}),feature_group_f96313327808bfcc1b71eec0319fc499searchControl.on(`search:collapsed`,function(e){feature_group_f96313327808bfcc1b71eec0319fc499.setStyle(function(feature){return feature.properties.style})}),map_dd58a2cf6cbf834c3254e5dd50de21c5.addControl(feature_group_f96313327808bfcc1b71eec0319fc499searchControl);function customFlyToBounds(){let bounds=L.latLngBounds([]);map_dd58a2cf6cbf834c3254e5dd50de21c5.eachLayer(function(layer){typeof layer.getBounds==`function`&&bounds.extend(layer.getBounds())}),bounds.isValid()&&map_dd58a2cf6cbf834c3254e5dd50de21c5.fitBounds(bounds,{padding:[30,30]})}map_dd58a2cf6cbf834c3254e5dd50de21c5.on(`overlayadd`,customFlyToBounds),customFlyToBounds(); diff --git a/doc/_static/Network/MVFeeder015.html b/doc/_static/Network/MVFeeder015.html index 2c7f9eeb..f6126d95 100644 --- a/doc/_static/Network/MVFeeder015.html +++ b/doc/_static/Network/MVFeeder015.html @@ -1,1614 +1,37 @@ - - - - MV Feeder 015 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

MV Feeder 015

- -
- -

MV Feeder 015

- + ${handleObject(layer.feature.properties[v]).toLocaleString()} + `).join(``))+``,div},{className:`foliumpopup`}),geo_json_30427a8ad75d1e510e523ad5cdbce36b.addTo(feature_group_sub_group_a6f4b647ef602801249753aa60914364),feature_group_sub_group_a6f4b647ef602801249753aa60914364.addTo(map_708c0f4106bd247a4225caab1cf68e00);var layer_control_0cd2d2df049fc70f0fc647c4b53f0af8_layers={base_layers:{openstreetmap:tile_layer_80424c561da0bffb02a458d02a9f980e},overlays:{"Electrical Network":feature_group_16dfc1c7aea799cdda0bcda84b5d1909,Buses:feature_group_sub_group_3afbc7ce144d575820294653bcd8a72c,Lines:feature_group_sub_group_a6f4b647ef602801249753aa60914364}};let layer_control_0cd2d2df049fc70f0fc647c4b53f0af8=L.control.layers(layer_control_0cd2d2df049fc70f0fc647c4b53f0af8_layers.base_layers,layer_control_0cd2d2df049fc70f0fc647c4b53f0af8_layers.overlays,{position:`bottomright`,collapsed:!1,autoZIndex:!0}).addTo(map_708c0f4106bd247a4225caab1cf68e00);new L.Draggable(layer_control_0cd2d2df049fc70f0fc647c4b53f0af8.getContainer()).enable();var feature_group_16dfc1c7aea799cdda0bcda84b5d1909searchControl=new L.Control.Search({layer:feature_group_16dfc1c7aea799cdda0bcda84b5d1909,propertyName:`id`,collapsed:!1,textPlaceholder:`Search network elements...`,position:`topleft`,initial:!1,hideMarkerOnCollapse:!0});feature_group_16dfc1c7aea799cdda0bcda84b5d1909searchControl.on(`search:locationfound`,function(e){feature_group_16dfc1c7aea799cdda0bcda84b5d1909.setStyle(function(feature){return feature.properties.style}),e.layer._popup&&e.layer.openPopup()}),feature_group_16dfc1c7aea799cdda0bcda84b5d1909searchControl.on(`search:collapsed`,function(e){feature_group_16dfc1c7aea799cdda0bcda84b5d1909.setStyle(function(feature){return feature.properties.style})}),map_708c0f4106bd247a4225caab1cf68e00.addControl(feature_group_16dfc1c7aea799cdda0bcda84b5d1909searchControl);function customFlyToBounds(){let bounds=L.latLngBounds([]);map_708c0f4106bd247a4225caab1cf68e00.eachLayer(function(layer){typeof layer.getBounds==`function`&&bounds.extend(layer.getBounds())}),bounds.isValid()&&map_708c0f4106bd247a4225caab1cf68e00.fitBounds(bounds,{padding:[30,30]})}map_708c0f4106bd247a4225caab1cf68e00.on(`overlayadd`,customFlyToBounds),customFlyToBounds(); diff --git a/doc/_static/Network/MVFeeder032.html b/doc/_static/Network/MVFeeder032.html index 98476f66..4de90f86 100644 --- a/doc/_static/Network/MVFeeder032.html +++ b/doc/_static/Network/MVFeeder032.html @@ -1,2568 +1,37 @@ - - - - MV Feeder 032 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

MV Feeder 032

- -
- -

MV Feeder 032

- + ${handleObject(layer.feature.properties[v]).toLocaleString()} + `).join(``))+``,div},{className:`foliumpopup`}),geo_json_035a36d4259122f70f278a5656b3ea20.addTo(feature_group_sub_group_aab12b56b133dbf874a0c970dc9716df),feature_group_sub_group_aab12b56b133dbf874a0c970dc9716df.addTo(map_3515078c5b8bf29e6b6cb6c0cea5137b);var layer_control_69b5db394572086e3fec8212b5f6ab4a_layers={base_layers:{openstreetmap:tile_layer_0254d6656c85e825892ccfe1a4c4cd0f},overlays:{"Electrical Network":feature_group_0328d5562d445a250bfabe990b1ae428,Buses:feature_group_sub_group_35a43897603e64e16ed9b8f93cf49629,Lines:feature_group_sub_group_aab12b56b133dbf874a0c970dc9716df}};let layer_control_69b5db394572086e3fec8212b5f6ab4a=L.control.layers(layer_control_69b5db394572086e3fec8212b5f6ab4a_layers.base_layers,layer_control_69b5db394572086e3fec8212b5f6ab4a_layers.overlays,{position:`bottomright`,collapsed:!1,autoZIndex:!0}).addTo(map_3515078c5b8bf29e6b6cb6c0cea5137b);new L.Draggable(layer_control_69b5db394572086e3fec8212b5f6ab4a.getContainer()).enable();var feature_group_0328d5562d445a250bfabe990b1ae428searchControl=new L.Control.Search({layer:feature_group_0328d5562d445a250bfabe990b1ae428,propertyName:`id`,collapsed:!1,textPlaceholder:`Search network elements...`,position:`topleft`,initial:!1,hideMarkerOnCollapse:!0});feature_group_0328d5562d445a250bfabe990b1ae428searchControl.on(`search:locationfound`,function(e){feature_group_0328d5562d445a250bfabe990b1ae428.setStyle(function(feature){return feature.properties.style}),e.layer._popup&&e.layer.openPopup()}),feature_group_0328d5562d445a250bfabe990b1ae428searchControl.on(`search:collapsed`,function(e){feature_group_0328d5562d445a250bfabe990b1ae428.setStyle(function(feature){return feature.properties.style})}),map_3515078c5b8bf29e6b6cb6c0cea5137b.addControl(feature_group_0328d5562d445a250bfabe990b1ae428searchControl);function customFlyToBounds(){let bounds=L.latLngBounds([]);map_3515078c5b8bf29e6b6cb6c0cea5137b.eachLayer(function(layer){typeof layer.getBounds==`function`&&bounds.extend(layer.getBounds())}),bounds.isValid()&&map_3515078c5b8bf29e6b6cb6c0cea5137b.fitBounds(bounds,{padding:[30,30]})}map_3515078c5b8bf29e6b6cb6c0cea5137b.on(`overlayadd`,customFlyToBounds),customFlyToBounds(); diff --git a/doc/_static/Network/MVFeeder041.html b/doc/_static/Network/MVFeeder041.html index 6c089b70..3d7b9950 100644 --- a/doc/_static/Network/MVFeeder041.html +++ b/doc/_static/Network/MVFeeder041.html @@ -1,3920 +1,37 @@ - - - - MV Feeder 041 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

MV Feeder 041

- -
- -

MV Feeder 041

- + ${handleObject(layer.feature.properties[v]).toLocaleString()} + `).join(``))+``,div},{className:`foliumpopup`}),geo_json_af9eb521f3c171d9909c90851d30f8bd.addTo(feature_group_sub_group_fea5831cf639f2c7ad900a9fbb4e4c4d),feature_group_sub_group_fea5831cf639f2c7ad900a9fbb4e4c4d.addTo(map_3ab88a26145db36e8455b34490ae1c5a);var layer_control_f7eaa11e9c3455938061a7800820e27b_layers={base_layers:{openstreetmap:tile_layer_9efc194a8aae8cd517e3299c7e6caa5d},overlays:{"Electrical Network":feature_group_e8e2bb5538b828e4184b1ddf6334d333,Buses:feature_group_sub_group_b304d28100f366f9f20016ea3df9bf01,Lines:feature_group_sub_group_fea5831cf639f2c7ad900a9fbb4e4c4d}};let layer_control_f7eaa11e9c3455938061a7800820e27b=L.control.layers(layer_control_f7eaa11e9c3455938061a7800820e27b_layers.base_layers,layer_control_f7eaa11e9c3455938061a7800820e27b_layers.overlays,{position:`bottomright`,collapsed:!1,autoZIndex:!0}).addTo(map_3ab88a26145db36e8455b34490ae1c5a);new L.Draggable(layer_control_f7eaa11e9c3455938061a7800820e27b.getContainer()).enable();var feature_group_e8e2bb5538b828e4184b1ddf6334d333searchControl=new L.Control.Search({layer:feature_group_e8e2bb5538b828e4184b1ddf6334d333,propertyName:`id`,collapsed:!1,textPlaceholder:`Search network elements...`,position:`topleft`,initial:!1,hideMarkerOnCollapse:!0});feature_group_e8e2bb5538b828e4184b1ddf6334d333searchControl.on(`search:locationfound`,function(e){feature_group_e8e2bb5538b828e4184b1ddf6334d333.setStyle(function(feature){return feature.properties.style}),e.layer._popup&&e.layer.openPopup()}),feature_group_e8e2bb5538b828e4184b1ddf6334d333searchControl.on(`search:collapsed`,function(e){feature_group_e8e2bb5538b828e4184b1ddf6334d333.setStyle(function(feature){return feature.properties.style})}),map_3ab88a26145db36e8455b34490ae1c5a.addControl(feature_group_e8e2bb5538b828e4184b1ddf6334d333searchControl);function customFlyToBounds(){let bounds=L.latLngBounds([]);map_3ab88a26145db36e8455b34490ae1c5a.eachLayer(function(layer){typeof layer.getBounds==`function`&&bounds.extend(layer.getBounds())}),bounds.isValid()&&map_3ab88a26145db36e8455b34490ae1c5a.fitBounds(bounds,{padding:[30,30]})}map_3ab88a26145db36e8455b34490ae1c5a.on(`overlayadd`,customFlyToBounds),customFlyToBounds(); diff --git a/doc/_static/Network/MVFeeder063.html b/doc/_static/Network/MVFeeder063.html index 36929d25..d2de4d2b 100644 --- a/doc/_static/Network/MVFeeder063.html +++ b/doc/_static/Network/MVFeeder063.html @@ -1,1990 +1,37 @@ - - - - MV Feeder 063 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

MV Feeder 063

- -
- -

MV Feeder 063

- + ${handleObject(layer.feature.properties[v]).toLocaleString()} + `).join(``))+``,div},{className:`foliumpopup`}),geo_json_b4394803aa1b5904e4355761501bd072.addTo(feature_group_sub_group_0602905f2c93f7eaa83202019cef3d32),feature_group_sub_group_0602905f2c93f7eaa83202019cef3d32.addTo(map_c5fc2db49fc91b5c21a7b2dfc15df404);var layer_control_b4fb83f486a2c12a436de785b5a68827_layers={base_layers:{openstreetmap:tile_layer_cacca3cc09290e0f727638d4d6b670cd},overlays:{"Electrical Network":feature_group_cfee4559e73b0b46b7c5d343f28a62e0,Buses:feature_group_sub_group_faa45587cc11c8f2ab39d25426f7fee0,Lines:feature_group_sub_group_0602905f2c93f7eaa83202019cef3d32}};let layer_control_b4fb83f486a2c12a436de785b5a68827=L.control.layers(layer_control_b4fb83f486a2c12a436de785b5a68827_layers.base_layers,layer_control_b4fb83f486a2c12a436de785b5a68827_layers.overlays,{position:`bottomright`,collapsed:!1,autoZIndex:!0}).addTo(map_c5fc2db49fc91b5c21a7b2dfc15df404);new L.Draggable(layer_control_b4fb83f486a2c12a436de785b5a68827.getContainer()).enable();var feature_group_cfee4559e73b0b46b7c5d343f28a62e0searchControl=new L.Control.Search({layer:feature_group_cfee4559e73b0b46b7c5d343f28a62e0,propertyName:`id`,collapsed:!1,textPlaceholder:`Search network elements...`,position:`topleft`,initial:!1,hideMarkerOnCollapse:!0});feature_group_cfee4559e73b0b46b7c5d343f28a62e0searchControl.on(`search:locationfound`,function(e){feature_group_cfee4559e73b0b46b7c5d343f28a62e0.setStyle(function(feature){return feature.properties.style}),e.layer._popup&&e.layer.openPopup()}),feature_group_cfee4559e73b0b46b7c5d343f28a62e0searchControl.on(`search:collapsed`,function(e){feature_group_cfee4559e73b0b46b7c5d343f28a62e0.setStyle(function(feature){return feature.properties.style})}),map_c5fc2db49fc91b5c21a7b2dfc15df404.addControl(feature_group_cfee4559e73b0b46b7c5d343f28a62e0searchControl);function customFlyToBounds(){let bounds=L.latLngBounds([]);map_c5fc2db49fc91b5c21a7b2dfc15df404.eachLayer(function(layer){typeof layer.getBounds==`function`&&bounds.extend(layer.getBounds())}),bounds.isValid()&&map_c5fc2db49fc91b5c21a7b2dfc15df404.fitBounds(bounds,{padding:[30,30]})}map_c5fc2db49fc91b5c21a7b2dfc15df404.on(`overlayadd`,customFlyToBounds),customFlyToBounds(); diff --git a/doc/_static/Network/MVFeeder078.html b/doc/_static/Network/MVFeeder078.html index 1b479500..9f6f1d1e 100644 --- a/doc/_static/Network/MVFeeder078.html +++ b/doc/_static/Network/MVFeeder078.html @@ -1,3433 +1,37 @@ - - - - MV Feeder 078 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

MV Feeder 078

- -
- -

MV Feeder 078

- + ${handleObject(layer.feature.properties[v]).toLocaleString()} + `).join(``))+``,div},{className:`foliumpopup`}),geo_json_1e9900ad89cdc6da3460bdf102e19bfb.addTo(feature_group_sub_group_4bc17e7a249ae2c9ec560f7952aab7b5),feature_group_sub_group_4bc17e7a249ae2c9ec560f7952aab7b5.addTo(map_9fc79fbbaed1681bf4e21a48317bef4a);var layer_control_f16faf35801ee20e045aa165ec1b4788_layers={base_layers:{openstreetmap:tile_layer_35af3471c611aed77069d50ebfd1bc98},overlays:{"Electrical Network":feature_group_5093b1e289f42e102757788cf659b422,Buses:feature_group_sub_group_252ce46696ff86546af1a89d8deadeaf,Lines:feature_group_sub_group_4bc17e7a249ae2c9ec560f7952aab7b5}};let layer_control_f16faf35801ee20e045aa165ec1b4788=L.control.layers(layer_control_f16faf35801ee20e045aa165ec1b4788_layers.base_layers,layer_control_f16faf35801ee20e045aa165ec1b4788_layers.overlays,{position:`bottomright`,collapsed:!1,autoZIndex:!0}).addTo(map_9fc79fbbaed1681bf4e21a48317bef4a);new L.Draggable(layer_control_f16faf35801ee20e045aa165ec1b4788.getContainer()).enable();var feature_group_5093b1e289f42e102757788cf659b422searchControl=new L.Control.Search({layer:feature_group_5093b1e289f42e102757788cf659b422,propertyName:`id`,collapsed:!1,textPlaceholder:`Search network elements...`,position:`topleft`,initial:!1,hideMarkerOnCollapse:!0});feature_group_5093b1e289f42e102757788cf659b422searchControl.on(`search:locationfound`,function(e){feature_group_5093b1e289f42e102757788cf659b422.setStyle(function(feature){return feature.properties.style}),e.layer._popup&&e.layer.openPopup()}),feature_group_5093b1e289f42e102757788cf659b422searchControl.on(`search:collapsed`,function(e){feature_group_5093b1e289f42e102757788cf659b422.setStyle(function(feature){return feature.properties.style})}),map_9fc79fbbaed1681bf4e21a48317bef4a.addControl(feature_group_5093b1e289f42e102757788cf659b422searchControl);function customFlyToBounds(){let bounds=L.latLngBounds([]);map_9fc79fbbaed1681bf4e21a48317bef4a.eachLayer(function(layer){typeof layer.getBounds==`function`&&bounds.extend(layer.getBounds())}),bounds.isValid()&&map_9fc79fbbaed1681bf4e21a48317bef4a.fitBounds(bounds,{padding:[30,30]})}map_9fc79fbbaed1681bf4e21a48317bef4a.on(`overlayadd`,customFlyToBounds),customFlyToBounds(); diff --git a/doc/_static/Network/MVFeeder115.html b/doc/_static/Network/MVFeeder115.html index c189e4eb..94a97f8a 100644 --- a/doc/_static/Network/MVFeeder115.html +++ b/doc/_static/Network/MVFeeder115.html @@ -1,620 +1,37 @@ - - - - MV Feeder 115 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

MV Feeder 115

- -
- -

MV Feeder 115

- + ${handleObject(layer.feature.properties[v]).toLocaleString()} + `).join(``))+``,div},{className:`foliumpopup`}),geo_json_63f8eeb420e7aa69574c37a8ddf344ff.addTo(feature_group_sub_group_a5eb95d421d275d3a6c05bef32f9b3bd),feature_group_sub_group_a5eb95d421d275d3a6c05bef32f9b3bd.addTo(map_6c93c70b981ec88337c5f72a3479624e);var layer_control_c2c9a3c1e294c5c739200d0f10c225b9_layers={base_layers:{openstreetmap:tile_layer_c952986caca21bff46e4bb9bade40271},overlays:{"Electrical Network":feature_group_08a227b6e37a90ac4edca38000d3ea3e,Buses:feature_group_sub_group_bb7aff3e9eb5fd5152775c739ee68ede,Lines:feature_group_sub_group_a5eb95d421d275d3a6c05bef32f9b3bd}};let layer_control_c2c9a3c1e294c5c739200d0f10c225b9=L.control.layers(layer_control_c2c9a3c1e294c5c739200d0f10c225b9_layers.base_layers,layer_control_c2c9a3c1e294c5c739200d0f10c225b9_layers.overlays,{position:`bottomright`,collapsed:!1,autoZIndex:!0}).addTo(map_6c93c70b981ec88337c5f72a3479624e);new L.Draggable(layer_control_c2c9a3c1e294c5c739200d0f10c225b9.getContainer()).enable();var feature_group_08a227b6e37a90ac4edca38000d3ea3esearchControl=new L.Control.Search({layer:feature_group_08a227b6e37a90ac4edca38000d3ea3e,propertyName:`id`,collapsed:!1,textPlaceholder:`Search network elements...`,position:`topleft`,initial:!1,hideMarkerOnCollapse:!0});feature_group_08a227b6e37a90ac4edca38000d3ea3esearchControl.on(`search:locationfound`,function(e){feature_group_08a227b6e37a90ac4edca38000d3ea3e.setStyle(function(feature){return feature.properties.style}),e.layer._popup&&e.layer.openPopup()}),feature_group_08a227b6e37a90ac4edca38000d3ea3esearchControl.on(`search:collapsed`,function(e){feature_group_08a227b6e37a90ac4edca38000d3ea3e.setStyle(function(feature){return feature.properties.style})}),map_6c93c70b981ec88337c5f72a3479624e.addControl(feature_group_08a227b6e37a90ac4edca38000d3ea3esearchControl);function customFlyToBounds(){let bounds=L.latLngBounds([]);map_6c93c70b981ec88337c5f72a3479624e.eachLayer(function(layer){typeof layer.getBounds==`function`&&bounds.extend(layer.getBounds())}),bounds.isValid()&&map_6c93c70b981ec88337c5f72a3479624e.fitBounds(bounds,{padding:[30,30]})}map_6c93c70b981ec88337c5f72a3479624e.on(`overlayadd`,customFlyToBounds),customFlyToBounds(); diff --git a/doc/_static/Network/MVFeeder128.html b/doc/_static/Network/MVFeeder128.html index 8b6a7c2d..1d375a2d 100644 --- a/doc/_static/Network/MVFeeder128.html +++ b/doc/_static/Network/MVFeeder128.html @@ -1,2909 +1,37 @@ - - - - MV Feeder 128 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

MV Feeder 128

- -
- -

MV Feeder 128

- + ${handleObject(layer.feature.properties[v]).toLocaleString()} + `).join(``))+``,div},{className:`foliumpopup`}),geo_json_18e82920c6ee68c831036cbbc6550afa.addTo(feature_group_sub_group_534cd31b974775c02fd6aca8e091db3b),feature_group_sub_group_534cd31b974775c02fd6aca8e091db3b.addTo(map_f49fc7ca5d60b28ee094519686eb3390);var layer_control_bd8d528c4f3a73b93bca2eb62d0b3a69_layers={base_layers:{openstreetmap:tile_layer_394da49873f76209393e379965d37711},overlays:{"Electrical Network":feature_group_9b0714443e4f240114175352a546a019,Buses:feature_group_sub_group_f87920a3249209ee6ef0b2dee5456eed,Lines:feature_group_sub_group_534cd31b974775c02fd6aca8e091db3b}};let layer_control_bd8d528c4f3a73b93bca2eb62d0b3a69=L.control.layers(layer_control_bd8d528c4f3a73b93bca2eb62d0b3a69_layers.base_layers,layer_control_bd8d528c4f3a73b93bca2eb62d0b3a69_layers.overlays,{position:`bottomright`,collapsed:!1,autoZIndex:!0}).addTo(map_f49fc7ca5d60b28ee094519686eb3390);new L.Draggable(layer_control_bd8d528c4f3a73b93bca2eb62d0b3a69.getContainer()).enable();var feature_group_9b0714443e4f240114175352a546a019searchControl=new L.Control.Search({layer:feature_group_9b0714443e4f240114175352a546a019,propertyName:`id`,collapsed:!1,textPlaceholder:`Search network elements...`,position:`topleft`,initial:!1,hideMarkerOnCollapse:!0});feature_group_9b0714443e4f240114175352a546a019searchControl.on(`search:locationfound`,function(e){feature_group_9b0714443e4f240114175352a546a019.setStyle(function(feature){return feature.properties.style}),e.layer._popup&&e.layer.openPopup()}),feature_group_9b0714443e4f240114175352a546a019searchControl.on(`search:collapsed`,function(e){feature_group_9b0714443e4f240114175352a546a019.setStyle(function(feature){return feature.properties.style})}),map_f49fc7ca5d60b28ee094519686eb3390.addControl(feature_group_9b0714443e4f240114175352a546a019searchControl);function customFlyToBounds(){let bounds=L.latLngBounds([]);map_f49fc7ca5d60b28ee094519686eb3390.eachLayer(function(layer){typeof layer.getBounds==`function`&&bounds.extend(layer.getBounds())}),bounds.isValid()&&map_f49fc7ca5d60b28ee094519686eb3390.fitBounds(bounds,{padding:[30,30]})}map_f49fc7ca5d60b28ee094519686eb3390.on(`overlayadd`,customFlyToBounds),customFlyToBounds(); diff --git a/doc/_static/Network/MVFeeder151.html b/doc/_static/Network/MVFeeder151.html index 7bce0591..f49f8c21 100644 --- a/doc/_static/Network/MVFeeder151.html +++ b/doc/_static/Network/MVFeeder151.html @@ -1,2696 +1,37 @@ - - - - MV Feeder 151 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

MV Feeder 151

- -
- -

MV Feeder 151

- + ${handleObject(layer.feature.properties[v]).toLocaleString()} + `).join(``))+``,div},{className:`foliumpopup`}),geo_json_f3672b73a51562a4d06ae6f96daae2d3.addTo(feature_group_sub_group_f09b151cbe705aeeb111da0fb8c76799),feature_group_sub_group_f09b151cbe705aeeb111da0fb8c76799.addTo(map_bfdb1813acfa5d98b9eec89b1cfdbd89);var layer_control_8b27f472ce4054e0832c1ca820e40585_layers={base_layers:{openstreetmap:tile_layer_f018c12bc5574c7abf677635f23f1ef7},overlays:{"Electrical Network":feature_group_f679827758ed94ff3c06649bd8d4e233,Buses:feature_group_sub_group_d1f39e3b2456c225166c88ed58773e57,Lines:feature_group_sub_group_f09b151cbe705aeeb111da0fb8c76799}};let layer_control_8b27f472ce4054e0832c1ca820e40585=L.control.layers(layer_control_8b27f472ce4054e0832c1ca820e40585_layers.base_layers,layer_control_8b27f472ce4054e0832c1ca820e40585_layers.overlays,{position:`bottomright`,collapsed:!1,autoZIndex:!0}).addTo(map_bfdb1813acfa5d98b9eec89b1cfdbd89);new L.Draggable(layer_control_8b27f472ce4054e0832c1ca820e40585.getContainer()).enable();var feature_group_f679827758ed94ff3c06649bd8d4e233searchControl=new L.Control.Search({layer:feature_group_f679827758ed94ff3c06649bd8d4e233,propertyName:`id`,collapsed:!1,textPlaceholder:`Search network elements...`,position:`topleft`,initial:!1,hideMarkerOnCollapse:!0});feature_group_f679827758ed94ff3c06649bd8d4e233searchControl.on(`search:locationfound`,function(e){feature_group_f679827758ed94ff3c06649bd8d4e233.setStyle(function(feature){return feature.properties.style}),e.layer._popup&&e.layer.openPopup()}),feature_group_f679827758ed94ff3c06649bd8d4e233searchControl.on(`search:collapsed`,function(e){feature_group_f679827758ed94ff3c06649bd8d4e233.setStyle(function(feature){return feature.properties.style})}),map_bfdb1813acfa5d98b9eec89b1cfdbd89.addControl(feature_group_f679827758ed94ff3c06649bd8d4e233searchControl);function customFlyToBounds(){let bounds=L.latLngBounds([]);map_bfdb1813acfa5d98b9eec89b1cfdbd89.eachLayer(function(layer){typeof layer.getBounds==`function`&&bounds.extend(layer.getBounds())}),bounds.isValid()&&map_bfdb1813acfa5d98b9eec89b1cfdbd89.fitBounds(bounds,{padding:[30,30]})}map_bfdb1813acfa5d98b9eec89b1cfdbd89.on(`overlayadd`,customFlyToBounds),customFlyToBounds(); diff --git a/doc/_static/Network/MVFeeder159.html b/doc/_static/Network/MVFeeder159.html index 0fda13e4..4ccb316e 100644 --- a/doc/_static/Network/MVFeeder159.html +++ b/doc/_static/Network/MVFeeder159.html @@ -1,644 +1,37 @@ - - - - MV Feeder 159 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

MV Feeder 159

- -
- -

MV Feeder 159

- + ${handleObject(layer.feature.properties[v]).toLocaleString()} + `).join(``))+``,div},{className:`foliumpopup`}),geo_json_62d1d8fc056cbefdd098096759a90743.addTo(feature_group_sub_group_25515117fa9675da727e86d3a82541dc),feature_group_sub_group_25515117fa9675da727e86d3a82541dc.addTo(map_1f46ee09e1ace94e0b627cad52630a48);var layer_control_bccb50f9a8808495257952066f489080_layers={base_layers:{openstreetmap:tile_layer_dbda4aef69c2d150709156617d3c95eb},overlays:{"Electrical Network":feature_group_349f306219c81467f517db7411c96cbd,Buses:feature_group_sub_group_e21e573011323253df3bc8d6cf6aeabb,Lines:feature_group_sub_group_25515117fa9675da727e86d3a82541dc}};let layer_control_bccb50f9a8808495257952066f489080=L.control.layers(layer_control_bccb50f9a8808495257952066f489080_layers.base_layers,layer_control_bccb50f9a8808495257952066f489080_layers.overlays,{position:`bottomright`,collapsed:!1,autoZIndex:!0}).addTo(map_1f46ee09e1ace94e0b627cad52630a48);new L.Draggable(layer_control_bccb50f9a8808495257952066f489080.getContainer()).enable();var feature_group_349f306219c81467f517db7411c96cbdsearchControl=new L.Control.Search({layer:feature_group_349f306219c81467f517db7411c96cbd,propertyName:`id`,collapsed:!1,textPlaceholder:`Search network elements...`,position:`topleft`,initial:!1,hideMarkerOnCollapse:!0});feature_group_349f306219c81467f517db7411c96cbdsearchControl.on(`search:locationfound`,function(e){feature_group_349f306219c81467f517db7411c96cbd.setStyle(function(feature){return feature.properties.style}),e.layer._popup&&e.layer.openPopup()}),feature_group_349f306219c81467f517db7411c96cbdsearchControl.on(`search:collapsed`,function(e){feature_group_349f306219c81467f517db7411c96cbd.setStyle(function(feature){return feature.properties.style})}),map_1f46ee09e1ace94e0b627cad52630a48.addControl(feature_group_349f306219c81467f517db7411c96cbdsearchControl);function customFlyToBounds(){let bounds=L.latLngBounds([]);map_1f46ee09e1ace94e0b627cad52630a48.eachLayer(function(layer){typeof layer.getBounds==`function`&&bounds.extend(layer.getBounds())}),bounds.isValid()&&map_1f46ee09e1ace94e0b627cad52630a48.fitBounds(bounds,{padding:[30,30]})}map_1f46ee09e1ace94e0b627cad52630a48.on(`overlayadd`,customFlyToBounds),customFlyToBounds(); diff --git a/doc/_static/Network/MVFeeder176.html b/doc/_static/Network/MVFeeder176.html index b0536165..00b147cc 100644 --- a/doc/_static/Network/MVFeeder176.html +++ b/doc/_static/Network/MVFeeder176.html @@ -1,1646 +1,37 @@ - - - - MV Feeder 176 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

MV Feeder 176

- -
- -

MV Feeder 176

- + ${handleObject(layer.feature.properties[v]).toLocaleString()} + `).join(``))+``,div},{className:`foliumpopup`}),geo_json_60ad19bb1a2b724824a2c924b9c751d5.addTo(feature_group_sub_group_617eeca1428ed88b2335832c54f2bce6),feature_group_sub_group_617eeca1428ed88b2335832c54f2bce6.addTo(map_158fd81850b0d2737d930022d07aa9e4);var layer_control_26099b9088ad8b0f9c2a77641ea4b717_layers={base_layers:{openstreetmap:tile_layer_d761bd9e2cfd0b6a4377dd7571f3a659},overlays:{"Electrical Network":feature_group_4fcb8058bed09347b89c531607965bcc,Buses:feature_group_sub_group_a395af47abcfd6107c972afe965f1c7d,Lines:feature_group_sub_group_617eeca1428ed88b2335832c54f2bce6}};let layer_control_26099b9088ad8b0f9c2a77641ea4b717=L.control.layers(layer_control_26099b9088ad8b0f9c2a77641ea4b717_layers.base_layers,layer_control_26099b9088ad8b0f9c2a77641ea4b717_layers.overlays,{position:`bottomright`,collapsed:!1,autoZIndex:!0}).addTo(map_158fd81850b0d2737d930022d07aa9e4);new L.Draggable(layer_control_26099b9088ad8b0f9c2a77641ea4b717.getContainer()).enable();var feature_group_4fcb8058bed09347b89c531607965bccsearchControl=new L.Control.Search({layer:feature_group_4fcb8058bed09347b89c531607965bcc,propertyName:`id`,collapsed:!1,textPlaceholder:`Search network elements...`,position:`topleft`,initial:!1,hideMarkerOnCollapse:!0});feature_group_4fcb8058bed09347b89c531607965bccsearchControl.on(`search:locationfound`,function(e){feature_group_4fcb8058bed09347b89c531607965bcc.setStyle(function(feature){return feature.properties.style}),e.layer._popup&&e.layer.openPopup()}),feature_group_4fcb8058bed09347b89c531607965bccsearchControl.on(`search:collapsed`,function(e){feature_group_4fcb8058bed09347b89c531607965bcc.setStyle(function(feature){return feature.properties.style})}),map_158fd81850b0d2737d930022d07aa9e4.addControl(feature_group_4fcb8058bed09347b89c531607965bccsearchControl);function customFlyToBounds(){let bounds=L.latLngBounds([]);map_158fd81850b0d2737d930022d07aa9e4.eachLayer(function(layer){typeof layer.getBounds==`function`&&bounds.extend(layer.getBounds())}),bounds.isValid()&&map_158fd81850b0d2737d930022d07aa9e4.fitBounds(bounds,{padding:[30,30]})}map_158fd81850b0d2737d930022d07aa9e4.on(`overlayadd`,customFlyToBounds),customFlyToBounds(); diff --git a/doc/_static/Network/MVFeeder210.html b/doc/_static/Network/MVFeeder210.html index a184e5d9..0e2e6873 100644 --- a/doc/_static/Network/MVFeeder210.html +++ b/doc/_static/Network/MVFeeder210.html @@ -1,5750 +1,37 @@ - - - - MV Feeder 210 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

MV Feeder 210

- -
- -

MV Feeder 210

- + ${handleObject(layer.feature.properties[v]).toLocaleString()} + `).join(``))+``,div},{className:`foliumpopup`}),geo_json_82863dbf76f11f1f893c2a7793338e46.addTo(feature_group_sub_group_5e4cceff5300a415021019e9db8678cc),feature_group_sub_group_5e4cceff5300a415021019e9db8678cc.addTo(map_5f7d8ec1ae80a7dd8c494859b58a0501);var layer_control_e43aecc590d9902c00fcbdc2f189267d_layers={base_layers:{openstreetmap:tile_layer_d478276b5c910cf9da9534f2007a9ccf},overlays:{"Electrical Network":feature_group_b00e8c073ba0d80399a260b90551c962,Buses:feature_group_sub_group_0691cc4589623fd6df12c891cc5add5f,Lines:feature_group_sub_group_5e4cceff5300a415021019e9db8678cc}};let layer_control_e43aecc590d9902c00fcbdc2f189267d=L.control.layers(layer_control_e43aecc590d9902c00fcbdc2f189267d_layers.base_layers,layer_control_e43aecc590d9902c00fcbdc2f189267d_layers.overlays,{position:`bottomright`,collapsed:!1,autoZIndex:!0}).addTo(map_5f7d8ec1ae80a7dd8c494859b58a0501);new L.Draggable(layer_control_e43aecc590d9902c00fcbdc2f189267d.getContainer()).enable();var feature_group_b00e8c073ba0d80399a260b90551c962searchControl=new L.Control.Search({layer:feature_group_b00e8c073ba0d80399a260b90551c962,propertyName:`id`,collapsed:!1,textPlaceholder:`Search network elements...`,position:`topleft`,initial:!1,hideMarkerOnCollapse:!0});feature_group_b00e8c073ba0d80399a260b90551c962searchControl.on(`search:locationfound`,function(e){feature_group_b00e8c073ba0d80399a260b90551c962.setStyle(function(feature){return feature.properties.style}),e.layer._popup&&e.layer.openPopup()}),feature_group_b00e8c073ba0d80399a260b90551c962searchControl.on(`search:collapsed`,function(e){feature_group_b00e8c073ba0d80399a260b90551c962.setStyle(function(feature){return feature.properties.style})}),map_5f7d8ec1ae80a7dd8c494859b58a0501.addControl(feature_group_b00e8c073ba0d80399a260b90551c962searchControl);function customFlyToBounds(){let bounds=L.latLngBounds([]);map_5f7d8ec1ae80a7dd8c494859b58a0501.eachLayer(function(layer){typeof layer.getBounds==`function`&&bounds.extend(layer.getBounds())}),bounds.isValid()&&map_5f7d8ec1ae80a7dd8c494859b58a0501.fitBounds(bounds,{padding:[30,30]})}map_5f7d8ec1ae80a7dd8c494859b58a0501.on(`overlayadd`,customFlyToBounds),customFlyToBounds(); diff --git a/doc/_static/Network/MVFeeder217.html b/doc/_static/Network/MVFeeder217.html index 373a643f..9872db38 100644 --- a/doc/_static/Network/MVFeeder217.html +++ b/doc/_static/Network/MVFeeder217.html @@ -1,2948 +1,37 @@ - - - - MV Feeder 217 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

MV Feeder 217

- -
- -

MV Feeder 217

- + ${handleObject(layer.feature.properties[v]).toLocaleString()} + `).join(``))+``,div},{className:`foliumpopup`}),geo_json_225bf0a2c81d0867beb10292a39ce3fa.addTo(feature_group_sub_group_37996d86e99f6392171134783afcfeb9),feature_group_sub_group_37996d86e99f6392171134783afcfeb9.addTo(map_d9c6449cdd3f3185d1c83fb39c83c3b5);var layer_control_f28c1c178ded8057376d4188b8115d6f_layers={base_layers:{openstreetmap:tile_layer_11aedf0c142b2a2267e1a7b512328b04},overlays:{"Electrical Network":feature_group_25ad973a234d024cf6fbc0a21c6d20bc,Buses:feature_group_sub_group_8de16388f83a581195363ed4b3784be4,Lines:feature_group_sub_group_37996d86e99f6392171134783afcfeb9}};let layer_control_f28c1c178ded8057376d4188b8115d6f=L.control.layers(layer_control_f28c1c178ded8057376d4188b8115d6f_layers.base_layers,layer_control_f28c1c178ded8057376d4188b8115d6f_layers.overlays,{position:`bottomright`,collapsed:!1,autoZIndex:!0}).addTo(map_d9c6449cdd3f3185d1c83fb39c83c3b5);new L.Draggable(layer_control_f28c1c178ded8057376d4188b8115d6f.getContainer()).enable();var feature_group_25ad973a234d024cf6fbc0a21c6d20bcsearchControl=new L.Control.Search({layer:feature_group_25ad973a234d024cf6fbc0a21c6d20bc,propertyName:`id`,collapsed:!1,textPlaceholder:`Search network elements...`,position:`topleft`,initial:!1,hideMarkerOnCollapse:!0});feature_group_25ad973a234d024cf6fbc0a21c6d20bcsearchControl.on(`search:locationfound`,function(e){feature_group_25ad973a234d024cf6fbc0a21c6d20bc.setStyle(function(feature){return feature.properties.style}),e.layer._popup&&e.layer.openPopup()}),feature_group_25ad973a234d024cf6fbc0a21c6d20bcsearchControl.on(`search:collapsed`,function(e){feature_group_25ad973a234d024cf6fbc0a21c6d20bc.setStyle(function(feature){return feature.properties.style})}),map_d9c6449cdd3f3185d1c83fb39c83c3b5.addControl(feature_group_25ad973a234d024cf6fbc0a21c6d20bcsearchControl);function customFlyToBounds(){let bounds=L.latLngBounds([]);map_d9c6449cdd3f3185d1c83fb39c83c3b5.eachLayer(function(layer){typeof layer.getBounds==`function`&&bounds.extend(layer.getBounds())}),bounds.isValid()&&map_d9c6449cdd3f3185d1c83fb39c83c3b5.fitBounds(bounds,{padding:[30,30]})}map_d9c6449cdd3f3185d1c83fb39c83c3b5.on(`overlayadd`,customFlyToBounds),customFlyToBounds(); diff --git a/doc/_static/Network/MVFeeder232.html b/doc/_static/Network/MVFeeder232.html index 56f0c9d7..53e7524b 100644 --- a/doc/_static/Network/MVFeeder232.html +++ b/doc/_static/Network/MVFeeder232.html @@ -1,2970 +1,37 @@ - - - - MV Feeder 232 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

MV Feeder 232

- -
- -

MV Feeder 232

- + ${handleObject(layer.feature.properties[v]).toLocaleString()} + `).join(``))+``,div},{className:`foliumpopup`}),geo_json_0c357ed819db9e16726ebc61532e5e2a.addTo(feature_group_sub_group_41b321bb4160fa13ee906357a434fa04),feature_group_sub_group_41b321bb4160fa13ee906357a434fa04.addTo(map_e2207744494ba152f74fc01a411d4111);var layer_control_9b10306372430c752025ec322b9b1cf9_layers={base_layers:{openstreetmap:tile_layer_f35e34a669263124d98e9ebbe2c4accb},overlays:{"Electrical Network":feature_group_f3d6560b6527c2dea72bd804c57a8fcf,Buses:feature_group_sub_group_5d3a0934292957bf2b8fd66c15991065,Lines:feature_group_sub_group_41b321bb4160fa13ee906357a434fa04}};let layer_control_9b10306372430c752025ec322b9b1cf9=L.control.layers(layer_control_9b10306372430c752025ec322b9b1cf9_layers.base_layers,layer_control_9b10306372430c752025ec322b9b1cf9_layers.overlays,{position:`bottomright`,collapsed:!1,autoZIndex:!0}).addTo(map_e2207744494ba152f74fc01a411d4111);new L.Draggable(layer_control_9b10306372430c752025ec322b9b1cf9.getContainer()).enable();var feature_group_f3d6560b6527c2dea72bd804c57a8fcfsearchControl=new L.Control.Search({layer:feature_group_f3d6560b6527c2dea72bd804c57a8fcf,propertyName:`id`,collapsed:!1,textPlaceholder:`Search network elements...`,position:`topleft`,initial:!1,hideMarkerOnCollapse:!0});feature_group_f3d6560b6527c2dea72bd804c57a8fcfsearchControl.on(`search:locationfound`,function(e){feature_group_f3d6560b6527c2dea72bd804c57a8fcf.setStyle(function(feature){return feature.properties.style}),e.layer._popup&&e.layer.openPopup()}),feature_group_f3d6560b6527c2dea72bd804c57a8fcfsearchControl.on(`search:collapsed`,function(e){feature_group_f3d6560b6527c2dea72bd804c57a8fcf.setStyle(function(feature){return feature.properties.style})}),map_e2207744494ba152f74fc01a411d4111.addControl(feature_group_f3d6560b6527c2dea72bd804c57a8fcfsearchControl);function customFlyToBounds(){let bounds=L.latLngBounds([]);map_e2207744494ba152f74fc01a411d4111.eachLayer(function(layer){typeof layer.getBounds==`function`&&bounds.extend(layer.getBounds())}),bounds.isValid()&&map_e2207744494ba152f74fc01a411d4111.fitBounds(bounds,{padding:[30,30]})}map_e2207744494ba152f74fc01a411d4111.on(`overlayadd`,customFlyToBounds),customFlyToBounds(); diff --git a/doc/_static/Network/MVFeeder251.html b/doc/_static/Network/MVFeeder251.html index 31e078f4..9cba8ae3 100644 --- a/doc/_static/Network/MVFeeder251.html +++ b/doc/_static/Network/MVFeeder251.html @@ -1,5745 +1,37 @@ - - - - MV Feeder 251 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

MV Feeder 251

- -
- -

MV Feeder 251

- + ${handleObject(layer.feature.properties[v]).toLocaleString()} + `).join(``))+``,div},{className:`foliumpopup`}),geo_json_66ecc10c51f40ed61d903af0d61a1bdf.addTo(feature_group_sub_group_53a7ab933f885ab98ff69c28fb6129d9),feature_group_sub_group_53a7ab933f885ab98ff69c28fb6129d9.addTo(map_bc9d67811fb3b7e61f3750e882dab7e0);var layer_control_b56226ded737ab3633b68a7b31b49ac8_layers={base_layers:{openstreetmap:tile_layer_0af235a19367add4e50c0833e5d0e7c1},overlays:{"Electrical Network":feature_group_98e15a238e608f513c9ef47d578f002a,Buses:feature_group_sub_group_5b2e79801b84cb13475d46c9cc7864a8,Lines:feature_group_sub_group_53a7ab933f885ab98ff69c28fb6129d9}};let layer_control_b56226ded737ab3633b68a7b31b49ac8=L.control.layers(layer_control_b56226ded737ab3633b68a7b31b49ac8_layers.base_layers,layer_control_b56226ded737ab3633b68a7b31b49ac8_layers.overlays,{position:`bottomright`,collapsed:!1,autoZIndex:!0}).addTo(map_bc9d67811fb3b7e61f3750e882dab7e0);new L.Draggable(layer_control_b56226ded737ab3633b68a7b31b49ac8.getContainer()).enable();var feature_group_98e15a238e608f513c9ef47d578f002asearchControl=new L.Control.Search({layer:feature_group_98e15a238e608f513c9ef47d578f002a,propertyName:`id`,collapsed:!1,textPlaceholder:`Search network elements...`,position:`topleft`,initial:!1,hideMarkerOnCollapse:!0});feature_group_98e15a238e608f513c9ef47d578f002asearchControl.on(`search:locationfound`,function(e){feature_group_98e15a238e608f513c9ef47d578f002a.setStyle(function(feature){return feature.properties.style}),e.layer._popup&&e.layer.openPopup()}),feature_group_98e15a238e608f513c9ef47d578f002asearchControl.on(`search:collapsed`,function(e){feature_group_98e15a238e608f513c9ef47d578f002a.setStyle(function(feature){return feature.properties.style})}),map_bc9d67811fb3b7e61f3750e882dab7e0.addControl(feature_group_98e15a238e608f513c9ef47d578f002asearchControl);function customFlyToBounds(){let bounds=L.latLngBounds([]);map_bc9d67811fb3b7e61f3750e882dab7e0.eachLayer(function(layer){typeof layer.getBounds==`function`&&bounds.extend(layer.getBounds())}),bounds.isValid()&&map_bc9d67811fb3b7e61f3750e882dab7e0.fitBounds(bounds,{padding:[30,30]})}map_bc9d67811fb3b7e61f3750e882dab7e0.on(`overlayadd`,customFlyToBounds),customFlyToBounds(); diff --git a/doc/_static/Network/MVFeeder290.html b/doc/_static/Network/MVFeeder290.html index 062209f0..b2f3c352 100644 --- a/doc/_static/Network/MVFeeder290.html +++ b/doc/_static/Network/MVFeeder290.html @@ -1,864 +1,37 @@ - - - - MV Feeder 290 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

MV Feeder 290

- -
- -

MV Feeder 290

- + ${handleObject(layer.feature.properties[v]).toLocaleString()} + `).join(``))+``,div},{className:`foliumpopup`}),geo_json_edc500fba71b601f58ef574e0852180a.addTo(feature_group_sub_group_664f30a64c9a19005ffbfd49fa7c25b5),feature_group_sub_group_664f30a64c9a19005ffbfd49fa7c25b5.addTo(map_f206633506300028583b26b1107b1064);var layer_control_ac7f3d8691a8693764ff3ae164e8db85_layers={base_layers:{openstreetmap:tile_layer_b848f1d9fac98671434567bb95dbac88},overlays:{"Electrical Network":feature_group_f64dfa8e37b0e2d812e7fdfd35f3eed2,Buses:feature_group_sub_group_640fc578ca5fbd5ad95af639f5ee512e,Lines:feature_group_sub_group_664f30a64c9a19005ffbfd49fa7c25b5}};let layer_control_ac7f3d8691a8693764ff3ae164e8db85=L.control.layers(layer_control_ac7f3d8691a8693764ff3ae164e8db85_layers.base_layers,layer_control_ac7f3d8691a8693764ff3ae164e8db85_layers.overlays,{position:`bottomright`,collapsed:!1,autoZIndex:!0}).addTo(map_f206633506300028583b26b1107b1064);new L.Draggable(layer_control_ac7f3d8691a8693764ff3ae164e8db85.getContainer()).enable();var feature_group_f64dfa8e37b0e2d812e7fdfd35f3eed2searchControl=new L.Control.Search({layer:feature_group_f64dfa8e37b0e2d812e7fdfd35f3eed2,propertyName:`id`,collapsed:!1,textPlaceholder:`Search network elements...`,position:`topleft`,initial:!1,hideMarkerOnCollapse:!0});feature_group_f64dfa8e37b0e2d812e7fdfd35f3eed2searchControl.on(`search:locationfound`,function(e){feature_group_f64dfa8e37b0e2d812e7fdfd35f3eed2.setStyle(function(feature){return feature.properties.style}),e.layer._popup&&e.layer.openPopup()}),feature_group_f64dfa8e37b0e2d812e7fdfd35f3eed2searchControl.on(`search:collapsed`,function(e){feature_group_f64dfa8e37b0e2d812e7fdfd35f3eed2.setStyle(function(feature){return feature.properties.style})}),map_f206633506300028583b26b1107b1064.addControl(feature_group_f64dfa8e37b0e2d812e7fdfd35f3eed2searchControl);function customFlyToBounds(){let bounds=L.latLngBounds([]);map_f206633506300028583b26b1107b1064.eachLayer(function(layer){typeof layer.getBounds==`function`&&bounds.extend(layer.getBounds())}),bounds.isValid()&&map_f206633506300028583b26b1107b1064.fitBounds(bounds,{padding:[30,30]})}map_f206633506300028583b26b1107b1064.on(`overlayadd`,customFlyToBounds),customFlyToBounds(); diff --git a/doc/_static/Network/MVFeeder312.html b/doc/_static/Network/MVFeeder312.html index 7c485063..c4e4ee59 100644 --- a/doc/_static/Network/MVFeeder312.html +++ b/doc/_static/Network/MVFeeder312.html @@ -1,934 +1,37 @@ - - - - MV Feeder 312 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

MV Feeder 312

- -
- -

MV Feeder 312

- + ${handleObject(layer.feature.properties[v]).toLocaleString()} + `).join(``))+``,div},{className:`foliumpopup`}),geo_json_dd1d285f1871813ef7e964522cf8538a.addTo(feature_group_sub_group_0d0981a0afab470dc27f22ec1140b835),feature_group_sub_group_0d0981a0afab470dc27f22ec1140b835.addTo(map_be864bc81ca02425d49d5499e1281768);var layer_control_715e8a0604e5b7a503dfc0c80c0c5ddc_layers={base_layers:{openstreetmap:tile_layer_09283431e70ff5213c0a7fbdcfa7a9b6},overlays:{"Electrical Network":feature_group_b5c897990694c7a0a67514d0125547fe,Buses:feature_group_sub_group_41a5a87710ed46dcd8c6a4524d9f621d,Lines:feature_group_sub_group_0d0981a0afab470dc27f22ec1140b835}};let layer_control_715e8a0604e5b7a503dfc0c80c0c5ddc=L.control.layers(layer_control_715e8a0604e5b7a503dfc0c80c0c5ddc_layers.base_layers,layer_control_715e8a0604e5b7a503dfc0c80c0c5ddc_layers.overlays,{position:`bottomright`,collapsed:!1,autoZIndex:!0}).addTo(map_be864bc81ca02425d49d5499e1281768);new L.Draggable(layer_control_715e8a0604e5b7a503dfc0c80c0c5ddc.getContainer()).enable();var feature_group_b5c897990694c7a0a67514d0125547fesearchControl=new L.Control.Search({layer:feature_group_b5c897990694c7a0a67514d0125547fe,propertyName:`id`,collapsed:!1,textPlaceholder:`Search network elements...`,position:`topleft`,initial:!1,hideMarkerOnCollapse:!0});feature_group_b5c897990694c7a0a67514d0125547fesearchControl.on(`search:locationfound`,function(e){feature_group_b5c897990694c7a0a67514d0125547fe.setStyle(function(feature){return feature.properties.style}),e.layer._popup&&e.layer.openPopup()}),feature_group_b5c897990694c7a0a67514d0125547fesearchControl.on(`search:collapsed`,function(e){feature_group_b5c897990694c7a0a67514d0125547fe.setStyle(function(feature){return feature.properties.style})}),map_be864bc81ca02425d49d5499e1281768.addControl(feature_group_b5c897990694c7a0a67514d0125547fesearchControl);function customFlyToBounds(){let bounds=L.latLngBounds([]);map_be864bc81ca02425d49d5499e1281768.eachLayer(function(layer){typeof layer.getBounds==`function`&&bounds.extend(layer.getBounds())}),bounds.isValid()&&map_be864bc81ca02425d49d5499e1281768.fitBounds(bounds,{padding:[30,30]})}map_be864bc81ca02425d49d5499e1281768.on(`overlayadd`,customFlyToBounds),customFlyToBounds(); diff --git a/doc/_static/Network/MVFeeder320.html b/doc/_static/Network/MVFeeder320.html index 49d85807..4dddaf77 100644 --- a/doc/_static/Network/MVFeeder320.html +++ b/doc/_static/Network/MVFeeder320.html @@ -1,1186 +1,37 @@ - - - - MV Feeder 320 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

MV Feeder 320

- -
- -

MV Feeder 320

- + ${handleObject(layer.feature.properties[v]).toLocaleString()} + `).join(``))+``,div},{className:`foliumpopup`}),geo_json_bfd076d0d64bc418ee45018bb074ad52.addTo(feature_group_sub_group_a82011eefc75808d50225e2ef2ea8e92),feature_group_sub_group_a82011eefc75808d50225e2ef2ea8e92.addTo(map_d5e92d8dfed8991155caf2efa82660c9);var layer_control_a1d7a40fe7e00d7bec0542ad17045dad_layers={base_layers:{openstreetmap:tile_layer_efa4a4f4c87eebbc9d29fdd8b86cba99},overlays:{"Electrical Network":feature_group_24037402fc66d350ab0f70c2146de953,Buses:feature_group_sub_group_bd643abd952b7deb31fb4ed829bb8274,Lines:feature_group_sub_group_a82011eefc75808d50225e2ef2ea8e92}};let layer_control_a1d7a40fe7e00d7bec0542ad17045dad=L.control.layers(layer_control_a1d7a40fe7e00d7bec0542ad17045dad_layers.base_layers,layer_control_a1d7a40fe7e00d7bec0542ad17045dad_layers.overlays,{position:`bottomright`,collapsed:!1,autoZIndex:!0}).addTo(map_d5e92d8dfed8991155caf2efa82660c9);new L.Draggable(layer_control_a1d7a40fe7e00d7bec0542ad17045dad.getContainer()).enable();var feature_group_24037402fc66d350ab0f70c2146de953searchControl=new L.Control.Search({layer:feature_group_24037402fc66d350ab0f70c2146de953,propertyName:`id`,collapsed:!1,textPlaceholder:`Search network elements...`,position:`topleft`,initial:!1,hideMarkerOnCollapse:!0});feature_group_24037402fc66d350ab0f70c2146de953searchControl.on(`search:locationfound`,function(e){feature_group_24037402fc66d350ab0f70c2146de953.setStyle(function(feature){return feature.properties.style}),e.layer._popup&&e.layer.openPopup()}),feature_group_24037402fc66d350ab0f70c2146de953searchControl.on(`search:collapsed`,function(e){feature_group_24037402fc66d350ab0f70c2146de953.setStyle(function(feature){return feature.properties.style})}),map_d5e92d8dfed8991155caf2efa82660c9.addControl(feature_group_24037402fc66d350ab0f70c2146de953searchControl);function customFlyToBounds(){let bounds=L.latLngBounds([]);map_d5e92d8dfed8991155caf2efa82660c9.eachLayer(function(layer){typeof layer.getBounds==`function`&&bounds.extend(layer.getBounds())}),bounds.isValid()&&map_d5e92d8dfed8991155caf2efa82660c9.fitBounds(bounds,{padding:[30,30]})}map_d5e92d8dfed8991155caf2efa82660c9.on(`overlayadd`,customFlyToBounds),customFlyToBounds(); diff --git a/doc/_static/Network/MVFeeder339.html b/doc/_static/Network/MVFeeder339.html index ddeb076d..257ad06c 100644 --- a/doc/_static/Network/MVFeeder339.html +++ b/doc/_static/Network/MVFeeder339.html @@ -1,1780 +1,37 @@ - - - - MV Feeder 339 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

MV Feeder 339

- -
- -

MV Feeder 339

- + ${handleObject(layer.feature.properties[v]).toLocaleString()} + `).join(``))+``,div},{className:`foliumpopup`}),geo_json_ca4342d2cd796e2a71287ed14f6bf199.addTo(feature_group_sub_group_6343bacefd3f583c1ea4494562277011),feature_group_sub_group_6343bacefd3f583c1ea4494562277011.addTo(map_0ac47891e6d29d925bd9249688e3a504);var layer_control_136f2361649700758435b459c7bcc8e2_layers={base_layers:{openstreetmap:tile_layer_848ad0f11e03ad3faaa26372c5589abd},overlays:{"Electrical Network":feature_group_91d8fc69989776d25aaebf99d868af15,Buses:feature_group_sub_group_e36bef8eadda244950ee143094ab7b15,Lines:feature_group_sub_group_6343bacefd3f583c1ea4494562277011}};let layer_control_136f2361649700758435b459c7bcc8e2=L.control.layers(layer_control_136f2361649700758435b459c7bcc8e2_layers.base_layers,layer_control_136f2361649700758435b459c7bcc8e2_layers.overlays,{position:`bottomright`,collapsed:!1,autoZIndex:!0}).addTo(map_0ac47891e6d29d925bd9249688e3a504);new L.Draggable(layer_control_136f2361649700758435b459c7bcc8e2.getContainer()).enable();var feature_group_91d8fc69989776d25aaebf99d868af15searchControl=new L.Control.Search({layer:feature_group_91d8fc69989776d25aaebf99d868af15,propertyName:`id`,collapsed:!1,textPlaceholder:`Search network elements...`,position:`topleft`,initial:!1,hideMarkerOnCollapse:!0});feature_group_91d8fc69989776d25aaebf99d868af15searchControl.on(`search:locationfound`,function(e){feature_group_91d8fc69989776d25aaebf99d868af15.setStyle(function(feature){return feature.properties.style}),e.layer._popup&&e.layer.openPopup()}),feature_group_91d8fc69989776d25aaebf99d868af15searchControl.on(`search:collapsed`,function(e){feature_group_91d8fc69989776d25aaebf99d868af15.setStyle(function(feature){return feature.properties.style})}),map_0ac47891e6d29d925bd9249688e3a504.addControl(feature_group_91d8fc69989776d25aaebf99d868af15searchControl);function customFlyToBounds(){let bounds=L.latLngBounds([]);map_0ac47891e6d29d925bd9249688e3a504.eachLayer(function(layer){typeof layer.getBounds==`function`&&bounds.extend(layer.getBounds())}),bounds.isValid()&&map_0ac47891e6d29d925bd9249688e3a504.fitBounds(bounds,{padding:[30,30]})}map_0ac47891e6d29d925bd9249688e3a504.on(`overlayadd`,customFlyToBounds),customFlyToBounds(); diff --git a/doc/_static/Plotting/MVFeeder210.html b/doc/_static/Plotting/MVFeeder210.html index bfdaf57e..a0ff2dec 100644 --- a/doc/_static/Plotting/MVFeeder210.html +++ b/doc/_static/Plotting/MVFeeder210.html @@ -1,5728 +1,37 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- + ${handleObject(layer.feature.properties[v]).toLocaleString()} + `).join(``))+``,div},{className:`foliumpopup`}),geo_json_292f4ebca68aedd0d500904b188ec64d.addTo(feature_group_sub_group_5535b7b31c7d39f80f5b1322f1e2d669),feature_group_sub_group_5535b7b31c7d39f80f5b1322f1e2d669.addTo(map_5364bbe7961b88aed023066be222ce3c);var layer_control_f4f47867aeb92c3a581a64681d807be9_layers={base_layers:{openstreetmap:tile_layer_ebcec64e0e7b89934ee610288b4f4d78},overlays:{"Electrical Network":feature_group_ca2022bcf33ca4b872d8dc85d8cc809e,Buses:feature_group_sub_group_4330983a0e66b58717a8444539bb4fb4,Lines:feature_group_sub_group_5535b7b31c7d39f80f5b1322f1e2d669}};let layer_control_f4f47867aeb92c3a581a64681d807be9=L.control.layers(layer_control_f4f47867aeb92c3a581a64681d807be9_layers.base_layers,layer_control_f4f47867aeb92c3a581a64681d807be9_layers.overlays,{position:`bottomright`,collapsed:!1,autoZIndex:!0}).addTo(map_5364bbe7961b88aed023066be222ce3c);new L.Draggable(layer_control_f4f47867aeb92c3a581a64681d807be9.getContainer()).enable();var feature_group_ca2022bcf33ca4b872d8dc85d8cc809esearchControl=new L.Control.Search({layer:feature_group_ca2022bcf33ca4b872d8dc85d8cc809e,propertyName:`id`,collapsed:!1,textPlaceholder:`Search network elements...`,position:`topleft`,initial:!1,hideMarkerOnCollapse:!0});feature_group_ca2022bcf33ca4b872d8dc85d8cc809esearchControl.on(`search:locationfound`,function(e){feature_group_ca2022bcf33ca4b872d8dc85d8cc809e.setStyle(function(feature){return feature.properties.style}),e.layer._popup&&e.layer.openPopup()}),feature_group_ca2022bcf33ca4b872d8dc85d8cc809esearchControl.on(`search:collapsed`,function(e){feature_group_ca2022bcf33ca4b872d8dc85d8cc809e.setStyle(function(feature){return feature.properties.style})}),map_5364bbe7961b88aed023066be222ce3c.addControl(feature_group_ca2022bcf33ca4b872d8dc85d8cc809esearchControl);function customFlyToBounds(){let bounds=L.latLngBounds([]);map_5364bbe7961b88aed023066be222ce3c.eachLayer(function(layer){typeof layer.getBounds==`function`&&bounds.extend(layer.getBounds())}),bounds.isValid()&&map_5364bbe7961b88aed023066be222ce3c.fitBounds(bounds,{padding:[30,30]})}map_5364bbe7961b88aed023066be222ce3c.on(`overlayadd`,customFlyToBounds),customFlyToBounds(); diff --git a/doc/_static/Plotting/MVFeeder210_Graph_No_Geometries.png b/doc/_static/Plotting/MVFeeder210_Graph_No_Geometries.png deleted file mode 100644 index ab73fbad..00000000 --- a/doc/_static/Plotting/MVFeeder210_Graph_No_Geometries.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:5422b3b11c425fdfcc7ca5873cd8ba0d412ade535d05399836ff9c5b366958f0 -size 39593 diff --git a/doc/_static/Plotting/MVFeeder210_Graph_No_Geometries.webp b/doc/_static/Plotting/MVFeeder210_Graph_No_Geometries.webp new file mode 100644 index 00000000..4c2c5211 --- /dev/null +++ b/doc/_static/Plotting/MVFeeder210_Graph_No_Geometries.webp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:fa78584583958bf161ca50bb61b77b08bd8b866ea4444d5cb4b6afeeda2dd172 +size 14208 diff --git a/doc/_static/Plotting/MVFeeder210_Results.html b/doc/_static/Plotting/MVFeeder210_Results.html new file mode 100644 index 00000000..7566cfdb --- /dev/null +++ b/doc/_static/Plotting/MVFeeder210_Results.html @@ -0,0 +1,77 @@ +
diff --git a/doc/_static/Plotting/Plot_Voltage_Phasors.png b/doc/_static/Plotting/Plot_Voltage_Phasors.png deleted file mode 100644 index 63122884..00000000 --- a/doc/_static/Plotting/Plot_Voltage_Phasors.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:43807b8f3b694aaecff566ff7c21ee3345d68ab26503d39de45ac6a2556bc68a -size 31392 diff --git a/doc/_static/Plotting/Plot_Voltage_Phasors.webp b/doc/_static/Plotting/Plot_Voltage_Phasors.webp new file mode 100644 index 00000000..e7cb946d --- /dev/null +++ b/doc/_static/Plotting/Plot_Voltage_Phasors.webp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:081b920f858bcf3ca0f542eb0dcebac6dcdbc5d50b93fff9154cb8aae54ca756 +size 12104 diff --git a/doc/_static/Plotting/Result_States.webp b/doc/_static/Plotting/Result_States.webp new file mode 100644 index 00000000..61267c18 --- /dev/null +++ b/doc/_static/Plotting/Result_States.webp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:9fff7f2037608aa054b0f43077d1c385da2cdd08aef14274904510d89e15b9b0 +size 3094 diff --git a/doc/_static/Plotting/Voltage_Profile_LVFeeder36360_Min_Max.webp b/doc/_static/Plotting/Voltage_Profile_LVFeeder36360_Min_Max.webp new file mode 100644 index 00000000..5a38aca9 --- /dev/null +++ b/doc/_static/Plotting/Voltage_Profile_LVFeeder36360_Min_Max.webp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:2c50528c70c9244f477cb02afa3fa86356ea62768783b3c82b42bcf6fb94c14a +size 10344 diff --git a/doc/_static/Plotting/Voltage_Profile_LVFeeder36360_Plotly.html b/doc/_static/Plotting/Voltage_Profile_LVFeeder36360_Plotly.html new file mode 100644 index 00000000..ef3aee8b --- /dev/null +++ b/doc/_static/Plotting/Voltage_Profile_LVFeeder36360_Plotly.html @@ -0,0 +1 @@ +
diff --git a/doc/_static/PotentialRef.svg b/doc/_static/PotentialRef.svg index 7a27bd07..6493a2b8 100644 --- a/doc/_static/PotentialRef.svg +++ b/doc/_static/PotentialRef.svg @@ -1 +1 @@ - + diff --git a/doc/_static/PotentialRef_With_Ground.svg b/doc/_static/PotentialRef_With_Ground.svg index 13ad6428..6aa71836 100644 --- a/doc/_static/PotentialRef_With_Ground.svg +++ b/doc/_static/PotentialRef_With_Ground.svg @@ -1 +1 @@ - + diff --git a/doc/_static/Switch.svg b/doc/_static/Switch.svg index 98a09414..5aefae14 100644 --- a/doc/_static/Switch.svg +++ b/doc/_static/Switch.svg @@ -1 +1 @@ - + diff --git a/doc/_static/Transformer/Additional_Connections.svg b/doc/_static/Transformer/Additional_Connections.svg index 49743d08..da740648 100644 --- a/doc/_static/Transformer/Additional_Connections.svg +++ b/doc/_static/Transformer/Additional_Connections.svg @@ -1 +1 @@ - + diff --git a/doc/_static/Transformer/American_Center_Tapped_Transformer.svg b/doc/_static/Transformer/American_Center_Tapped_Transformer.svg index c3916c22..7e39e7c8 100644 --- a/doc/_static/Transformer/American_Center_Tapped_Transformer.svg +++ b/doc/_static/Transformer/American_Center_Tapped_Transformer.svg @@ -1 +1 @@ - + diff --git a/doc/_static/Transformer/American_Dyn11.svg b/doc/_static/Transformer/American_Dyn11.svg index f9f9aa16..93007f78 100644 --- a/doc/_static/Transformer/American_Dyn11.svg +++ b/doc/_static/Transformer/American_Dyn11.svg @@ -1 +1 @@ - + diff --git a/doc/_static/Transformer/American_Single_Phase_Transformer.svg b/doc/_static/Transformer/American_Single_Phase_Transformer.svg index 5c33c3e1..0661cbd5 100644 --- a/doc/_static/Transformer/American_Single_Phase_Transformer.svg +++ b/doc/_static/Transformer/American_Single_Phase_Transformer.svg @@ -1 +1 @@ - + diff --git a/doc/_static/Transformer/American_Three_Phase_Transformer.svg b/doc/_static/Transformer/American_Three_Phase_Transformer.svg index fa69be0a..1d260606 100644 --- a/doc/_static/Transformer/American_Three_Phase_Transformer.svg +++ b/doc/_static/Transformer/American_Three_Phase_Transformer.svg @@ -1 +1 @@ - + diff --git a/doc/_static/Transformer/Common_Connections.svg b/doc/_static/Transformer/Common_Connections.svg index d956c92d..47f3023b 100644 --- a/doc/_static/Transformer/Common_Connections.svg +++ b/doc/_static/Transformer/Common_Connections.svg @@ -1 +1 @@ - + diff --git a/doc/_static/Transformer/European_Center_Tapped_Transformer.svg b/doc/_static/Transformer/European_Center_Tapped_Transformer.svg index 75cd937b..f363ac67 100644 --- a/doc/_static/Transformer/European_Center_Tapped_Transformer.svg +++ b/doc/_static/Transformer/European_Center_Tapped_Transformer.svg @@ -1 +1 @@ - + diff --git a/doc/_static/Transformer/European_Dyn11.svg b/doc/_static/Transformer/European_Dyn11.svg index 9e5a8626..b900177f 100644 --- a/doc/_static/Transformer/European_Dyn11.svg +++ b/doc/_static/Transformer/European_Dyn11.svg @@ -1 +1 @@ - + diff --git a/doc/_static/Transformer/European_Single_Phase_Transformer.svg b/doc/_static/Transformer/European_Single_Phase_Transformer.svg index 0b8a075e..c7820ae6 100644 --- a/doc/_static/Transformer/European_Single_Phase_Transformer.svg +++ b/doc/_static/Transformer/European_Single_Phase_Transformer.svg @@ -1 +1 @@ - + diff --git a/doc/_static/Transformer/European_Three_Phase_Transformer.svg b/doc/_static/Transformer/European_Three_Phase_Transformer.svg index 9fe7ca59..4135a90a 100644 --- a/doc/_static/Transformer/European_Three_Phase_Transformer.svg +++ b/doc/_static/Transformer/European_Three_Phase_Transformer.svg @@ -1 +1 @@ - + diff --git a/doc/_static/Transformer/References/2023_03_30_Fiche_Technique_France_Transfo.pdf b/doc/_static/Transformer/References/2023_03_30_Fiche_Technique_France_Transfo.pdf index c2e5e9ae..fb7d86ad 100644 Binary files a/doc/_static/Transformer/References/2023_03_30_Fiche_Technique_France_Transfo.pdf and b/doc/_static/Transformer/References/2023_03_30_Fiche_Technique_France_Transfo.pdf differ diff --git a/doc/_static/Transformer/References/2023_03_31_Fiche_Technique_Schneider_Electric.pdf b/doc/_static/Transformer/References/2023_03_31_Fiche_Technique_Schneider_Electric.pdf index cddf9926..02ba16b5 100644 Binary files a/doc/_static/Transformer/References/2023_03_31_Fiche_Technique_Schneider_Electric.pdf and b/doc/_static/Transformer/References/2023_03_31_Fiche_Technique_Schneider_Electric.pdf differ diff --git a/doc/_static/Transformer/References/2024_03_18_Minera-EcoDesign2021-20kV_ZZ6921.pdf b/doc/_static/Transformer/References/2024_03_18_Minera-EcoDesign2021-20kV_ZZ6921.pdf index 71e86436..ebc878c5 100644 Binary files a/doc/_static/Transformer/References/2024_03_18_Minera-EcoDesign2021-20kV_ZZ6921.pdf and b/doc/_static/Transformer/References/2024_03_18_Minera-EcoDesign2021-20kV_ZZ6921.pdf differ diff --git a/doc/_static/Transformer/References/2024_03_18_Trihal-EcoDesign2021-20kV_ZZ6925.pdf b/doc/_static/Transformer/References/2024_03_18_Trihal-EcoDesign2021-20kV_ZZ6925.pdf index b758107e..0b571687 100644 Binary files a/doc/_static/Transformer/References/2024_03_18_Trihal-EcoDesign2021-20kV_ZZ6925.pdf and b/doc/_static/Transformer/References/2024_03_18_Trihal-EcoDesign2021-20kV_ZZ6925.pdf differ diff --git a/doc/_static/Transformer/References/2024_03_18_Vegeta-EcoDesign2021-20kV_ZZ6924.pdf b/doc/_static/Transformer/References/2024_03_18_Vegeta-EcoDesign2021-20kV_ZZ6924.pdf index 1b9f68ee..e2d38c5d 100644 Binary files a/doc/_static/Transformer/References/2024_03_18_Vegeta-EcoDesign2021-20kV_ZZ6924.pdf and b/doc/_static/Transformer/References/2024_03_18_Vegeta-EcoDesign2021-20kV_ZZ6924.pdf differ diff --git a/doc/_static/Transformer/References/2024_11_25_FRAED215018FR-Distribution-HTA-2023.pdf b/doc/_static/Transformer/References/2024_11_25_FRAED215018FR-Distribution-HTA-2023.pdf index fe7adc72..937d19b8 100644 Binary files a/doc/_static/Transformer/References/2024_11_25_FRAED215018FR-Distribution-HTA-2023.pdf and b/doc/_static/Transformer/References/2024_11_25_FRAED215018FR-Distribution-HTA-2023.pdf differ diff --git a/doc/_static/Transformer/References/2024_11_25_Schneider Electric_BC-Imprego_84408.pdf b/doc/_static/Transformer/References/2024_11_25_Schneider Electric_BC-Imprego_84408.pdf index 43088d12..122c5a4f 100644 Binary files a/doc/_static/Transformer/References/2024_11_25_Schneider Electric_BC-Imprego_84408.pdf and b/doc/_static/Transformer/References/2024_11_25_Schneider Electric_BC-Imprego_84408.pdf differ diff --git a/doc/_static/Transformer/References/2024_11_25_Schneider Electric_BC-Imprego_84410.pdf b/doc/_static/Transformer/References/2024_11_25_Schneider Electric_BC-Imprego_84410.pdf index 89c66f51..5764f570 100644 Binary files a/doc/_static/Transformer/References/2024_11_25_Schneider Electric_BC-Imprego_84410.pdf and b/doc/_static/Transformer/References/2024_11_25_Schneider Electric_BC-Imprego_84410.pdf differ diff --git a/doc/_static/Transformer/References/2024_11_25_chapitre_transformateurs_prives_0-cahors.pdf b/doc/_static/Transformer/References/2024_11_25_chapitre_transformateurs_prives_0-cahors.pdf index 2a469394..5a0b48d2 100644 Binary files a/doc/_static/Transformer/References/2024_11_25_chapitre_transformateurs_prives_0-cahors.pdf and b/doc/_static/Transformer/References/2024_11_25_chapitre_transformateurs_prives_0-cahors.pdf differ diff --git a/doc/_static/Transformer/References/2024_11_25_transformateur-triphase-schneider-imprego-84243-bt-bt.jpg b/doc/_static/Transformer/References/2024_11_25_transformateur-triphase-schneider-imprego-84243-bt-bt.jpg deleted file mode 100644 index cc829f77..00000000 Binary files a/doc/_static/Transformer/References/2024_11_25_transformateur-triphase-schneider-imprego-84243-bt-bt.jpg and /dev/null differ diff --git a/doc/_static/Transformer/References/2024_11_25_transformateur-triphase-schneider-imprego-84243-bt-bt.webp b/doc/_static/Transformer/References/2024_11_25_transformateur-triphase-schneider-imprego-84243-bt-bt.webp new file mode 100644 index 00000000..ed4c3cd8 --- /dev/null +++ b/doc/_static/Transformer/References/2024_11_25_transformateur-triphase-schneider-imprego-84243-bt-bt.webp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:3b8dc66d735158039a82e091d117cd77353457b553807d37f5be925d29277d01 +size 56052 diff --git a/doc/_static/Transformer/References/2025_03_14_SCOTECH_S11-30MVA-132-11KV.pdf b/doc/_static/Transformer/References/2025_03_14_SCOTECH_S11-30MVA-132-11KV.pdf index 2bb16b72..d00fc864 100644 Binary files a/doc/_static/Transformer/References/2025_03_14_SCOTECH_S11-30MVA-132-11KV.pdf and b/doc/_static/Transformer/References/2025_03_14_SCOTECH_S11-30MVA-132-11KV.pdf differ diff --git a/doc/_static/Transformer/References/2025_03_14_SCOTECH_SC-S-100MVA-220-35KV.pdf b/doc/_static/Transformer/References/2025_03_14_SCOTECH_SC-S-100MVA-220-35KV.pdf index e92b3f8e..45621eec 100644 Binary files a/doc/_static/Transformer/References/2025_03_14_SCOTECH_SC-S-100MVA-220-35KV.pdf and b/doc/_static/Transformer/References/2025_03_14_SCOTECH_SC-S-100MVA-220-35KV.pdf differ diff --git a/doc/_static/Transformer/References/2025_03_14_SCOTECH_SFZ11-25MVA-33-11KV.pdf b/doc/_static/Transformer/References/2025_03_14_SCOTECH_SFZ11-25MVA-33-11KV.pdf index 411e8924..93ffceb4 100644 Binary files a/doc/_static/Transformer/References/2025_03_14_SCOTECH_SFZ11-25MVA-33-11KV.pdf and b/doc/_static/Transformer/References/2025_03_14_SCOTECH_SFZ11-25MVA-33-11KV.pdf differ diff --git a/doc/_static/Transformer/References/2025_03_14_SCOTECH_SZ11-76MVA-110-35 kV.pdf b/doc/_static/Transformer/References/2025_03_14_SCOTECH_SZ11-76MVA-110-35 kV.pdf index 2cad52ad..1d2fe3d8 100644 Binary files a/doc/_static/Transformer/References/2025_03_14_SCOTECH_SZ11-76MVA-110-35 kV.pdf and b/doc/_static/Transformer/References/2025_03_14_SCOTECH_SZ11-76MVA-110-35 kV.pdf differ diff --git a/doc/_static/Transformer/Windings.svg b/doc/_static/Transformer/Windings.svg index 3bc5e315..c1f05e71 100644 --- a/doc/_static/Transformer/Windings.svg +++ b/doc/_static/Transformer/Windings.svg @@ -1 +1 @@ - + diff --git a/doc/_static/Transformer/Windings_Dd0.svg b/doc/_static/Transformer/Windings_Dd0.svg index c3ac2f63..0458479c 100644 --- a/doc/_static/Transformer/Windings_Dd0.svg +++ b/doc/_static/Transformer/Windings_Dd0.svg @@ -1 +1 @@ - + diff --git a/doc/_static/Transformer/Windings_Dd6.svg b/doc/_static/Transformer/Windings_Dd6.svg index 1d2220ef..7fdd6113 100644 --- a/doc/_static/Transformer/Windings_Dd6.svg +++ b/doc/_static/Transformer/Windings_Dd6.svg @@ -1 +1 @@ - + diff --git a/doc/_static/Transformer/Windings_Dy11.svg b/doc/_static/Transformer/Windings_Dy11.svg index 5603e241..2f796910 100644 --- a/doc/_static/Transformer/Windings_Dy11.svg +++ b/doc/_static/Transformer/Windings_Dy11.svg @@ -1 +1 @@ - + diff --git a/doc/_static/Transformer/Windings_Dy5.svg b/doc/_static/Transformer/Windings_Dy5.svg index c6e47421..c5f17795 100644 --- a/doc/_static/Transformer/Windings_Dy5.svg +++ b/doc/_static/Transformer/Windings_Dy5.svg @@ -1 +1 @@ - + diff --git a/doc/_static/Transformer/Windings_Dz0.svg b/doc/_static/Transformer/Windings_Dz0.svg index f8663b15..3349ec2a 100644 --- a/doc/_static/Transformer/Windings_Dz0.svg +++ b/doc/_static/Transformer/Windings_Dz0.svg @@ -1 +1 @@ - + diff --git a/doc/_static/Transformer/Windings_Dz6.svg b/doc/_static/Transformer/Windings_Dz6.svg index 0b009eda..0b83a053 100644 --- a/doc/_static/Transformer/Windings_Dz6.svg +++ b/doc/_static/Transformer/Windings_Dz6.svg @@ -1 +1 @@ - + diff --git a/doc/_static/Transformer/Windings_Yd11.svg b/doc/_static/Transformer/Windings_Yd11.svg index 7d2ede88..1e6f8413 100644 --- a/doc/_static/Transformer/Windings_Yd11.svg +++ b/doc/_static/Transformer/Windings_Yd11.svg @@ -1 +1 @@ - + diff --git a/doc/_static/Transformer/Windings_Yd5.svg b/doc/_static/Transformer/Windings_Yd5.svg index ae0c9344..c8c33d94 100644 --- a/doc/_static/Transformer/Windings_Yd5.svg +++ b/doc/_static/Transformer/Windings_Yd5.svg @@ -1 +1 @@ - + diff --git a/doc/_static/Transformer/Windings_Yy0.svg b/doc/_static/Transformer/Windings_Yy0.svg index 2aa1bce8..133ca1e4 100644 --- a/doc/_static/Transformer/Windings_Yy0.svg +++ b/doc/_static/Transformer/Windings_Yy0.svg @@ -1 +1 @@ - + diff --git a/doc/_static/Transformer/Windings_Yy6.svg b/doc/_static/Transformer/Windings_Yy6.svg index 6e5affe7..e8e06f4e 100644 --- a/doc/_static/Transformer/Windings_Yy6.svg +++ b/doc/_static/Transformer/Windings_Yy6.svg @@ -1 +1 @@ - + diff --git a/doc/_static/Transformer/Windings_Yz11.svg b/doc/_static/Transformer/Windings_Yz11.svg index 98e361b2..b7e78951 100644 --- a/doc/_static/Transformer/Windings_Yz11.svg +++ b/doc/_static/Transformer/Windings_Yz11.svg @@ -1 +1 @@ - + diff --git a/doc/_static/Transformer/Windings_Yz5.svg b/doc/_static/Transformer/Windings_Yz5.svg index 69751327..67ae9967 100644 --- a/doc/_static/Transformer/Windings_Yz5.svg +++ b/doc/_static/Transformer/Windings_Yz5.svg @@ -1 +1 @@ - + diff --git a/doc/_static/VoltageSource/American_Delta_Voltage_Source.svg b/doc/_static/VoltageSource/American_Delta_Voltage_Source.svg index c8a8d532..404b4c8c 100644 --- a/doc/_static/VoltageSource/American_Delta_Voltage_Source.svg +++ b/doc/_static/VoltageSource/American_Delta_Voltage_Source.svg @@ -1 +1 @@ - + diff --git a/doc/_static/VoltageSource/American_Star_Voltage_Source.svg b/doc/_static/VoltageSource/American_Star_Voltage_Source.svg index ab8f8668..580afe6d 100644 --- a/doc/_static/VoltageSource/American_Star_Voltage_Source.svg +++ b/doc/_static/VoltageSource/American_Star_Voltage_Source.svg @@ -1 +1 @@ - + diff --git a/doc/_static/VoltageSource/European_Delta_Voltage_Source.svg b/doc/_static/VoltageSource/European_Delta_Voltage_Source.svg index 937e078d..6996e24b 100644 --- a/doc/_static/VoltageSource/European_Delta_Voltage_Source.svg +++ b/doc/_static/VoltageSource/European_Delta_Voltage_Source.svg @@ -1 +1 @@ - + diff --git a/doc/_static/VoltageSource/European_Star_Voltage_Source.svg b/doc/_static/VoltageSource/European_Star_Voltage_Source.svg index 99bb6132..7fb13bd4 100644 --- a/doc/_static/VoltageSource/European_Star_Voltage_Source.svg +++ b/doc/_static/VoltageSource/European_Star_Voltage_Source.svg @@ -1 +1 @@ - + diff --git a/doc/_static/css/custom.css b/doc/_static/css/custom.css index 999b7b4e..61a73371 100644 --- a/doc/_static/css/custom.css +++ b/doc/_static/css/custom.css @@ -8,6 +8,8 @@ body { font-family: "Raleway", sans-serif; + display: flex; + flex-direction: column; } dl dd:not(:last-child) { diff --git a/doc/advanced/Floating_Neutral.md b/doc/advanced/Floating_Neutral.md index 8948bc08..f5d09d75 100644 --- a/doc/advanced/Floating_Neutral.md +++ b/doc/advanced/Floating_Neutral.md @@ -65,7 +65,7 @@ plot_voltage_phasors(unbalanced_load, ax=axes[2]) plt.show() ``` -```{image} /_static/Advanced/Floating_Neutral_Auto.png +```{image} /_static/Advanced/Floating_Neutral_Auto.webp --- alt: Floating neutral created automatically due to missing neutral in the bus align: center @@ -116,7 +116,7 @@ plot_voltage_phasors(floating_load, ax=axes[2]) plt.show() ``` -```{image} /_static/Advanced/Floating_Neutral_Manual.png +```{image} /_static/Advanced/Floating_Neutral_Manual.webp --- alt: Floating neutral created manually by setting `connect_neutral=False` align: center @@ -195,7 +195,7 @@ plot_voltage_phasors(load_tr_floating, ax=axes[1, 1]) plt.show() ``` -```{image} /_static/Advanced/Floating_Neutral_Transformer.png +```{image} /_static/Advanced/Floating_Neutral_Transformer.webp --- alt: Floating neutral on the LV side of a transformer align: center diff --git a/doc/conf.py b/doc/conf.py index 9781bd44..2491fad2 100644 --- a/doc/conf.py +++ b/doc/conf.py @@ -24,8 +24,8 @@ # author = "Benoît Vinot" # The full version, including alpha/beta/rc tags -version = "0.13" -release = "0.13.1" +version = "0.14" +release = "0.14.0" # -- General configuration --------------------------------------------------- diff --git a/doc/images/Line/Twisted_Geometry.tex b/doc/images/Line/Twisted_Geometry.tex index da4dd85d..1c2b6a14 100644 --- a/doc/images/Line/Twisted_Geometry.tex +++ b/doc/images/Line/Twisted_Geometry.tex @@ -1,6 +1,5 @@ \input{Preamble}% -\usetikzlibrary{patterns}% \begin{document} \begin{tikzpicture}[% @@ -12,7 +11,7 @@ % % Terre % - \filldraw[pattern=north west lines] (-5,0) rectangle (5,0.5);% + \filldraw[color=DarkGray] (-5,0) rectangle (5,0.5);% % % Conducteurs @@ -20,15 +19,14 @@ % Neutre \coordinate (n center) at (0,8);% \path[fill=RoseauGrey, draw=black] (n center) circle[radius=1];% - \draw[pattern=north east lines, pattern color=red, preaction={fill, white}] (n center) circle[radius=0.90];% + \draw[fill=red] (n center) circle[radius=0.90];% \node[shape=circle, draw, fill=white] (n center node) at (n center) {$\nrm$};% % Phases \foreach \x/\y/\z in {a/135/$\arm$,b/45/$\brm$,c/-90/$\crm$} {% \path (n center) ++(\y:2.5) coordinate (\x\space center);% \path[fill=RoseauGrey, draw=black] (\x\space center) circle[radius=1.5];% - \draw[pattern=north east lines, pattern color=RoseauGreen, preaction={fill, white}] % - (\x\space center) circle[radius=1.4];% + \draw[fill=RoseauGreen] (\x\space center) circle[radius=1.4];% \node[shape=circle, draw, fill=white] at (\x\space center) {\z};% }% \draw[dashed] (n center) circle[radius=4];% @@ -43,13 +41,13 @@ \path let \p1=($(dessin.north)!0.5!(dessin.south)$) in % coordinate (ancre legende) at (5,\y1);% \begin{scope}[shift={(ancre legende)}, local bounding box=legende] - \path[pattern=north east lines, pattern color=red] (0, 2) circle[radius=0.25];% + \path[fill=red] (0, 2) circle[radius=0.25];% \node[right] at (0.3, 2) {Neutral conductor};% - \path[pattern=north east lines, pattern color=RoseauGreen] (0, 1) circle[radius=0.25];% + \path[fill=RoseauGreen] (0, 1) circle[radius=0.25];% \node[right] at (0.3, 1) {Phase conductor};% \path[fill=RoseauGrey, draw=black] (0, 0) circle[radius=0.25];% \node[right] at (0.3, 0) {Insulator};% - \filldraw[pattern=north west lines] (-0.25, -1.25) rectangle +(0.5, 0.5);% + \filldraw[color=DarkGray] (-0.25, -1.25) rectangle +(0.5, 0.5);% \node[right] at (0.3, -1) {Ground};% \node[shape=circle, draw, fill=white] at (0, -2) {$\arm$};% \node[right] at (0.3, -2) {Identifier (phase or neutral)};% diff --git a/doc/images/Line/Underground_Geometry.tex b/doc/images/Line/Underground_Geometry.tex index 9e042b35..0240c6f4 100644 --- a/doc/images/Line/Underground_Geometry.tex +++ b/doc/images/Line/Underground_Geometry.tex @@ -1,7 +1,5 @@ \input{Preamble}% -\usetikzlibrary{patterns}% - \begin{document} \begin{tikzpicture}[% show background rectangle,% @@ -18,7 +16,7 @@ % % Terre % - \filldraw[pattern=north west lines] (-5,-5) rectangle (5,5);% + \filldraw[color=DarkGray] (-5,-5) rectangle (5,5);% \filldraw[fill=white,draw=black] (0, 0) circle[radius=4.5];% % @@ -29,15 +27,13 @@ % Neutre \path (wire center) ++(135:1.75) coordinate (n center);% - \draw[pattern=north east lines, pattern color=red, preaction={fill, white}]% - (n center) circle[radius=0.90];% + \draw[fill=red](n center) circle[radius=0.90];% \node[shape=circle, draw, fill=white] (n center node) at (n center) {$\nrm$};% % Phases \foreach \x/\y/\z in {a/-135/$\arm$,b/-45/$\brm$,c/45/$\crm$} {% \path (wire center) ++(\y:1.75) coordinate (\x\space center);% - \draw[pattern=north east lines, pattern color=RoseauGreen, preaction={fill, white}] % - (\x\space center) circle[radius=1.1];% + \draw[fill=RoseauGreen] (\x\space center) circle[radius=1.1];% \node[shape=circle, draw, fill=white] at (\x\space center) {\z};% }% @@ -52,13 +48,13 @@ \path let \p1=($(dessin.north)!0.5!(dessin.south)$) in % coordinate (ancre legende) at (7,\y1);% \begin{scope}[shift={(ancre legende)}, local bounding box=legende] - \path[pattern=north east lines, pattern color=red] (0, 2) circle[radius=0.25];% + \path[fill=red] (0, 2) circle[radius=0.25];% \node[right] at (0.3, 2) {Neutral conductor};% - \path[pattern=north east lines, pattern color=RoseauGreen] (0, 1) circle[radius=0.25];% + \path[fill=RoseauGreen] (0, 1) circle[radius=0.25];% \node[right] at (0.3, 1) {Phase conductor};% \path[fill=RoseauGrey, draw=black] (0, 0) circle[radius=0.25];% \node[right] at (0.3, 0) {Insulator};% - \filldraw[pattern=north west lines] (-0.25, -1.25) rectangle +(0.5, 0.5);% + \filldraw[color=DarkGray] (-0.25, -1.25) rectangle +(0.5, 0.5);% \node[right] at (0.3, -1) {Ground};% \node[shape=circle, draw, fill=white] at (0, -2) {$\arm$};% \node[right] at (0.3, -2) {Identifier (phase or neutral)};% diff --git a/doc/images/Load/FlexibleLoad/Constant_P_Projection.tex b/doc/images/Load/FlexibleLoad/Constant_P_Projection.tex index bc71a505..b5e640a8 100644 --- a/doc/images/Load/FlexibleLoad/Constant_P_Projection.tex +++ b/doc/images/Load/FlexibleLoad/Constant_P_Projection.tex @@ -8,7 +8,7 @@ ] % Styles \tikzset{fleche/.style={->, -{Latex}}}% - \tikzset{interdit/.style={pattern=north east lines, pattern color=red}}% + \tikzset{interdit/.style={fill=red!75!white, draw=black}}% \tikzset{point/.pic={\filldraw[#1] (0,0) circle[radius=0.05];}, point/.default=black}% % Parameters @@ -20,12 +20,6 @@ \pgfmathsetmacro{\startangle}{-10}% \pgfmathsetmacro{\endangle}{90-\startangle}% - % Axes - \pgfmathsetmacro{\tmp}{\r*cos(90-\startangle)};% - \draw[fleche] (\tmp,0) -- (\R,0) node[below right] {$P$};% - \pgfmathsetmacro{\tmp}{\r*sin(\startangle)};% - \draw[fleche] (0,\tmp) -- (0,\R) node[above right] {$Q$};% - % Circle \draw (\startangle:\r) arc[start angle=\startangle, end angle=\endangle, radius=\r];% \pgfmathsetmacro{\tmp}{\r*sin(\startangle)};% @@ -44,6 +38,12 @@ \fill[interdit] (\pth,\qth) arc[start angle=\angth, end angle=\startangle, radius=\r] -- (\pth,\tmp);% + % Axes + \pgfmathsetmacro{\tmp}{\r*cos(90-\startangle)};% + \draw[fleche] (\tmp,0) -- (\R,0) node[below right] {$P$};% + \pgfmathsetmacro{\tmp}{\r*sin(\startangle)};% + \draw[fleche] (0,\tmp) -- (0,\R) node[above right] {$Q$};% + % Point P^{\theo} \path (\pth,0) pic[pic type=point];% diff --git a/doc/images/Load/FlexibleLoad/Constant_Q_Projection.tex b/doc/images/Load/FlexibleLoad/Constant_Q_Projection.tex index e7916d39..bc1f1cd4 100644 --- a/doc/images/Load/FlexibleLoad/Constant_Q_Projection.tex +++ b/doc/images/Load/FlexibleLoad/Constant_Q_Projection.tex @@ -8,7 +8,7 @@ ] % Styles \tikzset{fleche/.style={->, -{Latex}}}% - \tikzset{interdit/.style={pattern=north east lines, pattern color=red}}% + \tikzset{interdit/.style={fill=red!75!white, draw=black}}% \tikzset{point/.pic={\filldraw[#1] (0,0) circle[radius=0.05];}, point/.default=black}% % Paramètres @@ -20,12 +20,6 @@ \pgfmathsetmacro{\startangle}{-10}% \pgfmathsetmacro{\endangle}{90-\startangle}% - % Axes - \pgfmathsetmacro{\tmp}{\r*cos(90-\startangle)};% - \draw[fleche] (\tmp,0) -- (\R,0) node[below right] {$P$};% - \pgfmathsetmacro{\tmp}{\r*sin(\startangle)};% - \draw[fleche] (0,\tmp) -- (0,\R) node[above right] {$Q$};% - % Cercle \draw (\startangle:\r) arc[start angle=\startangle, end angle=\endangle, radius=\r];% \pgfmathsetmacro{\tmp}{\r*sin(\startangle)};% @@ -44,6 +38,12 @@ \fill[interdit] (\pth,\qth) arc[start angle=\angth, end angle=\startangle, radius=\r] -- (\pth,\tmp);% + % Axes + \pgfmathsetmacro{\tmp}{\r*cos(90-\startangle)};% + \draw[fleche] (\tmp,0) -- (\R,0) node[below right] {$P$};% + \pgfmathsetmacro{\tmp}{\r*sin(\startangle)};% + \draw[fleche] (0,\tmp) -- (0,\R) node[above right] {$Q$};% + % Point noir sur P^{\theo} \path (\pth,0) pic[pic type=point];% diff --git a/doc/images/Load/FlexibleLoad/Domain_Common.tex b/doc/images/Load/FlexibleLoad/Domain_Common.tex index d2409fc2..9f63878d 100644 --- a/doc/images/Load/FlexibleLoad/Domain_Common.tex +++ b/doc/images/Load/FlexibleLoad/Domain_Common.tex @@ -5,7 +5,7 @@ \tikzset{fleche/.style={->, -{Latex}}};% \tikzset{point/.pic={\filldraw[#1] (0,0) circle[radius=0.05];}};% \tikzset{domaine/.style={blue, line width=0.75mm}};% -\tikzset{domaine hache/.style={domaine, pattern=north east lines, pattern color=blue}};% +\tikzset{domaine hache/.style={domaine, fill=blue}};% % % Macros diff --git a/doc/images/Load/FlexibleLoad/Euclidean_Projection.tex b/doc/images/Load/FlexibleLoad/Euclidean_Projection.tex index e8ab625a..a7138018 100644 --- a/doc/images/Load/FlexibleLoad/Euclidean_Projection.tex +++ b/doc/images/Load/FlexibleLoad/Euclidean_Projection.tex @@ -8,7 +8,7 @@ ] % Styles \tikzset{fleche/.style={->, -{Latex}}}% - \tikzset{interdit/.style={pattern=north east lines, pattern color=red}}% + \tikzset{interdit/.style={fill=red!75!white, draw=black}}% \tikzset{point/.pic={\filldraw[#1] (0,0) circle[radius=0.05];}, point/.default=black}% % Paramètres @@ -20,12 +20,6 @@ \pgfmathsetmacro{\startangle}{-10}% \pgfmathsetmacro{\endangle}{90-\startangle}% - % Axes - \pgfmathsetmacro{\tmp}{\r*cos(90-\startangle)};% - \draw[fleche] (\tmp,0) -- (\R,0) node[below right] {$P$};% - \pgfmathsetmacro{\tmp}{\r*sin(\startangle)};% - \draw[fleche] (0,\tmp) -- (0,\R) node[above right] {$Q$};% - % Circle \draw (\startangle:\r) arc[start angle=\startangle, end angle=\endangle, radius=\r];% \pgfmathsetmacro{\tmp}{\r*sin(\startangle)};% @@ -44,6 +38,12 @@ \fill[interdit] (\pth,\qth) arc[start angle=\angth, end angle=\startangle, radius=\r] -- (\pth,\tmp);% + % Axes + \pgfmathsetmacro{\tmp}{\r*cos(90-\startangle)};% + \draw[fleche] (\tmp,0) -- (\R,0) node[below right] {$P$};% + \pgfmathsetmacro{\tmp}{\r*sin(\startangle)};% + \draw[fleche] (0,\tmp) -- (0,\R) node[above right] {$Q$};% + % Point P^{\theo} \path (\pth,0) pic[pic type=point];% diff --git a/doc/images/Preamble.tex b/doc/images/Preamble.tex index 5a36ef14..9b1d0f1b 100644 --- a/doc/images/Preamble.tex +++ b/doc/images/Preamble.tex @@ -33,7 +33,7 @@ \ctikzset{bipoles/length=1.2cm}% % Colors -\usepackage{xcolor}% +\usepackage[svgnames]{xcolor}% \definecolor{RoseauGreen}{HTML}{cad40e}% \definecolor{RoseauGrey}{HTML}{adb9cb}% \definecolor{RoseauBlue}{HTML}{234e83}% diff --git a/doc/usage/Catalogues.md b/doc/usage/Catalogues.md index 49ea247a..99d4a88a 100644 --- a/doc/usage/Catalogues.md +++ b/doc/usage/Catalogues.md @@ -32,8 +32,14 @@ map. ### Source of data -All these networks are built from open data available in France. **The complete model of the French distribution network -can be provided on demand**. Please email us at [contact@roseautechnologies.com](mailto:contact@roseautechnologies.com). +All these networks are built from open data available in France. + +```{include} ../../README.md +--- +start-after: +end-before: +--- +``` ### Inspecting the catalogue @@ -403,6 +409,7 @@ The available lines data are based on the following sources: - IEC standards including: IEC-60228, IEC-60287, IEC-60364 - Technique de l'ingénieur (French technical and scientific documentation) +- Catalogues of Nexans and the NF C 33-209 and NF C 33-210 standards. ### Inspecting the catalogue @@ -521,39 +528,49 @@ down the result to a single line in the catalogue. For instance, these parameters filter the results down to a single line parameters: ```pycon ->>> rlf.LineParameters.from_catalogue(line_type="underground", material="al", section=240) -LineParameters(id='U_AL_240') +>>> rlf.LineParameters.from_catalogue(line_type="underground", material="al", section=288) +LineParameters(id='U_AL_288') ``` Or you can use the `name` filter directly: ```pycon ->>> rlf.LineParameters.from_catalogue(name="U_AL_240") -LineParameters(id='U_AL_240') +>>> rlf.LineParameters.from_catalogue(name="U_AL_288") +LineParameters(id='U_AL_288') ``` As you can see, the `id` of the created instance is the same as the name in the catalogue. You can override this behaviour by passing the `id` parameter to `from_catalogue`: ```pycon ->>> rlf.LineParameters.from_catalogue(name="U_AL_240", id="lp-special") +>>> rlf.LineParameters.from_catalogue(name="U_AL_288", id="lp-special") LineParameters(id='lp-special') ``` -Line parameters created from the catalogue are 3-phase without a neutral by default. It is possible to create line +Most line parameters created from the catalogue are 3-phase without a neutral by default. It is possible to create line parameters with different numbers of phases using the `nb_phases` parameter. ```pycon ->>> rlf.LineParameters.from_catalogue(name="U_AL_240").z_line.shape +>>> rlf.LineParameters.from_catalogue(name="U_AL_288").z_line.shape (3, 3) >>> # For 3-phase with neutral lines -... rlf.LineParameters.from_catalogue(name="U_AL_240", nb_phases=4).z_line.shape +... rlf.LineParameters.from_catalogue(name="U_AL_288", nb_phases=4).z_line.shape (4, 4) >>> # For single-phase lines -... rlf.LineParameters.from_catalogue(name="U_AL_240", nb_phases=2).z_line.shape +... rlf.LineParameters.from_catalogue(name="U_AL_288", nb_phases=2).z_line.shape (2, 2) ``` +LV line parameters have a neutral conductor by default. These are identified by a name having the format +`..._..._3x...+...`. + +```pycon +>>> rlf.LineParameters.from_catalogue(name="U_AL_3x150+70") +LineParameters(id='U_AL_3x150+70') +>>> rlf.LineParameters.from_catalogue(name="U_AL_3x150+70").z_line.shape +(4, 4) +``` + In case no or several results match the parameters, an error is raised: ```pycon diff --git a/doc/usage/Data_Exchange.md b/doc/usage/Data_Exchange.md index 5a4a61b4..02321e7f 100644 --- a/doc/usage/Data_Exchange.md +++ b/doc/usage/Data_Exchange.md @@ -63,7 +63,7 @@ Then drag-and-drop this file into your PowerFactory project to use it as "Export With the folder now available in PowerFactory, make sure you have your project activated then export the network to DGS, click on the `File` menu then hover over `Export` and choose `DGS Format...` from the list like so: -```{image} /_static/IO/DGS_How_To_Export.png +```{image} /_static/IO/DGS_How_To_Export.webp --- alt: Screenshot showing PowerFactory's "File/Export/DGS Format..." menu width: 500px @@ -73,7 +73,7 @@ align: center A "DGS-Export" window will open, set the "Export Options" and "Export Definition" as shown in the following picture: -```{image} /_static/IO/DGS_Export_Window.png +```{image} /_static/IO/DGS_Export_Window.webp --- alt: Screenshot showing PowerFactory's "DGS-Export" window width: 800px @@ -125,7 +125,7 @@ The parameters of a line type can be found in two different panels on the graphi - the "Basic Data" panel as shown in the figure below - ```{image} /_static/IO/DGS_Line_Basic_Data.png + ```{image} /_static/IO/DGS_Line_Basic_Data.webp --- alt: Line basic data panel align: center @@ -134,7 +134,7 @@ The parameters of a line type can be found in two different panels on the graphi - the "Load Flow" panel as shown in the figure below - ```{image} /_static/IO/DGS_Line_Load_Flow.png + ```{image} /_static/IO/DGS_Line_Load_Flow.webp --- alt: Line load flow panel align: center @@ -172,7 +172,7 @@ PowerFactory: - the "Basic Data" panel as shown in the figure below - ```{image} /_static/IO/DGS_Two_Winding_Three_Phase_Transformer_Basic_Data.png + ```{image} /_static/IO/DGS_Two_Winding_Three_Phase_Transformer_Basic_Data.webp --- alt: Two winding three-phase transformer basic data panel align: center @@ -181,7 +181,7 @@ PowerFactory: - the "Load Flow" panel as shown in the figure below - ```{image} /_static/IO/DGS_Two_Winding_Three_Phase_Transformer_Load_Flow.png + ```{image} /_static/IO/DGS_Two_Winding_Three_Phase_Transformer_Load_Flow.webp --- alt: Two winding three-phase transformer load flow panel align: center diff --git a/doc/usage/Extras.md b/doc/usage/Extras.md index abbc6a4f..303b8b17 100644 --- a/doc/usage/Extras.md +++ b/doc/usage/Extras.md @@ -156,6 +156,31 @@ array([345.+199.18584287j]) ['bn', 'cn'] ``` +## Kron's reduction + +Kron's reduction is a method to reduce the size of an admittance or impedance matrix by eliminating nodes that are not +of interest, typically the neutral conductor in power systems. You can use the function +{func}`roseau.load_flow.converters.kron_reduction` to perform Kron's reduction on any square matrix of real or complex +numbers. Example: + +```pycon +>>> import numpy as np +... import roseau.load_flow as rlf +>>> matrix_4x4 = np.array( +... [ +... [4, 1, 2, 0], +... [1, 3, 0, 1], +... [2, 0, 3, 1], +... [0, 1, 1, 2], +... ], +... dtype=np.float64, +... ) +... rlf.converters.kron_reduction(matrix_4x4) +array([[ 4. , 1. , 2. ], + [ 1. , 2.5, -0.5], + [ 2. , -0.5, 2.5]]) +``` + ## Constants {mod}`roseau.load_flow.constants` contains some common mathematical and physical constants like the resistivity and diff --git a/doc/usage/Plotting.md b/doc/usage/Plotting.md index b17b0fc6..98853107 100644 --- a/doc/usage/Plotting.md +++ b/doc/usage/Plotting.md @@ -4,99 +4,171 @@ myst: description lang=en: | Learn how to plot an MV or LV network with Roseau Load Flow, a powerful load flow solver for the electrical calculation of smart grids. - keywords lang=en: simulation, distribution grid, map, plot + keywords lang=en: simulation, distribution grid, map, voltage profile, plot # spellchecker:off description lang=fr: | Apprenez à tracer une carte du réseau MT ou BT avec Roseau Load Flow, solveur d'écoulements de charge pour le calcul électrique des réseaux intelligents. - keywords lang=fr: simulation, réseau, électrique, carte, tracé + keywords lang=fr: simulation, réseau, électrique, carte, profil de tension, tracé # spellchecker:on --- # Plotting -_Roseau Load Flow_ provides functions to plot networks and some electric quantities in the `roseau.load_flow.plotting` -module. +_Roseau Load Flow_ provides plotting functionality in the `rlf.plotting` module. -## Plotting a network on a map +## Plotting Networks -The {func}`~roseau.load_flow.plotting.plot_interactive_map` function plots an `ElectricalNetwork` on an interactive map -using the [folium](https://python-visualization.github.io/folium/latest) library. The function requires the geometries -of the elements in the network to be defined. Only buses and lines are currently plotted. Simply call the function with -an `ElectricalNetwork` to get an interactive map of the network `plot_interactive_map(en)`. +### Voltage Profile -The `plot_interactive_map` function uses the `ElectricalNetwork` geo dataframes of buses and lines to plot the network -on a map. The function accepts optional arguments to customize the appearance of the plot. Refer to the function's -documentation for more information. +The {func}`~roseau.load_flow.plotting.voltage_profile` function can be used to create a voltage profile of the network. -Let's take a MV network from the catalogue as an example to show how we can customize the style of the buses on the map: +A voltage profile represents the voltage (in %) of network nodes as a function of their distance from a reference node. +Branches connecting nodes (buses) are shown as lines between bus locations. Buses are color-coded according to their +voltages, while branches are colored based on their loading as described in the [Results Colors](#results-colors) +section below. + +The network must have nominal voltages defined for its buses and valid load flow results. + +For multiphase networks, the voltage profile must be selected for a specific mode: either `"min"` or `"max"`, which +represent the minimum or maximum voltage magnitude across all phases at each bus. + +To visualize the voltage profile of a network, use one of the `plot_` methods on the object returned by the +{func}`~roseau.load_flow.plotting.voltage_profile` function. Example: ```pycon >>> import roseau.load_flow as rlf ->>> from roseau.load_flow.plotting import plot_interactive_map ->>> en = rlf.ElectricalNetwork.from_catalogue(name="MVFeeder210", load_point_name="Winter") ->>> en - +... en = rlf.ElectricalNetwork.from_catalogue("LVFeeder36360", "Winter") +... en + + +>>> en.solve_load_flow() +(3, 4.206412995699793e-12) + +>>> rlf.plotting.voltage_profile( +... en, mode="min", traverse_transformers=True, distance_unit="m" +... ).plot_plotly().show() ``` -As the `id` of the buses of this network contains information about the type of bus, we can use it to apply different -styles for different bus types. For example, HV/MV substation can have different size and color than MV/LV substations -and junction buses. `plot_interactive_map` takes an optional `style_function` argument to customize the style of the -plots. This is a function that accepts a GeoJSON feature mapping and returns an optional dictionary of style properties. -The GeoJSON feature contains an `"element_type"` property that indicates the type of the element (bus, line, etc.). The -other properties are the columns of the dataframes of the elements of the network. + + + + +**Features** + +- **Reference bus**: select the reference bus for distance; defaults to the source bus with the highest voltage +- **Transformer traversal**: plot the entire network by traversing transformers; defaults to plotting the subnetwork + connected to the reference bus only +- **Distance unit**: choose the distance display unit; defaults to kilometers (`"km"`) +- **Switch length**: set a custom length for switches; defaults to 2 m or the shortest line length if smaller. + +**Supported Backends** + +- **Matplotlib**: use the `plot_matplotlib` method to create a static plot using the `matplotlib` library. You can + optionally pass an `Axes` object to the method to customize the plot further. +- **Plotly**: use the `plot_plotly` method to create an interactive plot using the `plotly` library. + +**Tip** + +You can plot both minimum and maximum voltage profiles on the same plot by passing the same `Axes` object to the +`plot_matplotlib` method for both modes. Example: ```pycon ->>> def style_function(feature: dict) -> dict | None: -... # If the element is not a bus, return None to use the default style -... if feature["properties"]["element_type"] != "bus": -... return None -... # Override the default style of buses based on the bus id -... bus_id = feature["properties"]["id"] -... if bus_id.startswith("HVMV"): # HV/MV substation -... return { -... "fill": True, -... "fillColor": "#000000", -... "color": "#000000", -... "fillOpacity": 1, -... "radius": 7, -... } -... elif bus_id.startswith("MVLV"): # MV/LV substations -... return { -... "fill": True, -... "fillColor": "#234e83", -... "color": "#234e83", -... "fillOpacity": 1, -... "radius": 5, -... } -... else: # Junction buses -... return { -... "fill": True, -... "fillColor": "#234e83", -... "color": "#234e83", -... "fillOpacity": 1, -... "radius": 3, -... } -... +>>> import matplotlib.pyplot as plt +... import roseau.load_flow as rlf +... en = rlf.ElectricalNetwork.from_catalogue("LVFeeder36360", "Winter") +... en.solve_load_flow() +... ax = plt.figure(figsize=(8, 4)).gca() +... rlf.plotting.voltage_profile( +... en, mode="min", traverse_transformers=True, distance_unit="m" +... ).plot_matplotlib(ax=ax) +... rlf.plotting.voltage_profile( +... en, mode="max", traverse_transformers=True, distance_unit="m" +... ).plot_matplotlib(ax=ax) +... ax.set_title("Voltage Profile (min and max)") +... ax.set_ylabel("Voltage (%)") +... plt.show() +``` +```{image} /_static/Plotting/Voltage_Profile_LVFeeder36360_Min_Max.webp +--- +alt: The voltage profile (min and max) of the network LVFeeder36360 +align: center +--- ``` -Finally, calling the `plot_interactive_map` function with the custom style function produces an interactive map of the -network: +### Interactive Map + +The simplest way to visualize an electrical network with bus and line geometries is to plot it on a map using the +{func}`~roseau.load_flow.plotting.plot_interactive_map` function. Example: ```pycon ->>> m = plot_interactive_map(en, style_function=style_function) ->>> m +>>> import roseau.load_flow as rlf +... en = rlf.ElectricalNetwork.from_catalogue(name="MVFeeder210", load_point_name="Winter") +... rlf.plotting.plot_interactive_map(en) ``` -## Plotting a network with no geometries +Make sure you have [folium](https://python-visualization.github.io/folium/latest) installed in your Python environment +and that your network has a coordinate reference system (CRS) set via the `en.crs` attribute. + +**Features** + +1. **Interactive map**: zoom in/out, pan, hover or click on elements to see their properties +2. **Base maps**: all + [folium tilesets](https://python-visualization.github.io/folium/latest/getting_started.html#Choosing-a-tileset) are + supported +3. **Search**: search for specific elements by their ID +4. **Line laying**: underground cables are dashed, other lines are solid +5. **Voltage levels**: HV/MV/LV elements have different sizes for easier identification +6. **Layer control**: toggle visibility of buses, lines, transformers +7. **Custom styling**: customize colors, sizes, and styles of elements based on their properties. -If the network does not have geometries defined for its elements, the `plot_interactive_map` function will not work. In -this case, you can use the {meth}`~roseau.load_flow.ElectricalNetwork.to_graph` method to convert the network to a -networkx `MultiGraph` and plot it using the `networkx` library. In the following example we plot the graph of the -network `MVFeeder210` from the previous example: +Use the `map_kws` keyword to pass additional arguments to the `folium.Map` constructor. Refer to the function's +documentation for more details. + +**Note** + +Only buses, lines and transformers are currently plotted. + +### Interactive Map with Load Flow Results + +The {func}`~roseau.load_flow.plotting.plot_results_interactive_map` function can be used to plot load flow results on +the map. The network must have valid results before calling this function. Example: + +```pycon +>>> import roseau.load_flow as rlf +... en = rlf.ElectricalNetwork.from_catalogue(name="MVFeeder210", load_point_name="Winter") +... # Let's create some extreme conditions to see voltage drops/rises and line overloads +... en.loads["MVLV14633_consumption"].powers = 3.5e6 +... en.loads["MVLV15838_production"].powers = -5.5e6 +... en.solve_load_flow() +... rlf.plotting.plot_results_interactive_map(en) +``` + + + +The plot shows the buses color-coded according to their voltages and the lines/transformers color-coded according to +their loading as described in the [Results Colors](#results-colors) section below. + +### Graph Plot + +If a network does not have geometries nor nominal voltages defined, the plotting functions mentioned above will not +work. In this case, you can have a visual representation of the network by converting it to a networkx graph using the +{meth}`~roseau.load_flow.ElectricalNetwork.to_graph` method and plotting it using the `networkx` library. In the +following example we plot the graph of the network `MVFeeder210` from the previous example: ```pycon >>> import networkx as nx @@ -108,7 +180,7 @@ network `MVFeeder210` from the previous example: ... nx.draw(G, node_size=50) # This works even if the geometries are not defined ``` -```{image} /_static/Plotting/MVFeeder210_Graph_No_Geometries.png +```{image} /_static/Plotting/MVFeeder210_Graph_No_Geometries.webp --- alt: The graph of the network MVFeeder210 with no geometries using networkx align: center @@ -117,12 +189,14 @@ align: center See the [networkx docs](https://networkx.org/documentation/stable/tutorial.html#drawing-graphs) for more information. -## Plotting voltage phasors +## Plotting Elements + +### Voltage Phasors -The {func}`~roseau.load_flow.plotting.plot_voltage_phasors` function plots the voltage phasors of a bus, load or source -in the complex plane. This function can be used to visualize voltage unbalance in multi-phase systems for instance. It -takes the element and an optional matplotlib `Axes` object to use for the plot. Note that the element must have load -flow results to plot the voltage phasors. +The {func}`~roseau.load_flow.plotting.plot_voltage_phasors` function plots the voltage phasors of a terminal element +(bus, load, source or a branch side) in the complex plane. This function can be used to visualize voltage unbalance in +multi-phase systems for instance. It takes the element and an optional matplotlib `Axes` object to use for the plot. +Note that the element must have load flow results to plot the voltage phasors. ```pycon >>> import matplotlib.pyplot as plt @@ -142,12 +216,36 @@ flow results to plot the voltage phasors. ... plt.show() ``` -```{image} /_static/Plotting/Plot_Voltage_Phasors.png +```{image} /_static/Plotting/Plot_Voltage_Phasors.webp --- alt: The voltage phasors of a wye-connected source and a delta-connected load align: center --- ``` +### Symmetrical Voltages + A similar function {func}`~roseau.load_flow.plotting.plot_symmetrical_voltages` plots the symmetrical components of the -voltage phasors of a three-phase bus, load or source. +voltage phasors of a three-phase terminal element. + +## Results Colors + +The results in plots are color-coded based on the following predefined states: + +- **very-low** (blue): bus voltage below {math}`U_{min}` +- **low** (light blue): bus voltage in the first quadrant of the {math}`(U_{min}, U_{n})` range +- **normal** (green): bus voltage in the last three quadrants of the {math}`(U_{min}, U_{n})` range or in the first + three quadrants of the {math}`(U_{n}, U_{max})` range; line or transformer loading below 75% {math}`load_{max}` +- **high** (orange): bus voltage in the last quadrant of the {math}`(U_{n}, U_{max})` range; line or transformer loading + between 75% and 100% {math}`load_{max}` +- **very-high** (red): bus voltage above {math}`U_{max}`; line or transformer loading above 100% {math}`load_{max}` +- **unknown** (gray): bus nominal voltage or limits not defined; line ampacity not defined + +```{image} /_static/Plotting/Result_States.webp +--- +alt: The different states for bus voltages and line/transformer loadings +align: center +--- +``` + +Colors are currently not customizable. Let us know if you need this feature. diff --git a/pyproject.toml b/pyproject.toml index c094e5cb..81daa4e8 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,93 +1,106 @@ [project] name = "roseau-load-flow" -version = "0.13.1" +version = "0.14.0" description = "Highly capable multi-phase load flow solver" +readme = "README.md" +requires-python = ">=3.12" +license = { file = "LICENSE.md" } authors = [ - { name = "Ali Hamdan", email = "ali.hamdan@roseautechnologies.com" }, - { name = "Sébastien Vallet", email = "sebastien.vallet@roseautechnologies.com" }, - { name = "Benoît Vinot", email = "benoit.vinot@roseautechnologies.com" }, - { name = "Florent Cadoux", email = "florent.cadoux@roseautechnologies.com" }, - { name = "Louise Muller", email = "louise.muller@roseautechnologies.com" }, - { name = "Audrey Ficot", email = "audrey.ficot@roseautechnologies.com" }, - { name = "Victor Gouin" }, + { name = "Ali Hamdan", email = "ali.hamdan@roseautechnologies.com" }, + { name = "Sébastien Vallet", email = "sebastien.vallet@roseautechnologies.com" }, + { name = "Benoît Vinot", email = "benoit.vinot@roseautechnologies.com" }, + { name = "Florent Cadoux", email = "florent.cadoux@roseautechnologies.com" }, + { name = "Louise Muller", email = "louise.muller@roseautechnologies.com" }, + { name = "Audrey Ficot", email = "audrey.ficot@roseautechnologies.com" }, + { name = "Victor Gouin" }, ] maintainers = [ - { name = "Ali Hamdan", email = "ali.hamdan@roseautechnologies.com" }, + { name = "Ali Hamdan", email = "ali.hamdan@roseautechnologies.com" }, ] -license = { file = "LICENSE.md" } -readme = "README.md" classifiers = [ - "Development Status :: 3 - Alpha", - # "License :: OSI Approved :: The 3-Clause BSD License (BSD-3-Clause)", # https://github.com/pypa/trove-classifiers/issues/70 - "Operating System :: MacOS :: MacOS X", - "Operating System :: Microsoft :: Windows", - "Operating System :: POSIX :: Linux", - "Programming Language :: Python :: 3.11", - "Programming Language :: Python :: 3.12", - "Programming Language :: Python :: 3.13", - "Programming Language :: Python :: 3.14", - "Programming Language :: Python :: Free Threading :: 2 - Beta", - "Topic :: Scientific/Engineering :: Physics", + "Development Status :: 3 - Alpha", + "Operating System :: MacOS :: MacOS X", + "Operating System :: Microsoft :: Windows", + "Operating System :: POSIX :: Linux", + "Programming Language :: Python :: 3.12", + "Programming Language :: Python :: 3.13", + "Programming Language :: Python :: 3.14", + "Programming Language :: Python :: Free Threading :: 2 - Beta", + "Topic :: Scientific/Engineering :: Physics", ] -requires-python = ">=3.11" dependencies = [ - "numpy>=1.21.5", - "pandas>=1.4.0", - "geopandas>=1.0.0", - "shapely>=2.0.0", - "pint>=0.21.0", - "typing-extensions>=4.6.2", - "pyproj>=3.3.0", - "certifi>=2023.5.7", - "platformdirs>=4.0.0", - "roseau-load-flow-engine==0.18.1", + "certifi>=2023.5.7", + "geopandas>=1.0.0", + "numpy>=2.0.0", + "pandas>=2.1.0", + "pint>=0.21.0", + "platformdirs>=4.0.0", + "pyproj>=3.3.0", + "roseau-load-flow-engine==0.19.0", + "shapely>=2.0.0", + "typing-extensions>=4.6.2", ] [project.urls] +documentation = "https://roseau-load-flow.roseautechnologies.com/" homepage = "https://www.roseautechnologies.com/roseau-load-flow/" -repository = "https://github.com/RoseauTechnologies/Roseau_Load_Flow/" issues = "https://github.com/RoseauTechnologies/Roseau_Load_Flow/issues/" -documentation = "https://roseau-load-flow.roseautechnologies.com/" +repository = "https://github.com/RoseauTechnologies/Roseau_Load_Flow/" [project.optional-dependencies] -plot = ["matplotlib>=3.7.2"] -graph = ["networkx>=3.0.0"] +graph = ["networkx>=3.3.0"] +plot = ["matplotlib>=3.9.0"] [dependency-groups] dev = [ - # Tests - "pytest>=8.0.0", - "pytest-cov>=5.0.0", - "pytest-xdist>=3.1.0", - "covdefaults>=2.3.0", + "covdefaults>=2.3.0", + "folium>=0.20.0", + "pytest>=9.0.0", + "pytest-cov>=5.0.0", ] doc = [ - # Docs - "sphinx>=8.0.2", - "myst-parser>=0.16.1", - "sphinx-math-dollar>=1.2.1", - "sphinx-autoapi>=3.0.0", - "sphinx-copybutton>=0.5.1", - "sphinx-inline-tabs>=2022.1.2b11", - "furo>=2022.9.29", - "sphinxcontrib-googleanalytics>=0.3", - "sphinxcontrib-bibtex>=2.5.0", - "sphinxext-opengraph>=0.9.1", - "ipython>=8.31.0", + "furo>=2022.9.29", + "ipython>=8.31.0", + "myst-parser>=0.16.1", + "sphinx>=8.0.2", + "sphinx-autoapi>=3.0.0", + "sphinx-copybutton>=0.5.1", + "sphinx-inline-tabs>=2022.1.2b11", + "sphinx-math-dollar>=1.2.1", + "sphinxcontrib-bibtex>=2.5.0", + "sphinxcontrib-googleanalytics>=0.3", + "sphinxext-opengraph>=0.9.1", ] -[tool.uv] -managed = true - [build-system] -requires = ["uv_build>=0.8.15,<0.9.0"] +requires = ["uv_build>=0.9.26,<0.10.0"] build-backend = "uv_build" -[tool.uv.build-backend] -module-name = ["roseau.load_flow", "roseau.load_flow_single"] -module-root = "" -source-exclude = ["*tests*", "*conftest.py"] +# Coverage +[tool.coverage.run] +branch = false +plugins = ["covdefaults"] +source = ["roseau/load_flow/", "roseau/load_flow_single/"] + +[tool.coverage.report] +fail_under = 93 + +[tool.coverage.html] +directory = "htmlcov" + +# MD format +[tool.mdformat] +wrap = 120 +number = true + +# Pytest +[tool.pytest] +addopts = ["--color=yes", "--import-mode=importlib"] +filterwarnings = [] +markers = ["no_patch_engine"] +testpaths = ["roseau/load_flow/", "roseau/load_flow_single/"] +# Ruff [tool.ruff] line-length = 120 show-fixes = true @@ -95,70 +108,63 @@ namespace-packages = ["roseau"] [tool.ruff.lint] select = [ - "E", - "F", - "C90", - "W", - "B", - "UP", - "I", - "RUF100", - "TID", - "SIM", - "PT", - "PIE", - "N", - "C4", - "NPY", - "T10", - "PTH", + "E", + "F", + "C90", + "W", + "B", + "UP", + "I", + "RUF100", + "TID", + "SIM", + "PT", + "PIE", + "N", + "C4", + "NPY", + "T10", + "PTH", ] unfixable = ["B"] -ignore = ["E501", "B024", "N818", "UP038", "PTH123"] +ignore = ["E501", "B024", "N818", "PTH123"] flake8-tidy-imports.ban-relative-imports = "all" flake8-pytest-style.parametrize-values-type = "tuple" mccabe.max-complexity = 15 -[tool.ruff.format] -docstring-code-format = true - [tool.ruff.lint.per-file-ignores] "*.ipynb" = ["E402", "F403", "F405"] -[tool.coverage.run] -branch = false -plugins = ["covdefaults"] -source = ["roseau/load_flow/", "roseau/load_flow_single/"] - -[tool.coverage.report] -fail_under = 93 +[tool.ruff.format] +docstring-code-format = true -[tool.coverage.html] -directory = "htmlcov" +# Tombi +[tool.tombi] +schema.strict = false -# Pytest -[tool.pytest.ini_options] -addopts = "--color=yes -n=0 --import-mode=importlib" -testpaths = ["roseau/load_flow/", "roseau/load_flow_single/"] -filterwarnings = [] -markers = ["no_patch_engine"] +[[tool.tombi.schemas]] +root = "tool.typos" +path = "https://raw.githubusercontent.com/crate-ci/typos/refs/heads/master/config.schema.json" +include = ["pyproject.toml"] # Typos [tool.typos.files] extend-exclude = [ - "*.svg", - "*.html", - "*.tex", - "*.xml", - "roseau/load_flow/tests/data/", + "*.svg", + "*.html", + "*.tex", + "*.xml", + "roseau/load_flow/tests/data/", ] [tool.typos.default] extend-ignore-re = [ - # spellchecker:disable-line - "(?Rm)^.*(#|//|%)\\s*spellchecker:disable-line$", - # spellchecker: - "(?s)(#|//)\\s*spellchecker:off.*?\\n\\s*(#|//)\\s*spellchecker:on", + # spellchecker:disable-line + "(?Rm)^.*(#|//|%)\\s*spellchecker:disable-line$", + # spellchecker: + "(?s)(#|//)\\s*spellchecker:off.*?\\n\\s*(#|//)\\s*spellchecker:on", + # spellchecker:ignore-next-line + "(#|//)\\s*spellchecker:ignore-next-line\\n.*", ] extend-ignore-identifiers-re = ["YNd[0-9]*"] @@ -176,8 +182,14 @@ typ = "typ" lod = "lod" # Phase to Neutral pn = "pn" +# In scripts/generate_lv_line_parameters_catalogue.py +AGS = "AGS" -# MD format -[tool.mdformat] -wrap = 120 -number = true +# UV +[tool.uv] +managed = true + +[tool.uv.build-backend] +module-name = ["roseau.load_flow", "roseau.load_flow_single"] +module-root = "" +source-exclude = ["*tests*", "*conftest.py"] diff --git a/roseau/load_flow/__init__.py b/roseau/load_flow/__init__.py index 1d9f4a52..95110a0d 100644 --- a/roseau/load_flow/__init__.py +++ b/roseau/load_flow/__init__.py @@ -130,16 +130,10 @@ def __getattr__(name: str) -> Any: deprecated_classes = {"ConductorType": Material, "InsulatorType": Insulator} if name in deprecated_classes and name not in globals(): - import warnings - - from roseau.load_flow.utils.exceptions import find_stack_level + from roseau.load_flow.utils.helpers import warn_external new_class = deprecated_classes[name] - warnings.warn( - f"The `{name}` class is deprecated. Use `{new_class.__name__}` instead.", - category=FutureWarning, - stacklevel=find_stack_level(), - ) + warn_external(f"The `{name}` class is deprecated. Use `{new_class.__name__}` instead.", category=FutureWarning) globals()[name] = new_class return new_class else: diff --git a/roseau/load_flow/_solvers.py b/roseau/load_flow/_solvers.py index eb12de5b..b387381d 100644 --- a/roseau/load_flow/_solvers.py +++ b/roseau/load_flow/_solvers.py @@ -1,8 +1,7 @@ import logging import time -import warnings from abc import ABC, abstractmethod -from typing import TYPE_CHECKING, Generic, TypeAlias +from typing import TYPE_CHECKING, Generic import numpy as np from typing_extensions import TypeVar @@ -10,7 +9,7 @@ from roseau.load_flow.exceptions import RoseauLoadFlowException, RoseauLoadFlowExceptionCode from roseau.load_flow.license import activate_license, get_license from roseau.load_flow.typing import FloatArray, FloatArrayLike1D, FloatMatrix, JsonDict, Solver -from roseau.load_flow.utils import find_stack_level +from roseau.load_flow.utils import warn_external from roseau.load_flow_engine.cy_engine import ( CyAbstractNewton, CyAbstractSolver, @@ -31,7 +30,7 @@ if TYPE_CHECKING: from roseau.load_flow.utils import AbstractElement, AbstractNetwork - ElectricalNetwork: TypeAlias = AbstractNetwork[AbstractElement] + type ElectricalNetwork = AbstractNetwork[AbstractElement] _CyS_co = TypeVar("_CyS_co", bound=CyAbstractSolver, default=CyAbstractSolver, covariant=True) @@ -140,7 +139,7 @@ def update_network(self, network: "ElectricalNetwork") -> None: def update_params(self, params: JsonDict) -> None: """If the network has changed, we need to re-create a solver for this new network.""" msg = "The update_params() method is called for a solver that doesn't have any parameters." - warnings.warn(msg, stacklevel=find_stack_level()) + warn_external(msg) def to_dict(self) -> JsonDict: """Return the solver information as a dictionary format.""" diff --git a/roseau/load_flow/conftest.py b/roseau/load_flow/conftest.py index ece0f549..9fa90859 100644 --- a/roseau/load_flow/conftest.py +++ b/roseau/load_flow/conftest.py @@ -112,8 +112,6 @@ def patch_engine_impl(request: pytest.FixtureRequest, extra_dir: Path | None = N for f in filenames: if not f.endswith(".py"): continue - if f in ("constants.py", "types.py") and base_module == "roseau.load_flow.utils": - continue # TODO: Remove when deprecated modules are removed module = importlib.import_module(f"{base_module}.{f.removesuffix('.py')}") for _, klass in inspect.getmembers( module, @@ -131,6 +129,19 @@ def patch_engine_impl(request: pytest.FixtureRequest, extra_dir: Path | None = N mpatch.undo() +@pytest.fixture(scope="session", autouse=True) +def patch_warn_external(): + # Exclude test files from skipped files in warn_external + from roseau.load_flow.utils import helpers + + paths = tuple( + str(p) + for p in Path(roseau.load_flow.__file__).resolve().parent.parent.rglob("**/*.py") + if "tests" not in p.parts + ) + helpers._get_skip_file_prefixes = lambda: paths + + @pytest.fixture(autouse=True) def patch_engine(request): yield from patch_engine_impl(request) diff --git a/roseau/load_flow/constants.py b/roseau/load_flow/constants.py index 41acaa6a..33c94550 100644 --- a/roseau/load_flow/constants.py +++ b/roseau/load_flow/constants.py @@ -114,22 +114,3 @@ } """Relative permittivity of common insulator materials according to the IEC 60287 standard.""" # IEC 60287-1-1 Table 3. We only include the MV values. - - -def __getattr__(name: str): - import warnings - - from roseau.load_flow.utils.exceptions import find_stack_level - - if name in ("PositiveSequence", "NegativeSequence", "ZeroSequence"): - # deprecated since 0.12.0 - warnings.warn( - f"'rlf.constants.{name}' is deprecated. Use 'rlf.sym.{name}' instead.", - category=FutureWarning, - stacklevel=find_stack_level(), - ) - from roseau.load_flow import sym - - return getattr(sym, name) - - raise AttributeError(f"module '{__name__}' has no attribute '{name}'") diff --git a/roseau/load_flow/converters.py b/roseau/load_flow/converters.py index 6c7fa659..95b02def 100644 --- a/roseau/load_flow/converters.py +++ b/roseau/load_flow/converters.py @@ -4,6 +4,7 @@ Available functions: * convert potentials to voltages +* perform Kron reduction on nxn matrices """ import logging @@ -118,20 +119,19 @@ def calculate_voltage_phases(phases: str) -> list[str]: raise RoseauLoadFlowException(msg, code=RoseauLoadFlowExceptionCode.BAD_PHASE) from None -def __getattr__(name: str): - import warnings +def kron_reduction[D: np.dtype](matrix: np.ndarray[tuple[int, int], D]) -> np.ndarray[tuple[int, int], D]: + """Perform Kron's reduction on a square matrix to reduce it by one dimension. - from roseau.load_flow.utils.exceptions import find_stack_level + Let :math:`M` be a :math:`n \\times n` matrix and :math:`M_{ij}` be the element at row :math:`i` + and column :math:`j` of :math:`M`. Kron's reduction of :math:`M`, denoted :math:`M'` is a + :math:`(n-1) \\times (n-1)` matrix with elements :math:`M'_{ij}` defined as: - if name in ("phasor_to_sym", "sym_to_phasor", "series_phasor_to_sym"): - # deprecated since 0.12.0 - warnings.warn( - f"'rlf.converters.{name}' is deprecated. Use 'rlf.sym.{name}' instead.", - category=FutureWarning, - stacklevel=find_stack_level(), - ) - from roseau.load_flow import sym - - return getattr(sym, name) + .. math:: - raise AttributeError(f"module '{__name__}' has no attribute '{name}'") + M'_{ij} = M_{ij} - (M_{in} * M_{nj}) / M_{nn} \\text{ for } i, j \\in \\{1, 2, ..., n-1\\} + """ + n = matrix.shape[0] + if matrix.shape != (n, n): + raise ValueError(f"Matrix must be square, got shape {matrix.shape}.") + n_1 = n - 1 + return matrix[:n_1, :n_1] - matrix[:n_1, n_1:] @ matrix[n_1:, :n_1] / matrix[n_1, n_1] diff --git a/roseau/load_flow/data/lines/Catalogue.csv b/roseau/load_flow/data/lines/Catalogue.csv index 93cfad67..9f142a55 100644 --- a/roseau/load_flow/data/lines/Catalogue.csv +++ b/roseau/load_flow/data/lines/Catalogue.csv @@ -354,3 +354,18 @@ T_AM_150,twisted,am,am,,,150,150,0.239372,0.239372,0.0960502777,0.0960502777,0.0 T_AM_228,twisted,am,am,,,228,228,0.1551375636,0.1551375636,0.0905569282,0.0905569282,0.0000366279,0.0000366279,395,395 T_AM_240,twisted,am,am,,,240,240,0.14525,0.14525,0.0899296465,0.0899296465,0.0000369374,0.0000369374,409,409 T_AM_288,twisted,am,am,,,288,288,0.12201,0.12201,0.0877788677,0.0877788677,0.0000380397,0.0000380397,459,459 +T_AL_3x25+54.6,twisted,aac,aaac,xlpe,xlpe,25,54.6,1.2,0.63,0.1058447031,0.0967323277,0.0000304155,0.0000338362,112,112 +T_AL_3x35+54.6,twisted,aac,aaac,xlpe,xlpe,35,54.6,0.868,0.63,0.1052321358,0.0967323277,0.0000306236,0.0000338362,138,138 +T_AL_3x50+54.6,twisted,aac,aaac,xlpe,xlpe,50,54.6,0.641,0.63,0.0996674142,0.0967323277,0.0000326533,0.0000338362,168,168 +T_AL_3x70+54.6,twisted,aac,aaac,xlpe,xlpe,70,54.6,0.443,0.63,0.0978244031,0.0967323277,0.0000333862,0.0000338362,213,213 +T_AL_3x70+70,twisted,aac,aaac,xlpe,xlpe,70,70.0,0.443,0.5,0.0978244031,0.0933453635,0.0000333862,0.0000353123,213,213 +T_AL_3x95+70,twisted,aac,aaac,xlpe,xlpe,95,70.0,0.32,0.5,0.0915882827,0.0933453635,0.00003613,0.0000353123,258,258 +T_AL_3x120+70,twisted,aac,aaac,xlpe,xlpe,120,70.0,0.253,0.5,0.0880993894,0.0933453635,0.0000378713,0.0000353123,300,300 +T_AL_3x150+70,twisted,aac,aaac,xlpe,xlpe,150,70.0,0.206,0.5,0.0856090614,0.0933453635,0.0000392205,0.0000353123,344,344 +T_AL_3x120+95,twisted,aac,aaac,xlpe,xlpe,120,95.0,0.253,0.343,0.0880993894,0.089505047,0.0000378713,0.0000371499,300,300 +T_AL_3x150+95,twisted,aac,aaac,xlpe,xlpe,150,95.0,0.206,0.343,0.0856090614,0.089505047,0.0000392205,0.0000371499,344,344 +U_AL_3x50+50,underground,aac,aac,xlpe,xlpe,50,50.0,0.641,0.641,0.08,0.08,0.0001757044,0.0001757044,160,160 +U_AL_3x95+50,underground,aac,aac,xlpe,xlpe,95,50.0,0.32,0.641,0.08,0.08,0.0001822124,0.0001757044,234,234 +U_AL_3x150+70,underground,aac,aac,xlpe,xlpe,150,70.0,0.206,0.443,0.08,0.08,0.0001979203,0.0001794958,300,300 +U_AL_3x150+150,underground,aac,aac,xlpe,xlpe,150,150.0,0.206,0.206,0.08,0.08,0.0001979203,0.0001979203,300,300 +U_AL_3x240+95,underground,aac,aac,xlpe,xlpe,240,95.0,0.125,0.32,0.08,0.08,0.0002104867,0.0001822124,388,388 diff --git a/roseau/load_flow/io/dgs/constants.py b/roseau/load_flow/io/dgs/constants.py index 5433a339..2ae8ff29 100644 --- a/roseau/load_flow/io/dgs/constants.py +++ b/roseau/load_flow/io/dgs/constants.py @@ -1,4 +1,4 @@ -from typing import Final, Literal, TypeAlias +from typing import Final, Literal from roseau.load_flow.types import Insulator, LineType, Material @@ -33,7 +33,7 @@ INSULATORS_REVERSE: Final[dict[Insulator, int]] = {v: k for k, v in INSULATORS.items()} # Loads -PwFLoadType: TypeAlias = Literal["MV", "LV", "General", "PV", "GenStat"] +type PwFLoadType = Literal["MV", "LV", "General", "PV", "GenStat"] LOAD_I_SYM_FIELD_NAMES: Final[dict[PwFLoadType, str | None]] = { "MV": "ci_sym", "LV": "i_sym", diff --git a/roseau/load_flow/io/dgs/utils.py b/roseau/load_flow/io/dgs/utils.py index fa36acb5..e317fc52 100644 --- a/roseau/load_flow/io/dgs/utils.py +++ b/roseau/load_flow/io/dgs/utils.py @@ -1,6 +1,5 @@ import json import logging -import warnings from collections.abc import Iterator, Mapping from typing import Any, Final, Self, TypedDict @@ -11,7 +10,7 @@ from roseau.load_flow.exceptions import RoseauLoadFlowException, RoseauLoadFlowExceptionCode from roseau.load_flow.typing import Id, JsonDict -from roseau.load_flow.utils import find_stack_level +from roseau.load_flow.utils import warn_external logger = logging.getLogger(__name__) @@ -71,7 +70,7 @@ def parse_dgs_version(data: Mapping[str, Any]) -> tuple[int, ...]: f"The DGS version {dgs_version} is too old, this may cause conversion errors. Try " f"updating the version before exporting." ) - warnings.warn(msg, stacklevel=find_stack_level()) + warn_external(msg) return dgs_version_tuple @@ -96,7 +95,7 @@ def has_typ_lne(typ_lne: pd.DataFrame | None) -> TypeIs[pd.DataFrame]: "types from the library to the project before exporting otherwise a LineParameter object " "will be created for each line." ) - warnings.warn(msg, stacklevel=find_stack_level()) + warn_external(msg) return False else: return True @@ -163,10 +162,7 @@ def gps_coords_to_linestring(elm_lne: pd.DataFrame, lne_idx: str) -> shapely.Lin if nb_points == 0 or nb_cols == 0: pass # nb_points is 0 -> no GPS points; nb_cols is 0 -> badly initialized GPS data by PwF elif nb_points == 1: - warnings.warn( - f"Failed to read geometry data for line {lne_idx!r}: it has a single GPS point.", - stacklevel=find_stack_level(), - ) + warn_external(f"Failed to read geometry data for line {lne_idx!r}: it has a single GPS point.") else: assert nb_cols == 2, f"Expected 2 GPS columns (Latitude/Longitude), got {nb_cols}." lat_cols = [f"GPScoords:{i}:0" for i in range(nb_points)] @@ -178,10 +174,7 @@ def gps_coords_to_linestring(elm_lne: pd.DataFrame, lne_idx: str) -> shapely.Lin ) # type: ignore ) except Exception as e: - warnings.warn( - f"Failed to read geometry data for line {lne_idx!r}: {type(e).__name__}: {e}", - stacklevel=find_stack_level(), - ) + warn_external(f"Failed to read geometry data for line {lne_idx!r}: {type(e).__name__}: {e}") return geometry diff --git a/roseau/load_flow/io/dict.py b/roseau/load_flow/io/dict.py index 074c2212..23f446a5 100644 --- a/roseau/load_flow/io/dict.py +++ b/roseau/load_flow/io/dict.py @@ -8,7 +8,6 @@ import copy import logging -import warnings from collections import defaultdict from typing import TYPE_CHECKING, Final @@ -34,7 +33,7 @@ ) from roseau.load_flow.types import Insulator, Material from roseau.load_flow.typing import Id, JsonDict -from roseau.load_flow.utils import SIDE_SUFFIX, find_stack_level, id_sort_key +from roseau.load_flow.utils import SIDE_SUFFIX, id_sort_key, warn_external if TYPE_CHECKING: from roseau.load_flow.network import ElectricalNetwork @@ -67,11 +66,10 @@ def network_from_dict( # noqa: C901 version = data.get("version", 0) if version <= 4: - warnings.warn( + warn_external( f"Got an outdated network file (version {version}), trying to update to the current format " f"(version {NETWORK_JSON_VERSION}). Please save the network again.", category=UserWarning, - stacklevel=find_stack_level(), ) if version <= 0: data = v0_to_v1_converter(data) @@ -652,11 +650,10 @@ def v2_to_v3_converter(data: JsonDict) -> JsonDict: # noqa: C901 for bus_data in old_buses: for key in ("min_voltage", "max_voltage"): if bus_data.pop(key, None) is not None and not bus_warning_emitted: - warnings.warn( + warn_external( "Starting with version 0.11.0 of roseau-load-flow (JSON file v3), `min_voltage` and " "`max_voltage` are replaced with `min_voltage_level`, `max_voltage_level` and `nominal_voltage`. " - "The found values of `min_voltage` or `max_voltage` are dropped.", - stacklevel=find_stack_level(), + "The found values of `min_voltage` or `max_voltage` are dropped." ) bus_warning_emitted = True buses.append(bus_data) diff --git a/roseau/load_flow/models/branches.py b/roseau/load_flow/models/branches.py index 2b780930..209c1e5e 100644 --- a/roseau/load_flow/models/branches.py +++ b/roseau/load_flow/models/branches.py @@ -1,6 +1,5 @@ import logging import math -import warnings from abc import abstractmethod from functools import cached_property from typing import Generic, Self @@ -16,7 +15,7 @@ from roseau.load_flow.models.transformer_parameters import TransformerParameters from roseau.load_flow.typing import ComplexArray, Id, JsonDict, Side from roseau.load_flow.units import Q_, ureg_wraps -from roseau.load_flow.utils import find_stack_level, one_or_more_repr +from roseau.load_flow.utils import one_or_more_repr, warn_external from roseau.load_flow_engine.cy_engine import CyBranch logger = logging.getLogger(__name__) @@ -206,12 +205,9 @@ def _check_same_voltage_level(self) -> None: and self.bus2._nominal_voltage is not None and not math.isclose(self.bus1._nominal_voltage, self.bus2._nominal_voltage) ): - warnings.warn( - ( - f"{self.element_type.capitalize()} {self.id!r} connects buses with different " - f"nominal voltages: {self.bus1._nominal_voltage} V and {self.bus2._nominal_voltage} V." - ), - stacklevel=find_stack_level(), + warn_external( + f"{self.element_type.capitalize()} {self.id!r} connects buses with different " + f"nominal voltages: {self.bus1._nominal_voltage} V and {self.bus2._nominal_voltage} V." ) def _update_network_parameters(self, old_parameters: _Parameters | None, new_parameters: _Parameters) -> None: diff --git a/roseau/load_flow/models/buses.py b/roseau/load_flow/models/buses.py index 4fa71f46..90f280ca 100644 --- a/roseau/load_flow/models/buses.py +++ b/roseau/load_flow/models/buses.py @@ -1,20 +1,18 @@ import logging -import warnings from collections.abc import Iterator from typing import TYPE_CHECKING, Any, Final, Self import numpy as np import pandas as pd from shapely.geometry.base import BaseGeometry -from typing_extensions import deprecated from roseau.load_flow.constants import SQRT3 from roseau.load_flow.exceptions import RoseauLoadFlowException, RoseauLoadFlowExceptionCode from roseau.load_flow.models.core import Element from roseau.load_flow.models.terminals import AbstractTerminal -from roseau.load_flow.typing import BoolArray, ComplexArray, ComplexArrayLike1D, FloatArray, Id, JsonDict +from roseau.load_flow.typing import BoolArray, ComplexArray, ComplexArrayLike1D, FloatArray, Id, JsonDict, ResultState from roseau.load_flow.units import Q_, ureg_wraps -from roseau.load_flow.utils import deprecate_renamed_parameter, find_stack_level +from roseau.load_flow.utils import warn_external from roseau.load_flow_engine.cy_engine import CyBus logger = logging.getLogger(__name__) @@ -28,9 +26,6 @@ class Bus(AbstractTerminal[CyBus]): element_type: Final = "bus" - @deprecate_renamed_parameter( - old_name="potentials", new_name="initial_potentials", version="0.12.0", category=DeprecationWarning - ) def __init__( self, id: Id, @@ -125,17 +120,6 @@ def initial_potentials(self, value: ComplexArrayLike1D) -> None: if self._cy_initialized: self._cy_element.initialize_potentials(self._initial_potentials) - @property - @deprecated("'Bus.potentials' is deprecated. It has been renamed to 'initial_potentials'.") - def potentials(self) -> Q_[ComplexArray]: - """Deprecated alias to `initial_potentials`.""" - return self.initial_potentials - - @potentials.setter - @deprecated("'Bus.potentials' is deprecated. It has been renamed to 'initial_potentials'.") - def potentials(self, value: ComplexArrayLike1D) -> None: - self.initial_potentials = value - @property def nominal_voltage(self) -> Q_[float] | None: """The phase-to-phase nominal voltage of the bus (V) if it is set.""" @@ -148,13 +132,12 @@ def nominal_voltage(self, value: float | Q_[float] | None) -> None: value = None if value is None: if self._max_voltage_level is not None or self._min_voltage_level is not None: - warnings.warn( + warn_external( message=( f"The nominal voltage of the bus {self.id!r} is required to use `min_voltage_level` and " f"`max_voltage_level`." ), category=UserWarning, - stacklevel=find_stack_level(), ) else: if value <= 0: @@ -182,13 +165,12 @@ def min_voltage_level(self, value: float | Q_[float] | None) -> None: logger.error(msg) raise RoseauLoadFlowException(msg=msg, code=RoseauLoadFlowExceptionCode.BAD_VOLTAGES) if self._nominal_voltage is None: - warnings.warn( + warn_external( message=( f"The min voltage level of the bus {self.id!r} is useless without a nominal voltage. Please " f"define a nominal voltage for this bus." ), category=UserWarning, - stacklevel=find_stack_level(), ) self._min_voltage_level = value @@ -221,13 +203,12 @@ def max_voltage_level(self, value: float | Q_[float] | None) -> None: logger.error(msg) raise RoseauLoadFlowException(msg=msg, code=RoseauLoadFlowExceptionCode.BAD_VOLTAGES) if self._nominal_voltage is None: - warnings.warn( + warn_external( message=( f"The max voltage level of the bus {self.id!r} is useless without a nominal voltage. Please " f"define a nominal voltage for this bus." ), category=UserWarning, - stacklevel=find_stack_level(), ) self._max_voltage_level = value @@ -425,6 +406,30 @@ def _res_voltage_levels_pn_getter(self, warning: bool) -> FloatArray | None: voltages_abs = abs(self._res_voltages_pn_getter(warning=warning)) return SQRT3 * voltages_abs / self._nominal_voltage + def _res_state_getter(self) -> ResultState: + """The state of the bus based on its voltage levels and limits.""" + u_array = self._res_voltage_levels_getter(warning=False) + if u_array is None: + return "unknown" + u_min = self._min_voltage_level + u_max = self._max_voltage_level + if u_min is None and u_max is None: + return "unknown" + u = u_array.tolist() + u_low, u_high = min(u), max(u) + + if u_max is not None: + if u_high > u_max: + return "very-high" + elif u_high > 0.75 * u_max + 0.25: + return "high" + if u_min is not None: + if u_low < u_min: + return "very-low" + elif u_low < 0.75 * u_min + 0.25: + return "low" + return "normal" + @property def res_voltage_levels(self) -> Q_[FloatArray] | None: """The load flow result of the bus voltage levels (p.u.).""" diff --git a/roseau/load_flow/models/connectables.py b/roseau/load_flow/models/connectables.py index 709e34db..f763c460 100644 --- a/roseau/load_flow/models/connectables.py +++ b/roseau/load_flow/models/connectables.py @@ -1,5 +1,4 @@ import logging -import warnings from abc import ABC, abstractmethod from functools import cached_property from typing import ClassVar @@ -14,7 +13,7 @@ from roseau.load_flow.sym import phasor_to_sym from roseau.load_flow.typing import ComplexArray, Id, JsonDict, Side from roseau.load_flow.units import Q_, ureg_wraps -from roseau.load_flow.utils import SIDE_DESC, abstractattrs, ensure_startsupper, find_stack_level, one_or_more_repr +from roseau.load_flow.utils import SIDE_DESC, abstractattrs, ensure_startsupper, one_or_more_repr, warn_external from roseau.load_flow_engine.cy_engine import CyBranch logger = logging.getLogger(__name__) @@ -106,13 +105,12 @@ def _check_bus_phases( if connect_neutral is not None: connect_neutral = bool(connect_neutral) # to allow np.bool if connect_neutral and "n" not in phases: - warnings.warn( + warn_external( message=( f"{ensure_startsupper(f'{side_desc}neutral')} connection requested for " f"{self.element_type} {id!r} with no neutral phase." ), category=UserWarning, - stacklevel=find_stack_level(), ) connect_neutral = None # Also check they are in the bus phases @@ -121,7 +119,10 @@ def _check_bus_phases( missing_ok = phases_not_in_bus == {"n"} and len(phases) > 2 and not connect_neutral if phases_not_in_bus and not missing_ok: ph, be = one_or_more_repr(sorted(phases_not_in_bus), "phase") - msg = f"{ensure_startsupper(f'{side_desc}{ph}')} of {self.element_type} {id!r} {be} not in phases {bus.phases!r} of its bus {bus.id!r}." + msg = ( + f"{ensure_startsupper(f'{side_desc}{ph}')} of {self.element_type} {id!r} {be} not " + f"in phases {bus.phases!r} of its bus {bus.id!r}." + ) logger.error(msg) raise RoseauLoadFlowException(msg=msg, code=RoseauLoadFlowExceptionCode.BAD_PHASE) return connect_neutral @@ -248,27 +249,6 @@ def is_disconnected(self) -> bool: """Is this element disconnected from the network?""" return self._is_disconnected - @property - def bus(self) -> Bus | None: - """The bus of the element, or None if it is disconnected. - - .. deprecated:: 0.13.0 - - Accessing the bus of a disconnected element will change in the future to return the bus - it was connected to before disconnection instead of `None`. If you rely on this behavior - to check if the element is disconnected, please use the `is_disconnected` property instead. - """ - if self._is_disconnected: - warnings.warn( - f"Accessing the bus of the disconnected {self._element_info} will change in the " - f"future to return the bus it was connected to before disconnection instead of None. " - f"If you rely on this behavior to check if the element is disconnected, please use " - f"`is_disconnected` instead.", - stacklevel=find_stack_level(), - ) - return None - return self._bus - def disconnect(self) -> None: """Disconnect this element from the network. It cannot be used afterwards.""" for element in self._connected_elements: diff --git a/roseau/load_flow/models/flexible_parameters.py b/roseau/load_flow/models/flexible_parameters.py index 83c1ca4d..1ebd3af5 100644 --- a/roseau/load_flow/models/flexible_parameters.py +++ b/roseau/load_flow/models/flexible_parameters.py @@ -1,5 +1,4 @@ import logging -import warnings from collections.abc import Iterable from typing import TYPE_CHECKING, NoReturn, Self @@ -19,7 +18,7 @@ ProjectionType, ) from roseau.load_flow.units import Q_, ureg_wraps -from roseau.load_flow.utils import JsonMixin, find_stack_level, optional_deps +from roseau.load_flow.utils import JsonMixin, optional_deps, warn_external from roseau.load_flow_engine.cy_engine import CyControl, CyFlexibleParameter, CyProjection logger = logging.getLogger(__name__) @@ -132,13 +131,12 @@ def _check_values(self) -> None: if msg_list: msg = ", ".join(msg_list) - warnings.warn( + warn_external( message=( f"The following voltage parameters are not used by the {self.type!r} control " f"and should be set to 0 V: {msg}" ), category=UserWarning, - stacklevel=find_stack_level(), ) # Raise an error if the useful values are not well-ordered and positive diff --git a/roseau/load_flow/models/grounds.py b/roseau/load_flow/models/grounds.py index a3f3d58f..bdaee8aa 100644 --- a/roseau/load_flow/models/grounds.py +++ b/roseau/load_flow/models/grounds.py @@ -1,5 +1,4 @@ import logging -import warnings from typing import TYPE_CHECKING, Final, Literal, Self import numpy as np @@ -10,11 +9,10 @@ from roseau.load_flow.models.terminals import AbstractTerminal from roseau.load_flow.typing import Complex, Id, JsonDict, Side from roseau.load_flow.units import Q_, ureg_wraps -from roseau.load_flow.utils import find_stack_level, one_or_more_repr +from roseau.load_flow.utils import one_or_more_repr, warn_external from roseau.load_flow_engine.cy_engine import CyBranch, CyGround, CySimplifiedLine, CySwitch if TYPE_CHECKING: - from roseau.load_flow.models.branches import AbstractBranch from roseau.load_flow.models.buses import Bus logger = logging.getLogger(__name__) @@ -58,16 +56,6 @@ def connections(self) -> list["GroundConnection"]: """The connections to the ground.""" return self._connections[:] - @property - @deprecated("`Ground.connected_buses` is deprecated, use `Ground.connections` instead.") - def connected_buses(self) -> dict[Id, str]: - """The bus ID and phase of the buses connected to this ground. - - .. deprecated:: 0.12.0 - Use the more flexible :attr:`Ground.connections` attribute instead. - """ - return {gc.element.id: gc.phase for gc in self._connections if gc.element.element_type == "bus"} - @deprecated("`Ground.connect` is deprecated, use the `GroundConnection` class instead.") def connect(self, bus: "Bus", phase: str = "n") -> None: """Connect the ground to a bus on the given phase. @@ -144,10 +132,9 @@ def __init__( id: Id | None = None, *, ground: Ground, - element: "AbstractTerminal | AbstractBranch", + element: AbstractTerminal, impedance: Complex | Q_[Complex] = 0j, phase: str = "n", - side: Side | None = None, on_connected: Literal["raise", "warn", "ignore"] = "raise", ) -> None: """Ground connection constructor. @@ -162,7 +149,7 @@ def __init__( element: The terminal element to connect to the ground. This can be a bus, source, load, or a - branch side. Passing a branch element is deprecated. + branch side. impedance: The impedance of the connection to the ground (ohm). Defaults to 0. @@ -171,16 +158,6 @@ def __init__( The phase of the connection. It must be one of ``{"a", "b", "c", "n"}``. Defaults to ``"n"``. - side: - The side of the branch element to connect to. If the element is a transformer, this - must be either ``'HV'`` or ``'LV'``. If the element is a line or a switch, this must - be either ``1`` or ``2``. For other elements, this must be ``None``. - - .. deprecated:: 0.13.0 - - Using the `side` argument with branch elements is deprecated. Use - `element.side1` or `element.side2` directly instead. - on_connected: The action to take if *other phases* of the element are already connected to this ground. If ``"raise"`` (default), raise an error. If ``"warn"``, issue a warning. If @@ -192,35 +169,14 @@ def __init__( self._check_compatible_phase_tech(element, id=id) element_to_connect = element - # Check the element type and the side. - if isinstance(element, AbstractTerminal): - if side is not None: - msg = f"Side cannot be used with {element.element_type} elements, only with branches." - logger.error(msg) - raise RoseauLoadFlowException(msg, RoseauLoadFlowExceptionCode.BAD_BRANCH_SIDE) - if element.element_type in {"transformer", "line", "switch"}: - element_to_connect = element._branch # type: ignore - elif element.element_type in {"transformer", "line", "switch"}: - if side not in (1, 2, "HV", "LV"): - side_status = "Side is missing" if side is None else f"Invalid side {side!r}" - expected_sides = ("HV", "LV") if element.element_type == "transformer" else (1, 2) - msg = f"{side_status} for {element._element_info}, expected one of {expected_sides}." - logger.error(msg) - raise RoseauLoadFlowException(msg, RoseauLoadFlowExceptionCode.BAD_BRANCH_SIDE) - element = element.side1 if side in (1, "HV") else element.side2 - warnings.warn( - ( - f"Connecting a {element_to_connect.element_type} to a ground using the side " - f"argument is deprecated. Use {element_to_connect.element_type}.side" - f"{element._side_suffix} directly instead." - ), - category=DeprecationWarning, - stacklevel=find_stack_level(), - ) - else: + if not isinstance(element, AbstractTerminal): msg = f"Cannot connect {element._element_info} to the ground." + if element.element_type in {"transformer", "line", "switch"}: + msg += " Did you mean to connect one of its sides?" logger.error(msg) raise RoseauLoadFlowException(msg, RoseauLoadFlowExceptionCode.BAD_ELEMENT_OBJECT) + if element.element_type in {"transformer", "line", "switch"}: + element_to_connect = element._branch # type: ignore if id is None: id = f"{element.element_type} {element.id!r} {element._side_desc}phase {phase!r} to ground {ground.id!r}" @@ -257,7 +213,7 @@ def __init__( logger.error(msg) raise RoseauLoadFlowException(msg=msg, code=RoseauLoadFlowExceptionCode.BAD_GROUND_ID) else: - warnings.warn(msg, stacklevel=find_stack_level()) + warn_external(msg) self._connect(ground, element_to_connect) self._ground = ground diff --git a/roseau/load_flow/models/line_parameters.py b/roseau/load_flow/models/line_parameters.py index f8d26b8a..2f2b811e 100644 --- a/roseau/load_flow/models/line_parameters.py +++ b/roseau/load_flow/models/line_parameters.py @@ -5,7 +5,7 @@ from enum import StrEnum from importlib import resources from pathlib import Path -from typing import Final, Literal, NoReturn, Self, TypeAlias, TypeVar +from typing import Any, Final, Literal, NoReturn, Self import numpy as np import numpy.linalg as nplin @@ -13,6 +13,7 @@ from numpy.typing import NDArray from roseau.load_flow.constants import EPSILON_0, EPSILON_R, MU_0, OMEGA, PI, RHO, SQRT3, TAN_D, F +from roseau.load_flow.converters import kron_reduction from roseau.load_flow.exceptions import RoseauLoadFlowException, RoseauLoadFlowExceptionCode from roseau.load_flow.sym import A_INV, A from roseau.load_flow.types import Insulator, LineType, Material @@ -26,7 +27,7 @@ JsonDict, ) from roseau.load_flow.units import Q_, ureg_wraps -from roseau.load_flow.utils import CatalogueMixin, Identifiable, JsonMixin, find_stack_level +from roseau.load_flow.utils import CatalogueMixin, Identifiable, JsonMixin, warn_external logger = logging.getLogger(__name__) @@ -42,9 +43,8 @@ LineType.UNDERGROUND: Insulator.PVC, } -MaterialArray: TypeAlias = NDArray[np.object_] -InsulatorArray: TypeAlias = NDArray[np.object_] -_StrEnumType = TypeVar("_StrEnumType", bound=StrEnum) +type MaterialArray = NDArray[np.object_] +type InsulatorArray = NDArray[np.object_] class LineParameters(Identifiable, JsonMixin, CatalogueMixin[pd.DataFrame]): @@ -366,11 +366,10 @@ def _sym_to_zy( ypn = bpn * 1j # Phase-to-neutral shunt admittance (Siemens/km) if np.isclose(zpn, 0) and np.isclose(zn, 0): - warnings.warn( + warn_external( f"The line model {id!r} does not have neutral elements. It will be modelled as a 3 wires line " f"instead.", category=UserWarning, - stacklevel=find_stack_level(), ) else: z_line = np.pad(z_line, (0, 1), mode="constant", constant_values=zpn) @@ -404,7 +403,7 @@ def _sym_to_zy( return z_line, y_shunt def _zy_to_sym( - self, operation: str, exc_code: RoseauLoadFlowExceptionCode + self, operation: str, exc_code: RoseauLoadFlowExceptionCode, kron: bool ) -> tuple[tuple[complex, complex], tuple[complex, complex]]: """Convert the Z and Y matrices to a symmetrical model. @@ -418,29 +417,42 @@ def _zy_to_sym( ) logger.error(msg) raise RoseauLoadFlowException(msg=msg, code=exc_code) - - z_012 = A_INV @ self._z_line[:3, :3] @ A - y_012 = A_INV @ self._y_shunt[:3, :3] @ A - z0 = z_012.item(0, 0) - y0 = y_012.item(0, 0) - z1 = z_012.item(1, 1) - y1 = y_012.item(1, 1) + if n_phases != 4: + kron = False + z_line = kron_reduction(self._z_line) if kron else self._z_line[:3, :3] + z_012 = A_INV @ z_line @ A + z0, z1, _ = z_012.diagonal().tolist() + if self.with_shunt: + y_shunt = self._y_shunt[:3, :3] + y_012 = A_INV @ y_shunt @ A + y0, y1, _ = y_012.diagonal().tolist() + else: + y0 = y1 = 0.0j return (z0, y0), (z1, y1) - def to_sym(self) -> dict[str, complex]: + def to_sym(self, *, eliminate_neutral: bool = False) -> dict[str, complex]: """Return the symmetrical components of a three-phase line parameters. An error is raised if the line parameters are not three-phase. + Args: + eliminate_neutral: + If True, perform Kron's reduction to eliminate the neutral conductor before computing + the symmetrical components. This option is only relevant for 4-wire lines. By + default, the neutral is kept and its parameters are returned. + Returns: The symmetrical components of the line impedance and shunt admittance. These are - ``z0, y0, z1, y1`` and optionally ``zn, zpn, bn, bpn`` if the line has a neutral. + ``z0, y0, z1, y1`` and optionally ``zn, zpn, bn, bpn`` if the line has a neutral and + ``eliminate_neutral`` is False. """ (z0, y0), (z1, y1) = self._zy_to_sym( - operation="compute symmetrical components from", exc_code=RoseauLoadFlowExceptionCode.BAD_LINE_MODEL + operation="compute symmetrical components from", + exc_code=RoseauLoadFlowExceptionCode.BAD_LINE_MODEL, + kron=eliminate_neutral, ) result = {"z0": z0, "z1": z1, "y0": y0, "y1": y1} - if self._z_line.shape[0] == 4: + if not eliminate_neutral and self._z_line.shape[0] == 4: result["zn"] = self._z_line.item(3, 3) result["yn"] = self._y_shunt.item(3, 3) pn_indices = (0, 1, 2, 3, 3, 3), (3, 3, 3, 0, 1, 2) # phase-neutral components indices @@ -825,10 +837,9 @@ def from_coiffier_model(cls, name: str, nb_phases: int = 3, id: Id | None = None raise RoseauLoadFlowException(msg=msg, code=RoseauLoadFlowExceptionCode.BAD_TYPE_NAME_SYNTAX) from None if insulator is not None: # TODO: add insulator support - warnings.warn( + warn_external( f"The insulator is currently ignored in the Coiffier model, got '{insulator.upper()}'.", category=UserWarning, - stacklevel=find_stack_level(), ) r = RHO[material] / section if line_type == LineType.OVERHEAD: @@ -897,6 +908,75 @@ def from_coiffier_model(cls, name: str, nb_phases: int = 3, id: Id | None = None # # Constructors from other software # + @classmethod + def _parse_power_factory_params( + cls, + id, + inom: float | Q_[float] | None, + cohl: Literal[0, "Cable", 1, "OHL"], + conductor: Literal["Al", "Cu", "Ad", "As", "Ds"] | None, + insulation: Literal[0, "PVC", 1, "XLPE", 2, "Mineral", 3, "Paper", 4, "EPR"] | None, + section: float | Q_[float] | None, + ) -> dict[str, Any]: + cohl_norm = str(cohl).upper() + if cohl_norm == "CABLE" or cohl_norm == "0": + line_type = LineType.UNDERGROUND + elif cohl_norm == "OHL" or cohl_norm == "1": + line_type = LineType.OVERHEAD + else: + msg = f"Expected cohl='Cable' or 'OHL', got {cohl!r} for line parameters {id!r}." + logger.error(msg) + raise RoseauLoadFlowException(msg=msg, code=RoseauLoadFlowExceptionCode.BAD_LINE_TYPE) + + mlei_norm = conductor.upper() if conductor is not None else None + if mlei_norm is None: + material = None + elif mlei_norm in ("AL", "ALUMINIUM", "ALUMINUM"): + material = Material.AL + elif mlei_norm in ("CU", "COPPER"): + material = Material.CU + elif mlei_norm in ("AD", "ALDREY"): + material = Material.AM + elif mlei_norm in ("AS", "ALUMINIUM-STEEL", "ALUMINUM-STEEL"): + material = Material.AA + elif mlei_norm in ("DS", "ALDREY-STEEL"): + material = Material.LA + else: + msg = f"Expected conductor='Al', 'Cu', 'Ad', 'As' or 'Ds', got {conductor!r} for line parameters {id!r}." + logger.error(msg) + raise RoseauLoadFlowException(msg=msg, code=RoseauLoadFlowExceptionCode.BAD_MATERIAL) + + imiso_norm = str(insulation).upper() if insulation is not None else None + if imiso_norm is None: + insulator = None + elif imiso_norm == "PVC" or imiso_norm == "0": + insulator = Insulator.PVC + elif imiso_norm == "XLPE" or imiso_norm == "1": + insulator = Insulator.XLPE + elif imiso_norm == "MINERAL" or imiso_norm == "2": + insulator = Insulator.NONE # not supported yet + elif imiso_norm == "PAPER" or imiso_norm == "3": + insulator = Insulator.IP + elif imiso_norm == "EPR" or imiso_norm == "4": + insulator = Insulator.EPR + else: + msg = ( + f"Expected insulation='PVC', 'XLPE', 'MINERAL', 'PAPER' or 'EPR', got {insulation!r} " + f"for line parameters {id!r}." + ) + logger.error(msg) + raise RoseauLoadFlowException(msg=msg, code=RoseauLoadFlowExceptionCode.BAD_INSULATOR) + + ampacity = inom * 1e3 if inom is not None else None + + return { + "line_type": line_type, + "material": material, + "insulator": insulator, + "section": section, + "ampacity": ampacity, + } + @classmethod @ureg_wraps( None, @@ -924,7 +1004,7 @@ def from_coiffier_model(cls, name: str, nb_phases: int = 3, id: Id | None = None "mm²", ), ) - def from_power_factory( # noqa: C901 + def from_power_factory( cls, id: Id, *, @@ -1037,56 +1117,9 @@ def from_power_factory( # noqa: C901 logger.error(msg) raise RoseauLoadFlowException(msg=msg, code=RoseauLoadFlowExceptionCode.BAD_PHASE) - cohl_norm = str(cohl).upper() - if cohl_norm == "CABLE" or cohl_norm == "0": - line_type = LineType.UNDERGROUND - elif cohl_norm == "OHL" or cohl_norm == "1": - line_type = LineType.OVERHEAD - else: - msg = f"Expected cohl='Cable' or 'OHL', got {cohl!r} for line parameters {id!r}." - logger.error(msg) - raise RoseauLoadFlowException(msg=msg, code=RoseauLoadFlowExceptionCode.BAD_LINE_TYPE) - - mlei_norm = conductor.upper() if conductor is not None else None - if mlei_norm is None: - material = None - elif mlei_norm in ("AL", "ALUMINIUM", "ALUMINUM"): - material = Material.AL - elif mlei_norm in ("CU", "COPPER"): - material = Material.CU - elif mlei_norm in ("AD", "ALDREY"): - material = Material.AM - elif mlei_norm in ("AS", "ALUMINIUM-STEEL", "ALUMINUM-STEEL"): - material = Material.AA - elif mlei_norm in ("DS", "ALDREY-STEEL"): - material = Material.LA - else: - msg = f"Expected conductor='Al', 'Cu', 'Ad', 'As' or 'Ds', got {conductor!r} for line parameters {id!r}." - logger.error(msg) - raise RoseauLoadFlowException(msg=msg, code=RoseauLoadFlowExceptionCode.BAD_MATERIAL) - - imiso_norm = str(insulation).upper() if insulation is not None else None - if imiso_norm is None: - insulator = None - elif imiso_norm == "PVC" or imiso_norm == "0": - insulator = Insulator.PVC - elif imiso_norm == "XLPE" or imiso_norm == "1": - insulator = Insulator.XLPE - elif imiso_norm == "MINERAL" or imiso_norm == "2": - insulator = Insulator.NONE # not supported yet - elif imiso_norm == "PAPER" or imiso_norm == "3": - insulator = Insulator.IP - elif imiso_norm == "EPR" or imiso_norm == "4": - insulator = Insulator.EPR - else: - msg = ( - f"Expected insulation='PVC', 'XLPE', 'MINERAL', 'PAPER' or 'EPR', got {insulation!r} " - f"for line parameters {id!r}." - ) - logger.error(msg) - raise RoseauLoadFlowException(msg=msg, code=RoseauLoadFlowExceptionCode.BAD_INSULATOR) - - ampacities = inom * 1e3 if inom is not None else None + params = cls._parse_power_factory_params( + id=id, inom=inom, cohl=cohl, conductor=conductor, insulation=insulation, section=section + ) z_line, y_shunt = cls._sym_to_zy_simple( n=nphase, z0=r0 + 1j * x0, z1=r1 + 1j * x1, y0=1j * b0 * 1e-6, y1=1j * b1 * 1e-6 @@ -1108,14 +1141,41 @@ def from_power_factory( # noqa: C901 id=id, z_line=z_line, y_shunt=y_shunt, - ampacities=ampacities, - line_type=line_type, - materials=material, - insulators=insulator, - sections=section, + ampacities=params["ampacity"], + line_type=params["line_type"], + materials=params["material"], + insulators=params["insulator"], + sections=params["section"], ) return obj + @classmethod + def _parse_open_dss_params( + cls, + id: Id, + normamps: FloatScalarOrArrayLike1D | None = None, + linetype: str | None = None, + ) -> dict[str, Any]: + # Convert OpenDSS line type to RLF line type + if linetype is None: + line_type = None + else: + line_type_upper = linetype.upper() + if line_type_upper == "OH": + line_type = LineType.OVERHEAD + elif line_type_upper == "UG": + line_type = LineType.UNDERGROUND + else: + # TODO other line types + # ['OH', 'UG', 'UG_TS', 'UG_CN', 'SWT_LDBRK', 'SWT_FUSE', 'SWT_SECT', + # 'SWT_REC', 'SWT_DISC', 'SWT_BRK', 'SWT_ELBOW', 'BUSBAR'] + logger.warning(f"Line type {linetype} from OpenDSS is not supported, it is ignored.") + line_type = None + return { + "line_type": line_type, + "ampacities": normamps, + } + @classmethod @ureg_wraps(None, (None, None, None, "ohm/km", "ohm/km", "ohm/km", "ohm/km", "nF/km", "nF/km", "Hz", "A", None)) def from_open_dss( @@ -1226,26 +1286,12 @@ def from_open_dss( z, yc = cls._sym_to_zy_simple(n=n_cond, z0=z0, y0=yc0, z1=z1, y1=yc1) cls._check_z_line_matrix(id=id, z_line=z) - # Convert OpenDSS line type to RLF line type - if linetype is None: - line_type = None - else: - line_type_upper = linetype.upper() - if line_type_upper == "OH": - line_type = LineType.OVERHEAD - elif line_type_upper == "UG": - line_type = LineType.UNDERGROUND - else: - # TODO other line types - # ['OH', 'UG', 'UG_TS', 'UG_CN', 'SWT_LDBRK', 'SWT_FUSE', 'SWT_SECT', - # 'SWT_REC', 'SWT_DISC', 'SWT_BRK', 'SWT_ELBOW', 'BUSBAR'] - logger.warning(f"Line type {linetype} from OpenDSS is not supported, it is ignored.") - line_type = None + params = cls._parse_open_dss_params(id=id, normamps=normamps, linetype=linetype) # Create the RLF line parameters with off-diagonal resistance allowed with warnings.catch_warnings(): warnings.filterwarnings(action="ignore", message=r".* off-diagonal elements ", category=UserWarning) - obj = cls(id=id, z_line=z, y_shunt=yc, ampacities=normamps, line_type=line_type) + obj = cls(id=id, z_line=z, y_shunt=yc, ampacities=params["ampacities"], line_type=params["line_type"]) return obj # @@ -1367,7 +1413,7 @@ def from_catalogue( section: float | Q_[float] | None = None, section_neutral: float | Q_[float] | None = None, id: Id | None = None, - nb_phases: int = 3, + nb_phases: int | None = None, ) -> Self: """Create line parameters from a catalogue. @@ -1408,13 +1454,14 @@ def from_catalogue( that this parameter is not used in the data filtering. nb_phases: - The number of phases of the line between 1 and 4, defaults to 3. It represents the - size of the ``z_line`` and ``y_shunt`` matrices. + The number of phases of the line between 1 and 4. It represents the size of the + ``z_line`` and ``y_shunt`` matrices. Default is 4 for LV lines (name in the form + ``"3x...+..."``) and 3 otherwise. Returns: The created line parameters. """ - if nb_phases not in {1, 2, 3, 4}: + if nb_phases not in {None, 1, 2, 3, 4}: msg = f"Expected nb_phases to be one of (1, 2, 3, 4), got {nb_phases!r} instead." logger.error(msg) raise RoseauLoadFlowException(msg=msg, code=RoseauLoadFlowExceptionCode.BAD_PHASE) @@ -1459,6 +1506,8 @@ def from_catalogue( ampacity_neutral = catalogue_data.at[idx, "ampacity_neutral"] if pd.isna(ampacity_neutral): ampacity_neutral = None + if nb_phases is None: + nb_phases = 4 if "3x" in name and "+" in name else 3 nb_phases_m1 = nb_phases - 1 z_line = (r + x * 1j) * np.eye(nb_phases, dtype=np.complex128) z_line[nb_phases_m1, nb_phases_m1] = rn + 1j * xn @@ -1644,11 +1693,10 @@ def _check_matrix(self) -> None: # Check that the off-diagonal element have a zero real part off_diagonal_elements = matrix[~np.eye(*matrix.shape, dtype=np.bool_)] if not np.allclose(off_diagonal_elements.real, 0): - warnings.warn( + warn_external( f"The {matrix_name} matrix of line type {self.id!r} has off-diagonal elements " f"with a non-zero real part.", category=UserWarning, - stacklevel=find_stack_level(), ) # Check that the real coefficients are non-negative diff --git a/roseau/load_flow/models/lines.py b/roseau/load_flow/models/lines.py index 77fb543c..a7af8427 100644 --- a/roseau/load_flow/models/lines.py +++ b/roseau/load_flow/models/lines.py @@ -1,5 +1,4 @@ import logging -import warnings from typing import Final, Self import numpy as np @@ -10,8 +9,9 @@ from roseau.load_flow.models.buses import Bus from roseau.load_flow.models.grounds import Ground from roseau.load_flow.models.line_parameters import LineParameters -from roseau.load_flow.typing import BoolArray, ComplexArray, ComplexMatrix, FloatArray, Id, JsonDict +from roseau.load_flow.typing import BoolArray, ComplexArray, ComplexMatrix, FloatArray, Id, JsonDict, ResultState from roseau.load_flow.units import Q_, ureg_wraps +from roseau.load_flow.utils import warn_external from roseau.load_flow_engine.cy_engine import CyShuntLine, CySimplifiedLine logger = logging.getLogger(__name__) @@ -95,13 +95,12 @@ def __init__( # Handle the ground if self.ground is not None and not self.with_shunt: - warnings.warn( + warn_external( message=( f"The ground element must not be provided for line {self.id!r} as it does not have a shunt " f"admittance." ), category=UserWarning, - stacklevel=2, ) self.ground = None elif self.with_shunt: @@ -303,6 +302,20 @@ def _res_loading_getter(self, warning: bool) -> FloatArray | None: currents2 = self._side2._res_currents_getter(warning=False) # warn only once return np.maximum(abs(currents1), abs(currents2)) / amp + def _res_state_getter(self) -> ResultState: + """Get the state of the line based on its loading.""" + loading_array = self._res_loading_getter(warning=False) + if loading_array is None: + return "unknown" + max_loading = self._max_loading + loading = max(loading_array.tolist()) + if loading > max_loading: + return "very-high" + elif loading > 0.75 * max_loading: + return "high" + else: + return "normal" + @property @ureg_wraps("V", (None,)) def res_ground_potential(self) -> Q_[complex]: diff --git a/roseau/load_flow/models/potential_refs.py b/roseau/load_flow/models/potential_refs.py index 41493c16..7ceedf40 100644 --- a/roseau/load_flow/models/potential_refs.py +++ b/roseau/load_flow/models/potential_refs.py @@ -7,7 +7,7 @@ from roseau.load_flow.models.grounds import Ground from roseau.load_flow.typing import Id, JsonDict from roseau.load_flow.units import Q_, ureg_wraps -from roseau.load_flow.utils import deprecate_renamed_parameter, one_or_more_repr +from roseau.load_flow.utils import one_or_more_repr from roseau.load_flow_engine.cy_engine import CyDeltaPotentialRef, CyPotentialRef logger = logging.getLogger(__name__) @@ -28,7 +28,6 @@ class PotentialRef(Element[CyPotentialRef | CyDeltaPotentialRef]): element_type: Final = "potential ref" allowed_phases: Final = frozenset({"a", "b", "c", "n"} | Bus.allowed_phases) - @deprecate_renamed_parameter(old_name="phase", new_name="phases", version="0.10.0", category=DeprecationWarning) def __init__(self, id: Id, element: Bus | Ground, *, phases: str | None = None) -> None: """PotentialRef constructor. diff --git a/roseau/load_flow/models/tests/test_buses.py b/roseau/load_flow/models/tests/test_buses.py index 2204143d..95070aac 100644 --- a/roseau/load_flow/models/tests/test_buses.py +++ b/roseau/load_flow/models/tests/test_buses.py @@ -1,3 +1,5 @@ +import warnings + import numpy as np import pandas as pd import pytest @@ -100,7 +102,7 @@ def test_short_circuit(): assert "ground" in en.grounds -def test_voltage_limits(recwarn): +def test_voltage_limits(): # Default values bus = Bus(id="bus", phases="abc") assert bus.nominal_voltage is None @@ -125,9 +127,9 @@ def test_voltage_limits(recwarn): assert bus.max_voltage == Q_(434.6, "V") # Can be reset to None - bus.nominal_voltage = None bus.min_voltage_level = None bus.max_voltage_level = None + bus.nominal_voltage = None assert bus.min_voltage_level is None assert bus.max_voltage_level is None assert bus.min_voltage is None @@ -145,9 +147,9 @@ def test_voltage_limits(recwarn): # NaNs are converted to None for na in (np.nan, float("nan"), pd.NA): - bus.nominal_voltage = na bus.min_voltage_level = na bus.max_voltage_level = na + bus.nominal_voltage = na assert bus.nominal_voltage is None assert bus.min_voltage_level is None assert bus.max_voltage_level is None @@ -158,43 +160,42 @@ def test_voltage_limits(recwarn): bus.nominal_voltage = None bus.min_voltage_level = None bus.max_voltage_level = None - recwarn.clear() - bus.min_voltage_level = 0.95 - assert len(recwarn) == 1 - assert ( - recwarn[0].message.args[0] - == "The min voltage level of the bus 'bus' is useless without a nominal voltage. Please define a nominal " - "voltage for this bus." - ) + with pytest.warns( + UserWarning, + match=( + "The min voltage level of the bus 'bus' is useless without a nominal voltage. Please " + "define a nominal voltage for this bus." + ), + ): + bus.min_voltage_level = 0.95 assert bus.min_voltage_level == Q_(0.95, "") assert bus.min_voltage is None - recwarn.clear() - bus.max_voltage_level = 1.05 - assert len(recwarn) == 1 - assert ( - recwarn[0].message.args[0] - == "The max voltage level of the bus 'bus' is useless without a nominal voltage. Please define a nominal " - "voltage for this bus." - ) + with pytest.warns( + UserWarning, + match=( + "The max voltage level of the bus 'bus' is useless without a nominal voltage. Please " + "define a nominal voltage for this bus." + ), + ): + bus.max_voltage_level = 1.05 assert bus.max_voltage_level == Q_(1.05, "") assert bus.max_voltage is None # Erasing a nominal voltage with a min or max voltage level emits a warning bus.nominal_voltage = Q_(400, "V") - recwarn.clear() - bus.nominal_voltage = None - assert len(recwarn) == 1 - assert ( - recwarn[0].message.args[0] - == "The nominal voltage of the bus 'bus' is required to use `min_voltage_level` and `max_voltage_level`." - ) + with pytest.warns( + UserWarning, + match="The nominal voltage of the bus 'bus' is required to use `min_voltage_level` and `max_voltage_level`.", + ): + bus.nominal_voltage = None + bus.nominal_voltage = Q_(400, "V") bus.min_voltage_level = None bus.max_voltage_level = None - recwarn.clear() - bus.nominal_voltage = None - assert len(recwarn) == 0 + with warnings.catch_warnings(action="error"): + bus.nominal_voltage = None + bus.nominal_voltage = Q_(400, "V") # Bad values bus.min_voltage_level = 0.95 with pytest.raises(RoseauLoadFlowException) as e: @@ -287,6 +288,51 @@ def test_res_violated(): assert (bus.res_violated == [True, False, True]).all() +def test_res_state(): + bus = Bus(id="bus", phases="abc") + bus._res_potentials = 230 * PositiveSequence + + # No nominal voltage + assert bus._res_state_getter() == "unknown" + + # No limits + bus.nominal_voltage = 230 * np.sqrt(3) + assert bus._res_state_getter() == "unknown" + + # Only max voltage + bus.max_voltage_level = 1.05 + bus._res_potentials = 230 * 1.06 * PositiveSequence + assert bus._res_state_getter() == "very-high" + bus._res_potentials = 230 * 1.04 * PositiveSequence + assert bus._res_state_getter() == "high" + bus._res_potentials = 230 * 1.02 * PositiveSequence + assert bus._res_state_getter() == "normal" + + # Only min voltage + bus.max_voltage_level = None + bus.min_voltage_level = 0.95 + bus._res_potentials = 230 * 0.94 * PositiveSequence + assert bus._res_state_getter() == "very-low" + bus._res_potentials = 230 * 0.96 * PositiveSequence + assert bus._res_state_getter() == "low" + bus._res_potentials = 230 * 0.98 * PositiveSequence + assert bus._res_state_getter() == "normal" + + # Both min and max voltage + bus.min_voltage_level = 0.95 + bus.max_voltage_level = 1.05 + bus._res_potentials = 230 * 1.06 * PositiveSequence + assert bus._res_state_getter() == "very-high" + bus._res_potentials = 230 * 1.04 * PositiveSequence + assert bus._res_state_getter() == "high" + bus._res_potentials = 230 * 1.0 * PositiveSequence + assert bus._res_state_getter() == "normal" + bus._res_potentials = 230 * 0.96 * PositiveSequence + assert bus._res_state_getter() == "low" + bus._res_potentials = 230 * 0.94 * PositiveSequence + assert bus._res_state_getter() == "very-low" + + def test_propagate_limits(): # noqa: C901 b1_mv = Bus(id="b1_mv", phases="abc") b2_mv = Bus(id="b2_mv", phases="abc") @@ -594,28 +640,3 @@ def test_to_from_dict_roundtrip(): bus2 = Bus.from_dict(bus_dict) bus2_dict = bus2.to_dict(include_results=False) assert_json_close(bus_dict, bus2_dict) - - -def test_deprecated_potentials(): - # Constructor - with pytest.warns( - DeprecationWarning, - match=r"Argument 'potentials' for Bus\(\) is deprecated. It has been renamed to 'initial_potentials'", - ): - bus = Bus(id="bus", phases="an", potentials=[230, 0]) # type: ignore - np.testing.assert_allclose(bus.initial_potentials.m, [230, 0]) - - # Property getter - with pytest.warns( - DeprecationWarning, - match=r"'Bus.potentials' is deprecated. It has been renamed to 'initial_potentials'", - ): - _ = bus.potentials - - # Property setter - with pytest.warns( - DeprecationWarning, - match=r"'Bus.potentials' is deprecated. It has been renamed to 'initial_potentials'", - ): - bus.potentials = [220, 0] - np.testing.assert_allclose(bus.initial_potentials.m, [220, 0]) diff --git a/roseau/load_flow/models/tests/test_grounds.py b/roseau/load_flow/models/tests/test_grounds.py index 7f6d5959..f5da81af 100644 --- a/roseau/load_flow/models/tests/test_grounds.py +++ b/roseau/load_flow/models/tests/test_grounds.py @@ -70,12 +70,6 @@ def test_ground_connections(): gc5 = GroundConnection(ground=ground2, element=bus3, phase="c") assert gc5 in ground2.connections - # Cannot use side terminal elements - with pytest.raises(RoseauLoadFlowException) as e: - GroundConnection(ground=ground1, element=bus1, side="HV") - assert e.value.code == RoseauLoadFlowExceptionCode.BAD_BRANCH_SIDE - assert e.value.msg == "Side cannot be used with bus elements, only with branches." - # Loads and sources load = PowerLoad("load", bus=bus2, phases="abcn", powers=3e3, connect_neutral=False) source = VoltageSource("source", bus=bus2, phases="abcn", voltages=230) @@ -88,13 +82,9 @@ def test_ground_connections(): tp = TransformerParameters("tp", vg="Yzn11", uhv=20e3, ulv=400, sn=160e3, z2=0.01, ym=0.01j) tr = Transformer("tr", bus_hv=bus1, bus_lv=bus2, parameters=tp) with pytest.raises(RoseauLoadFlowException) as e: - GroundConnection(ground=ground1, element=tr) - assert e.value.code == RoseauLoadFlowExceptionCode.BAD_BRANCH_SIDE - assert e.value.msg == "Side is missing for transformer 'tr', expected one of ('HV', 'LV')." - with pytest.raises(RoseauLoadFlowException) as e: - GroundConnection(ground=ground1, element=tr, side="BT") # type: ignore - assert e.value.code == RoseauLoadFlowExceptionCode.BAD_BRANCH_SIDE - assert e.value.msg == "Invalid side 'BT' for transformer 'tr', expected one of ('HV', 'LV')." + GroundConnection(ground=ground1, element=tr) # type: ignore + assert e.value.code == RoseauLoadFlowExceptionCode.BAD_ELEMENT_OBJECT + assert e.value.msg == "Cannot connect transformer 'tr' to the ground. Did you mean to connect one of its sides?" gc8 = GroundConnection(ground=ground1, element=tr.side_lv, phase="n") assert gc8 in ground1.connections assert gc8.id == "transformer 'tr' LV side phase 'n' to ground 'ground1'" @@ -110,13 +100,13 @@ def test_ground_connections(): ln = Line("ln", bus1=bus1, bus2=bus2, parameters=lp, phases="an", length=1) sw = Switch("sw", bus1=bus2, bus2=bus3, phases="bc") with pytest.raises(RoseauLoadFlowException) as e: - GroundConnection(ground=ground1, element=ln) - assert e.value.code == RoseauLoadFlowExceptionCode.BAD_BRANCH_SIDE - assert e.value.msg == "Side is missing for line 'ln', expected one of (1, 2)." + GroundConnection(ground=ground1, element=ln) # type: ignore + assert e.value.code == RoseauLoadFlowExceptionCode.BAD_ELEMENT_OBJECT + assert e.value.msg == "Cannot connect line 'ln' to the ground. Did you mean to connect one of its sides?" with pytest.raises(RoseauLoadFlowException) as e: - GroundConnection(ground=ground1, element=sw) - assert e.value.code == RoseauLoadFlowExceptionCode.BAD_BRANCH_SIDE - assert e.value.msg == "Side is missing for switch 'sw', expected one of (1, 2)." + GroundConnection(ground=ground1, element=sw) # type: ignore + assert e.value.code == RoseauLoadFlowExceptionCode.BAD_ELEMENT_OBJECT + assert e.value.msg == "Cannot connect switch 'sw' to the ground. Did you mean to connect one of its sides?" with pytest.raises(RoseauLoadFlowException) as e: GroundConnection(ground=ground1, element=sw.side1) assert e.value.code == RoseauLoadFlowExceptionCode.BAD_PHASE @@ -194,7 +184,6 @@ def test_ground_connections_to_from_dict_roundtrip(): def test_ground_deprecations(): ground = Ground("ground") bus = Bus("bus", phases="abcn") - load = PowerLoad("load", bus=bus, phases="abcn", powers=3e3, connect_neutral=False) with pytest.warns( DeprecationWarning, match=r"`Ground.connect` is deprecated, use the `GroundConnection` class instead." @@ -204,51 +193,3 @@ def test_ground_deprecations(): assert ground.connections[0].element is bus assert ground.connections[0].phase == "a" assert ground.connections[0].side is None - - GroundConnection(ground=ground, element=load, phase="n") - with pytest.warns( - DeprecationWarning, match=r"`Ground.connected_buses` is deprecated, use `Ground.connections` instead." - ): - connected_buses = ground.connected_buses - assert connected_buses == {"bus": "a"} - - # Deprecated side argument for branches - ground1 = Ground("ground1") - bus1 = Bus("bus1", phases="abcn") - bus2 = Bus("bus2", phases="abcn") - bus3 = Bus("bus3", phases="abc") - tp = TransformerParameters("tp", vg="Yzn11", uhv=20e3, ulv=400, sn=160e3, z2=0.01, ym=0.01j) - tr = Transformer("tr", bus_hv=bus1, bus_lv=bus2, parameters=tp) - lp = LineParameters("lp", z_line=[[0.1, 0], [0, 0.1]]) - ln = Line("ln", bus1=bus1, bus2=bus2, parameters=lp, phases="an", length=1) - sw = Switch("sw", bus1=bus2, bus2=bus3, phases="bc") - with pytest.warns( - DeprecationWarning, - match=( - r"Connecting a transformer to a ground using the side argument is deprecated. Use " - r"transformer.side_lv directly instead." - ), - ): - gc8 = GroundConnection(ground=ground1, element=tr, side="LV", phase="n") - assert gc8 in ground1.connections - assert gc8.id == "transformer 'tr' LV side phase 'n' to ground 'ground1'" - with pytest.warns( - DeprecationWarning, - match=( - r"Connecting a line to a ground using the side argument is deprecated. Use " - r"line.side1 directly instead." - ), - ): - gc10 = GroundConnection(ground=ground1, element=ln, side=1, phase="a") - assert gc10 in ground1.connections - assert gc10.id == "line 'ln' side (1) phase 'a' to ground 'ground1'" - with pytest.warns( - DeprecationWarning, - match=( - r"Connecting a switch to a ground using the side argument is deprecated. Use " - r"switch.side2 directly instead." - ), - ): - gc11 = GroundConnection(ground=ground1, element=sw, side=2, phase="b") - assert gc11 in ground1.connections - assert gc11.id == "switch 'sw' side (2) phase 'b' to ground 'ground1'" diff --git a/roseau/load_flow/models/tests/test_line_parameters.py b/roseau/load_flow/models/tests/test_line_parameters.py index 2d897cb3..0b090014 100644 --- a/roseau/load_flow/models/tests/test_line_parameters.py +++ b/roseau/load_flow/models/tests/test_line_parameters.py @@ -586,7 +586,9 @@ def test_catalogue_data(): for row in catalogue_data.itertuples(): assert isinstance(row.name, str) - assert re.match(r"^[UOT]_[A-Z]+_\d+(?:_\w+)?$", row.name) + assert re.match(r"^[UOT]_[A-Z]+_\d+(?:_\w+)?$", row.name) or re.match( + r"^[UOT]_[A-Z]+_3x(\d+)\+(\d+(?:\.\d+)?)$", row.name + ) assert isinstance(row.resistance, float) assert isinstance(row.resistance_neutral, float) assert isinstance(row.reactance, float) @@ -659,7 +661,8 @@ def test_from_catalogue(): "'U_AL_54', 'U_AL_55', 'U_AL_59', 'U_AL_60', 'U_AL_69', 'U_AL_70', 'U_AL_74', " "'U_AL_75', 'U_AL_79', 'U_AL_80', 'U_AL_90', 'U_AL_93', 'U_AL_95', 'U_AL_100', " "'U_AL_116', 'U_AL_117', 'U_AL_120', 'U_AL_147', 'U_AL_148', 'U_AL_150', 'U_AL_228', " - "'U_AL_240', 'U_AL_288'." + "'U_AL_240', 'U_AL_288', 'U_AL_3x50+50', 'U_AL_3x95+50', 'U_AL_3x150+70', " + "'U_AL_3x150+150', 'U_AL_3x240+95'." ) assert e.value.code == RoseauLoadFlowExceptionCode.CATALOGUE_SEVERAL_FOUND @@ -688,7 +691,7 @@ def test_get_catalogue(): # Get the entire catalogue catalogue = LineParameters.get_catalogue() assert isinstance(catalogue, pd.DataFrame) - assert catalogue.shape == (355, 15) + assert catalogue.shape == (370, 15) # Filter on a single attribute for field_name, value, expected_size in ( @@ -697,23 +700,23 @@ def test_get_catalogue(): ("material", "Cu", 121), ("material_neutral", "Cu", 121), # ("insulator", Insulator.SE, 240), - ("section", 150, 9), - ("section_neutral", 150, 9), - ("section", Q_(1.5, "cm²"), 9), - ("section_neutral", Q_(1.5, "cm²"), 9), + ("section", 150, 13), + ("section_neutral", 150, 10), + ("section", Q_(1.5, "cm²"), 13), + ("section_neutral", Q_(1.5, "cm²"), 10), ): filtered_catalogue = LineParameters.get_catalogue(**{field_name: value}) - assert filtered_catalogue.shape == (expected_size, 15) + assert filtered_catalogue.shape == (expected_size, 15), f"Failed for {field_name}={value}" # Filter on two attributes for field_name, value, expected_size in ( ("name", r"U_AL_150.*", 1), - ("line_type", "OvErHeAd", 122), - ("section", 150, 9), - ("section_neutral", 150, 9), + ("line_type", "OvErHeAd", 40), + ("section", 150, 7), + ("section_neutral", 150, 4), ): - filtered_catalogue = LineParameters.get_catalogue(**{field_name: value}) - assert filtered_catalogue.shape == (expected_size, 15) + filtered_catalogue = LineParameters.get_catalogue(**{field_name: value}, material="AL") + assert filtered_catalogue.shape == (expected_size, 15), f"Failed for {field_name}={value}" # No results empty_catalogue = LineParameters.get_catalogue(section=15000) diff --git a/roseau/load_flow/models/tests/test_lines.py b/roseau/load_flow/models/tests/test_lines.py index 45e27f6f..97eaa02d 100644 --- a/roseau/load_flow/models/tests/test_lines.py +++ b/roseau/load_flow/models/tests/test_lines.py @@ -98,7 +98,7 @@ def test_line_parameters_shortcut(): assert np.allclose(line.y_shunt.m_as("S"), 0.05 * y_shunt) -def test_line_ground(recwarn): +def test_line_ground(): bus1 = Bus(id="bus1", phases="abc") bus2 = Bus(id="bus2", phases="abc") z_line = 0.01 * np.eye(3, dtype=complex) @@ -108,16 +108,13 @@ def test_line_ground(recwarn): ground = Ground(id="ground") # Create a line with a useless ground - recwarn.clear() - line_without_shunt = Line( - id="line", bus1=bus1, bus2=bus2, parameters=lp_without_shunt, length=Q_(50, "m"), ground=ground - ) - assert len(recwarn) == 1 - assert recwarn[0].category is UserWarning - assert ( - recwarn[0].message.args[0] - == "The ground element must not be provided for line 'line' as it does not have a shunt admittance." - ) + with pytest.warns( + UserWarning, + match="The ground element must not be provided for line 'line' as it does not have a shunt admittance.", + ): + line_without_shunt = Line( + id="line", bus1=bus1, bus2=bus2, parameters=lp_without_shunt, length=Q_(50, "m"), ground=ground + ) assert line_without_shunt.ground is None # assign a line parameter with shunt to a line without ground @@ -233,6 +230,38 @@ def test_res_violated(): np.testing.assert_allclose(line.res_loading.m, [12 / 11, 12 / 11, 12 / 13]) +def test_res_state(): + bus1 = Bus(id="bus1", phases="abc") + bus2 = Bus(id="bus2", phases="abc") + lp = LineParameters(id="lp", z_line=np.eye(3, dtype=complex)) + line = Line(id="line", bus1=bus1, bus2=bus2, parameters=lp, length=Q_(50, "m")) + + bus1._res_potentials = 230 * PosSeq + bus2._res_potentials = 225 * PosSeq + line.side1._res_currents = 50 * PosSeq + line.side2._res_currents = -50 * PosSeq + + # No ampacity + assert line._res_state_getter() == "unknown" + + # With ampacity + lp._ampacities = np.array([100, 100, 100], dtype=np.float64) + assert line._res_state_getter() == "normal" + line.side1._res_currents = 80 * PosSeq + assert line._res_state_getter() == "high" + line.side1._res_currents = 120 * PosSeq + assert line._res_state_getter() == "very-high" + + line.side1._res_currents = 50 * PosSeq + assert line._res_state_getter() == "normal" + line.side2._res_currents = 120 * PosSeq * (1, 0.5, 0.5) # Only one violation + assert line._res_state_getter() == "very-high" + + # Change max loading + line._max_loading = 1.2 + assert line._res_state_getter() == "high" + + @pytest.mark.parametrize( ("phases", "z_line", "y_shunt", "len_line", "bus_pot", "line_cur", "ground_pot", "expected_pow"), ( diff --git a/roseau/load_flow/models/tests/test_phases.py b/roseau/load_flow/models/tests/test_phases.py index 8e8854cf..8625d2d7 100644 --- a/roseau/load_flow/models/tests/test_phases.py +++ b/roseau/load_flow/models/tests/test_phases.py @@ -714,10 +714,3 @@ def test_potential_ref_phases(): PotentialRef(id="ref9", element=switch) # type: ignore assert e.value.code == RoseauLoadFlowExceptionCode.BAD_ELEMENT_OBJECT assert e.value.msg == "Potential reference 'ref9' cannot be connected to a switch." - - # Deprecated - with pytest.warns( - DeprecationWarning, - match=r"Argument 'phase' for PotentialRef\(\) is deprecated. It has been renamed to 'phases'.", - ): - assert PotentialRef(id="ref10", element=bus_abc, phase="a").phases == "a" # type: ignore diff --git a/roseau/load_flow/models/tests/test_transformers.py b/roseau/load_flow/models/tests/test_transformers.py index d76bb278..04c5e9ef 100644 --- a/roseau/load_flow/models/tests/test_transformers.py +++ b/roseau/load_flow/models/tests/test_transformers.py @@ -83,6 +83,33 @@ def test_res_violated(): np.testing.assert_allclose(transformer.res_loading.m, 80 * 230 * 3 / 50_000) +def test_res_state(): + bus1 = Bus(id="bus1", phases="abc") + bus2 = Bus(id="bus2", phases="abcn") + tp = TransformerParameters.from_open_and_short_circuit_tests( + id="tp", vg="Yzn11", sn=50e3, uhv=20e3, ulv=400, p0=145, i0=0.018, psc=1350, vsc=0.04 + ) + tr = Transformer(id="transformer", bus_hv=bus1, bus_lv=bus2, parameters=tp) + + def current(s, u): + return s / (np.sqrt(3) * u) + + tr.side_hv._res_potentials = 20e3 / np.sqrt(3) * PosSeq + tr.side_lv._res_potentials = 400 / np.sqrt(3) * PosSeq + tr.side_hv._res_currents = current(30e3, 20e3) * PosSeq + tr.side_lv._res_currents = current(-30e3, 400) * PosSeq + + assert tr._res_state_getter() == "normal" + tr.side_hv._res_currents = current(45e3, 20e3) * PosSeq + assert tr._res_state_getter() == "high" + tr.side_hv._res_currents = current(60e3, 20e3) * PosSeq + assert tr._res_state_getter() == "very-high" + + # Change max loading + tr._max_loading = 1.2 + assert tr._res_state_getter() == "high" + + def test_transformer_results(): bus_hv = Bus(id="bus_hv", phases="abc") bus_lv = Bus(id="bus_lv", phases="abcn") @@ -123,23 +150,23 @@ def test_brought_out_neutral(): tr2 = Transformer(id="tr2", bus_hv=bus_hv, bus_lv=bus_lv, parameters=tp2) assert tr2.phases_lv == "abc" - # Warn on old behavior + # Warn on missing brought out neutral with pytest.warns( - FutureWarning, + UserWarning, match=( r"Transformer 'tr3' with vector group 'Yd5' does not have a brought out neutral on the " r"HV side. The neutral phase 'n' is ignored. If you meant to use a brought out neutral, " - r"use vector group 'YNd5'. This will raise an error in the future." + r"use vector group 'YNd5'." ), ): tr3 = Transformer(id="tr3", bus_hv=bus_hv, bus_lv=bus_lv, parameters=tp1, phases_hv="abcn", phases_lv="abc") assert tr3.phases_hv == "abc" with pytest.warns( - FutureWarning, + UserWarning, match=( r"Transformer 'tr4' with vector group 'Dy11' does not have a brought out neutral on the " r"LV side. The neutral phase 'n' is ignored. If you meant to use a brought out neutral, " - r"use vector group 'Dyn11'. This will raise an error in the future." + r"use vector group 'Dyn11'." ), ): tr4 = Transformer(id="tr4", bus_hv=bus_hv, bus_lv=bus_lv, parameters=tp2, phases_hv="abc", phases_lv="abcn") diff --git a/roseau/load_flow/models/transformers.py b/roseau/load_flow/models/transformers.py index 4130c253..6fb1479c 100644 --- a/roseau/load_flow/models/transformers.py +++ b/roseau/load_flow/models/transformers.py @@ -1,19 +1,16 @@ import logging -import warnings from functools import cached_property from typing import Final from shapely.geometry.base import BaseGeometry -from typing_extensions import deprecated -from roseau.load_flow.converters import _calculate_voltages from roseau.load_flow.exceptions import RoseauLoadFlowException, RoseauLoadFlowExceptionCode from roseau.load_flow.models.branches import AbstractBranch, AbstractBranchSide from roseau.load_flow.models.buses import Bus from roseau.load_flow.models.transformer_parameters import TransformerParameters -from roseau.load_flow.typing import ComplexArray, Id, JsonDict +from roseau.load_flow.typing import Id, JsonDict, ResultState from roseau.load_flow.units import Q_, ureg_wraps -from roseau.load_flow.utils import deprecate_renamed_parameters, find_stack_level +from roseau.load_flow.utils import deprecate_renamed_parameters, warn_external from roseau.load_flow_engine.cy_engine import CyTransformer logger = logging.getLogger(__name__) @@ -281,13 +278,11 @@ def _compute_phases_three( if "n" in phases_hv and not w1_has_neutral: if whv.startswith(("Y", "Z")): correct_vg = f"{whv}N{wlv}{clock}" - warnings.warn( + warn_external( f"Transformer {id!r} with vector group '{parameters.vg}' does not have a " f"brought out neutral on the HV side. The neutral phase 'n' is ignored. If " - f"you meant to use a brought out neutral, use vector group '{correct_vg}'. " - f"This will raise an error in the future.", - FutureWarning, - stacklevel=find_stack_level(), + f"you meant to use a brought out neutral, use vector group '{correct_vg}'.", + UserWarning, ) phases_hv = phases_hv.replace("n", "") else: @@ -304,13 +299,11 @@ def _compute_phases_three( if "n" in phases_lv and not w2_has_neutral: if wlv.startswith(("y", "z")): correct_vg = f"{whv}{wlv}n{clock}" - warnings.warn( + warn_external( f"Transformer {id!r} with vector group '{parameters.vg}' does not have a " f"brought out neutral on the LV side. The neutral phase 'n' is ignored. If " - f"you meant to use a brought out neutral, use vector group '{correct_vg}'. " - f"This will raise an error in the future.", - FutureWarning, - stacklevel=find_stack_level(), + f"you meant to use a brought out neutral, use vector group '{correct_vg}'.", + UserWarning, ) phases_lv = phases_lv.replace("n", "") else: @@ -396,6 +389,17 @@ def _res_loading_getter(self, warning: bool) -> float: powers_lv = self._side2._res_powers_getter(warning=False) # warn only once return max(abs(powers_hv.sum()), abs(powers_lv.sum())) / self._parameters._sn + def _res_state_getter(self) -> ResultState: + """Get the state of the transformer based on its loading.""" + loading = self._res_loading_getter(warning=False) + max_loading = self._max_loading + if loading > max_loading: + return "very-high" + elif loading > 0.75 * max_loading: + return "high" + else: + return "normal" + @property @ureg_wraps("", (None,)) def res_loading(self) -> Q_[float]: @@ -417,22 +421,6 @@ def res_violated(self) -> bool: loading = self._res_loading_getter(warning=True) return bool(loading > self._max_loading) - @property # TODO remove in version 0.14 - @deprecated("`res_voltages_hv` will be removed in the next release, use `res_voltages[0]` instead") - @ureg_wraps("V", (None,)) - def res_voltages_hv(self) -> Q_[ComplexArray]: - """The load flow result of the transformer voltages on the HV side (V).""" - potentials_hv = self._side1._res_potentials_getter(warning=True) - return _calculate_voltages(potentials=potentials_hv, phases=self.phases_hv) - - @property # TODO remove in version 0.14 - @deprecated("`res_voltages_lv` will be removed in the next release, use `res_voltages[1]` instead") - @ureg_wraps("V", (None,)) - def res_voltages_lv(self) -> Q_[ComplexArray]: - """The load flow result of the transformer voltages on the LV side (V).""" - potentials_lv = self._side2._res_potentials_getter(warning=True) - return _calculate_voltages(potentials=potentials_lv, phases=self.phases_lv) - # # Json Mixin interface # diff --git a/roseau/load_flow/network.py b/roseau/load_flow/network.py index 4ef3fa42..261f8430 100644 --- a/roseau/load_flow/network.py +++ b/roseau/load_flow/network.py @@ -7,7 +7,7 @@ import re from collections.abc import Generator, Iterable, Mapping from math import nan -from typing import TYPE_CHECKING, Any, Final, Literal, Self, TypeVar, final +from typing import TYPE_CHECKING, Any, Final, Literal, Self, final import geopandas as gpd import numpy as np @@ -51,8 +51,6 @@ logger = logging.getLogger(__name__) -_AT = TypeVar("_AT", bound=AbstractTerminal) - @final class ElectricalNetwork(AbstractNetwork[Element]): @@ -418,6 +416,7 @@ def to_graph(self, *, respect_switches: bool = True) -> "MultiGraph": parameters_id=transformer.parameters.id, max_loading=transformer._max_loading, sn=transformer.parameters._sn, + tap=transformer._tap, geom=geom_mapping(transformer.geometry), ) for switch in self.switches.values(): @@ -835,9 +834,9 @@ def res_ground_connections(self) -> pd.DataFrame: return pd.DataFrame(res_dict).astype(dtypes).set_index(["connection_id"]) # Voltages results - def _iter_terminal_res_voltages( - self, terminals: Mapping[Id, _AT], voltage_type: Literal["pp", "pn", "auto"] - ) -> Generator[tuple[_AT, ComplexArray, list[str]]]: + def _iter_terminal_res_voltages[AT: AbstractTerminal]( + self, terminals: Mapping[Id, AT], voltage_type: Literal["pp", "pn", "auto"] + ) -> Generator[tuple[AT, ComplexArray, list[str]]]: if voltage_type == "auto": for e in terminals.values(): yield e, e._res_voltages_getter(warning=False), e.voltage_phases @@ -1167,7 +1166,9 @@ def _get_starting_potentials(self, all_phases: set[str]) -> tuple[dict[str, comp starting_source = None potentials = {"n": 0j} # if there are multiple voltage sources, start from the higher one (the last one in the sorted below) - for source in sorted(self.sources.values(), key=lambda x: abs(x._voltages).mean()): + for source in sorted( + self.sources.values(), key=lambda x: abs(x._voltages).mean() / (1 if "n" in x.phases else SQRT3) + ): source_voltages = source._voltages.tolist() starting_source = source if "n" in source.phases: @@ -1194,7 +1195,9 @@ def _get_starting_potentials(self, all_phases: set[str]) -> tuple[dict[str, comp assert starting_source is not None, "No voltage source found in the network." if len(potentials) < len(all_phases): # We failed to determine all the potentials (the sources are strange), fallback to something simple - v = abs(starting_source._voltages).mean() + v = abs(starting_source._voltages).mean().item() + if "n" not in starting_source.phases: + v /= SQRT3 potentials["a"] = v potentials["b"] = v * ALPHA2 potentials["c"] = v * ALPHA @@ -1202,6 +1205,10 @@ def _get_starting_potentials(self, all_phases: set[str]) -> tuple[dict[str, comp return potentials, starting_source + def _get_starting_bus_id(self) -> Id: + _, starting_source = self._get_starting_potentials(all_phases=set()) + return starting_source.bus.id + @staticmethod def _check_ref(elements: Iterable[Element]) -> None: """Check the number of potential references to avoid having a singular jacobian matrix.""" diff --git a/roseau/load_flow/plotting.py b/roseau/load_flow/plotting.py index e898d400..170e3558 100644 --- a/roseau/load_flow/plotting.py +++ b/roseau/load_flow/plotting.py @@ -1,27 +1,50 @@ """Plotting functions for `roseau.load_flow`.""" import cmath +import dataclasses import math -import warnings from collections.abc import Callable, Iterable, Mapping -from typing import TYPE_CHECKING, Any, Literal, overload +from typing import TYPE_CHECKING, Any, Literal, Self, TypedDict import geopandas as gpd import numpy as np -from typing_extensions import deprecated +from pint import PintError -from roseau.load_flow.models import AbstractBranch, AbstractTerminal +from roseau.load_flow.models import AbstractTerminal, Bus, Line, Switch, Transformer from roseau.load_flow.network import ElectricalNetwork from roseau.load_flow.sym import NegativeSequence, PositiveSequence, ZeroSequence, phasor_to_sym -from roseau.load_flow.typing import ComplexArray, Id, Side -from roseau.load_flow.utils import find_stack_level +from roseau.load_flow.types import LineType +from roseau.load_flow.typing import ComplexArray, Id, ResultState +from roseau.load_flow.units import Q_ if TYPE_CHECKING: import folium + import plotly.graph_objects as go from matplotlib.axes import Axes - FeatureMap = dict[str, Any] - StyleDict = dict[str, Any] + import roseau.load_flow_single as rlfs + + type FeatureMap = dict[str, Any] + type StyleDict = dict[str, Any] + type MapElementType = Literal["bus", "line", "transformer"] + + class VoltageProfileNode(TypedDict): + distance: float + voltage: float + voltages: list[float] | None + min_voltage: float | None + max_voltage: float | None + state: ResultState + is_tr_bus: bool + + class VoltageProfileEdge(TypedDict): + from_bus: Id + to_bus: Id + loading: float | None + loadings: list[float] | None + max_loading: float + state: ResultState + _COLORS = {"a": "#234e83", "b": "#cad40e", "c": "#55b2aa", "n": "#000000"} _COLORS.update( @@ -35,6 +58,16 @@ } ) +# TODO: consult with the frontend team for a color scheme +_RESULT_COLORS: dict[ResultState, str] = { + "very-high": "#d7191c", # reddish + "high": "#fdae61", # orangy + "normal": "#1a9850", # greenish + "low": "#abd9e9", # light bluish + "very-low": "#2c7bb6", # bluish + "unknown": "#666666", # gray +} + # # Utility functions @@ -82,31 +115,13 @@ def _draw_voltage_phasor( def _get_phases_and_potentials( - element: AbstractTerminal | AbstractBranch, voltage_type: Literal["pp", "pn", "auto"], side: Side | None + element: AbstractTerminal, voltage_type: Literal["pp", "pn", "auto"] ) -> tuple[AbstractTerminal, str, ComplexArray]: if not element.is_multi_phase: raise TypeError(f"Only multi-phase elements can be plotted. Did you mean to use rlf.{type(element).__name__}?") - if isinstance(element, AbstractTerminal): - if side is not None: - raise ValueError("The side argument is only valid for branch elements.") - else: - if side in (1, "HV"): - element = element.side1 - elif side in (2, "LV"): - element = element.side2 - elif side is None: - expected = ("HV", "LV") if element.element_type == "transformer" else (1, 2) - raise ValueError(f"The side for a {element.element_type} must be one of {expected}.") - else: - raise ValueError(f"Invalid side: {side!r}") - warnings.warn( - ( - f"Plotting the voltages of a {element._branch.element_type} using the side argument " - f"is deprecated. Use {element._branch.element_type}.side{element._side_suffix} " - f"directly instead." - ), - category=DeprecationWarning, - stacklevel=find_stack_level(), + if not isinstance(element, AbstractTerminal): + raise ValueError( + "The element must be a terminal (bus, load, source) or a branch side (line, switch, transformer)." ) phases, potentials = element.phases, element.res_potentials.m @@ -129,33 +144,47 @@ def _get_phases_and_potentials( return element, phases, potentials +def _pu_to_pct[V: (float, list[float])](v: V | None, /) -> V | None: + """Convert per unit value to percentage.""" + if v is None: + return None + elif isinstance(v, list): + return [val * 100 for val in v] + else: + return v * 100 + + +def _pp_num(v: float | list[float] | list[float | None] | None, /, missing: str = "n/a") -> str: + """Pretty print number(s) or `missing` if `None`.""" + if v is None: + return missing + elif isinstance(v, list): + return "[" + ", ".join(missing if val is None else f"{val:.5g}" for val in v) + "]" + else: + return f"{v:.5g}" + + +def _scalar_if_unique(value: np.ndarray | None): + # If the value is the same for all phases, return it as a scalar, otherwise, return the array + if value is None: + return None + unique = np.unique(value) + if unique.size == 1: + return unique.item() + return value.tolist() + + # # Phasor plotting functions # -@overload def plot_voltage_phasors( element: AbstractTerminal, *, voltage_type: Literal["pp", "pn", "auto"] = "auto", ax: "Axes | None" = None -) -> "Axes": ... -@overload -@deprecated( - "Plotting the voltage phasors of a branch using the side argument is deprecated. Use " - "branch.side1 or branch.side2 directly instead." -) -def plot_voltage_phasors( - element: AbstractBranch, *, voltage_type: Literal["pp", "pn", "auto"] = "auto", side: Side, ax: "Axes | None" = None -) -> "Axes": ... -def plot_voltage_phasors( - element: AbstractTerminal | AbstractBranch, - *, - voltage_type: Literal["pp", "pn", "auto"] = "auto", - side: Side | None = None, - ax: "Axes | None" = None, ) -> "Axes": """Plot the voltage phasors of a terminal element or a branch element. Args: element: - The bus, load, source, line, switch or transformer whose voltages to plot. + The bus, load, source, branch side whose voltages to plot. voltage_type: The type of the voltages to plot. @@ -167,13 +196,6 @@ def plot_voltage_phasors( - ``"pn"``: Plots the phase-to-neutral voltages. Raises an error if the element has no neutral. - side: - The side of the branch element to plot. - - - For transformers: ``"HV"`` or ``"LV"`` - - For lines/switches: ``1`` or ``2`` - - For buses/loads/sources: ignored - ax: The axes to plot on. If None, the currently active axes object is used. @@ -184,24 +206,25 @@ def plot_voltage_phasors( if ax is None: ax = plt.gca() - element, phases, potentials = _get_phases_and_potentials(element, voltage_type, side) + element, phases, potentials = _get_phases_and_potentials(element, voltage_type) _configure_axes(ax, potentials) ax.set_title(f"{element.id}" if element._side_value is None else f"{element.id} ({element._side_value})") + potentials = potentials.tolist() if "n" in phases: - origin = potentials.flat[-1] - for phase, potential in zip(phases[:-1], potentials[:-1].flat, strict=True): + origin = potentials[-1] + for phase, potential in zip(phases[:-1], potentials[:-1], strict=True): _draw_voltage_phasor(ax, potential, origin, color=_COLORS[phase]) - for phase, potential in zip(phases, potentials.flat, strict=True): + for phase, potential in zip(phases, potentials, strict=True): ax.scatter(potential.real, potential.imag, color=_COLORS[phase], label=phase) elif len(phases) == 2: - v1, v2 = potentials.flat + v1, v2 = potentials phase = phases _draw_voltage_phasor(ax, v1, v2, color=_COLORS[phase]) for v, ph in ((v1, phase[0]), (v2, phase[1])): ax.scatter(v.real, v.imag, color=_COLORS[ph], label=ph) else: assert phases == "abc" - va, vb, vc = potentials.flat + va, vb, vc = potentials for v1, v2, phase in ((va, vb, "ab"), (vb, vc, "bc"), (vc, va, "ca")): _draw_voltage_phasor(ax, v1, v2, color=_COLORS[phase]) for v, phase in ((va, "a"), (vb, "b"), (vc, "c")): @@ -210,34 +233,15 @@ def plot_voltage_phasors( return ax -@overload def plot_symmetrical_voltages( element: AbstractTerminal, *, axes: Iterable["Axes"] | None = None -) -> "tuple[Axes, Axes, Axes]": ... -@overload -@deprecated( - "Plotting the symmetrical voltages of a branch using the side argument is deprecated. Use " - "branch.side1 or branch.side2 directly instead." -) -def plot_symmetrical_voltages( - element: AbstractBranch, *, side: Side, axes: Iterable["Axes"] | None = None -) -> "tuple[Axes, Axes, Axes]": ... -def plot_symmetrical_voltages( - element: AbstractTerminal | AbstractBranch, *, side: Side | None = None, axes: Iterable["Axes"] | None = None ) -> "tuple[Axes, Axes, Axes]": """Plot the symmetrical voltages of a terminal element or a branch element. Args: element: - The bus, load, source, line, switch or transformer whose voltages to plot. The element - must have ``'abc'`` or ``'abcn'`` phases. - - side: - The side of the branch element to plot. - - - For transformers: ``"HV"`` or ``"LV"`` - - For lines/switches: ``1`` or ``2`` - - For buses/loads/sources: ignored + The bus, load, source, branch side whose voltages to plot. The element must have + ``'abc'`` or ``'abcn'`` phases. axes: The three axes to plot on for the symmetrical components in the order zero, positive, @@ -249,23 +253,24 @@ def plot_symmetrical_voltages( """ from roseau.load_flow.utils.optional_deps import pyplot as plt - element, phases, potentials = _get_phases_and_potentials(element, "auto", side) + element, phases, potentials = _get_phases_and_potentials(element, "auto") if phases not in {"abc", "abcn"}: raise ValueError("The element must have 'abc' or 'abcn' phases.") if axes is None: _, axes = plt.subplots(1, 3) ax0, ax1, ax2 = axes # type: ignore - u0, u1, u2 = sym_components = phasor_to_sym(potentials[:3]) - un = potentials[3] if "n" in phases else 0j - ax_limits = np.array(1.2 * max(abs(sym_components)) * PositiveSequence, dtype=np.complex128) + sym_components = phasor_to_sym(potentials[:3]) + u0, u1, u2 = sym_components.tolist() + un = potentials.item(3) if "n" in phases else 0j + ax_limits = (1.2 * max(abs(sym_components)) * PositiveSequence).ravel() title = f"{element.id}" if element._side_value is None else f"{element.id} ({element._side_value})" def _draw_balanced_voltages(ax: "Axes", u: "complex", seq: "ComplexArray"): - seq_potentials = np.array(u * seq, dtype=np.complex128) - for phase, u in zip("abc", seq_potentials.flat, strict=False): - _draw_voltage_phasor(ax, u, 0j, color=_COLORS[phase], annotate=False) - for phase, u in zip("abc", seq_potentials.flat, strict=False): - ax.scatter(u.real, u.imag, color=_COLORS[phase], label=phase) + seq_potentials = (u * seq).ravel().tolist() + for phase, v in zip("abc", seq_potentials, strict=False): + _draw_voltage_phasor(ax, v, 0j, color=_COLORS[phase], annotate=False) + for phase, v in zip("abc", seq_potentials, strict=False): + ax.scatter(v.real, v.imag, color=_COLORS[phase], label=phase) def _draw_zero_voltages(ax: "Axes", u: "complex", seq: "ComplexArray"): _draw_voltage_phasor(ax, u, un, color=_COLORS["a"], annotate=False) @@ -284,7 +289,7 @@ def _draw_zero_voltages(ax: "Axes", u: "complex", seq: "ComplexArray"): angle = cmath.phase(u) ha = "right" if cmath.pi / 2 < abs(angle) < 3 * cmath.pi / 2 else "left" va = "bottom" if abs(angle) < cmath.pi else "top" - xy = u + ax_limits[0] / 20 * cmath.exp(1j * angle) # move it 5% of the axis limits + xy = u + ax_limits.item(0) / 20 * cmath.exp(1j * angle) # move it 5% of the axis limits ax.annotate(f"{abs(u):.0f}V", (xy.real, xy.imag), ha=ha, va=va) ax.legend() @@ -303,11 +308,10 @@ def _check_folium(func_name: str) -> None: raise -def _plot_interactive_map_internal( - buses_gdf: gpd.GeoDataFrame, - lines_gdf: gpd.GeoDataFrame, - bus_fields: dict[str, str], - line_fields: dict[str, str], +def _plot_interactive_map_internal( # noqa: C901 + network: "ElectricalNetwork | rlfs.ElectricalNetwork", + dataframes: dict["MapElementType", gpd.GeoDataFrame], + fields: dict["MapElementType", dict[str, str]], style_color_callback: Callable[[str, Id], str], highlight_color: str, style_function: Callable[["FeatureMap"], "StyleDict | None"] | None, @@ -316,25 +320,91 @@ def _plot_interactive_map_internal( add_tooltips: bool, add_popups: bool, add_search: bool, + fit_bounds: bool, ) -> "folium.Map": import folium + from folium.plugins import FeatureGroupSubGroup, Search def internal_style_function(feature): result = style_function(feature) if style_function is not None else None if result is not None: return result # Default style - style_color = style_color_callback(feature["properties"]["element_type"], feature["properties"]["id"]) - if feature["properties"]["element_type"] == "bus": - return { - "fill": True, - "fillColor": style_color, - "color": style_color, - "fillOpacity": 1, - "radius": 3, - } - elif feature["properties"]["element_type"] == "line": - return {"color": style_color, "weight": 2} + e_id, e_type = feature["properties"]["id"], feature["properties"]["element_type"] + style_color = style_color_callback(e_type, e_id) + if e_type == "bus": + vn = nominal_voltages[e_id] + if e_id in source_buses: + radius, margin = 15, -1 + border_radius = 0 # Source bus: square + else: + if vn < lv: + radius, margin = 5, 3 # LV + elif vn < mv: + radius, margin = 10, 1 # MV + else: + radius, margin = 15, -1 # HV + border_radius = radius / 2 + markup = f""" +
+
+
+
+ """ + return {"html": markup} + elif e_type == "line": + line = network.lines[e_id] + line_type = line.parameters._line_type + vn = nominal_voltages[line.bus1.id] + if vn < lv: + weight = 1.5 # LV + elif vn < mv: + weight = 3.0 # MV + else: + weight = 4.5 # HV + dash_array = "5, 5" if line_type == LineType.UNDERGROUND else None + return {"color": style_color, "weight": weight, "dashArray": dash_array} + elif e_type == "transformer": + bus_hv_id = feature["properties"]["bus_hv_id"] + bus_lv_id = feature["properties"]["bus_lv_id"] + vn = nominal_voltages[bus_hv_id] + if bus_hv_id in source_buses or bus_lv_id in source_buses: + radius, margin = 15, -1 + else: + if vn < lv: + radius, margin = 5, 3 # LV + elif vn < mv: + radius, margin = 10, 1 # MV + else: + radius, margin = 15, -1 # HV + tr_color = style_color + hv_color = style_color_callback("bus", bus_hv_id) + lv_color = style_color_callback("bus", bus_lv_id) + markup = f""" +
+
+
+ +
+ """ + return {"html": markup} else: return {"color": style_color, "weight": 2} @@ -343,53 +413,54 @@ def internal_highlight_function(feature): if result is not None: return result # Default highlight style - if feature["properties"]["element_type"] == "bus": + e_type = feature["properties"]["element_type"] + if e_type == "bus": # noqa: SIM116 return {"color": highlight_color, "fillColor": highlight_color} - elif feature["properties"]["element_type"] == "line": + elif e_type == "line": return {"color": highlight_color} + elif e_type == "transformer": + return {"color": highlight_color, "fillColor": highlight_color} else: return {"color": highlight_color} + source_buses = {src.bus.id for src in network.sources.values()} + transformer_buses = {side.bus.id for tr in network.transformers.values() for side in (tr.side_hv, tr.side_lv)} + nominal_voltages = network._get_nominal_voltages() + mv, lv = 60e3, 1e3 + + # Filter out transformer buses, these are represented by the transformers themselves + dataframes["bus"] = dataframes["bus"].loc[~dataframes["bus"]["id"].isin(transformer_buses)] + + tooltips: dict[MapElementType, folium.GeoJsonTooltip | None] = {} if add_tooltips: - bus_tooltip = folium.GeoJsonTooltip( - fields=list(bus_fields.keys()), - aliases=list(bus_fields.values()), - localize=True, - sticky=False, - labels=True, - max_width=800, - ) - line_tooltip = folium.GeoJsonTooltip( - fields=list(line_fields.keys()), - aliases=list(line_fields.values()), - localize=True, - sticky=False, - labels=True, - max_width=800, - ) + for e_type, e_fields in fields.items(): + tooltips[e_type] = folium.GeoJsonTooltip( + fields=list(e_fields.keys()), + aliases=list(e_fields.values()), + localize=True, + sticky=False, + labels=True, + max_width=800, + ) else: - bus_tooltip = line_tooltip = None + tooltips = dict.fromkeys(fields.keys(), None) + popups: dict[MapElementType, folium.GeoJsonPopup | None] = {} if add_popups: - bus_popup = folium.GeoJsonPopup( - fields=list(bus_fields.keys()), - aliases=list(bus_fields.values()), - localize=True, - labels=True, - ) - line_popup = folium.GeoJsonPopup( - fields=list(line_fields.keys()), - aliases=list(line_fields.values()), - localize=True, - labels=True, - ) + for e_type, e_fields in fields.items(): + popups[e_type] = folium.GeoJsonPopup( + fields=list(e_fields.keys()), + aliases=list(e_fields.values()), + localize=True, + labels=True, + ) else: - bus_popup = line_popup = None + popups = dict.fromkeys(fields.keys(), None) map_kws = dict(map_kws) if map_kws is not None else {} # Calculate the center and zoom level of the map if not provided - if "location" not in map_kws or "zoom_start" not in map_kws: - geom_union = buses_gdf.union_all() + if not fit_bounds and ("location" not in map_kws or "zoom_start" not in map_kws): + geom_union = dataframes["bus"].union_all().union(dataframes["line"].union_all()) if "location" not in map_kws: map_kws["location"] = list(reversed(geom_union.centroid.coords[0])) if "zoom_start" not in map_kws: @@ -399,32 +470,37 @@ def internal_highlight_function(feature): # cases, we set a default zoom level of 16. zoom_lon = math.ceil(math.log2(360 * 2.0 / (max_x - min_x))) if max_x > min_x else 16 zoom_lat = math.ceil(math.log2(360 * 2.0 / (max_y - min_y))) if max_y > min_y else 16 - map_kws["zoom_start"] = min(zoom_lon, zoom_lat) + map_kws["zoom_start"] = min(zoom_lon, zoom_lat) - 1 + + if "zoom_control" not in map_kws and add_search: + map_kws["zoom_control"] = "topright" m = folium.Map(**map_kws) network_layer = folium.FeatureGroup(name="Electrical Network").add_to(m) - folium.GeoJson( - data=lines_gdf, - name="lines", - style_function=internal_style_function, - highlight_function=internal_highlight_function, - tooltip=line_tooltip, - popup=line_popup, - ).add_to(network_layer) - folium.GeoJson( - data=buses_gdf, - name="buses", - marker=folium.CircleMarker(), - style_function=internal_style_function, - highlight_function=internal_highlight_function, - tooltip=bus_tooltip, - popup=bus_popup, - ).add_to(network_layer) - folium.LayerControl().add_to(m) + names = {"bus": "Buses", "line": "Lines", "transformer": "Transformers"} + for e_type, frame in dataframes.items(): + if frame.empty: + continue + marker = folium.Marker(icon=folium.DivIcon()) if e_type != "line" else None + name = names[e_type] + folium.GeoJson( + data=frame, + name=name, + marker=marker, + style_function=internal_style_function, + highlight_function=internal_highlight_function, + tooltip=tooltips[e_type], + popup=popups[e_type], + ).add_to(FeatureGroupSubGroup(network_layer, name).add_to(m)) + folium.LayerControl( + collapsed=False, + draggable=True, + position="bottomright", + ).add_to(m) if add_search: - from folium.plugins import Search - Search(network_layer, search_label="id", placeholder="Search network elements...").add_to(m) + if fit_bounds: + folium.FitOverlays(padding=30).add_to(m) return m @@ -439,6 +515,7 @@ def plot_interactive_map( add_tooltips: bool = True, add_popups: bool = True, add_search: bool = True, + fit_bounds: bool = True, ) -> "folium.Map": """Plot an electrical network on an interactive map. @@ -446,10 +523,12 @@ def plot_interactive_map( Make sure you have defined the geometry of the buses and lines in the network before using this function. You can do this by setting the `geometry` attribute of the buses and lines. + Transformers use the geometry of their HV buses. Args: network: - The electrical network to plot. Only the buses and lines are currently plotted. + The electrical network to plot. Buses, lines and transformers are plotted. Buses of + source elements are represented with bigger square markers. style_color: The color of the default style of an element. Defaults to :roseau-primary:`■ #234e83`. @@ -468,8 +547,8 @@ def plot_interactive_map( map_kws: Additional keyword arguments to pass to the :class:`folium.Map` constructor. By default, - `location` is set to the centroid of the network geometry and `zoom_start` is calculated - based on its bounding box. + if ``fit_bounds`` is false, `location` is set to the centroid of the network geometry + and `zoom_start` is calculated based on its bounding box. add_tooltips: If ``True`` (default), tooltips will be added to the map elements. Tooltips appear when @@ -483,6 +562,11 @@ def plot_interactive_map( If ``True`` (default), a search bar will be added to the map to search for network elements by their ID. + fit_bounds: + If ``True`` (default), the map view will be adjusted to fit all network elements. If + ``False``, the initial view is determined by the `location` and `zoom_start` parameters + in `map_kws`. + Returns: The :class:`folium.Map` object with the network plot. """ @@ -492,20 +576,12 @@ def plot_interactive_map( "Only multi-phase networks can be plotted. Did you mean to use rlfs.plotting.plot_interactive_map?" ) - def _scalar_if_unique(value): - # If the value is the same for all phases, return it as a scalar, otherwise, return the array - if value is None: - return None - unique = np.unique(value) - if unique.size == 1: - return unique.item() - return value.tolist() - buses_gdf = network.buses_frame buses_gdf.reset_index(inplace=True) buses_gdf["element_type"] = "bus" buses_gdf["min_voltage_level"] *= 100 # Convert to percentage buses_gdf["max_voltage_level"] *= 100 # Convert to percentage + lines_gdf = network.lines_frame lines_gdf.reset_index(inplace=True) lines_gdf["element_type"] = "line" @@ -513,7 +589,8 @@ def _scalar_if_unique(value): lines_gdf[["ampacity", "section", "line_type", "material", "insulator"]] = None line_params = {} for idx in lines_gdf.index: - lp = network.lines[lines_gdf.at[idx, "id"]].parameters + line_id: Id = lines_gdf.at[idx, "id"] # type: ignore + lp = network.lines[line_id].parameters if lp.id not in line_params: line_params[lp.id] = { "ampacity": _scalar_if_unique(lp._ampacities), @@ -528,34 +605,360 @@ def _scalar_if_unique(value): lines_gdf.at[idx, "material"] = line_params[lp.id]["material"] lines_gdf.at[idx, "insulator"] = line_params[lp.id]["insulator"] - bus_fields = { - "id": "Id:", - "phases": "Phases:", - "nominal_voltage": "Un (V):", - "min_voltage_level": "Umin (%):", - "max_voltage_level": "Umax (%):", + transformers_gdf = network.transformers_frame + transformers_gdf.reset_index(inplace=True) + transformers_gdf["element_type"] = "transformer" + transformers_gdf["tap"] *= 100 # Convert to percentage + transformers_gdf[["hv_side", "lv_side"]] = "" + transformers_gdf[["vg", "sn", "uhv", "ulv"]] = None + for idx in transformers_gdf.index: + tr_id: Id = transformers_gdf.at[idx, "id"] # type: ignore + # Replace geometry with that of the HV bus + bus_hv_id: Id = transformers_gdf.at[idx, "bus_hv_id"] # type: ignore + transformers_gdf.at[idx, "geometry"] = network.buses[bus_hv_id].geometry # type: ignore + lp = network.transformers[tr_id].parameters + transformers_gdf.at[idx, "vg"] = lp.vg + transformers_gdf.at[idx, "sn"] = lp._sn / 1e3 # Convert to kVA + transformers_gdf.at[idx, "uhv"] = lp._uhv + transformers_gdf.at[idx, "ulv"] = lp._ulv + + m = _plot_interactive_map_internal( + network=network, + dataframes={"bus": buses_gdf, "line": lines_gdf, "transformer": transformers_gdf}, + fields={ + "bus": { + "id": "Id:", + "phases": "Phases:", + "nominal_voltage": "Un (V):", + "min_voltage_level": "Umin (%):", + "max_voltage_level": "Umax (%):", + }, + "line": { + "id": "Id:", + "phases": "Phases:", + "bus1_id": "Bus1:", + "bus2_id": "Bus2:", + "parameters_id": "Parameters:", + "length": "Length (km):", + "line_type": "Line Type:", + "material": "Material:", + "insulator": "Insulator:", + "section": "Section (mm²):", + "ampacity": "Ampacity (A):", + "max_loading": "Max loading (%):", + }, + "transformer": { + "id": "Id:", + "vg": "Vector Group:", + "sn": "Sn (kVA):", + "tap": "Tap Position (%):", + "parameters_id": "Parameters:", + "max_loading": "Max loading (%):", + "hv_side": "HV Side", + "bus_hv_id": "» Bus:", + "phases_hv": "» Phases:", + "uhv": "» Ur (V):", + "lv_side": "LV Side", + "bus_lv_id": "» Bus:", + "phases_lv": "» Phases:", + "ulv": "» Ur (V):", + }, + }, + style_color_callback=lambda et, id: "#000000" if et == "transformer" else style_color, + highlight_color=highlight_color, + style_function=style_function, + highlight_function=highlight_function, + map_kws=map_kws, + add_tooltips=add_tooltips, + add_popups=add_popups, + add_search=add_search, + fit_bounds=fit_bounds, + ) + return m + + +def plot_results_interactive_map( + network: ElectricalNetwork, + *, + style_color: str = "#234e83", + highlight_color: str = "#cad40e", + style_function: Callable[["FeatureMap"], "StyleDict | None"] | None = None, + highlight_function: Callable[["FeatureMap"], "StyleDict | None"] | None = None, + map_kws: Mapping[str, Any] | None = None, + add_tooltips: bool = True, + add_popups: bool = True, + add_search: bool = True, + fit_bounds: bool = True, +) -> "folium.Map": + """Plot an electrical network on an interactive map with the load flow results. + + This function uses the `folium` library to create an interactive map of the electrical network + with buses colored according to their voltage levels and lines/transformers colored according to + their loadings. + + Make sure you have defined the geometry of the buses and lines in the network before using this + function. You can do this by setting the `geometry` attribute of the buses and lines. + Transformers use the geometry of their HV buses. Also, ensure that the network has valid results + by running a load flow calculation before plotting. + + Args: + network: + The electrical network to plot. Buses, lines and transformers are plotted. Buses of + source elements are represented with bigger square markers. + + style_color: + The color of the default style of an element. Defaults to :roseau-primary:`■ #234e83`. + + highlight_color: + The color of the default style when an element is highlighted. Defaults to + :roseau-secondary:`■ #cad40e`. + + style_function: + Function mapping a GeoJson Feature to a style dict. If not provided or when it returns + ``None``, the default style is used. The default style colors of buses depend on their + voltage levels: + - blue: `U` below `Umin` + - cyan: `U` close to `Umin`; specifically, `Umin ≤ U < 0.75 * Umin + 0.25` + - green: `U` within `Umin` and `Umax` and not close to the limits + - orange: `U` close to `Umax`; specifically, `0.75 * Umax + 0.25 < U ≤ Umax` + - red: `U` above `Umax` + + The default style colors of lines and transformers depend on their loadings: + - green: below 75% of the maximum loading + - orange: between 75% and 100% of the maximum loading + - red: above 100% of the maximum loading + + highlight_function: + Function mapping a GeoJson Feature to a style dict for mouse events. If not provided or + when it returns ``None``, the default highlight style is used. + + map_kws: + Additional keyword arguments to pass to the :class:`folium.Map` constructor. By default, + if ``fit_bounds`` is false, `location` is set to the centroid of the network geometry + and `zoom_start` is calculated based on its bounding box. + + add_tooltips: + If ``True`` (default), tooltips will be added to the map elements. Tooltips appear when + hovering over an element. + + add_popups: + If ``True`` (default), popups will be added to the map elements. Popups appear when + clicking on an element. + + add_search: + If ``True`` (default), a search bar will be added to the map to search for network + elements by their ID. + + fit_bounds: + If ``True`` (default), the map view will be adjusted to fit all network elements. If + ``False``, the initial view is determined by the `location` and `zoom_start` parameters + in `map_kws`. + + Returns: + The `folium.Map` object with the network plot. + """ + _check_folium(func_name="plot_results_interactive_map") + + if not network.is_multi_phase: + raise TypeError( + "Only multi-phase networks can be plotted. Did you mean to use rlfs.plotting.plot_results_interactive_map?" + ) + network._check_valid_results() + + buses_data: dict[str, list[Any]] = { + "id": [], + "phases": [], + "element_type": [], + "nominal_voltage": [], + "min_voltage_level": [], + "max_voltage_level": [], + "geometry": [], + "res_separator": [], + "res_voltage": [], + "res_voltage_level": [], } - line_fields = { - "id": "Id:", - "phases": "Phases:", - "bus1_id": "Bus1:", - "bus2_id": "Bus2:", - "parameters_id": "Parameters:", - "length": "Length (km):", - "line_type": "Line Type:", - "material": "Material:", - "insulator": "Insulator:", - "section": "Section (mm²):", - "ampacity": "Ampacity (A):", - "max_loading": "Max loading (%):", + buses_ids: list[Id] = [] + for bus in network.buses.values(): + buses_ids.append(bus.id) + buses_data["id"].append(bus.id) + buses_data["phases"].append(bus.phases) + buses_data["element_type"].append("bus") + buses_data["nominal_voltage"].append(bus._nominal_voltage) + buses_data["min_voltage_level"].append(_pu_to_pct(bus._min_voltage_level)) + buses_data["max_voltage_level"].append(_pu_to_pct(bus._max_voltage_level)) + buses_data["geometry"].append(bus.geometry) + buses_data["res_separator"].append("") # Results separator + buses_data["res_voltage"].append(_pp_num([abs(v) for v in bus._res_voltages_getter(warning=False).tolist()])) + buses_data["res_voltage_level"].append( + _pp_num( + _pu_to_pct( + v_levels.tolist() + if (v_levels := bus._res_voltage_levels_getter(warning=False)) is not None + else None + ) + ) + ) + + lines_data: dict[str, list[Any]] = { + "id": [], + "phases": [], + "element_type": [], + "bus1_id": [], + "bus2_id": [], + "parameters_id": [], + "length": [], + "line_type": [], + "material": [], + "insulator": [], + "section": [], + "ampacity": [], + "geometry": [], + "res_separator": [], # Results separator + "max_loading": [], + "res_loading": [], + } + for line in network.lines.values(): + lines_data["id"].append(line.id) + lines_data["phases"].append(line.phases) + lines_data["element_type"].append("line") + lines_data["bus1_id"].append(line.bus1.id) + lines_data["bus2_id"].append(line.bus2.id) + lines_data["parameters_id"].append(line._parameters.id) + lines_data["length"].append(line._length) + lines_data["line_type"].append(line._parameters._line_type) + lines_data["material"].append(_scalar_if_unique(line._parameters._materials)) + lines_data["insulator"].append(_scalar_if_unique(line._parameters._insulators)) + lines_data["section"].append(_scalar_if_unique(line._parameters._sections)) + lines_data["ampacity"].append(_scalar_if_unique(line._parameters._ampacities)) + lines_data["geometry"].append(line.geometry) + lines_data["res_separator"].append("") # Results separator + lines_data["max_loading"].append(line._max_loading * 100) + lines_data["res_loading"].append( + _pp_num( + _pu_to_pct( + loading.tolist() if (loading := line._res_loading_getter(warning=False)) is not None else None + ) + ) + ) + + def _get_tr_buses_data(tr: Transformer, field: str) -> str: + return _pp_num([buses_data[field][buses_ids.index(bus_id)] for bus_id in (tr.bus_hv.id, tr.bus_lv.id)]) + + transformers_data: dict[str, list[Any]] = { + "id": [], + "phases": [], + "element_type": [], + "bus_hv_id": [], + "bus_lv_id": [], + "parameters_id": [], + "geometry": [], + "vg": [], + "sn": [], + "tap": [], + "rated_voltages": [], + "max_loading": [], + "nominal_voltages": [], + "min_voltage_levels": [], + "max_voltage_levels": [], + "res_separator": [], + "res_loading": [], + "res_voltage_hv": [], + "res_voltage_lv": [], + "res_voltage_level_hv": [], + "res_voltage_level_lv": [], } + for tr in network.transformers.values(): + transformers_data["id"].append(tr.id) + transformers_data["phases"].append(f"[{tr.phases_hv}, {tr.phases_lv}]") + transformers_data["element_type"].append("transformer") + transformers_data["bus_hv_id"].append(tr.bus_hv.id) + transformers_data["bus_lv_id"].append(tr.bus_lv.id) + transformers_data["parameters_id"].append(tr._parameters.id) + transformers_data["geometry"].append(tr.bus_hv.geometry) + transformers_data["vg"].append(tr._parameters.vg) + transformers_data["sn"].append(tr._parameters._sn / 1e3) # Convert to kVA + transformers_data["tap"].append(tr._tap * 100) # Convert to percentage + transformers_data["rated_voltages"].append(_pp_num([tr._parameters._uhv, tr._parameters._ulv])) + transformers_data["max_loading"].append(tr._max_loading * 100) + transformers_data["nominal_voltages"].append(_get_tr_buses_data(tr, "nominal_voltage")) + transformers_data["min_voltage_levels"].append(_get_tr_buses_data(tr, "min_voltage_level")) + transformers_data["max_voltage_levels"].append(_get_tr_buses_data(tr, "max_voltage_level")) + transformers_data["res_separator"].append("") # Results separator + transformers_data["res_loading"].append(tr._res_loading_getter(warning=False) * 100) + bus_hv_idx = buses_ids.index(tr.bus_hv.id) + bus_lv_idx = buses_ids.index(tr.bus_lv.id) + transformers_data["res_voltage_hv"].append(buses_data["res_voltage"][bus_hv_idx]) + transformers_data["res_voltage_lv"].append(buses_data["res_voltage"][bus_lv_idx]) + transformers_data["res_voltage_level_hv"].append(buses_data["res_voltage_level"][bus_hv_idx]) + transformers_data["res_voltage_level_lv"].append(buses_data["res_voltage_level"][bus_lv_idx]) + + buses_gdf = gpd.GeoDataFrame(buses_data, crs=network.crs) + lines_gdf = gpd.GeoDataFrame(lines_data, crs=network.crs) + transformers_gdf = gpd.GeoDataFrame(transformers_data, crs=network.crs) + + def style_color_callback(et, eid): + if et == "bus": + return _RESULT_COLORS[network.buses[eid]._res_state_getter()] + elif et == "line": + return _RESULT_COLORS[network.lines[eid]._res_state_getter()] + elif et == "transformer": + return _RESULT_COLORS[network.transformers[eid]._res_state_getter()] + else: + return style_color m = _plot_interactive_map_internal( - buses_gdf=buses_gdf, - lines_gdf=lines_gdf, - bus_fields=bus_fields, - line_fields=line_fields, - style_color_callback=lambda et, id: style_color, + network=network, + dataframes={"bus": buses_gdf, "line": lines_gdf, "transformer": transformers_gdf}, + fields={ + "bus": { + "id": "Id:", + "phases": "Phases:", + "nominal_voltage": "Un (V):", + "min_voltage_level": "Umin (%):", + "max_voltage_level": "Umax (%):", + "res_separator": "--", + "res_voltage": "U (V):", + "res_voltage_level": "U (%):", + }, + "line": { + "id": "Id:", + "phases": "Phases:", + "bus1_id": "Bus1:", + "bus2_id": "Bus2:", + "parameters_id": "Parameters:", + "length": "Length (km):", + "line_type": "Line Type:", + "material": "Material:", + "insulator": "Insulator:", + "section": "Section (mm²):", + "ampacity": "Ampacity (A):", + "max_loading": "Max loading (%):", + "res_separator": "--", + "res_loading": "Loading (%):", + }, + "transformer": { + "id": "Id:", + "bus_hv_id": "HV Bus:", + "bus_lv_id": "LV Bus:", + "phases": "Bus phases [ʜv,ʟv]:", + "vg": "Vector Group:", + "sn": "Sn (kVA):", + "rated_voltages": "Ur [ʜv,ʟv] (V):", + "tap": "Tap Position (%):", + "parameters_id": "Parameters:", + "max_loading": "Max loading (%):", + "nominal_voltages": "Un [ʜv,ʟv] (V):", + "min_voltage_levels": "Umin [ʜv,ʟv] (%):", + "max_voltage_levels": "Umax [ʜv,ʟv] (%):", + "res_separator": "--", + "res_loading": "Loading (%):", + "res_voltage_hv": "Uʜv (V):", + "res_voltage_lv": "Uʟv (V):", + "res_voltage_level_hv": "Uʜv (%):", + "res_voltage_level_lv": "Uʟv (%):", + }, + }, + style_color_callback=style_color_callback, highlight_color=highlight_color, style_function=style_function, highlight_function=highlight_function, @@ -563,5 +966,519 @@ def _scalar_if_unique(value): add_tooltips=add_tooltips, add_popups=add_popups, add_search=add_search, + fit_bounds=fit_bounds, ) return m + + +# +# Voltage profile plotting functions +# +@dataclasses.dataclass(frozen=True, slots=True, kw_only=True) +class _VoltageProfile[NetT: ElectricalNetwork | rlfs.ElectricalNetwork, ModeT: Literal["min", "max", ""]]: + network: NetT + mode: ModeT + starting_bus_id: Id + traverse_transformers: bool + switch_length: float + distance_unit: str + colors: dict[ResultState, str] = dataclasses.field(repr=False) + buses: dict[Id, "VoltageProfileNode"] = dataclasses.field(repr=False) + lines: dict[Id, "VoltageProfileEdge"] = dataclasses.field(repr=False) + transformers: dict[Id, "VoltageProfileEdge"] = dataclasses.field(repr=False) + switches: dict[Id, "VoltageProfileEdge"] = dataclasses.field(repr=False) + + @classmethod + def _from_network( + cls, + network: NetT, + mode: ModeT, + *, + starting_bus_id: Id | None = None, + traverse_transformers: bool = False, + switch_length: float | None = None, + distance_unit: str = "km", + ) -> Self: + network._check_valid_results() + + if starting_bus_id is None: + starting_bus_id = network._get_starting_bus_id() + elif starting_bus_id not in network.buses: + raise ValueError(f"Bus {starting_bus_id!r} not found in the network.") + + try: + distance_factor = Q_(1.0, units="km").m_as(distance_unit) + except PintError as e: + raise ValueError(f"Invalid distance unit: {distance_unit}") from e + + if switch_length is None: + min_line_length = min((line._length for line in network.lines.values()), default=math.inf) + switch_length = min(2e-3, min_line_length) + elif switch_length < 0: + raise ValueError("switch_length must be non-negative.") + + distances = network._shortest_paths( + starting_bus_id, + weight=lambda et, eid: ( + network.lines[eid]._length + if et == "line" + else (0.0 if traverse_transformers else None) + if et == "transformer" + else (switch_length if network.switches[eid].closed else None) + ), + ) + + buses: dict[Id, VoltageProfileNode] = {} + lines: dict[Id, VoltageProfileEdge] = {} + transformers: dict[Id, VoltageProfileEdge] = {} + switches: dict[Id, VoltageProfileEdge] = {} + for bus_id, distance in distances.items(): + buses[bus_id] = cls._handle_bus(network.buses[bus_id], distance=distance * distance_factor, mode=mode) + for line in network.lines.values(): + if not traverse_transformers and line.bus1.id not in distances: + continue + lines[line.id] = cls._handle_line(line) + if traverse_transformers: + for tr in network.transformers.values(): + transformers[tr.id] = cls._handle_transformer(tr) + buses[tr.bus_hv.id]["is_tr_bus"] = True + buses[tr.bus_lv.id]["is_tr_bus"] = True + for switch in network.switches.values(): + if not switch.closed or (not traverse_transformers and switch.bus1.id not in distances): + continue + switches[switch.id] = cls._handle_switch(switch) + + return cls( + network=network, + mode=mode, + starting_bus_id=starting_bus_id, + traverse_transformers=traverse_transformers, + switch_length=switch_length, + distance_unit=distance_unit, + buses=buses, + lines=lines, + transformers=transformers, + switches=switches, + colors=_RESULT_COLORS, + ) + + @classmethod + def _handle_bus(cls, bus: "Bus | rlfs.Bus", distance: float, mode: ModeT) -> "VoltageProfileNode": + if bus._nominal_voltage is None: + raise ValueError( + f"The voltage profile requires buses to have their nominal voltage defined. " + f"Bus {bus.id!r} has no nominal voltage." + ) + if isinstance(bus, Bus): + voltages = bus._res_voltage_levels_getter(warning=False) + assert voltages is not None + voltages = voltages.tolist() + voltage = {"min": min(voltages), "max": max(voltages)}[mode] + else: + voltages = None + voltage = bus._res_voltage_level_getter(warning=False) + assert voltage is not None + + return { + "distance": distance, + "voltage": voltage * 100, + "voltages": _pu_to_pct(voltages), + "min_voltage": _pu_to_pct(bus._min_voltage_level), + "max_voltage": _pu_to_pct(bus._max_voltage_level), + "state": bus._res_state_getter(), + "is_tr_bus": False, # Will be updated later if needed + } + + @classmethod + def _handle_line(cls, line: "Line | rlfs.Line") -> "VoltageProfileEdge": + if isinstance(line, Line): + loadings = line._res_loading_getter(warning=False) + loading = None + if loadings is not None: + loadings = loadings.tolist() + loading = max(loadings) + else: + loadings = None + loading = line._res_loading_getter(warning=False) + return { + "from_bus": line.bus1.id, + "to_bus": line.bus2.id, + "loading": _pu_to_pct(loading), + "loadings": _pu_to_pct(loadings), + "max_loading": line._max_loading * 100, + "state": line._res_state_getter(), + } + + @classmethod + def _handle_transformer(cls, tr: "Transformer | rlfs.Transformer") -> "VoltageProfileEdge": + return { + "from_bus": tr.bus_hv.id, + "to_bus": tr.bus_lv.id, + "loading": tr._res_loading_getter(warning=False) * 100, + "loadings": None, + "max_loading": tr._max_loading * 100, + "state": tr._res_state_getter(), + } + + @classmethod + def _handle_switch(cls, switch: "Switch | rlfs.Switch") -> "VoltageProfileEdge": + return { + "from_bus": switch.bus1.id, + "to_bus": switch.bus2.id, + "loading": None, + "loadings": None, + "max_loading": 100.0, + "state": "unknown", + } + + @property + def _title(self) -> str: + title = f"Voltage Profile Starting at Bus {self.starting_bus_id!r}" + if self.mode: + title = f"{self.mode.capitalize()} {title}" + return title + + @property + def _xlabel(self) -> str: + return f"Distance ({self.distance_unit})" + + @property + def _ylabel(self) -> str: + label = "Voltage (%)" + if self.mode: + label = f"{self.mode.capitalize()} {label}" + return label + + def _edge_segs(self, edge: "VoltageProfileEdge") -> tuple[tuple[float, float], tuple[float, float]]: + """Get the segments for an edge in the form ((x1, y1), (x2, y2)).""" + return ( + (self.buses[edge["from_bus"]]["distance"], self.buses[edge["from_bus"]]["voltage"]), + (self.buses[edge["to_bus"]]["distance"], self.buses[edge["to_bus"]]["voltage"]), + ) + + def _edge_xs(self, edge: "VoltageProfileEdge") -> tuple[float, float]: + """Get the x coordinates for an edge in the form (x1, x2).""" + return (self.buses[edge["from_bus"]]["distance"], self.buses[edge["to_bus"]]["distance"]) + + def _edge_ys(self, edge: "VoltageProfileEdge") -> tuple[float, float]: + """Get the y coordinates for an edge in the form (y1, y2).""" + return (self.buses[edge["from_bus"]]["voltage"], self.buses[edge["to_bus"]]["voltage"]) + + # Public API + # ---------- + def plot_matplotlib(self, *, ax: "Axes | None" = None) -> "Axes": + """Plot the network voltage profile using Matplotlib. + + Args: + ax: + The axes to plot on. If None, the current axes will be used. + + Returns: + The Matplotlib Axes with the voltage profile plot. + """ + try: + import matplotlib.pyplot as plt + except ImportError as e: + e.add_note("matplotlib is required for plotting the voltage profile using plot_matplotlib.") + raise + from matplotlib.collections import LineCollection + from matplotlib.markers import MarkerStyle + from matplotlib.patheffects import Normal, Stroke + + if ax is None: + ax = plt.gca() + + ax.add_collection( + LineCollection( + segments=[self._edge_segs(ln) for ln in self.lines.values()], + colors=[self.colors[ln["state"]] for ln in self.lines.values()], + zorder=2, + ) + ) + + if self.transformers: + ax.add_collection( + LineCollection( + segments=[self._edge_segs(tr) for tr in self.transformers.values()], + colors=[self.colors[tr["state"]] for tr in self.transformers.values()], + linewidths=3, + zorder=3, + path_effects=[Stroke(linewidth=6, foreground="k"), Normal()], + ) + ) + + if self.switches: + ax.add_collection( + LineCollection( + segments=[self._edge_segs(sw) for sw in self.switches.values()], + colors=[self.colors[sw["state"]] for sw in self.switches.values()], + linestyles="dashed", + linewidths=3, + zorder=3, + ) + ) + + bus_pc = ax.scatter( + x=[bus["distance"] for bus in self.buses.values()], + y=[bus["voltage"] for bus in self.buses.values()], + c=[self.colors[bus["state"]] for bus in self.buses.values()], + s=10, + zorder=4, + ) + if self.traverse_transformers: + # ax.scatter does not support per-point marker styles, so we set them manually + bus_pc.set_paths( + [ + (m := MarkerStyle("s" if bus["is_tr_bus"] else "o")).get_path().transformed(m.get_transform()) + for bus in self.buses.values() + ] + ) + + ax.set_title(self._title, fontsize=10) + ax.set_xlabel(self._xlabel) + ax.set_ylabel(self._ylabel) + ax.spines["top"].set_visible(False) + ax.spines["right"].set_visible(False) + ax.grid(alpha=0.25) + return ax + + def plot_plotly(self) -> "go.Figure": + """Plot the network voltage profile using Plotly. + + Returns: + A Plotly Figure with the voltage profile plot. + """ + try: + import plotly.graph_objects as go + except ImportError as e: + e.add_note("plotly is required for plotting the voltage profile using plot_plotly.") + raise + + traces: list[go.Scatter] = [] + + # Buses + voltage_key = "voltages" if self.network.is_multi_phase else "voltage" + buses_trace = go.Scatter( + x=[bus["distance"] for bus in self.buses.values()], + y=[bus["voltage"] for bus in self.buses.values()], + mode="markers", + marker={ + "color": [self.colors[bus["state"]] for bus in self.buses.values()], + "symbol": ( + ["square" if bus["is_tr_bus"] else "circle" for bus in self.buses.values()] + if self.traverse_transformers + else "circle" + ), + "size": 6, + }, + customdata=[ # used in hovers + (bus_id, _pp_num(bus[voltage_key]), _pp_num(bus["min_voltage"]), _pp_num(bus["max_voltage"])) + for bus_id, bus in self.buses.items() + ], + hovertemplate=( + "Bus: %{customdata[0]}" + "
Voltage (%): %{customdata[1]}" + "
Voltage limits (%): [%{customdata[2]}, %{customdata[3]}]" + "" + ), + zorder=3, + ) + traces.append(buses_trace) + + # Transformers + if self.transformers: + # Black borders for transformers + traces.append( + go.Scatter( + x=[x for tr in self.transformers.values() for x in (*self._edge_xs(tr), None)], + y=[y for tr in self.transformers.values() for y in (*self._edge_ys(tr), None)], + mode="lines", + line={"color": "black", "width": 6}, + zorder=2, + hoverinfo="skip", + ) + ) + # Traces for transformers (grouped by color for better performance) + tr_traces: dict[ResultState, dict[str, list[float | None]]] = { + state: {"x": [], "y": []} for state in ("normal", "high", "very-high") + } + for tr in self.transformers.values(): + tr_traces[tr["state"]]["x"].extend((*self._edge_xs(tr), None)) + tr_traces[tr["state"]]["y"].extend((*self._edge_ys(tr), None)) + traces.extend( + go.Scatter( + x=t["x"], + y=t["y"], + mode="lines", + line={"color": self.colors[s], "width": 3}, + zorder=2, + hoverinfo="skip", + ) + for s, t in tr_traces.items() + if t["x"] # skip empty colors + ) + # Cannot hover on line traces, add invisible midpoint markers to show hover info + # https://github.com/plotly/plotly.js/issues/1960 + traces.append( + go.Scatter( + x=[sum(self._edge_xs(tr)) / 2 for tr in self.transformers.values()], + y=[sum(self._edge_ys(tr)) / 2 for tr in self.transformers.values()], + mode="markers", + marker={"opacity": 0, "color": [self.colors[tr["state"]] for tr in self.transformers.values()]}, + customdata=[(tr_id, tr["loading"], tr["max_loading"]) for tr_id, tr in self.transformers.items()], + hovertemplate=( + # For parallel transformers, only the last one might be shown in hover + # https://github.com/plotly/plotly.py/issues/2476 + "Transformer: %{customdata[0]}" + "
Loading (%): %{customdata[1]:.5g}" + "
Loading limit (%): %{customdata[2]:.5g}" + "" + ), + ) + ) + + # Lines + lines_traces: dict[ResultState, dict[str, list[float | None]]] = { + state: {"x": [], "y": []} for state in ("normal", "high", "very-high", "unknown") + } + loading_key = "loadings" if self.network.is_multi_phase else "loading" + for line in self.lines.values(): + lines_traces[line["state"]]["x"].extend((*self._edge_xs(line), None)) + lines_traces[line["state"]]["y"].extend((*self._edge_ys(line), None)) + # Traces for lines (grouped by color for better performance) + traces.extend( + go.Scatter( + x=t["x"], + y=t["y"], + mode="lines", + line={"color": self.colors[s], "width": 1.5}, + zorder=1, + hoverinfo="skip", + ) + for s, t in lines_traces.items() + if t["x"] # skip empty colors + ) + # Cannot hover on line traces, add invisible midpoint markers to show hover info + # https://github.com/plotly/plotly.js/issues/1960 + traces.append( + go.Scatter( + x=[sum(self._edge_xs(line)) / 2 for line in self.lines.values()], + y=[sum(self._edge_ys(line)) / 2 for line in self.lines.values()], + mode="markers", + marker={"opacity": 0, "color": [self.colors[ln["state"]] for ln in self.lines.values()]}, + customdata=[ + (ln_id, _pp_num(ln[loading_key]), _pp_num(ln["max_loading"])) for ln_id, ln in self.lines.items() + ], + hovertemplate=( + "Line: %{customdata[0]}" + "
Loading (%): %{customdata[1]}" + "
Loading limit (%): %{customdata[2]}" + "" + ), + ) + ) + + # Switches + if self.switches: + sw_traces: dict[ResultState, dict[str, list[float | None]]] = { + state: {"x": [], "y": []} for state in ("normal", "high", "very-high", "unknown") + } + for sw in self.switches.values(): + sw_traces[sw["state"]]["x"].extend((*self._edge_xs(sw), None)) + sw_traces[sw["state"]]["y"].extend((*self._edge_ys(sw), None)) + # Traces for switches (grouped by color for better performance) + traces.extend( + go.Scatter( + x=t["x"], + y=t["y"], + mode="lines", + line={"color": self.colors[s], "width": 5, "dash": "dash"}, + zorder=2, + hoverinfo="skip", + ) + for s, t in sw_traces.items() + if t["x"] # skip empty colors + ) + # Cannot hover on line traces, add invisible midpoint markers to show hover info + # https://github.com/plotly/plotly.js/issues/1960 + traces.append( + go.Scatter( + x=[sum(self._edge_xs(sw)) / 2 for sw in self.switches.values()], + y=[sum(self._edge_ys(sw)) / 2 for sw in self.switches.values()], + mode="markers", + marker={"opacity": 0, "color": [self.colors[sw["state"]] for sw in self.switches.values()]}, + customdata=list(self.switches), + hovertemplate="Switch: %{customdata}", + ) + ) + + return go.Figure( + data=traces, + layout=go.Layout( + title=self._title, + xaxis_title=self._xlabel, + yaxis_title=self._ylabel, + template="plotly_white", + margin={"l": 20, "r": 20, "t": 40, "b": 20}, + showlegend=False, + width=800, + ), + ) + + +def voltage_profile( + network: ElectricalNetwork, + *, + mode: Literal["min", "max"], + starting_bus_id: Id | None = None, + traverse_transformers: bool = False, + switch_length: float | None = None, + distance_unit: str = "km", +) -> _VoltageProfile[ElectricalNetwork, Literal["min", "max"]]: + """Create a voltage profile of the network. + + A voltage profile shows the voltage (in %) of buses in the network as a function of distance + from a starting bus. Lines and transformers are also represented, colored according to their + loading levels. + + The network does not need to have geometries defined for this function to work, as distances are + calculated based on line lengths. However, the network must have valid load flow results, and + relevant buses must have nominal voltages defined. + + Args: + network: + The electrical network to create the voltage profile for. + + mode: + The aggregation mode to use for bus voltages plots. `"min"` for the minimum voltage of + buses' phases, `"max"` for the maximum. + + starting_bus_id: + The ID of the bus to start the profile from. If None, the bus of the source with the + highest voltage is used. + + traverse_transformers: + If True, the entire network is traversed including transformers. If False, transformers + are not traversed. + + switch_length: + The length in km to assign to switches when calculating distances. If None, it is set to + the minimum of 2 meters and the shortest line in the network. Must be non-negative. + + distance_unit: + The unit to use for distances in the profile. Defaults to "km". + + Returns: + An object containing the voltage profile data for plotting. Use its plotting methods to + create plots. E.g., ``rlf.plotting.voltage_profile(en).plot_matplotlib()``. + """ + if not network.is_multi_phase: + raise TypeError("Only multi-phase networks can be plotted. Did you mean to use rlfs.plotting.voltage_profile?") + return _VoltageProfile._from_network( + network, + mode=mode, + starting_bus_id=starting_bus_id, + traverse_transformers=traverse_transformers, + switch_length=switch_length, + distance_unit=distance_unit, + ) diff --git a/roseau/load_flow/tests/test_converters.py b/roseau/load_flow/tests/test_converters.py index aee34610..d97894b7 100644 --- a/roseau/load_flow/tests/test_converters.py +++ b/roseau/load_flow/tests/test_converters.py @@ -1,6 +1,7 @@ import numpy as np +import pytest -from roseau.load_flow.converters import calculate_voltages +from roseau.load_flow.converters import calculate_voltages, kron_reduction from roseau.load_flow.units import Q_, ureg @@ -28,3 +29,29 @@ def test_calculate_voltages(): np.testing.assert_allclose(voltages.m, np.array([230.0 - 230.0j, 460.0j, -230.0 - 230.0j])) voltages = calculate_voltages([230, 230j, -230j, 0], "abcn") np.testing.assert_allclose(voltages.m, np.array([230.0, 230.0j, -230.0j])) + + +def test_kron_reduction(): + nxn = np.array( + [ + [10, 2, 3, 4], + [2, 20, 5, 6], + [3, 5, 30, 7], + [4, 6, 7, 40], + ], + dtype=np.complex128, + ) + reduced = kron_reduction(nxn) + expected = np.array( + # New_ij = Old_ij - Old_in * Old_nj / Old_nn; i, j ∈ {1,...,n-1} + [ + [10 - 4 * 4 / 40, 2 - 4 * 6 / 40, 3 - 4 * 7 / 40], + [2 - 6 * 4 / 40, 20 - 6 * 6 / 40, 5 - 6 * 7 / 40], + [3 - 7 * 4 / 40, 5 - 7 * 6 / 40, 30 - 7 * 7 / 40], + ], + dtype=np.complex128, + ) + np.testing.assert_allclose(reduced, expected) + + with pytest.raises(ValueError, match=r"Matrix must be square, got shape \(3, 4\)."): + kron_reduction(nxn[:3, :4]) diff --git a/roseau/load_flow/tests/test_deprecations.py b/roseau/load_flow/tests/test_deprecations.py index dc73cf31..3d2c6257 100644 --- a/roseau/load_flow/tests/test_deprecations.py +++ b/roseau/load_flow/tests/test_deprecations.py @@ -1,59 +1,6 @@ -import importlib - import pytest -from roseau.load_flow import Insulator, Material, constants, converters, utils - - -def test_moved_names(): - # utils -> constants - for name in ( - "ALPHA", - "ALPHA2", - "PI", - "MU_0", - "EPSILON_0", - "F", - "OMEGA", - "RHO", - "MU_R", - "DELTA_P", - "TAN_D", - "EPSILON_R", - ): - with pytest.warns( - FutureWarning, - match=f"Importing {name} from 'roseau.load_flow.utils' is deprecated. Use 'rlf.constants.{name}' instead.", - ): - getattr(utils, name) - # utils -> sym - for name in ("PositiveSequence", "NegativeSequence", "ZeroSequence"): - with pytest.warns( - FutureWarning, - match=f"Importing {name} from 'roseau.load_flow.utils' is deprecated. Use 'rlf.sym.{name}' instead.", - ): - getattr(utils, name) - # utils -> types - for name in ("LineType", "Material", "Insulator"): - with pytest.warns( - FutureWarning, - match=f"Importing {name} from 'roseau.load_flow.utils' is deprecated. Use 'rlf.types.{name}' instead.", - ): - getattr(utils, name) - # constants -> sym - for name in ("PositiveSequence", "NegativeSequence", "ZeroSequence"): - with pytest.warns( - FutureWarning, - match=f"'rlf.constants.{name}' is deprecated. Use 'rlf.sym.{name}' instead.", - ): - getattr(constants, name) - # converters -> sym - for name in ("phasor_to_sym", "sym_to_phasor", "series_phasor_to_sym"): - with pytest.warns( - FutureWarning, - match=f"'rlf.converters.{name}' is deprecated. Use 'rlf.sym.{name}' instead.", - ): - getattr(converters, name) +from roseau.load_flow import Insulator, Material def test_renamed_classes(): @@ -68,19 +15,5 @@ def test_renamed_classes(): def test_non_existent_name(): from roseau import load_flow - for mod in (utils, constants, converters, load_flow): - with pytest.raises(AttributeError, match=f"module '{mod.__name__}' has no attribute 'non_existent_name'"): - _ = mod.non_existent_name - - -def test_deprecated_utils_modules(): - with pytest.warns( - FutureWarning, - match="Module 'roseau.load_flow.utils.constants' is deprecated. Use 'rlf.constants' directly instead.", - ): - importlib.import_module("roseau.load_flow.utils.constants") - with pytest.warns( - FutureWarning, - match="Module 'roseau.load_flow.utils.types' is deprecated. Use 'rlf.types' directly instead.", - ): - importlib.import_module("roseau.load_flow.utils.types") + with pytest.raises(AttributeError, match=f"module '{load_flow.__name__}' has no attribute 'non_existent_name'"): + _ = load_flow.non_existent_name diff --git a/roseau/load_flow/tests/test_electrical_network.py b/roseau/load_flow/tests/test_electrical_network.py index 3de695f0..13d64e83 100644 --- a/roseau/load_flow/tests/test_electrical_network.py +++ b/roseau/load_flow/tests/test_electrical_network.py @@ -123,16 +123,7 @@ def test_connect_and_disconnect(): assert load.is_disconnected assert repr(load) == " (disconnected)" assert load.network is None - with pytest.warns( - UserWarning, - match=( - r"Accessing the bus of the disconnected load 'power load' will change in the future to " - r"return the bus it was connected to before disconnection instead of None. If you rely " - r"on this behavior to check if the element is disconnected, please use `is_disconnected` " - r"instead" - ), - ): - assert load.bus is None + assert load.bus is load_bus with pytest.raises(RoseauLoadFlowException) as e: load.to_dict() assert e.value.msg == "The load 'power load' is disconnected and cannot be used anymore." @@ -156,16 +147,7 @@ def test_connect_and_disconnect(): assert vs.is_disconnected assert vs.network is None assert repr(vs) == " (disconnected)" - with pytest.warns( - UserWarning, - match=( - r"Accessing the bus of the disconnected source 'vs' will change in the future to " - r"return the bus it was connected to before disconnection instead of None. If you rely " - r"on this behavior to check if the element is disconnected, please use `is_disconnected` " - r"instead" - ), - ): - assert vs.bus is None + assert vs.bus is source_bus with pytest.raises(RoseauLoadFlowException) as e: vs.to_dict() assert e.value.msg == "The source 'vs' is disconnected and cannot be used anymore." @@ -755,7 +737,7 @@ def test_buses_voltages(small_network_with_results): pd.DataFrame.from_records(voltage_records) .astype( { - "bus_id": str, + "bus_id": object, "phase": VoltagePhaseDtype, "voltage": complex, "voltage_level": float, @@ -835,7 +817,7 @@ def test_single_phase_network(single_phase_network: ElectricalNetwork): {"bus_id": "bus1", "phase": "n", "potential": 0j}, ] ) - .astype({"phase": PhaseDtype, "potential": complex}) + .astype({"bus_id": object, "phase": PhaseDtype, "potential": complex}) .set_index(["bus_id", "phase"]), ) # Buses voltages results @@ -867,6 +849,7 @@ def test_single_phase_network(single_phase_network: ElectricalNetwork): ) .astype( { + "bus_id": object, "phase": VoltagePhaseDtype, "voltage": complex, "voltage_level": float, @@ -901,6 +884,7 @@ def test_single_phase_network(single_phase_network: ElectricalNetwork): ) .astype( { + "transformer_id": object, "phase": PhaseDtype, "current_hv": complex, "current_lv": complex, @@ -963,6 +947,7 @@ def test_single_phase_network(single_phase_network: ElectricalNetwork): ) .astype( { + "line_id": object, "phase": PhaseDtype, "current1": complex, "current2": complex, @@ -999,6 +984,7 @@ def test_single_phase_network(single_phase_network: ElectricalNetwork): ) .astype( { + "switch_id": object, "phase": PhaseDtype, "current1": complex, "current2": complex, @@ -1034,7 +1020,14 @@ def test_single_phase_network(single_phase_network: ElectricalNetwork): ] ) .astype( - {"phase": PhaseDtype, "type": LoadTypeDtype, "current": complex, "power": complex, "potential": complex} + { + "load_id": object, + "phase": PhaseDtype, + "type": LoadTypeDtype, + "current": complex, + "power": complex, + "potential": complex, + } ) .set_index(["load_id", "phase"]), ) @@ -1911,6 +1904,19 @@ def test_propagate_voltages(): load_bus.initial_potentials.m, 100 * np.array([1, np.exp(-2j * np.pi / 3), np.exp(2j * np.pi / 3), 0]) ) + # Delta vs Wye + bus = Bus("Bus", phases="abcn") + src_y = VoltageSource("Y src", bus=bus, phases="an", voltages=230) + VoltageSource("D src", bus=bus, phases="bc", voltages=300) + PotentialRef(id="pref", element=bus) + en = ElectricalNetwork.from_element(bus) + main_v, main_src = en._get_starting_potentials(set("abcn")) + assert main_src is src_y # Y has lower V input but higher Vphase-phase value than D + assert main_v["a"] == 230 + src_y.disconnect() # now the voltages of the delta source are used + main_v, main_src = en._get_starting_potentials(set("abcn")) + npt.assert_allclose(abs(main_v["a"] - main_v["b"]), 300) + def test_short_circuits(): vn = 400 / np.sqrt(3) @@ -2098,6 +2104,7 @@ def test_to_graph(all_element_network: ElectricalNetwork): "parameters_id": transformer.parameters.id, "max_loading": max_loading, "sn": transformer.sn.magnitude, + "tap": transformer.tap, "geom": transformer.geometry.__geo_interface__ if transformer.geometry is not None else None, } @@ -2153,6 +2160,50 @@ def test_to_graph(all_element_network: ElectricalNetwork): json.dumps(json_data, ensure_ascii=False) +def test_propagate_nominal_voltages(all_element_network, small_network): + en = all_element_network + # Test that it works even if some nominal voltages are missing + assert en.buses["bus0"].nominal_voltage is None + assert en.buses["bus4"].nominal_voltage is None + assert en.buses["bus6"].nominal_voltage is None + nominal_voltages = en._get_nominal_voltages() + assert nominal_voltages == { + "bus1": 20000.0, + "bus2": 400, + "bus3": 400, + "bus5": 400, + "bus0": 20000.0, + "bus4": 400, + "bus6": 400, + } + + # No nominal voltages in the network + for bus in en.buses.values(): + bus._min_voltage_level = None + bus._max_voltage_level = None + bus._nominal_voltage = None + nominal_voltages = en._get_nominal_voltages() + assert nominal_voltages == { + "bus1": 20000.0, + "bus2": 410, # not exactly 400V but close enough for determining the voltage level + "bus3": 410, + "bus5": 410, + "bus0": 20000.0, + "bus4": 410, + "bus6": 410, + } + + # No transformer + en = small_network + assert not en.transformers, "This test requires a network without transformers" + for bus in en.buses.values(): + bus._min_voltage_level = None + bus._max_voltage_level = None + bus._nominal_voltage = None + nominal_voltages = en._get_nominal_voltages() + npt.assert_allclose(list(nominal_voltages.values()), 20e3 * np.sqrt(3)) + + def test_serialization(all_element_network, all_element_network_with_results): def assert_results(en_dict: dict, included: bool): for bus_data in en_dict["buses"]: diff --git a/roseau/load_flow/tests/test_plotting.py b/roseau/load_flow/tests/test_plotting.py index 25ceac74..05a0725c 100644 --- a/roseau/load_flow/tests/test_plotting.py +++ b/roseau/load_flow/tests/test_plotting.py @@ -15,7 +15,13 @@ TransformerParameters, VoltageSource, ) -from roseau.load_flow.plotting import plot_symmetrical_voltages, plot_voltage_phasors +from roseau.load_flow.network import ElectricalNetwork +from roseau.load_flow.plotting import ( + plot_interactive_map, + plot_results_interactive_map, + plot_symmetrical_voltages, + plot_voltage_phasors, +) from roseau.load_flow.sym import PositiveSequence @@ -36,36 +42,40 @@ def subplots(nrows, ncols): yield m -bus = Bus(id="Bus", phases="abcn") -source = VoltageSource(id="Source", bus=bus, phases="abcn", voltages=230) -load = PowerLoad(id="Load", bus=bus, phases="abcn", powers=1e3) -potentials = 230 * np.array([*PositiveSequence, 0.0j]) -currents = 1e3 / np.array([*potentials[:3], np.inf]) -bus._res_potentials = np.array(potentials, dtype=np.complex128) -load._res_potentials = np.array(potentials, dtype=np.complex128) -load._res_currents = np.array(currents, dtype=np.complex128) -source._res_potentials = np.array(potentials, dtype=np.complex128) -source._res_currents = np.array(-currents, dtype=np.complex128) -bus_single = rlfs.Bus(id="Bus") -bus_single._res_voltage = 400 + 0j +@pytest.fixture(scope="module") +def elements(): + bus = Bus(id="Bus", phases="abcn") + source = VoltageSource(id="Source", bus=bus, phases="abcn", voltages=230) + load = PowerLoad(id="Load", bus=bus, phases="abcn", powers=1e3) + potentials = 230 * np.array([*PositiveSequence, 0.0j]) + currents = 1e3 / np.array([*potentials[:3], np.inf]) + bus._res_potentials = np.array(potentials, dtype=np.complex128) + load._res_potentials = np.array(potentials, dtype=np.complex128) + load._res_currents = np.array(currents, dtype=np.complex128) + source._res_potentials = np.array(potentials, dtype=np.complex128) + source._res_currents = np.array(-currents, dtype=np.complex128) + bus_single = rlfs.Bus(id="Bus") + bus_single._res_voltage = 400 + 0j + return {"bus": bus, "load": load, "source": source, "bus_single": bus_single} @pytest.mark.usefixtures("mock_gca") @pytest.mark.parametrize( - ("element", "voltage_type"), + ("element_key", "voltage_type"), ( - pytest.param(bus, "auto", id="Bus"), - pytest.param(bus, "pp", id="Bus-pp"), - pytest.param(bus, "pn", id="Bus-pn"), - pytest.param(load, "auto", id="Load"), - pytest.param(source, "auto", id="Source"), + pytest.param("bus", "auto", id="Bus"), + pytest.param("bus", "pp", id="Bus-pp"), + pytest.param("bus", "pn", id="Bus-pn"), + pytest.param("load", "auto", id="Load"), + pytest.param("source", "auto", id="Source"), ), ) -def test_plot_voltage_phasors(element, voltage_type): +def test_plot_voltage_phasors(element_key, voltage_type, elements): + element = elements[element_key] ax = plot_voltage_phasors(element, voltage_type=voltage_type) # The title is set to the element's id - ax.set_title.assert_called_once_with(f"{element.id}") + ax.set_title.assert_called_once_with(f"{element.id}") # type: ignore ua, ub, uc, un = element._res_potentials if voltage_type == "pp": @@ -76,20 +86,20 @@ def test_plot_voltage_phasors(element, voltage_type): voltages = [(ua, un), (ub, un), (uc, un)] # Draws three (3P) or four (3P+N) potential points - assert ax.scatter.call_count == n - for u, phase, call in zip(element._res_potentials[:n], element.phases[:n], ax.scatter.call_args_list, strict=True): + assert ax.scatter.call_count == n # type: ignore + for u, phase, call in zip(element._res_potentials[:n], element.phases[:n], ax.scatter.call_args_list, strict=True): # type: ignore assert call.args == (u.real, u.imag) assert call.kwargs["label"] == phase # Draws three voltage phasors - assert ax.arrow.call_count == 3 - for (u1, u2), call in zip(voltages, ax.arrow.call_args_list, strict=True): + assert ax.arrow.call_count == 3 # type: ignore + for (u1, u2), call in zip(voltages, ax.arrow.call_args_list, strict=True): # type: ignore npt.assert_allclose(call.args, (u2.real, u2.imag, u1.real - u2.real, u1.imag - u2.imag)) assert "label" not in call.kwargs @pytest.mark.usefixtures("mock_gca") -def test_plot_voltage_phasors_errors(): +def test_plot_voltage_phasors_errors(elements): bus_abc = Bus(id="Bus", phases="abc") bus_an = Bus(id="Bus", phases="an") bus_abc._res_potentials = np.array(20e3 * PositiveSequence, dtype=np.complex128) @@ -97,9 +107,9 @@ def test_plot_voltage_phasors_errors(): # By default both work ax = plot_voltage_phasors(bus_abc) - assert ax.scatter.call_count == 3 + assert ax.scatter.call_count == 3 # type: ignore ax = plot_voltage_phasors(bus_an) - assert ax.scatter.call_count == 2 + assert ax.scatter.call_count == 2 # type: ignore # 'pn' without neutral with pytest.raises(ValueError, match=r"The element must have a neutral to plot phase-to-neutral voltages"): @@ -113,11 +123,8 @@ def test_plot_voltage_phasors_errors(): with pytest.raises(ValueError, match=r"Invalid voltage_type: 'bad'"): plot_voltage_phasors(bus_abc, voltage_type="bad") # type: ignore - # Bad side - with pytest.raises(ValueError, match=r"The side argument is only valid for branch elements"): - plot_voltage_phasors(bus_abc, side="HV") # type: ignore - # Not a multi-phase element + bus_single = elements["bus_single"] with pytest.raises(TypeError, match=r"Only multi-phase elements can be plotted. Did you mean to use rlf.Bus\?"): plot_voltage_phasors(bus_single) # type: ignore @@ -141,75 +148,55 @@ def test_plot_voltage_phasors_branches(): tr.side_hv._res_potentials = np.array(potentials, dtype=np.complex128) tr.side_lv._res_potentials = np.array(potentials / 2, dtype=np.complex128) - # Bad side - with pytest.raises(ValueError, match=r"The side for a switch must be one of \(1, 2\)"): - plot_voltage_phasors(sw) # type: ignore - with pytest.raises(ValueError, match=r"The side for a line must be one of \(1, 2\)"): - plot_voltage_phasors(ln) # type: ignore - with pytest.raises(ValueError, match=r"The side for a transformer must be one of \('HV', 'LV'\)"): - plot_voltage_phasors(tr) # type: ignore - with pytest.raises(ValueError, match=r"Invalid side: 'bad'"): - plot_voltage_phasors(tr, side="bad") # type: ignore - # Switches warnings ax = plot_voltage_phasors(sw.side1) - ax.set_title.assert_called_once_with("Sw (1)") + ax.set_title.assert_called_once_with("Sw (1)") # type: ignore ax = plot_voltage_phasors(sw.side2) - ax.set_title.assert_called_once_with("Sw (2)") + ax.set_title.assert_called_once_with("Sw (2)") # type: ignore # Lines ax = plot_voltage_phasors(ln.side1) - ax.set_title.assert_called_once_with("Ln (1)") + ax.set_title.assert_called_once_with("Ln (1)") # type: ignore ax = plot_voltage_phasors(ln.side2) - ax.set_title.assert_called_once_with("Ln (2)") + ax.set_title.assert_called_once_with("Ln (2)") # type: ignore # Transformers ax = plot_voltage_phasors(tr.side_hv) - ax.set_title.assert_called_once_with("Tr (HV)") - npt.assert_allclose(abs(complex(*ax.scatter.call_args.args)), 20e3) + ax.set_title.assert_called_once_with("Tr (HV)") # type: ignore + npt.assert_allclose(abs(complex(*ax.scatter.call_args.args)), 20e3) # type: ignore ax = plot_voltage_phasors(tr.side_lv) - ax.set_title.assert_called_once_with("Tr (LV)") - npt.assert_allclose(abs(complex(*ax.scatter.call_args.args)), 10e3) - - # Deprecations - for element, side, element_type, side_suffix, expected_id in [ - (sw, 1, "switch", "1", "Sw (1)"), - (sw, 2, "switch", "2", "Sw (2)"), - (ln, 1, "line", "1", "Ln (1)"), - (ln, 2, "line", "2", "Ln (2)"), - (tr, "HV", "transformer", "_hv", "Tr (HV)"), - (tr, "LV", "transformer", "_lv", "Tr (LV)"), - ]: - with pytest.warns( - DeprecationWarning, - match=( - rf"Plotting the voltages of a {element_type} using the side argument is deprecated. " - rf"Use {element_type}.side{side_suffix} directly instead." - ), - ): - ax = plot_voltage_phasors(element, side=side) - ax.set_title.assert_called_once_with(expected_id) + ax.set_title.assert_called_once_with("Tr (LV)") # type: ignore + npt.assert_allclose(abs(complex(*ax.scatter.call_args.args)), 10e3) # type: ignore @pytest.mark.usefixtures("mock_subplots") -def test_plot_symmetrical_voltages(): +def test_plot_symmetrical_voltages(elements): + bus = elements["bus"] ax0, ax1, ax2 = plot_symmetrical_voltages(bus) # The title is set to the element's id - ax0.set_title.assert_called_once_with(f"{bus.id}\nZero Sequence") - ax1.set_title.assert_called_once_with(f"{bus.id}\nPositive Sequence") - ax2.set_title.assert_called_once_with(f"{bus.id}\nNegative Sequence") + ax0.set_title.assert_called_once_with(f"{bus.id}\nZero Sequence") # type: ignore + ax1.set_title.assert_called_once_with(f"{bus.id}\nPositive Sequence") # type: ignore + ax2.set_title.assert_called_once_with(f"{bus.id}\nNegative Sequence") # type: ignore ua, ub, uc, un = bus._res_potentials # type: ignore - assert ax0.scatter.call_count == 2 # 1 "abc" + 1 "n" - assert ax0.arrow.call_count == 1 - assert ax0.annotate.call_count == 1 + assert ax0.scatter.call_count == 2 # 1 "abc" + 1 "n" # type: ignore + assert ax0.arrow.call_count == 1 # type: ignore + assert ax0.annotate.call_count == 1 # type: ignore for ax in (ax1, ax2): - assert ax.scatter.call_count == 3 # 1 "a" + "b" + "c" - assert ax.arrow.call_count == 3 - assert ax.annotate.call_count == 1 + assert ax.scatter.call_count == 3 # 1 "a" + "b" + "c" # type: ignore + assert ax.arrow.call_count == 3 # type: ignore + assert ax.annotate.call_count == 1 # type: ignore # Not a multi-phase element + bus_single = elements["bus_single"] with pytest.raises(TypeError, match=r"Only multi-phase elements can be plotted. Did you mean to use rlf.Bus\?"): plot_symmetrical_voltages(bus_single) # type: ignore + + +def test_plot_interactive_map(test_networks_path): + en = ElectricalNetwork.from_json(path=test_networks_path / "all_element_network.json", include_results=True) + en.crs = "EPSG:4326" + plot_interactive_map(en) + plot_results_interactive_map(en) diff --git a/roseau/load_flow/typing.py b/roseau/load_flow/typing.py index b449349f..9412a03e 100644 --- a/roseau/load_flow/typing.py +++ b/roseau/load_flow/typing.py @@ -116,7 +116,7 @@ import os from collections.abc import Mapping, Sequence -from typing import Any, Literal, Protocol, TypeAlias, TypeVar +from typing import Any, Literal, Protocol import numpy as np from numpy.typing import NDArray @@ -124,38 +124,37 @@ from roseau.load_flow.units import Q_ -T = TypeVar("T", bound=Any) - class _SupportsToWkt(Protocol): def to_wkt(self) -> str: ... # RLF Helpers -Id: TypeAlias = int | str -JsonDict: TypeAlias = dict[str, Any] -StrPath: TypeAlias = str | os.PathLike[str] -MapOrSeq: TypeAlias = Mapping[int, T] | Mapping[str, T] | Mapping[Id, T] | Sequence[T] -QtyOrMag: TypeAlias = Q_[T] | T +type Id = int | str +type JsonDict = dict[str, Any] +type StrPath = str | os.PathLike[str] +type MapOrSeq[T] = Mapping[int, T] | Mapping[str, T] | Mapping[Id, T] | Sequence[T] +type QtyOrMag[T: Any] = Q_[T] | T # RLF Literals -ControlType: TypeAlias = Literal["constant", "p_max_u_production", "p_max_u_consumption", "q_u"] -ProjectionType: TypeAlias = Literal["euclidean", "keep_p", "keep_q"] -Solver: TypeAlias = Literal["newton", "newton_goldstein", "backward_forward"] -Side: TypeAlias = Literal[1, 2, "HV", "LV"] +type ControlType = Literal["constant", "p_max_u_production", "p_max_u_consumption", "q_u"] +type ProjectionType = Literal["euclidean", "keep_p", "keep_q"] +type Solver = Literal["newton", "newton_goldstein", "backward_forward"] +type Side = Literal[1, 2, "HV", "LV"] +type ResultState = Literal["very-low", "low", "normal", "high", "very-high", "unknown"] # Input Types (Wide) -Int: TypeAlias = int | np.integer -Float: TypeAlias = float | np.floating | Int -Complex: TypeAlias = complex | np.complexfloating[Any, Any] | Float -ComplexArrayLike1D: TypeAlias = QtyOrMag[NDArray[np.number] | Sequence[Complex]] | Sequence[QtyOrMag[Complex]] -ComplexScalarOrArrayLike1D: TypeAlias = ComplexArrayLike1D | QtyOrMag[Complex] -ComplexArrayLike2D: TypeAlias = ( +type Int = int | np.integer +type Float = float | np.floating | Int +type Complex = complex | np.complexfloating[Any, Any] | Float +type ComplexArrayLike1D = QtyOrMag[NDArray[np.number] | Sequence[Complex]] | Sequence[QtyOrMag[Complex]] +type ComplexScalarOrArrayLike1D = ComplexArrayLike1D | QtyOrMag[Complex] +type ComplexArrayLike2D = ( QtyOrMag[NDArray[np.number] | Sequence[Sequence[Complex]]] | Sequence[Sequence[QtyOrMag[Complex]]] ) -FloatArrayLike1D: TypeAlias = QtyOrMag[NDArray[np.floating | np.integer] | Sequence[Float]] | Sequence[QtyOrMag[Float]] -FloatScalarOrArrayLike1D: TypeAlias = FloatArrayLike1D | QtyOrMag[Float] -CRSLike: TypeAlias = ( +type FloatArrayLike1D = QtyOrMag[NDArray[np.floating | np.integer] | Sequence[Float]] | Sequence[QtyOrMag[Float]] +type FloatScalarOrArrayLike1D = FloatArrayLike1D | QtyOrMag[Float] +type CRSLike = ( # The following are documented in the pyproj.CRS class # - PROJ string # - JSON string with PROJ parameters @@ -175,11 +174,11 @@ def to_wkt(self) -> str: ... ) # Numpy Output Types (Narrow) -ComplexMatrix: TypeAlias = np.ndarray[tuple[int, int], np.dtype[np.complex128]] # 2D -FloatMatrix: TypeAlias = np.ndarray[tuple[int, int], np.dtype[np.float64]] # 2D -ComplexArray: TypeAlias = np.ndarray[tuple[int], np.dtype[np.complex128]] # 1D -FloatArray: TypeAlias = np.ndarray[tuple[int], np.dtype[np.float64]] # 1D -BoolArray: TypeAlias = np.ndarray[tuple[int], np.dtype[np.bool_]] # 1D +type ComplexMatrix = np.ndarray[tuple[int, int], np.dtype[np.complex128]] # 2D +type FloatMatrix = np.ndarray[tuple[int, int], np.dtype[np.float64]] # 2D +type ComplexArray = np.ndarray[tuple[int], np.dtype[np.complex128]] # 1D +type FloatArray = np.ndarray[tuple[int], np.dtype[np.float64]] # 1D +type BoolArray = np.ndarray[tuple[int], np.dtype[np.bool_]] # 1D __all__ = [ # Helpers diff --git a/roseau/load_flow/units.py b/roseau/load_flow/units.py index e38f9524..ce28fbd5 100644 --- a/roseau/load_flow/units.py +++ b/roseau/load_flow/units.py @@ -28,7 +28,7 @@ from inspect import Parameter, Signature, signature from itertools import zip_longest from types import GenericAlias -from typing import TYPE_CHECKING, Any, TypeAlias, TypeVar, overload +from typing import TYPE_CHECKING, Any, Protocol, TypeVar, overload import numpy as np from numpy.typing import NDArray @@ -47,19 +47,16 @@ if TYPE_CHECKING: # Copy types from pint and add complex - Scalar: TypeAlias = int | float | Decimal | Fraction | complex | np.number[Any] - Array: TypeAlias = np.ndarray[Any, Any] - UnitLike = str | dict[str, Scalar] | UnitsContainer | Unit - - NpNumT = TypeVar("NpNumT", bound=np.number[Any]) - MagBound = Scalar | Array | Sequence[Scalar | Array] | Sequence[Sequence[Scalar | Array]] - MagT = TypeVar("MagT", bound=MagBound) - MagT_co = TypeVar("MagT_co", covariant=True, bound=MagBound) + type Scalar = int | float | Decimal | Fraction | complex | np.number[Any] + type Array = np.ndarray[Any, Any] + type UnitLike = str | dict[str, Scalar] | UnitsContainer | Unit + type Magnitude = Scalar | Array | Sequence[Scalar | Array] | Sequence[Sequence[Scalar | Array]] + M_co = TypeVar("M_co", covariant=True, bound=Magnitude) # Redefine Q_ with support for complex and better type hints - class Q_(NumpyQuantity[MagT_co]): # type: ignore # noqa: N801 + class Q_(NumpyQuantity[M_co]): # type: ignore # noqa: N801 @overload # Known magnitude type - def __new__(cls, value: MagT, units: UnitLike | None = None) -> "Q_[MagT]": ... + def __new__[M: Magnitude](cls, value: M, units: UnitLike | None = None) -> "Q_[M]": ... @overload # Unknown magnitude type def __new__(cls, value: str, units: UnitLike | None = None) -> "Q_[Any]": ... @@ -80,20 +77,20 @@ def __new__( ) -> "Q_[NDArray[np.complex128]]": ... @overload # numpy number sequence becomes array with same dtype - def __new__( - cls, value: Sequence[NpNumT | Sequence[NpNumT]], units: UnitLike | None = None - ) -> "Q_[NDArray[NpNumT]]": ... + def __new__[N: np.number]( + cls, value: Sequence[N | Sequence[N]], units: UnitLike | None = None + ) -> "Q_[NDArray[N]]": ... @overload # quantity gets passed through (copied) when units are None - def __new__(cls, value: "Q_[MagT]", units: None = None) -> "Q_[MagT]": ... + def __new__[M: Magnitude](cls, value: "Q_[M]", units: None = None) -> "Q_[M]": ... @overload # quantity may get altered when units are not None (conversion) def __new__(cls, value: "Q_[Any]", units: UnitLike | None = None) -> "Q_[Any]": ... - def __new__(cls, value: MagT_co, units: UnitLike | None = None) -> "Q_[MagT_co]": # type: ignore + def __new__(cls, value: M_co, units: UnitLike | None = None) -> "Q_[M_co]": # type: ignore return super().__new__(cls, value, units) # type: ignore - def __init__(self, value: MagT_co, units: UnitLike | None = None) -> None: + def __init__(self, value: M_co, units: UnitLike | None = None) -> None: super().__init__(value, units) # type: ignore # for PyCharm only, it does not recognize __new__ alone def __getattr__(self, name: str) -> Any: ... # attributes of the magnitude are accessible on the quantity @@ -102,11 +99,14 @@ def __getattr__(self, name: str) -> Any: ... # attributes of the magnitude are ureg.Quantity.__class_getitem__ = classmethod(GenericAlias) globals()["Q_"] = ureg.Quantity # Use globals() to trick PyCharm -FuncT = TypeVar("FuncT", bound=Callable) -OptionalUnits: TypeAlias = str | Unit | None | tuple[str | Unit | None, ...] | list[str | Unit | None] +type OptionalUnits = str | Unit | None | tuple[str | Unit | None, ...] | list[str | Unit | None] + + +class _IdentityFunction(Protocol): + def __call__[F: Callable](self, fn: F, /) -> F: ... -def ureg_wraps(ret: OptionalUnits, args: OptionalUnits, strict: bool = True) -> Callable[[FuncT], FuncT]: +def ureg_wraps(ret: OptionalUnits, args: OptionalUnits, strict: bool = True) -> _IdentityFunction: """Wraps a function to become pint-aware. Args: @@ -130,7 +130,7 @@ def _parse_wrap_args(args: Iterable[str | Unit | None]) -> Callable: # Check for references in args, remove None values unit_args_ndx = {ndx for ndx, arg in enumerate(args_as_uc) if arg is not None} - def _converter(ureg: "UnitRegistry", sig: "Signature", values: "list[Any]", kw: "dict[Any]"): + def _converter(ureg: "UnitRegistry", sig: "Signature", values: "list[Any]", kw: "dict[str, Any]"): len_initial_values = len(values) # pack kwargs @@ -171,7 +171,7 @@ def _apply_defaults(sig: Signature, args: tuple[Any], kwargs: dict[str, Any]) -> return list(args), kwargs -def wraps(ureg: UnitRegistry, ret: OptionalUnits, args: OptionalUnits) -> Callable[[FuncT], FuncT]: +def wraps(ureg: UnitRegistry, ret: OptionalUnits, args: OptionalUnits) -> _IdentityFunction: """Wraps a function to become pint-aware. Use it when a function requires a numerical value but in some specific diff --git a/roseau/load_flow/utils/__init__.py b/roseau/load_flow/utils/__init__.py index bc49c839..932f8621 100644 --- a/roseau/load_flow/utils/__init__.py +++ b/roseau/load_flow/utils/__init__.py @@ -17,7 +17,6 @@ SourceTypeDtype, VoltagePhaseDtype, ) -from roseau.load_flow.utils.exceptions import find_stack_level from roseau.load_flow.utils.helpers import ( SIDE_DESC, SIDE_INDEX, @@ -29,6 +28,7 @@ geom_mapping, id_sort_key, one_or_more_repr, + warn_external, ) from roseau.load_flow.utils.log import set_logging_config from roseau.load_flow.utils.mixins import AbstractElement, AbstractNetwork, CatalogueMixin, Identifiable, JsonMixin @@ -42,7 +42,7 @@ "AbstractElement", "AbstractNetwork", # Exceptions and warnings - "find_stack_level", + "warn_external", "deprecate_nonkeyword_arguments", "deprecate_parameter_as_multi_positional", "deprecate_renamed_parameter", @@ -74,54 +74,3 @@ "SIDE_INDEX", "SIDE_SUFFIX", ] - - -def __getattr__(name: str): - import warnings - - deprecation_template = ( - "Importing {name} from 'roseau.load_flow.utils' is deprecated. Use 'rlf.{module}.{name}' instead." - ) - if name in ( - "ALPHA", - "ALPHA2", - "PI", - "SQRT3", - "DELTA_P", - "EPSILON_0", - "EPSILON_R", - "F", - "MU_0", - "MU_R", - "OMEGA", - "RHO", - "TAN_D", - ): - # deprecated since 0.12.0 - warnings.warn( - deprecation_template.format(name=name, module="constants"), - category=FutureWarning, - stacklevel=find_stack_level(), - ) - from roseau.load_flow import constants - - return getattr(constants, name) - elif name in ("PositiveSequence", "NegativeSequence", "ZeroSequence"): - warnings.warn( - deprecation_template.format(name=name, module="sym"), - category=FutureWarning, - stacklevel=find_stack_level(), - ) - from roseau.load_flow import sym - - return getattr(sym, name) - elif name in ("LineType", "Material", "Insulator"): - warnings.warn( - deprecation_template.format(name=name, module="types"), - category=FutureWarning, - stacklevel=find_stack_level(), - ) - from roseau.load_flow import types - - return getattr(types, name) - raise AttributeError(f"module '{__name__}' has no attribute '{name}'") diff --git a/roseau/load_flow/utils/constants.py b/roseau/load_flow/utils/constants.py deleted file mode 100644 index ec2bed60..00000000 --- a/roseau/load_flow/utils/constants.py +++ /dev/null @@ -1,12 +0,0 @@ -import warnings - -warnings.warn( - "Module 'roseau.load_flow.utils.constants' is deprecated. Use 'rlf.constants' directly instead.", - category=FutureWarning, - stacklevel=2, -) -# ruff: noqa: E402, F401 -# pyright: reportUnusedImport=none -# deprecated since 0.12.0 -from roseau.load_flow.constants import DELTA_P, EPSILON_0, EPSILON_R, MU_0, MU_R, OMEGA, PI, RHO, TAN_D, F -from roseau.load_flow.sym import ALPHA, ALPHA2, NegativeSequence, PositiveSequence, ZeroSequence diff --git a/roseau/load_flow/utils/deprecations.py b/roseau/load_flow/utils/deprecations.py index 64079973..8b9eaabc 100644 --- a/roseau/load_flow/utils/deprecations.py +++ b/roseau/load_flow/utils/deprecations.py @@ -3,18 +3,13 @@ # under the MIT license. # polars source code is available at https://github.com/pola-rs/polars import inspect -import warnings from collections.abc import Callable, Mapping, Sequence from functools import wraps -from typing import ParamSpec, TypeVar -from roseau.load_flow.utils.exceptions import find_stack_level +from roseau.load_flow.utils.helpers import warn_external -P = ParamSpec("P") -T = TypeVar("T") - -def deprecate_renamed_parameters( +def deprecate_renamed_parameters[**P, T]( replaced_names: Mapping[str, str], *, version: str, category: type[Warning] = FutureWarning ) -> Callable[[Callable[P, T]], Callable[P, T]]: """Decorator to mark function parameters as deprecated due to being renamed. @@ -36,13 +31,12 @@ def wrapper(*args: P.args, **kwargs: P.kwargs) -> T: f"{func_name}() got both {old_name!r} and {new_name!r} as arguments; " f"{old_name!r} is deprecated, use {new_name!r} instead." ) - warnings.warn( + warn_external( message=( f"Argument {old_name!r} for {func_name}() is deprecated. It has been " f"renamed to {new_name!r}." ), category=category, - stacklevel=find_stack_level(), ) kwargs[new_name] = kwargs.pop(old_name) return function(*args, **kwargs) @@ -53,7 +47,7 @@ def wrapper(*args: P.args, **kwargs: P.kwargs) -> T: return decorate -def deprecate_renamed_parameter( +def deprecate_renamed_parameter[**P, T]( old_name: str, new_name: str, *, version: str, category: type[Warning] = FutureWarning ) -> Callable[[Callable[P, T]], Callable[P, T]]: """Decorator to mark a function parameter as deprecated due to being renamed. @@ -66,7 +60,7 @@ def my_func(new_name): ... return deprecate_renamed_parameters({old_name: new_name}, version=version, category=category) -def deprecate_nonkeyword_arguments( +def deprecate_nonkeyword_arguments[**P, T]( allowed_args: Sequence[str] | None = None, message: str | None = None, *, version: str ) -> Callable[[Callable[P, T]], Callable[P, T]]: """Decorator to deprecate the use of non-keyword arguments of a function. @@ -127,7 +121,7 @@ def decorate(function: Callable[P, T]) -> Callable[P, T]: @wraps(function) def wrapper(*args: P.args, **kwargs: P.kwargs) -> T: if len(args) > num_allowed_args: - warnings.warn(message=msg, category=FutureWarning, stacklevel=find_stack_level()) + warn_external(message=msg, category=FutureWarning) return function(*args, **kwargs) wrapper.__signature__ = new_sig # type: ignore @@ -136,7 +130,7 @@ def wrapper(*args: P.args, **kwargs: P.kwargs) -> T: return decorate -def deprecate_parameter_as_multi_positional( +def deprecate_parameter_as_multi_positional[**P, T]( old_name: str, *, version: str ) -> Callable[[Callable[P, T]], Callable[P, T]]: """Decorator to mark a function argument as deprecated due to being made multi-positional. @@ -155,13 +149,12 @@ def wrapper(*args: P.args, **kwargs: P.kwargs) -> T: except KeyError: return function(*args, **kwargs) - warnings.warn( + warn_external( message=( f"Passing {old_name!r} as a keyword argument is deprecated. Pass it as a " "positional argument instead." ), category=FutureWarning, - stacklevel=find_stack_level(), ) if not isinstance(arg_value, Sequence) or isinstance(arg_value, str): diff --git a/roseau/load_flow/utils/dtypes.py b/roseau/load_flow/utils/dtypes.py index 2ecd0419..d04c0475 100644 --- a/roseau/load_flow/utils/dtypes.py +++ b/roseau/load_flow/utils/dtypes.py @@ -16,7 +16,7 @@ SequenceDtype: Final = pd.CategoricalDtype(categories=["zero", "pos", "neg"], ordered=True) """Categorical data type used for symmetrical components.""" DTYPES: Final = { - "bus_id": object, + "bus_id": object, # we use object for ids because they could be either str or int "branch_id": object, "transformer_id": object, "line_id": object, diff --git a/roseau/load_flow/utils/exceptions.py b/roseau/load_flow/utils/exceptions.py deleted file mode 100644 index 3db0cd06..00000000 --- a/roseau/load_flow/utils/exceptions.py +++ /dev/null @@ -1,40 +0,0 @@ -# The find_stack_level function is adapted from the `pandas.util._exceptions.find_stack_level` -# function from the pandas library licensed under the BSD 3-Clause license. -# pandas source code is available at https://github.com/pandas-dev/pandas -import inspect -from pathlib import Path - -_pkg_and_tests_dirs: tuple[str, tuple[str, ...]] | None = None - - -def _get_dirs() -> tuple[str, tuple[str, ...]]: - global _pkg_and_tests_dirs - if _pkg_and_tests_dirs is None: - import roseau.load_flow - - pkg_dir = Path(roseau.load_flow.__file__).parent - test_dirs = tuple(str(p) for p in pkg_dir.glob("**/tests") if p.is_dir()) - _pkg_and_tests_dirs = str(pkg_dir), test_dirs - return _pkg_and_tests_dirs - - -def find_stack_level() -> int: - """Find the first place in the stack that is not inside `roseau.load_flow` (tests notwithstanding).""" - pkg_dir, test_dirs = _get_dirs() - - # https://stackoverflow.com/questions/17407119/python-inspect-stack-is-slow - frame = inspect.currentframe() - try: - n = 0 - while frame: # pragma: no cover - filename = inspect.getfile(frame) - if filename.startswith(pkg_dir) and not filename.startswith(test_dirs): - frame = frame.f_back - n += 1 - else: - break - finally: - # See note in https://docs.python.org/3/library/inspect.html#inspect.Traceback - # And Issue https://github.com/pandas-dev/pandas/issues/54628 - del frame - return max(n, 2) diff --git a/roseau/load_flow/utils/helpers.py b/roseau/load_flow/utils/helpers.py index b36a5c99..cefc2818 100644 --- a/roseau/load_flow/utils/helpers.py +++ b/roseau/load_flow/utils/helpers.py @@ -1,7 +1,10 @@ +import warnings from abc import ABCMeta, abstractmethod, update_abstractmethods from collections.abc import Callable, Collection, Sized from enum import StrEnum -from typing import Final, TypeVar +from functools import cache +from pathlib import Path +from typing import Final from shapely.geometry.base import BaseGeometry @@ -83,9 +86,6 @@ def _missing_(cls, value: object) -> object: return None -_ABCT = TypeVar("_ABCT", bound=ABCMeta) - - @staticmethod @abstractmethod def _abstract_attr(): @@ -93,10 +93,10 @@ def _abstract_attr(): raise TypeError("abstract attributes are not callable") -def abstractattrs(*attrs: str) -> Callable[[_ABCT], _ABCT]: +def abstractattrs[T: ABCMeta](*attrs: str) -> Callable[[T], T]: """Class decorator to mark attributes as abstract.""" - def decorator(cls: "_ABCT", /) -> "_ABCT": + def decorator(cls: "T", /) -> "T": assert isinstance(cls, ABCMeta), "abstractattrs can only be used on ABC classes" for attr in attrs: if not hasattr(cls, attr): @@ -105,3 +105,18 @@ def decorator(cls: "_ABCT", /) -> "_ABCT": return cls return decorator + + +@cache +def _get_skip_file_prefixes() -> tuple[str, ...]: + import roseau.load_flow as rlf + import roseau.load_flow_single as rlfs + + rlf_dir = Path(rlf.__file__).parent + rlfs_dir = Path(rlfs.__file__).parent + return str(rlf_dir), str(rlfs_dir) + + +def warn_external(message: str, category: type[Warning] | None = None) -> None: + """Issue a warning to external code, skipping internal frames.""" + warnings.warn(message, category, skip_file_prefixes=_get_skip_file_prefixes()) diff --git a/roseau/load_flow/utils/mixins.py b/roseau/load_flow/utils/mixins.py index 75435ed5..1f481908 100644 --- a/roseau/load_flow/utils/mixins.py +++ b/roseau/load_flow/utils/mixins.py @@ -2,10 +2,10 @@ import logging import re import textwrap -import warnings from abc import ABCMeta, abstractmethod from collections import defaultdict -from collections.abc import Collection, Iterable, Mapping, Sequence +from collections.abc import Callable, Collection, Iterable, Mapping, Sequence +from heapq import heappop, heappush from importlib import resources from pathlib import Path from typing import Any, ClassVar, Generic, NoReturn, Self, overload @@ -20,15 +20,12 @@ from roseau.load_flow._solvers import AbstractSolver from roseau.load_flow.exceptions import RoseauLoadFlowException, RoseauLoadFlowExceptionCode from roseau.load_flow.typing import CRSLike, Id, JsonDict, MapOrSeq, Solver, StrPath -from roseau.load_flow.utils.exceptions import find_stack_level -from roseau.load_flow.utils.helpers import abstractattrs +from roseau.load_flow.utils.helpers import abstractattrs, warn_external from roseau.load_flow.utils.tool_data import ToolData from roseau.load_flow_engine.cy_engine import CyElectricalNetwork, CyElement logger = logging.getLogger(__name__) -_T = TypeVar("_T") -_E = TypeVar("_E", bound="AbstractElement") _E_co = TypeVar("_E_co", bound="AbstractElement", covariant=True) _N_co = TypeVar("_N_co", bound="AbstractNetwork", covariant=True) _CyE_co = TypeVar("_CyE_co", bound=CyElement, default=CyElement, covariant=True) @@ -250,7 +247,7 @@ def results_to_json(self, path: StrPath, *, full: bool = False) -> Path: return path -class CatalogueMixin(Generic[_T], metaclass=ABCMeta): +class CatalogueMixin[T](metaclass=ABCMeta): """A mixin class for objects which can be built from a catalogue. It adds the `from_catalogue` class method.""" @classmethod @@ -261,7 +258,7 @@ def catalogue_path(cls) -> Path: @classmethod @abstractmethod - def catalogue_data(cls) -> _T: + def catalogue_data(cls) -> T: """Get the catalogue data.""" raise NotImplementedError @@ -305,7 +302,7 @@ def _filter_catalogue_str( """ vector = pd.Series(strings) if isinstance(value, re.Pattern): - result = vector.str.fullmatch(value, case=False) + result = vector.str.fullmatch(value.pattern, case=False, flags=value.flags) else: try: result = vector.str.fullmatch(value, case=False) | (vector.str.casefold() == value.casefold()) @@ -530,7 +527,7 @@ def _refresh_results(self) -> None: """Refresh the results of the element.""" raise NotImplementedError - def _res_getter(self, value: _T | None, warning: bool) -> _T: + def _res_getter[T](self, value: T | None, warning: bool) -> T: """A safe getter for load flow results. Args: @@ -551,13 +548,12 @@ def _res_getter(self, value: _T | None, warning: bool) -> _T: logger.error(msg) raise RoseauLoadFlowException(msg=msg, code=RoseauLoadFlowExceptionCode.LOAD_FLOW_NOT_RUN) if warning and self._network is not None and not self._network._results_valid: - warnings.warn( + warn_external( message=( f"The results of {type(self).__name__} {self.id!r} may be outdated. Please re-run a load flow to " "ensure the validity of results." ), category=UserWarning, - stacklevel=find_stack_level(), ) self._fetch_results = False return value @@ -592,7 +588,7 @@ def _raise_several_network(self) -> NoReturn: raise RoseauLoadFlowException(msg, code=RoseauLoadFlowExceptionCode.SEVERAL_NETWORKS) -class AbstractNetwork(RLFObject, JsonMixin, CatalogueMixin[JsonDict], Generic[_E_co]): +class AbstractNetwork(RLFObject, JsonMixin, CatalogueMixin[JsonDict], Generic[_E_co]): # noqa: UP046 """An abstract class of an electrical network.""" _DEFAULT_SOLVER: Solver = "newton_goldstein" @@ -765,10 +761,12 @@ def buses_clusters(self) -> list[set[Id]]: return result @staticmethod - def _elements_as_dict(elements: MapOrSeq[_E], error_code: RoseauLoadFlowExceptionCode) -> dict[Id, _E]: + def _elements_as_dict[E: AbstractElement]( + elements: MapOrSeq[E], error_code: RoseauLoadFlowExceptionCode + ) -> dict[Id, E]: """Convert a sequence or a mapping of elements to a dictionary of elements with their IDs as keys.""" typ = error_code.name.removeprefix("BAD_").removesuffix("_ID").replace("_", " ") - elements_dict: dict[Id, _E] = {} + elements_dict: dict[Id, E] = {} if isinstance(elements, Mapping): for element_id, element in elements.items(): if element.id != element_id: @@ -858,7 +856,9 @@ def _add_parameters(self, element_type: str, params: Identifiable) -> None: def _remove_parameters(self, element_type: str, params_id: Id) -> None: del self._parameters[element_type][params_id] - def _add_element_to_dict(self, element: _E, to: dict[Id, _E], disconnectable: bool = False) -> None: + def _add_element_to_dict[E: AbstractElement]( + self, element: E, to: dict[Id, E], disconnectable: bool = False + ) -> None: if element.id in to and (old := to[element.id]) is not element: element._disconnect() # Don't leave it lingering in other elements _connected_elements old_type = type(old).__name__ @@ -996,17 +996,189 @@ def _check_valid_results(self) -> bool: raise RoseauLoadFlowException(msg=msg, code=RoseauLoadFlowExceptionCode.LOAD_FLOW_NOT_RUN) if not self._results_valid: - warnings.warn( + warn_external( message=( "The results of this network may be outdated. Please re-run a load flow to " "ensure the validity of results." ), category=UserWarning, - stacklevel=find_stack_level(), ) return False return True + def _get_nominal_voltages(self) -> dict[Id, float]: # noqa: C901 + """Get approximate nominal voltages for all buses in the network (even if not defined). + + This function attempts to infer nominal voltages for all buses in the network by propagating + known nominal voltages through connected feeders and transformers. If there are no defined + nominal voltages, it uses the HV voltage of the transformer with the highest voltage or the + voltage of the starting source as a reference. + + These voltages are used to determine voltage levels for plotting purposes only. + """ + import roseau.load_flow as rlf + import roseau.load_flow_single as rlfs + + assert isinstance(self, (rlf.ElectricalNetwork, rlfs.ElectricalNetwork)) + + nominal_voltages: dict[Id, float] = {} + nb_buses = len(self.buses) + + for bus in self.buses.values(): + if bus._nominal_voltage is not None: + nominal_voltages[bus.id] = bus._nominal_voltage + + if len(nominal_voltages) == nb_buses: + # all nominal voltages are defined, return them + return nominal_voltages + + # Propagate nominal voltages of each feeder first (shortcut version) + for bus_id, nominal_voltage in list(nominal_voltages.items()): + for feeder_bus_id in self.buses[bus_id].get_connected_buses(): + if feeder_bus_id not in nominal_voltages: + nominal_voltages[feeder_bus_id] = nominal_voltage + + if len(nominal_voltages) == nb_buses: + # all nominal voltages are defined, return them + return nominal_voltages + + # Determine reference bus for voltage propagation + if nominal_voltages: + # We have at least one nominal voltage defined, use it as reference + reference_bus = self.buses[next(iter(nominal_voltages))] + reference_nominal_voltage = nominal_voltages[reference_bus.id] + elif self.transformers: + # Use the highest voltage transformer HV side as reference + starting_transformer = max(self.transformers.values(), key=lambda t: t.parameters._uhv) + reference_bus = starting_transformer.bus_hv + reference_nominal_voltage = starting_transformer.parameters._uhv + else: + # Use the first source bus as reference + if isinstance(self, rlf.ElectricalNetwork): + starting_potentials, starting_source = self._get_starting_potentials(all_phases=set("abcn")) + reference_bus = starting_source.bus + reference_nominal_voltage = abs(starting_potentials["a"] - starting_potentials["b"]) + else: + starting_voltage, starting_source = self._get_starting_voltage() + reference_bus = starting_source.bus + reference_nominal_voltage = abs(starting_voltage) + + # Propagate voltages by traversing the entire network + buses = [(reference_bus, reference_nominal_voltage)] + seen_buses: set[Id] = set() + while buses: + current_bus, current_vn = buses.pop() + if current_bus.id in seen_buses: + continue + seen_buses.add(current_bus.id) + if current_bus.id not in nominal_voltages: + nominal_voltages[current_bus.id] = current_vn + for e in current_bus._connected_elements: + if isinstance(e, (rlf.Transformer, rlfs.Transformer)): + if e.bus_hv.id == current_bus.id: + other_bus = e.bus_lv + other_vn = ( + nominal_voltages[other_bus.id] + if other_bus.id in nominal_voltages + else current_vn * e.parameters._ulv / e.parameters._uhv + ) + else: + other_bus = e.bus_hv + other_vn = ( + nominal_voltages[other_bus.id] + if other_bus.id in nominal_voltages + else current_vn * e.parameters._uhv / e.parameters._ulv + ) + buses.append((other_bus, other_vn)) + elif isinstance(e, (rlf.Line, rlf.Switch, rlfs.Line, rlfs.Switch)): + other_bus = e.bus2 if e.bus1.id == current_bus.id else e.bus1 + other_vn = nominal_voltages.get(other_bus.id, current_vn) + buses.append((other_bus, other_vn)) + + assert len(nominal_voltages) == nb_buses, "Failed to infer nominal voltages for all buses." + return nominal_voltages + + @abstractmethod + def _get_starting_bus_id(self) -> Id: + raise NotImplementedError + + def _shortest_paths( + self, + source: Id, + *, + weight: Callable[[str, Id], float | None], + pred: dict[Id, list[Id]] | None = None, + adj: dict[Id, dict[Id, list[tuple[str, Id]]]] | None = None, + ) -> dict[Id, float]: + """Compute the shortest paths from a source bus to all buses in the network. + + The network is represented as an undirected multigraph where edges correspond to lines, + transformers, and closed switches. The length of lines is used as the weight for the edges, + while transformers and closed switches have a length of 0. Open switches are ignored. + + The algorithm used is Dijkstra's algorithm. + + Args: + source: + The ID of the source bus. All distances are computed from this bus. + + weight: + A callable that takes the element type and element ID and returns the weight for the edge. + If the callable returns None, the edge is ignored. + + pred: + An optional dictionary to store the predecessors of each bus in the shortest paths. + If provided, it will be filled with the predecessors during the computation. + + adj: + An optional adjacency representation of the network. If provided, it will be filled + with the adjacency information during the computation. + + Returns: + The distances from the source bus to all other buses in the network. + """ + if adj is None: + adj = {} + for n in self._elements_by_type["bus"]: + adj.setdefault(n, {}) + for et in ("line", "transformer", "switch"): + for e in self._elements_by_type[et].values(): + u, v = e.bus1.id, e.bus2.id # type: ignore + edge_data = (et, e.id) + adj[u].setdefault(v, []).append(edge_data) + adj[v].setdefault(u, []).append(edge_data) + if pred is not None: + pred.setdefault(source, []) + + distances: dict[Id, float] = {} + seen: dict[Id, float] = {source: 0.0} + + # middle item is a counter used to avoid comparing nodes (which may not be comparable) + heap: list[tuple[float, int, Id]] = [(0.0, 0, source)] + while heap: + (v_dist, c, v) = heappop(heap) + if v in distances: + continue + distances[v] = v_dist + for u, edges in adj[v].items(): + cost = min((w for (et, eid) in edges if (w := weight(et, eid)) is not None), default=None) + if cost is None: + continue + vu_dist = v_dist + cost + if u in distances: + u_dist = distances[u] + if pred is not None and vu_dist == u_dist: + pred[u].append(v) + elif u not in seen or vu_dist < seen[u]: + seen[u] = vu_dist + heappush(heap, (vu_dist, c + 1, u)) + if pred is not None: + pred[u] = [v] + elif pred is not None and vu_dist == seen[u]: + pred[u].append(v) + + return distances + # # DGS interface # diff --git a/roseau/load_flow/utils/testing.py b/roseau/load_flow/utils/testing.py index 636c41b7..60043d85 100644 --- a/roseau/load_flow/utils/testing.py +++ b/roseau/load_flow/utils/testing.py @@ -3,13 +3,9 @@ from collections.abc import Callable, Generator from contextlib import AbstractContextManager, contextmanager from functools import cache -from typing import ParamSpec, TypeVar from roseau.load_flow.utils.mixins import AbstractNetwork -P = ParamSpec("P") -R = TypeVar("R") - @contextmanager def check_result_warning(match: str | re.Pattern[str]) -> Generator[None]: @@ -22,7 +18,7 @@ def check_result_warning(match: str | re.Pattern[str]) -> Generator[None]: assert record.category is UserWarning -def invoke_result_access( +def invoke_result_access[**P, R]( en_or_elm: object, res_name: str, func: Callable[P, AbstractContextManager[R]], /, *args: P.args, **kwargs: P.kwargs ) -> R: """Invoke a context manager when accessing a result on a network or element. @@ -68,7 +64,7 @@ def get_result_names(en_or_elm_class: type[object], /) -> Generator[str]: yield from (attr for attr in dir(en_or_elm_class) if attr.startswith("res_")) -def access_elements_results( +def access_elements_results[**P, R]( en: "AbstractNetwork", func: Callable[P, AbstractContextManager[R]], /, *args: P.args, **kwargs: P.kwargs ) -> Generator[R]: for element_type, elements in en._elements_by_type.items(): diff --git a/roseau/load_flow/utils/types.py b/roseau/load_flow/utils/types.py deleted file mode 100644 index 098418d5..00000000 --- a/roseau/load_flow/utils/types.py +++ /dev/null @@ -1,13 +0,0 @@ -import warnings - -warnings.warn( - "Module 'roseau.load_flow.utils.types' is deprecated. Use 'rlf.types' directly instead.", - category=FutureWarning, - stacklevel=2, -) -# ruff: noqa: E402, F401 -# pyright: reportUnusedImport=none -# deprecated since 0.12.0 -from roseau.load_flow.types import Insulator, LineType, Material -from roseau.load_flow.utils.dtypes import DTYPES as _DTYPES -from roseau.load_flow.utils.dtypes import BranchTypeDtype, LoadTypeDtype, PhaseDtype, SequenceDtype, VoltagePhaseDtype diff --git a/roseau/load_flow_single/conftest.py b/roseau/load_flow_single/conftest.py index 1e5024bb..78990dc8 100644 --- a/roseau/load_flow_single/conftest.py +++ b/roseau/load_flow_single/conftest.py @@ -2,7 +2,7 @@ import pytest -import roseau.load_flow_single +import roseau.load_flow_single as rlfs from roseau.load_flow.conftest import patch_engine_impl HERE = Path(__file__).parent.expanduser().absolute() @@ -56,4 +56,47 @@ def three_phases_transformer_type(request) -> str: @pytest.fixture(autouse=True) def patch_engine(request): - yield from patch_engine_impl(request, extra_dir=Path(roseau.load_flow_single.__file__).parent) + assert rlfs.__file__ is not None + yield from patch_engine_impl(request, extra_dir=Path(rlfs.__file__).parent) + + +@pytest.fixture(scope="session", autouse=True) +def patch_warn_external(): + # Exclude test files from skipped files in warn_external + from roseau.load_flow.utils import helpers + + assert rlfs.__file__ is not None + paths = tuple( + str(p) for p in Path(rlfs.__file__).resolve().parent.parent.rglob("**/*.py") if "tests" not in p.parts + ) + helpers._get_skip_file_prefixes = lambda: paths + + +# The following networks are generated using the scripts/generate_test_networks.py script +@pytest.fixture +def all_elements_network_path(test_networks_path) -> Path: + return test_networks_path / "all_elements_network.json" + + +@pytest.fixture +def all_elements_network(all_elements_network_path) -> rlfs.ElectricalNetwork: + """Load the network from the JSON file (without results).""" + return rlfs.ElectricalNetwork.from_json(path=all_elements_network_path, include_results=False) + + +@pytest.fixture +def all_elements_network_with_results(all_elements_network_path) -> rlfs.ElectricalNetwork: + """Load the network from the JSON file (with results, no need to invoke the solver).""" + return rlfs.ElectricalNetwork.from_json(path=all_elements_network_path, include_results=True) + + +@pytest.fixture +def small_network(test_networks_path) -> rlfs.ElectricalNetwork: + """Load the network from the JSON file (without results).""" + return rlfs.ElectricalNetwork.from_json(path=test_networks_path / "small_network.json", include_results=False) + + +@pytest.fixture +def small_network_with_results(test_networks_path) -> rlfs.ElectricalNetwork: + """Load the network from the JSON file (with results, no need to invoke the solver).""" + return rlfs.ElectricalNetwork.from_json(path=test_networks_path / "small_network.json", include_results=True) diff --git a/roseau/load_flow_single/io/dgs/buses.py b/roseau/load_flow_single/io/dgs/buses.py index 28002707..50f3c405 100644 --- a/roseau/load_flow_single/io/dgs/buses.py +++ b/roseau/load_flow_single/io/dgs/buses.py @@ -1,5 +1,4 @@ import logging -import warnings from collections.abc import Iterable, Iterator import pandas as pd @@ -10,7 +9,7 @@ from roseau.load_flow.io.dgs.utils import DEFAULT_GPS_COORDS, DEFAULT_TERM_VMAX, DEFAULT_TERM_VMIN, DGSData, clean_id from roseau.load_flow.typing import Id from roseau.load_flow.units import Q_ -from roseau.load_flow.utils import find_stack_level +from roseau.load_flow.utils import warn_external from roseau.load_flow_single.models import Bus logger = logging.getLogger(__name__) @@ -108,12 +107,9 @@ def buses_to_elm_term(buses: Iterable[Bus], fid_counter: Iterator[str], fold_id: ] ) if buses_missing_un: - warnings.warn( - ( - f"Power factory requires all buses to define their nominal voltage. Missing nominal " - f"voltage might cause problems on import. The following buses do not define their " - f"nominal voltage: {buses_missing_un}" - ), - stacklevel=find_stack_level(), + warn_external( + f"Power factory requires all buses to define their nominal voltage. Missing nominal " + f"voltage might cause problems on import. The following buses do not define their " + f"nominal voltage: {buses_missing_un}" ) return {"Attributes": attributes, "Values": values} diff --git a/roseau/load_flow_single/io/dgs/lines.py b/roseau/load_flow_single/io/dgs/lines.py index 3be436c2..de0a1ece 100644 --- a/roseau/load_flow_single/io/dgs/lines.py +++ b/roseau/load_flow_single/io/dgs/lines.py @@ -1,6 +1,5 @@ import logging import math -import warnings from collections.abc import Iterable, Iterator import pandas as pd @@ -23,7 +22,7 @@ ) from roseau.load_flow.typing import Id from roseau.load_flow.units import Q_ -from roseau.load_flow.utils import find_stack_level +from roseau.load_flow.utils import warn_external from roseau.load_flow_single.io.dgs.pwf import STA_CUBIC_FID_INDEX, STA_CUBIC_OBJ_ID_INDEX from roseau.load_flow_single.models import Bus, Line, LineParameters @@ -260,22 +259,16 @@ def lp_to_typ_lne( for lp, uns in zip(line_params, lp_uns, strict=True): if len(uns) == 0: uline = 0.0 - warnings.warn( - ( - f"Cannot determine the nominal voltage of line parameters {lp.id!r} because buses " - f"connected to its lines do not define a nominal voltage." - ), - stacklevel=find_stack_level(), + warn_external( + f"Cannot determine the nominal voltage of line parameters {lp.id!r} because buses " + f"connected to its lines do not define a nominal voltage." ) elif len(uns) > 1: uline = max(uns) - warnings.warn( - ( - f"Line parameters {lp.id!r} has line that are connected to buses with different " - f"nominal voltages {sorted(uns)}. This may cause errors in the load flow " - f"calculation in PowerFactory. Choosing {uline} V as the nominal voltage." - ), - stacklevel=find_stack_level(), + warn_external( + f"Line parameters {lp.id!r} has line that are connected to buses with different " + f"nominal voltages {sorted(uns)}. This may cause errors in the load flow " + f"calculation in PowerFactory. Choosing {uline} V as the nominal voltage." ) else: uline = next(iter(uns)) diff --git a/roseau/load_flow_single/io/dgs/loads.py b/roseau/load_flow_single/io/dgs/loads.py index 6666a696..f66a27de 100644 --- a/roseau/load_flow_single/io/dgs/loads.py +++ b/roseau/load_flow_single/io/dgs/loads.py @@ -1,5 +1,4 @@ import logging -import warnings from collections.abc import Iterable, Iterator import pandas as pd @@ -17,7 +16,7 @@ from roseau.load_flow.io.dgs.loads import LOAD_POWER_FUNCTIONS from roseau.load_flow.io.dgs.utils import DGSData, clean_id from roseau.load_flow.typing import Id -from roseau.load_flow.utils import find_stack_level +from roseau.load_flow.utils import warn_external from roseau.load_flow_single.io.dgs.pwf import STA_CUBIC_FID_INDEX, STA_CUBIC_OBJ_ID_INDEX from roseau.load_flow_single.models import AbstractLoad, Bus, PowerLoad @@ -71,7 +70,7 @@ def elm_lod_all_to_loads( f"Unbalanced loads are not supported, {load_type} load {load_id!r} is unbalanced. " f"It will be processed as balanced." ) - warnings.warn(msg, stacklevel=find_stack_level()) + warn_external(msg) if load_type == "MV": # Seems like MV Loads in PF just inherit the phase of the bus sometimes diff --git a/roseau/load_flow_single/io/dgs/pwf.py b/roseau/load_flow_single/io/dgs/pwf.py index 072e3539..c7e013a3 100644 --- a/roseau/load_flow_single/io/dgs/pwf.py +++ b/roseau/load_flow_single/io/dgs/pwf.py @@ -103,6 +103,7 @@ def create_graphic_net(fid_counter: Iterator[str]) -> DGSData: "OP", # Operation (C=create, U=update, D=delete, M=merge, I=ignore) "loc_name", # Name "fold_id", # In Folder + # spellchecker:ignore-next-line "sBordSym:SIZEROW", "snap_on", # Snap to grid: 0=off, 1=on "ortho_on", # Line routing: 0=non-orthogonal, 1=orthogonal, 2=semi-orthogonal @@ -115,6 +116,7 @@ def create_graphic_net(fid_counter: Iterator[str]) -> DGSData: "C", # OP "RLF Graphic", # loc_name None, # fold_id + # spellchecker:ignore-next-line "0", # sBordSym:SIZEROW 1, # snap_on 1, # ortho_on diff --git a/roseau/load_flow_single/io/dgs/transformers.py b/roseau/load_flow_single/io/dgs/transformers.py index 6fd86a9d..2209d2bb 100644 --- a/roseau/load_flow_single/io/dgs/transformers.py +++ b/roseau/load_flow_single/io/dgs/transformers.py @@ -1,6 +1,5 @@ import logging import math -import warnings from collections.abc import Iterable, Iterator import pandas as pd @@ -15,7 +14,7 @@ ) from roseau.load_flow.typing import Id from roseau.load_flow.units import Q_ -from roseau.load_flow.utils import find_stack_level +from roseau.load_flow.utils import warn_external from roseau.load_flow_single.io.dgs.pwf import STA_CUBIC_FID_INDEX, STA_CUBIC_OBJ_ID_INDEX from roseau.load_flow_single.models import Bus, Transformer, TransformerParameters @@ -189,10 +188,7 @@ def tp_to_typ_tr2(transformer_params: Iterable[TransformerParameters], fid_count } ) if (fn := tp.fn) is None: - warnings.warn( - f"Transformer parameters {tp.id!r} has no nominal frequency. Setting it to 50 Hz.", - stacklevel=find_stack_level(), - ) + warn_external(f"Transformer parameters {tp.id!r} has no nominal frequency. Setting it to 50 Hz.") frnom = 50.0 else: frnom = fn.m_as("Hz") @@ -265,13 +261,10 @@ def transformers_to_elm_tr2( nntap_float = 100 * (1.0 - tr.tap) / DU_TAP nntap = round(nntap_float) if not math.isclose(nntap_float, nntap, abs_tol=0.1): - warnings.warn( - ( - f"Transformer {tr.id!r} has tap value {tr.tap} which is equivalent to position " - f"{nntap_float} of {DU_TAP}% additional voltage per tap. Setting the tap position " - f"to {nntap} instead." - ), - stacklevel=find_stack_level(), + warn_external( + f"Transformer {tr.id!r} has tap value {tr.tap} which is equivalent to position " + f"{nntap_float} of {DU_TAP}% additional voltage per tap. Setting the tap position " + f"to {nntap} instead." ) values.append( [ diff --git a/roseau/load_flow_single/io/dict.py b/roseau/load_flow_single/io/dict.py index e56756c4..bf320bcb 100644 --- a/roseau/load_flow_single/io/dict.py +++ b/roseau/load_flow_single/io/dict.py @@ -8,7 +8,6 @@ import copy import logging -import warnings from typing import TYPE_CHECKING from pyproj import CRS @@ -16,7 +15,7 @@ from roseau.load_flow import Insulator, Material from roseau.load_flow.io.dict import NETWORK_JSON_VERSION as NETWORK_JSON_VERSION from roseau.load_flow.typing import Id, JsonDict -from roseau.load_flow.utils import find_stack_level, id_sort_key +from roseau.load_flow.utils import id_sort_key, warn_external from roseau.load_flow_single.io.common import NetworkElements from roseau.load_flow_single.models import ( AbstractLoad, @@ -69,11 +68,10 @@ def network_from_dict( f"Unsupported network file version {version}, expected <={NETWORK_JSON_VERSION}." ) if version < NETWORK_JSON_VERSION: - warnings.warn( + warn_external( f"Got an outdated network file (version {version}), trying to update to the current format " f"(version {NETWORK_JSON_VERSION}). Please save the network again.", category=UserWarning, - stacklevel=find_stack_level(), ) if version <= 3: data = v3_to_v4_converter(data) diff --git a/roseau/load_flow_single/io/rlf.py b/roseau/load_flow_single/io/rlf.py index d0da9587..c8238841 100644 --- a/roseau/load_flow_single/io/rlf.py +++ b/roseau/load_flow_single/io/rlf.py @@ -1,13 +1,12 @@ import cmath import logging -import warnings -from typing import Literal, TypeAlias +from typing import Literal import numpy as np import roseau.load_flow as rlf from roseau.load_flow.typing import ComplexArray, Id, JsonDict -from roseau.load_flow.utils import find_stack_level +from roseau.load_flow.utils import warn_external from roseau.load_flow_single.io.common import NetworkElements from roseau.load_flow_single.models import ( AbstractLoad, @@ -26,19 +25,19 @@ logger = logging.getLogger(__name__) -OnIncompatibleType: TypeAlias = Literal["ignore", "warn", "raise-critical", "raise"] +type OnIncompatibleType = Literal["ignore", "warn", "raise-critical", "raise"] def _handle_incompatibility(msg: str, on_incompatible: OnIncompatibleType, critical: bool = True) -> None: if on_incompatible == "ignore": pass elif on_incompatible == "warn": - warnings.warn(msg, UserWarning, stacklevel=find_stack_level()) + warn_external(msg, UserWarning) elif on_incompatible == "raise-critical": if critical: raise rlf.RoseauLoadFlowException(msg, code=rlf.RoseauLoadFlowExceptionCode.INVALID_FOR_SINGLE_PHASE) else: - warnings.warn(msg, UserWarning, stacklevel=find_stack_level()) + warn_external(msg, UserWarning) elif on_incompatible == "raise": raise rlf.RoseauLoadFlowException(msg, code=rlf.RoseauLoadFlowExceptionCode.INVALID_FOR_SINGLE_PHASE) else: diff --git a/roseau/load_flow_single/models/branches.py b/roseau/load_flow_single/models/branches.py index 3bd7a944..4ce115b3 100644 --- a/roseau/load_flow_single/models/branches.py +++ b/roseau/load_flow_single/models/branches.py @@ -1,6 +1,5 @@ import logging import math -import warnings from abc import abstractmethod from typing import Generic, Self @@ -10,7 +9,7 @@ from roseau.load_flow import SQRT3 from roseau.load_flow.typing import Id, JsonDict, Side from roseau.load_flow.units import Q_, ureg_wraps -from roseau.load_flow.utils import find_stack_level +from roseau.load_flow.utils import warn_external from roseau.load_flow_engine.cy_engine import CyBranch from roseau.load_flow_single.models.buses import Bus from roseau.load_flow_single.models.connectables import AbstractConnectable @@ -137,12 +136,9 @@ def _check_same_voltage_level(self) -> None: and self.bus2._nominal_voltage is not None and not math.isclose(self.bus1._nominal_voltage, self.bus2._nominal_voltage) ): - warnings.warn( - ( - f"{self.element_type.capitalize()} {self.id!r} connects buses with different " - f"nominal voltages: {self.bus1._nominal_voltage} V and {self.bus2._nominal_voltage} V." - ), - stacklevel=find_stack_level(), + warn_external( + f"{self.element_type.capitalize()} {self.id!r} connects buses with different " + f"nominal voltages: {self.bus1._nominal_voltage} V and {self.bus2._nominal_voltage} V." ) def _update_network_parameters(self, old_parameters: _Parameters | None, new_parameters: _Parameters) -> None: diff --git a/roseau/load_flow_single/models/buses.py b/roseau/load_flow_single/models/buses.py index 9f309f28..743508fb 100644 --- a/roseau/load_flow_single/models/buses.py +++ b/roseau/load_flow_single/models/buses.py @@ -1,6 +1,5 @@ import logging import math -import warnings from collections.abc import Iterator from typing import Final, Self @@ -9,9 +8,9 @@ from shapely.geometry.base import BaseGeometry from roseau.load_flow import SQRT3, RoseauLoadFlowException, RoseauLoadFlowExceptionCode -from roseau.load_flow.typing import Complex, Float, Id, JsonDict +from roseau.load_flow.typing import Complex, Float, Id, JsonDict, ResultState from roseau.load_flow.units import Q_, ureg_wraps -from roseau.load_flow.utils import find_stack_level +from roseau.load_flow.utils import warn_external from roseau.load_flow_engine.cy_engine import CyBus from roseau.load_flow_single.models.core import Element from roseau.load_flow_single.models.terminals import AbstractTerminal @@ -118,13 +117,12 @@ def nominal_voltage(self) -> Q_[float] | None: def nominal_voltage(self, value: Float | Q_[Float] | None) -> None: if pd.isna(value): if self._max_voltage_level is not None or self._min_voltage_level is not None: - warnings.warn( + warn_external( message=( f"The nominal voltage of bus {self.id!r} is required to use `min_voltage_level` " f"and `max_voltage_level`." ), category=UserWarning, - stacklevel=find_stack_level(), ) self._nominal_voltage = None else: @@ -153,13 +151,12 @@ def min_voltage_level(self, value: Float | Q_[Float] | None) -> None: logger.error(msg) raise RoseauLoadFlowException(msg=msg, code=RoseauLoadFlowExceptionCode.BAD_VOLTAGES) if self._nominal_voltage is None: - warnings.warn( + warn_external( message=( f"The min voltage level of bus {self.id!r} is useless without a nominal voltage. Please " f"define a nominal voltage for this bus." ), category=UserWarning, - stacklevel=find_stack_level(), ) self._min_voltage_level = float(value) @@ -191,13 +188,12 @@ def max_voltage_level(self, value: Float | Q_[Float] | None) -> None: logger.error(msg) raise RoseauLoadFlowException(msg=msg, code=RoseauLoadFlowExceptionCode.BAD_VOLTAGES) if self._nominal_voltage is None: - warnings.warn( + warn_external( message=( f"The max voltage level of bus {self.id!r} is useless without a nominal voltage. Please " f"define a nominal voltage for this bus." ), category=UserWarning, - stacklevel=find_stack_level(), ) self._max_voltage_level = float(value) @@ -347,6 +343,27 @@ def _res_voltage_level_getter(self, warning: bool) -> float | None: voltage = self._res_voltage_getter(warning) return abs(voltage) / self._nominal_voltage + def _res_state_getter(self) -> ResultState: + """The state of the bus based on its voltage levels and limits.""" + u = self._res_voltage_level_getter(warning=False) + if u is None: + return "unknown" + u_min = self._min_voltage_level + u_max = self._max_voltage_level + if u_min is None and u_max is None: + return "unknown" + if u_max is not None: + if u > u_max: + return "very-high" + elif u > 0.75 * u_max + 0.25: + return "high" + if u_min is not None: + if u < u_min: + return "very-low" + elif u < 0.75 * u_min + 0.25: + return "low" + return "normal" + @property def res_voltage_level(self) -> Q_[float] | None: """The load flow result of the bus voltage levels (unitless).""" diff --git a/roseau/load_flow_single/models/line_parameters.py b/roseau/load_flow_single/models/line_parameters.py index 17ebe61d..443dd1aa 100644 --- a/roseau/load_flow_single/models/line_parameters.py +++ b/roseau/load_flow_single/models/line_parameters.py @@ -1,9 +1,10 @@ import cmath import logging +import math import re from enum import StrEnum from pathlib import Path -from typing import Final, Literal, NoReturn, Self, TypeVar +from typing import Final, Literal, NoReturn, Self import numpy as np import pandas as pd @@ -17,7 +18,6 @@ logger = logging.getLogger(__name__) -_StrEnumT = TypeVar("_StrEnumT", bound=StrEnum) _triu_i = np.triu_indices(3, 1) _tril_i = np.tril_indices(3, -1) @@ -46,10 +46,11 @@ def __init__( A unique ID of the line parameters, typically its canonical name. z_line: - The Z of the line (Ohm/km). + The positive-sequence series impedance (z1) of the line (Ohm/km). y_shunt: - The Y of the line (Siemens/km). This field is optional if the line has no shunt part. + The positive-sequence shunt admittance (y1) of the line (Siemens/km). This field is + optional if the line has no shunt part. ampacity: The ampacity of the line (A). The ampacity is optional, it is @@ -75,9 +76,9 @@ def __init__( from the catalogue. section: - The section of the conductor. The section is optional, it is informative only and is not used in - the load flow. This field gets automatically filled when the line parameters are created from a - geometric model or from the catalogue. + The section of the conductor. The section is optional, it is informative only and is + not used in the load flow. This field gets automatically filled when the line + parameters are created from a geometric model or from the catalogue. """ super().__init__(id) self._z_line = self._check_value(id=id, value=z_line, name="z_line") @@ -182,46 +183,6 @@ def ampacity(self) -> Q_[float] | None: def ampacity(self, value: Float | Q_[Float] | None) -> None: self._ampacity = self._check_positive_float(value=value, name="ampacity", unit="A") - @classmethod - @ureg_wraps(None, (None, None, "ohm/km", "ohm/km", "S/km", "S/km", "A")) - def from_sym( - cls, - id: Id, - *, - z0: Complex | Q_[Complex] | None = None, - z1: Complex | Q_[Complex], - y0: Complex | Q_[Complex] | None = None, - y1: Complex | Q_[Complex], - ampacity: Float | Q_[Float] | None = None, - ) -> Self: - """Create line parameters from a symmetric model. - - Args: - id: - A unique ID of the line parameters, typically its canonical name. - - z0: - Impedance - zero sequence - :math:`r_0+x_0\\cdot j` (ohms/km). - Not used in this positive-sequence line model. - - z1: - Impedance - direct sequence - :math:`r_1+x_1\\cdot j` (ohms/km). - - y0: - Admittance - zero sequence - :math:`g_0+b_0\\cdot j` (Siemens/km). - Not used in this positive-sequence line model. - - y1: - Conductance - direct sequence - :math:`g_1+b_1\\cdot j` (Siemens/km). - - ampacity - An optional ampacity for the line parameters (A). It is not used in the load flow. - - Returns: - The created line parameters. - """ - return cls(id=id, z_line=z1, y_shunt=y1, ampacity=ampacity) - @classmethod @ureg_wraps(None, (None, None, None, None, None, None, None, "mm**2", "mm**2", "m", "m", "A")) def from_geometry( @@ -345,6 +306,7 @@ def from_roseau_load_flow(cls, lp_m: MultiLineParameters, /, *, strict: bool = F _, (z1, y1) = lp_m._zy_to_sym( operation="create `rlfs.LineParameters` from multi-phase", exc_code=RoseauLoadFlowExceptionCode.INVALID_FOR_SINGLE_PHASE, + kron=True, ) if y1.real < 0: # might produce a value with a small negative real part y1 = 1j * y1.imag @@ -386,18 +348,13 @@ def from_roseau_load_flow(cls, lp_m: MultiLineParameters, /, *, strict: bool = F ) @classmethod - @ureg_wraps( - None, (None, None, "ohm/km", "ohm/km", "ohm/km", "ohm/km", "µS/km", "µS/km", "kA", None, None, None, "mm**2") - ) + @ureg_wraps(None, (None, None, "ohm/km", "ohm/km", "µS/km", "kA", None, None, None, "mm**2")) def from_power_factory( cls, id: Id, *, - r0: Float | Q_[Float] | None = None, r1: Float | Q_[Float], - x0: Float | Q_[Float] | None = None, x1: Float | Q_[Float], - b0: Float | Q_[Float] | None = None, b1: Float | Q_[Float], inom: Float | Q_[Float] | None = None, cohl: Literal[0, "Cable", 1, "OHL"] = "Cable", @@ -407,28 +364,19 @@ def from_power_factory( ) -> Self: """Create a line parameters object from PowerFactory "TypLne" data. + Note that only positive-sequence parameters are used, zero-sequence parameters (`r0`, `x0`, + `b0`) and neutral parameters (`rn`, `xn`, `bn`, `rpn`, `xpn`, `bpn`) are not needed. + Args: id: A unique ID of the line parameters. - r0: - PwF parameter `rline0` (AC-Resistance R0'). Zero sequence resistance in (ohms/km). - Not used in this positive-sequence line model. - r1: PwF parameter `rline` (AC-Resistance R1'). Direct sequence resistance in (ohms/km). - x0: - PwF parameter `xline0` (Reactance X0'). Zero sequence reactance in (ohms/km). - Not used in this positive-sequence line model. - x1: PwF parameter `xline` (Reactance X1'). Direct sequence reactance in (ohms/km). - b0: - PwF parameter `bline0` (Susceptance B0'). Zero sequence susceptance in (µS/km). - Not used in this positive-sequence line model. - b1: PwF parameter `bline` (Susceptance B'). Direct sequence susceptance in (µS/km). @@ -461,42 +409,38 @@ def from_power_factory( Returns: The created line parameters. """ - lp_m = MultiLineParameters.from_power_factory( + params = MultiLineParameters._parse_power_factory_params( + id=id, inom=inom, cohl=cohl, conductor=conductor, insulation=insulation, section=section + ) + return cls( id=id, - r0=r0 if r0 is not None else r1, - r1=r1, - x0=x0 if x0 is not None else x1, - x1=x1, - b0=b0 if b0 is not None else b1, - b1=b1, - inom=inom, - cohl=cohl, - conductor=conductor, - insulation=insulation, - section=section, - nphase=3, - nneutral=0, + z_line=r1 + 1j * x1, + y_shunt=1j * b1 * 1e-6, + ampacity=params["ampacity"], + line_type=params["line_type"], + material=params["material"], + insulator=params["insulator"], + section=params["section"], ) - return cls.from_roseau_load_flow(lp_m) @classmethod - @ureg_wraps(None, (None, None, "ohm/km", "ohm/km", "ohm/km", "ohm/km", "nF/km", "nF/km", "Hz", "A", None)) + @ureg_wraps(None, (None, None, "ohm/km", "ohm/km", "nF/km", "Hz", "A", None)) def from_open_dss( cls, id: Id, *, r1: Float | Q_[Float], - r0: Float | Q_[Float] | None = None, x1: Float | Q_[Float], - x0: Float | Q_[Float] | None = None, c1: Float | Q_[Float] = 3.4, # default value used in OpenDSS - c0: Float | Q_[Float] | None = None, basefreq: Float | Q_[Float] = F, normamps: Float | Q_[Float] | None = None, linetype: str | None = None, ) -> Self: """Create a line parameters object from OpenDSS "LineCode" data. + Note that only positive-sequence parameters are used, zero-sequence parameters (`r0`, `x0`, + `c0`) are not needed. + Args: id: The unique ID of the line parameters. @@ -504,24 +448,12 @@ def from_open_dss( r1: OpenDSS parameter: `R1`. Positive-sequence resistance in (ohm/km). - r0: - OpenDSS parameter: `R0`. Positive-sequence resistance in (ohm/km). - Not used in this positive-sequence line model. - x1: OpenDSS parameter: `X1`. Positive-sequence reactance in (ohm/km). - x0: - OpenDSS parameter: `X0`. Positive-sequence reactance in (ohm/km). - Not used in this positive-sequence line model. - c1: OpenDSS parameter: `C1`. Positive-sequence capacitance in (nF/km). - c0: - OpenDSS parameter: `C0`. Positive-sequence capacitance in (nF/km). - Not used in this positive-sequence line model. - basefreq: OpenDSS parameter: `BaseFreq`. Frequency at which impedances are specified (Hz). Defaults to 50 Hz. @@ -546,10 +478,7 @@ def from_open_dss( id="linecode-240sq", r1=Q_(0.127, "ohm/km"), x1=Q_(0.072, "ohm/km"), - r0=Q_(0.342, "ohm/km"), - x0=Q_(0.089, "ohm/km"), c1=Q_(3.4, "nF/km"), # default value used in OpenDSS code - c0=Q_(1.6, "nF/km"), # default value used in OpenDSS code ) # DSS command: `New LineCode.16sq NPhases=1 R1=0.350, X1=0.025, R0=0.366, X0=0.025, C1=1.036, C0=0.488 Units=kft NormAmps=400` @@ -557,27 +486,18 @@ def from_open_dss( id="linecode-16sq", r1=Q_(0.350, "ohm/kft"), x1=Q_(0.025, "ohm/kft"), - r0=Q_(0.366, "ohm/kft"), - x0=Q_(0.025, "ohm/kft"), c1=Q_(1.036, "nF/kft"), - c0=Q_(0.488, "nF/kft"), normamps=Q_(400, "A"), ) """ - lp_m = MultiLineParameters.from_open_dss( + params = MultiLineParameters._parse_open_dss_params(id=id, normamps=normamps, linetype=linetype) + return cls( id=id, - r1=r1, - r0=r0 if r0 is not None else r1, - x1=x1, - x0=x0 if x0 is not None else x1, - c1=c1, - c0=c0 if c0 is not None else c1, - basefreq=basefreq, - normamps=normamps, - linetype=linetype, - nphases=3, + z_line=r1 + 1j * x1, + y_shunt=1j * 2 * math.pi * basefreq * c1 * 1e-9, + ampacity=np.array(params["ampacities"]).item(0), # make it scalar if needed + line_type=params["line_type"], ) - return cls.from_roseau_load_flow(lp_m) # # Catalogue Mixin @@ -588,9 +508,6 @@ def catalogue_path(cls) -> Path: @classmethod def catalogue_data(cls) -> pd.DataFrame: - # TODO: Delete from the catalogue of RLF lines with a different neutral section to only keep one version of - # each. Currently, all the lines have the same phase section and neutral section - return MultiLineParameters.catalogue_data().drop( columns=[ "resistance_neutral", @@ -924,7 +841,7 @@ def _check_positive_float(value: Float | None, name: Literal["section", "ampacit return float(value) @staticmethod - def _check_str_enum(value: _StrEnumT | str | None, enum_class: type[_StrEnumT], error_code) -> _StrEnumT | None: + def _check_str_enum[SE: StrEnum](value: SE | str | None, enum_class: type[SE], error_code) -> SE | None: if pd.isna(value): return None try: diff --git a/roseau/load_flow_single/models/lines.py b/roseau/load_flow_single/models/lines.py index b922f65f..1dbea485 100644 --- a/roseau/load_flow_single/models/lines.py +++ b/roseau/load_flow_single/models/lines.py @@ -5,7 +5,7 @@ from shapely.geometry.base import BaseGeometry from roseau.load_flow import SQRT3, RoseauLoadFlowException, RoseauLoadFlowExceptionCode -from roseau.load_flow.typing import Float, Id, JsonDict +from roseau.load_flow.typing import Float, Id, JsonDict, ResultState from roseau.load_flow.units import Q_, ureg_wraps from roseau.load_flow_engine.cy_engine import CyShuntLine, CySimplifiedLine from roseau.load_flow_single.models.branches import AbstractBranch, AbstractBranchSide @@ -94,13 +94,10 @@ def _update_internal_parameters(self) -> None: if self._cy_initialized: if self._parameters.with_shunt: assert isinstance(self._cy_element, CyShuntLine) - self._cy_element.update_line_parameters( - y_shunt=np.array([self._y_shunt], dtype=np.complex128), - z_line=np.array([self._z_line], dtype=np.complex128), - ) + self._cy_element.update_single_line_parameters(y_shunt=self._y_shunt, z_line=self._z_line) else: assert isinstance(self._cy_element, CySimplifiedLine) - self._cy_element.update_line_parameters(z_line=np.array([self._z_line], dtype=np.complex128)) + self._cy_element.update_single_line_parameters(z_line=self._z_line) @property @ureg_wraps("km", (None,)) @@ -219,6 +216,19 @@ def _res_loading_getter(self, warning: bool) -> float | None: current2 = self._side2._res_current_getter(warning=False) # warn only once return max(abs(current1), abs(current2)) / amp + def _res_state_getter(self) -> ResultState: + """Get the state of the line based on its loading.""" + loading = self._res_loading_getter(warning=False) + if loading is None: + return "unknown" + max_loading = self._max_loading + if loading > max_loading: + return "very-high" + elif loading > 0.75 * max_loading: + return "high" + else: + return "normal" + @property @ureg_wraps("A", (None,)) def res_series_current(self) -> Q_[complex]: diff --git a/roseau/load_flow_single/models/loads.py b/roseau/load_flow_single/models/loads.py index 809142d0..8fb8ba7b 100644 --- a/roseau/load_flow_single/models/loads.py +++ b/roseau/load_flow_single/models/loads.py @@ -178,7 +178,7 @@ def power(self, value: Complex | Q_[Complex]) -> None: self._power = value self._invalidate_network_results() if self._cy_initialized: - self._cy_element.update_powers(np.array([self._power / 3.0], dtype=np.complex128)) + self._cy_element.update_power(self._power / 3.0) # # Json Mixin interface @@ -240,7 +240,7 @@ def current(self, value: Complex | Q_[Complex]) -> None: self._current = self._validate_value(value) self._invalidate_network_results() if self._cy_initialized: - self._cy_element.update_currents(np.array([self._current], dtype=np.complex128)) + self._cy_element.update_current(self._current) class ImpedanceLoad(AbstractLoad[CyAdmittanceLoad]): @@ -292,4 +292,4 @@ def impedance(self, value: Complex | Q_[Complex]) -> None: self._impedance = self._validate_value(value) self._invalidate_network_results() if self._cy_initialized: - self._cy_element.update_admittances(np.array([1.0 / self._impedance], dtype=np.complex128)) + self._cy_element.update_admittance(1.0 / self._impedance) diff --git a/roseau/load_flow_single/models/sources.py b/roseau/load_flow_single/models/sources.py index f1022fca..a569379f 100644 --- a/roseau/load_flow_single/models/sources.py +++ b/roseau/load_flow_single/models/sources.py @@ -57,7 +57,7 @@ def voltage(self, value: Complex | Q_[Complex]) -> None: self._voltage = complex(value) self._invalidate_network_results() if self._cy_initialized: - self._cy_element.update_voltages(np.array([self._voltage / SQRT3], dtype=np.complex128)) + self._cy_element.update_voltage(self._voltage / SQRT3) # # Json Mixin interface diff --git a/roseau/load_flow_single/models/tests/test_buses.py b/roseau/load_flow_single/models/tests/test_buses.py index 90f7aa06..1f04c0d4 100644 --- a/roseau/load_flow_single/models/tests/test_buses.py +++ b/roseau/load_flow_single/models/tests/test_buses.py @@ -222,6 +222,51 @@ def test_res_violated(): assert bus.res_violated +def test_res_state(): + bus = Bus(id="bus") + bus._res_voltage = 400 + 0j + + # No nominal voltage + assert bus._res_state_getter() == "unknown" + + # No limits + bus.nominal_voltage = 400 + assert bus._res_state_getter() == "unknown" + + # Only max voltage + bus.max_voltage_level = 1.05 + bus._res_voltage = (400 + 0j) * 1.06 + assert bus._res_state_getter() == "very-high" + bus._res_voltage = (400 + 0j) * 1.04 + assert bus._res_state_getter() == "high" + bus._res_voltage = (400 + 0j) * 1.02 + assert bus._res_state_getter() == "normal" + + # Only min voltage + bus.max_voltage_level = None + bus.min_voltage_level = 0.95 + bus._res_voltage = (400 + 0j) * 0.94 + assert bus._res_state_getter() == "very-low" + bus._res_voltage = (400 + 0j) * 0.96 + assert bus._res_state_getter() == "low" + bus._res_voltage = (400 + 0j) * 0.98 + assert bus._res_state_getter() == "normal" + + # Both min and max voltage + bus.min_voltage_level = 0.95 + bus.max_voltage_level = 1.05 + bus._res_voltage = (400 + 0j) * 1.06 + assert bus._res_state_getter() == "very-high" + bus._res_voltage = (400 + 0j) * 1.04 + assert bus._res_state_getter() == "high" + bus._res_voltage = (400 + 0j) * 1.0 + assert bus._res_state_getter() == "normal" + bus._res_voltage = (400 + 0j) * 0.96 + assert bus._res_state_getter() == "low" + bus._res_voltage = (400 + 0j) * 0.94 + assert bus._res_state_getter() == "very-low" + + def test_propagate_limits(): # noqa: C901 b1_mv = Bus(id="b1_mv") b2_mv = Bus(id="b2_mv") diff --git a/roseau/load_flow_single/models/tests/test_line_parameters.py b/roseau/load_flow_single/models/tests/test_line_parameters.py index fa26dd90..2ec91075 100644 --- a/roseau/load_flow_single/models/tests/test_line_parameters.py +++ b/roseau/load_flow_single/models/tests/test_line_parameters.py @@ -155,7 +155,7 @@ def test_from_geometry(): # TODO regenerate all expected values with the IEC constants and update this test z_line_expected = 0.18842666666666666 + 0.08071828175629972j y_shunt_expected = 0.0006515742213003806j - assert np.isclose(lp.z_line.m, z_line_expected, atol=1e-6) + assert np.isclose(lp.z_line.m, z_line_expected, atol=1e-3) assert np.isclose(lp.y_shunt.m, y_shunt_expected, atol=1e-4) assert isinstance(lp.line_type, LineType) assert lp.line_type == LineType.UNDERGROUND @@ -165,18 +165,27 @@ def test_from_geometry(): def test_sym(): - z0 = 0.0j - z1 = 1.0 + 1.0j - y0 = 0.0j - y1 = 1e-06j - lp = LineParameters.from_sym(id="NKBA NOR 25.00 kV", z0=z0, z1=z1, y0=y0, y1=y1) - assert np.isclose(lp.z_line.m, z1) - assert np.isclose(lp.y_shunt.m, y1) - - # Test optional zero-sequence parameters - lp2 = LineParameters.from_sym(id="NKBA NOR 25.00 kV", z1=z1, y1=y1) - assert np.isclose(lp2.z_line.m, z1) - assert np.isclose(lp2.y_shunt.m, y1) + # There is no rlfs.LineParameters.from_sym method because it is redundant with calling the + # constructor directly with z1 and y1. This is for two reasons: + # 1. The method would create a line model that is always symmetric (diagonal elements are equal + # and off-diagonal elements are equal): + # z,ii = (z0 + 2*z1)/3; z,ij = (z0 - z1)/3; z,nn = zn; z,in = complex(0, xpn); i,j in {a,b,c} + # 2. We are only interested in the positive-sequence parameters which are not affected by + # Kron's reduction if the model is symmetric (point 1): + # z1' = zs' - zm' = (zs - zpn²/zn) - (zm - zpn²/zn) = zs - zm = z1 + # This test proves this claim. + z0 = 0.188 + 0.8224j + z1 = 0.188 + 0.0812j + zn = 0.4029 + 0.3522j + xpn = 0.2471 + y0 = 0.000010462 + 0.000063134j + y1 = 0.000010462 + 0.00022999j + bn = 0.00011407 + bpn = -0.000031502 + lp_m = MultiLineParameters.from_sym(id="TP", z0=z0, z1=z1, y0=y0, y1=y1, zn=zn, xpn=xpn, bn=bn, bpn=bpn) + lp4 = LineParameters.from_roseau_load_flow(lp_m) + assert np.isclose(lp4.z_line.m, z1) + assert np.isclose(lp4.y_shunt.m, y1) def test_from_coiffier_model(): @@ -225,7 +234,10 @@ def test_catalogue_data(): assert catalogue_data["name"].is_unique, "Regenerate catalogue." for row in catalogue_data.itertuples(): - assert re.match(r"^[UOT]_[A-Z]+_\d+(?:_\w+)?$", row.name) + assert isinstance(row.name, str) + assert re.match(r"^[UOT]_[A-Z]+_\d+(?:_\w+)?$", row.name) or re.match( + r"^[UOT]_[A-Z]+_3x(\d+)\+(\d+(?:\.\d+)?)$", row.name + ) assert isinstance(row.resistance, float) assert isinstance(row.reactance, float) assert isinstance(row.susceptance, float) @@ -290,7 +302,8 @@ def test_from_catalogue(): "'U_AL_54', 'U_AL_55', 'U_AL_59', 'U_AL_60', 'U_AL_69', 'U_AL_70', 'U_AL_74', " "'U_AL_75', 'U_AL_79', 'U_AL_80', 'U_AL_90', 'U_AL_93', 'U_AL_95', 'U_AL_100', " "'U_AL_116', 'U_AL_117', 'U_AL_120', 'U_AL_147', 'U_AL_148', 'U_AL_150', 'U_AL_228', " - "'U_AL_240', 'U_AL_288'." + "'U_AL_240', 'U_AL_288', 'U_AL_3x50+50', 'U_AL_3x95+50', 'U_AL_3x150+70', " + "'U_AL_3x150+150', 'U_AL_3x240+95'." ) assert e.value.code == RoseauLoadFlowExceptionCode.CATALOGUE_SEVERAL_FOUND @@ -319,7 +332,7 @@ def test_get_catalogue(): # Get the entire catalogue catalogue = LineParameters.get_catalogue() assert isinstance(catalogue, pd.DataFrame) - assert catalogue.shape == (355, 8) + assert catalogue.shape == (370, 8) # Filter on a single attribute for field_name, value, expected_size in ( @@ -327,20 +340,20 @@ def test_get_catalogue(): ("line_type", "OvErHeAd", 122), ("material", "Cu", 121), # ("insulator", Insulator.SE, 240), - ("section", 150, 9), - ("section", Q_(1.5, "cm²"), 9), + ("section", 150, 13), + ("section", Q_(1.5, "cm²"), 13), ): filtered_catalogue = LineParameters.get_catalogue(**{field_name: value}) - assert filtered_catalogue.shape == (expected_size, 8) + assert filtered_catalogue.shape == (expected_size, 8), f"Failed for {field_name}={value}" # Filter on two attributes for field_name, value, expected_size in ( ("name", r"U_AL_150.*", 1), - ("line_type", "OvErHeAd", 122), - ("section", 150, 9), + ("line_type", "OvErHeAd", 40), + ("section", 150, 7), ): - filtered_catalogue = LineParameters.get_catalogue(**{field_name: value}) - assert filtered_catalogue.shape == (expected_size, 8) + filtered_catalogue = LineParameters.get_catalogue(**{field_name: value}, material="AL") + assert filtered_catalogue.shape == (expected_size, 8), f"Failed for {field_name}={value}" # No results empty_catalogue = LineParameters.get_catalogue(section=15000) @@ -475,11 +488,8 @@ def test_from_open_dss(): # DSS command: `New linecode.240sq nphases=3 R1=0.127 X1=0.072 R0=0.342 X0=0.089 units=km` r1 = Q_(0.127, "ohm/km") x1 = Q_(0.072, "ohm/km") - r0 = Q_(0.342, "ohm/km") - x0 = Q_(0.089, "ohm/km") c1 = Q_(3.4, "nF/km") - c0 = Q_(1.6, "nF/km") - lp240sq = LineParameters.from_open_dss(id="linecode-240sq", r1=r1, x1=x1, r0=r0, x0=x0, c1=c1, c0=c0) + lp240sq = LineParameters.from_open_dss(id="linecode-240sq", r1=r1, x1=x1, c1=c1) assert lp240sq.id == "linecode-240sq" z_expected = complex(r1.m_as("ohm/km"), x1.m_as("ohm/km")) assert np.isclose(lp240sq.z_line.m, z_expected) @@ -491,13 +501,8 @@ def test_from_open_dss(): # DSS command: `New LineCode.16sq NPhases=1 R1=0.350, X1=0.025, R0=0.366, X0=0.025, C1=1.036, C0=0.488 Units=kft NormAmps=400 LineType=OH` r1 = Q_(0.350, "ohm/kft") x1 = Q_(0.025, "ohm/kft") - r0 = Q_(0.366, "ohm/kft") - x0 = Q_(0.025, "ohm/kft") c1 = Q_(1.036, "nF/kft") - c0 = Q_(0.488, "nF/kft") - lp16sq = LineParameters.from_open_dss( - id="linecode-16sq", r1=r1, x1=x1, r0=r0, x0=x0, c1=c1, c0=c0, linetype="OH", normamps=Q_(400, "A") - ) + lp16sq = LineParameters.from_open_dss(id="linecode-16sq", r1=r1, x1=x1, c1=c1, linetype="OH", normamps=Q_(400, "A")) assert lp16sq.id == "linecode-16sq" z_expected = complex(r1.m_as("ohm/km"), x1.m_as("ohm/km")) assert np.isclose(lp16sq.z_line.m, z_expected) @@ -519,9 +524,6 @@ def test_from_power_factory(): "r1": 0.3225, # Ohm/km "x1": 0.125663, # Ohm/km "b1": 72.25663, # µS/km - "r0": 1.29, # Ohm/km - "x0": 0.502654, # Ohm/km - "b0": 75.05265, # µS/km "inom": 0.235, # kA "cohl": 0, # Cable (underground) "conductor": "Al", # Aluminium diff --git a/roseau/load_flow_single/models/tests/test_lines.py b/roseau/load_flow_single/models/tests/test_lines.py index b1462d4f..b79d4c6d 100644 --- a/roseau/load_flow_single/models/tests/test_lines.py +++ b/roseau/load_flow_single/models/tests/test_lines.py @@ -193,6 +193,33 @@ def test_res_violated(): assert np.allclose(line.res_loading, 12 / 11) +def test_res_state(): + bus1 = Bus(id="bus1") + bus2 = Bus(id="bus2") + lp = LineParameters(id="lp", z_line=1 + 0j) + line = Line(id="line", bus1=bus1, bus2=bus2, parameters=lp, length=Q_(50, "m")) + + line.side1._res_voltage = 230 + line.side2._res_voltage = 225 + line.side1._res_current = 50 + line.side2._res_current = -50 + + # No ampacity + assert line._res_state_getter() == "unknown" + + # With ampacity + lp._ampacity = 100 + assert line._res_state_getter() == "normal" + line.side1._res_current = 80 + assert line._res_state_getter() == "high" + line.side1._res_current = 120 + assert line._res_state_getter() == "very-high" + + # Change max loading + line._max_loading = 1.2 + assert line._res_state_getter() == "high" + + def test_lines_results(): z_line = (0.1 + 0.1j) / 2 y_shunt = None diff --git a/roseau/load_flow_single/models/tests/test_transformers.py b/roseau/load_flow_single/models/tests/test_transformers.py index fe3573ad..a7925ad6 100644 --- a/roseau/load_flow_single/models/tests/test_transformers.py +++ b/roseau/load_flow_single/models/tests/test_transformers.py @@ -80,6 +80,33 @@ def test_res_violated(): assert np.allclose(transformer.res_loading, 87 * 400 * np.sqrt(3) / 50_000) +def test_res_state(): + bus1 = Bus(id="bus1") + bus2 = Bus(id="bus2") + tp = TransformerParameters.from_open_and_short_circuit_tests( + id="tp", vg="Yzn11", sn=50e3, uhv=20e3, ulv=400, p0=145, i0=0.018, psc=1350, vsc=0.04 + ) + tr = Transformer(id="transformer", bus_hv=bus1, bus_lv=bus2, parameters=tp) + + def current(s, u): + return s / (np.sqrt(3) * u) + + tr.side_hv._res_voltage = 20e3 + tr.side_lv._res_voltage = 400 + tr.side_hv._res_current = current(30e3, 20e3) + tr.side_lv._res_current = current(-30e3, 400) + + assert tr._res_state_getter() == "normal" + tr.side_hv._res_current = current(45e3, 20e3) + assert tr._res_state_getter() == "high" + tr.side_hv._res_current = current(60e3, 20e3) + assert tr._res_state_getter() == "very-high" + + # Change max loading + tr._max_loading = 1.2 + assert tr._res_state_getter() == "high" + + def test_transformer_results(): bus_hv = Bus(id="bus_hv") bus_lv = Bus(id="bus_lv") diff --git a/roseau/load_flow_single/models/transformers.py b/roseau/load_flow_single/models/transformers.py index 79f3ee45..24fc6548 100644 --- a/roseau/load_flow_single/models/transformers.py +++ b/roseau/load_flow_single/models/transformers.py @@ -4,7 +4,7 @@ from shapely.geometry.base import BaseGeometry from roseau.load_flow import RoseauLoadFlowException, RoseauLoadFlowExceptionCode -from roseau.load_flow.typing import Float, Id, JsonDict +from roseau.load_flow.typing import Float, Id, JsonDict, ResultState from roseau.load_flow.units import Q_, ureg_wraps from roseau.load_flow.utils import deprecate_renamed_parameters from roseau.load_flow_engine.cy_engine import CySingleTransformer @@ -180,6 +180,17 @@ def _res_loading_getter(self, warning: bool) -> float: power_lv = self._side2._res_power_getter(warning=False) # warn only once return max(abs(power_hv), abs(power_lv)) / sn + def _res_state_getter(self) -> ResultState: + """Get the state of the transformer based on its loading.""" + loading = self._res_loading_getter(warning=False) + max_loading = self._max_loading + if loading > max_loading: + return "very-high" + elif loading > 0.75 * max_loading: + return "high" + else: + return "normal" + @property @ureg_wraps("", (None,)) def res_loading(self) -> Q_[float]: diff --git a/roseau/load_flow_single/network.py b/roseau/load_flow_single/network.py index 7624b964..1b2da454 100644 --- a/roseau/load_flow_single/network.py +++ b/roseau/load_flow_single/network.py @@ -284,6 +284,7 @@ def to_graph(self, *, respect_switches: bool = True) -> "MultiGraph": id=line.id, type="line", parameters_id=line.parameters.id, + length=line._length, max_loading=line._max_loading, ampacity=line.parameters._ampacity, geom=geom_mapping(line.geometry), @@ -297,6 +298,7 @@ def to_graph(self, *, respect_switches: bool = True) -> "MultiGraph": parameters_id=transformer.parameters.id, max_loading=transformer._max_loading, sn=transformer.parameters._sn, + tap=transformer._tap, geom=geom_mapping(transformer.geometry), ) for switch in self.switches.values(): @@ -664,6 +666,10 @@ def _get_starting_voltage(self) -> tuple[complex, VoltageSource]: starting_source = source return starting_source._voltage, starting_source + def _get_starting_bus_id(self) -> Id: + _, starting_source = self._get_starting_voltage() + return starting_source.bus.id + @classmethod def _check_ref(cls, elements: Iterable[Element]) -> None: pass # potential reference is managed internally diff --git a/roseau/load_flow_single/plotting.py b/roseau/load_flow_single/plotting.py index e132ecc8..49d6a96d 100644 --- a/roseau/load_flow_single/plotting.py +++ b/roseau/load_flow_single/plotting.py @@ -1,13 +1,21 @@ -from collections.abc import Callable, Mapping, Sequence -from typing import TYPE_CHECKING, Any +from collections.abc import Callable, Mapping +from typing import TYPE_CHECKING, Any, Literal import geopandas as gpd -from roseau.load_flow.plotting import _check_folium, _plot_interactive_map_internal +from roseau.load_flow.plotting import ( + _RESULT_COLORS, + _check_folium, + _plot_interactive_map_internal, + _pp_num, + _pu_to_pct, + _VoltageProfile, +) +from roseau.load_flow.typing import Id +from roseau.load_flow_single.models import Transformer from roseau.load_flow_single.network import ElectricalNetwork if TYPE_CHECKING: - import branca.colormap as cm import folium from roseau.load_flow.plotting import FeatureMap, StyleDict @@ -24,6 +32,7 @@ def plot_interactive_map( add_tooltips: bool = True, add_popups: bool = True, add_search: bool = True, + fit_bounds: bool = True, ) -> "folium.Map": """Plot an electrical network on an interactive map. @@ -31,10 +40,12 @@ def plot_interactive_map( Make sure you have defined the geometry of the buses and lines in the network before using this function. You can do this by setting the `geometry` attribute of the buses and lines. + Transformers use the geometry of their HV buses. Args: network: - The electrical network to plot. Only the buses and lines are currently plotted. + The electrical network to plot. Buses, lines and transformers are plotted. Buses of + source elements are represented with bigger square markers. style_color: The color of the default style of an element. Defaults to :roseau-primary:`■ #234e83`. @@ -53,8 +64,8 @@ def plot_interactive_map( map_kws: Additional keyword arguments to pass to the :class:`folium.Map` constructor. By default, - `location` is set to the centroid of the network geometry and `zoom_start` is calculated - based on its bounding box. + if ``fit_bounds`` is false, `location` is set to the centroid of the network geometry + and `zoom_start` is calculated based on its bounding box. add_tooltips: If ``True`` (default), tooltips will be added to the map elements. Tooltips appear when @@ -68,6 +79,11 @@ def plot_interactive_map( If ``True`` (default), a search bar will be added to the map to search for network elements by their ID. + fit_bounds: + If ``True`` (default), the map view will be adjusted to fit all network elements. If + ``False``, the initial view is determined by the `location` and `zoom_start` parameters + in `map_kws`. + Returns: The :class:`folium.Map` object with the network plot. """ @@ -82,45 +98,77 @@ def plot_interactive_map( buses_gdf["element_type"] = "bus" buses_gdf["min_voltage_level"] *= 100 # Convert to percentage buses_gdf["max_voltage_level"] *= 100 # Convert to percentage + lines_gdf = network.lines_frame lines_gdf.reset_index(inplace=True) lines_gdf["element_type"] = "line" lines_gdf["max_loading"] *= 100 # Convert to percentage lines_gdf[["ampacity", "section", "line_type", "material", "insulator"]] = None for idx in lines_gdf.index: - lp = network.lines[lines_gdf.at[idx, "id"]].parameters + line_id: Id = lines_gdf.at[idx, "id"] # type: ignore + lp = network.lines[line_id].parameters lines_gdf.at[idx, "ampacity"] = lp._ampacity lines_gdf.at[idx, "section"] = lp._section lines_gdf.at[idx, "line_type"] = lp._line_type lines_gdf.at[idx, "material"] = lp._material lines_gdf.at[idx, "insulator"] = lp._insulator - bus_fields = { - "id": "Id:", - "nominal_voltage": "Un (V):", - "min_voltage_level": "Umin (%):", - "max_voltage_level": "Umax (%):", - } - line_fields = { - "id": "Id:", - "bus1_id": "Bus1:", - "bus2_id": "Bus2:", - "parameters_id": "Parameters:", - "length": "Length (km):", - "line_type": "Line Type:", - "material": "Material:", - "insulator": "Insulator:", - "section": "Section (mm²):", - "ampacity": "Ampacity (A):", - "max_loading": "Max loading (%):", - } + transformers_gdf = network.transformers_frame + transformers_gdf.reset_index(inplace=True) + transformers_gdf["element_type"] = "transformer" + transformers_gdf["tap"] *= 100 # Convert to percentage + transformers_gdf[["hv_side", "lv_side"]] = "" + transformers_gdf[["vg", "sn", "uhv", "ulv"]] = None + for idx in transformers_gdf.index: + tr_id: Id = transformers_gdf.at[idx, "id"] # type: ignore + # Replace geometry with that of the HV bus + bus_hv_id: Id = transformers_gdf.at[idx, "bus_hv_id"] # type: ignore + transformers_gdf.at[idx, "geometry"] = network.buses[bus_hv_id].geometry # type: ignore + lp = network.transformers[tr_id].parameters + transformers_gdf.at[idx, "vg"] = lp.vg + transformers_gdf.at[idx, "sn"] = lp._sn / 1e3 # Convert to kVA + transformers_gdf.at[idx, "uhv"] = lp._uhv + transformers_gdf.at[idx, "ulv"] = lp._ulv m = _plot_interactive_map_internal( - buses_gdf=buses_gdf, - lines_gdf=lines_gdf, - bus_fields=bus_fields, - line_fields=line_fields, - style_color_callback=lambda et, id: style_color, + network=network, + dataframes={"bus": buses_gdf, "line": lines_gdf, "transformer": transformers_gdf}, + fields={ + "bus": { + "id": "Id:", + "nominal_voltage": "Un (V):", + "min_voltage_level": "Umin (%):", + "max_voltage_level": "Umax (%):", + }, + "line": { + "id": "Id:", + "bus1_id": "Bus1:", + "bus2_id": "Bus2:", + "parameters_id": "Parameters:", + "length": "Length (km):", + "line_type": "Line Type:", + "material": "Material:", + "insulator": "Insulator:", + "section": "Section (mm²):", + "ampacity": "Ampacity (A):", + "max_loading": "Max loading (%):", + }, + "transformer": { + "id": "Id:", + "vg": "Vector Group:", + "sn": "Sn (kVA):", + "tap": "Tap Position (%):", + "parameters_id": "Parameters:", + "max_loading": "Max loading (%):", + "hv_side": "HV Side", + "bus_hv_id": "» Bus:", + "uhv": "» Ur (V):", + "lv_side": "LV Side", + "bus_lv_id": "» Bus:", + "ulv": "» Ur (V):", + }, + }, + style_color_callback=lambda et, id: "#000000" if et == "transformer" else style_color, highlight_color=highlight_color, style_function=style_function, highlight_function=highlight_function, @@ -128,6 +176,7 @@ def plot_interactive_map( add_tooltips=add_tooltips, add_popups=add_popups, add_search=add_search, + fit_bounds=fit_bounds, ) return m @@ -139,26 +188,27 @@ def plot_results_interactive_map( highlight_color: str = "#cad40e", style_function: Callable[["FeatureMap"], "StyleDict | None"] | None = None, highlight_function: Callable[["FeatureMap"], "StyleDict | None"] | None = None, - bus_colormap: "cm.ColorMap | Sequence[str] | None" = None, - line_colormap: "cm.ColorMap | Sequence[str] | None" = None, map_kws: Mapping[str, Any] | None = None, add_tooltips: bool = True, add_popups: bool = True, add_search: bool = True, + fit_bounds: bool = True, ) -> "folium.Map": """Plot an electrical network on an interactive map with the load flow results. This function uses the `folium` library to create an interactive map of the electrical network - with the buses colored according to their voltage levels and the lines colored according to their - loading. + with buses colored according to their voltage levels and lines/transformers colored according to + their loadings. Make sure you have defined the geometry of the buses and lines in the network before using this - function. You can do this by setting the `geometry` attribute of the buses and lines. Also, - ensure that the network has valid results by running a load flow calculation before plotting. + function. You can do this by setting the `geometry` attribute of the buses and lines. + Transformers use the geometry of their HV buses. Also, ensure that the network has valid results + by running a load flow calculation before plotting. Args: network: - The electrical network to plot. Only the buses and lines are currently plotted. + The electrical network to plot. Buses, lines and transformers are plotted. Buses of + source elements are represented with bigger square markers. style_color: The color of the default style of an element. Defaults to :roseau-primary:`■ #234e83`. @@ -169,28 +219,17 @@ def plot_results_interactive_map( style_function: Function mapping a GeoJson Feature to a style dict. If not provided or when it returns - ``None``, the default style is used. + ``None``, the default style is used. By default, buses and lines are colored according + to their voltage levels and loadings, respectively. highlight_function: Function mapping a GeoJson Feature to a style dict for mouse events. If not provided or when it returns ``None``, the default highlight style is used. - bus_colormap: - A callable that takes a voltage level in % and returns a color for the bus markers - or a sequence of colors to create a linear colormap representing the voltage level - from minimum to maximum. If not provided, a linear colormap is created with the - colors ``["blue", "cyan", "green", "yellow", "red"]`` - - line_colormap: - A callable that takes a loading in % and returns a color for the line markers or a - sequence of colors to create a linear colormap representing the loading from 0% to - maximum. If not provided, a linear colormap is created with the colors - ``["green", "yellow", "red"]``. - map_kws: Additional keyword arguments to pass to the :class:`folium.Map` constructor. By default, - `location` is set to the centroid of the network geometry and `zoom_start` is calculated - based on its bounding box. + if ``fit_bounds`` is false, `location` is set to the centroid of the network geometry + and `zoom_start` is calculated based on its bounding box. add_tooltips: If ``True`` (default), tooltips will be added to the map elements. Tooltips appear when @@ -204,138 +243,184 @@ def plot_results_interactive_map( If ``True`` (default), a search bar will be added to the map to search for network elements by their ID. + fit_bounds: + If ``True`` (default), the map view will be adjusted to fit all network elements. If + ``False``, the initial view is determined by the `location` and `zoom_start` parameters + in `map_kws`. + Returns: The `folium.Map` object with the network plot. """ _check_folium(func_name="plot_results_interactive_map") - import branca.colormap as cm if network.is_multi_phase: - # TODO: add " Did you mean to use rlf.plotting.plot_results_interactive_map?" when it is implemented - raise TypeError("Only single-phase networks can be plotted.") + raise TypeError( + "Only single-phase networks can be plotted. Did you mean to use rlf.plotting.plot_results_interactive_map?" + ) network._check_valid_results() - min_voltage = float("inf") - max_voltage = 0.0 - max_loading = 0.0 - buses_data = [] - buses_voltage_levels = {} + buses_data: dict[str, list[Any]] = { + "id": [], + "element_type": [], + "nominal_voltage": [], + "min_voltage_level": [], + "max_voltage_level": [], + "geometry": [], + "res_separator": [], + "res_voltage": [], + "res_voltage_level": [], + } + buses_ids: list[Id] = [] for bus in network.buses.values(): - if bus._nominal_voltage is None: - no_nominal_voltage = [bus.id for bus in network.buses.values() if bus._nominal_voltage is None] - raise ValueError(f"The following buses do not have a nominal voltage defined: {no_nominal_voltage}.") - if bus._min_voltage_level is None: - no_min_voltage = [bus.id for bus in network.buses.values() if bus._min_voltage_level is None] - raise ValueError(f"The following buses do not have a minimum voltage level defined: {no_min_voltage}.") - if bus._max_voltage_level is None: - no_max_voltage = [bus.id for bus in network.buses.values() if bus._max_voltage_level is None] - raise ValueError(f"The following buses do not have a maximum voltage level defined: {no_max_voltage}.") - min_voltage = min(min_voltage, bus._min_voltage_level * 100) - max_voltage = max(max_voltage, bus._max_voltage_level * 100) - res_voltage_level = bus._res_voltage_level_getter(warning=False) - assert res_voltage_level is not None - res_voltage_level *= 100 - buses_data.append( - { - "id": bus.id, - "element_type": "bus", - "nominal_voltage": bus._nominal_voltage, - "min_voltage_level": bus._min_voltage_level * 100, - "max_voltage_level": bus._max_voltage_level * 100, - "geometry": bus.geometry, - "res_separator": "", # Results separator - "res_voltage": abs(bus.res_voltage.m), - "res_voltage_level": res_voltage_level, - } - ) - buses_voltage_levels[bus.id] = res_voltage_level - - lines_data = [] - lines_loading = {} + buses_ids.append(bus.id) + buses_data["id"].append(bus.id) + buses_data["element_type"].append("bus") + buses_data["nominal_voltage"].append(bus._nominal_voltage) + buses_data["min_voltage_level"].append(_pu_to_pct(bus._min_voltage_level)) + buses_data["max_voltage_level"].append(_pu_to_pct(bus._max_voltage_level)) + buses_data["geometry"].append(bus.geometry) + buses_data["res_separator"].append("") # Results separator + buses_data["res_voltage"].append(abs(bus._res_voltage_getter(warning=False))) + buses_data["res_voltage_level"].append(_pu_to_pct(bus._res_voltage_level_getter(warning=False))) + + lines_data: dict[str, list[Any]] = { + "id": [], + "element_type": [], + "bus1_id": [], + "bus2_id": [], + "parameters_id": [], + "length": [], + "line_type": [], + "material": [], + "insulator": [], + "section": [], + "ampacity": [], + "geometry": [], + "res_separator": [], + "max_loading": [], + "res_loading": [], + } for line in network.lines.values(): - lp = line.parameters - if lp._ampacity is None: - no_ampacity = list(dict.fromkeys(lp.id for line in network.lines.values() if lp._ampacity is None)) - raise ValueError(f"The following line parameters do not have an ampacity defined: {no_ampacity}.") - max_loading = max(max_loading, line._max_loading * 100) - res_loading = line._res_loading_getter(warning=False) - assert res_loading is not None - res_loading *= 100 - lines_data.append( - { - "id": line.id, - "element_type": "line", - "bus1_id": line.bus1.id, - "bus2_id": line.bus2.id, - "parameters_id": lp.id, - "length": line._length, - "line_type": lp._line_type, - "material": lp._material, - "insulator": lp._insulator, - "section": lp._section, - "ampacity": lp._ampacity, - "geometry": line.geometry, - "res_separator": "", # Results separator - "max_loading": line._max_loading * 100, - "res_loading": res_loading, - } - ) - lines_loading[line.id] = res_loading + lines_data["id"].append(line.id) + lines_data["element_type"].append("line") + lines_data["bus1_id"].append(line.bus1.id) + lines_data["bus2_id"].append(line.bus2.id) + lines_data["parameters_id"].append(line._parameters.id) + lines_data["length"].append(line._length) + lines_data["line_type"].append(line._parameters._line_type) + lines_data["material"].append(line._parameters._material) + lines_data["insulator"].append(line._parameters._insulator) + lines_data["section"].append(line._parameters._section) + lines_data["ampacity"].append(line._parameters._ampacity) + lines_data["geometry"].append(line.geometry) + lines_data["res_separator"].append("") # Results separator + lines_data["max_loading"].append(line._max_loading * 100) + lines_data["res_loading"].append(_pu_to_pct(line._res_loading_getter(warning=False))) + + def _get_tr_buses_data(tr: Transformer, field: str) -> str: + return _pp_num([buses_data[field][buses_ids.index(bus_id)] for bus_id in (tr.bus_hv.id, tr.bus_lv.id)]) + + transformers_data: dict[str, list[Any]] = { + "id": [], + "element_type": [], + "bus_hv_id": [], + "bus_lv_id": [], + "parameters_id": [], + "geometry": [], + "vg": [], + "sn": [], + "tap": [], + "rated_voltages": [], + "max_loading": [], + "nominal_voltages": [], + "min_voltage_levels": [], + "max_voltage_levels": [], + "res_separator": [], + "res_loading": [], + "res_voltages": [], + "res_voltage_levels": [], + } + for tr in network.transformers.values(): + transformers_data["id"].append(tr.id) + transformers_data["element_type"].append("transformer") + transformers_data["bus_hv_id"].append(tr.bus_hv.id) + transformers_data["bus_lv_id"].append(tr.bus_lv.id) + transformers_data["parameters_id"].append(tr._parameters.id) + transformers_data["geometry"].append(tr.bus_hv.geometry) + transformers_data["vg"].append(tr._parameters.vg) + transformers_data["sn"].append(tr._parameters._sn / 1e3) # Convert to kVA + transformers_data["tap"].append(tr._tap * 100) # Convert to percentage + transformers_data["rated_voltages"].append(_pp_num([tr._parameters._uhv, tr._parameters._ulv])) + transformers_data["max_loading"].append(tr._max_loading * 100) + transformers_data["nominal_voltages"].append(_get_tr_buses_data(tr, "nominal_voltage")) + transformers_data["min_voltage_levels"].append(_get_tr_buses_data(tr, "min_voltage_level")) + transformers_data["max_voltage_levels"].append(_get_tr_buses_data(tr, "max_voltage_level")) + transformers_data["res_separator"].append("") # Results separator + transformers_data["res_loading"].append(tr._res_loading_getter(warning=False) * 100) + transformers_data["res_voltages"].append(_get_tr_buses_data(tr, "res_voltage")) + transformers_data["res_voltage_levels"].append(_get_tr_buses_data(tr, "res_voltage_level")) buses_gdf = gpd.GeoDataFrame(buses_data, crs=network.crs) lines_gdf = gpd.GeoDataFrame(lines_data, crs=network.crs) - if not isinstance(bus_colormap, cm.ColorMap): - bus_colormap = cm.LinearColormap( - colors=["blue", "cyan", "green", "yellow", "red"] if bus_colormap is None else bus_colormap, - vmin=min_voltage, - vmax=max_voltage, - caption="Voltage level (%)", - ) - if not isinstance(line_colormap, cm.ColorMap): - line_colormap = cm.LinearColormap( - ["green", "yellow", "red"] if line_colormap is None else line_colormap, - vmin=0, - vmax=max_loading, - caption="Line loading %", - ) + transformers_gdf = gpd.GeoDataFrame(transformers_data, crs=network.crs) def style_color_callback(et, eid): if et == "bus": - return bus_colormap(buses_voltage_levels[eid]) + return _RESULT_COLORS[network.buses[eid]._res_state_getter()] elif et == "line": - return line_colormap(lines_loading[eid]) + return _RESULT_COLORS[network.lines[eid]._res_state_getter()] + elif et == "transformer": + return _RESULT_COLORS[network.transformers[eid]._res_state_getter()] else: return style_color - bus_fields = { - "id": "Id:", - "nominal_voltage": "Un (V):", - "min_voltage_level": "Umin (%):", - "max_voltage_level": "Umax (%):", - "res_separator": "--", - "res_voltage": "U (V):", - "res_voltage_level": "U (%):", - } - line_fields = { - "id": "Id:", - "bus1_id": "Bus1:", - "bus2_id": "Bus2:", - "parameters_id": "Parameters:", - "length": "Length (km):", - "line_type": "Line Type:", - "material": "Material:", - "insulator": "Insulator:", - "section": "Section (mm²):", - "ampacity": "Ampacity (A):", - "max_loading": "Max loading (%):", - "res_separator": "--", - "res_loading": "Loading (%):", - } m = _plot_interactive_map_internal( - buses_gdf=buses_gdf, - lines_gdf=lines_gdf, - bus_fields=bus_fields, - line_fields=line_fields, + network=network, + dataframes={"bus": buses_gdf, "line": lines_gdf, "transformer": transformers_gdf}, + fields={ + "bus": { + "id": "Id:", + "nominal_voltage": "Un (V):", + "min_voltage_level": "Umin (%):", + "max_voltage_level": "Umax (%):", + "res_separator": "--", + "res_voltage": "U (V):", + "res_voltage_level": "U (%):", + }, + "line": { + "id": "Id:", + "bus1_id": "Bus1:", + "bus2_id": "Bus2:", + "parameters_id": "Parameters:", + "length": "Length (km):", + "line_type": "Line Type:", + "material": "Material:", + "insulator": "Insulator:", + "section": "Section (mm²):", + "ampacity": "Ampacity (A):", + "max_loading": "Max loading (%):", + "res_separator": "--", + "res_loading": "Loading (%):", + }, + "transformer": { + "id": "Id:", + "bus_hv_id": "HV Bus:", + "bus_lv_id": "LV Bus:", + "vg": "Vector Group:", + "sn": "Sn (kVA):", + "rated_voltages": "Ur [ʜv,ʟv] (V):", + "tap": "Tap Position (%):", + "parameters_id": "Parameters:", + "max_loading": "Max loading (%):", + "nominal_voltages": "Un [ʜv,ʟv] (V):", + "min_voltage_levels": "Umin [ʜv,ʟv] (%):", + "max_voltage_levels": "Umax [ʜv,ʟv] (%):", + "res_separator": "--", + "res_loading": "Loading (%):", + "res_voltages": "U [ʜv,ʟv] (V):", + "res_voltage_levels": "U [ʜv,ʟv] (%):", + }, + }, style_color_callback=style_color_callback, highlight_color=highlight_color, style_function=style_function, @@ -344,8 +429,59 @@ def style_color_callback(et, eid): add_tooltips=add_tooltips, add_popups=add_popups, add_search=add_search, + fit_bounds=fit_bounds, ) - bus_colormap.add_to(m) - line_colormap.add_to(m) - return m + + +def voltage_profile( + network: ElectricalNetwork, + *, + starting_bus_id: Id | None = None, + traverse_transformers: bool = False, + switch_length: float | None = None, + distance_unit: str = "km", +) -> _VoltageProfile[ElectricalNetwork, Literal[""]]: + """Create a voltage profile of the network. + + A voltage profile shows the voltage (in %) of buses in the network as a function of distance + from a starting bus. Lines and transformers are also represented, colored according to their + loading levels. + + The network does not need to have geometries defined for this function to work, as distances are + calculated based on line lengths. However, the network must have valid load flow results, and + relevant buses must have nominal voltages defined. + + Args: + network: + The electrical network to create the voltage profile for. + + starting_bus_id: + The ID of the bus to start the profile from. If None, the bus of the source with the + highest voltage is used. + + traverse_transformers: + If True, the entire network is traversed including transformers. If False, transformers + are not traversed. + + switch_length: + The length in km to assign to switches when calculating distances. If None, it is set to + the minimum of 2 meters and the shortest line in the network. Must be non-negative. + + distance_unit: + The unit to use for distances in the profile. Defaults to "km". + + Returns: + An object containing the voltage profile data for plotting. Use its plotting methods to + create plots. E.g., ``rlfs.plotting.voltage_profile(en).plot_matplotlib()``. + """ + if network.is_multi_phase: + raise TypeError("Only single-phase networks can be plotted. Did you mean to use rlf.plotting.voltage_profile?") + return _VoltageProfile._from_network( + network, + mode="", + starting_bus_id=starting_bus_id, + traverse_transformers=traverse_transformers, + switch_length=switch_length, + distance_unit=distance_unit, + ) diff --git a/roseau/load_flow_single/tests/test_electrical_network.py b/roseau/load_flow_single/tests/test_electrical_network.py index 12a75790..067b66a6 100644 --- a/roseau/load_flow_single/tests/test_electrical_network.py +++ b/roseau/load_flow_single/tests/test_electrical_network.py @@ -3,7 +3,6 @@ import json import re import warnings -from pathlib import Path import geopandas as gpd import networkx as nx @@ -38,36 +37,6 @@ from roseau.load_flow_single.network import ElectricalNetwork -# The following networks are generated using the scripts/generate_test_networks.py script -@pytest.fixture -def all_elements_network_path(test_networks_path) -> Path: - return test_networks_path / "all_elements_network.json" - - -@pytest.fixture -def all_elements_network(all_elements_network_path) -> ElectricalNetwork: - """Load the network from the JSON file (without results).""" - return ElectricalNetwork.from_json(path=all_elements_network_path, include_results=False) - - -@pytest.fixture -def all_elements_network_with_results(all_elements_network_path) -> ElectricalNetwork: - """Load the network from the JSON file (with results, no need to invoke the solver).""" - return ElectricalNetwork.from_json(path=all_elements_network_path, include_results=True) - - -@pytest.fixture -def small_network(test_networks_path) -> ElectricalNetwork: - """Load the network from the JSON file (without results).""" - return ElectricalNetwork.from_json(path=test_networks_path / "small_network.json", include_results=False) - - -@pytest.fixture -def small_network_with_results(test_networks_path) -> ElectricalNetwork: - """Load the network from the JSON file (with results, no need to invoke the solver).""" - return ElectricalNetwork.from_json(path=test_networks_path / "small_network.json", include_results=True) - - def strip_q(value): return None if value is None else value.m @@ -933,6 +902,63 @@ def test_propagate_voltages(): assert np.allclose(source_bus.initial_voltage.m, expected_voltages) +def test_propagate_nominal_voltages(all_elements_network): + en = all_elements_network + # Test that it works even if some nominal voltages are missing + assert en.buses["bus0"].nominal_voltage is None + assert en.buses["bus4"].nominal_voltage is None + nominal_voltages = en._get_nominal_voltages() + assert nominal_voltages == { + "bus1": 20000.0, + "bus2": 400, + "bus3": 400, + "bus0": 20000.0, + "bus4": 400, + } + + # No nominal voltages in the network + for bus in en.buses.values(): + bus._min_voltage_level = None + bus._max_voltage_level = None + bus._nominal_voltage = None + nominal_voltages = en._get_nominal_voltages() + assert nominal_voltages == { + "bus1": 20000.0, + "bus2": 400, + "bus3": 400, + "bus0": 20000.0, + "bus4": 400, + } + + # No transformer + bus1 = Bus(id="bus1") + bus2 = Bus(id="bus2") + VoltageSource(id="vs", bus=bus1, voltage=20e3) + Switch(id="sw", bus1=bus1, bus2=bus2) + en = ElectricalNetwork.from_element(bus1) + assert not en.transformers, "This test requires a network without transformers" + nominal_voltages = en._get_nominal_voltages() + npt.assert_allclose(list(nominal_voltages.values()), 20e3) + + # With transformer and one nominal voltage at the source + bus1 = Bus(id="bus1", nominal_voltage=20.5e3) + bus2 = Bus(id="bus2") + bus3 = Bus(id="bus3") + VoltageSource(id="vs", bus=bus1, voltage=21e3) + Switch(id="sw", bus1=bus1, bus2=bus2) + tp = TransformerParameters.from_open_and_short_circuit_tests( + id="t1", vg="Dyn11", uhv=20e3, ulv=400, sn=100e3, p0=200, i0=1.5e-2, psc=1e3, vsc=4e-2 + ) + Transformer(id="t1", bus_hv=bus2, bus_lv=bus3, parameters=tp) + en = ElectricalNetwork.from_element(bus1) + nominal_voltages = en._get_nominal_voltages() + assert nominal_voltages == { + "bus1": 20.5e3, # the expected vn from the source bus (not the transformer or the source) + "bus2": 20.5e3, + "bus3": 410.0, + } + + def test_catalogue_data(): # The catalogue data path exists catalogue_path = ElectricalNetwork.catalogue_path() @@ -1083,6 +1109,7 @@ def test_to_graph(small_network: ElectricalNetwork): "parameters_id": line.parameters.id, "max_loading": line.max_loading.m, "ampacity": ampacity, + "length": line.length.m, "geom": line.geometry.__geo_interface__ if line.geometry is not None else None, } @@ -1094,6 +1121,7 @@ def test_to_graph(small_network: ElectricalNetwork): "parameters_id": transformer.parameters.id, "max_loading": transformer.max_loading.m, "sn": transformer.sn.m, + "tap": transformer.tap, "geom": transformer.geometry.__geo_interface__ if transformer.geometry is not None else None, } diff --git a/roseau/load_flow_single/tests/test_multi_compat.py b/roseau/load_flow_single/tests/test_multi_compat.py index 00bbf1af..acf32dc1 100644 --- a/roseau/load_flow_single/tests/test_multi_compat.py +++ b/roseau/load_flow_single/tests/test_multi_compat.py @@ -8,7 +8,7 @@ def test_import(): # Ensure that RLF and RLFS have nearly the same interface - rlf_dir = set(dir(rlf)) - {"ConductorType", "InsulatorType"} + rlf_dir = set(dir(rlf)) - {"ConductorType", "InsulatorType", "__warningregistry__"} rlfs_dir = set(dir(rlfs)) assert rlf_dir - rlfs_dir == { diff --git a/roseau/load_flow_single/tests/test_plotting.py b/roseau/load_flow_single/tests/test_plotting.py new file mode 100644 index 00000000..ba4bfed9 --- /dev/null +++ b/roseau/load_flow_single/tests/test_plotting.py @@ -0,0 +1,119 @@ +import roseau.load_flow_single as rlfs +from roseau.load_flow.testing import assert_json_close + + +def test_plot_interactive_map(all_elements_network_with_results): + en = all_elements_network_with_results + en.crs = "EPSG:4326" + rlfs.plotting.plot_interactive_map(en) + rlfs.plotting.plot_results_interactive_map(en) + + +def test_voltage_profile(all_elements_network_with_results): + en = all_elements_network_with_results + for bus_id, vn in en._get_nominal_voltages().items(): + en.buses[bus_id].nominal_voltage = vn + en.buses["bus1"].min_voltage_level = 0.9 + en.buses["bus1"].max_voltage_level = 1.1 + profile = rlfs.plotting.voltage_profile(en) + assert profile.starting_bus_id == next(iter(profile.network.sources.values())).bus.id + assert_json_close( + profile.buses, + { + "bus0": { + "distance": 0.0, + "voltage": profile.network.buses["bus0"].res_voltage_level.m * 100, # type: ignore + "voltages": None, + "min_voltage": None, + "max_voltage": None, + "state": "unknown", # no voltage limits + "is_tr_bus": False, + }, + "bus1": { + "distance": 1.5, + "voltage": profile.network.buses["bus1"].res_voltage_level.m * 100, # type: ignore + "voltages": None, + "min_voltage": 90, + "max_voltage": 110, + "state": "normal", + "is_tr_bus": False, # because traverse_transformers=False by default + }, + }, + ) + assert_json_close( + profile.lines, + { + "line0": { + "from_bus": "bus0", + "to_bus": "bus1", + "loading": profile.network.lines["line0"].res_loading.m * 100, # type: ignore + "loadings": None, + "max_loading": 100.0, + "state": "normal", + }, + }, + ) + assert not profile.transformers # because traverse_transformers=False by default + + +def test_voltage_profile_traverse_transformers(all_elements_network_with_results): + en = all_elements_network_with_results + for bus_id, vn in en._get_nominal_voltages().items(): + en.buses[bus_id].nominal_voltage = vn + profile = rlfs.plotting.voltage_profile(en, traverse_transformers=True) + assert profile.starting_bus_id == next(iter(profile.network.sources.values())).bus.id + assert len(profile.buses) == len(profile.network.buses) + assert profile.buses["bus0"]["is_tr_bus"] is False + assert profile.buses["bus1"]["is_tr_bus"] is True + assert profile.buses["bus2"]["is_tr_bus"] is True + assert profile.buses["bus3"]["is_tr_bus"] is False + assert len(profile.lines) == len(profile.network.lines) + tr = profile.network.transformers["transformer0"] + assert_json_close( + profile.transformers, + { + "transformer0": { + "from_bus": "bus1", + "to_bus": "bus2", + "loading": tr.res_loading.m * 100, + "loadings": None, + "max_loading": tr.max_loading.m * 100, + "state": "normal", + }, + }, + ) + + +def test_voltage_profile_parallel_branches(): + bus1 = rlfs.Bus(id="Bus 1", nominal_voltage=400) + bus2 = rlfs.Bus(id="Bus 2", nominal_voltage=400) + lp = rlfs.LineParameters.from_catalogue("U_AL_120") + line1 = rlfs.Line(id="Line 1", bus1=bus1, bus2=bus2, parameters=lp, length=1.0) + line2 = rlfs.Line(id="Line 2", bus1=bus1, bus2=bus2, parameters=lp, length=2.0) + src = rlfs.VoltageSource(id="Src", bus=bus1, voltage=400) + + # Set fake results + bus1._res_voltage = 400 + 0j + bus2._res_voltage = 380 + 0j + line1.side1._res_current = 50 + 0j + line1.side2._res_current = -50 + 0j + line2.side1._res_current = 25 + 0j + line2.side2._res_current = -25 + 0j + src._res_current = -75 + 0j + en = rlfs.ElectricalNetwork.from_element(bus1) + for e in en._elements: + e._fetch_results = False + e._no_results = False + en._results_valid = True + en._no_results = False + + profile = rlfs.plotting.voltage_profile(en) + assert sorted(profile.lines) == ["Line 1", "Line 2"] + assert profile.buses["Bus 1"]["distance"] == 0.0 + assert profile.buses["Bus 2"]["distance"] == 1.0 # shortest path + + line2._length = 1.0 + profile = rlfs.plotting.voltage_profile(en) + assert sorted(profile.lines) == ["Line 1", "Line 2"] + assert profile.buses["Bus 1"]["distance"] == 0.0 + assert profile.buses["Bus 2"]["distance"] == 1.0 # both paths equal length diff --git a/scripts/generate_lv_line_parameters_catalogue.py b/scripts/generate_lv_line_parameters_catalogue.py new file mode 100644 index 00000000..0210e8ac --- /dev/null +++ b/scripts/generate_lv_line_parameters_catalogue.py @@ -0,0 +1,447 @@ +import math +import statistics +import warnings + +import polars as pl + +import roseau.load_flow as rlf + + +def line_parameters( + type: rlf.LineType, material: rlf.Material, insulator: rlf.Insulator, section: float, insulator_thickness: float +) -> tuple[float, float]: + """Compute the line parameters (reactance and susceptance) using IEC/NFC approximate formulas. + + Args: + type: + The line type (overhead, underground, twisted). + + material: + The conductor material (copper, aluminium, aluminium alloy). + + insulator: + The insulator type. + + section: + The conductor section in mm². + + insulator_thickness: + The insulator thickness in mm. + + Returns: + A tuple containing the linear reactance (Ohm/km) and linear susceptance (S/km). + """ + if type == rlf.LineType.OVERHEAD and (insulator != rlf.Insulator.NONE and insulator_thickness != 0): + warnings.warn("Overhead lines should not have an insulator or insulator thickness.", stacklevel=2) + + epsilon_r = rlf.constants.EPSILON_R[insulator].m + + # + # IEC/NFC (approximate) computation + # + # Inductance + radius = math.sqrt(section / math.pi) * 1e-3 # mm -> m + # Geometric mean radius + gmr = radius * math.exp(-1 / 4) # m + + # Geometric mean distance (here distance between conductors in the case of a symmetrical line) + gmd = 1 if type == rlf.LineType.OVERHEAD else 2 * (radius + insulator_thickness * 1e-3) # m + linear_inductance = rlf.constants.MU_0.m / (2 * math.pi) * math.log(gmd / gmr) * 1e3 # H/m -> H/km + linear_capacitance = epsilon_r / (18 * math.log(gmd / radius)) # µF/km + + linear_reactance = linear_inductance * rlf.constants.OMEGA.m + linear_susceptance = rlf.constants.OMEGA.m * linear_capacitance * 1e-6 + + return linear_reactance, linear_susceptance + + +def approx[T](x: T, /) -> T: + """Indicate that the value is approximate, not from a table or measurement.""" + return x + + +def extrapolate[X: float](table: dict[X, float], x: X) -> None: + """Extrapolate a value inplace from a table using linear regression. + + Args: + table: + A dictionary mapping x values to y values. + + x: + The x value to extrapolate. + """ + if x in table: + warnings.warn(f"Value for x={x} already exists in the table, no extrapolation needed.", stacklevel=2) + return + lr = statistics.linear_regression(list(table.keys()), list(table.values())) + table[x] = x * lr.slope + lr.intercept + + +def generate_c33209_lv_twisted_parameters() -> pl.DataFrame: + """Nexans: Network aerial bundled conductors 3-phases+neutral messenger (NF-C-33-209). + + Description + ----------- + + - Messenger + - Core (1): circular stranded in AGS aluminum alloy, cross-section area 54.6 mm² or 70 mm² + - Insulation (2): Black XLPE + - Specifications (54.6 mm²): + - Nominal cross section: 54.6 mm², + - Core diameter: 9.2 mm to 9.6 mm, + - Insulated core diameter: min. 12.3 mm; max. 13.0 mm, min. breaking load 1660 daN, + - Elasticity modulus: 62000 MPa, + - Linear coefficient: 23x10⁶ °C⁻¹. + - Specifications (70 mm²): + - Nominal cross section: 70 mm², + - Core diameter: 10.0 mm to 10.2 mm, + - Insulated core diameter: min. 12.9 mm; max. 13.6 mm, min. breaking load 2050 daN, + - Elasticity modulus: 62000 MPa, + - Linear coefficient: 23x10⁶ °C⁻¹. + - Phase or public lighting conductor + - Core (3): circular stranded (class 2) aluminum. + - Insulation (4): black extruded XLPE. + + Markings + -------- + + - Neutral: 211 NF C 33-209 211 «manufacturing number», «metric marks» ink printed. + - Phase 1, 2, 3: the identification number is printed and embossed on insulation. + - Public lighting: «EP1», «EP2 » is printed and embossed on each conductor. + «EP3» if three conductors are required. + + Electrical characteristics + -------------------------- + + - Rated voltage: 0.6/1 kV + - Test voltage: 4 kV AC + - Resistance to voltage surges: 1.2/50µs with a positive or negative polarity and a peak value + of 20 kV. + + Correction coefficients + ----------------------- + + To apply to the intensity in accordance with the air temperature + + Ambient. temperature °C | 10 | 15 | 20 | 25 | 30 | 35 | 40 | 45 | 50 | 60 | 70 + Coefficient | 1.17 | 1.13 | 1.09 | 1.04 | 1.00 | 0.95 | 0.91 | 0.85 | 0.80 | 0.67 | 0.52 + + Technical characteristics + ------------------------- + + sections | d_core_ph | d_core_pl | d_ins_ph | d_ins_pl | diam | weight | r_ph | r_pl | imax_ph | imax_pl + -------------- | --------- | --------- | -------- | -------- | ---- | ------ | ----- | ---- | ------- | ------- + 3x35+54.6 | 6.8 | - | 10.0 | - | 29.0 | 622 | 0.868 | - | 138 | - + 3x35+54.6+1x16 | 6.8 | 4.6 | 10.0 | 7.0 | 29.0 | 686 | 0.868 | 1.91 | 138 | 83 + 3x35+54.6+2x16 | 6.8 | 4.6 | 10.0 | 7.0 | 29.0 | 753 | 0.868 | 1.91 | 138 | 83 + 3+50+54.6 | 7.9 | - | 11.1 | - | 30.4 | 746 | 0.641 | - | 168 | - + 3x50+54.6+1x16 | 7.9 | 4.6 | 11.1 | 7.0 | 30.4 | 812 | 0.641 | 1.91 | 168 | 83 + 3x50+54.6+2x16 | 7.9 | 4.6 | 11.1 | 7.0 | 30.4 | 877 | 0.641 | 1.91 | 168 | 83 + 3x70+54.6 | 9.7 | - | 13.3 | - | 34.0 | 954 | 0.443 | - | 213 | - + 3x70+54.6+1x16 | 9.7 | 4.6 | 13.3 | 7.0 | 34.0 | 1020 | 0.443 | 1.91 | 213 | 83 + 3x70+54.6+2x16 | 9.7 | 4.6 | 13.3 | 7.0 | 34.0 | 1085 | 0.443 | 1.91 | 213 | 83 + 3x70+70 | 9.7 | - | 13.3 | - | 34.3 | 986 | 0.443 | - | 213 | - + 3x70+70+1x16 | 9.7 | 4.6 | 13.3 | 7.0 | 34.3 | 1051 | 0.443 | 1.91 | 213 | 83 + 3x70+70+2x16 | 9.7 | 4.6 | 13.3 | 7.0 | 34.3 | 1117 | 0.443 | 1.91 | 213 | 83 + 3x95+70* | 11.0 | - | 14.6 | - | 37.0 | 1228 | 0.343 | - | 258 | - + 3x95+70+1x16* | 11.0 | 4.6 | 14.6 | 7.0 | 37.0 | 1294 | 0.343 | 1.91 | 258 | 83 + 3x95+70+2x16* | 11.0 | 4.6 | 14.6 | 7.0 | 37.0 | 1338 | 0.343 | 1.91 | 258 | 83 + 3x150+70 | 13.9 | - | 17.3 | - | 41.4 | 1698 | 0.206 | - | 344 | - + 3x150+70+1x16 | 13.9 | 4.6 | 17.3 | 7.0 | 41.4 | 1763 | 0.206 | 1.91 | 344 | 83 + 3x150+70+2x16 | 13.9 | 4.6 | 17.3 | 7.0 | 41.4 | 1828 | 0.206 | 1.91 | 344 | 83 + + * on demand + + With the following original column names: + - sections: Core cross section (mm²) + - d_core_ph: Diameter in mm / Minimum on core / Phase conductor + - d_core_pl: Diameter in mm / Minimum on core / Public lighting + - d_ins_ph: Diameter in mm / Minimum insulation / Phase conductor + - d_ins_pl: Diameter in mm / Minimum insulation / Public lighting + - diam: Diameter in mm / Bundled conductors (approx.) + - weight: Weight (kg/km) + - r_ph: Maximum linear resistance on the core at 20 °C (Ω/km) / Phase conductor + - r_pl: Maximum linear resistance on the core at 20 °C (Ω/km) / Public lighting + - imax_ph: Current through conductors in continuous operation (A) / Phase conductor + - imax_pl: Current through conductors in continuous operation (A) / Public lighting + + + Full table Technical characteristics + ------------------------------------ + + sections | imax_ph | imax_pl | ext_diam | weight | du | r_ph | r_pl | length | reel + -------------- | ------- | ------- | -------- | ------ | ---- | ----- | ---- | ------ | ---- + 3x25+54.6 | 112 | - | 24 | 531 | 2.20 | 1.200 | - | 2000 | CF + 3x25+54.6+1x16 | 112 | 83 | 25 | 600 | 2.20 | 1.200 | 1.91 | 2000 | CF + 3x25+54.6+2x16 | 112 | 83 | 27.5 | 670 | 2.20 | 1.200 | 1.91 | 2000 | CF + 3x35+54.6 | 138 | - | 24.6 | 641 | 1.65 | 0.868 | - | 2000 | CF + 3x35+54.6+1x16 | 138 | 83 | 25.5 | 710 | 1.65 | 0.868 | 1.91 | 2000 | CF + 3x35+54.6+2x16 | 138 | 83 | 27.5 | 779 | 1.65 | 0.868 | 1.91 | 2000 | CF + 3x50+54.6 | 168 | - | 27 | 770 | 1.27 | 0.641 | - | 2000 | DF + 3x50+54.6+1x16 | 168 | 83 | 28.5 | 839 | 1.27 | 0.641 | 1.91 | 2000 | DF + 3x50+54.6+2x16 | 168 | 83 | 30 | 907 | 1.27 | 0.641 | 1.91 | 2000 | DF + 3x70+54.6 | 213 | - | 30 | 985 | 0.87 | 0.443 | - | 2000 | EF + 3x70+54.6+1x16 | 213 | 83 | 32.2 | 1054 | 0.87 | 0.443 | 1.91 | 2000 | EF + 3x70+54.6+2x16 | 213 | 83 | 33 | 1122 | 0.87 | 0.443 | 1.91 | 2000 | EF + 3x70+70 | 213 | - | 32 | 1019 | 0.87 | 0.443 | - | 1000 | CF + 3x70+70+1x16 | 213 | 83 | 33 | 1087 | 0.87 | 0.443 | 1.91 | 1000 | CF + 3x70+70+2x16 | 213 | 83 | 34 | 1155 | 0.87 | 0.443 | 1.91 | 1000 | CF + 3x95+70 | 258 | - | 35 | 1264 | 0.67 | 0.320 | - | 1000 | CF + 3x95+70+1x16 | 258 | 83 | 36 | 1331 | 0.67 | 0.320 | 1.91 | 1000 | CF + 3x95+70+2x16 | 258 | 83 | 37 | 1398 | 0.67 | 0.320 | 1.91 | 1000 | DF + 3x120+70 | 300 | - | 38 | 1488 | 0.55 | 0.253 | - | 1000 | DF + 3x120+70+1x16 | 300 | 83 | 39 | 1555 | 0.55 | 0.253 | 1.91 | 1000 | DF + 3x120+70+2x16 | 300 | 83 | 40 | 1623 | 0.55 | 0.253 | 1.91 | 1000 | DF + 3x150+70 | 344 | - | 40 | 1731 | 0.46 | 0.206 | - | 1000 | EF + 3x150+70+1x16 | 344 | 83 | 41 | 1799 | 0.46 | 0.206 | 1.91 | 1000 | EF + 3x150+70+2x16 | 344 | 83 | 42 | 1866 | 0.46 | 0.206 | 1.91 | 1000 | EF + 3x120+95 | 300 | - | 39 | 1569 | 0.55 | 0.253 | - | 1000 | EF + 3x120+95+1x16 | 300 | 83 | 40 | 1637 | 0.55 | 0.253 | 1.91 | 1000 | EF + 3x120+95+2x16 | 300 | 83 | 41 | 1704 | 0.55 | 0.253 | 1.91 | 1000 | EF + 3x150+95 | 344 | - | 42 | 1812 | 0.46 | 0.206 | - | 1000 | EF + 3x150+95+1x16 | 344 | 83 | 43 | 1880 | 0.46 | 0.206 | 1.91 | 1000 | EF + 3x150+95+2x16 | 344 | 83 | 44 | 1948 | 0.46 | 0.206 | 1.91 | 1000 | EF + + With the following original column names: + - sections: Core cross section (mm²) + - imax_ph: Current through conductors in continuous operation (A) / Phase conductor + - imax_pl: Current through conductors in continuous operation (A) / Public lighting + - ext_diam: External diameter (mm) + - weight: Weight (kg/km) + - du: Voltage drop with cos(φ) = 0.8 (V/A/km) + - r_ph: Maximum linear resistance on the core at 20 °C (Ω/km) / Phase conductor + - r_pl: Maximum linear resistance on the core at 20 °C (Ω/km) / Public lighting + - length: Length (m) + - reel: Reel type + """ + header = ("sections", "imax_ph", "ext_diam", "weight", "du", "r_ph") + data = [ + ("3x25+54.6", 112, 24, 531, 2.20, 1.200), + ("3x35+54.6", 138, 24.6, 641, 1.65, 0.868), + ("3x50+54.6", 168, 27, 770, 1.27, 0.641), + ("3x70+54.6", 213, 30, 985, 0.87, 0.443), + ("3x70+70", 213, 32, 1019, 0.87, 0.443), + ("3x95+70", 258, 35, 1264, 0.67, 0.320), + ("3x120+70", 300, 38, 1488, 0.55, 0.253), + ("3x150+70", 344, 40, 1731, 0.46, 0.206), + ("3x120+95", 300, 39, 1569, 0.55, 0.253), + ("3x150+95", 344, 42, 1812, 0.46, 0.206), + ] + c33209_phase_insulation_thickness = { + # min and max of: insulated core diameter - core diameter (mm) + # we take the max insulation thickness to calculate the max inductance; in line with + # the max resistance value in the table + 16: max((7.0 - 4.6, 7.8 - 5.1)), + 25: max((8.6 - 5.8, 9.4 - 6.3)), + 35: max((10.0 - 6.8, 10.9 - 7.3)), + 50: max((11.1 - 7.9, 12.0 - 8.4)), + 70: max((13.3 - 9.7, 14.2 - 10.2)), + 95: max((14.6 - 11.0, 15.7 - 12.0)), + 120: max((15.6 - 12.0, 16.7 - 13.1)), + 150: max((17.3 - 13.9, 18.6 - 15.0)), + } + c33209_neutral_messenger_insulation_thickness = { + # min and max of: insulated core diameter - core diameter (mm) + # we take the max insulation thickness to calculate the max inductance; in line with + # the max resistance value in the table + 54.6: max((12.3 - 9.2, 13.0 - 9.6)), + 70.0: max((12.9 - 10.0, 13.6 - 10.2)), + 95.0: max((15.3 - 12.2, 16.3 - 12.9)), + } + c33209_neutral_messenger_resistance = { + 54.6: 0.63, + 70: 0.50, + 95: 0.343, + } + twisted_df = ( + pl.DataFrame(data, schema=header, orient="row") + .select( + name=pl.format("T_AL_{}", pl.col("sections")), + type=pl.lit(rlf.LineType.TWISTED), + material=pl.lit(rlf.Material.AL), + material_neutral=pl.lit(rlf.Material.AM), + insulator=pl.lit(rlf.Insulator.XLPE), + insulator_neutral=pl.lit(rlf.Insulator.XLPE), + section=pl.col("sections").str.extract(r"^3x(\d+)\+\d+(?:\.\d+)?$", 1).cast(pl.Int64), + section_neutral=pl.col("sections").str.extract(r"^3x\d+\+(\d+(?:\.\d+)?)$", 1).cast(pl.Float64), + resistance=pl.col("r_ph"), + resistance_neutral=pl.lit(None, dtype=pl.Float64), # Computed below + reactance=pl.lit(None, dtype=pl.Float64), # Computed below + reactance_neutral=pl.lit(None, dtype=pl.Float64), # Computed below + susceptance=pl.lit(None, dtype=pl.Float64), # Computed below + susceptance_neutral=pl.lit(None, dtype=pl.Float64), # Computed below + ampacity=pl.col("imax_ph"), + # The neutral is usually assigned the same ampacity as the phase conductors + ampacity_neutral=pl.col("imax_ph"), + ) + .with_columns( + resistance_neutral=pl.col("section_neutral").replace_strict(c33209_neutral_messenger_resistance), + ) + ) + twisted_params = {"reactance": [], "susceptance": [], "reactance_neutral": [], "susceptance_neutral": []} + for row in twisted_df.iter_rows(named=True): + insulator_thickness = c33209_phase_insulation_thickness[row["section"]] + reactance, susceptance = line_parameters( + type=row["type"], + material=row["material"], + insulator=row["insulator"], + section=row["section"], + insulator_thickness=insulator_thickness, + ) + insulator_thickness_neutral = c33209_neutral_messenger_insulation_thickness[row["section_neutral"]] + reactance_neutral, susceptance_neutral = line_parameters( + type=row["type"], + material=row["material_neutral"], + insulator=row["insulator_neutral"], + section=row["section_neutral"], + insulator_thickness=insulator_thickness_neutral, + ) + twisted_params["reactance"].append(reactance) + twisted_params["susceptance"].append(susceptance) + twisted_params["reactance_neutral"].append(reactance_neutral) + twisted_params["susceptance_neutral"].append(susceptance_neutral) + twisted_df = twisted_df.with_columns(**{k: pl.Series(v) for k, v in twisted_params.items()}) + return twisted_df + + +def generate_c33210_lv_underground_parameters() -> pl.DataFrame: + """Nexans: Distribution cable 3 conductors + neutral (NF-C-33-210). + + Description + ----------- + + 1. Core (Neutral conductor): solid or stranded circular (class 2) aluminum depending on type. + 2. Protection (Neutral conductor): lead sheath + 3. Core (Phase conductor): aluminum stranded circular (class 2) of solid round, cross section 50 mm²; + stranded sector-shaped (class 2), cross section 95 to 240 mm². + 4. Insulation (Phase conductor): black XLPE. + 5. Watertight textile material + 6. Armour: two lapped galvanized mild steel tapes + 7. Filler: PVC material only 50 mm². + 8. Sheath: black PVC, special antitermite treatment possible. + + Table of marking + ---------------- + + Section | Marking + Manufact. nb / manufact. year / metric marks / manufact. date. + ---------- | ------------------------------------------------------------------------ + 3x50+1x50 | H1 XDV-AR 3x50+1x50 DISTRICABLE ® 211 NF C 33-210 + 3x95+1x50 | H1 XDV-AS 3x95+1x50 DISTRICABLE ® 211 NF C 33-210 + 3x150+1x70 | H1 XDV-AS 3x150+1x70 DISTRICABLE ® 211 NF C 33-210 + 3x240+1x95 | H1 XDV-AS 3x240+1x95 DISTRICABLE ® 211 NF C 33-210 + + Correction coefficients + ----------------------- + + To apply to the current in accordance with the ground temperature and its thermal resistivity + + Ground temp. | Ground thermal resistivity (K.m/W) | . | . | . | . | . | . + ------------ | ---------------------------------- | - | - | - | - | - | - + (°C) | 0.7 | 0.85 | 1 | 1.2 | 1.5 | 2 | 2.5 + 10 | 1.19 | 1.12 | 1.07 | 1.01 | 0.93 | 0.81 | 0.77 + 15 | 1.16 | 1.09 | 1.04 | 0.98 | 0.90 | 0.79 | 0.74 + 20 | 1.13 | 1.05 | 1.00 | 0.94 | 0.86 | 0.76 | 0.70 + 25 | 1.08 | 1.01 | 0.96 | 0.90 | 0.83 | 0.72 | 0,66 + 30 | 1.05 | 0.98 | 0.93 | 0.85 | 0.78 | 0.69 | 0.63 + 35 | 1.00 | 0.93 | 0.89 | 0.82 | 0.75 | 0.65 | 0.60 + + Technical characteristics + ------------------------- + + sections | diam_min | diam_max | weight | bend_rad | r_ph | r_neu | imax_bur | imax_air | delta_u + ---------- | -------- | -------- | ------ | -------- | ----- | ----- | -------- | -------- | ------- + 3x50+1x50 | 25.5 | 33.5 | 1670 | 270 | 0.641 | 0.641 | 160 | 149 | 1.18 + 3x95+1x50 | 30.0 | 38.6 | 1845 | 310 | 0.320 | 0.641 | 234 | 241 | 0.64 + 3x150+1x70 | 36.5 | 48.5 | 2570 | 390 | 0.206 | 0.443 | 300 | 324 | 0.51 + 3x240+1x95 | 45.5 | 58.7 | 3900 | 470 | 0.125 | 0.320 | 388 | 439 | 0.31 + + With the following original column names: + - sections: Sections (mm²) + - diam_min: Overall Diameter (mm) / minimum + - diam_max: Overall Diameter (mm) / maximum + - weight: Weight (kg/km) + - bend_rad: Minimum bending radius (mm) + - r_ph: Max. linear resistance at 20 °C (Ω/km) / Phase Cond. + - r_neu: Max. linear resistance at 20 °C (Ω/km) / Neutral Cond. + - imax_bur: Current (A) / Buried cables + - imax_air: Current (A) / Open air + - delta_u: Voltage drop between phases Cos ϕ = 0,8 (V/A.km) + """ + header = ( + "sections", + "diam_min", + "diam_max", + "weight", + "bend_rad", + "r_ph", + "r_neu", + "imax_bur", + "imax_air", + "delta_u", + ) + data = [ + ("3x50+1x50", 25.5, 33.5, 1670, 270, 0.641, 0.641, 160, 149, 1.18), + ("3x95+1x50", 30.0, 38.6, 1845, 310, 0.320, 0.641, 234, 241, 0.64), + ("3x150+1x70", 36.5, 48.5, 2570, 390, 0.206, 0.443, 300, 324, 0.51), + ("3x150+1x150", 38.5, 50.8, approx(3000), 390, 0.206, 0.206, 300, 324, 0.51), # Source: NF-C-33-210 + ("3x240+1x95", 45.5, 58.7, 3900, 470, 0.125, 0.320, 388, 439, 0.31), + ] + + nexans_underground_cable_reactance = {95: 0.08, 150: 0.08, 240: 0.08} # Ohm/km + nexans_underground_cable_capacitance = {95: 0.58, 150: 0.63, 240: 0.67} # µF/km + # c33210_phase_insulation_thickness = {50: 1.0, 95: 1.1, 150: 1.4, 240: 1.7} + # c33210_neutral_insulation_thickness = {50: 0.9, 70: 0.9, 95: 0.9, 150: 0.9} + extrapolate(nexans_underground_cable_reactance, 50) + extrapolate(nexans_underground_cable_reactance, 70) + extrapolate(nexans_underground_cable_capacitance, 50) + extrapolate(nexans_underground_cable_capacitance, 70) + + underground_df = ( + pl.DataFrame(data, schema=header, orient="row") + .select( + name=pl.format("U_AL_{}", pl.col("sections").str.replace(r"\+1x", "+")), + type=pl.lit(rlf.LineType.UNDERGROUND), + material=pl.lit(rlf.Material.AL), + material_neutral=pl.lit(rlf.Material.AL), + insulator=pl.lit(rlf.Insulator.XLPE), + insulator_neutral=pl.lit(rlf.Insulator.XLPE), # maybe NONE? + section=pl.col("sections").str.extract(r"^3x(\d+)\+1x\d+$", 1).cast(pl.Int64), + section_neutral=pl.col("sections").str.extract(r"^3x\d+\+1x(\d+)$", 1).cast(pl.Float64), + resistance=pl.col("r_ph"), + resistance_neutral=pl.col("r_neu"), + reactance=pl.lit(None, dtype=pl.Float64), # Computed below + reactance_neutral=pl.lit(None, dtype=pl.Float64), # Computed below + susceptance=pl.lit(None, dtype=pl.Float64), # Computed below + susceptance_neutral=pl.lit(None, dtype=pl.Float64), # Computed below + ampacity=pl.col("imax_bur"), + ampacity_neutral=pl.col("imax_bur"), # The neutral is usually assigned the same ampacity + ) + .with_columns( + reactance=pl.col("section").replace_strict(nexans_underground_cable_reactance), + reactance_neutral=pl.col("section_neutral").replace_strict(nexans_underground_cable_reactance), + susceptance=( + pl.col("section").replace_strict(nexans_underground_cable_capacitance) * rlf.constants.OMEGA.m * 1e-6 + ), + susceptance_neutral=( + pl.col("section_neutral").replace_strict(nexans_underground_cable_capacitance) + * rlf.constants.OMEGA.m + * 1e-6 + ), + ) + ) + return underground_df + + +if __name__ == "__main__": + import io + + twisted_df = generate_c33209_lv_twisted_parameters() + underground_df = generate_c33210_lv_underground_parameters() + all_df = pl.concat([twisted_df, underground_df], how="vertical") + + s = io.StringIO() + all_df.with_columns( + # Round float columns for better CSV readability + pl.col(pl.Float64).round(10) + ).write_csv(s) + print(s.getvalue()) diff --git a/scripts/plot_network_catalogue.py b/scripts/plot_network_catalogue.py index 79411110..ece8c739 100644 --- a/scripts/plot_network_catalogue.py +++ b/scripts/plot_network_catalogue.py @@ -1,149 +1,84 @@ import re from pathlib import Path +from typing import TYPE_CHECKING, Any, Literal import folium -import pandas as pd from branca.element import CssLink, Element, Figure from jinja2 import Template -from roseau.load_flow import ElectricalNetwork +import roseau.load_flow as rlf +from roseau.load_flow.plotting import _scalar_if_unique +from roseau.load_flow.typing import Id OUTPUT_DIR = Path("doc") / "_static" / "Network" - -def buses_style_function(feature): - if feature["properties"]["id"].startswith("HVMV"): # HV/MV substation - return { - "fill": True, - "fillColor": "#000000", - "color": "#000000", - "fillOpacity": 1, - "radius": 7, - } - elif feature["properties"]["id"].startswith("MVLV"): # MV/LV substations - return { - "fill": True, - "fillColor": "#234e83", - "color": "#234e83", - "fillOpacity": 1, - "radius": 5, - } - elif feature["properties"]["id"].startswith("MV"): # MV buses - return { - "fill": True, - "fillColor": "#234e83", - "color": "#234e83", - "fillOpacity": 1, - "radius": 3, - } - else: # LV buses - return { - "fill": True, - "fillColor": "#adb9cb", - "color": "#adb9cb", - "fillOpacity": 1, - "radius": 1, - } - - -def buses_highlight_function(feature): - return {"color": "#cad40e", "fillColor": "#cad40e"} - - -buses_tooltip = folium.GeoJsonTooltip( - fields=["id", "phases"], - aliases=["Id:", "Phases:"], - localize=True, - sticky=False, - labels=True, - max_width=800, -) - - -def lines_style_function(feature): - if feature["properties"]["network"].startswith("MV"): - return {"color": "#234e83", "weight": 4} - else: - return {"color": "#adb9cb", "weight": 3} - - -def lines_highlight_function(feature): - return {"color": "#cad40e"} - - -lines_tooltip = folium.GeoJsonTooltip( - fields=["id", "phases", "bus1_id", "bus2_id", "parameters_id", "length"], - aliases=["Id:", "Phases:", "Bus1:", "Bus2:", "Parameters:", "Length (km):"], - localize=True, - sticky=False, - labels=True, - max_width=800, -) - - -class RoseauMap(folium.Map): - def render(self, title: str | None, **kwargs) -> None: - """Add the network name to the function signature. - - Args: - title: - The pretty version of the network name. - - Keyword Args: - Traditional render arguments - """ - figure = self.get_root() - assert isinstance(figure, Figure), "You cannot render this Element if it is not in a Figure." - - # Add a title to the figure - figure.title = title - - # Add description and keywords in the headers - figure.header.add_child( - Element( - '' - ), - name="meta_description", - ) - figure.header.add_child( - Element( - '' - ), - name="meta_keywords", - ) - - # Add a H1 section in the body - figure.header.add_child( - Element("{% if kwargs['title'] %}{% endif %}"), - name="h1_css_style", - ) - figure.html.add_child( - Element("{% if kwargs['title'] %}

{{kwargs['title']}}

{% endif %}"), name="h1_title" - ) - - # Modify the template of the figure to add the lang to the HTML document - figure._template = Template( - "\n" - "\n" # <---- Modified here - "\n" - "{% if this.title %}{{this.title}}{% endif %}" - " {{this.header.render(**kwargs)}}\n" - "\n" - "\n" - " {{this.html.render(**kwargs)}}\n" - "\n" - "\n" - "\n", - ) - - super().render(title=title, **kwargs) - - # Add custom css file (at the end of the header) - figure.header.add_child(CssLink(url="../css/custom.css", download=False), name="custom_css") +if TYPE_CHECKING: + type FeatureMap = dict[str, Any] + type StyleDict = dict[str, Any] + +type MapElementType = Literal["bus", "line", "transformer"] + + +def enhance_map(map: "folium.Map", title: str) -> "folium.Map": + """Add the network name to the function signature. + + Args: + map: + The map to enhance. + + title: + The pretty version of the network name. + """ + figure = map.get_root() + assert isinstance(figure, Figure), "You cannot render this Element if it is not in a Figure." + + # Add a title to the figure + figure.title = title + + # Add description and keywords in the headers + figure.header.add_child( + Element( + '' + ), + name="meta_description", + ) + figure.header.add_child( + Element( + '' + ), + name="meta_keywords", + ) + + # Add a H1 section in the body + figure.header.add_child( + Element("{% if kwargs['title'] %}{% endif %}"), + name="h1_css_style", + ) + figure.html.add_child(Element("{% if kwargs['title'] %}

{{kwargs['title']}}

{% endif %}"), name="h1_title") + + # Modify the template of the figure to add the lang to the HTML document + figure._template = Template( + "\n" + "\n" # <---- Modified here + "\n" + "{% if this.title %}{{this.title}}{% endif %}" + " {{this.header.render(**kwargs)}}\n" + "\n" + "\n" + " {{this.html.render(**kwargs)}}\n" + "\n" + "\n" + "\n", + ) + + # Add custom CSS file (at the end of the header) + figure.header.add_child(CssLink(url="../css/custom.css", download=False), name="custom_css") + + return m def prettify_network_name(name: str) -> str: @@ -155,72 +90,300 @@ def prettify_network_name(name: str) -> str: if __name__ == "__main__": - catalogue_data = ElectricalNetwork.catalogue_data() - aggregated_buses_gdf_list = [] - aggregated_lines_gdf_list = [] + catalogue_data = rlf.ElectricalNetwork.catalogue_data() + + # + # Plot individual maps + # for network_name in catalogue_data: print(f"Plotting network {network_name!r}") + # Read the network data - en = ElectricalNetwork.from_catalogue(name=network_name, load_point_name="Winter") - buses_gdf = en.buses_frame.reset_index() - lines_gdf = en.lines_frame.reset_index() - buses_gdf["network"] = network_name - lines_gdf["network"] = network_name - - # Create the map - zoom_start = 12 if network_name.startswith("MV") else 16 + en = rlf.ElectricalNetwork.from_catalogue(name=network_name, load_point_name="Winter") + + # Plot the network + m = rlf.plotting.plot_interactive_map(en) + + # Add some elements for Google Index title = prettify_network_name(name=network_name) - m = RoseauMap(location=list(reversed(buses_gdf.union_all().centroid.coords[0])), zoom_start=zoom_start) - folium.GeoJson( - data=lines_gdf, - name="lines", - marker=folium.CircleMarker(), - style_function=lines_style_function, - highlight_function=lines_highlight_function, - tooltip=lines_tooltip, - ).add_to(m) - folium.GeoJson( - data=buses_gdf, - name="buses", - marker=folium.CircleMarker(), - style_function=buses_style_function, - highlight_function=buses_highlight_function, - tooltip=buses_tooltip, - ).add_to(m) - folium.LayerControl().add_to(m) + m = enhance_map(map=m, title=title) # Save the map m.save(outfile=OUTPUT_DIR / f"{network_name}.html", title=title) - # Aggregate the data frame - aggregated_buses_gdf_list.append(buses_gdf) - aggregated_lines_gdf_list.append(lines_gdf) - - # Create the global map + # + # Plot the global map + # + # This code is absolutely not optimised and well-written! print("Plotting the global map") - buses_gdf = pd.concat(objs=aggregated_buses_gdf_list, ignore_index=True) - lines_gdf = pd.concat(objs=aggregated_lines_gdf_list, ignore_index=True) - - # Create the map - title = "Available networks" - m = RoseauMap(location=list(reversed(buses_gdf.union_all().centroid.coords[0])), zoom_start=9) - folium.GeoJson( - data=lines_gdf, - name="lines", - marker=folium.CircleMarker(), - style_function=lines_style_function, - highlight_function=lines_highlight_function, - tooltip=lines_tooltip, - ).add_to(m) - folium.GeoJson( - data=buses_gdf, - name="buses", - marker=folium.CircleMarker(), - style_function=buses_style_function, - highlight_function=buses_highlight_function, - tooltip=buses_tooltip, - ).add_to(m) - folium.LayerControl().add_to(m) + m = folium.Map() + + mv, lv = 60e3, 1e3 + style_color: str = "#234e83" + + def style_color_callback(et): + return "#000000" if et == "transformer" else style_color + + highlight_color: str = "#cad40e" + add_tooltips: bool = True + add_popups: bool = True + add_search: bool = True + fit_bounds: bool = True + + fields = { + "bus": { + "network": "Network: ", + "id": "Id:", + "phases": "Phases:", + "nominal_voltage": "Un (V):", + "min_voltage_level": "Umin (%):", + "max_voltage_level": "Umax (%):", + }, + "line": { + "network": "Network: ", + "id": "Id:", + "phases": "Phases:", + "bus1_id": "Bus1:", + "bus2_id": "Bus2:", + "parameters_id": "Parameters:", + "length": "Length (km):", + "line_type": "Line Type:", + "material": "Material:", + "insulator": "Insulator:", + "section": "Section (mm²):", + "ampacity": "Ampacity (A):", + "max_loading": "Max loading (%):", + }, + "transformer": { + "network": "Network: ", + "id": "Id:", + "vg": "Vector Group:", + "sn": "Sn (kVA):", + "tap": "Tap Position (%):", + "parameters_id": "Parameters:", + "max_loading": "Max loading (%):", + "hv_side": "HV Side", + "bus_hv_id": "» Bus:", + "phases_hv": "» Phases:", + "uhv": "» Ur (V):", + "lv_side": "LV Side", + "bus_lv_id": "» Bus:", + "phases_lv": "» Phases:", + "ulv": "» Ur (V):", + }, + } + + def internal_style_function(feature): + # Default style + e_type = feature["properties"]["element_type"] + style_color = style_color_callback(e_type) + if e_type == "bus": + vn: int | float = feature["properties"]["approximate_nominal_voltage"] + is_source: bool = feature["properties"]["is_source"] + if is_source: + radius, margin = 15, -1 + border_radius = 0 # Source bus: square + else: + if vn < lv: + radius, margin = 5, 3 # LV + elif vn < mv: + radius, margin = 10, 1 # MV + else: + radius, margin = 15, -1 # HV + border_radius = radius / 2 + markup = f""" +
+
+
+
+ """ + return {"html": markup} + elif e_type == "line": + line_type: rlf.LineType | None = feature["properties"]["line_type"] + vn: int | float = feature["properties"]["approximate_nominal_voltage"] + if vn < lv: + weight = 1.5 # LV + elif vn < mv: + weight = 3.0 # MV + else: + weight = 4.5 # HV + dash_array = "5, 5" if line_type == rlf.LineType.UNDERGROUND else None + return {"color": style_color, "weight": weight, "dashArray": dash_array} + elif e_type == "transformer": + bus_hv_is_source = feature["properties"]["bus_hv_is_source"] + bus_lv_is_source = feature["properties"]["bus_lv_is_source"] + vn: int | float = feature["properties"]["approximate_hv_nominal_voltage"] + if bus_hv_is_source or bus_lv_is_source: + radius, margin = 15, -1 + else: + if vn < lv: + radius, margin = 5, 3 # LV + elif vn < mv: + radius, margin = 10, 1 # MV + else: + radius, margin = 15, -1 # HV + tr_color = style_color + hv_color = style_color_callback("bus") + lv_color = style_color_callback("bus") + markup = f""" +
+
+
+
+ """ + return {"html": markup} + else: + return {"color": style_color, "weight": 2} + + def internal_highlight_function(feature): + # Default highlight style + e_type = feature["properties"]["element_type"] + if e_type == "bus": # noqa: SIM116 + return {"color": highlight_color, "fillColor": highlight_color} + elif e_type == "line": + return {"color": highlight_color} + elif e_type == "transformer": + return {"color": highlight_color, "fillColor": highlight_color} + else: + return {"color": highlight_color} + + for network_name in catalogue_data: + pretty_network_name = prettify_network_name(name=network_name) + network = rlf.ElectricalNetwork.from_catalogue(name=network_name, load_point_name="Winter") + + buses_gdf = network.buses_frame + buses_gdf["network"] = pretty_network_name + buses_gdf["element_type"] = "bus" + buses_gdf["min_voltage_level"] *= 100 # Convert to percentage + buses_gdf["max_voltage_level"] *= 100 # Convert to percentage + source_buses = {src.bus.id for src in network.sources.values()} + buses_gdf["is_source"] = False + for bus_id in source_buses: + buses_gdf.at[bus_id, "is_source"] = True + + nominal_voltages = network._get_nominal_voltages() + buses_gdf["approximate_nominal_voltage"] = None + for bus_id, value in nominal_voltages.items(): + buses_gdf.at[bus_id, "approximate_nominal_voltage"] = value + buses_gdf.reset_index(inplace=True) + + lines_gdf = network.lines_frame + lines_gdf.reset_index(inplace=True) + lines_gdf["network"] = pretty_network_name + lines_gdf["element_type"] = "line" + lines_gdf["max_loading"] *= 100 # Convert to percentage + lines_gdf[["ampacity", "section", "line_type", "material", "insulator", "approximate_nominal_voltage"]] = None + line_params = {} + for idx in lines_gdf.index: + line_id: Id = lines_gdf.at[idx, "id"] # type: ignore + lp = network.lines[line_id].parameters + if lp.id not in line_params: + line_params[lp.id] = { + "ampacity": _scalar_if_unique(lp._ampacities), + "section": _scalar_if_unique(lp._sections), + "line_type": lp._line_type, + "material": _scalar_if_unique(lp._materials), + "insulator": _scalar_if_unique(lp._insulators), + } + lines_gdf.at[idx, "ampacity"] = line_params[lp.id]["ampacity"] + lines_gdf.at[idx, "section"] = line_params[lp.id]["section"] + lines_gdf.at[idx, "line_type"] = line_params[lp.id]["line_type"] + lines_gdf.at[idx, "material"] = line_params[lp.id]["material"] + lines_gdf.at[idx, "insulator"] = line_params[lp.id]["insulator"] + bus1_id = lines_gdf.at[idx, "bus1_id"] + lines_gdf.at[idx, "approximate_nominal_voltage"] = nominal_voltages.get(bus1_id) + + transformers_gdf = network.transformers_frame + transformers_gdf.reset_index(inplace=True) + transformers_gdf["network"] = pretty_network_name + transformers_gdf["element_type"] = "transformer" + transformers_gdf["tap"] *= 100 # Convert to percentage + transformers_gdf[["hv_side", "lv_side"]] = "" + transformers_gdf[ + ["vg", "sn", "uhv", "ulv", "bus_hv_is_source", "bus_lv_is_source", "approximate_hv_nominal_voltage"] + ] = None + for idx in transformers_gdf.index: + tr_id: Id = transformers_gdf.at[idx, "id"] # type: ignore + # Replace geometry with that of the HV bus + bus_hv_id: Id = transformers_gdf.at[idx, "bus_hv_id"] # type: ignore + bus_lv_id: Id = transformers_gdf.at[idx, "bus_lv_id"] # type: ignore + transformers_gdf.at[idx, "geometry"] = network.buses[bus_hv_id].geometry # type: ignore + lp = network.transformers[tr_id].parameters + transformers_gdf.at[idx, "vg"] = lp.vg + transformers_gdf.at[idx, "sn"] = lp._sn / 1e3 # Convert to kVA + transformers_gdf.at[idx, "uhv"] = lp._uhv + transformers_gdf.at[idx, "ulv"] = lp._ulv + transformers_gdf.at[idx, "bus_hv_is_source"] = bus_hv_id in source_buses + transformers_gdf.at[idx, "bus_lv_is_source"] = bus_lv_id in source_buses + transformers_gdf.at[idx, "approximate_hv_nominal_voltage"] = nominal_voltages.get(bus_hv_id) + + dataframes = {"bus": buses_gdf, "line": lines_gdf, "transformer": transformers_gdf} + + # Filter out transformer buses, these are represented by the transformers themselves + transformer_buses = {side.bus.id for tr in network.transformers.values() for side in (tr.side_hv, tr.side_lv)} + dataframes["bus"] = dataframes["bus"].loc[~dataframes["bus"]["id"].isin(transformer_buses)] + + tooltips: dict["MapElementType", folium.GeoJsonTooltip | None] = {} + if add_tooltips: + for e_type, e_fields in fields.items(): + tooltips[e_type] = folium.GeoJsonTooltip( + fields=list(e_fields.keys()), + aliases=list(e_fields.values()), + localize=True, + sticky=False, + labels=True, + max_width=800, + ) + else: + tooltips = dict.fromkeys(fields.keys(), None) + popups: dict[MapElementType, folium.GeoJsonPopup | None] = {} + if add_popups: + for e_type, e_fields in fields.items(): + popups[e_type] = folium.GeoJsonPopup( + fields=list(e_fields.keys()), aliases=list(e_fields.values()), localize=True, labels=True + ) + else: + popups = dict.fromkeys(fields.keys(), None) + + network_layer = folium.FeatureGroup(name=network_name).add_to(m) + names = {"bus": "Buses", "line": "Lines", "transformer": "Transformers"} + for e_type, frame in dataframes.items(): + if frame.empty: + continue + marker = folium.Marker(icon=folium.DivIcon()) if e_type != "line" else None + name = names[e_type] + folium.GeoJson( + data=frame, + name=name, + marker=marker, + style_function=internal_style_function, + highlight_function=internal_highlight_function, + tooltip=tooltips[e_type], + popup=popups[e_type], + # ).add_to(FeatureGroupSubGroup(network_layer, name).add_to(m)) + ).add_to(network_layer) + + folium.LayerControl(collapsed=False, draggable=True, position="bottomright").add_to(m) + folium.FitOverlays(padding=30).add_to(m) + + m = enhance_map(map=m, title="Available networks") # Hide the ReadTheDoc flyout in the Catalogue.html file m.get_root().header.add_child(Element("")) diff --git a/uv.lock b/uv.lock index 0ab1535d..b9b1c080 100644 --- a/uv.lock +++ b/uv.lock @@ -1,9 +1,13 @@ version = 1 revision = 3 -requires-python = ">=3.11" +requires-python = ">=3.12" resolution-markers = [ - "python_full_version >= '3.12'", - "python_full_version < '3.12'", + "python_full_version >= '3.14' and sys_platform == 'win32'", + "python_full_version >= '3.14' and sys_platform == 'emscripten'", + "python_full_version >= '3.14' and sys_platform != 'emscripten' and sys_platform != 'win32'", + "python_full_version < '3.14' and sys_platform == 'win32'", + "python_full_version < '3.14' and sys_platform == 'emscripten'", + "python_full_version < '3.14' and sys_platform != 'emscripten' and sys_platform != 'win32'", ] [[package]] @@ -29,20 +33,20 @@ wheels = [ [[package]] name = "astroid" -version = "3.3.11" +version = "4.0.3" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/18/74/dfb75f9ccd592bbedb175d4a32fc643cf569d7c218508bfbd6ea7ef9c091/astroid-3.3.11.tar.gz", hash = "sha256:1e5a5011af2920c7c67a53f65d536d65bfa7116feeaf2354d8b94f29573bb0ce", size = 400439, upload-time = "2025-07-13T18:04:23.177Z" } +sdist = { url = "https://files.pythonhosted.org/packages/a1/ca/c17d0f83016532a1ad87d1de96837164c99d47a3b6bbba28bd597c25b37a/astroid-4.0.3.tar.gz", hash = "sha256:08d1de40d251cc3dc4a7a12726721d475ac189e4e583d596ece7422bc176bda3", size = 406224, upload-time = "2026-01-03T22:14:26.096Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/af/0f/3b8fdc946b4d9cc8cc1e8af42c4e409468c84441b933d037e101b3d72d86/astroid-3.3.11-py3-none-any.whl", hash = "sha256:54c760ae8322ece1abd213057c4b5bba7c49818853fc901ef09719a60dbf9dec", size = 275612, upload-time = "2025-07-13T18:04:21.07Z" }, + { url = "https://files.pythonhosted.org/packages/ce/66/686ac4fc6ef48f5bacde625adac698f41d5316a9753c2b20bb0931c9d4e2/astroid-4.0.3-py3-none-any.whl", hash = "sha256:864a0a34af1bd70e1049ba1e61cee843a7252c826d97825fcee9b2fcbd9e1b14", size = 276443, upload-time = "2026-01-03T22:14:24.412Z" }, ] [[package]] name = "asttokens" -version = "3.0.0" +version = "3.0.1" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/4a/e7/82da0a03e7ba5141f05cce0d302e6eed121ae055e0456ca228bf693984bc/asttokens-3.0.0.tar.gz", hash = "sha256:0dcd8baa8d62b0c1d118b399b2ddba3c4aff271d0d7a9e0d4c1681c79035bbc7", size = 61978, upload-time = "2024-11-30T04:30:14.439Z" } +sdist = { url = "https://files.pythonhosted.org/packages/be/a5/8e3f9b6771b0b408517c82d97aed8f2036509bc247d46114925e32fe33f0/asttokens-3.0.1.tar.gz", hash = "sha256:71a4ee5de0bde6a31d64f6b13f2293ac190344478f081c3d1bccfcf5eacb0cb7", size = 62308, upload-time = "2025-11-15T16:43:48.578Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/25/8a/c46dcc25341b5bce5472c718902eb3d38600a903b14fa6aeecef3f21a46f/asttokens-3.0.0-py3-none-any.whl", hash = "sha256:e3078351a059199dd5138cb1c706e6430c05eff2ff136af5eb4790f9d28932e2", size = 26918, upload-time = "2024-11-30T04:30:10.946Z" }, + { url = "https://files.pythonhosted.org/packages/d2/39/e7eaf1799466a4aef85b6a4fe7bd175ad2b1c6345066aa33f1f58d4b18d0/asttokens-3.0.1-py3-none-any.whl", hash = "sha256:15a3ebc0f43c2d0a50eeafea25e19046c68398e487b9f1f5b517f7c0f40f976a", size = 27047, upload-time = "2025-11-15T16:43:16.109Z" }, ] [[package]] @@ -56,77 +60,93 @@ wheels = [ [[package]] name = "beautifulsoup4" -version = "4.13.5" +version = "4.14.3" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "soupsieve" }, { name = "typing-extensions" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/85/2e/3e5079847e653b1f6dc647aa24549d68c6addb4c595cc0d902d1b19308ad/beautifulsoup4-4.13.5.tar.gz", hash = "sha256:5e70131382930e7c3de33450a2f54a63d5e4b19386eab43a5b34d594268f3695", size = 622954, upload-time = "2025-08-24T14:06:13.168Z" } +sdist = { url = "https://files.pythonhosted.org/packages/c3/b0/1c6a16426d389813b48d95e26898aff79abbde42ad353958ad95cc8c9b21/beautifulsoup4-4.14.3.tar.gz", hash = "sha256:6292b1c5186d356bba669ef9f7f051757099565ad9ada5dd630bd9de5fa7fb86", size = 627737, upload-time = "2025-11-30T15:08:26.084Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/04/eb/f4151e0c7377a6e08a38108609ba5cede57986802757848688aeedd1b9e8/beautifulsoup4-4.13.5-py3-none-any.whl", hash = "sha256:642085eaa22233aceadff9c69651bc51e8bf3f874fb6d7104ece2beb24b47c4a", size = 105113, upload-time = "2025-08-24T14:06:14.884Z" }, + { url = "https://files.pythonhosted.org/packages/1a/39/47f9197bdd44df24d67ac8893641e16f386c984a0619ef2ee4c51fbbc019/beautifulsoup4-4.14.3-py3-none-any.whl", hash = "sha256:0918bfe44902e6ad8d57732ba310582e98da931428d231a5ecb9e7c703a735bb", size = 107721, upload-time = "2025-11-30T15:08:24.087Z" }, +] + +[[package]] +name = "branca" +version = "0.8.2" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "jinja2" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/32/14/9d409124bda3f4ab7af3802aba07181d1fd56aa96cc4b999faea6a27a0d2/branca-0.8.2.tar.gz", hash = "sha256:e5040f4c286e973658c27de9225c1a5a7356dd0702a7c8d84c0f0dfbde388fe7", size = 27890, upload-time = "2025-10-06T10:28:20.305Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/7e/50/fc9680058e63161f2f63165b84c957a0df1415431104c408e8104a3a18ef/branca-0.8.2-py3-none-any.whl", hash = "sha256:2ebaef3983e3312733c1ae2b793b0a8ba3e1c4edeb7598e10328505280cf2f7c", size = 26193, upload-time = "2025-10-06T10:28:19.255Z" }, ] [[package]] name = "certifi" -version = "2025.8.3" +version = "2026.1.4" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/dc/67/960ebe6bf230a96cda2e0abcf73af550ec4f090005363542f0765df162e0/certifi-2025.8.3.tar.gz", hash = "sha256:e564105f78ded564e3ae7c923924435e1daa7463faeab5bb932bc53ffae63407", size = 162386, upload-time = "2025-08-03T03:07:47.08Z" } +sdist = { url = "https://files.pythonhosted.org/packages/e0/2d/a891ca51311197f6ad14a7ef42e2399f36cf2f9bd44752b3dc4eab60fdc5/certifi-2026.1.4.tar.gz", hash = "sha256:ac726dd470482006e014ad384921ed6438c457018f4b3d204aea4281258b2120", size = 154268, upload-time = "2026-01-04T02:42:41.825Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/e5/48/1549795ba7742c948d2ad169c1c8cdbae65bc450d6cd753d124b17c8cd32/certifi-2025.8.3-py3-none-any.whl", hash = "sha256:f6c12493cfb1b06ba2ff328595af9350c65d6644968e5d3a2ffd78699af217a5", size = 161216, upload-time = "2025-08-03T03:07:45.777Z" }, + { url = "https://files.pythonhosted.org/packages/e6/ad/3cc14f097111b4de0040c83a525973216457bbeeb63739ef1ed275c1c021/certifi-2026.1.4-py3-none-any.whl", hash = "sha256:9943707519e4add1115f44c2bc244f782c0249876bf51b6599fee1ffbedd685c", size = 152900, upload-time = "2026-01-04T02:42:40.15Z" }, ] [[package]] name = "charset-normalizer" -version = "3.4.3" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/83/2d/5fd176ceb9b2fc619e63405525573493ca23441330fcdaee6bef9460e924/charset_normalizer-3.4.3.tar.gz", hash = "sha256:6fce4b8500244f6fcb71465d4a4930d132ba9ab8e71a7859e6a5d59851068d14", size = 122371, upload-time = "2025-08-09T07:57:28.46Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/7f/b5/991245018615474a60965a7c9cd2b4efbaabd16d582a5547c47ee1c7730b/charset_normalizer-3.4.3-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:b256ee2e749283ef3ddcff51a675ff43798d92d746d1a6e4631bf8c707d22d0b", size = 204483, upload-time = "2025-08-09T07:55:53.12Z" }, - { url = "https://files.pythonhosted.org/packages/c7/2a/ae245c41c06299ec18262825c1569c5d3298fc920e4ddf56ab011b417efd/charset_normalizer-3.4.3-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:13faeacfe61784e2559e690fc53fa4c5ae97c6fcedb8eb6fb8d0a15b475d2c64", size = 145520, upload-time = "2025-08-09T07:55:54.712Z" }, - { url = "https://files.pythonhosted.org/packages/3a/a4/b3b6c76e7a635748c4421d2b92c7b8f90a432f98bda5082049af37ffc8e3/charset_normalizer-3.4.3-cp311-cp311-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:00237675befef519d9af72169d8604a067d92755e84fe76492fef5441db05b91", size = 158876, upload-time = "2025-08-09T07:55:56.024Z" }, - { url = "https://files.pythonhosted.org/packages/e2/e6/63bb0e10f90a8243c5def74b5b105b3bbbfb3e7bb753915fe333fb0c11ea/charset_normalizer-3.4.3-cp311-cp311-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:585f3b2a80fbd26b048a0be90c5aae8f06605d3c92615911c3a2b03a8a3b796f", size = 156083, upload-time = "2025-08-09T07:55:57.582Z" }, - { url = "https://files.pythonhosted.org/packages/87/df/b7737ff046c974b183ea9aa111b74185ac8c3a326c6262d413bd5a1b8c69/charset_normalizer-3.4.3-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:0e78314bdc32fa80696f72fa16dc61168fda4d6a0c014e0380f9d02f0e5d8a07", size = 150295, upload-time = "2025-08-09T07:55:59.147Z" }, - { url = "https://files.pythonhosted.org/packages/61/f1/190d9977e0084d3f1dc169acd060d479bbbc71b90bf3e7bf7b9927dec3eb/charset_normalizer-3.4.3-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:96b2b3d1a83ad55310de8c7b4a2d04d9277d5591f40761274856635acc5fcb30", size = 148379, upload-time = "2025-08-09T07:56:00.364Z" }, - { url = "https://files.pythonhosted.org/packages/4c/92/27dbe365d34c68cfe0ca76f1edd70e8705d82b378cb54ebbaeabc2e3029d/charset_normalizer-3.4.3-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:939578d9d8fd4299220161fdd76e86c6a251987476f5243e8864a7844476ba14", size = 160018, upload-time = "2025-08-09T07:56:01.678Z" }, - { url = "https://files.pythonhosted.org/packages/99/04/baae2a1ea1893a01635d475b9261c889a18fd48393634b6270827869fa34/charset_normalizer-3.4.3-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:fd10de089bcdcd1be95a2f73dbe6254798ec1bda9f450d5828c96f93e2536b9c", size = 157430, upload-time = "2025-08-09T07:56:02.87Z" }, - { url = "https://files.pythonhosted.org/packages/2f/36/77da9c6a328c54d17b960c89eccacfab8271fdaaa228305330915b88afa9/charset_normalizer-3.4.3-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:1e8ac75d72fa3775e0b7cb7e4629cec13b7514d928d15ef8ea06bca03ef01cae", size = 151600, upload-time = "2025-08-09T07:56:04.089Z" }, - { url = "https://files.pythonhosted.org/packages/64/d4/9eb4ff2c167edbbf08cdd28e19078bf195762e9bd63371689cab5ecd3d0d/charset_normalizer-3.4.3-cp311-cp311-win32.whl", hash = "sha256:6cf8fd4c04756b6b60146d98cd8a77d0cdae0e1ca20329da2ac85eed779b6849", size = 99616, upload-time = "2025-08-09T07:56:05.658Z" }, - { url = "https://files.pythonhosted.org/packages/f4/9c/996a4a028222e7761a96634d1820de8a744ff4327a00ada9c8942033089b/charset_normalizer-3.4.3-cp311-cp311-win_amd64.whl", hash = "sha256:31a9a6f775f9bcd865d88ee350f0ffb0e25936a7f930ca98995c05abf1faf21c", size = 107108, upload-time = "2025-08-09T07:56:07.176Z" }, - { url = "https://files.pythonhosted.org/packages/e9/5e/14c94999e418d9b87682734589404a25854d5f5d0408df68bc15b6ff54bb/charset_normalizer-3.4.3-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:e28e334d3ff134e88989d90ba04b47d84382a828c061d0d1027b1b12a62b39b1", size = 205655, upload-time = "2025-08-09T07:56:08.475Z" }, - { url = "https://files.pythonhosted.org/packages/7d/a8/c6ec5d389672521f644505a257f50544c074cf5fc292d5390331cd6fc9c3/charset_normalizer-3.4.3-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:0cacf8f7297b0c4fcb74227692ca46b4a5852f8f4f24b3c766dd94a1075c4884", size = 146223, upload-time = "2025-08-09T07:56:09.708Z" }, - { url = "https://files.pythonhosted.org/packages/fc/eb/a2ffb08547f4e1e5415fb69eb7db25932c52a52bed371429648db4d84fb1/charset_normalizer-3.4.3-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:c6fd51128a41297f5409deab284fecbe5305ebd7e5a1f959bee1c054622b7018", size = 159366, upload-time = "2025-08-09T07:56:11.326Z" }, - { url = "https://files.pythonhosted.org/packages/82/10/0fd19f20c624b278dddaf83b8464dcddc2456cb4b02bb902a6da126b87a1/charset_normalizer-3.4.3-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:3cfb2aad70f2c6debfbcb717f23b7eb55febc0bb23dcffc0f076009da10c6392", size = 157104, upload-time = "2025-08-09T07:56:13.014Z" }, - { url = "https://files.pythonhosted.org/packages/16/ab/0233c3231af734f5dfcf0844aa9582d5a1466c985bbed6cedab85af9bfe3/charset_normalizer-3.4.3-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:1606f4a55c0fd363d754049cdf400175ee96c992b1f8018b993941f221221c5f", size = 151830, upload-time = "2025-08-09T07:56:14.428Z" }, - { url = "https://files.pythonhosted.org/packages/ae/02/e29e22b4e02839a0e4a06557b1999d0a47db3567e82989b5bb21f3fbbd9f/charset_normalizer-3.4.3-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:027b776c26d38b7f15b26a5da1044f376455fb3766df8fc38563b4efbc515154", size = 148854, upload-time = "2025-08-09T07:56:16.051Z" }, - { url = "https://files.pythonhosted.org/packages/05/6b/e2539a0a4be302b481e8cafb5af8792da8093b486885a1ae4d15d452bcec/charset_normalizer-3.4.3-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:42e5088973e56e31e4fa58eb6bd709e42fc03799c11c42929592889a2e54c491", size = 160670, upload-time = "2025-08-09T07:56:17.314Z" }, - { url = "https://files.pythonhosted.org/packages/31/e7/883ee5676a2ef217a40ce0bffcc3d0dfbf9e64cbcfbdf822c52981c3304b/charset_normalizer-3.4.3-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:cc34f233c9e71701040d772aa7490318673aa7164a0efe3172b2981218c26d93", size = 158501, upload-time = "2025-08-09T07:56:18.641Z" }, - { url = "https://files.pythonhosted.org/packages/c1/35/6525b21aa0db614cf8b5792d232021dca3df7f90a1944db934efa5d20bb1/charset_normalizer-3.4.3-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:320e8e66157cc4e247d9ddca8e21f427efc7a04bbd0ac8a9faf56583fa543f9f", size = 153173, upload-time = "2025-08-09T07:56:20.289Z" }, - { url = "https://files.pythonhosted.org/packages/50/ee/f4704bad8201de513fdc8aac1cabc87e38c5818c93857140e06e772b5892/charset_normalizer-3.4.3-cp312-cp312-win32.whl", hash = "sha256:fb6fecfd65564f208cbf0fba07f107fb661bcd1a7c389edbced3f7a493f70e37", size = 99822, upload-time = "2025-08-09T07:56:21.551Z" }, - { url = "https://files.pythonhosted.org/packages/39/f5/3b3836ca6064d0992c58c7561c6b6eee1b3892e9665d650c803bd5614522/charset_normalizer-3.4.3-cp312-cp312-win_amd64.whl", hash = "sha256:86df271bf921c2ee3818f0522e9a5b8092ca2ad8b065ece5d7d9d0e9f4849bcc", size = 107543, upload-time = "2025-08-09T07:56:23.115Z" }, - { url = "https://files.pythonhosted.org/packages/65/ca/2135ac97709b400c7654b4b764daf5c5567c2da45a30cdd20f9eefe2d658/charset_normalizer-3.4.3-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:14c2a87c65b351109f6abfc424cab3927b3bdece6f706e4d12faaf3d52ee5efe", size = 205326, upload-time = "2025-08-09T07:56:24.721Z" }, - { url = "https://files.pythonhosted.org/packages/71/11/98a04c3c97dd34e49c7d247083af03645ca3730809a5509443f3c37f7c99/charset_normalizer-3.4.3-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:41d1fc408ff5fdfb910200ec0e74abc40387bccb3252f3f27c0676731df2b2c8", size = 146008, upload-time = "2025-08-09T07:56:26.004Z" }, - { url = "https://files.pythonhosted.org/packages/60/f5/4659a4cb3c4ec146bec80c32d8bb16033752574c20b1252ee842a95d1a1e/charset_normalizer-3.4.3-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:1bb60174149316da1c35fa5233681f7c0f9f514509b8e399ab70fea5f17e45c9", size = 159196, upload-time = "2025-08-09T07:56:27.25Z" }, - { url = "https://files.pythonhosted.org/packages/86/9e/f552f7a00611f168b9a5865a1414179b2c6de8235a4fa40189f6f79a1753/charset_normalizer-3.4.3-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:30d006f98569de3459c2fc1f2acde170b7b2bd265dc1943e87e1a4efe1b67c31", size = 156819, upload-time = "2025-08-09T07:56:28.515Z" }, - { url = "https://files.pythonhosted.org/packages/7e/95/42aa2156235cbc8fa61208aded06ef46111c4d3f0de233107b3f38631803/charset_normalizer-3.4.3-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:416175faf02e4b0810f1f38bcb54682878a4af94059a1cd63b8747244420801f", size = 151350, upload-time = "2025-08-09T07:56:29.716Z" }, - { url = "https://files.pythonhosted.org/packages/c2/a9/3865b02c56f300a6f94fc631ef54f0a8a29da74fb45a773dfd3dcd380af7/charset_normalizer-3.4.3-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:6aab0f181c486f973bc7262a97f5aca3ee7e1437011ef0c2ec04b5a11d16c927", size = 148644, upload-time = "2025-08-09T07:56:30.984Z" }, - { url = "https://files.pythonhosted.org/packages/77/d9/cbcf1a2a5c7d7856f11e7ac2d782aec12bdfea60d104e60e0aa1c97849dc/charset_normalizer-3.4.3-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:fdabf8315679312cfa71302f9bd509ded4f2f263fb5b765cf1433b39106c3cc9", size = 160468, upload-time = "2025-08-09T07:56:32.252Z" }, - { url = "https://files.pythonhosted.org/packages/f6/42/6f45efee8697b89fda4d50580f292b8f7f9306cb2971d4b53f8914e4d890/charset_normalizer-3.4.3-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:bd28b817ea8c70215401f657edef3a8aa83c29d447fb0b622c35403780ba11d5", size = 158187, upload-time = "2025-08-09T07:56:33.481Z" }, - { url = "https://files.pythonhosted.org/packages/70/99/f1c3bdcfaa9c45b3ce96f70b14f070411366fa19549c1d4832c935d8e2c3/charset_normalizer-3.4.3-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:18343b2d246dc6761a249ba1fb13f9ee9a2bcd95decc767319506056ea4ad4dc", size = 152699, upload-time = "2025-08-09T07:56:34.739Z" }, - { url = "https://files.pythonhosted.org/packages/a3/ad/b0081f2f99a4b194bcbb1934ef3b12aa4d9702ced80a37026b7607c72e58/charset_normalizer-3.4.3-cp313-cp313-win32.whl", hash = "sha256:6fb70de56f1859a3f71261cbe41005f56a7842cc348d3aeb26237560bfa5e0ce", size = 99580, upload-time = "2025-08-09T07:56:35.981Z" }, - { url = "https://files.pythonhosted.org/packages/9a/8f/ae790790c7b64f925e5c953b924aaa42a243fb778fed9e41f147b2a5715a/charset_normalizer-3.4.3-cp313-cp313-win_amd64.whl", hash = "sha256:cf1ebb7d78e1ad8ec2a8c4732c7be2e736f6e5123a4146c5b89c9d1f585f8cef", size = 107366, upload-time = "2025-08-09T07:56:37.339Z" }, - { url = "https://files.pythonhosted.org/packages/8e/91/b5a06ad970ddc7a0e513112d40113e834638f4ca1120eb727a249fb2715e/charset_normalizer-3.4.3-cp314-cp314-macosx_10_13_universal2.whl", hash = "sha256:3cd35b7e8aedeb9e34c41385fda4f73ba609e561faedfae0a9e75e44ac558a15", size = 204342, upload-time = "2025-08-09T07:56:38.687Z" }, - { url = "https://files.pythonhosted.org/packages/ce/ec/1edc30a377f0a02689342f214455c3f6c2fbedd896a1d2f856c002fc3062/charset_normalizer-3.4.3-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:b89bc04de1d83006373429975f8ef9e7932534b8cc9ca582e4db7d20d91816db", size = 145995, upload-time = "2025-08-09T07:56:40.048Z" }, - { url = "https://files.pythonhosted.org/packages/17/e5/5e67ab85e6d22b04641acb5399c8684f4d37caf7558a53859f0283a650e9/charset_normalizer-3.4.3-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:2001a39612b241dae17b4687898843f254f8748b796a2e16f1051a17078d991d", size = 158640, upload-time = "2025-08-09T07:56:41.311Z" }, - { url = "https://files.pythonhosted.org/packages/f1/e5/38421987f6c697ee3722981289d554957c4be652f963d71c5e46a262e135/charset_normalizer-3.4.3-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:8dcfc373f888e4fb39a7bc57e93e3b845e7f462dacc008d9749568b1c4ece096", size = 156636, upload-time = "2025-08-09T07:56:43.195Z" }, - { url = "https://files.pythonhosted.org/packages/a0/e4/5a075de8daa3ec0745a9a3b54467e0c2967daaaf2cec04c845f73493e9a1/charset_normalizer-3.4.3-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:18b97b8404387b96cdbd30ad660f6407799126d26a39ca65729162fd810a99aa", size = 150939, upload-time = "2025-08-09T07:56:44.819Z" }, - { url = "https://files.pythonhosted.org/packages/02/f7/3611b32318b30974131db62b4043f335861d4d9b49adc6d57c1149cc49d4/charset_normalizer-3.4.3-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:ccf600859c183d70eb47e05a44cd80a4ce77394d1ac0f79dbd2dd90a69a3a049", size = 148580, upload-time = "2025-08-09T07:56:46.684Z" }, - { url = "https://files.pythonhosted.org/packages/7e/61/19b36f4bd67f2793ab6a99b979b4e4f3d8fc754cbdffb805335df4337126/charset_normalizer-3.4.3-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:53cd68b185d98dde4ad8990e56a58dea83a4162161b1ea9272e5c9182ce415e0", size = 159870, upload-time = "2025-08-09T07:56:47.941Z" }, - { url = "https://files.pythonhosted.org/packages/06/57/84722eefdd338c04cf3030ada66889298eaedf3e7a30a624201e0cbe424a/charset_normalizer-3.4.3-cp314-cp314-musllinux_1_2_s390x.whl", hash = "sha256:30a96e1e1f865f78b030d65241c1ee850cdf422d869e9028e2fc1d5e4db73b92", size = 157797, upload-time = "2025-08-09T07:56:49.756Z" }, - { url = "https://files.pythonhosted.org/packages/72/2a/aff5dd112b2f14bcc3462c312dce5445806bfc8ab3a7328555da95330e4b/charset_normalizer-3.4.3-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:d716a916938e03231e86e43782ca7878fb602a125a91e7acb8b5112e2e96ac16", size = 152224, upload-time = "2025-08-09T07:56:51.369Z" }, - { url = "https://files.pythonhosted.org/packages/b7/8c/9839225320046ed279c6e839d51f028342eb77c91c89b8ef2549f951f3ec/charset_normalizer-3.4.3-cp314-cp314-win32.whl", hash = "sha256:c6dbd0ccdda3a2ba7c2ecd9d77b37f3b5831687d8dc1b6ca5f56a4880cc7b7ce", size = 100086, upload-time = "2025-08-09T07:56:52.722Z" }, - { url = "https://files.pythonhosted.org/packages/ee/7a/36fbcf646e41f710ce0a563c1c9a343c6edf9be80786edeb15b6f62e17db/charset_normalizer-3.4.3-cp314-cp314-win_amd64.whl", hash = "sha256:73dc19b562516fc9bcf6e5d6e596df0b4eb98d87e4f79f3ae71840e6ed21361c", size = 107400, upload-time = "2025-08-09T07:56:55.172Z" }, - { url = "https://files.pythonhosted.org/packages/8a/1f/f041989e93b001bc4e44bb1669ccdcf54d3f00e628229a85b08d330615c5/charset_normalizer-3.4.3-py3-none-any.whl", hash = "sha256:ce571ab16d890d23b5c278547ba694193a45011ff86a9162a71307ed9f86759a", size = 53175, upload-time = "2025-08-09T07:57:26.864Z" }, +version = "3.4.4" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/13/69/33ddede1939fdd074bce5434295f38fae7136463422fe4fd3e0e89b98062/charset_normalizer-3.4.4.tar.gz", hash = "sha256:94537985111c35f28720e43603b8e7b43a6ecfb2ce1d3058bbe955b73404e21a", size = 129418, upload-time = "2025-10-14T04:42:32.879Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/f3/85/1637cd4af66fa687396e757dec650f28025f2a2f5a5531a3208dc0ec43f2/charset_normalizer-3.4.4-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:0a98e6759f854bd25a58a73fa88833fba3b7c491169f86ce1180c948ab3fd394", size = 208425, upload-time = "2025-10-14T04:40:53.353Z" }, + { url = "https://files.pythonhosted.org/packages/9d/6a/04130023fef2a0d9c62d0bae2649b69f7b7d8d24ea5536feef50551029df/charset_normalizer-3.4.4-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:b5b290ccc2a263e8d185130284f8501e3e36c5e02750fc6b6bdeb2e9e96f1e25", size = 148162, upload-time = "2025-10-14T04:40:54.558Z" }, + { url = "https://files.pythonhosted.org/packages/78/29/62328d79aa60da22c9e0b9a66539feae06ca0f5a4171ac4f7dc285b83688/charset_normalizer-3.4.4-cp312-cp312-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:74bb723680f9f7a6234dcf67aea57e708ec1fbdf5699fb91dfd6f511b0a320ef", size = 144558, upload-time = "2025-10-14T04:40:55.677Z" }, + { url = "https://files.pythonhosted.org/packages/86/bb/b32194a4bf15b88403537c2e120b817c61cd4ecffa9b6876e941c3ee38fe/charset_normalizer-3.4.4-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:f1e34719c6ed0b92f418c7c780480b26b5d9c50349e9a9af7d76bf757530350d", size = 161497, upload-time = "2025-10-14T04:40:57.217Z" }, + { url = "https://files.pythonhosted.org/packages/19/89/a54c82b253d5b9b111dc74aca196ba5ccfcca8242d0fb64146d4d3183ff1/charset_normalizer-3.4.4-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:2437418e20515acec67d86e12bf70056a33abdacb5cb1655042f6538d6b085a8", size = 159240, upload-time = "2025-10-14T04:40:58.358Z" }, + { url = "https://files.pythonhosted.org/packages/c0/10/d20b513afe03acc89ec33948320a5544d31f21b05368436d580dec4e234d/charset_normalizer-3.4.4-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:11d694519d7f29d6cd09f6ac70028dba10f92f6cdd059096db198c283794ac86", size = 153471, upload-time = "2025-10-14T04:40:59.468Z" }, + { url = "https://files.pythonhosted.org/packages/61/fa/fbf177b55bdd727010f9c0a3c49eefa1d10f960e5f09d1d887bf93c2e698/charset_normalizer-3.4.4-cp312-cp312-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:ac1c4a689edcc530fc9d9aa11f5774b9e2f33f9a0c6a57864e90908f5208d30a", size = 150864, upload-time = "2025-10-14T04:41:00.623Z" }, + { url = "https://files.pythonhosted.org/packages/05/12/9fbc6a4d39c0198adeebbde20b619790e9236557ca59fc40e0e3cebe6f40/charset_normalizer-3.4.4-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:21d142cc6c0ec30d2efee5068ca36c128a30b0f2c53c1c07bd78cb6bc1d3be5f", size = 150647, upload-time = "2025-10-14T04:41:01.754Z" }, + { url = "https://files.pythonhosted.org/packages/ad/1f/6a9a593d52e3e8c5d2b167daf8c6b968808efb57ef4c210acb907c365bc4/charset_normalizer-3.4.4-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:5dbe56a36425d26d6cfb40ce79c314a2e4dd6211d51d6d2191c00bed34f354cc", size = 145110, upload-time = "2025-10-14T04:41:03.231Z" }, + { url = "https://files.pythonhosted.org/packages/30/42/9a52c609e72471b0fc54386dc63c3781a387bb4fe61c20231a4ebcd58bdd/charset_normalizer-3.4.4-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:5bfbb1b9acf3334612667b61bd3002196fe2a1eb4dd74d247e0f2a4d50ec9bbf", size = 162839, upload-time = "2025-10-14T04:41:04.715Z" }, + { url = "https://files.pythonhosted.org/packages/c4/5b/c0682bbf9f11597073052628ddd38344a3d673fda35a36773f7d19344b23/charset_normalizer-3.4.4-cp312-cp312-musllinux_1_2_riscv64.whl", hash = "sha256:d055ec1e26e441f6187acf818b73564e6e6282709e9bcb5b63f5b23068356a15", size = 150667, upload-time = "2025-10-14T04:41:05.827Z" }, + { url = "https://files.pythonhosted.org/packages/e4/24/a41afeab6f990cf2daf6cb8c67419b63b48cf518e4f56022230840c9bfb2/charset_normalizer-3.4.4-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:af2d8c67d8e573d6de5bc30cdb27e9b95e49115cd9baad5ddbd1a6207aaa82a9", size = 160535, upload-time = "2025-10-14T04:41:06.938Z" }, + { url = "https://files.pythonhosted.org/packages/2a/e5/6a4ce77ed243c4a50a1fecca6aaaab419628c818a49434be428fe24c9957/charset_normalizer-3.4.4-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:780236ac706e66881f3b7f2f32dfe90507a09e67d1d454c762cf642e6e1586e0", size = 154816, upload-time = "2025-10-14T04:41:08.101Z" }, + { url = "https://files.pythonhosted.org/packages/a8/ef/89297262b8092b312d29cdb2517cb1237e51db8ecef2e9af5edbe7b683b1/charset_normalizer-3.4.4-cp312-cp312-win32.whl", hash = "sha256:5833d2c39d8896e4e19b689ffc198f08ea58116bee26dea51e362ecc7cd3ed26", size = 99694, upload-time = "2025-10-14T04:41:09.23Z" }, + { url = "https://files.pythonhosted.org/packages/3d/2d/1e5ed9dd3b3803994c155cd9aacb60c82c331bad84daf75bcb9c91b3295e/charset_normalizer-3.4.4-cp312-cp312-win_amd64.whl", hash = "sha256:a79cfe37875f822425b89a82333404539ae63dbdddf97f84dcbc3d339aae9525", size = 107131, upload-time = "2025-10-14T04:41:10.467Z" }, + { url = "https://files.pythonhosted.org/packages/d0/d9/0ed4c7098a861482a7b6a95603edce4c0d9db2311af23da1fb2b75ec26fc/charset_normalizer-3.4.4-cp312-cp312-win_arm64.whl", hash = "sha256:376bec83a63b8021bb5c8ea75e21c4ccb86e7e45ca4eb81146091b56599b80c3", size = 100390, upload-time = "2025-10-14T04:41:11.915Z" }, + { url = "https://files.pythonhosted.org/packages/97/45/4b3a1239bbacd321068ea6e7ac28875b03ab8bc0aa0966452db17cd36714/charset_normalizer-3.4.4-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:e1f185f86a6f3403aa2420e815904c67b2f9ebc443f045edd0de921108345794", size = 208091, upload-time = "2025-10-14T04:41:13.346Z" }, + { url = "https://files.pythonhosted.org/packages/7d/62/73a6d7450829655a35bb88a88fca7d736f9882a27eacdca2c6d505b57e2e/charset_normalizer-3.4.4-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6b39f987ae8ccdf0d2642338faf2abb1862340facc796048b604ef14919e55ed", size = 147936, upload-time = "2025-10-14T04:41:14.461Z" }, + { url = "https://files.pythonhosted.org/packages/89/c5/adb8c8b3d6625bef6d88b251bbb0d95f8205831b987631ab0c8bb5d937c2/charset_normalizer-3.4.4-cp313-cp313-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:3162d5d8ce1bb98dd51af660f2121c55d0fa541b46dff7bb9b9f86ea1d87de72", size = 144180, upload-time = "2025-10-14T04:41:15.588Z" }, + { url = "https://files.pythonhosted.org/packages/91/ed/9706e4070682d1cc219050b6048bfd293ccf67b3d4f5a4f39207453d4b99/charset_normalizer-3.4.4-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:81d5eb2a312700f4ecaa977a8235b634ce853200e828fbadf3a9c50bab278328", size = 161346, upload-time = "2025-10-14T04:41:16.738Z" }, + { url = "https://files.pythonhosted.org/packages/d5/0d/031f0d95e4972901a2f6f09ef055751805ff541511dc1252ba3ca1f80cf5/charset_normalizer-3.4.4-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:5bd2293095d766545ec1a8f612559f6b40abc0eb18bb2f5d1171872d34036ede", size = 158874, upload-time = "2025-10-14T04:41:17.923Z" }, + { url = "https://files.pythonhosted.org/packages/f5/83/6ab5883f57c9c801ce5e5677242328aa45592be8a00644310a008d04f922/charset_normalizer-3.4.4-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:a8a8b89589086a25749f471e6a900d3f662d1d3b6e2e59dcecf787b1cc3a1894", size = 153076, upload-time = "2025-10-14T04:41:19.106Z" }, + { url = "https://files.pythonhosted.org/packages/75/1e/5ff781ddf5260e387d6419959ee89ef13878229732732ee73cdae01800f2/charset_normalizer-3.4.4-cp313-cp313-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:bc7637e2f80d8530ee4a78e878bce464f70087ce73cf7c1caf142416923b98f1", size = 150601, upload-time = "2025-10-14T04:41:20.245Z" }, + { url = "https://files.pythonhosted.org/packages/d7/57/71be810965493d3510a6ca79b90c19e48696fb1ff964da319334b12677f0/charset_normalizer-3.4.4-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:f8bf04158c6b607d747e93949aa60618b61312fe647a6369f88ce2ff16043490", size = 150376, upload-time = "2025-10-14T04:41:21.398Z" }, + { url = "https://files.pythonhosted.org/packages/e5/d5/c3d057a78c181d007014feb7e9f2e65905a6c4ef182c0ddf0de2924edd65/charset_normalizer-3.4.4-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:554af85e960429cf30784dd47447d5125aaa3b99a6f0683589dbd27e2f45da44", size = 144825, upload-time = "2025-10-14T04:41:22.583Z" }, + { url = "https://files.pythonhosted.org/packages/e6/8c/d0406294828d4976f275ffbe66f00266c4b3136b7506941d87c00cab5272/charset_normalizer-3.4.4-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:74018750915ee7ad843a774364e13a3db91682f26142baddf775342c3f5b1133", size = 162583, upload-time = "2025-10-14T04:41:23.754Z" }, + { url = "https://files.pythonhosted.org/packages/d7/24/e2aa1f18c8f15c4c0e932d9287b8609dd30ad56dbe41d926bd846e22fb8d/charset_normalizer-3.4.4-cp313-cp313-musllinux_1_2_riscv64.whl", hash = "sha256:c0463276121fdee9c49b98908b3a89c39be45d86d1dbaa22957e38f6321d4ce3", size = 150366, upload-time = "2025-10-14T04:41:25.27Z" }, + { url = "https://files.pythonhosted.org/packages/e4/5b/1e6160c7739aad1e2df054300cc618b06bf784a7a164b0f238360721ab86/charset_normalizer-3.4.4-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:362d61fd13843997c1c446760ef36f240cf81d3ebf74ac62652aebaf7838561e", size = 160300, upload-time = "2025-10-14T04:41:26.725Z" }, + { url = "https://files.pythonhosted.org/packages/7a/10/f882167cd207fbdd743e55534d5d9620e095089d176d55cb22d5322f2afd/charset_normalizer-3.4.4-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:9a26f18905b8dd5d685d6d07b0cdf98a79f3c7a918906af7cc143ea2e164c8bc", size = 154465, upload-time = "2025-10-14T04:41:28.322Z" }, + { url = "https://files.pythonhosted.org/packages/89/66/c7a9e1b7429be72123441bfdbaf2bc13faab3f90b933f664db506dea5915/charset_normalizer-3.4.4-cp313-cp313-win32.whl", hash = "sha256:9b35f4c90079ff2e2edc5b26c0c77925e5d2d255c42c74fdb70fb49b172726ac", size = 99404, upload-time = "2025-10-14T04:41:29.95Z" }, + { url = "https://files.pythonhosted.org/packages/c4/26/b9924fa27db384bdcd97ab83b4f0a8058d96ad9626ead570674d5e737d90/charset_normalizer-3.4.4-cp313-cp313-win_amd64.whl", hash = "sha256:b435cba5f4f750aa6c0a0d92c541fb79f69a387c91e61f1795227e4ed9cece14", size = 107092, upload-time = "2025-10-14T04:41:31.188Z" }, + { url = "https://files.pythonhosted.org/packages/af/8f/3ed4bfa0c0c72a7ca17f0380cd9e4dd842b09f664e780c13cff1dcf2ef1b/charset_normalizer-3.4.4-cp313-cp313-win_arm64.whl", hash = "sha256:542d2cee80be6f80247095cc36c418f7bddd14f4a6de45af91dfad36d817bba2", size = 100408, upload-time = "2025-10-14T04:41:32.624Z" }, + { url = "https://files.pythonhosted.org/packages/2a/35/7051599bd493e62411d6ede36fd5af83a38f37c4767b92884df7301db25d/charset_normalizer-3.4.4-cp314-cp314-macosx_10_13_universal2.whl", hash = "sha256:da3326d9e65ef63a817ecbcc0df6e94463713b754fe293eaa03da99befb9a5bd", size = 207746, upload-time = "2025-10-14T04:41:33.773Z" }, + { url = "https://files.pythonhosted.org/packages/10/9a/97c8d48ef10d6cd4fcead2415523221624bf58bcf68a802721a6bc807c8f/charset_normalizer-3.4.4-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:8af65f14dc14a79b924524b1e7fffe304517b2bff5a58bf64f30b98bbc5079eb", size = 147889, upload-time = "2025-10-14T04:41:34.897Z" }, + { url = "https://files.pythonhosted.org/packages/10/bf/979224a919a1b606c82bd2c5fa49b5c6d5727aa47b4312bb27b1734f53cd/charset_normalizer-3.4.4-cp314-cp314-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:74664978bb272435107de04e36db5a9735e78232b85b77d45cfb38f758efd33e", size = 143641, upload-time = "2025-10-14T04:41:36.116Z" }, + { url = "https://files.pythonhosted.org/packages/ba/33/0ad65587441fc730dc7bd90e9716b30b4702dc7b617e6ba4997dc8651495/charset_normalizer-3.4.4-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:752944c7ffbfdd10c074dc58ec2d5a8a4cd9493b314d367c14d24c17684ddd14", size = 160779, upload-time = "2025-10-14T04:41:37.229Z" }, + { url = "https://files.pythonhosted.org/packages/67/ed/331d6b249259ee71ddea93f6f2f0a56cfebd46938bde6fcc6f7b9a3d0e09/charset_normalizer-3.4.4-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:d1f13550535ad8cff21b8d757a3257963e951d96e20ec82ab44bc64aeb62a191", size = 159035, upload-time = "2025-10-14T04:41:38.368Z" }, + { url = "https://files.pythonhosted.org/packages/67/ff/f6b948ca32e4f2a4576aa129d8bed61f2e0543bf9f5f2b7fc3758ed005c9/charset_normalizer-3.4.4-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:ecaae4149d99b1c9e7b88bb03e3221956f68fd6d50be2ef061b2381b61d20838", size = 152542, upload-time = "2025-10-14T04:41:39.862Z" }, + { url = "https://files.pythonhosted.org/packages/16/85/276033dcbcc369eb176594de22728541a925b2632f9716428c851b149e83/charset_normalizer-3.4.4-cp314-cp314-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:cb6254dc36b47a990e59e1068afacdcd02958bdcce30bb50cc1700a8b9d624a6", size = 149524, upload-time = "2025-10-14T04:41:41.319Z" }, + { url = "https://files.pythonhosted.org/packages/9e/f2/6a2a1f722b6aba37050e626530a46a68f74e63683947a8acff92569f979a/charset_normalizer-3.4.4-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:c8ae8a0f02f57a6e61203a31428fa1d677cbe50c93622b4149d5c0f319c1d19e", size = 150395, upload-time = "2025-10-14T04:41:42.539Z" }, + { url = "https://files.pythonhosted.org/packages/60/bb/2186cb2f2bbaea6338cad15ce23a67f9b0672929744381e28b0592676824/charset_normalizer-3.4.4-cp314-cp314-musllinux_1_2_armv7l.whl", hash = "sha256:47cc91b2f4dd2833fddaedd2893006b0106129d4b94fdb6af1f4ce5a9965577c", size = 143680, upload-time = "2025-10-14T04:41:43.661Z" }, + { url = "https://files.pythonhosted.org/packages/7d/a5/bf6f13b772fbb2a90360eb620d52ed8f796f3c5caee8398c3b2eb7b1c60d/charset_normalizer-3.4.4-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:82004af6c302b5d3ab2cfc4cc5f29db16123b1a8417f2e25f9066f91d4411090", size = 162045, upload-time = "2025-10-14T04:41:44.821Z" }, + { url = "https://files.pythonhosted.org/packages/df/c5/d1be898bf0dc3ef9030c3825e5d3b83f2c528d207d246cbabe245966808d/charset_normalizer-3.4.4-cp314-cp314-musllinux_1_2_riscv64.whl", hash = "sha256:2b7d8f6c26245217bd2ad053761201e9f9680f8ce52f0fcd8d0755aeae5b2152", size = 149687, upload-time = "2025-10-14T04:41:46.442Z" }, + { url = "https://files.pythonhosted.org/packages/a5/42/90c1f7b9341eef50c8a1cb3f098ac43b0508413f33affd762855f67a410e/charset_normalizer-3.4.4-cp314-cp314-musllinux_1_2_s390x.whl", hash = "sha256:799a7a5e4fb2d5898c60b640fd4981d6a25f1c11790935a44ce38c54e985f828", size = 160014, upload-time = "2025-10-14T04:41:47.631Z" }, + { url = "https://files.pythonhosted.org/packages/76/be/4d3ee471e8145d12795ab655ece37baed0929462a86e72372fd25859047c/charset_normalizer-3.4.4-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:99ae2cffebb06e6c22bdc25801d7b30f503cc87dbd283479e7b606f70aff57ec", size = 154044, upload-time = "2025-10-14T04:41:48.81Z" }, + { url = "https://files.pythonhosted.org/packages/b0/6f/8f7af07237c34a1defe7defc565a9bc1807762f672c0fde711a4b22bf9c0/charset_normalizer-3.4.4-cp314-cp314-win32.whl", hash = "sha256:f9d332f8c2a2fcbffe1378594431458ddbef721c1769d78e2cbc06280d8155f9", size = 99940, upload-time = "2025-10-14T04:41:49.946Z" }, + { url = "https://files.pythonhosted.org/packages/4b/51/8ade005e5ca5b0d80fb4aff72a3775b325bdc3d27408c8113811a7cbe640/charset_normalizer-3.4.4-cp314-cp314-win_amd64.whl", hash = "sha256:8a6562c3700cce886c5be75ade4a5db4214fda19fede41d9792d100288d8f94c", size = 107104, upload-time = "2025-10-14T04:41:51.051Z" }, + { url = "https://files.pythonhosted.org/packages/da/5f/6b8f83a55bb8278772c5ae54a577f3099025f9ade59d0136ac24a0df4bde/charset_normalizer-3.4.4-cp314-cp314-win_arm64.whl", hash = "sha256:de00632ca48df9daf77a2c65a484531649261ec9f25489917f09e455cb09ddb2", size = 100743, upload-time = "2025-10-14T04:41:52.122Z" }, + { url = "https://files.pythonhosted.org/packages/0a/4c/925909008ed5a988ccbb72dcc897407e5d6d3bd72410d69e051fc0c14647/charset_normalizer-3.4.4-py3-none-any.whl", hash = "sha256:7a32c560861a02ff789ad905a2fe94e3f840803362c84fecf1851cb4cf3dc37f", size = 53402, upload-time = "2025-10-14T04:42:31.76Z" }, ] [[package]] @@ -147,17 +167,6 @@ dependencies = [ ] sdist = { url = "https://files.pythonhosted.org/packages/58/01/1253e6698a07380cd31a736d248a3f2a50a7c88779a1813da27503cadc2a/contourpy-1.3.3.tar.gz", hash = "sha256:083e12155b210502d0bca491432bb04d56dc3432f95a979b429f2848c3dbe880", size = 13466174, upload-time = "2025-07-26T12:03:12.549Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/91/2e/c4390a31919d8a78b90e8ecf87cd4b4c4f05a5b48d05ec17db8e5404c6f4/contourpy-1.3.3-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:709a48ef9a690e1343202916450bc48b9e51c049b089c7f79a267b46cffcdaa1", size = 288773, upload-time = "2025-07-26T12:01:02.277Z" }, - { url = "https://files.pythonhosted.org/packages/0d/44/c4b0b6095fef4dc9c420e041799591e3b63e9619e3044f7f4f6c21c0ab24/contourpy-1.3.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:23416f38bfd74d5d28ab8429cc4d63fa67d5068bd711a85edb1c3fb0c3e2f381", size = 270149, upload-time = "2025-07-26T12:01:04.072Z" }, - { url = "https://files.pythonhosted.org/packages/30/2e/dd4ced42fefac8470661d7cb7e264808425e6c5d56d175291e93890cce09/contourpy-1.3.3-cp311-cp311-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:929ddf8c4c7f348e4c0a5a3a714b5c8542ffaa8c22954862a46ca1813b667ee7", size = 329222, upload-time = "2025-07-26T12:01:05.688Z" }, - { url = "https://files.pythonhosted.org/packages/f2/74/cc6ec2548e3d276c71389ea4802a774b7aa3558223b7bade3f25787fafc2/contourpy-1.3.3-cp311-cp311-manylinux_2_26_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:9e999574eddae35f1312c2b4b717b7885d4edd6cb46700e04f7f02db454e67c1", size = 377234, upload-time = "2025-07-26T12:01:07.054Z" }, - { url = "https://files.pythonhosted.org/packages/03/b3/64ef723029f917410f75c09da54254c5f9ea90ef89b143ccadb09df14c15/contourpy-1.3.3-cp311-cp311-manylinux_2_26_s390x.manylinux_2_28_s390x.whl", hash = "sha256:0bf67e0e3f482cb69779dd3061b534eb35ac9b17f163d851e2a547d56dba0a3a", size = 380555, upload-time = "2025-07-26T12:01:08.801Z" }, - { url = "https://files.pythonhosted.org/packages/5f/4b/6157f24ca425b89fe2eb7e7be642375711ab671135be21e6faa100f7448c/contourpy-1.3.3-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:51e79c1f7470158e838808d4a996fa9bac72c498e93d8ebe5119bc1e6becb0db", size = 355238, upload-time = "2025-07-26T12:01:10.319Z" }, - { url = "https://files.pythonhosted.org/packages/98/56/f914f0dd678480708a04cfd2206e7c382533249bc5001eb9f58aa693e200/contourpy-1.3.3-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:598c3aaece21c503615fd59c92a3598b428b2f01bfb4b8ca9c4edeecc2438620", size = 1326218, upload-time = "2025-07-26T12:01:12.659Z" }, - { url = "https://files.pythonhosted.org/packages/fb/d7/4a972334a0c971acd5172389671113ae82aa7527073980c38d5868ff1161/contourpy-1.3.3-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:322ab1c99b008dad206d406bb61d014cf0174df491ae9d9d0fac6a6fda4f977f", size = 1392867, upload-time = "2025-07-26T12:01:15.533Z" }, - { url = "https://files.pythonhosted.org/packages/75/3e/f2cc6cd56dc8cff46b1a56232eabc6feea52720083ea71ab15523daab796/contourpy-1.3.3-cp311-cp311-win32.whl", hash = "sha256:fd907ae12cd483cd83e414b12941c632a969171bf90fc937d0c9f268a31cafff", size = 183677, upload-time = "2025-07-26T12:01:17.088Z" }, - { url = "https://files.pythonhosted.org/packages/98/4b/9bd370b004b5c9d8045c6c33cf65bae018b27aca550a3f657cdc99acdbd8/contourpy-1.3.3-cp311-cp311-win_amd64.whl", hash = "sha256:3519428f6be58431c56581f1694ba8e50626f2dd550af225f82fb5f5814d2a42", size = 225234, upload-time = "2025-07-26T12:01:18.256Z" }, - { url = "https://files.pythonhosted.org/packages/d9/b6/71771e02c2e004450c12b1120a5f488cad2e4d5b590b1af8bad060360fe4/contourpy-1.3.3-cp311-cp311-win_arm64.whl", hash = "sha256:15ff10bfada4bf92ec8b31c62bf7c1834c244019b4a33095a68000d7075df470", size = 193123, upload-time = "2025-07-26T12:01:19.848Z" }, { url = "https://files.pythonhosted.org/packages/be/45/adfee365d9ea3d853550b2e735f9d66366701c65db7855cd07621732ccfc/contourpy-1.3.3-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:b08a32ea2f8e42cf1d4be3169a98dd4be32bafe4f22b6c4cb4ba810fa9e5d2cb", size = 293419, upload-time = "2025-07-26T12:01:21.16Z" }, { url = "https://files.pythonhosted.org/packages/53/3e/405b59cfa13021a56bba395a6b3aca8cec012b45bf177b0eaf7a202cde2c/contourpy-1.3.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:556dba8fb6f5d8742f2923fe9457dbdd51e1049c4a43fd3986a0b14a1d815fc6", size = 273979, upload-time = "2025-07-26T12:01:22.448Z" }, { url = "https://files.pythonhosted.org/packages/d4/1c/a12359b9b2ca3a845e8f7f9ac08bdf776114eb931392fcad91743e2ea17b/contourpy-1.3.3-cp312-cp312-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:92d9abc807cf7d0e047b95ca5d957cf4792fcd04e920ca70d48add15c1a90ea7", size = 332653, upload-time = "2025-07-26T12:01:24.155Z" }, @@ -213,11 +222,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/93/8a/68a4ec5c55a2971213d29a9374913f7e9f18581945a7a31d1a39b5d2dfe5/contourpy-1.3.3-cp314-cp314t-win32.whl", hash = "sha256:e74a9a0f5e3fff48fb5a7f2fd2b9b70a3fe014a67522f79b7cca4c0c7e43c9ae", size = 202428, upload-time = "2025-07-26T12:02:48.691Z" }, { url = "https://files.pythonhosted.org/packages/fa/96/fd9f641ffedc4fa3ace923af73b9d07e869496c9cc7a459103e6e978992f/contourpy-1.3.3-cp314-cp314t-win_amd64.whl", hash = "sha256:13b68d6a62db8eafaebb8039218921399baf6e47bf85006fd8529f2a08ef33fc", size = 250331, upload-time = "2025-07-26T12:02:50.137Z" }, { url = "https://files.pythonhosted.org/packages/ae/8c/469afb6465b853afff216f9528ffda78a915ff880ed58813ba4faf4ba0b6/contourpy-1.3.3-cp314-cp314t-win_arm64.whl", hash = "sha256:b7448cb5a725bb1e35ce88771b86fba35ef418952474492cf7c764059933ff8b", size = 203831, upload-time = "2025-07-26T12:02:51.449Z" }, - { url = "https://files.pythonhosted.org/packages/a5/29/8dcfe16f0107943fa92388c23f6e05cff0ba58058c4c95b00280d4c75a14/contourpy-1.3.3-pp311-pypy311_pp73-macosx_10_15_x86_64.whl", hash = "sha256:cd5dfcaeb10f7b7f9dc8941717c6c2ade08f587be2226222c12b25f0483ed497", size = 278809, upload-time = "2025-07-26T12:02:52.74Z" }, - { url = "https://files.pythonhosted.org/packages/85/a9/8b37ef4f7dafeb335daee3c8254645ef5725be4d9c6aa70b50ec46ef2f7e/contourpy-1.3.3-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:0c1fc238306b35f246d61a1d416a627348b5cf0648648a031e14bb8705fcdfe8", size = 261593, upload-time = "2025-07-26T12:02:54.037Z" }, - { url = "https://files.pythonhosted.org/packages/0a/59/ebfb8c677c75605cc27f7122c90313fd2f375ff3c8d19a1694bda74aaa63/contourpy-1.3.3-pp311-pypy311_pp73-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:70f9aad7de812d6541d29d2bbf8feb22ff7e1c299523db288004e3157ff4674e", size = 302202, upload-time = "2025-07-26T12:02:55.947Z" }, - { url = "https://files.pythonhosted.org/packages/3c/37/21972a15834d90bfbfb009b9d004779bd5a07a0ec0234e5ba8f64d5736f4/contourpy-1.3.3-pp311-pypy311_pp73-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:5ed3657edf08512fc3fe81b510e35c2012fbd3081d2e26160f27ca28affec989", size = 329207, upload-time = "2025-07-26T12:02:57.468Z" }, - { url = "https://files.pythonhosted.org/packages/0c/58/bd257695f39d05594ca4ad60df5bcb7e32247f9951fd09a9b8edb82d1daa/contourpy-1.3.3-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:3d1a3799d62d45c18bafd41c5fa05120b96a28079f2393af559b843d1a966a77", size = 225315, upload-time = "2025-07-26T12:02:58.801Z" }, ] [[package]] @@ -234,82 +238,76 @@ wheels = [ [[package]] name = "coverage" -version = "7.10.6" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/14/70/025b179c993f019105b79575ac6edb5e084fb0f0e63f15cdebef4e454fb5/coverage-7.10.6.tar.gz", hash = "sha256:f644a3ae5933a552a29dbb9aa2f90c677a875f80ebea028e5a52a4f429044b90", size = 823736, upload-time = "2025-08-29T15:35:16.668Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/d4/16/2bea27e212c4980753d6d563a0803c150edeaaddb0771a50d2afc410a261/coverage-7.10.6-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:c706db3cabb7ceef779de68270150665e710b46d56372455cd741184f3868d8f", size = 217129, upload-time = "2025-08-29T15:33:13.575Z" }, - { url = "https://files.pythonhosted.org/packages/2a/51/e7159e068831ab37e31aac0969d47b8c5ee25b7d307b51e310ec34869315/coverage-7.10.6-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:8e0c38dc289e0508ef68ec95834cb5d2e96fdbe792eaccaa1bccac3966bbadcc", size = 217532, upload-time = "2025-08-29T15:33:14.872Z" }, - { url = "https://files.pythonhosted.org/packages/e7/c0/246ccbea53d6099325d25cd208df94ea435cd55f0db38099dd721efc7a1f/coverage-7.10.6-cp311-cp311-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:752a3005a1ded28f2f3a6e8787e24f28d6abe176ca64677bcd8d53d6fe2ec08a", size = 247931, upload-time = "2025-08-29T15:33:16.142Z" }, - { url = "https://files.pythonhosted.org/packages/7d/fb/7435ef8ab9b2594a6e3f58505cc30e98ae8b33265d844007737946c59389/coverage-7.10.6-cp311-cp311-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:689920ecfd60f992cafca4f5477d55720466ad2c7fa29bb56ac8d44a1ac2b47a", size = 249864, upload-time = "2025-08-29T15:33:17.434Z" }, - { url = "https://files.pythonhosted.org/packages/51/f8/d9d64e8da7bcddb094d511154824038833c81e3a039020a9d6539bf303e9/coverage-7.10.6-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ec98435796d2624d6905820a42f82149ee9fc4f2d45c2c5bc5a44481cc50db62", size = 251969, upload-time = "2025-08-29T15:33:18.822Z" }, - { url = "https://files.pythonhosted.org/packages/43/28/c43ba0ef19f446d6463c751315140d8f2a521e04c3e79e5c5fe211bfa430/coverage-7.10.6-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:b37201ce4a458c7a758ecc4efa92fa8ed783c66e0fa3c42ae19fc454a0792153", size = 249659, upload-time = "2025-08-29T15:33:20.407Z" }, - { url = "https://files.pythonhosted.org/packages/79/3e/53635bd0b72beaacf265784508a0b386defc9ab7fad99ff95f79ce9db555/coverage-7.10.6-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:2904271c80898663c810a6b067920a61dd8d38341244a3605bd31ab55250dad5", size = 247714, upload-time = "2025-08-29T15:33:21.751Z" }, - { url = "https://files.pythonhosted.org/packages/4c/55/0964aa87126624e8c159e32b0bc4e84edef78c89a1a4b924d28dd8265625/coverage-7.10.6-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:5aea98383463d6e1fa4e95416d8de66f2d0cb588774ee20ae1b28df826bcb619", size = 248351, upload-time = "2025-08-29T15:33:23.105Z" }, - { url = "https://files.pythonhosted.org/packages/eb/ab/6cfa9dc518c6c8e14a691c54e53a9433ba67336c760607e299bfcf520cb1/coverage-7.10.6-cp311-cp311-win32.whl", hash = "sha256:e3fb1fa01d3598002777dd259c0c2e6d9d5e10e7222976fc8e03992f972a2cba", size = 219562, upload-time = "2025-08-29T15:33:24.717Z" }, - { url = "https://files.pythonhosted.org/packages/5b/18/99b25346690cbc55922e7cfef06d755d4abee803ef335baff0014268eff4/coverage-7.10.6-cp311-cp311-win_amd64.whl", hash = "sha256:f35ed9d945bece26553d5b4c8630453169672bea0050a564456eb88bdffd927e", size = 220453, upload-time = "2025-08-29T15:33:26.482Z" }, - { url = "https://files.pythonhosted.org/packages/d8/ed/81d86648a07ccb124a5cf1f1a7788712b8d7216b593562683cd5c9b0d2c1/coverage-7.10.6-cp311-cp311-win_arm64.whl", hash = "sha256:99e1a305c7765631d74b98bf7dbf54eeea931f975e80f115437d23848ee8c27c", size = 219127, upload-time = "2025-08-29T15:33:27.777Z" }, - { url = "https://files.pythonhosted.org/packages/26/06/263f3305c97ad78aab066d116b52250dd316e74fcc20c197b61e07eb391a/coverage-7.10.6-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:5b2dd6059938063a2c9fee1af729d4f2af28fd1a545e9b7652861f0d752ebcea", size = 217324, upload-time = "2025-08-29T15:33:29.06Z" }, - { url = "https://files.pythonhosted.org/packages/e9/60/1e1ded9a4fe80d843d7d53b3e395c1db3ff32d6c301e501f393b2e6c1c1f/coverage-7.10.6-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:388d80e56191bf846c485c14ae2bc8898aa3124d9d35903fef7d907780477634", size = 217560, upload-time = "2025-08-29T15:33:30.748Z" }, - { url = "https://files.pythonhosted.org/packages/b8/25/52136173c14e26dfed8b106ed725811bb53c30b896d04d28d74cb64318b3/coverage-7.10.6-cp312-cp312-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:90cb5b1a4670662719591aa92d0095bb41714970c0b065b02a2610172dbf0af6", size = 249053, upload-time = "2025-08-29T15:33:32.041Z" }, - { url = "https://files.pythonhosted.org/packages/cb/1d/ae25a7dc58fcce8b172d42ffe5313fc267afe61c97fa872b80ee72d9515a/coverage-7.10.6-cp312-cp312-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:961834e2f2b863a0e14260a9a273aff07ff7818ab6e66d2addf5628590c628f9", size = 251802, upload-time = "2025-08-29T15:33:33.625Z" }, - { url = "https://files.pythonhosted.org/packages/f5/7a/1f561d47743710fe996957ed7c124b421320f150f1d38523d8d9102d3e2a/coverage-7.10.6-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:bf9a19f5012dab774628491659646335b1928cfc931bf8d97b0d5918dd58033c", size = 252935, upload-time = "2025-08-29T15:33:34.909Z" }, - { url = "https://files.pythonhosted.org/packages/6c/ad/8b97cd5d28aecdfde792dcbf646bac141167a5cacae2cd775998b45fabb5/coverage-7.10.6-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:99c4283e2a0e147b9c9cc6bc9c96124de9419d6044837e9799763a0e29a7321a", size = 250855, upload-time = "2025-08-29T15:33:36.922Z" }, - { url = "https://files.pythonhosted.org/packages/33/6a/95c32b558d9a61858ff9d79580d3877df3eb5bc9eed0941b1f187c89e143/coverage-7.10.6-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:282b1b20f45df57cc508c1e033403f02283adfb67d4c9c35a90281d81e5c52c5", size = 248974, upload-time = "2025-08-29T15:33:38.175Z" }, - { url = "https://files.pythonhosted.org/packages/0d/9c/8ce95dee640a38e760d5b747c10913e7a06554704d60b41e73fdea6a1ffd/coverage-7.10.6-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:8cdbe264f11afd69841bd8c0d83ca10b5b32853263ee62e6ac6a0ab63895f972", size = 250409, upload-time = "2025-08-29T15:33:39.447Z" }, - { url = "https://files.pythonhosted.org/packages/04/12/7a55b0bdde78a98e2eb2356771fd2dcddb96579e8342bb52aa5bc52e96f0/coverage-7.10.6-cp312-cp312-win32.whl", hash = "sha256:a517feaf3a0a3eca1ee985d8373135cfdedfbba3882a5eab4362bda7c7cf518d", size = 219724, upload-time = "2025-08-29T15:33:41.172Z" }, - { url = "https://files.pythonhosted.org/packages/36/4a/32b185b8b8e327802c9efce3d3108d2fe2d9d31f153a0f7ecfd59c773705/coverage-7.10.6-cp312-cp312-win_amd64.whl", hash = "sha256:856986eadf41f52b214176d894a7de05331117f6035a28ac0016c0f63d887629", size = 220536, upload-time = "2025-08-29T15:33:42.524Z" }, - { url = "https://files.pythonhosted.org/packages/08/3a/d5d8dc703e4998038c3099eaf77adddb00536a3cec08c8dcd556a36a3eb4/coverage-7.10.6-cp312-cp312-win_arm64.whl", hash = "sha256:acf36b8268785aad739443fa2780c16260ee3fa09d12b3a70f772ef100939d80", size = 219171, upload-time = "2025-08-29T15:33:43.974Z" }, - { url = "https://files.pythonhosted.org/packages/bd/e7/917e5953ea29a28c1057729c1d5af9084ab6d9c66217523fd0e10f14d8f6/coverage-7.10.6-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:ffea0575345e9ee0144dfe5701aa17f3ba546f8c3bb48db62ae101afb740e7d6", size = 217351, upload-time = "2025-08-29T15:33:45.438Z" }, - { url = "https://files.pythonhosted.org/packages/eb/86/2e161b93a4f11d0ea93f9bebb6a53f113d5d6e416d7561ca41bb0a29996b/coverage-7.10.6-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:95d91d7317cde40a1c249d6b7382750b7e6d86fad9d8eaf4fa3f8f44cf171e80", size = 217600, upload-time = "2025-08-29T15:33:47.269Z" }, - { url = "https://files.pythonhosted.org/packages/0e/66/d03348fdd8df262b3a7fb4ee5727e6e4936e39e2f3a842e803196946f200/coverage-7.10.6-cp313-cp313-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:3e23dd5408fe71a356b41baa82892772a4cefcf758f2ca3383d2aa39e1b7a003", size = 248600, upload-time = "2025-08-29T15:33:48.953Z" }, - { url = "https://files.pythonhosted.org/packages/73/dd/508420fb47d09d904d962f123221bc249f64b5e56aa93d5f5f7603be475f/coverage-7.10.6-cp313-cp313-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:0f3f56e4cb573755e96a16501a98bf211f100463d70275759e73f3cbc00d4f27", size = 251206, upload-time = "2025-08-29T15:33:50.697Z" }, - { url = "https://files.pythonhosted.org/packages/e9/1f/9020135734184f439da85c70ea78194c2730e56c2d18aee6e8ff1719d50d/coverage-7.10.6-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:db4a1d897bbbe7339946ffa2fe60c10cc81c43fab8b062d3fcb84188688174a4", size = 252478, upload-time = "2025-08-29T15:33:52.303Z" }, - { url = "https://files.pythonhosted.org/packages/a4/a4/3d228f3942bb5a2051fde28c136eea23a761177dc4ff4ef54533164ce255/coverage-7.10.6-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:d8fd7879082953c156d5b13c74aa6cca37f6a6f4747b39538504c3f9c63d043d", size = 250637, upload-time = "2025-08-29T15:33:53.67Z" }, - { url = "https://files.pythonhosted.org/packages/36/e3/293dce8cdb9a83de971637afc59b7190faad60603b40e32635cbd15fbf61/coverage-7.10.6-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:28395ca3f71cd103b8c116333fa9db867f3a3e1ad6a084aa3725ae002b6583bc", size = 248529, upload-time = "2025-08-29T15:33:55.022Z" }, - { url = "https://files.pythonhosted.org/packages/90/26/64eecfa214e80dd1d101e420cab2901827de0e49631d666543d0e53cf597/coverage-7.10.6-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:61c950fc33d29c91b9e18540e1aed7d9f6787cc870a3e4032493bbbe641d12fc", size = 250143, upload-time = "2025-08-29T15:33:56.386Z" }, - { url = "https://files.pythonhosted.org/packages/3e/70/bd80588338f65ea5b0d97e424b820fb4068b9cfb9597fbd91963086e004b/coverage-7.10.6-cp313-cp313-win32.whl", hash = "sha256:160c00a5e6b6bdf4e5984b0ef21fc860bc94416c41b7df4d63f536d17c38902e", size = 219770, upload-time = "2025-08-29T15:33:58.063Z" }, - { url = "https://files.pythonhosted.org/packages/a7/14/0b831122305abcc1060c008f6c97bbdc0a913ab47d65070a01dc50293c2b/coverage-7.10.6-cp313-cp313-win_amd64.whl", hash = "sha256:628055297f3e2aa181464c3808402887643405573eb3d9de060d81531fa79d32", size = 220566, upload-time = "2025-08-29T15:33:59.766Z" }, - { url = "https://files.pythonhosted.org/packages/83/c6/81a83778c1f83f1a4a168ed6673eeedc205afb562d8500175292ca64b94e/coverage-7.10.6-cp313-cp313-win_arm64.whl", hash = "sha256:df4ec1f8540b0bcbe26ca7dd0f541847cc8a108b35596f9f91f59f0c060bfdd2", size = 219195, upload-time = "2025-08-29T15:34:01.191Z" }, - { url = "https://files.pythonhosted.org/packages/d7/1c/ccccf4bf116f9517275fa85047495515add43e41dfe8e0bef6e333c6b344/coverage-7.10.6-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:c9a8b7a34a4de3ed987f636f71881cd3b8339f61118b1aa311fbda12741bff0b", size = 218059, upload-time = "2025-08-29T15:34:02.91Z" }, - { url = "https://files.pythonhosted.org/packages/92/97/8a3ceff833d27c7492af4f39d5da6761e9ff624831db9e9f25b3886ddbca/coverage-7.10.6-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:8dd5af36092430c2b075cee966719898f2ae87b636cefb85a653f1d0ba5d5393", size = 218287, upload-time = "2025-08-29T15:34:05.106Z" }, - { url = "https://files.pythonhosted.org/packages/92/d8/50b4a32580cf41ff0423777a2791aaf3269ab60c840b62009aec12d3970d/coverage-7.10.6-cp313-cp313t-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:b0353b0f0850d49ada66fdd7d0c7cdb0f86b900bb9e367024fd14a60cecc1e27", size = 259625, upload-time = "2025-08-29T15:34:06.575Z" }, - { url = "https://files.pythonhosted.org/packages/7e/7e/6a7df5a6fb440a0179d94a348eb6616ed4745e7df26bf2a02bc4db72c421/coverage-7.10.6-cp313-cp313t-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:d6b9ae13d5d3e8aeca9ca94198aa7b3ebbc5acfada557d724f2a1f03d2c0b0df", size = 261801, upload-time = "2025-08-29T15:34:08.006Z" }, - { url = "https://files.pythonhosted.org/packages/3a/4c/a270a414f4ed5d196b9d3d67922968e768cd971d1b251e1b4f75e9362f75/coverage-7.10.6-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:675824a363cc05781b1527b39dc2587b8984965834a748177ee3c37b64ffeafb", size = 264027, upload-time = "2025-08-29T15:34:09.806Z" }, - { url = "https://files.pythonhosted.org/packages/9c/8b/3210d663d594926c12f373c5370bf1e7c5c3a427519a8afa65b561b9a55c/coverage-7.10.6-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:692d70ea725f471a547c305f0d0fc6a73480c62fb0da726370c088ab21aed282", size = 261576, upload-time = "2025-08-29T15:34:11.585Z" }, - { url = "https://files.pythonhosted.org/packages/72/d0/e1961eff67e9e1dba3fc5eb7a4caf726b35a5b03776892da8d79ec895775/coverage-7.10.6-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:851430a9a361c7a8484a36126d1d0ff8d529d97385eacc8dfdc9bfc8c2d2cbe4", size = 259341, upload-time = "2025-08-29T15:34:13.159Z" }, - { url = "https://files.pythonhosted.org/packages/3a/06/d6478d152cd189b33eac691cba27a40704990ba95de49771285f34a5861e/coverage-7.10.6-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:d9369a23186d189b2fc95cc08b8160ba242057e887d766864f7adf3c46b2df21", size = 260468, upload-time = "2025-08-29T15:34:14.571Z" }, - { url = "https://files.pythonhosted.org/packages/ed/73/737440247c914a332f0b47f7598535b29965bf305e19bbc22d4c39615d2b/coverage-7.10.6-cp313-cp313t-win32.whl", hash = "sha256:92be86fcb125e9bda0da7806afd29a3fd33fdf58fba5d60318399adf40bf37d0", size = 220429, upload-time = "2025-08-29T15:34:16.394Z" }, - { url = "https://files.pythonhosted.org/packages/bd/76/b92d3214740f2357ef4a27c75a526eb6c28f79c402e9f20a922c295c05e2/coverage-7.10.6-cp313-cp313t-win_amd64.whl", hash = "sha256:6b3039e2ca459a70c79523d39347d83b73f2f06af5624905eba7ec34d64d80b5", size = 221493, upload-time = "2025-08-29T15:34:17.835Z" }, - { url = "https://files.pythonhosted.org/packages/fc/8e/6dcb29c599c8a1f654ec6cb68d76644fe635513af16e932d2d4ad1e5ac6e/coverage-7.10.6-cp313-cp313t-win_arm64.whl", hash = "sha256:3fb99d0786fe17b228eab663d16bee2288e8724d26a199c29325aac4b0319b9b", size = 219757, upload-time = "2025-08-29T15:34:19.248Z" }, - { url = "https://files.pythonhosted.org/packages/d3/aa/76cf0b5ec00619ef208da4689281d48b57f2c7fde883d14bf9441b74d59f/coverage-7.10.6-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:6008a021907be8c4c02f37cdc3ffb258493bdebfeaf9a839f9e71dfdc47b018e", size = 217331, upload-time = "2025-08-29T15:34:20.846Z" }, - { url = "https://files.pythonhosted.org/packages/65/91/8e41b8c7c505d398d7730206f3cbb4a875a35ca1041efc518051bfce0f6b/coverage-7.10.6-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:5e75e37f23eb144e78940b40395b42f2321951206a4f50e23cfd6e8a198d3ceb", size = 217607, upload-time = "2025-08-29T15:34:22.433Z" }, - { url = "https://files.pythonhosted.org/packages/87/7f/f718e732a423d442e6616580a951b8d1ec3575ea48bcd0e2228386805e79/coverage-7.10.6-cp314-cp314-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:0f7cb359a448e043c576f0da00aa8bfd796a01b06aa610ca453d4dde09cc1034", size = 248663, upload-time = "2025-08-29T15:34:24.425Z" }, - { url = "https://files.pythonhosted.org/packages/e6/52/c1106120e6d801ac03e12b5285e971e758e925b6f82ee9b86db3aa10045d/coverage-7.10.6-cp314-cp314-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:c68018e4fc4e14b5668f1353b41ccf4bc83ba355f0e1b3836861c6f042d89ac1", size = 251197, upload-time = "2025-08-29T15:34:25.906Z" }, - { url = "https://files.pythonhosted.org/packages/3d/ec/3a8645b1bb40e36acde9c0609f08942852a4af91a937fe2c129a38f2d3f5/coverage-7.10.6-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:cd4b2b0707fc55afa160cd5fc33b27ccbf75ca11d81f4ec9863d5793fc6df56a", size = 252551, upload-time = "2025-08-29T15:34:27.337Z" }, - { url = "https://files.pythonhosted.org/packages/a1/70/09ecb68eeb1155b28a1d16525fd3a9b65fbe75337311a99830df935d62b6/coverage-7.10.6-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:4cec13817a651f8804a86e4f79d815b3b28472c910e099e4d5a0e8a3b6a1d4cb", size = 250553, upload-time = "2025-08-29T15:34:29.065Z" }, - { url = "https://files.pythonhosted.org/packages/c6/80/47df374b893fa812e953b5bc93dcb1427a7b3d7a1a7d2db33043d17f74b9/coverage-7.10.6-cp314-cp314-musllinux_1_2_i686.whl", hash = "sha256:f2a6a8e06bbda06f78739f40bfb56c45d14eb8249d0f0ea6d4b3d48e1f7c695d", size = 248486, upload-time = "2025-08-29T15:34:30.897Z" }, - { url = "https://files.pythonhosted.org/packages/4a/65/9f98640979ecee1b0d1a7164b589de720ddf8100d1747d9bbdb84be0c0fb/coverage-7.10.6-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:081b98395ced0d9bcf60ada7661a0b75f36b78b9d7e39ea0790bb4ed8da14747", size = 249981, upload-time = "2025-08-29T15:34:32.365Z" }, - { url = "https://files.pythonhosted.org/packages/1f/55/eeb6603371e6629037f47bd25bef300387257ed53a3c5fdb159b7ac8c651/coverage-7.10.6-cp314-cp314-win32.whl", hash = "sha256:6937347c5d7d069ee776b2bf4e1212f912a9f1f141a429c475e6089462fcecc5", size = 220054, upload-time = "2025-08-29T15:34:34.124Z" }, - { url = "https://files.pythonhosted.org/packages/15/d1/a0912b7611bc35412e919a2cd59ae98e7ea3b475e562668040a43fb27897/coverage-7.10.6-cp314-cp314-win_amd64.whl", hash = "sha256:adec1d980fa07e60b6ef865f9e5410ba760e4e1d26f60f7e5772c73b9a5b0713", size = 220851, upload-time = "2025-08-29T15:34:35.651Z" }, - { url = "https://files.pythonhosted.org/packages/ef/2d/11880bb8ef80a45338e0b3e0725e4c2d73ffbb4822c29d987078224fd6a5/coverage-7.10.6-cp314-cp314-win_arm64.whl", hash = "sha256:a80f7aef9535442bdcf562e5a0d5a5538ce8abe6bb209cfbf170c462ac2c2a32", size = 219429, upload-time = "2025-08-29T15:34:37.16Z" }, - { url = "https://files.pythonhosted.org/packages/83/c0/1f00caad775c03a700146f55536ecd097a881ff08d310a58b353a1421be0/coverage-7.10.6-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:0de434f4fbbe5af4fa7989521c655c8c779afb61c53ab561b64dcee6149e4c65", size = 218080, upload-time = "2025-08-29T15:34:38.919Z" }, - { url = "https://files.pythonhosted.org/packages/a9/c4/b1c5d2bd7cc412cbeb035e257fd06ed4e3e139ac871d16a07434e145d18d/coverage-7.10.6-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:6e31b8155150c57e5ac43ccd289d079eb3f825187d7c66e755a055d2c85794c6", size = 218293, upload-time = "2025-08-29T15:34:40.425Z" }, - { url = "https://files.pythonhosted.org/packages/3f/07/4468d37c94724bf6ec354e4ec2f205fda194343e3e85fd2e59cec57e6a54/coverage-7.10.6-cp314-cp314t-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:98cede73eb83c31e2118ae8d379c12e3e42736903a8afcca92a7218e1f2903b0", size = 259800, upload-time = "2025-08-29T15:34:41.996Z" }, - { url = "https://files.pythonhosted.org/packages/82/d8/f8fb351be5fee31690cd8da768fd62f1cfab33c31d9f7baba6cd8960f6b8/coverage-7.10.6-cp314-cp314t-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:f863c08f4ff6b64fa8045b1e3da480f5374779ef187f07b82e0538c68cb4ff8e", size = 261965, upload-time = "2025-08-29T15:34:43.61Z" }, - { url = "https://files.pythonhosted.org/packages/e8/70/65d4d7cfc75c5c6eb2fed3ee5cdf420fd8ae09c4808723a89a81d5b1b9c3/coverage-7.10.6-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:2b38261034fda87be356f2c3f42221fdb4171c3ce7658066ae449241485390d5", size = 264220, upload-time = "2025-08-29T15:34:45.387Z" }, - { url = "https://files.pythonhosted.org/packages/98/3c/069df106d19024324cde10e4ec379fe2fb978017d25e97ebee23002fbadf/coverage-7.10.6-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:0e93b1476b79eae849dc3872faeb0bf7948fd9ea34869590bc16a2a00b9c82a7", size = 261660, upload-time = "2025-08-29T15:34:47.288Z" }, - { url = "https://files.pythonhosted.org/packages/fc/8a/2974d53904080c5dc91af798b3a54a4ccb99a45595cc0dcec6eb9616a57d/coverage-7.10.6-cp314-cp314t-musllinux_1_2_i686.whl", hash = "sha256:ff8a991f70f4c0cf53088abf1e3886edcc87d53004c7bb94e78650b4d3dac3b5", size = 259417, upload-time = "2025-08-29T15:34:48.779Z" }, - { url = "https://files.pythonhosted.org/packages/30/38/9616a6b49c686394b318974d7f6e08f38b8af2270ce7488e879888d1e5db/coverage-7.10.6-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:ac765b026c9f33044419cbba1da913cfb82cca1b60598ac1c7a5ed6aac4621a0", size = 260567, upload-time = "2025-08-29T15:34:50.718Z" }, - { url = "https://files.pythonhosted.org/packages/76/16/3ed2d6312b371a8cf804abf4e14895b70e4c3491c6e53536d63fd0958a8d/coverage-7.10.6-cp314-cp314t-win32.whl", hash = "sha256:441c357d55f4936875636ef2cfb3bee36e466dcf50df9afbd398ce79dba1ebb7", size = 220831, upload-time = "2025-08-29T15:34:52.653Z" }, - { url = "https://files.pythonhosted.org/packages/d5/e5/d38d0cb830abede2adb8b147770d2a3d0e7fecc7228245b9b1ae6c24930a/coverage-7.10.6-cp314-cp314t-win_amd64.whl", hash = "sha256:073711de3181b2e204e4870ac83a7c4853115b42e9cd4d145f2231e12d670930", size = 221950, upload-time = "2025-08-29T15:34:54.212Z" }, - { url = "https://files.pythonhosted.org/packages/f4/51/e48e550f6279349895b0ffcd6d2a690e3131ba3a7f4eafccc141966d4dea/coverage-7.10.6-cp314-cp314t-win_arm64.whl", hash = "sha256:137921f2bac5559334ba66122b753db6dc5d1cf01eb7b64eb412bb0d064ef35b", size = 219969, upload-time = "2025-08-29T15:34:55.83Z" }, - { url = "https://files.pythonhosted.org/packages/44/0c/50db5379b615854b5cf89146f8f5bd1d5a9693d7f3a987e269693521c404/coverage-7.10.6-py3-none-any.whl", hash = "sha256:92c4ecf6bf11b2e85fd4d8204814dc26e6a19f0c9d938c207c5cb0eadfcabbe3", size = 208986, upload-time = "2025-08-29T15:35:14.506Z" }, -] - -[package.optional-dependencies] -toml = [ - { name = "tomli", marker = "python_full_version <= '3.11'" }, +version = "7.13.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/23/f9/e92df5e07f3fc8d4c7f9a0f146ef75446bf870351cd37b788cf5897f8079/coverage-7.13.1.tar.gz", hash = "sha256:b7593fe7eb5feaa3fbb461ac79aac9f9fc0387a5ca8080b0c6fe2ca27b091afd", size = 825862, upload-time = "2025-12-28T15:42:56.969Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/ce/8a/87af46cccdfa78f53db747b09f5f9a21d5fc38d796834adac09b30a8ce74/coverage-7.13.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:6f34591000f06e62085b1865c9bc5f7858df748834662a51edadfd2c3bfe0dd3", size = 218927, upload-time = "2025-12-28T15:40:52.814Z" }, + { url = "https://files.pythonhosted.org/packages/82/a8/6e22fdc67242a4a5a153f9438d05944553121c8f4ba70cb072af4c41362e/coverage-7.13.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:b67e47c5595b9224599016e333f5ec25392597a89d5744658f837d204e16c63e", size = 219288, upload-time = "2025-12-28T15:40:54.262Z" }, + { url = "https://files.pythonhosted.org/packages/d0/0a/853a76e03b0f7c4375e2ca025df45c918beb367f3e20a0a8e91967f6e96c/coverage-7.13.1-cp312-cp312-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:3e7b8bd70c48ffb28461ebe092c2345536fb18bbbf19d287c8913699735f505c", size = 250786, upload-time = "2025-12-28T15:40:56.059Z" }, + { url = "https://files.pythonhosted.org/packages/ea/b4/694159c15c52b9f7ec7adf49d50e5f8ee71d3e9ef38adb4445d13dd56c20/coverage-7.13.1-cp312-cp312-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:c223d078112e90dc0e5c4e35b98b9584164bea9fbbd221c0b21c5241f6d51b62", size = 253543, upload-time = "2025-12-28T15:40:57.585Z" }, + { url = "https://files.pythonhosted.org/packages/96/b2/7f1f0437a5c855f87e17cf5d0dc35920b6440ff2b58b1ba9788c059c26c8/coverage-7.13.1-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:794f7c05af0763b1bbd1b9e6eff0e52ad068be3b12cd96c87de037b01390c968", size = 254635, upload-time = "2025-12-28T15:40:59.443Z" }, + { url = "https://files.pythonhosted.org/packages/e9/d1/73c3fdb8d7d3bddd9473c9c6a2e0682f09fc3dfbcb9c3f36412a7368bcab/coverage-7.13.1-cp312-cp312-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:0642eae483cc8c2902e4af7298bf886d605e80f26382124cddc3967c2a3df09e", size = 251202, upload-time = "2025-12-28T15:41:01.328Z" }, + { url = "https://files.pythonhosted.org/packages/66/3c/f0edf75dcc152f145d5598329e864bbbe04ab78660fe3e8e395f9fff010f/coverage-7.13.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:9f5e772ed5fef25b3de9f2008fe67b92d46831bd2bc5bdc5dd6bfd06b83b316f", size = 252566, upload-time = "2025-12-28T15:41:03.319Z" }, + { url = "https://files.pythonhosted.org/packages/17/b3/e64206d3c5f7dcbceafd14941345a754d3dbc78a823a6ed526e23b9cdaab/coverage-7.13.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:45980ea19277dc0a579e432aef6a504fe098ef3a9032ead15e446eb0f1191aee", size = 250711, upload-time = "2025-12-28T15:41:06.411Z" }, + { url = "https://files.pythonhosted.org/packages/dc/ad/28a3eb970a8ef5b479ee7f0c484a19c34e277479a5b70269dc652b730733/coverage-7.13.1-cp312-cp312-musllinux_1_2_riscv64.whl", hash = "sha256:e4f18eca6028ffa62adbd185a8f1e1dd242f2e68164dba5c2b74a5204850b4cf", size = 250278, upload-time = "2025-12-28T15:41:08.285Z" }, + { url = "https://files.pythonhosted.org/packages/54/e3/c8f0f1a93133e3e1291ca76cbb63565bd4b5c5df63b141f539d747fff348/coverage-7.13.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:f8dca5590fec7a89ed6826fce625595279e586ead52e9e958d3237821fbc750c", size = 252154, upload-time = "2025-12-28T15:41:09.969Z" }, + { url = "https://files.pythonhosted.org/packages/d0/bf/9939c5d6859c380e405b19e736321f1c7d402728792f4c752ad1adcce005/coverage-7.13.1-cp312-cp312-win32.whl", hash = "sha256:ff86d4e85188bba72cfb876df3e11fa243439882c55957184af44a35bd5880b7", size = 221487, upload-time = "2025-12-28T15:41:11.468Z" }, + { url = "https://files.pythonhosted.org/packages/fa/dc/7282856a407c621c2aad74021680a01b23010bb8ebf427cf5eacda2e876f/coverage-7.13.1-cp312-cp312-win_amd64.whl", hash = "sha256:16cc1da46c04fb0fb128b4dc430b78fa2aba8a6c0c9f8eb391fd5103409a6ac6", size = 222299, upload-time = "2025-12-28T15:41:13.386Z" }, + { url = "https://files.pythonhosted.org/packages/10/79/176a11203412c350b3e9578620013af35bcdb79b651eb976f4a4b32044fa/coverage-7.13.1-cp312-cp312-win_arm64.whl", hash = "sha256:8d9bc218650022a768f3775dd7fdac1886437325d8d295d923ebcfef4892ad5c", size = 220941, upload-time = "2025-12-28T15:41:14.975Z" }, + { url = "https://files.pythonhosted.org/packages/a3/a4/e98e689347a1ff1a7f67932ab535cef82eb5e78f32a9e4132e114bbb3a0a/coverage-7.13.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:cb237bfd0ef4d5eb6a19e29f9e528ac67ac3be932ea6b44fb6cc09b9f3ecff78", size = 218951, upload-time = "2025-12-28T15:41:16.653Z" }, + { url = "https://files.pythonhosted.org/packages/32/33/7cbfe2bdc6e2f03d6b240d23dc45fdaf3fd270aaf2d640be77b7f16989ab/coverage-7.13.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:1dcb645d7e34dcbcc96cd7c132b1fc55c39263ca62eb961c064eb3928997363b", size = 219325, upload-time = "2025-12-28T15:41:18.609Z" }, + { url = "https://files.pythonhosted.org/packages/59/f6/efdabdb4929487baeb7cb2a9f7dac457d9356f6ad1b255be283d58b16316/coverage-7.13.1-cp313-cp313-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:3d42df8201e00384736f0df9be2ced39324c3907607d17d50d50116c989d84cd", size = 250309, upload-time = "2025-12-28T15:41:20.629Z" }, + { url = "https://files.pythonhosted.org/packages/12/da/91a52516e9d5aea87d32d1523f9cdcf7a35a3b298e6be05d6509ba3cfab2/coverage-7.13.1-cp313-cp313-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:fa3edde1aa8807de1d05934982416cb3ec46d1d4d91e280bcce7cca01c507992", size = 252907, upload-time = "2025-12-28T15:41:22.257Z" }, + { url = "https://files.pythonhosted.org/packages/75/38/f1ea837e3dc1231e086db1638947e00d264e7e8c41aa8ecacf6e1e0c05f4/coverage-7.13.1-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:9edd0e01a343766add6817bc448408858ba6b489039eaaa2018474e4001651a4", size = 254148, upload-time = "2025-12-28T15:41:23.87Z" }, + { url = "https://files.pythonhosted.org/packages/7f/43/f4f16b881aaa34954ba446318dea6b9ed5405dd725dd8daac2358eda869a/coverage-7.13.1-cp313-cp313-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:985b7836931d033570b94c94713c6dba5f9d3ff26045f72c3e5dbc5fe3361e5a", size = 250515, upload-time = "2025-12-28T15:41:25.437Z" }, + { url = "https://files.pythonhosted.org/packages/84/34/8cba7f00078bd468ea914134e0144263194ce849ec3baad187ffb6203d1c/coverage-7.13.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:ffed1e4980889765c84a5d1a566159e363b71d6b6fbaf0bebc9d3c30bc016766", size = 252292, upload-time = "2025-12-28T15:41:28.459Z" }, + { url = "https://files.pythonhosted.org/packages/8c/a4/cffac66c7652d84ee4ac52d3ccb94c015687d3b513f9db04bfcac2ac800d/coverage-7.13.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:8842af7f175078456b8b17f1b73a0d16a65dcbdc653ecefeb00a56b3c8c298c4", size = 250242, upload-time = "2025-12-28T15:41:30.02Z" }, + { url = "https://files.pythonhosted.org/packages/f4/78/9a64d462263dde416f3c0067efade7b52b52796f489b1037a95b0dc389c9/coverage-7.13.1-cp313-cp313-musllinux_1_2_riscv64.whl", hash = "sha256:ccd7a6fca48ca9c131d9b0a2972a581e28b13416fc313fb98b6d24a03ce9a398", size = 250068, upload-time = "2025-12-28T15:41:32.007Z" }, + { url = "https://files.pythonhosted.org/packages/69/c8/a8994f5fece06db7c4a97c8fc1973684e178599b42e66280dded0524ef00/coverage-7.13.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:0403f647055de2609be776965108447deb8e384fe4a553c119e3ff6bfbab4784", size = 251846, upload-time = "2025-12-28T15:41:33.946Z" }, + { url = "https://files.pythonhosted.org/packages/cc/f7/91fa73c4b80305c86598a2d4e54ba22df6bf7d0d97500944af7ef155d9f7/coverage-7.13.1-cp313-cp313-win32.whl", hash = "sha256:549d195116a1ba1e1ae2f5ca143f9777800f6636eab917d4f02b5310d6d73461", size = 221512, upload-time = "2025-12-28T15:41:35.519Z" }, + { url = "https://files.pythonhosted.org/packages/45/0b/0768b4231d5a044da8f75e097a8714ae1041246bb765d6b5563bab456735/coverage-7.13.1-cp313-cp313-win_amd64.whl", hash = "sha256:5899d28b5276f536fcf840b18b61a9fce23cc3aec1d114c44c07fe94ebeaa500", size = 222321, upload-time = "2025-12-28T15:41:37.371Z" }, + { url = "https://files.pythonhosted.org/packages/9b/b8/bdcb7253b7e85157282450262008f1366aa04663f3e3e4c30436f596c3e2/coverage-7.13.1-cp313-cp313-win_arm64.whl", hash = "sha256:868a2fae76dfb06e87291bcbd4dcbcc778a8500510b618d50496e520bd94d9b9", size = 220949, upload-time = "2025-12-28T15:41:39.553Z" }, + { url = "https://files.pythonhosted.org/packages/70/52/f2be52cc445ff75ea8397948c96c1b4ee14f7f9086ea62fc929c5ae7b717/coverage-7.13.1-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:67170979de0dacac3f3097d02b0ad188d8edcea44ccc44aaa0550af49150c7dc", size = 219643, upload-time = "2025-12-28T15:41:41.567Z" }, + { url = "https://files.pythonhosted.org/packages/47/79/c85e378eaa239e2edec0c5523f71542c7793fe3340954eafb0bc3904d32d/coverage-7.13.1-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:f80e2bb21bfab56ed7405c2d79d34b5dc0bc96c2c1d2a067b643a09fb756c43a", size = 219997, upload-time = "2025-12-28T15:41:43.418Z" }, + { url = "https://files.pythonhosted.org/packages/fe/9b/b1ade8bfb653c0bbce2d6d6e90cc6c254cbb99b7248531cc76253cb4da6d/coverage-7.13.1-cp313-cp313t-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:f83351e0f7dcdb14d7326c3d8d8c4e915fa685cbfdc6281f9470d97a04e9dfe4", size = 261296, upload-time = "2025-12-28T15:41:45.207Z" }, + { url = "https://files.pythonhosted.org/packages/1f/af/ebf91e3e1a2473d523e87e87fd8581e0aa08741b96265730e2d79ce78d8d/coverage-7.13.1-cp313-cp313t-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:bb3f6562e89bad0110afbe64e485aac2462efdce6232cdec7862a095dc3412f6", size = 263363, upload-time = "2025-12-28T15:41:47.163Z" }, + { url = "https://files.pythonhosted.org/packages/c4/8b/fb2423526d446596624ac7fde12ea4262e66f86f5120114c3cfd0bb2befa/coverage-7.13.1-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:77545b5dcda13b70f872c3b5974ac64c21d05e65b1590b441c8560115dc3a0d1", size = 265783, upload-time = "2025-12-28T15:41:49.03Z" }, + { url = "https://files.pythonhosted.org/packages/9b/26/ef2adb1e22674913b89f0fe7490ecadcef4a71fa96f5ced90c60ec358789/coverage-7.13.1-cp313-cp313t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:a4d240d260a1aed814790bbe1f10a5ff31ce6c21bc78f0da4a1e8268d6c80dbd", size = 260508, upload-time = "2025-12-28T15:41:51.035Z" }, + { url = "https://files.pythonhosted.org/packages/ce/7d/f0f59b3404caf662e7b5346247883887687c074ce67ba453ea08c612b1d5/coverage-7.13.1-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:d2287ac9360dec3837bfdad969963a5d073a09a85d898bd86bea82aa8876ef3c", size = 263357, upload-time = "2025-12-28T15:41:52.631Z" }, + { url = "https://files.pythonhosted.org/packages/1a/b1/29896492b0b1a047604d35d6fa804f12818fa30cdad660763a5f3159e158/coverage-7.13.1-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:0d2c11f3ea4db66b5cbded23b20185c35066892c67d80ec4be4bab257b9ad1e0", size = 260978, upload-time = "2025-12-28T15:41:54.589Z" }, + { url = "https://files.pythonhosted.org/packages/48/f2/971de1238a62e6f0a4128d37adadc8bb882ee96afbe03ff1570291754629/coverage-7.13.1-cp313-cp313t-musllinux_1_2_riscv64.whl", hash = "sha256:3fc6a169517ca0d7ca6846c3c5392ef2b9e38896f61d615cb75b9e7134d4ee1e", size = 259877, upload-time = "2025-12-28T15:41:56.263Z" }, + { url = "https://files.pythonhosted.org/packages/6a/fc/0474efcbb590ff8628830e9aaec5f1831594874360e3251f1fdec31d07a3/coverage-7.13.1-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:d10a2ed46386e850bb3de503a54f9fe8192e5917fcbb143bfef653a9355e9a53", size = 262069, upload-time = "2025-12-28T15:41:58.093Z" }, + { url = "https://files.pythonhosted.org/packages/88/4f/3c159b7953db37a7b44c0eab8a95c37d1aa4257c47b4602c04022d5cb975/coverage-7.13.1-cp313-cp313t-win32.whl", hash = "sha256:75a6f4aa904301dab8022397a22c0039edc1f51e90b83dbd4464b8a38dc87842", size = 222184, upload-time = "2025-12-28T15:41:59.763Z" }, + { url = "https://files.pythonhosted.org/packages/58/a5/6b57d28f81417f9335774f20679d9d13b9a8fb90cd6160957aa3b54a2379/coverage-7.13.1-cp313-cp313t-win_amd64.whl", hash = "sha256:309ef5706e95e62578cda256b97f5e097916a2c26247c287bbe74794e7150df2", size = 223250, upload-time = "2025-12-28T15:42:01.52Z" }, + { url = "https://files.pythonhosted.org/packages/81/7c/160796f3b035acfbb58be80e02e484548595aa67e16a6345e7910ace0a38/coverage-7.13.1-cp313-cp313t-win_arm64.whl", hash = "sha256:92f980729e79b5d16d221038dbf2e8f9a9136afa072f9d5d6ed4cb984b126a09", size = 221521, upload-time = "2025-12-28T15:42:03.275Z" }, + { url = "https://files.pythonhosted.org/packages/aa/8e/ba0e597560c6563fc0adb902fda6526df5d4aa73bb10adf0574d03bd2206/coverage-7.13.1-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:97ab3647280d458a1f9adb85244e81587505a43c0c7cff851f5116cd2814b894", size = 218996, upload-time = "2025-12-28T15:42:04.978Z" }, + { url = "https://files.pythonhosted.org/packages/6b/8e/764c6e116f4221dc7aa26c4061181ff92edb9c799adae6433d18eeba7a14/coverage-7.13.1-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:8f572d989142e0908e6acf57ad1b9b86989ff057c006d13b76c146ec6a20216a", size = 219326, upload-time = "2025-12-28T15:42:06.691Z" }, + { url = "https://files.pythonhosted.org/packages/4f/a6/6130dc6d8da28cdcbb0f2bf8865aeca9b157622f7c0031e48c6cf9a0e591/coverage-7.13.1-cp314-cp314-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:d72140ccf8a147e94274024ff6fd8fb7811354cf7ef88b1f0a988ebaa5bc774f", size = 250374, upload-time = "2025-12-28T15:42:08.786Z" }, + { url = "https://files.pythonhosted.org/packages/82/2b/783ded568f7cd6b677762f780ad338bf4b4750205860c17c25f7c708995e/coverage-7.13.1-cp314-cp314-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:d3c9f051b028810f5a87c88e5d6e9af3c0ff32ef62763bf15d29f740453ca909", size = 252882, upload-time = "2025-12-28T15:42:10.515Z" }, + { url = "https://files.pythonhosted.org/packages/cd/b2/9808766d082e6a4d59eb0cc881a57fc1600eb2c5882813eefff8254f71b5/coverage-7.13.1-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:f398ba4df52d30b1763f62eed9de5620dcde96e6f491f4c62686736b155aa6e4", size = 254218, upload-time = "2025-12-28T15:42:12.208Z" }, + { url = "https://files.pythonhosted.org/packages/44/ea/52a985bb447c871cb4d2e376e401116520991b597c85afdde1ea9ef54f2c/coverage-7.13.1-cp314-cp314-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:132718176cc723026d201e347f800cd1a9e4b62ccd3f82476950834dad501c75", size = 250391, upload-time = "2025-12-28T15:42:14.21Z" }, + { url = "https://files.pythonhosted.org/packages/7f/1d/125b36cc12310718873cfc8209ecfbc1008f14f4f5fa0662aa608e579353/coverage-7.13.1-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:9e549d642426e3579b3f4b92d0431543b012dcb6e825c91619d4e93b7363c3f9", size = 252239, upload-time = "2025-12-28T15:42:16.292Z" }, + { url = "https://files.pythonhosted.org/packages/6a/16/10c1c164950cade470107f9f14bbac8485f8fb8515f515fca53d337e4a7f/coverage-7.13.1-cp314-cp314-musllinux_1_2_i686.whl", hash = "sha256:90480b2134999301eea795b3a9dbf606c6fbab1b489150c501da84a959442465", size = 250196, upload-time = "2025-12-28T15:42:18.54Z" }, + { url = "https://files.pythonhosted.org/packages/2a/c6/cd860fac08780c6fd659732f6ced1b40b79c35977c1356344e44d72ba6c4/coverage-7.13.1-cp314-cp314-musllinux_1_2_riscv64.whl", hash = "sha256:e825dbb7f84dfa24663dd75835e7257f8882629fc11f03ecf77d84a75134b864", size = 250008, upload-time = "2025-12-28T15:42:20.365Z" }, + { url = "https://files.pythonhosted.org/packages/f0/3a/a8c58d3d38f82a5711e1e0a67268362af48e1a03df27c03072ac30feefcf/coverage-7.13.1-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:623dcc6d7a7ba450bbdbeedbaa0c42b329bdae16491af2282f12a7e809be7eb9", size = 251671, upload-time = "2025-12-28T15:42:22.114Z" }, + { url = "https://files.pythonhosted.org/packages/f0/bc/fd4c1da651d037a1e3d53e8cb3f8182f4b53271ffa9a95a2e211bacc0349/coverage-7.13.1-cp314-cp314-win32.whl", hash = "sha256:6e73ebb44dca5f708dc871fe0b90cf4cff1a13f9956f747cc87b535a840386f5", size = 221777, upload-time = "2025-12-28T15:42:23.919Z" }, + { url = "https://files.pythonhosted.org/packages/4b/50/71acabdc8948464c17e90b5ffd92358579bd0910732c2a1c9537d7536aa6/coverage-7.13.1-cp314-cp314-win_amd64.whl", hash = "sha256:be753b225d159feb397bd0bf91ae86f689bad0da09d3b301478cd39b878ab31a", size = 222592, upload-time = "2025-12-28T15:42:25.619Z" }, + { url = "https://files.pythonhosted.org/packages/f7/c8/a6fb943081bb0cc926499c7907731a6dc9efc2cbdc76d738c0ab752f1a32/coverage-7.13.1-cp314-cp314-win_arm64.whl", hash = "sha256:228b90f613b25ba0019361e4ab81520b343b622fc657daf7e501c4ed6a2366c0", size = 221169, upload-time = "2025-12-28T15:42:27.629Z" }, + { url = "https://files.pythonhosted.org/packages/16/61/d5b7a0a0e0e40d62e59bc8c7aa1afbd86280d82728ba97f0673b746b78e2/coverage-7.13.1-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:60cfb538fe9ef86e5b2ab0ca8fc8d62524777f6c611dcaf76dc16fbe9b8e698a", size = 219730, upload-time = "2025-12-28T15:42:29.306Z" }, + { url = "https://files.pythonhosted.org/packages/a3/2c/8881326445fd071bb49514d1ce97d18a46a980712b51fee84f9ab42845b4/coverage-7.13.1-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:57dfc8048c72ba48a8c45e188d811e5efd7e49b387effc8fb17e97936dde5bf6", size = 220001, upload-time = "2025-12-28T15:42:31.319Z" }, + { url = "https://files.pythonhosted.org/packages/b5/d7/50de63af51dfa3a7f91cc37ad8fcc1e244b734232fbc8b9ab0f3c834a5cd/coverage-7.13.1-cp314-cp314t-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:3f2f725aa3e909b3c5fdb8192490bdd8e1495e85906af74fe6e34a2a77ba0673", size = 261370, upload-time = "2025-12-28T15:42:32.992Z" }, + { url = "https://files.pythonhosted.org/packages/e1/2c/d31722f0ec918fd7453b2758312729f645978d212b410cd0f7c2aed88a94/coverage-7.13.1-cp314-cp314t-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:9ee68b21909686eeb21dfcba2c3b81fee70dcf38b140dcd5aa70680995fa3aa5", size = 263485, upload-time = "2025-12-28T15:42:34.759Z" }, + { url = "https://files.pythonhosted.org/packages/fa/7a/2c114fa5c5fc08ba0777e4aec4c97e0b4a1afcb69c75f1f54cff78b073ab/coverage-7.13.1-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:724b1b270cb13ea2e6503476e34541a0b1f62280bc997eab443f87790202033d", size = 265890, upload-time = "2025-12-28T15:42:36.517Z" }, + { url = "https://files.pythonhosted.org/packages/65/d9/f0794aa1c74ceabc780fe17f6c338456bbc4e96bd950f2e969f48ac6fb20/coverage-7.13.1-cp314-cp314t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:916abf1ac5cf7eb16bc540a5bf75c71c43a676f5c52fcb9fe75a2bd75fb944e8", size = 260445, upload-time = "2025-12-28T15:42:38.646Z" }, + { url = "https://files.pythonhosted.org/packages/49/23/184b22a00d9bb97488863ced9454068c79e413cb23f472da6cbddc6cfc52/coverage-7.13.1-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:776483fd35b58d8afe3acbd9988d5de592ab6da2d2a865edfdbc9fdb43e7c486", size = 263357, upload-time = "2025-12-28T15:42:40.788Z" }, + { url = "https://files.pythonhosted.org/packages/7d/bd/58af54c0c9199ea4190284f389005779d7daf7bf3ce40dcd2d2b2f96da69/coverage-7.13.1-cp314-cp314t-musllinux_1_2_i686.whl", hash = "sha256:b6f3b96617e9852703f5b633ea01315ca45c77e879584f283c44127f0f1ec564", size = 260959, upload-time = "2025-12-28T15:42:42.808Z" }, + { url = "https://files.pythonhosted.org/packages/4b/2a/6839294e8f78a4891bf1df79d69c536880ba2f970d0ff09e7513d6e352e9/coverage-7.13.1-cp314-cp314t-musllinux_1_2_riscv64.whl", hash = "sha256:bd63e7b74661fed317212fab774e2a648bc4bb09b35f25474f8e3325d2945cd7", size = 259792, upload-time = "2025-12-28T15:42:44.818Z" }, + { url = "https://files.pythonhosted.org/packages/ba/c3/528674d4623283310ad676c5af7414b9850ab6d55c2300e8aa4b945ec554/coverage-7.13.1-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:933082f161bbb3e9f90d00990dc956120f608cdbcaeea15c4d897f56ef4fe416", size = 262123, upload-time = "2025-12-28T15:42:47.108Z" }, + { url = "https://files.pythonhosted.org/packages/06/c5/8c0515692fb4c73ac379d8dc09b18eaf0214ecb76ea6e62467ba7a1556ff/coverage-7.13.1-cp314-cp314t-win32.whl", hash = "sha256:18be793c4c87de2965e1c0f060f03d9e5aff66cfeae8e1dbe6e5b88056ec153f", size = 222562, upload-time = "2025-12-28T15:42:49.144Z" }, + { url = "https://files.pythonhosted.org/packages/05/0e/c0a0c4678cb30dac735811db529b321d7e1c9120b79bd728d4f4d6b010e9/coverage-7.13.1-cp314-cp314t-win_amd64.whl", hash = "sha256:0e42e0ec0cd3e0d851cb3c91f770c9301f48647cb2877cb78f74bdaa07639a79", size = 223670, upload-time = "2025-12-28T15:42:51.218Z" }, + { url = "https://files.pythonhosted.org/packages/f5/5f/b177aa0011f354abf03a8f30a85032686d290fdeed4222b27d36b4372a50/coverage-7.13.1-cp314-cp314t-win_arm64.whl", hash = "sha256:eaecf47ef10c72ece9a2a92118257da87e460e113b83cc0d2905cbbe931792b4", size = 221707, upload-time = "2025-12-28T15:42:53.034Z" }, + { url = "https://files.pythonhosted.org/packages/cc/48/d9f421cb8da5afaa1a64570d9989e00fb7955e6acddc5a12979f7666ef60/coverage-7.13.1-py3-none-any.whl", hash = "sha256:2016745cb3ba554469d02819d78958b571792bb68e31302610e898f80dd3a573", size = 210722, upload-time = "2025-12-28T15:42:54.901Z" }, ] [[package]] @@ -332,20 +330,11 @@ wheels = [ [[package]] name = "docutils" -version = "0.21.2" +version = "0.22.4" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/ae/ed/aefcc8cd0ba62a0560c3c18c33925362d46c6075480bfa4df87b28e169a9/docutils-0.21.2.tar.gz", hash = "sha256:3a6b18732edf182daa3cd12775bbb338cf5691468f91eeeb109deff6ebfa986f", size = 2204444, upload-time = "2024-04-23T18:57:18.24Z" } +sdist = { url = "https://files.pythonhosted.org/packages/ae/b6/03bb70946330e88ffec97aefd3ea75ba575cb2e762061e0e62a213befee8/docutils-0.22.4.tar.gz", hash = "sha256:4db53b1fde9abecbb74d91230d32ab626d94f6badfc575d6db9194a49df29968", size = 2291750, upload-time = "2025-12-18T19:00:26.443Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/8f/d7/9322c609343d929e75e7e5e6255e614fcc67572cfd083959cdef3b7aad79/docutils-0.21.2-py3-none-any.whl", hash = "sha256:dafca5b9e384f0e419294eb4d2ff9fa826435bf15f15b7bd45723e8ad76811b2", size = 587408, upload-time = "2024-04-23T18:57:14.835Z" }, -] - -[[package]] -name = "execnet" -version = "2.1.1" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/bb/ff/b4c0dc78fbe20c3e59c0c7334de0c27eb4001a2b2017999af398bf730817/execnet-2.1.1.tar.gz", hash = "sha256:5189b52c6121c24feae288166ab41b32549c7e2348652736540b9e6e7d4e72e3", size = 166524, upload-time = "2024-04-08T09:04:19.245Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/43/09/2aea36ff60d16dd8879bdb2f5b3ee0ba8d08cbbdcdfe870e695ce3784385/execnet-2.1.1-py3-none-any.whl", hash = "sha256:26dee51f1b80cebd6d0ca8e74dd8745419761d3bef34163928cbebbdc4749fdc", size = 40612, upload-time = "2024-04-08T09:04:17.414Z" }, + { url = "https://files.pythonhosted.org/packages/02/10/5da547df7a391dcde17f59520a231527b8571e6f46fc8efb02ccb370ab12/docutils-0.22.4-py3-none-any.whl", hash = "sha256:d0013f540772d1420576855455d050a2180186c91c15779301ac2ccb3eeb68de", size = 633196, upload-time = "2025-12-18T19:00:18.077Z" }, ] [[package]] @@ -381,58 +370,66 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/fe/5e/3be305568fe5f34448807976dc82fc151d76c3e0e03958f34770286278c1/flexparser-0.4-py3-none-any.whl", hash = "sha256:3738b456192dcb3e15620f324c447721023c0293f6af9955b481e91d00179846", size = 27625, upload-time = "2024-11-07T02:00:54.523Z" }, ] +[[package]] +name = "folium" +version = "0.20.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "branca" }, + { name = "jinja2" }, + { name = "numpy" }, + { name = "requests" }, + { name = "xyzservices" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/c7/76/84a1b1b00ce71f9c0c44af7d80f310c02e2e583591fe7d4cb03baecd0d3f/folium-0.20.0.tar.gz", hash = "sha256:a0d78b9d5a36ba7589ca9aedbd433e84e9fcab79cd6ac213adbcff922e454cb9", size = 109932, upload-time = "2025-06-16T20:22:51.803Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/b5/a8/5f764f333204db0390362a4356d03a43626997f26818a0e9396f1b3bd8c9/folium-0.20.0-py2.py3-none-any.whl", hash = "sha256:f0bc2a92acde20bca56367aa5c1c376c433f450608d058daebab2fc9bf8198bf", size = 113394, upload-time = "2025-06-16T20:22:50.318Z" }, +] + [[package]] name = "fonttools" -version = "4.59.2" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/0d/a5/fba25f9fbdab96e26dedcaeeba125e5f05a09043bf888e0305326e55685b/fonttools-4.59.2.tar.gz", hash = "sha256:e72c0749b06113f50bcb80332364c6be83a9582d6e3db3fe0b280f996dc2ef22", size = 3540889, upload-time = "2025-08-27T16:40:30.97Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/f8/53/742fcd750ae0bdc74de4c0ff923111199cc2f90a4ee87aaddad505b6f477/fonttools-4.59.2-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:511946e8d7ea5c0d6c7a53c4cb3ee48eda9ab9797cd9bf5d95829a398400354f", size = 2774961, upload-time = "2025-08-27T16:38:47.536Z" }, - { url = "https://files.pythonhosted.org/packages/57/2a/976f5f9fa3b4dd911dc58d07358467bec20e813d933bc5d3db1a955dd456/fonttools-4.59.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:8e5e2682cf7be766d84f462ba8828d01e00c8751a8e8e7ce12d7784ccb69a30d", size = 2344690, upload-time = "2025-08-27T16:38:49.723Z" }, - { url = "https://files.pythonhosted.org/packages/c1/8f/b7eefc274fcf370911e292e95565c8253b0b87c82a53919ab3c795a4f50e/fonttools-4.59.2-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:5729e12a982dba3eeae650de48b06f3b9ddb51e9aee2fcaf195b7d09a96250e2", size = 5026910, upload-time = "2025-08-27T16:38:51.904Z" }, - { url = "https://files.pythonhosted.org/packages/69/95/864726eaa8f9d4e053d0c462e64d5830ec7c599cbdf1db9e40f25ca3972e/fonttools-4.59.2-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:c52694eae5d652361d59ecdb5a2246bff7cff13b6367a12da8499e9df56d148d", size = 4971031, upload-time = "2025-08-27T16:38:53.676Z" }, - { url = "https://files.pythonhosted.org/packages/24/4c/b8c4735ebdea20696277c70c79e0de615dbe477834e5a7c2569aa1db4033/fonttools-4.59.2-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:f1f1bbc23ba1312bd8959896f46f667753b90216852d2a8cfa2d07e0cb234144", size = 5006112, upload-time = "2025-08-27T16:38:55.69Z" }, - { url = "https://files.pythonhosted.org/packages/3b/23/f9ea29c292aa2fc1ea381b2e5621ac436d5e3e0a5dee24ffe5404e58eae8/fonttools-4.59.2-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:1a1bfe5378962825dabe741720885e8b9ae9745ec7ecc4a5ec1f1ce59a6062bf", size = 5117671, upload-time = "2025-08-27T16:38:58.984Z" }, - { url = "https://files.pythonhosted.org/packages/ba/07/cfea304c555bf06e86071ff2a3916bc90f7c07ec85b23bab758d4908c33d/fonttools-4.59.2-cp311-cp311-win32.whl", hash = "sha256:e937790f3c2c18a1cbc7da101550a84319eb48023a715914477d2e7faeaba570", size = 2218157, upload-time = "2025-08-27T16:39:00.75Z" }, - { url = "https://files.pythonhosted.org/packages/d7/de/35d839aa69db737a3f9f3a45000ca24721834d40118652a5775d5eca8ebb/fonttools-4.59.2-cp311-cp311-win_amd64.whl", hash = "sha256:9836394e2f4ce5f9c0a7690ee93bd90aa1adc6b054f1a57b562c5d242c903104", size = 2265846, upload-time = "2025-08-27T16:39:02.453Z" }, - { url = "https://files.pythonhosted.org/packages/ba/3d/1f45db2df51e7bfa55492e8f23f383d372200be3a0ded4bf56a92753dd1f/fonttools-4.59.2-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:82906d002c349cad647a7634b004825a7335f8159d0d035ae89253b4abf6f3ea", size = 2769711, upload-time = "2025-08-27T16:39:04.423Z" }, - { url = "https://files.pythonhosted.org/packages/29/df/cd236ab32a8abfd11558f296e064424258db5edefd1279ffdbcfd4fd8b76/fonttools-4.59.2-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:a10c1bd7644dc58f8862d8ba0cf9fb7fef0af01ea184ba6ce3f50ab7dfe74d5a", size = 2340225, upload-time = "2025-08-27T16:39:06.143Z" }, - { url = "https://files.pythonhosted.org/packages/98/12/b6f9f964fe6d4b4dd4406bcbd3328821c3de1f909ffc3ffa558fe72af48c/fonttools-4.59.2-cp312-cp312-manylinux1_x86_64.manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:738f31f23e0339785fd67652a94bc69ea49e413dfdb14dcb8c8ff383d249464e", size = 4912766, upload-time = "2025-08-27T16:39:08.138Z" }, - { url = "https://files.pythonhosted.org/packages/73/78/82bde2f2d2c306ef3909b927363170b83df96171f74e0ccb47ad344563cd/fonttools-4.59.2-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:0ec99f9bdfee9cdb4a9172f9e8fd578cce5feb231f598909e0aecf5418da4f25", size = 4955178, upload-time = "2025-08-27T16:39:10.094Z" }, - { url = "https://files.pythonhosted.org/packages/92/77/7de766afe2d31dda8ee46d7e479f35c7d48747e558961489a2d6e3a02bd4/fonttools-4.59.2-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:0476ea74161322e08c7a982f83558a2b81b491509984523a1a540baf8611cc31", size = 4897898, upload-time = "2025-08-27T16:39:12.087Z" }, - { url = "https://files.pythonhosted.org/packages/c5/77/ce0e0b905d62a06415fda9f2b2e109a24a5db54a59502b769e9e297d2242/fonttools-4.59.2-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:95922a922daa1f77cc72611747c156cfb38030ead72436a2c551d30ecef519b9", size = 5049144, upload-time = "2025-08-27T16:39:13.84Z" }, - { url = "https://files.pythonhosted.org/packages/d9/ea/870d93aefd23fff2e07cbeebdc332527868422a433c64062c09d4d5e7fe6/fonttools-4.59.2-cp312-cp312-win32.whl", hash = "sha256:39ad9612c6a622726a6a130e8ab15794558591f999673f1ee7d2f3d30f6a3e1c", size = 2206473, upload-time = "2025-08-27T16:39:15.854Z" }, - { url = "https://files.pythonhosted.org/packages/61/c4/e44bad000c4a4bb2e9ca11491d266e857df98ab6d7428441b173f0fe2517/fonttools-4.59.2-cp312-cp312-win_amd64.whl", hash = "sha256:980fd7388e461b19a881d35013fec32c713ffea1fc37aef2f77d11f332dfd7da", size = 2254706, upload-time = "2025-08-27T16:39:17.893Z" }, - { url = "https://files.pythonhosted.org/packages/13/7b/d0d3b9431642947b5805201fbbbe938a47b70c76685ef1f0cb5f5d7140d6/fonttools-4.59.2-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:381bde13216ba09489864467f6bc0c57997bd729abfbb1ce6f807ba42c06cceb", size = 2761563, upload-time = "2025-08-27T16:39:20.286Z" }, - { url = "https://files.pythonhosted.org/packages/76/be/fc5fe58dd76af7127b769b68071dbc32d4b95adc8b58d1d28d42d93c90f2/fonttools-4.59.2-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:f33839aa091f7eef4e9078f5b7ab1b8ea4b1d8a50aeaef9fdb3611bba80869ec", size = 2335671, upload-time = "2025-08-27T16:39:22.027Z" }, - { url = "https://files.pythonhosted.org/packages/f2/9f/bf231c2a3fac99d1d7f1d89c76594f158693f981a4aa02be406e9f036832/fonttools-4.59.2-cp313-cp313-manylinux1_x86_64.manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:6235fc06bcbdb40186f483ba9d5d68f888ea68aa3c8dac347e05a7c54346fbc8", size = 4893967, upload-time = "2025-08-27T16:39:23.664Z" }, - { url = "https://files.pythonhosted.org/packages/26/a9/d46d2ad4fcb915198504d6727f83aa07f46764c64f425a861aa38756c9fd/fonttools-4.59.2-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:83ad6e5d06ef3a2884c4fa6384a20d6367b5cfe560e3b53b07c9dc65a7020e73", size = 4951986, upload-time = "2025-08-27T16:39:25.379Z" }, - { url = "https://files.pythonhosted.org/packages/07/90/1cc8d7dd8f707dfeeca472b82b898d3add0ebe85b1f645690dcd128ee63f/fonttools-4.59.2-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:d029804c70fddf90be46ed5305c136cae15800a2300cb0f6bba96d48e770dde0", size = 4891630, upload-time = "2025-08-27T16:39:27.494Z" }, - { url = "https://files.pythonhosted.org/packages/d8/04/f0345b0d9fe67d65aa8d3f2d4cbf91d06f111bc7b8d802e65914eb06194d/fonttools-4.59.2-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:95807a3b5e78f2714acaa26a33bc2143005cc05c0217b322361a772e59f32b89", size = 5035116, upload-time = "2025-08-27T16:39:29.406Z" }, - { url = "https://files.pythonhosted.org/packages/d7/7d/5ba5eefffd243182fbd067cdbfeb12addd4e5aec45011b724c98a344ea33/fonttools-4.59.2-cp313-cp313-win32.whl", hash = "sha256:b3ebda00c3bb8f32a740b72ec38537d54c7c09f383a4cfefb0b315860f825b08", size = 2204907, upload-time = "2025-08-27T16:39:31.42Z" }, - { url = "https://files.pythonhosted.org/packages/ea/a9/be7219fc64a6026cc0aded17fa3720f9277001c185434230bd351bf678e6/fonttools-4.59.2-cp313-cp313-win_amd64.whl", hash = "sha256:a72155928d7053bbde499d32a9c77d3f0f3d29ae72b5a121752481bcbd71e50f", size = 2253742, upload-time = "2025-08-27T16:39:33.079Z" }, - { url = "https://files.pythonhosted.org/packages/fc/c7/486580d00be6fa5d45e41682e5ffa5c809f3d25773c6f39628d60f333521/fonttools-4.59.2-cp314-cp314-macosx_10_13_universal2.whl", hash = "sha256:d09e487d6bfbe21195801323ba95c91cb3523f0fcc34016454d4d9ae9eaa57fe", size = 2762444, upload-time = "2025-08-27T16:39:34.759Z" }, - { url = "https://files.pythonhosted.org/packages/d3/9b/950ea9b7b764ceb8d18645c62191e14ce62124d8e05cb32a4dc5e65fde0b/fonttools-4.59.2-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:dec2f22486d7781087b173799567cffdcc75e9fb2f1c045f05f8317ccce76a3e", size = 2333256, upload-time = "2025-08-27T16:39:40.777Z" }, - { url = "https://files.pythonhosted.org/packages/9b/4d/8ee9d563126de9002eede950cde0051be86cc4e8c07c63eca0c9fc95734a/fonttools-4.59.2-cp314-cp314-manylinux1_x86_64.manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:1647201af10993090120da2e66e9526c4e20e88859f3e34aa05b8c24ded2a564", size = 4834846, upload-time = "2025-08-27T16:39:42.885Z" }, - { url = "https://files.pythonhosted.org/packages/03/26/f26d947b0712dce3d118e92ce30ca88f98938b066498f60d0ee000a892ae/fonttools-4.59.2-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:47742c33fe65f41eabed36eec2d7313a8082704b7b808752406452f766c573fc", size = 4930871, upload-time = "2025-08-27T16:39:44.818Z" }, - { url = "https://files.pythonhosted.org/packages/fc/7f/ebe878061a5a5e6b6502f0548489e01100f7e6c0049846e6546ba19a3ab4/fonttools-4.59.2-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:92ac2d45794f95d1ad4cb43fa07e7e3776d86c83dc4b9918cf82831518165b4b", size = 4876971, upload-time = "2025-08-27T16:39:47.027Z" }, - { url = "https://files.pythonhosted.org/packages/eb/0d/0d22e3a20ac566836098d30718092351935487e3271fd57385db1adb2fde/fonttools-4.59.2-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:fa9ecaf2dcef8941fb5719e16322345d730f4c40599bbf47c9753de40eb03882", size = 4987478, upload-time = "2025-08-27T16:39:48.774Z" }, - { url = "https://files.pythonhosted.org/packages/3b/a3/960cc83182a408ffacc795e61b5f698c6f7b0cfccf23da4451c39973f3c8/fonttools-4.59.2-cp314-cp314-win32.whl", hash = "sha256:a8d40594982ed858780e18a7e4c80415af65af0f22efa7de26bdd30bf24e1e14", size = 2208640, upload-time = "2025-08-27T16:39:50.592Z" }, - { url = "https://files.pythonhosted.org/packages/d8/74/55e5c57c414fa3965fee5fc036ed23f26a5c4e9e10f7f078a54ff9c7dfb7/fonttools-4.59.2-cp314-cp314-win_amd64.whl", hash = "sha256:9cde8b6a6b05f68516573523f2013a3574cb2c75299d7d500f44de82ba947b80", size = 2258457, upload-time = "2025-08-27T16:39:52.611Z" }, - { url = "https://files.pythonhosted.org/packages/e1/dc/8e4261dc591c5cfee68fecff3ffee2a9b29e1edc4c4d9cbafdc5aefe74ee/fonttools-4.59.2-cp314-cp314t-macosx_10_13_universal2.whl", hash = "sha256:036cd87a2dbd7ef72f7b68df8314ced00b8d9973aee296f2464d06a836aeb9a9", size = 2829901, upload-time = "2025-08-27T16:39:55.014Z" }, - { url = "https://files.pythonhosted.org/packages/fb/05/331538dcf21fd6331579cd628268150e85210d0d2bdae20f7598c2b36c05/fonttools-4.59.2-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:14870930181493b1d740b6f25483e20185e5aea58aec7d266d16da7be822b4bb", size = 2362717, upload-time = "2025-08-27T16:39:56.843Z" }, - { url = "https://files.pythonhosted.org/packages/60/ae/d26428ca9ede809c0a93f0af91f44c87433dc0251e2aec333da5ed00d38f/fonttools-4.59.2-cp314-cp314t-manylinux1_x86_64.manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:7ff58ea1eb8fc7e05e9a949419f031890023f8785c925b44d6da17a6a7d6e85d", size = 4835120, upload-time = "2025-08-27T16:39:59.06Z" }, - { url = "https://files.pythonhosted.org/packages/07/c4/0f6ac15895de509e07688cb1d45f1ae583adbaa0fa5a5699d73f3bd58ca0/fonttools-4.59.2-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6dee142b8b3096514c96ad9e2106bf039e2fe34a704c587585b569a36df08c3c", size = 5071115, upload-time = "2025-08-27T16:40:01.009Z" }, - { url = "https://files.pythonhosted.org/packages/b2/b6/147a711b7ecf7ea39f9da9422a55866f6dd5747c2f36b3b0a7a7e0c6820b/fonttools-4.59.2-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:8991bdbae39cf78bcc9cd3d81f6528df1f83f2e7c23ccf6f990fa1f0b6e19708", size = 4943905, upload-time = "2025-08-27T16:40:03.179Z" }, - { url = "https://files.pythonhosted.org/packages/5b/4e/2ab19006646b753855e2b02200fa1cabb75faa4eeca4ef289f269a936974/fonttools-4.59.2-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:53c1a411b7690042535a4f0edf2120096a39a506adeb6c51484a232e59f2aa0c", size = 4960313, upload-time = "2025-08-27T16:40:05.45Z" }, - { url = "https://files.pythonhosted.org/packages/98/3d/df77907e5be88adcca93cc2cee00646d039da220164be12bee028401e1cf/fonttools-4.59.2-cp314-cp314t-win32.whl", hash = "sha256:59d85088e29fa7a8f87d19e97a1beae2a35821ee48d8ef6d2c4f965f26cb9f8a", size = 2269719, upload-time = "2025-08-27T16:40:07.553Z" }, - { url = "https://files.pythonhosted.org/packages/2d/a0/d4c4bc5b50275449a9a908283b567caa032a94505fe1976e17f994faa6be/fonttools-4.59.2-cp314-cp314t-win_amd64.whl", hash = "sha256:7ad5d8d8cc9e43cb438b3eb4a0094dd6d4088daa767b0a24d52529361fd4c199", size = 2333169, upload-time = "2025-08-27T16:40:09.656Z" }, - { url = "https://files.pythonhosted.org/packages/65/a4/d2f7be3c86708912c02571db0b550121caab8cd88a3c0aacb9cfa15ea66e/fonttools-4.59.2-py3-none-any.whl", hash = "sha256:8bd0f759020e87bb5d323e6283914d9bf4ae35a7307dafb2cbd1e379e720ad37", size = 1132315, upload-time = "2025-08-27T16:40:28.984Z" }, +version = "4.61.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/ec/ca/cf17b88a8df95691275a3d77dc0a5ad9907f328ae53acbe6795da1b2f5ed/fonttools-4.61.1.tar.gz", hash = "sha256:6675329885c44657f826ef01d9e4fb33b9158e9d93c537d84ad8399539bc6f69", size = 3565756, upload-time = "2025-12-12T17:31:24.246Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/6f/16/7decaa24a1bd3a70c607b2e29f0adc6159f36a7e40eaba59846414765fd4/fonttools-4.61.1-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:f3cb4a569029b9f291f88aafc927dd53683757e640081ca8c412781ea144565e", size = 2851593, upload-time = "2025-12-12T17:30:04.225Z" }, + { url = "https://files.pythonhosted.org/packages/94/98/3c4cb97c64713a8cf499b3245c3bf9a2b8fd16a3e375feff2aed78f96259/fonttools-4.61.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:41a7170d042e8c0024703ed13b71893519a1a6d6e18e933e3ec7507a2c26a4b2", size = 2400231, upload-time = "2025-12-12T17:30:06.47Z" }, + { url = "https://files.pythonhosted.org/packages/b7/37/82dbef0f6342eb01f54bca073ac1498433d6ce71e50c3c3282b655733b31/fonttools-4.61.1-cp312-cp312-manylinux1_x86_64.manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:10d88e55330e092940584774ee5e8a6971b01fc2f4d3466a1d6c158230880796", size = 4954103, upload-time = "2025-12-12T17:30:08.432Z" }, + { url = "https://files.pythonhosted.org/packages/6c/44/f3aeac0fa98e7ad527f479e161aca6c3a1e47bb6996b053d45226fe37bf2/fonttools-4.61.1-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:15acc09befd16a0fb8a8f62bc147e1a82817542d72184acca9ce6e0aeda9fa6d", size = 5004295, upload-time = "2025-12-12T17:30:10.56Z" }, + { url = "https://files.pythonhosted.org/packages/14/e8/7424ced75473983b964d09f6747fa09f054a6d656f60e9ac9324cf40c743/fonttools-4.61.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:e6bcdf33aec38d16508ce61fd81838f24c83c90a1d1b8c68982857038673d6b8", size = 4944109, upload-time = "2025-12-12T17:30:12.874Z" }, + { url = "https://files.pythonhosted.org/packages/c8/8b/6391b257fa3d0b553d73e778f953a2f0154292a7a7a085e2374b111e5410/fonttools-4.61.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:5fade934607a523614726119164ff621e8c30e8fa1ffffbbd358662056ba69f0", size = 5093598, upload-time = "2025-12-12T17:30:15.79Z" }, + { url = "https://files.pythonhosted.org/packages/d9/71/fd2ea96cdc512d92da5678a1c98c267ddd4d8c5130b76d0f7a80f9a9fde8/fonttools-4.61.1-cp312-cp312-win32.whl", hash = "sha256:75da8f28eff26defba42c52986de97b22106cb8f26515b7c22443ebc9c2d3261", size = 2269060, upload-time = "2025-12-12T17:30:18.058Z" }, + { url = "https://files.pythonhosted.org/packages/80/3b/a3e81b71aed5a688e89dfe0e2694b26b78c7d7f39a5ffd8a7d75f54a12a8/fonttools-4.61.1-cp312-cp312-win_amd64.whl", hash = "sha256:497c31ce314219888c0e2fce5ad9178ca83fe5230b01a5006726cdf3ac9f24d9", size = 2319078, upload-time = "2025-12-12T17:30:22.862Z" }, + { url = "https://files.pythonhosted.org/packages/4b/cf/00ba28b0990982530addb8dc3e9e6f2fa9cb5c20df2abdda7baa755e8fe1/fonttools-4.61.1-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:8c56c488ab471628ff3bfa80964372fc13504ece601e0d97a78ee74126b2045c", size = 2846454, upload-time = "2025-12-12T17:30:24.938Z" }, + { url = "https://files.pythonhosted.org/packages/5a/ca/468c9a8446a2103ae645d14fee3f610567b7042aba85031c1c65e3ef7471/fonttools-4.61.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:dc492779501fa723b04d0ab1f5be046797fee17d27700476edc7ee9ae535a61e", size = 2398191, upload-time = "2025-12-12T17:30:27.343Z" }, + { url = "https://files.pythonhosted.org/packages/a3/4b/d67eedaed19def5967fade3297fed8161b25ba94699efc124b14fb68cdbc/fonttools-4.61.1-cp313-cp313-manylinux1_x86_64.manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:64102ca87e84261419c3747a0d20f396eb024bdbeb04c2bfb37e2891f5fadcb5", size = 4928410, upload-time = "2025-12-12T17:30:29.771Z" }, + { url = "https://files.pythonhosted.org/packages/b0/8d/6fb3494dfe61a46258cd93d979cf4725ded4eb46c2a4ca35e4490d84daea/fonttools-4.61.1-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:4c1b526c8d3f615a7b1867f38a9410849c8f4aef078535742198e942fba0e9bd", size = 4984460, upload-time = "2025-12-12T17:30:32.073Z" }, + { url = "https://files.pythonhosted.org/packages/f7/f1/a47f1d30b3dc00d75e7af762652d4cbc3dff5c2697a0dbd5203c81afd9c3/fonttools-4.61.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:41ed4b5ec103bd306bb68f81dc166e77409e5209443e5773cb4ed837bcc9b0d3", size = 4925800, upload-time = "2025-12-12T17:30:34.339Z" }, + { url = "https://files.pythonhosted.org/packages/a7/01/e6ae64a0981076e8a66906fab01539799546181e32a37a0257b77e4aa88b/fonttools-4.61.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:b501c862d4901792adaec7c25b1ecc749e2662543f68bb194c42ba18d6eec98d", size = 5067859, upload-time = "2025-12-12T17:30:36.593Z" }, + { url = "https://files.pythonhosted.org/packages/73/aa/28e40b8d6809a9b5075350a86779163f074d2b617c15d22343fce81918db/fonttools-4.61.1-cp313-cp313-win32.whl", hash = "sha256:4d7092bb38c53bbc78e9255a59158b150bcdc115a1e3b3ce0b5f267dc35dd63c", size = 2267821, upload-time = "2025-12-12T17:30:38.478Z" }, + { url = "https://files.pythonhosted.org/packages/1a/59/453c06d1d83dc0951b69ef692d6b9f1846680342927df54e9a1ca91c6f90/fonttools-4.61.1-cp313-cp313-win_amd64.whl", hash = "sha256:21e7c8d76f62ab13c9472ccf74515ca5b9a761d1bde3265152a6dc58700d895b", size = 2318169, upload-time = "2025-12-12T17:30:40.951Z" }, + { url = "https://files.pythonhosted.org/packages/32/8f/4e7bf82c0cbb738d3c2206c920ca34ca74ef9dabde779030145d28665104/fonttools-4.61.1-cp314-cp314-macosx_10_15_universal2.whl", hash = "sha256:fff4f534200a04b4a36e7ae3cb74493afe807b517a09e99cb4faa89a34ed6ecd", size = 2846094, upload-time = "2025-12-12T17:30:43.511Z" }, + { url = "https://files.pythonhosted.org/packages/71/09/d44e45d0a4f3a651f23a1e9d42de43bc643cce2971b19e784cc67d823676/fonttools-4.61.1-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:d9203500f7c63545b4ce3799319fe4d9feb1a1b89b28d3cb5abd11b9dd64147e", size = 2396589, upload-time = "2025-12-12T17:30:45.681Z" }, + { url = "https://files.pythonhosted.org/packages/89/18/58c64cafcf8eb677a99ef593121f719e6dcbdb7d1c594ae5a10d4997ca8a/fonttools-4.61.1-cp314-cp314-manylinux1_x86_64.manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:fa646ecec9528bef693415c79a86e733c70a4965dd938e9a226b0fc64c9d2e6c", size = 4877892, upload-time = "2025-12-12T17:30:47.709Z" }, + { url = "https://files.pythonhosted.org/packages/8a/ec/9e6b38c7ba1e09eb51db849d5450f4c05b7e78481f662c3b79dbde6f3d04/fonttools-4.61.1-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:11f35ad7805edba3aac1a3710d104592df59f4b957e30108ae0ba6c10b11dd75", size = 4972884, upload-time = "2025-12-12T17:30:49.656Z" }, + { url = "https://files.pythonhosted.org/packages/5e/87/b5339da8e0256734ba0dbbf5b6cdebb1dd79b01dc8c270989b7bcd465541/fonttools-4.61.1-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:b931ae8f62db78861b0ff1ac017851764602288575d65b8e8ff1963fed419063", size = 4924405, upload-time = "2025-12-12T17:30:51.735Z" }, + { url = "https://files.pythonhosted.org/packages/0b/47/e3409f1e1e69c073a3a6fd8cb886eb18c0bae0ee13db2c8d5e7f8495e8b7/fonttools-4.61.1-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:b148b56f5de675ee16d45e769e69f87623a4944f7443850bf9a9376e628a89d2", size = 5035553, upload-time = "2025-12-12T17:30:54.823Z" }, + { url = "https://files.pythonhosted.org/packages/bf/b6/1f6600161b1073a984294c6c031e1a56ebf95b6164249eecf30012bb2e38/fonttools-4.61.1-cp314-cp314-win32.whl", hash = "sha256:9b666a475a65f4e839d3d10473fad6d47e0a9db14a2f4a224029c5bfde58ad2c", size = 2271915, upload-time = "2025-12-12T17:30:57.913Z" }, + { url = "https://files.pythonhosted.org/packages/52/7b/91e7b01e37cc8eb0e1f770d08305b3655e4f002fc160fb82b3390eabacf5/fonttools-4.61.1-cp314-cp314-win_amd64.whl", hash = "sha256:4f5686e1fe5fce75d82d93c47a438a25bf0d1319d2843a926f741140b2b16e0c", size = 2323487, upload-time = "2025-12-12T17:30:59.804Z" }, + { url = "https://files.pythonhosted.org/packages/39/5c/908ad78e46c61c3e3ed70c3b58ff82ab48437faf84ec84f109592cabbd9f/fonttools-4.61.1-cp314-cp314t-macosx_10_15_universal2.whl", hash = "sha256:e76ce097e3c57c4bcb67c5aa24a0ecdbd9f74ea9219997a707a4061fbe2707aa", size = 2929571, upload-time = "2025-12-12T17:31:02.574Z" }, + { url = "https://files.pythonhosted.org/packages/bd/41/975804132c6dea64cdbfbaa59f3518a21c137a10cccf962805b301ac6ab2/fonttools-4.61.1-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:9cfef3ab326780c04d6646f68d4b4742aae222e8b8ea1d627c74e38afcbc9d91", size = 2435317, upload-time = "2025-12-12T17:31:04.974Z" }, + { url = "https://files.pythonhosted.org/packages/b0/5a/aef2a0a8daf1ebaae4cfd83f84186d4a72ee08fd6a8451289fcd03ffa8a4/fonttools-4.61.1-cp314-cp314t-manylinux1_x86_64.manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:a75c301f96db737e1c5ed5fd7d77d9c34466de16095a266509e13da09751bd19", size = 4882124, upload-time = "2025-12-12T17:31:07.456Z" }, + { url = "https://files.pythonhosted.org/packages/80/33/d6db3485b645b81cea538c9d1c9219d5805f0877fda18777add4671c5240/fonttools-4.61.1-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:91669ccac46bbc1d09e9273546181919064e8df73488ea087dcac3e2968df9ba", size = 5100391, upload-time = "2025-12-12T17:31:09.732Z" }, + { url = "https://files.pythonhosted.org/packages/6c/d6/675ba631454043c75fcf76f0ca5463eac8eb0666ea1d7badae5fea001155/fonttools-4.61.1-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:c33ab3ca9d3ccd581d58e989d67554e42d8d4ded94ab3ade3508455fe70e65f7", size = 4978800, upload-time = "2025-12-12T17:31:11.681Z" }, + { url = "https://files.pythonhosted.org/packages/7f/33/d3ec753d547a8d2bdaedd390d4a814e8d5b45a093d558f025c6b990b554c/fonttools-4.61.1-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:664c5a68ec406f6b1547946683008576ef8b38275608e1cee6c061828171c118", size = 5006426, upload-time = "2025-12-12T17:31:13.764Z" }, + { url = "https://files.pythonhosted.org/packages/b4/40/cc11f378b561a67bea850ab50063366a0d1dd3f6d0a30ce0f874b0ad5664/fonttools-4.61.1-cp314-cp314t-win32.whl", hash = "sha256:aed04cabe26f30c1647ef0e8fbb207516fd40fe9472e9439695f5c6998e60ac5", size = 2335377, upload-time = "2025-12-12T17:31:16.49Z" }, + { url = "https://files.pythonhosted.org/packages/e4/ff/c9a2b66b39f8628531ea58b320d66d951267c98c6a38684daa8f50fb02f8/fonttools-4.61.1-cp314-cp314t-win_amd64.whl", hash = "sha256:2180f14c141d2f0f3da43f3a81bc8aa4684860f6b0e6f9e165a4831f24e6a23b", size = 2400613, upload-time = "2025-12-12T17:31:18.769Z" }, + { url = "https://files.pythonhosted.org/packages/c7/4e/ce75a57ff3aebf6fc1f4e9d508b8e5810618a33d900ad6c19eb30b290b97/fonttools-4.61.1-py3-none-any.whl", hash = "sha256:17d2bf5d541add43822bcf0c43d7d847b160c9bb01d15d5007d84e2217aaa371", size = 1148996, upload-time = "2025-12-12T17:31:21.03Z" }, ] [[package]] name = "furo" -version = "2025.7.19" +version = "2025.12.19" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "accessible-pygments" }, @@ -441,14 +438,14 @@ dependencies = [ { name = "sphinx" }, { name = "sphinx-basic-ng" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/d0/69/312cd100fa45ddaea5a588334d2defa331ff427bcb61f5fe2ae61bdc3762/furo-2025.7.19.tar.gz", hash = "sha256:4164b2cafcf4023a59bb3c594e935e2516f6b9d35e9a5ea83d8f6b43808fe91f", size = 1662054, upload-time = "2025-07-19T10:52:09.754Z" } +sdist = { url = "https://files.pythonhosted.org/packages/ec/20/5f5ad4da6a5a27c80f2ed2ee9aee3f9e36c66e56e21c00fde467b2f8f88f/furo-2025.12.19.tar.gz", hash = "sha256:188d1f942037d8b37cd3985b955839fea62baa1730087dc29d157677c857e2a7", size = 1661473, upload-time = "2025-12-19T17:34:40.889Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/3a/34/2b07b72bee02a63241d654f5d8af87a2de977c59638eec41ca356ab915cd/furo-2025.7.19-py3-none-any.whl", hash = "sha256:bdea869822dfd2b494ea84c0973937e35d1575af088b6721a29c7f7878adc9e3", size = 342175, upload-time = "2025-07-19T10:52:02.399Z" }, + { url = "https://files.pythonhosted.org/packages/f4/b2/50e9b292b5cac13e9e81272c7171301abc753a60460d21505b606e15cf21/furo-2025.12.19-py3-none-any.whl", hash = "sha256:bb0ead5309f9500130665a26bee87693c41ce4dbdff864dbfb6b0dae4673d24f", size = 339262, upload-time = "2025-12-19T17:34:38.905Z" }, ] [[package]] name = "geopandas" -version = "1.1.1" +version = "1.1.2" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "numpy" }, @@ -458,18 +455,18 @@ dependencies = [ { name = "pyproj" }, { name = "shapely" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/8c/76/e1960ba846f153ab109575242abf89dc98f8e057faa32f3decf4cce9247a/geopandas-1.1.1.tar.gz", hash = "sha256:1745713f64d095c43e72e08e753dbd271678254b24f2e01db8cdb8debe1d293d", size = 332655, upload-time = "2025-06-26T21:04:56.57Z" } +sdist = { url = "https://files.pythonhosted.org/packages/8d/24/5eb5685d7bf89d64218919379f882d19a60f8219d66d833c83b1cf264c95/geopandas-1.1.2.tar.gz", hash = "sha256:33f7b33565c46a45b8459a2ab699ec943fdbb5716e58e251b3c413cf7783106c", size = 336037, upload-time = "2025-12-22T21:06:13.749Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/0b/70/d5cd0696eff08e62fdbdebe5b46527facb4e7220eabe0ac6225efab50168/geopandas-1.1.1-py3-none-any.whl", hash = "sha256:589e61aaf39b19828843df16cb90234e72897e2579be236f10eee0d052ad98e8", size = 338365, upload-time = "2025-06-26T21:04:55.139Z" }, + { url = "https://files.pythonhosted.org/packages/54/e4/fac19dc34cb686c96011388b813ff7b858a70681e5ce6ce7698e5021b0f4/geopandas-1.1.2-py3-none-any.whl", hash = "sha256:2bb0b1052cb47378addb4ba54c47f8d4642dcbda9b61375638274f49d9f0bb0d", size = 341734, upload-time = "2025-12-22T21:06:12.498Z" }, ] [[package]] name = "idna" -version = "3.10" +version = "3.11" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/f1/70/7703c29685631f5a7590aa73f1f1d3fa9a380e654b86af429e0934a32f7d/idna-3.10.tar.gz", hash = "sha256:12f65c9b470abda6dc35cf8e63cc574b1c52b11df2c86030af0ac09b01b13ea9", size = 190490, upload-time = "2024-09-15T18:07:39.745Z" } +sdist = { url = "https://files.pythonhosted.org/packages/6f/6d/0703ccc57f3a7233505399edb88de3cbd678da106337b9fcde432b65ed60/idna-3.11.tar.gz", hash = "sha256:795dafcc9c04ed0c1fb032c2aa73654d8e8c5023a7df64a53f39190ada629902", size = 194582, upload-time = "2025-10-12T14:55:20.501Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/76/c6/c88e154df9c4e1a2a66ccf0005a88dfb2650c1dffb6f5ce603dfbd452ce3/idna-3.10-py3-none-any.whl", hash = "sha256:946d195a0d259cbba61165e88e65941f16e9b36ea6ddb97f00452bae8b1287d3", size = 70442, upload-time = "2024-09-15T18:07:37.964Z" }, + { url = "https://files.pythonhosted.org/packages/0e/61/66938bbb5fc52dbdf84594873d5b51fb1f7c7794e9c0f5bd885f30bc507b/idna-3.11-py3-none-any.whl", hash = "sha256:771a87f49d9defaf64091e6e6fe9c18d4833f140bd19464795bc32d966ca37ea", size = 71008, upload-time = "2025-10-12T14:55:18.883Z" }, ] [[package]] @@ -483,16 +480,16 @@ wheels = [ [[package]] name = "iniconfig" -version = "2.1.0" +version = "2.3.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/f2/97/ebf4da567aa6827c909642694d71c9fcf53e5b504f2d96afea02718862f3/iniconfig-2.1.0.tar.gz", hash = "sha256:3abbd2e30b36733fee78f9c7f7308f2d0050e88f0087fd25c2645f63c773e1c7", size = 4793, upload-time = "2025-03-19T20:09:59.721Z" } +sdist = { url = "https://files.pythonhosted.org/packages/72/34/14ca021ce8e5dfedc35312d08ba8bf51fdd999c576889fc2c24cb97f4f10/iniconfig-2.3.0.tar.gz", hash = "sha256:c76315c77db068650d49c5b56314774a7804df16fee4402c1f19d6d15d8c4730", size = 20503, upload-time = "2025-10-18T21:55:43.219Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/2c/e1/e6716421ea10d38022b952c159d5161ca1193197fb744506875fbb87ea7b/iniconfig-2.1.0-py3-none-any.whl", hash = "sha256:9deba5723312380e77435581c6bf4935c94cbfab9b1ed33ef8d238ea168eb760", size = 6050, upload-time = "2025-03-19T20:10:01.071Z" }, + { url = "https://files.pythonhosted.org/packages/cb/b1/3846dd7f199d53cb17f49cba7e651e9ce294d8497c8c150530ed11865bb8/iniconfig-2.3.0-py3-none-any.whl", hash = "sha256:f631c04d2c48c52b84d0d0549c99ff3859c98df65b3101406327ecc7d53fbf12", size = 7484, upload-time = "2025-10-18T21:55:41.639Z" }, ] [[package]] name = "ipython" -version = "9.5.0" +version = "9.9.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "colorama", marker = "sys_platform == 'win32'" }, @@ -505,11 +502,10 @@ dependencies = [ { name = "pygments" }, { name = "stack-data" }, { name = "traitlets" }, - { name = "typing-extensions", marker = "python_full_version < '3.12'" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/6e/71/a86262bf5a68bf211bcc71fe302af7e05f18a2852fdc610a854d20d085e6/ipython-9.5.0.tar.gz", hash = "sha256:129c44b941fe6d9b82d36fc7a7c18127ddb1d6f02f78f867f402e2e3adde3113", size = 4389137, upload-time = "2025-08-29T12:15:21.519Z" } +sdist = { url = "https://files.pythonhosted.org/packages/46/dd/fb08d22ec0c27e73c8bc8f71810709870d51cadaf27b7ddd3f011236c100/ipython-9.9.0.tar.gz", hash = "sha256:48fbed1b2de5e2c7177eefa144aba7fcb82dac514f09b57e2ac9da34ddb54220", size = 4425043, upload-time = "2026-01-05T12:36:46.233Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/08/2a/5628a99d04acb2d2f2e749cdf4ea571d2575e898df0528a090948018b726/ipython-9.5.0-py3-none-any.whl", hash = "sha256:88369ffa1d5817d609120daa523a6da06d02518e582347c29f8451732a9c5e72", size = 612426, upload-time = "2025-08-29T12:15:18.866Z" }, + { url = "https://files.pythonhosted.org/packages/86/92/162cfaee4ccf370465c5af1ce36a9eacec1becb552f2033bb3584e6f640a/ipython-9.9.0-py3-none-any.whl", hash = "sha256:b457fe9165df2b84e8ec909a97abcf2ed88f565970efba16b1f7229c283d252b", size = 621431, upload-time = "2026-01-05T12:36:44.669Z" }, ] [[package]] @@ -554,19 +550,6 @@ version = "1.4.9" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/5c/3c/85844f1b0feb11ee581ac23fe5fce65cd049a200c1446708cc1b7f922875/kiwisolver-1.4.9.tar.gz", hash = "sha256:c3b22c26c6fd6811b0ae8363b95ca8ce4ea3c202d3d0975b2914310ceb1bcc4d", size = 97564, upload-time = "2025-08-10T21:27:49.279Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/6f/ab/c80b0d5a9d8a1a65f4f815f2afff9798b12c3b9f31f1d304dd233dd920e2/kiwisolver-1.4.9-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:eb14a5da6dc7642b0f3a18f13654847cd8b7a2550e2645a5bda677862b03ba16", size = 124167, upload-time = "2025-08-10T21:25:53.403Z" }, - { url = "https://files.pythonhosted.org/packages/a0/c0/27fe1a68a39cf62472a300e2879ffc13c0538546c359b86f149cc19f6ac3/kiwisolver-1.4.9-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:39a219e1c81ae3b103643d2aedb90f1ef22650deb266ff12a19e7773f3e5f089", size = 66579, upload-time = "2025-08-10T21:25:54.79Z" }, - { url = "https://files.pythonhosted.org/packages/31/a2/a12a503ac1fd4943c50f9822678e8015a790a13b5490354c68afb8489814/kiwisolver-1.4.9-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:2405a7d98604b87f3fc28b1716783534b1b4b8510d8142adca34ee0bc3c87543", size = 65309, upload-time = "2025-08-10T21:25:55.76Z" }, - { url = "https://files.pythonhosted.org/packages/66/e1/e533435c0be77c3f64040d68d7a657771194a63c279f55573188161e81ca/kiwisolver-1.4.9-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:dc1ae486f9abcef254b5618dfb4113dd49f94c68e3e027d03cf0143f3f772b61", size = 1435596, upload-time = "2025-08-10T21:25:56.861Z" }, - { url = "https://files.pythonhosted.org/packages/67/1e/51b73c7347f9aabdc7215aa79e8b15299097dc2f8e67dee2b095faca9cb0/kiwisolver-1.4.9-cp311-cp311-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:8a1f570ce4d62d718dce3f179ee78dac3b545ac16c0c04bb363b7607a949c0d1", size = 1246548, upload-time = "2025-08-10T21:25:58.246Z" }, - { url = "https://files.pythonhosted.org/packages/21/aa/72a1c5d1e430294f2d32adb9542719cfb441b5da368d09d268c7757af46c/kiwisolver-1.4.9-cp311-cp311-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:cb27e7b78d716c591e88e0a09a2139c6577865d7f2e152488c2cc6257f460872", size = 1263618, upload-time = "2025-08-10T21:25:59.857Z" }, - { url = "https://files.pythonhosted.org/packages/a3/af/db1509a9e79dbf4c260ce0cfa3903ea8945f6240e9e59d1e4deb731b1a40/kiwisolver-1.4.9-cp311-cp311-manylinux_2_24_s390x.manylinux_2_28_s390x.whl", hash = "sha256:15163165efc2f627eb9687ea5f3a28137217d217ac4024893d753f46bce9de26", size = 1317437, upload-time = "2025-08-10T21:26:01.105Z" }, - { url = "https://files.pythonhosted.org/packages/e0/f2/3ea5ee5d52abacdd12013a94130436e19969fa183faa1e7c7fbc89e9a42f/kiwisolver-1.4.9-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:bdee92c56a71d2b24c33a7d4c2856bd6419d017e08caa7802d2963870e315028", size = 2195742, upload-time = "2025-08-10T21:26:02.675Z" }, - { url = "https://files.pythonhosted.org/packages/6f/9b/1efdd3013c2d9a2566aa6a337e9923a00590c516add9a1e89a768a3eb2fc/kiwisolver-1.4.9-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:412f287c55a6f54b0650bd9b6dce5aceddb95864a1a90c87af16979d37c89771", size = 2290810, upload-time = "2025-08-10T21:26:04.009Z" }, - { url = "https://files.pythonhosted.org/packages/fb/e5/cfdc36109ae4e67361f9bc5b41323648cb24a01b9ade18784657e022e65f/kiwisolver-1.4.9-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:2c93f00dcba2eea70af2be5f11a830a742fe6b579a1d4e00f47760ef13be247a", size = 2461579, upload-time = "2025-08-10T21:26:05.317Z" }, - { url = "https://files.pythonhosted.org/packages/62/86/b589e5e86c7610842213994cdea5add00960076bef4ae290c5fa68589cac/kiwisolver-1.4.9-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:f117e1a089d9411663a3207ba874f31be9ac8eaa5b533787024dc07aeb74f464", size = 2268071, upload-time = "2025-08-10T21:26:06.686Z" }, - { url = "https://files.pythonhosted.org/packages/3b/c6/f8df8509fd1eee6c622febe54384a96cfaf4d43bf2ccec7a0cc17e4715c9/kiwisolver-1.4.9-cp311-cp311-win_amd64.whl", hash = "sha256:be6a04e6c79819c9a8c2373317d19a96048e5a3f90bec587787e86a1153883c2", size = 73840, upload-time = "2025-08-10T21:26:07.94Z" }, - { url = "https://files.pythonhosted.org/packages/e2/2d/16e0581daafd147bc11ac53f032a2b45eabac897f42a338d0a13c1e5c436/kiwisolver-1.4.9-cp311-cp311-win_arm64.whl", hash = "sha256:0ae37737256ba2de764ddc12aed4956460277f00c4996d51a197e72f62f5eec7", size = 65159, upload-time = "2025-08-10T21:26:09.048Z" }, { url = "https://files.pythonhosted.org/packages/86/c9/13573a747838aeb1c76e3267620daa054f4152444d1f3d1a2324b78255b5/kiwisolver-1.4.9-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:ac5a486ac389dddcc5bef4f365b6ae3ffff2c433324fb38dd35e3fab7c957999", size = 123686, upload-time = "2025-08-10T21:26:10.034Z" }, { url = "https://files.pythonhosted.org/packages/51/ea/2ecf727927f103ffd1739271ca19c424d0e65ea473fbaeea1c014aea93f6/kiwisolver-1.4.9-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:f2ba92255faa7309d06fe44c3a4a97efe1c8d640c2a79a5ef728b685762a6fd2", size = 66460, upload-time = "2025-08-10T21:26:11.083Z" }, { url = "https://files.pythonhosted.org/packages/5b/5a/51f5464373ce2aeb5194508298a508b6f21d3867f499556263c64c621914/kiwisolver-1.4.9-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:4a2899935e724dd1074cb568ce7ac0dce28b2cd6ab539c8e001a8578eb106d14", size = 64952, upload-time = "2025-08-10T21:26:12.058Z" }, @@ -631,11 +614,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/99/dd/841e9a66c4715477ea0abc78da039832fbb09dac5c35c58dc4c41a407b8a/kiwisolver-1.4.9-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:aedff62918805fb62d43a4aa2ecd4482c380dc76cd31bd7c8878588a61bd0369", size = 2391835, upload-time = "2025-08-10T21:27:34.23Z" }, { url = "https://files.pythonhosted.org/packages/0c/28/4b2e5c47a0da96896fdfdb006340ade064afa1e63675d01ea5ac222b6d52/kiwisolver-1.4.9-cp314-cp314t-win_amd64.whl", hash = "sha256:1fa333e8b2ce4d9660f2cda9c0e1b6bafcfb2457a9d259faa82289e73ec24891", size = 79988, upload-time = "2025-08-10T21:27:35.587Z" }, { url = "https://files.pythonhosted.org/packages/80/be/3578e8afd18c88cdf9cb4cffde75a96d2be38c5a903f1ed0ceec061bd09e/kiwisolver-1.4.9-cp314-cp314t-win_arm64.whl", hash = "sha256:4a48a2ce79d65d363597ef7b567ce3d14d68783d2b2263d98db3d9477805ba32", size = 70260, upload-time = "2025-08-10T21:27:36.606Z" }, - { url = "https://files.pythonhosted.org/packages/a3/0f/36d89194b5a32c054ce93e586d4049b6c2c22887b0eb229c61c68afd3078/kiwisolver-1.4.9-pp311-pypy311_pp73-macosx_10_15_x86_64.whl", hash = "sha256:720e05574713db64c356e86732c0f3c5252818d05f9df320f0ad8380641acea5", size = 60104, upload-time = "2025-08-10T21:27:43.287Z" }, - { url = "https://files.pythonhosted.org/packages/52/ba/4ed75f59e4658fd21fe7dde1fee0ac397c678ec3befba3fe6482d987af87/kiwisolver-1.4.9-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:17680d737d5335b552994a2008fab4c851bcd7de33094a82067ef3a576ff02fa", size = 58592, upload-time = "2025-08-10T21:27:44.314Z" }, - { url = "https://files.pythonhosted.org/packages/33/01/a8ea7c5ea32a9b45ceeaee051a04c8ed4320f5add3c51bfa20879b765b70/kiwisolver-1.4.9-pp311-pypy311_pp73-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:85b5352f94e490c028926ea567fc569c52ec79ce131dadb968d3853e809518c2", size = 80281, upload-time = "2025-08-10T21:27:45.369Z" }, - { url = "https://files.pythonhosted.org/packages/da/e3/dbd2ecdce306f1d07a1aaf324817ee993aab7aee9db47ceac757deabafbe/kiwisolver-1.4.9-pp311-pypy311_pp73-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:464415881e4801295659462c49461a24fb107c140de781d55518c4b80cb6790f", size = 78009, upload-time = "2025-08-10T21:27:46.376Z" }, - { url = "https://files.pythonhosted.org/packages/da/e9/0d4add7873a73e462aeb45c036a2dead2562b825aa46ba326727b3f31016/kiwisolver-1.4.9-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:fb940820c63a9590d31d88b815e7a3aa5915cad3ce735ab45f0c730b39547de1", size = 73929, upload-time = "2025-08-10T21:27:48.236Z" }, ] [[package]] @@ -649,67 +627,82 @@ wheels = [ [[package]] name = "markdown-it-py" -version = "3.0.0" +version = "4.0.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "mdurl" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/38/71/3b932df36c1a044d397a1f92d1cf91ee0a503d91e470cbd670aa66b07ed0/markdown-it-py-3.0.0.tar.gz", hash = "sha256:e3f60a94fa066dc52ec76661e37c851cb232d92f9886b15cb560aaada2df8feb", size = 74596, upload-time = "2023-06-03T06:41:14.443Z" } +sdist = { url = "https://files.pythonhosted.org/packages/5b/f5/4ec618ed16cc4f8fb3b701563655a69816155e79e24a17b651541804721d/markdown_it_py-4.0.0.tar.gz", hash = "sha256:cb0a2b4aa34f932c007117b194e945bd74e0ec24133ceb5bac59009cda1cb9f3", size = 73070, upload-time = "2025-08-11T12:57:52.854Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/42/d7/1ec15b46af6af88f19b8e5ffea08fa375d433c998b8a7639e76935c14f1f/markdown_it_py-3.0.0-py3-none-any.whl", hash = "sha256:355216845c60bd96232cd8d8c40e8f9765cc86f46880e43a8fd22dc1a1a8cab1", size = 87528, upload-time = "2023-06-03T06:41:11.019Z" }, + { url = "https://files.pythonhosted.org/packages/94/54/e7d793b573f298e1c9013b8c4dade17d481164aa517d1d7148619c2cedbf/markdown_it_py-4.0.0-py3-none-any.whl", hash = "sha256:87327c59b172c5011896038353a81343b6754500a08cd7a4973bb48c6d578147", size = 87321, upload-time = "2025-08-11T12:57:51.923Z" }, ] [[package]] name = "markupsafe" -version = "3.0.2" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/b2/97/5d42485e71dfc078108a86d6de8fa46db44a1a9295e89c5d6d4a06e23a62/markupsafe-3.0.2.tar.gz", hash = "sha256:ee55d3edf80167e48ea11a923c7386f4669df67d7994554387f84e7d8b0a2bf0", size = 20537, upload-time = "2024-10-18T15:21:54.129Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/6b/28/bbf83e3f76936960b850435576dd5e67034e200469571be53f69174a2dfd/MarkupSafe-3.0.2-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:9025b4018f3a1314059769c7bf15441064b2207cb3f065e6ea1e7359cb46db9d", size = 14353, upload-time = "2024-10-18T15:21:02.187Z" }, - { url = "https://files.pythonhosted.org/packages/6c/30/316d194b093cde57d448a4c3209f22e3046c5bb2fb0820b118292b334be7/MarkupSafe-3.0.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:93335ca3812df2f366e80509ae119189886b0f3c2b81325d39efdb84a1e2ae93", size = 12392, upload-time = "2024-10-18T15:21:02.941Z" }, - { url = "https://files.pythonhosted.org/packages/f2/96/9cdafba8445d3a53cae530aaf83c38ec64c4d5427d975c974084af5bc5d2/MarkupSafe-3.0.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2cb8438c3cbb25e220c2ab33bb226559e7afb3baec11c4f218ffa7308603c832", size = 23984, upload-time = "2024-10-18T15:21:03.953Z" }, - { url = "https://files.pythonhosted.org/packages/f1/a4/aefb044a2cd8d7334c8a47d3fb2c9f328ac48cb349468cc31c20b539305f/MarkupSafe-3.0.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a123e330ef0853c6e822384873bef7507557d8e4a082961e1defa947aa59ba84", size = 23120, upload-time = "2024-10-18T15:21:06.495Z" }, - { url = "https://files.pythonhosted.org/packages/8d/21/5e4851379f88f3fad1de30361db501300d4f07bcad047d3cb0449fc51f8c/MarkupSafe-3.0.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1e084f686b92e5b83186b07e8a17fc09e38fff551f3602b249881fec658d3eca", size = 23032, upload-time = "2024-10-18T15:21:07.295Z" }, - { url = "https://files.pythonhosted.org/packages/00/7b/e92c64e079b2d0d7ddf69899c98842f3f9a60a1ae72657c89ce2655c999d/MarkupSafe-3.0.2-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:d8213e09c917a951de9d09ecee036d5c7d36cb6cb7dbaece4c71a60d79fb9798", size = 24057, upload-time = "2024-10-18T15:21:08.073Z" }, - { url = "https://files.pythonhosted.org/packages/f9/ac/46f960ca323037caa0a10662ef97d0a4728e890334fc156b9f9e52bcc4ca/MarkupSafe-3.0.2-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:5b02fb34468b6aaa40dfc198d813a641e3a63b98c2b05a16b9f80b7ec314185e", size = 23359, upload-time = "2024-10-18T15:21:09.318Z" }, - { url = "https://files.pythonhosted.org/packages/69/84/83439e16197337b8b14b6a5b9c2105fff81d42c2a7c5b58ac7b62ee2c3b1/MarkupSafe-3.0.2-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:0bff5e0ae4ef2e1ae4fdf2dfd5b76c75e5c2fa4132d05fc1b0dabcd20c7e28c4", size = 23306, upload-time = "2024-10-18T15:21:10.185Z" }, - { url = "https://files.pythonhosted.org/packages/9a/34/a15aa69f01e2181ed8d2b685c0d2f6655d5cca2c4db0ddea775e631918cd/MarkupSafe-3.0.2-cp311-cp311-win32.whl", hash = "sha256:6c89876f41da747c8d3677a2b540fb32ef5715f97b66eeb0c6b66f5e3ef6f59d", size = 15094, upload-time = "2024-10-18T15:21:11.005Z" }, - { url = "https://files.pythonhosted.org/packages/da/b8/3a3bd761922d416f3dc5d00bfbed11f66b1ab89a0c2b6e887240a30b0f6b/MarkupSafe-3.0.2-cp311-cp311-win_amd64.whl", hash = "sha256:70a87b411535ccad5ef2f1df5136506a10775d267e197e4cf531ced10537bd6b", size = 15521, upload-time = "2024-10-18T15:21:12.911Z" }, - { url = "https://files.pythonhosted.org/packages/22/09/d1f21434c97fc42f09d290cbb6350d44eb12f09cc62c9476effdb33a18aa/MarkupSafe-3.0.2-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:9778bd8ab0a994ebf6f84c2b949e65736d5575320a17ae8984a77fab08db94cf", size = 14274, upload-time = "2024-10-18T15:21:13.777Z" }, - { url = "https://files.pythonhosted.org/packages/6b/b0/18f76bba336fa5aecf79d45dcd6c806c280ec44538b3c13671d49099fdd0/MarkupSafe-3.0.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:846ade7b71e3536c4e56b386c2a47adf5741d2d8b94ec9dc3e92e5e1ee1e2225", size = 12348, upload-time = "2024-10-18T15:21:14.822Z" }, - { url = "https://files.pythonhosted.org/packages/e0/25/dd5c0f6ac1311e9b40f4af06c78efde0f3b5cbf02502f8ef9501294c425b/MarkupSafe-3.0.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1c99d261bd2d5f6b59325c92c73df481e05e57f19837bdca8413b9eac4bd8028", size = 24149, upload-time = "2024-10-18T15:21:15.642Z" }, - { url = "https://files.pythonhosted.org/packages/f3/f0/89e7aadfb3749d0f52234a0c8c7867877876e0a20b60e2188e9850794c17/MarkupSafe-3.0.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e17c96c14e19278594aa4841ec148115f9c7615a47382ecb6b82bd8fea3ab0c8", size = 23118, upload-time = "2024-10-18T15:21:17.133Z" }, - { url = "https://files.pythonhosted.org/packages/d5/da/f2eeb64c723f5e3777bc081da884b414671982008c47dcc1873d81f625b6/MarkupSafe-3.0.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:88416bd1e65dcea10bc7569faacb2c20ce071dd1f87539ca2ab364bf6231393c", size = 22993, upload-time = "2024-10-18T15:21:18.064Z" }, - { url = "https://files.pythonhosted.org/packages/da/0e/1f32af846df486dce7c227fe0f2398dc7e2e51d4a370508281f3c1c5cddc/MarkupSafe-3.0.2-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:2181e67807fc2fa785d0592dc2d6206c019b9502410671cc905d132a92866557", size = 24178, upload-time = "2024-10-18T15:21:18.859Z" }, - { url = "https://files.pythonhosted.org/packages/c4/f6/bb3ca0532de8086cbff5f06d137064c8410d10779c4c127e0e47d17c0b71/MarkupSafe-3.0.2-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:52305740fe773d09cffb16f8ed0427942901f00adedac82ec8b67752f58a1b22", size = 23319, upload-time = "2024-10-18T15:21:19.671Z" }, - { url = "https://files.pythonhosted.org/packages/a2/82/8be4c96ffee03c5b4a034e60a31294daf481e12c7c43ab8e34a1453ee48b/MarkupSafe-3.0.2-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:ad10d3ded218f1039f11a75f8091880239651b52e9bb592ca27de44eed242a48", size = 23352, upload-time = "2024-10-18T15:21:20.971Z" }, - { url = "https://files.pythonhosted.org/packages/51/ae/97827349d3fcffee7e184bdf7f41cd6b88d9919c80f0263ba7acd1bbcb18/MarkupSafe-3.0.2-cp312-cp312-win32.whl", hash = "sha256:0f4ca02bea9a23221c0182836703cbf8930c5e9454bacce27e767509fa286a30", size = 15097, upload-time = "2024-10-18T15:21:22.646Z" }, - { url = "https://files.pythonhosted.org/packages/c1/80/a61f99dc3a936413c3ee4e1eecac96c0da5ed07ad56fd975f1a9da5bc630/MarkupSafe-3.0.2-cp312-cp312-win_amd64.whl", hash = "sha256:8e06879fc22a25ca47312fbe7c8264eb0b662f6db27cb2d3bbbc74b1df4b9b87", size = 15601, upload-time = "2024-10-18T15:21:23.499Z" }, - { url = "https://files.pythonhosted.org/packages/83/0e/67eb10a7ecc77a0c2bbe2b0235765b98d164d81600746914bebada795e97/MarkupSafe-3.0.2-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:ba9527cdd4c926ed0760bc301f6728ef34d841f405abf9d4f959c478421e4efd", size = 14274, upload-time = "2024-10-18T15:21:24.577Z" }, - { url = "https://files.pythonhosted.org/packages/2b/6d/9409f3684d3335375d04e5f05744dfe7e9f120062c9857df4ab490a1031a/MarkupSafe-3.0.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:f8b3d067f2e40fe93e1ccdd6b2e1d16c43140e76f02fb1319a05cf2b79d99430", size = 12352, upload-time = "2024-10-18T15:21:25.382Z" }, - { url = "https://files.pythonhosted.org/packages/d2/f5/6eadfcd3885ea85fe2a7c128315cc1bb7241e1987443d78c8fe712d03091/MarkupSafe-3.0.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:569511d3b58c8791ab4c2e1285575265991e6d8f8700c7be0e88f86cb0672094", size = 24122, upload-time = "2024-10-18T15:21:26.199Z" }, - { url = "https://files.pythonhosted.org/packages/0c/91/96cf928db8236f1bfab6ce15ad070dfdd02ed88261c2afafd4b43575e9e9/MarkupSafe-3.0.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:15ab75ef81add55874e7ab7055e9c397312385bd9ced94920f2802310c930396", size = 23085, upload-time = "2024-10-18T15:21:27.029Z" }, - { url = "https://files.pythonhosted.org/packages/c2/cf/c9d56af24d56ea04daae7ac0940232d31d5a8354f2b457c6d856b2057d69/MarkupSafe-3.0.2-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f3818cb119498c0678015754eba762e0d61e5b52d34c8b13d770f0719f7b1d79", size = 22978, upload-time = "2024-10-18T15:21:27.846Z" }, - { url = "https://files.pythonhosted.org/packages/2a/9f/8619835cd6a711d6272d62abb78c033bda638fdc54c4e7f4272cf1c0962b/MarkupSafe-3.0.2-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:cdb82a876c47801bb54a690c5ae105a46b392ac6099881cdfb9f6e95e4014c6a", size = 24208, upload-time = "2024-10-18T15:21:28.744Z" }, - { url = "https://files.pythonhosted.org/packages/f9/bf/176950a1792b2cd2102b8ffeb5133e1ed984547b75db47c25a67d3359f77/MarkupSafe-3.0.2-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:cabc348d87e913db6ab4aa100f01b08f481097838bdddf7c7a84b7575b7309ca", size = 23357, upload-time = "2024-10-18T15:21:29.545Z" }, - { url = "https://files.pythonhosted.org/packages/ce/4f/9a02c1d335caabe5c4efb90e1b6e8ee944aa245c1aaaab8e8a618987d816/MarkupSafe-3.0.2-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:444dcda765c8a838eaae23112db52f1efaf750daddb2d9ca300bcae1039adc5c", size = 23344, upload-time = "2024-10-18T15:21:30.366Z" }, - { url = "https://files.pythonhosted.org/packages/ee/55/c271b57db36f748f0e04a759ace9f8f759ccf22b4960c270c78a394f58be/MarkupSafe-3.0.2-cp313-cp313-win32.whl", hash = "sha256:bcf3e58998965654fdaff38e58584d8937aa3096ab5354d493c77d1fdd66d7a1", size = 15101, upload-time = "2024-10-18T15:21:31.207Z" }, - { url = "https://files.pythonhosted.org/packages/29/88/07df22d2dd4df40aba9f3e402e6dc1b8ee86297dddbad4872bd5e7b0094f/MarkupSafe-3.0.2-cp313-cp313-win_amd64.whl", hash = "sha256:e6a2a455bd412959b57a172ce6328d2dd1f01cb2135efda2e4576e8a23fa3b0f", size = 15603, upload-time = "2024-10-18T15:21:32.032Z" }, - { url = "https://files.pythonhosted.org/packages/62/6a/8b89d24db2d32d433dffcd6a8779159da109842434f1dd2f6e71f32f738c/MarkupSafe-3.0.2-cp313-cp313t-macosx_10_13_universal2.whl", hash = "sha256:b5a6b3ada725cea8a5e634536b1b01c30bcdcd7f9c6fff4151548d5bf6b3a36c", size = 14510, upload-time = "2024-10-18T15:21:33.625Z" }, - { url = "https://files.pythonhosted.org/packages/7a/06/a10f955f70a2e5a9bf78d11a161029d278eeacbd35ef806c3fd17b13060d/MarkupSafe-3.0.2-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:a904af0a6162c73e3edcb969eeeb53a63ceeb5d8cf642fade7d39e7963a22ddb", size = 12486, upload-time = "2024-10-18T15:21:34.611Z" }, - { url = "https://files.pythonhosted.org/packages/34/cf/65d4a571869a1a9078198ca28f39fba5fbb910f952f9dbc5220afff9f5e6/MarkupSafe-3.0.2-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4aa4e5faecf353ed117801a068ebab7b7e09ffb6e1d5e412dc852e0da018126c", size = 25480, upload-time = "2024-10-18T15:21:35.398Z" }, - { url = "https://files.pythonhosted.org/packages/0c/e3/90e9651924c430b885468b56b3d597cabf6d72be4b24a0acd1fa0e12af67/MarkupSafe-3.0.2-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c0ef13eaeee5b615fb07c9a7dadb38eac06a0608b41570d8ade51c56539e509d", size = 23914, upload-time = "2024-10-18T15:21:36.231Z" }, - { url = "https://files.pythonhosted.org/packages/66/8c/6c7cf61f95d63bb866db39085150df1f2a5bd3335298f14a66b48e92659c/MarkupSafe-3.0.2-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d16a81a06776313e817c951135cf7340a3e91e8c1ff2fac444cfd75fffa04afe", size = 23796, upload-time = "2024-10-18T15:21:37.073Z" }, - { url = "https://files.pythonhosted.org/packages/bb/35/cbe9238ec3f47ac9a7c8b3df7a808e7cb50fe149dc7039f5f454b3fba218/MarkupSafe-3.0.2-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:6381026f158fdb7c72a168278597a5e3a5222e83ea18f543112b2662a9b699c5", size = 25473, upload-time = "2024-10-18T15:21:37.932Z" }, - { url = "https://files.pythonhosted.org/packages/e6/32/7621a4382488aa283cc05e8984a9c219abad3bca087be9ec77e89939ded9/MarkupSafe-3.0.2-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:3d79d162e7be8f996986c064d1c7c817f6df3a77fe3d6859f6f9e7be4b8c213a", size = 24114, upload-time = "2024-10-18T15:21:39.799Z" }, - { url = "https://files.pythonhosted.org/packages/0d/80/0985960e4b89922cb5a0bac0ed39c5b96cbc1a536a99f30e8c220a996ed9/MarkupSafe-3.0.2-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:131a3c7689c85f5ad20f9f6fb1b866f402c445b220c19fe4308c0b147ccd2ad9", size = 24098, upload-time = "2024-10-18T15:21:40.813Z" }, - { url = "https://files.pythonhosted.org/packages/82/78/fedb03c7d5380df2427038ec8d973587e90561b2d90cd472ce9254cf348b/MarkupSafe-3.0.2-cp313-cp313t-win32.whl", hash = "sha256:ba8062ed2cf21c07a9e295d5b8a2a5ce678b913b45fdf68c32d95d6c1291e0b6", size = 15208, upload-time = "2024-10-18T15:21:41.814Z" }, - { url = "https://files.pythonhosted.org/packages/4f/65/6079a46068dfceaeabb5dcad6d674f5f5c61a6fa5673746f42a9f4c233b3/MarkupSafe-3.0.2-cp313-cp313t-win_amd64.whl", hash = "sha256:e444a31f8db13eb18ada366ab3cf45fd4b31e4db1236a4448f68778c1d1a5a2f", size = 15739, upload-time = "2024-10-18T15:21:42.784Z" }, +version = "3.0.3" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/7e/99/7690b6d4034fffd95959cbe0c02de8deb3098cc577c67bb6a24fe5d7caa7/markupsafe-3.0.3.tar.gz", hash = "sha256:722695808f4b6457b320fdc131280796bdceb04ab50fe1795cd540799ebe1698", size = 80313, upload-time = "2025-09-27T18:37:40.426Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/5a/72/147da192e38635ada20e0a2e1a51cf8823d2119ce8883f7053879c2199b5/markupsafe-3.0.3-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:d53197da72cc091b024dd97249dfc7794d6a56530370992a5e1a08983ad9230e", size = 11615, upload-time = "2025-09-27T18:36:30.854Z" }, + { url = "https://files.pythonhosted.org/packages/9a/81/7e4e08678a1f98521201c3079f77db69fb552acd56067661f8c2f534a718/markupsafe-3.0.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:1872df69a4de6aead3491198eaf13810b565bdbeec3ae2dc8780f14458ec73ce", size = 12020, upload-time = "2025-09-27T18:36:31.971Z" }, + { url = "https://files.pythonhosted.org/packages/1e/2c/799f4742efc39633a1b54a92eec4082e4f815314869865d876824c257c1e/markupsafe-3.0.3-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:3a7e8ae81ae39e62a41ec302f972ba6ae23a5c5396c8e60113e9066ef893da0d", size = 24332, upload-time = "2025-09-27T18:36:32.813Z" }, + { url = "https://files.pythonhosted.org/packages/3c/2e/8d0c2ab90a8c1d9a24f0399058ab8519a3279d1bd4289511d74e909f060e/markupsafe-3.0.3-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:d6dd0be5b5b189d31db7cda48b91d7e0a9795f31430b7f271219ab30f1d3ac9d", size = 22947, upload-time = "2025-09-27T18:36:33.86Z" }, + { url = "https://files.pythonhosted.org/packages/2c/54/887f3092a85238093a0b2154bd629c89444f395618842e8b0c41783898ea/markupsafe-3.0.3-cp312-cp312-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:94c6f0bb423f739146aec64595853541634bde58b2135f27f61c1ffd1cd4d16a", size = 21962, upload-time = "2025-09-27T18:36:35.099Z" }, + { url = "https://files.pythonhosted.org/packages/c9/2f/336b8c7b6f4a4d95e91119dc8521402461b74a485558d8f238a68312f11c/markupsafe-3.0.3-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:be8813b57049a7dc738189df53d69395eba14fb99345e0a5994914a3864c8a4b", size = 23760, upload-time = "2025-09-27T18:36:36.001Z" }, + { url = "https://files.pythonhosted.org/packages/32/43/67935f2b7e4982ffb50a4d169b724d74b62a3964bc1a9a527f5ac4f1ee2b/markupsafe-3.0.3-cp312-cp312-musllinux_1_2_riscv64.whl", hash = "sha256:83891d0e9fb81a825d9a6d61e3f07550ca70a076484292a70fde82c4b807286f", size = 21529, upload-time = "2025-09-27T18:36:36.906Z" }, + { url = "https://files.pythonhosted.org/packages/89/e0/4486f11e51bbba8b0c041098859e869e304d1c261e59244baa3d295d47b7/markupsafe-3.0.3-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:77f0643abe7495da77fb436f50f8dab76dbc6e5fd25d39589a0f1fe6548bfa2b", size = 23015, upload-time = "2025-09-27T18:36:37.868Z" }, + { url = "https://files.pythonhosted.org/packages/2f/e1/78ee7a023dac597a5825441ebd17170785a9dab23de95d2c7508ade94e0e/markupsafe-3.0.3-cp312-cp312-win32.whl", hash = "sha256:d88b440e37a16e651bda4c7c2b930eb586fd15ca7406cb39e211fcff3bf3017d", size = 14540, upload-time = "2025-09-27T18:36:38.761Z" }, + { url = "https://files.pythonhosted.org/packages/aa/5b/bec5aa9bbbb2c946ca2733ef9c4ca91c91b6a24580193e891b5f7dbe8e1e/markupsafe-3.0.3-cp312-cp312-win_amd64.whl", hash = "sha256:26a5784ded40c9e318cfc2bdb30fe164bdb8665ded9cd64d500a34fb42067b1c", size = 15105, upload-time = "2025-09-27T18:36:39.701Z" }, + { url = "https://files.pythonhosted.org/packages/e5/f1/216fc1bbfd74011693a4fd837e7026152e89c4bcf3e77b6692fba9923123/markupsafe-3.0.3-cp312-cp312-win_arm64.whl", hash = "sha256:35add3b638a5d900e807944a078b51922212fb3dedb01633a8defc4b01a3c85f", size = 13906, upload-time = "2025-09-27T18:36:40.689Z" }, + { url = "https://files.pythonhosted.org/packages/38/2f/907b9c7bbba283e68f20259574b13d005c121a0fa4c175f9bed27c4597ff/markupsafe-3.0.3-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:e1cf1972137e83c5d4c136c43ced9ac51d0e124706ee1c8aa8532c1287fa8795", size = 11622, upload-time = "2025-09-27T18:36:41.777Z" }, + { url = "https://files.pythonhosted.org/packages/9c/d9/5f7756922cdd676869eca1c4e3c0cd0df60ed30199ffd775e319089cb3ed/markupsafe-3.0.3-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:116bb52f642a37c115f517494ea5feb03889e04df47eeff5b130b1808ce7c219", size = 12029, upload-time = "2025-09-27T18:36:43.257Z" }, + { url = "https://files.pythonhosted.org/packages/00/07/575a68c754943058c78f30db02ee03a64b3c638586fba6a6dd56830b30a3/markupsafe-3.0.3-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:133a43e73a802c5562be9bbcd03d090aa5a1fe899db609c29e8c8d815c5f6de6", size = 24374, upload-time = "2025-09-27T18:36:44.508Z" }, + { url = "https://files.pythonhosted.org/packages/a9/21/9b05698b46f218fc0e118e1f8168395c65c8a2c750ae2bab54fc4bd4e0e8/markupsafe-3.0.3-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:ccfcd093f13f0f0b7fdd0f198b90053bf7b2f02a3927a30e63f3ccc9df56b676", size = 22980, upload-time = "2025-09-27T18:36:45.385Z" }, + { url = "https://files.pythonhosted.org/packages/7f/71/544260864f893f18b6827315b988c146b559391e6e7e8f7252839b1b846a/markupsafe-3.0.3-cp313-cp313-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:509fa21c6deb7a7a273d629cf5ec029bc209d1a51178615ddf718f5918992ab9", size = 21990, upload-time = "2025-09-27T18:36:46.916Z" }, + { url = "https://files.pythonhosted.org/packages/c2/28/b50fc2f74d1ad761af2f5dcce7492648b983d00a65b8c0e0cb457c82ebbe/markupsafe-3.0.3-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:a4afe79fb3de0b7097d81da19090f4df4f8d3a2b3adaa8764138aac2e44f3af1", size = 23784, upload-time = "2025-09-27T18:36:47.884Z" }, + { url = "https://files.pythonhosted.org/packages/ed/76/104b2aa106a208da8b17a2fb72e033a5a9d7073c68f7e508b94916ed47a9/markupsafe-3.0.3-cp313-cp313-musllinux_1_2_riscv64.whl", hash = "sha256:795e7751525cae078558e679d646ae45574b47ed6e7771863fcc079a6171a0fc", size = 21588, upload-time = "2025-09-27T18:36:48.82Z" }, + { url = "https://files.pythonhosted.org/packages/b5/99/16a5eb2d140087ebd97180d95249b00a03aa87e29cc224056274f2e45fd6/markupsafe-3.0.3-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:8485f406a96febb5140bfeca44a73e3ce5116b2501ac54fe953e488fb1d03b12", size = 23041, upload-time = "2025-09-27T18:36:49.797Z" }, + { url = "https://files.pythonhosted.org/packages/19/bc/e7140ed90c5d61d77cea142eed9f9c303f4c4806f60a1044c13e3f1471d0/markupsafe-3.0.3-cp313-cp313-win32.whl", hash = "sha256:bdd37121970bfd8be76c5fb069c7751683bdf373db1ed6c010162b2a130248ed", size = 14543, upload-time = "2025-09-27T18:36:51.584Z" }, + { url = "https://files.pythonhosted.org/packages/05/73/c4abe620b841b6b791f2edc248f556900667a5a1cf023a6646967ae98335/markupsafe-3.0.3-cp313-cp313-win_amd64.whl", hash = "sha256:9a1abfdc021a164803f4d485104931fb8f8c1efd55bc6b748d2f5774e78b62c5", size = 15113, upload-time = "2025-09-27T18:36:52.537Z" }, + { url = "https://files.pythonhosted.org/packages/f0/3a/fa34a0f7cfef23cf9500d68cb7c32dd64ffd58a12b09225fb03dd37d5b80/markupsafe-3.0.3-cp313-cp313-win_arm64.whl", hash = "sha256:7e68f88e5b8799aa49c85cd116c932a1ac15caaa3f5db09087854d218359e485", size = 13911, upload-time = "2025-09-27T18:36:53.513Z" }, + { url = "https://files.pythonhosted.org/packages/e4/d7/e05cd7efe43a88a17a37b3ae96e79a19e846f3f456fe79c57ca61356ef01/markupsafe-3.0.3-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:218551f6df4868a8d527e3062d0fb968682fe92054e89978594c28e642c43a73", size = 11658, upload-time = "2025-09-27T18:36:54.819Z" }, + { url = "https://files.pythonhosted.org/packages/99/9e/e412117548182ce2148bdeacdda3bb494260c0b0184360fe0d56389b523b/markupsafe-3.0.3-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:3524b778fe5cfb3452a09d31e7b5adefeea8c5be1d43c4f810ba09f2ceb29d37", size = 12066, upload-time = "2025-09-27T18:36:55.714Z" }, + { url = "https://files.pythonhosted.org/packages/bc/e6/fa0ffcda717ef64a5108eaa7b4f5ed28d56122c9a6d70ab8b72f9f715c80/markupsafe-3.0.3-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:4e885a3d1efa2eadc93c894a21770e4bc67899e3543680313b09f139e149ab19", size = 25639, upload-time = "2025-09-27T18:36:56.908Z" }, + { url = "https://files.pythonhosted.org/packages/96/ec/2102e881fe9d25fc16cb4b25d5f5cde50970967ffa5dddafdb771237062d/markupsafe-3.0.3-cp313-cp313t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:8709b08f4a89aa7586de0aadc8da56180242ee0ada3999749b183aa23df95025", size = 23569, upload-time = "2025-09-27T18:36:57.913Z" }, + { url = "https://files.pythonhosted.org/packages/4b/30/6f2fce1f1f205fc9323255b216ca8a235b15860c34b6798f810f05828e32/markupsafe-3.0.3-cp313-cp313t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:b8512a91625c9b3da6f127803b166b629725e68af71f8184ae7e7d54686a56d6", size = 23284, upload-time = "2025-09-27T18:36:58.833Z" }, + { url = "https://files.pythonhosted.org/packages/58/47/4a0ccea4ab9f5dcb6f79c0236d954acb382202721e704223a8aafa38b5c8/markupsafe-3.0.3-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:9b79b7a16f7fedff2495d684f2b59b0457c3b493778c9eed31111be64d58279f", size = 24801, upload-time = "2025-09-27T18:36:59.739Z" }, + { url = "https://files.pythonhosted.org/packages/6a/70/3780e9b72180b6fecb83a4814d84c3bf4b4ae4bf0b19c27196104149734c/markupsafe-3.0.3-cp313-cp313t-musllinux_1_2_riscv64.whl", hash = "sha256:12c63dfb4a98206f045aa9563db46507995f7ef6d83b2f68eda65c307c6829eb", size = 22769, upload-time = "2025-09-27T18:37:00.719Z" }, + { url = "https://files.pythonhosted.org/packages/98/c5/c03c7f4125180fc215220c035beac6b9cb684bc7a067c84fc69414d315f5/markupsafe-3.0.3-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:8f71bc33915be5186016f675cd83a1e08523649b0e33efdb898db577ef5bb009", size = 23642, upload-time = "2025-09-27T18:37:01.673Z" }, + { url = "https://files.pythonhosted.org/packages/80/d6/2d1b89f6ca4bff1036499b1e29a1d02d282259f3681540e16563f27ebc23/markupsafe-3.0.3-cp313-cp313t-win32.whl", hash = "sha256:69c0b73548bc525c8cb9a251cddf1931d1db4d2258e9599c28c07ef3580ef354", size = 14612, upload-time = "2025-09-27T18:37:02.639Z" }, + { url = "https://files.pythonhosted.org/packages/2b/98/e48a4bfba0a0ffcf9925fe2d69240bfaa19c6f7507b8cd09c70684a53c1e/markupsafe-3.0.3-cp313-cp313t-win_amd64.whl", hash = "sha256:1b4b79e8ebf6b55351f0d91fe80f893b4743f104bff22e90697db1590e47a218", size = 15200, upload-time = "2025-09-27T18:37:03.582Z" }, + { url = "https://files.pythonhosted.org/packages/0e/72/e3cc540f351f316e9ed0f092757459afbc595824ca724cbc5a5d4263713f/markupsafe-3.0.3-cp313-cp313t-win_arm64.whl", hash = "sha256:ad2cf8aa28b8c020ab2fc8287b0f823d0a7d8630784c31e9ee5edea20f406287", size = 13973, upload-time = "2025-09-27T18:37:04.929Z" }, + { url = "https://files.pythonhosted.org/packages/33/8a/8e42d4838cd89b7dde187011e97fe6c3af66d8c044997d2183fbd6d31352/markupsafe-3.0.3-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:eaa9599de571d72e2daf60164784109f19978b327a3910d3e9de8c97b5b70cfe", size = 11619, upload-time = "2025-09-27T18:37:06.342Z" }, + { url = "https://files.pythonhosted.org/packages/b5/64/7660f8a4a8e53c924d0fa05dc3a55c9cee10bbd82b11c5afb27d44b096ce/markupsafe-3.0.3-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:c47a551199eb8eb2121d4f0f15ae0f923d31350ab9280078d1e5f12b249e0026", size = 12029, upload-time = "2025-09-27T18:37:07.213Z" }, + { url = "https://files.pythonhosted.org/packages/da/ef/e648bfd021127bef5fa12e1720ffed0c6cbb8310c8d9bea7266337ff06de/markupsafe-3.0.3-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:f34c41761022dd093b4b6896d4810782ffbabe30f2d443ff5f083e0cbbb8c737", size = 24408, upload-time = "2025-09-27T18:37:09.572Z" }, + { url = "https://files.pythonhosted.org/packages/41/3c/a36c2450754618e62008bf7435ccb0f88053e07592e6028a34776213d877/markupsafe-3.0.3-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:457a69a9577064c05a97c41f4e65148652db078a3a509039e64d3467b9e7ef97", size = 23005, upload-time = "2025-09-27T18:37:10.58Z" }, + { url = "https://files.pythonhosted.org/packages/bc/20/b7fdf89a8456b099837cd1dc21974632a02a999ec9bf7ca3e490aacd98e7/markupsafe-3.0.3-cp314-cp314-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:e8afc3f2ccfa24215f8cb28dcf43f0113ac3c37c2f0f0806d8c70e4228c5cf4d", size = 22048, upload-time = "2025-09-27T18:37:11.547Z" }, + { url = "https://files.pythonhosted.org/packages/9a/a7/591f592afdc734f47db08a75793a55d7fbcc6902a723ae4cfbab61010cc5/markupsafe-3.0.3-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:ec15a59cf5af7be74194f7ab02d0f59a62bdcf1a537677ce67a2537c9b87fcda", size = 23821, upload-time = "2025-09-27T18:37:12.48Z" }, + { url = "https://files.pythonhosted.org/packages/7d/33/45b24e4f44195b26521bc6f1a82197118f74df348556594bd2262bda1038/markupsafe-3.0.3-cp314-cp314-musllinux_1_2_riscv64.whl", hash = "sha256:0eb9ff8191e8498cca014656ae6b8d61f39da5f95b488805da4bb029cccbfbaf", size = 21606, upload-time = "2025-09-27T18:37:13.485Z" }, + { url = "https://files.pythonhosted.org/packages/ff/0e/53dfaca23a69fbfbbf17a4b64072090e70717344c52eaaaa9c5ddff1e5f0/markupsafe-3.0.3-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:2713baf880df847f2bece4230d4d094280f4e67b1e813eec43b4c0e144a34ffe", size = 23043, upload-time = "2025-09-27T18:37:14.408Z" }, + { url = "https://files.pythonhosted.org/packages/46/11/f333a06fc16236d5238bfe74daccbca41459dcd8d1fa952e8fbd5dccfb70/markupsafe-3.0.3-cp314-cp314-win32.whl", hash = "sha256:729586769a26dbceff69f7a7dbbf59ab6572b99d94576a5592625d5b411576b9", size = 14747, upload-time = "2025-09-27T18:37:15.36Z" }, + { url = "https://files.pythonhosted.org/packages/28/52/182836104b33b444e400b14f797212f720cbc9ed6ba34c800639d154e821/markupsafe-3.0.3-cp314-cp314-win_amd64.whl", hash = "sha256:bdc919ead48f234740ad807933cdf545180bfbe9342c2bb451556db2ed958581", size = 15341, upload-time = "2025-09-27T18:37:16.496Z" }, + { url = "https://files.pythonhosted.org/packages/6f/18/acf23e91bd94fd7b3031558b1f013adfa21a8e407a3fdb32745538730382/markupsafe-3.0.3-cp314-cp314-win_arm64.whl", hash = "sha256:5a7d5dc5140555cf21a6fefbdbf8723f06fcd2f63ef108f2854de715e4422cb4", size = 14073, upload-time = "2025-09-27T18:37:17.476Z" }, + { url = "https://files.pythonhosted.org/packages/3c/f0/57689aa4076e1b43b15fdfa646b04653969d50cf30c32a102762be2485da/markupsafe-3.0.3-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:1353ef0c1b138e1907ae78e2f6c63ff67501122006b0f9abad68fda5f4ffc6ab", size = 11661, upload-time = "2025-09-27T18:37:18.453Z" }, + { url = "https://files.pythonhosted.org/packages/89/c3/2e67a7ca217c6912985ec766c6393b636fb0c2344443ff9d91404dc4c79f/markupsafe-3.0.3-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:1085e7fbddd3be5f89cc898938f42c0b3c711fdcb37d75221de2666af647c175", size = 12069, upload-time = "2025-09-27T18:37:19.332Z" }, + { url = "https://files.pythonhosted.org/packages/f0/00/be561dce4e6ca66b15276e184ce4b8aec61fe83662cce2f7d72bd3249d28/markupsafe-3.0.3-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:1b52b4fb9df4eb9ae465f8d0c228a00624de2334f216f178a995ccdcf82c4634", size = 25670, upload-time = "2025-09-27T18:37:20.245Z" }, + { url = "https://files.pythonhosted.org/packages/50/09/c419f6f5a92e5fadde27efd190eca90f05e1261b10dbd8cbcb39cd8ea1dc/markupsafe-3.0.3-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:fed51ac40f757d41b7c48425901843666a6677e3e8eb0abcff09e4ba6e664f50", size = 23598, upload-time = "2025-09-27T18:37:21.177Z" }, + { url = "https://files.pythonhosted.org/packages/22/44/a0681611106e0b2921b3033fc19bc53323e0b50bc70cffdd19f7d679bb66/markupsafe-3.0.3-cp314-cp314t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:f190daf01f13c72eac4efd5c430a8de82489d9cff23c364c3ea822545032993e", size = 23261, upload-time = "2025-09-27T18:37:22.167Z" }, + { url = "https://files.pythonhosted.org/packages/5f/57/1b0b3f100259dc9fffe780cfb60d4be71375510e435efec3d116b6436d43/markupsafe-3.0.3-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:e56b7d45a839a697b5eb268c82a71bd8c7f6c94d6fd50c3d577fa39a9f1409f5", size = 24835, upload-time = "2025-09-27T18:37:23.296Z" }, + { url = "https://files.pythonhosted.org/packages/26/6a/4bf6d0c97c4920f1597cc14dd720705eca0bf7c787aebc6bb4d1bead5388/markupsafe-3.0.3-cp314-cp314t-musllinux_1_2_riscv64.whl", hash = "sha256:f3e98bb3798ead92273dc0e5fd0f31ade220f59a266ffd8a4f6065e0a3ce0523", size = 22733, upload-time = "2025-09-27T18:37:24.237Z" }, + { url = "https://files.pythonhosted.org/packages/14/c7/ca723101509b518797fedc2fdf79ba57f886b4aca8a7d31857ba3ee8281f/markupsafe-3.0.3-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:5678211cb9333a6468fb8d8be0305520aa073f50d17f089b5b4b477ea6e67fdc", size = 23672, upload-time = "2025-09-27T18:37:25.271Z" }, + { url = "https://files.pythonhosted.org/packages/fb/df/5bd7a48c256faecd1d36edc13133e51397e41b73bb77e1a69deab746ebac/markupsafe-3.0.3-cp314-cp314t-win32.whl", hash = "sha256:915c04ba3851909ce68ccc2b8e2cd691618c4dc4c4232fb7982bca3f41fd8c3d", size = 14819, upload-time = "2025-09-27T18:37:26.285Z" }, + { url = "https://files.pythonhosted.org/packages/1a/8a/0402ba61a2f16038b48b39bccca271134be00c5c9f0f623208399333c448/markupsafe-3.0.3-cp314-cp314t-win_amd64.whl", hash = "sha256:4faffd047e07c38848ce017e8725090413cd80cbc23d86e55c587bf979e579c9", size = 15426, upload-time = "2025-09-27T18:37:27.316Z" }, + { url = "https://files.pythonhosted.org/packages/70/bc/6f1c2f612465f5fa89b95bead1f44dcb607670fd42891d8fdcd5d039f4f4/markupsafe-3.0.3-cp314-cp314t-win_arm64.whl", hash = "sha256:32001d6a8fc98c8cb5c947787c5d08b0a50663d139f1305bac5885d98d9b40fa", size = 14146, upload-time = "2025-09-27T18:37:28.327Z" }, ] [[package]] name = "matplotlib" -version = "3.10.6" +version = "3.10.8" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "contourpy" }, @@ -722,65 +715,55 @@ dependencies = [ { name = "pyparsing" }, { name = "python-dateutil" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/a0/59/c3e6453a9676ffba145309a73c462bb407f4400de7de3f2b41af70720a3c/matplotlib-3.10.6.tar.gz", hash = "sha256:ec01b645840dd1996df21ee37f208cd8ba57644779fa20464010638013d3203c", size = 34804264, upload-time = "2025-08-30T00:14:25.137Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/80/d6/5d3665aa44c49005aaacaa68ddea6fcb27345961cd538a98bb0177934ede/matplotlib-3.10.6-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:905b60d1cb0ee604ce65b297b61cf8be9f4e6cfecf95a3fe1c388b5266bc8f4f", size = 8257527, upload-time = "2025-08-30T00:12:45.31Z" }, - { url = "https://files.pythonhosted.org/packages/8c/af/30ddefe19ca67eebd70047dabf50f899eaff6f3c5e6a1a7edaecaf63f794/matplotlib-3.10.6-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:7bac38d816637343e53d7185d0c66677ff30ffb131044a81898b5792c956ba76", size = 8119583, upload-time = "2025-08-30T00:12:47.236Z" }, - { url = "https://files.pythonhosted.org/packages/d3/29/4a8650a3dcae97fa4f375d46efcb25920d67b512186f8a6788b896062a81/matplotlib-3.10.6-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:942a8de2b5bfff1de31d95722f702e2966b8a7e31f4e68f7cd963c7cd8861cf6", size = 8692682, upload-time = "2025-08-30T00:12:48.781Z" }, - { url = "https://files.pythonhosted.org/packages/aa/d3/b793b9cb061cfd5d42ff0f69d1822f8d5dbc94e004618e48a97a8373179a/matplotlib-3.10.6-cp311-cp311-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:a3276c85370bc0dfca051ec65c5817d1e0f8f5ce1b7787528ec8ed2d524bbc2f", size = 9521065, upload-time = "2025-08-30T00:12:50.602Z" }, - { url = "https://files.pythonhosted.org/packages/f7/c5/53de5629f223c1c66668d46ac2621961970d21916a4bc3862b174eb2a88f/matplotlib-3.10.6-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:9df5851b219225731f564e4b9e7f2ac1e13c9e6481f941b5631a0f8e2d9387ce", size = 9576888, upload-time = "2025-08-30T00:12:52.92Z" }, - { url = "https://files.pythonhosted.org/packages/fc/8e/0a18d6d7d2d0a2e66585032a760d13662e5250c784d53ad50434e9560991/matplotlib-3.10.6-cp311-cp311-win_amd64.whl", hash = "sha256:abb5d9478625dd9c9eb51a06d39aae71eda749ae9b3138afb23eb38824026c7e", size = 8115158, upload-time = "2025-08-30T00:12:54.863Z" }, - { url = "https://files.pythonhosted.org/packages/07/b3/1a5107bb66c261e23b9338070702597a2d374e5aa7004b7adfc754fbed02/matplotlib-3.10.6-cp311-cp311-win_arm64.whl", hash = "sha256:886f989ccfae63659183173bb3fced7fd65e9eb793c3cc21c273add368536951", size = 7992444, upload-time = "2025-08-30T00:12:57.067Z" }, - { url = "https://files.pythonhosted.org/packages/ea/1a/7042f7430055d567cc3257ac409fcf608599ab27459457f13772c2d9778b/matplotlib-3.10.6-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:31ca662df6a80bd426f871105fdd69db7543e28e73a9f2afe80de7e531eb2347", size = 8272404, upload-time = "2025-08-30T00:12:59.112Z" }, - { url = "https://files.pythonhosted.org/packages/a9/5d/1d5f33f5b43f4f9e69e6a5fe1fb9090936ae7bc8e2ff6158e7a76542633b/matplotlib-3.10.6-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:1678bb61d897bb4ac4757b5ecfb02bfb3fddf7f808000fb81e09c510712fda75", size = 8128262, upload-time = "2025-08-30T00:13:01.141Z" }, - { url = "https://files.pythonhosted.org/packages/67/c3/135fdbbbf84e0979712df58e5e22b4f257b3f5e52a3c4aacf1b8abec0d09/matplotlib-3.10.6-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:56cd2d20842f58c03d2d6e6c1f1cf5548ad6f66b91e1e48f814e4fb5abd1cb95", size = 8697008, upload-time = "2025-08-30T00:13:03.24Z" }, - { url = "https://files.pythonhosted.org/packages/9c/be/c443ea428fb2488a3ea7608714b1bd85a82738c45da21b447dc49e2f8e5d/matplotlib-3.10.6-cp312-cp312-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:662df55604a2f9a45435566d6e2660e41efe83cd94f4288dfbf1e6d1eae4b0bb", size = 9530166, upload-time = "2025-08-30T00:13:05.951Z" }, - { url = "https://files.pythonhosted.org/packages/a9/35/48441422b044d74034aea2a3e0d1a49023f12150ebc58f16600132b9bbaf/matplotlib-3.10.6-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:08f141d55148cd1fc870c3387d70ca4df16dee10e909b3b038782bd4bda6ea07", size = 9593105, upload-time = "2025-08-30T00:13:08.356Z" }, - { url = "https://files.pythonhosted.org/packages/45/c3/994ef20eb4154ab84cc08d033834555319e4af970165e6c8894050af0b3c/matplotlib-3.10.6-cp312-cp312-win_amd64.whl", hash = "sha256:590f5925c2d650b5c9d813c5b3b5fc53f2929c3f8ef463e4ecfa7e052044fb2b", size = 8122784, upload-time = "2025-08-30T00:13:10.367Z" }, - { url = "https://files.pythonhosted.org/packages/57/b8/5c85d9ae0e40f04e71bedb053aada5d6bab1f9b5399a0937afb5d6b02d98/matplotlib-3.10.6-cp312-cp312-win_arm64.whl", hash = "sha256:f44c8d264a71609c79a78d50349e724f5d5fc3684ead7c2a473665ee63d868aa", size = 7992823, upload-time = "2025-08-30T00:13:12.24Z" }, - { url = "https://files.pythonhosted.org/packages/a0/db/18380e788bb837e724358287b08e223b32bc8dccb3b0c12fa8ca20bc7f3b/matplotlib-3.10.6-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:819e409653c1106c8deaf62e6de6b8611449c2cd9939acb0d7d4e57a3d95cc7a", size = 8273231, upload-time = "2025-08-30T00:13:13.881Z" }, - { url = "https://files.pythonhosted.org/packages/d3/0f/38dd49445b297e0d4f12a322c30779df0d43cb5873c7847df8a82e82ec67/matplotlib-3.10.6-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:59c8ac8382fefb9cb71308dde16a7c487432f5255d8f1fd32473523abecfecdf", size = 8128730, upload-time = "2025-08-30T00:13:15.556Z" }, - { url = "https://files.pythonhosted.org/packages/e5/b8/9eea6630198cb303d131d95d285a024b3b8645b1763a2916fddb44ca8760/matplotlib-3.10.6-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:84e82d9e0fd70c70bc55739defbd8055c54300750cbacf4740c9673a24d6933a", size = 8698539, upload-time = "2025-08-30T00:13:17.297Z" }, - { url = "https://files.pythonhosted.org/packages/71/34/44c7b1f075e1ea398f88aeabcc2907c01b9cc99e2afd560c1d49845a1227/matplotlib-3.10.6-cp313-cp313-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:25f7a3eb42d6c1c56e89eacd495661fc815ffc08d9da750bca766771c0fd9110", size = 9529702, upload-time = "2025-08-30T00:13:19.248Z" }, - { url = "https://files.pythonhosted.org/packages/b5/7f/e5c2dc9950c7facaf8b461858d1b92c09dd0cf174fe14e21953b3dda06f7/matplotlib-3.10.6-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:f9c862d91ec0b7842920a4cfdaaec29662195301914ea54c33e01f1a28d014b2", size = 9593742, upload-time = "2025-08-30T00:13:21.181Z" }, - { url = "https://files.pythonhosted.org/packages/ff/1d/70c28528794f6410ee2856cd729fa1f1756498b8d3126443b0a94e1a8695/matplotlib-3.10.6-cp313-cp313-win_amd64.whl", hash = "sha256:1b53bd6337eba483e2e7d29c5ab10eee644bc3a2491ec67cc55f7b44583ffb18", size = 8122753, upload-time = "2025-08-30T00:13:23.44Z" }, - { url = "https://files.pythonhosted.org/packages/e8/74/0e1670501fc7d02d981564caf7c4df42974464625935424ca9654040077c/matplotlib-3.10.6-cp313-cp313-win_arm64.whl", hash = "sha256:cbd5eb50b7058b2892ce45c2f4e92557f395c9991f5c886d1bb74a1582e70fd6", size = 7992973, upload-time = "2025-08-30T00:13:26.632Z" }, - { url = "https://files.pythonhosted.org/packages/b1/4e/60780e631d73b6b02bd7239f89c451a72970e5e7ec34f621eda55cd9a445/matplotlib-3.10.6-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:acc86dd6e0e695c095001a7fccff158c49e45e0758fdf5dcdbb0103318b59c9f", size = 8316869, upload-time = "2025-08-30T00:13:28.262Z" }, - { url = "https://files.pythonhosted.org/packages/f8/15/baa662374a579413210fc2115d40c503b7360a08e9cc254aa0d97d34b0c1/matplotlib-3.10.6-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:e228cd2ffb8f88b7d0b29e37f68ca9aaf83e33821f24a5ccc4f082dd8396bc27", size = 8178240, upload-time = "2025-08-30T00:13:30.007Z" }, - { url = "https://files.pythonhosted.org/packages/c6/3f/3c38e78d2aafdb8829fcd0857d25aaf9e7dd2dfcf7ec742765b585774931/matplotlib-3.10.6-cp313-cp313t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:658bc91894adeab669cf4bb4a186d049948262987e80f0857216387d7435d833", size = 8711719, upload-time = "2025-08-30T00:13:31.72Z" }, - { url = "https://files.pythonhosted.org/packages/96/4b/2ec2bbf8cefaa53207cc56118d1fa8a0f9b80642713ea9390235d331ede4/matplotlib-3.10.6-cp313-cp313t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:8913b7474f6dd83ac444c9459c91f7f0f2859e839f41d642691b104e0af056aa", size = 9541422, upload-time = "2025-08-30T00:13:33.611Z" }, - { url = "https://files.pythonhosted.org/packages/83/7d/40255e89b3ef11c7871020563b2dd85f6cb1b4eff17c0f62b6eb14c8fa80/matplotlib-3.10.6-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:091cea22e059b89f6d7d1a18e2c33a7376c26eee60e401d92a4d6726c4e12706", size = 9594068, upload-time = "2025-08-30T00:13:35.833Z" }, - { url = "https://files.pythonhosted.org/packages/f0/a9/0213748d69dc842537a113493e1c27daf9f96bd7cc316f933dc8ec4de985/matplotlib-3.10.6-cp313-cp313t-win_amd64.whl", hash = "sha256:491e25e02a23d7207629d942c666924a6b61e007a48177fdd231a0097b7f507e", size = 8200100, upload-time = "2025-08-30T00:13:37.668Z" }, - { url = "https://files.pythonhosted.org/packages/be/15/79f9988066ce40b8a6f1759a934ea0cde8dc4adc2262255ee1bc98de6ad0/matplotlib-3.10.6-cp313-cp313t-win_arm64.whl", hash = "sha256:3d80d60d4e54cda462e2cd9a086d85cd9f20943ead92f575ce86885a43a565d5", size = 8042142, upload-time = "2025-08-30T00:13:39.426Z" }, - { url = "https://files.pythonhosted.org/packages/7c/58/e7b6d292beae6fb4283ca6fb7fa47d7c944a68062d6238c07b497dd35493/matplotlib-3.10.6-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:70aaf890ce1d0efd482df969b28a5b30ea0b891224bb315810a3940f67182899", size = 8273802, upload-time = "2025-08-30T00:13:41.006Z" }, - { url = "https://files.pythonhosted.org/packages/9f/f6/7882d05aba16a8cdd594fb9a03a9d3cca751dbb6816adf7b102945522ee9/matplotlib-3.10.6-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:1565aae810ab79cb72e402b22facfa6501365e73ebab70a0fdfb98488d2c3c0c", size = 8131365, upload-time = "2025-08-30T00:13:42.664Z" }, - { url = "https://files.pythonhosted.org/packages/94/bf/ff32f6ed76e78514e98775a53715eca4804b12bdcf35902cdd1cf759d324/matplotlib-3.10.6-cp314-cp314-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:f3b23315a01981689aa4e1a179dbf6ef9fbd17143c3eea77548c2ecfb0499438", size = 9533961, upload-time = "2025-08-30T00:13:44.372Z" }, - { url = "https://files.pythonhosted.org/packages/fe/c3/6bf88c2fc2da7708a2ff8d2eeb5d68943130f50e636d5d3dcf9d4252e971/matplotlib-3.10.6-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:30fdd37edf41a4e6785f9b37969de57aea770696cb637d9946eb37470c94a453", size = 9804262, upload-time = "2025-08-30T00:13:46.614Z" }, - { url = "https://files.pythonhosted.org/packages/0f/7a/e05e6d9446d2d577b459427ad060cd2de5742d0e435db3191fea4fcc7e8b/matplotlib-3.10.6-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:bc31e693da1c08012c764b053e702c1855378e04102238e6a5ee6a7117c53a47", size = 9595508, upload-time = "2025-08-30T00:13:48.731Z" }, - { url = "https://files.pythonhosted.org/packages/39/fb/af09c463ced80b801629fd73b96f726c9f6124c3603aa2e480a061d6705b/matplotlib-3.10.6-cp314-cp314-win_amd64.whl", hash = "sha256:05be9bdaa8b242bc6ff96330d18c52f1fc59c6fb3a4dd411d953d67e7e1baf98", size = 8252742, upload-time = "2025-08-30T00:13:50.539Z" }, - { url = "https://files.pythonhosted.org/packages/b1/f9/b682f6db9396d9ab8f050c0a3bfbb5f14fb0f6518f08507c04cc02f8f229/matplotlib-3.10.6-cp314-cp314-win_arm64.whl", hash = "sha256:f56a0d1ab05d34c628592435781d185cd99630bdfd76822cd686fb5a0aecd43a", size = 8124237, upload-time = "2025-08-30T00:13:54.3Z" }, - { url = "https://files.pythonhosted.org/packages/b5/d2/b69b4a0923a3c05ab90527c60fdec899ee21ca23ede7f0fb818e6620d6f2/matplotlib-3.10.6-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:94f0b4cacb23763b64b5dace50d5b7bfe98710fed5f0cef5c08135a03399d98b", size = 8316956, upload-time = "2025-08-30T00:13:55.932Z" }, - { url = "https://files.pythonhosted.org/packages/28/e9/dc427b6f16457ffaeecb2fc4abf91e5adb8827861b869c7a7a6d1836fa73/matplotlib-3.10.6-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:cc332891306b9fb39462673d8225d1b824c89783fee82840a709f96714f17a5c", size = 8178260, upload-time = "2025-08-30T00:14:00.942Z" }, - { url = "https://files.pythonhosted.org/packages/c4/89/1fbd5ad611802c34d1c7ad04607e64a1350b7fb9c567c4ec2c19e066ed35/matplotlib-3.10.6-cp314-cp314t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ee1d607b3fb1590deb04b69f02ea1d53ed0b0bf75b2b1a5745f269afcbd3cdd3", size = 9541422, upload-time = "2025-08-30T00:14:02.664Z" }, - { url = "https://files.pythonhosted.org/packages/b0/3b/65fec8716025b22c1d72d5a82ea079934c76a547696eaa55be6866bc89b1/matplotlib-3.10.6-cp314-cp314t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:376a624a218116461696b27b2bbf7a8945053e6d799f6502fc03226d077807bf", size = 9803678, upload-time = "2025-08-30T00:14:04.741Z" }, - { url = "https://files.pythonhosted.org/packages/c7/b0/40fb2b3a1ab9381bb39a952e8390357c8be3bdadcf6d5055d9c31e1b35ae/matplotlib-3.10.6-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:83847b47f6524c34b4f2d3ce726bb0541c48c8e7692729865c3df75bfa0f495a", size = 9594077, upload-time = "2025-08-30T00:14:07.012Z" }, - { url = "https://files.pythonhosted.org/packages/76/34/c4b71b69edf5b06e635eee1ed10bfc73cf8df058b66e63e30e6a55e231d5/matplotlib-3.10.6-cp314-cp314t-win_amd64.whl", hash = "sha256:c7e0518e0d223683532a07f4b512e2e0729b62674f1b3a1a69869f98e6b1c7e3", size = 8342822, upload-time = "2025-08-30T00:14:09.041Z" }, - { url = "https://files.pythonhosted.org/packages/e8/62/aeabeef1a842b6226a30d49dd13e8a7a1e81e9ec98212c0b5169f0a12d83/matplotlib-3.10.6-cp314-cp314t-win_arm64.whl", hash = "sha256:4dd83e029f5b4801eeb87c64efd80e732452781c16a9cf7415b7b63ec8f374d7", size = 8172588, upload-time = "2025-08-30T00:14:11.166Z" }, - { url = "https://files.pythonhosted.org/packages/12/bb/02c35a51484aae5f49bd29f091286e7af5f3f677a9736c58a92b3c78baeb/matplotlib-3.10.6-pp311-pypy311_pp73-macosx_10_15_x86_64.whl", hash = "sha256:f2d684c3204fa62421bbf770ddfebc6b50130f9cad65531eeba19236d73bb488", size = 8252296, upload-time = "2025-08-30T00:14:19.49Z" }, - { url = "https://files.pythonhosted.org/packages/7d/85/41701e3092005aee9a2445f5ee3904d9dbd4a7df7a45905ffef29b7ef098/matplotlib-3.10.6-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:6f4a69196e663a41d12a728fab8751177215357906436804217d6d9cf0d4d6cf", size = 8116749, upload-time = "2025-08-30T00:14:21.344Z" }, - { url = "https://files.pythonhosted.org/packages/16/53/8d8fa0ea32a8c8239e04d022f6c059ee5e1b77517769feccd50f1df43d6d/matplotlib-3.10.6-pp311-pypy311_pp73-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:4d6ca6ef03dfd269f4ead566ec6f3fb9becf8dab146fb999022ed85ee9f6b3eb", size = 8693933, upload-time = "2025-08-30T00:14:22.942Z" }, +sdist = { url = "https://files.pythonhosted.org/packages/8a/76/d3c6e3a13fe484ebe7718d14e269c9569c4eb0020a968a327acb3b9a8fe6/matplotlib-3.10.8.tar.gz", hash = "sha256:2299372c19d56bcd35cf05a2738308758d32b9eaed2371898d8f5bd33f084aa3", size = 34806269, upload-time = "2025-12-10T22:56:51.155Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/9e/67/f997cdcbb514012eb0d10cd2b4b332667997fb5ebe26b8d41d04962fa0e6/matplotlib-3.10.8-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:64fcc24778ca0404ce0cb7b6b77ae1f4c7231cdd60e6778f999ee05cbd581b9a", size = 8260453, upload-time = "2025-12-10T22:55:30.709Z" }, + { url = "https://files.pythonhosted.org/packages/7e/65/07d5f5c7f7c994f12c768708bd2e17a4f01a2b0f44a1c9eccad872433e2e/matplotlib-3.10.8-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:b9a5ca4ac220a0cdd1ba6bcba3608547117d30468fefce49bb26f55c1a3d5c58", size = 8148321, upload-time = "2025-12-10T22:55:33.265Z" }, + { url = "https://files.pythonhosted.org/packages/3e/f3/c5195b1ae57ef85339fd7285dfb603b22c8b4e79114bae5f4f0fcf688677/matplotlib-3.10.8-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:3ab4aabc72de4ff77b3ec33a6d78a68227bf1123465887f9905ba79184a1cc04", size = 8716944, upload-time = "2025-12-10T22:55:34.922Z" }, + { url = "https://files.pythonhosted.org/packages/00/f9/7638f5cc82ec8a7aa005de48622eecc3ed7c9854b96ba15bd76b7fd27574/matplotlib-3.10.8-cp312-cp312-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:24d50994d8c5816ddc35411e50a86ab05f575e2530c02752e02538122613371f", size = 9550099, upload-time = "2025-12-10T22:55:36.789Z" }, + { url = "https://files.pythonhosted.org/packages/57/61/78cd5920d35b29fd2a0fe894de8adf672ff52939d2e9b43cb83cd5ce1bc7/matplotlib-3.10.8-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:99eefd13c0dc3b3c1b4d561c1169e65fe47aab7b8158754d7c084088e2329466", size = 9613040, upload-time = "2025-12-10T22:55:38.715Z" }, + { url = "https://files.pythonhosted.org/packages/30/4e/c10f171b6e2f44d9e3a2b96efa38b1677439d79c99357600a62cc1e9594e/matplotlib-3.10.8-cp312-cp312-win_amd64.whl", hash = "sha256:dd80ecb295460a5d9d260df63c43f4afbdd832d725a531f008dad1664f458adf", size = 8142717, upload-time = "2025-12-10T22:55:41.103Z" }, + { url = "https://files.pythonhosted.org/packages/f1/76/934db220026b5fef85f45d51a738b91dea7d70207581063cd9bd8fafcf74/matplotlib-3.10.8-cp312-cp312-win_arm64.whl", hash = "sha256:3c624e43ed56313651bc18a47f838b60d7b8032ed348911c54906b130b20071b", size = 8012751, upload-time = "2025-12-10T22:55:42.684Z" }, + { url = "https://files.pythonhosted.org/packages/3d/b9/15fd5541ef4f5b9a17eefd379356cf12175fe577424e7b1d80676516031a/matplotlib-3.10.8-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:3f2e409836d7f5ac2f1c013110a4d50b9f7edc26328c108915f9075d7d7a91b6", size = 8261076, upload-time = "2025-12-10T22:55:44.648Z" }, + { url = "https://files.pythonhosted.org/packages/8d/a0/2ba3473c1b66b9c74dc7107c67e9008cb1782edbe896d4c899d39ae9cf78/matplotlib-3.10.8-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:56271f3dac49a88d7fca5060f004d9d22b865f743a12a23b1e937a0be4818ee1", size = 8148794, upload-time = "2025-12-10T22:55:46.252Z" }, + { url = "https://files.pythonhosted.org/packages/75/97/a471f1c3eb1fd6f6c24a31a5858f443891d5127e63a7788678d14e249aea/matplotlib-3.10.8-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:a0a7f52498f72f13d4a25ea70f35f4cb60642b466cbb0a9be951b5bc3f45a486", size = 8718474, upload-time = "2025-12-10T22:55:47.864Z" }, + { url = "https://files.pythonhosted.org/packages/01/be/cd478f4b66f48256f42927d0acbcd63a26a893136456cd079c0cc24fbabf/matplotlib-3.10.8-cp313-cp313-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:646d95230efb9ca614a7a594d4fcacde0ac61d25e37dd51710b36477594963ce", size = 9549637, upload-time = "2025-12-10T22:55:50.048Z" }, + { url = "https://files.pythonhosted.org/packages/5d/7c/8dc289776eae5109e268c4fb92baf870678dc048a25d4ac903683b86d5bf/matplotlib-3.10.8-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:f89c151aab2e2e23cb3fe0acad1e8b82841fd265379c4cecd0f3fcb34c15e0f6", size = 9613678, upload-time = "2025-12-10T22:55:52.21Z" }, + { url = "https://files.pythonhosted.org/packages/64/40/37612487cc8a437d4dd261b32ca21fe2d79510fe74af74e1f42becb1bdb8/matplotlib-3.10.8-cp313-cp313-win_amd64.whl", hash = "sha256:e8ea3e2d4066083e264e75c829078f9e149fa119d27e19acd503de65e0b13149", size = 8142686, upload-time = "2025-12-10T22:55:54.253Z" }, + { url = "https://files.pythonhosted.org/packages/66/52/8d8a8730e968185514680c2a6625943f70269509c3dcfc0dcf7d75928cb8/matplotlib-3.10.8-cp313-cp313-win_arm64.whl", hash = "sha256:c108a1d6fa78a50646029cb6d49808ff0fc1330fda87fa6f6250c6b5369b6645", size = 8012917, upload-time = "2025-12-10T22:55:56.268Z" }, + { url = "https://files.pythonhosted.org/packages/b5/27/51fe26e1062f298af5ef66343d8ef460e090a27fea73036c76c35821df04/matplotlib-3.10.8-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:ad3d9833a64cf48cc4300f2b406c3d0f4f4724a91c0bd5640678a6ba7c102077", size = 8305679, upload-time = "2025-12-10T22:55:57.856Z" }, + { url = "https://files.pythonhosted.org/packages/2c/1e/4de865bc591ac8e3062e835f42dd7fe7a93168d519557837f0e37513f629/matplotlib-3.10.8-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:eb3823f11823deade26ce3b9f40dcb4a213da7a670013929f31d5f5ed1055b22", size = 8198336, upload-time = "2025-12-10T22:55:59.371Z" }, + { url = "https://files.pythonhosted.org/packages/c6/cb/2f7b6e75fb4dce87ef91f60cac4f6e34f4c145ab036a22318ec837971300/matplotlib-3.10.8-cp313-cp313t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:d9050fee89a89ed57b4fb2c1bfac9a3d0c57a0d55aed95949eedbc42070fea39", size = 8731653, upload-time = "2025-12-10T22:56:01.032Z" }, + { url = "https://files.pythonhosted.org/packages/46/b3/bd9c57d6ba670a37ab31fb87ec3e8691b947134b201f881665b28cc039ff/matplotlib-3.10.8-cp313-cp313t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:b44d07310e404ba95f8c25aa5536f154c0a8ec473303535949e52eb71d0a1565", size = 9561356, upload-time = "2025-12-10T22:56:02.95Z" }, + { url = "https://files.pythonhosted.org/packages/c0/3d/8b94a481456dfc9dfe6e39e93b5ab376e50998cddfd23f4ae3b431708f16/matplotlib-3.10.8-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:0a33deb84c15ede243aead39f77e990469fff93ad1521163305095b77b72ce4a", size = 9614000, upload-time = "2025-12-10T22:56:05.411Z" }, + { url = "https://files.pythonhosted.org/packages/bd/cd/bc06149fe5585ba800b189a6a654a75f1f127e8aab02fd2be10df7fa500c/matplotlib-3.10.8-cp313-cp313t-win_amd64.whl", hash = "sha256:3a48a78d2786784cc2413e57397981fb45c79e968d99656706018d6e62e57958", size = 8220043, upload-time = "2025-12-10T22:56:07.551Z" }, + { url = "https://files.pythonhosted.org/packages/e3/de/b22cf255abec916562cc04eef457c13e58a1990048de0c0c3604d082355e/matplotlib-3.10.8-cp313-cp313t-win_arm64.whl", hash = "sha256:15d30132718972c2c074cd14638c7f4592bd98719e2308bccea40e0538bc0cb5", size = 8062075, upload-time = "2025-12-10T22:56:09.178Z" }, + { url = "https://files.pythonhosted.org/packages/3c/43/9c0ff7a2f11615e516c3b058e1e6e8f9614ddeca53faca06da267c48345d/matplotlib-3.10.8-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:b53285e65d4fa4c86399979e956235deb900be5baa7fc1218ea67fbfaeaadd6f", size = 8262481, upload-time = "2025-12-10T22:56:10.885Z" }, + { url = "https://files.pythonhosted.org/packages/6f/ca/e8ae28649fcdf039fda5ef554b40a95f50592a3c47e6f7270c9561c12b07/matplotlib-3.10.8-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:32f8dce744be5569bebe789e46727946041199030db8aeb2954d26013a0eb26b", size = 8151473, upload-time = "2025-12-10T22:56:12.377Z" }, + { url = "https://files.pythonhosted.org/packages/f1/6f/009d129ae70b75e88cbe7e503a12a4c0670e08ed748a902c2568909e9eb5/matplotlib-3.10.8-cp314-cp314-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:4cf267add95b1c88300d96ca837833d4112756045364f5c734a2276038dae27d", size = 9553896, upload-time = "2025-12-10T22:56:14.432Z" }, + { url = "https://files.pythonhosted.org/packages/f5/26/4221a741eb97967bc1fd5e4c52b9aa5a91b2f4ec05b59f6def4d820f9df9/matplotlib-3.10.8-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:2cf5bd12cecf46908f286d7838b2abc6c91cda506c0445b8223a7c19a00df008", size = 9824193, upload-time = "2025-12-10T22:56:16.29Z" }, + { url = "https://files.pythonhosted.org/packages/1f/f3/3abf75f38605772cf48a9daf5821cd4f563472f38b4b828c6fba6fa6d06e/matplotlib-3.10.8-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:41703cc95688f2516b480f7f339d8851a6035f18e100ee6a32bc0b8536a12a9c", size = 9615444, upload-time = "2025-12-10T22:56:18.155Z" }, + { url = "https://files.pythonhosted.org/packages/93/a5/de89ac80f10b8dc615807ee1133cd99ac74082581196d4d9590bea10690d/matplotlib-3.10.8-cp314-cp314-win_amd64.whl", hash = "sha256:83d282364ea9f3e52363da262ce32a09dfe241e4080dcedda3c0db059d3c1f11", size = 8272719, upload-time = "2025-12-10T22:56:20.366Z" }, + { url = "https://files.pythonhosted.org/packages/69/ce/b006495c19ccc0a137b48083168a37bd056392dee02f87dba0472f2797fe/matplotlib-3.10.8-cp314-cp314-win_arm64.whl", hash = "sha256:2c1998e92cd5999e295a731bcb2911c75f597d937341f3030cc24ef2733d78a8", size = 8144205, upload-time = "2025-12-10T22:56:22.239Z" }, + { url = "https://files.pythonhosted.org/packages/68/d9/b31116a3a855bd313c6fcdb7226926d59b041f26061c6c5b1be66a08c826/matplotlib-3.10.8-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:b5a2b97dbdc7d4f353ebf343744f1d1f1cca8aa8bfddb4262fcf4306c3761d50", size = 8305785, upload-time = "2025-12-10T22:56:24.218Z" }, + { url = "https://files.pythonhosted.org/packages/1e/90/6effe8103f0272685767ba5f094f453784057072f49b393e3ea178fe70a5/matplotlib-3.10.8-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:3f5c3e4da343bba819f0234186b9004faba952cc420fbc522dc4e103c1985908", size = 8198361, upload-time = "2025-12-10T22:56:26.787Z" }, + { url = "https://files.pythonhosted.org/packages/d7/65/a73188711bea603615fc0baecca1061429ac16940e2385433cc778a9d8e7/matplotlib-3.10.8-cp314-cp314t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:5f62550b9a30afde8c1c3ae450e5eb547d579dd69b25c2fc7a1c67f934c1717a", size = 9561357, upload-time = "2025-12-10T22:56:28.953Z" }, + { url = "https://files.pythonhosted.org/packages/f4/3d/b5c5d5d5be8ce63292567f0e2c43dde9953d3ed86ac2de0a72e93c8f07a1/matplotlib-3.10.8-cp314-cp314t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:495672de149445ec1b772ff2c9ede9b769e3cb4f0d0aa7fa730d7f59e2d4e1c1", size = 9823610, upload-time = "2025-12-10T22:56:31.455Z" }, + { url = "https://files.pythonhosted.org/packages/4d/4b/e7beb6bbd49f6bae727a12b270a2654d13c397576d25bd6786e47033300f/matplotlib-3.10.8-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:595ba4d8fe983b88f0eec8c26a241e16d6376fe1979086232f481f8f3f67494c", size = 9614011, upload-time = "2025-12-10T22:56:33.85Z" }, + { url = "https://files.pythonhosted.org/packages/7c/e6/76f2813d31f032e65f6f797e3f2f6e4aab95b65015924b1c51370395c28a/matplotlib-3.10.8-cp314-cp314t-win_amd64.whl", hash = "sha256:25d380fe8b1dc32cf8f0b1b448470a77afb195438bafdf1d858bfb876f3edf7b", size = 8362801, upload-time = "2025-12-10T22:56:36.107Z" }, + { url = "https://files.pythonhosted.org/packages/5d/49/d651878698a0b67f23aa28e17f45a6d6dd3d3f933fa29087fa4ce5947b5a/matplotlib-3.10.8-cp314-cp314t-win_arm64.whl", hash = "sha256:113bb52413ea508ce954a02c10ffd0d565f9c3bc7f2eddc27dfe1731e71c7b5f", size = 8192560, upload-time = "2025-12-10T22:56:38.008Z" }, ] [[package]] name = "matplotlib-inline" -version = "0.1.7" +version = "0.2.1" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "traitlets" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/99/5b/a36a337438a14116b16480db471ad061c36c3694df7c2084a0da7ba538b7/matplotlib_inline-0.1.7.tar.gz", hash = "sha256:8423b23ec666be3d16e16b60bdd8ac4e86e840ebd1dd11a30b9f117f2fa0ab90", size = 8159, upload-time = "2024-04-15T13:44:44.803Z" } +sdist = { url = "https://files.pythonhosted.org/packages/c7/74/97e72a36efd4ae2bccb3463284300f8953f199b5ffbc04cbbb0ec78f74b1/matplotlib_inline-0.2.1.tar.gz", hash = "sha256:e1ee949c340d771fc39e241ea75683deb94762c8fa5f2927ec57c83c4dffa9fe", size = 8110, upload-time = "2025-10-23T09:00:22.126Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/8f/8e/9ad090d3553c280a8060fbf6e24dc1c0c29704ee7d1c372f0c174aa59285/matplotlib_inline-0.1.7-py3-none-any.whl", hash = "sha256:df192d39a4ff8f21b1895d72e6a13f5fcc5099f00fa84384e0ea28c2cc0653ca", size = 9899, upload-time = "2024-04-15T13:44:43.265Z" }, + { url = "https://files.pythonhosted.org/packages/af/33/ee4519fa02ed11a94aef9559552f3b17bb863f2ecfe1a35dc7f548cde231/matplotlib_inline-0.2.1-py3-none-any.whl", hash = "sha256:d56ce5156ba6085e00a9d54fead6ed29a9c47e215cd1bba2e976ef39f5710a76", size = 9516, upload-time = "2025-10-23T09:00:20.675Z" }, ] [[package]] @@ -806,7 +789,7 @@ wheels = [ [[package]] name = "myst-parser" -version = "4.0.1" +version = "5.0.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "docutils" }, @@ -816,99 +799,79 @@ dependencies = [ { name = "pyyaml" }, { name = "sphinx" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/66/a5/9626ba4f73555b3735ad86247a8077d4603aa8628537687c839ab08bfe44/myst_parser-4.0.1.tar.gz", hash = "sha256:5cfea715e4f3574138aecbf7d54132296bfd72bb614d31168f48c477a830a7c4", size = 93985, upload-time = "2025-02-12T10:53:03.833Z" } +sdist = { url = "https://files.pythonhosted.org/packages/33/fa/7b45eef11b7971f0beb29d27b7bfe0d747d063aa29e170d9edd004733c8a/myst_parser-5.0.0.tar.gz", hash = "sha256:f6f231452c56e8baa662cc352c548158f6a16fcbd6e3800fc594978002b94f3a", size = 98535, upload-time = "2026-01-15T09:08:18.036Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/5f/df/76d0321c3797b54b60fef9ec3bd6f4cfd124b9e422182156a1dd418722cf/myst_parser-4.0.1-py3-none-any.whl", hash = "sha256:9134e88959ec3b5780aedf8a99680ea242869d012e8821db3126d427edc9c95d", size = 84579, upload-time = "2025-02-12T10:53:02.078Z" }, + { url = "https://files.pythonhosted.org/packages/d3/ac/686789b9145413f1a61878c407210e41bfdb097976864e0913078b24098c/myst_parser-5.0.0-py3-none-any.whl", hash = "sha256:ab31e516024918296e169139072b81592336f2fef55b8986aa31c9f04b5f7211", size = 84533, upload-time = "2026-01-15T09:08:16.788Z" }, ] [[package]] name = "networkx" -version = "3.5" +version = "3.6.1" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/6c/4f/ccdb8ad3a38e583f214547fd2f7ff1fc160c43a75af88e6aec213404b96a/networkx-3.5.tar.gz", hash = "sha256:d4c6f9cf81f52d69230866796b82afbccdec3db7ae4fbd1b65ea750feed50037", size = 2471065, upload-time = "2025-05-29T11:35:07.804Z" } +sdist = { url = "https://files.pythonhosted.org/packages/6a/51/63fe664f3908c97be9d2e4f1158eb633317598cfa6e1fc14af5383f17512/networkx-3.6.1.tar.gz", hash = "sha256:26b7c357accc0c8cde558ad486283728b65b6a95d85ee1cd66bafab4c8168509", size = 2517025, upload-time = "2025-12-08T17:02:39.908Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/eb/8d/776adee7bbf76365fdd7f2552710282c79a4ead5d2a46408c9043a2b70ba/networkx-3.5-py3-none-any.whl", hash = "sha256:0030d386a9a06dee3565298b4a734b68589749a544acbb6c412dc9e2489ec6ec", size = 2034406, upload-time = "2025-05-29T11:35:04.961Z" }, + { url = "https://files.pythonhosted.org/packages/9e/c9/b2622292ea83fbb4ec318f5b9ab867d0a28ab43c5717bb85b0a5f6b3b0a4/networkx-3.6.1-py3-none-any.whl", hash = "sha256:d47fbf302e7d9cbbb9e2555a0d267983d2aa476bac30e90dfbe5669bd57f3762", size = 2068504, upload-time = "2025-12-08T17:02:38.159Z" }, ] [[package]] name = "numpy" -version = "2.3.2" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/37/7d/3fec4199c5ffb892bed55cff901e4f39a58c81df9c44c280499e92cad264/numpy-2.3.2.tar.gz", hash = "sha256:e0486a11ec30cdecb53f184d496d1c6a20786c81e55e41640270130056f8ee48", size = 20489306, upload-time = "2025-07-24T21:32:07.553Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/96/26/1320083986108998bd487e2931eed2aeedf914b6e8905431487543ec911d/numpy-2.3.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:852ae5bed3478b92f093e30f785c98e0cb62fa0a939ed057c31716e18a7a22b9", size = 21259016, upload-time = "2025-07-24T20:24:35.214Z" }, - { url = "https://files.pythonhosted.org/packages/c4/2b/792b341463fa93fc7e55abbdbe87dac316c5b8cb5e94fb7a59fb6fa0cda5/numpy-2.3.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:7a0e27186e781a69959d0230dd9909b5e26024f8da10683bd6344baea1885168", size = 14451158, upload-time = "2025-07-24T20:24:58.397Z" }, - { url = "https://files.pythonhosted.org/packages/b7/13/e792d7209261afb0c9f4759ffef6135b35c77c6349a151f488f531d13595/numpy-2.3.2-cp311-cp311-macosx_14_0_arm64.whl", hash = "sha256:f0a1a8476ad77a228e41619af2fa9505cf69df928e9aaa165746584ea17fed2b", size = 5379817, upload-time = "2025-07-24T20:25:07.746Z" }, - { url = "https://files.pythonhosted.org/packages/49/ce/055274fcba4107c022b2113a213c7287346563f48d62e8d2a5176ad93217/numpy-2.3.2-cp311-cp311-macosx_14_0_x86_64.whl", hash = "sha256:cbc95b3813920145032412f7e33d12080f11dc776262df1712e1638207dde9e8", size = 6913606, upload-time = "2025-07-24T20:25:18.84Z" }, - { url = "https://files.pythonhosted.org/packages/17/f2/e4d72e6bc5ff01e2ab613dc198d560714971900c03674b41947e38606502/numpy-2.3.2-cp311-cp311-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:f75018be4980a7324edc5930fe39aa391d5734531b1926968605416ff58c332d", size = 14589652, upload-time = "2025-07-24T20:25:40.356Z" }, - { url = "https://files.pythonhosted.org/packages/c8/b0/fbeee3000a51ebf7222016e2939b5c5ecf8000a19555d04a18f1e02521b8/numpy-2.3.2-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:20b8200721840f5621b7bd03f8dcd78de33ec522fc40dc2641aa09537df010c3", size = 16938816, upload-time = "2025-07-24T20:26:05.721Z" }, - { url = "https://files.pythonhosted.org/packages/a9/ec/2f6c45c3484cc159621ea8fc000ac5a86f1575f090cac78ac27193ce82cd/numpy-2.3.2-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:1f91e5c028504660d606340a084db4b216567ded1056ea2b4be4f9d10b67197f", size = 16370512, upload-time = "2025-07-24T20:26:30.545Z" }, - { url = "https://files.pythonhosted.org/packages/b5/01/dd67cf511850bd7aefd6347aaae0956ed415abea741ae107834aae7d6d4e/numpy-2.3.2-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:fb1752a3bb9a3ad2d6b090b88a9a0ae1cd6f004ef95f75825e2f382c183b2097", size = 18884947, upload-time = "2025-07-24T20:26:58.24Z" }, - { url = "https://files.pythonhosted.org/packages/a7/17/2cf60fd3e6a61d006778735edf67a222787a8c1a7842aed43ef96d777446/numpy-2.3.2-cp311-cp311-win32.whl", hash = "sha256:4ae6863868aaee2f57503c7a5052b3a2807cf7a3914475e637a0ecd366ced220", size = 6599494, upload-time = "2025-07-24T20:27:09.786Z" }, - { url = "https://files.pythonhosted.org/packages/d5/03/0eade211c504bda872a594f045f98ddcc6caef2b7c63610946845e304d3f/numpy-2.3.2-cp311-cp311-win_amd64.whl", hash = "sha256:240259d6564f1c65424bcd10f435145a7644a65a6811cfc3201c4a429ba79170", size = 13087889, upload-time = "2025-07-24T20:27:29.558Z" }, - { url = "https://files.pythonhosted.org/packages/13/32/2c7979d39dafb2a25087e12310fc7f3b9d3c7d960df4f4bc97955ae0ce1d/numpy-2.3.2-cp311-cp311-win_arm64.whl", hash = "sha256:4209f874d45f921bde2cff1ffcd8a3695f545ad2ffbef6d3d3c6768162efab89", size = 10459560, upload-time = "2025-07-24T20:27:46.803Z" }, - { url = "https://files.pythonhosted.org/packages/00/6d/745dd1c1c5c284d17725e5c802ca4d45cfc6803519d777f087b71c9f4069/numpy-2.3.2-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:bc3186bea41fae9d8e90c2b4fb5f0a1f5a690682da79b92574d63f56b529080b", size = 20956420, upload-time = "2025-07-24T20:28:18.002Z" }, - { url = "https://files.pythonhosted.org/packages/bc/96/e7b533ea5740641dd62b07a790af5d9d8fec36000b8e2d0472bd7574105f/numpy-2.3.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:2f4f0215edb189048a3c03bd5b19345bdfa7b45a7a6f72ae5945d2a28272727f", size = 14184660, upload-time = "2025-07-24T20:28:39.522Z" }, - { url = "https://files.pythonhosted.org/packages/2b/53/102c6122db45a62aa20d1b18c9986f67e6b97e0d6fbc1ae13e3e4c84430c/numpy-2.3.2-cp312-cp312-macosx_14_0_arm64.whl", hash = "sha256:8b1224a734cd509f70816455c3cffe13a4f599b1bf7130f913ba0e2c0b2006c0", size = 5113382, upload-time = "2025-07-24T20:28:48.544Z" }, - { url = "https://files.pythonhosted.org/packages/2b/21/376257efcbf63e624250717e82b4fae93d60178f09eb03ed766dbb48ec9c/numpy-2.3.2-cp312-cp312-macosx_14_0_x86_64.whl", hash = "sha256:3dcf02866b977a38ba3ec10215220609ab9667378a9e2150615673f3ffd6c73b", size = 6647258, upload-time = "2025-07-24T20:28:59.104Z" }, - { url = "https://files.pythonhosted.org/packages/91/ba/f4ebf257f08affa464fe6036e13f2bf9d4642a40228781dc1235da81be9f/numpy-2.3.2-cp312-cp312-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:572d5512df5470f50ada8d1972c5f1082d9a0b7aa5944db8084077570cf98370", size = 14281409, upload-time = "2025-07-24T20:40:30.298Z" }, - { url = "https://files.pythonhosted.org/packages/59/ef/f96536f1df42c668cbacb727a8c6da7afc9c05ece6d558927fb1722693e1/numpy-2.3.2-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:8145dd6d10df13c559d1e4314df29695613575183fa2e2d11fac4c208c8a1f73", size = 16641317, upload-time = "2025-07-24T20:40:56.625Z" }, - { url = "https://files.pythonhosted.org/packages/f6/a7/af813a7b4f9a42f498dde8a4c6fcbff8100eed00182cc91dbaf095645f38/numpy-2.3.2-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:103ea7063fa624af04a791c39f97070bf93b96d7af7eb23530cd087dc8dbe9dc", size = 16056262, upload-time = "2025-07-24T20:41:20.797Z" }, - { url = "https://files.pythonhosted.org/packages/8b/5d/41c4ef8404caaa7f05ed1cfb06afe16a25895260eacbd29b4d84dff2920b/numpy-2.3.2-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:fc927d7f289d14f5e037be917539620603294454130b6de200091e23d27dc9be", size = 18579342, upload-time = "2025-07-24T20:41:50.753Z" }, - { url = "https://files.pythonhosted.org/packages/a1/4f/9950e44c5a11636f4a3af6e825ec23003475cc9a466edb7a759ed3ea63bd/numpy-2.3.2-cp312-cp312-win32.whl", hash = "sha256:d95f59afe7f808c103be692175008bab926b59309ade3e6d25009e9a171f7036", size = 6320610, upload-time = "2025-07-24T20:42:01.551Z" }, - { url = "https://files.pythonhosted.org/packages/7c/2f/244643a5ce54a94f0a9a2ab578189c061e4a87c002e037b0829dd77293b6/numpy-2.3.2-cp312-cp312-win_amd64.whl", hash = "sha256:9e196ade2400c0c737d93465327d1ae7c06c7cb8a1756121ebf54b06ca183c7f", size = 12786292, upload-time = "2025-07-24T20:42:20.738Z" }, - { url = "https://files.pythonhosted.org/packages/54/cd/7b5f49d5d78db7badab22d8323c1b6ae458fbf86c4fdfa194ab3cd4eb39b/numpy-2.3.2-cp312-cp312-win_arm64.whl", hash = "sha256:ee807923782faaf60d0d7331f5e86da7d5e3079e28b291973c545476c2b00d07", size = 10194071, upload-time = "2025-07-24T20:42:36.657Z" }, - { url = "https://files.pythonhosted.org/packages/1c/c0/c6bb172c916b00700ed3bf71cb56175fd1f7dbecebf8353545d0b5519f6c/numpy-2.3.2-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:c8d9727f5316a256425892b043736d63e89ed15bbfe6556c5ff4d9d4448ff3b3", size = 20949074, upload-time = "2025-07-24T20:43:07.813Z" }, - { url = "https://files.pythonhosted.org/packages/20/4e/c116466d22acaf4573e58421c956c6076dc526e24a6be0903219775d862e/numpy-2.3.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:efc81393f25f14d11c9d161e46e6ee348637c0a1e8a54bf9dedc472a3fae993b", size = 14177311, upload-time = "2025-07-24T20:43:29.335Z" }, - { url = "https://files.pythonhosted.org/packages/78/45/d4698c182895af189c463fc91d70805d455a227261d950e4e0f1310c2550/numpy-2.3.2-cp313-cp313-macosx_14_0_arm64.whl", hash = "sha256:dd937f088a2df683cbb79dda9a772b62a3e5a8a7e76690612c2737f38c6ef1b6", size = 5106022, upload-time = "2025-07-24T20:43:37.999Z" }, - { url = "https://files.pythonhosted.org/packages/9f/76/3e6880fef4420179309dba72a8c11f6166c431cf6dee54c577af8906f914/numpy-2.3.2-cp313-cp313-macosx_14_0_x86_64.whl", hash = "sha256:11e58218c0c46c80509186e460d79fbdc9ca1eb8d8aee39d8f2dc768eb781089", size = 6640135, upload-time = "2025-07-24T20:43:49.28Z" }, - { url = "https://files.pythonhosted.org/packages/34/fa/87ff7f25b3c4ce9085a62554460b7db686fef1e0207e8977795c7b7d7ba1/numpy-2.3.2-cp313-cp313-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:5ad4ebcb683a1f99f4f392cc522ee20a18b2bb12a2c1c42c3d48d5a1adc9d3d2", size = 14278147, upload-time = "2025-07-24T20:44:10.328Z" }, - { url = "https://files.pythonhosted.org/packages/1d/0f/571b2c7a3833ae419fe69ff7b479a78d313581785203cc70a8db90121b9a/numpy-2.3.2-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:938065908d1d869c7d75d8ec45f735a034771c6ea07088867f713d1cd3bbbe4f", size = 16635989, upload-time = "2025-07-24T20:44:34.88Z" }, - { url = "https://files.pythonhosted.org/packages/24/5a/84ae8dca9c9a4c592fe11340b36a86ffa9fd3e40513198daf8a97839345c/numpy-2.3.2-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:66459dccc65d8ec98cc7df61307b64bf9e08101f9598755d42d8ae65d9a7a6ee", size = 16053052, upload-time = "2025-07-24T20:44:58.872Z" }, - { url = "https://files.pythonhosted.org/packages/57/7c/e5725d99a9133b9813fcf148d3f858df98511686e853169dbaf63aec6097/numpy-2.3.2-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:a7af9ed2aa9ec5950daf05bb11abc4076a108bd3c7db9aa7251d5f107079b6a6", size = 18577955, upload-time = "2025-07-24T20:45:26.714Z" }, - { url = "https://files.pythonhosted.org/packages/ae/11/7c546fcf42145f29b71e4d6f429e96d8d68e5a7ba1830b2e68d7418f0bbd/numpy-2.3.2-cp313-cp313-win32.whl", hash = "sha256:906a30249315f9c8e17b085cc5f87d3f369b35fedd0051d4a84686967bdbbd0b", size = 6311843, upload-time = "2025-07-24T20:49:24.444Z" }, - { url = "https://files.pythonhosted.org/packages/aa/6f/a428fd1cb7ed39b4280d057720fed5121b0d7754fd2a9768640160f5517b/numpy-2.3.2-cp313-cp313-win_amd64.whl", hash = "sha256:c63d95dc9d67b676e9108fe0d2182987ccb0f11933c1e8959f42fa0da8d4fa56", size = 12782876, upload-time = "2025-07-24T20:49:43.227Z" }, - { url = "https://files.pythonhosted.org/packages/65/85/4ea455c9040a12595fb6c43f2c217257c7b52dd0ba332c6a6c1d28b289fe/numpy-2.3.2-cp313-cp313-win_arm64.whl", hash = "sha256:b05a89f2fb84d21235f93de47129dd4f11c16f64c87c33f5e284e6a3a54e43f2", size = 10192786, upload-time = "2025-07-24T20:49:59.443Z" }, - { url = "https://files.pythonhosted.org/packages/80/23/8278f40282d10c3f258ec3ff1b103d4994bcad78b0cba9208317f6bb73da/numpy-2.3.2-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:4e6ecfeddfa83b02318f4d84acf15fbdbf9ded18e46989a15a8b6995dfbf85ab", size = 21047395, upload-time = "2025-07-24T20:45:58.821Z" }, - { url = "https://files.pythonhosted.org/packages/1f/2d/624f2ce4a5df52628b4ccd16a4f9437b37c35f4f8a50d00e962aae6efd7a/numpy-2.3.2-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:508b0eada3eded10a3b55725b40806a4b855961040180028f52580c4729916a2", size = 14300374, upload-time = "2025-07-24T20:46:20.207Z" }, - { url = "https://files.pythonhosted.org/packages/f6/62/ff1e512cdbb829b80a6bd08318a58698867bca0ca2499d101b4af063ee97/numpy-2.3.2-cp313-cp313t-macosx_14_0_arm64.whl", hash = "sha256:754d6755d9a7588bdc6ac47dc4ee97867271b17cee39cb87aef079574366db0a", size = 5228864, upload-time = "2025-07-24T20:46:30.58Z" }, - { url = "https://files.pythonhosted.org/packages/7d/8e/74bc18078fff03192d4032cfa99d5a5ca937807136d6f5790ce07ca53515/numpy-2.3.2-cp313-cp313t-macosx_14_0_x86_64.whl", hash = "sha256:a9f66e7d2b2d7712410d3bc5684149040ef5f19856f20277cd17ea83e5006286", size = 6737533, upload-time = "2025-07-24T20:46:46.111Z" }, - { url = "https://files.pythonhosted.org/packages/19/ea/0731efe2c9073ccca5698ef6a8c3667c4cf4eea53fcdcd0b50140aba03bc/numpy-2.3.2-cp313-cp313t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:de6ea4e5a65d5a90c7d286ddff2b87f3f4ad61faa3db8dabe936b34c2275b6f8", size = 14352007, upload-time = "2025-07-24T20:47:07.1Z" }, - { url = "https://files.pythonhosted.org/packages/cf/90/36be0865f16dfed20f4bc7f75235b963d5939707d4b591f086777412ff7b/numpy-2.3.2-cp313-cp313t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:a3ef07ec8cbc8fc9e369c8dcd52019510c12da4de81367d8b20bc692aa07573a", size = 16701914, upload-time = "2025-07-24T20:47:32.459Z" }, - { url = "https://files.pythonhosted.org/packages/94/30/06cd055e24cb6c38e5989a9e747042b4e723535758e6153f11afea88c01b/numpy-2.3.2-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:27c9f90e7481275c7800dc9c24b7cc40ace3fdb970ae4d21eaff983a32f70c91", size = 16132708, upload-time = "2025-07-24T20:47:58.129Z" }, - { url = "https://files.pythonhosted.org/packages/9a/14/ecede608ea73e58267fd7cb78f42341b3b37ba576e778a1a06baffbe585c/numpy-2.3.2-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:07b62978075b67eee4065b166d000d457c82a1efe726cce608b9db9dd66a73a5", size = 18651678, upload-time = "2025-07-24T20:48:25.402Z" }, - { url = "https://files.pythonhosted.org/packages/40/f3/2fe6066b8d07c3685509bc24d56386534c008b462a488b7f503ba82b8923/numpy-2.3.2-cp313-cp313t-win32.whl", hash = "sha256:c771cfac34a4f2c0de8e8c97312d07d64fd8f8ed45bc9f5726a7e947270152b5", size = 6441832, upload-time = "2025-07-24T20:48:37.181Z" }, - { url = "https://files.pythonhosted.org/packages/0b/ba/0937d66d05204d8f28630c9c60bc3eda68824abde4cf756c4d6aad03b0c6/numpy-2.3.2-cp313-cp313t-win_amd64.whl", hash = "sha256:72dbebb2dcc8305c431b2836bcc66af967df91be793d63a24e3d9b741374c450", size = 12927049, upload-time = "2025-07-24T20:48:56.24Z" }, - { url = "https://files.pythonhosted.org/packages/e9/ed/13542dd59c104d5e654dfa2ac282c199ba64846a74c2c4bcdbc3a0f75df1/numpy-2.3.2-cp313-cp313t-win_arm64.whl", hash = "sha256:72c6df2267e926a6d5286b0a6d556ebe49eae261062059317837fda12ddf0c1a", size = 10262935, upload-time = "2025-07-24T20:49:13.136Z" }, - { url = "https://files.pythonhosted.org/packages/c9/7c/7659048aaf498f7611b783e000c7268fcc4dcf0ce21cd10aad7b2e8f9591/numpy-2.3.2-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:448a66d052d0cf14ce9865d159bfc403282c9bc7bb2a31b03cc18b651eca8b1a", size = 20950906, upload-time = "2025-07-24T20:50:30.346Z" }, - { url = "https://files.pythonhosted.org/packages/80/db/984bea9d4ddf7112a04cfdfb22b1050af5757864cfffe8e09e44b7f11a10/numpy-2.3.2-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:546aaf78e81b4081b2eba1d105c3b34064783027a06b3ab20b6eba21fb64132b", size = 14185607, upload-time = "2025-07-24T20:50:51.923Z" }, - { url = "https://files.pythonhosted.org/packages/e4/76/b3d6f414f4eca568f469ac112a3b510938d892bc5a6c190cb883af080b77/numpy-2.3.2-cp314-cp314-macosx_14_0_arm64.whl", hash = "sha256:87c930d52f45df092f7578889711a0768094debf73cfcde105e2d66954358125", size = 5114110, upload-time = "2025-07-24T20:51:01.041Z" }, - { url = "https://files.pythonhosted.org/packages/9e/d2/6f5e6826abd6bca52392ed88fe44a4b52aacb60567ac3bc86c67834c3a56/numpy-2.3.2-cp314-cp314-macosx_14_0_x86_64.whl", hash = "sha256:8dc082ea901a62edb8f59713c6a7e28a85daddcb67454c839de57656478f5b19", size = 6642050, upload-time = "2025-07-24T20:51:11.64Z" }, - { url = "https://files.pythonhosted.org/packages/c4/43/f12b2ade99199e39c73ad182f103f9d9791f48d885c600c8e05927865baf/numpy-2.3.2-cp314-cp314-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:af58de8745f7fa9ca1c0c7c943616c6fe28e75d0c81f5c295810e3c83b5be92f", size = 14296292, upload-time = "2025-07-24T20:51:33.488Z" }, - { url = "https://files.pythonhosted.org/packages/5d/f9/77c07d94bf110a916b17210fac38680ed8734c236bfed9982fd8524a7b47/numpy-2.3.2-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:fed5527c4cf10f16c6d0b6bee1f89958bccb0ad2522c8cadc2efd318bcd545f5", size = 16638913, upload-time = "2025-07-24T20:51:58.517Z" }, - { url = "https://files.pythonhosted.org/packages/9b/d1/9d9f2c8ea399cc05cfff8a7437453bd4e7d894373a93cdc46361bbb49a7d/numpy-2.3.2-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:095737ed986e00393ec18ec0b21b47c22889ae4b0cd2d5e88342e08b01141f58", size = 16071180, upload-time = "2025-07-24T20:52:22.827Z" }, - { url = "https://files.pythonhosted.org/packages/4c/41/82e2c68aff2a0c9bf315e47d61951099fed65d8cb2c8d9dc388cb87e947e/numpy-2.3.2-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:b5e40e80299607f597e1a8a247ff8d71d79c5b52baa11cc1cce30aa92d2da6e0", size = 18576809, upload-time = "2025-07-24T20:52:51.015Z" }, - { url = "https://files.pythonhosted.org/packages/14/14/4b4fd3efb0837ed252d0f583c5c35a75121038a8c4e065f2c259be06d2d8/numpy-2.3.2-cp314-cp314-win32.whl", hash = "sha256:7d6e390423cc1f76e1b8108c9b6889d20a7a1f59d9a60cac4a050fa734d6c1e2", size = 6366410, upload-time = "2025-07-24T20:56:44.949Z" }, - { url = "https://files.pythonhosted.org/packages/11/9e/b4c24a6b8467b61aced5c8dc7dcfce23621baa2e17f661edb2444a418040/numpy-2.3.2-cp314-cp314-win_amd64.whl", hash = "sha256:b9d0878b21e3918d76d2209c924ebb272340da1fb51abc00f986c258cd5e957b", size = 12918821, upload-time = "2025-07-24T20:57:06.479Z" }, - { url = "https://files.pythonhosted.org/packages/0e/0f/0dc44007c70b1007c1cef86b06986a3812dd7106d8f946c09cfa75782556/numpy-2.3.2-cp314-cp314-win_arm64.whl", hash = "sha256:2738534837c6a1d0c39340a190177d7d66fdf432894f469728da901f8f6dc910", size = 10477303, upload-time = "2025-07-24T20:57:22.879Z" }, - { url = "https://files.pythonhosted.org/packages/8b/3e/075752b79140b78ddfc9c0a1634d234cfdbc6f9bbbfa6b7504e445ad7d19/numpy-2.3.2-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:4d002ecf7c9b53240be3bb69d80f86ddbd34078bae04d87be81c1f58466f264e", size = 21047524, upload-time = "2025-07-24T20:53:22.086Z" }, - { url = "https://files.pythonhosted.org/packages/fe/6d/60e8247564a72426570d0e0ea1151b95ce5bd2f1597bb878a18d32aec855/numpy-2.3.2-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:293b2192c6bcce487dbc6326de5853787f870aeb6c43f8f9c6496db5b1781e45", size = 14300519, upload-time = "2025-07-24T20:53:44.053Z" }, - { url = "https://files.pythonhosted.org/packages/4d/73/d8326c442cd428d47a067070c3ac6cc3b651a6e53613a1668342a12d4479/numpy-2.3.2-cp314-cp314t-macosx_14_0_arm64.whl", hash = "sha256:0a4f2021a6da53a0d580d6ef5db29947025ae8b35b3250141805ea9a32bbe86b", size = 5228972, upload-time = "2025-07-24T20:53:53.81Z" }, - { url = "https://files.pythonhosted.org/packages/34/2e/e71b2d6dad075271e7079db776196829019b90ce3ece5c69639e4f6fdc44/numpy-2.3.2-cp314-cp314t-macosx_14_0_x86_64.whl", hash = "sha256:9c144440db4bf3bb6372d2c3e49834cc0ff7bb4c24975ab33e01199e645416f2", size = 6737439, upload-time = "2025-07-24T20:54:04.742Z" }, - { url = "https://files.pythonhosted.org/packages/15/b0/d004bcd56c2c5e0500ffc65385eb6d569ffd3363cb5e593ae742749b2daa/numpy-2.3.2-cp314-cp314t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:f92d6c2a8535dc4fe4419562294ff957f83a16ebdec66df0805e473ffaad8bd0", size = 14352479, upload-time = "2025-07-24T20:54:25.819Z" }, - { url = "https://files.pythonhosted.org/packages/11/e3/285142fcff8721e0c99b51686426165059874c150ea9ab898e12a492e291/numpy-2.3.2-cp314-cp314t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:cefc2219baa48e468e3db7e706305fcd0c095534a192a08f31e98d83a7d45fb0", size = 16702805, upload-time = "2025-07-24T20:54:50.814Z" }, - { url = "https://files.pythonhosted.org/packages/33/c3/33b56b0e47e604af2c7cd065edca892d180f5899599b76830652875249a3/numpy-2.3.2-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:76c3e9501ceb50b2ff3824c3589d5d1ab4ac857b0ee3f8f49629d0de55ecf7c2", size = 16133830, upload-time = "2025-07-24T20:55:17.306Z" }, - { url = "https://files.pythonhosted.org/packages/6e/ae/7b1476a1f4d6a48bc669b8deb09939c56dd2a439db1ab03017844374fb67/numpy-2.3.2-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:122bf5ed9a0221b3419672493878ba4967121514b1d7d4656a7580cd11dddcbf", size = 18652665, upload-time = "2025-07-24T20:55:46.665Z" }, - { url = "https://files.pythonhosted.org/packages/14/ba/5b5c9978c4bb161034148ade2de9db44ec316fab89ce8c400db0e0c81f86/numpy-2.3.2-cp314-cp314t-win32.whl", hash = "sha256:6f1ae3dcb840edccc45af496f312528c15b1f79ac318169d094e85e4bb35fdf1", size = 6514777, upload-time = "2025-07-24T20:55:57.66Z" }, - { url = "https://files.pythonhosted.org/packages/eb/46/3dbaf0ae7c17cdc46b9f662c56da2054887b8d9e737c1476f335c83d33db/numpy-2.3.2-cp314-cp314t-win_amd64.whl", hash = "sha256:087ffc25890d89a43536f75c5fe8770922008758e8eeeef61733957041ed2f9b", size = 13111856, upload-time = "2025-07-24T20:56:17.318Z" }, - { url = "https://files.pythonhosted.org/packages/c1/9e/1652778bce745a67b5fe05adde60ed362d38eb17d919a540e813d30f6874/numpy-2.3.2-cp314-cp314t-win_arm64.whl", hash = "sha256:092aeb3449833ea9c0bf0089d70c29ae480685dd2377ec9cdbbb620257f84631", size = 10544226, upload-time = "2025-07-24T20:56:34.509Z" }, - { url = "https://files.pythonhosted.org/packages/cf/ea/50ebc91d28b275b23b7128ef25c3d08152bc4068f42742867e07a870a42a/numpy-2.3.2-pp311-pypy311_pp73-macosx_10_15_x86_64.whl", hash = "sha256:14a91ebac98813a49bc6aa1a0dfc09513dcec1d97eaf31ca21a87221a1cdcb15", size = 21130338, upload-time = "2025-07-24T20:57:54.37Z" }, - { url = "https://files.pythonhosted.org/packages/9f/57/cdd5eac00dd5f137277355c318a955c0d8fb8aa486020c22afd305f8b88f/numpy-2.3.2-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:71669b5daae692189540cffc4c439468d35a3f84f0c88b078ecd94337f6cb0ec", size = 14375776, upload-time = "2025-07-24T20:58:16.303Z" }, - { url = "https://files.pythonhosted.org/packages/83/85/27280c7f34fcd305c2209c0cdca4d70775e4859a9eaa92f850087f8dea50/numpy-2.3.2-pp311-pypy311_pp73-macosx_14_0_arm64.whl", hash = "sha256:69779198d9caee6e547adb933941ed7520f896fd9656834c300bdf4dd8642712", size = 5304882, upload-time = "2025-07-24T20:58:26.199Z" }, - { url = "https://files.pythonhosted.org/packages/48/b4/6500b24d278e15dd796f43824e69939d00981d37d9779e32499e823aa0aa/numpy-2.3.2-pp311-pypy311_pp73-macosx_14_0_x86_64.whl", hash = "sha256:2c3271cc4097beb5a60f010bcc1cc204b300bb3eafb4399376418a83a1c6373c", size = 6818405, upload-time = "2025-07-24T20:58:37.341Z" }, - { url = "https://files.pythonhosted.org/packages/9b/c9/142c1e03f199d202da8e980c2496213509291b6024fd2735ad28ae7065c7/numpy-2.3.2-pp311-pypy311_pp73-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:8446acd11fe3dc1830568c941d44449fd5cb83068e5c70bd5a470d323d448296", size = 14419651, upload-time = "2025-07-24T20:58:59.048Z" }, - { url = "https://files.pythonhosted.org/packages/8b/95/8023e87cbea31a750a6c00ff9427d65ebc5fef104a136bfa69f76266d614/numpy-2.3.2-pp311-pypy311_pp73-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:aa098a5ab53fa407fded5870865c6275a5cd4101cfdef8d6fafc48286a96e981", size = 16760166, upload-time = "2025-07-24T21:28:56.38Z" }, - { url = "https://files.pythonhosted.org/packages/78/e3/6690b3f85a05506733c7e90b577e4762517404ea78bab2ca3a5cb1aeb78d/numpy-2.3.2-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:6936aff90dda378c09bea075af0d9c675fe3a977a9d2402f95a87f440f59f619", size = 12977811, upload-time = "2025-07-24T21:29:18.234Z" }, +version = "2.4.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/24/62/ae72ff66c0f1fd959925b4c11f8c2dea61f47f6acaea75a08512cdfe3fed/numpy-2.4.1.tar.gz", hash = "sha256:a1ceafc5042451a858231588a104093474c6a5c57dcc724841f5c888d237d690", size = 20721320, upload-time = "2026-01-10T06:44:59.619Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/78/7f/ec53e32bf10c813604edf07a3682616bd931d026fcde7b6d13195dfb684a/numpy-2.4.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:d3703409aac693fa82c0aee023a1ae06a6e9d065dba10f5e8e80f642f1e9d0a2", size = 16656888, upload-time = "2026-01-10T06:42:40.913Z" }, + { url = "https://files.pythonhosted.org/packages/b8/e0/1f9585d7dae8f14864e948fd7fa86c6cb72dee2676ca2748e63b1c5acfe0/numpy-2.4.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:7211b95ca365519d3596a1d8688a95874cc94219d417504d9ecb2df99fa7bfa8", size = 12373956, upload-time = "2026-01-10T06:42:43.091Z" }, + { url = "https://files.pythonhosted.org/packages/8e/43/9762e88909ff2326f5e7536fa8cb3c49fb03a7d92705f23e6e7f553d9cb3/numpy-2.4.1-cp312-cp312-macosx_14_0_arm64.whl", hash = "sha256:5adf01965456a664fc727ed69cc71848f28d063217c63e1a0e200a118d5eec9a", size = 5202567, upload-time = "2026-01-10T06:42:45.107Z" }, + { url = "https://files.pythonhosted.org/packages/4b/ee/34b7930eb61e79feb4478800a4b95b46566969d837546aa7c034c742ef98/numpy-2.4.1-cp312-cp312-macosx_14_0_x86_64.whl", hash = "sha256:26f0bcd9c79a00e339565b303badc74d3ea2bd6d52191eeca5f95936cad107d0", size = 6549459, upload-time = "2026-01-10T06:42:48.152Z" }, + { url = "https://files.pythonhosted.org/packages/79/e3/5f115fae982565771be994867c89bcd8d7208dbfe9469185497d70de5ddf/numpy-2.4.1-cp312-cp312-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:0093e85df2960d7e4049664b26afc58b03236e967fb942354deef3208857a04c", size = 14404859, upload-time = "2026-01-10T06:42:49.947Z" }, + { url = "https://files.pythonhosted.org/packages/d9/7d/9c8a781c88933725445a859cac5d01b5871588a15969ee6aeb618ba99eee/numpy-2.4.1-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:7ad270f438cbdd402c364980317fb6b117d9ec5e226fff5b4148dd9aa9fc6e02", size = 16371419, upload-time = "2026-01-10T06:42:52.409Z" }, + { url = "https://files.pythonhosted.org/packages/a6/d2/8aa084818554543f17cf4162c42f162acbd3bb42688aefdba6628a859f77/numpy-2.4.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:297c72b1b98100c2e8f873d5d35fb551fce7040ade83d67dd51d38c8d42a2162", size = 16182131, upload-time = "2026-01-10T06:42:54.694Z" }, + { url = "https://files.pythonhosted.org/packages/60/db/0425216684297c58a8df35f3284ef56ec4a043e6d283f8a59c53562caf1b/numpy-2.4.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:cf6470d91d34bf669f61d515499859fa7a4c2f7c36434afb70e82df7217933f9", size = 18295342, upload-time = "2026-01-10T06:42:56.991Z" }, + { url = "https://files.pythonhosted.org/packages/31/4c/14cb9d86240bd8c386c881bafbe43f001284b7cce3bc01623ac9475da163/numpy-2.4.1-cp312-cp312-win32.whl", hash = "sha256:b6bcf39112e956594b3331316d90c90c90fb961e39696bda97b89462f5f3943f", size = 5959015, upload-time = "2026-01-10T06:42:59.631Z" }, + { url = "https://files.pythonhosted.org/packages/51/cf/52a703dbeb0c65807540d29699fef5fda073434ff61846a564d5c296420f/numpy-2.4.1-cp312-cp312-win_amd64.whl", hash = "sha256:e1a27bb1b2dee45a2a53f5ca6ff2d1a7f135287883a1689e930d44d1ff296c87", size = 12310730, upload-time = "2026-01-10T06:43:01.627Z" }, + { url = "https://files.pythonhosted.org/packages/69/80/a828b2d0ade5e74a9fe0f4e0a17c30fdc26232ad2bc8c9f8b3197cf7cf18/numpy-2.4.1-cp312-cp312-win_arm64.whl", hash = "sha256:0e6e8f9d9ecf95399982019c01223dc130542960a12edfa8edd1122dfa66a8a8", size = 10312166, upload-time = "2026-01-10T06:43:03.673Z" }, + { url = "https://files.pythonhosted.org/packages/04/68/732d4b7811c00775f3bd522a21e8dd5a23f77eb11acdeb663e4a4ebf0ef4/numpy-2.4.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:d797454e37570cfd61143b73b8debd623c3c0952959adb817dd310a483d58a1b", size = 16652495, upload-time = "2026-01-10T06:43:06.283Z" }, + { url = "https://files.pythonhosted.org/packages/20/ca/857722353421a27f1465652b2c66813eeeccea9d76d5f7b74b99f298e60e/numpy-2.4.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:82c55962006156aeef1629b953fd359064aa47e4d82cfc8e67f0918f7da3344f", size = 12368657, upload-time = "2026-01-10T06:43:09.094Z" }, + { url = "https://files.pythonhosted.org/packages/81/0d/2377c917513449cc6240031a79d30eb9a163d32a91e79e0da47c43f2c0c8/numpy-2.4.1-cp313-cp313-macosx_14_0_arm64.whl", hash = "sha256:71abbea030f2cfc3092a0ff9f8c8fdefdc5e0bf7d9d9c99663538bb0ecdac0b9", size = 5197256, upload-time = "2026-01-10T06:43:13.634Z" }, + { url = "https://files.pythonhosted.org/packages/17/39/569452228de3f5de9064ac75137082c6214be1f5c532016549a7923ab4b5/numpy-2.4.1-cp313-cp313-macosx_14_0_x86_64.whl", hash = "sha256:5b55aa56165b17aaf15520beb9cbd33c9039810e0d9643dd4379e44294c7303e", size = 6545212, upload-time = "2026-01-10T06:43:15.661Z" }, + { url = "https://files.pythonhosted.org/packages/8c/a4/77333f4d1e4dac4395385482557aeecf4826e6ff517e32ca48e1dafbe42a/numpy-2.4.1-cp313-cp313-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:c0faba4a331195bfa96f93dd9dfaa10b2c7aa8cda3a02b7fd635e588fe821bf5", size = 14402871, upload-time = "2026-01-10T06:43:17.324Z" }, + { url = "https://files.pythonhosted.org/packages/ba/87/d341e519956273b39d8d47969dd1eaa1af740615394fe67d06f1efa68773/numpy-2.4.1-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:d3e3087f53e2b4428766b54932644d148613c5a595150533ae7f00dab2f319a8", size = 16359305, upload-time = "2026-01-10T06:43:19.376Z" }, + { url = "https://files.pythonhosted.org/packages/32/91/789132c6666288eaa20ae8066bb99eba1939362e8f1a534949a215246e97/numpy-2.4.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:49e792ec351315e16da54b543db06ca8a86985ab682602d90c60ef4ff4db2a9c", size = 16181909, upload-time = "2026-01-10T06:43:21.808Z" }, + { url = "https://files.pythonhosted.org/packages/cf/b8/090b8bd27b82a844bb22ff8fdf7935cb1980b48d6e439ae116f53cdc2143/numpy-2.4.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:79e9e06c4c2379db47f3f6fc7a8652e7498251789bf8ff5bd43bf478ef314ca2", size = 18284380, upload-time = "2026-01-10T06:43:23.957Z" }, + { url = "https://files.pythonhosted.org/packages/67/78/722b62bd31842ff029412271556a1a27a98f45359dea78b1548a3a9996aa/numpy-2.4.1-cp313-cp313-win32.whl", hash = "sha256:3d1a100e48cb266090a031397863ff8a30050ceefd798f686ff92c67a486753d", size = 5957089, upload-time = "2026-01-10T06:43:27.535Z" }, + { url = "https://files.pythonhosted.org/packages/da/a6/cf32198b0b6e18d4fbfa9a21a992a7fca535b9bb2b0cdd217d4a3445b5ca/numpy-2.4.1-cp313-cp313-win_amd64.whl", hash = "sha256:92a0e65272fd60bfa0d9278e0484c2f52fe03b97aedc02b357f33fe752c52ffb", size = 12307230, upload-time = "2026-01-10T06:43:29.298Z" }, + { url = "https://files.pythonhosted.org/packages/44/6c/534d692bfb7d0afe30611320c5fb713659dcb5104d7cc182aff2aea092f5/numpy-2.4.1-cp313-cp313-win_arm64.whl", hash = "sha256:20d4649c773f66cc2fc36f663e091f57c3b7655f936a4c681b4250855d1da8f5", size = 10313125, upload-time = "2026-01-10T06:43:31.782Z" }, + { url = "https://files.pythonhosted.org/packages/da/a1/354583ac5c4caa566de6ddfbc42744409b515039e085fab6e0ff942e0df5/numpy-2.4.1-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:f93bc6892fe7b0663e5ffa83b61aab510aacffd58c16e012bb9352d489d90cb7", size = 12496156, upload-time = "2026-01-10T06:43:34.237Z" }, + { url = "https://files.pythonhosted.org/packages/51/b0/42807c6e8cce58c00127b1dc24d365305189991f2a7917aa694a109c8d7d/numpy-2.4.1-cp313-cp313t-macosx_14_0_arm64.whl", hash = "sha256:178de8f87948163d98a4c9ab5bee4ce6519ca918926ec8df195af582de28544d", size = 5324663, upload-time = "2026-01-10T06:43:36.211Z" }, + { url = "https://files.pythonhosted.org/packages/fe/55/7a621694010d92375ed82f312b2f28017694ed784775269115323e37f5e2/numpy-2.4.1-cp313-cp313t-macosx_14_0_x86_64.whl", hash = "sha256:98b35775e03ab7f868908b524fc0a84d38932d8daf7b7e1c3c3a1b6c7a2c9f15", size = 6645224, upload-time = "2026-01-10T06:43:37.884Z" }, + { url = "https://files.pythonhosted.org/packages/50/96/9fa8635ed9d7c847d87e30c834f7109fac5e88549d79ef3324ab5c20919f/numpy-2.4.1-cp313-cp313t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:941c2a93313d030f219f3a71fd3d91a728b82979a5e8034eb2e60d394a2b83f9", size = 14462352, upload-time = "2026-01-10T06:43:39.479Z" }, + { url = "https://files.pythonhosted.org/packages/03/d1/8cf62d8bb2062da4fb82dd5d49e47c923f9c0738032f054e0a75342faba7/numpy-2.4.1-cp313-cp313t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:529050522e983e00a6c1c6b67411083630de8b57f65e853d7b03d9281b8694d2", size = 16407279, upload-time = "2026-01-10T06:43:41.93Z" }, + { url = "https://files.pythonhosted.org/packages/86/1c/95c86e17c6b0b31ce6ef219da00f71113b220bcb14938c8d9a05cee0ff53/numpy-2.4.1-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:2302dc0224c1cbc49bb94f7064f3f923a971bfae45c33870dcbff63a2a550505", size = 16248316, upload-time = "2026-01-10T06:43:44.121Z" }, + { url = "https://files.pythonhosted.org/packages/30/b4/e7f5ff8697274c9d0fa82398b6a372a27e5cef069b37df6355ccb1f1db1a/numpy-2.4.1-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:9171a42fcad32dcf3fa86f0a4faa5e9f8facefdb276f54b8b390d90447cff4e2", size = 18329884, upload-time = "2026-01-10T06:43:46.613Z" }, + { url = "https://files.pythonhosted.org/packages/37/a4/b073f3e9d77f9aec8debe8ca7f9f6a09e888ad1ba7488f0c3b36a94c03ac/numpy-2.4.1-cp313-cp313t-win32.whl", hash = "sha256:382ad67d99ef49024f11d1ce5dcb5ad8432446e4246a4b014418ba3a1175a1f4", size = 6081138, upload-time = "2026-01-10T06:43:48.854Z" }, + { url = "https://files.pythonhosted.org/packages/16/16/af42337b53844e67752a092481ab869c0523bc95c4e5c98e4dac4e9581ac/numpy-2.4.1-cp313-cp313t-win_amd64.whl", hash = "sha256:62fea415f83ad8fdb6c20840578e5fbaf5ddd65e0ec6c3c47eda0f69da172510", size = 12447478, upload-time = "2026-01-10T06:43:50.476Z" }, + { url = "https://files.pythonhosted.org/packages/6c/f8/fa85b2eac68ec631d0b631abc448552cb17d39afd17ec53dcbcc3537681a/numpy-2.4.1-cp313-cp313t-win_arm64.whl", hash = "sha256:a7870e8c5fc11aef57d6fea4b4085e537a3a60ad2cdd14322ed531fdca68d261", size = 10382981, upload-time = "2026-01-10T06:43:52.575Z" }, + { url = "https://files.pythonhosted.org/packages/1b/a7/ef08d25698e0e4b4efbad8d55251d20fe2a15f6d9aa7c9b30cd03c165e6f/numpy-2.4.1-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:3869ea1ee1a1edc16c29bbe3a2f2a4e515cc3a44d43903ad41e0cacdbaf733dc", size = 16652046, upload-time = "2026-01-10T06:43:54.797Z" }, + { url = "https://files.pythonhosted.org/packages/8f/39/e378b3e3ca13477e5ac70293ec027c438d1927f18637e396fe90b1addd72/numpy-2.4.1-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:e867df947d427cdd7a60e3e271729090b0f0df80f5f10ab7dd436f40811699c3", size = 12378858, upload-time = "2026-01-10T06:43:57.099Z" }, + { url = "https://files.pythonhosted.org/packages/c3/74/7ec6154f0006910ed1fdbb7591cf4432307033102b8a22041599935f8969/numpy-2.4.1-cp314-cp314-macosx_14_0_arm64.whl", hash = "sha256:e3bd2cb07841166420d2fa7146c96ce00cb3410664cbc1a6be028e456c4ee220", size = 5207417, upload-time = "2026-01-10T06:43:59.037Z" }, + { url = "https://files.pythonhosted.org/packages/f7/b7/053ac11820d84e42f8feea5cb81cc4fcd1091499b45b1ed8c7415b1bf831/numpy-2.4.1-cp314-cp314-macosx_14_0_x86_64.whl", hash = "sha256:f0a90aba7d521e6954670550e561a4cb925713bd944445dbe9e729b71f6cabee", size = 6542643, upload-time = "2026-01-10T06:44:01.852Z" }, + { url = "https://files.pythonhosted.org/packages/c0/c4/2e7908915c0e32ca636b92e4e4a3bdec4cb1e7eb0f8aedf1ed3c68a0d8cd/numpy-2.4.1-cp314-cp314-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:5d558123217a83b2d1ba316b986e9248a1ed1971ad495963d555ccd75dcb1556", size = 14418963, upload-time = "2026-01-10T06:44:04.047Z" }, + { url = "https://files.pythonhosted.org/packages/eb/c0/3ed5083d94e7ffd7c404e54619c088e11f2e1939a9544f5397f4adb1b8ba/numpy-2.4.1-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:2f44de05659b67d20499cbc96d49f2650769afcb398b79b324bb6e297bfe3844", size = 16363811, upload-time = "2026-01-10T06:44:06.207Z" }, + { url = "https://files.pythonhosted.org/packages/0e/68/42b66f1852bf525050a67315a4fb94586ab7e9eaa541b1bef530fab0c5dd/numpy-2.4.1-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:69e7419c9012c4aaf695109564e3387f1259f001b4326dfa55907b098af082d3", size = 16197643, upload-time = "2026-01-10T06:44:08.33Z" }, + { url = "https://files.pythonhosted.org/packages/d2/40/e8714fc933d85f82c6bfc7b998a0649ad9769a32f3494ba86598aaf18a48/numpy-2.4.1-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:2ffd257026eb1b34352e749d7cc1678b5eeec3e329ad8c9965a797e08ccba205", size = 18289601, upload-time = "2026-01-10T06:44:10.841Z" }, + { url = "https://files.pythonhosted.org/packages/80/9a/0d44b468cad50315127e884802351723daca7cf1c98d102929468c81d439/numpy-2.4.1-cp314-cp314-win32.whl", hash = "sha256:727c6c3275ddefa0dc078524a85e064c057b4f4e71ca5ca29a19163c607be745", size = 6005722, upload-time = "2026-01-10T06:44:13.332Z" }, + { url = "https://files.pythonhosted.org/packages/7e/bb/c6513edcce5a831810e2dddc0d3452ce84d208af92405a0c2e58fd8e7881/numpy-2.4.1-cp314-cp314-win_amd64.whl", hash = "sha256:7d5d7999df434a038d75a748275cd6c0094b0ecdb0837342b332a82defc4dc4d", size = 12438590, upload-time = "2026-01-10T06:44:15.006Z" }, + { url = "https://files.pythonhosted.org/packages/e9/da/a598d5cb260780cf4d255102deba35c1d072dc028c4547832f45dd3323a8/numpy-2.4.1-cp314-cp314-win_arm64.whl", hash = "sha256:ce9ce141a505053b3c7bce3216071f3bf5c182b8b28930f14cd24d43932cd2df", size = 10596180, upload-time = "2026-01-10T06:44:17.386Z" }, + { url = "https://files.pythonhosted.org/packages/de/bc/ea3f2c96fcb382311827231f911723aeff596364eb6e1b6d1d91128aa29b/numpy-2.4.1-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:4e53170557d37ae404bf8d542ca5b7c629d6efa1117dac6a83e394142ea0a43f", size = 12498774, upload-time = "2026-01-10T06:44:19.467Z" }, + { url = "https://files.pythonhosted.org/packages/aa/ab/ef9d939fe4a812648c7a712610b2ca6140b0853c5efea361301006c02ae5/numpy-2.4.1-cp314-cp314t-macosx_14_0_arm64.whl", hash = "sha256:a73044b752f5d34d4232f25f18160a1cc418ea4507f5f11e299d8ac36875f8a0", size = 5327274, upload-time = "2026-01-10T06:44:23.189Z" }, + { url = "https://files.pythonhosted.org/packages/bd/31/d381368e2a95c3b08b8cf7faac6004849e960f4a042d920337f71cef0cae/numpy-2.4.1-cp314-cp314t-macosx_14_0_x86_64.whl", hash = "sha256:fb1461c99de4d040666ca0444057b06541e5642f800b71c56e6ea92d6a853a0c", size = 6648306, upload-time = "2026-01-10T06:44:25.012Z" }, + { url = "https://files.pythonhosted.org/packages/c8/e5/0989b44ade47430be6323d05c23207636d67d7362a1796ccbccac6773dd2/numpy-2.4.1-cp314-cp314t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:423797bdab2eeefbe608d7c1ec7b2b4fd3c58d51460f1ee26c7500a1d9c9ee93", size = 14464653, upload-time = "2026-01-10T06:44:26.706Z" }, + { url = "https://files.pythonhosted.org/packages/10/a7/cfbe475c35371cae1358e61f20c5f075badc18c4797ab4354140e1d283cf/numpy-2.4.1-cp314-cp314t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:52b5f61bdb323b566b528899cc7db2ba5d1015bda7ea811a8bcf3c89c331fa42", size = 16405144, upload-time = "2026-01-10T06:44:29.378Z" }, + { url = "https://files.pythonhosted.org/packages/f8/a3/0c63fe66b534888fa5177cc7cef061541064dbe2b4b60dcc60ffaf0d2157/numpy-2.4.1-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:42d7dd5fa36d16d52a84f821eb96031836fd405ee6955dd732f2023724d0aa01", size = 16247425, upload-time = "2026-01-10T06:44:31.721Z" }, + { url = "https://files.pythonhosted.org/packages/6b/2b/55d980cfa2c93bd40ff4c290bf824d792bd41d2fe3487b07707559071760/numpy-2.4.1-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:e7b6b5e28bbd47b7532698e5db2fe1db693d84b58c254e4389d99a27bb9b8f6b", size = 18330053, upload-time = "2026-01-10T06:44:34.617Z" }, + { url = "https://files.pythonhosted.org/packages/23/12/8b5fc6b9c487a09a7957188e0943c9ff08432c65e34567cabc1623b03a51/numpy-2.4.1-cp314-cp314t-win32.whl", hash = "sha256:5de60946f14ebe15e713a6f22850c2372fa72f4ff9a432ab44aa90edcadaa65a", size = 6152482, upload-time = "2026-01-10T06:44:36.798Z" }, + { url = "https://files.pythonhosted.org/packages/00/a5/9f8ca5856b8940492fc24fbe13c1bc34d65ddf4079097cf9e53164d094e1/numpy-2.4.1-cp314-cp314t-win_amd64.whl", hash = "sha256:8f085da926c0d491ffff3096f91078cc97ea67e7e6b65e490bc8dcda65663be2", size = 12627117, upload-time = "2026-01-10T06:44:38.828Z" }, + { url = "https://files.pythonhosted.org/packages/ad/0d/eca3d962f9eef265f01a8e0d20085c6dd1f443cbffc11b6dede81fd82356/numpy-2.4.1-cp314-cp314t-win_arm64.whl", hash = "sha256:6436cffb4f2bf26c974344439439c95e152c9a527013f26b3577be6c2ca64295", size = 10667121, upload-time = "2026-01-10T06:44:41.644Z" }, ] [[package]] @@ -922,43 +885,54 @@ wheels = [ [[package]] name = "pandas" -version = "2.3.2" +version = "3.0.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "numpy" }, { name = "python-dateutil" }, - { name = "pytz" }, - { name = "tzdata" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/79/8e/0e90233ac205ad182bd6b422532695d2b9414944a280488105d598c70023/pandas-2.3.2.tar.gz", hash = "sha256:ab7b58f8f82706890924ccdfb5f48002b83d2b5a3845976a9fb705d36c34dcdb", size = 4488684, upload-time = "2025-08-21T10:28:29.257Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/7a/59/f3e010879f118c2d400902d2d871c2226cef29b08c09fb8dc41111730400/pandas-2.3.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:1333e9c299adcbb68ee89a9bb568fc3f20f9cbb419f1dd5225071e6cddb2a743", size = 11563308, upload-time = "2025-08-21T10:26:56.656Z" }, - { url = "https://files.pythonhosted.org/packages/38/18/48f10f1cc5c397af59571d638d211f494dba481f449c19adbd282aa8f4ca/pandas-2.3.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:76972bcbd7de8e91ad5f0ca884a9f2c477a2125354af624e022c49e5bd0dfff4", size = 10820319, upload-time = "2025-08-21T10:26:59.162Z" }, - { url = "https://files.pythonhosted.org/packages/95/3b/1e9b69632898b048e223834cd9702052bcf06b15e1ae716eda3196fb972e/pandas-2.3.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b98bdd7c456a05eef7cd21fd6b29e3ca243591fe531c62be94a2cc987efb5ac2", size = 11790097, upload-time = "2025-08-21T10:27:02.204Z" }, - { url = "https://files.pythonhosted.org/packages/8b/ef/0e2ffb30b1f7fbc9a588bd01e3c14a0d96854d09a887e15e30cc19961227/pandas-2.3.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1d81573b3f7db40d020983f78721e9bfc425f411e616ef019a10ebf597aedb2e", size = 12397958, upload-time = "2025-08-21T10:27:05.409Z" }, - { url = "https://files.pythonhosted.org/packages/23/82/e6b85f0d92e9afb0e7f705a51d1399b79c7380c19687bfbf3d2837743249/pandas-2.3.2-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:e190b738675a73b581736cc8ec71ae113d6c3768d0bd18bffa5b9a0927b0b6ea", size = 13225600, upload-time = "2025-08-21T10:27:07.791Z" }, - { url = "https://files.pythonhosted.org/packages/e8/f1/f682015893d9ed51611948bd83683670842286a8edd4f68c2c1c3b231eef/pandas-2.3.2-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:c253828cb08f47488d60f43c5fc95114c771bbfff085da54bfc79cb4f9e3a372", size = 13879433, upload-time = "2025-08-21T10:27:10.347Z" }, - { url = "https://files.pythonhosted.org/packages/a7/e7/ae86261695b6c8a36d6a4c8d5f9b9ede8248510d689a2f379a18354b37d7/pandas-2.3.2-cp311-cp311-win_amd64.whl", hash = "sha256:9467697b8083f9667b212633ad6aa4ab32436dcbaf4cd57325debb0ddef2012f", size = 11336557, upload-time = "2025-08-21T10:27:12.983Z" }, - { url = "https://files.pythonhosted.org/packages/ec/db/614c20fb7a85a14828edd23f1c02db58a30abf3ce76f38806155d160313c/pandas-2.3.2-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:3fbb977f802156e7a3f829e9d1d5398f6192375a3e2d1a9ee0803e35fe70a2b9", size = 11587652, upload-time = "2025-08-21T10:27:15.888Z" }, - { url = "https://files.pythonhosted.org/packages/99/b0/756e52f6582cade5e746f19bad0517ff27ba9c73404607c0306585c201b3/pandas-2.3.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:1b9b52693123dd234b7c985c68b709b0b009f4521000d0525f2b95c22f15944b", size = 10717686, upload-time = "2025-08-21T10:27:18.486Z" }, - { url = "https://files.pythonhosted.org/packages/37/4c/dd5ccc1e357abfeee8353123282de17997f90ff67855f86154e5a13b81e5/pandas-2.3.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0bd281310d4f412733f319a5bc552f86d62cddc5f51d2e392c8787335c994175", size = 11278722, upload-time = "2025-08-21T10:27:21.149Z" }, - { url = "https://files.pythonhosted.org/packages/d3/a4/f7edcfa47e0a88cda0be8b068a5bae710bf264f867edfdf7b71584ace362/pandas-2.3.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:96d31a6b4354e3b9b8a2c848af75d31da390657e3ac6f30c05c82068b9ed79b9", size = 11987803, upload-time = "2025-08-21T10:27:23.767Z" }, - { url = "https://files.pythonhosted.org/packages/f6/61/1bce4129f93ab66f1c68b7ed1c12bac6a70b1b56c5dab359c6bbcd480b52/pandas-2.3.2-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:df4df0b9d02bb873a106971bb85d448378ef14b86ba96f035f50bbd3688456b4", size = 12766345, upload-time = "2025-08-21T10:27:26.6Z" }, - { url = "https://files.pythonhosted.org/packages/8e/46/80d53de70fee835531da3a1dae827a1e76e77a43ad22a8cd0f8142b61587/pandas-2.3.2-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:213a5adf93d020b74327cb2c1b842884dbdd37f895f42dcc2f09d451d949f811", size = 13439314, upload-time = "2025-08-21T10:27:29.213Z" }, - { url = "https://files.pythonhosted.org/packages/28/30/8114832daff7489f179971dbc1d854109b7f4365a546e3ea75b6516cea95/pandas-2.3.2-cp312-cp312-win_amd64.whl", hash = "sha256:8c13b81a9347eb8c7548f53fd9a4f08d4dfe996836543f805c987bafa03317ae", size = 10983326, upload-time = "2025-08-21T10:27:31.901Z" }, - { url = "https://files.pythonhosted.org/packages/27/64/a2f7bf678af502e16b472527735d168b22b7824e45a4d7e96a4fbb634b59/pandas-2.3.2-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:0c6ecbac99a354a051ef21c5307601093cb9e0f4b1855984a084bfec9302699e", size = 11531061, upload-time = "2025-08-21T10:27:34.647Z" }, - { url = "https://files.pythonhosted.org/packages/54/4c/c3d21b2b7769ef2f4c2b9299fcadd601efa6729f1357a8dbce8dd949ed70/pandas-2.3.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:c6f048aa0fd080d6a06cc7e7537c09b53be6642d330ac6f54a600c3ace857ee9", size = 10668666, upload-time = "2025-08-21T10:27:37.203Z" }, - { url = "https://files.pythonhosted.org/packages/50/e2/f775ba76ecfb3424d7f5862620841cf0edb592e9abd2d2a5387d305fe7a8/pandas-2.3.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0064187b80a5be6f2f9c9d6bdde29372468751dfa89f4211a3c5871854cfbf7a", size = 11332835, upload-time = "2025-08-21T10:27:40.188Z" }, - { url = "https://files.pythonhosted.org/packages/8f/52/0634adaace9be2d8cac9ef78f05c47f3a675882e068438b9d7ec7ef0c13f/pandas-2.3.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4ac8c320bded4718b298281339c1a50fb00a6ba78cb2a63521c39bec95b0209b", size = 12057211, upload-time = "2025-08-21T10:27:43.117Z" }, - { url = "https://files.pythonhosted.org/packages/0b/9d/2df913f14b2deb9c748975fdb2491da1a78773debb25abbc7cbc67c6b549/pandas-2.3.2-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:114c2fe4f4328cf98ce5716d1532f3ab79c5919f95a9cfee81d9140064a2e4d6", size = 12749277, upload-time = "2025-08-21T10:27:45.474Z" }, - { url = "https://files.pythonhosted.org/packages/87/af/da1a2417026bd14d98c236dba88e39837182459d29dcfcea510b2ac9e8a1/pandas-2.3.2-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:48fa91c4dfb3b2b9bfdb5c24cd3567575f4e13f9636810462ffed8925352be5a", size = 13415256, upload-time = "2025-08-21T10:27:49.885Z" }, - { url = "https://files.pythonhosted.org/packages/22/3c/f2af1ce8840ef648584a6156489636b5692c162771918aa95707c165ad2b/pandas-2.3.2-cp313-cp313-win_amd64.whl", hash = "sha256:12d039facec710f7ba305786837d0225a3444af7bbd9c15c32ca2d40d157ed8b", size = 10982579, upload-time = "2025-08-21T10:28:08.435Z" }, - { url = "https://files.pythonhosted.org/packages/f3/98/8df69c4097a6719e357dc249bf437b8efbde808038268e584421696cbddf/pandas-2.3.2-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:c624b615ce97864eb588779ed4046186f967374185c047070545253a52ab2d57", size = 12028163, upload-time = "2025-08-21T10:27:52.232Z" }, - { url = "https://files.pythonhosted.org/packages/0e/23/f95cbcbea319f349e10ff90db488b905c6883f03cbabd34f6b03cbc3c044/pandas-2.3.2-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:0cee69d583b9b128823d9514171cabb6861e09409af805b54459bd0c821a35c2", size = 11391860, upload-time = "2025-08-21T10:27:54.673Z" }, - { url = "https://files.pythonhosted.org/packages/ad/1b/6a984e98c4abee22058aa75bfb8eb90dce58cf8d7296f8bc56c14bc330b0/pandas-2.3.2-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2319656ed81124982900b4c37f0e0c58c015af9a7bbc62342ba5ad07ace82ba9", size = 11309830, upload-time = "2025-08-21T10:27:56.957Z" }, - { url = "https://files.pythonhosted.org/packages/15/d5/f0486090eb18dd8710bf60afeaf638ba6817047c0c8ae5c6a25598665609/pandas-2.3.2-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b37205ad6f00d52f16b6d09f406434ba928c1a1966e2771006a9033c736d30d2", size = 11883216, upload-time = "2025-08-21T10:27:59.302Z" }, - { url = "https://files.pythonhosted.org/packages/10/86/692050c119696da19e20245bbd650d8dfca6ceb577da027c3a73c62a047e/pandas-2.3.2-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:837248b4fc3a9b83b9c6214699a13f069dc13510a6a6d7f9ba33145d2841a012", size = 12699743, upload-time = "2025-08-21T10:28:02.447Z" }, - { url = "https://files.pythonhosted.org/packages/cd/d7/612123674d7b17cf345aad0a10289b2a384bff404e0463a83c4a3a59d205/pandas-2.3.2-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:d2c3554bd31b731cd6490d94a28f3abb8dd770634a9e06eb6d2911b9827db370", size = 13186141, upload-time = "2025-08-21T10:28:05.377Z" }, + { name = "tzdata", marker = "sys_platform == 'emscripten' or sys_platform == 'win32'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/de/da/b1dc0481ab8d55d0f46e343cfe67d4551a0e14fcee52bd38ca1bd73258d8/pandas-3.0.0.tar.gz", hash = "sha256:0facf7e87d38f721f0af46fe70d97373a37701b1c09f7ed7aeeb292ade5c050f", size = 4633005, upload-time = "2026-01-21T15:52:04.726Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/0b/38/db33686f4b5fa64d7af40d96361f6a4615b8c6c8f1b3d334eee46ae6160e/pandas-3.0.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:9803b31f5039b3c3b10cc858c5e40054adb4b29b4d81cb2fd789f4121c8efbcd", size = 10334013, upload-time = "2026-01-21T15:50:34.771Z" }, + { url = "https://files.pythonhosted.org/packages/a5/7b/9254310594e9774906bacdd4e732415e1f86ab7dbb4b377ef9ede58cd8ec/pandas-3.0.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:14c2a4099cd38a1d18ff108168ea417909b2dea3bd1ebff2ccf28ddb6a74d740", size = 9874154, upload-time = "2026-01-21T15:50:36.67Z" }, + { url = "https://files.pythonhosted.org/packages/63/d4/726c5a67a13bc66643e66d2e9ff115cead482a44fc56991d0c4014f15aaf/pandas-3.0.0-cp312-cp312-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:d257699b9a9960e6125686098d5714ac59d05222bef7a5e6af7a7fd87c650801", size = 10384433, upload-time = "2026-01-21T15:50:39.132Z" }, + { url = "https://files.pythonhosted.org/packages/bf/2e/9211f09bedb04f9832122942de8b051804b31a39cfbad199a819bb88d9f3/pandas-3.0.0-cp312-cp312-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:69780c98f286076dcafca38d8b8eee1676adf220199c0a39f0ecbf976b68151a", size = 10864519, upload-time = "2026-01-21T15:50:41.043Z" }, + { url = "https://files.pythonhosted.org/packages/00/8d/50858522cdc46ac88b9afdc3015e298959a70a08cd21e008a44e9520180c/pandas-3.0.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:4a66384f017240f3858a4c8a7cf21b0591c3ac885cddb7758a589f0f71e87ebb", size = 11394124, upload-time = "2026-01-21T15:50:43.377Z" }, + { url = "https://files.pythonhosted.org/packages/86/3f/83b2577db02503cd93d8e95b0f794ad9d4be0ba7cb6c8bcdcac964a34a42/pandas-3.0.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:be8c515c9bc33989d97b89db66ea0cececb0f6e3c2a87fcc8b69443a6923e95f", size = 11920444, upload-time = "2026-01-21T15:50:45.932Z" }, + { url = "https://files.pythonhosted.org/packages/64/2d/4f8a2f192ed12c90a0aab47f5557ece0e56b0370c49de9454a09de7381b2/pandas-3.0.0-cp312-cp312-win_amd64.whl", hash = "sha256:a453aad8c4f4e9f166436994a33884442ea62aa8b27d007311e87521b97246e1", size = 9730970, upload-time = "2026-01-21T15:50:47.962Z" }, + { url = "https://files.pythonhosted.org/packages/d4/64/ff571be435cf1e643ca98d0945d76732c0b4e9c37191a89c8550b105eed1/pandas-3.0.0-cp312-cp312-win_arm64.whl", hash = "sha256:da768007b5a33057f6d9053563d6b74dd6d029c337d93c6d0d22a763a5c2ecc0", size = 9041950, upload-time = "2026-01-21T15:50:50.422Z" }, + { url = "https://files.pythonhosted.org/packages/6f/fa/7f0ac4ca8877c57537aaff2a842f8760e630d8e824b730eb2e859ffe96ca/pandas-3.0.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:b78d646249b9a2bc191040988c7bb524c92fa8534fb0898a0741d7e6f2ffafa6", size = 10307129, upload-time = "2026-01-21T15:50:52.877Z" }, + { url = "https://files.pythonhosted.org/packages/6f/11/28a221815dcea4c0c9414dfc845e34a84a6a7dabc6da3194498ed5ba4361/pandas-3.0.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:bc9cba7b355cb4162442a88ce495e01cb605f17ac1e27d6596ac963504e0305f", size = 9850201, upload-time = "2026-01-21T15:50:54.807Z" }, + { url = "https://files.pythonhosted.org/packages/ba/da/53bbc8c5363b7e5bd10f9ae59ab250fc7a382ea6ba08e4d06d8694370354/pandas-3.0.0-cp313-cp313-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:3c9a1a149aed3b6c9bf246033ff91e1b02d529546c5d6fb6b74a28fea0cf4c70", size = 10354031, upload-time = "2026-01-21T15:50:57.463Z" }, + { url = "https://files.pythonhosted.org/packages/f7/a3/51e02ebc2a14974170d51e2410dfdab58870ea9bcd37cda15bd553d24dc4/pandas-3.0.0-cp313-cp313-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:95683af6175d884ee89471842acfca29172a85031fccdabc35e50c0984470a0e", size = 10861165, upload-time = "2026-01-21T15:50:59.32Z" }, + { url = "https://files.pythonhosted.org/packages/a5/fe/05a51e3cac11d161472b8297bd41723ea98013384dd6d76d115ce3482f9b/pandas-3.0.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:1fbbb5a7288719e36b76b4f18d46ede46e7f916b6c8d9915b756b0a6c3f792b3", size = 11359359, upload-time = "2026-01-21T15:51:02.014Z" }, + { url = "https://files.pythonhosted.org/packages/ee/56/ba620583225f9b85a4d3e69c01df3e3870659cc525f67929b60e9f21dcd1/pandas-3.0.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:8e8b9808590fa364416b49b2a35c1f4cf2785a6c156935879e57f826df22038e", size = 11912907, upload-time = "2026-01-21T15:51:05.175Z" }, + { url = "https://files.pythonhosted.org/packages/c9/8c/c6638d9f67e45e07656b3826405c5cc5f57f6fd07c8b2572ade328c86e22/pandas-3.0.0-cp313-cp313-win_amd64.whl", hash = "sha256:98212a38a709feb90ae658cb6227ea3657c22ba8157d4b8f913cd4c950de5e7e", size = 9732138, upload-time = "2026-01-21T15:51:07.569Z" }, + { url = "https://files.pythonhosted.org/packages/7b/bf/bd1335c3bf1770b6d8fed2799993b11c4971af93bb1b729b9ebbc02ca2ec/pandas-3.0.0-cp313-cp313-win_arm64.whl", hash = "sha256:177d9df10b3f43b70307a149d7ec49a1229a653f907aa60a48f1877d0e6be3be", size = 9033568, upload-time = "2026-01-21T15:51:09.484Z" }, + { url = "https://files.pythonhosted.org/packages/8e/c6/f5e2171914d5e29b9171d495344097d54e3ffe41d2d85d8115baba4dc483/pandas-3.0.0-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:2713810ad3806767b89ad3b7b69ba153e1c6ff6d9c20f9c2140379b2a98b6c98", size = 10741936, upload-time = "2026-01-21T15:51:11.693Z" }, + { url = "https://files.pythonhosted.org/packages/51/88/9a0164f99510a1acb9f548691f022c756c2314aad0d8330a24616c14c462/pandas-3.0.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:15d59f885ee5011daf8335dff47dcb8a912a27b4ad7826dc6cbe809fd145d327", size = 10393884, upload-time = "2026-01-21T15:51:14.197Z" }, + { url = "https://files.pythonhosted.org/packages/e0/53/b34d78084d88d8ae2b848591229da8826d1e65aacf00b3abe34023467648/pandas-3.0.0-cp313-cp313t-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:24e6547fb64d2c92665dd2adbfa4e85fa4fd70a9c070e7cfb03b629a0bbab5eb", size = 10310740, upload-time = "2026-01-21T15:51:16.093Z" }, + { url = "https://files.pythonhosted.org/packages/5b/d3/bee792e7c3d6930b74468d990604325701412e55d7aaf47460a22311d1a5/pandas-3.0.0-cp313-cp313t-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:48ee04b90e2505c693d3f8e8f524dab8cb8aaf7ddcab52c92afa535e717c4812", size = 10700014, upload-time = "2026-01-21T15:51:18.818Z" }, + { url = "https://files.pythonhosted.org/packages/55/db/2570bc40fb13aaed1cbc3fbd725c3a60ee162477982123c3adc8971e7ac1/pandas-3.0.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:66f72fb172959af42a459e27a8d8d2c7e311ff4c1f7db6deb3b643dbc382ae08", size = 11323737, upload-time = "2026-01-21T15:51:20.784Z" }, + { url = "https://files.pythonhosted.org/packages/bc/2e/297ac7f21c8181b62a4cccebad0a70caf679adf3ae5e83cb676194c8acc3/pandas-3.0.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:4a4a400ca18230976724a5066f20878af785f36c6756e498e94c2a5e5d57779c", size = 11771558, upload-time = "2026-01-21T15:51:22.977Z" }, + { url = "https://files.pythonhosted.org/packages/0a/46/e1c6876d71c14332be70239acce9ad435975a80541086e5ffba2f249bcf6/pandas-3.0.0-cp313-cp313t-win_amd64.whl", hash = "sha256:940eebffe55528074341a5a36515f3e4c5e25e958ebbc764c9502cfc35ba3faa", size = 10473771, upload-time = "2026-01-21T15:51:25.285Z" }, + { url = "https://files.pythonhosted.org/packages/c0/db/0270ad9d13c344b7a36fa77f5f8344a46501abf413803e885d22864d10bf/pandas-3.0.0-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:597c08fb9fef0edf1e4fa2f9828dd27f3d78f9b8c9b4a748d435ffc55732310b", size = 10312075, upload-time = "2026-01-21T15:51:28.5Z" }, + { url = "https://files.pythonhosted.org/packages/09/9f/c176f5e9717f7c91becfe0f55a52ae445d3f7326b4a2cf355978c51b7913/pandas-3.0.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:447b2d68ac5edcbf94655fe909113a6dba6ef09ad7f9f60c80477825b6c489fe", size = 9900213, upload-time = "2026-01-21T15:51:30.955Z" }, + { url = "https://files.pythonhosted.org/packages/d9/e7/63ad4cc10b257b143e0a5ebb04304ad806b4e1a61c5da25f55896d2ca0f4/pandas-3.0.0-cp314-cp314-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:debb95c77ff3ed3ba0d9aa20c3a2f19165cc7956362f9873fce1ba0a53819d70", size = 10428768, upload-time = "2026-01-21T15:51:33.018Z" }, + { url = "https://files.pythonhosted.org/packages/9e/0e/4e4c2d8210f20149fd2248ef3fff26623604922bd564d915f935a06dd63d/pandas-3.0.0-cp314-cp314-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:fedabf175e7cd82b69b74c30adbaa616de301291a5231138d7242596fc296a8d", size = 10882954, upload-time = "2026-01-21T15:51:35.287Z" }, + { url = "https://files.pythonhosted.org/packages/c6/60/c9de8ac906ba1f4d2250f8a951abe5135b404227a55858a75ad26f84db47/pandas-3.0.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:412d1a89aab46889f3033a386912efcdfa0f1131c5705ff5b668dda88305e986", size = 11430293, upload-time = "2026-01-21T15:51:37.57Z" }, + { url = "https://files.pythonhosted.org/packages/a1/69/806e6637c70920e5787a6d6896fd707f8134c2c55cd761e7249a97b7dc5a/pandas-3.0.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:e979d22316f9350c516479dd3a92252be2937a9531ed3a26ec324198a99cdd49", size = 11952452, upload-time = "2026-01-21T15:51:39.618Z" }, + { url = "https://files.pythonhosted.org/packages/cb/de/918621e46af55164c400ab0ef389c9d969ab85a43d59ad1207d4ddbe30a5/pandas-3.0.0-cp314-cp314-win_amd64.whl", hash = "sha256:083b11415b9970b6e7888800c43c82e81a06cd6b06755d84804444f0007d6bb7", size = 9851081, upload-time = "2026-01-21T15:51:41.758Z" }, + { url = "https://files.pythonhosted.org/packages/91/a1/3562a18dd0bd8c73344bfa26ff90c53c72f827df119d6d6b1dacc84d13e3/pandas-3.0.0-cp314-cp314-win_arm64.whl", hash = "sha256:5db1e62cb99e739fa78a28047e861b256d17f88463c76b8dafc7c1338086dca8", size = 9174610, upload-time = "2026-01-21T15:51:44.312Z" }, + { url = "https://files.pythonhosted.org/packages/ce/26/430d91257eaf366f1737d7a1c158677caaf6267f338ec74e3a1ec444111c/pandas-3.0.0-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:697b8f7d346c68274b1b93a170a70974cdc7d7354429894d5927c1effdcccd73", size = 10761999, upload-time = "2026-01-21T15:51:46.899Z" }, + { url = "https://files.pythonhosted.org/packages/ec/1a/954eb47736c2b7f7fe6a9d56b0cb6987773c00faa3c6451a43db4beb3254/pandas-3.0.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:8cb3120f0d9467ed95e77f67a75e030b67545bcfa08964e349252d674171def2", size = 10410279, upload-time = "2026-01-21T15:51:48.89Z" }, + { url = "https://files.pythonhosted.org/packages/20/fc/b96f3a5a28b250cd1b366eb0108df2501c0f38314a00847242abab71bb3a/pandas-3.0.0-cp314-cp314t-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:33fd3e6baa72899746b820c31e4b9688c8e1b7864d7aec2de7ab5035c285277a", size = 10330198, upload-time = "2026-01-21T15:51:51.015Z" }, + { url = "https://files.pythonhosted.org/packages/90/b3/d0e2952f103b4fbef1ef22d0c2e314e74fc9064b51cee30890b5e3286ee6/pandas-3.0.0-cp314-cp314t-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:a8942e333dc67ceda1095227ad0febb05a3b36535e520154085db632c40ad084", size = 10728513, upload-time = "2026-01-21T15:51:53.387Z" }, + { url = "https://files.pythonhosted.org/packages/76/81/832894f286df828993dc5fd61c63b231b0fb73377e99f6c6c369174cf97e/pandas-3.0.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:783ac35c4d0fe0effdb0d67161859078618b1b6587a1af15928137525217a721", size = 11345550, upload-time = "2026-01-21T15:51:55.329Z" }, + { url = "https://files.pythonhosted.org/packages/34/a0/ed160a00fb4f37d806406bc0a79a8b62fe67f29d00950f8d16203ff3409b/pandas-3.0.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:125eb901e233f155b268bbef9abd9afb5819db74f0e677e89a61b246228c71ac", size = 11799386, upload-time = "2026-01-21T15:51:57.457Z" }, + { url = "https://files.pythonhosted.org/packages/36/c8/2ac00d7255252c5e3cf61b35ca92ca25704b0188f7454ca4aec08a33cece/pandas-3.0.0-cp314-cp314t-win_amd64.whl", hash = "sha256:b86d113b6c109df3ce0ad5abbc259fe86a1bd4adfd4a31a89da42f84f65509bb", size = 10873041, upload-time = "2026-01-21T15:52:00.034Z" }, + { url = "https://files.pythonhosted.org/packages/e6/3f/a80ac00acbc6b35166b42850e98a4f466e2c0d9c64054161ba9620f95680/pandas-3.0.0-cp314-cp314t-win_arm64.whl", hash = "sha256:1c39eab3ad38f2d7a249095f0a3d8f8c22cc0f847e98ccf5bbe732b272e2d9fa", size = 9441003, upload-time = "2026-01-21T15:52:02.281Z" }, ] [[package]] @@ -975,7 +949,7 @@ name = "pexpect" version = "4.9.0" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "ptyprocess" }, + { name = "ptyprocess", marker = "sys_platform != 'emscripten' and sys_platform != 'win32'" }, ] 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 = [ @@ -984,91 +958,76 @@ wheels = [ [[package]] name = "pillow" -version = "11.3.0" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/f3/0d/d0d6dea55cd152ce3d6767bb38a8fc10e33796ba4ba210cbab9354b6d238/pillow-11.3.0.tar.gz", hash = "sha256:3828ee7586cd0b2091b6209e5ad53e20d0649bbe87164a459d0676e035e8f523", size = 47113069, upload-time = "2025-07-01T09:16:30.666Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/db/26/77f8ed17ca4ffd60e1dcd220a6ec6d71210ba398cfa33a13a1cd614c5613/pillow-11.3.0-cp311-cp311-macosx_10_10_x86_64.whl", hash = "sha256:1cd110edf822773368b396281a2293aeb91c90a2db00d78ea43e7e861631b722", size = 5316531, upload-time = "2025-07-01T09:13:59.203Z" }, - { url = "https://files.pythonhosted.org/packages/cb/39/ee475903197ce709322a17a866892efb560f57900d9af2e55f86db51b0a5/pillow-11.3.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:9c412fddd1b77a75aa904615ebaa6001f169b26fd467b4be93aded278266b288", size = 4686560, upload-time = "2025-07-01T09:14:01.101Z" }, - { url = "https://files.pythonhosted.org/packages/d5/90/442068a160fd179938ba55ec8c97050a612426fae5ec0a764e345839f76d/pillow-11.3.0-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:7d1aa4de119a0ecac0a34a9c8bde33f34022e2e8f99104e47a3ca392fd60e37d", size = 5870978, upload-time = "2025-07-03T13:09:55.638Z" }, - { url = "https://files.pythonhosted.org/packages/13/92/dcdd147ab02daf405387f0218dcf792dc6dd5b14d2573d40b4caeef01059/pillow-11.3.0-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:91da1d88226663594e3f6b4b8c3c8d85bd504117d043740a8e0ec449087cc494", size = 7641168, upload-time = "2025-07-03T13:10:00.37Z" }, - { url = "https://files.pythonhosted.org/packages/6e/db/839d6ba7fd38b51af641aa904e2960e7a5644d60ec754c046b7d2aee00e5/pillow-11.3.0-cp311-cp311-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:643f189248837533073c405ec2f0bb250ba54598cf80e8c1e043381a60632f58", size = 5973053, upload-time = "2025-07-01T09:14:04.491Z" }, - { url = "https://files.pythonhosted.org/packages/f2/2f/d7675ecae6c43e9f12aa8d58b6012683b20b6edfbdac7abcb4e6af7a3784/pillow-11.3.0-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:106064daa23a745510dabce1d84f29137a37224831d88eb4ce94bb187b1d7e5f", size = 6640273, upload-time = "2025-07-01T09:14:06.235Z" }, - { url = "https://files.pythonhosted.org/packages/45/ad/931694675ede172e15b2ff03c8144a0ddaea1d87adb72bb07655eaffb654/pillow-11.3.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:cd8ff254faf15591e724dc7c4ddb6bf4793efcbe13802a4ae3e863cd300b493e", size = 6082043, upload-time = "2025-07-01T09:14:07.978Z" }, - { url = "https://files.pythonhosted.org/packages/3a/04/ba8f2b11fc80d2dd462d7abec16351b45ec99cbbaea4387648a44190351a/pillow-11.3.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:932c754c2d51ad2b2271fd01c3d121daaa35e27efae2a616f77bf164bc0b3e94", size = 6715516, upload-time = "2025-07-01T09:14:10.233Z" }, - { url = "https://files.pythonhosted.org/packages/48/59/8cd06d7f3944cc7d892e8533c56b0acb68399f640786313275faec1e3b6f/pillow-11.3.0-cp311-cp311-win32.whl", hash = "sha256:b4b8f3efc8d530a1544e5962bd6b403d5f7fe8b9e08227c6b255f98ad82b4ba0", size = 6274768, upload-time = "2025-07-01T09:14:11.921Z" }, - { url = "https://files.pythonhosted.org/packages/f1/cc/29c0f5d64ab8eae20f3232da8f8571660aa0ab4b8f1331da5c2f5f9a938e/pillow-11.3.0-cp311-cp311-win_amd64.whl", hash = "sha256:1a992e86b0dd7aeb1f053cd506508c0999d710a8f07b4c791c63843fc6a807ac", size = 6986055, upload-time = "2025-07-01T09:14:13.623Z" }, - { url = "https://files.pythonhosted.org/packages/c6/df/90bd886fabd544c25addd63e5ca6932c86f2b701d5da6c7839387a076b4a/pillow-11.3.0-cp311-cp311-win_arm64.whl", hash = "sha256:30807c931ff7c095620fe04448e2c2fc673fcbb1ffe2a7da3fb39613489b1ddd", size = 2423079, upload-time = "2025-07-01T09:14:15.268Z" }, - { url = "https://files.pythonhosted.org/packages/40/fe/1bc9b3ee13f68487a99ac9529968035cca2f0a51ec36892060edcc51d06a/pillow-11.3.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:fdae223722da47b024b867c1ea0be64e0df702c5e0a60e27daad39bf960dd1e4", size = 5278800, upload-time = "2025-07-01T09:14:17.648Z" }, - { url = "https://files.pythonhosted.org/packages/2c/32/7e2ac19b5713657384cec55f89065fb306b06af008cfd87e572035b27119/pillow-11.3.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:921bd305b10e82b4d1f5e802b6850677f965d8394203d182f078873851dada69", size = 4686296, upload-time = "2025-07-01T09:14:19.828Z" }, - { url = "https://files.pythonhosted.org/packages/8e/1e/b9e12bbe6e4c2220effebc09ea0923a07a6da1e1f1bfbc8d7d29a01ce32b/pillow-11.3.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:eb76541cba2f958032d79d143b98a3a6b3ea87f0959bbe256c0b5e416599fd5d", size = 5871726, upload-time = "2025-07-03T13:10:04.448Z" }, - { url = "https://files.pythonhosted.org/packages/8d/33/e9200d2bd7ba00dc3ddb78df1198a6e80d7669cce6c2bdbeb2530a74ec58/pillow-11.3.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:67172f2944ebba3d4a7b54f2e95c786a3a50c21b88456329314caaa28cda70f6", size = 7644652, upload-time = "2025-07-03T13:10:10.391Z" }, - { url = "https://files.pythonhosted.org/packages/41/f1/6f2427a26fc683e00d985bc391bdd76d8dd4e92fac33d841127eb8fb2313/pillow-11.3.0-cp312-cp312-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:97f07ed9f56a3b9b5f49d3661dc9607484e85c67e27f3e8be2c7d28ca032fec7", size = 5977787, upload-time = "2025-07-01T09:14:21.63Z" }, - { url = "https://files.pythonhosted.org/packages/e4/c9/06dd4a38974e24f932ff5f98ea3c546ce3f8c995d3f0985f8e5ba48bba19/pillow-11.3.0-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:676b2815362456b5b3216b4fd5bd89d362100dc6f4945154ff172e206a22c024", size = 6645236, upload-time = "2025-07-01T09:14:23.321Z" }, - { url = "https://files.pythonhosted.org/packages/40/e7/848f69fb79843b3d91241bad658e9c14f39a32f71a301bcd1d139416d1be/pillow-11.3.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:3e184b2f26ff146363dd07bde8b711833d7b0202e27d13540bfe2e35a323a809", size = 6086950, upload-time = "2025-07-01T09:14:25.237Z" }, - { url = "https://files.pythonhosted.org/packages/0b/1a/7cff92e695a2a29ac1958c2a0fe4c0b2393b60aac13b04a4fe2735cad52d/pillow-11.3.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:6be31e3fc9a621e071bc17bb7de63b85cbe0bfae91bb0363c893cbe67247780d", size = 6723358, upload-time = "2025-07-01T09:14:27.053Z" }, - { url = "https://files.pythonhosted.org/packages/26/7d/73699ad77895f69edff76b0f332acc3d497f22f5d75e5360f78cbcaff248/pillow-11.3.0-cp312-cp312-win32.whl", hash = "sha256:7b161756381f0918e05e7cb8a371fff367e807770f8fe92ecb20d905d0e1c149", size = 6275079, upload-time = "2025-07-01T09:14:30.104Z" }, - { url = "https://files.pythonhosted.org/packages/8c/ce/e7dfc873bdd9828f3b6e5c2bbb74e47a98ec23cc5c74fc4e54462f0d9204/pillow-11.3.0-cp312-cp312-win_amd64.whl", hash = "sha256:a6444696fce635783440b7f7a9fc24b3ad10a9ea3f0ab66c5905be1c19ccf17d", size = 6986324, upload-time = "2025-07-01T09:14:31.899Z" }, - { url = "https://files.pythonhosted.org/packages/16/8f/b13447d1bf0b1f7467ce7d86f6e6edf66c0ad7cf44cf5c87a37f9bed9936/pillow-11.3.0-cp312-cp312-win_arm64.whl", hash = "sha256:2aceea54f957dd4448264f9bf40875da0415c83eb85f55069d89c0ed436e3542", size = 2423067, upload-time = "2025-07-01T09:14:33.709Z" }, - { url = "https://files.pythonhosted.org/packages/1e/93/0952f2ed8db3a5a4c7a11f91965d6184ebc8cd7cbb7941a260d5f018cd2d/pillow-11.3.0-cp313-cp313-ios_13_0_arm64_iphoneos.whl", hash = "sha256:1c627742b539bba4309df89171356fcb3cc5a9178355b2727d1b74a6cf155fbd", size = 2128328, upload-time = "2025-07-01T09:14:35.276Z" }, - { url = "https://files.pythonhosted.org/packages/4b/e8/100c3d114b1a0bf4042f27e0f87d2f25e857e838034e98ca98fe7b8c0a9c/pillow-11.3.0-cp313-cp313-ios_13_0_arm64_iphonesimulator.whl", hash = "sha256:30b7c02f3899d10f13d7a48163c8969e4e653f8b43416d23d13d1bbfdc93b9f8", size = 2170652, upload-time = "2025-07-01T09:14:37.203Z" }, - { url = "https://files.pythonhosted.org/packages/aa/86/3f758a28a6e381758545f7cdb4942e1cb79abd271bea932998fc0db93cb6/pillow-11.3.0-cp313-cp313-ios_13_0_x86_64_iphonesimulator.whl", hash = "sha256:7859a4cc7c9295f5838015d8cc0a9c215b77e43d07a25e460f35cf516df8626f", size = 2227443, upload-time = "2025-07-01T09:14:39.344Z" }, - { url = "https://files.pythonhosted.org/packages/01/f4/91d5b3ffa718df2f53b0dc109877993e511f4fd055d7e9508682e8aba092/pillow-11.3.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:ec1ee50470b0d050984394423d96325b744d55c701a439d2bd66089bff963d3c", size = 5278474, upload-time = "2025-07-01T09:14:41.843Z" }, - { url = "https://files.pythonhosted.org/packages/f9/0e/37d7d3eca6c879fbd9dba21268427dffda1ab00d4eb05b32923d4fbe3b12/pillow-11.3.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:7db51d222548ccfd274e4572fdbf3e810a5e66b00608862f947b163e613b67dd", size = 4686038, upload-time = "2025-07-01T09:14:44.008Z" }, - { url = "https://files.pythonhosted.org/packages/ff/b0/3426e5c7f6565e752d81221af9d3676fdbb4f352317ceafd42899aaf5d8a/pillow-11.3.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:2d6fcc902a24ac74495df63faad1884282239265c6839a0a6416d33faedfae7e", size = 5864407, upload-time = "2025-07-03T13:10:15.628Z" }, - { url = "https://files.pythonhosted.org/packages/fc/c1/c6c423134229f2a221ee53f838d4be9d82bab86f7e2f8e75e47b6bf6cd77/pillow-11.3.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:f0f5d8f4a08090c6d6d578351a2b91acf519a54986c055af27e7a93feae6d3f1", size = 7639094, upload-time = "2025-07-03T13:10:21.857Z" }, - { url = "https://files.pythonhosted.org/packages/ba/c9/09e6746630fe6372c67c648ff9deae52a2bc20897d51fa293571977ceb5d/pillow-11.3.0-cp313-cp313-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:c37d8ba9411d6003bba9e518db0db0c58a680ab9fe5179f040b0463644bc9805", size = 5973503, upload-time = "2025-07-01T09:14:45.698Z" }, - { url = "https://files.pythonhosted.org/packages/d5/1c/a2a29649c0b1983d3ef57ee87a66487fdeb45132df66ab30dd37f7dbe162/pillow-11.3.0-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:13f87d581e71d9189ab21fe0efb5a23e9f28552d5be6979e84001d3b8505abe8", size = 6642574, upload-time = "2025-07-01T09:14:47.415Z" }, - { url = "https://files.pythonhosted.org/packages/36/de/d5cc31cc4b055b6c6fd990e3e7f0f8aaf36229a2698501bcb0cdf67c7146/pillow-11.3.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:023f6d2d11784a465f09fd09a34b150ea4672e85fb3d05931d89f373ab14abb2", size = 6084060, upload-time = "2025-07-01T09:14:49.636Z" }, - { url = "https://files.pythonhosted.org/packages/d5/ea/502d938cbaeec836ac28a9b730193716f0114c41325db428e6b280513f09/pillow-11.3.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:45dfc51ac5975b938e9809451c51734124e73b04d0f0ac621649821a63852e7b", size = 6721407, upload-time = "2025-07-01T09:14:51.962Z" }, - { url = "https://files.pythonhosted.org/packages/45/9c/9c5e2a73f125f6cbc59cc7087c8f2d649a7ae453f83bd0362ff7c9e2aee2/pillow-11.3.0-cp313-cp313-win32.whl", hash = "sha256:a4d336baed65d50d37b88ca5b60c0fa9d81e3a87d4a7930d3880d1624d5b31f3", size = 6273841, upload-time = "2025-07-01T09:14:54.142Z" }, - { url = "https://files.pythonhosted.org/packages/23/85/397c73524e0cd212067e0c969aa245b01d50183439550d24d9f55781b776/pillow-11.3.0-cp313-cp313-win_amd64.whl", hash = "sha256:0bce5c4fd0921f99d2e858dc4d4d64193407e1b99478bc5cacecba2311abde51", size = 6978450, upload-time = "2025-07-01T09:14:56.436Z" }, - { url = "https://files.pythonhosted.org/packages/17/d2/622f4547f69cd173955194b78e4d19ca4935a1b0f03a302d655c9f6aae65/pillow-11.3.0-cp313-cp313-win_arm64.whl", hash = "sha256:1904e1264881f682f02b7f8167935cce37bc97db457f8e7849dc3a6a52b99580", size = 2423055, upload-time = "2025-07-01T09:14:58.072Z" }, - { url = "https://files.pythonhosted.org/packages/dd/80/a8a2ac21dda2e82480852978416cfacd439a4b490a501a288ecf4fe2532d/pillow-11.3.0-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:4c834a3921375c48ee6b9624061076bc0a32a60b5532b322cc0ea64e639dd50e", size = 5281110, upload-time = "2025-07-01T09:14:59.79Z" }, - { url = "https://files.pythonhosted.org/packages/44/d6/b79754ca790f315918732e18f82a8146d33bcd7f4494380457ea89eb883d/pillow-11.3.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:5e05688ccef30ea69b9317a9ead994b93975104a677a36a8ed8106be9260aa6d", size = 4689547, upload-time = "2025-07-01T09:15:01.648Z" }, - { url = "https://files.pythonhosted.org/packages/49/20/716b8717d331150cb00f7fdd78169c01e8e0c219732a78b0e59b6bdb2fd6/pillow-11.3.0-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:1019b04af07fc0163e2810167918cb5add8d74674b6267616021ab558dc98ced", size = 5901554, upload-time = "2025-07-03T13:10:27.018Z" }, - { url = "https://files.pythonhosted.org/packages/74/cf/a9f3a2514a65bb071075063a96f0a5cf949c2f2fce683c15ccc83b1c1cab/pillow-11.3.0-cp313-cp313t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:f944255db153ebb2b19c51fe85dd99ef0ce494123f21b9db4877ffdfc5590c7c", size = 7669132, upload-time = "2025-07-03T13:10:33.01Z" }, - { url = "https://files.pythonhosted.org/packages/98/3c/da78805cbdbee9cb43efe8261dd7cc0b4b93f2ac79b676c03159e9db2187/pillow-11.3.0-cp313-cp313t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:1f85acb69adf2aaee8b7da124efebbdb959a104db34d3a2cb0f3793dbae422a8", size = 6005001, upload-time = "2025-07-01T09:15:03.365Z" }, - { url = "https://files.pythonhosted.org/packages/6c/fa/ce044b91faecf30e635321351bba32bab5a7e034c60187fe9698191aef4f/pillow-11.3.0-cp313-cp313t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:05f6ecbeff5005399bb48d198f098a9b4b6bdf27b8487c7f38ca16eeb070cd59", size = 6668814, upload-time = "2025-07-01T09:15:05.655Z" }, - { url = "https://files.pythonhosted.org/packages/7b/51/90f9291406d09bf93686434f9183aba27b831c10c87746ff49f127ee80cb/pillow-11.3.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:a7bc6e6fd0395bc052f16b1a8670859964dbd7003bd0af2ff08342eb6e442cfe", size = 6113124, upload-time = "2025-07-01T09:15:07.358Z" }, - { url = "https://files.pythonhosted.org/packages/cd/5a/6fec59b1dfb619234f7636d4157d11fb4e196caeee220232a8d2ec48488d/pillow-11.3.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:83e1b0161c9d148125083a35c1c5a89db5b7054834fd4387499e06552035236c", size = 6747186, upload-time = "2025-07-01T09:15:09.317Z" }, - { url = "https://files.pythonhosted.org/packages/49/6b/00187a044f98255225f172de653941e61da37104a9ea60e4f6887717e2b5/pillow-11.3.0-cp313-cp313t-win32.whl", hash = "sha256:2a3117c06b8fb646639dce83694f2f9eac405472713fcb1ae887469c0d4f6788", size = 6277546, upload-time = "2025-07-01T09:15:11.311Z" }, - { url = "https://files.pythonhosted.org/packages/e8/5c/6caaba7e261c0d75bab23be79f1d06b5ad2a2ae49f028ccec801b0e853d6/pillow-11.3.0-cp313-cp313t-win_amd64.whl", hash = "sha256:857844335c95bea93fb39e0fa2726b4d9d758850b34075a7e3ff4f4fa3aa3b31", size = 6985102, upload-time = "2025-07-01T09:15:13.164Z" }, - { url = "https://files.pythonhosted.org/packages/f3/7e/b623008460c09a0cb38263c93b828c666493caee2eb34ff67f778b87e58c/pillow-11.3.0-cp313-cp313t-win_arm64.whl", hash = "sha256:8797edc41f3e8536ae4b10897ee2f637235c94f27404cac7297f7b607dd0716e", size = 2424803, upload-time = "2025-07-01T09:15:15.695Z" }, - { url = "https://files.pythonhosted.org/packages/73/f4/04905af42837292ed86cb1b1dabe03dce1edc008ef14c473c5c7e1443c5d/pillow-11.3.0-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:d9da3df5f9ea2a89b81bb6087177fb1f4d1c7146d583a3fe5c672c0d94e55e12", size = 5278520, upload-time = "2025-07-01T09:15:17.429Z" }, - { url = "https://files.pythonhosted.org/packages/41/b0/33d79e377a336247df6348a54e6d2a2b85d644ca202555e3faa0cf811ecc/pillow-11.3.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:0b275ff9b04df7b640c59ec5a3cb113eefd3795a8df80bac69646ef699c6981a", size = 4686116, upload-time = "2025-07-01T09:15:19.423Z" }, - { url = "https://files.pythonhosted.org/packages/49/2d/ed8bc0ab219ae8768f529597d9509d184fe8a6c4741a6864fea334d25f3f/pillow-11.3.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:0743841cabd3dba6a83f38a92672cccbd69af56e3e91777b0ee7f4dba4385632", size = 5864597, upload-time = "2025-07-03T13:10:38.404Z" }, - { url = "https://files.pythonhosted.org/packages/b5/3d/b932bb4225c80b58dfadaca9d42d08d0b7064d2d1791b6a237f87f661834/pillow-11.3.0-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:2465a69cf967b8b49ee1b96d76718cd98c4e925414ead59fdf75cf0fd07df673", size = 7638246, upload-time = "2025-07-03T13:10:44.987Z" }, - { url = "https://files.pythonhosted.org/packages/09/b5/0487044b7c096f1b48f0d7ad416472c02e0e4bf6919541b111efd3cae690/pillow-11.3.0-cp314-cp314-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:41742638139424703b4d01665b807c6468e23e699e8e90cffefe291c5832b027", size = 5973336, upload-time = "2025-07-01T09:15:21.237Z" }, - { url = "https://files.pythonhosted.org/packages/a8/2d/524f9318f6cbfcc79fbc004801ea6b607ec3f843977652fdee4857a7568b/pillow-11.3.0-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:93efb0b4de7e340d99057415c749175e24c8864302369e05914682ba642e5d77", size = 6642699, upload-time = "2025-07-01T09:15:23.186Z" }, - { url = "https://files.pythonhosted.org/packages/6f/d2/a9a4f280c6aefedce1e8f615baaa5474e0701d86dd6f1dede66726462bbd/pillow-11.3.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:7966e38dcd0fa11ca390aed7c6f20454443581d758242023cf36fcb319b1a874", size = 6083789, upload-time = "2025-07-01T09:15:25.1Z" }, - { url = "https://files.pythonhosted.org/packages/fe/54/86b0cd9dbb683a9d5e960b66c7379e821a19be4ac5810e2e5a715c09a0c0/pillow-11.3.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:98a9afa7b9007c67ed84c57c9e0ad86a6000da96eaa638e4f8abe5b65ff83f0a", size = 6720386, upload-time = "2025-07-01T09:15:27.378Z" }, - { url = "https://files.pythonhosted.org/packages/e7/95/88efcaf384c3588e24259c4203b909cbe3e3c2d887af9e938c2022c9dd48/pillow-11.3.0-cp314-cp314-win32.whl", hash = "sha256:02a723e6bf909e7cea0dac1b0e0310be9d7650cd66222a5f1c571455c0a45214", size = 6370911, upload-time = "2025-07-01T09:15:29.294Z" }, - { url = "https://files.pythonhosted.org/packages/2e/cc/934e5820850ec5eb107e7b1a72dd278140731c669f396110ebc326f2a503/pillow-11.3.0-cp314-cp314-win_amd64.whl", hash = "sha256:a418486160228f64dd9e9efcd132679b7a02a5f22c982c78b6fc7dab3fefb635", size = 7117383, upload-time = "2025-07-01T09:15:31.128Z" }, - { url = "https://files.pythonhosted.org/packages/d6/e9/9c0a616a71da2a5d163aa37405e8aced9a906d574b4a214bede134e731bc/pillow-11.3.0-cp314-cp314-win_arm64.whl", hash = "sha256:155658efb5e044669c08896c0c44231c5e9abcaadbc5cd3648df2f7c0b96b9a6", size = 2511385, upload-time = "2025-07-01T09:15:33.328Z" }, - { url = "https://files.pythonhosted.org/packages/1a/33/c88376898aff369658b225262cd4f2659b13e8178e7534df9e6e1fa289f6/pillow-11.3.0-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:59a03cdf019efbfeeed910bf79c7c93255c3d54bc45898ac2a4140071b02b4ae", size = 5281129, upload-time = "2025-07-01T09:15:35.194Z" }, - { url = "https://files.pythonhosted.org/packages/1f/70/d376247fb36f1844b42910911c83a02d5544ebd2a8bad9efcc0f707ea774/pillow-11.3.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:f8a5827f84d973d8636e9dc5764af4f0cf2318d26744b3d902931701b0d46653", size = 4689580, upload-time = "2025-07-01T09:15:37.114Z" }, - { url = "https://files.pythonhosted.org/packages/eb/1c/537e930496149fbac69efd2fc4329035bbe2e5475b4165439e3be9cb183b/pillow-11.3.0-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:ee92f2fd10f4adc4b43d07ec5e779932b4eb3dbfbc34790ada5a6669bc095aa6", size = 5902860, upload-time = "2025-07-03T13:10:50.248Z" }, - { url = "https://files.pythonhosted.org/packages/bd/57/80f53264954dcefeebcf9dae6e3eb1daea1b488f0be8b8fef12f79a3eb10/pillow-11.3.0-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:c96d333dcf42d01f47b37e0979b6bd73ec91eae18614864622d9b87bbd5bbf36", size = 7670694, upload-time = "2025-07-03T13:10:56.432Z" }, - { url = "https://files.pythonhosted.org/packages/70/ff/4727d3b71a8578b4587d9c276e90efad2d6fe0335fd76742a6da08132e8c/pillow-11.3.0-cp314-cp314t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:4c96f993ab8c98460cd0c001447bff6194403e8b1d7e149ade5f00594918128b", size = 6005888, upload-time = "2025-07-01T09:15:39.436Z" }, - { url = "https://files.pythonhosted.org/packages/05/ae/716592277934f85d3be51d7256f3636672d7b1abfafdc42cf3f8cbd4b4c8/pillow-11.3.0-cp314-cp314t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:41342b64afeba938edb034d122b2dda5db2139b9a4af999729ba8818e0056477", size = 6670330, upload-time = "2025-07-01T09:15:41.269Z" }, - { url = "https://files.pythonhosted.org/packages/e7/bb/7fe6cddcc8827b01b1a9766f5fdeb7418680744f9082035bdbabecf1d57f/pillow-11.3.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:068d9c39a2d1b358eb9f245ce7ab1b5c3246c7c8c7d9ba58cfa5b43146c06e50", size = 6114089, upload-time = "2025-07-01T09:15:43.13Z" }, - { url = "https://files.pythonhosted.org/packages/8b/f5/06bfaa444c8e80f1a8e4bff98da9c83b37b5be3b1deaa43d27a0db37ef84/pillow-11.3.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:a1bc6ba083b145187f648b667e05a2534ecc4b9f2784c2cbe3089e44868f2b9b", size = 6748206, upload-time = "2025-07-01T09:15:44.937Z" }, - { url = "https://files.pythonhosted.org/packages/f0/77/bc6f92a3e8e6e46c0ca78abfffec0037845800ea38c73483760362804c41/pillow-11.3.0-cp314-cp314t-win32.whl", hash = "sha256:118ca10c0d60b06d006be10a501fd6bbdfef559251ed31b794668ed569c87e12", size = 6377370, upload-time = "2025-07-01T09:15:46.673Z" }, - { url = "https://files.pythonhosted.org/packages/4a/82/3a721f7d69dca802befb8af08b7c79ebcab461007ce1c18bd91a5d5896f9/pillow-11.3.0-cp314-cp314t-win_amd64.whl", hash = "sha256:8924748b688aa210d79883357d102cd64690e56b923a186f35a82cbc10f997db", size = 7121500, upload-time = "2025-07-01T09:15:48.512Z" }, - { url = "https://files.pythonhosted.org/packages/89/c7/5572fa4a3f45740eaab6ae86fcdf7195b55beac1371ac8c619d880cfe948/pillow-11.3.0-cp314-cp314t-win_arm64.whl", hash = "sha256:79ea0d14d3ebad43ec77ad5272e6ff9bba5b679ef73375ea760261207fa8e0aa", size = 2512835, upload-time = "2025-07-01T09:15:50.399Z" }, - { url = "https://files.pythonhosted.org/packages/9e/e3/6fa84033758276fb31da12e5fb66ad747ae83b93c67af17f8c6ff4cc8f34/pillow-11.3.0-pp311-pypy311_pp73-macosx_10_15_x86_64.whl", hash = "sha256:7c8ec7a017ad1bd562f93dbd8505763e688d388cde6e4a010ae1486916e713e6", size = 5270566, upload-time = "2025-07-01T09:16:19.801Z" }, - { url = "https://files.pythonhosted.org/packages/5b/ee/e8d2e1ab4892970b561e1ba96cbd59c0d28cf66737fc44abb2aec3795a4e/pillow-11.3.0-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:9ab6ae226de48019caa8074894544af5b53a117ccb9d3b3dcb2871464c829438", size = 4654618, upload-time = "2025-07-01T09:16:21.818Z" }, - { url = "https://files.pythonhosted.org/packages/f2/6d/17f80f4e1f0761f02160fc433abd4109fa1548dcfdca46cfdadaf9efa565/pillow-11.3.0-pp311-pypy311_pp73-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:fe27fb049cdcca11f11a7bfda64043c37b30e6b91f10cb5bab275806c32f6ab3", size = 4874248, upload-time = "2025-07-03T13:11:20.738Z" }, - { url = "https://files.pythonhosted.org/packages/de/5f/c22340acd61cef960130585bbe2120e2fd8434c214802f07e8c03596b17e/pillow-11.3.0-pp311-pypy311_pp73-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:465b9e8844e3c3519a983d58b80be3f668e2a7a5db97f2784e7079fbc9f9822c", size = 6583963, upload-time = "2025-07-03T13:11:26.283Z" }, - { url = "https://files.pythonhosted.org/packages/31/5e/03966aedfbfcbb4d5f8aa042452d3361f325b963ebbadddac05b122e47dd/pillow-11.3.0-pp311-pypy311_pp73-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:5418b53c0d59b3824d05e029669efa023bbef0f3e92e75ec8428f3799487f361", size = 4957170, upload-time = "2025-07-01T09:16:23.762Z" }, - { url = "https://files.pythonhosted.org/packages/cc/2d/e082982aacc927fc2cab48e1e731bdb1643a1406acace8bed0900a61464e/pillow-11.3.0-pp311-pypy311_pp73-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:504b6f59505f08ae014f724b6207ff6222662aab5cc9542577fb084ed0676ac7", size = 5581505, upload-time = "2025-07-01T09:16:25.593Z" }, - { url = "https://files.pythonhosted.org/packages/34/e7/ae39f538fd6844e982063c3a5e4598b8ced43b9633baa3a85ef33af8c05c/pillow-11.3.0-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:c84d689db21a1c397d001aa08241044aa2069e7587b398c8cc63020390b1c1b8", size = 6984598, upload-time = "2025-07-01T09:16:27.732Z" }, +version = "12.1.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/d0/02/d52c733a2452ef1ffcc123b68e6606d07276b0e358db70eabad7e40042b7/pillow-12.1.0.tar.gz", hash = "sha256:5c5ae0a06e9ea030ab786b0251b32c7e4ce10e58d983c0d5c56029455180b5b9", size = 46977283, upload-time = "2026-01-02T09:13:29.892Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/20/31/dc53fe21a2f2996e1b7d92bf671cdb157079385183ef7c1ae08b485db510/pillow-12.1.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:a332ac4ccb84b6dde65dbace8431f3af08874bf9770719d32a635c4ef411b18b", size = 5262642, upload-time = "2026-01-02T09:11:10.138Z" }, + { url = "https://files.pythonhosted.org/packages/ab/c1/10e45ac9cc79419cedf5121b42dcca5a50ad2b601fa080f58c22fb27626e/pillow-12.1.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:907bfa8a9cb790748a9aa4513e37c88c59660da3bcfffbd24a7d9e6abf224551", size = 4657464, upload-time = "2026-01-02T09:11:12.319Z" }, + { url = "https://files.pythonhosted.org/packages/ad/26/7b82c0ab7ef40ebede7a97c72d473bda5950f609f8e0c77b04af574a0ddb/pillow-12.1.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:efdc140e7b63b8f739d09a99033aa430accce485ff78e6d311973a67b6bf3208", size = 6234878, upload-time = "2026-01-02T09:11:14.096Z" }, + { url = "https://files.pythonhosted.org/packages/76/25/27abc9792615b5e886ca9411ba6637b675f1b77af3104710ac7353fe5605/pillow-12.1.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:bef9768cab184e7ae6e559c032e95ba8d07b3023c289f79a2bd36e8bf85605a5", size = 8044868, upload-time = "2026-01-02T09:11:15.903Z" }, + { url = "https://files.pythonhosted.org/packages/0a/ea/f200a4c36d836100e7bc738fc48cd963d3ba6372ebc8298a889e0cfc3359/pillow-12.1.0-cp312-cp312-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:742aea052cf5ab5034a53c3846165bc3ce88d7c38e954120db0ab867ca242661", size = 6349468, upload-time = "2026-01-02T09:11:17.631Z" }, + { url = "https://files.pythonhosted.org/packages/11/8f/48d0b77ab2200374c66d344459b8958c86693be99526450e7aee714e03e4/pillow-12.1.0-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:a6dfc2af5b082b635af6e08e0d1f9f1c4e04d17d4e2ca0ef96131e85eda6eb17", size = 7041518, upload-time = "2026-01-02T09:11:19.389Z" }, + { url = "https://files.pythonhosted.org/packages/1d/23/c281182eb986b5d31f0a76d2a2c8cd41722d6fb8ed07521e802f9bba52de/pillow-12.1.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:609e89d9f90b581c8d16358c9087df76024cf058fa693dd3e1e1620823f39670", size = 6462829, upload-time = "2026-01-02T09:11:21.28Z" }, + { url = "https://files.pythonhosted.org/packages/25/ef/7018273e0faac099d7b00982abdcc39142ae6f3bd9ceb06de09779c4a9d6/pillow-12.1.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:43b4899cfd091a9693a1278c4982f3e50f7fb7cff5153b05174b4afc9593b616", size = 7166756, upload-time = "2026-01-02T09:11:23.559Z" }, + { url = "https://files.pythonhosted.org/packages/8f/c8/993d4b7ab2e341fe02ceef9576afcf5830cdec640be2ac5bee1820d693d4/pillow-12.1.0-cp312-cp312-win32.whl", hash = "sha256:aa0c9cc0b82b14766a99fbe6084409972266e82f459821cd26997a488a7261a7", size = 6328770, upload-time = "2026-01-02T09:11:25.661Z" }, + { url = "https://files.pythonhosted.org/packages/a7/87/90b358775a3f02765d87655237229ba64a997b87efa8ccaca7dd3e36e7a7/pillow-12.1.0-cp312-cp312-win_amd64.whl", hash = "sha256:d70534cea9e7966169ad29a903b99fc507e932069a881d0965a1a84bb57f6c6d", size = 7033406, upload-time = "2026-01-02T09:11:27.474Z" }, + { url = "https://files.pythonhosted.org/packages/5d/cf/881b457eccacac9e5b2ddd97d5071fb6d668307c57cbf4e3b5278e06e536/pillow-12.1.0-cp312-cp312-win_arm64.whl", hash = "sha256:65b80c1ee7e14a87d6a068dd3b0aea268ffcabfe0498d38661b00c5b4b22e74c", size = 2452612, upload-time = "2026-01-02T09:11:29.309Z" }, + { url = "https://files.pythonhosted.org/packages/dd/c7/2530a4aa28248623e9d7f27316b42e27c32ec410f695929696f2e0e4a778/pillow-12.1.0-cp313-cp313-ios_13_0_arm64_iphoneos.whl", hash = "sha256:7b5dd7cbae20285cdb597b10eb5a2c13aa9de6cde9bb64a3c1317427b1db1ae1", size = 4062543, upload-time = "2026-01-02T09:11:31.566Z" }, + { url = "https://files.pythonhosted.org/packages/8f/1f/40b8eae823dc1519b87d53c30ed9ef085506b05281d313031755c1705f73/pillow-12.1.0-cp313-cp313-ios_13_0_arm64_iphonesimulator.whl", hash = "sha256:29a4cef9cb672363926f0470afc516dbf7305a14d8c54f7abbb5c199cd8f8179", size = 4138373, upload-time = "2026-01-02T09:11:33.367Z" }, + { url = "https://files.pythonhosted.org/packages/d4/77/6fa60634cf06e52139fd0e89e5bbf055e8166c691c42fb162818b7fda31d/pillow-12.1.0-cp313-cp313-ios_13_0_x86_64_iphonesimulator.whl", hash = "sha256:681088909d7e8fa9e31b9799aaa59ba5234c58e5e4f1951b4c4d1082a2e980e0", size = 3601241, upload-time = "2026-01-02T09:11:35.011Z" }, + { url = "https://files.pythonhosted.org/packages/4f/bf/28ab865de622e14b747f0cd7877510848252d950e43002e224fb1c9ababf/pillow-12.1.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:983976c2ab753166dc66d36af6e8ec15bb511e4a25856e2227e5f7e00a160587", size = 5262410, upload-time = "2026-01-02T09:11:36.682Z" }, + { url = "https://files.pythonhosted.org/packages/1c/34/583420a1b55e715937a85bd48c5c0991598247a1fd2eb5423188e765ea02/pillow-12.1.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:db44d5c160a90df2d24a24760bbd37607d53da0b34fb546c4c232af7192298ac", size = 4657312, upload-time = "2026-01-02T09:11:38.535Z" }, + { url = "https://files.pythonhosted.org/packages/1d/fd/f5a0896839762885b3376ff04878f86ab2b097c2f9a9cdccf4eda8ba8dc0/pillow-12.1.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:6b7a9d1db5dad90e2991645874f708e87d9a3c370c243c2d7684d28f7e133e6b", size = 6232605, upload-time = "2026-01-02T09:11:40.602Z" }, + { url = "https://files.pythonhosted.org/packages/98/aa/938a09d127ac1e70e6ed467bd03834350b33ef646b31edb7452d5de43792/pillow-12.1.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:6258f3260986990ba2fa8a874f8b6e808cf5abb51a94015ca3dc3c68aa4f30ea", size = 8041617, upload-time = "2026-01-02T09:11:42.721Z" }, + { url = "https://files.pythonhosted.org/packages/17/e8/538b24cb426ac0186e03f80f78bc8dc7246c667f58b540bdd57c71c9f79d/pillow-12.1.0-cp313-cp313-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:e115c15e3bc727b1ca3e641a909f77f8ca72a64fff150f666fcc85e57701c26c", size = 6346509, upload-time = "2026-01-02T09:11:44.955Z" }, + { url = "https://files.pythonhosted.org/packages/01/9a/632e58ec89a32738cabfd9ec418f0e9898a2b4719afc581f07c04a05e3c9/pillow-12.1.0-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:6741e6f3074a35e47c77b23a4e4f2d90db3ed905cb1c5e6e0d49bff2045632bc", size = 7038117, upload-time = "2026-01-02T09:11:46.736Z" }, + { url = "https://files.pythonhosted.org/packages/c7/a2/d40308cf86eada842ca1f3ffa45d0ca0df7e4ab33c83f81e73f5eaed136d/pillow-12.1.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:935b9d1aed48fcfb3f838caac506f38e29621b44ccc4f8a64d575cb1b2a88644", size = 6460151, upload-time = "2026-01-02T09:11:48.625Z" }, + { url = "https://files.pythonhosted.org/packages/f1/88/f5b058ad6453a085c5266660a1417bdad590199da1b32fb4efcff9d33b05/pillow-12.1.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:5fee4c04aad8932da9f8f710af2c1a15a83582cfb884152a9caa79d4efcdbf9c", size = 7164534, upload-time = "2026-01-02T09:11:50.445Z" }, + { url = "https://files.pythonhosted.org/packages/19/ce/c17334caea1db789163b5d855a5735e47995b0b5dc8745e9a3605d5f24c0/pillow-12.1.0-cp313-cp313-win32.whl", hash = "sha256:a786bf667724d84aa29b5db1c61b7bfdde380202aaca12c3461afd6b71743171", size = 6332551, upload-time = "2026-01-02T09:11:52.234Z" }, + { url = "https://files.pythonhosted.org/packages/e5/07/74a9d941fa45c90a0d9465098fe1ec85de3e2afbdc15cc4766622d516056/pillow-12.1.0-cp313-cp313-win_amd64.whl", hash = "sha256:461f9dfdafa394c59cd6d818bdfdbab4028b83b02caadaff0ffd433faf4c9a7a", size = 7040087, upload-time = "2026-01-02T09:11:54.822Z" }, + { url = "https://files.pythonhosted.org/packages/88/09/c99950c075a0e9053d8e880595926302575bc742b1b47fe1bbcc8d388d50/pillow-12.1.0-cp313-cp313-win_arm64.whl", hash = "sha256:9212d6b86917a2300669511ed094a9406888362e085f2431a7da985a6b124f45", size = 2452470, upload-time = "2026-01-02T09:11:56.522Z" }, + { url = "https://files.pythonhosted.org/packages/b5/ba/970b7d85ba01f348dee4d65412476321d40ee04dcb51cd3735b9dc94eb58/pillow-12.1.0-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:00162e9ca6d22b7c3ee8e61faa3c3253cd19b6a37f126cad04f2f88b306f557d", size = 5264816, upload-time = "2026-01-02T09:11:58.227Z" }, + { url = "https://files.pythonhosted.org/packages/10/60/650f2fb55fdba7a510d836202aa52f0baac633e50ab1cf18415d332188fb/pillow-12.1.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:7d6daa89a00b58c37cb1747ec9fb7ac3bc5ffd5949f5888657dfddde6d1312e0", size = 4660472, upload-time = "2026-01-02T09:12:00.798Z" }, + { url = "https://files.pythonhosted.org/packages/2b/c0/5273a99478956a099d533c4f46cbaa19fd69d606624f4334b85e50987a08/pillow-12.1.0-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:e2479c7f02f9d505682dc47df8c0ea1fc5e264c4d1629a5d63fe3e2334b89554", size = 6268974, upload-time = "2026-01-02T09:12:02.572Z" }, + { url = "https://files.pythonhosted.org/packages/b4/26/0bf714bc2e73d5267887d47931d53c4ceeceea6978148ed2ab2a4e6463c4/pillow-12.1.0-cp313-cp313t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:f188d580bd870cda1e15183790d1cc2fa78f666e76077d103edf048eed9c356e", size = 8073070, upload-time = "2026-01-02T09:12:04.75Z" }, + { url = "https://files.pythonhosted.org/packages/43/cf/1ea826200de111a9d65724c54f927f3111dc5ae297f294b370a670c17786/pillow-12.1.0-cp313-cp313t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:0fde7ec5538ab5095cc02df38ee99b0443ff0e1c847a045554cf5f9af1f4aa82", size = 6380176, upload-time = "2026-01-02T09:12:06.626Z" }, + { url = "https://files.pythonhosted.org/packages/03/e0/7938dd2b2013373fd85d96e0f38d62b7a5a262af21ac274250c7ca7847c9/pillow-12.1.0-cp313-cp313t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:0ed07dca4a8464bada6139ab38f5382f83e5f111698caf3191cb8dbf27d908b4", size = 7067061, upload-time = "2026-01-02T09:12:08.624Z" }, + { url = "https://files.pythonhosted.org/packages/86/ad/a2aa97d37272a929a98437a8c0ac37b3cf012f4f8721e1bd5154699b2518/pillow-12.1.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:f45bd71d1fa5e5749587613037b172e0b3b23159d1c00ef2fc920da6f470e6f0", size = 6491824, upload-time = "2026-01-02T09:12:10.488Z" }, + { url = "https://files.pythonhosted.org/packages/a4/44/80e46611b288d51b115826f136fb3465653c28f491068a72d3da49b54cd4/pillow-12.1.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:277518bf4fe74aa91489e1b20577473b19ee70fb97c374aa50830b279f25841b", size = 7190911, upload-time = "2026-01-02T09:12:12.772Z" }, + { url = "https://files.pythonhosted.org/packages/86/77/eacc62356b4cf81abe99ff9dbc7402750044aed02cfd6a503f7c6fc11f3e/pillow-12.1.0-cp313-cp313t-win32.whl", hash = "sha256:7315f9137087c4e0ee73a761b163fc9aa3b19f5f606a7fc08d83fd3e4379af65", size = 6336445, upload-time = "2026-01-02T09:12:14.775Z" }, + { url = "https://files.pythonhosted.org/packages/e7/3c/57d81d0b74d218706dafccb87a87ea44262c43eef98eb3b164fd000e0491/pillow-12.1.0-cp313-cp313t-win_amd64.whl", hash = "sha256:0ddedfaa8b5f0b4ffbc2fa87b556dc59f6bb4ecb14a53b33f9189713ae8053c0", size = 7045354, upload-time = "2026-01-02T09:12:16.599Z" }, + { url = "https://files.pythonhosted.org/packages/ac/82/8b9b97bba2e3576a340f93b044a3a3a09841170ab4c1eb0d5c93469fd32f/pillow-12.1.0-cp313-cp313t-win_arm64.whl", hash = "sha256:80941e6d573197a0c28f394753de529bb436b1ca990ed6e765cf42426abc39f8", size = 2454547, upload-time = "2026-01-02T09:12:18.704Z" }, + { url = "https://files.pythonhosted.org/packages/8c/87/bdf971d8bbcf80a348cc3bacfcb239f5882100fe80534b0ce67a784181d8/pillow-12.1.0-cp314-cp314-ios_13_0_arm64_iphoneos.whl", hash = "sha256:5cb7bc1966d031aec37ddb9dcf15c2da5b2e9f7cc3ca7c54473a20a927e1eb91", size = 4062533, upload-time = "2026-01-02T09:12:20.791Z" }, + { url = "https://files.pythonhosted.org/packages/ff/4f/5eb37a681c68d605eb7034c004875c81f86ec9ef51f5be4a63eadd58859a/pillow-12.1.0-cp314-cp314-ios_13_0_arm64_iphonesimulator.whl", hash = "sha256:97e9993d5ed946aba26baf9c1e8cf18adbab584b99f452ee72f7ee8acb882796", size = 4138546, upload-time = "2026-01-02T09:12:23.664Z" }, + { url = "https://files.pythonhosted.org/packages/11/6d/19a95acb2edbace40dcd582d077b991646b7083c41b98da4ed7555b59733/pillow-12.1.0-cp314-cp314-ios_13_0_x86_64_iphonesimulator.whl", hash = "sha256:414b9a78e14ffeb98128863314e62c3f24b8a86081066625700b7985b3f529bd", size = 3601163, upload-time = "2026-01-02T09:12:26.338Z" }, + { url = "https://files.pythonhosted.org/packages/fc/36/2b8138e51cb42e4cc39c3297713455548be855a50558c3ac2beebdc251dd/pillow-12.1.0-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:e6bdb408f7c9dd2a5ff2b14a3b0bb6d4deb29fb9961e6eb3ae2031ae9a5cec13", size = 5266086, upload-time = "2026-01-02T09:12:28.782Z" }, + { url = "https://files.pythonhosted.org/packages/53/4b/649056e4d22e1caa90816bf99cef0884aed607ed38075bd75f091a607a38/pillow-12.1.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:3413c2ae377550f5487991d444428f1a8ae92784aac79caa8b1e3b89b175f77e", size = 4657344, upload-time = "2026-01-02T09:12:31.117Z" }, + { url = "https://files.pythonhosted.org/packages/6c/6b/c5742cea0f1ade0cd61485dc3d81f05261fc2276f537fbdc00802de56779/pillow-12.1.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:e5dcbe95016e88437ecf33544ba5db21ef1b8dd6e1b434a2cb2a3d605299e643", size = 6232114, upload-time = "2026-01-02T09:12:32.936Z" }, + { url = "https://files.pythonhosted.org/packages/bf/8f/9f521268ce22d63991601aafd3d48d5ff7280a246a1ef62d626d67b44064/pillow-12.1.0-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:d0a7735df32ccbcc98b98a1ac785cc4b19b580be1bdf0aeb5c03223220ea09d5", size = 8042708, upload-time = "2026-01-02T09:12:34.78Z" }, + { url = "https://files.pythonhosted.org/packages/1a/eb/257f38542893f021502a1bbe0c2e883c90b5cff26cc33b1584a841a06d30/pillow-12.1.0-cp314-cp314-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:0c27407a2d1b96774cbc4a7594129cc027339fd800cd081e44497722ea1179de", size = 6347762, upload-time = "2026-01-02T09:12:36.748Z" }, + { url = "https://files.pythonhosted.org/packages/c4/5a/8ba375025701c09b309e8d5163c5a4ce0102fa86bbf8800eb0d7ac87bc51/pillow-12.1.0-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:15c794d74303828eaa957ff8070846d0efe8c630901a1c753fdc63850e19ecd9", size = 7039265, upload-time = "2026-01-02T09:12:39.082Z" }, + { url = "https://files.pythonhosted.org/packages/cf/dc/cf5e4cdb3db533f539e88a7bbf9f190c64ab8a08a9bc7a4ccf55067872e4/pillow-12.1.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:c990547452ee2800d8506c4150280757f88532f3de2a58e3022e9b179107862a", size = 6462341, upload-time = "2026-01-02T09:12:40.946Z" }, + { url = "https://files.pythonhosted.org/packages/d0/47/0291a25ac9550677e22eda48510cfc4fa4b2ef0396448b7fbdc0a6946309/pillow-12.1.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:b63e13dd27da389ed9475b3d28510f0f954bca0041e8e551b2a4eb1eab56a39a", size = 7165395, upload-time = "2026-01-02T09:12:42.706Z" }, + { url = "https://files.pythonhosted.org/packages/4f/4c/e005a59393ec4d9416be06e6b45820403bb946a778e39ecec62f5b2b991e/pillow-12.1.0-cp314-cp314-win32.whl", hash = "sha256:1a949604f73eb07a8adab38c4fe50791f9919344398bdc8ac6b307f755fc7030", size = 6431413, upload-time = "2026-01-02T09:12:44.944Z" }, + { url = "https://files.pythonhosted.org/packages/1c/af/f23697f587ac5f9095d67e31b81c95c0249cd461a9798a061ed6709b09b5/pillow-12.1.0-cp314-cp314-win_amd64.whl", hash = "sha256:4f9f6a650743f0ddee5593ac9e954ba1bdbc5e150bc066586d4f26127853ab94", size = 7176779, upload-time = "2026-01-02T09:12:46.727Z" }, + { url = "https://files.pythonhosted.org/packages/b3/36/6a51abf8599232f3e9afbd16d52829376a68909fe14efe29084445db4b73/pillow-12.1.0-cp314-cp314-win_arm64.whl", hash = "sha256:808b99604f7873c800c4840f55ff389936ef1948e4e87645eaf3fccbc8477ac4", size = 2543105, upload-time = "2026-01-02T09:12:49.243Z" }, + { url = "https://files.pythonhosted.org/packages/82/54/2e1dd20c8749ff225080d6ba465a0cab4387f5db0d1c5fb1439e2d99923f/pillow-12.1.0-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:bc11908616c8a283cf7d664f77411a5ed2a02009b0097ff8abbba5e79128ccf2", size = 5268571, upload-time = "2026-01-02T09:12:51.11Z" }, + { url = "https://files.pythonhosted.org/packages/57/61/571163a5ef86ec0cf30d265ac2a70ae6fc9e28413d1dc94fa37fae6bda89/pillow-12.1.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:896866d2d436563fa2a43a9d72f417874f16b5545955c54a64941e87c1376c61", size = 4660426, upload-time = "2026-01-02T09:12:52.865Z" }, + { url = "https://files.pythonhosted.org/packages/5e/e1/53ee5163f794aef1bf84243f755ee6897a92c708505350dd1923f4afec48/pillow-12.1.0-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:8e178e3e99d3c0ea8fc64b88447f7cac8ccf058af422a6cedc690d0eadd98c51", size = 6269908, upload-time = "2026-01-02T09:12:54.884Z" }, + { url = "https://files.pythonhosted.org/packages/bc/0b/b4b4106ff0ee1afa1dc599fde6ab230417f800279745124f6c50bcffed8e/pillow-12.1.0-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:079af2fb0c599c2ec144ba2c02766d1b55498e373b3ac64687e43849fbbef5bc", size = 8074733, upload-time = "2026-01-02T09:12:56.802Z" }, + { url = "https://files.pythonhosted.org/packages/19/9f/80b411cbac4a732439e629a26ad3ef11907a8c7fc5377b7602f04f6fe4e7/pillow-12.1.0-cp314-cp314t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:bdec5e43377761c5dbca620efb69a77f6855c5a379e32ac5b158f54c84212b14", size = 6381431, upload-time = "2026-01-02T09:12:58.823Z" }, + { url = "https://files.pythonhosted.org/packages/8f/b7/d65c45db463b66ecb6abc17c6ba6917a911202a07662247e1355ce1789e7/pillow-12.1.0-cp314-cp314t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:565c986f4b45c020f5421a4cea13ef294dde9509a8577f29b2fc5edc7587fff8", size = 7068529, upload-time = "2026-01-02T09:13:00.885Z" }, + { url = "https://files.pythonhosted.org/packages/50/96/dfd4cd726b4a45ae6e3c669fc9e49deb2241312605d33aba50499e9d9bd1/pillow-12.1.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:43aca0a55ce1eefc0aefa6253661cb54571857b1a7b2964bd8a1e3ef4b729924", size = 6492981, upload-time = "2026-01-02T09:13:03.314Z" }, + { url = "https://files.pythonhosted.org/packages/4d/1c/b5dc52cf713ae46033359c5ca920444f18a6359ce1020dd3e9c553ea5bc6/pillow-12.1.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:0deedf2ea233722476b3a81e8cdfbad786f7adbed5d848469fa59fe52396e4ef", size = 7191878, upload-time = "2026-01-02T09:13:05.276Z" }, + { url = "https://files.pythonhosted.org/packages/53/26/c4188248bd5edaf543864fe4834aebe9c9cb4968b6f573ce014cc42d0720/pillow-12.1.0-cp314-cp314t-win32.whl", hash = "sha256:b17fbdbe01c196e7e159aacb889e091f28e61020a8abeac07b68079b6e626988", size = 6438703, upload-time = "2026-01-02T09:13:07.491Z" }, + { url = "https://files.pythonhosted.org/packages/b8/0e/69ed296de8ea05cb03ee139cee600f424ca166e632567b2d66727f08c7ed/pillow-12.1.0-cp314-cp314t-win_amd64.whl", hash = "sha256:27b9baecb428899db6c0de572d6d305cfaf38ca1596b5c0542a5182e3e74e8c6", size = 7182927, upload-time = "2026-01-02T09:13:09.841Z" }, + { url = "https://files.pythonhosted.org/packages/fc/f5/68334c015eed9b5cff77814258717dec591ded209ab5b6fb70e2ae873d1d/pillow-12.1.0-cp314-cp314t-win_arm64.whl", hash = "sha256:f61333d817698bdcdd0f9d7793e365ac3d2a21c1f1eb02b32ad6aefb8d8ea831", size = 2545104, upload-time = "2026-01-02T09:13:12.068Z" }, ] [[package]] name = "pint" -version = "0.25" +version = "0.25.2" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "flexcache" }, @@ -1076,18 +1035,18 @@ dependencies = [ { name = "platformdirs" }, { name = "typing-extensions" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/5a/cb/e6ffaf3d019e8501b1264dac529bf829ac2f1fe1d488cfcf67f1fccadacf/pint-0.25.tar.gz", hash = "sha256:22911a30d682ee0540d656571c19a7b1806ce00b2be88a16f67218108b7b8cc2", size = 253010, upload-time = "2025-08-15T19:49:12.72Z" } +sdist = { url = "https://files.pythonhosted.org/packages/5f/74/bc3f671997158aef171194c3c4041e549946f4784b8690baa0626a0a164b/pint-0.25.2.tar.gz", hash = "sha256:85a45d1da8fe9c9f7477fed8aef59ad2b939af3d6611507e1a9cbdacdcd3450a", size = 254467, upload-time = "2025-11-06T22:08:09.184Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/76/cc/c528311d798e22ec884b816e8aa2989e0f1f28cdc8e5969e2be5f10bce85/pint-0.25-py3-none-any.whl", hash = "sha256:cc20ae3dff010b9bbea41fb80c2de008f683cc83512cea73633d55aead80aa1e", size = 305462, upload-time = "2025-08-15T19:49:11.083Z" }, + { url = "https://files.pythonhosted.org/packages/ab/88/550d41e81e6d43335603a960cd9c75c1d88f9cf01bc9d4ee8e86290aba7d/pint-0.25.2-py3-none-any.whl", hash = "sha256:ca35ab1d8eeeb6f7d9942b3cb5f34ca42b61cdd5fb3eae79531553dcca04dda7", size = 306762, upload-time = "2025-11-06T22:08:07.745Z" }, ] [[package]] name = "platformdirs" -version = "4.4.0" +version = "4.5.1" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/23/e8/21db9c9987b0e728855bd57bff6984f67952bea55d6f75e055c46b5383e8/platformdirs-4.4.0.tar.gz", hash = "sha256:ca753cf4d81dc309bc67b0ea38fd15dc97bc30ce419a7f58d13eb3bf14c4febf", size = 21634, upload-time = "2025-08-26T14:32:04.268Z" } +sdist = { url = "https://files.pythonhosted.org/packages/cf/86/0248f086a84f01b37aaec0fa567b397df1a119f73c16f6c7a9aac73ea309/platformdirs-4.5.1.tar.gz", hash = "sha256:61d5cdcc6065745cdd94f0f878977f8de9437be93de97c1c12f853c9c0cdcbda", size = 21715, upload-time = "2025-12-05T13:52:58.638Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/40/4b/2028861e724d3bd36227adfa20d3fd24c3fc6d52032f4a93c133be5d17ce/platformdirs-4.4.0-py3-none-any.whl", hash = "sha256:abd01743f24e5287cd7a5db3752faf1a2d65353f38ec26d98e25a6db65958c85", size = 18654, upload-time = "2025-08-26T14:32:02.735Z" }, + { url = "https://files.pythonhosted.org/packages/cb/28/3bfe2fa5a7b9c46fe7e13c97bda14c895fb10fa2ebf1d0abb90e0cea7ee1/platformdirs-4.5.1-py3-none-any.whl", hash = "sha256:d03afa3963c806a9bed9d5125c8f4cb2fdaf74a55ab60e5d59b3fde758104d31", size = 18731, upload-time = "2025-12-05T13:52:56.823Z" }, ] [[package]] @@ -1166,42 +1125,54 @@ wheels = [ [[package]] name = "pyogrio" -version = "0.11.1" +version = "0.12.1" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "certifi" }, { name = "numpy" }, { name = "packaging" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/bf/1d/ae0340237207664e2da1b77f2cdbcb5f81fd0fc9f3200a48ca993a5e12ef/pyogrio-0.11.1.tar.gz", hash = "sha256:e1441dc9c866f10d8e6ae7ea9249a10c1f57ea921b1f19a5b0977ab91ef8082c", size = 287267, upload-time = "2025-08-02T20:19:20.167Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/d0/81/50441f029609bcb883ee2738bdee3f81a998a11e4052b6ad0ef0ae4c0ae5/pyogrio-0.11.1-cp311-cp311-macosx_12_0_arm64.whl", hash = "sha256:d36162ddc1a309bb941a3cfb550b8f88c862c67ef2f52df6460100e5e958bbc6", size = 19459279, upload-time = "2025-08-02T20:18:18.955Z" }, - { url = "https://files.pythonhosted.org/packages/0d/4a/a3a2fae13e42ee98574b18591ddb66bca88bc1fa812c017437b42c85569f/pyogrio-0.11.1-cp311-cp311-macosx_12_0_x86_64.whl", hash = "sha256:845c78d5e7c9ec1c7d00250c07e144e5fe504fdb4ccdc141d9413f85b8c55c91", size = 20646364, upload-time = "2025-08-02T20:18:21.171Z" }, - { url = "https://files.pythonhosted.org/packages/7d/f2/1dd5795f8cccf8f97d5ac7f28fee31fc1afc5f6bce9fab2ac4486ed3af44/pyogrio-0.11.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:50aa869509f189fa1bff4d90d2d4c7860b963e693af85f2957646306e882b631", size = 26999659, upload-time = "2025-08-02T20:18:25.482Z" }, - { url = "https://files.pythonhosted.org/packages/ea/ef/4f8d61afb6798edde8bd6d2721032e868ff78a25395d9512f7e5e50b23c4/pyogrio-0.11.1-cp311-cp311-manylinux_2_28_aarch64.whl", hash = "sha256:dd0f44dd2d849d32aea3f73647c74083996917e446479645bf93de6656160f2d", size = 26523036, upload-time = "2025-08-02T20:18:28.761Z" }, - { url = "https://files.pythonhosted.org/packages/e7/99/81d9a441ac7709407750f359813889b9a3f6076999cb9ae8893d5ba7c707/pyogrio-0.11.1-cp311-cp311-manylinux_2_28_x86_64.whl", hash = "sha256:36b910d4037694b2935b5b1c1eb757dcc2906dca05cb2992cbdaf1291b54ff97", size = 27678041, upload-time = "2025-08-02T20:18:31.103Z" }, - { url = "https://files.pythonhosted.org/packages/74/4e/a5d00c30e5ca3f4133a425fe41531b219139ad4451ea8edc3520f221f9dd/pyogrio-0.11.1-cp311-cp311-win_amd64.whl", hash = "sha256:cb744097f302f19dcc5c93ee5e9cfd707b864c9a418e399f0908406a60003728", size = 19226619, upload-time = "2025-08-02T20:18:34.261Z" }, - { url = "https://files.pythonhosted.org/packages/72/d3/2ba967ca4255cdfa130a6d8b437826488567b4bc1bb417c442bb43d62611/pyogrio-0.11.1-cp312-cp312-macosx_12_0_arm64.whl", hash = "sha256:f186456ebe5d5f61e7bd883bad25a59d43d6304178d4f0d3e03273f42b40a4cc", size = 19450110, upload-time = "2025-08-02T20:18:36.643Z" }, - { url = "https://files.pythonhosted.org/packages/5a/e1/3bc29ae71d24a91cf91f7413541e50acb7de2ce609587168ce2f4b405d3b/pyogrio-0.11.1-cp312-cp312-macosx_12_0_x86_64.whl", hash = "sha256:b8a199bc0e421eac444af96942b7553268e43d0cadf30d0d6d41017de05b7e9e", size = 20635348, upload-time = "2025-08-02T20:18:38.714Z" }, - { url = "https://files.pythonhosted.org/packages/8c/b2/ec453e544370a90b4e8b2c6afa72501963ddc33afe883f0e5ba34af6a80f/pyogrio-0.11.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:afce80b4b32f043fcf76a50e8572e3ad8d9d3e6abbbfa6137f0975ba55c4eeb8", size = 26980190, upload-time = "2025-08-02T20:18:41.197Z" }, - { url = "https://files.pythonhosted.org/packages/b1/f6/337f122b58f697f807bf9093b606b33b3ef52fe06a21e88d8a9230844cc3/pyogrio-0.11.1-cp312-cp312-manylinux_2_28_aarch64.whl", hash = "sha256:0cfd79caf0b8cb7bbf30b419dff7f21509169efcf4d431172c61b44fe1029dba", size = 26474852, upload-time = "2025-08-02T20:18:43.74Z" }, - { url = "https://files.pythonhosted.org/packages/e6/0f/8193a4a879f1284d693793e59a2e185c8fd3c47cb562b0e5daf7289997ea/pyogrio-0.11.1-cp312-cp312-manylinux_2_28_x86_64.whl", hash = "sha256:ab3aa6dbf2441d2407ce052233f2966324a3cff752bd43d99e4c779ea54e0a16", size = 27659721, upload-time = "2025-08-02T20:18:46.398Z" }, - { url = "https://files.pythonhosted.org/packages/5f/7d/3e818625a435fcc196ea441a6ca8495f87dd1f1eebeb95760eb401ea425d/pyogrio-0.11.1-cp312-cp312-win_amd64.whl", hash = "sha256:cd10035eb3b5e5a43bdafbd777339d2274e9b75972658364f0ce31c4d3400d1e", size = 19219350, upload-time = "2025-08-02T20:18:48.866Z" }, - { url = "https://files.pythonhosted.org/packages/f2/68/86328e36d010ee565ce0c65cdf9b830afcb1fb5972f537fe1cc561a49247/pyogrio-0.11.1-cp313-cp313-macosx_12_0_arm64.whl", hash = "sha256:3b368c597357ff262f3b46591ded86409462ee594ef42556708b090d121f873c", size = 19445347, upload-time = "2025-08-02T20:18:51.088Z" }, - { url = "https://files.pythonhosted.org/packages/20/bc/34bd87641fc2ecc6d842d6d758bbaa8d58aea4d36aa6a1111cbc9d450e74/pyogrio-0.11.1-cp313-cp313-macosx_12_0_x86_64.whl", hash = "sha256:1cb82cfd3493f32396e9c3f9255e17885610f62a323870947f4e04dd59bc3595", size = 20630594, upload-time = "2025-08-02T20:18:53.176Z" }, - { url = "https://files.pythonhosted.org/packages/68/9a/41b72ffa3e21354eb9afbbae855c86b94dbf06b22e89c16a807cc8b22bd2/pyogrio-0.11.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5d61aae22e67030fd354f03e21c6462537bf56160134dd8663709335a5a46b28", size = 26929440, upload-time = "2025-08-02T20:18:55.614Z" }, - { url = "https://files.pythonhosted.org/packages/42/dd/c968c49a2e9b7c219eac0cc504241c21ef789f1f1b34d33780508cea9764/pyogrio-0.11.1-cp313-cp313-manylinux_2_28_aarch64.whl", hash = "sha256:76150a3cd787c31628191c7abc6f8c796660125852fb65ae15dd7be1e9196816", size = 26433178, upload-time = "2025-08-02T20:18:58.274Z" }, - { url = "https://files.pythonhosted.org/packages/89/a9/79eca15094f7806a3adcf0bb976ab4346b0fb1bd87956c1933df44546c14/pyogrio-0.11.1-cp313-cp313-manylinux_2_28_x86_64.whl", hash = "sha256:e929452f6988c0365dd32ff2485d9488160a709fee28743abbbc18d663169ed0", size = 27616835, upload-time = "2025-08-02T20:19:01.112Z" }, - { url = "https://files.pythonhosted.org/packages/2b/f3/7722bc81e9eee39b528c1cbc6289a26d2d3b1b187491ed8493457d6a3a0e/pyogrio-0.11.1-cp313-cp313-win_amd64.whl", hash = "sha256:d6d56862b89a05fccd7211171c88806b6ec9b5effb79bf807cce0a57c1f2a606", size = 19219088, upload-time = "2025-08-02T20:19:03.732Z" }, +sdist = { url = "https://files.pythonhosted.org/packages/49/d4/12f86b1ed09721363da4c09622464b604c851a9223fc0c6b393fb2012208/pyogrio-0.12.1.tar.gz", hash = "sha256:e548ab705bb3e5383693717de1e6c76da97f3762ab92522cb310f93128a75ff1", size = 303289, upload-time = "2025-11-28T19:04:53.341Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/ad/e0/656b6536549d41b5aec57e0deca1f269b4f17532f0636836f587e581603a/pyogrio-0.12.1-cp312-cp312-macosx_12_0_arm64.whl", hash = "sha256:7a0d5ca39184030aec4cde30f4258f75b227a854530d2659babc8189d76e657d", size = 23661857, upload-time = "2025-11-28T19:03:27.744Z" }, + { url = "https://files.pythonhosted.org/packages/14/78/313259e40da728bdb60106ffdc7ea8224d164498cb838ecb79b634aab967/pyogrio-0.12.1-cp312-cp312-macosx_12_0_x86_64.whl", hash = "sha256:feaff42bbe8087ca0b30e33b09d1ce049ca55fe83ad83db1139ef37d1d04f30c", size = 25237106, upload-time = "2025-11-28T19:03:30.018Z" }, + { url = "https://files.pythonhosted.org/packages/8f/ca/5368571a8b00b941ccfbe6ea29a5566aaffd45d4eb1553b956f7755af43e/pyogrio-0.12.1-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:81096a5139532de5a8003ef02b41d5d2444cb382a9aecd1165b447eb549180d3", size = 31417048, upload-time = "2025-11-28T19:03:32.572Z" }, + { url = "https://files.pythonhosted.org/packages/ef/85/6eeb875f27bf498d657eb5dab9f58e4c48b36c9037122787abee9a1ba4ba/pyogrio-0.12.1-cp312-cp312-manylinux_2_28_aarch64.whl", hash = "sha256:41b78863f782f7a113ed0d36a5dc74d59735bd3a82af53510899bb02a18b06bb", size = 30952115, upload-time = "2025-11-28T19:03:35.332Z" }, + { url = "https://files.pythonhosted.org/packages/36/f7/cf8bec9024625947e1a71441906f60a5fa6f9e4c441c4428037e73b1fcc8/pyogrio-0.12.1-cp312-cp312-manylinux_2_28_x86_64.whl", hash = "sha256:8b65be8c4258b27cc8f919b21929cecdadda4c353e3637fa30850339ef4d15c5", size = 32537246, upload-time = "2025-11-28T19:03:37.969Z" }, + { url = "https://files.pythonhosted.org/packages/ab/10/7c9f5e428273574e69f217eba3a6c0c42936188ad4dcd9e2c41ebb711188/pyogrio-0.12.1-cp312-cp312-win_amd64.whl", hash = "sha256:1291b866c2c81d991bda15021b08b3621709b40ee3a85689229929e9465788bf", size = 22933980, upload-time = "2025-11-28T19:03:41.047Z" }, + { url = "https://files.pythonhosted.org/packages/be/56/f56e79f71b84aa9bea25fdde39fab3846841bd7926be96f623eb7253b7e1/pyogrio-0.12.1-cp313-cp313-macosx_12_0_arm64.whl", hash = "sha256:ec0e47a5a704e575092b2fd5c83fa0472a1d421e590f94093eb837bb0a11125d", size = 23658483, upload-time = "2025-11-28T19:03:43.567Z" }, + { url = "https://files.pythonhosted.org/packages/66/ac/5559f8a35d58a16cbb2dd7602dd11936ff8796d8c9bf789f14da88764ec3/pyogrio-0.12.1-cp313-cp313-macosx_12_0_x86_64.whl", hash = "sha256:b4c888fc08f388be4dd99dfca5e84a5cdc5994deeec0230cc45144d3460e2b21", size = 25232737, upload-time = "2025-11-28T19:03:45.92Z" }, + { url = "https://files.pythonhosted.org/packages/59/58/925f1c129ddd7cbba8dea4e7609797cea7a76dbc863ac9afd318a679c4b9/pyogrio-0.12.1-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:73a88436f9962750d782853727897ac2722cac5900d920e39fab3e56d7a6a7f1", size = 31377986, upload-time = "2025-11-28T19:03:48.495Z" }, + { url = "https://files.pythonhosted.org/packages/18/5f/c87034e92847b1844d0e8492a6a8e3301147d32c5e57909397ce64dbedf5/pyogrio-0.12.1-cp313-cp313-manylinux_2_28_aarch64.whl", hash = "sha256:b5d248a0d59fe9bbf9a35690b70004c67830ee0ebe7d4f7bb8ffd8659f684b3a", size = 30915791, upload-time = "2025-11-28T19:03:51.267Z" }, + { url = "https://files.pythonhosted.org/packages/46/35/b874f79d03e9f900012cf609f7fff97b77164f2e14ee5aac282f8a999c1b/pyogrio-0.12.1-cp313-cp313-manylinux_2_28_x86_64.whl", hash = "sha256:0622bc1a186421547660271083079b38d42e6f868802936d8538c0b379f1ab6b", size = 32499754, upload-time = "2025-11-28T19:03:58.776Z" }, + { url = "https://files.pythonhosted.org/packages/c3/c4/705678c9c4200130290b3a104b45c0cc10aaa48fcef3b2585b34e34ab3e1/pyogrio-0.12.1-cp313-cp313-win_amd64.whl", hash = "sha256:207bd60c7ffbcea84584596e3637653aa7095e9ee20fa408f90c7f9460392613", size = 22933945, upload-time = "2025-11-28T19:04:01.551Z" }, + { url = "https://files.pythonhosted.org/packages/f9/e0/d92d4944001330bc87742d43f112d63d12fc89378b6187e62ff3fc1e8e85/pyogrio-0.12.1-cp313-cp313t-macosx_12_0_arm64.whl", hash = "sha256:1511b39a283fa27cda906cd187a791578942a87a40b6a06697d9b43bb8ac80b0", size = 23692697, upload-time = "2025-11-28T19:04:04.208Z" }, + { url = "https://files.pythonhosted.org/packages/e5/d7/40acbe06d1b1140e3bb27b79e9163776469c1dc785f1be7d9a7fc7b95c87/pyogrio-0.12.1-cp313-cp313t-macosx_12_0_x86_64.whl", hash = "sha256:e486cd6aa9ea8a15394a5f84e019d61ec18f257eeeb642348bd68c3d1e57280b", size = 25258083, upload-time = "2025-11-28T19:04:07.121Z" }, + { url = "https://files.pythonhosted.org/packages/87/a1/39fefd9cddd95986700524f43d3093b4350f6e4fc200623c3838424a5080/pyogrio-0.12.1-cp313-cp313t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:d3f1a19f63bfd1d3042e45f37ad1d6598123a5a604b6c4ba3f38b419273486cd", size = 31368995, upload-time = "2025-11-28T19:04:09.88Z" }, + { url = "https://files.pythonhosted.org/packages/18/d7/da88c566e67d741a03851eb8d01358949d52e0b0fc2cd953582dc6d89ff8/pyogrio-0.12.1-cp313-cp313t-manylinux_2_28_aarch64.whl", hash = "sha256:f3dcc59b3316b8a0f59346bcc638a4d69997864a4d21da839192f50c4c92369a", size = 31035589, upload-time = "2025-11-28T19:04:12.993Z" }, + { url = "https://files.pythonhosted.org/packages/11/ac/8f0199f0d31b8ddbc4b4ea1918df8070fdf3e0a63100b898633ec9396224/pyogrio-0.12.1-cp313-cp313t-manylinux_2_28_x86_64.whl", hash = "sha256:a0643e041dee3e8e038fce69f52a915ecb486e6d7b674c0f9919f3c9e9629689", size = 32487973, upload-time = "2025-11-28T19:04:16.103Z" }, + { url = "https://files.pythonhosted.org/packages/bd/64/8541a27e9635a335835d234dfaeb19d6c26097fd88224eda7791f83ca98d/pyogrio-0.12.1-cp313-cp313t-win_amd64.whl", hash = "sha256:5881017f29e110d3613819667657844d8e961b747f2d35cf92f273c27af6d068", size = 22987374, upload-time = "2025-11-28T19:04:18.91Z" }, + { url = "https://files.pythonhosted.org/packages/f4/6f/b4d5e285e08c0c60bcc23b50d73038ddc7335d8de79cc25678cd486a3db0/pyogrio-0.12.1-cp314-cp314-macosx_12_0_arm64.whl", hash = "sha256:5a1b0453d1c9e7b03715dd57296c8f3790acb8b50d7e3b5844b3074a18f50709", size = 23660673, upload-time = "2025-11-28T19:04:21.662Z" }, + { url = "https://files.pythonhosted.org/packages/8d/75/4b29e71489c5551aa1a1c5ca8c5160a60203c94f2f68c87c0e3614d58965/pyogrio-0.12.1-cp314-cp314-macosx_12_0_x86_64.whl", hash = "sha256:e7ee560422239dd09ca7f8284cc8483a8919c30d25f3049bb0249bff4c38dec4", size = 25232194, upload-time = "2025-11-28T19:04:23.975Z" }, + { url = "https://files.pythonhosted.org/packages/89/6e/e9929d2261a07c36301983de2767bcde90d441ab5bf1d767ce56dd07f8b4/pyogrio-0.12.1-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:648c6f7f5f214d30e6cf493b4af1d59782907ac068af9119ca35f18153d6865a", size = 31336936, upload-time = "2025-11-28T19:04:26.594Z" }, + { url = "https://files.pythonhosted.org/packages/1d/9e/c59941d734ed936d4e5c89b4b99cb5541307cc42b3fd466ee78a1850c177/pyogrio-0.12.1-cp314-cp314-manylinux_2_28_aarch64.whl", hash = "sha256:58042584f3fd4cabb0f55d26c1405053f656be8a5c266c38140316a1e981aca0", size = 30902210, upload-time = "2025-11-28T19:04:29.143Z" }, + { url = "https://files.pythonhosted.org/packages/d1/68/cc07320a63f9c2586e60bf11d148b00e12d0e707673bffe609bbdcb7e754/pyogrio-0.12.1-cp314-cp314-manylinux_2_28_x86_64.whl", hash = "sha256:b438e38e4ccbaedaa5cb5824ff5de5539315d9b2fde6547c1e816576924ee8ca", size = 32461674, upload-time = "2025-11-28T19:04:31.792Z" }, + { url = "https://files.pythonhosted.org/packages/13/bc/e4522f429c45a3b6ad28185849dd76e5c8718b780883c4795e7ee41841ae/pyogrio-0.12.1-cp314-cp314-win_amd64.whl", hash = "sha256:f1d8d8a2fea3781dc2a05982c050259261ebc0f6c5e03732d6d79d582adf9363", size = 23550575, upload-time = "2025-11-28T19:04:34.556Z" }, + { url = "https://files.pythonhosted.org/packages/bd/ac/34f0664d0e391994a7b68529ae07a96432b2b4926dbac173ddc4ec94d310/pyogrio-0.12.1-cp314-cp314t-macosx_12_0_arm64.whl", hash = "sha256:9fe7286946f35a73e6370dc5855bc7a5e8e7babf9e4a8bad7a3279a1d94c7ea9", size = 23694285, upload-time = "2025-11-28T19:04:37.833Z" }, + { url = "https://files.pythonhosted.org/packages/8a/93/873255529faff1da09d0b27287e85ec805a318c60c0c74fd7df77f94e557/pyogrio-0.12.1-cp314-cp314t-macosx_12_0_x86_64.whl", hash = "sha256:2c50345b382f1be801d654ec22c70ee974d6057d4ba7afe984b55f2192bc94ee", size = 25259825, upload-time = "2025-11-28T19:04:40.125Z" }, + { url = "https://files.pythonhosted.org/packages/27/95/4d4c3644695d99c6fa0b0b42f0d6266ae9dfaf64478a3371eaac950bdd02/pyogrio-0.12.1-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:f0db95765ac0ca935c7fe579e29451294e3ab19c317b0c59c31fbe92a69155e0", size = 31371995, upload-time = "2025-11-28T19:04:42.736Z" }, + { url = "https://files.pythonhosted.org/packages/4c/6f/71f6bcca8754c8bf55a4b7153c61c91f8ac5ba992568e9fa3e54a0ee76fd/pyogrio-0.12.1-cp314-cp314t-manylinux_2_28_aarch64.whl", hash = "sha256:fc882779075982b93064b3bf3d8642514a6df00d9dd752493b104817072cfb01", size = 31035498, upload-time = "2025-11-28T19:04:45.79Z" }, + { url = "https://files.pythonhosted.org/packages/fd/47/75c1aa165a988347317afab9b938a01ad25dbca559b582ea34473703dc38/pyogrio-0.12.1-cp314-cp314t-manylinux_2_28_x86_64.whl", hash = "sha256:806f620e0c54b54dbdd65e9b6368d24f344cda84c9343364b40a57eb3e1c4dca", size = 32496390, upload-time = "2025-11-28T19:04:48.786Z" }, + { url = "https://files.pythonhosted.org/packages/31/93/4641dc5d952f6bdb71dabad2c50e3f8a5d58396cdea6ff8f8a08bfd4f4a6/pyogrio-0.12.1-cp314-cp314t-win_amd64.whl", hash = "sha256:5399f66730978d8852ef5f44dbafa0f738e7f28f4f784349f36830b69a9d2134", size = 23620996, upload-time = "2025-11-28T19:04:51.132Z" }, ] [[package]] name = "pyparsing" -version = "3.2.3" +version = "3.3.2" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/bb/22/f1129e69d94ffff626bdb5c835506b3a5b4f3d070f17ea295e12c2c6f60f/pyparsing-3.2.3.tar.gz", hash = "sha256:b9c13f1ab8b3b542f72e28f634bad4de758ab3ce4546e4301970ad6fa77c38be", size = 1088608, upload-time = "2025-03-25T05:01:28.114Z" } +sdist = { url = "https://files.pythonhosted.org/packages/f3/91/9c6ee907786a473bf81c5f53cf703ba0957b23ab84c264080fb5a450416f/pyparsing-3.3.2.tar.gz", hash = "sha256:c777f4d763f140633dcb6d8a3eda953bf7a214dc4eff598413c070bcdc117cbc", size = 6851574, upload-time = "2026-01-21T03:57:59.36Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/05/e7/df2285f3d08fee213f2d041540fa4fc9ca6c2d44cf36d3a035bf2a8d2bcc/pyparsing-3.2.3-py3-none-any.whl", hash = "sha256:a749938e02d6fd0b59b356ca504a24982314bb090c383e3cf201c95ef7e2bfcf", size = 111120, upload-time = "2025-03-25T05:01:24.908Z" }, + { url = "https://files.pythonhosted.org/packages/10/bd/c038d7cc38edc1aa5bf91ab8068b63d4308c66c4c8bb3cbba7dfbc049f9c/pyparsing-3.3.2-py3-none-any.whl", hash = "sha256:850ba148bd908d7e2411587e247a1e4f0327839c40e2e5e6d05a007ecc69911d", size = 122781, upload-time = "2026-01-21T03:57:55.912Z" }, ] [[package]] @@ -1213,15 +1184,6 @@ dependencies = [ ] sdist = { url = "https://files.pythonhosted.org/packages/04/90/67bd7260b4ea9b8b20b4f58afef6c223ecb3abf368eb4ec5bc2cdef81b49/pyproj-3.7.2.tar.gz", hash = "sha256:39a0cf1ecc7e282d1d30f36594ebd55c9fae1fda8a2622cee5d100430628f88c", size = 226279, upload-time = "2025-08-14T12:05:42.18Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/a6/bd/f205552cd1713b08f93b09e39a3ec99edef0b3ebbbca67b486fdf1abe2de/pyproj-3.7.2-cp311-cp311-macosx_13_0_x86_64.whl", hash = "sha256:2514d61f24c4e0bb9913e2c51487ecdaeca5f8748d8313c933693416ca41d4d5", size = 6227022, upload-time = "2025-08-14T12:03:51.474Z" }, - { url = "https://files.pythonhosted.org/packages/75/4c/9a937e659b8b418ab573c6d340d27e68716928953273e0837e7922fcac34/pyproj-3.7.2-cp311-cp311-macosx_14_0_arm64.whl", hash = "sha256:8693ca3892d82e70de077701ee76dd13d7bca4ae1c9d1e739d72004df015923a", size = 4625810, upload-time = "2025-08-14T12:03:53.808Z" }, - { url = "https://files.pythonhosted.org/packages/c0/7d/a9f41e814dc4d1dc54e95b2ccaf0b3ebe3eb18b1740df05fe334724c3d89/pyproj-3.7.2-cp311-cp311-manylinux_2_28_aarch64.whl", hash = "sha256:5e26484d80fea56273ed1555abaea161e9661d81a6c07815d54b8e883d4ceb25", size = 9638694, upload-time = "2025-08-14T12:03:55.669Z" }, - { url = "https://files.pythonhosted.org/packages/ad/ab/9bdb4a6216b712a1f9aab1c0fcbee5d3726f34a366f29c3e8c08a78d6b70/pyproj-3.7.2-cp311-cp311-manylinux_2_28_x86_64.whl", hash = "sha256:281cb92847814e8018010c48b4069ff858a30236638631c1a91dd7bfa68f8a8a", size = 9493977, upload-time = "2025-08-14T12:03:57.937Z" }, - { url = "https://files.pythonhosted.org/packages/c9/db/2db75b1b6190f1137b1c4e8ef6a22e1c338e46320f6329bfac819143e063/pyproj-3.7.2-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:9c8577f0b7bb09118ec2e57e3babdc977127dd66326d6c5d755c76b063e6d9dc", size = 10841151, upload-time = "2025-08-14T12:04:00.271Z" }, - { url = "https://files.pythonhosted.org/packages/89/f7/989643394ba23a286e9b7b3f09981496172f9e0d4512457ffea7dc47ffc7/pyproj-3.7.2-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:a23f59904fac3a5e7364b3aa44d288234af267ca041adb2c2b14a903cd5d3ac5", size = 10751585, upload-time = "2025-08-14T12:04:02.228Z" }, - { url = "https://files.pythonhosted.org/packages/53/6d/ad928fe975a6c14a093c92e6a319ca18f479f3336bb353a740bdba335681/pyproj-3.7.2-cp311-cp311-win32.whl", hash = "sha256:f2af4ed34b2cf3e031a2d85b067a3ecbd38df073c567e04b52fa7a0202afde8a", size = 5908533, upload-time = "2025-08-14T12:04:04.821Z" }, - { url = "https://files.pythonhosted.org/packages/79/e0/b95584605cec9ed50b7ebaf7975d1c4ddeec5a86b7a20554ed8b60042bd7/pyproj-3.7.2-cp311-cp311-win_amd64.whl", hash = "sha256:0b7cb633565129677b2a183c4d807c727d1c736fcb0568a12299383056e67433", size = 6320742, upload-time = "2025-08-14T12:04:06.357Z" }, - { url = "https://files.pythonhosted.org/packages/b7/4d/536e8f93bca808175c2d0a5ac9fdf69b960d8ab6b14f25030dccb07464d7/pyproj-3.7.2-cp311-cp311-win_arm64.whl", hash = "sha256:38b08d85e3a38e455625b80e9eb9f78027c8e2649a21dec4df1f9c3525460c71", size = 6245772, upload-time = "2025-08-14T12:04:08.365Z" }, { url = "https://files.pythonhosted.org/packages/8d/ab/9893ea9fb066be70ed9074ae543914a618c131ed8dff2da1e08b3a4df4db/pyproj-3.7.2-cp312-cp312-macosx_13_0_x86_64.whl", hash = "sha256:0a9bb26a6356fb5b033433a6d1b4542158fb71e3c51de49b4c318a1dff3aeaab", size = 6219832, upload-time = "2025-08-14T12:04:10.264Z" }, { url = "https://files.pythonhosted.org/packages/53/78/4c64199146eed7184eb0e85bedec60a4aa8853b6ffe1ab1f3a8b962e70a0/pyproj-3.7.2-cp312-cp312-macosx_14_0_arm64.whl", hash = "sha256:567caa03021178861fad27fabde87500ec6d2ee173dd32f3e2d9871e40eebd68", size = 4620650, upload-time = "2025-08-14T12:04:11.978Z" }, { url = "https://files.pythonhosted.org/packages/b6/ac/14a78d17943898a93ef4f8c6a9d4169911c994e3161e54a7cedeba9d8dde/pyproj-3.7.2-cp312-cp312-manylinux_2_28_aarch64.whl", hash = "sha256:c203101d1dc3c038a56cff0447acc515dd29d6e14811406ac539c21eed422b2a", size = 9667087, upload-time = "2025-08-14T12:04:13.964Z" }, @@ -1271,7 +1233,7 @@ wheels = [ [[package]] name = "pytest" -version = "8.4.1" +version = "9.0.2" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "colorama", marker = "sys_platform == 'win32'" }, @@ -1280,36 +1242,23 @@ dependencies = [ { name = "pluggy" }, { name = "pygments" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/08/ba/45911d754e8eba3d5a841a5ce61a65a685ff1798421ac054f85aa8747dfb/pytest-8.4.1.tar.gz", hash = "sha256:7c67fd69174877359ed9371ec3af8a3d2b04741818c51e5e99cc1742251fa93c", size = 1517714, upload-time = "2025-06-18T05:48:06.109Z" } +sdist = { url = "https://files.pythonhosted.org/packages/d1/db/7ef3487e0fb0049ddb5ce41d3a49c235bf9ad299b6a25d5780a89f19230f/pytest-9.0.2.tar.gz", hash = "sha256:75186651a92bd89611d1d9fc20f0b4345fd827c41ccd5c299a868a05d70edf11", size = 1568901, upload-time = "2025-12-06T21:30:51.014Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/29/16/c8a903f4c4dffe7a12843191437d7cd8e32751d5de349d45d3fe69544e87/pytest-8.4.1-py3-none-any.whl", hash = "sha256:539c70ba6fcead8e78eebbf1115e8b589e7565830d7d006a8723f19ac8a0afb7", size = 365474, upload-time = "2025-06-18T05:48:03.955Z" }, + { url = "https://files.pythonhosted.org/packages/3b/ab/b3226f0bd7cdcf710fbede2b3548584366da3b19b5021e74f5bde2a8fa3f/pytest-9.0.2-py3-none-any.whl", hash = "sha256:711ffd45bf766d5264d487b917733b453d917afd2b0ad65223959f59089f875b", size = 374801, upload-time = "2025-12-06T21:30:49.154Z" }, ] [[package]] name = "pytest-cov" -version = "6.2.1" +version = "7.0.0" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "coverage", extra = ["toml"] }, + { name = "coverage" }, { name = "pluggy" }, { name = "pytest" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/18/99/668cade231f434aaa59bbfbf49469068d2ddd945000621d3d165d2e7dd7b/pytest_cov-6.2.1.tar.gz", hash = "sha256:25cc6cc0a5358204b8108ecedc51a9b57b34cc6b8c967cc2c01a4e00d8a67da2", size = 69432, upload-time = "2025-06-12T10:47:47.684Z" } +sdist = { url = "https://files.pythonhosted.org/packages/5e/f7/c933acc76f5208b3b00089573cf6a2bc26dc80a8aece8f52bb7d6b1855ca/pytest_cov-7.0.0.tar.gz", hash = "sha256:33c97eda2e049a0c5298e91f519302a1334c26ac65c1a483d6206fd458361af1", size = 54328, upload-time = "2025-09-09T10:57:02.113Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/bc/16/4ea354101abb1287856baa4af2732be351c7bee728065aed451b678153fd/pytest_cov-6.2.1-py3-none-any.whl", hash = "sha256:f5bc4c23f42f1cdd23c70b1dab1bbaef4fc505ba950d53e0081d0730dd7e86d5", size = 24644, upload-time = "2025-06-12T10:47:45.932Z" }, -] - -[[package]] -name = "pytest-xdist" -version = "3.8.0" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "execnet" }, - { name = "pytest" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/78/b4/439b179d1ff526791eb921115fca8e44e596a13efeda518b9d845a619450/pytest_xdist-3.8.0.tar.gz", hash = "sha256:7e578125ec9bc6050861aa93f2d59f1d8d085595d6551c2c90b6f4fad8d3a9f1", size = 88069, upload-time = "2025-07-01T13:30:59.346Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/ca/31/d4e37e9e550c2b92a9cbc2e4d0b7420a27224968580b5a447f420847c975/pytest_xdist-3.8.0-py3-none-any.whl", hash = "sha256:202ca578cfeb7370784a8c33d6d05bc6e13b4f25b5053c30a152269fd10f0b88", size = 46396, upload-time = "2025-07-01T13:30:56.632Z" }, + { url = "https://files.pythonhosted.org/packages/ee/49/1377b49de7d0c1ce41292161ea0f721913fa8722c19fb9c1e3aa0367eecb/pytest_cov-7.0.0-py3-none-any.whl", hash = "sha256:3b8e9558b16cc1479da72058bdecf8073661c7f57f7d3c5f22a1c23507f2d861", size = 22424, upload-time = "2025-09-09T10:57:00.695Z" }, ] [[package]] @@ -1324,48 +1273,50 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/ec/57/56b9bcc3c9c6a792fcbaf139543cee77261f3651ca9da0c93f5c1221264b/python_dateutil-2.9.0.post0-py2.py3-none-any.whl", hash = "sha256:a8b2bc7bffae282281c8140a97d3aa9c14da0b136dfe83f850eea9a5f7470427", size = 229892, upload-time = "2024-03-01T18:36:18.57Z" }, ] -[[package]] -name = "pytz" -version = "2025.2" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/f8/bf/abbd3cdfb8fbc7fb3d4d38d320f2441b1e7cbe29be4f23797b4a2b5d8aac/pytz-2025.2.tar.gz", hash = "sha256:360b9e3dbb49a209c21ad61809c7fb453643e048b38924c765813546746e81c3", size = 320884, upload-time = "2025-03-25T02:25:00.538Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/81/c4/34e93fe5f5429d7570ec1fa436f1986fb1f00c3e0f43a589fe2bbcd22c3f/pytz-2025.2-py2.py3-none-any.whl", hash = "sha256:5ddf76296dd8c44c26eb8f4b6f35488f3ccbf6fbbd7adee0b7262d43f0ec2f00", size = 509225, upload-time = "2025-03-25T02:24:58.468Z" }, -] - [[package]] name = "pyyaml" -version = "6.0.2" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/54/ed/79a089b6be93607fa5cdaedf301d7dfb23af5f25c398d5ead2525b063e17/pyyaml-6.0.2.tar.gz", hash = "sha256:d584d9ec91ad65861cc08d42e834324ef890a082e591037abe114850ff7bbc3e", size = 130631, upload-time = "2024-08-06T20:33:50.674Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/f8/aa/7af4e81f7acba21a4c6be026da38fd2b872ca46226673c89a758ebdc4fd2/PyYAML-6.0.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:cc1c1159b3d456576af7a3e4d1ba7e6924cb39de8f67111c735f6fc832082774", size = 184612, upload-time = "2024-08-06T20:32:03.408Z" }, - { url = "https://files.pythonhosted.org/packages/8b/62/b9faa998fd185f65c1371643678e4d58254add437edb764a08c5a98fb986/PyYAML-6.0.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:1e2120ef853f59c7419231f3bf4e7021f1b936f6ebd222406c3b60212205d2ee", size = 172040, upload-time = "2024-08-06T20:32:04.926Z" }, - { url = "https://files.pythonhosted.org/packages/ad/0c/c804f5f922a9a6563bab712d8dcc70251e8af811fce4524d57c2c0fd49a4/PyYAML-6.0.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5d225db5a45f21e78dd9358e58a98702a0302f2659a3c6cd320564b75b86f47c", size = 736829, upload-time = "2024-08-06T20:32:06.459Z" }, - { url = "https://files.pythonhosted.org/packages/51/16/6af8d6a6b210c8e54f1406a6b9481febf9c64a3109c541567e35a49aa2e7/PyYAML-6.0.2-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5ac9328ec4831237bec75defaf839f7d4564be1e6b25ac710bd1a96321cc8317", size = 764167, upload-time = "2024-08-06T20:32:08.338Z" }, - { url = "https://files.pythonhosted.org/packages/75/e4/2c27590dfc9992f73aabbeb9241ae20220bd9452df27483b6e56d3975cc5/PyYAML-6.0.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3ad2a3decf9aaba3d29c8f537ac4b243e36bef957511b4766cb0057d32b0be85", size = 762952, upload-time = "2024-08-06T20:32:14.124Z" }, - { url = "https://files.pythonhosted.org/packages/9b/97/ecc1abf4a823f5ac61941a9c00fe501b02ac3ab0e373c3857f7d4b83e2b6/PyYAML-6.0.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:ff3824dc5261f50c9b0dfb3be22b4567a6f938ccce4587b38952d85fd9e9afe4", size = 735301, upload-time = "2024-08-06T20:32:16.17Z" }, - { url = "https://files.pythonhosted.org/packages/45/73/0f49dacd6e82c9430e46f4a027baa4ca205e8b0a9dce1397f44edc23559d/PyYAML-6.0.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:797b4f722ffa07cc8d62053e4cff1486fa6dc094105d13fea7b1de7d8bf71c9e", size = 756638, upload-time = "2024-08-06T20:32:18.555Z" }, - { url = "https://files.pythonhosted.org/packages/22/5f/956f0f9fc65223a58fbc14459bf34b4cc48dec52e00535c79b8db361aabd/PyYAML-6.0.2-cp311-cp311-win32.whl", hash = "sha256:11d8f3dd2b9c1207dcaf2ee0bbbfd5991f571186ec9cc78427ba5bd32afae4b5", size = 143850, upload-time = "2024-08-06T20:32:19.889Z" }, - { url = "https://files.pythonhosted.org/packages/ed/23/8da0bbe2ab9dcdd11f4f4557ccaf95c10b9811b13ecced089d43ce59c3c8/PyYAML-6.0.2-cp311-cp311-win_amd64.whl", hash = "sha256:e10ce637b18caea04431ce14fabcf5c64a1c61ec9c56b071a4b7ca131ca52d44", size = 161980, upload-time = "2024-08-06T20:32:21.273Z" }, - { url = "https://files.pythonhosted.org/packages/86/0c/c581167fc46d6d6d7ddcfb8c843a4de25bdd27e4466938109ca68492292c/PyYAML-6.0.2-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:c70c95198c015b85feafc136515252a261a84561b7b1d51e3384e0655ddf25ab", size = 183873, upload-time = "2024-08-06T20:32:25.131Z" }, - { url = "https://files.pythonhosted.org/packages/a8/0c/38374f5bb272c051e2a69281d71cba6fdb983413e6758b84482905e29a5d/PyYAML-6.0.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:ce826d6ef20b1bc864f0a68340c8b3287705cae2f8b4b1d932177dcc76721725", size = 173302, upload-time = "2024-08-06T20:32:26.511Z" }, - { url = "https://files.pythonhosted.org/packages/c3/93/9916574aa8c00aa06bbac729972eb1071d002b8e158bd0e83a3b9a20a1f7/PyYAML-6.0.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1f71ea527786de97d1a0cc0eacd1defc0985dcf6b3f17bb77dcfc8c34bec4dc5", size = 739154, upload-time = "2024-08-06T20:32:28.363Z" }, - { url = "https://files.pythonhosted.org/packages/95/0f/b8938f1cbd09739c6da569d172531567dbcc9789e0029aa070856f123984/PyYAML-6.0.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9b22676e8097e9e22e36d6b7bda33190d0d400f345f23d4065d48f4ca7ae0425", size = 766223, upload-time = "2024-08-06T20:32:30.058Z" }, - { url = "https://files.pythonhosted.org/packages/b9/2b/614b4752f2e127db5cc206abc23a8c19678e92b23c3db30fc86ab731d3bd/PyYAML-6.0.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:80bab7bfc629882493af4aa31a4cfa43a4c57c83813253626916b8c7ada83476", size = 767542, upload-time = "2024-08-06T20:32:31.881Z" }, - { url = "https://files.pythonhosted.org/packages/d4/00/dd137d5bcc7efea1836d6264f049359861cf548469d18da90cd8216cf05f/PyYAML-6.0.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:0833f8694549e586547b576dcfaba4a6b55b9e96098b36cdc7ebefe667dfed48", size = 731164, upload-time = "2024-08-06T20:32:37.083Z" }, - { url = "https://files.pythonhosted.org/packages/c9/1f/4f998c900485e5c0ef43838363ba4a9723ac0ad73a9dc42068b12aaba4e4/PyYAML-6.0.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:8b9c7197f7cb2738065c481a0461e50ad02f18c78cd75775628afb4d7137fb3b", size = 756611, upload-time = "2024-08-06T20:32:38.898Z" }, - { url = "https://files.pythonhosted.org/packages/df/d1/f5a275fdb252768b7a11ec63585bc38d0e87c9e05668a139fea92b80634c/PyYAML-6.0.2-cp312-cp312-win32.whl", hash = "sha256:ef6107725bd54b262d6dedcc2af448a266975032bc85ef0172c5f059da6325b4", size = 140591, upload-time = "2024-08-06T20:32:40.241Z" }, - { url = "https://files.pythonhosted.org/packages/0c/e8/4f648c598b17c3d06e8753d7d13d57542b30d56e6c2dedf9c331ae56312e/PyYAML-6.0.2-cp312-cp312-win_amd64.whl", hash = "sha256:7e7401d0de89a9a855c839bc697c079a4af81cf878373abd7dc625847d25cbd8", size = 156338, upload-time = "2024-08-06T20:32:41.93Z" }, - { url = "https://files.pythonhosted.org/packages/ef/e3/3af305b830494fa85d95f6d95ef7fa73f2ee1cc8ef5b495c7c3269fb835f/PyYAML-6.0.2-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:efdca5630322a10774e8e98e1af481aad470dd62c3170801852d752aa7a783ba", size = 181309, upload-time = "2024-08-06T20:32:43.4Z" }, - { url = "https://files.pythonhosted.org/packages/45/9f/3b1c20a0b7a3200524eb0076cc027a970d320bd3a6592873c85c92a08731/PyYAML-6.0.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:50187695423ffe49e2deacb8cd10510bc361faac997de9efef88badc3bb9e2d1", size = 171679, upload-time = "2024-08-06T20:32:44.801Z" }, - { url = "https://files.pythonhosted.org/packages/7c/9a/337322f27005c33bcb656c655fa78325b730324c78620e8328ae28b64d0c/PyYAML-6.0.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0ffe8360bab4910ef1b9e87fb812d8bc0a308b0d0eef8c8f44e0254ab3b07133", size = 733428, upload-time = "2024-08-06T20:32:46.432Z" }, - { url = "https://files.pythonhosted.org/packages/a3/69/864fbe19e6c18ea3cc196cbe5d392175b4cf3d5d0ac1403ec3f2d237ebb5/PyYAML-6.0.2-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:17e311b6c678207928d649faa7cb0d7b4c26a0ba73d41e99c4fff6b6c3276484", size = 763361, upload-time = "2024-08-06T20:32:51.188Z" }, - { url = "https://files.pythonhosted.org/packages/04/24/b7721e4845c2f162d26f50521b825fb061bc0a5afcf9a386840f23ea19fa/PyYAML-6.0.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:70b189594dbe54f75ab3a1acec5f1e3faa7e8cf2f1e08d9b561cb41b845f69d5", size = 759523, upload-time = "2024-08-06T20:32:53.019Z" }, - { url = "https://files.pythonhosted.org/packages/2b/b2/e3234f59ba06559c6ff63c4e10baea10e5e7df868092bf9ab40e5b9c56b6/PyYAML-6.0.2-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:41e4e3953a79407c794916fa277a82531dd93aad34e29c2a514c2c0c5fe971cc", size = 726660, upload-time = "2024-08-06T20:32:54.708Z" }, - { url = "https://files.pythonhosted.org/packages/fe/0f/25911a9f080464c59fab9027482f822b86bf0608957a5fcc6eaac85aa515/PyYAML-6.0.2-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:68ccc6023a3400877818152ad9a1033e3db8625d899c72eacb5a668902e4d652", size = 751597, upload-time = "2024-08-06T20:32:56.985Z" }, - { url = "https://files.pythonhosted.org/packages/14/0d/e2c3b43bbce3cf6bd97c840b46088a3031085179e596d4929729d8d68270/PyYAML-6.0.2-cp313-cp313-win32.whl", hash = "sha256:bc2fa7c6b47d6bc618dd7fb02ef6fdedb1090ec036abab80d4681424b84c1183", size = 140527, upload-time = "2024-08-06T20:33:03.001Z" }, - { url = "https://files.pythonhosted.org/packages/fa/de/02b54f42487e3d3c6efb3f89428677074ca7bf43aae402517bc7cca949f3/PyYAML-6.0.2-cp313-cp313-win_amd64.whl", hash = "sha256:8388ee1976c416731879ac16da0aff3f63b286ffdd57cdeb95f3f2e085687563", size = 156446, upload-time = "2024-08-06T20:33:04.33Z" }, +version = "6.0.3" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/05/8e/961c0007c59b8dd7729d542c61a4d537767a59645b82a0b521206e1e25c2/pyyaml-6.0.3.tar.gz", hash = "sha256:d76623373421df22fb4cf8817020cbb7ef15c725b9d5e45f17e189bfc384190f", size = 130960, upload-time = "2025-09-25T21:33:16.546Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/d1/33/422b98d2195232ca1826284a76852ad5a86fe23e31b009c9886b2d0fb8b2/pyyaml-6.0.3-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:7f047e29dcae44602496db43be01ad42fc6f1cc0d8cd6c83d342306c32270196", size = 182063, upload-time = "2025-09-25T21:32:11.445Z" }, + { url = "https://files.pythonhosted.org/packages/89/a0/6cf41a19a1f2f3feab0e9c0b74134aa2ce6849093d5517a0c550fe37a648/pyyaml-6.0.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:fc09d0aa354569bc501d4e787133afc08552722d3ab34836a80547331bb5d4a0", size = 173973, upload-time = "2025-09-25T21:32:12.492Z" }, + { url = "https://files.pythonhosted.org/packages/ed/23/7a778b6bd0b9a8039df8b1b1d80e2e2ad78aa04171592c8a5c43a56a6af4/pyyaml-6.0.3-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:9149cad251584d5fb4981be1ecde53a1ca46c891a79788c0df828d2f166bda28", size = 775116, upload-time = "2025-09-25T21:32:13.652Z" }, + { url = "https://files.pythonhosted.org/packages/65/30/d7353c338e12baef4ecc1b09e877c1970bd3382789c159b4f89d6a70dc09/pyyaml-6.0.3-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:5fdec68f91a0c6739b380c83b951e2c72ac0197ace422360e6d5a959d8d97b2c", size = 844011, upload-time = "2025-09-25T21:32:15.21Z" }, + { url = "https://files.pythonhosted.org/packages/8b/9d/b3589d3877982d4f2329302ef98a8026e7f4443c765c46cfecc8858c6b4b/pyyaml-6.0.3-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:ba1cc08a7ccde2d2ec775841541641e4548226580ab850948cbfda66a1befcdc", size = 807870, upload-time = "2025-09-25T21:32:16.431Z" }, + { url = "https://files.pythonhosted.org/packages/05/c0/b3be26a015601b822b97d9149ff8cb5ead58c66f981e04fedf4e762f4bd4/pyyaml-6.0.3-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:8dc52c23056b9ddd46818a57b78404882310fb473d63f17b07d5c40421e47f8e", size = 761089, upload-time = "2025-09-25T21:32:17.56Z" }, + { url = "https://files.pythonhosted.org/packages/be/8e/98435a21d1d4b46590d5459a22d88128103f8da4c2d4cb8f14f2a96504e1/pyyaml-6.0.3-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:41715c910c881bc081f1e8872880d3c650acf13dfa8214bad49ed4cede7c34ea", size = 790181, upload-time = "2025-09-25T21:32:18.834Z" }, + { url = "https://files.pythonhosted.org/packages/74/93/7baea19427dcfbe1e5a372d81473250b379f04b1bd3c4c5ff825e2327202/pyyaml-6.0.3-cp312-cp312-win32.whl", hash = "sha256:96b533f0e99f6579b3d4d4995707cf36df9100d67e0c8303a0c55b27b5f99bc5", size = 137658, upload-time = "2025-09-25T21:32:20.209Z" }, + { url = "https://files.pythonhosted.org/packages/86/bf/899e81e4cce32febab4fb42bb97dcdf66bc135272882d1987881a4b519e9/pyyaml-6.0.3-cp312-cp312-win_amd64.whl", hash = "sha256:5fcd34e47f6e0b794d17de1b4ff496c00986e1c83f7ab2fb8fcfe9616ff7477b", size = 154003, upload-time = "2025-09-25T21:32:21.167Z" }, + { url = "https://files.pythonhosted.org/packages/1a/08/67bd04656199bbb51dbed1439b7f27601dfb576fb864099c7ef0c3e55531/pyyaml-6.0.3-cp312-cp312-win_arm64.whl", hash = "sha256:64386e5e707d03a7e172c0701abfb7e10f0fb753ee1d773128192742712a98fd", size = 140344, upload-time = "2025-09-25T21:32:22.617Z" }, + { url = "https://files.pythonhosted.org/packages/d1/11/0fd08f8192109f7169db964b5707a2f1e8b745d4e239b784a5a1dd80d1db/pyyaml-6.0.3-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:8da9669d359f02c0b91ccc01cac4a67f16afec0dac22c2ad09f46bee0697eba8", size = 181669, upload-time = "2025-09-25T21:32:23.673Z" }, + { url = "https://files.pythonhosted.org/packages/b1/16/95309993f1d3748cd644e02e38b75d50cbc0d9561d21f390a76242ce073f/pyyaml-6.0.3-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:2283a07e2c21a2aa78d9c4442724ec1eb15f5e42a723b99cb3d822d48f5f7ad1", size = 173252, upload-time = "2025-09-25T21:32:25.149Z" }, + { url = "https://files.pythonhosted.org/packages/50/31/b20f376d3f810b9b2371e72ef5adb33879b25edb7a6d072cb7ca0c486398/pyyaml-6.0.3-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ee2922902c45ae8ccada2c5b501ab86c36525b883eff4255313a253a3160861c", size = 767081, upload-time = "2025-09-25T21:32:26.575Z" }, + { url = "https://files.pythonhosted.org/packages/49/1e/a55ca81e949270d5d4432fbbd19dfea5321eda7c41a849d443dc92fd1ff7/pyyaml-6.0.3-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:a33284e20b78bd4a18c8c2282d549d10bc8408a2a7ff57653c0cf0b9be0afce5", size = 841159, upload-time = "2025-09-25T21:32:27.727Z" }, + { url = "https://files.pythonhosted.org/packages/74/27/e5b8f34d02d9995b80abcef563ea1f8b56d20134d8f4e5e81733b1feceb2/pyyaml-6.0.3-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:0f29edc409a6392443abf94b9cf89ce99889a1dd5376d94316ae5145dfedd5d6", size = 801626, upload-time = "2025-09-25T21:32:28.878Z" }, + { url = "https://files.pythonhosted.org/packages/f9/11/ba845c23988798f40e52ba45f34849aa8a1f2d4af4b798588010792ebad6/pyyaml-6.0.3-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:f7057c9a337546edc7973c0d3ba84ddcdf0daa14533c2065749c9075001090e6", size = 753613, upload-time = "2025-09-25T21:32:30.178Z" }, + { url = "https://files.pythonhosted.org/packages/3d/e0/7966e1a7bfc0a45bf0a7fb6b98ea03fc9b8d84fa7f2229e9659680b69ee3/pyyaml-6.0.3-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:eda16858a3cab07b80edaf74336ece1f986ba330fdb8ee0d6c0d68fe82bc96be", size = 794115, upload-time = "2025-09-25T21:32:31.353Z" }, + { url = "https://files.pythonhosted.org/packages/de/94/980b50a6531b3019e45ddeada0626d45fa85cbe22300844a7983285bed3b/pyyaml-6.0.3-cp313-cp313-win32.whl", hash = "sha256:d0eae10f8159e8fdad514efdc92d74fd8d682c933a6dd088030f3834bc8e6b26", size = 137427, upload-time = "2025-09-25T21:32:32.58Z" }, + { url = "https://files.pythonhosted.org/packages/97/c9/39d5b874e8b28845e4ec2202b5da735d0199dbe5b8fb85f91398814a9a46/pyyaml-6.0.3-cp313-cp313-win_amd64.whl", hash = "sha256:79005a0d97d5ddabfeeea4cf676af11e647e41d81c9a7722a193022accdb6b7c", size = 154090, upload-time = "2025-09-25T21:32:33.659Z" }, + { url = "https://files.pythonhosted.org/packages/73/e8/2bdf3ca2090f68bb3d75b44da7bbc71843b19c9f2b9cb9b0f4ab7a5a4329/pyyaml-6.0.3-cp313-cp313-win_arm64.whl", hash = "sha256:5498cd1645aa724a7c71c8f378eb29ebe23da2fc0d7a08071d89469bf1d2defb", size = 140246, upload-time = "2025-09-25T21:32:34.663Z" }, + { url = "https://files.pythonhosted.org/packages/9d/8c/f4bd7f6465179953d3ac9bc44ac1a8a3e6122cf8ada906b4f96c60172d43/pyyaml-6.0.3-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:8d1fab6bb153a416f9aeb4b8763bc0f22a5586065f86f7664fc23339fc1c1fac", size = 181814, upload-time = "2025-09-25T21:32:35.712Z" }, + { url = "https://files.pythonhosted.org/packages/bd/9c/4d95bb87eb2063d20db7b60faa3840c1b18025517ae857371c4dd55a6b3a/pyyaml-6.0.3-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:34d5fcd24b8445fadc33f9cf348c1047101756fd760b4dacb5c3e99755703310", size = 173809, upload-time = "2025-09-25T21:32:36.789Z" }, + { url = "https://files.pythonhosted.org/packages/92/b5/47e807c2623074914e29dabd16cbbdd4bf5e9b2db9f8090fa64411fc5382/pyyaml-6.0.3-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:501a031947e3a9025ed4405a168e6ef5ae3126c59f90ce0cd6f2bfc477be31b7", size = 766454, upload-time = "2025-09-25T21:32:37.966Z" }, + { url = "https://files.pythonhosted.org/packages/02/9e/e5e9b168be58564121efb3de6859c452fccde0ab093d8438905899a3a483/pyyaml-6.0.3-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:b3bc83488de33889877a0f2543ade9f70c67d66d9ebb4ac959502e12de895788", size = 836355, upload-time = "2025-09-25T21:32:39.178Z" }, + { url = "https://files.pythonhosted.org/packages/88/f9/16491d7ed2a919954993e48aa941b200f38040928474c9e85ea9e64222c3/pyyaml-6.0.3-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c458b6d084f9b935061bc36216e8a69a7e293a2f1e68bf956dcd9e6cbcd143f5", size = 794175, upload-time = "2025-09-25T21:32:40.865Z" }, + { url = "https://files.pythonhosted.org/packages/dd/3f/5989debef34dc6397317802b527dbbafb2b4760878a53d4166579111411e/pyyaml-6.0.3-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:7c6610def4f163542a622a73fb39f534f8c101d690126992300bf3207eab9764", size = 755228, upload-time = "2025-09-25T21:32:42.084Z" }, + { url = "https://files.pythonhosted.org/packages/d7/ce/af88a49043cd2e265be63d083fc75b27b6ed062f5f9fd6cdc223ad62f03e/pyyaml-6.0.3-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:5190d403f121660ce8d1d2c1bb2ef1bd05b5f68533fc5c2ea899bd15f4399b35", size = 789194, upload-time = "2025-09-25T21:32:43.362Z" }, + { url = "https://files.pythonhosted.org/packages/23/20/bb6982b26a40bb43951265ba29d4c246ef0ff59c9fdcdf0ed04e0687de4d/pyyaml-6.0.3-cp314-cp314-win_amd64.whl", hash = "sha256:4a2e8cebe2ff6ab7d1050ecd59c25d4c8bd7e6f400f5f82b96557ac0abafd0ac", size = 156429, upload-time = "2025-09-25T21:32:57.844Z" }, + { url = "https://files.pythonhosted.org/packages/f4/f4/a4541072bb9422c8a883ab55255f918fa378ecf083f5b85e87fc2b4eda1b/pyyaml-6.0.3-cp314-cp314-win_arm64.whl", hash = "sha256:93dda82c9c22deb0a405ea4dc5f2d0cda384168e466364dec6255b293923b2f3", size = 143912, upload-time = "2025-09-25T21:32:59.247Z" }, + { url = "https://files.pythonhosted.org/packages/7c/f9/07dd09ae774e4616edf6cda684ee78f97777bdd15847253637a6f052a62f/pyyaml-6.0.3-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:02893d100e99e03eda1c8fd5c441d8c60103fd175728e23e431db1b589cf5ab3", size = 189108, upload-time = "2025-09-25T21:32:44.377Z" }, + { url = "https://files.pythonhosted.org/packages/4e/78/8d08c9fb7ce09ad8c38ad533c1191cf27f7ae1effe5bb9400a46d9437fcf/pyyaml-6.0.3-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:c1ff362665ae507275af2853520967820d9124984e0f7466736aea23d8611fba", size = 183641, upload-time = "2025-09-25T21:32:45.407Z" }, + { url = "https://files.pythonhosted.org/packages/7b/5b/3babb19104a46945cf816d047db2788bcaf8c94527a805610b0289a01c6b/pyyaml-6.0.3-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6adc77889b628398debc7b65c073bcb99c4a0237b248cacaf3fe8a557563ef6c", size = 831901, upload-time = "2025-09-25T21:32:48.83Z" }, + { url = "https://files.pythonhosted.org/packages/8b/cc/dff0684d8dc44da4d22a13f35f073d558c268780ce3c6ba1b87055bb0b87/pyyaml-6.0.3-cp314-cp314t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:a80cb027f6b349846a3bf6d73b5e95e782175e52f22108cfa17876aaeff93702", size = 861132, upload-time = "2025-09-25T21:32:50.149Z" }, + { url = "https://files.pythonhosted.org/packages/b1/5e/f77dc6b9036943e285ba76b49e118d9ea929885becb0a29ba8a7c75e29fe/pyyaml-6.0.3-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:00c4bdeba853cc34e7dd471f16b4114f4162dc03e6b7afcc2128711f0eca823c", size = 839261, upload-time = "2025-09-25T21:32:51.808Z" }, + { url = "https://files.pythonhosted.org/packages/ce/88/a9db1376aa2a228197c58b37302f284b5617f56a5d959fd1763fb1675ce6/pyyaml-6.0.3-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:66e1674c3ef6f541c35191caae2d429b967b99e02040f5ba928632d9a7f0f065", size = 805272, upload-time = "2025-09-25T21:32:52.941Z" }, + { url = "https://files.pythonhosted.org/packages/da/92/1446574745d74df0c92e6aa4a7b0b3130706a4142b2d1a5869f2eaa423c6/pyyaml-6.0.3-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:16249ee61e95f858e83976573de0f5b2893b3677ba71c9dd36b9cf8be9ac6d65", size = 829923, upload-time = "2025-09-25T21:32:54.537Z" }, + { url = "https://files.pythonhosted.org/packages/f0/7a/1c7270340330e575b92f397352af856a8c06f230aa3e76f86b39d01b416a/pyyaml-6.0.3-cp314-cp314t-win_amd64.whl", hash = "sha256:4ad1906908f2f5ae4e5a8ddfce73c320c2a1429ec52eafd27138b7f1cbe341c9", size = 174062, upload-time = "2025-09-25T21:32:55.767Z" }, + { url = "https://files.pythonhosted.org/packages/f1/12/de94a39c2ef588c7e6455cfbe7343d3b2dc9d6b6b2f40c4c6565744c873d/pyyaml-6.0.3-cp314-cp314t-win_arm64.whl", hash = "sha256:ebc55a14a21cb14062aa4162f906cd962b28e2e9ea38f9b4391244cd8de4ae0b", size = 149341, upload-time = "2025-09-25T21:32:56.828Z" }, ] [[package]] @@ -1384,17 +1335,17 @@ wheels = [ ] [[package]] -name = "roman-numerals-py" -version = "3.1.0" +name = "roman-numerals" +version = "4.1.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/30/76/48fd56d17c5bdbdf65609abbc67288728a98ed4c02919428d4f52d23b24b/roman_numerals_py-3.1.0.tar.gz", hash = "sha256:be4bf804f083a4ce001b5eb7e3c0862479d10f94c936f6c4e5f250aa5ff5bd2d", size = 9017, upload-time = "2025-02-22T07:34:54.333Z" } +sdist = { url = "https://files.pythonhosted.org/packages/ae/f9/41dc953bbeb056c17d5f7a519f50fdf010bd0553be2d630bc69d1e022703/roman_numerals-4.1.0.tar.gz", hash = "sha256:1af8b147eb1405d5839e78aeb93131690495fe9da5c91856cb33ad55a7f1e5b2", size = 9077, upload-time = "2025-12-17T18:25:34.381Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/53/97/d2cbbaa10c9b826af0e10fdf836e1bf344d9f0abb873ebc34d1f49642d3f/roman_numerals_py-3.1.0-py3-none-any.whl", hash = "sha256:9da2ad2fb670bcf24e81070ceb3be72f6c11c440d73bd579fbeca1e9f330954c", size = 7742, upload-time = "2025-02-22T07:34:52.422Z" }, + { url = "https://files.pythonhosted.org/packages/04/54/6f679c435d28e0a568d8e8a7c0a93a09010818634c3c3907fc98d8983770/roman_numerals-4.1.0-py3-none-any.whl", hash = "sha256:647ba99caddc2cc1e55a51e4360689115551bf4476d90e8162cf8c345fe233c7", size = 7676, upload-time = "2025-12-17T18:25:33.098Z" }, ] [[package]] name = "roseau-load-flow" -version = "0.13.1" +version = "0.14.0" source = { editable = "." } dependencies = [ { name = "certifi" }, @@ -1420,9 +1371,9 @@ plot = [ [package.dev-dependencies] dev = [ { name = "covdefaults" }, + { name = "folium" }, { name = "pytest" }, { name = "pytest-cov" }, - { name = "pytest-xdist" }, ] doc = [ { name = "furo" }, @@ -1442,25 +1393,25 @@ doc = [ requires-dist = [ { name = "certifi", specifier = ">=2023.5.7" }, { name = "geopandas", specifier = ">=1.0.0" }, - { name = "matplotlib", marker = "extra == 'plot'", specifier = ">=3.7.2" }, - { name = "networkx", marker = "extra == 'graph'", specifier = ">=3.0.0" }, - { name = "numpy", specifier = ">=1.21.5" }, - { name = "pandas", specifier = ">=1.4.0" }, + { name = "matplotlib", marker = "extra == 'plot'", specifier = ">=3.9.0" }, + { name = "networkx", marker = "extra == 'graph'", specifier = ">=3.3.0" }, + { name = "numpy", specifier = ">=2.0.0" }, + { name = "pandas", specifier = ">=2.1.0" }, { name = "pint", specifier = ">=0.21.0" }, { name = "platformdirs", specifier = ">=4.0.0" }, { name = "pyproj", specifier = ">=3.3.0" }, - { name = "roseau-load-flow-engine", specifier = "==0.18.1" }, + { name = "roseau-load-flow-engine", specifier = "==0.19.0" }, { name = "shapely", specifier = ">=2.0.0" }, { name = "typing-extensions", specifier = ">=4.6.2" }, ] -provides-extras = ["plot", "graph"] +provides-extras = ["graph", "plot"] [package.metadata.requires-dev] dev = [ { name = "covdefaults", specifier = ">=2.3.0" }, - { name = "pytest", specifier = ">=8.0.0" }, + { name = "folium", specifier = ">=0.20.0" }, + { name = "pytest", specifier = ">=9.0.0" }, { name = "pytest-cov", specifier = ">=5.0.0" }, - { name = "pytest-xdist", specifier = ">=3.1.0" }, ] doc = [ { name = "furo", specifier = ">=2022.9.29" }, @@ -1478,67 +1429,75 @@ doc = [ [[package]] name = "roseau-load-flow-engine" -version = "0.18.1" +version = "0.19.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "numpy" }, ] wheels = [ - { url = "https://files.pythonhosted.org/packages/25/8f/ab1d235b9d964d93e05201534c5c21daceb660d6ac8f7fdfce4c17e862b0/roseau_load_flow_engine-0.18.1-cp311-abi3-macosx_14_0_arm64.whl", hash = "sha256:5dccdf347c8139293671372bf31eea0e0b2c2a7d3a7eaa2c05d546f0509e1a99", size = 1187969, upload-time = "2025-09-03T17:44:28.595Z" }, - { url = "https://files.pythonhosted.org/packages/6f/ad/f90914e4f5cba8316e4305968a35f215a6e5070681c658494c029a8b9517/roseau_load_flow_engine-0.18.1-cp311-abi3-manylinux_2_34_x86_64.whl", hash = "sha256:eb9415ec0a766afd126bf191480b3e298c278cfebebc0fcf77e170adfa01f813", size = 2332425, upload-time = "2025-09-03T17:44:30.749Z" }, - { url = "https://files.pythonhosted.org/packages/bd/8e/7e41f6a3a785ce610cafb2b66182733444e210353b0c9a8ed5a842996e9d/roseau_load_flow_engine-0.18.1-cp311-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:37f396996a8f8d0423a9a55fce7092c36f6da7848f213bac6ab152ed05a8499d", size = 3267696, upload-time = "2025-09-03T17:44:32.331Z" }, - { url = "https://files.pythonhosted.org/packages/69/26/5cee8778ed86d794890d659a3f5987f07e81bfc983d61d82bd144318d8e4/roseau_load_flow_engine-0.18.1-cp311-abi3-win_amd64.whl", hash = "sha256:ac79912213cfdace50574ad765617a8e367fca7ccecca71a28427b852837855c", size = 1545877, upload-time = "2025-09-03T17:44:34.138Z" }, - { url = "https://files.pythonhosted.org/packages/c5/58/5604048fec4b910294684373392795330505db6759bc639183676bd1d76c/roseau_load_flow_engine-0.18.1-cp313-cp313t-macosx_14_0_arm64.whl", hash = "sha256:7a2ff764bb3227aa3f3a3a5a5e4573bfbc35b128540ba92371a70ecb00c2f8b7", size = 1214703, upload-time = "2025-09-03T17:44:36.268Z" }, - { url = "https://files.pythonhosted.org/packages/46/e8/58bc39b67871301d01c0bac2b69b17e36ac003d6054ea6ee1357abc5ce3c/roseau_load_flow_engine-0.18.1-cp313-cp313t-manylinux_2_34_x86_64.whl", hash = "sha256:6246cc9978dc7e341033cef66bbf1a9fea2ad7aa520ce1d1b8a401894e96d5f1", size = 2321626, upload-time = "2025-09-03T17:44:38.076Z" }, - { url = "https://files.pythonhosted.org/packages/f4/99/19eb864a9e3cde37394f15fbced023210d32cc5c7dff49687675dab05aa3/roseau_load_flow_engine-0.18.1-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:590f14cc596e1cefeb05d2320d9220da68e9ae64819616bf75967bc8bf80ce69", size = 6676925, upload-time = "2025-09-03T17:44:40.111Z" }, - { url = "https://files.pythonhosted.org/packages/bc/f0/444f0ae275d72d123beb27843ef1d3c6b94b4818a527486c47c42b67b4e6/roseau_load_flow_engine-0.18.1-cp313-cp313t-win_amd64.whl", hash = "sha256:390372cef52e345f78e82a8e41750cece712e0f483f5e41d17152087b420113a", size = 1576411, upload-time = "2025-09-03T17:44:42.068Z" }, - { url = "https://files.pythonhosted.org/packages/eb/5e/58a00f59294ff9121f8180e51a9a3ed58f2c8e806feb3f26793f8034f90e/roseau_load_flow_engine-0.18.1-cp314-cp314t-macosx_14_0_arm64.whl", hash = "sha256:bebd787048abb0b1851e5cfabd868114db5d93671b032c04a9f2e0024ee57740", size = 1214563, upload-time = "2025-09-03T17:44:44.198Z" }, - { url = "https://files.pythonhosted.org/packages/29/66/a3850276cf3d0759eab5633aee3bae97ea057865fc387d78f9df31283210/roseau_load_flow_engine-0.18.1-cp314-cp314t-manylinux_2_34_x86_64.whl", hash = "sha256:15e9df62b650f0d0fc174b1398c13dc68176a00585e5bb057e3711b8e76e15b8", size = 2321662, upload-time = "2025-09-03T17:44:46.05Z" }, - { url = "https://files.pythonhosted.org/packages/05/dc/f4a15100aa81931e56bed6daee2d8c2dd6c8895f3e7794b331531b728164/roseau_load_flow_engine-0.18.1-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:2e203b45c6c4a8aa8d0ae6bab5dde55d0251540867d4d7ef0a1c1ce26db9fefd", size = 6676684, upload-time = "2025-09-03T17:44:49.142Z" }, - { url = "https://files.pythonhosted.org/packages/69/96/586cd5c61c887386e26b7908a3e537e7d50af6740db7bbfeb4f9d36a0e67/roseau_load_flow_engine-0.18.1-cp314-cp314t-win_amd64.whl", hash = "sha256:e487c02cf90aaa5e4dda52206946945a80797e07ddb698dcf605ee73ce916734", size = 1627427, upload-time = "2025-09-03T17:44:51.063Z" }, + { url = "https://files.pythonhosted.org/packages/7b/8a/408f96b8fd5989f6dcdcb3b50f8c2fb570c17bbc9fcec9c86e59b9867918/roseau_load_flow_engine-0.19.0-cp312-abi3-macosx_14_0_arm64.whl", hash = "sha256:ac47c6847c87e00b824ae039cf8d7b6bd49db5515379b860df9b3812754d451d", size = 1205069, upload-time = "2026-01-21T16:45:57.449Z" }, + { url = "https://files.pythonhosted.org/packages/e2/06/4bad543fc3e812e910b799497a2da0f17e774275f6a013ae9b7a4d34dfb3/roseau_load_flow_engine-0.19.0-cp312-abi3-manylinux_2_34_x86_64.whl", hash = "sha256:2eb80805a0bf88cc01dc2ec68272057b97cd32894e5503f3fa2f667f347985e8", size = 2403310, upload-time = "2026-01-21T16:46:04.621Z" }, + { url = "https://files.pythonhosted.org/packages/b4/bf/6354e292bdf31edc6fb1bfc039874e428a445eee226090633c532bed56d8/roseau_load_flow_engine-0.19.0-cp312-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:2c34094c3987f1031f450fcd01b211f151b485a034efc9b633d54ed87ae0558b", size = 3253936, upload-time = "2026-01-21T16:46:06.678Z" }, + { url = "https://files.pythonhosted.org/packages/88/23/b0fa72548cd0472077f5a7adf4d827bce44a8e1d70abf436a319e79b3c6e/roseau_load_flow_engine-0.19.0-cp312-abi3-win_amd64.whl", hash = "sha256:6a6de20eb9509c4acc0d86b4425bdd3390729ecc61f1e6ff664cc132ac58c356", size = 1566444, upload-time = "2026-01-21T16:46:02.387Z" }, + { url = "https://files.pythonhosted.org/packages/c5/48/20390efd3db0b6084338a9c4f3e9c1add09e00beb89fd95998cb95886893/roseau_load_flow_engine-0.19.0-cp313-cp313t-macosx_14_0_arm64.whl", hash = "sha256:8a69040cada98366de658e949cfe603ae3c1eabffe6d3fe3d158b19472321c12", size = 1232743, upload-time = "2026-01-21T16:46:15.25Z" }, + { url = "https://files.pythonhosted.org/packages/5b/e0/a3c79a4f19b7840a734a619f88d9b2d06fe22cb25faf9f6c1329277f61bd/roseau_load_flow_engine-0.19.0-cp313-cp313t-manylinux_2_34_x86_64.whl", hash = "sha256:6d9bc0329a08b7ad943e2b3bf761131a82211637715532d2efc7e7a29f2cb8fb", size = 2400839, upload-time = "2026-01-21T16:46:13.239Z" }, + { url = "https://files.pythonhosted.org/packages/ae/61/4802d42cfe97abacd9dcd30ad9392b18f78c7f12f1a45c1ac4eeec220ee4/roseau_load_flow_engine-0.19.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:03da1a12bbff942b8c5de20a058d85ebb089d8513cfbfcd680d8533cca376470", size = 3255297, upload-time = "2026-01-21T16:46:17.241Z" }, + { url = "https://files.pythonhosted.org/packages/e5/e4/bec49b00774b9ac337439682e71e61ac1efbd53062ad7d1aaa92aeb66152/roseau_load_flow_engine-0.19.0-cp313-cp313t-win_amd64.whl", hash = "sha256:8d0df75ea5dfb09303ebbbf09b5a1221a2c839b509e8dbb862fc1acf28ec53c3", size = 1595220, upload-time = "2026-01-21T16:46:11.513Z" }, + { url = "https://files.pythonhosted.org/packages/15/34/dbb27c04f7dc9908963e3ee12914ea5e3c6830c186bbb70b8dbe79de1760/roseau_load_flow_engine-0.19.0-cp314-cp314t-macosx_14_0_arm64.whl", hash = "sha256:7dd1d2dde756cc292e73e9003f77ee7d9566e8c5c11a626119e4aa06a8c88160", size = 1234572, upload-time = "2026-01-21T16:45:59Z" }, + { url = "https://files.pythonhosted.org/packages/93/c1/4f2bd49d44ecd30942b181b931180b692571d1c36924d32fcb56d8c7d0f0/roseau_load_flow_engine-0.19.0-cp314-cp314t-manylinux_2_34_x86_64.whl", hash = "sha256:3957ee7d15cef663690fe234c02681880e800306682684d8c2154d3bddec2555", size = 2401799, upload-time = "2026-01-21T16:46:19.253Z" }, + { url = "https://files.pythonhosted.org/packages/48/74/09e930f5b897d71ca428094125342520d8d35b75cb1215b6860fc48411aa/roseau_load_flow_engine-0.19.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:8b71559ed58cf42ad7c794629f2a2ba3c98ab730b8c688026020b94ca5803c26", size = 3255846, upload-time = "2026-01-21T16:46:09.767Z" }, + { url = "https://files.pythonhosted.org/packages/01/ac/d618905964769db22379e035e943bef5a3a740970af12fb7702e30645493/roseau_load_flow_engine-0.19.0-cp314-cp314t-win_amd64.whl", hash = "sha256:007f641a0bbca86acdb39aef8aa6ba16a53e14b6607120003e4ff0f9c3d39622", size = 1648027, upload-time = "2026-01-21T16:46:00.521Z" }, ] [[package]] name = "shapely" -version = "2.1.1" +version = "2.1.2" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "numpy" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/ca/3c/2da625233f4e605155926566c0e7ea8dda361877f48e8b1655e53456f252/shapely-2.1.1.tar.gz", hash = "sha256:500621967f2ffe9642454808009044c21e5b35db89ce69f8a2042c2ffd0e2772", size = 315422, upload-time = "2025-05-19T11:04:41.265Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/19/97/2df985b1e03f90c503796ad5ecd3d9ed305123b64d4ccb54616b30295b29/shapely-2.1.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:587a1aa72bc858fab9b8c20427b5f6027b7cbc92743b8e2c73b9de55aa71c7a7", size = 1819368, upload-time = "2025-05-19T11:03:55.937Z" }, - { url = "https://files.pythonhosted.org/packages/56/17/504518860370f0a28908b18864f43d72f03581e2b6680540ca668f07aa42/shapely-2.1.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:9fa5c53b0791a4b998f9ad84aad456c988600757a96b0a05e14bba10cebaaaea", size = 1625362, upload-time = "2025-05-19T11:03:57.06Z" }, - { url = "https://files.pythonhosted.org/packages/36/a1/9677337d729b79fce1ef3296aac6b8ef4743419086f669e8a8070eff8f40/shapely-2.1.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:aabecd038841ab5310d23495253f01c2a82a3aedae5ab9ca489be214aa458aa7", size = 2999005, upload-time = "2025-05-19T11:03:58.692Z" }, - { url = "https://files.pythonhosted.org/packages/a2/17/e09357274699c6e012bbb5a8ea14765a4d5860bb658df1931c9f90d53bd3/shapely-2.1.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:586f6aee1edec04e16227517a866df3e9a2e43c1f635efc32978bb3dc9c63753", size = 3108489, upload-time = "2025-05-19T11:04:00.059Z" }, - { url = "https://files.pythonhosted.org/packages/17/5d/93a6c37c4b4e9955ad40834f42b17260ca74ecf36df2e81bb14d12221b90/shapely-2.1.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:b9878b9e37ad26c72aada8de0c9cfe418d9e2ff36992a1693b7f65a075b28647", size = 3945727, upload-time = "2025-05-19T11:04:01.786Z" }, - { url = "https://files.pythonhosted.org/packages/a3/1a/ad696648f16fd82dd6bfcca0b3b8fbafa7aacc13431c7fc4c9b49e481681/shapely-2.1.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:d9a531c48f289ba355e37b134e98e28c557ff13965d4653a5228d0f42a09aed0", size = 4109311, upload-time = "2025-05-19T11:04:03.134Z" }, - { url = "https://files.pythonhosted.org/packages/d4/38/150dd245beab179ec0d4472bf6799bf18f21b1efbef59ac87de3377dbf1c/shapely-2.1.1-cp311-cp311-win32.whl", hash = "sha256:4866de2673a971820c75c0167b1f1cd8fb76f2d641101c23d3ca021ad0449bab", size = 1522982, upload-time = "2025-05-19T11:04:05.217Z" }, - { url = "https://files.pythonhosted.org/packages/93/5b/842022c00fbb051083c1c85430f3bb55565b7fd2d775f4f398c0ba8052ce/shapely-2.1.1-cp311-cp311-win_amd64.whl", hash = "sha256:20a9d79958b3d6c70d8a886b250047ea32ff40489d7abb47d01498c704557a93", size = 1703872, upload-time = "2025-05-19T11:04:06.791Z" }, - { url = "https://files.pythonhosted.org/packages/fb/64/9544dc07dfe80a2d489060791300827c941c451e2910f7364b19607ea352/shapely-2.1.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:2827365b58bf98efb60affc94a8e01c56dd1995a80aabe4b701465d86dcbba43", size = 1833021, upload-time = "2025-05-19T11:04:08.022Z" }, - { url = "https://files.pythonhosted.org/packages/07/aa/fb5f545e72e89b6a0f04a0effda144f5be956c9c312c7d4e00dfddbddbcf/shapely-2.1.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:a9c551f7fa7f1e917af2347fe983f21f212863f1d04f08eece01e9c275903fad", size = 1643018, upload-time = "2025-05-19T11:04:09.343Z" }, - { url = "https://files.pythonhosted.org/packages/03/46/61e03edba81de729f09d880ce7ae5c1af873a0814206bbfb4402ab5c3388/shapely-2.1.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:78dec4d4fbe7b1db8dc36de3031767e7ece5911fb7782bc9e95c5cdec58fb1e9", size = 2986417, upload-time = "2025-05-19T11:04:10.56Z" }, - { url = "https://files.pythonhosted.org/packages/1f/1e/83ec268ab8254a446b4178b45616ab5822d7b9d2b7eb6e27cf0b82f45601/shapely-2.1.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:872d3c0a7b8b37da0e23d80496ec5973c4692920b90de9f502b5beb994bbaaef", size = 3098224, upload-time = "2025-05-19T11:04:11.903Z" }, - { url = "https://files.pythonhosted.org/packages/f1/44/0c21e7717c243e067c9ef8fa9126de24239f8345a5bba9280f7bb9935959/shapely-2.1.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:2e2b9125ebfbc28ecf5353511de62f75a8515ae9470521c9a693e4bb9fbe0cf1", size = 3925982, upload-time = "2025-05-19T11:04:13.224Z" }, - { url = "https://files.pythonhosted.org/packages/15/50/d3b4e15fefc103a0eb13d83bad5f65cd6e07a5d8b2ae920e767932a247d1/shapely-2.1.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:4b96cea171b3d7f6786976a0520f178c42792897653ecca0c5422fb1e6946e6d", size = 4089122, upload-time = "2025-05-19T11:04:14.477Z" }, - { url = "https://files.pythonhosted.org/packages/bd/05/9a68f27fc6110baeedeeebc14fd86e73fa38738c5b741302408fb6355577/shapely-2.1.1-cp312-cp312-win32.whl", hash = "sha256:39dca52201e02996df02e447f729da97cfb6ff41a03cb50f5547f19d02905af8", size = 1522437, upload-time = "2025-05-19T11:04:16.203Z" }, - { url = "https://files.pythonhosted.org/packages/bc/e9/a4560e12b9338842a1f82c9016d2543eaa084fce30a1ca11991143086b57/shapely-2.1.1-cp312-cp312-win_amd64.whl", hash = "sha256:13d643256f81d55a50013eff6321142781cf777eb6a9e207c2c9e6315ba6044a", size = 1703479, upload-time = "2025-05-19T11:04:18.497Z" }, - { url = "https://files.pythonhosted.org/packages/71/8e/2bc836437f4b84d62efc1faddce0d4e023a5d990bbddd3c78b2004ebc246/shapely-2.1.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:3004a644d9e89e26c20286d5fdc10f41b1744c48ce910bd1867fdff963fe6c48", size = 1832107, upload-time = "2025-05-19T11:04:19.736Z" }, - { url = "https://files.pythonhosted.org/packages/12/a2/12c7cae5b62d5d851c2db836eadd0986f63918a91976495861f7c492f4a9/shapely-2.1.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:1415146fa12d80a47d13cfad5310b3c8b9c2aa8c14a0c845c9d3d75e77cb54f6", size = 1642355, upload-time = "2025-05-19T11:04:21.035Z" }, - { url = "https://files.pythonhosted.org/packages/5b/7e/6d28b43d53fea56de69c744e34c2b999ed4042f7a811dc1bceb876071c95/shapely-2.1.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:21fcab88b7520820ec16d09d6bea68652ca13993c84dffc6129dc3607c95594c", size = 2968871, upload-time = "2025-05-19T11:04:22.167Z" }, - { url = "https://files.pythonhosted.org/packages/dd/87/1017c31e52370b2b79e4d29e07cbb590ab9e5e58cf7e2bdfe363765d6251/shapely-2.1.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e5ce6a5cc52c974b291237a96c08c5592e50f066871704fb5b12be2639d9026a", size = 3080830, upload-time = "2025-05-19T11:04:23.997Z" }, - { url = "https://files.pythonhosted.org/packages/1d/fe/f4a03d81abd96a6ce31c49cd8aaba970eaaa98e191bd1e4d43041e57ae5a/shapely-2.1.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:04e4c12a45a1d70aeb266618d8cf81a2de9c4df511b63e105b90bfdfb52146de", size = 3908961, upload-time = "2025-05-19T11:04:25.702Z" }, - { url = "https://files.pythonhosted.org/packages/ef/59/7605289a95a6844056a2017ab36d9b0cb9d6a3c3b5317c1f968c193031c9/shapely-2.1.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:6ca74d851ca5264aae16c2b47e96735579686cb69fa93c4078070a0ec845b8d8", size = 4079623, upload-time = "2025-05-19T11:04:27.171Z" }, - { url = "https://files.pythonhosted.org/packages/bc/4d/9fea036eff2ef4059d30247128b2d67aaa5f0b25e9fc27e1d15cc1b84704/shapely-2.1.1-cp313-cp313-win32.whl", hash = "sha256:fd9130501bf42ffb7e0695b9ea17a27ae8ce68d50b56b6941c7f9b3d3453bc52", size = 1521916, upload-time = "2025-05-19T11:04:28.405Z" }, - { url = "https://files.pythonhosted.org/packages/12/d9/6d13b8957a17c95794f0c4dfb65ecd0957e6c7131a56ce18d135c1107a52/shapely-2.1.1-cp313-cp313-win_amd64.whl", hash = "sha256:ab8d878687b438a2f4c138ed1a80941c6ab0029e0f4c785ecfe114413b498a97", size = 1702746, upload-time = "2025-05-19T11:04:29.643Z" }, - { url = "https://files.pythonhosted.org/packages/60/36/b1452e3e7f35f5f6454d96f3be6e2bb87082720ff6c9437ecc215fa79be0/shapely-2.1.1-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:0c062384316a47f776305ed2fa22182717508ffdeb4a56d0ff4087a77b2a0f6d", size = 1833482, upload-time = "2025-05-19T11:04:30.852Z" }, - { url = "https://files.pythonhosted.org/packages/ce/ca/8e6f59be0718893eb3e478141285796a923636dc8f086f83e5b0ec0036d0/shapely-2.1.1-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:4ecf6c196b896e8f1360cc219ed4eee1c1e5f5883e505d449f263bd053fb8c05", size = 1642256, upload-time = "2025-05-19T11:04:32.068Z" }, - { url = "https://files.pythonhosted.org/packages/ab/78/0053aea449bb1d4503999525fec6232f049abcdc8df60d290416110de943/shapely-2.1.1-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fb00070b4c4860f6743c600285109c273cca5241e970ad56bb87bef0be1ea3a0", size = 3016614, upload-time = "2025-05-19T11:04:33.7Z" }, - { url = "https://files.pythonhosted.org/packages/ee/53/36f1b1de1dfafd1b457dcbafa785b298ce1b8a3e7026b79619e708a245d5/shapely-2.1.1-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d14a9afa5fa980fbe7bf63706fdfb8ff588f638f145a1d9dbc18374b5b7de913", size = 3093542, upload-time = "2025-05-19T11:04:34.952Z" }, - { url = "https://files.pythonhosted.org/packages/b9/bf/0619f37ceec6b924d84427c88835b61f27f43560239936ff88915c37da19/shapely-2.1.1-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:b640e390dabde790e3fb947198b466e63223e0a9ccd787da5f07bcb14756c28d", size = 3945961, upload-time = "2025-05-19T11:04:36.32Z" }, - { url = "https://files.pythonhosted.org/packages/93/c9/20ca4afeb572763b07a7997f00854cb9499df6af85929e93012b189d8917/shapely-2.1.1-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:69e08bf9697c1b73ec6aa70437db922bafcea7baca131c90c26d59491a9760f9", size = 4089514, upload-time = "2025-05-19T11:04:37.683Z" }, - { url = "https://files.pythonhosted.org/packages/33/6a/27036a5a560b80012a544366bceafd491e8abb94a8db14047b5346b5a749/shapely-2.1.1-cp313-cp313t-win32.whl", hash = "sha256:ef2d09d5a964cc90c2c18b03566cf918a61c248596998a0301d5b632beadb9db", size = 1540607, upload-time = "2025-05-19T11:04:38.925Z" }, - { url = "https://files.pythonhosted.org/packages/ea/f1/5e9b3ba5c7aa7ebfaf269657e728067d16a7c99401c7973ddf5f0cf121bd/shapely-2.1.1-cp313-cp313t-win_amd64.whl", hash = "sha256:8cb8f17c377260452e9d7720eeaf59082c5f8ea48cf104524d953e5d36d4bdb7", size = 1723061, upload-time = "2025-05-19T11:04:40.082Z" }, +sdist = { url = "https://files.pythonhosted.org/packages/4d/bc/0989043118a27cccb4e906a46b7565ce36ca7b57f5a18b78f4f1b0f72d9d/shapely-2.1.2.tar.gz", hash = "sha256:2ed4ecb28320a433db18a5bf029986aa8afcfd740745e78847e330d5d94922a9", size = 315489, upload-time = "2025-09-24T13:51:41.432Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/24/c0/f3b6453cf2dfa99adc0ba6675f9aaff9e526d2224cbd7ff9c1a879238693/shapely-2.1.2-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:fe2533caae6a91a543dec62e8360fe86ffcdc42a7c55f9dfd0128a977a896b94", size = 1833550, upload-time = "2025-09-24T13:50:30.019Z" }, + { url = "https://files.pythonhosted.org/packages/86/07/59dee0bc4b913b7ab59ab1086225baca5b8f19865e6101db9ebb7243e132/shapely-2.1.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:ba4d1333cc0bc94381d6d4308d2e4e008e0bd128bdcff5573199742ee3634359", size = 1643556, upload-time = "2025-09-24T13:50:32.291Z" }, + { url = "https://files.pythonhosted.org/packages/26/29/a5397e75b435b9895cd53e165083faed5d12fd9626eadec15a83a2411f0f/shapely-2.1.2-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:0bd308103340030feef6c111d3eb98d50dc13feea33affc8a6f9fa549e9458a3", size = 2988308, upload-time = "2025-09-24T13:50:33.862Z" }, + { url = "https://files.pythonhosted.org/packages/b9/37/e781683abac55dde9771e086b790e554811a71ed0b2b8a1e789b7430dd44/shapely-2.1.2-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:1e7d4d7ad262a48bb44277ca12c7c78cb1b0f56b32c10734ec9a1d30c0b0c54b", size = 3099844, upload-time = "2025-09-24T13:50:35.459Z" }, + { url = "https://files.pythonhosted.org/packages/d8/f3/9876b64d4a5a321b9dc482c92bb6f061f2fa42131cba643c699f39317cb9/shapely-2.1.2-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:e9eddfe513096a71896441a7c37db72da0687b34752c4e193577a145c71736fc", size = 3988842, upload-time = "2025-09-24T13:50:37.478Z" }, + { url = "https://files.pythonhosted.org/packages/d1/a0/704c7292f7014c7e74ec84eddb7b109e1fbae74a16deae9c1504b1d15565/shapely-2.1.2-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:980c777c612514c0cf99bc8a9de6d286f5e186dcaf9091252fcd444e5638193d", size = 4152714, upload-time = "2025-09-24T13:50:39.9Z" }, + { url = "https://files.pythonhosted.org/packages/53/46/319c9dc788884ad0785242543cdffac0e6530e4d0deb6c4862bc4143dcf3/shapely-2.1.2-cp312-cp312-win32.whl", hash = "sha256:9111274b88e4d7b54a95218e243282709b330ef52b7b86bc6aaf4f805306f454", size = 1542745, upload-time = "2025-09-24T13:50:41.414Z" }, + { url = "https://files.pythonhosted.org/packages/ec/bf/cb6c1c505cb31e818e900b9312d514f381fbfa5c4363edfce0fcc4f8c1a4/shapely-2.1.2-cp312-cp312-win_amd64.whl", hash = "sha256:743044b4cfb34f9a67205cee9279feaf60ba7d02e69febc2afc609047cb49179", size = 1722861, upload-time = "2025-09-24T13:50:43.35Z" }, + { url = "https://files.pythonhosted.org/packages/c3/90/98ef257c23c46425dc4d1d31005ad7c8d649fe423a38b917db02c30f1f5a/shapely-2.1.2-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:b510dda1a3672d6879beb319bc7c5fd302c6c354584690973c838f46ec3e0fa8", size = 1832644, upload-time = "2025-09-24T13:50:44.886Z" }, + { url = "https://files.pythonhosted.org/packages/6d/ab/0bee5a830d209adcd3a01f2d4b70e587cdd9fd7380d5198c064091005af8/shapely-2.1.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:8cff473e81017594d20ec55d86b54bc635544897e13a7cfc12e36909c5309a2a", size = 1642887, upload-time = "2025-09-24T13:50:46.735Z" }, + { url = "https://files.pythonhosted.org/packages/2d/5e/7d7f54ba960c13302584c73704d8c4d15404a51024631adb60b126a4ae88/shapely-2.1.2-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:fe7b77dc63d707c09726b7908f575fc04ff1d1ad0f3fb92aec212396bc6cfe5e", size = 2970931, upload-time = "2025-09-24T13:50:48.374Z" }, + { url = "https://files.pythonhosted.org/packages/f2/a2/83fc37e2a58090e3d2ff79175a95493c664bcd0b653dd75cb9134645a4e5/shapely-2.1.2-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:7ed1a5bbfb386ee8332713bf7508bc24e32d24b74fc9a7b9f8529a55db9f4ee6", size = 3082855, upload-time = "2025-09-24T13:50:50.037Z" }, + { url = "https://files.pythonhosted.org/packages/44/2b/578faf235a5b09f16b5f02833c53822294d7f21b242f8e2d0cf03fb64321/shapely-2.1.2-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:a84e0582858d841d54355246ddfcbd1fce3179f185da7470f41ce39d001ee1af", size = 3979960, upload-time = "2025-09-24T13:50:51.74Z" }, + { url = "https://files.pythonhosted.org/packages/4d/04/167f096386120f692cc4ca02f75a17b961858997a95e67a3cb6a7bbd6b53/shapely-2.1.2-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:dc3487447a43d42adcdf52d7ac73804f2312cbfa5d433a7d2c506dcab0033dfd", size = 4142851, upload-time = "2025-09-24T13:50:53.49Z" }, + { url = "https://files.pythonhosted.org/packages/48/74/fb402c5a6235d1c65a97348b48cdedb75fb19eca2b1d66d04969fc1c6091/shapely-2.1.2-cp313-cp313-win32.whl", hash = "sha256:9c3a3c648aedc9f99c09263b39f2d8252f199cb3ac154fadc173283d7d111350", size = 1541890, upload-time = "2025-09-24T13:50:55.337Z" }, + { url = "https://files.pythonhosted.org/packages/41/47/3647fe7ad990af60ad98b889657a976042c9988c2807cf322a9d6685f462/shapely-2.1.2-cp313-cp313-win_amd64.whl", hash = "sha256:ca2591bff6645c216695bdf1614fca9c82ea1144d4a7591a466fef64f28f0715", size = 1722151, upload-time = "2025-09-24T13:50:57.153Z" }, + { url = "https://files.pythonhosted.org/packages/3c/49/63953754faa51ffe7d8189bfbe9ca34def29f8c0e34c67cbe2a2795f269d/shapely-2.1.2-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:2d93d23bdd2ed9dc157b46bc2f19b7da143ca8714464249bef6771c679d5ff40", size = 1834130, upload-time = "2025-09-24T13:50:58.49Z" }, + { url = "https://files.pythonhosted.org/packages/7f/ee/dce001c1984052970ff60eb4727164892fb2d08052c575042a47f5a9e88f/shapely-2.1.2-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:01d0d304b25634d60bd7cf291828119ab55a3bab87dc4af1e44b07fb225f188b", size = 1642802, upload-time = "2025-09-24T13:50:59.871Z" }, + { url = "https://files.pythonhosted.org/packages/da/e7/fc4e9a19929522877fa602f705706b96e78376afb7fad09cad5b9af1553c/shapely-2.1.2-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:8d8382dd120d64b03698b7298b89611a6ea6f55ada9d39942838b79c9bc89801", size = 3018460, upload-time = "2025-09-24T13:51:02.08Z" }, + { url = "https://files.pythonhosted.org/packages/a1/18/7519a25db21847b525696883ddc8e6a0ecaa36159ea88e0fef11466384d0/shapely-2.1.2-cp313-cp313t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:19efa3611eef966e776183e338b2d7ea43569ae99ab34f8d17c2c054d3205cc0", size = 3095223, upload-time = "2025-09-24T13:51:04.472Z" }, + { url = "https://files.pythonhosted.org/packages/48/de/b59a620b1f3a129c3fecc2737104a0a7e04e79335bd3b0a1f1609744cf17/shapely-2.1.2-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:346ec0c1a0fcd32f57f00e4134d1200e14bf3f5ae12af87ba83ca275c502498c", size = 4030760, upload-time = "2025-09-24T13:51:06.455Z" }, + { url = "https://files.pythonhosted.org/packages/96/b3/c6655ee7232b417562bae192ae0d3ceaadb1cc0ffc2088a2ddf415456cc2/shapely-2.1.2-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:6305993a35989391bd3476ee538a5c9a845861462327efe00dd11a5c8c709a99", size = 4170078, upload-time = "2025-09-24T13:51:08.584Z" }, + { url = "https://files.pythonhosted.org/packages/a0/8e/605c76808d73503c9333af8f6cbe7e1354d2d238bda5f88eea36bfe0f42a/shapely-2.1.2-cp313-cp313t-win32.whl", hash = "sha256:c8876673449f3401f278c86eb33224c5764582f72b653a415d0e6672fde887bf", size = 1559178, upload-time = "2025-09-24T13:51:10.73Z" }, + { url = "https://files.pythonhosted.org/packages/36/f7/d317eb232352a1f1444d11002d477e54514a4a6045536d49d0c59783c0da/shapely-2.1.2-cp313-cp313t-win_amd64.whl", hash = "sha256:4a44bc62a10d84c11a7a3d7c1c4fe857f7477c3506e24c9062da0db0ae0c449c", size = 1739756, upload-time = "2025-09-24T13:51:12.105Z" }, + { url = "https://files.pythonhosted.org/packages/fc/c4/3ce4c2d9b6aabd27d26ec988f08cb877ba9e6e96086eff81bfea93e688c7/shapely-2.1.2-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:9a522f460d28e2bf4e12396240a5fc1518788b2fcd73535166d748399ef0c223", size = 1831290, upload-time = "2025-09-24T13:51:13.56Z" }, + { url = "https://files.pythonhosted.org/packages/17/b9/f6ab8918fc15429f79cb04afa9f9913546212d7fb5e5196132a2af46676b/shapely-2.1.2-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:1ff629e00818033b8d71139565527ced7d776c269a49bd78c9df84e8f852190c", size = 1641463, upload-time = "2025-09-24T13:51:14.972Z" }, + { url = "https://files.pythonhosted.org/packages/a5/57/91d59ae525ca641e7ac5551c04c9503aee6f29b92b392f31790fcb1a4358/shapely-2.1.2-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:f67b34271dedc3c653eba4e3d7111aa421d5be9b4c4c7d38d30907f796cb30df", size = 2970145, upload-time = "2025-09-24T13:51:16.961Z" }, + { url = "https://files.pythonhosted.org/packages/8a/cb/4948be52ee1da6927831ab59e10d4c29baa2a714f599f1f0d1bc747f5777/shapely-2.1.2-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:21952dc00df38a2c28375659b07a3979d22641aeb104751e769c3ee825aadecf", size = 3073806, upload-time = "2025-09-24T13:51:18.712Z" }, + { url = "https://files.pythonhosted.org/packages/03/83/f768a54af775eb41ef2e7bec8a0a0dbe7d2431c3e78c0a8bdba7ab17e446/shapely-2.1.2-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:1f2f33f486777456586948e333a56ae21f35ae273be99255a191f5c1fa302eb4", size = 3980803, upload-time = "2025-09-24T13:51:20.37Z" }, + { url = "https://files.pythonhosted.org/packages/9f/cb/559c7c195807c91c79d38a1f6901384a2878a76fbdf3f1048893a9b7534d/shapely-2.1.2-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:cf831a13e0d5a7eb519e96f58ec26e049b1fad411fc6fc23b162a7ce04d9cffc", size = 4133301, upload-time = "2025-09-24T13:51:21.887Z" }, + { url = "https://files.pythonhosted.org/packages/80/cd/60d5ae203241c53ef3abd2ef27c6800e21afd6c94e39db5315ea0cbafb4a/shapely-2.1.2-cp314-cp314-win32.whl", hash = "sha256:61edcd8d0d17dd99075d320a1dd39c0cb9616f7572f10ef91b4b5b00c4aeb566", size = 1583247, upload-time = "2025-09-24T13:51:23.401Z" }, + { url = "https://files.pythonhosted.org/packages/74/d4/135684f342e909330e50d31d441ace06bf83c7dc0777e11043f99167b123/shapely-2.1.2-cp314-cp314-win_amd64.whl", hash = "sha256:a444e7afccdb0999e203b976adb37ea633725333e5b119ad40b1ca291ecf311c", size = 1773019, upload-time = "2025-09-24T13:51:24.873Z" }, + { url = "https://files.pythonhosted.org/packages/a3/05/a44f3f9f695fa3ada22786dc9da33c933da1cbc4bfe876fe3a100bafe263/shapely-2.1.2-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:5ebe3f84c6112ad3d4632b1fd2290665aa75d4cef5f6c5d77c4c95b324527c6a", size = 1834137, upload-time = "2025-09-24T13:51:26.665Z" }, + { url = "https://files.pythonhosted.org/packages/52/7e/4d57db45bf314573427b0a70dfca15d912d108e6023f623947fa69f39b72/shapely-2.1.2-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:5860eb9f00a1d49ebb14e881f5caf6c2cf472c7fd38bd7f253bbd34f934eb076", size = 1642884, upload-time = "2025-09-24T13:51:28.029Z" }, + { url = "https://files.pythonhosted.org/packages/5a/27/4e29c0a55d6d14ad7422bf86995d7ff3f54af0eba59617eb95caf84b9680/shapely-2.1.2-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:b705c99c76695702656327b819c9660768ec33f5ce01fa32b2af62b56ba400a1", size = 3018320, upload-time = "2025-09-24T13:51:29.903Z" }, + { url = "https://files.pythonhosted.org/packages/9f/bb/992e6a3c463f4d29d4cd6ab8963b75b1b1040199edbd72beada4af46bde5/shapely-2.1.2-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:a1fd0ea855b2cf7c9cddaf25543e914dd75af9de08785f20ca3085f2c9ca60b0", size = 3094931, upload-time = "2025-09-24T13:51:32.699Z" }, + { url = "https://files.pythonhosted.org/packages/9c/16/82e65e21070e473f0ed6451224ed9fa0be85033d17e0c6e7213a12f59d12/shapely-2.1.2-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:df90e2db118c3671a0754f38e36802db75fe0920d211a27481daf50a711fdf26", size = 4030406, upload-time = "2025-09-24T13:51:34.189Z" }, + { url = "https://files.pythonhosted.org/packages/7c/75/c24ed871c576d7e2b64b04b1fe3d075157f6eb54e59670d3f5ffb36e25c7/shapely-2.1.2-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:361b6d45030b4ac64ddd0a26046906c8202eb60d0f9f53085f5179f1d23021a0", size = 4169511, upload-time = "2025-09-24T13:51:36.297Z" }, + { url = "https://files.pythonhosted.org/packages/b1/f7/b3d1d6d18ebf55236eec1c681ce5e665742aab3c0b7b232720a7d43df7b6/shapely-2.1.2-cp314-cp314t-win32.whl", hash = "sha256:b54df60f1fbdecc8ebc2c5b11870461a6417b3d617f555e5033f1505d36e5735", size = 1602607, upload-time = "2025-09-24T13:51:37.757Z" }, + { url = "https://files.pythonhosted.org/packages/9a/f6/f09272a71976dfc138129b8faf435d064a811ae2f708cb147dccdf7aacdb/shapely-2.1.2-cp314-cp314t-win_amd64.whl", hash = "sha256:0036ac886e0923417932c2e6369b6c52e38e0ff5d9120b90eef5cd9a5fc5cae9", size = 1796682, upload-time = "2025-09-24T13:51:39.233Z" }, ] [[package]] @@ -1561,16 +1520,16 @@ wheels = [ [[package]] name = "soupsieve" -version = "2.8" +version = "2.8.3" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/6d/e6/21ccce3262dd4889aa3332e5a119a3491a95e8f60939870a3a035aabac0d/soupsieve-2.8.tar.gz", hash = "sha256:e2dd4a40a628cb5f28f6d4b0db8800b8f581b65bb380b97de22ba5ca8d72572f", size = 103472, upload-time = "2025-08-27T15:39:51.78Z" } +sdist = { url = "https://files.pythonhosted.org/packages/7b/ae/2d9c981590ed9999a0d91755b47fc74f74de286b0f5cee14c9269041e6c4/soupsieve-2.8.3.tar.gz", hash = "sha256:3267f1eeea4251fb42728b6dfb746edc9acaffc4a45b27e19450b676586e8349", size = 118627, upload-time = "2026-01-20T04:27:02.457Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/14/a0/bb38d3b76b8cae341dad93a2dd83ab7462e6dbcdd84d43f54ee60a8dc167/soupsieve-2.8-py3-none-any.whl", hash = "sha256:0cc76456a30e20f5d7f2e14a98a4ae2ee4e5abdc7c5ea0aafe795f344bc7984c", size = 36679, upload-time = "2025-08-27T15:39:50.179Z" }, + { url = "https://files.pythonhosted.org/packages/46/2c/1462b1d0a634697ae9e55b3cecdcb64788e8b7d63f54d923fcd0bb140aed/soupsieve-2.8.3-py3-none-any.whl", hash = "sha256:ed64f2ba4eebeab06cc4962affce381647455978ffc1e36bb79a545b91f45a95", size = 37016, upload-time = "2026-01-20T04:27:01.012Z" }, ] [[package]] name = "sphinx" -version = "8.2.3" +version = "9.1.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "alabaster" }, @@ -1582,7 +1541,7 @@ dependencies = [ { name = "packaging" }, { name = "pygments" }, { name = "requests" }, - { name = "roman-numerals-py" }, + { name = "roman-numerals" }, { name = "snowballstemmer" }, { name = "sphinxcontrib-applehelp" }, { name = "sphinxcontrib-devhelp" }, @@ -1591,14 +1550,14 @@ dependencies = [ { name = "sphinxcontrib-qthelp" }, { name = "sphinxcontrib-serializinghtml" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/38/ad/4360e50ed56cb483667b8e6dadf2d3fda62359593faabbe749a27c4eaca6/sphinx-8.2.3.tar.gz", hash = "sha256:398ad29dee7f63a75888314e9424d40f52ce5a6a87ae88e7071e80af296ec348", size = 8321876, upload-time = "2025-03-02T22:31:59.658Z" } +sdist = { url = "https://files.pythonhosted.org/packages/cd/bd/f08eb0f4eed5c83f1ba2a3bd18f7745a2b1525fad70660a1c00224ec468a/sphinx-9.1.0.tar.gz", hash = "sha256:7741722357dd75f8190766926071fed3bdc211c74dd2d7d4df5404da95930ddb", size = 8718324, upload-time = "2025-12-31T15:09:27.646Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/31/53/136e9eca6e0b9dc0e1962e2c908fbea2e5ac000c2a2fbd9a35797958c48b/sphinx-8.2.3-py3-none-any.whl", hash = "sha256:4405915165f13521d875a8c29c8970800a0141c14cc5416a38feca4ea5d9b9c3", size = 3589741, upload-time = "2025-03-02T22:31:56.836Z" }, + { url = "https://files.pythonhosted.org/packages/73/f7/b1884cb3188ab181fc81fa00c266699dab600f927a964df02ec3d5d1916a/sphinx-9.1.0-py3-none-any.whl", hash = "sha256:c84fdd4e782504495fe4f2c0b3413d6c2bf388589bb352d439b2a3bb99991978", size = 3921742, upload-time = "2025-12-31T15:09:25.561Z" }, ] [[package]] name = "sphinx-autoapi" -version = "3.6.0" +version = "3.6.1" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "astroid" }, @@ -1606,9 +1565,9 @@ dependencies = [ { name = "pyyaml" }, { name = "sphinx" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/7f/a8/22b379a2a75ccb881217d3d4ae56d7d35f2d1bb4c8c0c51d0253676746a1/sphinx_autoapi-3.6.0.tar.gz", hash = "sha256:c685f274e41d0842ae7e199460c322c4bd7fec816ccc2da8d806094b4f64af06", size = 55417, upload-time = "2025-02-18T01:50:55.241Z" } +sdist = { url = "https://files.pythonhosted.org/packages/a9/ad/c627976d5f4d812b203ef1136108bbd81ef9bbbfd3f700f1295c322c22e6/sphinx_autoapi-3.6.1.tar.gz", hash = "sha256:1ff2992b7d5e39ccf92413098a376e0f91e7b4ca532c4f3e71298dbc8a4a9900", size = 55456, upload-time = "2025-10-06T16:21:22.888Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/58/17/0eda9dc80fcaf257222b506844207e71b5d59567c41bbdcca2a72da119b9/sphinx_autoapi-3.6.0-py3-none-any.whl", hash = "sha256:f3b66714493cab140b0e896d33ce7137654a16ac1edb6563edcbd47bf975f711", size = 35281, upload-time = "2025-02-18T01:50:52.789Z" }, + { url = "https://files.pythonhosted.org/packages/ca/89/aea2f346fcdb44eb72464842e106b6291b2687feec2dd8b2de920ab89f28/sphinx_autoapi-3.6.1-py3-none-any.whl", hash = "sha256:6b7af0d5650f6eac1f4b85c1eb9f9a4911160ec7138bdc4451c77a5e94d5832c", size = 35334, upload-time = "2025-10-06T16:21:21.33Z" }, ] [[package]] @@ -1637,14 +1596,14 @@ wheels = [ [[package]] name = "sphinx-inline-tabs" -version = "2023.4.21" +version = "2025.12.21.14" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "sphinx" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/48/f5/f8a2be63ed7be9f91a4c2bea0e25bcb56aa4c5cc37ec4d8ead8065f926b1/sphinx_inline_tabs-2023.4.21.tar.gz", hash = "sha256:5df2f13f602c158f3f5f6c509e008aeada199a8c76d97ba3aa2822206683bebc", size = 42664, upload-time = "2023-04-21T20:25:30.578Z" } +sdist = { url = "https://files.pythonhosted.org/packages/76/6a/f39bde46a79b80a9983233d99b773bd24b468bdd9c1e87acb46ff69af441/sphinx_inline_tabs-2025.12.21.14.tar.gz", hash = "sha256:c71a75800326e613fb4e410eed92a0934214741326aca9897c18018b9f968cb6", size = 45572, upload-time = "2025-12-21T13:30:51.071Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/9d/60/1e4c9017d722b9c7731abc11f39ac8b083b479fbcefe12015b57e457a296/sphinx_inline_tabs-2023.4.21-py3-none-any.whl", hash = "sha256:06809ac613f7c48ddd6e2fa588413e3fe92cff2397b56e2ccf0b0218f9ef6a78", size = 6850, upload-time = "2023-04-21T20:25:28.778Z" }, + { url = "https://files.pythonhosted.org/packages/02/2b/e64e7de34663cff1df029ba4f05a86124315bd9eba3d3b78e64904bea7e0/sphinx_inline_tabs-2025.12.21.14-py3-none-any.whl", hash = "sha256:e685c782b58d4e01490bcc4e2367cf7135ec28e7283a05e89095394e4ca6e81a", size = 7082, upload-time = "2025-12-21T13:30:50.142Z" }, ] [[package]] @@ -1766,45 +1725,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/f1/7b/ce1eafaf1a76852e2ec9b22edecf1daa58175c090266e9f6c64afcd81d91/stack_data-0.6.3-py3-none-any.whl", hash = "sha256:d5558e0c25a4cb0853cddad3d77da9891a08cb85dd9f9f91b9f8cd66e511e695", size = 24521, upload-time = "2023-09-30T13:58:03.53Z" }, ] -[[package]] -name = "tomli" -version = "2.2.1" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/18/87/302344fed471e44a87289cf4967697d07e532f2421fdaf868a303cbae4ff/tomli-2.2.1.tar.gz", hash = "sha256:cd45e1dc79c835ce60f7404ec8119f2eb06d38b1deba146f07ced3bbc44505ff", size = 17175, upload-time = "2024-11-27T22:38:36.873Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/43/ca/75707e6efa2b37c77dadb324ae7d9571cb424e61ea73fad7c56c2d14527f/tomli-2.2.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:678e4fa69e4575eb77d103de3df8a895e1591b48e740211bd1067378c69e8249", size = 131077, upload-time = "2024-11-27T22:37:54.956Z" }, - { url = "https://files.pythonhosted.org/packages/c7/16/51ae563a8615d472fdbffc43a3f3d46588c264ac4f024f63f01283becfbb/tomli-2.2.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:023aa114dd824ade0100497eb2318602af309e5a55595f76b626d6d9f3b7b0a6", size = 123429, upload-time = "2024-11-27T22:37:56.698Z" }, - { url = "https://files.pythonhosted.org/packages/f1/dd/4f6cd1e7b160041db83c694abc78e100473c15d54620083dbd5aae7b990e/tomli-2.2.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ece47d672db52ac607a3d9599a9d48dcb2f2f735c6c2d1f34130085bb12b112a", size = 226067, upload-time = "2024-11-27T22:37:57.63Z" }, - { url = "https://files.pythonhosted.org/packages/a9/6b/c54ede5dc70d648cc6361eaf429304b02f2871a345bbdd51e993d6cdf550/tomli-2.2.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6972ca9c9cc9f0acaa56a8ca1ff51e7af152a9f87fb64623e31d5c83700080ee", size = 236030, upload-time = "2024-11-27T22:37:59.344Z" }, - { url = "https://files.pythonhosted.org/packages/1f/47/999514fa49cfaf7a92c805a86c3c43f4215621855d151b61c602abb38091/tomli-2.2.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c954d2250168d28797dd4e3ac5cf812a406cd5a92674ee4c8f123c889786aa8e", size = 240898, upload-time = "2024-11-27T22:38:00.429Z" }, - { url = "https://files.pythonhosted.org/packages/73/41/0a01279a7ae09ee1573b423318e7934674ce06eb33f50936655071d81a24/tomli-2.2.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:8dd28b3e155b80f4d54beb40a441d366adcfe740969820caf156c019fb5c7ec4", size = 229894, upload-time = "2024-11-27T22:38:02.094Z" }, - { url = "https://files.pythonhosted.org/packages/55/18/5d8bc5b0a0362311ce4d18830a5d28943667599a60d20118074ea1b01bb7/tomli-2.2.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:e59e304978767a54663af13c07b3d1af22ddee3bb2fb0618ca1593e4f593a106", size = 245319, upload-time = "2024-11-27T22:38:03.206Z" }, - { url = "https://files.pythonhosted.org/packages/92/a3/7ade0576d17f3cdf5ff44d61390d4b3febb8a9fc2b480c75c47ea048c646/tomli-2.2.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:33580bccab0338d00994d7f16f4c4ec25b776af3ffaac1ed74e0b3fc95e885a8", size = 238273, upload-time = "2024-11-27T22:38:04.217Z" }, - { url = "https://files.pythonhosted.org/packages/72/6f/fa64ef058ac1446a1e51110c375339b3ec6be245af9d14c87c4a6412dd32/tomli-2.2.1-cp311-cp311-win32.whl", hash = "sha256:465af0e0875402f1d226519c9904f37254b3045fc5084697cefb9bdde1ff99ff", size = 98310, upload-time = "2024-11-27T22:38:05.908Z" }, - { url = "https://files.pythonhosted.org/packages/6a/1c/4a2dcde4a51b81be3530565e92eda625d94dafb46dbeb15069df4caffc34/tomli-2.2.1-cp311-cp311-win_amd64.whl", hash = "sha256:2d0f2fdd22b02c6d81637a3c95f8cd77f995846af7414c5c4b8d0545afa1bc4b", size = 108309, upload-time = "2024-11-27T22:38:06.812Z" }, - { url = "https://files.pythonhosted.org/packages/52/e1/f8af4c2fcde17500422858155aeb0d7e93477a0d59a98e56cbfe75070fd0/tomli-2.2.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:4a8f6e44de52d5e6c657c9fe83b562f5f4256d8ebbfe4ff922c495620a7f6cea", size = 132762, upload-time = "2024-11-27T22:38:07.731Z" }, - { url = "https://files.pythonhosted.org/packages/03/b8/152c68bb84fc00396b83e7bbddd5ec0bd3dd409db4195e2a9b3e398ad2e3/tomli-2.2.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:8d57ca8095a641b8237d5b079147646153d22552f1c637fd3ba7f4b0b29167a8", size = 123453, upload-time = "2024-11-27T22:38:09.384Z" }, - { url = "https://files.pythonhosted.org/packages/c8/d6/fc9267af9166f79ac528ff7e8c55c8181ded34eb4b0e93daa767b8841573/tomli-2.2.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4e340144ad7ae1533cb897d406382b4b6fede8890a03738ff1683af800d54192", size = 233486, upload-time = "2024-11-27T22:38:10.329Z" }, - { url = "https://files.pythonhosted.org/packages/5c/51/51c3f2884d7bab89af25f678447ea7d297b53b5a3b5730a7cb2ef6069f07/tomli-2.2.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:db2b95f9de79181805df90bedc5a5ab4c165e6ec3fe99f970d0e302f384ad222", size = 242349, upload-time = "2024-11-27T22:38:11.443Z" }, - { url = "https://files.pythonhosted.org/packages/ab/df/bfa89627d13a5cc22402e441e8a931ef2108403db390ff3345c05253935e/tomli-2.2.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:40741994320b232529c802f8bc86da4e1aa9f413db394617b9a256ae0f9a7f77", size = 252159, upload-time = "2024-11-27T22:38:13.099Z" }, - { url = "https://files.pythonhosted.org/packages/9e/6e/fa2b916dced65763a5168c6ccb91066f7639bdc88b48adda990db10c8c0b/tomli-2.2.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:400e720fe168c0f8521520190686ef8ef033fb19fc493da09779e592861b78c6", size = 237243, upload-time = "2024-11-27T22:38:14.766Z" }, - { url = "https://files.pythonhosted.org/packages/b4/04/885d3b1f650e1153cbb93a6a9782c58a972b94ea4483ae4ac5cedd5e4a09/tomli-2.2.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:02abe224de6ae62c19f090f68da4e27b10af2b93213d36cf44e6e1c5abd19fdd", size = 259645, upload-time = "2024-11-27T22:38:15.843Z" }, - { url = "https://files.pythonhosted.org/packages/9c/de/6b432d66e986e501586da298e28ebeefd3edc2c780f3ad73d22566034239/tomli-2.2.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:b82ebccc8c8a36f2094e969560a1b836758481f3dc360ce9a3277c65f374285e", size = 244584, upload-time = "2024-11-27T22:38:17.645Z" }, - { url = "https://files.pythonhosted.org/packages/1c/9a/47c0449b98e6e7d1be6cbac02f93dd79003234ddc4aaab6ba07a9a7482e2/tomli-2.2.1-cp312-cp312-win32.whl", hash = "sha256:889f80ef92701b9dbb224e49ec87c645ce5df3fa2cc548664eb8a25e03127a98", size = 98875, upload-time = "2024-11-27T22:38:19.159Z" }, - { url = "https://files.pythonhosted.org/packages/ef/60/9b9638f081c6f1261e2688bd487625cd1e660d0a85bd469e91d8db969734/tomli-2.2.1-cp312-cp312-win_amd64.whl", hash = "sha256:7fc04e92e1d624a4a63c76474610238576942d6b8950a2d7f908a340494e67e4", size = 109418, upload-time = "2024-11-27T22:38:20.064Z" }, - { url = "https://files.pythonhosted.org/packages/04/90/2ee5f2e0362cb8a0b6499dc44f4d7d48f8fff06d28ba46e6f1eaa61a1388/tomli-2.2.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:f4039b9cbc3048b2416cc57ab3bda989a6fcf9b36cf8937f01a6e731b64f80d7", size = 132708, upload-time = "2024-11-27T22:38:21.659Z" }, - { url = "https://files.pythonhosted.org/packages/c0/ec/46b4108816de6b385141f082ba99e315501ccd0a2ea23db4a100dd3990ea/tomli-2.2.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:286f0ca2ffeeb5b9bd4fcc8d6c330534323ec51b2f52da063b11c502da16f30c", size = 123582, upload-time = "2024-11-27T22:38:22.693Z" }, - { url = "https://files.pythonhosted.org/packages/a0/bd/b470466d0137b37b68d24556c38a0cc819e8febe392d5b199dcd7f578365/tomli-2.2.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a92ef1a44547e894e2a17d24e7557a5e85a9e1d0048b0b5e7541f76c5032cb13", size = 232543, upload-time = "2024-11-27T22:38:24.367Z" }, - { url = "https://files.pythonhosted.org/packages/d9/e5/82e80ff3b751373f7cead2815bcbe2d51c895b3c990686741a8e56ec42ab/tomli-2.2.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9316dc65bed1684c9a98ee68759ceaed29d229e985297003e494aa825ebb0281", size = 241691, upload-time = "2024-11-27T22:38:26.081Z" }, - { url = "https://files.pythonhosted.org/packages/05/7e/2a110bc2713557d6a1bfb06af23dd01e7dde52b6ee7dadc589868f9abfac/tomli-2.2.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e85e99945e688e32d5a35c1ff38ed0b3f41f43fad8df0bdf79f72b2ba7bc5272", size = 251170, upload-time = "2024-11-27T22:38:27.921Z" }, - { url = "https://files.pythonhosted.org/packages/64/7b/22d713946efe00e0adbcdfd6d1aa119ae03fd0b60ebed51ebb3fa9f5a2e5/tomli-2.2.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:ac065718db92ca818f8d6141b5f66369833d4a80a9d74435a268c52bdfa73140", size = 236530, upload-time = "2024-11-27T22:38:29.591Z" }, - { url = "https://files.pythonhosted.org/packages/38/31/3a76f67da4b0cf37b742ca76beaf819dca0ebef26d78fc794a576e08accf/tomli-2.2.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:d920f33822747519673ee656a4b6ac33e382eca9d331c87770faa3eef562aeb2", size = 258666, upload-time = "2024-11-27T22:38:30.639Z" }, - { url = "https://files.pythonhosted.org/packages/07/10/5af1293da642aded87e8a988753945d0cf7e00a9452d3911dd3bb354c9e2/tomli-2.2.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:a198f10c4d1b1375d7687bc25294306e551bf1abfa4eace6650070a5c1ae2744", size = 243954, upload-time = "2024-11-27T22:38:31.702Z" }, - { url = "https://files.pythonhosted.org/packages/5b/b9/1ed31d167be802da0fc95020d04cd27b7d7065cc6fbefdd2f9186f60d7bd/tomli-2.2.1-cp313-cp313-win32.whl", hash = "sha256:d3f5614314d758649ab2ab3a62d4f2004c825922f9e370b29416484086b264ec", size = 98724, upload-time = "2024-11-27T22:38:32.837Z" }, - { url = "https://files.pythonhosted.org/packages/c7/32/b0963458706accd9afcfeb867c0f9175a741bf7b19cd424230714d722198/tomli-2.2.1-cp313-cp313-win_amd64.whl", hash = "sha256:a38aa0308e754b0e3c67e344754dff64999ff9b513e691d0e786265c93583c69", size = 109383, upload-time = "2024-11-27T22:38:34.455Z" }, - { url = "https://files.pythonhosted.org/packages/6e/c2/61d3e0f47e2b74ef40a68b9e6ad5984f6241a942f7cd3bbfbdbd03861ea9/tomli-2.2.1-py3-none-any.whl", hash = "sha256:cb55c73c5f4408779d0cf3eef9f762b9c9f147a77de7b258bef0a5628adc85cc", size = 14257, upload-time = "2024-11-27T22:38:35.385Z" }, -] - [[package]] name = "traitlets" version = "5.14.3" @@ -1825,27 +1745,36 @@ wheels = [ [[package]] name = "tzdata" -version = "2025.2" +version = "2025.3" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/95/32/1a225d6164441be760d75c2c42e2780dc0873fe382da3e98a2e1e48361e5/tzdata-2025.2.tar.gz", hash = "sha256:b60a638fcc0daffadf82fe0f57e53d06bdec2f36c4df66280ae79bce6bd6f2b9", size = 196380, upload-time = "2025-03-23T13:54:43.652Z" } +sdist = { url = "https://files.pythonhosted.org/packages/5e/a7/c202b344c5ca7daf398f3b8a477eeb205cf3b6f32e7ec3a6bac0629ca975/tzdata-2025.3.tar.gz", hash = "sha256:de39c2ca5dc7b0344f2eba86f49d614019d29f060fc4ebc8a417896a620b56a7", size = 196772, upload-time = "2025-12-13T17:45:35.667Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/5c/23/c7abc0ca0a1526a0774eca151daeb8de62ec457e77262b66b359c3c7679e/tzdata-2025.2-py2.py3-none-any.whl", hash = "sha256:1a403fada01ff9221ca8044d701868fa132215d84beb92242d9acd2147f667a8", size = 347839, upload-time = "2025-03-23T13:54:41.845Z" }, + { url = "https://files.pythonhosted.org/packages/c7/b0/003792df09decd6849a5e39c28b513c06e84436a54440380862b5aeff25d/tzdata-2025.3-py2.py3-none-any.whl", hash = "sha256:06a47e5700f3081aab02b2e513160914ff0694bce9947d6b76ebd6bf57cfc5d1", size = 348521, upload-time = "2025-12-13T17:45:33.889Z" }, ] [[package]] name = "urllib3" -version = "2.5.0" +version = "2.6.3" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/15/22/9ee70a2574a4f4599c47dd506532914ce044817c7752a79b6a51286319bc/urllib3-2.5.0.tar.gz", hash = "sha256:3fc47733c7e419d4bc3f6b3dc2b4f890bb743906a30d56ba4a5bfa4bbff92760", size = 393185, upload-time = "2025-06-18T14:07:41.644Z" } +sdist = { url = "https://files.pythonhosted.org/packages/c7/24/5f1b3bdffd70275f6661c76461e25f024d5a38a46f04aaca912426a2b1d3/urllib3-2.6.3.tar.gz", hash = "sha256:1b62b6884944a57dbe321509ab94fd4d3b307075e0c2eae991ac71ee15ad38ed", size = 435556, upload-time = "2026-01-07T16:24:43.925Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/a7/c2/fe1e52489ae3122415c51f387e221dd0773709bad6c6cdaa599e8a2c5185/urllib3-2.5.0-py3-none-any.whl", hash = "sha256:e6b01673c0fa6a13e374b50871808eb3bf7046c4b125b216f6bf1cc604cff0dc", size = 129795, upload-time = "2025-06-18T14:07:40.39Z" }, + { url = "https://files.pythonhosted.org/packages/39/08/aaaad47bc4e9dc8c725e68f9d04865dbcb2052843ff09c97b08904852d84/urllib3-2.6.3-py3-none-any.whl", hash = "sha256:bf272323e553dfb2e87d9bfd225ca7b0f467b919d7bbd355436d3fd37cb0acd4", size = 131584, upload-time = "2026-01-07T16:24:42.685Z" }, ] [[package]] name = "wcwidth" -version = "0.2.13" +version = "0.2.14" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/24/30/6b0809f4510673dc723187aeaf24c7f5459922d01e2f794277a3dfb90345/wcwidth-0.2.14.tar.gz", hash = "sha256:4d478375d31bc5395a3c55c40ccdf3354688364cd61c4f6adacaa9215d0b3605", size = 102293, upload-time = "2025-09-22T16:29:53.023Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/af/b5/123f13c975e9f27ab9c0770f514345bd406d0e8d3b7a0723af9d43f710af/wcwidth-0.2.14-py2.py3-none-any.whl", hash = "sha256:a7bb560c8aee30f9957e5f9895805edd20602f2d7f720186dfd906e82b4982e1", size = 37286, upload-time = "2025-09-22T16:29:51.641Z" }, +] + +[[package]] +name = "xyzservices" +version = "2025.11.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/6c/63/53559446a878410fc5a5974feb13d31d78d752eb18aeba59c7fef1af7598/wcwidth-0.2.13.tar.gz", hash = "sha256:72ea0c06399eb286d978fdedb6923a9eb47e1c486ce63e9b4e64fc18303972b5", size = 101301, upload-time = "2024-01-06T02:10:57.829Z" } +sdist = { url = "https://files.pythonhosted.org/packages/ee/0f/022795fc1201e7c29e742a509913badb53ce0b38f64b6db859e2f6339da9/xyzservices-2025.11.0.tar.gz", hash = "sha256:2fc72b49502b25023fd71e8f532fb4beddbbf0aa124d90ea25dba44f545e17ce", size = 1135703, upload-time = "2025-11-22T11:31:51.82Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/fd/84/fd2ba7aafacbad3c4201d395674fc6348826569da3c0937e75505ead3528/wcwidth-0.2.13-py2.py3-none-any.whl", hash = "sha256:3da69048e4540d84af32131829ff948f1e022c1c6bdb8d6102117aac784f6859", size = 34166, upload-time = "2024-01-06T02:10:55.763Z" }, + { url = "https://files.pythonhosted.org/packages/ef/5c/2c189d18d495dd0fa3f27ccc60762bbc787eed95b9b0147266e72bb76585/xyzservices-2025.11.0-py3-none-any.whl", hash = "sha256:de66a7599a8d6dad63980b77defd1d8f5a5a9cb5fc8774ea1c6e89ca7c2a3d2f", size = 93916, upload-time = "2025-11-22T11:31:50.525Z" }, ] diff --git a/zizmor.yml b/zizmor.yml index f11a5b3c..7454d28e 100644 --- a/zizmor.yml +++ b/zizmor.yml @@ -8,5 +8,6 @@ rules: astral-sh/*: ref-pin cache-poisoning: ignore: - # ignore ci.yml as there is no release in this workflow + # ignore ci.yml and pre-commit.yml as there is no release in these workflows - ci.yml + - pre-commit.yml