diff --git a/.gitattributes b/.gitattributes
new file mode 100644
index 00000000..887a2c18
--- /dev/null
+++ b/.gitattributes
@@ -0,0 +1,2 @@
+# SCM syntax highlighting & preventing 3-way merges
+pixi.lock merge=binary linguist-language=YAML linguist-generated=true
diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md
new file mode 100644
index 00000000..042fd93e
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/bug_report.md
@@ -0,0 +1,37 @@
+---
+name: Bug report
+about: Something is broken in the build or packaging pipeline
+title: "fix: "
+labels: bug
+assignees: ""
+---
+
+## Environment
+
+- **OS / Platform**:
+- **Python version**:
+- **ITK version / branch**:
+- **Script / entry point used**:
+
+## Steps to Reproduce
+
+
+## Expected Behavior
+
+
+
+## Actual Behavior
+
+
+
+
+Log output
+
+```
+```
+
+
+
+## Additional Context
+
+
diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml
new file mode 100644
index 00000000..07191d51
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/config.yml
@@ -0,0 +1,8 @@
+blank_issues_enabled: true
+contact_links:
+ - name: ITK Discourse (questions & support)
+ url: https://discourse.itk.org
+ about: For build questions or general ITK support, please use the ITK Discourse forum.
+ - name: ITK Documentation
+ url: https://itkpythonpackage.readthedocs.io
+ about: Check the docs before filing an issue.
diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md
new file mode 100644
index 00000000..f54cb07a
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/feature_request.md
@@ -0,0 +1,23 @@
+---
+name: Feature request
+about: Suggest a new capability or improvement to the build/packaging pipeline
+title: "feat: "
+labels: enhancement
+assignees: ""
+---
+
+## Problem / Motivation
+
+
+
+## Proposed Solution
+
+
+
+## Alternatives Considered
+
+
+
+## Additional Context
+
+
diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md
new file mode 100644
index 00000000..fa1ada99
--- /dev/null
+++ b/.github/pull_request_template.md
@@ -0,0 +1,30 @@
+## Summary
+
+
+
+## Type of Change
+
+- [ ] Bug fix
+- [ ] New feature / enhancement
+- [ ] Refactor / cleanup
+- [ ] Docs / CI only
+
+## Checklist
+
+- [ ] Pre-commit hooks pass locally (`pre-commit run --all-files`)
+- [ ] Tested wheel build on affected platform(s) (Linux / macOS / Windows)
+- [ ] Docs updated if behavior changed (`docs/`)
+- [ ] Commit messages follow Conventional Commits (`feat:`, `fix:`, `chore:`, etc.)
+
+## Platform(s) Tested
+
+
+- [ ] Linux x86_64 (manylinux)
+- [ ] Linux aarch64 (manylinux)
+- [ ] macOS x86_64
+- [ ] macOS arm64
+- [ ] Windows x86_64
+
+## Related Issues
+
+
diff --git a/.github/workflows/docs.yaml b/.github/workflows/docs.yaml
new file mode 100644
index 00000000..133a0df4
--- /dev/null
+++ b/.github/workflows/docs.yaml
@@ -0,0 +1,31 @@
+name: docs
+
+on:
+ pull_request:
+ paths:
+ - "docs/**"
+ - ".readthedocs.yml"
+ push:
+ branches: [main]
+ paths:
+ - "docs/**"
+ - ".readthedocs.yml"
+
+jobs:
+ build:
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v4
+ - uses: actions/setup-python@v5
+ with:
+ python-version: "3.11"
+ - name: Install dependencies
+ run: pip install -r docs/requirements-docs.txt
+ - name: Build docs
+ run: sphinx-build -W --keep-going -b html docs docs/_build/html
+ - uses: actions/upload-artifact@v4
+ if: always()
+ with:
+ name: docs-html
+ path: docs/_build/html
+ retention-days: 7
diff --git a/.github/workflows/pre-commit.yaml b/.github/workflows/pre-commit.yaml
new file mode 100644
index 00000000..f1356482
--- /dev/null
+++ b/.github/workflows/pre-commit.yaml
@@ -0,0 +1,16 @@
+name: pre-commit
+
+on:
+ pull_request:
+ push:
+ branches: [main]
+
+jobs:
+ pre-commit:
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v4
+ - uses: actions/setup-python@v5
+ with:
+ python-version: "3.11"
+ - uses: pre-commit/action@v3.0.1
diff --git a/.gitignore b/.gitignore
index cffba1ed..c49bb1de 100644
--- a/.gitignore
+++ b/.gitignore
@@ -43,7 +43,6 @@ lib
lib64
MANIFEST
oneTBB-prefix/
-pyproject.toml
# Installer logs
pip-log.txt
@@ -73,3 +72,10 @@ docs/_build
# IDE junk
.idea/*
*.swp
+/itkVersion.py
+# PyPI credentials
+.pypirc
+
+# pixi environments
+.pixi/*
+!.pixi/config.toml
diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml
new file mode 100644
index 00000000..8e3166d1
--- /dev/null
+++ b/.pre-commit-config.yaml
@@ -0,0 +1,82 @@
+# Pre-commit configuration for ITKPythonPackage
+# Run `pre-commit install` to install git hooks locally
+# Run `pre-commit run --all-files` to check all files
+# Run `pre-commit autoupdate` to update hook versions
+
+# Exclude generated/vendored directories from all hooks
+exclude: ^(\.pixi|build|pixi.lock|docs)/
+
+repos:
+ # General file hygiene
+ - repo: https://github.com/pre-commit/pre-commit-hooks
+ rev: v5.0.0
+ hooks:
+ - id: trailing-whitespace
+ stages: [pre-commit]
+ - id: end-of-file-fixer
+ stages: [pre-commit]
+ - id: check-yaml
+ stages: [pre-commit]
+ - id: check-toml
+ stages: [pre-commit]
+ - id: check-merge-conflict
+ stages: [pre-commit]
+ - id: check-added-large-files
+ args: [--maxkb=500]
+ stages: [pre-commit]
+ # Enforce LF line endings everywhere except Windows PowerShell scripts
+ - id: mixed-line-ending
+ args: [--fix=lf]
+ exclude: \.ps1$
+ stages: [pre-commit]
+
+ # Python: formatting
+ - repo: https://github.com/psf/black
+ rev: 24.10.0
+ hooks:
+ - id: black
+ stages: [pre-commit]
+
+ # Python: linting + import sorting
+ - repo: https://github.com/astral-sh/ruff-pre-commit
+ rev: v0.8.6
+ hooks:
+ - id: ruff
+ args: [--fix]
+ stages: [pre-commit]
+
+ # Shell: linting
+ - repo: https://github.com/shellcheck-py/shellcheck-py
+ rev: v0.10.0.1
+ hooks:
+ - id: shellcheck
+ stages: [pre-commit]
+
+ # Shell: formatting
+ - repo: https://github.com/scop/pre-commit-shfmt
+ rev: v3.12.0-2
+ hooks:
+ - id: shfmt
+ args: [-i, "2", -w]
+ stages: [pre-commit]
+
+ # TOML: formatting
+ - repo: https://github.com/ComPWA/taplo-pre-commit
+ rev: v0.9.3
+ hooks:
+ - id: taplo-format
+ stages: [pre-commit]
+
+ # ITK commit message hooks (matching ITK/Utilities/Hooks/)
+ - repo: local
+ hooks:
+ - id: local-prepare-commit-msg
+ name: 'local prepare-commit-msg'
+ entry: 'Utilities/Hooks/prepare-commit-msg'
+ language: system
+ stages: [prepare-commit-msg]
+ - id: kw-commit-msg
+ name: 'kw commit-msg'
+ entry: 'python3 Utilities/Hooks/kw-commit-msg.py'
+ language: system
+ stages: [commit-msg]
diff --git a/.pypirc.example b/.pypirc.example
new file mode 100644
index 00000000..05b64161
--- /dev/null
+++ b/.pypirc.example
@@ -0,0 +1,23 @@
+# .pypirc.example -- DO NOT commit real credentials
+# Copy to ~/.pypirc and fill in your token.
+#
+# Generate a token at: https://pypi.org/manage/account/token/
+# For TestPyPI: https://test.pypi.org/manage/account/token/
+#
+# Alternatively, set environment variables:
+# TWINE_USERNAME=__token__
+# TWINE_PASSWORD=pypi-
+
+[distutils]
+index-servers =
+ pypi
+ testpypi
+
+[pypi]
+username = __token__
+password = pypi-YOUR-TOKEN-HERE
+
+[testpypi]
+repository = https://test.pypi.org/legacy/
+username = __token__
+password = pypi-YOUR-TOKEN-HERE
diff --git a/.readthedocs.yml b/.readthedocs.yml
new file mode 100644
index 00000000..72aeff6c
--- /dev/null
+++ b/.readthedocs.yml
@@ -0,0 +1,13 @@
+version: 2
+
+build:
+ os: ubuntu-22.04
+ tools:
+ python: "3.11"
+
+sphinx:
+ configuration: docs/conf.py
+
+python:
+ install:
+ - requirements: docs/requirements-docs.txt
diff --git a/.travis.yml b/.travis.yml
deleted file mode 100644
index e00ff622..00000000
--- a/.travis.yml
+++ /dev/null
@@ -1,15 +0,0 @@
-sudo: required
-
-services:
- - docker
-
-cache:
- directories:
- - $HOME/docker
-
-before_install:
- - sudo pip install -U scikit-ci-addons
- - ci_addons docker load-pull-save r.j3ss.co/shellcheck
-
-script:
- - scripts/lint-shell-scripts.sh
diff --git a/BuildWheelsSupport/CMakeLists.txt b/BuildWheelsSupport/CMakeLists.txt
new file mode 100644
index 00000000..dbaa4a66
--- /dev/null
+++ b/BuildWheelsSupport/CMakeLists.txt
@@ -0,0 +1,7 @@
+cmake_minimum_required(VERSION 3.26.6 FATAL_ERROR)
+# NOTE: 3.26.6 is the first cmake version to support Development.SABIModule
+
+project(ITKPythonPackageWheels CXX)
+
+include(${CMAKE_CURRENT_SOURCE_DIR}/../cmake/ITKPythonPackage_Utils.cmake)
+include(${CMAKE_CURRENT_SOURCE_DIR}/../cmake/ITKPythonPackage_BuildWheels.cmake)
diff --git a/LICENSE b/BuildWheelsSupport/LICENSE
similarity index 100%
rename from LICENSE
rename to BuildWheelsSupport/LICENSE
diff --git a/scripts/WHEEL_NAMES.txt b/BuildWheelsSupport/WHEEL_NAMES.txt
similarity index 89%
rename from scripts/WHEEL_NAMES.txt
rename to BuildWheelsSupport/WHEEL_NAMES.txt
index 94ff00af..434c06c1 100644
--- a/scripts/WHEEL_NAMES.txt
+++ b/BuildWheelsSupport/WHEEL_NAMES.txt
@@ -4,4 +4,4 @@ itk-io
itk-filtering
itk-registration
itk-segmentation
-itk-meta
\ No newline at end of file
+itk-meta
diff --git a/CLAUDE.md b/CLAUDE.md
new file mode 100644
index 00000000..d49e838e
--- /dev/null
+++ b/CLAUDE.md
@@ -0,0 +1,108 @@
+# CLAUDE.md
+
+This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
+
+## Project Overview
+
+ITKPythonPackage is a cross-platform build system for creating Python binary wheels for the Insight Toolkit (ITK) — an open-source C++ image analysis library. It builds wheels for ITK itself and for ITK external (remote) modules across Linux, macOS, and Windows (x86_64 and arm64/aarch64).
+
+ITK external modules require pre-built ITK artifacts. These are cached as [ITKPythonBuilds](https://github.com/InsightSoftwareConsortium/ITKPythonBuilds) releases to avoid rebuilding ITK for every module.
+
+## Build System
+
+### Running a build
+
+The primary entry point is `scripts/build_wheels.py`, orchestrated via pixi:
+
+```sh
+pixi run build-itk-wheels
+```
+
+Or directly:
+```sh
+python scripts/build_wheels.py
+```
+
+### Environment management
+
+**pixi** (conda-like) manages reproducible build environments defined in `pixi.toml`. Environments are composed per-platform and per-Python-version (e.g., `manylinux228-py310`, `macosx-py311`).
+
+### Key environment variables (GitHub Actions compatible)
+
+- `ITK_PACKAGE_VERSION` — Version string for wheels
+- `ITKPYTHONPACKAGE_TAG` — ITKPythonPackage version/tag to use
+- `ITKPYTHONPACKAGE_ORG` — GitHub org (default: InsightSoftwareConsortium)
+- `ITK_MODULE_PREQ` — Module dependencies (`org/repo@tag:org/repo@tag:...`)
+- `CMAKE_OPTIONS` — Extra CMake flags
+- `MANYLINUX_VERSION` — Manylinux ABI version (_2_28, _2_34, etc.)
+- `MACOSX_DEPLOYMENT_TARGET` — macOS minimum deployment target
+
+### Linting
+
+```sh
+pre-commit run --all-files
+```
+
+Shell script linting was previously via `.travis.yml`; now uses pre-commit hooks.
+
+## Architecture
+
+### Python build scripts (`scripts/`)
+
+Class hierarchy for platform-specific wheel building:
+
+- **`build_wheels.py`** — Main driver. Detects platform/arch, selects pixi environment, creates platform-specific build instance.
+- **`build_python_instance_base.py`** — Abstract base class defining the shared build pipeline (download, configure, build, package).
+- **`linux_build_python_instance.py`** — Linux: TBB support, `auditwheel` for manylinux compliance.
+- **`macos_build_python_instance.py`** — macOS: `delocate` for dylib relocation.
+- **`windows_build_python_instance.py`** — Windows: `delvewheel` for DLL bundling.
+
+Supporting scripts:
+- **`pyproject_configure.py`** — Generates `pyproject.toml` from `pyproject.toml.in` template with platform-specific substitutions.
+- **`wheel_builder_utils.py`** — Shared utilities (subprocess wrappers, path handling, env parsing).
+- **`cmake_argument_builder.py`** — Builds CMake args for both direct invocation (`-DKEY=VALUE`) and scikit-build-core (`--config-setting=cmake.define.KEY=VALUE`).
+- **`BuildManager.py`** — JSON-based build step tracking for resuming interrupted builds.
+
+### CMake layer (`cmake/`)
+
+- **`ITKPythonPackage_Utils.cmake`** — Utility functions for module dependency resolution, wheel-to-group mapping.
+- **`ITKPythonPackage_BuildWheels.cmake`** — Wheel-specific CMake build configuration.
+- **`ITKPythonPackage_SuperBuild.cmake`** — ITK + dependencies superbuild.
+
+### Wheel targets
+
+Defined in `BuildWheelsSupport/WHEEL_NAMES.txt`: itk-core, itk-numerics, itk-io, itk-filtering, itk-registration, itk-segmentation, itk-meta.
+
+### Build backend
+
+Uses **scikit-build-core**. The `pyproject.toml.in` template is the single source of truth for project metadata.
+
+### Conda/pixi-build integration (`packages/libitk-wrapping/`)
+
+The `libitk-wrapping` package is a rattler-build recipe that produces a conda package of ITK C++ with full Python wrapping artifacts. When installed in a pixi/conda environment, the build system automatically detects it and skips the expensive ITK C++ compilation (steps 01-02), reducing remote module build times from ~1-2 hours to ~15 minutes.
+
+- **`packages/libitk-wrapping/recipe.yaml`** — rattler-build recipe (configurable via `ITK_GIT_URL`/`ITK_GIT_TAG` env vars)
+- **`packages/libitk-wrapping/build-libitk-wrapping.sh`** — Unix build script
+- **`packages/libitk-wrapping/build-libitk-wrapping.bat`** — Windows build script
+- **`conda-forge/`** — Prepared conda-forge staged-recipes submission
+
+Detection is in `build_python_instance_base.py:_detect_conda_itk()` — checks `CONDA_PREFIX` and `PIXI_ENVIRONMENT_DIR` for `lib/cmake/ITK-*/ITKConfig.cmake`.
+
+## Shell script entry points
+
+Legacy shell/PowerShell scripts are preserved for backward compatibility with existing CI workflows:
+- `scripts/dockcross-manylinux-download-cache-and-build-module-wheels.sh` (Linux)
+- `scripts/macpython-download-cache-and-build-module-wheels.sh` (macOS)
+- `scripts/windows-download-cache-and-build-module-wheels.ps1` (Windows)
+
+These scripts delegate to the Python build system internally and will skip tarball downloads when a conda-installed ITK is detected.
+
+### Commit message convention
+
+This project follows the ITK commit message convention: `PREFIX: Description`. Valid prefixes: `BUG:`, `COMP:`, `DOC:`, `ENH:`, `PERF:`, `STYLE:`. Enforced via commitizen (configured in `pyproject.toml`, validated by the `commit-msg` pre-commit hook).
+
+## Related repositories
+
+- [ITK](https://github.com/InsightSoftwareConsortium/ITK) — The C++ toolkit itself
+- [ITKPythonBuilds](https://github.com/InsightSoftwareConsortium/ITKPythonBuilds) — Cached ITK build artifacts
+- [ITKRemoteModuleBuildTestPackageAction](https://github.com/InsightSoftwareConsortium/ITKRemoteModuleBuildTestPackageAction) — GitHub Actions reusable workflows for building/testing/packaging
diff --git a/CMakeLists.txt b/CMakeLists.txt
deleted file mode 100644
index 6908545c..00000000
--- a/CMakeLists.txt
+++ /dev/null
@@ -1,571 +0,0 @@
-cmake_minimum_required(VERSION 3.26.6 FATAL_ERROR)
-# NOTE: 3.26.6 is the first cmake vesion to support Development.SABIModule
-
-project(ITKPythonPackage CXX)
-
-set(CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake ${CMAKE_MODULE_PATH})
-include(ITKPythonPackage)
-
-if(NOT DEFINED ITKPythonPackage_SUPERBUILD)
- set(ITKPythonPackage_SUPERBUILD 1)
-endif()
-
-if(NOT DEFINED ITKPythonPackage_WHEEL_NAME)
- set(ITKPythonPackage_WHEEL_NAME "itk")
-endif()
-message(STATUS "SuperBuild - ITKPythonPackage_WHEEL_NAME:${ITKPythonPackage_WHEEL_NAME}")
-
-option(ITKPythonPackage_USE_TBB "Build and use oneTBB in the ITK python package" ON)
-
-if(ITKPythonPackage_SUPERBUILD)
-
- #-----------------------------------------------------------------------------
- #------------------------------------------------------
- #----------------------------------
- # ITKPythonPackage_SUPERBUILD: ON
- #----------------------------------
- #------------------------------------------------------
- #-----------------------------------------------------------------------------
-
- # Avoid "Manually-specified variables were not used by the project" warnings.
- ipp_unused_vars(${PYTHON_VERSION_STRING} ${SKBUILD})
-
- set(ep_common_cmake_cache_args )
- if(NOT CMAKE_CONFIGURATION_TYPES)
- list(APPEND ep_common_cmake_cache_args
- -DCMAKE_BUILD_TYPE:STRING=${CMAKE_BUILD_TYPE}
- )
- endif()
- set(ep_download_extract_timestamp_arg )
- if(CMAKE_VERSION VERSION_EQUAL "3.24" OR CMAKE_VERSION VERSION_GREATER "3.24")
- # See https://cmake.org/cmake/help/latest/policy/CMP0135.html
- set(ep_download_extract_timestamp_arg DOWNLOAD_EXTRACT_TIMESTAMP 1)
- endif()
-
- #-----------------------------------------------------------------------------
- # Options
-
- # When building different "flavor" of ITK python packages on a given platform,
- # explicitly setting the following options allow to speed up package generation by
- # re-using existing resources.
- #
- # ITK_SOURCE_DIR: Path to an existing source directory
- #
-
- option(ITKPythonPackage_BUILD_PYTHON "Build ITK python module" ON)
- mark_as_advanced(ITKPythonPackage_BUILD_PYTHON)
-
- if(CMAKE_OSX_DEPLOYMENT_TARGET)
- list(APPEND ep_common_cmake_cache_args
- -DCMAKE_OSX_DEPLOYMENT_TARGET:STRING=${CMAKE_OSX_DEPLOYMENT_TARGET})
- endif()
- if(CMAKE_OSX_ARCHITECTURES)
- list(APPEND ep_common_cmake_cache_args
- -DCMAKE_OSX_ARCHITECTURES:STRING=${CMAKE_OSX_ARCHITECTURES})
- endif()
-
- if(CMAKE_MAKE_PROGRAM)
- list(APPEND ep_common_cmake_cache_args
- -DCMAKE_MAKE_PROGRAM:FILEPATH=${CMAKE_MAKE_PROGRAM})
- endif()
-
- #-----------------------------------------------------------------------------
- # compile with multiple processors
- include(ProcessorCount)
- ProcessorCount(NPROC)
- if(NOT NPROC EQUAL 0)
- set( ENV{MAKEFLAGS} "-j${NPROC}" )
- endif()
-
- #-----------------------------------------------------------------------------
- include(ExternalProject)
-
- set(ITK_REPOSITORY "https://github.com/InsightSoftwareConsortium/ITK.git")
-
- # release branch, 2026-03-10
- set(ITK_GIT_TAG "c6e1c1be6a86236cbb812bd71eec5a4df9b1353c")
-
- #-----------------------------------------------------------------------------
- # A separate project is used to download ITK, so that it can reused
- # when building different "flavor" of ITK python packages
-
- message(STATUS "SuperBuild -")
- message(STATUS "SuperBuild - ITK-source-download")
-
- # Sanity checks
- if(DEFINED ITK_SOURCE_DIR AND NOT EXISTS ${ITK_SOURCE_DIR})
- message(FATAL_ERROR "ITK_SOURCE_DIR variable is defined but corresponds to nonexistent directory")
- endif()
-
- if(ITKPythonPackage_USE_TBB)
- if(ITK_SOURCE_DIR)
- set(TBB_DIR "${ITK_SOURCE_DIR}/../oneTBB-prefix/lib/cmake/TBB")
- else()
- set(TBB_DIR "${CMAKE_BINARY_DIR}/../oneTBB-prefix/lib/cmake/TBB")
- endif()
- set(tbb_args )
- if(ITKPythonPackage_USE_TBB)
- set(tbb_args
- -DModule_ITKTBB:BOOL=ON
- -DTBB_DIR:PATH=${TBB_DIR}
- )
- endif()
-
- set(tbb_cmake_cache_args)
- if(CMAKE_OSX_DEPLOYMENT_TARGET)
- list(APPEND tbb_cmake_cache_args
- -DCMAKE_CXX_OSX_DEPLOYMENT_TARGET_FLAG:STRING="-mmacosx-version-min=${CMAKE_OSX_DEPLOYMENT_TARGET}"
- -DCMAKE_C_OSX_DEPLOYMENT_TARGET_FLAG:STRING="-mmacosx-version-min=${CMAKE_OSX_DEPLOYMENT_TARGET}"
- )
- endif()
-
- ExternalProject_add(oneTBB
- URL https://github.com/oneapi-src/oneTBB/archive/refs/tags/v2022.2.0.tar.gz
- URL_HASH SHA256=f0f78001c8c8edb4bddc3d4c5ee7428d56ae313254158ad1eec49eced57f6a5b
- CMAKE_ARGS
- -DTBB_TEST:BOOL=OFF
- -DCMAKE_BUILD_TYPE:STRING=Release
- -DCMAKE_INSTALL_PREFIX:PATH=${CMAKE_BINARY_DIR}/../oneTBB-prefix
- -DCMAKE_INSTALL_LIBDIR:STRING=lib # Skip default initialization by GNUInstallDirs CMake module
- ${ep_common_cmake_cache_args}
- ${tbb_cmake_cache_args}
- ${ep_download_extract_timestamp_arg}
- -DCMAKE_BUILD_TYPE:STRING=Release
- BUILD_BYPRODUCTS "${TBB_DIR}/TBBConfig.cmake"
- USES_TERMINAL_DOWNLOAD 1
- USES_TERMINAL_UPDATE 1
- USES_TERMINAL_CONFIGURE 1
- USES_TERMINAL_BUILD 1
- )
- message(STATUS "SuperBuild - TBB: Enabled")
- message(STATUS "SuperBuild - TBB_DIR: ${TBB_DIR}")
- endif()
- set(tbb_depends "")
- if(ITKPythonPackage_USE_TBB)
- set(tbb_depends oneTBB)
- endif()
-
-
- if(NOT DEFINED ITK_SOURCE_DIR)
-
- set(ITK_SOURCE_DIR ${CMAKE_BINARY_DIR}/ITK)
-
- ExternalProject_add(ITK-source-download
- SOURCE_DIR ${ITK_SOURCE_DIR}
- GIT_REPOSITORY ${ITK_REPOSITORY}
- GIT_TAG ${ITK_GIT_TAG}
- USES_TERMINAL_DOWNLOAD 1
- CONFIGURE_COMMAND ""
- BUILD_COMMAND ""
- INSTALL_COMMAND ""
- DEPENDS "${tbb_depends}"
- )
- set(proj_status "")
-
- else()
-
- ipp_ExternalProject_Add_Empty(
- ITK-source-download
- ""
- )
- set(proj_status " (REUSE)")
-
- endif()
-
- message(STATUS "SuperBuild - ITK_SOURCE_DIR: ${ITK_SOURCE_DIR}")
- message(STATUS "SuperBuild - ITK-source-download[OK]${proj_status}")
-
- #-----------------------------------------------------------------------------
- if(NOT ITKPythonPackage_BUILD_PYTHON)
- return()
- endif()
-
- #-----------------------------------------------------------------------------
- # Search for python interpreter and libraries
-
- message(STATUS "SuperBuild -")
- message(STATUS "SuperBuild - Searching for python")
-
- # Sanity checks
- if(DEFINED Python3_INCLUDE_DIR AND NOT EXISTS ${Python3_INCLUDE_DIR})
- message(FATAL_ERROR "Python3_INCLUDE_DIR variable is defined but corresponds to nonexistent directory")
- endif()
- if(DEFINED Python3_LIBRARY AND NOT EXISTS ${Python3_LIBRARY})
- message(FATAL_ERROR "Python3_LIBRARY variable is defined but corresponds to nonexistent file")
- endif()
- if(DEFINED Python3_EXECUTABLE AND NOT EXISTS ${Python3_EXECUTABLE})
- message(FATAL_ERROR "Python3_EXECUTABLE variable is defined but corresponds to nonexistent file")
- endif()
- if(DEFINED DOXYGEN_EXECUTABLE AND NOT EXISTS ${DOXYGEN_EXECUTABLE})
- message(FATAL_ERROR "DOXYGEN_EXECUTABLE variable is defined but corresponds to nonexistent file")
- endif()
-
- if(NOT DEFINED Python3_INCLUDE_DIR
- OR NOT DEFINED Python3_LIBRARY
- OR NOT DEFINED Python3_EXECUTABLE)
-
- find_package(Python3 COMPONENTS Interpreter Development)
- if(NOT Python3_EXECUTABLE AND _Python3_EXECUTABLE)
- set(Python3_EXECUTABLE ${_Python3_EXECUTABLE} CACHE INTERNAL
- "Path to the Python interpreter" FORCE)
- endif()
- endif()
- if(NOT DEFINED DOXYGEN_EXECUTABLE)
- find_package(Doxygen REQUIRED)
- endif()
-
- message(STATUS "SuperBuild - Python3_INCLUDE_DIR: ${Python3_INCLUDE_DIR}")
- message(STATUS "SuperBuild - Python3_INCLUDE_DIRS: ${Python3_INCLUDE_DIRS}")
- message(STATUS "SuperBuild - Python3_LIBRARY: ${Python3_LIBRARY}")
- message(STATUS "SuperBuild - Python3_EXECUTABLE: ${Python3_EXECUTABLE}")
- message(STATUS "SuperBuild - Searching for python[OK]")
- message(STATUS "SuperBuild - DOXYGEN_EXECUTABLE: ${DOXYGEN_EXECUTABLE}")
-
- # CMake configuration variables to pass to ITK's build
- set(ep_itk_cmake_cache_args "")
- foreach(var
- BUILD_SHARED_LIBS
- ITK_BUILD_DEFAULT_MODULES
- )
- if(DEFINED ${var})
- list(APPEND ep_itk_cmake_cache_args "-D${var}=${${var}}")
- endif()
- endforeach()
- function(cached_variables RESULTVAR PATTERN)
- get_cmake_property(variables CACHE_VARIABLES)
- set(result)
- foreach(variable ${variables})
- if(${variable} AND variable MATCHES "${PATTERN}")
- list(APPEND result "-D${variable}=${${variable}}")
- endif()
- endforeach()
- set(${RESULTVAR} ${result} PARENT_SCOPE)
- endfunction()
- cached_variables(itk_pattern_cached_vars "^(ITK_WRAP_)|(ITKGroup_)|(Module_)")
- list(APPEND ep_itk_cmake_cache_args ${itk_pattern_cached_vars})
- # Todo, also pass all Module_* variables
- message(STATUS "ITK CMake Cache Args - ${ep_itk_cmake_cache_args}")
- #-----------------------------------------------------------------------------
- # ITK: This project builds ITK and associated Python modules
-
- option(ITKPythonPackage_ITK_BINARY_REUSE "Reuse provided ITK_BINARY_DIR without configuring or building ITK" OFF)
-
- set(ITK_BINARY_DIR "${CMAKE_BINARY_DIR}/ITKb" CACHE PATH "ITK build directory")
-
- message(STATUS "SuperBuild -")
- message(STATUS "SuperBuild - ITK => Requires ITK-source-download")
- message(STATUS "SuperBuild - ITK_BINARY_DIR: ${ITK_BINARY_DIR}")
-
- if(NOT ITKPythonPackage_ITK_BINARY_REUSE)
-
- set(_stamp "${CMAKE_BINARY_DIR}/ITK-prefix/src/ITK-stamp/ITK-configure")
- if(EXISTS ${_stamp})
- execute_process(COMMAND ${CMAKE_COMMAND} -E remove ${_stamp})
- message(STATUS "SuperBuild - Force re-configure removing ${_stamp}")
- endif()
-
- set(install_component_per_module OFF)
- if(NOT ITKPythonPackage_WHEEL_NAME STREQUAL "itk")
- set(install_component_per_module ON)
- endif()
-
- ExternalProject_add(ITK
- DOWNLOAD_COMMAND ""
- SOURCE_DIR ${ITK_SOURCE_DIR}
- BINARY_DIR ${ITK_BINARY_DIR}
- PREFIX "ITKp"
- CMAKE_ARGS
- -DBUILD_TESTING:BOOL=OFF
- -DCMAKE_INSTALL_PREFIX:PATH=${CMAKE_INSTALL_PREFIX}
- -DPY_SITE_PACKAGES_PATH:PATH=${CMAKE_INSTALL_PREFIX}
- -DWRAP_ITK_INSTALL_COMPONENT_IDENTIFIER:STRING=PythonWheel
- -DWRAP_ITK_INSTALL_COMPONENT_PER_MODULE:BOOL=${install_component_per_module}
- -DITK_LEGACY_SILENT:BOOL=ON
- -DITK_WRAP_PYTHON:BOOL=ON
- -DDOXYGEN_EXECUTABLE:FILEPATH=${DOXYGEN_EXECUTABLE}
- -DPython3_INCLUDE_DIR:PATH=${Python3_INCLUDE_DIR}
- -DPython3_LIBRARY:FILEPATH=${Python3_LIBRARY}
- -DPython3_EXECUTABLE:FILEPATH=${Python3_EXECUTABLE}
- ${ep_common_cmake_cache_args}
- ${tbb_args}
- ${ep_itk_cmake_cache_args}
- ${ep_download_extract_timestamp_arg}
- USES_TERMINAL_DOWNLOAD 1
- USES_TERMINAL_UPDATE 1
- USES_TERMINAL_CONFIGURE 1
- USES_TERMINAL_BUILD 1
- INSTALL_COMMAND ""
- )
- set(proj_status "")
-
- else()
-
- # Sanity checks
- if(NOT EXISTS "${ITK_BINARY_DIR}/CMakeCache.txt")
- message(FATAL_ERROR "ITKPythonPackage_ITK_BINARY_REUSE is ON but ITK_BINARY_DIR variable is not associated with an ITK build directory. [ITK_BINARY_DIR:${ITK_BINARY_DIR}]")
- endif()
-
- ipp_ExternalProject_Add_Empty(
- ITK
- ""
- )
- set(proj_status " (REUSE)")
-
- endif()
- ExternalProject_Add_StepDependencies(ITK download ITK-source-download)
-
- message(STATUS "SuperBuild - ITK[OK]${proj_status}")
-
- #-----------------------------------------------------------------------------
- # ITKPythonPackage: This project adds install rules for the "RuntimeLibraries"
- # components associated with the ITK project.
-
- message(STATUS "SuperBuild -")
- message(STATUS "SuperBuild - ${PROJECT_NAME} => Requires ITK")
-
- ExternalProject_add(${PROJECT_NAME}
- SOURCE_DIR ${CMAKE_SOURCE_DIR}
- BINARY_DIR ${CMAKE_BINARY_DIR}/${PROJECT_NAME}-build
- DOWNLOAD_COMMAND ""
- UPDATE_COMMAND ""
- CMAKE_CACHE_ARGS
- -DITKPythonPackage_SUPERBUILD:BOOL=0
- -DITK_BINARY_DIR:PATH=${ITK_BINARY_DIR}
- -DITK_SOURCE_DIR:PATH=${ITK_SOURCE_DIR}
- -DCMAKE_INSTALL_PREFIX:PATH=${CMAKE_INSTALL_PREFIX}
- -DITKPythonPackage_WHEEL_NAME:STRING=${ITKPythonPackage_WHEEL_NAME}
- -DITKPythonPackage_USE_TBB:BOOL=${ITKPythonPackage_USE_TBB}
- ${ep_common_cmake_cache_args}
- USES_TERMINAL_CONFIGURE 1
- INSTALL_COMMAND ""
- DEPENDS ITK
- )
-
- install(SCRIPT ${CMAKE_BINARY_DIR}/${PROJECT_NAME}-build/cmake_install.cmake)
-
- message(STATUS "SuperBuild - ${PROJECT_NAME}[OK]")
-
-else()
-
- #-----------------------------------------------------------------------------
- #------------------------------------------------------
- #----------------------------------
- # ITKPythonPackage_SUPERBUILD: OFF
- #----------------------------------
- #------------------------------------------------------
- #-----------------------------------------------------------------------------
-
- set(components "PythonWheelRuntimeLibraries")
- if(NOT ITKPythonPackage_WHEEL_NAME STREQUAL "itk")
-
- message(STATUS "ITKPythonPackage_WHEEL_NAME: ${ITKPythonPackage_WHEEL_NAME}")
-
- # Extract ITK group name from wheel name
- message(STATUS "")
- set(msg "Extracting ITK_WHEEL_GROUP")
- message(STATUS ${msg})
- ipp_wheel_to_group(${ITKPythonPackage_WHEEL_NAME} ITK_WHEEL_GROUP)
- message(STATUS "${msg} - done [${ITK_WHEEL_GROUP}]")
-
- #
- # Considering that
- #
- # * Every ITK module is associated with exactly one ITK group.
- # * ITK module dependencies are specified independently of ITK groups
- #
- # we semi-arbitrarily defined a collection of wheels (see ``ITK_WHEEL_GROUPS``)
- # that will roughly bundle the modules associated with each group.
- #
- # Based on the module dependency graph, the code below will determine which module
- # should be packaged in which wheel.
- #
-
- # List of ITK wheel groups
- set(ITK_WHEEL_GROUPS "")
- file(STRINGS "${CMAKE_SOURCE_DIR}/scripts/WHEEL_NAMES.txt" ITK_WHEELS REGEX "^itk-.+")
- foreach(wheel_name IN LISTS ITK_WHEELS)
- ipp_wheel_to_group(${wheel_name} group)
- list(APPEND ITK_WHEEL_GROUPS ${group})
- endforeach()
-
- # Define below a reasonable dependency graph for ITK groups
- set(ITK_GROUP_Core_DEPENDS)
- set(ITK_GROUP_IO_DEPENDS Core)
- set(ITK_GROUP_Numerics_DEPENDS Core)
- set(ITK_GROUP_Filtering_DEPENDS Numerics)
- set(ITK_GROUP_Segmentation_DEPENDS Filtering)
- set(ITK_GROUP_Registration_DEPENDS Filtering)
- set(ITK_GROUP_Video_DEPENDS Core)
-
- # ITK is needed to retrieve ITK module information
- set(ITK_DIR ${ITK_BINARY_DIR})
- find_package(ITK REQUIRED)
- set(CMAKE_MODULE_PATH ${ITK_CMAKE_DIR} ${CMAKE_MODULE_PATH})
-
- # Sort wheel groups
- include(TopologicalSort)
- topological_sort(ITK_WHEEL_GROUPS ITK_GROUP_ _DEPENDS)
-
- # Set ``ITK_MODULE__DEPENDS`` variables
- #
- # Notes:
- #
- # * ``_DEPENDS`` variables are set after calling ``find_package(ITK REQUIRED)``
- #
- # * This naming convention corresponds to what is used internally in ITK and allow
- # to differentiate with variable like ``ITK_GROUP__DEPENDS`` set above.
- #
- foreach(module IN LISTS ITK_MODULES_ENABLED)
- set(ITK_MODULE_${module}_DEPENDS "${${module}_DEPENDS}")
- endforeach()
-
- # Set ``ITK_MODULE__DEPENDEES`` variables
- foreach(module IN LISTS ITK_MODULES_ENABLED)
- ipp_get_module_dependees(${module} ITK_MODULE_${module}_DEPENDEES)
- endforeach()
-
- # Set ``ITK_GROUPS`` variable
- file(GLOB group_dirs "${ITK_SOURCE_DIR}/Modules/*")
- set(ITK_GROUPS )
- foreach(dir IN LISTS group_dirs)
- file(RELATIVE_PATH group "${ITK_SOURCE_DIR}/Modules" "${dir}")
- if(NOT IS_DIRECTORY "${dir}" OR "${group}" MATCHES "^External$")
- continue()
- endif()
- list(APPEND ITK_GROUPS ${group})
- endforeach()
- message(STATUS "")
- message(STATUS "ITK_GROUPS:${ITK_GROUPS}")
-
- # Set ``ITK_MODULE__GROUP`` variables
- foreach(group IN LISTS ITK_GROUPS)
- file( GLOB_RECURSE _${group}_module_files ${ITK_SOURCE_DIR}/Modules/${group}/itk-module.cmake )
- foreach( _module_file ${_${group}_module_files} )
- file(READ ${_module_file} _module_file_content)
- string( REGEX MATCH "itk_module[ \n]*(\\([ \n]*)([A-Za-z0-9]*)" _module_name ${_module_file_content} )
- set(_module_name ${CMAKE_MATCH_2})
- list( APPEND _${group}_module_list ${_module_name} )
- set(ITK_MODULE_${_module_name}_GROUP ${group})
- endforeach()
- endforeach()
-
- # Initialize ``ITK_WHEEL__MODULES`` variables that will contain list of modules
- # to package in each wheel.
- foreach(group IN LISTS ITK_WHEEL_GROUPS)
- set(ITK_WHEEL_${group}_MODULES "")
- endforeach()
-
- # Configure table display
- set(row_widths 40 20 20 10 90 12)
- set(row_headers MODULE_NAME MODULE_GROUP WHEEL_GROUP IS_LEAF MODULE_DEPENDEES_GROUPS IS_WRAPPED)
- message(STATUS "")
- ipp_display_table_row("${row_headers}" "${row_widths}")
-
- # Update ``ITK_WHEEL__MODULES`` variables
- foreach(module IN LISTS ITK_MODULES_ENABLED)
-
- ipp_is_module_leaf(${module} leaf)
- set(dependees_groups)
- if(NOT leaf)
- set(dependees "")
- ipp_recursive_module_dependees(${module} dependees)
- foreach(dep IN LISTS dependees)
- list(APPEND dependees_groups ${ITK_MODULE_${dep}_GROUP})
- endforeach()
- if(dependees_groups)
- list(REMOVE_DUPLICATES dependees_groups)
- endif()
- endif()
-
- # Filter out group not associated with a wheel
- set(dependees_wheel_groups)
- foreach(group IN LISTS dependees_groups)
- list(FIND ITK_WHEEL_GROUPS ${group} _index)
- if(_index EQUAL -1)
- continue()
- endif()
- list(APPEND dependees_wheel_groups ${group})
- endforeach()
-
- set(wheel_group)
- list(LENGTH dependees_wheel_groups _length)
-
- # Sanity check
- if(leaf AND _length GREATER 0)
- message(FATAL_ERROR "leaf module should not module depending on them !")
- endif()
-
- if(_length EQUAL 0)
- set(wheel_group "${ITK_MODULE_${module}_GROUP}")
- elseif(_length EQUAL 1)
- # Since packages depending on this module belong to one group, also package this module
- set(wheel_group "${dependees_wheel_groups}")
- elseif(_length GREATER 1)
- # If more than one group is associated with the dependees, package the module in the
- # "common ancestor" group.
- set(common_ancestor_index 999999)
- foreach(g IN LISTS dependees_wheel_groups)
- list(FIND ITK_WHEEL_GROUPS ${g} _index)
- if(NOT _index EQUAL -1 AND _index LESS common_ancestor_index)
- set(common_ancestor_index ${_index})
- endif()
- endforeach()
- list(GET ITK_WHEEL_GROUPS ${common_ancestor_index} wheel_group)
- endif()
-
- set(wheel_group_display ${wheel_group})
-
- # XXX Hard-coded dispatch
- if(module STREQUAL "ITKBridgeNumPy")
- set(new_wheel_group "Core")
- set(wheel_group_display "${new_wheel_group} (was ${wheel_group})")
- set(wheel_group ${new_wheel_group})
- endif()
- if(module STREQUAL "ITKVTK")
- set(new_wheel_group "Core")
- set(wheel_group_display "${new_wheel_group} (was ${wheel_group})")
- set(wheel_group ${new_wheel_group})
- endif()
-
- # Associate module with a wheel
- list(APPEND ITK_WHEEL_${wheel_group}_MODULES ${module})
-
- # Display module info
- ipp_is_module_python_wrapped(${module} is_wrapped)
- ipp_list_to_string("^^" "${dependees_groups}" dependees_groups_str)
- set(row_values "${module};${ITK_MODULE_${module}_GROUP};${wheel_group_display};${leaf};${dependees_groups_str};${is_wrapped}")
- ipp_display_table_row("${row_values}" "${row_widths}")
-
- endforeach()
-
- # Set list of components to install
- set(components "")
- foreach(module IN LISTS ITK_WHEEL_${ITK_WHEEL_GROUP}_MODULES)
- list(APPEND components ${module}PythonWheelRuntimeLibraries)
- endforeach()
-
- endif()
-
- if(MSVC AND ITKPythonPackage_WHEEL_NAME STREQUAL "itk-core")
- message(STATUS "Adding install rules for compiler runtime libraries")
- # Put the runtime libraries next to the "itk/_*.pyd" C-extensions so they
- # are found.
- set(CMAKE_INSTALL_SYSTEM_RUNTIME_DESTINATION "itk")
- include(InstallRequiredSystemLibraries)
- endif()
-
- #-----------------------------------------------------------------------------
- # Install ITK components
- message(STATUS "Adding install rules for components:")
- foreach(component IN LISTS components)
- message(STATUS " ${component}")
- install(CODE "
-unset(CMAKE_INSTALL_COMPONENT)
-set(COMPONENT \"${component}\")
-set(CMAKE_INSTALL_DO_STRIP 1)
-include(\"${ITK_BINARY_DIR}/cmake_install.cmake\")
-unset(CMAKE_INSTALL_COMPONENT)
-")
- endforeach()
-
-endif()
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
new file mode 100644
index 00000000..719705d1
--- /dev/null
+++ b/CONTRIBUTING.md
@@ -0,0 +1,73 @@
+# Contributing to ITKPythonPackage
+
+## Getting Started
+
+Clone the repository and install the pre-commit hooks:
+
+```bash
+git clone https://github.com/InsightSoftwareConsortium/ITKPythonPackage.git
+cd ITKPythonPackage
+````
+
+Install [Pixi](https://pixi.sh) for managing the build environment:
+
+```bash
+curl -fsSL https://pixi.sh/install.sh | bash
+pixi install
+```
+
+Install pre-commit hooks
+
+```bash
+pixi run pre-commit-install
+# optionally run pre-commit hooks
+pixi run pre-commit-run
+```
+
+
+## Development Workflow
+
+### Code Style
+
+Pre-commit hooks enforce all formatting and linting automatically on commit:
+
+- **Python**: Black (formatting), Ruff (linting + import sorting)
+- **Shell**: ShellCheck (linting), shfmt (formatting)
+- **TOML**: Taplo (formatting)
+
+Run against all files manually:
+
+```bash
+pre-commit run --all-files
+```
+
+### Commit Messages
+
+This project uses [Conventional Commits](https://www.conventionalcommits.org), enforced by Commitizen:
+
+```
+feat: add support for Python 3.12 wheels
+fix: correct cmake args not propagating to module builds
+chore: update pre-commit hook versions
+docs: clarify aarch64 build requirements
+```
+
+Commitizen will reject commits that don't follow this format.
+
+### Building Docs
+
+```bash
+pip install -r docs/requirements-docs.txt
+sphinx-build -W -b html docs docs/_build/html
+```
+
+## Submitting a Pull Request
+
+1. Create a branch from `main`
+2. Make your changes and ensure `pre-commit run --all-files` passes
+3. Open a PR, fill out the template, including which platforms you tested on
+4. CI will run pre-commit checks automatically
+
+## Questions
+
+For build questions or general ITK support, use the [ITK Discourse forum](https://discourse.itk.org).
diff --git a/README.md b/README.md
index 052a849a..3b42c7de 100644
--- a/README.md
+++ b/README.md
@@ -1,8 +1,8 @@
# ITK Python Package
This project configures pyproject.toml files and manages environmental
-variables needed to build ITK Python binary wheels on MacOS, Linux, and Windows platforms.
-Scripts are available for both [ITK infrastructure](https://github.com/insightSoftwareConsortium/ITK) and
+variables needed to build ITK Python binary wheels on macOS, Linux, and Windows platforms.
+Scripts are available for both [ITK infrastructure](https://github.com/insightSoftwareConsortium/ITK) and
ITK external module Python packages.
The Insight Toolkit (ITK) is an open-source, cross-platform system that provides developers
@@ -12,86 +12,327 @@ or at the [ITK GitHub homepage](https://github.com/insightSoftwareConsortium/ITK
## Table of Contents
-- [Using ITK Python Packages](#using-itk-python-packages)
-- [Building with ITKPythonPackage](#building-with-itkpythonpackage)
+- [Building Remote Modules with ITKPythonPackage](#building-remote-modules-with-itkpythonpackage)
+- [Building ITK Python Wheels](#building-itk-python-wheels)
- [Frequently Asked Questions](#frequently-asked-questions)
- [Additional Information](#additional-information)
-## Using ITK Python Packages (pre-built, or locally built)
+## Building Remote Modules with ITKPythonPackage
-ITKPythonPackage scripts can be used to produce [Python](https://www.python.org/) packages
-for ITK and ITK external modules. The resulting packages can be
-hosted on the [Python Package Index (PyPI)](https://pypi.org/)
-for easy distribution.
+ITK reusable workflows are available to build and package Python wheels as
+part of Continuous Integration (CI) via GitHub Actions runners.
+Those workflows can handle the overhead of fetching, configuring, and
+running ITKPythonPackage build scripts for most ITK external modules.
+See [ITKRemoteModuleBuildTestPackageAction](https://github.com/InsightSoftwareConsortium/ITKRemoteModuleBuildTestPackageAction)
+for more information.
+
+> [!NOTE]
+> When using`ITKRemoteModuleBuildTestPackageAction` in your remote module, you can specify the `itk-python-package-org` and `itk-python-package-tag` to build with.
+
+For special cases where ITK reusable workflows are not a good fit,
+ITKPythonPackage scripts can be directly used to build Python wheels
+to target Windows, Linux, and macOS platforms. See
+below or the [ITKPythonPackage ReadTheDocs](https://itkpythonpackage.readthedocs.io/en/latest/Build_ITK_Module_Python_packages.html)
+documentation for more information on building wheels by hand.
+
+## Building ITK Python Wheels
+
+### Do You Actually Need to Build ITK?
+
+Most users do not need to build ITK from source.
-### Installation of pre-built packages
+Pre-built ITK binaries are available as downloadable tarballs and the provided download-and-build shell scripts will fetch them automatically.
-To install baseline ITK Python packages:
+You may only need to build ITK yourself if you:
+- Have a local ITK with custom patches or bug fixes not yet in a release
+- Need to build against a specific unreleased commit
+- Are developing ITK core itself
-```sh
-> pip install itk
+If none of the above apply to you, you may download an existing build of ITK from ITK's repository for [ITK Python Builds](https://github.com/InsightSoftwareConsortium/ITKPythonBuilds/releases). **Or**, use the download-and-build script seen in the [Building Remote Module Wheels](#building-remote-module-wheels) section below.
+
+For more control over your builds, skip to [The Build Process](#the-build-process)
+
+---
+
+### Prerequisites
+
+- Python 3.10 or later
+- Git
+- Docker (for manylinux builds)
+- [Pixi](https://pixi.sh) package manager
+
+**Install Pixi:**
+```bash
+# Linux or Mac
+curl -fsSL https://pixi.sh/install.sh | bash
+
+# Windows
+powershell -ExecutionPolicy Bypass -c "irm -useb https://pixi.sh/install.ps1 | iex"
```
-To install ITK external module packages:
+**Clone the repo:**
+```bash
+git clone https://github.com/InsightSoftwareConsortium/ITKPythonPackage.git
+cd ITKPythonPackage
+```
+
+---
+
+### Building Remote Module Wheels
+
+#### The Build Process
+
+The build process calls `build_wheels.py`, which runs up to 7 steps:
+
+1. Build SuperBuild support components
+2. Build ITK C++ with Python wrapping
+3. Build wheels for ITK C++
+4. Fix up wheels if needed
+5. Import test
+6. *(optional)* Build a remote module against the ITK build
+7. *(optional)* Build an ITK tarball cache
-```sh
-> pip install itk-
+> [!NOTE]
+> When using the download-and-build scripts, steps 2–3 are skipped because the pre-built cache covers them.
+
+You can invoke the `build_wheels.py` script directly for more control shown below
+
+Available pixi platform build environments:
+
+| Platform | Architectures | Python Versions |
+|----------|---------------|-----------------|
+| `linux` | x86_64, aarch64 | py310, py311 |
+| `manylinux228` | x86_64, aarch64 | py310, py311 |
+| `macosx` | x86_64, arm64 | py310, py311 |
+| `windows` | x86_64 | py310, py311 |
+
+
+```bash
+# Building ITK Python Wheels on macOS for ITK v6.0b01
+pixi run python3 scripts/build_wheels.py \
+ --platform-env macosx-py310 \
+ --itk-git-tag v6.0b01 \
+ --no-build-itk-tarball-cache
```
-### Using ITK in Python scripts
+Key options:
+
+| Option | Description | Example |
+|----------------------------------|----------------------------------------------|-------------------------------|
+| `--platform-env` | Target platform and Python version | `macosx-py310` |
+| `--build-dir-root` | Location for build artifacts | `/tmp/ITKPythonPackage-build` |
+| `--itk-git-tag` | ITK version/branch/commit to use | `0ffcaed`, `main`, `v6.0b01` |
+| `--itk-package-version` | PEP440 version string for wheels | `v6.0b01` |
+| `--manylinux-version` | Manylinux standard version | `_2_28` |
+| `--module-source-dir` | Path to remote module to build | `/path/to/module` |
+| `--itk-module-deps` | Remote module dependencies | `Mod1@tag:Mod2@tag` |
+| `--module-dependencies-root-dir` | Root directory for module dependencies | `./dependencies` |
+| `--itk-source-dir` | Path to ITK source (use local development) | `/path/to/ITK` |
+| `--cleanup` | Leave temporary build files after completion | (flag) |
+| `--no-build-itk-tarball-cache` | Skip tarball generation (default) | (flag) |
+| `--no-skip-itk-build` | Don't skip ITK build step (default | (flag) |
+| `--no-skip-itk-wheel-build` | Don't skip the ITK wheel build step (default) | (flag) |
-```python
- import itk
- import sys
- input_filename = sys.argv[1]
- output_filename = sys.argv[2]
+Run `pixi run python3 scripts/build_wheels.py --help` for the full option list.
- image = itk.imread(input_filename)
+> [!NOTE]
+> Building ITK from source can take 1-2 hours on typical hardware. Once complete, use `--build-itk-tarball-cache` to save the result and avoid rebuilding.
- median = itk.median_image_filter(image, radius=2)
+To use the scripts that take care of the build for you, see this section:
- itk.imwrite(median, output_filename)
+
+Download-and-Build Remote Module Builds
+
+This is the same process as used in the GitHub Actions CI/CD
+
+```bash
+cd ITKRemoteModule
```
-### Other Resources for Using ITK in Python
+#### Linux (manylinux)
-See also the [ITK Python Quick Start
-Guide](https://itkpythonpackage.readthedocs.io/en/master/Quick_start_guide.html).
-There are also many [downloadable examples on the ITK examples website](https://examples.itk.org/search.html?q=Python).
+Use `dockcross-manylinux-download-cache-and-build-module-wheels.sh`. This script:
+1. Downloads the pre-built ITK binary tarball for your platform
+2. Extracts it to a local build directory
+3. Calls `dockcross-manylinux-build-module-wheels.sh` to build the module wheels inside a manylinux Docker container
-For more information on ITK's Python wrapping, [an introduction is
-provided in the ITK Software
-Guide](https://itk.org/ITKSoftwareGuide/html/Book1/ITKSoftwareGuide-Book1ch3.html#x32-420003.7).
+Run from your ITK external module root:
+```bash
+bash dockcross-manylinux-download-cache-and-build-module-wheels.sh cp310
+```
-## Building with ITKPythonPackage
+> [!NOTE]
+> Omit the Python version argument (e.g. `cp310`) to build for all default versions (cp310 and cp311).
-ITK reusable workflows are available to build and package Python wheels as
-part of Continuous Integration (CI) via Github Actions runners.
-Those workflows can handle the overhead of fetching, configuring, and
-running ITKPythonPackage build scripts for most ITK external modules.
-See [ITKRemoteModuleBuildTestPackageAction](https://github.com/InsightSoftwareConsortium/ITKRemoteModuleBuildTestPackageAction)
-for more information.
+#### macOS
+
+Use `macpython-download-cache-and-build-module-wheels.sh`. This script:
+1. Installs required tools (aria2, zstd, gnu-tar) via Pixi if not present
+2. Downloads and extracts the macOS ITK binary tarball
+3. Builds your module wheels for each requested Python version
+
+Run from your module root:
+```bash
+bash macpython-download-cache-and-build-module-wheels.sh 3.10
+```
+
+#### Windows
+
+Use `windows-download-cache-and-build-module-wheels.ps1`. This script:
+1. Installs required tools (git, aria2) via Pixi if not present
+2. Downloads and extracts the Windows ITK binary zip file
+3. Builds your module wheels for each requested Python version
+
+Run from your module root:
+```powershell
+.\windows-download-cache-and-build-module-wheels.ps1 3.11
+```
-For special cases where ITK reusable workflows are not a good fit,
-ITKPythonPackage scripts can be directly used to build Python wheels
-to target Windows, Linux, and MacOS platforms. See
-[ITKPythonPackage ReadTheDocs](https://itkpythonpackage.readthedocs.io/en/master/Build_ITK_Module_Python_packages.html)
-documentation for more information on building wheels by hand.
+#### Output
+
+Finished wheels are placed in `/dist/`.
+
+
+
+
+To see how to build wheels for your version of ITK see this section:
+
+
+Building ITK from Source
+
+If you have a local ITK with custom patches, a bug fix not yet released, or you're developing ITK core itself. Build as follows
+
+Pass `--itk-source-dir` pointing to your local ITK clone. `build_wheels.py` will build ITK from that source instead of re-cloning.
+
+#### manylinux — building ITK from source
+
+Use `dockcross-manylinux-build-wheels.sh` directly (skips the download step):
+
+```bash
+ITK_SOURCE_DIR=/path/to/your/ITK \
+bash scripts/dockcross-manylinux-build-wheels.sh cp310
+```
+
+Key environment variables:
+
+| Variable | Default | Description |
+|----------|-----------------------------------------|-------------|
+| `ITK_GIT_TAG` | `main` | ITK branch/tag/commit to build |
+| `ITK_SOURCE_DIR` | `/ITKPythonPackage-build/ITK` | Path to local ITK source (skips git clone) |
+| `MANYLINUX_VERSION` | `_2_28` | Manylinux standard to target |
+| `IMAGE_TAG` | `20250913-6ea98ba` | Dockcross image tag |
+
+#### Linux/macOS/Windows — building ITK from source
+
+Use `build_wheels.py` directly with `--itk-source-dir`:
+
+```bash
+# Building on macOS with a specific git tag
+pixi run python3 scripts/build_wheels.py \
+ --platform-env macosx-py310 \
+ --itk-source-dir /path/to/your/ITK \
+ --itk-git-tag my-bugfix-branch \
+ --no-build-itk-tarball-cache \
+ --build-dir-root /tmp/itk-build
+```
+
+Add `--build-itk-tarball-cache` if you want to save the result as a reusable tarball.
+
+
+
+To see how to build ITK Python Build Caches, see this section:
+
+
+Building ITK Python Caches
+
+#### GitHub Compatible Caches
+
+To build the caches compatible with GitHub Actions CI and the ITKPythonBuilds repository. You can run:
+
+On Linux and macOS systems
+```bash
+bash scripts/make_tarballs.sh # py310 (optionally add specific version of Python)
+```
+
+On Windows systems
+```powershell
+.\scripts\make_windows_zip.ps1 # py310 (optionally add specific version of Python)
+```
+
+> [!IMPORTANT]
+> Build caches embed absolute paths. If you extract a tarball to a different path than it was built with, CMake will fail. Standard build paths for CI/CD are:
+> - manylinux (Docker): `/work/ITKPythonPackage-build`
+> - macOS: `/Users/svc-dashboard/D/P/ITKPythonPackage-build`
+> - Windows: `C:\BDR`
+>
+> This script ensures you are building with the correct conventions
+
+#### Local Caches
+
+To build caches for local use, you can run the `build_wheels.py` script with the `--build-itk-tarball-cache`
+
+#### Publish Tarball Caches
+
+To publish the tarball caches to a GitHub Release, you can run:
+
+> [!NOTE]
+> This requires the `GH_TOKEN` environment variable to be set or `gh auth login` to have been run beforehand.
+> Tarballs are expected in the parent directory of `--build-dir-root` (POSIX `.tar.zst`) or inside it (Windows `.zip`).
+
+```bash
+pixi run -e publish publish-tarball-cache --itk-package-version v6.0b02 --build-dir-root /path/to/build/root
+```
+
+Users can also specify the GitHub repository to publish to using `--repo` (defaults to ITKPythonBuilds) and
+`--create-release` to create the release if it does not already exist.
+
+
+
+To see how to publish wheels see this section:
+
+
+Publishing Wheels
+This repository contains a script for publishing wheels to PyPI and TestPyPI.
+
+The script can be run with the pixi environment as such:
+
+> [!NOTE]
+> This script assumes you have the `TWINE_USERNAME` and `TWINE_PASSWORD` environment variables set or the
+> `.pypirc` file configured on your machine. An example `.pypirc` can be seen in the root of this repository
+
+```bash
+pixi run -e publish publish-wheels --dist-directory /path/to/dist/
+```
+
+You can also optionally pass in `--test` to publish to TestPyPI for validation before uploading to production,
+`--repository-url` to specify a custom package index, or `--skip-existing` to skip already-uploaded wheels.
+
+
+
+---
## Frequently Asked Questions
### What target platforms and architectures are supported?
ITKPythonPackage currently supports building wheels for the following platforms and architectures:
- - Windows 10 x86_64 platforms
- - Windows 11 x86_64 platforms
- - MacOS 15.0+ arm64 platforms
- - Linux glibc 2.17+ (E.g. Ubuntu 18.04+) x86_64 platforms
- - Linux glibc 2.28+ (E.g. Ubuntu 20.04+) aarch64 (ARMv8) platforms
+
+- Windows 10/11 x86_64 platforms
+- macOS arm64 (Apple Silicon)
+- macOS x86_64 (Intel)
+- Linux glibc 2.17+ (e.g. Ubuntu 20.04+) x86_64
+- Linux glibc 2.28+ (e.g. Ubuntu 20.04+) aarch64 (ARMv8)
Python 3.10+ is required.
+[ITKRemoteModuleBuildTestPackageAction](https://github.com/InsightSoftwareConsortium/ITKRemoteModuleBuildTestPackageAction)
+CI workflows support Python 3.10–3.11 on GitHub-hosted runners for:
+- Ubuntu x86_64
+- Ubuntu aarch64 (ARM)
+- macOS arm64 (Apple Silicon)
+- Windows x86_64
+
### What should I do if my target platform/architecture does not appear on the list above?
Please open an issue in the [ITKPythonPackage issue tracker](https://github.com/InsightSoftwareConsortium/ITKPythonPackage/issues)
diff --git a/SuperbuildSupport/CMakeLists.txt b/SuperbuildSupport/CMakeLists.txt
new file mode 100644
index 00000000..25311ae9
--- /dev/null
+++ b/SuperbuildSupport/CMakeLists.txt
@@ -0,0 +1,7 @@
+cmake_minimum_required(VERSION 3.26.6 FATAL_ERROR)
+# NOTE: 3.26.6 is the first cmake version to support Development.SABIModule
+
+project(ITKPythonPackageSuperbuild CXX)
+
+include(${CMAKE_CURRENT_SOURCE_DIR}/../cmake/ITKPythonPackage_Utils.cmake)
+include(${CMAKE_CURRENT_SOURCE_DIR}/../cmake/ITKPythonPackage_SuperBuild.cmake)
diff --git a/Utilities/Hooks/kw-commit-msg.py b/Utilities/Hooks/kw-commit-msg.py
new file mode 100755
index 00000000..0d6b0af8
--- /dev/null
+++ b/Utilities/Hooks/kw-commit-msg.py
@@ -0,0 +1,153 @@
+#!/usr/bin/env python3
+# ==========================================================================
+#
+# Copyright NumFOCUS
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# https://www.apache.org/licenses/LICENSE-2.0.txt
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# ==========================================================================
+
+import os
+import re
+import subprocess
+import sys
+
+from pathlib import Path
+
+
+DEFAULT_LINE_LENGTH: int = 78
+
+
+def die(message, commit_msg_path):
+ print("commit-msg hook failure", file=sys.stderr)
+ print("-----------------------", file=sys.stderr)
+ print(message, file=sys.stderr)
+ print("-----------------------", file=sys.stderr)
+ print(
+ f"""
+To continue editing, run the command
+ git commit -e -F "{commit_msg_path}"
+(assuming your working directory is at the top).""",
+ file=sys.stderr,
+ )
+ sys.exit(1)
+
+
+def get_max_length():
+ try:
+ result = subprocess.run(
+ ["git", "config", "--get", "hooks.commit-msg.ITKCommitSubjectMaxLength"],
+ capture_output=True,
+ text=True,
+ check=True,
+ )
+ return int(result.stdout.strip())
+ except (subprocess.CalledProcessError, ValueError):
+ return DEFAULT_LINE_LENGTH
+
+
+def main():
+ git_dir_path: Path = Path(os.environ.get("GIT_DIR", ".git")).resolve()
+ commit_msg_path: Path = git_dir_path / "COMMIT_MSG"
+
+ if len(sys.argv) < 2:
+ die(f"Usage: {sys.argv[0]} ", commit_msg_path)
+
+ input_file: Path = Path(sys.argv[1])
+ if not input_file.exists():
+ die(
+ f"Missing input_file {sys.argv[1]} for {sys.argv[0]} processing",
+ commit_msg_path,
+ )
+ max_subjectline_length: int = get_max_length()
+
+ original_input_file_lines: list[str] = []
+ with open(input_file) as f_in:
+ original_input_file_lines = f_in.readlines()
+
+ input_file_lines: list[str] = []
+ for test_line in original_input_file_lines:
+ test_line = test_line.strip()
+ is_empty_line_before_subject: bool = (
+ len(input_file_lines) == 0 and len(test_line) == 0
+ )
+ if test_line.startswith("#") or is_empty_line_before_subject:
+ continue
+ input_file_lines.append(f"{test_line}\n")
+
+ with open(commit_msg_path, "w") as f_out:
+ f_out.writelines(input_file_lines)
+
+ subject_line: str = input_file_lines[0]
+
+ if len(subject_line) < 8:
+ die(
+ f"The first line must be at least 8 characters:\n--------\n{subject_line}\n--------",
+ commit_msg_path,
+ )
+ if (
+ len(subject_line) > max_subjectline_length
+ and not subject_line.startswith("Merge ")
+ and not subject_line.startswith("Revert ")
+ ):
+ die(
+ f"The first line may be at most {max_subjectline_length} characters:\n"
+ + "-" * max_subjectline_length
+ + f"\n{subject_line}\n"
+ + "-" * max_subjectline_length,
+ commit_msg_path,
+ )
+ if re.match(r"^[ \t]|[ \t]$", subject_line):
+ die(
+ f"The first line may not have leading or trailing space:\n[{subject_line}]",
+ commit_msg_path,
+ )
+ if not re.match(
+ r"^(Merge|Revert|BUG:|COMP:|DOC:|ENH:|PERF:|STYLE:|WIP:)\s", subject_line
+ ):
+ die(
+ f"""Start ITK commit messages with a standard prefix (and a space):
+ BUG: - fix for runtime crash or incorrect result
+ COMP: - compiler error or warning fix
+ DOC: - documentation change
+ ENH: - new functionality
+ PERF: - performance improvement
+ STYLE: - no logic impact (indentation, comments)
+ WIP: - Work In Progress not ready for merge
+To reference GitHub issue XXXX, add "Issue #XXXX" to the commit message.
+If the issue addresses an open issue, add "Closes #XXXX" to the message.""",
+ commit_msg_path,
+ )
+ if re.match(r"^BUG: [0-9]+\.", subject_line):
+ die(
+ f'Do not put a "." after the bug number:\n\n {subject_line}',
+ commit_msg_path,
+ )
+ del subject_line
+
+ if len(input_file_lines) > 1:
+ second_line: str = input_file_lines[
+ 1
+ ].strip() # Remove whitespace at beginning and end
+ if len(second_line) == 0:
+ input_file_lines[1] = "\n" # Replace line with only newline
+ else:
+ die(
+ f'The second line of the commit message must be empty:\n"{second_line}" with length {len(second_line)}',
+ commit_msg_path,
+ )
+ del second_line
+
+
+if __name__ == "__main__":
+ main()
diff --git a/Utilities/Hooks/prepare-commit-msg b/Utilities/Hooks/prepare-commit-msg
new file mode 100755
index 00000000..276fd093
--- /dev/null
+++ b/Utilities/Hooks/prepare-commit-msg
@@ -0,0 +1,53 @@
+#!/usr/bin/env bash
+#==========================================================================
+#
+# Copyright NumFOCUS
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# https://www.apache.org/licenses/LICENSE-2.0.txt
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+#==========================================================================
+
+egrep-q() {
+ egrep "$@" >/dev/null 2>/dev/null
+}
+
+# First argument is file containing commit message.
+commit_msg="$1"
+
+# Check for our extra instructions.
+egrep-q "^# Start ITK commit messages" -- "$commit_msg" && return 0
+
+# Insert our extra instructions.
+commit_msg_tmp="$commit_msg.$$"
+instructions='#\
+# Start ITK commit messages with a standard prefix (and a space):\
+# BUG: - fix for runtime crash or incorrect result\
+# COMP: - compiler error or warning fix\
+# DOC: - documentation change\
+# ENH: - new functionality\
+# PERF: - performance improvement\
+# STYLE: - no logic impact (indentation, comments)\
+# WIP: - Work In Progress not ready for merge\
+#\
+# The first line of the commit message should preferably be 72 characters\
+# or less; the maximum allowed is 78 characters.\
+#\
+# Follow the first line commit summary with an empty line, then a detailed\
+# description in one or more paragraphs.\
+#' &&
+sed '/^# On branch.*$/ a\
+'"$instructions"'
+/^# Not currently on any branch.*$/ a\
+'"$instructions"'
+' "$commit_msg" > "$commit_msg_tmp" &&
+mv "$commit_msg_tmp" "$commit_msg"
diff --git a/Utilities/scripts/build-all-latest-wheels.sh b/Utilities/scripts/build-all-latest-wheels.sh
new file mode 100755
index 00000000..948c379e
--- /dev/null
+++ b/Utilities/scripts/build-all-latest-wheels.sh
@@ -0,0 +1,121 @@
+#!/bin/bash
+# Build ITK + all remote module Python wheels.
+# Usage: ./scripts/build-all-latest-wheels.sh [options]
+# --platform-env ENV Pixi environment (default: linux-py311)
+# --itk-ref REF ITK branch, tag, or commit hash (default: main)
+# --itk-repo URL ITK git URL
+# --ipp-branch BRANCH ITKPythonPackage branch (default: python-build-system)
+# --ipp-repo URL ITKPythonPackage git URL
+# Example:
+# ./scripts/build-all-latest-wheels.sh --itk-ref v6.0b02 --platform-env linux-py311
+set -euo pipefail
+
+# Defaults
+PLATFORM_ENV="linux-py311"
+ITK_REF="main"
+ITK_REPO="https://github.com/InsightSoftwareConsortium/ITK.git"
+IPP_REPO="https://github.com/BRAINSia/ITKPythonPackage.git"
+IPP_BRANCH="python-build-system"
+
+while [[ $# -gt 0 ]]; do
+ case "$1" in
+ --platform-env) PLATFORM_ENV="$2"; shift 2 ;;
+ --itk-ref) ITK_REF="$2"; shift 2 ;;
+ --itk-repo) ITK_REPO="$2"; shift 2 ;;
+ --ipp-branch) IPP_BRANCH="$2"; shift 2 ;;
+ --ipp-repo) IPP_REPO="$2"; shift 2 ;;
+ *) echo "Unknown option: $1"; exit 1 ;;
+ esac
+done
+
+TIMESTAMP=$(date +%Y%m%d%H%M%S)
+WORKDIR="/tmp/${TIMESTAMP}_LatestITKPython"
+DIST_DIR="${WORKDIR}/dist"
+
+mkdir -p "${DIST_DIR}"
+echo "=== Build directory: ${WORKDIR}"
+echo "=== Platform: ${PLATFORM_ENV}"
+echo "=== ITK ref: ${ITK_REF}"
+
+# 1) Clone ITK
+echo "=== Cloning ITK (${ITK_REF})..."
+git clone "${ITK_REPO}" "${WORKDIR}/ITK"
+git -C "${WORKDIR}/ITK" checkout "${ITK_REF}"
+
+# 2) Clone ITKPythonPackage
+echo "=== Cloning ITKPythonPackage (${IPP_BRANCH})..."
+git clone --branch "${IPP_BRANCH}" "${IPP_REPO}" "${WORKDIR}/ITKPythonPackage"
+
+# 3) Parse remote modules from ITK and clone each
+echo "=== Cloning remote modules..."
+MODULES_DIR="${WORKDIR}/modules"
+mkdir -p "${MODULES_DIR}"
+module_list=()
+
+for rc in "${WORKDIR}"/ITK/Modules/Remote/*.remote.cmake; do
+ name=$(basename "${rc}" .remote.cmake)
+ repo=$(grep 'GIT_REPOSITORY' "${rc}" | sed 's/.*GIT_REPOSITORY *//;s/ *)//;s/[[:space:]]*$//')
+ [ -z "${repo}" ] && continue
+
+ echo " Cloning ${name} from ${repo}..."
+ if git clone --depth 1 "${repo}" "${MODULES_DIR}/${name}" 2>/dev/null; then
+ # Only keep modules that have Python wrapping
+ if [ -d "${MODULES_DIR}/${name}/wrapping" ] && [ -f "${MODULES_DIR}/${name}/pyproject.toml" ]; then
+ module_list+=("${name}")
+ else
+ rm -rf "${MODULES_DIR}/${name}"
+ fi
+ else
+ echo " WARNING: Failed to clone ${name}, skipping"
+ fi
+done
+
+echo "=== ${#module_list[@]} modules with Python wrapping"
+
+# 4) Build ITK wheels
+cd "${WORKDIR}/ITKPythonPackage"
+echo "=== Building ITK Python wheels..."
+pixi run -e "${PLATFORM_ENV}" -- python scripts/build_wheels.py \
+ --platform-env "${PLATFORM_ENV}" \
+ --itk-git-tag main \
+ --itk-source-dir "${WORKDIR}/ITK" \
+ --no-build-itk-tarball-cache \
+ --no-use-sudo \
+ --build-dir-root "${WORKDIR}/build"
+
+# Copy ITK wheels to dist
+cp "${WORKDIR}"/build/dist/*.whl "${DIST_DIR}/" 2>/dev/null || true
+
+# 5) Build each remote module wheel
+failed_modules=()
+for name in "${module_list[@]}"; do
+ echo "=== Building ${name}..."
+ if pixi run -e "${PLATFORM_ENV}" -- python scripts/build_wheels.py \
+ --platform-env "${PLATFORM_ENV}" \
+ --itk-git-tag "${ITK_REF}" \
+ --itk-source-dir "${WORKDIR}/ITK" \
+ --module-source-dir "${MODULES_DIR}/${name}" \
+ --no-build-itk-tarball-cache \
+ --no-use-sudo \
+ --skip-itk-build \
+ --skip-itk-wheel-build \
+ --build-dir-root "${WORKDIR}/build" 2>&1; then
+ cp "${MODULES_DIR}/${name}"/dist/*.whl "${DIST_DIR}/" 2>/dev/null || true
+ else
+ echo " FAILED: ${name}"
+ failed_modules+=("${name}")
+ fi
+done
+
+# 6) Summary
+echo ""
+echo "=== Build complete ==="
+echo "Wheels: ${DIST_DIR}"
+ls -1 "${DIST_DIR}"/*.whl 2>/dev/null | wc -l
+echo "total wheels produced"
+
+if [ ${#failed_modules[@]} -gt 0 ]; then
+ echo ""
+ echo "Failed modules (${#failed_modules[@]}):"
+ printf ' %s\n' "${failed_modules[@]}"
+fi
diff --git a/Utilities/scripts/build_all_latest_wheels.py b/Utilities/scripts/build_all_latest_wheels.py
new file mode 100755
index 00000000..a75ee44c
--- /dev/null
+++ b/Utilities/scripts/build_all_latest_wheels.py
@@ -0,0 +1,203 @@
+#!/usr/bin/env python3
+"""Build ITK + all remote module Python wheels from latest main branches.
+
+Usage::
+
+ python scripts/build_all_latest_wheels.py [--platform-env linux-py311]
+ python scripts/build_all_latest_wheels.py --help
+"""
+
+import argparse
+import re
+import shutil
+import subprocess
+import sys
+from datetime import datetime
+from pathlib import Path
+
+
+def run(cmd: list[str], **kwargs) -> subprocess.CompletedProcess:
+ print(f" $ {' '.join(str(c) for c in cmd)}")
+ return subprocess.run(cmd, check=True, **kwargs)
+
+
+def clone(repo: str, dest: Path, branch: str | None = None, depth: int | None = 1) -> bool:
+ cmd = ["git", "clone"]
+ if depth is not None:
+ cmd += ["--depth", str(depth)]
+ if branch:
+ cmd += ["--branch", branch]
+ cmd += [repo, str(dest)]
+ try:
+ run(cmd, capture_output=True)
+ return True
+ except subprocess.CalledProcessError:
+ return False
+
+
+def parse_remote_modules(itk_dir: Path) -> list[tuple[str, str]]:
+ """Parse ITK remote .cmake files, return [(name, git_url), ...]."""
+ modules = []
+ for rc in sorted((itk_dir / "Modules" / "Remote").glob("*.remote.cmake")):
+ name = rc.stem.replace(".remote", "")
+ text = rc.read_text()
+ m = re.search(r"GIT_REPOSITORY\s+(\S+)", text)
+ if m:
+ modules.append((name, m.group(1)))
+ return modules
+
+
+def build_wheels(
+ ipp_dir: Path,
+ platform_env: str,
+ build_dir: Path,
+ itk_source: Path,
+ itk_ref: str = "main",
+ module_source: Path | None = None,
+ skip_itk: bool = False,
+) -> bool:
+ cmd = [
+ "pixi",
+ "run",
+ "-e",
+ platform_env,
+ "--",
+ "python",
+ "scripts/build_wheels.py",
+ "--platform-env",
+ platform_env,
+ "--itk-git-tag",
+ itk_ref,
+ "--itk-source-dir",
+ str(itk_source),
+ "--no-build-itk-tarball-cache",
+ "--no-use-sudo",
+ "--build-dir-root",
+ str(build_dir),
+ ]
+ if module_source:
+ cmd += ["--module-source-dir", str(module_source)]
+ if skip_itk:
+ cmd += ["--skip-itk-build", "--skip-itk-wheel-build"]
+
+ try:
+ run(cmd, cwd=ipp_dir)
+ return True
+ except subprocess.CalledProcessError:
+ return False
+
+
+def main():
+ parser = argparse.ArgumentParser(description=__doc__)
+ parser.add_argument(
+ "--platform-env", default="linux-py311", help="Pixi environment name"
+ )
+ parser.add_argument(
+ "--ipp-branch",
+ default="python-build-system",
+ help="ITKPythonPackage branch to use",
+ )
+ parser.add_argument(
+ "--ipp-repo",
+ default="https://github.com/BRAINSia/ITKPythonPackage.git",
+ help="ITKPythonPackage git URL",
+ )
+ parser.add_argument(
+ "--itk-repo",
+ default="https://github.com/InsightSoftwareConsortium/ITK.git",
+ help="ITK git URL",
+ )
+ parser.add_argument(
+ "--itk-ref",
+ default="main",
+ help="ITK branch, tag, or commit hash (default: main)",
+ )
+ args = parser.parse_args()
+
+ timestamp = datetime.now().strftime("%Y%m%d%H%M%S")
+ workdir = Path(f"/tmp/{timestamp}_LatestITKPython")
+ dist_dir = workdir / "dist"
+ dist_dir.mkdir(parents=True)
+ build_dir = workdir / "build"
+
+ print(f"=== Build directory: {workdir}")
+ print(f"=== Platform: {args.platform_env}")
+ print(f"=== ITK ref: {args.itk_ref}")
+
+ # 1) Clone ITK
+ print(f"=== Cloning ITK ({args.itk_ref})...")
+ itk_dir = workdir / "ITK"
+ clone(args.itk_repo, itk_dir, depth=None)
+ run(["git", "checkout", args.itk_ref], cwd=itk_dir)
+
+ # 2) Clone ITKPythonPackage
+ print(f"=== Cloning ITKPythonPackage ({args.ipp_branch})...")
+ ipp_dir = workdir / "ITKPythonPackage"
+ clone(args.ipp_repo, ipp_dir, branch=args.ipp_branch)
+
+ # 3) Clone remote modules
+ print("=== Cloning remote modules...")
+ modules_dir = workdir / "modules"
+ modules_dir.mkdir()
+ remote_modules = parse_remote_modules(itk_dir)
+
+ module_list: list[str] = []
+ for name, repo in remote_modules:
+ mod_dir = modules_dir / name
+ if not clone(repo, mod_dir):
+ print(f" WARNING: Failed to clone {name}, skipping")
+ continue
+ # Keep only modules with Python wrapping
+ if (mod_dir / "wrapping").is_dir() and (mod_dir / "pyproject.toml").is_file():
+ module_list.append(name)
+ else:
+ shutil.rmtree(mod_dir)
+
+ print(f"=== {len(module_list)} modules with Python wrapping")
+
+ # 4) Build ITK wheels
+ print("=== Building ITK Python wheels...")
+ if not build_wheels(ipp_dir, args.platform_env, build_dir, itk_dir, args.itk_ref):
+ print("FATAL: ITK wheel build failed")
+ sys.exit(1)
+
+ # Copy ITK wheels to dist
+ for whl in (build_dir / "dist").glob("*.whl"):
+ shutil.copy2(whl, dist_dir)
+
+ # 5) Build each remote module wheel
+ failed: list[str] = []
+ for name in module_list:
+ print(f"=== Building {name}...")
+ mod_dir = modules_dir / name
+ if build_wheels(
+ ipp_dir,
+ args.platform_env,
+ build_dir,
+ itk_dir,
+ args.itk_ref,
+ module_source=mod_dir,
+ skip_itk=True,
+ ):
+ for whl in (mod_dir / "dist").glob("*.whl"):
+ shutil.copy2(whl, dist_dir)
+ else:
+ print(f" FAILED: {name}")
+ failed.append(name)
+
+ # 6) Summary
+ wheels = list(dist_dir.glob("*.whl"))
+ print()
+ print("=== Build complete ===")
+ print(f"Wheels: {dist_dir}")
+ print(f"{len(wheels)} total wheels produced")
+
+ if failed:
+ print(f"\nFailed modules ({len(failed)}):")
+ for name in failed:
+ print(f" {name}")
+ sys.exit(1)
+
+
+if __name__ == "__main__":
+ main()
diff --git a/cmake/ITKPythonPackage.cmake b/cmake/ITKPythonPackage.cmake
deleted file mode 100644
index 4190c4e4..00000000
--- a/cmake/ITKPythonPackage.cmake
+++ /dev/null
@@ -1,240 +0,0 @@
-
-# ipp_ExternalProject_Add_Empty( )
-#
-# Add an empty external project
-#
-function(ipp_ExternalProject_Add_Empty proj depends)
- set(depends_args)
- if(NOT depends STREQUAL "")
- set(depends_args DEPENDS ${depends})
- endif()
- ExternalProject_add(${proj}
- SOURCE_DIR ${CMAKE_BINARY_DIR}/${proj}
- DOWNLOAD_COMMAND ""
- UPDATE_COMMAND ""
- CONFIGURE_COMMAND ""
- BUILD_COMMAND ""
- BUILD_IN_SOURCE 1
- BUILD_ALWAYS 1
- INSTALL_COMMAND ""
- ${depends_args}
- )
-endfunction()
-
-# ipp_get_module_dependees( )
-#
-# Collect all modules depending on ````.
-#
-function(ipp_get_module_dependees itk-module output_var)
- set(dependees "")
- foreach(m_enabled IN LISTS ITK_MODULES_ENABLED)
- list(FIND ITK_MODULE_${m_enabled}_DEPENDS ${itk-module} _index)
- if(NOT _index EQUAL -1)
- list(APPEND dependees ${m_enabled})
- endif()
- endforeach()
- list(REMOVE_DUPLICATES dependees)
- set(${output_var} ${dependees} PARENT_SCOPE)
-endfunction()
-
-function(_recursive_deps item-type item-category itk-item output_var)
- set(_${itk-item}_deps )
- foreach(dep IN LISTS ITK_${item-type}_${itk-item}_${item-category})
- list(APPEND _${itk-item}_deps ${dep})
- _recursive_deps(${item-type} ${item-category} ${dep} _${itk-item}_deps)
- endforeach()
- list(APPEND ${output_var} ${_${itk-item}_deps})
- list(REMOVE_DUPLICATES ${output_var})
- set(${output_var} ${${output_var}} PARENT_SCOPE)
-endfunction()
-
-# ipp_recursive_module_dependees( )
-#
-# Recursively collect all modules depending on ````.
-#
-function(ipp_recursive_module_dependees itk-module output_var)
- set(_${itk-module}_deps )
- _recursive_deps("MODULE" "DEPENDEES" ${itk-module} ${output_var})
- set(${output_var} ${${output_var}} PARENT_SCOPE)
-endfunction()
-
-# ipp_is_module_leaf( )
-#
-# If ```` has no dependencies, set `` to 1
-# otherwise set `` to 0.
-#
-function(ipp_is_module_leaf itk-module output_var)
- set(leaf 1)
- foreach(m_enabled IN LISTS ITK_MODULES_ENABLED)
- list(FIND ITK_MODULE_${m_enabled}_DEPENDS ${itk-module} _index)
- if(NOT _index EQUAL -1)
- set(leaf 0)
- break()
- endif()
- endforeach()
- set(${output_var} ${leaf} PARENT_SCOPE)
-endfunction()
-
-# ipp_is_module_python_wrapped( )
-#
-# If ```` is wrapped in python, set `` to 1
-# otherwise set `` to 0.
-#
-function(ipp_is_module_python_wrapped itk-module output_var)
- set(wrapped 0)
- if(NOT DEFINED ITK_MODULE_${itk-module}_GROUP)
- message(AUTHOR_WARNING "Variable ITK_MODULE_${itk-module}_GROUP is not defined")
- else()
- set(group ${ITK_MODULE_${itk-module}_GROUP})
- set(module_folder ${itk-module})
- # if any, strip ITK prefix
- if(module_folder MATCHES "^ITK.+$")
- string(REGEX REPLACE "^ITK(.+)$" "\\1" module_folder ${module_folder})
- endif()
- if(EXISTS ${ITK_SOURCE_DIR}/Modules/${group}/${itk-module}/wrapping/CMakeLists.txt
- OR EXISTS ${ITK_SOURCE_DIR}/Modules/${group}/${module_folder}/wrapping/CMakeLists.txt)
- set(wrapped 1)
- endif()
- endif()
- set(${output_var} ${wrapped} PARENT_SCOPE)
-endfunction()
-
-# ipp_wheel_to_group( )
-#
-# Extract ITK group name from wheel name (e.g 'itk-core' -> 'Core').
-#
-# If the group name has less than 3 characters, take the uppercase
-# value (e.g 'itk-io' -> 'IO').
-#
-function(ipp_wheel_to_group wheel_name group_name_var)
- string(REPLACE "itk-" "" _group ${wheel_name})
- string(SUBSTRING ${_group} 0 1 _first)
- string(TOUPPER ${_first} _first_uc)
- string(SUBSTRING ${_group} 1 -1 _remaining)
- set(group_name "${_first_uc}${_remaining}")
- # Convert to upper case if length <= 2
- string(LENGTH ${group_name} _length)
- if(_length LESS 3)
- string(TOUPPER ${group_name} group_name)
- endif()
- set(${group_name_var} ${group_name} PARENT_SCOPE)
-endfunction()
-
-# ipp_pad_text( )
-#
-# Example:
-#
-# set(row "Apple")
-# ipp_pad_text(${row} 20 row)
-#
-# set(row "${row}Banana")
-# ipp_pad_text(${row} 40 row)
-#
-# set(row "${row}Kiwi")
-# ipp_pad_text(${row} 60 row)
-#
-# message(${row})
-#
-# Output:
-#
-# Apple Banana Kiwi
-#
-function(ipp_pad_text text text_right_jusitfy_length output_var)
- set(fill_char " ")
- string(LENGTH "${text}" text_length)
- math(EXPR pad_length "${text_right_jusitfy_length} - ${text_length} - 1")
- if(pad_length GREATER 0)
- string(RANDOM LENGTH ${pad_length} ALPHABET ${fill_char} text_dots)
- set(${output_var} "${text} ${text_dots}" PARENT_SCOPE)
- else()
- set(${output_var} "${text}" PARENT_SCOPE)
- endif()
-endfunction()
-
-# ipp_display_table_row( )
-#
-# Example:
-#
-# ipp_display_table_row("Apple^^Banana^^Kiwi" "20;20;20")
-# ipp_display_table_row("Eiger^^Rainer^^Sajama" "20;20;20")
-#
-# Output:
-#
-# Apple Banana Kiwi
-# Eiger Rainer Sajama
-#
-function(ipp_display_table_row values widths)
- list(LENGTH values length)
- set(text "")
- math(EXPR range "${length} - 1")
- foreach(index RANGE ${range})
- list(GET widths ${index} width)
- list(GET values ${index} value)
- string(REPLACE "^^" ";" value "${value}")
- ipp_pad_text("${value}" ${width} value)
- set(text "${text}${value}")
- endforeach()
- message(STATUS "${text}")
-endfunction()
-
-# ipp_list_to_string( )
-#
-# Example:
-#
-# set(values Foo Bar Oof)
-# message("${values}")
-# ipp_list_to_string("^^" "${values}" values)
-# message("${values}")
-#
-# Output:
-#
-# Foo;Bar;Oof
-# Foo^^Bar^^Oof
-#
-# Copied from Slicer/CMake/ListToString.cmake
-#
-function(ipp_list_to_string separator input_list output_string_var)
- set(_string "")
- # Get list length
- list(LENGTH input_list list_length)
- # If the list has 0 or 1 element, there is no need to loop over.
- if(list_length LESS 2)
- set(_string "${input_list}")
- else()
- math(EXPR last_element_index "${list_length} - 1")
- foreach(index RANGE ${last_element_index})
- # Get current item_value
- list(GET input_list ${index} item_value)
- if(NOT item_value STREQUAL "")
- # .. and append non-empty value to output string
- set(_string "${_string}${item_value}")
- # Append separator if current element is NOT the last one.
- if(NOT index EQUAL last_element_index)
- set(_string "${_string}${separator}")
- endif()
- endif()
- endforeach()
- endif()
- set(${output_string_var} ${_string} PARENT_SCOPE)
-endfunction()
-
-# No-op function allowing to shut-up "Manually-specified variables were not used by the project"
-# warnings.
-function(ipp_unused_vars)
-endfunction()
-
-#
-# Unused
-#
-
-function(recursive_module_deps itk-module output_var)
- set(_${itk-module}_deps )
- _recursive_deps("MODULE" "DEPENDS" ${itk-module} ${output_var})
- set(${output_var} ${${output_var}} PARENT_SCOPE)
-endfunction()
-
-function(recursive_group_deps itk-group output_var)
- set(_${itk-group}_deps )
- _recursive_deps("GROUP" "DEPENDS" ${itk-group} ${output_var})
- set(${output_var} ${${output_var}} PARENT_SCOPE)
-endfunction()
diff --git a/cmake/ITKPythonPackage_BuildWheels.cmake b/cmake/ITKPythonPackage_BuildWheels.cmake
new file mode 100644
index 00000000..94fa89d9
--- /dev/null
+++ b/cmake/ITKPythonPackage_BuildWheels.cmake
@@ -0,0 +1,250 @@
+#-----------------------------------------------------------------------------
+#------------------------------------------------------
+#----------------------------------
+# ITKPythonPackage_SUPERBUILD: OFF
+#----------------------------------
+#------------------------------------------------------
+#-----------------------------------------------------------------------------
+if(NOT DEFINED ITKPythonPackage_WHEEL_NAME)
+ message(FATAL_ERROR "ITKPythonPackage_WHEEL_NAME must be defined")
+endif()
+
+message(
+ STATUS
+ "SuperBuild - ITKPythonPackage_WHEEL_NAME:${ITKPythonPackage_WHEEL_NAME}"
+)
+
+set(components "PythonWheelRuntimeLibraries")
+
+message(STATUS "ITKPythonPackage_WHEEL_NAME: ${ITKPythonPackage_WHEEL_NAME}")
+
+# Extract ITK group name from wheel name
+message(STATUS "")
+set(msg "Extracting ITK_WHEEL_GROUP")
+message(STATUS ${msg})
+ipp_wheel_to_group(${ITKPythonPackage_WHEEL_NAME} ITK_WHEEL_GROUP)
+message(STATUS "${msg} - done [${ITK_WHEEL_GROUP}]")
+
+#
+# Considering that
+#
+# * Every ITK module is associated with exactly one ITK group.
+# * ITK module dependencies are specified independently of ITK groups
+#
+# we semi-arbitrarily defined a collection of wheels (see ``ITK_WHEEL_GROUPS``)
+# that will roughly bundle the modules associated with each group.
+#
+# Based on the module dependency graph, the code below will determine which module
+# should be packaged in which wheel.
+#
+
+# List of ITK wheel groups
+set(ITK_WHEEL_GROUPS "")
+file(STRINGS "${CMAKE_SOURCE_DIR}/WHEEL_NAMES.txt" ITK_WHEELS REGEX "^itk-.+")
+foreach(wheel_name IN LISTS ITK_WHEELS)
+ ipp_wheel_to_group(${wheel_name} group)
+ list(APPEND ITK_WHEEL_GROUPS ${group})
+endforeach()
+
+# Define below a reasonable dependency graph for ITK groups
+set(ITK_GROUP_Core_DEPENDS)
+set(ITK_GROUP_IO_DEPENDS Core)
+set(ITK_GROUP_Numerics_DEPENDS Core)
+set(ITK_GROUP_Filtering_DEPENDS Numerics)
+set(ITK_GROUP_Segmentation_DEPENDS Filtering)
+set(ITK_GROUP_Registration_DEPENDS Filtering)
+set(ITK_GROUP_Video_DEPENDS Core)
+
+# ITK is needed to retrieve ITK module information
+set(ITK_DIR ${ITK_BINARY_DIR})
+find_package(ITK REQUIRED)
+set(CMAKE_MODULE_PATH ${ITK_CMAKE_DIR} ${CMAKE_MODULE_PATH})
+
+# Sort wheel groups
+include(TopologicalSort)
+topological_sort(ITK_WHEEL_GROUPS ITK_GROUP_ _DEPENDS)
+
+# Set ``ITK_MODULE__DEPENDS`` variables
+#
+# Notes:
+#
+# * ``_DEPENDS`` variables are set after calling ``find_package(ITK REQUIRED)``
+#
+# * This naming convention corresponds to what is used internally in ITK and allow
+# to differentiate with variable like ``ITK_GROUP__DEPENDS`` set above.
+#
+foreach(module IN LISTS ITK_MODULES_ENABLED)
+ set(ITK_MODULE_${module}_DEPENDS "${${module}_DEPENDS}")
+endforeach()
+
+# Set ``ITK_MODULE__DEPENDEES`` variables
+foreach(module IN LISTS ITK_MODULES_ENABLED)
+ ipp_get_module_dependees(${module} ITK_MODULE_${module}_DEPENDEES)
+endforeach()
+
+# Set ``ITK_GROUPS`` variable
+file(GLOB group_dirs "${ITK_SOURCE_DIR}/Modules/*")
+set(ITK_GROUPS)
+foreach(dir IN LISTS group_dirs)
+ file(RELATIVE_PATH group "${ITK_SOURCE_DIR}/Modules" "${dir}")
+ if(NOT IS_DIRECTORY "${dir}" OR "${group}" MATCHES "^External$")
+ continue()
+ endif()
+ list(APPEND ITK_GROUPS ${group})
+endforeach()
+message(STATUS "")
+message(STATUS "ITK_GROUPS:${ITK_GROUPS}")
+
+# Set ``ITK_MODULE__GROUP`` variables
+foreach(group IN LISTS ITK_GROUPS)
+ file(
+ GLOB_RECURSE _${group}_module_files
+ ${ITK_SOURCE_DIR}/Modules/${group}/itk-module.cmake
+ )
+ foreach(_module_file ${_${group}_module_files})
+ file(READ ${_module_file} _module_file_content)
+ string(
+ REGEX MATCH
+ "itk_module[ \n]*(\\([ \n]*)([A-Za-z0-9]*)"
+ _module_name
+ ${_module_file_content}
+ )
+ set(_module_name ${CMAKE_MATCH_2})
+ list(APPEND _${group}_module_list ${_module_name})
+ set(ITK_MODULE_${_module_name}_GROUP ${group})
+ endforeach()
+endforeach()
+
+# Initialize ``ITK_WHEEL__MODULES`` variables that will contain list of modules
+# to package in each wheel.
+foreach(group IN LISTS ITK_WHEEL_GROUPS)
+ set(ITK_WHEEL_${group}_MODULES "")
+endforeach()
+
+# Configure table display
+set(row_widths
+ 40
+ 20
+ 20
+ 10
+ 90
+ 12
+)
+set(row_headers
+ MODULE_NAME
+ MODULE_GROUP
+ WHEEL_GROUP
+ IS_LEAF
+ MODULE_DEPENDEES_GROUPS
+ IS_WRAPPED
+)
+message(STATUS "")
+ipp_display_table_row("${row_headers}" "${row_widths}")
+
+# Update ``ITK_WHEEL__MODULES`` variables
+foreach(module IN LISTS ITK_MODULES_ENABLED)
+ ipp_is_module_leaf(${module} leaf)
+ set(dependees_groups)
+ if(NOT leaf)
+ set(dependees "")
+ ipp_recursive_module_dependees(${module} dependees)
+ foreach(dep IN LISTS dependees)
+ list(APPEND dependees_groups ${ITK_MODULE_${dep}_GROUP})
+ endforeach()
+ if(dependees_groups)
+ list(REMOVE_DUPLICATES dependees_groups)
+ endif()
+ endif()
+
+ # Filter out group not associated with a wheel
+ set(dependees_wheel_groups)
+ foreach(group IN LISTS dependees_groups)
+ list(FIND ITK_WHEEL_GROUPS ${group} _index)
+ if(_index EQUAL -1)
+ continue()
+ endif()
+ list(APPEND dependees_wheel_groups ${group})
+ endforeach()
+
+ set(wheel_group)
+ list(LENGTH dependees_wheel_groups _length)
+
+ # Sanity check
+ if(leaf AND _length GREATER 0)
+ message(FATAL_ERROR "leaf module should not module depending on them !")
+ endif()
+
+ if(_length EQUAL 0)
+ set(wheel_group "${ITK_MODULE_${module}_GROUP}")
+ elseif(_length EQUAL 1)
+ # Since packages depending on this module belong to one group, also package this module
+ set(wheel_group "${dependees_wheel_groups}")
+ elseif(_length GREATER 1)
+ # If more than one group is associated with the dependees, package the module in the
+ # "common ancestor" group.
+ set(common_ancestor_index 999999)
+ foreach(g IN LISTS dependees_wheel_groups)
+ list(FIND ITK_WHEEL_GROUPS ${g} _index)
+ if(NOT _index EQUAL -1 AND _index LESS common_ancestor_index)
+ set(common_ancestor_index ${_index})
+ endif()
+ endforeach()
+ list(GET ITK_WHEEL_GROUPS ${common_ancestor_index} wheel_group)
+ endif()
+
+ set(wheel_group_display ${wheel_group})
+
+ # XXX Hard-coded dispatch
+ if(module STREQUAL "ITKBridgeNumPy")
+ set(new_wheel_group "Core")
+ set(wheel_group_display "${new_wheel_group} (was ${wheel_group})")
+ set(wheel_group ${new_wheel_group})
+ endif()
+ if(module STREQUAL "ITKVTK")
+ set(new_wheel_group "Core")
+ set(wheel_group_display "${new_wheel_group} (was ${wheel_group})")
+ set(wheel_group ${new_wheel_group})
+ endif()
+
+ # Associate module with a wheel
+ list(APPEND ITK_WHEEL_${wheel_group}_MODULES ${module})
+
+ # Display module info
+ ipp_is_module_python_wrapped(${module} is_wrapped)
+ ipp_list_to_string("^^" "${dependees_groups}" dependees_groups_str)
+ set(row_values
+ "${module};${ITK_MODULE_${module}_GROUP};${wheel_group_display};${leaf};${dependees_groups_str};${is_wrapped}"
+ )
+ ipp_display_table_row("${row_values}" "${row_widths}")
+endforeach()
+
+# Set list of components to install
+set(components "")
+foreach(module IN LISTS ITK_WHEEL_${ITK_WHEEL_GROUP}_MODULES)
+ list(APPEND components ${module}PythonWheelRuntimeLibraries)
+endforeach()
+
+if(MSVC AND ITKPythonPackage_WHEEL_NAME STREQUAL "itk-core")
+ message(STATUS "Adding install rules for compiler runtime libraries")
+ # Put the runtime libraries next to the "itk/_*.pyd" C-extensions so they
+ # are found.
+ set(CMAKE_INSTALL_SYSTEM_RUNTIME_DESTINATION "itk")
+ include(InstallRequiredSystemLibraries)
+endif()
+
+#-----------------------------------------------------------------------------
+# Install ITK components
+message(STATUS "Adding install rules for components:")
+foreach(component IN LISTS components)
+ message(STATUS " ${component}")
+ install(
+ CODE
+ "
+unset(CMAKE_INSTALL_COMPONENT)
+set(COMPONENT \"${component}\")
+set(CMAKE_INSTALL_DO_STRIP 1)
+include(\"${ITK_BINARY_DIR}/cmake_install.cmake\")
+unset(CMAKE_INSTALL_COMPONENT)
+"
+ )
+endforeach()
diff --git a/cmake/ITKPythonPackage_SuperBuild.cmake b/cmake/ITKPythonPackage_SuperBuild.cmake
new file mode 100644
index 00000000..1c59987b
--- /dev/null
+++ b/cmake/ITKPythonPackage_SuperBuild.cmake
@@ -0,0 +1,368 @@
+#-----------------------------------------------------------------------------
+#------------------------------------------------------
+#----------------------------------
+# ITKPythonPackage_SUPERBUILD: ON
+#----------------------------------
+#------------------------------------------------------
+#-----------------------------------------------------------------------------
+
+option(
+ ITKPythonPackage_USE_TBB
+ "Build and use oneTBB in the ITK python package"
+ ON
+)
+
+# Avoid "Manually-specified variables were not used by the project" warnings.
+ipp_unused_vars(${PYTHON_VERSION_STRING} ${SKBUILD})
+
+set(ep_download_extract_timestamp_arg)
+if(CMAKE_VERSION VERSION_EQUAL "3.24" OR CMAKE_VERSION VERSION_GREATER "3.24")
+ # See https://cmake.org/cmake/help/latest/policy/CMP0135.html
+ set(ep_download_extract_timestamp_arg DOWNLOAD_EXTRACT_TIMESTAMP 1)
+endif()
+
+#-----------------------------------------------------------------------------
+# Options
+
+# When building different "flavor" of ITK python packages on a given platform,
+# explicitly setting the following options allow to speed up package generation by
+# re-using existing resources.
+#
+# ITK_SOURCE_DIR: Path to an existing source directory
+#
+
+option(ITKPythonPackage_BUILD_PYTHON "Build ITK python module" ON)
+mark_as_advanced(ITKPythonPackage_BUILD_PYTHON)
+
+set(ep_common_cmake_cache_args)
+if(NOT CMAKE_CONFIGURATION_TYPES)
+ if(NOT CMAKE_BUILD_TYPE)
+ set(CMAKE_BUILD_TYPE "Release")
+ endif()
+ list(
+ APPEND ep_common_cmake_cache_args
+ -DCMAKE_BUILD_TYPE:STRING=${CMAKE_BUILD_TYPE}
+ )
+endif()
+
+if(CMAKE_OSX_DEPLOYMENT_TARGET)
+ list(
+ APPEND ep_common_cmake_cache_args
+ -DCMAKE_OSX_DEPLOYMENT_TARGET:STRING=${CMAKE_OSX_DEPLOYMENT_TARGET}
+ )
+endif()
+if(CMAKE_OSX_ARCHITECTURES)
+ list(
+ APPEND ep_common_cmake_cache_args
+ -DCMAKE_OSX_ARCHITECTURES:STRING=${CMAKE_OSX_ARCHITECTURES}
+ )
+endif()
+
+if(CMAKE_MAKE_PROGRAM)
+ list(
+ APPEND ep_common_cmake_cache_args
+ -DCMAKE_MAKE_PROGRAM:FILEPATH=${CMAKE_MAKE_PROGRAM}
+ )
+endif()
+
+if(CMAKE_CXX_COMPILER)
+ list(
+ APPEND ep_common_cmake_cache_args
+ -DCMAKE_CXX_COMPILER:PATH=${CMAKE_CXX_COMPILER}
+ )
+elseif(ENV{CXX})
+ list(APPEND ep_common_cmake_cache_args -DCMAKE_CXX_COMPILER:PATH=$ENV{CXX})
+endif()
+
+if(CMAKE_C_COMPILER)
+ list(
+ APPEND ep_common_cmake_cache_args
+ -DCMAKE_C_COMPILER:PATH=${CMAKE_C_COMPILER}
+ )
+elseif(ENV{CC})
+ list(APPEND ep_common_cmake_cache_args -DCMAKE_C_COMPILER:PATH=$ENV{CC})
+endif()
+
+#-----------------------------------------------------------------------------
+# compile with multiple processors
+include(ProcessorCount)
+ProcessorCount(NPROC)
+if(NOT NPROC EQUAL 0)
+ set(ENV{MAKEFLAGS} "-j${NPROC}")
+endif()
+
+#-----------------------------------------------------------------------------
+include(ExternalProject)
+
+#-----------------------------------------------------------------------------
+# A separate project is used to download ITK, so that it can reused
+# when building different "flavor" of ITK python packages
+
+message(STATUS "SuperBuild -")
+message(STATUS "SuperBuild - ITK-source-download")
+
+if(NOT ITK_SOURCE_DIR AND ENV{ITK_SOURCE_DIR})
+ set(ITK_SOURCE_DIR "$ENV{ITK_SOURCE_DIR}")
+endif()
+
+set(tbb_depends "")
+set(tbb_args -DModule_ITKTBB:BOOL=OFF)
+if(ITKPythonPackage_USE_TBB)
+ set(TBB_INSTALL_PREFIX "${CMAKE_BINARY_DIR}/../oneTBB-prefix")
+ set(TBB_DIR "${TBB_INSTALL_PREFIX}/lib/cmake/TBB")
+ set(tbb_args -DModule_ITKTBB:BOOL=ON -DTBB_DIR:PATH=${TBB_DIR})
+
+ set(tbb_cmake_cache_args)
+ if(CMAKE_OSX_DEPLOYMENT_TARGET)
+ list(
+ APPEND tbb_cmake_cache_args
+ -DCMAKE_CXX_OSX_DEPLOYMENT_TARGET_FLAG:STRING="-mmacosx-version-min=${CMAKE_OSX_DEPLOYMENT_TARGET}"
+ -DCMAKE_C_OSX_DEPLOYMENT_TARGET_FLAG:STRING="-mmacosx-version-min=${CMAKE_OSX_DEPLOYMENT_TARGET}"
+ )
+ endif()
+
+ ExternalProject_Add(
+ oneTBB
+ URL
+ https://github.com/oneapi-src/oneTBB/archive/refs/tags/v2022.2.0.tar.gz
+ URL_HASH
+ SHA256=f0f78001c8c8edb4bddc3d4c5ee7428d56ae313254158ad1eec49eced57f6a5b
+ CMAKE_ARGS
+ -DTBB_TEST:BOOL=OFF
+ -DCMAKE_INSTALL_PREFIX:PATH=${TBB_INSTALL_PREFIX}
+ -DCMAKE_INSTALL_LIBDIR:STRING=lib # Skip default initialization by GNUInstallDirs CMake module
+ ${ep_common_cmake_cache_args} ${tbb_cmake_cache_args}
+ ${ep_download_extract_timestamp_arg}
+ BUILD_BYPRODUCTS "${TBB_DIR}/TBBConfig.cmake"
+ USES_TERMINAL_DOWNLOAD 1
+ USES_TERMINAL_UPDATE 1
+ USES_TERMINAL_CONFIGURE 1
+ USES_TERMINAL_BUILD 1
+ )
+ message(STATUS "SuperBuild - TBB: Enabled")
+ message(STATUS "SuperBuild - TBB_DIR: ${TBB_DIR}")
+ set(tbb_depends oneTBB)
+endif()
+
+# Only add ITK-source-download ExternalProject if directory does not
+# already exist
+if(NOT EXISTS ${ITK_SOURCE_DIR})
+ set(ITK_REPOSITORY "https://github.com/InsightSoftwareConsortium/ITK.git")
+
+ if(NOT DEFINED ITK_GIT_TAG AND DEFINED ENV{ITK_GIT_TAG})
+ set(ITK_GIT_TAG "$ENV{ITK_GIT_TAG}")
+ endif()
+
+ if(NOT DEFINED ITK_GIT_TAG)
+ message(
+ FATAL_ERROR
+ "ITK_GIT_TAG must be defined when configuring cmake"
+ )
+ endif()
+ ExternalProject_Add(
+ ITK-source-download
+ SOURCE_DIR ${ITK_SOURCE_DIR}
+ GIT_REPOSITORY ${ITK_REPOSITORY}
+ GIT_TAG ${ITK_GIT_TAG}
+ USES_TERMINAL_DOWNLOAD 1
+ CONFIGURE_COMMAND ""
+ BUILD_COMMAND ""
+ INSTALL_COMMAND ""
+ DEPENDS "${tbb_depends}"
+ )
+ set(proj_status "")
+else()
+ # Suppress unused variable warning
+ set(_unused "${ITK_GIT_TAG}")
+ ipp_externalproject_add_empty(
+ ITK-source-download
+ ""
+ )
+ set(proj_status " (REUSE)")
+endif()
+
+message(STATUS "SuperBuild - ITK_SOURCE_DIR: ${ITK_SOURCE_DIR}")
+message(STATUS "SuperBuild - ITK-source-download[OK]${proj_status}")
+
+#-----------------------------------------------------------------------------
+if(NOT ITKPythonPackage_BUILD_PYTHON)
+ return()
+endif()
+
+#-----------------------------------------------------------------------------
+# Search for python interpreter and libraries
+
+message(STATUS "SuperBuild -")
+message(STATUS "SuperBuild - Searching for python")
+
+# Sanity checks
+if(DEFINED Python3_INCLUDE_DIR AND NOT EXISTS ${Python3_INCLUDE_DIR})
+ message(
+ FATAL_ERROR
+ "Python3_INCLUDE_DIR=${Python3_INCLUDE_DIR}: variable is defined but corresponds to nonexistent directory"
+ )
+endif()
+if(DEFINED Python3_LIBRARY AND NOT EXISTS ${Python3_LIBRARY})
+ message(
+ FATAL_ERROR
+ "Python3_LIBRARY=${Python3_LIBRARY}: variable is defined but corresponds to nonexistent file"
+ )
+endif()
+if(DEFINED Python3_EXECUTABLE AND NOT EXISTS ${Python3_EXECUTABLE})
+ message(
+ FATAL_ERROR
+ "Python3_EXECUTABLE=${Python3_EXECUTABLE}: variable is defined but corresponds to nonexistent file"
+ )
+endif()
+if(DEFINED DOXYGEN_EXECUTABLE AND NOT EXISTS ${DOXYGEN_EXECUTABLE})
+ message(
+ FATAL_ERROR
+ "DOXYGEN_EXECUTABLE=${DOXYGEN_EXECUTABLE}: variable is defined but corresponds to nonexistent file"
+ )
+endif()
+
+if(
+ NOT DEFINED Python3_INCLUDE_DIR
+ OR NOT DEFINED Python3_LIBRARY
+ OR NOT DEFINED Python3_EXECUTABLE
+)
+ find_package(Python3 COMPONENTS Interpreter Development)
+ if(NOT Python3_EXECUTABLE AND _Python3_EXECUTABLE)
+ set(Python3_EXECUTABLE
+ ${_Python3_EXECUTABLE}
+ CACHE INTERNAL
+ "Path to the Python interpreter"
+ FORCE
+ )
+ endif()
+endif()
+if(NOT DEFINED DOXYGEN_EXECUTABLE)
+ find_package(Doxygen REQUIRED)
+endif()
+
+message(STATUS "SuperBuild - Python3_INCLUDE_DIR: ${Python3_INCLUDE_DIR}")
+message(STATUS "SuperBuild - Python3_INCLUDE_DIRS: ${Python3_INCLUDE_DIRS}")
+message(STATUS "SuperBuild - Python3_LIBRARY: ${Python3_LIBRARY}")
+message(STATUS "SuperBuild - Python3_SABI_LIBRARY: ${Python3_SABI_LIBRARY}")
+message(STATUS "SuperBuild - Python3_EXECUTABLE: ${Python3_EXECUTABLE}")
+message(STATUS "SuperBuild - Searching for python[OK]")
+message(STATUS "SuperBuild - DOXYGEN_EXECUTABLE: ${DOXYGEN_EXECUTABLE}")
+
+# CMake configuration variables to pass to ITK's build
+set(ep_itk_cmake_cache_args "")
+foreach(var BUILD_SHARED_LIBS ITK_BUILD_DEFAULT_MODULES)
+ if(DEFINED ${var})
+ list(APPEND ep_itk_cmake_cache_args "-D${var}=${${var}}")
+ endif()
+endforeach()
+function(cached_variables RESULTVAR PATTERN)
+ get_cmake_property(variables CACHE_VARIABLES)
+ set(result)
+ foreach(variable ${variables})
+ if(${variable} AND variable MATCHES "${PATTERN}")
+ list(APPEND result "-D${variable}=${${variable}}")
+ endif()
+ endforeach()
+ set(${RESULTVAR} ${result} PARENT_SCOPE)
+endfunction()
+cached_variables(itk_pattern_cached_vars "^(ITK_WRAP_)|(ITKGroup_)|(Module_)")
+list(APPEND ep_itk_cmake_cache_args ${itk_pattern_cached_vars})
+# Todo, also pass all Module_* variables
+message(STATUS "ITK CMake Cache Args - ${ep_itk_cmake_cache_args}")
+#-----------------------------------------------------------------------------
+# ITK: This project builds ITK and associated Python modules
+
+option(
+ ITKPythonPackage_ITK_BINARY_REUSE
+ "Reuse provided ITK_BINARY_DIR without configuring or building ITK"
+ OFF
+)
+
+set(ITK_BINARY_DIR "${CMAKE_BINARY_DIR}/ITKb" CACHE PATH "ITK build directory")
+
+message(STATUS "SuperBuild -")
+message(STATUS "SuperBuild - ITK => Requires ITK-source-download")
+message(STATUS "SuperBuild - ITK_BINARY_DIR: ${ITK_BINARY_DIR}")
+
+if(NOT ITKPythonPackage_ITK_BINARY_REUSE)
+ set(_stamp "${CMAKE_BINARY_DIR}/ITK-prefix/src/ITK-stamp/ITK-configure")
+ if(EXISTS ${_stamp})
+ execute_process(COMMAND ${CMAKE_COMMAND} -E remove ${_stamp})
+ message(STATUS "SuperBuild - Force re-configure removing ${_stamp}")
+ endif()
+
+ ExternalProject_Add(
+ ITK
+ DOWNLOAD_COMMAND ""
+ SOURCE_DIR ${ITK_SOURCE_DIR}
+ BINARY_DIR ${ITK_BINARY_DIR}
+ PREFIX "ITKp"
+ CMAKE_ARGS
+ -DBUILD_TESTING:BOOL=OFF
+ -DCMAKE_INSTALL_PREFIX:PATH=${CMAKE_INSTALL_PREFIX}
+ -DPY_SITE_PACKAGES_PATH:PATH=${CMAKE_INSTALL_PREFIX}
+ -DWRAP_ITK_INSTALL_COMPONENT_IDENTIFIER:STRING=PythonWheel
+ -DWRAP_ITK_INSTALL_COMPONENT_PER_MODULE:BOOL=ON
+ -DITK_LEGACY_SILENT:BOOL=ON -DITK_WRAP_PYTHON:BOOL=ON
+ -DDOXYGEN_EXECUTABLE:FILEPATH=${DOXYGEN_EXECUTABLE}
+ -DPython3_INCLUDE_DIR:PATH=${Python3_INCLUDE_DIR}
+ -DPython3_LIBRARY:FILEPATH=${Python3_LIBRARY}
+ -DPython3_SABI_LIBRARY:FILEPATH=${Python3_SABI_LIBRARY}
+ -DPython3_EXECUTABLE:FILEPATH=${Python3_EXECUTABLE}
+ ${ep_common_cmake_cache_args} ${tbb_args} ${ep_itk_cmake_cache_args}
+ ${ep_download_extract_timestamp_arg}
+ USES_TERMINAL_DOWNLOAD 1
+ USES_TERMINAL_UPDATE 1
+ USES_TERMINAL_CONFIGURE 1
+ USES_TERMINAL_BUILD 1
+ INSTALL_COMMAND ""
+ )
+ set(proj_status "")
+else()
+ # Sanity checks
+ if(NOT EXISTS "${ITK_BINARY_DIR}/CMakeCache.txt")
+ message(
+ FATAL_ERROR
+ "ITKPythonPackage_ITK_BINARY_REUSE is ON but ITK_BINARY_DIR variable is not associated with an ITK build directory. [ITK_BINARY_DIR:${ITK_BINARY_DIR}]"
+ )
+ endif()
+
+ ipp_externalproject_add_empty(
+ ITK
+ ""
+ )
+ set(proj_status " (REUSE)")
+endif()
+ExternalProject_Add_StepDependencies(ITK download ITK-source-download)
+
+message(STATUS "SuperBuild - ITK[OK]${proj_status}")
+
+#-----------------------------------------------------------------------------
+# ITKPythonPackage: This project adds install rules for the "RuntimeLibraries"
+# components associated with the ITK project.
+
+message(STATUS "SuperBuild -")
+message(STATUS "SuperBuild - ${PROJECT_NAME} => Requires ITK")
+
+ExternalProject_Add(
+ ${PROJECT_NAME}
+ SOURCE_DIR ${CMAKE_SOURCE_DIR}
+ BINARY_DIR ${CMAKE_BINARY_DIR}/${PROJECT_NAME}-build
+ DOWNLOAD_COMMAND ""
+ UPDATE_COMMAND ""
+ CMAKE_CACHE_ARGS
+ -DITKPythonPackage_SUPERBUILD:BOOL=0
+ -DITK_BINARY_DIR:PATH=${ITK_BINARY_DIR}
+ -DITK_SOURCE_DIR:PATH=${ITK_SOURCE_DIR}
+ -DCMAKE_INSTALL_PREFIX:PATH=${CMAKE_INSTALL_PREFIX}
+ -DITKPythonPackage_WHEEL_NAME:STRING=${ITKPythonPackage_WHEEL_NAME}
+ -DITKPythonPackage_USE_TBB:BOOL=${ITKPythonPackage_USE_TBB}
+ ${ep_common_cmake_cache_args}
+ USES_TERMINAL_CONFIGURE 1
+ INSTALL_COMMAND ""
+ DEPENDS ITK
+)
+
+install(SCRIPT ${CMAKE_BINARY_DIR}/${PROJECT_NAME}-build/cmake_install.cmake)
+
+message(STATUS "SuperBuild - ${PROJECT_NAME}[OK]")
diff --git a/cmake/ITKPythonPackage_Utils.cmake b/cmake/ITKPythonPackage_Utils.cmake
new file mode 100644
index 00000000..5282b416
--- /dev/null
+++ b/cmake/ITKPythonPackage_Utils.cmake
@@ -0,0 +1,252 @@
+# ipp_ExternalProject_Add_Empty( )
+#
+# Add an empty external project
+#
+function(ipp_ExternalProject_Add_Empty proj depends)
+ set(depends_args)
+ if(NOT depends STREQUAL "")
+ set(depends_args DEPENDS ${depends})
+ endif()
+ ExternalProject_Add(
+ ${proj}
+ SOURCE_DIR ${CMAKE_BINARY_DIR}/${proj}
+ DOWNLOAD_COMMAND ""
+ UPDATE_COMMAND ""
+ CONFIGURE_COMMAND ""
+ BUILD_COMMAND ""
+ BUILD_IN_SOURCE 1
+ BUILD_ALWAYS 1
+ INSTALL_COMMAND "" ${depends_args}
+ )
+endfunction()
+
+# ipp_get_module_dependees( )
+#
+# Collect all modules depending on ````.
+#
+function(ipp_get_module_dependees itk-module output_var)
+ set(dependees "")
+ foreach(m_enabled IN LISTS ITK_MODULES_ENABLED)
+ list(FIND ITK_MODULE_${m_enabled}_DEPENDS ${itk-module} _index)
+ if(NOT _index EQUAL -1)
+ list(APPEND dependees ${m_enabled})
+ endif()
+ endforeach()
+ list(REMOVE_DUPLICATES dependees)
+ set(${output_var} ${dependees} PARENT_SCOPE)
+endfunction()
+
+function(_recursive_deps item-type item-category itk-item output_var)
+ set(_${itk-item}_deps)
+ foreach(dep IN LISTS ITK_${item-type}_${itk-item}_${item-category})
+ list(APPEND _${itk-item}_deps ${dep})
+ _recursive_deps(${item-type} ${item-category} ${dep} _${itk-item}_deps)
+ endforeach()
+ list(APPEND ${output_var} ${_${itk-item}_deps})
+ list(REMOVE_DUPLICATES ${output_var})
+ set(${output_var} ${${output_var}} PARENT_SCOPE)
+endfunction()
+
+# ipp_recursive_module_dependees( )
+#
+# Recursively collect all modules depending on ````.
+#
+function(ipp_recursive_module_dependees itk-module output_var)
+ set(_${itk-module}_deps)
+ _recursive_deps("MODULE" "DEPENDEES" ${itk-module} ${output_var})
+ set(${output_var} ${${output_var}} PARENT_SCOPE)
+endfunction()
+
+# ipp_is_module_leaf( )
+#
+# If ```` has no dependencies, set `` to 1
+# otherwise set `` to 0.
+#
+function(ipp_is_module_leaf itk-module output_var)
+ set(leaf 1)
+ foreach(m_enabled IN LISTS ITK_MODULES_ENABLED)
+ list(FIND ITK_MODULE_${m_enabled}_DEPENDS ${itk-module} _index)
+ if(NOT _index EQUAL -1)
+ set(leaf 0)
+ break()
+ endif()
+ endforeach()
+ set(${output_var} ${leaf} PARENT_SCOPE)
+endfunction()
+
+# ipp_is_module_python_wrapped( )
+#
+# If ```` is wrapped in python, set `` to 1
+# otherwise set `` to 0.
+#
+function(ipp_is_module_python_wrapped itk-module output_var)
+ set(wrapped 0)
+ if(NOT DEFINED ITK_MODULE_${itk-module}_GROUP)
+ message(
+ AUTHOR_WARNING
+ "Variable ITK_MODULE_${itk-module}_GROUP is not defined"
+ )
+ else()
+ set(group ${ITK_MODULE_${itk-module}_GROUP})
+ set(module_folder ${itk-module})
+ # if any, strip ITK prefix
+ if(module_folder MATCHES "^ITK.+$")
+ string(
+ REGEX REPLACE
+ "^ITK(.+)$"
+ "\\1"
+ module_folder
+ ${module_folder}
+ )
+ endif()
+ if(
+ EXISTS
+ ${ITK_SOURCE_DIR}/Modules/${group}/${itk-module}/wrapping/CMakeLists.txt
+ OR EXISTS
+ ${ITK_SOURCE_DIR}/Modules/${group}/${module_folder}/wrapping/CMakeLists.txt
+ )
+ set(wrapped 1)
+ endif()
+ endif()
+ set(${output_var} ${wrapped} PARENT_SCOPE)
+endfunction()
+
+# ipp_wheel_to_group( )
+#
+# Extract ITK group name from wheel name (e.g 'itk-core' -> 'Core').
+#
+# If the group name has less than 3 characters, take the uppercase
+# value (e.g 'itk-io' -> 'IO').
+#
+function(ipp_wheel_to_group wheel_name group_name_var)
+ string(REPLACE "itk-" "" _group ${wheel_name})
+ string(SUBSTRING ${_group} 0 1 _first)
+ string(TOUPPER ${_first} _first_uc)
+ string(SUBSTRING ${_group} 1 -1 _remaining)
+ set(group_name "${_first_uc}${_remaining}")
+ # Convert to upper case if length <= 2
+ string(LENGTH ${group_name} _length)
+ if(_length LESS 3)
+ string(TOUPPER ${group_name} group_name)
+ endif()
+ set(${group_name_var} ${group_name} PARENT_SCOPE)
+endfunction()
+
+# ipp_pad_text( )
+#
+# Example:
+#
+# set(row "Apple")
+# ipp_pad_text(${row} 20 row)
+#
+# set(row "${row}Banana")
+# ipp_pad_text(${row} 40 row)
+#
+# set(row "${row}Kiwi")
+# ipp_pad_text(${row} 60 row)
+#
+# message(${row})
+#
+# Output:
+#
+# Apple Banana Kiwi
+#
+function(ipp_pad_text text text_right_jusitfy_length output_var)
+ set(fill_char " ")
+ string(LENGTH "${text}" text_length)
+ math(EXPR pad_length "${text_right_jusitfy_length} - ${text_length} - 1")
+ if(pad_length GREATER 0)
+ string(RANDOM LENGTH ${pad_length} ALPHABET ${fill_char} text_dots)
+ set(${output_var} "${text} ${text_dots}" PARENT_SCOPE)
+ else()
+ set(${output_var} "${text}" PARENT_SCOPE)
+ endif()
+endfunction()
+
+# ipp_display_table_row( )
+#
+# Example:
+#
+# ipp_display_table_row("Apple^^Banana^^Kiwi" "20;20;20")
+# ipp_display_table_row("Eiger^^Rainer^^Sajama" "20;20;20")
+#
+# Output:
+#
+# Apple Banana Kiwi
+# Eiger Rainer Sajama
+#
+function(ipp_display_table_row values widths)
+ list(LENGTH values length)
+ set(text "")
+ math(EXPR range "${length} - 1")
+ foreach(index RANGE ${range})
+ list(GET widths ${index} width)
+ list(GET values ${index} value)
+ string(REPLACE "^^" ";" value "${value}")
+ ipp_pad_text("${value}" ${width} value)
+ set(text "${text}${value}")
+ endforeach()
+ message(STATUS "${text}")
+endfunction()
+
+# ipp_list_to_string( )
+#
+# Example:
+#
+# set(values Foo Bar Oof)
+# message("${values}")
+# ipp_list_to_string("^^" "${values}" values)
+# message("${values}")
+#
+# Output:
+#
+# Foo;Bar;Oof
+# Foo^^Bar^^Oof
+#
+# Copied from Slicer/CMake/ListToString.cmake
+#
+function(ipp_list_to_string separator input_list output_string_var)
+ set(_string "")
+ # Get list length
+ list(LENGTH input_list list_length)
+ # If the list has 0 or 1 element, there is no need to loop over.
+ if(list_length LESS 2)
+ set(_string "${input_list}")
+ else()
+ math(EXPR last_element_index "${list_length} - 1")
+ foreach(index RANGE ${last_element_index})
+ # Get current item_value
+ list(GET input_list ${index} item_value)
+ if(NOT item_value STREQUAL "")
+ # .. and append non-empty value to output string
+ set(_string "${_string}${item_value}")
+ # Append separator if current element is NOT the last one.
+ if(NOT index EQUAL last_element_index)
+ set(_string "${_string}${separator}")
+ endif()
+ endif()
+ endforeach()
+ endif()
+ set(${output_string_var} ${_string} PARENT_SCOPE)
+endfunction()
+
+# No-op function allowing to shut-up "Manually-specified variables were not used by the project"
+# warnings.
+function(ipp_unused_vars)
+endfunction()
+
+#
+# Unused
+#
+
+function(recursive_module_deps itk-module output_var)
+ set(_${itk-module}_deps)
+ _recursive_deps("MODULE" "DEPENDS" ${itk-module} ${output_var})
+ set(${output_var} ${${output_var}} PARENT_SCOPE)
+endfunction()
+
+function(recursive_group_deps itk-group output_var)
+ set(_${itk-group}_deps)
+ _recursive_deps("GROUP" "DEPENDS" ${itk-group} ${output_var})
+ set(${output_var} ${${output_var}} PARENT_SCOPE)
+endfunction()
diff --git a/conda-forge/README.md b/conda-forge/README.md
new file mode 100644
index 00000000..140624c7
--- /dev/null
+++ b/conda-forge/README.md
@@ -0,0 +1,36 @@
+# conda-forge Submission
+
+This directory contains recipe files for submitting ITK packages to conda-forge
+via [staged-recipes](https://github.com/conda-forge/staged-recipes).
+
+## Packages
+
+### libitk-wrapping
+
+A conda package containing ITK C++ libraries with full Python wrapping
+artifacts (SWIG interfaces, CastXML outputs, compiled Python modules).
+This package enables building ITK Python wheels and remote module wheels
+without recompiling ITK from source.
+
+### Submission Process
+
+1. Fork [conda-forge/staged-recipes](https://github.com/conda-forge/staged-recipes)
+2. Copy `libitk-wrapping/` into `recipes/libitk-wrapping/`
+3. Open a PR against staged-recipes
+4. Address conda-forge review feedback
+5. Once merged, a feedstock will be created automatically
+
+### Updating the existing libitk feedstock
+
+The existing [libitk-feedstock](https://github.com/conda-forge/libitk-feedstock)
+(currently at v5.4.5) should be updated to ITK 6 separately. The `libitk-wrapping`
+package will depend on `libitk-devel` once both are at ITK 6.
+
+## Environment Variables for Custom Builds
+
+When building from a non-default ITK branch (e.g., for PR testing):
+
+```bash
+export ITK_GIT_URL="https://github.com/BRAINSia/ITK.git"
+export ITK_GIT_TAG="itk-conda-pythonpackage-support"
+```
diff --git a/conda-forge/libitk-wrapping/bld.bat b/conda-forge/libitk-wrapping/bld.bat
new file mode 100644
index 00000000..cce966e5
--- /dev/null
+++ b/conda-forge/libitk-wrapping/bld.bat
@@ -0,0 +1,60 @@
+@echo off
+setlocal enabledelayedexpansion
+
+set BUILD_DIR=%SRC_DIR%\..\build
+mkdir %BUILD_DIR%
+cd %BUILD_DIR%
+
+cmake ^
+ -G "Ninja" ^
+ %CMAKE_ARGS% ^
+ -D BUILD_SHARED_LIBS:BOOL=ON ^
+ -D BUILD_TESTING:BOOL=OFF ^
+ -D BUILD_EXAMPLES:BOOL=OFF ^
+ -D CMAKE_BUILD_TYPE:STRING=Release ^
+ -D "CMAKE_INSTALL_PREFIX=%LIBRARY_PREFIX%" ^
+ ^
+ -D ITK_WRAP_PYTHON:BOOL=ON ^
+ -D ITK_WRAP_DOC:BOOL=ON ^
+ -D ITK_LEGACY_SILENT:BOOL=ON ^
+ -D CMAKE_POSITION_INDEPENDENT_CODE:BOOL=ON ^
+ ^
+ -D ITK_WRAP_unsigned_short:BOOL=ON ^
+ -D ITK_WRAP_double:BOOL=ON ^
+ -D ITK_WRAP_complex_double:BOOL=ON ^
+ -D "ITK_WRAP_IMAGE_DIMS:STRING=2;3;4" ^
+ ^
+ -D WRAP_ITK_INSTALL_COMPONENT_IDENTIFIER:STRING=PythonWheel ^
+ -D WRAP_ITK_INSTALL_COMPONENT_PER_MODULE:BOOL=ON ^
+ ^
+ -D ITK_USE_SYSTEM_EXPAT:BOOL=ON ^
+ -D ITK_USE_SYSTEM_HDF5:BOOL=ON ^
+ -D ITK_USE_SYSTEM_JPEG:BOOL=ON ^
+ -D ITK_USE_SYSTEM_PNG:BOOL=ON ^
+ -D ITK_USE_SYSTEM_TIFF:BOOL=ON ^
+ -D ITK_USE_SYSTEM_ZLIB:BOOL=ON ^
+ -D ITK_USE_SYSTEM_FFTW:BOOL=ON ^
+ -D ITK_USE_SYSTEM_EIGEN:BOOL=ON ^
+ -D ITK_USE_FFTWD:BOOL=ON ^
+ -D ITK_USE_FFTWF:BOOL=ON ^
+ ^
+ -D ITK_BUILD_DEFAULT_MODULES:BOOL=ON ^
+ -D Module_ITKReview:BOOL=ON ^
+ -D Module_ITKTBB:BOOL=ON ^
+ -D Module_MGHIO:BOOL=ON ^
+ -D Module_ITKIOTransformMINC:BOOL=ON ^
+ -D Module_GenericLabelInterpolator:BOOL=ON ^
+ -D Module_AdaptiveDenoising:BOOL=ON ^
+ ^
+ -D ITK_USE_KWSTYLE:BOOL=OFF ^
+ -D "ITK_DEFAULT_THREADER:STRING=Pool" ^
+ ^
+ "%SRC_DIR%"
+
+if errorlevel 1 exit /b 1
+
+cmake --build . --config Release
+if errorlevel 1 exit /b 1
+
+cmake --install . --config Release
+if errorlevel 1 exit /b 1
diff --git a/conda-forge/libitk-wrapping/build.sh b/conda-forge/libitk-wrapping/build.sh
new file mode 100755
index 00000000..48a9f657
--- /dev/null
+++ b/conda-forge/libitk-wrapping/build.sh
@@ -0,0 +1,86 @@
+#!/bin/bash
+set -euo pipefail
+
+# Build ITK C++ with Python wrapping for conda-forge.
+# Produces headers, shared libraries, CMake config, and all wrapping
+# metadata (SWIG .i/.idx/.mdx, Python stubs) needed by downstream
+# ITK remote modules.
+
+BUILD_DIR="${SRC_DIR}/../build"
+mkdir -p "${BUILD_DIR}"
+cd "${BUILD_DIR}"
+
+# TBB: enabled on Linux, disabled on macOS (conda TBB issues)
+use_tbb=ON
+if [ "$(uname)" = "Darwin" ]; then
+ use_tbb=OFF
+fi
+
+# Cross-compilation support
+if [[ "${CONDA_BUILD_CROSS_COMPILATION:-0}" == "1" ]]; then
+ try_run_results="${RECIPE_DIR}/TryRunResults-${target_platform}.cmake"
+ if [[ -f "${try_run_results}" ]]; then
+ CMAKE_ARGS="${CMAKE_ARGS} -C ${try_run_results}"
+ fi
+fi
+
+cmake \
+ -G "Ninja" \
+ ${CMAKE_ARGS} \
+ -D BUILD_SHARED_LIBS:BOOL=ON \
+ -D BUILD_TESTING:BOOL=OFF \
+ -D BUILD_EXAMPLES:BOOL=OFF \
+ -D CMAKE_BUILD_TYPE:STRING=Release \
+ -D "CMAKE_INSTALL_PREFIX=${PREFIX}" \
+ \
+ -D ITK_WRAP_PYTHON:BOOL=ON \
+ -D ITK_WRAP_DOC:BOOL=ON \
+ -D ITK_LEGACY_SILENT:BOOL=ON \
+ -D CMAKE_POSITION_INDEPENDENT_CODE:BOOL=ON \
+ \
+ -D ITK_WRAP_unsigned_short:BOOL=ON \
+ -D ITK_WRAP_double:BOOL=ON \
+ -D ITK_WRAP_complex_double:BOOL=ON \
+ -D "ITK_WRAP_IMAGE_DIMS:STRING=2;3;4" \
+ \
+ -D WRAP_ITK_INSTALL_COMPONENT_IDENTIFIER:STRING=PythonWheel \
+ -D WRAP_ITK_INSTALL_COMPONENT_PER_MODULE:BOOL=ON \
+ \
+ -D ITK_USE_SYSTEM_EXPAT:BOOL=ON \
+ -D ITK_USE_SYSTEM_HDF5:BOOL=ON \
+ -D ITK_USE_SYSTEM_JPEG:BOOL=ON \
+ -D ITK_USE_SYSTEM_PNG:BOOL=ON \
+ -D ITK_USE_SYSTEM_TIFF:BOOL=ON \
+ -D ITK_USE_SYSTEM_ZLIB:BOOL=ON \
+ -D ITK_USE_SYSTEM_FFTW:BOOL=ON \
+ -D ITK_USE_SYSTEM_EIGEN:BOOL=ON \
+ -D ITK_USE_FFTWD:BOOL=ON \
+ -D ITK_USE_FFTWF:BOOL=ON \
+ \
+ -D ITK_BUILD_DEFAULT_MODULES:BOOL=ON \
+ -D Module_ITKReview:BOOL=ON \
+ -D Module_ITKTBB:BOOL=${use_tbb} \
+ -D Module_MGHIO:BOOL=ON \
+ -D Module_ITKIOTransformMINC:BOOL=ON \
+ -D Module_GenericLabelInterpolator:BOOL=ON \
+ -D Module_AdaptiveDenoising:BOOL=ON \
+ \
+ -D ITK_USE_KWSTYLE:BOOL=OFF \
+ -D NIFTI_SYSTEM_MATH_LIB= \
+ -D GDCM_USE_COREFOUNDATION_LIBRARY:BOOL=OFF \
+ -D "ITK_DEFAULT_THREADER:STRING=Pool" \
+ \
+ -D "CMAKE_FIND_ROOT_PATH:PATH=${PREFIX}" \
+ -D "CMAKE_FIND_ROOT_PATH_MODE_INCLUDE:STRING=ONLY" \
+ -D "CMAKE_FIND_ROOT_PATH_MODE_LIBRARY:STRING=ONLY" \
+ -D "CMAKE_FIND_ROOT_PATH_MODE_PROGRAM:STRING=NEVER" \
+ -D "CMAKE_FIND_ROOT_PATH_MODE_PACKAGE:STRING=ONLY" \
+ -D "CMAKE_FIND_FRAMEWORK:STRING=NEVER" \
+ -D "CMAKE_FIND_APPBUNDLE:STRING=NEVER" \
+ -D "CMAKE_PROGRAM_PATH=${BUILD_PREFIX}" \
+ \
+ "${SRC_DIR}"
+
+cmake --build . --config Release
+
+cmake --install . --config Release
diff --git a/conda-forge/libitk-wrapping/meta.yaml b/conda-forge/libitk-wrapping/meta.yaml
new file mode 100644
index 00000000..cbbd755f
--- /dev/null
+++ b/conda-forge/libitk-wrapping/meta.yaml
@@ -0,0 +1,73 @@
+{% set version = "6.0.0" %}
+{% set itk_tag = "v" + version %}
+
+package:
+ name: libitk-wrapping
+ version: {{ version }}
+
+source:
+ url: https://github.com/InsightSoftwareConsortium/ITK/archive/{{ itk_tag }}.tar.gz
+ # sha256: UPDATE_WITH_ACTUAL_HASH
+
+build:
+ number: 0
+ skip: true # [win and vc<14]
+
+requirements:
+ build:
+ - cmake >=3.26
+ - ninja
+ - {{ compiler('c') }}
+ - {{ stdlib("c") }}
+ - {{ compiler('cxx') }}
+ host:
+ - python
+ - swig >=4.1
+ - castxml
+ - expat # [not win]
+ - hdf5
+ - libjpeg-turbo
+ - libtiff
+ - libpng # [not win]
+ - eigen
+ - zlib # [not win]
+ - fftw
+ - tbb-devel
+ - doxygen
+ run:
+ - python
+ - tbb
+ - hdf5
+ - fftw
+ - libjpeg-turbo
+ - libtiff
+ - libpng # [not win]
+ - expat # [not win]
+ - zlib # [not win]
+
+test:
+ commands:
+ # Verify CMake config is installed and discoverable
+ - test -d $PREFIX/lib/cmake/ITK* # [not win]
+ - if not exist %LIBRARY_LIB%\\cmake\\ITK* exit 1 # [win]
+ # Verify Python wrapping modules are installed
+ - test -f $PREFIX/lib/python*/site-packages/itk/__init__.py # [not win]
+ # Verify wrapping metadata is installed
+ - test -d $PREFIX/lib/cmake/ITK*/WrapITK/Typedefs # [not win]
+
+about:
+ home: https://itk.org
+ license: Apache-2.0
+ license_file:
+ - LICENSE
+ - NOTICE
+ summary: >
+ ITK C++ libraries with Python wrapping artifacts for building
+ ITK Python wheels and remote module packages.
+ dev_url: https://github.com/InsightSoftwareConsortium/ITK
+
+extra:
+ recipe-maintainers:
+ - hjmjohnson
+ - thewtex
+ - blowekamp
diff --git a/docs/Build_ITK_Module_Python_packages.rst b/docs/Build_ITK_Module_Python_packages.rst
index dd88d7b9..2abdcfc8 100644
--- a/docs/Build_ITK_Module_Python_packages.rst
+++ b/docs/Build_ITK_Module_Python_packages.rst
@@ -1,238 +1,394 @@
=====================================
-Build ITK Module Python packages
-======================================
-
-ITK is organized into *modules*. Modules for ITK can be developed outside the
-ITK source tree as *remote modules*. The *remote module* can be made
-available in ITK's `CMake `_ configuration by
-`contributing it
-`_
-as a *remote module*. Python packages can also be generated for remote
-modules and uploaded to the `Python Package Index (PyPI) `_
-
-This section describes how to create, build, and upload ITK remote
-module Python packages to PyPI.
+Build ITK Module Python Packages
+=====================================
+ITK is organized into *modules*. Community members can extend ITK by developing
+an ITK *external module* in a separate repository. When a module meets community
+standards for documentation and maintenance it may be included in the ITK build
+as a *remote module*.
-.. include:: Prerequisites.rst
+This section describes how to create, build, and publish Python packages for
+ITK remote and external modules to PyPI.
-Create the module
-=================
+Create a Module
+===============
-To create an ITK module with Python wrapping, first run cookiecutter::
+To scaffold a new ITK module with Python wrapping, use the official template::
python -m pip install cookiecutter
python -m cookiecutter gh:InsightSoftwareConsortium/ITKModuleTemplate
# Fill in the information requested at the prompts
+Fill in the prompts, then add your C++ filter classes. See
+`Chapter 9 of the ITK Software Guide
+`_
+for guidance on populating the module and writing ``.wrap`` files for SWIG.
+
-Then, add your classes. Reference documentation on `how to populate the module
-`_
-can be found in the `ITK Software Guide
-`_.
+GitHub Actions Workflows
+==============================
+For most ITK external modules, the recommended and easiest path to building, testing, and
+publishing Python wheels is the
+`ITKRemoteModuleBuildTestPackageAction
+`_
+reusable workflow. It handles fetching, configuring, and running
+ITKPythonPackage build scripts automatically.
-GitHub automated CI package builds
-==================================
+Every pull request and push triggers a build that:
-Freely available GitHub Actions continous integration (CI) build and test
-services for open source repositories are provided by
-`GitHub `_. These services will build and test the C++
-code for your module and also generate Linux, macOS, and Windows Python
-packages for your module.
+- Compiles and runs your module's C++ tests
+- Generates Linux, macOS, and Windows Python wheels
-For every pull request and push to the GitHub repository, a GitHub Action will
-run that builds and runs the repository's C++ tests and reports the results to
-the `ITK CDash Dashboard `_.
-Python packages are also generated for every commit. Packages for a commit's
-build can be downloaded from the GitHub Action result page in the *Artifacts*
-Section.
+Wheel artifacts are downloadable from the **Artifacts** section of the
+GitHub Actions run page.
.. figure:: images/GitHubActionArtifacts.png
- :alt: GitHub Action Artifacts
+ :alt: GitHub Action Artifacts
-Reusable workflows available in
-[ITKRemoteModuleBuildTestPackageAction](https://github.com/InsightSoftwareConsortium/ITKRemoteModuleBuildTestPackageAction)
-can be used to handle the build-test-package process
-for a majority of ITK external modules with minimal extra development.
+To pin the specific ITKPythonPackage version used by the workflow (defaults are shown below):
-Upload the packages to PyPI
-----------------------------
+.. code-block:: yaml
-First, `register for an account on PyPI `_.
+ uses: InsightSoftwareConsortium/ITKRemoteModuleBuildTestPackageAction/.github/workflows/build-test-package.yml@v5.4.5
+ with:
+ itk-python-package-org: InsightSoftwareConsortium
+ itk-python-package-tag: main
-Next, create a `~/.pypirc` file with your login credentials::
+.. include:: Prerequisites.rst
- [distutils]
- index-servers =
- pypi
- pypitest
+Manual Builds
+=============
- [pypi]
- username=
- password=
+For cases where the reusable workflow is not a good fit, the
+download-and-build scripts can be run locally. Each script:
- [pypitest]
- repository=https://test.pypi.org/legacy/
- username=
- password=
+1. Downloads and installs the necessary build packages
+2. Downloads the pre-built ITK binary tarball for the target platform from
+ `ITKPythonBuilds `_
+3. Extracts it to a local build directory
+4. Builds your module wheels against the pre-built ITK
-where `` and `` correspond to your PyPI account.
+.. important::
+ Place and run the script from your module's root directory. Or specify exact paths using the environment variables below
-Then, upload wheels to the testing server. The wheels of dist/* are those that
-you have built locally or have downloaded from a recent build listed at
-`https://github.com/InsightSoftwareConsortium//actions`.
-::
+Set the ITK PEP 440 compliant version before running any script::
- python -m pip install twine
- python -m twine upload -r pypitest dist/*
+ export ITK_PACKAGE_VERSION=v6.0b01 # Linux / macOS
+ $env:ITK_PACKAGE_VERSION = "v6.0b01" # Windows PowerShell
-Check out the packages on ``_ the testing server.
+Linux (manylinux)
+-----------------
-Finally, upload the wheel packages to the production PyPI server::
+Requires Docker. Produces ``manylinux_2_28`` portable wheels.
- python -m twine upload dist/*
+.. code-block:: bash
-Congratulations! Your packages can be installed with the commands::
+ cd ~/ITKMyModule
+ # First build — downloads ITK cache, then builds module wheels
+ export MODULE_SRC_DIRECTORY=/path/to/module
+ bash ITKPythonPackage/scripts/dockcross-manylinux-download-cache-and-build-module-wheels.sh cp310
- python -m pip install --upgrade pip
- python -m pip install itk-
+ # Subsequent builds — reuses the downloaded cache
+ bash ITKPythonPackage/scripts/dockcross-manylinux-build-module-wheels.sh cp310
-where `itk-` is the short name for your module that is
-specified in the configured `pyproject.toml` file.
+Omit the Python version argument to build all supported versions (cp310 and cp311):
-Automate PyPI Package Uploads
------------------------------
+.. code-block:: bash
-Automated uploads of Python packages to the Python package index, `PyPI
-`_ will occur after adding a PyPI upload token to GitHub and
-creating a Git tag. Create a PyPI API token by logging in to
-``_. Generally, for the token name
-use::
+ export MODULE_SRC_DIRECTORY=/path/to/module
+ bash ITKPythonPackage/scripts/dockcross-manylinux-download-cache-and-build-module-wheels.sh
- itk--github-action
+macOS
+-----
-and for the scope use::
+.. code-block:: bash
- itk-
+ cd ~/ITKMyModule
+ export MODULE_SRC_DIRECTORY=/path/to/module
+ bash ITKPythonPackage/scripts/macpython-download-cache-and-build-module-wheels.sh 3.10 3.11
-where `` is the short name for your module that is
-specified in your configured `pyproject.toml` file. That scope will be available if you have
-already uploaded a first set of wheels via twine as described above; and that
-is the recommended approach. Otherwise, if you are creating the project at
-this time, choose an unlimited scope, but be careful with the created token.
+Windows
+-------
-.. figure:: images/PyPIToken.png
- :alt: PyPI Token
+Open a PowerShell terminal:
+
+.. code-block:: powershell
+
+ cd C:\ITKMyModule
+ $env:ITK_PACKAGE_VERSION = "v6.0b01"
+ $env:MODULE_SRC_DIRECTORY = /path/to/module
+ .\ITKPythonPackage\scripts\windows-download-cache-and-build-module-wheels.ps1 -python_version_minor 10
+
+Build multiple Python versions:
+
+.. code-block:: powershell
+
+ foreach ($v in @(10, 11)) {
+ .\ITKPythonPackage\scripts\windows-download-cache-and-build-module-wheels.ps1 -python_version_minor $v
+ }
+
+.. important::
+ Use a short build path (e.g. ``C:\BDR``) to avoid Windows 260-character
+ path length limits. See the Troubleshooting section in
+ :doc:`Build_ITK_Python_packages` for details.
+
+Key environment variables:
+
+.. list-table::
+ :header-rows: 1
+ :widths: 30 20 50
+
+ * - Variable
+ - Default
+ - Description
+ * - ``ITK_PACKAGE_VERSION``
+ - ``v6.0b01``
+ - PEP 440 ITK release to build against
+ * - ``TARGET_ARCH``
+ - ``x64``
+ - ``x64`` or ``aarch64``
+ * - ``IMAGE_TAG``
+ - ``20250913-6ea98ba``
+ - Dockcross Docker image tag
+ * - ``MODULE_SRC_DIRECTORY``
+ - script directory
+ - Path to your module source
+ * - ``MODULE_DEPS_DIR``
+ - platform dependant
+ - Root directory for module dependency checkouts
+ * - ``DASHBOARD_BUILD_DIRECTORY``
+ - platform dependant
+ - Root directory for build artifacts
+ * - ``MANYLINUX_VERSION``
+ - ``_2_28``
+ - Manylinux compatibility standard
+ * - ``CMAKE_OPTIONS``
+ - *(empty)*
+ - Extra CMake ``-D`` definitions
+ * - ``ITKPYTHONPACKAGE_TAG``
+ - ``main``
+ - ITKPythonPackage branch/tag to fetch
+ * - ``ITKPYTHONPACKAGE_ORG``
+ - ``InsightSoftwareConsortium``
+ - ITKPythonPackage organization to fetch
+ * - ``NO_SUDO``
+ - *(unset)*
+ - Set to skip ``sudo`` for Docker commands
+ * - ``DYLD_LIBRARY_PATH``
+ - *(unset)*
+ - Extra library paths to bundle into wheels
-Then, add the API token to the GitHub repository
-`https://github.com/InsightSoftwareConsortium/`. Choose
-the *Settings -> Secrets* page and add a key called *pypi_password*, setting
-the password to be the token string that begins with `pypi-`. Note that this
-will be a *token* instead of a password. Limit the scope of the token to the
-individual package as a best practice.
-.. figure:: images/GitHubPyPISecret.png
- :alt: GitHub PyPI token secret
+Use the Build Script Directly
+====================================
-To push packages to PyPI, first, make sure to update the `version` for your
-package in the *pyproject.toml* file. The initial version might be `0.1.0` or
-`1.0.0`. Subsequent versions should follow
-`semantic versioning `_.
+For more control over build option, call ``build_wheels.py`` directly with
+``--module-source-dir``. This approach will create a local ITK build by default:
-Then, create a Git tag corresponding to the version. A Git tag can be created
-in the GitHub user interface via *Releases -> Draft a new release*.
+.. code-block:: bash
-.. figure:: images/GitHubReleaseTag.png
- :alt: GitHub Release Tag
+ pixi run python3 scripts/build_wheels.py \
+ --platform-env macosx-py310 \
+ --itk-git-tag v6.0b01 \
+ --module-source-dir /path/to/ITKMyModule \
+ --no-skip-itk-build \
+ --no-skip-itk-wheel-build \
+ --no-build-itk-tarball-cache
-Automated platform scripts
-==========================
+.. _accelerated-builds:
-Automated scripts are available in this repository to build Python packages
-that are binary compatible with the Python distributions provided by
-Python.org, Anaconda, and package managers like apt or Homebrew.
-The following sections outline how to use the associated scripts for Linux,
-macOS, and Windows.
+Accelerated Builds with libitk-wrapping (pixi-build)
+=====================================================
-Once the builds are complete, Python packages will be available in the `dist`
-directory.
+When ITK is pre-installed in the conda/pixi environment via the
+``libitk-wrapping`` package, the build system automatically skips the
+expensive ITK C++ compilation (steps 01 and 02). This reduces remote
+module build times from ~1-2 hours to ~15 minutes.
-Linux
------
+To use this workflow, first build and install the ``libitk-wrapping``
+package:
-To build portable Python packages on Linux, first `install Docker
-`_.
+.. code-block:: bash
-For the first local build, clone the `ITKPythonPackage` repository inside your
-and download the required ITK binary builds::
+ cd packages/libitk-wrapping
+ pixi build
- cd ~/ITKMyModule
- git clone https://github.com/InsightSoftwareConsortium/ITKPythonPackage
- ./ITKPythonPackage/scripts/dockcross-manylinux-download-cache-and-build-module-wheels.sh
+Then build your module wheel — ITK will be detected automatically:
-For subsequent builds, just call the build script::
+.. code-block:: bash
- ./ITKPythonPackage/scripts/dockcross-manylinux-build-module-wheels.sh
+ pixi run -e linux-py311 python scripts/build_wheels.py \
+ --platform-env linux-py311 \
+ --module-source-dir /path/to/ITKMyModule \
+ --skip-itk-build \
+ --skip-itk-wheel-build \
+ --no-build-itk-tarball-cache
-macOS
------
+The detection checks ``CONDA_PREFIX`` and ``PIXI_ENVIRONMENT_DIR`` for
+``lib/cmake/ITK-*/ITKConfig.cmake``. When found, the console will print::
-First, install the Python.org macOS Python distributions. This step requires sudo::
+ Detected conda-installed ITK at (via $CONDA_PREFIX)
+ Using conda-installed ITK; skipping superbuild and C++ build steps.
- cd ~/ITKMyModule
- git clone https://github.com/InsightSoftwareConsortium/ITKPythonPackage
- ./ITKPythonPackage/scripts/macpython-install-python.sh
+To override the ITK source repository and tag for the ``libitk-wrapping``
+build (e.g., to test a feature branch):
-Then, build the wheels::
+.. code-block:: bash
- ./ITKPythonPackage/scripts/macpython-build-wheels.sh
+ export ITK_GIT_URL="https://github.com/MyOrg/ITK.git"
+ export ITK_GIT_TAG="my-feature-branch"
+ cd packages/libitk-wrapping
+ pixi build
-Windows
--------
-First, install Microsoft Visual Studio 2022, Git, and CMake, which should be added to the system PATH environmental variable.
+Module Dependencies
+===================
+
+If your module depends on other ITK external modules, list them with
+``--itk-module-deps`` (or the ``ITK_MODULE_PREQ`` environment variable for the
+shell scripts):
+
+.. code-block:: bash
+
+ pixi run python3 scripts/build_wheels.py \
+ --platform-env macosx-py310 \
+ --itk-git-tag v6.0b01 \
+ --module-source-dir /path/to/ITKMyModule \
+ --itk-module-deps "InsightSoftwareConsortium/ITKMeshToPolyData@v1.0.0" \
+ --no-build-itk-tarball-cache
+
+For multiple dependencies, separate them with colons in **dependency order**
+(each module listed before the modules that depend on it):
+
+.. code-block:: bash
+
+ --itk-module-deps "org/ITKModA@v1.0:org/ITKModB@v2.1:org/ITKModC@main"
+
+The format for each entry is ``/@``.
+
+For the download-and-build shell scripts, set ``ITK_MODULE_PREQ`` instead:
+
+.. code-block:: bash
+
+ export ITK_MODULE_PREQ="org/ITKModA@v1.0:org/ITKModB@v2.1"
+ bash ITKPythonPackage/scripts/dockcross-manylinux-download-cache-and-build-module-wheels.sh cp310
+
+Dependencies are cloned to ``/`` before the
+main module build begins.
+
+
+Third-Party Libraries
+=====================
+
+If your module links against a third-party library that is not part of ITK,
+the wheel repair tools (``auditwheel``, ``delocate``, ``delvewheel``) need
+to be able to find it to bundle it into the wheel.
+
+**Linux**: add the library's directory to ``LD_LIBRARY_PATH`` before running
+the build script::
+
+ export LD_LIBRARY_PATH=/path/to/mylib/lib:$LD_LIBRARY_PATH
+
+**macOS**: add the directory to ``DYLD_LIBRARY_PATH``::
+
+ export DYLD_LIBRARY_PATH=/path/to/mylib/lib:$DYLD_LIBRARY_PATH
+
+**Windows**: pass the library directory via ``--lib-paths`` (or the
+``-setup_options`` parameter of the PowerShell script):
+
+.. code-block:: powershell
+
+ .\windows-download-cache-and-build-module-wheels.ps1 `
+ -python_version_minor 10 `
+ -setup_options "--exclude-libs nvcuda.dll"
+
+
+Output
+======
+
+Finished wheels are placed in ``dist/`` inside your module directory
+(or ``/dist/`` when running ``build_wheels.py`` directly).
+
+Example output::
+
+ dist/
+ itk-mymodule-1.0.0-cp310-cp310-manylinux_2_28_x86_64.whl
+ itk-mymodule-1.0.0-cp310-cp310-macosx_13_0_arm64.whl
+ itk-mymodule-1.0.0-cp310-cp310-win_amd64.whl
+
+
+Uploading to PyPI
+=================
+
+Using the Publish Environment
+-----------------------------
+
+ITKPythonPackage provides a ``publish`` Pixi environment with ``twine``
+pre-configured. Set your PyPI credentials (see ``.pypirc.example`` in the
+repository root) and run:
+
+.. code-block:: bash
+
+ export TWINE_USERNAME=__token__
+ export TWINE_PASSWORD=pypi-
+
+ # Test on TestPyPI first
+ pixi run -e publish publish-wheels \
+ --dist-directory /path/to/module/dist \
+ --test
+
+ # Then upload to production PyPI
+ pixi run -e publish publish-wheels \
+ --dist-directory /path/to/module/dist
+
+Pass ``--skip-existing`` to skip already-uploaded wheels when re-running after
+a partial upload failure.
+
+Manual Upload
+-------------
+
+Alternatively, install and use ``twine`` directly.
+
+Test on TestPyPI first::
+
+ pip install twine
+ twine upload -r testpypi dist/*.whl
+
+Then upload to production PyPI::
-Open a PowerShell terminal as Administrator, and install Python::
+ twine upload dist/*.whl
- PS C:\> Set-ExecutionPolicy Unrestricted
- PS C:\> $pythonArch = "64"
- PS C:\> iex ((new-object net.webclient).DownloadString('https://raw.githubusercontent.com/scikit-build/scikit-ci-addons/master/windows/install-python.ps1'))
+Your package can then be installed with::
-In a PowerShell prompt, run the `windows-build-wheels.ps1` script::
+ pip install itk-
- PS C:\Windows> cd C:\ITKMyModule
- PS C:\ITKMyModule> git clone https://github.com/InsightSoftwareConsortium/ITKPythonPackage.git IPP
- PS C:\ITKMyModule> .\ITKPythonPackage\scripts\windows-download-cache-and-build-module-wheels.ps1
+Automated Upload via GitHub Actions
+-------------------------------------
-Other Notes
------------
+To automate publishing on every tagged release:
-ITK modules sometimes depend on third-party libraries. To include third-party libraries
-in development wheels for distribution, first add the library path to `LD_LIBRARY_PATH`
-on Linux, `DYLD_LIBRARY_PATH` on MacOS, or `PATH` on Windows. Then, run the platform
-build script.
+1. Create a PyPI API token at ``_.
+ Name it ``itk--github-action`` and scope it to your
+ package (scope becomes available after the first manual upload).
-ITK modules sometimes depend on other ITK modules. For instance, to build
-[ITKBSplineGradient](https://github.com/InsightSoftwareConsortium/ITKBSplineGradient)
-the user must first build ITK and then [ITKMeshToPolyData](https://github.com/InsightSoftwareConsortium/ITKmeshtopolydata).
-ITKPythonPackage scripts support iterative prerequisite ITK module dependencies with the `ITK_MODULE_PREQ`
-environment variable.
+ .. figure:: images/PyPIToken.png
+ :alt: PyPI Token
-For Python build scripts, the ordered list of ITK module dependencies must be formatted as follows:
+2. In your GitHub repository, go to **Settings → Secrets → Actions** and
+ add a secret named ``pypi_password`` with the token value (starts with
+ ``pypi-``).
-```
-ITK_MODULE_PREQ=/@:/@:...
-```
+ .. figure:: images/GitHubPyPISecret.png
+ :alt: GitHub PyPI token secret
-Where
-- `module_org` is the name of a Github organization to use to fetch the module, i.e. "InsightSoftwareConsortium";
-- `module_name` is the name of the module, i.e. "ITKMeshToPolyData";
-- `module_tag` is the git tag or commit hash to use to fetch the module, i.e. "v1.0.0"
+3. Create a GitHub Release (via **Releases → Draft a new release**).
+ The tag name should match the version in your ``pyproject.toml``.
-Module names must be provided in order of dependencies for the build to succeed.
+ .. figure:: images/GitHubReleaseTag.png
+ :alt: GitHub Release Tag
-For more information see the
-[build scripts directory](https://github.com/InsightSoftwareConsortium/ITKPythonPackage/tree/master/scripts).
+The ``ITKRemoteModuleBuildTestPackageAction`` workflow will detect the tag
+and upload wheels automatically.
diff --git a/docs/Build_ITK_Python_packages.rst b/docs/Build_ITK_Python_packages.rst
index bb0d647c..781bc61d 100644
--- a/docs/Build_ITK_Python_packages.rst
+++ b/docs/Build_ITK_Python_packages.rst
@@ -1,14 +1,13 @@
-======================================
-Build ITK Python packages
-======================================
+==============================
+Build ITK Python Packages
+==============================
-This section describes how to builds ITK's Python packages. In most cases, the
-:ref:`pre-built ITK binary wheels can be used `.
-
-ITK Python packages are built nightly on Kitware build systems and uploaded to
-the `ITKPythonPackage GitHub releases page
-`_.
+This section describes how to build ITK's core Python wheels
+(``itk-core``, ``itk-numerics``, ``itk-io``, ``itk-filtering``,
+``itk-registration``, ``itk-segmentation``, and ``itk-meta``). In most cases, the pre-built ITK binary wheels can be used.
+You may only need to build ITK from source if you need a custom patch, a specific unreleased
+commit, or are developing ITK core itself.
.. include:: Prerequisites.rst
@@ -18,115 +17,469 @@ Automated platform scripts
Steps required to build wheels on Linux, macOS and Windows have been
automated. The following sections outline how to use the associated scripts.
-Linux
------
-On any linux distribution with docker and bash installed, running the script dockcross-manylinux-build-wheels.sh will create 64-bit wheels for python 3.9+ in the dist directory.
+Overview
+========
-For example::
+The build is driven by ``scripts/build_wheels.py``, which orchestrates up to
+seven sequential steps:
- $ git clone https://github.com/InsightSoftwareConsortium/ITKPythonPackage.git
- [...]
+1. Build SuperBuild support components (oneTBB and other ITK dependencies)
+2. Build ITK C++ with Python wrapping
+3. Build Python wheels for each ITK subpackage
+4. Fix up wheels if platform requires (``auditwheel`` / ``delocate`` / ``delvewheel``)
+5. Import test
+6. *(optional)* Build a remote module against the ITK build
+7. *(optional)* Create a reusable ITK build tarball cache
- $ ./scripts/dockcross-manylinux-build-wheels.sh
- [...]
+Step state is persisted to ``/dist/build_report-.json`` so that a
+build interrupted part-way through can be resumed by re-running the same command.
- $ ls -1 dist/
- itk-4.11.0.dev20170218-cp27-cp27m-manylinux2014_x86_64.whl
- itk-4.11.0.dev20170218-cp27-cp27mu-manylinux2014_x86_64.whl
- itk-4.11.0.dev20170218-cp34-cp34m-manylinux2014_x86_64.whl
- itk-4.11.0.dev20170218-cp35-cp35m-manylinux2014_x86_64.whl
- itk-4.11.0.dev20170218-cp36-cp36m-manylinux2014_x86_64.whl
-macOS
------
+Setup
+=====
+
+Clone the repository::
+
+ git clone https://github.com/InsightSoftwareConsortium/ITKPythonPackage.git
+ cd ITKPythonPackage
+
+
+Platform Environments
+=====================
+
+Each Pixi environment targets a specific OS and Python version. Pass the
+environment name to ``--platform-env``:
+
+.. list-table::
+ :header-rows: 1
+ :widths: 30 70
+
+ * - ``--platform-env``
+ - Notes
+ * - ``linux-py310``
+ - Native Linux (GCC, glibc of host)
+ * - ``linux-py311``
+ - Native Linux (GCC, glibc of host)
+ * - ``manylinux228-py310``
+ - Portable Linux ≥ glibc 2.28 (x86_64 or aarch64 via Docker)
+ * - ``manylinux228-py311``
+ - Portable Linux ≥ glibc 2.28 (x86_64 or aarch64 via Docker)
+ * - ``macosx-py310``
+ - macOS (x86_64 and arm64)
+ * - ``macosx-py311``
+ - macOS (x86_64 and arm64)
+ * - ``windows-py310``
+ - Windows x86_64 (MSVC 2022)
+ * - ``windows-py311``
+ - Windows x86_64 (MSVC 2022)
+
+If ``--platform-env`` is omitted, the platform is auto-detected from the
+host OS and defaults to Python 3.10.
+
+
+Building Wheels
+===============
-First, install the Python.org macOS Python distributions. This step requires sudo::
+manylinux
+---------
- ./scripts/macpython-install-python.sh
+On any linux distribution with docker and bash installed, running the script dockcross-manylinux-build-wheels.sh will create 64-bit wheels for python 3.10+ in the dist directory.
+.. code-block:: bash
-Then, build the wheels::
+ ./scripts/dockcross-manylinux-build-wheels.sh # py310 optionally specify python version
- $ ./scripts/macpython-build-wheels.sh
- [...]
+Or you can build using a specific platform environment using:
- $ ls -1 dist/
- itk-4.11.0.dev20170213-cp27-cp27m-macosx_10_6_x86_64.whl
- itk-4.11.0.dev20170213-cp34-cp34m-macosx_10_6_x86_64.whl
- itk-4.11.0.dev20170213-cp35-cp35m-macosx_10_6_x86_64.whl
- itk-4.11.0.dev20170213-cp36-cp36m-macosx_10_6_x86_64.whl
+Linux
+-----
+
+.. code-block:: bash
+
+ pixi run python3 scripts/build_wheels.py \
+ --platform-env linux-py310 \
+ --itk-git-tag v6.0b01 \
+ --no-build-itk-tarball-cache
+
+macOS
+-----
+
+.. code-block:: bash
+
+ pixi run python3 scripts/build_wheels.py \
+ --platform-env macosx-py310 \
+ --itk-git-tag v6.0b01 \
+ --no-build-itk-tarball-cache
Windows
-------
-First, install Microsoft Visual Studio 2015, Git, and CMake, which should be added to the system PATH environmental variable.
-
-Open a PowerShell terminal as Administrator, and install Python::
-
- PS C:\> Set-ExecutionPolicy Unrestricted
- PS C:\> $pythonArch = "64"
- PS C:\> iex ((new-object net.webclient).DownloadString('https://raw.githubusercontent.com/scikit-build/scikit-ci-addons/master/windows/install-python.ps1'))
-
-In a PowerShell prompt::
-
- PS C:\Windows> cd C:\
- PS C:\> git clone https://github.com/InsightSoftwareConsortium/ITKPythonPackage.git IPP
- PS C:\> cd IPP
- PS C:\IPP> .\scripts\windows-build-wheels.ps1
- [...]
-
- PS C:\IPP> ls dist
- Directory: C:\IPP\dist
-
-
- Mode LastWriteTime Length Name
- ---- ------------- ------ ----
- -a---- 4/9/2017 11:14 PM 63274441 itk-4.11.0.dev20170407-cp35-cp35m-win_amd64.whl
- -a---- 4/10/2017 2:08 AM 63257220 itk-4.11.0.dev20170407-cp36-cp36m-win_amd64.whl
-
-We need to work in a short directory to avoid path length limitations on
-Windows, so the repository is cloned into C:\IPP.
-
-Also, it is very important to disable antivirus checking on the C:\IPP
-directory. Otherwise, the build system conflicts with the antivirus when many
-files are created and deleted quickly, which can result in Access Denied
-errors. Windows 10 ships with an antivirus application, Windows Defender, that
-is enabled by default.
-
-.. The below instructions are outdated and need to be re-written
-.. sdist
-.. -----
-..
-.. To create source distributions, sdist's, that will be used by pip to compile a wheel for installation if a binary wheel is not available for the current Python version or platform::
-..
-.. $ python setup.py sdist --formats=gztar,zip
-.. [...]
-..
-.. $ ls -1 dist/
-.. itk-4.11.0.dev20170216.tar.gz
-.. itk-4.11.0.dev20170216.zip
-..
-.. Manual builds
-.. =============
-..
-.. Building ITK Python wheels
-.. --------------------------
-..
-.. Build the ITK Python wheel with the following command::
-..
-.. python3 -m venv build-itk
-.. ./build-itk/bin/pip install --upgrade pip
-.. ./build-itk/bin/pip install -r requirements-dev.txt numpy
-.. ./build-itk/bin/python setup.py bdist_wheel
-..
-.. Build a wheel for a custom version of ITK
-.. -----------------------------------------
-..
-.. To build a wheel for a custom version of ITK, point to your ITK git repository
-.. with the `ITK_SOURCE_DIR` CMake variable::
-..
-.. ./build-itk/bin/python setup.py bdist_wheel -- \
-.. -DITK_SOURCE_DIR:PATH=/path/to/ITKPythonPackage-core-build/ITK
-..
-.. Other CMake variables can also be passed with `-D` after the double dash.
+Similarly, on windows
+
+.. code-block:: powershell
+
+ pixi run python3 scripts/build_wheels.py `
+ --platform-env windows-py310 `
+ --itk-git-tag v6.0b01 `
+ --no-build-itk-tarball-cache
+
+
+Finished wheels are placed in ``/dist/``.
+
+.. note::
+ Building ITK from source takes 1–2 hours on typical hardware. Pass
+ ``--build-itk-tarball-cache`` to save the result as a reusable tarball
+ and avoid rebuilding on subsequent runs.
+
+.. tip::
+ For even faster builds, install the ``libitk-wrapping`` conda package
+ (see ``packages/libitk-wrapping/``). When present in the pixi/conda
+ environment, the build system automatically detects it and skips the
+ ITK C++ compilation entirely. See
+ :ref:`Build ITK Module Python Packages ` for details.
+
+
+Key Options
+===========
+
+.. list-table::
+ :header-rows: 1
+ :widths: 35 15 50
+
+ * - Option
+ - Default
+ - Description
+ * - ``--platform-env``
+ - auto-detected
+ - Target platform and Python version (see table above)
+ * - ``--itk-git-tag``
+ - ``main``
+ - ITK version, branch, or commit to build
+ * - ``--itk-package-version``
+ - auto (git describe)
+ - PEP 440 version string embedded in the wheels
+ * - ``--build-dir-root``
+ - ``../ITKPythonPackage-build``
+ - Root directory for all build artifacts
+ * - ``--manylinux-version``
+ - ``_2_28``
+ - Manylinux compatibility standard (e.g. ``_2_28``, ``_2_34``)
+ * - ``--itk-source-dir``
+ - cloned automatically
+ - Path to a local ITK checkout (skips git clone)
+ * - ``--module-source-dir``
+ - *(none)*
+ - Path to an ITK external module to build against the ITK build
+ * - ``--itk-module-deps``
+ - *(none)*
+ - Colon-delimited prerequisite modules (``org/repo@tag:org/repo@tag``)
+ * - ``--build-itk-tarball-cache``
+ - off
+ - Package the ITK build as a reusable ``.tar.zst`` / ``.zip``
+ * - ``--no-build-itk-tarball-cache``
+ - *(default)*
+ - Skip tarball generation
+ * - ``--skip-itk-build`` / ``--no-skip-itk-build``
+ - off
+ - Skip step 2 (ITK C++ build) when a build already exists
+ * - ``--skip-itk-wheel-build`` / ``--no-skip-itk-wheel-build``
+ - off
+ - Skip step 3 (wheel build) when wheels already exist
+ * - ``--cleanup``
+ - off
+ - Remove intermediate build files after completion
+ * - ``--use-ccache``
+ - off
+ - Enable ccache to speed up recompilation
+ * - ``--macosx-deployment-target``
+ - ``10.7``
+ - Minimum macOS version for compiled binaries
+ * - ``--use-sudo`` / ``--no-use-sudo``
+ - off
+ - Pass ``sudo`` to Docker commands (manylinux only)
+
+Any remaining positional arguments are forwarded to CMake as ``-D`` definitions,
+for example::
+
+ pixi run python3 scripts/build_wheels.py \
+ --platform-env macosx-py310 \
+ --itk-git-tag v6.0b01 \
+ -DBUILD_SHARED_LIBS:BOOL=OFF
+
+
+Environment Variable Equivalents
+---------------------------------
+
+All ``--`` options can alternatively be set as environment variables, which is
+useful in CI pipelines:
+
+.. list-table::
+ :header-rows: 1
+ :widths: 35 65
+
+ * - Environment Variable
+ - Equivalent Option
+ * - ``ITK_GIT_TAG``
+ - ``--itk-git-tag``
+ * - ``ITK_PACKAGE_VERSION``
+ - ``--itk-package-version``
+ * - ``ITK_SOURCE_DIR``
+ - ``--itk-source-dir``
+ * - ``MANYLINUX_VERSION``
+ - ``--manylinux-version``
+ * - ``TARGET_ARCH``
+ - target architecture (``x64`` or ``aarch64``)
+ * - ``IMAGE_TAG``
+ - Docker image tag for manylinux builds
+ * - ``NO_SUDO``
+ - ``--no-use-sudo``
+ * - ``USE_CCACHE``
+ - ``--use-ccache``
+ * - ``CMAKE_OPTIONS``
+ - extra CMake ``-D`` definitions
+ * - ``MACOSX_DEPLOYMENT_TARGET``
+ - ``--macosx-deployment-target``
+
+
+Building from a Local ITK Source
+=================================
+
+If you have a local ITK checkout with custom patches or an unreleased fix, pass
+``--itk-source-dir`` to use it instead of cloning from GitHub:
+
+.. code-block:: bash
+
+ pixi run python3 scripts/build_wheels.py \
+ --platform-env macosx-py310 \
+ --itk-source-dir /path/to/your/ITK \
+ --itk-git-tag my-bugfix-branch \
+ --no-build-itk-tarball-cache
+
+For manylinux, use the shell wrapper which handles Docker volume mounting:
+
+.. code-block:: bash
+
+ ITK_SOURCE_DIR=/path/to/your/ITK \
+ bash scripts/dockcross-manylinux-build-wheels.sh cp310
+
+
+Building ITK Tarball Caches
+============================
+
+Tarball caches package the entire ITK build output (headers, libraries, wrapper
+artifacts) so that external module builds can skip the costly ITK compilation step.
+These are the same caches distributed via `ITKPythonBuilds
+`_ releases.
+
+By default these scripts build for python version 3.10 and 3.11 but you can optionally add a specific version to build for
+
+Linux / macOS:
+
+.. code-block:: bash
+
+ ITK_GIT_TAG=v6.0b01
+ bash scripts/make_tarballs.sh py310
+
+Windows (PowerShell):
+
+.. code-block:: powershell
+
+ $env:ITK_GIT_TAG = "v6.0b01"
+ .\scripts\make_windows_zip.ps1 py310
+
+Or via ``build_wheels.py`` directly:
+
+.. code-block:: bash
+
+ pixi run python3 scripts/build_wheels.py \
+ --platform-env macosx-py310 \
+ --itk-git-tag v6.0b01 \
+ --build-itk-tarball-cache
+
+.. important::
+ Build caches embed absolute paths. They must be extracted to the same path
+ they were built from or CMake will fail to locate required files. The
+ standard CI/CD paths are:
+
+ - **manylinux (Docker)**: ``/work/ITKPythonPackage-build``
+ - **macOS**: ``/Users/svc-dashboard/D/P/ITKPythonPackage-build``
+ - **Windows**: ``C:\BDR``
+
+ The ``make_tarballs.sh`` and ``make_windows_zip.ps1`` scripts enforce these
+ paths automatically.
+
+
+Output Artifacts
+================
+
+.. list-table::
+ :header-rows: 1
+ :widths: 30 70
+
+ * - Artifact
+ - Location
+ * - Built wheels
+ - ``/dist/*.whl``
+ * - Effective command line
+ - ``/effective_cmdline_.sh``
+ * - manylinux tarball caches
+ - ``/ITKPythonBuilds-manylinux_2_28-*.tar.zst``
+ * - Linux tarball caches
+ - ``/ITKPythonBuilds-linux-*.tar.zst``
+ * - macOS tarball caches
+ - ``/ITKPythonBuilds-macosx-*.tar.zst``
+ * - Windows ZIP cache
+ - ``/ITKPythonBuilds-windows.zip``
+
+Example wheel names::
+
+ itk-6.0.0-cp310-cp310-manylinux_2_28_x86_64.whl
+ itk-6.0.0-cp310-cp310-macosx_13_0_arm64.whl
+ itk-6.0.0-cp310-cp310-win_amd64.whl
+
+
+Testing Built Wheels
+====================
+
+Install and smoke-test a wheel directly from the ``dist/`` directory:
+
+.. code-block:: bash
+
+ pip install dist/itk-6.0.0-cp310-cp310-macosx_13_0_arm64.whl
+ python -c "import itk; print(itk.__version__)"
+
+
+Publishing
+==========
+
+ITKPythonPackage provides a lightweight ``publish`` Pixi environment with
+`twine `_ for uploading wheels to PyPI and the
+`GitHub CLI `_ for uploading tarball caches to GitHub
+Releases. Install it with::
+
+ pixi install -e publish
+
+
+Publishing Wheels to PyPI
+-------------------------
+
+The ``publish-wheels`` task validates wheel metadata with ``twine check`` and
+then uploads all ``.whl`` files from a ``dist/`` directory.
+
+**Authentication** — set environment variables or configure ``~/.pypirc``
+(see ``.pypirc.example`` in the repository root):
+
+.. code-block:: bash
+
+ export TWINE_USERNAME=__token__
+ export TWINE_PASSWORD=pypi-
+
+Upload to **TestPyPI** first for validation:
+
+.. code-block:: bash
+
+ pixi run -e publish publish-wheels \
+ --dist-directory /path/to/dist \
+ --test
+
+Then upload to **production PyPI**:
+
+.. code-block:: bash
+
+ pixi run -e publish publish-wheels \
+ --dist-directory /path/to/dist
+
+Additional options:
+
+.. list-table::
+ :header-rows: 1
+ :widths: 30 70
+
+ * - Option
+ - Description
+ * - ``--test``
+ - Upload to TestPyPI (``https://test.pypi.org/legacy/``)
+ * - ``--repository-url``
+ - Custom package index URL (overrides ``--test``)
+ * - ``--skip-existing``
+ - Skip already-uploaded wheels instead of failing
+
+
+Publishing Tarball Caches to GitHub Releases
+--------------------------------------------
+
+The ``publish-tarball-cache`` task uploads ``.tar.zst`` (POSIX) and ``.zip``
+(Windows) build caches to a GitHub Release on the
+`ITKPythonBuilds `_
+repository.
+
+**Authentication** — set the ``GH_TOKEN`` environment variable or run
+``gh auth login`` beforehand.
+
+.. code-block:: bash
+
+ pixi run -e publish publish-tarball-cache \
+ --itk-package-version v6.0b02 \
+ --build-dir-root /path/to/build \
+ --create-release
+
+Additional options:
+
+.. list-table::
+ :header-rows: 1
+ :widths: 30 70
+
+ * - Option
+ - Description
+ * - ``--itk-package-version``
+ - **(required)** Release tag name (e.g. ``v6.0b02``)
+ * - ``--build-dir-root``
+ - Root of the build directory; tarballs are found in its parent
+ (POSIX ``.tar.zst``) or inside it (Windows ``.zip``)
+ * - ``--repo``
+ - Target GitHub repository (default: ``InsightSoftwareConsortium/ITKPythonBuilds``)
+ * - ``--create-release``
+ - Create the GitHub Release if it does not already exist
+
+.. note::
+ The ``--clobber`` flag is used internally so re-uploading a tarball for the
+ same platform replaces the existing asset without manual cleanup.
+
+
+Troubleshooting
+===============
+
+Path Length Issues (Windows)
+-----------------------------
+
+If you encounter path length errors:
+
+Windows has a 260-character path limit by default. Use a short build directory
+(e.g. ``C:\BDR``) and optionally enable long path support:
+
+.. code-block:: powershell
+
+ New-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Control\FileSystem" `
+ -Name "LongPathsEnabled" -Value 1 -PropertyType DWORD -Force
+
+Antivirus Conflicts (Windows)
+------------------------------
+
+The build creates and deletes large numbers of files rapidly, which can trigger
+Windows Defender and produce "Access Denied" errors. Add the build directory to
+Windows Defender exclusions:
+
+1. Open **Windows Security → Virus & threat protection → Manage settings**
+2. Scroll to **Exclusions → Add or remove exclusions**
+3. Add the build root (e.g. ``C:\BDR``)
+
+Docker Permissions (Linux)
+---------------------------
+
+If Docker requires ``sudo``, pass ``--use-sudo`` to ``build_wheels.py`` or set
+``NO_SUDO=`` (empty string) before running the manylinux shell script. To add
+your user to the ``docker`` group instead::
+
+ sudo usermod -aG docker $USER
+ # Then log out and back in
diff --git a/docs/Miscellaneous.rst b/docs/Miscellaneous.rst
index d7ae223f..acf64221 100644
--- a/docs/Miscellaneous.rst
+++ b/docs/Miscellaneous.rst
@@ -2,7 +2,7 @@
Miscellaneous
=============
-Written by Jean-Christophe Fillion-Robin and Matt McCormick from Kitware Inc.
+Written by Jean-Christophe Fillion-Robin and Matt McCormick from Kitware Inc and Cavan Riley from the University of Iowa.
It is covered by the Apache License, Version 2.0:
diff --git a/docs/Prerequisites.rst b/docs/Prerequisites.rst
index 83b0f1a7..73b22012 100644
--- a/docs/Prerequisites.rst
+++ b/docs/Prerequisites.rst
@@ -1,9 +1,52 @@
Prerequisites
=============
-Building wheels requires:
+The following tools are required to build ITK Python wheels locally.
-- CMake
-- Git
-- C++ Compiler - Platform specific requirements are summarized in scikit-build documentation.
-- Python
+All Platforms
+-------------
+
+`Pixi `_ is the primary build environment manager. It automatically
+provisions the correct Python version, compiler toolchain, CMake, Ninja, and all
+other build dependencies for each target platform. Manual installation of compilers
+or CMake is not required when using Pixi.
+
+Install Pixi:
+
+.. code-block:: bash
+
+ # Linux or macOS
+ curl -fsSL https://pixi.sh/install.sh | bash
+
+ # Windows (PowerShell)
+ powershell -ExecutionPolicy Bypass -c "irm -useb https://pixi.sh/install.ps1 | iex"
+
+You will also need `Git `_ 2.x or later.
+
+Linux
+-----
+
+Portable manylinux builds require Docker (or an OCI-compatible runtime such as
+Podman or nerdctl) to run the manylinux container environment.
+
+Install Docker by following the official `Docker Engine installation guide
+`_.
+
+macOS
+-----
+
+No additional tools are required beyond Pixi. The Pixi ``macosx-build``
+environment provides the Clang 1.10.0 compiler toolchain and the
+`delocate `_ wheel repair utility.
+
+Windows
+-------
+
+`Microsoft Visual Studio 2022 `_
+(or the Build Tools for Visual Studio 2022) with the
+**Desktop development with C++** workload is required.
+
+.. note::
+ Pixi environments provision Python, CMake, Ninja, and build helpers
+ (``auditwheel`` on Linux, ``delocate`` on macOS, ``delvewheel`` on Windows)
+ automatically. Only Docker (Linux) and MSVC (Windows) require separate installation.
diff --git a/docs/Quick_start_guide.rst b/docs/Quick_start_guide.rst
deleted file mode 100644
index f1ae8205..00000000
--- a/docs/Quick_start_guide.rst
+++ /dev/null
@@ -1,247 +0,0 @@
-===========================
-Quick start guide
-===========================
-
-.. _quick-start:
-
-Installation
-------------
-
-To install the ITK Python package::
-
- $ pip install itk
-
-
-Usage
------
-
-Basic example
-..............
-
-Here is a simple python script that reads an image, applies a median image filter (radius of 2 pixels), and writes the resulting image in a file.
-
-.. literalinclude:: code/ReadMedianWrite.py
-
-ITK and NumPy
-.............
-
-A common use case for using ITK in Python is to mingle NumPy and ITK operations on raster data. ITK provides a large number of I/O image formats and several sophisticated image processing algorithms not available in any other packages. The ability to intersperse that with the SciPy ecosystem provides a great tool for rapid prototyping.
-
-The following script shows how to integrate NumPy and `itk.Image`:
-
-.. literalinclude:: code/MixingITKAndNumPy.py
- :lines: 16-59
-
-NumPy and `itk.Mesh`:
-
-.. literalinclude:: code/MixingITKAndNumPy.py
- :lines: 62-76
-
-NumPy and `itk.Transform`:
-
-.. literalinclude:: code/MixingITKAndNumPy.py
- :lines: 96-115
-
-NumPy and `itk.Matrix`, VNL vectors, and VNL matrices:
-
-.. literalinclude:: code/MixingITKAndNumPy.py
- :lines: 118-
-
-ITK and Xarray
-..............
-
-An `itk.Image` can be converted to and from an `xarray.DataArray
-`_ while
-preserving metadata::
-
- da = itk.xarray_from_image(image)
-
- image = itk.image_from_xarray(da)
-
-ITK and VTK
-............
-
-An `itk.Image` can be converted to and from a `vtk.vtkImageData
-`_ while
-preserving metadata::
-
- vtk_image = itk.vtk_image_from_image(image)
-
- image = itk.image_from_vtk_image(vtk_image)
-
-ITK and napari
-..............
-
-An `itk.Image` can be converted to and from a `napari.layers.Image
-`_ while
-preserving metadata with the `itk-napari-conversion package
-`_.
-
-ITK Python types
-................
-
-+---------------------+--------------------+--------------------+
-| C++ type | Python type | NumPy dtype |
-+=====================+====================+====================+
-| float | itk.F | np.float32 |
-+---------------------+--------------------+--------------------+
-| double | itk.D | np.float64 |
-+---------------------+--------------------+--------------------+
-| unsigned char | itk.UC | np.uint8 |
-+---------------------+--------------------+--------------------+
-| std::complex | itk.complex[itk.F] | np.complex64 |
-+---------------------+--------------------+--------------------+
-
-This list is not exhaustive and is only presented to illustrate the type names. The complete list of types can be found in the `ITK Software Guide `_.
-
-Types can also be obtained from their name in the C programming language:
-
-.. literalinclude:: code/CompareITKTypes.py
- :lines: 5
-
-To cast the pixel type of an image, use `.astype`:
-
-.. literalinclude:: code/Cast.py
- :lines: 10-18
-
-Metadata dictionary
-...................
-
-An `itk.Image` has a metadata dict of `key: value` pairs.
-
-
-The metadata dictionary can be retrieved with::
-
- meta_dict = dict(image)
-
-For example::
-
- In [3]: dict(image)
- Out[3]:
- {'0008|0005': 'ISO IR 100',
- '0008|0008': 'ORIGINAL\\PRIMARY\\AXIAL',
- '0008|0016': '1.2.840.10008.5.1.4.1.1.2',
- '0008|0018': '1.3.12.2.1107.5.8.99.484849.834848.79844848.2001082217554549',
- '0008|0020': '20010822',
-
-Individual dictionary items can be accessed or assigned::
-
- print(image['0008|0008'])
-
- image['origin'] = [4.0, 2.0, 2.0]
-
-In the Python dictionary interface to image metadata, keys for the spatial
-metadata, the *'origin'*, *'spacing'*, and *'direction'*, are reversed in
-order from `image.GetOrigin()`, `image.GetSpacing()`, `image.GetDirection()`
-to be consistent with the `NumPy array index order
-`_
-resulting from pixel buffer array views on the image.
-
-Access pixel data with NumPy indexing
-.....................................
-
-Array views of an `itk.Image` provide a way to set and get pixel values with NumPy indexing syntax, e.g.::
-
- In [6]: image[0,:2,4] = [5,5]
-
- In [7]: image[0,:4,4:6]
- Out[7]:
- NDArrayITKBase([[ 5, -997],
- [ 5, -1003],
- [ -993, -999],
- [ -996, -994]], dtype=int16)
-
-Input/Output (IO)
-.................
-
-Convenient functions are provided read and write from ITK's many supported
-file formats::
-
- image = itk.imread('image.tif')
-
- # Read in with a specific pixel type.
- image = itk.imread('image.tif', itk.F)
-
- # Read in an image series.
- # Pass a sorted list of files.
- image = itk.imread(['image1.png', 'image2.png', 'image3.png'])
-
- # Read in a volume from a DICOM series.
- # Pass a directory.
- # Only a single series, sorted spatially, will be returned.
- image = itk.imread('/a/dicom/directory/')
-
- # Write an image.
- itk.imwrite(image, 'image.tif')
-
-
- # Read a mesh.
- mesh = itk.meshread('mesh.vtk')
-
- # Write a mesh.
- itk.meshwrite(mesh, 'mesh.vtk')
-
-
- # Read a spatial transform.
- transform = itk.transformread('transform.h5')
-
- # Write a spatial transform.
- itk.transformwrite(transform, 'transform.h5')
-
-Image filters and Image-like inputs and outputs
-...............................................
-
-All `itk` functional image filters operate on an `itk.Image` but also:
-
-- `xarray.DataArray `_ *
-- `numpy.ndarray `_
-- `dask.array.Array `_
-
-\* Preserves image metadata
-
-Filter parameters
-.................
-
-ITK filter parameters can be specified in the following ways:
-
-.. literalinclude:: code/FilterParameters.py
- :lines: 10-
-
-Filter types
-............
-
-In `itk`, filters are optimized at compile time for each image pixel type and
-image dimension. There are two ways to instantiate these filters with the `itk`
-Python wrapping:
-
-- *Implicit (recommended)*: Type information is automatically detected from the data. Typed filter objects and images are implicitly created.
-
-.. literalinclude:: code/ImplicitInstantiation.py
- :lines: 8-
-
-- *Explicit*: This can be useful if an appropriate type cannot be determined implicitly or when a different filter type than the default is desired.
-
-To specify the type of the filter, use the `ttype` keyword argument. Explicit instantiation of a median image filter:
-
-.. literalinclude:: code/ExplicitInstantiation.py
- :lines: 8-
-
-Instantiate an ITK object
-.........................
-
-There are two types of ITK objects. Most ITK objects, such as images, filters, or adapters, are instantiated the following way:
-
-.. literalinclude:: code/InstantiateITKObjects.py
- :lines: 6-8
-
-Some objects, like a Matrix, Vector, or RGBPixel, do not require the attribute `.New()` to be added to instantiate them:
-
-.. literalinclude:: code/InstantiateITKObjects.py
- :lines: 11
-
-In case of doubt, look at the attributes of the object you are trying to instantiate.
-
-Examples
---------
-
-Examples can be found in the `ITKSphinxExamples project `_.
diff --git a/docs/_static/custom.css b/docs/_static/custom.css
new file mode 100644
index 00000000..7b5c8b9d
--- /dev/null
+++ b/docs/_static/custom.css
@@ -0,0 +1,29 @@
+/* -- ITKPythonPackage custom styles (pydata-sphinx-theme) -- */
+
+/* Sidebar brand text */
+.navbar-brand p {
+ font-weight: 700;
+ font-size: 1.15rem;
+}
+
+/* Better code block styling */
+.highlight pre {
+ border-radius: 6px;
+ font-size: 0.85rem;
+}
+
+/* Admonition tweaks */
+.admonition {
+ border-radius: 6px;
+ font-size: 0.92rem;
+}
+
+/* Quick-links card grid on index */
+.sd-card {
+ border-radius: 8px;
+ transition: box-shadow 0.2s ease;
+}
+
+.sd-card:hover {
+ box-shadow: 0 4px 12px rgba(0, 0, 0, 0.12);
+}
diff --git a/docs/conf.py b/docs/conf.py
index b642ec55..8be81c96 100644
--- a/docs/conf.py
+++ b/docs/conf.py
@@ -1,28 +1,5 @@
import os
-# -*- coding: utf-8 -*-
-#
-# ITKPythonPackage documentation build configuration file, created by
-# sphinx-quickstart on Mon May 29 15:53:20 2017.
-#
-# This file is execfile()d with the current directory set to its
-# containing dir.
-#
-# Note that not all possible configuration values are present in this
-# autogenerated file.
-#
-# All configuration values have a default; values that are commented out
-# serve to show the default.
-
-# If extensions (or modules to document with autodoc) are in another directory,
-# add these directories to sys.path here. If the directory is relative to the
-# documentation root, use os.path.abspath to make it absolute, like shown here.
-#
-# import os
-# import sys
-# sys.path.insert(0, os.path.abspath('.'))
-
-
# -- General configuration ------------------------------------------------
# If your documentation needs a minimal Sphinx version, state it here.
@@ -32,8 +9,10 @@
# Add any Sphinx extension module names here, as strings. They can be
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
# ones.
-extensions = []
-
+extensions = [
+ "sphinx_copybutton",
+ "sphinx_design",
+]
# Add any paths that contain templates here, relative to this directory.
templates_path = ["_templates"]
@@ -51,21 +30,10 @@
copyright = "2017, Jean-Christophe Fillion-Robin and Matt McCormick"
author = "Jean-Christophe Fillion-Robin and Matt McCormick"
-# The version info for the project you're documenting, acts as replacement for
-# |version| and |release|, also used in various other places throughout the
-# built documents.
-#
-# The short X.Y version.
-version = ""
-# The full version, including alpha/beta/rc tags.
-release = ""
+version = os.environ.get("READTHEDOCS_VERSION", "")
+release = version
-# The language for content autogenerated by Sphinx. Refer to documentation
-# for a list of supported languages.
-#
-# This is also used if you do content translation via gettext catalogs.
-# Usually you set "language" from the command line for these cases.
-language = None
+language = "en"
# List of patterns, relative to source directory, that match files and
# directories to ignore when looking for source files.
@@ -81,21 +49,27 @@
# -- Options for HTML output ----------------------------------------------
-# The theme to use for HTML and HTML Help pages. See the documentation for
-# a list of builtin themes.
-#
-html_theme = "default"
-
-# Theme options are theme-specific and customize the look and feel of a theme
-# further. For a list of options available for each theme, see the
-# documentation.
-#
-# html_theme_options = {}
-
-# Add any paths that contain custom static files (such as style sheets) here,
-# relative to this directory. They are copied after the builtin static files,
-# so a file named "default.css" will overwrite the builtin "default.css".
+html_theme = "furo"
html_static_path = ["_static"]
+html_css_files = ["custom.css"]
+html_title = "ITKPythonPackage"
+
+html_theme_options = {
+ "source_repository": "https://github.com/InsightSoftwareConsortium/ITKPythonPackage",
+ "source_branch": "main",
+ "source_directory": "docs/",
+ "sidebar_hide_name": False,
+ "navigation_with_keys": True,
+ "top_of_page_buttons": ["view", "edit"],
+ "light_css_variables": {
+ "color-brand-primary": "#2962FF",
+ "color-brand-content": "#2962FF",
+ },
+ "dark_css_variables": {
+ "color-brand-primary": "#82B1FF",
+ "color-brand-content": "#82B1FF",
+ },
+}
# -- Options for HTMLHelp output ------------------------------------------
@@ -156,19 +130,7 @@
"ITKPythonPackage Documentation",
author,
"ITKPythonPackage",
- "One line description of project.",
+ "Scripts and configuration for building ITK Python binary wheels.",
"Miscellaneous",
),
]
-
-
-# -- Read The Docs -----------------------------------------------------
-
-# on_rtd is whether we are on readthedocs.io
-on_rtd = os.environ.get("READTHEDOCS", None) == "True"
-
-if not on_rtd: # only import and set the theme if we're building docs locally
- import sphinx_rtd_theme
-
- html_theme = "sphinx_rtd_theme"
- html_theme_path = [sphinx_rtd_theme.get_html_theme_path()]
diff --git a/docs/index.rst b/docs/index.rst
index 32fc2fbc..00db0e9f 100644
--- a/docs/index.rst
+++ b/docs/index.rst
@@ -1,36 +1,62 @@
-Welcome to ITKPythonPackage's documentation!
-============================================
+ITKPythonPackage
+================
-This project provides a script to generate `pyproject.toml` files used to build
-ITK Python wheels and infrastructure to build ITK external module Python
+Build infrastructure for ITK Python wheels and ITK external module Python
wheels.
`ITK `_ is an open-source, cross-platform system that
provides developers with an extensive suite of software tools for image
analysis.
-To install the pre-built stable ITK Python package::
+.. code-block:: bash
- $ pip install itk
+ pip install itk
For more information on ITK's Python wrapping, see `an introduction in the
Book 1, Chapter 3 of the ITK Software Guide `_.
There are also many `downloadable examples documented in Sphinx
`_.
+----
-.. toctree::
- :maxdepth: 2
- :caption: Contents
+Quick Links
+-----------
+
+.. grid:: 2
+ :gutter: 3
+
+ .. grid-item-card:: Prerequisites
+ :link: Prerequisites
+ :link-type: doc
+
+ Platform requirements and tooling setup for building ITK wheels.
+
+ .. grid-item-card:: Build ITK Python Packages
+ :link: Build_ITK_Python_packages
+ :link-type: doc
+
+ Build core ITK wheels (``itk-core``, ``itk-numerics``, ``itk-io``, etc.)
+ from source.
- Quick_start_guide.rst
- Build_ITK_Module_Python_packages.rst
- Build_ITK_Python_packages.rst
- Miscellaneous.rst
+ .. grid-item-card:: Build ITK Module Packages
+ :link: Build_ITK_Module_Python_packages
+ :link-type: doc
-Indices and tables
-==================
+ Create, build, and publish Python packages for ITK remote and external
+ modules.
+
+ .. grid-item-card:: Miscellaneous
+ :link: Miscellaneous
+ :link-type: doc
+
+ License, authors, and additional resources.
+
+----
+
+.. toctree::
+ :maxdepth: 3
-* :ref:`genindex`
-* :ref:`modindex`
-* :ref:`search`
+ Prerequisites
+ Build_ITK_Python_packages
+ Build_ITK_Module_Python_packages
+ Miscellaneous
diff --git a/docs/requirements-docs.txt b/docs/requirements-docs.txt
index 82133027..7d464dc3 100644
--- a/docs/requirements-docs.txt
+++ b/docs/requirements-docs.txt
@@ -1,2 +1,4 @@
sphinx
-sphinx_rtd_theme
+furo
+sphinx-copybutton
+sphinx-design
diff --git a/itkVersion.py b/itkVersion.py
deleted file mode 100644
index acf9bffb..00000000
--- a/itkVersion.py
+++ /dev/null
@@ -1,31 +0,0 @@
-from packaging.version import Version
-
-# Version needs to be python PEP 440 compliant (no leading v)
-VERSION = '6.0b2'.removeprefix("v")
-
-def get_versions():
- """Returns versions for the ITK Python package.
-
- from itkVersion import get_versions
-
- # Returns the ITK repository version
- get_versions()['version']
-
- # Returns the package version. Since GitHub Releases do not support the '+'
- # character in file names, this does not contain the local version
- # identifier in nightly builds, i.e.
- #
- # '4.11.0.dev20170208'
- #
- # instead of
- #
- # '4.11.0.dev20170208+139.g922f2d9'
- get_versions()['package-version']
- """
-
- Version(VERSION) # Raise InvalidVersion exception if not PEP 440 compliant
-
- versions = {}
- versions['version'] = VERSION
- versions['package-version'] = VERSION.split('+')[0]
- return versions
diff --git a/packages/libitk-wrapping/build-libitk-wrapping.bat b/packages/libitk-wrapping/build-libitk-wrapping.bat
new file mode 100644
index 00000000..781af091
--- /dev/null
+++ b/packages/libitk-wrapping/build-libitk-wrapping.bat
@@ -0,0 +1,62 @@
+@echo off
+setlocal enabledelayedexpansion
+
+:: Build ITK C++ with Python wrapping for use as a conda package (Windows).
+
+set BUILD_DIR=%SRC_DIR%\..\build
+mkdir %BUILD_DIR%
+cd %BUILD_DIR%
+
+cmake ^
+ -G "Ninja" ^
+ %CMAKE_ARGS% ^
+ -D BUILD_SHARED_LIBS:BOOL=ON ^
+ -D BUILD_TESTING:BOOL=OFF ^
+ -D BUILD_EXAMPLES:BOOL=OFF ^
+ -D CMAKE_BUILD_TYPE:STRING=Release ^
+ -D "CMAKE_INSTALL_PREFIX=%LIBRARY_PREFIX%" ^
+ ^
+ -D ITK_WRAP_PYTHON:BOOL=ON ^
+ -D ITK_WRAP_DOC:BOOL=ON ^
+ -D ITK_LEGACY_SILENT:BOOL=ON ^
+ -D CMAKE_POSITION_INDEPENDENT_CODE:BOOL=ON ^
+ ^
+ -D ITK_WRAP_unsigned_short:BOOL=ON ^
+ -D ITK_WRAP_double:BOOL=ON ^
+ -D ITK_WRAP_complex_double:BOOL=ON ^
+ -D "ITK_WRAP_IMAGE_DIMS:STRING=2;3;4" ^
+ ^
+ -D WRAP_ITK_INSTALL_COMPONENT_IDENTIFIER:STRING=PythonWheel ^
+ -D WRAP_ITK_INSTALL_COMPONENT_PER_MODULE:BOOL=ON ^
+ ^
+ -D ITK_USE_SYSTEM_EXPAT:BOOL=ON ^
+ -D ITK_USE_SYSTEM_HDF5:BOOL=ON ^
+ -D ITK_USE_SYSTEM_JPEG:BOOL=ON ^
+ -D ITK_USE_SYSTEM_PNG:BOOL=ON ^
+ -D ITK_USE_SYSTEM_TIFF:BOOL=ON ^
+ -D ITK_USE_SYSTEM_ZLIB:BOOL=ON ^
+ -D ITK_USE_SYSTEM_FFTW:BOOL=ON ^
+ -D ITK_USE_SYSTEM_EIGEN:BOOL=ON ^
+ -D ITK_USE_FFTWD:BOOL=ON ^
+ -D ITK_USE_FFTWF:BOOL=ON ^
+ ^
+ -D ITK_BUILD_DEFAULT_MODULES:BOOL=ON ^
+ -D Module_ITKReview:BOOL=ON ^
+ -D Module_ITKTBB:BOOL=ON ^
+ -D Module_MGHIO:BOOL=ON ^
+ -D Module_ITKIOTransformMINC:BOOL=ON ^
+ -D Module_GenericLabelInterpolator:BOOL=ON ^
+ -D Module_AdaptiveDenoising:BOOL=ON ^
+ ^
+ -D ITK_USE_KWSTYLE:BOOL=OFF ^
+ -D "ITK_DEFAULT_THREADER:STRING=Pool" ^
+ ^
+ "%SRC_DIR%"
+
+if errorlevel 1 exit /b 1
+
+cmake --build . --config Release
+if errorlevel 1 exit /b 1
+
+cmake --install . --config Release
+if errorlevel 1 exit /b 1
diff --git a/packages/libitk-wrapping/build-libitk-wrapping.sh b/packages/libitk-wrapping/build-libitk-wrapping.sh
new file mode 100755
index 00000000..994c6c4f
--- /dev/null
+++ b/packages/libitk-wrapping/build-libitk-wrapping.sh
@@ -0,0 +1,77 @@
+#!/bin/bash
+set -euo pipefail
+
+# Build ITK C++ with Python wrapping for use as a conda package.
+# This produces headers, shared libraries, CMake config, and all
+# wrapping metadata (SWIG .i/.idx/.mdx files, Python stubs) needed
+# by downstream ITK remote modules.
+
+BUILD_DIR="${SRC_DIR}/../build"
+mkdir -p "${BUILD_DIR}"
+cd "${BUILD_DIR}"
+
+# Use TBB on Linux; macOS has known issues with conda TBB
+use_tbb=ON
+if [ "$(uname)" = "Darwin" ]; then
+ use_tbb=OFF
+fi
+
+# Handle cross-compilation try-run results if available
+if [[ "${CONDA_BUILD_CROSS_COMPILATION:-0}" == "1" ]]; then
+ try_run_results="${RECIPE_DIR}/TryRunResults-${target_platform}.cmake"
+ if [[ -f "${try_run_results}" ]]; then
+ CMAKE_ARGS="${CMAKE_ARGS} -C ${try_run_results}"
+ fi
+fi
+
+cmake \
+ -G "Ninja" \
+ ${CMAKE_ARGS} \
+ -D BUILD_SHARED_LIBS:BOOL=ON \
+ -D BUILD_TESTING:BOOL=OFF \
+ -D BUILD_EXAMPLES:BOOL=OFF \
+ -D CMAKE_BUILD_TYPE:STRING=Release \
+ -D "CMAKE_INSTALL_PREFIX=${PREFIX}" \
+ \
+ -D ITK_WRAP_PYTHON:BOOL=ON \
+ -D ITK_WRAP_DOC:BOOL=ON \
+ -D ITK_LEGACY_SILENT:BOOL=ON \
+ -D CMAKE_POSITION_INDEPENDENT_CODE:BOOL=ON \
+ \
+ -D ITK_WRAP_unsigned_short:BOOL=ON \
+ -D ITK_WRAP_double:BOOL=ON \
+ -D ITK_WRAP_complex_double:BOOL=ON \
+ -D "ITK_WRAP_IMAGE_DIMS:STRING=2;3;4" \
+ \
+ -D WRAP_ITK_INSTALL_COMPONENT_IDENTIFIER:STRING=PythonWheel \
+ -D WRAP_ITK_INSTALL_COMPONENT_PER_MODULE:BOOL=ON \
+ \
+ -D ITK_USE_SYSTEM_EXPAT:BOOL=ON \
+ -D ITK_USE_SYSTEM_HDF5:BOOL=ON \
+ -D ITK_USE_SYSTEM_JPEG:BOOL=ON \
+ -D ITK_USE_SYSTEM_PNG:BOOL=ON \
+ -D ITK_USE_SYSTEM_TIFF:BOOL=ON \
+ -D ITK_USE_SYSTEM_ZLIB:BOOL=ON \
+ -D ITK_USE_SYSTEM_FFTW:BOOL=ON \
+ -D ITK_USE_SYSTEM_EIGEN:BOOL=ON \
+ -D ITK_USE_FFTWD:BOOL=ON \
+ -D ITK_USE_FFTWF:BOOL=ON \
+ \
+ -D ITK_BUILD_DEFAULT_MODULES:BOOL=ON \
+ -D Module_ITKReview:BOOL=ON \
+ -D Module_ITKTBB:BOOL=${use_tbb} \
+ -D Module_MGHIO:BOOL=ON \
+ -D Module_ITKIOTransformMINC:BOOL=ON \
+ -D Module_GenericLabelInterpolator:BOOL=ON \
+ -D Module_AdaptiveDenoising:BOOL=ON \
+ \
+ -D ITK_USE_KWSTYLE:BOOL=OFF \
+ -D NIFTI_SYSTEM_MATH_LIB= \
+ -D GDCM_USE_COREFOUNDATION_LIBRARY:BOOL=OFF \
+ -D "ITK_DEFAULT_THREADER:STRING=Pool" \
+ \
+ "${SRC_DIR}"
+
+cmake --build . --config Release
+
+cmake --install . --config Release
diff --git a/packages/libitk-wrapping/pixi.toml b/packages/libitk-wrapping/pixi.toml
new file mode 100644
index 00000000..6bf85641
--- /dev/null
+++ b/packages/libitk-wrapping/pixi.toml
@@ -0,0 +1,15 @@
+[workspace]
+channels = ["https://prefix.dev/conda-forge"]
+platforms = ["linux-64", "linux-aarch64", "osx-arm64", "osx-64", "win-64"]
+preview = ["pixi-build"]
+
+[dependencies]
+libitk-wrapping = { path = "." }
+python = ">=3.10"
+
+[package]
+name = "libitk-wrapping"
+version = "6.99.0"
+
+[package.build]
+backend = { name = "pixi-build-rattler-build", version = "0.3.*" }
diff --git a/packages/libitk-wrapping/recipe.yaml b/packages/libitk-wrapping/recipe.yaml
new file mode 100644
index 00000000..9cfe7a5b
--- /dev/null
+++ b/packages/libitk-wrapping/recipe.yaml
@@ -0,0 +1,56 @@
+package:
+ name: libitk-wrapping
+ version: "6.99.0"
+
+source:
+ git: ${{ env.get("ITK_GIT_URL", "https://github.com/BRAINSia/ITK.git") }}
+ tag: ${{ env.get("ITK_GIT_TAG", "itk-conda-pythonpackage-support") }}
+
+build:
+ number: 0
+ script:
+ - if: unix
+ then: bash ${RECIPE_DIR}/build-libitk-wrapping.sh
+ - if: win
+ then: cmd /c ${RECIPE_DIR}/build-libitk-wrapping.bat
+
+requirements:
+ build:
+ - ${{ compiler('c') }}
+ - ${{ compiler('cxx') }}
+ - cmake >=3.26
+ - ninja
+ host:
+ - python
+ - swig >=4.1
+ - castxml
+ - expat
+ - hdf5
+ - libjpeg-turbo
+ - libtiff
+ - libpng
+ - eigen
+ - zlib
+ - fftw
+ - tbb-devel
+ - doxygen
+ run:
+ - python
+ - tbb
+ - hdf5
+ - fftw
+ - libjpeg-turbo
+ - libtiff
+ - libpng
+ - expat
+ - zlib
+
+about:
+ home: https://itk.org
+ license: Apache-2.0
+ license_file: LICENSE
+ summary: >
+ ITK C++ libraries with Python wrapping artifacts (SWIG interfaces,
+ CastXML outputs, compiled Python modules). Used as a build dependency
+ for ITK Python wheel generation and remote module packaging.
+ dev_url: https://github.com/InsightSoftwareConsortium/ITK
diff --git a/pixi.lock b/pixi.lock
new file mode 100644
index 00000000..e1622f65
--- /dev/null
+++ b/pixi.lock
@@ -0,0 +1,13400 @@
+version: 6
+environments:
+ default:
+ channels:
+ - url: https://conda.anaconda.org/conda-forge/
+ options:
+ pypi-prerelease-mode: if-necessary-or-explicit
+ packages:
+ linux-64:
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/_openmp_mutex-4.5-20_gnu.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/archspec-0.2.5-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/backports.zstd-1.3.0-py314h680f03e_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/boltons-25.0.0-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/brotli-python-1.2.0-py314h3de4e8d_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/bzip2-1.0.8-hda65f42_9.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/c-ares-1.34.6-hb03c661_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2026.2.25-hbd8a1cb_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/certifi-2026.2.25-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/cffi-2.0.0-py314h4a8dc5f_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/cfgv-3.5.0-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/charset-normalizer-3.4.5-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/conda-26.1.1-py314hdafbbf9_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/conda-libmamba-solver-25.11.0-pyhd8ed1ab_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/conda-package-handling-2.4.0-pyh7900ff3_2.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/conda-package-streaming-0.12.0-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/cpp-expected-1.3.1-h171cf75_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/distlib-0.4.0-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/distro-1.9.0-pyhd8ed1ab_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/filelock-3.25.2-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/fmt-12.1.0-hff5e90c_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/frozendict-2.4.7-py314h5bd0f2a_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/h2-4.3.0-pyhcf101f3_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/hpack-4.1.0-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/hyperframe-6.1.0-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/icu-78.2-h33c6efd_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/identify-2.6.18-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/idna-3.11-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/importlib-metadata-8.8.0-pyhcf101f3_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/jsonpatch-1.33-pyhd8ed1ab_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/jsonpointer-3.0.0-pyhcf101f3_3.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/keyutils-1.6.3-hb9d3cd8_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/krb5-1.22.2-ha1258a1_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/ld_impl_linux-64-2.45.1-default_hbd61a6d_101.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/libarchive-3.8.6-gpl_hc2c16d8_100.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/libcurl-8.19.0-hcf29cc6_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/libedit-3.1.20250104-pl5321h7949ede_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/libev-4.33-hd590300_2.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/libexpat-2.7.4-hecca717_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/libffi-3.5.2-h3435931_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/libgcc-15.2.0-he0feb66_18.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/libgcc-ng-15.2.0-h69a702a_18.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/libgomp-15.2.0-he0feb66_18.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/libiconv-1.18-h3b78370_2.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/liblzma-5.8.2-hb03c661_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/libmamba-2.5.0-hd28c85e_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/libmamba-spdlog-2.5.0-h12fcf84_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/libmambapy-2.5.0-py314hcbd71af_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/libmpdec-4.0.0-hb03c661_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/libnghttp2-1.67.0-had1ee68_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/libsolv-0.7.35-h9463b59_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/libsqlite-3.52.0-hf4e2dac_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/libssh2-1.11.1-hcf80075_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-15.2.0-h934c35e_18.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/libuuid-2.41.3-h5347b49_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/libxml2-16-2.15.2-hca6bf5a_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/libxml2-2.15.2-he237659_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/libzlib-1.3.1-hb9d3cd8_2.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/lz4-c-1.10.0-h5888daf_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/lzo-2.10-h280c20c_1002.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/menuinst-2.4.2-py314hdafbbf9_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/msgpack-python-1.1.2-py314h9891dd4_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/ncurses-6.5-h2d0b736_3.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/nlohmann_json-abi-3.12.0-h0f90c79_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/nodeenv-1.10.0-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/openssl-3.6.1-h35e630c_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/packaging-26.0-pyhcf101f3_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/pixi-pycharm-0.0.10-unix_hf108a03_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/platformdirs-4.9.4-pyhcf101f3_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/pluggy-1.6.0-pyhf9edf01_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/pre-commit-4.5.1-pyha770c72_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/pybind11-abi-11-hc364b38_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/pycosat-0.6.6-py314h5bd0f2a_3.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/pycparser-2.22-pyh29332c3_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/pysocks-1.7.1-pyha55dd90_7.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/python-3.14.3-h32b2ec7_101_cp314.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/python-discovery-1.2.1-pyhcf101f3_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/python_abi-3.14-8_cp314.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/pyyaml-6.0.3-py314h67df5f8_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/readline-8.3-h853b02a_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/reproc-14.2.5.post0-hb9d3cd8_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/reproc-cpp-14.2.5.post0-h5888daf_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/requests-2.32.5-pyhcf101f3_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/ruamel.yaml-0.18.17-py314h0f05182_2.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/ruamel.yaml.clib-0.2.15-py314h0f05182_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/setuptools-82.0.1-pyh332efcf_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/simdjson-4.2.4-hb700be7_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/spdlog-1.17.0-hab81395_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/taplo-0.10.0-h2d22210_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/tk-8.6.13-noxft_h366c992_103.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/tqdm-4.67.3-pyh8f84b5b_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/truststore-0.10.4-pyhcf101f3_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/typing_extensions-4.15.0-pyhcf101f3_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/tzdata-2025c-hc9c84f9_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/ukkonen-1.1.0-py314h9891dd4_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/urllib3-2.6.3-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/virtualenv-21.2.0-pyhcf101f3_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/yaml-0.2.5-h280c20c_3.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/yaml-cpp-0.8.0-h3f2d84a_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/zipp-3.23.0-pyhcf101f3_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/zstandard-0.25.0-py314h0f05182_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/zstd-1.5.7-hb78ec9c_6.conda
+ linux-aarch64:
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/_openmp_mutex-4.5-20_gnu.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/archspec-0.2.5-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/backports.zstd-1.3.0-py314h680f03e_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/boltons-25.0.0-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/brotli-python-1.2.0-py314h352cb57_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/bzip2-1.0.8-h4777abc_9.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/c-ares-1.34.6-he30d5cf_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2026.2.25-hbd8a1cb_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/certifi-2026.2.25-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/cffi-2.0.0-py314h0bd77cf_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/cfgv-3.5.0-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/charset-normalizer-3.4.5-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/conda-26.1.1-py314h28a4750_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/conda-libmamba-solver-25.11.0-pyhd8ed1ab_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/conda-package-handling-2.4.0-pyh7900ff3_2.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/conda-package-streaming-0.12.0-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/cpp-expected-1.3.1-hdc560ac_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/distlib-0.4.0-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/distro-1.9.0-pyhd8ed1ab_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/filelock-3.25.2-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/fmt-12.1.0-h20c602a_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/frozendict-2.4.7-py314h51f160d_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/h2-4.3.0-pyhcf101f3_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/hpack-4.1.0-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/hyperframe-6.1.0-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/icu-78.2-hcab7f73_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/identify-2.6.18-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/idna-3.11-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/importlib-metadata-8.8.0-pyhcf101f3_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/jsonpatch-1.33-pyhd8ed1ab_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/jsonpointer-3.0.0-pyhcf101f3_3.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/keyutils-1.6.3-h86ecc28_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/krb5-1.22.2-hfd895c2_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/ld_impl_linux-aarch64-2.45.1-default_h1979696_101.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libarchive-3.8.6-gpl_hbe7d12b_100.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libcurl-8.19.0-hc57f145_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libedit-3.1.20250104-pl5321h976ea20_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libev-4.33-h31becfc_2.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libexpat-2.7.4-hfae3067_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libffi-3.5.2-h376a255_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libgcc-15.2.0-h8acb6b2_18.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libgcc-ng-15.2.0-he9431aa_18.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libgomp-15.2.0-h8acb6b2_18.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libiconv-1.18-h90929bb_2.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/liblzma-5.8.2-he30d5cf_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libmamba-2.5.0-hc712cdd_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libmamba-spdlog-2.5.0-h3ad78e7_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libmambapy-2.5.0-py314h709e558_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libmpdec-4.0.0-he30d5cf_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libnghttp2-1.67.0-ha888d0e_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libsolv-0.7.35-hdda61c4_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libsqlite-3.52.0-h10b116e_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libssh2-1.11.1-h18c354c_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libstdcxx-15.2.0-hef695bb_18.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libuuid-2.41.3-h1022ec0_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libxml2-16-2.15.2-h79dcc73_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libxml2-2.15.2-h825857f_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libzlib-1.3.1-h86ecc28_2.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/lz4-c-1.10.0-h5ad3122_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/lzo-2.10-h80f16a2_1002.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/menuinst-2.4.2-py314h28a4750_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/msgpack-python-1.1.2-py314hd7d8586_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/ncurses-6.5-ha32ae93_3.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/nlohmann_json-abi-3.12.0-h0f90c79_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/nodeenv-1.10.0-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/openssl-3.6.1-h546c87b_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/packaging-26.0-pyhcf101f3_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/pixi-pycharm-0.0.10-unix_hf108a03_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/platformdirs-4.9.4-pyhcf101f3_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/pluggy-1.6.0-pyhf9edf01_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/pre-commit-4.5.1-pyha770c72_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/pybind11-abi-11-hc364b38_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/pycosat-0.6.6-py314h51f160d_3.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/pycparser-2.22-pyh29332c3_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/pysocks-1.7.1-pyha55dd90_7.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/python-3.14.3-hb06a95a_101_cp314.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/python-discovery-1.2.1-pyhcf101f3_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/python_abi-3.14-8_cp314.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/pyyaml-6.0.3-py314h807365f_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/readline-8.3-hb682ff5_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/reproc-14.2.5.post0-h86ecc28_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/reproc-cpp-14.2.5.post0-h5ad3122_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/requests-2.32.5-pyhcf101f3_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/ruamel.yaml-0.18.17-py314h2e8dab5_2.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/ruamel.yaml.clib-0.2.15-py314h2e8dab5_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/setuptools-82.0.1-pyh332efcf_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/simdjson-4.2.4-hfefdfc9_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/spdlog-1.17.0-h9f97df7_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/taplo-0.10.0-h3618846_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/tk-8.6.13-noxft_h0dc03b3_103.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/tqdm-4.67.3-pyh8f84b5b_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/truststore-0.10.4-pyhcf101f3_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/typing_extensions-4.15.0-pyhcf101f3_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/tzdata-2025c-hc9c84f9_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/ukkonen-1.1.0-py314hd7d8586_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/urllib3-2.6.3-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/virtualenv-21.2.0-pyhcf101f3_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/yaml-0.2.5-h80f16a2_3.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/yaml-cpp-0.8.0-h5ad3122_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/zipp-3.23.0-pyhcf101f3_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/zstandard-0.25.0-py314h2e8dab5_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/zstd-1.5.7-h85ac4a6_6.conda
+ osx-64:
+ - conda: https://conda.anaconda.org/conda-forge/noarch/archspec-0.2.5-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/backports.zstd-1.3.0-py314h680f03e_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/boltons-25.0.0-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-64/brotli-python-1.2.0-py314h3262eb8_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-64/bzip2-1.0.8-h500dc9f_9.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-64/c-ares-1.34.6-hb5e19a0_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2026.2.25-hbd8a1cb_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/certifi-2026.2.25-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-64/cffi-2.0.0-py314h8ca4d5a_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/cfgv-3.5.0-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/charset-normalizer-3.4.5-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-64/conda-26.1.1-py314hee6578b_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/conda-libmamba-solver-25.11.0-pyhd8ed1ab_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/conda-package-handling-2.4.0-pyh7900ff3_2.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/conda-package-streaming-0.12.0-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-64/cpp-expected-1.3.1-h0ba0a54_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/distlib-0.4.0-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/distro-1.9.0-pyhd8ed1ab_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/filelock-3.25.2-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-64/fmt-12.1.0-hda137b5_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-64/frozendict-2.4.7-py314h6482030_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/h2-4.3.0-pyhcf101f3_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/hpack-4.1.0-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/hyperframe-6.1.0-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-64/icu-78.2-h14c5de8_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/identify-2.6.18-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/idna-3.11-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/importlib-metadata-8.8.0-pyhcf101f3_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/jsonpatch-1.33-pyhd8ed1ab_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/jsonpointer-3.0.0-pyhcf101f3_3.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-64/krb5-1.22.2-h207b36a_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-64/libarchive-3.8.6-gpl_h2bf6321_100.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-64/libcurl-8.19.0-h8f0b9e4_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-64/libcxx-22.1.1-h19cb2f5_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-64/libedit-3.1.20250104-pl5321ha958ccf_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-64/libev-4.33-h10d778d_2.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-64/libexpat-2.7.4-h991f03e_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-64/libffi-3.5.2-hd1f9c09_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-64/libiconv-1.18-h57a12c2_2.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-64/liblzma-5.8.2-h11316ed_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-64/libmamba-2.5.0-h7fe6c55_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-64/libmamba-spdlog-2.5.0-hb923e0c_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-64/libmambapy-2.5.0-py314haca2e77_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-64/libmpdec-4.0.0-hf3981d6_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-64/libnghttp2-1.67.0-h3338091_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-64/libsolv-0.7.35-h6fd32b5_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-64/libsqlite-3.52.0-h77d7759_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-64/libssh2-1.11.1-hed3591d_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-64/libxml2-16-2.15.2-h7a90416_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-64/libxml2-2.15.2-hd552753_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-64/libzlib-1.3.1-hd23fc13_2.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-64/lz4-c-1.10.0-h240833e_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-64/lzo-2.10-h4132b18_1002.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-64/menuinst-2.4.2-py314hee6578b_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-64/msgpack-python-1.1.2-py314h00ed6fe_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-64/ncurses-6.5-h0622a9a_3.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/nlohmann_json-abi-3.12.0-h0f90c79_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/nodeenv-1.10.0-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-64/openssl-3.6.1-hb6871ef_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/packaging-26.0-pyhcf101f3_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/pixi-pycharm-0.0.10-unix_hf108a03_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/platformdirs-4.9.4-pyhcf101f3_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/pluggy-1.6.0-pyhf9edf01_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/pre-commit-4.5.1-pyha770c72_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/pybind11-abi-11-hc364b38_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-64/pycosat-0.6.6-py314h03d016b_3.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/pycparser-2.22-pyh29332c3_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/pysocks-1.7.1-pyha55dd90_7.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-64/python-3.14.3-h4f44bb5_101_cp314.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/python-discovery-1.2.1-pyhcf101f3_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/python_abi-3.14-8_cp314.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-64/pyyaml-6.0.3-py314h10d0514_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-64/readline-8.3-h68b038d_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-64/reproc-14.2.5.post0-h6e16a3a_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-64/reproc-cpp-14.2.5.post0-h240833e_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/requests-2.32.5-pyhcf101f3_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-64/ruamel.yaml-0.18.17-py314hd330473_2.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-64/ruamel.yaml.clib-0.2.15-py314hd330473_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/setuptools-82.0.1-pyh332efcf_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-64/simdjson-4.2.4-hcb651aa_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-64/spdlog-1.17.0-h30f01e4_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-64/taplo-0.10.0-hffa81eb_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-64/tk-8.6.13-h7142dee_3.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/tqdm-4.67.3-pyh8f84b5b_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/truststore-0.10.4-pyhcf101f3_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/typing_extensions-4.15.0-pyhcf101f3_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/tzdata-2025c-hc9c84f9_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-64/ukkonen-1.1.0-py314h473ef84_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/urllib3-2.6.3-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/virtualenv-21.2.0-pyhcf101f3_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-64/yaml-0.2.5-h4132b18_3.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-64/yaml-cpp-0.8.0-h92383a6_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/zipp-3.23.0-pyhcf101f3_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-64/zstandard-0.25.0-py314hd1e8ddb_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-64/zstd-1.5.7-h3eecb57_6.conda
+ osx-arm64:
+ - conda: https://conda.anaconda.org/conda-forge/noarch/archspec-0.2.5-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/backports.zstd-1.3.0-py314h680f03e_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/boltons-25.0.0-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-arm64/brotli-python-1.2.0-py314h3daef5d_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-arm64/bzip2-1.0.8-hd037594_9.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-arm64/c-ares-1.34.6-hc919400_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2026.2.25-hbd8a1cb_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/certifi-2026.2.25-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-arm64/cffi-2.0.0-py314h44086f9_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/cfgv-3.5.0-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/charset-normalizer-3.4.5-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-arm64/conda-26.1.1-py314h4dc9dd8_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/conda-libmamba-solver-25.11.0-pyhd8ed1ab_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/conda-package-handling-2.4.0-pyh7900ff3_2.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/conda-package-streaming-0.12.0-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-arm64/cpp-expected-1.3.1-h4f10f1e_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/distlib-0.4.0-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/distro-1.9.0-pyhd8ed1ab_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/filelock-3.25.2-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-arm64/fmt-12.1.0-h403dcb5_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-arm64/frozendict-2.4.7-py314h0612a62_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/h2-4.3.0-pyhcf101f3_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/hpack-4.1.0-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/hyperframe-6.1.0-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-arm64/icu-78.2-hef89b57_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/identify-2.6.18-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/idna-3.11-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/importlib-metadata-8.8.0-pyhcf101f3_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/jsonpatch-1.33-pyhd8ed1ab_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/jsonpointer-3.0.0-pyhcf101f3_3.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-arm64/krb5-1.22.2-h385eeb1_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libarchive-3.8.6-gpl_h6fbacd7_100.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libcurl-8.19.0-hd5a2499_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libcxx-22.1.1-h55c6f16_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libedit-3.1.20250104-pl5321hafb1f1b_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libev-4.33-h93a5062_2.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libexpat-2.7.4-hf6b4638_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libffi-3.5.2-hcf2aa1b_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libiconv-1.18-h23cfdf5_2.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-arm64/liblzma-5.8.2-h8088a28_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libmamba-2.5.0-h7950639_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libmamba-spdlog-2.5.0-h85b9800_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libmambapy-2.5.0-py314hf8f60b7_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libmpdec-4.0.0-h84a0fba_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libnghttp2-1.67.0-hc438710_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libsolv-0.7.35-h5f525b2_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libsqlite-3.52.0-h1ae2325_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libssh2-1.11.1-h1590b86_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libxml2-16-2.15.2-h5ef1a60_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libxml2-2.15.2-h8d039ee_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libzlib-1.3.1-h8359307_2.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-arm64/lz4-c-1.10.0-h286801f_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-arm64/lzo-2.10-h925e9cb_1002.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-arm64/menuinst-2.4.2-py314h4dc9dd8_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-arm64/msgpack-python-1.1.2-py314h784bc60_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-arm64/ncurses-6.5-h5e97a16_3.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/nlohmann_json-abi-3.12.0-h0f90c79_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/nodeenv-1.10.0-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-arm64/openssl-3.6.1-hd24854e_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/packaging-26.0-pyhcf101f3_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/pixi-pycharm-0.0.10-unix_hf108a03_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/platformdirs-4.9.4-pyhcf101f3_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/pluggy-1.6.0-pyhf9edf01_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/pre-commit-4.5.1-pyha770c72_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/pybind11-abi-11-hc364b38_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-arm64/pycosat-0.6.6-py314hb84d1df_3.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/pycparser-2.22-pyh29332c3_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/pysocks-1.7.1-pyha55dd90_7.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-arm64/python-3.14.3-h4c637c5_101_cp314.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/python-discovery-1.2.1-pyhcf101f3_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/python_abi-3.14-8_cp314.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-arm64/pyyaml-6.0.3-py314h6e9b3f0_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-arm64/readline-8.3-h46df422_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-arm64/reproc-14.2.5.post0-h5505292_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-arm64/reproc-cpp-14.2.5.post0-h286801f_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/requests-2.32.5-pyhcf101f3_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-arm64/ruamel.yaml-0.18.17-py314ha14b1ff_2.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-arm64/ruamel.yaml.clib-0.2.15-py314ha14b1ff_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/setuptools-82.0.1-pyh332efcf_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-arm64/simdjson-4.2.4-ha7d2532_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-arm64/spdlog-1.17.0-ha0f8610_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-arm64/taplo-0.10.0-h2b2570c_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-arm64/tk-8.6.13-h010d191_3.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/tqdm-4.67.3-pyh8f84b5b_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/truststore-0.10.4-pyhcf101f3_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/typing_extensions-4.15.0-pyhcf101f3_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/tzdata-2025c-hc9c84f9_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-arm64/ukkonen-1.1.0-py314h6cfcd04_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/urllib3-2.6.3-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/virtualenv-21.2.0-pyhcf101f3_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-arm64/yaml-0.2.5-h925e9cb_3.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-arm64/yaml-cpp-0.8.0-ha1acc90_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/zipp-3.23.0-pyhcf101f3_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-arm64/zstandard-0.25.0-py314h9d33bd4_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-arm64/zstd-1.5.7-hbf9d68e_6.conda
+ win-64:
+ - conda: https://conda.anaconda.org/conda-forge/noarch/archspec-0.2.5-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/backports.zstd-1.3.0-py314h680f03e_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/boltons-25.0.0-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/win-64/brotli-python-1.2.0-py314he701e3d_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/win-64/bzip2-1.0.8-h0ad9c76_9.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2026.2.25-h4c7d964_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/certifi-2026.2.25-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/win-64/cffi-2.0.0-py314h5a2d7ad_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/cfgv-3.5.0-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/charset-normalizer-3.4.5-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/colorama-0.4.6-pyhd8ed1ab_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/win-64/conda-26.1.1-py314h86ab7b2_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/conda-libmamba-solver-25.11.0-pyhd8ed1ab_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/conda-package-handling-2.4.0-pyh7900ff3_2.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/conda-package-streaming-0.12.0-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/win-64/cpp-expected-1.3.1-h477610d_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/distlib-0.4.0-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/distro-1.9.0-pyhd8ed1ab_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/filelock-3.25.2-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/win-64/fmt-12.1.0-h7f4e812_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/win-64/frozendict-2.4.7-py314h5a2d7ad_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/h2-4.3.0-pyhcf101f3_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/hpack-4.1.0-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/hyperframe-6.1.0-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/identify-2.6.18-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/idna-3.11-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/importlib-metadata-8.8.0-pyhcf101f3_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/jsonpatch-1.33-pyhd8ed1ab_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/jsonpointer-3.0.0-pyhcf101f3_3.conda
+ - conda: https://conda.anaconda.org/conda-forge/win-64/krb5-1.22.2-h0ea6238_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/win-64/libarchive-3.8.6-gpl_he24518a_100.conda
+ - conda: https://conda.anaconda.org/conda-forge/win-64/libcurl-8.19.0-h8206538_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/win-64/libexpat-2.7.4-hac47afa_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/win-64/libffi-3.5.2-h3d046cb_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/win-64/libiconv-1.18-hc1393d2_2.conda
+ - conda: https://conda.anaconda.org/conda-forge/win-64/liblzma-5.8.2-hfd05255_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/win-64/libmamba-2.5.0-h06825f5_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/win-64/libmamba-spdlog-2.5.0-h9ae1bf1_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/win-64/libmambapy-2.5.0-py314h532c739_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/win-64/libmpdec-4.0.0-hfd05255_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/win-64/libsolv-0.7.35-h8883371_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/win-64/libsqlite-3.52.0-hf5d6505_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/win-64/libssh2-1.11.1-h9aa295b_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/win-64/libxml2-16-2.15.2-h692994f_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/win-64/libxml2-2.15.2-h5d26750_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/win-64/libzlib-1.3.1-h2466b09_2.conda
+ - conda: https://conda.anaconda.org/conda-forge/win-64/lz4-c-1.10.0-h2466b09_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/win-64/lzo-2.10-h6a83c73_1002.conda
+ - conda: https://conda.anaconda.org/conda-forge/win-64/menuinst-2.4.2-py314h13fbf68_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/win-64/msgpack-python-1.1.2-py314h909e829_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/nlohmann_json-abi-3.12.0-h0f90c79_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/nodeenv-1.10.0-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/win-64/openssl-3.6.1-hf411b9b_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/packaging-26.0-pyhcf101f3_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/pixi-pycharm-0.0.10-win_hba80fca_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/platformdirs-4.9.4-pyhcf101f3_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/pluggy-1.6.0-pyhf9edf01_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/pre-commit-4.5.1-pyha770c72_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/pybind11-abi-11-hc364b38_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/win-64/pycosat-0.6.6-py314h5a2d7ad_3.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/pycparser-2.22-pyh29332c3_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/pysocks-1.7.1-pyh09c184e_7.conda
+ - conda: https://conda.anaconda.org/conda-forge/win-64/python-3.14.3-h4b44e0e_101_cp314.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/python-discovery-1.2.1-pyhcf101f3_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/python_abi-3.14-8_cp314.conda
+ - conda: https://conda.anaconda.org/conda-forge/win-64/pyyaml-6.0.3-py314h2359020_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/win-64/reproc-14.2.5.post0-h2466b09_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/win-64/reproc-cpp-14.2.5.post0-he0c23c2_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/requests-2.32.5-pyhcf101f3_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/win-64/ruamel.yaml-0.18.17-py314hc5dbbe4_2.conda
+ - conda: https://conda.anaconda.org/conda-forge/win-64/ruamel.yaml.clib-0.2.15-py314hc5dbbe4_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/setuptools-82.0.1-pyh332efcf_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/win-64/simdjson-4.2.4-h49e36cd_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/win-64/spdlog-1.17.0-h9f585f1_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/win-64/taplo-0.10.0-h63977a8_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/win-64/tk-8.6.13-h6ed50ae_3.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/tqdm-4.67.3-pyha7b4d00_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/truststore-0.10.4-pyhcf101f3_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/typing_extensions-4.15.0-pyhcf101f3_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/tzdata-2025c-hc9c84f9_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/win-64/ucrt-10.0.26100.0-h57928b3_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/win-64/ukkonen-1.1.0-py314h909e829_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/urllib3-2.6.3-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/win-64/vc-14.3-h41ae7f8_34.conda
+ - conda: https://conda.anaconda.org/conda-forge/win-64/vc14_runtime-14.44.35208-h818238b_34.conda
+ - conda: https://conda.anaconda.org/conda-forge/win-64/vcomp14-14.44.35208-h818238b_34.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/virtualenv-21.2.0-pyhcf101f3_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/win_inet_pton-1.1.0-pyh7428d3b_8.conda
+ - conda: https://conda.anaconda.org/conda-forge/win-64/yaml-0.2.5-h6a83c73_3.conda
+ - conda: https://conda.anaconda.org/conda-forge/win-64/yaml-cpp-0.8.0-he0c23c2_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/zipp-3.23.0-pyhcf101f3_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/win-64/zstandard-0.25.0-py314hc5dbbe4_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/win-64/zstd-1.5.7-h534d264_6.conda
+ linux-py310:
+ channels:
+ - url: https://conda.anaconda.org/conda-forge/
+ indexes:
+ - https://pypi.org/simple
+ options:
+ pypi-prerelease-mode: if-necessary-or-explicit
+ packages:
+ linux-64:
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/_openmp_mutex-4.5-20_gnu.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/archspec-0.2.5-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/auditwheel-6.6.0-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/backports.zstd-1.3.0-py310h69bd2ac_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/binutils-2.45.1-default_h4852527_101.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/binutils_impl_linux-64-2.45.1-default_hfdba357_101.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/binutils_linux-64-2.45.1-default_h4852527_101.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/boltons-25.0.0-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/brotli-python-1.2.0-py310hba01987_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/bzip2-1.0.8-hda65f42_9.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/c-ares-1.34.6-hb03c661_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/c-compiler-1.11.0-h4d9bdce_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2026.2.25-hbd8a1cb_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/certifi-2026.2.25-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/cffi-2.0.0-py310he7384ee_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/cfgv-3.5.0-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/charset-normalizer-3.4.5-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/cmake-3.31.8-hc85cc9f_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/conda-26.1.1-py310hff52083_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/conda-gcc-specs-14.3.0-he8ccf15_18.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/conda-libmamba-solver-25.11.0-pyhd8ed1ab_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/conda-package-handling-2.4.0-pyh7900ff3_2.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/conda-package-streaming-0.12.0-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/cpp-expected-1.3.1-h171cf75_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/cxx-compiler-1.11.0-hfcd1e18_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/distlib-0.4.0-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/distro-1.9.0-pyhd8ed1ab_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/doxygen-1.13.2-h8e693c7_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/exceptiongroup-1.3.1-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/filelock-3.25.2-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/fmt-12.1.0-hff5e90c_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/frozendict-2.4.7-py310h7c4b9e2_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/gcc-14.3.0-h0dff253_18.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/gcc_impl_linux-64-14.3.0-hbdf3cc3_18.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/gcc_linux-64-14.3.0-h298d278_21.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/gxx-14.3.0-h76987e4_18.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/gxx_impl_linux-64-14.3.0-h2185e75_18.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/gxx_linux-64-14.3.0-he467f4b_21.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/h2-4.3.0-pyhcf101f3_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/hpack-4.1.0-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/hyperframe-6.1.0-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/icu-78.2-h33c6efd_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/identify-2.6.18-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/idna-3.11-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/importlib-metadata-8.7.0-pyhe01879c_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/importlib-resources-6.5.2-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/importlib_resources-6.5.2-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/jsonpatch-1.33-pyhd8ed1ab_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/jsonpointer-3.0.0-pyhcf101f3_3.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/kernel-headers_linux-64-4.18.0-he073ed8_9.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/keyutils-1.6.3-hb9d3cd8_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/krb5-1.22.2-ha1258a1_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/ld_impl_linux-64-2.45.1-default_hbd61a6d_101.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/libarchive-3.8.6-gpl_hc2c16d8_100.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/libblas-3.11.0-5_h4a7cf45_openblas.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/libcblas-3.11.0-5_h0358290_openblas.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/libcurl-8.19.0-hcf29cc6_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/libedit-3.1.20250104-pl5321h7949ede_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/libev-4.33-hd590300_2.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/libexpat-2.7.4-hecca717_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/libffi-3.5.2-h3435931_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/libgcc-15.2.0-he0feb66_18.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/libgcc-devel_linux-64-14.3.0-hf649bbc_118.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/libgcc-ng-15.2.0-h69a702a_18.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/libgfortran-15.2.0-h69a702a_18.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/libgfortran5-15.2.0-h68bc16d_18.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/libgomp-15.2.0-he0feb66_18.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/libhwloc-2.13.0-default_he001693_1000.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/libiconv-1.18-h3b78370_2.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/liblapack-3.11.0-5_h47877c9_openblas.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/liblzma-5.8.2-hb03c661_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/libmamba-2.5.0-hd28c85e_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/libmamba-spdlog-2.5.0-h12fcf84_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/libmambapy-2.5.0-py310h74f1d5f_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/libnghttp2-1.67.0-had1ee68_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/libnsl-2.0.1-hb9d3cd8_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/libopenblas-0.3.30-pthreads_h94d23a6_4.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/libsanitizer-14.3.0-h8f1669f_18.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/libsolv-0.7.35-h9463b59_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/libsqlite-3.52.0-hf4e2dac_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/libssh2-1.11.1-hcf80075_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-15.2.0-h934c35e_18.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/libstdcxx-devel_linux-64-14.3.0-h9f08a49_118.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-ng-15.2.0-hdf11a46_18.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/libuuid-2.41.3-h5347b49_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/libuv-1.51.0-hb03c661_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/libxcrypt-4.4.36-hd590300_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/libxml2-16-2.15.2-hca6bf5a_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/libxml2-2.15.2-he237659_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/libzlib-1.3.1-hb9d3cd8_2.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/lz4-c-1.10.0-h5888daf_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/lzo-2.10-h280c20c_1002.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/menuinst-2.4.2-py310hff52083_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/msgpack-python-1.1.2-py310h03d9f68_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/ncurses-6.5-h2d0b736_3.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/ninja-1.13.2-h171cf75_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/nlohmann_json-abi-3.12.0-h0f90c79_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/nodeenv-1.10.0-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/numpy-2.2.6-py310hefbff90_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/openssl-3.6.1-h35e630c_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/packaging-25.0-pyh29332c3_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/patchelf-0.17.2-h58526e2_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/pathspec-1.0.4-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/pip-26.0.1-pyh8b19718_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/pixi-pycharm-0.0.10-unix_hf108a03_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/pkginfo-1.12.1.2-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/platformdirs-4.9.4-pyhcf101f3_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/pluggy-1.6.0-pyhf9edf01_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/pre-commit-4.5.1-pyha770c72_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/pybind11-abi-11-hc364b38_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/pycosat-0.6.6-py310h7c4b9e2_3.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/pycparser-2.22-pyh29332c3_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/pyelftools-0.32-pyh707e725_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/pyproject-metadata-0.11.0-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/pysocks-1.7.1-pyha55dd90_7.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/python-3.10.20-h3c07f61_0_cpython.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/python-discovery-1.2.1-pyhcf101f3_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/python_abi-3.10-8_cp310.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/pyyaml-6.0.3-py310h3406613_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/readline-8.3-h853b02a_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/reproc-14.2.5.post0-hb9d3cd8_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/reproc-cpp-14.2.5.post0-h5888daf_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/requests-2.32.5-pyhcf101f3_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/rhash-1.4.6-hb9d3cd8_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/ruamel.yaml-0.18.17-py310h139afa4_2.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/ruamel.yaml.clib-0.2.15-py310h139afa4_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/scikit-build-core-0.11.6-pyh7e86bf3_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/setuptools-82.0.1-pyh332efcf_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/setuptools-scm-9.2.2-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/setuptools_scm-9.2.2-hd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/simdjson-4.2.4-hb700be7_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/spdlog-1.17.0-hab81395_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/sysroot_linux-64-2.28-h4ee821c_9.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/taplo-0.10.0-h2d22210_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/tk-8.6.13-noxft_h366c992_103.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/tomli-2.4.0-pyhcf101f3_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/tqdm-4.67.3-pyh8f84b5b_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/truststore-0.10.4-pyhcf101f3_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/typing-extensions-4.15.0-h396c80c_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/typing_extensions-4.15.0-pyhcf101f3_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/tzdata-2025c-hc9c84f9_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/ukkonen-1.1.0-py310h03d9f68_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/urllib3-2.6.3-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/virtualenv-21.2.0-pyhcf101f3_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/wheel-0.46.3-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/yaml-0.2.5-h280c20c_3.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/yaml-cpp-0.8.0-h3f2d84a_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/zipp-3.23.0-pyhcf101f3_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/zstandard-0.25.0-py310h139afa4_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/zstd-1.5.7-hb78ec9c_6.conda
+ - pypi: https://files.pythonhosted.org/packages/c5/0d/84a4380f930db0010168e0aa7b7a8fed9ba1835a8fbb1472bc6d0201d529/build-1.4.0-py3-none-any.whl
+ - pypi: https://files.pythonhosted.org/packages/bd/24/12818598c362d7f300f18e74db45963dbcb85150324092410c8b49405e42/pyproject_hooks-1.2.0-py3-none-any.whl
+ linux-aarch64:
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/_openmp_mutex-4.5-20_gnu.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/archspec-0.2.5-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/auditwheel-6.6.0-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/backports.zstd-1.3.0-py310hfa1aa29_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/binutils-2.45.1-default_hf1166c9_101.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/binutils_impl_linux-aarch64-2.45.1-default_h5f4c503_101.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/binutils_linux-aarch64-2.45.1-default_hf1166c9_101.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/boltons-25.0.0-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/brotli-python-1.2.0-py310hbe54bbb_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/bzip2-1.0.8-h4777abc_9.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/c-ares-1.34.6-he30d5cf_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/c-compiler-1.11.0-hdceaead_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2026.2.25-hbd8a1cb_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/certifi-2026.2.25-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/cffi-2.0.0-py310h0826a50_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/cfgv-3.5.0-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/charset-normalizer-3.4.6-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/cmake-3.31.8-hc9d863e_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/conda-26.1.1-py310h4c7bcd0_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/conda-gcc-specs-14.3.0-hadff5d6_18.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/conda-libmamba-solver-25.11.0-pyhd8ed1ab_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/conda-package-handling-2.4.0-pyh7900ff3_2.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/conda-package-streaming-0.12.0-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/cpp-expected-1.3.1-hdc560ac_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/cxx-compiler-1.11.0-h7b35c40_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/distlib-0.4.0-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/distro-1.9.0-pyhd8ed1ab_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/doxygen-1.13.2-h5e0f5ae_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/exceptiongroup-1.3.1-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/filelock-3.25.2-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/fmt-12.1.0-h20c602a_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/frozendict-2.4.7-py310h5b55623_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/gcc-14.3.0-h2e72a27_18.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/gcc_impl_linux-aarch64-14.3.0-h533bfc8_18.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/gcc_linux-aarch64-14.3.0-h118592a_21.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/gxx-14.3.0-ha384071_18.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/gxx_impl_linux-aarch64-14.3.0-h0d4f5d4_18.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/gxx_linux-aarch64-14.3.0-h32e4f2e_21.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/h2-4.3.0-pyhcf101f3_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/hpack-4.1.0-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/hyperframe-6.1.0-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/icu-78.3-hcab7f73_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/identify-2.6.18-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/idna-3.11-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/importlib-metadata-8.7.0-pyhe01879c_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/importlib-resources-6.5.2-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/importlib_resources-6.5.2-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/jsonpatch-1.33-pyhd8ed1ab_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/jsonpointer-3.0.0-pyhcf101f3_3.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/kernel-headers_linux-aarch64-4.18.0-h05a177a_9.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/keyutils-1.6.3-h86ecc28_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/krb5-1.22.2-hfd895c2_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/ld_impl_linux-aarch64-2.45.1-default_h1979696_101.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libarchive-3.8.6-gpl_hbe7d12b_100.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libblas-3.11.0-5_haddc8a3_openblas.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libcblas-3.11.0-5_hd72aa62_openblas.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libcurl-8.19.0-hc57f145_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libedit-3.1.20250104-pl5321h976ea20_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libev-4.33-h31becfc_2.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libexpat-2.7.4-hfae3067_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libffi-3.5.2-h376a255_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libgcc-15.2.0-h8acb6b2_18.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/libgcc-devel_linux-aarch64-14.3.0-h25ba3ff_118.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libgcc-ng-15.2.0-he9431aa_18.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libgfortran-15.2.0-he9431aa_18.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libgfortran5-15.2.0-h1b7bec0_18.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libgomp-15.2.0-h8acb6b2_18.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libhwloc-2.13.0-default_ha95e27d_1000.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libiconv-1.18-h90929bb_2.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/liblapack-3.11.0-5_h88aeb00_openblas.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/liblzma-5.8.2-he30d5cf_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libmamba-2.5.0-hc712cdd_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libmamba-spdlog-2.5.0-h3ad78e7_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libmambapy-2.5.0-py310hdf79504_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libnghttp2-1.68.1-hd3077d7_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libnsl-2.0.1-h86ecc28_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libopenblas-0.3.30-pthreads_h9d3fd7e_4.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libsanitizer-14.3.0-hedb4206_18.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libsolv-0.7.36-hdda61c4_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libsqlite-3.52.0-h10b116e_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libssh2-1.11.1-h18c354c_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libstdcxx-15.2.0-hef695bb_18.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/libstdcxx-devel_linux-aarch64-14.3.0-h57c8d61_118.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libstdcxx-ng-15.2.0-hdbbeba8_18.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libuuid-2.41.3-h1022ec0_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libuv-1.51.0-he30d5cf_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libxcrypt-4.4.36-h31becfc_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libxml2-16-2.15.2-h79dcc73_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libxml2-2.15.2-h825857f_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libzlib-1.3.1-h86ecc28_2.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/lz4-c-1.10.0-h5ad3122_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/lzo-2.10-h80f16a2_1002.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/menuinst-2.4.2-py310h4c7bcd0_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/msgpack-python-1.1.2-py310h0992a49_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/ncurses-6.5-ha32ae93_3.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/ninja-1.13.2-hdc560ac_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/nlohmann_json-abi-3.12.0-h0f90c79_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/nodeenv-1.10.0-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/numpy-2.2.6-py310h6e5608f_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/openssl-3.6.1-h546c87b_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/packaging-25.0-pyh29332c3_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/patchelf-0.17.2-h884eca8_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/pathspec-1.0.4-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/pip-26.0.1-pyh8b19718_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/pixi-pycharm-0.0.10-unix_hf108a03_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/pkginfo-1.12.1.2-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/platformdirs-4.9.4-pyhcf101f3_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/pluggy-1.6.0-pyhf9edf01_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/pre-commit-4.5.1-pyha770c72_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/pybind11-abi-11-hc364b38_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/pycosat-0.6.6-py310h5b55623_3.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/pycparser-2.22-pyh29332c3_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/pyelftools-0.32-pyh707e725_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/pyproject-metadata-0.11.0-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/pysocks-1.7.1-pyha55dd90_7.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/python-3.10.20-h28be5d3_0_cpython.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/python-discovery-1.2.1-pyhcf101f3_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/python_abi-3.10-8_cp310.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/pyyaml-6.0.3-py310h2d8da20_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/readline-8.3-hb682ff5_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/reproc-14.2.5.post0-h86ecc28_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/reproc-cpp-14.2.5.post0-h5ad3122_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/requests-2.32.5-pyhcf101f3_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/rhash-1.4.6-h86ecc28_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/ruamel.yaml-0.18.17-py310hef25091_2.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/ruamel.yaml.clib-0.2.15-py310hef25091_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/scikit-build-core-0.11.6-pyh7e86bf3_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/setuptools-82.0.1-pyh332efcf_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/setuptools-scm-9.2.2-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/setuptools_scm-9.2.2-hd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/simdjson-4.2.4-hfefdfc9_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/spdlog-1.17.0-h9f97df7_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/sysroot_linux-aarch64-2.28-h585391f_9.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/taplo-0.10.0-h3618846_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/tk-8.6.13-noxft_h0dc03b3_103.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/tomli-2.4.0-pyhcf101f3_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/tqdm-4.67.3-pyh8f84b5b_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/truststore-0.10.4-pyhcf101f3_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/typing-extensions-4.15.0-h396c80c_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/typing_extensions-4.15.0-pyhcf101f3_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/tzdata-2025c-hc9c84f9_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/ukkonen-1.1.0-py310h0992a49_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/urllib3-2.6.3-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/virtualenv-21.2.0-pyhcf101f3_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/wheel-0.46.3-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/yaml-0.2.5-h80f16a2_3.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/yaml-cpp-0.8.0-h5ad3122_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/zipp-3.23.0-pyhcf101f3_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/zstandard-0.25.0-py310hef25091_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/zstd-1.5.7-h85ac4a6_6.conda
+ - pypi: https://files.pythonhosted.org/packages/c5/0d/84a4380f930db0010168e0aa7b7a8fed9ba1835a8fbb1472bc6d0201d529/build-1.4.0-py3-none-any.whl
+ - pypi: https://files.pythonhosted.org/packages/bd/24/12818598c362d7f300f18e74db45963dbcb85150324092410c8b49405e42/pyproject_hooks-1.2.0-py3-none-any.whl
+ linux-py311:
+ channels:
+ - url: https://conda.anaconda.org/conda-forge/
+ indexes:
+ - https://pypi.org/simple
+ options:
+ pypi-prerelease-mode: if-necessary-or-explicit
+ packages:
+ linux-64:
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/_openmp_mutex-4.5-20_gnu.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/archspec-0.2.5-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/auditwheel-6.6.0-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/backports.zstd-1.3.0-py311h6b1f9c4_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/binutils-2.45.1-default_h4852527_101.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/binutils_impl_linux-64-2.45.1-default_hfdba357_101.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/binutils_linux-64-2.45.1-default_h4852527_101.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/boltons-25.0.0-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/brotli-python-1.2.0-py311h66f275b_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/bzip2-1.0.8-hda65f42_9.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/c-ares-1.34.6-hb03c661_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/c-compiler-1.11.0-h4d9bdce_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2026.2.25-hbd8a1cb_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/certifi-2026.2.25-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/cffi-2.0.0-py311h03d9500_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/cfgv-3.5.0-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/charset-normalizer-3.4.5-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/cmake-3.31.8-hc85cc9f_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/conda-26.1.1-py311h38be061_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/conda-gcc-specs-14.3.0-he8ccf15_18.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/conda-libmamba-solver-25.11.0-pyhd8ed1ab_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/conda-package-handling-2.4.0-pyh7900ff3_2.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/conda-package-streaming-0.12.0-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/cpp-expected-1.3.1-h171cf75_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/cxx-compiler-1.11.0-hfcd1e18_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/distlib-0.4.0-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/distro-1.9.0-pyhd8ed1ab_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/doxygen-1.13.2-h8e693c7_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/exceptiongroup-1.3.1-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/filelock-3.25.2-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/fmt-12.1.0-hff5e90c_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/frozendict-2.4.7-py311h49ec1c0_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/gcc-14.3.0-h0dff253_18.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/gcc_impl_linux-64-14.3.0-hbdf3cc3_18.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/gcc_linux-64-14.3.0-h298d278_21.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/gxx-14.3.0-h76987e4_18.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/gxx_impl_linux-64-14.3.0-h2185e75_18.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/gxx_linux-64-14.3.0-he467f4b_21.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/h2-4.3.0-pyhcf101f3_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/hpack-4.1.0-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/hyperframe-6.1.0-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/icu-78.2-h33c6efd_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/identify-2.6.18-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/idna-3.11-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/importlib-metadata-8.7.0-pyhe01879c_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/importlib-resources-6.5.2-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/importlib_resources-6.5.2-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/jsonpatch-1.33-pyhd8ed1ab_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/jsonpointer-3.0.0-pyhcf101f3_3.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/kernel-headers_linux-64-4.18.0-he073ed8_9.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/keyutils-1.6.3-hb9d3cd8_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/krb5-1.22.2-ha1258a1_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/ld_impl_linux-64-2.45.1-default_hbd61a6d_101.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/libarchive-3.8.6-gpl_hc2c16d8_100.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/libblas-3.11.0-5_h4a7cf45_openblas.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/libcblas-3.11.0-5_h0358290_openblas.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/libcurl-8.19.0-hcf29cc6_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/libedit-3.1.20250104-pl5321h7949ede_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/libev-4.33-hd590300_2.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/libexpat-2.7.4-hecca717_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/libffi-3.5.2-h3435931_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/libgcc-15.2.0-he0feb66_18.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/libgcc-devel_linux-64-14.3.0-hf649bbc_118.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/libgcc-ng-15.2.0-h69a702a_18.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/libgfortran-15.2.0-h69a702a_18.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/libgfortran5-15.2.0-h68bc16d_18.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/libgomp-15.2.0-he0feb66_18.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/libhwloc-2.13.0-default_he001693_1000.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/libiconv-1.18-h3b78370_2.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/liblapack-3.11.0-5_h47877c9_openblas.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/liblzma-5.8.2-hb03c661_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/libmamba-2.5.0-hd28c85e_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/libmamba-spdlog-2.5.0-h12fcf84_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/libmambapy-2.5.0-py311hc5d5c7c_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/libnghttp2-1.67.0-had1ee68_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/libnsl-2.0.1-hb9d3cd8_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/libopenblas-0.3.30-pthreads_h94d23a6_4.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/libsanitizer-14.3.0-h8f1669f_18.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/libsolv-0.7.35-h9463b59_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/libsqlite-3.52.0-hf4e2dac_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/libssh2-1.11.1-hcf80075_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-15.2.0-h934c35e_18.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/libstdcxx-devel_linux-64-14.3.0-h9f08a49_118.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-ng-15.2.0-hdf11a46_18.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/libuuid-2.41.3-h5347b49_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/libuv-1.51.0-hb03c661_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/libxcrypt-4.4.36-hd590300_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/libxml2-16-2.15.2-hca6bf5a_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/libxml2-2.15.2-he237659_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/libzlib-1.3.1-hb9d3cd8_2.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/lz4-c-1.10.0-h5888daf_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/lzo-2.10-h280c20c_1002.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/menuinst-2.4.2-py311h38be061_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/msgpack-python-1.1.2-py311hdf67eae_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/ncurses-6.5-h2d0b736_3.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/ninja-1.13.2-h171cf75_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/nlohmann_json-abi-3.12.0-h0f90c79_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/nodeenv-1.10.0-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/numpy-2.4.2-py311h2e04523_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/openssl-3.6.1-h35e630c_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/packaging-25.0-pyh29332c3_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/patchelf-0.17.2-h58526e2_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/pathspec-1.0.4-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/pip-26.0.1-pyh8b19718_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/pixi-pycharm-0.0.10-unix_hf108a03_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/pkginfo-1.12.1.2-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/platformdirs-4.9.4-pyhcf101f3_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/pluggy-1.6.0-pyhf9edf01_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/pre-commit-4.5.1-pyha770c72_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/pybind11-abi-11-hc364b38_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/pycosat-0.6.6-py311h49ec1c0_3.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/pycparser-2.22-pyh29332c3_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/pyelftools-0.32-pyh707e725_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/pyproject-metadata-0.11.0-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/pysocks-1.7.1-pyha55dd90_7.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/python-3.11.15-hd63d673_0_cpython.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/python-discovery-1.2.1-pyhcf101f3_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/python_abi-3.11-8_cp311.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/pyyaml-6.0.3-py311h3778330_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/readline-8.3-h853b02a_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/reproc-14.2.5.post0-hb9d3cd8_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/reproc-cpp-14.2.5.post0-h5888daf_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/requests-2.32.5-pyhcf101f3_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/rhash-1.4.6-hb9d3cd8_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/ruamel.yaml-0.18.17-py311haee01d2_2.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/ruamel.yaml.clib-0.2.15-py311haee01d2_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/scikit-build-core-0.11.6-pyh7e86bf3_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/setuptools-82.0.1-pyh332efcf_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/setuptools-scm-9.2.2-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/setuptools_scm-9.2.2-hd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/simdjson-4.2.4-hb700be7_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/spdlog-1.17.0-hab81395_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/sysroot_linux-64-2.28-h4ee821c_9.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/taplo-0.10.0-h2d22210_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/tk-8.6.13-noxft_h366c992_103.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/tomli-2.4.0-pyhcf101f3_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/tqdm-4.67.3-pyh8f84b5b_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/truststore-0.10.4-pyhcf101f3_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/typing-extensions-4.15.0-h396c80c_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/typing_extensions-4.15.0-pyhcf101f3_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/tzdata-2025c-hc9c84f9_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/ukkonen-1.1.0-py311hdf67eae_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/urllib3-2.6.3-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/virtualenv-21.2.0-pyhcf101f3_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/wheel-0.46.3-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/yaml-0.2.5-h280c20c_3.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/yaml-cpp-0.8.0-h3f2d84a_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/zipp-3.23.0-pyhcf101f3_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/zstandard-0.25.0-py311haee01d2_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/zstd-1.5.7-hb78ec9c_6.conda
+ - pypi: https://files.pythonhosted.org/packages/c5/0d/84a4380f930db0010168e0aa7b7a8fed9ba1835a8fbb1472bc6d0201d529/build-1.4.0-py3-none-any.whl
+ - pypi: https://files.pythonhosted.org/packages/bd/24/12818598c362d7f300f18e74db45963dbcb85150324092410c8b49405e42/pyproject_hooks-1.2.0-py3-none-any.whl
+ linux-aarch64:
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/_openmp_mutex-4.5-20_gnu.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/archspec-0.2.5-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/auditwheel-6.6.0-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/backports.zstd-1.3.0-py311h6ce31b0_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/binutils-2.45.1-default_hf1166c9_101.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/binutils_impl_linux-aarch64-2.45.1-default_h5f4c503_101.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/binutils_linux-aarch64-2.45.1-default_hf1166c9_101.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/boltons-25.0.0-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/brotli-python-1.2.0-py311h14a79a7_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/bzip2-1.0.8-h4777abc_9.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/c-ares-1.34.6-he30d5cf_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/c-compiler-1.11.0-hdceaead_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2026.2.25-hbd8a1cb_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/certifi-2026.2.25-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/cffi-2.0.0-py311h460c349_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/cfgv-3.5.0-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/charset-normalizer-3.4.6-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/cmake-3.31.8-hc9d863e_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/conda-26.1.1-py311hec3470c_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/conda-gcc-specs-14.3.0-hadff5d6_18.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/conda-libmamba-solver-25.11.0-pyhd8ed1ab_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/conda-package-handling-2.4.0-pyh7900ff3_2.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/conda-package-streaming-0.12.0-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/cpp-expected-1.3.1-hdc560ac_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/cxx-compiler-1.11.0-h7b35c40_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/distlib-0.4.0-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/distro-1.9.0-pyhd8ed1ab_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/doxygen-1.13.2-h5e0f5ae_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/exceptiongroup-1.3.1-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/filelock-3.25.2-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/fmt-12.1.0-h20c602a_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/frozendict-2.4.7-py311h19352d5_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/gcc-14.3.0-h2e72a27_18.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/gcc_impl_linux-aarch64-14.3.0-h533bfc8_18.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/gcc_linux-aarch64-14.3.0-h118592a_21.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/gxx-14.3.0-ha384071_18.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/gxx_impl_linux-aarch64-14.3.0-h0d4f5d4_18.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/gxx_linux-aarch64-14.3.0-h32e4f2e_21.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/h2-4.3.0-pyhcf101f3_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/hpack-4.1.0-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/hyperframe-6.1.0-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/icu-78.3-hcab7f73_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/identify-2.6.18-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/idna-3.11-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/importlib-metadata-8.7.0-pyhe01879c_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/importlib-resources-6.5.2-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/importlib_resources-6.5.2-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/jsonpatch-1.33-pyhd8ed1ab_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/jsonpointer-3.0.0-pyhcf101f3_3.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/kernel-headers_linux-aarch64-4.18.0-h05a177a_9.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/keyutils-1.6.3-h86ecc28_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/krb5-1.22.2-hfd895c2_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/ld_impl_linux-aarch64-2.45.1-default_h1979696_101.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libarchive-3.8.6-gpl_hbe7d12b_100.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libblas-3.11.0-5_haddc8a3_openblas.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libcblas-3.11.0-5_hd72aa62_openblas.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libcurl-8.19.0-hc57f145_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libedit-3.1.20250104-pl5321h976ea20_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libev-4.33-h31becfc_2.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libexpat-2.7.4-hfae3067_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libffi-3.5.2-h376a255_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libgcc-15.2.0-h8acb6b2_18.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/libgcc-devel_linux-aarch64-14.3.0-h25ba3ff_118.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libgcc-ng-15.2.0-he9431aa_18.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libgfortran-15.2.0-he9431aa_18.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libgfortran5-15.2.0-h1b7bec0_18.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libgomp-15.2.0-h8acb6b2_18.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libhwloc-2.13.0-default_ha95e27d_1000.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libiconv-1.18-h90929bb_2.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/liblapack-3.11.0-5_h88aeb00_openblas.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/liblzma-5.8.2-he30d5cf_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libmamba-2.5.0-hc712cdd_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libmamba-spdlog-2.5.0-h3ad78e7_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libmambapy-2.5.0-py311h6a8bf82_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libnghttp2-1.68.1-hd3077d7_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libnsl-2.0.1-h86ecc28_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libopenblas-0.3.30-pthreads_h9d3fd7e_4.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libsanitizer-14.3.0-hedb4206_18.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libsolv-0.7.36-hdda61c4_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libsqlite-3.52.0-h10b116e_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libssh2-1.11.1-h18c354c_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libstdcxx-15.2.0-hef695bb_18.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/libstdcxx-devel_linux-aarch64-14.3.0-h57c8d61_118.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libstdcxx-ng-15.2.0-hdbbeba8_18.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libuuid-2.41.3-h1022ec0_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libuv-1.51.0-he30d5cf_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libxcrypt-4.4.36-h31becfc_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libxml2-16-2.15.2-h79dcc73_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libxml2-2.15.2-h825857f_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libzlib-1.3.1-h86ecc28_2.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/lz4-c-1.10.0-h5ad3122_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/lzo-2.10-h80f16a2_1002.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/menuinst-2.4.2-py311hec3470c_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/msgpack-python-1.1.2-py311hfca10b7_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/ncurses-6.5-ha32ae93_3.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/ninja-1.13.2-hdc560ac_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/nlohmann_json-abi-3.12.0-h0f90c79_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/nodeenv-1.10.0-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/numpy-2.4.3-py311h669026d_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/openssl-3.6.1-h546c87b_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/packaging-25.0-pyh29332c3_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/patchelf-0.17.2-h884eca8_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/pathspec-1.0.4-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/pip-26.0.1-pyh8b19718_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/pixi-pycharm-0.0.10-unix_hf108a03_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/pkginfo-1.12.1.2-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/platformdirs-4.9.4-pyhcf101f3_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/pluggy-1.6.0-pyhf9edf01_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/pre-commit-4.5.1-pyha770c72_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/pybind11-abi-11-hc364b38_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/pycosat-0.6.6-py311h19352d5_3.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/pycparser-2.22-pyh29332c3_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/pyelftools-0.32-pyh707e725_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/pyproject-metadata-0.11.0-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/pysocks-1.7.1-pyha55dd90_7.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/python-3.11.15-h91f4b29_0_cpython.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/python-discovery-1.2.1-pyhcf101f3_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/python_abi-3.11-8_cp311.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/pyyaml-6.0.3-py311h164a683_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/readline-8.3-hb682ff5_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/reproc-14.2.5.post0-h86ecc28_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/reproc-cpp-14.2.5.post0-h5ad3122_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/requests-2.32.5-pyhcf101f3_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/rhash-1.4.6-h86ecc28_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/ruamel.yaml-0.18.17-py311h51cfe5d_2.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/ruamel.yaml.clib-0.2.15-py311h51cfe5d_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/scikit-build-core-0.11.6-pyh7e86bf3_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/setuptools-82.0.1-pyh332efcf_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/setuptools-scm-9.2.2-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/setuptools_scm-9.2.2-hd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/simdjson-4.2.4-hfefdfc9_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/spdlog-1.17.0-h9f97df7_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/sysroot_linux-aarch64-2.28-h585391f_9.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/taplo-0.10.0-h3618846_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/tk-8.6.13-noxft_h0dc03b3_103.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/tomli-2.4.0-pyhcf101f3_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/tqdm-4.67.3-pyh8f84b5b_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/truststore-0.10.4-pyhcf101f3_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/typing-extensions-4.15.0-h396c80c_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/typing_extensions-4.15.0-pyhcf101f3_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/tzdata-2025c-hc9c84f9_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/ukkonen-1.1.0-py311hfca10b7_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/urllib3-2.6.3-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/virtualenv-21.2.0-pyhcf101f3_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/wheel-0.46.3-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/yaml-0.2.5-h80f16a2_3.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/yaml-cpp-0.8.0-h5ad3122_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/zipp-3.23.0-pyhcf101f3_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/zstandard-0.25.0-py311h51cfe5d_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/zstd-1.5.7-h85ac4a6_6.conda
+ - pypi: https://files.pythonhosted.org/packages/c5/0d/84a4380f930db0010168e0aa7b7a8fed9ba1835a8fbb1472bc6d0201d529/build-1.4.0-py3-none-any.whl
+ - pypi: https://files.pythonhosted.org/packages/bd/24/12818598c362d7f300f18e74db45963dbcb85150324092410c8b49405e42/pyproject_hooks-1.2.0-py3-none-any.whl
+ macosx-py310:
+ channels:
+ - url: https://conda.anaconda.org/conda-forge/
+ indexes:
+ - https://pypi.org/simple
+ options:
+ pypi-prerelease-mode: if-necessary-or-explicit
+ packages:
+ osx-64:
+ - conda: https://conda.anaconda.org/conda-forge/osx-64/_openmp_mutex-4.5-7_kmp_llvm.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/archspec-0.2.5-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/boltons-25.0.0-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-64/brotli-python-1.1.0-py310h9e9d8ca_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-64/bzip2-1.0.8-h10d778d_5.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-64/c-ares-1.28.1-h10d778d_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-64/c-compiler-1.10.0-h09a7c41_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2026.2.25-hbd8a1cb_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-64/cctools-986-hd3558d4_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-64/cctools_osx-64-986-h58a35ae_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/certifi-2026.2.25-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-64/cffi-1.16.0-py310hdca579f_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/cfgv-3.5.0-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/charset-normalizer-3.4.5-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-64/clang-18-18.1.3-default_h7151d67_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-64/clang-18.1.3-default_h7151d67_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-64/clang_impl_osx-64-18.1.3-hdbcc6ac_11.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-64/clang_osx-64-18.1.3-hb91bd55_11.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-64/clangxx-18.1.3-default_h7151d67_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-64/clangxx_impl_osx-64-18.1.3-h5bc21ce_11.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-64/clangxx_osx-64-18.1.3-hb91bd55_11.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-64/cmake-3.27.6-hf40c264_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-64/compiler-rt-18.1.3-ha38d28d_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/compiler-rt_osx-64-18.1.3-ha38d28d_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-64/conda-23.9.0-py310h2ec42d9_2.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/conda-package-handling-2.4.0-pyh7900ff3_2.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/conda-package-streaming-0.12.0-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-64/cryptography-41.0.7-py310h527a09d_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-64/cxx-compiler-1.10.0-h20888b2_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/distlib-0.4.0-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-64/doxygen-1.10.0-h5ff76d1_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/exceptiongroup-1.3.1-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/filelock-3.25.2-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/h2-4.3.0-pyhcf101f3_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/hpack-4.1.0-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/hyperframe-6.1.0-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-64/icu-73.2-hf5e326d_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/identify-2.6.18-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/idna-3.11-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/importlib-metadata-8.7.0-pyhe01879c_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/importlib-resources-6.5.2-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/importlib_resources-6.5.2-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/jsonpatch-1.33-pyhd8ed1ab_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/jsonpointer-3.0.0-pyhcf101f3_3.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-64/krb5-1.21.2-hb884880_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-64/ld64-711-h4e51db5_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-64/ld64_osx-64-711-had5d0d3_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-64/libblas-3.9.0-22_osx64_openblas.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-64/libcblas-3.9.0-22_osx64_openblas.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-64/libclang-cpp18.1-18.1.3-default_h7151d67_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-64/libcurl-8.4.0-h726d00d_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-64/libcxx-16.0.6-hd57cbcb_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-64/libedit-3.1.20191231-h0678c8f_2.tar.bz2
+ - conda: https://conda.anaconda.org/conda-forge/osx-64/libev-4.33-h10d778d_2.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-64/libexpat-2.6.2-h73e2aa4_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-64/libffi-3.4.2-h0d85af4_5.tar.bz2
+ - conda: https://conda.anaconda.org/conda-forge/osx-64/libgcc-15.2.0-h08519bb_18.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-64/libgfortran-15.2.0-h7e5c614_18.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-64/libgfortran5-15.2.0-hd16e46c_18.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-64/libiconv-1.17-hd75f5a5_2.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-64/liblapack-3.9.0-22_osx64_openblas.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-64/libllvm18-18.1.3-hbcf5fad_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-64/libnghttp2-1.52.0-he2ab024_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-64/libopenblas-0.3.27-openmp_hfef2a42_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-64/libsqlite-3.45.3-h92b6c6a_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-64/libssh2-1.11.0-hd019ec5_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-64/libuv-1.48.0-h67532ce_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-64/libxml2-2.12.6-hc0ae0f7_2.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-64/libzlib-1.3.1-hd75f5a5_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-64/llvm-openmp-18.1.3-hb6ac08f_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-64/llvm-tools-18.1.3-hbcf5fad_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-64/ncurses-6.5-h5846eda_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-64/ninja-1.12.0-h7728843_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/nodeenv-1.10.0-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-64/numpy-1.26.4-py310h4bfa8fc_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-64/openssl-3.3.0-hd75f5a5_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/packaging-25.0-pyh29332c3_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/pathspec-1.0.4-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/pip-26.0.1-pyh8b19718_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/pixi-pycharm-0.0.10-unix_hf108a03_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/pkginfo-1.12.1.2-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/platformdirs-4.9.4-pyhcf101f3_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/pluggy-1.6.0-pyhf9edf01_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/pre-commit-4.5.1-pyha770c72_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-64/pycosat-0.6.6-py310h6729b98_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/pycparser-2.22-pyh29332c3_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/pyopenssl-25.1.0-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/pyproject-metadata-0.11.0-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/pysocks-1.7.1-pyha55dd90_7.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-64/python-3.10.14-h00d2728_0_cpython.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/python-discovery-1.2.1-pyhcf101f3_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/python_abi-3.10-8_cp310.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-64/pyyaml-6.0.1-py310h6729b98_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-64/readline-8.2-h7cca4af_2.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/requests-2.32.5-pyhcf101f3_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-64/rhash-1.4.4-h0dc2134_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-64/ruamel.yaml-0.17.40-py310hb372a2b_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-64/ruamel.yaml.clib-0.2.8-py310hb372a2b_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/scikit-build-core-0.11.6-pyh7e86bf3_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/setuptools-82.0.1-pyh332efcf_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/setuptools-scm-9.2.2-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/setuptools_scm-9.2.2-hd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-64/sigtool-0.1.3-h88f4db0_0.tar.bz2
+ - conda: https://conda.anaconda.org/conda-forge/osx-64/tapi-1100.0.11-h9ce4665_0.tar.bz2
+ - conda: https://conda.anaconda.org/conda-forge/osx-64/taplo-0.8.1-h7205ca4_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-64/tk-8.6.13-h1abcd95_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/tomli-2.4.0-pyhcf101f3_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/tqdm-4.67.3-pyh8f84b5b_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/truststore-0.10.4-pyhcf101f3_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/typing-extensions-4.15.0-h396c80c_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/typing_extensions-4.15.0-pyhcf101f3_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/tzdata-2025c-hc9c84f9_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-64/ukkonen-1.0.1-py310h88cfcbd_4.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/urllib3-2.5.0-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/virtualenv-21.2.0-pyhcf101f3_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/wheel-0.46.3-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-64/xz-5.2.6-h775f41a_0.tar.bz2
+ - conda: https://conda.anaconda.org/conda-forge/osx-64/yaml-0.2.5-h0d85af4_2.tar.bz2
+ - conda: https://conda.anaconda.org/conda-forge/noarch/zipp-3.23.0-pyhcf101f3_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-64/zstandard-0.22.0-py310hd88f66e_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-64/zstd-1.5.5-h829000d_0.conda
+ - pypi: https://files.pythonhosted.org/packages/a9/ba/000a1996d4308bc65120167c21241a3b205464a2e0b58deda26ae8ac21d1/altgraph-0.17.5-py2.py3-none-any.whl
+ - pypi: https://files.pythonhosted.org/packages/c5/0d/84a4380f930db0010168e0aa7b7a8fed9ba1835a8fbb1472bc6d0201d529/build-1.4.0-py3-none-any.whl
+ - pypi: https://files.pythonhosted.org/packages/2b/dd/437e601fa9d2b6bf8507256daf52196a226c3b340261f4cde8fac8e853ea/delocate-0.13.0-py3-none-any.whl
+ - pypi: https://files.pythonhosted.org/packages/c7/d1/a9f36f8ecdf0fb7c9b1e78c8d7af12b8c8754e74851ac7b94a8305540fc7/macholib-1.16.4-py2.py3-none-any.whl
+ - pypi: https://files.pythonhosted.org/packages/bd/24/12818598c362d7f300f18e74db45963dbcb85150324092410c8b49405e42/pyproject_hooks-1.2.0-py3-none-any.whl
+ osx-arm64:
+ - conda: https://conda.anaconda.org/conda-forge/osx-arm64/_openmp_mutex-4.5-7_kmp_llvm.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/archspec-0.2.5-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/boltons-25.0.0-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-arm64/brotli-python-1.1.0-py310h1253130_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-arm64/bzip2-1.0.8-h93a5062_5.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-arm64/c-ares-1.28.1-h93a5062_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-arm64/c-compiler-1.10.0-hdf49b6b_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2026.2.25-hbd8a1cb_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-arm64/cctools-986-h4c9edd9_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-arm64/cctools_osx-arm64-986-hd11630f_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/certifi-2026.2.25-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-arm64/cffi-1.16.0-py310hdcd7c05_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/cfgv-3.5.0-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/charset-normalizer-3.4.5-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-arm64/clang-18-18.1.3-default_he012953_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-arm64/clang-18.1.3-default_h4cf2255_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-arm64/clang_impl_osx-arm64-18.1.3-hda94301_11.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-arm64/clang_osx-arm64-18.1.3-h54d7cd3_11.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-arm64/clangxx-18.1.3-default_h4cf2255_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-arm64/clangxx_impl_osx-arm64-18.1.3-h1ba0cb9_11.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-arm64/clangxx_osx-arm64-18.1.3-h54d7cd3_11.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-arm64/cmake-3.27.6-h1c59155_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-arm64/compiler-rt-18.1.3-h3808999_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/compiler-rt_osx-arm64-18.1.3-h3808999_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-arm64/conda-23.9.0-py310hbe9552e_2.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/conda-package-handling-2.4.0-pyh7900ff3_2.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/conda-package-streaming-0.12.0-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-arm64/cryptography-41.0.7-py310h4c55245_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-arm64/cxx-compiler-1.10.0-hba80287_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/distlib-0.4.0-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-arm64/doxygen-1.10.0-h8fbad5d_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/exceptiongroup-1.3.1-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/filelock-3.25.2-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/h2-4.3.0-pyhcf101f3_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/hpack-4.1.0-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/hyperframe-6.1.0-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-arm64/icu-73.2-hc8870d7_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/identify-2.6.18-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/idna-3.11-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/importlib-metadata-8.7.0-pyhe01879c_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/importlib-resources-6.5.2-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/importlib_resources-6.5.2-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/jsonpatch-1.33-pyhd8ed1ab_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/jsonpointer-3.0.0-pyhcf101f3_3.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-arm64/krb5-1.21.2-h92f50d5_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-arm64/ld64-711-h4c6efb1_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-arm64/ld64_osx-arm64-711-h5e7191b_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libblas-3.9.0-24_osxarm64_openblas.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libcblas-3.9.0-24_osxarm64_openblas.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libclang-cpp18.1-18.1.3-default_he012953_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libcurl-8.4.0-h2d989ff_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libcxx-16.0.6-h4653b0c_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libedit-3.1.20191231-hc8eb9b7_2.tar.bz2
+ - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libev-4.33-h93a5062_2.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libexpat-2.6.2-hebf3989_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libffi-3.4.2-h3422bc3_5.tar.bz2
+ - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libgcc-15.2.0-hcbb3090_18.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libgfortran-15.2.0-h07b0088_18.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libgfortran5-15.2.0-hdae7583_18.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libiconv-1.17-h0d3ecfb_2.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-arm64/liblapack-3.9.0-24_osxarm64_openblas.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libllvm18-18.1.3-h30cc82d_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libnghttp2-1.52.0-hae82a92_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libopenblas-0.3.27-openmp_h6c19121_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libsqlite-3.45.3-h091b4b1_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libssh2-1.11.0-h7a5bd25_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libuv-1.48.0-h93a5062_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libxml2-2.12.6-h35eab27_2.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libzlib-1.3.1-h0d3ecfb_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-arm64/llvm-openmp-18.1.3-hcd81f8e_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-arm64/llvm-tools-18.1.3-h30cc82d_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-arm64/ncurses-6.5-hb89a1cb_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-arm64/ninja-1.12.0-h2ffa867_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/nodeenv-1.10.0-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-arm64/numpy-1.26.4-py310hd45542a_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-arm64/openssl-3.3.0-h0d3ecfb_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/packaging-25.0-pyh29332c3_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/pathspec-1.0.4-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/pip-26.0.1-pyh8b19718_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/pixi-pycharm-0.0.10-unix_hf108a03_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/pkginfo-1.12.1.2-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/platformdirs-4.9.4-pyhcf101f3_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/pluggy-1.6.0-pyhf9edf01_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/pre-commit-4.5.1-pyha770c72_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-arm64/pycosat-0.6.6-py310h2aa6e3c_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/pycparser-2.22-pyh29332c3_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/pyopenssl-25.1.0-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/pyproject-metadata-0.11.0-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/pysocks-1.7.1-pyha55dd90_7.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-arm64/python-3.10.14-h2469fbe_0_cpython.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/python-discovery-1.2.1-pyhcf101f3_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/python_abi-3.10-8_cp310.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-arm64/pyyaml-6.0.1-py310h2aa6e3c_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-arm64/readline-8.2-h1d1bf99_2.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/requests-2.32.5-pyhcf101f3_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-arm64/rhash-1.4.4-hb547adb_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-arm64/ruamel.yaml-0.17.40-py310hd125d64_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-arm64/ruamel.yaml.clib-0.2.8-py310hd125d64_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/scikit-build-core-0.11.6-pyh7e86bf3_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/setuptools-82.0.1-pyh332efcf_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/setuptools-scm-9.2.2-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/setuptools_scm-9.2.2-hd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-arm64/sigtool-0.1.3-h44b9a77_0.tar.bz2
+ - conda: https://conda.anaconda.org/conda-forge/osx-arm64/tapi-1100.0.11-he4954df_0.tar.bz2
+ - conda: https://conda.anaconda.org/conda-forge/osx-arm64/taplo-0.8.1-h69fbcac_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-arm64/tk-8.6.13-h5083fa2_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/tomli-2.4.0-pyhcf101f3_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/tqdm-4.67.3-pyh8f84b5b_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/truststore-0.10.4-pyhcf101f3_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/typing-extensions-4.15.0-h396c80c_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/typing_extensions-4.15.0-pyhcf101f3_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/tzdata-2025c-hc9c84f9_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-arm64/ukkonen-1.0.1-py310h38f39d4_4.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/urllib3-2.5.0-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/virtualenv-21.2.0-pyhcf101f3_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/wheel-0.46.3-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-arm64/xz-5.2.6-h57fd34a_0.tar.bz2
+ - conda: https://conda.anaconda.org/conda-forge/osx-arm64/yaml-0.2.5-h3422bc3_2.tar.bz2
+ - conda: https://conda.anaconda.org/conda-forge/noarch/zipp-3.23.0-pyhcf101f3_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-arm64/zstandard-0.22.0-py310h6289e41_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-arm64/zstd-1.5.5-h4f39d0f_0.conda
+ - pypi: https://files.pythonhosted.org/packages/a9/ba/000a1996d4308bc65120167c21241a3b205464a2e0b58deda26ae8ac21d1/altgraph-0.17.5-py2.py3-none-any.whl
+ - pypi: https://files.pythonhosted.org/packages/c5/0d/84a4380f930db0010168e0aa7b7a8fed9ba1835a8fbb1472bc6d0201d529/build-1.4.0-py3-none-any.whl
+ - pypi: https://files.pythonhosted.org/packages/2b/dd/437e601fa9d2b6bf8507256daf52196a226c3b340261f4cde8fac8e853ea/delocate-0.13.0-py3-none-any.whl
+ - pypi: https://files.pythonhosted.org/packages/c7/d1/a9f36f8ecdf0fb7c9b1e78c8d7af12b8c8754e74851ac7b94a8305540fc7/macholib-1.16.4-py2.py3-none-any.whl
+ - pypi: https://files.pythonhosted.org/packages/bd/24/12818598c362d7f300f18e74db45963dbcb85150324092410c8b49405e42/pyproject_hooks-1.2.0-py3-none-any.whl
+ macosx-py311:
+ channels:
+ - url: https://conda.anaconda.org/conda-forge/
+ indexes:
+ - https://pypi.org/simple
+ options:
+ pypi-prerelease-mode: if-necessary-or-explicit
+ packages:
+ osx-64:
+ - conda: https://conda.anaconda.org/conda-forge/osx-64/_openmp_mutex-4.5-7_kmp_llvm.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/archspec-0.2.5-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/boltons-25.0.0-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-64/brotli-python-1.1.0-py311hdf8f085_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-64/bzip2-1.0.8-h10d778d_5.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-64/c-ares-1.28.1-h10d778d_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-64/c-compiler-1.10.0-h09a7c41_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2026.2.25-hbd8a1cb_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-64/cctools-986-hd3558d4_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-64/cctools_osx-64-986-h58a35ae_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/certifi-2026.2.25-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-64/cffi-1.16.0-py311hc0b63fd_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/cfgv-3.5.0-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/charset-normalizer-3.4.5-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-64/clang-18-18.1.3-default_h7151d67_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-64/clang-18.1.3-default_h7151d67_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-64/clang_impl_osx-64-18.1.3-hdbcc6ac_11.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-64/clang_osx-64-18.1.3-hb91bd55_11.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-64/clangxx-18.1.3-default_h7151d67_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-64/clangxx_impl_osx-64-18.1.3-h5bc21ce_11.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-64/clangxx_osx-64-18.1.3-hb91bd55_11.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-64/cmake-3.27.6-hf40c264_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-64/compiler-rt-18.1.3-ha38d28d_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/compiler-rt_osx-64-18.1.3-ha38d28d_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-64/conda-23.9.0-py311h6eed73b_2.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/conda-package-handling-2.4.0-pyh7900ff3_2.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/conda-package-streaming-0.12.0-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-64/cryptography-41.0.7-py311h48c7838_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-64/cxx-compiler-1.10.0-h20888b2_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/distlib-0.4.0-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-64/doxygen-1.10.0-h5ff76d1_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/exceptiongroup-1.3.1-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/filelock-3.25.2-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/h2-4.3.0-pyhcf101f3_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/hpack-4.1.0-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/hyperframe-6.1.0-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-64/icu-73.2-hf5e326d_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/identify-2.6.18-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/idna-3.11-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/importlib-metadata-8.7.0-pyhe01879c_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/importlib-resources-6.5.2-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/importlib_resources-6.5.2-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/jsonpatch-1.33-pyhd8ed1ab_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/jsonpointer-3.0.0-pyhcf101f3_3.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-64/krb5-1.21.2-hb884880_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-64/ld64-711-h4e51db5_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-64/ld64_osx-64-711-had5d0d3_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-64/libblas-3.9.0-22_osx64_openblas.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-64/libcblas-3.9.0-22_osx64_openblas.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-64/libclang-cpp18.1-18.1.3-default_h7151d67_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-64/libcurl-8.4.0-h726d00d_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-64/libcxx-16.0.6-hd57cbcb_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-64/libedit-3.1.20191231-h0678c8f_2.tar.bz2
+ - conda: https://conda.anaconda.org/conda-forge/osx-64/libev-4.33-h10d778d_2.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-64/libexpat-2.6.2-h73e2aa4_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-64/libffi-3.4.2-h0d85af4_5.tar.bz2
+ - conda: https://conda.anaconda.org/conda-forge/osx-64/libgcc-15.2.0-h08519bb_18.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-64/libgfortran-15.2.0-h7e5c614_18.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-64/libgfortran5-15.2.0-hd16e46c_18.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-64/libiconv-1.17-hd75f5a5_2.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-64/liblapack-3.9.0-22_osx64_openblas.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-64/libllvm18-18.1.3-hbcf5fad_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-64/libnghttp2-1.52.0-he2ab024_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-64/libopenblas-0.3.27-openmp_hfef2a42_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-64/libsqlite-3.45.3-h92b6c6a_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-64/libssh2-1.11.0-hd019ec5_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-64/libuv-1.48.0-h67532ce_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-64/libxml2-2.12.6-hc0ae0f7_2.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-64/libzlib-1.3.1-hd75f5a5_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-64/llvm-openmp-18.1.3-hb6ac08f_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-64/llvm-tools-18.1.3-hbcf5fad_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-64/ncurses-6.5-h5846eda_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-64/ninja-1.12.0-h7728843_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/nodeenv-1.10.0-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-64/numpy-1.26.4-py311hc43a94b_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-64/openssl-3.3.0-hd75f5a5_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/packaging-25.0-pyh29332c3_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/pathspec-1.0.4-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/pip-26.0.1-pyh8b19718_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/pixi-pycharm-0.0.10-unix_hf108a03_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/pkginfo-1.12.1.2-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/platformdirs-4.9.4-pyhcf101f3_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/pluggy-1.6.0-pyhf9edf01_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/pre-commit-4.5.1-pyha770c72_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-64/pycosat-0.6.6-py311h2725bcf_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/pycparser-2.22-pyh29332c3_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/pyopenssl-25.1.0-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/pyproject-metadata-0.11.0-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/pysocks-1.7.1-pyha55dd90_7.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-64/python-3.11.8-h9f0c242_0_cpython.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/python-discovery-1.2.1-pyhcf101f3_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/python_abi-3.11-8_cp311.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-64/pyyaml-6.0.1-py311h2725bcf_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-64/readline-8.2-h7cca4af_2.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/requests-2.32.5-pyhcf101f3_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-64/rhash-1.4.4-h0dc2134_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-64/ruamel.yaml-0.17.40-py311he705e18_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-64/ruamel.yaml.clib-0.2.8-py311he705e18_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/scikit-build-core-0.11.6-pyh7e86bf3_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/setuptools-82.0.1-pyh332efcf_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/setuptools-scm-9.2.2-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/setuptools_scm-9.2.2-hd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-64/sigtool-0.1.3-h88f4db0_0.tar.bz2
+ - conda: https://conda.anaconda.org/conda-forge/osx-64/tapi-1100.0.11-h9ce4665_0.tar.bz2
+ - conda: https://conda.anaconda.org/conda-forge/osx-64/taplo-0.8.1-h7205ca4_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-64/tk-8.6.13-h1abcd95_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/tomli-2.4.0-pyhcf101f3_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/tqdm-4.67.3-pyh8f84b5b_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/truststore-0.10.4-pyhcf101f3_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/typing-extensions-4.15.0-h396c80c_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/typing_extensions-4.15.0-pyhcf101f3_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/tzdata-2025c-hc9c84f9_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-64/ukkonen-1.0.1-py311h5fe6e05_4.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/urllib3-2.5.0-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/virtualenv-21.2.0-pyhcf101f3_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/wheel-0.46.3-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-64/xz-5.2.6-h775f41a_0.tar.bz2
+ - conda: https://conda.anaconda.org/conda-forge/osx-64/yaml-0.2.5-h0d85af4_2.tar.bz2
+ - conda: https://conda.anaconda.org/conda-forge/noarch/zipp-3.23.0-pyhcf101f3_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-64/zstandard-0.22.0-py311hed14148_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-64/zstd-1.5.5-h829000d_0.conda
+ - pypi: https://files.pythonhosted.org/packages/a9/ba/000a1996d4308bc65120167c21241a3b205464a2e0b58deda26ae8ac21d1/altgraph-0.17.5-py2.py3-none-any.whl
+ - pypi: https://files.pythonhosted.org/packages/c5/0d/84a4380f930db0010168e0aa7b7a8fed9ba1835a8fbb1472bc6d0201d529/build-1.4.0-py3-none-any.whl
+ - pypi: https://files.pythonhosted.org/packages/2b/dd/437e601fa9d2b6bf8507256daf52196a226c3b340261f4cde8fac8e853ea/delocate-0.13.0-py3-none-any.whl
+ - pypi: https://files.pythonhosted.org/packages/c7/d1/a9f36f8ecdf0fb7c9b1e78c8d7af12b8c8754e74851ac7b94a8305540fc7/macholib-1.16.4-py2.py3-none-any.whl
+ - pypi: https://files.pythonhosted.org/packages/bd/24/12818598c362d7f300f18e74db45963dbcb85150324092410c8b49405e42/pyproject_hooks-1.2.0-py3-none-any.whl
+ osx-arm64:
+ - conda: https://conda.anaconda.org/conda-forge/osx-arm64/_openmp_mutex-4.5-7_kmp_llvm.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/archspec-0.2.5-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/boltons-25.0.0-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-arm64/brotli-python-1.1.0-py311ha891d26_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-arm64/bzip2-1.0.8-h93a5062_5.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-arm64/c-ares-1.28.1-h93a5062_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-arm64/c-compiler-1.10.0-hdf49b6b_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2026.2.25-hbd8a1cb_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-arm64/cctools-986-h4c9edd9_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-arm64/cctools_osx-arm64-986-hd11630f_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/certifi-2026.2.25-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-arm64/cffi-1.16.0-py311h4a08483_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/cfgv-3.5.0-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/charset-normalizer-3.4.5-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-arm64/clang-18-18.1.3-default_he012953_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-arm64/clang-18.1.3-default_h4cf2255_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-arm64/clang_impl_osx-arm64-18.1.3-hda94301_11.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-arm64/clang_osx-arm64-18.1.3-h54d7cd3_11.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-arm64/clangxx-18.1.3-default_h4cf2255_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-arm64/clangxx_impl_osx-arm64-18.1.3-h1ba0cb9_11.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-arm64/clangxx_osx-arm64-18.1.3-h54d7cd3_11.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-arm64/cmake-3.27.6-h1c59155_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-arm64/compiler-rt-18.1.3-h3808999_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/compiler-rt_osx-arm64-18.1.3-h3808999_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-arm64/conda-23.9.0-py311h267d04e_2.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/conda-package-handling-2.4.0-pyh7900ff3_2.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/conda-package-streaming-0.12.0-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-arm64/cryptography-41.0.7-py311h08c85a6_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-arm64/cxx-compiler-1.10.0-hba80287_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/distlib-0.4.0-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-arm64/doxygen-1.10.0-h8fbad5d_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/exceptiongroup-1.3.1-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/filelock-3.25.2-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/h2-4.3.0-pyhcf101f3_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/hpack-4.1.0-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/hyperframe-6.1.0-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-arm64/icu-73.2-hc8870d7_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/identify-2.6.18-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/idna-3.11-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/importlib-metadata-8.7.0-pyhe01879c_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/importlib-resources-6.5.2-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/importlib_resources-6.5.2-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/jsonpatch-1.33-pyhd8ed1ab_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/jsonpointer-3.0.0-pyhcf101f3_3.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-arm64/krb5-1.21.2-h92f50d5_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-arm64/ld64-711-h4c6efb1_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-arm64/ld64_osx-arm64-711-h5e7191b_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libblas-3.9.0-24_osxarm64_openblas.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libcblas-3.9.0-24_osxarm64_openblas.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libclang-cpp18.1-18.1.3-default_he012953_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libcurl-8.4.0-h2d989ff_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libcxx-16.0.6-h4653b0c_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libedit-3.1.20191231-hc8eb9b7_2.tar.bz2
+ - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libev-4.33-h93a5062_2.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libexpat-2.6.2-hebf3989_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libffi-3.4.2-h3422bc3_5.tar.bz2
+ - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libgcc-15.2.0-hcbb3090_18.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libgfortran-15.2.0-h07b0088_18.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libgfortran5-15.2.0-hdae7583_18.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libiconv-1.17-h0d3ecfb_2.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-arm64/liblapack-3.9.0-24_osxarm64_openblas.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libllvm18-18.1.3-h30cc82d_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libnghttp2-1.52.0-hae82a92_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libopenblas-0.3.27-openmp_h6c19121_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libsqlite-3.45.3-h091b4b1_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libssh2-1.11.0-h7a5bd25_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libuv-1.48.0-h93a5062_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libxml2-2.12.6-h35eab27_2.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libzlib-1.3.1-h0d3ecfb_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-arm64/llvm-openmp-18.1.3-hcd81f8e_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-arm64/llvm-tools-18.1.3-h30cc82d_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-arm64/ncurses-6.5-hb89a1cb_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-arm64/ninja-1.12.0-h2ffa867_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/nodeenv-1.10.0-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-arm64/numpy-1.26.4-py311h7125741_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-arm64/openssl-3.3.0-h0d3ecfb_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/packaging-25.0-pyh29332c3_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/pathspec-1.0.4-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/pip-26.0.1-pyh8b19718_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/pixi-pycharm-0.0.10-unix_hf108a03_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/pkginfo-1.12.1.2-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/platformdirs-4.9.4-pyhcf101f3_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/pluggy-1.6.0-pyhf9edf01_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/pre-commit-4.5.1-pyha770c72_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-arm64/pycosat-0.6.6-py311heffc1b2_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/pycparser-2.22-pyh29332c3_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/pyopenssl-25.1.0-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/pyproject-metadata-0.11.0-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/pysocks-1.7.1-pyha55dd90_7.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-arm64/python-3.11.8-hdf0ec26_0_cpython.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/python-discovery-1.2.1-pyhcf101f3_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/python_abi-3.11-8_cp311.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-arm64/pyyaml-6.0.1-py311heffc1b2_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-arm64/readline-8.2-h1d1bf99_2.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/requests-2.32.5-pyhcf101f3_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-arm64/rhash-1.4.4-hb547adb_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-arm64/ruamel.yaml-0.17.40-py311h05b510d_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-arm64/ruamel.yaml.clib-0.2.8-py311h05b510d_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/scikit-build-core-0.11.6-pyh7e86bf3_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/setuptools-82.0.1-pyh332efcf_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/setuptools-scm-9.2.2-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/setuptools_scm-9.2.2-hd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-arm64/sigtool-0.1.3-h44b9a77_0.tar.bz2
+ - conda: https://conda.anaconda.org/conda-forge/osx-arm64/tapi-1100.0.11-he4954df_0.tar.bz2
+ - conda: https://conda.anaconda.org/conda-forge/osx-arm64/taplo-0.8.1-h69fbcac_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-arm64/tk-8.6.13-h5083fa2_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/tomli-2.4.0-pyhcf101f3_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/tqdm-4.67.3-pyh8f84b5b_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/truststore-0.10.4-pyhcf101f3_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/typing-extensions-4.15.0-h396c80c_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/typing_extensions-4.15.0-pyhcf101f3_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/tzdata-2025c-hc9c84f9_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-arm64/ukkonen-1.0.1-py311he4fd1f5_4.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/urllib3-2.5.0-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/virtualenv-21.2.0-pyhcf101f3_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/wheel-0.46.3-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-arm64/xz-5.2.6-h57fd34a_0.tar.bz2
+ - conda: https://conda.anaconda.org/conda-forge/osx-arm64/yaml-0.2.5-h3422bc3_2.tar.bz2
+ - conda: https://conda.anaconda.org/conda-forge/noarch/zipp-3.23.0-pyhcf101f3_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-arm64/zstandard-0.22.0-py311h67b91a1_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-arm64/zstd-1.5.5-h4f39d0f_0.conda
+ - pypi: https://files.pythonhosted.org/packages/a9/ba/000a1996d4308bc65120167c21241a3b205464a2e0b58deda26ae8ac21d1/altgraph-0.17.5-py2.py3-none-any.whl
+ - pypi: https://files.pythonhosted.org/packages/c5/0d/84a4380f930db0010168e0aa7b7a8fed9ba1835a8fbb1472bc6d0201d529/build-1.4.0-py3-none-any.whl
+ - pypi: https://files.pythonhosted.org/packages/2b/dd/437e601fa9d2b6bf8507256daf52196a226c3b340261f4cde8fac8e853ea/delocate-0.13.0-py3-none-any.whl
+ - pypi: https://files.pythonhosted.org/packages/c7/d1/a9f36f8ecdf0fb7c9b1e78c8d7af12b8c8754e74851ac7b94a8305540fc7/macholib-1.16.4-py2.py3-none-any.whl
+ - pypi: https://files.pythonhosted.org/packages/bd/24/12818598c362d7f300f18e74db45963dbcb85150324092410c8b49405e42/pyproject_hooks-1.2.0-py3-none-any.whl
+ manylinux228-py310:
+ channels:
+ - url: https://conda.anaconda.org/conda-forge/
+ indexes:
+ - https://pypi.org/simple
+ options:
+ pypi-prerelease-mode: if-necessary-or-explicit
+ packages:
+ linux-64:
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/_openmp_mutex-4.5-20_gnu.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/archspec-0.2.5-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/auditwheel-6.6.0-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/backports.zstd-1.3.0-py310h69bd2ac_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/boltons-25.0.0-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/brotli-python-1.2.0-py310hba01987_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/bzip2-1.0.8-hda65f42_9.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/c-ares-1.34.6-hb03c661_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2026.2.25-hbd8a1cb_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/certifi-2026.2.25-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/cffi-2.0.0-py310he7384ee_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/cfgv-3.5.0-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/charset-normalizer-3.4.5-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/cmake-3.31.8-hc85cc9f_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/conda-26.1.1-py310hff52083_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/conda-libmamba-solver-25.11.0-pyhd8ed1ab_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/conda-package-handling-2.4.0-pyh7900ff3_2.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/conda-package-streaming-0.12.0-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/cpp-expected-1.3.1-h171cf75_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/distlib-0.4.0-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/distro-1.9.0-pyhd8ed1ab_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/doxygen-1.13.2-h8e693c7_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/exceptiongroup-1.3.1-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/filelock-3.25.2-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/fmt-12.1.0-hff5e90c_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/frozendict-2.4.7-py310h7c4b9e2_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/h2-4.3.0-pyhcf101f3_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/hpack-4.1.0-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/hyperframe-6.1.0-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/icu-78.2-h33c6efd_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/identify-2.6.18-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/idna-3.11-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/importlib-metadata-8.7.0-pyhe01879c_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/importlib-resources-6.5.2-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/importlib_resources-6.5.2-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/jsonpatch-1.33-pyhd8ed1ab_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/jsonpointer-3.0.0-pyhcf101f3_3.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/keyutils-1.6.3-hb9d3cd8_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/krb5-1.22.2-ha1258a1_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/ld_impl_linux-64-2.45.1-default_hbd61a6d_101.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/libarchive-3.8.6-gpl_hc2c16d8_100.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/libblas-3.11.0-5_h4a7cf45_openblas.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/libcblas-3.11.0-5_h0358290_openblas.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/libcurl-8.19.0-hcf29cc6_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/libedit-3.1.20250104-pl5321h7949ede_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/libev-4.33-hd590300_2.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/libexpat-2.7.4-hecca717_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/libffi-3.5.2-h3435931_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/libgcc-15.2.0-he0feb66_18.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/libgcc-ng-15.2.0-h69a702a_18.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/libgfortran-15.2.0-h69a702a_18.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/libgfortran5-15.2.0-h68bc16d_18.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/libgomp-15.2.0-he0feb66_18.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/libiconv-1.18-h3b78370_2.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/liblapack-3.11.0-5_h47877c9_openblas.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/liblzma-5.8.2-hb03c661_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/libmamba-2.5.0-hd28c85e_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/libmamba-spdlog-2.5.0-h12fcf84_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/libmambapy-2.5.0-py310h74f1d5f_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/libnghttp2-1.67.0-had1ee68_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/libnsl-2.0.1-hb9d3cd8_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/libopenblas-0.3.30-pthreads_h94d23a6_4.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/libsolv-0.7.35-h9463b59_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/libsqlite-3.52.0-hf4e2dac_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/libssh2-1.11.1-hcf80075_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-15.2.0-h934c35e_18.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-ng-15.2.0-hdf11a46_18.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/libuuid-2.41.3-h5347b49_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/libuv-1.51.0-hb03c661_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/libxcrypt-4.4.36-hd590300_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/libxml2-16-2.15.2-hca6bf5a_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/libxml2-2.15.2-he237659_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/libzlib-1.3.1-hb9d3cd8_2.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/lz4-c-1.10.0-h5888daf_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/lzo-2.10-h280c20c_1002.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/menuinst-2.4.2-py310hff52083_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/msgpack-python-1.1.2-py310h03d9f68_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/ncurses-6.5-h2d0b736_3.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/ninja-1.13.2-h171cf75_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/nlohmann_json-abi-3.12.0-h0f90c79_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/nodeenv-1.10.0-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/numpy-2.2.6-py310hefbff90_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/openssl-3.6.1-h35e630c_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/packaging-25.0-pyh29332c3_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/patchelf-0.17.2-h58526e2_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/pathspec-1.0.4-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/pip-26.0.1-pyh8b19718_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/pixi-pycharm-0.0.10-unix_hf108a03_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/pkginfo-1.12.1.2-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/platformdirs-4.9.4-pyhcf101f3_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/pluggy-1.6.0-pyhf9edf01_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/pre-commit-4.5.1-pyha770c72_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/pybind11-abi-11-hc364b38_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/pycosat-0.6.6-py310h7c4b9e2_3.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/pycparser-2.22-pyh29332c3_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/pyelftools-0.32-pyh707e725_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/pyproject-metadata-0.11.0-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/pysocks-1.7.1-pyha55dd90_7.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/python-3.10.20-h3c07f61_0_cpython.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/python-discovery-1.2.1-pyhcf101f3_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/python_abi-3.10-8_cp310.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/pyyaml-6.0.3-py310h3406613_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/readline-8.3-h853b02a_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/reproc-14.2.5.post0-hb9d3cd8_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/reproc-cpp-14.2.5.post0-h5888daf_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/requests-2.32.5-pyhcf101f3_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/rhash-1.4.6-hb9d3cd8_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/ruamel.yaml-0.18.17-py310h139afa4_2.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/ruamel.yaml.clib-0.2.15-py310h139afa4_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/scikit-build-core-0.11.6-pyh7e86bf3_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/setuptools-82.0.1-pyh332efcf_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/setuptools-scm-9.2.2-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/setuptools_scm-9.2.2-hd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/simdjson-4.2.4-hb700be7_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/spdlog-1.17.0-hab81395_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/taplo-0.10.0-h2d22210_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/tk-8.6.13-noxft_h366c992_103.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/tomli-2.4.0-pyhcf101f3_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/tqdm-4.67.3-pyh8f84b5b_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/truststore-0.10.4-pyhcf101f3_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/typing-extensions-4.15.0-h396c80c_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/typing_extensions-4.15.0-pyhcf101f3_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/tzdata-2025c-hc9c84f9_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/ukkonen-1.1.0-py310h03d9f68_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/urllib3-2.6.3-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/virtualenv-21.2.0-pyhcf101f3_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/wheel-0.46.3-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/yaml-0.2.5-h280c20c_3.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/yaml-cpp-0.8.0-h3f2d84a_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/zipp-3.23.0-pyhcf101f3_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/zstandard-0.25.0-py310h139afa4_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/zstd-1.5.7-hb78ec9c_6.conda
+ - pypi: https://files.pythonhosted.org/packages/c5/0d/84a4380f930db0010168e0aa7b7a8fed9ba1835a8fbb1472bc6d0201d529/build-1.4.0-py3-none-any.whl
+ - pypi: https://files.pythonhosted.org/packages/bd/24/12818598c362d7f300f18e74db45963dbcb85150324092410c8b49405e42/pyproject_hooks-1.2.0-py3-none-any.whl
+ linux-aarch64:
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/_openmp_mutex-4.5-20_gnu.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/archspec-0.2.5-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/auditwheel-6.6.0-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/backports.zstd-1.3.0-py310hfa1aa29_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/boltons-25.0.0-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/brotli-python-1.2.0-py310hbe54bbb_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/bzip2-1.0.8-h4777abc_9.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/c-ares-1.34.6-he30d5cf_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2026.2.25-hbd8a1cb_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/certifi-2026.2.25-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/cffi-2.0.0-py310h0826a50_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/cfgv-3.5.0-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/charset-normalizer-3.4.5-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/cmake-3.31.8-hc9d863e_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/conda-26.1.1-py310h4c7bcd0_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/conda-libmamba-solver-25.11.0-pyhd8ed1ab_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/conda-package-handling-2.4.0-pyh7900ff3_2.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/conda-package-streaming-0.12.0-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/cpp-expected-1.3.1-hdc560ac_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/distlib-0.4.0-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/distro-1.9.0-pyhd8ed1ab_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/doxygen-1.13.2-h5e0f5ae_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/exceptiongroup-1.3.1-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/filelock-3.25.2-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/fmt-12.1.0-h20c602a_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/frozendict-2.4.7-py310h5b55623_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/h2-4.3.0-pyhcf101f3_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/hpack-4.1.0-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/hyperframe-6.1.0-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/icu-78.2-hcab7f73_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/identify-2.6.18-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/idna-3.11-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/importlib-metadata-8.7.0-pyhe01879c_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/importlib-resources-6.5.2-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/importlib_resources-6.5.2-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/jsonpatch-1.33-pyhd8ed1ab_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/jsonpointer-3.0.0-pyhcf101f3_3.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/keyutils-1.6.3-h86ecc28_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/krb5-1.22.2-hfd895c2_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/ld_impl_linux-aarch64-2.45.1-default_h1979696_101.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libarchive-3.8.6-gpl_hbe7d12b_100.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libblas-3.11.0-5_haddc8a3_openblas.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libcblas-3.11.0-5_hd72aa62_openblas.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libcurl-8.19.0-hc57f145_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libedit-3.1.20250104-pl5321h976ea20_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libev-4.33-h31becfc_2.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libexpat-2.7.4-hfae3067_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libffi-3.5.2-h376a255_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libgcc-15.2.0-h8acb6b2_18.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libgcc-ng-15.2.0-he9431aa_18.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libgfortran-15.2.0-he9431aa_18.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libgfortran5-15.2.0-h1b7bec0_18.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libgomp-15.2.0-h8acb6b2_18.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libiconv-1.18-h90929bb_2.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/liblapack-3.11.0-5_h88aeb00_openblas.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/liblzma-5.8.2-he30d5cf_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libmamba-2.5.0-hc712cdd_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libmamba-spdlog-2.5.0-h3ad78e7_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libmambapy-2.5.0-py310hdf79504_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libnghttp2-1.67.0-ha888d0e_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libnsl-2.0.1-h86ecc28_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libopenblas-0.3.30-pthreads_h9d3fd7e_4.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libsolv-0.7.36-hdda61c4_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libsqlite-3.52.0-h10b116e_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libssh2-1.11.1-h18c354c_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libstdcxx-15.2.0-hef695bb_18.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libstdcxx-ng-15.2.0-hdbbeba8_18.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libuuid-2.41.3-h1022ec0_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libuv-1.51.0-he30d5cf_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libxcrypt-4.4.36-h31becfc_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libxml2-16-2.15.2-h79dcc73_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libxml2-2.15.2-h825857f_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libzlib-1.3.1-h86ecc28_2.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/lz4-c-1.10.0-h5ad3122_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/lzo-2.10-h80f16a2_1002.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/menuinst-2.4.2-py310h4c7bcd0_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/msgpack-python-1.1.2-py310h0992a49_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/ncurses-6.5-ha32ae93_3.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/ninja-1.13.2-hdc560ac_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/nlohmann_json-abi-3.12.0-h0f90c79_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/nodeenv-1.10.0-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/numpy-2.2.6-py310h6e5608f_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/openssl-3.6.1-h546c87b_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/packaging-25.0-pyh29332c3_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/patchelf-0.17.2-h884eca8_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/pathspec-1.0.4-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/pip-26.0.1-pyh8b19718_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/pixi-pycharm-0.0.10-unix_hf108a03_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/pkginfo-1.12.1.2-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/platformdirs-4.9.4-pyhcf101f3_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/pluggy-1.6.0-pyhf9edf01_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/pre-commit-4.5.1-pyha770c72_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/pybind11-abi-11-hc364b38_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/pycosat-0.6.6-py310h5b55623_3.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/pycparser-2.22-pyh29332c3_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/pyelftools-0.32-pyh707e725_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/pyproject-metadata-0.11.0-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/pysocks-1.7.1-pyha55dd90_7.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/python-3.10.20-h28be5d3_0_cpython.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/python-discovery-1.2.1-pyhcf101f3_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/python_abi-3.10-8_cp310.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/pyyaml-6.0.3-py310h2d8da20_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/readline-8.3-hb682ff5_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/reproc-14.2.5.post0-h86ecc28_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/reproc-cpp-14.2.5.post0-h5ad3122_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/requests-2.32.5-pyhcf101f3_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/rhash-1.4.6-h86ecc28_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/ruamel.yaml-0.18.17-py310hef25091_2.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/ruamel.yaml.clib-0.2.15-py310hef25091_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/scikit-build-core-0.11.6-pyh7e86bf3_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/setuptools-82.0.1-pyh332efcf_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/setuptools-scm-9.2.2-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/setuptools_scm-9.2.2-hd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/simdjson-4.2.4-hfefdfc9_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/spdlog-1.17.0-h9f97df7_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/taplo-0.10.0-h3618846_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/tk-8.6.13-noxft_h0dc03b3_103.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/tomli-2.4.0-pyhcf101f3_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/tqdm-4.67.3-pyh8f84b5b_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/truststore-0.10.4-pyhcf101f3_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/typing-extensions-4.15.0-h396c80c_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/typing_extensions-4.15.0-pyhcf101f3_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/tzdata-2025c-hc9c84f9_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/ukkonen-1.1.0-py310h0992a49_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/urllib3-2.6.3-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/virtualenv-21.2.0-pyhcf101f3_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/wheel-0.46.3-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/yaml-0.2.5-h80f16a2_3.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/yaml-cpp-0.8.0-h5ad3122_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/zipp-3.23.0-pyhcf101f3_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/zstandard-0.25.0-py310hef25091_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/zstd-1.5.7-h85ac4a6_6.conda
+ - pypi: https://files.pythonhosted.org/packages/c5/0d/84a4380f930db0010168e0aa7b7a8fed9ba1835a8fbb1472bc6d0201d529/build-1.4.0-py3-none-any.whl
+ - pypi: https://files.pythonhosted.org/packages/bd/24/12818598c362d7f300f18e74db45963dbcb85150324092410c8b49405e42/pyproject_hooks-1.2.0-py3-none-any.whl
+ manylinux228-py311:
+ channels:
+ - url: https://conda.anaconda.org/conda-forge/
+ indexes:
+ - https://pypi.org/simple
+ options:
+ pypi-prerelease-mode: if-necessary-or-explicit
+ packages:
+ linux-64:
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/_openmp_mutex-4.5-20_gnu.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/archspec-0.2.5-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/auditwheel-6.6.0-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/backports.zstd-1.3.0-py311h6b1f9c4_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/boltons-25.0.0-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/brotli-python-1.2.0-py311h66f275b_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/bzip2-1.0.8-hda65f42_9.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/c-ares-1.34.6-hb03c661_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2026.2.25-hbd8a1cb_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/certifi-2026.2.25-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/cffi-2.0.0-py311h03d9500_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/cfgv-3.5.0-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/charset-normalizer-3.4.5-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/cmake-3.31.8-hc85cc9f_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/conda-26.1.1-py311h38be061_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/conda-libmamba-solver-25.11.0-pyhd8ed1ab_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/conda-package-handling-2.4.0-pyh7900ff3_2.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/conda-package-streaming-0.12.0-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/cpp-expected-1.3.1-h171cf75_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/distlib-0.4.0-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/distro-1.9.0-pyhd8ed1ab_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/doxygen-1.13.2-h8e693c7_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/exceptiongroup-1.3.1-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/filelock-3.25.2-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/fmt-12.1.0-hff5e90c_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/frozendict-2.4.7-py311h49ec1c0_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/h2-4.3.0-pyhcf101f3_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/hpack-4.1.0-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/hyperframe-6.1.0-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/icu-78.2-h33c6efd_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/identify-2.6.18-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/idna-3.11-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/importlib-metadata-8.7.0-pyhe01879c_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/importlib-resources-6.5.2-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/importlib_resources-6.5.2-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/jsonpatch-1.33-pyhd8ed1ab_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/jsonpointer-3.0.0-pyhcf101f3_3.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/keyutils-1.6.3-hb9d3cd8_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/krb5-1.22.2-ha1258a1_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/ld_impl_linux-64-2.45.1-default_hbd61a6d_101.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/libarchive-3.8.6-gpl_hc2c16d8_100.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/libblas-3.11.0-5_h4a7cf45_openblas.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/libcblas-3.11.0-5_h0358290_openblas.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/libcurl-8.19.0-hcf29cc6_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/libedit-3.1.20250104-pl5321h7949ede_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/libev-4.33-hd590300_2.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/libexpat-2.7.4-hecca717_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/libffi-3.5.2-h3435931_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/libgcc-15.2.0-he0feb66_18.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/libgcc-ng-15.2.0-h69a702a_18.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/libgfortran-15.2.0-h69a702a_18.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/libgfortran5-15.2.0-h68bc16d_18.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/libgomp-15.2.0-he0feb66_18.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/libiconv-1.18-h3b78370_2.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/liblapack-3.11.0-5_h47877c9_openblas.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/liblzma-5.8.2-hb03c661_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/libmamba-2.5.0-hd28c85e_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/libmamba-spdlog-2.5.0-h12fcf84_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/libmambapy-2.5.0-py311hc5d5c7c_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/libnghttp2-1.67.0-had1ee68_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/libnsl-2.0.1-hb9d3cd8_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/libopenblas-0.3.30-pthreads_h94d23a6_4.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/libsolv-0.7.35-h9463b59_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/libsqlite-3.52.0-hf4e2dac_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/libssh2-1.11.1-hcf80075_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-15.2.0-h934c35e_18.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-ng-15.2.0-hdf11a46_18.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/libuuid-2.41.3-h5347b49_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/libuv-1.51.0-hb03c661_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/libxcrypt-4.4.36-hd590300_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/libxml2-16-2.15.2-hca6bf5a_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/libxml2-2.15.2-he237659_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/libzlib-1.3.1-hb9d3cd8_2.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/lz4-c-1.10.0-h5888daf_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/lzo-2.10-h280c20c_1002.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/menuinst-2.4.2-py311h38be061_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/msgpack-python-1.1.2-py311hdf67eae_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/ncurses-6.5-h2d0b736_3.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/ninja-1.13.2-h171cf75_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/nlohmann_json-abi-3.12.0-h0f90c79_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/nodeenv-1.10.0-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/numpy-2.4.2-py311h2e04523_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/openssl-3.6.1-h35e630c_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/packaging-25.0-pyh29332c3_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/patchelf-0.17.2-h58526e2_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/pathspec-1.0.4-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/pip-26.0.1-pyh8b19718_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/pixi-pycharm-0.0.10-unix_hf108a03_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/pkginfo-1.12.1.2-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/platformdirs-4.9.4-pyhcf101f3_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/pluggy-1.6.0-pyhf9edf01_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/pre-commit-4.5.1-pyha770c72_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/pybind11-abi-11-hc364b38_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/pycosat-0.6.6-py311h49ec1c0_3.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/pycparser-2.22-pyh29332c3_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/pyelftools-0.32-pyh707e725_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/pyproject-metadata-0.11.0-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/pysocks-1.7.1-pyha55dd90_7.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/python-3.11.15-hd63d673_0_cpython.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/python-discovery-1.2.1-pyhcf101f3_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/python_abi-3.11-8_cp311.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/pyyaml-6.0.3-py311h3778330_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/readline-8.3-h853b02a_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/reproc-14.2.5.post0-hb9d3cd8_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/reproc-cpp-14.2.5.post0-h5888daf_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/requests-2.32.5-pyhcf101f3_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/rhash-1.4.6-hb9d3cd8_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/ruamel.yaml-0.18.17-py311haee01d2_2.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/ruamel.yaml.clib-0.2.15-py311haee01d2_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/scikit-build-core-0.11.6-pyh7e86bf3_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/setuptools-82.0.1-pyh332efcf_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/setuptools-scm-9.2.2-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/setuptools_scm-9.2.2-hd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/simdjson-4.2.4-hb700be7_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/spdlog-1.17.0-hab81395_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/taplo-0.10.0-h2d22210_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/tk-8.6.13-noxft_h366c992_103.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/tomli-2.4.0-pyhcf101f3_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/tqdm-4.67.3-pyh8f84b5b_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/truststore-0.10.4-pyhcf101f3_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/typing-extensions-4.15.0-h396c80c_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/typing_extensions-4.15.0-pyhcf101f3_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/tzdata-2025c-hc9c84f9_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/ukkonen-1.1.0-py311hdf67eae_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/urllib3-2.6.3-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/virtualenv-21.2.0-pyhcf101f3_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/wheel-0.46.3-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/yaml-0.2.5-h280c20c_3.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/yaml-cpp-0.8.0-h3f2d84a_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/zipp-3.23.0-pyhcf101f3_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/zstandard-0.25.0-py311haee01d2_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/zstd-1.5.7-hb78ec9c_6.conda
+ - pypi: https://files.pythonhosted.org/packages/c5/0d/84a4380f930db0010168e0aa7b7a8fed9ba1835a8fbb1472bc6d0201d529/build-1.4.0-py3-none-any.whl
+ - pypi: https://files.pythonhosted.org/packages/bd/24/12818598c362d7f300f18e74db45963dbcb85150324092410c8b49405e42/pyproject_hooks-1.2.0-py3-none-any.whl
+ linux-aarch64:
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/_openmp_mutex-4.5-20_gnu.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/archspec-0.2.5-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/auditwheel-6.6.0-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/backports.zstd-1.3.0-py311h6ce31b0_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/boltons-25.0.0-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/brotli-python-1.2.0-py311h14a79a7_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/bzip2-1.0.8-h4777abc_9.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/c-ares-1.34.6-he30d5cf_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2026.2.25-hbd8a1cb_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/certifi-2026.2.25-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/cffi-2.0.0-py311h460c349_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/cfgv-3.5.0-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/charset-normalizer-3.4.5-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/cmake-3.31.8-hc9d863e_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/conda-26.1.1-py311hec3470c_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/conda-libmamba-solver-25.11.0-pyhd8ed1ab_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/conda-package-handling-2.4.0-pyh7900ff3_2.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/conda-package-streaming-0.12.0-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/cpp-expected-1.3.1-hdc560ac_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/distlib-0.4.0-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/distro-1.9.0-pyhd8ed1ab_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/doxygen-1.13.2-h5e0f5ae_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/exceptiongroup-1.3.1-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/filelock-3.25.2-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/fmt-12.1.0-h20c602a_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/frozendict-2.4.7-py311h19352d5_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/h2-4.3.0-pyhcf101f3_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/hpack-4.1.0-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/hyperframe-6.1.0-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/icu-78.2-hcab7f73_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/identify-2.6.18-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/idna-3.11-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/importlib-metadata-8.7.0-pyhe01879c_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/importlib-resources-6.5.2-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/importlib_resources-6.5.2-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/jsonpatch-1.33-pyhd8ed1ab_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/jsonpointer-3.0.0-pyhcf101f3_3.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/keyutils-1.6.3-h86ecc28_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/krb5-1.22.2-hfd895c2_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/ld_impl_linux-aarch64-2.45.1-default_h1979696_101.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libarchive-3.8.6-gpl_hbe7d12b_100.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libblas-3.11.0-5_haddc8a3_openblas.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libcblas-3.11.0-5_hd72aa62_openblas.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libcurl-8.19.0-hc57f145_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libedit-3.1.20250104-pl5321h976ea20_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libev-4.33-h31becfc_2.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libexpat-2.7.4-hfae3067_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libffi-3.5.2-h376a255_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libgcc-15.2.0-h8acb6b2_18.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libgcc-ng-15.2.0-he9431aa_18.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libgfortran-15.2.0-he9431aa_18.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libgfortran5-15.2.0-h1b7bec0_18.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libgomp-15.2.0-h8acb6b2_18.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libiconv-1.18-h90929bb_2.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/liblapack-3.11.0-5_h88aeb00_openblas.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/liblzma-5.8.2-he30d5cf_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libmamba-2.5.0-hc712cdd_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libmamba-spdlog-2.5.0-h3ad78e7_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libmambapy-2.5.0-py311h6a8bf82_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libnghttp2-1.67.0-ha888d0e_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libnsl-2.0.1-h86ecc28_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libopenblas-0.3.30-pthreads_h9d3fd7e_4.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libsolv-0.7.36-hdda61c4_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libsqlite-3.52.0-h10b116e_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libssh2-1.11.1-h18c354c_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libstdcxx-15.2.0-hef695bb_18.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libstdcxx-ng-15.2.0-hdbbeba8_18.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libuuid-2.41.3-h1022ec0_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libuv-1.51.0-he30d5cf_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libxcrypt-4.4.36-h31becfc_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libxml2-16-2.15.2-h79dcc73_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libxml2-2.15.2-h825857f_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libzlib-1.3.1-h86ecc28_2.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/lz4-c-1.10.0-h5ad3122_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/lzo-2.10-h80f16a2_1002.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/menuinst-2.4.2-py311hec3470c_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/msgpack-python-1.1.2-py311hfca10b7_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/ncurses-6.5-ha32ae93_3.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/ninja-1.13.2-hdc560ac_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/nlohmann_json-abi-3.12.0-h0f90c79_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/nodeenv-1.10.0-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/numpy-2.4.2-py311h669026d_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/openssl-3.6.1-h546c87b_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/packaging-25.0-pyh29332c3_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/patchelf-0.17.2-h884eca8_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/pathspec-1.0.4-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/pip-26.0.1-pyh8b19718_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/pixi-pycharm-0.0.10-unix_hf108a03_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/pkginfo-1.12.1.2-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/platformdirs-4.9.4-pyhcf101f3_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/pluggy-1.6.0-pyhf9edf01_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/pre-commit-4.5.1-pyha770c72_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/pybind11-abi-11-hc364b38_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/pycosat-0.6.6-py311h19352d5_3.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/pycparser-2.22-pyh29332c3_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/pyelftools-0.32-pyh707e725_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/pyproject-metadata-0.11.0-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/pysocks-1.7.1-pyha55dd90_7.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/python-3.11.15-h91f4b29_0_cpython.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/python-discovery-1.2.1-pyhcf101f3_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/python_abi-3.11-8_cp311.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/pyyaml-6.0.3-py311h164a683_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/readline-8.3-hb682ff5_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/reproc-14.2.5.post0-h86ecc28_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/reproc-cpp-14.2.5.post0-h5ad3122_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/requests-2.32.5-pyhcf101f3_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/rhash-1.4.6-h86ecc28_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/ruamel.yaml-0.18.17-py311h51cfe5d_2.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/ruamel.yaml.clib-0.2.15-py311h51cfe5d_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/scikit-build-core-0.11.6-pyh7e86bf3_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/setuptools-82.0.1-pyh332efcf_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/setuptools-scm-9.2.2-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/setuptools_scm-9.2.2-hd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/simdjson-4.2.4-hfefdfc9_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/spdlog-1.17.0-h9f97df7_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/taplo-0.10.0-h3618846_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/tk-8.6.13-noxft_h0dc03b3_103.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/tomli-2.4.0-pyhcf101f3_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/tqdm-4.67.3-pyh8f84b5b_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/truststore-0.10.4-pyhcf101f3_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/typing-extensions-4.15.0-h396c80c_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/typing_extensions-4.15.0-pyhcf101f3_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/tzdata-2025c-hc9c84f9_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/ukkonen-1.1.0-py311hfca10b7_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/urllib3-2.6.3-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/virtualenv-21.2.0-pyhcf101f3_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/wheel-0.46.3-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/yaml-0.2.5-h80f16a2_3.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/yaml-cpp-0.8.0-h5ad3122_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/zipp-3.23.0-pyhcf101f3_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/zstandard-0.25.0-py311h51cfe5d_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/zstd-1.5.7-h85ac4a6_6.conda
+ - pypi: https://files.pythonhosted.org/packages/c5/0d/84a4380f930db0010168e0aa7b7a8fed9ba1835a8fbb1472bc6d0201d529/build-1.4.0-py3-none-any.whl
+ - pypi: https://files.pythonhosted.org/packages/bd/24/12818598c362d7f300f18e74db45963dbcb85150324092410c8b49405e42/pyproject_hooks-1.2.0-py3-none-any.whl
+ publish:
+ channels:
+ - url: https://conda.anaconda.org/conda-forge/
+ indexes:
+ - https://pypi.org/simple
+ options:
+ pypi-prerelease-mode: if-necessary-or-explicit
+ packages:
+ linux-64:
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/_openmp_mutex-4.5-20_gnu.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/archspec-0.2.5-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/backports.zstd-1.3.0-py314h680f03e_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/boltons-25.0.0-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/brotli-python-1.2.0-py314h3de4e8d_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/bzip2-1.0.8-hda65f42_9.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/c-ares-1.34.6-hb03c661_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2026.2.25-hbd8a1cb_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/certifi-2026.2.25-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/cffi-2.0.0-py314h4a8dc5f_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/cfgv-3.5.0-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/charset-normalizer-3.4.6-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/conda-26.1.1-py314hdafbbf9_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/conda-libmamba-solver-25.11.0-pyhd8ed1ab_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/conda-package-handling-2.4.0-pyh7900ff3_2.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/conda-package-streaming-0.12.0-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/cpp-expected-1.3.1-h171cf75_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/distlib-0.4.0-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/distro-1.9.0-pyhd8ed1ab_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/filelock-3.25.2-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/fmt-12.1.0-hff5e90c_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/frozendict-2.4.7-py314h5bd0f2a_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/gh-2.88.1-h76a2195_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/h2-4.3.0-pyhcf101f3_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/hpack-4.1.0-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/hyperframe-6.1.0-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/icu-78.3-h33c6efd_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/identify-2.6.18-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/idna-3.11-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/importlib-metadata-8.8.0-pyhcf101f3_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/jsonpatch-1.33-pyhd8ed1ab_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/jsonpointer-3.1.1-pyhcf101f3_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/keyutils-1.6.3-hb9d3cd8_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/krb5-1.22.2-ha1258a1_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/ld_impl_linux-64-2.45.1-default_hbd61a6d_102.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/libarchive-3.8.6-gpl_hc2c16d8_100.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/libcurl-8.19.0-hcf29cc6_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/libedit-3.1.20250104-pl5321h7949ede_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/libev-4.33-hd590300_2.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/libexpat-2.7.5-hecca717_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/libffi-3.5.2-h3435931_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/libgcc-15.2.0-he0feb66_18.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/libgcc-ng-15.2.0-h69a702a_18.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/libgomp-15.2.0-he0feb66_18.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/libiconv-1.18-h3b78370_2.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/liblzma-5.8.2-hb03c661_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/libmamba-2.5.0-hd28c85e_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/libmamba-spdlog-2.5.0-h12fcf84_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/libmambapy-2.5.0-py314hcbd71af_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/libmpdec-4.0.0-hb03c661_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/libnghttp2-1.68.1-h877daf1_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/libsolv-0.7.36-h9463b59_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/libsqlite-3.52.0-hf4e2dac_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/libssh2-1.11.1-hcf80075_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-15.2.0-h934c35e_18.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/libuuid-2.42-h5347b49_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/libxml2-16-2.15.2-hca6bf5a_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/libxml2-2.15.2-he237659_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/libzlib-1.3.2-h25fd6f3_2.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/lz4-c-1.10.0-h5888daf_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/lzo-2.10-h280c20c_1002.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/menuinst-2.4.2-py314hdafbbf9_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/msgpack-python-1.1.2-py314h9891dd4_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/ncurses-6.5-h2d0b736_3.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/nlohmann_json-abi-3.12.0-h0f90c79_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/nodeenv-1.10.0-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/openssl-3.6.1-h35e630c_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/packaging-26.0-pyhcf101f3_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/pixi-pycharm-0.0.10-unix_hf108a03_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/platformdirs-4.9.4-pyhcf101f3_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/pluggy-1.6.0-pyhf9edf01_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/pre-commit-4.5.1-pyha770c72_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/pybind11-abi-11-hc364b38_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/pycosat-0.6.6-py314h5bd0f2a_3.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/pycparser-2.22-pyh29332c3_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/pysocks-1.7.1-pyha55dd90_7.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/python-3.14.3-h32b2ec7_101_cp314.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/python-discovery-1.2.1-pyhcf101f3_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/python_abi-3.14-8_cp314.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/pyyaml-6.0.3-py314h67df5f8_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/readline-8.3-h853b02a_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/reproc-14.2.5.post0-hb9d3cd8_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/reproc-cpp-14.2.5.post0-h5888daf_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/requests-2.33.1-pyhcf101f3_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/ruamel.yaml-0.18.17-py314h0f05182_2.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/ruamel.yaml.clib-0.2.15-py314h0f05182_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/setuptools-82.0.1-pyh332efcf_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/simdjson-4.2.4-hb700be7_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/spdlog-1.17.0-hab81395_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/taplo-0.10.0-h2d22210_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/tk-8.6.13-noxft_h366c992_103.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/tqdm-4.67.3-pyh8f84b5b_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/truststore-0.10.4-pyhcf101f3_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/typing_extensions-4.15.0-pyhcf101f3_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/tzdata-2025c-hc9c84f9_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/ukkonen-1.1.0-py314h9891dd4_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/urllib3-2.6.3-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/virtualenv-21.2.0-pyhcf101f3_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/yaml-0.2.5-h280c20c_3.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/yaml-cpp-0.8.0-h3f2d84a_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/zipp-3.23.0-pyhcf101f3_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/zstandard-0.25.0-py314h0f05182_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/zstd-1.5.7-hb78ec9c_6.conda
+ - pypi: https://files.pythonhosted.org/packages/34/71/1ea5a7352ae516d5512d17babe7e1b87d9db5150b21f794b1377eac1edc0/cryptography-46.0.6-cp311-abi3-manylinux_2_28_x86_64.whl
+ - pypi: https://files.pythonhosted.org/packages/02/10/5da547df7a391dcde17f59520a231527b8571e6f46fc8efb02ccb370ab12/docutils-0.22.4-py3-none-any.whl
+ - pypi: https://files.pythonhosted.org/packages/42/77/de194443bf38daed9452139e960c632b0ef9f9a5dd9ce605fdf18ca9f1b1/id-1.6.1-py3-none-any.whl
+ - pypi: https://files.pythonhosted.org/packages/7f/66/b15ce62552d84bbfcec9a4873ab79d993a1dd4edb922cbfccae192bd5b5f/jaraco.classes-3.4.0-py3-none-any.whl
+ - pypi: https://files.pythonhosted.org/packages/f2/58/bc8954bda5fcda97bd7c19be11b85f91973d67a706ed4a3aec33e7de22db/jaraco_context-6.1.2-py3-none-any.whl
+ - pypi: https://files.pythonhosted.org/packages/fd/c4/813bb09f0985cb21e959f21f2464169eca882656849adf727ac7bb7e1767/jaraco_functools-4.4.0-py3-none-any.whl
+ - pypi: https://files.pythonhosted.org/packages/b2/a3/e137168c9c44d18eff0376253da9f1e9234d0239e0ee230d2fee6cea8e55/jeepney-0.9.0-py3-none-any.whl
+ - pypi: https://files.pythonhosted.org/packages/81/db/e655086b7f3a705df045bf0933bdd9c2f79bb3c97bfef1384598bb79a217/keyring-25.7.0-py3-none-any.whl
+ - pypi: https://files.pythonhosted.org/packages/94/54/e7d793b573f298e1c9013b8c4dade17d481164aa517d1d7148619c2cedbf/markdown_it_py-4.0.0-py3-none-any.whl
+ - pypi: https://files.pythonhosted.org/packages/b3/38/89ba8ad64ae25be8de66a6d463314cf1eb366222074cfda9ee839c56a4b4/mdurl-0.1.2-py3-none-any.whl
+ - pypi: https://files.pythonhosted.org/packages/a4/8e/469e5a4a2f5855992e425f3cb33804cc07bf18d48f2db061aec61ce50270/more_itertools-10.8.0-py3-none-any.whl
+ - pypi: https://files.pythonhosted.org/packages/d6/b7/ec1cbc6b297a808c513f59f501656389623fc09ad6a58c640851289c7854/nh3-0.3.4-cp38-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
+ - pypi: https://files.pythonhosted.org/packages/f4/7e/a72dd26f3b0f4f2bf1dd8923c85f7ceb43172af56d63c7383eb62b332364/pygments-2.20.0-py3-none-any.whl
+ - pypi: https://files.pythonhosted.org/packages/e1/67/921ec3024056483db83953ae8e48079ad62b92db7880013ca77632921dd0/readme_renderer-44.0-py3-none-any.whl
+ - pypi: https://files.pythonhosted.org/packages/3f/51/d4db610ef29373b879047326cbf6fa98b6c1969d6f6dc423279de2b1be2c/requests_toolbelt-1.0.0-py2.py3-none-any.whl
+ - pypi: https://files.pythonhosted.org/packages/ff/9a/9afaade874b2fa6c752c36f1548f718b5b83af81ed9b76628329dab81c1b/rfc3986-2.0.0-py2.py3-none-any.whl
+ - pypi: https://files.pythonhosted.org/packages/14/25/b208c5683343959b670dc001595f2f3737e051da617f66c31f7c4fa93abc/rich-14.3.3-py3-none-any.whl
+ - pypi: https://files.pythonhosted.org/packages/b7/46/f5af3402b579fd5e11573ce652019a67074317e18c1935cc0b4ba9b35552/secretstorage-3.5.0-py3-none-any.whl
+ - pypi: https://files.pythonhosted.org/packages/3a/7a/882d99539b19b1490cac5d77c67338d126e4122c8276bf640e411650c830/twine-6.2.0-py3-none-any.whl
+ linux-aarch64:
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/_openmp_mutex-4.5-20_gnu.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/archspec-0.2.5-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/backports.zstd-1.3.0-py314h680f03e_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/boltons-25.0.0-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/brotli-python-1.2.0-py314h352cb57_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/bzip2-1.0.8-h4777abc_9.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/c-ares-1.34.6-he30d5cf_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2026.2.25-hbd8a1cb_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/certifi-2026.2.25-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/cffi-2.0.0-py314h0bd77cf_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/cfgv-3.5.0-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/charset-normalizer-3.4.6-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/conda-26.1.1-py314h28a4750_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/conda-libmamba-solver-25.11.0-pyhd8ed1ab_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/conda-package-handling-2.4.0-pyh7900ff3_2.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/conda-package-streaming-0.12.0-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/cpp-expected-1.3.1-hdc560ac_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/distlib-0.4.0-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/distro-1.9.0-pyhd8ed1ab_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/filelock-3.25.2-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/fmt-12.1.0-h20c602a_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/frozendict-2.4.7-py314h51f160d_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/gh-2.88.1-h94b2740_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/h2-4.3.0-pyhcf101f3_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/hpack-4.1.0-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/hyperframe-6.1.0-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/icu-78.3-hcab7f73_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/identify-2.6.18-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/idna-3.11-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/importlib-metadata-8.8.0-pyhcf101f3_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/jsonpatch-1.33-pyhd8ed1ab_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/jsonpointer-3.1.1-pyhcf101f3_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/keyutils-1.6.3-h86ecc28_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/krb5-1.22.2-hfd895c2_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/ld_impl_linux-aarch64-2.45.1-default_h1979696_102.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libarchive-3.8.6-gpl_hbe7d12b_100.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libcurl-8.19.0-hc57f145_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libedit-3.1.20250104-pl5321h976ea20_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libev-4.33-h31becfc_2.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libexpat-2.7.5-hfae3067_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libffi-3.5.2-h376a255_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libgcc-15.2.0-h8acb6b2_18.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libgcc-ng-15.2.0-he9431aa_18.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libgomp-15.2.0-h8acb6b2_18.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libiconv-1.18-h90929bb_2.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/liblzma-5.8.2-he30d5cf_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libmamba-2.5.0-hc712cdd_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libmamba-spdlog-2.5.0-h3ad78e7_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libmambapy-2.5.0-py314h709e558_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libmpdec-4.0.0-he30d5cf_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libnghttp2-1.68.1-hd3077d7_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libsolv-0.7.36-hdda61c4_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libsqlite-3.52.0-h10b116e_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libssh2-1.11.1-h18c354c_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libstdcxx-15.2.0-hef695bb_18.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libuuid-2.42-h1022ec0_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libxml2-16-2.15.2-h79dcc73_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libxml2-2.15.2-h825857f_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libzlib-1.3.2-hdc9db2a_2.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/lz4-c-1.10.0-h5ad3122_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/lzo-2.10-h80f16a2_1002.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/menuinst-2.4.2-py314h28a4750_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/msgpack-python-1.1.2-py314hd7d8586_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/ncurses-6.5-ha32ae93_3.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/nlohmann_json-abi-3.12.0-h0f90c79_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/nodeenv-1.10.0-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/openssl-3.6.1-h546c87b_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/packaging-26.0-pyhcf101f3_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/pixi-pycharm-0.0.10-unix_hf108a03_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/platformdirs-4.9.4-pyhcf101f3_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/pluggy-1.6.0-pyhf9edf01_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/pre-commit-4.5.1-pyha770c72_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/pybind11-abi-11-hc364b38_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/pycosat-0.6.6-py314h51f160d_3.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/pycparser-2.22-pyh29332c3_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/pysocks-1.7.1-pyha55dd90_7.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/python-3.14.3-hb06a95a_101_cp314.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/python-discovery-1.2.1-pyhcf101f3_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/python_abi-3.14-8_cp314.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/pyyaml-6.0.3-py314h807365f_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/readline-8.3-hb682ff5_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/reproc-14.2.5.post0-h86ecc28_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/reproc-cpp-14.2.5.post0-h5ad3122_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/requests-2.33.1-pyhcf101f3_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/ruamel.yaml-0.18.17-py314h2e8dab5_2.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/ruamel.yaml.clib-0.2.15-py314h2e8dab5_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/setuptools-82.0.1-pyh332efcf_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/simdjson-4.2.4-hfefdfc9_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/spdlog-1.17.0-h9f97df7_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/taplo-0.10.0-h3618846_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/tk-8.6.13-noxft_h0dc03b3_103.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/tqdm-4.67.3-pyh8f84b5b_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/truststore-0.10.4-pyhcf101f3_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/typing_extensions-4.15.0-pyhcf101f3_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/tzdata-2025c-hc9c84f9_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/ukkonen-1.1.0-py314hd7d8586_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/urllib3-2.6.3-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/virtualenv-21.2.0-pyhcf101f3_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/yaml-0.2.5-h80f16a2_3.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/yaml-cpp-0.8.0-h5ad3122_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/zipp-3.23.0-pyhcf101f3_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/zstandard-0.25.0-py314h2e8dab5_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/zstd-1.5.7-h85ac4a6_6.conda
+ - pypi: https://files.pythonhosted.org/packages/d4/12/123be7292674abf76b21ac1fc0e1af50661f0e5b8f0ec8285faac18eb99e/cryptography-46.0.6-cp311-abi3-manylinux_2_28_aarch64.whl
+ - pypi: https://files.pythonhosted.org/packages/02/10/5da547df7a391dcde17f59520a231527b8571e6f46fc8efb02ccb370ab12/docutils-0.22.4-py3-none-any.whl
+ - pypi: https://files.pythonhosted.org/packages/42/77/de194443bf38daed9452139e960c632b0ef9f9a5dd9ce605fdf18ca9f1b1/id-1.6.1-py3-none-any.whl
+ - pypi: https://files.pythonhosted.org/packages/7f/66/b15ce62552d84bbfcec9a4873ab79d993a1dd4edb922cbfccae192bd5b5f/jaraco.classes-3.4.0-py3-none-any.whl
+ - pypi: https://files.pythonhosted.org/packages/f2/58/bc8954bda5fcda97bd7c19be11b85f91973d67a706ed4a3aec33e7de22db/jaraco_context-6.1.2-py3-none-any.whl
+ - pypi: https://files.pythonhosted.org/packages/fd/c4/813bb09f0985cb21e959f21f2464169eca882656849adf727ac7bb7e1767/jaraco_functools-4.4.0-py3-none-any.whl
+ - pypi: https://files.pythonhosted.org/packages/b2/a3/e137168c9c44d18eff0376253da9f1e9234d0239e0ee230d2fee6cea8e55/jeepney-0.9.0-py3-none-any.whl
+ - pypi: https://files.pythonhosted.org/packages/81/db/e655086b7f3a705df045bf0933bdd9c2f79bb3c97bfef1384598bb79a217/keyring-25.7.0-py3-none-any.whl
+ - pypi: https://files.pythonhosted.org/packages/94/54/e7d793b573f298e1c9013b8c4dade17d481164aa517d1d7148619c2cedbf/markdown_it_py-4.0.0-py3-none-any.whl
+ - pypi: https://files.pythonhosted.org/packages/b3/38/89ba8ad64ae25be8de66a6d463314cf1eb366222074cfda9ee839c56a4b4/mdurl-0.1.2-py3-none-any.whl
+ - pypi: https://files.pythonhosted.org/packages/a4/8e/469e5a4a2f5855992e425f3cb33804cc07bf18d48f2db061aec61ce50270/more_itertools-10.8.0-py3-none-any.whl
+ - pypi: https://files.pythonhosted.org/packages/2b/60/c9a33361da8cde7c7760f091cd10467bc470634e4eea31c8bb70935b00a4/nh3-0.3.4-cp38-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
+ - pypi: https://files.pythonhosted.org/packages/f4/7e/a72dd26f3b0f4f2bf1dd8923c85f7ceb43172af56d63c7383eb62b332364/pygments-2.20.0-py3-none-any.whl
+ - pypi: https://files.pythonhosted.org/packages/e1/67/921ec3024056483db83953ae8e48079ad62b92db7880013ca77632921dd0/readme_renderer-44.0-py3-none-any.whl
+ - pypi: https://files.pythonhosted.org/packages/3f/51/d4db610ef29373b879047326cbf6fa98b6c1969d6f6dc423279de2b1be2c/requests_toolbelt-1.0.0-py2.py3-none-any.whl
+ - pypi: https://files.pythonhosted.org/packages/ff/9a/9afaade874b2fa6c752c36f1548f718b5b83af81ed9b76628329dab81c1b/rfc3986-2.0.0-py2.py3-none-any.whl
+ - pypi: https://files.pythonhosted.org/packages/14/25/b208c5683343959b670dc001595f2f3737e051da617f66c31f7c4fa93abc/rich-14.3.3-py3-none-any.whl
+ - pypi: https://files.pythonhosted.org/packages/b7/46/f5af3402b579fd5e11573ce652019a67074317e18c1935cc0b4ba9b35552/secretstorage-3.5.0-py3-none-any.whl
+ - pypi: https://files.pythonhosted.org/packages/3a/7a/882d99539b19b1490cac5d77c67338d126e4122c8276bf640e411650c830/twine-6.2.0-py3-none-any.whl
+ osx-64:
+ - conda: https://conda.anaconda.org/conda-forge/noarch/archspec-0.2.5-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/backports.zstd-1.3.0-py314h680f03e_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/boltons-25.0.0-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-64/brotli-python-1.2.0-py314h3262eb8_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-64/bzip2-1.0.8-h500dc9f_9.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-64/c-ares-1.34.6-hb5e19a0_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2026.2.25-hbd8a1cb_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/certifi-2026.2.25-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-64/cffi-2.0.0-py314h8ca4d5a_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/cfgv-3.5.0-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/charset-normalizer-3.4.6-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-64/conda-26.1.1-py314hee6578b_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/conda-libmamba-solver-25.11.0-pyhd8ed1ab_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/conda-package-handling-2.4.0-pyh7900ff3_2.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/conda-package-streaming-0.12.0-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-64/cpp-expected-1.3.1-h0ba0a54_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/distlib-0.4.0-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/distro-1.9.0-pyhd8ed1ab_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/filelock-3.25.2-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-64/fmt-12.1.0-hda137b5_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-64/frozendict-2.4.7-py314h6482030_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-64/gh-2.88.1-hdaada87_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/h2-4.3.0-pyhcf101f3_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/hpack-4.1.0-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/hyperframe-6.1.0-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-64/icu-78.3-h25d91c4_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/identify-2.6.18-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/idna-3.11-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/importlib-metadata-8.8.0-pyhcf101f3_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/jsonpatch-1.33-pyhd8ed1ab_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/jsonpointer-3.1.1-pyhcf101f3_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-64/krb5-1.22.2-h207b36a_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-64/libarchive-3.8.6-gpl_h2bf6321_100.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-64/libcurl-8.19.0-h8f0b9e4_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-64/libcxx-22.1.2-h19cb2f5_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-64/libedit-3.1.20250104-pl5321ha958ccf_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-64/libev-4.33-h10d778d_2.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-64/libexpat-2.7.5-hcc62823_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-64/libffi-3.5.2-hd1f9c09_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-64/libiconv-1.18-h57a12c2_2.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-64/liblzma-5.8.2-h11316ed_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-64/libmamba-2.5.0-h7fe6c55_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-64/libmamba-spdlog-2.5.0-hb923e0c_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-64/libmambapy-2.5.0-py314haca2e77_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-64/libmpdec-4.0.0-hf3981d6_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-64/libnghttp2-1.68.1-h70048d4_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-64/libsolv-0.7.36-hf97c9bc_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-64/libsqlite-3.52.0-h77d7759_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-64/libssh2-1.11.1-hed3591d_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-64/libxml2-16-2.15.2-h7a90416_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-64/libxml2-2.15.2-hd552753_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-64/libzlib-1.3.2-hbb4bfdb_2.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-64/lz4-c-1.10.0-h240833e_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-64/lzo-2.10-h4132b18_1002.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-64/menuinst-2.4.2-py314hee6578b_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-64/msgpack-python-1.1.2-py314h00ed6fe_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-64/ncurses-6.5-h0622a9a_3.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/nlohmann_json-abi-3.12.0-h0f90c79_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/nodeenv-1.10.0-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-64/openssl-3.6.1-hb6871ef_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/packaging-26.0-pyhcf101f3_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/pixi-pycharm-0.0.10-unix_hf108a03_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/platformdirs-4.9.4-pyhcf101f3_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/pluggy-1.6.0-pyhf9edf01_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/pre-commit-4.5.1-pyha770c72_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/pybind11-abi-11-hc364b38_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-64/pycosat-0.6.6-py314h03d016b_3.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/pycparser-2.22-pyh29332c3_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/pysocks-1.7.1-pyha55dd90_7.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-64/python-3.14.3-h4f44bb5_101_cp314.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/python-discovery-1.2.1-pyhcf101f3_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/python_abi-3.14-8_cp314.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-64/pyyaml-6.0.3-py314h10d0514_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-64/readline-8.3-h68b038d_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-64/reproc-14.2.5.post0-h6e16a3a_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-64/reproc-cpp-14.2.5.post0-h240833e_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/requests-2.33.1-pyhcf101f3_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-64/ruamel.yaml-0.18.17-py314hd330473_2.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-64/ruamel.yaml.clib-0.2.15-py314hd330473_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/setuptools-82.0.1-pyh332efcf_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-64/simdjson-4.2.4-hcb651aa_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-64/spdlog-1.17.0-h30f01e4_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-64/taplo-0.10.0-hffa81eb_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-64/tk-8.6.13-h7142dee_3.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/tqdm-4.67.3-pyh8f84b5b_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/truststore-0.10.4-pyhcf101f3_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/typing_extensions-4.15.0-pyhcf101f3_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/tzdata-2025c-hc9c84f9_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-64/ukkonen-1.1.0-py314h473ef84_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/urllib3-2.6.3-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/virtualenv-21.2.0-pyhcf101f3_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-64/yaml-0.2.5-h4132b18_3.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-64/yaml-cpp-0.8.0-h92383a6_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/zipp-3.23.0-pyhcf101f3_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-64/zstandard-0.25.0-py314hd1e8ddb_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-64/zstd-1.5.7-h3eecb57_6.conda
+ - pypi: https://files.pythonhosted.org/packages/02/10/5da547df7a391dcde17f59520a231527b8571e6f46fc8efb02ccb370ab12/docutils-0.22.4-py3-none-any.whl
+ - pypi: https://files.pythonhosted.org/packages/42/77/de194443bf38daed9452139e960c632b0ef9f9a5dd9ce605fdf18ca9f1b1/id-1.6.1-py3-none-any.whl
+ - pypi: https://files.pythonhosted.org/packages/7f/66/b15ce62552d84bbfcec9a4873ab79d993a1dd4edb922cbfccae192bd5b5f/jaraco.classes-3.4.0-py3-none-any.whl
+ - pypi: https://files.pythonhosted.org/packages/f2/58/bc8954bda5fcda97bd7c19be11b85f91973d67a706ed4a3aec33e7de22db/jaraco_context-6.1.2-py3-none-any.whl
+ - pypi: https://files.pythonhosted.org/packages/fd/c4/813bb09f0985cb21e959f21f2464169eca882656849adf727ac7bb7e1767/jaraco_functools-4.4.0-py3-none-any.whl
+ - pypi: https://files.pythonhosted.org/packages/81/db/e655086b7f3a705df045bf0933bdd9c2f79bb3c97bfef1384598bb79a217/keyring-25.7.0-py3-none-any.whl
+ - pypi: https://files.pythonhosted.org/packages/94/54/e7d793b573f298e1c9013b8c4dade17d481164aa517d1d7148619c2cedbf/markdown_it_py-4.0.0-py3-none-any.whl
+ - pypi: https://files.pythonhosted.org/packages/b3/38/89ba8ad64ae25be8de66a6d463314cf1eb366222074cfda9ee839c56a4b4/mdurl-0.1.2-py3-none-any.whl
+ - pypi: https://files.pythonhosted.org/packages/a4/8e/469e5a4a2f5855992e425f3cb33804cc07bf18d48f2db061aec61ce50270/more_itertools-10.8.0-py3-none-any.whl
+ - pypi: https://files.pythonhosted.org/packages/4a/57/a97955bc95960cfb1f0517043d60a121f4ba93fde252d4d9ffd3c2a9eead/nh3-0.3.4-cp38-abi3-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl
+ - pypi: https://files.pythonhosted.org/packages/f4/7e/a72dd26f3b0f4f2bf1dd8923c85f7ceb43172af56d63c7383eb62b332364/pygments-2.20.0-py3-none-any.whl
+ - pypi: https://files.pythonhosted.org/packages/e1/67/921ec3024056483db83953ae8e48079ad62b92db7880013ca77632921dd0/readme_renderer-44.0-py3-none-any.whl
+ - pypi: https://files.pythonhosted.org/packages/3f/51/d4db610ef29373b879047326cbf6fa98b6c1969d6f6dc423279de2b1be2c/requests_toolbelt-1.0.0-py2.py3-none-any.whl
+ - pypi: https://files.pythonhosted.org/packages/ff/9a/9afaade874b2fa6c752c36f1548f718b5b83af81ed9b76628329dab81c1b/rfc3986-2.0.0-py2.py3-none-any.whl
+ - pypi: https://files.pythonhosted.org/packages/14/25/b208c5683343959b670dc001595f2f3737e051da617f66c31f7c4fa93abc/rich-14.3.3-py3-none-any.whl
+ - pypi: https://files.pythonhosted.org/packages/3a/7a/882d99539b19b1490cac5d77c67338d126e4122c8276bf640e411650c830/twine-6.2.0-py3-none-any.whl
+ osx-arm64:
+ - conda: https://conda.anaconda.org/conda-forge/noarch/archspec-0.2.5-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/backports.zstd-1.3.0-py314h680f03e_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/boltons-25.0.0-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-arm64/brotli-python-1.2.0-py314h3daef5d_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-arm64/bzip2-1.0.8-hd037594_9.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-arm64/c-ares-1.34.6-hc919400_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2026.2.25-hbd8a1cb_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/certifi-2026.2.25-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-arm64/cffi-2.0.0-py314h44086f9_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/cfgv-3.5.0-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/charset-normalizer-3.4.6-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-arm64/conda-26.1.1-py314h4dc9dd8_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/conda-libmamba-solver-25.11.0-pyhd8ed1ab_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/conda-package-handling-2.4.0-pyh7900ff3_2.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/conda-package-streaming-0.12.0-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-arm64/cpp-expected-1.3.1-h4f10f1e_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/distlib-0.4.0-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/distro-1.9.0-pyhd8ed1ab_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/filelock-3.25.2-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-arm64/fmt-12.1.0-h403dcb5_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-arm64/frozendict-2.4.7-py314h0612a62_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-arm64/gh-2.88.1-h01237fd_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/h2-4.3.0-pyhcf101f3_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/hpack-4.1.0-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/hyperframe-6.1.0-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-arm64/icu-78.3-hef89b57_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/identify-2.6.18-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/idna-3.11-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/importlib-metadata-8.8.0-pyhcf101f3_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/jsonpatch-1.33-pyhd8ed1ab_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/jsonpointer-3.1.1-pyhcf101f3_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-arm64/krb5-1.22.2-h385eeb1_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libarchive-3.8.6-gpl_h6fbacd7_100.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libcurl-8.19.0-hd5a2499_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libcxx-22.1.2-h55c6f16_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libedit-3.1.20250104-pl5321hafb1f1b_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libev-4.33-h93a5062_2.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libexpat-2.7.5-hf6b4638_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libffi-3.5.2-hcf2aa1b_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libiconv-1.18-h23cfdf5_2.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-arm64/liblzma-5.8.2-h8088a28_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libmamba-2.5.0-h7950639_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libmamba-spdlog-2.5.0-h85b9800_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libmambapy-2.5.0-py314hf8f60b7_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libmpdec-4.0.0-h84a0fba_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libnghttp2-1.68.1-h8f3e76b_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libsolv-0.7.36-h7d962ec_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libsqlite-3.52.0-h1ae2325_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libssh2-1.11.1-h1590b86_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libxml2-16-2.15.2-h5ef1a60_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libxml2-2.15.2-h8d039ee_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libzlib-1.3.2-h8088a28_2.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-arm64/lz4-c-1.10.0-h286801f_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-arm64/lzo-2.10-h925e9cb_1002.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-arm64/menuinst-2.4.2-py314h4dc9dd8_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-arm64/msgpack-python-1.1.2-py314h784bc60_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-arm64/ncurses-6.5-h5e97a16_3.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/nlohmann_json-abi-3.12.0-h0f90c79_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/nodeenv-1.10.0-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-arm64/openssl-3.6.1-hd24854e_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/packaging-26.0-pyhcf101f3_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/pixi-pycharm-0.0.10-unix_hf108a03_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/platformdirs-4.9.4-pyhcf101f3_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/pluggy-1.6.0-pyhf9edf01_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/pre-commit-4.5.1-pyha770c72_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/pybind11-abi-11-hc364b38_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-arm64/pycosat-0.6.6-py314hb84d1df_3.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/pycparser-2.22-pyh29332c3_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/pysocks-1.7.1-pyha55dd90_7.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-arm64/python-3.14.3-h4c637c5_101_cp314.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/python-discovery-1.2.1-pyhcf101f3_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/python_abi-3.14-8_cp314.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-arm64/pyyaml-6.0.3-py314h6e9b3f0_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-arm64/readline-8.3-h46df422_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-arm64/reproc-14.2.5.post0-h5505292_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-arm64/reproc-cpp-14.2.5.post0-h286801f_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/requests-2.33.1-pyhcf101f3_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-arm64/ruamel.yaml-0.18.17-py314ha14b1ff_2.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-arm64/ruamel.yaml.clib-0.2.15-py314ha14b1ff_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/setuptools-82.0.1-pyh332efcf_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-arm64/simdjson-4.2.4-ha7d2532_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-arm64/spdlog-1.17.0-ha0f8610_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-arm64/taplo-0.10.0-h2b2570c_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-arm64/tk-8.6.13-h010d191_3.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/tqdm-4.67.3-pyh8f84b5b_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/truststore-0.10.4-pyhcf101f3_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/typing_extensions-4.15.0-pyhcf101f3_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/tzdata-2025c-hc9c84f9_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-arm64/ukkonen-1.1.0-py314h6cfcd04_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/urllib3-2.6.3-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/virtualenv-21.2.0-pyhcf101f3_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-arm64/yaml-0.2.5-h925e9cb_3.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-arm64/yaml-cpp-0.8.0-ha1acc90_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/zipp-3.23.0-pyhcf101f3_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-arm64/zstandard-0.25.0-py314h9d33bd4_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/osx-arm64/zstd-1.5.7-hbf9d68e_6.conda
+ - pypi: https://files.pythonhosted.org/packages/02/10/5da547df7a391dcde17f59520a231527b8571e6f46fc8efb02ccb370ab12/docutils-0.22.4-py3-none-any.whl
+ - pypi: https://files.pythonhosted.org/packages/42/77/de194443bf38daed9452139e960c632b0ef9f9a5dd9ce605fdf18ca9f1b1/id-1.6.1-py3-none-any.whl
+ - pypi: https://files.pythonhosted.org/packages/7f/66/b15ce62552d84bbfcec9a4873ab79d993a1dd4edb922cbfccae192bd5b5f/jaraco.classes-3.4.0-py3-none-any.whl
+ - pypi: https://files.pythonhosted.org/packages/f2/58/bc8954bda5fcda97bd7c19be11b85f91973d67a706ed4a3aec33e7de22db/jaraco_context-6.1.2-py3-none-any.whl
+ - pypi: https://files.pythonhosted.org/packages/fd/c4/813bb09f0985cb21e959f21f2464169eca882656849adf727ac7bb7e1767/jaraco_functools-4.4.0-py3-none-any.whl
+ - pypi: https://files.pythonhosted.org/packages/81/db/e655086b7f3a705df045bf0933bdd9c2f79bb3c97bfef1384598bb79a217/keyring-25.7.0-py3-none-any.whl
+ - pypi: https://files.pythonhosted.org/packages/94/54/e7d793b573f298e1c9013b8c4dade17d481164aa517d1d7148619c2cedbf/markdown_it_py-4.0.0-py3-none-any.whl
+ - pypi: https://files.pythonhosted.org/packages/b3/38/89ba8ad64ae25be8de66a6d463314cf1eb366222074cfda9ee839c56a4b4/mdurl-0.1.2-py3-none-any.whl
+ - pypi: https://files.pythonhosted.org/packages/a4/8e/469e5a4a2f5855992e425f3cb33804cc07bf18d48f2db061aec61ce50270/more_itertools-10.8.0-py3-none-any.whl
+ - pypi: https://files.pythonhosted.org/packages/4a/57/a97955bc95960cfb1f0517043d60a121f4ba93fde252d4d9ffd3c2a9eead/nh3-0.3.4-cp38-abi3-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl
+ - pypi: https://files.pythonhosted.org/packages/f4/7e/a72dd26f3b0f4f2bf1dd8923c85f7ceb43172af56d63c7383eb62b332364/pygments-2.20.0-py3-none-any.whl
+ - pypi: https://files.pythonhosted.org/packages/e1/67/921ec3024056483db83953ae8e48079ad62b92db7880013ca77632921dd0/readme_renderer-44.0-py3-none-any.whl
+ - pypi: https://files.pythonhosted.org/packages/3f/51/d4db610ef29373b879047326cbf6fa98b6c1969d6f6dc423279de2b1be2c/requests_toolbelt-1.0.0-py2.py3-none-any.whl
+ - pypi: https://files.pythonhosted.org/packages/ff/9a/9afaade874b2fa6c752c36f1548f718b5b83af81ed9b76628329dab81c1b/rfc3986-2.0.0-py2.py3-none-any.whl
+ - pypi: https://files.pythonhosted.org/packages/14/25/b208c5683343959b670dc001595f2f3737e051da617f66c31f7c4fa93abc/rich-14.3.3-py3-none-any.whl
+ - pypi: https://files.pythonhosted.org/packages/3a/7a/882d99539b19b1490cac5d77c67338d126e4122c8276bf640e411650c830/twine-6.2.0-py3-none-any.whl
+ win-64:
+ - conda: https://conda.anaconda.org/conda-forge/noarch/archspec-0.2.5-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/backports.zstd-1.3.0-py314h680f03e_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/boltons-25.0.0-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/win-64/brotli-python-1.2.0-py314he701e3d_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/win-64/bzip2-1.0.8-h0ad9c76_9.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2026.2.25-h4c7d964_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/certifi-2026.2.25-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/win-64/cffi-2.0.0-py314h5a2d7ad_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/cfgv-3.5.0-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/charset-normalizer-3.4.6-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/colorama-0.4.6-pyhd8ed1ab_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/win-64/conda-26.1.1-py314h86ab7b2_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/conda-libmamba-solver-25.11.0-pyhd8ed1ab_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/conda-package-handling-2.4.0-pyh7900ff3_2.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/conda-package-streaming-0.12.0-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/win-64/cpp-expected-1.3.1-h477610d_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/distlib-0.4.0-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/distro-1.9.0-pyhd8ed1ab_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/filelock-3.25.2-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/win-64/fmt-12.1.0-h7f4e812_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/win-64/frozendict-2.4.7-py314h5a2d7ad_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/win-64/gh-2.88.1-h36e2d1d_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/h2-4.3.0-pyhcf101f3_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/hpack-4.1.0-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/hyperframe-6.1.0-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/identify-2.6.18-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/idna-3.11-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/importlib-metadata-8.8.0-pyhcf101f3_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/jsonpatch-1.33-pyhd8ed1ab_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/jsonpointer-3.1.1-pyhcf101f3_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/win-64/krb5-1.22.2-h0ea6238_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/win-64/libarchive-3.8.6-gpl_he24518a_100.conda
+ - conda: https://conda.anaconda.org/conda-forge/win-64/libcurl-8.19.0-h8206538_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/win-64/libexpat-2.7.5-hac47afa_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/win-64/libffi-3.5.2-h3d046cb_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/win-64/libiconv-1.18-hc1393d2_2.conda
+ - conda: https://conda.anaconda.org/conda-forge/win-64/liblzma-5.8.2-hfd05255_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/win-64/libmamba-2.5.0-h06825f5_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/win-64/libmamba-spdlog-2.5.0-h9ae1bf1_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/win-64/libmambapy-2.5.0-py314h532c739_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/win-64/libmpdec-4.0.0-hfd05255_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/win-64/libsolv-0.7.36-h8883371_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/win-64/libsqlite-3.52.0-hf5d6505_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/win-64/libssh2-1.11.1-h9aa295b_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/win-64/libxml2-16-2.15.2-h692994f_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/win-64/libxml2-2.15.2-h5d26750_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/win-64/libzlib-1.3.2-hfd05255_2.conda
+ - conda: https://conda.anaconda.org/conda-forge/win-64/lz4-c-1.10.0-h2466b09_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/win-64/lzo-2.10-h6a83c73_1002.conda
+ - conda: https://conda.anaconda.org/conda-forge/win-64/menuinst-2.4.2-py314h13fbf68_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/win-64/msgpack-python-1.1.2-py314h909e829_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/nlohmann_json-abi-3.12.0-h0f90c79_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/nodeenv-1.10.0-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/win-64/openssl-3.6.1-hf411b9b_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/packaging-26.0-pyhcf101f3_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/pixi-pycharm-0.0.10-win_hba80fca_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/platformdirs-4.9.4-pyhcf101f3_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/pluggy-1.6.0-pyhf9edf01_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/pre-commit-4.5.1-pyha770c72_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/pybind11-abi-11-hc364b38_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/win-64/pycosat-0.6.6-py314h5a2d7ad_3.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/pycparser-2.22-pyh29332c3_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/pysocks-1.7.1-pyh09c184e_7.conda
+ - conda: https://conda.anaconda.org/conda-forge/win-64/python-3.14.3-h4b44e0e_101_cp314.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/python-discovery-1.2.1-pyhcf101f3_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/python_abi-3.14-8_cp314.conda
+ - conda: https://conda.anaconda.org/conda-forge/win-64/pyyaml-6.0.3-py314h2359020_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/win-64/reproc-14.2.5.post0-h2466b09_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/win-64/reproc-cpp-14.2.5.post0-he0c23c2_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/requests-2.33.1-pyhcf101f3_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/win-64/ruamel.yaml-0.18.17-py314hc5dbbe4_2.conda
+ - conda: https://conda.anaconda.org/conda-forge/win-64/ruamel.yaml.clib-0.2.15-py314hc5dbbe4_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/setuptools-82.0.1-pyh332efcf_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/win-64/simdjson-4.2.4-h49e36cd_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/win-64/spdlog-1.17.0-h9f585f1_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/win-64/taplo-0.10.0-h63977a8_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/win-64/tk-8.6.13-h6ed50ae_3.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/tqdm-4.67.3-pyha7b4d00_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/truststore-0.10.4-pyhcf101f3_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/typing_extensions-4.15.0-pyhcf101f3_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/tzdata-2025c-hc9c84f9_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/win-64/ucrt-10.0.26100.0-h57928b3_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/win-64/ukkonen-1.1.0-py314h909e829_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/urllib3-2.6.3-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/win-64/vc-14.3-h41ae7f8_34.conda
+ - conda: https://conda.anaconda.org/conda-forge/win-64/vc14_runtime-14.44.35208-h818238b_34.conda
+ - conda: https://conda.anaconda.org/conda-forge/win-64/vcomp14-14.44.35208-h818238b_34.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/virtualenv-21.2.0-pyhcf101f3_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/win_inet_pton-1.1.0-pyh7428d3b_8.conda
+ - conda: https://conda.anaconda.org/conda-forge/win-64/yaml-0.2.5-h6a83c73_3.conda
+ - conda: https://conda.anaconda.org/conda-forge/win-64/yaml-cpp-0.8.0-he0c23c2_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/zipp-3.23.0-pyhcf101f3_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/win-64/zstandard-0.25.0-py314hc5dbbe4_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/win-64/zstd-1.5.7-h534d264_6.conda
+ - pypi: https://files.pythonhosted.org/packages/02/10/5da547df7a391dcde17f59520a231527b8571e6f46fc8efb02ccb370ab12/docutils-0.22.4-py3-none-any.whl
+ - pypi: https://files.pythonhosted.org/packages/42/77/de194443bf38daed9452139e960c632b0ef9f9a5dd9ce605fdf18ca9f1b1/id-1.6.1-py3-none-any.whl
+ - pypi: https://files.pythonhosted.org/packages/7f/66/b15ce62552d84bbfcec9a4873ab79d993a1dd4edb922cbfccae192bd5b5f/jaraco.classes-3.4.0-py3-none-any.whl
+ - pypi: https://files.pythonhosted.org/packages/f2/58/bc8954bda5fcda97bd7c19be11b85f91973d67a706ed4a3aec33e7de22db/jaraco_context-6.1.2-py3-none-any.whl
+ - pypi: https://files.pythonhosted.org/packages/fd/c4/813bb09f0985cb21e959f21f2464169eca882656849adf727ac7bb7e1767/jaraco_functools-4.4.0-py3-none-any.whl
+ - pypi: https://files.pythonhosted.org/packages/81/db/e655086b7f3a705df045bf0933bdd9c2f79bb3c97bfef1384598bb79a217/keyring-25.7.0-py3-none-any.whl
+ - pypi: https://files.pythonhosted.org/packages/94/54/e7d793b573f298e1c9013b8c4dade17d481164aa517d1d7148619c2cedbf/markdown_it_py-4.0.0-py3-none-any.whl
+ - pypi: https://files.pythonhosted.org/packages/b3/38/89ba8ad64ae25be8de66a6d463314cf1eb366222074cfda9ee839c56a4b4/mdurl-0.1.2-py3-none-any.whl
+ - pypi: https://files.pythonhosted.org/packages/a4/8e/469e5a4a2f5855992e425f3cb33804cc07bf18d48f2db061aec61ce50270/more_itertools-10.8.0-py3-none-any.whl
+ - pypi: https://files.pythonhosted.org/packages/73/4f/af8e9071d7464575a7316831938237ffc9d92d27f163dbdd964b1309cd9b/nh3-0.3.4-cp38-abi3-win_amd64.whl
+ - pypi: https://files.pythonhosted.org/packages/f4/7e/a72dd26f3b0f4f2bf1dd8923c85f7ceb43172af56d63c7383eb62b332364/pygments-2.20.0-py3-none-any.whl
+ - pypi: https://files.pythonhosted.org/packages/de/3d/8161f7711c017e01ac9f008dfddd9410dff3674334c233bde66e7ba65bbf/pywin32_ctypes-0.2.3-py3-none-any.whl
+ - pypi: https://files.pythonhosted.org/packages/e1/67/921ec3024056483db83953ae8e48079ad62b92db7880013ca77632921dd0/readme_renderer-44.0-py3-none-any.whl
+ - pypi: https://files.pythonhosted.org/packages/3f/51/d4db610ef29373b879047326cbf6fa98b6c1969d6f6dc423279de2b1be2c/requests_toolbelt-1.0.0-py2.py3-none-any.whl
+ - pypi: https://files.pythonhosted.org/packages/ff/9a/9afaade874b2fa6c752c36f1548f718b5b83af81ed9b76628329dab81c1b/rfc3986-2.0.0-py2.py3-none-any.whl
+ - pypi: https://files.pythonhosted.org/packages/14/25/b208c5683343959b670dc001595f2f3737e051da617f66c31f7c4fa93abc/rich-14.3.3-py3-none-any.whl
+ - pypi: https://files.pythonhosted.org/packages/3a/7a/882d99539b19b1490cac5d77c67338d126e4122c8276bf640e411650c830/twine-6.2.0-py3-none-any.whl
+ windows-py310:
+ channels:
+ - url: https://conda.anaconda.org/conda-forge/
+ indexes:
+ - https://pypi.org/simple
+ options:
+ pypi-prerelease-mode: if-necessary-or-explicit
+ packages:
+ win-64:
+ - conda: https://conda.anaconda.org/conda-forge/noarch/archspec-0.2.5-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/win-64/backports.zstd-1.3.0-py310h458dff3_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/boltons-25.0.0-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/win-64/brotli-python-1.2.0-py310hfff998d_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/win-64/bzip2-1.0.8-h0ad9c76_9.conda
+ - conda: https://conda.anaconda.org/conda-forge/win-64/c-compiler-1.11.0-h528c1b4_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2026.2.25-h4c7d964_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/certifi-2026.2.25-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/win-64/cffi-2.0.0-py310h29418f3_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/cfgv-3.5.0-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/charset-normalizer-3.4.5-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/win-64/cmake-3.31.8-hdcbee5b_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/colorama-0.4.6-pyhd8ed1ab_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/win-64/conda-26.1.1-py310h5588dad_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/conda-libmamba-solver-25.11.0-pyhd8ed1ab_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/conda-package-handling-2.4.0-pyh7900ff3_2.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/conda-package-streaming-0.12.0-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/win-64/cpp-expected-1.3.1-h477610d_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/win-64/cxx-compiler-1.11.0-h1c1089f_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/distlib-0.4.0-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/distro-1.9.0-pyhd8ed1ab_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/win-64/doxygen-1.13.2-hbf3f430_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/exceptiongroup-1.3.1-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/filelock-3.25.2-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/win-64/fmt-12.1.0-h7f4e812_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/win-64/frozendict-2.4.7-py310h29418f3_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/win-64/git-2.53.0-h57928b3_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/h2-4.3.0-pyhcf101f3_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/hpack-4.1.0-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/hyperframe-6.1.0-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/identify-2.6.18-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/idna-3.11-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/importlib-metadata-8.7.0-pyhe01879c_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/importlib-resources-6.5.2-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/importlib_resources-6.5.2-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/jsonpatch-1.33-pyhd8ed1ab_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/jsonpointer-3.0.0-pyhcf101f3_3.conda
+ - conda: https://conda.anaconda.org/conda-forge/win-64/krb5-1.22.2-h0ea6238_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/win-64/libarchive-3.8.6-gpl_he24518a_100.conda
+ - conda: https://conda.anaconda.org/conda-forge/win-64/libblas-3.11.0-5_hf2e6a31_mkl.conda
+ - conda: https://conda.anaconda.org/conda-forge/win-64/libcblas-3.11.0-5_h2a3cdd5_mkl.conda
+ - conda: https://conda.anaconda.org/conda-forge/win-64/libcurl-8.19.0-h8206538_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/win-64/libexpat-2.7.4-hac47afa_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/win-64/libffi-3.5.2-h3d046cb_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/win-64/libhwloc-2.12.2-default_h4379cf1_1000.conda
+ - conda: https://conda.anaconda.org/conda-forge/win-64/libiconv-1.18-hc1393d2_2.conda
+ - conda: https://conda.anaconda.org/conda-forge/win-64/liblapack-3.11.0-5_hf9ab0e9_mkl.conda
+ - conda: https://conda.anaconda.org/conda-forge/win-64/liblzma-5.8.2-hfd05255_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/win-64/libmamba-2.5.0-h06825f5_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/win-64/libmamba-spdlog-2.5.0-h9ae1bf1_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/win-64/libmambapy-2.5.0-py310h1916185_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/win-64/libsolv-0.7.35-h8883371_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/win-64/libsqlite-3.52.0-hf5d6505_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/win-64/libssh2-1.11.1-h9aa295b_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/win-64/libuv-1.51.0-hfd05255_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/win-64/libwinpthread-12.0.0.r4.gg4f2fc60ca-h57928b3_10.conda
+ - conda: https://conda.anaconda.org/conda-forge/win-64/libxml2-16-2.15.2-h692994f_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/win-64/libxml2-2.15.2-h5d26750_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/win-64/libzlib-1.3.1-h2466b09_2.conda
+ - conda: https://conda.anaconda.org/conda-forge/win-64/llvm-openmp-22.1.0-h4fa8253_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/win-64/lz4-c-1.10.0-h2466b09_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/win-64/lzo-2.10-h6a83c73_1002.conda
+ - conda: https://conda.anaconda.org/conda-forge/win-64/menuinst-2.4.2-py310h73ae2b4_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/win-64/mkl-2025.3.0-hac47afa_455.conda
+ - conda: https://conda.anaconda.org/conda-forge/win-64/msgpack-python-1.1.2-py310he9f1925_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/win-64/ninja-1.13.2-h477610d_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/nlohmann_json-abi-3.12.0-h0f90c79_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/nodeenv-1.10.0-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/win-64/numpy-2.2.6-py310h4987827_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/win-64/openssl-3.6.1-hf411b9b_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/packaging-25.0-pyh29332c3_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/pathspec-1.0.4-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/pip-26.0.1-pyh8b19718_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/pixi-pycharm-0.0.10-win_hba80fca_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/pkginfo-1.12.1.2-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/platformdirs-4.9.4-pyhcf101f3_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/pluggy-1.6.0-pyhf9edf01_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/pre-commit-4.5.1-pyha770c72_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/pybind11-abi-11-hc364b38_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/win-64/pycosat-0.6.6-py310h29418f3_3.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/pycparser-2.22-pyh29332c3_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/pyproject-metadata-0.11.0-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/pysocks-1.7.1-pyh09c184e_7.conda
+ - conda: https://conda.anaconda.org/conda-forge/win-64/python-3.10.20-hc20f281_0_cpython.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/python-discovery-1.2.1-pyhcf101f3_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/python_abi-3.10-8_cp310.conda
+ - conda: https://conda.anaconda.org/conda-forge/win-64/pyyaml-6.0.3-py310hdb0e946_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/win-64/reproc-14.2.5.post0-h2466b09_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/win-64/reproc-cpp-14.2.5.post0-he0c23c2_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/requests-2.32.5-pyhcf101f3_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/win-64/ruamel.yaml-0.18.17-py310h1637853_2.conda
+ - conda: https://conda.anaconda.org/conda-forge/win-64/ruamel.yaml.clib-0.2.15-py310h1637853_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/scikit-build-core-0.11.6-pyh7e86bf3_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/setuptools-82.0.1-pyh332efcf_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/setuptools-scm-9.2.2-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/setuptools_scm-9.2.2-hd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/win-64/simdjson-4.2.4-h49e36cd_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/win-64/spdlog-1.17.0-h9f585f1_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/win-64/taplo-0.10.0-h63977a8_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/win-64/tbb-2022.3.0-h3155e25_2.conda
+ - conda: https://conda.anaconda.org/conda-forge/win-64/tk-8.6.13-h6ed50ae_3.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/tomli-2.4.0-pyhcf101f3_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/tqdm-4.67.3-pyha7b4d00_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/truststore-0.10.4-pyhcf101f3_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/typing-extensions-4.15.0-h396c80c_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/typing_extensions-4.15.0-pyhcf101f3_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/tzdata-2025c-hc9c84f9_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/win-64/ucrt-10.0.26100.0-h57928b3_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/win-64/ukkonen-1.1.0-py310he9f1925_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/urllib3-2.6.3-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/win-64/vc-14.3-h41ae7f8_34.conda
+ - conda: https://conda.anaconda.org/conda-forge/win-64/vc14_runtime-14.44.35208-h818238b_34.conda
+ - conda: https://conda.anaconda.org/conda-forge/win-64/vcomp14-14.44.35208-h818238b_34.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/virtualenv-21.2.0-pyhcf101f3_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/win-64/vs2022_win-64-19.44.35207-ha74f236_34.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/vswhere-3.1.7-h40126e0_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/wheel-0.46.3-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/win_inet_pton-1.1.0-pyh7428d3b_8.conda
+ - conda: https://conda.anaconda.org/conda-forge/win-64/yaml-0.2.5-h6a83c73_3.conda
+ - conda: https://conda.anaconda.org/conda-forge/win-64/yaml-cpp-0.8.0-he0c23c2_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/zipp-3.23.0-pyhcf101f3_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/win-64/zstandard-0.25.0-py310h1637853_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/win-64/zstd-1.5.7-h534d264_6.conda
+ - pypi: https://files.pythonhosted.org/packages/c5/0d/84a4380f930db0010168e0aa7b7a8fed9ba1835a8fbb1472bc6d0201d529/build-1.4.0-py3-none-any.whl
+ - pypi: https://files.pythonhosted.org/packages/89/74/bf0ea7b89e114af19a38c2341746fd1f17f1de23fa8d8019cbcd39719c5f/delvewheel-1.12.0-py3-none-any.whl
+ - pypi: https://files.pythonhosted.org/packages/54/16/12b82f791c7f50ddec566873d5bdd245baa1491bac11d15ffb98aecc8f8b/pefile-2024.8.26-py3-none-any.whl
+ - pypi: https://files.pythonhosted.org/packages/bd/24/12818598c362d7f300f18e74db45963dbcb85150324092410c8b49405e42/pyproject_hooks-1.2.0-py3-none-any.whl
+ windows-py311:
+ channels:
+ - url: https://conda.anaconda.org/conda-forge/
+ indexes:
+ - https://pypi.org/simple
+ options:
+ pypi-prerelease-mode: if-necessary-or-explicit
+ packages:
+ win-64:
+ - conda: https://conda.anaconda.org/conda-forge/noarch/archspec-0.2.5-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/win-64/backports.zstd-1.3.0-py311h71c1bcc_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/boltons-25.0.0-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/win-64/brotli-python-1.2.0-py311hc5da9e4_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/win-64/bzip2-1.0.8-h0ad9c76_9.conda
+ - conda: https://conda.anaconda.org/conda-forge/win-64/c-compiler-1.11.0-h528c1b4_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2026.2.25-h4c7d964_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/certifi-2026.2.25-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/win-64/cffi-2.0.0-py311h3485c13_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/cfgv-3.5.0-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/charset-normalizer-3.4.5-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/win-64/cmake-3.31.8-hdcbee5b_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/colorama-0.4.6-pyhd8ed1ab_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/win-64/conda-26.1.1-py311h1ea47a8_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/conda-libmamba-solver-25.11.0-pyhd8ed1ab_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/conda-package-handling-2.4.0-pyh7900ff3_2.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/conda-package-streaming-0.12.0-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/win-64/cpp-expected-1.3.1-h477610d_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/win-64/cxx-compiler-1.11.0-h1c1089f_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/distlib-0.4.0-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/distro-1.9.0-pyhd8ed1ab_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/win-64/doxygen-1.13.2-hbf3f430_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/exceptiongroup-1.3.1-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/filelock-3.25.2-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/win-64/fmt-12.1.0-h7f4e812_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/win-64/frozendict-2.4.7-py311h3485c13_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/win-64/git-2.53.0-h57928b3_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/h2-4.3.0-pyhcf101f3_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/hpack-4.1.0-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/hyperframe-6.1.0-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/identify-2.6.18-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/idna-3.11-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/importlib-metadata-8.7.0-pyhe01879c_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/importlib-resources-6.5.2-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/importlib_resources-6.5.2-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/jsonpatch-1.33-pyhd8ed1ab_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/jsonpointer-3.0.0-pyhcf101f3_3.conda
+ - conda: https://conda.anaconda.org/conda-forge/win-64/krb5-1.22.2-h0ea6238_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/win-64/libarchive-3.8.6-gpl_he24518a_100.conda
+ - conda: https://conda.anaconda.org/conda-forge/win-64/libblas-3.11.0-5_hf2e6a31_mkl.conda
+ - conda: https://conda.anaconda.org/conda-forge/win-64/libcblas-3.11.0-5_h2a3cdd5_mkl.conda
+ - conda: https://conda.anaconda.org/conda-forge/win-64/libcurl-8.19.0-h8206538_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/win-64/libexpat-2.7.4-hac47afa_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/win-64/libffi-3.5.2-h3d046cb_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/win-64/libhwloc-2.12.2-default_h4379cf1_1000.conda
+ - conda: https://conda.anaconda.org/conda-forge/win-64/libiconv-1.18-hc1393d2_2.conda
+ - conda: https://conda.anaconda.org/conda-forge/win-64/liblapack-3.11.0-5_hf9ab0e9_mkl.conda
+ - conda: https://conda.anaconda.org/conda-forge/win-64/liblzma-5.8.2-hfd05255_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/win-64/libmamba-2.5.0-h06825f5_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/win-64/libmamba-spdlog-2.5.0-h9ae1bf1_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/win-64/libmambapy-2.5.0-py311hb0041a4_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/win-64/libsolv-0.7.35-h8883371_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/win-64/libsqlite-3.52.0-hf5d6505_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/win-64/libssh2-1.11.1-h9aa295b_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/win-64/libuv-1.51.0-hfd05255_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/win-64/libwinpthread-12.0.0.r4.gg4f2fc60ca-h57928b3_10.conda
+ - conda: https://conda.anaconda.org/conda-forge/win-64/libxml2-16-2.15.2-h692994f_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/win-64/libxml2-2.15.2-h5d26750_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/win-64/libzlib-1.3.1-h2466b09_2.conda
+ - conda: https://conda.anaconda.org/conda-forge/win-64/llvm-openmp-22.1.0-h4fa8253_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/win-64/lz4-c-1.10.0-h2466b09_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/win-64/lzo-2.10-h6a83c73_1002.conda
+ - conda: https://conda.anaconda.org/conda-forge/win-64/menuinst-2.4.2-py311h3e6a449_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/win-64/mkl-2025.3.0-hac47afa_455.conda
+ - conda: https://conda.anaconda.org/conda-forge/win-64/msgpack-python-1.1.2-py311h3fd045d_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/win-64/ninja-1.13.2-h477610d_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/nlohmann_json-abi-3.12.0-h0f90c79_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/nodeenv-1.10.0-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/win-64/numpy-2.4.2-py311h80b3fa1_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/win-64/openssl-3.6.1-hf411b9b_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/packaging-25.0-pyh29332c3_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/pathspec-1.0.4-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/pip-26.0.1-pyh8b19718_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/pixi-pycharm-0.0.10-win_hba80fca_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/pkginfo-1.12.1.2-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/platformdirs-4.9.4-pyhcf101f3_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/pluggy-1.6.0-pyhf9edf01_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/pre-commit-4.5.1-pyha770c72_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/pybind11-abi-11-hc364b38_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/win-64/pycosat-0.6.6-py311h3485c13_3.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/pycparser-2.22-pyh29332c3_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/pyproject-metadata-0.11.0-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/pysocks-1.7.1-pyh09c184e_7.conda
+ - conda: https://conda.anaconda.org/conda-forge/win-64/python-3.11.15-h0159041_0_cpython.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/python-discovery-1.2.1-pyhcf101f3_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/python_abi-3.11-8_cp311.conda
+ - conda: https://conda.anaconda.org/conda-forge/win-64/pyyaml-6.0.3-py311h3f79411_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/win-64/reproc-14.2.5.post0-h2466b09_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/win-64/reproc-cpp-14.2.5.post0-he0c23c2_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/requests-2.32.5-pyhcf101f3_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/win-64/ruamel.yaml-0.18.17-py311hf893f09_2.conda
+ - conda: https://conda.anaconda.org/conda-forge/win-64/ruamel.yaml.clib-0.2.15-py311hf893f09_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/scikit-build-core-0.11.6-pyh7e86bf3_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/setuptools-82.0.1-pyh332efcf_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/setuptools-scm-9.2.2-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/setuptools_scm-9.2.2-hd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/win-64/simdjson-4.2.4-h49e36cd_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/win-64/spdlog-1.17.0-h9f585f1_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/win-64/taplo-0.10.0-h63977a8_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/win-64/tbb-2022.3.0-h3155e25_2.conda
+ - conda: https://conda.anaconda.org/conda-forge/win-64/tk-8.6.13-h6ed50ae_3.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/tomli-2.4.0-pyhcf101f3_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/tqdm-4.67.3-pyha7b4d00_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/truststore-0.10.4-pyhcf101f3_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/typing-extensions-4.15.0-h396c80c_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/typing_extensions-4.15.0-pyhcf101f3_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/tzdata-2025c-hc9c84f9_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/win-64/ucrt-10.0.26100.0-h57928b3_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/win-64/ukkonen-1.1.0-py311h3fd045d_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/urllib3-2.6.3-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/win-64/vc-14.3-h41ae7f8_34.conda
+ - conda: https://conda.anaconda.org/conda-forge/win-64/vc14_runtime-14.44.35208-h818238b_34.conda
+ - conda: https://conda.anaconda.org/conda-forge/win-64/vcomp14-14.44.35208-h818238b_34.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/virtualenv-21.2.0-pyhcf101f3_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/win-64/vs2022_win-64-19.44.35207-ha74f236_34.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/vswhere-3.1.7-h40126e0_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/wheel-0.46.3-pyhd8ed1ab_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/win_inet_pton-1.1.0-pyh7428d3b_8.conda
+ - conda: https://conda.anaconda.org/conda-forge/win-64/yaml-0.2.5-h6a83c73_3.conda
+ - conda: https://conda.anaconda.org/conda-forge/win-64/yaml-cpp-0.8.0-he0c23c2_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/zipp-3.23.0-pyhcf101f3_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/win-64/zstandard-0.25.0-py311hf893f09_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/win-64/zstd-1.5.7-h534d264_6.conda
+ - pypi: https://files.pythonhosted.org/packages/c5/0d/84a4380f930db0010168e0aa7b7a8fed9ba1835a8fbb1472bc6d0201d529/build-1.4.0-py3-none-any.whl
+ - pypi: https://files.pythonhosted.org/packages/89/74/bf0ea7b89e114af19a38c2341746fd1f17f1de23fa8d8019cbcd39719c5f/delvewheel-1.12.0-py3-none-any.whl
+ - pypi: https://files.pythonhosted.org/packages/54/16/12b82f791c7f50ddec566873d5bdd245baa1491bac11d15ffb98aecc8f8b/pefile-2024.8.26-py3-none-any.whl
+ - pypi: https://files.pythonhosted.org/packages/bd/24/12818598c362d7f300f18e74db45963dbcb85150324092410c8b49405e42/pyproject_hooks-1.2.0-py3-none-any.whl
+packages:
+- conda: https://conda.anaconda.org/conda-forge/linux-64/_openmp_mutex-4.5-20_gnu.conda
+ build_number: 20
+ sha256: 1dd3fffd892081df9726d7eb7e0dea6198962ba775bd88842135a4ddb4deb3c9
+ md5: a9f577daf3de00bca7c3c76c0ecbd1de
+ depends:
+ - __glibc >=2.17,<3.0.a0
+ - libgomp >=7.5.0
+ constrains:
+ - openmp_impl <0.0a0
+ license: BSD-3-Clause
+ license_family: BSD
+ purls: []
+ size: 28948
+ timestamp: 1770939786096
+- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/_openmp_mutex-4.5-20_gnu.conda
+ build_number: 20
+ sha256: a2527b1d81792a0ccd2c05850960df119c2b6d8f5fdec97f2db7d25dc23b1068
+ md5: 468fd3bb9e1f671d36c2cbc677e56f1d
+ depends:
+ - libgomp >=7.5.0
+ constrains:
+ - openmp_impl <0.0a0
+ license: BSD-3-Clause
+ license_family: BSD
+ purls: []
+ size: 28926
+ timestamp: 1770939656741
+- conda: https://conda.anaconda.org/conda-forge/osx-64/_openmp_mutex-4.5-7_kmp_llvm.conda
+ build_number: 7
+ sha256: 30006902a9274de8abdad5a9f02ef7c8bb3d69a503486af0c1faee30b023e5b7
+ md5: eaac87c21aff3ed21ad9656697bb8326
+ depends:
+ - llvm-openmp >=9.0.1
+ license: BSD-3-Clause
+ license_family: BSD
+ purls: []
+ size: 8328
+ timestamp: 1764092562779
+- conda: https://conda.anaconda.org/conda-forge/osx-arm64/_openmp_mutex-4.5-7_kmp_llvm.conda
+ build_number: 7
+ sha256: 7acaa2e0782cad032bdaf756b536874346ac1375745fb250e9bdd6a48a7ab3cd
+ md5: a44032f282e7d2acdeb1c240308052dd
+ depends:
+ - llvm-openmp >=9.0.1
+ license: BSD-3-Clause
+ license_family: BSD
+ purls: []
+ size: 8325
+ timestamp: 1764092507920
+- pypi: https://files.pythonhosted.org/packages/a9/ba/000a1996d4308bc65120167c21241a3b205464a2e0b58deda26ae8ac21d1/altgraph-0.17.5-py2.py3-none-any.whl
+ name: altgraph
+ version: 0.17.5
+ sha256: f3a22400bce1b0c701683820ac4f3b159cd301acab067c51c653e06961600597
+- conda: https://conda.anaconda.org/conda-forge/noarch/archspec-0.2.5-pyhd8ed1ab_0.conda
+ sha256: eb68e1ce9e9a148168a4b1e257a8feebffdb0664b557bb526a1e4853f2d2fc00
+ md5: 845b38297fca2f2d18a29748e2ece7fa
+ depends:
+ - python >=3.9
+ license: MIT OR Apache-2.0
+ purls:
+ - pkg:pypi/archspec?source=hash-mapping
+ size: 50894
+ timestamp: 1737352715041
+- conda: https://conda.anaconda.org/conda-forge/noarch/auditwheel-6.6.0-pyhd8ed1ab_0.conda
+ sha256: edba8fbf77c737ee991ae56f3cf5297f23c82eeb6033d6cfb4b78c2545cc66f0
+ md5: b0eb66b5e5335471c1148199a26ceb79
+ depends:
+ - packaging >=20.9
+ - pyelftools >=0.24
+ - python >=3.10
+ license: MIT
+ license_family: MIT
+ purls:
+ - pkg:pypi/auditwheel?source=hash-mapping
+ size: 51557
+ timestamp: 1767633848607
+- conda: https://conda.anaconda.org/conda-forge/linux-64/backports.zstd-1.3.0-py310h69bd2ac_0.conda
+ sha256: 6660be15a45175c98f750b8bbc3fd07e0da36043624b376de49769bd14a0a16f
+ md5: 276a3ddf300498921601822e3b407088
+ depends:
+ - python
+ - __glibc >=2.17,<3.0.a0
+ - libgcc >=14
+ - zstd >=1.5.7,<1.6.0a0
+ - python_abi 3.10.* *_cp310
+ license: BSD-3-Clause AND MIT AND EPL-2.0
+ purls:
+ - pkg:pypi/backports-zstd?source=hash-mapping
+ size: 191286
+ timestamp: 1767044984395
+- conda: https://conda.anaconda.org/conda-forge/linux-64/backports.zstd-1.3.0-py311h6b1f9c4_0.conda
+ sha256: 246e50ec7fc222875c6ecfa3feab77f5661dc43e26397bc01d9e0310e3cd48a0
+ md5: adda5ef2a74c9bdb338ff8a51192898a
+ depends:
+ - python
+ - __glibc >=2.17,<3.0.a0
+ - libgcc >=14
+ - python_abi 3.11.* *_cp311
+ - zstd >=1.5.7,<1.6.0a0
+ license: BSD-3-Clause AND MIT AND EPL-2.0
+ purls:
+ - pkg:pypi/backports-zstd?source=hash-mapping
+ size: 244920
+ timestamp: 1767044984647
+- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/backports.zstd-1.3.0-py310hfa1aa29_0.conda
+ sha256: 92708591d7219370df1b63a96f68be0a2bc6422b8c5c35757b27751ab658ac44
+ md5: e6c4c73503900c04b9e8d273fc5db976
+ depends:
+ - python
+ - python 3.10.* *_cpython
+ - libgcc >=14
+ - python_abi 3.10.* *_cp310
+ - zstd >=1.5.7,<1.6.0a0
+ license: BSD-3-Clause AND MIT AND EPL-2.0
+ purls:
+ - pkg:pypi/backports-zstd?source=hash-mapping
+ size: 196369
+ timestamp: 1767044996002
+- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/backports.zstd-1.3.0-py311h6ce31b0_0.conda
+ sha256: b11baef215becac7d657289bc4171640be7ec6ff5068d3f9fb8a2b0e06242852
+ md5: 219e216268cad83c58f10435ce2001fb
+ depends:
+ - python
+ - python 3.11.* *_cpython
+ - libgcc >=14
+ - zstd >=1.5.7,<1.6.0a0
+ - python_abi 3.11.* *_cp311
+ license: BSD-3-Clause AND MIT AND EPL-2.0
+ purls:
+ - pkg:pypi/backports-zstd?source=hash-mapping
+ size: 250129
+ timestamp: 1767044999147
+- conda: https://conda.anaconda.org/conda-forge/noarch/backports.zstd-1.3.0-py314h680f03e_0.conda
+ noarch: generic
+ sha256: c31ab719d256bc6f89926131e88ecd0f0c5d003fe8481852c6424f4ec6c7eb29
+ md5: a2ac7763a9ac75055b68f325d3255265
+ depends:
+ - python >=3.14
+ license: BSD-3-Clause AND MIT AND EPL-2.0
+ purls: []
+ size: 7514
+ timestamp: 1767044983590
+- conda: https://conda.anaconda.org/conda-forge/win-64/backports.zstd-1.3.0-py310h458dff3_0.conda
+ sha256: ceb8b49b9bf0246b606089ce95e5afe0c4fd39ada3c8c381a3d03fd9beafba88
+ md5: 9f9e5cd3aa06ea10681a65355f5dca09
+ depends:
+ - python
+ - vc >=14.3,<15
+ - vc14_runtime >=14.44.35208
+ - ucrt >=10.0.20348.0
+ - python_abi 3.10.* *_cp310
+ - zstd >=1.5.7,<1.6.0a0
+ license: BSD-3-Clause AND MIT AND EPL-2.0
+ purls:
+ - pkg:pypi/backports-zstd?source=hash-mapping
+ size: 190164
+ timestamp: 1767045016166
+- conda: https://conda.anaconda.org/conda-forge/win-64/backports.zstd-1.3.0-py311h71c1bcc_0.conda
+ sha256: 5a30429e009b93c6dffe539cf0e3d220ef8d36ea42d36ca5c26b603cb3319c71
+ md5: 49eb28c4f92e8a7440e3da6d8e8b5e58
+ depends:
+ - python
+ - vc >=14.3,<15
+ - vc14_runtime >=14.44.35208
+ - ucrt >=10.0.20348.0
+ - zstd >=1.5.7,<1.6.0a0
+ - python_abi 3.11.* *_cp311
+ license: BSD-3-Clause AND MIT AND EPL-2.0
+ purls:
+ - pkg:pypi/backports-zstd?source=hash-mapping
+ size: 243289
+ timestamp: 1767045012846
+- conda: https://conda.anaconda.org/conda-forge/linux-64/binutils-2.45.1-default_h4852527_101.conda
+ sha256: 2851d34944b056d028543f0440fb631aeeff204151ea09589d8d9c13882395de
+ md5: 9902aeb08445c03fb31e01beeb173988
+ depends:
+ - binutils_impl_linux-64 >=2.45.1,<2.45.2.0a0
+ license: GPL-3.0-only
+ license_family: GPL
+ purls: []
+ size: 35128
+ timestamp: 1770267175160
+- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/binutils-2.45.1-default_hf1166c9_101.conda
+ sha256: 7113440420c6f31742c2b29d7590900362007a0bb0d31f9bc5c9a1379d9ab702
+ md5: 77f58300ab7d95ce79f9c2c13ad72d5c
+ depends:
+ - binutils_impl_linux-aarch64 >=2.45.1,<2.45.2.0a0
+ license: GPL-3.0-only
+ license_family: GPL
+ purls: []
+ size: 35322
+ timestamp: 1770267247190
+- conda: https://conda.anaconda.org/conda-forge/linux-64/binutils_impl_linux-64-2.45.1-default_hfdba357_101.conda
+ sha256: 74341b26a2b9475dc14ba3cf12432fcd10a23af285101883e720216d81d44676
+ md5: 83aa53cb3f5fc849851a84d777a60551
+ depends:
+ - ld_impl_linux-64 2.45.1 default_hbd61a6d_101
+ - sysroot_linux-64
+ - zstd >=1.5.7,<1.6.0a0
+ license: GPL-3.0-only
+ license_family: GPL
+ purls: []
+ size: 3744895
+ timestamp: 1770267152681
+- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/binutils_impl_linux-aarch64-2.45.1-default_h5f4c503_101.conda
+ sha256: e90ab42a5225dc1eaa6e4e7201cd7b8ed52dad6ec46814be7e5a4039433ae85c
+ md5: df6e1dc38cbe5642350fa09d4a1d546b
+ depends:
+ - ld_impl_linux-aarch64 2.45.1 default_h1979696_101
+ - sysroot_linux-aarch64
+ - zstd >=1.5.7,<1.6.0a0
+ license: GPL-3.0-only
+ license_family: GPL
+ purls: []
+ size: 4741684
+ timestamp: 1770267224406
+- conda: https://conda.anaconda.org/conda-forge/linux-64/binutils_linux-64-2.45.1-default_h4852527_101.conda
+ sha256: 4826f97d33cbe54459970a1e84500dbe0cccf8326aaf370e707372ae20ec5a47
+ md5: dec96579f9a7035a59492bf6ee613b53
+ depends:
+ - binutils_impl_linux-64 2.45.1 default_hfdba357_101
+ license: GPL-3.0-only
+ license_family: GPL
+ purls: []
+ size: 36060
+ timestamp: 1770267177798
+- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/binutils_linux-aarch64-2.45.1-default_hf1166c9_101.conda
+ sha256: 4ed3cf8af327b1c8b7e71433c98eb0154027e07b726136e81235276e9025489a
+ md5: 99924e610d9960dc3d8b865614787cec
+ depends:
+ - binutils_impl_linux-aarch64 2.45.1 default_h5f4c503_101
+ license: GPL-3.0-only
+ license_family: GPL
+ purls: []
+ size: 36223
+ timestamp: 1770267249899
+- conda: https://conda.anaconda.org/conda-forge/noarch/boltons-25.0.0-pyhd8ed1ab_0.conda
+ sha256: ea5f4c876eff2ed469551b57f1cc889a3c01128bf3e2e10b1fea11c3ef39eac2
+ md5: c7eb87af73750d6fd97eff8bbee8cb9c
+ depends:
+ - python >=3.9
+ license: BSD-3-Clause
+ license_family: BSD
+ purls:
+ - pkg:pypi/boltons?source=hash-mapping
+ size: 302296
+ timestamp: 1749686302834
+- conda: https://conda.anaconda.org/conda-forge/linux-64/brotli-python-1.2.0-py310hba01987_1.conda
+ sha256: f036fe554d902549f86689a9650a0996901d5c9242b0a1e3fbfe6dbccd2ae011
+ md5: 393fca4557fbd2c4d995dcb89f569048
+ depends:
+ - __glibc >=2.17,<3.0.a0
+ - libgcc >=14
+ - libstdcxx >=14
+ - python >=3.10,<3.11.0a0
+ - python_abi 3.10.* *_cp310
+ constrains:
+ - libbrotlicommon 1.2.0 hb03c661_1
+ license: MIT
+ license_family: MIT
+ purls:
+ - pkg:pypi/brotli?source=hash-mapping
+ size: 367099
+ timestamp: 1764017439384
+- conda: https://conda.anaconda.org/conda-forge/linux-64/brotli-python-1.2.0-py311h66f275b_1.conda
+ sha256: c36eb061d9ead85f97644cfb740d485dba9b8823357f35c17851078e95e975c1
+ md5: 86daecb8e4ed1042d5dc6efbe0152590
+ depends:
+ - __glibc >=2.17,<3.0.a0
+ - libgcc >=14
+ - libstdcxx >=14
+ - python >=3.11,<3.12.0a0
+ - python_abi 3.11.* *_cp311
+ constrains:
+ - libbrotlicommon 1.2.0 hb03c661_1
+ license: MIT
+ license_family: MIT
+ purls:
+ - pkg:pypi/brotli?source=hash-mapping
+ size: 367573
+ timestamp: 1764017405384
+- conda: https://conda.anaconda.org/conda-forge/linux-64/brotli-python-1.2.0-py314h3de4e8d_1.conda
+ sha256: 3ad3500bff54a781c29f16ce1b288b36606e2189d0b0ef2f67036554f47f12b0
+ md5: 8910d2c46f7e7b519129f486e0fe927a
+ depends:
+ - __glibc >=2.17,<3.0.a0
+ - libgcc >=14
+ - libstdcxx >=14
+ - python >=3.14,<3.15.0a0
+ - python_abi 3.14.* *_cp314
+ constrains:
+ - libbrotlicommon 1.2.0 hb03c661_1
+ license: MIT
+ license_family: MIT
+ purls:
+ - pkg:pypi/brotli?source=hash-mapping
+ size: 367376
+ timestamp: 1764017265553
+- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/brotli-python-1.2.0-py310hbe54bbb_1.conda
+ sha256: febea9d5c157f0a78dc0ffde32fe37b1f19eae812784f6e5505d471bf60d6f43
+ md5: 49a57b1956565528e382d8c9af4854c7
+ depends:
+ - libgcc >=14
+ - libstdcxx >=14
+ - python >=3.10,<3.11.0a0
+ - python >=3.10,<3.11.0a0 *_cpython
+ - python_abi 3.10.* *_cp310
+ constrains:
+ - libbrotlicommon 1.2.0 he30d5cf_1
+ license: MIT
+ license_family: MIT
+ purls:
+ - pkg:pypi/brotli?source=hash-mapping
+ size: 372450
+ timestamp: 1764017428950
+- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/brotli-python-1.2.0-py311h14a79a7_1.conda
+ sha256: bf73f124e8dd683c5f414b9bea077246fcdec3f6c530bd83234b5eb329b52423
+ md5: 292e7c014bfab5c77a2ff9c92728bb50
+ depends:
+ - libgcc >=14
+ - libstdcxx >=14
+ - python >=3.11,<3.12.0a0
+ - python >=3.11,<3.12.0a0 *_cpython
+ - python_abi 3.11.* *_cp311
+ constrains:
+ - libbrotlicommon 1.2.0 he30d5cf_1
+ license: MIT
+ license_family: MIT
+ purls:
+ - pkg:pypi/brotli?source=hash-mapping
+ size: 373346
+ timestamp: 1764017600174
+- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/brotli-python-1.2.0-py314h352cb57_1.conda
+ sha256: 5a5b0cdcd7ed89c6a8fb830924967f6314a2b71944bc1ebc2c105781ba97aa75
+ md5: a1b5c571a0923a205d663d8678df4792
+ depends:
+ - libgcc >=14
+ - libstdcxx >=14
+ - python >=3.14,<3.15.0a0
+ - python >=3.14,<3.15.0a0 *_cp314
+ - python_abi 3.14.* *_cp314
+ constrains:
+ - libbrotlicommon 1.2.0 he30d5cf_1
+ license: MIT
+ license_family: MIT
+ purls:
+ - pkg:pypi/brotli?source=hash-mapping
+ size: 373193
+ timestamp: 1764017486851
+- conda: https://conda.anaconda.org/conda-forge/osx-64/brotli-python-1.1.0-py310h9e9d8ca_1.conda
+ sha256: 57d66ca3e072b889c94cfaf56eb7e1794d3b1b3179bd475a4edef50a03359354
+ md5: 2362e323293e7699cf1e621d502f86d6
+ depends:
+ - libcxx >=15.0.7
+ - python >=3.10,<3.11.0a0
+ - python_abi 3.10.* *_cp310
+ constrains:
+ - libbrotlicommon 1.1.0 h0dc2134_1
+ license: MIT
+ license_family: MIT
+ purls:
+ - pkg:pypi/brotli?source=hash-mapping
+ size: 367037
+ timestamp: 1695990378635
+- conda: https://conda.anaconda.org/conda-forge/osx-64/brotli-python-1.1.0-py311hdf8f085_1.conda
+ sha256: 0f5e0a7de58006f349220365e32db521a1fe494c37ee455e5ecf05b8fe567dcc
+ md5: 546fdccabb90492fbaf2da4ffb78f352
+ depends:
+ - libcxx >=15.0.7
+ - python >=3.11,<3.12.0a0
+ - python_abi 3.11.* *_cp311
+ constrains:
+ - libbrotlicommon 1.1.0 h0dc2134_1
+ license: MIT
+ license_family: MIT
+ purls:
+ - pkg:pypi/brotli?source=hash-mapping
+ size: 366864
+ timestamp: 1695990449997
+- conda: https://conda.anaconda.org/conda-forge/osx-64/brotli-python-1.2.0-py314h3262eb8_1.conda
+ sha256: 2e34922abda4ac5726c547887161327b97c3bbd39f1204a5db162526b8b04300
+ md5: 389d75a294091e0d7fa5a6fc683c4d50
+ depends:
+ - __osx >=10.13
+ - libcxx >=19
+ - python >=3.14,<3.15.0a0
+ - python_abi 3.14.* *_cp314
+ constrains:
+ - libbrotlicommon 1.2.0 h8616949_1
+ license: MIT
+ license_family: MIT
+ purls:
+ - pkg:pypi/brotli?source=hash-mapping
+ size: 390153
+ timestamp: 1764017784596
+- conda: https://conda.anaconda.org/conda-forge/osx-arm64/brotli-python-1.1.0-py310h1253130_1.conda
+ sha256: dab21e18c0275bfd93a09b751096998485677ed17c2e2d08298bc5b43c10bee1
+ md5: 26fab7f65a80fff9f402ec3b7860b88a
+ depends:
+ - libcxx >=15.0.7
+ - python >=3.10,<3.11.0a0
+ - python >=3.10,<3.11.0a0 *_cpython
+ - python_abi 3.10.* *_cp310
+ constrains:
+ - libbrotlicommon 1.1.0 hb547adb_1
+ license: MIT
+ license_family: MIT
+ purls:
+ - pkg:pypi/brotli?source=hash-mapping
+ size: 344275
+ timestamp: 1695990848681
+- conda: https://conda.anaconda.org/conda-forge/osx-arm64/brotli-python-1.1.0-py311ha891d26_1.conda
+ sha256: 2d78c79ccf2c17236c52ef217a4c34b762eb7908a6903d94439f787aac1c8f4b
+ md5: 5e802b015e33447d1283d599d21f052b
+ depends:
+ - libcxx >=15.0.7
+ - python >=3.11,<3.12.0a0
+ - python >=3.11,<3.12.0a0 *_cpython
+ - python_abi 3.11.* *_cp311
+ constrains:
+ - libbrotlicommon 1.1.0 hb547adb_1
+ license: MIT
+ license_family: MIT
+ purls:
+ - pkg:pypi/brotli?source=hash-mapping
+ size: 343332
+ timestamp: 1695991223439
+- conda: https://conda.anaconda.org/conda-forge/osx-arm64/brotli-python-1.2.0-py314h3daef5d_1.conda
+ sha256: 5c2e471fd262fcc3c5a9d5ea4dae5917b885e0e9b02763dbd0f0d9635ed4cb99
+ md5: f9501812fe7c66b6548c7fcaa1c1f252
+ depends:
+ - __osx >=11.0
+ - libcxx >=19
+ - python >=3.14,<3.15.0a0
+ - python >=3.14,<3.15.0a0 *_cp314
+ - python_abi 3.14.* *_cp314
+ constrains:
+ - libbrotlicommon 1.2.0 hc919400_1
+ license: MIT
+ license_family: MIT
+ purls:
+ - pkg:pypi/brotli?source=hash-mapping
+ size: 359854
+ timestamp: 1764018178608
+- conda: https://conda.anaconda.org/conda-forge/win-64/brotli-python-1.2.0-py310hfff998d_1.conda
+ sha256: fd250a4f92c2176f23dd4e07de1faf76741dabcc8fa00b182748db4d9578ff7e
+ md5: 0caf12fa6690b7f64883b2239853dda0
+ depends:
+ - python >=3.10,<3.11.0a0
+ - python_abi 3.10.* *_cp310
+ - ucrt >=10.0.20348.0
+ - vc >=14.3,<15
+ - vc14_runtime >=14.44.35208
+ constrains:
+ - libbrotlicommon 1.2.0 hfd05255_1
+ license: MIT
+ license_family: MIT
+ purls:
+ - pkg:pypi/brotli?source=hash-mapping
+ size: 335476
+ timestamp: 1764018212429
+- conda: https://conda.anaconda.org/conda-forge/win-64/brotli-python-1.2.0-py311hc5da9e4_1.conda
+ sha256: 1803c838946d79ef6485ae8c7dafc93e28722c5999b059a34118ef758387a4c9
+ md5: b0c459f98ac5ea504a9d9df6242f7ee1
+ depends:
+ - python >=3.11,<3.12.0a0
+ - python_abi 3.11.* *_cp311
+ - ucrt >=10.0.20348.0
+ - vc >=14.3,<15
+ - vc14_runtime >=14.44.35208
+ constrains:
+ - libbrotlicommon 1.2.0 hfd05255_1
+ license: MIT
+ license_family: MIT
+ purls:
+ - pkg:pypi/brotli?source=hash-mapping
+ size: 335333
+ timestamp: 1764018370925
+- conda: https://conda.anaconda.org/conda-forge/win-64/brotli-python-1.2.0-py314he701e3d_1.conda
+ sha256: 6854ee7675135c57c73a04849c29cbebc2fb6a3a3bfee1f308e64bf23074719b
+ md5: 1302b74b93c44791403cbeee6a0f62a3
+ depends:
+ - python >=3.14,<3.15.0a0
+ - python_abi 3.14.* *_cp314
+ - ucrt >=10.0.20348.0
+ - vc >=14.3,<15
+ - vc14_runtime >=14.44.35208
+ constrains:
+ - libbrotlicommon 1.2.0 hfd05255_1
+ license: MIT
+ license_family: MIT
+ purls:
+ - pkg:pypi/brotli?source=hash-mapping
+ size: 335782
+ timestamp: 1764018443683
+- pypi: https://files.pythonhosted.org/packages/c5/0d/84a4380f930db0010168e0aa7b7a8fed9ba1835a8fbb1472bc6d0201d529/build-1.4.0-py3-none-any.whl
+ name: build
+ version: 1.4.0
+ sha256: 6a07c1b8eb6f2b311b96fcbdbce5dab5fe637ffda0fd83c9cac622e927501596
+ requires_dist:
+ - packaging>=24.0
+ - pyproject-hooks
+ - colorama ; os_name == 'nt'
+ - importlib-metadata>=4.6 ; python_full_version < '3.10.2'
+ - tomli>=1.1.0 ; python_full_version < '3.11'
+ - uv>=0.1.18 ; extra == 'uv'
+ - virtualenv>=20.11 ; python_full_version < '3.10' and extra == 'virtualenv'
+ - virtualenv>=20.17 ; python_full_version >= '3.10' and python_full_version < '3.14' and extra == 'virtualenv'
+ - virtualenv>=20.31 ; python_full_version >= '3.14' and extra == 'virtualenv'
+ requires_python: '>=3.9'
+- conda: https://conda.anaconda.org/conda-forge/linux-64/bzip2-1.0.8-hda65f42_9.conda
+ sha256: 0b75d45f0bba3e95dc693336fa51f40ea28c980131fec438afb7ce6118ed05f6
+ md5: d2ffd7602c02f2b316fd921d39876885
+ depends:
+ - __glibc >=2.17,<3.0.a0
+ - libgcc >=14
+ license: bzip2-1.0.6
+ license_family: BSD
+ purls: []
+ size: 260182
+ timestamp: 1771350215188
+- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/bzip2-1.0.8-h4777abc_9.conda
+ sha256: b3495077889dde6bb370938e7db82be545c73e8589696ad0843a32221520ad4c
+ md5: 840d8fc0d7b3209be93080bc20e07f2d
+ depends:
+ - libgcc >=14
+ license: bzip2-1.0.6
+ license_family: BSD
+ purls: []
+ size: 192412
+ timestamp: 1771350241232
+- conda: https://conda.anaconda.org/conda-forge/osx-64/bzip2-1.0.8-h10d778d_5.conda
+ sha256: 61fb2b488928a54d9472113e1280b468a309561caa54f33825a3593da390b242
+ md5: 6097a6ca9ada32699b5fc4312dd6ef18
+ license: bzip2-1.0.6
+ license_family: BSD
+ purls: []
+ size: 127885
+ timestamp: 1699280178474
+- conda: https://conda.anaconda.org/conda-forge/osx-64/bzip2-1.0.8-h500dc9f_9.conda
+ sha256: 9f242f13537ef1ce195f93f0cc162965d6cc79da578568d6d8e50f70dd025c42
+ md5: 4173ac3b19ec0a4f400b4f782910368b
+ depends:
+ - __osx >=10.13
+ license: bzip2-1.0.6
+ license_family: BSD
+ purls: []
+ size: 133427
+ timestamp: 1771350680709
+- conda: https://conda.anaconda.org/conda-forge/osx-arm64/bzip2-1.0.8-h93a5062_5.conda
+ sha256: bfa84296a638bea78a8bb29abc493ee95f2a0218775642474a840411b950fe5f
+ md5: 1bbc659ca658bfd49a481b5ef7a0f40f
+ license: bzip2-1.0.6
+ license_family: BSD
+ purls: []
+ size: 122325
+ timestamp: 1699280294368
+- conda: https://conda.anaconda.org/conda-forge/osx-arm64/bzip2-1.0.8-hd037594_9.conda
+ sha256: 540fe54be35fac0c17feefbdc3e29725cce05d7367ffedfaaa1bdda234b019df
+ md5: 620b85a3f45526a8bc4d23fd78fc22f0
+ depends:
+ - __osx >=11.0
+ license: bzip2-1.0.6
+ license_family: BSD
+ purls: []
+ size: 124834
+ timestamp: 1771350416561
+- conda: https://conda.anaconda.org/conda-forge/win-64/bzip2-1.0.8-h0ad9c76_9.conda
+ sha256: 76dfb71df5e8d1c4eded2dbb5ba15bb8fb2e2b0fe42d94145d5eed4c75c35902
+ md5: 4cb8e6b48f67de0b018719cdf1136306
+ depends:
+ - ucrt >=10.0.20348.0
+ - vc >=14.3,<15
+ - vc14_runtime >=14.44.35208
+ license: bzip2-1.0.6
+ license_family: BSD
+ purls: []
+ size: 56115
+ timestamp: 1771350256444
+- conda: https://conda.anaconda.org/conda-forge/linux-64/c-ares-1.34.6-hb03c661_0.conda
+ sha256: cc9accf72fa028d31c2a038460787751127317dcfa991f8d1f1babf216bb454e
+ md5: 920bb03579f15389b9e512095ad995b7
+ depends:
+ - __glibc >=2.17,<3.0.a0
+ - libgcc >=14
+ license: MIT
+ license_family: MIT
+ purls: []
+ size: 207882
+ timestamp: 1765214722852
+- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/c-ares-1.34.6-he30d5cf_0.conda
+ sha256: 7ec8a68efe479e2e298558cbc2e79d29430d5c7508254268818c0ae19b206519
+ md5: 1dfbec0d08f112103405756181304c16
+ depends:
+ - libgcc >=14
+ license: MIT
+ license_family: MIT
+ purls: []
+ size: 217215
+ timestamp: 1765214743735
+- conda: https://conda.anaconda.org/conda-forge/osx-64/c-ares-1.28.1-h10d778d_0.conda
+ sha256: fccd7ad7e3dfa6b19352705b33eb738c4c55f79f398e106e6cf03bab9415595a
+ md5: d5eb7992227254c0e9a0ce71151f0079
+ license: MIT
+ license_family: MIT
+ purls: []
+ size: 152607
+ timestamp: 1711819681694
+- conda: https://conda.anaconda.org/conda-forge/osx-64/c-ares-1.34.6-hb5e19a0_0.conda
+ sha256: 2f5bc0292d595399df0d168355b4e9820affc8036792d6984bd751fdda2bcaea
+ md5: fc9a153c57c9f070bebaa7eef30a8f17
+ depends:
+ - __osx >=10.13
+ license: MIT
+ license_family: MIT
+ purls: []
+ size: 186122
+ timestamp: 1765215100384
+- conda: https://conda.anaconda.org/conda-forge/osx-arm64/c-ares-1.28.1-h93a5062_0.conda
+ sha256: 2fc553d7a75e912efbdd6b82cd7916cc9cb2773e6cd873b77e02d631dd7be698
+ md5: 04f776a6139f7eafc2f38668570eb7db
+ license: MIT
+ license_family: MIT
+ purls: []
+ size: 150488
+ timestamp: 1711819630164
+- conda: https://conda.anaconda.org/conda-forge/osx-arm64/c-ares-1.34.6-hc919400_0.conda
+ sha256: 2995f2aed4e53725e5efbc28199b46bf311c3cab2648fc4f10c2227d6d5fa196
+ md5: bcb3cba70cf1eec964a03b4ba7775f01
+ depends:
+ - __osx >=11.0
+ license: MIT
+ license_family: MIT
+ purls: []
+ size: 180327
+ timestamp: 1765215064054
+- conda: https://conda.anaconda.org/conda-forge/linux-64/c-compiler-1.11.0-h4d9bdce_0.conda
+ sha256: 8e7a40f16400d7839c82581410aa05c1f8324a693c9d50079f8c50dc9fb241f0
+ md5: abd85120de1187b0d1ec305c2173c71b
+ depends:
+ - binutils
+ - gcc
+ - gcc_linux-64 14.*
+ license: BSD-3-Clause
+ license_family: BSD
+ purls: []
+ size: 6693
+ timestamp: 1753098721814
+- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/c-compiler-1.11.0-hdceaead_0.conda
+ sha256: a16c5078619d60e54f75336ed2bbb4ee0fb6f711de02dd364983748beda31e04
+ md5: 89bc32110bba0dc160bb69427e196dc4
+ depends:
+ - binutils
+ - gcc
+ - gcc_linux-aarch64 14.*
+ license: BSD-3-Clause
+ license_family: BSD
+ purls: []
+ size: 6721
+ timestamp: 1753098688332
+- conda: https://conda.anaconda.org/conda-forge/osx-64/c-compiler-1.10.0-h09a7c41_0.conda
+ sha256: 6a3f6b72bf5ad154630f79bd600f6ccf0f5c6a4be5297e4831d63016f4220e62
+ md5: 7b7c12e4774b83c18612c78073d12adc
+ depends:
+ - cctools >=949.0.1
+ - clang_osx-64 18.*
+ - ld64 >=530
+ - llvm-openmp
+ license: BSD-3-Clause
+ license_family: BSD
+ purls: []
+ size: 6773
+ timestamp: 1751115657381
+- conda: https://conda.anaconda.org/conda-forge/osx-arm64/c-compiler-1.10.0-hdf49b6b_0.conda
+ sha256: efc71f2ae5901bea633c67468b3aa774b6bcf46c9433e1ab5d640e3faf1680b9
+ md5: 7ca1bdcc45db75f54ed7b3ac969ed888
+ depends:
+ - cctools >=949.0.1
+ - clang_osx-arm64 18.*
+ - ld64 >=530
+ - llvm-openmp
+ license: BSD-3-Clause
+ license_family: BSD
+ purls: []
+ size: 6758
+ timestamp: 1751115540465
+- conda: https://conda.anaconda.org/conda-forge/win-64/c-compiler-1.11.0-h528c1b4_0.conda
+ sha256: 55e04bd4af61500cb8cae064386be57d18fbfdf676655ff1c97c7e5d146c6e34
+ md5: 6d994ff9ab924ba11c2c07e93afbe485
+ depends:
+ - vs2022_win-64
+ license: BSD-3-Clause
+ license_family: BSD
+ purls: []
+ size: 6938
+ timestamp: 1753098808371
+- conda: https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2026.2.25-h4c7d964_0.conda
+ sha256: 37950019c59b99585cee5d30dbc2cc9696ed4e11f5742606a4db1621ed8f94d6
+ md5: f001e6e220355b7f87403a4d0e5bf1ca
+ depends:
+ - __win
+ license: ISC
+ purls: []
+ size: 147734
+ timestamp: 1772006322223
+- conda: https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2026.2.25-hbd8a1cb_0.conda
+ sha256: 67cc7101b36421c5913a1687ef1b99f85b5d6868da3abbf6ec1a4181e79782fc
+ md5: 4492fd26db29495f0ba23f146cd5638d
+ depends:
+ - __unix
+ license: ISC
+ purls: []
+ size: 147413
+ timestamp: 1772006283803
+- conda: https://conda.anaconda.org/conda-forge/osx-64/cctools-986-hd3558d4_0.conda
+ sha256: 0879b6169986404d3e79e16676fe3de0cd962b522b7e8ef0fdad345400a28571
+ md5: 64cd107846d3407b8d75899078ffb2ab
+ depends:
+ - cctools_osx-64 986 h58a35ae_0
+ - ld64 711 h4e51db5_0
+ - libllvm18 >=18.1.1,<18.2.0a0
+ license: APSL-2.0
+ license_family: Other
+ purls: []
+ size: 21451
+ timestamp: 1710484533466
+- conda: https://conda.anaconda.org/conda-forge/osx-arm64/cctools-986-h4c9edd9_0.conda
+ sha256: bfbfc99da17828d007286f40af86b44315769cfbcc4beba62a8ae64264bd1193
+ md5: abcfabe468c14e506fceab2e85380b3b
+ depends:
+ - cctools_osx-arm64 986 hd11630f_0
+ - ld64 711 h4c6efb1_0
+ - libllvm18 >=18.1.1,<18.2.0a0
+ license: APSL-2.0
+ license_family: Other
+ purls: []
+ size: 21460
+ timestamp: 1710484691219
+- conda: https://conda.anaconda.org/conda-forge/osx-64/cctools_osx-64-986-h58a35ae_0.conda
+ sha256: a11f85e26b7189af87aa7e42b29a80f6bae73a92710cd5a40e278d6376a66ef5
+ md5: 1139258589f2d752a578ed5b2680eb60
+ depends:
+ - ld64_osx-64 >=711,<712.0a0
+ - libcxx
+ - libllvm18 >=18.1.1,<18.2.0a0
+ - libzlib >=1.2.13,<2.0.0a0
+ - sigtool
+ constrains:
+ - ld64 711.*
+ - cctools 986.*
+ - clang 18.1.*
+ license: APSL-2.0
+ license_family: Other
+ purls: []
+ size: 1104790
+ timestamp: 1710484461097
+- conda: https://conda.anaconda.org/conda-forge/osx-arm64/cctools_osx-arm64-986-hd11630f_0.conda
+ sha256: 4152323bbb78e2730fea9004333c9c51fb82a9ddd935f005280bf621849ec53d
+ md5: cce200c91b2d291c85e66098fe0d31c2
+ depends:
+ - ld64_osx-arm64 >=711,<712.0a0
+ - libcxx
+ - libllvm18 >=18.1.1,<18.2.0a0
+ - libzlib >=1.2.13,<2.0.0a0
+ - sigtool
+ constrains:
+ - cctools 986.*
+ - clang 18.1.*
+ - ld64 711.*
+ license: APSL-2.0
+ license_family: Other
+ purls: []
+ size: 1123368
+ timestamp: 1710484635601
+- conda: https://conda.anaconda.org/conda-forge/noarch/certifi-2026.2.25-pyhd8ed1ab_0.conda
+ sha256: a6b118fd1ed6099dc4fc03f9c492b88882a780fadaef4ed4f93dc70757713656
+ md5: 765c4d97e877cdbbb88ff33152b86125
+ depends:
+ - python >=3.10
+ license: ISC
+ purls:
+ - pkg:pypi/certifi?source=compressed-mapping
+ size: 151445
+ timestamp: 1772001170301
+- conda: https://conda.anaconda.org/conda-forge/linux-64/cffi-2.0.0-py310he7384ee_1.conda
+ sha256: bf76ead6d59b70f3e901476a73880ac92011be63b151972d135eec55bbbe6091
+ md5: 803e2d778b8dcccdc014127ec5001681
+ depends:
+ - __glibc >=2.17,<3.0.a0
+ - libffi >=3.5.2,<3.6.0a0
+ - libgcc >=14
+ - pycparser
+ - python >=3.10,<3.11.0a0
+ - python_abi 3.10.* *_cp310
+ license: MIT
+ license_family: MIT
+ purls:
+ - pkg:pypi/cffi?source=hash-mapping
+ size: 244766
+ timestamp: 1761203011221
+- conda: https://conda.anaconda.org/conda-forge/linux-64/cffi-2.0.0-py311h03d9500_1.conda
+ sha256: 3ad13377356c86d3a945ae30e9b8c8734300925ef81a3cb0a9db0d755afbe7bb
+ md5: 3912e4373de46adafd8f1e97e4bd166b
+ depends:
+ - __glibc >=2.17,<3.0.a0
+ - libffi >=3.5.2,<3.6.0a0
+ - libgcc >=14
+ - pycparser
+ - python >=3.11,<3.12.0a0
+ - python_abi 3.11.* *_cp311
+ license: MIT
+ license_family: MIT
+ purls:
+ - pkg:pypi/cffi?source=hash-mapping
+ size: 303338
+ timestamp: 1761202960110
+- conda: https://conda.anaconda.org/conda-forge/linux-64/cffi-2.0.0-py314h4a8dc5f_1.conda
+ sha256: c6339858a0aaf5d939e00d345c98b99e4558f285942b27232ac098ad17ac7f8e
+ md5: cf45f4278afd6f4e6d03eda0f435d527
+ depends:
+ - __glibc >=2.17,<3.0.a0
+ - libffi >=3.5.2,<3.6.0a0
+ - libgcc >=14
+ - pycparser
+ - python >=3.14,<3.15.0a0
+ - python_abi 3.14.* *_cp314
+ license: MIT
+ license_family: MIT
+ purls:
+ - pkg:pypi/cffi?source=hash-mapping
+ size: 300271
+ timestamp: 1761203085220
+- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/cffi-2.0.0-py310h0826a50_1.conda
+ sha256: 63458040026be843a189e319190a0622486017c92ef251d4dff7ec847f9a8418
+ md5: 152a5ba791642d8a81fe02d134ab3839
+ depends:
+ - libffi >=3.5.2,<3.6.0a0
+ - libgcc >=14
+ - pycparser
+ - python >=3.10,<3.11.0a0
+ - python_abi 3.10.* *_cp310
+ license: MIT
+ license_family: MIT
+ purls:
+ - pkg:pypi/cffi?source=hash-mapping
+ size: 261471
+ timestamp: 1761204343202
+- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/cffi-2.0.0-py311h460c349_1.conda
+ sha256: a0a49dc4fc0d177ba75d797660145d9405f956944af75d0c402d7733c6c71f60
+ md5: eef8f2527e60a82df85eba1cc4f9d5e1
+ depends:
+ - libffi >=3.5.2,<3.6.0a0
+ - libgcc >=14
+ - pycparser
+ - python >=3.11,<3.12.0a0
+ - python_abi 3.11.* *_cp311
+ license: MIT
+ license_family: MIT
+ purls:
+ - pkg:pypi/cffi?source=hash-mapping
+ size: 321642
+ timestamp: 1761203947874
+- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/cffi-2.0.0-py314h0bd77cf_1.conda
+ sha256: 728e55b32bf538e792010308fbe55d26d02903ddc295fbe101167903a123dd6f
+ md5: f333c475896dbc8b15efd8f7c61154c7
+ depends:
+ - libffi >=3.5.2,<3.6.0a0
+ - libgcc >=14
+ - pycparser
+ - python >=3.14,<3.15.0a0
+ - python_abi 3.14.* *_cp314
+ license: MIT
+ license_family: MIT
+ purls:
+ - pkg:pypi/cffi?source=hash-mapping
+ size: 318357
+ timestamp: 1761203973223
+- conda: https://conda.anaconda.org/conda-forge/osx-64/cffi-1.16.0-py310hdca579f_0.conda
+ sha256: 37802485964f1a3137ed6ab21ebc08fe9d35e7dc4da39f2b72a814644dd1ac15
+ md5: b9e6213f0eb91f40c009ce69139c1869
+ depends:
+ - libffi >=3.4,<4.0a0
+ - pycparser
+ - python >=3.10,<3.11.0a0
+ - python_abi 3.10.* *_cp310
+ license: MIT
+ license_family: MIT
+ purls:
+ - pkg:pypi/cffi?source=hash-mapping
+ size: 229407
+ timestamp: 1696002017767
+- conda: https://conda.anaconda.org/conda-forge/osx-64/cffi-1.16.0-py311hc0b63fd_0.conda
+ sha256: 1f13a5fa7f310fdbd27f5eddceb9e62cfb10012c58a58c923dd6f51fa979748a
+ md5: 15d07b82223cac96af629e5e747ba27a
+ depends:
+ - libffi >=3.4,<4.0a0
+ - pycparser
+ - python >=3.11,<3.12.0a0
+ - python_abi 3.11.* *_cp311
+ license: MIT
+ license_family: MIT
+ purls:
+ - pkg:pypi/cffi?source=hash-mapping
+ size: 289932
+ timestamp: 1696002096156
+- conda: https://conda.anaconda.org/conda-forge/osx-64/cffi-2.0.0-py314h8ca4d5a_1.conda
+ sha256: e2c58cc2451cc96db2a3c8ec34e18889878db1e95cc3e32c85e737e02a7916fb
+ md5: 71c2caaa13f50fe0ebad0f961aee8073
+ depends:
+ - __osx >=10.13
+ - libffi >=3.5.2,<3.6.0a0
+ - pycparser
+ - python >=3.14,<3.15.0a0
+ - python_abi 3.14.* *_cp314
+ license: MIT
+ license_family: MIT
+ purls:
+ - pkg:pypi/cffi?source=hash-mapping
+ size: 293633
+ timestamp: 1761203106369
+- conda: https://conda.anaconda.org/conda-forge/osx-arm64/cffi-1.16.0-py310hdcd7c05_0.conda
+ sha256: 4edab3f1f855554e10950efe064b75138943812af829a764f9b570d1a7189d15
+ md5: 8855823d908004e4d3b4fd4218795ad2
+ depends:
+ - libffi >=3.4,<4.0a0
+ - pycparser
+ - python >=3.10,<3.11.0a0
+ - python >=3.10,<3.11.0a0 *_cpython
+ - python_abi 3.10.* *_cp310
+ license: MIT
+ license_family: MIT
+ purls:
+ - pkg:pypi/cffi?source=hash-mapping
+ size: 232227
+ timestamp: 1696002085787
+- conda: https://conda.anaconda.org/conda-forge/osx-arm64/cffi-1.16.0-py311h4a08483_0.conda
+ sha256: 9430416328fe2a28e206e703de771817064c8613a79a6a21fe7107f6a783104c
+ md5: cbdde0484a47b40e6ce2a4e5aaeb48d7
+ depends:
+ - libffi >=3.4,<4.0a0
+ - pycparser
+ - python >=3.11,<3.12.0a0
+ - python >=3.11,<3.12.0a0 *_cpython
+ - python_abi 3.11.* *_cp311
+ license: MIT
+ license_family: MIT
+ purls:
+ - pkg:pypi/cffi?source=hash-mapping
+ size: 292511
+ timestamp: 1696002194472
+- conda: https://conda.anaconda.org/conda-forge/osx-arm64/cffi-2.0.0-py314h44086f9_1.conda
+ sha256: 5b5ee5de01eb4e4fd2576add5ec9edfc654fbaf9293e7b7ad2f893a67780aa98
+ md5: 10dd19e4c797b8f8bdb1ec1fbb6821d7
+ depends:
+ - __osx >=11.0
+ - libffi >=3.5.2,<3.6.0a0
+ - pycparser
+ - python >=3.14,<3.15.0a0
+ - python >=3.14,<3.15.0a0 *_cp314
+ - python_abi 3.14.* *_cp314
+ license: MIT
+ license_family: MIT
+ purls:
+ - pkg:pypi/cffi?source=hash-mapping
+ size: 292983
+ timestamp: 1761203354051
+- conda: https://conda.anaconda.org/conda-forge/win-64/cffi-2.0.0-py310h29418f3_1.conda
+ sha256: abd04b75ee9a04a2f00dc102b4dc126f393fde58536ca4eaf1a72bb7d60dadf4
+ md5: 269ba3d69bf6569296a29425a26400df
+ depends:
+ - pycparser
+ - python >=3.10,<3.11.0a0
+ - python_abi 3.10.* *_cp310
+ - ucrt >=10.0.20348.0
+ - vc >=14.3,<15
+ - vc14_runtime >=14.44.35208
+ license: MIT
+ license_family: MIT
+ purls:
+ - pkg:pypi/cffi?source=hash-mapping
+ size: 239862
+ timestamp: 1761203282977
+- conda: https://conda.anaconda.org/conda-forge/win-64/cffi-2.0.0-py311h3485c13_1.conda
+ sha256: c9caca6098e3d92b1a269159b759d757518f2c477fbbb5949cb9fee28807c1f1
+ md5: f02335db0282d5077df5bc84684f7ff9
+ depends:
+ - pycparser
+ - python >=3.11,<3.12.0a0
+ - python_abi 3.11.* *_cp311
+ - ucrt >=10.0.20348.0
+ - vc >=14.3,<15
+ - vc14_runtime >=14.44.35208
+ license: MIT
+ license_family: MIT
+ purls:
+ - pkg:pypi/cffi?source=hash-mapping
+ size: 297941
+ timestamp: 1761203850323
+- conda: https://conda.anaconda.org/conda-forge/win-64/cffi-2.0.0-py314h5a2d7ad_1.conda
+ sha256: 924f2f01fa7a62401145ef35ab6fc95f323b7418b2644a87fea0ea68048880ed
+ md5: c360170be1c9183654a240aadbedad94
+ depends:
+ - pycparser
+ - python >=3.14,<3.15.0a0
+ - python_abi 3.14.* *_cp314
+ - ucrt >=10.0.20348.0
+ - vc >=14.3,<15
+ - vc14_runtime >=14.44.35208
+ license: MIT
+ license_family: MIT
+ purls:
+ - pkg:pypi/cffi?source=hash-mapping
+ size: 294731
+ timestamp: 1761203441365
+- conda: https://conda.anaconda.org/conda-forge/noarch/cfgv-3.5.0-pyhd8ed1ab_0.conda
+ sha256: aa589352e61bb221351a79e5946d56916e3c595783994884accdb3b97fe9d449
+ md5: 381bd45fb7aa032691f3063aff47e3a1
+ depends:
+ - python >=3.10
+ license: MIT
+ license_family: MIT
+ purls:
+ - pkg:pypi/cfgv?source=hash-mapping
+ size: 13589
+ timestamp: 1763607964133
+- conda: https://conda.anaconda.org/conda-forge/noarch/charset-normalizer-3.4.5-pyhd8ed1ab_0.conda
+ sha256: 05ea76a016c77839b64f9f8ec581775f6c8a259044bd5b45a177e46ab4e7feac
+ md5: beb628209b2b354b98203066f90b3287
+ depends:
+ - python >=3.10
+ license: MIT
+ license_family: MIT
+ purls:
+ - pkg:pypi/charset-normalizer?source=compressed-mapping
+ size: 53210
+ timestamp: 1772816516728
+- conda: https://conda.anaconda.org/conda-forge/noarch/charset-normalizer-3.4.6-pyhd8ed1ab_0.conda
+ sha256: d86dfd428b2e3c364fa90e07437c8405d635aa4ef54b25ab51d9c712be4112a5
+ md5: 49ee13eb9b8f44d63879c69b8a40a74b
+ depends:
+ - python >=3.10
+ license: MIT
+ license_family: MIT
+ purls:
+ - pkg:pypi/charset-normalizer?source=compressed-mapping
+ size: 58510
+ timestamp: 1773660086450
+- conda: https://conda.anaconda.org/conda-forge/osx-64/clang-18.1.3-default_h7151d67_0.conda
+ sha256: 12fbd85852e6a55612d33e8beb4bfe19b6b9b64b44e97753f5c8a2a42decb64a
+ md5: 1160f27e680531f1ef4f32517238a7f5
+ depends:
+ - clang-18 18.1.3 default_h7151d67_0
+ license: Apache-2.0 WITH LLVM-exception
+ license_family: Apache
+ purls: []
+ size: 22898
+ timestamp: 1712569254288
+- conda: https://conda.anaconda.org/conda-forge/osx-arm64/clang-18.1.3-default_h4cf2255_0.conda
+ sha256: 613f4c4773f1dd274d2682a9170d52cb466f437a47ebcad2c2634c3b37aeb73f
+ md5: efbaa3d968b1dcacba9eb980d1ab66f4
+ depends:
+ - clang-18 18.1.3 default_he012953_0
+ license: Apache-2.0 WITH LLVM-exception
+ license_family: Apache
+ purls: []
+ size: 22913
+ timestamp: 1712569692457
+- conda: https://conda.anaconda.org/conda-forge/osx-64/clang-18-18.1.3-default_h7151d67_0.conda
+ sha256: 41a929a017ef2b1b3c5066ddde16c0e68b5fc15a0de49d61cdf414fc13d09336
+ md5: 76cf851fa13b7f48939befb147cc78eb
+ depends:
+ - libclang-cpp18.1 18.1.3 default_h7151d67_0
+ - libcxx >=16.0.6
+ - libllvm18 >=18.1.3,<18.2.0a0
+ constrains:
+ - clangxx 18.1.3
+ - llvm-tools 18.1.3
+ - clang-tools 18.1.3
+ - clangdev 18.1.3
+ license: Apache-2.0 WITH LLVM-exception
+ license_family: Apache
+ purls: []
+ size: 760437
+ timestamp: 1712569132861
+- conda: https://conda.anaconda.org/conda-forge/osx-arm64/clang-18-18.1.3-default_he012953_0.conda
+ sha256: edb5c1e2ffc7704b0e0bce0f5315eb1aba8fd9710e61bcbdeb40e340720123c6
+ md5: 931dd6124b399ae12172f235f5ace407
+ depends:
+ - libclang-cpp18.1 18.1.3 default_he012953_0
+ - libcxx >=16.0.6
+ - libllvm18 >=18.1.3,<18.2.0a0
+ constrains:
+ - clang-tools 18.1.3
+ - clangxx 18.1.3
+ - llvm-tools 18.1.3
+ - clangdev 18.1.3
+ license: Apache-2.0 WITH LLVM-exception
+ license_family: Apache
+ purls: []
+ size: 754206
+ timestamp: 1712569562918
+- conda: https://conda.anaconda.org/conda-forge/osx-64/clang_impl_osx-64-18.1.3-hdbcc6ac_11.conda
+ sha256: cfa641fb177fc1a75c5e2d9f941ad6576f5786a254d5af265e5b548ebaea29d0
+ md5: f895cb5eeb844bc8b2dd9147ec07896b
+ depends:
+ - cctools_osx-64
+ - clang 18.1.3.*
+ - compiler-rt 18.1.3.*
+ - ld64_osx-64
+ - llvm-tools 18.1.3.*
+ license: BSD-3-Clause
+ license_family: BSD
+ purls: []
+ size: 17413
+ timestamp: 1712621383914
+- conda: https://conda.anaconda.org/conda-forge/osx-arm64/clang_impl_osx-arm64-18.1.3-hda94301_11.conda
+ sha256: f00e3930fa341ad5fa87a90f297b385a949bf2ee100a3a2cc2a135629fde6d7e
+ md5: 90e54a957e833f7cd2412b6d2e1d84fa
+ depends:
+ - cctools_osx-arm64
+ - clang 18.1.3.*
+ - compiler-rt 18.1.3.*
+ - ld64_osx-arm64
+ - llvm-tools 18.1.3.*
+ license: BSD-3-Clause
+ license_family: BSD
+ purls: []
+ size: 17571
+ timestamp: 1712621386541
+- conda: https://conda.anaconda.org/conda-forge/osx-64/clang_osx-64-18.1.3-hb91bd55_11.conda
+ sha256: 94f9471f5b5b14a229cc44d65c01d383f79de179830b03045fc864f6489550f3
+ md5: b0acbcfd68b99fe852942eea93a0f36d
+ depends:
+ - clang_impl_osx-64 18.1.3 hdbcc6ac_11
+ license: BSD-3-Clause
+ license_family: BSD
+ purls: []
+ size: 20494
+ timestamp: 1712621391590
+- conda: https://conda.anaconda.org/conda-forge/osx-arm64/clang_osx-arm64-18.1.3-h54d7cd3_11.conda
+ sha256: 595cbec0f835ba16ad551315079193d16fc7f3a4e136aa1045ab9104cac79bf7
+ md5: 7bdafeb8d61d59551df2417995bc3d46
+ depends:
+ - clang_impl_osx-arm64 18.1.3 hda94301_11
+ license: BSD-3-Clause
+ license_family: BSD
+ purls: []
+ size: 20490
+ timestamp: 1712621394350
+- conda: https://conda.anaconda.org/conda-forge/osx-64/clangxx-18.1.3-default_h7151d67_0.conda
+ sha256: 53d34a151f47971f55425154423b470273fb2c51e1c0a4ddb261aaa6502a7d50
+ md5: 323c1678ff1cf1b8d05981eb2906f45e
+ depends:
+ - clang 18.1.3 default_h7151d67_0
+ license: Apache-2.0 WITH LLVM-exception
+ license_family: Apache
+ purls: []
+ size: 22972
+ timestamp: 1712569279378
+- conda: https://conda.anaconda.org/conda-forge/osx-arm64/clangxx-18.1.3-default_h4cf2255_0.conda
+ sha256: 1f9c1605d4f74b1d5df7d44676a5a6c53d542fc8c44d94fcc1d4d1977cede661
+ md5: fd98656c5b62774633c84c41f42bdd6d
+ depends:
+ - clang 18.1.3 default_h4cf2255_0
+ license: Apache-2.0 WITH LLVM-exception
+ license_family: Apache
+ purls: []
+ size: 22939
+ timestamp: 1712569715149
+- conda: https://conda.anaconda.org/conda-forge/osx-64/clangxx_impl_osx-64-18.1.3-h5bc21ce_11.conda
+ sha256: 89fe02a10de21dc553ff79296ef322536b692e50382e248c8625f07dba6176c2
+ md5: 1e203622262bd949727467d61e819184
+ depends:
+ - clang_osx-64 18.1.3 hb91bd55_11
+ - clangxx 18.1.3.*
+ - libcxx >=16
+ - libllvm18 >=18.1.3,<18.2.0a0
+ license: BSD-3-Clause
+ license_family: BSD
+ purls: []
+ size: 17496
+ timestamp: 1712621429065
+- conda: https://conda.anaconda.org/conda-forge/osx-arm64/clangxx_impl_osx-arm64-18.1.3-h1ba0cb9_11.conda
+ sha256: 91c6d2a6d9555110d6710d3766eb724dfdeed17b23a7965649523675d2251fce
+ md5: 5c29e4473f07af49ced6984531048fa4
+ depends:
+ - clang_osx-arm64 18.1.3 h54d7cd3_11
+ - clangxx 18.1.3.*
+ - libcxx >=16
+ - libllvm18 >=18.1.3,<18.2.0a0
+ license: BSD-3-Clause
+ license_family: BSD
+ purls: []
+ size: 17636
+ timestamp: 1712621421262
+- conda: https://conda.anaconda.org/conda-forge/osx-64/clangxx_osx-64-18.1.3-hb91bd55_11.conda
+ sha256: fa2acbc8c9575951a523e1f2dc16bd82d22386fbd312dbe05559bed2be94f306
+ md5: 5c514320afcbaef94ab371abd3995bfb
+ depends:
+ - clang_osx-64 18.1.3 hb91bd55_11
+ - clangxx_impl_osx-64 18.1.3 h5bc21ce_11
+ license: BSD-3-Clause
+ license_family: BSD
+ purls: []
+ size: 19255
+ timestamp: 1712621436405
+- conda: https://conda.anaconda.org/conda-forge/osx-arm64/clangxx_osx-arm64-18.1.3-h54d7cd3_11.conda
+ sha256: c92c008817c2e25409b1328e580798855d082b504b39d8f42b21791da215c9f6
+ md5: 3b5c8fe78441bc034aceadfa80dae7cc
+ depends:
+ - clang_osx-arm64 18.1.3 h54d7cd3_11
+ - clangxx_impl_osx-arm64 18.1.3 h1ba0cb9_11
+ license: BSD-3-Clause
+ license_family: BSD
+ purls: []
+ size: 19244
+ timestamp: 1712621431069
+- conda: https://conda.anaconda.org/conda-forge/linux-64/cmake-3.31.8-hc85cc9f_0.conda
+ sha256: 10660ed21b9d591f8306028bd36212467b94f23bc2f78faec76524f6ee592613
+ md5: 057e16a12847eea846ecf99710d3591b
+ depends:
+ - __glibc >=2.17,<3.0.a0
+ - bzip2 >=1.0.8,<2.0a0
+ - libcurl >=8.14.1,<9.0a0
+ - libexpat >=2.7.1,<3.0a0
+ - libgcc >=14
+ - liblzma >=5.8.1,<6.0a0
+ - libstdcxx >=14
+ - libuv >=1.51.0,<2.0a0
+ - libzlib >=1.3.1,<2.0a0
+ - ncurses >=6.5,<7.0a0
+ - rhash >=1.4.6,<2.0a0
+ - zstd >=1.5.7,<1.6.0a0
+ license: BSD-3-Clause
+ license_family: BSD
+ purls: []
+ size: 20991288
+ timestamp: 1757877168657
+- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/cmake-3.31.8-hc9d863e_0.conda
+ sha256: 91cbfd13132b7253a6ef001292f5cf59deac38d2cbc86d6c1ad6ebf344cd998c
+ md5: 855e698fd08794a573cd6104be8da4d0
+ depends:
+ - bzip2 >=1.0.8,<2.0a0
+ - libcurl >=8.14.1,<9.0a0
+ - libexpat >=2.7.1,<3.0a0
+ - libgcc >=14
+ - liblzma >=5.8.1,<6.0a0
+ - libstdcxx >=14
+ - libuv >=1.51.0,<2.0a0
+ - libzlib >=1.3.1,<2.0a0
+ - ncurses >=6.5,<7.0a0
+ - rhash >=1.4.6,<2.0a0
+ - zstd >=1.5.7,<1.6.0a0
+ license: BSD-3-Clause
+ license_family: BSD
+ purls: []
+ size: 20216587
+ timestamp: 1757877248575
+- conda: https://conda.anaconda.org/conda-forge/osx-64/cmake-3.27.6-hf40c264_0.conda
+ sha256: 9216698f88b82e99db950f8c372038931c54ea3e0b0b05e2a3ce03ec4b405df7
+ md5: 771da6a52aaf0f9d84114d0ed0d0299f
+ depends:
+ - bzip2 >=1.0.8,<2.0a0
+ - libcurl >=8.3.0,<9.0a0
+ - libcxx >=15.0.7
+ - libexpat >=2.5.0,<3.0a0
+ - libuv >=1.46.0,<2.0a0
+ - libzlib >=1.2.13,<2.0.0a0
+ - ncurses >=6.4,<7.0a0
+ - rhash >=1.4.4,<2.0a0
+ - xz >=5.2.6,<6.0a0
+ - zstd >=1.5.5,<1.6.0a0
+ license: BSD-3-Clause
+ license_family: BSD
+ purls: []
+ size: 16525734
+ timestamp: 1695270838345
+- conda: https://conda.anaconda.org/conda-forge/osx-arm64/cmake-3.27.6-h1c59155_0.conda
+ sha256: 31be31e358e6f6f8818d8f9c9086da4404f8c6fc89d71d55887bed11ce6d463e
+ md5: 3c0dd04401438fec44cd113247ba2852
+ depends:
+ - bzip2 >=1.0.8,<2.0a0
+ - libcurl >=8.3.0,<9.0a0
+ - libcxx >=15.0.7
+ - libexpat >=2.5.0,<3.0a0
+ - libuv >=1.46.0,<2.0a0
+ - libzlib >=1.2.13,<2.0.0a0
+ - ncurses >=6.4,<7.0a0
+ - rhash >=1.4.4,<2.0a0
+ - xz >=5.2.6,<6.0a0
+ - zstd >=1.5.5,<1.6.0a0
+ license: BSD-3-Clause
+ license_family: BSD
+ purls: []
+ size: 16007289
+ timestamp: 1695270816826
+- conda: https://conda.anaconda.org/conda-forge/win-64/cmake-3.31.8-hdcbee5b_0.conda
+ sha256: 074400a63931d8d571b2b2284bc5f105fd578c381847b05d5e3d0b03c3db8f69
+ md5: 96afa0e05c4a683b1c3de91b0259b235
+ depends:
+ - bzip2 >=1.0.8,<2.0a0
+ - libcurl >=8.14.1,<9.0a0
+ - libexpat >=2.7.1,<3.0a0
+ - liblzma >=5.8.1,<6.0a0
+ - libuv >=1.51.0,<2.0a0
+ - libzlib >=1.3.1,<2.0a0
+ - ucrt >=10.0.20348.0
+ - vc14_runtime >=14.44.35208
+ - zstd >=1.5.7,<1.6.0a0
+ license: BSD-3-Clause
+ license_family: BSD
+ purls: []
+ size: 14669008
+ timestamp: 1757878123930
+- conda: https://conda.anaconda.org/conda-forge/noarch/colorama-0.4.6-pyhd8ed1ab_1.conda
+ sha256: ab29d57dc70786c1269633ba3dff20288b81664d3ff8d21af995742e2bb03287
+ md5: 962b9857ee8e7018c22f2776ffa0b2d7
+ depends:
+ - python >=3.9
+ license: BSD-3-Clause
+ license_family: BSD
+ purls:
+ - pkg:pypi/colorama?source=hash-mapping
+ size: 27011
+ timestamp: 1733218222191
+- conda: https://conda.anaconda.org/conda-forge/osx-64/compiler-rt-18.1.3-ha38d28d_0.conda
+ sha256: 623f4a180fdb58c5480ea8e724162a57c5955b2f6ecc938a8314bf853dda4b60
+ md5: 7a828727c9afa54e7a773e734f628a88
+ depends:
+ - clang 18.1.3.*
+ - clangxx 18.1.3.*
+ - compiler-rt_osx-64 18.1.3.*
+ license: Apache-2.0 WITH LLVM-exception
+ license_family: APACHE
+ purls: []
+ size: 96452
+ timestamp: 1712580504480
+- conda: https://conda.anaconda.org/conda-forge/osx-arm64/compiler-rt-18.1.3-h3808999_0.conda
+ sha256: dfada604649fb2cfa6fb3dbd657fccf81cd01e00a7f6f29da24fc40e36cd51fa
+ md5: 09f614cf0dc4ea2b249c2e522b337730
+ depends:
+ - clang 18.1.3.*
+ - clangxx 18.1.3.*
+ - compiler-rt_osx-arm64 18.1.3.*
+ license: Apache-2.0 WITH LLVM-exception
+ license_family: APACHE
+ purls: []
+ size: 96152
+ timestamp: 1712580507858
+- conda: https://conda.anaconda.org/conda-forge/noarch/compiler-rt_osx-64-18.1.3-ha38d28d_0.conda
+ sha256: 4084d02399a9176a7a8bdccc530142b429846c166a1a0d65d15a0b7de465e7bb
+ md5: 678d71ebac649fc7324026e05930bf4c
+ depends:
+ - clang 18.1.3.*
+ - clangxx 18.1.3.*
+ constrains:
+ - compiler-rt 18.1.3
+ license: Apache-2.0 WITH LLVM-exception
+ license_family: APACHE
+ purls: []
+ size: 10367732
+ timestamp: 1712580438913
+- conda: https://conda.anaconda.org/conda-forge/noarch/compiler-rt_osx-arm64-18.1.3-h3808999_0.conda
+ sha256: 4bbe97d77ae12edd5c0206d014e0473ae8c4fcacbc1e1b21e8e92fd694608301
+ md5: 78c11131b59e53aedcf7854956a9347c
+ depends:
+ - clang 18.1.3.*
+ - clangxx 18.1.3.*
+ constrains:
+ - compiler-rt 18.1.3
+ license: Apache-2.0 WITH LLVM-exception
+ license_family: APACHE
+ purls: []
+ size: 10165573
+ timestamp: 1712580450851
+- conda: https://conda.anaconda.org/conda-forge/linux-64/conda-26.1.1-py310hff52083_0.conda
+ sha256: 38b5e5057fe3a69ea82125874f4653cfda2d5ca764a9a0bb8084e1ea3c53a661
+ md5: fdd3d2814d732e0d878fc7d4a2289f7f
+ depends:
+ - archspec >=0.2.3
+ - boltons >=23.0.0
+ - charset-normalizer
+ - conda-libmamba-solver >=25.4.0
+ - conda-package-handling >=2.2.0
+ - distro >=1.5.0
+ - frozendict >=2.4.2
+ - jsonpatch >=1.32
+ - menuinst >=2
+ - packaging >=23.0
+ - platformdirs >=3.10.0
+ - pluggy >=1.0.0
+ - pycosat >=0.6.3
+ - python >=3.10,<3.11.0a0
+ - python_abi 3.10.* *_cp310
+ - requests >=2.28.0,<3
+ - ruamel.yaml >=0.11.14,<0.19
+ - setuptools >=60.0.0
+ - tqdm >=4
+ - truststore >=0.8.0
+ - zstandard >=0.19.0
+ constrains:
+ - conda-env >=2.6
+ - conda-content-trust >=0.1.1
+ - conda-build >=25.9
+ license: BSD-3-Clause
+ license_family: BSD
+ purls:
+ - pkg:pypi/conda?source=hash-mapping
+ size: 999473
+ timestamp: 1772191385548
+- conda: https://conda.anaconda.org/conda-forge/linux-64/conda-26.1.1-py311h38be061_0.conda
+ sha256: 9cd790637fcab45938ad49753d15b0cfbe847f9f0d4a1b7213d30b6fb412fede
+ md5: 52f7c28c287da1a28cb9cabda1f5d0cf
+ depends:
+ - archspec >=0.2.3
+ - boltons >=23.0.0
+ - charset-normalizer
+ - conda-libmamba-solver >=25.4.0
+ - conda-package-handling >=2.2.0
+ - distro >=1.5.0
+ - frozendict >=2.4.2
+ - jsonpatch >=1.32
+ - menuinst >=2
+ - packaging >=23.0
+ - platformdirs >=3.10.0
+ - pluggy >=1.0.0
+ - pycosat >=0.6.3
+ - python >=3.11,<3.12.0a0
+ - python_abi 3.11.* *_cp311
+ - requests >=2.28.0,<3
+ - ruamel.yaml >=0.11.14,<0.19
+ - setuptools >=60.0.0
+ - tqdm >=4
+ - truststore >=0.8.0
+ - zstandard >=0.19.0
+ constrains:
+ - conda-env >=2.6
+ - conda-build >=25.9
+ - conda-content-trust >=0.1.1
+ license: BSD-3-Clause
+ license_family: BSD
+ purls:
+ - pkg:pypi/conda?source=compressed-mapping
+ size: 1286583
+ timestamp: 1772191375962
+- conda: https://conda.anaconda.org/conda-forge/linux-64/conda-26.1.1-py314hdafbbf9_0.conda
+ sha256: 287ebc90f9659755cf626e1dd1d405690bef16e805942b4a3d8008e2376ff8bf
+ md5: c1c5e3d6e85f5fe5a47789d7a10b140f
+ depends:
+ - archspec >=0.2.3
+ - boltons >=23.0.0
+ - charset-normalizer
+ - conda-libmamba-solver >=25.4.0
+ - conda-package-handling >=2.2.0
+ - distro >=1.5.0
+ - frozendict >=2.4.2
+ - jsonpatch >=1.32
+ - menuinst >=2
+ - packaging >=23.0
+ - platformdirs >=3.10.0
+ - pluggy >=1.0.0
+ - pycosat >=0.6.3
+ - python >=3.14,<3.15.0a0
+ - python_abi 3.14.* *_cp314
+ - requests >=2.28.0,<3
+ - ruamel.yaml >=0.11.14,<0.19
+ - setuptools >=60.0.0
+ - tqdm >=4
+ - truststore >=0.8.0
+ - zstandard >=0.19.0
+ constrains:
+ - conda-build >=25.9
+ - conda-env >=2.6
+ - conda-content-trust >=0.1.1
+ license: BSD-3-Clause
+ license_family: BSD
+ purls:
+ - pkg:pypi/conda?source=hash-mapping
+ size: 1307275
+ timestamp: 1772191378974
+- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/conda-26.1.1-py310h4c7bcd0_0.conda
+ sha256: 87aed41c4a995f4939816fce5c3555d66ad9551707fc117f3dde3884629c5b3a
+ md5: 42e348e1bb733f0095fa1ded7e1cfb00
+ depends:
+ - archspec >=0.2.3
+ - boltons >=23.0.0
+ - charset-normalizer
+ - conda-libmamba-solver >=25.4.0
+ - conda-package-handling >=2.2.0
+ - distro >=1.5.0
+ - frozendict >=2.4.2
+ - jsonpatch >=1.32
+ - menuinst >=2
+ - packaging >=23.0
+ - platformdirs >=3.10.0
+ - pluggy >=1.0.0
+ - pycosat >=0.6.3
+ - python >=3.10,<3.11.0a0
+ - python >=3.10,<3.11.0a0 *_cpython
+ - python_abi 3.10.* *_cp310
+ - requests >=2.28.0,<3
+ - ruamel.yaml >=0.11.14,<0.19
+ - setuptools >=60.0.0
+ - tqdm >=4
+ - truststore >=0.8.0
+ - zstandard >=0.19.0
+ constrains:
+ - conda-env >=2.6
+ - conda-content-trust >=0.1.1
+ - conda-build >=25.9
+ license: BSD-3-Clause
+ license_family: BSD
+ purls:
+ - pkg:pypi/conda?source=hash-mapping
+ size: 1001496
+ timestamp: 1772191435996
+- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/conda-26.1.1-py311hec3470c_0.conda
+ sha256: 6c0920b4eaf5c13201c05c7de3080289468a1281ad9eb14719635815acf44523
+ md5: 2d434ed94247068c4cc439c22d51b693
+ depends:
+ - archspec >=0.2.3
+ - boltons >=23.0.0
+ - charset-normalizer
+ - conda-libmamba-solver >=25.4.0
+ - conda-package-handling >=2.2.0
+ - distro >=1.5.0
+ - frozendict >=2.4.2
+ - jsonpatch >=1.32
+ - menuinst >=2
+ - packaging >=23.0
+ - platformdirs >=3.10.0
+ - pluggy >=1.0.0
+ - pycosat >=0.6.3
+ - python >=3.11,<3.12.0a0
+ - python >=3.11,<3.12.0a0 *_cpython
+ - python_abi 3.11.* *_cp311
+ - requests >=2.28.0,<3
+ - ruamel.yaml >=0.11.14,<0.19
+ - setuptools >=60.0.0
+ - tqdm >=4
+ - truststore >=0.8.0
+ - zstandard >=0.19.0
+ constrains:
+ - conda-env >=2.6
+ - conda-build >=25.9
+ - conda-content-trust >=0.1.1
+ license: BSD-3-Clause
+ license_family: BSD
+ purls:
+ - pkg:pypi/conda?source=hash-mapping
+ size: 1288665
+ timestamp: 1772191444841
+- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/conda-26.1.1-py314h28a4750_0.conda
+ sha256: 694fdd47a58ea57163ca5bb64bbe1332d413644f3a2cfa9ea515828aa98b73ab
+ md5: d511b5ac95faec60409f48c00a6d8f06
+ depends:
+ - archspec >=0.2.3
+ - boltons >=23.0.0
+ - charset-normalizer
+ - conda-libmamba-solver >=25.4.0
+ - conda-package-handling >=2.2.0
+ - distro >=1.5.0
+ - frozendict >=2.4.2
+ - jsonpatch >=1.32
+ - menuinst >=2
+ - packaging >=23.0
+ - platformdirs >=3.10.0
+ - pluggy >=1.0.0
+ - pycosat >=0.6.3
+ - python >=3.14,<3.15.0a0
+ - python >=3.14,<3.15.0a0 *_cp314
+ - python_abi 3.14.* *_cp314
+ - requests >=2.28.0,<3
+ - ruamel.yaml >=0.11.14,<0.19
+ - setuptools >=60.0.0
+ - tqdm >=4
+ - truststore >=0.8.0
+ - zstandard >=0.19.0
+ constrains:
+ - conda-build >=25.9
+ - conda-content-trust >=0.1.1
+ - conda-env >=2.6
+ license: BSD-3-Clause
+ license_family: BSD
+ purls:
+ - pkg:pypi/conda?source=hash-mapping
+ size: 1311034
+ timestamp: 1772191450615
+- conda: https://conda.anaconda.org/conda-forge/osx-64/conda-23.9.0-py310h2ec42d9_2.conda
+ sha256: 743fb814fa36fc2bfb976d258fc0854ceb6cb2552cf2bc8a6ab7407c8aed0dff
+ md5: 478a4d7f1b36bbf317b41027e2bc5d9d
+ depends:
+ - archspec
+ - boltons >=23.0.0
+ - conda-package-handling >=2.2.0
+ - jsonpatch >=1.32
+ - packaging >=23.0
+ - pluggy >=1.0.0
+ - pycosat >=0.6.3
+ - pyopenssl >=16.2.0
+ - python >=3.10,<3.11.0a0
+ - python_abi 3.10.* *_cp310
+ - requests >=2.27.0,<3
+ - ruamel.yaml >=0.11.14,<0.18
+ - setuptools >=60.0.0
+ - tqdm >=4
+ - truststore >=0.8.0
+ constrains:
+ - conda-env >=2.6
+ - conda-content-trust >=0.1.1
+ - conda-libmamba-solver >=23.7.0
+ - conda-build >=3
+ license: BSD-3-Clause
+ license_family: BSD
+ purls:
+ - pkg:pypi/conda?source=hash-mapping
+ size: 970554
+ timestamp: 1698451059802
+- conda: https://conda.anaconda.org/conda-forge/osx-64/conda-23.9.0-py311h6eed73b_2.conda
+ sha256: 894332c6be0df4be919dadd33dc9bf365e9851db3a6c65b5331986d6277296f4
+ md5: 8f27c249b5c0a2185f18250120613565
+ depends:
+ - archspec
+ - boltons >=23.0.0
+ - conda-package-handling >=2.2.0
+ - jsonpatch >=1.32
+ - packaging >=23.0
+ - pluggy >=1.0.0
+ - pycosat >=0.6.3
+ - pyopenssl >=16.2.0
+ - python >=3.11,<3.12.0a0
+ - python_abi 3.11.* *_cp311
+ - requests >=2.27.0,<3
+ - ruamel.yaml >=0.11.14,<0.18
+ - setuptools >=60.0.0
+ - tqdm >=4
+ - truststore >=0.8.0
+ constrains:
+ - conda-libmamba-solver >=23.7.0
+ - conda-build >=3
+ - conda-env >=2.6
+ - conda-content-trust >=0.1.1
+ license: BSD-3-Clause
+ license_family: BSD
+ purls:
+ - pkg:pypi/conda?source=hash-mapping
+ size: 1264324
+ timestamp: 1698451045537
+- conda: https://conda.anaconda.org/conda-forge/osx-64/conda-26.1.1-py314hee6578b_0.conda
+ sha256: 30f3fda3b376079a273a6a73dc510fdc663c77ba4fa696f82a48545476eb8014
+ md5: fa5b5fd3010a1bfcf558901f3ee09b9e
+ depends:
+ - archspec >=0.2.3
+ - boltons >=23.0.0
+ - charset-normalizer
+ - conda-libmamba-solver >=25.4.0
+ - conda-package-handling >=2.2.0
+ - distro >=1.5.0
+ - frozendict >=2.4.2
+ - jsonpatch >=1.32
+ - menuinst >=2
+ - packaging >=23.0
+ - platformdirs >=3.10.0
+ - pluggy >=1.0.0
+ - pycosat >=0.6.3
+ - python >=3.14,<3.15.0a0
+ - python_abi 3.14.* *_cp314
+ - requests >=2.28.0,<3
+ - ruamel.yaml >=0.11.14,<0.19
+ - setuptools >=60.0.0
+ - tqdm >=4
+ - truststore >=0.8.0
+ - zstandard >=0.19.0
+ constrains:
+ - conda-content-trust >=0.1.1
+ - conda-build >=25.9
+ - conda-env >=2.6
+ license: BSD-3-Clause
+ license_family: BSD
+ purls:
+ - pkg:pypi/conda?source=hash-mapping
+ size: 1310551
+ timestamp: 1772191748761
+- conda: https://conda.anaconda.org/conda-forge/osx-arm64/conda-23.9.0-py310hbe9552e_2.conda
+ sha256: 58834d003f2dfef45ccd8421adb0bdc4228542223563aa8681f3563c026fb005
+ md5: 629fd52fcd8e0559573559a6b008ce0e
+ depends:
+ - archspec
+ - boltons >=23.0.0
+ - conda-package-handling >=2.2.0
+ - jsonpatch >=1.32
+ - packaging >=23.0
+ - pluggy >=1.0.0
+ - pycosat >=0.6.3
+ - pyopenssl >=16.2.0
+ - python >=3.10,<3.11.0a0
+ - python >=3.10,<3.11.0a0 *_cpython
+ - python_abi 3.10.* *_cp310
+ - requests >=2.27.0,<3
+ - ruamel.yaml >=0.11.14,<0.18
+ - setuptools >=60.0.0
+ - tqdm >=4
+ - truststore >=0.8.0
+ constrains:
+ - conda-content-trust >=0.1.1
+ - conda-libmamba-solver >=23.7.0
+ - conda-env >=2.6
+ - conda-build >=3
+ license: BSD-3-Clause
+ license_family: BSD
+ purls:
+ - pkg:pypi/conda?source=hash-mapping
+ size: 970987
+ timestamp: 1698451243924
+- conda: https://conda.anaconda.org/conda-forge/osx-arm64/conda-23.9.0-py311h267d04e_2.conda
+ sha256: 700460cbbf01e9b37b375a62f25e195583964dd87720755d0bad43913c30d928
+ md5: f03a4e5f471e82036ebc4b5db54abc9d
+ depends:
+ - archspec
+ - boltons >=23.0.0
+ - conda-package-handling >=2.2.0
+ - jsonpatch >=1.32
+ - packaging >=23.0
+ - pluggy >=1.0.0
+ - pycosat >=0.6.3
+ - pyopenssl >=16.2.0
+ - python >=3.11,<3.12.0a0
+ - python >=3.11,<3.12.0a0 *_cpython
+ - python_abi 3.11.* *_cp311
+ - requests >=2.27.0,<3
+ - ruamel.yaml >=0.11.14,<0.18
+ - setuptools >=60.0.0
+ - tqdm >=4
+ - truststore >=0.8.0
+ constrains:
+ - conda-content-trust >=0.1.1
+ - conda-env >=2.6
+ - conda-libmamba-solver >=23.7.0
+ - conda-build >=3
+ license: BSD-3-Clause
+ license_family: BSD
+ purls:
+ - pkg:pypi/conda?source=hash-mapping
+ size: 1261327
+ timestamp: 1698451125796
+- conda: https://conda.anaconda.org/conda-forge/osx-arm64/conda-26.1.1-py314h4dc9dd8_0.conda
+ sha256: e07221f4bda014e492e9a8e99dc5ec307147afd44483346e58eaec6770f10865
+ md5: 29a62536271a0869f2d0ecb04e834634
+ depends:
+ - archspec >=0.2.3
+ - boltons >=23.0.0
+ - charset-normalizer
+ - conda-libmamba-solver >=25.4.0
+ - conda-package-handling >=2.2.0
+ - distro >=1.5.0
+ - frozendict >=2.4.2
+ - jsonpatch >=1.32
+ - menuinst >=2
+ - packaging >=23.0
+ - platformdirs >=3.10.0
+ - pluggy >=1.0.0
+ - pycosat >=0.6.3
+ - python >=3.14,<3.15.0a0
+ - python >=3.14,<3.15.0a0 *_cp314
+ - python_abi 3.14.* *_cp314
+ - requests >=2.28.0,<3
+ - ruamel.yaml >=0.11.14,<0.19
+ - setuptools >=60.0.0
+ - tqdm >=4
+ - truststore >=0.8.0
+ - zstandard >=0.19.0
+ constrains:
+ - conda-content-trust >=0.1.1
+ - conda-build >=25.9
+ - conda-env >=2.6
+ license: BSD-3-Clause
+ license_family: BSD
+ purls:
+ - pkg:pypi/conda?source=hash-mapping
+ size: 1310581
+ timestamp: 1772191962239
+- conda: https://conda.anaconda.org/conda-forge/win-64/conda-26.1.1-py310h5588dad_0.conda
+ sha256: b46279535611a3082d932c0aa5d6e13e2a56bb021a55370879692126a388b8e5
+ md5: 1e3fa316ac3da6d31d703ca70c8bbf47
+ depends:
+ - archspec >=0.2.3
+ - boltons >=23.0.0
+ - charset-normalizer
+ - conda-libmamba-solver >=25.4.0
+ - conda-package-handling >=2.2.0
+ - distro >=1.5.0
+ - frozendict >=2.4.2
+ - jsonpatch >=1.32
+ - menuinst >=2
+ - packaging >=23.0
+ - platformdirs >=3.10.0
+ - pluggy >=1.0.0
+ - pycosat >=0.6.3
+ - python >=3.10,<3.11.0a0
+ - python_abi 3.10.* *_cp310
+ - requests >=2.28.0,<3
+ - ruamel.yaml >=0.11.14,<0.19
+ - setuptools >=60.0.0
+ - tqdm >=4
+ - truststore >=0.8.0
+ - zstandard >=0.19.0
+ constrains:
+ - conda-content-trust >=0.1.1
+ - conda-build >=25.9
+ - conda-env >=2.6
+ license: BSD-3-Clause
+ license_family: BSD
+ purls:
+ - pkg:pypi/conda?source=hash-mapping
+ size: 1002216
+ timestamp: 1772191581878
+- conda: https://conda.anaconda.org/conda-forge/win-64/conda-26.1.1-py311h1ea47a8_0.conda
+ sha256: a2d7a3b3b48bf15bb705a6b6dce061e0ee05275159fbe105acea30be989d13cd
+ md5: 07554fc0615396c760ca7bebd6a3797c
+ depends:
+ - archspec >=0.2.3
+ - boltons >=23.0.0
+ - charset-normalizer
+ - conda-libmamba-solver >=25.4.0
+ - conda-package-handling >=2.2.0
+ - distro >=1.5.0
+ - frozendict >=2.4.2
+ - jsonpatch >=1.32
+ - menuinst >=2
+ - packaging >=23.0
+ - platformdirs >=3.10.0
+ - pluggy >=1.0.0
+ - pycosat >=0.6.3
+ - python >=3.11,<3.12.0a0
+ - python_abi 3.11.* *_cp311
+ - requests >=2.28.0,<3
+ - ruamel.yaml >=0.11.14,<0.19
+ - setuptools >=60.0.0
+ - tqdm >=4
+ - truststore >=0.8.0
+ - zstandard >=0.19.0
+ constrains:
+ - conda-env >=2.6
+ - conda-build >=25.9
+ - conda-content-trust >=0.1.1
+ license: BSD-3-Clause
+ license_family: BSD
+ purls:
+ - pkg:pypi/conda?source=hash-mapping
+ size: 1287539
+ timestamp: 1772191674230
+- conda: https://conda.anaconda.org/conda-forge/win-64/conda-26.1.1-py314h86ab7b2_0.conda
+ sha256: 1b6770ef97301830842c57ad0c18ad25858c0d62e2a1b1248d9b37fb1ce3eaf6
+ md5: 2ce9348410797986e1c59939d6162826
+ depends:
+ - archspec >=0.2.3
+ - boltons >=23.0.0
+ - charset-normalizer
+ - conda-libmamba-solver >=25.4.0
+ - conda-package-handling >=2.2.0
+ - distro >=1.5.0
+ - frozendict >=2.4.2
+ - jsonpatch >=1.32
+ - menuinst >=2
+ - packaging >=23.0
+ - platformdirs >=3.10.0
+ - pluggy >=1.0.0
+ - pycosat >=0.6.3
+ - python >=3.14,<3.15.0a0
+ - python_abi 3.14.* *_cp314
+ - requests >=2.28.0,<3
+ - ruamel.yaml >=0.11.14,<0.19
+ - setuptools >=60.0.0
+ - tqdm >=4
+ - truststore >=0.8.0
+ - zstandard >=0.19.0
+ constrains:
+ - conda-env >=2.6
+ - conda-content-trust >=0.1.1
+ - conda-build >=25.9
+ license: BSD-3-Clause
+ license_family: BSD
+ purls:
+ - pkg:pypi/conda?source=hash-mapping
+ size: 1309098
+ timestamp: 1772191684896
+- conda: https://conda.anaconda.org/conda-forge/linux-64/conda-gcc-specs-14.3.0-he8ccf15_18.conda
+ sha256: b90ec0e6a9eb22f7240b3584fe785457cff961fec68d40e6aece5d596f9bbd9a
+ md5: 0e3e144115c43c9150d18fa20db5f31c
+ depends:
+ - gcc_impl_linux-64 >=14.3.0,<14.3.1.0a0
+ license: GPL-3.0-only WITH GCC-exception-3.1
+ license_family: GPL
+ purls: []
+ size: 31705
+ timestamp: 1771378159534
+- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/conda-gcc-specs-14.3.0-hadff5d6_18.conda
+ sha256: 7b018e74d2f828e887faabc9d5c5bef6d432c3356dcac3e691ee6b24bc82ef52
+ md5: 184c1aba41c40e6bc59fa91b37cd7c3f
+ depends:
+ - gcc_impl_linux-aarch64 >=14.3.0,<14.3.1.0a0
+ license: GPL-3.0-only WITH GCC-exception-3.1
+ license_family: GPL
+ purls: []
+ size: 31474
+ timestamp: 1771377963347
+- conda: https://conda.anaconda.org/conda-forge/noarch/conda-libmamba-solver-25.11.0-pyhd8ed1ab_1.conda
+ sha256: 001812b000c9791db53a85b0f215952b7497ca1fd6e3070314e20f707556765b
+ md5: 1d545b8b06123889395de8a3674fc0e7
+ depends:
+ - boltons >=23.0.0
+ - libmambapy >=2.0.0
+ - msgpack-python >=1.1.1
+ - python >=3.10
+ - requests >=2.28.0,<3
+ - zstandard >=0.15
+ constrains:
+ - conda >=25.9
+ license: BSD-3-Clause
+ license_family: BSD
+ purls:
+ - pkg:pypi/conda-libmamba-solver?source=hash-mapping
+ size: 56969
+ timestamp: 1770137431666
+- conda: https://conda.anaconda.org/conda-forge/noarch/conda-package-handling-2.4.0-pyh7900ff3_2.conda
+ sha256: 8b2b1c235b7cbfa8488ad88ff934bdad25bac6a4c035714681fbff85b602f3f0
+ md5: 32c158f481b4fd7630c565030f7bc482
+ depends:
+ - conda-package-streaming >=0.9.0
+ - python >=3.9
+ - requests
+ - zstandard >=0.15
+ license: BSD-3-Clause
+ license_family: BSD
+ purls:
+ - pkg:pypi/conda-package-handling?source=hash-mapping
+ size: 257995
+ timestamp: 1736345601691
+- conda: https://conda.anaconda.org/conda-forge/noarch/conda-package-streaming-0.12.0-pyhd8ed1ab_0.conda
+ sha256: 11b76b0be2f629e8035be1d723ccb6e583eb0d2af93bde56113da7fa6e2f2649
+ md5: ff75d06af779966a5aeae1be1d409b96
+ depends:
+ - python >=3.9
+ - zstandard >=0.15
+ license: BSD-3-Clause
+ license_family: BSD
+ purls:
+ - pkg:pypi/conda-package-streaming?source=hash-mapping
+ size: 21933
+ timestamp: 1751548225624
+- conda: https://conda.anaconda.org/conda-forge/linux-64/cpp-expected-1.3.1-h171cf75_0.conda
+ sha256: 0d9405d9f2de5d4b15d746609d87807aac10e269072d6408b769159762ed113d
+ md5: d17488e343e4c5c0bd0db18b3934d517
+ depends:
+ - libstdcxx >=14
+ - libgcc >=14
+ - __glibc >=2.17,<3.0.a0
+ license: CC0-1.0
+ purls: []
+ size: 24283
+ timestamp: 1756734785482
+- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/cpp-expected-1.3.1-hdc560ac_0.conda
+ sha256: 4edebca2a9dadd8afabb3948a007edae2072e4869d8959b3e51aebc2367e1df4
+ md5: 13f0be21fdd39114c28501ac21f0dd00
+ depends:
+ - libstdcxx >=14
+ - libgcc >=14
+ license: CC0-1.0
+ purls: []
+ size: 25132
+ timestamp: 1756734793606
+- conda: https://conda.anaconda.org/conda-forge/osx-64/cpp-expected-1.3.1-h0ba0a54_0.conda
+ sha256: 3192481102b7ad011933620791355148c16fb29ab8e0dac657de5388c05f44e8
+ md5: d788061f51b79dfcb6c1521507ca08c7
+ depends:
+ - __osx >=10.13
+ - libcxx >=19
+ license: CC0-1.0
+ purls: []
+ size: 24618
+ timestamp: 1756734941438
+- conda: https://conda.anaconda.org/conda-forge/osx-arm64/cpp-expected-1.3.1-h4f10f1e_0.conda
+ sha256: a7380056125a29ddc4c4efc4e39670bc8002609c70f143d92df801b42e0b486f
+ md5: 5cb4f9b93055faf7b6ae76da6123f927
+ depends:
+ - __osx >=11.0
+ - libcxx >=19
+ license: CC0-1.0
+ purls: []
+ size: 24960
+ timestamp: 1756734870487
+- conda: https://conda.anaconda.org/conda-forge/win-64/cpp-expected-1.3.1-h477610d_0.conda
+ sha256: cd24ac6768812d53c3b14c29b468cc9a5516b71e1880d67f58d98d9787f4cc3a
+ md5: 444e9f7d9b3f69006c3af5db59e11364
+ depends:
+ - vc >=14.3,<15
+ - vc14_runtime >=14.44.35208
+ - ucrt >=10.0.20348.0
+ - vc >=14.3,<15
+ - vc14_runtime >=14.44.35208
+ - ucrt >=10.0.20348.0
+ license: CC0-1.0
+ purls: []
+ size: 21733
+ timestamp: 1756734797622
+- pypi: https://files.pythonhosted.org/packages/34/71/1ea5a7352ae516d5512d17babe7e1b87d9db5150b21f794b1377eac1edc0/cryptography-46.0.6-cp311-abi3-manylinux_2_28_x86_64.whl
+ name: cryptography
+ version: 46.0.6
+ sha256: 22259338084d6ae497a19bae5d4c66b7ca1387d3264d1c2c0e72d9e9b6a77b97
+ requires_dist:
+ - cffi>=1.14 ; python_full_version == '3.8.*' and platform_python_implementation != 'PyPy'
+ - cffi>=2.0.0 ; python_full_version >= '3.9' and platform_python_implementation != 'PyPy'
+ - typing-extensions>=4.13.2 ; python_full_version < '3.11'
+ - bcrypt>=3.1.5 ; extra == 'ssh'
+ - nox[uv]>=2024.4.15 ; extra == 'nox'
+ - cryptography-vectors==46.0.6 ; extra == 'test'
+ - pytest>=7.4.0 ; extra == 'test'
+ - pytest-benchmark>=4.0 ; extra == 'test'
+ - pytest-cov>=2.10.1 ; extra == 'test'
+ - pytest-xdist>=3.5.0 ; extra == 'test'
+ - pretend>=0.7 ; extra == 'test'
+ - certifi>=2024 ; extra == 'test'
+ - pytest-randomly ; extra == 'test-randomorder'
+ - sphinx>=5.3.0 ; extra == 'docs'
+ - sphinx-rtd-theme>=3.0.0 ; extra == 'docs'
+ - sphinx-inline-tabs ; extra == 'docs'
+ - pyenchant>=3 ; extra == 'docstest'
+ - readme-renderer>=30.0 ; extra == 'docstest'
+ - sphinxcontrib-spelling>=7.3.1 ; extra == 'docstest'
+ - build>=1.0.0 ; extra == 'sdist'
+ - ruff>=0.11.11 ; extra == 'pep8test'
+ - mypy>=1.14 ; extra == 'pep8test'
+ - check-sdist ; extra == 'pep8test'
+ - click>=8.0.1 ; extra == 'pep8test'
+ requires_python: '>=3.8,!=3.9.0,!=3.9.1'
+- pypi: https://files.pythonhosted.org/packages/d4/12/123be7292674abf76b21ac1fc0e1af50661f0e5b8f0ec8285faac18eb99e/cryptography-46.0.6-cp311-abi3-manylinux_2_28_aarch64.whl
+ name: cryptography
+ version: 46.0.6
+ sha256: 67177e8a9f421aa2d3a170c3e56eca4e0128883cf52a071a7cbf53297f18b175
+ requires_dist:
+ - cffi>=1.14 ; python_full_version == '3.8.*' and platform_python_implementation != 'PyPy'
+ - cffi>=2.0.0 ; python_full_version >= '3.9' and platform_python_implementation != 'PyPy'
+ - typing-extensions>=4.13.2 ; python_full_version < '3.11'
+ - bcrypt>=3.1.5 ; extra == 'ssh'
+ - nox[uv]>=2024.4.15 ; extra == 'nox'
+ - cryptography-vectors==46.0.6 ; extra == 'test'
+ - pytest>=7.4.0 ; extra == 'test'
+ - pytest-benchmark>=4.0 ; extra == 'test'
+ - pytest-cov>=2.10.1 ; extra == 'test'
+ - pytest-xdist>=3.5.0 ; extra == 'test'
+ - pretend>=0.7 ; extra == 'test'
+ - certifi>=2024 ; extra == 'test'
+ - pytest-randomly ; extra == 'test-randomorder'
+ - sphinx>=5.3.0 ; extra == 'docs'
+ - sphinx-rtd-theme>=3.0.0 ; extra == 'docs'
+ - sphinx-inline-tabs ; extra == 'docs'
+ - pyenchant>=3 ; extra == 'docstest'
+ - readme-renderer>=30.0 ; extra == 'docstest'
+ - sphinxcontrib-spelling>=7.3.1 ; extra == 'docstest'
+ - build>=1.0.0 ; extra == 'sdist'
+ - ruff>=0.11.11 ; extra == 'pep8test'
+ - mypy>=1.14 ; extra == 'pep8test'
+ - check-sdist ; extra == 'pep8test'
+ - click>=8.0.1 ; extra == 'pep8test'
+ requires_python: '>=3.8,!=3.9.0,!=3.9.1'
+- conda: https://conda.anaconda.org/conda-forge/osx-64/cryptography-41.0.7-py310h527a09d_1.conda
+ sha256: cb43f44af3ff4ec8ffb1517234075d39e64442ec75ce995f1e9bd8b032a8aef0
+ md5: e5291aa101f6590559177df876cd0955
+ depends:
+ - cffi >=1.12
+ - openssl >=3.1.4,<4.0a0
+ - python >=3.10,<3.11.0a0
+ - python_abi 3.10.* *_cp310
+ license: Apache-2.0 AND BSD-3-Clause AND PSF-2.0 AND MIT
+ license_family: BSD
+ purls:
+ - pkg:pypi/cryptography?source=hash-mapping
+ size: 1218731
+ timestamp: 1701563760923
+- conda: https://conda.anaconda.org/conda-forge/osx-64/cryptography-41.0.7-py311h48c7838_1.conda
+ sha256: f4c5e683386acf06cfa85805d264c9cd540361ec6e86740cb03312e560aa706a
+ md5: 65293feff96135571de02c047ecbd5a2
+ depends:
+ - cffi >=1.12
+ - openssl >=3.1.4,<4.0a0
+ - python >=3.11,<3.12.0a0
+ - python_abi 3.11.* *_cp311
+ license: Apache-2.0 AND BSD-3-Clause AND PSF-2.0 AND MIT
+ license_family: BSD
+ purls:
+ - pkg:pypi/cryptography?source=hash-mapping
+ size: 1280957
+ timestamp: 1701563770508
+- conda: https://conda.anaconda.org/conda-forge/osx-arm64/cryptography-41.0.7-py310h4c55245_1.conda
+ sha256: 85ce5e6db3093fea6bb45c28d783db002339cc56b578789d6141b136a4266a59
+ md5: 9d2f02b43aaceb00fbe294ce9e9646c6
+ depends:
+ - cffi >=1.12
+ - openssl >=3.1.4,<4.0a0
+ - python >=3.10,<3.11.0a0
+ - python >=3.10,<3.11.0a0 *_cpython
+ - python_abi 3.10.* *_cp310
+ license: Apache-2.0 AND BSD-3-Clause AND PSF-2.0 AND MIT
+ license_family: BSD
+ purls:
+ - pkg:pypi/cryptography?source=hash-mapping
+ size: 1200542
+ timestamp: 1701563810375
+- conda: https://conda.anaconda.org/conda-forge/osx-arm64/cryptography-41.0.7-py311h08c85a6_1.conda
+ sha256: 9d51ba743069d19aae08361a7b051ca1f281fb3b3ccb162e96c2503cf5a7d365
+ md5: 729546a91873db64ab8e675008845fb5
+ depends:
+ - cffi >=1.12
+ - openssl >=3.1.4,<4.0a0
+ - python >=3.11,<3.12.0a0
+ - python >=3.11,<3.12.0a0 *_cpython
+ - python_abi 3.11.* *_cp311
+ license: Apache-2.0 AND BSD-3-Clause AND PSF-2.0 AND MIT
+ license_family: BSD
+ purls:
+ - pkg:pypi/cryptography?source=hash-mapping
+ size: 1263886
+ timestamp: 1701563842828
+- conda: https://conda.anaconda.org/conda-forge/linux-64/cxx-compiler-1.11.0-hfcd1e18_0.conda
+ sha256: 3fcc97ae3e89c150401a50a4de58794ffc67b1ed0e1851468fcc376980201e25
+ md5: 5da8c935dca9186673987f79cef0b2a5
+ depends:
+ - c-compiler 1.11.0 h4d9bdce_0
+ - gxx
+ - gxx_linux-64 14.*
+ license: BSD-3-Clause
+ license_family: BSD
+ purls: []
+ size: 6635
+ timestamp: 1753098722177
+- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/cxx-compiler-1.11.0-h7b35c40_0.conda
+ sha256: b87cd33501867d999caa1a57e488e69dc9e08011ec8685586df754302247a7a4
+ md5: 0234c63e6b36b1677fd6c5238ef0a4ec
+ depends:
+ - c-compiler 1.11.0 hdceaead_0
+ - gxx
+ - gxx_linux-aarch64 14.*
+ license: BSD-3-Clause
+ license_family: BSD
+ purls: []
+ size: 6705
+ timestamp: 1753098688728
+- conda: https://conda.anaconda.org/conda-forge/osx-64/cxx-compiler-1.10.0-h20888b2_0.conda
+ sha256: 15f6ea7258555b2e34d147d378f4e8e08343ca3e71a18bd98b89a3dbc43142a2
+ md5: b3a935ade707c54ebbea5f8a7c6f4549
+ depends:
+ - c-compiler 1.10.0 h09a7c41_0
+ - clangxx_osx-64 18.*
+ license: BSD-3-Clause
+ license_family: BSD
+ purls: []
+ size: 6785
+ timestamp: 1751115659099
+- conda: https://conda.anaconda.org/conda-forge/osx-arm64/cxx-compiler-1.10.0-hba80287_0.conda
+ sha256: 52cbfc615a9727294fccdd507f11919ca01ff29bd928bb5aa0b211697a983e9f
+ md5: 7fca30a1585a85ec8ab63579afcac5d3
+ depends:
+ - c-compiler 1.10.0 hdf49b6b_0
+ - clangxx_osx-arm64 18.*
+ license: BSD-3-Clause
+ license_family: BSD
+ purls: []
+ size: 6784
+ timestamp: 1751115541888
+- conda: https://conda.anaconda.org/conda-forge/win-64/cxx-compiler-1.11.0-h1c1089f_0.conda
+ sha256: c888f4fe9ec117c1c01bfaa4c722ca475ebbb341c92d1718afa088bb0d710619
+ md5: 4d94d3c01add44dc9d24359edf447507
+ depends:
+ - vs2022_win-64
+ license: BSD-3-Clause
+ license_family: BSD
+ purls: []
+ size: 6957
+ timestamp: 1753098809481
+- pypi: https://files.pythonhosted.org/packages/2b/dd/437e601fa9d2b6bf8507256daf52196a226c3b340261f4cde8fac8e853ea/delocate-0.13.0-py3-none-any.whl
+ name: delocate
+ version: 0.13.0
+ sha256: 11f7596f88984c33f76b27fe2eea7637d1ce369a9e0b6737bbc706b6426e862c
+ requires_dist:
+ - packaging>=20.9
+ - typing-extensions>=4.12.2
+ - macholib
+ requires_python: '>=3.9'
+- pypi: https://files.pythonhosted.org/packages/89/74/bf0ea7b89e114af19a38c2341746fd1f17f1de23fa8d8019cbcd39719c5f/delvewheel-1.12.0-py3-none-any.whl
+ name: delvewheel
+ version: 1.12.0
+ sha256: 659ef85a83e4503e037e65570f7a87d2ad4e0ee55dc2d19d9afed420a031caf0
+ requires_dist:
+ - pefile>=2024.8.26
+ requires_python: '>=3.9'
+- conda: https://conda.anaconda.org/conda-forge/noarch/distlib-0.4.0-pyhd8ed1ab_0.conda
+ sha256: 6d977f0b2fc24fee21a9554389ab83070db341af6d6f09285360b2e09ef8b26e
+ md5: 003b8ba0a94e2f1e117d0bd46aebc901
+ depends:
+ - python >=3.9
+ license: Apache-2.0
+ license_family: APACHE
+ purls:
+ - pkg:pypi/distlib?source=hash-mapping
+ size: 275642
+ timestamp: 1752823081585
+- conda: https://conda.anaconda.org/conda-forge/noarch/distro-1.9.0-pyhd8ed1ab_1.conda
+ sha256: 5603c7d0321963bb9b4030eadabc3fd7ca6103a38475b4e0ed13ed6d97c86f4e
+ md5: 0a2014fd9860f8b1eaa0b1f3d3771a08
+ depends:
+ - python >=3.9
+ license: Apache-2.0
+ license_family: APACHE
+ purls:
+ - pkg:pypi/distro?source=hash-mapping
+ size: 41773
+ timestamp: 1734729953882
+- pypi: https://files.pythonhosted.org/packages/02/10/5da547df7a391dcde17f59520a231527b8571e6f46fc8efb02ccb370ab12/docutils-0.22.4-py3-none-any.whl
+ name: docutils
+ version: 0.22.4
+ sha256: d0013f540772d1420576855455d050a2180186c91c15779301ac2ccb3eeb68de
+ requires_python: '>=3.9'
+- conda: https://conda.anaconda.org/conda-forge/linux-64/doxygen-1.13.2-h8e693c7_0.conda
+ sha256: 349c4c872357b4a533e127b2ade8533796e8e062abc2cd685756a1a063ae1e35
+ md5: 0869f41ea5c64643dd2f5b47f32709ca
+ depends:
+ - __glibc >=2.17,<3.0.a0
+ - libgcc >=13
+ - libiconv >=1.17,<2.0a0
+ - libstdcxx >=13
+ license: GPL-2.0-only
+ license_family: GPL
+ purls: []
+ size: 13148627
+ timestamp: 1738164137421
+- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/doxygen-1.13.2-h5e0f5ae_0.conda
+ sha256: 671fc9849fcdb9138daf2ab6b2d45b0650055ba1496cda19c415f57cabc381b8
+ md5: 9091aa1c92ed01d5fe3d34d7e585b6a1
+ depends:
+ - libgcc >=13
+ - libiconv >=1.17,<2.0a0
+ - libstdcxx >=13
+ license: GPL-2.0-only
+ license_family: GPL
+ purls: []
+ size: 13227405
+ timestamp: 1738171320483
+- conda: https://conda.anaconda.org/conda-forge/osx-64/doxygen-1.10.0-h5ff76d1_0.conda
+ sha256: c329a379f8bc8a66bb91527efca44fb17b35ccf6f1dd1efc6b439fafe9ff67d4
+ md5: 4b0fd9ed5a22b919a04bc147f9d65654
+ depends:
+ - libcxx >=15
+ - libiconv >=1.17,<2.0a0
+ license: GPL-2.0-only
+ license_family: GPL
+ purls: []
+ size: 11525553
+ timestamp: 1703609916595
+- conda: https://conda.anaconda.org/conda-forge/osx-arm64/doxygen-1.10.0-h8fbad5d_0.conda
+ sha256: d609f61b22cb7fc5441a5bf1e6ac989840977cc682e94d726fdcc74c6cd89ea2
+ md5: 80aaa05136ea0b7cea754bb28488cc0f
+ depends:
+ - libcxx >=15
+ - libiconv >=1.17,<2.0a0
+ license: GPL-2.0-only
+ license_family: GPL
+ purls: []
+ size: 10593614
+ timestamp: 1703609902689
+- conda: https://conda.anaconda.org/conda-forge/win-64/doxygen-1.13.2-hbf3f430_0.conda
+ sha256: 7a0fd40fd704e97a8f6533a081ba29579766d7a60bcb8e5de76679b066c4a72e
+ md5: 5cb2e11931773612d7a24b53f0c57594
+ depends:
+ - libiconv >=1.17,<2.0a0
+ - ucrt >=10.0.20348.0
+ - vc >=14.2,<15
+ - vc14_runtime >=14.29.30139
+ license: GPL-2.0-only
+ license_family: GPL
+ purls: []
+ size: 9219343
+ timestamp: 1738165042524
+- conda: https://conda.anaconda.org/conda-forge/noarch/exceptiongroup-1.3.1-pyhd8ed1ab_0.conda
+ sha256: ee6cf346d017d954255bbcbdb424cddea4d14e4ed7e9813e429db1d795d01144
+ md5: 8e662bd460bda79b1ea39194e3c4c9ab
+ depends:
+ - python >=3.10
+ - typing_extensions >=4.6.0
+ license: MIT and PSF-2.0
+ purls:
+ - pkg:pypi/exceptiongroup?source=hash-mapping
+ size: 21333
+ timestamp: 1763918099466
+- conda: https://conda.anaconda.org/conda-forge/noarch/filelock-3.25.2-pyhd8ed1ab_0.conda
+ sha256: dddea9ec53d5e179de82c24569d41198f98db93314f0adae6b15195085d5567f
+ md5: f58064cec97b12a7136ebb8a6f8a129b
+ depends:
+ - python >=3.10
+ license: Unlicense
+ purls:
+ - pkg:pypi/filelock?source=compressed-mapping
+ size: 25845
+ timestamp: 1773314012590
+- conda: https://conda.anaconda.org/conda-forge/linux-64/fmt-12.1.0-hff5e90c_0.conda
+ sha256: d4e92ba7a7b4965341dc0fca57ec72d01d111b53c12d11396473115585a9ead6
+ md5: f7d7a4104082b39e3b3473fbd4a38229
+ depends:
+ - __glibc >=2.17,<3.0.a0
+ - libgcc >=14
+ - libstdcxx >=14
+ license: MIT
+ license_family: MIT
+ purls: []
+ size: 198107
+ timestamp: 1767681153946
+- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/fmt-12.1.0-h20c602a_0.conda
+ sha256: 7826619c80af5a5fb0c1f2a965c93f4b92670523e12ff45c592daa3f11340746
+ md5: 067209b690c2d7f42e1e4c370d1aff12
+ depends:
+ - libgcc >=14
+ - libstdcxx >=14
+ license: MIT
+ license_family: MIT
+ purls: []
+ size: 197671
+ timestamp: 1767681179883
+- conda: https://conda.anaconda.org/conda-forge/osx-64/fmt-12.1.0-hda137b5_0.conda
+ sha256: 3c56fc4b3528acb29d89d139f9800b86425e643be8d9caddd4d6f4a8b09a8db4
+ md5: 265ec3c628a7e2324d86a08205ada7a8
+ depends:
+ - __osx >=10.13
+ - libcxx >=19
+ license: MIT
+ license_family: MIT
+ purls: []
+ size: 188352
+ timestamp: 1767681462452
+- conda: https://conda.anaconda.org/conda-forge/osx-arm64/fmt-12.1.0-h403dcb5_0.conda
+ sha256: dba5d4a93dc62f20e4c2de813ccf7beefed1fb54313faff9c4f2383e4744c8e5
+ md5: ae2f556fbb43e5a75cc80a47ac942a8e
+ depends:
+ - __osx >=11.0
+ - libcxx >=19
+ license: MIT
+ license_family: MIT
+ purls: []
+ size: 180970
+ timestamp: 1767681372955
+- conda: https://conda.anaconda.org/conda-forge/win-64/fmt-12.1.0-h7f4e812_0.conda
+ sha256: cce96406ec353692ab46cd9d992eddb6923979c1a342cbdba33521a7c234176f
+ md5: 6e226b58e18411571aaa57a16ad10831
+ depends:
+ - ucrt >=10.0.20348.0
+ - vc >=14.3,<15
+ - vc14_runtime >=14.44.35208
+ license: MIT
+ license_family: MIT
+ purls: []
+ size: 186390
+ timestamp: 1767681264793
+- conda: https://conda.anaconda.org/conda-forge/linux-64/frozendict-2.4.7-py310h7c4b9e2_0.conda
+ sha256: 584dd9b80818771700875465b2906a4a8cc1e766d802ce269a00d8622b92e522
+ md5: 901de6f1f35f811f8d194785838a5977
+ depends:
+ - __glibc >=2.17,<3.0.a0
+ - libgcc >=14
+ - python >=3.10,<3.11.0a0
+ - python_abi 3.10.* *_cp310
+ license: LGPL-3.0-only
+ license_family: LGPL
+ purls:
+ - pkg:pypi/frozendict?source=hash-mapping
+ size: 49924
+ timestamp: 1763082943540
+- conda: https://conda.anaconda.org/conda-forge/linux-64/frozendict-2.4.7-py311h49ec1c0_0.conda
+ sha256: df99ccc63c065875cc150f451aaab03e6733898219cf2f248543fe53b08deff0
+ md5: cfc74ea184e02e531732abb17778e9fc
+ depends:
+ - __glibc >=2.17,<3.0.a0
+ - libgcc >=14
+ - python >=3.11,<3.12.0a0
+ - python_abi 3.11.* *_cp311
+ license: LGPL-3.0-only
+ license_family: LGPL
+ purls:
+ - pkg:pypi/frozendict?source=hash-mapping
+ size: 32010
+ timestamp: 1763082979695
+- conda: https://conda.anaconda.org/conda-forge/linux-64/frozendict-2.4.7-py314h5bd0f2a_0.conda
+ sha256: 3e04b8293122e923f1c66599525e8b0e743f532b5c53d932c41105311b721526
+ md5: 7a884102c0e9fb57012a6f49259475fc
+ depends:
+ - __glibc >=2.17,<3.0.a0
+ - libgcc >=14
+ - python >=3.14,<3.15.0a0
+ - python_abi 3.14.* *_cp314
+ license: LGPL-3.0-only
+ license_family: LGPL
+ purls:
+ - pkg:pypi/frozendict?source=hash-mapping
+ size: 31627
+ timestamp: 1763082886391
+- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/frozendict-2.4.7-py310h5b55623_0.conda
+ sha256: bc856378ebcd12d761a9992cdb37719ea1dfed9c8b77e45951723aefbe8cd7da
+ md5: 31ee97292b96431bdafcc3af09c21550
+ depends:
+ - libgcc >=14
+ - python >=3.10,<3.11.0a0
+ - python >=3.10,<3.11.0a0 *_cpython
+ - python_abi 3.10.* *_cp310
+ license: LGPL-3.0-only
+ license_family: LGPL
+ purls:
+ - pkg:pypi/frozendict?source=hash-mapping
+ size: 51959
+ timestamp: 1763082951492
+- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/frozendict-2.4.7-py311h19352d5_0.conda
+ sha256: 0951b89bc10e54b5e20c6bd8ef990e5afc155d13d713c45a525fe87f478980a6
+ md5: 9ef6a694ecd981dad43ab8f1864bcf43
+ depends:
+ - libgcc >=14
+ - python >=3.11,<3.12.0a0
+ - python >=3.11,<3.12.0a0 *_cpython
+ - python_abi 3.11.* *_cp311
+ license: LGPL-3.0-only
+ license_family: LGPL
+ purls:
+ - pkg:pypi/frozendict?source=hash-mapping
+ size: 32258
+ timestamp: 1763083003765
+- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/frozendict-2.4.7-py314h51f160d_0.conda
+ sha256: 669bfad0045393c79ad96fea1900d30d9c497cde6dd79ff6500be53245874c67
+ md5: 723828d9832e586bf2f9c52c38d4bf01
+ depends:
+ - libgcc >=14
+ - python >=3.14,<3.15.0a0
+ - python >=3.14,<3.15.0a0 *_cp314
+ - python_abi 3.14.* *_cp314
+ license: LGPL-3.0-only
+ license_family: LGPL
+ purls:
+ - pkg:pypi/frozendict?source=hash-mapping
+ size: 31504
+ timestamp: 1763082941890
+- conda: https://conda.anaconda.org/conda-forge/osx-64/frozendict-2.4.7-py314h6482030_0.conda
+ sha256: 5d0f185b622da1bd23beafb7e66dc14d3d1335f1c3e7eca91e731f2ded12800b
+ md5: d7ab51dbffe250c5570d766c44db6af0
+ depends:
+ - __osx >=10.13
+ - python >=3.14,<3.15.0a0
+ - python_abi 3.14.* *_cp314
+ license: LGPL-3.0-only
+ license_family: LGPL
+ purls:
+ - pkg:pypi/frozendict?source=hash-mapping
+ size: 31842
+ timestamp: 1763083176058
+- conda: https://conda.anaconda.org/conda-forge/osx-arm64/frozendict-2.4.7-py314h0612a62_0.conda
+ sha256: 614c604a4ff2ee59579d6ad6489726b56027bd49f50f4674cdaf98c6a0daa6be
+ md5: 8e7628502497ee2940f8864a22e3bd0c
+ depends:
+ - __osx >=11.0
+ - python >=3.14,<3.15.0a0
+ - python >=3.14,<3.15.0a0 *_cp314
+ - python_abi 3.14.* *_cp314
+ license: LGPL-3.0-only
+ license_family: LGPL
+ purls:
+ - pkg:pypi/frozendict?source=hash-mapping
+ size: 32182
+ timestamp: 1763083208667
+- conda: https://conda.anaconda.org/conda-forge/win-64/frozendict-2.4.7-py310h29418f3_0.conda
+ sha256: 0d07dddfc0fcaf7532b2d7b70619422116f95296d68d714686c32b3eb431c218
+ md5: 76c23d3bc5ebfa998703241569ee7b7e
+ depends:
+ - python >=3.10,<3.11.0a0
+ - python_abi 3.10.* *_cp310
+ - ucrt >=10.0.20348.0
+ - vc >=14.3,<15
+ - vc14_runtime >=14.44.35208
+ license: LGPL-3.0-only
+ license_family: LGPL
+ purls:
+ - pkg:pypi/frozendict?source=hash-mapping
+ size: 47769
+ timestamp: 1763083252959
+- conda: https://conda.anaconda.org/conda-forge/win-64/frozendict-2.4.7-py311h3485c13_0.conda
+ sha256: 2f719c3f15a54d02b5970075d013440eb9cc16503128cd9a8e97cb6275c57c82
+ md5: b17cb83dcb04b06a3377c3ce8423bca9
+ depends:
+ - python >=3.11,<3.12.0a0
+ - python_abi 3.11.* *_cp311
+ - ucrt >=10.0.20348.0
+ - vc >=14.3,<15
+ - vc14_runtime >=14.44.35208
+ license: LGPL-3.0-only
+ license_family: LGPL
+ purls:
+ - pkg:pypi/frozendict?source=hash-mapping
+ size: 32227
+ timestamp: 1763083050764
+- conda: https://conda.anaconda.org/conda-forge/win-64/frozendict-2.4.7-py314h5a2d7ad_0.conda
+ sha256: 87f206e4ac1ee9cc7099f3bbb05c039650b9a606bebb59c3778e5f2050795930
+ md5: dbac0ebdc50febbb706fcd765227c90f
+ depends:
+ - python >=3.14,<3.15.0a0
+ - python_abi 3.14.* *_cp314
+ - ucrt >=10.0.20348.0
+ - vc >=14.3,<15
+ - vc14_runtime >=14.44.35208
+ license: LGPL-3.0-only
+ license_family: LGPL
+ purls:
+ - pkg:pypi/frozendict?source=hash-mapping
+ size: 32072
+ timestamp: 1763082973024
+- conda: https://conda.anaconda.org/conda-forge/linux-64/gcc-14.3.0-h0dff253_18.conda
+ sha256: 9b34b57b06b485e33a40d430f71ac88c8f381673592507cf7161c50ff0832772
+ md5: 52d6457abc42e320787ada5f9033fa99
+ depends:
+ - conda-gcc-specs
+ - gcc_impl_linux-64 14.3.0 hbdf3cc3_18
+ license: BSD-3-Clause
+ license_family: BSD
+ purls: []
+ size: 29506
+ timestamp: 1771378321585
+- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/gcc-14.3.0-h2e72a27_18.conda
+ sha256: debc5c801b3af35f1d474aead8621c4869a022d35ca3c5195a9843d81c1c9ab4
+ md5: db4bf1a70c2481c06fe8174390a325c0
+ depends:
+ - conda-gcc-specs
+ - gcc_impl_linux-aarch64 14.3.0 h533bfc8_18
+ license: BSD-3-Clause
+ license_family: BSD
+ purls: []
+ size: 29438
+ timestamp: 1771378102660
+- conda: https://conda.anaconda.org/conda-forge/linux-64/gcc_impl_linux-64-14.3.0-hbdf3cc3_18.conda
+ sha256: 3b31a273b806c6851e16e9cf63ef87cae28d19be0df148433f3948e7da795592
+ md5: 30bb690150536f622873758b0e8d6712
+ depends:
+ - binutils_impl_linux-64 >=2.45
+ - libgcc >=14.3.0
+ - libgcc-devel_linux-64 14.3.0 hf649bbc_118
+ - libgomp >=14.3.0
+ - libsanitizer 14.3.0 h8f1669f_18
+ - libstdcxx >=14.3.0
+ - libstdcxx-devel_linux-64 14.3.0 h9f08a49_118
+ - sysroot_linux-64
+ license: GPL-3.0-only WITH GCC-exception-3.1
+ license_family: GPL
+ purls: []
+ size: 76302378
+ timestamp: 1771378056505
+- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/gcc_impl_linux-aarch64-14.3.0-h533bfc8_18.conda
+ sha256: e2488aac8472cfdff4f8a893861acd1ce1c66eafb28e7585ec52fe4e7546df7e
+ md5: 2ac1b579c1560e021a4086d0d704e2be
+ depends:
+ - binutils_impl_linux-aarch64 >=2.45
+ - libgcc >=14.3.0
+ - libgcc-devel_linux-aarch64 14.3.0 h25ba3ff_118
+ - libgomp >=14.3.0
+ - libsanitizer 14.3.0 hedb4206_18
+ - libstdcxx >=14.3.0
+ - libstdcxx-devel_linux-aarch64 14.3.0 h57c8d61_118
+ - sysroot_linux-aarch64
+ license: GPL-3.0-only WITH GCC-exception-3.1
+ license_family: GPL
+ purls: []
+ size: 69149627
+ timestamp: 1771377858762
+- conda: https://conda.anaconda.org/conda-forge/linux-64/gcc_linux-64-14.3.0-h298d278_21.conda
+ sha256: 27ad0cd10dccffca74e20fb38c9f8643ff8fce56eee260bf89fa257d5ab0c90a
+ md5: 1403ed5fe091bd7442e4e8a229d14030
+ depends:
+ - gcc_impl_linux-64 14.3.0.*
+ - binutils_linux-64
+ - sysroot_linux-64
+ license: BSD-3-Clause
+ license_family: BSD
+ purls: []
+ size: 28946
+ timestamp: 1770908213807
+- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/gcc_linux-aarch64-14.3.0-h118592a_21.conda
+ sha256: 2b4c579549e63f8f7e29aa332a95b85a5a33976d6caf42d7c3dc147d2939d7a0
+ md5: dfe811f86ef2d8f511263ef38b773a39
+ depends:
+ - gcc_impl_linux-aarch64 14.3.0.*
+ - binutils_linux-aarch64
+ - sysroot_linux-aarch64
+ license: BSD-3-Clause
+ license_family: BSD
+ purls: []
+ size: 28666
+ timestamp: 1770908257439
+- conda: https://conda.anaconda.org/conda-forge/linux-64/gh-2.88.1-h76a2195_0.conda
+ sha256: 78f9fbbf18272e92e62bc1672d34178760ced73edc1e818ebd5fd00296b5df88
+ md5: 0290cdefa20d98adb936c465ccb76ad6
+ depends:
+ - __glibc >=2.17,<3.0.a0
+ license: Apache-2.0
+ license_family: APACHE
+ purls: []
+ size: 22875681
+ timestamp: 1773332470542
+- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/gh-2.88.1-h94b2740_0.conda
+ sha256: bfa267b3a68c629b8d5a3bbb06dc828ba724f68a1e10aa5cc62667cca690d16a
+ md5: e1f7ec5f227660d3e0ce658e9acb3827
+ license: Apache-2.0
+ license_family: APACHE
+ purls: []
+ size: 20986983
+ timestamp: 1773335353762
+- conda: https://conda.anaconda.org/conda-forge/osx-64/gh-2.88.1-hdaada87_0.conda
+ sha256: c587e956e14f06b8517923864410e612c7882bac57cc7f1b5b11398f907362f9
+ md5: af030582e521e76176f9765bd0d623a8
+ depends:
+ - __osx >=11.0
+ constrains:
+ - __osx>=10.12
+ license: Apache-2.0
+ license_family: APACHE
+ purls: []
+ size: 23106117
+ timestamp: 1773333114711
+- conda: https://conda.anaconda.org/conda-forge/osx-arm64/gh-2.88.1-h01237fd_0.conda
+ sha256: ed5ac50ece778e035d7739dc7547023c0391b44d20b98d7ef473b06cbdb5d040
+ md5: 1bb23382c23eae0e52a48bfd4c3cd5e6
+ depends:
+ - __osx >=11.0
+ license: Apache-2.0
+ license_family: APACHE
+ purls: []
+ size: 21742200
+ timestamp: 1773332985739
+- conda: https://conda.anaconda.org/conda-forge/win-64/gh-2.88.1-h36e2d1d_0.conda
+ sha256: b286e07b5aa44db0e4969789da8b27ec62974108efd45900a444b72f32941859
+ md5: 70ee65f0ce705a07b4848aec9ce97014
+ depends:
+ - ucrt >=10.0.20348.0
+ - vc >=14.3,<15
+ - vc14_runtime >=14.44.35208
+ license: Apache-2.0
+ license_family: APACHE
+ purls: []
+ size: 22357323
+ timestamp: 1773332611831
+- conda: https://conda.anaconda.org/conda-forge/win-64/git-2.53.0-h57928b3_0.conda
+ sha256: 6bc7eb1202395c044ff24f175f9f6d594bdc4c620e0cfa9e03ed46ef34c265ba
+ md5: b63e3ad61f7507fc72479ab0dde1a6be
+ license: GPL-2.0-or-later and LGPL-2.1-or-later
+ purls: []
+ size: 123465948
+ timestamp: 1770982612399
+- conda: https://conda.anaconda.org/conda-forge/linux-64/gxx-14.3.0-h76987e4_18.conda
+ sha256: 1b490c9be9669f9c559db7b2a1f7d8b973c58ca0c6f21a5d2ba3f0ab2da63362
+ md5: 19189121d644d4ef75fed05383bc75f5
+ depends:
+ - gcc 14.3.0 h0dff253_18
+ - gxx_impl_linux-64 14.3.0 h2185e75_18
+ license: BSD-3-Clause
+ license_family: BSD
+ purls: []
+ size: 28883
+ timestamp: 1771378355605
+- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/gxx-14.3.0-ha384071_18.conda
+ sha256: 09fb56bcb1594d667e39b1ff4fced377f1b3f6c83f5b651d500db0b4865df68a
+ md5: 3d5380505980f8859a796af4c1b49452
+ depends:
+ - gcc 14.3.0 h2e72a27_18
+ - gxx_impl_linux-aarch64 14.3.0 h0d4f5d4_18
+ license: BSD-3-Clause
+ license_family: BSD
+ purls: []
+ size: 28822
+ timestamp: 1771378129202
+- conda: https://conda.anaconda.org/conda-forge/linux-64/gxx_impl_linux-64-14.3.0-h2185e75_18.conda
+ sha256: 38ffca57cc9c264d461ac2ce9464a9d605e0f606d92d831de9075cb0d95fc68a
+ md5: 6514b3a10e84b6a849e1b15d3753eb22
+ depends:
+ - gcc_impl_linux-64 14.3.0 hbdf3cc3_18
+ - libstdcxx-devel_linux-64 14.3.0 h9f08a49_118
+ - sysroot_linux-64
+ - tzdata
+ license: GPL-3.0-only WITH GCC-exception-3.1
+ license_family: GPL
+ purls: []
+ size: 14566100
+ timestamp: 1771378271421
+- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/gxx_impl_linux-aarch64-14.3.0-h0d4f5d4_18.conda
+ sha256: 859a78ff16bef8d1d1d89d0604929c3c256ac0248b9a688e8defe9bbc027c886
+ md5: a12277d1ec675dbb993ad72dce735530
+ depends:
+ - gcc_impl_linux-aarch64 14.3.0 h533bfc8_18
+ - libstdcxx-devel_linux-aarch64 14.3.0 h57c8d61_118
+ - sysroot_linux-aarch64
+ - tzdata
+ license: GPL-3.0-only WITH GCC-exception-3.1
+ license_family: GPL
+ purls: []
+ size: 13513218
+ timestamp: 1771378064341
+- conda: https://conda.anaconda.org/conda-forge/linux-64/gxx_linux-64-14.3.0-he467f4b_21.conda
+ sha256: 1e07c197e0779fa9105e59cd55a835ded96bfde59eb169439736a89b27b48e5d
+ md5: 7b51f4ff82eeb1f386bfee20a7bed3ed
+ depends:
+ - gxx_impl_linux-64 14.3.0.*
+ - gcc_linux-64 ==14.3.0 h298d278_21
+ - binutils_linux-64
+ - sysroot_linux-64
+ license: BSD-3-Clause
+ license_family: BSD
+ purls: []
+ size: 27503
+ timestamp: 1770908213813
+- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/gxx_linux-aarch64-14.3.0-h32e4f2e_21.conda
+ sha256: 10059135f9960de93f991ce7fb6ef9d833dc2ac675459a1a08def052e5a29667
+ md5: 3114b029596eff0aeb9fc0c81f598211
+ depends:
+ - gxx_impl_linux-aarch64 14.3.0.*
+ - gcc_linux-aarch64 ==14.3.0 h118592a_21
+ - binutils_linux-aarch64
+ - sysroot_linux-aarch64
+ license: BSD-3-Clause
+ license_family: BSD
+ purls: []
+ size: 27275
+ timestamp: 1770908257444
+- conda: https://conda.anaconda.org/conda-forge/noarch/h2-4.3.0-pyhcf101f3_0.conda
+ sha256: 84c64443368f84b600bfecc529a1194a3b14c3656ee2e832d15a20e0329b6da3
+ md5: 164fc43f0b53b6e3a7bc7dce5e4f1dc9
+ depends:
+ - python >=3.10
+ - hyperframe >=6.1,<7
+ - hpack >=4.1,<5
+ - python
+ license: MIT
+ license_family: MIT
+ purls:
+ - pkg:pypi/h2?source=hash-mapping
+ size: 95967
+ timestamp: 1756364871835
+- conda: https://conda.anaconda.org/conda-forge/noarch/hpack-4.1.0-pyhd8ed1ab_0.conda
+ sha256: 6ad78a180576c706aabeb5b4c8ceb97c0cb25f1e112d76495bff23e3779948ba
+ md5: 0a802cb9888dd14eeefc611f05c40b6e
+ depends:
+ - python >=3.9
+ license: MIT
+ license_family: MIT
+ purls:
+ - pkg:pypi/hpack?source=hash-mapping
+ size: 30731
+ timestamp: 1737618390337
+- conda: https://conda.anaconda.org/conda-forge/noarch/hyperframe-6.1.0-pyhd8ed1ab_0.conda
+ sha256: 77af6f5fe8b62ca07d09ac60127a30d9069fdc3c68d6b256754d0ffb1f7779f8
+ md5: 8e6923fc12f1fe8f8c4e5c9f343256ac
+ depends:
+ - python >=3.9
+ license: MIT
+ license_family: MIT
+ purls:
+ - pkg:pypi/hyperframe?source=hash-mapping
+ size: 17397
+ timestamp: 1737618427549
+- conda: https://conda.anaconda.org/conda-forge/linux-64/icu-78.2-h33c6efd_0.conda
+ sha256: 142a722072fa96cf16ff98eaaf641f54ab84744af81754c292cb81e0881c0329
+ md5: 186a18e3ba246eccfc7cff00cd19a870
+ depends:
+ - __glibc >=2.17,<3.0.a0
+ - libgcc >=14
+ - libstdcxx >=14
+ license: MIT
+ license_family: MIT
+ purls: []
+ size: 12728445
+ timestamp: 1767969922681
+- conda: https://conda.anaconda.org/conda-forge/linux-64/icu-78.3-h33c6efd_0.conda
+ sha256: fbf86c4a59c2ed05bbffb2ba25c7ed94f6185ec30ecb691615d42342baa1a16a
+ md5: c80d8a3b84358cb967fa81e7075fbc8a
+ depends:
+ - __glibc >=2.17,<3.0.a0
+ - libgcc >=14
+ - libstdcxx >=14
+ license: MIT
+ license_family: MIT
+ purls: []
+ size: 12723451
+ timestamp: 1773822285671
+- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/icu-78.2-hcab7f73_0.conda
+ sha256: dcbaa3042084ac58685e3ef4547e4c4be9d37dc52b92ea18581288af95e48b52
+ md5: 998ee7d53e32f7ab57fc35707285527e
+ depends:
+ - libgcc >=14
+ - libstdcxx >=14
+ license: MIT
+ license_family: MIT
+ purls: []
+ size: 12851689
+ timestamp: 1772208964788
+- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/icu-78.3-hcab7f73_0.conda
+ sha256: 49ba6aed2c6b482bb0ba41078057555d29764299bc947b990708617712ef6406
+ md5: 546da38c2fa9efacf203e2ad3f987c59
+ depends:
+ - libgcc >=14
+ - libstdcxx >=14
+ license: MIT
+ license_family: MIT
+ purls: []
+ size: 12837286
+ timestamp: 1773822650615
+- conda: https://conda.anaconda.org/conda-forge/osx-64/icu-73.2-hf5e326d_0.conda
+ sha256: f66362dc36178ac9b7c7a9b012948a9d2d050b3debec24bbd94aadbc44854185
+ md5: 5cc301d759ec03f28328428e28f65591
+ license: MIT
+ license_family: MIT
+ purls: []
+ size: 11787527
+ timestamp: 1692901622519
+- conda: https://conda.anaconda.org/conda-forge/osx-64/icu-78.2-h14c5de8_0.conda
+ sha256: f3066beae7fe3002f09c8a412cdf1819f49a2c9a485f720ec11664330cf9f1fe
+ md5: 30334add4de016489b731c6662511684
+ depends:
+ - __osx >=10.13
+ license: MIT
+ license_family: MIT
+ size: 12263724
+ timestamp: 1767970604977
+- conda: https://conda.anaconda.org/conda-forge/osx-64/icu-78.3-h25d91c4_0.conda
+ sha256: 1294117122d55246bb83ad5b589e2a031aacdf2d0b1f99fd338aa4394f881735
+ md5: 627eca44e62e2b665eeec57a984a7f00
+ depends:
+ - __osx >=11.0
+ license: MIT
+ license_family: MIT
+ purls: []
+ size: 12273764
+ timestamp: 1773822733780
+- conda: https://conda.anaconda.org/conda-forge/osx-arm64/icu-73.2-hc8870d7_0.conda
+ sha256: ff9cd0c6cd1349954c801fb443c94192b637e1b414514539f3c49c56a39f51b1
+ md5: 8521bd47c0e11c5902535bb1a17c565f
+ license: MIT
+ license_family: MIT
+ purls: []
+ size: 11997841
+ timestamp: 1692902104771
+- conda: https://conda.anaconda.org/conda-forge/osx-arm64/icu-78.2-hef89b57_0.conda
+ sha256: 24bc62335106c30fecbcc1dba62c5eba06d18b90ea1061abd111af7b9c89c2d7
+ md5: 114e6bfe7c5ad2525eb3597acdbf2300
+ depends:
+ - __osx >=11.0
+ license: MIT
+ license_family: MIT
+ size: 12389400
+ timestamp: 1772209104304
+- conda: https://conda.anaconda.org/conda-forge/osx-arm64/icu-78.3-hef89b57_0.conda
+ sha256: 3a7907a17e9937d3a46dfd41cffaf815abad59a569440d1e25177c15fd0684e5
+ md5: f1182c91c0de31a7abd40cedf6a5ebef
+ depends:
+ - __osx >=11.0
+ license: MIT
+ license_family: MIT
+ purls: []
+ size: 12361647
+ timestamp: 1773822915649
+- pypi: https://files.pythonhosted.org/packages/42/77/de194443bf38daed9452139e960c632b0ef9f9a5dd9ce605fdf18ca9f1b1/id-1.6.1-py3-none-any.whl
+ name: id
+ version: 1.6.1
+ sha256: f5ec41ed2629a508f5d0988eda142e190c9c6da971100612c4de9ad9f9b237ca
+ requires_dist:
+ - urllib3>=2,<3
+ - build ; extra == 'dev'
+ - bump>=1.3.2 ; extra == 'dev'
+ - id[test,lint] ; extra == 'dev'
+ - bandit ; extra == 'lint'
+ - interrogate ; extra == 'lint'
+ - mypy ; extra == 'lint'
+ - ruff<0.14.15 ; extra == 'lint'
+ - pytest ; extra == 'test'
+ - pytest-cov ; extra == 'test'
+ - pretend ; extra == 'test'
+ - coverage[toml] ; extra == 'test'
+ requires_python: '>=3.9'
+- conda: https://conda.anaconda.org/conda-forge/noarch/identify-2.6.18-pyhd8ed1ab_0.conda
+ sha256: 3bae1b612ccc71e49c5795a369a82c4707ae6fd4e63360e8ecc129f9539f779b
+ md5: 635d1a924e1c55416fce044ed96144a2
+ depends:
+ - python >=3.10
+ - ukkonen
+ license: MIT
+ license_family: MIT
+ purls:
+ - pkg:pypi/identify?source=hash-mapping
+ size: 79749
+ timestamp: 1774239544252
+- conda: https://conda.anaconda.org/conda-forge/noarch/idna-3.11-pyhd8ed1ab_0.conda
+ sha256: ae89d0299ada2a3162c2614a9d26557a92aa6a77120ce142f8e0109bbf0342b0
+ md5: 53abe63df7e10a6ba605dc5f9f961d36
+ depends:
+ - python >=3.10
+ license: BSD-3-Clause
+ license_family: BSD
+ purls:
+ - pkg:pypi/idna?source=hash-mapping
+ size: 50721
+ timestamp: 1760286526795
+- conda: https://conda.anaconda.org/conda-forge/noarch/importlib-metadata-8.7.0-pyhe01879c_1.conda
+ sha256: c18ab120a0613ada4391b15981d86ff777b5690ca461ea7e9e49531e8f374745
+ md5: 63ccfdc3a3ce25b027b8767eb722fca8
+ depends:
+ - python >=3.9
+ - zipp >=3.20
+ - python
+ license: Apache-2.0
+ license_family: APACHE
+ purls:
+ - pkg:pypi/importlib-metadata?source=hash-mapping
+ size: 34641
+ timestamp: 1747934053147
+- conda: https://conda.anaconda.org/conda-forge/noarch/importlib-metadata-8.8.0-pyhcf101f3_0.conda
+ sha256: 82ab2a0d91ca1e7e63ab6a4939356667ef683905dea631bc2121aa534d347b16
+ md5: 080594bf4493e6bae2607e65390c520a
+ depends:
+ - python >=3.10
+ - zipp >=3.20
+ - python
+ license: Apache-2.0
+ license_family: APACHE
+ purls:
+ - pkg:pypi/importlib-metadata?source=compressed-mapping
+ size: 34387
+ timestamp: 1773931568510
+- conda: https://conda.anaconda.org/conda-forge/noarch/importlib-resources-6.5.2-pyhd8ed1ab_0.conda
+ sha256: a99a3dafdfff2bb648d2b10637c704400295cb2ba6dc929e2d814870cf9f6ae5
+ md5: e376ea42e9ae40f3278b0f79c9bf9826
+ depends:
+ - importlib_resources >=6.5.2,<6.5.3.0a0
+ - python >=3.9
+ license: Apache-2.0
+ license_family: APACHE
+ purls: []
+ size: 9724
+ timestamp: 1736252443859
+- conda: https://conda.anaconda.org/conda-forge/noarch/importlib_resources-6.5.2-pyhd8ed1ab_0.conda
+ sha256: acc1d991837c0afb67c75b77fdc72b4bf022aac71fedd8b9ea45918ac9b08a80
+ md5: c85c76dc67d75619a92f51dfbce06992
+ depends:
+ - python >=3.9
+ - zipp >=3.1.0
+ constrains:
+ - importlib-resources >=6.5.2,<6.5.3.0a0
+ license: Apache-2.0
+ license_family: APACHE
+ purls:
+ - pkg:pypi/importlib-resources?source=hash-mapping
+ size: 33781
+ timestamp: 1736252433366
+- pypi: https://files.pythonhosted.org/packages/7f/66/b15ce62552d84bbfcec9a4873ab79d993a1dd4edb922cbfccae192bd5b5f/jaraco.classes-3.4.0-py3-none-any.whl
+ name: jaraco-classes
+ version: 3.4.0
+ sha256: f662826b6bed8cace05e7ff873ce0f9283b5c924470fe664fff1c2f00f581790
+ requires_dist:
+ - more-itertools
+ - sphinx>=3.5 ; extra == 'docs'
+ - jaraco-packaging>=9.3 ; extra == 'docs'
+ - rst-linker>=1.9 ; extra == 'docs'
+ - furo ; extra == 'docs'
+ - sphinx-lint ; extra == 'docs'
+ - jaraco-tidelift>=1.4 ; extra == 'docs'
+ - pytest>=6 ; extra == 'testing'
+ - pytest-checkdocs>=2.4 ; extra == 'testing'
+ - pytest-cov ; extra == 'testing'
+ - pytest-mypy ; extra == 'testing'
+ - pytest-enabler>=2.2 ; extra == 'testing'
+ - pytest-ruff>=0.2.1 ; extra == 'testing'
+ requires_python: '>=3.8'
+- pypi: https://files.pythonhosted.org/packages/f2/58/bc8954bda5fcda97bd7c19be11b85f91973d67a706ed4a3aec33e7de22db/jaraco_context-6.1.2-py3-none-any.whl
+ name: jaraco-context
+ version: 6.1.2
+ sha256: bf8150b79a2d5d91ae48629d8b427a8f7ba0e1097dd6202a9059f29a36379535
+ requires_dist:
+ - backports-tarfile ; python_full_version < '3.12'
+ - pytest>=6,!=8.1.* ; extra == 'test'
+ - jaraco-test>=5.6.0 ; extra == 'test'
+ - portend ; extra == 'test'
+ - sphinx>=3.5 ; extra == 'doc'
+ - jaraco-packaging>=9.3 ; extra == 'doc'
+ - rst-linker>=1.9 ; extra == 'doc'
+ - furo ; extra == 'doc'
+ - sphinx-lint ; extra == 'doc'
+ - jaraco-tidelift>=1.4 ; extra == 'doc'
+ - pytest-checkdocs>=2.14 ; extra == 'check'
+ - pytest-ruff>=0.2.1 ; sys_platform != 'cygwin' and extra == 'check'
+ - pytest-cov ; extra == 'cover'
+ - pytest-enabler>=3.4 ; extra == 'enabler'
+ - pytest-mypy>=1.0.1 ; platform_python_implementation != 'PyPy' and extra == 'type'
+ requires_python: '>=3.10'
+- pypi: https://files.pythonhosted.org/packages/fd/c4/813bb09f0985cb21e959f21f2464169eca882656849adf727ac7bb7e1767/jaraco_functools-4.4.0-py3-none-any.whl
+ name: jaraco-functools
+ version: 4.4.0
+ sha256: 9eec1e36f45c818d9bf307c8948eb03b2b56cd44087b3cdc989abca1f20b9176
+ requires_dist:
+ - more-itertools
+ - pytest>=6,!=8.1.* ; extra == 'test'
+ - jaraco-classes ; extra == 'test'
+ - sphinx>=3.5 ; extra == 'doc'
+ - jaraco-packaging>=9.3 ; extra == 'doc'
+ - rst-linker>=1.9 ; extra == 'doc'
+ - furo ; extra == 'doc'
+ - sphinx-lint ; extra == 'doc'
+ - jaraco-tidelift>=1.4 ; extra == 'doc'
+ - pytest-checkdocs>=2.4 ; extra == 'check'
+ - pytest-ruff>=0.2.1 ; sys_platform != 'cygwin' and extra == 'check'
+ - pytest-cov ; extra == 'cover'
+ - pytest-enabler>=3.4 ; extra == 'enabler'
+ - pytest-mypy>=1.0.1 ; extra == 'type'
+ - mypy<1.19 ; platform_python_implementation == 'PyPy' and extra == 'type'
+ requires_python: '>=3.9'
+- pypi: https://files.pythonhosted.org/packages/b2/a3/e137168c9c44d18eff0376253da9f1e9234d0239e0ee230d2fee6cea8e55/jeepney-0.9.0-py3-none-any.whl
+ name: jeepney
+ version: 0.9.0
+ sha256: 97e5714520c16fc0a45695e5365a2e11b81ea79bba796e26f9f1d178cb182683
+ requires_dist:
+ - pytest ; extra == 'test'
+ - pytest-trio ; extra == 'test'
+ - pytest-asyncio>=0.17 ; extra == 'test'
+ - testpath ; extra == 'test'
+ - trio ; extra == 'test'
+ - async-timeout ; python_full_version < '3.11' and extra == 'test'
+ - trio ; extra == 'trio'
+ requires_python: '>=3.7'
+- conda: https://conda.anaconda.org/conda-forge/noarch/jsonpatch-1.33-pyhd8ed1ab_1.conda
+ sha256: 304955757d1fedbe344af43b12b5467cca072f83cce6109361ba942e186b3993
+ md5: cb60ae9cf02b9fcb8004dec4089e5691
+ depends:
+ - jsonpointer >=1.9
+ - python >=3.9
+ license: BSD-3-Clause
+ license_family: BSD
+ purls:
+ - pkg:pypi/jsonpatch?source=hash-mapping
+ size: 17311
+ timestamp: 1733814664790
+- conda: https://conda.anaconda.org/conda-forge/noarch/jsonpointer-3.0.0-pyhcf101f3_3.conda
+ sha256: 1a1328476d14dfa8b84dbacb7f7cd7051c175498406dc513ca6c679dc44f3981
+ md5: cd2214824e36b0180141d422aba01938
+ depends:
+ - python >=3.10
+ - python
+ license: BSD-3-Clause
+ license_family: BSD
+ purls:
+ - pkg:pypi/jsonpointer?source=hash-mapping
+ size: 13967
+ timestamp: 1765026384757
+- conda: https://conda.anaconda.org/conda-forge/noarch/jsonpointer-3.1.1-pyhcf101f3_0.conda
+ sha256: a3d10301b6ff399ba1f3d39e443664804a3d28315a4fb81e745b6817845f70ae
+ md5: 89bf346df77603055d3c8fe5811691e6
+ depends:
+ - python >=3.10
+ - python
+ license: BSD-3-Clause
+ license_family: BSD
+ purls:
+ - pkg:pypi/jsonpointer?source=compressed-mapping
+ size: 14190
+ timestamp: 1774311356147
+- conda: https://conda.anaconda.org/conda-forge/noarch/kernel-headers_linux-64-4.18.0-he073ed8_9.conda
+ sha256: 41557eeadf641de6aeae49486cef30d02a6912d8da98585d687894afd65b356a
+ md5: 86d9cba083cd041bfbf242a01a7a1999
+ constrains:
+ - sysroot_linux-64 ==2.28
+ license: LGPL-2.0-or-later AND LGPL-2.0-or-later WITH exceptions AND GPL-2.0-or-later
+ license_family: GPL
+ purls: []
+ size: 1278712
+ timestamp: 1765578681495
+- conda: https://conda.anaconda.org/conda-forge/noarch/kernel-headers_linux-aarch64-4.18.0-h05a177a_9.conda
+ sha256: 5d224bf4df9bac24e69de41897c53756108c5271a0e5d2d2f66fd4e2fbc1d84b
+ md5: bb3b7cad9005f2cbf9d169fb30263f3e
+ constrains:
+ - sysroot_linux-aarch64 ==2.28
+ license: LGPL-2.0-or-later AND LGPL-2.0-or-later WITH exceptions AND GPL-2.0-or-later
+ license_family: GPL
+ purls: []
+ size: 1248134
+ timestamp: 1765578613607
+- pypi: https://files.pythonhosted.org/packages/81/db/e655086b7f3a705df045bf0933bdd9c2f79bb3c97bfef1384598bb79a217/keyring-25.7.0-py3-none-any.whl
+ name: keyring
+ version: 25.7.0
+ sha256: be4a0b195f149690c166e850609a477c532ddbfbaed96a404d4e43f8d5e2689f
+ requires_dist:
+ - pywin32-ctypes>=0.2.0 ; sys_platform == 'win32'
+ - secretstorage>=3.2 ; sys_platform == 'linux'
+ - jeepney>=0.4.2 ; sys_platform == 'linux'
+ - importlib-metadata>=4.11.4 ; python_full_version < '3.12'
+ - jaraco-classes
+ - jaraco-functools
+ - jaraco-context
+ - pytest>=6,!=8.1.* ; extra == 'test'
+ - pyfakefs ; extra == 'test'
+ - sphinx>=3.5 ; extra == 'doc'
+ - jaraco-packaging>=9.3 ; extra == 'doc'
+ - rst-linker>=1.9 ; extra == 'doc'
+ - furo ; extra == 'doc'
+ - sphinx-lint ; extra == 'doc'
+ - jaraco-tidelift>=1.4 ; extra == 'doc'
+ - pytest-checkdocs>=2.4 ; extra == 'check'
+ - pytest-ruff>=0.2.1 ; sys_platform != 'cygwin' and extra == 'check'
+ - pytest-cov ; extra == 'cover'
+ - pytest-enabler>=3.4 ; extra == 'enabler'
+ - pytest-mypy>=1.0.1 ; extra == 'type'
+ - pygobject-stubs ; extra == 'type'
+ - shtab ; extra == 'type'
+ - types-pywin32 ; extra == 'type'
+ - shtab>=1.1.0 ; extra == 'completion'
+ requires_python: '>=3.9'
+- conda: https://conda.anaconda.org/conda-forge/linux-64/keyutils-1.6.3-hb9d3cd8_0.conda
+ sha256: 0960d06048a7185d3542d850986d807c6e37ca2e644342dd0c72feefcf26c2a4
+ md5: b38117a3c920364aff79f870c984b4a3
+ depends:
+ - __glibc >=2.17,<3.0.a0
+ - libgcc >=13
+ license: LGPL-2.1-or-later
+ purls: []
+ size: 134088
+ timestamp: 1754905959823
+- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/keyutils-1.6.3-h86ecc28_0.conda
+ sha256: 5ce830ca274b67de11a7075430a72020c1fb7d486161a82839be15c2b84e9988
+ md5: e7df0aab10b9cbb73ab2a467ebfaf8c7
+ depends:
+ - libgcc >=13
+ license: LGPL-2.1-or-later
+ purls: []
+ size: 129048
+ timestamp: 1754906002667
+- conda: https://conda.anaconda.org/conda-forge/linux-64/krb5-1.22.2-ha1258a1_0.conda
+ sha256: 3e307628ca3527448dd1cb14ad7bb9d04d1d28c7d4c5f97ba196ae984571dd25
+ md5: fb53fb07ce46a575c5d004bbc96032c2
+ depends:
+ - __glibc >=2.17,<3.0.a0
+ - keyutils >=1.6.3,<2.0a0
+ - libedit >=3.1.20250104,<3.2.0a0
+ - libedit >=3.1.20250104,<4.0a0
+ - libgcc >=14
+ - libstdcxx >=14
+ - openssl >=3.5.5,<4.0a0
+ license: MIT
+ license_family: MIT
+ purls: []
+ size: 1386730
+ timestamp: 1769769569681
+- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/krb5-1.22.2-hfd895c2_0.conda
+ sha256: b53999d888dda53c506b264e8c02b5f5c8e022c781eda0718f007339e6bc90ba
+ md5: d9ca108bd680ea86a963104b6b3e95ca
+ depends:
+ - keyutils >=1.6.3,<2.0a0
+ - libedit >=3.1.20250104,<3.2.0a0
+ - libedit >=3.1.20250104,<4.0a0
+ - libgcc >=14
+ - libstdcxx >=14
+ - openssl >=3.5.5,<4.0a0
+ license: MIT
+ license_family: MIT
+ purls: []
+ size: 1517436
+ timestamp: 1769773395215
+- conda: https://conda.anaconda.org/conda-forge/osx-64/krb5-1.21.2-hb884880_0.conda
+ sha256: 081ae2008a21edf57c048f331a17c65d1ccb52d6ca2f87ee031a73eff4dc0fc6
+ md5: 80505a68783f01dc8d7308c075261b2f
+ depends:
+ - libcxx >=15.0.7
+ - libedit >=3.1.20191231,<3.2.0a0
+ - libedit >=3.1.20191231,<4.0a0
+ - openssl >=3.1.2,<4.0a0
+ license: MIT
+ license_family: MIT
+ purls: []
+ size: 1183568
+ timestamp: 1692098004387
+- conda: https://conda.anaconda.org/conda-forge/osx-64/krb5-1.22.2-h207b36a_0.conda
+ sha256: df009385e8262c234c0dae9016540b86dad3d299f0d9366d08e327e8e7731634
+ md5: e66e2c52d2fdddcf314ad750fb4ebb4a
+ depends:
+ - __osx >=10.13
+ - libcxx >=19
+ - libedit >=3.1.20250104,<3.2.0a0
+ - libedit >=3.1.20250104,<4.0a0
+ - openssl >=3.5.5,<4.0a0
+ license: MIT
+ license_family: MIT
+ purls: []
+ size: 1193620
+ timestamp: 1769770267475
+- conda: https://conda.anaconda.org/conda-forge/osx-arm64/krb5-1.21.2-h92f50d5_0.conda
+ sha256: 70bdb9b4589ec7c7d440e485ae22b5a352335ffeb91a771d4c162996c3070875
+ md5: 92f1cff174a538e0722bf2efb16fc0b2
+ depends:
+ - libcxx >=15.0.7
+ - libedit >=3.1.20191231,<3.2.0a0
+ - libedit >=3.1.20191231,<4.0a0
+ - openssl >=3.1.2,<4.0a0
+ license: MIT
+ license_family: MIT
+ purls: []
+ size: 1195575
+ timestamp: 1692098070699
+- conda: https://conda.anaconda.org/conda-forge/osx-arm64/krb5-1.22.2-h385eeb1_0.conda
+ sha256: c0a0bf028fe7f3defcdcaa464e536cf1b202d07451e18ad83fdd169d15bef6ed
+ md5: e446e1822f4da8e5080a9de93474184d
+ depends:
+ - __osx >=11.0
+ - libcxx >=19
+ - libedit >=3.1.20250104,<3.2.0a0
+ - libedit >=3.1.20250104,<4.0a0
+ - openssl >=3.5.5,<4.0a0
+ license: MIT
+ license_family: MIT
+ purls: []
+ size: 1160828
+ timestamp: 1769770119811
+- conda: https://conda.anaconda.org/conda-forge/win-64/krb5-1.22.2-h0ea6238_0.conda
+ sha256: eb60f1ad8b597bcf95dee11bc11fe71a8325bc1204cf51d2bb1f2120ffd77761
+ md5: 4432f52dc0c8eb6a7a6abc00a037d93c
+ depends:
+ - openssl >=3.5.5,<4.0a0
+ - ucrt >=10.0.20348.0
+ - vc >=14.3,<15
+ - vc14_runtime >=14.44.35208
+ license: MIT
+ license_family: MIT
+ purls: []
+ size: 751055
+ timestamp: 1769769688841
+- conda: https://conda.anaconda.org/conda-forge/osx-64/ld64-711-h4e51db5_0.conda
+ sha256: 230be4e751f17fa1ccc15066086d1726d1d223e98f8337f435b4472bfe00436b
+ md5: cc84dae1a60ee59f6098f93b76d74b60
+ depends:
+ - ld64_osx-64 711 had5d0d3_0
+ - libllvm18 >=18.1.1,<18.2.0a0
+ constrains:
+ - cctools_osx-64 986.*
+ - cctools 986.*
+ license: APSL-2.0
+ license_family: Other
+ purls: []
+ size: 18568
+ timestamp: 1710484499499
+- conda: https://conda.anaconda.org/conda-forge/osx-arm64/ld64-711-h4c6efb1_0.conda
+ sha256: 467371e8dbd4fc99f507024c3d10c0ac4a8528286e9507a1f365e26cb90f4df0
+ md5: 289df626863e8c720c3aa220964378cc
+ depends:
+ - ld64_osx-arm64 711 h5e7191b_0
+ - libllvm18 >=18.1.1,<18.2.0a0
+ constrains:
+ - cctools 986.*
+ - cctools_osx-arm64 986.*
+ license: APSL-2.0
+ license_family: Other
+ purls: []
+ size: 18678
+ timestamp: 1710484665887
+- conda: https://conda.anaconda.org/conda-forge/osx-64/ld64_osx-64-711-had5d0d3_0.conda
+ sha256: 14d3fd593a7fd1cc472167dc00fd1d3176b8ce9dfc9b9d003359ecde4ded7459
+ md5: cb63e1d1e11a1fffad54333330486ddd
+ depends:
+ - libcxx
+ - libllvm18 >=18.1.1,<18.2.0a0
+ - sigtool
+ - tapi >=1100.0.11,<1101.0a0
+ constrains:
+ - cctools_osx-64 986.*
+ - ld 711.*
+ - cctools 986.*
+ - clang >=18.1.1,<19.0a0
+ license: APSL-2.0
+ license_family: Other
+ purls: []
+ size: 1071472
+ timestamp: 1710484364960
+- conda: https://conda.anaconda.org/conda-forge/osx-arm64/ld64_osx-arm64-711-h5e7191b_0.conda
+ sha256: 82f964dcff2052b327762ca44651407451ad396a1540c664928841c72b7cf3c0
+ md5: c751b76ae8112e3d516831063da179cc
+ depends:
+ - libcxx
+ - libllvm18 >=18.1.1,<18.2.0a0
+ - sigtool
+ - tapi >=1100.0.11,<1101.0a0
+ constrains:
+ - ld 711.*
+ - cctools 986.*
+ - cctools_osx-arm64 986.*
+ - clang >=18.1.1,<19.0a0
+ license: APSL-2.0
+ license_family: Other
+ purls: []
+ size: 1064448
+ timestamp: 1710484550965
+- conda: https://conda.anaconda.org/conda-forge/linux-64/ld_impl_linux-64-2.45.1-default_hbd61a6d_101.conda
+ sha256: 565941ac1f8b0d2f2e8f02827cbca648f4d18cd461afc31f15604cd291b5c5f3
+ md5: 12bd9a3f089ee6c9266a37dab82afabd
+ depends:
+ - __glibc >=2.17,<3.0.a0
+ - zstd >=1.5.7,<1.6.0a0
+ constrains:
+ - binutils_impl_linux-64 2.45.1
+ license: GPL-3.0-only
+ license_family: GPL
+ purls: []
+ size: 725507
+ timestamp: 1770267139900
+- conda: https://conda.anaconda.org/conda-forge/linux-64/ld_impl_linux-64-2.45.1-default_hbd61a6d_102.conda
+ sha256: 3d584956604909ff5df353767f3a2a2f60e07d070b328d109f30ac40cd62df6c
+ md5: 18335a698559cdbcd86150a48bf54ba6
+ depends:
+ - __glibc >=2.17,<3.0.a0
+ - zstd >=1.5.7,<1.6.0a0
+ constrains:
+ - binutils_impl_linux-64 2.45.1
+ license: GPL-3.0-only
+ license_family: GPL
+ purls: []
+ size: 728002
+ timestamp: 1774197446916
+- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/ld_impl_linux-aarch64-2.45.1-default_h1979696_101.conda
+ sha256: 44527364aa333be631913451c32eb0cae1e09343827e9ce3ccabd8d962584226
+ md5: 35b2ae7fadf364b8e5fb8185aaeb80e5
+ depends:
+ - zstd >=1.5.7,<1.6.0a0
+ constrains:
+ - binutils_impl_linux-aarch64 2.45.1
+ license: GPL-3.0-only
+ license_family: GPL
+ purls: []
+ size: 875924
+ timestamp: 1770267209884
+- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/ld_impl_linux-aarch64-2.45.1-default_h1979696_102.conda
+ sha256: 7abd913d81a9bf00abb699e8987966baa2065f5132e37e815f92d90fc6bba530
+ md5: a21644fc4a83da26452a718dc9468d5f
+ depends:
+ - zstd >=1.5.7,<1.6.0a0
+ constrains:
+ - binutils_impl_linux-aarch64 2.45.1
+ license: GPL-3.0-only
+ license_family: GPL
+ purls: []
+ size: 875596
+ timestamp: 1774197520746
+- conda: https://conda.anaconda.org/conda-forge/linux-64/libarchive-3.8.6-gpl_hc2c16d8_100.conda
+ sha256: 69ea8da58658ad26cb64fb0bfccd8a3250339811f0b57c6b8a742e5e51bacf70
+ md5: 981d372c31a23e1aa9965d4e74d085d5
+ depends:
+ - __glibc >=2.17,<3.0.a0
+ - bzip2 >=1.0.8,<2.0a0
+ - libgcc >=14
+ - liblzma >=5.8.2,<6.0a0
+ - libxml2
+ - libxml2-16 >=2.14.6
+ - libzlib >=1.3.1,<2.0a0
+ - lz4-c >=1.10.0,<1.11.0a0
+ - lzo >=2.10,<3.0a0
+ - openssl >=3.5.5,<4.0a0
+ - zstd >=1.5.7,<1.6.0a0
+ license: BSD-2-Clause
+ license_family: BSD
+ purls: []
+ size: 887139
+ timestamp: 1773243188979
+- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libarchive-3.8.6-gpl_hbe7d12b_100.conda
+ sha256: 635a78a04461e82150263ee9a1fbf6c965de0b811a10e87392a1e44be1115a39
+ md5: f2c45cbb67fd0f668a1a0c152b70dc5f
+ depends:
+ - bzip2 >=1.0.8,<2.0a0
+ - libgcc >=14
+ - liblzma >=5.8.2,<6.0a0
+ - libxml2
+ - libxml2-16 >=2.14.6
+ - libzlib >=1.3.1,<2.0a0
+ - lz4-c >=1.10.0,<1.11.0a0
+ - lzo >=2.10,<3.0a0
+ - openssl >=3.5.5,<4.0a0
+ - zstd >=1.5.7,<1.6.0a0
+ license: BSD-2-Clause
+ license_family: BSD
+ purls: []
+ size: 1000663
+ timestamp: 1773243230880
+- conda: https://conda.anaconda.org/conda-forge/osx-64/libarchive-3.8.6-gpl_h2bf6321_100.conda
+ sha256: 54a4e32132d45557e5f79ec88e4ab951c36fbd8acf256949121656c9f6979998
+ md5: b69c2c71c786c9fd1524e69072e96bc7
+ depends:
+ - __osx >=11.0
+ - bzip2 >=1.0.8,<2.0a0
+ - libiconv >=1.18,<2.0a0
+ - liblzma >=5.8.2,<6.0a0
+ - libxml2
+ - libxml2-16 >=2.14.6
+ - libzlib >=1.3.1,<2.0a0
+ - lz4-c >=1.10.0,<1.11.0a0
+ - lzo >=2.10,<3.0a0
+ - openssl >=3.5.5,<4.0a0
+ - zstd >=1.5.7,<1.6.0a0
+ license: BSD-2-Clause
+ license_family: BSD
+ purls: []
+ size: 761501
+ timestamp: 1773243700449
+- conda: https://conda.anaconda.org/conda-forge/osx-arm64/libarchive-3.8.6-gpl_h6fbacd7_100.conda
+ sha256: 57fcc5cb6203cb0e119f46be708c8b2cf2bae47dc7580e5b4e76bd4b4c6d164a
+ md5: 4133c0cef1c6a25426b35f790e006648
+ depends:
+ - __osx >=11.0
+ - bzip2 >=1.0.8,<2.0a0
+ - libiconv >=1.18,<2.0a0
+ - liblzma >=5.8.2,<6.0a0
+ - libxml2
+ - libxml2-16 >=2.14.6
+ - libzlib >=1.3.1,<2.0a0
+ - lz4-c >=1.10.0,<1.11.0a0
+ - lzo >=2.10,<3.0a0
+ - openssl >=3.5.5,<4.0a0
+ - zstd >=1.5.7,<1.6.0a0
+ license: BSD-2-Clause
+ license_family: BSD
+ purls: []
+ size: 791560
+ timestamp: 1773243648871
+- conda: https://conda.anaconda.org/conda-forge/win-64/libarchive-3.8.6-gpl_he24518a_100.conda
+ sha256: 0cc7f963d689fcadc0f7e83eb1f538ea73543af92e2b988d552a3d12cceb56e6
+ md5: c76cc84cfafa74e43d8951db29983ebb
+ depends:
+ - bzip2 >=1.0.8,<2.0a0
+ - liblzma >=5.8.2,<6.0a0
+ - libxml2
+ - libxml2-16 >=2.14.6
+ - libzlib >=1.3.1,<2.0a0
+ - lz4-c >=1.10.0,<1.11.0a0
+ - lzo >=2.10,<3.0a0
+ - openssl >=3.5.5,<4.0a0
+ - ucrt >=10.0.20348.0
+ - vc >=14.3,<15
+ - vc14_runtime >=14.44.35208
+ - zstd >=1.5.7,<1.6.0a0
+ license: BSD-2-Clause
+ license_family: BSD
+ purls: []
+ size: 1106665
+ timestamp: 1773243755298
+- conda: https://conda.anaconda.org/conda-forge/linux-64/libblas-3.11.0-5_h4a7cf45_openblas.conda
+ build_number: 5
+ sha256: 18c72545080b86739352482ba14ba2c4815e19e26a7417ca21a95b76ec8da24c
+ md5: c160954f7418d7b6e87eaf05a8913fa9
+ depends:
+ - libopenblas >=0.3.30,<0.3.31.0a0
+ - libopenblas >=0.3.30,<1.0a0
+ constrains:
+ - mkl <2026
+ - liblapack 3.11.0 5*_openblas
+ - libcblas 3.11.0 5*_openblas
+ - blas 2.305 openblas
+ - liblapacke 3.11.0 5*_openblas
+ license: BSD-3-Clause
+ license_family: BSD
+ purls: []
+ size: 18213
+ timestamp: 1765818813880
+- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libblas-3.11.0-5_haddc8a3_openblas.conda
+ build_number: 5
+ sha256: 700f3c03d0fba8e687a345404a45fbabe781c1cf92242382f62cef2948745ec4
+ md5: 5afcea37a46f76ec1322943b3c4dfdc0
+ depends:
+ - libopenblas >=0.3.30,<0.3.31.0a0
+ - libopenblas >=0.3.30,<1.0a0
+ constrains:
+ - mkl <2026
+ - libcblas 3.11.0 5*_openblas
+ - liblapack 3.11.0 5*_openblas
+ - liblapacke 3.11.0 5*_openblas
+ - blas 2.305 openblas
+ license: BSD-3-Clause
+ license_family: BSD
+ purls: []
+ size: 18369
+ timestamp: 1765818610617
+- conda: https://conda.anaconda.org/conda-forge/osx-64/libblas-3.9.0-22_osx64_openblas.conda
+ build_number: 22
+ sha256: d72060239f904b3a81d2329efcf84dc62c2dfd66dbc4efc8dcae1afdf8f02b59
+ md5: b80966a8c8dd0b531f8e65f709d732e8
+ depends:
+ - libopenblas >=0.3.27,<0.3.28.0a0
+ - libopenblas >=0.3.27,<1.0a0
+ constrains:
+ - liblapacke 3.9.0 22_osx64_openblas
+ - blas * openblas
+ - libcblas 3.9.0 22_osx64_openblas
+ - liblapack 3.9.0 22_osx64_openblas
+ license: BSD-3-Clause
+ license_family: BSD
+ purls: []
+ size: 14749
+ timestamp: 1712542279018
+- conda: https://conda.anaconda.org/conda-forge/osx-arm64/libblas-3.9.0-24_osxarm64_openblas.conda
+ build_number: 24
+ sha256: 4739f7463efb12e6d71536d8b0285a8de5aaadcc442bfedb9d92d1b4cbc47847
+ md5: 35cb711e7bc46ee5f3dd67af99ad1986
+ depends:
+ - libopenblas >=0.3.27,<0.3.28.0a0
+ - libopenblas >=0.3.27,<1.0a0
+ constrains:
+ - liblapack 3.9.0 24_osxarm64_openblas
+ - blas * openblas
+ - liblapacke 3.9.0 24_osxarm64_openblas
+ - libcblas 3.9.0 24_osxarm64_openblas
+ license: BSD-3-Clause
+ license_family: BSD
+ purls: []
+ size: 15144
+ timestamp: 1726668802976
+- conda: https://conda.anaconda.org/conda-forge/win-64/libblas-3.11.0-5_hf2e6a31_mkl.conda
+ build_number: 5
+ sha256: f0cb7b2697461a306341f7ff32d5b361bb84f3e94478464c1e27ee01fc8f276b
+ md5: f9decf88743af85c9c9e05556a4c47c0
+ depends:
+ - mkl >=2025.3.0,<2026.0a0
+ constrains:
+ - liblapack 3.11.0 5*_mkl
+ - libcblas 3.11.0 5*_mkl
+ - blas 2.305 mkl
+ - liblapacke 3.11.0 5*_mkl
+ license: BSD-3-Clause
+ license_family: BSD
+ purls: []
+ size: 67438
+ timestamp: 1765819100043
+- conda: https://conda.anaconda.org/conda-forge/linux-64/libcblas-3.11.0-5_h0358290_openblas.conda
+ build_number: 5
+ sha256: 0cbdcc67901e02dc17f1d19e1f9170610bd828100dc207de4d5b6b8ad1ae7ad8
+ md5: 6636a2b6f1a87572df2970d3ebc87cc0
+ depends:
+ - libblas 3.11.0 5_h4a7cf45_openblas
+ constrains:
+ - liblapacke 3.11.0 5*_openblas
+ - blas 2.305 openblas
+ - liblapack 3.11.0 5*_openblas
+ license: BSD-3-Clause
+ license_family: BSD
+ purls: []
+ size: 18194
+ timestamp: 1765818837135
+- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libcblas-3.11.0-5_hd72aa62_openblas.conda
+ build_number: 5
+ sha256: 3fad5c9de161dccb4e42c8b1ae8eccb33f4ed56bccbcced9cbb0956ae7869e61
+ md5: 0b2f1143ae2d0aa4c991959d0daaf256
+ depends:
+ - libblas 3.11.0 5_haddc8a3_openblas
+ constrains:
+ - liblapack 3.11.0 5*_openblas
+ - liblapacke 3.11.0 5*_openblas
+ - blas 2.305 openblas
+ license: BSD-3-Clause
+ license_family: BSD
+ purls: []
+ size: 18371
+ timestamp: 1765818618899
+- conda: https://conda.anaconda.org/conda-forge/osx-64/libcblas-3.9.0-22_osx64_openblas.conda
+ build_number: 22
+ sha256: 6a2ba9198e2320c3e22fe3d121310cf8a8ac663e94100c5693b34523fcb3cc04
+ md5: b9fef82772330f61b2b0201c72d2c29b
+ depends:
+ - libblas 3.9.0 22_osx64_openblas
+ constrains:
+ - liblapacke 3.9.0 22_osx64_openblas
+ - blas * openblas
+ - liblapack 3.9.0 22_osx64_openblas
+ license: BSD-3-Clause
+ license_family: BSD
+ purls: []
+ size: 14636
+ timestamp: 1712542311437
+- conda: https://conda.anaconda.org/conda-forge/osx-arm64/libcblas-3.9.0-24_osxarm64_openblas.conda
+ build_number: 24
+ sha256: 40dc3f7c44af5cd5a2020386cb30f92943a9d8f7f54321b4d6ae32b2e54af9a4
+ md5: c8977086a19233153e454bb2b332a920
+ depends:
+ - libblas 3.9.0 24_osxarm64_openblas
+ constrains:
+ - liblapack 3.9.0 24_osxarm64_openblas
+ - blas * openblas
+ - liblapacke 3.9.0 24_osxarm64_openblas
+ license: BSD-3-Clause
+ license_family: BSD
+ purls: []
+ size: 15062
+ timestamp: 1726668809379
+- conda: https://conda.anaconda.org/conda-forge/win-64/libcblas-3.11.0-5_h2a3cdd5_mkl.conda
+ build_number: 5
+ sha256: 49dc59d8e58360920314b8d276dd80da7866a1484a9abae4ee2760bc68f3e68d
+ md5: b3fa8e8b55310ba8ef0060103afb02b5
+ depends:
+ - libblas 3.11.0 5_hf2e6a31_mkl
+ constrains:
+ - liblapack 3.11.0 5*_mkl
+ - liblapacke 3.11.0 5*_mkl
+ - blas 2.305 mkl
+ license: BSD-3-Clause
+ license_family: BSD
+ purls: []
+ size: 68079
+ timestamp: 1765819124349
+- conda: https://conda.anaconda.org/conda-forge/osx-64/libclang-cpp18.1-18.1.3-default_h7151d67_0.conda
+ sha256: e3b693234b50f553441795f7f7f89e4f1b1258433634f3c9988e75f30ea9e3ee
+ md5: 02eea994247b28cbf46b8ca52530bb39
+ depends:
+ - libcxx >=16.0.6
+ - libllvm18 >=18.1.3,<18.2.0a0
+ license: Apache-2.0 WITH LLVM-exception
+ license_family: Apache
+ purls: []
+ size: 13694951
+ timestamp: 1712568723512
+- conda: https://conda.anaconda.org/conda-forge/osx-arm64/libclang-cpp18.1-18.1.3-default_he012953_0.conda
+ sha256: a528f933aa430c86591ed94e7eb5e4c16947232f149920250ba78e104d91e0b3
+ md5: d8e0decc03dadc234e0885bb2a857c68
+ depends:
+ - libcxx >=16.0.6
+ - libllvm18 >=18.1.3,<18.2.0a0
+ license: Apache-2.0 WITH LLVM-exception
+ license_family: Apache
+ purls: []
+ size: 12809223
+ timestamp: 1712569190982
+- conda: https://conda.anaconda.org/conda-forge/linux-64/libcurl-8.19.0-hcf29cc6_0.conda
+ sha256: a0390fd0536ebcd2244e243f5f00ab8e76ab62ed9aa214cd54470fe7496620f4
+ md5: d50608c443a30c341c24277d28290f76
+ depends:
+ - __glibc >=2.17,<3.0.a0
+ - krb5 >=1.22.2,<1.23.0a0
+ - libgcc >=14
+ - libnghttp2 >=1.67.0,<2.0a0
+ - libssh2 >=1.11.1,<2.0a0
+ - libzlib >=1.3.1,<2.0a0
+ - openssl >=3.5.5,<4.0a0
+ - zstd >=1.5.7,<1.6.0a0
+ license: curl
+ license_family: MIT
+ purls: []
+ size: 466704
+ timestamp: 1773218522665
+- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libcurl-8.19.0-hc57f145_0.conda
+ sha256: 75c1b2f9cff7598c593dda96c55963298bebb5bcb5a77af0b4c41cb03d26100b
+ md5: d5306c7ec07faf48cfb0e552c67339e0
+ depends:
+ - krb5 >=1.22.2,<1.23.0a0
+ - libgcc >=14
+ - libnghttp2 >=1.67.0,<2.0a0
+ - libssh2 >=1.11.1,<2.0a0
+ - libzlib >=1.3.1,<2.0a0
+ - openssl >=3.5.5,<4.0a0
+ - zstd >=1.5.7,<1.6.0a0
+ license: curl
+ license_family: MIT
+ purls: []
+ size: 485694
+ timestamp: 1773218484057
+- conda: https://conda.anaconda.org/conda-forge/osx-64/libcurl-8.19.0-h8f0b9e4_0.conda
+ sha256: 55c6b34ae18a7f8f57d9ffe3f4ec2a82ddcc8a87248d2447f9bbba3ba66d8aec
+ md5: 8bc2742696d50c358f4565b25ba33b08
+ depends:
+ - __osx >=11.0
+ - krb5 >=1.22.2,<1.23.0a0
+ - libnghttp2 >=1.67.0,<2.0a0
+ - libssh2 >=1.11.1,<2.0a0
+ - libzlib >=1.3.1,<2.0a0
+ - openssl >=3.5.5,<4.0a0
+ - zstd >=1.5.7,<1.6.0a0
+ license: curl
+ license_family: MIT
+ purls: []
+ size: 419039
+ timestamp: 1773219507657
+- conda: https://conda.anaconda.org/conda-forge/osx-64/libcurl-8.4.0-h726d00d_0.conda
+ sha256: cd3400ecb42fc420acb18e2d836535c44ebd501ebeb4e0bf3830776e9b4ca650
+ md5: 2c17b4dedf0039736951471f493353bd
+ depends:
+ - krb5 >=1.21.2,<1.22.0a0
+ - libnghttp2 >=1.52.0,<2.0a0
+ - libssh2 >=1.11.0,<2.0a0
+ - libzlib >=1.2.13,<2.0.0a0
+ - openssl >=3.1.3,<4.0a0
+ - zstd >=1.5.5,<1.6.0a0
+ license: curl
+ license_family: MIT
+ purls: []
+ size: 366039
+ timestamp: 1697009485409
+- conda: https://conda.anaconda.org/conda-forge/osx-arm64/libcurl-8.19.0-hd5a2499_0.conda
+ sha256: c4d581b067fa60f9dc0e1c5f18b756760ff094a03139e6b206eb98d185ae2bb1
+ md5: 9fc7771fc8104abed9119113160be15a
+ depends:
+ - __osx >=11.0
+ - krb5 >=1.22.2,<1.23.0a0
+ - libnghttp2 >=1.67.0,<2.0a0
+ - libssh2 >=1.11.1,<2.0a0
+ - libzlib >=1.3.1,<2.0a0
+ - openssl >=3.5.5,<4.0a0
+ - zstd >=1.5.7,<1.6.0a0
+ license: curl
+ license_family: MIT
+ purls: []
+ size: 399616
+ timestamp: 1773219210246
+- conda: https://conda.anaconda.org/conda-forge/osx-arm64/libcurl-8.4.0-h2d989ff_0.conda
+ sha256: 5ca24ab030b1c56ce07921bf901ea99076e8b7e45586b4a04e5187cc67c87273
+ md5: afabb3372209028627ec03e206f4d967
+ depends:
+ - krb5 >=1.21.2,<1.22.0a0
+ - libnghttp2 >=1.52.0,<2.0a0
+ - libssh2 >=1.11.0,<2.0a0
+ - libzlib >=1.2.13,<2.0.0a0
+ - openssl >=3.1.3,<4.0a0
+ - zstd >=1.5.5,<1.6.0a0
+ license: curl
+ license_family: MIT
+ purls: []
+ size: 348974
+ timestamp: 1697009607821
+- conda: https://conda.anaconda.org/conda-forge/win-64/libcurl-8.19.0-h8206538_0.conda
+ sha256: 6b2143ba5454b399dab4471e9e1d07352a2f33b569975e6b8aedc2d9bf51cbb0
+ md5: ed181e29a7ebf0f60b84b98d6140a340
+ depends:
+ - krb5 >=1.22.2,<1.23.0a0
+ - libssh2 >=1.11.1,<2.0a0
+ - libzlib >=1.3.1,<2.0a0
+ - ucrt >=10.0.20348.0
+ - vc >=14.3,<15
+ - vc14_runtime >=14.44.35208
+ license: curl
+ license_family: MIT
+ purls: []
+ size: 392543
+ timestamp: 1773218585056
+- conda: https://conda.anaconda.org/conda-forge/osx-64/libcxx-16.0.6-hd57cbcb_0.conda
+ sha256: 9063271847cf05f3a6cc6cae3e7f0ced032ab5f3a3c9d3f943f876f39c5c2549
+ md5: 7d6972792161077908b62971802f289a
+ license: Apache-2.0 WITH LLVM-exception
+ license_family: Apache
+ purls: []
+ size: 1142172
+ timestamp: 1686896907750
+- conda: https://conda.anaconda.org/conda-forge/osx-64/libcxx-22.1.1-h19cb2f5_0.conda
+ sha256: db3adcb33eaca02311d3ba17e06c60ceaedda20240414f7b1df6e7f9ec902bfa
+ md5: 799141ac68a99265f04bcee196b2df51
+ depends:
+ - __osx >=11.0
+ license: Apache-2.0 WITH LLVM-exception
+ license_family: Apache
+ size: 564942
+ timestamp: 1773203656390
+- conda: https://conda.anaconda.org/conda-forge/osx-64/libcxx-22.1.2-h19cb2f5_0.conda
+ sha256: 46561199545890e050a8a90edcfce984e5f881da86b09388926e3a6c6b759dec
+ md5: ed6f7b7a35f942a0301e581d72616f7d
+ depends:
+ - __osx >=11.0
+ license: Apache-2.0 WITH LLVM-exception
+ license_family: Apache
+ purls: []
+ size: 564908
+ timestamp: 1774439353713
+- conda: https://conda.anaconda.org/conda-forge/osx-arm64/libcxx-16.0.6-h4653b0c_0.conda
+ sha256: 11d3fb51c14832d9e4f6d84080a375dec21ea8a3a381a1910e67ff9cedc20355
+ md5: 9d7d724faf0413bf1dbc5a85935700c8
+ license: Apache-2.0 WITH LLVM-exception
+ license_family: Apache
+ purls: []
+ size: 1160232
+ timestamp: 1686896993785
+- conda: https://conda.anaconda.org/conda-forge/osx-arm64/libcxx-22.1.1-h55c6f16_0.conda
+ sha256: 3c8142cdd3109c250a926c492ec45bc954697b288e5d1154ada95272ffa21be8
+ md5: 7a290d944bc0c481a55baf33fa289deb
+ depends:
+ - __osx >=11.0
+ license: Apache-2.0 WITH LLVM-exception
+ license_family: Apache
+ size: 570281
+ timestamp: 1773203613980
+- conda: https://conda.anaconda.org/conda-forge/osx-arm64/libcxx-22.1.2-h55c6f16_0.conda
+ sha256: d1402087c8792461bfc081629e8aa97e6e577a31ae0b84e6b9cc144a18f48067
+ md5: 4280e0a7fd613b271e022e60dea0138c
+ depends:
+ - __osx >=11.0
+ license: Apache-2.0 WITH LLVM-exception
+ license_family: Apache
+ purls: []
+ size: 568094
+ timestamp: 1774439202359
+- conda: https://conda.anaconda.org/conda-forge/linux-64/libedit-3.1.20250104-pl5321h7949ede_0.conda
+ sha256: d789471216e7aba3c184cd054ed61ce3f6dac6f87a50ec69291b9297f8c18724
+ md5: c277e0a4d549b03ac1e9d6cbbe3d017b
+ depends:
+ - ncurses
+ - __glibc >=2.17,<3.0.a0
+ - libgcc >=13
+ - ncurses >=6.5,<7.0a0
+ license: BSD-2-Clause
+ license_family: BSD
+ purls: []
+ size: 134676
+ timestamp: 1738479519902
+- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libedit-3.1.20250104-pl5321h976ea20_0.conda
+ sha256: c0b27546aa3a23d47919226b3a1635fccdb4f24b94e72e206a751b33f46fd8d6
+ md5: fb640d776fc92b682a14e001980825b1
+ depends:
+ - ncurses
+ - libgcc >=13
+ - ncurses >=6.5,<7.0a0
+ license: BSD-2-Clause
+ license_family: BSD
+ purls: []
+ size: 148125
+ timestamp: 1738479808948
+- conda: https://conda.anaconda.org/conda-forge/osx-64/libedit-3.1.20191231-h0678c8f_2.tar.bz2
+ sha256: dbd3c3f2eca1d21c52e4c03b21930bbce414c4592f8ce805801575b9e9256095
+ md5: 6016a8a1d0e63cac3de2c352cd40208b
+ depends:
+ - ncurses >=6.2,<7.0.0a0
+ license: BSD-2-Clause
+ license_family: BSD
+ purls: []
+ size: 105382
+ timestamp: 1597616576726
+- conda: https://conda.anaconda.org/conda-forge/osx-64/libedit-3.1.20250104-pl5321ha958ccf_0.conda
+ sha256: 6cc49785940a99e6a6b8c6edbb15f44c2dd6c789d9c283e5ee7bdfedd50b4cd6
+ md5: 1f4ed31220402fcddc083b4bff406868
+ depends:
+ - ncurses
+ - __osx >=10.13
+ - ncurses >=6.5,<7.0a0
+ license: BSD-2-Clause
+ license_family: BSD
+ purls: []
+ size: 115563
+ timestamp: 1738479554273
+- conda: https://conda.anaconda.org/conda-forge/osx-arm64/libedit-3.1.20191231-hc8eb9b7_2.tar.bz2
+ sha256: 3912636197933ecfe4692634119e8644904b41a58f30cad9d1fc02f6ba4d9fca
+ md5: 30e4362988a2623e9eb34337b83e01f9
+ depends:
+ - ncurses >=6.2,<7.0.0a0
+ license: BSD-2-Clause
+ license_family: BSD
+ purls: []
+ size: 96607
+ timestamp: 1597616630749
+- conda: https://conda.anaconda.org/conda-forge/osx-arm64/libedit-3.1.20250104-pl5321hafb1f1b_0.conda
+ sha256: 66aa216a403de0bb0c1340a88d1a06adaff66bae2cfd196731aa24db9859d631
+ md5: 44083d2d2c2025afca315c7a172eab2b
+ depends:
+ - ncurses
+ - __osx >=11.0
+ - ncurses >=6.5,<7.0a0
+ license: BSD-2-Clause
+ license_family: BSD
+ purls: []
+ size: 107691
+ timestamp: 1738479560845
+- conda: https://conda.anaconda.org/conda-forge/linux-64/libev-4.33-hd590300_2.conda
+ sha256: 1cd6048169fa0395af74ed5d8f1716e22c19a81a8a36f934c110ca3ad4dd27b4
+ md5: 172bf1cd1ff8629f2b1179945ed45055
+ depends:
+ - libgcc-ng >=12
+ license: BSD-2-Clause
+ license_family: BSD
+ purls: []
+ size: 112766
+ timestamp: 1702146165126
+- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libev-4.33-h31becfc_2.conda
+ sha256: 973af77e297f1955dd1f69c2cbdc5ab9dfc88388a5576cd152cda178af0fd006
+ md5: a9a13cb143bbaa477b1ebaefbe47a302
+ depends:
+ - libgcc-ng >=12
+ license: BSD-2-Clause
+ license_family: BSD
+ purls: []
+ size: 115123
+ timestamp: 1702146237623
+- conda: https://conda.anaconda.org/conda-forge/osx-64/libev-4.33-h10d778d_2.conda
+ sha256: 0d238488564a7992942aa165ff994eca540f687753b4f0998b29b4e4d030ff43
+ md5: 899db79329439820b7e8f8de41bca902
+ license: BSD-2-Clause
+ license_family: BSD
+ purls: []
+ size: 106663
+ timestamp: 1702146352558
+- conda: https://conda.anaconda.org/conda-forge/osx-arm64/libev-4.33-h93a5062_2.conda
+ sha256: 95cecb3902fbe0399c3a7e67a5bed1db813e5ab0e22f4023a5e0f722f2cc214f
+ md5: 36d33e440c31857372a72137f78bacf5
+ license: BSD-2-Clause
+ license_family: BSD
+ purls: []
+ size: 107458
+ timestamp: 1702146414478
+- conda: https://conda.anaconda.org/conda-forge/linux-64/libexpat-2.7.4-hecca717_0.conda
+ sha256: d78f1d3bea8c031d2f032b760f36676d87929b18146351c4464c66b0869df3f5
+ md5: e7f7ce06ec24cfcfb9e36d28cf82ba57
+ depends:
+ - __glibc >=2.17,<3.0.a0
+ - libgcc >=14
+ constrains:
+ - expat 2.7.4.*
+ license: MIT
+ license_family: MIT
+ purls: []
+ size: 76798
+ timestamp: 1771259418166
+- conda: https://conda.anaconda.org/conda-forge/linux-64/libexpat-2.7.5-hecca717_0.conda
+ sha256: e8c2b57f6aacabdf2f1b0924bd4831ce5071ba080baa4a9e8c0d720588b6794c
+ md5: 49f570f3bc4c874a06ea69b7225753af
+ depends:
+ - __glibc >=2.17,<3.0.a0
+ - libgcc >=14
+ constrains:
+ - expat 2.7.5.*
+ license: MIT
+ license_family: MIT
+ purls: []
+ size: 76624
+ timestamp: 1774719175983
+- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libexpat-2.7.4-hfae3067_0.conda
+ sha256: 995ce3ad96d0f4b5ed6296b051a0d7b6377718f325bc0e792fbb96b0e369dad7
+ md5: 57f3b3da02a50a1be2a6fe847515417d
+ depends:
+ - libgcc >=14
+ constrains:
+ - expat 2.7.4.*
+ license: MIT
+ license_family: MIT
+ purls: []
+ size: 76564
+ timestamp: 1771259530958
+- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libexpat-2.7.5-hfae3067_0.conda
+ sha256: 6d438fc0bfdb263c24654fe49c09b31f06ec78eb709eb386392d2499af105f85
+ md5: 05d1e0b30acd816a192c03dc6e164f4d
+ depends:
+ - libgcc >=14
+ constrains:
+ - expat 2.7.5.*
+ license: MIT
+ license_family: MIT
+ purls: []
+ size: 76523
+ timestamp: 1774719129371
+- conda: https://conda.anaconda.org/conda-forge/osx-64/libexpat-2.6.2-h73e2aa4_0.conda
+ sha256: a188a77b275d61159a32ab547f7d17892226e7dac4518d2c6ac3ac8fc8dfde92
+ md5: 3d1d51c8f716d97c864d12f7af329526
+ constrains:
+ - expat 2.6.2.*
+ license: MIT
+ license_family: MIT
+ purls: []
+ size: 69246
+ timestamp: 1710362566073
+- conda: https://conda.anaconda.org/conda-forge/osx-64/libexpat-2.7.4-h991f03e_0.conda
+ sha256: 8d9d79b2de7d6f335692391f5281607221bf5d040e6724dad4c4d77cd603ce43
+ md5: a684eb8a19b2aa68fde0267df172a1e3
+ depends:
+ - __osx >=10.13
+ constrains:
+ - expat 2.7.4.*
+ license: MIT
+ license_family: MIT
+ size: 74578
+ timestamp: 1771260142624
+- conda: https://conda.anaconda.org/conda-forge/osx-64/libexpat-2.7.5-hcc62823_0.conda
+ sha256: 341d8a457a8342c396a8ac788da2639cbc8b62568f6ba2a3d322d1ace5aa9e16
+ md5: 1d6e71b8c73711e28ffe207acdc4e2f8
+ depends:
+ - __osx >=11.0
+ constrains:
+ - expat 2.7.5.*
+ license: MIT
+ license_family: MIT
+ purls: []
+ size: 74797
+ timestamp: 1774719557730
+- conda: https://conda.anaconda.org/conda-forge/osx-arm64/libexpat-2.6.2-hebf3989_0.conda
+ sha256: ba7173ac30064ea901a4c9fb5a51846dcc25512ceb565759be7d18cbf3e5415e
+ md5: e3cde7cfa87f82f7cb13d482d5e0ad09
+ constrains:
+ - expat 2.6.2.*
+ license: MIT
+ license_family: MIT
+ purls: []
+ size: 63655
+ timestamp: 1710362424980
+- conda: https://conda.anaconda.org/conda-forge/osx-arm64/libexpat-2.7.4-hf6b4638_0.conda
+ sha256: 03887d8080d6a8fe02d75b80929271b39697ecca7628f0657d7afaea87761edf
+ md5: a92e310ae8dfc206ff449f362fc4217f
+ depends:
+ - __osx >=11.0
+ constrains:
+ - expat 2.7.4.*
+ license: MIT
+ license_family: MIT
+ size: 68199
+ timestamp: 1771260020767
+- conda: https://conda.anaconda.org/conda-forge/osx-arm64/libexpat-2.7.5-hf6b4638_0.conda
+ sha256: 06780dec91dd25770c8cf01e158e1062fbf7c576b1406427475ce69a8af75b7e
+ md5: a32123f93e168eaa4080d87b0fb5da8a
+ depends:
+ - __osx >=11.0
+ constrains:
+ - expat 2.7.5.*
+ license: MIT
+ license_family: MIT
+ purls: []
+ size: 68192
+ timestamp: 1774719211725
+- conda: https://conda.anaconda.org/conda-forge/win-64/libexpat-2.7.4-hac47afa_0.conda
+ sha256: b31f6fb629c4e17885aaf2082fb30384156d16b48b264e454de4a06a313b533d
+ md5: 1c1ced969021592407f16ada4573586d
+ depends:
+ - ucrt >=10.0.20348.0
+ - vc >=14.3,<15
+ - vc14_runtime >=14.44.35208
+ constrains:
+ - expat 2.7.4.*
+ license: MIT
+ license_family: MIT
+ purls: []
+ size: 70323
+ timestamp: 1771259521393
+- conda: https://conda.anaconda.org/conda-forge/win-64/libexpat-2.7.5-hac47afa_0.conda
+ sha256: 6850c3a4d5dc215b86f58518cfb8752998533d6569b08da8df1da72e7c68e571
+ md5: bfb43f52f13b7c56e7677aa7a8efdf0c
+ depends:
+ - ucrt >=10.0.20348.0
+ - vc >=14.3,<15
+ - vc14_runtime >=14.44.35208
+ constrains:
+ - expat 2.7.5.*
+ license: MIT
+ license_family: MIT
+ purls: []
+ size: 70609
+ timestamp: 1774719377850
+- conda: https://conda.anaconda.org/conda-forge/linux-64/libffi-3.5.2-h3435931_0.conda
+ sha256: 31f19b6a88ce40ebc0d5a992c131f57d919f73c0b92cd1617a5bec83f6e961e6
+ md5: a360c33a5abe61c07959e449fa1453eb
+ depends:
+ - __glibc >=2.17,<3.0.a0
+ - libgcc >=14
+ license: MIT
+ license_family: MIT
+ purls: []
+ size: 58592
+ timestamp: 1769456073053
+- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libffi-3.5.2-h376a255_0.conda
+ sha256: 3df4c539449aabc3443bbe8c492c01d401eea894603087fca2917aa4e1c2dea9
+ md5: 2f364feefb6a7c00423e80dcb12db62a
+ depends:
+ - libgcc >=14
+ license: MIT
+ license_family: MIT
+ purls: []
+ size: 55952
+ timestamp: 1769456078358
+- conda: https://conda.anaconda.org/conda-forge/osx-64/libffi-3.4.2-h0d85af4_5.tar.bz2
+ sha256: 7a2d27a936ceee6942ea4d397f9c7d136f12549d86f7617e8b6bad51e01a941f
+ md5: ccb34fb14960ad8b125962d3d79b31a9
+ license: MIT
+ license_family: MIT
+ purls: []
+ size: 51348
+ timestamp: 1636488394370
+- conda: https://conda.anaconda.org/conda-forge/osx-64/libffi-3.5.2-hd1f9c09_0.conda
+ sha256: 951958d1792238006fdc6fce7f71f1b559534743b26cc1333497d46e5903a2d6
+ md5: 66a0dc7464927d0853b590b6f53ba3ea
+ depends:
+ - __osx >=10.13
+ license: MIT
+ license_family: MIT
+ purls: []
+ size: 53583
+ timestamp: 1769456300951
+- conda: https://conda.anaconda.org/conda-forge/osx-arm64/libffi-3.4.2-h3422bc3_5.tar.bz2
+ sha256: 41b3d13efb775e340e4dba549ab5c029611ea6918703096b2eaa9c015c0750ca
+ md5: 086914b672be056eb70fd4285b6783b6
+ license: MIT
+ license_family: MIT
+ purls: []
+ size: 39020
+ timestamp: 1636488587153
+- conda: https://conda.anaconda.org/conda-forge/osx-arm64/libffi-3.5.2-hcf2aa1b_0.conda
+ sha256: 6686a26466a527585e6a75cc2a242bf4a3d97d6d6c86424a441677917f28bec7
+ md5: 43c04d9cb46ef176bb2a4c77e324d599
+ depends:
+ - __osx >=11.0
+ license: MIT
+ license_family: MIT
+ purls: []
+ size: 40979
+ timestamp: 1769456747661
+- conda: https://conda.anaconda.org/conda-forge/win-64/libffi-3.5.2-h3d046cb_0.conda
+ sha256: 59d01f2dfa8b77491b5888a5ab88ff4e1574c9359f7e229da254cdfe27ddc190
+ md5: 720b39f5ec0610457b725eb3f396219a
+ depends:
+ - ucrt >=10.0.20348.0
+ - vc >=14.3,<15
+ - vc14_runtime >=14.44.35208
+ license: MIT
+ license_family: MIT
+ purls: []
+ size: 45831
+ timestamp: 1769456418774
+- conda: https://conda.anaconda.org/conda-forge/linux-64/libgcc-15.2.0-he0feb66_18.conda
+ sha256: faf7d2017b4d718951e3a59d081eb09759152f93038479b768e3d612688f83f5
+ md5: 0aa00f03f9e39fb9876085dee11a85d4
+ depends:
+ - __glibc >=2.17,<3.0.a0
+ - _openmp_mutex >=4.5
+ constrains:
+ - libgcc-ng ==15.2.0=*_18
+ - libgomp 15.2.0 he0feb66_18
+ license: GPL-3.0-only WITH GCC-exception-3.1
+ license_family: GPL
+ purls: []
+ size: 1041788
+ timestamp: 1771378212382
+- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libgcc-15.2.0-h8acb6b2_18.conda
+ sha256: 43df385bedc1cab11993c4369e1f3b04b4ca5d0ea16cba6a0e7f18dbc129fcc9
+ md5: 552567ea2b61e3a3035759b2fdb3f9a6
+ depends:
+ - _openmp_mutex >=4.5
+ constrains:
+ - libgcc-ng ==15.2.0=*_18
+ - libgomp 15.2.0 h8acb6b2_18
+ license: GPL-3.0-only WITH GCC-exception-3.1
+ license_family: GPL
+ purls: []
+ size: 622900
+ timestamp: 1771378128706
+- conda: https://conda.anaconda.org/conda-forge/osx-64/libgcc-15.2.0-h08519bb_18.conda
+ sha256: 83366f11615ab234aa1e0797393f9e07b78124b5a24c4a9f8af0113d02df818e
+ md5: 9a5cb96e43f5c2296690186e15b3296f
+ depends:
+ - _openmp_mutex
+ constrains:
+ - libgcc-ng ==15.2.0=*_18
+ - libgomp 15.2.0 18
+ license: GPL-3.0-only WITH GCC-exception-3.1
+ license_family: GPL
+ purls: []
+ size: 423025
+ timestamp: 1771378225170
+- conda: https://conda.anaconda.org/conda-forge/osx-arm64/libgcc-15.2.0-hcbb3090_18.conda
+ sha256: 1d9c4f35586adb71bcd23e31b68b7f3e4c4ab89914c26bed5f2859290be5560e
+ md5: 92df6107310b1fff92c4cc84f0de247b
+ depends:
+ - _openmp_mutex
+ constrains:
+ - libgcc-ng ==15.2.0=*_18
+ - libgomp 15.2.0 18
+ license: GPL-3.0-only WITH GCC-exception-3.1
+ license_family: GPL
+ purls: []
+ size: 401974
+ timestamp: 1771378877463
+- conda: https://conda.anaconda.org/conda-forge/noarch/libgcc-devel_linux-64-14.3.0-hf649bbc_118.conda
+ sha256: 1abc6a81ee66e8ac9ac09a26e2d6ad7bba23f0a0cc3a6118654f036f9c0e1854
+ md5: 06901733131833f5edd68cf3d9679798
+ depends:
+ - __unix
+ license: GPL-3.0-only WITH GCC-exception-3.1
+ license_family: GPL
+ purls: []
+ size: 3084533
+ timestamp: 1771377786730
+- conda: https://conda.anaconda.org/conda-forge/noarch/libgcc-devel_linux-aarch64-14.3.0-h25ba3ff_118.conda
+ sha256: 058fab0156cb13897f7e4a2fc9d63c922d3de09b6429390365f91b62f1dddb0e
+ md5: 3733752e5a7a0737c8c4f1897f2074f9
+ depends:
+ - __unix
+ license: GPL-3.0-only WITH GCC-exception-3.1
+ license_family: GPL
+ purls: []
+ size: 2335839
+ timestamp: 1771377646960
+- conda: https://conda.anaconda.org/conda-forge/linux-64/libgcc-ng-15.2.0-h69a702a_18.conda
+ sha256: e318a711400f536c81123e753d4c797a821021fb38970cebfb3f454126016893
+ md5: d5e96b1ed75ca01906b3d2469b4ce493
+ depends:
+ - libgcc 15.2.0 he0feb66_18
+ license: GPL-3.0-only WITH GCC-exception-3.1
+ license_family: GPL
+ purls: []
+ size: 27526
+ timestamp: 1771378224552
+- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libgcc-ng-15.2.0-he9431aa_18.conda
+ sha256: 83bb0415f59634dccfa8335d4163d1f6db00a27b36666736f9842b650b92cf2f
+ md5: 4feebd0fbf61075a1a9c2e9b3936c257
+ depends:
+ - libgcc 15.2.0 h8acb6b2_18
+ license: GPL-3.0-only WITH GCC-exception-3.1
+ license_family: GPL
+ purls: []
+ size: 27568
+ timestamp: 1771378136019
+- conda: https://conda.anaconda.org/conda-forge/linux-64/libgfortran-15.2.0-h69a702a_18.conda
+ sha256: d2c9fad338fd85e4487424865da8e74006ab2e2475bd788f624d7a39b2a72aee
+ md5: 9063115da5bc35fdc3e1002e69b9ef6e
+ depends:
+ - libgfortran5 15.2.0 h68bc16d_18
+ constrains:
+ - libgfortran-ng ==15.2.0=*_18
+ license: GPL-3.0-only WITH GCC-exception-3.1
+ license_family: GPL
+ purls: []
+ size: 27523
+ timestamp: 1771378269450
+- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libgfortran-15.2.0-he9431aa_18.conda
+ sha256: 7dcd7dff2505d56fd5272a6e712ec912f50a46bf07dc6873a7e853694304e6e4
+ md5: 41f261f5e4e2e8cbd236c2f1f15dae1b
+ depends:
+ - libgfortran5 15.2.0 h1b7bec0_18
+ constrains:
+ - libgfortran-ng ==15.2.0=*_18
+ license: GPL-3.0-only WITH GCC-exception-3.1
+ license_family: GPL
+ purls: []
+ size: 27587
+ timestamp: 1771378169244
+- conda: https://conda.anaconda.org/conda-forge/osx-64/libgfortran-15.2.0-h7e5c614_18.conda
+ sha256: fb06c2a2ef06716a0f2a6550f5d13cdd1d89365993068512b7ae3c34e6e665d9
+ md5: 34a9f67498721abcfef00178bcf4b190
+ depends:
+ - libgfortran5 15.2.0 hd16e46c_18
+ constrains:
+ - libgfortran-ng ==15.2.0=*_18
+ license: GPL-3.0-only WITH GCC-exception-3.1
+ license_family: GPL
+ purls: []
+ size: 139761
+ timestamp: 1771378423828
+- conda: https://conda.anaconda.org/conda-forge/osx-arm64/libgfortran-15.2.0-h07b0088_18.conda
+ sha256: 63f89087c3f0c8621c5c89ecceec1e56e5e1c84f65fc9c5feca33a07c570a836
+ md5: 26981599908ed2205366e8fc91b37fc6
+ depends:
+ - libgfortran5 15.2.0 hdae7583_18
+ constrains:
+ - libgfortran-ng ==15.2.0=*_18
+ license: GPL-3.0-only WITH GCC-exception-3.1
+ license_family: GPL
+ purls: []
+ size: 138973
+ timestamp: 1771379054939
+- conda: https://conda.anaconda.org/conda-forge/linux-64/libgfortran5-15.2.0-h68bc16d_18.conda
+ sha256: 539b57cf50ec85509a94ba9949b7e30717839e4d694bc94f30d41c9d34de2d12
+ md5: 646855f357199a12f02a87382d429b75
+ depends:
+ - __glibc >=2.17,<3.0.a0
+ - libgcc >=15.2.0
+ constrains:
+ - libgfortran 15.2.0
+ license: GPL-3.0-only WITH GCC-exception-3.1
+ license_family: GPL
+ purls: []
+ size: 2482475
+ timestamp: 1771378241063
+- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libgfortran5-15.2.0-h1b7bec0_18.conda
+ sha256: 85347670dfb4a8d4c13cd7cae54138dcf2b1606b6bede42eef5507bf5f9660c6
+ md5: 574d88ce3348331e962cfa5ed451b247
+ depends:
+ - libgcc >=15.2.0
+ constrains:
+ - libgfortran 15.2.0
+ license: GPL-3.0-only WITH GCC-exception-3.1
+ license_family: GPL
+ purls: []
+ size: 1486341
+ timestamp: 1771378148102
+- conda: https://conda.anaconda.org/conda-forge/osx-64/libgfortran5-15.2.0-hd16e46c_18.conda
+ sha256: ddaf9dcf008c031b10987991aa78643e03c24a534ad420925cbd5851b31faa11
+ md5: ca52daf58cea766656266c8771d8be81
+ depends:
+ - libgcc >=15.2.0
+ constrains:
+ - libgfortran 15.2.0
+ license: GPL-3.0-only WITH GCC-exception-3.1
+ license_family: GPL
+ purls: []
+ size: 1062274
+ timestamp: 1771378232014
+- conda: https://conda.anaconda.org/conda-forge/osx-arm64/libgfortran5-15.2.0-hdae7583_18.conda
+ sha256: 91033978ba25e6a60fb86843cf7e1f7dc8ad513f9689f991c9ddabfaf0361e7e
+ md5: c4a6f7989cffb0544bfd9207b6789971
+ depends:
+ - libgcc >=15.2.0
+ constrains:
+ - libgfortran 15.2.0
+ license: GPL-3.0-only WITH GCC-exception-3.1
+ license_family: GPL
+ purls: []
+ size: 598634
+ timestamp: 1771378886363
+- conda: https://conda.anaconda.org/conda-forge/linux-64/libgomp-15.2.0-he0feb66_18.conda
+ sha256: 21337ab58e5e0649d869ab168d4e609b033509de22521de1bfed0c031bfc5110
+ md5: 239c5e9546c38a1e884d69effcf4c882
+ depends:
+ - __glibc >=2.17,<3.0.a0
+ license: GPL-3.0-only WITH GCC-exception-3.1
+ license_family: GPL
+ purls: []
+ size: 603262
+ timestamp: 1771378117851
+- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libgomp-15.2.0-h8acb6b2_18.conda
+ sha256: fc716f11a6a8525e27a5d332ef6a689210b0d2a4dd1133edc0f530659aa9faa6
+ md5: 4faa39bf919939602e594253bd673958
+ license: GPL-3.0-only WITH GCC-exception-3.1
+ license_family: GPL
+ purls: []
+ size: 588060
+ timestamp: 1771378040807
+- conda: https://conda.anaconda.org/conda-forge/linux-64/libhwloc-2.13.0-default_he001693_1000.conda
+ sha256: 5041d295813dfb84652557839825880aae296222ab725972285c5abe3b6e4288
+ md5: c197985b58bc813d26b42881f0021c82
+ depends:
+ - __glibc >=2.17,<3.0.a0
+ - libgcc >=14
+ - libstdcxx >=14
+ - libxml2
+ - libxml2-16 >=2.14.6
+ license: BSD-3-Clause
+ license_family: BSD
+ purls: []
+ size: 2436378
+ timestamp: 1770953868164
+- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libhwloc-2.13.0-default_ha95e27d_1000.conda
+ sha256: 88888d99e81c93e7331f2eb0fec08b3c4a47a1bfa1c88b3e641f6568569b6261
+ md5: 974183f6420938051e2f3208922d057f
+ depends:
+ - libgcc >=14
+ - libstdcxx >=14
+ - libxml2
+ - libxml2-16 >=2.14.6
+ license: BSD-3-Clause
+ license_family: BSD
+ purls: []
+ size: 2453519
+ timestamp: 1770953713701
+- conda: https://conda.anaconda.org/conda-forge/win-64/libhwloc-2.12.2-default_h4379cf1_1000.conda
+ sha256: 8cdf11333a81085468d9aa536ebb155abd74adc293576f6013fc0c85a7a90da3
+ md5: 3b576f6860f838f950c570f4433b086e
+ depends:
+ - libwinpthread >=12.0.0.r4.gg4f2fc60ca
+ - libxml2
+ - libxml2-16 >=2.14.6
+ - ucrt >=10.0.20348.0
+ - vc >=14.3,<15
+ - vc14_runtime >=14.44.35208
+ license: BSD-3-Clause
+ license_family: BSD
+ purls: []
+ size: 2411241
+ timestamp: 1765104337762
+- conda: https://conda.anaconda.org/conda-forge/linux-64/libiconv-1.18-h3b78370_2.conda
+ sha256: c467851a7312765447155e071752d7bf9bf44d610a5687e32706f480aad2833f
+ md5: 915f5995e94f60e9a4826e0b0920ee88
+ depends:
+ - __glibc >=2.17,<3.0.a0
+ - libgcc >=14
+ license: LGPL-2.1-only
+ purls: []
+ size: 790176
+ timestamp: 1754908768807
+- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libiconv-1.18-h90929bb_2.conda
+ sha256: 1473451cd282b48d24515795a595801c9b65b567fe399d7e12d50b2d6cdb04d9
+ md5: 5a86bf847b9b926f3a4f203339748d78
+ depends:
+ - libgcc >=14
+ license: LGPL-2.1-only
+ purls: []
+ size: 791226
+ timestamp: 1754910975665
+- conda: https://conda.anaconda.org/conda-forge/osx-64/libiconv-1.17-hd75f5a5_2.conda
+ sha256: 23d4923baeca359423a7347c2ed7aaf48c68603df0cf8b87cc94a10b0d4e9a23
+ md5: 6c3628d047e151efba7cf08c5e54d1ca
+ license: LGPL-2.1-only
+ purls: []
+ size: 666538
+ timestamp: 1702682713201
+- conda: https://conda.anaconda.org/conda-forge/osx-64/libiconv-1.18-h57a12c2_2.conda
+ sha256: a1c8cecdf9966921e13f0ae921309a1f415dfbd2b791f2117cf7e8f5e61a48b6
+ md5: 210a85a1119f97ea7887188d176db135
+ depends:
+ - __osx >=10.13
+ license: LGPL-2.1-only
+ purls: []
+ size: 737846
+ timestamp: 1754908900138
+- conda: https://conda.anaconda.org/conda-forge/osx-arm64/libiconv-1.17-h0d3ecfb_2.conda
+ sha256: bc7de5097b97bcafcf7deaaed505f7ce02f648aac8eccc0d5a47cc599a1d0304
+ md5: 69bda57310071cf6d2b86caf11573d2d
+ license: LGPL-2.1-only
+ purls: []
+ size: 676469
+ timestamp: 1702682458114
+- conda: https://conda.anaconda.org/conda-forge/osx-arm64/libiconv-1.18-h23cfdf5_2.conda
+ sha256: de0336e800b2af9a40bdd694b03870ac4a848161b35c8a2325704f123f185f03
+ md5: 4d5a7445f0b25b6a3ddbb56e790f5251
+ depends:
+ - __osx >=11.0
+ license: LGPL-2.1-only
+ purls: []
+ size: 750379
+ timestamp: 1754909073836
+- conda: https://conda.anaconda.org/conda-forge/win-64/libiconv-1.18-hc1393d2_2.conda
+ sha256: 0dcdb1a5f01863ac4e8ba006a8b0dc1a02d2221ec3319b5915a1863254d7efa7
+ md5: 64571d1dd6cdcfa25d0664a5950fdaa2
+ depends:
+ - ucrt >=10.0.20348.0
+ - vc >=14.3,<15
+ - vc14_runtime >=14.44.35208
+ license: LGPL-2.1-only
+ purls: []
+ size: 696926
+ timestamp: 1754909290005
+- conda: https://conda.anaconda.org/conda-forge/linux-64/liblapack-3.11.0-5_h47877c9_openblas.conda
+ build_number: 5
+ sha256: c723b6599fcd4c6c75dee728359ef418307280fa3e2ee376e14e85e5bbdda053
+ md5: b38076eb5c8e40d0106beda6f95d7609
+ depends:
+ - libblas 3.11.0 5_h4a7cf45_openblas
+ constrains:
+ - blas 2.305 openblas
+ - liblapacke 3.11.0 5*_openblas
+ - libcblas 3.11.0 5*_openblas
+ license: BSD-3-Clause
+ license_family: BSD
+ purls: []
+ size: 18200
+ timestamp: 1765818857876
+- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/liblapack-3.11.0-5_h88aeb00_openblas.conda
+ build_number: 5
+ sha256: 692222d186d3ffbc99eaf04b5b20181fd26aee1edec1106435a0a755c57cce86
+ md5: 88d1e4133d1182522b403e9ba7435f04
+ depends:
+ - libblas 3.11.0 5_haddc8a3_openblas
+ constrains:
+ - liblapacke 3.11.0 5*_openblas
+ - blas 2.305 openblas
+ - libcblas 3.11.0 5*_openblas
+ license: BSD-3-Clause
+ license_family: BSD
+ purls: []
+ size: 18392
+ timestamp: 1765818627104
+- conda: https://conda.anaconda.org/conda-forge/osx-64/liblapack-3.9.0-22_osx64_openblas.conda
+ build_number: 22
+ sha256: e36744f3e780564d6748b5dd05e15ad6a1af9184cf32ab9d1304c13a6bc3e16b
+ md5: f21b282ff7ba14df6134a0fe6ab42b1b
+ depends:
+ - libblas 3.9.0 22_osx64_openblas
+ constrains:
+ - liblapacke 3.9.0 22_osx64_openblas
+ - blas * openblas
+ - libcblas 3.9.0 22_osx64_openblas
+ license: BSD-3-Clause
+ license_family: BSD
+ purls: []
+ size: 14657
+ timestamp: 1712542322711
+- conda: https://conda.anaconda.org/conda-forge/osx-arm64/liblapack-3.9.0-24_osxarm64_openblas.conda
+ build_number: 24
+ sha256: 67fbfd0466eee443cda9596ed22daabedc96b7b4d1b31f49b1c1b0983dd1dd2c
+ md5: 49a3241f76cdbe705e346204a328f66c
+ depends:
+ - libblas 3.9.0 24_osxarm64_openblas
+ constrains:
+ - blas * openblas
+ - liblapacke 3.9.0 24_osxarm64_openblas
+ - libcblas 3.9.0 24_osxarm64_openblas
+ license: BSD-3-Clause
+ license_family: BSD
+ purls: []
+ size: 15063
+ timestamp: 1726668815824
+- conda: https://conda.anaconda.org/conda-forge/win-64/liblapack-3.11.0-5_hf9ab0e9_mkl.conda
+ build_number: 5
+ sha256: a2d33f5cc2b8a9042f2af6981c6733ab1a661463823eaa56595a9c58c0ab77e1
+ md5: e62c42a4196dee97d20400612afcb2b1
+ depends:
+ - libblas 3.11.0 5_hf2e6a31_mkl
+ constrains:
+ - libcblas 3.11.0 5*_mkl
+ - blas 2.305 mkl
+ - liblapacke 3.11.0 5*_mkl
+ license: BSD-3-Clause
+ license_family: BSD
+ purls: []
+ size: 80225
+ timestamp: 1765819148014
+- conda: https://conda.anaconda.org/conda-forge/osx-64/libllvm18-18.1.3-hbcf5fad_0.conda
+ sha256: bc42a9999c8846f50f5b3bb9a2338caeab34f2d7de8202e3fad7f929f38e3287
+ md5: f286e87d892273a1ef3059744c833f91
+ depends:
+ - libcxx >=16
+ - libxml2 >=2.12.6,<2.14.0a0
+ - libzlib >=1.2.13,<2.0.0a0
+ - zstd >=1.5.5,<1.6.0a0
+ license: Apache-2.0 WITH LLVM-exception
+ license_family: Apache
+ purls: []
+ size: 27580830
+ timestamp: 1712517566570
+- conda: https://conda.anaconda.org/conda-forge/osx-arm64/libllvm18-18.1.3-h30cc82d_0.conda
+ sha256: 5a8781ab13b163fd028916d050bb209718b14de85493bb7a4b93ea798998b9fe
+ md5: fad73e8421bcd0de381d172c2224d3a5
+ depends:
+ - libcxx >=16
+ - libxml2 >=2.12.6,<2.14.0a0
+ - libzlib >=1.2.13,<2.0.0a0
+ - zstd >=1.5.5,<1.6.0a0
+ license: Apache-2.0 WITH LLVM-exception
+ license_family: Apache
+ purls: []
+ size: 25782519
+ timestamp: 1712517407600
+- conda: https://conda.anaconda.org/conda-forge/linux-64/liblzma-5.8.2-hb03c661_0.conda
+ sha256: 755c55ebab181d678c12e49cced893598f2bab22d582fbbf4d8b83c18be207eb
+ md5: c7c83eecbb72d88b940c249af56c8b17
+ depends:
+ - __glibc >=2.17,<3.0.a0
+ - libgcc >=14
+ constrains:
+ - xz 5.8.2.*
+ license: 0BSD
+ purls: []
+ size: 113207
+ timestamp: 1768752626120
+- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/liblzma-5.8.2-he30d5cf_0.conda
+ sha256: 843c46e20519651a3e357a8928352b16c5b94f4cd3d5481acc48be2e93e8f6a3
+ md5: 96944e3c92386a12755b94619bae0b35
+ depends:
+ - libgcc >=14
+ constrains:
+ - xz 5.8.2.*
+ license: 0BSD
+ purls: []
+ size: 125916
+ timestamp: 1768754941722
+- conda: https://conda.anaconda.org/conda-forge/osx-64/liblzma-5.8.2-h11316ed_0.conda
+ sha256: 7ab3c98abd3b5d5ec72faa8d9f5d4b50dcee4970ed05339bc381861199dabb41
+ md5: 688a0c3d57fa118b9c97bf7e471ab46c
+ depends:
+ - __osx >=10.13
+ constrains:
+ - xz 5.8.2.*
+ license: 0BSD
+ purls: []
+ size: 105482
+ timestamp: 1768753411348
+- conda: https://conda.anaconda.org/conda-forge/osx-arm64/liblzma-5.8.2-h8088a28_0.conda
+ sha256: 7bfc7ffb2d6a9629357a70d4eadeadb6f88fa26ebc28f606b1c1e5e5ed99dc7e
+ md5: 009f0d956d7bfb00de86901d16e486c7
+ depends:
+ - __osx >=11.0
+ constrains:
+ - xz 5.8.2.*
+ license: 0BSD
+ purls: []
+ size: 92242
+ timestamp: 1768752982486
+- conda: https://conda.anaconda.org/conda-forge/win-64/liblzma-5.8.2-hfd05255_0.conda
+ sha256: f25bf293f550c8ed2e0c7145eb404324611cfccff37660869d97abf526eb957c
+ md5: ba0bfd4c3cf73f299ffe46ff0eaeb8e3
+ depends:
+ - ucrt >=10.0.20348.0
+ - vc >=14.3,<15
+ - vc14_runtime >=14.44.35208
+ constrains:
+ - xz 5.8.2.*
+ license: 0BSD
+ purls: []
+ size: 106169
+ timestamp: 1768752763559
+- conda: https://conda.anaconda.org/conda-forge/linux-64/libmamba-2.5.0-hd28c85e_0.conda
+ sha256: ca2d384f30e1582b7c6ae9f1406fb51f993e44c92799e3cabf2130f69c7261d5
+ md5: a24532d0660b8a58ca2955301281f71e
+ depends:
+ - cpp-expected >=1.3.1,<1.3.2.0a0
+ - __glibc >=2.17,<3.0.a0
+ - libstdcxx >=14
+ - libgcc >=14
+ - zstd >=1.5.7,<1.6.0a0
+ - reproc >=14.2,<15.0a0
+ - spdlog >=1.17.0,<1.18.0a0
+ - libarchive >=3.8.5,<3.9.0a0
+ - openssl >=3.5.4,<4.0a0
+ - nlohmann_json-abi ==3.12.0
+ - fmt >=12.1.0,<12.2.0a0
+ - simdjson >=4.2.4,<4.3.0a0
+ - libsolv >=0.7.35,<0.8.0a0
+ - reproc-cpp >=14.2,<15.0a0
+ - libcurl >=8.18.0,<9.0a0
+ - yaml-cpp >=0.8.0,<0.9.0a0
+ license: BSD-3-Clause
+ license_family: BSD
+ purls: []
+ size: 2567543
+ timestamp: 1767884157869
+- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libmamba-2.5.0-hc712cdd_0.conda
+ sha256: 480913318158db625ca7862a2447eda8aa84c8a315d4f86cc1764a5f1050e61c
+ md5: 45c3a33d8c6db2382678b3c90af03dd4
+ depends:
+ - cpp-expected >=1.3.1,<1.3.2.0a0
+ - libstdcxx >=14
+ - libgcc >=14
+ - nlohmann_json-abi ==3.12.0
+ - zstd >=1.5.7,<1.6.0a0
+ - libsolv >=0.7.35,<0.8.0a0
+ - yaml-cpp >=0.8.0,<0.9.0a0
+ - reproc-cpp >=14.2,<15.0a0
+ - fmt >=12.1.0,<12.2.0a0
+ - spdlog >=1.17.0,<1.18.0a0
+ - reproc >=14.2,<15.0a0
+ - openssl >=3.5.4,<4.0a0
+ - simdjson >=4.2.4,<4.3.0a0
+ - libarchive >=3.8.5,<3.9.0a0
+ - libcurl >=8.18.0,<9.0a0
+ license: BSD-3-Clause
+ license_family: BSD
+ purls: []
+ size: 2414027
+ timestamp: 1767884182395
+- conda: https://conda.anaconda.org/conda-forge/osx-64/libmamba-2.5.0-h7fe6c55_0.conda
+ sha256: 614dc840d50442e8732e7373821ca5802626bd9b0654491a135e6cf3dbbbb428
+ md5: bcc1e88e0437b6a0a5fb5bab84b7b995
+ depends:
+ - cpp-expected >=1.3.1,<1.3.2.0a0
+ - __osx >=10.13
+ - libcxx >=19
+ - simdjson >=4.2.4,<4.3.0a0
+ - reproc >=14.2,<15.0a0
+ - libarchive >=3.8.5,<3.9.0a0
+ - yaml-cpp >=0.8.0,<0.9.0a0
+ - spdlog >=1.17.0,<1.18.0a0
+ - nlohmann_json-abi ==3.12.0
+ - zstd >=1.5.7,<1.6.0a0
+ - reproc-cpp >=14.2,<15.0a0
+ - openssl >=3.5.4,<4.0a0
+ - libcurl >=8.18.0,<9.0a0
+ - fmt >=12.1.0,<12.2.0a0
+ - libsolv >=0.7.35,<0.8.0a0
+ license: BSD-3-Clause
+ license_family: BSD
+ purls: []
+ size: 1785898
+ timestamp: 1767884200743
+- conda: https://conda.anaconda.org/conda-forge/osx-arm64/libmamba-2.5.0-h7950639_0.conda
+ sha256: 78fccef61fe4d6763c60e19dd5bc8aad7db553188609e3bd91159d158aecabaa
+ md5: 29e8e662089a1226a90a5dc5d499b7b7
+ depends:
+ - cpp-expected >=1.3.1,<1.3.2.0a0
+ - libcxx >=19
+ - __osx >=11.0
+ - zstd >=1.5.7,<1.6.0a0
+ - reproc >=14.2,<15.0a0
+ - libsolv >=0.7.35,<0.8.0a0
+ - fmt >=12.1.0,<12.2.0a0
+ - yaml-cpp >=0.8.0,<0.9.0a0
+ - libarchive >=3.8.5,<3.9.0a0
+ - nlohmann_json-abi ==3.12.0
+ - spdlog >=1.17.0,<1.18.0a0
+ - simdjson >=4.2.4,<4.3.0a0
+ - libcurl >=8.18.0,<9.0a0
+ - openssl >=3.5.4,<4.0a0
+ - reproc-cpp >=14.2,<15.0a0
+ license: BSD-3-Clause
+ license_family: BSD
+ purls: []
+ size: 1653523
+ timestamp: 1767884201469
+- conda: https://conda.anaconda.org/conda-forge/win-64/libmamba-2.5.0-h06825f5_0.conda
+ sha256: 632acf45a127242ca0dddc942c635bd43de718c51477ac000ed579410b7363a3
+ md5: df96c0c3390a753e0c2df57fdbf98d97
+ depends:
+ - cpp-expected >=1.3.1,<1.3.2.0a0
+ - vc >=14.3,<15
+ - vc14_runtime >=14.44.35208
+ - ucrt >=10.0.20348.0
+ - libarchive >=3.8.5,<3.9.0a0
+ - libcurl >=8.18.0,<9.0a0
+ - spdlog >=1.17.0,<1.18.0a0
+ - zstd >=1.5.7,<1.6.0a0
+ - yaml-cpp >=0.8.0,<0.9.0a0
+ - reproc >=14.2,<15.0a0
+ - fmt >=12.1.0,<12.2.0a0
+ - nlohmann_json-abi ==3.12.0
+ - libsolv >=0.7.35,<0.8.0a0
+ - simdjson >=4.2.4,<4.3.0a0
+ - openssl >=3.5.4,<4.0a0
+ - reproc-cpp >=14.2,<15.0a0
+ license: BSD-3-Clause
+ license_family: BSD
+ purls: []
+ size: 4995231
+ timestamp: 1767884194847
+- conda: https://conda.anaconda.org/conda-forge/linux-64/libmamba-spdlog-2.5.0-h12fcf84_0.conda
+ sha256: 75deca8004690aed0985845f734927e48aa49a683ee09b3d9ff4e22ace9e4a8e
+ md5: c866cdca3b16b5c7a0fd9916d5d64577
+ depends:
+ - libstdcxx >=14
+ - libgcc >=14
+ - __glibc >=2.17,<3.0.a0
+ - libmamba >=2.5.0,<2.6.0a0
+ license: BSD-3-Clause
+ license_family: BSD
+ purls: []
+ size: 20396
+ timestamp: 1767884157870
+- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libmamba-spdlog-2.5.0-h3ad78e7_0.conda
+ sha256: d100a04349427cfb8cc76b4c0736bd27fd77ccb9c07e8a25e9988cbf718c610b
+ md5: 4abcea9b345dd46ecc86ca7c20f3db62
+ depends:
+ - libstdcxx >=14
+ - libgcc >=14
+ - libmamba >=2.5.0,<2.6.0a0
+ license: BSD-3-Clause
+ license_family: BSD
+ purls: []
+ size: 23017
+ timestamp: 1767884182397
+- conda: https://conda.anaconda.org/conda-forge/osx-64/libmamba-spdlog-2.5.0-hb923e0c_0.conda
+ sha256: 3bc7cdc7d617a62b86df95cb198614794a533edc360d47b5116a9295215e6955
+ md5: 7e25602d391cbdba87191a231594058d
+ depends:
+ - libcxx >=19
+ - __osx >=10.13
+ - libmamba >=2.5.0,<2.6.0a0
+ license: BSD-3-Clause
+ license_family: BSD
+ purls: []
+ size: 20784
+ timestamp: 1767884200753
+- conda: https://conda.anaconda.org/conda-forge/osx-arm64/libmamba-spdlog-2.5.0-h85b9800_0.conda
+ sha256: c0efbd9cf938a44fe98cfeb77d9bbb119f58bf0202ec5009b7d6621c6b96721c
+ md5: 6a3a2f6d6e90363288a96bc355b417c2
+ depends:
+ - libcxx >=19
+ - __osx >=11.0
+ - libmamba >=2.5.0,<2.6.0a0
+ license: BSD-3-Clause
+ license_family: BSD
+ purls: []
+ size: 23068
+ timestamp: 1767884201476
+- conda: https://conda.anaconda.org/conda-forge/win-64/libmamba-spdlog-2.5.0-h9ae1bf1_0.conda
+ sha256: 172991ecd8ffe8aadff9f083b8c1de282d91e670c939cdfff5970ccacbe98548
+ md5: 463b59502db7115998f7d537ccd932df
+ depends:
+ - vc >=14.3,<15
+ - vc14_runtime >=14.44.35208
+ - ucrt >=10.0.20348.0
+ - libmamba >=2.5.0,<2.6.0a0
+ license: BSD-3-Clause
+ license_family: BSD
+ purls: []
+ size: 18007
+ timestamp: 1767884194852
+- conda: https://conda.anaconda.org/conda-forge/linux-64/libmambapy-2.5.0-py310h74f1d5f_0.conda
+ sha256: a949389f9c3196fed8377a47ee266546f3e35d6d237f8209d3bb77ffc104c748
+ md5: edd4cf55ce1926c90c5702ba24b3fc08
+ depends:
+ - python
+ - libmamba ==2.5.0 hd28c85e_0
+ - libmamba-spdlog ==2.5.0 h12fcf84_0
+ - libstdcxx >=14
+ - libgcc >=14
+ - __glibc >=2.17,<3.0.a0
+ - libmamba >=2.5.0,<2.6.0a0
+ - openssl >=3.5.4,<4.0a0
+ - nlohmann_json-abi ==3.12.0
+ - zstd >=1.5.7,<1.6.0a0
+ - spdlog >=1.17.0,<1.18.0a0
+ - pybind11-abi ==11
+ - python_abi 3.10.* *_cp310
+ - fmt >=12.1.0,<12.2.0a0
+ - yaml-cpp >=0.8.0,<0.9.0a0
+ license: BSD-3-Clause
+ license_family: BSD
+ purls:
+ - pkg:pypi/libmambapy?source=hash-mapping
+ size: 943029
+ timestamp: 1767884157872
+- conda: https://conda.anaconda.org/conda-forge/linux-64/libmambapy-2.5.0-py311hc5d5c7c_0.conda
+ sha256: ebd16f6685bdc2f0cf595f0f441b638b378a43e76e2124763c35d548df09084b
+ md5: f72a2daebdd84c968828602bfa081ae5
+ depends:
+ - python
+ - libmamba ==2.5.0 hd28c85e_0
+ - libmamba-spdlog ==2.5.0 h12fcf84_0
+ - __glibc >=2.17,<3.0.a0
+ - libstdcxx >=14
+ - libgcc >=14
+ - zstd >=1.5.7,<1.6.0a0
+ - fmt >=12.1.0,<12.2.0a0
+ - python_abi 3.11.* *_cp311
+ - openssl >=3.5.4,<4.0a0
+ - yaml-cpp >=0.8.0,<0.9.0a0
+ - spdlog >=1.17.0,<1.18.0a0
+ - nlohmann_json-abi ==3.12.0
+ - pybind11-abi ==11
+ - libmamba >=2.5.0,<2.6.0a0
+ license: BSD-3-Clause
+ license_family: BSD
+ purls:
+ - pkg:pypi/libmambapy?source=hash-mapping
+ size: 944797
+ timestamp: 1767884157872
+- conda: https://conda.anaconda.org/conda-forge/linux-64/libmambapy-2.5.0-py314hcbd71af_0.conda
+ sha256: 578a2ec09095c81674af0fa88ee44083c3a4ab10c31b498ddfa519fc9ff855b1
+ md5: 54125b30d5031808bca8018561843f40
+ depends:
+ - python
+ - libmamba ==2.5.0 hd28c85e_0
+ - libmamba-spdlog ==2.5.0 h12fcf84_0
+ - libstdcxx >=14
+ - libgcc >=14
+ - __glibc >=2.17,<3.0.a0
+ - zstd >=1.5.7,<1.6.0a0
+ - python_abi 3.14.* *_cp314
+ - pybind11-abi ==11
+ - fmt >=12.1.0,<12.2.0a0
+ - nlohmann_json-abi ==3.12.0
+ - spdlog >=1.17.0,<1.18.0a0
+ - openssl >=3.5.4,<4.0a0
+ - yaml-cpp >=0.8.0,<0.9.0a0
+ - libmamba >=2.5.0,<2.6.0a0
+ license: BSD-3-Clause
+ license_family: BSD
+ purls:
+ - pkg:pypi/libmambapy?source=hash-mapping
+ size: 948138
+ timestamp: 1767884157875
+- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libmambapy-2.5.0-py310hdf79504_0.conda
+ sha256: 48fe0ec831974af7f660bfe8e8bfbf5a1a4a2fed125496b1ee53fd83c40a5027
+ md5: 59097ccbbc66568039aa714f48f77700
+ depends:
+ - python
+ - libmamba ==2.5.0 hc712cdd_0
+ - libmamba-spdlog ==2.5.0 h3ad78e7_0
+ - libstdcxx >=14
+ - libgcc >=14
+ - python 3.10.* *_cpython
+ - zstd >=1.5.7,<1.6.0a0
+ - pybind11-abi ==11
+ - spdlog >=1.17.0,<1.18.0a0
+ - yaml-cpp >=0.8.0,<0.9.0a0
+ - fmt >=12.1.0,<12.2.0a0
+ - nlohmann_json-abi ==3.12.0
+ - openssl >=3.5.4,<4.0a0
+ - python_abi 3.10.* *_cp310
+ - libmamba >=2.5.0,<2.6.0a0
+ license: BSD-3-Clause
+ license_family: BSD
+ purls:
+ - pkg:pypi/libmambapy?source=hash-mapping
+ size: 832789
+ timestamp: 1767884182399
+- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libmambapy-2.5.0-py311h6a8bf82_0.conda
+ sha256: caef2c6e32e15afc8bb1cf66151223738a29d45cf639acad0267bce948518cc7
+ md5: e022e9542b664361fcbc1f9c5528a0a8
+ depends:
+ - python
+ - libmamba ==2.5.0 hc712cdd_0
+ - libmamba-spdlog ==2.5.0 h3ad78e7_0
+ - python 3.11.* *_cpython
+ - libstdcxx >=14
+ - libgcc >=14
+ - nlohmann_json-abi ==3.12.0
+ - fmt >=12.1.0,<12.2.0a0
+ - libmamba >=2.5.0,<2.6.0a0
+ - python_abi 3.11.* *_cp311
+ - zstd >=1.5.7,<1.6.0a0
+ - pybind11-abi ==11
+ - openssl >=3.5.4,<4.0a0
+ - yaml-cpp >=0.8.0,<0.9.0a0
+ - spdlog >=1.17.0,<1.18.0a0
+ license: BSD-3-Clause
+ license_family: BSD
+ purls:
+ - pkg:pypi/libmambapy?source=hash-mapping
+ size: 832040
+ timestamp: 1767884182400
+- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libmambapy-2.5.0-py314h709e558_0.conda
+ sha256: c226d92922115e9e4a0097b15521b0238a69a028ed0d525f5a5ed6696314ed69
+ md5: b9108a7151ea087a321b7ebe3aaba999
+ depends:
+ - python
+ - libmamba ==2.5.0 hc712cdd_0
+ - libmamba-spdlog ==2.5.0 h3ad78e7_0
+ - python 3.14.* *_cp314
+ - libstdcxx >=14
+ - libgcc >=14
+ - fmt >=12.1.0,<12.2.0a0
+ - spdlog >=1.17.0,<1.18.0a0
+ - python_abi 3.14.* *_cp314
+ - zstd >=1.5.7,<1.6.0a0
+ - yaml-cpp >=0.8.0,<0.9.0a0
+ - libmamba >=2.5.0,<2.6.0a0
+ - pybind11-abi ==11
+ - openssl >=3.5.4,<4.0a0
+ - nlohmann_json-abi ==3.12.0
+ license: BSD-3-Clause
+ license_family: BSD
+ purls:
+ - pkg:pypi/libmambapy?source=hash-mapping
+ size: 834849
+ timestamp: 1767884182402
+- conda: https://conda.anaconda.org/conda-forge/osx-64/libmambapy-2.5.0-py314haca2e77_0.conda
+ sha256: a3dad1d241d2fd1831dd4e8893ecdd4e4daa1cba4f1c3d8b630d5f4cd5a1279d
+ md5: a015fcf12fbe739adfae4cb32f627da6
+ depends:
+ - python
+ - libmamba ==2.5.0 h7fe6c55_0
+ - libmamba-spdlog ==2.5.0 hb923e0c_0
+ - __osx >=10.13
+ - libcxx >=19
+ - fmt >=12.1.0,<12.2.0a0
+ - pybind11-abi ==11
+ - libmamba >=2.5.0,<2.6.0a0
+ - yaml-cpp >=0.8.0,<0.9.0a0
+ - python_abi 3.14.* *_cp314
+ - zstd >=1.5.7,<1.6.0a0
+ - spdlog >=1.17.0,<1.18.0a0
+ - nlohmann_json-abi ==3.12.0
+ - openssl >=3.5.4,<4.0a0
+ license: BSD-3-Clause
+ license_family: BSD
+ purls:
+ - pkg:pypi/libmambapy?source=hash-mapping
+ size: 815795
+ timestamp: 1767884200763
+- conda: https://conda.anaconda.org/conda-forge/osx-arm64/libmambapy-2.5.0-py314hf8f60b7_0.conda
+ sha256: 11824fa9b721afe43cfd83ba899c893c1dba0b42c85ec618aa9284fd2ad66d6c
+ md5: c215957a49ac69b30d94a39eb1182009
+ depends:
+ - python
+ - libmamba ==2.5.0 h7950639_0
+ - libmamba-spdlog ==2.5.0 h85b9800_0
+ - __osx >=11.0
+ - python 3.14.* *_cp314
+ - libcxx >=19
+ - yaml-cpp >=0.8.0,<0.9.0a0
+ - libmamba >=2.5.0,<2.6.0a0
+ - zstd >=1.5.7,<1.6.0a0
+ - spdlog >=1.17.0,<1.18.0a0
+ - nlohmann_json-abi ==3.12.0
+ - python_abi 3.14.* *_cp314
+ - openssl >=3.5.4,<4.0a0
+ - fmt >=12.1.0,<12.2.0a0
+ - pybind11-abi ==11
+ license: BSD-3-Clause
+ license_family: BSD
+ purls:
+ - pkg:pypi/libmambapy?source=hash-mapping
+ size: 769644
+ timestamp: 1767884201481
+- conda: https://conda.anaconda.org/conda-forge/win-64/libmambapy-2.5.0-py310h1916185_0.conda
+ sha256: c62cb131596e5aaba82591a5c76081d06b6b4dde5af25c25cbd796efc0458fab
+ md5: 4c67f7b1103f72faa72a50f79587990b
+ depends:
+ - python
+ - libmamba ==2.5.0 h06825f5_0
+ - libmamba-spdlog ==2.5.0 h9ae1bf1_0
+ - vc >=14.3,<15
+ - vc14_runtime >=14.44.35208
+ - ucrt >=10.0.20348.0
+ - spdlog >=1.17.0,<1.18.0a0
+ - python_abi 3.10.* *_cp310
+ - fmt >=12.1.0,<12.2.0a0
+ - nlohmann_json-abi ==3.12.0
+ - openssl >=3.5.4,<4.0a0
+ - yaml-cpp >=0.8.0,<0.9.0a0
+ - libmamba >=2.5.0,<2.6.0a0
+ - zstd >=1.5.7,<1.6.0a0
+ - pybind11-abi ==11
+ license: BSD-3-Clause
+ license_family: BSD
+ purls:
+ - pkg:pypi/libmambapy?source=hash-mapping
+ size: 583910
+ timestamp: 1767884194854
+- conda: https://conda.anaconda.org/conda-forge/win-64/libmambapy-2.5.0-py311hb0041a4_0.conda
+ sha256: d3ec31a3cfb43b07d04899cfd84376a31049be9611ab249b4889f0672e6d81b9
+ md5: 2b522dd15f2449d921759864fd0648aa
+ depends:
+ - python
+ - libmamba ==2.5.0 h06825f5_0
+ - libmamba-spdlog ==2.5.0 h9ae1bf1_0
+ - vc >=14.3,<15
+ - vc14_runtime >=14.44.35208
+ - ucrt >=10.0.20348.0
+ - nlohmann_json-abi ==3.12.0
+ - openssl >=3.5.4,<4.0a0
+ - python_abi 3.11.* *_cp311
+ - zstd >=1.5.7,<1.6.0a0
+ - libmamba >=2.5.0,<2.6.0a0
+ - fmt >=12.1.0,<12.2.0a0
+ - pybind11-abi ==11
+ - yaml-cpp >=0.8.0,<0.9.0a0
+ - spdlog >=1.17.0,<1.18.0a0
+ license: BSD-3-Clause
+ license_family: BSD
+ purls:
+ - pkg:pypi/libmambapy?source=hash-mapping
+ size: 583683
+ timestamp: 1767884194856
+- conda: https://conda.anaconda.org/conda-forge/win-64/libmambapy-2.5.0-py314h532c739_0.conda
+ sha256: 3b5bec6472c07448e8485def16a11157c32295e9016130809fc4b3b1e6dda174
+ md5: c9cd67775b772d64b54239fefb4d8504
+ depends:
+ - python
+ - libmamba ==2.5.0 h06825f5_0
+ - libmamba-spdlog ==2.5.0 h9ae1bf1_0
+ - vc >=14.3,<15
+ - vc14_runtime >=14.44.35208
+ - ucrt >=10.0.20348.0
+ - fmt >=12.1.0,<12.2.0a0
+ - zstd >=1.5.7,<1.6.0a0
+ - yaml-cpp >=0.8.0,<0.9.0a0
+ - nlohmann_json-abi ==3.12.0
+ - spdlog >=1.17.0,<1.18.0a0
+ - pybind11-abi ==11
+ - libmamba >=2.5.0,<2.6.0a0
+ - python_abi 3.14.* *_cp314
+ - openssl >=3.5.4,<4.0a0
+ license: BSD-3-Clause
+ license_family: BSD
+ purls:
+ - pkg:pypi/libmambapy?source=hash-mapping
+ size: 587744
+ timestamp: 1767884194858
+- conda: https://conda.anaconda.org/conda-forge/linux-64/libmpdec-4.0.0-hb03c661_1.conda
+ sha256: fe171ed5cf5959993d43ff72de7596e8ac2853e9021dec0344e583734f1e0843
+ md5: 2c21e66f50753a083cbe6b80f38268fa
+ depends:
+ - __glibc >=2.17,<3.0.a0
+ - libgcc >=14
+ license: BSD-2-Clause
+ license_family: BSD
+ purls: []
+ size: 92400
+ timestamp: 1769482286018
+- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libmpdec-4.0.0-he30d5cf_1.conda
+ sha256: 57c0dd12d506e84541c4e877898bd2a59cca141df493d34036f18b2751e0a453
+ md5: 7b9813e885482e3ccb1fa212b86d7fd0
+ depends:
+ - libgcc >=14
+ license: BSD-2-Clause
+ license_family: BSD
+ purls: []
+ size: 114056
+ timestamp: 1769482343003
+- conda: https://conda.anaconda.org/conda-forge/osx-64/libmpdec-4.0.0-hf3981d6_1.conda
+ sha256: 1096c740109386607938ab9f09a7e9bca06d86770a284777586d6c378b8fb3fd
+ md5: ec88ba8a245855935b871a7324373105
+ depends:
+ - __osx >=10.13
+ license: BSD-2-Clause
+ license_family: BSD
+ purls: []
+ size: 79899
+ timestamp: 1769482558610
+- conda: https://conda.anaconda.org/conda-forge/osx-arm64/libmpdec-4.0.0-h84a0fba_1.conda
+ sha256: 1089c7f15d5b62c622625ec6700732ece83be8b705da8c6607f4dabb0c4bd6d2
+ md5: 57c4be259f5e0b99a5983799a228ae55
+ depends:
+ - __osx >=11.0
+ license: BSD-2-Clause
+ license_family: BSD
+ purls: []
+ size: 73690
+ timestamp: 1769482560514
+- conda: https://conda.anaconda.org/conda-forge/win-64/libmpdec-4.0.0-hfd05255_1.conda
+ sha256: 40dcd0b9522a6e0af72a9db0ced619176e7cfdb114855c7a64f278e73f8a7514
+ md5: e4a9fc2bba3b022dad998c78856afe47
+ depends:
+ - ucrt >=10.0.20348.0
+ - vc >=14.3,<15
+ - vc14_runtime >=14.44.35208
+ license: BSD-2-Clause
+ license_family: BSD
+ purls: []
+ size: 89411
+ timestamp: 1769482314283
+- conda: https://conda.anaconda.org/conda-forge/linux-64/libnghttp2-1.67.0-had1ee68_0.conda
+ sha256: a4a7dab8db4dc81c736e9a9b42bdfd97b087816e029e221380511960ac46c690
+ md5: b499ce4b026493a13774bcf0f4c33849
+ depends:
+ - __glibc >=2.17,<3.0.a0
+ - c-ares >=1.34.5,<2.0a0
+ - libev >=4.33,<4.34.0a0
+ - libev >=4.33,<5.0a0
+ - libgcc >=14
+ - libstdcxx >=14
+ - libzlib >=1.3.1,<2.0a0
+ - openssl >=3.5.2,<4.0a0
+ license: MIT
+ license_family: MIT
+ purls: []
+ size: 666600
+ timestamp: 1756834976695
+- conda: https://conda.anaconda.org/conda-forge/linux-64/libnghttp2-1.68.1-h877daf1_0.conda
+ sha256: 663444d77a42f2265f54fb8b48c5450bfff4388d9c0f8253dd7855f0d993153f
+ md5: 2a45e7f8af083626f009645a6481f12d
+ depends:
+ - __glibc >=2.17,<3.0.a0
+ - c-ares >=1.34.6,<2.0a0
+ - libev >=4.33,<4.34.0a0
+ - libev >=4.33,<5.0a0
+ - libgcc >=14
+ - libstdcxx >=14
+ - libzlib >=1.3.1,<2.0a0
+ - openssl >=3.5.5,<4.0a0
+ license: MIT
+ license_family: MIT
+ purls: []
+ size: 663344
+ timestamp: 1773854035739
+- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libnghttp2-1.67.0-ha888d0e_0.conda
+ sha256: b03f406fd5c3f865a5e08c89b625245a9c4e026438fd1a445e45e6a0d69c2749
+ md5: 981082c1cc262f514a5a2cf37cab9b81
+ depends:
+ - c-ares >=1.34.5,<2.0a0
+ - libev >=4.33,<4.34.0a0
+ - libev >=4.33,<5.0a0
+ - libgcc >=14
+ - libstdcxx >=14
+ - libzlib >=1.3.1,<2.0a0
+ - openssl >=3.5.2,<4.0a0
+ license: MIT
+ license_family: MIT
+ purls: []
+ size: 728661
+ timestamp: 1756835019535
+- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libnghttp2-1.68.1-hd3077d7_0.conda
+ sha256: 13782715b9eeebc4ad16d36e84ca569d1495e3516aea3fe546a32caa0a597d82
+ md5: be5f0f007a4500a226ef001115535a3d
+ depends:
+ - c-ares >=1.34.6,<2.0a0
+ - libev >=4.33,<4.34.0a0
+ - libev >=4.33,<5.0a0
+ - libgcc >=14
+ - libstdcxx >=14
+ - libzlib >=1.3.1,<2.0a0
+ - openssl >=3.5.5,<4.0a0
+ license: MIT
+ license_family: MIT
+ purls: []
+ size: 726928
+ timestamp: 1773854039807
+- conda: https://conda.anaconda.org/conda-forge/osx-64/libnghttp2-1.52.0-he2ab024_0.conda
+ sha256: 093e4f3f62b3b07befa403e84a1f550cffe3b3961e435d42a75284f44be5f68a
+ md5: 12ac7d100bf260263e30a019517f42a2
+ depends:
+ - c-ares >=1.18.1,<2.0a0
+ - libcxx >=14.0.6
+ - libev >=4.33,<4.34.0a0
+ - libzlib >=1.2.13,<2.0.0a0
+ - openssl >=3.0.8,<4.0a0
+ license: MIT
+ license_family: MIT
+ purls: []
+ size: 613074
+ timestamp: 1677678399575
+- conda: https://conda.anaconda.org/conda-forge/osx-64/libnghttp2-1.67.0-h3338091_0.conda
+ sha256: c48d7e1cc927aef83ff9c48ae34dd1d7495c6ccc1edc4a3a6ba6aff1624be9ac
+ md5: e7630cef881b1174d40f3e69a883e55f
+ depends:
+ - __osx >=10.13
+ - c-ares >=1.34.5,<2.0a0
+ - libcxx >=19
+ - libev >=4.33,<4.34.0a0
+ - libev >=4.33,<5.0a0
+ - libzlib >=1.3.1,<2.0a0
+ - openssl >=3.5.2,<4.0a0
+ license: MIT
+ license_family: MIT
+ size: 605680
+ timestamp: 1756835898134
+- conda: https://conda.anaconda.org/conda-forge/osx-64/libnghttp2-1.68.1-h70048d4_0.conda
+ sha256: 899551e16aac9dfb85bfc2fd98b655f4d1b7fea45720ec04ccb93d95b4d24798
+ md5: dba4c95e2fe24adcae4b77ebf33559ae
+ depends:
+ - __osx >=11.0
+ - c-ares >=1.34.6,<2.0a0
+ - libcxx >=19
+ - libev >=4.33,<4.34.0a0
+ - libev >=4.33,<5.0a0
+ - libzlib >=1.3.1,<2.0a0
+ - openssl >=3.5.5,<4.0a0
+ license: MIT
+ license_family: MIT
+ purls: []
+ size: 606749
+ timestamp: 1773854765508
+- conda: https://conda.anaconda.org/conda-forge/osx-arm64/libnghttp2-1.52.0-hae82a92_0.conda
+ sha256: 1a3944d6295dcbecdf6489ce8a05fe416ad401727c901ec390e9200a351bdb10
+ md5: 1d319e95a0216f801293626a00337712
+ depends:
+ - c-ares >=1.18.1,<2.0a0
+ - libcxx >=14.0.6
+ - libev >=4.33,<4.34.0a0
+ - libzlib >=1.2.13,<2.0.0a0
+ - openssl >=3.0.8,<4.0a0
+ license: MIT
+ license_family: MIT
+ purls: []
+ size: 564295
+ timestamp: 1677678452375
+- conda: https://conda.anaconda.org/conda-forge/osx-arm64/libnghttp2-1.67.0-hc438710_0.conda
+ sha256: a07cb53b5ffa2d5a18afc6fd5a526a5a53dd9523fbc022148bd2f9395697c46d
+ md5: a4b4dd73c67df470d091312ab87bf6ae
+ depends:
+ - __osx >=11.0
+ - c-ares >=1.34.5,<2.0a0
+ - libcxx >=19
+ - libev >=4.33,<4.34.0a0
+ - libev >=4.33,<5.0a0
+ - libzlib >=1.3.1,<2.0a0
+ - openssl >=3.5.2,<4.0a0
+ license: MIT
+ license_family: MIT
+ size: 575454
+ timestamp: 1756835746393
+- conda: https://conda.anaconda.org/conda-forge/osx-arm64/libnghttp2-1.68.1-h8f3e76b_0.conda
+ sha256: 2bc7bc3978066f2c274ebcbf711850cc9ab92e023e433b9631958a098d11e10a
+ md5: 6ea18834adbc3b33df9bd9fb45eaf95b
+ depends:
+ - __osx >=11.0
+ - c-ares >=1.34.6,<2.0a0
+ - libcxx >=19
+ - libev >=4.33,<4.34.0a0
+ - libev >=4.33,<5.0a0
+ - libzlib >=1.3.1,<2.0a0
+ - openssl >=3.5.5,<4.0a0
+ license: MIT
+ license_family: MIT
+ purls: []
+ size: 576526
+ timestamp: 1773854624224
+- conda: https://conda.anaconda.org/conda-forge/linux-64/libnsl-2.0.1-hb9d3cd8_1.conda
+ sha256: 927fe72b054277cde6cb82597d0fcf6baf127dcbce2e0a9d8925a68f1265eef5
+ md5: d864d34357c3b65a4b731f78c0801dc4
+ depends:
+ - __glibc >=2.17,<3.0.a0
+ - libgcc >=13
+ license: LGPL-2.1-only
+ license_family: GPL
+ purls: []
+ size: 33731
+ timestamp: 1750274110928
+- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libnsl-2.0.1-h86ecc28_1.conda
+ sha256: c0dc4d84198e3eef1f37321299e48e2754ca83fd12e6284754e3cb231357c3a5
+ md5: d5d58b2dc3e57073fe22303f5fed4db7
+ depends:
+ - libgcc >=13
+ license: LGPL-2.1-only
+ license_family: GPL
+ purls: []
+ size: 34831
+ timestamp: 1750274211
+- conda: https://conda.anaconda.org/conda-forge/linux-64/libopenblas-0.3.30-pthreads_h94d23a6_4.conda
+ sha256: 199d79c237afb0d4780ccd2fbf829cea80743df60df4705202558675e07dd2c5
+ md5: be43915efc66345cccb3c310b6ed0374
+ depends:
+ - __glibc >=2.17,<3.0.a0
+ - libgcc >=14
+ - libgfortran
+ - libgfortran5 >=14.3.0
+ constrains:
+ - openblas >=0.3.30,<0.3.31.0a0
+ license: BSD-3-Clause
+ license_family: BSD
+ purls: []
+ size: 5927939
+ timestamp: 1763114673331
+- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libopenblas-0.3.30-pthreads_h9d3fd7e_4.conda
+ sha256: 794a7270ea049ec931537874cd8d2de0ef4b3cef71c055cfd8b4be6d2f4228b0
+ md5: 11d7d57b7bdd01da745bbf2b67020b2e
+ depends:
+ - libgcc >=14
+ - libgfortran
+ - libgfortran5 >=14.3.0
+ constrains:
+ - openblas >=0.3.30,<0.3.31.0a0
+ license: BSD-3-Clause
+ license_family: BSD
+ purls: []
+ size: 4959359
+ timestamp: 1763114173544
+- conda: https://conda.anaconda.org/conda-forge/osx-64/libopenblas-0.3.27-openmp_hfef2a42_0.conda
+ sha256: 45519189c0295296268cb7eabeeaa03ef54d780416c9a24be1d2a21db63a7848
+ md5: 00237c9c7f2cb6725fe2960680a6e225
+ depends:
+ - libgfortran >=5
+ - libgfortran5 >=12.3.0
+ - llvm-openmp >=16.0.6
+ constrains:
+ - openblas >=0.3.27,<0.3.28.0a0
+ license: BSD-3-Clause
+ license_family: BSD
+ purls: []
+ size: 6047531
+ timestamp: 1712366254156
+- conda: https://conda.anaconda.org/conda-forge/osx-arm64/libopenblas-0.3.27-openmp_h6c19121_0.conda
+ sha256: feb2662444fc98a4842fe54cc70b1f109b2146108e7bac2b3bbad1f219cede90
+ md5: 82eba59f4eca26a9fc904d584f8761c0
+ depends:
+ - libgfortran >=5
+ - libgfortran5 >=12.3.0
+ - llvm-openmp >=16.0.6
+ constrains:
+ - openblas >=0.3.27,<0.3.28.0a0
+ license: BSD-3-Clause
+ license_family: BSD
+ purls: []
+ size: 2925015
+ timestamp: 1712364212874
+- conda: https://conda.anaconda.org/conda-forge/linux-64/libsanitizer-14.3.0-h8f1669f_18.conda
+ sha256: e03ed186eefb46d7800224ad34bad1268c9d19ecb8f621380a50601c6221a4a7
+ md5: ad3a0e2dc4cce549b2860e2ef0e6d75b
+ depends:
+ - __glibc >=2.17,<3.0.a0
+ - libgcc >=14.3.0
+ - libstdcxx >=14.3.0
+ license: GPL-3.0-only WITH GCC-exception-3.1
+ license_family: GPL
+ purls: []
+ size: 7949259
+ timestamp: 1771377982207
+- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libsanitizer-14.3.0-hedb4206_18.conda
+ sha256: 48641a458e3da681038af7ebdab143f9b6861ad9d1dcc2b4997ff2b744709423
+ md5: 03feac8b6e64b72ae536fdb264e2618d
+ depends:
+ - libgcc >=14.3.0
+ - libstdcxx >=14.3.0
+ license: GPL-3.0-only WITH GCC-exception-3.1
+ license_family: GPL
+ purls: []
+ size: 7526147
+ timestamp: 1771377792671
+- conda: https://conda.anaconda.org/conda-forge/linux-64/libsolv-0.7.35-h9463b59_0.conda
+ sha256: 2fc2cdc8ea4dfd9277ae910fa3cfbf342d7890837a2002cf427fd306a869150b
+ md5: 21769ce326958ec230cdcbd0f2ad97eb
+ depends:
+ - libstdcxx >=14
+ - libgcc >=14
+ - __glibc >=2.17,<3.0.a0
+ - libzlib >=1.3.1,<2.0a0
+ license: BSD-3-Clause
+ license_family: BSD
+ purls: []
+ size: 518374
+ timestamp: 1754325691186
+- conda: https://conda.anaconda.org/conda-forge/linux-64/libsolv-0.7.36-h9463b59_0.conda
+ sha256: 2a336d83e25e67b69548ee233188fa612cbce6809b3e2d45dd0b6520d75b3870
+ md5: e6e2535fc6b69b08cdbaeab01aa1c277
+ depends:
+ - libstdcxx >=14
+ - libgcc >=14
+ - __glibc >=2.17,<3.0.a0
+ - libzlib >=1.3.1,<2.0a0
+ license: BSD-3-Clause
+ license_family: BSD
+ purls: []
+ size: 519098
+ timestamp: 1773328331358
+- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libsolv-0.7.35-hdda61c4_0.conda
+ sha256: f68dde30e903721825214310a98ff2444857d168b12ef657c064aad22a620f06
+ md5: 3e817cbcc10f018c547a1b4885094b15
+ depends:
+ - libstdcxx >=14
+ - libgcc >=14
+ - libzlib >=1.3.1,<2.0a0
+ license: BSD-3-Clause
+ license_family: BSD
+ size: 535157
+ timestamp: 1754325829284
+- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libsolv-0.7.36-hdda61c4_0.conda
+ sha256: 25019059bcbe38bdf66899d3d7b5dd48d17e01b2ff9f9e8e4d494ce51e156d75
+ md5: 9b21c050436d116716f113cecd3bbcb8
+ depends:
+ - libstdcxx >=14
+ - libgcc >=14
+ - libzlib >=1.3.1,<2.0a0
+ license: BSD-3-Clause
+ license_family: BSD
+ purls: []
+ size: 535353
+ timestamp: 1773328550407
+- conda: https://conda.anaconda.org/conda-forge/osx-64/libsolv-0.7.35-h6fd32b5_0.conda
+ sha256: 9a510035a9b72e3e059f2cd5f031f300ed8f2971014fcdea06a84c104ce3b44b
+ md5: 9aca75cdbe9f71e9b2e717fb3e02cba0
+ depends:
+ - __osx >=10.13
+ - libcxx >=19
+ - libzlib >=1.3.1,<2.0a0
+ license: BSD-3-Clause
+ license_family: BSD
+ size: 457297
+ timestamp: 1754325699071
+- conda: https://conda.anaconda.org/conda-forge/osx-64/libsolv-0.7.36-hf97c9bc_0.conda
+ sha256: 622bc7d0799ba7f9825ca82fcee3d4d60bef3acdb1ad1136bfa618e479c6d338
+ md5: 06871f2bcba5d0026d6698f363c36a87
+ depends:
+ - __osx >=11.0
+ - libcxx >=19
+ - libzlib >=1.3.1,<2.0a0
+ license: BSD-3-Clause
+ license_family: BSD
+ purls: []
+ size: 459988
+ timestamp: 1773328382913
+- conda: https://conda.anaconda.org/conda-forge/osx-arm64/libsolv-0.7.35-h5f525b2_0.conda
+ sha256: 6da97a1c572659c2be3c3f2f39d9238dac5af2b1fd546adf2b735b0fda2ed8ec
+ md5: b7ffc6dc926929b9b35af5084a761f26
+ depends:
+ - libcxx >=19
+ - __osx >=11.0
+ - libzlib >=1.3.1,<2.0a0
+ license: BSD-3-Clause
+ license_family: BSD
+ size: 428408
+ timestamp: 1754325703193
+- conda: https://conda.anaconda.org/conda-forge/osx-arm64/libsolv-0.7.36-h7d962ec_0.conda
+ sha256: d7eeef792c8b12804c99b6a2c66e635e4f7d7a3d34713af070c2aa6c41c9b750
+ md5: 038c047500a1db74206cf56811e80e08
+ depends:
+ - __osx >=11.0
+ - libcxx >=19
+ - libzlib >=1.3.1,<2.0a0
+ license: BSD-3-Clause
+ license_family: BSD
+ purls: []
+ size: 428233
+ timestamp: 1773328439105
+- conda: https://conda.anaconda.org/conda-forge/win-64/libsolv-0.7.35-h8883371_0.conda
+ sha256: 80ccb7857fa2b60679a5209ca04334c86c46a441e8f4f2859308b69f8e1e928a
+ md5: 987be7025314bcfe936de3f0e91082b5
+ depends:
+ - vc >=14.3,<15
+ - vc14_runtime >=14.44.35208
+ - ucrt >=10.0.20348.0
+ - vc >=14.3,<15
+ - vc14_runtime >=14.44.35208
+ - ucrt >=10.0.20348.0
+ - libzlib >=1.3.1,<2.0a0
+ license: BSD-3-Clause
+ license_family: BSD
+ purls: []
+ size: 466924
+ timestamp: 1754325716718
+- conda: https://conda.anaconda.org/conda-forge/win-64/libsolv-0.7.36-h8883371_0.conda
+ sha256: a5abc59cd2644b964a303cc62ef8c2e08adad05d14941196130cd718d00e6eea
+ md5: 3ab153559588783712f13ab285a0a506
+ depends:
+ - vc >=14.3,<15
+ - vc14_runtime >=14.44.35208
+ - ucrt >=10.0.20348.0
+ - libzlib >=1.3.1,<2.0a0
+ license: BSD-3-Clause
+ license_family: BSD
+ purls: []
+ size: 468194
+ timestamp: 1773328370793
+- conda: https://conda.anaconda.org/conda-forge/linux-64/libsqlite-3.52.0-hf4e2dac_0.conda
+ sha256: d716847b7deca293d2e49ed1c8ab9e4b9e04b9d780aea49a97c26925b28a7993
+ md5: fd893f6a3002a635b5e50ceb9dd2c0f4
+ depends:
+ - __glibc >=2.17,<3.0.a0
+ - icu >=78.2,<79.0a0
+ - libgcc >=14
+ - libzlib >=1.3.1,<2.0a0
+ license: blessing
+ purls: []
+ size: 951405
+ timestamp: 1772818874251
+- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libsqlite-3.52.0-h10b116e_0.conda
+ sha256: 1ddaf91b44fae83856276f4cb7ce544ffe41d4b55c1e346b504c6b45f19098d6
+ md5: 77891484f18eca74b8ad83694da9815e
+ depends:
+ - icu >=78.2,<79.0a0
+ - libgcc >=14
+ - libzlib >=1.3.1,<2.0a0
+ license: blessing
+ purls: []
+ size: 952296
+ timestamp: 1772818881550
+- conda: https://conda.anaconda.org/conda-forge/osx-64/libsqlite-3.45.3-h92b6c6a_0.conda
+ sha256: 4d44b68fb29dcbc2216a8cae0b274b02ef9b4ae05d1d0f785362ed30b91c9b52
+ md5: 68e462226209f35182ef66eda0f794ff
+ depends:
+ - libzlib >=1.2.13,<2.0.0a0
+ license: Unlicense
+ purls: []
+ size: 902546
+ timestamp: 1713367776445
+- conda: https://conda.anaconda.org/conda-forge/osx-64/libsqlite-3.52.0-h77d7759_0.conda
+ sha256: f500d1cd50cfcd288d02b8fc3c3b7ecf8de6fec7b86e57ea058def02908e4231
+ md5: d553eb96758e038b04027b30fe314b2d
+ depends:
+ - __osx >=11.0
+ - libzlib >=1.3.1,<2.0a0
+ license: blessing
+ purls: []
+ size: 996526
+ timestamp: 1772819669038
+- conda: https://conda.anaconda.org/conda-forge/osx-arm64/libsqlite-3.45.3-h091b4b1_0.conda
+ sha256: 4337f466eb55bbdc74e168b52ec8c38f598e3664244ec7a2536009036e2066cc
+ md5: c8c1186c7f3351f6ffddb97b1f54fc58
+ depends:
+ - libzlib >=1.2.13,<2.0.0a0
+ license: Unlicense
+ purls: []
+ size: 824794
+ timestamp: 1713367748819
+- conda: https://conda.anaconda.org/conda-forge/osx-arm64/libsqlite-3.52.0-h1ae2325_0.conda
+ sha256: beb0fd5594d6d7c7cd42c992b6bb4d66cbb39d6c94a8234f15956da99a04306c
+ md5: f6233a3fddc35a2ec9f617f79d6f3d71
+ depends:
+ - __osx >=11.0
+ - icu >=78.2,<79.0a0
+ - libzlib >=1.3.1,<2.0a0
+ license: blessing
+ purls: []
+ size: 918420
+ timestamp: 1772819478684
+- conda: https://conda.anaconda.org/conda-forge/win-64/libsqlite-3.52.0-hf5d6505_0.conda
+ sha256: 5fccf1e4e4062f8b9a554abf4f9735a98e70f82e2865d0bfdb47b9de94887583
+ md5: 8830689d537fda55f990620680934bb1
+ depends:
+ - ucrt >=10.0.20348.0
+ - vc >=14.3,<15
+ - vc14_runtime >=14.44.35208
+ license: blessing
+ purls: []
+ size: 1297302
+ timestamp: 1772818899033
+- conda: https://conda.anaconda.org/conda-forge/linux-64/libssh2-1.11.1-hcf80075_0.conda
+ sha256: fa39bfd69228a13e553bd24601332b7cfeb30ca11a3ca50bb028108fe90a7661
+ md5: eecce068c7e4eddeb169591baac20ac4
+ depends:
+ - __glibc >=2.17,<3.0.a0
+ - libgcc >=13
+ - libzlib >=1.3.1,<2.0a0
+ - openssl >=3.5.0,<4.0a0
+ license: BSD-3-Clause
+ license_family: BSD
+ purls: []
+ size: 304790
+ timestamp: 1745608545575
+- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libssh2-1.11.1-h18c354c_0.conda
+ sha256: 1e289bcce4ee6a5817a19c66e296f3c644dcfa6e562e5c1cba807270798814e7
+ md5: eecc495bcfdd9da8058969656f916cc2
+ depends:
+ - libgcc >=13
+ - libzlib >=1.3.1,<2.0a0
+ - openssl >=3.5.0,<4.0a0
+ license: BSD-3-Clause
+ license_family: BSD
+ purls: []
+ size: 311396
+ timestamp: 1745609845915
+- conda: https://conda.anaconda.org/conda-forge/osx-64/libssh2-1.11.0-hd019ec5_0.conda
+ sha256: f3886763b88f4b24265db6036535ef77b7b77ce91b1cbe588c0fbdd861eec515
+ md5: ca3a72efba692c59a90d4b9fc0dfe774
+ depends:
+ - libzlib >=1.2.13,<2.0.0a0
+ - openssl >=3.1.1,<4.0a0
+ license: BSD-3-Clause
+ license_family: BSD
+ purls: []
+ size: 259556
+ timestamp: 1685837820566
+- conda: https://conda.anaconda.org/conda-forge/osx-64/libssh2-1.11.1-hed3591d_0.conda
+ sha256: 00654ba9e5f73aa1f75c1f69db34a19029e970a4aeb0fa8615934d8e9c369c3c
+ md5: a6cb15db1c2dc4d3a5f6cf3772e09e81
+ depends:
+ - __osx >=10.13
+ - libzlib >=1.3.1,<2.0a0
+ - openssl >=3.5.0,<4.0a0
+ license: BSD-3-Clause
+ license_family: BSD
+ purls: []
+ size: 284216
+ timestamp: 1745608575796
+- conda: https://conda.anaconda.org/conda-forge/osx-arm64/libssh2-1.11.0-h7a5bd25_0.conda
+ sha256: bb57d0c53289721fff1eeb3103a1c6a988178e88d8a8f4345b0b91a35f0e0015
+ md5: 029f7dc931a3b626b94823bc77830b01
+ depends:
+ - libzlib >=1.2.13,<2.0.0a0
+ - openssl >=3.1.1,<4.0a0
+ license: BSD-3-Clause
+ license_family: BSD
+ purls: []
+ size: 255610
+ timestamp: 1685837894256
+- conda: https://conda.anaconda.org/conda-forge/osx-arm64/libssh2-1.11.1-h1590b86_0.conda
+ sha256: 8bfe837221390ffc6f111ecca24fa12d4a6325da0c8d131333d63d6c37f27e0a
+ md5: b68e8f66b94b44aaa8de4583d3d4cc40
+ depends:
+ - libzlib >=1.3.1,<2.0a0
+ - openssl >=3.5.0,<4.0a0
+ license: BSD-3-Clause
+ license_family: BSD
+ purls: []
+ size: 279193
+ timestamp: 1745608793272
+- conda: https://conda.anaconda.org/conda-forge/win-64/libssh2-1.11.1-h9aa295b_0.conda
+ sha256: cbdf93898f2e27cefca5f3fe46519335d1fab25c4ea2a11b11502ff63e602c09
+ md5: 9dce2f112bfd3400f4f432b3d0ac07b2
+ depends:
+ - libzlib >=1.3.1,<2.0a0
+ - openssl >=3.5.0,<4.0a0
+ - ucrt >=10.0.20348.0
+ - vc >=14.2,<15
+ - vc14_runtime >=14.29.30139
+ license: BSD-3-Clause
+ license_family: BSD
+ purls: []
+ size: 292785
+ timestamp: 1745608759342
+- conda: https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-15.2.0-h934c35e_18.conda
+ sha256: 78668020064fdaa27e9ab65cd2997e2c837b564ab26ce3bf0e58a2ce1a525c6e
+ md5: 1b08cd684f34175e4514474793d44bcb
+ depends:
+ - __glibc >=2.17,<3.0.a0
+ - libgcc 15.2.0 he0feb66_18
+ constrains:
+ - libstdcxx-ng ==15.2.0=*_18
+ license: GPL-3.0-only WITH GCC-exception-3.1
+ license_family: GPL
+ purls: []
+ size: 5852330
+ timestamp: 1771378262446
+- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libstdcxx-15.2.0-hef695bb_18.conda
+ sha256: 31fdb9ffafad106a213192d8319b9f810e05abca9c5436b60e507afb35a6bc40
+ md5: f56573d05e3b735cb03efeb64a15f388
+ depends:
+ - libgcc 15.2.0 h8acb6b2_18
+ constrains:
+ - libstdcxx-ng ==15.2.0=*_18
+ license: GPL-3.0-only WITH GCC-exception-3.1
+ license_family: GPL
+ purls: []
+ size: 5541411
+ timestamp: 1771378162499
+- conda: https://conda.anaconda.org/conda-forge/noarch/libstdcxx-devel_linux-64-14.3.0-h9f08a49_118.conda
+ sha256: b1c3824769b92a1486bf3e2cc5f13304d83ae613ea061b7bc47bb6080d6dfdba
+ md5: 865a399bce236119301ebd1532fced8d
+ depends:
+ - __unix
+ license: GPL-3.0-only WITH GCC-exception-3.1
+ license_family: GPL
+ purls: []
+ size: 20171098
+ timestamp: 1771377827750
+- conda: https://conda.anaconda.org/conda-forge/noarch/libstdcxx-devel_linux-aarch64-14.3.0-h57c8d61_118.conda
+ sha256: 609585a02b05a2b0f2cabb18849328455cbce576f2e3eb8108f3ef7f4cb165a6
+ md5: bcf29f2ed914259a258204b05346abb1
+ depends:
+ - __unix
+ license: GPL-3.0-only WITH GCC-exception-3.1
+ license_family: GPL
+ purls: []
+ size: 17565700
+ timestamp: 1771377672552
+- conda: https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-ng-15.2.0-hdf11a46_18.conda
+ sha256: 3c902ffd673cb3c6ddde624cdb80f870b6c835f8bf28384b0016e7d444dd0145
+ md5: 6235adb93d064ecdf3d44faee6f468de
+ depends:
+ - libstdcxx 15.2.0 h934c35e_18
+ license: GPL-3.0-only WITH GCC-exception-3.1
+ license_family: GPL
+ purls: []
+ size: 27575
+ timestamp: 1771378314494
+- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libstdcxx-ng-15.2.0-hdbbeba8_18.conda
+ sha256: 035a31cde134e706e30029a837a31f729ad32b7c5bca023271dfe91a8ba6c896
+ md5: 699d294376fe18d80b7ce7876c3a875d
+ depends:
+ - libstdcxx 15.2.0 hef695bb_18
+ license: GPL-3.0-only WITH GCC-exception-3.1
+ license_family: GPL
+ purls: []
+ size: 27645
+ timestamp: 1771378204663
+- conda: https://conda.anaconda.org/conda-forge/linux-64/libuuid-2.41.3-h5347b49_0.conda
+ sha256: 1a7539cfa7df00714e8943e18de0b06cceef6778e420a5ee3a2a145773758aee
+ md5: db409b7c1720428638e7c0d509d3e1b5
+ depends:
+ - __glibc >=2.17,<3.0.a0
+ - libgcc >=14
+ license: BSD-3-Clause
+ license_family: BSD
+ purls: []
+ size: 40311
+ timestamp: 1766271528534
+- conda: https://conda.anaconda.org/conda-forge/linux-64/libuuid-2.42-h5347b49_0.conda
+ sha256: bc1b08c92626c91500fd9f26f2c797f3eb153b627d53e9c13cd167f1e12b2829
+ md5: 38ffe67b78c9d4de527be8315e5ada2c
+ depends:
+ - __glibc >=2.17,<3.0.a0
+ - libgcc >=14
+ license: BSD-3-Clause
+ license_family: BSD
+ purls: []
+ size: 40297
+ timestamp: 1775052476770
+- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libuuid-2.41.3-h1022ec0_0.conda
+ sha256: c37a8e89b700646f3252608f8368e7eb8e2a44886b92776e57ad7601fc402a11
+ md5: cf2861212053d05f27ec49c3784ff8bb
+ depends:
+ - libgcc >=14
+ license: BSD-3-Clause
+ license_family: BSD
+ purls: []
+ size: 43453
+ timestamp: 1766271546875
+- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libuuid-2.42-h1022ec0_0.conda
+ sha256: 7d427edf58c702c337bf62bc90f355b7fc374a65fd9f70ea7a490f13bb76b1b9
+ md5: a0b5de740d01c390bdbb46d7503c9fab
+ depends:
+ - libgcc >=14
+ license: BSD-3-Clause
+ license_family: BSD
+ purls: []
+ size: 43567
+ timestamp: 1775052485727
+- conda: https://conda.anaconda.org/conda-forge/linux-64/libuv-1.51.0-hb03c661_1.conda
+ sha256: c180f4124a889ac343fc59d15558e93667d894a966ec6fdb61da1604481be26b
+ md5: 0f03292cc56bf91a077a134ea8747118
+ depends:
+ - __glibc >=2.17,<3.0.a0
+ - libgcc >=14
+ license: MIT
+ license_family: MIT
+ purls: []
+ size: 895108
+ timestamp: 1753948278280
+- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libuv-1.51.0-he30d5cf_1.conda
+ sha256: 7a0fb5638582efc887a18b7d270b0c4a6f6e681bf401cab25ebafa2482569e90
+ md5: 8e62bf5af966325ee416f19c6f14ffa3
+ depends:
+ - libgcc >=14
+ license: MIT
+ license_family: MIT
+ purls: []
+ size: 629238
+ timestamp: 1753948296190
+- conda: https://conda.anaconda.org/conda-forge/osx-64/libuv-1.48.0-h67532ce_0.conda
+ sha256: fb87f7bfd464a3a841d23f418c86a206818da0c4346984392071d9342c9ea367
+ md5: c8e7344c74f0d86584f7ecdc9f25c198
+ license: MIT
+ license_family: MIT
+ purls: []
+ size: 407040
+ timestamp: 1709913680478
+- conda: https://conda.anaconda.org/conda-forge/osx-arm64/libuv-1.48.0-h93a5062_0.conda
+ sha256: 60bed2a7a85096387ab0381cbc32ea2da7f8dd99bd90e440983019c0cdd96ad1
+ md5: abfd49e80f13453b62a56be226120ea8
+ license: MIT
+ license_family: MIT
+ purls: []
+ size: 405988
+ timestamp: 1709913494015
+- conda: https://conda.anaconda.org/conda-forge/win-64/libuv-1.51.0-hfd05255_1.conda
+ sha256: f03dc82e6fb1725788e73ae97f0cd3d820d5af0d351a274104a0767035444c59
+ md5: 31e1545994c48efc3e6ea32ca02a8724
+ depends:
+ - ucrt >=10.0.20348.0
+ - vc >=14.3,<15
+ - vc14_runtime >=14.44.35208
+ license: MIT
+ license_family: MIT
+ purls: []
+ size: 297087
+ timestamp: 1753948490874
+- conda: https://conda.anaconda.org/conda-forge/win-64/libwinpthread-12.0.0.r4.gg4f2fc60ca-h57928b3_10.conda
+ sha256: 0fccf2d17026255b6e10ace1f191d0a2a18f2d65088fd02430be17c701f8ffe0
+ md5: 8a86073cf3b343b87d03f41790d8b4e5
+ depends:
+ - ucrt
+ constrains:
+ - pthreads-win32 <0.0a0
+ - msys2-conda-epoch <0.0a0
+ license: MIT AND BSD-3-Clause-Clear
+ purls: []
+ size: 36621
+ timestamp: 1759768399557
+- conda: https://conda.anaconda.org/conda-forge/linux-64/libxcrypt-4.4.36-hd590300_1.conda
+ sha256: 6ae68e0b86423ef188196fff6207ed0c8195dd84273cb5623b85aa08033a410c
+ md5: 5aa797f8787fe7a17d1b0821485b5adc
+ depends:
+ - libgcc-ng >=12
+ license: LGPL-2.1-or-later
+ purls: []
+ size: 100393
+ timestamp: 1702724383534
+- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libxcrypt-4.4.36-h31becfc_1.conda
+ sha256: 6b46c397644091b8a26a3048636d10b989b1bf266d4be5e9474bf763f828f41f
+ md5: b4df5d7d4b63579d081fd3a4cf99740e
+ depends:
+ - libgcc-ng >=12
+ license: LGPL-2.1-or-later
+ purls: []
+ size: 114269
+ timestamp: 1702724369203
+- conda: https://conda.anaconda.org/conda-forge/linux-64/libxml2-2.15.2-he237659_0.conda
+ sha256: 275c324f87bda1a3b67d2f4fcc3555eeff9e228a37655aa001284a7ceb6b0392
+ md5: e49238a1609f9a4a844b09d9926f2c3d
+ depends:
+ - __glibc >=2.17,<3.0.a0
+ - icu >=78.2,<79.0a0
+ - libgcc >=14
+ - libiconv >=1.18,<2.0a0
+ - liblzma >=5.8.2,<6.0a0
+ - libxml2-16 2.15.2 hca6bf5a_0
+ - libzlib >=1.3.1,<2.0a0
+ license: MIT
+ license_family: MIT
+ purls: []
+ size: 45968
+ timestamp: 1772704614539
+- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libxml2-2.15.2-h825857f_0.conda
+ sha256: 3e51e1952cb60c8107094b6b78473d91ff49d428ad4bef6806124b383e8fe29c
+ md5: 19de96909ee1198e2853acd8aba89f6c
+ depends:
+ - icu >=78.2,<79.0a0
+ - libgcc >=14
+ - libiconv >=1.18,<2.0a0
+ - liblzma >=5.8.2,<6.0a0
+ - libxml2-16 2.15.2 h79dcc73_0
+ - libzlib >=1.3.1,<2.0a0
+ license: MIT
+ license_family: MIT
+ purls: []
+ size: 47837
+ timestamp: 1772704681112
+- conda: https://conda.anaconda.org/conda-forge/osx-64/libxml2-2.12.6-hc0ae0f7_2.conda
+ sha256: 2598a525b1769338f96c3d4badad7d8b95c9ddcea86db3f9479a274803190e5c
+ md5: 50b997370584f2c83ca0c38e9028eab9
+ depends:
+ - icu >=73.2,<74.0a0
+ - libiconv >=1.17,<2.0a0
+ - libzlib >=1.2.13,<2.0.0a0
+ - xz >=5.2.6,<6.0a0
+ license: MIT
+ license_family: MIT
+ purls: []
+ size: 619622
+ timestamp: 1713314870641
+- conda: https://conda.anaconda.org/conda-forge/osx-64/libxml2-2.15.2-hd552753_0.conda
+ sha256: 5b9e8a5146275ac0539231f646ee51a9e4629e730026ff69dadff35bfb745911
+ md5: eea3155f3b4a3b75af504c871ec23858
+ depends:
+ - __osx >=11.0
+ - icu >=78.2,<79.0a0
+ - libiconv >=1.18,<2.0a0
+ - liblzma >=5.8.2,<6.0a0
+ - libxml2-16 2.15.2 h7a90416_0
+ - libzlib >=1.3.1,<2.0a0
+ license: MIT
+ license_family: MIT
+ purls: []
+ size: 41106
+ timestamp: 1772705465931
+- conda: https://conda.anaconda.org/conda-forge/osx-arm64/libxml2-2.12.6-h35eab27_2.conda
+ sha256: 14870a455d478682a60655e3026c51d01ebc1747ccce726ae495a693b304c9b1
+ md5: d3a4a3d691494491a08e05f66a0aa35a
+ depends:
+ - icu >=73.2,<74.0a0
+ - libiconv >=1.17,<2.0a0
+ - libzlib >=1.3.1,<1.4.0a0
+ - xz >=5.2.6,<6.0a0
+ license: MIT
+ license_family: MIT
+ purls: []
+ size: 587544
+ timestamp: 1713314830067
+- conda: https://conda.anaconda.org/conda-forge/osx-arm64/libxml2-2.15.2-h8d039ee_0.conda
+ sha256: 99cb32dd06a2e58c12981b71a84b052293f27b5ab042e3f21d895f5d7ee13eff
+ md5: e476ba84e57f2bd2004a27381812ad4e
+ depends:
+ - __osx >=11.0
+ - icu >=78.2,<79.0a0
+ - libiconv >=1.18,<2.0a0
+ - liblzma >=5.8.2,<6.0a0
+ - libxml2-16 2.15.2 h5ef1a60_0
+ - libzlib >=1.3.1,<2.0a0
+ license: MIT
+ license_family: MIT
+ purls: []
+ size: 41206
+ timestamp: 1772704982288
+- conda: https://conda.anaconda.org/conda-forge/win-64/libxml2-2.15.2-h5d26750_0.conda
+ sha256: f905eb7046987c336122121759e7f09144729f6898f48cd06df2a945b86998d8
+ md5: 1007e1bfe181a2aee214779ee7f13d30
+ depends:
+ - libiconv >=1.18,<2.0a0
+ - liblzma >=5.8.2,<6.0a0
+ - libxml2-16 2.15.2 h692994f_0
+ - libzlib >=1.3.1,<2.0a0
+ - ucrt >=10.0.20348.0
+ - vc >=14.3,<15
+ - vc14_runtime >=14.44.35208
+ constrains:
+ - icu <0.0a0
+ license: MIT
+ license_family: MIT
+ purls: []
+ size: 43681
+ timestamp: 1772704748950
+- conda: https://conda.anaconda.org/conda-forge/linux-64/libxml2-16-2.15.2-hca6bf5a_0.conda
+ sha256: 08d2b34b49bec9613784f868209bb7c3bb8840d6cf835ff692e036b09745188c
+ md5: f3bc152cb4f86babe30f3a4bf0dbef69
+ depends:
+ - __glibc >=2.17,<3.0.a0
+ - icu >=78.2,<79.0a0
+ - libgcc >=14
+ - libiconv >=1.18,<2.0a0
+ - liblzma >=5.8.2,<6.0a0
+ - libzlib >=1.3.1,<2.0a0
+ constrains:
+ - libxml2 2.15.2
+ license: MIT
+ license_family: MIT
+ purls: []
+ size: 557492
+ timestamp: 1772704601644
+- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libxml2-16-2.15.2-h79dcc73_0.conda
+ sha256: da6b2ebbcecc158200d90be39514e4e902971628029b35b7f6ad57270659c5d9
+ md5: e3ec9079759d35b875097d6a9a69e744
+ depends:
+ - icu >=78.2,<79.0a0
+ - libgcc >=14
+ - libiconv >=1.18,<2.0a0
+ - liblzma >=5.8.2,<6.0a0
+ - libzlib >=1.3.1,<2.0a0
+ constrains:
+ - libxml2 2.15.2
+ license: MIT
+ license_family: MIT
+ purls: []
+ size: 598438
+ timestamp: 1772704671710
+- conda: https://conda.anaconda.org/conda-forge/osx-64/libxml2-16-2.15.2-h7a90416_0.conda
+ sha256: f67e4b7d7f97e57ecd611a42e42d5f6c047fd3d1eb8270813b888924440c8a59
+ md5: 0c8bdbfd118f5963ab343846094932a3
+ depends:
+ - __osx >=11.0
+ - icu >=78.2,<79.0a0
+ - libiconv >=1.18,<2.0a0
+ - liblzma >=5.8.2,<6.0a0
+ - libzlib >=1.3.1,<2.0a0
+ constrains:
+ - libxml2 2.15.2
+ license: MIT
+ license_family: MIT
+ purls: []
+ size: 495922
+ timestamp: 1772705426323
+- conda: https://conda.anaconda.org/conda-forge/osx-arm64/libxml2-16-2.15.2-h5ef1a60_0.conda
+ sha256: 6432259204e78c8a8a815afae987fbf60bd722605fe2c4b022e65196b17d4537
+ md5: b284e2b02d53ef7981613839fb86beee
+ depends:
+ - __osx >=11.0
+ - icu >=78.2,<79.0a0
+ - libiconv >=1.18,<2.0a0
+ - liblzma >=5.8.2,<6.0a0
+ - libzlib >=1.3.1,<2.0a0
+ constrains:
+ - libxml2 2.15.2
+ license: MIT
+ license_family: MIT
+ purls: []
+ size: 466220
+ timestamp: 1772704950232
+- conda: https://conda.anaconda.org/conda-forge/win-64/libxml2-16-2.15.2-h692994f_0.conda
+ sha256: b8c71b3b609c7cfe17f3f2a47c75394d7b30acfb8b34ad7a049ea8757b4d33df
+ md5: e365238134188e42ed36ee996159d482
+ depends:
+ - libiconv >=1.18,<2.0a0
+ - liblzma >=5.8.2,<6.0a0
+ - libzlib >=1.3.1,<2.0a0
+ - ucrt >=10.0.20348.0
+ - vc >=14.3,<15
+ - vc14_runtime >=14.44.35208
+ constrains:
+ - libxml2 2.15.2
+ - icu <0.0a0
+ license: MIT
+ license_family: MIT
+ purls: []
+ size: 520078
+ timestamp: 1772704728534
+- conda: https://conda.anaconda.org/conda-forge/linux-64/libzlib-1.3.1-hb9d3cd8_2.conda
+ sha256: d4bfe88d7cb447768e31650f06257995601f89076080e76df55e3112d4e47dc4
+ md5: edb0dca6bc32e4f4789199455a1dbeb8
+ depends:
+ - __glibc >=2.17,<3.0.a0
+ - libgcc >=13
+ constrains:
+ - zlib 1.3.1 *_2
+ license: Zlib
+ license_family: Other
+ purls: []
+ size: 60963
+ timestamp: 1727963148474
+- conda: https://conda.anaconda.org/conda-forge/linux-64/libzlib-1.3.2-h25fd6f3_2.conda
+ sha256: 55044c403570f0dc26e6364de4dc5368e5f3fc7ff103e867c487e2b5ab2bcda9
+ md5: d87ff7921124eccd67248aa483c23fec
+ depends:
+ - __glibc >=2.17,<3.0.a0
+ constrains:
+ - zlib 1.3.2 *_2
+ license: Zlib
+ license_family: Other
+ purls: []
+ size: 63629
+ timestamp: 1774072609062
+- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libzlib-1.3.1-h86ecc28_2.conda
+ sha256: 5a2c1eeef69342e88a98d1d95bff1603727ab1ff4ee0e421522acd8813439b84
+ md5: 08aad7cbe9f5a6b460d0976076b6ae64
+ depends:
+ - libgcc >=13
+ constrains:
+ - zlib 1.3.1 *_2
+ license: Zlib
+ license_family: Other
+ purls: []
+ size: 66657
+ timestamp: 1727963199518
+- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libzlib-1.3.2-hdc9db2a_2.conda
+ sha256: eb111e32e5a7313a5bf799c7fb2419051fa2fe7eff74769fac8d5a448b309f7f
+ md5: 502006882cf5461adced436e410046d1
+ constrains:
+ - zlib 1.3.2 *_2
+ license: Zlib
+ license_family: Other
+ purls: []
+ size: 69833
+ timestamp: 1774072605429
+- conda: https://conda.anaconda.org/conda-forge/osx-64/libzlib-1.3.1-hd23fc13_2.conda
+ sha256: 8412f96504fc5993a63edf1e211d042a1fd5b1d51dedec755d2058948fcced09
+ md5: 003a54a4e32b02f7355b50a837e699da
+ depends:
+ - __osx >=10.13
+ constrains:
+ - zlib 1.3.1 *_2
+ license: Zlib
+ license_family: Other
+ size: 57133
+ timestamp: 1727963183990
+- conda: https://conda.anaconda.org/conda-forge/osx-64/libzlib-1.3.1-hd75f5a5_0.conda
+ sha256: 49fd2bde256952ab6a8265f3b2978ae624db1f096e3340253699e2534426244a
+ md5: fad941436715cc1b6f6e55a14372f70c
+ constrains:
+ - zlib 1.3.1 *_0
+ license: Zlib
+ license_family: Other
+ purls: []
+ size: 57480
+ timestamp: 1709241092733
+- conda: https://conda.anaconda.org/conda-forge/osx-64/libzlib-1.3.2-hbb4bfdb_2.conda
+ sha256: 4c6da089952b2d70150c74234679d6f7ac04f4a98f9432dec724968f912691e7
+ md5: 30439ff30578e504ee5e0b390afc8c65
+ depends:
+ - __osx >=11.0
+ constrains:
+ - zlib 1.3.2 *_2
+ license: Zlib
+ license_family: Other
+ purls: []
+ size: 59000
+ timestamp: 1774073052242
+- conda: https://conda.anaconda.org/conda-forge/osx-arm64/libzlib-1.3.1-h0d3ecfb_0.conda
+ sha256: 9c59bd3f3e3e1900620e3a85c04d3a3699cb93c714333d06cb8afdd7addaae9d
+ md5: 2a2463424cc5e961a6d04bbbfb5838cf
+ constrains:
+ - zlib 1.3.1 *_0
+ license: Zlib
+ license_family: Other
+ purls: []
+ size: 47040
+ timestamp: 1709241137619
+- conda: https://conda.anaconda.org/conda-forge/osx-arm64/libzlib-1.3.1-h8359307_2.conda
+ sha256: ce34669eadaba351cd54910743e6a2261b67009624dbc7daeeafdef93616711b
+ md5: 369964e85dc26bfe78f41399b366c435
+ depends:
+ - __osx >=11.0
+ constrains:
+ - zlib 1.3.1 *_2
+ license: Zlib
+ license_family: Other
+ size: 46438
+ timestamp: 1727963202283
+- conda: https://conda.anaconda.org/conda-forge/osx-arm64/libzlib-1.3.2-h8088a28_2.conda
+ sha256: 361415a698514b19a852f5d1123c5da746d4642139904156ddfca7c922d23a05
+ md5: bc5a5721b6439f2f62a84f2548136082
+ depends:
+ - __osx >=11.0
+ constrains:
+ - zlib 1.3.2 *_2
+ license: Zlib
+ license_family: Other
+ purls: []
+ size: 47759
+ timestamp: 1774072956767
+- conda: https://conda.anaconda.org/conda-forge/win-64/libzlib-1.3.1-h2466b09_2.conda
+ sha256: ba945c6493449bed0e6e29883c4943817f7c79cbff52b83360f7b341277c6402
+ md5: 41fbfac52c601159df6c01f875de31b9
+ depends:
+ - ucrt >=10.0.20348.0
+ - vc >=14.2,<15
+ - vc14_runtime >=14.29.30139
+ constrains:
+ - zlib 1.3.1 *_2
+ license: Zlib
+ license_family: Other
+ purls: []
+ size: 55476
+ timestamp: 1727963768015
+- conda: https://conda.anaconda.org/conda-forge/win-64/libzlib-1.3.2-hfd05255_2.conda
+ sha256: 88609816e0cc7452bac637aaf65783e5edf4fee8a9f8e22bdc3a75882c536061
+ md5: dbabbd6234dea34040e631f87676292f
+ depends:
+ - ucrt >=10.0.20348.0
+ - vc >=14.3,<15
+ - vc14_runtime >=14.44.35208
+ constrains:
+ - zlib 1.3.2 *_2
+ license: Zlib
+ license_family: Other
+ purls: []
+ size: 58347
+ timestamp: 1774072851498
+- conda: https://conda.anaconda.org/conda-forge/osx-64/llvm-openmp-18.1.3-hb6ac08f_0.conda
+ sha256: 997e4169ea474a7bc137fed3b5f4d94b1175162b3318e8cb3943003e460fe458
+ md5: 506f270f4f00980d27cc1fc127e0ed37
+ constrains:
+ - openmp 18.1.3|18.1.3.*
+ license: Apache-2.0 WITH LLVM-exception
+ license_family: APACHE
+ purls: []
+ size: 300597
+ timestamp: 1712603382363
+- conda: https://conda.anaconda.org/conda-forge/osx-arm64/llvm-openmp-18.1.3-hcd81f8e_0.conda
+ sha256: 4cb4eadd633669496ed70c580c965f5f2ed29336890636c61a53e9c1c1541073
+ md5: 24cbf1fb1b83056f8ba1beaac0619bf8
+ constrains:
+ - openmp 18.1.3|18.1.3.*
+ license: Apache-2.0 WITH LLVM-exception
+ license_family: APACHE
+ purls: []
+ size: 276320
+ timestamp: 1712603367897
+- conda: https://conda.anaconda.org/conda-forge/win-64/llvm-openmp-22.1.0-h4fa8253_0.conda
+ sha256: bb55a3736380759d338f87aac68df4fd7d845ae090b94400525f5d21a55eea31
+ md5: e5505e0b7d6ef5c19d5c0c1884a2f494
+ depends:
+ - ucrt >=10.0.20348.0
+ - vc >=14.3,<15
+ - vc14_runtime >=14.44.35208
+ constrains:
+ - openmp 22.1.0|22.1.0.*
+ - intel-openmp <0.0a0
+ license: Apache-2.0 WITH LLVM-exception
+ license_family: APACHE
+ purls: []
+ size: 347404
+ timestamp: 1772025050288
+- conda: https://conda.anaconda.org/conda-forge/osx-64/llvm-tools-18.1.3-hbcf5fad_0.conda
+ sha256: be89293b54032198a28d3a4b91e50eb4d79e252d9e3ab609501ea0324fbf478a
+ md5: f91db97d91a080e0024307fa3808cc7b
+ depends:
+ - libllvm18 18.1.3 hbcf5fad_0
+ - libxml2 >=2.12.6,<2.14.0a0
+ - libzlib >=1.2.13,<2.0.0a0
+ - zstd >=1.5.5,<1.6.0a0
+ constrains:
+ - clang-tools 18.1.3
+ - llvmdev 18.1.3
+ - llvm 18.1.3
+ - clang 18.1.3
+ license: Apache-2.0 WITH LLVM-exception
+ license_family: Apache
+ purls: []
+ size: 24449337
+ timestamp: 1712518244229
+- conda: https://conda.anaconda.org/conda-forge/osx-arm64/llvm-tools-18.1.3-h30cc82d_0.conda
+ sha256: 48eb7b17ca6de1b43dfddc3b4a629a8a9764c9da3f3012980e1b917c71f06a4f
+ md5: 505aef673d805f9efe0c61954a6a99d0
+ depends:
+ - libllvm18 18.1.3 h30cc82d_0
+ - libxml2 >=2.12.6,<2.14.0a0
+ - libzlib >=1.2.13,<2.0.0a0
+ - zstd >=1.5.5,<1.6.0a0
+ constrains:
+ - llvm 18.1.3
+ - clang-tools 18.1.3
+ - clang 18.1.3
+ - llvmdev 18.1.3
+ license: Apache-2.0 WITH LLVM-exception
+ license_family: Apache
+ purls: []
+ size: 23023681
+ timestamp: 1712517958538
+- conda: https://conda.anaconda.org/conda-forge/linux-64/lz4-c-1.10.0-h5888daf_1.conda
+ sha256: 47326f811392a5fd3055f0f773036c392d26fdb32e4d8e7a8197eed951489346
+ md5: 9de5350a85c4a20c685259b889aa6393
+ depends:
+ - __glibc >=2.17,<3.0.a0
+ - libgcc >=13
+ - libstdcxx >=13
+ license: BSD-2-Clause
+ license_family: BSD
+ purls: []
+ size: 167055
+ timestamp: 1733741040117
+- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/lz4-c-1.10.0-h5ad3122_1.conda
+ sha256: 67e55058d275beea76c1882399640c37b5be8be4eb39354c94b610928e9a0573
+ md5: 6654e411da94011e8fbe004eacb8fe11
+ depends:
+ - libgcc >=13
+ - libstdcxx >=13
+ license: BSD-2-Clause
+ license_family: BSD
+ purls: []
+ size: 184953
+ timestamp: 1733740984533
+- conda: https://conda.anaconda.org/conda-forge/osx-64/lz4-c-1.10.0-h240833e_1.conda
+ sha256: 8da3c9d4b596e481750440c0250a7e18521e7f69a47e1c8415d568c847c08a1c
+ md5: d6b9bd7e356abd7e3a633d59b753495a
+ depends:
+ - __osx >=10.13
+ - libcxx >=18
+ license: BSD-2-Clause
+ license_family: BSD
+ purls: []
+ size: 159500
+ timestamp: 1733741074747
+- conda: https://conda.anaconda.org/conda-forge/osx-arm64/lz4-c-1.10.0-h286801f_1.conda
+ sha256: 94d3e2a485dab8bdfdd4837880bde3dd0d701e2b97d6134b8806b7c8e69c8652
+ md5: 01511afc6cc1909c5303cf31be17b44f
+ depends:
+ - __osx >=11.0
+ - libcxx >=18
+ license: BSD-2-Clause
+ license_family: BSD
+ purls: []
+ size: 148824
+ timestamp: 1733741047892
+- conda: https://conda.anaconda.org/conda-forge/win-64/lz4-c-1.10.0-h2466b09_1.conda
+ sha256: 632cf3bdaf7a7aeb846de310b6044d90917728c73c77f138f08aa9438fc4d6b5
+ md5: 0b69331897a92fac3d8923549d48d092
+ depends:
+ - ucrt >=10.0.20348.0
+ - vc >=14.2,<15
+ - vc14_runtime >=14.29.30139
+ license: BSD-2-Clause
+ license_family: BSD
+ purls: []
+ size: 139891
+ timestamp: 1733741168264
+- conda: https://conda.anaconda.org/conda-forge/linux-64/lzo-2.10-h280c20c_1002.conda
+ sha256: 5c6bbeec116e29f08e3dad3d0524e9bc5527098e12fc432c0e5ca53ea16337d4
+ md5: 45161d96307e3a447cc3eb5896cf6f8c
+ depends:
+ - libgcc >=14
+ - __glibc >=2.17,<3.0.a0
+ license: GPL-2.0-or-later
+ license_family: GPL
+ purls: []
+ size: 191060
+ timestamp: 1753889274283
+- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/lzo-2.10-h80f16a2_1002.conda
+ sha256: 036428c7b9fd22889108d04c91cecc431f95dc3dba2ede3057330c8125080fd5
+ md5: 97af2e332449dd9e92ad7db93b02e918
+ depends:
+ - libgcc >=14
+ license: GPL-2.0-or-later
+ license_family: GPL
+ purls: []
+ size: 190187
+ timestamp: 1753889356434
+- conda: https://conda.anaconda.org/conda-forge/osx-64/lzo-2.10-h4132b18_1002.conda
+ sha256: bb5fe07123a7d573af281d04b75e1e77e87e62c5c4eb66d9781aa919450510d1
+ md5: 5a047b9aa4be1dcdb62bd561d9eb6ceb
+ depends:
+ - __osx >=10.13
+ license: GPL-2.0-or-later
+ license_family: GPL
+ purls: []
+ size: 174634
+ timestamp: 1753889269889
+- conda: https://conda.anaconda.org/conda-forge/osx-arm64/lzo-2.10-h925e9cb_1002.conda
+ sha256: db40fd25c6306bfda469f84cddd8b5ebb9aa08d509cecb49dfd0bb8228466d0c
+ md5: e56eaa1beab0e7fed559ae9c0264dd88
+ depends:
+ - __osx >=11.0
+ license: GPL-2.0-or-later
+ license_family: GPL
+ purls: []
+ size: 152755
+ timestamp: 1753889267953
+- conda: https://conda.anaconda.org/conda-forge/win-64/lzo-2.10-h6a83c73_1002.conda
+ sha256: 344f4f225c6dfb523fb477995545542224c37a5c86161f053a1a18fe547aa979
+ md5: c5cb4159f0eea65663b31dd1e49bbb71
+ depends:
+ - vc >=14.3,<15
+ - vc14_runtime >=14.44.35208
+ - ucrt >=10.0.20348.0
+ - vc >=14.3,<15
+ - vc14_runtime >=14.44.35208
+ - ucrt >=10.0.20348.0
+ license: GPL-2.0-or-later
+ license_family: GPL
+ purls: []
+ size: 165589
+ timestamp: 1753889311940
+- pypi: https://files.pythonhosted.org/packages/c7/d1/a9f36f8ecdf0fb7c9b1e78c8d7af12b8c8754e74851ac7b94a8305540fc7/macholib-1.16.4-py2.py3-none-any.whl
+ name: macholib
+ version: 1.16.4
+ sha256: da1a3fa8266e30f0ce7e97c6a54eefaae8edd1e5f86f3eb8b95457cae90265ea
+ requires_dist:
+ - altgraph>=0.17
+- pypi: https://files.pythonhosted.org/packages/94/54/e7d793b573f298e1c9013b8c4dade17d481164aa517d1d7148619c2cedbf/markdown_it_py-4.0.0-py3-none-any.whl
+ name: markdown-it-py
+ version: 4.0.0
+ sha256: 87327c59b172c5011896038353a81343b6754500a08cd7a4973bb48c6d578147
+ requires_dist:
+ - mdurl~=0.1
+ - psutil ; extra == 'benchmarking'
+ - pytest ; extra == 'benchmarking'
+ - pytest-benchmark ; extra == 'benchmarking'
+ - commonmark~=0.9 ; extra == 'compare'
+ - markdown~=3.4 ; extra == 'compare'
+ - mistletoe~=1.0 ; extra == 'compare'
+ - mistune~=3.0 ; extra == 'compare'
+ - panflute~=2.3 ; extra == 'compare'
+ - markdown-it-pyrs ; extra == 'compare'
+ - linkify-it-py>=1,<3 ; extra == 'linkify'
+ - mdit-py-plugins>=0.5.0 ; extra == 'plugins'
+ - gprof2dot ; extra == 'profiling'
+ - mdit-py-plugins>=0.5.0 ; extra == 'rtd'
+ - myst-parser ; extra == 'rtd'
+ - pyyaml ; extra == 'rtd'
+ - sphinx ; extra == 'rtd'
+ - sphinx-copybutton ; extra == 'rtd'
+ - sphinx-design ; extra == 'rtd'
+ - sphinx-book-theme~=1.0 ; extra == 'rtd'
+ - jupyter-sphinx ; extra == 'rtd'
+ - ipykernel ; extra == 'rtd'
+ - coverage ; extra == 'testing'
+ - pytest ; extra == 'testing'
+ - pytest-cov ; extra == 'testing'
+ - pytest-regressions ; extra == 'testing'
+ - requests ; extra == 'testing'
+ requires_python: '>=3.10'
+- pypi: https://files.pythonhosted.org/packages/b3/38/89ba8ad64ae25be8de66a6d463314cf1eb366222074cfda9ee839c56a4b4/mdurl-0.1.2-py3-none-any.whl
+ name: mdurl
+ version: 0.1.2
+ sha256: 84008a41e51615a49fc9966191ff91509e3c40b939176e643fd50a5c2196b8f8
+ requires_python: '>=3.7'
+- conda: https://conda.anaconda.org/conda-forge/linux-64/menuinst-2.4.2-py310hff52083_0.conda
+ sha256: ec100872ca86c8dc6a08b16d0046661dd85ebb6b6910c57dfcafecbdc622a1ba
+ md5: 937b4f62485b63f71ee8d50ae021cc33
+ depends:
+ - python >=3.10,<3.11.0a0
+ - python_abi 3.10.* *_cp310
+ license: BSD-3-Clause AND MIT
+ purls:
+ - pkg:pypi/menuinst?source=hash-mapping
+ size: 155578
+ timestamp: 1765733217218
+- conda: https://conda.anaconda.org/conda-forge/linux-64/menuinst-2.4.2-py311h38be061_0.conda
+ sha256: 096f1db22fd47ddcf5df82aed016ef8cef4c1b810925bf63b67cfc3f9ba67cdb
+ md5: ba48e568ec4fdbcb8f3fef87bca9fddb
+ depends:
+ - python >=3.11,<3.12.0a0
+ - python_abi 3.11.* *_cp311
+ license: BSD-3-Clause AND MIT
+ purls:
+ - pkg:pypi/menuinst?source=hash-mapping
+ size: 186910
+ timestamp: 1765733175922
+- conda: https://conda.anaconda.org/conda-forge/linux-64/menuinst-2.4.2-py314hdafbbf9_0.conda
+ sha256: 223306ba7f78599abc65f8ca14116650c228cbdca273ca15804544ac343a9e69
+ md5: 608ee3d8065e9b1e9e1f3115d8aab9ab
+ depends:
+ - python >=3.14,<3.15.0a0
+ - python_abi 3.14.* *_cp314
+ license: BSD-3-Clause AND MIT
+ purls:
+ - pkg:pypi/menuinst?source=hash-mapping
+ size: 188752
+ timestamp: 1765733220513
+- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/menuinst-2.4.2-py310h4c7bcd0_0.conda
+ sha256: 331b93ad811c1033b5d22a23541b23c75c0d1b31ad0ed2d6f4117a79f3676f0e
+ md5: 928764c3c75aaabcc1bac5ebf4a8a7c2
+ depends:
+ - python >=3.10,<3.11.0a0
+ - python >=3.10,<3.11.0a0 *_cpython
+ - python_abi 3.10.* *_cp310
+ license: BSD-3-Clause AND MIT
+ purls:
+ - pkg:pypi/menuinst?source=hash-mapping
+ size: 156117
+ timestamp: 1765733228621
+- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/menuinst-2.4.2-py311hec3470c_0.conda
+ sha256: 803b3fc3b4c0c4abc8d2c720793c1cbe784506762a0dcdcb736805c0aebc797d
+ md5: b2b440c867b680594a750a00c3425417
+ depends:
+ - python >=3.11,<3.12.0a0
+ - python >=3.11,<3.12.0a0 *_cpython
+ - python_abi 3.11.* *_cp311
+ license: BSD-3-Clause AND MIT
+ purls:
+ - pkg:pypi/menuinst?source=hash-mapping
+ size: 187037
+ timestamp: 1765733232285
+- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/menuinst-2.4.2-py314h28a4750_0.conda
+ sha256: ed5d3d0b646207b15aea1022ed10ccccfebfa271b152eeb6169b767a02b632a5
+ md5: 41fc65edb06fbcc2c2e68c02d06f6bf7
+ depends:
+ - python >=3.14,<3.15.0a0
+ - python >=3.14,<3.15.0a0 *_cp314
+ - python_abi 3.14.* *_cp314
+ license: BSD-3-Clause AND MIT
+ purls:
+ - pkg:pypi/menuinst?source=hash-mapping
+ size: 188584
+ timestamp: 1765733234092
+- conda: https://conda.anaconda.org/conda-forge/osx-64/menuinst-2.4.2-py314hee6578b_0.conda
+ sha256: f9967b4794840bbc1e1a02b0f8e2d9c2a97216e1d5eb88024ca3e34d6f0c7838
+ md5: 70759a82982d21ee091d7004b945048a
+ depends:
+ - python >=3.14,<3.15.0a0
+ - python_abi 3.14.* *_cp314
+ license: BSD-3-Clause AND MIT
+ purls:
+ - pkg:pypi/menuinst?source=hash-mapping
+ size: 187629
+ timestamp: 1765733352246
+- conda: https://conda.anaconda.org/conda-forge/osx-arm64/menuinst-2.4.2-py314h4dc9dd8_0.conda
+ sha256: cfe6079a2193f9ecf0279bff01eb57499a5a081607ea3c83b2c5522c00a538ca
+ md5: 312610ff2ccaa1e4995f4fb3d8c04f96
+ depends:
+ - python >=3.14,<3.15.0a0
+ - python >=3.14,<3.15.0a0 *_cp314
+ - python_abi 3.14.* *_cp314
+ license: BSD-3-Clause AND MIT
+ purls:
+ - pkg:pypi/menuinst?source=hash-mapping
+ size: 188284
+ timestamp: 1765733422732
+- conda: https://conda.anaconda.org/conda-forge/win-64/menuinst-2.4.2-py310h73ae2b4_0.conda
+ sha256: 3b5ab966d63a2e217f15a437be470bee04d69b63f5205a5d1a8d012008ba6b04
+ md5: fd40b3f1395d1b1e9071961d90a3f0f0
+ depends:
+ - python >=3.10,<3.11.0a0
+ - python_abi 3.10.* *_cp310
+ - ucrt >=10.0.20348.0
+ - vc >=14.3,<15
+ - vc14_runtime >=14.44.35208
+ license: BSD-3-Clause AND MIT
+ purls:
+ - pkg:pypi/menuinst?source=hash-mapping
+ size: 146344
+ timestamp: 1765733517640
+- conda: https://conda.anaconda.org/conda-forge/win-64/menuinst-2.4.2-py311h3e6a449_0.conda
+ sha256: 0482c0c5962ba3da648071affec41b416a51c6afbf52264ea40434e43993b0cf
+ md5: 25b1fdcd2436106cab080dc1932dba63
+ depends:
+ - python >=3.11,<3.12.0a0
+ - python_abi 3.11.* *_cp311
+ - ucrt >=10.0.20348.0
+ - vc >=14.3,<15
+ - vc14_runtime >=14.44.35208
+ license: BSD-3-Clause AND MIT
+ purls:
+ - pkg:pypi/menuinst?source=hash-mapping
+ size: 179383
+ timestamp: 1765733304312
+- conda: https://conda.anaconda.org/conda-forge/win-64/menuinst-2.4.2-py314h13fbf68_0.conda
+ sha256: 1f4535acbc5a2d75e2b6d83fca659c468bc2597af798fdf2e45091265a094a32
+ md5: ced101aaa08315eb8a058b1190500d12
+ depends:
+ - python >=3.14,<3.15.0a0
+ - python_abi 3.14.* *_cp314
+ - ucrt >=10.0.20348.0
+ - vc >=14.3,<15
+ - vc14_runtime >=14.44.35208
+ license: BSD-3-Clause AND MIT
+ purls:
+ - pkg:pypi/menuinst?source=hash-mapping
+ size: 179510
+ timestamp: 1765733497067
+- conda: https://conda.anaconda.org/conda-forge/win-64/mkl-2025.3.0-hac47afa_455.conda
+ sha256: b2b4c84b95210760e4d12319416c60ab66e03674ccdcbd14aeb59f82ebb1318d
+ md5: fd05d1e894497b012d05a804232254ed
+ depends:
+ - llvm-openmp >=21.1.8
+ - tbb >=2022.3.0
+ - ucrt >=10.0.20348.0
+ - vc >=14.3,<15
+ - vc14_runtime >=14.44.35208
+ license: LicenseRef-IntelSimplifiedSoftwareOct2022
+ license_family: Proprietary
+ purls: []
+ size: 100224829
+ timestamp: 1767634557029
+- pypi: https://files.pythonhosted.org/packages/a4/8e/469e5a4a2f5855992e425f3cb33804cc07bf18d48f2db061aec61ce50270/more_itertools-10.8.0-py3-none-any.whl
+ name: more-itertools
+ version: 10.8.0
+ sha256: 52d4362373dcf7c52546bc4af9a86ee7c4579df9a8dc268be0a2f949d376cc9b
+ requires_python: '>=3.9'
+- conda: https://conda.anaconda.org/conda-forge/linux-64/msgpack-python-1.1.2-py310h03d9f68_1.conda
+ sha256: 61cf3572d6afa3fa711c5f970a832783d2c281facb7b3b946a6b71a0bac2c592
+ md5: 5eea9d8f8fcf49751dab7927cb0dfc3f
+ depends:
+ - __glibc >=2.17,<3.0.a0
+ - libgcc >=14
+ - libstdcxx >=14
+ - python >=3.10,<3.11.0a0
+ - python_abi 3.10.* *_cp310
+ license: Apache-2.0
+ license_family: Apache
+ purls:
+ - pkg:pypi/msgpack?source=hash-mapping
+ size: 95105
+ timestamp: 1762504073388
+- conda: https://conda.anaconda.org/conda-forge/linux-64/msgpack-python-1.1.2-py311hdf67eae_1.conda
+ sha256: 8c81a6208def64afc3e208326d78d7af60bcbc32d44afe1269b332df84084f29
+ md5: c1153b2cb3318889ce624a3b4f0db7f7
+ depends:
+ - __glibc >=2.17,<3.0.a0
+ - libgcc >=14
+ - libstdcxx >=14
+ - python >=3.11,<3.12.0a0
+ - python_abi 3.11.* *_cp311
+ license: Apache-2.0
+ license_family: Apache
+ purls:
+ - pkg:pypi/msgpack?source=hash-mapping
+ size: 102979
+ timestamp: 1762504186626
+- conda: https://conda.anaconda.org/conda-forge/linux-64/msgpack-python-1.1.2-py314h9891dd4_1.conda
+ sha256: d41c2734d314303e329680aeef282766fe399a0ce63297a68a2f8f9b43b1b68a
+ md5: c6752022dcdbf4b9ef94163de1ab7f03
+ depends:
+ - __glibc >=2.17,<3.0.a0
+ - libgcc >=14
+ - libstdcxx >=14
+ - python >=3.14,<3.15.0a0
+ - python_abi 3.14.* *_cp314
+ license: Apache-2.0
+ license_family: Apache
+ purls:
+ - pkg:pypi/msgpack?source=hash-mapping
+ size: 103380
+ timestamp: 1762504077009
+- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/msgpack-python-1.1.2-py310h0992a49_1.conda
+ sha256: 663967ac8fbe9a5e32246784d0c6c08be8394dab5c045297121550beb967b127
+ md5: 0d9ac8c2994a3681e44edcf9bb1a3e8e
+ depends:
+ - libgcc >=14
+ - libstdcxx >=14
+ - python >=3.10,<3.11.0a0
+ - python >=3.10,<3.11.0a0 *_cpython
+ - python_abi 3.10.* *_cp310
+ license: Apache-2.0
+ license_family: Apache
+ purls:
+ - pkg:pypi/msgpack?source=hash-mapping
+ size: 93092
+ timestamp: 1762504199089
+- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/msgpack-python-1.1.2-py311hfca10b7_1.conda
+ sha256: 35a36e3062bf84a70c0105b1553a1aa7b16a1dad19a97945efeea2b92ca95f23
+ md5: 560e361fc9aff96fdd179e7e5d41471e
+ depends:
+ - libgcc >=14
+ - libstdcxx >=14
+ - python >=3.11,<3.12.0a0
+ - python >=3.11,<3.12.0a0 *_cpython
+ - python_abi 3.11.* *_cp311
+ license: Apache-2.0
+ license_family: Apache
+ purls:
+ - pkg:pypi/msgpack?source=hash-mapping
+ size: 100340
+ timestamp: 1762504276815
+- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/msgpack-python-1.1.2-py314hd7d8586_1.conda
+ sha256: 124a778a7065d75d9d36d80563e75d3a13455b160a761cd38a5ce8f50f87705c
+ md5: e93c66201de71acb9e99d94f84f897b1
+ depends:
+ - libgcc >=14
+ - libstdcxx >=14
+ - python >=3.14,<3.15.0a0
+ - python >=3.14,<3.15.0a0 *_cp314
+ - python_abi 3.14.* *_cp314
+ license: Apache-2.0
+ license_family: Apache
+ purls:
+ - pkg:pypi/msgpack?source=hash-mapping
+ size: 100176
+ timestamp: 1762504193305
+- conda: https://conda.anaconda.org/conda-forge/osx-64/msgpack-python-1.1.2-py314h00ed6fe_1.conda
+ sha256: 1e82a903c5b5fb1555851ff1ef9068a538f4d8652eee2c31935d2d6d326a99f7
+ md5: 977962f6bb6f922ee0caabcb5a1b1d8c
+ depends:
+ - __osx >=10.13
+ - libcxx >=19
+ - python >=3.14,<3.15.0a0
+ - python_abi 3.14.* *_cp314
+ license: Apache-2.0
+ license_family: Apache
+ purls:
+ - pkg:pypi/msgpack?source=hash-mapping
+ size: 92312
+ timestamp: 1762504434513
+- conda: https://conda.anaconda.org/conda-forge/osx-arm64/msgpack-python-1.1.2-py314h784bc60_1.conda
+ sha256: 9dc4ebe88064cf96bb97a4de83be10fbc52a24d2ff48a4561fb0fed337b526f0
+ md5: 305227e4de261896033ad8081e8b52ae
+ depends:
+ - __osx >=11.0
+ - libcxx >=19
+ - python >=3.14,<3.15.0a0
+ - python >=3.14,<3.15.0a0 *_cp314
+ - python_abi 3.14.* *_cp314
+ license: Apache-2.0
+ license_family: Apache
+ purls:
+ - pkg:pypi/msgpack?source=hash-mapping
+ size: 92381
+ timestamp: 1762504601981
+- conda: https://conda.anaconda.org/conda-forge/win-64/msgpack-python-1.1.2-py310he9f1925_1.conda
+ sha256: 6b7bfd07c5be57df2922e2f5238751ee6bb09d81540a44c6554d059eac2a3bd5
+ md5: 65fb9838e245ef4bea6cab32a7056dfc
+ depends:
+ - python >=3.10,<3.11.0a0
+ - python_abi 3.10.* *_cp310
+ - ucrt >=10.0.20348.0
+ - vc >=14.3,<15
+ - vc14_runtime >=14.44.35208
+ license: Apache-2.0
+ license_family: Apache
+ purls:
+ - pkg:pypi/msgpack?source=hash-mapping
+ size: 80807
+ timestamp: 1762504309629
+- conda: https://conda.anaconda.org/conda-forge/win-64/msgpack-python-1.1.2-py311h3fd045d_1.conda
+ sha256: 9883b64dea87c50e98fabc05719ff0fdc347f57d7bacda19bcd69b80d8c436d4
+ md5: b0f2fb2eadce667ad09ca7d3ff868c71
+ depends:
+ - python >=3.11,<3.12.0a0
+ - python_abi 3.11.* *_cp311
+ - ucrt >=10.0.20348.0
+ - vc >=14.3,<15
+ - vc14_runtime >=14.44.35208
+ license: Apache-2.0
+ license_family: Apache
+ purls:
+ - pkg:pypi/msgpack?source=hash-mapping
+ size: 87848
+ timestamp: 1762504210288
+- conda: https://conda.anaconda.org/conda-forge/win-64/msgpack-python-1.1.2-py314h909e829_1.conda
+ sha256: 2ce1f564d5aa2e0637c03692baeea4ecf234c7fb2a43e7810c369e1b054d7a30
+ md5: ad4584f884d029b02fc9eaf89afc5d9f
+ depends:
+ - python >=3.14,<3.15.0a0
+ - python_abi 3.14.* *_cp314
+ - ucrt >=10.0.20348.0
+ - vc >=14.3,<15
+ - vc14_runtime >=14.44.35208
+ license: Apache-2.0
+ license_family: Apache
+ purls:
+ - pkg:pypi/msgpack?source=hash-mapping
+ size: 88657
+ timestamp: 1762504357246
+- conda: https://conda.anaconda.org/conda-forge/linux-64/ncurses-6.5-h2d0b736_3.conda
+ sha256: 3fde293232fa3fca98635e1167de6b7c7fda83caf24b9d6c91ec9eefb4f4d586
+ md5: 47e340acb35de30501a76c7c799c41d7
+ depends:
+ - __glibc >=2.17,<3.0.a0
+ - libgcc >=13
+ license: X11 AND BSD-3-Clause
+ purls: []
+ size: 891641
+ timestamp: 1738195959188
+- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/ncurses-6.5-ha32ae93_3.conda
+ sha256: 91cfb655a68b0353b2833521dc919188db3d8a7f4c64bea2c6a7557b24747468
+ md5: 182afabe009dc78d8b73100255ee6868
+ depends:
+ - libgcc >=13
+ license: X11 AND BSD-3-Clause
+ purls: []
+ size: 926034
+ timestamp: 1738196018799
+- conda: https://conda.anaconda.org/conda-forge/osx-64/ncurses-6.5-h0622a9a_3.conda
+ sha256: ea4a5d27ded18443749aefa49dc79f6356da8506d508b5296f60b8d51e0c4bd9
+ md5: ced34dd9929f491ca6dab6a2927aff25
+ depends:
+ - __osx >=10.13
+ license: X11 AND BSD-3-Clause
+ purls: []
+ size: 822259
+ timestamp: 1738196181298
+- conda: https://conda.anaconda.org/conda-forge/osx-64/ncurses-6.5-h5846eda_0.conda
+ sha256: 6ecc73db0e49143092c0934355ac41583a5d5a48c6914c5f6ca48e562d3a4b79
+ md5: 02a888433d165c99bf09784a7b14d900
+ license: X11 AND BSD-3-Clause
+ purls: []
+ size: 823601
+ timestamp: 1715195267791
+- conda: https://conda.anaconda.org/conda-forge/osx-arm64/ncurses-6.5-h5e97a16_3.conda
+ sha256: 2827ada40e8d9ca69a153a45f7fd14f32b2ead7045d3bbb5d10964898fe65733
+ md5: 068d497125e4bf8a66bf707254fff5ae
+ depends:
+ - __osx >=11.0
+ license: X11 AND BSD-3-Clause
+ purls: []
+ size: 797030
+ timestamp: 1738196177597
+- conda: https://conda.anaconda.org/conda-forge/osx-arm64/ncurses-6.5-hb89a1cb_0.conda
+ sha256: 87d7cf716d9d930dab682cb57b3b8d3a61940b47d6703f3529a155c938a6990a
+ md5: b13ad5724ac9ae98b6b4fd87e4500ba4
+ license: X11 AND BSD-3-Clause
+ purls: []
+ size: 795131
+ timestamp: 1715194898402
+- pypi: https://files.pythonhosted.org/packages/2b/60/c9a33361da8cde7c7760f091cd10467bc470634e4eea31c8bb70935b00a4/nh3-0.3.4-cp38-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
+ name: nh3
+ version: 0.3.4
+ sha256: 0d825722a1e8cbc87d7ca1e47ffb1d2a6cf343ad4c1b8465becf7cadcabcdfd0
+ requires_python: '>=3.8'
+- pypi: https://files.pythonhosted.org/packages/4a/57/a97955bc95960cfb1f0517043d60a121f4ba93fde252d4d9ffd3c2a9eead/nh3-0.3.4-cp38-abi3-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl
+ name: nh3
+ version: 0.3.4
+ sha256: d8bebcb20ab4b91858385cd98fe58046ec4a624275b45ef9b976475604f45b49
+ requires_python: '>=3.8'
+- pypi: https://files.pythonhosted.org/packages/73/4f/af8e9071d7464575a7316831938237ffc9d92d27f163dbdd964b1309cd9b/nh3-0.3.4-cp38-abi3-win_amd64.whl
+ name: nh3
+ version: 0.3.4
+ sha256: c10b1f0c741e257a5cb2978d6bac86e7c784ab20572724b20c6402c2e24bce75
+ requires_python: '>=3.8'
+- pypi: https://files.pythonhosted.org/packages/d6/b7/ec1cbc6b297a808c513f59f501656389623fc09ad6a58c640851289c7854/nh3-0.3.4-cp38-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
+ name: nh3
+ version: 0.3.4
+ sha256: 0961a27dc2057c38d0364cb05880e1997ae1c80220cbc847db63213720b8f304
+ requires_python: '>=3.8'
+- conda: https://conda.anaconda.org/conda-forge/linux-64/ninja-1.13.2-h171cf75_0.conda
+ sha256: 6f7d59dbec0a7b00bf5d103a4306e8886678b796ff2151b62452d4582b2a53fb
+ md5: b518e9e92493721281a60fa975bddc65
+ depends:
+ - libstdcxx >=14
+ - libgcc >=14
+ - __glibc >=2.17,<3.0.a0
+ license: Apache-2.0
+ license_family: APACHE
+ purls: []
+ size: 186323
+ timestamp: 1763688260928
+- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/ninja-1.13.2-hdc560ac_0.conda
+ sha256: 45fbc7c8c44681f5cefba1e5b26ca504a4485b000c5dfaa31cec0b7bc78d0de4
+ md5: 8b5222a41b5d51fb1a5a2c514e770218
+ depends:
+ - libstdcxx >=14
+ - libgcc >=14
+ license: Apache-2.0
+ license_family: APACHE
+ purls: []
+ size: 182666
+ timestamp: 1763688214250
+- conda: https://conda.anaconda.org/conda-forge/osx-64/ninja-1.12.0-h7728843_0.conda
+ sha256: dcc10cbea89b1846c76d7df06023f23866e794beb6412fffafb2fce6da19db05
+ md5: 1ac079f6ecddd2c336f3acb7b371851f
+ depends:
+ - libcxx >=16
+ license: Apache-2.0
+ license_family: Apache
+ purls: []
+ size: 124810
+ timestamp: 1713204841161
+- conda: https://conda.anaconda.org/conda-forge/osx-arm64/ninja-1.12.0-h2ffa867_0.conda
+ sha256: 634ff2cda6a77b9cd8935e748a1d5698f51f87f1a226638ddc95eb22f6a172ea
+ md5: 24e1b17a513393ee4e81e51fdab1fa93
+ depends:
+ - libcxx >=16
+ license: Apache-2.0
+ license_family: Apache
+ purls: []
+ size: 111688
+ timestamp: 1713205253264
+- conda: https://conda.anaconda.org/conda-forge/win-64/ninja-1.13.2-h477610d_0.conda
+ sha256: e41a945c34a5f0bd2109b73a65486cd93023fa0a9bcba3ef98f9a3da40ba1180
+ md5: 7ecb9f2f112c66f959d2bb7dbdb89b67
+ depends:
+ - vc >=14.3,<15
+ - vc14_runtime >=14.44.35208
+ - ucrt >=10.0.20348.0
+ - vc >=14.3,<15
+ - vc14_runtime >=14.44.35208
+ - ucrt >=10.0.20348.0
+ license: Apache-2.0
+ license_family: APACHE
+ purls: []
+ size: 309417
+ timestamp: 1763688227932
+- conda: https://conda.anaconda.org/conda-forge/noarch/nlohmann_json-abi-3.12.0-h0f90c79_1.conda
+ sha256: 2a909594ca78843258e4bda36e43d165cda844743329838a29402823c8f20dec
+ md5: 59659d0213082bc13be8500bab80c002
+ license: MIT
+ license_family: MIT
+ purls: []
+ size: 4335
+ timestamp: 1758194464430
+- conda: https://conda.anaconda.org/conda-forge/noarch/nodeenv-1.10.0-pyhd8ed1ab_0.conda
+ sha256: 4fa40e3e13fc6ea0a93f67dfc76c96190afd7ea4ffc1bac2612d954b42cdc3ee
+ md5: eb52d14a901e23c39e9e7b4a1a5c015f
+ depends:
+ - python >=3.10
+ - setuptools
+ license: BSD-3-Clause
+ license_family: BSD
+ purls:
+ - pkg:pypi/nodeenv?source=hash-mapping
+ size: 40866
+ timestamp: 1766261270149
+- conda: https://conda.anaconda.org/conda-forge/linux-64/numpy-2.2.6-py310hefbff90_0.conda
+ sha256: 0ba94a61f91d67413e60fa8daa85627a8f299b5054b0eff8f93d26da83ec755e
+ md5: b0cea2c364bf65cd19e023040eeab05d
+ depends:
+ - __glibc >=2.17,<3.0.a0
+ - libblas >=3.9.0,<4.0a0
+ - libcblas >=3.9.0,<4.0a0
+ - libgcc >=13
+ - liblapack >=3.9.0,<4.0a0
+ - libstdcxx >=13
+ - python >=3.10,<3.11.0a0
+ - python_abi 3.10.* *_cp310
+ constrains:
+ - numpy-base <0a0
+ license: BSD-3-Clause
+ license_family: BSD
+ purls:
+ - pkg:pypi/numpy?source=hash-mapping
+ size: 7893263
+ timestamp: 1747545075833
+- conda: https://conda.anaconda.org/conda-forge/linux-64/numpy-2.4.2-py311h2e04523_1.conda
+ sha256: 2f9971a62316b9acb6ade749cebb59ffe750d1c2d99fe7061c6440589f6d3299
+ md5: a8105076864776eceae69d64d30e24d7
+ depends:
+ - python
+ - __glibc >=2.17,<3.0.a0
+ - libstdcxx >=14
+ - libgcc >=14
+ - libblas >=3.9.0,<4.0a0
+ - python_abi 3.11.* *_cp311
+ - libcblas >=3.9.0,<4.0a0
+ - liblapack >=3.9.0,<4.0a0
+ constrains:
+ - numpy-base <0a0
+ license: BSD-3-Clause
+ license_family: BSD
+ purls:
+ - pkg:pypi/numpy?source=compressed-mapping
+ size: 9385101
+ timestamp: 1770098496391
+- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/numpy-2.2.6-py310h6e5608f_0.conda
+ sha256: d7234b9c45e4863c7d4c5221c1e91d69b0e0009464bf361c3fea47e64dc4adc2
+ md5: 9e9f1f279eb02c41bda162a42861adc0
+ depends:
+ - libblas >=3.9.0,<4.0a0
+ - libcblas >=3.9.0,<4.0a0
+ - libgcc >=13
+ - liblapack >=3.9.0,<4.0a0
+ - libstdcxx >=13
+ - python >=3.10,<3.11.0a0
+ - python >=3.10,<3.11.0a0 *_cpython
+ - python_abi 3.10.* *_cp310
+ constrains:
+ - numpy-base <0a0
+ license: BSD-3-Clause
+ license_family: BSD
+ purls:
+ - pkg:pypi/numpy?source=hash-mapping
+ size: 6556655
+ timestamp: 1747545077963
+- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/numpy-2.4.2-py311h669026d_1.conda
+ sha256: b40796e2b47878a38ffa5e76703a1d4d9f5fc09787cdf54fed9f4af8b66d1eb8
+ md5: 6b411688a868a37d95abfb99ebc8b88e
+ depends:
+ - python
+ - libstdcxx >=14
+ - libgcc >=14
+ - python 3.11.* *_cpython
+ - liblapack >=3.9.0,<4.0a0
+ - libcblas >=3.9.0,<4.0a0
+ - python_abi 3.11.* *_cp311
+ - libblas >=3.9.0,<4.0a0
+ constrains:
+ - numpy-base <0a0
+ license: BSD-3-Clause
+ license_family: BSD
+ purls:
+ - pkg:pypi/numpy?source=hash-mapping
+ size: 8462316
+ timestamp: 1770098524745
+- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/numpy-2.4.3-py311h669026d_0.conda
+ sha256: 33e4d3e097a9d05e9e09d2895f4bd20f7fc93c8cb0df35da4716d0ba836a0d86
+ md5: 23c6d37dec83159283cfeee4fceebf84
+ depends:
+ - python
+ - python 3.11.* *_cpython
+ - libgcc >=14
+ - libstdcxx >=14
+ - libblas >=3.9.0,<4.0a0
+ - liblapack >=3.9.0,<4.0a0
+ - python_abi 3.11.* *_cp311
+ - libcblas >=3.9.0,<4.0a0
+ constrains:
+ - numpy-base <0a0
+ license: BSD-3-Clause
+ purls:
+ - pkg:pypi/numpy?source=hash-mapping
+ size: 8464385
+ timestamp: 1773839300790
+- conda: https://conda.anaconda.org/conda-forge/osx-64/numpy-1.26.4-py310h4bfa8fc_0.conda
+ sha256: 914476e2d3273fdf9c0419a7bdcb7b31a5ec25949e4afbc847297ff3a50c62c8
+ md5: cd6a2298387f558c9ea70ee73a189791
+ depends:
+ - libblas >=3.9.0,<4.0a0
+ - libcblas >=3.9.0,<4.0a0
+ - libcxx >=16
+ - liblapack >=3.9.0,<4.0a0
+ - python >=3.10,<3.11.0a0
+ - python_abi 3.10.* *_cp310
+ constrains:
+ - numpy-base <0a0
+ license: BSD-3-Clause
+ license_family: BSD
+ purls:
+ - pkg:pypi/numpy?source=hash-mapping
+ size: 6491938
+ timestamp: 1707226191321
+- conda: https://conda.anaconda.org/conda-forge/osx-64/numpy-1.26.4-py311hc43a94b_0.conda
+ sha256: dc9628197125ee1d02b2e7a859a769d26291d747ed79337309b8a9e67a8b8e00
+ md5: bb02b8801d17265160e466cf8bbf28da
+ depends:
+ - libblas >=3.9.0,<4.0a0
+ - libcblas >=3.9.0,<4.0a0
+ - libcxx >=16
+ - liblapack >=3.9.0,<4.0a0
+ - python >=3.11,<3.12.0a0
+ - python_abi 3.11.* *_cp311
+ constrains:
+ - numpy-base <0a0
+ license: BSD-3-Clause
+ license_family: BSD
+ purls:
+ - pkg:pypi/numpy?source=hash-mapping
+ size: 7504319
+ timestamp: 1707226235372
+- conda: https://conda.anaconda.org/conda-forge/osx-arm64/numpy-1.26.4-py310hd45542a_0.conda
+ sha256: e3078108a4973e73c813b89228f4bd8095ec58f96ca29f55d2e45a6223a9a1db
+ md5: 267ee89a3a0b8c8fa838a2353f9ea0c0
+ depends:
+ - libblas >=3.9.0,<4.0a0
+ - libcblas >=3.9.0,<4.0a0
+ - libcxx >=16
+ - liblapack >=3.9.0,<4.0a0
+ - python >=3.10,<3.11.0a0
+ - python >=3.10,<3.11.0a0 *_cpython
+ - python_abi 3.10.* *_cp310
+ constrains:
+ - numpy-base <0a0
+ license: BSD-3-Clause
+ license_family: BSD
+ purls:
+ - pkg:pypi/numpy?source=hash-mapping
+ size: 5475744
+ timestamp: 1707226187124
+- conda: https://conda.anaconda.org/conda-forge/osx-arm64/numpy-1.26.4-py311h7125741_0.conda
+ sha256: 160a52a01fea44fe9753a2ed22cf13d7b55c8a89ea0b8738546fdbf4795d6514
+ md5: 3160b93669a0def35a7a8158ebb33816
+ depends:
+ - libblas >=3.9.0,<4.0a0
+ - libcblas >=3.9.0,<4.0a0
+ - libcxx >=16
+ - liblapack >=3.9.0,<4.0a0
+ - python >=3.11,<3.12.0a0
+ - python >=3.11,<3.12.0a0 *_cpython
+ - python_abi 3.11.* *_cp311
+ constrains:
+ - numpy-base <0a0
+ license: BSD-3-Clause
+ license_family: BSD
+ purls:
+ - pkg:pypi/numpy?source=hash-mapping
+ size: 6652352
+ timestamp: 1707226297967
+- conda: https://conda.anaconda.org/conda-forge/win-64/numpy-2.2.6-py310h4987827_0.conda
+ sha256: 6f628e51763b86a535a723664e3aa1e38cb7147a2697f80b75c1980c1ed52f3e
+ md5: d2596785ac2cf5bab04e2ee9e5d04041
+ depends:
+ - libblas >=3.9.0,<4.0a0
+ - libcblas >=3.9.0,<4.0a0
+ - liblapack >=3.9.0,<4.0a0
+ - python >=3.10,<3.11.0a0
+ - python_abi 3.10.* *_cp310
+ - ucrt >=10.0.20348.0
+ - vc >=14.2,<15
+ - vc14_runtime >=14.29.30139
+ constrains:
+ - numpy-base <0a0
+ license: BSD-3-Clause
+ license_family: BSD
+ purls:
+ - pkg:pypi/numpy?source=hash-mapping
+ size: 6596153
+ timestamp: 1747545352390
+- conda: https://conda.anaconda.org/conda-forge/win-64/numpy-2.4.2-py311h80b3fa1_1.conda
+ sha256: c5cd26fb28d92d6c3843b96489f433ef87d1866d03a746f7228230b74bef431a
+ md5: a824c6667179120c458beb9e9394932f
+ depends:
+ - python
+ - vc >=14.3,<15
+ - vc14_runtime >=14.44.35208
+ - ucrt >=10.0.20348.0
+ - python_abi 3.11.* *_cp311
+ - libcblas >=3.9.0,<4.0a0
+ - liblapack >=3.9.0,<4.0a0
+ - libblas >=3.9.0,<4.0a0
+ constrains:
+ - numpy-base <0a0
+ license: BSD-3-Clause
+ license_family: BSD
+ purls:
+ - pkg:pypi/numpy?source=hash-mapping
+ size: 7803678
+ timestamp: 1770098404597
+- conda: https://conda.anaconda.org/conda-forge/linux-64/openssl-3.6.1-h35e630c_1.conda
+ sha256: 44c877f8af015332a5d12f5ff0fb20ca32f896526a7d0cdb30c769df1144fb5c
+ md5: f61eb8cd60ff9057122a3d338b99c00f
+ depends:
+ - __glibc >=2.17,<3.0.a0
+ - ca-certificates
+ - libgcc >=14
+ license: Apache-2.0
+ license_family: Apache
+ purls: []
+ size: 3164551
+ timestamp: 1769555830639
+- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/openssl-3.6.1-h546c87b_1.conda
+ sha256: 7f8048c0e75b2620254218d72b4ae7f14136f1981c5eb555ef61645a9344505f
+ md5: 25f5885f11e8b1f075bccf4a2da91c60
+ depends:
+ - ca-certificates
+ - libgcc >=14
+ license: Apache-2.0
+ license_family: Apache
+ purls: []
+ size: 3692030
+ timestamp: 1769557678657
+- conda: https://conda.anaconda.org/conda-forge/osx-64/openssl-3.3.0-hd75f5a5_0.conda
+ sha256: d3889b0c89c2742e92e20f01e8f298b64c221df5d577c639b823a0bfe314e2e3
+ md5: eb8c33aa7929a7714eab8b90c1d88afe
+ depends:
+ - ca-certificates
+ constrains:
+ - pyopenssl >=22.1
+ license: Apache-2.0
+ license_family: Apache
+ purls: []
+ size: 2541802
+ timestamp: 1714467068742
+- conda: https://conda.anaconda.org/conda-forge/osx-64/openssl-3.6.1-hb6871ef_1.conda
+ sha256: e02e5639b0e4d6d4fcf0f3b082642844fb5a37316f5b0a1126c6271347462e90
+ md5: 30bb8d08b99b9a7600d39efb3559fff0
+ depends:
+ - __osx >=10.13
+ - ca-certificates
+ license: Apache-2.0
+ license_family: Apache
+ purls: []
+ size: 2777136
+ timestamp: 1769557662405
+- conda: https://conda.anaconda.org/conda-forge/osx-arm64/openssl-3.3.0-h0d3ecfb_0.conda
+ sha256: 51f9be8fe929c2bb3243cd0707b6dfcec27541f8284b4bd9b063c288fc46f482
+ md5: 25b0e522c3131886a637e347b2ca0c0f
+ depends:
+ - ca-certificates
+ constrains:
+ - pyopenssl >=22.1
+ license: Apache-2.0
+ license_family: Apache
+ purls: []
+ size: 2888226
+ timestamp: 1714466346030
+- conda: https://conda.anaconda.org/conda-forge/osx-arm64/openssl-3.6.1-hd24854e_1.conda
+ sha256: 361f5c5e60052abc12bdd1b50d7a1a43e6a6653aab99a2263bf2288d709dcf67
+ md5: f4f6ad63f98f64191c3e77c5f5f29d76
+ depends:
+ - __osx >=11.0
+ - ca-certificates
+ license: Apache-2.0
+ license_family: Apache
+ purls: []
+ size: 3104268
+ timestamp: 1769556384749
+- conda: https://conda.anaconda.org/conda-forge/win-64/openssl-3.6.1-hf411b9b_1.conda
+ sha256: 53a5ad2e5553b8157a91bb8aa375f78c5958f77cb80e9d2ce59471ea8e5c0bd6
+ md5: eb585509b815415bc964b2c7e11c7eb3
+ depends:
+ - ca-certificates
+ - ucrt >=10.0.20348.0
+ - vc >=14.3,<15
+ - vc14_runtime >=14.44.35208
+ license: Apache-2.0
+ license_family: Apache
+ purls: []
+ size: 9343023
+ timestamp: 1769557547888
+- conda: https://conda.anaconda.org/conda-forge/noarch/packaging-25.0-pyh29332c3_1.conda
+ sha256: 289861ed0c13a15d7bbb408796af4de72c2fe67e2bcb0de98f4c3fce259d7991
+ md5: 58335b26c38bf4a20f399384c33cbcf9
+ depends:
+ - python >=3.8
+ - python
+ license: Apache-2.0
+ license_family: APACHE
+ purls:
+ - pkg:pypi/packaging?source=hash-mapping
+ size: 62477
+ timestamp: 1745345660407
+- conda: https://conda.anaconda.org/conda-forge/noarch/packaging-26.0-pyhcf101f3_0.conda
+ sha256: c1fc0f953048f743385d31c468b4a678b3ad20caffdeaa94bed85ba63049fd58
+ md5: b76541e68fea4d511b1ac46a28dcd2c6
+ depends:
+ - python >=3.8
+ - python
+ license: Apache-2.0
+ license_family: APACHE
+ purls:
+ - pkg:pypi/packaging?source=compressed-mapping
+ size: 72010
+ timestamp: 1769093650580
+- conda: https://conda.anaconda.org/conda-forge/linux-64/patchelf-0.17.2-h58526e2_0.conda
+ sha256: eb355ac225be2f698e19dba4dcab7cb0748225677a9799e9cc8e4cadc3cb738f
+ md5: ba76a6a448819560b5f8b08a9c74f415
+ depends:
+ - libgcc-ng >=7.5.0
+ - libstdcxx-ng >=7.5.0
+ license: GPL-3.0-or-later
+ license_family: GPL
+ purls: []
+ size: 94048
+ timestamp: 1673473024463
+- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/patchelf-0.17.2-h884eca8_0.conda
+ sha256: 8b98158f36a7a92013a1982ab7a60947151350ac5c513c1d1575825d0fa52518
+ md5: bbd8dee69c4ac2e2d07bca100b8fcc31
+ depends:
+ - libgcc-ng >=7.5.0
+ - libstdcxx-ng >=7.5.0
+ license: GPL-3.0-or-later
+ license_family: GPL
+ purls: []
+ size: 101306
+ timestamp: 1673473812166
+- conda: https://conda.anaconda.org/conda-forge/noarch/pathspec-1.0.4-pyhd8ed1ab_0.conda
+ sha256: 29ea20d0faf20374fcd61c25f6d32fb8e9a2c786a7f1473a0c3ead359470fbe1
+ md5: 2908273ac396d2cd210a8127f5f1c0d6
+ depends:
+ - python >=3.10
+ license: MPL-2.0
+ license_family: MOZILLA
+ purls:
+ - pkg:pypi/pathspec?source=hash-mapping
+ size: 53739
+ timestamp: 1769677743677
+- pypi: https://files.pythonhosted.org/packages/54/16/12b82f791c7f50ddec566873d5bdd245baa1491bac11d15ffb98aecc8f8b/pefile-2024.8.26-py3-none-any.whl
+ name: pefile
+ version: 2024.8.26
+ sha256: 76f8b485dcd3b1bb8166f1128d395fa3d87af26360c2358fb75b80019b957c6f
+ requires_python: '>=3.6.0'
+- conda: https://conda.anaconda.org/conda-forge/noarch/pip-26.0.1-pyh8b19718_0.conda
+ sha256: 8e1497814a9997654ed7990a79c054ea5a42545679407acbc6f7e809c73c9120
+ md5: 67bdec43082fd8a9cffb9484420b39a2
+ depends:
+ - python >=3.10,<3.13.0a0
+ - setuptools
+ - wheel
+ license: MIT
+ license_family: MIT
+ purls:
+ - pkg:pypi/pip?source=compressed-mapping
+ size: 1181790
+ timestamp: 1770270305795
+- conda: https://conda.anaconda.org/conda-forge/noarch/pixi-pycharm-0.0.10-unix_hf108a03_0.conda
+ sha256: c84a62f421f3ba388df06df7f414d7b568ad4bc3c33a7799b3405f213a3b1ff5
+ md5: 07b709969aa53039501c5960e45794b8
+ depends:
+ - __unix
+ - python >=3.8
+ license: BSD-3-Clause
+ license_family: BSD
+ purls: []
+ size: 7034
+ timestamp: 1763572165675
+- conda: https://conda.anaconda.org/conda-forge/noarch/pixi-pycharm-0.0.10-win_hba80fca_0.conda
+ sha256: c0399f79f0656df7e265ae53630e08cad2d2203a2f39181ff1a68b3b39466d0d
+ md5: 6dea6b7cca5948b0cfd6eeb5ddecce67
+ depends:
+ - __win
+ - python >=3.8
+ license: BSD-3-Clause
+ license_family: BSD
+ purls: []
+ size: 7042
+ timestamp: 1763572121812
+- conda: https://conda.anaconda.org/conda-forge/noarch/pkginfo-1.12.1.2-pyhd8ed1ab_0.conda
+ sha256: 353fd5a2c3ce31811a6272cd328874eb0d327b1eafd32a1e19001c4ad137ad3a
+ md5: dc702b2fae7ebe770aff3c83adb16b63
+ depends:
+ - python >=3.9
+ license: MIT
+ license_family: MIT
+ purls:
+ - pkg:pypi/pkginfo?source=hash-mapping
+ size: 30536
+ timestamp: 1739984682585
+- conda: https://conda.anaconda.org/conda-forge/noarch/platformdirs-4.9.4-pyhcf101f3_0.conda
+ sha256: 0289f0a38337ee201d984f8f31f11f6ef076cfbbfd0ab9181d12d9d1d099bf46
+ md5: 82c1787f2a65c0155ef9652466ee98d6
+ depends:
+ - python >=3.10
+ - python
+ license: MIT
+ license_family: MIT
+ purls:
+ - pkg:pypi/platformdirs?source=compressed-mapping
+ size: 25646
+ timestamp: 1773199142345
+- conda: https://conda.anaconda.org/conda-forge/noarch/pluggy-1.6.0-pyhf9edf01_1.conda
+ sha256: e14aafa63efa0528ca99ba568eaf506eb55a0371d12e6250aaaa61718d2eb62e
+ md5: d7585b6550ad04c8c5e21097ada2888e
+ depends:
+ - python >=3.9
+ - python
+ license: MIT
+ license_family: MIT
+ purls:
+ - pkg:pypi/pluggy?source=compressed-mapping
+ size: 25877
+ timestamp: 1764896838868
+- conda: https://conda.anaconda.org/conda-forge/noarch/pre-commit-4.5.1-pyha770c72_0.conda
+ sha256: 5b81b7516d4baf43d0c185896b245fa7384b25dc5615e7baa504b7fa4e07b706
+ md5: 7f3ac694319c7eaf81a0325d6405e974
+ depends:
+ - cfgv >=2.0.0
+ - identify >=1.0.0
+ - nodeenv >=0.11.1
+ - python >=3.10
+ - pyyaml >=5.1
+ - virtualenv >=20.10.0
+ license: MIT
+ license_family: MIT
+ purls:
+ - pkg:pypi/pre-commit?source=compressed-mapping
+ size: 200827
+ timestamp: 1765937577534
+- conda: https://conda.anaconda.org/conda-forge/noarch/pybind11-abi-11-hc364b38_1.conda
+ sha256: 9e7fe12f727acd2787fb5816b2049cef4604b7a00ad3e408c5e709c298ce8bf1
+ md5: f0599959a2447c1e544e216bddf393fa
+ license: BSD-3-Clause
+ license_family: BSD
+ purls: []
+ size: 14671
+ timestamp: 1752769938071
+- conda: https://conda.anaconda.org/conda-forge/linux-64/pycosat-0.6.6-py310h7c4b9e2_3.conda
+ sha256: 86d343a2122b55394fda137eaf5461b6e91ac459ffc6f5b4c78f69f00ffd1a12
+ md5: 14ab9efb46276ca0d751c942381e90dd
+ depends:
+ - __glibc >=2.17,<3.0.a0
+ - libgcc >=14
+ - python >=3.10,<3.11.0a0
+ - python_abi 3.10.* *_cp310
+ license: MIT
+ license_family: MIT
+ purls:
+ - pkg:pypi/pycosat?source=hash-mapping
+ size: 84754
+ timestamp: 1757744718942
+- conda: https://conda.anaconda.org/conda-forge/linux-64/pycosat-0.6.6-py311h49ec1c0_3.conda
+ sha256: 61c07e45a0a0c7a2b0dc986a65067fc2b00aba51663b7b05d4449c7862d7a390
+ md5: 77c1b47af5775a813193f7870be8644a
+ depends:
+ - __glibc >=2.17,<3.0.a0
+ - libgcc >=14
+ - python >=3.11,<3.12.0a0
+ - python_abi 3.11.* *_cp311
+ license: MIT
+ license_family: MIT
+ purls:
+ - pkg:pypi/pycosat?source=hash-mapping
+ size: 88491
+ timestamp: 1757744790912
+- conda: https://conda.anaconda.org/conda-forge/linux-64/pycosat-0.6.6-py314h5bd0f2a_3.conda
+ sha256: ccef6174b89815de1ede61b3b20ebccfe301865f2954d789e0b5c1e52dd45f91
+ md5: be49bb746ad2cd2ba6737b4afd6cf32a
+ depends:
+ - __glibc >=2.17,<3.0.a0
+ - libgcc >=14
+ - python >=3.14.0rc2,<3.15.0a0
+ - python_abi 3.14.* *_cp314
+ license: MIT
+ license_family: MIT
+ purls:
+ - pkg:pypi/pycosat?source=hash-mapping
+ size: 88644
+ timestamp: 1757744868118
+- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/pycosat-0.6.6-py310h5b55623_3.conda
+ sha256: 8d9511499803b3899273964a9a571760de5bd7ad4d90cbdf9a16946fc1c60605
+ md5: 49ad177a7adc4c714b2725c36f8b1f45
+ depends:
+ - libgcc >=14
+ - python >=3.10,<3.11.0a0
+ - python >=3.10,<3.11.0a0 *_cpython
+ - python_abi 3.10.* *_cp310
+ license: MIT
+ license_family: MIT
+ purls:
+ - pkg:pypi/pycosat?source=hash-mapping
+ size: 86257
+ timestamp: 1757744805289
+- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/pycosat-0.6.6-py311h19352d5_3.conda
+ sha256: 792ef42d5691757c087c2214e03e6e5cd1470075bc99c53a62067690345f80be
+ md5: 8b3741984919ba072ef6d1243e543336
+ depends:
+ - libgcc >=14
+ - python >=3.11,<3.12.0a0
+ - python >=3.11,<3.12.0a0 *_cpython
+ - python_abi 3.11.* *_cp311
+ license: MIT
+ license_family: MIT
+ purls:
+ - pkg:pypi/pycosat?source=hash-mapping
+ size: 88731
+ timestamp: 1757744856802
+- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/pycosat-0.6.6-py314h51f160d_3.conda
+ sha256: 20c29d8283581ed5fece2ea5ebac9c1f78756ff523d9c866b50110d8fadc3b7f
+ md5: 180a289ef4d6ce81588a13f55a4b7238
+ depends:
+ - libgcc >=14
+ - python >=3.14.0rc2,<3.15.0a0
+ - python >=3.14.0rc2,<3.15.0a0 *_cp314
+ - python_abi 3.14.* *_cp314
+ license: MIT
+ license_family: MIT
+ purls:
+ - pkg:pypi/pycosat?source=hash-mapping
+ size: 89501
+ timestamp: 1757744787708
+- conda: https://conda.anaconda.org/conda-forge/osx-64/pycosat-0.6.6-py310h6729b98_0.conda
+ sha256: c8ce26a91bd19ab83f8fb7e2f8ada1de799453b519ee156f59aa901146f353d8
+ md5: 89b601f80d076bf8053eea906293353c
+ depends:
+ - python >=3.10,<3.11.0a0
+ - python_abi 3.10.* *_cp310
+ license: MIT
+ license_family: MIT
+ purls:
+ - pkg:pypi/pycosat?source=hash-mapping
+ size: 84654
+ timestamp: 1696356173413
+- conda: https://conda.anaconda.org/conda-forge/osx-64/pycosat-0.6.6-py311h2725bcf_0.conda
+ sha256: 1899b863919c949d38634dbdaec7af2ddb52326a496dd68751ab4f4fe0e8f36a
+ md5: 47b4652f8a7e6222786663c757815dd5
+ depends:
+ - python >=3.11,<3.12.0a0
+ - python_abi 3.11.* *_cp311
+ license: MIT
+ license_family: MIT
+ purls:
+ - pkg:pypi/pycosat?source=hash-mapping
+ size: 88031
+ timestamp: 1696356171531
+- conda: https://conda.anaconda.org/conda-forge/osx-64/pycosat-0.6.6-py314h03d016b_3.conda
+ sha256: 6e361e86d25f9ca4b923c85cb0fb34c581b68199d9787df433260722e8101ab7
+ md5: a4e0b3801e6673059cea365dc47e4a6e
+ depends:
+ - __osx >=10.13
+ - python >=3.14.0rc2,<3.15.0a0
+ - python_abi 3.14.* *_cp314
+ license: MIT
+ license_family: MIT
+ purls:
+ - pkg:pypi/pycosat?source=hash-mapping
+ size: 96705
+ timestamp: 1757744863538
+- conda: https://conda.anaconda.org/conda-forge/osx-arm64/pycosat-0.6.6-py310h2aa6e3c_0.conda
+ sha256: 43fc36a584cc9db9cbcd0bee62875ca7702e68fd1df1f35db87f3a14098bb8bc
+ md5: 3a048bfd19ef0f4e1d6efd3f821c3988
+ depends:
+ - python >=3.10,<3.11.0a0
+ - python >=3.10,<3.11.0a0 *_cpython
+ - python_abi 3.10.* *_cp310
+ license: MIT
+ license_family: MIT
+ purls:
+ - pkg:pypi/pycosat?source=hash-mapping
+ size: 82535
+ timestamp: 1696356406059
+- conda: https://conda.anaconda.org/conda-forge/osx-arm64/pycosat-0.6.6-py311heffc1b2_0.conda
+ sha256: 4451971678bbc4fb314201f786c5c3640d429985d195e7d940bfd7d33a384560
+ md5: d60b2f87d7b8dd1623fb1baf91a0e311
+ depends:
+ - python >=3.11,<3.12.0a0
+ - python >=3.11,<3.12.0a0 *_cpython
+ - python_abi 3.11.* *_cp311
+ license: MIT
+ license_family: MIT
+ purls:
+ - pkg:pypi/pycosat?source=hash-mapping
+ size: 85652
+ timestamp: 1696356197481
+- conda: https://conda.anaconda.org/conda-forge/osx-arm64/pycosat-0.6.6-py314hb84d1df_3.conda
+ sha256: ec919254bca5ba7ef89ac1284582aa91297b89c3b640feda05a3cab0a0402db2
+ md5: b23019984b3399dada68581c20e6ef85
+ depends:
+ - __osx >=11.0
+ - python >=3.14.0rc2,<3.15.0a0
+ - python >=3.14.0rc2,<3.15.0a0 *_cp314
+ - python_abi 3.14.* *_cp314
+ license: MIT
+ license_family: MIT
+ purls:
+ - pkg:pypi/pycosat?source=hash-mapping
+ size: 92986
+ timestamp: 1757744788529
+- conda: https://conda.anaconda.org/conda-forge/win-64/pycosat-0.6.6-py310h29418f3_3.conda
+ sha256: e81fa9c4554907d3051f4fe6166d66949075bd6fac01f284902f73f4ac9da73e
+ md5: c51140b7978bf63c441af87be1f6fedf
+ depends:
+ - python >=3.10,<3.11.0a0
+ - python_abi 3.10.* *_cp310
+ - ucrt >=10.0.20348.0
+ - vc >=14.3,<15
+ - vc14_runtime >=14.44.35208
+ license: MIT
+ license_family: MIT
+ purls:
+ - pkg:pypi/pycosat?source=hash-mapping
+ size: 76648
+ timestamp: 1757744973237
+- conda: https://conda.anaconda.org/conda-forge/win-64/pycosat-0.6.6-py311h3485c13_3.conda
+ sha256: f2968e9d6516d7df4c678ce99e922285f244bfaf65069fb2cb3d307b4661f889
+ md5: b0cdbb8f4ecd5e1750400ef8bbcb390b
+ depends:
+ - python >=3.11,<3.12.0a0
+ - python_abi 3.11.* *_cp311
+ - ucrt >=10.0.20348.0
+ - vc >=14.3,<15
+ - vc14_runtime >=14.44.35208
+ license: MIT
+ license_family: MIT
+ purls:
+ - pkg:pypi/pycosat?source=hash-mapping
+ size: 79248
+ timestamp: 1757744865552
+- conda: https://conda.anaconda.org/conda-forge/win-64/pycosat-0.6.6-py314h5a2d7ad_3.conda
+ sha256: e14a8c506e699c968596f1a07e925d63dcc49ee9f3623c4c8a5541ad186e9071
+ md5: 4e6be0e1a7a9cd7dde994137b8ebd5cf
+ depends:
+ - python >=3.14.0rc2,<3.15.0a0
+ - python_abi 3.14.* *_cp314
+ - ucrt >=10.0.20348.0
+ - vc >=14.3,<15
+ - vc14_runtime >=14.44.35208
+ license: MIT
+ license_family: MIT
+ purls:
+ - pkg:pypi/pycosat?source=hash-mapping
+ size: 79551
+ timestamp: 1757744726713
+- conda: https://conda.anaconda.org/conda-forge/noarch/pycparser-2.22-pyh29332c3_1.conda
+ sha256: 79db7928d13fab2d892592223d7570f5061c192f27b9febd1a418427b719acc6
+ md5: 12c566707c80111f9799308d9e265aef
+ depends:
+ - python >=3.9
+ - python
+ license: BSD-3-Clause
+ license_family: BSD
+ purls:
+ - pkg:pypi/pycparser?source=hash-mapping
+ size: 110100
+ timestamp: 1733195786147
+- conda: https://conda.anaconda.org/conda-forge/noarch/pyelftools-0.32-pyh707e725_1.conda
+ sha256: de3a334388959397ba7b69ee92d5dfaa0c1bd6a7ffcf49c3c4de2ac045c69d28
+ md5: eae78c632c980c396cf6f711cf515c3a
+ depends:
+ - __unix
+ - python >=3.9
+ license: Unlicense
+ purls:
+ - pkg:pypi/pyelftools?source=hash-mapping
+ size: 149336
+ timestamp: 1744148364068
+- pypi: https://files.pythonhosted.org/packages/f4/7e/a72dd26f3b0f4f2bf1dd8923c85f7ceb43172af56d63c7383eb62b332364/pygments-2.20.0-py3-none-any.whl
+ name: pygments
+ version: 2.20.0
+ sha256: 81a9e26dd42fd28a23a2d169d86d7ac03b46e2f8b59ed4698fb4785f946d0176
+ requires_dist:
+ - colorama>=0.4.6 ; extra == 'windows-terminal'
+ requires_python: '>=3.9'
+- conda: https://conda.anaconda.org/conda-forge/noarch/pyopenssl-25.1.0-pyhd8ed1ab_0.conda
+ sha256: 0d7a8ebdfff0f579a64a95a94cf280ec2889d6c52829a9dbbd3ea9eef02c2f6f
+ md5: 63d6393b45f33dc0782d73f6d8ae36a0
+ depends:
+ - cryptography >=41.0.5,<46
+ - python >=3.9
+ - typing-extensions >=4.9
+ - typing_extensions >=4.9
+ license: Apache-2.0
+ license_family: Apache
+ purls:
+ - pkg:pypi/pyopenssl?source=hash-mapping
+ size: 123256
+ timestamp: 1747560884456
+- pypi: https://files.pythonhosted.org/packages/bd/24/12818598c362d7f300f18e74db45963dbcb85150324092410c8b49405e42/pyproject_hooks-1.2.0-py3-none-any.whl
+ name: pyproject-hooks
+ version: 1.2.0
+ sha256: 9e5c6bfa8dcc30091c74b0cf803c81fdd29d94f01992a7707bc97babb1141913
+ requires_python: '>=3.7'
+- conda: https://conda.anaconda.org/conda-forge/noarch/pyproject-metadata-0.11.0-pyhd8ed1ab_0.conda
+ sha256: 7e709bde682104c241674f8005fd560d7ea8599458c94d03ed51ef8a4ae7d737
+ md5: cd6dae6c673c8f12fe7267eac3503961
+ depends:
+ - packaging >=23.2
+ - python >=3.10
+ license: MIT
+ license_family: MIT
+ purls:
+ - pkg:pypi/pyproject-metadata?source=hash-mapping
+ size: 25200
+ timestamp: 1770672303277
+- conda: https://conda.anaconda.org/conda-forge/noarch/pysocks-1.7.1-pyh09c184e_7.conda
+ sha256: d016e04b0e12063fbee4a2d5fbb9b39a8d191b5a0042f0b8459188aedeabb0ca
+ md5: e2fd202833c4a981ce8a65974fe4abd1
+ depends:
+ - __win
+ - python >=3.9
+ - win_inet_pton
+ license: BSD-3-Clause
+ license_family: BSD
+ purls:
+ - pkg:pypi/pysocks?source=hash-mapping
+ size: 21784
+ timestamp: 1733217448189
+- conda: https://conda.anaconda.org/conda-forge/noarch/pysocks-1.7.1-pyha55dd90_7.conda
+ sha256: ba3b032fa52709ce0d9fd388f63d330a026754587a2f461117cac9ab73d8d0d8
+ md5: 461219d1a5bd61342293efa2c0c90eac
+ depends:
+ - __unix
+ - python >=3.9
+ license: BSD-3-Clause
+ license_family: BSD
+ purls:
+ - pkg:pypi/pysocks?source=hash-mapping
+ size: 21085
+ timestamp: 1733217331982
+- conda: https://conda.anaconda.org/conda-forge/linux-64/python-3.10.20-h3c07f61_0_cpython.conda
+ sha256: 8ff2ce308faf2588b69c65b120293f59a8f2577b772b34df4e817d220b09e081
+ md5: 5d4e2b00d99feacd026859b7fa239dc0
+ depends:
+ - __glibc >=2.17,<3.0.a0
+ - bzip2 >=1.0.8,<2.0a0
+ - ld_impl_linux-64 >=2.36.1
+ - libexpat >=2.7.4,<3.0a0
+ - libffi >=3.4,<4.0a0
+ - libgcc >=14
+ - liblzma >=5.8.2,<6.0a0
+ - libnsl >=2.0.1,<2.1.0a0
+ - libsqlite >=3.51.2,<4.0a0
+ - libuuid >=2.41.3,<3.0a0
+ - libxcrypt >=4.4.36
+ - libzlib >=1.3.1,<2.0a0
+ - ncurses >=6.5,<7.0a0
+ - openssl >=3.5.5,<4.0a0
+ - readline >=8.3,<9.0a0
+ - tk >=8.6.13,<8.7.0a0
+ - tzdata
+ constrains:
+ - python_abi 3.10.* *_cp310
+ license: Python-2.0
+ purls: []
+ size: 25455342
+ timestamp: 1772729810280
+- conda: https://conda.anaconda.org/conda-forge/linux-64/python-3.11.15-hd63d673_0_cpython.conda
+ sha256: bf6a32c69889d38482436a786bea32276756cedf0e9805cc856ffd088e8d00f0
+ md5: a5ebcefec0c12a333bcd6d7bf3bddc1f
+ depends:
+ - __glibc >=2.17,<3.0.a0
+ - bzip2 >=1.0.8,<2.0a0
+ - ld_impl_linux-64 >=2.36.1
+ - libexpat >=2.7.4,<3.0a0
+ - libffi >=3.5.2,<3.6.0a0
+ - libgcc >=14
+ - liblzma >=5.8.2,<6.0a0
+ - libnsl >=2.0.1,<2.1.0a0
+ - libsqlite >=3.51.2,<4.0a0
+ - libuuid >=2.41.3,<3.0a0
+ - libxcrypt >=4.4.36
+ - libzlib >=1.3.1,<2.0a0
+ - ncurses >=6.5,<7.0a0
+ - openssl >=3.5.5,<4.0a0
+ - readline >=8.3,<9.0a0
+ - tk >=8.6.13,<8.7.0a0
+ - tzdata
+ constrains:
+ - python_abi 3.11.* *_cp311
+ license: Python-2.0
+ purls: []
+ size: 30949404
+ timestamp: 1772730362552
+- conda: https://conda.anaconda.org/conda-forge/linux-64/python-3.14.3-h32b2ec7_101_cp314.conda
+ build_number: 101
+ sha256: cb0628c5f1732f889f53a877484da98f5a0e0f47326622671396fb4f2b0cd6bd
+ md5: c014ad06e60441661737121d3eae8a60
+ depends:
+ - __glibc >=2.17,<3.0.a0
+ - bzip2 >=1.0.8,<2.0a0
+ - ld_impl_linux-64 >=2.36.1
+ - libexpat >=2.7.3,<3.0a0
+ - libffi >=3.5.2,<3.6.0a0
+ - libgcc >=14
+ - liblzma >=5.8.2,<6.0a0
+ - libmpdec >=4.0.0,<5.0a0
+ - libsqlite >=3.51.2,<4.0a0
+ - libuuid >=2.41.3,<3.0a0
+ - libzlib >=1.3.1,<2.0a0
+ - ncurses >=6.5,<7.0a0
+ - openssl >=3.5.5,<4.0a0
+ - python_abi 3.14.* *_cp314
+ - readline >=8.3,<9.0a0
+ - tk >=8.6.13,<8.7.0a0
+ - tzdata
+ - zstd >=1.5.7,<1.6.0a0
+ license: Python-2.0
+ purls: []
+ size: 36702440
+ timestamp: 1770675584356
+ python_site_packages_path: lib/python3.14/site-packages
+- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/python-3.10.20-h28be5d3_0_cpython.conda
+ sha256: 2f16794d69e058404cca633021b284e70253dfb76e4b314d9dbd448aa0354e84
+ md5: 5d61c9a2acf7c675f7ae5f6cf51ffb0b
+ depends:
+ - bzip2 >=1.0.8,<2.0a0
+ - ld_impl_linux-aarch64 >=2.36.1
+ - libexpat >=2.7.4,<3.0a0
+ - libffi >=3.4,<4.0a0
+ - libgcc >=14
+ - liblzma >=5.8.2,<6.0a0
+ - libnsl >=2.0.1,<2.1.0a0
+ - libsqlite >=3.51.2,<4.0a0
+ - libuuid >=2.41.3,<3.0a0
+ - libxcrypt >=4.4.36
+ - libzlib >=1.3.1,<2.0a0
+ - ncurses >=6.5,<7.0a0
+ - openssl >=3.5.5,<4.0a0
+ - readline >=8.3,<9.0a0
+ - tk >=8.6.13,<8.7.0a0
+ - tzdata
+ constrains:
+ - python_abi 3.10.* *_cp310
+ license: Python-2.0
+ purls: []
+ size: 13234644
+ timestamp: 1772728813900
+- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/python-3.11.15-h91f4b29_0_cpython.conda
+ sha256: da3aa4c63af904d38c2e0b6ceecfa539d60c2653ac3cff7cae79d87298dc4fb0
+ md5: bb09184ea3313703da05516cd730e8f8
+ depends:
+ - bzip2 >=1.0.8,<2.0a0
+ - ld_impl_linux-aarch64 >=2.36.1
+ - libexpat >=2.7.4,<3.0a0
+ - libffi >=3.5.2,<3.6.0a0
+ - libgcc >=14
+ - liblzma >=5.8.2,<6.0a0
+ - libnsl >=2.0.1,<2.1.0a0
+ - libsqlite >=3.51.2,<4.0a0
+ - libuuid >=2.41.3,<3.0a0
+ - libxcrypt >=4.4.36
+ - libzlib >=1.3.1,<2.0a0
+ - ncurses >=6.5,<7.0a0
+ - openssl >=3.5.5,<4.0a0
+ - readline >=8.3,<9.0a0
+ - tk >=8.6.13,<8.7.0a0
+ - tzdata
+ constrains:
+ - python_abi 3.11.* *_cp311
+ license: Python-2.0
+ purls: []
+ size: 14306513
+ timestamp: 1772728906052
+- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/python-3.14.3-hb06a95a_101_cp314.conda
+ build_number: 101
+ sha256: 87e9dff5646aba87cecfbc08789634c855871a7325169299d749040b0923a356
+ md5: 205011b36899ff0edf41b3db0eda5a44
+ depends:
+ - bzip2 >=1.0.8,<2.0a0
+ - ld_impl_linux-aarch64 >=2.36.1
+ - libexpat >=2.7.3,<3.0a0
+ - libffi >=3.5.2,<3.6.0a0
+ - libgcc >=14
+ - liblzma >=5.8.2,<6.0a0
+ - libmpdec >=4.0.0,<5.0a0
+ - libsqlite >=3.51.2,<4.0a0
+ - libuuid >=2.41.3,<3.0a0
+ - libzlib >=1.3.1,<2.0a0
+ - ncurses >=6.5,<7.0a0
+ - openssl >=3.5.5,<4.0a0
+ - python_abi 3.14.* *_cp314
+ - readline >=8.3,<9.0a0
+ - tk >=8.6.13,<8.7.0a0
+ - tzdata
+ - zstd >=1.5.7,<1.6.0a0
+ license: Python-2.0
+ purls: []
+ size: 37305578
+ timestamp: 1770674395875
+ python_site_packages_path: lib/python3.14/site-packages
+- conda: https://conda.anaconda.org/conda-forge/osx-64/python-3.10.14-h00d2728_0_cpython.conda
+ sha256: 00c1de2d46ede26609ef4e84a44b83be7876ba6a0215b7c83bff41a0656bf694
+ md5: 0a1cddc4382c5c171e791c70740546dd
+ depends:
+ - bzip2 >=1.0.8,<2.0a0
+ - libffi >=3.4,<4.0a0
+ - libsqlite >=3.45.2,<4.0a0
+ - libzlib >=1.2.13,<2.0.0a0
+ - ncurses >=6.4.20240210,<7.0a0
+ - openssl >=3.2.1,<4.0a0
+ - readline >=8.2,<9.0a0
+ - tk >=8.6.13,<8.7.0a0
+ - tzdata
+ - xz >=5.2.6,<6.0a0
+ constrains:
+ - python_abi 3.10.* *_cp310
+ license: Python-2.0
+ purls: []
+ size: 11890228
+ timestamp: 1710940046031
+- conda: https://conda.anaconda.org/conda-forge/osx-64/python-3.11.8-h9f0c242_0_cpython.conda
+ sha256: 645dad20b46041ecd6a85eccbb3291fa1ad7921eea065c0081efff78c3d7e27a
+ md5: 22bda10a0f425564a538aed9a0e8a9df
+ depends:
+ - bzip2 >=1.0.8,<2.0a0
+ - libexpat >=2.5.0,<3.0a0
+ - libffi >=3.4,<4.0a0
+ - libsqlite >=3.45.1,<4.0a0
+ - libzlib >=1.2.13,<2.0.0a0
+ - ncurses >=6.4,<7.0a0
+ - openssl >=3.2.1,<4.0a0
+ - readline >=8.2,<9.0a0
+ - tk >=8.6.13,<8.7.0a0
+ - tzdata
+ - xz >=5.2.6,<6.0a0
+ constrains:
+ - python_abi 3.11.* *_cp311
+ license: Python-2.0
+ purls: []
+ size: 14067894
+ timestamp: 1708117836907
+- conda: https://conda.anaconda.org/conda-forge/osx-64/python-3.14.3-h4f44bb5_101_cp314.conda
+ build_number: 101
+ sha256: f64e357aa0168a201c9b3eedf500d89a8550d6631d26a95590b12de61f8fd660
+ md5: 030ec23658b941438ac42303aff0db2b
+ depends:
+ - __osx >=10.13
+ - bzip2 >=1.0.8,<2.0a0
+ - libexpat >=2.7.3,<3.0a0
+ - libffi >=3.5.2,<3.6.0a0
+ - liblzma >=5.8.2,<6.0a0
+ - libmpdec >=4.0.0,<5.0a0
+ - libsqlite >=3.51.2,<4.0a0
+ - libzlib >=1.3.1,<2.0a0
+ - ncurses >=6.5,<7.0a0
+ - openssl >=3.5.5,<4.0a0
+ - python_abi 3.14.* *_cp314
+ - readline >=8.3,<9.0a0
+ - tk >=8.6.13,<8.7.0a0
+ - tzdata
+ - zstd >=1.5.7,<1.6.0a0
+ license: Python-2.0
+ purls: []
+ size: 14387288
+ timestamp: 1770676578632
+ python_site_packages_path: lib/python3.14/site-packages
+- conda: https://conda.anaconda.org/conda-forge/osx-arm64/python-3.10.14-h2469fbe_0_cpython.conda
+ sha256: 454d609fe25daedce9e886efcbfcadad103ed0362e7cb6d2bcddec90b1ecd3ee
+ md5: 4ae999c8227c6d8c7623d32d51d25ea9
+ depends:
+ - bzip2 >=1.0.8,<2.0a0
+ - libffi >=3.4,<4.0a0
+ - libsqlite >=3.45.2,<4.0a0
+ - libzlib >=1.2.13,<2.0.0a0
+ - ncurses >=6.4.20240210,<7.0a0
+ - openssl >=3.2.1,<4.0a0
+ - readline >=8.2,<9.0a0
+ - tk >=8.6.13,<8.7.0a0
+ - tzdata
+ - xz >=5.2.6,<6.0a0
+ constrains:
+ - python_abi 3.10.* *_cp310
+ license: Python-2.0
+ purls: []
+ size: 12336005
+ timestamp: 1710939659384
+- conda: https://conda.anaconda.org/conda-forge/osx-arm64/python-3.11.8-hdf0ec26_0_cpython.conda
+ sha256: 6c9bbac137759e013e6a50593c7cf10a06032fcb1ef3a994c598c7a95e73a8e1
+ md5: 8f4076d960f17f19ae8b2f66727ea1c6
+ depends:
+ - bzip2 >=1.0.8,<2.0a0
+ - libexpat >=2.5.0,<3.0a0
+ - libffi >=3.4,<4.0a0
+ - libsqlite >=3.45.1,<4.0a0
+ - libzlib >=1.2.13,<2.0.0a0
+ - ncurses >=6.4,<7.0a0
+ - openssl >=3.2.1,<4.0a0
+ - readline >=8.2,<9.0a0
+ - tk >=8.6.13,<8.7.0a0
+ - tzdata
+ - xz >=5.2.6,<6.0a0
+ constrains:
+ - python_abi 3.11.* *_cp311
+ license: Python-2.0
+ purls: []
+ size: 14623079
+ timestamp: 1708116925163
+- conda: https://conda.anaconda.org/conda-forge/osx-arm64/python-3.14.3-h4c637c5_101_cp314.conda
+ build_number: 101
+ sha256: fccce2af62d11328d232df9f6bbf63464fd45f81f718c661757f9c628c4378ce
+ md5: 753c8d0447677acb7ddbcc6e03e82661
+ depends:
+ - __osx >=11.0
+ - bzip2 >=1.0.8,<2.0a0
+ - libexpat >=2.7.3,<3.0a0
+ - libffi >=3.5.2,<3.6.0a0
+ - liblzma >=5.8.2,<6.0a0
+ - libmpdec >=4.0.0,<5.0a0
+ - libsqlite >=3.51.2,<4.0a0
+ - libzlib >=1.3.1,<2.0a0
+ - ncurses >=6.5,<7.0a0
+ - openssl >=3.5.5,<4.0a0
+ - python_abi 3.14.* *_cp314
+ - readline >=8.3,<9.0a0
+ - tk >=8.6.13,<8.7.0a0
+ - tzdata
+ - zstd >=1.5.7,<1.6.0a0
+ license: Python-2.0
+ purls: []
+ size: 13522698
+ timestamp: 1770675365241
+ python_site_packages_path: lib/python3.14/site-packages
+- conda: https://conda.anaconda.org/conda-forge/win-64/python-3.10.20-hc20f281_0_cpython.conda
+ sha256: e71595dd281a9902d7b84f545f16d7d4c0fb62cc6816431301f8f4870c94dc8c
+ md5: 6c18c24d33a7ac8a4f81c68b8eb8581b
+ depends:
+ - bzip2 >=1.0.8,<2.0a0
+ - libexpat >=2.7.4,<3.0a0
+ - libffi >=3.4,<4.0a0
+ - liblzma >=5.8.2,<6.0a0
+ - libsqlite >=3.51.2,<4.0a0
+ - libzlib >=1.3.1,<2.0a0
+ - openssl >=3.5.5,<4.0a0
+ - tk >=8.6.13,<8.7.0a0
+ - tzdata
+ - ucrt >=10.0.20348.0
+ - vc >=14.3,<15
+ - vc14_runtime >=14.44.35208
+ constrains:
+ - python_abi 3.10.* *_cp310
+ license: Python-2.0
+ purls: []
+ size: 16028082
+ timestamp: 1772728853200
+- conda: https://conda.anaconda.org/conda-forge/win-64/python-3.11.15-h0159041_0_cpython.conda
+ sha256: a1f1031088ce69bc99c82b95980c1f54e16cbd5c21f042e9c1ea25745a8fc813
+ md5: d09dbf470b41bca48cbe6a78ba1e009b
+ depends:
+ - bzip2 >=1.0.8,<2.0a0
+ - libexpat >=2.7.4,<3.0a0
+ - libffi >=3.5.2,<3.6.0a0
+ - liblzma >=5.8.2,<6.0a0
+ - libsqlite >=3.51.2,<4.0a0
+ - libzlib >=1.3.1,<2.0a0
+ - openssl >=3.5.5,<4.0a0
+ - tk >=8.6.13,<8.7.0a0
+ - tzdata
+ - ucrt >=10.0.20348.0
+ - vc >=14.3,<15
+ - vc14_runtime >=14.44.35208
+ constrains:
+ - python_abi 3.11.* *_cp311
+ license: Python-2.0
+ purls: []
+ size: 18416208
+ timestamp: 1772728847666
+- conda: https://conda.anaconda.org/conda-forge/win-64/python-3.14.3-h4b44e0e_101_cp314.conda
+ build_number: 101
+ sha256: 3f99d83bfd95b9bdae64a42a1e4bf5131dc20b724be5ac8a9a7e1ac2c0f006d7
+ md5: 7ec2be7eaf59f83f3e5617665f3fbb2e
+ depends:
+ - bzip2 >=1.0.8,<2.0a0
+ - libexpat >=2.7.3,<3.0a0
+ - libffi >=3.5.2,<3.6.0a0
+ - liblzma >=5.8.2,<6.0a0
+ - libmpdec >=4.0.0,<5.0a0
+ - libsqlite >=3.51.2,<4.0a0
+ - libzlib >=1.3.1,<2.0a0
+ - openssl >=3.5.5,<4.0a0
+ - python_abi 3.14.* *_cp314
+ - tk >=8.6.13,<8.7.0a0
+ - tzdata
+ - ucrt >=10.0.20348.0
+ - vc >=14.3,<15
+ - vc14_runtime >=14.44.35208
+ - zstd >=1.5.7,<1.6.0a0
+ license: Python-2.0
+ purls: []
+ size: 18273230
+ timestamp: 1770675442998
+ python_site_packages_path: Lib/site-packages
+- conda: https://conda.anaconda.org/conda-forge/noarch/python-discovery-1.2.1-pyhcf101f3_0.conda
+ sha256: 5a70a9cbcf48be522c2b82df8c7a57988eed776f159142b0d30099b61f31a35e
+ md5: f2e88fc463b249bc1f40d9ca969d9b5e
+ depends:
+ - python >=3.10
+ - filelock >=3.15.4
+ - platformdirs <5,>=4.3.6
+ - python
+ license: MIT
+ purls:
+ - pkg:pypi/python-discovery?source=compressed-mapping
+ size: 34137
+ timestamp: 1774605818480
+- conda: https://conda.anaconda.org/conda-forge/noarch/python_abi-3.10-8_cp310.conda
+ build_number: 8
+ sha256: 7ad76fa396e4bde336872350124c0819032a9e8a0a40590744ff9527b54351c1
+ md5: 05e00f3b21e88bb3d658ac700b2ce58c
+ constrains:
+ - python 3.10.* *_cpython
+ license: BSD-3-Clause
+ license_family: BSD
+ purls: []
+ size: 6999
+ timestamp: 1752805924192
+- conda: https://conda.anaconda.org/conda-forge/noarch/python_abi-3.11-8_cp311.conda
+ build_number: 8
+ sha256: fddf123692aa4b1fc48f0471e346400d9852d96eeed77dbfdd746fa50a8ff894
+ md5: 8fcb6b0e2161850556231336dae58358
+ constrains:
+ - python 3.11.* *_cpython
+ license: BSD-3-Clause
+ license_family: BSD
+ purls: []
+ size: 7003
+ timestamp: 1752805919375
+- conda: https://conda.anaconda.org/conda-forge/noarch/python_abi-3.14-8_cp314.conda
+ build_number: 8
+ sha256: ad6d2e9ac39751cc0529dd1566a26751a0bf2542adb0c232533d32e176e21db5
+ md5: 0539938c55b6b1a59b560e843ad864a4
+ constrains:
+ - python 3.14.* *_cp314
+ license: BSD-3-Clause
+ license_family: BSD
+ purls: []
+ size: 6989
+ timestamp: 1752805904792
+- pypi: https://files.pythonhosted.org/packages/de/3d/8161f7711c017e01ac9f008dfddd9410dff3674334c233bde66e7ba65bbf/pywin32_ctypes-0.2.3-py3-none-any.whl
+ name: pywin32-ctypes
+ version: 0.2.3
+ sha256: 8a1513379d709975552d202d942d9837758905c8d01eb82b8bcc30918929e7b8
+ requires_python: '>=3.6'
+- conda: https://conda.anaconda.org/conda-forge/linux-64/pyyaml-6.0.3-py310h3406613_1.conda
+ sha256: f23de6cc72541c6081d3d27482dbc9fc5dd03be93126d9155f06d0cf15d6e90e
+ md5: 2160894f57a40d2d629a34ee8497795f
+ depends:
+ - __glibc >=2.17,<3.0.a0
+ - libgcc >=14
+ - python >=3.10,<3.11.0a0
+ - python_abi 3.10.* *_cp310
+ - yaml >=0.2.5,<0.3.0a0
+ license: MIT
+ license_family: MIT
+ purls:
+ - pkg:pypi/pyyaml?source=hash-mapping
+ size: 176522
+ timestamp: 1770223379599
+- conda: https://conda.anaconda.org/conda-forge/linux-64/pyyaml-6.0.3-py311h3778330_1.conda
+ sha256: c9a6cd2c290d7c3d2b30ea34a0ccda30f770e8ddb2937871f2c404faf60d0050
+ md5: a24add9a3bababee946f3bc1c829acfe
+ depends:
+ - __glibc >=2.17,<3.0.a0
+ - libgcc >=14
+ - python >=3.11,<3.12.0a0
+ - python_abi 3.11.* *_cp311
+ - yaml >=0.2.5,<0.3.0a0
+ license: MIT
+ license_family: MIT
+ purls:
+ - pkg:pypi/pyyaml?source=compressed-mapping
+ size: 206190
+ timestamp: 1770223702917
+- conda: https://conda.anaconda.org/conda-forge/linux-64/pyyaml-6.0.3-py314h67df5f8_1.conda
+ sha256: b318fb070c7a1f89980ef124b80a0b5ccf3928143708a85e0053cde0169c699d
+ md5: 2035f68f96be30dc60a5dfd7452c7941
+ depends:
+ - __glibc >=2.17,<3.0.a0
+ - libgcc >=14
+ - python >=3.14,<3.15.0a0
+ - python_abi 3.14.* *_cp314
+ - yaml >=0.2.5,<0.3.0a0
+ license: MIT
+ license_family: MIT
+ purls:
+ - pkg:pypi/pyyaml?source=compressed-mapping
+ size: 202391
+ timestamp: 1770223462836
+- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/pyyaml-6.0.3-py310h2d8da20_1.conda
+ sha256: 8acefeb5cc4bcf835f33e45b5cc8b350e738b4954f68c3d8051426e851ca2806
+ md5: 7e1a74e779e08e3504230f8216be618b
+ depends:
+ - libgcc >=14
+ - python >=3.10,<3.11.0a0
+ - python >=3.10,<3.11.0a0 *_cpython
+ - python_abi 3.10.* *_cp310
+ - yaml >=0.2.5,<0.3.0a0
+ license: MIT
+ license_family: MIT
+ purls:
+ - pkg:pypi/pyyaml?source=hash-mapping
+ size: 171618
+ timestamp: 1770223419125
+- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/pyyaml-6.0.3-py311h164a683_1.conda
+ sha256: e3175f507827cd575b5a7b7b50058cd253977f8286079cb3a6bf0aeaa878071b
+ md5: 7e1888f50cc191b7817848dbf6f90590
+ depends:
+ - libgcc >=14
+ - python >=3.11,<3.12.0a0
+ - python >=3.11,<3.12.0a0 *_cpython
+ - python_abi 3.11.* *_cp311
+ - yaml >=0.2.5,<0.3.0a0
+ license: MIT
+ license_family: MIT
+ purls:
+ - pkg:pypi/pyyaml?source=hash-mapping
+ size: 201473
+ timestamp: 1770223445971
+- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/pyyaml-6.0.3-py314h807365f_1.conda
+ sha256: 496b5e65dfdd0aaaaa5de0dcaaf3bceea00fcb4398acf152f89e567c82ec1046
+ md5: 9ae2c92975118058bd720e9ba2bb7c58
+ depends:
+ - libgcc >=14
+ - python >=3.14,<3.15.0a0
+ - python >=3.14,<3.15.0a0 *_cp314
+ - python_abi 3.14.* *_cp314
+ - yaml >=0.2.5,<0.3.0a0
+ license: MIT
+ license_family: MIT
+ purls:
+ - pkg:pypi/pyyaml?source=hash-mapping
+ size: 195678
+ timestamp: 1770223441816
+- conda: https://conda.anaconda.org/conda-forge/osx-64/pyyaml-6.0.1-py310h6729b98_1.conda
+ sha256: 00567f2cb2d1c8fede8fe7727f7bbd1c38cbca886814d612e162d5c936d8db1b
+ md5: d964cec3e7972e44bc4a328134b9eaf1
+ depends:
+ - python >=3.10,<3.11.0a0
+ - python_abi 3.10.* *_cp310
+ - yaml >=0.2.5,<0.3.0a0
+ license: MIT
+ license_family: MIT
+ purls:
+ - pkg:pypi/pyyaml?source=hash-mapping
+ size: 160097
+ timestamp: 1695373947773
+- conda: https://conda.anaconda.org/conda-forge/osx-64/pyyaml-6.0.1-py311h2725bcf_1.conda
+ sha256: 8ce2ba443414170a2570514d0ce6d03625a847e91af9763d48dc58c338e6f7f3
+ md5: 9283f991b5e5856a99f8aabba9927df5
+ depends:
+ - python >=3.11,<3.12.0a0
+ - python_abi 3.11.* *_cp311
+ - yaml >=0.2.5,<0.3.0a0
+ license: MIT
+ license_family: MIT
+ purls:
+ - pkg:pypi/pyyaml?source=hash-mapping
+ size: 188606
+ timestamp: 1695373840022
+- conda: https://conda.anaconda.org/conda-forge/osx-64/pyyaml-6.0.3-py314h10d0514_1.conda
+ sha256: aef010899d642b24de6ccda3bc49ef008f8fddf7bad15ebce9bdebeae19a4599
+ md5: ebd224b733573c50d2bfbeacb5449417
+ depends:
+ - __osx >=10.13
+ - python >=3.14,<3.15.0a0
+ - python_abi 3.14.* *_cp314
+ - yaml >=0.2.5,<0.3.0a0
+ license: MIT
+ license_family: MIT
+ purls:
+ - pkg:pypi/pyyaml?source=hash-mapping
+ size: 191947
+ timestamp: 1770226344240
+- conda: https://conda.anaconda.org/conda-forge/osx-arm64/pyyaml-6.0.1-py310h2aa6e3c_1.conda
+ sha256: 7b8668cd86d2421c62ec241f840d84a600b854afc91383a509bbb60ba907aeec
+ md5: 0e7ccdd121ce7b486f1de7917178387c
+ depends:
+ - python >=3.10,<3.11.0a0
+ - python >=3.10,<3.11.0a0 *_cpython
+ - python_abi 3.10.* *_cp310
+ - yaml >=0.2.5,<0.3.0a0
+ license: MIT
+ license_family: MIT
+ purls:
+ - pkg:pypi/pyyaml?source=hash-mapping
+ size: 158641
+ timestamp: 1695373859696
+- conda: https://conda.anaconda.org/conda-forge/osx-arm64/pyyaml-6.0.1-py311heffc1b2_1.conda
+ sha256: b155f5c27f0e2951256774628c4b91fdeee3267018eef29897a74e3d1316c8b0
+ md5: d310bfbb8230b9175c0cbc10189ad804
+ depends:
+ - python >=3.11,<3.12.0a0
+ - python >=3.11,<3.12.0a0 *_cpython
+ - python_abi 3.11.* *_cp311
+ - yaml >=0.2.5,<0.3.0a0
+ license: MIT
+ license_family: MIT
+ purls:
+ - pkg:pypi/pyyaml?source=hash-mapping
+ size: 187795
+ timestamp: 1695373829282
+- conda: https://conda.anaconda.org/conda-forge/osx-arm64/pyyaml-6.0.3-py314h6e9b3f0_1.conda
+ sha256: 95f385f9606e30137cf0b5295f63855fd22223a4cf024d306cf9098ea1c4a252
+ md5: dcf51e564317816cb8d546891019b3ab
+ depends:
+ - __osx >=11.0
+ - python >=3.14,<3.15.0a0
+ - python >=3.14,<3.15.0a0 *_cp314
+ - python_abi 3.14.* *_cp314
+ - yaml >=0.2.5,<0.3.0a0
+ license: MIT
+ license_family: MIT
+ purls:
+ - pkg:pypi/pyyaml?source=hash-mapping
+ size: 189475
+ timestamp: 1770223788648
+- conda: https://conda.anaconda.org/conda-forge/win-64/pyyaml-6.0.3-py310hdb0e946_1.conda
+ sha256: 3b643534d7b029073fd0ec1548a032854bb45391bc51dfdf9fec8d327e9f688d
+ md5: 463566b14434383e34e366143808b4b7
+ depends:
+ - python >=3.10,<3.11.0a0
+ - python_abi 3.10.* *_cp310
+ - ucrt >=10.0.20348.0
+ - vc >=14.3,<15
+ - vc14_runtime >=14.44.35208
+ - yaml >=0.2.5,<0.3.0a0
+ license: MIT
+ license_family: MIT
+ purls:
+ - pkg:pypi/pyyaml?source=hash-mapping
+ size: 157282
+ timestamp: 1770223476842
+- conda: https://conda.anaconda.org/conda-forge/win-64/pyyaml-6.0.3-py311h3f79411_1.conda
+ sha256: 301c3ba100d25cd5ae37895988ee3ab986210d4d972aa58efed948fbe857773d
+ md5: a0153c033dc55203e11d1cac8f6a9cf2
+ depends:
+ - python >=3.11,<3.12.0a0
+ - python_abi 3.11.* *_cp311
+ - ucrt >=10.0.20348.0
+ - vc >=14.3,<15
+ - vc14_runtime >=14.44.35208
+ - yaml >=0.2.5,<0.3.0a0
+ license: MIT
+ license_family: MIT
+ purls:
+ - pkg:pypi/pyyaml?source=hash-mapping
+ size: 187108
+ timestamp: 1770223467913
+- conda: https://conda.anaconda.org/conda-forge/win-64/pyyaml-6.0.3-py314h2359020_1.conda
+ sha256: a2aff34027aa810ff36a190b75002d2ff6f9fbef71ec66e567616ac3a679d997
+ md5: 0cd9b88826d0f8db142071eb830bce56
+ depends:
+ - python >=3.14,<3.15.0a0
+ - python_abi 3.14.* *_cp314
+ - ucrt >=10.0.20348.0
+ - vc >=14.3,<15
+ - vc14_runtime >=14.44.35208
+ - yaml >=0.2.5,<0.3.0a0
+ license: MIT
+ license_family: MIT
+ purls:
+ - pkg:pypi/pyyaml?source=compressed-mapping
+ size: 181257
+ timestamp: 1770223460931
+- conda: https://conda.anaconda.org/conda-forge/linux-64/readline-8.3-h853b02a_0.conda
+ sha256: 12ffde5a6f958e285aa22c191ca01bbd3d6e710aa852e00618fa6ddc59149002
+ md5: d7d95fc8287ea7bf33e0e7116d2b95ec
+ depends:
+ - __glibc >=2.17,<3.0.a0
+ - libgcc >=14
+ - ncurses >=6.5,<7.0a0
+ license: GPL-3.0-only
+ license_family: GPL
+ purls: []
+ size: 345073
+ timestamp: 1765813471974
+- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/readline-8.3-hb682ff5_0.conda
+ sha256: fe695f9d215e9a2e3dd0ca7f56435ab4df24f5504b83865e3d295df36e88d216
+ md5: 3d49cad61f829f4f0e0611547a9cda12
+ depends:
+ - libgcc >=14
+ - ncurses >=6.5,<7.0a0
+ license: GPL-3.0-only
+ license_family: GPL
+ purls: []
+ size: 357597
+ timestamp: 1765815673644
+- conda: https://conda.anaconda.org/conda-forge/osx-64/readline-8.2-h7cca4af_2.conda
+ sha256: 53017e80453c4c1d97aaf78369040418dea14cf8f46a2fa999f31bd70b36c877
+ md5: 342570f8e02f2f022147a7f841475784
+ depends:
+ - ncurses >=6.5,<7.0a0
+ license: GPL-3.0-only
+ license_family: GPL
+ purls: []
+ size: 256712
+ timestamp: 1740379577668
+- conda: https://conda.anaconda.org/conda-forge/osx-64/readline-8.3-h68b038d_0.conda
+ sha256: 4614af680aa0920e82b953fece85a03007e0719c3399f13d7de64176874b80d5
+ md5: eefd65452dfe7cce476a519bece46704
+ depends:
+ - __osx >=10.13
+ - ncurses >=6.5,<7.0a0
+ license: GPL-3.0-only
+ license_family: GPL
+ purls: []
+ size: 317819
+ timestamp: 1765813692798
+- conda: https://conda.anaconda.org/conda-forge/osx-arm64/readline-8.2-h1d1bf99_2.conda
+ sha256: 7db04684d3904f6151eff8673270922d31da1eea7fa73254d01c437f49702e34
+ md5: 63ef3f6e6d6d5c589e64f11263dc5676
+ depends:
+ - ncurses >=6.5,<7.0a0
+ license: GPL-3.0-only
+ license_family: GPL
+ purls: []
+ size: 252359
+ timestamp: 1740379663071
+- conda: https://conda.anaconda.org/conda-forge/osx-arm64/readline-8.3-h46df422_0.conda
+ sha256: a77010528efb4b548ac2a4484eaf7e1c3907f2aec86123ed9c5212ae44502477
+ md5: f8381319127120ce51e081dce4865cf4
+ depends:
+ - __osx >=11.0
+ - ncurses >=6.5,<7.0a0
+ license: GPL-3.0-only
+ license_family: GPL
+ purls: []
+ size: 313930
+ timestamp: 1765813902568
+- pypi: https://files.pythonhosted.org/packages/e1/67/921ec3024056483db83953ae8e48079ad62b92db7880013ca77632921dd0/readme_renderer-44.0-py3-none-any.whl
+ name: readme-renderer
+ version: '44.0'
+ sha256: 2fbca89b81a08526aadf1357a8c2ae889ec05fb03f5da67f9769c9a592166151
+ requires_dist:
+ - nh3>=0.2.14
+ - docutils>=0.21.2
+ - pygments>=2.5.1
+ - cmarkgfm>=0.8.0 ; extra == 'md'
+ requires_python: '>=3.9'
+- conda: https://conda.anaconda.org/conda-forge/linux-64/reproc-14.2.5.post0-hb9d3cd8_0.conda
+ sha256: a1973f41a6b956f1305f9aaefdf14b2f35a8c9615cfe5f143f1784ed9aa6bf47
+ md5: 69fbc0a9e42eb5fe6733d2d60d818822
+ depends:
+ - __glibc >=2.17,<3.0.a0
+ - libgcc >=13
+ license: MIT
+ license_family: MIT
+ purls: []
+ size: 34194
+ timestamp: 1731925834928
+- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/reproc-14.2.5.post0-h86ecc28_0.conda
+ sha256: 3bbcfd61da8ab71c0b7b5bbff471669f64e6a3fb759411a46a2d4fd31a9642cc
+ md5: 70b14ba118c2c19b240a39577b3e607a
+ depends:
+ - libgcc >=13
+ license: MIT
+ license_family: MIT
+ purls: []
+ size: 36102
+ timestamp: 1745309589538
+- conda: https://conda.anaconda.org/conda-forge/osx-64/reproc-14.2.5.post0-h6e16a3a_0.conda
+ sha256: dda2a8bc1bf16b563b74c2a01dccea657bda573b0c45e708bfeee01c208bcbaf
+ md5: eda18d4a7dce3831016086a482965345
+ depends:
+ - __osx >=10.13
+ license: MIT
+ license_family: MIT
+ purls: []
+ size: 31749
+ timestamp: 1731926270954
+- conda: https://conda.anaconda.org/conda-forge/osx-arm64/reproc-14.2.5.post0-h5505292_0.conda
+ sha256: a5f0dbfa8099a3d3c281ea21932b6359775fd8ce89acc53877a6ee06f50642bc
+ md5: f1d129089830365d9dac932c4dd8c675
+ depends:
+ - __osx >=11.0
+ license: MIT
+ license_family: MIT
+ purls: []
+ size: 32023
+ timestamp: 1731926255834
+- conda: https://conda.anaconda.org/conda-forge/win-64/reproc-14.2.5.post0-h2466b09_0.conda
+ sha256: 112dee79da4f55de91f029dd9808f4284bc5e0cf0c4d308d4cec3381bf5bc836
+ md5: c3ca4c18c99a3b9832e11b11af227713
+ depends:
+ - ucrt >=10.0.20348.0
+ - vc >=14.2,<15
+ - vc14_runtime >=14.29.30139
+ license: MIT
+ license_family: MIT
+ purls: []
+ size: 37058
+ timestamp: 1731926140985
+- conda: https://conda.anaconda.org/conda-forge/linux-64/reproc-cpp-14.2.5.post0-h5888daf_0.conda
+ sha256: 568485837b905b1ea7bdb6e6496d914b83db57feda57f6050d5a694977478691
+ md5: 828302fca535f9cfeb598d5f7c204323
+ depends:
+ - __glibc >=2.17,<3.0.a0
+ - libgcc >=13
+ - libstdcxx >=13
+ - reproc 14.2.5.post0 hb9d3cd8_0
+ license: MIT
+ license_family: MIT
+ purls: []
+ size: 25665
+ timestamp: 1731925852714
+- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/reproc-cpp-14.2.5.post0-h5ad3122_0.conda
+ sha256: 57831399b5c2ccc4a2ec4fad4ec70609ddc0e7098a1d8cca62e063860fd1674b
+ md5: fde98968589573ad478b504642319105
+ depends:
+ - libgcc >=13
+ - libstdcxx >=13
+ - reproc 14.2.5.post0 h86ecc28_0
+ license: MIT
+ license_family: MIT
+ purls: []
+ size: 26291
+ timestamp: 1745309832653
+- conda: https://conda.anaconda.org/conda-forge/osx-64/reproc-cpp-14.2.5.post0-h240833e_0.conda
+ sha256: 4d8638b7f44082302c7687c99079789f42068d34cddc0959c11ad5d28aab3d47
+ md5: 420229341978751bd96faeced92c200e
+ depends:
+ - __osx >=10.13
+ - libcxx >=18
+ - reproc 14.2.5.post0 h6e16a3a_0
+ license: MIT
+ license_family: MIT
+ purls: []
+ size: 24394
+ timestamp: 1731926392643
+- conda: https://conda.anaconda.org/conda-forge/osx-arm64/reproc-cpp-14.2.5.post0-h286801f_0.conda
+ sha256: f1b6aa9d9131ea159a5883bc5990b91b4b8f56eb52e0dc2b01aa9622e14edc81
+ md5: 11a3d09937d250fc4423bf28837d9363
+ depends:
+ - __osx >=11.0
+ - libcxx >=18
+ - reproc 14.2.5.post0 h5505292_0
+ license: MIT
+ license_family: MIT
+ purls: []
+ size: 24834
+ timestamp: 1731926355120
+- conda: https://conda.anaconda.org/conda-forge/win-64/reproc-cpp-14.2.5.post0-he0c23c2_0.conda
+ sha256: ccf49fb5149298015ab410aae88e43600954206608089f0dfb7aea8b771bbe8e
+ md5: d2ce31fa746dddeb37f24f32da0969e9
+ depends:
+ - reproc 14.2.5.post0 h2466b09_0
+ - ucrt >=10.0.20348.0
+ - vc >=14.2,<15
+ - vc14_runtime >=14.29.30139
+ license: MIT
+ license_family: MIT
+ purls: []
+ size: 30096
+ timestamp: 1731926177599
+- conda: https://conda.anaconda.org/conda-forge/noarch/requests-2.32.5-pyhcf101f3_1.conda
+ sha256: 7813c38b79ae549504b2c57b3f33394cea4f2ad083f0994d2045c2e24cb538c5
+ md5: c65df89a0b2e321045a9e01d1337b182
+ depends:
+ - python >=3.10
+ - certifi >=2017.4.17
+ - charset-normalizer >=2,<4
+ - idna >=2.5,<4
+ - urllib3 >=1.21.1,<3
+ - python
+ constrains:
+ - chardet >=3.0.2,<6
+ license: Apache-2.0
+ license_family: APACHE
+ purls:
+ - pkg:pypi/requests?source=compressed-mapping
+ size: 63602
+ timestamp: 1766926974520
+- conda: https://conda.anaconda.org/conda-forge/noarch/requests-2.33.1-pyhcf101f3_0.conda
+ sha256: c0249bc4bf4c0e8e06d0e7b4d117a5d593cc4ab2144d5006d6d47c83cb0af18e
+ md5: 10afbb4dbf06ff959ad25a92ccee6e59
+ depends:
+ - python >=3.10
+ - certifi >=2023.5.7
+ - charset-normalizer >=2,<4
+ - idna >=2.5,<4
+ - urllib3 >=1.26,<3
+ - python
+ constrains:
+ - chardet >=3.0.2,<6
+ license: Apache-2.0
+ license_family: APACHE
+ purls:
+ - pkg:pypi/requests?source=compressed-mapping
+ size: 63712
+ timestamp: 1774894783063
+- pypi: https://files.pythonhosted.org/packages/3f/51/d4db610ef29373b879047326cbf6fa98b6c1969d6f6dc423279de2b1be2c/requests_toolbelt-1.0.0-py2.py3-none-any.whl
+ name: requests-toolbelt
+ version: 1.0.0
+ sha256: cccfdd665f0a24fcf4726e690f65639d272bb0637b9b92dfd91a5568ccf6bd06
+ requires_dist:
+ - requests>=2.0.1,<3.0.0
+ requires_python: '>=2.7,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*'
+- pypi: https://files.pythonhosted.org/packages/ff/9a/9afaade874b2fa6c752c36f1548f718b5b83af81ed9b76628329dab81c1b/rfc3986-2.0.0-py2.py3-none-any.whl
+ name: rfc3986
+ version: 2.0.0
+ sha256: 50b1502b60e289cb37883f3dfd34532b8873c7de9f49bb546641ce9cbd256ebd
+ requires_dist:
+ - idna ; extra == 'idna2008'
+ requires_python: '>=3.7'
+- conda: https://conda.anaconda.org/conda-forge/linux-64/rhash-1.4.6-hb9d3cd8_1.conda
+ sha256: d5c73079c1dd2c2a313c3bfd81c73dbd066b7eb08d213778c8bff520091ae894
+ md5: c1c9b02933fdb2cfb791d936c20e887e
+ depends:
+ - __glibc >=2.17,<3.0.a0
+ - libgcc >=13
+ license: MIT
+ license_family: MIT
+ purls: []
+ size: 193775
+ timestamp: 1748644872902
+- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/rhash-1.4.6-h86ecc28_1.conda
+ sha256: 0fe6f40213f2d8af4fcb7388eeb782a4e496c8bab32c189c3a34b37e8004e5a4
+ md5: 745d02c0c22ea2f28fbda2cb5dbec189
+ depends:
+ - libgcc >=13
+ license: MIT
+ license_family: MIT
+ purls: []
+ size: 207475
+ timestamp: 1748644952027
+- conda: https://conda.anaconda.org/conda-forge/osx-64/rhash-1.4.4-h0dc2134_0.conda
+ sha256: f1ae47e8c4e46f856faf5d8ee1e5291f55627aa93401b61a877f18ade5780c87
+ md5: 55a2ada70c8a208c01f77978f2783121
+ license: MIT
+ license_family: MIT
+ purls: []
+ size: 177229
+ timestamp: 1693456080514
+- conda: https://conda.anaconda.org/conda-forge/osx-arm64/rhash-1.4.4-hb547adb_0.conda
+ sha256: 3ab595e2280ed2118b6b1e8ce7e5949da2047846c81b6af1bbf5ac859d062edd
+ md5: 710c4b1abf65b697c1d9716eba16dbb0
+ license: MIT
+ license_family: MIT
+ purls: []
+ size: 177491
+ timestamp: 1693456037505
+- pypi: https://files.pythonhosted.org/packages/14/25/b208c5683343959b670dc001595f2f3737e051da617f66c31f7c4fa93abc/rich-14.3.3-py3-none-any.whl
+ name: rich
+ version: 14.3.3
+ sha256: 793431c1f8619afa7d3b52b2cdec859562b950ea0d4b6b505397612db8d5362d
+ requires_dist:
+ - ipywidgets>=7.5.1,<9 ; extra == 'jupyter'
+ - markdown-it-py>=2.2.0
+ - pygments>=2.13.0,<3.0.0
+ requires_python: '>=3.8.0'
+- conda: https://conda.anaconda.org/conda-forge/linux-64/ruamel.yaml-0.18.17-py310h139afa4_2.conda
+ sha256: 0741675606a288ca70a68282d9b8b67b61cc6e991dcec38bae9ec1e38237524c
+ md5: 26ad912afb7835e474284d61f482905d
+ depends:
+ - python
+ - ruamel.yaml.clib >=0.2.15
+ - __glibc >=2.17,<3.0.a0
+ - libgcc >=14
+ - python_abi 3.10.* *_cp310
+ license: MIT
+ license_family: MIT
+ purls:
+ - pkg:pypi/ruamel-yaml?source=hash-mapping
+ size: 219162
+ timestamp: 1766175793325
+- conda: https://conda.anaconda.org/conda-forge/linux-64/ruamel.yaml-0.18.17-py311haee01d2_2.conda
+ sha256: 5324d0353c9cca813501ea9b20186f8e6835cd4ff6e4dfa897c5faeecce8cdaa
+ md5: 672395a7f912a9eda492959b7632ae6c
+ depends:
+ - python
+ - ruamel.yaml.clib >=0.2.15
+ - libgcc >=14
+ - __glibc >=2.17,<3.0.a0
+ - python_abi 3.11.* *_cp311
+ license: MIT
+ license_family: MIT
+ purls:
+ - pkg:pypi/ruamel-yaml?source=hash-mapping
+ size: 294535
+ timestamp: 1766175791754
+- conda: https://conda.anaconda.org/conda-forge/linux-64/ruamel.yaml-0.18.17-py314h0f05182_2.conda
+ sha256: 59f7773ed8c6f2bcab3e953e2b4816c86cf71e5508dc571f8073b8c2294b5787
+ md5: 8ea76c64b49b16c37769ea7c4dca993b
+ depends:
+ - python
+ - ruamel.yaml.clib >=0.2.15
+ - libgcc >=14
+ - __glibc >=2.17,<3.0.a0
+ - python_abi 3.14.* *_cp314
+ license: MIT
+ license_family: MIT
+ purls:
+ - pkg:pypi/ruamel-yaml?source=hash-mapping
+ size: 308487
+ timestamp: 1766175778417
+- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/ruamel.yaml-0.18.17-py310hef25091_2.conda
+ sha256: 4ba656144b8e56490f4dcec674310a4a7c411e43dfad8945c43c239c1faec898
+ md5: e867ca69a8d4866b05a363bfddad2250
+ depends:
+ - python
+ - ruamel.yaml.clib >=0.2.15
+ - libgcc >=14
+ - python 3.10.* *_cpython
+ - python_abi 3.10.* *_cp310
+ license: MIT
+ license_family: MIT
+ purls:
+ - pkg:pypi/ruamel-yaml?source=hash-mapping
+ size: 222819
+ timestamp: 1766175822103
+- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/ruamel.yaml-0.18.17-py311h51cfe5d_2.conda
+ sha256: b965d2023a41acbf76bd965e106835d19e6a26cd69c4e1d439df17471336226e
+ md5: ecf191a9fa6a518ca91aaa49e3c87584
+ depends:
+ - python
+ - ruamel.yaml.clib >=0.2.15
+ - libgcc >=14
+ - python 3.11.* *_cpython
+ - python_abi 3.11.* *_cp311
+ license: MIT
+ license_family: MIT
+ purls:
+ - pkg:pypi/ruamel-yaml?source=hash-mapping
+ size: 298156
+ timestamp: 1766175797018
+- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/ruamel.yaml-0.18.17-py314h2e8dab5_2.conda
+ sha256: baedba4fb0d0929ffcbebd001876c115d23c5620457eb9347cdac5978963c262
+ md5: 1f86e018331edc941dedc796c4373fe3
+ depends:
+ - python
+ - ruamel.yaml.clib >=0.2.15
+ - libgcc >=14
+ - python 3.14.* *_cp314
+ - python_abi 3.14.* *_cp314
+ license: MIT
+ license_family: MIT
+ purls:
+ - pkg:pypi/ruamel-yaml?source=hash-mapping
+ size: 311783
+ timestamp: 1766175823921
+- conda: https://conda.anaconda.org/conda-forge/osx-64/ruamel.yaml-0.17.40-py310hb372a2b_0.conda
+ sha256: a6f883e95ff6c0b48ecdc16113deae57961c24a3d9458ebabd489f61a9aae4d5
+ md5: 150037c34bc1cd6bbe69876c4e7347f4
+ depends:
+ - python >=3.10,<3.11.0a0
+ - python_abi 3.10.* *_cp310
+ - ruamel.yaml.clib >=0.1.2
+ - setuptools
+ license: MIT
+ license_family: MIT
+ purls:
+ - pkg:pypi/ruamel-yaml?source=hash-mapping
+ size: 200022
+ timestamp: 1698138926099
+- conda: https://conda.anaconda.org/conda-forge/osx-64/ruamel.yaml-0.17.40-py311he705e18_0.conda
+ sha256: 0260c295cdfae417f107fe2fae66bae4eb260195885d81d8b1cd4fc6d81c849b
+ md5: 4796cc1d45c88ace8f5bb7950167a568
+ depends:
+ - python >=3.11,<3.12.0a0
+ - python_abi 3.11.* *_cp311
+ - ruamel.yaml.clib >=0.1.2
+ - setuptools
+ license: MIT
+ license_family: MIT
+ purls:
+ - pkg:pypi/ruamel-yaml?source=hash-mapping
+ size: 277064
+ timestamp: 1698138918002
+- conda: https://conda.anaconda.org/conda-forge/osx-64/ruamel.yaml-0.18.17-py314hd330473_2.conda
+ sha256: 59edac475c2e53dda7802554aa8310b4214ef0a536841be4ab318e0b5b7563fc
+ md5: c64fb655de0ccaafb1d875f4fa1f0fc3
+ depends:
+ - python
+ - ruamel.yaml.clib >=0.2.15
+ - __osx >=10.13
+ - python_abi 3.14.* *_cp314
+ license: MIT
+ license_family: MIT
+ purls:
+ - pkg:pypi/ruamel-yaml?source=hash-mapping
+ size: 308947
+ timestamp: 1766175829662
+- conda: https://conda.anaconda.org/conda-forge/osx-arm64/ruamel.yaml-0.17.40-py310hd125d64_0.conda
+ sha256: efc0814c8d5b9e20d75a425f0a9c782e5642a4a349849fa95c8b5b2f1108f6c9
+ md5: 77e106fbe41acee97140e992dc52ad77
+ depends:
+ - python >=3.10,<3.11.0a0
+ - python >=3.10,<3.11.0a0 *_cpython
+ - python_abi 3.10.* *_cp310
+ - ruamel.yaml.clib >=0.1.2
+ - setuptools
+ license: MIT
+ license_family: MIT
+ purls:
+ - pkg:pypi/ruamel-yaml?source=hash-mapping
+ size: 200368
+ timestamp: 1698139000522
+- conda: https://conda.anaconda.org/conda-forge/osx-arm64/ruamel.yaml-0.17.40-py311h05b510d_0.conda
+ sha256: bf44774cbd03eb8d396a078b4af1b194f8600f8ca7ea7ca0e3d61dc16b400cb4
+ md5: 640b6933c680860877b32a4c11076ab9
+ depends:
+ - python >=3.11,<3.12.0a0
+ - python >=3.11,<3.12.0a0 *_cpython
+ - python_abi 3.11.* *_cp311
+ - ruamel.yaml.clib >=0.1.2
+ - setuptools
+ license: MIT
+ license_family: MIT
+ purls:
+ - pkg:pypi/ruamel-yaml?source=hash-mapping
+ size: 276178
+ timestamp: 1698139045095
+- conda: https://conda.anaconda.org/conda-forge/osx-arm64/ruamel.yaml-0.18.17-py314ha14b1ff_2.conda
+ sha256: 0f498e343be464219a99424260ff442144d0461a3a5eb30c9de6081af358b281
+ md5: 87fc3a204f105e7e61c60a72509cccbd
+ depends:
+ - python
+ - ruamel.yaml.clib >=0.2.15
+ - __osx >=11.0
+ - python 3.14.* *_cp314
+ - python_abi 3.14.* *_cp314
+ license: MIT
+ license_family: MIT
+ purls:
+ - pkg:pypi/ruamel-yaml?source=hash-mapping
+ size: 311922
+ timestamp: 1766175797575
+- conda: https://conda.anaconda.org/conda-forge/win-64/ruamel.yaml-0.18.17-py310h1637853_2.conda
+ sha256: cb42613022b37517a10064e399a9f5b929a02d6c8a135e84b248a69d39fc7a8a
+ md5: 20dfd23643ca21f251dfa6c6853c06c4
+ depends:
+ - python
+ - ruamel.yaml.clib >=0.2.15
+ - vc >=14.3,<15
+ - vc14_runtime >=14.44.35208
+ - ucrt >=10.0.20348.0
+ - python_abi 3.10.* *_cp310
+ license: MIT
+ license_family: MIT
+ purls:
+ - pkg:pypi/ruamel-yaml?source=hash-mapping
+ size: 217306
+ timestamp: 1766175806668
+- conda: https://conda.anaconda.org/conda-forge/win-64/ruamel.yaml-0.18.17-py311hf893f09_2.conda
+ sha256: 90f4058642a6badfe710b2d1b0dd8cd802485303a209e6591c3c77ed74f0c363
+ md5: a4d4fcbe5a1b6e5bae7cb5a1bac4919d
+ depends:
+ - python
+ - ruamel.yaml.clib >=0.2.15
+ - vc >=14.3,<15
+ - vc14_runtime >=14.44.35208
+ - ucrt >=10.0.20348.0
+ - python_abi 3.11.* *_cp311
+ license: MIT
+ license_family: MIT
+ purls:
+ - pkg:pypi/ruamel-yaml?source=hash-mapping
+ size: 292781
+ timestamp: 1766175809044
+- conda: https://conda.anaconda.org/conda-forge/win-64/ruamel.yaml-0.18.17-py314hc5dbbe4_2.conda
+ sha256: 62b73874b6c264a73e7904b33322128c4881c78dfe2fb9131becfbf84343ee2d
+ md5: 027ff6055e5c82ba4e085857f09302cb
+ depends:
+ - python
+ - ruamel.yaml.clib >=0.2.15
+ - vc >=14.3,<15
+ - vc14_runtime >=14.44.35208
+ - ucrt >=10.0.20348.0
+ - python_abi 3.14.* *_cp314
+ license: MIT
+ license_family: MIT
+ purls:
+ - pkg:pypi/ruamel-yaml?source=hash-mapping
+ size: 306951
+ timestamp: 1766175833786
+- conda: https://conda.anaconda.org/conda-forge/linux-64/ruamel.yaml.clib-0.2.15-py310h139afa4_1.conda
+ sha256: 242ff560883541acc447b4fb11f1c6c0a4e91479b70c8ce895aee5d9a8ce346a
+ md5: a7e3055859e9162d5f7adb9b3c229d56
+ depends:
+ - python
+ - __glibc >=2.17,<3.0.a0
+ - libgcc >=14
+ - python_abi 3.10.* *_cp310
+ license: MIT
+ license_family: MIT
+ purls:
+ - pkg:pypi/ruamel-yaml-clib?source=hash-mapping
+ size: 152839
+ timestamp: 1766159514181
+- conda: https://conda.anaconda.org/conda-forge/linux-64/ruamel.yaml.clib-0.2.15-py311haee01d2_1.conda
+ sha256: 2d7e8976b0542b7aae1a9e4383b7b1135e64e9e190ce394aed44983adc6eb3f2
+ md5: e3dfd8043a0fac038fe0d7c2d08ac28c
+ depends:
+ - python
+ - __glibc >=2.17,<3.0.a0
+ - libgcc >=14
+ - python_abi 3.11.* *_cp311
+ license: MIT
+ license_family: MIT
+ purls:
+ - pkg:pypi/ruamel-yaml-clib?source=hash-mapping
+ size: 153044
+ timestamp: 1766159530795
+- conda: https://conda.anaconda.org/conda-forge/linux-64/ruamel.yaml.clib-0.2.15-py314h0f05182_1.conda
+ sha256: 3bd8db7556e87c98933a47ff9f962af7b8e0dc3757a72180b27cbfcb1f98d2d9
+ md5: 4f35ae1228a6c5d9df593367ffe8dda1
+ depends:
+ - python
+ - libgcc >=14
+ - __glibc >=2.17,<3.0.a0
+ - python_abi 3.14.* *_cp314
+ license: MIT
+ license_family: MIT
+ purls:
+ - pkg:pypi/ruamel-yaml-clib?source=hash-mapping
+ size: 150041
+ timestamp: 1766159514023
+- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/ruamel.yaml.clib-0.2.15-py310hef25091_1.conda
+ sha256: fc5cf2db69fab279d0be46a8a077d9354991be5f4d317a73c453fc8df7c69f0a
+ md5: e91e48a36a6c9f761e259b967878831a
+ depends:
+ - python
+ - python 3.10.* *_cpython
+ - libgcc >=14
+ - python_abi 3.10.* *_cp310
+ license: MIT
+ license_family: MIT
+ purls:
+ - pkg:pypi/ruamel-yaml-clib?source=hash-mapping
+ size: 153169
+ timestamp: 1766159548278
+- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/ruamel.yaml.clib-0.2.15-py311h51cfe5d_1.conda
+ sha256: 77be521169904f2687cb09b6ab8d6bcee0d73d06284bfed84617668ad81c22f3
+ md5: 471b202396dfeb16adde1930cd7a8001
+ depends:
+ - python
+ - libgcc >=14
+ - python 3.11.* *_cpython
+ - python_abi 3.11.* *_cp311
+ license: MIT
+ license_family: MIT
+ purls:
+ - pkg:pypi/ruamel-yaml-clib?source=hash-mapping
+ size: 152961
+ timestamp: 1766159559428
+- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/ruamel.yaml.clib-0.2.15-py314h2e8dab5_1.conda
+ sha256: 18a34470b351fccfe6694215b01a9a68a0a9979336b0ea85709bbdeef0658e1c
+ md5: ca756356e2920f248a74cb42e0b4578d
+ depends:
+ - python
+ - python 3.14.* *_cp314
+ - libgcc >=14
+ - python_abi 3.14.* *_cp314
+ license: MIT
+ license_family: MIT
+ purls:
+ - pkg:pypi/ruamel-yaml-clib?source=hash-mapping
+ size: 148495
+ timestamp: 1766159541094
+- conda: https://conda.anaconda.org/conda-forge/osx-64/ruamel.yaml.clib-0.2.15-py314hd330473_1.conda
+ sha256: dbcc0ff6e902468314d10d9f59d289ad078e5eac02d72b9092fa96e88b91d5dd
+ md5: e41e8948899a09937c068f71fe65ebb6
+ depends:
+ - python
+ - __osx >=10.13
+ - python_abi 3.14.* *_cp314
+ license: MIT
+ license_family: MIT
+ purls:
+ - pkg:pypi/ruamel-yaml-clib?source=hash-mapping
+ size: 136902
+ timestamp: 1766159517466
+- conda: https://conda.anaconda.org/conda-forge/osx-64/ruamel.yaml.clib-0.2.8-py310hb372a2b_0.conda
+ sha256: 76535acf0bbefbbfeeca68bc732e4b8eea7526f0ef2090f2bdcf0283ec4b3738
+ md5: a6254db88b5bf45d4870c3a63dc39e8d
+ depends:
+ - python >=3.10,<3.11.0a0
+ - python_abi 3.10.* *_cp310
+ license: MIT
+ license_family: MIT
+ purls:
+ - pkg:pypi/ruamel-yaml-clib?source=hash-mapping
+ size: 118488
+ timestamp: 1707314814452
+- conda: https://conda.anaconda.org/conda-forge/osx-64/ruamel.yaml.clib-0.2.8-py311he705e18_0.conda
+ sha256: e6d5b2c9a75191305c8d367d13218c0bd0cc7a640ae776b541124c0fe8341bc9
+ md5: 3fdbde273667047893775e077cef290d
+ depends:
+ - python >=3.11,<3.12.0a0
+ - python_abi 3.11.* *_cp311
+ license: MIT
+ license_family: MIT
+ purls:
+ - pkg:pypi/ruamel-yaml-clib?source=hash-mapping
+ size: 117859
+ timestamp: 1707314957390
+- conda: https://conda.anaconda.org/conda-forge/osx-arm64/ruamel.yaml.clib-0.2.15-py314ha14b1ff_1.conda
+ sha256: ad575cae7f662b2dafca88c4ce05120e322f825c0610e54b0a116550c817bbbe
+ md5: 5836fbf79e5f279ffbe4ba06066c51a3
+ depends:
+ - python
+ - python 3.14.* *_cp314
+ - __osx >=11.0
+ - python_abi 3.14.* *_cp314
+ license: MIT
+ license_family: MIT
+ purls:
+ - pkg:pypi/ruamel-yaml-clib?source=hash-mapping
+ size: 133016
+ timestamp: 1766159585543
+- conda: https://conda.anaconda.org/conda-forge/osx-arm64/ruamel.yaml.clib-0.2.8-py310hd125d64_0.conda
+ sha256: 83b27f5dafd201a9408886ff18af6ccdde45e748c934fce588a4b531cdd249d5
+ md5: e0b9a24f19622386be17bf9f29674e81
+ depends:
+ - python >=3.10,<3.11.0a0
+ - python >=3.10,<3.11.0a0 *_cpython
+ - python_abi 3.10.* *_cp310
+ license: MIT
+ license_family: MIT
+ purls:
+ - pkg:pypi/ruamel-yaml-clib?source=hash-mapping
+ size: 111512
+ timestamp: 1707315215965
+- conda: https://conda.anaconda.org/conda-forge/osx-arm64/ruamel.yaml.clib-0.2.8-py311h05b510d_0.conda
+ sha256: 8b64d7ac6d544cdb1c5e3677c3a6ea10f1d87f818888b25df5f3b97f271ef14f
+ md5: 0fbb200e26cec1931d0337ee70422965
+ depends:
+ - python >=3.11,<3.12.0a0
+ - python >=3.11,<3.12.0a0 *_cpython
+ - python_abi 3.11.* *_cp311
+ license: MIT
+ license_family: MIT
+ purls:
+ - pkg:pypi/ruamel-yaml-clib?source=hash-mapping
+ size: 111700
+ timestamp: 1707315151942
+- conda: https://conda.anaconda.org/conda-forge/win-64/ruamel.yaml.clib-0.2.15-py310h1637853_1.conda
+ sha256: 3c2ba1f6757863affd1a2996cffcf63b2e13594300862cd38c9235b652a17ad7
+ md5: 07f6b7231ccb637d76e1550ababded60
+ depends:
+ - python
+ - vc >=14.3,<15
+ - vc14_runtime >=14.44.35208
+ - ucrt >=10.0.20348.0
+ - python_abi 3.10.* *_cp310
+ license: MIT
+ license_family: MIT
+ purls:
+ - pkg:pypi/ruamel-yaml-clib?source=hash-mapping
+ size: 107521
+ timestamp: 1766159541493
+- conda: https://conda.anaconda.org/conda-forge/win-64/ruamel.yaml.clib-0.2.15-py311hf893f09_1.conda
+ sha256: 5810ddd1efe4ac259ad0ff55778da71205a68edfbbb4d45488b270e7f2f23438
+ md5: 4bf8909dc04f6ab8c6d7f2a2a4a51d19
+ depends:
+ - python
+ - vc >=14.3,<15
+ - vc14_runtime >=14.44.35208
+ - ucrt >=10.0.20348.0
+ - python_abi 3.11.* *_cp311
+ license: MIT
+ license_family: MIT
+ purls:
+ - pkg:pypi/ruamel-yaml-clib?source=hash-mapping
+ size: 107529
+ timestamp: 1766159555820
+- conda: https://conda.anaconda.org/conda-forge/win-64/ruamel.yaml.clib-0.2.15-py314hc5dbbe4_1.conda
+ sha256: b719637ce71e533193cd2bcacbf6ba5c10deaafa1be90d96040ee2314c6b17d1
+ md5: 496de351b0f9afe9e245229528304f25
+ depends:
+ - python
+ - vc >=14.3,<15
+ - vc14_runtime >=14.44.35208
+ - ucrt >=10.0.20348.0
+ - python_abi 3.14.* *_cp314
+ license: MIT
+ license_family: MIT
+ purls:
+ - pkg:pypi/ruamel-yaml-clib?source=hash-mapping
+ size: 105668
+ timestamp: 1766159584330
+- conda: https://conda.anaconda.org/conda-forge/noarch/scikit-build-core-0.11.6-pyh7e86bf3_1.conda
+ sha256: bf802baa1a770c0ca631624a3627f84cae7978b56da02826b37ff1c5852a720a
+ md5: 4965b07e5cae94005cbe759e39f3def1
+ depends:
+ - typing_extensions >=3.10.0
+ - python >=3.8
+ - exceptiongroup >=1.0
+ - importlib-metadata >=4.13
+ - importlib-resources >=1.3
+ - packaging >=21.3
+ - pathspec >=0.10.1
+ - tomli >=1.2.2
+ - typing-extensions >=3.10
+ - python
+ license: Apache-2.0
+ license_family: APACHE
+ purls:
+ - pkg:pypi/scikit-build-core?source=hash-mapping
+ size: 213181
+ timestamp: 1755919500167
+- pypi: https://files.pythonhosted.org/packages/b7/46/f5af3402b579fd5e11573ce652019a67074317e18c1935cc0b4ba9b35552/secretstorage-3.5.0-py3-none-any.whl
+ name: secretstorage
+ version: 3.5.0
+ sha256: 0ce65888c0725fcb2c5bc0fdb8e5438eece02c523557ea40ce0703c266248137
+ requires_dist:
+ - cryptography>=2.0
+ - jeepney>=0.6
+ requires_python: '>=3.10'
+- conda: https://conda.anaconda.org/conda-forge/noarch/setuptools-82.0.1-pyh332efcf_0.conda
+ sha256: 82088a6e4daa33329a30bc26dc19a98c7c1d3f05c0f73ce9845d4eab4924e9e1
+ md5: 8e194e7b992f99a5015edbd4ebd38efd
+ depends:
+ - python >=3.10
+ license: MIT
+ license_family: MIT
+ purls:
+ - pkg:pypi/setuptools?source=compressed-mapping
+ size: 639697
+ timestamp: 1773074868565
+- conda: https://conda.anaconda.org/conda-forge/noarch/setuptools-scm-9.2.2-pyhd8ed1ab_0.conda
+ sha256: 2161ac35fc22770b248bab0be2cc3b5bd765f528a9e60e7f3be784fd8d0d605a
+ md5: e2e4d7094d0580ccd62e2a41947444f3
+ depends:
+ - importlib-metadata
+ - packaging >=20.0
+ - python >=3.10
+ - setuptools >=45
+ - tomli >=1.0.0
+ - typing-extensions
+ license: MIT
+ license_family: MIT
+ purls:
+ - pkg:pypi/setuptools-scm?source=hash-mapping
+ size: 52539
+ timestamp: 1760965125925
+- conda: https://conda.anaconda.org/conda-forge/noarch/setuptools_scm-9.2.2-hd8ed1ab_0.conda
+ sha256: 60eec92bd931bbcba700b9a70b1446dccbf62d3298e408d3a28e09b8ecd96d98
+ md5: 7537abc2590073ffde5545c648ad6974
+ depends:
+ - setuptools-scm >=9.2.2,<9.2.3.0a0
+ license: MIT
+ license_family: MIT
+ purls: []
+ size: 6653
+ timestamp: 1760965126461
+- conda: https://conda.anaconda.org/conda-forge/osx-64/sigtool-0.1.3-h88f4db0_0.tar.bz2
+ sha256: 46fdeadf8f8d725819c4306838cdfd1099cd8fe3e17bd78862a5dfdcd6de61cf
+ md5: fbfb84b9de9a6939cb165c02c69b1865
+ depends:
+ - openssl >=3.0.0,<4.0a0
+ license: MIT
+ license_family: MIT
+ purls: []
+ size: 213817
+ timestamp: 1643442169866
+- conda: https://conda.anaconda.org/conda-forge/osx-arm64/sigtool-0.1.3-h44b9a77_0.tar.bz2
+ sha256: 70791ae00a3756830cb50451db55f63e2a42a2fa2a8f1bab1ebd36bbb7d55bff
+ md5: 4a2cac04f86a4540b8c9b8d8f597848f
+ depends:
+ - openssl >=3.0.0,<4.0a0
+ license: MIT
+ license_family: MIT
+ purls: []
+ size: 210264
+ timestamp: 1643442231687
+- conda: https://conda.anaconda.org/conda-forge/linux-64/simdjson-4.2.4-hb700be7_0.conda
+ sha256: ffe0c49e65486b485e66c7e116b1782189c970c16cb2fe9710a568e44bb9ede3
+ md5: da6caa4c932708d447fb80eed702cb4e
+ depends:
+ - __glibc >=2.17,<3.0.a0
+ - libgcc >=14
+ - libstdcxx >=14
+ license: Apache-2.0
+ license_family: APACHE
+ purls: []
+ size: 294996
+ timestamp: 1766034103379
+- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/simdjson-4.2.4-hfefdfc9_0.conda
+ sha256: 8731e7cb9438deb3275c4d33d402b99da12f250c4b0bd635a58784c5a01e38f5
+ md5: 829b13867c30e5d44ab7d851bfdb5d63
+ depends:
+ - libgcc >=14
+ - libstdcxx >=14
+ license: Apache-2.0
+ license_family: APACHE
+ purls: []
+ size: 260530
+ timestamp: 1766034125791
+- conda: https://conda.anaconda.org/conda-forge/osx-64/simdjson-4.2.4-hcb651aa_0.conda
+ sha256: 33767091b867a05e47cdb8e756e84d82237be25a82f896ece073f06801ebfee7
+ md5: 4670f8951ec3f5f3a09e7c580d964088
+ depends:
+ - __osx >=10.13
+ - libcxx >=19
+ license: Apache-2.0
+ license_family: APACHE
+ purls: []
+ size: 286025
+ timestamp: 1766034310103
+- conda: https://conda.anaconda.org/conda-forge/osx-arm64/simdjson-4.2.4-ha7d2532_0.conda
+ sha256: 142758c665c2a896c1f275213068b324e92f378b03ba8d0019f57d72ea319515
+ md5: b6ac50035bdc00e3f01322c43062b855
+ depends:
+ - __osx >=11.0
+ - libcxx >=19
+ license: Apache-2.0
+ license_family: APACHE
+ purls: []
+ size: 252462
+ timestamp: 1766034371359
+- conda: https://conda.anaconda.org/conda-forge/win-64/simdjson-4.2.4-h49e36cd_0.conda
+ sha256: 4bb3d41240e455bffc919042d8bbe64ae6cfd560dc9eeda0e84fd8f33b53da26
+ md5: c625e0530b27e3bad5f59fa00744bbb8
+ depends:
+ - ucrt >=10.0.20348.0
+ - vc >=14.3,<15
+ - vc14_runtime >=14.44.35208
+ license: Apache-2.0
+ license_family: APACHE
+ purls: []
+ size: 298171
+ timestamp: 1766034112737
+- conda: https://conda.anaconda.org/conda-forge/linux-64/spdlog-1.17.0-hab81395_1.conda
+ sha256: c650f3df027afde77a5fbf58600ec4ed81a9edddf81f323cfb3e260f6dc19f56
+ md5: a3b0e874fa56f72bc54e5c595712a333
+ depends:
+ - __glibc >=2.17,<3.0.a0
+ - fmt >=12.1.0,<12.2.0a0
+ - libgcc >=14
+ - libstdcxx >=14
+ license: MIT
+ license_family: MIT
+ purls: []
+ size: 196681
+ timestamp: 1767781665629
+- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/spdlog-1.17.0-h9f97df7_1.conda
+ sha256: 36f5c0d73d88760438388bc940a65af4d9de3ecaf6fa5656a22a060d262d56f5
+ md5: 910d3cbb4ccf371b6355a98b1233eb8f
+ depends:
+ - fmt >=12.1.0,<12.2.0a0
+ - libgcc >=14
+ - libstdcxx >=14
+ license: MIT
+ license_family: MIT
+ purls: []
+ size: 195699
+ timestamp: 1767781668042
+- conda: https://conda.anaconda.org/conda-forge/osx-64/spdlog-1.17.0-h30f01e4_1.conda
+ sha256: a44fbcfdccf08211d39af11c08707b7f5748ad5e619adea7957decd21949018c
+ md5: 9ffcaf6ea8a92baea102b24c556140ae
+ depends:
+ - __osx >=10.13
+ - fmt >=12.1.0,<12.2.0a0
+ - libcxx >=19
+ license: MIT
+ license_family: MIT
+ purls: []
+ size: 173402
+ timestamp: 1767782141460
+- conda: https://conda.anaconda.org/conda-forge/osx-arm64/spdlog-1.17.0-ha0f8610_1.conda
+ sha256: 465e81abc0e662937046a2c6318d1a9e74baee0addd51234d36e08bae6811296
+ md5: 1885f7cface8cd627774407eeacb2caf
+ depends:
+ - __osx >=11.0
+ - fmt >=12.1.0,<12.2.0a0
+ - libcxx >=19
+ license: MIT
+ license_family: MIT
+ purls: []
+ size: 166603
+ timestamp: 1767781942683
+- conda: https://conda.anaconda.org/conda-forge/win-64/spdlog-1.17.0-h9f585f1_1.conda
+ sha256: 90c9befa5f154463647c8e101bc7a4e05cb84b731e2dea5406bedfea02f8b012
+ md5: 5c17c0a063b4d36b15d5f9c0ca5377a0
+ depends:
+ - fmt >=12.1.0,<12.2.0a0
+ - ucrt >=10.0.20348.0
+ - vc >=14.3,<15
+ - vc14_runtime >=14.44.35208
+ license: MIT
+ license_family: MIT
+ purls: []
+ size: 174787
+ timestamp: 1767781882230
+- conda: https://conda.anaconda.org/conda-forge/noarch/sysroot_linux-64-2.28-h4ee821c_9.conda
+ sha256: c47299fe37aebb0fcf674b3be588e67e4afb86225be4b0d452c7eb75c086b851
+ md5: 13dc3adbc692664cd3beabd216434749
+ depends:
+ - __glibc >=2.28
+ - kernel-headers_linux-64 4.18.0 he073ed8_9
+ - tzdata
+ license: LGPL-2.0-or-later AND LGPL-2.0-or-later WITH exceptions AND GPL-2.0-or-later
+ license_family: GPL
+ purls: []
+ size: 24008591
+ timestamp: 1765578833462
+- conda: https://conda.anaconda.org/conda-forge/noarch/sysroot_linux-aarch64-2.28-h585391f_9.conda
+ sha256: 1bd2db6b2e451247bab103e4a0128cf6c7595dd72cb26d70f7fadd9edd1d1bc3
+ md5: fdf07ab944a222ff28c754914fdb0740
+ depends:
+ - __glibc >=2.28
+ - kernel-headers_linux-aarch64 4.18.0 h05a177a_9
+ - tzdata
+ license: LGPL-2.0-or-later AND LGPL-2.0-or-later WITH exceptions AND GPL-2.0-or-later
+ license_family: GPL
+ purls: []
+ size: 23644746
+ timestamp: 1765578629426
+- conda: https://conda.anaconda.org/conda-forge/osx-64/tapi-1100.0.11-h9ce4665_0.tar.bz2
+ sha256: 34b18ce8d1518b67e333ca1d3af733c3976ecbdf3a36b727f9b4dedddcc588fa
+ md5: f9ff42ccf809a21ba6f8607f8de36108
+ depends:
+ - libcxx >=10.0.0.a0
+ license: NCSA
+ license_family: MIT
+ purls: []
+ size: 201044
+ timestamp: 1602664232074
+- conda: https://conda.anaconda.org/conda-forge/osx-arm64/tapi-1100.0.11-he4954df_0.tar.bz2
+ sha256: 1709265fbee693a9e8b4126b0a3e68a6c4718b05821c659279c1af051f2d40f3
+ md5: d83362e7d0513f35f454bc50b0ca591d
+ depends:
+ - libcxx >=11.0.0.a0
+ license: NCSA
+ license_family: MIT
+ purls: []
+ size: 191416
+ timestamp: 1602687595316
+- conda: https://conda.anaconda.org/conda-forge/linux-64/taplo-0.10.0-h2d22210_1.conda
+ sha256: 7d313578d79ece2b328084d906958888b5a474326a24833317d95a71e264b219
+ md5: a4935b2eea119342f6a9d666e821984d
+ depends:
+ - __glibc >=2.17,<3.0.a0
+ - libgcc >=13
+ - openssl >=3.5.0,<4.0a0
+ constrains:
+ - __glibc >=2.17
+ license: MIT
+ license_family: MIT
+ purls: []
+ size: 4319647
+ timestamp: 1748302828104
+- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/taplo-0.10.0-h3618846_1.conda
+ sha256: 50944952f49509d1125bfafe2a958e55f5dc585dd6f7608c6707dd892e8356a8
+ md5: 9bdb00138021e1f22b8d14a2f7fe52dc
+ depends:
+ - libgcc >=13
+ - openssl >=3.5.0,<4.0a0
+ constrains:
+ - __glibc >=2.17
+ license: MIT
+ license_family: MIT
+ purls: []
+ size: 4155701
+ timestamp: 1748302870538
+- conda: https://conda.anaconda.org/conda-forge/osx-64/taplo-0.10.0-hffa81eb_1.conda
+ sha256: 47b343fd4779605c431f10e1bfe07e84df63884d4e081aafca027262b317bb7a
+ md5: c8ed0c445e126bc7519c32509b67fa2a
+ depends:
+ - __osx >=10.13
+ - openssl >=3.5.0,<4.0a0
+ constrains:
+ - __osx >=10.13
+ license: MIT
+ license_family: MIT
+ purls: []
+ size: 4286090
+ timestamp: 1748302835791
+- conda: https://conda.anaconda.org/conda-forge/osx-64/taplo-0.8.1-h7205ca4_0.conda
+ sha256: 493b5f8db450f37e8bb50fdfd02c06499c18391c806d2220e65ac801f6b7c2f0
+ md5: 8e99d4b2850401094fe7c83273d3c4e8
+ license: MIT
+ license_family: MIT
+ purls: []
+ size: 3446470
+ timestamp: 1689048461323
+- conda: https://conda.anaconda.org/conda-forge/osx-arm64/taplo-0.10.0-h2b2570c_1.conda
+ sha256: c05b9d0bb740f48671d643d0e258639a3e727785b1eb62582385943ddabc5b6b
+ md5: 7b818d29210b93c231bc5bb0cd133d3b
+ depends:
+ - __osx >=11.0
+ - openssl >=3.5.0,<4.0a0
+ constrains:
+ - __osx >=11.0
+ license: MIT
+ license_family: MIT
+ purls: []
+ size: 4005794
+ timestamp: 1748302845549
+- conda: https://conda.anaconda.org/conda-forge/osx-arm64/taplo-0.8.1-h69fbcac_0.conda
+ sha256: 5a46bbdac42c2aa1d59f3f7f61aa92eaed5f6936b01de4f3519f5ad40374973f
+ md5: 268425eeb6db286378bb05f69331feea
+ license: MIT
+ license_family: MIT
+ purls: []
+ size: 3339855
+ timestamp: 1689048706766
+- conda: https://conda.anaconda.org/conda-forge/win-64/taplo-0.10.0-h63977a8_1.conda
+ sha256: b38dd1dd1fe52d26f739d144a85fd277103320bd8e037b66a299457d5a827a04
+ md5: 5fc2fa2f444b00e0f5b1f60a23f2c2f8
+ depends:
+ - vc >=14.2,<15
+ - vc14_runtime >=14.29.30139
+ - ucrt >=10.0.20348.0
+ - vc >=14.2,<15
+ - vc14_runtime >=14.29.30139
+ - ucrt >=10.0.20348.0
+ license: MIT
+ license_family: MIT
+ purls: []
+ size: 4441127
+ timestamp: 1748302918824
+- conda: https://conda.anaconda.org/conda-forge/win-64/tbb-2022.3.0-h3155e25_2.conda
+ sha256: abd9a489f059fba85c8ffa1abdaa4d515d6de6a3325238b8e81203b913cf65a9
+ md5: 0f9817ffbe25f9e69ceba5ea70c52606
+ depends:
+ - libhwloc >=2.12.2,<2.12.3.0a0
+ - ucrt >=10.0.20348.0
+ - vc >=14.3,<15
+ - vc14_runtime >=14.44.35208
+ license: Apache-2.0
+ license_family: APACHE
+ purls: []
+ size: 155869
+ timestamp: 1767886839029
+- conda: https://conda.anaconda.org/conda-forge/linux-64/tk-8.6.13-noxft_h366c992_103.conda
+ sha256: cafeec44494f842ffeca27e9c8b0c27ed714f93ac77ddadc6aaf726b5554ebac
+ md5: cffd3bdd58090148f4cfcd831f4b26ab
+ depends:
+ - __glibc >=2.17,<3.0.a0
+ - libgcc >=14
+ - libzlib >=1.3.1,<2.0a0
+ constrains:
+ - xorg-libx11 >=1.8.12,<2.0a0
+ license: TCL
+ license_family: BSD
+ purls: []
+ size: 3301196
+ timestamp: 1769460227866
+- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/tk-8.6.13-noxft_h0dc03b3_103.conda
+ sha256: e25c314b52764219f842b41aea2c98a059f06437392268f09b03561e4f6e5309
+ md5: 7fc6affb9b01e567d2ef1d05b84aa6ed
+ depends:
+ - libgcc >=14
+ - libzlib >=1.3.1,<2.0a0
+ constrains:
+ - xorg-libx11 >=1.8.12,<2.0a0
+ license: TCL
+ license_family: BSD
+ purls: []
+ size: 3368666
+ timestamp: 1769464148928
+- conda: https://conda.anaconda.org/conda-forge/osx-64/tk-8.6.13-h1abcd95_1.conda
+ sha256: 30412b2e9de4ff82d8c2a7e5d06a15f4f4fef1809a72138b6ccb53a33b26faf5
+ md5: bf830ba5afc507c6232d4ef0fb1a882d
+ depends:
+ - libzlib >=1.2.13,<2.0.0a0
+ license: TCL
+ license_family: BSD
+ purls: []
+ size: 3270220
+ timestamp: 1699202389792
+- conda: https://conda.anaconda.org/conda-forge/osx-64/tk-8.6.13-h7142dee_3.conda
+ sha256: 7f0d9c320288532873e2d8486c331ec6d87919c9028208d3f6ac91dc8f99a67b
+ md5: 6e6efb7463f8cef69dbcb4c2205bf60e
+ depends:
+ - __osx >=10.13
+ - libzlib >=1.3.1,<2.0a0
+ license: TCL
+ license_family: BSD
+ purls: []
+ size: 3282953
+ timestamp: 1769460532442
+- conda: https://conda.anaconda.org/conda-forge/osx-arm64/tk-8.6.13-h010d191_3.conda
+ sha256: 799cab4b6cde62f91f750149995d149bc9db525ec12595e8a1d91b9317f038b3
+ md5: a9d86bc62f39b94c4661716624eb21b0
+ depends:
+ - __osx >=11.0
+ - libzlib >=1.3.1,<2.0a0
+ license: TCL
+ license_family: BSD
+ purls: []
+ size: 3127137
+ timestamp: 1769460817696
+- conda: https://conda.anaconda.org/conda-forge/osx-arm64/tk-8.6.13-h5083fa2_1.conda
+ sha256: 72457ad031b4c048e5891f3f6cb27a53cb479db68a52d965f796910e71a403a8
+ md5: b50a57ba89c32b62428b71a875291c9b
+ depends:
+ - libzlib >=1.2.13,<2.0.0a0
+ license: TCL
+ license_family: BSD
+ purls: []
+ size: 3145523
+ timestamp: 1699202432999
+- conda: https://conda.anaconda.org/conda-forge/win-64/tk-8.6.13-h6ed50ae_3.conda
+ sha256: 0e79810fae28f3b69fe7391b0d43f5474d6bd91d451d5f2bde02f55ae481d5e3
+ md5: 0481bfd9814bf525bd4b3ee4b51494c4
+ depends:
+ - ucrt >=10.0.20348.0
+ - vc >=14.3,<15
+ - vc14_runtime >=14.44.35208
+ license: TCL
+ license_family: BSD
+ purls: []
+ size: 3526350
+ timestamp: 1769460339384
+- conda: https://conda.anaconda.org/conda-forge/noarch/tomli-2.4.0-pyhcf101f3_0.conda
+ sha256: 62940c563de45790ba0f076b9f2085a842a65662268b02dd136a8e9b1eaf47a8
+ md5: 72e780e9aa2d0a3295f59b1874e3768b
+ depends:
+ - python >=3.10
+ - python
+ license: MIT
+ license_family: MIT
+ purls:
+ - pkg:pypi/tomli?source=compressed-mapping
+ size: 21453
+ timestamp: 1768146676791
+- conda: https://conda.anaconda.org/conda-forge/noarch/tqdm-4.67.3-pyh8f84b5b_0.conda
+ sha256: 9ef8e47cf00e4d6dcc114eb32a1504cc18206300572ef14d76634ba29dfe1eb6
+ md5: e5ce43272193b38c2e9037446c1d9206
+ depends:
+ - python >=3.10
+ - __unix
+ - python
+ license: MPL-2.0 and MIT
+ purls:
+ - pkg:pypi/tqdm?source=compressed-mapping
+ size: 94132
+ timestamp: 1770153424136
+- conda: https://conda.anaconda.org/conda-forge/noarch/tqdm-4.67.3-pyha7b4d00_0.conda
+ sha256: 63cc2def6e168622728c7800ed6b3c1761ceecb18b354c81cee1a0a94c09900a
+ md5: af77160f8428924c17db94e04aa69409
+ depends:
+ - python >=3.10
+ - colorama
+ - __win
+ - python
+ license: MPL-2.0 and MIT
+ purls:
+ - pkg:pypi/tqdm?source=hash-mapping
+ size: 93399
+ timestamp: 1770153445242
+- conda: https://conda.anaconda.org/conda-forge/noarch/truststore-0.10.4-pyhcf101f3_0.conda
+ sha256: eece5be81588c39a855a0b70da84e0febb878a6d91dd27d6d21370ce9e5c5a46
+ md5: c2db35b004913ec69bcac64fb0783de0
+ depends:
+ - python >=3.10,<4
+ - python
+ license: MIT
+ license_family: MIT
+ purls:
+ - pkg:pypi/truststore?source=hash-mapping
+ size: 24279
+ timestamp: 1766494826559
+- pypi: https://files.pythonhosted.org/packages/3a/7a/882d99539b19b1490cac5d77c67338d126e4122c8276bf640e411650c830/twine-6.2.0-py3-none-any.whl
+ name: twine
+ version: 6.2.0
+ sha256: 418ebf08ccda9a8caaebe414433b0ba5e25eb5e4a927667122fbe8f829f985d8
+ requires_dist:
+ - readme-renderer>=35.0
+ - requests>=2.20
+ - requests-toolbelt>=0.8.0,!=0.9.0
+ - urllib3>=1.26.0
+ - importlib-metadata>=3.6 ; python_full_version < '3.10'
+ - keyring>=21.2.0 ; platform_machine != 'ppc64le' and platform_machine != 's390x'
+ - rfc3986>=1.4.0
+ - rich>=12.0.0
+ - packaging>=24.0
+ - id
+ - keyring>=21.2.0 ; extra == 'keyring'
+ requires_python: '>=3.9'
+- conda: https://conda.anaconda.org/conda-forge/noarch/typing-extensions-4.15.0-h396c80c_0.conda
+ sha256: 7c2df5721c742c2a47b2c8f960e718c930031663ac1174da67c1ed5999f7938c
+ md5: edd329d7d3a4ab45dcf905899a7a6115
+ depends:
+ - typing_extensions ==4.15.0 pyhcf101f3_0
+ license: PSF-2.0
+ license_family: PSF
+ purls: []
+ size: 91383
+ timestamp: 1756220668932
+- conda: https://conda.anaconda.org/conda-forge/noarch/typing_extensions-4.15.0-pyhcf101f3_0.conda
+ sha256: 032271135bca55aeb156cee361c81350c6f3fb203f57d024d7e5a1fc9ef18731
+ md5: 0caa1af407ecff61170c9437a808404d
+ depends:
+ - python >=3.10
+ - python
+ license: PSF-2.0
+ license_family: PSF
+ purls:
+ - pkg:pypi/typing-extensions?source=hash-mapping
+ size: 51692
+ timestamp: 1756220668932
+- conda: https://conda.anaconda.org/conda-forge/noarch/tzdata-2025c-hc9c84f9_1.conda
+ sha256: 1d30098909076af33a35017eed6f2953af1c769e273a0626a04722ac4acaba3c
+ md5: ad659d0a2b3e47e38d829aa8cad2d610
+ license: LicenseRef-Public-Domain
+ purls: []
+ size: 119135
+ timestamp: 1767016325805
+- conda: https://conda.anaconda.org/conda-forge/win-64/ucrt-10.0.26100.0-h57928b3_0.conda
+ sha256: 3005729dce6f3d3f5ec91dfc49fc75a0095f9cd23bab49efb899657297ac91a5
+ md5: 71b24316859acd00bdb8b38f5e2ce328
+ constrains:
+ - vc14_runtime >=14.29.30037
+ - vs2015_runtime >=14.29.30037
+ license: LicenseRef-MicrosoftWindowsSDK10
+ purls: []
+ size: 694692
+ timestamp: 1756385147981
+- conda: https://conda.anaconda.org/conda-forge/linux-64/ukkonen-1.1.0-py310h03d9f68_0.conda
+ sha256: 24a1140fa1dcaf2d2b7da1014eba5801eae8c4c025bb17845a3b1b6c487cf8f7
+ md5: c3b1f5bc28ae6282ba95156d18fde825
+ depends:
+ - __glibc >=2.17,<3.0.a0
+ - cffi
+ - libgcc >=14
+ - libstdcxx >=14
+ - python >=3.10,<3.11.0a0
+ - python_abi 3.10.* *_cp310
+ license: MIT
+ license_family: MIT
+ purls:
+ - pkg:pypi/ukkonen?source=hash-mapping
+ size: 14822
+ timestamp: 1769438718477
+- conda: https://conda.anaconda.org/conda-forge/linux-64/ukkonen-1.1.0-py311hdf67eae_0.conda
+ sha256: 31ad759e2d7668f1615021bca0ae2358a284939e3ca3fcb971b3f7aa83c2a6d6
+ md5: 5a715cf5e3dc6cd68717c50e47dd7b6b
+ depends:
+ - __glibc >=2.17,<3.0.a0
+ - cffi
+ - libgcc >=14
+ - libstdcxx >=14
+ - python >=3.11,<3.12.0a0
+ - python_abi 3.11.* *_cp311
+ license: MIT
+ license_family: MIT
+ purls:
+ - pkg:pypi/ukkonen?source=compressed-mapping
+ size: 14898
+ timestamp: 1769438724694
+- conda: https://conda.anaconda.org/conda-forge/linux-64/ukkonen-1.1.0-py314h9891dd4_0.conda
+ sha256: c84034056dc938c853e4f61e72e5bd37e2ec91927a661fb9762f678cbea52d43
+ md5: 5d3c008e54c7f49592fca9c32896a76f
+ depends:
+ - __glibc >=2.17,<3.0.a0
+ - cffi
+ - libgcc >=14
+ - libstdcxx >=14
+ - python >=3.14,<3.15.0a0
+ - python_abi 3.14.* *_cp314
+ license: MIT
+ license_family: MIT
+ purls:
+ - pkg:pypi/ukkonen?source=hash-mapping
+ size: 15004
+ timestamp: 1769438727085
+- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/ukkonen-1.1.0-py310h0992a49_0.conda
+ sha256: 9547520cb3504f6acf364f4fa2447d19901360adae69701d7a3906458a7e3538
+ md5: bac9c59669edb94e345b97412af6d283
+ depends:
+ - cffi
+ - libgcc >=14
+ - libstdcxx >=14
+ - python >=3.10,<3.11.0a0
+ - python >=3.10,<3.11.0a0 *_cpython
+ - python_abi 3.10.* *_cp310
+ license: MIT
+ license_family: MIT
+ purls:
+ - pkg:pypi/ukkonen?source=hash-mapping
+ size: 15584
+ timestamp: 1769438771691
+- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/ukkonen-1.1.0-py311hfca10b7_0.conda
+ sha256: 8870876bc36f47d7aea163843e01399c37153c7f448335f629d37f276bfa5010
+ md5: 07e977e2a642a2348385860eb6fa84e9
+ depends:
+ - cffi
+ - libgcc >=14
+ - libstdcxx >=14
+ - python >=3.11,<3.12.0a0
+ - python >=3.11,<3.12.0a0 *_cpython
+ - python_abi 3.11.* *_cp311
+ license: MIT
+ license_family: MIT
+ purls:
+ - pkg:pypi/ukkonen?source=hash-mapping
+ size: 15709
+ timestamp: 1769438766154
+- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/ukkonen-1.1.0-py314hd7d8586_0.conda
+ sha256: 0a7efe469d7e2a34a1d017bc51cf6fb9a51436730256983694c5ad74a33bd4e0
+ md5: f3a967efabf9cf450b7741487318ea6e
+ depends:
+ - cffi
+ - libgcc >=14
+ - libstdcxx >=14
+ - python >=3.14,<3.15.0a0
+ - python >=3.14,<3.15.0a0 *_cp314
+ - python_abi 3.14.* *_cp314
+ license: MIT
+ license_family: MIT
+ purls:
+ - pkg:pypi/ukkonen?source=hash-mapping
+ size: 15756
+ timestamp: 1769438772414
+- conda: https://conda.anaconda.org/conda-forge/osx-64/ukkonen-1.0.1-py310h88cfcbd_4.conda
+ sha256: 662d357d36210e7cad2072e5e071b98fc18985ec36293f43139812efc29c6b4b
+ md5: 9b1aa3d9f02b72f2544ee531bb7ccea9
+ depends:
+ - cffi
+ - libcxx >=15.0.7
+ - python >=3.10,<3.11.0a0
+ - python_abi 3.10.* *_cp310
+ license: MIT
+ license_family: MIT
+ purls:
+ - pkg:pypi/ukkonen?source=hash-mapping
+ size: 13071
+ timestamp: 1695549876888
+- conda: https://conda.anaconda.org/conda-forge/osx-64/ukkonen-1.0.1-py311h5fe6e05_4.conda
+ sha256: b273782a1277042a54e12411beebd378d2a2a69e503bcf147766e98628e91c91
+ md5: 8f750b84128d48dc8376572c5eace61e
+ depends:
+ - cffi
+ - libcxx >=15.0.7
+ - python >=3.11,<3.12.0a0
+ - python_abi 3.11.* *_cp311
+ license: MIT
+ license_family: MIT
+ purls:
+ - pkg:pypi/ukkonen?source=hash-mapping
+ size: 13193
+ timestamp: 1695549883822
+- conda: https://conda.anaconda.org/conda-forge/osx-64/ukkonen-1.1.0-py314h473ef84_0.conda
+ sha256: a77214fabb930c5332dece5407973c0c1c711298bf687976a0b6a9207b758e12
+ md5: 08a26dd1ba8fc9681d6b5256b2895f8e
+ depends:
+ - __osx >=10.13
+ - cffi
+ - libcxx >=19
+ - python >=3.14,<3.15.0a0
+ - python_abi 3.14.* *_cp314
+ license: MIT
+ license_family: MIT
+ purls:
+ - pkg:pypi/ukkonen?source=hash-mapping
+ size: 14286
+ timestamp: 1769439103231
+- conda: https://conda.anaconda.org/conda-forge/osx-arm64/ukkonen-1.0.1-py310h38f39d4_4.conda
+ sha256: 3d668d21ba00d5e8c90c64cfaffc5bccd8b3349f584f1e96c7423f372289227a
+ md5: d44fc7ee5098e2cf4db125eda63878c6
+ depends:
+ - cffi
+ - libcxx >=15.0.7
+ - python >=3.10,<3.11.0a0
+ - python >=3.10,<3.11.0a0 *_cpython
+ - python_abi 3.10.* *_cp310
+ license: MIT
+ license_family: MIT
+ purls:
+ - pkg:pypi/ukkonen?source=hash-mapping
+ size: 13807
+ timestamp: 1695549789224
+- conda: https://conda.anaconda.org/conda-forge/osx-arm64/ukkonen-1.0.1-py311he4fd1f5_4.conda
+ sha256: 384fc81a34e248019d43a115386f77859ab63e0e6f12dade486d76359703743f
+ md5: 5d5ab5c5af32931e03608034f4a5fd75
+ depends:
+ - cffi
+ - libcxx >=15.0.7
+ - python >=3.11,<3.12.0a0
+ - python >=3.11,<3.12.0a0 *_cpython
+ - python_abi 3.11.* *_cp311
+ license: MIT
+ license_family: MIT
+ purls:
+ - pkg:pypi/ukkonen?source=hash-mapping
+ size: 13958
+ timestamp: 1695549884615
+- conda: https://conda.anaconda.org/conda-forge/osx-arm64/ukkonen-1.1.0-py314h6cfcd04_0.conda
+ sha256: 033dbf9859fe58fb85350cf6395be6b1346792e1766d2d5acab538a6eb3659fb
+ md5: e229f444fbdb28d8c4f40e247154d993
+ depends:
+ - __osx >=11.0
+ - cffi
+ - libcxx >=19
+ - python >=3.14,<3.15.0a0
+ - python >=3.14,<3.15.0a0 *_cp314
+ - python_abi 3.14.* *_cp314
+ license: MIT
+ license_family: MIT
+ purls:
+ - pkg:pypi/ukkonen?source=hash-mapping
+ size: 14884
+ timestamp: 1769439056290
+- conda: https://conda.anaconda.org/conda-forge/win-64/ukkonen-1.1.0-py310he9f1925_0.conda
+ sha256: f66932dc9e68950dae39a6ccd5ef00503e433414e25267185ff8416cb3be1282
+ md5: f63f6904311dc01152f624c828ee24b5
+ depends:
+ - cffi
+ - python >=3.10,<3.11.0a0
+ - python_abi 3.10.* *_cp310
+ - ucrt >=10.0.20348.0
+ - vc >=14.3,<15
+ - vc14_runtime >=14.44.35208
+ license: MIT
+ license_family: MIT
+ purls:
+ - pkg:pypi/ukkonen?source=hash-mapping
+ size: 18319
+ timestamp: 1769438862573
+- conda: https://conda.anaconda.org/conda-forge/win-64/ukkonen-1.1.0-py311h3fd045d_0.conda
+ sha256: f30fdd8cdc5aa9800d6f05ed772d8e5b6427202c4bf2c86513ac62070215f19d
+ md5: fb1cf06b4259739eaa61d94bc219c0e8
+ depends:
+ - cffi
+ - python >=3.11,<3.12.0a0
+ - python_abi 3.11.* *_cp311
+ - ucrt >=10.0.20348.0
+ - vc >=14.3,<15
+ - vc14_runtime >=14.44.35208
+ license: MIT
+ license_family: MIT
+ purls:
+ - pkg:pypi/ukkonen?source=hash-mapping
+ size: 18452
+ timestamp: 1769438859987
+- conda: https://conda.anaconda.org/conda-forge/win-64/ukkonen-1.1.0-py314h909e829_0.conda
+ sha256: 96990a5948e0c30788360836d94bf6145fdac0c187695ed9b3c2d61d9e11d267
+ md5: 54e012b629ac5a40c9b3fa32738375dc
+ depends:
+ - cffi
+ - python >=3.14,<3.15.0a0
+ - python_abi 3.14.* *_cp314
+ - ucrt >=10.0.20348.0
+ - vc >=14.3,<15
+ - vc14_runtime >=14.44.35208
+ license: MIT
+ license_family: MIT
+ purls:
+ - pkg:pypi/ukkonen?source=hash-mapping
+ size: 18504
+ timestamp: 1769438844417
+- conda: https://conda.anaconda.org/conda-forge/noarch/urllib3-2.5.0-pyhd8ed1ab_0.conda
+ sha256: 4fb9789154bd666ca74e428d973df81087a697dbb987775bc3198d2215f240f8
+ md5: 436c165519e140cb08d246a4472a9d6a
+ depends:
+ - brotli-python >=1.0.9
+ - h2 >=4,<5
+ - pysocks >=1.5.6,<2.0,!=1.5.7
+ - python >=3.9
+ - zstandard >=0.18.0
+ license: MIT
+ license_family: MIT
+ purls:
+ - pkg:pypi/urllib3?source=hash-mapping
+ size: 101735
+ timestamp: 1750271478254
+- conda: https://conda.anaconda.org/conda-forge/noarch/urllib3-2.6.3-pyhd8ed1ab_0.conda
+ sha256: af641ca7ab0c64525a96fd9ad3081b0f5bcf5d1cbb091afb3f6ed5a9eee6111a
+ md5: 9272daa869e03efe68833e3dc7a02130
+ depends:
+ - backports.zstd >=1.0.0
+ - brotli-python >=1.2.0
+ - h2 >=4,<5
+ - pysocks >=1.5.6,<2.0,!=1.5.7
+ - python >=3.10
+ license: MIT
+ license_family: MIT
+ purls:
+ - pkg:pypi/urllib3?source=hash-mapping
+ size: 103172
+ timestamp: 1767817860341
+- conda: https://conda.anaconda.org/conda-forge/win-64/vc-14.3-h41ae7f8_34.conda
+ sha256: 9dc40c2610a6e6727d635c62cced5ef30b7b30123f5ef67d6139e23d21744b3a
+ md5: 1e610f2416b6acdd231c5f573d754a0f
+ depends:
+ - vc14_runtime >=14.44.35208
+ track_features:
+ - vc14
+ license: BSD-3-Clause
+ license_family: BSD
+ purls: []
+ size: 19356
+ timestamp: 1767320221521
+- conda: https://conda.anaconda.org/conda-forge/win-64/vc14_runtime-14.44.35208-h818238b_34.conda
+ sha256: 02732f953292cce179de9b633e74928037fa3741eb5ef91c3f8bae4f761d32a5
+ md5: 37eb311485d2d8b2c419449582046a42
+ depends:
+ - ucrt >=10.0.20348.0
+ - vcomp14 14.44.35208 h818238b_34
+ constrains:
+ - vs2015_runtime 14.44.35208.* *_34
+ license: LicenseRef-MicrosoftVisualCpp2015-2022Runtime
+ license_family: Proprietary
+ purls: []
+ size: 683233
+ timestamp: 1767320219644
+- conda: https://conda.anaconda.org/conda-forge/win-64/vcomp14-14.44.35208-h818238b_34.conda
+ sha256: 878d5d10318b119bd98ed3ed874bd467acbe21996e1d81597a1dbf8030ea0ce6
+ md5: 242d9f25d2ae60c76b38a5e42858e51d
+ depends:
+ - ucrt >=10.0.20348.0
+ constrains:
+ - vs2015_runtime 14.44.35208.* *_34
+ license: LicenseRef-MicrosoftVisualCpp2015-2022Runtime
+ license_family: Proprietary
+ purls: []
+ size: 115235
+ timestamp: 1767320173250
+- conda: https://conda.anaconda.org/conda-forge/noarch/virtualenv-21.2.0-pyhcf101f3_0.conda
+ sha256: b83246d145ba0e6814d2ed0b616293e56924e6c7d6649101f5a4f97f9e757ed1
+ md5: 704c22301912f7e37d0a92b2e7d5942d
+ depends:
+ - python >=3.10
+ - distlib >=0.3.7,<1
+ - filelock <4,>=3.24.2
+ - importlib-metadata >=6.6
+ - platformdirs >=3.9.1,<5
+ - python-discovery >=1
+ - typing_extensions >=4.13.2
+ - python
+ license: MIT
+ license_family: MIT
+ purls:
+ - pkg:pypi/virtualenv?source=compressed-mapping
+ size: 4647775
+ timestamp: 1773133660203
+- conda: https://conda.anaconda.org/conda-forge/win-64/vs2022_win-64-19.44.35207-ha74f236_34.conda
+ sha256: 05bc657625b58159bcea039a35cc89d1f8baf54bf4060019c2b559a03ba4a45e
+ md5: 1d699ffd41c140b98e199ddd9787e1e1
+ depends:
+ - vswhere
+ constrains:
+ - vs_win-64 2022.14
+ track_features:
+ - vc14
+ license: BSD-3-Clause
+ license_family: BSD
+ purls: []
+ size: 23060
+ timestamp: 1767320175868
+- conda: https://conda.anaconda.org/conda-forge/noarch/vswhere-3.1.7-h40126e0_1.conda
+ sha256: b72270395326dc56de9bd6ca82f63791b3c8c9e2b98e25242a9869a4ca821895
+ md5: f622897afff347b715d046178ad745a5
+ depends:
+ - __win
+ license: MIT
+ license_family: MIT
+ purls: []
+ size: 238764
+ timestamp: 1745560912727
+- conda: https://conda.anaconda.org/conda-forge/noarch/wheel-0.46.3-pyhd8ed1ab_0.conda
+ sha256: d6cf2f0ebd5e09120c28ecba450556ce553752652d91795442f0e70f837126ae
+ md5: bdbd7385b4a67025ac2dba4ef8cb6a8f
+ depends:
+ - packaging >=24.0
+ - python >=3.10
+ license: MIT
+ license_family: MIT
+ purls:
+ - pkg:pypi/wheel?source=hash-mapping
+ size: 31858
+ timestamp: 1769139207397
+- conda: https://conda.anaconda.org/conda-forge/noarch/win_inet_pton-1.1.0-pyh7428d3b_8.conda
+ sha256: 93807369ab91f230cf9e6e2a237eaa812492fe00face5b38068735858fba954f
+ md5: 46e441ba871f524e2b067929da3051c2
+ depends:
+ - __win
+ - python >=3.9
+ license: LicenseRef-Public-Domain
+ purls:
+ - pkg:pypi/win-inet-pton?source=hash-mapping
+ size: 9555
+ timestamp: 1733130678956
+- conda: https://conda.anaconda.org/conda-forge/osx-64/xz-5.2.6-h775f41a_0.tar.bz2
+ sha256: eb09823f34cc2dd663c0ec4ab13f246f45dcd52e5b8c47b9864361de5204a1c8
+ md5: a72f9d4ea13d55d745ff1ed594747f10
+ license: LGPL-2.1 and GPL-2.0
+ purls: []
+ size: 238119
+ timestamp: 1660346964847
+- conda: https://conda.anaconda.org/conda-forge/osx-arm64/xz-5.2.6-h57fd34a_0.tar.bz2
+ sha256: 59d78af0c3e071021cfe82dc40134c19dab8cdf804324b62940f5c8cd71803ec
+ md5: 39c6b54e94014701dd157f4f576ed211
+ license: LGPL-2.1 and GPL-2.0
+ purls: []
+ size: 235693
+ timestamp: 1660346961024
+- conda: https://conda.anaconda.org/conda-forge/linux-64/yaml-0.2.5-h280c20c_3.conda
+ sha256: 6d9ea2f731e284e9316d95fa61869fe7bbba33df7929f82693c121022810f4ad
+ md5: a77f85f77be52ff59391544bfe73390a
+ depends:
+ - libgcc >=14
+ - __glibc >=2.17,<3.0.a0
+ license: MIT
+ license_family: MIT
+ purls: []
+ size: 85189
+ timestamp: 1753484064210
+- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/yaml-0.2.5-h80f16a2_3.conda
+ sha256: 66265e943f32ce02396ad214e27cb35f5b0490b3bd4f064446390f9d67fa5d88
+ md5: 032d8030e4a24fe1f72c74423a46fb88
+ depends:
+ - libgcc >=14
+ license: MIT
+ license_family: MIT
+ purls: []
+ size: 88088
+ timestamp: 1753484092643
+- conda: https://conda.anaconda.org/conda-forge/osx-64/yaml-0.2.5-h0d85af4_2.tar.bz2
+ sha256: 5301417e2c8dea45b401ffee8df3957d2447d4ce80c83c5ff151fc6bfe1c4148
+ md5: d7e08fcf8259d742156188e8762b4d20
+ license: MIT
+ license_family: MIT
+ purls: []
+ size: 84237
+ timestamp: 1641347062780
+- conda: https://conda.anaconda.org/conda-forge/osx-64/yaml-0.2.5-h4132b18_3.conda
+ sha256: a335161bfa57b64e6794c3c354e7d49449b28b8d8a7c4ed02bf04c3f009953f9
+ md5: a645bb90997d3fc2aea0adf6517059bd
+ depends:
+ - __osx >=10.13
+ license: MIT
+ license_family: MIT
+ purls: []
+ size: 79419
+ timestamp: 1753484072608
+- conda: https://conda.anaconda.org/conda-forge/osx-arm64/yaml-0.2.5-h3422bc3_2.tar.bz2
+ sha256: 93181a04ba8cfecfdfb162fc958436d868cc37db504c58078eab4c1a3e57fbb7
+ md5: 4bb3f014845110883a3c5ee811fd84b4
+ license: MIT
+ license_family: MIT
+ purls: []
+ size: 88016
+ timestamp: 1641347076660
+- conda: https://conda.anaconda.org/conda-forge/osx-arm64/yaml-0.2.5-h925e9cb_3.conda
+ sha256: b03433b13d89f5567e828ea9f1a7d5c5d697bf374c28a4168d71e9464f5dafac
+ md5: 78a0fe9e9c50d2c381e8ee47e3ea437d
+ depends:
+ - __osx >=11.0
+ license: MIT
+ license_family: MIT
+ purls: []
+ size: 83386
+ timestamp: 1753484079473
+- conda: https://conda.anaconda.org/conda-forge/win-64/yaml-0.2.5-h6a83c73_3.conda
+ sha256: 80ee68c1e7683a35295232ea79bcc87279d31ffeda04a1665efdb43cbd50a309
+ md5: 433699cba6602098ae8957a323da2664
+ depends:
+ - vc >=14.3,<15
+ - vc14_runtime >=14.44.35208
+ - ucrt >=10.0.20348.0
+ - vc >=14.3,<15
+ - vc14_runtime >=14.44.35208
+ - ucrt >=10.0.20348.0
+ license: MIT
+ license_family: MIT
+ purls: []
+ size: 63944
+ timestamp: 1753484092156
+- conda: https://conda.anaconda.org/conda-forge/linux-64/yaml-cpp-0.8.0-h3f2d84a_0.conda
+ sha256: 4b0b713a4308864a59d5f0b66ac61b7960151c8022511cdc914c0c0458375eca
+ md5: 92b90f5f7a322e74468bb4909c7354b5
+ depends:
+ - libstdcxx >=13
+ - libgcc >=13
+ - __glibc >=2.17,<3.0.a0
+ - libgcc >=13
+ license: MIT
+ license_family: MIT
+ purls: []
+ size: 223526
+ timestamp: 1745307989800
+- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/yaml-cpp-0.8.0-h5ad3122_0.conda
+ sha256: e146d83cdcf92506ab709c6e10acabd18a3394a23e6334a322c57e5d1d6d9f26
+ md5: b9e5a9da5729019c4f216cf0d386a70c
+ depends:
+ - libstdcxx >=13
+ - libgcc >=13
+ license: MIT
+ license_family: MIT
+ purls: []
+ size: 213281
+ timestamp: 1745308220432
+- conda: https://conda.anaconda.org/conda-forge/osx-64/yaml-cpp-0.8.0-h92383a6_0.conda
+ sha256: 67d25c3aa2b4ee54abc53060188542d6086b377878ebf3e2b262ae7379e05a6d
+ md5: e15e9855092a8bdaaaed6ad5c173fffa
+ depends:
+ - libcxx >=18
+ - __osx >=10.13
+ license: MIT
+ license_family: MIT
+ purls: []
+ size: 145204
+ timestamp: 1745308032698
+- conda: https://conda.anaconda.org/conda-forge/osx-arm64/yaml-cpp-0.8.0-ha1acc90_0.conda
+ sha256: 66ba31cfb8014fdd3456f2b3b394df123bbd05d95b75328b7c4131639e299749
+ md5: 30475b3d0406587cf90386a283bb3cd0
+ depends:
+ - libcxx >=18
+ - __osx >=11.0
+ license: MIT
+ license_family: MIT
+ purls: []
+ size: 136222
+ timestamp: 1745308075886
+- conda: https://conda.anaconda.org/conda-forge/win-64/yaml-cpp-0.8.0-he0c23c2_0.conda
+ sha256: 031642d753e0ebd666a76cea399497cc7048ff363edf7d76a630ee0a19e341da
+ md5: 9bb5064a9fca5ca8e7d7f1ae677354b6
+ depends:
+ - vc >=14.2,<15
+ - vc14_runtime >=14.29.30139
+ - ucrt >=10.0.20348.0
+ - vc >=14.2,<15
+ - vc14_runtime >=14.29.30139
+ - ucrt >=10.0.20348.0
+ license: MIT
+ license_family: MIT
+ purls: []
+ size: 148572
+ timestamp: 1745308037198
+- conda: https://conda.anaconda.org/conda-forge/noarch/zipp-3.23.0-pyhcf101f3_1.conda
+ sha256: b4533f7d9efc976511a73ef7d4a2473406d7f4c750884be8e8620b0ce70f4dae
+ md5: 30cd29cb87d819caead4d55184c1d115
+ depends:
+ - python >=3.10
+ - python
+ license: MIT
+ license_family: MIT
+ purls:
+ - pkg:pypi/zipp?source=hash-mapping
+ size: 24194
+ timestamp: 1764460141901
+- conda: https://conda.anaconda.org/conda-forge/linux-64/zstandard-0.25.0-py310h139afa4_1.conda
+ sha256: b0103e8bb639dbc6b9de8ef9a18a06b403b687a33dec83c25bd003190942259a
+ md5: 3741aefc198dfed2e3c9adc79d706bb7
+ depends:
+ - python
+ - cffi >=1.11
+ - zstd >=1.5.7,<1.5.8.0a0
+ - libgcc >=14
+ - __glibc >=2.17,<3.0.a0
+ - zstd >=1.5.7,<1.6.0a0
+ - python_abi 3.10.* *_cp310
+ license: BSD-3-Clause
+ license_family: BSD
+ purls:
+ - pkg:pypi/zstandard?source=hash-mapping
+ size: 455614
+ timestamp: 1762512676430
+- conda: https://conda.anaconda.org/conda-forge/linux-64/zstandard-0.25.0-py311haee01d2_1.conda
+ sha256: d534a6518c2d8eccfa6579d75f665261484f0f2f7377b50402446a9433d46234
+ md5: ca45bfd4871af957aaa5035593d5efd2
+ depends:
+ - python
+ - cffi >=1.11
+ - zstd >=1.5.7,<1.5.8.0a0
+ - libgcc >=14
+ - __glibc >=2.17,<3.0.a0
+ - zstd >=1.5.7,<1.6.0a0
+ - python_abi 3.11.* *_cp311
+ license: BSD-3-Clause
+ license_family: BSD
+ purls:
+ - pkg:pypi/zstandard?source=hash-mapping
+ size: 466893
+ timestamp: 1762512695614
+- conda: https://conda.anaconda.org/conda-forge/linux-64/zstandard-0.25.0-py314h0f05182_1.conda
+ sha256: e589f694b44084f2e04928cabd5dda46f20544a512be2bdb0d067d498e4ac8d0
+ md5: 2930a6e1c7b3bc5f66172e324a8f5fc3
+ depends:
+ - python
+ - cffi >=1.11
+ - zstd >=1.5.7,<1.5.8.0a0
+ - __glibc >=2.17,<3.0.a0
+ - libgcc >=14
+ - zstd >=1.5.7,<1.6.0a0
+ - python_abi 3.14.* *_cp314
+ license: BSD-3-Clause
+ license_family: BSD
+ purls:
+ - pkg:pypi/zstandard?source=hash-mapping
+ size: 473605
+ timestamp: 1762512687493
+- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/zstandard-0.25.0-py310hef25091_1.conda
+ sha256: 30202c0e21618a421d189c70b71c152f53a6f605f8fb053a7faf844dffd4843b
+ md5: ef07dc8296f6e4df546b8d41bfb0a1fe
+ depends:
+ - python
+ - cffi >=1.11
+ - zstd >=1.5.7,<1.5.8.0a0
+ - python 3.10.* *_cpython
+ - libgcc >=14
+ - zstd >=1.5.7,<1.6.0a0
+ - python_abi 3.10.* *_cp310
+ license: BSD-3-Clause
+ license_family: BSD
+ purls:
+ - pkg:pypi/zstandard?source=hash-mapping
+ size: 447338
+ timestamp: 1762512738321
+- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/zstandard-0.25.0-py311h51cfe5d_1.conda
+ sha256: ddeec193065b235166fb9f8ca4e5cbb931215ab90cbd17e9f9d753c8966b57b1
+ md5: c8b3365fe290eeee3084274948012394
+ depends:
+ - python
+ - cffi >=1.11
+ - zstd >=1.5.7,<1.5.8.0a0
+ - python 3.11.* *_cpython
+ - libgcc >=14
+ - zstd >=1.5.7,<1.6.0a0
+ - python_abi 3.11.* *_cp311
+ license: BSD-3-Clause
+ license_family: BSD
+ purls:
+ - pkg:pypi/zstandard?source=hash-mapping
+ size: 459426
+ timestamp: 1762512724303
+- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/zstandard-0.25.0-py314h2e8dab5_1.conda
+ sha256: 051f12494f28f9de8b1bf1a787646c1f675d8eba0ba0eac79ab96ef960d24746
+ md5: db33d0e8888bef6ef78207c5e6106a5b
+ depends:
+ - python
+ - cffi >=1.11
+ - zstd >=1.5.7,<1.5.8.0a0
+ - python 3.14.* *_cp314
+ - libgcc >=14
+ - python_abi 3.14.* *_cp314
+ - zstd >=1.5.7,<1.6.0a0
+ license: BSD-3-Clause
+ license_family: BSD
+ purls:
+ - pkg:pypi/zstandard?source=hash-mapping
+ size: 465094
+ timestamp: 1762512736835
+- conda: https://conda.anaconda.org/conda-forge/osx-64/zstandard-0.22.0-py310hd88f66e_0.conda
+ sha256: cdc8b9fc1352f19c73f16b0b0b3595a5a70758b3dfbd0398eac1db69910389bd
+ md5: 88c991558201cae2b7e690c2e9d2e618
+ depends:
+ - cffi >=1.11
+ - python >=3.10,<3.11.0a0
+ - python_abi 3.10.* *_cp310
+ - zstd >=1.5.5,<1.5.6.0a0
+ - zstd >=1.5.5,<1.6.0a0
+ license: BSD-3-Clause
+ license_family: BSD
+ purls:
+ - pkg:pypi/zstandard?source=hash-mapping
+ size: 399250
+ timestamp: 1698830565851
+- conda: https://conda.anaconda.org/conda-forge/osx-64/zstandard-0.22.0-py311hed14148_0.conda
+ sha256: 97e4ba1fb5a0d4310262da602bf283f058d63ab40e1dd74d93440f27823b1be5
+ md5: 027bd8663474659bb949785d4e2b8599
+ depends:
+ - cffi >=1.11
+ - python >=3.11,<3.12.0a0
+ - python_abi 3.11.* *_cp311
+ - zstd >=1.5.5,<1.5.6.0a0
+ - zstd >=1.5.5,<1.6.0a0
+ license: BSD-3-Clause
+ license_family: BSD
+ purls:
+ - pkg:pypi/zstandard?source=hash-mapping
+ size: 410219
+ timestamp: 1698830417763
+- conda: https://conda.anaconda.org/conda-forge/osx-64/zstandard-0.25.0-py314hd1e8ddb_1.conda
+ sha256: cf12b4c138eef5160b12990278ac77dec5ca91de60638dd6cf1e60e4331d8087
+ md5: b94712955dc017da312e6f6b4c6d4866
+ depends:
+ - python
+ - cffi >=1.11
+ - zstd >=1.5.7,<1.5.8.0a0
+ - __osx >=10.13
+ - python_abi 3.14.* *_cp314
+ - zstd >=1.5.7,<1.6.0a0
+ license: BSD-3-Clause
+ license_family: BSD
+ purls:
+ - pkg:pypi/zstandard?source=hash-mapping
+ size: 470136
+ timestamp: 1762512696464
+- conda: https://conda.anaconda.org/conda-forge/osx-arm64/zstandard-0.22.0-py310h6289e41_0.conda
+ sha256: 806c1a7519dca20df58bce3b88392f2f4c2f04c0257789c2bd94b9c31b173dc2
+ md5: f09fc5240964cceff0bbb2d68dbb6a5d
+ depends:
+ - cffi >=1.11
+ - python >=3.10,<3.11.0a0
+ - python >=3.10,<3.11.0a0 *_cpython
+ - python_abi 3.10.* *_cp310
+ - zstd >=1.5.5,<1.5.6.0a0
+ - zstd >=1.5.5,<1.6.0a0
+ license: BSD-3-Clause
+ license_family: BSD
+ purls:
+ - pkg:pypi/zstandard?source=hash-mapping
+ size: 320728
+ timestamp: 1698830561905
+- conda: https://conda.anaconda.org/conda-forge/osx-arm64/zstandard-0.22.0-py311h67b91a1_0.conda
+ sha256: 0bbe223fc0b6cb37f5f2287295f610e73a50888401c865448ce6db7bf79ac416
+ md5: 396d81ee96c6d91c3bdfe13a785f4636
+ depends:
+ - cffi >=1.11
+ - python >=3.11,<3.12.0a0
+ - python >=3.11,<3.12.0a0 *_cpython
+ - python_abi 3.11.* *_cp311
+ - zstd >=1.5.5,<1.5.6.0a0
+ - zstd >=1.5.5,<1.6.0a0
+ license: BSD-3-Clause
+ license_family: BSD
+ purls:
+ - pkg:pypi/zstandard?source=hash-mapping
+ size: 332059
+ timestamp: 1698830508653
+- conda: https://conda.anaconda.org/conda-forge/osx-arm64/zstandard-0.25.0-py314h9d33bd4_1.conda
+ sha256: cdeb350914094e15ec6310f4699fa81120700ca7ab7162a6b3421f9ea9c690b4
+ md5: 8a92a736ab23b4633ac49dcbfcc81e14
+ depends:
+ - python
+ - cffi >=1.11
+ - zstd >=1.5.7,<1.5.8.0a0
+ - python 3.14.* *_cp314
+ - __osx >=11.0
+ - python_abi 3.14.* *_cp314
+ - zstd >=1.5.7,<1.6.0a0
+ license: BSD-3-Clause
+ license_family: BSD
+ purls:
+ - pkg:pypi/zstandard?source=hash-mapping
+ size: 397786
+ timestamp: 1762512730914
+- conda: https://conda.anaconda.org/conda-forge/win-64/zstandard-0.25.0-py310h1637853_1.conda
+ sha256: db2a40dbe124b275fb0b8fdfd6e3b377963849897ab2b4d7696354040c52570b
+ md5: 1d261480977c268b3b209b7deaca0dd7
+ depends:
+ - python
+ - cffi >=1.11
+ - zstd >=1.5.7,<1.5.8.0a0
+ - vc >=14.3,<15
+ - vc14_runtime >=14.44.35208
+ - ucrt >=10.0.20348.0
+ - vc >=14.3,<15
+ - vc14_runtime >=14.44.35208
+ - ucrt >=10.0.20348.0
+ - python_abi 3.10.* *_cp310
+ - zstd >=1.5.7,<1.6.0a0
+ license: BSD-3-Clause
+ license_family: BSD
+ purls:
+ - pkg:pypi/zstandard?source=hash-mapping
+ size: 364167
+ timestamp: 1762512706699
+- conda: https://conda.anaconda.org/conda-forge/win-64/zstandard-0.25.0-py311hf893f09_1.conda
+ sha256: 10f089bedef1a28c663ef575fb9cec66b2058e342c4cf4a753083ab07591008f
+ md5: b2d90bca78b57c17205ce3ca1c427813
+ depends:
+ - python
+ - cffi >=1.11
+ - zstd >=1.5.7,<1.5.8.0a0
+ - vc >=14.3,<15
+ - vc14_runtime >=14.44.35208
+ - ucrt >=10.0.20348.0
+ - vc >=14.3,<15
+ - vc14_runtime >=14.44.35208
+ - ucrt >=10.0.20348.0
+ - python_abi 3.11.* *_cp311
+ - zstd >=1.5.7,<1.6.0a0
+ license: BSD-3-Clause
+ license_family: BSD
+ purls:
+ - pkg:pypi/zstandard?source=hash-mapping
+ size: 375869
+ timestamp: 1762512737575
+- conda: https://conda.anaconda.org/conda-forge/win-64/zstandard-0.25.0-py314hc5dbbe4_1.conda
+ sha256: 87bf6ba2dcc59dfbb8d977b9c29d19b6845ad54e092ea8204dcec62d7b461a30
+ md5: c1ef46c3666be935fbb7460c24950cff
+ depends:
+ - python
+ - cffi >=1.11
+ - zstd >=1.5.7,<1.5.8.0a0
+ - vc >=14.3,<15
+ - vc14_runtime >=14.44.35208
+ - ucrt >=10.0.20348.0
+ - vc >=14.3,<15
+ - vc14_runtime >=14.44.35208
+ - ucrt >=10.0.20348.0
+ - zstd >=1.5.7,<1.6.0a0
+ - python_abi 3.14.* *_cp314
+ license: BSD-3-Clause
+ license_family: BSD
+ purls:
+ - pkg:pypi/zstandard?source=hash-mapping
+ size: 381179
+ timestamp: 1762512709971
+- conda: https://conda.anaconda.org/conda-forge/linux-64/zstd-1.5.7-hb78ec9c_6.conda
+ sha256: 68f0206ca6e98fea941e5717cec780ed2873ffabc0e1ed34428c061e2c6268c7
+ md5: 4a13eeac0b5c8e5b8ab496e6c4ddd829
+ depends:
+ - __glibc >=2.17,<3.0.a0
+ - libzlib >=1.3.1,<2.0a0
+ license: BSD-3-Clause
+ license_family: BSD
+ purls: []
+ size: 601375
+ timestamp: 1764777111296
+- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/zstd-1.5.7-h85ac4a6_6.conda
+ sha256: 569990cf12e46f9df540275146da567d9c618c1e9c7a0bc9d9cfefadaed20b75
+ md5: c3655f82dcea2aa179b291e7099c1fcc
+ depends:
+ - libzlib >=1.3.1,<2.0a0
+ license: BSD-3-Clause
+ license_family: BSD
+ purls: []
+ size: 614429
+ timestamp: 1764777145593
+- conda: https://conda.anaconda.org/conda-forge/osx-64/zstd-1.5.5-h829000d_0.conda
+ sha256: d54e31d3d8de5e254c0804abd984807b8ae5cd3708d758a8bf1adff1f5df166c
+ md5: 80abc41d0c48b82fe0f04e7f42f5cb7e
+ depends:
+ - libzlib >=1.2.13,<2.0.0a0
+ license: BSD-3-Clause
+ license_family: BSD
+ purls: []
+ size: 499383
+ timestamp: 1693151312586
+- conda: https://conda.anaconda.org/conda-forge/osx-64/zstd-1.5.7-h3eecb57_6.conda
+ sha256: 47101a4055a70a4876ffc87b750ab2287b67eca793f21c8224be5e1ee6394d3f
+ md5: 727109b184d680772e3122f40136d5ca
+ depends:
+ - __osx >=10.13
+ - libzlib >=1.3.1,<2.0a0
+ license: BSD-3-Clause
+ license_family: BSD
+ purls: []
+ size: 528148
+ timestamp: 1764777156963
+- conda: https://conda.anaconda.org/conda-forge/osx-arm64/zstd-1.5.5-h4f39d0f_0.conda
+ sha256: 7e1fe6057628bbb56849a6741455bbb88705bae6d6646257e57904ac5ee5a481
+ md5: 5b212cfb7f9d71d603ad891879dc7933
+ depends:
+ - libzlib >=1.2.13,<2.0.0a0
+ license: BSD-3-Clause
+ license_family: BSD
+ purls: []
+ size: 400508
+ timestamp: 1693151393180
+- conda: https://conda.anaconda.org/conda-forge/osx-arm64/zstd-1.5.7-hbf9d68e_6.conda
+ sha256: 9485ba49e8f47d2b597dd399e88f4802e100851b27c21d7525625b0b4025a5d9
+ md5: ab136e4c34e97f34fb621d2592a393d8
+ depends:
+ - __osx >=11.0
+ - libzlib >=1.3.1,<2.0a0
+ license: BSD-3-Clause
+ license_family: BSD
+ purls: []
+ size: 433413
+ timestamp: 1764777166076
+- conda: https://conda.anaconda.org/conda-forge/win-64/zstd-1.5.7-h534d264_6.conda
+ sha256: 368d8628424966fd8f9c8018326a9c779e06913dd39e646cf331226acc90e5b2
+ md5: 053b84beec00b71ea8ff7a4f84b55207
+ depends:
+ - vc >=14.3,<15
+ - vc14_runtime >=14.44.35208
+ - ucrt >=10.0.20348.0
+ - libzlib >=1.3.1,<2.0a0
+ license: BSD-3-Clause
+ license_family: BSD
+ purls: []
+ size: 388453
+ timestamp: 1764777142545
diff --git a/pixi.toml b/pixi.toml
new file mode 100644
index 00000000..5f89234d
--- /dev/null
+++ b/pixi.toml
@@ -0,0 +1,211 @@
+[workspace]
+authors = [
+ "Insight Software Consortium <>",
+ "Matt McCormick ",
+ "Jean-Christophe Fillion-Robin ",
+ "Tom Birdsong ",
+ "Hans J. Johnson ",
+ "Dženan Zukić ",
+ "Simon Rit ",
+ "Francois Budin ",
+ "LucasGandel ",
+ "Davis Marc Vigneault ",
+ "Jon Haitz Legarreta Gorroño ",
+ "Lee Newberg ",
+ "Cavan Riley ",
+]
+
+name = "ITKPythonPackage"
+version = "0.1.0"
+channels = ["conda-forge"]
+platforms = ["linux-64", "linux-aarch64", "osx-64", "osx-arm64", "win-64"]
+
+########################################
+# Common features used by all envs
+########################################
+
+# Build tooling shared by all platforms
+[feature.build-dev-tools]
+[feature.build-dev-tools.dependencies]
+cmake = ">=3.26,<4"
+doxygen = "<2"
+ninja = ">=1.11.1,<2"
+pkginfo = ">=1.12.1.2,<2"
+
+# Python packaging/build support shared by all platforms
+[feature.python-dev-pkgs]
+[feature.python-dev-pkgs.dependencies]
+numpy = ">=1.26"
+packaging = ">=25.0,<26"
+pathspec = "*"
+pyproject-metadata = "*"
+scikit-build-core = ">=0.11.6,<0.12.0"
+setuptools_scm = ">=9.2.0"
+setuptools = ">=61"
+tomli = "*"
+pip = "*"
+
+[feature.python-dev-pkgs.pypi-dependencies]
+build = "*"
+
+########################################
+# Manylinux-specific features
+########################################
+
+# Shared dependencies for all manylinux wheel builds
+# (might be helpful for including newer manylinux versions later)
+[feature.manylinux-common-build]
+platforms = ["linux-64", "linux-aarch64"]
+
+[feature.manylinux-common-build.dependencies]
+auditwheel = "*"
+patchelf = "*" # Needed for auditwheel
+wheel = "*"
+
+[feature.manylinux-common-build.pypi-dependencies]
+build = "*"
+
+[feature.linux-build]
+platforms = ["linux-64", "linux-aarch64"]
+
+[feature.linux-build.dependencies]
+cxx-compiler = "==1.11.0"
+c-compiler = "==1.11.0"
+libhwloc = "*" # Needed for tbb
+auditwheel = "*"
+patchelf = "*" # Needed for auditwheel
+wheel = "*"
+
+[feature.manylinux228-build]
+platforms = ["linux-64", "linux-aarch64"]
+
+[feature.manylinux228-build.system-requirements]
+linux = "5.4"
+libc = { family = "glibc", version = "2.28" }
+
+[feature.linux-build.activation.env]
+PYTHONNOUSERSITE = "1" # Exclude system .local site packages
+
+########################################
+# macOS-specific feature
+########################################
+
+[feature.macosx-build]
+platforms = ["osx-64", "osx-arm64"]
+system-requirements = { macos = "10.7" }
+
+# delocate is a Python tool; cxx-compiler is the macOS toolchain meta-package
+[feature.macosx-build.pypi-dependencies]
+delocate = "*"
+
+[feature.macosx-build.dependencies]
+cxx-compiler = "==1.10.0" # XCode 16.0 before castxml required updates
+c-compiler = "==1.10.0" # XCode 16.0 before castxml required updates
+#libhwloc = "*" # Needed for tbb
+
+[feature.windows-build]
+platforms = ["win-64"]
+
+[feature.windows-build.dependencies]
+git = "*" # Git is not always available in PowerShell by default
+cxx-compiler = "==1.11.0" # MSVC 2022
+c-compiler = "==1.11.0" # MSVC 2022
+
+[feature.windows-build.pypi-dependencies]
+delvewheel = "*"
+# windows = "*"
+
+[feature.py310]
+[feature.py310.dependencies]
+python = ">=3.10,<3.11"
+
+[feature.py311]
+[feature.py311.dependencies]
+python = ">=3.11,<3.12"
+
+#[feature.py312]
+#[feature.py312.dependencies]
+#python = ">=3.12,<3.13"
+#
+#[feature.py313]
+#[feature.py313.dependencies]
+#python = ">=3.13,<3.14"
+#
+#[feature.py314]
+#[feature.py314.dependencies]
+#python = ">=3.14,<3.15"
+
+########################################
+# Publishing feature (no compilers needed)
+########################################
+[feature.publish]
+[feature.publish.dependencies]
+python = ">=3.10"
+gh = "*"
+zstd = "*"
+
+[feature.publish.pypi-dependencies]
+twine = ">=6.0"
+
+
+########################################
+# Environments: compose features per target
+########################################
+
+[environments]
+publish = ["publish"]
+linux-py310 = ["py310", "linux-build", "build-dev-tools", "python-dev-pkgs"]
+linux-py311 = ["py311", "linux-build", "build-dev-tools", "python-dev-pkgs"]
+
+# Manylinux wheel-build env (docker manylinux228 images, CI, etc.)
+manylinux228-py310 = [
+ "py310",
+ "manylinux-common-build",
+ "manylinux228-build",
+ "build-dev-tools",
+ "python-dev-pkgs",
+]
+manylinux228-py311 = [
+ "py311",
+ "manylinux-common-build",
+ "manylinux228-build",
+ "build-dev-tools",
+ "python-dev-pkgs",
+]
+
+
+# macOS build env (both Intel and Apple Silicon)
+macosx-py310 = ["py310", "build-dev-tools", "python-dev-pkgs", "macosx-build"]
+macosx-py311 = ["py311", "build-dev-tools", "python-dev-pkgs", "macosx-build"]
+
+# Windows build env
+windows-py310 = ["py310", "build-dev-tools", "python-dev-pkgs", "windows-build"]
+windows-py311 = ["py311", "build-dev-tools", "python-dev-pkgs", "windows-build"]
+
+[dependencies]
+# pixi-pycharm and conda are only needed to support development in pycharm
+# https://pixi.prefix.dev/v0.21.1/ide_integration/pycharm/#how-to-use
+pixi-pycharm = ">=0.0.10,<0.0.11"
+conda = "*"
+taplo = ">=0.8.1,<0.11"
+pre-commit = "*"
+
+[tasks]
+taplo = "fmt pixi.toml"
+
+[tasks.build-itk-wheels]
+cmd = ["python", "scripts/build_wheels.py"]
+
+[tasks.pre-commit-install]
+cmd = "pre-commit install -f -t pre-commit -t prepare-commit-msg -t commit-msg --hook-type commit-msg --install-hooks"
+
+[tasks.pre-commit-run]
+cmd = "pre-commit run --all-files"
+
+[tasks.publish-wheels]
+cmd = ["python", "scripts/publish_wheels.py"]
+description = "Upload built wheels to PyPI (or TestPyPI with --test)"
+
+[tasks.publish-tarball-cache]
+cmd = ["python", "scripts/publish_tarball_cache.py"]
+description = "Upload .tar.zst/.zip build caches to GitHub Releases"
diff --git a/pyproject.toml b/pyproject.toml
new file mode 100644
index 00000000..5871eda1
--- /dev/null
+++ b/pyproject.toml
@@ -0,0 +1,65 @@
+# Root-level pyproject.toml — developer tooling configuration only.
+# This file configures linters/formatters for the ITKPythonPackage build scripts.
+# It does NOT define a Python package; wheel-specific pyproject.toml files are
+# generated dynamically by scripts/pyproject_configure.py into build subdirectories.
+
+[tool.black]
+line-length = 88
+target-version = ["py310", "py311"]
+
+[tool.ruff]
+line-length = 88
+target-version = "py310"
+
+[tool.ruff.lint]
+# E/F: pycodestyle errors + pyflakes
+# I: isort import ordering
+# UP: pyupgrade (modernise syntax for Python 3.10+)
+# B: flake8-bugbear (opinionated bug detection)
+select = ["E", "F", "I", "UP", "B"]
+# E501 (line-too-long) is handled by black; suppress here to avoid duplication
+ignore = ["E501"]
+
+[tool.commitizen]
+name = "cz_customize"
+
+[tool.commitizen.customize]
+message_template = "{{change_type}}: {{message}}"
+example = "ENH: Add support for Python 3.12"
+schema = ": "
+schema_pattern = "(BUG|COMP|DOC|ENH|PERF|STYLE): [A-Z].*"
+bump_pattern = "^(ENH|BUG|COMP|PERF)"
+bump_map = { "ENH" = "MINOR", "BUG" = "PATCH", "COMP" = "PATCH", "PERF" = "PATCH" }
+commit_parser = "^(?PBUG|COMP|DOC|ENH|PERF|STYLE): (?P.*)"
+changelog_pattern = "^(BUG|COMP|DOC|ENH|PERF|STYLE)?(!)?"
+change_type_map = { "ENH" = "Enhancements", "BUG" = "Bug Fixes", "COMP" = "Build Fixes", "DOC" = "Documentation", "PERF" = "Performance", "STYLE" = "Style" }
+change_type_order = ["Enhancements", "Bug Fixes", "Build Fixes", "Performance", "Documentation", "Style"]
+info = """
+ITK commit message convention: PREFIX: Description
+
+Valid prefixes:
+ BUG: a bug fix
+ COMP: a compilation/build fix
+ DOC: documentation changes
+ ENH: new feature or enhancement
+ PERF: performance improvement
+ STYLE: code style/formatting (no logic change)
+"""
+
+[[tool.commitizen.customize.questions]]
+type = "list"
+name = "change_type"
+message = "Select the type of change:"
+choices = [
+ { value = "ENH", name = "ENH: A new feature or enhancement", key = "e" },
+ { value = "BUG", name = "BUG: A bug fix", key = "b" },
+ { value = "COMP", name = "COMP: A compilation/build fix", key = "c" },
+ { value = "DOC", name = "DOC: Documentation changes", key = "d" },
+ { value = "PERF", name = "PERF: A performance improvement", key = "p" },
+ { value = "STYLE", name = "STYLE: Code style/formatting (no logic change)", key = "s" },
+]
+
+[[tool.commitizen.customize.questions]]
+type = "input"
+name = "message"
+message = "Commit description (start with capital letter):"
diff --git a/requirements-dev.txt b/requirements-dev.txt
deleted file mode 100644
index 5fac7875..00000000
--- a/requirements-dev.txt
+++ /dev/null
@@ -1,6 +0,0 @@
-ninja==1.11.1.1
-scikit-build-core==0.10.7
-build==1.2.1
-pyproject-metadata
-pathspec
-setuptools_scm==8.1.0
diff --git a/scripts/BuildManager.py b/scripts/BuildManager.py
new file mode 100644
index 00000000..a7fd9942
--- /dev/null
+++ b/scripts/BuildManager.py
@@ -0,0 +1,134 @@
+import json
+import time
+from datetime import datetime
+from pathlib import Path
+
+
+class BuildManager:
+ """Manage a JSON build report for multistep runs.
+
+ Persists status and timing for each named step to a JSON file.
+ Steps already marked ``"done"`` are skipped on subsequent runs,
+ enabling resumable builds.
+
+ Parameters
+ ----------
+ report_path : Path
+ Path to the JSON report file (created if absent).
+ step_names : list[str]
+ Ordered names of build steps to track.
+
+ Attributes
+ ----------
+ report : dict
+ In-memory report structure with ``created_at``, ``updated_at``,
+ and ``steps`` keys.
+ """
+
+ def __init__(self, report_path: Path, step_names: list[str]):
+ self.report_path = Path(report_path)
+ self._init_structure(step_names)
+ self._load_if_exists()
+
+ # ---- Public API ----
+ def run_step(self, step_name: str, func, force_rerun=False) -> None:
+ """Execute a build step, recording timing and status.
+
+ Parameters
+ ----------
+ step_name : str
+ Key identifying the step in the report.
+ func : callable
+ Zero-argument callable that performs the step's work.
+ force_rerun : bool, optional
+ If True, re-execute even when the step is already ``"done"``.
+
+ Raises
+ ------
+ Exception
+ Re-raises any exception thrown by *func* after recording
+ the failure in the report.
+ """
+ entry = self.report["steps"].setdefault(step_name, self._new_step_entry())
+ if entry.get("status") == "done" and not force_rerun:
+ # Already completed in a previous run; skip
+ return
+
+ # Mark start
+ entry["status"] = "running"
+ entry["started_at"] = self._now()
+ self.report["updated_at"] = entry["started_at"]
+ self.save()
+
+ start = time.perf_counter()
+ try:
+ func()
+ except Exception as e:
+ # Record failure and re-raise
+ entry["status"] = "failed"
+ entry["finished_at"] = self._now()
+ entry["duration_sec"] = round(time.perf_counter() - start, 3)
+ entry["error"] = f"{type(e).__name__}: {e}"
+ self.report["updated_at"] = entry["finished_at"]
+ self.save()
+ raise
+ else:
+ # Record success
+ entry["status"] = "done"
+ entry["finished_at"] = self._now()
+ entry["duration_sec"] = round(time.perf_counter() - start, 3)
+ self.report["updated_at"] = entry["finished_at"]
+ self.save()
+
+ def save(self) -> None:
+ """Write the current report to disk atomically."""
+ self.report_path.parent.mkdir(parents=True, exist_ok=True)
+ tmp = self.report_path.with_suffix(self.report_path.suffix + ".tmp")
+ with open(tmp, "w", encoding="utf-8") as f:
+ json.dump(self.report, f, indent=2, sort_keys=True)
+ tmp.replace(self.report_path)
+
+ # ---- Internal helpers ----
+ def _init_structure(self, step_names: list[str]) -> None:
+ steps = {name: self._new_step_entry() for name in step_names}
+ now = self._now()
+ self.report = {
+ "created_at": now,
+ "updated_at": now,
+ "steps": steps,
+ }
+
+ def _load_if_exists(self) -> None:
+ if not self.report_path.exists():
+ return
+ try:
+ with open(self.report_path, encoding="utf-8") as f:
+ existing = json.load(f)
+ # Merge existing with current set of steps, preserving statuses
+ existing_steps = existing.get("steps", {})
+ for name in self.report["steps"].keys():
+ if name in existing_steps:
+ self.report["steps"][name] = existing_steps[name]
+ # Bring over timestamps
+ self.report["created_at"] = existing.get(
+ "created_at", self.report["created_at"]
+ )
+ self.report["updated_at"] = existing.get(
+ "updated_at", self.report["updated_at"]
+ )
+ except Exception as e:
+ # Corrupt or unreadable file; keep freshly initialized structure
+ raise RuntimeError(f"Failed to load build report: {e}") from e
+
+ @staticmethod
+ def _now() -> str:
+ return datetime.now().isoformat(timespec="seconds")
+
+ @staticmethod
+ def _new_step_entry() -> dict:
+ return {
+ "status": "pending",
+ "started_at": None,
+ "finished_at": None,
+ "duration_sec": None,
+ }
diff --git a/scripts/build_python_instance_base.py b/scripts/build_python_instance_base.py
new file mode 100644
index 00000000..fd5d3763
--- /dev/null
+++ b/scripts/build_python_instance_base.py
@@ -0,0 +1,1467 @@
+import copy
+import os
+import shutil
+import subprocess
+import sys
+from abc import ABC, abstractmethod
+from collections import OrderedDict
+from collections.abc import Callable
+from os import environ
+from pathlib import Path
+
+from BuildManager import BuildManager
+from cmake_argument_builder import CMakeArgumentBuilder
+from pyproject_configure import configure_one_pyproject_file
+from wheel_builder_utils import (
+ _remove_tree,
+ _which,
+ get_default_platform_build,
+ run_commandLine_subprocess,
+)
+
+
+class BuildPythonInstanceBase(ABC):
+ """Abstract base class to build wheels for a single Python environment.
+
+ Concrete subclasses implement platform-specific details (environment
+ setup, wheel fixup, tarball creation) while this class provides the
+ shared build orchestration, CMake configuration, and wheel-building
+ logic.
+
+ Parameters
+ ----------
+ platform_env : str
+ Platform/environment identifier (e.g. ``'manylinux228-py311'``).
+ build_dir_root : Path
+ Root directory for all build artifacts.
+ package_env_config : dict
+ Mutable configuration dictionary populated throughout the build.
+ cleanup : bool
+ Whether to remove intermediate build artifacts.
+ build_itk_tarball_cache : bool
+ Whether to create a reusable tarball of the ITK build tree.
+ cmake_options : list[str]
+ Extra ``-D`` options forwarded to CMake.
+ windows_extra_lib_paths : list[str]
+ Additional library paths for Windows wheel fixup (delvewheel).
+ dist_dir : Path
+ Output directory for built wheel files.
+ module_source_dir : Path, optional
+ Path to an external ITK remote module to build.
+ module_dependencies_root_dir : Path, optional
+ Directory where remote module dependencies are cloned.
+ itk_module_deps : str, optional
+ Colon-delimited dependency specifications for remote modules.
+ skip_itk_build : bool, optional
+ Skip the ITK C++ build step.
+ skip_itk_wheel_build : bool, optional
+ Skip the ITK wheel build step.
+ """
+
+ def __init__(
+ self,
+ *,
+ platform_env,
+ build_dir_root,
+ package_env_config: dict,
+ cleanup: bool,
+ build_itk_tarball_cache: bool,
+ cmake_options: list[str],
+ windows_extra_lib_paths: list[str],
+ dist_dir: Path,
+ module_source_dir: Path | None = None,
+ module_dependencies_root_dir: Path | None = None,
+ itk_module_deps: str | None = None,
+ skip_itk_build: bool | None = None,
+ skip_itk_wheel_build: bool | None = None,
+ ) -> None:
+ self.build_node_cpu_count: int = os.cpu_count() or 1
+ self.platform_env = platform_env
+ self.ipp_dir = Path(__file__).parent.parent
+
+ self.build_dir_root = build_dir_root
+ self.cmake_itk_source_build_configurations: CMakeArgumentBuilder = (
+ CMakeArgumentBuilder()
+ )
+ self.cmake_compiler_configurations: CMakeArgumentBuilder = (
+ CMakeArgumentBuilder()
+ )
+ # TODO: Partial refactoring cleanup later
+ package_env_config["IPP_SOURCE_DIR"] = self.ipp_dir
+ IPP_BuildWheelsSupport_DIR: Path = self.ipp_dir / "BuildWheelsSupport"
+ package_env_config["IPP_BuildWheelsSupport_DIR"] = IPP_BuildWheelsSupport_DIR
+
+ self.package_env_config = package_env_config
+
+ # declare this dict before self.prepare_build_env() or dict will be empty in later functions
+ self.venv_info_dict = {
+ # Filled in for each platform and each pyenvs
+ # "python_executable": None,
+ # "python_include_dir": None,
+ # "python_library": None,
+ # "venv_bin_path": None,
+ # "venv_base_dir": None,
+ }
+
+ with open(
+ IPP_BuildWheelsSupport_DIR / "WHEEL_NAMES.txt",
+ encoding="utf-8",
+ ) as content:
+ self.wheel_names = [
+ wheel_name.strip() for wheel_name in content.readlines()
+ ]
+ del package_env_config
+
+ self.cleanup = cleanup
+ self.build_itk_tarball_cache = build_itk_tarball_cache
+ self.cmake_options = cmake_options
+ self.windows_extra_lib_paths = windows_extra_lib_paths
+ self.dist_dir = dist_dir
+ # Needed for processing remote modules and their dependencies
+ self.module_source_dir: Path = (
+ Path(module_source_dir) if module_source_dir else None
+ )
+ self.module_dependencies_root_dir: Path = (
+ Path(module_dependencies_root_dir) if module_dependencies_root_dir else None
+ )
+ self.itk_module_deps = itk_module_deps
+ self.skip_itk_build = skip_itk_build
+ self.skip_itk_wheel_build = skip_itk_wheel_build
+ self.prepare_build_env()
+
+ self.package_env_config["BUILD_TYPE"] = "Release"
+ # Unified place to collect cmake -D definitions for this instance
+ self.cmake_cmdline_definitions: CMakeArgumentBuilder = CMakeArgumentBuilder()
+ # Seed from legacy cmake_options if provided as ['-D=', ...]
+ if cmake_options:
+ for opt in cmake_options:
+ if not opt.startswith("-D"):
+ continue
+ # Strip leading -D, split on first '=' into key and value
+ try:
+ key, value = opt[2:].split("=", 1)
+ except ValueError:
+ # Malformed option; skip to avoid breaking build
+ continue
+ # Preserve value verbatim (may contain quotes)
+ self.cmake_cmdline_definitions.set(key, value)
+
+ self.cmake_compiler_configurations.update(
+ {
+ "CMAKE_BUILD_TYPE:STRING": self.package_env_config["BUILD_TYPE"],
+ }
+ )
+ # Set cmake flags for the compiler if CC or CXX are specified
+ cxx_compiler: str = self.package_env_config.get("CXX", "")
+ if cxx_compiler != "":
+ self.cmake_compiler_configurations.set(
+ "CMAKE_CXX_COMPILER:STRING", cxx_compiler
+ )
+
+ c_compiler: str = self.package_env_config.get("CC", "")
+ if c_compiler != "":
+ self.cmake_compiler_configurations.set(
+ "CMAKE_C_COMPILER:STRING", c_compiler
+ )
+
+ if self.package_env_config.get("USE_CCACHE", "OFF") == "ON":
+ ccache_exe: Path = _which("ccache")
+ self.cmake_compiler_configurations.set(
+ "CMAKE_C_COMPILER_LAUNCHER:FILEPATH", f"{ccache_exe}"
+ )
+ self.cmake_compiler_configurations.set(
+ "CMAKE_CXX_COMPILER_LAUNCHER:FILEPATH", f"{ccache_exe}"
+ )
+
+ self.cmake_itk_source_build_configurations.update(
+ # ITK wrapping options
+ {
+ "ITK_SOURCE_DIR:PATH": f"{self.package_env_config['ITK_SOURCE_DIR']}",
+ "BUILD_TESTING:BOOL": "OFF",
+ "ITK_WRAP_unsigned_short:BOOL": "ON",
+ "ITK_WRAP_double:BOOL": "ON",
+ "ITK_WRAP_complex_double:BOOL": "ON",
+ "ITK_WRAP_IMAGE_DIMS:STRING": "2;3;4",
+ "WRAP_ITK_INSTALL_COMPONENT_IDENTIFIER:STRING": "PythonWheel",
+ "WRAP_ITK_INSTALL_COMPONENT_PER_MODULE:BOOL": "ON",
+ "PY_SITE_PACKAGES_PATH:PATH": ".",
+ "ITK_LEGACY_SILENT:BOOL": "ON",
+ "ITK_WRAP_PYTHON:BOOL": "ON",
+ "ITK_WRAP_DOC:BOOL": "ON",
+ "DOXYGEN_EXECUTABLE:FILEPATH": f"{self.package_env_config['DOXYGEN_EXECUTABLE']}",
+ "Module_ITKTBB:BOOL": self.package_env_config["USE_TBB"],
+ "TBB_DIR:PATH": self.package_env_config["TBB_DIR"],
+ # Python settings
+ "SKBUILD:BOOL": "ON",
+ }
+ )
+
+ def update_venv_itk_build_configurations(self) -> None:
+ """Set ``Python3_ROOT_DIR`` in ITK build configurations from venv info."""
+ # Python3_EXECUTABLE, Python3_INCLUDE_DIR, and Python3_LIBRARY are validated
+ # and resolved by find_package(Python3) in cmake/ITKPythonPackage_SuperBuild.cmake
+ # when not already defined. Python3_ROOT_DIR is set here to guide that search.
+ self.cmake_itk_source_build_configurations.set(
+ "Python3_ROOT_DIR:PATH", f"{self.venv_info_dict['python_root_dir']}"
+ )
+
+ def _detect_conda_itk(self) -> Path | None:
+ """Detect a pre-installed ITK from a conda/pixi environment.
+
+ Checks ``CONDA_PREFIX`` (or ``PIXI_ENVIRONMENT_DIR``) for an
+ installed ITK CMake config directory. When found, the superbuild
+ and C++ build steps can be skipped entirely.
+
+ Returns
+ -------
+ Path or None
+ Path to the ITK CMake config directory, or *None* if not found.
+ """
+ for env_var in ("CONDA_PREFIX", "PIXI_ENVIRONMENT_DIR"):
+ prefix = os.environ.get(env_var, "")
+ if not prefix:
+ continue
+ # Search for lib/cmake/ITK-* (version may vary)
+ cmake_dir = Path(prefix) / "lib" / "cmake"
+ if cmake_dir.is_dir():
+ for candidate in sorted(cmake_dir.glob("ITK-*")):
+ itk_config = candidate / "ITKConfig.cmake"
+ if itk_config.is_file():
+ print(
+ f"Detected conda-installed ITK at {candidate} "
+ f"(via ${env_var})"
+ )
+ return candidate
+ return None
+
+ def run(self) -> None:
+ """Run the full build flow for this Python instance."""
+ # Use BuildManager to persist and resume build steps
+
+ # HACK
+ if self.itk_module_deps:
+ self._build_module_dependencies()
+
+ # Check for conda/pixi-provided ITK (libitk-wrapping package)
+ conda_itk_dir = self._detect_conda_itk()
+ if conda_itk_dir is not None:
+ # Point the build at the pre-installed ITK — skip compilation
+ self.cmake_itk_source_build_configurations.set(
+ "ITK_DIR:PATH", str(conda_itk_dir)
+ )
+ # Set ITK_BINARY_DIR so wheel build and cleanup paths still resolve
+ self.cmake_itk_source_build_configurations.set(
+ "ITK_BINARY_DIR:PATH", str(conda_itk_dir)
+ )
+ print(
+ "Using conda-installed ITK; skipping superbuild and C++ build steps."
+ )
+
+ python_package_build_steps: OrderedDict[str, Callable] = OrderedDict(
+ {
+ "01_superbuild_support_components": self.build_superbuild_support_components,
+ "02_build_wrapped_itk_cplusplus": self.build_wrapped_itk_cplusplus,
+ "03_build_wheels": self.build_itk_python_wheels,
+ "04_post_build_fixup": self.post_build_fixup,
+ "05_final_import_test": self.final_import_test,
+ }
+ )
+
+ if conda_itk_dir is not None:
+ # Skip both superbuild and C++ build when using conda ITK
+ python_package_build_steps = OrderedDict(
+ (
+ (f"{k}_skipped", (lambda: None))
+ if k
+ in (
+ "01_superbuild_support_components",
+ "02_build_wrapped_itk_cplusplus",
+ )
+ else (k, v)
+ )
+ for k, v in python_package_build_steps.items()
+ )
+
+ if self.skip_itk_build:
+ # Skip these steps if we are in the CI environment
+ python_package_build_steps = OrderedDict(
+ (
+ ("02_build_wrapped_itk_cplusplus_skipped", (lambda: None))
+ if k == "02_build_wrapped_itk_cplusplus"
+ else (k, v)
+ )
+ for k, v in python_package_build_steps.items()
+ )
+ if self.skip_itk_wheel_build:
+ python_package_build_steps = OrderedDict(
+ (
+ ("03_build_wheels_skipped", (lambda: None))
+ if k == "03_build_wheels"
+ else (k, v)
+ )
+ for k, v in python_package_build_steps.items()
+ )
+
+ if self.module_source_dir is not None:
+ python_package_build_steps[
+ f"06_build_external_module_wheel_{self.module_source_dir.name}"
+ ] = self.build_external_module_python_wheel
+ else:
+ python_package_build_steps["06_build_external_module_wheel_skipped"] = (
+ lambda: None
+ )
+ if self.build_itk_tarball_cache:
+ python_package_build_steps[
+ f"07_build_itk_tarball_cache_{self.package_env_config['OS_NAME']}_{self.package_env_config['ARCH']}"
+ ] = self.build_tarball
+
+ self.dist_dir.mkdir(parents=True, exist_ok=True)
+ build_report_fn: Path = self.dist_dir / f"build_log_{self.platform_env}.json"
+ build_manager: BuildManager = BuildManager(
+ build_report_fn, list(python_package_build_steps.keys())
+ )
+ build_manager.save()
+ for build_step_name, build_step_func in python_package_build_steps.items():
+ print("=" * 80)
+ print(
+ f"Running build step: {build_step_name}: recording status in {build_report_fn}"
+ )
+ # always force_rerun of the tarball step if requested
+ build_manager.run_step(
+ build_step_name,
+ build_step_func,
+ force_rerun=("tarball_cache" in build_step_name),
+ )
+ build_manager.save()
+ print(
+ f"Build step {build_step_name} completed. Edit {build_report_fn} to rerun step."
+ )
+ print("=" * 80)
+
+ def build_superbuild_support_components(self):
+ """Configure and build the superbuild support components (ITK source, TBB)."""
+ # -----------------------------------------------------------------------
+ # Build required components (optional local ITK source, TBB builds) used to populate the archive cache
+
+ # Build up definitions using the builder
+ cmake_superbuild_argumets = CMakeArgumentBuilder()
+ if self.cmake_compiler_configurations:
+ cmake_superbuild_argumets.update(self.cmake_compiler_configurations.items())
+ # Add superbuild-specific flags
+ cmake_superbuild_argumets.update(
+ {
+ "ITKPythonPackage_BUILD_PYTHON:BOOL": "OFF",
+ "ITKPythonPackage_USE_TBB:BOOL": self.package_env_config["USE_TBB"],
+ "ITK_SOURCE_DIR:PATH": f"{self.package_env_config['ITK_SOURCE_DIR']}",
+ "ITK_GIT_TAG:STRING": f"{self.package_env_config['ITK_GIT_TAG']}",
+ }
+ )
+ # Start from any platform/user-provided defaults
+ if self.cmake_cmdline_definitions:
+ cmake_superbuild_argumets.update(self.cmake_cmdline_definitions.items())
+
+ cmd = [
+ self.package_env_config["CMAKE_EXECUTABLE"],
+ "-G",
+ "Ninja",
+ ]
+
+ cmd += cmake_superbuild_argumets.getCMakeCommandLineArguments()
+
+ cmd += [
+ "-S",
+ str(self.package_env_config["IPP_SOURCE_DIR"] / "SuperbuildSupport"),
+ "-B",
+ str(self.package_env_config["IPP_SUPERBUILD_BINARY_DIR"]),
+ ]
+
+ self.echo_check_call(cmd)
+ self.echo_check_call(
+ [
+ self.package_env_config["CMAKE_EXECUTABLE"],
+ "--build",
+ # "--load-average",
+ # str(self.build_node_cpu_count),
+ # "--parallel",
+ # str(self.build_node_cpu_count),
+ str(self.package_env_config["IPP_SUPERBUILD_BINARY_DIR"]),
+ ],
+ )
+
+ def fixup_wheels(self, lib_paths: str = ""):
+ """Apply platform-specific fixups to ``itk_core`` wheels for TBB linkage."""
+ # TBB library fix-up (applies to itk_core wheel)
+ tbb_wheel = "itk_core"
+ for wheel in (self.build_dir_root / "dist").glob(f"{tbb_wheel}*.whl"):
+ self.fixup_wheel(str(wheel), lib_paths)
+
+ def final_wheel_import_test(self, installed_dist_dir: Path):
+ """Install and smoke-test all ITK wheels from *installed_dist_dir*.
+
+ Parameters
+ ----------
+ installed_dist_dir : Path
+ Directory containing the built ``.whl`` files to install and
+ verify.
+ """
+ exit_status = self.echo_check_call(
+ [
+ self.package_env_config["PYTHON_EXECUTABLE"],
+ "-m",
+ "pip",
+ "install",
+ "itk",
+ "--no-cache-dir",
+ "--no-index",
+ "-f",
+ str(installed_dist_dir),
+ ]
+ )
+ if exit_status == 0:
+ print("Wheels successfully installed.")
+ else:
+ print(f"Failed to install wheels: {exit_status}")
+ # Basic imports
+ self.echo_check_call(
+ [self.package_env_config["PYTHON_EXECUTABLE"], "-c", "import itk;"]
+ )
+ self.echo_check_call(
+ [
+ self.package_env_config["PYTHON_EXECUTABLE"],
+ "-c",
+ "import itk; image = itk.Image[itk.UC, 2].New()",
+ ]
+ )
+ self.echo_check_call(
+ [
+ self.package_env_config["PYTHON_EXECUTABLE"],
+ "-c",
+ "import itkConfig; itkConfig.LazyLoading=False; import itk;",
+ ]
+ )
+ # Full doc tests
+ self.echo_check_call(
+ [
+ self.package_env_config["PYTHON_EXECUTABLE"],
+ str(
+ self.package_env_config["IPP_SOURCE_DIR"]
+ / "docs"
+ / "code"
+ / "test.py"
+ ),
+ ]
+ )
+ print("Documentation tests passed.")
+
+ def _pip_uninstall_itk_wildcard(self, python_executable: str | Path):
+ """Uninstall all installed packages whose name starts with 'itk'.
+
+ pip does not support shell-style wildcards directly for uninstall, so we:
+ - run 'pip list --format=freeze'
+ - collect package names whose normalized name starts with 'itk'
+ - call 'pip uninstall -y ' if any are found
+ """
+ python_executable = str(python_executable)
+ try:
+ proc = subprocess.run(
+ [python_executable, "-m", "pip", "list", "--format=freeze"],
+ check=True,
+ capture_output=True,
+ text=True,
+ )
+ except subprocess.CalledProcessError as e:
+ print(
+ f"Warning: failed to list packages with pip at {python_executable}: {e}"
+ )
+ return
+
+ packages = []
+ for line in proc.stdout.splitlines():
+ line = line.strip()
+ if not line or line.startswith("#"):
+ continue
+ # Formats like 'name==version' or 'name @ URL'
+ name = line.split("==")[0].split(" @ ")[0].strip()
+ if name.lower().startswith("itk"):
+ packages.append(name)
+
+ if packages:
+ print(f"Uninstalling existing ITK-related packages: {' '.join(packages)}")
+ # Use echo_check_call for consistent logging/behavior
+ self.echo_check_call(
+ [python_executable, "-m", "pip", "uninstall", "-y", *packages]
+ )
+
+ def find_unix_exectable_paths(
+ self,
+ venv_dir: Path,
+ ) -> tuple[str, str, str, str, str]:
+ """Resolve Python interpreter and virtualenv paths on Unix.
+
+ Parameters
+ ----------
+ venv_dir : Path
+ Root of the Python virtual environment.
+
+ Returns
+ -------
+ tuple[str, str, str, str, str]
+ ``(python_executable, python_include_dir, python_library,
+ venv_bin_path, venv_base_dir)``.
+
+ Raises
+ ------
+ FileNotFoundError
+ If the Python executable does not exist under *venv_dir*.
+ """
+ python_executable = venv_dir / "bin" / "python"
+ if not python_executable.exists():
+ raise FileNotFoundError(f"Python executable not found: {python_executable}")
+
+ # Compute Python include dir using sysconfig for the given interpreter
+ try:
+ python_include_dir = (
+ subprocess.check_output(
+ [
+ str(python_executable),
+ "-c",
+ "import sysconfig; print(sysconfig.get_paths()['include'])",
+ ],
+ text=True,
+ ).strip()
+ or ""
+ )
+ except Exception as e:
+ print(f"Failed to compute Python include dir: {e}\n defaulting to empty")
+ python_include_dir = ""
+
+ # modern CMake with Python3 can infer the library from executable; leave empty
+ python_library = ""
+
+ # Update PATH
+ venv_bin_path = venv_dir / "bin"
+ return (
+ str(python_executable),
+ str(python_include_dir),
+ str(python_library),
+ str(venv_bin_path),
+ str(venv_dir),
+ )
+
+ def clone(self):
+ """Return a deep copy of this instance for building a dependency.
+
+ Uses ``self.__class__`` so the returned object is the same concrete
+ subclass as the original (e.g. ``LinuxBuildPythonInstance``).
+ """
+ cls = self.__class__
+ new = cls.__new__(cls)
+ new.__dict__ = copy.deepcopy(self.__dict__)
+ return new
+
+ def venv_paths(self) -> None:
+ """Populate ``venv_info_dict`` from the pixi-managed Python interpreter.
+
+ Default Unix implementation shared by Linux and macOS. Windows
+ overrides this method with its own path conventions.
+ """
+ primary_python_base_dir = Path(
+ self.package_env_config["PYTHON_EXECUTABLE"]
+ ).parent.parent
+ (
+ python_executable,
+ python_include_dir,
+ python_library,
+ venv_bin_path,
+ venv_base_dir,
+ ) = self.find_unix_exectable_paths(primary_python_base_dir)
+ self.venv_info_dict = {
+ "python_executable": python_executable,
+ "python_include_dir": python_include_dir,
+ "python_library": python_library,
+ "venv_bin_path": venv_bin_path,
+ "venv_base_dir": venv_base_dir,
+ "python_root_dir": primary_python_base_dir,
+ }
+
+ @abstractmethod
+ def fixup_wheel(
+ self, filepath, lib_paths: str = "", remote_module_wheel: bool = False
+ ): # pragma: no cover - abstract
+ """Apply platform-specific wheel repairs (auditwheel, delocate, delvewheel).
+
+ Parameters
+ ----------
+ filepath : str
+ Path to the ``.whl`` file to fix.
+ lib_paths : str, optional
+ Additional library search paths (semicolon-delimited on Windows).
+ remote_module_wheel : bool, optional
+ True when fixing a wheel for an external remote module.
+ """
+ pass
+
+ @abstractmethod
+ def build_tarball(self):
+ """Create a compressed archive of the ITK build tree for caching."""
+ pass
+
+ def post_build_cleanup(self) -> None:
+ """Remove intermediate build artifacts, leaving ``dist/`` intact.
+
+ Actions:
+ - remove oneTBB-prefix (symlink or dir)
+ - remove ITKPythonPackage/, tools/, _skbuild/, build/
+ - remove top-level *.egg-info
+ - remove ITK-* build tree and tarballs
+ - if ITK_MODULE_PREQ is set, remove cloned module dirs
+ """
+ base = Path(self.package_env_config["IPP_SOURCE_DIR"])
+
+ def rm(tree_path: Path):
+ try:
+ _remove_tree(tree_path)
+ except Exception:
+ pass
+
+ # 1) unlink oneTBB-prefix if it's a symlink or file
+ tbb_prefix_dir = base / "oneTBB-prefix"
+ try:
+ if tbb_prefix_dir.is_symlink() or tbb_prefix_dir.is_file():
+ tbb_prefix_dir.unlink(missing_ok=True) # type: ignore[arg-type]
+ elif tbb_prefix_dir.exists():
+ rm(tbb_prefix_dir)
+ except Exception:
+ pass
+
+ # 2) standard build directories
+ for rel in ("ITKPythonPackage", "tools", "_skbuild", "build"):
+ rm(base / rel)
+
+ # 3) egg-info folders at top-level
+ for p in base.glob("*.egg-info"):
+ rm(p)
+
+ # 4) ITK build tree and tarballs
+ target_arch = self.package_env_config["ARCH"]
+ for p in base.glob(f"ITK-*-{self.package_env_config}_{target_arch}"):
+ rm(p)
+
+ # Tarballs
+ for p in base.glob(f"ITKPythonBuilds-{self.package_env_config}*.tar.zst"):
+ rm(p)
+
+ # 5) Optional module prerequisites cleanup (ITK_MODULE_PREQ)
+ # Format: "InsightSoftwareConsortium/ITKModuleA@v1.0:Kitware/ITKModuleB@sha"
+ itk_preq = self.package_env_config.get("ITK_MODULE_PREQ") or environ.get(
+ "ITK_MODULE_PREQ", ""
+ )
+ if itk_preq:
+ for entry in itk_preq.split(":"):
+ entry = entry.strip()
+ if not entry:
+ continue
+ try:
+ module_name = entry.split("@", 1)[0].split("/", 1)[1]
+ except Exception:
+ continue
+ rm(base / module_name)
+
+ @abstractmethod
+ def prepare_build_env(self) -> None: # pragma: no cover - abstract
+ """Set up platform-specific build environment and CMake configurations.
+
+ Must populate ``self.venv_info_dict``, configure TBB settings,
+ and set the ITK binary build directory in
+ ``self.cmake_itk_source_build_configurations``.
+ """
+ pass
+
+ @abstractmethod
+ def post_build_fixup(self) -> None: # pragma: no cover - abstract
+ """Run platform-specific post-build wheel fixups.
+
+ Called after all wheels are built but before the final import
+ test. Typically invokes ``fixup_wheel`` or ``fixup_wheels``.
+ """
+ pass
+
+ def final_import_test(self) -> None: # pragma: no cover
+ """Install and smoke-test the built wheels."""
+ self.final_wheel_import_test(installed_dist_dir=self.dist_dir)
+
+ @abstractmethod
+ def discover_python_venvs(
+ self, platform_os_name: str, platform_architechure: str
+ ) -> list[str]:
+ """Return available Python environment names for the given platform.
+
+ Parameters
+ ----------
+ platform_os_name : str
+ Operating system identifier.
+ platform_architechure : str
+ CPU architecture identifier.
+
+ Returns
+ -------
+ list[str]
+ Sorted list of discovered environment names.
+ """
+ pass
+
+ @staticmethod
+ def _update_module_itk_deps(pyproject_path: Path, itk_version: str) -> bool:
+ """Rewrite ITK dependency pins in a remote module's pyproject.toml.
+
+ Replaces hard-coded ITK sub-package version pins (e.g.
+ ``itk-io == 5.4.*``) with a pin matching the ITK version being
+ built against (e.g. ``itk-io >= 5.4``). This ensures that
+ wheels produced for ITK 6 can be installed alongside ITK 6
+ packages without pip dependency conflicts.
+
+ .. note:: Strategy 1 (build-time rewrite) — interim solution.
+
+ This approach rewrites the module's pyproject.toml on disk,
+ builds the wheel, then restores the original. It works today
+ with zero changes to remote modules but is inherently fragile
+ (regex-based, modifies the source tree).
+
+ **Plan to migrate to Strategy 3 (scikit-build-core dynamic
+ metadata provider):**
+
+ 1. Create a small installable package ``itk-build-metadata``
+ that implements the scikit-build-core dynamic metadata
+ provider interface (see scikit-build-core docs:
+ ``tool.scikit-build.metadata..provider``).
+
+ 2. The provider inspects the build environment at wheel-build
+ time to discover the ITK version — either from the
+ ``ITK_PACKAGE_VERSION`` env var (set by this build system),
+ from ``ITKConfig.cmake`` on ``CMAKE_PREFIX_PATH``, or from
+ an already-installed ``itk-core`` package.
+
+ 3. It emits the correct ``Requires-Dist`` entries (e.g.
+ ``itk-io >= 5.4``) into the wheel metadata without
+ touching ``pyproject.toml`` on disk at all.
+
+ 4. Remote modules opt in by declaring dynamic dependencies::
+
+ [project]
+ dynamic = ["dependencies"]
+
+ [tool.scikit-build.metadata.dependencies]
+ provider = "itk_build_metadata"
+ provider-path = "." # or from installed package
+
+ 5. Roll out incrementally: update ITKModuleTemplate first,
+ then migrate existing modules via the ``/update-itk-deps``
+ skill (in REMOTE_MODULES/.claude/skills/). Modules that
+ have not migrated continue to work via this Strategy 1
+ fallback, so both approaches coexist during the transition.
+
+ 6. Once all ~60 remote modules have adopted Strategy 3,
+ this method can be removed.
+
+ Parameters
+ ----------
+ pyproject_path : Path
+ Path to the module's ``pyproject.toml``.
+ itk_version : str
+ The ITK PEP 440 version string being built (e.g. ``6.0.0b2``).
+ Used to compute the minimum major version for the ``>=`` pin.
+
+ Returns
+ -------
+ bool
+ *True* if any dependency was rewritten.
+ """
+ import re
+
+ try:
+ import tomllib
+ except ModuleNotFoundError:
+ import tomli as tomllib # Python < 3.11
+
+ with open(pyproject_path, "rb") as f:
+ pyproject_data = tomllib.load(f)
+
+ # --- Strategy 3: module declares dynamic dependencies -----------------
+ dynamic_fields = (
+ pyproject_data.get("project", {}).get("dynamic", [])
+ )
+ if "dependencies" in dynamic_fields:
+ # The module has opted into dynamic dependency resolution.
+ # Set ITK_PACKAGE_VERSION in the environment so the
+ # scikit-build-core metadata provider (itk-build-metadata)
+ # can emit the correct Requires-Dist at build time.
+ os.environ["ITK_PACKAGE_VERSION"] = itk_version
+ print(
+ f"Strategy 3: {pyproject_path.name} declares "
+ f"dynamic=[\"dependencies\"]; set ITK_PACKAGE_VERSION="
+ f"{itk_version} for metadata provider"
+ )
+ return False # no file modification needed
+
+ # --- Strategy 1: build-time rewrite (fallback) ------------------------
+ text = pyproject_path.read_text(encoding="utf-8")
+
+ # Only rewrite ITK *base* sub-packages whose versions are tied to
+ # the ITK release. Remote module cross-deps (e.g.
+ # itk-meshtopolydata == 0.12.*) are versioned independently and
+ # must NOT be rewritten — flag them for manual review instead.
+ _ITK_BASE_PACKAGES = (
+ "itk-core",
+ "itk-numerics",
+ "itk-io",
+ "itk-filtering",
+ "itk-registration",
+ "itk-segmentation",
+ )
+ _base_pkg_alt = "|".join(re.escape(p) for p in _ITK_BASE_PACKAGES)
+ pattern = re.compile(
+ rf'"({_base_pkg_alt})\s*==\s*[\d]+\.[\d]+\.\*"'
+ )
+
+ # Warn about pinned remote-module cross-deps that may also need
+ # attention but should not be auto-rewritten.
+ cross_dep_pattern = re.compile(
+ r'"(itk-[a-z][a-z0-9-]*)\s*==\s*[\d]+\.[\d]+\.\*"'
+ )
+ for m in cross_dep_pattern.finditer(text):
+ pkg = m.group(1)
+ if pkg not in _ITK_BASE_PACKAGES:
+ print(
+ f" WARNING: {pyproject_path.name} pins remote module "
+ f"cross-dep {m.group(0)} — review manually"
+ )
+
+ # The minimum version floor is the MAJOR.MINOR of the ITK version
+ # being built. A wheel compiled against ITK 6.0 requires ITK >= 6.0
+ # at install time; one compiled against ITK 5.4 requires >= 5.4.
+ # The build system itself supports building against any ITK from
+ # v5.4 through the latest (v5.5, v6.0, v7.1, etc.) — the floor
+ # simply reflects which ITK the wheel was actually linked against.
+ parts = itk_version.split(".")
+ try:
+ min_floor = f"{parts[0]}.{parts[1]}"
+ except IndexError:
+ min_floor = itk_version
+
+ changed = False
+ def _replace(m: re.Match) -> str:
+ nonlocal changed
+ changed = True
+ pkg = m.group(1)
+ return f'"{pkg} >= {min_floor}"'
+
+ new_text = pattern.sub(_replace, text)
+ if changed:
+ pyproject_path.write_text(new_text, encoding="utf-8")
+ print(
+ f"Strategy 1: Updated ITK dependency pins in {pyproject_path} "
+ f"(>= {min_floor} for ITK {itk_version})"
+ )
+ return changed
+
+ def build_external_module_python_wheel(self):
+ """Build a wheel for an external ITK remote module via scikit-build-core."""
+ self.module_source_dir = Path(self.module_source_dir)
+ out_dir = self.module_source_dir / "dist"
+ out_dir.mkdir(parents=True, exist_ok=True)
+
+ # Dynamically update ITK dependency pins to match the version being built.
+ # Back up the original pyproject.toml so the working tree is restored
+ # after the wheel is produced.
+ module_pyproject = self.module_source_dir / "pyproject.toml"
+ pyproject_orig = module_pyproject.with_suffix(".toml.orig")
+ pyproject_whl = module_pyproject.with_suffix(".toml.whl")
+ deps_rewritten = False
+ if module_pyproject.is_file():
+ itk_ver = self.package_env_config.get("ITK_PACKAGE_VERSION", "")
+ if itk_ver:
+ shutil.copy2(module_pyproject, pyproject_orig)
+ deps_rewritten = self._update_module_itk_deps(
+ module_pyproject, itk_ver
+ )
+
+ # Ensure venv tools are first in PATH
+ py_exe = str(self.package_env_config["PYTHON_EXECUTABLE"]) # Python3_EXECUTABLE
+
+ # Compute Python include directory (Python3_INCLUDE_DIR)
+ py_include = self.venv_info_dict.get("python_include_dir", "")
+ if not py_include:
+ try:
+ py_include = (
+ subprocess.check_output(
+ [
+ py_exe,
+ "-c",
+ "import sysconfig; print(sysconfig.get_paths()['include'])",
+ ],
+ text=True,
+ ).strip()
+ or ""
+ )
+ except Exception:
+ py_include = ""
+
+ # Determine platform-specific settings (macOS)
+ config_settings: dict[str, str] = {}
+
+ # ITK build path for external modules: prefer configured ITK binary dir
+ itk_build_path = self.cmake_itk_source_build_configurations.get(
+ "ITK_BINARY_DIR:PATH",
+ "",
+ )
+
+ # wheel.py-api for stable ABI when Python >= 3.11
+ try:
+ py_minor = int(
+ subprocess.check_output(
+ [py_exe, "-c", "import sys; print(sys.version_info.minor)"],
+ text=True,
+ ).strip()
+ )
+ except Exception:
+ py_minor = 0
+ wheel_py_api = f"cp3{py_minor}" if py_minor >= 11 else ""
+
+ # Base build command
+ cmd = [
+ py_exe,
+ "-m",
+ "build",
+ "--verbose",
+ "--wheel",
+ "--outdir",
+ str(out_dir),
+ "--no-isolation",
+ "--skip-dependency-check",
+ f"--config-setting=cmake.build-type={self.package_env_config['BUILD_TYPE']}",
+ ]
+
+ # Collect scikit-build CMake definitions
+ defs = CMakeArgumentBuilder()
+ defs.update(self.cmake_compiler_configurations.items())
+ # Propagate macOS specific defines if any were set above
+ for k, v in config_settings.items():
+ defs.set(k, v)
+
+ # Required defines for external module build
+ if itk_build_path:
+ defs.set("ITK_DIR:PATH", str(itk_build_path))
+ defs.set("CMAKE_INSTALL_LIBDIR:STRING", "lib")
+ defs.set("WRAP_ITK_INSTALL_COMPONENT_IDENTIFIER:STRING", "PythonWheel")
+ defs.set("PY_SITE_PACKAGES_PATH:PATH", ".")
+ defs.set("BUILD_TESTING:BOOL", "OFF")
+ defs.set("Python3_EXECUTABLE:FILEPATH", py_exe)
+ if py_include:
+ defs.set("Python3_INCLUDE_DIR:PATH", py_include)
+
+ # Pass Python library paths when explicitly known (Windows)
+ py_library = self.venv_info_dict.get("python_library", "")
+ if py_library:
+ defs.set("Python3_LIBRARY:FILEPATH", str(py_library))
+ py_sabi_library = self.venv_info_dict.get("python_sabi_library", "")
+ if py_sabi_library:
+ defs.set("Python3_SABI_LIBRARY:FILEPATH", str(py_sabi_library))
+
+ # Allow command-line cmake -D overrides to win last
+ if self.cmake_cmdline_definitions:
+ defs.update(self.cmake_cmdline_definitions.items())
+
+ # Append all cmake.define entries to the build cmd
+ cmd += defs.getPythonBuildCommandLineArguments()
+
+ # Stable ABI setting if applicable
+ if wheel_py_api:
+ cmd += [f"--config-setting=wheel.py-api={wheel_py_api}"]
+
+ # Module source directory to build
+ cmd += [self.module_source_dir]
+
+ try:
+ self.echo_check_call(cmd)
+
+ # Post-process produced wheels (e.g., delocate on macOS x86_64)
+ for wheel in out_dir.glob("*.whl"):
+ self.fixup_wheel(str(wheel), remote_module_wheel=True)
+ finally:
+ # Restore original pyproject.toml so the working tree stays clean
+ if deps_rewritten and pyproject_orig.is_file():
+ shutil.copy2(module_pyproject, pyproject_whl)
+ shutil.move(str(pyproject_orig), str(module_pyproject))
+ print(
+ f"Restored {module_pyproject} "
+ f"(modified version saved as {pyproject_whl.name})"
+ )
+
+ def build_itk_python_wheels(self):
+ """Build all ITK Python wheels listed in ``WHEEL_NAMES.txt``."""
+ # Build wheels
+ for wheel_name in self.wheel_names:
+ print("#")
+ print(f"# Build ITK wheel {wheel_name} from {self.wheel_names}")
+ print("#")
+ # Configure pyproject.toml
+ wheel_configbuild_dir_root: Path = (
+ self.build_dir_root
+ / "wheelbuilds"
+ / f"{wheel_name}_{self.get_pixi_environment_name()}"
+ )
+ wheel_configbuild_dir_root.mkdir(parents=True, exist_ok=True)
+ configure_one_pyproject_file(
+ str(self.ipp_dir / "scripts"),
+ self.package_env_config,
+ wheel_configbuild_dir_root,
+ wheel_name,
+ )
+
+ # Generate wheel using
+ cmd = [
+ str(self.package_env_config["PYTHON_EXECUTABLE"]),
+ "-m",
+ "build",
+ "--verbose",
+ "--wheel",
+ "--outdir",
+ str(self.build_dir_root / "dist"),
+ "--no-isolation",
+ "--skip-dependency-check",
+ f"--config-setting=cmake.build-type={self.package_env_config['BUILD_TYPE']}",
+ f"--config-setting=cmake.source-dir={self.package_env_config['IPP_SOURCE_DIR'] / 'BuildWheelsSupport'}",
+ f"--config-setting=build-dir={wheel_configbuild_dir_root/'build'}",
+ ]
+ # Build scikit-build defines via builder
+ scikitbuild_cmdline_args = CMakeArgumentBuilder()
+ scikitbuild_cmdline_args.update(self.cmake_compiler_configurations.items())
+ scikitbuild_cmdline_args.update(
+ self.cmake_itk_source_build_configurations.items()
+ )
+ scikitbuild_cmdline_args.update(
+ {
+ "ITKPythonPackage_USE_TBB:BOOL": self.package_env_config["USE_TBB"],
+ "ITKPythonPackage_ITK_BINARY_REUSE:BOOL": "ON",
+ "ITKPythonPackage_WHEEL_NAME:STRING": f"{wheel_name}",
+ "DOXYGEN_EXECUTABLE:FILEPATH": f"{self.package_env_config['DOXYGEN_EXECUTABLE']}",
+ }
+ )
+
+ if (
+ self.cmake_cmdline_definitions
+ ): # Do last to override with command line items
+ scikitbuild_cmdline_args.update(self.cmake_cmdline_definitions.items())
+ # Append all cmake.define entries
+ cmd += scikitbuild_cmdline_args.getPythonBuildCommandLineArguments()
+ # The location of the generated pyproject.toml file
+ cmd += [wheel_configbuild_dir_root]
+ self.echo_check_call(cmd)
+
+ # Remove unnecessary files for building against ITK
+ if self.cleanup:
+ bp = Path(
+ self.cmake_itk_source_build_configurations["ITK_BINARY_DIR:PATH"]
+ )
+ for p in bp.rglob("*"):
+ if p.is_file() and p.suffix in [".cpp", ".xml", ".obj", ".o"]:
+ try:
+ p.unlink()
+ except OSError:
+ pass
+ _remove_tree(bp / "Wrapping" / "Generators" / "CastXML")
+
+ def build_wrapped_itk_cplusplus(self):
+ """Configure and build the ITK C++ libraries with Python wrapping."""
+ # Clean up previous invocations
+ if (
+ self.cleanup
+ and Path(
+ self.cmake_itk_source_build_configurations["ITK_BINARY_DIR:PATH"]
+ ).exists()
+ ):
+ _remove_tree(
+ Path(self.cmake_itk_source_build_configurations["ITK_BINARY_DIR:PATH"])
+ )
+
+ print("#")
+ print("# START-Build ITK C++")
+ print("#")
+
+ # Build ITK python
+ cmd = [
+ self.package_env_config["CMAKE_EXECUTABLE"],
+ "-G",
+ "Ninja",
+ ]
+ # Collect all -D definitions via builder
+ defs = CMakeArgumentBuilder()
+ defs.update(self.cmake_compiler_configurations.items())
+ defs.update(self.cmake_itk_source_build_configurations.items())
+ # NOTE Do cmake_cmdline_definitions last so they override internal defaults
+ defs.update(self.cmake_cmdline_definitions.items())
+ cmd += defs.getCMakeCommandLineArguments()
+ cmd += [
+ "-S",
+ self.package_env_config["ITK_SOURCE_DIR"],
+ "-B",
+ self.cmake_itk_source_build_configurations["ITK_BINARY_DIR:PATH"],
+ ]
+ self.echo_check_call(cmd)
+ self.echo_check_call(
+ [
+ self.package_env_config["NINJA_EXECUTABLE"],
+ f"-j{self.build_node_cpu_count}",
+ f"-l{self.build_node_cpu_count}",
+ "-C",
+ self.cmake_itk_source_build_configurations["ITK_BINARY_DIR:PATH"],
+ ]
+ )
+ print("# FINISHED-Build ITK C++")
+
+ def _build_module_dependencies(self):
+ """
+ Build prerequisite ITK external modules, mirroring the behavior of
+ the platform shell scripts that use the ITK_MODULE_PREQ environment.
+
+ Accepted formats in self.itk_module_deps (colon-delimited):
+ - "MeshToPolyData@v0.10.0" -> defaults to
+ "InsightSoftwareConsortium/ITKMeshToPolyData@v0.10.0"
+ - "InsightSoftwareConsortium/ITKMeshToPolyData@v0.10.0"
+
+ For each dependency, clone the repository, checkout the given tag,
+ invoke the platform download-cache-and-build script, then copy
+ headers and wrapping input files into the current module tree
+ (include/ and wrapping/), similar to the bash implementations.
+ """
+
+ if len(self.itk_module_deps) == 0:
+ return
+ print(f"Building module dependencies: {self.itk_module_deps}")
+ self.module_dependencies_root_dir.mkdir(parents=True, exist_ok=True)
+
+ # Normalize entries to "Org/Repo@Tag"
+ def _normalize(entry: str) -> str:
+ entry = entry.strip()
+ if not entry:
+ return ""
+ if "/" in entry:
+ # Already Org/Repo@Tag
+ return entry
+ # Short form: Name@Tag -> InsightSoftwareConsortium/ITKName@Tag
+ try:
+ name, tag = entry.split("@", 1)
+ except ValueError:
+ # If no tag, pass-through (unexpected)
+ return entry
+ repo = f"ITK{name}"
+ return f"InsightSoftwareConsortium/{repo}@{tag}"
+
+ # Ensure working directories exist
+ module_root = Path(self.module_source_dir).resolve()
+ include_dir = module_root / "include"
+ wrapping_dir = module_root / "wrapping"
+ include_dir.mkdir(parents=True, exist_ok=True)
+ wrapping_dir.mkdir(parents=True, exist_ok=True)
+
+ dep_entries = [e for e in (s for s in self.itk_module_deps.split(":")) if e]
+ normalized = [_normalize(e) for e in dep_entries]
+ normalized = [e for e in normalized if e]
+
+ # Build each dependency in order
+ for _current_entry, entry in enumerate(normalized):
+ if len(entry) == 0:
+ continue
+ print(f"Get dependency module information for {entry}")
+ org = entry.split("/", 1)[0]
+ repo_tag = entry.split("/", 1)[1]
+ repo = repo_tag.split("@", 1)[0]
+ tag = repo_tag.split("@", 1)[1] if "@" in repo_tag else ""
+
+ upstream = f"https://github.com/{org}/{repo}.git"
+ dependant_module_clone_dir = (
+ self.module_dependencies_root_dir / repo
+ if self.module_dependencies_root_dir
+ else module_root / repo
+ )
+ if not dependant_module_clone_dir.exists():
+ self.echo_check_call(
+ ["git", "clone", upstream, dependant_module_clone_dir]
+ )
+
+ # Checkout requested tag
+ self.echo_check_call(
+ [
+ "git",
+ "-C",
+ dependant_module_clone_dir,
+ "fetch",
+ "--all",
+ "--tags",
+ ]
+ )
+ if tag:
+ self.echo_check_call(
+ ["git", "-C", dependant_module_clone_dir, "checkout", tag]
+ )
+
+ if (dependant_module_clone_dir / "setup.py").exists():
+ msg: str = (
+ f"Old sci-kit-build with setup.py is no longer supported for {dependant_module_clone_dir} at {tag}"
+ )
+ raise RuntimeError(msg)
+
+ # Clone the current build environment and modify for the current module
+ dependent_module_build_setup = self.clone()
+ dependent_module_build_setup.module_source_dir = Path(
+ dependant_module_clone_dir
+ )
+ dependent_module_build_setup.itk_module_deps = None # Prevent recursion
+ dependent_module_build_setup.run()
+
+ # After building dependency, copy includes and wrapping files
+ # 1) Top-level include/* -> include/
+ dep_include = dependant_module_clone_dir / "include"
+ if dep_include.exists():
+ for src in dep_include.rglob("*"):
+ if src.is_file():
+ rel = src.relative_to(dep_include)
+ dst = include_dir / rel
+ dst.parent.mkdir(parents=True, exist_ok=True)
+ try:
+ shutil.copy2(src, dst)
+ except Exception:
+ pass
+
+ # 2) Any */build/*/include/* -> include/
+ for sub in dependant_module_clone_dir.rglob("*build*/**/include"):
+ if sub.is_dir():
+ for src in sub.rglob("*"):
+ if src.is_file():
+ rel = src.relative_to(sub)
+ dst = include_dir / rel
+ dst.parent.mkdir(parents=True, exist_ok=True)
+ try:
+ shutil.copy2(src, dst)
+ except Exception:
+ pass
+
+ # 3) Wrapping templates (*.in, *.init) -> wrapping/
+ dep_wrapping = dependant_module_clone_dir / "wrapping"
+ if dep_wrapping.exists():
+ for pattern in ("*.in", "*.init"):
+ for src in dep_wrapping.rglob(pattern):
+ if src.is_file():
+ dst = wrapping_dir / src.name
+ try:
+ shutil.copy2(src, dst)
+ except Exception:
+ pass
+
+ def create_posix_tarball(self):
+ """Create a compressed tarball of the ITK Python build tree.
+
+ Mirrors the historical scripts/*-build-tarball.sh behavior:
+ - zstd compress with options (-10 -T6 --long=31)
+
+ Warns if directory structure doesn't match expected layout for GitHub Actions.
+ """
+ arch_postfix: str = f"{self.package_env_config['ARCH']}"
+ # Fixup platform name for macOS, eventually need to standardize on macosx naming convention
+ platform_name: str = get_default_platform_build().split("-")[0]
+ tar_name: str = f"ITKPythonBuilds-{platform_name}-{arch_postfix}.tar"
+ itk_packaging_reference_dir = self.build_dir_root.parent
+
+ tar_path: Path = itk_packaging_reference_dir / tar_name
+ zst_path: Path = itk_packaging_reference_dir / f"{tar_name}.zst"
+
+ itk_resources_build_dir: Path = self.build_dir_root
+ ipp_source_dir: Path = self.package_env_config["IPP_SOURCE_DIR"]
+
+ # Validate directory structure and determine tarball strategy
+ issues = []
+
+ # Try to use relative paths first
+ try:
+ rel_build = itk_resources_build_dir.relative_to(itk_packaging_reference_dir)
+ rel_ipp = ipp_source_dir.relative_to(itk_packaging_reference_dir)
+ except ValueError:
+ # Fall back to absolute paths
+ rel_build = itk_resources_build_dir
+ rel_ipp = ipp_source_dir
+ itk_packaging_reference_dir = Path(
+ "/"
+ ) # Tar from root when using absolute paths
+
+ if itk_resources_build_dir.parent != ipp_source_dir.parent:
+ issues.append("Build and source dirs are not siblings")
+
+ if ipp_source_dir.name != "ITKPythonPackage":
+ issues.append(
+ f"Source dir is '{ipp_source_dir.name}', expected 'ITKPythonPackage'"
+ )
+
+ # Issue consolidated warning for compatibility issues
+ if issues:
+ print("\n" + "=" * 70)
+ print("WARNING: Tarball will NOT be compatible with GitHub Actions")
+ print("=" * 70)
+ for issue in issues:
+ print(f" * {issue}")
+ print(
+ "\nExpected structure: /{ITKPythonPackage, ITKPythonPackage-build}"
+ )
+ print(f"Current: Build={itk_resources_build_dir}")
+ print(f" Source={ipp_source_dir}")
+ print(
+ "\nTarball will be created for local reuse but may not work in CI/CD."
+ )
+ print("=" * 70 + "\n")
+
+ # Build tarball include paths
+ tarball_include_paths = [
+ str(rel_build),
+ str(rel_ipp),
+ ]
+
+ if tar_path.exists():
+ print(f"Removing existing tarball {tar_path}")
+ tar_path.unlink()
+ if zst_path.exists():
+ print(f"Removing existing zstd tarball {zst_path}")
+ zst_path.unlink()
+
+ # Create tarball
+ self.echo_check_call(
+ [
+ "tar",
+ "-C",
+ str(itk_packaging_reference_dir),
+ "-cf",
+ str(tar_path),
+ "--exclude=*.o",
+ "--exclude=*.whl", # Do not include built wheels
+ "--exclude=*/dist/*", # Do not include the dist whl output directory
+ "--exclude=*/wheelbuilds/*", # Do not include the wheelbuild support directory
+ "--exclude=*/__pycache__/*", # Do not include __pycache__
+ "--exclude=install_manifest_*.txt", # Do not include install manifest files
+ "--exclude=._*", # Exclude mac dot files
+ "--exclude=*/.git/*",
+ "--exclude=*/.idea/*",
+ "--exclude=*/.pixi/*",
+ "--exclude=*/castxml_inputs/*",
+ "--exclude=*/Wrapping/Modules/*",
+ *tarball_include_paths,
+ ]
+ )
+
+ # Compress with zstd
+ self.echo_check_call(
+ [
+ "zstd",
+ "-f",
+ "-10",
+ "-T6",
+ "--long=31",
+ str(tar_path),
+ "-o",
+ str(zst_path),
+ ]
+ )
+
+ print(f"Tarball created: {zst_path}")
+ if issues:
+ print("Compatibility warnings above - review before using in CI/CD")
+
+ def get_pixi_environment_name(self):
+ """Return the pixi environment name for this build instance.
+
+ The pixi environment name is the same as the platform_env and
+ is related to the environment setups defined in pixi.toml
+ in the root of this git directory that contains these scripts.
+ """
+ return self.platform_env
+
+ def echo_check_call(
+ self,
+ cmd: list[str | Path] | tuple[str | Path] | str | Path,
+ use_pixi_env: bool = True,
+ env=None,
+ **kwargs: dict,
+ ) -> int:
+ """Print the command, then run subprocess.check_call.
+
+ Parameters
+ ----------
+ cmd :
+ Command to execute, same as subprocess.check_call.
+ **kwargs :
+ Additional keyword arguments forwarded to subprocess.check_call.
+ """
+
+ pixi_environment: str = self.get_pixi_environment_name()
+ pixi_executable: Path = self.package_env_config["PIXI_EXECUTABLE"]
+ pixi_run_preamble: list[str] = []
+ pixi_run_dir: Path = self.ipp_dir
+ pixi_env: dict[str, str] = os.environ.copy()
+ if env is not None:
+ pixi_env.update(env)
+ pixi_env.update(
+ {
+ "PIXI_HOME": str(pixi_run_dir / ".pixi"),
+ }
+ )
+ # if self.pa == "windows":
+ # pixi_env.update(
+ # {
+ # "TEMP": "C:\Temp",
+ # "TMP": "C:\Temp",
+ # }
+ # )
+
+ if pixi_environment and use_pixi_env:
+ pixi_run_preamble = [
+ str(pixi_executable),
+ "run",
+ "-e",
+ pixi_environment,
+ "--",
+ ]
+
+ # convert all items to strings (i.e. Path() to str)
+ cmd = pixi_run_preamble + [str(c) for c in cmd]
+ # Prepare a friendly command-line string for display
+ try:
+ if isinstance(cmd, list | tuple):
+ display_cmd = " ".join(cmd)
+ else:
+ display_cmd = str(cmd)
+ except Exception as e:
+ display_cmd = f"{str(cmd)}\nERROR: {e}"
+ sys.exit(1)
+ print(f">>Start Running: cd {pixi_run_dir} && {display_cmd}")
+ print("^" * 60)
+ print(cmd)
+ print("^" * 60)
+ print(kwargs)
+ print("^" * 60)
+ process_completion_info: subprocess.CompletedProcess = (
+ run_commandLine_subprocess(cmd, env=pixi_env, cwd=pixi_run_dir, **kwargs)
+ )
+ cmd_return_status: int = process_completion_info.returncode
+ print("^" * 60)
+ print(f"< dict[str, str]:
+ """Collect GitHub Actions environment variables for remote module builds.
+
+ The following environment variables are defined by the
+ ``ITKRemoteModuleBuildTestPackageAction`` GitHub Action. Variables
+ marked *active* are read from the environment with a default
+ fallback; those marked *not used* are documented here for
+ cross-reference but are no longer consumed at runtime.
+
+ Environment Variables
+ ---------------------
+ ITK_PACKAGE_VERSION : str (active)
+ PEP 440 version string for ITK packages.
+ GitHub Action source: ``inputs.itk-wheel-tag``.
+ Default ``"auto"`` triggers automatic version computation.
+ ITKPYTHONPACKAGE_TAG : str (not used — GitHub Actions scripts only)
+ Git tag for ITKPythonPackage checkout.
+ GitHub Action source: ``inputs.itk-python-package-tag``.
+ ITKPYTHONPACKAGE_ORG : str (not used — GitHub Actions scripts only)
+ GitHub organization owning ITKPythonPackage.
+ GitHub Action source: ``inputs.itk-python-package-org``.
+ ITK_MODULE_PREQ : str (active)
+ Colon-delimited list of remote module dependencies.
+ GitHub Action source: ``inputs.itk-module-deps``.
+ CMAKE_OPTIONS : str (active)
+ Extra options forwarded to CMake.
+ GitHub Action source: ``inputs.cmake-options``.
+ MANYLINUX_PLATFORM : str (not used — computed internally)
+ Full manylinux platform string (e.g. ``"manylinux_2_28-x64"``).
+ GitHub Action source: ``matrix.manylinux-platform``.
+ MANYLINUX_VERSION : str (active)
+ Manylinux specification (e.g. ``"_2_28"``). Historically
+ computed as the first part of ``MANYLINUX_PLATFORM``.
+ TARGET_ARCH : str (not used — computed internally)
+ Target architecture (e.g. ``"x64"``). Historically computed
+ as the second part of ``MANYLINUX_PLATFORM``.
+ MACOSX_DEPLOYMENT_TARGET : str (active)
+ Minimum macOS version for wheel compatibility.
+ GitHub Action source: ``inputs.macosx-deployment-target``.
+ Default ``"10.7"`` is outdated but provides backward
+ compatibility.
+
+ Returns
+ -------
+ dict[str, str]
+ A mapping of active configuration keys to their values, sourced
+ from environment variables with sensible defaults.
+ """
+ env_defaults: dict[str, str] = {
+ "ITK_PACKAGE_VERSION": "auto",
+ "ITK_MODULE_PREQ": "",
+ "CMAKE_OPTIONS": "",
+ "MANYLINUX_VERSION": "",
+ "MACOSX_DEPLOYMENT_TARGET": "10.7",
+ }
+ return {key: os.environ.get(key, default) for key, default in env_defaults.items()}
+
+
+def in_pixi_env() -> bool:
+ """Check whether the process is running inside a pixi environment.
+
+ Returns
+ -------
+ bool
+ True if both ``PIXI_ENVIRONMENT_NAME`` and ``PIXI_PROJECT_ROOT``
+ are set in the environment.
+ """
+ return "PIXI_ENVIRONMENT_NAME" in os.environ and "PIXI_PROJECT_ROOT" in os.environ
+
+
+def get_effective_command_line(
+ parser: argparse.ArgumentParser, args: argparse.Namespace
+) -> str:
+ """Reconstruct a reproducible command line from parsed arguments.
+
+ Parameters
+ ----------
+ parser : argparse.ArgumentParser
+ The argument parser used to parse *args*.
+ args : argparse.Namespace
+ Parsed command-line arguments.
+
+ Returns
+ -------
+ str
+ A shell-safe command string suitable for logging or re-execution
+ inside a pixi environment.
+ """
+ pixi_executable: str = os.environ.get("PIXI_EXE", "pixi")
+ effective_command = [
+ pixi_executable,
+ "run",
+ "-e",
+ args.platform_env,
+ "--",
+ sys.executable,
+ sys.argv[0],
+ ]
+ for action in parser._actions:
+ if isinstance(action, argparse._HelpAction):
+ continue
+ dest = action.dest
+ value = getattr(args, dest, None)
+ if value is None:
+ continue
+ if action.option_strings:
+ option_string = action.option_strings[0]
+ if isinstance(action, argparse._StoreTrueAction):
+ if value:
+ effective_command.append(option_string)
+ elif isinstance(action, argparse._StoreFalseAction):
+ if not value:
+ effective_command.append(option_string)
+ else:
+ if isinstance(value, list):
+ if value:
+ effective_command.append(option_string)
+ effective_command.extend([str(v) for v in value])
+ else:
+ effective_command.append(option_string)
+ effective_command.append(str(value))
+ else:
+ if isinstance(value, list):
+ effective_command.extend([str(v) for v in value])
+ else:
+ effective_command.append(str(value))
+ return shlex.join(effective_command)
+
+
+def build_wheels_main() -> None:
+ """Entry point: parse arguments, configure, and run the wheel build."""
+ os_name, arch = detect_platform()
+ ipp_script_dir: Path = Path(__file__).parent
+ ipp_dir: Path = ipp_script_dir.parent
+ if (ipp_dir / ".pixi" / "bin").exists():
+ os.environ["PATH"] = (
+ str(ipp_dir / ".pixi" / "bin") + os.pathsep + os.environ["PATH"]
+ )
+
+ remote_module_build_dict = remotemodulebuildandtestaction()
+ parser = argparse.ArgumentParser(
+ description="Driver script to build ITK Python wheels."
+ )
+ parser.add_argument(
+ "--platform-env",
+ default=get_default_platform_build("py311"),
+ help=(
+ """A platform environment name or path:
+ linux-py310, linux-py311,
+ manylinux228-py310, manylinux228-py311,
+ windows-py310, windows-py311,
+ macosx-py310, macosx-py311
+ """
+ ),
+ )
+ parser.add_argument(
+ "--cleanup",
+ dest="cleanup",
+ action="store_true",
+ help="""
+ 'ITK_MODULE_NO_CLEANUP': Option to skip cleanup steps.
+ =1 <- Leave temporary build files in place after completion, 0 <- remove temporary build files
+ """,
+ )
+ parser.add_argument(
+ "--lib-paths",
+ nargs=1,
+ default="",
+ help=(
+ "Windows only: semicolon-delimited library directories for delvewheel to include in module wheel"
+ ),
+ )
+ _cmake_options_default = remote_module_build_dict["CMAKE_OPTIONS"]
+ parser.add_argument(
+ "cmake_options",
+ nargs="*",
+ default=shlex.split(_cmake_options_default) if _cmake_options_default else [],
+ help="Extra options to pass to CMake, e.g. -DBUILD_SHARED_LIBS:BOOL=OFF.\n"
+ " These will override defaults if duplicated",
+ )
+ parser.add_argument(
+ "--module-source-dir",
+ type=str,
+ default=None,
+ help="Path to the (remote) module source directory to build.",
+ )
+ parser.add_argument(
+ "--module-dependencies-root-dir",
+ type=str,
+ default=None,
+ help="Path to the root directory for module dependencies.\n"
+ + "This is the path where a remote module dependencies (other remote modules)\n"
+ + "are searched for, or automatically git cloned to.",
+ )
+ parser.add_argument(
+ "--itk-module-deps",
+ type=str,
+ default=remote_module_build_dict["ITK_MODULE_PREQ"],
+ help="Semicolon-delimited list of a remote modules dependencies.\n"
+ + "'gitorg/repo@tag:gitorg/repo@tag:gitorg/repo@tag'\n"
+ + "These are set in ITKRemoteModuleBuildTestPackageAction:itk-module-deps github actions."
+ + "and were historically set as an environment variable ITK_MODULE_PREQ.",
+ )
+
+ parser.add_argument(
+ "--build-itk-tarball-cache",
+ dest="build_itk_tarball_cache",
+ action="store_true",
+ default=False,
+ help="Build an uploadable tarball. The tarball can be used as a cache for remote module builds.",
+ )
+ parser.add_argument(
+ "--no-build-itk-tarball-cache",
+ dest="build_itk_tarball_cache",
+ action="store_false",
+ help="Do not build an uploadable tarball. The tarball can be used as a cache for remote module builds.",
+ )
+
+ # set the default build_dir_root to a very short path on Windows to avoid path too long errors
+ default_build_dir_root = (
+ ipp_dir.parent / "ITKPythonPackage-build"
+ if os_name != "windows"
+ else Path("C:/") / "BDR"
+ )
+ parser.add_argument(
+ "--build-dir-root",
+ type=str,
+ default=f"{default_build_dir_root}",
+ help="The root of the build resources.",
+ )
+ parser.add_argument(
+ "--manylinux-version",
+ type=str,
+ default=remote_module_build_dict["MANYLINUX_VERSION"],
+ help="default manylinux version (_2_28, _2_34, ...), if empty, build native linux instead of cross compiling",
+ )
+
+ parser.add_argument(
+ "--itk-git-tag",
+ type=str,
+ default=os.environ.get(
+ "ITK_GIT_TAG", os.environ.get("ITK_PACKAGE_VERSION", "main")
+ ),
+ help="""
+ - 'ITK_GIT_TAG': Tag/branch/hash for the ITK source code to use in packaging.
+ Which ITK git tag/hash/branch to use as reference for building wheels/modules
+ https://github.com/InsightSoftwareConsortium/ITK.git@${ITK_GIT_TAG}
+ Examples: v5.4.0, v5.2.1.post1, 0ffcaed12552, my-testing-branch
+ See available release tags at https://github.com/InsightSoftwareConsortium/ITKPythonBuilds/tags
+ """,
+ )
+
+ # set the default build_dir_root to a very short path on Windows to avoid path too long errors
+ default_itk_source_dir = (
+ ipp_dir.parent / "ITKPythonPackage-build" / "ITK"
+ if os_name != "windows"
+ else Path("C:/") / "BDR" / "ITK"
+ )
+ parser.add_argument(
+ "--itk-source-dir",
+ type=str,
+ default=os.environ.get("ITK_SOURCE_DIR", str(default_itk_source_dir)),
+ help="""
+ - 'ITK_SOURCE_DIR': When building different 'flavor' of ITK python packages
+ on a given platform, explicitly setting the ITK_SOURCE_DIR options allow to
+ speed up source-code downloads by re-using an existing repository.
+ If the requested directory does not exist, manually clone and checkout ${ITK_GIT_TAG}""",
+ )
+
+ parser.add_argument(
+ "--itk-package-version",
+ type=str,
+ default=remote_module_build_dict["ITK_PACKAGE_VERSION"],
+ help="""
+ - 'ITK_PACKAGE_VERSION' A valid PEP440 version string for the itk packages generated.
+ The default is to automatically generate a PEP440 version automatically based on relative
+ versioning from the latest tagged release.
+ (in github action ITKRemoteModuleBuildTestPackage itk-wheel-tag is used to set this value)
+ """,
+ )
+
+ if os_name == "darwin":
+ parser.add_argument(
+ "--macosx-deployment-target",
+ type=str,
+ default=remote_module_build_dict["MACOSX_DEPLOYMENT_TARGET"],
+ help="""
+ The MacOSX deployment target to use for building wheels.
+ """,
+ )
+
+ parser.add_argument(
+ "--use-sudo",
+ action="store_true",
+ dest="use_sudo",
+ default=False,
+ help="""
+ - Enable if running docker requires sudo privileges
+ """,
+ )
+ parser.add_argument(
+ "--no-use-sudo",
+ action="store_false",
+ dest="use_sudo",
+ help="""
+ - Enable if running docker requires sudo privileges
+ """,
+ )
+
+ parser.add_argument(
+ "--use-ccache",
+ action="store_true",
+ dest="use_ccache",
+ default=False,
+ help="""
+ - Option to indicate that ccache should be used
+ """,
+ )
+ parser.add_argument(
+ "--no-use-ccache",
+ action="store_false",
+ dest="use_ccache",
+ help="""
+ - Option to indicate that ccache should not be used
+ """,
+ )
+
+ parser.add_argument(
+ "--skip-itk-build",
+ action="store_true",
+ dest="skip_itk_build",
+ default=False,
+ help="""
+ - Option to skip the ITK C++ build step (Step 2)
+ """,
+ )
+
+ parser.add_argument(
+ "--no-skip-itk-build",
+ action="store_false",
+ dest="skip_itk_build",
+ help="""
+ - Option to not skip the ITK C++ build step (Step 2)
+ """,
+ )
+
+ parser.add_argument(
+ "--skip-itk-wheel-build",
+ action="store_true",
+ dest="skip_itk_wheel_build",
+ default=False,
+ help="""
+ - Option to skip the ITK wheel build step (Step 3)
+ """,
+ )
+
+ parser.add_argument(
+ "--no-skip-itk-wheel-build",
+ action="store_false",
+ dest="skip_itk_wheel_build",
+ help="""
+ - Option to not skip the ITK wheel build step (Step 3)
+ """,
+ )
+
+ args = parser.parse_args()
+
+ # Historical dist_dir name for compatibility with ITKRemoteModuleBuildTestPackageAction
+ _ipp_dir_path: Path = Path(__file__).resolve().parent.parent
+ dist_dir: Path = Path(args.build_dir_root) / "dist"
+
+ # Platform detection
+ binary_ext: str = ".exe" if os_name == "windows" else ""
+ env_bin_dir: str = "Scripts" if os_name == "windows" else "bin"
+
+ env_path = _ipp_dir_path / ".pixi" / "envs" / args.platform_env
+ # multiple locations the executables can be at on Windows
+ env_subdirs = (
+ [env_bin_dir, "Library/bin"] if os_name == "windows" else [env_bin_dir]
+ )
+
+ os.environ["PATH"] = os.pathsep.join(
+ [
+ *[str(env_path / d) for d in env_subdirs],
+ str(_ipp_dir_path / ".pixi" / "bin"),
+ os.environ.get("PATH", ""),
+ ]
+ )
+ pixi_exec_path: Path = _which("pixi" + binary_ext)
+ package_env_config: dict[str, str | Path | None] = {}
+
+ args.build_dir_root = Path(args.build_dir_root)
+ if str(args.build_dir_root) != str(default_build_dir_root) and str(
+ args.itk_source_dir
+ ) == str(default_itk_source_dir):
+ args.itk_source_dir = args.build_dir_root / "ITK"
+
+ args.itk_source_dir = Path(args.itk_source_dir)
+ package_env_config["ITK_SOURCE_DIR"] = Path(args.itk_source_dir)
+
+ ipp_superbuild_binary_dir: Path = args.build_dir_root / "build" / "ITK-support-bld"
+ package_env_config["IPP_SUPERBUILD_BINARY_DIR"] = ipp_superbuild_binary_dir
+
+ package_env_config["OS_NAME"] = os_name
+ package_env_config["ARCH"] = arch
+
+ # ITK repo handling
+
+ if not Path(args.itk_source_dir).exists():
+ args.itk_source_dir.parent.mkdir(parents=True, exist_ok=True)
+ print(f"Cloning ITK into {args.itk_source_dir}...")
+ run_result = run_commandLine_subprocess(
+ [
+ "git",
+ "clone",
+ "https://github.com/InsightSoftwareConsortium/ITK.git",
+ str(args.itk_source_dir),
+ ],
+ cwd=_ipp_dir_path,
+ env=os.environ.copy(),
+ )
+ if run_result.returncode != 0:
+ raise RuntimeError(f"Failed to clone ITK: {run_result.stderr}")
+
+ run_commandLine_subprocess(
+ ["git", "fetch", "--tags", "origin"],
+ cwd=args.itk_source_dir,
+ env=os.environ.copy(),
+ )
+ try:
+ run_commandLine_subprocess(
+ ["git", "checkout", args.itk_git_tag],
+ cwd=args.itk_source_dir,
+ env=os.environ.copy(),
+ )
+ except subprocess.CalledProcessError:
+ print(f"WARNING: Failed to checkout {args.itk_git_tag}, reverting to 'main':")
+ run_commandLine_subprocess(
+ ["git", "checkout", "main"],
+ cwd=args.itk_source_dir,
+ env=os.environ.copy(),
+ )
+
+ if (
+ args.itk_package_version == "auto"
+ or args.itk_package_version is None
+ or len(args.itk_package_version) == 0
+ ):
+ args.itk_package_version = os.environ.get(
+ "ITK_PACKAGE_VERSION",
+ compute_itk_package_version(
+ args.itk_source_dir, args.itk_git_tag, pixi_exec_path, os.environ
+ ),
+ )
+
+ # ITKPythonPackage origin/tag
+ # NO_SUDO, ITK_MODULE_NO_CLEANUP, USE_CCACHE
+ no_sudo = os.environ.get("NO_SUDO", "0")
+ module_no_cleanup = os.environ.get("ITK_MODULE_NO_CLEANUP", "1")
+ use_ccache = os.environ.get("USE_CCACHE", "0")
+
+ package_env_config["BUILD_DIR_ROOT"] = str(args.build_dir_root)
+ package_env_config["ITK_GIT_TAG"] = args.itk_git_tag
+ package_env_config["ITK_SOURCE_DIR"] = args.itk_source_dir
+ package_env_config["ITK_PACKAGE_VERSION"] = args.itk_package_version
+ if os_name == "darwin":
+ package_env_config["MACOSX_DEPLOYMENT_TARGET"] = args.macosx_deployment_target
+ else:
+ package_env_config["MACOSX_DEPLOYMENT_TARGET"] = "RELEVANT_FOR_MACOS_ONLY"
+ package_env_config["ITK_MODULE_PREQ"] = args.itk_module_deps
+ package_env_config["NO_SUDO"] = no_sudo
+ package_env_config["ITK_MODULE_NO_CLEANUP"] = module_no_cleanup
+ package_env_config["USE_CCACHE"] = use_ccache
+ package_env_config["PIXI_EXECUTABLE"] = _which("pixi")
+ package_env_config["CMAKE_EXECUTABLE"] = _which("cmake")
+ package_env_config["NINJA_EXECUTABLE"] = _which("ninja")
+ package_env_config["DOXYGEN_EXECUTABLE"] = _which("doxygen")
+ package_env_config["GIT_EXECUTABLE"] = _which("git")
+
+ # reliably find the python executable in pixi
+ cmd = [
+ package_env_config["PIXI_EXECUTABLE"],
+ "run",
+ "-e",
+ args.platform_env,
+ "python",
+ "-c",
+ "import sys; print(sys.executable)",
+ ]
+ package_env_config["PYTHON_EXECUTABLE"] = run_commandLine_subprocess(
+ cmd, env=os.environ.copy()
+ ).stdout.strip()
+
+ oci_exe = resolve_oci_exe(os.environ.copy())
+ package_env_config["OCI_EXE"] = oci_exe
+ del oci_exe
+
+ # -------------
+ platform = package_env_config["OS_NAME"].lower()
+ if platform == "windows":
+ from windows_build_python_instance import WindowsBuildPythonInstance
+
+ builder_cls = WindowsBuildPythonInstance
+ elif platform in ("darwin", "mac", "macos", "macosx", "osx"):
+ from macos_build_python_instance import MacOSBuildPythonInstance
+
+ builder_cls = MacOSBuildPythonInstance
+ elif platform == "linux":
+ from linux_build_python_instance import LinuxBuildPythonInstance
+
+ # Manylinux/docker bits for Linux
+ target_arch = os.environ.get("TARGET_ARCH") or arch
+
+ manylinux_version: str = args.manylinux_version
+ if manylinux_version and len(manylinux_version) > 0:
+ if (
+ os.environ.get("MANYLINUX_VERSION", manylinux_version)
+ != manylinux_version
+ ):
+ print(
+ f"WARNING: environment variable MANYLINUX_VERSION={manylinux_version} is changed to command line value of {manylinux_version}."
+ )
+ package_env_config["MANYLINUX_VERSION"] = manylinux_version
+ image_tag, manylinux_image_name, container_source = default_manylinux(
+ manylinux_version, os_name, target_arch, os.environ.copy()
+ )
+ package_env_config["IMAGE_TAG"] = image_tag
+ package_env_config["MANYLINUX_IMAGE_NAME"] = manylinux_image_name
+ package_env_config["CONTAINER_SOURCE"] = container_source
+ package_env_config["TARGET_ARCH"] = target_arch
+
+ # Native builds without dockcross need a separate dist dir to avoid conflicts with manylinux
+ # dist_dir = IPP_SOURCE_DIR / f"{platform}_dist"
+ # For the aarch64 manylinux builds, the CROSS_TRIPLE environment variable is unset
+ if os.environ.get("CROSS_TRIPLE", None) is None and target_arch not in (
+ "arm64",
+ "aarch64",
+ ):
+ msg: str = (
+ f"ERROR: MANYLINUX_VERSION={manylinux_version} and TARGET_ARCH={target_arch} but not building in dockcross."
+ )
+ raise RuntimeError(msg)
+
+ builder_cls = LinuxBuildPythonInstance
+ else:
+ raise ValueError(f"Unknown platform {platform}")
+
+ print("=" * 80)
+ print("=" * 80)
+ print("= Building Wheels with effective command line")
+ print("\n\n")
+ cmdline: str = f"{get_effective_command_line(parser, args)}"
+ args.build_dir_root.mkdir(parents=True, exist_ok=True)
+ with open(
+ args.build_dir_root / f"effective_cmdline_{args.platform_env}.sh", "w"
+ ) as f:
+ f.write("#!/bin/bash\n")
+ f.write(
+ "# Generated by build_wheels.py as documentation for describing how these wheels were created.\n"
+ )
+ f.write(cmdline)
+ f.write("\n")
+ print(f"cmdline: {cmdline}")
+ print("\n\n\n\n")
+ print("=" * 80)
+ print("=" * 80)
+ print(f"Building wheels for platform: {args.platform_env}")
+ # Pass helper function callables and dist dir to avoid circular imports
+ builder = builder_cls(
+ platform_env=args.platform_env,
+ build_dir_root=args.build_dir_root,
+ package_env_config=package_env_config,
+ cleanup=args.cleanup,
+ build_itk_tarball_cache=args.build_itk_tarball_cache,
+ cmake_options=args.cmake_options,
+ windows_extra_lib_paths=args.lib_paths,
+ dist_dir=dist_dir,
+ module_source_dir=args.module_source_dir,
+ module_dependencies_root_dir=args.module_dependencies_root_dir,
+ itk_module_deps=args.itk_module_deps,
+ skip_itk_build=args.skip_itk_build,
+ skip_itk_wheel_build=args.skip_itk_wheel_build,
+ )
+ builder.run()
+
+
+if __name__ == "__main__":
+ build_wheels_main()
diff --git a/scripts/cmake_argument_builder.py b/scripts/cmake_argument_builder.py
new file mode 100644
index 00000000..22aee6d2
--- /dev/null
+++ b/scripts/cmake_argument_builder.py
@@ -0,0 +1,107 @@
+from collections.abc import Iterable, Iterator, Mapping
+
+
+def drop_quotes(s: str) -> str:
+ """Strip surrounding double-quote characters from *s*."""
+ return str(s).strip('"')
+
+
+class CMakeArgumentBuilder:
+ """Manage CMake-style key/value definitions and render them as CLI args.
+
+ Keys should include any CMake type suffix (e.g.
+ ``'CMAKE_BUILD_TYPE:STRING'``). Values are rendered verbatim.
+
+ Parameters
+ ----------
+ initial : Mapping[str, str], optional
+ Initial set of definitions to populate the builder.
+
+ Examples
+ --------
+ >>> flags = {
+ ... 'CMAKE_BUILD_TYPE:STRING': 'Release',
+ ... 'CMAKE_OSX_ARCHITECTURES:STRING': 'arm64',
+ ... }
+ >>> builder = CMakeArgumentBuilder(flags)
+ >>> builder.getCMakeCommandLineArguments()
+ ["-DCMAKE_BUILD_TYPE:STRING='Release'", "-DCMAKE_OSX_ARCHITECTURES:STRING='arm64'"]
+ >>> builder.getPythonBuildCommandLineArguments()
+ ['--config-setting=cmake.define.CMAKE_BUILD_TYPE:STRING=Release',
+ '--config-setting=cmake.define.CMAKE_OSX_ARCHITECTURES:STRING=arm64']
+ """
+
+ def __init__(self, initial: Mapping[str, str] | None = None) -> None:
+ # dict preserves insertion order; keep user's order when possible
+ self._defs: dict[str, str] = dict(initial) if initial else {}
+
+ # Basic mapping helpers (optional convenience)
+ def set(self, key: str, value: str) -> None:
+ """Set or replace a definition.
+
+ Parameters
+ ----------
+ key : str
+ CMake variable name, optionally with a type suffix
+ (e.g. ``'CMAKE_BUILD_TYPE:STRING'``).
+ value : str
+ Value for the definition.
+ """
+ self._defs[key] = value
+
+ def get(self, key: str, default: str | None = None) -> str | None:
+ """Return the value for *key*, or *default* if absent."""
+ return self._defs.get(key, default)
+
+ def update(self, other: Mapping[str, str] | Iterable[tuple[str, str]]) -> None:
+ """Merge definitions from *other* into this builder.
+
+ Parameters
+ ----------
+ other : Mapping[str, str] or Iterable[tuple[str, str]]
+ Definitions to merge. Existing keys are overwritten.
+ """
+ if isinstance(other, Mapping):
+ self._defs.update(other)
+ else:
+ for k, v in other:
+ self._defs[k] = v
+
+ def __contains__(self, key: str) -> bool: # pragma: no cover - trivial
+ return key in self._defs
+
+ def __getitem__(self, key: str) -> str: # pragma: no cover - trivial
+ return self._defs[key]
+
+ def __iter__(self) -> Iterator[str]: # pragma: no cover - trivial
+ return iter(self._defs)
+
+ def items(self) -> Iterable[tuple[str, str]]: # pragma: no cover - trivial
+ """Return an iterable of ``(key, value)`` definition pairs."""
+ return self._defs.items()
+
+ # Renderers
+ def getCMakeCommandLineArguments(self) -> list[str]:
+ """Render definitions as CMake ``-D`` arguments.
+
+ Returns
+ -------
+ list[str]
+ A list like ``["-D=''", ...]``.
+ """
+ return [f"""-D{k}='{drop_quotes(v)}'""" for k, v in self._defs.items()]
+
+ def getPythonBuildCommandLineArguments(self) -> list[str]:
+ """Render definitions as scikit-build-core ``--config-setting`` arguments.
+
+ Returns
+ -------
+ list[str]
+ A list like
+ ``["--config-setting=cmake.define.=''", ...]``.
+ """
+ prefix = "--config-setting=cmake.define."
+ return [f"""{prefix}{k}='{drop_quotes(v)}'""" for k, v in self._defs.items()]
+
+
+__all__ = ["CMakeArgumentBuilder"]
diff --git a/scripts/dockcross-manylinux-build-module-deps.sh b/scripts/dockcross-manylinux-build-module-deps.sh
deleted file mode 100755
index dede51d3..00000000
--- a/scripts/dockcross-manylinux-build-module-deps.sh
+++ /dev/null
@@ -1,105 +0,0 @@
-#!/bin/bash
-
-########################################################################
-# Run this script in an ITK external module directory to generate
-# build artifacts for prerequisite ITK external modules.
-#
-# Module dependencies are built in a flat directory structure regardless
-# of recursive dependencies. Prerequisite sources are required to be passed
-# in the order in which they should be built.
-# For example, if ITKTargetModule depends on ITKTargetModuleDep2 which
-# depends on ITKTargetModuleDep1, the output directory structure
-# will look like this:
-#
-# / ITKTargetModule
-# -- / ITKTargetModuleDep1
-# -- / ITKTargetModuleDep2
-# ..
-#
-# ===========================================
-# ENVIRONMENT VARIABLES
-#
-# - `ITK_MODULE_PREQ`: Prerequisite ITK modules that must be built before the requested module.
-# Format is `/@:/@:...`.
-# For instance, `export ITK_MODULE_PREQ=InsightSoftwareConsortium/ITKMeshToPolyData@v0.10.0`
-#
-########################################################################
-
-# Initialize variables
-
-script_dir=$(cd $(dirname $0) || exit 1; pwd)
-if [[ ! -f "${script_dir}/dockcross-manylinux-download-cache-and-build-module-wheels.sh" ]]; then
- echo "Could not find download script to use for building module dependencies!"
- exit 1
-fi
-
-source "${script_dir}/dockcross-manylinux-set-vars.sh"
-
-# Temporarily update prerequisite environment variable to prevent infinite recursion.
-ITK_MODULE_PREQ_TOPLEVEL=${ITK_MODULE_PREQ}
-ITK_MODULE_NO_CLEANUP_TOPLEVEL=${ITK_MODULE_NO_CLEANUP}
-export ITK_MODULE_PREQ=""
-export ITK_MODULE_NO_CLEANUP="ON"
-
-########################################################################
-# Build ITK module dependencies
-
-for MODULE_INFO in ${ITK_MODULE_PREQ_TOPLEVEL//:/ }; do
- MODULE_ORG=`(echo ${MODULE_INFO} | cut -d'/' -f 1)`
- MODULE_NAME=`(echo ${MODULE_INFO} | cut -d'@' -f 1 | cut -d'/' -f 2)`
- MODULE_TAG=`(echo ${MODULE_INFO} | cut -d'@' -f 2)`
-
- MODULE_UPSTREAM=https://github.com/${MODULE_ORG}/${MODULE_NAME}.git
- echo "Cloning from ${MODULE_UPSTREAM}"
- git clone ${MODULE_UPSTREAM}
-
- # Reuse cached build archive instead of redownloading.
- # Build archives are usually ~2GB so it is reasonable to move
- # instead of redownloading.
- if [[ `(compgen -G ./ITKPythonBuilds-linux*.tar.zst)` ]]; then
- mv ITKPythonBuilds-linux*.tar.zst ${MODULE_NAME}/
- fi
-
- pushd ${MODULE_NAME}
- git checkout ${MODULE_TAG}
- cp ../dockcross-manylinux-download-cache-and-build-module-wheels.sh .
- if [[ -d ../ITKPythonPackage ]]; then
- ln -s ../ITKPythonPackage
- ln -s ./ITKPythonPackage/oneTBB-prefix
- fi
-
- echo "Building module dependency ${MODULE_NAME}"
- ./dockcross-manylinux-download-cache-and-build-module-wheels.sh "$@"
- popd
-
- echo "Cleaning up module dependency"
- cp ./${MODULE_NAME}/include/* include/
- find ${MODULE_NAME}/wrapping -name '*.in' -print -exec cp {} wrapping \;
- find ${MODULE_NAME}/wrapping -name '*.init' -print -exec cp {} wrapping \;
- find ${MODULE_NAME}/*build/*/include -type f -print -exec cp {} include \;
-
- # Cache build archive
- if [[ `(compgen -G ./ITKPythonBuilds-linux*.tar.zst)` ]]; then
- rm -f ./${MODULE_NAME}/ITKPythonBuilds-linux*.tar.zst
- else
- mv ./${MODULE_NAME}/ITKPythonBuilds-linux*.tar.zst .
- fi
-
- # Cache ITKPythonPackage build scripts
- if [[ ! -d ./ITKPythonPackage ]]; then
- mv ./${MODULE_NAME}/ITKPythonPackage .
- ln -s ./ITKPythonPackage/oneTBB-prefix .
- fi
-
-done
-
-# Restore environment variable
-export ITK_MODULE_PREQ=${ITK_MODULE_PREQ_TOPLEVEL}
-ITK_MODULE_PREQ_TOPLEVEL=""
-export ITK_MODULE_NO_CLEANUP=${ITK_MODULE_NO_CLEANUP_TOPLEVEL}
-ITK_MODULE_NO_CLEANUP_TOPLEVEL=""
-
-# Summarize disk usage for debugging
-du -sh ./* | sort -hr | head -n 20
-
-echo "Done building ITK external module dependencies"
diff --git a/scripts/dockcross-manylinux-build-module-wheels.sh b/scripts/dockcross-manylinux-build-module-wheels.sh
index 392a2190..4c6f04e4 100755
--- a/scripts/dockcross-manylinux-build-module-wheels.sh
+++ b/scripts/dockcross-manylinux-build-module-wheels.sh
@@ -4,9 +4,6 @@
# Run this script to build the Python wheel packages for Linux for an ITK
# external module.
#
-# ========================================================================
-# PARAMETERS
-#
# Versions can be restricted by passing them in as arguments to the script
# For example,
#
@@ -26,13 +23,13 @@
#
# `MANYLINUX_VERSION`: Specialized manylinux image to use for building. Default is _2_28.
# See https://github.com/dockcross/dockcross for available versions and tags.
-# For instance, `export MANYLINUX_VERSION=2014`
+# For instance, `export MANYLINUX_VERSION=_2_28`
#
# `TARGET_ARCH`: Target architecture for which wheels should be built.
# For instance, `export MANYLINUX_VERSION=aarch64`
#
# `IMAGE_TAG`: Specialized manylinux image tag to use for building.
-# For instance, `export IMAGE_TAG=20221205-459c9f0`.
+# For instance, `export IMAGE_TAG=2025.08.12-1`.
# Tagged images are available at:
# - https://github.com/dockcross/dockcross (x64 architecture)
# - https://quay.io/organization/pypa (ARM architecture)
@@ -44,62 +41,179 @@
#
# - `NO_SUDO`: Disable the use of superuser permissions for running docker.
#
+# DIRECTORY STRUCTURE (expected):
+# ${IPP_DIR}/ <- ITKPythonPackage
+# ${BUILD_DIR}/ <- ITKPythonPackage-manylinux${VERSION}-build
+# ${MODULE_SOURCE_DIR}/ <- Module source (current directory)
########################################################################
-# Handle case where the script directory is not the working directory
-script_dir=$(cd $(dirname $0) || exit 1; pwd)
-source "${script_dir}/dockcross-manylinux-set-vars.sh"
-source "${script_dir}/oci_exe.sh"
+script_dir=$(
+ cd "$(dirname "$0")" || exit 1
+ pwd
+)
+_ipp_dir=$(dirname "${script_dir}")
+
+# -----------------------------------------------------------------------
+# Find container runtime
+for cand in nerdctl docker podman; do
+ if which "${cand}" >/dev/null 2>&1; then
+ export OCI_EXE=${OCI_EXE:-"$cand"}
+ break
+ fi
+done
-oci_exe=$(ociExe)
+if [ -z "${OCI_EXE}" ]; then
+ echo "ERROR: No container runtime found. Please install docker, podman, or nerdctl."
+ exit 1
+fi
+echo "Found OCI_EXE=$(which "${OCI_EXE}")"
-if [[ -n ${ITK_MODULE_PREQ} ]]; then
- echo "Building module dependencies ${ITK_MODULE_PREQ}"
- source "${script_dir}/dockcross-manylinux-build-module-deps.sh"
+# -----------------------------------------------------------------------
+# Set default values
+MANYLINUX_VERSION=${MANYLINUX_VERSION:-_2_28}
+TARGET_ARCH=${TARGET_ARCH:-x64}
+# Default image tag differs by architecture:
+# x64 → dockcross/manylinux image (docker.io/dockcross)
+# aarch64 → pypa manylinux image (quay.io/pypa, native ARM64 / QEMU on x64)
+if [[ "${TARGET_ARCH}" == "aarch64" ]]; then
+ IMAGE_TAG=${IMAGE_TAG:-2025.08.12-1}
+ CONTAINER_SOURCE=${CONTAINER_SOURCE:-"quay.io/pypa/manylinux${MANYLINUX_VERSION}_${TARGET_ARCH}:${IMAGE_TAG}"}
+else
+ # if x64 arch then default manylinux version is _2_28
+ IMAGE_TAG=${IMAGE_TAG:=20260203-3dfb3ff}
+ CONTAINER_SOURCE=${CONTAINER_SOURCE:-"docker.io/dockcross/manylinux${MANYLINUX_VERSION}-${TARGET_ARCH}:${IMAGE_TAG}"}
fi
+ITKPYTHONPACKAGE_ORG=${ITKPYTHONPACKAGE_ORG:-InsightSoftwareConsortium}
+ITKPYTHONPACKAGE_TAG=${ITKPYTHONPACKAGE_TAG:-main}
+
+# For backwards compatibility
+ITK_GIT_TAG=${ITK_GIT_TAG:-${ITK_PACKAGE_VERSION}}
+
+# Required environment variables
+required_vars=(
+ ITK_GIT_TAG
+ MANYLINUX_VERSION
+ IMAGE_TAG
+ TARGET_ARCH
+ ITKPYTHONPACKAGE_ORG
+ ITKPYTHONPACKAGE_TAG
+)
+# Sanity Validation loop
+_missing_required=0
+for v in "${required_vars[@]}"; do
+ if [ -z "${!v:-}" ]; then
+ _missing_required=1
+ echo "ERROR: Required environment variable '$v' is not set or empty."
+ fi
+done
+if [ "${_missing_required}" -ne 0 ]; then
+ exit 1
+fi
+unset _missing_required
+
+mkdir -p "${_ipp_dir}"/build
+cd "$(dirname "${_ipp_dir}")" || exit
+
+HOST_MODULE_DIRECTORY=${MODULE_SRC_DIRECTORY}
# Set up paths and variables for build
-mkdir -p $(pwd)/tools
-chmod 777 $(pwd)/tools
-mkdir -p dist
-DOCKER_ARGS="-v $(pwd)/dist:/work/dist/ -v ${script_dir}/..:/ITKPythonPackage -v $(pwd)/tools:/tools"
-DOCKER_ARGS+=" -e MANYLINUX_VERSION"
-DOCKER_ARGS+=" -e LD_LIBRARY_PATH"
-# Mount any shared libraries
+CONTAINER_WORK_DIR=/work
+CONTAINER_PACKAGE_BUILD_DIR=${CONTAINER_WORK_DIR}/ITKPythonPackage-build
+CONTAINER_PACKAGE_SCRIPTS_DIR=${CONTAINER_WORK_DIR}/ITKPythonPackage
+HOST_PACKAGE_BUILD_DIR=$(dirname "${_ipp_dir}")/ITKPythonPackage-build
+HOST_PACKAGE_SCRIPTS_DIR=${_ipp_dir}
+
+CONTAINER_ITK_SOURCE_DIR=${CONTAINER_PACKAGE_BUILD_DIR}/ITK
+HOST_PACKAGE_DIST=${HOST_MODULE_DIRECTORY}/dist
+mkdir -p "${HOST_PACKAGE_DIST}"
+CONTAINER_MODULE_DIR=${CONTAINER_WORK_DIR}/$(basename "${MODULE_SRC_DIRECTORY}")
+CONTAINER_MODULE_DEPS_DIR=${CONTAINER_WORK_DIR}/$(basename "${MODULE_DEPS_DIR}")
+
+# Build docker arguments
+DOCKER_ARGS=" --network=host "
+DOCKER_ARGS+=" -v ${HOST_PACKAGE_BUILD_DIR}:${CONTAINER_PACKAGE_BUILD_DIR} "
+DOCKER_ARGS+=" -v ${HOST_PACKAGE_SCRIPTS_DIR}:${CONTAINER_PACKAGE_SCRIPTS_DIR} "
+DOCKER_ARGS+=" -v ${MODULE_SRC_DIRECTORY}:${CONTAINER_MODULE_DIR} "
+DOCKER_ARGS+=" -v ${MODULE_DEPS_DIR}:${CONTAINER_MODULE_DEPS_DIR} "
+
+if [ "${ITK_SOURCE_DIR}" != "" ]; then
+ DOCKER_ARGS+=" -v ${ITK_SOURCE_DIR}:${CONTAINER_ITK_SOURCE_DIR} "
+fi
+
+# Environment variables for the container
+DOCKER_ARGS+=" -e PYTHONUNBUFFERED=1 "
+DOCKER_ARGS+=" -e CMAKE_OPTIONS='${CMAKE_OPTIONS}' "
+
+# Mount shared libraries if LD_LIBRARY_PATH is set
if [[ -n ${LD_LIBRARY_PATH} ]]; then
for libpath in ${LD_LIBRARY_PATH//:/ }; do
- DOCKER_LIBRARY_PATH="/usr/lib64/$(basename -- ${libpath})"
- DOCKER_ARGS+=" -v ${libpath}:${DOCKER_LIBRARY_PATH}"
- if test -d ${libpath}; then
- DOCKER_LD_LIBRARY_PATH+="${DOCKER_LIBRARY_PATH}:${DOCKER_LD_LIBRARY_PATH}"
- fi
+ DOCKER_LIBRARY_PATH="/usr/lib64/$(basename -- "${libpath}")"
+ DOCKER_ARGS+=" -v ${libpath}:${DOCKER_LIBRARY_PATH}"
+ if test -d "${libpath}"; then
+ DOCKER_LD_LIBRARY_PATH+="${DOCKER_LIBRARY_PATH}:${DOCKER_LD_LIBRARY_PATH}"
+ fi
done
fi
export LD_LIBRARY_PATH="${DOCKER_LD_LIBRARY_PATH}"
-if [[ "${TARGET_ARCH}" = "aarch64" ]]; then
- echo "Install aarch64 architecture emulation tools to perform build for ARM platform"
+# To build tarballs in manylinux, use 'export BUILD_WHEELS_EXTRA_FLAGS=" --build-itk-tarball-cache "'
+BUILD_WHEELS_EXTRA_FLAGS=${BUILD_WHEELS_EXTRA_FLAGS:=""} # No tarball by default
+PY_ENVS=("${@:-py310 py311}")
+
+if [[ "${TARGET_ARCH}" == "aarch64" ]]; then
+ # aarch64: run the quay.io/pypa native image directly.
+ # On ARM64 hosts (e.g. Apple Silicon) this runs natively.
+ # On x64 hosts, first register QEMU binfmt emulation.
if [[ ! ${NO_SUDO} ]]; then
docker_prefix="sudo"
fi
+ # Only install QEMU binfmt emulation on non-ARM64 hosts; ARM64 hosts run natively
+ if [[ "$(uname -m)" != "arm64" && "$(uname -m)" != "aarch64" ]]; then
+ echo "Installing aarch64 architecture emulation tools to perform build for ARM platform"
+ ${docker_prefix} "$OCI_EXE" run --privileged --rm tonistiigi/binfmt --install all
+ fi
- ${docker_prefix} $oci_exe run --privileged --rm tonistiigi/binfmt --install all
-
- # Build wheels
- DOCKER_ARGS+=" -v $(pwd):/work/ --rm"
- ${docker_prefix} $oci_exe run $DOCKER_ARGS ${CONTAINER_SOURCE} "/ITKPythonPackage/scripts/internal/manylinux-aarch64-build-module-wheels.sh" "$@"
+ cmd="${docker_prefix} \"$OCI_EXE\" run --rm \
+ ${DOCKER_ARGS} \
+ -e PY_ENVS=\"${PY_ENVS[*]}\" \
+ -e ITK_GIT_TAG=\"${ITK_GIT_TAG}\" \
+ -e ITK_PACKAGE_VERSION=\"${ITK_PACKAGE_VERSION}\" \
+ -e ITK_MODULE_PREQ=\"${ITK_MODULE_PREQ}\" \
+ -e MODULE_SRC_DIRECTORY=\"${CONTAINER_MODULE_DIR}\" \
+ -e MODULE_DEPS_DIR=\"${CONTAINER_MODULE_DEPS_DIR}\" \
+ -e MANYLINUX_VERSION=\"${MANYLINUX_VERSION}\" \
+ -e IMAGE_TAG=\"${IMAGE_TAG}\" \
+ -e TARGET_ARCH=\"${TARGET_ARCH}\" \
+ -e ITKPYTHONPACKAGE_ORG=\"${ITKPYTHONPACKAGE_ORG}\" \
+ -e ITKPYTHONPACKAGE_TAG=\"${ITKPYTHONPACKAGE_TAG}\" \
+ -e BUILD_WHEELS_EXTRA_FLAGS=\"${BUILD_WHEELS_EXTRA_FLAGS}\" \
+ ${CONTAINER_SOURCE} \
+ /bin/bash -x ${CONTAINER_PACKAGE_SCRIPTS_DIR}/scripts/docker_build_environment_driver.sh"
else
- # Generate dockcross scripts
- $oci_exe run --rm ${CONTAINER_SOURCE} > /tmp/dockcross-manylinux-x64
- chmod u+x /tmp/dockcross-manylinux-x64
-
- # Build wheels
- /tmp/dockcross-manylinux-x64 \
- -a "$DOCKER_ARGS" \
- "/ITKPythonPackage/scripts/internal/manylinux-build-module-wheels.sh" "$@"
-fi
+ # x64: generate the dockcross runner script from the image, then invoke it.
+ _local_dockcross_script=${_ipp_dir}/build/runner_dockcross-${MANYLINUX_VERSION}-${TARGET_ARCH}_${IMAGE_TAG}.sh
+ "$OCI_EXE" run --rm "${CONTAINER_SOURCE}" >"${_local_dockcross_script}"
+ chmod u+x "${_local_dockcross_script}"
-if [[ -z ${ITK_MODULE_NO_CLEANUP} ]]; then
- source "${script_dir}/dockcross-manylinux-cleanup.sh"
+ # When building ITK remote wheels, --module-source-dir, --module-dependencies-root-dir, and --itk-module-deps should be present
+ cmd="bash -x ${_local_dockcross_script} \
+ -a \"$DOCKER_ARGS\" \
+ /usr/bin/env \
+ PY_ENVS=\"${PY_ENVS[*]}\" \
+ ITK_GIT_TAG=\"${ITK_GIT_TAG}\" \
+ ITK_PACKAGE_VERSION=\"${ITK_PACKAGE_VERSION}\" \
+ ITK_MODULE_PREQ=\"${ITK_MODULE_PREQ}\" \
+ MODULE_SRC_DIRECTORY=\"${CONTAINER_MODULE_DIR}\" \
+ MODULE_DEPS_DIR=\"${CONTAINER_MODULE_DEPS_DIR}\" \
+ MANYLINUX_VERSION=\"${MANYLINUX_VERSION}\" \
+ IMAGE_TAG=\"${IMAGE_TAG}\" \
+ TARGET_ARCH=\"${TARGET_ARCH}\" \
+ ITKPYTHONPACKAGE_ORG=\"${ITKPYTHONPACKAGE_ORG}\" \
+ ITKPYTHONPACKAGE_TAG=\"${ITKPYTHONPACKAGE_TAG}\" \
+ BUILD_WHEELS_EXTRA_FLAGS=\"${BUILD_WHEELS_EXTRA_FLAGS}\" \
+ /bin/bash -x ${CONTAINER_PACKAGE_SCRIPTS_DIR}/scripts/docker_build_environment_driver.sh"
fi
+
+echo "RUNNING: $cmd"
+eval "$cmd"
diff --git a/scripts/dockcross-manylinux-build-tarball.sh b/scripts/dockcross-manylinux-build-tarball.sh
deleted file mode 100755
index ca29e75c..00000000
--- a/scripts/dockcross-manylinux-build-tarball.sh
+++ /dev/null
@@ -1,44 +0,0 @@
-#!/usr/bin/env bash
-
-# This script creates a tarball of the ITK Python package build tree. It is
-# downloaded by the external module build scripts and used to build their
-# Python package on GitHub CI services.
-
-# -----------------------------------------------------------------------
-
-zstd_exe=`(which zstd)`
-
-# Find an appropriately versioned zstd.
-#
-# "--long" is introduced in zstd==v1.3.2
-# https://github.com/facebook/zstd/releases/tag/v1.3.2
-#
-# Sample --version output:
-# *** zstd command line interface 64-bits v1.4.4, by Yann Collet *** #
-ZSTD_MIN_VERSION="1.3.2"
-
-if [[ -n `(which dpkg)` && `(${zstd_exe} --version)` =~ v([0-9]+.[0-9]+.[0-9]+) ]]; then
- if $(dpkg --compare-versions ${BASH_REMATCH[1]} "ge" ${ZSTD_MIN_VERSION} ); then
- echo "Found zstd v${BASH_REMATCH[1]} at ${zstd_exe}"
- else
- echo "Expected zstd v${ZSTD_MIN_VERSION} or higher but found v${BASH_REMATCH[1]} at ${zstd_exe}"
- exit 255
- fi
-else
- # dpkg not available for version comparison so simply print version
- ${zstd_exe} --version
-fi
-
-# -----------------------------------------------------------------------
-
-tar -cf ITKPythonBuilds-linux.tar \
- ITKPythonPackage/ITK-* \
- ITKPythonPackage/oneTBB* \
- ITKPythonPackage/requirements-dev.txt \
- ITKPythonPackage/scripts
-$zstd_exe -f \
- -10 \
- -T6 \
- --long=31 \
- ./ITKPythonBuilds-linux.tar \
- -o ./ITKPythonBuilds-linux.tar.zst
diff --git a/scripts/dockcross-manylinux-build-wheels.sh b/scripts/dockcross-manylinux-build-wheels.sh
index 0619b301..eadba903 100755
--- a/scripts/dockcross-manylinux-build-wheels.sh
+++ b/scripts/dockcross-manylinux-build-wheels.sh
@@ -1,5 +1,4 @@
#!/bin/bash
-
# Run this script to build the ITK Python wheel packages for Linux.
#
# Versions can be restricted by passing them in as arguments to the script
@@ -7,42 +6,144 @@
#
# scripts/dockcross-manylinux-build-wheels.sh cp310
#
-# A specialized manylinux image and tag can be used by exporting to
-# MANYLINUX_VERSION and IMAGE_TAG before running this script.
-# See https://github.com/dockcross/dockcross for available versions and tags.
+# A specialized manylinux image and tag can be used by setting
+# MANYLINUX_VERSION and IMAGE_TAG
#
# For example,
#
-# export MANYLINUX_VERSION=2014
-# export IMAGE_TAG=20221205-459c9f0
+# export MANYLINUX_VERSION=_2_28
+# export IMAGE_TAG=20260203-3dfb3ff
# scripts/dockcross-manylinux-build-module-wheels.sh cp310
#
-script_dir=$(cd $(dirname $0) || exit 1; pwd)
-source "${script_dir}/oci_exe.sh"
+script_dir=$(
+ cd "$(dirname "$0")" || exit 1
+ pwd
+)
+_ipp_dir=$(dirname "${script_dir}")
-oci_exe=$(ociExe)
+for cand in nerdctl docker podman; do
+ if which "${cand}" >/dev/null; then
+ export OCI_EXE=${OCI_EXE:="$cand"}
+ break
+ fi
+done
+echo "FOUND OCI_EXE=$(which "${OCI_EXE}")"
+#For backwards compatibility when the ITK_GIT_TAG was required to match the ITK_PACKAGE_VERSION
+ITK_PACKAGE_VERSION=${ITK_PACKAGE_VERSION:="v6.0b02"}
+ITK_GIT_TAG=${ITK_GIT_TAG:=${ITK_PACKAGE_VERSION}}
MANYLINUX_VERSION=${MANYLINUX_VERSION:=_2_28}
-if [[ ${MANYLINUX_VERSION} == _2_28 ]]; then
+# Default image tag differs by architecture:
+# x64 → dockcross/manylinux image (docker.io/dockcross)
+# aarch64 → pypa manylinux image (quay.io/pypa, native ARM64 / QEMU on x64)
+if [[ "${TARGET_ARCH}" == "aarch64" ]]; then
+ IMAGE_TAG=${IMAGE_TAG:=2025.08.12-1}
+ CONTAINER_SOURCE=${CONTAINER_SOURCE:="quay.io/pypa/manylinux${MANYLINUX_VERSION}_${TARGET_ARCH}:${IMAGE_TAG}"}
+else
+ # if x64 arch then default manylinux version is _2_28
IMAGE_TAG=${IMAGE_TAG:=20260203-3dfb3ff}
-elif [[ ${MANYLINUX_VERSION} == 2014 ]]; then
- IMAGE_TAG=${IMAGE_TAG:=20240304-9e57d2b}
+ CONTAINER_SOURCE=${CONTAINER_SOURCE:="docker.io/dockcross/manylinux${MANYLINUX_VERSION}-${TARGET_ARCH}:${IMAGE_TAG}"}
+fi
+ITKPYTHONPACKAGE_ORG=${ITKPYTHONPACKAGE_ORG:=InsightSoftwareConsortium}
+ITKPYTHONPACKAGE_TAG=${ITKPYTHONPACKAGE_TAG:=main}
+
+# Required environment variables
+required_vars=(
+ ITK_GIT_TAG
+ MANYLINUX_VERSION
+ IMAGE_TAG
+ TARGET_ARCH
+ ITKPYTHONPACKAGE_ORG
+ ITKPYTHONPACKAGE_TAG
+)
+# Sanity Validation loop
+_missing_required=0
+for v in "${required_vars[@]}"; do
+ if [ -z "${!v:-}" ]; then
+ _missing_required=1
+ echo "ERROR: Required environment variable '$v' is not set or empty."
+ fi
+done
+if [ "${_missing_required}" -ne 0 ]; then
+ exit 1
+fi
+unset _missing_required
+
+mkdir -p "${_ipp_dir}/build"
+cd "$(dirname "${_ipp_dir}")" || exit
+
+# Build wheels in dockcross environment
+CONTAINER_WORK_DIR=/work
+CONTAINER_PACKAGE_BUILD_DIR=${CONTAINER_WORK_DIR}/ITKPythonPackage-build
+CONTAINER_PACKAGE_SCRIPTS_DIR=${CONTAINER_WORK_DIR}/ITKPythonPackage
+CONTAINER_ITK_SOURCE_DIR=${CONTAINER_PACKAGE_BUILD_DIR}/ITK
+
+HOST_PACKAGE_SCRIPTS_DIR=${_ipp_dir}
+HOST_PACKAGE_BUILD_DIR=$(dirname "${_ipp_dir}")/ITKPythonPackage-manylinux${MANYLINUX_VERSION}-build
+mkdir -p "${HOST_PACKAGE_BUILD_DIR}"
+
+DOCKER_ARGS=" -v ${HOST_PACKAGE_BUILD_DIR}:${CONTAINER_PACKAGE_BUILD_DIR} "
+DOCKER_ARGS+=" -v ${HOST_PACKAGE_SCRIPTS_DIR}:${CONTAINER_PACKAGE_SCRIPTS_DIR} "
+if [ "${ITK_SOURCE_DIR}" != "" ]; then
+ DOCKER_ARGS+=" -v${ITK_SOURCE_DIR}:${CONTAINER_ITK_SOURCE_DIR} "
+fi
+DOCKER_ARGS+=" -e PYTHONUNBUFFERED=1 " # Turn off buffering of outputs in python
+
+# To build tarballs in manylinux, use 'export BUILD_WHEELS_EXTRA_FLAGS=" --build-itk-tarball-cache "'
+BUILD_WHEELS_EXTRA_FLAGS=${BUILD_WHEELS_EXTRA_FLAGS:=""} # No tarball by default
+
+# If args are given, use them. Otherwise use default python environments
+PY_ENVS=("${@:-py310 py311}")
+
+if [[ "${TARGET_ARCH}" == "aarch64" ]]; then
+ # aarch64: run the quay.io/pypa native image directly.
+ # On ARM64 hosts (e.g. Apple Silicon) this runs natively.
+ # On x64 hosts, first register QEMU binfmt emulation.
+ if [[ ! ${NO_SUDO} ]]; then
+ docker_prefix="sudo"
+ fi
+ # Only install QEMU binfmt emulation on non-ARM64 hosts; ARM64 hosts run natively
+ if [[ "$(uname -m)" != "arm64" && "$(uname -m)" != "aarch64" ]]; then
+ echo "Installing aarch64 architecture emulation tools to perform build for ARM platform"
+ ${docker_prefix} "$OCI_EXE" run --privileged --rm tonistiigi/binfmt --install all
+ fi
+
+ # When building ITK wheels, module-related vars are empty
+ cmd="${docker_prefix} \"$OCI_EXE\" run --rm \
+ ${DOCKER_ARGS} \
+ -e PY_ENVS=\"${PY_ENVS[*]}\" \
+ -e ITK_GIT_TAG=\"${ITK_GIT_TAG}\" \
+ -e ITK_PACKAGE_VERSION=\"${ITK_PACKAGE_VERSION:-}\" \
+ -e MANYLINUX_VERSION=\"${MANYLINUX_VERSION}\" \
+ -e IMAGE_TAG=\"${IMAGE_TAG}\" \
+ -e TARGET_ARCH=\"${TARGET_ARCH}\" \
+ -e ITKPYTHONPACKAGE_ORG=\"${ITKPYTHONPACKAGE_ORG}\" \
+ -e ITKPYTHONPACKAGE_TAG=\"${ITKPYTHONPACKAGE_TAG}\" \
+ -e BUILD_WHEELS_EXTRA_FLAGS=\"${BUILD_WHEELS_EXTRA_FLAGS}\" \
+ ${CONTAINER_SOURCE} \
+ /bin/bash -x ${CONTAINER_PACKAGE_SCRIPTS_DIR}/scripts/docker_build_environment_driver.sh"
else
- echo "Unknown manylinux version ${MANYLINUX_VERSION}"
- exit 1;
+ # x64: generate the dockcross runner script from the image, then invoke it.
+ _local_dockercross_script=${_ipp_dir}/build/runner_dockcross-${MANYLINUX_VERSION}-${TARGET_ARCH}_${IMAGE_TAG}.sh
+ "$OCI_EXE" run --rm "${CONTAINER_SOURCE}" >"${_local_dockercross_script}"
+ chmod u+x "${_local_dockercross_script}"
+
+ # When building ITK wheels, --module-source-dir, --module-dependancies-root-dir, and --itk-module-deps to be empty
+ cmd="bash -x ${_local_dockercross_script} \
+ -a \"$DOCKER_ARGS\" \
+ /usr/bin/env \
+ PY_ENVS=\"${PY_ENVS[*]}\" \
+ ITK_GIT_TAG=\"${ITK_GIT_TAG}\" \
+ ITK_PACKAGE_VERSION=\"${ITK_PACKAGE_VERSION:-}\" \
+ MANYLINUX_VERSION=\"${MANYLINUX_VERSION}\" \
+ IMAGE_TAG=\"${IMAGE_TAG}\" \
+ TARGET_ARCH=\"${TARGET_ARCH}\" \
+ ITKPYTHONPACKAGE_ORG=\"${ITKPYTHONPACKAGE_ORG}\" \
+ ITKPYTHONPACKAGE_TAG=\"${ITKPYTHONPACKAGE_TAG}\" \
+ BUILD_WHEELS_EXTRA_FLAGS=\"${BUILD_WHEELS_EXTRA_FLAGS}\" \
+ /bin/bash -x ${CONTAINER_PACKAGE_SCRIPTS_DIR}/scripts/docker_build_environment_driver.sh"
fi
-# Generate dockcross scripts
-$oci_exe run --rm docker.io/dockcross/manylinux${MANYLINUX_VERSION}-x64:${IMAGE_TAG} > /tmp/dockcross-manylinux-x64
-chmod u+x /tmp/dockcross-manylinux-x64
-
-# Build wheels
-pushd $script_dir/..
-mkdir -p dist
-DOCKER_ARGS="-v $(pwd)/dist:/work/dist/"
-DOCKER_ARGS+=" -e MANYLINUX_VERSION"
-/tmp/dockcross-manylinux-x64 \
- -a "$DOCKER_ARGS" \
- ./scripts/internal/manylinux-build-wheels.sh "$@"
-popd
+echo "RUNNING: $cmd"
+eval "$cmd"
diff --git a/scripts/dockcross-manylinux-cleanup.sh b/scripts/dockcross-manylinux-cleanup.sh
deleted file mode 100755
index 52702518..00000000
--- a/scripts/dockcross-manylinux-cleanup.sh
+++ /dev/null
@@ -1,46 +0,0 @@
-#!/bin/bash
-
-########################################################################
-# Run this script in an ITK external module directory to clean up
-# Linux Python build artifacts.
-#
-# Typically required for building multiple types of module wheels in the same
-# directory, such as using different toolsets or targeting different
-# architectures.
-#
-# ===========================================
-# ENVIRONMENT VARIABLES
-#
-# - `ITK_MODULE_PREQ`: Prerequisite ITK modules that must be built before the requested module.
-# Format is `/@:/@:...`.
-# For instance, `export ITK_MODULE_PREQ=InsightSoftwareConsortium/ITKMeshToPolyData@v0.10.0`
-#
-# - `NO_SUDO`: Disable the use of superuser permissions for removing directories.
-# `sudo` is required by default for cleanup on Github Actions runners.
-#
-########################################################################
-
-echo "Cleaning up artifacts from module build"
-
-# ARM platform observed to require sudo for removing ITKPythonPackage sources
-rm_prefix=""
-if [[ ! ${NO_SUDO} ]]; then
- rm_prefix="sudo "
-fi
-
-unlink oneTBB-prefix
-${rm_prefix} rm -rf ITKPythonPackage/
-${rm_prefix} rm -rf tools/
-${rm_prefix} rm -rf _skbuild/ build/
-${rm_prefix} rm -rf ./*.egg-info/
-${rm_prefix} rm -rf ./ITK-*-manylinux${MANYLINUX_VERSION}_${TARGET_ARCH}/
-${rm_prefix} rm -rf ./ITKPythonBuilds-linux-manylinux*${MANYLINUX_VERSION}*.tar.zst
-
-if [[ -n ${ITK_MODULE_PREQ} ]]; then
- for MODULE_INFO in ${ITK_MODULE_PREQ//:/ }; do
- MODULE_NAME=`(echo ${MODULE_INFO} | cut -d'@' -f 1 | cut -d'/' -f 2)`
- ${rm_prefix} rm -rf ${MODULE_NAME}/
- done
-fi
-
-# Leave dist/ and download scripts intact
diff --git a/scripts/dockcross-manylinux-download-cache-and-build-module-wheels.sh b/scripts/dockcross-manylinux-download-cache-and-build-module-wheels.sh
index 37166edd..d94e2d68 100755
--- a/scripts/dockcross-manylinux-download-cache-and-build-module-wheels.sh
+++ b/scripts/dockcross-manylinux-download-cache-and-build-module-wheels.sh
@@ -16,9 +16,6 @@
# ENVIRONMENT VARIABLES
#
# These variables are set with the `export` bash command before calling the script.
-# For example,
-#
-# scripts/dockcross-manylinux-build-module-wheels.sh cp310
#
# `ITKPYTHONPACKAGE_ORG`: Github organization for fetching ITKPythonPackage build scripts.
#
@@ -28,11 +25,18 @@
#
########################################################################
+download_script_dir=$(
+ cd "$(dirname "$0")" || exit 1
+ pwd
+)
+# if not specified, use the current directory for MODULE_SRC_DIRECTORY
+MODULE_SRC_DIRECTORY=${MODULE_SRC_DIRECTORY:=${download_script_dir}}
+# if not specified then use the a dummy MODULE_DEPENDENCIES directory in the build dashboard
+MODULE_DEPS_DIR=${MODULE_DEPS_DIR:=${DASHBOARD_BUILD_DIRECTORY}/MODULE_DEPENDENCIES}
# -----------------------------------------------------------------------
# Script argument parsing
#
-usage()
-{
+usage() {
echo "Usage:
dockcross-manylinux-download-cache-and-build-module-wheels
[ -h | --help ] show usage
@@ -42,34 +46,111 @@ usage()
exit 2
}
-FORWARD_ARGS=("$@") # Store arguments to forward them later
PARSED_ARGS=$(getopt -a -n dockcross-manylinux-download-cache-and-build-module-wheels \
-o hc:x: --long help,cmake_options:,exclude_libs: -- "$@")
eval set -- "$PARSED_ARGS"
-while :
-do
+while :; do
case "$1" in
- -h | --help) usage; break ;;
- -c | --cmake_options) CMAKE_OPTIONS="$2" ; shift 2 ;;
- -x | --exclude_libs) EXCLUDE_LIBS="$2" ; shift 2 ;;
- --) shift; break ;;
- *) echo "Unexpected option: $1.";
- usage; break ;;
+ -h | --help)
+ usage
+ ;;
+ -c | --cmake_options)
+ export CMAKE_OPTIONS="$2"
+ shift 2
+ ;;
+ -x | --exclude_libs)
+ export EXCLUDE_LIBS="$2"
+ shift 2
+ ;;
+ --)
+ shift
+ break
+ ;;
+ *)
+ echo "Unexpected option: $1."
+ usage
+ ;;
esac
done
+#For backwards compatibility when the ITK_GIT_TAG was required to match the ITK_PACKAGE_VERSION
+ITK_PACKAGE_VERSION=${ITK_PACKAGE_VERSION:="v6.0b02"}
+ITK_GIT_TAG=${ITK_GIT_TAG:=${ITK_PACKAGE_VERSION}}
+
# -----------------------------------------------------------------------
-# Download and extract cache
+# Set default values
+MANYLINUX_VERSION=${MANYLINUX_VERSION:-_2_28}
+TARGET_ARCH=${TARGET_ARCH:-x64}
-echo "Fetching https://raw.githubusercontent.com/${ITKPYTHONPACKAGE_ORG:=InsightSoftwareConsortium}/ITKPythonPackage/${ITKPYTHONPACKAGE_TAG:=v5.4.0}/scripts/dockcross-manylinux-download-cache.sh"
-curl -L https://raw.githubusercontent.com/${ITKPYTHONPACKAGE_ORG:=InsightSoftwareConsortium}/ITKPythonPackage/${ITKPYTHONPACKAGE_TAG:=v5.4.0}/scripts/dockcross-manylinux-download-cache.sh -O
-chmod u+x dockcross-manylinux-download-cache.sh
-./dockcross-manylinux-download-cache.sh $1
+ITKPYTHONPACKAGE_ORG=${ITKPYTHONPACKAGE_ORG:-InsightSoftwareConsortium}
+ITKPYTHONPACKAGE_TAG=${ITKPYTHONPACKAGE_TAG:-main}
+
+# -----------------------------------------------------------------------
+# Check for conda/pixi-provided ITK (libitk-wrapping package).
+# When available, skip the tarball download entirely.
+
+_conda_itk_dir=""
+for _prefix_var in CONDA_PREFIX PIXI_ENVIRONMENT_DIR; do
+ _prefix="${!_prefix_var:-}"
+ if [ -n "${_prefix}" ]; then
+ for _candidate in "${_prefix}"/lib/cmake/ITK-*; do
+ if [ -f "${_candidate}/ITKConfig.cmake" ]; then
+ _conda_itk_dir="${_candidate}"
+ echo "Detected conda-installed ITK at ${_conda_itk_dir} (via \$${_prefix_var})"
+ break 2
+ fi
+ done
+ fi
+done
+
+if [ -n "${_conda_itk_dir}" ]; then
+ echo "Using conda-installed ITK; skipping tarball download."
+ # Point to this repo's own scripts (already present on disk)
+ untarred_ipp_dir=${download_script_dir}
+ ITK_SOURCE_DIR=""
+else
+ # -----------------------------------------------------------------------
+ # Download and extract cache (legacy tarball path)
+
+ echo "Fetching https://raw.githubusercontent.com/${ITKPYTHONPACKAGE_ORG}/ITKPythonPackage/${ITKPYTHONPACKAGE_TAG}/scripts/dockcross-manylinux-download-cache.sh"
+ curl -L "https://raw.githubusercontent.com/${ITKPYTHONPACKAGE_ORG}/ITKPythonPackage/${ITKPYTHONPACKAGE_TAG}/scripts/dockcross-manylinux-download-cache.sh" -O
+ chmod u+x dockcross-manylinux-download-cache.sh
+ _download_cmd="ITK_GIT_TAG=${ITK_GIT_TAG} \
+ ITK_PACKAGE_VERSION=${ITK_PACKAGE_VERSION} \
+ ITKPYTHONPACKAGE_ORG=${ITKPYTHONPACKAGE_ORG} \
+ ITKPYTHONPACKAGE_TAG=${ITKPYTHONPACKAGE_TAG} \
+ MANYLINUX_VERSION=${MANYLINUX_VERSION} \
+ TARGET_ARCH=${TARGET_ARCH} \
+ bash -x \
+ ${download_script_dir}/dockcross-manylinux-download-cache.sh $1"
+ echo "Running: ${_download_cmd}"
+ eval "${_download_cmd}"
+
+ #NOTE: in this scenario, untarred_ipp_dir is extracted from tarball
+ # during ${download_script_dir}/dockcross-manylinux-download-cache.sh
+ untarred_ipp_dir=${download_script_dir}/ITKPythonPackage
+
+ ITK_SOURCE_DIR=${download_script_dir}/ITKPythonPackage-build/ITK
+fi
# -----------------------------------------------------------------------
# Build module wheels
echo "Building module wheels"
-set -- "${FORWARD_ARGS[@]}"; # Restore initial argument list
-./ITKPythonPackage/scripts/dockcross-manylinux-build-module-wheels.sh "$@"
+
+_bld_cmd="NO_SUDO=${NO_SUDO} \
+ LD_LIBRARY_PATH=${LD_LIBRARY_PATH} \
+ IMAGE_TAG=${IMAGE_TAG} \
+ TARGET_ARCH=${TARGET_ARCH} \
+ ITK_SOURCE_DIR=${ITK_SOURCE_DIR} \
+ ITK_GIT_TAG=${ITK_GIT_TAG} \
+ ITK_PACKAGE_VERSION=${ITK_PACKAGE_VERSION} \
+ ITK_MODULE_PREQ=${ITK_MODULE_PREQ} \
+ ITK_MODULE_NO_CLEANUP=${ITK_MODULE_NO_CLEANUP} \
+ MODULE_SRC_DIRECTORY=${MODULE_SRC_DIRECTORY} \
+ MODULE_DEPS_DIR=${MODULE_DEPS_DIR} \
+ MANYLINUX_VERSION=${MANYLINUX_VERSION} \
+ ${untarred_ipp_dir}/scripts/dockcross-manylinux-build-module-wheels.sh $*"
+echo "Running: ${_bld_cmd}"
+eval "${_bld_cmd}"
diff --git a/scripts/dockcross-manylinux-download-cache.sh b/scripts/dockcross-manylinux-download-cache.sh
index 10d17e2d..d3571228 100755
--- a/scripts/dockcross-manylinux-download-cache.sh
+++ b/scripts/dockcross-manylinux-download-cache.sh
@@ -11,31 +11,13 @@
# steps not present in `dockcross-manylinux-download-cache-and-build-module-wheels.sh`.
#
# ===========================================
-# ENVIRONMENT VARIABLES
-#
-# `ITK_PACKAGE_VERSION`: Tag for ITKPythonBuilds build cache to use
-# Examples: "v5.4.0", "v5.2.1.post1"
-# See available tags at https://github.com/InsightSoftwareConsortium/ITKPythonBuilds/tags
-#
-# `MANYLINUX_VERSION`: manylinux specialization used to build ITK for cache
-# Examples: "_2_28", "2014", "_2_28_aarch64"
-# See https://github.com/dockcross/dockcross
-#
-# `ITKPYTHONPACKAGE_TAG`: Tag for ITKPythonPackage build scripts to use.
-# If ITKPYTHONPACKAGE_TAG is empty then the default scripts distributed
-# with the ITKPythonBuilds archive will be used.
-#
-# `ITKPYTHONPACKAGE_ORG`: Github organization or user to use for ITKPythonPackage
-# build script source. Default is InsightSoftwareConsortium.
-# Ignored if ITKPYTHONPACKAGE_TAG is empty.
-#
+# ENVIRONMENT VARIABLES: ITK_GIT_TAG, MANYLINUX_VERSION, ITKPYTHONPACKAGE_TAG, ITKPYTHONPACKAGE_ORG
########################################################################
# -----------------------------------------------------------------------
# Script argument parsing
#
-usage()
-{
+usage() {
echo "Usage:
dockcross-manylinux-download-cache.sh
[ -h | --help ] show usage
@@ -43,25 +25,53 @@ usage()
exit 2
}
-FORWARD_ARGS=("$@") # Store arguments to forward them later
+# Required environment variables
+required_vars=(
+ ITK_GIT_TAG
+ ITK_PACKAGE_VERSION
+ ITKPYTHONPACKAGE_ORG
+ ITKPYTHONPACKAGE_TAG
+ MANYLINUX_VERSION
+ TARGET_ARCH
+)
+
+# Sanity Validation loop
+_missing_required=0
+for v in "${required_vars[@]}"; do
+ if [ -z "${!v:-}" ]; then
+ _missing_required=1
+ echo "ERROR: Required environment variable '$v' is not set or empty."
+ fi
+done
+if [ "${_missing_required}" -ne 0 ]; then
+ exit 1
+fi
+unset _missing_required
+
PARSED_ARGS=$(getopt -a -n dockcross-manylinux-download-cache-and-build-module-wheels \
-o hc:x: --long help,cmake_options:,exclude_libs: -- "$@")
eval set -- "$PARSED_ARGS"
-while :
-do
+while :; do
case "$1" in
- -h | --help) usage; break ;;
- --) shift; break ;;
- *) echo "Unexpected option: $1.";
- usage; break ;;
+ -h | --help)
+ usage
+ ;;
+ --)
+ shift
+ break
+ ;;
+ *)
+ echo "Unexpected option: $1."
+ usage
+ ;;
esac
done
# -----------------------------------------------------------------------
# Verify that unzstd binary is available to decompress ITK build archives.
-unzstd_exe=`(which unzstd)`
+unzstd_exe=$(which unzstd)
if [[ -z ${unzstd_exe} ]]; then
echo "ERROR: can not find required binary 'unzstd' "
@@ -73,42 +83,27 @@ ${unzstd_exe} --version
# -----------------------------------------------------------------------
# Fetch build archive
-
-MANYLINUX_VERSION=${MANYLINUX_VERSION:=_2_28}
-TARGET_ARCH=${TARGET_ARCH:=x64}
-
-case ${TARGET_ARCH} in
- x64)
- TARBALL_SPECIALIZATION="-manylinux${MANYLINUX_VERSION}"
- ;;
- *)
- TARBALL_SPECIALIZATION="-manylinux${MANYLINUX_VERSION}_${TARGET_ARCH}"
- ;;
-esac
-TARBALL_NAME="ITKPythonBuilds-linux${TARBALL_SPECIALIZATION}.tar"
+TARBALL_NAME="ITKPythonBuilds-manylinux${MANYLINUX_VERSION}-${TARGET_ARCH}.tar"
if [[ ! -f ${TARBALL_NAME}.zst ]]; then
- echo "Fetching https://github.com/InsightSoftwareConsortium/ITKPythonBuilds/releases/download/${ITK_PACKAGE_VERSION:=v5.4.0}/${TARBALL_NAME}.zst"
- curl -L https://github.com/InsightSoftwareConsortium/ITKPythonBuilds/releases/download/${ITK_PACKAGE_VERSION:=v5.4.0}/${TARBALL_NAME}.zst -O
+ echo "Local ITK cache tarball file not found..."
+ echo "Fetching https://github.com/InsightSoftwareConsortium/ITKPythonBuilds/releases/download/${ITK_PACKAGE_VERSION}/${TARBALL_NAME}.zst"
+ if ! curl -L "https://github.com/InsightSoftwareConsortium/ITKPythonBuilds/releases/download/${ITK_PACKAGE_VERSION}/${TARBALL_NAME}.zst" -O; then
+ echo "FAILED Download:"
+ echo "curl -L https://github.com/InsightSoftwareConsortium/ITKPythonBuilds/releases/download/${ITK_PACKAGE_VERSION}/${TARBALL_NAME}.zst -O"
+ exit 1
+ fi
fi
if [[ ! -f ./${TARBALL_NAME}.zst ]]; then
echo "ERROR: can not find required binary './${TARBALL_NAME}.zst'"
exit 255
fi
-${unzstd_exe} --long=31 ./${TARBALL_NAME}.zst -o ${TARBALL_NAME}
-if [ "$#" -lt 1 ]; then
- echo "Extracting all files";
- tar xf ${TARBALL_NAME}
-else
- echo "Extracting files relevant for: $1";
- tar xf ${TARBALL_NAME} ITKPythonPackage/scripts/
- tar xf ${TARBALL_NAME} ITKPythonPackage/ITK-source/
- tar xf ${TARBALL_NAME} ITKPythonPackage/oneTBB-prefix/
- tar xf ${TARBALL_NAME} --wildcards ITKPythonPackage/ITK-$1*
-fi
-rm ${TARBALL_NAME}
+"${unzstd_exe}" --long=31 "./${TARBALL_NAME}.zst" -o "${TARBALL_NAME}"
-ln -s ITKPythonPackage/oneTBB-prefix ./
+current_dir=$(pwd)
+echo "Extracting all cache files from ${TARBALL_NAME} in ${current_dir}"
+tar xf "${TARBALL_NAME}" --warning=no-unknown-keyword
+rm "${TARBALL_NAME}"
# -----------------------------------------------------------------------
# Optional: Update build scripts
@@ -118,22 +113,22 @@ ln -s ITKPythonPackage/oneTBB-prefix ./
# since the archives were generated.
if [[ -n ${ITKPYTHONPACKAGE_TAG} ]]; then
- echo "Updating build scripts to ${ITKPYTHONPACKAGE_ORG:=InsightSoftwareConsortium}/ITKPythonPackage@${ITKPYTHONPACKAGE_TAG}"
- git clone "https://github.com/${ITKPYTHONPACKAGE_ORG}/ITKPythonPackage.git" "IPP-tmp"
+ # shellcheck disable=SC2153
+ echo "Updating build scripts to ${ITKPYTHONPACKAGE_ORG}/ITKPythonPackage@${ITKPYTHONPACKAGE_TAG}"
+ git clone "https://github.com/${ITKPYTHONPACKAGE_ORG}/ITKPythonPackage.git" "${current_dir}/IPP-tmp"
- pushd IPP-tmp/
+ pushd "${current_dir}/IPP-tmp/" || exit
git checkout "${ITKPYTHONPACKAGE_TAG}"
git status
- popd
+ popd || exit
- rm -rf ITKPythonPackage/scripts/
- cp -r IPP-tmp/scripts ITKPythonPackage/
- cp IPP-tmp/requirements-dev.txt ITKPythonPackage/
- rm -rf IPP-tmp/
+ rm -rf "${current_dir}/ITKPythonPackage/scripts/"
+ rsync -av "${current_dir}"/IPP-tmp/ "${current_dir}/ITKPythonPackage/"
+ rm -rf "${current_dir}/IPP-tmp/"
fi
-if [[ ! -f ./ITKPythonPackage/scripts/dockcross-manylinux-build-module-wheels.sh ]]; then
- echo "ERROR: can not find required binary './ITKPythonPackage/scripts/dockcross-manylinux-build-module-wheels.sh'"
+if [[ ! -f ${current_dir}/ITKPythonPackage/scripts/dockcross-manylinux-build-module-wheels.sh ]]; then
+ echo "ERROR: can not find required binary '${current_dir}/ITKPythonPackage/scripts/dockcross-manylinux-build-module-wheels.sh'"
exit 255
fi
diff --git a/scripts/dockcross-manylinux-set-vars.sh b/scripts/dockcross-manylinux-set-vars.sh
deleted file mode 100755
index f39ce7ab..00000000
--- a/scripts/dockcross-manylinux-set-vars.sh
+++ /dev/null
@@ -1,62 +0,0 @@
-#!/bin/bash
-
-########################################################################
-# Run this script to set common enviroment variables used in building the
-# ITK Python wheel packages for Linux.
-#
-# ENVIRONMENT VARIABLES
-# These environment variables will be populated by the script when invoked with `source`
-# if their value is not set with `export` before invocation.
-# For example,
-#
-# export ITK_PACKAGE_VERSION=v5.4.0
-# scripts/dockcross-manylinux-set-vars.sh cp310
-#
-########################################################################
-
-########################################################################
-# ITKPythonBuilds parameters
-
-# ITKPythonBuilds archive tag to use for ITK build artifacts.
-# See https://github.com/insightSoftwareConsortium/ITKpythonbuilds for available tags.
-ITK_PACKAGE_VERSION=${ITK_PACKAGE_VERSION:=v6.0b01}
-
-# Github organization for fetching ITKPythonPackage build scripts
-ITKPYTHONPACKAGE_ORG=${ITKPYTHONPACKAGE_ORG:=InsightSoftwareConsortium}
-
-# ITKPythonPackage tag for fetching build scripts
-ITKPYTHONPACKAGE_TAG=${ITKPYTHONPACKAGE_TAG:=main}
-
-########################################################################
-# Docker image parameters
-
-# Specialized manylinux image to use for building. Default is _2_28.
-# See https://github.com/dockcross/dockcross for available versions and tags.
-MANYLINUX_VERSION=${MANYLINUX_VERSION:=_2_28}
-
-# Target platform architecture (x64, aarch64)
-TARGET_ARCH=${TARGET_ARCH:=x64}
-
-# Specialized manylinux image tag to use for building.
-if [[ ${MANYLINUX_VERSION} == _2_28 && ${TARGET_ARCH} == x64 ]]; then
- IMAGE_TAG=${IMAGE_TAG:=20260203-3dfb3ff}
-elif [[ ${MANYLINUX_VERSION} == _2_28 && ${TARGET_ARCH} == aarch64 ]]; then
- IMAGE_TAG=${IMAGE_TAG:=2025.08.12-1}
-elif [[ ${MANYLINUX_VERSION} == 2014 ]]; then
- IMAGE_TAG=${IMAGE_TAG:=20240304-9e57d2b}
-else
- echo "Unknown manylinux version ${MANYLINUX_VERSION}"
- exit 1;
-fi
-
-# Set container for requested version/arch/tag.
-if [[ ${TARGET_ARCH} == x64 ]]; then
- MANYLINUX_IMAGE_NAME=${MANYLINUX_IMAGE_NAME:="manylinux${MANYLINUX_VERSION}-${TARGET_ARCH}:${IMAGE_TAG}"}
- CONTAINER_SOURCE="docker.io/dockcross/${MANYLINUX_IMAGE_NAME}"
-elif [[ ${TARGET_ARCH} == aarch64 ]]; then
- MANYLINUX_IMAGE_NAME=${MANYLINUX_IMAGE_NAME:="manylinux${MANYLINUX_VERSION}_${TARGET_ARCH}:${IMAGE_TAG}"}
- CONTAINER_SOURCE="quay.io/pypa/${MANYLINUX_IMAGE_NAME}"
-else
- echo "Unknown target architecture ${TARGET_ARCH}"
- exit 1;
-fi
diff --git a/scripts/docker_build_environment_driver.sh b/scripts/docker_build_environment_driver.sh
new file mode 100755
index 00000000..47dc611a
--- /dev/null
+++ b/scripts/docker_build_environment_driver.sh
@@ -0,0 +1,100 @@
+#!/bin/bash
+
+# Required environment variables
+required_vars=(
+ ITK_GIT_TAG
+ MANYLINUX_VERSION
+ IMAGE_TAG
+ TARGET_ARCH
+ ITKPYTHONPACKAGE_ORG
+ ITKPYTHONPACKAGE_TAG
+ PY_ENVS
+)
+# Sanity Validation loop
+_missing_required=0
+for v in "${required_vars[@]}"; do
+ if [ -z "${!v:-}" ]; then
+ _missing_required=1
+ echo "ERROR: Required environment variable '$v' is not set or empty."
+ fi
+done
+if [ "${_missing_required}" -ne 0 ]; then
+ exit 1
+fi
+unset _missing_required
+
+# -----------------------------------------------------------------------
+# Set up paths
+# These paths are inside the container
+
+CONTAINER_WORK_DIR=/work
+cd "${CONTAINER_WORK_DIR}" || exit
+CONTAINER_PACKAGE_BUILD_DIR=${CONTAINER_WORK_DIR}/ITKPythonPackage-build
+CONTAINER_PACKAGE_SCRIPTS_DIR=${CONTAINER_WORK_DIR}/ITKPythonPackage
+CONTAINER_MODULE_SRC_DIRECTORY=${CONTAINER_WORK_DIR}/$(basename "${MODULE_SRC_DIRECTORY}")
+CONTAINER_ITK_SOURCE_DIR=${CONTAINER_PACKAGE_BUILD_DIR}/ITK
+BUILD_WHEELS_EXTRA_FLAGS=${BUILD_WHEELS_EXTRA_FLAGS:=""}
+read -ra BUILD_WHEELS_EXTRA_FLAGS_ARRAY <<<"${BUILD_WHEELS_EXTRA_FLAGS}"
+
+echo "BUILD FOR ${PY_ENVS}"
+read -ra PY_ENVS_ARRAY <<<"${PY_ENVS}"
+
+for py_indicator in "${PY_ENVS_ARRAY[@]}"; do
+ py_squashed_numeric="${py_indicator//py/}"
+ py_squashed_numeric="${py_squashed_numeric//cp/}"
+ py_squashed_numeric="${py_squashed_numeric//./}"
+ manylinux_vername="${MANYLINUX_VERSION//_/}"
+ PIXI_ENV="manylinux${manylinux_vername}-py${py_squashed_numeric}"
+
+ # Use pixi to ensure all required tools are installed and
+ # visible in the PATH
+ export PIXI_HOME=${CONTAINER_PACKAGE_SCRIPTS_DIR}/.pixi
+ export PATH="${PIXI_HOME}/bin:${PATH}"
+ python3.12 "${CONTAINER_PACKAGE_SCRIPTS_DIR}/scripts/install_pixi.py" --platform-env "${PIXI_ENV}"
+
+ cd "${CONTAINER_PACKAGE_SCRIPTS_DIR}" || exit
+ if [ -n "${MODULE_SRC_DIRECTORY}" ]; then
+ pixi run -e "${PIXI_ENV}" python3 \
+ "${CONTAINER_PACKAGE_SCRIPTS_DIR}/scripts/build_wheels.py" \
+ --platform-env "${PIXI_ENV}" \
+ "${BUILD_WHEELS_EXTRA_FLAGS_ARRAY[@]}" \
+ --module-source-dir "${CONTAINER_MODULE_SRC_DIRECTORY}" \
+ --module-dependencies-root-dir "${CONTAINER_MODULES_ROOT_DIRECTORY}" \
+ --itk-module-deps "${ITK_MODULE_PREQ}" \
+ --no-build-itk-tarball-cache \
+ --build-dir-root "${CONTAINER_PACKAGE_BUILD_DIR}" \
+ --itk-source-dir "${CONTAINER_ITK_SOURCE_DIR}" \
+ --itk-git-tag "${ITK_GIT_TAG}" \
+ --itk-package-version "${ITK_PACKAGE_VERSION:-}" \
+ --manylinux-version "${MANYLINUX_VERSION}" \
+ --no-use-sudo \
+ --no-use-ccache \
+ --skip-itk-build \
+ --skip-itk-wheel-build
+ else
+ pixi run -e "${PIXI_ENV}" python3 \
+ "${CONTAINER_PACKAGE_SCRIPTS_DIR}/scripts/build_wheels.py" \
+ --platform-env "${PIXI_ENV}" \
+ "${BUILD_WHEELS_EXTRA_FLAGS_ARRAY[@]}" \
+ --build-itk-tarball-cache \
+ --build-dir-root "${CONTAINER_PACKAGE_BUILD_DIR}" \
+ --itk-source-dir "${CONTAINER_ITK_SOURCE_DIR}" \
+ --itk-git-tag "${ITK_GIT_TAG}" \
+ --itk-package-version "${ITK_PACKAGE_VERSION:-}" \
+ --manylinux-version "${MANYLINUX_VERSION}" \
+ --no-use-sudo \
+ --no-use-ccache
+ fi
+ build_status=$?
+ if [ "${build_status}" -ne 0 ]; then
+ echo "ERROR: Build failed for ${py_indicator} with exit code ${build_status}"
+ exit "${build_status}"
+ fi
+
+ echo "Successfully built wheel for ${py_indicator}"
+done
+
+echo ""
+echo "========================================"
+echo "All builds completed successfully!"
+echo "========================================"
diff --git a/scripts/install_pixi.py b/scripts/install_pixi.py
new file mode 100755
index 00000000..986e7629
--- /dev/null
+++ b/scripts/install_pixi.py
@@ -0,0 +1,153 @@
+#!/usr/bin/env python3
+
+import os
+from pathlib import Path
+
+from wheel_builder_utils import detect_platform, run_commandLine_subprocess
+
+
+def download_and_install_pixi(
+ binary_ext: str, os_name: str, pixi_home: Path, platform_env: str = "default"
+) -> Path:
+ """Download pixi (if not already present) and install a platform environment.
+
+ Parameters
+ ----------
+ binary_ext : str
+ Executable extension (``'.exe'`` on Windows, ``''`` elsewhere).
+ os_name : str
+ Operating system name (``'windows'``, ``'linux'``, ``'darwin'``).
+ pixi_home : Path
+ Directory where pixi is (or will be) installed.
+ platform_env : str, optional
+ Pixi environment name to install (default ``'default'``).
+
+ Returns
+ -------
+ pixi_exec_path : Path
+ Path to the pixi executable.
+
+ Raises
+ ------
+ RuntimeError
+ If the download, installation, or environment setup fails.
+ """
+ pixi_bin_name: str = "pixi" + binary_ext
+ # Attempt to find an existing pixi binary on the system first (cross-platform)
+ pixi_exec_path: Path = Path(pixi_home) / "bin" / pixi_bin_name
+
+ pixi_install_env = os.environ.copy()
+ pixi_install_env["PIXI_NO_PATH_UPDATE"] = "1"
+ pixi_install_env["PIXI_HOME"] = str(pixi_home)
+
+ # If not found, we will install into the local build .pixi
+ if pixi_exec_path.is_file():
+ print(f"Previous install of pixi will be used {pixi_exec_path}.")
+ else:
+ if os_name == "windows":
+ # Use PowerShell to install pixi on Windows
+ result = run_commandLine_subprocess(
+ [
+ "powershell",
+ "-NoProfile",
+ "-ExecutionPolicy",
+ "Bypass",
+ "-Command",
+ "irm -UseBasicParsing https://pixi.sh/install.ps1 | iex",
+ ],
+ env=pixi_install_env,
+ )
+ if result.returncode != 0:
+ raise RuntimeError(f"Failed to install pixi: {result.stderr}")
+ else:
+ pixi_install_script: Path = pixi_home / "pixi_install.sh"
+ result = run_commandLine_subprocess(
+ [
+ "curl",
+ "-fsSL",
+ "https://pixi.sh/install.sh",
+ "-o",
+ str(pixi_install_script),
+ ]
+ )
+ if result.returncode != 0:
+ raise RuntimeError(
+ f"Failed to download {pixi_install_script}: {result.stderr}"
+ )
+ result = run_commandLine_subprocess(
+ [
+ "/bin/sh",
+ str(pixi_install_script),
+ ],
+ env=pixi_install_env,
+ )
+ if result.returncode != 0:
+ raise RuntimeError(f"Failed to install pixi: {result.stderr}")
+ del pixi_install_script
+
+ if not pixi_exec_path.exists():
+ raise RuntimeError(
+ f"Failed to install {pixi_exec_path} pixi into {pixi_exec_path}"
+ )
+ # Now install the desired platform
+ if (pixi_home.parent / "pixi.toml").exists():
+ result = run_commandLine_subprocess(
+ [pixi_exec_path, "install", "--environment", platform_env],
+ cwd=pixi_home.parent,
+ env=pixi_install_env,
+ )
+ if result.returncode != 0:
+ raise RuntimeError(
+ f"Failed to install environment {platform_env}: {result.stderr}"
+ )
+ else:
+ print(
+ f"pixi.toml not found {pixi_home.parent / 'pixi.toml'}, skipping environment install."
+ )
+ return pixi_exec_path
+
+
+def install_pixi_tools(platform_env: str = "default"):
+ """High-level helper: detect the platform, install pixi, and set up *platform_env*.
+
+ Parameters
+ ----------
+ platform_env : str, optional
+ Pixi environment name to install (default ``'default'``).
+ """
+ _ipp_dir_path: Path = Path(__file__).resolve().parent.parent
+ os_name, arch = detect_platform()
+ binary_ext: str = ".exe" if os_name == "windows" else ""
+
+ pixi_home: Path = Path(
+ os.environ.get("PIXI_HOME")
+ if "PIXI_HOME" in os.environ
+ else _ipp_dir_path / ".pixi"
+ )
+ pixi_home.mkdir(parents=True, exist_ok=True)
+ pixi_exec_path = Path(
+ download_and_install_pixi(binary_ext, os_name, pixi_home, platform_env)
+ )
+ print(f"Installed pixi locally to {pixi_home} with binary of {pixi_exec_path}")
+
+
+if __name__ == "__main__":
+ import argparse
+
+ parser = argparse.ArgumentParser(
+ description="Driver script to build ITK Python wheels."
+ )
+ parser.add_argument(
+ "--platform-env",
+ default="default",
+ help=(
+ """A platform environment name or path:
+ linux-py310, linux-py311,
+ manylinux228-py310, manylinux228-py311,
+ windows-py310, windows-py311,
+ macosx-py310, macosx-py311
+ """
+ ),
+ )
+ args = parser.parse_args()
+ install_pixi_tools(args.platform_env)
diff --git a/scripts/internal/Support.cmake b/scripts/internal/Support.cmake
deleted file mode 100644
index 84487a32..00000000
--- a/scripts/internal/Support.cmake
+++ /dev/null
@@ -1,2749 +0,0 @@
-# Distributed under the OSI-approved BSD 3-Clause License. See accompanying
-# file Copyright.txt or https://cmake.org/licensing for details.
-
-#
-# This file is a "template" file used by various FindPython modules.
-#
-
-cmake_policy (GET CMP0094 _${_PYTHON_PREFIX}_LOOKUP_POLICY)
-
-cmake_policy (VERSION 3.7)
-
-if (_${_PYTHON_PREFIX}_LOOKUP_POLICY)
- cmake_policy (SET CMP0094 ${_${_PYTHON_PREFIX}_LOOKUP_POLICY})
-endif()
-
-#
-# Initial configuration
-#
-if (NOT DEFINED _PYTHON_PREFIX)
- message (FATAL_ERROR "FindPython: INTERNAL ERROR")
-endif()
-if (NOT DEFINED _${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR)
- message (FATAL_ERROR "FindPython: INTERNAL ERROR")
-endif()
-if (_${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR EQUAL "3")
- set(_${_PYTHON_PREFIX}_VERSIONS 3.9 3.8 3.7 3.6 3.5 3.4 3.3 3.2 3.1 3.0)
-elseif (_${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR EQUAL "2")
- set(_${_PYTHON_PREFIX}_VERSIONS 2.7 2.6 2.5 2.4 2.3 2.2 2.1 2.0)
-else()
- message (FATAL_ERROR "FindPython: INTERNAL ERROR")
-endif()
-
-get_property(_${_PYTHON_PREFIX}_CMAKE_ROLE GLOBAL PROPERTY CMAKE_ROLE)
-
-
-#
-# helper commands
-#
-macro (_PYTHON_DISPLAY_FAILURE _PYTHON_MSG)
- if (${_PYTHON_PREFIX}_FIND_REQUIRED)
- message (FATAL_ERROR "${_PYTHON_MSG}")
- else()
- if (NOT ${_PYTHON_PREFIX}_FIND_QUIETLY)
- message(STATUS "${_PYTHON_MSG}")
- endif ()
- endif()
-
- set (${_PYTHON_PREFIX}_FOUND FALSE)
- string (TOUPPER "${_PYTHON_PREFIX}" _${_PYTHON_PREFIX}_UPPER_PREFIX)
- set (${_PYTHON_UPPER_PREFIX}_FOUND FALSE)
- return()
-endmacro()
-
-
-function (_PYTHON_MARK_AS_INTERNAL)
- foreach (var IN LISTS ARGV)
- if (DEFINED CACHE{${var}})
- set_property (CACHE ${var} PROPERTY TYPE INTERNAL)
- endif()
- endforeach()
-endfunction()
-
-
-macro (_PYTHON_SELECT_LIBRARY_CONFIGURATIONS _PYTHON_BASENAME)
- if(NOT DEFINED ${_PYTHON_BASENAME}_LIBRARY_RELEASE)
- set(${_PYTHON_BASENAME}_LIBRARY_RELEASE "${_PYTHON_BASENAME}_LIBRARY_RELEASE-NOTFOUND")
- endif()
- if(NOT DEFINED ${_PYTHON_BASENAME}_LIBRARY_DEBUG)
- set(${_PYTHON_BASENAME}_LIBRARY_DEBUG "${_PYTHON_BASENAME}_LIBRARY_DEBUG-NOTFOUND")
- endif()
-
- get_property(_PYTHON_isMultiConfig GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG)
- if (${_PYTHON_BASENAME}_LIBRARY_DEBUG AND ${_PYTHON_BASENAME}_LIBRARY_RELEASE AND
- NOT ${_PYTHON_BASENAME}_LIBRARY_DEBUG STREQUAL ${_PYTHON_BASENAME}_LIBRARY_RELEASE AND
- (_PYTHON_isMultiConfig OR CMAKE_BUILD_TYPE))
- # if the generator is multi-config or if CMAKE_BUILD_TYPE is set for
- # single-config generators, set optimized and debug libraries
- set (${_PYTHON_BASENAME}_LIBRARIES "")
- foreach (_PYTHON_libname IN LISTS ${_PYTHON_BASENAME}_LIBRARY_RELEASE)
- list( APPEND ${_PYTHON_BASENAME}_LIBRARIES optimized "${_PYTHON_libname}")
- endforeach()
- foreach (_PYTHON_libname IN LISTS ${_PYTHON_BASENAME}_LIBRARY_DEBUG)
- list( APPEND ${_PYTHON_BASENAME}_LIBRARIES debug "${_PYTHON_libname}")
- endforeach()
- elseif (${_PYTHON_BASENAME}_LIBRARY_RELEASE)
- set (${_PYTHON_BASENAME}_LIBRARIES "${${_PYTHON_BASENAME}_LIBRARY_RELEASE}")
- elseif (${_PYTHON_BASENAME}_LIBRARY_DEBUG)
- set (${_PYTHON_BASENAME}_LIBRARIES "${${_PYTHON_BASENAME}_LIBRARY_DEBUG}")
- else()
- set (${_PYTHON_BASENAME}_LIBRARIES "${_PYTHON_BASENAME}_LIBRARY-NOTFOUND")
- endif()
-endmacro()
-
-
-macro (_PYTHON_FIND_FRAMEWORKS)
- set (${_PYTHON_PREFIX}_FRAMEWORKS)
- if (CMAKE_HOST_APPLE OR APPLE)
- file(TO_CMAKE_PATH "$ENV{CMAKE_FRAMEWORK_PATH}" _pff_CMAKE_FRAMEWORK_PATH)
- set (_pff_frameworks ${CMAKE_FRAMEWORK_PATH}
- ${_pff_CMAKE_FRAMEWORK_PATH}
- ~/Library/Frameworks
- /usr/local/Frameworks
- ${CMAKE_SYSTEM_FRAMEWORK_PATH})
- list (REMOVE_DUPLICATES _pff_frameworks)
- foreach (_pff_framework IN LISTS _pff_frameworks)
- if (EXISTS ${_pff_framework}/Python${_${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR}.framework)
- list (APPEND ${_PYTHON_PREFIX}_FRAMEWORKS ${_pff_framework}/Python${_${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR}.framework)
- endif()
- if (EXISTS ${_pff_framework}/Python.framework)
- list (APPEND ${_PYTHON_PREFIX}_FRAMEWORKS ${_pff_framework}/Python.framework)
- endif()
- endforeach()
- unset (_pff_frameworks)
- unset (_pff_framework)
- endif()
-endmacro()
-
-function (_PYTHON_GET_FRAMEWORKS _PYTHON_PGF_FRAMEWORK_PATHS _PYTHON_VERSION)
- set (_PYTHON_FRAMEWORK_PATHS)
- foreach (_PYTHON_FRAMEWORK IN LISTS ${_PYTHON_PREFIX}_FRAMEWORKS)
- list (APPEND _PYTHON_FRAMEWORK_PATHS
- "${_PYTHON_FRAMEWORK}/Versions/${_PYTHON_VERSION}")
- endforeach()
- set (${_PYTHON_PGF_FRAMEWORK_PATHS} ${_PYTHON_FRAMEWORK_PATHS} PARENT_SCOPE)
-endfunction()
-
-function (_PYTHON_GET_REGISTRIES _PYTHON_PGR_REGISTRY_PATHS _PYTHON_VERSION)
- string (REPLACE "." "" _PYTHON_VERSION_NO_DOTS ${_PYTHON_VERSION})
- set (${_PYTHON_PGR_REGISTRY_PATHS}
- [HKEY_CURRENT_USER\\SOFTWARE\\Python\\PythonCore\\${_PYTHON_VERSION}-${_${_PYTHON_PREFIX}_ARCH}\\InstallPath]
- [HKEY_CURRENT_USER\\SOFTWARE\\Python\\PythonCore\\${_PYTHON_VERSION}-${_${_PYTHON_PREFIX}_ARCH2}\\InstallPath]
- [HKEY_CURRENT_USER\\SOFTWARE\\Python\\PythonCore\\${_PYTHON_VERSION}\\InstallPath]
- [HKEY_CURRENT_USER\\SOFTWARE\\Python\\ContinuumAnalytics\\Anaconda${_PYTHON_VERSION_NO_DOTS}-${_${_PYTHON_PREFIX}_ARCH}\\InstallPath]
- [HKEY_CURRENT_USER\\SOFTWARE\\Python\\ContinuumAnalytics\\Anaconda${_PYTHON_VERSION_NO_DOTS}-${_${_PYTHON_PREFIX}_ARCH2}\\InstallPath]
- [HKEY_LOCAL_MACHINE\\SOFTWARE\\Python\\PythonCore\\${_PYTHON_VERSION}-${_${_PYTHON_PREFIX}_ARCH}\\InstallPath]
- [HKEY_LOCAL_MACHINE\\SOFTWARE\\Python\\PythonCore\\${_PYTHON_VERSION}-${_${_PYTHON_PREFIX}_ARCH2}\\InstallPath]
- [HKEY_LOCAL_MACHINE\\SOFTWARE\\Python\\PythonCore\\${_PYTHON_VERSION}\\InstallPath]
- [HKEY_LOCAL_MACHINE\\SOFTWARE\\Python\\ContinuumAnalytics\\Anaconda${_PYTHON_VERSION_NO_DOTS}-${_${_PYTHON_PREFIX}_ARCH}\\InstallPath]
- [HKEY_LOCAL_MACHINE\\SOFTWARE\\Python\\ContinuumAnalytics\\Anaconda${_PYTHON_VERSION_NO_DOTS}-${_${_PYTHON_PREFIX}_ARCH2}\\InstallPath]
- PARENT_SCOPE)
-endfunction()
-
-
-function (_PYTHON_GET_ABIFLAGS _PGABIFLAGS)
- set (abiflags)
- list (GET _${_PYTHON_PREFIX}_FIND_ABI 0 pydebug)
- list (GET _${_PYTHON_PREFIX}_FIND_ABI 1 pymalloc)
- list (GET _${_PYTHON_PREFIX}_FIND_ABI 2 unicode)
-
- if (pymalloc STREQUAL "ANY" AND unicode STREQUAL "ANY")
- set (abiflags "mu" "m" "u" "")
- elseif (pymalloc STREQUAL "ANY" AND unicode STREQUAL "ON")
- set (abiflags "mu" "u")
- elseif (pymalloc STREQUAL "ANY" AND unicode STREQUAL "OFF")
- set (abiflags "m" "")
- elseif (pymalloc STREQUAL "ON" AND unicode STREQUAL "ANY")
- set (abiflags "mu" "m")
- elseif (pymalloc STREQUAL "ON" AND unicode STREQUAL "ON")
- set (abiflags "mu")
- elseif (pymalloc STREQUAL "ON" AND unicode STREQUAL "OFF")
- set (abiflags "m")
- elseif (pymalloc STREQUAL "ON" AND unicode STREQUAL "ANY")
- set (abiflags "u" "")
- elseif (pymalloc STREQUAL "OFF" AND unicode STREQUAL "ON")
- set (abiflags "u")
- endif()
-
- if (pydebug STREQUAL "ON")
- if (abiflags)
- list (TRANSFORM abiflags PREPEND "d")
- else()
- set (abiflags "d")
- endif()
- elseif (pydebug STREQUAL "ANY")
- if (abiflags)
- set (flags "${abiflags}")
- list (TRANSFORM flags PREPEND "d")
- list (APPEND abiflags "${flags}")
- else()
- set (abiflags "" "d")
- endif()
- endif()
-
- set (${_PGABIFLAGS} "${abiflags}" PARENT_SCOPE)
-endfunction()
-
-function (_PYTHON_GET_PATH_SUFFIXES _PYTHON_PGPS_PATH_SUFFIXES)
- cmake_parse_arguments (PARSE_ARGV 1 _PGPS "LIBRARY;INCLUDE" "VERSION" "")
-
- if (DEFINED _${_PYTHON_PREFIX}_ABIFLAGS)
- set (abi "${_${_PYTHON_PREFIX}_ABIFLAGS}")
- else()
- set (abi "mu" "m" "u" "")
- endif()
-
- set (path_suffixes)
- if (_PGPS_LIBRARY)
- if (CMAKE_LIBRARY_ARCHITECTURE)
- list (APPEND path_suffixes lib/${CMAKE_LIBRARY_ARCHITECTURE})
- endif()
- list (APPEND path_suffixes lib libs)
-
- if (CMAKE_LIBRARY_ARCHITECTURE)
- set (suffixes "${abi}")
- if (suffixes)
- list (TRANSFORM suffixes PREPEND "lib/python${_PGPS_VERSION}/config-${_PGPS_VERSION}")
- list (TRANSFORM suffixes APPEND "-${CMAKE_LIBRARY_ARCHITECTURE}")
- else()
- set (suffixes "lib/python${_PGPS_VERSION}/config-${_PGPS_VERSION}-${CMAKE_LIBRARY_ARCHITECTURE}")
- endif()
- list (APPEND path_suffixes ${suffixes})
- endif()
- set (suffixes "${abi}")
- if (suffixes)
- list (TRANSFORM suffixes PREPEND "lib/python${_PGPS_VERSION}/config-${_PGPS_VERSION}")
- else()
- set (suffixes "lib/python${_PGPS_VERSION}/config-${_PGPS_VERSION}")
- endif()
- list (APPEND path_suffixes ${suffixes})
- elseif (_PGPS_INCLUDE)
- set (suffixes "${abi}")
- if (suffixes)
- list (TRANSFORM suffixes PREPEND "include/python${_PGPS_VERSION}")
- else()
- set (suffixes "include/python${_PGPS_VERSION}")
- endif()
- list (APPEND path_suffixes ${suffixes} include)
- endif()
-
- set (${_PYTHON_PGPS_PATH_SUFFIXES} ${path_suffixes} PARENT_SCOPE)
-endfunction()
-
-function (_PYTHON_GET_NAMES _PYTHON_PGN_NAMES)
- cmake_parse_arguments (PARSE_ARGV 1 _PGN "POSIX;EXECUTABLE;CONFIG;LIBRARY;WIN32;DEBUG" "VERSION" "")
-
- set (names)
-
- if (_PGN_WIN32)
- string (REPLACE "." "" _PYTHON_VERSION_NO_DOTS ${_PGN_VERSION})
-
- set (name python${_PYTHON_VERSION_NO_DOTS})
- if (_PGN_DEBUG)
- string (APPEND name "_d")
- endif()
-
- list (APPEND names "${name}")
- endif()
-
- if (_PGN_POSIX)
- if (DEFINED _${_PYTHON_PREFIX}_ABIFLAGS)
- set (abi "${_${_PYTHON_PREFIX}_ABIFLAGS}")
- else()
- if (_PGN_EXECUTABLE OR _PGN_CONFIG)
- set (abi "")
- else()
- set (abi "mu" "m" "u" "")
- endif()
- endif()
-
- if (abi)
- if (_PGN_CONFIG AND DEFINED CMAKE_LIBRARY_ARCHITECTURE)
- set (abinames "${abi}")
- list (TRANSFORM abinames PREPEND "${CMAKE_LIBRARY_ARCHITECTURE}-python${_PGN_VERSION}")
- list (TRANSFORM abinames APPEND "-config")
- list (APPEND names ${abinames})
- endif()
- set (abinames "${abi}")
- list (TRANSFORM abinames PREPEND "python${_PGN_VERSION}")
- if (_PGN_CONFIG)
- list (TRANSFORM abinames APPEND "-config")
- endif()
- list (APPEND names ${abinames})
- else()
- if (_PGN_CONFIG AND DEFINED CMAKE_LIBRARY_ARCHITECTURE)
- set (abinames "${CMAKE_LIBRARY_ARCHITECTURE}-python${_PGN_VERSION}")
- endif()
- list (APPEND abinames "python${_PGN_VERSION}")
- if (_PGN_CONFIG)
- list (TRANSFORM abinames APPEND "-config")
- endif()
- list (APPEND names ${abinames})
- endif()
- endif()
-
- set (${_PYTHON_PGN_NAMES} ${names} PARENT_SCOPE)
-endfunction()
-
-function (_PYTHON_GET_CONFIG_VAR _PYTHON_PGCV_VALUE NAME)
- unset (${_PYTHON_PGCV_VALUE} PARENT_SCOPE)
-
- if (NOT NAME MATCHES "^(PREFIX|ABIFLAGS|CONFIGDIR|INCLUDES|LIBS|SOABI)$")
- return()
- endif()
-
- if (_${_PYTHON_PREFIX}_CONFIG)
- if (NAME STREQUAL "SOABI")
- set (config_flag "--extension-suffix")
- else()
- set (config_flag "--${NAME}")
- endif()
- string (TOLOWER "${config_flag}" config_flag)
- execute_process (COMMAND "${_${_PYTHON_PREFIX}_CONFIG}" ${config_flag}
- RESULT_VARIABLE _result
- OUTPUT_VARIABLE _values
- ERROR_QUIET
- OUTPUT_STRIP_TRAILING_WHITESPACE)
- if (_result)
- unset (_values)
- else()
- if (NAME STREQUAL "INCLUDES")
- # do some clean-up
- string (REGEX MATCHALL "(-I|-iwithsysroot)[ ]*[^ ]+" _values "${_values}")
- string (REGEX REPLACE "(-I|-iwithsysroot)[ ]*" "" _values "${_values}")
- list (REMOVE_DUPLICATES _values)
- elseif (NAME STREQUAL "SOABI")
- # clean-up: remove prefix character and suffix
- string (REGEX REPLACE "^[.-](.+)(${CMAKE_SHARED_LIBRARY_SUFFIX}|\\.(so|pyd))$" "\\1" _values "${_values}")
- endif()
- endif()
- endif()
-
- if (_${_PYTHON_PREFIX}_EXECUTABLE AND NOT CMAKE_CROSSCOMPILING)
- if (NAME STREQUAL "PREFIX")
- execute_process (COMMAND "${_${_PYTHON_PREFIX}_EXECUTABLE}" -c "import sys\ntry:\n from distutils import sysconfig\n sys.stdout.write(';'.join([sysconfig.PREFIX,sysconfig.EXEC_PREFIX,sysconfig.BASE_EXEC_PREFIX]))\nexcept Exception:\n import sysconfig\n sys.stdout.write(';'.join([sysconfig.get_config_var('base') or '', sysconfig.get_config_var('installed_base') or '']))"
- RESULT_VARIABLE _result
- OUTPUT_VARIABLE _values
- ERROR_QUIET
- OUTPUT_STRIP_TRAILING_WHITESPACE)
- if (_result)
- unset (_values)
- else()
- list (REMOVE_DUPLICATES _values)
- endif()
- elseif (NAME STREQUAL "INCLUDES")
- if (WIN32)
- set (_scheme "nt")
- else()
- set (_scheme "posix_prefix")
- endif()
- execute_process (COMMAND "${_${_PYTHON_PREFIX}_EXECUTABLE}" -c "import sys\ntry:\n from distutils import sysconfig\n sys.stdout.write(';'.join([sysconfig.get_python_inc(plat_specific=True),sysconfig.get_python_inc(plat_specific=False)]))\nexcept Exception:\n import sysconfig\n sys.stdout.write(';'.join([sysconfig.get_path('platinclude'),sysconfig.get_path('platinclude','${_scheme}'),sysconfig.get_path('include'),sysconfig.get_path('include','${_scheme}')]))"
- RESULT_VARIABLE _result
- OUTPUT_VARIABLE _values
- ERROR_QUIET
- OUTPUT_STRIP_TRAILING_WHITESPACE)
- if (_result)
- unset (_values)
- else()
- list (REMOVE_DUPLICATES _values)
- endif()
- elseif (NAME STREQUAL "SOABI")
- execute_process (COMMAND "${_${_PYTHON_PREFIX}_EXECUTABLE}" -c "import sys\ntry:\n from distutils import sysconfig\n sys.stdout.write(';'.join([sysconfig.get_config_var('SOABI') or '',sysconfig.get_config_var('EXT_SUFFIX') or '']))\nexcept Exception:\n import sysconfig;sys.stdout.write(';'.join([sysconfig.get_config_var('SOABI') or '',sysconfig.get_config_var('EXT_SUFFIX') or '']))"
- RESULT_VARIABLE _result
- OUTPUT_VARIABLE _soabi
- ERROR_QUIET
- OUTPUT_STRIP_TRAILING_WHITESPACE)
- if (_result)
- unset (_values)
- else()
- foreach (_item IN LISTS _soabi)
- if (_item)
- set (_values "${_item}")
- break()
- endif()
- endforeach()
- if (_values)
- # clean-up: remove prefix character and suffix
- string (REGEX REPLACE "^[.-](.+)(${CMAKE_SHARED_LIBRARY_SUFFIX}|\\.(so|pyd))$" "\\1" _values "${_values}")
- endif()
- endif()
- else()
- set (config_flag "${NAME}")
- if (NAME STREQUAL "CONFIGDIR")
- set (config_flag "LIBPL")
- endif()
- execute_process (COMMAND "${_${_PYTHON_PREFIX}_EXECUTABLE}" -c "import sys\ntry:\n from distutils import sysconfig\n sys.stdout.write(sysconfig.get_config_var('${config_flag}'))\nexcept Exception:\n import sysconfig\n sys.stdout.write(sysconfig.get_config_var('${config_flag}'))"
- RESULT_VARIABLE _result
- OUTPUT_VARIABLE _values
- ERROR_QUIET
- OUTPUT_STRIP_TRAILING_WHITESPACE)
- if (_result)
- unset (_values)
- endif()
- endif()
- endif()
-
- if (config_flag STREQUAL "ABIFLAGS")
- set (${_PYTHON_PGCV_VALUE} "${_values}" PARENT_SCOPE)
- return()
- endif()
-
- if (NOT _values OR _values STREQUAL "None")
- return()
- endif()
-
- if (NAME STREQUAL "LIBS")
- # do some clean-up
- string (REGEX MATCHALL "-(l|framework)[ ]*[^ ]+" _values "${_values}")
- # remove elements relative to python library itself
- list (FILTER _values EXCLUDE REGEX "-lpython")
- list (REMOVE_DUPLICATES _values)
- endif()
-
- if (WIN32 AND NAME MATCHES "^(PREFIX|CONFIGDIR|INCLUDES)$")
- file (TO_CMAKE_PATH "${_values}" _values)
- endif()
-
- set (${_PYTHON_PGCV_VALUE} "${_values}" PARENT_SCOPE)
-endfunction()
-
-function (_PYTHON_GET_VERSION)
- cmake_parse_arguments (PARSE_ARGV 0 _PGV "LIBRARY;INCLUDE" "PREFIX" "")
-
- unset (${_PGV_PREFIX}VERSION PARENT_SCOPE)
- unset (${_PGV_PREFIX}VERSION_MAJOR PARENT_SCOPE)
- unset (${_PGV_PREFIX}VERSION_MINOR PARENT_SCOPE)
- unset (${_PGV_PREFIX}VERSION_PATCH PARENT_SCOPE)
- unset (${_PGV_PREFIX}ABI PARENT_SCOPE)
-
- if (_PGV_LIBRARY)
- # retrieve version and abi from library name
- if (_${_PYTHON_PREFIX}_LIBRARY_RELEASE)
- # extract version from library name
- if (_${_PYTHON_PREFIX}_LIBRARY_RELEASE MATCHES "python([23])([0-9]+)")
- set (${_PGV_PREFIX}VERSION_MAJOR "${CMAKE_MATCH_1}" PARENT_SCOPE)
- set (${_PGV_PREFIX}VERSION_MINOR "${CMAKE_MATCH_2}" PARENT_SCOPE)
- set (${_PGV_PREFIX}VERSION "${CMAKE_MATCH_1}.${CMAKE_MATCH_2}" PARENT_SCOPE)
- set (${_PGV_PREFIX}ABI "" PARENT_SCOPE)
- elseif (_${_PYTHON_PREFIX}_LIBRARY_RELEASE MATCHES "python([23])\\.([0-9]+)([dmu]*)")
- set (${_PGV_PREFIX}VERSION_MAJOR "${CMAKE_MATCH_1}" PARENT_SCOPE)
- set (${_PGV_PREFIX}VERSION_MINOR "${CMAKE_MATCH_2}" PARENT_SCOPE)
- set (${_PGV_PREFIX}VERSION "${CMAKE_MATCH_1}.${CMAKE_MATCH_2}" PARENT_SCOPE)
- set (${_PGV_PREFIX}ABI "${CMAKE_MATCH_3}" PARENT_SCOPE)
- endif()
- endif()
- else()
- if (_${_PYTHON_PREFIX}_INCLUDE_DIR)
- # retrieve version from header file
- file (STRINGS "${_${_PYTHON_PREFIX}_INCLUDE_DIR}/patchlevel.h" version
- REGEX "^#define[ \t]+PY_VERSION[ \t]+\"[^\"]+\"")
- string (REGEX REPLACE "^#define[ \t]+PY_VERSION[ \t]+\"([^\"]+)\".*" "\\1"
- version "${version}")
- string (REGEX MATCHALL "[0-9]+" versions "${version}")
- list (GET versions 0 version_major)
- list (GET versions 1 version_minor)
- list (GET versions 2 version_patch)
-
- set (${_PGV_PREFIX}VERSION "${version_major}.${version_minor}" PARENT_SCOPE)
- set (${_PGV_PREFIX}VERSION_MAJOR ${version_major} PARENT_SCOPE)
- set (${_PGV_PREFIX}VERSION_MINOR ${version_minor} PARENT_SCOPE)
- set (${_PGV_PREFIX}VERSION_PATCH ${version_patch} PARENT_SCOPE)
-
- # compute ABI flags
- if (version_major VERSION_GREATER "2")
- file (STRINGS "${_${_PYTHON_PREFIX}_INCLUDE_DIR}/pyconfig.h" config REGEX "(Py_DEBUG|WITH_PYMALLOC|Py_UNICODE_SIZE|MS_WIN32)")
- set (abi)
- if (config MATCHES "#[ ]*define[ ]+MS_WIN32")
- # ABI not used on Windows
- set (abi "")
- else()
- if (config MATCHES "#[ ]*define[ ]+Py_DEBUG[ ]+1")
- string (APPEND abi "d")
- endif()
- if (config MATCHES "#[ ]*define[ ]+WITH_PYMALLOC[ ]+1")
- string (APPEND abi "m")
- endif()
- if (config MATCHES "#[ ]*define[ ]+Py_UNICODE_SIZE[ ]+4")
- string (APPEND abi "u")
- endif()
- set (${_PGV_PREFIX}ABI "${abi}" PARENT_SCOPE)
- endif()
- else()
- # ABI not supported
- set (${_PGV_PREFIX}ABI "" PARENT_SCOPE)
- endif()
- endif()
- endif()
-endfunction()
-
-
-function (_PYTHON_VALIDATE_INTERPRETER)
- if (NOT _${_PYTHON_PREFIX}_EXECUTABLE)
- return()
- endif()
-
- cmake_parse_arguments (PARSE_ARGV 0 _PVI "EXACT;CHECK_EXISTS" "" "")
- if (_PVI_UNPARSED_ARGUMENTS)
- set (expected_version ${_PVI_UNPARSED_ARGUMENTS})
- else()
- unset (expected_version)
- endif()
-
- if (_PVI_CHECK_EXISTS AND NOT EXISTS "${_${_PYTHON_PREFIX}_EXECUTABLE}")
- # interpreter does not exist anymore
- set (_${_PYTHON_PREFIX}_Interpreter_REASON_FAILURE "Cannot find the interpreter \"${_${_PYTHON_PREFIX}_EXECUTABLE}\"")
- set_property (CACHE _${_PYTHON_PREFIX}_EXECUTABLE PROPERTY VALUE "${_PYTHON_PREFIX}_EXECUTABLE-NOTFOUND")
- return()
- endif()
-
- # validate ABI compatibility
- if (DEFINED _${_PYTHON_PREFIX}_FIND_ABI)
- execute_process (COMMAND "${_${_PYTHON_PREFIX}_EXECUTABLE}" -c
- "import sys; sys.stdout.write(sys.abiflags)"
- RESULT_VARIABLE result
- OUTPUT_VARIABLE abi
- ERROR_QUIET
- OUTPUT_STRIP_TRAILING_WHITESPACE)
- if (result)
- # assume ABI is not supported
- set (abi "")
- endif()
- if (NOT abi IN_LIST _${_PYTHON_PREFIX}_ABIFLAGS)
- # incompatible ABI
- set (_${_PYTHON_PREFIX}_Interpreter_REASON_FAILURE "Wrong ABI for the interpreter \"${_${_PYTHON_PREFIX}_EXECUTABLE}\"")
- set_property (CACHE _${_PYTHON_PREFIX}_EXECUTABLE PROPERTY VALUE "${_PYTHON_PREFIX}_EXECUTABLE-NOTFOUND")
- return()
- endif()
- endif()
-
- get_filename_component (python_name "${_${_PYTHON_PREFIX}_EXECUTABLE}" NAME)
-
- if (expected_version AND NOT python_name STREQUAL "python${expected_version}${abi}${CMAKE_EXECUTABLE_SUFFIX}")
- # executable found must have a specific version
- execute_process (COMMAND "${_${_PYTHON_PREFIX}_EXECUTABLE}" -c
- "import sys; sys.stdout.write('.'.join([str(x) for x in sys.version_info[:2]]))"
- RESULT_VARIABLE result
- OUTPUT_VARIABLE version
- ERROR_QUIET
- OUTPUT_STRIP_TRAILING_WHITESPACE)
- if (result)
- # interpreter is not usable
- set (_${_PYTHON_PREFIX}_Interpreter_REASON_FAILURE "Cannot use the interpreter \"${_${_PYTHON_PREFIX}_EXECUTABLE}\"")
- set_property (CACHE _${_PYTHON_PREFIX}_EXECUTABLE PROPERTY VALUE "${_PYTHON_PREFIX}_EXECUTABLE-NOTFOUND")
- else()
- if (_PVI_EXACT AND NOT version VERSION_EQUAL expected_version)
- # interpreter has wrong version
- set (_${_PYTHON_PREFIX}_Interpreter_REASON_FAILURE "Wrong version for the interpreter \"${_${_PYTHON_PREFIX}_EXECUTABLE}\"")
- set_property (CACHE _${_PYTHON_PREFIX}_EXECUTABLE PROPERTY VALUE "${_PYTHON_PREFIX}_EXECUTABLE-NOTFOUND")
- else()
- # check that version is OK
- string(REGEX REPLACE "^([0-9]+)\\..*$" "\\1" major_version "${version}")
- string(REGEX REPLACE "^([0-9]+)\\.?.*$" "\\1" expected_major_version "${expected_version}")
- if (NOT major_version VERSION_EQUAL expected_major_version
- OR NOT version VERSION_GREATER_EQUAL expected_version)
- set (_${_PYTHON_PREFIX}_Interpreter_REASON_FAILURE "Wrong version for the interpreter \"${_${_PYTHON_PREFIX}_EXECUTABLE}\"")
- set_property (CACHE _${_PYTHON_PREFIX}_EXECUTABLE PROPERTY VALUE "${_PYTHON_PREFIX}_EXECUTABLE-NOTFOUND")
- endif()
- endif()
- endif()
- if (NOT _${_PYTHON_PREFIX}_EXECUTABLE)
- return()
- endif()
- else()
- if (NOT python_name STREQUAL "python${_${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR}${CMAKE_EXECUTABLE_SUFFIX}")
- # executable found do not have version in name
- # ensure major version is OK
- execute_process (COMMAND "${_${_PYTHON_PREFIX}_EXECUTABLE}" -c
- "import sys; sys.stdout.write(str(sys.version_info[0]))"
- RESULT_VARIABLE result
- OUTPUT_VARIABLE version
- ERROR_QUIET
- OUTPUT_STRIP_TRAILING_WHITESPACE)
- if (result OR NOT version EQUAL _${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR)
- # interpreter not usable or has wrong major version
- if (result)
- set (_${_PYTHON_PREFIX}_Interpreter_REASON_FAILURE "Cannot use the interpreter \"${_${_PYTHON_PREFIX}_EXECUTABLE}\"")
- else()
- set (_${_PYTHON_PREFIX}_Interpreter_REASON_FAILURE "Wrong major version for the interpreter \"${_${_PYTHON_PREFIX}_EXECUTABLE}\"")
- endif()
- set_property (CACHE _${_PYTHON_PREFIX}_EXECUTABLE PROPERTY VALUE "${_PYTHON_PREFIX}_EXECUTABLE-NOTFOUND")
- return()
- endif()
- endif()
- endif()
-
- if (CMAKE_SIZEOF_VOID_P AND ("Development.Module" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS
- OR "Development.Embed" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS)
- AND NOT CMAKE_CROSSCOMPILING)
- # In this case, interpreter must have same architecture as environment
- execute_process (COMMAND "${_${_PYTHON_PREFIX}_EXECUTABLE}" -c
- "import sys, struct; sys.stdout.write(str(struct.calcsize(\"P\")))"
- RESULT_VARIABLE result
- OUTPUT_VARIABLE size
- ERROR_QUIET
- OUTPUT_STRIP_TRAILING_WHITESPACE)
- if (result OR NOT size EQUAL CMAKE_SIZEOF_VOID_P)
- # interpreter not usable or has wrong architecture
- if (result)
- set (_${_PYTHON_PREFIX}_Interpreter_REASON_FAILURE "Cannot use the interpreter \"${_${_PYTHON_PREFIX}_EXECUTABLE}\"")
- else()
- set (_${_PYTHON_PREFIX}_Interpreter_REASON_FAILURE "Wrong architecture for the interpreter \"${_${_PYTHON_PREFIX}_EXECUTABLE}\"")
- endif()
- set_property (CACHE _${_PYTHON_PREFIX}_EXECUTABLE PROPERTY VALUE "${_PYTHON_PREFIX}_EXECUTABLE-NOTFOUND")
- return()
- endif()
- endif()
-endfunction()
-
-
-function (_PYTHON_VALIDATE_COMPILER expected_version)
- if (NOT _${_PYTHON_PREFIX}_COMPILER)
- return()
- endif()
-
- cmake_parse_arguments (_PVC "EXACT;CHECK_EXISTS" "" "" ${ARGN})
- if (_PVC_UNPARSED_ARGUMENTS)
- set (major_version FALSE)
- set (expected_version ${_PVC_UNPARSED_ARGUMENTS})
- else()
- set (major_version TRUE)
- set (expected_version ${_${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR})
- set (_PVC_EXACT TRUE)
- endif()
-
- if (_PVC_CHECK_EXISTS AND NOT EXISTS "${_${_PYTHON_PREFIX}_COMPILER}")
- # Compiler does not exist anymore
- set (_${_PYTHON_PREFIX}_Compiler_REASON_FAILURE "Cannot find the compiler \"${_${_PYTHON_PREFIX}_COMPILER}\"")
- set_property (CACHE _${_PYTHON_PREFIX}_COMPILER PROPERTY VALUE "${_PYTHON_PREFIX}_COMPILER-NOTFOUND")
- return()
- endif()
-
- # retrieve python environment version from compiler
- set (working_dir "${CMAKE_CURRENT_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/PythonCompilerVersion.dir")
- if (major_version)
- # check only major version
- file (WRITE "${working_dir}/version.py" "import sys; sys.stdout.write(str(sys.version_info[0]))")
- else()
- file (WRITE "${working_dir}/version.py" "import sys; sys.stdout.write('.'.join([str(x) for x in sys.version_info[:2]]))\n")
- endif()
- execute_process (COMMAND "${_${_PYTHON_PREFIX}_COMPILER}" /target:exe /embed "${working_dir}/version.py"
- WORKING_DIRECTORY "${working_dir}"
- OUTPUT_QUIET
- ERROR_QUIET
- OUTPUT_STRIP_TRAILING_WHITESPACE)
- execute_process (COMMAND "${working_dir}/version"
- WORKING_DIRECTORY "${working_dir}"
- RESULT_VARIABLE result
- OUTPUT_VARIABLE version
- ERROR_QUIET)
- file (REMOVE_RECURSE "${_${_PYTHON_PREFIX}_VERSION_DIR}")
-
- if (result OR (_PVC_EXACT AND NOT version VERSION_EQUAL expected_version) OR (version VERSION_LESS expected_version))
- # Compiler not usable or has wrong version
- if (result)
- set (_${_PYTHON_PREFIX}_Compiler_REASON_FAILURE "Cannot use the compiler \"${_${_PYTHON_PREFIX}_COMPILER}\"")
- else()
- set (_${_PYTHON_PREFIX}_Compiler_REASON_FAILURE "Wrong version for the compiler \"${_${_PYTHON_PREFIX}_COMPILER}\"")
- endif()
- set_property (CACHE _${_PYTHON_PREFIX}_COMPILER PROPERTY VALUE "${_PYTHON_PREFIX}_COMPILER-NOTFOUND")
- endif()
-endfunction()
-
-
-function (_PYTHON_VALIDATE_LIBRARY)
- if (NOT _${_PYTHON_PREFIX}_LIBRARY_RELEASE)
- unset (_${_PYTHON_PREFIX}_LIBRARY_DEBUG)
- return()
- endif()
-
- cmake_parse_arguments (PARSE_ARGV 0 _PVL "EXACT;CHECK_EXISTS" "" "")
- if (_PVL_UNPARSED_ARGUMENTS)
- set (expected_version ${_PVL_UNPARSED_ARGUMENTS})
- else()
- unset (expected_version)
- endif()
-
- if (_PVL_CHECK_EXISTS AND NOT EXISTS "${_${_PYTHON_PREFIX}_LIBRARY_RELEASE}")
- # library does not exist anymore
- set (_${_PYTHON_PREFIX}_Development_REASON_FAILURE "Cannot find the library \"${_${_PYTHON_PREFIX}_LIBRARY_RELEASE}\"")
- set_property (CACHE _${_PYTHON_PREFIX}_LIBRARY_RELEASE PROPERTY VALUE "${_PYTHON_PREFIX}_LIBRARY_RELEASE-NOTFOUND")
- if (WIN32)
- set_property (CACHE _${_PYTHON_PREFIX}_LIBRARY_DEBUG PROPERTY VALUE "${_PYTHON_PREFIX}_LIBRARY_DEBUG-NOTFOUND")
- endif()
- set_property (CACHE _${_PYTHON_PREFIX}_INCLUDE_DIR PROPERTY VALUE "${_PYTHON_PREFIX}_INCLUDE_DIR-NOTFOUND")
- return()
- endif()
-
- # retrieve version and abi from library name
- _python_get_version (LIBRARY PREFIX lib_)
-
- if (DEFINED _${_PYTHON_PREFIX}_FIND_ABI AND NOT lib_ABI IN_LIST _${_PYTHON_PREFIX}_ABIFLAGS)
- # incompatible ABI
- set (_${_PYTHON_PREFIX}_Development_REASON_FAILURE "Wrong ABI for the library \"${_${_PYTHON_PREFIX}_LIBRARY_RELEASE}\"")
- set_property (CACHE _${_PYTHON_PREFIX}_LIBRARY_RELEASE PROPERTY VALUE "${_PYTHON_PREFIX}_LIBRARY_RELEASE-NOTFOUND")
- else()
- if (expected_version)
- if ((_PVL_EXACT AND NOT lib_VERSION VERSION_EQUAL expected_version) OR (lib_VERSION VERSION_LESS expected_version))
- # library has wrong version
- set (_${_PYTHON_PREFIX}_Development_REASON_FAILURE "Wrong version for the library \"${_${_PYTHON_PREFIX}_LIBRARY_RELEASE}\"")
- set_property (CACHE _${_PYTHON_PREFIX}_LIBRARY_RELEASE PROPERTY VALUE "${_PYTHON_PREFIX}_LIBRARY_RELEASE-NOTFOUND")
- endif()
- else()
- if (NOT lib_VERSION_MAJOR VERSION_EQUAL _${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR)
- # library has wrong major version
- set (_${_PYTHON_PREFIX}_Development_REASON_FAILURE "Wrong major version for the library \"${_${_PYTHON_PREFIX}_LIBRARY_RELEASE}\"")
- set_property (CACHE _${_PYTHON_PREFIX}_LIBRARY_RELEASE PROPERTY VALUE "${_PYTHON_PREFIX}_LIBRARY_RELEASE-NOTFOUND")
- endif()
- endif()
- endif()
-
- if (NOT _${_PYTHON_PREFIX}_LIBRARY_RELEASE)
- if (WIN32)
- set_property (CACHE _${_PYTHON_PREFIX}_LIBRARY_DEBUG PROPERTY VALUE "${_PYTHON_PREFIX}_LIBRARY_DEBUG-NOTFOUND")
- endif()
- unset (_${_PYTHON_PREFIX}_RUNTIME_LIBRARY_RELEASE CACHE)
- unset (_${_PYTHON_PREFIX}_RUNTIME_LIBRARY_DEBUG CACHE)
- set_property (CACHE _${_PYTHON_PREFIX}_INCLUDE_DIR PROPERTY VALUE "${_PYTHON_PREFIX}_INCLUDE_DIR-NOTFOUND")
- endif()
-endfunction()
-
-
-function (_PYTHON_VALIDATE_INCLUDE_DIR)
- if (NOT _${_PYTHON_PREFIX}_INCLUDE_DIR)
- return()
- endif()
-
- cmake_parse_arguments (PARSE_ARGV 0 _PVID "EXACT;CHECK_EXISTS" "" "")
- if (_PVID_UNPARSED_ARGUMENTS)
- set (expected_version ${_PVID_UNPARSED_ARGUMENTS})
- else()
- unset (expected_version)
- endif()
-
- if (_PVID_CHECK_EXISTS AND NOT EXISTS "${_${_PYTHON_PREFIX}_INCLUDE_DIR}")
- # include file does not exist anymore
- set (_${_PYTHON_PREFIX}_Development_REASON_FAILURE "Cannot find the directory \"${_${_PYTHON_PREFIX}_INCLUDE_DIR}\"")
- set_property (CACHE _${_PYTHON_PREFIX}_INCLUDE_DIR PROPERTY VALUE "${_PYTHON_PREFIX}_INCLUDE_DIR-NOTFOUND")
- return()
- endif()
-
- # retrieve version from header file
- _python_get_version (INCLUDE PREFIX inc_)
-
- if (DEFINED _${_PYTHON_PREFIX}_FIND_ABI AND NOT inc_ABI IN_LIST _${_PYTHON_PREFIX}_ABIFLAGS)
- # incompatible ABI
- set (_${_PYTHON_PREFIX}_Development_REASON_FAILURE "Wrong ABI for the directory \"${_${_PYTHON_PREFIX}_INCLUDE_DIR}\"")
- set_property (CACHE _${_PYTHON_PREFIX}_INCLUDE_DIR PROPERTY VALUE "${_PYTHON_PREFIX}_INCLUDE_DIR-NOTFOUND")
- else()
- if (expected_version)
- if ((_PVID_EXACT AND NOT inc_VERSION VERSION_EQUAL expected_version) OR (inc_VERSION VERSION_LESS expected_version))
- # include dir has wrong version
- set (_${_PYTHON_PREFIX}_Development_REASON_FAILURE "Wrong version for the directory \"${_${_PYTHON_PREFIX}_INCLUDE_DIR}\"")
- set_property (CACHE _${_PYTHON_PREFIX}_INCLUDE_DIR PROPERTY VALUE "${_PYTHON_PREFIX}_INCLUDE_DIR-NOTFOUND")
- endif()
- else()
- if (NOT inc_VERSION_MAJOR VERSION_EQUAL _${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR)
- # include dir has wrong major version
- set (_${_PYTHON_PREFIX}_Development_REASON_FAILURE "Wrong major version for the directory \"${_${_PYTHON_PREFIX}_INCLUDE_DIR}\"")
- set_property (CACHE _${_PYTHON_PREFIX}_INCLUDE_DIR PROPERTY VALUE "${_PYTHON_PREFIX}_INCLUDE_DIR-NOTFOUND")
- endif()
- endif()
- endif()
-endfunction()
-
-
-function (_PYTHON_FIND_RUNTIME_LIBRARY _PYTHON_LIB)
- string (REPLACE "_RUNTIME" "" _PYTHON_LIB "${_PYTHON_LIB}")
- # look at runtime part on systems supporting it
- if (CMAKE_SYSTEM_NAME STREQUAL "Windows" OR
- (CMAKE_SYSTEM_NAME MATCHES "MSYS|CYGWIN"
- AND ${_PYTHON_LIB} MATCHES "${CMAKE_IMPORT_LIBRARY_SUFFIX}$"))
- set (CMAKE_FIND_LIBRARY_SUFFIXES ${CMAKE_SHARED_LIBRARY_SUFFIX})
- # MSYS has a special syntax for runtime libraries
- if (CMAKE_SYSTEM_NAME MATCHES "MSYS")
- list (APPEND CMAKE_FIND_LIBRARY_PREFIXES "msys-")
- endif()
- find_library (${ARGV})
- endif()
-endfunction()
-
-
-function (_PYTHON_SET_LIBRARY_DIRS _PYTHON_SLD_RESULT)
- unset (_PYTHON_DIRS)
- set (_PYTHON_LIBS ${ARGN})
- foreach (_PYTHON_LIB IN LISTS _PYTHON_LIBS)
- if (${_PYTHON_LIB})
- get_filename_component (_PYTHON_DIR "${${_PYTHON_LIB}}" DIRECTORY)
- list (APPEND _PYTHON_DIRS "${_PYTHON_DIR}")
- endif()
- endforeach()
- list (REMOVE_DUPLICATES _PYTHON_DIRS)
- set (${_PYTHON_SLD_RESULT} ${_PYTHON_DIRS} PARENT_SCOPE)
-endfunction()
-
-
-function (_PYTHON_SET_DEVELOPMENT_MODULE_FOUND module)
- if ("Development.${module}" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS)
- string(TOUPPER "${module}" id)
- set (module_found TRUE)
-
- if ("LIBRARY" IN_LIST _${_PYTHON_PREFIX}_FIND_DEVELOPMENT_${id}_ARTIFACTS
- AND NOT _${_PYTHON_PREFIX}_LIBRARY_RELEASE)
- set (module_found FALSE)
- endif()
- if ("INCLUDE_DIR" IN_LIST _${_PYTHON_PREFIX}_FIND_DEVELOPMENT_${id}_ARTIFACTS
- AND NOT _${_PYTHON_PREFIX}_INCLUDE_DIR)
- set (module_found FALSE)
- endif()
-
- set (${_PYTHON_PREFIX}_Development.${module}_FOUND ${module_found} PARENT_SCOPE)
- endif()
-endfunction()
-
-
-# If major version is specified, it must be the same as internal major version
-if (DEFINED ${_PYTHON_PREFIX}_FIND_VERSION_MAJOR
- AND NOT ${_PYTHON_PREFIX}_FIND_VERSION_MAJOR VERSION_EQUAL _${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR)
- _python_display_failure ("Could NOT find ${_PYTHON_PREFIX}: Wrong major version specified is \"${${_PYTHON_PREFIX}_FIND_VERSION_MAJOR}\", but expected major version is \"${_${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR}\"")
-endif()
-
-
-# handle components
-if (NOT ${_PYTHON_PREFIX}_FIND_COMPONENTS)
- set (${_PYTHON_PREFIX}_FIND_COMPONENTS Interpreter)
- set (${_PYTHON_PREFIX}_FIND_REQUIRED_Interpreter TRUE)
-endif()
-if ("NumPy" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS)
- list (APPEND ${_PYTHON_PREFIX}_FIND_COMPONENTS "Interpreter" "Development.Module")
-endif()
-if ("Development" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS)
- list (APPEND ${_PYTHON_PREFIX}_FIND_COMPONENTS "Development.Module" "Development.Embed")
-endif()
-list (REMOVE_DUPLICATES ${_PYTHON_PREFIX}_FIND_COMPONENTS)
-foreach (_${_PYTHON_PREFIX}_COMPONENT IN ITEMS Interpreter Compiler Development Development.Module Development.Embed NumPy)
- set (${_PYTHON_PREFIX}_${_${_PYTHON_PREFIX}_COMPONENT}_FOUND FALSE)
-endforeach()
-if (${_PYTHON_PREFIX}_FIND_REQUIRED_Development)
- set (${_PYTHON_PREFIX}_FIND_REQUIRED_Development.Module TRUE)
- set (${_PYTHON_PREFIX}_FIND_REQUIRED_Development.Embed TRUE)
-endif()
-
-unset (_${_PYTHON_PREFIX}_FIND_DEVELOPMENT_ARTIFACTS)
-unset (_${_PYTHON_PREFIX}_FIND_DEVELOPMENT_MODULE_ARTIFACTS)
-unset (_${_PYTHON_PREFIX}_FIND_DEVELOPMENT_EMBED_ARTIFACTS)
-if ("Development.Module" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS)
- if (CMAKE_SYSTEM_NAME MATCHES "^(Windows.*|CYGWIN|MSYS)$")
- list (APPEND _${_PYTHON_PREFIX}_FIND_DEVELOPMENT_MODULE_ARTIFACTS "LIBRARY")
- endif()
- list (APPEND _${_PYTHON_PREFIX}_FIND_DEVELOPMENT_MODULE_ARTIFACTS "INCLUDE_DIR")
-endif()
-if ("Development.Embed" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS)
- list (APPEND _${_PYTHON_PREFIX}_FIND_DEVELOPMENT_EMBED_ARTIFACTS "LIBRARY" "INCLUDE_DIR")
-endif()
-set (_${_PYTHON_PREFIX}_FIND_DEVELOPMENT_ARTIFACTS ${_${_PYTHON_PREFIX}_FIND_DEVELOPMENT_MODULE_ARTIFACTS} ${_${_PYTHON_PREFIX}_FIND_DEVELOPMENT_EMBED_ARTIFACTS})
-list (REMOVE_DUPLICATES _${_PYTHON_PREFIX}_FIND_DEVELOPMENT_ARTIFACTS)
-
-unset (_${_PYTHON_PREFIX}_FIND_VERSIONS)
-
-# Set versions to search
-## default: search any version
-set (_${_PYTHON_PREFIX}_FIND_VERSIONS ${_${_PYTHON_PREFIX}_VERSIONS})
-
-if (${_PYTHON_PREFIX}_FIND_VERSION_COUNT GREATER "1")
- if (${_PYTHON_PREFIX}_FIND_VERSION_EXACT)
- set (_${_PYTHON_PREFIX}_FIND_VERSIONS ${${_PYTHON_PREFIX}_FIND_VERSION_MAJOR}.${${_PYTHON_PREFIX}_FIND_VERSION_MINOR})
- else()
- unset (_${_PYTHON_PREFIX}_FIND_VERSIONS)
- # add all compatible versions
- foreach (_${_PYTHON_PREFIX}_VERSION IN LISTS _${_PYTHON_PREFIX}_VERSIONS)
- if (_${_PYTHON_PREFIX}_VERSION VERSION_GREATER_EQUAL ${_PYTHON_PREFIX}_FIND_VERSION)
- list (APPEND _${_PYTHON_PREFIX}_FIND_VERSIONS ${_${_PYTHON_PREFIX}_VERSION})
- endif()
- endforeach()
- endif()
-endif()
-
-# Set ABIs to search
-## default: search any ABI
-if (_${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR VERSION_LESS "3")
- # ABI not supported
- unset (_${_PYTHON_PREFIX}_FIND_ABI)
- set (_${_PYTHON_PREFIX}_ABIFLAGS "")
-else()
- unset (_${_PYTHON_PREFIX}_FIND_ABI)
- unset (_${_PYTHON_PREFIX}_ABIFLAGS)
- if (DEFINED ${_PYTHON_PREFIX}_FIND_ABI)
- # normalization
- string (TOUPPER "${${_PYTHON_PREFIX}_FIND_ABI}" _${_PYTHON_PREFIX}_FIND_ABI)
- list (TRANSFORM _${_PYTHON_PREFIX}_FIND_ABI REPLACE "^(TRUE|Y(ES)?|1)$" "ON")
- list (TRANSFORM _${_PYTHON_PREFIX}_FIND_ABI REPLACE "^(FALSE|N(O)?|0)$" "OFF")
- if (NOT _${_PYTHON_PREFIX}_FIND_ABI MATCHES "^(ON|OFF|ANY);(ON|OFF|ANY);(ON|OFF|ANY)$")
- message (AUTHOR_WARNING "Find${_PYTHON_PREFIX}: ${${_PYTHON_PREFIX}_FIND_ABI}: invalid value for '${_PYTHON_PREFIX}_FIND_ABI'. Ignore it")
- unset (_${_PYTHON_PREFIX}_FIND_ABI)
- endif()
- _python_get_abiflags (_${_PYTHON_PREFIX}_ABIFLAGS)
- endif()
-endif()
-unset (${_PYTHON_PREFIX}_SOABI)
-
-# Define lookup strategy
-if (_${_PYTHON_PREFIX}_LOOKUP_POLICY STREQUAL "NEW")
- set (_${_PYTHON_PREFIX}_FIND_STRATEGY "LOCATION")
-else()
- set (_${_PYTHON_PREFIX}_FIND_STRATEGY "VERSION")
-endif()
-if (DEFINED ${_PYTHON_PREFIX}_FIND_STRATEGY)
- if (NOT ${_PYTHON_PREFIX}_FIND_STRATEGY MATCHES "^(VERSION|LOCATION)$")
- message (AUTHOR_WARNING "Find${_PYTHON_PREFIX}: ${${_PYTHON_PREFIX}_FIND_STRATEGY}: invalid value for '${_PYTHON_PREFIX}_FIND_STRATEGY'. 'VERSION' or 'LOCATION' expected.")
- set (_${_PYTHON_PREFIX}_FIND_STRATEGY "VERSION")
- else()
- set (_${_PYTHON_PREFIX}_FIND_STRATEGY "${${_PYTHON_PREFIX}_FIND_STRATEGY}")
- endif()
-endif()
-
-# Python and Anaconda distributions: define which architectures can be used
-if (CMAKE_SIZEOF_VOID_P)
- # In this case, search only for 64bit or 32bit
- math (EXPR _${_PYTHON_PREFIX}_ARCH "${CMAKE_SIZEOF_VOID_P} * 8")
- set (_${_PYTHON_PREFIX}_ARCH2 ${_${_PYTHON_PREFIX}_ARCH})
-else()
- # architecture unknown, search for both 64bit and 32bit
- set (_${_PYTHON_PREFIX}_ARCH 64)
- set (_${_PYTHON_PREFIX}_ARCH2 32)
-endif()
-
-# IronPython support
-if (CMAKE_SIZEOF_VOID_P)
- # In this case, search only for 64bit or 32bit
- math (EXPR _${_PYTHON_PREFIX}_ARCH "${CMAKE_SIZEOF_VOID_P} * 8")
- set (_${_PYTHON_PREFIX}_IRON_PYTHON_NAMES ipy${_${_PYTHON_PREFIX}_ARCH} ipy)
-else()
- # architecture unknown, search for natural interpreter
- set (_${_PYTHON_PREFIX}_IRON_PYTHON_NAMES ipy)
-endif()
-set (_${_PYTHON_PREFIX}_IRON_PYTHON_PATH_SUFFIXES net45 net40)
-
-# Apple frameworks handling
-_python_find_frameworks ()
-
-set (_${_PYTHON_PREFIX}_FIND_FRAMEWORK "FIRST")
-
-if (DEFINED ${_PYTHON_PREFIX}_FIND_FRAMEWORK)
- if (NOT ${_PYTHON_PREFIX}_FIND_FRAMEWORK MATCHES "^(FIRST|LAST|NEVER)$")
- message (AUTHOR_WARNING "Find${_PYTHON_PREFIX}: ${${_PYTHON_PREFIX}_FIND_FRAMEWORK}: invalid value for '${_PYTHON_PREFIX}_FIND_FRAMEWORK'. 'FIRST', 'LAST' or 'NEVER' expected. 'FIRST' will be used instead.")
- else()
- set (_${_PYTHON_PREFIX}_FIND_FRAMEWORK ${${_PYTHON_PREFIX}_FIND_FRAMEWORK})
- endif()
-elseif (DEFINED CMAKE_FIND_FRAMEWORK)
- if (CMAKE_FIND_FRAMEWORK STREQUAL "ONLY")
- message (AUTHOR_WARNING "Find${_PYTHON_PREFIX}: CMAKE_FIND_FRAMEWORK: 'ONLY' value is not supported. 'FIRST' will be used instead.")
- elseif (NOT CMAKE_FIND_FRAMEWORK MATCHES "^(FIRST|LAST|NEVER)$")
- message (AUTHOR_WARNING "Find${_PYTHON_PREFIX}: ${CMAKE_FIND_FRAMEWORK}: invalid value for 'CMAKE_FIND_FRAMEWORK'. 'FIRST', 'LAST' or 'NEVER' expected. 'FIRST' will be used instead.")
- else()
- set (_${_PYTHON_PREFIX}_FIND_FRAMEWORK ${CMAKE_FIND_FRAMEWORK})
- endif()
-endif()
-
-# Save CMAKE_FIND_APPBUNDLE
-if (DEFINED CMAKE_FIND_APPBUNDLE)
- set (_${_PYTHON_PREFIX}_CMAKE_FIND_APPBUNDLE ${CMAKE_FIND_APPBUNDLE})
-else()
- unset (_${_PYTHON_PREFIX}_CMAKE_FIND_APPBUNDLE)
-endif()
-# To avoid app bundle lookup
-set (CMAKE_FIND_APPBUNDLE "NEVER")
-
-# Save CMAKE_FIND_FRAMEWORK
-if (DEFINED CMAKE_FIND_FRAMEWORK)
- set (_${_PYTHON_PREFIX}_CMAKE_FIND_FRAMEWORK ${CMAKE_FIND_FRAMEWORK})
-else()
- unset (_${_PYTHON_PREFIX}_CMAKE_FIND_FRAMEWORK)
-endif()
-# To avoid framework lookup
-set (CMAKE_FIND_FRAMEWORK "NEVER")
-
-# Windows Registry handling
-if (DEFINED ${_PYTHON_PREFIX}_FIND_REGISTRY)
- if (NOT ${_PYTHON_PREFIX}_FIND_REGISTRY MATCHES "^(FIRST|LAST|NEVER)$")
- message (AUTHOR_WARNING "Find${_PYTHON_PREFIX}: ${${_PYTHON_PREFIX}_FIND_REGISTRY}: invalid value for '${_PYTHON_PREFIX}_FIND_REGISTRY'. 'FIRST', 'LAST' or 'NEVER' expected. 'FIRST' will be used instead.")
- set (_${_PYTHON_PREFIX}_FIND_REGISTRY "FIRST")
- else()
- set (_${_PYTHON_PREFIX}_FIND_REGISTRY ${${_PYTHON_PREFIX}_FIND_REGISTRY})
- endif()
-else()
- set (_${_PYTHON_PREFIX}_FIND_REGISTRY "FIRST")
-endif()
-
-# virtual environments recognition
-if (DEFINED ENV{VIRTUAL_ENV} OR DEFINED ENV{CONDA_PREFIX})
- if (DEFINED ${_PYTHON_PREFIX}_FIND_VIRTUALENV)
- if (NOT ${_PYTHON_PREFIX}_FIND_VIRTUALENV MATCHES "^(FIRST|ONLY|STANDARD)$")
- message (AUTHOR_WARNING "Find${_PYTHON_PREFIX}: ${${_PYTHON_PREFIX}_FIND_VIRTUALENV}: invalid value for '${_PYTHON_PREFIX}_FIND_VIRTUALENV'. 'FIRST', 'ONLY' or 'STANDARD' expected. 'FIRST' will be used instead.")
- set (_${_PYTHON_PREFIX}_FIND_VIRTUALENV "FIRST")
- else()
- set (_${_PYTHON_PREFIX}_FIND_VIRTUALENV ${${_PYTHON_PREFIX}_FIND_VIRTUALENV})
- endif()
- else()
- set (_${_PYTHON_PREFIX}_FIND_VIRTUALENV FIRST)
- endif()
-else()
- set (_${_PYTHON_PREFIX}_FIND_VIRTUALENV STANDARD)
-endif()
-
-
-# Compute search signature
-# This signature will be used to check validity of cached variables on new search
-set (_${_PYTHON_PREFIX}_SIGNATURE "${${_PYTHON_PREFIX}_ROOT_DIR}:${_${_PYTHON_PREFIX}_FIND_STRATEGY}:${${_PYTHON_PREFIX}_FIND_VIRTUALENV}")
-if (NOT WIN32)
- string (APPEND _${_PYTHON_PREFIX}_SIGNATURE ":${${_PYTHON_PREFIX}_USE_STATIC_LIBS}:")
-endif()
-if (CMAKE_HOST_APPLE)
- string (APPEND _${_PYTHON_PREFIX}_SIGNATURE ":${_${_PYTHON_PREFIX}_FIND_FRAMEWORK}")
-endif()
-if (CMAKE_HOST_WIN32)
- string (APPEND _${_PYTHON_PREFIX}_SIGNATURE ":${_${_PYTHON_PREFIX}_FIND_REGISTRY}")
-endif()
-
-function (_PYTHON_CHECK_DEVELOPMENT_SIGNATURE module)
- if ("Development.${module}" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS)
- string (TOUPPER "${module}" id)
- set (signature "${_${_PYTHON_PREFIX}_SIGNATURE}:")
- if ("LIBRARY" IN_LIST _${_PYTHON_PREFIX}_FIND_DEVELOPMENT_${id}_ARTIFACTS)
- list (APPEND signature "${_${_PYTHON_PREFIX}_LIBRARY_RELEASE}:")
- endif()
- if ("INCLUDE_DIR" IN_LIST _${_PYTHON_PREFIX}_FIND_DEVELOPMENT_${id}_ARTIFACTS)
- list (APPEND signature "${_${_PYTHON_PREFIX}_INCLUDE_DIR}:")
- endif()
- string (MD5 signature "${signature}")
- if (signature STREQUAL _${_PYTHON_PREFIX}_DEVELOPMENT_${id}_SIGNATURE)
- if (${_PYTHON_PREFIX}_FIND_VERSION_EXACT)
- set (exact EXACT)
- endif()
- if ("LIBRARY" IN_LIST _${_PYTHON_PREFIX}_FIND_DEVELOPMENT_${id}_ARTIFACTS)
- _python_validate_library (${${_PYTHON_PREFIX}_FIND_VERSION} ${exact} CHECK_EXISTS)
- endif()
- if ("INCLUDE_DIR" IN_LIST _${_PYTHON_PREFIX}_FIND_DEVELOPMENT_${id}_ARTIFACTS)
- _python_validate_include_dir (${${_PYTHON_PREFIX}_FIND_VERSION} ${exact} CHECK_EXISTS)
- endif()
- else()
- if ("LIBRARY" IN_LIST _${_PYTHON_PREFIX}_FIND_DEVELOPMENT_${id}_ARTIFACTS)
- unset (_${_PYTHON_PREFIX}_LIBRARY_RELEASE CACHE)
- unset (_${_PYTHON_PREFIX}_LIBRARY_DEBUG CACHE)
- endif()
- if ("INCLUDE_DIR" IN_LIST _${_PYTHON_PREFIX}_FIND_DEVELOPMENT_${id}_ARTIFACTS)
- unset (_${_PYTHON_PREFIX}_INCLUDE_DIR CACHE)
- endif()
- endif()
- if (("LIBRARY" IN_LIST _${_PYTHON_PREFIX}_FIND_DEVELOPMENT_${id}_ARTIFACTS
- AND NOT _${_PYTHON_PREFIX}_LIBRARY_RELEASE)
- OR ("INCLUDE_DIR" IN_LIST _${_PYTHON_PREFIX}_FIND_DEVELOPMENT_${id}_ARTIFACTS
- AND NOT _${_PYTHON_PREFIX}_INCLUDE_DIR))
- unset (_${_PYTHON_PREFIX}_CONFIG CACHE)
- unset (_${_PYTHON_PREFIX}_DEVELOPMENT_${id}_SIGNATURE CACHE)
- endif()
- endif()
-endfunction()
-
-function (_PYTHON_COMPUTE_DEVELOPMENT_SIGNATURE module)
- string (TOUPPER "${module}" id)
- if (${_PYTHON_PREFIX}_Development.${module}_FOUND)
- set (signature "${_${_PYTHON_PREFIX}_SIGNATURE}:")
- if ("LIBRARY" IN_LIST _${_PYTHON_PREFIX}_FIND_DEVELOPMENT_${id}_ARTIFACTS)
- list (APPEND signature "${_${_PYTHON_PREFIX}_LIBRARY_RELEASE}:")
- endif()
- if ("INCLUDE_DIR" IN_LIST _${_PYTHON_PREFIX}_FIND_DEVELOPMENT_${id}_ARTIFACTS)
- list (APPEND signature "${_${_PYTHON_PREFIX}_INCLUDE_DIR}:")
- endif()
- string (MD5 signature "${signature}")
- set (_${_PYTHON_PREFIX}_DEVELOPMENT_${id}_SIGNATURE "${signature}" CACHE INTERNAL "")
- else()
- unset (_${_PYTHON_PREFIX}_DEVELOPMENT_${id}_SIGNATURE CACHE)
- endif()
-endfunction()
-
-
-unset (_${_PYTHON_PREFIX}_REQUIRED_VARS)
-unset (_${_PYTHON_PREFIX}_CACHED_VARS)
-unset (_${_PYTHON_PREFIX}_Interpreter_REASON_FAILURE)
-unset (_${_PYTHON_PREFIX}_Compiler_REASON_FAILURE)
-unset (_${_PYTHON_PREFIX}_Development_REASON_FAILURE)
-unset (_${_PYTHON_PREFIX}_NumPy_REASON_FAILURE)
-
-
-# first step, search for the interpreter
-if ("Interpreter" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS)
- list (APPEND _${_PYTHON_PREFIX}_CACHED_VARS _${_PYTHON_PREFIX}_EXECUTABLE)
- if (${_PYTHON_PREFIX}_FIND_REQUIRED_Interpreter)
- list (APPEND _${_PYTHON_PREFIX}_REQUIRED_VARS ${_PYTHON_PREFIX}_EXECUTABLE)
- endif()
-
- if (DEFINED ${_PYTHON_PREFIX}_EXECUTABLE
- AND IS_ABSOLUTE "${${_PYTHON_PREFIX}_EXECUTABLE}")
- if (NOT ${_PYTHON_PREFIX}_EXECUTABLE STREQUAL _${_PYTHON_PREFIX}_EXECUTABLE)
- # invalidate cache properties
- unset (_${_PYTHON_PREFIX}_INTERPRETER_PROPERTIES CACHE)
- endif()
- set (_${_PYTHON_PREFIX}_EXECUTABLE "${${_PYTHON_PREFIX}_EXECUTABLE}" CACHE INTERNAL "")
- elseif (DEFINED _${_PYTHON_PREFIX}_EXECUTABLE)
- # compute interpreter signature and check validity of definition
- string (MD5 __${_PYTHON_PREFIX}_INTERPRETER_SIGNATURE "${_${_PYTHON_PREFIX}_SIGNATURE}:${_${_PYTHON_PREFIX}_EXECUTABLE}")
- if (__${_PYTHON_PREFIX}_INTERPRETER_SIGNATURE STREQUAL _${_PYTHON_PREFIX}_INTERPRETER_SIGNATURE)
- # check version validity
- if (${_PYTHON_PREFIX}_FIND_VERSION_EXACT)
- _python_validate_interpreter (${${_PYTHON_PREFIX}_FIND_VERSION} EXACT CHECK_EXISTS)
- else()
- _python_validate_interpreter (${${_PYTHON_PREFIX}_FIND_VERSION} CHECK_EXISTS)
- endif()
- else()
- unset (_${_PYTHON_PREFIX}_EXECUTABLE CACHE)
- endif()
- if (NOT _${_PYTHON_PREFIX}_EXECUTABLE)
- unset (_${_PYTHON_PREFIX}_INTERPRETER_SIGNATURE CACHE)
- unset (_${_PYTHON_PREFIX}_INTERPRETER_PROPERTIES CACHE)
- endif()
- endif()
-
- if (NOT _${_PYTHON_PREFIX}_EXECUTABLE)
- set (_${_PYTHON_PREFIX}_HINTS "${${_PYTHON_PREFIX}_ROOT_DIR}" ENV ${_PYTHON_PREFIX}_ROOT_DIR)
-
- if (_${_PYTHON_PREFIX}_FIND_STRATEGY STREQUAL "LOCATION")
- unset (_${_PYTHON_PREFIX}_NAMES)
- unset (_${_PYTHON_PREFIX}_FRAMEWORK_PATHS)
- unset (_${_PYTHON_PREFIX}_REGISTRY_PATHS)
-
- foreach (_${_PYTHON_PREFIX}_VERSION IN LISTS _${_PYTHON_PREFIX}_FIND_VERSIONS)
- # build all executable names
- _python_get_names (_${_PYTHON_PREFIX}_VERSION_NAMES VERSION ${_${_PYTHON_PREFIX}_VERSION} POSIX EXECUTABLE)
- list (APPEND _${_PYTHON_PREFIX}_NAMES ${_${_PYTHON_PREFIX}_VERSION_NAMES})
-
- # Framework Paths
- _python_get_frameworks (_${_PYTHON_PREFIX}_VERSION_PATHS ${_${_PYTHON_PREFIX}_VERSION})
- list (APPEND _${_PYTHON_PREFIX}_FRAMEWORK_PATHS ${_${_PYTHON_PREFIX}_VERSION_PATHS})
-
- # Registry Paths
- _python_get_registries (_${_PYTHON_PREFIX}_VERSION_PATHS ${_${_PYTHON_PREFIX}_VERSION})
- list (APPEND _${_PYTHON_PREFIX}_REGISTRY_PATHS ${_${_PYTHON_PREFIX}_VERSION_PATHS}
- [HKEY_LOCAL_MACHINE\\SOFTWARE\\IronPython\\${_${_PYTHON_PREFIX}_VERSION}\\InstallPath])
- endforeach()
- list (APPEND _${_PYTHON_PREFIX}_NAMES python${_${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR} python)
-
- while (TRUE)
- # Virtual environments handling
- if (_${_PYTHON_PREFIX}_FIND_VIRTUALENV MATCHES "^(FIRST|ONLY)$")
- find_program (_${_PYTHON_PREFIX}_EXECUTABLE
- NAMES ${_${_PYTHON_PREFIX}_NAMES}
- NAMES_PER_DIR
- HINTS ${_${_PYTHON_PREFIX}_HINTS}
- PATHS ENV VIRTUAL_ENV ENV CONDA_PREFIX
- PATH_SUFFIXES bin Scripts
- NO_CMAKE_PATH
- NO_CMAKE_ENVIRONMENT_PATH
- NO_SYSTEM_ENVIRONMENT_PATH
- NO_CMAKE_SYSTEM_PATH)
-
- _python_validate_interpreter (${${_PYTHON_PREFIX}_FIND_VERSION})
- if (_${_PYTHON_PREFIX}_EXECUTABLE)
- break()
- endif()
- if (_${_PYTHON_PREFIX}_FIND_VIRTUALENV STREQUAL "ONLY")
- break()
- endif()
- endif()
-
- # Apple frameworks handling
- if (CMAKE_HOST_APPLE AND _${_PYTHON_PREFIX}_FIND_FRAMEWORK STREQUAL "FIRST")
- find_program (_${_PYTHON_PREFIX}_EXECUTABLE
- NAMES ${_${_PYTHON_PREFIX}_NAMES}
- NAMES_PER_DIR
- HINTS ${_${_PYTHON_PREFIX}_HINTS}
- PATHS ${_${_PYTHON_PREFIX}_FRAMEWORK_PATHS}
- PATH_SUFFIXES bin
- NO_CMAKE_PATH
- NO_CMAKE_ENVIRONMENT_PATH
- NO_SYSTEM_ENVIRONMENT_PATH
- NO_CMAKE_SYSTEM_PATH)
- _python_validate_interpreter (${${_PYTHON_PREFIX}_FIND_VERSION})
- if (_${_PYTHON_PREFIX}_EXECUTABLE)
- break()
- endif()
- endif()
- # Windows registry
- if (CMAKE_HOST_WIN32 AND _${_PYTHON_PREFIX}_FIND_REGISTRY STREQUAL "FIRST")
- find_program (_${_PYTHON_PREFIX}_EXECUTABLE
- NAMES ${_${_PYTHON_PREFIX}_NAMES}
- ${_${_PYTHON_PREFIX}_IRON_PYTHON_NAMES}
- NAMES_PER_DIR
- HINTS ${_${_PYTHON_PREFIX}_HINTS}
- PATHS ${_${_PYTHON_PREFIX}_REGISTRY_PATHS}
- PATH_SUFFIXES bin ${_${_PYTHON_PREFIX}_IRON_PYTHON_PATH_SUFFIXES}
- NO_SYSTEM_ENVIRONMENT_PATH
- NO_CMAKE_SYSTEM_PATH)
- _python_validate_interpreter (${${_PYTHON_PREFIX}_FIND_VERSION})
- if (_${_PYTHON_PREFIX}_EXECUTABLE)
- break()
- endif()
- endif()
-
- # try using HINTS
- find_program (_${_PYTHON_PREFIX}_EXECUTABLE
- NAMES ${_${_PYTHON_PREFIX}_NAMES}
- ${_${_PYTHON_PREFIX}_IRON_PYTHON_NAMES}
- NAMES_PER_DIR
- HINTS ${_${_PYTHON_PREFIX}_HINTS}
- PATH_SUFFIXES bin ${_${_PYTHON_PREFIX}_IRON_PYTHON_PATH_SUFFIXES}
- NO_SYSTEM_ENVIRONMENT_PATH
- NO_CMAKE_SYSTEM_PATH)
- _python_validate_interpreter (${${_PYTHON_PREFIX}_FIND_VERSION})
- if (_${_PYTHON_PREFIX}_EXECUTABLE)
- break()
- endif()
- # try using standard paths
- find_program (_${_PYTHON_PREFIX}_EXECUTABLE
- NAMES ${_${_PYTHON_PREFIX}_NAMES}
- ${_${_PYTHON_PREFIX}_IRON_PYTHON_NAMES}
- NAMES_PER_DIR
- PATH_SUFFIXES bin ${_${_PYTHON_PREFIX}_IRON_PYTHON_PATH_SUFFIXES})
- _python_validate_interpreter (${${_PYTHON_PREFIX}_FIND_VERSION})
- if (_${_PYTHON_PREFIX}_EXECUTABLE)
- break()
- endif()
-
- # Apple frameworks handling
- if (CMAKE_HOST_APPLE AND _${_PYTHON_PREFIX}_FIND_FRAMEWORK STREQUAL "LAST")
- find_program (_${_PYTHON_PREFIX}_EXECUTABLE
- NAMES ${_${_PYTHON_PREFIX}_NAMES}
- NAMES_PER_DIR
- PATHS ${_${_PYTHON_PREFIX}_FRAMEWORK_PATHS}
- PATH_SUFFIXES bin
- NO_DEFAULT_PATH)
- _python_validate_interpreter (${${_PYTHON_PREFIX}_FIND_VERSION})
- if (_${_PYTHON_PREFIX}_EXECUTABLE)
- break()
- endif()
- endif()
- # Windows registry
- if (CMAKE_HOST_WIN32 AND _${_PYTHON_PREFIX}_FIND_REGISTRY STREQUAL "LAST")
- find_program (_${_PYTHON_PREFIX}_EXECUTABLE
- NAMES ${_${_PYTHON_PREFIX}_NAMES}
- ${_${_PYTHON_PREFIX}_IRON_PYTHON_NAMES}
- NAMES_PER_DIR
- PATHS ${_${_PYTHON_PREFIX}_REGISTRY_PATHS}
- PATH_SUFFIXES bin ${_${_PYTHON_PREFIX}_IRON_PYTHON_PATH_SUFFIXES}
- NO_DEFAULT_PATH)
- _python_validate_interpreter (${${_PYTHON_PREFIX}_FIND_VERSION})
- if (_${_PYTHON_PREFIX}_EXECUTABLE)
- break()
- endif()
- endif()
-
- break()
- endwhile()
- else()
- # look-up for various versions and locations
- foreach (_${_PYTHON_PREFIX}_VERSION IN LISTS _${_PYTHON_PREFIX}_FIND_VERSIONS)
- _python_get_names (_${_PYTHON_PREFIX}_NAMES VERSION ${_${_PYTHON_PREFIX}_VERSION} POSIX EXECUTABLE)
- list (APPEND _${_PYTHON_PREFIX}_NAMES python${_${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR}
- python)
-
- _python_get_frameworks (_${_PYTHON_PREFIX}_FRAMEWORK_PATHS ${_${_PYTHON_PREFIX}_VERSION})
- _python_get_registries (_${_PYTHON_PREFIX}_REGISTRY_PATHS ${_${_PYTHON_PREFIX}_VERSION})
-
- # Virtual environments handling
- if (_${_PYTHON_PREFIX}_FIND_VIRTUALENV MATCHES "^(FIRST|ONLY)$")
- find_program (_${_PYTHON_PREFIX}_EXECUTABLE
- NAMES ${_${_PYTHON_PREFIX}_NAMES}
- NAMES_PER_DIR
- HINTS ${_${_PYTHON_PREFIX}_HINTS}
- PATHS ENV VIRTUAL_ENV ENV CONDA_PREFIX
- PATH_SUFFIXES bin Scripts
- NO_CMAKE_PATH
- NO_CMAKE_ENVIRONMENT_PATH
- NO_SYSTEM_ENVIRONMENT_PATH
- NO_CMAKE_SYSTEM_PATH)
- _python_validate_interpreter (${_${_PYTHON_PREFIX}_VERSION} EXACT)
- if (_${_PYTHON_PREFIX}_EXECUTABLE)
- break()
- endif()
- if (_${_PYTHON_PREFIX}_FIND_VIRTUALENV STREQUAL "ONLY")
- continue()
- endif()
- endif()
-
- # Apple frameworks handling
- if (CMAKE_HOST_APPLE AND _${_PYTHON_PREFIX}_FIND_FRAMEWORK STREQUAL "FIRST")
- find_program (_${_PYTHON_PREFIX}_EXECUTABLE
- NAMES ${_${_PYTHON_PREFIX}_NAMES}
- NAMES_PER_DIR
- HINTS ${_${_PYTHON_PREFIX}_HINTS}
- PATHS ${_${_PYTHON_PREFIX}_FRAMEWORK_PATHS}
- PATH_SUFFIXES bin
- NO_CMAKE_PATH
- NO_CMAKE_ENVIRONMENT_PATH
- NO_SYSTEM_ENVIRONMENT_PATH
- NO_CMAKE_SYSTEM_PATH)
- endif()
-
- # Windows registry
- if (CMAKE_HOST_WIN32 AND _${_PYTHON_PREFIX}_FIND_REGISTRY STREQUAL "FIRST")
- find_program (_${_PYTHON_PREFIX}_EXECUTABLE
- NAMES ${_${_PYTHON_PREFIX}_NAMES}
- ${_${_PYTHON_PREFIX}_IRON_PYTHON_NAMES}
- NAMES_PER_DIR
- HINTS ${_${_PYTHON_PREFIX}_HINTS}
- PATHS ${_${_PYTHON_PREFIX}_REGISTRY_PATHS}
- [HKEY_LOCAL_MACHINE\\SOFTWARE\\IronPython\\${_${_PYTHON_PREFIX}_VERSION}\\InstallPath]
- PATH_SUFFIXES bin ${_${_PYTHON_PREFIX}_IRON_PYTHON_PATH_SUFFIXES}
- NO_SYSTEM_ENVIRONMENT_PATH
- NO_CMAKE_SYSTEM_PATH)
- endif()
-
- _python_validate_interpreter (${_${_PYTHON_PREFIX}_VERSION} EXACT)
- if (_${_PYTHON_PREFIX}_EXECUTABLE)
- break()
- endif()
-
- # try using HINTS
- find_program (_${_PYTHON_PREFIX}_EXECUTABLE
- NAMES ${_${_PYTHON_PREFIX}_NAMES}
- ${_${_PYTHON_PREFIX}_IRON_PYTHON_NAMES}
- NAMES_PER_DIR
- HINTS ${_${_PYTHON_PREFIX}_HINTS}
- PATH_SUFFIXES bin ${_${_PYTHON_PREFIX}_IRON_PYTHON_PATH_SUFFIXES}
- NO_SYSTEM_ENVIRONMENT_PATH
- NO_CMAKE_SYSTEM_PATH)
- _python_validate_interpreter (${_${_PYTHON_PREFIX}_VERSION} EXACT)
- if (_${_PYTHON_PREFIX}_EXECUTABLE)
- break()
- endif()
- # try using standard paths.
- # NAMES_PER_DIR is not defined on purpose to have a chance to find
- # expected version.
- # For example, typical systems have 'python' for version 2.* and 'python3'
- # for version 3.*. So looking for names per dir will find, potentially,
- # systematically 'python' (i.e. version 2) even if version 3 is searched.
- if (CMAKE_HOST_WIN32)
- find_program (_${_PYTHON_PREFIX}_EXECUTABLE
- NAMES ${_${_PYTHON_PREFIX}_NAMES}
- python
- ${_${_PYTHON_PREFIX}_IRON_PYTHON_NAMES})
- else()
- find_program (_${_PYTHON_PREFIX}_EXECUTABLE
- NAMES ${_${_PYTHON_PREFIX}_NAMES})
- endif()
- _python_validate_interpreter (${_${_PYTHON_PREFIX}_VERSION} EXACT)
- if (_${_PYTHON_PREFIX}_EXECUTABLE)
- break()
- endif()
-
- # Apple frameworks handling
- if (CMAKE_HOST_APPLE AND _${_PYTHON_PREFIX}_FIND_FRAMEWORK STREQUAL "LAST")
- find_program (_${_PYTHON_PREFIX}_EXECUTABLE
- NAMES ${_${_PYTHON_PREFIX}_NAMES}
- NAMES_PER_DIR
- PATHS ${_${_PYTHON_PREFIX}_FRAMEWORK_PATHS}
- PATH_SUFFIXES bin
- NO_DEFAULT_PATH)
- endif()
-
- # Windows registry
- if (CMAKE_HOST_WIN32 AND _${_PYTHON_PREFIX}_FIND_REGISTRY STREQUAL "LAST")
- find_program (_${_PYTHON_PREFIX}_EXECUTABLE
- NAMES ${_${_PYTHON_PREFIX}_NAMES}
- ${_${_PYTHON_PREFIX}_IRON_PYTHON_NAMES}
- NAMES_PER_DIR
- PATHS ${_${_PYTHON_PREFIX}_REGISTRY_PATHS}
- [HKEY_LOCAL_MACHINE\\SOFTWARE\\IronPython\\${_${_PYTHON_PREFIX}_VERSION}\\InstallPath]
- PATH_SUFFIXES bin ${_${_PYTHON_PREFIX}_IRON_PYTHON_PATH_SUFFIXES}
- NO_DEFAULT_PATH)
- endif()
-
- _python_validate_interpreter (${_${_PYTHON_PREFIX}_VERSION} EXACT)
- if (_${_PYTHON_PREFIX}_EXECUTABLE)
- break()
- endif()
- endforeach()
-
- if (NOT _${_PYTHON_PREFIX}_EXECUTABLE AND
- NOT _${_PYTHON_PREFIX}_FIND_VIRTUALENV STREQUAL "ONLY")
- # No specific version found. Retry with generic names and standard paths.
- # NAMES_PER_DIR is not defined on purpose to have a chance to find
- # expected version.
- # For example, typical systems have 'python' for version 2.* and 'python3'
- # for version 3.*. So looking for names per dir will find, potentially,
- # systematically 'python' (i.e. version 2) even if version 3 is searched.
- find_program (_${_PYTHON_PREFIX}_EXECUTABLE
- NAMES python${_${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR}
- python
- ${_${_PYTHON_PREFIX}_IRON_PYTHON_NAMES})
- _python_validate_interpreter ()
- endif()
- endif()
- endif()
-
- set (${_PYTHON_PREFIX}_EXECUTABLE "${_${_PYTHON_PREFIX}_EXECUTABLE}")
-
- # retrieve exact version of executable found
- if (_${_PYTHON_PREFIX}_EXECUTABLE)
- execute_process (COMMAND "${_${_PYTHON_PREFIX}_EXECUTABLE}" -c
- "import sys; sys.stdout.write('.'.join([str(x) for x in sys.version_info[:3]]))"
- RESULT_VARIABLE _${_PYTHON_PREFIX}_RESULT
- OUTPUT_VARIABLE ${_PYTHON_PREFIX}_VERSION
- ERROR_QUIET
- OUTPUT_STRIP_TRAILING_WHITESPACE)
- if (NOT _${_PYTHON_PREFIX}_RESULT)
- set (_${_PYTHON_PREFIX}_EXECUTABLE_USABLE TRUE)
- else()
- # Interpreter is not usable
- set (_${_PYTHON_PREFIX}_EXECUTABLE_USABLE FALSE)
- unset (${_PYTHON_PREFIX}_VERSION)
- set (_${_PYTHON_PREFIX}_Interpreter_REASON_FAILURE "Cannot run the interpreter \"${_${_PYTHON_PREFIX}_EXECUTABLE}\"")
- endif()
- endif()
-
- if (_${_PYTHON_PREFIX}_EXECUTABLE AND _${_PYTHON_PREFIX}_EXECUTABLE_USABLE)
- if (_${_PYTHON_PREFIX}_INTERPRETER_PROPERTIES)
- set (${_PYTHON_PREFIX}_Interpreter_FOUND TRUE)
-
- list (GET _${_PYTHON_PREFIX}_INTERPRETER_PROPERTIES 0 ${_PYTHON_PREFIX}_INTERPRETER_ID)
-
- list (GET _${_PYTHON_PREFIX}_INTERPRETER_PROPERTIES 1 ${_PYTHON_PREFIX}_VERSION_MAJOR)
- list (GET _${_PYTHON_PREFIX}_INTERPRETER_PROPERTIES 2 ${_PYTHON_PREFIX}_VERSION_MINOR)
- list (GET _${_PYTHON_PREFIX}_INTERPRETER_PROPERTIES 3 ${_PYTHON_PREFIX}_VERSION_PATCH)
-
- list (GET _${_PYTHON_PREFIX}_INTERPRETER_PROPERTIES 4 _${_PYTHON_PREFIX}_ARCH)
- set (_${_PYTHON_PREFIX}_ARCH2 ${_${_PYTHON_PREFIX}_ARCH})
-
- list (GET _${_PYTHON_PREFIX}_INTERPRETER_PROPERTIES 5 _${_PYTHON_PREFIX}_ABIFLAGS)
- list (GET _${_PYTHON_PREFIX}_INTERPRETER_PROPERTIES 6 ${_PYTHON_PREFIX}_SOABI)
-
- list (GET _${_PYTHON_PREFIX}_INTERPRETER_PROPERTIES 7 ${_PYTHON_PREFIX}_STDLIB)
- list (GET _${_PYTHON_PREFIX}_INTERPRETER_PROPERTIES 8 ${_PYTHON_PREFIX}_STDARCH)
- list (GET _${_PYTHON_PREFIX}_INTERPRETER_PROPERTIES 9 ${_PYTHON_PREFIX}_SITELIB)
- list (GET _${_PYTHON_PREFIX}_INTERPRETER_PROPERTIES 10 ${_PYTHON_PREFIX}_SITEARCH)
- else()
- string (REGEX MATCHALL "[0-9]+" _${_PYTHON_PREFIX}_VERSIONS "${${_PYTHON_PREFIX}_VERSION}")
- list (GET _${_PYTHON_PREFIX}_VERSIONS 0 ${_PYTHON_PREFIX}_VERSION_MAJOR)
- list (GET _${_PYTHON_PREFIX}_VERSIONS 1 ${_PYTHON_PREFIX}_VERSION_MINOR)
- list (GET _${_PYTHON_PREFIX}_VERSIONS 2 ${_PYTHON_PREFIX}_VERSION_PATCH)
-
- if (${_PYTHON_PREFIX}_VERSION_MAJOR VERSION_EQUAL _${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR)
- set (${_PYTHON_PREFIX}_Interpreter_FOUND TRUE)
-
- # Use interpreter version and ABI for future searches to ensure consistency
- set (_${_PYTHON_PREFIX}_FIND_VERSIONS ${${_PYTHON_PREFIX}_VERSION_MAJOR}.${${_PYTHON_PREFIX}_VERSION_MINOR})
- execute_process (COMMAND "${_${_PYTHON_PREFIX}_EXECUTABLE}" -c "import sys; sys.stdout.write(sys.abiflags)"
- RESULT_VARIABLE _${_PYTHON_PREFIX}_RESULT
- OUTPUT_VARIABLE _${_PYTHON_PREFIX}_ABIFLAGS
- ERROR_QUIET
- OUTPUT_STRIP_TRAILING_WHITESPACE)
- if (_${_PYTHON_PREFIX}_RESULT)
- # assunme ABI is not supported
- set (_${_PYTHON_PREFIX}_ABIFLAGS "")
- endif()
- endif()
-
- if (${_PYTHON_PREFIX}_Interpreter_FOUND)
- # compute and save interpreter signature
- string (MD5 __${_PYTHON_PREFIX}_INTERPRETER_SIGNATURE "${_${_PYTHON_PREFIX}_SIGNATURE}:${_${_PYTHON_PREFIX}_EXECUTABLE}")
- set (_${_PYTHON_PREFIX}_INTERPRETER_SIGNATURE "${__${_PYTHON_PREFIX}_INTERPRETER_SIGNATURE}" CACHE INTERNAL "")
-
- if (NOT CMAKE_SIZEOF_VOID_P)
- # determine interpreter architecture
- execute_process (COMMAND "${_${_PYTHON_PREFIX}_EXECUTABLE}" -c "import sys; print(sys.maxsize > 2**32)"
- RESULT_VARIABLE _${_PYTHON_PREFIX}_RESULT
- OUTPUT_VARIABLE ${_PYTHON_PREFIX}_IS64BIT
- ERROR_VARIABLE ${_PYTHON_PREFIX}_IS64BIT)
- if (NOT _${_PYTHON_PREFIX}_RESULT)
- if (${_PYTHON_PREFIX}_IS64BIT)
- set (_${_PYTHON_PREFIX}_ARCH 64)
- set (_${_PYTHON_PREFIX}_ARCH2 64)
- else()
- set (_${_PYTHON_PREFIX}_ARCH 32)
- set (_${_PYTHON_PREFIX}_ARCH2 32)
- endif()
- endif()
- endif()
-
- # retrieve interpreter identity
- execute_process (COMMAND "${_${_PYTHON_PREFIX}_EXECUTABLE}" -V
- RESULT_VARIABLE _${_PYTHON_PREFIX}_RESULT
- OUTPUT_VARIABLE ${_PYTHON_PREFIX}_INTERPRETER_ID
- ERROR_VARIABLE ${_PYTHON_PREFIX}_INTERPRETER_ID)
- if (NOT _${_PYTHON_PREFIX}_RESULT)
- if (${_PYTHON_PREFIX}_INTERPRETER_ID MATCHES "Anaconda")
- set (${_PYTHON_PREFIX}_INTERPRETER_ID "Anaconda")
- elseif (${_PYTHON_PREFIX}_INTERPRETER_ID MATCHES "Enthought")
- set (${_PYTHON_PREFIX}_INTERPRETER_ID "Canopy")
- else()
- string (REGEX REPLACE "^([^ ]+).*" "\\1" ${_PYTHON_PREFIX}_INTERPRETER_ID "${${_PYTHON_PREFIX}_INTERPRETER_ID}")
- if (${_PYTHON_PREFIX}_INTERPRETER_ID STREQUAL "Python")
- # try to get a more precise ID
- execute_process (COMMAND "${_${_PYTHON_PREFIX}_EXECUTABLE}" -c "import sys; print(sys.copyright)"
- RESULT_VARIABLE _${_PYTHON_PREFIX}_RESULT
- OUTPUT_VARIABLE ${_PYTHON_PREFIX}_COPYRIGHT
- ERROR_QUIET)
- if (${_PYTHON_PREFIX}_COPYRIGHT MATCHES "ActiveState")
- set (${_PYTHON_PREFIX}_INTERPRETER_ID "ActivePython")
- endif()
- endif()
- endif()
- else()
- set (${_PYTHON_PREFIX}_INTERPRETER_ID Python)
- endif()
-
- # retrieve various package installation directories
- execute_process (COMMAND "${_${_PYTHON_PREFIX}_EXECUTABLE}" -c "import sys\ntry:\n from distutils import sysconfig\n sys.stdout.write(';'.join([sysconfig.get_python_lib(plat_specific=False,standard_lib=True),sysconfig.get_python_lib(plat_specific=True,standard_lib=True),sysconfig.get_python_lib(plat_specific=False,standard_lib=False),sysconfig.get_python_lib(plat_specific=True,standard_lib=False)]))\nexcept Exception:\n import sysconfig\n sys.stdout.write(';'.join([sysconfig.get_path('stdlib'),sysconfig.get_path('platstdlib'),sysconfig.get_path('purelib'),sysconfig.get_path('platlib')]))"
- RESULT_VARIABLE _${_PYTHON_PREFIX}_RESULT
- OUTPUT_VARIABLE _${_PYTHON_PREFIX}_LIBPATHS
- ERROR_QUIET)
- if (NOT _${_PYTHON_PREFIX}_RESULT)
- list (GET _${_PYTHON_PREFIX}_LIBPATHS 0 ${_PYTHON_PREFIX}_STDLIB)
- list (GET _${_PYTHON_PREFIX}_LIBPATHS 1 ${_PYTHON_PREFIX}_STDARCH)
- list (GET _${_PYTHON_PREFIX}_LIBPATHS 2 ${_PYTHON_PREFIX}_SITELIB)
- list (GET _${_PYTHON_PREFIX}_LIBPATHS 3 ${_PYTHON_PREFIX}_SITEARCH)
- else()
- unset (${_PYTHON_PREFIX}_STDLIB)
- unset (${_PYTHON_PREFIX}_STDARCH)
- unset (${_PYTHON_PREFIX}_SITELIB)
- unset (${_PYTHON_PREFIX}_SITEARCH)
- endif()
-
- if (_${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR VERSION_GREATER_EQUAL "3")
- _python_get_config_var (${_PYTHON_PREFIX}_SOABI SOABI)
- endif()
-
- # store properties in the cache to speed-up future searches
- set (_${_PYTHON_PREFIX}_INTERPRETER_PROPERTIES
- "${${_PYTHON_PREFIX}_INTERPRETER_ID};${${_PYTHON_PREFIX}_VERSION_MAJOR};${${_PYTHON_PREFIX}_VERSION_MINOR};${${_PYTHON_PREFIX}_VERSION_PATCH};${_${_PYTHON_PREFIX}_ARCH};${_${_PYTHON_PREFIX}_ABIFLAGS};${${_PYTHON_PREFIX}_SOABI};${${_PYTHON_PREFIX}_STDLIB};${${_PYTHON_PREFIX}_STDARCH};${${_PYTHON_PREFIX}_SITELIB};${${_PYTHON_PREFIX}_SITEARCH}" CACHE INTERNAL "${_PYTHON_PREFIX} Properties")
- else()
- unset (_${_PYTHON_PREFIX}_INTERPRETER_SIGNATURE CACHE)
- unset (${_PYTHON_PREFIX}_INTERPRETER_ID)
- endif()
- endif()
- endif()
-
- if (${_PYTHON_PREFIX}_ARTIFACTS_INTERACTIVE)
- set (${_PYTHON_PREFIX}_EXECUTABLE "${_${_PYTHON_PREFIX}_EXECUTABLE}" CACHE FILEPATH "${_PYTHON_PREFIX} Interpreter")
- endif()
-
- _python_mark_as_internal (_${_PYTHON_PREFIX}_EXECUTABLE
- _${_PYTHON_PREFIX}_INTERPRETER_PROPERTIES
- _${_PYTHON_PREFIX}_INTERPRETER_SIGNATURE)
-endif()
-
-
-# second step, search for compiler (IronPython)
-if ("Compiler" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS)
- list (APPEND _${_PYTHON_PREFIX}_CACHED_VARS _${_PYTHON_PREFIX}_COMPILER)
- if (${_PYTHON_PREFIX}_FIND_REQUIRED_Compiler)
- list (APPEND _${_PYTHON_PREFIX}_REQUIRED_VARS ${_PYTHON_PREFIX}_COMPILER)
- endif()
-
- if (DEFINED ${_PYTHON_PREFIX}_COMPILER
- AND IS_ABSOLUTE "${${_PYTHON_PREFIX}_COMPILER}")
- set (_${_PYTHON_PREFIX}_COMPILER "${${_PYTHON_PREFIX}_COMPILER}" CACHE INTERNAL "")
- elseif (DEFINED _${_PYTHON_PREFIX}_COMPILER)
- # compute compiler signature and check validity of definition
- string (MD5 __${_PYTHON_PREFIX}_COMPILER_SIGNATURE "${_${_PYTHON_PREFIX}_SIGNATURE}:${_${_PYTHON_PREFIX}_COMPILER}")
- if (__${_PYTHON_PREFIX}_COMPILER_SIGNATURE STREQUAL _${_PYTHON_PREFIX}_COMPILER_SIGNATURE)
- # check version validity
- if (${_PYTHON_PREFIX}_FIND_VERSION_EXACT)
- _python_validate_compiler (${${_PYTHON_PREFIX}_FIND_VERSION} EXACT CHECK_EXISTS)
- else()
- _python_validate_compiler (${${_PYTHON_PREFIX}_FIND_VERSION} CHECK_EXISTS)
- endif()
- else()
- unset (_${_PYTHON_PREFIX}_COMPILER CACHE)
- unset (_${_PYTHON_PREFIX}_COMPILER_SIGNATURE CACHE)
- endif()
- endif()
-
- if (NOT _${_PYTHON_PREFIX}_COMPILER)
- # IronPython specific artifacts
- # If IronPython interpreter is found, use its path
- unset (_${_PYTHON_PREFIX}_IRON_ROOT)
- if (${_PYTHON_PREFIX}_Interpreter_FOUND AND ${_PYTHON_PREFIX}_INTERPRETER_ID STREQUAL "IronPython")
- get_filename_component (_${_PYTHON_PREFIX}_IRON_ROOT "${${_PYTHON_PREFIX}_EXECUTABLE}" DIRECTORY)
- endif()
-
- if (_${_PYTHON_PREFIX}_FIND_STRATEGY STREQUAL "LOCATION")
- set (_${_PYTHON_PREFIX}_REGISTRY_PATHS)
-
- foreach (_${_PYTHON_PREFIX}_VERSION IN LISTS _${_PYTHON_PREFIX}_FIND_VERSIONS)
- # Registry Paths
- list (APPEND _${_PYTHON_PREFIX}_REGISTRY_PATHS
- [HKEY_LOCAL_MACHINE\\SOFTWARE\\IronPython\\${_${_PYTHON_PREFIX}_VERSION}\\InstallPath])
- endforeach()
-
- while (TRUE)
- if (_${_PYTHON_PREFIX}_FIND_REGISTRY STREQUAL "FIRST")
- find_program (_${_PYTHON_PREFIX}_COMPILER
- NAMES ipyc
- HINTS ${_${_PYTHON_PREFIX}_IRON_ROOT} ${_${_PYTHON_PREFIX}_HINTS}
- PATHS ${_${_PYTHON_PREFIX}_REGISTRY_PATHS}
- PATH_SUFFIXES ${_${_PYTHON_PREFIX}_IRON_PYTHON_PATH_SUFFIXES}
- NO_SYSTEM_ENVIRONMENT_PATH
- NO_CMAKE_SYSTEM_PATH)
- _python_validate_compiler (${${_PYTHON_PREFIX}_FIND_VERSION})
- if (_${_PYTHON_PREFIX}_COMPILER)
- break()
- endif()
- endif()
-
- find_program (_${_PYTHON_PREFIX}_COMPILER
- NAMES ipyc
- HINTS ${_${_PYTHON_PREFIX}_IRON_ROOT} ${_${_PYTHON_PREFIX}_HINTS}
- PATH_SUFFIXES ${_${_PYTHON_PREFIX}_IRON_PYTHON_PATH_SUFFIXES}
- NO_SYSTEM_ENVIRONMENT_PATH
- NO_CMAKE_SYSTEM_PATH)
- _python_validate_compiler (${${_PYTHON_PREFIX}_FIND_VERSION})
- if (_${_PYTHON_PREFIX}_COMPILER)
- break()
- endif()
-
- if (_${_PYTHON_PREFIX}_FIND_REGISTRY STREQUAL "LAST")
- find_program (_${_PYTHON_PREFIX}_COMPILER
- NAMES ipyc
- PATHS ${_${_PYTHON_PREFIX}_REGISTRY_PATHS}
- PATH_SUFFIXES ${_${_PYTHON_PREFIX}_IRON_PYTHON_PATH_SUFFIXES}
- NO_DEFAULT_PATH)
- endif()
-
- break()
- endwhile()
- else()
- # try using root dir and registry
- foreach (_${_PYTHON_PREFIX}_VERSION IN LISTS _${_PYTHON_PREFIX}_FIND_VERSIONS)
- if (_${_PYTHON_PREFIX}_FIND_REGISTRY STREQUAL "FIRST")
- find_program (_${_PYTHON_PREFIX}_COMPILER
- NAMES ipyc
- HINTS ${_${_PYTHON_PREFIX}_IRON_ROOT} ${_${_PYTHON_PREFIX}_HINTS}
- PATHS [HKEY_LOCAL_MACHINE\\SOFTWARE\\IronPython\\${_${_PYTHON_PREFIX}_VERSION}\\InstallPath]
- PATH_SUFFIXES ${_${_PYTHON_PREFIX}_IRON_PYTHON_PATH_SUFFIXES}
- NO_SYSTEM_ENVIRONMENT_PATH
- NO_CMAKE_SYSTEM_PATH)
- _python_validate_compiler (${_${_PYTHON_PREFIX}_VERSION} EXACT)
- if (_${_PYTHON_PREFIX}_COMPILER)
- break()
- endif()
- endif()
-
- find_program (_${_PYTHON_PREFIX}_COMPILER
- NAMES ipyc
- HINTS ${_${_PYTHON_PREFIX}_IRON_ROOT} ${_${_PYTHON_PREFIX}_HINTS}
- PATH_SUFFIXES ${_${_PYTHON_PREFIX}_IRON_PYTHON_PATH_SUFFIXES}
- NO_SYSTEM_ENVIRONMENT_PATH
- NO_CMAKE_SYSTEM_PATH)
- _python_validate_compiler (${_${_PYTHON_PREFIX}_VERSION} EXACT)
- if (_${_PYTHON_PREFIX}_COMPILER)
- break()
- endif()
-
- if (_${_PYTHON_PREFIX}_FIND_REGISTRY STREQUAL "LAST")
- find_program (_${_PYTHON_PREFIX}_COMPILER
- NAMES ipyc
- PATHS [HKEY_LOCAL_MACHINE\\SOFTWARE\\IronPython\\${_${_PYTHON_PREFIX}_VERSION}\\InstallPath]
- PATH_SUFFIXES ${_${_PYTHON_PREFIX}_IRON_PYTHON_PATH_SUFFIXES}
- NO_DEFAULT_PATH)
- _python_validate_compiler (${_${_PYTHON_PREFIX}_VERSION} EXACT)
- if (_${_PYTHON_PREFIX}_COMPILER)
- break()
- endif()
- endif()
- endforeach()
-
- # no specific version found, re-try in standard paths
- find_program (_${_PYTHON_PREFIX}_COMPILER
- NAMES ipyc
- HINTS ${_${_PYTHON_PREFIX}_IRON_ROOT} ${_${_PYTHON_PREFIX}_HINTS}
- PATH_SUFFIXES ${_${_PYTHON_PREFIX}_IRON_PYTHON_PATH_SUFFIXES})
- endif()
- endif()
-
- set (${_PYTHON_PREFIX}_COMPILER "${_${_PYTHON_PREFIX}_COMPILER}")
-
- if (_${_PYTHON_PREFIX}_COMPILER)
- # retrieve python environment version from compiler
- set (_${_PYTHON_PREFIX}_VERSION_DIR "${CMAKE_CURRENT_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/PythonCompilerVersion.dir")
- file (WRITE "${_${_PYTHON_PREFIX}_VERSION_DIR}/version.py" "import sys; sys.stdout.write('.'.join([str(x) for x in sys.version_info[:3]]))\n")
- execute_process (COMMAND "${_${_PYTHON_PREFIX}_COMPILER}" /target:exe /embed "${_${_PYTHON_PREFIX}_VERSION_DIR}/version.py"
- WORKING_DIRECTORY "${_${_PYTHON_PREFIX}_VERSION_DIR}"
- OUTPUT_QUIET
- ERROR_QUIET)
- execute_process (COMMAND "${_${_PYTHON_PREFIX}_VERSION_DIR}/version"
- WORKING_DIRECTORY "${_${_PYTHON_PREFIX}_VERSION_DIR}"
- RESULT_VARIABLE _${_PYTHON_PREFIX}_RESULT
- OUTPUT_VARIABLE _${_PYTHON_PREFIX}_VERSION
- ERROR_QUIET)
- if (NOT _${_PYTHON_PREFIX}_RESULT)
- set (_${_PYTHON_PREFIX}_COMPILER_USABLE TRUE)
- string (REGEX MATCHALL "[0-9]+" _${_PYTHON_PREFIX}_VERSIONS "${_${_PYTHON_PREFIX}_VERSION}")
- list (GET _${_PYTHON_PREFIX}_VERSIONS 0 _${_PYTHON_PREFIX}_VERSION_MAJOR)
- list (GET _${_PYTHON_PREFIX}_VERSIONS 1 _${_PYTHON_PREFIX}_VERSION_MINOR)
- list (GET _${_PYTHON_PREFIX}_VERSIONS 2 _${_PYTHON_PREFIX}_VERSION_PATCH)
-
- if (NOT ${_PYTHON_PREFIX}_Interpreter_FOUND)
- # set public version information
- set (${_PYTHON_PREFIX}_VERSION ${_${_PYTHON_PREFIX}_VERSION})
- set (${_PYTHON_PREFIX}_VERSION_MAJOR ${_${_PYTHON_PREFIX}_VERSION_MAJOR})
- set (${_PYTHON_PREFIX}_VERSION_MINOR ${_${_PYTHON_PREFIX}_VERSION_MINOR})
- set (${_PYTHON_PREFIX}_VERSION_PATCH ${_${_PYTHON_PREFIX}_VERSION_PATCH})
- endif()
- else()
- # compiler not usable
- set (_${_PYTHON_PREFIX}_COMPILER_USABLE FALSE)
- set (_${_PYTHON_PREFIX}_Compiler_REASON_FAILURE "Cannot run the compiler \"${_${_PYTHON_PREFIX}_COMPILER}\"")
- endif()
- file (REMOVE_RECURSE "${_${_PYTHON_PREFIX}_VERSION_DIR}")
- endif()
-
- if (_${_PYTHON_PREFIX}_COMPILER AND _${_PYTHON_PREFIX}_COMPILER_USABLE)
- if (${_PYTHON_PREFIX}_Interpreter_FOUND)
- # Compiler must be compatible with interpreter
- if ("${_${_PYTHON_PREFIX}_VERSION_MAJOR}.${_${_PYTHON_PREFIX}_VERSION_MINOR}" VERSION_EQUAL "${${_PYTHON_PREFIX}_VERSION_MAJOR}.${${_PYTHON_PREFIX}_VERSION_MINOR}")
- set (${_PYTHON_PREFIX}_Compiler_FOUND TRUE)
- endif()
- elseif (${_PYTHON_PREFIX}_VERSION_MAJOR VERSION_EQUAL _${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR)
- set (${_PYTHON_PREFIX}_Compiler_FOUND TRUE)
- # Use compiler version for future searches to ensure consistency
- set (_${_PYTHON_PREFIX}_FIND_VERSIONS ${${_PYTHON_PREFIX}_VERSION_MAJOR}.${${_PYTHON_PREFIX}_VERSION_MINOR})
- endif()
- endif()
-
- if (${_PYTHON_PREFIX}_Compiler_FOUND)
- # compute and save compiler signature
- string (MD5 __${_PYTHON_PREFIX}_COMPILER_SIGNATURE "${_${_PYTHON_PREFIX}_SIGNATURE}:${_${_PYTHON_PREFIX}_COMPILER}")
- set (_${_PYTHON_PREFIX}_COMPILER_SIGNATURE "${__${_PYTHON_PREFIX}_COMPILER_SIGNATURE}" CACHE INTERNAL "")
-
- set (${_PYTHON_PREFIX}_COMPILER_ID IronPython)
- else()
- unset (_${_PYTHON_PREFIX}_COMPILER_SIGNATURE CACHE)
- unset (${_PYTHON_PREFIX}_COMPILER_ID)
- endif()
-
- if (${_PYTHON_PREFIX}_ARTIFACTS_INTERACTIVE)
- set (${_PYTHON_PREFIX}_COMPILER "${_${_PYTHON_PREFIX}_COMPILER}" CACHE FILEPATH "${_PYTHON_PREFIX} Compiler")
- endif()
-
- _python_mark_as_internal (_${_PYTHON_PREFIX}_COMPILER
- _${_PYTHON_PREFIX}_COMPILER_SIGNATURE)
-endif()
-
-
-# third step, search for the development artifacts
-## Development environment is not compatible with IronPython interpreter
-if (("Development.Module" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS
- OR "Development.Embed" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS)
- AND NOT ${_PYTHON_PREFIX}_INTERPRETER_ID STREQUAL "IronPython")
- if ("LIBRARY" IN_LIST _${_PYTHON_PREFIX}_FIND_DEVELOPMENT_ARTIFACTS)
- list (APPEND _${_PYTHON_PREFIX}_CACHED_VARS _${_PYTHON_PREFIX}_LIBRARY_RELEASE
- _${_PYTHON_PREFIX}_RUNTIME_LIBRARY_RELEASE
- _${_PYTHON_PREFIX}_LIBRARY_DEBUG
- _${_PYTHON_PREFIX}_RUNTIME_LIBRARY_DEBUG)
- endif()
- if ("INCLUDE_DIR" IN_LIST _${_PYTHON_PREFIX}_FIND_DEVELOPMENT_ARTIFACTS)
- list (APPEND _${_PYTHON_PREFIX}_CACHED_VARS _${_PYTHON_PREFIX}_INCLUDE_DIR)
- endif()
- if (${_PYTHON_PREFIX}_FIND_REQUIRED_Development.Module)
- if ("LIBRARY" IN_LIST _${_PYTHON_PREFIX}_FIND_DEVELOPMENT_MODULE_ARTIFACTS)
- list (APPEND _${_PYTHON_PREFIX}_REQUIRED_VARS ${_PYTHON_PREFIX}_LIBRARIES)
- endif()
- if ("INCLUDE_DIR" IN_LIST _${_PYTHON_PREFIX}_FIND_DEVELOPMENT_MODULE_ARTIFACTS)
- list (APPEND _${_PYTHON_PREFIX}_REQUIRED_VARS ${_PYTHON_PREFIX}_INCLUDE_DIRS)
- endif()
- endif()
- if (${_PYTHON_PREFIX}_FIND_REQUIRED_Development.Embed)
- if ("LIBRARY" IN_LIST _${_PYTHON_PREFIX}_FIND_DEVELOPMENT_EMBED_ARTIFACTS)
- list (APPEND _${_PYTHON_PREFIX}_REQUIRED_VARS ${_PYTHON_PREFIX}_LIBRARIES)
- endif()
- if ("INCLUDE_DIR" IN_LIST _${_PYTHON_PREFIX}_FIND_DEVELOPMENT_EMBED_ARTIFACTS)
- list (APPEND _${_PYTHON_PREFIX}_REQUIRED_VARS ${_PYTHON_PREFIX}_INCLUDE_DIRS)
- endif()
- endif()
- list (REMOVE_DUPLICATES _${_PYTHON_PREFIX}_REQUIRED_VARS)
-
- _python_check_development_signature (Module)
- _python_check_development_signature (Embed)
-
- if (DEFINED ${_PYTHON_PREFIX}_LIBRARY
- AND IS_ABSOLUTE "${${_PYTHON_PREFIX}_LIBRARY}")
- set (_${_PYTHON_PREFIX}_LIBRARY_RELEASE "${${_PYTHON_PREFIX}_LIBRARY}" CACHE INTERNAL "")
- unset (_${_PYTHON_PREFIX}_LIBRARY_DEBUG CACHE)
- unset (_${_PYTHON_PREFIX}_INCLUDE_DIR CACHE)
- endif()
- if (DEFINED ${_PYTHON_PREFIX}_INCLUDE_DIR
- AND IS_ABSOLUTE "${${_PYTHON_PREFIX}_INCLUDE_DIR}")
- set (_${_PYTHON_PREFIX}_INCLUDE_DIR "${${_PYTHON_PREFIX}_INCLUDE_DIR}" CACHE INTERNAL "")
- endif()
-
- # Support preference of static libs by adjusting CMAKE_FIND_LIBRARY_SUFFIXES
- unset (_${_PYTHON_PREFIX}_CMAKE_FIND_LIBRARY_SUFFIXES)
- if (DEFINED ${_PYTHON_PREFIX}_USE_STATIC_LIBS AND NOT WIN32)
- set(_${_PYTHON_PREFIX}_CMAKE_FIND_LIBRARY_SUFFIXES ${CMAKE_FIND_LIBRARY_SUFFIXES})
- if(${_PYTHON_PREFIX}_USE_STATIC_LIBS)
- set (CMAKE_FIND_LIBRARY_SUFFIXES ${CMAKE_STATIC_LIBRARY_SUFFIX})
- else()
- list (REMOVE_ITEM CMAKE_FIND_LIBRARY_SUFFIXES ${CMAKE_STATIC_LIBRARY_SUFFIX})
- endif()
- endif()
-
- if (NOT _${_PYTHON_PREFIX}_LIBRARY_RELEASE OR NOT _${_PYTHON_PREFIX}_INCLUDE_DIR)
- # if python interpreter is found, use it to look-up for artifacts
- # to ensure consistency between interpreter and development environments.
- # If not, try to locate a compatible config tool
- if (NOT ${_PYTHON_PREFIX}_Interpreter_FOUND OR CMAKE_CROSSCOMPILING)
- set (_${_PYTHON_PREFIX}_HINTS "${${_PYTHON_PREFIX}_ROOT_DIR}" ENV ${_PYTHON_PREFIX}_ROOT_DIR)
- unset (_${_PYTHON_PREFIX}_VIRTUALENV_PATHS)
- if (_${_PYTHON_PREFIX}_FIND_VIRTUALENV MATCHES "^(FIRST|ONLY)$")
- set (_${_PYTHON_PREFIX}_VIRTUALENV_PATHS ENV VIRTUAL_ENV ENV CONDA_PREFIX)
- endif()
- unset (_${_PYTHON_PREFIX}_FRAMEWORK_PATHS)
-
- if (_${_PYTHON_PREFIX}_FIND_STRATEGY STREQUAL "LOCATION")
- set (_${_PYTHON_PREFIX}_CONFIG_NAMES)
-
- foreach (_${_PYTHON_PREFIX}_VERSION IN LISTS _${_PYTHON_PREFIX}_FIND_VERSIONS)
- _python_get_names (_${_PYTHON_PREFIX}_VERSION_NAMES VERSION ${_${_PYTHON_PREFIX}_VERSION} POSIX CONFIG)
- list (APPEND _${_PYTHON_PREFIX}_CONFIG_NAMES ${_${_PYTHON_PREFIX}_VERSION_NAMES})
-
- # Framework Paths
- _python_get_frameworks (_${_PYTHON_PREFIX}_VERSION_PATHS ${_${_PYTHON_PREFIX}_VERSION})
- list (APPEND _${_PYTHON_PREFIX}_FRAMEWORK_PATHS ${_${_PYTHON_PREFIX}_VERSION_PATHS})
- endforeach()
-
- # Apple frameworks handling
- if (CMAKE_HOST_APPLE AND _${_PYTHON_PREFIX}_FIND_FRAMEWORK STREQUAL "FIRST")
- find_program (_${_PYTHON_PREFIX}_CONFIG
- NAMES ${_${_PYTHON_PREFIX}_CONFIG_NAMES}
- NAMES_PER_DIR
- HINTS ${_${_PYTHON_PREFIX}_HINTS}
- PATHS ${_${_PYTHON_PREFIX}_VIRTUALENV_PATHS}
- ${_${_PYTHON_PREFIX}_FRAMEWORK_PATHS}
- PATH_SUFFIXES bin
- NO_CMAKE_PATH
- NO_CMAKE_ENVIRONMENT_PATH
- NO_SYSTEM_ENVIRONMENT_PATH
- NO_CMAKE_SYSTEM_PATH)
- endif()
-
- find_program (_${_PYTHON_PREFIX}_CONFIG
- NAMES ${_${_PYTHON_PREFIX}_CONFIG_NAMES}
- NAMES_PER_DIR
- HINTS ${_${_PYTHON_PREFIX}_HINTS}
- PATHS ${_${_PYTHON_PREFIX}_VIRTUALENV_PATHS}
- PATH_SUFFIXES bin)
-
- # Apple frameworks handling
- if (CMAKE_HOST_APPLE AND _${_PYTHON_PREFIX}_FIND_FRAMEWORK STREQUAL "LAST")
- find_program (_${_PYTHON_PREFIX}_CONFIG
- NAMES ${_${_PYTHON_PREFIX}_CONFIG_NAMES}
- NAMES_PER_DIR
- PATHS ${_${_PYTHON_PREFIX}_FRAMEWORK_PATHS}
- PATH_SUFFIXES bin
- NO_DEFAULT_PATH)
- endif()
-
- if (_${_PYTHON_PREFIX}_CONFIG)
- execute_process (COMMAND "${_${_PYTHON_PREFIX}_CONFIG}" --help
- RESULT_VARIABLE _${_PYTHON_PREFIX}_RESULT
- OUTPUT_VARIABLE __${_PYTHON_PREFIX}_HELP
- ERROR_QUIET
- OUTPUT_STRIP_TRAILING_WHITESPACE)
- if (_${_PYTHON_PREFIX}_RESULT)
- # assume config tool is not usable
- unset (_${_PYTHON_PREFIX}_CONFIG CACHE)
- endif()
- endif()
-
- if (_${_PYTHON_PREFIX}_CONFIG)
- execute_process (COMMAND "${_${_PYTHON_PREFIX}_CONFIG}" --abiflags
- RESULT_VARIABLE _${_PYTHON_PREFIX}_RESULT
- OUTPUT_VARIABLE __${_PYTHON_PREFIX}_ABIFLAGS
- ERROR_QUIET
- OUTPUT_STRIP_TRAILING_WHITESPACE)
- if (_${_PYTHON_PREFIX}_RESULT)
- # assume ABI is not supported
- set (__${_PYTHON_PREFIX}_ABIFLAGS "")
- endif()
- if (DEFINED _${_PYTHON_PREFIX}_FIND_ABI AND NOT __${_PYTHON_PREFIX}_ABIFLAGS IN_LIST _${_PYTHON_PREFIX}_ABIFLAGS)
- # Wrong ABI
- unset (_${_PYTHON_PREFIX}_CONFIG CACHE)
- endif()
- endif()
-
- if (_${_PYTHON_PREFIX}_CONFIG AND DEFINED CMAKE_LIBRARY_ARCHITECTURE)
- # check that config tool match library architecture
- execute_process (COMMAND "${_${_PYTHON_PREFIX}_CONFIG}" --configdir
- RESULT_VARIABLE _${_PYTHON_PREFIX}_RESULT
- OUTPUT_VARIABLE _${_PYTHON_PREFIX}_CONFIGDIR
- ERROR_QUIET
- OUTPUT_STRIP_TRAILING_WHITESPACE)
- if (_${_PYTHON_PREFIX}_RESULT)
- unset (_${_PYTHON_PREFIX}_CONFIG CACHE)
- else()
- string(FIND "${_${_PYTHON_PREFIX}_CONFIGDIR}" "${CMAKE_LIBRARY_ARCHITECTURE}" _${_PYTHON_PREFIX}_RESULT)
- if (_${_PYTHON_PREFIX}_RESULT EQUAL -1)
- unset (_${_PYTHON_PREFIX}_CONFIG CACHE)
- endif()
- endif()
- endif()
- else()
- foreach (_${_PYTHON_PREFIX}_VERSION IN LISTS _${_PYTHON_PREFIX}_FIND_VERSIONS)
- # try to use pythonX.Y-config tool
- _python_get_names (_${_PYTHON_PREFIX}_CONFIG_NAMES VERSION ${_${_PYTHON_PREFIX}_VERSION} POSIX CONFIG)
-
- # Framework Paths
- _python_get_frameworks (_${_PYTHON_PREFIX}_FRAMEWORK_PATHS ${_${_PYTHON_PREFIX}_VERSION})
-
- # Apple frameworks handling
- if (CMAKE_HOST_APPLE AND _${_PYTHON_PREFIX}_FIND_FRAMEWORK STREQUAL "FIRST")
- find_program (_${_PYTHON_PREFIX}_CONFIG
- NAMES ${_${_PYTHON_PREFIX}_CONFIG_NAMES}
- NAMES_PER_DIR
- HINTS ${_${_PYTHON_PREFIX}_HINTS}
- PATHS ${_${_PYTHON_PREFIX}_VIRTUALENV_PATHS}
- ${_${_PYTHON_PREFIX}_FRAMEWORK_PATHS}
- PATH_SUFFIXES bin
- NO_CMAKE_PATH
- NO_CMAKE_ENVIRONMENT_PATH
- NO_SYSTEM_ENVIRONMENT_PATH
- NO_CMAKE_SYSTEM_PATH)
- endif()
-
- find_program (_${_PYTHON_PREFIX}_CONFIG
- NAMES ${_${_PYTHON_PREFIX}_CONFIG_NAMES}
- NAMES_PER_DIR
- HINTS ${_${_PYTHON_PREFIX}_HINTS}
- PATHS ${_${_PYTHON_PREFIX}_VIRTUALENV_PATHS}
- PATH_SUFFIXES bin)
-
- # Apple frameworks handling
- if (CMAKE_HOST_APPLE AND _${_PYTHON_PREFIX}_FIND_FRAMEWORK STREQUAL "LAST")
- find_program (_${_PYTHON_PREFIX}_CONFIG
- NAMES ${_${_PYTHON_PREFIX}_CONFIG_NAMES}
- NAMES_PER_DIR
- PATHS ${_${_PYTHON_PREFIX}_FRAMEWORK_PATHS}
- PATH_SUFFIXES bin
- NO_DEFAULT_PATH)
- endif()
-
- unset (_${_PYTHON_PREFIX}_CONFIG_NAMES)
-
- if (_${_PYTHON_PREFIX}_CONFIG)
- execute_process (COMMAND "${_${_PYTHON_PREFIX}_CONFIG}" --help
- RESULT_VARIABLE _${_PYTHON_PREFIX}_RESULT
- OUTPUT_VARIABLE __${_PYTHON_PREFIX}_HELP
- ERROR_QUIET
- OUTPUT_STRIP_TRAILING_WHITESPACE)
- if (_${_PYTHON_PREFIX}_RESULT)
- # assume config tool is not usable
- unset (_${_PYTHON_PREFIX}_CONFIG CACHE)
- endif()
- endif()
-
- if (NOT _${_PYTHON_PREFIX}_CONFIG)
- continue()
- endif()
-
- execute_process (COMMAND "${_${_PYTHON_PREFIX}_CONFIG}" --abiflags
- RESULT_VARIABLE _${_PYTHON_PREFIX}_RESULT
- OUTPUT_VARIABLE __${_PYTHON_PREFIX}_ABIFLAGS
- ERROR_QUIET
- OUTPUT_STRIP_TRAILING_WHITESPACE)
- if (_${_PYTHON_PREFIX}_RESULT)
- # assume ABI is not supported
- set (__${_PYTHON_PREFIX}_ABIFLAGS "")
- endif()
- if (DEFINED _${_PYTHON_PREFIX}_FIND_ABI AND NOT __${_PYTHON_PREFIX}_ABIFLAGS IN_LIST _${_PYTHON_PREFIX}_ABIFLAGS)
- # Wrong ABI
- unset (_${_PYTHON_PREFIX}_CONFIG CACHE)
- continue()
- endif()
-
- if (_${_PYTHON_PREFIX}_CONFIG AND DEFINED CMAKE_LIBRARY_ARCHITECTURE)
- # check that config tool match library architecture
- execute_process (COMMAND "${_${_PYTHON_PREFIX}_CONFIG}" --configdir
- RESULT_VARIABLE _${_PYTHON_PREFIX}_RESULT
- OUTPUT_VARIABLE _${_PYTHON_PREFIX}_CONFIGDIR
- ERROR_QUIET
- OUTPUT_STRIP_TRAILING_WHITESPACE)
- if (_${_PYTHON_PREFIX}_RESULT)
- unset (_${_PYTHON_PREFIX}_CONFIG CACHE)
- continue()
- endif()
- string (FIND "${_${_PYTHON_PREFIX}_CONFIGDIR}" "${CMAKE_LIBRARY_ARCHITECTURE}" _${_PYTHON_PREFIX}_RESULT)
- if (_${_PYTHON_PREFIX}_RESULT EQUAL -1)
- unset (_${_PYTHON_PREFIX}_CONFIG CACHE)
- continue()
- endif()
- endif()
-
- if (_${_PYTHON_PREFIX}_CONFIG)
- break()
- endif()
- endforeach()
- endif()
- endif()
- endif()
-
- if ("LIBRARY" IN_LIST _${_PYTHON_PREFIX}_FIND_DEVELOPMENT_ARTIFACTS)
- if (NOT _${_PYTHON_PREFIX}_LIBRARY_RELEASE)
- if ((${_PYTHON_PREFIX}_Interpreter_FOUND AND NOT CMAKE_CROSSCOMPILING) OR _${_PYTHON_PREFIX}_CONFIG)
- # retrieve root install directory
- _python_get_config_var (_${_PYTHON_PREFIX}_PREFIX PREFIX)
-
- # enforce current ABI
- _python_get_config_var (_${_PYTHON_PREFIX}_ABIFLAGS ABIFLAGS)
-
- set (_${_PYTHON_PREFIX}_HINTS "${_${_PYTHON_PREFIX}_PREFIX}")
-
- # retrieve library
- ## compute some paths and artifact names
- if (_${_PYTHON_PREFIX}_CONFIG)
- string (REGEX REPLACE "^.+python([0-9.]+)[a-z]*-config" "\\1" _${_PYTHON_PREFIX}_VERSION "${_${_PYTHON_PREFIX}_CONFIG}")
- else()
- set (_${_PYTHON_PREFIX}_VERSION "${${_PYTHON_PREFIX}_VERSION_MAJOR}.${${_PYTHON_PREFIX}_VERSION_MINOR}")
- endif()
- _python_get_path_suffixes (_${_PYTHON_PREFIX}_PATH_SUFFIXES VERSION ${_${_PYTHON_PREFIX}_VERSION} LIBRARY)
- _python_get_names (_${_PYTHON_PREFIX}_LIB_NAMES VERSION ${_${_PYTHON_PREFIX}_VERSION} WIN32 POSIX LIBRARY)
-
- _python_get_config_var (_${_PYTHON_PREFIX}_CONFIGDIR CONFIGDIR)
- list (APPEND _${_PYTHON_PREFIX}_HINTS "${_${_PYTHON_PREFIX}_CONFIGDIR}")
-
- list (APPEND _${_PYTHON_PREFIX}_HINTS "${${_PYTHON_PREFIX}_ROOT_DIR}" ENV ${_PYTHON_PREFIX}_ROOT_DIR)
-
- find_library (_${_PYTHON_PREFIX}_LIBRARY_RELEASE
- NAMES ${_${_PYTHON_PREFIX}_LIB_NAMES}
- NAMES_PER_DIR
- HINTS ${_${_PYTHON_PREFIX}_HINTS}
- PATH_SUFFIXES ${_${_PYTHON_PREFIX}_PATH_SUFFIXES}
- NO_SYSTEM_ENVIRONMENT_PATH
- NO_CMAKE_SYSTEM_PATH)
- endif()
-
- # Rely on HINTS and standard paths if interpreter or config tool failed to locate artifacts
- if (NOT _${_PYTHON_PREFIX}_LIBRARY_RELEASE)
- set (_${_PYTHON_PREFIX}_HINTS "${${_PYTHON_PREFIX}_ROOT_DIR}" ENV ${_PYTHON_PREFIX}_ROOT_DIR)
-
- unset (_${_PYTHON_PREFIX}_VIRTUALENV_PATHS)
- if (_${_PYTHON_PREFIX}_FIND_VIRTUALENV MATCHES "^(FIRST|ONLY)$")
- set (_${_PYTHON_PREFIX}_VIRTUALENV_PATHS ENV VIRTUAL_ENV ENV CONDA_PREFIX)
- endif()
-
- if (_${_PYTHON_PREFIX}_FIND_STRATEGY STREQUAL "LOCATION")
- unset (_${_PYTHON_PREFIX}_LIB_NAMES)
- unset (_${_PYTHON_PREFIX}_LIB_NAMES_DEBUG)
- unset (_${_PYTHON_PREFIX}_FRAMEWORK_PATHS)
- unset (_${_PYTHON_PREFIX}_REGISTRY_PATHS)
- unset (_${_PYTHON_PREFIX}_PATH_SUFFIXES)
-
- foreach (_${_PYTHON_PREFIX}_LIB_VERSION IN LISTS _${_PYTHON_PREFIX}_FIND_VERSIONS)
- # library names
- _python_get_names (_${_PYTHON_PREFIX}_VERSION_NAMES VERSION ${_${_PYTHON_PREFIX}_LIB_VERSION} WIN32 POSIX LIBRARY)
- list (APPEND _${_PYTHON_PREFIX}_LIB_NAMES ${_${_PYTHON_PREFIX}_VERSION_NAMES})
- _python_get_names (_${_PYTHON_PREFIX}_VERSION_NAMES VERSION ${_${_PYTHON_PREFIX}_LIB_VERSION} WIN32 DEBUG)
- list (APPEND _${_PYTHON_PREFIX}_LIB_NAMES_DEBUG ${_${_PYTHON_PREFIX}_VERSION_NAMES})
-
- # Framework Paths
- _python_get_frameworks (_${_PYTHON_PREFIX}_VERSION_PATHS ${_${_PYTHON_PREFIX}_LIB_VERSION})
- list (APPEND _${_PYTHON_PREFIX}_FRAMEWORK_PATHS ${_${_PYTHON_PREFIX}_VERSION_PATHS})
-
- # Registry Paths
- _python_get_registries (_${_PYTHON_PREFIX}_VERSION_PATHS ${_${_PYTHON_PREFIX}_LIB_VERSION})
- list (APPEND _${_PYTHON_PREFIX}_REGISTRY_PATHS ${_${_PYTHON_PREFIX}_VERSION_PATHS})
-
- # Paths suffixes
- _python_get_path_suffixes (_${_PYTHON_PREFIX}_VERSION_PATHS VERSION ${_${_PYTHON_PREFIX}_LIB_VERSION} LIBRARY)
- list (APPEND _${_PYTHON_PREFIX}_PATH_SUFFIXES ${_${_PYTHON_PREFIX}_VERSION_PATHS})
- endforeach()
-
- if (APPLE AND _${_PYTHON_PREFIX}_FIND_FRAMEWORK STREQUAL "FIRST")
- find_library (_${_PYTHON_PREFIX}_LIBRARY_RELEASE
- NAMES ${_${_PYTHON_PREFIX}_LIB_NAMES}
- NAMES_PER_DIR
- HINTS ${_${_PYTHON_PREFIX}_HINTS}
- PATHS ${_${_PYTHON_PREFIX}_VIRTUALENV_PATHS}
- ${_${_PYTHON_PREFIX}_FRAMEWORK_PATHS}
- PATH_SUFFIXES ${_${_PYTHON_PREFIX}_PATH_SUFFIXES}
- NO_CMAKE_PATH
- NO_CMAKE_ENVIRONMENT_PATH
- NO_SYSTEM_ENVIRONMENT_PATH
- NO_CMAKE_SYSTEM_PATH)
- endif()
-
- if (WIN32 AND _${_PYTHON_PREFIX}_FIND_REGISTRY STREQUAL "FIRST")
- find_library (_${_PYTHON_PREFIX}_LIBRARY_RELEASE
- NAMES ${_${_PYTHON_PREFIX}_LIB_NAMES}
- NAMES_PER_DIR
- HINTS ${_${_PYTHON_PREFIX}_HINTS}
- PATHS ${_${_PYTHON_PREFIX}_VIRTUALENV_PATHS}
- ${_${_PYTHON_PREFIX}_REGISTRY_PATHS}
- PATH_SUFFIXES ${_${_PYTHON_PREFIX}_PATH_SUFFIXES}
- NO_SYSTEM_ENVIRONMENT_PATH
- NO_CMAKE_SYSTEM_PATH)
- endif()
-
- # search in HINTS locations
- find_library (_${_PYTHON_PREFIX}_LIBRARY_RELEASE
- NAMES ${_${_PYTHON_PREFIX}_LIB_NAMES}
- NAMES_PER_DIR
- HINTS ${_${_PYTHON_PREFIX}_HINTS}
- PATHS ${_${_PYTHON_PREFIX}_VIRTUALENV_PATHS}
- PATH_SUFFIXES ${_${_PYTHON_PREFIX}_PATH_SUFFIXES}
- NO_SYSTEM_ENVIRONMENT_PATH
- NO_CMAKE_SYSTEM_PATH)
-
- if (APPLE AND _${_PYTHON_PREFIX}_FIND_FRAMEWORK STREQUAL "LAST")
- set (__${_PYTHON_PREFIX}_FRAMEWORK_PATHS ${_${_PYTHON_PREFIX}_FRAMEWORK_PATHS})
- else()
- unset (__${_PYTHON_PREFIX}_FRAMEWORK_PATHS)
- endif()
-
- if (WIN32 AND _${_PYTHON_PREFIX}_FIND_REGISTRY STREQUAL "LAST")
- set (__${_PYTHON_PREFIX}_REGISTRY_PATHS ${_${_PYTHON_PREFIX}_REGISTRY_PATHS})
- else()
- unset (__${_PYTHON_PREFIX}_REGISTRY_PATHS)
- endif()
-
- # search in all default paths
- find_library (_${_PYTHON_PREFIX}_LIBRARY_RELEASE
- NAMES ${_${_PYTHON_PREFIX}_LIB_NAMES}
- NAMES_PER_DIR
- PATHS ${__${_PYTHON_PREFIX}_FRAMEWORK_PATHS}
- ${__${_PYTHON_PREFIX}_REGISTRY_PATHS}
- PATH_SUFFIXES ${_${_PYTHON_PREFIX}_PATH_SUFFIXES})
- else()
- foreach (_${_PYTHON_PREFIX}_LIB_VERSION IN LISTS _${_PYTHON_PREFIX}_FIND_VERSIONS)
- _python_get_names (_${_PYTHON_PREFIX}_LIB_NAMES VERSION ${_${_PYTHON_PREFIX}_LIB_VERSION} WIN32 POSIX LIBRARY)
- _python_get_names (_${_PYTHON_PREFIX}_LIB_NAMES_DEBUG VERSION ${_${_PYTHON_PREFIX}_LIB_VERSION} WIN32 DEBUG)
-
- _python_get_frameworks (_${_PYTHON_PREFIX}_FRAMEWORK_PATHS ${_${_PYTHON_PREFIX}_LIB_VERSION})
- _python_get_registries (_${_PYTHON_PREFIX}_REGISTRY_PATHS ${_${_PYTHON_PREFIX}_LIB_VERSION})
-
- _python_get_path_suffixes (_${_PYTHON_PREFIX}_PATH_SUFFIXES VERSION ${_${_PYTHON_PREFIX}_LIB_VERSION} LIBRARY)
-
- if (APPLE AND _${_PYTHON_PREFIX}_FIND_FRAMEWORK STREQUAL "FIRST")
- find_library (_${_PYTHON_PREFIX}_LIBRARY_RELEASE
- NAMES ${_${_PYTHON_PREFIX}_LIB_NAMES}
- NAMES_PER_DIR
- HINTS ${_${_PYTHON_PREFIX}_HINTS}
- PATHS ${_${_PYTHON_PREFIX}_VIRTUALENV_PATHS}
- ${_${_PYTHON_PREFIX}_FRAMEWORK_PATHS}
- PATH_SUFFIXES ${_${_PYTHON_PREFIX}_PATH_SUFFIXES}
- NO_CMAKE_PATH
- NO_CMAKE_ENVIRONMENT_PATH
- NO_SYSTEM_ENVIRONMENT_PATH
- NO_CMAKE_SYSTEM_PATH)
- endif()
-
- if (WIN32 AND _${_PYTHON_PREFIX}_FIND_REGISTRY STREQUAL "FIRST")
- find_library (_${_PYTHON_PREFIX}_LIBRARY_RELEASE
- NAMES ${_${_PYTHON_PREFIX}_LIB_NAMES}
- NAMES_PER_DIR
- HINTS ${_${_PYTHON_PREFIX}_HINTS}
- PATHS ${_${_PYTHON_PREFIX}_VIRTUALENV_PATHS}
- ${_${_PYTHON_PREFIX}_REGISTRY_PATHS}
- PATH_SUFFIXES ${_${_PYTHON_PREFIX}_PATH_SUFFIXES}
- NO_SYSTEM_ENVIRONMENT_PATH
- NO_CMAKE_SYSTEM_PATH)
- endif()
-
- # search in HINTS locations
- find_library (_${_PYTHON_PREFIX}_LIBRARY_RELEASE
- NAMES ${_${_PYTHON_PREFIX}_LIB_NAMES}
- NAMES_PER_DIR
- HINTS ${_${_PYTHON_PREFIX}_HINTS}
- PATHS ${_${_PYTHON_PREFIX}_VIRTUALENV_PATHS}
- PATH_SUFFIXES ${_${_PYTHON_PREFIX}_PATH_SUFFIXES}
- NO_SYSTEM_ENVIRONMENT_PATH
- NO_CMAKE_SYSTEM_PATH)
-
- if (APPLE AND _${_PYTHON_PREFIX}_FIND_FRAMEWORK STREQUAL "LAST")
- set (__${_PYTHON_PREFIX}_FRAMEWORK_PATHS ${_${_PYTHON_PREFIX}_FRAMEWORK_PATHS})
- else()
- unset (__${_PYTHON_PREFIX}_FRAMEWORK_PATHS)
- endif()
-
- if (WIN32 AND _${_PYTHON_PREFIX}_FIND_REGISTRY STREQUAL "LAST")
- set (__${_PYTHON_PREFIX}_REGISTRY_PATHS ${_${_PYTHON_PREFIX}_REGISTRY_PATHS})
- else()
- unset (__${_PYTHON_PREFIX}_REGISTRY_PATHS)
- endif()
-
- # search in all default paths
- find_library (_${_PYTHON_PREFIX}_LIBRARY_RELEASE
- NAMES ${_${_PYTHON_PREFIX}_LIB_NAMES}
- NAMES_PER_DIR
- PATHS ${__${_PYTHON_PREFIX}_FRAMEWORK_PATHS}
- ${__${_PYTHON_PREFIX}_REGISTRY_PATHS}
- PATH_SUFFIXES ${_${_PYTHON_PREFIX}_PATH_SUFFIXES})
-
- if (_${_PYTHON_PREFIX}_LIBRARY_RELEASE)
- break()
- endif()
- endforeach()
- endif()
- endif()
- endif()
-
- # finalize library version information
- _python_get_version (LIBRARY PREFIX _${_PYTHON_PREFIX}_)
-
- set (${_PYTHON_PREFIX}_LIBRARY_RELEASE "${_${_PYTHON_PREFIX}_LIBRARY_RELEASE}")
-
- if (_${_PYTHON_PREFIX}_LIBRARY_RELEASE AND NOT EXISTS "${_${_PYTHON_PREFIX}_LIBRARY_RELEASE}")
- set (_${_PYTHON_PREFIX}_Development_REASON_FAILURE "Cannot find the library \"${_${_PYTHON_PREFIX}_LIBRARY_RELEASE}\"")
- set_property (CACHE _${_PYTHON_PREFIX}_LIBRARY_RELEASE PROPERTY VALUE "${_PYTHON_PREFIX}_LIBRARY_RELEASE-NOTFOUND")
- endif()
-
- set (_${_PYTHON_PREFIX}_HINTS "${${_PYTHON_PREFIX}_ROOT_DIR}" ENV ${_PYTHON_PREFIX}_ROOT_DIR)
-
- if (WIN32 AND _${_PYTHON_PREFIX}_LIBRARY_RELEASE)
- # search for debug library
- # use release library location as a hint
- _python_get_names (_${_PYTHON_PREFIX}_LIB_NAMES_DEBUG VERSION ${_${_PYTHON_PREFIX}_VERSION} WIN32 DEBUG)
- get_filename_component (_${_PYTHON_PREFIX}_PATH "${_${_PYTHON_PREFIX}_LIBRARY_RELEASE}" DIRECTORY)
- find_library (_${_PYTHON_PREFIX}_LIBRARY_DEBUG
- NAMES ${_${_PYTHON_PREFIX}_LIB_NAMES_DEBUG}
- NAMES_PER_DIR
- HINTS "${_${_PYTHON_PREFIX}_PATH}" ${_${_PYTHON_PREFIX}_HINTS}
- NO_DEFAULT_PATH)
- endif()
-
- # retrieve runtime libraries
- if (_${_PYTHON_PREFIX}_LIBRARY_RELEASE)
- _python_get_names (_${_PYTHON_PREFIX}_LIB_NAMES VERSION ${_${_PYTHON_PREFIX}_VERSION} WIN32 POSIX LIBRARY)
- get_filename_component (_${_PYTHON_PREFIX}_PATH "${_${_PYTHON_PREFIX}_LIBRARY_RELEASE}" DIRECTORY)
- get_filename_component (_${_PYTHON_PREFIX}_PATH2 "${_${_PYTHON_PREFIX}_PATH}" DIRECTORY)
- _python_find_runtime_library (_${_PYTHON_PREFIX}_RUNTIME_LIBRARY_RELEASE
- NAMES ${_${_PYTHON_PREFIX}_LIB_NAMES}
- NAMES_PER_DIR
- HINTS "${_${_PYTHON_PREFIX}_PATH}" "${_${_PYTHON_PREFIX}_PATH2}" ${_${_PYTHON_PREFIX}_HINTS}
- PATH_SUFFIXES bin)
- endif()
- if (_${_PYTHON_PREFIX}_LIBRARY_DEBUG)
- _python_get_names (_${_PYTHON_PREFIX}_LIB_NAMES_DEBUG VERSION ${_${_PYTHON_PREFIX}_VERSION} WIN32 DEBUG)
- get_filename_component (_${_PYTHON_PREFIX}_PATH "${_${_PYTHON_PREFIX}_LIBRARY_DEBUG}" DIRECTORY)
- get_filename_component (_${_PYTHON_PREFIX}_PATH2 "${_${_PYTHON_PREFIX}_PATH}" DIRECTORY)
- _python_find_runtime_library (_${_PYTHON_PREFIX}_RUNTIME_LIBRARY_DEBUG
- NAMES ${_${_PYTHON_PREFIX}_LIB_NAMES_DEBUG}
- NAMES_PER_DIR
- HINTS "${_${_PYTHON_PREFIX}_PATH}" "${_${_PYTHON_PREFIX}_PATH2}" ${_${_PYTHON_PREFIX}_HINTS}
- PATH_SUFFIXES bin)
- endif()
- endif()
-
- if ("INCLUDE_DIR" IN_LIST _${_PYTHON_PREFIX}_FIND_DEVELOPMENT_ARTIFACTS)
- while (NOT _${_PYTHON_PREFIX}_INCLUDE_DIR)
- if ("LIBRARY" IN_LIST _${_PYTHON_PREFIX}_FIND_DEVELOPMENT_ARTIFACTS
- AND NOT _${_PYTHON_PREFIX}_LIBRARY_RELEASE)
- # Don't search for include dir if no library was founded
- break()
- endif()
-
- if ((${_PYTHON_PREFIX}_Interpreter_FOUND AND NOT CMAKE_CROSSCOMPILING) OR _${_PYTHON_PREFIX}_CONFIG)
- _python_get_config_var (_${_PYTHON_PREFIX}_INCLUDE_DIRS INCLUDES)
-
- find_path (_${_PYTHON_PREFIX}_INCLUDE_DIR
- NAMES Python.h
- HINTS ${_${_PYTHON_PREFIX}_INCLUDE_DIRS}
- NO_SYSTEM_ENVIRONMENT_PATH
- NO_CMAKE_SYSTEM_PATH)
- endif()
-
- # Rely on HINTS and standard paths if interpreter or config tool failed to locate artifacts
- if (NOT _${_PYTHON_PREFIX}_INCLUDE_DIR)
- unset (_${_PYTHON_PREFIX}_VIRTUALENV_PATHS)
- if (_${_PYTHON_PREFIX}_FIND_VIRTUALENV MATCHES "^(FIRST|ONLY)$")
- set (_${_PYTHON_PREFIX}_VIRTUALENV_PATHS ENV VIRTUAL_ENV ENV CONDA_PREFIX)
- endif()
- unset (_${_PYTHON_PREFIX}_INCLUDE_HINTS)
-
- if (_${_PYTHON_PREFIX}_LIBRARY_RELEASE)
- # Use the library's install prefix as a hint
- if (_${_PYTHON_PREFIX}_LIBRARY_RELEASE MATCHES "^(.+/Frameworks/Python.framework/Versions/[0-9.]+)")
- list (APPEND _${_PYTHON_PREFIX}_INCLUDE_HINTS "${CMAKE_MATCH_1}")
- elseif (_${_PYTHON_PREFIX}_LIBRARY_RELEASE MATCHES "^(.+)/lib(64|32)?/python[0-9.]+/config")
- list (APPEND _${_PYTHON_PREFIX}_INCLUDE_HINTS "${CMAKE_MATCH_1}")
- elseif (DEFINED CMAKE_LIBRARY_ARCHITECTURE AND ${_${_PYTHON_PREFIX}_LIBRARY_RELEASE} MATCHES "^(.+)/lib/${CMAKE_LIBRARY_ARCHITECTURE}")
- list (APPEND _${_PYTHON_PREFIX}_INCLUDE_HINTS "${CMAKE_MATCH_1}")
- else()
- # assume library is in a directory under root
- get_filename_component (_${_PYTHON_PREFIX}_PREFIX "${_${_PYTHON_PREFIX}_LIBRARY_RELEASE}" DIRECTORY)
- get_filename_component (_${_PYTHON_PREFIX}_PREFIX "${_${_PYTHON_PREFIX}_PREFIX}" DIRECTORY)
- list (APPEND _${_PYTHON_PREFIX}_INCLUDE_HINTS "${_${_PYTHON_PREFIX}_PREFIX}")
- endif()
- endif()
-
- _python_get_frameworks (_${_PYTHON_PREFIX}_FRAMEWORK_PATHS ${_${_PYTHON_PREFIX}_VERSION})
- _python_get_registries (_${_PYTHON_PREFIX}_REGISTRY_PATHS ${_${_PYTHON_PREFIX}_VERSION})
- _python_get_path_suffixes (_${_PYTHON_PREFIX}_PATH_SUFFIXES VERSION ${_${_PYTHON_PREFIX}_VERSION} INCLUDE)
-
- if (APPLE AND _${_PYTHON_PREFIX}_FIND_FRAMEWORK STREQUAL "FIRST")
- find_path (_${_PYTHON_PREFIX}_INCLUDE_DIR
- NAMES Python.h
- HINTS ${_${_PYTHON_PREFIX}_INCLUDE_HINTS} ${_${_PYTHON_PREFIX}_HINTS}
- PATHS ${_${_PYTHON_PREFIX}_VIRTUALENV_PATHS}
- ${_${_PYTHON_PREFIX}_FRAMEWORK_PATHS}
- PATH_SUFFIXES ${_${_PYTHON_PREFIX}_PATH_SUFFIXES}
- NO_CMAKE_PATH
- NO_CMAKE_ENVIRONMENT_PATH
- NO_SYSTEM_ENVIRONMENT_PATH
- NO_CMAKE_SYSTEM_PATH)
- endif()
-
- if (WIN32 AND _${_PYTHON_PREFIX}_FIND_REGISTRY STREQUAL "FIRST")
- find_path (_${_PYTHON_PREFIX}_INCLUDE_DIR
- NAMES Python.h
- HINTS ${_${_PYTHON_PREFIX}_INCLUDE_HINTS} ${_${_PYTHON_PREFIX}_HINTS}
- PATHS ${_${_PYTHON_PREFIX}_VIRTUALENV_PATHS}
- ${_${_PYTHON_PREFIX}_REGISTRY_PATHS}
- PATH_SUFFIXES ${_${_PYTHON_PREFIX}_PATH_SUFFIXES}
- NO_SYSTEM_ENVIRONMENT_PATH
- NO_CMAKE_SYSTEM_PATH)
- endif()
-
- if (APPLE AND _${_PYTHON_PREFIX}_FIND_FRAMEWORK STREQUAL "LAST")
- set (__${_PYTHON_PREFIX}_FRAMEWORK_PATHS ${_${_PYTHON_PREFIX}_FRAMEWORK_PATHS})
- else()
- unset (__${_PYTHON_PREFIX}_FRAMEWORK_PATHS)
- endif()
-
- if (WIN32 AND _${_PYTHON_PREFIX}_FIND_REGISTRY STREQUAL "LAST")
- set (__${_PYTHON_PREFIX}_REGISTRY_PATHS ${_${_PYTHON_PREFIX}_REGISTRY_PATHS})
- else()
- unset (__${_PYTHON_PREFIX}_REGISTRY_PATHS)
- endif()
-
- find_path (_${_PYTHON_PREFIX}_INCLUDE_DIR
- NAMES Python.h
- HINTS ${_${_PYTHON_PREFIX}_INCLUDE_HINTS} ${_${_PYTHON_PREFIX}_HINTS}
- PATHS ${_${_PYTHON_PREFIX}_VIRTUALENV_PATHS}
- ${__${_PYTHON_PREFIX}_FRAMEWORK_PATHS}
- ${__${_PYTHON_PREFIX}_REGISTRY_PATHS}
- PATH_SUFFIXES ${_${_PYTHON_PREFIX}_PATH_SUFFIXES}
- NO_SYSTEM_ENVIRONMENT_PATH
- NO_CMAKE_SYSTEM_PATH)
- endif()
-
- # search header file in standard locations
- find_path (_${_PYTHON_PREFIX}_INCLUDE_DIR
- NAMES Python.h)
-
- break()
- endwhile()
-
- set (${_PYTHON_PREFIX}_INCLUDE_DIRS "${_${_PYTHON_PREFIX}_INCLUDE_DIR}")
-
- if (_${_PYTHON_PREFIX}_INCLUDE_DIR AND NOT EXISTS "${_${_PYTHON_PREFIX}_INCLUDE_DIR}")
- set (_${_PYTHON_PREFIX}_Development_REASON_FAILURE "Cannot find the directory \"${_${_PYTHON_PREFIX}_INCLUDE_DIR}\"")
- set_property (CACHE _${_PYTHON_PREFIX}_INCLUDE_DIR PROPERTY VALUE "${_PYTHON_PREFIX}_INCLUDE_DIR-NOTFOUND")
- endif()
-
- if (_${_PYTHON_PREFIX}_INCLUDE_DIR)
- # retrieve version from header file
- _python_get_version (INCLUDE PREFIX _${_PYTHON_PREFIX}_INC_)
-
- if (_${_PYTHON_PREFIX}_LIBRARY_RELEASE)
- # update versioning
- if (_${_PYTHON_PREFIX}_INC_VERSION VERSION_EQUAL _${_PYTHON_PREFIX}_VERSION)
- set (_${_PYTHON_PREFIX}_VERSION_PATCH ${_${_PYTHON_PREFIX}_INC_VERSION_PATCH})
- endif()
- else()
- set (_${_PYTHON_PREFIX}_VERSION ${_${_PYTHON_PREFIX}_INC_VERSION})
- set (_${_PYTHON_PREFIX}_VERSION_MAJOR ${_${_PYTHON_PREFIX}_INC_VERSION_MAJOR})
- set (_${_PYTHON_PREFIX}_VERSION_MINOR ${_${_PYTHON_PREFIX}_INC_VERSION_MINOR})
- set (_${_PYTHON_PREFIX}_VERSION_PATCH ${_${_PYTHON_PREFIX}_INC_VERSION_PATCH})
- endif()
- endif()
- endif()
-
- if (NOT ${_PYTHON_PREFIX}_Interpreter_FOUND AND NOT ${_PYTHON_PREFIX}_Compiler_FOUND)
- # set public version information
- set (${_PYTHON_PREFIX}_VERSION ${_${_PYTHON_PREFIX}_VERSION})
- set (${_PYTHON_PREFIX}_VERSION_MAJOR ${_${_PYTHON_PREFIX}_VERSION_MAJOR})
- set (${_PYTHON_PREFIX}_VERSION_MINOR ${_${_PYTHON_PREFIX}_VERSION_MINOR})
- set (${_PYTHON_PREFIX}_VERSION_PATCH ${_${_PYTHON_PREFIX}_VERSION_PATCH})
- endif()
-
- # define public variables
- if ("LIBRARY" IN_LIST _${_PYTHON_PREFIX}_FIND_DEVELOPMENT_ARTIFACTS)
- set (${_PYTHON_PREFIX}_LIBRARY_DEBUG "${_${_PYTHON_PREFIX}_LIBRARY_DEBUG}")
- _python_select_library_configurations (${_PYTHON_PREFIX})
-
- set (${_PYTHON_PREFIX}_RUNTIME_LIBRARY_RELEASE "${_${_PYTHON_PREFIX}_RUNTIME_LIBRARY_RELEASE}")
- set (${_PYTHON_PREFIX}_RUNTIME_LIBRARY_DEBUG "${_${_PYTHON_PREFIX}_RUNTIME_LIBRARY_DEBUG}")
-
- if (_${_PYTHON_PREFIX}_RUNTIME_LIBRARY_RELEASE)
- set (${_PYTHON_PREFIX}_RUNTIME_LIBRARY "${_${_PYTHON_PREFIX}_RUNTIME_LIBRARY_RELEASE}")
- elseif (_${_PYTHON_PREFIX}_RUNTIME_LIBRARY_DEBUG)
- set (${_PYTHON_PREFIX}_RUNTIME_LIBRARY "${_${_PYTHON_PREFIX}_RUNTIME_LIBRARY_DEBUG}")
- else()
- set (${_PYTHON_PREFIX}_RUNTIME_LIBRARY "${_PYTHON_PREFIX}_RUNTIME_LIBRARY-NOTFOUND")
- endif()
-
- _python_set_library_dirs (${_PYTHON_PREFIX}_LIBRARY_DIRS
- _${_PYTHON_PREFIX}_LIBRARY_RELEASE _${_PYTHON_PREFIX}_LIBRARY_DEBUG)
- if (UNIX)
- if (_${_PYTHON_PREFIX}_LIBRARY_RELEASE MATCHES "${CMAKE_SHARED_LIBRARY_SUFFIX}$")
- set (${_PYTHON_PREFIX}_RUNTIME_LIBRARY_DIRS ${${_PYTHON_PREFIX}_LIBRARY_DIRS})
- endif()
- else()
- _python_set_library_dirs (${_PYTHON_PREFIX}_RUNTIME_LIBRARY_DIRS
- _${_PYTHON_PREFIX}_RUNTIME_LIBRARY_RELEASE _${_PYTHON_PREFIX}_RUNTIME_LIBRARY_DEBUG)
- endif()
- endif()
-
- if (_${_PYTHON_PREFIX}_LIBRARY_RELEASE OR _${_PYTHON_PREFIX}_INCLUDE_DIR)
- if (${_PYTHON_PREFIX}_Interpreter_FOUND OR ${_PYTHON_PREFIX}_Compiler_FOUND)
- # development environment must be compatible with interpreter/compiler
- if ("${_${_PYTHON_PREFIX}_VERSION_MAJOR}.${_${_PYTHON_PREFIX}_VERSION_MINOR}" VERSION_EQUAL "${${_PYTHON_PREFIX}_VERSION_MAJOR}.${${_PYTHON_PREFIX}_VERSION_MINOR}"
- AND "${_${_PYTHON_PREFIX}_INC_VERSION_MAJOR}.${_${_PYTHON_PREFIX}_INC_VERSION_MINOR}" VERSION_EQUAL "${_${_PYTHON_PREFIX}_VERSION_MAJOR}.${_${_PYTHON_PREFIX}_VERSION_MINOR}")
- _python_set_development_module_found (Module)
- _python_set_development_module_found (Embed)
- endif()
- elseif (${_PYTHON_PREFIX}_VERSION_MAJOR VERSION_EQUAL _${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR
- AND "${_${_PYTHON_PREFIX}_INC_VERSION_MAJOR}.${_${_PYTHON_PREFIX}_INC_VERSION_MINOR}" VERSION_EQUAL "${_${_PYTHON_PREFIX}_VERSION_MAJOR}.${_${_PYTHON_PREFIX}_VERSION_MINOR}")
- _python_set_development_module_found (Module)
- _python_set_development_module_found (Embed)
- endif()
- if (DEFINED _${_PYTHON_PREFIX}_FIND_ABI AND
- (NOT _${_PYTHON_PREFIX}_ABI IN_LIST _${_PYTHON_PREFIX}_ABIFLAGS
- OR NOT _${_PYTHON_PREFIX}_INC_ABI IN_LIST _${_PYTHON_PREFIX}_ABIFLAGS))
- set (${_PYTHON_PREFIX}_Development.Module_FOUND FALSE)
- set (${_PYTHON_PREFIX}_Development.Embed_FOUND FALSE)
- endif()
- endif()
-
- if ("Development" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS
- AND ${_PYTHON_PREFIX}_Development.Module_FOUND
- AND ${_PYTHON_PREFIX}_Development.Embed_FOUND)
- set (${_PYTHON_PREFIX}_Development_FOUND TRUE)
- endif()
-
- if (_${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR VERSION_GREATER_EQUAL "3"
- AND NOT DEFINED ${_PYTHON_PREFIX}_SOABI)
- _python_get_config_var (${_PYTHON_PREFIX}_SOABI SOABI)
- endif()
-
- _python_compute_development_signature (Module)
- _python_compute_development_signature (Embed)
-
- # Restore the original find library ordering
- if (DEFINED _${_PYTHON_PREFIX}_CMAKE_FIND_LIBRARY_SUFFIXES)
- set (CMAKE_FIND_LIBRARY_SUFFIXES ${_${_PYTHON_PREFIX}_CMAKE_FIND_LIBRARY_SUFFIXES})
- endif()
-
- if (${_PYTHON_PREFIX}_ARTIFACTS_INTERACTIVE)
- if ("LIBRARY" IN_LIST _${_PYTHON_PREFIX}_FIND_DEVELOPMENT_ARTIFACTS)
- set (${_PYTHON_PREFIX}_LIBRARY "${_${_PYTHON_PREFIX}_LIBRARY_RELEASE}" CACHE FILEPATH "${_PYTHON_PREFIX} Library")
- endif()
- if ("INCLUDE_DIR" IN_LIST _${_PYTHON_PREFIX}_FIND_DEVELOPMENT_ARTIFACTS)
- set (${_PYTHON_PREFIX}_INCLUDE_DIR "${_${_PYTHON_PREFIX}_INCLUDE_DIR}" CACHE FILEPATH "${_PYTHON_PREFIX} Include Directory")
- endif()
- endif()
-
- _python_mark_as_internal (_${_PYTHON_PREFIX}_LIBRARY_RELEASE
- _${_PYTHON_PREFIX}_LIBRARY_DEBUG
- _${_PYTHON_PREFIX}_RUNTIME_LIBRARY_RELEASE
- _${_PYTHON_PREFIX}_RUNTIME_LIBRARY_DEBUG
- _${_PYTHON_PREFIX}_INCLUDE_DIR
- _${_PYTHON_PREFIX}_CONFIG
- _${_PYTHON_PREFIX}_DEVELOPMENT_MODULE_SIGNATURE
- _${_PYTHON_PREFIX}_DEVELOPMENT_EMBED_SIGNATURE)
-endif()
-
-if ("NumPy" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS AND ${_PYTHON_PREFIX}_Interpreter_FOUND)
- list (APPEND _${_PYTHON_PREFIX}_CACHED_VARS _${_PYTHON_PREFIX}_NumPy_INCLUDE_DIR)
- if (${_PYTHON_PREFIX}_FIND_REQUIRED_NumPy)
- list (APPEND _${_PYTHON_PREFIX}_REQUIRED_VARS ${_PYTHON_PREFIX}_NumPy_INCLUDE_DIRS)
- endif()
-
- if (DEFINED ${_PYTHON_PREFIX}_NumPy_INCLUDE_DIR
- AND IS_ABSOLUTE "${${_PYTHON_PREFIX}_NumPy_INCLUDE_DIR}")
- set (_${_PYTHON_PREFIX}_NumPy_INCLUDE_DIR "${${_PYTHON_PREFIX}_NumPy_INCLUDE_DIR}" CACHE INTERNAL "")
- elseif (DEFINED _${_PYTHON_PREFIX}_NumPy_INCLUDE_DIR)
- # compute numpy signature. Depends on interpreter and development signatures
- string (MD5 __${_PYTHON_PREFIX}_NUMPY_SIGNATURE "${_${_PYTHON_PREFIX}_INTERPRETER_SIGNATURE}:${_${_PYTHON_PREFIX}_DEVELOPMENT_MODULE_SIGNATURE}:${_${_PYTHON_PREFIX}_NumPy_INCLUDE_DIR}")
- if (NOT __${_PYTHON_PREFIX}_NUMPY_SIGNATURE STREQUAL _${_PYTHON_PREFIX}_NUMPY_SIGNATURE
- OR NOT EXISTS "${_${_PYTHON_PREFIX}_NumPy_INCLUDE_DIR}")
- unset (_${_PYTHON_PREFIX}_NumPy_INCLUDE_DIR CACHE)
- unset (_${_PYTHON_PREFIX}_NUMPY_SIGNATURE CACHE)
- endif()
- endif()
-
- if (NOT _${_PYTHON_PREFIX}_NumPy_INCLUDE_DIR)
- execute_process(
- COMMAND "${${_PYTHON_PREFIX}_EXECUTABLE}" -c
- "from __future__ import print_function\ntry: import numpy; print(numpy.get_include(), end='')\nexcept:pass\n"
- RESULT_VARIABLE _${_PYTHON_PREFIX}_RESULT
- OUTPUT_VARIABLE _${_PYTHON_PREFIX}_NumPy_PATH
- ERROR_QUIET
- OUTPUT_STRIP_TRAILING_WHITESPACE)
-
- if (NOT _${_PYTHON_PREFIX}_RESULT)
- find_path (_${_PYTHON_PREFIX}_NumPy_INCLUDE_DIR
- NAMES "numpy/arrayobject.h" "numpy/numpyconfig.h"
- HINTS "${_${_PYTHON_PREFIX}_NumPy_PATH}"
- NO_DEFAULT_PATH)
- endif()
- endif()
-
- set (${_PYTHON_PREFIX}_NumPy_INCLUDE_DIRS "${_${_PYTHON_PREFIX}_NumPy_INCLUDE_DIR}")
-
- if(_${_PYTHON_PREFIX}_NumPy_INCLUDE_DIR AND NOT EXISTS "${_${_PYTHON_PREFIX}_NumPy_INCLUDE_DIR}")
- set (_${_PYTHON_PREFIX}_NumPy_REASON_FAILURE "Cannot find the directory \"${_${_PYTHON_PREFIX}_NumPy_INCLUDE_DIR}\"")
- set_property (CACHE _${_PYTHON_PREFIX}_NumPy_INCLUDE_DIR PROPERTY VALUE "${_PYTHON_PREFIX}_NumPy_INCLUDE_DIR-NOTFOUND")
- endif()
-
- if (_${_PYTHON_PREFIX}_NumPy_INCLUDE_DIR)
- execute_process (
- COMMAND "${${_PYTHON_PREFIX}_EXECUTABLE}" -c
- "from __future__ import print_function\ntry: import numpy; print(numpy.__version__, end='')\nexcept:pass\n"
- RESULT_VARIABLE _${_PYTHON_PREFIX}_RESULT
- OUTPUT_VARIABLE _${_PYTHON_PREFIX}_NumPy_VERSION)
- if (NOT _${_PYTHON_PREFIX}_RESULT)
- set (${_PYTHON_PREFIX}_NumPy_VERSION "${_${_PYTHON_PREFIX}_NumPy_VERSION}")
- else()
- unset (${_PYTHON_PREFIX}_NumPy_VERSION)
- endif()
-
- # final step: set NumPy founded only if Development.Module component is founded as well
- set(${_PYTHON_PREFIX}_NumPy_FOUND ${${_PYTHON_PREFIX}_Development.Module_FOUND})
- else()
- set (${_PYTHON_PREFIX}_NumPy_FOUND FALSE)
- endif()
-
- if (${_PYTHON_PREFIX}_NumPy_FOUND)
- # compute and save numpy signature
- string (MD5 __${_PYTHON_PREFIX}_NUMPY_SIGNATURE "${_${_PYTHON_PREFIX}_INTERPRETER_SIGNATURE}:${_${_PYTHON_PREFIX}_DEVELOPMENT_MODULE_SIGNATURE}:${${_PYTHON_PREFIX}_NumPyINCLUDE_DIR}")
- set (_${_PYTHON_PREFIX}_NUMPY_SIGNATURE "${__${_PYTHON_PREFIX}_NUMPY_SIGNATURE}" CACHE INTERNAL "")
- else()
- unset (_${_PYTHON_PREFIX}_NUMPY_SIGNATURE CACHE)
- endif()
-
- if (${_PYTHON_PREFIX}_ARTIFACTS_INTERACTIVE)
- set (${_PYTHON_PREFIX}_NumPy_INCLUDE_DIR "${_${_PYTHON_PREFIX}_NumPy_INCLUDE_DIR}" CACHE FILEPATH "${_PYTHON_PREFIX} NumPy Include Directory")
- endif()
-
- _python_mark_as_internal (_${_PYTHON_PREFIX}_NumPy_INCLUDE_DIR
- _${_PYTHON_PREFIX}_NUMPY_SIGNATURE)
-endif()
-
-# final validation
-if (${_PYTHON_PREFIX}_VERSION_MAJOR AND
- NOT ${_PYTHON_PREFIX}_VERSION_MAJOR VERSION_EQUAL _${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR)
- _python_display_failure ("Could NOT find ${_PYTHON_PREFIX}: Found unsuitable major version \"${${_PYTHON_PREFIX}_VERSION_MAJOR}\", but required major version is exact version \"${_${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR}\"")
-endif()
-
-unset (_${_PYTHON_PREFIX}_REASON_FAILURE)
-foreach (_${_PYTHON_PREFIX}_COMPONENT IN ITEMS Interpreter Compiler Development NumPy)
- if (_${_PYTHON_PREFIX}_${_${_PYTHON_PREFIX}_COMPONENT}_REASON_FAILURE)
- string (APPEND _${_PYTHON_PREFIX}_REASON_FAILURE "\n ${_${_PYTHON_PREFIX}_COMPONENT}: ${_${_PYTHON_PREFIX}_${_${_PYTHON_PREFIX}_COMPONENT}_REASON_FAILURE}")
- endif()
-endforeach()
-
-include (${CMAKE_CURRENT_LIST_DIR}/../FindPackageHandleStandardArgs.cmake)
-find_package_handle_standard_args (${_PYTHON_PREFIX}
- REQUIRED_VARS ${_${_PYTHON_PREFIX}_REQUIRED_VARS}
- VERSION_VAR ${_PYTHON_PREFIX}_VERSION
- HANDLE_COMPONENTS
- REASON_FAILURE_MESSAGE "${_${_PYTHON_PREFIX}_REASON_FAILURE}")
-
-# Create imported targets and helper functions
-if(_${_PYTHON_PREFIX}_CMAKE_ROLE STREQUAL "PROJECT")
- if ("Interpreter" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS
- AND ${_PYTHON_PREFIX}_Interpreter_FOUND
- AND NOT TARGET ${_PYTHON_PREFIX}::Interpreter)
- add_executable (${_PYTHON_PREFIX}::Interpreter IMPORTED)
- set_property (TARGET ${_PYTHON_PREFIX}::Interpreter
- PROPERTY IMPORTED_LOCATION "${${_PYTHON_PREFIX}_EXECUTABLE}")
- endif()
-
- if ("Compiler" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS
- AND ${_PYTHON_PREFIX}_Compiler_FOUND
- AND NOT TARGET ${_PYTHON_PREFIX}::Compiler)
- add_executable (${_PYTHON_PREFIX}::Compiler IMPORTED)
- set_property (TARGET ${_PYTHON_PREFIX}::Compiler
- PROPERTY IMPORTED_LOCATION "${${_PYTHON_PREFIX}_COMPILER}")
- endif()
-
- if (("Development.Module" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS
- AND ${_PYTHON_PREFIX}_Development.Module_FOUND)
- OR ("Development.Embed" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS
- AND ${_PYTHON_PREFIX}_Development.Embed_FOUND))
-
- macro (__PYTHON_IMPORT_LIBRARY __name)
- if (${_PYTHON_PREFIX}_LIBRARY_RELEASE MATCHES "${CMAKE_SHARED_LIBRARY_SUFFIX}$"
- OR ${_PYTHON_PREFIX}_RUNTIME_LIBRARY_RELEASE)
- set (_${_PYTHON_PREFIX}_LIBRARY_TYPE SHARED)
- else()
- set (_${_PYTHON_PREFIX}_LIBRARY_TYPE STATIC)
- endif()
-
- if (NOT TARGET ${__name})
- add_library (${__name} ${_${_PYTHON_PREFIX}_LIBRARY_TYPE} IMPORTED)
- endif()
-
- set_property (TARGET ${__name}
- PROPERTY INTERFACE_INCLUDE_DIRECTORIES "${${_PYTHON_PREFIX}_INCLUDE_DIRS}")
-
- if (${_PYTHON_PREFIX}_LIBRARY_RELEASE AND ${_PYTHON_PREFIX}_RUNTIME_LIBRARY_RELEASE)
- # System manage shared libraries in two parts: import and runtime
- if (${_PYTHON_PREFIX}_LIBRARY_RELEASE AND ${_PYTHON_PREFIX}_LIBRARY_DEBUG)
- set_property (TARGET ${__name} PROPERTY IMPORTED_CONFIGURATIONS RELEASE DEBUG)
- set_target_properties (${__name}
- PROPERTIES IMPORTED_LINK_INTERFACE_LANGUAGES_RELEASE "C"
- IMPORTED_IMPLIB_RELEASE "${${_PYTHON_PREFIX}_LIBRARY_RELEASE}"
- IMPORTED_LOCATION_RELEASE "${${_PYTHON_PREFIX}_RUNTIME_LIBRARY_RELEASE}")
- set_target_properties (${__name}
- PROPERTIES IMPORTED_LINK_INTERFACE_LANGUAGES_DEBUG "C"
- IMPORTED_IMPLIB_DEBUG "${${_PYTHON_PREFIX}_LIBRARY_DEBUG}"
- IMPORTED_LOCATION_DEBUG "${${_PYTHON_PREFIX}_RUNTIME_LIBRARY_DEBUG}")
- else()
- set_target_properties (${__name}
- PROPERTIES IMPORTED_LINK_INTERFACE_LANGUAGES "C"
- IMPORTED_IMPLIB "${${_PYTHON_PREFIX}_LIBRARIES}"
- IMPORTED_LOCATION "${${_PYTHON_PREFIX}_RUNTIME_LIBRARY_RELEASE}")
- endif()
- else()
- if (${_PYTHON_PREFIX}_LIBRARY_RELEASE AND ${_PYTHON_PREFIX}_LIBRARY_DEBUG)
- set_property (TARGET ${__name} PROPERTY IMPORTED_CONFIGURATIONS RELEASE DEBUG)
- set_target_properties (${__name}
- PROPERTIES IMPORTED_LINK_INTERFACE_LANGUAGES_RELEASE "C"
- IMPORTED_LOCATION_RELEASE "${${_PYTHON_PREFIX}_LIBRARY_RELEASE}")
- set_target_properties (${__name}
- PROPERTIES IMPORTED_LINK_INTERFACE_LANGUAGES_DEBUG "C"
- IMPORTED_LOCATION_DEBUG "${${_PYTHON_PREFIX}_LIBRARY_DEBUG}")
- else()
- set_target_properties (${__name}
- PROPERTIES IMPORTED_LINK_INTERFACE_LANGUAGES "C"
- IMPORTED_LOCATION "${${_PYTHON_PREFIX}_LIBRARY_RELEASE}")
- endif()
- endif()
-
- if (_${_PYTHON_PREFIX}_LIBRARY_TYPE STREQUAL "STATIC")
- # extend link information with dependent libraries
- _python_get_config_var (_${_PYTHON_PREFIX}_LINK_LIBRARIES LIBS)
- if (_${_PYTHON_PREFIX}_LINK_LIBRARIES)
- set_property (TARGET ${__name}
- PROPERTY INTERFACE_LINK_LIBRARIES ${_${_PYTHON_PREFIX}_LINK_LIBRARIES})
- endif()
- endif()
- endmacro()
-
- if (${_PYTHON_PREFIX}_Development.Embed_FOUND)
- __python_import_library (${_PYTHON_PREFIX}::Python)
- endif()
-
- if (${_PYTHON_PREFIX}_Development.Module_FOUND)
- if ("LIBRARY" IN_LIST _${_PYTHON_PREFIX}_FIND_DEVELOPMENT_MODULE_ARTIFACTS)
- # On Windows/CYGWIN/MSYS, Python::Module is the same as Python::Python
- # but ALIAS cannot be used because the imported library is not GLOBAL.
- __python_import_library (${_PYTHON_PREFIX}::Module)
- else()
- if (NOT TARGET ${_PYTHON_PREFIX}::Module)
- add_library (${_PYTHON_PREFIX}::Module INTERFACE IMPORTED)
- endif()
- set_property (TARGET ${_PYTHON_PREFIX}::Module
- PROPERTY INTERFACE_INCLUDE_DIRECTORIES "${${_PYTHON_PREFIX}_INCLUDE_DIRS}")
-
- # When available, enforce shared library generation with undefined symbols
- if (APPLE)
- set_property (TARGET ${_PYTHON_PREFIX}::Module
- PROPERTY INTERFACE_LINK_OPTIONS "LINKER:-undefined,dynamic_lookup")
- endif()
- if (CMAKE_SYSTEM_NAME STREQUAL "SunOS")
- set_property (TARGET ${_PYTHON_PREFIX}::Module
- PROPERTY INTERFACE_LINK_OPTIONS "LINKER:-z,nodefs")
- endif()
- if (CMAKE_SYSTEM_NAME STREQUAL "AIX")
- set_property (TARGET ${_PYTHON_PREFIX}::Module
- PROPERTY INTERFACE_LINK_OPTIONS "LINKER:-b,erok")
- endif()
- endif()
- endif()
-
- #
- # PYTHON_ADD_LIBRARY ( [STATIC|SHARED|MODULE] src1 src2 ... srcN)
- # It is used to build modules for python.
- #
- function (__${_PYTHON_PREFIX}_ADD_LIBRARY prefix name)
- cmake_parse_arguments (PARSE_ARGV 2 PYTHON_ADD_LIBRARY
- "STATIC;SHARED;MODULE;WITH_SOABI" "" "")
-
- if (prefix STREQUAL "Python2" AND PYTHON_ADD_LIBRARY_WITH_SOABI)
- message (AUTHOR_WARNING "FindPython2: Option `WITH_SOABI` is not supported for Python2 and will be ignored.")
- unset (PYTHON_ADD_LIBRARY_WITH_SOABI)
- endif()
-
- if (PYTHON_ADD_LIBRARY_STATIC)
- set (type STATIC)
- elseif (PYTHON_ADD_LIBRARY_SHARED)
- set (type SHARED)
- else()
- set (type MODULE)
- endif()
-
- if (type STREQUAL "MODULE" AND NOT TARGET ${prefix}::Module)
- message (SEND_ERROR "${prefix}_ADD_LIBRARY: dependent target '${prefix}::Module' is not defined.\n Did you miss to request COMPONENT 'Development.Module'?")
- return()
- endif()
- if (NOT type STREQUAL "MODULE" AND NOT TARGET ${prefix}::Python)
- message (SEND_ERROR "${prefix}_ADD_LIBRARY: dependent target '${prefix}::Python' is not defined.\n Did you miss to request COMPONENT 'Development.Embed'?")
- return()
- endif()
-
- add_library (${name} ${type} ${PYTHON_ADD_LIBRARY_UNPARSED_ARGUMENTS})
-
- get_property (type TARGET ${name} PROPERTY TYPE)
-
- if (type STREQUAL "MODULE_LIBRARY")
- target_link_libraries (${name} PRIVATE ${prefix}::Module)
- # customize library name to follow module name rules
- set_property (TARGET ${name} PROPERTY PREFIX "")
- if(CMAKE_SYSTEM_NAME STREQUAL "Windows")
- set_property (TARGET ${name} PROPERTY SUFFIX ".pyd")
- endif()
-
- if (PYTHON_ADD_LIBRARY_WITH_SOABI AND ${prefix}_SOABI)
- get_property (suffix TARGET ${name} PROPERTY SUFFIX)
- if (NOT suffix)
- set (suffix "${CMAKE_SHARED_MODULE_SUFFIX}")
- endif()
- set_property (TARGET ${name} PROPERTY SUFFIX ".${${prefix}_SOABI}${suffix}")
- endif()
- else()
- if (PYTHON_ADD_LIBRARY_WITH_SOABI)
- message (AUTHOR_WARNING "Find${prefix}: Option `WITH_SOABI` is only supported for `MODULE` library type.")
- endif()
- target_link_libraries (${name} PRIVATE ${prefix}::Python)
- endif()
- endfunction()
- endif()
-
- if ("NumPy" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS AND ${_PYTHON_PREFIX}_NumPy_FOUND
- AND NOT TARGET ${_PYTHON_PREFIX}::NumPy AND TARGET ${_PYTHON_PREFIX}::Module)
- add_library (${_PYTHON_PREFIX}::NumPy INTERFACE IMPORTED)
- set_property (TARGET ${_PYTHON_PREFIX}::NumPy
- PROPERTY INTERFACE_INCLUDE_DIRECTORIES "${${_PYTHON_PREFIX}_NumPy_INCLUDE_DIRS}")
- target_link_libraries (${_PYTHON_PREFIX}::NumPy INTERFACE ${_PYTHON_PREFIX}::Module)
- endif()
-endif()
-
-# final clean-up
-
-# Restore CMAKE_FIND_APPBUNDLE
-if (DEFINED _${_PYTHON_PREFIX}_CMAKE_FIND_APPBUNDLE)
- set (CMAKE_FIND_APPBUNDLE ${_${_PYTHON_PREFIX}_CMAKE_FIND_APPBUNDLE})
- unset (_${_PYTHON_PREFIX}_CMAKE_FIND_APPBUNDLE)
-else()
- unset (CMAKE_FIND_APPBUNDLE)
-endif()
-# Restore CMAKE_FIND_FRAMEWORK
-if (DEFINED _${_PYTHON_PREFIX}_CMAKE_FIND_FRAMEWORK)
- set (CMAKE_FIND_FRAMEWORK ${_${_PYTHON_PREFIX}_CMAKE_FIND_FRAMEWORK})
- unset (_${_PYTHON_PREFIX}_CMAKE_FIND_FRAMEWORK)
-else()
- unset (CMAKE_FIND_FRAMEWORK)
-endif()
diff --git a/scripts/internal/libpython-not-needed-symbols-exported-by-interpreter b/scripts/internal/libpython-not-needed-symbols-exported-by-interpreter
deleted file mode 100644
index e69de29b..00000000
diff --git a/scripts/internal/manylinux-aarch64-build-module-wheels.sh b/scripts/internal/manylinux-aarch64-build-module-wheels.sh
deleted file mode 100755
index f43a7f87..00000000
--- a/scripts/internal/manylinux-aarch64-build-module-wheels.sh
+++ /dev/null
@@ -1,15 +0,0 @@
-#!/usr/bin/env bash
-
-# Run this script inside a dockcross container to build Python wheels for an aarch ITK module.
-cd /work
-# Update GPG keys
-dnf upgrade -y almalinux-release
-# Newer Python.cmake module required for SABI
-pipx upgrade cmake
-yum -y install sudo ninja-build
-/opt/python/cp310-cp310/bin/python -m pip install -r /ITKPythonPackage/requirements-dev.txt
-for PYBIN in "${PYBINARIES[@]}"; do
- ${PYBIN}/pip install -r /ITKPythonPackage/requirements-dev.txt
-done
-
-"/ITKPythonPackage/scripts/internal/manylinux-build-module-wheels.sh" "$@"
diff --git a/scripts/internal/manylinux-build-common.sh b/scripts/internal/manylinux-build-common.sh
deleted file mode 100644
index 6443b4c0..00000000
--- a/scripts/internal/manylinux-build-common.sh
+++ /dev/null
@@ -1,85 +0,0 @@
-# Content common to manylinux-build-wheels.sh and
-# manylinux-build-module-wheels.sh
-
-set -e -x
-
-script_dir=$(cd $(dirname $0) || exit 1; pwd)
-
-# Versions can be restricted by passing them in as arguments to the script
-# For example,
-# manylinux-build-wheels.sh cp310
-if [[ $# -eq 0 ]]; then
- PYBIN=(/opt/python/*/bin)
- PYBINARIES=()
- for version in "${PYBIN[@]}"; do
- if [[ ${version} == *"cp310"* || ${version} == *"cp311"* ]]; then
- PYBINARIES+=(${version})
- fi
- done
-else
- PYBINARIES=()
- for version in "$@"; do
- PYBINARIES+=(/opt/python/*${version}*/bin)
- done
-fi
-
-# i686 or x86_64 ?
-case $(uname -m) in
- i686)
- ARCH=x86
- ;;
- x86_64)
- ARCH=x64
- ;;
- aarch64)
- ARCH=aarch64
- ;;
- *)
- die "Unknown architecture $(uname -m)"
- ;;
-esac
-
-# Install prerequirements
-export PATH=/work/tools/doxygen-1.8.16/bin:$PATH
-case $(uname -m) in
- i686)
- ARCH=x86
- ;;
- x86_64)
- if ! type doxygen > /dev/null 2>&1; then
- mkdir -p /work/tools
- pushd /work/tools > /dev/null 2>&1
- curl https://data.kitware.com/api/v1/file/62c4d615bddec9d0c46cb705/download -o doxygen-1.8.16.linux.bin.tar.gz
- tar -xvzf doxygen-1.8.16.linux.bin.tar.gz
- popd > /dev/null 2>&1
- fi
- ;;
- aarch64)
- ARCH=aarch64
- if ! type doxygen > /dev/null 2>&1; then
- mkdir -p /work/tools
- pushd /work/tools > /dev/null 2>&1
- curl https://data.kitware.com/api/v1/file/62c4ed58bddec9d0c46f1388/download -o doxygen-1.8.16.linux.aarch64.bin.tar.gz
- tar -xvzf doxygen-1.8.16.linux.aarch64.bin.tar.gz
- popd > /dev/null 2>&1
- fi
- ;;
- *)
- die "Unknown architecture $(uname -m)"
- ;;
-esac
-if ! type ninja > /dev/null 2>&1; then
- if test ! -d ninja; then
- git clone https://github.com/ninja-build/ninja.git
- fi
- pushd ninja
- git checkout release
- cmake -Bbuild-cmake -H.
- cmake --build build-cmake
- cp build-cmake/ninja /usr/local/bin/
- popd
-fi
-
-MANYLINUX_VERSION=${MANYLINUX_VERSION:=_2_28}
-
-echo "Building wheels for $ARCH using manylinux${MANYLINUX_VERSION}"
diff --git a/scripts/internal/manylinux-build-module-wheels.sh b/scripts/internal/manylinux-build-module-wheels.sh
deleted file mode 100755
index 37ab0382..00000000
--- a/scripts/internal/manylinux-build-module-wheels.sh
+++ /dev/null
@@ -1,144 +0,0 @@
-#!/usr/bin/env bash
-
-# Run this script inside a dockcross container to build Python wheels for an ITK module.
-#
-# Versions can be restricted by passing them in as arguments to the script.
-# For example,
-#
-# /tmp/dockcross-manylinux-x64 manylinux-build-module-wheels.sh cp310
-#
-# Shared library dependencies can be included in the wheel by mounting them to /usr/lib64 or /usr/local/lib64
-# before running this script.
-#
-# For example,
-#
-# DOCKER_ARGS="-v /path/to/lib.so:/usr/local/lib64/lib.so"
-# /tmp/dockcross-manylinux-x64 -a "$DOCKER_ARGS" manylinux-build-module-wheels.sh
-#
-# The specialized manylinux container version should be set prior to running this script.
-# See https://github.com/dockcross/dockcross for available versions and tags.
-#
-# For example, `docker run -e ` can be used to set an environment variable when launching a container:
-#
-# export MANYLINUX_VERSION=2014
-# docker run --rm dockcross/manylinux${MANYLINUX_VERSION}-x64:${IMAGE_TAG} > /tmp/dockcross-manylinux-x64
-# chmod u+x /tmp/dockcross-manylinux-x64
-# /tmp/dockcross-manylinux-x64 -e MANYLINUX_VERSION manylinux-build-module-wheels.sh cp310
-#
-
-# -----------------------------------------------------------------------
-# Script argument parsing
-#
-usage()
-{
- echo "Usage:
- manylinux-build-module-wheels
- [ -h | --help ] show usage
- [ -c | --cmake_options ] space-separated string of CMake options to forward to the module (e.g. \"--config-setting=cmake.define.BUILD_TESTING=OFF\")
- [ -x | --exclude_libs ] semicolon-separated library names to exclude when repairing wheel (e.g. \"libcuda.so\")
- [ python_version ] build wheel for a specific python version. (e.g. cp310)"
- exit 2
-}
-
-PARSED_ARGS=$(getopt -a -n dockcross-manylinux-download-cache-and-build-module-wheels \
- -o hc:x: --long help,cmake_options:,exclude_libs: -- "$@")
-eval set -- "$PARSED_ARGS"
-
-while :
-do
- case "$1" in
- -h | --help) usage; break ;;
- -c | --cmake_options) CMAKE_OPTIONS="$2" ; shift 2 ;;
- -x | --exclude_libs) EXCLUDE_LIBS="$2" ; shift 2 ;;
- --) shift; break ;;
- *) echo "Unexpected option: $1.";
- usage; break ;;
- esac
-done
-
-PYTHON_VERSION="$@"
-# -----------------------------------------------------------------------
-
-# -----------------------------------------------------------------------
-# These variables are set in common script:
-#
-ARCH=""
-PYBINARIES=""
-
-script_dir=$(cd $(dirname $0) || exit 1; pwd)
-source "${script_dir}/manylinux-build-common.sh"
-# -----------------------------------------------------------------------
-
-# Set up library paths in container so that shared libraries can be added to wheels
-sudo ldconfig
-export LD_LIBRARY_PATH=${LD_LIBRARY_PATH}:/work/oneTBB-prefix/lib:/usr/lib:/usr/lib64:/usr/local/lib:/usr/local/lib64
-
-# Compile wheels re-using standalone project and archive cache
-for PYBIN in "${PYBINARIES[@]}"; do
- Python3_EXECUTABLE=${PYBIN}/python
- Python3_INCLUDE_DIR=$( find -L ${PYBIN}/../include/ -name Python.h -exec dirname {} \; )
-
- echo ""
- echo "Python3_EXECUTABLE:${Python3_EXECUTABLE}"
- echo "Python3_INCLUDE_DIR:${Python3_INCLUDE_DIR}"
-
- if [[ -e /work/requirements-dev.txt ]]; then
- sudo ${PYBIN}/pip install --upgrade -r /work/requirements-dev.txt
- fi
- if [[ -e /ITKPythonPackage/requirements-dev.txt ]]; then
- sudo ${PYBIN}/pip install --upgrade -r /ITKPythonPackage/requirements-dev.txt
- fi
- version=$(basename $(dirname ${PYBIN}))
- # Remove "m" -- not present in Python 3.8 and later
- version=${version:0:9}
- itk_build_dir=/work/$(basename /ITKPythonPackage/ITK-${version}*-manylinux${MANYLINUX_VERSION}_${ARCH})
- ln -fs /ITKPythonPackage/ITK-${version}*-manylinux${MANYLINUX_VERSION}_${ARCH} $itk_build_dir
- if [[ ! -d ${itk_build_dir} ]]; then
- echo 'ITK build tree not available!' 1>&2
- exit 1
- fi
- itk_source_dir=/work/ITK-source/ITK
- ln -fs /ITKPythonPackage/ITK-source/ /work/ITK-source
- if [[ ! -d ${itk_source_dir} ]]; then
- echo 'ITK source tree not available!' 1>&2
- exit 1
- fi
- py_minor=$(echo $version | cut -d '-' -f 1 | cut -d '3' -f 2)
- wheel_py_api=""
- if test $py_minor -ge 11; then
- wheel_py_api=cp3$py_minor
- fi
- ${PYBIN}/python -m build \
- --verbose \
- --wheel \
- --outdir dist \
- --no-isolation \
- --skip-dependency-check \
- --config-setting=cmake.define.ITK_DIR:PATH=${itk_build_dir} \
- --config-setting=cmake.define.WRAP_ITK_INSTALL_COMPONENT_IDENTIFIER:STRING=PythonWheel \
- --config-setting=cmake.define.CMAKE_CXX_COMPILER_TARGET:STRING=$(uname -m)-linux-gnu \
- --config-setting=cmake.define.CMAKE_INSTALL_LIBDIR:STRING=lib \
- --config-setting=cmake.define.PY_SITE_PACKAGES_PATH:PATH="." \
- --config-setting=wheel.py-api=$wheel_py_api \
- --config-setting=cmake.define.BUILD_TESTING:BOOL=OFF \
- --config-setting=cmake.define.Python3_EXECUTABLE:FILEPATH=${Python3_EXECUTABLE} \
- --config-setting=cmake.define.Python3_INCLUDE_DIR:PATH=${Python3_INCLUDE_DIR} \
- ${CMAKE_OPTIONS//'-D'/'--config-setting=cmake.define.'} \
- || exit 1
-done
-
-# Convert list of excluded libs in --exclude_libs to auditwheel --exclude options
-if test -n "$EXCLUDE_LIBS"; then
- AUDITWHEEL_EXCLUDE_ARGS="--exclude ${EXCLUDE_LIBS//;/ --exclude }"
-fi
-
-sudo ${Python3_EXECUTABLE} -m pip install auditwheel
-for whl in dist/*linux*$(uname -m).whl; do
- auditwheel repair ${whl} -w /work/dist/ ${AUDITWHEEL_EXCLUDE_ARGS}
-done
-
-if compgen -G "dist/itk*-linux*.whl" > /dev/null; then
- for itk_wheel in dist/itk*-linux*.whl; do
- rm ${itk_wheel}
- done
-fi
diff --git a/scripts/internal/manylinux-build-wheels.sh b/scripts/internal/manylinux-build-wheels.sh
deleted file mode 100755
index 2ebacbec..00000000
--- a/scripts/internal/manylinux-build-wheels.sh
+++ /dev/null
@@ -1,215 +0,0 @@
-#!/usr/bin/env bash
-
-# Run this script inside a dockcross container to build Python wheels for ITK.
-#
-# Versions can be restricted by passing them in as arguments to the script.
-# For example,
-#
-# /tmp/dockcross-manylinux-x64 manylinux-build-wheels.sh cp310
-#
-# Shared library dependencies can be included wheels by mounting them to /usr/lib64 or /usr/local/lib64
-# before running this script.
-#
-# For example,
-#
-# DOCKER_ARGS="-v /path/to/lib.so:/usr/local/lib64/lib.so"
-# /tmp/dockcross-manylinux-x64 -a "$DOCKER_ARGS" manylinux-build-wheels.sh
-#
-# The specialized manylinux container version should be set prior to running this script.
-# See https://github.com/dockcross/dockcross for available versions and tags.
-#
-# For example, `docker run -e ` can be used to set an environment variable when launching a container:
-#
-# export MANYLINUX_VERSION=2014
-# docker run --rm dockcross/manylinux${MANYLINUX_VERSION}-x64:${IMAGE_TAG} > /tmp/dockcross-manylinux-x64
-# chmod u+x /tmp/dockcross-manylinux-x64
-# /tmp/dockcross-manylinux-x64 -e MANYLINUX_VERSION manylinux-build-module-wheels.sh cp310
-#
-
-# -----------------------------------------------------------------------
-# These variables are set in common script:
-#
-ARCH=""
-PYBINARIES=""
-Python3_LIBRARY=""
-
-script_dir=$(cd $(dirname $0) || exit 1; pwd)
-source "${script_dir}/manylinux-build-common.sh"
-
-# -----------------------------------------------------------------------
-
-# Build standalone project and populate archive cache
-mkdir -p /work/ITK-source
-pushd /work/ITK-source > /dev/null 2>&1
- cmake -DITKPythonPackage_BUILD_PYTHON:PATH=0 -G Ninja ../
- ninja
-popd > /dev/null 2>&1
-tbb_dir=/work/oneTBB-prefix/lib/cmake/TBB
-# So auditwheel can find the libs
-sudo ldconfig
-export LD_LIBRARY_PATH=${LD_LIBRARY_PATH}:/work/oneTBB-prefix/lib:/usr/lib:/usr/lib64
-
-# TODO: More work is required to re-enable this feature.
-SINGLE_WHEEL=0
-
-# Compile wheels re-using standalone project and archive cache
-for PYBIN in "${PYBINARIES[@]}"; do
- export Python3_EXECUTABLE=${PYBIN}/python3
- Python3_INCLUDE_DIR=$( find -L ${PYBIN}/../include/ -name Python.h -exec dirname {} \; )
-
- echo ""
- echo "Python3_EXECUTABLE:${Python3_EXECUTABLE}"
- echo "Python3_INCLUDE_DIR:${Python3_INCLUDE_DIR}"
-
- # Install dependencies
- sudo ${PYBIN}/pip install --upgrade -r /work/requirements-dev.txt
-
- build_type="Release"
- compile_flags="-O3 -DNDEBUG"
- source_path=/work/ITK-source/ITK
- build_path=/work/ITK-$(basename $(dirname ${PYBIN}))-manylinux${MANYLINUX_VERSION}_${ARCH}
- PYPROJECT_CONFIGURE="${script_dir}/../pyproject_configure.py"
-
- # Clean up previous invocations
- # rm -rf ${build_path}
-
- if [[ ${SINGLE_WHEEL} == 1 ]]; then
-
- echo "#"
- echo "# Build single ITK wheel"
- echo "#"
-
- # Configure pyproject.toml
- ${PYBIN}/python ${PYPROJECT_CONFIGURE} "itk"
- # Generate wheel
- ${PYBIN}/python -m build \
- --verbose \
- --wheel \
- --outdir dist \
- --no-isolation \
- --skip-dependency-check \
- --config-setting=cmake.define.ITK_SOURCE_DIR:PATH=${source_path} \
- --config-setting=cmake.define.ITK_BINARY_DIR:PATH=${build_path} \
- --config-setting=cmake.define.ITKPythonPackage_ITK_BINARY_REUSE:BOOL=OFF \
- --config-setting=cmake.define.ITKPythonPackage_WHEEL_NAME:STRING=itk \
- --config-setting=cmake.define.CMAKE_CXX_COMPILER_TARGET:STRING=$(uname -m)-linux-gnu \
- "--config-setting=cmake.define.CMAKE_CXX_FLAGS:STRING=$compile_flags" \
- "--config-setting=cmake.define.CMAKE_C_FLAGS:STRING=$compile_flags" \
- "--config-setting=cmake.define.CMAKE_BUILD_TYPE:STRING=${build_type}" \
- --config-setting=cmake.define.Python3_EXECUTABLE:FILEPATH=${Python3_EXECUTABLE} \
- --config-setting=cmake.define.Python3_INCLUDE_DIR:PATH=${Python3_INCLUDE_DIR} \
- --config-setting=cmake.define.Module_ITKTBB:BOOL=ON \
- --config-setting=cmake.define.TBB_DIR:PATH=${tbb_dir} \
- .
-
- else
-
- echo "#"
- echo "# Build multiple ITK wheels"
- echo "#"
-
- # Build ITK python
- (
- mkdir -p ${build_path} \
- && cd ${build_path} \
- && cmake \
- -DCMAKE_BUILD_TYPE:STRING=${build_type} \
- -DITK_SOURCE_DIR:PATH=${source_path} \
- -DITK_BINARY_DIR:PATH=${build_path} \
- -DBUILD_TESTING:BOOL=OFF \
- -DPython3_EXECUTABLE:FILEPATH=${Python3_EXECUTABLE} \
- -DPython3_INCLUDE_DIR:PATH=${Python3_INCLUDE_DIR} \
- -DCMAKE_CXX_COMPILER_TARGET:STRING=$(uname -m)-linux-gnu \
- -DCMAKE_CXX_FLAGS:STRING="$compile_flags" \
- -DCMAKE_C_FLAGS:STRING="$compile_flags" \
- -DCMAKE_BUILD_TYPE:STRING="${build_type}" \
- -DWRAP_ITK_INSTALL_COMPONENT_IDENTIFIER:STRING=PythonWheel \
- -DWRAP_ITK_INSTALL_COMPONENT_PER_MODULE:BOOL=ON \
- -DITK_WRAP_unsigned_short:BOOL=ON \
- -DITK_WRAP_double:BOOL=ON \
- -DITK_WRAP_complex_double:BOOL=ON \
- -DITK_WRAP_IMAGE_DIMS:STRING="2;3;4" \
- -DPY_SITE_PACKAGES_PATH:PATH="." \
- -DITK_LEGACY_SILENT:BOOL=ON \
- -DITK_WRAP_PYTHON:BOOL=ON \
- -DITK_WRAP_DOC:BOOL=ON \
- -DModule_ITKTBB:BOOL=ON \
- -DTBB_DIR:PATH=${tbb_dir} \
- -G Ninja \
- ${source_path} \
- && ninja \
- || exit 1
- )
-
- wheel_names=$(cat ${script_dir}/../WHEEL_NAMES.txt)
- for wheel_name in ${wheel_names}; do
- # Configure pyproject.toml
- ${PYBIN}/python ${PYPROJECT_CONFIGURE} ${wheel_name}
- # Generate wheel
- ${PYBIN}/python -m build \
- --verbose \
- --wheel \
- --outdir dist \
- --no-isolation \
- --skip-dependency-check \
- --config-setting=cmake.define.ITK_SOURCE_DIR:PATH=${source_path} \
- --config-setting=cmake.define.ITK_BINARY_DIR:PATH=${build_path} \
- --config-setting=cmake.define.ITKPythonPackage_ITK_BINARY_REUSE:BOOL=ON \
- --config-setting=cmake.define.ITKPythonPackage_WHEEL_NAME:STRING=${wheel_name} \
- --config-setting=cmake.define.Python3_EXECUTABLE:FILEPATH=${Python3_EXECUTABLE} \
- --config-setting=cmake.define.Python3_INCLUDE_DIR:PATH=${Python3_INCLUDE_DIR} \
- --config-setting=cmake.define.CMAKE_CXX_FLAGS:STRING="${compile_flags}" \
- --config-setting=cmake.define.CMAKE_C_FLAGS:STRING="${compile_flags}" \
- . \
- || exit 1
- done
- fi
-
- # Remove unnecessary files for building against ITK
- find ${build_path} -name '*.cpp' -delete -o -name '*.xml' -delete
- rm -rf ${build_path}/Wrapping/Generators/castxml*
- find ${build_path} -name '*.o' -delete
-
-done
-
-sudo /opt/python/cp311-cp311/bin/pip3 install auditwheel wheel
-
-if test "${ARCH}" == "x64"; then
- # This step will fixup the wheel switching from 'linux' to 'manylinux' tag
- for whl in dist/itk_*linux_*.whl; do
- /opt/python/cp311-cp311/bin/auditwheel repair --plat manylinux${MANYLINUX_VERSION}_x86_64 ${whl} -w /work/dist/
- done
-else
- for whl in dist/itk_*$(uname -m).whl; do
- /opt/python/cp311-cp311/bin/auditwheel repair ${whl} -w /work/dist/
- done
-fi
-
-# auditwheel does not process this "metawheel" correctly since it does not
-# have any native SO's.
-mkdir -p metawheel-dist
-for whl in dist/itk-*linux_*.whl; do
- /opt/python/cp311-cp311/bin/wheel unpack --dest metawheel ${whl}
- manylinux_version=manylinux${MANYLINUX_VERSION}
- new_tag=$(basename ${whl/linux/${manylinux_version}} .whl)
- sed -i "s/Tag: .*/Tag: ${new_tag}/" metawheel/itk-*/itk*.dist-info/WHEEL
- /opt/python/cp311-cp311/bin/wheel pack --dest metawheel-dist metawheel/itk-*
- mv metawheel-dist/*.whl dist/${new_tag}.whl
- rm -rf metawheel
-done
-rm -rf metawheel-dist
-rm dist/itk-*-linux_*.whl
-rm dist/itk_*-linux_*.whl
-
-# Install packages and test
-for PYBIN in "${PYBINARIES[@]}"; do
- ${PYBIN}/pip install --user numpy
- sudo ${PYBIN}/pip install --upgrade pip
- ${PYBIN}/pip install itk --user --no-cache-dir --no-index -f /work/dist
- (cd $HOME && ${PYBIN}/python -c 'from itk import ITKCommon;')
- (cd $HOME && ${PYBIN}/python -c 'import itk; image = itk.Image[itk.UC, 2].New()')
- (cd $HOME && ${PYBIN}/python -c 'import itkConfig; itkConfig.LazyLoading = False; import itk;')
- (cd $HOME && ${PYBIN}/python ${script_dir}/../../docs/code/test.py )
-done
-
-rm -f dist/numpy*.whl
diff --git a/scripts/internal/shellcheck-run.sh b/scripts/internal/shellcheck-run.sh
deleted file mode 100755
index e110bb79..00000000
--- a/scripts/internal/shellcheck-run.sh
+++ /dev/null
@@ -1,35 +0,0 @@
-#!/bin/bash
-
-set -e
-set -o pipefail
-
-(
-exit_code=0
-
-#
-# SC1090: Can't follow non-constant source. Use a directive to specify location.
-# SC2006: Use $(..) instead of legacy `..`.
-# SC2046: Quote this to prevent word splitting.
-# SC2086: Double quote to prevent globbing and word splitting.
-# SC2153: Possible misspelling: SCRIPT_DIR may not be assigned, but script_dir is.
-# SC2155: Declare and assign separately to avoid masking return values.
-#
-
-# find all executables and run `shellcheck`
-for f in $(find . -type f -not -iwholename '*.git*' | sort -u); do
- if file "$f" | grep --quiet -e shell -e bash; then
- shellcheck \
- -e SC1090 \
- -e SC2046 \
- -e SC2086 \
- "$f" \
- && echo "[OK]: successfully linted $f" || echo "[FAILED]: found issues linting $f"
- current_exit_code=$?
- if [[ $current_exit_code != 0 ]]; then
- exit_code=$current_exit_code
- fi
- fi
-done
-
-exit $exit_code
-)
diff --git a/scripts/internal/wheel_builder_utils.py b/scripts/internal/wheel_builder_utils.py
deleted file mode 100644
index 422d4f51..00000000
--- a/scripts/internal/wheel_builder_utils.py
+++ /dev/null
@@ -1,95 +0,0 @@
-"""This module provides convenient function facilitating scripting.
-
-These functions have been copied from scikit-build project.
-See https://github.com/scikit-build/scikit-build
-"""
-
-import errno
-import os
-
-from contextlib import contextmanager
-from functools import wraps
-
-
-def mkdir_p(path):
- """Ensure directory ``path`` exists. If needed, parent directories
- are created.
-
- Adapted from http://stackoverflow.com/a/600612/1539918
- """
- try:
- os.makedirs(path)
- except OSError as exc: # Python >2.5
- if exc.errno == errno.EEXIST and os.path.isdir(path):
- pass
- else: # pragma: no cover
- raise
-
-
-@contextmanager
-def push_env(**kwargs):
- """This context manager allow to set/unset environment variables."""
- saved_env = dict(os.environ)
- for var, value in kwargs.items():
- if value is not None:
- os.environ[var] = value
- elif var in os.environ:
- del os.environ[var]
- yield
- os.environ.clear()
- for saved_var, saved_value in saved_env.items():
- os.environ[saved_var] = saved_value
-
-
-class ContextDecorator(object):
- """A base class or mixin that enables context managers to work as
- decorators."""
-
- def __init__(self, **kwargs):
- self.__dict__.update(kwargs)
-
- def __enter__(self):
- # Note: Returning self means that in "with ... as x", x will be self
- return self
-
- def __exit__(self, typ, val, traceback):
- pass
-
- def __call__(self, func):
- @wraps(func)
- def inner(*args, **kwds): # pylint:disable=missing-docstring
- with self:
- return func(*args, **kwds)
-
- return inner
-
-
-class push_dir(ContextDecorator):
- """Context manager to change current directory."""
-
- def __init__(self, directory=None, make_directory=False):
- """
- :param directory:
- Path to set as current working directory. If ``None``
- is passed, ``os.getcwd()`` is used instead.
-
- :param make_directory:
- If True, ``directory`` is created.
- """
- self.directory = None
- self.make_directory = None
- self.old_cwd = None
- super(push_dir, self).__init__(
- directory=directory, make_directory=make_directory
- )
-
- def __enter__(self):
- self.old_cwd = os.getcwd()
- if self.directory:
- if self.make_directory:
- mkdir_p(self.directory)
- os.chdir(self.directory)
- return self
-
- def __exit__(self, typ, val, traceback):
- os.chdir(self.old_cwd)
diff --git a/scripts/internal/windows_build_common.py b/scripts/internal/windows_build_common.py
deleted file mode 100644
index 4cf2c739..00000000
--- a/scripts/internal/windows_build_common.py
+++ /dev/null
@@ -1,60 +0,0 @@
-__all__ = ["DEFAULT_PY_ENVS", "venv_paths"]
-
-from subprocess import check_call
-import os
-import shutil
-
-DEFAULT_PY_ENVS = ["310-x64", "311-x64"]
-
-SCRIPT_DIR = os.path.dirname(__file__)
-ROOT_DIR = os.path.abspath(os.path.join(SCRIPT_DIR, "..", ".."))
-
-
-def venv_paths(python_version):
- # Create venv
- venv_executable = "C:/Python%s/Scripts/virtualenv.exe" % (python_version)
- venv_dir = os.path.join(ROOT_DIR, "venv-%s" % python_version)
- check_call([venv_executable, venv_dir])
-
- python_executable = os.path.join(venv_dir, "Scripts", "python.exe")
- python_include_dir = "C:/Python%s/include" % (python_version)
-
- # XXX It should be possible to query skbuild for the library dir associated
- # with a given interpreter.
- xy_ver = python_version.split("-")[0]
-
- # Version-specific library (e.g., python311.lib) - required for
- # CMake's FindPython3 to extract version info for Development.Module
- python_library = "C:/Python%s/libs/python%s.lib" % (python_version, xy_ver)
-
- # Stable ABI library (python3.lib) - for Development.SABIModule
- if int(xy_ver[1:]) >= 11:
- python_sabi_library = "C:/Python%s/libs/python3.lib" % (python_version)
- else:
- python_sabi_library = python_library
-
- print("")
- print("Python3_EXECUTABLE: %s" % python_executable)
- print("Python3_INCLUDE_DIR: %s" % python_include_dir)
- print("Python3_LIBRARY: %s" % python_library)
- print("Python3_SABI_LIBRARY: %s" % python_sabi_library)
-
- pip = os.path.join(venv_dir, "Scripts", "pip.exe")
-
- ninja_executable = os.path.join(venv_dir, "Scripts", "ninja.exe")
- if not os.path.exists(ninja_executable):
- ninja_executable = shutil.which("ninja.exe")
- print("NINJA_EXECUTABLE:%s" % ninja_executable)
-
- # Update PATH
- path = os.path.join(venv_dir, "Scripts")
-
- return (
- python_executable,
- python_include_dir,
- python_library,
- python_sabi_library,
- pip,
- ninja_executable,
- path,
- )
diff --git a/scripts/lint-shell-scripts.sh b/scripts/lint-shell-scripts.sh
deleted file mode 100755
index 47e10c9a..00000000
--- a/scripts/lint-shell-scripts.sh
+++ /dev/null
@@ -1,20 +0,0 @@
-#!/bin/bash
-
-set -e
-set -o pipefail
-
-SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
-
-pushd $SCRIPT_DIR > /dev/null
-
-docker run --rm -it \
- --name df-shellcheck \
- -v $(pwd):/usr/src:ro \
- --workdir /usr/src \
- r.j3ss.co/shellcheck ./internal/shellcheck-run.sh
-
-exit_code=$?
-
-popd > /dev/null
-
-exit $exit_code
diff --git a/scripts/linux_build_python_instance.py b/scripts/linux_build_python_instance.py
new file mode 100644
index 00000000..4f2ea72e
--- /dev/null
+++ b/scripts/linux_build_python_instance.py
@@ -0,0 +1,278 @@
+import os
+import shutil
+from pathlib import Path
+
+from build_python_instance_base import BuildPythonInstanceBase
+from wheel_builder_utils import (
+ _remove_tree,
+)
+
+
+class LinuxBuildPythonInstance(BuildPythonInstanceBase):
+ """Linux-specific wheel builder.
+
+ Handles manylinux container builds, ``auditwheel`` wheel repair, and
+ Linux-specific compiler/target triple configuration.
+ """
+
+ def prepare_build_env(self) -> None:
+ """Set up the Linux build environment, TBB paths, and compiler targets."""
+ # #############################################
+ # ### Setup build tools
+ self.package_env_config["USE_TBB"] = "ON"
+ self.package_env_config["TBB_DIR"] = (
+ self.build_dir_root / "build" / "oneTBB-prefix" / "lib" / "cmake" / "TBB"
+ )
+
+ # The interpreter is provided; ensure basic tools are available
+ self.venv_paths()
+ self.update_venv_itk_build_configurations()
+ if self.package_env_config["ARCH"] == "x64":
+ target_triple = "x86_64-linux-gnu"
+ elif self.package_env_config["ARCH"] in ("aarch64", "arm64"):
+ target_triple = "aarch64-linux-gnu"
+ elif self.package_env_config["ARCH"] == "x86":
+ target_triple = "i686-linux-gnu"
+ else:
+ target_triple = f"{self.package_env_config['ARCH']}-linux-gnu"
+
+ target_arch = self.package_env_config["ARCH"]
+
+ self.cmake_compiler_configurations.set(
+ "CMAKE_CXX_COMPILER_TARGET:STRING", target_triple
+ )
+
+ # build will be here is downloaded
+ itk_binary_build_name: Path = (
+ self.build_dir_root
+ / "build"
+ / f"ITK-{self.platform_env}-{self.get_pixi_environment_name()}_{target_arch}"
+ )
+
+ self.cmake_itk_source_build_configurations.set(
+ "ITK_BINARY_DIR:PATH", itk_binary_build_name.as_posix()
+ )
+
+ # Keep values consistent with prior quoting behavior
+ # self.cmake_compiler_configurations.set("CMAKE_CXX_FLAGS:STRING", "-O3 -DNDEBUG")
+ # self.cmake_compiler_configurations.set("CMAKE_C_FLAGS:STRING", "-O3 -DNDEBUG")
+
+ def post_build_fixup(self) -> None:
+ """Repair wheels with ``auditwheel`` and retag the ITK meta-wheel."""
+ manylinux_ver: str | None = self.package_env_config.get(
+ "MANYLINUX_VERSION", None
+ )
+ if manylinux_ver:
+ # Repair all produced wheels with auditwheel for packages with so elements (starts with itk_)
+ whl = None
+ # cp39-cp39-linux itk_segmentation-6.0.0b2-cp39-cp39-linux_x86_64.whl
+ # Extract Python version from platform_env
+ if "-" in self.platform_env:
+ # in manylinux case, platform env is manylinux-cp310, for example, don't want anything before '-'
+ py_version = self.platform_env.split("-")[-1]
+ else:
+ py_version = self.platform_env
+ cp_prefix: str = py_version.replace("py", "cp").replace(".", "")
+ binary_wheel_glob_pattern: str = f"itk_*-*{cp_prefix}*-linux_*.whl"
+ dist_path: Path = self.build_dir_root / "dist"
+ for whl in dist_path.glob(binary_wheel_glob_pattern):
+ if whl.name.startswith("itk-"):
+ print(
+ f"Skipping the itk-meta wheel that has nothing to fixup {whl}"
+ )
+ continue
+ self.fixup_wheel(str(whl))
+ del whl
+ # Retag meta-wheel: Special handling for the itk meta wheel to adjust tag
+ # auditwheel does not process this "metawheel" correctly since it does not
+ # have any native SO's.
+ meta_wheel_glob_pattern: str = f"itk-*-*{cp_prefix}*-linux_*.whl"
+ for metawhl in dist_path.glob(meta_wheel_glob_pattern):
+ # Unpack, edit WHEEL tag, repack
+ metawheel_dir = self.build_dir_root / "metawheel"
+ metawheel_dir.mkdir(parents=True, exist_ok=True)
+ self.echo_check_call(
+ [
+ self.package_env_config["PYTHON_EXECUTABLE"],
+ "-m",
+ "wheel",
+ "unpack",
+ "--dest",
+ str(metawheel_dir),
+ str(metawhl),
+ ]
+ )
+ # Find unpacked dir
+ unpacked_dirs = list(metawheel_dir.glob("itk-*/itk*.dist-info/WHEEL"))
+ for wheel_file in unpacked_dirs:
+ content = wheel_file.read_text(encoding="utf-8").splitlines()
+ base = metawhl.name
+ if len(manylinux_ver) > 0:
+ base = metawhl.name.replace(
+ "linux", f"manylinux{manylinux_ver}"
+ )
+ # Wheel filename: {name}-{version}-{python}-{abi}-{platform}.whl
+ # Tag must be only "{python}-{abi}-{platform}", not the full stem.
+ stem = Path(base).stem
+ parts = stem.split("-")
+ tag = "-".join(parts[-3:])
+ new = []
+ for line in content:
+ if line.startswith("Tag: "):
+ new.append(f"Tag: {tag}")
+ else:
+ new.append(line)
+ wheel_file.write_text("\n".join(new) + "\n", encoding="utf-8")
+ for fixed_dir in metawheel_dir.glob("itk-*"):
+ metawheel_dist = self.build_dir_root / "metawheel-dist"
+ metawheel_dist.mkdir(parents=True, exist_ok=True)
+ self.echo_check_call(
+ [
+ self.package_env_config["PYTHON_EXECUTABLE"],
+ "-m",
+ "wheel",
+ "pack",
+ "--dest",
+ str(metawheel_dist),
+ str(fixed_dir),
+ ]
+ )
+ # Move and clean
+ for new_whl in metawheel_dist.glob("*.whl"):
+ shutil.move(
+ str(new_whl),
+ str((self.build_dir_root / "dist") / new_whl.name),
+ )
+ # Remove old and temp
+ try:
+ metawhl.unlink()
+ except OSError:
+ pass
+ _remove_tree(metawheel_dir)
+ _remove_tree(metawheel_dist)
+
+ def fixup_wheel(
+ self, filepath, lib_paths: str = "", remote_module_wheel: bool = False
+ ) -> None:
+ """Repair a wheel with ``auditwheel`` and apply manylinux platform tags.
+
+ Parameters
+ ----------
+ filepath : str
+ Path to the ``.whl`` file.
+ lib_paths : str, optional
+ Unused on Linux (kept for interface compatibility).
+ remote_module_wheel : bool, optional
+ If True, output repaired wheel to the remote module's ``dist/``
+ directory instead of the main build ``dist/``.
+ """
+ # Use auditwheel to repair wheels and set manylinux tags
+ manylinux_ver = self.package_env_config.get("MANYLINUX_VERSION", "")
+ if len(manylinux_ver) > 1:
+ plat = None
+ if self.package_env_config["ARCH"] == "x64" and manylinux_ver:
+ plat = f"manylinux{manylinux_ver}_x86_64"
+ cmd = [
+ self.package_env_config["PYTHON_EXECUTABLE"],
+ "-m",
+ "auditwheel",
+ "repair",
+ ]
+ if plat:
+ cmd += ["--plat", plat]
+ cmd += [
+ str(filepath),
+ "-w",
+ (
+ str(self.module_source_dir / "dist")
+ if remote_module_wheel
+ else str(self.build_dir_root / "dist")
+ ),
+ ]
+ # Provide LD_LIBRARY_PATH for oneTBB and common system paths
+ extra_lib = str(
+ self.package_env_config["IPP_SUPERBUILD_BINARY_DIR"].parent
+ / "oneTBB-prefix"
+ / "lib"
+ )
+ env = dict(self.package_env_config)
+ env["LD_LIBRARY_PATH"] = ":".join(
+ [
+ env.get("LD_LIBRARY_PATH", ""),
+ extra_lib,
+ "/usr/lib64",
+ "/usr/lib",
+ ]
+ )
+ print(f'RUNNING WITH PATH {os.environ["PATH"]}')
+ env["PATH"] = os.environ["PATH"]
+ self.echo_check_call(cmd, env=env)
+
+ # Remove the original linux_*.whl after successful repair
+ filepath_obj = Path(filepath)
+ if (
+ filepath_obj.exists()
+ and "-linux_" in filepath_obj.name
+ and filepath_obj.suffix == ".whl"
+ ):
+ print(
+ f"Removing original linux wheel after repair: {filepath_obj.name}"
+ )
+ try:
+ _remove_tree(filepath_obj)
+ except OSError as e:
+ print(f"Warning: Could not remove {filepath_obj.name}: {e}")
+ else:
+ print(
+ "Building outside of manylinux environment does not require wheel fixups."
+ )
+ return
+
+ def build_tarball(self):
+ """Create a zstd-compressed tarball of the ITK build tree."""
+ self.create_posix_tarball()
+
+ def discover_python_venvs(
+ self, platform_os_name: str, platform_architechure: str
+ ) -> list[str]:
+ """Discover available CPython installs on Linux.
+
+ Checks ``/opt/python`` (manylinux) and the project ``venvs/``
+ directory.
+
+ Parameters
+ ----------
+ platform_os_name : str
+ Operating system identifier (unused, kept for interface).
+ platform_architechure : str
+ Architecture identifier (unused, kept for interface).
+
+ Returns
+ -------
+ list[str]
+ Sorted list of discovered environment names.
+ """
+ names = []
+
+ # Discover virtualenvs under project 'venvs' folder
+ def _discover_ipp_venvs() -> list[str]:
+ venvs_dir = self.build_dir_root / "venvs"
+ if not venvs_dir.exists():
+ return []
+ names.extend([p.name for p in venvs_dir.iterdir() if p.is_dir()])
+ # Sort for stable order
+ return sorted(names)
+
+ # Discover available manylinux CPython installs under /opt/python
+ def _discover_manylinuxlocal_pythons() -> list[str]:
+ base = Path("/opt/python")
+ if not base.exists():
+ return []
+ names.extend([p.name for p in base.iterdir() if p.is_dir()])
+ return sorted(names)
+
+ default_platform_envs = (
+ _discover_manylinuxlocal_pythons() + _discover_ipp_venvs()
+ )
+
+ return default_platform_envs
diff --git a/scripts/macos_build_python_instance.py b/scripts/macos_build_python_instance.py
new file mode 100644
index 00000000..4b04fcc8
--- /dev/null
+++ b/scripts/macos_build_python_instance.py
@@ -0,0 +1,140 @@
+from pathlib import Path
+
+from build_python_instance_base import BuildPythonInstanceBase
+
+
+class MacOSBuildPythonInstance(BuildPythonInstanceBase):
+ """macOS-specific wheel builder.
+
+ Handles macOS deployment target and architecture settings, and uses
+ ``delocate`` for wheel repair on x86_64 builds.
+ """
+
+ def prepare_build_env(self) -> None:
+ """Set up the macOS build environment, deployment target, and architecture."""
+ # #############################################
+ # ### Setup build tools
+ self.package_env_config["USE_TBB"] = "OFF"
+ self.package_env_config["TBB_DIR"] = "NOT_FOUND"
+
+ # The interpreter is provided; ensure basic tools are available
+ self.venv_paths()
+ self.update_venv_itk_build_configurations()
+ macosx_target = self.package_env_config.get("MACOSX_DEPLOYMENT_TARGET", "")
+ if macosx_target:
+ self.cmake_compiler_configurations.set(
+ "CMAKE_OSX_DEPLOYMENT_TARGET:STRING", macosx_target
+ )
+
+ target_arch = self.package_env_config["ARCH"]
+
+ self.cmake_compiler_configurations.set(
+ "CMAKE_OSX_ARCHITECTURES:STRING", target_arch
+ )
+
+ # build will be here if downloaded
+ binaries_path = Path(
+ self.build_dir_root
+ / "build"
+ / f"ITK-{self.platform_env}-{self.platform_env}_{target_arch}"
+ )
+
+ if Path(binaries_path).exists():
+ itk_binary_build_name = binaries_path
+ else:
+ itk_binary_build_name: Path = (
+ self.build_dir_root
+ / "build"
+ / f"ITK-{self.platform_env}-{self.get_pixi_environment_name()}_{target_arch}"
+ )
+
+ self.cmake_itk_source_build_configurations.set(
+ "ITK_BINARY_DIR:PATH", itk_binary_build_name.as_posix()
+ )
+
+ # Keep values consistent with prior quoting behavior
+ # self.cmake_compiler_configurations.set("CMAKE_CXX_FLAGS:STRING", "-O3 -DNDEBUG")
+ # self.cmake_compiler_configurations.set("CMAKE_C_FLAGS:STRING", "-O3 -DNDEBUG")
+
+ def post_build_fixup(self) -> None:
+ """Run ``delocate`` on x86_64 wheels to bundle shared libraries."""
+ # delocate on macOS x86_64 only
+ if self.package_env_config["ARCH"] == "x86_64":
+ self.fixup_wheels()
+
+ def build_tarball(self):
+ """Create a zstd-compressed tarball of the ITK build tree."""
+ self.create_posix_tarball()
+
+ def discover_python_venvs(
+ self, platform_os_name: str, platform_architechure: str
+ ) -> list[str]:
+ """Discover available Python environments under the project ``venvs/`` dir.
+
+ Parameters
+ ----------
+ platform_os_name : str
+ Operating system identifier (unused, kept for interface).
+ platform_architechure : str
+ Architecture identifier (unused, kept for interface).
+
+ Returns
+ -------
+ list[str]
+ Sorted list of discovered environment names.
+ """
+ names = []
+
+ # Discover virtualenvs under project 'venvs' folder
+ def _discover_ipp_venvs() -> list[str]:
+ venvs_dir = self.build_dir_root / "venvs"
+ if not venvs_dir.exists():
+ return []
+ names.extend([p.name for p in venvs_dir.iterdir() if p.is_dir()])
+ # Sort for stable order
+ return sorted(names)
+
+ default_platform_envs = _discover_ipp_venvs()
+
+ return default_platform_envs
+
+ def fixup_wheel(
+ self, filepath, lib_paths: str = "", remote_module_wheel: bool = False
+ ) -> None:
+ """Repair a wheel using ``delocate`` on x86_64, cleaning AppleDouble files first.
+
+ Parameters
+ ----------
+ filepath : str
+ Path to the ``.whl`` file.
+ lib_paths : str, optional
+ Unused on macOS (kept for interface compatibility).
+ remote_module_wheel : bool, optional
+ Unused on macOS (kept for interface compatibility).
+ """
+ self.remove_apple_double_files()
+ # macOS fix-up with delocate (only needed for x86_64)
+ if self.package_env_config["ARCH"] != "arm64":
+ venv_bin_path = self.venv_info_dict.get("venv_bin_path", None)
+ if venv_bin_path:
+ delocate_listdeps = f"{venv_bin_path}/delocate-listdeps"
+ delocate_wheel = f"{venv_bin_path}/delocate-wheel"
+ self.echo_check_call([str(delocate_listdeps), str(filepath)])
+ self.echo_check_call([str(delocate_wheel), str(filepath)])
+ else:
+ print(
+ "=" * 20
+ + "WARNING: Could not find venv binary to delocate wheel"
+ + "=" * 20
+ )
+
+ def remove_apple_double_files(self):
+ """Remove AppleDouble ``._*`` files using ``dot_clean`` if available."""
+ try:
+ # Optional: clean AppleDouble files if tool is available
+ self.echo_check_call(
+ ["dot_clean", str(self.package_env_config["IPP_SOURCE_DIR"])]
+ )
+ except Exception:
+ # dot_clean may not be available; continue without it
+ pass
diff --git a/scripts/macpython-build-common.sh b/scripts/macpython-build-common.sh
deleted file mode 100644
index 123ced58..00000000
--- a/scripts/macpython-build-common.sh
+++ /dev/null
@@ -1,79 +0,0 @@
-# Content common to macpython-build-wheels.sh and
-# macpython-build-module-wheels.sh
-
-set -e -x
-
-SCRIPT_DIR=$(cd $(dirname $0) || exit 1; pwd)
-
-MACPYTHON_PY_PREFIX=/Library/Frameworks/Python.framework/Versions
-
-# -----------------------------------------------------------------------
-# Script argument parsing
-#
-usage()
-{
- echo "Usage:
- macpython-build-common
- [ -h | --help ] show usage
- [ -c | --cmake_options ] space-separated string of CMake options to forward to the module (e.g. \"--config-setting=cmake.define.BUILD_TESTING=OFF\")
- [ -- python_versions ] build wheel for a specific python version(s). (e.g. -- 3.10 3.11)"
- exit 2
-}
-
-PYTHON_VERSIONS=""
-CMAKE_OPTIONS=""
-
-while (( "$#" )); do
- case "$1" in
- -c|--cmake_options)
- CMAKE_OPTIONS="$2";
- shift 2;;
- -h|--help)
- usage;
- break;;
- --)
- shift;
- break;;
- *)
- # Parse any unrecognized arguments as python versions
- PYTHON_VERSIONS="${PYTHON_VERSIONS} $1";
- shift;;
- esac
-done
-
-# Parse all arguments after "--" as python versions
-PYTHON_VERSIONS="${PYTHON_VERSIONS} $@"
-# Trim whitespace
-PYTHON_VERSIONS=$(xargs <<< "${PYTHON_VERSIONS}")
-
-# Versions can be restricted by passing them in as arguments to the script
-# For example,
-# macpython-build-wheels.sh 3.10
-if [[ -z "${PYTHON_VERSIONS}" ]]; then
- PYBINARIES=(${MACPYTHON_PY_PREFIX}/*)
-else
- PYBINARIES=()
- for version in "$PYTHON_VERSIONS"; do
- PYBINARIES+=(${MACPYTHON_PY_PREFIX}/*${version}*)
- done
-fi
-
-VENVS=()
-mkdir -p ${SCRIPT_DIR}/../venvs
-for PYBIN in "${PYBINARIES[@]}"; do
- if [[ $(basename $PYBIN) = "Current" ]]; then
- continue
- fi
- py_mm=$(basename ${PYBIN})
- VENV=${SCRIPT_DIR}/../venvs/${py_mm}
- VENVS+=(${VENV})
-done
-
-# -----------------------------------------------------------------------
-# Ensure that requirements are met
-brew update
-brew info doxygen | grep --quiet 'Not installed' && brew install doxygen
-brew info ninja | grep --quiet 'Not installed' && brew install ninja
-NINJA_EXECUTABLE=$(which ninja)
-brew info cmake | grep --quiet 'Not installed' && brew install cmake
-CMAKE_EXECUTABLE=$(which cmake)
diff --git a/scripts/macpython-build-module-deps.sh b/scripts/macpython-build-module-deps.sh
deleted file mode 100644
index a74e9da7..00000000
--- a/scripts/macpython-build-module-deps.sh
+++ /dev/null
@@ -1,75 +0,0 @@
-#!/bin/bash
-
-########################################################################
-# Run this script in an ITK external module directory to generate
-# build artifacts for prerequisite ITK MacOS modules.
-#
-# Module dependencies are built in a flat directory structure regardless
-# of recursive dependencies. Prerequisite sources are required to be passed
-# in the order in which they should be built.
-# For example, if ITKTargetModule depends on ITKTargetModuleDep2 which
-# depends on ITKTargetModuleDep1, the output directory structure
-# will look like this:
-#
-# / ITKTargetModule
-# -- / ITKTargetModuleDep1
-# -- / ITKTargetModuleDep2
-# ..
-#
-# ===========================================
-# ENVIRONMENT VARIABLES
-#
-# - `ITK_MODULE_PREQ`: Prerequisite ITK modules that must be built before the requested module.
-# Format is `/@:/@:...`.
-# For instance, `export ITK_MODULE_PREQ=InsightSoftwareConsortium/ITKMeshToPolyData@v0.10.0`
-#
-########################################################################
-
-script_dir=$(cd $(dirname $0) || exit 1; pwd)
-if [[ ! -f "${script_dir}/macpython-download-cache-and-build-module-wheels.sh" ]]; then
- echo "Could not find download script to use for building module dependencies!"
- exit 1
-fi
-
-# Temporarily update prerequisite environment variable to prevent infinite recursion.
-ITK_MODULE_PREQ_TOPLEVEL=${ITK_MODULE_PREQ}
-ITK_USE_LOCAL_PYTHON_TOPLEVEL=${ITK_USE_LOCAL_PYTHON}
-export ITK_MODULE_PREQ=""
-export ITK_USE_LOCAL_PYTHON="ON"
-
-########################################################################
-echo "Building ITK module dependencies: ${ITK_MODULE_PREQ_TOPLEVEL}"
-
-for MODULE_INFO in ${ITK_MODULE_PREQ_TOPLEVEL//:/ }; do
- MODULE_ORG=`(echo ${MODULE_INFO} | cut -d'/' -f 1)`
- MODULE_NAME=`(echo ${MODULE_INFO} | cut -d'@' -f 1 | cut -d'/' -f 2)`
- MODULE_TAG=`(echo ${MODULE_INFO} | cut -d'@' -f 2)`
-
- MODULE_UPSTREAM=https://github.com/${MODULE_ORG}/${MODULE_NAME}.git
- echo "Cloning from ${MODULE_UPSTREAM}"
- git clone ${MODULE_UPSTREAM}
-
- pushd ${MODULE_NAME}
- git checkout ${MODULE_TAG}
- cp ${script_dir}/macpython-download-cache-and-build-module-wheels.sh .
- echo "Building dependency ${MODULE_NAME}"
- ./macpython-download-cache-and-build-module-wheels.sh $@
- popd
-
- cp ./${MODULE_NAME}/include/* include/
- find ${MODULE_NAME}/wrapping -name '*.in' -print -exec cp {} wrapping \;
- find ${MODULE_NAME}/wrapping -name '*.init' -print -exec cp {} wrapping \;
- find ${MODULE_NAME}/*build/*/include -type f -print -exec cp {} include \;
- rm -f ./${MODULE_NAME}/ITKPythonBuilds-macosx.tar.zst
-done
-
-# Restore environment variable
-export ITK_MODULE_PREQ=${ITK_MODULE_PREQ_TOPLEVEL}
-export ITK_USE_LOCAL_PYTHON=${ITK_USE_LOCAL_PYTHON_TOPLEVEL}
-ITK_MODULE_PREQ_TOPLEVEL=""
-ITK_USE_LOCAL_PYTHON_TOPLEVEL=""
-
-# Summarize disk usage for debugging
-du -sh ./* | sort -hr | head -n 20
-
-echo "Done building ITK external module dependencies"
diff --git a/scripts/macpython-build-module-wheels.sh b/scripts/macpython-build-module-wheels.sh
deleted file mode 100755
index 3c583d4d..00000000
--- a/scripts/macpython-build-module-wheels.sh
+++ /dev/null
@@ -1,134 +0,0 @@
-#!/usr/bin/env bash
-
-########################################################################
-# Run this script in an ITK external module directory to build the
-# Python wheel packages for macOS for an ITK external module.
-#
-# ========================================================================
-# PARAMETERS
-#
-# Versions can be restricted by passing them in as arguments to the script.
-# For example,
-#
-# scripts/macpython-build-module-wheels.sh 3.10 3.11
-# Shared libraries can be included in the wheel by exporting them to DYLD_LIBRARY_PATH before
-# running this script.
-#
-# ===========================================
-# ENVIRONMENT VARIABLES
-#
-# These variables are set with the `export` bash command before calling the script.
-# For example,
-#
-# export DYLD_LIBRARY_PATH="/path/to/libs"
-# scripts/macpython-build-module-wheels.sh 3.10 3.11
-#
-# `DYLD_LIBRARY_PATH`: Shared libraries to be included in the resulting wheel.
-# For instance, `export DYLD_LIBRARY_PATH="/path/to/OpenCL.so:/path/to/OpenCL.so.1.2"`
-#
-# `ITK_MODULE_PREQ`: Prerequisite ITK modules that must be built before the requested module.
-# Format is `/@:/@:...`.
-# For instance, `export ITK_MODULE_PREQ=InsightSoftwareConsortium/ITKMeshToPolyData@v0.10.0`
-#
-########################################################################
-
-
-# -----------------------------------------------------------------------
-# (Optional) Build ITK module dependencies
-
-script_dir=$(cd $(dirname $0) || exit 1; pwd)
-
-if [[ -n ${ITK_MODULE_PREQ} ]]; then
- source "${script_dir}/macpython-build-module-deps.sh"
-fi
-
-# -----------------------------------------------------------------------
-# These variables are set in common script:
-#
-# * CMAKE_EXECUTABLE
-# * CMAKE_OPTIONS
-# * MACPYTHON_PY_PREFIX
-# * PYBINARIES
-# * PYTHON_VERSIONS
-# * NINJA_EXECUTABLE
-# * SCRIPT_DIR
-# * SKBUILD_DIR
-# * VENVS=()
-
-MACPYTHON_PY_PREFIX=""
-SCRIPT_DIR=""
-VENVS=()
-
-source "${script_dir}/macpython-build-common.sh"
-# -----------------------------------------------------------------------
-
-VENV="${VENVS[0]}"
-Python3_EXECUTABLE=${VENV}/bin/python3
-dot_clean ${VENV}
-${Python3_EXECUTABLE} -m pip install --no-cache delocate
-DELOCATE_LISTDEPS=${VENV}/bin/delocate-listdeps
-DELOCATE_WHEEL=${VENV}/bin/delocate-wheel
-DELOCATE_PATCH=${VENV}/bin/delocate-patch
-# So delocate can find the libs
-export DYLD_LIBRARY_PATH=${DYLD_LIBRARY_PATH}:${script_dir}/../oneTBB-prefix/lib
-
-# Compile wheels re-using standalone project and archive cache
-for VENV in "${VENVS[@]}"; do
- py_mm=$(basename ${VENV})
- Python3_EXECUTABLE=${VENV}/bin/python
- Python3_INCLUDE_DIR=$( find -L ${MACPYTHON_PY_PREFIX}/${py_mm}/include -name Python.h -exec dirname {} \; )
-
- echo ""
- echo "Python3_EXECUTABLE:${Python3_EXECUTABLE}"
- echo "Python3_INCLUDE_DIR:${Python3_INCLUDE_DIR}"
-
- if [[ $(arch) == "arm64" ]]; then
- plat_name="macosx-15.0-arm64"
- osx_target="15.0"
- osx_arch="arm64"
- build_path="${SCRIPT_DIR}/../ITK-${py_mm}-macosx_arm64"
- else
- plat_name="macosx-15.0-x86_64"
- osx_target="15.0"
- osx_arch="x86_64"
- build_path="${SCRIPT_DIR}/../ITK-${py_mm}-macosx_x86_64"
- fi
- if [[ ! -z "${MACOSX_DEPLOYMENT_TARGET}" ]]; then
- osx_target="${MACOSX_DEPLOYMENT_TARGET}"
- fi
- export MACOSX_DEPLOYMENT_TARGET=${osx_target}
-
- if [[ -e $PWD/requirements-dev.txt ]]; then
- ${Python3_EXECUTABLE} -m pip install --upgrade -r $PWD/requirements-dev.txt
- fi
- itk_build_path="${build_path}"
- py_minor=$(echo $py_mm | cut -d '.' -f 2)
- wheel_py_api=""
- if test $py_minor -ge 11; then
- wheel_py_api=cp3$py_minor
- fi
- ${Python3_EXECUTABLE} -m build \
- --verbose \
- --wheel \
- --outdir dist \
- --no-isolation \
- --skip-dependency-check \
- --config-setting=cmake.define.CMAKE_MAKE_PROGRAM:FILEPATH=${NINJA_EXECUTABLE} \
- --config-setting=cmake.define.ITK_DIR:PATH=${itk_build_path} \
- --config-setting=cmake.define.CMAKE_INSTALL_LIBDIR:STRING=lib \
- --config-setting=cmake.define.WRAP_ITK_INSTALL_COMPONENT_IDENTIFIER:STRING=PythonWheel \
- --config-setting=cmake.define.CMAKE_OSX_DEPLOYMENT_TARGET:STRING=${osx_target} \
- --config-setting=cmake.define.CMAKE_OSX_ARCHITECTURES:STRING=${osx_arch} \
- --config-setting=cmake.define.PY_SITE_PACKAGES_PATH:PATH="." \
- --config-setting=wheel.py-api=$wheel_py_api \
- --config-setting=cmake.define.BUILD_TESTING:BOOL=OFF \
- --config-setting=cmake.define.Python3_EXECUTABLE:FILEPATH=${Python3_EXECUTABLE} \
- --config-setting=cmake.define.Python3_INCLUDE_DIR:PATH=${Python3_INCLUDE_DIR} \
- ${CMAKE_OPTIONS//'-D'/'--config-setting=cmake.define.'} \
- || exit 1
-done
-
-for wheel in $PWD/dist/*.whl; do
- ${DELOCATE_LISTDEPS} $wheel # lists library dependencies
- ${DELOCATE_WHEEL} $wheel # copies library dependencies into wheel
-done
diff --git a/scripts/macpython-build-tarball.sh b/scripts/macpython-build-tarball.sh
deleted file mode 100755
index c4a727b4..00000000
--- a/scripts/macpython-build-tarball.sh
+++ /dev/null
@@ -1,29 +0,0 @@
-#!/usr/bin/env bash
-
-# This script creates a tarball of the ITK Python package build tree. It is
-# downloaded by the external module build scripts and used to build their
-# Python package on GitHub CI services.
-
-#tbb_contents="ITKPythonPackage/oneTBB*"
-tbb_contents=""
-arch_postfix=""
-if test $(arch) == "arm64"; then
- arch_postfix="-arm64"
- tbb_contents=""
-fi
-
-pushd /Users/svc-dashboard/D/P > /dev/null
-dot_clean ITKPythonPackage
-tar -cf ITKPythonBuilds-macosx${arch_postfix}.tar \
- ITKPythonPackage/ITK-* \
- ${tbb_contents} \
- ITKPythonPackage/venvs \
- ITKPythonPackageRequiredExtractionDir.txt \
- ITKPythonPackage/scripts
-zstd -f \
- -10 \
- -T6 \
- --long=31 \
- ./ITKPythonBuilds-macosx${arch_postfix}.tar \
- -o ./ITKPythonBuilds-macosx${arch_postfix}.tar.zst
-popd > /dev/null
diff --git a/scripts/macpython-build-wheels.sh b/scripts/macpython-build-wheels.sh
deleted file mode 100755
index 60307e16..00000000
--- a/scripts/macpython-build-wheels.sh
+++ /dev/null
@@ -1,238 +0,0 @@
-#!/usr/bin/env bash
-
-# Run this script to build the ITK Python wheel packages for macOS.
-#
-# Versions can be restricted by passing them in as arguments to the script
-# For example,
-#
-# scripts/macpython-build-wheels.sh 3.10
-#
-# Shared libraries can be included in the wheel by exporting them to DYLD_LIBRARY_PATH before
-# running this script.
-#
-# For example,
-#
-# export DYLD_LIBRARY_PATH="/path/to/libs"
-# scripts/macpython-build-module-wheels.sh 3.10
-#
-
-# -----------------------------------------------------------------------
-# These variables are set in common script:
-#
-# * CMAKE_EXECUTABLE
-# * CMAKE_OPTIONS
-# * MACPYTHON_PY_PREFIX
-# * PYBINARIES
-# * PYTHON_VERSIONS
-# * NINJA_EXECUTABLE
-# * SCRIPT_DIR
-# * VENVS=()
-
-MACPYTHON_PY_PREFIX=""
-PYBINARIES=""
-SCRIPT_DIR=""
-
-script_dir=$(cd $(dirname $0) || exit 1; pwd)
-source "${script_dir}/macpython-build-common.sh"
-
-# -----------------------------------------------------------------------
-# Remove previous virtualenv's
-rm -rf ${SCRIPT_DIR}/../venvs
-# Create virtualenv's
-VENVS=()
-mkdir -p ${SCRIPT_DIR}/../venvs
-for PYBIN in "${PYBINARIES[@]}"; do
- if [[ $(basename $PYBIN) = "Current" ]]; then
- continue
- fi
- py_mm=$(basename ${PYBIN})
- VENV=${SCRIPT_DIR}/../venvs/${py_mm}
- VIRTUALENV_EXECUTABLE="${PYBIN}/bin/python3 -m venv"
- ${VIRTUALENV_EXECUTABLE} ${VENV}
- VENVS+=(${VENV})
-done
-
-VENV="${VENVS[0]}"
-Python3_EXECUTABLE=${VENV}/bin/python3
-${Python3_EXECUTABLE} -m pip install --upgrade pip
-${Python3_EXECUTABLE} -m pip install --no-cache delocate
-DELOCATE_LISTDEPS=${VENV}/bin/delocate-listdeps
-DELOCATE_WHEEL=${VENV}/bin/delocate-wheel
-DELOCATE_PATCH=${VENV}/bin/delocate-patch
-
-build_type="Release"
-
-if [[ $(arch) == "arm64" ]]; then
- osx_target="15.0"
- osx_arch="arm64"
- use_tbb="OFF"
-else
- osx_target="15.0"
- osx_arch="x86_64"
- use_tbb="OFF"
-fi
-
-export MACOSX_DEPLOYMENT_TARGET=${osx_target}
-
-# Build standalone project and populate archive cache
-tbb_dir=$PWD/oneTBB-prefix/lib/cmake/TBB
-n_processors=$(sysctl -n hw.ncpu)
-# So delocate can find the libs
-export DYLD_LIBRARY_PATH=${DYLD_LIBRARY_PATH}:$PWD/oneTBB-prefix/lib
-mkdir -p ITK-source
-pushd ITK-source > /dev/null 2>&1
- ${CMAKE_EXECUTABLE} -DITKPythonPackage_BUILD_PYTHON:PATH=0 \
- -DITKPythonPackage_USE_TBB:BOOL=${use_tbb} \
- -G Ninja \
- -DCMAKE_BUILD_TYPE:STRING=${build_type} \
- -DCMAKE_MAKE_PROGRAM:FILEPATH=${NINJA_EXECUTABLE} \
- -DCMAKE_OSX_DEPLOYMENT_TARGET:STRING=${osx_target} \
- -DCMAKE_OSX_ARCHITECTURES:STRING=${osx_arch} \
- ${SCRIPT_DIR}/../
- ${NINJA_EXECUTABLE} -j$n_processors -l$n_processors
-popd > /dev/null 2>&1
-
-SINGLE_WHEEL=0
-
-# Compile wheels re-using standalone project and archive cache
-for VENV in "${VENVS[@]}"; do
- py_mm=$(basename ${VENV})
- export Python3_EXECUTABLE=${VENV}/bin/python
- Python3_INCLUDE_DIR=$( find -L ${MACPYTHON_PY_PREFIX}/${py_mm}/include -name Python.h -exec dirname {} \; )
-
- echo ""
- echo "Python3_EXECUTABLE:${Python3_EXECUTABLE}"
- echo "Python3_INCLUDE_DIR:${Python3_INCLUDE_DIR}"
-
- ${Python3_EXECUTABLE} -m pip install --upgrade -r ${SCRIPT_DIR}/../requirements-dev.txt
-
- if [[ $(arch) == "arm64" ]]; then
- plat_name="macosx-15.0-arm64"
- build_path="${SCRIPT_DIR}/../ITK-${py_mm}-macosx_arm64"
- else
- plat_name="macosx-15.0-x86_64"
- build_path="${SCRIPT_DIR}/../ITK-${py_mm}-macosx_x86_64"
- fi
- if [[ ! -z "${MACOSX_DEPLOYMENT_TARGET}" ]]; then
- osx_target="${MACOSX_DEPLOYMENT_TARGET}"
- fi
- source_path=${SCRIPT_DIR}/../ITK-source/ITK
- PYPROJECT_CONFIGURE="${script_dir}/pyproject_configure.py"
-
- # Clean up previous invocations
- rm -rf ${build_path}
-
- if [[ ${SINGLE_WHEEL} == 1 ]]; then
-
- echo "#"
- echo "# Build single ITK wheel"
- echo "#"
-
- # Configure pyproject.toml
- ${Python3_EXECUTABLE} ${PYPROJECT_CONFIGURE} "itk"
- # Generate wheel
- ${Python3_EXECUTABLE} -m build \
- --verbose \
- --wheel \
- --outdir dist \
- --no-isolation \
- --skip-dependency-check \
- --config-setting=cmake.define.CMAKE_MAKE_PROGRAM:FILEPATH=${NINJA_EXECUTABLE} \
- --config-setting=cmake.define.ITK_SOURCE_DIR:PATH=${source_path} \
- --config-setting=cmake.define.ITK_BINARY_DIR:PATH=${build_path} \
- --config-setting=cmake.define.CMAKE_OSX_DEPLOYMENT_TARGET:STRING=${osx_target} \
- --config-setting=cmake.define.CMAKE_OSX_ARCHITECTURES:STRING=${osx_arch} \
- --config-setting=cmake.define.Python3_EXECUTABLE:FILEPATH=${Python3_EXECUTABLE} \
- --config-setting=cmake.define.Python3_INCLUDE_DIR:PATH=${Python3_INCLUDE_DIR} \
- --config-setting=cmake.define.Module_ITKTBB:BOOL=${use_tbb} \
- --config-setting=cmake.define.TBB_DIR:PATH=${tbb_dir} \
- . \
- ${CMAKE_OPTIONS}
-
- else
-
- echo "#"
- echo "# Build multiple ITK wheels"
- echo "#"
-
- # Build ITK python
- (
- mkdir -p ${build_path} \
- && cd ${build_path} \
- && cmake \
- -DCMAKE_BUILD_TYPE:STRING=${build_type} \
- -DITK_SOURCE_DIR:PATH=${source_path} \
- -DITK_BINARY_DIR:PATH=${build_path} \
- -DBUILD_TESTING:BOOL=OFF \
- -DCMAKE_OSX_DEPLOYMENT_TARGET:STRING=${osx_target} \
- -DCMAKE_OSX_ARCHITECTURES:STRING=${osx_arch} \
- -DITK_WRAP_unsigned_short:BOOL=ON \
- -DITK_WRAP_double:BOOL=ON \
- -DITK_WRAP_complex_double:BOOL=ON \
- -DITK_WRAP_IMAGE_DIMS:STRING="2;3;4" \
- -DPython3_EXECUTABLE:FILEPATH=${Python3_EXECUTABLE} \
- -DPython3_INCLUDE_DIR:PATH=${Python3_INCLUDE_DIR} \
- -DWRAP_ITK_INSTALL_COMPONENT_IDENTIFIER:STRING=PythonWheel \
- -DWRAP_ITK_INSTALL_COMPONENT_PER_MODULE:BOOL=ON \
- "-DPY_SITE_PACKAGES_PATH:PATH=." \
- -DITK_LEGACY_SILENT:BOOL=ON \
- -DITK_WRAP_PYTHON:BOOL=ON \
- -DITK_WRAP_DOC:BOOL=ON \
- -DModule_ITKTBB:BOOL=${use_tbb} \
- -DTBB_DIR:PATH=${tbb_dir} \
- ${CMAKE_OPTIONS} \
- -G Ninja \
- ${source_path} \
- && ninja -j$n_processors -l$n_processors \
- || exit 1
- )
-
- wheel_names=$(cat ${SCRIPT_DIR}/WHEEL_NAMES.txt)
- for wheel_name in ${wheel_names}; do
- # Configure pyproject.toml
- ${Python3_EXECUTABLE} ${PYPROJECT_CONFIGURE} ${wheel_name}
- # Generate wheel
- ${Python3_EXECUTABLE} -m build \
- --verbose \
- --wheel \
- --outdir dist \
- --no-isolation \
- --skip-dependency-check \
- --config-setting=cmake.define.ITK_SOURCE_DIR:PATH=${source_path} \
- --config-setting=cmake.define.ITK_BINARY_DIR:PATH=${build_path} \
- --config-setting=cmake.define.CMAKE_OSX_DEPLOYMENT_TARGET:STRING=${osx_target} \
- --config-setting=cmake.define.CMAKE_OSX_ARCHITECTURES:STRING=${osx_arch} \
- --config-setting=cmake.define.ITKPythonPackage_USE_TBB:BOOL=${use_tbb} \
- --config-setting=cmake.define.ITKPythonPackage_ITK_BINARY_REUSE:BOOL=ON \
- --config-setting=cmake.define.ITKPythonPackage_WHEEL_NAME:STRING=${wheel_name} \
- --config-setting=cmake.define.Python3_EXECUTABLE:FILEPATH=${Python3_EXECUTABLE} \
- --config-setting=cmake.define.Python3_INCLUDE_DIR:PATH=${Python3_INCLUDE_DIR} \
- . \
- ${CMAKE_OPTIONS} \
- || exit 1
- done
-
- fi
-
- # Remove unnecessary files for building against ITK
- find ${build_path} -name '*.cpp' -delete -o -name '*.xml' -delete
- rm -rf ${build_path}/Wrapping/Generators/castxml*
- find ${build_path} -name '*.o' -delete
-done
-
-if [[ $(arch) != "arm64" ]]; then
- for wheel in dist/itk_*.whl; do
- echo "Delocating $wheel"
- ${DELOCATE_LISTDEPS} $wheel # lists library dependencies
- ${DELOCATE_WHEEL} $wheel # copies library dependencies into wheel
- done
-fi
-
-for VENV in "${VENVS[@]}"; do
- ${VENV}/bin/pip install numpy
- ${VENV}/bin/pip install itk --no-cache-dir --no-index -f ${SCRIPT_DIR}/../dist
- (cd $HOME && ${VENV}/bin/python -c 'import itk;')
- (cd $HOME && ${VENV}/bin/python -c 'import itk; image = itk.Image[itk.UC, 2].New()')
- (cd $HOME && ${VENV}/bin/python -c 'import itkConfig; itkConfig.LazyLoading = False; import itk;')
- (cd $HOME && ${VENV}/bin/python ${SCRIPT_DIR}/../docs/code/test.py )
-done
diff --git a/scripts/macpython-download-cache-and-build-module-wheels.sh b/scripts/macpython-download-cache-and-build-module-wheels.sh
index 297e827d..f0189ab7 100755
--- a/scripts/macpython-download-cache-and-build-module-wheels.sh
+++ b/scripts/macpython-download-cache-and-build-module-wheels.sh
@@ -10,93 +10,187 @@
# Versions can be restricted by passing them in as arguments to the script.
# For example,
#
-# scripts/macpython-download-cache-and-build-module-wheels.sh 3.9 3.11
+# scripts/macpython-download-cache-and-build-module-wheels.sh 3.11
#
# Shared libraries can be included in the wheel by setting DYLD_LIBRARY_PATH before
# running this script.
-#
+
# ===========================================
-# ENVIRONMENT VARIABLES
+# ENVIRONMENT VARIABLES: ITK_GIT_TAG ITKPYTHONPACKAGE_ORG ITK_USE_LOCAL_PYTHON ITK_PACKAGE_VERSION
#
# These variables are set with the `export` bash command before calling the script.
# For example,
-#
-# export DYLD_LIBRARY_PATH="/path/to/libs"
-#
-# `ITK_PACKAGE_VERSION`: ITKPythonBuilds archive tag to use for ITK build artifacts.
-# See https://github.com/InsightSoftwareConsortium/ITKPythonBuilds for available tags.
-# For instance, `export ITK_PACKAGE_VERSION=v5.4.0`.
-#
-# `ITKPYTHONPACKAGE_ORG`: Github organization for fetching ITKPythonPackage build scripts.
-#
-# `ITKPYTHONPACKAGE_TAG`: ITKPythonPackage tag for fetching build scripts.
-#
-# `ITK_USE_LOCAL_PYTHON`: Determine how to get Python framework for build.
-# - If empty, Python frameworks will be fetched from python.org
-# - If not empty, frameworks already on machine will be used without fetching.
+# scripts/macpython-build-module-wheels.sh 3.10 3.11
#
########################################################################
+DEFAULT_MODULE_DIRECTORY=$(
+ cd "$(dirname "$0")" || exit 1
+ pwd
+)
+# if not specified, use the current directory for MODULE_SRC_DIRECTORY
+MODULE_SRC_DIRECTORY=${MODULE_SRC_DIRECTORY:=${DEFAULT_MODULE_DIRECTORY}}
-# Install dependencies
-brew update
-brew install --quiet zstd aria2 gnu-tar doxygen ninja
-brew upgrade --quiet cmake rustup
+usage() {
+ echo "Usage:
+ macpython-download-cache-and-build-module-wheels
+ [ -h | --help ] show usage
+ [ -c | --cmake_options ] space-delimited string containing CMake options to forward to the module (e.g. \"-DBUILD_TESTING=OFF\")
+ [ python_version ] build wheel for a specific python version. (e.g. 3.11)"
+ exit 2
+}
-if [[ $(arch) == "arm64" ]]; then
- tarball_arch="-arm64"
-else
- tarball_arch=""
+CMAKE_OPTIONS=""
+while [ $# -gt 0 ]; do
+ case "$1" in
+ -h | --help) usage ;;
+ -c | --cmake_options)
+ CMAKE_OPTIONS="$2"
+ shift 2
+ ;;
+ --)
+ shift
+ break
+ ;;
+ *)
+ break
+ ;;
+ esac
+done
+
+if [ -z "${ITK_PACKAGE_VERSION}" ]; then
+ echo "MUST SET ITK_PACKAGE_VERSION BEFORE RUNNING THIS SCRIPT"
+ exit 1
+fi
+
+# For backwards compatibility when the ITK_GIT_TAG was required to match the ITK_PACKAGE_VERSION
+ITK_GIT_TAG=${ITK_GIT_TAG:=${ITK_PACKAGE_VERSION}}
+
+DASHBOARD_BUILD_DIRECTORY=${DASHBOARD_BUILD_DIRECTORY:=/Users/svc-dashboard/D/P}
+ITKPYTHONPACKAGE_ORG=${ITKPYTHONPACKAGE_ORG:=InsightSoftwareConsortium}
+# Run build scripts
+if [ -z "${NO_SUDO}" ] || [ "${NO_SUDO}" -ne 1 ]; then
+ sudo_exec=sudo
fi
-# Fetch ITKPythonBuilds archive containing ITK build artifacts
-rm -fr ITKPythonPackage
-echo "Fetching https://github.com/InsightSoftwareConsortium/ITKPythonBuilds/releases/download/${ITK_PACKAGE_VERSION:=v5.4.0}/ITKPythonBuilds-macosx${tarball_arch}.tar.zst"
-if [[ ! -f ITKPythonBuilds-macosx${tarball_arch}.tar.zst ]]; then
- aria2c -c --file-allocation=none -o ITKPythonBuilds-macosx${tarball_arch}.tar.zst -s 10 -x 10 https://github.com/InsightSoftwareConsortium/ITKPythonBuilds/releases/download/${ITK_PACKAGE_VERSION:=v5.4.0}/ITKPythonBuilds-macosx${tarball_arch}.tar.zst
+if [ ! -d "${DASHBOARD_BUILD_DIRECTORY}" ]; then
+ ${sudo_exec} mkdir -p "${DASHBOARD_BUILD_DIRECTORY}" && ${sudo_exec} chown "$UID:$GID" "${DASHBOARD_BUILD_DIRECTORY}"
fi
-unzstd --long=31 ITKPythonBuilds-macosx${tarball_arch}.tar.zst -o ITKPythonBuilds-macosx${tarball_arch}.tar
-PATH="$(dirname $(brew list gnu-tar | grep gnubin)):$PATH"
-gtar xf ITKPythonBuilds-macosx${tarball_arch}.tar --warning=no-unknown-keyword --checkpoint=10000 --checkpoint-action=dot \
- ITKPythonPackage/ITK-source \
- ITKPythonPackageRequiredExtractionDir.txt \
- ITKPythonPackage/scripts
-
-# Extract subdirectories specific to the compiled python versions
-args=( "$@" )
-source ITKPythonPackage/scripts/macpython-build-common.sh
-for version in "$PYTHON_VERSIONS"; do
- gtar xf ITKPythonBuilds-macosx${tarball_arch}.tar --warning=no-unknown-keyword --checkpoint=10000 --checkpoint-action=dot \
- --wildcards "ITKPythonPackage/ITK-${version}-macosx*" \
- "ITKPythonPackage/venvs/${version}"
+cd "${DASHBOARD_BUILD_DIRECTORY}" || exit
+
+# -----------------------------------------------------------------------
+# Check for conda/pixi-provided ITK (libitk-wrapping package).
+# When available, skip the tarball download entirely.
+
+_conda_itk_dir=""
+for _prefix_var in CONDA_PREFIX PIXI_ENVIRONMENT_DIR; do
+ _prefix="${!_prefix_var:-}"
+ if [ -n "${_prefix}" ]; then
+ for _candidate in "${_prefix}"/lib/cmake/ITK-*; do
+ if [ -f "${_candidate}/ITKConfig.cmake" ]; then
+ _conda_itk_dir="${_candidate}"
+ echo "Detected conda-installed ITK at ${_conda_itk_dir} (via \$${_prefix_var})"
+ break 2
+ fi
+ done
+ fi
done
-rm ITKPythonBuilds-macosx${tarball_arch}.tar
+if [ -n "${_conda_itk_dir}" ]; then
+ echo "Using conda-installed ITK; skipping tarball download."
+else
+ # NOTE: download phase will install pixi in the DASHBOARD_BUILD_DIRECTORY (which is separate from the pixi
+ # environment used by ITKPythonPackage).
+ export PIXI_HOME=${DASHBOARD_BUILD_DIRECTORY}/.pixi
+ if [ ! -f "${PIXI_HOME}/.pixi/bin/pixi" ]; then
+ # Install pixi
+ curl -fsSL https://pixi.sh/install.sh | sh
+ # These are the tools needed for cross platform downloads of the ITK build caches stored in https://github.com/InsightSoftwareConsortium/ITKPythonBuilds
+ pixi global install zstd
+ pixi global install aria2
+ pixi global install gnu-tar
+ pixi global install git
+ pixi global install rsync
+ fi
+ export PATH="${PIXI_HOME}/bin:$PATH"
-# Optional: Update build scripts
-if [[ -n ${ITKPYTHONPACKAGE_TAG} ]]; then
- echo "Updating build scripts to ${ITKPYTHONPACKAGE_ORG:=InsightSoftwareConsortium}/ITKPythonPackage@${ITKPYTHONPACKAGE_TAG}"
- git clone "https://github.com/${ITKPYTHONPACKAGE_ORG}/ITKPythonPackage.git" "IPP-tmp"
- pushd IPP-tmp/
- git checkout "${ITKPYTHONPACKAGE_TAG}"
- git status
- popd
+ tarball_arch="-$(arch)"
+ TARBALL_NAME="ITKPythonBuilds-macosx${tarball_arch}.tar"
- rm -rf ITKPythonPackage/scripts/
- cp -r IPP-tmp/scripts ITKPythonPackage/
- rm -rf IPP-tmp/
-fi
+ if [[ ! -f ${TARBALL_NAME}.zst ]]; then
+ echo "Local ITK cache tarball file not found..."
+ # Fetch ITKPythonBuilds archive containing ITK build artifacts
+ echo "Fetching https://github.com/InsightSoftwareConsortium/ITKPythonBuilds/releases/download/${ITK_PACKAGE_VERSION}/ITKPythonBuilds-macosx${tarball_arch}.tar.zst"
+ if ! curl -L "https://github.com/InsightSoftwareConsortium/ITKPythonBuilds/releases/download/${ITK_PACKAGE_VERSION}/ITKPythonBuilds-macosx${tarball_arch}.tar.zst" -O; then
+ echo "FAILED Download:"
+ echo "curl -L https://github.com/InsightSoftwareConsortium/ITKPythonBuilds/releases/download/${ITK_PACKAGE_VERSION}/${TARBALL_NAME}.zst -O"
+ exit 1
+ fi
+ fi
-# Run build scripts
-sudo mkdir -p /Users/svc-dashboard/D/P && sudo chown $UID:$GID /Users/svc-dashboard/D/P
-if [[ ! -d /Users/svc-dashboard/D/P/ITKPythonPackage ]]; then
- mv ITKPythonPackage /Users/svc-dashboard/D/P/
-fi
+ if [[ ! -f ./${TARBALL_NAME}.zst ]]; then
+ echo "ERROR: can not find required binary './${TARBALL_NAME}.zst'"
+ exit 255
+ fi
-# Optionally install baseline Python versions
-if [[ ! ${ITK_USE_LOCAL_PYTHON} ]]; then
- echo "Fetching Python frameworks"
- sudo rm -rf /Library/Frameworks/Python.framework/Versions/*
- /Users/svc-dashboard/D/P/ITKPythonPackage/scripts/macpython-install-python.sh
+ local_compress_tarball_name=${DASHBOARD_BUILD_DIRECTORY}/ITKPythonBuilds-macosx${tarball_arch}.tar.zst
+ if [[ ! -f ${local_compress_tarball_name} ]]; then
+ aria2c -c --file-allocation=none -d "$(dirname "${local_compress_tarball_name}")" -o "$(basename "${local_compress_tarball_name}")" -s 10 -x 10 "https://github.com/InsightSoftwareConsortium/ITKPythonBuilds/releases/download/${ITK_PACKAGE_VERSION}/ITKPythonBuilds-macosx${tarball_arch}.tar.zst"
+ fi
+ local_tarball_name=${DASHBOARD_BUILD_DIRECTORY}/ITKPythonBuilds-macosx${tarball_arch}.tar
+ unzstd --long=31 "${local_compress_tarball_name}" -o "${local_tarball_name}"
+ # Find GNU tar (gtar from pixi or brew) for reliable extraction
+ if command -v gtar >/dev/null 2>&1; then
+ TAR_CMD=gtar
+ TAR_FLAGS=(--warning=no-unknown-keyword --checkpoint=10000 --checkpoint-action=dot)
+ elif tar --version 2>/dev/null | grep -q "GNU tar"; then
+ TAR_CMD=tar
+ TAR_FLAGS=(--warning=no-unknown-keyword --checkpoint=10000 --checkpoint-action=dot)
+ else
+ TAR_CMD=tar
+ TAR_FLAGS=()
+ fi
+ "${TAR_CMD}" xf "${local_tarball_name}" "${TAR_FLAGS[@]}"
+ rm "${local_tarball_name}"
+
+ # Optional: Update build scripts
+ if [[ -n ${ITKPYTHONPACKAGE_TAG} ]]; then
+ echo "Updating build scripts to ${ITKPYTHONPACKAGE_ORG}/ITKPythonPackage@${ITKPYTHONPACKAGE_TAG}"
+ local_clone_ipp=${DASHBOARD_BUILD_DIRECTORY}/ITKPythonPackage_${ITKPYTHONPACKAGE_TAG}
+ if [ ! -d "${local_clone_ipp}/.git" ]; then
+ git clone "https://github.com/${ITKPYTHONPACKAGE_ORG}/ITKPythonPackage.git" "${local_clone_ipp}"
+ fi
+ pushd "${local_clone_ipp}" || exit
+ git checkout "${ITKPYTHONPACKAGE_TAG}"
+ git reset "origin/${ITKPYTHONPACKAGE_TAG}" --hard
+ git status
+ popd || exit
+ rsync -av "${local_clone_ipp}/" "${DASHBOARD_BUILD_DIRECTORY}/ITKPythonPackage/"
+ fi
fi
echo "Building module wheels"
-/Users/svc-dashboard/D/P/ITKPythonPackage/scripts/macpython-build-module-wheels.sh "${args[@]}"
+cd "${DASHBOARD_BUILD_DIRECTORY}/ITKPythonPackage" || exit
+echo "$@"
+for py_indicator in "$@"; do
+ # The following line is to convert "py3.11|py311|cp311|3.11" -> py311 normalized form
+ py_squashed_numeric=$(echo "${py_indicator}" | sed 's/py//g' | sed 's/cp//g' | sed 's/\.//g')
+ pyenv=py${py_squashed_numeric}
+ pixi run -e "macosx-${pyenv}" -- python \
+ "${DASHBOARD_BUILD_DIRECTORY}/ITKPythonPackage/scripts/build_wheels.py" \
+ --platform-env "macosx-${pyenv}" \
+ --lib-paths '' '' \
+ --module-source-dir "${MODULE_SRC_DIRECTORY}" \
+ --module-dependencies-root-dir "${DASHBOARD_BUILD_DIRECTORY}/MODULE_DEPENDENCIES" \
+ --itk-module-deps "${ITK_MODULE_PREQ}" \
+ --no-build-itk-tarball-cache \
+ --build-dir-root "${DASHBOARD_BUILD_DIRECTORY}/ITKPythonPackage-build" \
+ --manylinux-version '' \
+ --itk-git-tag "${ITK_GIT_TAG}" \
+ --itk-source-dir "${DASHBOARD_BUILD_DIRECTORY}/ITKPythonPackage-build/ITK" \
+ --itk-package-version "${ITK_PACKAGE_VERSION}" \
+ --no-use-sudo \
+ --no-use-ccache \
+ --skip-itk-build \
+ --skip-itk-wheel-build \
+ ${CMAKE_OPTIONS:+-- ${CMAKE_OPTIONS}}
+ #Let this be automatically selected --macosx-deployment-target 10.7 \
+done
diff --git a/scripts/macpython-install-python.sh b/scripts/macpython-install-python.sh
deleted file mode 100755
index 70a57b7a..00000000
--- a/scripts/macpython-install-python.sh
+++ /dev/null
@@ -1,423 +0,0 @@
-#!/usr/bin/env bash
-
-# Download and install Python.org's MacPython and install Pip
-
-# Adapted from https://github.com/matthew-brett/multibuild
-# osx_utils.sh
-#The multibuild package, including all examples, code snippets and attached
-#documentation is covered by the 2-clause BSD license.
-
- #Copyright (c) 2013-2016, Matt Terry and Matthew Brett; all rights
- #reserved.
-
- #Redistribution and use in source and binary forms, with or without
- #modification, are permitted provided that the following conditions are
- #met:
-
- #1. Redistributions of source code must retain the above copyright notice,
- #this list of conditions and the following disclaimer.
-
- #2. Redistributions in binary form must reproduce the above copyright
- #notice, this list of conditions and the following disclaimer in the
- #documentation and/or other materials provided with the distribution.
-
- #THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
- #IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
- #THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- #PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
- #CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- #EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- #PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- #PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
- #LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- #NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- #SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-set -x
-
-MACPYTHON_URL=https://www.python.org/ftp/python
-MACPYTHON_PY_PREFIX=/Library/Frameworks/Python.framework/Versions
-MACPYTHON_DEFAULT_OSX="10.6"
-MB_PYTHON_OSX_VER=${MB_PYTHON_OSX_VER:-$MACPYTHON_DEFAULT_OSX}
-GET_PIP_URL=https://bootstrap.pypa.io/get-pip.py
-DOWNLOADS_SDIR=downloads
-WORKING_SDIR=working
-
-# As of 2 November 2022 - latest Python of each version with binary download
-# available.
-# See: https://www.python.org/downloads/mac-osx/
-LATEST_2p7=2.7.18
-LATEST_3p5=3.5.4
-LATEST_3p6=3.6.8
-LATEST_3p7=3.7.9
-LATEST_3p8=3.8.10
-LATEST_3p9=3.9.13
-LATEST_3p10=3.10.11
-LATEST_3p11=3.11.4
-LATEST_3p12=3.12.0
-
-
-function check_python {
- if [ -z "$PYTHON_EXE" ]; then
- echo "PYTHON_EXE variable not defined"
- exit 1
- fi
-}
-
-function check_pip {
- if [ -z "$PIP_CMD" ]; then
- echo "PIP_CMD variable not defined"
- exit 1
- fi
-}
-
-function check_var {
- if [ -z "$1" ]; then
- echo "required variable not defined"
- exit 1
- fi
-}
-
-function get_py_digit {
- check_python
- $PYTHON_EXE -c "import sys; print(sys.version_info[0])"
-}
-
-function get_py_mm {
- check_python
- $PYTHON_EXE -c "import sys; print('{0}.{1}'.format(*sys.version_info[0:2]))"
-}
-
-function get_py_mm_nodot {
- check_python
- $PYTHON_EXE -c "import sys; print('{0}{1}'.format(*sys.version_info[0:2]))"
-}
-
-function get_py_prefix {
- check_python
- $PYTHON_EXE -c "import sys; print(sys.prefix)"
-}
-
-function fill_pyver {
- # Convert major or major.minor format to major.minor.micro
- #
- # Hence:
- # 2 -> 2.7.11 (depending on LATEST_2p7 value)
- # 2.7 -> 2.7.11 (depending on LATEST_2p7 value)
- local ver=$1
- check_var $ver
- if [[ $ver =~ [0-9]+\.[0-9]+\.[0-9]+ ]]; then
- # Major.minor.micro format already
- echo $ver
- elif [ $ver == 2 ] || [ $ver == "2.7" ]; then
- echo $LATEST_2p7
- elif [ $ver == 3 ] || [ $ver == "3.11" ]; then
- echo $LATEST_3p11
- elif [ $ver == "3.12" ]; then
- echo $LATEST_3p12
- elif [ $ver == "3.10" ]; then
- echo $LATEST_3p10
- elif [ $ver == "3.9" ]; then
- echo $LATEST_3p9
- elif [ $ver == "3.8" ]; then
- echo $LATEST_3p8
- elif [ $ver == "3.7" ]; then
- echo $LATEST_3p7
- elif [ $ver == "3.6" ]; then
- echo $LATEST_3p6
- elif [ $ver == "3.5" ]; then
- echo $LATEST_3p5
- else
- echo "Can't fill version $ver" 1>&2
- exit 1
- fi
-}
-
-function macpython_sdk_list_for_version {
- # return a list of SDK targets supported for a given CPython version
- # Parameters
- # $py_version (python version in major.minor.extra format)
- # eg
- # macpython_sdks_for_version 2.7.15
- # >> 10.6 10.9
- local _ver=$(fill_pyver $1)
- local _major=${_ver%%.*}
- local _return
-
- if [ "${PLAT}" = "arm64" ]; then
- _return="11.0"
- elif [ "$_major" -eq "2" ]; then
- [ $(lex_ver $_ver) -lt $(lex_ver 2.7.18) ] && _return="10.6"
- [ $(lex_ver $_ver) -ge $(lex_ver 2.7.15) ] && _return="$_return 10.9"
- elif [ "$_major" -eq "3" ]; then
- [ $(lex_ver $_ver) -lt $(lex_ver 3.8) ] && _return="10.6"
- [ $(lex_ver $_ver) -ge $(lex_ver 3.6.5) ] && _return="$_return 10.9"
- else
- echo "Error version=${_ver}, expecting 2.x or 3.x" 1>&2
- exit 1
- fi
- echo $_return
-}
-
-function macpython_sdk_for_version {
- # assumes the output of macpython_sdk_list_for_version is a list
- # of SDK versions XX.Y in sorted order, eg "10.6 10.9" or "10.9"
- echo $(macpython_sdk_list_for_version $1) | awk -F' ' '{print $NF}'
-}
-
-function pyinst_ext_for_version {
- # echo "pkg" or "dmg" depending on the passed Python version
- # Parameters
- # $py_version (python version in major.minor.extra format)
- #
- # Earlier Python installers are .dmg, later are .pkg.
- local py_version=$1
- check_var $py_version
- py_version=$(fill_pyver $py_version)
- local py_0=${py_version:0:1}
- if [ $py_0 -eq 2 ]; then
- if [ "$(lex_ver $py_version)" -ge "$(lex_ver 2.7.9)" ]; then
- echo "pkg"
- else
- echo "dmg"
- fi
- elif [ $py_0 -ge 3 ]; then
- echo "pkg"
- fi
-}
-
-function pyinst_fname_for_version {
- # echo filename for OSX installer file given Python and minimum
- # macOS versions
- # Parameters
- # $py_version (Python version in major.minor.extra format)
- # $py_osx_ver: {major.minor | not defined}
- # if defined, the minimum macOS SDK version that Python is
- # built for, eg: "10.6" or "10.9", if not defined, infers
- # this from $py_version using macpython_sdk_for_version
- local py_version=$1
- local py_osx_ver=${2:-$(macpython_sdk_for_version $py_version)}
- local inst_ext=$(pyinst_ext_for_version $py_version)
- if [ "${PLAT:-}" == "arm64" ] || [ "${PLAT:-}" == "universal2" ]; then
- if [ "$py_version" == "3.9.1" ]; then
- echo "python-${py_version}-macos11.0.${inst_ext}"
- else
- echo "python-${py_version}-macos11.${inst_ext}"
- fi
- else
- if [ "$py_version" == "3.7.9" ]; then
- echo "python-${py_version}-macosx${py_osx_ver}.${inst_ext}"
- else
- echo "python-${py_version}-macos${py_osx_ver}.${inst_ext}"
- fi
- fi
-}
-
-function get_macpython_arch {
- # echo arch (e.g. intel or x86_64), extracted from the distutils platform tag
- # Parameters
- # $distutils_plat PEP425 style platform tag, or if not provided, calls
- # the function get_distutils_platform, provided by
- # common_utils.sh. Fails if this is not a mac platform
- #
- # Note: MUST only be called after the version of Python used to build the
- # target wheel has been installed and is on the path
- local distutils_plat=${1:-$(get_distutils_platform)}
- if [[ $distutils_plat =~ macosx-(1[0-9]\.[0-9]+)-(.*) ]]; then
- echo ${BASH_REMATCH[2]}
- else
- echo "Error parsing macOS distutils platform '$distutils_plat'"
- exit 1
- fi
-}
-
-function get_macpython_osx_ver {
- # echo minimum macOS version (e.g. 10.9) from the distutils platform tag
- # Parameters
- # $distutils_plat PEP425 style platform tag, or if not provided, calls
- # the function get_distutils_platform, provided by
- # common_utils.sh. Fails if this is not a mac platform
- #
- # Note: MUST only be called after the version of Python used to build the
- # target wheel has been installed and is on the path
- local distutils_plat=${1:-$(get_distutils_platform)}
- if [[ $distutils_plat =~ macosx-(1[0-9]\.[0-9]+)-(.*) ]]; then
- echo ${BASH_REMATCH[1]}
- else
- echo "Error parsing macOS distutils platform '$distutils_plat'"
- exit 1
- fi
-}
-
-function macpython_arch_for_version {
- # echo arch (intel or x86_64) that a version of Python is expected
- # to be built for
- # Parameters
- # $py_ver Python version, in the format (major.minor.patch) for
- # CPython, or pypy-(major.minor) for PyPy
- # $py_osx_ver minimum macOS version the target Python is built for
- # (major.minor)
- local py_ver=$1
- local py_osx_ver=${2:-$MB_PYTHON_OSX_VER}
- check_var $1
- if [[ $(macpython_impl_for_version $py_ver) == "cp" ]]; then
- if [[ "$py_osx_ver" == "10.6" ]]; then
- echo "intel"
- elif [[ "$py_osx_ver" == "10.9" ]]; then
- echo "x86_64"
- else
- echo "Unexpected CPython macOS version: ${py_osx_ver}, supported values: 10.6 and 10.9"
- exit 1
- fi
- else
- echo "x86_64"
- fi
-}
-
-function macpython_impl_for_version {
- # echo Python implementation (cp for CPython, pp for PyPy) given a
- # suitably formatted version string
- # Parameters:
- # $version : [implementation-]major[.minor[.patch]]
- # Python implementation, e.g. "3.6" for CPython or
- # "pypy-5.4" for PyPy
- local version=$1
- check_var $1
- if [[ "$version" =~ ^pypy ]]; then
- echo pp
- elif [[ "$version" =~ ([0-9\.]+) ]]; then
- echo cp
- else
- echo "config error: Issue parsing this implementation in install_python:"
- echo " version=$version"
- exit 1
- fi
-}
-
-function strip_macpython_ver_prefix {
- # strip any implementation prefix from a Python version string
- # Parameters:
- # $version : [implementation-]major[.minor[.patch]]
- # Python implementation, e.g. "3.6" for CPython or
- # "pypy-5.4" for PyPy
- local version=$1
- check_var $1
- if [[ "$version" =~ (pypy-)?([0-9\.]+) ]]; then
- echo ${BASH_REMATCH[2]}
- fi
-}
-
-function install_macpython {
- # Install Python and set $PYTHON_EXE to the installed executable
- # Parameters:
- # $version : [implementation-]major[.minor[.patch]]
- # The Python implementation to install, e.g. "3.6", "pypy-5.4" or "pypy3.6-7.2"
- # $py_osx_ver: {major.minor | not defined}
- # if defined, the macOS version that CPython is built for, e.g.
- # "10.6" or "10.9". Ignored for PyPy
- local version=$1
- local py_osx_ver=$2
- local impl=$(macpython_impl_for_version $version)
- if [[ "$impl" == "pp" ]]; then
- install_pypy $version
- elif [[ "$impl" == "cp" ]]; then
- local stripped_ver=$(strip_macpython_ver_prefix $version)
- install_mac_cpython $stripped_ver $py_osx_ver
- else
- echo "Unexpected Python impl: ${impl}"
- exit 1
- fi
-}
-
-function install_mac_cpython {
- # Installs Python.org Python
- # Parameters
- # $py_version
- # Version given in major or major.minor or major.minor.micro e.g
- # "3" or "3.7" or "3.7.1".
- # $py_osx_ver
- # {major.minor | not defined}
- # if defined, the macOS version that Python is built for, e.g.
- # "10.6" or "10.9"
- # sets $PYTHON_EXE variable to Python executable
- local py_version=$(fill_pyver $1)
- local py_osx_ver=$2
- #local py_stripped=$(strip_ver_suffix $py_version)
- local py_stripped=$py_version
- local py_inst=$(pyinst_fname_for_version $py_version $py_osx_ver)
- local inst_path=$DOWNLOADS_SDIR/$py_inst
- local retval=""
- mkdir -p $DOWNLOADS_SDIR
- # exit early on curl errors, but don't let it exit the shell
- curl -f $MACPYTHON_URL/$py_stripped/${py_inst} > $inst_path || retval=$?
- if [ ${retval:-0} -ne 0 ]; then
- echo "Python download failed! Check ${py_inst} exists on the server."
- exit $retval
- fi
-
- if [ "${py_inst: -3}" == "dmg" ]; then
- hdiutil attach $inst_path -mountpoint /Volumes/Python
- inst_path=/Volumes/Python/Python.mpkg
- fi
- sudo installer -pkg $inst_path -target /
- local py_mm=${py_version%.*}
- PYTHON_EXE=$MACPYTHON_PY_PREFIX/$py_mm/bin/python$py_mm
- # Install certificates for Python 3.6
- local inst_cmd="/Applications/Python ${py_mm}/Install Certificates.command"
- if [ -e "$inst_cmd" ]; then
- sh "$inst_cmd"
- fi
- PIP_CMD="$MACPYTHON_PY_PREFIX/$py_mm/bin/python$py_mm -m pip"
- $PIP_CMD install --upgrade pip
- export PIP_CMD
-}
-
-function install_virtualenv {
- # Generic install of virtualenv
- # Installs virtualenv into python given by $PYTHON_EXE
- # Assumes virtualenv will be installed into same directory as $PYTHON_EXE
- check_pip
- # Travis VMS install virtualenv for system python by default - force
- # install even if installed already
- $PIP_CMD install virtualenv --ignore-installed
- check_python
- VIRTUALENV_CMD="$(dirname $PYTHON_EXE)/virtualenv"
- export VIRTUALENV_CMD
-}
-
-function make_workon_venv {
- # Make a virtualenv in given directory ('venv' default)
- # Set $PYTHON_EXE, $PIP_CMD to virtualenv versions
- # Parameter $venv_dir
- # directory for virtualenv
- local venv_dir=$1
- if [ -z "$venv_dir" ]; then
- venv_dir="venv"
- fi
- venv_dir=`abspath $venv_dir`
- check_python
- $PYTHON_EXE -m virtualenv $venv_dir
- PYTHON_EXE=$venv_dir/bin/python
- PIP_CMD=$venv_dir/bin/pip
-}
-
-# Remove previous versions
-#echo "Remove and update Python files at ${MACPYTHON_FRAMEWORK}"
-#sudo rm -rf ${MACPYTHON_FRAMEWORK}
-
-if test "$(arch)" == "arm64"; then
- echo "we are arm"
- PLAT=arm64
- for pyversion in $LATEST_3p10 $LATEST_3p11; do
- install_macpython $pyversion 11
- install_virtualenv
- done
-else
- # Deployment target requirements:
- # * 10.9: Python 3.7
- # * 11: Python >= 3.8
- for pyversion in $LATEST_3p10 $LATEST_3p11; do
- install_macpython $pyversion 11
- install_virtualenv
- done
-fi
diff --git a/scripts/make_tarballs.sh b/scripts/make_tarballs.sh
new file mode 100755
index 00000000..cdd93d6e
--- /dev/null
+++ b/scripts/make_tarballs.sh
@@ -0,0 +1,120 @@
+#!/usr/bin/env bash
+# NOTES: Building tarballs requires specific pathing for supporting github CI
+# workflows
+
+script_dir=$(
+ cd "$(dirname "$0")" || exit 1
+ pwd
+)
+_ipp_dir=$(dirname "${script_dir}")
+
+# If args are given, use them. Otherwise use default python environments
+pyenvs=("${@:-py310 py311}")
+
+# Otherwise process mac and linux based on uname
+
+# Need to explicitly request to --build-itk-tarball-cache
+BUILD_WHEELS_EXTRA_FLAGS=("--build-itk-tarball-cache")
+if [ -z "${ITK_GIT_TAG}" ]; then
+ DEFAULT_ITK_GIT_TAG=v6.0b02
+ echo "============================================================================="
+ echo "============================================================================="
+ for _ in x x x x x x x x x x x x x x x x x x x x x x x x x x x x x; do
+ echo "===== WARNING: ITK_GIT_TAG not set, so defaulting to ${DEFAULT_ITK_GIT_TAG}"
+ done
+ echo "============================================================================="
+ echo "============================================================================="
+fi
+ITK_GIT_TAG=${ITK_GIT_TAG:=${DEFAULT_ITK_GIT_TAG}}
+
+## --
+# --
+# --
+# --
+# Short circuit builds to use dockcross if MANYLINUX_VERSION is requested
+if [ -n "${MANYLINUX_VERSION}" ]; then
+ BUILD_WHEELS_EXTRA_FLAGS="${BUILD_WHEELS_EXTRA_FLAGS[*]}" \
+ ITK_GIT_TAG=${ITK_GIT_TAG} \
+ MANYLINUX_VERSION=${MANYLINUX_VERSION} \
+ bash "${_ipp_dir}/scripts/dockcross-manylinux-build-wheels.sh" \
+ "${pyenvs[@]}"
+ exit $?
+fi
+
+## --
+# --
+# --
+# --
+case "$(uname -s)" in
+Darwin)
+ PLATFORM_PREFIX="macosx"
+ DASHBOARD_BUILD_DIRECTORY=${DASHBOARD_BUILD_DIRECTORY:=/Users/svc-dashboard/D/P}
+ ;;
+Linux)
+ PLATFORM_PREFIX="linux"
+ DASHBOARD_BUILD_DIRECTORY=${DASHBOARD_BUILD_DIRECTORY:=/work}
+ ;;
+ # POSIX build env NOT SUPPORTED for windows, Needs to be done in a .ps1 shell
+ # MINGW*|MSYS*|CYGWIN*)
+ # PLATFORM_PREFIX="windows"
+ # DASHBOARD_BUILD_DIRECTORY="C:\P"
+ # ;;
+*)
+ echo "Unsupported platform: $(uname -s)"
+ exit 1
+ ;;
+esac
+
+# Required environment variables
+required_vars=(
+ ITK_GIT_TAG
+ PLATFORM_PREFIX
+ DASHBOARD_BUILD_DIRECTORY
+
+)
+
+# Sanity Validation loop
+_missing_required=0
+for v in "${required_vars[@]}"; do
+ if [ -z "${!v:-}" ]; then
+ _missing_required=1
+ echo "ERROR: Required environment variable '$v' is not set or empty."
+ fi
+done
+if [ "${_missing_required}" -ne 0 ]; then
+ exit 1
+fi
+unset _missing_required
+
+if [ ! -d "${DASHBOARD_BUILD_DIRECTORY}" ]; then
+ # This is the expected directory for the cache, It may require creation with administrator credentials
+ mkdir -p "${DASHBOARD_BUILD_DIRECTORY}"
+fi
+if [ "${script_dir}" != "${DASHBOARD_BUILD_DIRECTORY}/ITKPythonPackage/scripts" ]; then
+ echo "ERROR: Github CI requires rigid directory structure, you may substitute the ITKPythonPackage organization if testing"
+ echo " RUN: cd ${DASHBOARD_BUILD_DIRECTORY}"
+ echo " RUN: git clone git@github.com:${ITKPYTHONPACKAGE_ORG}/ITKPythonPackage.git ${DASHBOARD_BUILD_DIRECTORY}/ITKPythonPackage"
+ echo " FOR DEVELOPMENT RUN: git checkout python_based_build_scripts"
+ echo " RUN: ${DASHBOARD_BUILD_DIRECTORY}/ITKPythonPackage/scripts/make_tarballs.sh"
+ exit 1
+fi
+
+export PIXI_HOME=${DASHBOARD_BUILD_DIRECTORY}/.pixi
+if [ ! -f "${PIXI_HOME}/bin/pixi" ]; then
+ #PIXI INSTALL
+ if [ ! -f "${PIXI_HOME}/bin/pixi" ]; then
+ curl -fsSL https://pixi.sh/install.sh | sh
+ export PATH="${PIXI_HOME}/bin:$PATH"
+ fi
+fi
+
+for pyenv in "${pyenvs[@]}"; do
+ cd "${DASHBOARD_BUILD_DIRECTORY}/ITKPythonPackage" || exit
+ "${PIXI_HOME}/bin/pixi" run -e "${PLATFORM_PREFIX}-${pyenv}" \
+ python3 "${DASHBOARD_BUILD_DIRECTORY}/ITKPythonPackage/scripts/build_wheels.py" \
+ --platform-env "${PLATFORM_PREFIX}-${pyenv}" \
+ --build-dir-root "${DASHBOARD_BUILD_DIRECTORY}/ITKPythonPackage-build" \
+ --itk-source-dir "${DASHBOARD_BUILD_DIRECTORY}/ITKPythonPackage-build/ITK" \
+ --itk-git-tag "${ITK_GIT_TAG}" \
+ "${BUILD_WHEELS_EXTRA_FLAGS[@]}"
+done
diff --git a/scripts/make_windows_zip.ps1 b/scripts/make_windows_zip.ps1
new file mode 100644
index 00000000..fe69477a
--- /dev/null
+++ b/scripts/make_windows_zip.ps1
@@ -0,0 +1,157 @@
+########################################################################
+# Build ITK Python wheel tarballs (build cache) on Windows.
+#
+# This is the Windows PowerShell equivalent of make_tarballs.sh.
+# POSIX shell is not supported for this workflow on Windows.
+#
+# This script builds the ITK core cache only — it has no knowledge of
+# external modules. Module-specific flags (--module-source-dir,
+# --module-dependencies-root-dir, --itk-module-deps, --lib-paths) are
+# intentionally absent; they belong only in the module wheel build script.
+#
+# Directory names are intentionally kept short to avoid Windows MAX_PATH
+# issues during deep CMake/compiler builds. Everything lives under one
+# root directory (C:\BDR) so no build artifacts are scattered at C:\:
+# ITKPythonPackage -> C:\BDR\IPP (scripts clone)
+# ITK source -> C:\BDR\ITK (ITK git checkout)
+# build root -> C:\BDR (build_wheels.py root; cached build lands at C:\BDR\build\ITK-windows-...)
+#
+# This script MUST be run from the canonical location:
+# C:\BDR\IPP\scripts\make_tarballs.ps1
+#
+# Typical usage:
+# > $env:ITK_GIT_TAG = "v6.0b02"
+# > .\make_tarballs.ps1
+#
+# Restrict to specific python versions by passing them as arguments:
+# > .\make_tarballs.ps1 py311
+#
+# -----------------------------------------------------------------------
+# Environment variables:
+#
+# `$env:ITK_GIT_TAG`
+# ITK git tag to build from. Falls back to v6.0b02 with loud warnings
+# if unset, matching the bash script behaviour.
+#
+########################################################################
+param (
+ [Parameter(ValueFromRemainingArguments)]
+ [string[]]$pyenvs
+)
+
+Set-StrictMode -Version Latest
+$ErrorActionPreference = "Stop"
+
+# Resolve python environments
+if (-not $pyenvs -or $pyenvs.Count -eq 0) {
+ $pyenvs = @("py310", "py311")
+}
+echo "Building for python environments: $($pyenvs -join ', ')"
+
+# Resolve ITK_GIT_TAG — loud warning if unset, matching bash behaviour
+$DEFAULT_ITK_GIT_TAG = "v6.0b02"
+if (-not $env:ITK_GIT_TAG) {
+ $warningLine = "===== WARNING: ITK_GIT_TAG not set, so defaulting to $DEFAULT_ITK_GIT_TAG"
+ echo "============================================================================="
+ 1..29 | ForEach-Object { echo $warningLine }
+ echo "============================================================================="
+ $env:ITK_GIT_TAG = $DEFAULT_ITK_GIT_TAG
+}
+$ITK_GIT_TAG = $env:ITK_GIT_TAG
+echo "ITK_GIT_TAG : $ITK_GIT_TAG"
+
+# Compute paths from this script's location.
+# Everything is contained under C:\BDR to keep all build artifacts in one
+# place and avoid spreading directories across the drive root.
+#
+# C:\BDR\ <- $BDR (single root for all build content)
+# C:\BDR\IPP\scripts\ <- $ScriptsDir (this file)
+# C:\BDR\IPP\ <- $IPPDir (ITKPythonPackage clone)
+# C:\BDR\ITK\ <- $ItkSourceDir (ITK git checkout)
+# C:\BDR\ <- $BuildDirRoot (build root; cached build lands at C:\BDR\build\ITK-windows-...)
+# C:\BDR\.pixi\ <- pixi home
+$BDR = "C:\BDR"
+$ScriptsDir = Split-Path -Parent $MyInvocation.MyCommand.Path
+$IPPDir = Split-Path -Parent $ScriptsDir
+$BuildScript = Join-Path $ScriptsDir "build_wheels.py"
+$ItkSourceDir = Join-Path $BDR "ITK"
+$BuildDirRoot = $BDR
+
+echo "BDR : $BDR"
+echo "IPPDir : $IPPDir"
+echo "ScriptsDir : $ScriptsDir"
+echo "ItkSourceDir : $ItkSourceDir"
+echo "BuildDirRoot : $BuildDirRoot"
+
+# Validate script is running from the expected canonical location
+$ExpectedScriptsDir = Join-Path $BDR "IPP\scripts"
+if ($ScriptsDir -ne $ExpectedScriptsDir) {
+ Write-Error @"
+ERROR: GitHub CI requires a rigid directory structure.
+Script found at : $ScriptsDir
+Expected location: $ExpectedScriptsDir
+
+ RUN: cd $BDR
+ RUN: git clone git@github.com:/ITKPythonPackage.git $BDR\IPP
+ FOR DEVELOPMENT: git checkout python_based_build_scripts
+ RUN: $ExpectedScriptsDir\make_windows_zip.ps1
+"@
+ exit 1
+}
+
+if (-not (Test-Path -LiteralPath $BuildScript)) {
+ throw "build_wheels.py not found at: $BuildScript"
+}
+
+# Create BDR if it doesn't exist
+# (may require administrator credentials on a fresh machine)
+if (-not (Test-Path -LiteralPath $BDR)) {
+ echo "Creating directory: $BDR"
+ New-Item -ItemType Directory -Path $BDR -Force | Out-Null
+}
+
+# Install pixi if not already present.
+# Python, Doxygen, and all build tools are provided by the pixi environment.
+$env:PIXI_HOME = "$BDR\.pixi"
+if (-not (Test-Path "$env:PIXI_HOME\bin\pixi.exe")) {
+ echo "Installing pixi..."
+ Invoke-WebRequest -Uri "https://pixi.sh/install.ps1" -OutFile "install-pixi.ps1"
+ powershell -ExecutionPolicy Bypass -File "install-pixi.ps1"
+}
+$env:Path = "$env:PIXI_HOME\bin;$env:Path"
+
+# Build each requested python environment.
+# Push-Location/finally ensures we always restore the caller's directory.
+Push-Location $IPPDir
+try {
+ foreach ($pyenv in $pyenvs) {
+ # Normalise any of: py311 / py3.11 / cp311 / 3.11 -> py311
+ $pySquashed = $pyenv -replace 'py|cp|\.', ''
+ $pyenv = "py$pySquashed"
+ $platformEnv = "windows-$pyenv"
+
+ echo ""
+ echo "========================================================"
+ echo "Building cache for platform env: $platformEnv"
+ echo "========================================================"
+
+ pixi run -e $platformEnv python $BuildScript `
+ --platform-env $platformEnv `
+ --build-itk-tarball-cache `
+ --build-dir-root $BuildDirRoot `
+ --itk-source-dir $ItkSourceDir `
+ --itk-git-tag $ITK_GIT_TAG `
+ --no-use-sudo `
+ --no-use-ccache
+
+ if ($LASTEXITCODE -ne 0) {
+ throw "build_wheels.py failed for $platformEnv (exit code $LASTEXITCODE)"
+ }
+ }
+}
+finally {
+ Pop-Location
+}
+
+echo ""
+echo "All tarball builds completed successfully."
diff --git a/scripts/oci_exe.sh b/scripts/oci_exe.sh
deleted file mode 100644
index f3d7cffb..00000000
--- a/scripts/oci_exe.sh
+++ /dev/null
@@ -1,23 +0,0 @@
-function ociExe() {
- # Check for OCI_EXE environmental variable
- if [[ -n "$OCI_EXE" && -x "$OCI_EXE" ]]; then
- echo "$OCI_EXE"
- return
- fi
-
- # Check for podman executable
- if which podman > /dev/null 2>&1; then
- echo "podman"
- return
- fi
-
- # Check for docker executable
- if which docker > /dev/null 2>&1; then
- echo "docker"
- return
- fi
-
- # If none of the above exist, return nothing
- echo "Could not find podman or docker executable" >&2
- exit 1
-}
\ No newline at end of file
diff --git a/scripts/publish_tarball_cache.py b/scripts/publish_tarball_cache.py
new file mode 100644
index 00000000..5ea1e350
--- /dev/null
+++ b/scripts/publish_tarball_cache.py
@@ -0,0 +1,126 @@
+"""Upload ITK build cache tarballs to a GitHub Release.
+
+Usage:
+ pixi run -e publish publish-tarball-cache --itk-package-version v6.0b02
+ pixi run -e publish publish-tarball-cache --itk-package-version v6.0b02 --create-release
+
+Authentication:
+ Set the GH_TOKEN environment variable, or run `gh auth login` beforehand.
+
+Cache files are expected at {build-dir-root}/../ITKPythonBuilds-*.tar.zst (POSIX)
+or {build-dir-root}/ITKPythonBuilds-*.zip (Windows).
+"""
+
+import argparse
+import subprocess
+import sys
+from pathlib import Path
+
+ITKPYTHONBUILDS_REPO = "InsightSoftwareConsortium/ITKPythonBuilds"
+
+
+def main() -> int:
+ parser = argparse.ArgumentParser(
+ description="Upload tarball caches to a GitHub Release on ITKPythonBuilds"
+ )
+ parser.add_argument(
+ "--build-dir-root",
+ type=Path,
+ default=Path(__file__).resolve().parent.parent.parent
+ / "ITKPythonPackage-build",
+ help="Root of the build directory (tarballs are in its parent). Default: ../ITKPythonPackage-build",
+ )
+ parser.add_argument(
+ "--itk-package-version",
+ required=True,
+ help="Release tag name, e.g. v6.0b02",
+ )
+ parser.add_argument(
+ "--repo",
+ default=ITKPYTHONBUILDS_REPO,
+ help=f"GitHub repository for the release (default: {ITKPYTHONBUILDS_REPO})",
+ )
+ parser.add_argument(
+ "--create-release",
+ action="store_true",
+ help="Create the GitHub release if it does not already exist",
+ )
+ args = parser.parse_args()
+
+ build_directory = Path(args.build_dir_root)
+ tarball_dir = build_directory.parent
+ # POSIX builds produce .tar.zst, Windows builds produce .zip in the build directory
+ tarballs = sorted(
+ list(tarball_dir.glob("ITKPythonBuilds-*.tar.zst"))
+ + list(
+ build_directory.glob("ITKPythonBuilds-*.zip")
+ ) # Windows builds will be in the build directory
+ )
+
+ if not tarballs:
+ print(
+ f"Error: No ITKPythonBuilds-*.tar.zst or .zip files found in {tarball_dir} or {build_directory}.",
+ file=sys.stderr,
+ )
+ return 1
+
+ print(
+ f"Found {len(tarballs)} cache file(s) in {tarball_dir} and {build_directory}:"
+ )
+ for tb in tarballs:
+ size_mb = tb.stat().st_size / (1024 * 1024)
+ print(f" {tb.name} ({size_mb:.1f} MB)")
+
+ tag = args.itk_package_version
+
+ # Check if the release exists
+ result = subprocess.run(
+ ["gh", "release", "view", tag, "--repo", args.repo],
+ capture_output=True,
+ text=True,
+ )
+ if result.returncode != 0:
+ if args.create_release:
+ print(f"\nCreating release '{tag}' on {args.repo}...")
+ create_result = subprocess.run(
+ [
+ "gh",
+ "release",
+ "create",
+ tag,
+ "--repo",
+ args.repo,
+ "--title",
+ tag,
+ "--notes",
+ f"ITK Python build cache for {tag}",
+ ],
+ )
+ if create_result.returncode != 0:
+ print("Error: Failed to create release.", file=sys.stderr)
+ return 1
+ else:
+ print(
+ f"Error: Failed to create release with code: {result.returncode}\nwith message:\n{result.stderr}",
+ file=sys.stderr,
+ )
+ return 1
+ else:
+ print(f"\nRelease '{tag}' exists on {args.repo}.")
+
+ # Upload each tarball (--clobber replaces existing assets with the same name)
+ for tb in tarballs:
+ print(f"Uploading {tb.name}...")
+ upload_result = subprocess.run(
+ ["gh", "release", "upload", tag, str(tb), "--repo", args.repo, "--clobber"],
+ )
+ if upload_result.returncode != 0:
+ print(f"Error: Failed to upload {tb.name}.", file=sys.stderr)
+ return 1
+
+ print("\nAll uploads complete.")
+ return 0
+
+
+if __name__ == "__main__":
+ raise SystemExit(main())
diff --git a/scripts/publish_wheels.py b/scripts/publish_wheels.py
new file mode 100644
index 00000000..e3e8f5f0
--- /dev/null
+++ b/scripts/publish_wheels.py
@@ -0,0 +1,93 @@
+"""Upload ITK Python wheels to PyPI or TestPyPI.
+
+Usage:
+ pixi run -e publish publish-wheels --dist-directory /path/to/dist
+ pixi run -e publish publish-wheels --dist-directory /path/to/dist --test
+
+Authentication:
+ Set TWINE_USERNAME and TWINE_PASSWORD environment variables.
+ For token-based auth:
+ TWINE_USERNAME=__token__
+ TWINE_PASSWORD=pypi-
+
+ Alternatively, configure ~/.pypirc (see .pypirc.example in the repo root).
+"""
+
+import argparse
+import subprocess
+import sys
+from pathlib import Path
+
+TESTPYPI_URL = "https://test.pypi.org/legacy/"
+
+
+def main() -> int:
+ parser = argparse.ArgumentParser(
+ description="Upload ITK wheels to PyPI or TestPyPI"
+ )
+ parser.add_argument(
+ "--dist-directory",
+ type=Path,
+ default=Path(__file__).resolve().parent.parent.parent
+ / "ITKPythonPackage-build/dist",
+ help="Root of the build dist directory containing dist/*.whl (default: ../ITKPythonPackage-build/dist)",
+ )
+ parser.add_argument(
+ "--test",
+ action="store_true",
+ help="Upload to TestPyPI instead of production PyPI",
+ )
+ parser.add_argument(
+ "--repository-url",
+ type=str,
+ default=None,
+ help="Custom repository URL (overrides --test)",
+ )
+ parser.add_argument(
+ "--skip-existing",
+ action="store_true",
+ help="Skip wheels that have already been uploaded",
+ )
+ args = parser.parse_args()
+
+ dist_dir = args.dist_directory
+ wheels = sorted(dist_dir.glob("*.whl"))
+
+ if not wheels:
+ print(f"Error: No .whl files found in {dist_dir}", file=sys.stderr)
+ return 1
+
+ print(f"Found {len(wheels)} wheel(s) in {dist_dir}:")
+ for w in wheels:
+ print(f" {w.name}")
+
+ # Validate wheel metadata before uploading
+ print("\nRunning twine check...")
+ result = subprocess.run(
+ ["twine", "check", *(str(w) for w in wheels)],
+ )
+ if result.returncode != 0:
+ print(
+ "Error: twine check failed. Fix metadata issues before uploading.",
+ file=sys.stderr,
+ )
+ return 1
+
+ # Build upload command
+ cmd = ["twine", "upload"]
+ if args.repository_url:
+ cmd += ["--repository-url", args.repository_url]
+ elif args.test:
+ cmd += ["--repository-url", TESTPYPI_URL]
+ if args.skip_existing:
+ cmd.append("--skip-existing")
+ cmd += [str(w) for w in wheels]
+
+ target = args.repository_url or (TESTPYPI_URL if args.test else "PyPI")
+ print(f"\nUploading to {target}...")
+ result = subprocess.run(cmd)
+ return result.returncode
+
+
+if __name__ == "__main__":
+ raise SystemExit(main())
diff --git a/scripts/pyproject.toml.in b/scripts/pyproject.toml.in
index 1ed3b17b..f583cc7e 100644
--- a/scripts/pyproject.toml.in
+++ b/scripts/pyproject.toml.in
@@ -9,7 +9,7 @@ name = "@PYPROJECT_NAME@"
version = "@PYPROJECT_VERSION@"
description = "@PYPROJECT_DESCRIPTION@"
-readme = "ITK-source/ITK/README.md"
+readme = "@ITK_SOURCE_README@"
license = {file = "LICENSE"}
authors = [
{ name = "Insight Software Consortium", email = "community@itk.org" },
@@ -39,7 +39,7 @@ classifiers = [
"Topic :: Scientific/Engineering :: Medical Science Apps.",
"Topic :: Software Development :: Libraries",
]
-requires-python = ">=3.9"
+requires-python = ">=3.10"
dependencies = [
@PYPROJECT_DEPENDENCIES@
]
@@ -96,7 +96,7 @@ sdist.include = ["CMakeLists.txt", "cmake/*.cmake", "README.md", "itkVersion.py"
sdist.exclude = ["scripts"]
# The Python tags. The default (empty string) will use the default Python
-# version. You can also set this to "cp37" to enable the CPython 3.7+ Stable ABI
+# version. You can also set this to "cp310" to enable the CPython 3.10+ Stable ABI
# / Limited API (only on CPython and if the version is sufficient, otherwise
# this has no effect). Or you can set it to "py3" or "py2.py3" to ignore Python
# ABI compatibility. The ABI tag is inferred from this tag.
diff --git a/scripts/pyproject_configure.py b/scripts/pyproject_configure.py
index 55ba9c2c..19b669a2 100755
--- a/scripts/pyproject_configure.py
+++ b/scripts/pyproject_configure.py
@@ -1,55 +1,48 @@
#!/usr/bin/env python
-
-"""CLI allowing to configure ``pyproject.toml`` found in ``ITKPythonPackage``
-source tree.
-
-Different version of ``pyproject.toml`` can be generated based on the value
-of the `wheel_name` positional parameter.
-
-Usage::
-
- pyproject_configure.py [-h] [--output-dir OUTPUT_DIR] wheel_name
-
- positional arguments:
- wheel_name
-
- optional arguments:
- -h, --help show this help message and exit
- --output-dir OUTPUT_DIR
- Output directory for configured 'pyproject.toml'
- (default: /work)
-
-
-Accepted values for `wheel_name` are ``itk`` and all values read from
-``WHEEL_NAMES.txt``.
-"""
-
import argparse
import os
import re
+import shutil
import sys
+from pathlib import Path
-sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
-
-PARAMETER_OPTION_DEFAULTS = {
- "indent": 0,
- "newline_if_set": False,
- "newline_indent": 0,
- "remove_line_if_empty": False,
-}
-
-PARAMETER_OPTIONS = {
- "PYPROJECT_PY_MODULES": {"indent": 8, "newline_if_set": True, "newline_indent": 4},
- "PYPROJECT_DEPENDENCIES": {"indent": 8, "remove_line_if_empty": True},
-}
+from packaging.version import Version
+from wheel_builder_utils import read_env_file
def parameter_option(key, option):
- """Return value of `option` associated with parameter `key`.
-
- If no option is found in `PARAMETER_OPTIONS`, default value from
- `PARAMETER_OPTION_DEFAULTS` is returned.
+ """Return a formatting option for a template parameter.
+
+ Parameters
+ ----------
+ key : str
+ Template parameter name (e.g. ``'PYPROJECT_PY_MODULES'``).
+ option : str
+ Option to look up (``'indent'``, ``'newline_if_set'``,
+ ``'newline_indent'``, or ``'remove_line_if_empty'``).
+
+ Returns
+ -------
+ int or bool
+ The option value from ``PARAMETER_OPTIONS`` if defined,
+ otherwise the default from ``PARAMETER_OPTION_DEFAULTS``.
"""
+ PARAMETER_OPTION_DEFAULTS = {
+ "indent": 0,
+ "newline_if_set": False,
+ "newline_indent": 0,
+ "remove_line_if_empty": False,
+ }
+
+ PARAMETER_OPTIONS = {
+ "PYPROJECT_PY_MODULES": {
+ "indent": 8,
+ "newline_if_set": True,
+ "newline_indent": 4,
+ },
+ "PYPROJECT_DEPENDENCIES": {"indent": 8, "remove_line_if_empty": True},
+ }
+
default = PARAMETER_OPTION_DEFAULTS.get(option)
if key not in PARAMETER_OPTIONS.keys():
return default
@@ -58,13 +51,24 @@ def parameter_option(key, option):
# Copied from scikit-ci/ci/utils.py
def indent(text, prefix, predicate=None):
- """Adds 'prefix' to the beginning of selected lines in 'text'.
- If 'predicate' is provided, 'prefix' will only be added to the lines
- where 'predicate(line)' is True. If 'predicate' is not provided,
- it will default to adding 'prefix' to all non-empty lines that do not
- consist solely of whitespace characters.
-
- Copied from textwrap.py available in python 3 (cpython/cpython@a2d2bef)
+ """Add *prefix* to the beginning of selected lines in *text*.
+
+ Copied from ``textwrap.py`` (cpython/cpython@a2d2bef).
+
+ Parameters
+ ----------
+ text : str
+ The multiline string to indent.
+ prefix : str
+ String prepended to each selected line.
+ predicate : callable, optional
+ Called with each line; *prefix* is added only when it returns
+ True. Defaults to adding *prefix* to all non-blank lines.
+
+ Returns
+ -------
+ str
+ The indented text.
"""
if predicate is None:
@@ -73,29 +77,51 @@ def predicate(line):
def prefixed_lines():
for line in text.splitlines(True):
- yield (prefix + line if predicate(line) else line)
+ yield prefix + line if predicate(line) else line
return "".join(prefixed_lines())
def list_to_str(list_, newline=True):
+ """Join a list of strings as quoted, comma-separated items.
+
+ Parameters
+ ----------
+ list_ : list[str]
+ Items to format.
+ newline : bool, optional
+ Use newline separators when True, spaces when False.
+
+ Returns
+ -------
+ str
+ Formatted string like ``'"a",\\n"b"'``.
+ """
sep = ", "
if newline:
sep = ",\n"
- return sep.join(['"%s"' % item for item in list_])
+ return sep.join([f'"{item}"' for item in list_])
def configure(template_file, parameters, output_file):
- """Configure `template_file` into `output_file` given a dictionary of
- `parameters`.
+ """Substitute ``@KEY@`` placeholders in *template_file* and write *output_file*.
+
+ Parameters
+ ----------
+ template_file : str or Path
+ Input template containing ``@KEY@`` placeholders.
+ parameters : dict[str, str]
+ Mapping of placeholder names to substitution values.
+ output_file : str or Path
+ Destination path for the configured file.
"""
updated_lines = []
- with open(template_file, "r") as file_:
+ with open(template_file) as file_:
lines = file_.readlines()
for line in lines:
append = True
for key in parameters.keys():
- value = parameters[key].strip()
+ value = str(parameters[key]).strip()
if (
key in line
and not value
@@ -107,8 +133,10 @@ def configure(template_file, parameters, output_file):
value = indent(value, block_indent)
newline_indent = " " * parameter_option(key, "newline_indent")
if value.strip() and parameter_option(key, "newline_if_set"):
- value = "\n%s\n%s" % (value, newline_indent)
- line = line.replace("@%s@" % key, value)
+ value = f"\n{value}\n{newline_indent}"
+ line = line.replace(f"@{key}@", value)
+ # Windows paths need to have backslashes escaped preserved in writing of files
+ line = line.replace("\\", "\\\\")
if append:
updated_lines.append(line)
@@ -117,16 +145,56 @@ def configure(template_file, parameters, output_file):
def from_group_to_wheel(group):
- return "itk-%s" % group.lower()
+ """Convert an ITK group name to its wheel package name.
+ Parameters
+ ----------
+ group : str
+ ITK group name (e.g. ``'Core'``, ``'Filtering'``).
-def update_wheel_pyproject_toml_parameters():
- global PYPROJECT_PY_PARAMETERS
- for wheel_name in get_wheel_names():
- params = dict(ITK_PYPROJECT_PY_PARAMETERS)
+ Returns
+ -------
+ str
+ Wheel name like ``'itk-core'``.
+ """
+ return f"itk-{group.lower()}"
+
+
+def update_wheel_pyproject_toml_parameters(
+ base_params: dict,
+ package_env_config: dict,
+ SCRIPT_NAME: str,
+ wheel_names: list,
+ wheel_dependencies: dict,
+):
+ """Build a mapping of wheel name to ``pyproject.toml`` template parameters.
+
+ This is a pure transformation and does not mutate global state.
+
+ Parameters
+ ----------
+ base_params : dict
+ Shared base parameters common to all wheels.
+ package_env_config : dict
+ Build environment configuration (ITK paths, versions, etc.).
+ SCRIPT_NAME : str
+ Name of the calling script, embedded in the generator field.
+ wheel_names : list[str]
+ Ordered list of wheel package names to generate parameters for.
+ wheel_dependencies : dict[str, list[str]]
+ Mapping from wheel name to its dependency list.
+
+ Returns
+ -------
+ dict[str, dict]
+ ``{wheel_name: parameters_dict}`` for each wheel.
+ """
+ PYPROJECT_PY_PARAMETERS = {}
+ for wheel_name in wheel_names:
+ params = dict(base_params)
# generator
- params["PYPROJECT_GENERATOR"] = "python %s '%s'" % (SCRIPT_NAME, wheel_name)
+ params["PYPROJECT_GENERATOR"] = f"python {SCRIPT_NAME} '{wheel_name}'"
# name
if wheel_name == "itk-meta":
@@ -182,18 +250,21 @@ def update_wheel_pyproject_toml_parameters():
# cmake_args
params["PYPROJECT_CMAKE_ARGS"] = list_to_str(
[
+ f"-DITK_SOURCE_DIR={package_env_config['ITK_SOURCE_DIR']}",
+ f"-DITK_GIT_TAG:STRING={package_env_config['ITK_GIT_TAG']}",
+ f"-DITK_PACKAGE_VERSION:STRING={package_env_config['ITK_PACKAGE_VERSION']}",
"-DITK_WRAP_unsigned_short:BOOL=ON",
"-DITK_WRAP_double:BOOL=ON",
"-DITK_WRAP_complex_double:BOOL=ON",
"-DITK_WRAP_IMAGE_DIMS:STRING=2;3;4",
"-DITK_WRAP_DOC:BOOL=ON",
- "-DITKPythonPackage_WHEEL_NAME:STRING=%s" % wheel_name,
+ f"-DITKPythonPackage_WHEEL_NAME:STRING={wheel_name}",
],
True,
)
# install_requires
- wheel_depends = get_wheel_dependencies()[wheel_name]
+ wheel_depends = list(wheel_dependencies[wheel_name])
# py_modules
if wheel_name != "itk-core":
@@ -205,35 +276,63 @@ def update_wheel_pyproject_toml_parameters():
PYPROJECT_PY_PARAMETERS[wheel_name] = params
+ return PYPROJECT_PY_PARAMETERS
-def get_wheel_names():
- with open(os.path.join(SCRIPT_DIR, "WHEEL_NAMES.txt"), "r") as _file:
- return [wheel_name.strip() for wheel_name in _file.readlines()]
+def get_wheel_names(IPP_BuildWheelsSupport_DIR: str):
+ """Read the ordered list of wheel names from ``WHEEL_NAMES.txt``.
-def get_version():
- from itkVersion import get_versions
+ Parameters
+ ----------
+ IPP_BuildWheelsSupport_DIR : str
+ Directory containing ``WHEEL_NAMES.txt``.
- version = get_versions()["package-version"]
- return version
+ Returns
+ -------
+ list[str]
+ Stripped wheel names, one per line.
+ """
+ with open(os.path.join(IPP_BuildWheelsSupport_DIR, "WHEEL_NAMES.txt")) as _file:
+ return [wheel_name.strip() for wheel_name in _file.readlines()]
def get_py_api():
- import sys
+ """Return the stable ABI tag for the running Python, or empty string.
+ Returns
+ -------
+ str
+ A tag like ``'cp311'`` for Python >= 3.11, or ``''`` otherwise.
+ """
+ # Return empty for Python < 3.11, otherwise a cp tag like 'cp311'
if sys.version_info < (3, 11):
return ""
- else:
- return "cp" + str(sys.version_info.major) + str(sys.version_info.minor)
+ return f"cp{sys.version_info.major}{sys.version_info.minor}"
-def get_wheel_dependencies():
- """Return a dictionary of ITK wheel dependencies."""
+def get_wheel_dependencies(SCRIPT_DIR: str, version: str, wheel_names: list):
+ """Parse ITK CMake files to build a wheel dependency graph.
+
+ Parameters
+ ----------
+ SCRIPT_DIR : str
+ Path to the ``scripts/`` directory.
+ version : str
+ PEP 440 version string pinned in each dependency.
+ wheel_names : list[str]
+ All known wheel names; used to build the ``itk-meta`` entry.
+
+ Returns
+ -------
+ dict[str, list[str]]
+ Mapping of wheel name to its list of pinned dependencies.
+ """
all_depends = {}
regex_group_depends = r"set\s*\(\s*ITK\_GROUP\_([a-zA-Z0-9\_\-]+)\_DEPENDS\s*([a-zA-Z0-9\_\-\s]*)\s*" # noqa: E501
pattern = re.compile(regex_group_depends)
- version = get_version()
- with open(os.path.join(SCRIPT_DIR, "..", "CMakeLists.txt"), "r") as file_:
+ with open(
+ os.path.join(SCRIPT_DIR, "..", "cmake/ITKPythonPackage_BuildWheels.cmake")
+ ) as file_:
for line in file_.readlines():
match = re.search(pattern, line)
if not match:
@@ -246,86 +345,226 @@ def get_wheel_dependencies():
all_depends[wheel] = _wheel_depends
all_depends["itk-meta"] = [
wheel_name + "==" + version
- for wheel_name in get_wheel_names()
+ for wheel_name in wheel_names
if wheel_name != "itk-meta"
]
all_depends["itk-meta"].append("numpy")
return all_depends
-SCRIPT_DIR = os.path.dirname(__file__)
-SCRIPT_NAME = os.path.basename(__file__)
-
-ITK_PYPROJECT_PY_PARAMETERS = {
- "PYPROJECT_GENERATOR": "python %s '%s'" % (SCRIPT_NAME, "itk"),
- "PYPROJECT_NAME": r"itk",
- "PYPROJECT_VERSION": get_version(),
- "PYPROJECT_CMAKE_ARGS": r"",
- "PYPROJECT_PY_API": get_py_api(),
- "PYPROJECT_PLATLIB": r"true",
- "PYPROJECT_PY_MODULES": list_to_str(
- [
- "itkBase",
- "itkConfig",
- "itkExtras",
- "itkHelpers",
- "itkLazy",
- "itkTemplate",
- "itkTypes",
- "itkVersion",
- "itkBuildOptions",
- ]
- ),
- "PYPROJECT_DOWNLOAD_URL": r"https://github.com/InsightSoftwareConsortium/ITK/releases",
- "PYPROJECT_DESCRIPTION": r"ITK is an open-source toolkit for multidimensional image analysis", # noqa: E501
- "PYPROJECT_LONG_DESCRIPTION": r"ITK is an open-source, cross-platform library that "
- "provides developers with an extensive suite of software "
- "tools for image analysis. Developed through extreme "
- "programming methodologies, ITK employs leading-edge "
- "algorithms for registering and segmenting "
- "multidimensional scientific images.",
- "PYPROJECT_EXTRA_KEYWORDS": r'"scientific", "medical", "image", "imaging"',
- "PYPROJECT_DEPENDENCIES": r"",
-}
-
-PYPROJECT_PY_PARAMETERS = {"itk": ITK_PYPROJECT_PY_PARAMETERS}
-
-update_wheel_pyproject_toml_parameters()
+def build_base_pyproject_parameters(
+ package_env_config: dict, SCRIPT_NAME: str, itk_package_version: str
+):
+ """Return the base ``pyproject.toml`` template parameters for ITK.
+
+ Parameters
+ ----------
+ package_env_config : dict
+ Build environment configuration.
+ SCRIPT_NAME : str
+ Name of the calling script.
+ itk_package_version : str
+ PEP 440 version string for the ITK packages.
+
+ Returns
+ -------
+ dict[str, str]
+ Base parameter mapping shared across all wheel configurations.
+ """
+ ITK_SOURCE_README: str = os.path.join(
+ package_env_config["ITK_SOURCE_DIR"], "README.md"
+ )
+ return {
+ "PYPROJECT_GENERATOR": f"python {SCRIPT_NAME} 'itk'",
+ "PYPROJECT_NAME": r"itk",
+ "PYPROJECT_VERSION": itk_package_version,
+ "PYPROJECT_CMAKE_ARGS": r"",
+ "PYPROJECT_PY_API": get_py_api(),
+ "PYPROJECT_PLATLIB": r"true",
+ "ITK_SOURCE_DIR": package_env_config["ITK_SOURCE_DIR"],
+ "ITK_SOURCE_README": ITK_SOURCE_README,
+ "PYPROJECT_PY_MODULES": list_to_str(
+ [
+ "itkBase",
+ "itkConfig",
+ "itkExtras",
+ "itkHelpers",
+ "itkLazy",
+ "itkTemplate",
+ "itkTypes",
+ "itkVersion",
+ "itkBuildOptions",
+ ]
+ ),
+ "PYPROJECT_DOWNLOAD_URL": r"https://github.com/InsightSoftwareConsortium/ITK/releases",
+ "PYPROJECT_DESCRIPTION": r"ITK is an open-source toolkit for multidimensional image analysis", # noqa: E501
+ "PYPROJECT_LONG_DESCRIPTION": r"ITK is an open-source, cross-platform library that "
+ "provides developers with an extensive suite of software "
+ "tools for image analysis. Developed through extreme "
+ "programming methodologies, ITK employs leading-edge "
+ "algorithms for registering and segmenting "
+ "multidimensional scientific images.",
+ "PYPROJECT_EXTRA_KEYWORDS": r'"scientific", "medical", "image", "imaging"',
+ "PYPROJECT_DEPENDENCIES": r"",
+ }
def main():
- # Defaults
- default_output_dir = os.path.abspath(os.path.join(SCRIPT_DIR, ".."))
-
# Parse arguments
+ SCRIPT_DIR = os.path.dirname(__file__)
parser = argparse.ArgumentParser(
- formatter_class=argparse.ArgumentDefaultsHelpFormatter
+ formatter_class=argparse.ArgumentDefaultsHelpFormatter,
+ description="""CLI allowing to configure ``pyproject.toml`` found in the `` ITKPythonPackage ``
+source tree.
+
+Different versions of ``pyproject.toml`` can be generated based on the value
+of the `wheel_name` positional parameter.
+
+Usage::
+
+ pyproject_configure.py [-h] [--output-dir OUTPUT_DIR] wheel_name
+
+ positional arguments:
+ wheel_name
+
+ optional arguments:
+ -h, --help show this help message and exit
+ --output-dir OUTPUT_DIR
+ Output directory for configured 'pyproject.toml'
+ (default: /work)
+
+Accepted values for `wheel_name` are ``itk`` and all values read from
+``WHEEL_NAMES.txt``.
+""",
)
parser.add_argument("wheel_name")
parser.add_argument(
"--output-dir",
type=str,
help="Output directory for configured 'pyproject.toml'",
- default=default_output_dir,
+ default=os.path.abspath(os.path.join(SCRIPT_DIR, "..")),
+ )
+ parser.add_argument(
+ "--build-dir-root",
+ type=str,
+ default=f"{SCRIPT_DIR}/../",
+ help="The root of the build resources.",
)
args = parser.parse_args()
- template = os.path.join(SCRIPT_DIR, "pyproject.toml.in")
- if args.wheel_name not in PYPROJECT_PY_PARAMETERS.keys():
- print("Unknown wheel name '%s'" % args.wheel_name)
+ print(f"Reading configuration settings from {args.env_file}")
+ package_env_config = read_env_file(args.env_file, args.build_dir_root)
+
+ configure_one_pyproject_file(
+ SCRIPT_DIR, package_env_config, args.output_dir, args.wheel_name
+ )
+
+
+def configure_one_pyproject_file(
+ SCRIPT_DIR: str | bytes, package_env_config, output_dir, wheel_name: str = "itk"
+):
+ """Generate a configured ``pyproject.toml`` for a single wheel.
+
+ Parameters
+ ----------
+ SCRIPT_DIR : str or bytes
+ Path to the ``scripts/`` directory containing templates.
+ package_env_config : dict
+ Build environment configuration.
+ output_dir : str or Path
+ Directory where ``pyproject.toml`` will be written.
+ wheel_name : str, optional
+ Which wheel to configure (default ``'itk'``).
+ """
+ # Version needs to be python PEP 440 compliant (no leading v)
+ PEP440_VERSION: str = package_env_config["ITK_PACKAGE_VERSION"].removeprefix("v")
+ try:
+ Version(
+ PEP440_VERSION
+ ) # Raise InvalidVersion exception if not PEP 440 compliant
+ except ValueError:
+ print(f"Invalid PEP 440 version: {PEP440_VERSION}")
+ sys.exit(1)
+
+ # Resolve script information locally
+
+ IPP_BuildWheelsSupport_DIR = os.path.join(SCRIPT_DIR, "..", "BuildWheelsSupport")
+ SCRIPT_NAME = os.path.basename(__file__)
+ # Write itkVersion.py file to report ITK version in python.
+ write_itkVersion_py(Path(output_dir) / "itkVersion.py", PEP440_VERSION)
+ # Copy LICENSE file needed for each wheel
+ shutil.copy(Path(IPP_BuildWheelsSupport_DIR) / "LICENSE", output_dir)
+
+ base_params = build_base_pyproject_parameters(
+ package_env_config, SCRIPT_NAME, PEP440_VERSION
+ )
+
+ wheel_names = get_wheel_names(IPP_BuildWheelsSupport_DIR)
+ wheel_dependencies = get_wheel_dependencies(
+ SCRIPT_DIR, base_params["PYPROJECT_VERSION"], wheel_names
+ )
+
+ PYPROJECT_PY_PARAMETERS = {"itk": dict(base_params)}
+ PYPROJECT_PY_PARAMETERS.update(
+ update_wheel_pyproject_toml_parameters(
+ base_params,
+ package_env_config,
+ SCRIPT_NAME,
+ wheel_names,
+ wheel_dependencies,
+ )
+ )
+
+ if wheel_name not in PYPROJECT_PY_PARAMETERS.keys():
+ print(f"Unknown wheel name '{wheel_name}'")
sys.exit(1)
# Configure 'pyproject.toml'
- output_file = os.path.join(args.output_dir, "pyproject.toml")
- configure(template, PYPROJECT_PY_PARAMETERS[args.wheel_name], output_file)
-
- # Configure or remove 'itk/__init__.py'
- # init_py = os.path.join(args.output_dir, "itk", "__init__.py")
- # if args.wheel_name in ["itk", "itk-core"]:
- # with open(init_py, 'w') as file_:
- # file_.write("# Stub required for package\n")
- # else:
- # if os.path.exists(init_py):
- # os.remove(init_py)
+ output_file = os.path.join(output_dir, "pyproject.toml")
+ print(f"Generating: {output_file}")
+ template = os.path.join(SCRIPT_DIR, "pyproject.toml.in")
+ configure(template, PYPROJECT_PY_PARAMETERS[wheel_name], output_file)
+
+
+def write_itkVersion_py(filename: str | Path, itk_package_version: str):
+ """Write an ``itkVersion.py`` file reporting the ITK package version.
+
+ Parameters
+ ----------
+ filename : str or Path
+ Output file path.
+ itk_package_version : str
+ PEP 440 version string to embed.
+ """
+ itk_version_python_code = f"""
+VERSION: str = '{itk_package_version}'
+
+def get_versions() -> str:
+ \"\"\"Returns versions for the ITK Python package.
+
+ from itkVersion import get_versions
+
+ # Returns the ITK repository version
+ get_versions()['version']
+
+ # Returns the package version. Since GitHub Releases do not support the '+'
+ # character in file names, this does not contain the local version
+ # identifier in nightly builds, i.e.
+ #
+ # '6.0.1.dev20251126'
+ #
+ # instead of
+ #
+ # '6.0.1.dev20251126+139.g922f2d9'
+ get_versions()['package-version']
+ \"\"\"
+
+ versions = {{}}
+ versions['version'] = VERSION
+ versions['package-version'] = VERSION.split('+')[0]
+ return versions
+"""
+ with open(filename, "w") as wfid:
+ wfid.write(itk_version_python_code)
if __name__ == "__main__":
diff --git a/scripts/update_python_version.py b/scripts/update_python_version.py
deleted file mode 100755
index f69207d3..00000000
--- a/scripts/update_python_version.py
+++ /dev/null
@@ -1,96 +0,0 @@
-#!/usr/bin/env python
-
-"""Update the ITKPythonPackage version based off the ITK Git nightly-master
-branch."""
-
-import argparse
-import sys
-import os
-import subprocess
-from datetime import datetime
-from packaging.version import Version
-
-argparser = argparse.ArgumentParser(description=__doc__)
-argparser.add_argument("itkSourceDir")
-
-args = argparser.parse_args()
-itkSourceDir = args.itkSourceDir
-if not os.path.exists(os.path.join(itkSourceDir, ".git")):
- print("itkSourceDir does not appear to be a git repository!")
- sys.exit(1)
-
-itkPythonPackageDir = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
-
-
-os.chdir(itkSourceDir)
-# "Wed Feb 8 15:21:09 2017"\n
-commitDate = subprocess.check_output(
- ["git", "show", "-s", "--date=local", '--format="%cd"']
-)
-# Wed Feb 8 15:21:09 2017
-commitDate = commitDate.strip()[1:-1]
-# Wed Feb 08 15:21:09 2017
-commitDate = commitDate.split(" ")
-commitDate[2] = "{:02d}".format(int(commitDate[2]))
-commitDate = " ".join(commitDate)
-# 2017-02-08
-commitDateDashes = datetime.strptime(commitDate, "%a %b %d %H:%M:%S %Y").strftime(
- "%Y-%m-%d"
-)
-# 20170208
-commitDate = commitDateDashes.replace("-", "")
-
-# v4.11.0-139-g922f2d9
-#
-revision = subprocess.check_output(["git", "describe", "--tags", "--long"])
-revision.strip()
-# 4.11.0-139-g922f2d9
-revision = revision[1:]
-version, numberOfCommits, gHash = revision.split("-")
-version = version.strip()
-numberOfCommits = numberOfCommits.strip()
-gHash = gHash.strip()
-
-pythonRevision = version
-if int(numberOfCommits) > 0:
- pythonRevision += ".dev"
- pythonRevision += commitDate
- pythonRevision += "+"
- pythonRevision += numberOfCommits
- pythonRevision += "."
- pythonRevision += gHash
-
-os.chdir(itkPythonPackageDir)
-itkVersionPath = os.path.join(itkPythonPackageDir, "itkVersion.py")
-
-Version(VERSION) # Raise InvalidVersion exception if not PEP 440 compliant
-
-if not os.path.exists(itkVersionPath):
- print("Expected file " + itkVersionPath + " not found!")
- sys.exit(1)
-with open(itkVersionPath, "r") as fp:
- lines = fp.readlines()
-with open(itkVersionPath, "w") as fp:
- for line in lines:
- if line.startswith("VERSION = "):
- fp.write("VERSION = '")
- fp.write(pythonRevision)
- fp.write("'\n")
- else:
- fp.write(line)
-
-
-with open("CMakeLists.txt", "r") as fp:
- lines = fp.readlines()
-with open("CMakeLists.txt", "w") as fp:
- for line in lines:
- if line.startswith(" # ITK nightly-master"):
- fp.write(" # ITK nightly-master ")
- fp.write(commitDateDashes)
- fp.write("\n")
- elif line.startswith(" set(ITK_GIT_TAG"):
- fp.write(' set(ITK_GIT_TAG "')
- fp.write(gHash[1:])
- fp.write('")\n')
- else:
- fp.write(line)
diff --git a/scripts/update_python_version.sh b/scripts/update_python_version.sh
deleted file mode 100755
index 9773056e..00000000
--- a/scripts/update_python_version.sh
+++ /dev/null
@@ -1,50 +0,0 @@
-#!/usr/bin/env bash
-
-# This script is use to update the version of ITK used by ITKPythonPackage. It
-# is run nightly by a system with push permissions to the
-#
-# git@github.com:InsightSoftwareConsortium/ITKPythonPackage.git
-#
-# repository.
-
-set -x -e
-
-workdir=/tmp/
-
-cd $workdir
-
-if test ! -d ITKNightlyMaster; then
- git clone --branch nightly-master \
- https://github.com/InsightSoftwareConsortium/ITK.git ITKNightlyMaster
-fi
-pushd ITKNightlyMaster/
-git checkout nightly-master
-git fetch
-git reset --hard origin/nightly-master
-ITK_SHA=$(git rev-parse --short HEAD)
-popd
-
-if test ! -d ITKPythonPackage; then
- git clone --branch master \
- git@github.com:InsightSoftwareConsortium/ITKPythonPackage.git ITKPythonPackage
-fi
-pushd ITKPythonPackage/
-git checkout master
-git fetch
-git reset --hard origin/master
-git config user.name 'Kitware Robot'
-git config user.email 'kwrobot@kitware.com'
-ITKPythonPackage_SHA=$(git rev-parse --short HEAD)
-./scripts/update_python_version.py ../ITKNightlyMaster
-git add -- CMakeLists.txt itkVersion.py
-git commit -m "ITK nightly version update
-
-This commit updates:
- (1) SHA used in CMakeLists.txt to checkout ITK sources
- (InsightSoftwareConsortium/ITK@${ITK_SHA})
- (2) VERSION variable set in itkVersion.py
-
-It was automatically generated by the script ``update_python_version.sh`` [1]
-
-[1] https://github.com/InsightSoftwareConsortium/ITKPythonPackage/blob/${ITKPythonPackage_SHA}/scripts/update_python_version.py"
-git push origin master
diff --git a/scripts/wheel_builder_utils.py b/scripts/wheel_builder_utils.py
new file mode 100644
index 00000000..1c40dc77
--- /dev/null
+++ b/scripts/wheel_builder_utils.py
@@ -0,0 +1,752 @@
+"""This module provides convenient function facilitating scripting.
+
+These functions have been copied from scikit-build project.
+See https://github.com/scikit-build/scikit-build
+"""
+
+import filecmp
+import os
+import re
+import shutil
+import subprocess
+import sys
+
+# from contextlib import contextmanager
+from functools import wraps
+from os import chdir as os_chdir
+from os import environ
+from pathlib import Path
+
+# @contextmanager
+# def push_env(**kwargs):
+# """This context manager allow to set/unset environment variables."""
+# saved_env = dict(os_environ)
+# for var, value in kwargs.items():
+# if value is not None:
+# os_environ[var] = value
+# elif var in os_environ:
+# del os_environ[var]
+# yield
+# os_environ.clear()
+# for saved_var, saved_value in saved_env.items():
+# os_environ[saved_var] = saved_value
+
+
+class ContextDecorator:
+ """A base class or mixin that enables context managers to work as
+ decorators."""
+
+ def __init__(self, **kwargs):
+ self.__dict__.update(kwargs)
+
+ def __enter__(self):
+ # Note: Returning self means that in "with ... as x", x will be self
+ return self
+
+ def __exit__(self, typ, val, traceback):
+ pass
+
+ def __call__(self, func):
+ @wraps(func)
+ def inner(*args, **kwds): # pylint:disable=missing-docstring
+ with self:
+ return func(*args, **kwds)
+
+ return inner
+
+
+class push_dir(ContextDecorator):
+ """Context manager to change current directory."""
+
+ def __init__(self, directory=None, make_directory=False):
+ """
+ :param directory:
+ Path to set as current working directory. If ``None``
+ is passed, current working directory is used instead.
+
+ :param make_directory:
+ If True, ``directory`` is created.
+ """
+ self.directory = None
+ self.make_directory = None
+ self.old_cwd = None
+ super().__init__(directory=directory, make_directory=make_directory)
+
+ def __enter__(self):
+ self.old_cwd = Path.cwd()
+ if self.directory:
+ if self.make_directory:
+ Path(self.directory).mkdir(parents=True, exist_ok=True)
+ os_chdir(self.directory)
+ return self
+
+ def __exit__(self, typ, val, traceback):
+ os_chdir(self.old_cwd)
+
+
+def _remove_tree(path: Path) -> None:
+ """Recursively delete a file or directory using pathlib only.
+
+ Parameters
+ ----------
+ path : Path
+ File or directory to remove. No error is raised if *path*
+ does not exist.
+ """
+ if not path.exists():
+ return
+ if path.is_file() or path.is_symlink():
+ try:
+ path.unlink()
+ except OSError:
+ pass
+ return
+ for child in path.iterdir():
+ _remove_tree(child)
+ try:
+ path.rmdir()
+ except OSError:
+ pass
+
+
+def read_env_file(
+ file_path: os.PathLike | str, build_dir_root: os.PathLike | str
+) -> dict[str, str]:
+ """Read a simple .env-style file and return a dict of key/value pairs.
+
+ Supported syntax:
+
+ - Blank lines and lines starting with ``#`` are ignored.
+ - Optional leading ``export`` prefix is stripped.
+ - ``KEY=VALUE`` pairs; surrounding single or double quotes are stripped.
+ - Whitespace around keys and the ``=`` is ignored.
+ - ``${BUILD_DIR_ROOT}`` in values is replaced with *build_dir_root*.
+
+ This function does not perform variable expansion or modify ``os.environ``.
+
+ Parameters
+ ----------
+ file_path : os.PathLike or str
+ Path to the ``.env`` file.
+ build_dir_root : os.PathLike or str
+ Value substituted for ``${BUILD_DIR_ROOT}`` placeholders in values.
+
+ Returns
+ -------
+ dict[str, str]
+ Parsed key/value pairs. Returns an empty dict if the file does
+ not exist or cannot be read.
+ """
+ result: dict[str, str] = {}
+ path = Path(file_path)
+ if not path.exists():
+ return result
+ try:
+ content = path.read_text(encoding="utf-8")
+ except Exception:
+ return result
+
+ for raw_line in content.splitlines():
+ line = raw_line.strip()
+ if not line or line.startswith("#"):
+ continue
+ if line.startswith("export "):
+ line = line[len("export ") :].lstrip()
+ if "=" not in line:
+ continue
+ key, value = line.split("=", 1)
+ key = key.strip()
+ value = value.strip()
+ value = value.replace("${BUILD_DIR_ROOT}", str(build_dir_root))
+ # Strip surrounding quotes if present
+ if (len(value) >= 2) and (
+ (value[0] == value[-1] == '"') or (value[0] == value[-1] == "'")
+ ):
+ value = value[1:-1]
+ result[key] = value
+ return result
+
+
+def _which(exe_name: str) -> Path | None:
+ """Locate an executable on ``PATH`` using pathlib.
+
+ A custom implementation is used because ``shutil.which`` does not
+ reliably resolve executables on Windows before Python 3.12.
+
+ Parameters
+ ----------
+ exe_name : str
+ Name (or path fragment) of the executable to find.
+
+ Returns
+ -------
+ Path or None
+ Absolute path to the first matching executable, or ``None`` if
+ not found.
+ """
+ # shutil.which only works on windows after python 3.12.
+ pathext: list[str] = environ.get("PATHEXT", ".EXE;.BAT;.CMD;.exe;.bat;.cmd").split(
+ ";"
+ )
+ paths: list[str] = environ.get("PATH", "").split(os.pathsep)
+ exe: Path = Path(exe_name)
+ candidates: list[Path] = (
+ [exe] if exe.suffix else [Path(exe_name + ext) for ext in pathext]
+ )
+ candidates = [exe] + candidates
+ for p in paths:
+ if not p:
+ continue
+ base = Path(p)
+ for c in candidates:
+ fp = base / c
+ try:
+ if fp.exists():
+ return fp
+ except OSError:
+ continue
+ return None
+
+
+def detect_platform() -> tuple[str, str]:
+ """Detect the current operating system and CPU architecture.
+
+ Returns
+ -------
+ tuple[str, str]
+ A ``(os_name, arch)`` pair where *os_name* is one of
+ ``'linux'``, ``'darwin'``, ``'windows'``, or ``'unknown'``, and
+ *arch* is a normalized architecture string (e.g. ``'x64'``,
+ ``'arm64'``, ``'x86_64'``, ``'aarch64'``).
+ """
+ uname = os.uname() if hasattr(os, "uname") else None
+ sysname = (
+ uname.sysname if uname else ("Windows" if os.name == "nt" else sys.platform)
+ )
+ machine = (
+ uname.machine
+ if uname
+ else (os.environ.get("PROCESSOR_ARCHITECTURE", "").lower())
+ )
+ os_name = (
+ "linux"
+ if sysname.lower().startswith("linux")
+ else (
+ "darwin"
+ if sysname.lower().startswith("darwin") or sys.platform == "darwin"
+ else ("windows" if os.name == "nt" else "unknown")
+ )
+ )
+ # Normalize machine
+ arch = machine
+ if os_name == "darwin":
+ if machine in ("x86_64",):
+ arch = "x86_64"
+ elif machine in ("arm64", "aarch64"):
+ arch = "arm64"
+ elif os_name == "linux":
+ if machine in ("x86_64",):
+ arch = "x64"
+ elif machine in ("i686", "i386"):
+ arch = "x86"
+ elif machine in ("aarch64",):
+ arch = "aarch64"
+ return os_name, arch
+
+
+def which_required(name: str) -> str:
+ path = shutil.which(name)
+ if not path:
+ raise RuntimeError(
+ f"MISSING: {name} not found in PATH; aborting until required executables can be found"
+ )
+ return path
+
+
+def run_commandLine_subprocess(
+ cmd: list[str | Path],
+ cwd: Path | None = None,
+ env: dict = None,
+ check: bool = False,
+) -> subprocess.CompletedProcess:
+ """Run a command via ``subprocess.run`` with logging.
+
+ Parameters
+ ----------
+ cmd : list[str or Path]
+ Command and arguments to execute.
+ cwd : Path, optional
+ Working directory for the subprocess.
+ env : dict, optional
+ Environment variables for the subprocess.
+ check : bool, optional
+ If True, raise ``RuntimeError`` on non-zero exit codes.
+
+ Returns
+ -------
+ subprocess.CompletedProcess
+ Completed process information including stdout, stderr, and
+ return code.
+
+ Raises
+ ------
+ RuntimeError
+ If *check* is True and the command exits with a non-zero code.
+ """
+ cmd = [str(x) for x in cmd]
+ print(f"Running >>>>>: {' '.join(cmd)} ; # in cwd={cwd} with check={check}\n")
+ completion_info = subprocess.run(
+ cmd,
+ cwd=str(cwd) if cwd else None,
+ capture_output=True,
+ text=True,
+ env=env if env else None,
+ )
+ if completion_info.returncode != 0 and check:
+ error_msg = "!~" * 40
+ if env:
+ error_msg += "ENVIRONMENT: ================="
+ for k, v in env.items():
+ error_msg += f"\n{k}={v}"
+ error_msg += "=============================="
+ if completion_info.stdout:
+ error_msg += f"\nStdout:\n {completion_info.stdout}"
+ if completion_info.stderr:
+ error_msg += f"\nStderr:\n {completion_info.stderr}"
+ error_msg += f"Command failed with exit code {completion_info.returncode}: {' '.join(cmd)}"
+ print(error_msg)
+ raise RuntimeError(error_msg)
+
+ return completion_info
+
+
+def git_describe_to_pep440(desc: str) -> str:
+ """
+ Convert `git describe --tags --long --dirty --always` output
+
+ # v6.0b03-3-g1a2b3c4
+ # │ | │ └── abbreviated commit hash
+ # │ | └────── commits since tag
+ # | └────────── pre-release type and number
+ # └────────────── nearest tag
+ to a PEP 440–compatible version string.
+
+ [N!]N(.N)*[{a|b|rc}N][.postN][.devN]+
+ 111122222233333333333444444445555555666666666666
+ 1 Epoch segment: N!
+ 2 Release segment: N(.N)*
+ 3 Pre-release segment: {a|b|rc}N
+ 4 Post-release segment: .postN
+ 5 Development release segment: .devN
+ 6 local info not used in version ordering. I.e. ignored by package resolution rules
+ """
+ desc = desc.strip()
+ semver_format = "0.0.0"
+
+ m = re.match(
+ r"^(v)*(?P\d+)(?P\.\d+)(?P\.\d+)*(?Pa|b|rc|alpha|beta)*0*(?P\d*)-*(?P\d*)-*g*(?P[0-9a-fA-F]+)*(?P.dirty)*$",
+ desc,
+ )
+ if m:
+ groupdict = m.groupdict()
+
+ semver_format = (
+ f"{groupdict.get('majorver','')}" + f"{groupdict.get('minor','')}"
+ )
+ patch = groupdict.get("patch", None)
+ if patch:
+ semver_format += f"{patch}"
+ else:
+ semver_format += ".0"
+
+ prereleasemapping = {
+ "alpha": "a",
+ "a": "a",
+ "beta": "b",
+ "b": "b",
+ "rc": "rc",
+ "": "",
+ }
+ prerelease_name = prereleasemapping.get(groupdict.get("pretype", ""), None)
+ prerelnum = groupdict.get("prerelnum", None)
+ if prerelease_name and prerelnum and len(prerelease_name) > 0:
+ semver_format += f"{prerelease_name}{prerelnum}"
+ posttagcount = groupdict.get("posttagcount", None)
+ dirty = groupdict.get("dirty", None)
+ if (
+ len(posttagcount) > 0
+ and int(posttagcount) == 0
+ and (dirty is None or len(dirty) == 0)
+ ):
+ # If exactly on a tag, then do not add post, or sha
+ return semver_format
+ else:
+ if posttagcount and int(posttagcount) > 0:
+ semver_format += f".post{posttagcount}"
+ sha = groupdict.get("sha", None)
+ if sha:
+ semver_format += f"+g{sha.lower()}"
+ if dirty:
+ semver_format += ".dirty"
+ return semver_format
+
+
+# def debug(msg: str, do_print=False) -> None:
+# """Print *msg* only when *do_print* is True."""
+# if do_print:
+# print(msg)
+#
+#
+# def parse_kv_overrides(pairs: list[str]) -> dict[str, str]:
+# """Parse a list of ``KEY=VALUE`` strings into a dict.
+#
+# A value of ``"UNSET"`` is stored as ``None`` so callers can remove
+# the key from a target mapping.
+#
+# Parameters
+# ----------
+# pairs : list[str]
+# Strings of the form ``KEY=VALUE``.
+#
+# Returns
+# -------
+# dict[str, str]
+# Parsed overrides.
+#
+# Raises
+# ------
+# SystemExit
+# If an entry is not a valid ``KEY=VALUE`` pair or the key name
+# is invalid.
+# """
+# result: dict[str, str] = {}
+# for kv in pairs:
+# if "=" not in kv:
+# raise SystemExit(f"ERROR: Trailing argument '{kv}' is not KEY=VALUE")
+# key, value = kv.split("=", 1)
+# if not key or not re.match(r"^[A-Za-z_][A-Za-z0-9_]*$", key):
+# raise SystemExit(f"ERROR: Invalid variable name '{key}' in '{kv}'")
+# if value == "UNSET":
+# # Explicitly remove if present later
+# result[key] = None # type: ignore
+# else:
+# result[key] = value
+# return result
+
+
+# def get_git_id(
+# repo_dir: Path, pixi_exec_path, env, backup_version: str = "v0.0.0"
+# ) -> str | None:
+# """Return a human-readable Git identifier for *repo_dir*.
+#
+# Tries, in order: exact tag, branch name, short commit hash.
+# Falls back to *backup_version* when none of these succeed.
+#
+# Parameters
+# ----------
+# repo_dir : Path
+# Root of the Git repository.
+# pixi_exec_path : Path or str
+# Path to the pixi executable (unused but kept for API compat).
+# env : dict
+# Environment variables passed to Git subprocesses.
+# backup_version : str, optional
+# Fallback identifier returned when Git queries fail.
+#
+# Returns
+# -------
+# str or None
+# A tag, branch name, short hash, or *backup_version*.
+# """
+# # 1. exact tag
+# try:
+# run_result = run_commandLine_subprocess(
+# ["git", "describe", "--tags", "--exact-match"],
+# cwd=repo_dir,
+# env=env,
+# check=False,
+# )
+#
+# if run_result.returncode == 0:
+# return run_result.stdout.strip()
+# except subprocess.CalledProcessError:
+# pass
+# # 2. branch
+# try:
+# run_result = run_commandLine_subprocess(
+# ["git", "rev-parse", "--abbrev-ref", "HEAD"],
+# cwd=repo_dir,
+# env=env,
+# )
+# branch = run_result.stdout.strip()
+# if run_result.returncode == 0 and branch != "HEAD":
+# return branch
+# except subprocess.CalledProcessError:
+# pass
+# # 3. short hash
+# try:
+# run_result = run_commandLine_subprocess(
+# ["git", "rev-parse", "--short", "HEAD"],
+# cwd=repo_dir,
+# env=env,
+# )
+# short_version = run_result.stdout.strip()
+# if run_result.returncode == 0 and short_version != "HEAD":
+# return short_version
+# except subprocess.CalledProcessError:
+# pass
+#
+# # 4. punt and give dummy backup_version identifier
+# if not (repo_dir / ".git").is_dir():
+# if (repo_dir / ".git").is_file():
+# print(
+# f"WARNING: {str(repo_dir)} is a secondary git worktree, and may not resolve from within dockcross build"
+# )
+# return backup_version
+# print(f"ERROR: {repo_dir} is not a primary git repository")
+# return backup_version
+
+
+def compute_itk_package_version(
+ itk_dir: Path, itk_git_tag: str, pixi_exec_path, env
+) -> str:
+ """Compute a PEP 440 version string for the ITK package.
+
+ Fetches tags, checks out *itk_git_tag*, and runs
+ ``git describe --tags --long --dirty --always`` to produce a version
+ via `git_describe_to_pep440`.
+
+ Parameters
+ ----------
+ itk_dir : Path
+ Path to the ITK source repository.
+ itk_git_tag : str
+ Git tag, branch, or commit to check out before describing.
+ pixi_exec_path : Path or str
+ Path to the pixi executable (unused but kept for API compat).
+ env : dict
+ Environment variables passed to Git subprocesses.
+
+ Returns
+ -------
+ str
+ PEP 440-compliant version string.
+ """
+ # Try to compute from git describe
+ try:
+ run_commandLine_subprocess(
+ ["git", "fetch", "--tags"],
+ cwd=itk_dir,
+ env=env,
+ )
+ try:
+ run_commandLine_subprocess(
+ ["git", "checkout", itk_git_tag],
+ cwd=itk_dir,
+ env=env,
+ )
+ except Exception as e:
+ print(
+ f"WARNING: Failed to checkout {itk_git_tag}, reverting to 'main': {e}"
+ )
+ itk_git_tag = "main"
+ run_commandLine_subprocess(
+ ["git", "checkout", itk_git_tag],
+ cwd=itk_dir,
+ env=env,
+ )
+ desc = run_commandLine_subprocess(
+ [
+ "git",
+ "describe",
+ "--tags",
+ "--long",
+ "--dirty",
+ "--always",
+ ],
+ cwd=itk_dir,
+ env=env,
+ ).stdout.strip()
+ version = git_describe_to_pep440(desc)
+ except subprocess.CalledProcessError:
+ version = itk_git_tag.lstrip("v")
+
+ return version
+
+
+def default_manylinux(
+ manylinux_version: str, os_name: str, arch: str, env: dict[str, str]
+) -> tuple[str, str, str]:
+ """Resolve default manylinux container image details.
+
+ Parameters
+ ----------
+ manylinux_version : str
+ Manylinux specification (e.g. ``'_2_28'``, ``'_2_34'``).
+ os_name : str
+ Operating system name (only ``'linux'`` triggers resolution).
+ arch : str
+ Target architecture (``'x64'``, ``'aarch64'``).
+ env : dict[str, str]
+ Environment variables that may override image defaults
+ (``IMAGE_TAG``, ``CONTAINER_SOURCE``, ``MANYLINUX_IMAGE_NAME``).
+
+ Returns
+ -------
+ tuple[str, str, str]
+ ``(image_tag, image_name, container_source)``.
+
+ Raises
+ ------
+ RuntimeError
+ If *manylinux_version* or *arch* is unrecognized.
+ """
+ image_tag = env.get("IMAGE_TAG", "")
+ container_source = env.get("CONTAINER_SOURCE", "")
+ image_name = env.get("MANYLINUX_IMAGE_NAME", "")
+
+ if os_name == "linux":
+ if arch == "x64" and manylinux_version == "_2_34":
+ image_tag = image_tag or "latest"
+ elif arch == "x64" and manylinux_version == "_2_28":
+ image_tag = image_tag or "20250913-6ea98ba"
+ elif arch == "aarch64" and manylinux_version == "_2_28":
+ image_tag = image_tag or "2025.08.12-1"
+ elif manylinux_version == "":
+ image_tag = ""
+ else:
+ raise RuntimeError(
+ f"FAILURE: Unknown manylinux version {manylinux_version}"
+ )
+
+ if arch == "x64":
+ image_name = (
+ image_name or f"manylinux{manylinux_version}-{arch}:{image_tag}"
+ )
+ container_source = container_source or f"docker.io/dockcross/{image_name}"
+ elif arch == "aarch64":
+ image_name = (
+ image_name or f"manylinux{manylinux_version}_{arch}:{image_tag}"
+ )
+ container_source = container_source or f"quay.io/pypa/{image_name}"
+ else:
+ raise RuntimeError(f"Unknown target architecture {arch}")
+
+ return image_tag, image_name, container_source
+
+
+def resolve_oci_exe(env: dict[str, str]) -> str:
+ """Find an OCI container runtime (docker, podman, or nerdctl).
+
+ Checks ``OCI_EXE`` in *env* first, then probes ``PATH`` for known
+ runtimes. Defaults to ``'docker'`` if nothing is found.
+
+ Parameters
+ ----------
+ env : dict[str, str]
+ Environment variables; ``OCI_EXE`` is checked first.
+
+ Returns
+ -------
+ str
+ Name or path of the OCI runtime executable.
+ """
+ if env.get("OCI_EXE"):
+ return env["OCI_EXE"]
+ for cand in ("docker", "podman", "nerdctl"):
+ if _which(cand): # NOTE shutil.which ALWAYS RETURNS NONE ON WINDOWS before 3.12
+ return cand
+ # Default to docker name if nothing found
+ return "docker"
+
+
+# def cmake_compiler_defaults(build_dir: Path) -> tuple[str | None, str | None]:
+# info = build_dir / "cmake_system_information"
+# if not info.exists():
+# try:
+# out = run_commandLine_subprocess(["cmake", "--system-information"]).stdout
+# info.write_text(out, encoding="utf-8")
+# except Exception as e:
+# print(f"WARNING: Failed to generate cmake_system_information: {e}")
+# return None, None
+# text = info.read_text(encoding="utf-8", errors="ignore")
+# cc = None
+# cxx = None
+# for line in text.splitlines():
+# if "CMAKE_C_COMPILER == " in line:
+# parts = re.split(r"\s+", line.strip())
+# if len(parts) >= 4:
+# cc = parts[3]
+# if "CMAKE_CXX_COMPILER == " in line:
+# parts = re.split(r"\s+", line.strip())
+# if len(parts) >= 4:
+# cxx = parts[3]
+# return cc, cxx
+
+
+def give_relative_path(bin_exec: Path, build_dir_root: Path) -> str:
+ bin_exec = Path(bin_exec).resolve()
+ build_dir_root = Path(build_dir_root).resolve()
+ if bin_exec.is_relative_to(build_dir_root):
+ return "${BUILD_DIR_ROOT}" + os.sep + str(bin_exec.relative_to(build_dir_root))
+ return str(bin_exec)
+
+
+def safe_copy_if_different(src: Path, dst: Path) -> None:
+ """Copy file only if destination is missing or contents differ.
+
+ This avoids unnecessary overwrites and timestamp churn when files are identical.
+ """
+ src = Path(src)
+ dst = Path(dst)
+ if not dst.exists():
+ dst.parent.mkdir(parents=True, exist_ok=True)
+ shutil.copyfile(src, dst)
+ return
+ try:
+ same = filecmp.cmp(src, dst, shallow=False)
+ except Exception as e:
+ # On any comparison failure, fall back to copying to be safe
+ same = False
+ print(f"WARNING: Failed to compare {src} to {dst}: {e}")
+ if not same:
+ shutil.copyfile(src, dst)
+
+
+def get_default_platform_build(default_python_version: str = "py311") -> str:
+ """Return a default ``-`` build identifier.
+
+ Inspects the ``PIXI_ENVIRONMENT_NAME`` environment variable first;
+ falls back to ``sys.platform`` detection.
+
+ Parameters
+ ----------
+ default_python_version : str, optional
+ Python version suffix used when not running inside pixi
+ (default ``'py311'``).
+
+ Returns
+ -------
+ str
+ A string like ``'manylinux_2_28-py311'`` or ``'macosx-py311'``.
+ """
+ from_pixi = os.environ.get("PIXI_ENVIRONMENT_NAME", None)
+ if from_pixi and "-" in from_pixi:
+ manylinux_pixi_to_pattern_renaming: dict[str, str] = {
+ "manylinux228": "manylinux_2_28",
+ "manylinux234": "manylinux_2_34",
+ }
+ platform_prefix: str = from_pixi.split("-")[0]
+ python_version: str = from_pixi.split("-")[1]
+ platform_prefix = manylinux_pixi_to_pattern_renaming.get(
+ platform_prefix, platform_prefix
+ )
+ return f"{platform_prefix}-{python_version}"
+ else:
+ if sys.platform == "darwin":
+ return f"macosx-{default_python_version}"
+ elif sys.platform.startswith("linux"):
+ return f"linux-{default_python_version}"
+ elif sys.platform == "win32":
+ return f"windows-{default_python_version}"
+ return f"unknown-{default_python_version}"
diff --git a/scripts/windows-build-tarball.ps1 b/scripts/windows-build-tarball.ps1
deleted file mode 100644
index dab4f09f..00000000
--- a/scripts/windows-build-tarball.ps1
+++ /dev/null
@@ -1,8 +0,0 @@
-# This script creates a tarball of the ITK Python package build tree. It is
-# downloaded by the external module build scripts and used to build their
-# Python package on GitHub CI services.
-
-cd C:\P\
-Remove-Item IPP\dist\*
-C:\7-Zip\7z.exe a -t7z -r 'C:\P\ITKPythonBuilds-windows.zip' -w 'C:\P\IPP'
-# C:\7-Zip\7z.exe a -t7z -mx=9 -mfb=273 -ms -md=31 -myx=9 -mtm=- -mmt -mmtf -md=1536m -mmf=bt3 -mmc=10000 -mpb=0 -mlc=0 -r 'C:\P\ITKPythonBuilds-windows.zip' -w 'C:\P\IPP'
diff --git a/scripts/windows-download-cache-and-build-module-wheels.ps1 b/scripts/windows-download-cache-and-build-module-wheels.ps1
index 0d7b8fe2..512ca641 100644
--- a/scripts/windows-download-cache-and-build-module-wheels.ps1
+++ b/scripts/windows-download-cache-and-build-module-wheels.ps1
@@ -1,134 +1,271 @@
########################################################################
-# Pull build dependencies and build an ITK external module.
+# Pull build dependencies and build an ITK external module on Windows.
#
-# This script must be run in an x64 Developer Powershell.
+# This script must be run in an x64 Developer PowerShell.
# See https://learn.microsoft.com/en-us/visualstudio/ide/reference/command-prompt-powershell?view=vs-2022#developer-powershell
#
# -----------------------------------------------------------------------
-# Positional parameters:
-# - 0th parameter or -python_version_minor option: Python minor version.
+# Positional parameters / named options:
+#
+# -python_version_minor Python minor version (required).
# For instance, for Python 3.11:
-# > windows-download-cache-and-build-module-wheels.ps1 11
-# or equivalently:
# > windows-download-cache-and-build-module-wheels.ps1 -python_version_minor 11
+# or positionally:
+# > windows-download-cache-and-build-module-wheels.ps1 11
#
-# - 1st parameter or -setup_options: pyproject.toml options.
-# For instance, for Python 3.11, excluding nvcuda.dll during packaging:
-# > windows-download-cache-and-build-module-wheels.ps1 11 "--exclude-libs nvcuda.dll"
-# or equivalently:
-# > windows-download-cache-and-build-module-wheels.ps1 -python_version_minor 11 -setup_options "--exclude-libs nvcuda.dll"
-#
-# - 2nd parameter or -cmake_options: CMake options passed to pyproject.tom for project configuration.
-# For instance, for Python 3.11, excluding nvcuda.dll during packaging
-# and setting RTK_USE_CUDA ON during configuration:
-# > windows-download-cache-and-build-module-wheels.ps1 11 "--exclude-libs nvcuda.dll" "-DRTK_USE_CUDA:BOOL=ON"
-# or equivalently:
-# > windows-download-cache-and-build-module-wheels.ps1 -python_version_minor 11 -setup_options "--exclude-libs nvcuda.dll" -cmake-options "-DRTK_USE_CUDA:BOOL=ON"
+# -setup_options pyproject.toml options forwarded to the build script.
+# For instance, to exclude a library during packaging:
+# > ... -setup_options "--exclude-libs nvcuda.dll"
#
+# -cmake_options CMake options passed to pyproject.toml for project configuration.
+# For instance:
+# > ... -cmake_options "-DRTK_USE_CUDA:BOOL=ON"
#
# -----------------------------------------------------------------------
# Environment variables used in this script:
#
-# `$env:ITK_PACKAGE_VERSION`: Tag for ITKPythonBuilds build archive to use
+# `$env:ITK_PACKAGE_VERSION`
+# Tag for the ITKPythonBuilds archive to download/use. Required.
#
-# `$env:ITKPYTHONPACKAGE_TAG`: Tag for ITKPythonPackage build scripts to use.
-# If ITKPYTHONPACKAGE_TAG is empty then the default scripts distributed
-# with the ITKPythonBuilds archive will be used.
+# `$env:ITKPYTHONPACKAGE_TAG`
+# Tag for ITKPythonPackage build scripts to use.
+# If empty, the scripts bundled in the archive will be used.
#
-# `$env:ITKPYTHONPACKAGE_ORG`: Github organization or user to use for ITKPythonPackage
-# build script source. Default is InsightSoftwareConsortium.
+# `$env:ITKPYTHONPACKAGE_ORG`
+# GitHub organization/user for ITKPythonPackage. Default: InsightSoftwareConsortium.
# Ignored if ITKPYTHONPACKAGE_TAG is empty.
#
-# `$env:ITK_MODULE_PREQ`: Delimited list of ITK module dependencies to build before building the target module.
-# Format is `/@:/@:...`.
-# For instance, `export ITK_MODULE_PREQ=InsightSoftwareConsortium/ITKMeshToPolyData@v0.10.0`
+# `$env:ITK_MODULE_PREQ`
+# Colon-delimited list of ITK module dependencies.
+# Format: `/@:/@:...`
+# Example: `InsightSoftwareConsortium/ITKMeshToPolyData@v0.10.0`
+# Passed directly to build_wheels.py via --itk-module-deps.
+#
+# `$env:MODULE_SRC_DIRECTORY`
+# Path to the ITK external module source. Defaults to the directory
+# containing this script.
#
########################################################################
param (
[int]$python_version_minor,
- [string]$setup_options,
- [string]$cmake_options
+ [string]$setup_options = "",
+ [string]$cmake_options = ""
)
-$pythonArch = "64"
-$pythonVersion = "3.$python_version_minor"
-echo "Pulling Python $pythonVersion-x$pythonArch"
-iex ((new-object net.webclient).DownloadString('https://raw.githubusercontent.com/scikit-build/scikit-ci-addons/master/windows/install-python.ps1'))
+Set-StrictMode -Version Latest
+$ErrorActionPreference = "Stop"
-if (-not $env:ITK_PACKAGE_VERSION) { $env:ITK_PACKAGE_VERSION = 'v5.4.0' }
-echo "Fetching build archive $env:ITK_PACKAGE_VERSION"
-if (Test-Path C:\P) {
- Remove-Item -Recurse -Force C:\P
+# Validate required inputs
+if (-not $python_version_minor) {
+ Write-Error "ERROR: -python_version_minor is required. Example: -python_version_minor 11"
+ exit 1
}
-if (-not (Test-Path ITKPythonBuilds-windows.zip)) {
- Invoke-WebRequest -Uri "https://github.com/InsightSoftwareConsortium/ITKPythonBuilds/releases/download/$env:ITK_PACKAGE_VERSION/ITKPythonBuilds-windows.zip" -OutFile "ITKPythonBuilds-windows.zip"
+if (-not $env:ITK_PACKAGE_VERSION) {
+ Write-Error "ERROR: `$env:ITK_PACKAGE_VERSION must be set before running this script."
+ exit 1
}
-7z x ITKPythonBuilds-windows.zip -oC:\P -aoa -r
-# Optional: Update ITKPythonPackage build scripts
-if ($env:ITKPYTHONPACKAGE_TAG) {
- if(-not $env:ITKPYTHONPACKAGE_ORG) {
- $env:ITKPYTHONPACKAGE_ORG="InsightSoftwareConsortium"
+# Resolve configuration
+$MODULE_SRC_DIRECTORY = if ($env:MODULE_SRC_DIRECTORY) {
+ $env:MODULE_SRC_DIRECTORY
+} else {
+ $PSScriptRoot
+}
+echo "MODULE_SRC_DIRECTORY: $MODULE_SRC_DIRECTORY"
+
+$ITK_PACKAGE_VERSION = $env:ITK_PACKAGE_VERSION
+# For backwards compatibility when the ITK_GIT_TAG was required to match the ITK_PACKAGE_VERSION
+$ITK_GIT_TAG = if ($env:ITK_GIT_TAG) { $env:ITK_GIT_TAG } else { $ITK_PACKAGE_VERSION }
+$ITKPYTHONPACKAGE_ORG = if ($env:ITKPYTHONPACKAGE_ORG) { $env:ITKPYTHONPACKAGE_ORG } else { "InsightSoftwareConsortium" }
+$ITKPYTHONPACKAGE_TAG = if ($env:ITKPYTHONPACKAGE_TAG) { $env:ITKPYTHONPACKAGE_TAG } else { "" }
+
+$DASHBOARD_BUILD_DIRECTORY = "C:\BDR"
+$platformEnv = "windows-py3$python_version_minor"
+
+echo "Python version : 3.$python_version_minor"
+echo "ITK_PACKAGE_VERSION: $ITK_PACKAGE_VERSION"
+echo "ITK_GIT_TAG : $ITK_GIT_TAG"
+echo "Platform env : $platformEnv"
+
+# ---------------------------------------------------------------------------
+# Check for conda/pixi-provided ITK (libitk-wrapping package).
+# When available, skip the archive download entirely.
+# ---------------------------------------------------------------------------
+$condaItkDir = $null
+foreach ($prefixVar in @("CONDA_PREFIX", "PIXI_ENVIRONMENT_DIR")) {
+ $prefix = [System.Environment]::GetEnvironmentVariable($prefixVar)
+ if ($prefix -and (Test-Path "$prefix\lib\cmake")) {
+ foreach ($candidate in (Get-ChildItem "$prefix\lib\cmake" -Directory -Filter "ITK-*" -ErrorAction SilentlyContinue)) {
+ if (Test-Path "$($candidate.FullName)\ITKConfig.cmake") {
+ $condaItkDir = $candidate.FullName
+ echo "Detected conda-installed ITK at $condaItkDir (via `$$prefixVar)"
+ break
+ }
+ }
+ if ($condaItkDir) { break }
}
+}
- echo "Updating build scripts to $env:ITKPYTHONPACKAGE_ORG/ITKPythonPackage@$env:ITKPYTHONPACKAGE_TAG"
+if ($condaItkDir) {
+ echo "Using conda-installed ITK; skipping archive download."
+ # Use local ITKPythonPackage scripts
+ $ippDir = $PSScriptRoot | Split-Path
+} else {
- pushd C:\P
- git clone "https://github.com/$env:ITKPYTHONPACKAGE_ORG/ITKPythonPackage.git" "IPP-tmp"
- pushd "IPP-tmp"
- git checkout "$env:ITKPYTHONPACKAGE_TAG"
- git status
- popd
+# Install pixi and required global tools
+# NOTE: Python and Doxygen are provided by the pixi environment; no need to
+# install them separately here.
+$env:PIXI_HOME = "$DASHBOARD_BUILD_DIRECTORY\.pixi"
+if (-not (Test-Path "$env:PIXI_HOME\bin\pixi.exe")) {
+ echo "Installing pixi..."
+ Invoke-WebRequest -Uri "https://pixi.sh/install.ps1" -OutFile "install-pixi.ps1"
+ powershell -ExecutionPolicy Bypass -File "install-pixi.ps1"
+}
+$env:Path = "$env:PIXI_HOME\bin;$env:Path"
- Remove-Item -Recurse -Force IPP/scripts/
- Copy-Item -Recurse IPP-tmp/scripts IPP/
- Copy-Item IPP-tmp/requirements-dev.txt IPP/
- Remove-Item -Recurse -Force IPP-tmp/
- popd
+# Install global packages via pixi for use in this script
+# Note: Using conda-forge packages that are available on Windows
+echo "Installing global tools via pixi..."
+$globalPackages = @(
+ "git", # Required for cloning ITKPythonPackage repo
+ "aria2" # Fast download utility (cross-platform)
+)
+
+foreach ($pkg in $globalPackages) {
+ echo " Installing $pkg..."
+ try {
+ & pixi global install $pkg
+ if ($LASTEXITCODE -ne 0) {
+ echo " Warning: Failed to install $pkg (exit code: $LASTEXITCODE)"
+ }
+ } catch {
+ echo " Warning: Failed to install $pkg - $($_.Exception.Message)"
+ }
+}
+
+# Refresh PATH to include pixi global binaries
+$env:Path = "$env:PIXI_HOME\bin;$env:Path"
+
+# ---------------------------------------------------------------------------
+# Download ITKPythonBuilds archive
+# ---------------------------------------------------------------------------
+$zipName = "ITKPythonBuilds-windows.zip"
+$zipDownloadUrl = "https://github.com/InsightSoftwareConsortium/ITKPythonBuilds/releases/download/$ITK_PACKAGE_VERSION/$zipName"
+$localZipName = "ITKPythonBuilds-windows.zip"
+
+if (Test-Path $localZipName) {
+ echo "Found cached archive: $localZipName -- skipping download."
+} else {
+ echo "Downloading $zipDownloadUrl ..."
+
+ # Try first (faster, resumable), fall back to Invoke-WebRequest
+ $aria2Path = Get-Command aria2c -ErrorAction SilentlyContinue
+ if ($aria2Path) {
+ echo " Using aria2c for download..."
+ & aria2c -c --file-allocation=none -s 10 -x 10 -o $localZipName $zipDownloadUrl
+ } else {
+ echo " Using Invoke-WebRequest for download..."
+ Invoke-WebRequest -Uri $zipDownloadUrl -OutFile $localZipName
+ }
}
-# Get other build dependencies
-if (-not (Test-Path doxygen-1.16.1.windows.bin.zip)) {
- Invoke-WebRequest -Uri "https://github.com/doxygen/doxygen/releases/download/Release_1_16_1/doxygen-1.16.1.windows.x64.bin.zip" -OutFile "doxygen-1.16.1.windows.bin.zip"
+# Unpack archive
+# Expected layout after extraction under $DASHBOARD_BUILD_DIRECTORY:
+# \ITK ITK source tree
+# \build\ pre-built ITK artifacts
+# \IPP ITKPythonPackage scripts
+
+echo "Extracting archive to $DASHBOARD_BUILD_DIRECTORY ..."
+# Use 7-Zip to extract (matches the format it was created in)
+$sevenZipPath = "C:\Program Files\7-Zip\7z.exe"
+if (-not (Test-Path $sevenZipPath)) {
+ Write-Error "7-Zip not found at $sevenZipPath. Please install 7-Zip."
+ exit 1
}
-7z x doxygen-1.16.1.windows.bin.zip -oC:\P\doxygen -aoa -r
-if (-not (Test-Path grep-win.zip)) {
- Invoke-WebRequest -Uri "https://data.kitware.com/api/v1/file/5bbf87ba8d777f06b91f27d6/download/grep-win.zip" -OutFile "grep-win.zip"
+
+& $sevenZipPath x $localZipName -o"$DASHBOARD_BUILD_DIRECTORY" -y
+if ($LASTEXITCODE -ne 0) {
+ Write-Error "Failed to extract archive (exit code: $LASTEXITCODE)"
+ exit 1
}
-7z x grep-win.zip -oC:\P\grep -aoa -r
-$env:Path += ";C:\P\grep"
+# Optional: overlay ITKPythonPackage build scripts from a specific tag
+cd "$DASHBOARD_BUILD_DIRECTORY\IPP"
+$env:PATH += ";C:\Program Files\Git\bin"
+if ($ITKPYTHONPACKAGE_TAG) {
+ echo "Updating build scripts to $ITKPYTHONPACKAGE_ORG/ITKPythonPackage@$ITKPYTHONPACKAGE_TAG"
+
+ $ippTmpDir = "$DASHBOARD_BUILD_DIRECTORY\IPP-tmp"
+ $ippCloneUrl = "https://github.com/$ITKPYTHONPACKAGE_ORG/ITKPythonPackage.git"
+
+ if (-not (Test-Path "$ippTmpDir\.git")) {
+ echo " Cloning repository..."
+ & git clone $ippCloneUrl $ippTmpDir
-# Build ITK module dependencies, if any
-$build_command = "& `"C:\Python$pythonVersion-x$pythonArch\python.exe`" `"C:\P\IPP\scripts\windows_build_module_wheels.py`" --no-cleanup --py-envs `"3$python_version_minor-x64`""
-if ("$setup_options".length -gt 0) {
- $build_command = "$build_command $setup_options"
+ # Check if clone succeeded
+ if ($LASTEXITCODE -ne 0 -or -not (Test-Path $ippTmpDir)) {
+ Write-Error "Failed to clone ITKPythonPackage repository"
+ exit 1
+ }
+ }
+
+ pushd $ippTmpDir
+ echo " Checking out $ITKPYTHONPACKAGE_TAG..."
+ & git checkout $ITKPYTHONPACKAGE_TAG
+ & git reset "origin/$ITKPYTHONPACKAGE_TAG" --hard
+ & git status
+ popd
+
+ echo " Copying updated scripts..."
+ Copy-Item -Recurse -Force "$ippTmpDir\*" "$DASHBOARD_BUILD_DIRECTORY\IPP\"
+ Remove-Item -Recurse -Force $ippTmpDir
}
-if("$cmake_options".length -gt 0) {
- $build_command = "$build_command -- $cmake_options"
+
+} # end else (tarball download path)
+
+# Build the module wheel
+# Assemble paths used by build_wheels.py
+if (-not $ippDir) {
+ $ippDir = "$DASHBOARD_BUILD_DIRECTORY\IPP"
}
-echo $build_command
+$buildScript = "$ippDir\scripts\build_wheels.py"
+# build_wheels.py expects the cached ITK build at \build\ITK-windows-py3XX-...
+# Since the zip extracts directly into BDR (i.e. BDR\build\ITK-windows-py311-...), BDR is the root.
+$buildDirRoot = $DASHBOARD_BUILD_DIRECTORY
+$itkSourceDir = "$DASHBOARD_BUILD_DIRECTORY\ITK"
+$moduleDepsDir = "$DASHBOARD_BUILD_DIRECTORY\MDEPS"
+
+# Instead of building a string and using iex, build an argument array
+$buildArgs = @(
+ "run", "-e", $platformEnv,
+ "python", $buildScript,
+ "--platform-env", $platformEnv,
+ "--module-source-dir", $MODULE_SRC_DIRECTORY,
+ "--module-dependencies-root-dir", $moduleDepsDir
+)
-echo "ITK_MODULE_PREQ: $env:ITK_MODULE_PREQ $ITK_MODULE_PREQ"
if ($env:ITK_MODULE_PREQ) {
- $MODULES_LIST = $env:ITK_MODULE_PREQ.split(":")
- foreach($MODULE_INFO in $MODULES_LIST) {
- $MODULE_ORG = $MODULE_INFO.split("/")[0]
- $MODULE_NAME = $MODULE_INFO.split("@")[0].split("/")[1]
- $MODULE_TAG = $MODULE_INFO.split("@")[1]
-
- $MODULE_UPSTREAM = "https://github.com/$MODULE_ORG/$MODULE_NAME.git"
- echo "Cloning from $MODULE_UPSTREAM"
- git clone $MODULE_UPSTREAM
-
- pushd $MODULE_NAME
- git checkout $MODULE_TAG
- echo "Building $MODULE_NAME"
- iex $build_command
- popd
-
- Copy-Item $MODULE_NAME/include/* include/
- }
+ $buildArgs += @("--itk-module-deps", $env:ITK_MODULE_PREQ)
+}
+
+$buildArgs += @(
+ "--no-build-itk-tarball-cache",
+ "--build-dir-root", $buildDirRoot,
+ "--itk-git-tag", $ITK_GIT_TAG,
+ "--itk-source-dir", $itkSourceDir,
+ "--itk-package-version", $ITK_PACKAGE_VERSION,
+ "--no-use-ccache",
+ "--skip-itk-build",
+ "--skip-itk-wheel-build"
+)
+
+if ($setup_options.Length -gt 0) {
+ $buildArgs += $setup_options.Split(" ")
+}
+
+if ($cmake_options.Length -gt 0) {
+ $buildArgs += @("--")
+ $buildArgs += $cmake_options.Split(" ")
}
-# Run build scripts
-iex $build_command
+echo "Building target module..."
+& pixi @buildArgs
diff --git a/scripts/windows_build_module_wheels.py b/scripts/windows_build_module_wheels.py
deleted file mode 100755
index 0a8f54f3..00000000
--- a/scripts/windows_build_module_wheels.py
+++ /dev/null
@@ -1,251 +0,0 @@
-#!/usr/bin/env python
-
-# See usage with .\scripts\windows_build_module_wheels.py --help
-
-from subprocess import check_call
-import os
-import glob
-import sys
-import argparse
-import shutil
-from pathlib import Path
-
-SCRIPT_DIR = os.path.dirname(__file__)
-ROOT_DIR = os.path.abspath(os.getcwd())
-
-print("SCRIPT_DIR: %s" % SCRIPT_DIR)
-print("ROOT_DIR: %s" % ROOT_DIR)
-
-sys.path.insert(0, os.path.join(SCRIPT_DIR, "internal"))
-
-from wheel_builder_utils import push_dir, push_env
-from windows_build_common import DEFAULT_PY_ENVS, venv_paths
-
-
-def install_and_import(package):
- """
- Install package with pip and import in current script.
- """
- import importlib
-
- try:
- importlib.import_module(package)
- except ImportError:
- import pip
-
- pip.main(["install", package])
- finally:
- globals()[package] = importlib.import_module(package)
-
-
-def build_wheels(py_envs=DEFAULT_PY_ENVS, cleanup=True, cmake_options=[]):
- for py_env in py_envs:
- (
- python_executable,
- python_include_dir,
- python_library,
- python_sabi_library,
- pip,
- ninja_executable,
- path,
- ) = venv_paths(py_env)
-
- with push_env(PATH="%s%s%s" % (path, os.pathsep, os.environ["PATH"])):
- # Install dependencies
- check_call([python_executable, "-m", "pip", "install", "pip", "--upgrade"])
- requirements_file = os.path.join(ROOT_DIR, "requirements-dev.txt")
- if os.path.exists(requirements_file):
- check_call([pip, "install", "--upgrade", "-r", requirements_file])
- check_call([pip, "install", "cmake"])
- check_call([pip, "install", "scikit-build-core", "--upgrade"])
-
- check_call([pip, "install", "ninja", "--upgrade"])
- check_call([pip, "install", "delvewheel"])
-
- source_path = ROOT_DIR
- itk_build_path = os.path.abspath(
- "%s/ITK-win_%s" % (os.path.join(SCRIPT_DIR, ".."), py_env)
- )
- print("ITKDIR: %s" % itk_build_path)
-
- minor_version = py_env.split("-")[0][1:]
- if int(minor_version) >= 11:
- # Stable ABI
- wheel_py_api = "cp3%s" % minor_version
- else:
- wheel_py_api = ""
- # Generate wheel
- check_call(
- [
- python_executable,
- "-m",
- "build",
- "--verbose",
- "--wheel",
- "--outdir",
- "dist",
- "--no-isolation",
- "--skip-dependency-check",
- "--config-setting=wheel.py-api=%s" % wheel_py_api,
- "--config-setting=cmake.define.SKBUILD:BOOL=ON",
- "--config-setting=cmake.define.PY_SITE_PACKAGES_PATH:PATH=.",
- "--config-setting=cmake.args=-G Ninja",
- "--config-setting=cmake.define.CMAKE_BUILD_TYPE:STRING=Release",
- "--config-setting=cmake.define.CMAKE_MAKE_PROGRAM:FILEPATH=%s"
- % ninja_executable,
- "--config-setting=cmake.define.ITK_DIR:PATH=%s"
- % itk_build_path,
- "--config-setting=cmake.define.WRAP_ITK_INSTALL_COMPONENT_IDENTIFIER:STRING=PythonWheel",
- "--config-setting=cmake.define.SWIG_EXECUTABLE:FILEPATH=%s/Wrapping/Generators/SwigInterface/swig/bin/swig.exe"
- % itk_build_path,
- "--config-setting=cmake.define.BUILD_TESTING:BOOL=OFF",
- "--config-setting=cmake.define.CMAKE_INSTALL_LIBDIR:STRING=lib",
- "--config-setting=cmake.define.Python3_EXECUTABLE:FILEPATH=%s"
- % python_executable,
- "--config-setting=cmake.define.Python3_INCLUDE_DIR:PATH=%s"
- % python_include_dir,
- "--config-setting=cmake.define.Python3_INCLUDE_DIRS:PATH=%s"
- % python_include_dir,
- "--config-setting=cmake.define.Python3_LIBRARY:FILEPATH=%s"
- % python_library,
- "--config-setting=cmake.define.Python3_SABI_LIBRARY:FILEPATH=%s"
- % python_sabi_library,
- ]
- + [
- o.replace("-D", "--config-setting=cmake.define.")
- for o in cmake_options
- ]
- + [
- ".",
- ]
- )
-
-
-def rename_wheel_init(py_env, filepath, add_module_name=True):
- """
- Rename module __init__ (if add_module_name is True) or __init_module__ (if
- add_module_name is False) file in wheel. This is required to prevent
- modules to override ITK's __init__ file on install or to prevent delvewheel
- to override __init_module__ file. If the module ships its own __init__
- file, it is automatically renamed to __init_{module_name}__ by this
- function. The renamed __init__ file will be executed by ITK's __init__ file
- when loading ITK.
- """
- (
- python_executable,
- python_include_dir,
- python_library,
- python_sabi_library,
- pip,
- ninja_executable,
- path,
- ) = venv_paths(py_env)
-
- # Get module info
- install_and_import("pkginfo")
- w = pkginfo.Wheel(filepath)
- module_name = w.name.split("itk-")[-1]
- module_version = w.version
-
- dist_dir = os.path.dirname(filepath)
- wheel_dir = os.path.join(
- dist_dir, "itk_" + module_name.replace("-", "_") + "-" + module_version
- )
- init_dir = os.path.join(wheel_dir, "itk")
- init_file = os.path.join(init_dir, "__init__.py")
- init_file_module = os.path.join(
- init_dir, "__init_" + module_name.split("-")[0] + "__.py"
- )
-
- # Unpack wheel and rename __init__ file if it exists.
- check_call([python_executable, "-m", "wheel", "unpack", filepath, "-d", dist_dir])
- if add_module_name and os.path.isfile(init_file):
- shutil.move(init_file, init_file_module)
- if not add_module_name and os.path.isfile(init_file_module):
- shutil.move(init_file_module, init_file)
-
- # Pack wheel and clean wheel folder
- check_call([python_executable, "-m", "wheel", "pack", wheel_dir, "-d", dist_dir])
- shutil.rmtree(wheel_dir)
-
-
-def fixup_wheel(py_envs, filepath, lib_paths: str = "", exclude_libs: str = ""):
- lib_paths = ";".join(["C:/P/IPP/oneTBB-prefix/bin", lib_paths.strip()]).strip(";")
- print(f"Library paths for fixup: {lib_paths}")
-
- py_env = py_envs[0]
-
- # Make sure the module __init_module__.py file has the expected name for
- # delvewheel, i.e., __init__.py.
- rename_wheel_init(py_env, filepath, False)
-
- delve_wheel = os.path.join(
- "C:/P/IPP", "venv-" + py_env, "Scripts", "delvewheel.exe"
- )
- check_call(
- [
- delve_wheel,
- "repair",
- "--no-mangle-all",
- "--add-path",
- lib_paths,
- "--no-dll",
- exclude_libs,
- "--ignore-in-wheel",
- "-w",
- os.path.join(ROOT_DIR, "dist"),
- filepath,
- ]
- )
-
- # The delve_wheel patch loading shared libraries is added to the module
- # __init__ file. Rename this file here to prevent conflicts on installation.
- # The renamed __init__ file will be executed when loading ITK.
- rename_wheel_init(py_env, filepath)
-
-
-def fixup_wheels(py_envs, lib_paths: str = "", exclude_libs: str = ""):
- # shared library fix-up
- for wheel in glob.glob(os.path.join(ROOT_DIR, "dist", "*.whl")):
- fixup_wheel(py_envs, wheel, lib_paths, exclude_libs)
-
-
-if __name__ == "__main__":
- parser = argparse.ArgumentParser(
- description="Driver script to build ITK Python module wheels."
- )
- parser.add_argument(
- "--py-envs",
- nargs="+",
- default=DEFAULT_PY_ENVS,
- help='Target Python environment versions, e.g. "310-x64".',
- )
- parser.add_argument(
- "--no-cleanup",
- dest="cleanup",
- action="store_false",
- help="Do not clean up temporary build files.",
- )
- parser.add_argument(
- "--lib-paths",
- nargs=1,
- default="",
- help="Add semicolon-delimited library directories for delvewheel to include in the module wheel",
- )
- parser.add_argument(
- "--exclude-libs",
- nargs=1,
- default="",
- help='Add semicolon-delimited library names that must not be included in the module wheel, e.g. "nvcuda.dll"',
- )
- parser.add_argument(
- "cmake_options",
- nargs="*",
- help="Extra options to pass to CMake, e.g. -DBUILD_SHARED_LIBS:BOOL=OFF",
- )
- args = parser.parse_args()
-
- build_wheels(
- cleanup=args.cleanup, py_envs=args.py_envs, cmake_options=args.cmake_options
- )
- fixup_wheels(args.py_envs, ";".join(args.lib_paths), ";".join(args.exclude_libs))
diff --git a/scripts/windows_build_python_instance.py b/scripts/windows_build_python_instance.py
new file mode 100644
index 00000000..0f966db1
--- /dev/null
+++ b/scripts/windows_build_python_instance.py
@@ -0,0 +1,256 @@
+import re
+from pathlib import Path
+
+from build_python_instance_base import BuildPythonInstanceBase
+
+
+class WindowsBuildPythonInstance(BuildPythonInstanceBase):
+ """Windows-specific wheel builder.
+
+ Handles Windows path conventions, pixi-based Python environment
+ discovery, and ``delvewheel`` for wheel repair.
+ """
+
+ def prepare_build_env(self) -> None:
+ """Set up the Windows build environment, TBB paths, and venv info."""
+ # #############################################
+ # ### Setup build tools
+ self.package_env_config["USE_TBB"] = "ON"
+ self.package_env_config["TBB_DIR"] = str(
+ self.build_dir_root / "build" / "oneTBB-prefix" / "lib" / "cmake" / "TBB"
+ )
+ # The interpreter is provided; ensure basic tools are available
+ self.venv_paths()
+ self.update_venv_itk_build_configurations()
+
+ target_arch = self.package_env_config["ARCH"]
+ itk_binary_build_name: Path = (
+ self.build_dir_root
+ / "build"
+ / f"ITK-{self.platform_env}-{self.get_pixi_environment_name()}_{target_arch}"
+ )
+
+ self.cmake_itk_source_build_configurations.set(
+ "ITK_BINARY_DIR:PATH", str(itk_binary_build_name)
+ )
+
+ # Keep values consistent with prior quoting behavior
+ # self.cmake_compiler_configurations.set("CMAKE_CXX_FLAGS:STRING", "-O3 -DNDEBUG")
+ # self.cmake_compiler_configurations.set("CMAKE_C_FLAGS:STRING", "-O3 -DNDEBUG")
+
+ def post_build_fixup(self) -> None:
+ """Repair wheels with ``delvewheel``, including oneTBB library paths."""
+ # append the oneTBB-prefix\\bin directory for fixing wheels built with local oneTBB
+ search_lib_paths = (
+ [s for s in str(self.windows_extra_lib_paths[0]).rstrip(";") if s]
+ if self.windows_extra_lib_paths
+ else []
+ )
+ search_lib_paths.append(str(self.build_dir_root / "oneTBB-prefix" / "bin"))
+ search_lib_paths_str: str = ";".join(map(str, search_lib_paths))
+ self.fixup_wheels(search_lib_paths_str)
+
+ def fixup_wheel(
+ self, filepath, lib_paths: str = "", remote_module_wheel: bool = False
+ ) -> None:
+ """Repair a wheel using ``delvewheel`` with the given library paths.
+
+ Parameters
+ ----------
+ filepath : str
+ Path to the ``.whl`` file to repair.
+ lib_paths : str, optional
+ Semicolon-delimited directories to add to ``delvewheel --add-path``.
+ remote_module_wheel : bool, optional
+ Unused on Windows (kept for interface compatibility).
+ """
+ # Windows fixup_wheel
+ lib_paths = lib_paths.strip()
+ lib_paths = lib_paths + ";" if lib_paths else ""
+ print(f"Library paths for fixup: {lib_paths}")
+
+ delve_wheel = "delvewheel.exe"
+ cmd = [
+ str(delve_wheel),
+ "repair",
+ "--no-mangle-all",
+ "--add-path",
+ lib_paths.strip(";"),
+ "--ignore-in-wheel",
+ "-w",
+ str(self.build_dir_root / "dist"),
+ str(filepath),
+ ]
+ self.echo_check_call(cmd)
+
+ def build_tarball(self):
+ """Create an archive of the ITK Python package build tree (Windows).
+
+ Mirrors scripts/windows-build-tarball.ps1 behavior:
+ - Remove contents of IPP/dist
+ - Use 7-Zip, when present, to archive the full IPP tree into
+ ITKPythonBuilds-windows.zip at the parent directory of IPP (e.g., C:\P)
+ - Fallback to Python's zip archive creation if 7-Zip is unavailable
+ """
+
+ # out_zip = self.build_dir_root / "build" / "ITKPythonBuilds-windows.zip"
+ out_zip = self.build_dir_root / "ITKPythonBuilds-windows.zip"
+
+ # 1) Clean IPP/dist contents (do not remove the directory itself)
+ dist_dir = self.build_dir_root / "dist"
+ if dist_dir.exists():
+ for p in dist_dir.glob("*"):
+ try:
+ if p.is_dir():
+ # shutil.rmtree alternative without importing here
+ for sub in p.rglob("*"):
+ # best-effort clean
+ try:
+ if sub.is_file() or sub.is_symlink():
+ sub.unlink(missing_ok=True)
+ except Exception:
+ pass
+ try:
+ p.rmdir()
+ except Exception:
+ pass
+ else:
+ p.unlink(missing_ok=True)
+ except Exception:
+ # best-effort cleanup; ignore errors to continue packaging
+ pass
+
+ # 2) Try to use 7-Zip if available
+ seven_zip_candidates = [
+ Path(r"C:\\7-Zip\\7z.exe"),
+ Path(r"C:\\Program Files\\7-Zip\\7z.exe"),
+ Path(r"C:\\Program Files (x86)\\7-Zip\\7z.exe"),
+ ]
+
+ seven_zip = None
+ for cand in seven_zip_candidates:
+ if cand.exists():
+ seven_zip = cand
+ break
+
+ if seven_zip is None:
+ # Try PATH lookup using where/which behavior from shutil
+ import shutil as _shutil
+
+ found = _shutil.which("7z.exe") or _shutil.which("7z")
+ if found:
+ seven_zip = Path(found)
+
+ if seven_zip is not None:
+ cmd = [
+ str(seven_zip),
+ "a",
+ "-t7z",
+ "-r",
+ str(out_zip),
+ str(self.build_dir_root / "ITK"),
+ str(self.build_dir_root / "build"),
+ str(self.ipp_dir),
+ "-xr!*.o",
+ "-xr!*.obj", # Windows equivalent of .o
+ "-xr!wheelbuilds", # Do not include the wheelbuild support directory
+ "-xr!__pycache__", # Do not include __pycache__
+ "-xr!install_manifest_*.txt", # Do not include install manifest files
+ "-xr!.git", # Exclude git directory
+ "-xr!.idea", # Exclude IDE directory
+ "-xr!.pixi", # Exclude pixi environment
+ "-xr!castxml_inputs",
+ "-xr!Wrapping\Modules",
+ "-xr!*.pdb", # Exclude debug symbols
+ ]
+ return_status: int = self.echo_check_call(cmd)
+ if return_status == 0:
+ return
+
+ # 3) Fallback: create a .zip using Python's shutil
+ # This will create a zip archive named ITKPythonBuilds-windows.zip
+ import shutil as _shutil
+
+ if out_zip.exists():
+ try:
+ out_zip.unlink()
+ except Exception:
+ pass
+ # make_archive requires base name without extension
+ base_name = str(out_zip.with_suffix("").with_suffix(""))
+ # shutil.make_archive will append .zip
+ _shutil.make_archive(
+ base_name,
+ "zip",
+ root_dir=str(self.build_dir_root),
+ base_dir=str(self.build_dir_root.name),
+ )
+
+ def venv_paths(self) -> None:
+ """Populate ``venv_info_dict`` from the pixi-managed Python environment on Windows."""
+
+ def get_python_version(platform_env: str) -> None | tuple[int, int]:
+ pattern = re.compile(r"py3(?P\d+)")
+ m = pattern.search(platform_env)
+ if not m:
+ return None
+ return 3, int(m.group("minor"))
+
+ # Get the python executable path
+ python_exe = Path(self.package_env_config["PYTHON_EXECUTABLE"])
+
+ # For the pixi environment structure:
+ # python.exe is at: /python.exe
+ # Headers are at: /include/
+ # Libraries are at: /libs/
+ env_root = python_exe.parent # C:/BDR/IPP/.pixi/envs/windows-py311
+
+ venv_bin_path = env_root # Where python.exe is
+ venv_base_dir = env_root
+
+ # Python development files are directly under env root
+ python_include_dir = env_root / "include"
+
+ python_major, python_minor = get_python_version(self.platform_env)
+ # Version-specific library (e.g., python311.lib) - required for
+ # CMake's FindPython3 to extract version info for Development.Module
+ xy_lib_ver = f"{python_major}{python_minor}"
+ python_library = env_root / "libs" / f"python{xy_lib_ver}.lib"
+
+ # Stable ABI library (python3.lib) - for Development.SABIModule
+ if python_minor >= 11:
+ python_sabi_library = env_root / "libs" / f"python{python_major}.lib"
+ else:
+ python_sabi_library = python_library
+
+ self.venv_info_dict = {
+ "python_include_dir": python_include_dir, # .../windows-py311/include
+ "python_library": python_library, # .../windows-py311/libs/python311.lib
+ "python_sabi_library": python_sabi_library, # .../windows-py311/libs/python3.lib
+ "venv_bin_path": venv_bin_path, # .../windows-py311
+ "venv_base_dir": venv_base_dir, # .../windows-py311
+ "python_root_dir": env_root, # .../windows-py311
+ }
+
+ def discover_python_venvs(
+ self, platform_os_name: str, platform_architecture: str
+ ) -> list[str]:
+ """Return default Windows Python environment names.
+
+ Parameters
+ ----------
+ platform_os_name : str
+ Operating system identifier (unused, kept for interface).
+ platform_architecture : str
+ Architecture suffix appended to each environment name.
+
+ Returns
+ -------
+ list[str]
+ Environment names like ``['39-x64', '310-x64', '311-x64']``.
+ """
+ default_platform_envs = [
+ f"310-{platform_architecture}",
+ f"311-{platform_architecture}",
+ ]
+ return default_platform_envs
diff --git a/scripts/windows_build_wheels.py b/scripts/windows_build_wheels.py
deleted file mode 100644
index 4c1404bd..00000000
--- a/scripts/windows_build_wheels.py
+++ /dev/null
@@ -1,411 +0,0 @@
-#!/usr/bin/env python
-
-import argparse
-import glob
-import json
-import os
-import shutil
-import sys
-import tempfile
-import textwrap
-
-from subprocess import check_call, check_output
-
-
-SCRIPT_DIR = os.path.dirname(__file__)
-ROOT_DIR = os.path.abspath(os.path.join(SCRIPT_DIR, ".."))
-ITK_SOURCE = os.path.join(ROOT_DIR, "ITK-source")
-
-print("SCRIPT_DIR: %s" % SCRIPT_DIR)
-print("ROOT_DIR: %s" % ROOT_DIR)
-print("ITK_SOURCE: %s" % ITK_SOURCE)
-
-sys.path.insert(0, os.path.join(SCRIPT_DIR, "internal"))
-from wheel_builder_utils import push_dir, push_env
-from windows_build_common import DEFAULT_PY_ENVS, venv_paths
-
-
-def pip_install(python_dir, package, upgrade=True):
- pip = os.path.join(python_dir, "Scripts", "pip.exe")
- print("Installing %s using %s" % (package, pip))
- args = [pip, "install"]
- if upgrade:
- args.append("--upgrade")
- args.append(package)
- check_call(args)
-
-
-def prepare_build_env(python_version):
- python_dir = "C:/Python%s" % python_version
- if not os.path.exists(python_dir):
- raise FileNotFoundError(
- "Aborting. python_dir [%s] does not exist." % python_dir
- )
-
- venv = os.path.join(python_dir, "Scripts", "virtualenv.exe")
- venv_dir = os.path.join(ROOT_DIR, "venv-%s" % python_version)
- print("Creating python virtual environment: %s" % venv_dir)
- if not os.path.exists(venv_dir):
- check_call([venv, venv_dir])
- pip_install(venv_dir, "scikit-build-core")
- pip_install(venv_dir, "ninja")
- pip_install(venv_dir, "delvewheel")
-
-
-def build_wrapped_itk(
- ninja_executable,
- build_type,
- source_path,
- build_path,
- python_executable,
- python_include_dir,
- python_library,
- python_sabi_library,
-):
- tbb_dir = os.path.join(ROOT_DIR, "oneTBB-prefix", "lib", "cmake", "TBB")
-
- # Build ITK python
- with push_dir(directory=build_path, make_directory=True):
- check_call(
- [
- "cmake",
- "-DCMAKE_MAKE_PROGRAM:FILEPATH=%s" % ninja_executable,
- "-DCMAKE_BUILD_TYPE:STRING=%s" % build_type,
- "-DITK_SOURCE_DIR:PATH=%s" % source_path,
- "-DITK_BINARY_DIR:PATH=%s" % build_path,
- "-DBUILD_TESTING:BOOL=OFF",
- "-DSKBUILD:BOOL=ON",
- "-DPython3_EXECUTABLE:FILEPATH=%s" % python_executable,
- "-DITK_WRAP_unsigned_short:BOOL=ON",
- "-DITK_WRAP_double:BOOL=ON",
- "-DITK_WRAP_complex_double:BOOL=ON",
- "-DITK_WRAP_IMAGE_DIMS:STRING=2;3;4",
- "-DPython3_INCLUDE_DIR:PATH=%s" % python_include_dir,
- "-DPython3_INCLUDE_DIRS:PATH=%s" % python_include_dir,
- "-DPython3_LIBRARY:FILEPATH=%s" % python_library,
- "-DPython3_SABI_LIBRARY:FILEPATH=%s" % python_sabi_library,
- "-DWRAP_ITK_INSTALL_COMPONENT_IDENTIFIER:STRING=PythonWheel",
- "-DWRAP_ITK_INSTALL_COMPONENT_PER_MODULE:BOOL=ON",
- "-DPY_SITE_PACKAGES_PATH:PATH=.",
- "-DITK_LEGACY_SILENT:BOOL=ON",
- "-DITK_WRAP_PYTHON:BOOL=ON",
- "-DITK_WRAP_DOC:BOOL=ON",
- "-DDOXYGEN_EXECUTABLE:FILEPATH=C:/P/doxygen/doxygen.exe",
- "-DModule_ITKTBB:BOOL=ON",
- "-DTBB_DIR:PATH=%s" % tbb_dir,
- "-G",
- "Ninja",
- source_path,
- ]
- )
- check_call([ninja_executable])
-
-
-def build_wheel(
- python_version,
- build_type="Release",
- single_wheel=False,
- cleanup=True,
- wheel_names=None,
- cmake_options=[],
-):
- (
- python_executable,
- python_include_dir,
- python_library,
- python_sabi_library,
- pip,
- ninja_executable,
- path,
- ) = venv_paths(python_version)
-
- with push_env(PATH="%s%s%s" % (path, os.pathsep, os.environ["PATH"])):
- # Install dependencies
- check_call(
- [
- pip,
- "install",
- "--upgrade",
- "-r",
- os.path.join(ROOT_DIR, "requirements-dev.txt"),
- ]
- )
-
- source_path = "%s/ITK" % ITK_SOURCE
- build_path = "%s/ITK-win_%s" % (ROOT_DIR, python_version)
- pyproject_configure = os.path.join(SCRIPT_DIR, "pyproject_configure.py")
-
- # Clean up previous invocations
- if cleanup and os.path.exists(build_path):
- shutil.rmtree(build_path)
-
- if single_wheel:
- print("#")
- print("# Build single ITK wheel")
- print("#")
-
- # Configure pyproject.toml
- check_call([python_executable, pyproject_configure, "itk"])
-
- # Generate wheel
- check_call(
- [
- python_executable,
- "-m",
- "build",
- "--verbose",
- "--wheel",
- "--outdir",
- "dist",
- "--no-isolation",
- "--skip-dependency-check",
- "--config-setting=cmake.build-type=%s" % build_type,
- "--config-setting=cmake.define.ITK_SOURCE_DIR:PATH=%s"
- % source_path,
- "--config-setting=cmake.define.ITK_BINARY_DIR:PATH=%s" % build_path,
- "--config-setting=cmake.define.Python3_EXECUTABLE:FILEPATH=%s"
- % python_executable,
- "--config-setting=cmake.define.Python3_INCLUDE_DIR:PATH=%s"
- % python_include_dir,
- "--config-setting=cmake.define.Python3_INCLUDE_DIRS:PATH=%s"
- % python_include_dir,
- "--config-setting=cmake.define.Python3_LIBRARY:FILEPATH=%s"
- % python_library,
- "--config-setting=cmake.define.Python3_SABI_LIBRARY:FILEPATH=%s"
- % python_sabi_library,
- "--config-setting=cmake.define.DOXYGEN_EXECUTABLE:FILEPATH=C:/P/doxygen/doxygen.exe",
- ]
- + [
- o.replace("-D", "--config-setting=cmake.define.")
- for o in cmake_options
- ]
- + [
- ".",
- ]
- )
-
- else:
- print("#")
- print("# Build multiple ITK wheels")
- print("#")
-
- build_wrapped_itk(
- ninja_executable,
- build_type,
- source_path,
- build_path,
- python_executable,
- python_include_dir,
- python_library,
- python_sabi_library,
- )
-
- # Build wheels
- if wheel_names is None:
- with open(os.path.join(SCRIPT_DIR, "WHEEL_NAMES.txt"), "r") as content:
- wheel_names = [
- wheel_name.strip() for wheel_name in content.readlines()
- ]
-
- for wheel_name in wheel_names:
- # Configure pyproject.toml
- check_call([python_executable, pyproject_configure, wheel_name])
-
- # Generate wheel
- check_call(
- [
- python_executable,
- "-m",
- "build",
- "--verbose",
- "--wheel",
- "--outdir",
- "dist",
- "--no-isolation",
- "--skip-dependency-check",
- "--config-setting=cmake.build-type=%s" % build_type,
- "--config-setting=cmake.define.ITK_SOURCE_DIR:PATH=%s"
- % source_path,
- "--config-setting=cmake.define.ITK_BINARY_DIR:PATH=%s"
- % build_path,
- "--config-setting=cmake.define.ITKPythonPackage_ITK_BINARY_REUSE:BOOL=ON",
- "--config-setting=cmake.define.ITKPythonPackage_WHEEL_NAME:STRING=%s"
- % wheel_name,
- "--config-setting=cmake.define.Python3_EXECUTABLE:FILEPATH=%s"
- % python_executable,
- "--config-setting=cmake.define.Python3_INCLUDE_DIR:PATH=%s"
- % python_include_dir,
- "--config-setting=cmake.define.Python3_INCLUDE_DIRS:PATH=%s"
- % python_include_dir,
- "--config-setting=cmake.define.Python3_LIBRARY:FILEPATH=%s"
- % python_library,
- "--config-setting=cmake.define.Python3_SABI_LIBRARY:FILEPATH=%s"
- % python_sabi_library,
- ]
- + [
- o.replace("-D", "--config-setting=cmake.define.")
- for o in cmake_options
- ]
- + [
- ".",
- ]
- )
-
- # Remove unnecessary files for building against ITK
- if cleanup:
- for root, _, file_list in os.walk(build_path):
- for filename in file_list:
- extension = os.path.splitext(filename)[1]
- if extension in [".cpp", ".xml", ".obj", ".o"]:
- os.remove(os.path.join(root, filename))
- shutil.rmtree(os.path.join(build_path, "Wrapping", "Generators", "CastXML"))
-
-
-def fixup_wheel(py_envs, filepath, lib_paths: str = ""):
- lib_paths = lib_paths.strip() if lib_paths.isspace() else lib_paths.strip() + ";"
- lib_paths += "C:/P/IPP/oneTBB-prefix/bin"
- print(f"Library paths for fixup: {lib_paths}")
-
- py_env = py_envs[0]
-
- delve_wheel = os.path.join(ROOT_DIR, "venv-" + py_env, "Scripts", "delvewheel.exe")
- check_call(
- [
- delve_wheel,
- "repair",
- "--no-mangle-all",
- "--add-path",
- lib_paths,
- "--ignore-in-wheel",
- "-w",
- os.path.join(ROOT_DIR, "dist"),
- filepath,
- ]
- )
-
-
-def fixup_wheels(single_wheel, py_envs, lib_paths: str = ""):
- # TBB library fix-up
- tbb_wheel = "itk_core"
- if single_wheel:
- tbb_wheel = "itk"
- for wheel in glob.glob(os.path.join(ROOT_DIR, "dist", tbb_wheel + "*.whl")):
- fixup_wheel(py_envs, wheel, lib_paths)
-
-
-def test_wheels(python_env):
- (
- python_executable,
- python_include_dir,
- python_library,
- python_sabi_library,
- pip,
- ninja_executable,
- path,
- ) = venv_paths(python_env)
- check_call([pip, "install", "numpy"])
- check_call([pip, "install", "itk", "--no-cache-dir", "--no-index", "-f", "dist"])
- print("Wheel successfully installed.")
- check_call([python_executable, os.path.join(ROOT_DIR, "docs/code/test.py")])
- print("Documentation tests passed.")
-
-
-def build_wheels(
- py_envs=DEFAULT_PY_ENVS,
- single_wheel=False,
- cleanup=False,
- wheel_names=None,
- cmake_options=[],
-):
- for py_env in py_envs:
- prepare_build_env(py_env)
-
- build_type = "Release"
-
- with push_dir(directory=ITK_SOURCE, make_directory=True):
- cmake_executable = "cmake.exe"
- tools_venv = os.path.join(ROOT_DIR, "venv-" + py_envs[0])
- ninja_executable = shutil.which("ninja.exe")
- if ninja_executable is None:
- pip_install(tools_venv, "ninja")
- ninja_executable = os.path.join(tools_venv, "Scripts", "ninja.exe")
-
- # Build standalone project and populate archive cache
- check_call(
- [
- cmake_executable,
- "-DCMAKE_BUILD_TYPE:STRING=%s" % build_type,
- "-DITKPythonPackage_BUILD_PYTHON:PATH=0",
- "-G",
- "Ninja",
- "-DCMAKE_MAKE_PROGRAM:FILEPATH=%s" % ninja_executable,
- ROOT_DIR,
- ]
- )
-
- check_call([ninja_executable])
-
- # Compile wheels re-using standalone project and archive cache
- for py_env in py_envs:
- tools_venv = os.path.join(ROOT_DIR, "venv-" + py_env)
- ninja_executable = shutil.which("ninja.exe")
- if ninja_executable is None:
- pip_install(tools_venv, "ninja")
- build_wheel(
- py_env,
- build_type,
- single_wheel=single_wheel,
- cleanup=cleanup,
- wheel_names=wheel_names,
- cmake_options=cmake_options,
- )
-
-
-def main(wheel_names=None):
- parser = argparse.ArgumentParser(
- description="Driver script to build ITK Python wheels."
- )
- parser.add_argument(
- "--single-wheel",
- action="store_true",
- help="Build a single wheel as opposed to one wheel per ITK module group.",
- )
- parser.add_argument(
- "--py-envs",
- nargs="+",
- default=DEFAULT_PY_ENVS,
- help='Target Python environment versions, e.g. "310-x64".',
- )
- parser.add_argument(
- "--no-cleanup",
- dest="cleanup",
- action="store_false",
- help="Do not clean up temporary build files.",
- )
- parser.add_argument(
- "--lib-paths",
- nargs=1,
- default="",
- help="Add semicolon-delimited library directories for delvewheel to include in the module wheel",
- )
- parser.add_argument(
- "cmake_options",
- nargs="*",
- help="Extra options to pass to CMake, e.g. -DBUILD_SHARED_LIBS:BOOL=OFF",
- )
- args = parser.parse_args()
-
- build_wheels(
- single_wheel=args.single_wheel,
- cleanup=args.cleanup,
- py_envs=args.py_envs,
- wheel_names=wheel_names,
- cmake_options=args.cmake_options,
- )
- fixup_wheels(args.single_wheel, args.py_envs, ";".join(args.lib_paths))
- for py_env in args.py_envs:
- test_wheels(py_env)
-
-
-if __name__ == "__main__":
- main()