From 41cfcb72734428fd86ad84410dff1bba97044815 Mon Sep 17 00:00:00 2001 From: bitranox Date: Sun, 26 Apr 2026 10:38:48 +0200 Subject: [PATCH 1/8] Switch packaging from poetry to uv; enable Python 3.14 via build123d dev branch Replace poetry/pipx setup with PEP 621 metadata + hatchling backend. Add SPDX license expression, dependency-groups for tests, and project scripts. Update README with uv install (Linux/Windows), uv tool install, uvx usage, and dev workflow. For Python 3.14, depend on build123d's upstream dev branch via a marker-conditional [tool.uv.sources] entry; 3.10-3.13 keep the PyPI release. Drop poetry.lock and ignore uv.lock. Co-Authored-By: Claude Opus 4.7 (1M context) --- .gitignore | 157 +++++++ README.md | 67 ++- poetry.lock | 1206 ------------------------------------------------ pyproject.toml | 46 +- 4 files changed, 246 insertions(+), 1230 deletions(-) delete mode 100644 poetry.lock diff --git a/.gitignore b/.gitignore index 52ddfd8..34ab516 100644 --- a/.gitignore +++ b/.gitignore @@ -3,3 +3,160 @@ __pycache__ .venv dist +uv.lock + +# ==================================== +# IDEs & Editors +# ==================================== +# IntelliJ, PyCharm, etc. +.idea/ +# VS Code workspace settings +.vscode/ +*.code-workspace + +# ==================================== +# Python bytecode & caches +# ==================================== +# __pycache__: compiled .pyc files at any depth +# *.py[cod]: catches .pyc, .pyo, .pyd +__pycache__/ +*.py[cod] +*$py.class # other compiled artifacts + +# pytest, coverage, MyPy, Hypothesis +.pytest_cache/ +.mypy_cache/ +.pyright/ +.coverage* +htmlcov/ +nosetests.xml +coverage.xml +*.cover +.hypothesis/ +.tox/ +.nox/ + +# general cache directories (any project-level caching) +.cache/ +.run/ +.import_linter_cache/ + +# ==================================== +# Build & distribution artifacts +# ==================================== +# source/package builds +build/ +dist/ +*.egg-info/ # metadata for pip installs +*.egg +*.whl +pip-wheel-metadata/ +*.manifest # PyInstaller metadata +*.spec # PyInstaller spec files + +# Eggs, parts, wheels, sdist, etc. +develop-eggs/ +.eggs/ +parts/ +sdist/ +wheels/ +downloads/ +var/ + +# pip logs & installer leftovers +pip-log.txt +pip-delete-this-directory.txt +.installed.cfg + +# ==================================== +# Virtual environments & secrets +# ==================================== +# common venv folder names +env/ +venv/ +ENV/ +.venv/ +# backups, alternate names +env.bak/ +venv.bak/ +# dotenv files with credentials +.env + +# ==================================== +# Project-specific & framework files +# ==================================== +# Django logs & local overrides +*.log +local_settings.py + +# Flask instance folder +instance/ +.webassets-cache + +# Scrapy cache +.scrapy + +# Sphinx docs +docs/_build/ + +# PyBuilder output +target/ + +# Jupyter notebooks checkpoints +.ipynb_checkpoints + +# pyenv Python version file +.python-version + +# Celery beat schedule +celerybeat-schedule + +# SageMath parsed files +*.sage.py + +# Spyder IDE +.spyderproject +.spyproject + +# Rope IDE +.ropeproject + +# MkDocs static site folder +/site + +# ==================================== +# OS-specific files +# ==================================== +# macOS +.DS_Store +# Windows +Thumbs.db +ehthumbs.db + +# Archives +*.zip + +# Thunderbird build artifact (created temporarily by pack script) +sources/manifest.json + +# ==================================== +# Tool-specific extras +# ==================================== +# Codecov uploader script (downloaded during local uploads) +codecov.sh +codecov.xml + +# Nix build result symlink +result + +# Optional lockfiles (for alternative managers) +poetry.lock +pdm.lock +uv.lock + +# div +# .devcontainer/ # needed for github codespaces +.claude/ +CLAUDE.md +old_code/ +prompts.md diff --git a/README.md b/README.md index bb43378..59f8661 100644 --- a/README.md +++ b/README.md @@ -10,20 +10,67 @@ Gridfinity is an open source storage system best introduced Look on [thangs](thangs.com) and [printables](printables.com) for more compatible parts. -Setup, You can install with pipx. +Install uv +---------- + +Linux / macOS: + + curl -LsSf https://astral.sh/uv/install.sh | sh + +Windows (PowerShell): + + powershell -ExecutionPolicy ByPass -c "irm https://astral.sh/uv/install.ps1 | iex" + +See [the uv install docs](https://docs.astral.sh/uv/getting-started/installation/) +for package-manager alternatives (Homebrew, winget, scoop, pipx, etc.). + +Install gfthings as a CLI tool +------------------------------ + +Install gfthings into an isolated, uv-managed environment and put its +commands (`gfbin`, `gfbase`, `gfedge`, `gfpin`) on your `PATH`: + + uv tool install gfthings + +Upgrade or remove later with: + + uv tool upgrade gfthings + uv tool uninstall gfthings + +Run without installing (uvx) +---------------------------- + +`uvx` runs a tool in a one-shot, ephemeral environment — handy for trying +things out or for CI: + + uvx --from gfthings gfbin -h + uvx --from gfthings gfbin -x 2 -y 3 -o bin.step + uvx --from gfthings gfbase -x 4 -y 3 -o base.step + +The `--from gfthings` is required because the command names (`gfbin`, +etc.) don't match the package name. + +Develop gfthings +---------------- + +Clone the repo and let uv manage the environment: - sudo apt install pipx - pipx install gfthings + uv sync # creates .venv and installs deps + project + uv add ocp-vscode # optional: add a dependency + uv run gfbin -h # run a script from the project -If you want to modify gfthings then build it with poetry. +`uv sync` also picks up the `test` dependency group; run the suite with: - sudo apt install pipx - pipx install poetry - poetry add ocp-vscode - poetry install + uv run --group test pytest -If you choose this option then you must prefix your commands with -`poetry run` +Python 3.14 note: the released `build123d` on PyPI caps at `python<3.14`. +On 3.14+, this project resolves `build123d` from its upstream `dev` branch +via a marker-conditional `[tool.uv.sources]` entry, so `uv sync` / +`uv tool install` from a checkout work; on 3.10–3.13 the regular PyPI +release is used. The `[tool.uv.sources]` block is uv-specific metadata +and is not baked into a built wheel, so the project remains publishable +to PyPI — but plain `pip install gfthings` on 3.14 will fail to resolve +`build123d` until upstream ships a 3.14-compatible release. Copyright (C) Paul Bone Distributed under: CC BY-NC-SA 4.0 diff --git a/poetry.lock b/poetry.lock deleted file mode 100644 index b9ea7b1..0000000 --- a/poetry.lock +++ /dev/null @@ -1,1206 +0,0 @@ -# This file is automatically @generated by Poetry 1.8.5 and should not be changed by hand. - -[[package]] -name = "anytree" -version = "2.13.0" -description = "Powerful and Lightweight Python Tree Data Structure with various plugins" -optional = false -python-versions = "<4.0,>=3.9.2" -files = [ - {file = "anytree-2.13.0-py3-none-any.whl", hash = "sha256:4cbcf10df36b1f1cba131b7e487ff3edafc9d6e932a3c70071b5b768bab901ff"}, - {file = "anytree-2.13.0.tar.gz", hash = "sha256:c9d3aa6825fdd06af7ebb05b4ef291d2db63e62bb1f9b7d9b71354be9d362714"}, -] - -[[package]] -name = "asttokens" -version = "3.0.0" -description = "Annotate AST trees with source code positions" -optional = false -python-versions = ">=3.8" -files = [ - {file = "asttokens-3.0.0-py3-none-any.whl", hash = "sha256:e3078351a059199dd5138cb1c706e6430c05eff2ff136af5eb4790f9d28932e2"}, - {file = "asttokens-3.0.0.tar.gz", hash = "sha256:0dcd8baa8d62b0c1d118b399b2ddba3c4aff271d0d7a9e0d4c1681c79035bbc7"}, -] - -[package.extras] -astroid = ["astroid (>=2,<4)"] -test = ["astroid (>=2,<4)", "pytest", "pytest-cov", "pytest-xdist"] - -[[package]] -name = "build123d" -version = "0.9.1" -description = "A python CAD programming library" -optional = false -python-versions = "<3.14,>=3.10" -files = [ - {file = "build123d-0.9.1-py3-none-any.whl", hash = "sha256:0e2a3c171d7db55329201438a95ab888df6c1b0fd13067a3780efcc8fbe1cc78"}, - {file = "build123d-0.9.1.tar.gz", hash = "sha256:8bc179cb65c7e7393191ad7113f13781fabf75892be07060f2bebf95369c093b"}, -] - -[package.dependencies] -anytree = ">=2.8.0,<3" -cadquery-ocp = ">=7.8,<7.9" -ezdxf = ">=1.1.0,<2" -ipython = ">=8.0.0,<9" -numpy = ">=2,<3" -ocpsvg = ">=0.4" -py-lib3mf = ">=2.3.1" -svgpathtools = ">=1.5.1,<2" -trianglesolver = "*" -typing_extensions = ">=4.6.0,<5" - -[package.extras] -all = ["build123d[benchmark]", "build123d[development]", "build123d[docs]", "build123d[ocp-vscode]"] -benchmark = ["pytest-benchmark"] -development = ["black", "mypy", "pylint", "pytest", "pytest-cov", "wheel"] -docs = ["sphinx (==8.1.3)", "sphinx-copybutton", "sphinx-design", "sphinx-hoverxref", "sphinx-rtd-theme", "sphinx_autodoc_typehints"] -ocp-vscode = ["ocp_vscode"] -stubs = ["cadquery-ocp-stubs (>=7.8,<7.9)"] - -[[package]] -name = "cadquery-ocp" -version = "7.8.1.1.post1" -description = "Python wrapper for Open CASCADE Technology 3D geometry library based on the official CadQuery/OCP sources" -optional = false -python-versions = "<3.14,>=3.10" -files = [ - {file = "cadquery_ocp-7.8.1.1.post1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:4413961e98a90686a56c2ac58b126773c7da4eb82b967ddcc1f394fe6a7b71ad"}, - {file = "cadquery_ocp-7.8.1.1.post1-cp310-cp310-macosx_11_0_x86_64.whl", hash = "sha256:687c8a22d6248b28e44f136cecf93d274a897efbd0d8b36e38d4e207fecf1d84"}, - {file = "cadquery_ocp-7.8.1.1.post1-cp310-cp310-manylinux_2_31_x86_64.whl", hash = "sha256:b843adfff9014011c32ec68028055e558023a1d567a3b27bcd19d2e97f35ac73"}, - {file = "cadquery_ocp-7.8.1.1.post1-cp310-cp310-win_amd64.whl", hash = "sha256:d1c3d5b228ca2c2b61a27fee8a279e3c889400a6f56abd7d36034cb9754cfff4"}, - {file = "cadquery_ocp-7.8.1.1.post1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:b80b28a2b24bfe52ddcc7962429455a0f8457e33747a0e4e3d184134e286ea7b"}, - {file = "cadquery_ocp-7.8.1.1.post1-cp311-cp311-macosx_11_0_x86_64.whl", hash = "sha256:313b12f268ef46087bf5d178aed2f97b1cbaccfd9667ecdb779331a6baa8c188"}, - {file = "cadquery_ocp-7.8.1.1.post1-cp311-cp311-manylinux_2_31_x86_64.whl", hash = "sha256:0ff754db099da9a4285268cecf7740fef782567621480b007697c00e47f8fbde"}, - {file = "cadquery_ocp-7.8.1.1.post1-cp311-cp311-win_amd64.whl", hash = "sha256:bfb110012766fa23e72c23eace00a791d9e7f86fc630694ef72d5e6b333df3aa"}, - {file = "cadquery_ocp-7.8.1.1.post1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:0022e854a3840efd5c7fc14fe933772613794777d5eb056a4754d44a86baf02a"}, - {file = "cadquery_ocp-7.8.1.1.post1-cp312-cp312-macosx_11_0_x86_64.whl", hash = "sha256:53dc24aed402b2ae52634a29b3b17e9c01e857b8ac34bb101d4e8fa76d3cd7f7"}, - {file = "cadquery_ocp-7.8.1.1.post1-cp312-cp312-manylinux_2_31_x86_64.whl", hash = "sha256:4882074e86722208153579baaee246be4fb10bda22dc20d101c4151f364207b9"}, - {file = "cadquery_ocp-7.8.1.1.post1-cp312-cp312-win_amd64.whl", hash = "sha256:06982855db94fa0056b922276f0ca94154e5d1eb16f6cba854d704885844924a"}, - {file = "cadquery_ocp-7.8.1.1.post1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:08fdc32b79e6f974cf692584be865985161e4fd8cbf854ed64c8c1530458fce3"}, - {file = "cadquery_ocp-7.8.1.1.post1-cp313-cp313-macosx_11_0_x86_64.whl", hash = "sha256:fd5ffec5e27846fe4796db9cdc0748324e4d7c59da7c6c7d86a6eb38e823b3f5"}, - {file = "cadquery_ocp-7.8.1.1.post1-cp313-cp313-manylinux_2_31_x86_64.whl", hash = "sha256:081017e5387debe4bf31a9dc222c2513e26d1860ca990119bfe90a6970a77104"}, - {file = "cadquery_ocp-7.8.1.1.post1-cp313-cp313-win_amd64.whl", hash = "sha256:22877143d06cb52bd7d48a591510f8e72c2fc5768bafebb99e5cf077798ee939"}, -] - -[package.dependencies] -vtk = "9.3.1" - -[[package]] -name = "colorama" -version = "0.4.6" -description = "Cross-platform colored terminal text." -optional = false -python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*,>=2.7" -files = [ - {file = "colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6"}, - {file = "colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44"}, -] - -[[package]] -name = "contourpy" -version = "1.3.2" -description = "Python library for calculating contours of 2D quadrilateral grids" -optional = false -python-versions = ">=3.10" -files = [ - {file = "contourpy-1.3.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:ba38e3f9f330af820c4b27ceb4b9c7feee5fe0493ea53a8720f4792667465934"}, - {file = "contourpy-1.3.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:dc41ba0714aa2968d1f8674ec97504a8f7e334f48eeacebcaa6256213acb0989"}, - {file = "contourpy-1.3.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9be002b31c558d1ddf1b9b415b162c603405414bacd6932d031c5b5a8b757f0d"}, - {file = "contourpy-1.3.2-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8d2e74acbcba3bfdb6d9d8384cdc4f9260cae86ed9beee8bd5f54fee49a430b9"}, - {file = "contourpy-1.3.2-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e259bced5549ac64410162adc973c5e2fb77f04df4a439d00b478e57a0e65512"}, - {file = "contourpy-1.3.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ad687a04bc802cbe8b9c399c07162a3c35e227e2daccf1668eb1f278cb698631"}, - {file = "contourpy-1.3.2-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:cdd22595308f53ef2f891040ab2b93d79192513ffccbd7fe19be7aa773a5e09f"}, - {file = "contourpy-1.3.2-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:b4f54d6a2defe9f257327b0f243612dd051cc43825587520b1bf74a31e2f6ef2"}, - {file = "contourpy-1.3.2-cp310-cp310-win32.whl", hash = "sha256:f939a054192ddc596e031e50bb13b657ce318cf13d264f095ce9db7dc6ae81c0"}, - {file = "contourpy-1.3.2-cp310-cp310-win_amd64.whl", hash = "sha256:c440093bbc8fc21c637c03bafcbef95ccd963bc6e0514ad887932c18ca2a759a"}, - {file = "contourpy-1.3.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:6a37a2fb93d4df3fc4c0e363ea4d16f83195fc09c891bc8ce072b9d084853445"}, - {file = "contourpy-1.3.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:b7cd50c38f500bbcc9b6a46643a40e0913673f869315d8e70de0438817cb7773"}, - {file = "contourpy-1.3.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d6658ccc7251a4433eebd89ed2672c2ed96fba367fd25ca9512aa92a4b46c4f1"}, - {file = "contourpy-1.3.2-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:70771a461aaeb335df14deb6c97439973d253ae70660ca085eec25241137ef43"}, - {file = "contourpy-1.3.2-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:65a887a6e8c4cd0897507d814b14c54a8c2e2aa4ac9f7686292f9769fcf9a6ab"}, - {file = "contourpy-1.3.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3859783aefa2b8355697f16642695a5b9792e7a46ab86da1118a4a23a51a33d7"}, - {file = "contourpy-1.3.2-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:eab0f6db315fa4d70f1d8ab514e527f0366ec021ff853d7ed6a2d33605cf4b83"}, - {file = "contourpy-1.3.2-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:d91a3ccc7fea94ca0acab82ceb77f396d50a1f67412efe4c526f5d20264e6ecd"}, - {file = "contourpy-1.3.2-cp311-cp311-win32.whl", hash = "sha256:1c48188778d4d2f3d48e4643fb15d8608b1d01e4b4d6b0548d9b336c28fc9b6f"}, - {file = "contourpy-1.3.2-cp311-cp311-win_amd64.whl", hash = "sha256:5ebac872ba09cb8f2131c46b8739a7ff71de28a24c869bcad554477eb089a878"}, - {file = "contourpy-1.3.2-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:4caf2bcd2969402bf77edc4cb6034c7dd7c0803213b3523f111eb7460a51b8d2"}, - {file = "contourpy-1.3.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:82199cb78276249796419fe36b7386bd8d2cc3f28b3bc19fe2454fe2e26c4c15"}, - {file = "contourpy-1.3.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:106fab697af11456fcba3e352ad50effe493a90f893fca6c2ca5c033820cea92"}, - {file = "contourpy-1.3.2-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d14f12932a8d620e307f715857107b1d1845cc44fdb5da2bc8e850f5ceba9f87"}, - {file = "contourpy-1.3.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:532fd26e715560721bb0d5fc7610fce279b3699b018600ab999d1be895b09415"}, - {file = "contourpy-1.3.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f26b383144cf2d2c29f01a1e8170f50dacf0eac02d64139dcd709a8ac4eb3cfe"}, - {file = "contourpy-1.3.2-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:c49f73e61f1f774650a55d221803b101d966ca0c5a2d6d5e4320ec3997489441"}, - {file = "contourpy-1.3.2-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:3d80b2c0300583228ac98d0a927a1ba6a2ba6b8a742463c564f1d419ee5b211e"}, - {file = "contourpy-1.3.2-cp312-cp312-win32.whl", hash = "sha256:90df94c89a91b7362e1142cbee7568f86514412ab8a2c0d0fca72d7e91b62912"}, - {file = "contourpy-1.3.2-cp312-cp312-win_amd64.whl", hash = "sha256:8c942a01d9163e2e5cfb05cb66110121b8d07ad438a17f9e766317bcb62abf73"}, - {file = "contourpy-1.3.2-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:de39db2604ae755316cb5967728f4bea92685884b1e767b7c24e983ef5f771cb"}, - {file = "contourpy-1.3.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:3f9e896f447c5c8618f1edb2bafa9a4030f22a575ec418ad70611450720b5b08"}, - {file = "contourpy-1.3.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:71e2bd4a1c4188f5c2b8d274da78faab884b59df20df63c34f74aa1813c4427c"}, - {file = "contourpy-1.3.2-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:de425af81b6cea33101ae95ece1f696af39446db9682a0b56daaa48cfc29f38f"}, - {file = "contourpy-1.3.2-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:977e98a0e0480d3fe292246417239d2d45435904afd6d7332d8455981c408b85"}, - {file = "contourpy-1.3.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:434f0adf84911c924519d2b08fc10491dd282b20bdd3fa8f60fd816ea0b48841"}, - {file = "contourpy-1.3.2-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:c66c4906cdbc50e9cba65978823e6e00b45682eb09adbb78c9775b74eb222422"}, - {file = "contourpy-1.3.2-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:8b7fc0cd78ba2f4695fd0a6ad81a19e7e3ab825c31b577f384aa9d7817dc3bef"}, - {file = "contourpy-1.3.2-cp313-cp313-win32.whl", hash = "sha256:15ce6ab60957ca74cff444fe66d9045c1fd3e92c8936894ebd1f3eef2fff075f"}, - {file = "contourpy-1.3.2-cp313-cp313-win_amd64.whl", hash = "sha256:e1578f7eafce927b168752ed7e22646dad6cd9bca673c60bff55889fa236ebf9"}, - {file = "contourpy-1.3.2-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:0475b1f6604896bc7c53bb070e355e9321e1bc0d381735421a2d2068ec56531f"}, - {file = "contourpy-1.3.2-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:c85bb486e9be652314bb5b9e2e3b0d1b2e643d5eec4992c0fbe8ac71775da739"}, - {file = "contourpy-1.3.2-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:745b57db7758f3ffc05a10254edd3182a2a83402a89c00957a8e8a22f5582823"}, - {file = "contourpy-1.3.2-cp313-cp313t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:970e9173dbd7eba9b4e01aab19215a48ee5dd3f43cef736eebde064a171f89a5"}, - {file = "contourpy-1.3.2-cp313-cp313t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c6c4639a9c22230276b7bffb6a850dfc8258a2521305e1faefe804d006b2e532"}, - {file = "contourpy-1.3.2-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cc829960f34ba36aad4302e78eabf3ef16a3a100863f0d4eeddf30e8a485a03b"}, - {file = "contourpy-1.3.2-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:d32530b534e986374fc19eaa77fcb87e8a99e5431499949b828312bdcd20ac52"}, - {file = "contourpy-1.3.2-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:e298e7e70cf4eb179cc1077be1c725b5fd131ebc81181bf0c03525c8abc297fd"}, - {file = "contourpy-1.3.2-cp313-cp313t-win32.whl", hash = "sha256:d0e589ae0d55204991450bb5c23f571c64fe43adaa53f93fc902a84c96f52fe1"}, - {file = "contourpy-1.3.2-cp313-cp313t-win_amd64.whl", hash = "sha256:78e9253c3de756b3f6a5174d024c4835acd59eb3f8e2ca13e775dbffe1558f69"}, - {file = "contourpy-1.3.2-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:fd93cc7f3139b6dd7aab2f26a90dde0aa9fc264dbf70f6740d498a70b860b82c"}, - {file = "contourpy-1.3.2-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:107ba8a6a7eec58bb475329e6d3b95deba9440667c4d62b9b6063942b61d7f16"}, - {file = "contourpy-1.3.2-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:ded1706ed0c1049224531b81128efbd5084598f18d8a2d9efae833edbd2b40ad"}, - {file = "contourpy-1.3.2-pp311-pypy311_pp73-macosx_10_15_x86_64.whl", hash = "sha256:5f5964cdad279256c084b69c3f412b7801e15356b16efa9d78aa974041903da0"}, - {file = "contourpy-1.3.2-pp311-pypy311_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:49b65a95d642d4efa8f64ba12558fcb83407e58a2dfba9d796d77b63ccfcaff5"}, - {file = "contourpy-1.3.2-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:8c5acb8dddb0752bf252e01a3035b21443158910ac16a3b0d20e7fed7d534ce5"}, - {file = "contourpy-1.3.2.tar.gz", hash = "sha256:b6945942715a034c671b7fc54f9588126b0b8bf23db2696e3ca8328f3ff0ab54"}, -] - -[package.dependencies] -numpy = ">=1.23" - -[package.extras] -bokeh = ["bokeh", "selenium"] -docs = ["furo", "sphinx (>=7.2)", "sphinx-copybutton"] -mypy = ["bokeh", "contourpy[bokeh,docs]", "docutils-stubs", "mypy (==1.15.0)", "types-Pillow"] -test = ["Pillow", "contourpy[test-no-images]", "matplotlib"] -test-no-images = ["pytest", "pytest-cov", "pytest-rerunfailures", "pytest-xdist", "wurlitzer"] - -[[package]] -name = "cycler" -version = "0.12.1" -description = "Composable style cycles" -optional = false -python-versions = ">=3.8" -files = [ - {file = "cycler-0.12.1-py3-none-any.whl", hash = "sha256:85cef7cff222d8644161529808465972e51340599459b8ac3ccbac5a854e0d30"}, - {file = "cycler-0.12.1.tar.gz", hash = "sha256:88bb128f02ba341da8ef447245a9e138fae777f6a23943da4540077d3601eb1c"}, -] - -[package.extras] -docs = ["ipython", "matplotlib", "numpydoc", "sphinx"] -tests = ["pytest", "pytest-cov", "pytest-xdist"] - -[[package]] -name = "decorator" -version = "5.2.1" -description = "Decorators for Humans" -optional = false -python-versions = ">=3.8" -files = [ - {file = "decorator-5.2.1-py3-none-any.whl", hash = "sha256:d316bb415a2d9e2d2b3abcc4084c6502fc09240e292cd76a76afc106a1c8e04a"}, - {file = "decorator-5.2.1.tar.gz", hash = "sha256:65f266143752f734b0a7cc83c46f4618af75b8c5911b00ccb61d0ac9b6da0360"}, -] - -[[package]] -name = "exceptiongroup" -version = "1.2.2" -description = "Backport of PEP 654 (exception groups)" -optional = false -python-versions = ">=3.7" -files = [ - {file = "exceptiongroup-1.2.2-py3-none-any.whl", hash = "sha256:3111b9d131c238bec2f8f516e123e14ba243563fb135d3fe885990585aa7795b"}, - {file = "exceptiongroup-1.2.2.tar.gz", hash = "sha256:47c2edf7c6738fafb49fd34290706d1a1a2f4d1c6df275526b62cbb4aa5393cc"}, -] - -[package.extras] -test = ["pytest (>=6)"] - -[[package]] -name = "executing" -version = "2.2.0" -description = "Get the currently executing AST node of a frame, and other information" -optional = false -python-versions = ">=3.8" -files = [ - {file = "executing-2.2.0-py2.py3-none-any.whl", hash = "sha256:11387150cad388d62750327a53d3339fad4888b39a6fe233c3afbb54ecffd3aa"}, - {file = "executing-2.2.0.tar.gz", hash = "sha256:5d108c028108fe2551d1a7b2e8b713341e2cb4fc0aa7dcf966fa4327a5226755"}, -] - -[package.extras] -tests = ["asttokens (>=2.1.0)", "coverage", "coverage-enable-subprocess", "ipython", "littleutils", "pytest", "rich"] - -[[package]] -name = "ezdxf" -version = "1.4.1" -description = "A Python package to create/manipulate DXF drawings." -optional = false -python-versions = ">=3.9" -files = [ - {file = "ezdxf-1.4.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:5167f620ec6f261f0216c11cbab4625ef0bf46167d6e1fdce5799dc7ea06c5dc"}, - {file = "ezdxf-1.4.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:fbcce92871ecc50eda683fc4845af4c8b98f0c69842b816c0477d2cc08a8f396"}, - {file = "ezdxf-1.4.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:20cc506f7adff134aeb063aa8f2a37c7e8041f216baaab191af03212ba2ffd29"}, - {file = "ezdxf-1.4.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6d5b3219d7e5f6d921080f4abf5abc99798a2ff4ff84e1a944009de744c373ad"}, - {file = "ezdxf-1.4.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ed9f7398c9253edf60599f815ab711b302cb747937e0713265d5bd41389f58b9"}, - {file = "ezdxf-1.4.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:04f3ba53d756d9b6d551a11fb118c6183c060dd186bdf1e1045b0916a8283010"}, - {file = "ezdxf-1.4.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:60b909553f241226480e1909280af8c29342ff8d6384bfff0cc48919712d7019"}, - {file = "ezdxf-1.4.1-cp310-cp310-win_amd64.whl", hash = "sha256:660fe5bb6ef0f0d2927029620e29eae1ec47cb843d73a2291817dae7716d6009"}, - {file = "ezdxf-1.4.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:62485e3488b9093e70a373f981184c4024975b87546c2567d6b0035c4f4df0e3"}, - {file = "ezdxf-1.4.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:e59c556c480ba2c9886f95ec3eac2006dc905b42871b402773f7220636936079"}, - {file = "ezdxf-1.4.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:7d36dd147c765937d0ab0fffdf6e1ef8008c2e9667bc92d08f938f0945176b5e"}, - {file = "ezdxf-1.4.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7b63357ad8b65574938d10ce571c1373cc6c8771c6aad40155f0c55607102237"}, - {file = "ezdxf-1.4.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d2abaecb2228b5b1a798149bcaefa45a5911ece631aa2717ff6dea1ab5713a6a"}, - {file = "ezdxf-1.4.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:6dd079a89299bd6be8ee63561121d3b02b7bad2b7f591469497455b3fddfd321"}, - {file = "ezdxf-1.4.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:5ed11a1b1f2c953dcfc500b4fee6570f3fcdb8fed1589bce5fcb81d58e1f32b0"}, - {file = "ezdxf-1.4.1-cp311-cp311-win_amd64.whl", hash = "sha256:2d0a8aba1eb1d2f81158e744c492cf2338fba6491cb6a7b409b232b6456e7919"}, - {file = "ezdxf-1.4.1-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:c592ee1970d11ebef66c800860f6a0f8fd560a0fde5c3c51556d06c8d422cc71"}, - {file = "ezdxf-1.4.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:dae904a0238e3ea74ae53c7036b6bebaf36c82b143a0e4e23c743ecf5a33d9fd"}, - {file = "ezdxf-1.4.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:44c695a6bf2eabcb88814bf108670067e496c569b10cabdb3c110c6aab7d5bea"}, - {file = "ezdxf-1.4.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bf7d0393eb1b680e088a8c56557a7019a77e7d3d0bca1bab7c036cad531a8d09"}, - {file = "ezdxf-1.4.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a821fdd5b24d0d820d2ee2644b1927ea777c7209573407c3e55bb6fdb3d04c05"}, - {file = "ezdxf-1.4.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:8a98a50e111163cf5799b09cdbc7bf302c323636afb454179dc4be4aa3edee3d"}, - {file = "ezdxf-1.4.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:1754cc1f11538ccc4c8b912947b6170b7a34532137d99c176457d207bc9d18b3"}, - {file = "ezdxf-1.4.1-cp312-cp312-win_amd64.whl", hash = "sha256:eecb3775ce8963dde38f0e223c7af86197d9762cd2f73f38a735688c871510b4"}, - {file = "ezdxf-1.4.1-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:69d66bbd976d5ebfd949d12cc44a778ec6db8ae2d223458b192d930d04a87265"}, - {file = "ezdxf-1.4.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:8c385633d2b2d841fe1f181954f594a8f35909c0ef56dda267ef11c3df77573a"}, - {file = "ezdxf-1.4.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:e4ebf64dd97a54c5ade7d27f550612ad7dcf4d8b498e26b594d9e9c054e989ef"}, - {file = "ezdxf-1.4.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d258dbf8fa10d8b30c8c80e76dc56e3533ca1c80098657317946a4bb2f0c59e1"}, - {file = "ezdxf-1.4.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6589905ae064c03de3c373c70fd2140d7337843147ad910c7bf2d0b9975396fa"}, - {file = "ezdxf-1.4.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:9fb788d9f8b6a872463e52efcf8ee582019d6bef4b1a5e12acd24eeb6dcab768"}, - {file = "ezdxf-1.4.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:d9330a42634165b24fcbb9f613421018837236449ba2dc159cedacee65943d03"}, - {file = "ezdxf-1.4.1-cp313-cp313-win_amd64.whl", hash = "sha256:84a278d1bc65de09047d7104c55b0c468494a44f774bc2f0e6f15b27e73704a9"}, - {file = "ezdxf-1.4.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:fad74d71d82b2480bf81204497dafd142f5dd8bafcd57f48bf1c8ef8197102e7"}, - {file = "ezdxf-1.4.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:5e30f5bfc89848dfb8b4d8865347b77dcd6127e2efeb48d985592a6ed0563f47"}, - {file = "ezdxf-1.4.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:5e63725f30cf734190bf5c567198e024d503fc28a942df616e39dc51a6590117"}, - {file = "ezdxf-1.4.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:00495568d5d775e77e97b1793ff6ffd944deeadee47477cd9fcd191b5f3181c4"}, - {file = "ezdxf-1.4.1-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:1b56c98b038dec287f80924483ca61caa45b1335ec05b4dce8bf825db09e303a"}, - {file = "ezdxf-1.4.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:1254c1a7002dcf3dab08b359d04f73f6e062afb7cdc704a46cdacacdc2cfb31e"}, - {file = "ezdxf-1.4.1-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:cb0123a9f00dc6e4b73004333ba34f9dfaece3d9fcf87c82369e3dd980218afc"}, - {file = "ezdxf-1.4.1-cp39-cp39-win_amd64.whl", hash = "sha256:233c05c3084451ef33bff6e8e414de9da7858ceb19d4b68d134060a7a511d00d"}, - {file = "ezdxf-1.4.1-py3-none-any.whl", hash = "sha256:fc3cf018ea0236c33cb3964743b04df54e35e0ff269518860a1f07a5b18b9cd0"}, - {file = "ezdxf-1.4.1.tar.gz", hash = "sha256:4806e4328214f7413a952b7e5066588a83e3c0d600dda8c5f86eed38cfcd706b"}, -] - -[package.dependencies] -fonttools = "*" -numpy = "*" -pyparsing = ">=2.0.1" -typing_extensions = ">=4.6.0" - -[package.extras] -dev = ["Cython", "Pillow", "PyMuPDF (>=1.20.0)", "PySide6", "matplotlib", "pytest", "setuptools", "wheel"] -dev5 = ["Cython", "Pillow", "PyMuPDF (>=1.20.0)", "PyQt5", "matplotlib", "pytest", "setuptools", "wheel"] -draw = ["Pillow", "PyMuPDF (>=1.20.0)", "PySide6", "matplotlib"] -draw5 = ["Pillow", "PyMuPDF (>=1.20.0)", "PyQt5", "matplotlib"] - -[[package]] -name = "fonttools" -version = "4.57.0" -description = "Tools to manipulate font files" -optional = false -python-versions = ">=3.8" -files = [ - {file = "fonttools-4.57.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:babe8d1eb059a53e560e7bf29f8e8f4accc8b6cfb9b5fd10e485bde77e71ef41"}, - {file = "fonttools-4.57.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:81aa97669cd726349eb7bd43ca540cf418b279ee3caba5e2e295fb4e8f841c02"}, - {file = "fonttools-4.57.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f0e9618630edd1910ad4f07f60d77c184b2f572c8ee43305ea3265675cbbfe7e"}, - {file = "fonttools-4.57.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:34687a5d21f1d688d7d8d416cb4c5b9c87fca8a1797ec0d74b9fdebfa55c09ab"}, - {file = "fonttools-4.57.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:69ab81b66ebaa8d430ba56c7a5f9abe0183afefd3a2d6e483060343398b13fb1"}, - {file = "fonttools-4.57.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:d639397de852f2ccfb3134b152c741406752640a266d9c1365b0f23d7b88077f"}, - {file = "fonttools-4.57.0-cp310-cp310-win32.whl", hash = "sha256:cc066cb98b912f525ae901a24cd381a656f024f76203bc85f78fcc9e66ae5aec"}, - {file = "fonttools-4.57.0-cp310-cp310-win_amd64.whl", hash = "sha256:7a64edd3ff6a7f711a15bd70b4458611fb240176ec11ad8845ccbab4fe6745db"}, - {file = "fonttools-4.57.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:3871349303bdec958360eedb619169a779956503ffb4543bb3e6211e09b647c4"}, - {file = "fonttools-4.57.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:c59375e85126b15a90fcba3443eaac58f3073ba091f02410eaa286da9ad80ed8"}, - {file = "fonttools-4.57.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:967b65232e104f4b0f6370a62eb33089e00024f2ce143aecbf9755649421c683"}, - {file = "fonttools-4.57.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:39acf68abdfc74e19de7485f8f7396fa4d2418efea239b7061d6ed6a2510c746"}, - {file = "fonttools-4.57.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:9d077f909f2343daf4495ba22bb0e23b62886e8ec7c109ee8234bdbd678cf344"}, - {file = "fonttools-4.57.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:46370ac47a1e91895d40e9ad48effbe8e9d9db1a4b80888095bc00e7beaa042f"}, - {file = "fonttools-4.57.0-cp311-cp311-win32.whl", hash = "sha256:ca2aed95855506b7ae94e8f1f6217b7673c929e4f4f1217bcaa236253055cb36"}, - {file = "fonttools-4.57.0-cp311-cp311-win_amd64.whl", hash = "sha256:17168a4670bbe3775f3f3f72d23ee786bd965395381dfbb70111e25e81505b9d"}, - {file = "fonttools-4.57.0-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:889e45e976c74abc7256d3064aa7c1295aa283c6bb19810b9f8b604dfe5c7f31"}, - {file = "fonttools-4.57.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:0425c2e052a5f1516c94e5855dbda706ae5a768631e9fcc34e57d074d1b65b92"}, - {file = "fonttools-4.57.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:44c26a311be2ac130f40a96769264809d3b0cb297518669db437d1cc82974888"}, - {file = "fonttools-4.57.0-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:84c41ba992df5b8d680b89fd84c6a1f2aca2b9f1ae8a67400c8930cd4ea115f6"}, - {file = "fonttools-4.57.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:ea1e9e43ca56b0c12440a7c689b1350066595bebcaa83baad05b8b2675129d98"}, - {file = "fonttools-4.57.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:84fd56c78d431606332a0627c16e2a63d243d0d8b05521257d77c6529abe14d8"}, - {file = "fonttools-4.57.0-cp312-cp312-win32.whl", hash = "sha256:f4376819c1c778d59e0a31db5dc6ede854e9edf28bbfa5b756604727f7f800ac"}, - {file = "fonttools-4.57.0-cp312-cp312-win_amd64.whl", hash = "sha256:57e30241524879ea10cdf79c737037221f77cc126a8cdc8ff2c94d4a522504b9"}, - {file = "fonttools-4.57.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:408ce299696012d503b714778d89aa476f032414ae57e57b42e4b92363e0b8ef"}, - {file = "fonttools-4.57.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:bbceffc80aa02d9e8b99f2a7491ed8c4a783b2fc4020119dc405ca14fb5c758c"}, - {file = "fonttools-4.57.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f022601f3ee9e1f6658ed6d184ce27fa5216cee5b82d279e0f0bde5deebece72"}, - {file = "fonttools-4.57.0-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4dea5893b58d4637ffa925536462ba626f8a1b9ffbe2f5c272cdf2c6ebadb817"}, - {file = "fonttools-4.57.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:dff02c5c8423a657c550b48231d0a48d7e2b2e131088e55983cfe74ccc2c7cc9"}, - {file = "fonttools-4.57.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:767604f244dc17c68d3e2dbf98e038d11a18abc078f2d0f84b6c24571d9c0b13"}, - {file = "fonttools-4.57.0-cp313-cp313-win32.whl", hash = "sha256:8e2e12d0d862f43d51e5afb8b9751c77e6bec7d2dc00aad80641364e9df5b199"}, - {file = "fonttools-4.57.0-cp313-cp313-win_amd64.whl", hash = "sha256:f1d6bc9c23356908db712d282acb3eebd4ae5ec6d8b696aa40342b1d84f8e9e3"}, - {file = "fonttools-4.57.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:9d57b4e23ebbe985125d3f0cabbf286efa191ab60bbadb9326091050d88e8213"}, - {file = "fonttools-4.57.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:579ba873d7f2a96f78b2e11028f7472146ae181cae0e4d814a37a09e93d5c5cc"}, - {file = "fonttools-4.57.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6e3e1ec10c29bae0ea826b61f265ec5c858c5ba2ce2e69a71a62f285cf8e4595"}, - {file = "fonttools-4.57.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a1968f2a2003c97c4ce6308dc2498d5fd4364ad309900930aa5a503c9851aec8"}, - {file = "fonttools-4.57.0-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:aff40f8ac6763d05c2c8f6d240c6dac4bb92640a86d9b0c3f3fff4404f34095c"}, - {file = "fonttools-4.57.0-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:d07f1b64008e39fceae7aa99e38df8385d7d24a474a8c9872645c4397b674481"}, - {file = "fonttools-4.57.0-cp38-cp38-win32.whl", hash = "sha256:51d8482e96b28fb28aa8e50b5706f3cee06de85cbe2dce80dbd1917ae22ec5a6"}, - {file = "fonttools-4.57.0-cp38-cp38-win_amd64.whl", hash = "sha256:03290e818782e7edb159474144fca11e36a8ed6663d1fcbd5268eb550594fd8e"}, - {file = "fonttools-4.57.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:7339e6a3283e4b0ade99cade51e97cde3d54cd6d1c3744459e886b66d630c8b3"}, - {file = "fonttools-4.57.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:05efceb2cb5f6ec92a4180fcb7a64aa8d3385fd49cfbbe459350229d1974f0b1"}, - {file = "fonttools-4.57.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a97bb05eb24637714a04dee85bdf0ad1941df64fe3b802ee4ac1c284a5f97b7c"}, - {file = "fonttools-4.57.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:541cb48191a19ceb1a2a4b90c1fcebd22a1ff7491010d3cf840dd3a68aebd654"}, - {file = "fonttools-4.57.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:cdef9a056c222d0479a1fdb721430f9efd68268014c54e8166133d2643cb05d9"}, - {file = "fonttools-4.57.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:3cf97236b192a50a4bf200dc5ba405aa78d4f537a2c6e4c624bb60466d5b03bd"}, - {file = "fonttools-4.57.0-cp39-cp39-win32.whl", hash = "sha256:e952c684274a7714b3160f57ec1d78309f955c6335c04433f07d36c5eb27b1f9"}, - {file = "fonttools-4.57.0-cp39-cp39-win_amd64.whl", hash = "sha256:a2a722c0e4bfd9966a11ff55c895c817158fcce1b2b6700205a376403b546ad9"}, - {file = "fonttools-4.57.0-py3-none-any.whl", hash = "sha256:3122c604a675513c68bd24c6a8f9091f1c2376d18e8f5fe5a101746c81b3e98f"}, - {file = "fonttools-4.57.0.tar.gz", hash = "sha256:727ece10e065be2f9dd239d15dd5d60a66e17eac11aea47d447f9f03fdbc42de"}, -] - -[package.extras] -all = ["brotli (>=1.0.1)", "brotlicffi (>=0.8.0)", "fs (>=2.2.0,<3)", "lxml (>=4.0)", "lz4 (>=1.7.4.2)", "matplotlib", "munkres", "pycairo", "scipy", "skia-pathops (>=0.5.0)", "sympy", "uharfbuzz (>=0.23.0)", "unicodedata2 (>=15.1.0)", "xattr", "zopfli (>=0.1.4)"] -graphite = ["lz4 (>=1.7.4.2)"] -interpolatable = ["munkres", "pycairo", "scipy"] -lxml = ["lxml (>=4.0)"] -pathops = ["skia-pathops (>=0.5.0)"] -plot = ["matplotlib"] -repacker = ["uharfbuzz (>=0.23.0)"] -symfont = ["sympy"] -type1 = ["xattr"] -ufo = ["fs (>=2.2.0,<3)"] -unicode = ["unicodedata2 (>=15.1.0)"] -woff = ["brotli (>=1.0.1)", "brotlicffi (>=0.8.0)", "zopfli (>=0.1.4)"] - -[[package]] -name = "iniconfig" -version = "2.1.0" -description = "brain-dead simple config-ini parsing" -optional = false -python-versions = ">=3.8" -files = [ - {file = "iniconfig-2.1.0-py3-none-any.whl", hash = "sha256:9deba5723312380e77435581c6bf4935c94cbfab9b1ed33ef8d238ea168eb760"}, - {file = "iniconfig-2.1.0.tar.gz", hash = "sha256:3abbd2e30b36733fee78f9c7f7308f2d0050e88f0087fd25c2645f63c773e1c7"}, -] - -[[package]] -name = "ipython" -version = "8.35.0" -description = "IPython: Productive Interactive Computing" -optional = false -python-versions = ">=3.10" -files = [ - {file = "ipython-8.35.0-py3-none-any.whl", hash = "sha256:e6b7470468ba6f1f0a7b116bb688a3ece2f13e2f94138e508201fad677a788ba"}, - {file = "ipython-8.35.0.tar.gz", hash = "sha256:d200b7d93c3f5883fc36ab9ce28a18249c7706e51347681f80a0aef9895f2520"}, -] - -[package.dependencies] -colorama = {version = "*", markers = "sys_platform == \"win32\""} -decorator = "*" -exceptiongroup = {version = "*", markers = "python_version < \"3.11\""} -jedi = ">=0.16" -matplotlib-inline = "*" -pexpect = {version = ">4.3", markers = "sys_platform != \"win32\" and sys_platform != \"emscripten\""} -prompt_toolkit = ">=3.0.41,<3.1.0" -pygments = ">=2.4.0" -stack_data = "*" -traitlets = ">=5.13.0" -typing_extensions = {version = ">=4.6", markers = "python_version < \"3.12\""} - -[package.extras] -all = ["ipython[black,doc,kernel,matplotlib,nbconvert,nbformat,notebook,parallel,qtconsole]", "ipython[test,test-extra]"] -black = ["black"] -doc = ["docrepr", "exceptiongroup", "intersphinx_registry", "ipykernel", "ipython[test]", "matplotlib", "setuptools (>=18.5)", "sphinx (>=1.3)", "sphinx-rtd-theme", "sphinxcontrib-jquery", "tomli", "typing_extensions"] -kernel = ["ipykernel"] -matplotlib = ["matplotlib"] -nbconvert = ["nbconvert"] -nbformat = ["nbformat"] -notebook = ["ipywidgets", "notebook"] -parallel = ["ipyparallel"] -qtconsole = ["qtconsole"] -test = ["packaging", "pickleshare", "pytest", "pytest-asyncio (<0.22)", "testpath"] -test-extra = ["curio", "ipython[test]", "jupyter_ai", "matplotlib (!=3.2.0)", "nbformat", "numpy (>=1.23)", "pandas", "trio"] - -[[package]] -name = "jedi" -version = "0.19.2" -description = "An autocompletion tool for Python that can be used for text editors." -optional = false -python-versions = ">=3.6" -files = [ - {file = "jedi-0.19.2-py2.py3-none-any.whl", hash = "sha256:a8ef22bde8490f57fe5c7681a3c83cb58874daf72b4784de3cce5b6ef6edb5b9"}, - {file = "jedi-0.19.2.tar.gz", hash = "sha256:4770dc3de41bde3966b02eb84fbcf557fb33cce26ad23da12c742fb50ecb11f0"}, -] - -[package.dependencies] -parso = ">=0.8.4,<0.9.0" - -[package.extras] -docs = ["Jinja2 (==2.11.3)", "MarkupSafe (==1.1.1)", "Pygments (==2.8.1)", "alabaster (==0.7.12)", "babel (==2.9.1)", "chardet (==4.0.0)", "commonmark (==0.8.1)", "docutils (==0.17.1)", "future (==0.18.2)", "idna (==2.10)", "imagesize (==1.2.0)", "mock (==1.0.1)", "packaging (==20.9)", "pyparsing (==2.4.7)", "pytz (==2021.1)", "readthedocs-sphinx-ext (==2.1.4)", "recommonmark (==0.5.0)", "requests (==2.25.1)", "six (==1.15.0)", "snowballstemmer (==2.1.0)", "sphinx (==1.8.5)", "sphinx-rtd-theme (==0.4.3)", "sphinxcontrib-serializinghtml (==1.1.4)", "sphinxcontrib-websupport (==1.2.4)", "urllib3 (==1.26.4)"] -qa = ["flake8 (==5.0.4)", "mypy (==0.971)", "types-setuptools (==67.2.0.1)"] -testing = ["Django", "attrs", "colorama", "docopt", "pytest (<9.0.0)"] - -[[package]] -name = "kiwisolver" -version = "1.4.8" -description = "A fast implementation of the Cassowary constraint solver" -optional = false -python-versions = ">=3.10" -files = [ - {file = "kiwisolver-1.4.8-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:88c6f252f6816a73b1f8c904f7bbe02fd67c09a69f7cb8a0eecdbf5ce78e63db"}, - {file = "kiwisolver-1.4.8-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:c72941acb7b67138f35b879bbe85be0f6c6a70cab78fe3ef6db9c024d9223e5b"}, - {file = "kiwisolver-1.4.8-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:ce2cf1e5688edcb727fdf7cd1bbd0b6416758996826a8be1d958f91880d0809d"}, - {file = "kiwisolver-1.4.8-cp310-cp310-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:c8bf637892dc6e6aad2bc6d4d69d08764166e5e3f69d469e55427b6ac001b19d"}, - {file = "kiwisolver-1.4.8-cp310-cp310-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:034d2c891f76bd3edbdb3ea11140d8510dca675443da7304205a2eaa45d8334c"}, - {file = "kiwisolver-1.4.8-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d47b28d1dfe0793d5e96bce90835e17edf9a499b53969b03c6c47ea5985844c3"}, - {file = "kiwisolver-1.4.8-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:eb158fe28ca0c29f2260cca8c43005329ad58452c36f0edf298204de32a9a3ed"}, - {file = "kiwisolver-1.4.8-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d5536185fce131780ebd809f8e623bf4030ce1b161353166c49a3c74c287897f"}, - {file = "kiwisolver-1.4.8-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:369b75d40abedc1da2c1f4de13f3482cb99e3237b38726710f4a793432b1c5ff"}, - {file = "kiwisolver-1.4.8-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:641f2ddf9358c80faa22e22eb4c9f54bd3f0e442e038728f500e3b978d00aa7d"}, - {file = "kiwisolver-1.4.8-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:d561d2d8883e0819445cfe58d7ddd673e4015c3c57261d7bdcd3710d0d14005c"}, - {file = "kiwisolver-1.4.8-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:1732e065704b47c9afca7ffa272f845300a4eb959276bf6970dc07265e73b605"}, - {file = "kiwisolver-1.4.8-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:bcb1ebc3547619c3b58a39e2448af089ea2ef44b37988caf432447374941574e"}, - {file = "kiwisolver-1.4.8-cp310-cp310-win_amd64.whl", hash = "sha256:89c107041f7b27844179ea9c85d6da275aa55ecf28413e87624d033cf1f6b751"}, - {file = "kiwisolver-1.4.8-cp310-cp310-win_arm64.whl", hash = "sha256:b5773efa2be9eb9fcf5415ea3ab70fc785d598729fd6057bea38d539ead28271"}, - {file = "kiwisolver-1.4.8-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:a4d3601908c560bdf880f07d94f31d734afd1bb71e96585cace0e38ef44c6d84"}, - {file = "kiwisolver-1.4.8-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:856b269c4d28a5c0d5e6c1955ec36ebfd1651ac00e1ce0afa3e28da95293b561"}, - {file = "kiwisolver-1.4.8-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:c2b9a96e0f326205af81a15718a9073328df1173a2619a68553decb7097fd5d7"}, - {file = "kiwisolver-1.4.8-cp311-cp311-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c5020c83e8553f770cb3b5fc13faac40f17e0b205bd237aebd21d53d733adb03"}, - {file = "kiwisolver-1.4.8-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dace81d28c787956bfbfbbfd72fdcef014f37d9b48830829e488fdb32b49d954"}, - {file = "kiwisolver-1.4.8-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:11e1022b524bd48ae56c9b4f9296bce77e15a2e42a502cceba602f804b32bb79"}, - {file = "kiwisolver-1.4.8-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3b9b4d2892fefc886f30301cdd80debd8bb01ecdf165a449eb6e78f79f0fabd6"}, - {file = "kiwisolver-1.4.8-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3a96c0e790ee875d65e340ab383700e2b4891677b7fcd30a699146f9384a2bb0"}, - {file = "kiwisolver-1.4.8-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:23454ff084b07ac54ca8be535f4174170c1094a4cff78fbae4f73a4bcc0d4dab"}, - {file = "kiwisolver-1.4.8-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:87b287251ad6488e95b4f0b4a79a6d04d3ea35fde6340eb38fbd1ca9cd35bbbc"}, - {file = "kiwisolver-1.4.8-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:b21dbe165081142b1232a240fc6383fd32cdd877ca6cc89eab93e5f5883e1c25"}, - {file = "kiwisolver-1.4.8-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:768cade2c2df13db52475bd28d3a3fac8c9eff04b0e9e2fda0f3760f20b3f7fc"}, - {file = "kiwisolver-1.4.8-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:d47cfb2650f0e103d4bf68b0b5804c68da97272c84bb12850d877a95c056bd67"}, - {file = "kiwisolver-1.4.8-cp311-cp311-win_amd64.whl", hash = "sha256:ed33ca2002a779a2e20eeb06aea7721b6e47f2d4b8a8ece979d8ba9e2a167e34"}, - {file = "kiwisolver-1.4.8-cp311-cp311-win_arm64.whl", hash = "sha256:16523b40aab60426ffdebe33ac374457cf62863e330a90a0383639ce14bf44b2"}, - {file = "kiwisolver-1.4.8-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:d6af5e8815fd02997cb6ad9bbed0ee1e60014438ee1a5c2444c96f87b8843502"}, - {file = "kiwisolver-1.4.8-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:bade438f86e21d91e0cf5dd7c0ed00cda0f77c8c1616bd83f9fc157fa6760d31"}, - {file = "kiwisolver-1.4.8-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:b83dc6769ddbc57613280118fb4ce3cd08899cc3369f7d0e0fab518a7cf37fdb"}, - {file = "kiwisolver-1.4.8-cp312-cp312-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:111793b232842991be367ed828076b03d96202c19221b5ebab421ce8bcad016f"}, - {file = "kiwisolver-1.4.8-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:257af1622860e51b1a9d0ce387bf5c2c4f36a90594cb9514f55b074bcc787cfc"}, - {file = "kiwisolver-1.4.8-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:69b5637c3f316cab1ec1c9a12b8c5f4750a4c4b71af9157645bf32830e39c03a"}, - {file = "kiwisolver-1.4.8-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:782bb86f245ec18009890e7cb8d13a5ef54dcf2ebe18ed65f795e635a96a1c6a"}, - {file = "kiwisolver-1.4.8-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cc978a80a0db3a66d25767b03688f1147a69e6237175c0f4ffffaaedf744055a"}, - {file = "kiwisolver-1.4.8-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:36dbbfd34838500a31f52c9786990d00150860e46cd5041386f217101350f0d3"}, - {file = "kiwisolver-1.4.8-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:eaa973f1e05131de5ff3569bbba7f5fd07ea0595d3870ed4a526d486fe57fa1b"}, - {file = "kiwisolver-1.4.8-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:a66f60f8d0c87ab7f59b6fb80e642ebb29fec354a4dfad687ca4092ae69d04f4"}, - {file = "kiwisolver-1.4.8-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:858416b7fb777a53f0c59ca08190ce24e9abbd3cffa18886a5781b8e3e26f65d"}, - {file = "kiwisolver-1.4.8-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:085940635c62697391baafaaeabdf3dd7a6c3643577dde337f4d66eba021b2b8"}, - {file = "kiwisolver-1.4.8-cp312-cp312-win_amd64.whl", hash = "sha256:01c3d31902c7db5fb6182832713d3b4122ad9317c2c5877d0539227d96bb2e50"}, - {file = "kiwisolver-1.4.8-cp312-cp312-win_arm64.whl", hash = "sha256:a3c44cb68861de93f0c4a8175fbaa691f0aa22550c331fefef02b618a9dcb476"}, - {file = "kiwisolver-1.4.8-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:1c8ceb754339793c24aee1c9fb2485b5b1f5bb1c2c214ff13368431e51fc9a09"}, - {file = "kiwisolver-1.4.8-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:54a62808ac74b5e55a04a408cda6156f986cefbcf0ada13572696b507cc92fa1"}, - {file = "kiwisolver-1.4.8-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:68269e60ee4929893aad82666821aaacbd455284124817af45c11e50a4b42e3c"}, - {file = "kiwisolver-1.4.8-cp313-cp313-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:34d142fba9c464bc3bbfeff15c96eab0e7310343d6aefb62a79d51421fcc5f1b"}, - {file = "kiwisolver-1.4.8-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3ddc373e0eef45b59197de815b1b28ef89ae3955e7722cc9710fb91cd77b7f47"}, - {file = "kiwisolver-1.4.8-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:77e6f57a20b9bd4e1e2cedda4d0b986ebd0216236f0106e55c28aea3d3d69b16"}, - {file = "kiwisolver-1.4.8-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:08e77738ed7538f036cd1170cbed942ef749137b1311fa2bbe2a7fda2f6bf3cc"}, - {file = "kiwisolver-1.4.8-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a5ce1e481a74b44dd5e92ff03ea0cb371ae7a0268318e202be06c8f04f4f1246"}, - {file = "kiwisolver-1.4.8-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:fc2ace710ba7c1dfd1a3b42530b62b9ceed115f19a1656adefce7b1782a37794"}, - {file = "kiwisolver-1.4.8-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:3452046c37c7692bd52b0e752b87954ef86ee2224e624ef7ce6cb21e8c41cc1b"}, - {file = "kiwisolver-1.4.8-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:7e9a60b50fe8b2ec6f448fe8d81b07e40141bfced7f896309df271a0b92f80f3"}, - {file = "kiwisolver-1.4.8-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:918139571133f366e8362fa4a297aeba86c7816b7ecf0bc79168080e2bd79957"}, - {file = "kiwisolver-1.4.8-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:e063ef9f89885a1d68dd8b2e18f5ead48653176d10a0e324e3b0030e3a69adeb"}, - {file = "kiwisolver-1.4.8-cp313-cp313-win_amd64.whl", hash = "sha256:a17b7c4f5b2c51bb68ed379defd608a03954a1845dfed7cc0117f1cc8a9b7fd2"}, - {file = "kiwisolver-1.4.8-cp313-cp313-win_arm64.whl", hash = "sha256:3cd3bc628b25f74aedc6d374d5babf0166a92ff1317f46267f12d2ed54bc1d30"}, - {file = "kiwisolver-1.4.8-cp313-cp313t-macosx_10_13_universal2.whl", hash = "sha256:370fd2df41660ed4e26b8c9d6bbcad668fbe2560462cba151a721d49e5b6628c"}, - {file = "kiwisolver-1.4.8-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:84a2f830d42707de1d191b9490ac186bf7997a9495d4e9072210a1296345f7dc"}, - {file = "kiwisolver-1.4.8-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:7a3ad337add5148cf51ce0b55642dc551c0b9d6248458a757f98796ca7348712"}, - {file = "kiwisolver-1.4.8-cp313-cp313t-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7506488470f41169b86d8c9aeff587293f530a23a23a49d6bc64dab66bedc71e"}, - {file = "kiwisolver-1.4.8-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2f0121b07b356a22fb0414cec4666bbe36fd6d0d759db3d37228f496ed67c880"}, - {file = "kiwisolver-1.4.8-cp313-cp313t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d6d6bd87df62c27d4185de7c511c6248040afae67028a8a22012b010bc7ad062"}, - {file = "kiwisolver-1.4.8-cp313-cp313t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:291331973c64bb9cce50bbe871fb2e675c4331dab4f31abe89f175ad7679a4d7"}, - {file = "kiwisolver-1.4.8-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:893f5525bb92d3d735878ec00f781b2de998333659507d29ea4466208df37bed"}, - {file = "kiwisolver-1.4.8-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:b47a465040146981dc9db8647981b8cb96366fbc8d452b031e4f8fdffec3f26d"}, - {file = "kiwisolver-1.4.8-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:99cea8b9dd34ff80c521aef46a1dddb0dcc0283cf18bde6d756f1e6f31772165"}, - {file = "kiwisolver-1.4.8-cp313-cp313t-musllinux_1_2_ppc64le.whl", hash = "sha256:151dffc4865e5fe6dafce5480fab84f950d14566c480c08a53c663a0020504b6"}, - {file = "kiwisolver-1.4.8-cp313-cp313t-musllinux_1_2_s390x.whl", hash = "sha256:577facaa411c10421314598b50413aa1ebcf5126f704f1e5d72d7e4e9f020d90"}, - {file = "kiwisolver-1.4.8-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:be4816dc51c8a471749d664161b434912eee82f2ea66bd7628bd14583a833e85"}, - {file = "kiwisolver-1.4.8-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:e7a019419b7b510f0f7c9dceff8c5eae2392037eae483a7f9162625233802b0a"}, - {file = "kiwisolver-1.4.8-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:286b18e86682fd2217a48fc6be6b0f20c1d0ed10958d8dc53453ad58d7be0bf8"}, - {file = "kiwisolver-1.4.8-pp310-pypy310_pp73-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4191ee8dfd0be1c3666ccbac178c5a05d5f8d689bbe3fc92f3c4abec817f8fe0"}, - {file = "kiwisolver-1.4.8-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7cd2785b9391f2873ad46088ed7599a6a71e762e1ea33e87514b1a441ed1da1c"}, - {file = "kiwisolver-1.4.8-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c07b29089b7ba090b6f1a669f1411f27221c3662b3a1b7010e67b59bb5a6f10b"}, - {file = "kiwisolver-1.4.8-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:65ea09a5a3faadd59c2ce96dc7bf0f364986a315949dc6374f04396b0d60e09b"}, - {file = "kiwisolver-1.4.8.tar.gz", hash = "sha256:23d5f023bdc8c7e54eb65f03ca5d5bb25b601eac4d7f1a042888a1f45237987e"}, -] - -[[package]] -name = "matplotlib" -version = "3.10.1" -description = "Python plotting package" -optional = false -python-versions = ">=3.10" -files = [ - {file = "matplotlib-3.10.1-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:ff2ae14910be903f4a24afdbb6d7d3a6c44da210fc7d42790b87aeac92238a16"}, - {file = "matplotlib-3.10.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:0721a3fd3d5756ed593220a8b86808a36c5031fce489adb5b31ee6dbb47dd5b2"}, - {file = "matplotlib-3.10.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d0673b4b8f131890eb3a1ad058d6e065fb3c6e71f160089b65f8515373394698"}, - {file = "matplotlib-3.10.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8e875b95ac59a7908978fe307ecdbdd9a26af7fa0f33f474a27fcf8c99f64a19"}, - {file = "matplotlib-3.10.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:2589659ea30726284c6c91037216f64a506a9822f8e50592d48ac16a2f29e044"}, - {file = "matplotlib-3.10.1-cp310-cp310-win_amd64.whl", hash = "sha256:a97ff127f295817bc34517255c9db6e71de8eddaab7f837b7d341dee9f2f587f"}, - {file = "matplotlib-3.10.1-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:057206ff2d6ab82ff3e94ebd94463d084760ca682ed5f150817b859372ec4401"}, - {file = "matplotlib-3.10.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:a144867dd6bf8ba8cb5fc81a158b645037e11b3e5cf8a50bd5f9917cb863adfe"}, - {file = "matplotlib-3.10.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:56c5d9fcd9879aa8040f196a235e2dcbdf7dd03ab5b07c0696f80bc6cf04bedd"}, - {file = "matplotlib-3.10.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0f69dc9713e4ad2fb21a1c30e37bd445d496524257dfda40ff4a8efb3604ab5c"}, - {file = "matplotlib-3.10.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:4c59af3e8aca75d7744b68e8e78a669e91ccbcf1ac35d0102a7b1b46883f1dd7"}, - {file = "matplotlib-3.10.1-cp311-cp311-win_amd64.whl", hash = "sha256:11b65088c6f3dae784bc72e8d039a2580186285f87448babb9ddb2ad0082993a"}, - {file = "matplotlib-3.10.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:66e907a06e68cb6cfd652c193311d61a12b54f56809cafbed9736ce5ad92f107"}, - {file = "matplotlib-3.10.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:e9b4bb156abb8fa5e5b2b460196f7db7264fc6d62678c03457979e7d5254b7be"}, - {file = "matplotlib-3.10.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1985ad3d97f51307a2cbfc801a930f120def19ba22864182dacef55277102ba6"}, - {file = "matplotlib-3.10.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c96f2c2f825d1257e437a1482c5a2cf4fee15db4261bd6fc0750f81ba2b4ba3d"}, - {file = "matplotlib-3.10.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:35e87384ee9e488d8dd5a2dd7baf471178d38b90618d8ea147aced4ab59c9bea"}, - {file = "matplotlib-3.10.1-cp312-cp312-win_amd64.whl", hash = "sha256:cfd414bce89cc78a7e1d25202e979b3f1af799e416010a20ab2b5ebb3a02425c"}, - {file = "matplotlib-3.10.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:c42eee41e1b60fd83ee3292ed83a97a5f2a8239b10c26715d8a6172226988d7b"}, - {file = "matplotlib-3.10.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:4f0647b17b667ae745c13721602b540f7aadb2a32c5b96e924cd4fea5dcb90f1"}, - {file = "matplotlib-3.10.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:aa3854b5f9473564ef40a41bc922be978fab217776e9ae1545c9b3a5cf2092a3"}, - {file = "matplotlib-3.10.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7e496c01441be4c7d5f96d4e40f7fca06e20dcb40e44c8daa2e740e1757ad9e6"}, - {file = "matplotlib-3.10.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:5d45d3f5245be5b469843450617dcad9af75ca50568acf59997bed9311131a0b"}, - {file = "matplotlib-3.10.1-cp313-cp313-win_amd64.whl", hash = "sha256:8e8e25b1209161d20dfe93037c8a7f7ca796ec9aa326e6e4588d8c4a5dd1e473"}, - {file = "matplotlib-3.10.1-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:19b06241ad89c3ae9469e07d77efa87041eac65d78df4fcf9cac318028009b01"}, - {file = "matplotlib-3.10.1-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:01e63101ebb3014e6e9f80d9cf9ee361a8599ddca2c3e166c563628b39305dbb"}, - {file = "matplotlib-3.10.1-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3f06bad951eea6422ac4e8bdebcf3a70c59ea0a03338c5d2b109f57b64eb3972"}, - {file = "matplotlib-3.10.1-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a3dfb036f34873b46978f55e240cff7a239f6c4409eac62d8145bad3fc6ba5a3"}, - {file = "matplotlib-3.10.1-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:dc6ab14a7ab3b4d813b88ba957fc05c79493a037f54e246162033591e770de6f"}, - {file = "matplotlib-3.10.1-cp313-cp313t-win_amd64.whl", hash = "sha256:bc411ebd5889a78dabbc457b3fa153203e22248bfa6eedc6797be5df0164dbf9"}, - {file = "matplotlib-3.10.1-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:648406f1899f9a818cef8c0231b44dcfc4ff36f167101c3fd1c9151f24220fdc"}, - {file = "matplotlib-3.10.1-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:02582304e352f40520727984a5a18f37e8187861f954fea9be7ef06569cf85b4"}, - {file = "matplotlib-3.10.1-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d3809916157ba871bcdd33d3493acd7fe3037db5daa917ca6e77975a94cef779"}, - {file = "matplotlib-3.10.1.tar.gz", hash = "sha256:e8d2d0e3881b129268585bf4765ad3ee73a4591d77b9a18c214ac7e3a79fb2ba"}, -] - -[package.dependencies] -contourpy = ">=1.0.1" -cycler = ">=0.10" -fonttools = ">=4.22.0" -kiwisolver = ">=1.3.1" -numpy = ">=1.23" -packaging = ">=20.0" -pillow = ">=8" -pyparsing = ">=2.3.1" -python-dateutil = ">=2.7" - -[package.extras] -dev = ["meson-python (>=0.13.1,<0.17.0)", "pybind11 (>=2.13.2,!=2.13.3)", "setuptools (>=64)", "setuptools_scm (>=7)"] - -[[package]] -name = "matplotlib-inline" -version = "0.1.7" -description = "Inline Matplotlib backend for Jupyter" -optional = false -python-versions = ">=3.8" -files = [ - {file = "matplotlib_inline-0.1.7-py3-none-any.whl", hash = "sha256:df192d39a4ff8f21b1895d72e6a13f5fcc5099f00fa84384e0ea28c2cc0653ca"}, - {file = "matplotlib_inline-0.1.7.tar.gz", hash = "sha256:8423b23ec666be3d16e16b60bdd8ac4e86e840ebd1dd11a30b9f117f2fa0ab90"}, -] - -[package.dependencies] -traitlets = "*" - -[[package]] -name = "numpy" -version = "2.2.5" -description = "Fundamental package for array computing in Python" -optional = false -python-versions = ">=3.10" -files = [ - {file = "numpy-2.2.5-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:1f4a922da1729f4c40932b2af4fe84909c7a6e167e6e99f71838ce3a29f3fe26"}, - {file = "numpy-2.2.5-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:b6f91524d31b34f4a5fee24f5bc16dcd1491b668798b6d85585d836c1e633a6a"}, - {file = "numpy-2.2.5-cp310-cp310-macosx_14_0_arm64.whl", hash = "sha256:19f4718c9012e3baea91a7dba661dcab2451cda2550678dc30d53acb91a7290f"}, - {file = "numpy-2.2.5-cp310-cp310-macosx_14_0_x86_64.whl", hash = "sha256:eb7fd5b184e5d277afa9ec0ad5e4eb562ecff541e7f60e69ee69c8d59e9aeaba"}, - {file = "numpy-2.2.5-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6413d48a9be53e183eb06495d8e3b006ef8f87c324af68241bbe7a39e8ff54c3"}, - {file = "numpy-2.2.5-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7451f92eddf8503c9b8aa4fe6aa7e87fd51a29c2cfc5f7dbd72efde6c65acf57"}, - {file = "numpy-2.2.5-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:0bcb1d057b7571334139129b7f941588f69ce7c4ed15a9d6162b2ea54ded700c"}, - {file = "numpy-2.2.5-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:36ab5b23915887543441efd0417e6a3baa08634308894316f446027611b53bf1"}, - {file = "numpy-2.2.5-cp310-cp310-win32.whl", hash = "sha256:422cc684f17bc963da5f59a31530b3936f57c95a29743056ef7a7903a5dbdf88"}, - {file = "numpy-2.2.5-cp310-cp310-win_amd64.whl", hash = "sha256:e4f0b035d9d0ed519c813ee23e0a733db81ec37d2e9503afbb6e54ccfdee0fa7"}, - {file = "numpy-2.2.5-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:c42365005c7a6c42436a54d28c43fe0e01ca11eb2ac3cefe796c25a5f98e5e9b"}, - {file = "numpy-2.2.5-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:498815b96f67dc347e03b719ef49c772589fb74b8ee9ea2c37feae915ad6ebda"}, - {file = "numpy-2.2.5-cp311-cp311-macosx_14_0_arm64.whl", hash = "sha256:6411f744f7f20081b1b4e7112e0f4c9c5b08f94b9f086e6f0adf3645f85d3a4d"}, - {file = "numpy-2.2.5-cp311-cp311-macosx_14_0_x86_64.whl", hash = "sha256:9de6832228f617c9ef45d948ec1cd8949c482238d68b2477e6f642c33a7b0a54"}, - {file = "numpy-2.2.5-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:369e0d4647c17c9363244f3468f2227d557a74b6781cb62ce57cf3ef5cc7c610"}, - {file = "numpy-2.2.5-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:262d23f383170f99cd9191a7c85b9a50970fe9069b2f8ab5d786eca8a675d60b"}, - {file = "numpy-2.2.5-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:aa70fdbdc3b169d69e8c59e65c07a1c9351ceb438e627f0fdcd471015cd956be"}, - {file = "numpy-2.2.5-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:37e32e985f03c06206582a7323ef926b4e78bdaa6915095ef08070471865b906"}, - {file = "numpy-2.2.5-cp311-cp311-win32.whl", hash = "sha256:f5045039100ed58fa817a6227a356240ea1b9a1bc141018864c306c1a16d4175"}, - {file = "numpy-2.2.5-cp311-cp311-win_amd64.whl", hash = "sha256:b13f04968b46ad705f7c8a80122a42ae8f620536ea38cf4bdd374302926424dd"}, - {file = "numpy-2.2.5-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:ee461a4eaab4f165b68780a6a1af95fb23a29932be7569b9fab666c407969051"}, - {file = "numpy-2.2.5-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:ec31367fd6a255dc8de4772bd1658c3e926d8e860a0b6e922b615e532d320ddc"}, - {file = "numpy-2.2.5-cp312-cp312-macosx_14_0_arm64.whl", hash = "sha256:47834cde750d3c9f4e52c6ca28a7361859fcaf52695c7dc3cc1a720b8922683e"}, - {file = "numpy-2.2.5-cp312-cp312-macosx_14_0_x86_64.whl", hash = "sha256:2c1a1c6ccce4022383583a6ded7bbcda22fc635eb4eb1e0a053336425ed36dfa"}, - {file = "numpy-2.2.5-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9d75f338f5f79ee23548b03d801d28a505198297534f62416391857ea0479571"}, - {file = "numpy-2.2.5-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3a801fef99668f309b88640e28d261991bfad9617c27beda4a3aec4f217ea073"}, - {file = "numpy-2.2.5-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:abe38cd8381245a7f49967a6010e77dbf3680bd3627c0fe4362dd693b404c7f8"}, - {file = "numpy-2.2.5-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:5a0ac90e46fdb5649ab6369d1ab6104bfe5854ab19b645bf5cda0127a13034ae"}, - {file = "numpy-2.2.5-cp312-cp312-win32.whl", hash = "sha256:0cd48122a6b7eab8f06404805b1bd5856200e3ed6f8a1b9a194f9d9054631beb"}, - {file = "numpy-2.2.5-cp312-cp312-win_amd64.whl", hash = "sha256:ced69262a8278547e63409b2653b372bf4baff0870c57efa76c5703fd6543282"}, - {file = "numpy-2.2.5-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:059b51b658f4414fff78c6d7b1b4e18283ab5fa56d270ff212d5ba0c561846f4"}, - {file = "numpy-2.2.5-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:47f9ed103af0bc63182609044b0490747e03bd20a67e391192dde119bf43d52f"}, - {file = "numpy-2.2.5-cp313-cp313-macosx_14_0_arm64.whl", hash = "sha256:261a1ef047751bb02f29dfe337230b5882b54521ca121fc7f62668133cb119c9"}, - {file = "numpy-2.2.5-cp313-cp313-macosx_14_0_x86_64.whl", hash = "sha256:4520caa3807c1ceb005d125a75e715567806fed67e315cea619d5ec6e75a4191"}, - {file = "numpy-2.2.5-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3d14b17b9be5f9c9301f43d2e2a4886a33b53f4e6fdf9ca2f4cc60aeeee76372"}, - {file = "numpy-2.2.5-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2ba321813a00e508d5421104464510cc962a6f791aa2fca1c97b1e65027da80d"}, - {file = "numpy-2.2.5-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:a4cbdef3ddf777423060c6f81b5694bad2dc9675f110c4b2a60dc0181543fac7"}, - {file = "numpy-2.2.5-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:54088a5a147ab71a8e7fdfd8c3601972751ded0739c6b696ad9cb0343e21ab73"}, - {file = "numpy-2.2.5-cp313-cp313-win32.whl", hash = "sha256:c8b82a55ef86a2d8e81b63da85e55f5537d2157165be1cb2ce7cfa57b6aef38b"}, - {file = "numpy-2.2.5-cp313-cp313-win_amd64.whl", hash = "sha256:d8882a829fd779f0f43998e931c466802a77ca1ee0fe25a3abe50278616b1471"}, - {file = "numpy-2.2.5-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:e8b025c351b9f0e8b5436cf28a07fa4ac0204d67b38f01433ac7f9b870fa38c6"}, - {file = "numpy-2.2.5-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:8dfa94b6a4374e7851bbb6f35e6ded2120b752b063e6acdd3157e4d2bb922eba"}, - {file = "numpy-2.2.5-cp313-cp313t-macosx_14_0_arm64.whl", hash = "sha256:97c8425d4e26437e65e1d189d22dff4a079b747ff9c2788057bfb8114ce1e133"}, - {file = "numpy-2.2.5-cp313-cp313t-macosx_14_0_x86_64.whl", hash = "sha256:352d330048c055ea6db701130abc48a21bec690a8d38f8284e00fab256dc1376"}, - {file = "numpy-2.2.5-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8b4c0773b6ada798f51f0f8e30c054d32304ccc6e9c5d93d46cb26f3d385ab19"}, - {file = "numpy-2.2.5-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:55f09e00d4dccd76b179c0f18a44f041e5332fd0e022886ba1c0bbf3ea4a18d0"}, - {file = "numpy-2.2.5-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:02f226baeefa68f7d579e213d0f3493496397d8f1cff5e2b222af274c86a552a"}, - {file = "numpy-2.2.5-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:c26843fd58f65da9491165072da2cccc372530681de481ef670dcc8e27cfb066"}, - {file = "numpy-2.2.5-cp313-cp313t-win32.whl", hash = "sha256:1a161c2c79ab30fe4501d5a2bbfe8b162490757cf90b7f05be8b80bc02f7bb8e"}, - {file = "numpy-2.2.5-cp313-cp313t-win_amd64.whl", hash = "sha256:d403c84991b5ad291d3809bace5e85f4bbf44a04bdc9a88ed2bb1807b3360bb8"}, - {file = "numpy-2.2.5-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:b4ea7e1cff6784e58fe281ce7e7f05036b3e1c89c6f922a6bfbc0a7e8768adbe"}, - {file = "numpy-2.2.5-pp310-pypy310_pp73-macosx_14_0_x86_64.whl", hash = "sha256:d7543263084a85fbc09c704b515395398d31d6395518446237eac219eab9e55e"}, - {file = "numpy-2.2.5-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0255732338c4fdd00996c0421884ea8a3651eea555c3a56b84892b66f696eb70"}, - {file = "numpy-2.2.5-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:d2e3bdadaba0e040d1e7ab39db73e0afe2c74ae277f5614dad53eadbecbbb169"}, - {file = "numpy-2.2.5.tar.gz", hash = "sha256:a9c0d994680cd991b1cb772e8b297340085466a6fe964bc9d4e80f5e2f43c291"}, -] - -[[package]] -name = "ocpsvg" -version = "0.5.0" -description = "" -optional = false -python-versions = ">=3.10" -files = [ - {file = "ocpsvg-0.5.0-py3-none-any.whl", hash = "sha256:68cafdc3d681a1707530360baf2d51cfd58414b7d439f42eafbd31e842cf295e"}, - {file = "ocpsvg-0.5.0.tar.gz", hash = "sha256:5cd8dbec8bf590d373a82aaebeab241838185aab04ee2859f33b9d7956bbfba6"}, -] - -[package.dependencies] -cadquery-ocp = ">=7.8.1,<7.9.0" -svgelements = ">=1.9.1,<2" - -[package.extras] -dev = ["pytest"] - -[[package]] -name = "packaging" -version = "25.0" -description = "Core utilities for Python packages" -optional = false -python-versions = ">=3.8" -files = [ - {file = "packaging-25.0-py3-none-any.whl", hash = "sha256:29572ef2b1f17581046b3a2227d5c611fb25ec70ca1ba8554b24b0e69331a484"}, - {file = "packaging-25.0.tar.gz", hash = "sha256:d443872c98d677bf60f6a1f2f8c1cb748e8fe762d2bf9d3148b5599295b0fc4f"}, -] - -[[package]] -name = "parso" -version = "0.8.4" -description = "A Python Parser" -optional = false -python-versions = ">=3.6" -files = [ - {file = "parso-0.8.4-py2.py3-none-any.whl", hash = "sha256:a418670a20291dacd2dddc80c377c5c3791378ee1e8d12bffc35420643d43f18"}, - {file = "parso-0.8.4.tar.gz", hash = "sha256:eb3a7b58240fb99099a345571deecc0f9540ea5f4dd2fe14c2a99d6b281ab92d"}, -] - -[package.extras] -qa = ["flake8 (==5.0.4)", "mypy (==0.971)", "types-setuptools (==67.2.0.1)"] -testing = ["docopt", "pytest"] - -[[package]] -name = "pexpect" -version = "4.9.0" -description = "Pexpect allows easy control of interactive console applications." -optional = false -python-versions = "*" -files = [ - {file = "pexpect-4.9.0-py2.py3-none-any.whl", hash = "sha256:7236d1e080e4936be2dc3e326cec0af72acf9212a7e1d060210e70a47e253523"}, - {file = "pexpect-4.9.0.tar.gz", hash = "sha256:ee7d41123f3c9911050ea2c2dac107568dc43b2d3b0c7557a33212c398ead30f"}, -] - -[package.dependencies] -ptyprocess = ">=0.5" - -[[package]] -name = "pillow" -version = "11.2.1" -description = "Python Imaging Library (Fork)" -optional = false -python-versions = ">=3.9" -files = [ - {file = "pillow-11.2.1-cp310-cp310-macosx_10_10_x86_64.whl", hash = "sha256:d57a75d53922fc20c165016a20d9c44f73305e67c351bbc60d1adaf662e74047"}, - {file = "pillow-11.2.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:127bf6ac4a5b58b3d32fc8289656f77f80567d65660bc46f72c0d77e6600cc95"}, - {file = "pillow-11.2.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b4ba4be812c7a40280629e55ae0b14a0aafa150dd6451297562e1764808bbe61"}, - {file = "pillow-11.2.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c8bd62331e5032bc396a93609982a9ab6b411c05078a52f5fe3cc59234a3abd1"}, - {file = "pillow-11.2.1-cp310-cp310-manylinux_2_28_aarch64.whl", hash = "sha256:562d11134c97a62fe3af29581f083033179f7ff435f78392565a1ad2d1c2c45c"}, - {file = "pillow-11.2.1-cp310-cp310-manylinux_2_28_x86_64.whl", hash = "sha256:c97209e85b5be259994eb5b69ff50c5d20cca0f458ef9abd835e262d9d88b39d"}, - {file = "pillow-11.2.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:0c3e6d0f59171dfa2e25d7116217543310908dfa2770aa64b8f87605f8cacc97"}, - {file = "pillow-11.2.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:cc1c3bc53befb6096b84165956e886b1729634a799e9d6329a0c512ab651e579"}, - {file = "pillow-11.2.1-cp310-cp310-win32.whl", hash = "sha256:312c77b7f07ab2139924d2639860e084ec2a13e72af54d4f08ac843a5fc9c79d"}, - {file = "pillow-11.2.1-cp310-cp310-win_amd64.whl", hash = "sha256:9bc7ae48b8057a611e5fe9f853baa88093b9a76303937449397899385da06fad"}, - {file = "pillow-11.2.1-cp310-cp310-win_arm64.whl", hash = "sha256:2728567e249cdd939f6cc3d1f049595c66e4187f3c34078cbc0a7d21c47482d2"}, - {file = "pillow-11.2.1-cp311-cp311-macosx_10_10_x86_64.whl", hash = "sha256:35ca289f712ccfc699508c4658a1d14652e8033e9b69839edf83cbdd0ba39e70"}, - {file = "pillow-11.2.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:e0409af9f829f87a2dfb7e259f78f317a5351f2045158be321fd135973fff7bf"}, - {file = "pillow-11.2.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d4e5c5edee874dce4f653dbe59db7c73a600119fbea8d31f53423586ee2aafd7"}, - {file = "pillow-11.2.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b93a07e76d13bff9444f1a029e0af2964e654bfc2e2c2d46bfd080df5ad5f3d8"}, - {file = "pillow-11.2.1-cp311-cp311-manylinux_2_28_aarch64.whl", hash = "sha256:e6def7eed9e7fa90fde255afaf08060dc4b343bbe524a8f69bdd2a2f0018f600"}, - {file = "pillow-11.2.1-cp311-cp311-manylinux_2_28_x86_64.whl", hash = "sha256:8f4f3724c068be008c08257207210c138d5f3731af6c155a81c2b09a9eb3a788"}, - {file = "pillow-11.2.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:a0a6709b47019dff32e678bc12c63008311b82b9327613f534e496dacaefb71e"}, - {file = "pillow-11.2.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:f6b0c664ccb879109ee3ca702a9272d877f4fcd21e5eb63c26422fd6e415365e"}, - {file = "pillow-11.2.1-cp311-cp311-win32.whl", hash = "sha256:cc5d875d56e49f112b6def6813c4e3d3036d269c008bf8aef72cd08d20ca6df6"}, - {file = "pillow-11.2.1-cp311-cp311-win_amd64.whl", hash = "sha256:0f5c7eda47bf8e3c8a283762cab94e496ba977a420868cb819159980b6709193"}, - {file = "pillow-11.2.1-cp311-cp311-win_arm64.whl", hash = "sha256:4d375eb838755f2528ac8cbc926c3e31cc49ca4ad0cf79cff48b20e30634a4a7"}, - {file = "pillow-11.2.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:78afba22027b4accef10dbd5eed84425930ba41b3ea0a86fa8d20baaf19d807f"}, - {file = "pillow-11.2.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:78092232a4ab376a35d68c4e6d5e00dfd73454bd12b230420025fbe178ee3b0b"}, - {file = "pillow-11.2.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:25a5f306095c6780c52e6bbb6109624b95c5b18e40aab1c3041da3e9e0cd3e2d"}, - {file = "pillow-11.2.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0c7b29dbd4281923a2bfe562acb734cee96bbb129e96e6972d315ed9f232bef4"}, - {file = "pillow-11.2.1-cp312-cp312-manylinux_2_28_aarch64.whl", hash = "sha256:3e645b020f3209a0181a418bffe7b4a93171eef6c4ef6cc20980b30bebf17b7d"}, - {file = "pillow-11.2.1-cp312-cp312-manylinux_2_28_x86_64.whl", hash = "sha256:b2dbea1012ccb784a65349f57bbc93730b96e85b42e9bf7b01ef40443db720b4"}, - {file = "pillow-11.2.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:da3104c57bbd72948d75f6a9389e6727d2ab6333c3617f0a89d72d4940aa0443"}, - {file = "pillow-11.2.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:598174aef4589af795f66f9caab87ba4ff860ce08cd5bb447c6fc553ffee603c"}, - {file = "pillow-11.2.1-cp312-cp312-win32.whl", hash = "sha256:1d535df14716e7f8776b9e7fee118576d65572b4aad3ed639be9e4fa88a1cad3"}, - {file = "pillow-11.2.1-cp312-cp312-win_amd64.whl", hash = "sha256:14e33b28bf17c7a38eede290f77db7c664e4eb01f7869e37fa98a5aa95978941"}, - {file = "pillow-11.2.1-cp312-cp312-win_arm64.whl", hash = "sha256:21e1470ac9e5739ff880c211fc3af01e3ae505859392bf65458c224d0bf283eb"}, - {file = "pillow-11.2.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:fdec757fea0b793056419bca3e9932eb2b0ceec90ef4813ea4c1e072c389eb28"}, - {file = "pillow-11.2.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:b0e130705d568e2f43a17bcbe74d90958e8a16263868a12c3e0d9c8162690830"}, - {file = "pillow-11.2.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7bdb5e09068332578214cadd9c05e3d64d99e0e87591be22a324bdbc18925be0"}, - {file = "pillow-11.2.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d189ba1bebfbc0c0e529159631ec72bb9e9bc041f01ec6d3233d6d82eb823bc1"}, - {file = "pillow-11.2.1-cp313-cp313-manylinux_2_28_aarch64.whl", hash = "sha256:191955c55d8a712fab8934a42bfefbf99dd0b5875078240943f913bb66d46d9f"}, - {file = "pillow-11.2.1-cp313-cp313-manylinux_2_28_x86_64.whl", hash = "sha256:ad275964d52e2243430472fc5d2c2334b4fc3ff9c16cb0a19254e25efa03a155"}, - {file = "pillow-11.2.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:750f96efe0597382660d8b53e90dd1dd44568a8edb51cb7f9d5d918b80d4de14"}, - {file = "pillow-11.2.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:fe15238d3798788d00716637b3d4e7bb6bde18b26e5d08335a96e88564a36b6b"}, - {file = "pillow-11.2.1-cp313-cp313-win32.whl", hash = "sha256:3fe735ced9a607fee4f481423a9c36701a39719252a9bb251679635f99d0f7d2"}, - {file = "pillow-11.2.1-cp313-cp313-win_amd64.whl", hash = "sha256:74ee3d7ecb3f3c05459ba95eed5efa28d6092d751ce9bf20e3e253a4e497e691"}, - {file = "pillow-11.2.1-cp313-cp313-win_arm64.whl", hash = "sha256:5119225c622403afb4b44bad4c1ca6c1f98eed79db8d3bc6e4e160fc6339d66c"}, - {file = "pillow-11.2.1-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:8ce2e8411c7aaef53e6bb29fe98f28cd4fbd9a1d9be2eeea434331aac0536b22"}, - {file = "pillow-11.2.1-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:9ee66787e095127116d91dea2143db65c7bb1e232f617aa5957c0d9d2a3f23a7"}, - {file = "pillow-11.2.1-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9622e3b6c1d8b551b6e6f21873bdcc55762b4b2126633014cea1803368a9aa16"}, - {file = "pillow-11.2.1-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:63b5dff3a68f371ea06025a1a6966c9a1e1ee452fc8020c2cd0ea41b83e9037b"}, - {file = "pillow-11.2.1-cp313-cp313t-manylinux_2_28_aarch64.whl", hash = "sha256:31df6e2d3d8fc99f993fd253e97fae451a8db2e7207acf97859732273e108406"}, - {file = "pillow-11.2.1-cp313-cp313t-manylinux_2_28_x86_64.whl", hash = "sha256:062b7a42d672c45a70fa1f8b43d1d38ff76b63421cbbe7f88146b39e8a558d91"}, - {file = "pillow-11.2.1-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:4eb92eca2711ef8be42fd3f67533765d9fd043b8c80db204f16c8ea62ee1a751"}, - {file = "pillow-11.2.1-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:f91ebf30830a48c825590aede79376cb40f110b387c17ee9bd59932c961044f9"}, - {file = "pillow-11.2.1-cp313-cp313t-win32.whl", hash = "sha256:e0b55f27f584ed623221cfe995c912c61606be8513bfa0e07d2c674b4516d9dd"}, - {file = "pillow-11.2.1-cp313-cp313t-win_amd64.whl", hash = "sha256:36d6b82164c39ce5482f649b437382c0fb2395eabc1e2b1702a6deb8ad647d6e"}, - {file = "pillow-11.2.1-cp313-cp313t-win_arm64.whl", hash = "sha256:225c832a13326e34f212d2072982bb1adb210e0cc0b153e688743018c94a2681"}, - {file = "pillow-11.2.1-cp39-cp39-macosx_10_10_x86_64.whl", hash = "sha256:7491cf8a79b8eb867d419648fff2f83cb0b3891c8b36da92cc7f1931d46108c8"}, - {file = "pillow-11.2.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:8b02d8f9cb83c52578a0b4beadba92e37d83a4ef11570a8688bbf43f4ca50909"}, - {file = "pillow-11.2.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:014ca0050c85003620526b0ac1ac53f56fc93af128f7546623cc8e31875ab928"}, - {file = "pillow-11.2.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3692b68c87096ac6308296d96354eddd25f98740c9d2ab54e1549d6c8aea9d79"}, - {file = "pillow-11.2.1-cp39-cp39-manylinux_2_28_aarch64.whl", hash = "sha256:f781dcb0bc9929adc77bad571b8621ecb1e4cdef86e940fe2e5b5ee24fd33b35"}, - {file = "pillow-11.2.1-cp39-cp39-manylinux_2_28_x86_64.whl", hash = "sha256:2b490402c96f907a166615e9a5afacf2519e28295f157ec3a2bb9bd57de638cb"}, - {file = "pillow-11.2.1-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:dd6b20b93b3ccc9c1b597999209e4bc5cf2853f9ee66e3fc9a400a78733ffc9a"}, - {file = "pillow-11.2.1-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:4b835d89c08a6c2ee7781b8dd0a30209a8012b5f09c0a665b65b0eb3560b6f36"}, - {file = "pillow-11.2.1-cp39-cp39-win32.whl", hash = "sha256:b10428b3416d4f9c61f94b494681280be7686bda15898a3a9e08eb66a6d92d67"}, - {file = "pillow-11.2.1-cp39-cp39-win_amd64.whl", hash = "sha256:6ebce70c3f486acf7591a3d73431fa504a4e18a9b97ff27f5f47b7368e4b9dd1"}, - {file = "pillow-11.2.1-cp39-cp39-win_arm64.whl", hash = "sha256:c27476257b2fdcd7872d54cfd119b3a9ce4610fb85c8e32b70b42e3680a29a1e"}, - {file = "pillow-11.2.1-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:9b7b0d4fd2635f54ad82785d56bc0d94f147096493a79985d0ab57aedd563156"}, - {file = "pillow-11.2.1-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:aa442755e31c64037aa7c1cb186e0b369f8416c567381852c63444dd666fb772"}, - {file = "pillow-11.2.1-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f0d3348c95b766f54b76116d53d4cb171b52992a1027e7ca50c81b43b9d9e363"}, - {file = "pillow-11.2.1-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:85d27ea4c889342f7e35f6d56e7e1cb345632ad592e8c51b693d7b7556043ce0"}, - {file = "pillow-11.2.1-pp310-pypy310_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:bf2c33d6791c598142f00c9c4c7d47f6476731c31081331664eb26d6ab583e01"}, - {file = "pillow-11.2.1-pp310-pypy310_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:e616e7154c37669fc1dfc14584f11e284e05d1c650e1c0f972f281c4ccc53193"}, - {file = "pillow-11.2.1-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:39ad2e0f424394e3aebc40168845fee52df1394a4673a6ee512d840d14ab3013"}, - {file = "pillow-11.2.1-pp311-pypy311_pp73-macosx_10_15_x86_64.whl", hash = "sha256:80f1df8dbe9572b4b7abdfa17eb5d78dd620b1d55d9e25f834efdbee872d3aed"}, - {file = "pillow-11.2.1-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:ea926cfbc3957090becbcbbb65ad177161a2ff2ad578b5a6ec9bb1e1cd78753c"}, - {file = "pillow-11.2.1-pp311-pypy311_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:738db0e0941ca0376804d4de6a782c005245264edaa253ffce24e5a15cbdc7bd"}, - {file = "pillow-11.2.1-pp311-pypy311_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9db98ab6565c69082ec9b0d4e40dd9f6181dab0dd236d26f7a50b8b9bfbd5076"}, - {file = "pillow-11.2.1-pp311-pypy311_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:036e53f4170e270ddb8797d4c590e6dd14d28e15c7da375c18978045f7e6c37b"}, - {file = "pillow-11.2.1-pp311-pypy311_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:14f73f7c291279bd65fda51ee87affd7c1e097709f7fdd0188957a16c264601f"}, - {file = "pillow-11.2.1-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:208653868d5c9ecc2b327f9b9ef34e0e42a4cdd172c2988fd81d62d2bc9bc044"}, - {file = "pillow-11.2.1.tar.gz", hash = "sha256:a64dd61998416367b7ef979b73d3a85853ba9bec4c2925f74e588879a58716b6"}, -] - -[package.extras] -docs = ["furo", "olefile", "sphinx (>=8.2)", "sphinx-copybutton", "sphinx-inline-tabs", "sphinxext-opengraph"] -fpx = ["olefile"] -mic = ["olefile"] -test-arrow = ["pyarrow"] -tests = ["check-manifest", "coverage (>=7.4.2)", "defusedxml", "markdown2", "olefile", "packaging", "pyroma", "pytest", "pytest-cov", "pytest-timeout", "trove-classifiers (>=2024.10.12)"] -typing = ["typing-extensions"] -xmp = ["defusedxml"] - -[[package]] -name = "pluggy" -version = "1.6.0" -description = "plugin and hook calling mechanisms for python" -optional = false -python-versions = ">=3.9" -files = [ - {file = "pluggy-1.6.0-py3-none-any.whl", hash = "sha256:e920276dd6813095e9377c0bc5566d94c932c33b27a3e3945d8389c374dd4746"}, - {file = "pluggy-1.6.0.tar.gz", hash = "sha256:7dcc130b76258d33b90f61b658791dede3486c3e6bfb003ee5c9bfb396dd22f3"}, -] - -[package.extras] -dev = ["pre-commit", "tox"] -testing = ["coverage", "pytest", "pytest-benchmark"] - -[[package]] -name = "prompt-toolkit" -version = "3.0.51" -description = "Library for building powerful interactive command lines in Python" -optional = false -python-versions = ">=3.8" -files = [ - {file = "prompt_toolkit-3.0.51-py3-none-any.whl", hash = "sha256:52742911fde84e2d423e2f9a4cf1de7d7ac4e51958f648d9540e0fb8db077b07"}, - {file = "prompt_toolkit-3.0.51.tar.gz", hash = "sha256:931a162e3b27fc90c86f1b48bb1fb2c528c2761475e57c9c06de13311c7b54ed"}, -] - -[package.dependencies] -wcwidth = "*" - -[[package]] -name = "ptyprocess" -version = "0.7.0" -description = "Run a subprocess in a pseudo terminal" -optional = false -python-versions = "*" -files = [ - {file = "ptyprocess-0.7.0-py2.py3-none-any.whl", hash = "sha256:4b41f3967fce3af57cc7e94b888626c18bf37a083e3651ca8feeb66d492fef35"}, - {file = "ptyprocess-0.7.0.tar.gz", hash = "sha256:5c5d0a3b48ceee0b48485e0c26037c0acd7d29765ca3fbb5cb3831d347423220"}, -] - -[[package]] -name = "pure-eval" -version = "0.2.3" -description = "Safely evaluate AST nodes without side effects" -optional = false -python-versions = "*" -files = [ - {file = "pure_eval-0.2.3-py3-none-any.whl", hash = "sha256:1db8e35b67b3d218d818ae653e27f06c3aa420901fa7b081ca98cbedc874e0d0"}, - {file = "pure_eval-0.2.3.tar.gz", hash = "sha256:5f4e983f40564c576c7c8635ae88db5956bb2229d7e9237d03b3c0b0190eaf42"}, -] - -[package.extras] -tests = ["pytest"] - -[[package]] -name = "py-lib3mf" -version = "2.3.1" -description = "A python package for Lib3MF tools" -optional = false -python-versions = ">=3.9" -files = [ - {file = "py_lib3mf-2.3.1-py3-none-any.whl", hash = "sha256:86a870ef386debba9b74683d3a08125a34c153aaa65e967f61677cc5a0a65e24"}, -] - -[[package]] -name = "pygments" -version = "2.19.1" -description = "Pygments is a syntax highlighting package written in Python." -optional = false -python-versions = ">=3.8" -files = [ - {file = "pygments-2.19.1-py3-none-any.whl", hash = "sha256:9ea1544ad55cecf4b8242fab6dd35a93bbce657034b0611ee383099054ab6d8c"}, - {file = "pygments-2.19.1.tar.gz", hash = "sha256:61c16d2a8576dc0649d9f39e089b5f02bcd27fba10d8fb4dcc28173f7a45151f"}, -] - -[package.extras] -windows-terminal = ["colorama (>=0.4.6)"] - -[[package]] -name = "pyparsing" -version = "3.2.3" -description = "pyparsing module - Classes and methods to define and execute parsing grammars" -optional = false -python-versions = ">=3.9" -files = [ - {file = "pyparsing-3.2.3-py3-none-any.whl", hash = "sha256:a749938e02d6fd0b59b356ca504a24982314bb090c383e3cf201c95ef7e2bfcf"}, - {file = "pyparsing-3.2.3.tar.gz", hash = "sha256:b9c13f1ab8b3b542f72e28f634bad4de758ab3ce4546e4301970ad6fa77c38be"}, -] - -[package.extras] -diagrams = ["jinja2", "railroad-diagrams"] - -[[package]] -name = "pytest" -version = "8.3.5" -description = "pytest: simple powerful testing with Python" -optional = false -python-versions = ">=3.8" -files = [ - {file = "pytest-8.3.5-py3-none-any.whl", hash = "sha256:c69214aa47deac29fad6c2a4f590b9c4a9fdb16a403176fe154b79c0b4d4d820"}, - {file = "pytest-8.3.5.tar.gz", hash = "sha256:f4efe70cc14e511565ac476b57c279e12a855b11f48f212af1080ef2263d3845"}, -] - -[package.dependencies] -colorama = {version = "*", markers = "sys_platform == \"win32\""} -exceptiongroup = {version = ">=1.0.0rc8", markers = "python_version < \"3.11\""} -iniconfig = "*" -packaging = "*" -pluggy = ">=1.5,<2" -tomli = {version = ">=1", markers = "python_version < \"3.11\""} - -[package.extras] -dev = ["argcomplete", "attrs (>=19.2)", "hypothesis (>=3.56)", "mock", "pygments (>=2.7.2)", "requests", "setuptools", "xmlschema"] - -[[package]] -name = "python-dateutil" -version = "2.9.0.post0" -description = "Extensions to the standard Python datetime module" -optional = false -python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,>=2.7" -files = [ - {file = "python-dateutil-2.9.0.post0.tar.gz", hash = "sha256:37dd54208da7e1cd875388217d5e00ebd4179249f90fb72437e91a35459a0ad3"}, - {file = "python_dateutil-2.9.0.post0-py2.py3-none-any.whl", hash = "sha256:a8b2bc7bffae282281c8140a97d3aa9c14da0b136dfe83f850eea9a5f7470427"}, -] - -[package.dependencies] -six = ">=1.5" - -[[package]] -name = "scipy" -version = "1.15.2" -description = "Fundamental algorithms for scientific computing in Python" -optional = false -python-versions = ">=3.10" -files = [ - {file = "scipy-1.15.2-cp310-cp310-macosx_10_13_x86_64.whl", hash = "sha256:a2ec871edaa863e8213ea5df811cd600734f6400b4af272e1c011e69401218e9"}, - {file = "scipy-1.15.2-cp310-cp310-macosx_12_0_arm64.whl", hash = "sha256:6f223753c6ea76983af380787611ae1291e3ceb23917393079dcc746ba60cfb5"}, - {file = "scipy-1.15.2-cp310-cp310-macosx_14_0_arm64.whl", hash = "sha256:ecf797d2d798cf7c838c6d98321061eb3e72a74710e6c40540f0e8087e3b499e"}, - {file = "scipy-1.15.2-cp310-cp310-macosx_14_0_x86_64.whl", hash = "sha256:9b18aa747da280664642997e65aab1dd19d0c3d17068a04b3fe34e2559196cb9"}, - {file = "scipy-1.15.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:87994da02e73549dfecaed9e09a4f9d58a045a053865679aeb8d6d43747d4df3"}, - {file = "scipy-1.15.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:69ea6e56d00977f355c0f84eba69877b6df084516c602d93a33812aa04d90a3d"}, - {file = "scipy-1.15.2-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:888307125ea0c4466287191e5606a2c910963405ce9671448ff9c81c53f85f58"}, - {file = "scipy-1.15.2-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:9412f5e408b397ff5641080ed1e798623dbe1ec0d78e72c9eca8992976fa65aa"}, - {file = "scipy-1.15.2-cp310-cp310-win_amd64.whl", hash = "sha256:b5e025e903b4f166ea03b109bb241355b9c42c279ea694d8864d033727205e65"}, - {file = "scipy-1.15.2-cp311-cp311-macosx_10_13_x86_64.whl", hash = "sha256:92233b2df6938147be6fa8824b8136f29a18f016ecde986666be5f4d686a91a4"}, - {file = "scipy-1.15.2-cp311-cp311-macosx_12_0_arm64.whl", hash = "sha256:62ca1ff3eb513e09ed17a5736929429189adf16d2d740f44e53270cc800ecff1"}, - {file = "scipy-1.15.2-cp311-cp311-macosx_14_0_arm64.whl", hash = "sha256:4c6676490ad76d1c2894d77f976144b41bd1a4052107902238047fb6a473e971"}, - {file = "scipy-1.15.2-cp311-cp311-macosx_14_0_x86_64.whl", hash = "sha256:a8bf5cb4a25046ac61d38f8d3c3426ec11ebc350246a4642f2f315fe95bda655"}, - {file = "scipy-1.15.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6a8e34cf4c188b6dd004654f88586d78f95639e48a25dfae9c5e34a6dc34547e"}, - {file = "scipy-1.15.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:28a0d2c2075946346e4408b211240764759e0fabaeb08d871639b5f3b1aca8a0"}, - {file = "scipy-1.15.2-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:42dabaaa798e987c425ed76062794e93a243be8f0f20fff6e7a89f4d61cb3d40"}, - {file = "scipy-1.15.2-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:6f5e296ec63c5da6ba6fa0343ea73fd51b8b3e1a300b0a8cae3ed4b1122c7462"}, - {file = "scipy-1.15.2-cp311-cp311-win_amd64.whl", hash = "sha256:597a0c7008b21c035831c39927406c6181bcf8f60a73f36219b69d010aa04737"}, - {file = "scipy-1.15.2-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:c4697a10da8f8765bb7c83e24a470da5797e37041edfd77fd95ba3811a47c4fd"}, - {file = "scipy-1.15.2-cp312-cp312-macosx_12_0_arm64.whl", hash = "sha256:869269b767d5ee7ea6991ed7e22b3ca1f22de73ab9a49c44bad338b725603301"}, - {file = "scipy-1.15.2-cp312-cp312-macosx_14_0_arm64.whl", hash = "sha256:bad78d580270a4d32470563ea86c6590b465cb98f83d760ff5b0990cb5518a93"}, - {file = "scipy-1.15.2-cp312-cp312-macosx_14_0_x86_64.whl", hash = "sha256:b09ae80010f52efddb15551025f9016c910296cf70adbf03ce2a8704f3a5ad20"}, - {file = "scipy-1.15.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5a6fd6eac1ce74a9f77a7fc724080d507c5812d61e72bd5e4c489b042455865e"}, - {file = "scipy-1.15.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2b871df1fe1a3ba85d90e22742b93584f8d2b8e6124f8372ab15c71b73e428b8"}, - {file = "scipy-1.15.2-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:03205d57a28e18dfd39f0377d5002725bf1f19a46f444108c29bdb246b6c8a11"}, - {file = "scipy-1.15.2-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:601881dfb761311045b03114c5fe718a12634e5608c3b403737ae463c9885d53"}, - {file = "scipy-1.15.2-cp312-cp312-win_amd64.whl", hash = "sha256:e7c68b6a43259ba0aab737237876e5c2c549a031ddb7abc28c7b47f22e202ded"}, - {file = "scipy-1.15.2-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:01edfac9f0798ad6b46d9c4c9ca0e0ad23dbf0b1eb70e96adb9fa7f525eff0bf"}, - {file = "scipy-1.15.2-cp313-cp313-macosx_12_0_arm64.whl", hash = "sha256:08b57a9336b8e79b305a143c3655cc5bdbe6d5ece3378578888d2afbb51c4e37"}, - {file = "scipy-1.15.2-cp313-cp313-macosx_14_0_arm64.whl", hash = "sha256:54c462098484e7466362a9f1672d20888f724911a74c22ae35b61f9c5919183d"}, - {file = "scipy-1.15.2-cp313-cp313-macosx_14_0_x86_64.whl", hash = "sha256:cf72ff559a53a6a6d77bd8eefd12a17995ffa44ad86c77a5df96f533d4e6c6bb"}, - {file = "scipy-1.15.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9de9d1416b3d9e7df9923ab23cd2fe714244af10b763975bea9e4f2e81cebd27"}, - {file = "scipy-1.15.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fb530e4794fc8ea76a4a21ccb67dea33e5e0e60f07fc38a49e821e1eae3b71a0"}, - {file = "scipy-1.15.2-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:5ea7ed46d437fc52350b028b1d44e002646e28f3e8ddc714011aaf87330f2f32"}, - {file = "scipy-1.15.2-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:11e7ad32cf184b74380f43d3c0a706f49358b904fa7d5345f16ddf993609184d"}, - {file = "scipy-1.15.2-cp313-cp313-win_amd64.whl", hash = "sha256:a5080a79dfb9b78b768cebf3c9dcbc7b665c5875793569f48bf0e2b1d7f68f6f"}, - {file = "scipy-1.15.2-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:447ce30cee6a9d5d1379087c9e474628dab3db4a67484be1b7dc3196bfb2fac9"}, - {file = "scipy-1.15.2-cp313-cp313t-macosx_12_0_arm64.whl", hash = "sha256:c90ebe8aaa4397eaefa8455a8182b164a6cc1d59ad53f79943f266d99f68687f"}, - {file = "scipy-1.15.2-cp313-cp313t-macosx_14_0_arm64.whl", hash = "sha256:def751dd08243934c884a3221156d63e15234a3155cf25978b0a668409d45eb6"}, - {file = "scipy-1.15.2-cp313-cp313t-macosx_14_0_x86_64.whl", hash = "sha256:302093e7dfb120e55515936cb55618ee0b895f8bcaf18ff81eca086c17bd80af"}, - {file = "scipy-1.15.2-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7cd5b77413e1855351cdde594eca99c1f4a588c2d63711388b6a1f1c01f62274"}, - {file = "scipy-1.15.2-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6d0194c37037707b2afa7a2f2a924cf7bac3dc292d51b6a925e5fcb89bc5c776"}, - {file = "scipy-1.15.2-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:bae43364d600fdc3ac327db99659dcb79e6e7ecd279a75fe1266669d9a652828"}, - {file = "scipy-1.15.2-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:f031846580d9acccd0044efd1a90e6f4df3a6e12b4b6bd694a7bc03a89892b28"}, - {file = "scipy-1.15.2-cp313-cp313t-win_amd64.whl", hash = "sha256:fe8a9eb875d430d81755472c5ba75e84acc980e4a8f6204d402849234d3017db"}, - {file = "scipy-1.15.2.tar.gz", hash = "sha256:cd58a314d92838f7e6f755c8a2167ead4f27e1fd5c1251fd54289569ef3495ec"}, -] - -[package.dependencies] -numpy = ">=1.23.5,<2.5" - -[package.extras] -dev = ["cython-lint (>=0.12.2)", "doit (>=0.36.0)", "mypy (==1.10.0)", "pycodestyle", "pydevtool", "rich-click", "ruff (>=0.0.292)", "types-psutil", "typing_extensions"] -doc = ["intersphinx_registry", "jupyterlite-pyodide-kernel", "jupyterlite-sphinx (>=0.16.5)", "jupytext", "matplotlib (>=3.5)", "myst-nb", "numpydoc", "pooch", "pydata-sphinx-theme (>=0.15.2)", "sphinx (>=5.0.0,<8.0.0)", "sphinx-copybutton", "sphinx-design (>=0.4.0)"] -test = ["Cython", "array-api-strict (>=2.0,<2.1.1)", "asv", "gmpy2", "hypothesis (>=6.30)", "meson", "mpmath", "ninja", "pooch", "pytest", "pytest-cov", "pytest-timeout", "pytest-xdist", "scikit-umfpack", "threadpoolctl"] - -[[package]] -name = "six" -version = "1.17.0" -description = "Python 2 and 3 compatibility utilities" -optional = false -python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,>=2.7" -files = [ - {file = "six-1.17.0-py2.py3-none-any.whl", hash = "sha256:4721f391ed90541fddacab5acf947aa0d3dc7d27b2e1e8eda2be8970586c3274"}, - {file = "six-1.17.0.tar.gz", hash = "sha256:ff70335d468e7eb6ec65b95b99d3a2836546063f63acc5171de367e834932a81"}, -] - -[[package]] -name = "stack-data" -version = "0.6.3" -description = "Extract data from python stack frames and tracebacks for informative displays" -optional = false -python-versions = "*" -files = [ - {file = "stack_data-0.6.3-py3-none-any.whl", hash = "sha256:d5558e0c25a4cb0853cddad3d77da9891a08cb85dd9f9f91b9f8cd66e511e695"}, - {file = "stack_data-0.6.3.tar.gz", hash = "sha256:836a778de4fec4dcd1dcd89ed8abff8a221f58308462e1c4aa2a3cf30148f0b9"}, -] - -[package.dependencies] -asttokens = ">=2.1.0" -executing = ">=1.2.0" -pure-eval = "*" - -[package.extras] -tests = ["cython", "littleutils", "pygments", "pytest", "typeguard"] - -[[package]] -name = "svgelements" -version = "1.9.6" -description = "Svg Elements Parsing" -optional = false -python-versions = "*" -files = [ - {file = "svgelements-1.9.6-py2.py3-none-any.whl", hash = "sha256:8a5cf2cc066d98e713d5b875b1d6e5eeb9b92e855e835ebd7caab2713ae1dcad"}, - {file = "svgelements-1.9.6.tar.gz", hash = "sha256:7c02ad6404cd3d1771fd50e40fbfc0550b0893933466f86a6eb815f3ba3f37f7"}, -] - -[[package]] -name = "svgpathtools" -version = "1.6.1" -description = "A collection of tools for manipulating and analyzing SVG Path objects and Bezier curves." -optional = false -python-versions = "*" -files = [ - {file = "svgpathtools-1.6.1-py2.py3-none-any.whl", hash = "sha256:39967f9a817b8a12cc6dd1646fc162d522fca6c3fd5f8c94913c15ee4cb3a906"}, - {file = "svgpathtools-1.6.1.tar.gz", hash = "sha256:7054e6de1953e295bf565d535d585695453b09f8db4a2f7c4853348732097a3e"}, -] - -[package.dependencies] -numpy = "*" -scipy = "*" -svgwrite = "*" - -[[package]] -name = "svgwrite" -version = "1.4.3" -description = "A Python library to create SVG drawings." -optional = false -python-versions = ">=3.6" -files = [ - {file = "svgwrite-1.4.3-py3-none-any.whl", hash = "sha256:bb6b2b5450f1edbfa597d924f9ac2dd099e625562e492021d7dd614f65f8a22d"}, - {file = "svgwrite-1.4.3.zip", hash = "sha256:a8fbdfd4443302a6619a7f76bc937fc683daf2628d9b737c891ec08b8ce524c3"}, -] - -[[package]] -name = "tomli" -version = "2.2.1" -description = "A lil' TOML parser" -optional = false -python-versions = ">=3.8" -files = [ - {file = "tomli-2.2.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:678e4fa69e4575eb77d103de3df8a895e1591b48e740211bd1067378c69e8249"}, - {file = "tomli-2.2.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:023aa114dd824ade0100497eb2318602af309e5a55595f76b626d6d9f3b7b0a6"}, - {file = "tomli-2.2.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ece47d672db52ac607a3d9599a9d48dcb2f2f735c6c2d1f34130085bb12b112a"}, - {file = "tomli-2.2.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6972ca9c9cc9f0acaa56a8ca1ff51e7af152a9f87fb64623e31d5c83700080ee"}, - {file = "tomli-2.2.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c954d2250168d28797dd4e3ac5cf812a406cd5a92674ee4c8f123c889786aa8e"}, - {file = "tomli-2.2.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:8dd28b3e155b80f4d54beb40a441d366adcfe740969820caf156c019fb5c7ec4"}, - {file = "tomli-2.2.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:e59e304978767a54663af13c07b3d1af22ddee3bb2fb0618ca1593e4f593a106"}, - {file = "tomli-2.2.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:33580bccab0338d00994d7f16f4c4ec25b776af3ffaac1ed74e0b3fc95e885a8"}, - {file = "tomli-2.2.1-cp311-cp311-win32.whl", hash = "sha256:465af0e0875402f1d226519c9904f37254b3045fc5084697cefb9bdde1ff99ff"}, - {file = "tomli-2.2.1-cp311-cp311-win_amd64.whl", hash = "sha256:2d0f2fdd22b02c6d81637a3c95f8cd77f995846af7414c5c4b8d0545afa1bc4b"}, - {file = "tomli-2.2.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:4a8f6e44de52d5e6c657c9fe83b562f5f4256d8ebbfe4ff922c495620a7f6cea"}, - {file = "tomli-2.2.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:8d57ca8095a641b8237d5b079147646153d22552f1c637fd3ba7f4b0b29167a8"}, - {file = "tomli-2.2.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4e340144ad7ae1533cb897d406382b4b6fede8890a03738ff1683af800d54192"}, - {file = "tomli-2.2.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:db2b95f9de79181805df90bedc5a5ab4c165e6ec3fe99f970d0e302f384ad222"}, - {file = "tomli-2.2.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:40741994320b232529c802f8bc86da4e1aa9f413db394617b9a256ae0f9a7f77"}, - {file = "tomli-2.2.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:400e720fe168c0f8521520190686ef8ef033fb19fc493da09779e592861b78c6"}, - {file = "tomli-2.2.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:02abe224de6ae62c19f090f68da4e27b10af2b93213d36cf44e6e1c5abd19fdd"}, - {file = "tomli-2.2.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:b82ebccc8c8a36f2094e969560a1b836758481f3dc360ce9a3277c65f374285e"}, - {file = "tomli-2.2.1-cp312-cp312-win32.whl", hash = "sha256:889f80ef92701b9dbb224e49ec87c645ce5df3fa2cc548664eb8a25e03127a98"}, - {file = "tomli-2.2.1-cp312-cp312-win_amd64.whl", hash = "sha256:7fc04e92e1d624a4a63c76474610238576942d6b8950a2d7f908a340494e67e4"}, - {file = "tomli-2.2.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:f4039b9cbc3048b2416cc57ab3bda989a6fcf9b36cf8937f01a6e731b64f80d7"}, - {file = "tomli-2.2.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:286f0ca2ffeeb5b9bd4fcc8d6c330534323ec51b2f52da063b11c502da16f30c"}, - {file = "tomli-2.2.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a92ef1a44547e894e2a17d24e7557a5e85a9e1d0048b0b5e7541f76c5032cb13"}, - {file = "tomli-2.2.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9316dc65bed1684c9a98ee68759ceaed29d229e985297003e494aa825ebb0281"}, - {file = "tomli-2.2.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e85e99945e688e32d5a35c1ff38ed0b3f41f43fad8df0bdf79f72b2ba7bc5272"}, - {file = "tomli-2.2.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:ac065718db92ca818f8d6141b5f66369833d4a80a9d74435a268c52bdfa73140"}, - {file = "tomli-2.2.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:d920f33822747519673ee656a4b6ac33e382eca9d331c87770faa3eef562aeb2"}, - {file = "tomli-2.2.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:a198f10c4d1b1375d7687bc25294306e551bf1abfa4eace6650070a5c1ae2744"}, - {file = "tomli-2.2.1-cp313-cp313-win32.whl", hash = "sha256:d3f5614314d758649ab2ab3a62d4f2004c825922f9e370b29416484086b264ec"}, - {file = "tomli-2.2.1-cp313-cp313-win_amd64.whl", hash = "sha256:a38aa0308e754b0e3c67e344754dff64999ff9b513e691d0e786265c93583c69"}, - {file = "tomli-2.2.1-py3-none-any.whl", hash = "sha256:cb55c73c5f4408779d0cf3eef9f762b9c9f147a77de7b258bef0a5628adc85cc"}, - {file = "tomli-2.2.1.tar.gz", hash = "sha256:cd45e1dc79c835ce60f7404ec8119f2eb06d38b1deba146f07ced3bbc44505ff"}, -] - -[[package]] -name = "traitlets" -version = "5.14.3" -description = "Traitlets Python configuration system" -optional = false -python-versions = ">=3.8" -files = [ - {file = "traitlets-5.14.3-py3-none-any.whl", hash = "sha256:b74e89e397b1ed28cc831db7aea759ba6640cb3de13090ca145426688ff1ac4f"}, - {file = "traitlets-5.14.3.tar.gz", hash = "sha256:9ed0579d3502c94b4b3732ac120375cda96f923114522847de4b3bb98b96b6b7"}, -] - -[package.extras] -docs = ["myst-parser", "pydata-sphinx-theme", "sphinx"] -test = ["argcomplete (>=3.0.3)", "mypy (>=1.7.0)", "pre-commit", "pytest (>=7.0,<8.2)", "pytest-mock", "pytest-mypy-testing"] - -[[package]] -name = "trianglesolver" -version = "1.2" -description = "Find all the sides and angles of a triangle, if you know some of the sides and/or angles. (Uses the Law of Sines and Law of Cosines.)" -optional = false -python-versions = "*" -files = [ - {file = "trianglesolver-1.2-py3-none-any.whl", hash = "sha256:aa0903c3708b4e2b496f06d490cae72c6ff6274b00d1edce420fcfa3b2b76682"}, - {file = "trianglesolver-1.2.tar.gz", hash = "sha256:4af18aade579d5c0d64389b3e65aeaf06cff26319762ccd859e3268559a76aea"}, -] - -[[package]] -name = "typing-extensions" -version = "4.13.2" -description = "Backported and Experimental Type Hints for Python 3.8+" -optional = false -python-versions = ">=3.8" -files = [ - {file = "typing_extensions-4.13.2-py3-none-any.whl", hash = "sha256:a439e7c04b49fec3e5d3e2beaa21755cadbbdc391694e28ccdd36ca4a1408f8c"}, - {file = "typing_extensions-4.13.2.tar.gz", hash = "sha256:e6c81219bd689f51865d9e372991c540bda33a0379d5573cddb9a3a23f7caaef"}, -] - -[[package]] -name = "vtk" -version = "9.3.1" -description = "VTK is an open-source toolkit for 3D computer graphics, image processing, and visualization" -optional = false -python-versions = "*" -files = [ - {file = "vtk-9.3.1-cp310-cp310-macosx_10_10_x86_64.whl", hash = "sha256:c41ed344b9cc90ee9dcfc5967815de272985647d0c8e0a57f0e8b4229bc1b0b9"}, - {file = "vtk-9.3.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:84c04327becc4c4dfe1fb04248baa4b5c480f188a9d52f4b912b163d33622442"}, - {file = "vtk-9.3.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:890aee533fc0caca70bd1c8a4026b0d7f877518f237cc976ed4fb509d5f1dd83"}, - {file = "vtk-9.3.1-cp310-cp310-win_amd64.whl", hash = "sha256:b8feed5029486703f4f8f81d8544a30d1788de87dc3396e16a281c343e1ac1cc"}, - {file = "vtk-9.3.1-cp311-cp311-macosx_10_10_x86_64.whl", hash = "sha256:55e2df9e6993b959b482b79a6d68b8d46397b479d69738d41b1501396fcad50c"}, - {file = "vtk-9.3.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:c977486b0e4d87cddb3f2c7c0710d1c86243cdd01286cbd036231143d8eb4f6e"}, - {file = "vtk-9.3.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f8edc04e0f8b6719cfc769e575a777267d667f447d1948c62fa97fb756cd75bb"}, - {file = "vtk-9.3.1-cp311-cp311-win_amd64.whl", hash = "sha256:59cc043f611e3eca2870cc50f27e67852a182857de322415e942bdc133594acd"}, - {file = "vtk-9.3.1-cp312-cp312-macosx_10_10_x86_64.whl", hash = "sha256:05a4b6e387a906e8c8d6844441f9200116e937069fcf81f43e2600f26eb046de"}, - {file = "vtk-9.3.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:bdbefb1aef9599a0a0b8222c9582f26946732a93534e6ec37d4b8e2c524c627e"}, - {file = "vtk-9.3.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f728bb61f43fce850d622ced3b3d51b3116f767685ca4e4e0076f624e2d2307d"}, - {file = "vtk-9.3.1-cp312-cp312-win_amd64.whl", hash = "sha256:685988e09070e06c8605886591698fd42d8225489509b6537a5046cd034cc93e"}, - {file = "vtk-9.3.1-cp36-cp36m-macosx_10_10_x86_64.whl", hash = "sha256:7b8b8b77b903d5515f2fe551807a6b2ee3e7e3cd112174b184a921ab57352f1e"}, - {file = "vtk-9.3.1-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:42684f38d8718b918fe1e4fee4e698d564b6daa16215c21811540c383e47dda2"}, - {file = "vtk-9.3.1-cp36-cp36m-win_amd64.whl", hash = "sha256:4a5de9f424647bc3c02e2d2882401eac8ecd33f1a5f18261dcc69e7a05915c14"}, - {file = "vtk-9.3.1-cp37-cp37m-macosx_10_10_x86_64.whl", hash = "sha256:279da9aee0fda31ee975e97b7b23480b54ea3b12d24ad8260760a3ededc32fad"}, - {file = "vtk-9.3.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:102ac70e8dad0b111347f00ccef39aea1771f4f0381a4b0ff3f1ea6539e500c8"}, - {file = "vtk-9.3.1-cp37-cp37m-win_amd64.whl", hash = "sha256:ee95c741a1ec3dc223c8233b1b59c5735c8249d4a15ee0b6370e7b010188397e"}, - {file = "vtk-9.3.1-cp38-cp38-macosx_10_10_x86_64.whl", hash = "sha256:6adf4b812528a4658667602de8f023400c4381b8166f11b0ea8e0ab83c066539"}, - {file = "vtk-9.3.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:eaf90d0a797b5b7ada3fd0100c072dd146e674a2ccd25411036a4aca676f9101"}, - {file = "vtk-9.3.1-cp38-cp38-win_amd64.whl", hash = "sha256:872e964c38dc1d969aaa29d10a5e56fd0324d61392e21dc044c679797fbdf0ef"}, - {file = "vtk-9.3.1-cp39-cp39-macosx_10_10_x86_64.whl", hash = "sha256:3ae62397364be3a40f89025fa844cbf38b422633c0dff1065d90eec74ca6facb"}, - {file = "vtk-9.3.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:ab96d6923fa37a202874cb8b8b4202d537bd4702bb151638d384e1966d877e3a"}, - {file = "vtk-9.3.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:592b303f96b4cf907df7914bbf8c1f374df382c70c1d0b4fa4bd32ac1f4365ce"}, - {file = "vtk-9.3.1-cp39-cp39-win_amd64.whl", hash = "sha256:6dee68abcd15603ad8ef6cef21fb13e2996d520a16880780abc41eb409dbec0c"}, -] - -[package.dependencies] -matplotlib = ">=2.0.0" - -[package.extras] -numpy = ["numpy (>=1.9)"] -web = ["wslink (>=1.0.4)"] - -[[package]] -name = "wcwidth" -version = "0.2.13" -description = "Measures the displayed width of unicode strings in a terminal" -optional = false -python-versions = "*" -files = [ - {file = "wcwidth-0.2.13-py2.py3-none-any.whl", hash = "sha256:3da69048e4540d84af32131829ff948f1e022c1c6bdb8d6102117aac784f6859"}, - {file = "wcwidth-0.2.13.tar.gz", hash = "sha256:72ea0c06399eb286d978fdedb6923a9eb47e1c486ce63e9b4e64fc18303972b5"}, -] - -[metadata] -lock-version = "2.0" -python-versions = ">=3.10,<3.14" -content-hash = "b32ee01aad884b766e9a671f33b4962d2163c828cb6559a3b2066d8219d46377" diff --git a/pyproject.toml b/pyproject.toml index 2ed94d3..659fd6d 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,38 +1,56 @@ -[tool.poetry] +[project] name = "gfthings" version = "0.8.0" description = "Paul's Gridfinity Things" -authors = ["Paul Bone "] -license = "CC BY-NC-SA 4.0" +authors = [ + { name = "Paul Bone", email = "paul@bone.id.au" }, +] +license = "CC-BY-NC-SA-4.0" readme = "README.md" +requires-python = ">=3.10,<3.15" classifiers = [ "Programming Language :: Python :: 3", "Operating System :: POSIX :: Linux", ] -packages = [{include = "gfthings"}] +dependencies = [ + "build123d>=0.10.0", +] -[tool.poetry.group.test.dependencies] -pytest = "^8.3.5" +[tool.uv.sources] +build123d = [ + { git = "https://github.com/gumyr/build123d.git", branch = "dev", marker = "python_version >= '3.14'" }, +] [project.urls] Homepage = "https://github.com/PaulBone/gfthings" -[tool.poetry.scripts] +[project.scripts] gfpin = "gfthings.gfpin:main" gfbin = "gfthings.gfbin:main" gfbase = "gfthings.gfbase:main" gfedge = "gfthings.gfedge:main" -[tool.poetry.dependencies] -python = ">=3.10,<3.14" -build123d = "^0.9.1" +[dependency-groups] +test = [ + "pytest>=8.3.5,<9.0.0", +] + +[build-system] +requires = ["hatchling"] +build-backend = "hatchling.build" + +[tool.hatch.build.targets.wheel] +packages = ["gfthings"] + +[tool.hatch.build.targets.sdist] +include = [ + "gfthings", + "tests", + "README.md", +] [tool.pytest.ini_options] minversion = "6.0" testpaths = [ "tests", ] - -[build-system] -requires = ["poetry-core"] -build-backend = "poetry.core.masonry.api" From d180abd0e6c8fb38c388cf461788b6d1cabc905b Mon Sep 17 00:00:00 2001 From: bitranox Date: Sun, 26 Apr 2026 11:00:50 +0200 Subject: [PATCH 2/8] gfbin: Fix invalid '\*' escape in --loop help string Python 3.14 raises SyntaxWarning on every run for invalid escape sequences in string literals; the literal asterisk does not need escaping. Co-Authored-By: Claude Opus 4.7 (1M context) --- gfthings/gfbin.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gfthings/gfbin.py b/gfthings/gfbin.py index 9d9a631..3cbb340 100644 --- a/gfthings/gfbin.py +++ b/gfthings/gfbin.py @@ -22,7 +22,7 @@ def main(argv: list[str] | None = None): parser.add_argument( "--loop", help="Generate a number of bins in a loop, bins will be named " + - "bin_\*.step.", + "bin_*.step.", default=False, action="store_true") parser.add_argument( From f610b038b75ca3bca0c248349b54434980965f2b Mon Sep 17 00:00:00 2001 From: bitranox Date: Sun, 26 Apr 2026 11:55:17 +0200 Subject: [PATCH 3/8] gfpin: Fix two latent bugs that broke the .step/.stl export path * Pin.__init__: plate_base_height was used as a number, but became a function (short: bool) -> float when --short support was added in e7296b9. Pass False to preserve the original 2.9mm constant. * gfpin.main: export_step/export_stl were called with `bin` (Python's built-in) instead of the local `pin` object. Together these prevented `gfpin -o file.step|.stl` from ever producing output; only the --vscode path worked. Co-Authored-By: Claude Opus 4.7 (1M context) --- gfthings/Pin.py | 2 +- gfthings/gfpin.py | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/gfthings/Pin.py b/gfthings/Pin.py index 33b5969..e347475 100644 --- a/gfthings/Pin.py +++ b/gfthings/Pin.py @@ -13,7 +13,7 @@ def __init__(self, align: Align | tuple[Align, Align, Align] = None, mode: Mode = Mode.ADD): with BuildPart() as p: - total_height = 3.2 + plate_base_height + 0.5 + total_height = 3.2 + plate_base_height(False) + 0.5 shaft_len = total_height - (magnet_dia - screw_dia)/2 inner_shaft = 1.0 outer_shaft = 1.7 diff --git a/gfthings/gfpin.py b/gfthings/gfpin.py index 2dd4853..e2b1cb8 100644 --- a/gfthings/gfpin.py +++ b/gfthings/gfpin.py @@ -34,9 +34,9 @@ def main(argv: list[str] | None = None): show_object(pin) else: if args.output.endswith(".step"): - export_step(bin, args.output) + export_step(pin, args.output) elif args.output.endswith('.stl'): - export_stl(bin, args.output) + export_stl(pin, args.output) else: print("Unknown output format.") exit(1) From 2eb7a0ba0cfea12e611cc95869711e402be780e9 Mon Sep 17 00:00:00 2001 From: bitranox Date: Sun, 26 Apr 2026 13:01:17 +0200 Subject: [PATCH 4/8] Adapt to build123d dev branch; cover Python 3.13 and 3.14 The released build123d 0.10.0 transitively pulls vtk, which has no Python 3.13 or 3.14 wheel, so a plain install fails on those interpreters. Route 3.13 and 3.14 to build123d's upstream `dev` branch (which uses cadquery-ocp-novtk and skips vtk) via a marker-conditional [tool.uv.sources] entry. 3.10-3.12 keep the released wheel from PyPI. The dev branch has small API drifts from 0.10.0 that the existing gfthings code tripped on; fix them so the test suite passes on 3.12 (released), 3.13 (dev), and 3.14 (dev): * GFProfile: Plane(origin, z_dir) on the dev branch picks a different default x_dir when z_dir is exactly axis-aligned vs nearly so. For non-square paths (depth != width) path%0 is exactly (-1, 0, 0) and the resulting y_dir flips, sending the swept profile along world Y instead of Z and collapsing GFProfile to volume 0. Pin x_dir explicitly. * Bin: when the cavity carve depth equals the box height, the dev branch leaves two coplanar faces at the cavity-floor Z (the actual cavity floor at +/-19.55 and the BinBase top at +/-20.75 with a near-degenerate inner edge ring). `sort_by(Axis.Z)[-2]` picks the wrong one at certain heights, which 1) places inner_front_centre at the bin's outer wall so the scoop overlaps wall material, and 2) makes the floor fillet fail outright. Select the smallest-area XY face at the cavity-floor Z instead. * Bin: a -2e-9 floating-point offset on inner_front_centre.X (from symmetric construction) triggers an OCCT boolean-ADD bug on the dev branch that drops the entire bin solid when the scoop is placed at that point. Snap sub-um X values to zero. * Pin: plate_base_height became a function (short: bool) -> float when --short bases were added; Pin still treated it as a number, raising TypeError on every gfpin invocation. Pass False to preserve the original 2.9mm geometry. * tests/Utils.py: loosen float_eq epsilon from 0.001 to 0.05 mm^3 to accommodate sub-mm^3 OCCT variance between build123d versions for the same input geometry. * README: expand the Python 3.13/3.14 note to explain the vtk wheel gap and that uv is the supported install path on those versions for now. Verified: 21/21 tests pass on Python 3.12 + released 0.10.0, on Python 3.13 + dev branch, and on Python 3.14 + dev branch. Co-Authored-By: Claude Opus 4.7 (1M context) --- README.md | 24 ++++++++++------ gfthings/Bin.py | 65 +++++++++++++++++++++++++++++++++++++++---- gfthings/GFProfile.py | 26 ++++++++++++++++- gfthings/Pin.py | 9 ++++++ pyproject.toml | 6 +++- tests/Utils.py | 7 +++-- 6 files changed, 119 insertions(+), 18 deletions(-) diff --git a/README.md b/README.md index 59f8661..bb0922f 100644 --- a/README.md +++ b/README.md @@ -63,14 +63,22 @@ Clone the repo and let uv manage the environment: uv run --group test pytest -Python 3.14 note: the released `build123d` on PyPI caps at `python<3.14`. -On 3.14+, this project resolves `build123d` from its upstream `dev` branch -via a marker-conditional `[tool.uv.sources]` entry, so `uv sync` / -`uv tool install` from a checkout work; on 3.10–3.13 the regular PyPI -release is used. The `[tool.uv.sources]` block is uv-specific metadata -and is not baked into a built wheel, so the project remains publishable -to PyPI — but plain `pip install gfthings` on 3.14 will fail to resolve -`build123d` until upstream ships a 3.14-compatible release. +Python 3.13 / 3.14 note: the released `build123d` on PyPI (0.10.0) +transitively pulls `vtk`, which has no Python 3.13 or 3.14 wheels, so a +plain install fails on those interpreters. On 3.13 and 3.14 this project +resolves `build123d` from its upstream `dev` branch (which depends on +`cadquery-ocp-novtk` and skips the `vtk` dependency entirely) via a +marker-conditional `[tool.uv.sources]` entry — `uv sync`, `uv tool +install`, and `uvx --from .` all work from a checkout. On 3.10–3.12 the +regular PyPI release is used. + +The `[tool.uv.sources]` block is uv-specific metadata and is not baked +into a built wheel, so the project remains publishable to PyPI. Plain +`pip install gfthings` on 3.13 / 3.14 will still fail (pip ignores +`[tool.uv.sources]` and tries to resolve the released wheel, which then +hits the missing `vtk` wheels) until upstream `build123d` ships a release +that also targets 3.13+ — `uv` is the supported install path on those +versions for now. Copyright (C) Paul Bone Distributed under: CC BY-NC-SA 4.0 diff --git a/gfthings/Bin.py b/gfthings/Bin.py index 8dceee4..9418a91 100644 --- a/gfthings/Bin.py +++ b/gfthings/Bin.py @@ -197,22 +197,75 @@ def __init__(self, width : int, depth : int, inner_height = wall_height if width > 1 or depth > 1 or half_grid: - # For a bin that covers more than one square we need a floor + # For a bin that covers more than one square we need a floor # to connect the squares. inner_height -= wall_thickness extrude(amount=-inner_height, mode=Mode.SUBTRACT) - inner_front_centre = faces().filter_by(Plane.XY) \ - .sort_by(Axis.Z)[-2].edges().filter_by(Axis.X) \ - .sort_by(Axis.Y)[0]@0.5 - + # Pick the cavity-floor face explicitly instead of trusting + # `sort_by(Axis.Z)[-2]`. + # + # Why this is needed on the dev branch of build123d: + # When the cavity carve depth equals the box height (1x1 bins), + # the cavity floor lands exactly on the BinBase top face. The + # dev-branch boolean leaves *two* coplanar faces at that Z: + # - the actual cavity floor (8 edges, bbox ±19.55 = inner + # cavity outline) + # - the BinBase top (16 edges, bbox ±20.75 = bin outline, + # with a near-degenerate duplicate inner edge ring at + # ±20.74 — a topological artifact of the boolean engine) + # `sort_by(Axis.Z)[-2]` picks one or the other depending on + # internal sort stability, which varies with bin height + # (e.g. h=4/h=6 happen to pick the cavity floor; h=5/h=8 pick + # BinBase top). When BinBase top is picked: + # 1. `inner_front_centre` lands at Y=-20.75 (bin outer wall) + # instead of Y=-19.55 (cavity inner wall) — the scoop is + # then positioned 1.2mm too far back, with part of it + # embedded in the wall material and only the rest adding + # new volume. + # 2. The fillet on the BinBase-top face fails outright + # because of the degenerate inner edge ring. + # Selecting the smallest-area XY face at the cavity-floor Z + # reliably resolves to the actual cavity floor in every case. + xy_floors = faces().filter_by(Plane.XY).sort_by(Axis.Z) + cavity_z = xy_floors[-2].center().Z + cavity_floor = min( + (f for f in xy_floors if abs(f.center().Z - cavity_z) < 1e-6), + key=lambda f: f.bounding_box().size.X * f.bounding_box().size.Y, + ) + inner_front_centre = cavity_floor.edges().filter_by(Axis.X).sort_by(Axis.Y)[0]@0.5 + # Snap a near-zero X coordinate to exactly 0. + # + # The midpoint of the front-most X-axis edge can land at + # X = -2e-9 due to floating-point drift in the symmetrically + # constructed cavity outline. That exact offset, when fed into + # `Locations(...)` for the subsequent Scoop placement, triggers + # an OCCT boolean-ADD bug on the dev branch: the resulting + # solid is just the scoop alone (the entire bin gets dropped). + # Other tiny X values (0, +1e-9, -1e-12) all work fine — only + # this specific magnitude/sign combination breaks. Snapping any + # sub-µm X value to zero sidesteps it without affecting the + # geometry the user actually sees. + if abs(inner_front_centre.X) < 1e-6: + inner_front_centre = Vector(0, inner_front_centre.Y, inner_front_centre.Z) + # This fillet rounds off the floor of the bin nicely. inner_fillet_rad=7.5/2 - wall_thickness if inner_height == wall_height: # It is it can also prevent the wall-base corner from being too thin. inner_fillet_rad = max(inner_fillet_rad, wall_thickness) if inner_fillet_rad: - fillet(faces().filter_by(Plane.XY).sort_by(Axis.Z)[-2].edges(), radius=inner_fillet_rad) + # Re-resolve the cavity floor here: the divisions block above + # may have added internal walls that change the face stack + # (their tops show up as additional XY faces). Same selection + # rule as before — smallest-area face at the cavity-floor Z. + xy_floors = faces().filter_by(Plane.XY).sort_by(Axis.Z) + cavity_z = xy_floors[-2].center().Z + cavity_floor = min( + (f for f in xy_floors if abs(f.center().Z - cavity_z) < 1e-6), + key=lambda f: f.bounding_box().size.X * f.bounding_box().size.Y, + ) + fillet(cavity_floor.edges(), radius=inner_fillet_rad) if divisions > 1: dividors = divisions-1 dividor_space = inner_width / divisions diff --git a/gfthings/GFProfile.py b/gfthings/GFProfile.py index 7580d2d..c231911 100644 --- a/gfthings/GFProfile.py +++ b/gfthings/GFProfile.py @@ -35,7 +35,31 @@ def __init__(self, width : float = 1, # build123d can't handle a line with no length. if base == 0: base = 0.01 - with BuildSketch(Plane(origin=path@0, z_dir=path%0).rotated((-90, 0, 0))): + # Pin the sketch plane orientation explicitly so the swept profile + # ends up with its local +Y aligned with world +Z (the gridfinity + # base height direction). + # + # Why this is needed on the dev branch of build123d: + # `Plane(origin, z_dir)` auto-computes x_dir/y_dir from z_dir. + # The auto-computation takes a different code path when z_dir is + # *exactly* axis-aligned vs. only nearly so. For non-square paths + # (e.g. width=1, depth=2) `path%0` returns exactly (-1, 0, 0) + # and the resulting plane has y_dir = (0, -1, 0); for square + # paths floating-point noise puts z_dir slightly off-axis and + # the plane has y_dir = (0, 0, 1). The polyline is drawn with + # its "up" direction along local +Y, so when y_dir flips the + # sweep ends up along world Y instead of Z, the SUBTRACT misses + # the extruded box, and GFProfile collapses to volume 0. + # The previous `.rotated((-90, 0, 0))` worked around the 0.10.0 + # convention; the dev branch flipped the convention so we now + # pin x_dir directly. + # + # x_dir = world_Z × z_dir gives a vector lying in the world XY + # plane perpendicular to the path tangent. y_dir = z_dir × x_dir + # then comes out as world +Z, which is what the polyline expects. + sweep_z = path%0 + sweep_x = Vector(0, 0, 1).cross(sweep_z).normalized() + with BuildSketch(Plane(origin=path@0, x_dir=sweep_x, z_dir=sweep_z)): with BuildLine(): Polyline( (0, support), diff --git a/gfthings/Pin.py b/gfthings/Pin.py index e347475..1a56088 100644 --- a/gfthings/Pin.py +++ b/gfthings/Pin.py @@ -13,6 +13,15 @@ def __init__(self, align: Align | tuple[Align, Align, Align] = None, mode: Mode = Mode.ADD): with BuildPart() as p: + # `plate_base_height` was originally a constant (2.9) and became + # a function `(short: bool) -> float` when --short bases were + # added (build123d commit e7296b9). Pin was not migrated at the + # time, so `3.2 + plate_base_height + 0.5` raised + # `TypeError: unsupported operand type(s) for +: 'float' and + # 'function'` on every invocation of `gfpin`. Pins are physical + # parts independent of base height and the original code targeted + # the 2.9mm (non-short) base, so we explicitly pass False here to + # preserve the historical geometry. total_height = 3.2 + plate_base_height(False) + 0.5 shaft_len = total_height - (magnet_dia - screw_dia)/2 inner_shaft = 1.0 diff --git a/pyproject.toml b/pyproject.toml index 659fd6d..c3f90a9 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -17,8 +17,12 @@ dependencies = [ ] [tool.uv.sources] +# Released build123d 0.10.0 transitively pulls vtk, which has no wheel for +# Python 3.13+ — so for 3.13 and 3.14 we resolve build123d from its +# upstream dev branch (which depends on cadquery-ocp-novtk and skips vtk +# entirely). Python 3.10–3.12 keep using the released wheel from PyPI. build123d = [ - { git = "https://github.com/gumyr/build123d.git", branch = "dev", marker = "python_version >= '3.14'" }, + { git = "https://github.com/gumyr/build123d.git", branch = "dev", marker = "python_version >= '3.13'" }, ] [project.urls] diff --git a/tests/Utils.py b/tests/Utils.py index c0f8dc8..88c6eea 100644 --- a/tests/Utils.py +++ b/tests/Utils.py @@ -2,8 +2,11 @@ # CC BY-NC-SA 4.0 # Comparing floating-point numbers should always be done with some error -# margin. +# margin. The tolerance accommodates small variance between build123d +# versions (notably between the released 0.10.0 and the upstream `dev` +# branch used on Python 3.14); OCCT boolean operations can shift volumes +# by ~0.05 mm^3 between versions for the same input geometry. def float_eq(exp, got): - epsilon = 0.001 + epsilon = 0.05 assert got < exp + epsilon assert got > exp - epsilon From 8606e71cb95f1da19db3904b3f54247c716b9bff Mon Sep 17 00:00:00 2001 From: bitranox Date: Sun, 26 Apr 2026 13:19:19 +0200 Subject: [PATCH 5/8] Add --no-magnet to gfbase and gfbin Skips the magnet pocket without removing screw functionality. For gfbase, the counterbore (screw + magnet recess) becomes a plain through-hole at screw_rad so the base can still be screwed down. For gfbin, both refined side slots and unrefined bottom holes are skipped (bins have no screw holes, so the result is a plain base profile). Plumbed through ScrewSupport/BaseSquare/BaseGrid in Base.py and BinBase/ Bin/FunkyBin/HalfWallBin in Bin.py via a new `magnet : bool = True` parameter on each. Default is True, preserving existing behavior; the test suite continues to pass on Python 3.12 + released build123d 0.10.0 and Python 3.13 / 3.14 + dev branch. CLI: gfbase ... --no-magnet gfbin ... --no-magnet Co-Authored-By: Claude Opus 4.7 (1M context) --- gfthings/Base.py | 24 ++++++++++++++++++++---- gfthings/Bin.py | 15 +++++++++++++-- gfthings/gfbase.py | 7 +++++++ gfthings/gfbin.py | 12 ++++++++++-- 4 files changed, 50 insertions(+), 8 deletions(-) diff --git a/gfthings/Base.py b/gfthings/Base.py index 297dd9d..0b2735a 100644 --- a/gfthings/Base.py +++ b/gfthings/Base.py @@ -14,6 +14,7 @@ def __init__(self, magnet_depth : float = 2, screw_rad : float = 2, counter_sink : bool = True, + magnet : bool = True, margin : float = 2, rotation: tuple[float, float, float] | Rotation = (0, 0, 0), align: Align | tuple[Align, Align, Align] = None, @@ -29,7 +30,11 @@ def __init__(self, with Locations(faces().filter_by(Plane.XY).sort_by(Axis.Z)[-1]): offset = screw_offset - len/2 with Locations((offset, offset)): - if counter_sink: + if not magnet: + # Skip the magnet pocket — plain through-hole at + # screw size so the base can still be screwed down. + Hole(screw_rad) + elif counter_sink: CounterSinkHole(screw_rad, magnet_rad) else: CounterBoreHole(screw_rad, magnet_rad, magnet_depth) @@ -84,6 +89,7 @@ def __init__(self, magnet_depth : float = 2, screw_rad : float = 2, counter_sink : bool = False, + magnet : bool = True, screw_hole_count : int = 2, short : bool = False, rotation: tuple[float, float, float] | Rotation = (0, 0, 0), @@ -100,8 +106,9 @@ def __init__(self, magnet_depth=magnet_depth, screw_rad=screw_rad, counter_sink=counter_sink, + magnet=magnet, align=(Align.MIN, Align.MIN, Align.MIN)) - + with Locations( vertices().group_by(Axis.Z)[0].group_by(Axis.X)[-1]. sort_by(Axis.Y)[-1]): @@ -109,6 +116,7 @@ def __init__(self, magnet_depth=magnet_depth, screw_rad=screw_rad, counter_sink=counter_sink, + magnet=magnet, align=(Align.MIN, Align.MIN, Align.MIN), rotation=(0, 0, 180)) @@ -120,6 +128,7 @@ def __init__(self, magnet_depth=magnet_depth, screw_rad=screw_rad, counter_sink=counter_sink, + magnet=magnet, align=(Align.MIN, Align.MIN, Align.MIN), rotation=(0, 0, 90)) with Locations( @@ -129,6 +138,7 @@ def __init__(self, magnet_depth=magnet_depth, screw_rad=screw_rad, counter_sink=counter_sink, + magnet=magnet, align=(Align.MIN, Align.MIN, Align.MIN), rotation=(0, 0, 270)) @@ -149,6 +159,7 @@ def __init__(self, x_num, y_num, magnet_depth : float = 2, screw_rad : float = 2, counter_sink : bool = False, + magnet : bool = True, screw_hole_count : int = 2, screw_hole_pattern_drawer : bool = False, short : bool = False, @@ -163,17 +174,19 @@ def __init__(self, x_num, y_num, screw_rad=screw_rad, screw_hole_count=screw_hole_count, counter_sink=counter_sink, + magnet=magnet, short=short) if screw_hole_pattern_drawer and x_num > 2 and y_num > 2: with Locations(faces().filter_by(Plane.XY).sort_by(Axis.Z)[0].center()): - with Locations((-(bin_size * x_num)/2+bin_size, - -(bin_size * y_num)/2+bin_size, + with Locations((-(bin_size * x_num)/2+bin_size, + -(bin_size * y_num)/2+bin_size, 0)): ScrewSupport(magnet_rad=magnet_rad, magnet_depth=magnet_depth, screw_rad=screw_rad, counter_sink=counter_sink, + magnet=magnet, align=(Align.MIN, Align.MIN, Align.MIN)) with Locations((-(bin_size * x_num)/2+bin_size, (bin_size * y_num)/2-bin_size, @@ -182,6 +195,7 @@ def __init__(self, x_num, y_num, magnet_depth=magnet_depth, screw_rad=screw_rad, counter_sink=counter_sink, + magnet=magnet, rotation=(0, 0, 270), align=(Align.MIN, Align.MIN, Align.MIN)) with Locations(((bin_size * x_num)/2-bin_size, @@ -191,6 +205,7 @@ def __init__(self, x_num, y_num, magnet_depth=magnet_depth, screw_rad=screw_rad, counter_sink=counter_sink, + magnet=magnet, rotation=(0, 0, 180), align=(Align.MIN, Align.MIN, Align.MIN)) with Locations(((bin_size * x_num)/2-bin_size, @@ -200,6 +215,7 @@ def __init__(self, x_num, y_num, magnet_depth=magnet_depth, screw_rad=screw_rad, counter_sink=counter_sink, + magnet=magnet, rotation=(0, 0, 90), align=(Align.MIN, Align.MIN, Align.MIN)) diff --git a/gfthings/Bin.py b/gfthings/Bin.py index 9418a91..2c1abbe 100644 --- a/gfthings/Bin.py +++ b/gfthings/Bin.py @@ -42,13 +42,18 @@ def __init__(self, refined: bool, magnet_dia: float, magnet_depth: float, + magnet: bool = True, bin_size: float = 42, rotation: tuple[float, float, float] | Rotation = (0, 0, 0), align: Align | tuple[Align, Align, Align] = None, mode: Mode = Mode.ADD): with BuildPart() as p: GFProfileBin(bin_size=bin_size) - if refined: + if not magnet: + # Skip both refined slots and unrefined holes — bins don't + # have screw holes, so --no-magnet means a plain base. + pass + elif refined: with Locations(faces().filter_by(Plane.XY).sort_by(Axis.Z)[0]): with PolarLocations(0, 4): with Locations((35.6/2-4.8+magnet_dia/2, 35.6/2+0.8+2.15)): @@ -61,7 +66,7 @@ def __init__(self, with Locations(faces().filter_by(Plane.XY).sort_by(Axis.Z)[0]): magnet_offset = 35.6/2 - 4.8 with GridLocations(magnet_offset*2, magnet_offset*2, 2, 2): - Hole(magnet_dia/2, magnet_depth) + Hole(magnet_dia/2, magnet_depth) super().__init__(p.part, rotation, align, mode) @@ -155,6 +160,7 @@ def __init__(self, width : int, depth : int, scoop_rad : float, divisions : int = 1, refined : bool = True, + magnet : bool = True, magnet_dia : float = 6, magnet_depth : float = 2, half_grid : bool = False, @@ -184,6 +190,7 @@ def __init__(self, width : int, depth : int, with GridLocations(bs, bs, int(w), int(d)): BinBase(refined=refined, bin_size = 42 if not half_grid else 21, + magnet=magnet, magnet_dia=magnet_dia, magnet_depth=magnet_depth, align=(Align.CENTER, Align.CENTER, Align.MAX)) @@ -321,6 +328,7 @@ def __init__(self, array : list, height_units : int, refined : bool = True, + magnet : bool = True, magnet_dia : float = 6, magnet_depth : float = 2, wall_thickness : float = 1.2, @@ -363,6 +371,7 @@ def __init__(self, (y - depth/2 + 1/2)*bin_size, -wall_height/2)): BinBase(refined=refined, + magnet=magnet, magnet_depth=magnet_depth, magnet_dia=magnet_dia, align=(Align.CENTER, Align.CENTER, Align.MAX)) @@ -381,6 +390,7 @@ def __init__(self, x, y, z, divisions : int = 1, lip : bool = True, refined : bool = True, + magnet : bool = True, half_grid : bool = False, wall_thickness : float = 1.2, magnet_dia : float = 6, @@ -391,6 +401,7 @@ def __init__(self, x, y, z, divisions=divisions, lip=lip, refined=refined, + magnet=magnet, magnet_dia=magnet_dia, magnet_depth=magnet_depth, scoop_rad=0, diff --git a/gfthings/gfbase.py b/gfthings/gfbase.py index a6558f8..9b3e038 100644 --- a/gfthings/gfbase.py +++ b/gfthings/gfbase.py @@ -72,6 +72,12 @@ def main(argv: list[str] | None = None): "--short", help="Make the short variant, doesn't support screw holes", action="store_true") + parser.add_argument( + "--no-magnet", + help="Skip the magnet pocket. Screw holes are kept as plain " + + "through holes at --screw-diameter so the base can still be " + + "fastened down.", + action="store_true") args = parser.parse_args(argv) @@ -109,6 +115,7 @@ def make_variant(file_base, obj): magnet_rad=magnet_rad, magnet_depth=magnet_depth, counter_sink=counter_sink, + magnet=not args.no_magnet, screw_hole_count=screw_hole_count, screw_hole_pattern_drawer=args.screw_hole_pattern_drawer, short=args.short) diff --git a/gfthings/gfbin.py b/gfthings/gfbin.py index 3cbb340..03a256a 100644 --- a/gfthings/gfbin.py +++ b/gfthings/gfbin.py @@ -70,12 +70,17 @@ def main(argv: list[str] | None = None): parser.add_argument( "--unrefined", help="Use unrefined magnet holes. " + - "Gridfinity Refind " + + "Gridfinity Refind " + "https://www.printables.com/model/413761-gridfinity-refined " + "has improved magnet holes that don't require glue, " + "If for some reason you don't want superiour magnet holes then " + "--unrefind will switch to plain circular holes", action="store_true") + parser.add_argument( + "--no-magnet", + help="Skip magnet holes entirely. The bin's base profile is " + + "produced without any magnet pockets or refined magnet slots.", + action="store_true") parser.add_argument( "--magnet-dia", help="Magnet hole diameter or width for 'refined' holes. " + @@ -184,6 +189,7 @@ def main(argv: list[str] | None = None): funky_expr = eval(args.funky) bin = FunkyBin(list(reversed(funky_expr)), z, refined=not args.unrefined, + magnet=not args.no_magnet, magnet_dia=args.magnet_dia, magnet_depth=args.magnet_height, half_grid=args.half_grid, @@ -193,9 +199,10 @@ def main(argv: list[str] | None = None): divisions=divisions, lip=not args.no_lip, refined=not args.unrefined, + magnet=not args.no_magnet, magnet_dia=args.magnet_dia, magnet_depth=args.magnet_height, - half_grid=args.half_grid, + half_grid=args.half_grid, wall_thickness=args.wall_thickness) else: @@ -204,6 +211,7 @@ def main(argv: list[str] | None = None): label=not args.no_label, lip=not args.no_lip, refined=not args.unrefined, + magnet=not args.no_magnet, magnet_dia=args.magnet_dia, magnet_depth=args.magnet_height, half_grid=args.half_grid, From b4222a2b7a13f84d4d54da17a042a8ba82bdcc42 Mon Sep 17 00:00:00 2001 From: bitranox Date: Sun, 26 Apr 2026 13:24:32 +0200 Subject: [PATCH 6/8] Add tests for --no-magnet on gfbase and gfbin MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cover the new `magnet=False` paths: * test_base.py: 2x2 base, 1x1 base, 2x2 base with 4 holes (counterbore branch in ScrewSupport replaced by a plain through-hole at screw_rad). * test_bins.py: 1x1x4 bin (refined slots skipped) plus an unrefined variant — both produce the same volume because both magnet branches are short-circuited when magnet=False. Reference volumes verified to match within 1e-6 between Python 3.12 + released build123d 0.10.0 and Python 3.13 / 3.14 + dev branch. Total: 26/26 tests pass on all three Python+build123d combos. Co-Authored-By: Claude Opus 4.7 (1M context) --- tests/test_base.py | 42 ++++++++++++++++++++++++++++++++++++++++++ tests/test_bins.py | 17 +++++++++++++++++ 2 files changed, 59 insertions(+) diff --git a/tests/test_base.py b/tests/test_base.py index 94b292a..6e76b3a 100644 --- a/tests/test_base.py +++ b/tests/test_base.py @@ -81,3 +81,45 @@ def test_screw_holes(): screw_hole_pattern_drawer=False, corner_screw_hole_count=0) float_eq(9623.029985813218, base.volume) + +# --- --no-magnet variants ------------------------------------------------- +# `magnet=False` skips the counterbore that combines screw + magnet recess +# and replaces it with a plain through-hole at screw_rad. The base is +# slightly heavier than the equivalent magneted base because the magnet +# pocket volume is no longer subtracted. + +def test_2x2_base_no_magnet(): + base = Base.BaseGrid(2, 2, + magnet_rad=3.1, + magnet_depth=2, + screw_rad=2, + counter_sink=False, + magnet=False, + screw_hole_count=2, + screw_hole_pattern_drawer=False, + corner_screw_hole_count=0) + float_eq(9705.824064564506, base.volume) + +def test_1x1_base_no_magnet(): + base = Base.BaseGrid(1, 1, + magnet_rad=3.1, + magnet_depth=2, + screw_rad=2, + counter_sink=False, + magnet=False, + screw_hole_count=2, + screw_hole_pattern_drawer=False, + corner_screw_hole_count=0) + float_eq(2454.3226457171168, base.volume) + +def test_4_holes_no_magnet(): + base = Base.BaseGrid(2, 2, + magnet_rad=3.1, + magnet_depth=2, + screw_rad=2, + counter_sink=False, + magnet=False, + screw_hole_count=4, + screw_hole_pattern_drawer=False, + corner_screw_hole_count=0) + float_eq(11548.322125649871, base.volume) diff --git a/tests/test_bins.py b/tests/test_bins.py index 3cf86b0..119ef1a 100644 --- a/tests/test_bins.py +++ b/tests/test_bins.py @@ -51,3 +51,20 @@ def test_nolip(): bin = Bin.Bin(1, 1, 4, scoop_rad=0, divisions=1, label=False, lip=False) float_eq(10817.207884007077, bin.volume) + +# --- --no-magnet variants ------------------------------------------------- +# `magnet=False` skips both the refined side-insertable slots and the +# unrefined bottom holes. Bins have no screw holes, so the result is a +# plain base profile — slightly heavier than the magneted bin because no +# magnet apertures are subtracted. + +def test_simple_bin_no_magnet(): + bin = Bin.Bin(1, 1, 4, scoop_rad=0, divisions=1, label=False, magnet=False) + float_eq(12809.059717125214, bin.volume) + +def test_simple_bin_no_magnet_unrefined(): + # Same volume as the refined case: when magnet=False both branches + # are skipped, so refined / unrefined make no difference. + bin = Bin.Bin(1, 1, 4, scoop_rad=0, divisions=1, label=False, + magnet=False, refined=False) + float_eq(12809.059717125214, bin.volume) From 2f6c522a7d4d9b1403f390f329f9df9a3b5c61d8 Mon Sep 17 00:00:00 2001 From: bitranox Date: Sun, 26 Apr 2026 13:34:03 +0200 Subject: [PATCH 7/8] Add recipe launcher scripts for each tool (.sh and .ps1) Each tool gets a paired Bash and PowerShell launcher (gfbin, gfbase, gfedge, gfpin). The scripts declare the CLI parameters as variables at the top, auto-derive an output filename from those parameters (so a tweak like NoMagnet=true produces a uniquely-named sibling without clobbering anything), and call `uvx --from ` for you. The .sh and .ps1 versions take exactly the same variable names and produce identical CAD output, so a recipe is portable between Linux / macOS and Windows. Both pin GfthingsSource to bitranox/gfthings@py314compat so 3.13 / 3.14 users get the build123d dev branch automatically. The .ps1 versions were added in an earlier commit; this commit adds the matching .sh versions and a "Recipe scripts" section to the README explaining the workflow (copy + rename, edit variables, run). Co-Authored-By: Claude Opus 4.7 (1M context) --- gfbase.ps1 | 59 ++++++++++++++++++++++++++++++++++++++++ gfbase.sh | 63 ++++++++++++++++++++++++++++++++++++++++++ gfbin.ps1 | 76 +++++++++++++++++++++++++++++++++++++++++++++++++++ gfbin.sh | 80 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ gfedge.ps1 | 38 ++++++++++++++++++++++++++ gfedge.sh | 42 ++++++++++++++++++++++++++++ gfpin.ps1 | 27 ++++++++++++++++++ gfpin.sh | 27 ++++++++++++++++++ 8 files changed, 412 insertions(+) create mode 100644 gfbase.ps1 create mode 100644 gfbase.sh create mode 100644 gfbin.ps1 create mode 100644 gfbin.sh create mode 100644 gfedge.ps1 create mode 100644 gfedge.sh create mode 100644 gfpin.ps1 create mode 100644 gfpin.sh diff --git a/gfbase.ps1 b/gfbase.ps1 new file mode 100644 index 0000000..40edd06 --- /dev/null +++ b/gfbase.ps1 @@ -0,0 +1,59 @@ +# gfbase recipe -- edit the variables below, then run: .\gfbase.ps1 +# Copy this file and rename it (e.g. drawer-base-4x3.ps1) to save a recipe. +# Re-running the same script regenerates the same object. + +$GfthingsSource = 'git+https://github.com/bitranox/gfthings.git@py314compat' + +# ---- Dimensions ---- +$X = 4 # gridfinity units across +$Y = 4 # gridfinity units deep + +# ---- Holes ---- +$ScrewDiameter = 4 # mm +$MagnetDiameter = 6.2 # mm (or countersink diameter) +$MagnetDepth = 2 # mm +$ScrewHoleCount = 2 # 0, 2, or 4 per grid square +$ScrewHolePatternDrawer = $false # add 4 extra screw holes in drawer pattern +$NoMagnet = $false # skip magnet pocket (screw holes kept as plain holes) + +# ---- Variant ---- +$Short = $false # short variant (no screw holes) + +# ---- Output ---- +$Format = 'step' # 'step' or 'stl' +$Loop = $false # batch-generate variants +$VsCode = 0 # >0 = run in vscode_ocp mode on that port (no file produced) + +# ---------- output filename (auto-derived from params) ---------- +$tags = @() +if ($ScrewHolePatternDrawer) { $tags += 'drawer' } +if ($NoMagnet) { $tags += 'nomagnet' } +if ($Short) { $tags += 'short' } +$tagSuffix = if ($tags) { '_' + ($tags -join '_') } else { '' } +$basename = "base_${X}x${Y}_screw${ScrewDiameter}_mag${MagnetDiameter}x${MagnetDepth}_holes${ScrewHoleCount}${tagSuffix}.${Format}" +$Output = Join-Path $PSScriptRoot $basename +# To override, set $Output = 'mycustomname.step' here. + +# ---------- build args ---------- +$cliArgs = @( + '-x', $X, '-y', $Y, + '--screw-diameter', $ScrewDiameter, + '--magnet-diameter', $MagnetDiameter, + '--magnet-depth', $MagnetDepth, + '--screw-hole-count', $ScrewHoleCount, + '-o', $Output +) +if ($ScrewHolePatternDrawer) { $cliArgs += '--screw-hole-pattern-drawer' } +if ($NoMagnet) { $cliArgs += '--no-magnet' } +if ($Short) { $cliArgs += '--short' } +if ($Loop) { $cliArgs += '--loop' } +if ($VsCode -gt 0) { $cliArgs += @('--vscode', $VsCode) } + +# ---------- invoke ---------- +$inv = [System.Globalization.CultureInfo]::InvariantCulture +$displayArgs = $cliArgs | ForEach-Object { + if ($_ -is [double] -or $_ -is [single] -or $_ -is [decimal]) { ([double]$_).ToString($inv) } else { "$_" } +} +Write-Host "uvx --from $GfthingsSource gfbase $($displayArgs -join ' ')" +& uvx --from $GfthingsSource gfbase @cliArgs +if ($LASTEXITCODE -eq 0) { Write-Host "Wrote: $Output" } diff --git a/gfbase.sh b/gfbase.sh new file mode 100644 index 0000000..dc98171 --- /dev/null +++ b/gfbase.sh @@ -0,0 +1,63 @@ +#!/usr/bin/env bash +# gfbase recipe -- edit the variables below, then run: ./gfbase.sh +# Copy this file and rename it (e.g. drawer-base-4x3.sh) to save a recipe. +# Re-running the same script regenerates the same object. + +set -euo pipefail + +GfthingsSource='git+https://github.com/bitranox/gfthings.git@py314compat' + +# ---- Dimensions ---- +X=4 # gridfinity units across +Y=4 # gridfinity units deep + +# ---- Holes ---- +ScrewDiameter=4 # mm +MagnetDiameter=6.2 # mm (or countersink diameter) +MagnetDepth=2 # mm +ScrewHoleCount=2 # 0, 2, or 4 per grid square +ScrewHolePatternDrawer=false # add 4 extra screw holes in drawer pattern +NoMagnet=false # skip magnet pocket (screw holes kept as plain holes) + +# ---- Variant ---- +Short=false # short variant (no screw holes) + +# ---- Output ---- +Format='step' # 'step' or 'stl' +Loop=false # batch-generate variants +VsCode=0 # >0 = run in vscode_ocp mode on that port (no file produced) + +# ---------- output filename (auto-derived from params) ---------- +ScriptDir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +tags=() +[[ "$ScrewHolePatternDrawer" == 'true' ]] && tags+=( 'drawer' ) +[[ "$NoMagnet" == 'true' ]] && tags+=( 'nomagnet' ) +[[ "$Short" == 'true' ]] && tags+=( 'short' ) +if (( ${#tags[@]} )); then + tagSuffix="_$(IFS=_; echo "${tags[*]}")" +else + tagSuffix='' +fi +basename="base_${X}x${Y}_screw${ScrewDiameter}_mag${MagnetDiameter}x${MagnetDepth}_holes${ScrewHoleCount}${tagSuffix}.${Format}" +Output="${ScriptDir}/${basename}" +# To override, set Output='mycustomname.step' here. + +# ---------- build args ---------- +cliArgs=( + '-x' "$X" '-y' "$Y" + '--screw-diameter' "$ScrewDiameter" + '--magnet-diameter' "$MagnetDiameter" + '--magnet-depth' "$MagnetDepth" + '--screw-hole-count' "$ScrewHoleCount" + '-o' "$Output" +) +[[ "$ScrewHolePatternDrawer" == 'true' ]] && cliArgs+=( '--screw-hole-pattern-drawer' ) +[[ "$NoMagnet" == 'true' ]] && cliArgs+=( '--no-magnet' ) +[[ "$Short" == 'true' ]] && cliArgs+=( '--short' ) +[[ "$Loop" == 'true' ]] && cliArgs+=( '--loop' ) +if [[ "$VsCode" -gt 0 ]]; then cliArgs+=( '--vscode' "$VsCode" ); fi + +# ---------- invoke ---------- +echo "uvx --from $GfthingsSource gfbase ${cliArgs[*]}" +uvx --from "$GfthingsSource" gfbase "${cliArgs[@]}" +echo "Wrote: $Output" diff --git a/gfbin.ps1 b/gfbin.ps1 new file mode 100644 index 0000000..3463d8a --- /dev/null +++ b/gfbin.ps1 @@ -0,0 +1,76 @@ +# gfbin recipe -- edit the variables below, then run: .\gfbin.ps1 +# Copy this file and rename it (e.g. screws-bin-2x2x4.ps1) to save a recipe. +# Re-running the same script regenerates the same object. + +$GfthingsSource = 'git+https://github.com/bitranox/gfthings.git@py314compat' + +# ---- Bin dimensions (gridfinity units) ---- +$X = 1 # width +$Y = 1 # depth +$Z = 4 # height (min 3) + +# ---- Interior ---- +$Scoop = 12.5 # scoop radius in mm (0 = none) +$Divisions = 1 # internal divisions (3+ per unit not recommended) +$NoLabel = $false # omit label shelf +$NoLip = $false # omit stacking lip +$HalfWall = $false # half walls (link bins end-to-end) + +# ---- Magnets / base ---- +$NoMagnet = $false # skip magnet holes entirely +$Unrefined = $false # circular holes instead of refined slots +$MagnetDia = 6 # mm +$MagnetHeight = 2 # mm +$HalfGrid = $false # 21mm units (may break magnet holes) +$WallThickness = 1.2 # mm + +# ---- Special ---- +$Funky = '' # python expr for non-rectangular shape (ignores X/Y/divisions); '' to skip + +# ---- Output ---- +$Format = 'step' # 'step' or 'stl' +$Loop = $false # batch-generate variants (names as bin_*.step) +$VsCode = 0 # >0 = run in vscode_ocp mode on that port (no file produced) + +# ---------- output filename (auto-derived from params) ---------- +$tags = @() +if ($NoLabel) { $tags += 'nolabel' } +if ($NoLip) { $tags += 'nolip' } +if ($HalfWall) { $tags += 'halfwall' } +if ($NoMagnet) { $tags += 'nomagnet' } +if ($Unrefined) { $tags += 'unrefined' } +if ($HalfGrid) { $tags += 'halfgrid' } +if ($Funky) { $tags += "funky-$Funky" } +$tagSuffix = if ($tags) { '_' + ($tags -join '_') } else { '' } +$basename = "bin_${X}x${Y}x${Z}_div${Divisions}_scoop${Scoop}_mag${MagnetDia}x${MagnetHeight}_wall${WallThickness}${tagSuffix}.${Format}" +$Output = Join-Path $PSScriptRoot $basename +# To override, set $Output = 'mycustomname.step' here. + +# ---------- build args ---------- +$cliArgs = @( + '-x', $X, '-y', $Y, '-z', $Z, + '--scoop', $Scoop, + '--divisions', $Divisions, + '--magnet-dia', $MagnetDia, + '--magnet-height', $MagnetHeight, + '--wall-thickness', $WallThickness, + '-o', $Output +) +if ($NoLabel) { $cliArgs += '--no-label' } +if ($NoLip) { $cliArgs += '--no-lip' } +if ($HalfWall) { $cliArgs += '--half-wall' } +if ($NoMagnet) { $cliArgs += '--no-magnet' } +if ($Unrefined) { $cliArgs += '--unrefined' } +if ($HalfGrid) { $cliArgs += '--half-grid' } +if ($Loop) { $cliArgs += '--loop' } +if ($Funky) { $cliArgs += @('--funky', $Funky) } +if ($VsCode -gt 0) { $cliArgs += @('--vscode', $VsCode) } + +# ---------- invoke ---------- +$inv = [System.Globalization.CultureInfo]::InvariantCulture +$displayArgs = $cliArgs | ForEach-Object { + if ($_ -is [double] -or $_ -is [single] -or $_ -is [decimal]) { ([double]$_).ToString($inv) } else { "$_" } +} +Write-Host "uvx --from $GfthingsSource gfbin $($displayArgs -join ' ')" +& uvx --from $GfthingsSource gfbin @cliArgs +if ($LASTEXITCODE -eq 0) { Write-Host "Wrote: $Output" } diff --git a/gfbin.sh b/gfbin.sh new file mode 100644 index 0000000..a37f30f --- /dev/null +++ b/gfbin.sh @@ -0,0 +1,80 @@ +#!/usr/bin/env bash +# gfbin recipe -- edit the variables below, then run: ./gfbin.sh +# Copy this file and rename it (e.g. screws-bin-2x2x4.sh) to save a recipe. +# Re-running the same script regenerates the same object. + +set -euo pipefail + +GfthingsSource='git+https://github.com/bitranox/gfthings.git@py314compat' + +# ---- Bin dimensions (gridfinity units) ---- +X=1 # width +Y=1 # depth +Z=4 # height (min 3) + +# ---- Interior ---- +Scoop=12.5 # scoop radius in mm (0 = none) +Divisions=1 # internal divisions (3+ per unit not recommended) +NoLabel=false # omit label shelf +NoLip=false # omit stacking lip +HalfWall=false # half walls (link bins end-to-end) + +# ---- Magnets / base ---- +NoMagnet=false # skip magnet holes entirely +Unrefined=false # circular holes instead of refined slots +MagnetDia=6 # mm +MagnetHeight=2 # mm +HalfGrid=false # 21mm units (may break magnet holes) +WallThickness=1.2 # mm + +# ---- Special ---- +Funky='' # python expr for non-rectangular shape (ignores X/Y/divisions); '' to skip + +# ---- Output ---- +Format='step' # 'step' or 'stl' +Loop=false # batch-generate variants (names as bin_*.step) +VsCode=0 # >0 = run in vscode_ocp mode on that port (no file produced) + +# ---------- output filename (auto-derived from params) ---------- +ScriptDir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +tags=() +[[ "$NoLabel" == 'true' ]] && tags+=( 'nolabel' ) +[[ "$NoLip" == 'true' ]] && tags+=( 'nolip' ) +[[ "$HalfWall" == 'true' ]] && tags+=( 'halfwall' ) +[[ "$NoMagnet" == 'true' ]] && tags+=( 'nomagnet' ) +[[ "$Unrefined" == 'true' ]] && tags+=( 'unrefined' ) +[[ "$HalfGrid" == 'true' ]] && tags+=( 'halfgrid' ) +[[ -n "$Funky" ]] && tags+=( "funky-${Funky}" ) +if (( ${#tags[@]} )); then + tagSuffix="_$(IFS=_; echo "${tags[*]}")" +else + tagSuffix='' +fi +basename="bin_${X}x${Y}x${Z}_div${Divisions}_scoop${Scoop}_mag${MagnetDia}x${MagnetHeight}_wall${WallThickness}${tagSuffix}.${Format}" +Output="${ScriptDir}/${basename}" +# To override, set Output='mycustomname.step' here. + +# ---------- build args ---------- +cliArgs=( + '-x' "$X" '-y' "$Y" '-z' "$Z" + '--scoop' "$Scoop" + '--divisions' "$Divisions" + '--magnet-dia' "$MagnetDia" + '--magnet-height' "$MagnetHeight" + '--wall-thickness' "$WallThickness" + '-o' "$Output" +) +[[ "$NoLabel" == 'true' ]] && cliArgs+=( '--no-label' ) +[[ "$NoLip" == 'true' ]] && cliArgs+=( '--no-lip' ) +[[ "$HalfWall" == 'true' ]] && cliArgs+=( '--half-wall' ) +[[ "$NoMagnet" == 'true' ]] && cliArgs+=( '--no-magnet' ) +[[ "$Unrefined" == 'true' ]] && cliArgs+=( '--unrefined' ) +[[ "$HalfGrid" == 'true' ]] && cliArgs+=( '--half-grid' ) +[[ "$Loop" == 'true' ]] && cliArgs+=( '--loop' ) +[[ -n "$Funky" ]] && cliArgs+=( '--funky' "$Funky" ) +if [[ "$VsCode" -gt 0 ]]; then cliArgs+=( '--vscode' "$VsCode" ); fi + +# ---------- invoke ---------- +echo "uvx --from $GfthingsSource gfbin ${cliArgs[*]}" +uvx --from "$GfthingsSource" gfbin "${cliArgs[@]}" +echo "Wrote: $Output" diff --git a/gfedge.ps1 b/gfedge.ps1 new file mode 100644 index 0000000..bd0a27d --- /dev/null +++ b/gfedge.ps1 @@ -0,0 +1,38 @@ +# gfedge recipe -- edit the variables below, then run: .\gfedge.ps1 +# Copy this file and rename it (e.g. drawer-edge-4x14.ps1) to save a recipe. +# Re-running the same script regenerates the same object. + +$GfthingsSource = 'git+https://github.com/bitranox/gfthings.git@py314compat' + +# ---- Dimensions ---- +$X = 4 # gridfinity units across +$Y = 16 # depth in mm +$Short = $false # short variant (no screw holes) + +# ---- Output ---- +$Format = 'step' # 'step' or 'stl' +$Loop = $false # batch-generate variants +$VsCode = 0 # >0 = run in vscode_ocp mode on that port (no file produced) + +# ---------- output filename (auto-derived from params) ---------- +$tags = @() +if ($Short) { $tags += 'short' } +$tagSuffix = if ($tags) { '_' + ($tags -join '_') } else { '' } +$basename = "edge_${X}x${Y}${tagSuffix}.${Format}" +$Output = Join-Path $PSScriptRoot $basename +# To override, set $Output = 'mycustomname.step' here. + +# ---------- build args ---------- +$cliArgs = @('-x', $X, '-y', $Y, '-o', $Output) +if ($Short) { $cliArgs += '--short' } +if ($Loop) { $cliArgs += '--loop' } +if ($VsCode -gt 0) { $cliArgs += @('--vscode', $VsCode) } + +# ---------- invoke ---------- +$inv = [System.Globalization.CultureInfo]::InvariantCulture +$displayArgs = $cliArgs | ForEach-Object { + if ($_ -is [double] -or $_ -is [single] -or $_ -is [decimal]) { ([double]$_).ToString($inv) } else { "$_" } +} +Write-Host "uvx --from $GfthingsSource gfedge $($displayArgs -join ' ')" +& uvx --from $GfthingsSource gfedge @cliArgs +if ($LASTEXITCODE -eq 0) { Write-Host "Wrote: $Output" } diff --git a/gfedge.sh b/gfedge.sh new file mode 100644 index 0000000..ccec960 --- /dev/null +++ b/gfedge.sh @@ -0,0 +1,42 @@ +#!/usr/bin/env bash +# gfedge recipe -- edit the variables below, then run: ./gfedge.sh +# Copy this file and rename it (e.g. drawer-edge-4x14.sh) to save a recipe. +# Re-running the same script regenerates the same object. + +set -euo pipefail + +GfthingsSource='git+https://github.com/bitranox/gfthings.git@py314compat' + +# ---- Dimensions ---- +X=4 # gridfinity units across +Y=16 # depth in mm +Short=false # short variant (no screw holes) + +# ---- Output ---- +Format='step' # 'step' or 'stl' +Loop=false # batch-generate variants +VsCode=0 # >0 = run in vscode_ocp mode on that port (no file produced) + +# ---------- output filename (auto-derived from params) ---------- +ScriptDir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +tags=() +[[ "$Short" == 'true' ]] && tags+=( 'short' ) +if (( ${#tags[@]} )); then + tagSuffix="_$(IFS=_; echo "${tags[*]}")" +else + tagSuffix='' +fi +basename="edge_${X}x${Y}${tagSuffix}.${Format}" +Output="${ScriptDir}/${basename}" +# To override, set Output='mycustomname.step' here. + +# ---------- build args ---------- +cliArgs=( '-x' "$X" '-y' "$Y" '-o' "$Output" ) +[[ "$Short" == 'true' ]] && cliArgs+=( '--short' ) +[[ "$Loop" == 'true' ]] && cliArgs+=( '--loop' ) +if [[ "$VsCode" -gt 0 ]]; then cliArgs+=( '--vscode' "$VsCode" ); fi + +# ---------- invoke ---------- +echo "uvx --from $GfthingsSource gfedge ${cliArgs[*]}" +uvx --from "$GfthingsSource" gfedge "${cliArgs[@]}" +echo "Wrote: $Output" diff --git a/gfpin.ps1 b/gfpin.ps1 new file mode 100644 index 0000000..d251a66 --- /dev/null +++ b/gfpin.ps1 @@ -0,0 +1,27 @@ +# gfpin recipe -- edit the variables below, then run: .\gfpin.ps1 +# Copy this file and rename it (e.g. drawer-pin.ps1) to save a recipe. +# Re-running the same script regenerates the same object. + +$GfthingsSource = 'git+https://github.com/bitranox/gfthings.git@py314compat' + +# ---- Output ---- +$Format = 'step' # 'step' or 'stl' +$VsCode = 0 # >0 = run in vscode_ocp mode on that port (no file produced) + +# ---------- output filename (auto-derived) ---------- +$basename = "pin.${Format}" +$Output = Join-Path $PSScriptRoot $basename +# To override, set $Output = 'mycustomname.step' here. + +# ---------- build args ---------- +$cliArgs = @('-o', $Output) +if ($VsCode -gt 0) { $cliArgs += @('--vscode', $VsCode) } + +# ---------- invoke ---------- +$inv = [System.Globalization.CultureInfo]::InvariantCulture +$displayArgs = $cliArgs | ForEach-Object { + if ($_ -is [double] -or $_ -is [single] -or $_ -is [decimal]) { ([double]$_).ToString($inv) } else { "$_" } +} +Write-Host "uvx --from $GfthingsSource gfpin $($displayArgs -join ' ')" +& uvx --from $GfthingsSource gfpin @cliArgs +if ($LASTEXITCODE -eq 0) { Write-Host "Wrote: $Output" } diff --git a/gfpin.sh b/gfpin.sh new file mode 100644 index 0000000..db46cde --- /dev/null +++ b/gfpin.sh @@ -0,0 +1,27 @@ +#!/usr/bin/env bash +# gfpin recipe -- edit the variables below, then run: ./gfpin.sh +# Copy this file and rename it (e.g. drawer-pin.sh) to save a recipe. +# Re-running the same script regenerates the same object. + +set -euo pipefail + +GfthingsSource='git+https://github.com/bitranox/gfthings.git@py314compat' + +# ---- Output ---- +Format='step' # 'step' or 'stl' +VsCode=0 # >0 = run in vscode_ocp mode on that port (no file produced) + +# ---------- output filename (auto-derived) ---------- +ScriptDir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +basename="pin.${Format}" +Output="${ScriptDir}/${basename}" +# To override, set Output='mycustomname.step' here. + +# ---------- build args ---------- +cliArgs=( '-o' "$Output" ) +if [[ "$VsCode" -gt 0 ]]; then cliArgs+=( '--vscode' "$VsCode" ); fi + +# ---------- invoke ---------- +echo "uvx --from $GfthingsSource gfpin ${cliArgs[*]}" +uvx --from "$GfthingsSource" gfpin "${cliArgs[@]}" +echo "Wrote: $Output" From 7c2c66434d37748eebc2fc6b50a1e514a67ae913 Mon Sep 17 00:00:00 2001 From: bitranox Date: Sun, 26 Apr 2026 13:37:33 +0200 Subject: [PATCH 8/8] Recipe scripts: README section + post-merge URL note MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * README: add the "Recipe scripts" section explaining the copy-and-edit workflow, that the .sh and .ps1 versions take the same variables and produce identical CAD output, and listing the four covered tools. (This section was prepared with the previous commit but didn't make it into the index — folding it in here.) * All 8 launcher scripts: add a NOTE above the `GfthingsSource` line pointing out that the URL targets the bitranox fork's `py314compat` branch only because the Python 3.13 / 3.14 compatibility work is not yet upstream (PaulBone/gfthings#9). Once that PR is merged, the URL should be replaced with `git+https://github.com/PaulBone/gfthings.git` or, after a PyPI release that supports 3.13/3.14, just `gfthings`. Co-Authored-By: Claude Opus 4.7 (1M context) --- README.md | 46 ++++++++++++++++++++++++++++++++++++++++++++++ gfbase.ps1 | 6 ++++++ gfbase.sh | 6 ++++++ gfbin.ps1 | 6 ++++++ gfbin.sh | 6 ++++++ gfedge.ps1 | 6 ++++++ gfedge.sh | 6 ++++++ gfpin.ps1 | 6 ++++++ gfpin.sh | 6 ++++++ 9 files changed, 94 insertions(+) diff --git a/README.md b/README.md index bb0922f..07ac5cb 100644 --- a/README.md +++ b/README.md @@ -50,6 +50,52 @@ things out or for CI: The `--from gfthings` is required because the command names (`gfbin`, etc.) don't match the package name. +Recipe scripts (gfbin.sh / .ps1, gfbase.sh / .ps1, gfedge.sh / .ps1, gfpin.sh / .ps1) +------------------------------------------------------------------------------------- + +For day-to-day printing it's awkward to remember the exact CLI flags +that produced a particular part. The repo ships a pair of *recipe* +launcher scripts for every tool — one Bash version (`*.sh`, for Linux +and macOS) and one PowerShell version (`*.ps1`, for Windows) — that +each declare the parameters as variables at the top, auto-derive the +output filename from those variables, and then call `uvx --from ` for you. + +Workflow: + +1. Copy the recipe for the tool you want, renaming it to whatever + describes the part — e.g. + + cp gfbin.sh screws-bin-2x2x4.sh # Linux / macOS + Copy-Item gfbin.ps1 .\screws-bin-2x2x4.ps1 # Windows + +2. Edit the variables at the top (dimensions, scoop, magnet flags, + output format, etc.) to taste. + +3. Run it: + + ./screws-bin-2x2x4.sh # Linux / macOS + .\screws-bin-2x2x4.ps1 # Windows + +The script prints the equivalent `uvx ... gfbin ...` invocation it's +about to run, then writes a `.step` (or `.stl`) file next to the +script. The filename is built from the parameters — toggling +`NoMagnet=true` adds `_nomagnet` to the name, switching to `Format=stl` +flips the extension, etc. — so the same recipe always regenerates the +same file, and small tweaks produce uniquely-named siblings without +clobbering anything. + +The Bash and PowerShell versions take exactly the same variables, so +recipes are portable: a `.sh` and `.ps1` with the same values produce +identical CAD output. Both pin `GfthingsSource` to the +`bitranox/gfthings@py314compat` branch so 3.13 / 3.14 users get the +upstream `build123d` `dev` branch automatically (see the Python 3.13 / +3.14 note below); change that line if you want to track a different +fork or branch. + +Tools covered: `gfbin` (bins), `gfbase` (bases), `gfedge` (drawer-edge +fillers), `gfpin` (the small attaching pin). + Develop gfthings ---------------- diff --git a/gfbase.ps1 b/gfbase.ps1 index 40edd06..8470095 100644 --- a/gfbase.ps1 +++ b/gfbase.ps1 @@ -2,6 +2,12 @@ # Copy this file and rename it (e.g. drawer-base-4x3.ps1) to save a recipe. # Re-running the same script regenerates the same object. +# NOTE: this URL points at the bitranox fork's `py314compat` branch, which +# carries the not-yet-upstreamed Python 3.13 / 3.14 compatibility patches +# (PaulBone/gfthings#9). Once that PR is merged upstream, replace the +# value below with one of: +# $GfthingsSource = 'git+https://github.com/PaulBone/gfthings.git' # or @main +# $GfthingsSource = 'gfthings' # once a PyPI release ships $GfthingsSource = 'git+https://github.com/bitranox/gfthings.git@py314compat' # ---- Dimensions ---- diff --git a/gfbase.sh b/gfbase.sh index dc98171..a5912a8 100644 --- a/gfbase.sh +++ b/gfbase.sh @@ -5,6 +5,12 @@ set -euo pipefail +# NOTE: this URL points at the bitranox fork's `py314compat` branch, which +# carries the not-yet-upstreamed Python 3.13 / 3.14 compatibility patches +# (PaulBone/gfthings#9). Once that PR is merged upstream, replace the +# value below with one of: +# GfthingsSource='git+https://github.com/PaulBone/gfthings.git' # or @main +# GfthingsSource='gfthings' # once a PyPI release ships GfthingsSource='git+https://github.com/bitranox/gfthings.git@py314compat' # ---- Dimensions ---- diff --git a/gfbin.ps1 b/gfbin.ps1 index 3463d8a..c441241 100644 --- a/gfbin.ps1 +++ b/gfbin.ps1 @@ -2,6 +2,12 @@ # Copy this file and rename it (e.g. screws-bin-2x2x4.ps1) to save a recipe. # Re-running the same script regenerates the same object. +# NOTE: this URL points at the bitranox fork's `py314compat` branch, which +# carries the not-yet-upstreamed Python 3.13 / 3.14 compatibility patches +# (PaulBone/gfthings#9). Once that PR is merged upstream, replace the +# value below with one of: +# $GfthingsSource = 'git+https://github.com/PaulBone/gfthings.git' # or @main +# $GfthingsSource = 'gfthings' # once a PyPI release ships $GfthingsSource = 'git+https://github.com/bitranox/gfthings.git@py314compat' # ---- Bin dimensions (gridfinity units) ---- diff --git a/gfbin.sh b/gfbin.sh index a37f30f..c3de8c4 100644 --- a/gfbin.sh +++ b/gfbin.sh @@ -5,6 +5,12 @@ set -euo pipefail +# NOTE: this URL points at the bitranox fork's `py314compat` branch, which +# carries the not-yet-upstreamed Python 3.13 / 3.14 compatibility patches +# (PaulBone/gfthings#9). Once that PR is merged upstream, replace the +# value below with one of: +# GfthingsSource='git+https://github.com/PaulBone/gfthings.git' # or @main +# GfthingsSource='gfthings' # once a PyPI release ships GfthingsSource='git+https://github.com/bitranox/gfthings.git@py314compat' # ---- Bin dimensions (gridfinity units) ---- diff --git a/gfedge.ps1 b/gfedge.ps1 index bd0a27d..1db10ff 100644 --- a/gfedge.ps1 +++ b/gfedge.ps1 @@ -2,6 +2,12 @@ # Copy this file and rename it (e.g. drawer-edge-4x14.ps1) to save a recipe. # Re-running the same script regenerates the same object. +# NOTE: this URL points at the bitranox fork's `py314compat` branch, which +# carries the not-yet-upstreamed Python 3.13 / 3.14 compatibility patches +# (PaulBone/gfthings#9). Once that PR is merged upstream, replace the +# value below with one of: +# $GfthingsSource = 'git+https://github.com/PaulBone/gfthings.git' # or @main +# $GfthingsSource = 'gfthings' # once a PyPI release ships $GfthingsSource = 'git+https://github.com/bitranox/gfthings.git@py314compat' # ---- Dimensions ---- diff --git a/gfedge.sh b/gfedge.sh index ccec960..1ea757f 100644 --- a/gfedge.sh +++ b/gfedge.sh @@ -5,6 +5,12 @@ set -euo pipefail +# NOTE: this URL points at the bitranox fork's `py314compat` branch, which +# carries the not-yet-upstreamed Python 3.13 / 3.14 compatibility patches +# (PaulBone/gfthings#9). Once that PR is merged upstream, replace the +# value below with one of: +# GfthingsSource='git+https://github.com/PaulBone/gfthings.git' # or @main +# GfthingsSource='gfthings' # once a PyPI release ships GfthingsSource='git+https://github.com/bitranox/gfthings.git@py314compat' # ---- Dimensions ---- diff --git a/gfpin.ps1 b/gfpin.ps1 index d251a66..de0f460 100644 --- a/gfpin.ps1 +++ b/gfpin.ps1 @@ -2,6 +2,12 @@ # Copy this file and rename it (e.g. drawer-pin.ps1) to save a recipe. # Re-running the same script regenerates the same object. +# NOTE: this URL points at the bitranox fork's `py314compat` branch, which +# carries the not-yet-upstreamed Python 3.13 / 3.14 compatibility patches +# (PaulBone/gfthings#9). Once that PR is merged upstream, replace the +# value below with one of: +# $GfthingsSource = 'git+https://github.com/PaulBone/gfthings.git' # or @main +# $GfthingsSource = 'gfthings' # once a PyPI release ships $GfthingsSource = 'git+https://github.com/bitranox/gfthings.git@py314compat' # ---- Output ---- diff --git a/gfpin.sh b/gfpin.sh index db46cde..e20ee76 100644 --- a/gfpin.sh +++ b/gfpin.sh @@ -5,6 +5,12 @@ set -euo pipefail +# NOTE: this URL points at the bitranox fork's `py314compat` branch, which +# carries the not-yet-upstreamed Python 3.13 / 3.14 compatibility patches +# (PaulBone/gfthings#9). Once that PR is merged upstream, replace the +# value below with one of: +# GfthingsSource='git+https://github.com/PaulBone/gfthings.git' # or @main +# GfthingsSource='gfthings' # once a PyPI release ships GfthingsSource='git+https://github.com/bitranox/gfthings.git@py314compat' # ---- Output ----